Homepage | Demos | Overview | Downloads | Tutorials | Reference | Credits |
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 return oledOFF; 00106 } else if(x>=1.0) { 00107 return oledON; 00108 } else { 00109 x*=x; // squared to "gamma correct" - we can see a single pulse better than a single flicker - after image and all that 00110 ledActivation[i]+=x; 00111 if(ledActivation[i]>=1.0) { 00112 ledActivation[i]-=1.0; 00113 return oledON; 00114 } else { 00115 return oledOFF; 00116 } 00117 } 00118 } 00119 00120 //! returns @a f clipped to be between 0 and 1 00121 inline static float clipRange01(float f) { 00122 if(f>1) 00123 return 1; 00124 if(f<0) 00125 return 0; 00126 return f; 00127 } 00128 00129 private: 00130 // WorldStateSerializer* wstateserializer; 00131 MMCombo(const MMCombo&); //!< should never be called... 00132 MMCombo& operator=(const MMCombo&); //!< should never be called... 00133 }; 00134 00135 /*! @file 00136 * @brief Describes MMCombo, the OObject which "forks" (sort of) into Main and Motion processes 00137 * @author ejt (Creator) 00138 * 00139 * $Author: ejt $ 00140 * $Name: tekkotsu-2_0 $ 00141 * $Revision: 1.24 $ 00142 * $State: Exp $ 00143 * $Date: 2004/01/18 10:16:57 $ 00144 */ 00145 00146 #endif 00147 00148 00149 00150 00151
Tekkotsu v2.0 |
Generated Wed Jan 21 03:20:29 2004 by Doxygen 1.3.4 |