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 // paris start
00055   void GotAudio(const ONotifyEvent& event);            //!< main only, called when a new audio buffer is available
00056 // paris end
00057   void GotPowerEvent(void * msg);                      //!< main only, called when a power event occurs (can be just status events)
00058   
00059   void GotMotionMsg(const ONotifyEvent& event);        //!< both, called when a new MotionManagerMsg has been received
00060   
00061   void GotSoundManager(const ONotifyEvent& event);     //!< both, called when the sndman global is received
00062 
00063   void ListenCont (void* msg) { wireless->ListenCont(msg); }  //!< main only, called when //ALTODO
00064   void BindCont   (void* msg) { wireless->BindCont(msg); }    //!< main only, called when //ALTODO
00065   void ConnectCont(void* msg) { wireless->ConnectCont(msg); } //!< main only, called when //ALTODO
00066   void SendCont   (void* msg) { wireless->SendCont(msg); }    //!< main only, called when //ALTODO
00067   void ReceiveCont(void* msg) { wireless->ReceiveCont(msg); } //!< main only, called when //ALTODO
00068   void CloseCont  (void* msg) { wireless->CloseCont(msg); }   //!< main only, called when //ALTODO
00069 
00070   bool RPOPENR_isReady() { return RPOPENR_isready; }          //!< main only, called when //ALTODO
00071   int RPOPENR_send(char *buf, int bufsize);                   //!< main only, called when //ALTODO
00072   
00073   void RPOPENR_ready(const OReadyEvent& /*event*/) { RPOPENR_isready=true; } //!< main only, called when //ALTODO
00074   void RPOPENR_notify(const ONotifyEvent& event);                            //!< main only, called when //ALTODO
00075  
00076 protected:
00077   void OpenPrimitives();                               //!< both, called from SetupOutputs() (mostly for motion, but main does ears), uses #open to tell which to open
00078   void SetupOutputs(const bool to_open[NumOutputs]);   //!< both, called from DoInit() (mostly for motion, but main does ears)
00079   RCRegion* InitRegion(unsigned int size);             //!< both, called to set up a shared memory region of a given size
00080 
00081   RCRegion * motmanMemRgn;     //!< Motion creates, Main receives
00082   RCRegion * worldStateMemRgn; //!< Main creates, Motion receives
00083   RCRegion * soundManagerMemRgn; //!< SoundPlay creates, Main & Motion receives
00084   RCRegion * eventTranslatorQueueMemRgn; //!< Main creates, Motion (& SoundPlay) receive
00085 
00086   OPrimitiveID primIDs[NumOutputs];    //!< both, Main ears only, Motion the rest
00087   static const unsigned int NUM_COMMAND_VECTOR=2; //!< both, for double buffering
00088   RCRegion*    region[NUM_COMMAND_VECTOR]; //!< both, the actual buffers
00089 
00090   float  ledActivation[NumLEDs]; //!< Motion, used for partial LED activation
00091 
00092   unsigned int runLevel;           //!< Main, incremented until all sections are ready
00093   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())
00094   void addRunLevel();              //!< Main, checks runLevel and creates StartBehavior when ready
00095 
00096   bool open[NumOutputs];    //!< both, holds information regarding which outputs are open in ("controlled by") this process
00097   unsigned int num_open;  //!< both, count of how many are open
00098 
00099   EventTranslator etrans; //!< both, allows events to be sent between processes (from other processes besides these two too)
00100 
00101   bool RPOPENR_isready;  //!< true if we've received a ready message from a remote process
00102 
00103   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
00104 
00105   //! Motion only, maintains the activation level of the LEDs, returns whether it should be 'fired'
00106   inline OLEDValue calcLEDValue(unsigned int i,float x) {
00107     if(x<=0.0) {
00108       ledActivation[i]*=.9; //decay activation... resets to keeps LEDs in sync, looks a little better
00109       return oledOFF;
00110     } else if(x>=1.0) {
00111       return oledON;
00112     } else {
00113       x*=x; // squared to "gamma correct" - we can see a single pulse better than a single flicker - after image and all that
00114       ledActivation[i]+=x;
00115       if(ledActivation[i]>=1.0) {
00116         ledActivation[i]-=1.0;
00117         return oledON;
00118       } else {
00119         return oledOFF;
00120       }           
00121     }
00122   }
00123 
00124   //! returns @a f clipped to be between 0 and 1
00125   inline static float clipRange01(float f) {
00126     if(f>1)
00127       return 1;
00128     if(f<0)
00129       return 0;
00130     return f;
00131   }
00132 
00133 private:
00134 //  WorldStateSerializer* wstateserializer;
00135   MMCombo(const MMCombo&); //!< should never be called...
00136   MMCombo& operator=(const MMCombo&); //!< should never be called...
00137 };
00138 
00139 /*! @file
00140  * @brief Describes MMCombo, the OObject which "forks" (sort of) into Main and Motion processes
00141  * @author ejt (Creator)
00142  *
00143  * $Author: ejt $
00144  * $Name: tekkotsu-2_2_1 $
00145  * $Revision: 1.26 $
00146  * $State: Exp $
00147  * $Date: 2004/09/28 23:07:04 $
00148  */
00149 
00150 #endif
00151 
00152 
00153 
00154 
00155 

Tekkotsu v2.2.1
Generated Tue Nov 23 16:36:39 2004 by Doxygen 1.3.9.1