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) ) {
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
00066 FailsafeThread failsafe(*this,(long)timeout,true);
00067 if(!readResponse(icomm,response,output))
00068 return NULL;
00069
00070 const ModelID_t responseModel = static_cast<ModelID_t>(response.getModelNumber());
00071
00072
00073
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
00084 } else if(responseModel!=MODEL_UNKNOWN && info!=NULL) {
00085
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
00116
00117
00118