Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

SensorObserverControl.cc

Go to the documentation of this file.
00001 #include "SensorObserverControl.h"
00002 #include "Events/EventRouter.h"
00003 #include "Motion/MMAccessor.h"
00004 #include "Shared/WorldState.h"
00005 #include "Sound/SoundManager.h"
00006 #include "Shared/Config.h"
00007 
00008 #include "Shared/RobotInfo.h"
00009 #ifdef TGT_HAS_LEDS
00010 #  include "Motion/LedMC.h"
00011 #endif
00012 
00013 #include <sstream>
00014 
00015 REGISTER_CONTROL(SensorObserverControl,"Status Reports");
00016 
00017 SensorObserverControl::SensorObserverControl()
00018   : ControlBase("Sensor Observer","Allows you to see/log the sensor data"), logfilePath(), logfile(), helpCtl(NULL), sensorCtl(NULL), buttonCtl(NULL), outputCtl(NULL), dutyCtl(NULL), consoleCtl(NULL), fileCtl(NULL), rtCtl(NULL), rtFreqCtl(NULL), numListeners(0)
00019 {
00020   pushSlot(consoleCtl=new ToggleControl("Console Output","If selected, outputs events to the console"));
00021   pushSlot(fileCtl=new StringInputControl("[ ] File Output","Please enter the filename to log to (in /ms/...)"));
00022   pushSlot(rtCtl=new RTViewControl(this));
00023   pushSlot(rtFreqCtl=new StringInputControl("Real-time Update Period","Please enter the time between refreshes, in milliseconds; '0' to require manual refresh"));
00024   pushSlot(helpCtl=new ControlBase("Help"));
00025   pushSlot(NULL);
00026   helpCtl->pushSlot(new NullControl("The indexes listed here"));
00027   helpCtl->pushSlot(new NullControl("correspond to offsets"));
00028   helpCtl->pushSlot(new NullControl("given in the __Info.h"));
00029   helpCtl->pushSlot(new NullControl("file for the model"));
00030   helpCtl->pushSlot(new NullControl("robot which you are "));
00031   helpCtl->pushSlot(new NullControl("currently using."));
00032   pushSlot(sensorCtl=new ControlBase("Sensors:","Toggles logging of various sensors"));
00033   for(unsigned int i=0; i<NumSensors; i++)
00034     sensorCtl->pushSlot(new ToggleControl(sensorNames[i],"Turns logging of this sensor on/off"));
00035   pushSlot(buttonCtl=new ControlBase("Buttons:","Toggles logging of various buttons"));
00036   for(unsigned int i=0; i<NumButtons; i++)
00037     buttonCtl->pushSlot(new ToggleControl(buttonNames[i],"Turns logging of this button on/off"));
00038   pushSlot(outputCtl=new ControlBase("Outputs:","Toggles logging of various outputs' positions"));
00039   for(unsigned int i=0; i<NumOutputs; i++)
00040     outputCtl->pushSlot(new ToggleControl(outputNames[i],"Turns logging of this output's values on/off"));
00041   pushSlot(dutyCtl=new ControlBase("Duties:","Toggles logging of various PID joint's duty cycles"));
00042   for(unsigned int i=0; i<NumPIDJoints; i++)
00043     dutyCtl->pushSlot(new ToggleControl(outputNames[i+PIDJointOffset],"Turns logging of how hard this output is working on/off"));
00044   updateRT();
00045 }
00046 
00047 ControlBase* SensorObserverControl::doSelect() {
00048   ControlBase* ans=this;
00049   bool wasListening=(numListeners>0);
00050   for(unsigned int i=0; i<hilights.size(); i++) {
00051     unsigned int cur=hilights[i];
00052     if(options[cur]==fileCtl) {
00053       if(options[cur]->getName()[1]!=' ') {
00054         logfile.close();
00055         options[cur]->setName("[ ] File Output");
00056         numListeners--;
00057       } else {
00058         ans=options[cur];
00059         numListeners++;
00060       }
00061     } else if(options[cur]==consoleCtl) {
00062       options[cur]->doSelect();
00063       if(consoleCtl->getStatus())
00064         numListeners--;
00065       else
00066         numListeners++;
00067     } else { //(options[cur]==helpCtl || options[cur]==sensorCtl || options[cur]==buttonCtl || options[cur]==outputCtl || options[cur]==dutyCtl || options[cur]==consoleCtl)
00068       ans=options[cur];
00069     }
00070   }
00071   sndman->playFile(config->controller.select_snd);
00072   if(wasListening!=(numListeners>0)) {
00073     if(numListeners>0)
00074       erouter->addListener(this,EventBase::sensorEGID,SensorSrcID::UpdatedSID);
00075     else
00076       erouter->removeListener(this);
00077   }
00078   if(ans==this)
00079     refresh();
00080   return ans;
00081 }
00082 
00083 void SensorObserverControl::refresh() {
00084   //check for change in log file
00085   checkLogFile();
00086   //check for change in real-time refresh period
00087   if(rtFreqCtl->getLastInput().size()>0) {
00088     unsigned int fr=atoi(rtFreqCtl->getLastInput().c_str());
00089     rtFreqCtl->clearLastInput();
00090     if(fr!=0 && rtCtl!=NULL)
00091       rtCtl->setPeriod(fr<100?100:fr); //limit to minimum period of 100ms
00092   }
00093   ControlBase::refresh();
00094 }
00095 
00096 void SensorObserverControl::processEvent(const EventBase& event) {
00097   if(event.getGeneratorID()==EventBase::sensorEGID) {
00098     std::ostringstream logdata;
00099     for(unsigned int i=0; i<NumSensors; i++)
00100       if(ToggleControl * tgl=dynamic_cast<ToggleControl*>(sensorCtl->getSlots()[i]))
00101         if(tgl->getStatus())
00102           logdata << state->lastSensorUpdateTime << "\tSENSOR:\t" << i << '\t' << state->sensors[i] << '\n';
00103     for(unsigned int i=0; i<NumButtons; i++)
00104       if(ToggleControl * tgl=dynamic_cast<ToggleControl*>(buttonCtl->getSlots()[i]))
00105         if(tgl->getStatus())
00106           logdata << state->lastSensorUpdateTime << "\tBUTTON:\t" << i << '\t' << state->buttons[i] << '\n';
00107     for(unsigned int i=0; i<NumOutputs; i++)
00108       if(ToggleControl * tgl=dynamic_cast<ToggleControl*>(outputCtl->getSlots()[i]))
00109         if(tgl->getStatus())
00110           logdata << state->lastSensorUpdateTime << "\tOUTPUT:\t" << i << '\t' << state->outputs[i] << '\n';
00111     for(unsigned int i=0; i<NumPIDJoints; i++)
00112       if(ToggleControl * tgl=dynamic_cast<ToggleControl*>(dutyCtl->getSlots()[i]))
00113         if(tgl->getStatus())
00114           logdata << state->lastSensorUpdateTime << "\tDUTY:\t" << i << '\t' << state->pidduties[i] << '\n';
00115     if(consoleCtl->getStatus())
00116       sout->printf("%s",logdata.str().c_str());
00117     checkLogFile();
00118     if(logfile)
00119       logfile << logdata.str() << std::flush;
00120   } else {
00121     serr->printf("WARNING: Unexpected event: %s\n",event.getName().c_str());
00122   }
00123 }
00124 
00125 void SensorObserverControl::checkLogFile() {
00126   if(fileCtl->getLastInput()!=logfilePath) {
00127     logfile.close();
00128     logfilePath=fileCtl->getLastInput();
00129     logfile.clear();
00130     if(logfilePath.size()!=0) {
00131       sout->printf("Opening `%s'\n",config->portPath(logfilePath).c_str());
00132       logfile.open(config->portPath(logfilePath).c_str());
00133       if(!logfile.fail()) {
00134         std::string tmp=fileCtl->getName();
00135         tmp[1]='X';
00136         fileCtl->setName(tmp+": "+logfilePath);
00137       } else {
00138         serr->printf("Opening `%s' failed\n",config->portPath(logfilePath).c_str());
00139       }
00140     }
00141   }
00142 }
00143 
00144 void SensorObserverControl::updateRT() {
00145   const unsigned int FTOS_LEN=50;
00146   char ftos[FTOS_LEN];
00147   rtCtl->clearSlots();
00148   bool first=true;
00149   for(unsigned int i=0; i<NumSensors; i++)
00150     if(ToggleControl * tgl=dynamic_cast<ToggleControl*>(sensorCtl->getSlots()[i]))
00151       if(tgl->getStatus()) {
00152         if(first)
00153           rtCtl->pushSlot(new NullControl("SENSORS:"));
00154         first=false;
00155         snprintf(ftos,FTOS_LEN,"%s: %g",sensorNames[i],state->sensors[i]);
00156         rtCtl->pushSlot(new NullControl(ftos));
00157       }
00158   first=true;
00159   for(unsigned int i=0; i<NumButtons; i++)
00160     if(ToggleControl * tgl=dynamic_cast<ToggleControl*>(buttonCtl->getSlots()[i]))
00161       if(tgl->getStatus()) {
00162         if(first)
00163           rtCtl->pushSlot(new NullControl("BUTTONS:"));
00164         first=false;
00165         snprintf(ftos,FTOS_LEN,"%s: %g",buttonNames[i],state->buttons[i]);
00166         rtCtl->pushSlot(new NullControl(ftos));
00167       }
00168   first=true;
00169   for(unsigned int i=0; i<NumOutputs; i++)
00170     if(ToggleControl * tgl=dynamic_cast<ToggleControl*>(outputCtl->getSlots()[i]))
00171       if(tgl->getStatus()) {
00172         if(first)
00173           rtCtl->pushSlot(new NullControl("OUTPUTS:"));
00174         first=false;
00175         snprintf(ftos,FTOS_LEN,"%s: %g",outputNames[i],state->outputs[i]);
00176         rtCtl->pushSlot(new NullControl(ftos));
00177       }
00178   first=true;
00179   for(unsigned int i=0; i<NumPIDJoints; i++)
00180     if(ToggleControl * tgl=dynamic_cast<ToggleControl*>(dutyCtl->getSlots()[i]))
00181       if(tgl->getStatus()) {
00182         if(first)
00183           rtCtl->pushSlot(new NullControl("DUTIES:"));
00184         first=false;
00185         snprintf(ftos,FTOS_LEN,"%s: %g",outputNames[i],state->pidduties[i]);
00186         rtCtl->pushSlot(new NullControl(ftos));
00187       }
00188   if(rtCtl->slotsSize()==0)
00189     rtCtl->pushSlot(new NullControl("No sensors selected","You need to select which sensors to view"));
00190 }
00191 
00192 void SensorObserverControl::RTViewControl::refresh() {
00193   if(parent!=NULL)
00194     parent->updateRT();
00195   if(period!=0)
00196     erouter->addTimer(this,0,period);
00197   ControlBase::refresh();
00198 }
00199 void SensorObserverControl::RTViewControl::pause() {
00200   erouter->removeTimer(this);
00201   ControlBase::pause();
00202 }
00203 void SensorObserverControl::RTViewControl::deactivate() {
00204   erouter->removeTimer(this);
00205   ControlBase::deactivate();
00206 }
00207 /*! The change doesn't get picked up until next call to refresh() */
00208 void SensorObserverControl::RTViewControl::setPeriod(unsigned int x) {
00209   period=x;
00210 }
00211 
00212 
00213 /*! @file
00214  * @brief Describes SensorObserverControl, which allows logging of sensor information to the console or file
00215  * @author ejt (Creator)
00216  */

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:50 2016 by Doxygen 1.6.3