Homepage Demos Overview Downloads Tutorials Reference
Credits

MMCombo.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_MMCombo_h_
00003 #define INCLUDED_MMCombo_h_
00004 
00005 #include "Shared/debuget.h"
00006 #include "Shared/RobotInfo.h"
00007 #include "Wireless/Wireless.h"
00008 #include "Events/EventTranslator.h"
00009 
00010 #include "MMCombo/entry.h"
00011 #include <OPENR/OObject.h>
00012 #include <OPENR/OSubject.h>
00013 #include <OPENR/OObserver.h>
00014 #include "def.h"
00015 
00016 //! Contains code for both MainObj and MotoObj processes
00017 /*! Why go to all this trouble?  Virtual functions and polymorphism!  Instead
00018  *  of writing my own object typing and serialization system, I would rather
00019  *  just use C++'s.  But function lookups of the run time type information (RTTI)
00020  *  will break unless the object that created the object and the object that's
00021  *  actually calling the function agree on what object A's information is.
00022  *
00023  *  The easiest way to guarantee this is to compile them as one object, and
00024  *  then replace the strings in the source binary with strings for each of
00025  *  the final objects so they'll each have their own identity, but share
00026  *  the same code.
00027  *
00028  *  This is as close as I can get to a "fork", which is what i really want.
00029  */
00030 class MMCombo : public OObject {
00031 public:
00032   //! constructor
00033   MMCombo();
00034   virtual ~MMCombo() {} //!< destructor
00035   
00036   OSubject*    subject[numOfSubject];   //!< holds information for each of our subjects (data we provide)
00037   OObserver*   observer[numOfObserver]; //!< holds information for each of the sources we're observing
00038   
00039   virtual OStatus DoInit   (const OSystemEvent&);      //!< first call (after constructor), set up memory
00040   virtual OStatus DoStart  (const OSystemEvent&);      //!< second call, ask for messages
00041   virtual OStatus DoStop   (const OSystemEvent&);      //!< next to last call, stop sending and receiving messages
00042   virtual OStatus DoDestroy(const OSystemEvent&);      //!< last call (before destructor), clean up memory here
00043   
00044   void ReadyRegisterWorldState(const OReadyEvent&);    //!< main only, send out the state global
00045   void GotWorldState(const ONotifyEvent& event);       //!< motion only, called when state global is received
00046   void ReadyRegisterMotionManager(const OReadyEvent&); //!< motion only, send out motman global
00047   void GotMotionManager(const ONotifyEvent& event);    //!< main only, called when motman global is received
00048   void ReadyRegisterEventTranslatorQueue(const OReadyEvent&);    //!< main only, send out the EventTranslatorQueue
00049   void GotEventTranslatorQueue(const ONotifyEvent& event);       //!< motion only, called when EventTranslatorQueue is received
00050   
00051   void ReadySendJoints(const OReadyEvent& event);      //!< motion only (until main does ears again, then both) calls SendJoints, if DoStart has already been called
00052   void GotSensorFrame(const ONotifyEvent& event);      //!< main only, called when new sensor information is available
00053   void GotImage(const ONotifyEvent& event);            //!< main only, called when a new image is available
00054   void GotPowerEvent(void * msg);                      //!< main only, called when a power event occurs (can be just status events)
00055   
00056   void GotMotionMsg(const ONotifyEvent& event);        //!< both, called when a new MotionManagerMsg has been received
00057   
00058   void GotSoundManager(const ONotifyEvent& event);     //!< both, called when the sndman global is received
00059 
00060   void ListenCont (void* msg) { wireless->ListenCont(msg); }  //!< main only, called when //ALTODO
00061   void BindCont   (void* msg) { wireless->BindCont(msg); }    //!< main only, called when //ALTODO
00062   void ConnectCont(void* msg) { wireless->ConnectCont(msg); } //!< main only, called when //ALTODO
00063   void SendCont   (void* msg) { wireless->SendCont(msg); }    //!< main only, called when //ALTODO
00064   void ReceiveCont(void* msg) { wireless->ReceiveCont(msg); } //!< main only, called when //ALTODO
00065   void CloseCont  (void* msg) { wireless->CloseCont(msg); }   //!< main only, called when //ALTODO
00066 
00067   bool RPOPENR_isReady() { return RPOPENR_isready; }          //!< main only, called when //ALTODO
00068   int RPOPENR_send(char *buf, int bufsize);                   //!< main only, called when //ALTODO
00069   
00070   void RPOPENR_ready(const OReadyEvent& /*event*/) { RPOPENR_isready=true; } //!< main only, called when //ALTODO
00071   void RPOPENR_notify(const ONotifyEvent& event);                            //!< main only, called when //ALTODO
00072  
00073 protected:
00074   void OpenPrimitives();                               //!< both, called from SetupOutputs() (mostly for motion, but main does ears), uses #open to tell which to open
00075   void SetupOutputs(const bool to_open[NumOutputs]);   //!< both, called from DoInit() (mostly for motion, but main does ears)
00076   RCRegion* InitRegion(unsigned int size);             //!< both, called to set up a shared memory region of a given size
00077 
00078   RCRegion * motmanMemRgn;     //!< Motion creates, Main receives
00079   RCRegion * worldStateMemRgn; //!< Main creates, Motion receives
00080   RCRegion * soundManagerMemRgn; //!< SoundPlay creates, Main & Motion receives
00081   RCRegion * eventTranslatorQueueMemRgn; //!< Main creates, Motion (& SoundPlay) receive
00082 
00083   OPrimitiveID primIDs[NumOutputs];    //!< both, Main ears only, Motion the rest
00084   static const unsigned int NUM_COMMAND_VECTOR=2; //!< both, for double buffering
00085   RCRegion*    region[NUM_COMMAND_VECTOR]; //!< both, the actual buffers
00086 
00087   float  ledActivation[NumLEDs]; //!< Motion, used for partial LED activation
00088 
00089   unsigned int runLevel;           //!< Main, incremented until all sections are ready
00090   static const unsigned int readyLevel=5; //!< Main, runLevel at which StartBehavior is created. (1st power event, 1st sensor event, motman init, sndman init, MainObj::DoStart())
00091   void addRunLevel();              //!< Main, checks runLevel and creates StartBehavior when ready
00092 
00093   bool open[NumOutputs];    //!< both, holds information regarding which outputs are open in ("controlled by") this process
00094   unsigned int num_open;  //!< both, count of how many are open
00095 
00096   EventTranslator etrans; //!< both, allows events to be sent between processes (from other processes besides these two too)
00097 
00098   bool RPOPENR_isready;  //!< true if we've received a ready message from a remote process
00099 
00100   bool isStopped; //!< true if we've received a DoStart and no DoStop - we need this because sometimes an extra message seems to slip in after we've been told to stop, in which case we should ignore it
00101 
00102   //! Motion only, maintains the activation level of the LEDs, returns whether it should be 'fired'
00103   inline OLEDValue calcLEDValue(unsigned int i,float x) {
00104     if(x<=0.0) {
00105       ledActivation[i]*=.9; //decay activation... resets to keeps LEDs in sync, looks a little better
00106       return oledOFF;
00107     } else if(x>=1.0) {
00108       return oledON;
00109     } else {
00110       x*=x; // squared to "gamma correct" - we can see a single pulse better than a single flicker - after image and all that
00111       ledActivation[i]+=x;
00112       if(ledActivation[i]>=1.0) {
00113         ledActivation[i]-=1.0;
00114         return oledON;
00115       } else {
00116         return oledOFF;
00117       }           
00118     }
00119   }
00120 
00121   //! returns @a f clipped to be between 0 and 1
00122   inline static float clipRange01(float f) {
00123     if(f>1)
00124       return 1;
00125     if(f<0)
00126       return 0;
00127     return f;
00128   }
00129 
00130 private:
00131 //  WorldStateSerializer* wstateserializer;
00132   MMCombo(const MMCombo&); //!< should never be called...
00133   MMCombo& operator=(const MMCombo&); //!< should never be called...
00134 };
00135 
00136 /*! @file
00137  * @brief Describes MMCombo, the OObject which "forks" (sort of) into Main and Motion processes
00138  * @author ejt (Creator)
00139  *
00140  * $Author: ejt $
00141  * $Name: tekkotsu-2_1 $
00142  * $Revision: 1.25 $
00143  * $State: Exp $
00144  * $Date: 2004/02/03 01:17:24 $
00145  */
00146 
00147 #endif
00148 
00149 
00150 
00151 
00152 

Tekkotsu v2.1
Generated Tue Mar 16 23:19:14 2004 by Doxygen 1.3.5