00001
00002
00003
00004
00005
00006
00007 #include <threemxl/platform/hardware/dynamixel/3mxl/3mxl.h>
00008 #include <threemxl/platform/hardware/dynamixel/CDxlPacketHandler.h>
00009
00010 #include <math.h>
00011 #include <sstream>
00012 #include <algorithm>
00013 #include <string.h>
00014 #include <unistd.h>
00015
00016 #include <threemxl/externals/half/half.h>
00017
00018 using namespace std;
00019
00020
00021
00022
00023
00024
00025 C3mxl::C3mxl(): CDxlGeneric(), mLog("3mxl")
00026 {
00027
00028
00029 mID = -1;
00030 mPosition = 0;
00031 mSpeed = 0;
00032 mRetlevel = 0;
00033 mStatus = 0;
00034 }
00035
00036 C3mxl::~C3mxl()
00037 {
00038 }
00039
00040 const char* C3mxl::translateErrorCode(int errorCode)
00041 {
00042 switch (errorCode)
00043 {
00044 case M3XL_STATUS_MOVING : return "M3XL_STATUS_MOVING";break;
00045 case M3XL_STATUS_MOVE_DONE : return "M3XL_STATUS_MOVE_DONE";break;
00046 case M3XL_STATUS_INITIALIZE_BUSY : return "M3XL_STATUS_INITIALIZE_BUSY";break;
00047 case M3XL_STATUS_INIT_DONE : return "M3XL_STATUS_INIT_DONE";break;
00048 case M3XL_STATUS_POS_MODE_EXECUTING : return "M3XL_STATUS_POS_MODE_EXECUTING";break;
00049 case M3XL_STATUS_POS_MODE_DONE : return "M3XL_STATUS_POS_MODE_DONE";break;
00050 case M3XL_STATUS_SPEED_MODE_EXECUTING : return "M3XL_STATUS_SPEED_MODE_EXECUTING";break;
00051 case M3XL_STATUS_SPEED_MODE_DONE : return "M3XL_STATUS_SPEED_MODE_DONE";break;
00052 case M3XL_STATUS_TORQUE_MODE_EXECUTING : return "M3XL_STATUS_TORQUE_MODE_EXECUTING";break;
00053 case M3XL_STATUS_TORQUE_MODE_DONE : return "M3XL_STATUS_TORQUE_MODE_DONE";break;
00054 case M3XL_STATUS_CURRENT_MODE_EXECUTING : return "M3XL_STATUS_CURRENT_MODE_EXECUTING";break;
00055 case M3XL_STATUS_CURRENT_MODE_DONE : return "M3XL_STATUS_CURRENT_MODE_DONE";break;
00056 case M3XL_STATUS_SEA_MODE_EXECUTING : return "M3XL_STATUS_SEA_MODE_EXECUTING";break;
00057 case M3XL_STATUS_SEA_MODE_DONE : return "M3XL_STATUS_SEA_MODE_DONE";break;
00058 case M3XL_STATUS_PWM_MODE_EXECUTING : return "M3XL_STATUS_PWM_MODE_EXECUTING";break;
00059 case M3XL_STATUS_PWM_MODE_DONE : return "M3XL_STATUS_PWM_MODE_DONE";break;
00060 case M3XL_STATUS_IDLE_STATE : return "M3XL_STATUS_IDLE_STATE";break;
00061 default : return CDxlCom::translateErrorCode(errorCode);
00062 }
00063 }
00064
00065
00066 double C3mxl::mxlCurrentToInternalCurrent(WORD current)
00067 {
00068 return (((short)current)/1000.0);
00069 }
00070
00071
00072 WORD C3mxl::internalCurrentToMxlCurrent(double current)
00073 {
00074 return clipToMaxWord((int)(current*1000));
00075 }
00076
00077
00078 double C3mxl::mxlVoltageToInternalVoltage(WORD voltage)
00079 {
00080 return (((int16_t)voltage)/100.0);
00081 }
00082
00083
00084 WORD C3mxl::internalVoltageToMxlVoltage(double voltage)
00085 {
00086 return (int)(voltage*100);
00087 }
00088
00089
00090 double C3mxl::mxlPosToInternalPos(WORD pos)
00091 {
00092 return (((short)pos)/1000.0);
00093 }
00094
00095
00096 WORD C3mxl::internalPosToMxlPos(double pos)
00097 {
00098 return clipToMaxWord((int)(pos*1000));
00099 }
00100
00101
00102 double C3mxl::mxlSpeedToInternalSpeed(WORD speed)
00103 {
00104 return (((short)speed)/100.0);
00105 }
00106
00107
00108 WORD C3mxl::internalSpeedToMxlSpeed(double speed)
00109 {
00110 return clipToMaxWord((int)(speed*100));
00111 }
00112
00113
00114 double C3mxl::mxlAccelerationToInternalAcceleration(WORD acceleration)
00115 {
00116 return (((short)acceleration)/100.0);
00117 }
00118
00119
00120 WORD C3mxl::internalAccelerationToMxlAcceleration(double acceleration)
00121 {
00122 return clipToMaxWord((int)(acceleration*100));
00123 }
00124
00125
00126 double C3mxl::mxlLinearPosToInternalLinearPos(DWORD pos)
00127 {
00128 return (((int)pos)/10000.0);
00129 }
00130
00131
00132 DWORD C3mxl::internalLinearPosToMxlLinearPos(double pos)
00133 {
00134 return clipToMaxDWord((int)(pos*10000));
00135 }
00136
00137
00138 double C3mxl::mxlLinearSpeedToInternalLinearSpeed(WORD speed)
00139 {
00140 return (((short)speed)/1000.0);
00141 }
00142
00143
00144 WORD C3mxl::internalLinearSpeedToMxlLinearSpeed(double speed)
00145 {
00146 return clipToMaxWord((int)(speed*1000));
00147 }
00148
00149
00150 double C3mxl::mxlLinearAccelerationToInternalLinearAcceleration(WORD acceleration)
00151 {
00152 return (((short)acceleration)/1000.0);
00153 }
00154
00155
00156 WORD C3mxl::internalLinearAccelerationToMxlLinearAcceleration(double acceleration)
00157 {
00158 return clipToMaxWord((int)(acceleration*1000));
00159 }
00160
00161
00162 double C3mxl::mxlTorqueToInternalTorque(WORD torque)
00163 {
00164 return (((short)torque)/1000.0) ;
00165 }
00166
00167
00168 WORD C3mxl::internalTorqueToMxlTorque(double torque)
00169 {
00170 return clipToMaxWord((int)(torque*1000));
00171 }
00172
00173
00174 WORD C3mxl::internalFreqToMxlFreq(double frequency)
00175 {
00176 return clipToMaxWord((int)(frequency*100));
00177 }
00178
00179
00180 WORD C3mxl::internalAmplitudeToMxlAmplitude(double amplitude)
00181 {
00182 return clipToMaxWord((int)(amplitude*1000));
00183 }
00184
00185
00186 WORD C3mxl::internalPhaseToMxlPhase(double phase)
00187 {
00188 return clipToMaxWord((int)(phase*1000));
00189 }
00190
00191
00192 double C3mxl::mxlPWMToInternalPWM(WORD pwm)
00193 {
00194 return (((short)pwm)/100.0);
00195 }
00196
00197
00198 WORD C3mxl::internalPWMToMxlPWM(double pwm)
00199 {
00200 return clipToMaxWord((int)(pwm*100));
00201 }
00202
00203 int C3mxl::clipToMaxWord(int value)
00204 {
00205 if (value>INT16_MAX)
00206 {
00207 mLogWarningLn("Clipping " << value << " to " << INT16_MAX);
00208 value = INT16_MAX;
00209 }
00210 else if (value<INT16_MIN)
00211 {
00212 mLogWarningLn("Clipping " << value << " to " << INT16_MIN);
00213 value = INT16_MIN;
00214 }
00215 return value;
00216 }
00217
00218 int C3mxl::clipToMaxDWord(int value)
00219 {
00220 if (value>INT32_MAX)
00221 {
00222 mLogWarningLn("Clipping " << value << " to " << INT32_MAX);
00223 value = INT32_MAX;
00224 }
00225 else if (value<INT32_MIN)
00226 {
00227 mLogWarningLn("Clipping " << value << " to " << INT32_MIN);
00228 value = INT32_MIN;
00229 }
00230 return value;
00231 }
00232
00233 void C3mxl::setConfig(CDxlConfig* config)
00234 {
00235
00236 mConfig = *config;
00237
00238
00239 if (!mInitialized && mConfig.mID.isSet())
00240 mID = mConfig.mID;
00241
00242
00243 if (mConfig.mClockwiseIsPositive.isSet())
00244 {setPositiveDirection(mConfig.mClockwiseIsPositive);}
00245 else
00246 {setPositiveDirection(1);}
00247
00248
00249 if (!mConfig.mReturnDelay.isSet() ) {setReturnDelayTime(INITIAL_RETURN_DELAY_TIME);}
00250 if (!mConfig.mAngleLowerLimit.isSet() ) {setAngleLowerLimit(0);}
00251 if (!mConfig.mAngleUpperLimit.isSet() ) {setAngleUpperLimit(0);}
00252 if (!mConfig.mTorqueLimit.isSet() ) {setTorqueLimit(INITIAL_TORQUE_LIMIT);}
00253 if (!mConfig.m3mxlMode.isSet()) {set3MxlMode(STOP_MODE);}
00254 if (!mConfig.mWatchdogMode.isSet()) {setWatchdogMode(INITIAL_WATCHDOG_MODE);}
00255 if (!mConfig.mWatchdogTime.isSet()) {setWatchdogTime(INITIAL_WATCHDOG_TIME);}
00256 if (!mConfig.mWatchdogMult.isSet()) {setWatchdogMultiplier(INITIAL_WATCHDOG_MULT);}
00257 if (!mConfig.mStatusReturnLevel.isSet()) {setRetlevel(INITIAL_STATUS_RETURN_LEVEL);}
00258 if (!mConfig.mMotorConstant.isSet()) {setMotorConstant(INITIAL_MOTOR_CONSTANT);}
00259 if (!mConfig.mGearboxRatioMotor.isSet()) {setGearboxRatioMotor(INITIAL_GEARBOX_RATIO);}
00260 if (!mConfig.mGearboxRatioJoint.isSet()) {setGearboxRatioJoint(INITIAL_GEARBOX_RATIO);}
00261 if (!mConfig.mEncoderCountMotor.isSet()) {setEncoderCountMotor(INITIAL_ENCODER_COUNT_MOTOR);}
00262 if (!mConfig.mOffsetMotor.isSet()) {setMotorOffset(INITIAL_OFFSET_MOTOR);}
00263
00264
00265 if (!mConfig.mEncoderCountJoint.isSet()) {setEncoderCountJoint(INITIAL_ENCODER_COUNT_JOINT);}
00266 if (!mConfig.mOffsetJoint.isSet()) {setJointOffset(INITIAL_OFFSET_JOINT);}
00267 if (!mConfig.mZeroLengthSpring.isSet()) {setZeroLengthSpring(INITIAL_ZERO_SPRING_LENGTH);}
00268 if (!mConfig.mSpringStiffness.isSet()) {setSpringStiffness(INITIAL_SPRING_STIFFNESS);}
00269 if (!mConfig.mJointClockWiseIsPositive.isSet()) {setPositiveDirectionJoint(INITIAL_JOINT_DIRECTION);}
00270
00271 }
00272
00273 void C3mxl::setSerialPort(LxSerial* serialPort)
00274 {
00275 mSerialPort = serialPort;
00276 mLogCrawlLn("set serialport called");
00277 }
00278
00279
00280 void C3mxl::setPositiveDirection(bool clockwiseIsPositive)
00281 {
00282 setPositiveDirectionMotor(clockwiseIsPositive);
00283 }
00284
00285 int C3mxl::setPositiveDirectionMotor(bool clockwiseIsPositive)
00286 {
00287 if (!mInitialized)
00288 return DXL_NOT_INITIALIZED;
00289
00290 mLogCrawlLn("setPositiveDirectionMotor with parameter " << (int)clockwiseIsPositive);
00291
00292 BYTE direction = 1;
00293 if (!clockwiseIsPositive)
00294 {
00295 direction = 0;
00296 }
00297 return writeData(M3XL_MOTOR_ENC_DIRECTION, 1, &direction);
00298
00299 }
00300
00301 int C3mxl::setPositiveDirectionJoint(bool clockwiseIsPositive)
00302 {
00303 if (!mInitialized)
00304 return DXL_NOT_INITIALIZED;
00305
00306 mLogCrawlLn("setPositiveDirectionJoint with parameter " << (int)clockwiseIsPositive);
00307
00308 BYTE direction = 1;
00309 if (!clockwiseIsPositive)
00310 {
00311 direction = 0;
00312 }
00313 return writeData(M3XL_JOINT_ENC_DIRECTION, 1, &direction);
00314 }
00315
00316 int C3mxl::setMotorOffset(double offset)
00317 {
00318 if (!mInitialized)
00319 return DXL_NOT_INITIALIZED;
00320 mLogCrawlLn("set motorOffset with parameter " << offset);
00321 WORD offsetmRad = internalPosToMxlPos(offset);
00322 return writeData(M3XL_OFFSET_MOTOR_L, 2,(BYTE*)&offsetmRad , false);
00323
00324 }
00325
00326 int C3mxl::setJointOffset(double offset)
00327 {
00328 if (!mInitialized)
00329 return DXL_NOT_INITIALIZED;
00330
00331 mLogCrawlLn("setJointOffset with parameter " << offset);
00332
00333 WORD offsetmRad = internalPosToMxlPos(offset);
00334 return writeData(M3XL_OFFSET_JOINT_L, 2,(BYTE*)&offsetmRad , false);
00335 }
00336
00337 int C3mxl::setEncoderCountMotor(WORD encodercount)
00338 {
00339 if (!mInitialized)
00340 return DXL_NOT_INITIALIZED;
00341
00342 mLogCrawlLn("setEncoderCountMotor with parameter " << (int)encodercount);
00343
00344 return writeData(M3XL_ENCODER_COUNT_MOTOR_L, 2,(BYTE*)&encodercount , false);
00345 }
00346
00347 int C3mxl::setEncoderCountJoint(WORD encodercount)
00348 {
00349 if (!mInitialized)
00350 return DXL_NOT_INITIALIZED;
00351
00352 mLogCrawlLn("setEncoderCountJoint with parameter " << (int)encodercount);
00353
00354 return writeData(M3XL_ENCODER_COUNT_JOINT_L, 2,(BYTE*)&encodercount , false);
00355 }
00356
00357 int C3mxl::setMotorConstant(WORD motorconstant)
00358 {
00359 if (!mInitialized)
00360 return DXL_NOT_INITIALIZED;
00361
00362 mLogCrawlLn("setMotorConstant with parameter " << (int)motorconstant);
00363
00364 return writeData(M3XL_MOTOR_CONSTANT_L, 2,(BYTE*)&motorconstant , false);
00365 }
00366
00367 int C3mxl::setMaxPeakMotorCurrent(double current)
00368 {
00369 if (!mInitialized)
00370 return DXL_NOT_INITIALIZED;
00371
00372 mLogCrawlLn("setMaxPeakMotorCurrent with parameter " << current);
00373
00374 WORD data = internalCurrentToMxlCurrent(current);
00375 return writeData(M3XL_MAX_MOTOR_PEAK_CURRENT_L, 2, (BYTE*)&data, false);
00376 }
00377
00378 int C3mxl::setMaxContinuousMotorCurrent(double current)
00379 {
00380 if (!mInitialized)
00381 return DXL_NOT_INITIALIZED;
00382
00383 mLogCrawlLn("setMaxContinuousMotorCurrent with parameter " << current);
00384
00385 WORD data = internalCurrentToMxlCurrent(current);
00386 return writeData(M3XL_MAX_CONTINUOUS_MOTOR_CURRENT_L, 2, (BYTE*)&data, false);
00387 }
00388
00389 int C3mxl::setMotorWindingTimeConstant(double time)
00390 {
00391 if (!mInitialized)
00392 return DXL_NOT_INITIALIZED;
00393
00394 mLogCrawlLn("setMotorWindingTimeConstant with parameter " << time);
00395
00396 WORD data = time*100;
00397 return writeData(M3XL_MOTOR_WINDING_TIME_CONSTANT_L, 2, (BYTE*)&data, false);
00398 }
00399
00400 int C3mxl::setEncoderIndexLevelMotor(BYTE level)
00401 {
00402 if (!mInitialized)
00403 return DXL_NOT_INITIALIZED;
00404
00405 mLogCrawlLn("setEncoderIndexLevelMotor with parameter " << (int)level);
00406
00407 return writeData(M3XL_MOTOR_ENC_INDEX_LEVEL, 1, &level, false);
00408 }
00409
00410 int C3mxl::setWheelDiameter(double diameter)
00411 {
00412 if (!mInitialized)
00413 return DXL_NOT_INITIALIZED;
00414
00415 mLogCrawlLn("setWheelDiameter with parameter " << diameter);
00416
00417 WORD data = internalLinearPosToMxlLinearPos(diameter);
00418
00419 return writeData(M3XL_WHEEL_DIAMETER_L, 2, (BYTE*)&data, false);
00420 }
00421
00422 int C3mxl::setGearboxRatioMotor(float gearboxratiomotor)
00423 {
00424 if (!mInitialized)
00425 return DXL_NOT_INITIALIZED;
00426
00427 mLogCrawlLn("setGearboxRatioMotor with parameter " << (int)gearboxratiomotor);
00428
00429 #ifdef PHIDES
00430 WORD dGearboxRatio = gearboxratiomotor;
00431 #else
00432 WORD dGearboxRatio = gearboxratiomotor * 10;
00433 #endif
00434
00435 return writeData(M3XL_GEARBOX_RATIO_MOTOR_L, 2,(BYTE*)&dGearboxRatio , false);
00436 }
00437
00438 int C3mxl::setGearboxRatioJoint(float gearboxratiojoint)
00439 {
00440 if (!mInitialized)
00441 return DXL_NOT_INITIALIZED;
00442
00443 mLogCrawlLn("setGearboxRatioJoint with parameter " << (int)gearboxratiojoint);
00444
00445 #ifdef PHIDES
00446 WORD dGearboxRatio = gearboxratiojoint;
00447 #else
00448 WORD dGearboxRatio = gearboxratiojoint * 10;
00449 #endif
00450
00451 return writeData(M3XL_GEARBOX_RATIO_JOINT_L, 2,(BYTE*)&dGearboxRatio , false);
00452 }
00453
00454 int C3mxl::set3MxlMode(BYTE mxlMode, bool shouldSyncWrite)
00455 {
00456 if (!mInitialized)
00457 return DXL_NOT_INITIALIZED;
00458 mLogCrawlLn("set 3mxl " << mID << " to mode " << (int)mxlMode << " with shouldSyncWrite == " << shouldSyncWrite);
00459
00460 int result = writeData(M3XL_CONTROL_MODE, 1,(BYTE*)&mxlMode , shouldSyncWrite);
00461 if (result != DXL_SUCCESS)
00462 return result;
00463 else
00464 mMxlMode = mxlMode;
00465
00466 return DXL_SUCCESS;
00467 }
00468
00469 int C3mxl::get3MxlMode()
00470 {
00471 if (!mInitialized)
00472 return DXL_NOT_INITIALIZED;
00473
00474 int result = readData(M3XL_CONTROL_MODE, 1, &mMxlMode);
00475 if (result != DXL_SUCCESS)
00476 return result;
00477
00478 return DXL_SUCCESS;
00479 }
00480
00481 int C3mxl::getAcceleration()
00482 {
00483 if (!mInitialized)
00484 return DXL_NOT_INITIALIZED;
00485 mLogCrawlLn("getAcceleration()");
00486
00487 WORD data;
00488 int result = readData(M3XL_DESIRED_ACCEL_L, 2, (BYTE *)&data);
00489 if (result != DXL_SUCCESS)
00490 return result;
00491
00492 mAcceleration = mxlAccelerationToInternalAcceleration(data);
00493
00494 return DXL_SUCCESS;
00495 }
00496
00497 int C3mxl::getLinearAcceleration()
00498 {
00499 if (!mInitialized)
00500 return DXL_NOT_INITIALIZED;
00501 mLogCrawlLn("getLinearAcceleration()");
00502
00503 WORD data;
00504 int result = readData(M3XL_DESIRED_LINEAR_ACCEL_L, 2, (BYTE *)&data);
00505 if (result != DXL_SUCCESS)
00506 return result;
00507
00508 mLinearAcceleration = mxlLinearAccelerationToInternalLinearAcceleration(data);
00509
00510 return DXL_SUCCESS;
00511 }
00512
00513 int C3mxl::setWatchdogMode(BYTE watchdogmode)
00514 {
00515 if (!mInitialized)
00516 return DXL_NOT_INITIALIZED;
00517
00518 mLogCrawlLn("setWatchdogMode with parameter " << (int)watchdogmode);
00519
00520 return writeData(M3XL_WATCHDOG_MODE, 1,(BYTE*)&watchdogmode , false);
00521 }
00522
00523 int C3mxl::setWatchdogTime(BYTE watchdogtime)
00524 {
00525 if (!mInitialized)
00526 return DXL_NOT_INITIALIZED;
00527
00528 mLogCrawlLn("setWatchdogTime with parameter " << (int)watchdogtime);
00529
00530 return writeData(M3XL_WATCHDOG_TIME_MS, 1,(BYTE*)&watchdogtime , false);
00531 }
00532
00533 int C3mxl::setWatchdogMultiplier(BYTE watchdogmultiplier)
00534 {
00535 if (!mInitialized)
00536 return DXL_NOT_INITIALIZED;
00537
00538 mLogCrawlLn("setWatchdogMultiplier with parameter " << (int)watchdogmultiplier);
00539
00540 return writeData(M3XL_WATCHDOG_TIMER_MUL, 1,(BYTE*)&watchdogmultiplier , false);
00541 }
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564 int C3mxl::setRetlevel(const int returnlevel)
00565 {
00566 if (!mInitialized)
00567 return DXL_NOT_INITIALIZED;
00568
00569 mLogCrawlLn("setRetlevel with parameter " << (int)returnlevel);
00570
00571 BYTE bRetlevel = returnlevel;
00572 mRetlevel = returnlevel;
00573 return writeData(M3XL_STATUS_RETURN_LEVEL, 1, &bRetlevel);
00574 }
00575
00576
00577 int C3mxl::setBaudRate(const int baudRate)
00578 {
00579 if (!mInitialized)
00580 return DXL_NOT_INITIALIZED;
00581
00582 mLogCrawlLn("setBaudRate with parameter " << (int)baudRate);
00583
00584 return writeData(M3XL_BAUD_RATE_L, 3, (BYTE*)&baudRate);
00585 }
00586
00587
00588 int C3mxl::setReturnDelayTime(const int microsecondsReturnDelay)
00589 {
00590 if (!mInitialized)
00591 return DXL_NOT_INITIALIZED;
00592
00593 mLogCrawlLn("setReturnDelayTime with parameter " << (int)microsecondsReturnDelay);
00594
00595 BYTE bReturnDelayIndex = microsecondsReturnDelay/2;
00596 return writeData(M3XL_RETURN_DELAY_TIME, 1, &bReturnDelayIndex);
00597 }
00598
00599
00600
00601 int C3mxl::setInitialTorqueLimit(double absMaxTorque)
00602 {
00603 if (!mInitialized)
00604 return DXL_NOT_INITIALIZED;
00605
00606 mLogCrawlLn("setInitialTorqueLimit with parameter " << absMaxTorque << "calls setTorqueLimit for now... nice to change to set maxUninitialisedMotorCurrent");
00607
00608 setTorqueLimit(absMaxTorque);
00609 return DXL_SUCCESS;
00610 }
00611
00612 int C3mxl::setTorqueLimit(double absMaxTorque)
00613 {
00614 if (!mInitialized)
00615 return DXL_NOT_INITIALIZED;
00616
00617 mLogCrawlLn("setTorqueLimit with parameter " << absMaxTorque);
00618
00619 WORD data = internalTorqueToMxlTorque(absMaxTorque);
00620 return writeData(M3XL_MAX_JOINT_TORQUE_L, 2, (BYTE*)&data);
00621 }
00622
00623 int C3mxl::setAngleLowerLimit(double limit)
00624 {
00625 if (!mInitialized)
00626 return DXL_NOT_INITIALIZED;
00627
00628 mLogCrawlLn("setAngleLowerLimit with parameter " << limit);
00629
00630 WORD data = internalPosToMxlPos(limit);
00631 return writeData(M3XL_CCW_JOINT_ANGLE_LIMIT_L, 2, (BYTE*)&data);
00632 }
00633
00634 int C3mxl::setAngleUpperLimit(double limit)
00635 {
00636 if (!mInitialized)
00637 return DXL_NOT_INITIALIZED;
00638
00639 mLogCrawlLn("setAngleUpperLimit with parameter " << limit);
00640
00641 WORD data = internalPosToMxlPos(limit);
00642 return writeData(M3XL_CW_JOINT_ANGLE_LIMIT_L, 2, (BYTE*)&data);
00643 }
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663 int C3mxl::setAngleLimits(double lowerLimit, double upperLimit)
00664 {
00665 if (!mInitialized)
00666 return DXL_NOT_INITIALIZED;
00667
00668 mLogCrawlLn("setAngleLimits with parameters " << lowerLimit << " and " << upperLimit);
00669
00670 if (upperLimit < lowerLimit)
00671 return DXL_INVALID_PARAMETER;
00672
00673
00674 WORD data[2];
00675 data[0] = internalPosToMxlPos(upperLimit);
00676 data[1] = internalPosToMxlPos(lowerLimit);
00677 return writeData(M3XL_CW_JOINT_ANGLE_LIMIT_L, 4, (BYTE*)data);
00678 }
00679
00680 int C3mxl::setZeroLengthSpring(double parameterInRad)
00681 {
00682 if (!mInitialized)
00683 return DXL_NOT_INITIALIZED;
00684
00685 mLogCrawlLn("setZeroLengthSpring with parameter " << parameterInRad);
00686
00687 WORD data = internalPosToMxlPos(parameterInRad);
00688 return writeData(M3XL_ZERO_LENGTH_SPRING_L, 2, (BYTE*)&data);
00689 }
00690
00691 int C3mxl::setSpringStiffness(double stiffness)
00692 {
00693 if (!mInitialized)
00694 return DXL_NOT_INITIALIZED;
00695
00696 mLogCrawlLn("setSpringStiffness with parameter " << stiffness);
00697
00698 WORD data[1];
00699 data[0] = 100 * stiffness;
00700
00701 return writeData(M3XL_SPRING_STIFFNESS_L, 2, (BYTE*)data);
00702 }
00703
00704 int C3mxl::setReferenceEnergy(double energy)
00705 {
00706 if (!mInitialized)
00707 return DXL_NOT_INITIALIZED;
00708
00709 mLogCrawlLn("setReferenceEnergy with parameter " << energy);
00710
00711 WORD data[1];
00712 data[0] = 1000 * energy;
00713
00714 return writeData(M3XL_REFERENCE_ENERGY_L, 2, (BYTE*)data);
00715 }
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742 int C3mxl::init(bool sendConfigToMotor)
00743 {
00744
00745
00746 int initResult = initPacketHandler();
00747 if (initResult != DXL_SUCCESS)
00748 {
00749 logDebugLn(mLog,"Error initializing packet handler!");
00750 return initResult;
00751 }
00752
00753
00754 if (mConfig.mID.isSet())
00755 {mID = mConfig.mID;}
00756 else
00757 {
00758 mInitialized = false;
00759 return DXL_NOT_INITIALIZED;
00760 }
00761
00762
00763 if (mID == BROADCAST_ID)
00764 {
00765 mInitialized = true;
00766 return DXL_SUCCESS;
00767 }
00768
00769
00770 int pingResult = ping();
00771 if (pingResult != DXL_SUCCESS)
00772 {
00773 mInitialized = false;
00774 return pingResult;
00775 }
00776 else
00777 {
00778 mLogNoticeLn("3mxl "<< mID << " responded to ping...");
00779 }
00780
00781
00782 BYTE retlevel;
00783 int result = readData(M3XL_STATUS_RETURN_LEVEL, 1, &retlevel);
00784 if (result == DXL_SUCCESS)
00785 {
00786 mRetlevel = retlevel;
00787 mInitialized = true;
00788 }
00789 else
00790 {
00791 if (result == DXL_PKT_RECV_TIMEOUT)
00792 {
00793 mLogNoticeLn("3mxl "<< mID << " did not return status return level, assuming it is 0");
00794 mRetlevel = 0;
00795 mInitialized = true;
00796 }
00797 else
00798 {
00799
00800 mLogErrorLn("3mxl " << mID << " did not return status return level!");
00801 mInitialized = false;
00802 }
00803 }
00804
00805 if (sendConfigToMotor)
00806 {
00807 result = mConfig.configureDynamixel(this);
00808 }
00809
00810
00811 return result;
00812 }
00813
00814
00815 int C3mxl::changeID(const int newID)
00816 {
00817 BYTE bNewID = newID;
00818
00819 mLogCrawlLn("changeID with parameter " << newID);
00820
00821 int result = writeData(M3XL_ID, 1, &bNewID);
00822
00823 if (result == DXL_PKT_RECV_ID_ERR)
00824 {
00825
00826 mID = newID;
00827 return DXL_SUCCESS;
00828 }
00829 else
00830 if (result == DXL_SUCCESS)
00831 {
00832
00833
00834 mID = newID;
00835 return DXL_SUCCESS;
00836 }
00837 else
00838 return result;
00839 }
00840
00841
00842 int C3mxl::getState()
00843 {
00844 if (!mInitialized)
00845 {
00846 return DXL_NOT_INITIALIZED;
00847 }
00848 mLogCrawlLn("getState called... ");
00849
00850 BYTE data[10];
00851 memset(data, 0, 10*sizeof(BYTE));
00852
00853 int result = readData(M3XL_VOLTAGE_L, 10, data);
00854 if (result != DXL_SUCCESS)
00855 {
00856 return result;
00857 }
00858
00859 mVoltage = mxlVoltageToInternalVoltage (*(WORD*)(data+0));
00860 mCurrent = mxlCurrentToInternalCurrent (*(WORD*)(data+2));
00861 mTorque = mxlTorqueToInternalTorque (*(WORD*)(data+4));
00862 mPosition = mxlPosToInternalPos (*(WORD*)(data+6));
00863 mSpeed = mxlSpeedToInternalSpeed (*(WORD*)(data+8));
00864
00865 return DXL_SUCCESS;
00866 }
00867
00868 int C3mxl::setLogInterval(BYTE interval)
00869 {
00870 BYTE one = 1;
00871
00872 int result = writeData(M3XL_LOG_DATA_INTERVAL, 1, &interval);
00873 if (result != DXL_SUCCESS)
00874 return result;
00875 result = writeData(M3XL_ENABLE_DATA_LOGGER, 1, &one);
00876 if (result != DXL_SUCCESS)
00877 return result;
00878
00879 return DXL_SUCCESS;
00880 }
00881
00882 int C3mxl::setSyncReadIndex(BYTE index)
00883 {
00884 int result = writeData(M3XL_SYNC_READ_INDEX, 1, &index);
00885 if (result != DXL_SUCCESS)
00886 return result;
00887
00888 return DXL_SUCCESS;
00889 }
00890
00891
00892 int C3mxl::getPos()
00893 {
00894 if (!mInitialized)
00895 return DXL_NOT_INITIALIZED;
00896
00897 mLogCrawlLn("getPos called... ");
00898
00899 BYTE data[2];
00900 int result = readData(M3XL_ANGLE_L, 2, data);
00901 if (result != DXL_SUCCESS)
00902 return result;
00903
00904 mPosition = mxlPosToInternalPos(*(WORD*)(data));
00905 return DXL_SUCCESS;
00906 }
00907
00908
00909 int C3mxl::getLinearPos()
00910 {
00911 if (!mInitialized)
00912 return DXL_NOT_INITIALIZED;
00913
00914 mLogCrawlLn("getLinearPos called... ");
00915
00916 DWORD data[1];
00917 int result = readData(M3XL_POSITION_32_1, 4, (BYTE*)data);
00918 if (result != DXL_SUCCESS)
00919 return result;
00920
00921 mLinearPosition = mxlLinearPosToInternalLinearPos(data[0]);
00922 return DXL_SUCCESS;
00923 }
00924
00925
00926 int C3mxl::getTorquePosSpeed()
00927 {
00928 if (!mInitialized)
00929 {
00930 return DXL_NOT_INITIALIZED;
00931 }
00932 mLogCrawlLn("getTorquePosSpeed called... ");
00933 BYTE data[6];
00934 memset(data, 0, 6*sizeof(BYTE));
00935
00936 int result = readData(M3XL_TORQUE_L, 6, data);
00937 if (result != DXL_SUCCESS)
00938 return result;
00939
00940 mTorque = mxlTorqueToInternalTorque(*(WORD*)(data));
00941 mPosition = mxlPosToInternalPos(*(WORD*)(data+2));
00942 mSpeed = mxlSpeedToInternalSpeed((*(WORD*)(data+4)));
00943
00944 return DXL_SUCCESS;
00945 }
00946
00947
00948 int C3mxl::getPosAndSpeed()
00949 {
00950 if (!mInitialized)
00951 {
00952 return DXL_NOT_INITIALIZED;
00953 }
00954
00955 mLogCrawlLn("getPosAndSpeed called... ");
00956
00957 BYTE data[4];
00958 memset(data, 0, 4*sizeof(BYTE));
00959
00960 int result = readData(M3XL_ANGLE_L, 4, data);
00961 if (result != DXL_SUCCESS)
00962 return result;
00963
00964 mPosition = mxlPosToInternalPos(*(WORD*)(data));
00965 mSpeed = mxlSpeedToInternalSpeed((*(WORD*)(data+2)));
00966
00967 return DXL_SUCCESS;
00968 }
00969
00970
00971 int C3mxl::getVoltage()
00972 {
00973 if (!mInitialized)
00974 return DXL_NOT_INITIALIZED;
00975 mLogCrawlLn("getVoltage called... ");
00976 BYTE data[2];
00977 int result = readData(M3XL_VOLTAGE_L, 2, data);
00978 if (result != DXL_SUCCESS)
00979 return result;
00980
00981 mVoltage = mxlVoltageToInternalVoltage(*(WORD*)(data));
00982 return DXL_SUCCESS;
00983 }
00984
00985
00986 int C3mxl::getBusVoltage()
00987 {
00988 if (!mInitialized)
00989 return DXL_NOT_INITIALIZED;
00990 mLogCrawlLn("getBusVoltage called... ");
00991 BYTE data[2];
00992 int result = readData(M3XL_BUS_VOLTAGE_L, 2, data);
00993 if (result != DXL_SUCCESS)
00994 return result;
00995
00996 mBusVoltage = mxlVoltageToInternalVoltage(*(WORD*)(data));
00997 return DXL_SUCCESS;
00998 }
00999
01000
01001 int C3mxl::getSensorVoltages()
01002 {
01003 if (!mInitialized)
01004 return DXL_NOT_INITIALIZED;
01005 mLogCrawlLn("getSensorVoltages called... ");
01006 BYTE data[12];
01007 int result = readData(M3XL_BUS_VOLTAGE_L, 12, data);
01008 if (result != DXL_SUCCESS)
01009 return result;
01010
01011 half h;
01012
01013 mBusVoltage = mxlVoltageToInternalVoltage(*(WORD*)(data));
01014 h.setBits(*(WORD*)(data+2)); mCurrentADCVoltage = h;
01015 h.setBits(*(WORD*)(data+4)); mAnalog1Voltage = h;
01016 h.setBits(*(WORD*)(data+6)); mAnalog2Voltage = h;
01017 h.setBits(*(WORD*)(data+8)); mAnalog3Voltage = h;
01018 h.setBits(*(WORD*)(data+10)); mAnalog4Voltage = h;
01019 return DXL_SUCCESS;
01020 }
01021
01022
01023 int C3mxl::getCurrent()
01024 {
01025 if (!mInitialized)
01026 return DXL_NOT_INITIALIZED;
01027 mLogCrawlLn("getCurrent called... ");
01028 BYTE data[2];
01029 int result = readData(M3XL_CURRENT_L, 2, data);
01030 if (result != DXL_SUCCESS)
01031 return result;
01032
01033 mCurrent = mxlCurrentToInternalCurrent(*(WORD*)(data));
01034 return DXL_SUCCESS;
01035 }
01036
01037
01038 int C3mxl::getTorque()
01039 {
01040 if (!mInitialized)
01041 return DXL_NOT_INITIALIZED;
01042 mLogCrawlLn("getTorque called... ");
01043 BYTE data[2];
01044 int result = readData(M3XL_TORQUE_L, 2, data);
01045 if (result != DXL_SUCCESS)
01046 return result;
01047
01048 mTorque = mxlTorqueToInternalTorque(*(WORD*)(data));
01049 return DXL_SUCCESS;
01050 }
01051
01052 int C3mxl::getStatus()
01053 {
01054 if (!mInitialized)
01055 return DXL_NOT_INITIALIZED;
01056 mLogCrawlLn("getStatus called... ");
01057
01058 BYTE data[2];
01059 int result = readData(M3XL_STATUS, 2, data);
01060 if (result != DXL_SUCCESS)
01061 return result;
01062 mStatus = data[0];
01063 mMotorInitialized = data[1];
01064 return DXL_SUCCESS;
01065 }
01066
01067 int C3mxl::getLog()
01068 {
01069 if (!mInitialized)
01070 return DXL_NOT_INITIALIZED;
01071 mLogCrawlLn("getLog called... ");
01072
01073
01074 mMxlLog.clear();
01075
01076 TMxlLogEntry data[M3XL_NR_OF_SAMPLES_PER_BLOCK];
01077
01078
01079 for (BYTE i = 1 ; i <= M3XL_NR_OF_BLOCKS; i++ ){
01080
01081 writeData(M3XL_DATA_LOGGER, 1, &i);
01082
01083 int result = readData(M3XL_DATA_LOGGER, M3XL_NR_OF_BYTES_PER_BLOCK, (BYTE*)data);
01084 if (result != DXL_SUCCESS)
01085 return result;
01086 for( int k = 0; k < M3XL_NR_OF_SAMPLES_PER_BLOCK; k++){
01087 if (data[k].time != 0 || data[k].pwm != 0 || data[k].current != 0 || data[k].voltage != 0 || data[k].desired != 0 || data[k].actual != 0)
01088 mMxlLog.push_back(data[k]);
01089 }
01090 }
01091 return DXL_SUCCESS;
01092 }
01093
01094 int C3mxl::setPos(double pos, bool shouldSyncWrite)
01095 {
01096 if (!mInitialized){
01097 return DXL_NOT_INITIALIZED;
01098 }
01099 mLogCrawlLn("setPos(double pos, bool shouldSyncWrite) with parameters " << pos << " " << shouldSyncWrite);
01100
01101 WORD data[1];
01102 data[0] = internalPosToMxlPos(pos);
01103 return writeData(M3XL_DESIRED_ANGLE_L, 2, (BYTE*)data, shouldSyncWrite);
01104 }
01105
01106 int C3mxl::setLinearPos(double pos, bool shouldSyncWrite)
01107 {
01108 if (!mInitialized){
01109 return DXL_NOT_INITIALIZED;
01110 }
01111 mLogCrawlLn("setLinearPos(double pos, bool shouldSyncWrite) with parameters " << pos << " " << shouldSyncWrite);
01112
01113 DWORD data[1];
01114 data[0] = internalLinearPosToMxlLinearPos(pos);
01115 return writeData(M3XL_DESIRED_POSITION_32_1, 4, (BYTE*)data, shouldSyncWrite);
01116 }
01117
01118 int C3mxl::setPos(double pos, double absSpeed, bool shouldSyncWrite)
01119 {
01120 if (!mInitialized){
01121 return DXL_NOT_INITIALIZED;
01122 }
01123 mLogCrawlLn("setPos(double pos, double absSpeed, bool shouldSyncWrite) with parameters " << pos << " " << absSpeed <<" " << shouldSyncWrite);
01124
01125 WORD data[2];
01126 data[0] = internalPosToMxlPos(pos);
01127 if (absSpeed < 0)
01128 data[1] = 0;
01129 else
01130 data[1] = abs(internalSpeedToMxlSpeed(absSpeed));
01131 return writeData(M3XL_DESIRED_ANGLE_L, 4, (BYTE*)data, shouldSyncWrite);
01132 }
01133
01134 int C3mxl::setLinearPos(double pos, double absSpeed, bool shouldSyncWrite)
01135 {
01136 if (!mInitialized){
01137 return DXL_NOT_INITIALIZED;
01138 }
01139 mLogCrawlLn("setLinearPos(double pos, bool shouldSyncWrite) with parameters " << pos << " " << absSpeed << " " << shouldSyncWrite);
01140
01141 if (absSpeed < 0)
01142 absSpeed = 0;
01143
01144 setLinearSpeed(absSpeed, shouldSyncWrite);
01145
01146 DWORD data[1];
01147 data[0] = internalLinearPosToMxlLinearPos(pos);
01148 writeData(M3XL_DESIRED_POSITION_32_1, 4, (BYTE*)data, shouldSyncWrite);
01149 }
01150
01151 int C3mxl::setPos(double pos, double absSpeed, double acceleration, bool shouldSyncWrite)
01152 {
01153 if (!mInitialized){
01154 return DXL_NOT_INITIALIZED;
01155 }
01156 mLogCrawlLn("setPos(double pos, double absSpeed, double acceleration, bool shouldSyncWrite) with parameters " << pos << " " << absSpeed << " " << acceleration << " " << shouldSyncWrite);
01157
01158 setAcceleration(acceleration, shouldSyncWrite);
01159
01160 WORD data[2];
01161 data[0] = internalPosToMxlPos(pos);
01162 if (absSpeed < 0)
01163 data[1] = 0;
01164 else
01165 data[1] = abs(internalSpeedToMxlSpeed(absSpeed));
01166 return writeData(M3XL_DESIRED_ANGLE_L, 4, (BYTE*)data, shouldSyncWrite);
01167 }
01168
01169 int C3mxl::setLinearPos(double pos, double absSpeed, double acceleration, bool shouldSyncWrite)
01170 {
01171 if (!mInitialized){
01172 return DXL_NOT_INITIALIZED;
01173 }
01174 mLogCrawlLn("setLinearPos(double pos, double absSpeed, double acceleration, bool shouldSyncWrite) with parameters " << pos << " " << absSpeed << " " << acceleration << " " << shouldSyncWrite);
01175
01176 if (absSpeed < 0) absSpeed = 0;
01177
01178 setLinearSpeed(absSpeed, shouldSyncWrite);
01179 setLinearAcceleration(acceleration, shouldSyncWrite);
01180
01181 DWORD data[1];
01182 data[0] = internalLinearPosToMxlLinearPos(pos);
01183 return writeData(M3XL_DESIRED_POSITION_32_1, 4, (BYTE*)data, shouldSyncWrite);
01184 }
01185
01186
01187 int C3mxl::setSpeed(double speed, bool shouldSyncWrite)
01188 {
01189 if (!mInitialized)
01190 return DXL_NOT_INITIALIZED;
01191 mLogCrawlLn("setSpeed(double speed, bool shouldSyncWrite) with parameters " << speed <<" " << shouldSyncWrite);
01192
01193
01194 WORD data[1];
01195 data[0] = internalSpeedToMxlSpeed(speed);
01196 return writeData(M3XL_DESIRED_SPEED_L, 2, (BYTE*)data, shouldSyncWrite);
01197 }
01198
01199
01200 int C3mxl::setLinearSpeed(double speed, bool shouldSyncWrite)
01201 {
01202 if (!mInitialized)
01203 return DXL_NOT_INITIALIZED;
01204 mLogCrawlLn("setLinearSpeed(double speed, bool shouldSyncWrite) with parameters " << speed <<" " << shouldSyncWrite);
01205
01206
01207 WORD data[1];
01208 data[0] = internalLinearSpeedToMxlLinearSpeed(speed);
01209 return writeData(M3XL_DESIRED_LINEAR_SPEED_L, 2, (BYTE*)data, shouldSyncWrite);
01210 }
01211
01212 int C3mxl::setAcceleration(double acceleration, bool shouldSyncWrite)
01213 {
01214 if (!mInitialized)
01215 return DXL_NOT_INITIALIZED;
01216 mLogCrawlLn("setAcceleration(double acceleration, bool shouldSyncWrite) with parameters " << acceleration <<" " << shouldSyncWrite);
01217
01218
01219 WORD data[1];
01220 data[0] = internalAccelerationToMxlAcceleration(acceleration);
01221 return writeData(M3XL_DESIRED_ACCEL_L, 2, (BYTE*)data, shouldSyncWrite);
01222 }
01223
01224 int C3mxl::setLinearAcceleration(double acceleration, bool shouldSyncWrite)
01225 {
01226 if (!mInitialized)
01227 return DXL_NOT_INITIALIZED;
01228 mLogCrawlLn("setAcceleration(double acceleration, bool shouldSyncWrite) with parameters " << acceleration <<" " << shouldSyncWrite);
01229
01230
01231 WORD data[1];
01232 data[0] = internalLinearAccelerationToMxlLinearAcceleration(acceleration);
01233 return writeData(M3XL_DESIRED_LINEAR_ACCEL_L, 2, (BYTE*)data, shouldSyncWrite);
01234 }
01235
01236 int C3mxl::setTorque(double torque, bool shouldSyncWrite)
01237 {
01238 if (!mInitialized)
01239 return DXL_NOT_INITIALIZED;
01240 mLogCrawlLn("setTorque(double torque, bool shouldSyncWrite) with parameters " << torque <<" " << shouldSyncWrite);
01241
01242 WORD data[1];
01243 data[0] = internalTorqueToMxlTorque(torque);
01244 return writeData(M3XL_DESIRED_TORQUE_L, 2, (BYTE*)data, shouldSyncWrite);
01245 }
01246
01247 int C3mxl::setCurrent(double current, bool shouldSyncWrite)
01248 {
01249 if (!mInitialized)
01250 return DXL_NOT_INITIALIZED;
01251 mLogCrawlLn("setCurrent(double current, bool shouldSyncWrite) with parameters " << current <<" " << shouldSyncWrite);
01252
01253 WORD data[1];
01254 data[0] = internalCurrentToMxlCurrent(current);
01255 return writeData(M3XL_DESIRED_CURRENT_L, 2, (BYTE*)data, shouldSyncWrite);
01256 }
01257
01258 int C3mxl::setPWM(double pwm, bool shouldSyncWrite)
01259 {
01260 if (!mInitialized)
01261 return DXL_NOT_INITIALIZED;
01262 mLogCrawlLn("setPWM(double pwm, bool shouldSyncWrite) with parameters " << pwm <<" " << shouldSyncWrite);
01263
01264 WORD data[1];
01265 data[0] = internalPWMToMxlPWM(pwm);
01266 return writeData(M3XL_DESIRED_PWM_L, 2, (BYTE*)data, shouldSyncWrite);
01267 }
01268
01269 int C3mxl::setSineFrequency(double frequency, bool shouldSyncWrite)
01270 {
01271 if (!mInitialized){
01272 return DXL_NOT_INITIALIZED;
01273 }
01274 mLogCrawlLn("setSineFrequency(double frequency, bool shouldSyncWrite) with parameters " << frequency << " " << shouldSyncWrite);
01275
01276 WORD data[1];
01277 data[0] = internalFreqToMxlFreq(frequency);
01278 return writeData(M3XL_SINUSOIDAL_FREQUENCY_L, 2, (BYTE*)data, shouldSyncWrite);
01279 }
01280
01281 int C3mxl::setSineAmplitude(double amplitude, bool shouldSyncWrite)
01282 {
01283 if (!mInitialized){
01284 return DXL_NOT_INITIALIZED;
01285 }
01286 mLogCrawlLn("setSineAmplitude(double amplitude, bool shouldSyncWrite) with parameters " << amplitude <<" " << shouldSyncWrite);
01287
01288 WORD data[1];
01289 data[0] = internalAmplitudeToMxlAmplitude(amplitude);
01290 return writeData(M3XL_SINUSOIDAL_AMPLITUDE_L, 2, (BYTE*)data, shouldSyncWrite);
01291 }
01292
01293 int C3mxl::setSinePhase(double phase, bool shouldSyncWrite)
01294 {
01295 if (!mInitialized){
01296 return DXL_NOT_INITIALIZED;
01297 }
01298 mLogCrawlLn("setSinePhase(double phase, bool shouldSyncWrite) with parameters " << phase <<" " << shouldSyncWrite);
01299
01300 WORD data[1];
01301 data[0] = internalPhaseToMxlPhase(phase);
01302 return writeData(M3XL_SINUSOIDAL_PHASE_ANGLE_L, 2, (BYTE*)data, shouldSyncWrite);
01303 }
01304
01305 int C3mxl::setPosSpeedTorquePPosDPos(double pos, double speed, double torque, int pPos, int dPos, bool shouldSyncWrite)
01306 {
01307 if (!mInitialized){
01308 return DXL_NOT_INITIALIZED;
01309 }
01310 mLogCrawlLn("setPosSpeedTorquePPosDPos(double pos, double speed, double torque, int pPos, int dPos, bool shouldSyncWrite) with parameters "
01311 << pos << " " << speed << " "<< torque << " " << pPos << " " << dPos <<" " << shouldSyncWrite);
01312
01313
01314
01315
01316
01317
01318 WORD data[5];
01319 data[0] = internalPosToMxlPos(pos);
01320 data[1] = internalSpeedToMxlSpeed(speed);
01321 data[2] = internalTorqueToMxlTorque(torque);
01322 data[3] = pPos;
01323 data[4] = dPos;
01324 return writeData(M3XL_DESIRED_ANGLE_L, 10, (BYTE*)data, shouldSyncWrite);
01325 }
01326
01327 int C3mxl::setPIDCurrent(double p, double d, double i, double i_limit, bool shouldSyncWrite)
01328 {
01329 if (!mInitialized){
01330 return DXL_NOT_INITIALIZED;
01331 }
01332 mLogCrawlLn("setPIDCurrent(double p, double d, double i, double i_limit, bool shouldSyncWrite) with parameters "
01333 << p << " " << d << " "<< i << " " << i_limit << " " << shouldSyncWrite);
01334
01335 WORD data[4];
01336 data[0] = half(p).bits();
01337 data[1] = half(d).bits();
01338 data[2] = half(i).bits();
01339 data[3] = half(i_limit).bits();
01340
01341 return writeData(M3XL_P_CURRENT_L, 8, (BYTE*)data, shouldSyncWrite);
01342 }
01343
01344 int C3mxl::setPIDPosition(double p, double d, double i, double i_limit, bool shouldSyncWrite)
01345 {
01346 if (!mInitialized){
01347 return DXL_NOT_INITIALIZED;
01348 }
01349 mLogCrawlLn("setPIDPosition(double p, double d, double i, double i_limit, bool shouldSyncWrite) with parameters "
01350 << p << " " << d << " "<< i << " " << i_limit << " " << shouldSyncWrite);
01351
01352 WORD data[4];
01353 data[0] = half(p).bits();
01354 data[1] = half(d).bits();
01355 data[2] = half(i).bits();
01356 data[3] = half(i_limit).bits();
01357 return writeData(M3XL_P_POSITION_L, 8, (BYTE*)data, shouldSyncWrite);
01358 }
01359
01360 int C3mxl::setPIDSpeed(double p, double d, double i, double i_limit, bool shouldSyncWrite)
01361 {
01362 if (!mInitialized){
01363 return DXL_NOT_INITIALIZED;
01364 }
01365 mLogCrawlLn("setPIDSpeed(double p, double d, double i, double i_limit, bool shouldSyncWrite) with parameters "
01366 << p << " " << d << " "<< i << " " << i_limit << " " << shouldSyncWrite);
01367
01368 WORD data[4];
01369 data[0] = half(p).bits();
01370 data[1] = half(d).bits();
01371 data[2] = half(i).bits();
01372 data[3] = half(i_limit).bits();
01373 return writeData(M3XL_P_SPEED_L, 8, (BYTE*)data, shouldSyncWrite);
01374 }
01375
01376 int C3mxl::setPIDTorque(double p, double d, double i, double i_limit, bool shouldSyncWrite)
01377 {
01378 if (!mInitialized){
01379 return DXL_NOT_INITIALIZED;
01380 }
01381 mLogCrawlLn("setPIDTorque(double p, double d, double i, double i_limit, bool shouldSyncWrite) with parameters "
01382 << p << " " << d << " "<< i << " " << i_limit << " " << shouldSyncWrite);
01383
01384 WORD data[4];
01385 data[0] = half(p).bits();
01386 data[1] = half(d).bits();
01387 data[2] = half(i).bits();
01388 data[3] = half(i_limit).bits();
01389 return writeData(M3XL_P_TORQUE_L, 8, (BYTE*)data, shouldSyncWrite);
01390 }
01391
01392 int C3mxl::setPIDEnergy(double p, double d, double i, double i_limit, bool shouldSyncWrite)
01393 {
01394 if (!mInitialized){
01395 return DXL_NOT_INITIALIZED;
01396 }
01397 mLogCrawlLn("setPIDEnergy(double p, double d, double i, double i_limit, bool shouldSyncWrite) with parameters "
01398 << p << " " << d << " "<< i << " " << i_limit << " " << shouldSyncWrite);
01399
01400 WORD data[4];
01401 data[0] = half(p).bits();
01402 data[1] = half(d).bits();
01403 data[2] = half(i).bits();
01404 data[3] = half(i_limit).bits();
01405 return writeData(M3XL_P_ENERGY_L, 8, (BYTE*)data, shouldSyncWrite);
01406 }
01407
01408 int C3mxl::getPIDCurrent(double &p, double &d, double &i, double &i_limit)
01409 {
01410 if (!mInitialized){
01411 return DXL_NOT_INITIALIZED;
01412 }
01413
01414 WORD data[4];
01415 int result;
01416
01417 if ((result = readData(M3XL_P_CURRENT_L, 8, (BYTE*)data)) != DXL_SUCCESS)
01418 return result;
01419
01420 half h;
01421 h.setBits(data[0]); p = (float) h;
01422 h.setBits(data[1]); d = (float) h;
01423 h.setBits(data[2]); i = (float) h;
01424 h.setBits(data[3]); i_limit = (float) h;
01425
01426 return DXL_SUCCESS;
01427 }
01428
01429 int C3mxl::getPIDPosition(double &p, double &d, double &i, double &i_limit)
01430 {
01431 if (!mInitialized){
01432 return DXL_NOT_INITIALIZED;
01433 }
01434
01435 WORD data[4];
01436 int result;
01437
01438 if ((result = readData(M3XL_P_POSITION_L, 8, (BYTE*)data)) != DXL_SUCCESS)
01439 return result;
01440
01441 half h;
01442 h.setBits(data[0]); p = (float) h;
01443 h.setBits(data[1]); d = (float) h;
01444 h.setBits(data[2]); i = (float) h;
01445 h.setBits(data[3]); i_limit = (float) h;
01446
01447 return DXL_SUCCESS;
01448 }
01449
01450 int C3mxl::getPIDSpeed(double &p, double &d, double &i, double &i_limit)
01451 {
01452 if (!mInitialized){
01453 return DXL_NOT_INITIALIZED;
01454 }
01455
01456 WORD data[4];
01457 int result;
01458
01459 if ((result = readData(M3XL_P_SPEED_L, 8, (BYTE*)data)) != DXL_SUCCESS)
01460 return result;
01461
01462 half h;
01463 h.setBits(data[0]); p = (float) h;
01464 h.setBits(data[1]); d = (float) h;
01465 h.setBits(data[2]); i = (float) h;
01466 h.setBits(data[3]); i_limit = (float) h;
01467
01468 return DXL_SUCCESS;
01469 }
01470
01471 int C3mxl::getPIDTorque(double &p, double &d, double &i, double &i_limit)
01472 {
01473 if (!mInitialized){
01474 return DXL_NOT_INITIALIZED;
01475 }
01476
01477 WORD data[4];
01478 int result;
01479
01480 if ((result = readData(M3XL_P_TORQUE_L, 8, (BYTE*)data)) != DXL_SUCCESS)
01481 return result;
01482
01483 half h;
01484 h.setBits(data[0]); p = (float) h;
01485 h.setBits(data[1]); d = (float) h;
01486 h.setBits(data[2]); i = (float) h;
01487 h.setBits(data[3]); i_limit = (float) h;
01488
01489 return DXL_SUCCESS;
01490 }
01491
01492 int C3mxl::getPIDEnergy(double &p, double &d, double &i, double &i_limit)
01493 {
01494 if (!mInitialized){
01495 return DXL_NOT_INITIALIZED;
01496 }
01497
01498 WORD data[4];
01499 int result;
01500
01501 if ((result = readData(M3XL_P_ENERGY_L, 8, (BYTE*)data)) != DXL_SUCCESS)
01502 return result;
01503
01504 half h;
01505 h.setBits(data[0]); p = (float) h;
01506 h.setBits(data[1]); d = (float) h;
01507 h.setBits(data[2]); i = (float) h;
01508 h.setBits(data[3]); i_limit = (float) h;
01509
01510 return DXL_SUCCESS;
01511 }
01512
01513
01514
01515
01516
01517
01518
01519
01520 int C3mxl::printReport(FILE* fOut)
01521 {
01522 int waitingtime = 0;
01523 if (!mInitialized)
01524 return DXL_NOT_INITIALIZED;
01525
01526 BYTE data[LAST_MESSAGE_ADDRESS];
01527 memset(data, 0, LAST_MESSAGE_ADDRESS*sizeof(BYTE));
01528
01529 mLogCrawlLn("waiting time set to "<< waitingtime);
01530 for(int i=0; i<LAST_MESSAGE_ADDRESS ; i++)
01531 {
01532 mLogCrawlLn("checking adress "<<i);
01533 int result = readData(i, 1, &data[i]);
01534 if (result != DXL_SUCCESS)
01535 {
01536 return result;
01537 }
01538
01539 usleep(waitingtime);
01540
01541
01542 }
01543
01544 return DXL_SUCCESS;
01545 }
01546
01547 int C3mxl::interpretControlData(BYTE address, BYTE length, BYTE *data)
01548 {
01549
01550
01551
01552
01553 if (address == M3XL_VOLTAGE_L && length == 10)
01554 {
01555 mVoltage = mxlVoltageToInternalVoltage (*(WORD*)(data+0));
01556 mCurrent = mxlCurrentToInternalCurrent (*(WORD*)(data+2));
01557 mTorque = mxlTorqueToInternalTorque (*(WORD*)(data+4));
01558 mPosition = mxlPosToInternalPos (*(WORD*)(data+6));
01559 mSpeed = mxlSpeedToInternalSpeed (*(WORD*)(data+8));
01560 }
01561 }
01562