Simulator.h
Go to the documentation of this file.00001
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
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
00053
00054 static void registerMotionHook(MotionHook& h) {
00055 MarkScope l(theSim ? dynamic_cast<Resource&>(theSim->simLock) : ::emptyResource);
00056 theSim->motionHooks.insert(&h);
00057 }
00058
00059
00060
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&);
00089 MotionMonitorThread& operator=(const MotionMonitorThread&);
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
00097 class FrameCounter : public MessageQueueBase::MessageFilter {
00098 public:
00099 virtual bool filterSendRequest(RCRegion* ) {
00100 globals->motion.frameNumber++;
00101
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&);
00118 CommandThread& operator=(const CommandThread&);
00119 } cmdThread;
00120
00121
00122 template<typename T> void abortable(const T& fn) {
00123 CallbackThread th(fn,false);
00124 cmdThread.runInitThread(th);
00125 }
00126
00127
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
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
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);
00188 static bool gotCommand(RCRegion* msg);
00189 static bool gotMotion(RCRegion* msg);
00190 static bool gotMotionPIDs(RCRegion* msg);
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;
00256 unsigned int fullspeedSimStart;
00257 TimeET lastFrameWallStart;
00258 float avgWallTime;
00259 float avgSimTime;
00260 static const float avgSpeedupGamma;
00261
00262 Thread::Lock simLock;
00263
00264 private:
00265 Simulator(const Simulator&);
00266 Simulator& operator=(const Simulator&);
00267 };
00268
00269
00270
00271
00272
00273
00274 #endif