3mxl.cpp
Go to the documentation of this file.
00001 // Dynamixel control code - C++ file
00002 // Copyright (c) 2010 Eelko van Breda
00003 // based on dynamixel.cpp (Erik Schuitema & Eelko van Breda)
00004 // Delft University of Technology
00005 // www.dbl.tudelft.nl
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> // we have a usleep in report which is nonrt
00015 
00016 #include <threemxl/externals/half/half.h>
00017 
00018 using namespace std;
00019 
00020 //***********************************************************//
00021 //*********************** CDynamixel ************************//
00022 //***********************************************************//
00023 
00024 
00025 C3mxl::C3mxl(): CDxlGeneric(), mLog("3mxl")
00026 {
00027         //NOTE: Most of the initial values are set in the  setConfig() and init() methods!
00028 //      mLog.setLevel(llCrawl);
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 //3MXL_OK
00066 double C3mxl::mxlCurrentToInternalCurrent(WORD current) //convert from mA to A
00067 {
00068         return (((short)current)/1000.0);
00069 }
00070 
00071 //3MXL_OK
00072 WORD C3mxl::internalCurrentToMxlCurrent(double current) //convert from A to mA
00073 {
00074         return clipToMaxWord((int)(current*1000));
00075 }
00076 
00077 //3MXL_OK
00078 double C3mxl::mxlVoltageToInternalVoltage(WORD voltage) //convert from cV to V
00079 {
00080         return (((int16_t)voltage)/100.0);
00081 }
00082 
00083 //3MXL_OK
00084 WORD C3mxl::internalVoltageToMxlVoltage(double voltage) //convert from V to cV
00085 {
00086         return (int)(voltage*100);
00087 }
00088 
00089 //3MXL_OK
00090 double C3mxl::mxlPosToInternalPos(WORD pos) //convert from mrad to rad
00091 {
00092         return (((short)pos)/1000.0);
00093 }
00094 
00095 //3MXL_OK
00096 WORD C3mxl::internalPosToMxlPos(double pos) //convert from rad to mrad
00097 {
00098         return clipToMaxWord((int)(pos*1000));
00099 }
00100 
00101 //3MXL_OK
00102 double C3mxl::mxlSpeedToInternalSpeed(WORD speed) //convert from 10mrad/s to rad/s
00103 {
00104         return  (((short)speed)/100.0);
00105 }
00106 
00107 //3MXL_OK
00108 WORD C3mxl::internalSpeedToMxlSpeed(double speed) //convert from rad/s to 10mrad/s
00109 {
00110         return clipToMaxWord((int)(speed*100));
00111 }
00112 
00113 //3MXL_OK
00114 double C3mxl::mxlAccelerationToInternalAcceleration(WORD acceleration) //convert from 10mrad/s^2 to rad/s^2
00115 {
00116         return  (((short)acceleration)/100.0);
00117 }
00118 
00119 //3MXL_OK
00120 WORD C3mxl::internalAccelerationToMxlAcceleration(double acceleration) //convert from rad/s^2 to 10mrad/s^2
00121 {
00122         return clipToMaxWord((int)(acceleration*100));
00123 }
00124 
00125 //3MXL_OK
00126 double C3mxl::mxlLinearPosToInternalLinearPos(DWORD pos) //convert from 100um to m
00127 {
00128         return (((int)pos)/10000.0);
00129 }
00130 
00131 //3MXL_OK
00132 DWORD C3mxl::internalLinearPosToMxlLinearPos(double pos) //convert from m to 100um
00133 {
00134         return clipToMaxDWord((int)(pos*10000));
00135 }
00136 
00137 //3MXL_OK
00138 double C3mxl::mxlLinearSpeedToInternalLinearSpeed(WORD speed) //convert from mm/s to m/s
00139 {
00140         return  (((short)speed)/1000.0);
00141 }
00142 
00143 //3MXL_OK
00144 WORD C3mxl::internalLinearSpeedToMxlLinearSpeed(double speed) //convert from m/s to mm/s
00145 {
00146         return clipToMaxWord((int)(speed*1000));
00147 }
00148 
00149 //3MXL_OK
00150 double C3mxl::mxlLinearAccelerationToInternalLinearAcceleration(WORD acceleration) //convert from mm/s^2 to m
00151 {
00152         return  (((short)acceleration)/1000.0);
00153 }
00154 
00155 //3MXL_OK
00156 WORD C3mxl::internalLinearAccelerationToMxlLinearAcceleration(double acceleration) //convert from m/s^2 to mm/s^2
00157 {
00158         return clipToMaxWord((int)(acceleration*1000));
00159 }
00160 
00161 //3MXL_OK
00162 double C3mxl::mxlTorqueToInternalTorque(WORD torque) //convert from 1 mNm to Nm
00163 {
00164         return  (((short)torque)/1000.0) ;
00165 }
00166 
00167 //3MXL_OK
00168 WORD C3mxl::internalTorqueToMxlTorque(double torque) //convert from Nm to mNm
00169 {
00170         return clipToMaxWord((int)(torque*1000));
00171 }
00172 
00173 //3MXL_OK
00174 WORD C3mxl::internalFreqToMxlFreq(double frequency) //convert from Hz to cHz
00175 {
00176         return clipToMaxWord((int)(frequency*100));
00177 }
00178 
00179 //3MXL_OK
00180 WORD C3mxl::internalAmplitudeToMxlAmplitude(double amplitude) //convert from rad to mrad
00181 {
00182         return clipToMaxWord((int)(amplitude*1000));
00183 }
00184 
00185 //3MXL_OK
00186 WORD C3mxl::internalPhaseToMxlPhase(double phase) //convert from rad to mrad
00187 {
00188         return clipToMaxWord((int)(phase*1000));
00189 }
00190 
00191 //3MXL_OK
00192 double C3mxl::mxlPWMToInternalPWM(WORD pwm) //convert percentage to fraction
00193 {
00194         return (((short)pwm)/100.0);
00195 }
00196 
00197 //3MXL_OK
00198 WORD C3mxl::internalPWMToMxlPWM(double pwm) //convert fraction to percentage
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 //still needs work
00233 void C3mxl::setConfig(CDxlConfig* config)
00234 {
00235         // Just copy the configuration
00236         mConfig = *config;
00237         
00238         // Immediately take over new ID when configuring a new motor.
00239         if (!mInitialized && mConfig.mID.isSet())
00240           mID = mConfig.mID;
00241 
00242         // Set direction convention
00243         if (mConfig.mClockwiseIsPositive.isSet())
00244                 {setPositiveDirection(mConfig.mClockwiseIsPositive);}
00245         else
00246                 {setPositiveDirection(1);}
00247 
00248         //set initial configuration if not defined in the configuration
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 //      if (!mConfig.mMaxUninitialisedMotorCurrent.isSet())     {setMaxUninitializedMotorCurrent(INITIAL_MAX_UNINITIALIZED_MOTOR_CURRENT);}
00264 //      if (!mConfig.mMaxMotorCurrent.isSet())                          {setMaxMotorCurrent(INITIAL_MAX_MOTOR_CURRENT);}
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 //3MXL_OK
00273 void C3mxl::setSerialPort(LxSerial* serialPort)
00274 {
00275         mSerialPort = serialPort;
00276         mLogCrawlLn("set serialport called");
00277 }
00278 //3MXL_OK
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 //3MXL_OK
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); // offset mRad
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); // offset in mRad
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); //send to 3mxl
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 //int C3mxl::setMaxUninitializedMotorCurrent(WORD maxcurrent)
00544 //{
00545 //      if (!mInitialized)
00546 //              return DXL_NOT_INITIALIZED;
00547 //
00548 //      mLogCrawlLn("setMaxUninitializedMotorCurrent with parameter " << (int)maxcurrent);
00549 //
00550 //      return writeData(M3XL_MAX_UNINITIALIZED_MOTOR_CURRENT_L, 2,(BYTE*)&maxcurrent , false);
00551 //}
00552 //
00553 //int C3mxl::setMaxMotorCurrent(WORD maxcurrent)
00554 //{
00555 //      if (!mInitialized)
00556 //              return DXL_NOT_INITIALIZED;
00557 //
00558 //      mLogCrawlLn("setMaxMotorCurrent with parameter " << (int)maxcurrent);
00559 //
00560 //      return writeData(M3XL_MAX_MOTOR_CURRENT_L, 2,(BYTE*)&maxcurrent , false);
00561 //}
00562 
00563 //3MXL_OK
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 //3MXL_OK
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 //3MXL_OK
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 //todo: convert initial torque to maxuninitialisedmotorcurrent
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 //int C3mxl::getAngleLimits()
00646 //{
00647 //      if (!mInitialized)
00648 //              return DXL_NOT_INITIALIZED;
00649 //      if (mEndlessTurnMode)
00650 //              return -DXL_ERR_INSTRUCTION;
00651 //
00652 //      WORD data[2];
00653 //      int result = readData(P_CW_ANGLE_LIMIT_L, 4, (BYTE*)data);
00654 //      if (result != DXL_SUCCESS)
00655 //              return result;
00656 //
00657 //      // The angle limits are NOT saved in SI units (see member field definitions).
00658 //      mCWAngleLimit   = data[0];
00659 //      mCCWAngleLimit  = data[1];
00660 //      return DXL_SUCCESS;
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         // The angle limits are NOT saved in SI units (see member field definitions).
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; //convert to cNm/rad
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; //convert to mJ
00713 
00714         return writeData(M3XL_REFERENCE_ENERGY_L, 2, (BYTE*)data);
00715 }
00716 
00717 //int C3mxl::set
00718 //{
00719 //      if (!mInitialized)
00720 //              return DXL_NOT_INITIALIZED;
00721 //
00722 //}
00723 
00724 //double C3mxl::presentAngleLowerLimit()
00725 //{
00726 //      if (mDirection<0)
00727 //              return dxlPosToInternalPos(mCCWAngleLimit);
00728 //      else
00729 //              return dxlPosToInternalPos(mCWAngleLimit);
00730 //}
00731 //
00732 //double C3mxl::presentAngleUpperLimit()
00733 //{
00734 //      if (mDirection<0)
00735 //              return dxlPosToInternalPos(mCWAngleLimit);
00736 //      else
00737 //              return dxlPosToInternalPos(mCCWAngleLimit);
00738 //}
00739 
00740 
00741 //3MXL_OK
00742 int C3mxl::init(bool sendConfigToMotor)
00743 {
00744 //      if (mInitialized)
00745 //              return DXL_ALREADY_INITIALIZED;
00746         int initResult = initPacketHandler();
00747         if (initResult != DXL_SUCCESS)
00748         {
00749                 logDebugLn(mLog,"Error initializing packet handler!");
00750                 return initResult;
00751         }
00752 
00753         // Set internal ID to perform initial ping() and return level readout
00754         if (mConfig.mID.isSet())
00755                 {mID = mConfig.mID;}
00756         else
00757         {
00758                 mInitialized = false;
00759                 return DXL_NOT_INITIALIZED;
00760         }
00761         
00762         // Can't ask anything of the broadcast address
00763         if (mID == BROADCAST_ID)
00764         {
00765             mInitialized = true;
00766             return DXL_SUCCESS;
00767         }
00768 
00769         // Is this dynamixel alive?
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         // Check return level
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)             // possible that return level is 0 and dynamixel doesn't respond
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                         // on all other errors do not initialize
00800                         mLogErrorLn("3mxl " << mID << " did not return status return level!");
00801                         mInitialized = false;
00802                 }
00803         }
00804 
00805         if (sendConfigToMotor)
00806         {       // Configure the motor according to mConfig
00807                 result = mConfig.configureDynamixel(this);
00808         }
00809 //      result += setPositiveDirectionMotor(clockwiseIsPositive);
00810 
00811         return result;
00812 }
00813 
00814 //3MXL_OK
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                 // This means the ID actually changed! Success!
00826                 mID = newID;
00827                 return DXL_SUCCESS;
00828         }
00829         else
00830         if (result == DXL_SUCCESS)
00831         {
00832                 // We should get a DXL_PKT_RECV_ID_ERR but hey.. DXL_SUCCESS is better than FAIL!
00833                 //printf(" (changeID returned DXL_SUCCESS instead of DXL_PKT_RECV_ID_ERR) \n");
00834                 mID = newID;
00835                 return DXL_SUCCESS;
00836         }
00837         else
00838                 return result;
00839 }
00840 
00841 //3MXL_OK
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 //3MXL_OK
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 //3MXL_OK
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 //3MXL_OK
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 //3MXL_OK
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 //3MXL_OK
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 //3MXL_OK
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 //3MXL_OK
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 //3MXL_OK
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 //3MXL_OK
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         //clear buffer
01074         mMxlLog.clear();
01075 
01076         TMxlLogEntry data[M3XL_NR_OF_SAMPLES_PER_BLOCK];
01077 
01078         //Read to buffer loop
01079         for (BYTE i = 1 ; i <= M3XL_NR_OF_BLOCKS; i++ ){
01080                 //write block pointer to 3mxl
01081                 writeData(M3XL_DATA_LOGGER, 1, &i);
01082                 //read the bytes to the buffer
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)       // Interpret negative speeds as maximum speed
01128                 data[1] = 0;    // speed = 0 means MAXIMUM speed.
01129         else
01130                 data[1] = abs(internalSpeedToMxlSpeed(absSpeed));       // use abs() here, because internalSpeedToDxlSpeed() may return something negative.
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)       // Interpret negative speeds as maximum speed
01163                 data[1] = 0;    // speed = 0 means MAXIMUM speed.
01164         else
01165                 data[1] = abs(internalSpeedToMxlSpeed(absSpeed));       // use abs() here, because internalSpeedToDxlSpeed() may return something negative.
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 //TODO: needs work, directly set correct mode on 3mxl if not in sync
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         //TODO: do something with mxlMode_Speed
01194         WORD data[1];
01195         data[0] = internalSpeedToMxlSpeed(speed);
01196         return writeData(M3XL_DESIRED_SPEED_L, 2, (BYTE*)data, shouldSyncWrite);
01197 }
01198 
01199 //TODO: needs work, directly set correct mode on 3mxl if not in sync
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         //TODO: do something with mxlMode_Speed
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         //TODO: do something with mxlMode_Speed
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         //TODO: do something with mxlMode_Speed
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         //TODO: do something with mxlMode_Speed
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         //TODO: do something with mxlMode_Speed
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 //      if (m3mxlMode == UNINITIALISED){
01313 //              mLogWarningLn("3mxl not initialized!");
01314 //              return DXL_NOT_INITIALIZED;
01315 //      }
01316         //TODO: do something with mxlMode_PosSpeedTorquePPosDPos
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 //string readToStr(BYTE startingAddress, BYTE dataLength)
01514 //{
01515 //      BYTE data[dataLength];
01516 //      readData(startingAddress,dataLength,data);
01517 //      string answer = data;
01518 //      return answer;
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         //      int result = readData(MODEL_NUMBER_L, M3XL_MAX_TABLE_SIZE, data);       // Read 50 bytes to read the complete control table
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]);  // Read each byte
01534                 if (result != DXL_SUCCESS)
01535                 {
01536                         return result;
01537                 }
01538                 //usleep(10000);
01539                 usleep(waitingtime);
01540                 //      s  m  u  n
01541                 //      rtdm_task_sleep((nanosecs_rel_t)0010000000);
01542         }
01543 
01544         return DXL_SUCCESS;
01545 }
01546 
01547 int C3mxl::interpretControlData(BYTE address, BYTE length, BYTE *data)
01548 {
01549   // should be like:
01550   // if (address >= M3XL_VOLTAGE_L && address+length >= M3XL_VOLTAGE_L+2)
01551   //   mVoltage    = mxlVoltageToInternalVoltage   (*(WORD*)(data+xxx));
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 


threemxl
Author(s):
autogenerated on Fri Aug 28 2015 13:21:08