Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

Motion.cc

Go to the documentation of this file.
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     //Setup wireless
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     //Setup Kinematics
00058     ASSERT(kine==NULL,"global kine already initialized before Motion?");
00059     kine=new Kinematics();
00060   }
00061 
00062   //EventRouter and Config are set up for all processes by main() before fork
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   //These are constructed by other processes, so need to wait
00077   //until the construction runlevel is complete before we access them
00078   sndman->InitAccess(*sounds);
00079   if(!sim::config.multiprocess) {
00080     // don't use our own etrans here, because erouter will delete it for us, don't want a double-delete in our destructor...
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     // Set up Event Translator to trap and send events to main process
00090     //send everything over except erouter events
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   // initialize output values from initial pose loaded by Simulator constructor
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   // might have shutdown triggered while waiting
00126   // (perhaps device isn't available, user's killing the process...)
00127   if(globals->isShutdown())
00128     return; // skip running altogether
00129   
00130   motionExec->reset(); //starts the thread if appropriate
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* /*msg*/) {
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(); //reset will set globals->getNextMotion(), so have to do this after the poll itself
00208   return true;
00209 }
00210 
00211 /*! @file
00212  * @brief 
00213  * @author ejt (Creator)
00214  */
00215 

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