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) ) {
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
00063 FailsafeThread failsafe(*this,(long)timeout,true);
00064 if(!readResponse(icomm,response,output))
00065 return NULL;
00066
00067 const ModelID_t responseModel = static_cast<ModelID_t>(response.getModelNumber());
00068
00069
00070
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
00082 } else if(responseModel!=MODEL_UNKNOWN && info!=NULL) {
00083
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
00114
00115
00116