00001
00025 #include "puma_motor_driver/driver.h"
00026 #include "puma_motor_driver/gateway.h"
00027 #include "puma_motor_driver/message.h"
00028 #include "puma_motor_msgs/MultiStatus.h"
00029 #include "puma_motor_msgs/Status.h"
00030 #include "puma_motor_msgs/MultiFeedback.h"
00031 #include "puma_motor_msgs/Feedback.h"
00032
00033 #include <string>
00034 #include <ros/ros.h>
00035
00036 namespace puma_motor_driver
00037 {
00038
00039 Driver::Driver(Gateway& gateway, uint8_t device_number, std::string device_name)
00040 : gateway_(gateway), device_number_(device_number), device_name_(device_name),
00041 configured_(false), state_(0), control_mode_(puma_motor_msgs::Status::MODE_SPEED),
00042 gain_p_(1), gain_i_(0), gain_d_(0), encoder_cpr_(1), gear_ratio_(1)
00043 {
00044 }
00045
00046 void Driver::processMessage(const Message& received_msg)
00047 {
00048
00049 if (received_msg.getDeviceNumber() != device_number_) return;
00050
00051
00052 if (received_msg.len == 0) return;
00053
00054 StatusField* field = statusFieldForMessage(received_msg);
00055
00056
00057 if (!field) return;
00058
00059
00060 memcpy(field->data, received_msg.data, received_msg.len);
00061 field->received = true;
00062 }
00063
00064 void Driver::sendUint8(uint32_t id, uint8_t value)
00065 {
00066 Message msg;
00067 msg.id = id;
00068 msg.len = 1;
00069 memcpy(msg.data, &value, msg.len);
00070 gateway_.queue(msg);
00071 }
00072
00073 void Driver::sendUint16(uint32_t id, uint16_t value)
00074 {
00075 Message msg;
00076 msg.id = id;
00077 msg.len = 2;
00078 memcpy(msg.data, &value, msg.len);
00079 gateway_.queue(msg);
00080 }
00081
00082 void Driver::sendFixed8x8(uint32_t id, float value)
00083 {
00084 Message msg;
00085 msg.id = id;
00086 msg.len = 2;
00087 int16_t output_value = static_cast<int16_t>(static_cast<float>(1<<8) * value);
00088 memcpy(msg.data, &output_value, msg.len);
00089 gateway_.queue(msg);
00090 }
00091
00092 void Driver::sendFixed16x16(uint32_t id, double value)
00093 {
00094 Message msg;
00095 msg.id = id;
00096 msg.len = 4;
00097 int32_t output_value = static_cast<int32_t>(static_cast<double>((1<<16) * value));
00098 memcpy(msg.data, &output_value, msg.len);
00099 gateway_.queue(msg);
00100 }
00101
00102 bool Driver::verifyRaw16x16(uint8_t* received, double expected)
00103 {
00104 uint8_t data[4];
00105 int32_t output_value = static_cast<int32_t>(static_cast<double>((1<<16) * expected));
00106 memcpy(data, &output_value, 4);
00107 for (uint8_t i = 0; i < 4; i++)
00108 {
00109 if (*received != data[i])
00110 {
00111 return false;
00112 }
00113 received++;
00114 }
00115 return true;
00116 }
00117
00118 bool Driver::verifyRaw8x8(uint8_t* received, float expected)
00119 {
00120 uint8_t data[2];
00121 int32_t output_value = static_cast<int32_t>(static_cast<float>((1<<8) * expected));
00122 memcpy(data, &output_value, 2);
00123 for (uint8_t i = 0; i < 2; i++)
00124 {
00125 if (*received != data[i])
00126 {
00127 return false;
00128 }
00129 received++;
00130 }
00131 return true;
00132 }
00133
00134 void Driver::setEncoderCPR(uint16_t encoder_cpr)
00135 {
00136 encoder_cpr_ = encoder_cpr;
00137 }
00138
00139 void Driver::setGearRatio(float gear_ratio)
00140 {
00141 gear_ratio_ = gear_ratio;
00142 }
00143
00144 void Driver::commandDutyCycle(float cmd)
00145 {
00146 sendFixed8x8((LM_API_VOLT_SET | device_number_), cmd);
00147 }
00148
00149 void Driver::commandSpeed(double cmd)
00150 {
00151
00152 sendFixed16x16((LM_API_SPD_SET | device_number_), (cmd * ((60 * gear_ratio_) / (2 * M_PI))));
00153 }
00154
00155 void Driver::verifyParams()
00156 {
00157 switch (state_)
00158 {
00159 case 0:
00160 ROS_DEBUG("Dev: %i starting to verify parameters.", device_number_);
00161 state_++;
00162 break;
00163 case 1:
00164 if (lastPower() == 0)
00165 {
00166 state_++;
00167 ROS_DEBUG("Dev: %i cleared power flag.", device_number_);
00168 }
00169 else
00170 {
00171 gateway_.queue(Message(LM_API_STATUS_POWER | device_number_));
00172 }
00173 break;
00174 case 2:
00175 if (posEncoderRef() == LM_REF_ENCODER)
00176 {
00177 state_++;
00178 ROS_DEBUG("Dev: %i set position encoder reference.", device_number_);
00179 }
00180 else
00181 {
00182 gateway_.queue(Message(LM_API_POS_REF | device_number_));
00183 }
00184 break;
00185 case 3:
00186 if (spdEncoderRef() == LM_REF_QUAD_ENCODER)
00187 {
00188 state_++;
00189 ROS_DEBUG("Dev: %i set speed encoder reference.", device_number_);
00190 }
00191 else
00192 {
00193 gateway_.queue(Message(LM_API_SPD_REF | device_number_));
00194 }
00195 break;
00196 case 4:
00197 if (encoderCounts() == encoder_cpr_)
00198 {
00199 state_++;
00200 ROS_DEBUG("Dev: %i set encoder counts to %i.", device_number_, encoder_cpr_);
00201 }
00202 else
00203 {
00204 gateway_.queue(Message(LM_API_CFG_ENC_LINES | device_number_));
00205 }
00206 break;
00207 case 5:
00208 if (lastMode() == puma_motor_msgs::Status::MODE_SPEED)
00209 {
00210 state_++;
00211 ROS_DEBUG("Dev: %i entered a close-loop control mode.", device_number_);
00212 }
00213 else
00214 {
00215 gateway_.queue(Message(LM_API_STATUS_CMODE | device_number_));
00216 }
00217 break;
00218 case 6:
00219 if (lastMode() == control_mode_)
00220 {
00221 if (control_mode_ != puma_motor_msgs::Status::MODE_VOLTAGE)
00222 {
00223 state_++;
00224 ROS_DEBUG("Dev: %i was set to a close loop control mode.", device_number_);
00225 }
00226 else
00227 {
00228 state_ = 200;
00229 ROS_DEBUG("Dev: %i was set to voltage control mode.", device_number_);
00230 }
00231 }
00232 break;
00233 case 7:
00234 if (verifyRaw16x16(getRawP(), gain_p_))
00235 {
00236 state_++;
00237 ROS_DEBUG("Dev: %i P gain constant was set to %f and %f was requested.", device_number_, getP(), gain_p_);
00238 }
00239 else
00240 {
00241 switch (control_mode_)
00242 {
00243 case puma_motor_msgs::Status::MODE_CURRENT:
00244 gateway_.queue(Message(LM_API_ICTRL_PC | device_number_));
00245 break;
00246 case puma_motor_msgs::Status::MODE_POSITION:
00247 gateway_.queue(Message(LM_API_POS_PC | device_number_));
00248 break;
00249 case puma_motor_msgs::Status::MODE_SPEED:
00250 gateway_.queue(Message(LM_API_SPD_PC | device_number_));
00251 break;
00252 }
00253 }
00254 break;
00255 case 8:
00256 if (verifyRaw16x16(getRawI(), gain_i_))
00257 {
00258 state_++;
00259 ROS_DEBUG("Dev: %i I gain constant was set to %f and %f was requested.", device_number_, getI(), gain_i_);
00260 }
00261 else
00262 {
00263 switch (control_mode_)
00264 {
00265 case puma_motor_msgs::Status::MODE_CURRENT:
00266 gateway_.queue(Message(LM_API_ICTRL_IC | device_number_));
00267 break;
00268 case puma_motor_msgs::Status::MODE_POSITION:
00269 gateway_.queue(Message(LM_API_POS_IC | device_number_));
00270 break;
00271 case puma_motor_msgs::Status::MODE_SPEED:
00272 gateway_.queue(Message(LM_API_SPD_IC | device_number_));
00273 break;
00274 }
00275 }
00276 break;
00277 case 9:
00278 if (verifyRaw16x16(getRawD(), gain_d_))
00279 {
00280 state_ = 200;
00281 ROS_DEBUG("Dev: %i D gain constant was set to %f and %f was requested.", device_number_, getD(), gain_d_);
00282 }
00283 else
00284 {
00285 switch (control_mode_)
00286 {
00287 case puma_motor_msgs::Status::MODE_CURRENT:
00288 gateway_.queue(Message(LM_API_ICTRL_DC | device_number_));
00289 break;
00290 case puma_motor_msgs::Status::MODE_POSITION:
00291 gateway_.queue(Message(LM_API_POS_DC | device_number_));
00292 break;
00293 case puma_motor_msgs::Status::MODE_SPEED:
00294 gateway_.queue(Message(LM_API_SPD_DC | device_number_));
00295 break;
00296 }
00297 }
00298 break;
00299 }
00300 if (state_ == 200)
00301 {
00302 ROS_INFO("Dev: %i all parameters verified.", device_number_);
00303 configured_ = true;
00304 state_ = 255;
00305 }
00306 }
00307
00308 void Driver::configureParams()
00309 {
00310 switch (state_)
00311 {
00312 case 1:
00313 sendUint8((LM_API_STATUS_POWER | device_number_), 1);
00314 break;
00315 case 2:
00316 sendUint8((LM_API_POS_REF | device_number_), LM_REF_ENCODER);
00317 break;
00318 case 3:
00319 sendUint8((LM_API_SPD_REF | device_number_), LM_REF_QUAD_ENCODER);
00320 break;
00321 case 4:
00322
00323 sendUint16((LM_API_CFG_ENC_LINES | device_number_), encoder_cpr_);
00324 break;
00325 case 5:
00326 gateway_.queue(Message(LM_API_SPD_EN | device_number_));
00327 break;
00328 case 6:
00329 switch (control_mode_)
00330 {
00331 case puma_motor_msgs::Status::MODE_VOLTAGE:
00332 gateway_.queue(Message(LM_API_VOLT_EN | device_number_));
00333 break;
00334 case puma_motor_msgs::Status::MODE_CURRENT:
00335 gateway_.queue(Message(LM_API_ICTRL_EN | device_number_));
00336 break;
00337 case puma_motor_msgs::Status::MODE_POSITION:
00338 gateway_.queue(Message(LM_API_POS_EN | device_number_));
00339 break;
00340 case puma_motor_msgs::Status::MODE_SPEED:
00341 gateway_.queue(Message(LM_API_SPD_EN | device_number_));
00342 break;
00343 }
00344 break;
00345 case 7:
00346
00347 switch (control_mode_)
00348 {
00349 case puma_motor_msgs::Status::MODE_CURRENT:
00350 sendFixed16x16((LM_API_ICTRL_PC | device_number_), gain_p_);
00351 break;
00352 case puma_motor_msgs::Status::MODE_POSITION:
00353 sendFixed16x16((LM_API_POS_PC | device_number_), gain_p_);
00354 break;
00355 case puma_motor_msgs::Status::MODE_SPEED:
00356 sendFixed16x16((LM_API_SPD_PC | device_number_), gain_p_);
00357 break;
00358 }
00359 break;
00360 case 8:
00361
00362 switch (control_mode_)
00363 {
00364 case puma_motor_msgs::Status::MODE_CURRENT:
00365 sendFixed16x16((LM_API_ICTRL_IC | device_number_), gain_i_);
00366 break;
00367 case puma_motor_msgs::Status::MODE_POSITION:
00368 sendFixed16x16((LM_API_POS_IC | device_number_), gain_i_);
00369 break;
00370 case puma_motor_msgs::Status::MODE_SPEED:
00371 sendFixed16x16((LM_API_SPD_IC | device_number_), gain_i_);
00372 break;
00373 }
00374 break;
00375 case 9:
00376
00377 switch (control_mode_)
00378 {
00379 case puma_motor_msgs::Status::MODE_CURRENT:
00380 sendFixed16x16((LM_API_ICTRL_DC | device_number_), gain_d_);
00381 break;
00382 case puma_motor_msgs::Status::MODE_POSITION:
00383 sendFixed16x16((LM_API_POS_DC | device_number_), gain_d_);
00384 break;
00385 case puma_motor_msgs::Status::MODE_SPEED:
00386 sendFixed16x16((LM_API_SPD_DC | device_number_), gain_d_);
00387 break;
00388 }
00389 break;
00390 }
00391 }
00392
00393 bool Driver::isConfigured()
00394 {
00395 return configured_;
00396 }
00397
00398 void Driver::setGains(double p, double i, double d)
00399 {
00400 gain_p_ = p;
00401 gain_i_ = i;
00402 gain_d_ = d;
00403
00404 if (configured_)
00405 {
00406 updateGains();
00407 }
00408 }
00409
00410 void Driver::setMode(uint8_t mode)
00411 {
00412 if (mode == puma_motor_msgs::Status::MODE_VOLTAGE)
00413 {
00414 control_mode_ = mode;
00415 ROS_INFO("Dev: %i mode set to voltage control.", device_number_);
00416 if (configured_)
00417 {
00418 resetConfiguration();
00419 }
00420 }
00421 else
00422 {
00423 ROS_ERROR("Close loop modes need PID gains.");
00424 }
00425 }
00426
00427 void Driver::setMode(uint8_t mode, double p, double i, double d)
00428 {
00429 if (mode == puma_motor_msgs::Status::MODE_VOLTAGE)
00430 {
00431 control_mode_ = mode;
00432 ROS_WARN("Dev: %i mode set to voltage control but PID gains are not needed.", device_number_);
00433 if (configured_)
00434 {
00435 resetConfiguration();
00436 }
00437 }
00438 else
00439 {
00440 control_mode_ = mode;
00441 if (configured_)
00442 {
00443 resetConfiguration();
00444 }
00445 setGains(p, i, d);
00446 ROS_INFO("Dev: %i mode set to a closed-loop control with PID gains of P:%f, I:%f and D:%f.",
00447 device_number_, gain_p_, gain_i_, gain_d_);
00448 }
00449 }
00450
00451 void Driver::clearStatusCache()
00452 {
00453
00454
00455 memset(status_fields_, 0, sizeof(status_fields_));
00456 }
00457
00458 void Driver::requestStatusMessages()
00459 {
00460 gateway_.queue(Message(LM_API_STATUS_POWER | device_number_));
00461 }
00462
00463 void Driver::requestFeedbackMessages()
00464 {
00465 gateway_.queue(Message(LM_API_STATUS_VOLTOUT | device_number_));
00466 gateway_.queue(Message(LM_API_STATUS_CURRENT | device_number_));
00467 gateway_.queue(Message(LM_API_STATUS_POS | device_number_));
00468 gateway_.queue(Message(LM_API_STATUS_SPD | device_number_));
00469 gateway_.queue(Message(LM_API_SPD_SET | device_number_));
00470 }
00471 void Driver::requestFeedbackDutyCycle()
00472 {
00473 gateway_.queue(Message(LM_API_STATUS_VOLTOUT | device_number_));
00474 }
00475
00476 void Driver::requestFeedbackCurrent()
00477 {
00478 gateway_.queue(Message(LM_API_STATUS_CURRENT | device_number_));
00479 }
00480
00481 void Driver::requestFeedbackPosition()
00482 {
00483 gateway_.queue(Message(LM_API_STATUS_POS | device_number_));
00484 }
00485
00486 void Driver::requestFeedbackSpeed()
00487 {
00488 gateway_.queue(Message(LM_API_STATUS_SPD | device_number_));
00489 }
00490
00491 void Driver::requestFeedbackPowerState()
00492 {
00493 gateway_.queue(Message(LM_API_STATUS_POWER | device_number_));
00494 }
00495
00496 void Driver::requestFeedbackSetpoint()
00497 {
00498 switch (control_mode_)
00499 {
00500 case puma_motor_msgs::Status::MODE_CURRENT:
00501 gateway_.queue(Message(LM_API_ICTRL_SET | device_number_));
00502 break;
00503 case puma_motor_msgs::Status::MODE_POSITION:
00504 gateway_.queue(Message(LM_API_POS_SET | device_number_));
00505 break;
00506 case puma_motor_msgs::Status::MODE_SPEED:
00507 gateway_.queue(Message(LM_API_SPD_SET | device_number_));
00508 break;
00509 case puma_motor_msgs::Status::MODE_VOLTAGE:
00510 gateway_.queue(Message(LM_API_VOLT_SET | device_number_));
00511 break;
00512 };
00513 }
00514
00515 void Driver::resetConfiguration()
00516 {
00517 configured_ = false;
00518 state_ = 0;
00519 }
00520
00521 void Driver::updateGains()
00522 {
00523 configured_ = false;
00524 state_ = 7;
00525 }
00526
00527 float Driver::lastDutyCycle()
00528 {
00529 StatusField* field = statusFieldForMessage(Message(LM_API_STATUS_VOLTOUT));
00530 return (field->interpretFixed8x8() / 128.0);
00531 }
00532
00533 float Driver::lastBusVoltage()
00534 {
00535 StatusField* field = statusFieldForMessage(Message(LM_API_STATUS_VOLTBUS));
00536 return field->interpretFixed8x8();
00537 }
00538
00539 float Driver::lastCurrent()
00540 {
00541 StatusField* field = statusFieldForMessage(Message(LM_API_STATUS_CURRENT));
00542 return field->interpretFixed8x8();
00543 }
00544
00545 double Driver::lastPosition()
00546 {
00547 StatusField* field = statusFieldForMessage(Message(LM_API_STATUS_POS));
00548 return (field->interpretFixed16x16() * ((2 * M_PI) / gear_ratio_));
00549 }
00550
00551 double Driver::lastSpeed()
00552 {
00553 StatusField* field = statusFieldForMessage(Message(LM_API_STATUS_SPD));
00554 return (field->interpretFixed16x16() * ((2 * M_PI) / (gear_ratio_ * 60)));
00555 }
00556
00557 uint8_t Driver::lastFault()
00558 {
00559 StatusField* field = statusFieldForMessage(Message(LM_API_STATUS_FAULT));
00560 return field->data[0];
00561 }
00562
00563 uint8_t Driver::lastPower()
00564 {
00565 StatusField* field = statusFieldForMessage(Message(LM_API_STATUS_POWER));
00566 return field->data[0];
00567 }
00568
00569 uint8_t Driver::lastMode()
00570 {
00571 StatusField* field = statusFieldForMessage(Message(LM_API_STATUS_CMODE));
00572 return field->data[0];
00573 }
00574
00575 float Driver::lastOutVoltage()
00576 {
00577 StatusField* field = statusFieldForMessage(Message(LM_API_STATUS_VOUT));
00578 return field->interpretFixed8x8();
00579 }
00580
00581 float Driver::lastTemperature()
00582 {
00583 StatusField* field = statusFieldForMessage(Message(LM_API_STATUS_TEMP));
00584 return field->interpretFixed8x8();
00585 }
00586
00587 float Driver::lastAnalogInput()
00588 {
00589 StatusField* field = statusFieldForMessage(Message(CPR_API_STATUS_ANALOG));
00590 return field->interpretFixed8x8();
00591 }
00592
00593 double Driver::lastSetpoint()
00594 {
00595 switch (control_mode_)
00596 {
00597 case puma_motor_msgs::Status::MODE_CURRENT:
00598 return statusCurrentGet();
00599 break;
00600 case puma_motor_msgs::Status::MODE_POSITION:
00601 return statusPositionGet();
00602 break;
00603 case puma_motor_msgs::Status::MODE_SPEED:
00604 return statusSpeedGet();
00605 break;
00606 case puma_motor_msgs::Status::MODE_VOLTAGE:
00607 return statusDutyCycleGet();
00608 break;
00609 default:
00610 return 0;
00611 break;
00612 }
00613 }
00614 double Driver::statusSpeedGet()
00615 {
00616 StatusField* field = statusFieldForMessage(Message(LM_API_SPD_SET));
00617 return (field->interpretFixed16x16() * ((2 * M_PI) / (gear_ratio_ * 60)));
00618 }
00619
00620 float Driver::statusDutyCycleGet()
00621 {
00622 StatusField* field = statusFieldForMessage(Message(LM_API_VOLT_SET));
00623 return (field->interpretFixed8x8() / 128.0);
00624 }
00625
00626 float Driver::statusCurrentGet()
00627 {
00628 StatusField* field = statusFieldForMessage(Message(LM_API_ICTRL_SET));
00629 return field->interpretFixed8x8();
00630 }
00631 double Driver::statusPositionGet()
00632 {
00633 StatusField* field = statusFieldForMessage(Message(LM_API_POS_SET));
00634 return (field->interpretFixed16x16() * (( 2 * M_PI) / gear_ratio_));
00635 }
00636
00637 uint8_t Driver::posEncoderRef()
00638 {
00639 StatusField* field = statusFieldForMessage(Message(LM_API_POS_REF));
00640 return field->data[0];
00641 }
00642
00643 uint8_t Driver::spdEncoderRef()
00644 {
00645 StatusField* field = statusFieldForMessage(Message(LM_API_SPD_REF));
00646 return field->data[0];
00647 }
00648
00649 uint16_t Driver::encoderCounts()
00650 {
00651 StatusField* field = statusFieldForMessage(Message(LM_API_CFG_ENC_LINES));
00652 return (static_cast<uint16_t>(field->data[0]) | static_cast<uint16_t>(field->data[1] << 8));
00653 }
00654
00655 double Driver::getP()
00656 {
00657 StatusField* field;
00658 switch (control_mode_)
00659 {
00660 case puma_motor_msgs::Status::MODE_CURRENT:
00661 field = statusFieldForMessage(Message(LM_API_ICTRL_PC));
00662 break;
00663 case puma_motor_msgs::Status::MODE_POSITION:
00664 field = statusFieldForMessage(Message(LM_API_POS_PC));
00665 break;
00666 case puma_motor_msgs::Status::MODE_SPEED:
00667 field = statusFieldForMessage(Message(LM_API_SPD_PC));
00668 break;
00669 };
00670 return field->interpretFixed16x16();
00671 }
00672
00673 double Driver::getI()
00674 {
00675 StatusField* field;
00676 switch (control_mode_)
00677 {
00678 case puma_motor_msgs::Status::MODE_CURRENT:
00679 field = statusFieldForMessage(Message(LM_API_ICTRL_IC));
00680 break;
00681 case puma_motor_msgs::Status::MODE_POSITION:
00682 field = statusFieldForMessage(Message(LM_API_POS_IC));
00683 break;
00684 case puma_motor_msgs::Status::MODE_SPEED:
00685 field = statusFieldForMessage(Message(LM_API_SPD_IC));
00686 break;
00687 };
00688 return field->interpretFixed16x16();
00689 }
00690
00691 double Driver::getD()
00692 {
00693 StatusField* field;
00694 switch (control_mode_)
00695 {
00696 case puma_motor_msgs::Status::MODE_CURRENT:
00697 field = statusFieldForMessage(Message(LM_API_ICTRL_DC));
00698 break;
00699 case puma_motor_msgs::Status::MODE_POSITION:
00700 field = statusFieldForMessage(Message(LM_API_POS_DC));
00701 break;
00702 case puma_motor_msgs::Status::MODE_SPEED:
00703 field = statusFieldForMessage(Message(LM_API_SPD_DC));
00704 break;
00705 };
00706 return field->interpretFixed16x16();
00707 }
00708
00709 uint8_t* Driver::getRawP()
00710 {
00711 StatusField* field;
00712 switch (control_mode_)
00713 {
00714 case puma_motor_msgs::Status::MODE_CURRENT:
00715 field = statusFieldForMessage(Message(LM_API_ICTRL_PC));
00716 break;
00717 case puma_motor_msgs::Status::MODE_POSITION:
00718 field = statusFieldForMessage(Message(LM_API_POS_PC));
00719 break;
00720 case puma_motor_msgs::Status::MODE_SPEED:
00721 field = statusFieldForMessage(Message(LM_API_SPD_PC));
00722 break;
00723 };
00724 return field->data;
00725 }
00726
00727 uint8_t* Driver::getRawI()
00728 {
00729 StatusField* field;
00730 switch (control_mode_)
00731 {
00732 case puma_motor_msgs::Status::MODE_CURRENT:
00733 field = statusFieldForMessage(Message(LM_API_ICTRL_IC));
00734 break;
00735 case puma_motor_msgs::Status::MODE_POSITION:
00736 field = statusFieldForMessage(Message(LM_API_POS_IC));
00737 break;
00738 case puma_motor_msgs::Status::MODE_SPEED:
00739 field = statusFieldForMessage(Message(LM_API_SPD_IC));
00740 break;
00741 };
00742 return field->data;
00743 }
00744
00745 uint8_t* Driver::getRawD()
00746 {
00747 StatusField* field;
00748 switch (control_mode_)
00749 {
00750 case puma_motor_msgs::Status::MODE_CURRENT:
00751 field = statusFieldForMessage(Message(LM_API_ICTRL_DC));
00752 break;
00753 case puma_motor_msgs::Status::MODE_POSITION:
00754 field = statusFieldForMessage(Message(LM_API_POS_DC));
00755 break;
00756 case puma_motor_msgs::Status::MODE_SPEED:
00757 field = statusFieldForMessage(Message(LM_API_SPD_DC));
00758 break;
00759 };
00760 return field->data;
00761 }
00762 Driver::StatusField* Driver::statusFieldForMessage(const Message& msg)
00763 {
00764
00765 if ((msg.getApi() & CAN_MSGID_API_M) != CAN_API_MC_STATUS)
00766 {
00767 return NULL;
00768 }
00769
00770 uint32_t status_field_index = (msg.getApi() & CAN_MSGID_API_ID_M) >> CAN_MSGID_API_S;
00771 return &status_fields_[status_field_index];
00772 }
00773
00774 }