Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

TorqueCalibrate.cc

Go to the documentation of this file.
00001 #define TORQUE_CALIBRATE_NO_WARN_NOOP
00002 #include "TorqueCalibrate.h"
00003 #undef TORQUE_CALIBRATE_NO_WARN_NOOP
00004 #include "Behaviors/Controls/NullControl.h"
00005 #include "Shared/WorldState.h"
00006 #include "Shared/Config.h"
00007 #include "Events/EventRouter.h"
00008 #include "Motion/MMAccessor.h"
00009 #include "Motion/PIDMC.h"
00010 #include "Motion/MotionSequenceMC.h"
00011 #include "Sound/SoundManager.h"
00012 #include "IPC/SharedObject.h"
00013 #include <fstream>
00014 #include <cmath>
00015 
00016 //better to put this here instead of the header
00017 using namespace std; 
00018 
00019 
00020 //***************************//
00021 //***** TorqueCalibrate *****//
00022 //***************************//
00023 
00024 void TorqueCalibrate::record(unsigned int joint, float sensorDist, float maxDuty, float maxForce) const {
00025   std::ofstream log(filename.c_str(),std::ios::app);
00026   if(!log) {
00027     serr->printf("ERROR: could not open %s for writing log\n",filename.c_str());
00028     sndman->playFile("fart.wav");
00029   } else {
00030     log << joint << '\t' << sensorDist << '\t' << maxDuty << '\t' << maxForce << std::endl;
00031     sndman->playFile("camera.wav");
00032   }
00033   std::cout << "DATA: " << joint << '\t' << sensorDist << '\t' << maxDuty << '\t' << maxForce << std::endl;
00034 }
00035 
00036 void TorqueCalibrate::refresh() {
00037   if(filenameInput->getLastInput()!=filename) {
00038     filename=filenameInput->getLastInput();
00039     std::string::size_type f=filename.rfind("/");
00040     filenameInput->setName("Storage: "+filename.substr(f==string::npos?0:f+1));
00041     std::string desc="Location where data will be appended to any previous contents";
00042     filenameInput->setDescription(desc+": "+filename);
00043     std::ofstream log(filename.c_str(),std::ios::app);
00044     if(!log)
00045       serr->printf("ERROR: could not open %s for writing log\n",filename.c_str());
00046   }
00047   ControlBase::refresh();
00048 }
00049 
00050 
00051 //******************************************************//
00052 //***** TorqueCalibrate::TakeMeasurementControl *****//
00053 //******************************************************//
00054 
00055 ControlBase * TorqueCalibrate::TakeMeasurementControl::activate(MC_ID disp_id, Socket * gui) {
00056 #ifdef TGT_HAS_BUTTONS
00057 #  ifdef TGT_ERS7
00058   erouter->addListener(this,EventBase::buttonEGID,FrontBackButOffset,EventBase::activateETID);
00059   erouter->addListener(this,EventBase::buttonEGID,MiddleBackButOffset,EventBase::activateETID);
00060   erouter->addListener(this,EventBase::buttonEGID,RearBackButOffset,EventBase::activateETID);
00061 #  else
00062   unsigned int offset = capabilities.findButtonOffset("BackBut");
00063   if(offset==-1U)
00064     offset=0; // we don't know what button to use, just take 'first' one
00065   erouter->addListener(this,EventBase::buttonEGID,offset,EventBase::activateETID);
00066 #  endif
00067 #endif
00068   cstate=ZERO_JOINT;
00069   SharedObject<PIDMC> pidmc(0);
00070   pidID=motman->addPersistentMotion(pidmc,MotionManager::kHighPriority);
00071   return ControlBase::activate(disp_id,gui);
00072 }
00073 
00074 void TorqueCalibrate::TakeMeasurementControl::processEvent(const EventBase& event) {
00075   if(cstate==ZERO_JOINT && event.getGeneratorID()==EventBase::buttonEGID) {
00076     basePosition=state->outputs[joint];
00077     transition(RECORD_POSITION);
00078   } else if(cstate==DO_PULSE && event.getGeneratorID()==EventBase::sensorEGID) {
00079     if(std::abs(state->pidduties[joint-PIDJointOffset]) > maxDuty)
00080       maxDuty=std::abs(state->pidduties[joint-PIDJointOffset]);
00081     std::cout << "Duty: " << state->pidduties[joint-PIDJointOffset] << std::endl;
00082   } else if(cstate==DO_PULSE && event.getGeneratorID()==EventBase::timerEGID) {
00083     erouter->removeListener(this,EventBase::sensorEGID);
00084   } else if(cstate==DO_PULSE && event.getGeneratorID()==EventBase::motmanEGID) {
00085     pulseID=invalid_MC_ID;
00086     std::cout << "Max duty: " << maxDuty << std::endl;
00087     transition(RECORD_FORCE);
00088   } else {
00089     std::cerr << "Unhandled event " << event.getName() << std::endl;
00090   }
00091 }
00092 
00093 void TorqueCalibrate::TakeMeasurementControl::refresh() {
00094   clearSlots();
00095   switch(cstate) {
00096     case ZERO_JOINT:
00097       pushSlot(new NullControl("Position the joint"));
00098       pushSlot(new NullControl("and press a back button"));
00099       break;
00100     case RECORD_POSITION:
00101       pushSlot(new NullControl("What is the length of"));
00102       pushSlot(new NullControl("the lever arm? (cm)"));
00103       pushSlot(new NullControl("(Dist. from axis of"));
00104       pushSlot(new NullControl("rot. to force sensor)"));
00105       break;
00106     case INPUT_PULSE:
00107       pushSlot(new NullControl("Enter the position"));
00108       pushSlot(new NullControl("offset to attempt"));
00109       pushSlot(new NullControl("(radians -- bigger"));
00110       pushSlot(new NullControl("offset means apply"));
00111       pushSlot(new NullControl("more force...)"));
00112       break;
00113     case DO_PULSE:
00114       pushSlot(new NullControl("Running..."));
00115       break;
00116     case RECORD_FORCE: {
00117       char res[256];
00118       snprintf(res,256,"Max duty was: %g",maxDuty);
00119       pushSlot(new NullControl(res));
00120       pushSlot(NULL);
00121       pushSlot(new NullControl("Enter the maximum"));
00122       pushSlot(new NullControl("force (N)"));
00123       break;
00124     }
00125   }
00126   ControlBase::refresh();
00127 }
00128 
00129 ControlBase * TorqueCalibrate::TakeMeasurementControl::takeInput(const std::string& msg) {
00130   switch(cstate) {
00131     case ZERO_JOINT:
00132     case DO_PULSE:
00133       break;
00134     case RECORD_POSITION:
00135       sensorDist=(float)atof(msg.c_str());
00136       if(sensorDist==0) {
00137         sndman->playFile("fart.wav");
00138         return NULL;
00139       }
00140       transition(INPUT_PULSE);
00141       break;
00142     case INPUT_PULSE: {
00143       float offset=(float)atof(msg.c_str());
00144       SharedObject<TinyMotionSequenceMC> ms;
00145       ms->advanceTime(350);
00146       if(offset>.1) {
00147         // move slowly at first in case not quite against sensor
00148         ms->setOutputCmd(joint,basePosition+offset/4);
00149         ms->advanceTime(300);
00150         ms->setOutputCmd(joint,basePosition+offset/2);
00151         ms->advanceTime(200);
00152         // hard push at the end
00153         ms->setOutputCmd(joint,basePosition+offset);
00154         ms->advanceTime(500);
00155       } else {
00156         ms->setOutputCmd(joint,basePosition+offset);
00157         ms->advanceTime(700);
00158       }
00159       ms->setOutputCmd(joint,basePosition+offset);
00160       ms->advanceTime(300);
00161       erouter->addTimer(this,0,ms->getTime(),false);
00162       ms->setOutputCmd(joint,basePosition);
00163       ms->advanceTime(200);
00164       ms->setOutputCmd(joint,basePosition);
00165       pulseID=motman->addPrunableMotion(ms);
00166       transition(DO_PULSE);
00167     } break;
00168     case RECORD_FORCE: {
00169       float f=(float)atof(msg.c_str());
00170       if(f!=0)
00171         parent.record(joint,sensorDist,maxDuty,f);
00172       else
00173         sndman->playFile("fart.wav");
00174       transition(INPUT_PULSE);
00175     } break;
00176   }
00177   return this;
00178 }
00179 
00180 void TorqueCalibrate::TakeMeasurementControl::deactivate() {
00181   erouter->remove(this);
00182   motman->removeMotion(pidID);
00183   pidID=invalid_MC_ID;
00184   if(pulseID!=invalid_MC_ID) {
00185     motman->removeMotion(pulseID);
00186     pulseID=invalid_MC_ID;
00187   }
00188   ControlBase::deactivate();
00189 }
00190 
00191 void TorqueCalibrate::TakeMeasurementControl::transition(State_t newstate) {
00192   MMAccessor<PIDMC>(pidID)->setAllPowerLevel(1);
00193   erouter->removeListener(this);
00194   cstate=newstate;
00195   if(cstate==RECORD_POSITION || cstate==INPUT_PULSE || cstate==RECORD_FORCE)
00196         sndman->playFile("ping.wav");
00197   else
00198         sndman->playFile("barkhigh.wav");
00199   refresh();
00200   if(cstate==DO_PULSE) {
00201         maxDuty=0;
00202         float pidSetting[] = {DefaultPIDs[joint][0],0,0};
00203         MMAccessor<PIDMC>(pidID)->setPID(joint,pidSetting);
00204         erouter->addListener(this,EventBase::sensorEGID);
00205         erouter->addListener(this,EventBase::motmanEGID,pulseID,EventBase::deactivateETID);
00206   }
00207 }
00208 
00209 
00210 /*! @file
00211  * @brief 
00212  * @author Ethan Tira-Thompson (ejt) (Creator)
00213  */

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