00001 #include "Robots/Scorbot/ScorbotInterface.H"
00002
00003
00004 ScorbotInterface::ScorbotInterface(OptionManager& mgr,
00005 const std::string& descrName, const std::string& tagName) :
00006 ModelComponent(mgr, descrName, tagName),
00007 itsSerial(new Serial(mgr))
00008 {
00009 addSubComponent(itsSerial);
00010 itsSerial->configure("/dev/ttyACM0", 115200, "8N1", false, false, 100000);
00011
00012 pthread_mutex_init(&itsSerialMutex, NULL);
00013 }
00014
00015
00016 void ScorbotInterface::start2()
00017 {
00018 itsSerial->flush();
00019
00020
00021 setControlParams(ScorbotInterface::Base,
00022 0.018,
00023 .00015,
00024 0.0000,
00025 200,
00026 1,
00027 0
00028 );
00029
00030 setControlParams(ScorbotInterface::Shoulder,
00031 0.009,
00032 0.0004,
00033 0,
00034 200,
00035 1,
00036 0
00037 );
00038
00039 setControlParams(ScorbotInterface::Elbow,
00040 0.015,
00041 0.0002,
00042 0,
00043 200,
00044 1,
00045 0
00046 );
00047
00048 setControlParams(ScorbotInterface::Wrist1,
00049 0.010,
00050 0.0002,
00051 0,
00052 200,
00053 1,
00054 0
00055 );
00056
00057 setControlParams(ScorbotInterface::Wrist2,
00058 0.015,
00059 0.0008,
00060 0,
00061 200,
00062 1,
00063 0
00064 );
00065
00066 setControlParams(ScorbotInterface::Slider,
00067 0.0015,
00068 0.00011,
00069 0.00011,
00070 2000,
00071 1,
00072 0
00073 );
00074
00075
00076 setJoints(getEncoders(), 1000);
00077 }
00078
00079
00080 ScorbotInterface::~ScorbotInterface()
00081 {
00082 setEnabled(false);
00083 }
00084
00085
00086 void ScorbotInterface::setJoint(ScorbotInterface::Joint_t joint, int32 encoderPos, int32 time_ms)
00087 {
00088 pthread_mutex_lock(&itsSerialMutex);
00089 byte cmd[11];
00090
00091 cmd[0] = 20;
00092 cmd[1] = (byte)joint;
00093
00094 cmd[2] = 0x0FF & ( encoderPos >> 24 );
00095 cmd[3] = 0x0FF & ( encoderPos >> 16 );
00096 cmd[4] = 0x0FF & ( encoderPos >> 8 );
00097 cmd[5] = 0x0FF & ( encoderPos >> 0 );
00098
00099 cmd[6] = 0x0FF & ( time_ms >> 24 );
00100 cmd[7] = 0x0FF & ( time_ms >> 16 );
00101 cmd[8] = 0x0FF & ( time_ms >> 8 );
00102 cmd[9] = 0x0FF & ( time_ms >> 0 );
00103
00104 cmd[10] = 255;
00105
00106 itsSerial->write(cmd, 11);
00107
00108
00109 byte retVal = 0;
00110 int retNum = itsSerial->read(&retVal, 1);
00111 if(retNum != 1 || retVal != 255)
00112 LERROR("Error Disabling Scorbot");
00113 itsSerial->flush();
00114 pthread_mutex_unlock(&itsSerialMutex);
00115 }
00116
00117
00118 void ScorbotInterface::setJoints(ScorbotInterface::encoderVals_t pos, int32 time_ms)
00119 {
00120 ScorbotInterface::encoderVals_t::iterator posIt;
00121 for(posIt = pos.begin(); posIt != pos.end(); ++posIt)
00122 setJoint(posIt->first, posIt->second, time_ms);
00123 }
00124
00125
00126 ScorbotInterface::encoderVals_t ScorbotInterface::getEncoders()
00127 {
00128 ScorbotInterface::encoderVals_t encoders;
00129
00130 pthread_mutex_lock(&itsSerialMutex);
00131 byte cmd[2];
00132 cmd[0] = 22;
00133 cmd[1] = 255;
00134 itsSerial->flush();
00135 itsSerial->write(cmd, 2);
00136
00137 std::vector<byte> res = itsSerial->readFrame(cmd[0], 255, -1, .01);
00138
00139 if(res.size() == 0)
00140 LINFO("Could Not Read Encoder Vals");
00141 else
00142 {
00143 int idx = 0;
00144 encoders[ScorbotInterface::Base] = res[idx++] << 24;
00145 encoders[ScorbotInterface::Base] |= res[idx++] << 16;
00146 encoders[ScorbotInterface::Base] |= res[idx++] << 8;
00147 encoders[ScorbotInterface::Base] |= res[idx++] << 0;
00148
00149 encoders[ScorbotInterface::Shoulder] = res[idx++] << 24;
00150 encoders[ScorbotInterface::Shoulder] |= res[idx++] << 16;
00151 encoders[ScorbotInterface::Shoulder] |= res[idx++] << 8;
00152 encoders[ScorbotInterface::Shoulder] |= res[idx++] << 0;
00153
00154 encoders[ScorbotInterface::Elbow] = res[idx++] << 24;
00155 encoders[ScorbotInterface::Elbow] |= res[idx++] << 16;
00156 encoders[ScorbotInterface::Elbow] |= res[idx++] << 8;
00157 encoders[ScorbotInterface::Elbow] |= res[idx++] << 0;
00158
00159 encoders[ScorbotInterface::Wrist1] = res[idx++] << 24;
00160 encoders[ScorbotInterface::Wrist1] |= res[idx++] << 16;
00161 encoders[ScorbotInterface::Wrist1] |= res[idx++] << 8;
00162 encoders[ScorbotInterface::Wrist1] |= res[idx++] << 0;
00163
00164 encoders[ScorbotInterface::Wrist2] = res[idx++] << 24;
00165 encoders[ScorbotInterface::Wrist2] |= res[idx++] << 16;
00166 encoders[ScorbotInterface::Wrist2] |= res[idx++] << 8;
00167 encoders[ScorbotInterface::Wrist2] |= res[idx++] << 0;
00168
00169 encoders[ScorbotInterface::Gripper] = res[idx++] << 24;
00170 encoders[ScorbotInterface::Gripper] |= res[idx++] << 16;
00171 encoders[ScorbotInterface::Gripper] |= res[idx++] << 8;
00172 encoders[ScorbotInterface::Gripper] |= res[idx++] << 0;
00173
00174 encoders[ScorbotInterface::Slider] = res[idx++] << 24;
00175 encoders[ScorbotInterface::Slider] |= res[idx++] << 16;
00176 encoders[ScorbotInterface::Slider] |= res[idx++] << 8;
00177 encoders[ScorbotInterface::Slider] |= res[idx++] << 0;
00178 }
00179
00180 itsSerial->flush();
00181 pthread_mutex_unlock(&itsSerialMutex);
00182
00183 return encoders;
00184 };
00185
00186
00187
00188 int32 ScorbotInterface::getEncoder(ScorbotInterface::Joint_t joint)
00189 {
00190 pthread_mutex_lock(&itsSerialMutex);
00191
00192 byte cmd[3];
00193 cmd[0] = 10;
00194 cmd[1] = (byte)joint;
00195 cmd[2] = 255;
00196 itsSerial->write(cmd, 3);
00197
00198
00199 byte retVal[5];
00200 retVal[4] = 0;
00201 int retNum = itsSerial->read(retVal, 5);
00202 if(retNum != 5 || retVal[4] != 255)
00203 LERROR("Error Getting Joint Position (Joint %d): Recieved %d bytes: %d", (byte)joint, retNum, retVal[4]);
00204
00205 int32 encoder = 0;
00206 encoder |= (0x0FF & retVal[0]) << 24;
00207 encoder |= (0x0FF & retVal[1]) << 16;
00208 encoder |= (0x0FF & retVal[2]) << 8;
00209 encoder |= (0x0FF & retVal[3]) << 0;
00210
00211 itsSerial->flush();
00212 pthread_mutex_unlock(&itsSerialMutex);
00213
00214 return encoder;
00215 }
00216
00217
00218 float ScorbotInterface::getPWM(ScorbotInterface::Joint_t joint)
00219 {
00220 pthread_mutex_lock(&itsSerialMutex);
00221
00222 byte cmd[3];
00223 cmd[0] = 12;
00224 cmd[1] = (byte)joint;
00225 cmd[2] = 255;
00226 itsSerial->write(cmd, 3);
00227
00228
00229 byte retVal[5];
00230 retVal[4] = 0;
00231 int retNum = itsSerial->read(retVal, 5);
00232 if(retNum != 5 || retVal[4] != 255)
00233 LERROR("Error Getting Joint PWM (Joint %d): Recieved %d bytes: %d", (byte)joint, retNum, retVal[4]);
00234
00235 int32 pwm_fp = 0;
00236 pwm_fp |= (0x0FF & retVal[0]) << 24;
00237 pwm_fp |= (0x0FF & retVal[1]) << 16;
00238 pwm_fp |= (0x0FF & retVal[2]) << 8;
00239 pwm_fp |= (0x0FF & retVal[3]) << 0;
00240
00241 itsSerial->flush();
00242 pthread_mutex_unlock(&itsSerialMutex);
00243
00244 return float(pwm_fp)/100000.0;
00245 }
00246
00247
00248 ScorbotInterface::pwmVals_t ScorbotInterface::getPWMs()
00249 {
00250 ScorbotInterface::pwmVals_t PWMs;
00251
00252 pthread_mutex_lock(&itsSerialMutex);
00253 byte cmd[2];
00254 cmd[0] = 23;
00255 cmd[1] = 255;
00256 itsSerial->flush();
00257 itsSerial->write(cmd, 2);
00258
00259 std::vector<byte> res = itsSerial->readFrame(cmd[0], 255, -1, .01);
00260
00261 if(res.size() == 0)
00262 LINFO("Could Not Read Encoder Vals");
00263 else
00264 {
00265 int32 tmp_fp = 0;
00266
00267 int idx = 0;
00268 tmp_fp = res[idx++] << 24;
00269 tmp_fp |= res[idx++] << 16;
00270 tmp_fp |= res[idx++] << 8;
00271 tmp_fp |= res[idx++] << 0;
00272 PWMs[ScorbotInterface::Base] = float(tmp_fp)/100000.0;
00273
00274 tmp_fp = res[idx++] << 24;
00275 tmp_fp |= res[idx++] << 16;
00276 tmp_fp |= res[idx++] << 8;
00277 tmp_fp |= res[idx++] << 0;
00278 PWMs[ScorbotInterface::Shoulder] = float(tmp_fp)/100000.0;
00279
00280 tmp_fp = res[idx++] << 24;
00281 tmp_fp |= res[idx++] << 16;
00282 tmp_fp |= res[idx++] << 8;
00283 tmp_fp |= res[idx++] << 0;
00284 PWMs[ScorbotInterface::Elbow] = float(tmp_fp)/100000.0;
00285
00286 tmp_fp = res[idx++] << 24;
00287 tmp_fp |= res[idx++] << 16;
00288 tmp_fp |= res[idx++] << 8;
00289 tmp_fp |= res[idx++] << 0;
00290 PWMs[ScorbotInterface::Wrist1] = float(tmp_fp)/100000.0;
00291
00292 tmp_fp = res[idx++] << 24;
00293 tmp_fp |= res[idx++] << 16;
00294 tmp_fp |= res[idx++] << 8;
00295 tmp_fp |= res[idx++] << 0;
00296 PWMs[ScorbotInterface::Wrist2] = float(tmp_fp)/100000.0;
00297
00298 tmp_fp = res[idx++] << 24;
00299 tmp_fp |= res[idx++] << 16;
00300 tmp_fp |= res[idx++] << 8;
00301 tmp_fp |= res[idx++] << 0;
00302 PWMs[ScorbotInterface::Gripper] = float(tmp_fp)/100000.0;
00303
00304 tmp_fp = res[idx++] << 24;
00305 tmp_fp |= res[idx++] << 16;
00306 tmp_fp |= res[idx++] << 8;
00307 tmp_fp |= res[idx++] << 0;
00308 PWMs[ScorbotInterface::Slider] = float(tmp_fp)/100000.0;
00309 }
00310
00311 itsSerial->flush();
00312 pthread_mutex_unlock(&itsSerialMutex);
00313
00314 return PWMs;
00315 };
00316
00317
00318 void ScorbotInterface::setEnabled(bool enabled)
00319 {
00320 pthread_mutex_lock(&itsSerialMutex);
00321
00322
00323 if(enabled)
00324 {
00325 byte cmd[2];
00326 cmd[0] = 30;
00327 cmd[1] = 255;
00328 itsSerial->write(cmd, 2);
00329 usleep(10000);
00330
00331
00332 byte retVal;
00333 int retNum = itsSerial->read(&retVal, 1);
00334
00335 if(retNum != 1 || retVal != 255)
00336 LERROR("Error Enabling Scorbot");
00337
00338 }
00339 else
00340 {
00341 byte cmd[2];
00342 cmd[0] = 31;
00343 cmd[1] = 255;
00344 itsSerial->write(cmd, 2);
00345
00346
00347 byte retVal;
00348 byte retNum = itsSerial->read(&retVal, 1);
00349
00350 if(retNum != 1 || retVal != 255)
00351 LERROR("Error Disabling Scorbot");
00352 }
00353 itsSerial->flush();
00354 pthread_mutex_unlock(&itsSerialMutex);
00355 }
00356
00357
00358 void ScorbotInterface::resetEncoders()
00359 {
00360
00361 setEnabled(false);
00362 usleep(10000);
00363
00364 pthread_mutex_lock(&itsSerialMutex);
00365
00366 byte cmd[2];
00367 cmd[0] = 21;
00368 cmd[1] = 255;
00369 itsSerial->write(cmd, 2);
00370
00371
00372 byte retVal = 0;
00373 int retNum = itsSerial->read(&retVal, 1);
00374 if(retNum != 1 || retVal != 255)
00375 LERROR("Error Disabling Scorbot");
00376
00377 itsSerial->flush();
00378 pthread_mutex_unlock(&itsSerialMutex);
00379
00380
00381 ScorbotInterface::encoderVals_t encoders;
00382 encoders[ScorbotInterface::Base] = 0;
00383 encoders[ScorbotInterface::Shoulder] = 0;
00384 encoders[ScorbotInterface::Elbow] = 0;
00385 encoders[ScorbotInterface::Wrist1] = 0;
00386 encoders[ScorbotInterface::Wrist2] = 0;
00387 encoders[ScorbotInterface::Gripper] = 0;
00388 encoders[ScorbotInterface::Slider] = 0;
00389 setJoints(encoders, 1000);
00390
00391 usleep(10000);
00392 }
00393
00394
00395 void ScorbotInterface::setControlParams(ScorbotInterface::Joint_t joint,
00396 float pGain, float iGain, float dGain, float maxI, float maxPWM, float pwmOffset)
00397 {
00398 pthread_mutex_lock(&itsSerialMutex);
00399
00400
00401 int32 pGain_fp = int32(pGain * 100000.0);
00402 int32 iGain_fp = int32(iGain * 100000.0);
00403 int32 dGain_fp = int32(dGain * 100000.0);
00404 int32 maxI_fp = int32(maxI * 100000.0);
00405 int32 maxPWM_fp = int32(maxPWM * 100000.0);
00406 int32 pwmOffset_fp = int32(pwmOffset * 100000.0);
00407
00408 byte cmd[28];
00409 cmd[0] = 25;
00410 cmd[1] = (byte)joint;
00411
00412 cmd[2] = 24;
00413
00414 cmd[3] = 0x0FF & (pGain_fp >> 24);
00415 cmd[4] = 0x0FF & (pGain_fp >> 16);
00416 cmd[5] = 0x0FF & (pGain_fp >> 8);
00417 cmd[6] = 0x0FF & (pGain_fp >> 0);
00418
00419 cmd[7] = 0x0FF & (iGain_fp >> 24);
00420 cmd[8] = 0x0FF & (iGain_fp >> 16);
00421 cmd[9] = 0x0FF & (iGain_fp >> 8);
00422 cmd[10] = 0x0FF & (iGain_fp >> 0);
00423
00424 cmd[11] = 0x0FF & (dGain_fp >> 24);
00425 cmd[12] = 0x0FF & (dGain_fp >> 16);
00426 cmd[13] = 0x0FF & (dGain_fp >> 8);
00427 cmd[14] = 0x0FF & (dGain_fp >> 0);
00428
00429 cmd[15] = 0x0FF & (maxI_fp >> 24);
00430 cmd[16] = 0x0FF & (maxI_fp >> 16);
00431 cmd[17] = 0x0FF & (maxI_fp >> 8);
00432 cmd[18] = 0x0FF & (maxI_fp >> 0);
00433
00434 cmd[19] = 0x0FF & (maxPWM_fp >> 24);
00435 cmd[20] = 0x0FF & (maxPWM_fp >> 16);
00436 cmd[21] = 0x0FF & (maxPWM_fp >> 8);
00437 cmd[22] = 0x0FF & (maxPWM_fp >> 0);
00438
00439 cmd[23] = 0x0FF & (pwmOffset_fp >> 24);
00440 cmd[24] = 0x0FF & (pwmOffset_fp >> 16);
00441 cmd[25] = 0x0FF & (pwmOffset_fp >> 8);
00442 cmd[26] = 0x0FF & (pwmOffset_fp >> 0);
00443
00444 cmd[27] = 255;
00445
00446 itsSerial->write(cmd, 28);
00447 usleep(1000);
00448
00449
00450 byte retVal = 0;
00451 int retNum = itsSerial->read(&retVal, 1);
00452 if(retNum != 1 || retVal != 255)
00453 LERROR("Error Setting Control Params (retNum: %d, retVal: %d)", retNum, retVal);
00454
00455 itsSerial->flush();
00456 pthread_mutex_unlock(&itsSerialMutex);
00457 }
00458
00459
00460 void ScorbotInterface::getPIDVals(ScorbotInterface::Joint_t joint,
00461 float &pGain, float &iGain, float &dGain, float &maxI, float &maxPWM, float &pwmOffset)
00462 {
00463 pthread_mutex_lock(&itsSerialMutex);
00464 byte cmd[3];
00465 cmd[0] = 15;
00466 cmd[1] = (byte)joint;
00467 cmd[2] = 255;
00468 itsSerial->write(cmd, 3);
00469
00470 byte numVals;
00471 int retNum = itsSerial->read(&numVals, 1);
00472 if(retNum != 1 || numVals != 24)
00473 LERROR("Could Not Read PID Values retNum: %d numVals %d", retNum, numVals);
00474 else
00475 {
00476 usleep(10000);
00477 byte retVal[numVals+1];
00478 retNum = itsSerial->read(retVal, numVals+1);
00479 if(retNum != numVals+1 || retVal[numVals] != 255)
00480 LERROR("Could Not Read PID Values (Error 2) retNum: %d, retVal[numVals]: %d", retNum, retVal[numVals]);
00481 else
00482 {
00483 int numIdx = 0;
00484
00485 int32 pGain_fp = 0;
00486 pGain_fp |= retVal[numIdx++] << 24;
00487 pGain_fp |= retVal[numIdx++] << 16;
00488 pGain_fp |= retVal[numIdx++] << 8;
00489 pGain_fp |= retVal[numIdx++] << 0;
00490
00491 int32 iGain_fp = 0;
00492 iGain_fp |= retVal[numIdx++] << 24;
00493 iGain_fp |= retVal[numIdx++] << 16;
00494 iGain_fp |= retVal[numIdx++] << 8;
00495 iGain_fp |= retVal[numIdx++] << 0;
00496
00497 int32 dGain_fp = 0;
00498 dGain_fp |= retVal[numIdx++] << 24;
00499 dGain_fp |= retVal[numIdx++] << 16;
00500 dGain_fp |= retVal[numIdx++] << 8;
00501 dGain_fp |= retVal[numIdx++] << 0;
00502
00503 int32 maxI_fp = 0;
00504 maxI_fp |= retVal[numIdx++] << 24;
00505 maxI_fp |= retVal[numIdx++] << 16;
00506 maxI_fp |= retVal[numIdx++] << 8;
00507 maxI_fp |= retVal[numIdx++] << 0;
00508
00509 int32 maxPWM_fp = 0;
00510 maxPWM_fp |= retVal[numIdx++] << 24;
00511 maxPWM_fp |= retVal[numIdx++] << 16;
00512 maxPWM_fp |= retVal[numIdx++] << 8;
00513 maxPWM_fp |= retVal[numIdx++] << 0;
00514
00515 int32 pwmOffset_fp = 0;
00516 pwmOffset_fp |= retVal[numIdx++] << 24;
00517 pwmOffset_fp |= retVal[numIdx++] << 16;
00518 pwmOffset_fp |= retVal[numIdx++] << 8;
00519 pwmOffset_fp |= retVal[numIdx++] << 0;
00520
00521 pGain = pGain_fp/100000.0;
00522 iGain = iGain_fp/100000.0;
00523 dGain = dGain_fp/100000.0;
00524 maxI = maxI_fp/100000.0;
00525 maxPWM = maxPWM_fp/100000.0;
00526 pwmOffset = pwmOffset_fp/100000.0;
00527 }
00528 }
00529
00530 itsSerial->flush();
00531 pthread_mutex_unlock(&itsSerialMutex);
00532 }
00533
00534
00535 void ScorbotInterface::getTuningVals(ScorbotInterface::Joint_t joint,
00536 int32 &targetPos, int32 &targetVel, float &gravityCompensation)
00537 {
00538 pthread_mutex_lock(&itsSerialMutex);
00539
00540 byte cmd[3];
00541 cmd[0] = 13;
00542 cmd[1] = (byte)joint;
00543 cmd[2] = 255;
00544 itsSerial->write(cmd, 3);
00545
00546 std::vector<byte> ret = itsSerial->readFrame(cmd[0], 255, -1, .3);
00547
00548 if(ret.size() == 0)
00549 {
00550 LERROR("Could Not Read Tuning Values");
00551 targetPos = 0;
00552 targetVel = 0;
00553 gravityCompensation = 0;
00554 }
00555 else
00556 {
00557 int idx=0;
00558 targetPos = 0;
00559 targetPos |= ret[idx++] << 24;
00560 targetPos |= ret[idx++] << 16;
00561 targetPos |= ret[idx++] << 8;
00562 targetPos |= ret[idx++] << 0;
00563
00564 targetVel = 0;
00565 targetVel |= ret[idx++] << 24;
00566 targetVel |= ret[idx++] << 16;
00567 targetVel |= ret[idx++] << 8;
00568 targetVel |= ret[idx++] << 0;
00569
00570 long gravityCompensationLong = 0;
00571 gravityCompensationLong = ret[idx++] << 24;
00572 gravityCompensationLong |= ret[idx++] << 16;
00573 gravityCompensationLong |= ret[idx++] << 8;
00574 gravityCompensationLong |= ret[idx++] << 0;
00575 gravityCompensation = (float) ((float) gravityCompensationLong) / 100000.0;
00576 }
00577
00578 itsSerial->flush();
00579 pthread_mutex_unlock(&itsSerialMutex);
00580 }
00581
00582
00583 void ScorbotInterface::setGravityParameters(int32 upperArmMass, int32 foreArmMass,
00584 float compensationScale)
00585 {
00586 pthread_mutex_lock(&itsSerialMutex);
00587
00588 byte cmd[14];
00589 cmd[0] = 40;
00590
00591 cmd[1] = 0x0FF & (upperArmMass >> 24);
00592 cmd[2] = 0x0FF & (upperArmMass >> 16);
00593 cmd[3] = 0x0FF & (upperArmMass >> 8);
00594 cmd[4] = 0x0FF & (upperArmMass >> 0);
00595
00596 cmd[5] = 0x0FF & (foreArmMass >> 24);
00597 cmd[6] = 0x0FF & (foreArmMass >> 16);
00598 cmd[7] = 0x0FF & (foreArmMass >> 8);
00599 cmd[8] = 0x0FF & (foreArmMass >> 0);
00600
00601 long compensationScale_fp = (long) (compensationScale * 100000.0);
00602 cmd[9] = 0x0FF & (compensationScale_fp >> 24);
00603 cmd[10] = 0x0FF & (compensationScale_fp >> 16);
00604 cmd[11] = 0x0FF & (compensationScale_fp >> 8);
00605 cmd[12] = 0x0FF & (compensationScale_fp >> 0);
00606
00607 cmd[13] = 255;
00608 itsSerial->write(cmd, 14);
00609
00610 byte retVal;
00611 int retNum = itsSerial->read(&retVal, 1);
00612 if(retNum != 1 || retVal != 255)
00613 LERROR("Could Not Set Gravity Values retNum: %d retVal[0]: %d", retNum, retVal);
00614
00615 itsSerial->flush();
00616 pthread_mutex_unlock(&itsSerialMutex);
00617 }
00618
00619
00620 void ScorbotInterface::getGravityParameters(int32 &upperArmMass, int32 &foreArmMass, float &compensationScale)
00621 {
00622 pthread_mutex_lock(&itsSerialMutex);
00623
00624 byte cmd[3];
00625 cmd[0] = 41;
00626 cmd[1] = 255;
00627 itsSerial->write(cmd, 2);
00628
00629 std::vector<byte> ret = itsSerial->readFrame(cmd[0], 255, -1, .3);
00630
00631 if(ret.size() == 0)
00632 {
00633 LERROR("Could Not Read Gravity Values");
00634 }
00635 else
00636 {
00637 int idx=0;
00638 upperArmMass = 0;
00639 upperArmMass |= ret[idx++] << 24;
00640 upperArmMass |= ret[idx++] << 16;
00641 upperArmMass |= ret[idx++] << 8;
00642 upperArmMass |= ret[idx++] << 0;
00643
00644 foreArmMass = 0;
00645 foreArmMass |= ret[idx++] << 24;
00646 foreArmMass |= ret[idx++] << 16;
00647 foreArmMass |= ret[idx++] << 8;
00648 foreArmMass |= ret[idx++] << 0;
00649
00650 long compensationScale_fp = 0;
00651 compensationScale_fp = ret[idx++] << 24;
00652 compensationScale_fp |= ret[idx++] << 16;
00653 compensationScale_fp |= ret[idx++] << 8;
00654 compensationScale_fp |= ret[idx++] << 0;
00655 compensationScale = (float) ((float) compensationScale_fp) / 100000.0;
00656 }
00657
00658 itsSerial->flush();
00659 pthread_mutex_unlock(&itsSerialMutex);
00660 }