Homepage Demos Overview Downloads Tutorials Reference
Credits
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members | Related Pages | Search

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   //!Use these to specify a style for displaying numbers using displayNumber()
00082   enum numStyle_t {
00083     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
00084     twodigit  //!< can display a number -99 thru 99, using setOneOfTwo().  For negative numbers, sets the top bar to 1 (off otherwise).
00085   };
00086   //!Use these to specify a style for displaying a percentage value [0-1] using displayPercent()
00087   enum percentStyle_t {
00088     major, //!< shows overall value
00089     minor, //!< shows value within major tick
00090     none   //!< if you want to leave blank
00091   };
00092     
00093   //!Allows convenient display of numerical information to the LEDs on the face.
00094   /*!If overflow occurs, the face LEDs are set to flash on and off 3 every 333 milliseconds*/
00095   void displayNumber(int x, numStyle_t style);
00096   //!Allows convenient display of percentage information to the LEDs on the face.
00097   /*!Besides allowing a two-digit display, the 'edge' bar for each type is blinked to
00098    * denote how full it is.  So you can get up to a two-digit, base 5 display, with an
00099    * extra digit of estimated value.
00100    *
00101    * If overflow (>1) occurs, sets everything to .75. <br>
00102    * If underflow (<0) occurs, sets everything to .25.
00103    * 
00104    * The left and right columns are combined with an OR operation.  (they overlap on the top bar)
00105    * Left and right designations are <em>dog centric!</em> */
00106   void displayPercent(float x, percentStyle_t left_style, percentStyle_t right_style);
00107   
00108  protected:
00109   //!Performs the 'invert' calculation based on current value (returns 1-value)
00110   static float calcInvert(float value) {
00111     return 1-value;
00112   }
00113   //!Performs the 'flash' calculation based on current value (uses calcInvert() if value upper or lower third, 0 or 1 otherwise)
00114   static float calcFlash(float value) {
00115     if(value>.33333 && value<.66666)
00116       return (value<.5 ? 1 : 0);
00117     else
00118       return calcInvert(value);
00119   }
00120   //!Performs the 'cycle' calculation based on desired period, amplituted, amplitude offset, and time since start.  See cycle()
00121   static float calcCycle(unsigned int period, float amp, float offset, unsigned int t) {
00122     //    cout << period << ',' << amp << ',' << offset << ',' << time << " -> " << x;
00123     float x=cos(t*6.2831853/period)*(-amp/2)+.5+offset;
00124     return x;
00125   }
00126   //!Calculates the current value of led @a i for current time t
00127   float calcValue(unsigned int i, unsigned int t) {
00128     if(t<infos[i].flashtime)
00129       return infos[i].flashvalue;
00130     else if(infos[i].isCycling)
00131       return calcCycle(infos[i].period,infos[i].amp,infos[i].offset,t-infos[i].starttime);
00132     else
00133       return infos[i].value;
00134   }
00135   //!used by displayNumber() to determine settings of LEDs when using #numStyle_t::twodigit
00136   void setOneOfTwo(unsigned int x, unsigned int low, unsigned int mid, unsigned int high);
00137   //!used by displayPercent() to determine settings of LEDs
00138   void setColumn(float x, unsigned int low, unsigned int mid, unsigned int high, unsigned int top);
00139 
00140   //!Holds all the information needed by each of the LEDs
00141   struct LEDInfo {
00142     float value;           //!< the current value being expressed
00143     float amp;             //!< the amplitude of the cycle (if cycling)
00144     unsigned int period;    //!< the period of the cycle (if cycling)
00145     unsigned int starttime; //!< the start time of the cycle (if cycling)
00146     float offset;          //!< the phase shift from normal of the cycle (if cycling)
00147     float flashvalue;      //!< the value being 'flashed' (only valid if current time is less than flashtime
00148     unsigned int flashtime; //!< the time the 'flash' should retire
00149     bool isCycling;         //!< true if in cycle mode
00150   };
00151   
00152   LEDInfo infos[NumLEDs]; //!< the information regarding each of the LEDs
00153   unsigned int numCycling;//!< the number of LEDs currently cycling (if non-zero, always dirty)
00154   bool dirty;             //!< true if changes since last updateLEDs
00155   unsigned int dirtyTime; //!< the time at which it becomes dirty again (if flashing)
00156 };
00157   
00158 /*! @file
00159  * @brief Describes LedEngine, which provides basic LED effects to anything that inherits or instantiates it
00160  * @author ejt (Creator)
00161  *
00162  * $Author: ejt $
00163  * $Name: tekkotsu-1_4_1 $
00164  * $Revision: 1.9 $
00165  * $State: Exp $
00166  * $Date: 2003/06/12 18:06:11 $
00167  */
00168 
00169 #endif

Tekkotsu v1.4
Generated Sat Jul 19 00:06:30 2003 by Doxygen 1.3.2