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