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
00017 using namespace std;
00018
00019
00020
00021
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
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;
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
00148 ms->setOutputCmd(joint,basePosition+offset/4);
00149 ms->advanceTime(300);
00150 ms->setOutputCmd(joint,basePosition+offset/2);
00151 ms->advanceTime(200);
00152
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
00211
00212
00213