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=14;
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_MX28, "MX-28"),
00026     std::make_pair(MODEL_MX64, "MX-64"),
00027     std::make_pair(MODEL_MX106, "MX-106"),
00028     std::make_pair(MODEL_EX106P, "EX-106+"),
00029   };
00030   const std::map<DynamixelProtocol::ModelID_t, const std::string> dynamixelModels(knownModels,&knownModels[NUM_KNOWN_MODELS]);
00031 
00032   const char* ResponseErrorNames[9] = {
00033     "VOLTAGE_ERROR",
00034     "ANGLE_ERROR",
00035     "HEAT_ERROR",
00036     "RANGE_ERROR",
00037     "CHECKSUM_ERROR",
00038     "LOAD_ERROR",
00039     "INSTRUCTION_ERROR",
00040     "UNKNOWN_ERROR",
00041     NULL
00042   };
00043 
00044   void reportErrors(unsigned int servoID, unsigned int offset, unsigned char err) {
00045     if(err==0)
00046       return;
00047     if ( err & ~(HEAT_ERROR | LOAD_ERROR) ) { // dont' report load or heat errors here; ResetServos will handle those
00048       std::cerr << "Dynamixel module " << servoID;
00049       if(offset<NumOutputs)
00050         std::cerr << " (" << outputNames[offset] << ")";
00051       std::cerr << " reported error " << (int)err << ":";
00052       for(unsigned int i=0; i<sizeof(err)*8; ++i)
00053         if( (err>>i) & 1 )
00054           std::cerr << ' ' << ResponseErrorNames[i];
00055       std::cerr << std::endl;
00056     }
00057     if(erouter!=NULL && offset<NumOutputs)
00058       erouter->postEvent(EventBase(EventBase::servoEGID, offset, EventBase::statusETID, 0,"Servo Error",(float)err));
00059   }
00060   
00061   long PingThread::timeout = 150;
00062   
00063   void * PingThread::run() {
00064     ocomm.write(ReadModelCmd(sid),sizeof(ReadModelCmd)).flush();
00065     //cout << "Ping " << (int)sid << ' ' << sizeof(response) << " bytes" << endl;
00066     FailsafeThread failsafe(*this,(long)timeout,true); // wait for servo response up to timeout
00067     if(!readResponse(icomm,response,output))
00068       return NULL;
00069     
00070     const ModelID_t responseModel = static_cast<ModelID_t>(response.getModelNumber());
00071     //cout << "Ping " << (int)sid << " response model " << responseModel << std::endl;
00072     
00073     // check AX-S1 sensors
00074     if (responseModel==MODEL_AXS1 && infoS1!=NULL) {
00075       ocomm.write(ReadAXS1SensorsCmd(sid),sizeof(ReadAXS1SensorsCmd)).flush();
00076       if(!ocomm) {
00077         std::cerr << "DynamixelDriver unable to send initial sensor poll request, lost comm?" << std::endl;
00078         return NULL;
00079       }
00080       AXS1SensorsResponse axS1response;
00081       if(readResponse(icomm,axS1response,output))
00082         *infoS1 = axS1response;
00083     // check servo sensors
00084     } else if(responseModel!=MODEL_UNKNOWN  && info!=NULL) {
00085       // it's an common servo module, get the current sensor values
00086       ocomm.write(ReadServoSensorsCmd(sid),sizeof(ReadServoSensorsCmd)).flush();
00087       if(!ocomm) {
00088         std::cerr << "DynamixelDriver unable to send initial sensor poll request, lost comm?" << std::endl;
00089         return NULL;
00090       }
00091       ServoSensorsResponse servoresponse;
00092       if(readResponse(icomm,servoresponse,output))
00093         *info = servoresponse;
00094     }
00095     
00096     if(response.getModelString()!=MODEL_UNKNOWN_NAME)
00097       return const_cast<char*>(response.getModelString());
00098     else {
00099       unknownModelName = response.getModelString();
00100       unknownModelName.append("=0x");
00101       if(response.modelh>>4)
00102         unknownModelName.append(1,debuget::hexdigit(response.modelh>>4));
00103       if(response.modelh&15)
00104         unknownModelName.append(1,debuget::hexdigit(response.modelh&15));
00105       if(response.modell>>4)
00106         unknownModelName.append(1,debuget::hexdigit(response.modell>>4));
00107       unknownModelName.append(1,debuget::hexdigit(response.modell&15));
00108       return const_cast<char*>(unknownModelName.c_str());
00109     }
00110   }
00111 
00112   void PingThread::cancelled() { icomm.clear(); }
00113 }
00114 
00115 /*! @file
00116  * @brief 
00117  * @author Ethan Tira-Thompson (ejt) (Creator)
00118  */

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