Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

Simulator.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_Simulator_h_
00003 #define INCLUDED_Simulator_h_
00004 
00005 #include "Process.h"
00006 #include "sim.h"
00007 #include "IPC/SharedObject.h"
00008 #include "IPC/MessageQueueStatusThread.h"
00009 #include "Sound/SoundManager.h"
00010 #include "SharedGlobals.h"
00011 #include "Shared/plist.h"
00012 #include "Shared/RobotInfo.h"
00013 #include "Shared/debuget.h"
00014 #include "local/MotionHook.h"
00015 #include "IPC/CallbackThread.h"
00016 #include "IPC/PollThread.h"
00017 #include <set>
00018 
00019 class MessageReceiver;
00020 class DeviceDriver;
00021 
00022 class Simulator : public Process,  public plist::PrimitiveListener, public plist::CollectionListener, public MessageQueueStatusThread::StatusListener {
00023 public:
00024   //! constructor
00025   Simulator();
00026   
00027   ~Simulator();
00028 
00029   virtual void doStart();
00030   virtual void doStop();
00031   virtual void run();
00032   
00033   static const char * getClassName() { return "Simulator"; }
00034   static ProcessID::ProcessID_t getID() { return ProcessID::SimulatorProcess; }
00035   
00036   static const char * getCameraQueueID() { return "CameraData"; }
00037   static const char * getSensorQueueID() { return "SensorData"; }
00038   static const char * getTimerWakeupID() { return "TimerWakeup"; }
00039   static const char * getMotionWakeupID() { return "MotionWakeup"; }
00040   static const char * getStatusRequestID() { return "StatusRequest"; }
00041   static const char * getCommandQueueID() { return "CommandQueue"; }
00042   
00043   virtual void plistValueChanged(const plist::PrimitiveBase& pl);
00044   virtual void plistCollectionEntryAdded(plist::Collection& col, plist::ObjectBase& primitive);
00045   virtual void plistCollectionEntryRemoved(plist::Collection& col, plist::ObjectBase& primitive);
00046   virtual void plistCollectionEntriesChanged(plist::Collection& col);
00047     
00048   virtual void messagesRead(MessageQueueBase& mq, unsigned int n);
00049   
00050   static void sendCommand(const std::string& cmd);
00051   
00052   //! Registers the MotionHook to have its motionCheck() called following each motion update.
00053   /*! Responsibility for memory (de)allocation is NOT assumed by registration. */
00054   static void registerMotionHook(MotionHook& h) {
00055     MarkScope l(theSim ? dynamic_cast<Resource&>(theSim->simLock) : ::emptyResource);
00056     theSim->motionHooks.insert(&h);
00057   }
00058   
00059   //! Removes the MotionHook from the list, no longer receives any notifications
00060   /*! Responsibility for memory (de)allocation is NOT assumed by registration, so this doesn't affect @a h directly. */
00061   static void deregisterMotionHook(MotionHook& h) {
00062     MarkScope l(theSim ? dynamic_cast<Resource&>(theSim->simLock) : ::emptyResource);
00063     theSim->motionHooks.erase(&h);
00064   }
00065   
00066   static void clearMotionHooks() {
00067     MarkScope l(theSim ? dynamic_cast<Resource&>(theSim->simLock) : ::emptyResource);
00068     theSim->motionHooks.clear();
00069   }
00070   
00071   static void setMotionStarting();
00072   static void setMotionStopping();
00073   static void updateMotion(const float outputs[][NumOutputs]);
00074   static void updatePIDs(const std::vector<MotionHook::PIDUpdate>& pids);
00075   static void setMotionLeavingRealtime(bool isFullSpeed);
00076   static void setMotionEnteringRealtime();
00077   
00078   class MotionMonitorThread : public Thread {
00079   public:
00080     MotionMonitorThread() : Thread(), curHook(NULL), curFuncName(NULL), motionCheckTime() { start(); }
00081     MotionHook * curHook;
00082     const char * curFuncName;
00083     TimeET motionCheckTime;
00084   protected:
00085     static const TimeET timeout;
00086     virtual unsigned int runloop();
00087   private:
00088     MotionMonitorThread(const MotionMonitorThread&);  //!< dummy
00089     MotionMonitorThread& operator=(const MotionMonitorThread&);  //!< dummy
00090   };
00091   static MotionMonitorThread * motionHookMonitor;
00092   
00093 protected:
00094   static void replaceEntry(const std::string& name, plist::Dictionary& d, const std::string& comment);
00095   
00096   //! subscribed by Simulator to message queue's send; ensures that SharedGlobals::MotionSimConfig::frameNumber stays in sync with the message serial number
00097   class FrameCounter : public MessageQueueBase::MessageFilter {
00098   public:
00099     virtual bool filterSendRequest(RCRegion* /*rcr*/) {
00100       globals->motion.frameNumber++;
00101       //ASSERT(globals->motion.frameNumber==LoadFileThread::recoverSN(rcr),"globals->motion.frameNumber does not match frame number sent! (" << globals->motion.frameNumber << " vs " << LoadDataThread::recoverSN(rcr));
00102       return true;
00103     }
00104   } frameCounter;
00105   
00106   class CommandThread : public Thread {
00107   public:
00108     CommandThread() : Thread(), initThreadsLock(), initThreads() {}
00109     ~CommandThread();
00110     virtual void * run();
00111     virtual void runInitThread(Thread& th);
00112     virtual void abortInitThreads();
00113   protected:
00114     Thread::Lock initThreadsLock;
00115     std::set<Thread*> initThreads;
00116   private:
00117     CommandThread(const CommandThread&); //!< do not call
00118     CommandThread& operator=(const CommandThread&); //!< do not call
00119   } cmdThread;
00120   
00121   //! blocks until the thread is either aborted by the user via cmdThread (i.e. shutdown) or completes successfully
00122   template<typename T> void abortable(const T& fn) {
00123     CallbackThread th(fn,false);
00124     cmdThread.runInitThread(th);
00125   }
00126   
00127   //! blocks until the thread is either aborted by the user via cmdThread (i.e. shutdown) or completes successfully
00128   template<typename T,typename C> void abortable(const T& fn, C& userdata) {
00129     CallbackThread th(fn,userdata,false);
00130     cmdThread.runInitThread(th);
00131   }
00132   
00133   //! blocks until the thread is either aborted by the user via cmdThread (i.e. shutdown) or completes successfully
00134   template<typename T,typename C> void abortable(const T& fn, const C& userdata) {
00135     CallbackThread th(fn,userdata,false);
00136     cmdThread.runInitThread(th);
00137   }
00138   
00139   class SyncDataThread : virtual public plist::PrimitiveListener, public PollThread {
00140   public:
00141     typedef bool (Simulator::*callback_t)(bool);
00142     SyncDataThread(Simulator* p, callback_t func) : plist::PrimitiveListener(), PollThread(0.f, 1.0/globals->sensors.framerate, true), process(p), callback(func) {}
00143     void sync() { (process->*callback)(true); }
00144   protected:
00145     virtual bool launched() {
00146       interrupted();
00147       globals->sensors.framerate.addPrimitiveListener(this);
00148       globals->timeScale.addPrimitiveListener(this);
00149       return PollThread::launched();
00150     }
00151     virtual void cancelled() {
00152       globals->sensors.framerate.removePrimitiveListener(this);
00153       globals->timeScale.removePrimitiveListener(this);
00154     }
00155     virtual bool poll() { (process->*callback)(false); return true; }
00156     virtual void interrupted() { delay = period = (1.0/globals->sensors.framerate) / globals->timeScale; }
00157     virtual void plistValueChanged(const plist::PrimitiveBase&) { interrupt(); }
00158     Simulator* process;
00159     callback_t callback;
00160   private:
00161     SyncDataThread(const SyncDataThread&);
00162     SyncDataThread& operator=(const SyncDataThread&);
00163   };
00164   SyncDataThread sensorThread;
00165   bool sendSensorSent;
00166 
00167   bool sendSensor(bool syncCall);
00168   unsigned int nextVisionTime();
00169   unsigned int nextSensorTime();
00170   //! this is registered as a callback with DataSource::resourceSync so we send notifications immediately following updates, cutting latency
00171   static void syncSensors() { theSim->sensorThread.sync(); }
00172   
00173   enum step_t {
00174     STEP_NONE,
00175     STEP_CAMERA,
00176     STEP_SENSOR,
00177     STEP_TIMER,
00178     STEP_MOTION
00179   };
00180   
00181   void incrementTime();
00182   void sendTimerWakeup();
00183   unsigned int getNextFrame();
00184   void resetSpeedMode();
00185   
00186   void processRunlevel(SharedGlobals::runlevel_t curRunLevel);
00187   bool processCommand(const std::string& line, bool addToHistory); //!< process an individual command
00188   static bool gotCommand(RCRegion* msg); //!< for commands coming from other processes via #commandQueue and #commandrecv
00189   static bool gotMotion(RCRegion* msg); //!< when running in multi-process mode, receives output value updates from motion process
00190   static bool gotMotionPIDs(RCRegion* msg); //!< when running in multi-process mode, receives output PID updates from motion process
00191   
00192   typedef void (DeviceDriver::*getDataSources_t)(std::map<std::string,DataSource*>&);
00193   void updateDataSources(std::set<std::string>& active, std::set<DataSource*>& activeSrcs, const plist::ArrayOf<plist::Primitive<std::string> >& requested, getDataSources_t getDataSources);
00194   void lookupDataSource(const std::string& name, getDataSources_t getDataSources, std::set<DataSource*>& dataSrcs, std::string& errStr);
00195   std::string lookupDataSourceName(const DataSource* src) const;
00196   
00197   void cmdQuit(const std::vector<std::string>& args);
00198   void cmdLoad(const std::vector<std::string>& args);
00199   void cmdSave(const std::vector<std::string>& args);
00200   void cmdRunlevel(const std::vector<std::string>& args);
00201   bool cmdPrint(const std::vector<std::string>& args);
00202   bool cmdSet(const std::vector<std::string>& args);
00203   void cmdRun(const std::vector<std::string>& args, bool isRelative);
00204   void cmdRun(const std::vector<std::string>& args);
00205   void cmdPause(const std::vector<std::string>& args);
00206   void cmdHelp(const std::vector<std::string>& args);
00207   void cmdStep(const std::vector<std::string>& args);
00208   void cmdStatus(const std::vector<std::string>& args);
00209   void cmdAdvance(const std::vector<std::string>& args);
00210   void cmdFreeze(bool v, const std::vector<std::string>& args);
00211   void cmdReset(const std::vector<std::string>& args);
00212   void cmdNew(const std::vector<std::string>& args);
00213   void cmdDelete(const std::vector<std::string>& args);
00214   void cmdPost(const std::vector<std::string>& args);
00215   void cmdMsg(const std::vector<std::string>& args);
00216   
00217   SharedObject<sim::CameraQueue_t> cameraQueue;
00218   SharedObject<sim::SensorQueue_t> sensorQueue;
00219   SharedObject<sim::TimerWakeup_t> timerWakeup;
00220   SharedObject<sim::MotionWakeup_t> motionWakeup;
00221   SharedObject<sim::StatusRequest_t> statusRequest;
00222   SharedObject<SoundManager> soundmanager;
00223   SharedObject<sim::SoundPlayQueue_t> sounds;
00224   SharedObject<sim::EventQueue_t> events;
00225   SharedObject<sim::MotionOutput_t> motionout;
00226   SharedObject<sim::MotionOutputPIDs_t> motionoutpids;
00227   typedef MessageQueue<10> CommandQueue_t;
00228   SharedObject<CommandQueue_t> commandQueue;
00229   
00230   MessageQueueStatusThread cameraStatus;
00231   MessageQueueStatusThread sensorStatus;
00232   MessageQueueStatusThread timerStatus;
00233   MessageQueueStatusThread motionStatus;
00234   MessageQueueStatusThread eventsStatus;
00235 
00236   IPCEventTranslator * etrans;
00237   MessageReceiver * commandrecv;
00238   MessageReceiver * motionrecv;
00239   MessageReceiver * motionpidsrecv;
00240   
00241   static Simulator* theSim;
00242   std::set<unsigned int> frameTimes;
00243   double runSpeed;
00244   double lastTimeScale;
00245   step_t step;
00246   unsigned int waitingSteps;
00247   SharedGlobals::runlevel_t curLevel;
00248   
00249   static std::set<MotionHook*> motionHooks;
00250   std::set<std::string> activeSensors;
00251   std::set<DataSource*> activeSensorSrcs;
00252   std::set<std::string> activeCameras;
00253   std::set<DataSource*> activeCameraSrcs;
00254     
00255   TimeET fullspeedWallStart; //!< "real" wall-clock time that full-speed mode was entered
00256   unsigned int fullspeedSimStart; //!< simulator time at which full-speed mode was entered
00257   TimeET lastFrameWallStart; //!< "real" wall-clock time that processing started on last frame (only valid in full-speed mode)
00258   float avgWallTime; //!< running average of frame processing time
00259   float avgSimTime; //!< running average of frame increments
00260   static const float avgSpeedupGamma; //!< gamma parameter for calculating running average in #avgWallTime and #avgSimTime
00261   
00262   Thread::Lock simLock;
00263   
00264 private:
00265   Simulator(const Simulator&); //!< don't call (copy constructor)
00266   Simulator& operator=(const Simulator&); //!< don't call (assignment operator)
00267 };
00268 
00269 /*! @file
00270  * @brief Defines Simulator, which DESCRIPTION
00271  * @author ejt (Creator)
00272  */
00273 
00274 #endif

Tekkotsu Hardware Abstraction Layer 5.1CVS
Generated Mon May 9 05:01:39 2016 by Doxygen 1.6.3