00001 #include "Motion.h"
00002 #include "Main.h"
00003 #include "SoundPlay.h"
00004 #include "Simulator.h"
00005 #include "SimConfig.h"
00006 #include "Shared/Config.h"
00007 #include "MotionExecThread.h"
00008
00009 #include "IPC/RegionRegistry.h"
00010 #include "IPC/MessageReceiver.h"
00011 #include "Motion/Kinematics.h"
00012 #include "Wireless/Wireless.h"
00013 #include "Events/EventRouter.h"
00014 #include "Shared/MarkScope.h"
00015
00016 #include "local/MotionHooks/IPCMotionHook.h"
00017
00018 using namespace std;
00019
00020 Motion::Motion()
00021 : Process(getID(),getClassName()),
00022 sounds(ipc_setup->registerRegion(SoundPlay::getSoundPlayID(),sizeof(sim::SoundPlayQueue_t))),
00023 motions(ipc_setup->registerRegion(getMotionCommandID(),sizeof(sim::MotionCommandQueue_t))),
00024 motionout(ipc_setup->registerRegion(getMotionOutputID(),sizeof(sim::MotionOutput_t))),
00025 motionoutpids(ipc_setup->registerRegion(getMotionOutputPIDsID(),sizeof(sim::MotionOutputPIDs_t))),
00026 events(ipc_setup->registerRegion(Main::getEventsID(),sizeof(sim::EventQueue_t))),
00027 statusRequest(ipc_setup->registerRegion(Simulator::getStatusRequestID(),sizeof(sim::StatusRequest_t))),
00028 motionmanager(ipc_setup->registerRegion(getMotionManagerID(),sizeof(MotionManager))),
00029 soundmanager(ipc_setup->registerRegion(SoundPlay::getSoundManagerID(),sizeof(SoundManager))),
00030 motionWakeup(ipc_setup->registerRegion(Simulator::getMotionWakeupID(),sizeof(sim::MotionWakeup_t))),
00031 motionProf(ipc_setup->registerRegion(getMotionProfilerID(),sizeof(motionProfiler_t))),
00032 etrans(NULL), statusrecv(NULL), wakeuprecv(NULL), motionExec(NULL), motionfwd(NULL),
00033 wireless_thread(), motionLock()
00034 {
00035 new (&(*motions)) sim::MotionCommandQueue_t;
00036 new (&(*motionout)) sim::MotionOutput_t;
00037 new (&(*motionoutpids)) sim::MotionOutputPIDs_t;
00038 new (&(*motionmanager)) MotionManager;
00039 new (&(*motionProf)) motionProfiler_t;
00040 motman=&(*motionmanager);
00041 motman->InitAccess(*motions,motionLock);
00042 sndman=&(*soundmanager);
00043 ::motionProfiler=&(*motionProf);
00044
00045 if(sim::config.multiprocess) {
00046
00047 ASSERT(wireless==NULL,"global wireless already initialized before Motion?");
00048 wireless = new Wireless();
00049 sout=wireless->socket(Socket::SOCK_STREAM,Wireless::WIRELESS_DEF_RECV_SIZE,Wireless::WIRELESS_DEF_SEND_SIZE*12);
00050 serr=wireless->socket(Socket::SOCK_STREAM,Wireless::WIRELESS_DEF_RECV_SIZE,Wireless::WIRELESS_DEF_SEND_SIZE*4);
00051 wireless->setDaemon(sout);
00052 wireless->setDaemon(serr);
00053 serr->setFlushType(Socket::FLUSH_BLOCKING);
00054 sout->setTextForward();
00055 serr->setForward(sout);
00056
00057
00058 ASSERT(kine==NULL,"global kine already initialized before Motion?");
00059 kine=new Kinematics();
00060 }
00061
00062
00063 }
00064
00065 Motion::~Motion() {
00066 if(sim::config.multiprocess) {
00067 delete wireless;
00068 wireless=NULL;
00069 delete kine;
00070 kine=NULL;
00071 }
00072 }
00073
00074 void Motion::doStart() {
00075 Process::doStart();
00076
00077
00078 sndman->InitAccess(*sounds);
00079 if(!sim::config.multiprocess) {
00080
00081 EventTranslator * forwardTrans = new IPCEventTranslator(*events);
00082 forwardTrans->setTrapEventValue(true);
00083 erouter->setForwardingAgent(getID(),forwardTrans);
00084 MotionManager::setTranslator(forwardTrans);
00085 } else {
00086 etrans=new IPCEventTranslator(*events);
00087 MotionManager::setTranslator(etrans);
00088
00089
00090
00091 for(unsigned int i=0; i<EventBase::numEGIDs; i++)
00092 if(i!=EventBase::erouterEGID)
00093 erouter->addTrapper(etrans,static_cast<EventBase::EventGeneratorID_t>(i));
00094
00095 wireless->listen(sout, config->motion.console_port);
00096 wireless->listen(serr, config->motion.stderr_port);
00097 wireless_thread.start();
00098
00099 Simulator::motionHookMonitor = new Simulator::MotionMonitorThread;
00100 }
00101
00102
00103 if(globals->motion.startPose.size()>0) {
00104 for(unsigned int i=0; i<NumOutputs; ++i)
00105 motman->setOutput(NULL, i, state->outputs[i]=globals->sensorState.outputs[i]);
00106 }
00107
00108 statusrecv=new MessageReceiver(*statusRequest,statusReport);
00109 wakeuprecv=new MessageReceiver(*motionWakeup,gotWakeup,false);
00110
00111 motionExec=new MotionExecThread(motionLock);
00112 if(sim::config.multiprocess) {
00113 Simulator::registerMotionHook(*(motionfwd=new IPCMotionHook(*motionout,*motionoutpids)));
00114 Simulator::setMotionStarting();
00115 if(globals->timeScale>0)
00116 Simulator::setMotionEnteringRealtime();
00117 }
00118 }
00119
00120
00121 void Motion::run() {
00122 if(globals->waitForSensors)
00123 globals->waitSensors();
00124
00125
00126
00127 if(globals->isShutdown())
00128 return;
00129
00130 motionExec->reset();
00131 wakeuprecv->start();
00132 Process::run();
00133 wakeuprecv->stop();
00134 wakeuprecv->join();
00135 if(motionExec->isStarted()) {
00136 motionExec->stop();
00137 motionExec->join();
00138 }
00139 }
00140
00141 void Motion::doStop() {
00142 Simulator::deregisterMotionHook(*motionfwd);
00143 delete motionfwd;
00144
00145 wakeuprecv->finish();
00146 statusrecv->finish();
00147
00148 delete wakeuprecv;
00149 wakeuprecv=NULL;
00150 delete statusrecv;
00151 statusrecv=NULL;
00152
00153 delete motionExec;
00154 motionExec=NULL;
00155
00156 if(!sim::config.multiprocess) {
00157 erouter->setForwardingAgent(getID(),NULL);
00158 MotionManager::setTranslator(NULL);
00159 } else {
00160 if(globals->timeScale>0)
00161 Simulator::setMotionLeavingRealtime(false);
00162 Simulator::setMotionStopping();
00163
00164 erouter->removeTrapper(etrans);
00165 delete etrans;
00166 etrans=NULL;
00167 MotionManager::setTranslator(NULL);
00168
00169 wireless_thread.stop();
00170 wireless_thread.join();
00171 wireless->setDaemon(sout,false);
00172 wireless->close(sout);
00173 sout=NULL;
00174 wireless->setDaemon(serr,false);
00175 wireless->close(serr);
00176 serr=NULL;
00177
00178 delete Simulator::motionHookMonitor;
00179 Simulator::motionHookMonitor=NULL;
00180 }
00181 motman->RemoveAccess();
00182
00183 Process::doStop();
00184 }
00185
00186 bool Motion::gotWakeup(RCRegion* ) {
00187 Motion * motion=dynamic_cast<Motion*>(Process::getCurrent());
00188 ASSERTRETVAL(motion!=NULL,"gotWakeup, but not within motion process!",true);
00189 ASSERTRETVAL(motion->motionExec!=NULL,"motionExec thread is NULL when motion wakeup received",true);
00190
00191 MarkScope l(motion->motionLock);
00192 if(sim::config.multiprocess) {
00193 if(globals->timeScale<=0) {
00194 if(motion->motionExec->isStarted())
00195 Simulator::setMotionLeavingRealtime(globals->timeScale<0);
00196 if(Simulator::motionHookMonitor->isStarted())
00197 Simulator::motionHookMonitor->stop();
00198 } else {
00199 if(!motion->motionExec->isStarted())
00200 Simulator::setMotionEnteringRealtime();
00201 if(!Simulator::motionHookMonitor->isStarted())
00202 Simulator::motionHookMonitor->start();
00203 }
00204 }
00205 if(globals->timeScale<=0 && get_time()>=globals->getNextMotion())
00206 motion->motionExec->poll();
00207 motion->motionExec->reset();
00208 return true;
00209 }
00210
00211
00212
00213
00214
00215