Homepage Demos Overview Downloads Tutorials Reference
Credits

LedEngine.h

Go to the documentation of this file.
00001 #ifndef INCLUDED_LedEngine_h
00002 #define INCLUDED_LedEngine_h
00003 
00004 #include "Shared/RobotInfo.h"
00005 #include "Shared/get_time.h"
00006 #include "OutputCmd.h"
00007 #include <math.h>
00008 
00009 class MotionCommand;
00010 
00011 // LEDBitMask_t and associated constants are defined in RobotInfo.h
00012 
00013 //! Provides basic LED effects to anything that inherits from (recommended method for MotionCommands) or instantiates it (just in case you have reason to)
00014 /*! Provides a collection of special effects so that the code can be reused various places
00015  *  as feedback to to the user.
00016  *
00017  * Cycling ("pulsing") and single-value setting are mutually exclusive - one will cut off the other
00018  *
00019  * A flash will invert and override the current setting, so that it will "reset" after the flash.
00020  * Flashes change mid-range values to extremes to make the flash visible (ie not just (1-current))
00021  * Normal invert will do simple inverses (just (1-current))
00022  *
00023  * getSetting() returns value of last set();
00024  * getValue() returns what's actually being returned to Motion at the moment
00025  *
00026  * There's some nice functions for using the LEDs to display numbers.  This is handy for when
00027  * you want to be free of the terminal.
00028  * <img src="NumberLEDs.jpg">
00029  */
00030 
00031 class LedEngine {
00032  public:
00033   //!constructor - don't forget to call if you inherit
00034   LedEngine();
00035   //!destructor
00036   virtual ~LedEngine() {}
00037   
00038   //! call this from a MotionCommand's updateOutputs() - makes calls to MotionManager to update LED values
00039   /*! @param caller pass the "parent" motioncommand's address here (usually will pass 'this')
00040    *  @param mask a bitmask of which leds to update (uses weight of 1) */
00041   int updateLEDs(const MotionCommand* caller,LEDBitMask_t mask=AllLEDMask);
00042   
00043   //! call this from a MotionCommand's updateOutputs() - performs the calculations to update LEDs' values
00044   /*! @param cmds on input, used for weight values - on return, holds the resulting OutputCmd's*/
00045   int updateLEDs(OutputCmd cmds[NumLEDs]);
00046 
00047   //! call this from a MotionCommand's updateOutputs() - performs the calculations to update LEDs' values
00048   /*! @param cmds on input, used for weight values - on return, holds the resulting OutputCmd's*/
00049   int updateLEDFrames(OutputCmd cmds[NumLEDs][NumFrames]);
00050   
00051   //!returns true if there are changes since the last updateLEDs()
00052   int isDirty();
00053 
00054   //!sets the leds specified by @a leds to the inverse of their current value
00055   void invert(LEDBitMask_t leds);
00056   //!sets the leds specified by @a leds to @a value, clears all the rest
00057   inline void cset(LEDBitMask_t leds, float value) { clear(); set(leds,value); }
00058   //!sets the leds specified by @a leds to @a value
00059   void set(LEDBitMask_t leds, float value);
00060   //!sets the leds specified by @a leds to @a value for @a ms milliseconds, then sets back.  Clears ~leds
00061   void cflash(LEDBitMask_t leds, float value, unsigned int ms);
00062   //!sets the leds specified by @a leds to @a value for @a ms milliseconds, then sets back.
00063   void flash(LEDBitMask_t leds, unsigned int ms=500);
00064   //!causes the leds specified by @a leds to cycle between low and high, clears others.  See cycle() for parameter documentation.
00065   inline void ccycle(LEDBitMask_t leds, unsigned int period, float amp, float offset=0, int phase=0) { clear(); cycle(leds,period,amp,offset,phase); }
00066   //!causes the leds specified by @a leds to cycle between low and high
00067   void cycle(LEDBitMask_t leds, unsigned int period, float amp, float offset=0, int phase=0);
00068   //!sets all leds to 0.
00069   void clear();
00070 
00071   //!returns the current setting of the LED specified by @a led_id (the value you passed in set())
00072   float getSetting(LEDOffset_t led_id) { return infos[led_id-LEDOffset].value; }
00073   //!returns the current value of the LED specified by @a led_id (the value being expressed - may change if cycling for instance)
00074   float getValue(LEDOffset_t led_id,unsigned int planahead=0) { return calcValue(led_id-LEDOffset,get_time()+planahead); }
00075   
00076   //!holds a series of bit masks for the onedigit style of numerical display (0-10 and '.')
00077   /*!the hope is that these actually resemble the shapes of the numbers so people can
00078    * recognize them more easily - without converting base 2 in their heads. */
00079   static const LEDBitMask_t ERS210numMasks[11];
00080   static const LEDBitMask_t ERS220numMasks[11]; //!< bit masks for the ondigit style of numberical display - just count the LEDs on the head
00081   static const LEDBitMask_t ERS7numMasks[11]; //!< writes a number on the display
00082   //!Use these to specify a style for displaying numbers using displayNumber()
00083   enum numStyle_t {
00084     onedigit, //!< can display a number -9 thru 9, using #numMask.  For negative numbers, blinks the top bar - fast if it's supposed to be on, slow if it would otherwise be off
00085     twodigit  //!< can display a number -99 thru 99, using setOneOfTwo().  For negative numbers, sets the top bar to 1 (off otherwise).
00086   };
00087   //!Use these to specify a style for displaying a percentage value [0-1] using displayPercent()
00088   enum percentStyle_t {
00089     major, //!< shows overall value
00090     minor, //!< shows value within major tick
00091     none   //!< if you want to leave blank
00092   };
00093     
00094   //!Allows convenient display of numerical information to the LEDs on the face.
00095   /*!If overflow occurs, the face LEDs are set to flash on and off 3 every 333 milliseconds*/
00096   void displayNumber(int x, numStyle_t style);
00097   //!Allows convenient display of percentage information to the LEDs on the face.
00098   /*!Besides allowing a two-digit display, the 'edge' bar for each type is blinked to
00099    * denote how full it is.  So you can get up to a two-digit, base 5 display, with an
00100    * extra digit of estimated value.
00101    *
00102    * If overflow (>1) occurs, sets everything to .75. <br>
00103    * If underflow (<0) occurs, sets everything to .25.
00104    * 
00105    * The left and right columns are combined with an OR operation.  (they overlap on the top bar)
00106    * Left and right designations are <em>dog centric!</em> */
00107   void displayPercent(float x, percentStyle_t left_style, percentStyle_t right_style);
00108   
00109  protected:
00110   //!Performs the 'invert' calculation based on current value (returns 1-value)
00111   static float calcInvert(float value) {
00112     return 1-value;
00113   }
00114   //!Performs the 'flash' calculation based on current value (uses calcInvert() if value upper or lower third, 0 or 1 otherwise)
00115   static float calcFlash(float value) {
00116     if(value>.33333 && value<.66666)
00117       return (value<.5 ? 1 : 0);
00118     else
00119       return calcInvert(value);
00120   }
00121   //!Performs the 'cycle' calculation based on desired period, amplituted, amplitude offset, and time since start.  See cycle()
00122   static float calcCycle(unsigned int period, float amp, float offset, unsigned int t) {
00123     //    cout << period << ',' << amp << ',' << offset << ',' << time << " -> " << x;
00124     float x=cos(t*6.2831853/period)*(-amp/2)+.5+offset;
00125     return x;
00126   }
00127   //!Calculates the current value of led @a i for current time t
00128   float calcValue(unsigned int i, unsigned int t) {
00129     if(t<infos[i].flashtime)
00130       return infos[i].flashvalue;
00131     else if(infos[i].isCycling)
00132       return calcCycle(infos[i].period,infos[i].amp,infos[i].offset,t-infos[i].starttime);
00133     else
00134       return infos[i].value;
00135   }
00136   //!used by displayNumber() to determine settings of LEDs when using #numStyle_t::twodigit
00137   void setOneOfTwo(unsigned int x, unsigned int low, unsigned int mid, unsigned int high);
00138   //!used by displayPercent() to determine settings of LEDs
00139   void setColumn(float x, unsigned int low, unsigned int mid, unsigned int high, unsigned int top);
00140 
00141   //!Holds all the information needed by each of the LEDs
00142   struct LEDInfo {
00143     float value;           //!< the current value being expressed
00144     float amp;             //!< the amplitude of the cycle (if cycling)
00145     unsigned int period;    //!< the period of the cycle (if cycling)
00146     unsigned int starttime; //!< the start time of the cycle (if cycling)
00147     float offset;          //!< the phase shift from normal of the cycle (if cycling)
00148     float flashvalue;      //!< the value being 'flashed' (only valid if current time is less than flashtime
00149     unsigned int flashtime; //!< the time the 'flash' should retire
00150     bool isCycling;         //!< true if in cycle mode
00151   };
00152   
00153   LEDInfo infos[NumLEDs]; //!< the information regarding each of the LEDs
00154   unsigned int numCycling;//!< the number of LEDs currently cycling (if non-zero, always dirty)
00155   bool dirty;             //!< true if changes since last updateLEDs
00156   unsigned int dirtyTime; //!< the time at which it becomes dirty again (if flashing)
00157 };
00158   
00159 /*! @file
00160  * @brief Describes LedEngine, which provides basic LED effects to anything that inherits or instantiates it
00161  * @author ejt (Creator)
00162  *
00163  * $Author: ejt $
00164  * $Name: tekkotsu-2_0 $
00165  * $Revision: 1.11 $
00166  * $State: Exp $
00167  * $Date: 2003/12/23 06:33:42 $
00168  */
00169 
00170 #endif

Tekkotsu v2.0
Generated Wed Jan 21 03:20:29 2004 by Doxygen 1.3.4