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 //Set the default gains 00020 00021 setControlParams(ScorbotInterface::Base, 00022 0.018, //pGain 00023 .00015, //iGain 00024 0.0000, //dGain 00025 200, //maxI 00026 1, //maxPWM 00027 0 //pwmOffset 00028 ); 00029 00030 setControlParams(ScorbotInterface::Shoulder, 00031 0.009, //pGain 00032 0.0004, //iGain 00033 0, //dGain 00034 200, //maxI 00035 1, //maxPWM 00036 0 //pwmOffset 00037 ); 00038 00039 setControlParams(ScorbotInterface::Elbow, 00040 0.015, //pGain 00041 0.0002, //iGain 00042 0, //dGain 00043 200, //maxI 00044 1, //maxPWM 00045 0 //pwmOffset 00046 ); 00047 00048 setControlParams(ScorbotInterface::Wrist1, 00049 0.010, //pGain 00050 0.0002, //iGain 00051 0, //dGain 00052 200, //maxI 00053 1, //maxPWM 00054 0 //pwmOffset 00055 ); 00056 00057 setControlParams(ScorbotInterface::Wrist2, 00058 0.015, //pGain 00059 0.0008, //iGain 00060 0, //dGain 00061 200, //maxI 00062 1, //maxPWM 00063 0 //pwmOffset 00064 ); 00065 00066 setControlParams(ScorbotInterface::Slider, 00067 0.0015, //pGain 00068 0.00011, //iGain 00069 0.00011, //dGain 00070 2000, //maxI 00071 1, //maxPWM 00072 0 //pwmOffset 00073 ); 00074 00075 //Set all desired joint positions to their current positions 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 // Check for success 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 // Check for success 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 // Check for success 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 // Check for success 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 // Check for success 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 // Check for success 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 //Reset all joints to 0 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 //Multiply all of our params by 100,000 to convert them to fixed point before we send them 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; //Number of bytes to follow 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 // Check for success 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 }