Go to the documentation of this file.00001
00002
00003
00004
00005
00006 #include <threemxl/platform/hardware/dynamixel/CDxlGroup.h>
00007 #include <threemxl/platform/hardware/dynamixel/dynamixel/Dynamixel.h>
00008 #include <threemxl/platform/hardware/dynamixel/3mxl/3mxl.h>
00009 #include <threemxl/platform/hardware/dynamixel/DxlClassFactory.hpp>
00010
00011
00012
00013
00014
00015
00016 CDxlGroup::CDxlGroup(): CDxlCom(), mLog("CDxlGroup")
00017 {
00018 mSerialPort = NULL;
00019 mNumDynamixels = 0;
00020 mSyncPacket = new CDxlSyncWritePacket();
00021 mLog.setLevel(llCrawl);
00022 mSyncRead = false;
00023
00024 }
00025
00026 CDxlGroup::~CDxlGroup()
00027 {
00028
00029 for(int iDxl = 0; iDxl < mNumDynamixels; iDxl++)
00030 {
00031 if (mDynamixels[mNumDynamixels] != NULL)
00032 {
00033 delete mDynamixels[mNumDynamixels];
00034 mDynamixels[mNumDynamixels] = NULL;
00035 mLogCrawlLn("deleted dynamixel object " << iDxl << " from serialport group " << getName() );
00036 }
00037 }
00038 delete mSyncPacket;
00039 }
00040
00041 void CDxlGroup::setSerialPort(LxSerial* serialport)
00042 {
00043 mSerialPort = serialport;
00044 mName = "DxlGroup-" + serialport->get_port_name();
00045 }
00046
00047 void CDxlGroup::setName(const std::string& name)
00048 {
00049 mName = name;
00050 }
00051
00052 std::string& CDxlGroup::getName()
00053 {
00054 return mName;
00055 }
00056
00057 bool CDxlGroup::init()
00058 {
00059 return (initAll() == DXL_SUCCESS);
00060 }
00061
00062 bool CDxlGroup::deinit()
00063 {
00064
00065 for(int iDxl = 0; iDxl < mNumDynamixels; iDxl++)
00066 {
00067 if (mDynamixels[iDxl] != NULL)
00068 {
00069 delete mDynamixels[iDxl];
00070 mDynamixels[iDxl] = NULL;
00071 mLogCrawlLn("deleted dynamixel object " << iDxl << " from serialport group " << getName() );
00072 }
00073 else
00074 {
00075 mLogErrorLn("unable to delete dynamixel object "<< iDxl << " from serialport group " << getName() );
00076 }
00077 mNumDynamixels =0;
00078 }
00079 return true;
00080 }
00081
00082 int CDxlGroup::action()
00083 {
00084 CDxlPacket packet(DXL_BROADCAST_ID, INST_ACTION, 0);
00085 packet.setChecksum();
00086 return sendPacket(&packet, false);
00087 }
00088
00089 int CDxlGroup::addNewDynamixel(CDxlConfig* config)
00090 {
00091 CDxlGeneric* pDxl = gDxlCreate(config->mDxlTypeStr);
00092 if(pDxl==NULL)
00093 {
00094 #ifdef __DBG__
00095 printf("Dynamixel with wrong type was not added to group!\n");
00096 #endif
00097 return DXL_NOT_INITIALIZED;
00098 }
00099 else
00100 {
00101 mDynamixels[mNumDynamixels] = pDxl;
00102 mDynamixels[mNumDynamixels]->setConfig(config);
00103 mDynamixels[mNumDynamixels]->setGroup(this);
00104 mNumDynamixels++;
00105 }
00106 return 0;
00107 }
00108
00109 int CDxlGroup::setupSyncReadChain()
00110 {
00111 int result = DXL_SUCCESS;
00112 for (int i=0; i<mNumDynamixels; i++)
00113 {
00114 int newResult = mDynamixels[i]->setSyncReadIndex(i+1);
00115 #ifdef __DBG__
00116 if (newResult != DXL_SUCCESS)
00117 mLogErrorLn("Dynamixel with ID " << mDynamixels[i]->getID() << " returned " << translateErrorCode(newResult) << "(last error = " << mDynamixels[i]->getLastError() << ") while setting up sync read chain" );
00118 #endif
00119
00120 result |= newResult;
00121 }
00122
00123 if (result == DXL_SUCCESS )
00124 mSyncRead = true;
00125
00126 return result;
00127 }
00128
00133 int CDxlGroup::sendSyncWritePacket()
00134 {
00135 if (mNumDynamixels > 0)
00136 {
00137 if (mSyncPacket->getID() != 0xFE)
00138 {
00139 mLogCrawlLn("did not send empty syncWritePacket...");
00140 return DXL_SUCCESS;
00141 }
00142 mSyncPacket->setChecksum();
00143
00144 int result = sendPacket(mSyncPacket, false);
00145 mLogCrawlLn("reset syncWritePacket");
00146 mSyncPacket->reset();
00147 return result;
00148 }
00149 else
00150 return DXL_SUCCESS;
00151
00152
00153 }
00154
00161 int CDxlGroup::writeData(int ID, int startingAddress, int dataLength, BYTE* data)
00162 {
00163 if (mSyncPacket->getStartingAddress() == 0)
00164 {
00165 mLogCrawlLn("configuring syncWritePacket for "<< mNumDynamixels <<" servo's with starting address "<<startingAddress << " and dataLength "<< dataLength );
00166 mSyncPacket->configurePacket(mNumDynamixels, startingAddress, dataLength);
00167 }
00168 else
00169 {
00170 if(mSyncPacket->getStartingAddress() != startingAddress)
00171 {
00172 mLogErrorLn("Trying to write different messages in same syncWritePacket "
00173 << "expecting:"
00174 << mSyncPacket->getStartingAddress()
00175 << ", getting:"
00176 << startingAddress);
00177 return DXL_INVALID_PARAMETER;
00178 }
00179 }
00180
00181 mSyncPacket->addCommand(ID, data, dataLength);
00182 return DXL_SUCCESS;
00183 }
00184
00185 int CDxlGroup::syncRead(int startingAddress, int dataLength)
00186 {
00187
00188 CDxlPacket packet(DXL_BROADCAST_ID, INST_READ, 2);
00189 packet.setParam(0, startingAddress);
00190 packet.setParam(1, dataLength);
00191 packet.setChecksum();
00192
00193
00194 if (sendPacket(&packet) != DXL_SUCCESS)
00195 {
00196 mLogErrorLn("Couldn't send sync read packet " << packet.getPktString());
00197 return DXL_ERROR;
00198 }
00199
00200 for (int i=0; i<mNumDynamixels; i++)
00201 {
00202
00203 CDxlStatusPacket statusPacket(dataLength);
00204 int result = receivePacketWait(&statusPacket);
00205
00206 if (result != DXL_SUCCESS)
00207 {
00208 mLogErrorLn("Dynamixel with ID " << mDynamixels[i]->getID() << " returned " << translateErrorCode(result) << "(last error = " << mDynamixels[i]->getLastError() << ") during sync read" );
00209 return result;
00210 }
00211
00212 mDynamixels[i]->interpretControlData(startingAddress, dataLength, statusPacket.data()+DXL_HEADER_LENGTH);
00213 }
00214
00215 return DXL_SUCCESS;
00216 }
00217
00221 void CDxlGroup::setSyncWriteType(const BYTE instruction)
00222 {
00223 mSyncPacket->setInstruction(instruction);
00224 }
00225
00226 int CDxlGroup::initAll()
00227 {
00228 int result = DXL_SUCCESS;
00229 for (int i=0; i<mNumDynamixels; i++)
00230 {
00231 if(mDynamixels[i] != NULL)
00232 {
00233 mDynamixels[i]->setSerialPort(mSerialPort);
00234 result |= mDynamixels[i]->init();
00235 if(result != DXL_SUCCESS){
00236 mLogErrorLn("Servo " << i << " did not initialize correctly! Error:" << result);
00237 break;
00238 }
00239 }
00240 else
00241 {
00242 mLogErrorLn("Trying to initialize non-existent servo with nr:" << i);
00243 }
00244 }
00245
00246 return result;
00247 }
00248
00249 int CDxlGroup::getStateAll()
00250 {
00251 if (mSyncRead)
00252 {
00253 return syncRead(M3XL_VOLTAGE_L, 10);
00254 }
00255 else
00256 {
00257 int result = DXL_SUCCESS;
00258 for (int i=0; i<mNumDynamixels; i++)
00259 {
00260 int newResult = mDynamixels[i]->getState();
00261 #ifdef __DBG__
00262 if (newResult != DXL_SUCCESS)
00263 mLogErrorLn("Dynamixel with ID " << mDynamixels[i]->getID() << " returned " << translateErrorCode(newResult) << "(last error = " << mDynamixels[i]->getLastError() << ")!" );
00264 #endif
00265
00266 result |= newResult;
00267 }
00268
00269 return result;
00270 }
00271 }
00272
00273 int CDxlGroup::getStatusAll()
00274 {
00275 int result = DXL_SUCCESS;
00276 for (int i=0; i<mNumDynamixels; i++)
00277 {
00278 int newResult = mDynamixels[i]->getStatus();
00279 #ifdef __DBG__
00280 if (newResult != DXL_SUCCESS)
00281 mLogErrorLn("Dynamixel with ID " << mDynamixels[i]->getID() << " returned " << translateErrorCode(newResult) << "(last error = " << mDynamixels[i]->getLastError() << ")!" );
00282 #endif
00283
00284 result |= newResult;
00285 }
00286
00287 return result;
00288 }
00289
00290 int CDxlGroup::getPosAll()
00291 {
00292 int result = DXL_SUCCESS;
00293 for (int i=0; i<mNumDynamixels; i++)
00294 {
00295 int newResult = mDynamixels[i]->getPos();
00296 #ifdef __DBG__
00297 if (newResult != DXL_SUCCESS)
00298 mLogErrorLn("Dynamixel with ID " << mDynamixels[i]->getID() << " returned " << translateErrorCode(newResult) << "(last error = " << mDynamixels[i]->getLastError() << ")!" );
00299 #endif
00300
00301 result |= newResult;
00302 }
00303
00304 return result;
00305 }
00306
00307 int CDxlGroup::getPosAndSpeedAll()
00308 {
00309 int result = DXL_SUCCESS;
00310 for (int i=0; i<mNumDynamixels; i++)
00311 {
00312 int newResult = mDynamixels[i]->getPosAndSpeed();
00313 #ifdef __DBG__
00314 if (newResult != DXL_SUCCESS)
00315 mLogErrorLn("Dynamixel with ID " << mDynamixels[i]->getID() << " returned " << translateErrorCode(newResult) << "(last error = " << mDynamixels[i]->getLastError() << ")!" );
00316 #endif
00317
00318 result |= newResult;
00319 }
00320
00321 return result;
00322 }
00323
00324
00325 int CDxlGroup::getPosSpeedTorqueAll()
00326 {
00327 int result = DXL_SUCCESS;
00328 for (int i=0; i<mNumDynamixels; i++)
00329 {
00330 int newResult = mDynamixels[i]->getTorquePosSpeed();
00331 #ifdef __DBG__
00332 if (newResult != DXL_SUCCESS)
00333 mLogErrorLn("Dynamixel with ID " << mDynamixels[i]->getID() << " returned " << translateErrorCode(newResult) << "(last error = " << mDynamixels[i]->getLastError() << ")!" );
00334 #endif
00335
00336 result |= newResult;
00337 }
00338
00339 return result;
00340 }
00341
00342 int CDxlGroup::getTempAll()
00343 {
00344 int result = DXL_SUCCESS;
00345 for (int i=0; i<mNumDynamixels; i++)
00346 {
00347 int newResult = mDynamixels[i]->getTemp();
00348 #ifdef __DBG__
00349 if (newResult != DXL_SUCCESS)
00350 mLogErrorLn("Dynamixel with ID " << mDynamixels[i]->getID() << " returned " << translateErrorCode(newResult) << "(last error = " << mDynamixels[i]->getLastError() << ")!" );
00351 #endif
00352
00353 result |= newResult;
00354 }
00355
00356 return result;
00357 }
00358
00359 int CDxlGroup::setEndlessTurnModeAll(bool enabled)
00360 {
00361 int result = DXL_SUCCESS;
00362 for (int i=0; i<mNumDynamixels; i++)
00363 {
00364 int newResult = mDynamixels[i]->setEndlessTurnMode(enabled);
00365 #ifdef __DBG__
00366 if (newResult != DXL_SUCCESS)
00367 mLogErrorLn("Dynamixel with ID " << mDynamixels[i]->getID() << " returned " << translateErrorCode(newResult) << "(last error = " << mDynamixels[i]->getLastError() << ")!" );
00368 #endif
00369
00370 result |= newResult;
00371 }
00372
00373 return result;
00374 }
00375
00376 int CDxlGroup::enableTorqueAll(int state)
00377 {
00378 int result = DXL_SUCCESS;
00379 for (int i=0; i<mNumDynamixels; i++)
00380 {
00381 int newResult = mDynamixels[i]->enableTorque(state);
00382 #ifdef __DBG__
00383 if (newResult != DXL_SUCCESS)
00384 mLogErrorLn("Dynamixel with ID " << mDynamixels[i]->getID() << " returned " << translateErrorCode(newResult) << "(last error = " << mDynamixels[i]->getLastError() << ")!" );
00385 #endif
00386
00387 result |= newResult;
00388 }
00389
00390 return result;
00391 }
00392
00393 int CDxlGroup::getNumDynamixels()
00394 {
00395 return mNumDynamixels;
00396 }
00397
00398 CDxlGeneric* CDxlGroup::getDynamixel(const int index)
00399 {
00400 return mDynamixels[index];
00401 }
00402
00403
00404 int CDxlGroup::setConfig(CDxlGroupConfig* config)
00405 {
00406 int result = 0;
00407 for (int i=0; i<config->getNumDynamixels(); i++)
00408 {
00409 result = addNewDynamixel(config->getDynamixelConfig(i));
00410 }
00411 return result;
00412 }