Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

DynamixelProtocol.cc

Go to the documentation of this file.
00001 #include "DynamixelProtocol.h"
00002 #include "Events/EventRouter.h"
00003 #include "IPC/FailsafeThread.h"
00004 #include "Shared/RobotInfo.h"
00005 #include "Shared/debuget.h"
00006 #include <iostream>
00007 
00008 using namespace std;
00009 
00010 namespace DynamixelProtocol {
00011   const char* MODEL_UNKNOWN_NAME="UNKNOWN";
00012   
00013   const size_t NUM_KNOWN_MODELS=11;
00014   std::pair<DynamixelProtocol::ModelID_t, const std::string> knownModels[NUM_KNOWN_MODELS] = {
00015     std::make_pair(MODEL_DX113, "DX-113"),
00016     std::make_pair(MODEL_DX116, "DX-116"),
00017     std::make_pair(MODEL_DX117, "DX-117"),
00018     std::make_pair(MODEL_AX12, "AX-12"),
00019     std::make_pair(MODEL_AX18, "AX-18"),
00020     std::make_pair(MODEL_AXS1, "AX-S1"),
00021     std::make_pair(MODEL_RX10, "RX-10"),
00022     std::make_pair(MODEL_RX24, "RX-24"),
00023     std::make_pair(MODEL_RX28, "RX-28"),
00024     std::make_pair(MODEL_RX64, "RX-64"),
00025     std::make_pair(MODEL_EX106P, "EX-106+"),
00026   };
00027   const std::map<DynamixelProtocol::ModelID_t, const std::string> dynamixelModels(knownModels,&knownModels[NUM_KNOWN_MODELS]);
00028 
00029   const char* ResponseErrorNames[9] = {
00030     "VOLTAGE_ERROR",
00031     "ANGLE_ERROR",
00032     "HEAT_ERROR",
00033     "RANGE_ERROR",
00034     "CHECKSUM_ERROR",
00035     "LOAD_ERROR",
00036     "INSTRUCTION_ERROR",
00037     "UNKNOWN_ERROR",
00038     NULL
00039   };
00040 
00041   void reportErrors(unsigned int servoID, unsigned int offset, unsigned char err) {
00042     if(err==0)
00043       return;
00044     if ( err & ~(HEAT_ERROR | LOAD_ERROR) ) { // dont' report load or heat errors here; ResetServos will handle those
00045       std::cerr << "Dynamixel module " << servoID;
00046       if(offset<NumOutputs)
00047         std::cerr << " (" << outputNames[offset] << ")";
00048       std::cerr << " reported error " << (int)err << ":";
00049       for(unsigned int i=0; i<sizeof(err)*8; ++i)
00050         if( (err>>i) & 1 )
00051           std::cerr << ' ' << ResponseErrorNames[i];
00052       std::cerr << std::endl;
00053     }
00054     if(erouter!=NULL && offset<NumOutputs)
00055       erouter->postEvent(EventBase(EventBase::servoEGID, offset, EventBase::statusETID, 0,"Servo Error",(float)err));
00056   }
00057   
00058   long PingThread::timeout = 150;
00059   
00060   void * PingThread::run() {
00061     ocomm.write(ReadModelCmd(sid),sizeof(ReadModelCmd)).flush();
00062     //cout << "Ping " << (int)sid << ' ' << sizeof(response) << " bytes" << endl;
00063     FailsafeThread failsafe(*this,(long)timeout,true); // wait for servo response up to timeout
00064     if(!readResponse(icomm,response,output))
00065       return NULL;
00066     
00067     const ModelID_t responseModel = static_cast<ModelID_t>(response.getModelNumber());
00068     //cout << "Ping " << (int)sid << " response model " << responseModel << std::endl;
00069     
00070     // check AX-S1 sensors
00071     if (responseModel==MODEL_AXS1 && infoS1!=NULL) {
00072       ocomm.write(ReadAXS1SensorsCmd(sid),sizeof(ReadAXS1SensorsCmd)).flush();
00073       if(!ocomm) {
00074         std::cerr << "DynamixelDriver unable to send initial sensor poll request, lost comm?" << std::endl;
00075         return NULL;
00076       }
00077       AXS1SensorsResponse axS1response;
00078       if(readResponse(icomm,axS1response,output))
00079         *infoS1 = axS1response;
00080 
00081     // check servo sensors
00082     } else if(responseModel!=MODEL_UNKNOWN  && info!=NULL) {
00083       // it's an common servo module, get the current sensor values
00084       ocomm.write(ReadServoSensorsCmd(sid),sizeof(ReadServoSensorsCmd)).flush();
00085       if(!ocomm) {
00086         std::cerr << "DynamixelDriver unable to send initial sensor poll request, lost comm?" << std::endl;
00087         return NULL;
00088       }
00089       ServoSensorsResponse servoresponse;
00090       if(readResponse(icomm,servoresponse,output))
00091         *info = servoresponse;
00092     }
00093     
00094     if(response.getModelString()!=MODEL_UNKNOWN_NAME)
00095       return const_cast<char*>(response.getModelString());
00096     else {
00097       unknownModelName = response.getModelString();
00098       unknownModelName.append("=0x");
00099       if(response.modelh>>4)
00100         unknownModelName.append(1,debuget::hexdigit(response.modelh>>4));
00101       if(response.modelh&15)
00102         unknownModelName.append(1,debuget::hexdigit(response.modelh&15));
00103       if(response.modell>>4)
00104         unknownModelName.append(1,debuget::hexdigit(response.modell>>4));
00105       unknownModelName.append(1,debuget::hexdigit(response.modell&15));
00106       return const_cast<char*>(unknownModelName.c_str());
00107     }
00108   }
00109 
00110   void PingThread::cancelled() { icomm.clear(); }
00111 }
00112 
00113 /*! @file
00114  * @brief 
00115  * @author Ethan Tira-Thompson (ejt) (Creator)
00116  */

Tekkotsu Hardware Abstraction Layer 5.1CVS
Generated Tue Jan 31 04:35:31 2012 by Doxygen 1.6.3