00001 #include "Simulator.h"
00002 #include "Main.h"
00003 #include "Motion.h"
00004 #include "SoundPlay.h"
00005 #include "sim.h"
00006 #include "Shared/string_util.h"
00007 #include "Shared/RobotInfo.h"
00008 #include "SimConfig.h"
00009 #include "Shared/debuget.h"
00010 #include "Shared/MarkScope.h"
00011 #include "IPC/MessageReceiver.h"
00012 #include "IPC/RegionRegistry.h"
00013 #include "IPC/FailsafeThread.h"
00014 #include "local/DataSources/FileSystemDataSource.h"
00015 #include "local/DataSources/FileSystemImageSource.h"
00016 #include "local/CommPort.h"
00017 #include "local/DeviceDriver.h"
00018 #include "Events/EventRouter.h"
00019 #include "Events/TextMsgEvent.h"
00020 #include "Motion/PostureEngine.h"
00021 #include "local/DataSources/SensorStateAccessor.h"
00022
00023 #include <iostream>
00024 #include <iterator>
00025 #include <libxml/tree.h>
00026
00027 #ifndef DISABLE_READLINE
00028 # include <readline/readline.h>
00029 # include <readline/history.h>
00030 # include <dlfcn.h>
00031 #endif
00032
00033 using namespace std;
00034
00035 const float Simulator::avgSpeedupGamma=.99f;
00036
00037 Simulator::MotionMonitorThread * Simulator::motionHookMonitor=NULL;
00038 Simulator* Simulator::theSim=NULL;
00039 std::set<MotionHook*> Simulator::motionHooks;
00040
00041 Simulator::Simulator()
00042 : Process(getID(),getClassName()), plist::PrimitiveListener(), plist::CollectionListener(), MessageQueueStatusThread::StatusListener(),
00043 frameCounter(), cmdThread(),
00044 sensorThread(this,&Simulator::sendSensor), sendSensorSent(false),
00045 cameraQueue(ipc_setup->registerRegion(Simulator::getCameraQueueID(),sizeof(sim::CameraQueue_t))),
00046 sensorQueue(ipc_setup->registerRegion(Simulator::getSensorQueueID(),sizeof(sim::SensorQueue_t))),
00047 timerWakeup(ipc_setup->registerRegion(Simulator::getTimerWakeupID(),sizeof(sim::TimerWakeup_t))),
00048 motionWakeup(ipc_setup->registerRegion(Simulator::getMotionWakeupID(),sizeof(sim::MotionWakeup_t))),
00049 statusRequest(ipc_setup->registerRegion(Simulator::getStatusRequestID(),sizeof(sim::StatusRequest_t))),
00050 soundmanager(ipc_setup->registerRegion(SoundPlay::getSoundManagerID(),sizeof(SoundManager))),
00051 sounds(ipc_setup->registerRegion(SoundPlay::getSoundPlayID(),sizeof(sim::SoundPlayQueue_t))),
00052 events(ipc_setup->registerRegion(Main::getEventsID(),sizeof(sim::EventQueue_t))),
00053 motionout(ipc_setup->registerRegion(Motion::getMotionOutputID(),sizeof(sim::MotionOutput_t))),
00054 motionoutpids(ipc_setup->registerRegion(Motion::getMotionOutputPIDsID(),sizeof(sim::MotionOutputPIDs_t))),
00055 commandQueue(ipc_setup->registerRegion(Simulator::getCommandQueueID(),sizeof(CommandQueue_t))),
00056 cameraStatus(*cameraQueue), sensorStatus(*sensorQueue), timerStatus(*timerWakeup), motionStatus(*motionWakeup), eventsStatus(), etrans(NULL), commandrecv(NULL), motionrecv(NULL), motionpidsrecv(NULL),
00057 frameTimes(), runSpeed(1), lastTimeScale(0), step(STEP_NONE), waitingSteps(0), curLevel(SharedGlobals::CONSTRUCTING),
00058 activeSensors(), activeSensorSrcs(), activeCameras(), activeCameraSrcs(),
00059 fullspeedWallStart(), fullspeedSimStart(), lastFrameWallStart(), avgWallTime(), avgSimTime(),
00060 simLock()
00061 {
00062 theSim=this;
00063 new (&(*cameraQueue)) sim::CameraQueue_t;
00064 new (&(*sensorQueue)) sim::SensorQueue_t;
00065 new (&(*timerWakeup)) sim::TimerWakeup_t;
00066 new (&(*motionWakeup)) sim::MotionWakeup_t;
00067 new (&(*statusRequest)) sim::StatusRequest_t;
00068 new (&(*commandQueue)) CommandQueue_t;
00069 statusRequest->setOverflowPolicy(MessageQueueBase::WAIT);
00070 commandQueue->setOverflowPolicy(MessageQueueBase::WAIT);
00071 sndman=&(*soundmanager);
00072
00073 DataSource::setSensorFramerate(&globals->sensors.framerate);
00074
00075
00076
00077
00078 sim::config.setSavePolicy(plist::Collection::UNION);
00079
00080 sim::config.writeParseTree();
00081
00082 replaceEntry("CommPorts",CommPort::getRegistry(),"Communication portals for use by device drivers");
00083
00084 sim::config.readParseTree();
00085
00086 replaceEntry("Drivers",DeviceDriver::getRegistry(),"Settings for device drivers");
00087
00088 sim::config.setUnusedWarning(true);
00089
00090 sim::config.readParseTree();
00091
00092 sim::config.setSavePolicy(plist::Collection::SYNC);
00093
00094 motionWakeup->setOverflowPolicy(MessageQueueBase::DROP_OLDEST);
00095 timerWakeup->setOverflowPolicy(MessageQueueBase::DROP_OLDEST);
00096 cameraQueue->setOverflowPolicy(MessageQueueBase::DROP_OLDEST);
00097 sensorQueue->setOverflowPolicy(MessageQueueBase::DROP_OLDEST);
00098 sensorQueue->addMessageFilter(frameCounter);
00099
00100
00101 list<vector<string> > delayed;
00102 for(unsigned int i=0; i<sim::cmdlineArgs.size(); i++) {
00103
00104 if(sim::cmdlineArgs[i].find(".Source=")!=string::npos) {
00105 vector<string> setarg;
00106 setarg.push_back("set");
00107 setarg.push_back(sim::cmdlineArgs[i]);
00108 delayed.push_back(setarg);
00109 } else if(sim::cmdlineArgs[i].find(".CommPort=")!=string::npos) {
00110 vector<string> setarg;
00111 setarg.push_back("set");
00112 setarg.push_back(sim::cmdlineArgs[i]);
00113 delayed.push_front(setarg);
00114 } else {
00115 if(!processCommand(sim::cmdlineArgs[i],false))
00116 cerr << "Occurred while processing " << sim::cmdlineArgs[i] << endl;
00117 }
00118 }
00119 for(list<vector<string> >::const_iterator it=delayed.begin(); it!=delayed.end(); ++it) {
00120
00121
00122 if(!cmdSet(*it))
00123 cerr << "Occurred while processing " << (*it)[1] << endl;
00124 }
00125
00126
00127 if(globals->timeScale<=0)
00128 globals->resetBootTime();
00129
00130
00131 if(globals->motion.startPose.size()>0) {
00132 PostureEngine pose(globals->motion.startPose);
00133 for(unsigned int i=0; i<NumOutputs; ++i)
00134 state->outputs[i]=globals->sensorState.outputs[i]=pose(i).value;
00135 }
00136
00137 globals->motion.verbose.addPrimitiveListener(this);
00138 globals->sensors.sources.addCollectionListener(this);
00139 globals->vision.sources.addCollectionListener(this);
00140
00141
00142 cmdThread.start();
00143
00144 if(sim::config.tgtRunlevel>SharedGlobals::RUNNING)
00145 globals->signalShutdown();
00146 processRunlevel(SharedGlobals::CONSTRUCTING);
00147 }
00148
00149 Simulator::~Simulator() {
00150 curLevel=SharedGlobals::DESTRUCTING;
00151 globals->vision.sources.clear();
00152 globals->sensors.sources.clear();
00153 DeviceDriver::getRegistry().clear();
00154 CommPort::getRegistry().clear();
00155 DeviceDriver::getRegistry().removeCollectionListener(this);
00156 globals->motion.verbose.removePrimitiveListener(this);
00157 globals->vision.sources.removeCollectionListener(this);
00158 globals->sensors.sources.removeCollectionListener(this);
00159 globals->sensorState.resourceSync = NULL;
00160 DataSource::setSensorFramerate(NULL);
00161 processRunlevel(SharedGlobals::DESTRUCTING);
00162
00163 theSim=NULL;
00164 }
00165
00166 static void driversChangedFunctor(Simulator* s) { s->plistCollectionEntriesChanged(DeviceDriver::getRegistry()); }
00167
00168 void Simulator::doStart() {
00169 curLevel=SharedGlobals::STARTING;
00170 Process::doStart();
00171
00172 sndman->InitAccess(*sounds);
00173
00174 motionHookMonitor = new MotionMonitorThread;
00175
00176 eventsStatus.setMessageQueue(*events);
00177 if(!sim::config.multiprocess) {
00178
00179 EventTranslator * forwardTrans = new IPCEventTranslator(*events);
00180 forwardTrans->setTrapEventValue(true);
00181 erouter->setForwardingAgent(getID(),forwardTrans);
00182 } else {
00183 etrans=new IPCEventTranslator(*events);
00184 MotionManager::setTranslator(etrans);
00185
00186
00187
00188 for(unsigned int i=0; i<EventBase::numEGIDs; i++)
00189 if(i!=EventBase::erouterEGID)
00190 erouter->addTrapper(etrans,static_cast<EventBase::EventGeneratorID_t>(i));
00191 }
00192 commandrecv = new MessageReceiver(*commandQueue, gotCommand);
00193
00194
00195 DeviceDriver::getRegistry().addCollectionListener(this);
00196
00197
00198 abortable(&driversChangedFunctor,this);
00199
00200 processRunlevel(SharedGlobals::STARTING);
00201 }
00202
00203 void Simulator::run() {
00204 curLevel=SharedGlobals::RUNNING;
00205 if(sim::config.multiprocess) {
00206 for(unsigned int i=0; i<ProcessID::NumProcesses; ++i)
00207 cout << globals->processNames[i] << " pid=" << globals->pids[i] << "; ";
00208 cout << endl;
00209 }
00210
00211 motionrecv = new MessageReceiver(*motionout, gotMotion);
00212 motionpidsrecv = new MessageReceiver(*motionoutpids, gotMotionPIDs);
00213
00214 if(globals->timeScale!=0)
00215 runSpeed=globals->timeScale;
00216
00217 DataSource::setNeedsSensor(globals->waitForSensors);
00218 if(!globals->waitForSensors) {
00219 resetSpeedMode();
00220 } else {
00221 globals->waitForSensors.addPrimitiveListener(this);
00222 if(globals->sensors.sources.size()==0) {
00223 cout << "WARNING: Ignoring WaitForSensors configuration flag because Sensors has no sources" << endl;
00224 globals->signalHaveSensors();
00225 resetSpeedMode();
00226 } else if(0==std::count_if(motionHooks.begin(),motionHooks.end(),std::mem_fun(&MotionHook::isConnected))) {
00227 cout << "WARNING: Ignoring WaitForSensors configuration flag because there are no connected MotionHooks" << endl;
00228 globals->signalHaveSensors();
00229 resetSpeedMode();
00230 } else {
00231 if(activeSensorSrcs.size()==0) {
00232 std::cout << "WARNING: WaitForSensors is true, but all Sensors.Sources are invalid (";
00233 for(plist::ArrayOf<plist::Primitive<std::string> >::const_iterator it=globals->sensors.sources.begin(); it!=globals->sensors.sources.end(); ++it) {
00234 if(it!=globals->sensors.sources.begin())
00235 std::cout << ", ";
00236 std::cout << **it;
00237 }
00238 std::cout << ")\n Instantiate the missing drivers, or set WaitForSensors=false to continue." << std::endl;
00239 }
00240 if(globals->timeScale>0) {
00241 resetSpeedMode();
00242 abortable(&SharedGlobals::waitSensors,*globals);
00243 } else {
00244 for(std::set<DataSource*>::const_iterator it=activeSensorSrcs.begin(); it!=activeSensorSrcs.end(); ++it)
00245 abortable(&DataSource::advance,**it);
00246 sendSensorSent=false;
00247 sendSensor(true);
00248 while(!globals->haveSensors() && !globals->isShutdown()) {
00249 CallbackThread w4s(&SharedGlobals::waitSensors,*globals,true);
00250 FailsafeThread fs(w4s,0.5,true);
00251 if(w4s.join()==Thread::CANCELLED && 0==std::count_if(motionHooks.begin(),motionHooks.end(),std::mem_fun(&MotionHook::isConnected))) {
00252 cout << "WARNING: Ignoring WaitForSensors configuration flag because there are no longer any connected MotionHooks" << endl;
00253 globals->signalHaveSensors();
00254 }
00255 }
00256 resetSpeedMode();
00257 }
00258 }
00259 globals->waitForSensors.removePrimitiveListener(this);
00260 }
00261 DataSource::setNeedsSensor(false);
00262
00263 if(globals->timeScale<0)
00264 incrementTime();
00265 globals->timeScale.addPrimitiveListener(this);
00266
00267 if(sim::config.tgtRunlevel==SharedGlobals::RUNNING)
00268 Process::run();
00269
00270 globals->timeScale.removePrimitiveListener(this);
00271 if(globals->timeScale<0) {
00272 motionStatus.removeStatusListener(this);
00273 timerStatus.removeStatusListener(this);
00274 sensorStatus.removeStatusListener(this);
00275 cameraStatus.removeStatusListener(this);
00276 }
00277 if(sensorThread.isStarted())
00278 sensorThread.stop().join();
00279 if(globals->timeScale!=0)
00280 setMotionLeavingRealtime(false);
00281 globals->signalShutdown();
00282 }
00283
00284 void Simulator::plistValueChanged(const plist::PrimitiveBase& pl) {
00285 MarkScope l(simLock);
00286 if(&pl==&globals->timeScale) {
00287 get_time();
00288 resetSpeedMode();
00289 if(globals->timeScale<0)
00290 incrementTime();
00291 timerWakeup->sendMessage(NULL);
00292 motionWakeup->sendMessage(NULL);
00293 } else if(&pl==&globals->motion.verbose) {
00294 for(std::set<MotionHook*>::iterator it=motionHooks.begin(); it!=motionHooks.end(); ++it)
00295 (*it)->setMotionHookVerbose(globals->motion.verbose);
00296 } else if(&pl==&globals->waitForSensors) {
00297 cout << "Aborting block on WaitForSensors flag" << endl;
00298 DataSource::setNeedsSensor(false);
00299 globals->signalHaveSensors();
00300 } else if(std::count(globals->sensors.sources.begin(),globals->sensors.sources.end(),&pl)) {
00301 updateDataSources(activeSensors, activeSensorSrcs, globals->sensors.sources, &DeviceDriver::getSensorSources);
00302 } else if(std::count(globals->vision.sources.begin(),globals->vision.sources.end(),&pl)) {
00303 updateDataSources(activeCameras, activeCameraSrcs, globals->vision.sources, &DeviceDriver::getImageSources);
00304 } else {
00305 cerr << "WARNING: Simulator got a plistValueChanged for an unknown plist primitive";
00306 }
00307 }
00308 void Simulator::plistCollectionEntryAdded(plist::Collection& col, plist::ObjectBase& primitive) {
00309 MarkScope l(simLock);
00310 if(&col==&DeviceDriver::getRegistry()) {
00311 if(DeviceDriver * d=dynamic_cast<DeviceDriver*>(&primitive)) {
00312 if(MotionHook * mh = d->getMotionSink()) {
00313 motionHookMonitor->motionCheckTime.Set();
00314 ASSERT(motionHooks.find(mh)==motionHooks.end(),"new DeviceDriver already has active MotionHook?");
00315 mh->setMotionHookVerbose(globals->motion.verbose);
00316 if(curLevel==SharedGlobals::RUNNING || curLevel==SharedGlobals::STARTING) {
00317 motionHookMonitor->curFuncName="motionStarting()"; motionHookMonitor->curHook=mh;
00318 mh->motionStarting();
00319 motionHookMonitor->curHook=NULL;
00320 }
00321 if(curLevel==SharedGlobals::RUNNING) {
00322 if(globals->timeScale>0) {
00323 motionHookMonitor->curFuncName="enteringRealtime()"; motionHookMonitor->curHook=mh;
00324 mh->enteringRealtime(globals->timeScale);
00325 } else {
00326 motionHookMonitor->curFuncName="leavingRealtime()"; motionHookMonitor->curHook=mh;
00327 mh->leavingRealtime(globals->timeScale<0);
00328 }
00329 motionHookMonitor->curHook=NULL;
00330 }
00331 motionHooks.insert(mh);
00332 }
00333 } else {
00334 cerr << "WARNING: Simulator got a plistCollectionEntryAdded for an unknown primitive type";
00335 }
00336 updateDataSources(activeSensors, activeSensorSrcs, globals->sensors.sources, &DeviceDriver::getSensorSources);
00337 updateDataSources(activeCameras, activeCameraSrcs, globals->vision.sources, &DeviceDriver::getImageSources);
00338 } else if(&col==&globals->sensors.sources) {
00339 updateDataSources(activeSensors, activeSensorSrcs, globals->sensors.sources, &DeviceDriver::getSensorSources);
00340 } else if(&col==&globals->vision.sources) {
00341 updateDataSources(activeCameras, activeCameraSrcs, globals->vision.sources, &DeviceDriver::getImageSources);
00342 } else {
00343 cerr << "WARNING: Simulator got a plistCollectionEntryAdded for an unknown plist collection";
00344 }
00345 }
00346 void Simulator::plistCollectionEntryRemoved(plist::Collection& col, plist::ObjectBase& primitive) {
00347 MarkScope l(simLock);
00348 if(&col==&DeviceDriver::getRegistry()) {
00349 if(DeviceDriver * d=dynamic_cast<DeviceDriver*>(&primitive)) {
00350 if(MotionHook * mh = d->getMotionSink()) {
00351 motionHooks.erase(mh);
00352 motionHookMonitor->motionCheckTime.Set();
00353 if(curLevel==SharedGlobals::RUNNING && globals->timeScale!=0) {
00354 motionHookMonitor->curFuncName="leavingRealtime()"; motionHookMonitor->curHook=mh;
00355 mh->leavingRealtime(false);
00356 motionHookMonitor->curHook=NULL;
00357 }
00358 if(curLevel==SharedGlobals::STARTING || curLevel==SharedGlobals::RUNNING) {
00359 motionHookMonitor->curFuncName="motionStopping()"; motionHookMonitor->curHook=mh;
00360 mh->motionStopping();
00361 motionHookMonitor->curHook=NULL;
00362 }
00363 }
00364 } else {
00365 cerr << "WARNING: Simulator got a plistCollectionEntryRemoved for an unknown primitive type";
00366 }
00367 updateDataSources(activeSensors, activeSensorSrcs, globals->sensors.sources, &DeviceDriver::getSensorSources);
00368 updateDataSources(activeCameras, activeCameraSrcs, globals->vision.sources, &DeviceDriver::getImageSources);
00369 } else if(&col==&globals->sensors.sources) {
00370 dynamic_cast<plist::PrimitiveBase&>(primitive).removePrimitiveListener(this);
00371 updateDataSources(activeSensors, activeSensorSrcs, globals->sensors.sources, &DeviceDriver::getSensorSources);
00372 } else if(&col==&globals->vision.sources) {
00373 dynamic_cast<plist::PrimitiveBase&>(primitive).removePrimitiveListener(this);
00374 updateDataSources(activeCameras, activeCameraSrcs, globals->vision.sources, &DeviceDriver::getImageSources);
00375 } else {
00376 cerr << "WARNING: Simulator got a plistCollectionEntryRemoved for an unknown plist collection";
00377 }
00378 }
00379 void Simulator::plistCollectionEntriesChanged(plist::Collection& col) {
00380 MarkScope l(simLock);
00381 if(&col==&DeviceDriver::getRegistry()) {
00382 for(DeviceDriver::registry_t::const_iterator it=DeviceDriver::getRegistry().begin(); it!=DeviceDriver::getRegistry().end(); ++it) {
00383 if(DeviceDriver * d=DeviceDriver::getRegistry().getInstance(it->first)) {
00384 if(MotionHook * mh = d->getMotionSink()) {
00385 if(motionHooks.find(mh)!=motionHooks.end())
00386 continue;
00387 motionHookMonitor->motionCheckTime.Set();
00388 mh->setMotionHookVerbose(globals->motion.verbose);
00389 if(curLevel==SharedGlobals::RUNNING || curLevel==SharedGlobals::STARTING) {
00390 motionHookMonitor->curFuncName="motionStarting()"; motionHookMonitor->curHook=mh;
00391 mh->motionStarting();
00392 motionHookMonitor->curHook=NULL;
00393 }
00394 if(curLevel==SharedGlobals::RUNNING) {
00395 if(globals->timeScale>0) {
00396 motionHookMonitor->curFuncName="enteringRealtime()"; motionHookMonitor->curHook=mh;
00397 mh->enteringRealtime(globals->timeScale);
00398 } else {
00399 motionHookMonitor->curFuncName="leavingRealtime()"; motionHookMonitor->curHook=mh;
00400 mh->leavingRealtime(globals->timeScale<0);
00401 }
00402 motionHookMonitor->curHook=NULL;
00403 }
00404 motionHooks.insert(mh);
00405 }
00406 } else {
00407 cerr << "WARNING: In Simulator::plistCollectionEntriesChanged, driver " << it->first << " does not correspond to a known instance" << endl;
00408 }
00409 }
00410 updateDataSources(activeSensors, activeSensorSrcs, globals->sensors.sources, &DeviceDriver::getSensorSources);
00411 updateDataSources(activeCameras, activeCameraSrcs, globals->vision.sources, &DeviceDriver::getImageSources);
00412 } else if(&col==&globals->sensors.sources) {
00413 updateDataSources(activeSensors, activeSensorSrcs, globals->sensors.sources, &DeviceDriver::getSensorSources);
00414 } else if(&col==&globals->vision.sources) {
00415 updateDataSources(activeCameras, activeCameraSrcs, globals->vision.sources, &DeviceDriver::getImageSources);
00416 } else {
00417 cerr << "WARNING: Simulator got a plistCollectionEntriesChanged for an unknown plist collection";
00418 }
00419 }
00420
00421 void Simulator::messagesRead(MessageQueueBase& mq, unsigned int ) {
00422 MarkScope l(simLock);
00423 if(globals->timeScale<0) {
00424
00425 if(&mq==&(*cameraQueue)) {
00426
00427 waitingSteps&=~(1<<STEP_CAMERA);
00428 } else if(&mq==&(*sensorQueue)) {
00429
00430 waitingSteps&=~(1<<STEP_SENSOR);
00431 } else if(&mq==&(*timerWakeup)) {
00432
00433 waitingSteps&=~(1<<STEP_TIMER);
00434 } else if(&mq==&(*motionWakeup)) {
00435
00436 waitingSteps&=~(1<<STEP_MOTION);
00437 } else if(&mq==&(*events)) {
00438
00439
00440 } else {
00441 cout << "Unknown message base read (either you meant to add some code to Simulator::messagesRead, or why did you bother to register a listener?)" << endl;
00442 }
00443
00444
00445 if(waitingSteps==0 && events->getMessagesUnread()==0)
00446 incrementTime();
00447 }
00448 }
00449
00450 void Simulator::sendCommand(const std::string& cmd) {
00451 static unsigned int cmdSN=0;
00452 char msgname[30];
00453 snprintf(msgname,30,"SimCommand.%d.%d",ProcessID::getID(),cmdSN++);
00454 RCRegion * msg = new RCRegion(msgname,cmd.size());
00455 strcpy(msg->Base(),cmd.c_str());
00456 SharedObject<CommandQueue_t> commandQ(ipc_setup->registerRegion(Simulator::getCommandQueueID(),sizeof(CommandQueue_t)));
00457 commandQ->sendMessage(msg,true);
00458 }
00459
00460 void Simulator::setMotionStarting() {
00461
00462
00463 Simulator::motionHookMonitor->motionCheckTime.Set();
00464 Simulator::motionHookMonitor->curFuncName="motionStarting()";
00465 for(std::set<MotionHook*>::iterator it=theSim->motionHooks.begin(); it!=theSim->motionHooks.end(); ++it) {
00466 Simulator::motionHookMonitor->curHook=*it;
00467 (*it)->motionStarting();
00468 }
00469 Simulator::motionHookMonitor->curHook=NULL;
00470 }
00471 void Simulator::setMotionStopping() {
00472
00473
00474 Simulator::motionHookMonitor->motionCheckTime.Set();
00475 Simulator::motionHookMonitor->curFuncName="motionStopping()";
00476 for(std::set<MotionHook*>::iterator it=theSim->motionHooks.begin(); it!=theSim->motionHooks.end(); ++it) {
00477 Simulator::motionHookMonitor->curHook=*it;
00478 (*it)->motionStopping();
00479 }
00480 Simulator::motionHookMonitor->curHook=NULL;
00481 }
00482 void Simulator::updateMotion(const float outputs[][NumOutputs]) {
00483 MarkScope l(theSim ? dynamic_cast<Resource&>(theSim->simLock) : ::emptyResource);
00484 Simulator::motionHookMonitor->motionCheckTime.Set();
00485 Simulator::motionHookMonitor->curFuncName="motionCheck(const float[][])";
00486 for(std::set<MotionHook*>::iterator it=theSim->motionHooks.begin(); it!=theSim->motionHooks.end(); ++it) {
00487 Simulator::motionHookMonitor->curHook=*it;
00488 (*it)->motionCheck(outputs);
00489 }
00490 Simulator::motionHookMonitor->curHook=NULL;
00491 }
00492 void Simulator::updatePIDs(const std::vector<MotionHook::PIDUpdate>& pids) {
00493 MarkScope l(theSim ? dynamic_cast<Resource&>(theSim->simLock) : ::emptyResource);
00494 Simulator::motionHookMonitor->motionCheckTime.Set();
00495 Simulator::motionHookMonitor->curFuncName="updatePIDs(PIDUpdate)";
00496 for(std::set<MotionHook*>::iterator it=theSim->motionHooks.begin(); it!=theSim->motionHooks.end(); ++it) {
00497 Simulator::motionHookMonitor->curHook=*it;
00498 (*it)->updatePIDs(pids);
00499 }
00500 Simulator::motionHookMonitor->curHook=NULL;
00501 }
00502 void Simulator::setMotionLeavingRealtime(bool isFullSpeed) {
00503 MarkScope l(theSim ? dynamic_cast<Resource&>(theSim->simLock) : ::emptyResource);
00504 Simulator::motionHookMonitor->motionCheckTime.Set();
00505 Simulator::motionHookMonitor->curFuncName="leavingRealtime()";
00506 for(std::set<MotionHook*>::iterator it=theSim->motionHooks.begin(); it!=theSim->motionHooks.end(); ++it) {
00507 Simulator::motionHookMonitor->curHook=*it;
00508 (*it)->leavingRealtime(isFullSpeed);
00509 }
00510 Simulator::motionHookMonitor->curHook=NULL;
00511 if(theSim!=NULL) {
00512 globals->sensorState.resourceSync = NULL;
00513 for(std::set<DataSource*>::const_iterator it=theSim->activeCameraSrcs.begin(); it!=theSim->activeCameraSrcs.end(); ++it)
00514 (*it)->leavingRealtime(isFullSpeed);
00515 for(std::set<DataSource*>::const_iterator it=theSim->activeSensorSrcs.begin(); it!=theSim->activeSensorSrcs.end(); ++it)
00516 (*it)->leavingRealtime(isFullSpeed);
00517 }
00518 }
00519 void Simulator::setMotionEnteringRealtime() {
00520 MarkScope l(theSim ? dynamic_cast<Resource&>(theSim->simLock) : ::emptyResource);
00521 Simulator::motionHookMonitor->motionCheckTime.Set();
00522 Simulator::motionHookMonitor->curFuncName="enteringRealtime()";
00523 for(std::set<MotionHook*>::iterator it=theSim->motionHooks.begin(); it!=theSim->motionHooks.end(); ++it) {
00524 Simulator::motionHookMonitor->curHook=*it;
00525 (*it)->enteringRealtime(globals->timeScale);
00526 }
00527 Simulator::motionHookMonitor->curHook=NULL;
00528 if(theSim!=NULL) {
00529 globals->sensorState.resourceSync = syncSensors;
00530 for(std::set<DataSource*>::const_iterator it=theSim->activeCameraSrcs.begin(); it!=theSim->activeCameraSrcs.end(); ++it)
00531 (*it)->enteringRealtime(globals->timeScale);
00532 for(std::set<DataSource*>::const_iterator it=theSim->activeSensorSrcs.begin(); it!=theSim->activeSensorSrcs.end(); ++it)
00533 (*it)->enteringRealtime(globals->timeScale);
00534 }
00535 }
00536
00537 const TimeET Simulator::MotionMonitorThread::timeout(1000L);
00538 unsigned int Simulator::MotionMonitorThread::runloop() {
00539 if(timeout < motionCheckTime.Age()) {
00540 float blockTime = static_cast<unsigned int>(motionCheckTime.Age().Value()*10+.5)/10.0f;
00541 if(curHook==NULL) {
00542 std::cerr << "Looks like " << ProcessID::getIDStr() << " has been stuck for " << blockTime << " seconds, but I can't tell where, try attaching debugger?" << std::endl;
00543 return 2000000;
00544 }
00545 const DeviceDriver * guilty=NULL;
00546 for(DeviceDriver::registry_t::const_iterator it=DeviceDriver::getRegistry().begin(); it!=DeviceDriver::getRegistry().end(); ++it) {
00547 if(DeviceDriver * d=DeviceDriver::getRegistry().getInstance(it->first)) {
00548 if(curHook == d->getMotionSink()) {
00549 guilty = d;
00550 }
00551 }
00552 }
00553 if(guilty==NULL) {
00554 std::cerr << ProcessID::getIDStr() << " has blocked within " << curFuncName << " on an unknown " << " MotionHook with typeid '" << typeid(*curHook).name() << "' @" << curHook << " for " << motionCheckTime.Age() << std::endl;
00555 } else {
00556 std::cerr << ProcessID::getIDStr() << " has blocked within " << curFuncName << " on MotionHook with typeid '" << typeid(*curHook).name() << "'";
00557 if(guilty->getName()==guilty->getClassName())
00558 std::cerr << " from driver " << guilty->getName();
00559 else
00560 std::cerr << " from driver instance " << guilty->getName() << " (type " << guilty->getClassName() << ")";
00561 std::cerr << " for " << blockTime << " seconds" << std::endl;
00562 }
00563 }
00564 return 2000000;
00565 }
00566
00567
00568 void Simulator::doStop() {
00569 curLevel=SharedGlobals::STOPPING;
00570 commandrecv->finish();
00571 delete commandrecv;
00572 commandrecv=NULL;
00573 motionrecv->finish();
00574 delete motionrecv;
00575 motionrecv=NULL;
00576 motionpidsrecv->finish();
00577 delete motionpidsrecv;
00578 motionpidsrecv=NULL;
00579 setMotionStopping();
00580 delete motionHookMonitor;
00581 motionHookMonitor=NULL;
00582
00583 if(!sim::config.multiprocess) {
00584 erouter->setForwardingAgent(getID(),NULL);
00585 MotionManager::setTranslator(NULL);
00586 } else {
00587 erouter->removeTrapper(etrans);
00588 delete etrans;
00589 etrans=NULL;
00590 MotionManager::setTranslator(NULL);
00591 }
00592
00593 processRunlevel(SharedGlobals::STOPPING);
00594 Process::doStop();
00595 }
00596
00597
00598 Simulator::CommandThread::~CommandThread() {
00599 if(isStarted()) {
00600 interrupt();
00601 join();
00602 }
00603 }
00604
00605 #ifndef DISABLE_READLINE
00606 extern int rl_catch_signals;
00607 #endif
00608
00609 void* Simulator::CommandThread::run() {
00610 Simulator * simp=dynamic_cast<Simulator*>(Process::getCurrent());
00611 ASSERTRETVAL(simp!=NULL,"CommandThread not in Simulator!",NULL);
00612 string prompt;
00613
00614 while(true) {
00615 testCancel();
00616 string line;
00617 #ifndef DISABLE_READLINE
00618
00619
00620 {
00621
00622 static bool tested=false, haveGNU;
00623 if(!tested) {
00624 void* gnuFlag = dlsym(RTLD_DEFAULT,"rl_gnu_readline_p");
00625 haveGNU = (gnuFlag!=NULL && *reinterpret_cast<int*>(gnuFlag));
00626 tested=true;
00627 }
00628 if(haveGNU)
00629 rl_getc_function = ::getc;
00630
00631 }
00632 rl_catch_signals = 0;
00633 char* readin=readline(prompt.c_str());
00634 if(readin==NULL) {
00635 cout << endl;
00636 simp->cmdQuit(vector<string>());
00637 break;
00638 }
00639 line=readin;
00640 free(readin);
00641 #else
00642 cout << prompt << flush;
00643 getline(cin,line);
00644 if(!cin) {
00645 cout << endl;
00646 simp->cmdQuit(vector<string>());
00647 break;
00648 }
00649 #endif
00650 simp->processCommand(line,true);
00651 prompt = sim::config.cmdPrompt;
00652 }
00653 return NULL;
00654 }
00655
00656 void Simulator::CommandThread::runInitThread(Thread& th) {
00657 Thread::NoCancelScope nc;
00658 {
00659 MarkScope l(initThreadsLock);
00660 th.start();
00661 initThreads.insert(&th);
00662 }
00663 th.join();
00664 {
00665 MarkScope l(initThreadsLock);
00666 initThreads.erase(&th);
00667 }
00668 }
00669 void Simulator::CommandThread::abortInitThreads() {
00670 MarkScope l(initThreadsLock);
00671 std::for_each(initThreads.begin(),initThreads.end(),std::mem_fun(&Thread::stop));
00672 }
00673
00674
00675
00676 void Simulator::resetSpeedMode() {
00677 if(globals->timeScale<=0) {
00678 if(sensorThread.isStarted()) {
00679 sensorThread.stop();
00680
00681 }
00682 if(motionHookMonitor->isStarted() && curLevel==SharedGlobals::RUNNING)
00683 motionHookMonitor->stop();
00684 }
00685 if( (lastTimeScale>0 && globals->timeScale<=0)
00686 || (lastTimeScale==0 && globals->timeScale<0)
00687 || (lastTimeScale<0 && globals->timeScale==0) ) {
00688 setMotionLeavingRealtime(globals->timeScale<0);
00689 } else if(lastTimeScale<=0 && globals->timeScale>0) {
00690 setMotionEnteringRealtime();
00691 }
00692 if(curLevel==SharedGlobals::RUNNING) {
00693 if(globals->timeScale>0) {
00694 if(!sensorThread.isStarted())
00695 sensorThread.start();
00696 if(!motionHookMonitor->isStarted())
00697 motionHookMonitor->start();
00698 }
00699 } else {
00700 if(!motionHookMonitor->isStarted())
00701 motionHookMonitor->start();
00702 }
00703
00704 if(globals->timeScale<0) {
00705 cameraQueue->setOverflowPolicy(MessageQueueBase::WAIT);
00706 sensorQueue->setOverflowPolicy(MessageQueueBase::WAIT);
00707
00708 cameraStatus.addStatusListener(this);
00709 sensorStatus.addStatusListener(this);
00710 timerStatus.addStatusListener(this);
00711 motionStatus.addStatusListener(this);
00712 eventsStatus.addStatusListener(this);
00713 fullspeedWallStart.Set();
00714 fullspeedSimStart=globals->simulatorTime;
00715 lastFrameWallStart.Set();
00716 avgWallTime=avgSimTime=0;
00717 } else {
00718 cameraQueue->setOverflowPolicy(MessageQueueBase::DROP_OLDEST);
00719 sensorQueue->setOverflowPolicy(MessageQueueBase::DROP_OLDEST);
00720 eventsStatus.removeStatusListener(this);
00721 motionStatus.removeStatusListener(this);
00722 timerStatus.removeStatusListener(this);
00723 sensorStatus.removeStatusListener(this);
00724 cameraStatus.removeStatusListener(this);
00725 }
00726 if(globals->timeScale==0)
00727 globals->setAutoPauseTime(-1U);
00728 lastTimeScale=globals->timeScale;
00729 }
00730
00731 void Simulator::replaceEntry(const std::string& name, plist::Dictionary& d, const std::string& comment) {
00732 plist::Dictionary::const_iterator it = sim::config.findEntry(name);
00733 if(it==sim::config.end()) {
00734 sim::config.addEntry(name,d,comment);
00735 } else {
00736 d.set(*it->second);
00737 sim::config.setEntry(name,d);
00738 sim::config.setComment(name,comment);
00739 }
00740 }
00741
00742 bool Simulator::sendSensor(bool syncCall) {
00743 bool sent=false;
00744 Thread::NoCancelScope nc;
00745 if(!syncCall)
00746 sendSensorSent=false;
00747 if(globals->sensorState.dirty) {
00748 if(!syncCall)
00749 return false;
00750 if(sendSensorSent)
00751 return false;
00752 if(globals->sensors.verbose>=2)
00753 std::cout << "Sending sensor update at " << get_time() << std::endl;
00754 ++globals->sensorState.frameNumber;
00755 globals->sensorState.dirty=false;
00756 sensorQueue->sendMessage(NULL);
00757 sendSensorSent=sent=true;
00758 } else if(globals->sensors.heartbeat) {
00759 unsigned int curTime = get_time();
00760 unsigned int tgtTime = globals->sensorState.timestamp + static_cast<unsigned int>(1000.f / globals->sensors.framerate + 0.5f);
00761
00762 if(tgtTime<=curTime) {
00763 if(globals->sensors.verbose>=3)
00764 std::cout << "Sending sensor heartbeat at " << curTime << std::endl;
00765 ++globals->sensorState.frameNumber;
00766 globals->sensorState.timestamp=curTime;
00767 sensorQueue->sendMessage(NULL);
00768 sent=true;
00769 }
00770 }
00771 return sent;
00772 }
00773
00774 unsigned int Simulator::nextVisionTime() {
00775 unsigned int vis=-1U;
00776 for(std::set<DataSource*>::const_iterator it=activeCameraSrcs.begin(); it!=activeCameraSrcs.end(); ++it) {
00777 if(!(*it)->getFrozen())
00778 vis = std::min(vis,(*it)->nextTimestamp());
00779 }
00780 return vis;
00781 }
00782
00783 unsigned int Simulator::nextSensorTime() {
00784 unsigned int tpf = static_cast<unsigned int>(1000/globals->sensors.framerate + .5f);
00785 return (get_time()/tpf + 1)*tpf;
00786 }
00787
00788 void Simulator::incrementTime() {
00789 MarkScope l(simLock);
00790 waitingSteps=getNextFrame();
00791 if(waitingSteps==0)
00792 return;
00793 unsigned int next=*frameTimes.begin();
00794 if(next>globals->simulatorTime) {
00795 unsigned int adv=next-globals->simulatorTime;
00796 avgWallTime=avgWallTime*avgSpeedupGamma + (float)lastFrameWallStart.Age().Value()*(1-avgSpeedupGamma);
00797 avgSimTime=avgSimTime*avgSpeedupGamma + adv*(1-avgSpeedupGamma);
00798 lastFrameWallStart.Set();
00799
00800 globals->simulatorTime=next;
00801 }
00802 if(waitingSteps & (1<<STEP_CAMERA)) {
00803 bool sent=false;
00804 for(std::set<DataSource*>::const_iterator it=activeCameraSrcs.begin(); it!=activeCameraSrcs.end(); ++it)
00805 if((*it)->advance())
00806 sent=true;
00807 if(!sent)
00808 waitingSteps &= ~(1<<STEP_CAMERA);
00809 }
00810 if(waitingSteps & (1<<STEP_SENSOR)) {
00811 for(std::set<DataSource*>::const_iterator it=activeSensorSrcs.begin(); it!=activeSensorSrcs.end(); ++it)
00812 (*it)->advance();
00813 sendSensorSent=false;
00814 if(!sendSensor(true))
00815 waitingSteps &= ~(1<<STEP_SENSOR);
00816 }
00817 if(waitingSteps & (1<<STEP_TIMER))
00818 timerWakeup->sendMessage(NULL);
00819 if(waitingSteps & (1<<STEP_MOTION))
00820 motionWakeup->sendMessage(NULL);
00821 if(globals->getAutoPauseTime()<=globals->simulatorTime || (1<<step) & waitingSteps) {
00822
00823 globals->timeScale=0;
00824 step=STEP_NONE;
00825 globals->setAutoPauseTime(-1U);
00826 }
00827 }
00828
00829 unsigned int Simulator::getNextFrame() {
00830 frameTimes.clear();
00831 unsigned int vis = nextVisionTime();
00832 frameTimes.insert(vis);
00833 unsigned int sen = nextSensorTime();
00834 frameTimes.insert(sen);
00835 unsigned int tim=globals->getNextTimer();
00836 frameTimes.insert(tim);
00837 unsigned int mot=globals->getNextMotion();
00838 frameTimes.insert(mot);
00839 unsigned int next=*frameTimes.begin();
00840
00841 unsigned int steps=0;
00842 if(next!=-1U) {
00843 if(next==vis) {
00844 steps |= 1<<STEP_CAMERA;
00845 }
00846 if(next==sen) {
00847 steps |= 1<<STEP_SENSOR;
00848 }
00849 if(next==tim) {
00850 steps |= 1<<STEP_TIMER;
00851 }
00852 if(next==mot) {
00853 steps |= 1<<STEP_MOTION;
00854 }
00855 }
00856 return steps;
00857 }
00858
00859 void Simulator::processRunlevel(SharedGlobals::runlevel_t curRunLevel) {
00860 curLevel=curRunLevel;
00861 if(sim::config.tgtRunlevel==curLevel && (!globals->isShutdown() || curLevel>SharedGlobals::RUNNING))
00862 cout << sim::config.cmdPrompt << flush;
00863 while(sim::config.tgtRunlevel==curLevel && (!globals->isShutdown() || curLevel>SharedGlobals::RUNNING)) {
00864 usleep(500000);
00865 }
00866 }
00867
00868 bool Simulator::processCommand(const std::string& line, bool addToHistory) {
00869 vector<string> args;
00870 vector<unsigned int> offs;
00871 if(!string_util::parseArgs(line,args,offs)) {
00872 cerr << "Mismatched quotes" << endl;
00873 return false;
00874 }
00875 if(args.size()==0)
00876 return true;
00877 #ifndef DISABLE_READLINE
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901 if(addToHistory && (current_history()==NULL || current_history()->line==NULL || line!=current_history()->line))
00902 add_history(line.c_str());
00903 #endif
00904 if(args[0]=="shutdown" || args[0]=="quit" || args[0]=="exit") {
00905 cmdQuit(args);
00906 } else if(args[0]=="load") {
00907 cmdLoad(args);
00908 } else if(args[0]=="save") {
00909 cmdSave(args);
00910 } else if(args[0]=="runlevel") {
00911 cmdRunlevel(args);
00912 } else if(args[0]=="get_time") {
00913 cout << "Current time is " << get_time() << endl;
00914 } else if(args[0]=="print") {
00915 cmdPrint(args);
00916 } else if(args[0]=="set") {
00917 cmdSet(args);
00918 } else if(args[0]=="runto") {
00919 cmdRun(args,false);
00920 } else if(args[0]=="runfor") {
00921 cmdRun(args,true);
00922 } else if(args[0]=="run" || args[0]=="r") {
00923 cmdRun(args);
00924 } else if(args[0]=="pause" || args[0]=="p") {
00925 cmdPause(args);
00926 } else if(args[0]=="help") {
00927 cmdHelp(args);
00928 } else if(args[0]=="step") {
00929 cmdStep(args);
00930 } else if(args[0]=="status") {
00931 cmdStatus(args);
00932 } else if(args[0]=="advance") {
00933 cmdAdvance(args);
00934 } else if(args[0]=="freeze") {
00935 cmdFreeze(true,args);
00936 } else if(args[0]=="unfreeze") {
00937 cmdFreeze(false,args);
00938 } else if(args[0]=="reset") {
00939 cmdReset(args);
00940 } else if(args[0]=="new") {
00941 cmdNew(args);
00942 } else if(args[0]=="delete") {
00943 cmdDelete(args);
00944 } else if(args[0]=="post") {
00945 cmdPost(args);
00946 } else if(args[0]=="msg") {
00947 cmdMsg(args);
00948 } else {
00949 unsigned int i;
00950 for(i=0; i<args.size(); ++i) {
00951 if(args[i].find("=")!=string::npos) {
00952 cmdSet(args);
00953 break;
00954 }
00955 }
00956 if(i==args.size()) {
00957 cout << "Unknown command '" << args[0] << "'" << endl;
00958 return false;
00959 }
00960 }
00961 return true;
00962 }
00963
00964 bool Simulator::gotCommand(RCRegion* msg) {
00965 Simulator * simp=dynamic_cast<Simulator*>(Process::getCurrent());
00966 ASSERTRETVAL(simp!=NULL,"gotCommand, but not within Simulator process!",true);
00967 simp->processCommand(msg->Base(),false);
00968 return true;
00969 }
00970
00971 bool Simulator::gotMotion(RCRegion* msg) {
00972 #ifdef DEBUG
00973 Simulator * simp=dynamic_cast<Simulator*>(Process::getCurrent());
00974 ASSERTRETVAL(simp!=NULL,"gotMotion, but not within Simulator process!",true);
00975 #endif
00976 updateMotion(reinterpret_cast<float(*)[NumOutputs]>(msg->Base()));
00977 return true;
00978 }
00979
00980 bool Simulator::gotMotionPIDs(RCRegion* msg) {
00981 #ifdef DEBUG
00982 Simulator * simp=dynamic_cast<Simulator*>(Process::getCurrent());
00983 ASSERTRETVAL(simp!=NULL,"gotMotion, but not within Simulator process!",true);
00984 #endif
00985 std::vector<MotionHook::PIDUpdate> updates;
00986 unsigned int num = msg->Size()/sizeof(MotionHook::PIDUpdate);
00987 MotionHook::PIDUpdate * incoming = reinterpret_cast<MotionHook::PIDUpdate*>(msg->Base());
00988 updates.reserve(num);
00989 std::copy(incoming,incoming+num,std::back_inserter(updates));
00990 updatePIDs(updates);
00991 return true;
00992 }
00993
00994 void Simulator::updateDataSources(std::set<std::string>& active, std::set<DataSource*>& activeSrcs, const plist::ArrayOf<plist::Primitive<std::string> >& requested, getDataSources_t getDataSources) {
00995 std::set<std::string> reqNames;
00996 for(plist::ArrayOf<plist::Primitive<std::string> >::const_iterator it=requested.begin(); it!=requested.end(); ++it) {
00997 (*it)->addPrimitiveListener(this);
00998 reqNames.insert(**it);
00999 }
01000 std::set<std::string> newNames;
01001 std::set_difference(reqNames.begin(),reqNames.end(),active.begin(),active.end(),std::inserter(newNames,newNames.end()));
01002
01003
01004 std::set<DataSource*> reqSrcs;
01005 for(std::set<std::string>::const_iterator it=reqNames.begin(); it!=reqNames.end(); ++it) {
01006 std::string errStr;
01007 lookupDataSource(*it, getDataSources, reqSrcs, errStr);
01008 if(errStr.size()>0) {
01009 if(newNames.count(*it))
01010 std::cerr << errStr << std::endl;
01011 }
01012 }
01013
01014
01015 std::set<DataSource*> newSrcs, delSrcs;
01016 std::set_difference(reqSrcs.begin(),reqSrcs.end(),activeSrcs.begin(),activeSrcs.end(),std::inserter(newSrcs,newSrcs.end()));
01017 std::set_difference(activeSrcs.begin(),activeSrcs.end(),reqSrcs.begin(),reqSrcs.end(),std::inserter(delSrcs,delSrcs.end()));
01018
01019 if(curLevel==SharedGlobals::RUNNING) {
01020 if(globals->timeScale!=0) {
01021
01022 for(std::set<DataSource*>::const_iterator it=delSrcs.begin(); it!=delSrcs.end(); ++it)
01023 (*it)->leavingRealtime(false);
01024 }
01025 }
01026
01027 if(curLevel>=SharedGlobals::STARTING) {
01028 for(std::set<DataSource*>::const_iterator it=delSrcs.begin(); it!=delSrcs.end(); ++it)
01029 (*it)->deregisterSource();
01030 }
01031 if(getDataSources == &DeviceDriver::getImageSources) {
01032 for(std::set<DataSource*>::const_iterator it=delSrcs.begin(); it!=delSrcs.end(); ++it)
01033 (*it)->setImageQueue(NULL);
01034 for(std::set<DataSource*>::const_iterator it=newSrcs.begin(); it!=newSrcs.end(); ++it)
01035 (*it)->setImageQueue(&*cameraQueue);
01036 }
01037 if(curLevel>=SharedGlobals::STARTING) {
01038 for(std::set<DataSource*>::const_iterator it=newSrcs.begin(); it!=newSrcs.end(); ++it)
01039 (*it)->registerSource();
01040 }
01041
01042 if(curLevel==SharedGlobals::RUNNING) {
01043
01044 if(globals->timeScale<=0) {
01045 for(std::set<DataSource*>::const_iterator it=newSrcs.begin(); it!=newSrcs.end(); ++it)
01046 (*it)->leavingRealtime(globals->timeScale<0);
01047 } else if(globals->timeScale>0) {
01048 for(std::set<DataSource*>::const_iterator it=newSrcs.begin(); it!=newSrcs.end(); ++it)
01049 (*it)->enteringRealtime(globals->timeScale);
01050 }
01051 }
01052
01053 activeSrcs = reqSrcs;
01054 }
01055
01056 void Simulator::lookupDataSource(const std::string& name, getDataSources_t getDataSources, std::set<DataSource*>& dataSrcs, std::string& errStr) {
01057 errStr.clear();
01058 std::string::size_type dot=name.find('.');
01059 DeviceDriver* dd=DeviceDriver::getRegistry().getInstance(name.substr(0,dot));
01060 if(dd==NULL) {
01061 errStr = "Could not find driver named '" + name + "' for data source";
01062 } else {
01063 std::map<std::string,DataSource*> dsmap;
01064 (dd->*getDataSources)(dsmap);
01065 if(dsmap.size()==0) {
01066 errStr = "Driver '" + name.substr(0,dot) + "' does not have any data sources";
01067 } else if(dot==std::string::npos) {
01068
01069 for(std::map<std::string,DataSource*>::const_iterator ds = dsmap.begin(); ds!=dsmap.end(); ++ds)
01070 dataSrcs.insert(ds->second);
01071 } else {
01072 std::map<std::string,DataSource*>::const_iterator ds=dsmap.find(name.substr(dot+1));
01073 if(ds!=dsmap.end()) {
01074 dataSrcs.insert(ds->second);
01075 } else {
01076 errStr = "Could not find stream named '" + name.substr(dot+1) + "' in driver '" + name.substr(0,dot) + "'";
01077 }
01078 }
01079 }
01080 }
01081
01082 std::string Simulator::lookupDataSourceName(const DataSource* src) const {
01083 for(DeviceDriver::registry_t::const_iterator it = DeviceDriver::getRegistry().begin(); it!=DeviceDriver::getRegistry().end(); ++it) {
01084 DeviceDriver* dd = DeviceDriver::getRegistry().getInstance(it->first);
01085 std::map<std::string,DataSource*> sources, sensorSources, imageSources;
01086 dd->getSensorSources(sensorSources);
01087 dd->getImageSources(imageSources);
01088 std::merge(sensorSources.begin(),sensorSources.end(), imageSources.begin(),imageSources.end(), std::inserter(sources,sources.end()));
01089 bool foundNonMatch=false;
01090 std::string ans;
01091 for(std::map<std::string,DataSource*>::const_iterator sit=sources.begin(); sit!=sources.end(); ++sit) {
01092 if(sit->second == src) {
01093 if(ans.size()==0)
01094 ans = it->first + "." + sit->first;
01095 else
01096 ans += "/" + sit->first;
01097 } else {
01098 foundNonMatch=true;
01099 }
01100 }
01101 if(ans.size()>0) {
01102
01103 return !foundNonMatch ? it->first : ans;
01104 }
01105 }
01106 return std::string();
01107 }
01108
01109
01110 void Simulator::cmdQuit(const std::vector<std::string>& ) {
01111 sim::config.tgtRunlevel=SharedGlobals::DESTRUCTED;
01112 cmdThread.abortInitThreads();
01113 globals->signalShutdown();
01114 }
01115 void Simulator::cmdLoad(const std::vector<std::string>& args) {
01116 if(args.size()>1)
01117 for(unsigned int i=1; i<args.size(); i++) {
01118 cout << "Loading from " << args[i] << "... " << flush;
01119 size_t res=sim::config.loadFile(args[i].c_str());
01120 cout << (res>0 ? "done." : "load failed.") << endl;
01121 }
01122 else {
01123 cout << "Loading from " << sim::config.getLastFile() << "... " << flush;
01124 size_t res=sim::config.loadFile(sim::config.getLastFile().c_str());
01125 cout << (res>0 ? "done." : "load failed.") << endl;
01126 }
01127 }
01128 void Simulator::cmdSave(const std::vector<std::string>& args) {
01129 if(args.size()>1)
01130 for(unsigned int i=1; i<args.size(); i++)
01131 sim::config.saveFile(args[i].c_str());
01132 else {
01133 cout << "Saving to " << sim::config.getLastFile() << "... " << flush;
01134 size_t res=sim::config.saveFile(sim::config.getLastFile().c_str());
01135 cout << (res>0 ? "done." : "save failed.") << endl;
01136 }
01137 }
01138 void Simulator::cmdRunlevel(const std::vector<std::string>& args) {
01139 if(args.size()<=1) {
01140 sim::config.tgtRunlevel=static_cast<SharedGlobals::runlevel_t>(sim::config.tgtRunlevel+1);
01141 cout << "Moving to next runlevel: " << SharedGlobals::runlevel_names[sim::config.tgtRunlevel] << endl;
01142 } else {
01143 try {
01144 sim::config.tgtRunlevel=string_util::makeUpper(args[1]);
01145 } catch(...) {
01146 cout << "Invalid runlevel specification. Try one of:\n\t";
01147 for(unsigned int i=0; i<SharedGlobals::NUM_RUNLEVELS; i++)
01148 cout << i << ' ' << SharedGlobals::runlevel_names[i] << ", ";
01149 cout << "\nCurrently at " << SharedGlobals::runlevel_names[curLevel] << endl;
01150 return;
01151 }
01152 if(sim::config.tgtRunlevel<curLevel) {
01153 sim::config.tgtRunlevel=curLevel;
01154 cout << "Cannot reduce runlevel, currently at " << curLevel << ' ' << SharedGlobals::runlevel_names[curLevel] << "\n\t";
01155 for(unsigned int i=0; i<SharedGlobals::NUM_RUNLEVELS; i++)
01156 cout << i << ' ' << SharedGlobals::runlevel_names[i] << ", ";
01157 cout << endl;
01158 return;
01159 } else if(sim::config.tgtRunlevel==curLevel) {
01160 cout << "Already at " << curLevel << ' ' << SharedGlobals::runlevel_names[curLevel] << "\n\t";
01161 for(unsigned int i=0; i<SharedGlobals::NUM_RUNLEVELS; i++)
01162 cout << i << ' ' << SharedGlobals::runlevel_names[i] << ", ";
01163 cout << endl;
01164 return;
01165 }
01166 }
01167 if(sim::config.tgtRunlevel>SharedGlobals::RUNNING && curLevel<=SharedGlobals::RUNNING)
01168 globals->signalShutdown();
01169 }
01170 bool Simulator::cmdPrint(const std::vector<std::string>& args) {
01171 if(args.size()==0 || (args[0]=="print" && args.size()==1)) {
01172 plist::filteredDisplay(cout,sim::config,"^[^.].*",REG_EXTENDED,3);
01173 return false;
01174 }
01175 string arg;
01176 for(unsigned int i=(args[0]=="print"?1:0); i<args.size(); i++) {
01177 arg+=args[i];
01178 if(i!=args.size()-1)
01179 arg+=" ";
01180 }
01181 const string WS_PREFIX="WorldState";
01182 if(arg.substr(0,WS_PREFIX.size())==WS_PREFIX) {
01183 return SensorStateAccessor().print(arg);
01184 }
01185 plist::ObjectBase* ob=sim::config.resolveEntry(arg);
01186 if(ob==NULL) {
01187 cout << "'" << arg << "' is unknown" << endl;
01188 return false;
01189 }
01190 plist::filteredDisplay(cout,*ob,"^[^.].*",REG_EXTENDED,3);
01191 return true;
01192 }
01193 bool Simulator::cmdSet(const std::vector<std::string>& args) {
01194 if(args.size()==0 || (args[0]=="set" && args.size()==1)) {
01195 plist::filteredDisplay(cout,sim::config,"^[^.].*",REG_EXTENDED,3);
01196 return false;
01197 }
01198 string arg;
01199 for(unsigned int i=(args[0]=="set"?1:0); i<args.size(); i++) {
01200 arg+=args[i];
01201 if(i!=args.size()-1)
01202 arg+=" ";
01203 }
01204 const string WS_PREFIX="WorldState";
01205 if(arg.rfind("=")==string::npos) {
01206 if(arg.substr(0,WS_PREFIX.size())==WS_PREFIX) {
01207 return SensorStateAccessor().print(arg);
01208 }
01209 plist::ObjectBase* ob=sim::config.resolveEntry(arg);
01210 if(ob==NULL) {
01211 cout << "'" << arg << "' is unknown" << endl;
01212 return false;
01213 }
01214 plist::filteredDisplay(cout,*ob,"^[^.].*",REG_EXTENDED,3);
01215 } else {
01216 return sim::config.resolveAssignment(arg,std::cerr);
01217 }
01218 return false;
01219 }
01220 void Simulator::cmdRun(const std::vector<std::string>& args, bool isRelative) {
01221 if(args.size()<=1) {
01222 cout << "runfor/runto requires an argument" << endl;
01223 return;
01224 }
01225 if(isRelative)
01226 globals->setAutoPauseTime(get_time()+atoi(args[1].c_str()));
01227 else
01228 globals->setAutoPauseTime(atoi(args[1].c_str()));
01229 if(globals->timeScale==0)
01230 globals->timeScale=runSpeed;
01231 }
01232 void Simulator::cmdRun(const std::vector<std::string>& args) {
01233 if(args.size()<=1) {
01234 if(globals->timeScale!=0) {
01235 cout << "Already running" << endl;
01236 return;
01237 }
01238 globals->timeScale=runSpeed;
01239 } else {
01240 float speed=(float)atof(args[1].c_str());
01241 if(speed!=0)
01242 runSpeed=speed;
01243 globals->timeScale=speed;
01244 }
01245 }
01246 void Simulator::cmdPause(const std::vector<std::string>& args) {
01247 if(globals->timeScale==0) {
01248 if(find(args.begin(),args.end(),"quiet")==args.end())
01249 cout << "Already paused" << endl;
01250 return;
01251 }
01252 runSpeed=globals->timeScale;
01253 globals->timeScale=0;
01254 }
01255 void Simulator::cmdHelp(const std::vector<std::string>& args) {
01256 map<string,string> syntax;
01257 syntax["load"]="[file]";
01258 syntax["save"]="[file]";
01259 syntax["runlevel"]="[";
01260 for(unsigned int i=0; i<SharedGlobals::NUM_RUNLEVELS; i++) {
01261 stringstream ss;
01262 ss << i << "|" << SharedGlobals::runlevel_names[i];
01263 if(i!=SharedGlobals::NUM_RUNLEVELS-1)
01264 ss << " | ";
01265 syntax["runlevel"]+=ss.str();
01266 }
01267 syntax["runlevel"]+="]";
01268 syntax["get_time"]="";
01269 syntax["print"]="[var]";
01270 syntax["set"]="[var=value]";
01271 syntax["runto"]="time";
01272 syntax["runfor"]="time";
01273 syntax["run"]="[speed]";
01274 syntax["pause"]="";
01275 syntax["step"]="[camera|sensor|timer|motion]";
01276 syntax["status"]="[Main|Motion|SoundPlay|Simulator|all]*";
01277 syntax["advance"]=syntax["freeze"]=syntax["unfreeze"]="[camera|sensors|all]*";
01278 syntax["reset"]="[camera|sensors|all]";
01279 syntax["new"]="<type> [name]";
01280 syntax["delete"]="name";
01281 syntax["post"]="<generator> <source> <type> [duration]";
01282 syntax["msg"]="<string>";
01283
01284 map<string,string> help;
01285
01286 help["load"]="Load HAL configuration from file; if file unspecified, uses last specified file ('hal-$MODEL.plist' by default).\n"
01287 "Note that these files are human-readable XML (with comments!), and you can remove values to specify only a subset of settings.";
01288
01289 help["save"]="Save HAL configuration to file; if file unspecified, uses last specified file ('hal-$MODEL.plist' by default).\n"
01290 "Note that these files are human-readable XML (with comments!), and you can remove values to specify only a subset of settings.";
01291
01292 help["runlevel"]="You can specify a runlevel to move to, or if unspecified, the next one.\n"
01293 "You can only move forward runlevels, not backward. Usually you'll only need RUNNING, "
01294 "unless you are debugging startup/shutdown code or the Tekkotsu itself.";
01295
01296 help["get_time"]="Displays the simulator time.";
01297
01298 help["print"]="Displays a configuration entry. Can also call 'set' without an assignment.";
01299
01300 help["set"]="Sets HAL configuration variables. Without any arguments, displays all available variables and their current values.\n"
01301 "Type 'help set <variable>' to get more information about a particular variable.\n"
01302 "You can also use the set command to assign values for buttons and sensors when not connected to physical hardware. Type 'print WorldState' to see available keys.";
01303
01304 help["runto"]="Triggers 'run' until the simulator time reaches the specified value and then pauses.";
01305
01306 help["runfor"]="Triggers 'run' until the simulator time has moved by the specified number of milliseconds, then pauses.";
01307
01308 help["run"]="Resets speed to last non-zero value (i.e. value prior to last 'pause'), can override by passing a new value as argument. Can be abbreviated 'r'.";
01309
01310 help["pause"]="Equivalent to 'set Speed=0'. Can be abbreviated 'p'. Stops the flow of time within the simulator.";
01311
01312 help["step"]="Runs at \"full\" speed until the next indicated time frame, or the next available frame if no type is specified.\n"
01313 "See 'status' for available frames.";
01314
01315 help["status"]="Displays a status report regarding current time, upcoming keyframes, and semaphore usage. Specify one or more processes to get more in-depth, per-process status reports.";
01316
01317 help["advance"]="Sends the next frame for the specified queue(s) in their listed order (can be listed more than once).\n"
01318 "Disregards timestamp information, and doesn't advance time, unlike 'step' command. No arguments and \"all\" is the same as \"sensors camera\".";
01319
01320 help["freeze"]="Equivalent to 'set queue.Frozen=true'.\n"
01321 "Stops sending frames from the specified queue(s), but still allows time to move (unlike 'pause'). No arguments is the same as \"all\". See 'advance' and 'unfreeze'.";
01322
01323 help["unfreeze"]="Equivalent to 'set queue.Frozen=false'.\n"
01324 "Begin sending frames from the specified queue(s) again. Timestamps for the file listing are offset by the time spent frozen minus frames advanced so the queue(s) will continue from their current position. No arguments is the same as \"all\".";
01325
01326 help["reset"]="Moves the specified data queue(s) back to the first entry in their list.";
01327
01328 help["new"]="Creates a new driver or communication port instance.\n Driver types are:";
01329 set<string> driverNames;
01330 DeviceDriver::getRegistry().getTypeNames(driverNames);
01331 for(set<string>::iterator it=driverNames.begin(); it!=driverNames.end(); ++it)
01332 help["new"]+=" "+*it;
01333 set<string> commNames;
01334 CommPort::getRegistry().getTypeNames(commNames);
01335 help["new"]+="\n Communication ports types are:";
01336 for(set<string>::iterator it=commNames.begin(); it!=commNames.end(); ++it)
01337 help["new"]+=" "+*it;
01338
01339 help["delete"]="Remove an entry from the CommPort or Drivers list";
01340
01341 help["post"]="Posts an event to the Main process, same as Controller's !post command";
01342
01343 help["msg"]="Posts a TextMsgEvent to the Main process, same as Controller's !msg command";
01344
01345 if(args.size()==1) {
01346 cout << "Available commands: " << endl;
01347 for(map<string,string>::const_iterator it=help.begin(); it!=help.end(); ++it) {
01348 cout << '\t' << it->first << " " << syntax[it->first] << endl;
01349 }
01350 cout << "type 'help <command>' for more information" << endl;
01351 } else {
01352 if(help.find(args[1])==help.end()) {
01353 cout << "The command '"<< args[1] << "' was not found" << endl;
01354 return;
01355 }
01356 if(args.size()==2) {
01357 cout << args[1] << " " << syntax[args[1]] << endl;
01358 cout << help[args[1]] << endl;
01359 } else {
01360 if(args[1]=="set") {
01361 plist::ObjectBase* ob=sim::config.resolveEntry(args[2]);
01362 if(ob==NULL) {
01363 cout << "'" << args[2] << "' is unknown" << endl;
01364 return;
01365 }
01366 size_t n=args[2].rfind('.');
01367 if(n==string::npos)
01368 cout << sim::config.getComment(args[2]) << endl;
01369 else {
01370 ob=sim::config.resolveEntry(args[2].substr(0,n));
01371 if(const plist::Dictionary * dict=dynamic_cast<const plist::Dictionary*>(ob))
01372 cout << dict->getComment(args[2].substr(n+1)) << endl;
01373 else
01374 cout << "'" << args[2].substr(0,n) << "' is not a dictionary" << endl;
01375 }
01376 } else {
01377 cout << args[1] << " " << syntax[args[1]] << endl;
01378 cout << help[args[1]] << endl;
01379 }
01380 }
01381 }
01382 }
01383 void Simulator::cmdStep(const std::vector<std::string>& args) {
01384 if(args.size()<=1) {
01385 if(globals->timeScale!=0)
01386 globals->timeScale=0;
01387 step=STEP_NONE;
01388 incrementTime();
01389 return;
01390 }
01391 if(args.size()>2) {
01392 cout << args[0] << " takes 0 or 1 arguments; " << args.size()-1 << " supplied" << endl;
01393 return;
01394 }
01395 if(args[1]=="camera")
01396 step=STEP_CAMERA;
01397 else if(args[1]=="sensor" || args[1]=="sensors")
01398 step=STEP_SENSOR;
01399 else if(args[1]=="timer")
01400 step=STEP_TIMER;
01401 else if(args[1]=="motion")
01402 step=STEP_MOTION;
01403 else {
01404 cout << args[1] << " is not a valid argument for 'step'. Type 'help step'." << endl;
01405 return;
01406 }
01407
01408
01409
01410
01411
01412
01413
01414
01415 {
01416 unsigned int steps=getNextFrame();
01417 if((1<<step) & steps) {
01418 if(globals->timeScale!=0)
01419 globals->timeScale=0;
01420 step=STEP_NONE;
01421 incrementTime();
01422 } else if(globals->timeScale!=-1)
01423 globals->timeScale=-1;
01424 }
01425 }
01426 void Simulator::cmdStatus(const std::vector<std::string>& args) {
01427 cout << "Speed is " << static_cast<float>(globals->timeScale);
01428 if(globals->timeScale<0)
01429 cout << " (full speed mode: avg speed=" << ((globals->simulatorTime-fullspeedSimStart)/fullspeedWallStart.Age().Value()/1000) << "x, "
01430 << " current speed=" << (avgSimTime/avgWallTime/1000) << "x)";
01431 cout << endl;
01432 cout << "Current time is " << get_time() << endl;
01433 unsigned int sen=nextSensorTime();
01434 unsigned int tim=globals->getNextTimer();
01435 unsigned int mot=globals->getNextMotion();
01436 cout << "Next camera: ";
01437 if(activeCameraSrcs.size()==0) cout << "(none)"; else {
01438 cout << nextVisionTime() << " (";
01439 for(std::set<DataSource*>::const_iterator it=activeCameraSrcs.begin(); it!=activeCameraSrcs.end(); ++it) {
01440 if(it!=activeCameraSrcs.begin())
01441 cout << ' ';
01442 cout << lookupDataSourceName(*it) << ':' << (*it)->nextName() << '@' << (*it)->nextTimestamp();
01443 if((*it)->getFrozen())
01444 cout << "(frozen)";
01445 }
01446 cout << ")";
01447 }
01448 cout << endl;
01449
01450 cout << "Next sensor: ";
01451 if(sen==-1U) cout << "(none)"; else cout << sen;
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462 cout << endl;
01463 cout << "Next timer: ";
01464 if(tim==-1U) cout << "(none)"; else cout << tim;
01465 cout << endl;
01466 cout << "Next motion: ";
01467 if(mot==-1U) cout << "(none)"; else cout << mot;
01468 cout << endl;
01469 unsigned int semUsed=MessageQueueBase::getSemaphoreManager()->used();
01470 unsigned int semMax=semUsed+MessageQueueBase::getSemaphoreManager()->available();
01471 cout << "Semaphores used: " << semUsed << "/" << semMax << " (" << ((semUsed*10000+5)/semMax/10)/10.f << "%)" << endl;
01472 cout << endl;
01473 if(args.size()>1) {
01474 if(args[1].substr(0,6)=="region") {
01475 SemaphoreManager::semid_t sem=statusRequest->addReadStatusListener();
01476 std::set<std::string> tgts;
01477 std::copy(args.begin()+2,args.end(),std::inserter(tgts,tgts.end()));
01478 if(tgts.size()==0)
01479 tgts.insert("all");
01480 for(std::set<std::string>::const_iterator it=tgts.begin(); it!=tgts.end(); ++it) {
01481 RCRegion * region=new RCRegion(it->size()+1);
01482 strncpy(region->Base(),it->c_str(),region->Size());
01483 statusRequest->sendMessage(region);
01484 region->RemoveReference();
01485 }
01486
01487 if(sem!=statusRequest->getSemaphoreManager()->invalid()) {
01488 statusRequest->getSemaphoreManager()->lower(sem,tgts.size());
01489 statusRequest->removeReadStatusListener(sem);
01490 }
01491
01492 for(std::set<std::string>::const_iterator it=tgts.begin(); it!=tgts.end(); ++it) {
01493 if(strcasecmp(it->c_str(),getName())==0 || strcasecmp(it->c_str(),"all")==0) {
01494 statusReport(cout);
01495 cout << endl;
01496 }
01497 }
01498 } else if(args[1]=="feedback") {
01499 cout << "Sensor feedback for outputs:\n";
01500 unsigned int len=10;
01501 for(unsigned int i=0; i<NumOutputs; ++i)
01502 if(strlen(outputNames[i])>len)
01503 len=strlen(outputNames[i]);
01504 cout << " " << setw(len+2) << left << "--OUTPUT--" << "--FEEDBACK-SOURCE--\n";
01505 for(unsigned int i=0; i<NumOutputs; ++i) {
01506 cout << " " << setw(len+2) << left << outputNames[i];
01507 if(globals->sensorState.providedOutputs[i]==0) {
01508 cout << (globals->motion.feedbackDelay<0 ? "none (Motion.FeedbackDelay is negative)\n" : "motion process (open loop)\n");
01509 } else if(globals->sensorState.providedOutputs[i]==1) {
01510 cout << (globals->motion.feedbackDelay>=0 && globals->motion.override ? "motion process override (open loop)\n" : "sensed by device driver\n");
01511 } else {
01512 if(globals->motion.feedbackDelay>=0 && globals->motion.override)
01513 cout << "motion process override (open loop)\n";
01514 else
01515 cout << "provided by " << globals->sensorState.providedOutputs[i] << " device drivers (may be conflict)\n";
01516 }
01517 }
01518 }
01519 }
01520 }
01521 void Simulator::cmdAdvance(const std::vector<std::string>& args) {
01522 if(curLevel!=SharedGlobals::RUNNING) {
01523 cout << args[0] << " can only be used in the RUNNING runlevel" << endl;
01524 return;
01525 }
01526
01527
01528 struct { void operator()(const std::set<DataSource*>& src, std::set<DataSource*>& dst) {
01529 std::remove_copy_if(src.begin(), src.end(), std::inserter(dst,dst.end()), std::not1(std::mem_fun(&DataSource::getFrozen)));
01530 } } copyUnfrozen;
01531
01532 std::set<DataSource*> camSrcs, senSrcs;
01533
01534 bool isAll=false;
01535 if(args.size()<=1) {
01536
01537 copyUnfrozen(activeCameraSrcs,camSrcs);
01538 copyUnfrozen(activeSensorSrcs,senSrcs);
01539 isAll=true;
01540
01541 } else for(unsigned int i=1; i<args.size(); ++i) {
01542
01543 if(args[i]=="camera" || args[i]=="vision" || args[i]=="image") {
01544 copyUnfrozen(activeCameraSrcs,camSrcs);
01545 } else if(args[i]=="sensors") {
01546 copyUnfrozen(activeSensorSrcs,senSrcs);
01547 } else {
01548 std::string errStrC,errStrS;
01549
01550 std::set<DataSource*> tmp;
01551 lookupDataSource(args[i], &DeviceDriver::getImageSources, tmp, errStrC);
01552 copyUnfrozen(tmp,camSrcs);
01553
01554 tmp.clear();
01555 lookupDataSource(args[i], &DeviceDriver::getSensorSources, tmp, errStrS);
01556 copyUnfrozen(tmp,senSrcs);
01557
01558 if(errStrC.size()>0 && errStrS.size()>0) {
01559 std::cerr << errStrS << std::endl;
01560 return;
01561 }
01562 }
01563 }
01564
01565
01566
01567 for(std::set<DataSource*>::const_iterator it=camSrcs.begin(); it!=camSrcs.end(); ++it) {
01568 SemaphoreManager::semid_t sem=cameraQueue->addReadStatusListener();
01569 bool sent = (*it)->advance();
01570 if(!sent && !isAll)
01571 cout << "No data in " << lookupDataSourceName(*it) << " queue" << endl;
01572 if(sent)
01573 cameraQueue->getSemaphoreManager()->lower(sem,true);
01574 cameraQueue->removeReadStatusListener(sem);
01575 }
01576
01577
01578 for(std::set<DataSource*>::const_iterator it=senSrcs.begin(); it!=senSrcs.end(); ++it) {
01579 SemaphoreManager::semid_t sem=sensorQueue->addReadStatusListener();
01580 bool sent = (*it)->advance();
01581 if(!sent && !isAll)
01582 cout << "No data in " << lookupDataSourceName(*it) << " queue" << endl;
01583 if(sent && globals->timeScale==0) {
01584 ASSERT(!sensorThread.isStarted(), "advance while paused, yet timeScale is non-zero?");
01585 sendSensorSent=false;
01586 sent = sendSensor(true);
01587 }
01588 if(sent)
01589 sensorQueue->getSemaphoreManager()->lower(sem,true);
01590 sensorQueue->removeReadStatusListener(sem);
01591 }
01592 }
01593 void Simulator::cmdFreeze(bool v, const std::vector<std::string>& args) {
01594 std::set<DataSource*> srcs;
01595
01596 if(args.size()<=1) {
01597
01598 std::merge(activeSensorSrcs.begin(),activeSensorSrcs.end(), activeCameraSrcs.begin(),activeCameraSrcs.end(), std::inserter(srcs,srcs.end()));
01599
01600 } else for(unsigned int i=1; i<args.size(); ++i) {
01601 if(args[i]=="camera" || args[i]=="vision" || args[i]=="image") {
01602 srcs.insert(activeCameraSrcs.begin(),activeCameraSrcs.end());
01603 } else if(args[i]=="sensors") {
01604 srcs.insert(activeSensorSrcs.begin(),activeSensorSrcs.end());
01605 } else {
01606 std::string errStrC,errStrS;
01607 lookupDataSource(args[i], &DeviceDriver::getImageSources, srcs, errStrC);
01608 lookupDataSource(args[i], &DeviceDriver::getSensorSources, srcs, errStrS);
01609 if(errStrC.size()>0 && errStrS.size()>0) {
01610 std::cerr << errStrS << std::endl;
01611 return;
01612 }
01613 }
01614 }
01615
01616 for(std::set<DataSource*>::const_iterator it=srcs.begin(); it!=srcs.end(); ++it)
01617 (*it)->setFrozen(v);
01618 }
01619 void Simulator::cmdReset(const std::vector<std::string>& args) {
01620 std::set<DataSource*> srcs;
01621 for(unsigned int i=1; i<args.size(); ++i) {
01622 if(args[i]=="camera" || args[i]=="vision" || args[i]=="image") {
01623 srcs.insert(activeCameraSrcs.begin(),activeCameraSrcs.end());
01624 } else if(args[i]=="sensors") {
01625 srcs.insert(activeSensorSrcs.begin(),activeSensorSrcs.end());
01626 } else {
01627 std::string errStr;
01628 lookupDataSource(args[i], &DeviceDriver::getSensorSources, srcs, errStr);
01629 if(errStr.size()>0) {
01630 lookupDataSource(args[i], &DeviceDriver::getImageSources, srcs, errStr);
01631 if(errStr.size()>0) {
01632 std::cerr << errStr << std::endl;
01633 return;
01634 }
01635 }
01636 }
01637 }
01638
01639 for(std::set<DataSource*>::const_iterator it=srcs.begin(); it!=srcs.end(); ++it)
01640 (*it)->reset();
01641 }
01642 void Simulator::cmdNew(const std::vector<std::string>& args) {
01643 set<string> driverNames;
01644 DeviceDriver::getRegistry().getTypeNames(driverNames);
01645 set<string> commNames;
01646 CommPort::getRegistry().getTypeNames(commNames);
01647 if(args.size()<2) {
01648 cerr << "Must specify type to instantiate:\n";
01649 cerr << " Communication Ports:";
01650 for(set<string>::iterator it=commNames.begin(); it!=commNames.end(); ++it)
01651 cerr << ' ' << *it;
01652 cerr << endl;
01653 cerr << " Device Drivers:";
01654 for(set<string>::iterator it=driverNames.begin(); it!=driverNames.end(); ++it)
01655 cerr << ' ' << *it;
01656 cerr << endl;
01657 return;
01658 }
01659 std::string type = args[1];
01660 std::string name = (args.size()>2) ? args[2] : args[1];
01661 try {
01662 if(driverNames.find(type)!=driverNames.end()) {
01663 DeviceDriver * d = DeviceDriver::getRegistry().create(type,name);
01664 if(d==NULL) {
01665 cerr << "Error instantiating " << type << " (instance with same name already exists?)" << endl;
01666 return;
01667 }
01668 } else if(commNames.find(type)!=commNames.end()) {
01669 CommPort * c = CommPort::getRegistry().create(type,name);
01670 if(c==NULL) {
01671 cerr << "Error instantiating " << type << " (instance with same name already exists?)" << endl;
01672 return;
01673 }
01674 } else {
01675 cerr << "'" << type << "' is not a valid type for instantiation. Please choose one of:\n";
01676 cerr << " Communication Ports:";
01677 for(set<string>::iterator it=commNames.begin(); it!=commNames.end(); ++it)
01678 cerr << ' ' << *it;
01679 cerr << endl;
01680 cerr << " Device Drivers:";
01681 for(set<string>::iterator it=driverNames.begin(); it!=driverNames.end(); ++it)
01682 cerr << ' ' << *it;
01683 cerr << endl;
01684 }
01685 } catch(const std::exception& e) {
01686 cout << "An exception occured during construction of "<<type<<": " << e.what() << endl;
01687 } catch(...) {
01688 cout << "An exception occured during construction of "<<type << endl;
01689 }
01690 }
01691
01692 void Simulator::cmdDelete(const std::vector<std::string>& args) {
01693 if(args.size()<2) {
01694 cerr << "Must specify instance to delete:\n";
01695 cerr << " Communication Ports:";
01696 for(CommPort::registry_t::const_iterator it=CommPort::getRegistry().begin(); it!=CommPort::getRegistry().end(); ++it)
01697 cerr << ' ' << it->first;
01698 cerr << endl;
01699 cerr << " Device Drivers:";
01700 for(DeviceDriver::registry_t::const_iterator it=DeviceDriver::getRegistry().begin(); it!=DeviceDriver::getRegistry().end(); ++it)
01701 cerr << ' ' << it->first;
01702 cerr << endl;
01703 return;
01704 }
01705 if(DeviceDriver::getRegistry().getInstance(args[1])!=NULL) {
01706 if(!DeviceDriver::getRegistry().destroy(args[1]))
01707 cerr << "Could not delete driver named '" << args[1] << "'" << endl;
01708 } else if(CommPort::getRegistry().getInstance(args[1])!=NULL) {
01709 if(!CommPort::getRegistry().destroy(args[1]))
01710 cerr << "Could not delete comm port named '" << args[1] << "'" << endl;
01711 } else {
01712
01713 string key=string_util::trim(args[1]);
01714 plist::ObjectBase* ob=sim::config.resolveEntry(key);
01715 if(ob==NULL) {
01716 cerr << "'" << key << "' is unknown" << endl;
01717 } else {
01718 string::size_type dotpos = key.rfind(".");
01719 string parent = key.substr(0,dotpos);
01720 string entry = key.substr(dotpos+1);
01721 ob=sim::config.resolveEntry(parent);
01722 if(ob==NULL) {
01723 cerr << "Internal error, could not access parent '" << parent << "' of key '" << key << "' for removal" << endl;
01724 } else if(plist::Collection* col=dynamic_cast<plist::Collection*>(ob)) {
01725 if((col->getLoadPolicy() & plist::Collection::REMOVALS) != plist::Collection::REMOVALS) {
01726 cerr << "Collection '" << parent << "' is not dynamically resizeable, cannot remove entry '" << entry << "'" << endl;
01727 } else if(plist::ArrayBase* arr=dynamic_cast<plist::ArrayBase*>(ob)) {
01728 size_t i = atoi(entry.c_str());
01729 arr->removeEntry(i);
01730 } else if(plist::DictionaryBase* dict=dynamic_cast<plist::DictionaryBase*>(ob)) {
01731 dict->removeEntry(entry);
01732 } else {
01733 cerr << "Internal error, unknown collection type for removing entry '" << entry <<"' from '" << parent << "'" << endl;
01734 }
01735 } else {
01736 cerr << '\'' << parent <<'\'' << " is not a collection, cannot remove entry '" << entry << '\'' << endl;
01737 }
01738 }
01739 }
01740 }
01741
01742 void Simulator::cmdPost(const std::vector<std::string>& args) {
01743 if(args.size()<4) {
01744 cerr << "Bad post command, need at least 3 arguments: generator source type [duration]" << endl;
01745 return;
01746 }
01747
01748 int egid=0;
01749 for(;egid<EventBase::numEGIDs && args[1]!=EventBase::EventGeneratorNames[egid];egid++) {}
01750 if(egid==EventBase::numEGIDs) {
01751 egid=atoi(args[1].c_str());
01752 if(egid==0 && args[1]!="0") {
01753 cerr << "Bad event generator '" << args[1] << "'" << endl;
01754 return;
01755 }
01756 }
01757
01758
01759 unsigned int name;
01760 if(egid==EventBase::buttonEGID) {
01761 name=capabilities.findButtonOffset(args[2].c_str());
01762 if(name==-1U) {
01763 name=atoi(args[2].c_str());
01764 if(name==0 && args[2]!="0") {
01765 cerr << "Invalid button name or index '" << args[2] << "'" << endl;
01766 return;
01767 }
01768 }
01769 } else {
01770 name=atoi(args[2].c_str());
01771 }
01772
01773 int etid=0;
01774 for(;etid<EventBase::numETIDs && args[3]!=EventBase::EventTypeNames[etid];etid++) {}
01775 if(etid==EventBase::numETIDs) {
01776 etid=0;
01777 for(;etid<EventBase::numETIDs && args[3]!=EventBase::EventTypeAbbr[etid];etid++) {}
01778 if(etid==EventBase::numETIDs) {
01779 etid=atoi(args[3].c_str());
01780 if(etid==0 && args[3]!="0") {
01781 cerr << "Bad event type '" << args[3] << "'" << endl;
01782 return;
01783 }
01784 }
01785 }
01786
01787 int dur=0;
01788 if(args.size()>4)
01789 dur=atoi(args[4].c_str());
01790
01791 SemaphoreManager::semid_t sem=events->addReadStatusListener();
01792 erouter->postEvent((EventBase::EventGeneratorID_t)egid,name,(EventBase::EventTypeID_t)etid,dur);
01793 events->getSemaphoreManager()->lower(sem,true);
01794 events->removeReadStatusListener(sem);
01795 }
01796
01797 void Simulator::cmdMsg(const std::vector<std::string>& args) {
01798 SemaphoreManager::semid_t sem=events->addReadStatusListener();
01799 string s;
01800 if(args.size()>1)
01801 s=args[1];
01802 for(size_t i=2; i<args.size(); ++i)
01803 s.append(" ").append(args[i]);
01804 erouter->postEvent(TextMsgEvent(s,0));
01805 events->getSemaphoreManager()->lower(sem,true);
01806 events->removeReadStatusListener(sem);
01807 }
01808
01809
01810
01811
01812
01813
01814