00001
00002 #include <robotican_hardware_interface/armadillo2_hardware_interface.h>
00003
00004
00005
00006 class Armadillo2Robot : public hardware_interface::RobotHW
00007 {
00008 public:
00009
00010 robotican_hardware::RiCBoardManager _boardManager;
00011
00012 Armadillo2Robot(ros::NodeHandle &nh)
00013 {
00014
00015
00016 _boardManager.connect();
00017
00018 while (ros::ok() && _boardManager.getConnectState() != ConnectEnum::Connected) { ros::Rate(10).sleep(); }
00019 if(ros::ok()) {
00020 _boardManager.buildDevices();
00021 _boardManager.buildDevices(&jnt_state_interface,&jnt_pos_interface);
00022 _boardManager.buildDevices(&jnt_state_interface,&jnt_vel_interface);
00023 }
00024
00025 initSpecFile();
00026
00027 nh.param<std::string>("device", device_name, "/dev/USB2DYNAMIXEL");
00028 nh.param<int>("device_baudrate", device_baudrate, 1000000);
00029
00030 if(nh.hasParam("dynamixel_motors")) {
00031 XmlRpc::XmlRpcValue dynamixel_motors;
00032 nh.getParam("dynamixel_motors", dynamixel_motors);
00033 if(!dynamixel_motors.getType() == XmlRpc::XmlRpcValue::TypeArray) {
00034 ROS_ERROR("[%s]: Invalid/missing servo information on the param server", ros::this_node::getName().c_str());
00035 exit(-1);
00036 }
00037 else {
00038
00039 NUM_ARM_MOTORS = dynamixel_motors.size();
00040 for(int i = 0; i < NUM_ARM_MOTORS && ros::ok(); ++i) {
00041
00042
00043
00044 if(!dynamixel_motors[i].getType() == XmlRpc::XmlRpcValue::TypeStruct) {
00045 ROS_ERROR("[%s]: Invalid/Missing info-struct for servo index %d",ros::this_node::getName().c_str() ,i);
00046 exit(-1);
00047 }
00048 else {
00049
00050 struct motor m;
00051 m.model = 0;
00052 m.protocol_ver = 2.0;
00053 m.command_position = 0.0;
00054 m.command_velocity = 1.5;
00055 m.pre_command_velocity=0.01;
00056 m.first_read=false;
00057 m.torque=false;
00058
00059 if(!dynamixel_motors[i]["id"].getType() == XmlRpc::XmlRpcValue::TypeInt) {
00060 ROS_ERROR("[%s]: Invalid/Missing id for servo index %d", ros::this_node::getName().c_str(), i);
00061 exit(-1);
00062 }
00063 else {
00064 m.id = static_cast<int>(dynamixel_motors[i]["id"]);
00065 }
00066 if (!dynamixel_motors[i]["joint_name"].getType() == XmlRpc::XmlRpcValue::TypeString)
00067 {
00068 ROS_ERROR("[%s]: Invalid/Missing joint name for servo index %d, id: %d", ros::this_node::getName().c_str() ,i, m.id);
00069 exit(-1);
00070 }
00071 else {
00072 m.joint_name = static_cast<std::string>(dynamixel_motors[i]["joint_name"]);
00073 }
00074 if (!dynamixel_motors[i]["interface"].getType() == XmlRpc::XmlRpcValue::TypeString)
00075 {
00076 ROS_ERROR("[%s]: Invalid/Missing interface for servo index %d, id: %d", ros::this_node::getName().c_str() ,i, m.id);
00077 exit(-1);
00078 }
00079 else {
00080 m.interface = static_cast<std::string>(dynamixel_motors[i]["interface"]);
00081 }
00082 if (!dynamixel_motors[i]["protocol"].getType() == XmlRpc::XmlRpcValue::TypeInt)
00083 {
00084 ROS_ERROR("[%s]: Invalid/Missing protocol for servo index %d, id: %d", ros::this_node::getName().c_str() ,i, m.id);
00085 exit(-1);
00086 }
00087 else {
00088 m.protocol_ver = static_cast<int>(dynamixel_motors[i]["protocol"]);
00089 }
00090
00091 motors.push_back(m);
00092 }
00093
00094 }
00095
00096 }
00097 }
00098
00099
00100 first=true;
00101
00102
00103
00104
00105 for (int i=0;i<NUM_ARM_MOTORS;i++){
00106
00107 state_handles.push_back( hardware_interface::JointStateHandle(motors[i].joint_name, &motors[i].position, &motors[i].velocity, &motors[i].effort));
00108 jnt_state_interface.registerHandle(state_handles[i]);
00109 }
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 registerInterface(&jnt_state_interface);
00128
00129
00130 for (int i=0;i<NUM_ARM_MOTORS;i++){
00131 if (motors[i].interface=="PosVel") {
00132 posvel_handles.push_back( hardware_interface::PosVelJointHandle(jnt_state_interface.getHandle(motors[i].joint_name), &motors[i].command_position, &motors[i].command_velocity));
00133 jnt_posvel_interface.registerHandle(posvel_handles[posvel_handles.size()-1]);
00134
00135 }
00136 else if (motors[i].interface=="Pos") {
00137
00138 pos_handles.push_back( hardware_interface::JointHandle(jnt_state_interface.getHandle(motors[i].joint_name), &motors[i].command_position));
00139
00140 jnt_pos_interface.registerHandle(pos_handles[pos_handles.size()-1]);
00141
00142 }
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 registerInterface(&jnt_posvel_interface);
00162 registerInterface(&jnt_pos_interface);
00163 registerInterface(&jnt_vel_interface);
00164
00165
00166
00167
00168 packetHandler = dynamixel::PacketHandler::getPacketHandler(PROTOCOL_VERSION2);
00169
00170
00171 portHandler = dynamixel::PortHandler::getPortHandler(device_name.c_str());
00172
00173
00174 if (portHandler->openPort())
00175 {
00176 portHandler->setBaudRate(device_baudrate);
00177 ROS_INFO("Succeeded to open the port!");
00178 ROS_INFO(" - Device Name : %s", device_name.c_str());
00179 ROS_INFO(" - Baudrate : %d", portHandler->getBaudRate());
00180 }
00181 else
00182 {
00183 ROS_ERROR("Failed to open the port! [%s]\n", device_name.c_str());
00184 ros::shutdown();
00185 }
00186
00187
00188 ROS_INFO("Pinging motors...");
00189 for (int i = 0; i<NUM_ARM_MOTORS; i++) {
00190 int err_cnt=0;
00191 while ((!ping(motors[i]) || motors[i].model == 0)&&ros::ok()) {
00192 ROS_ERROR("[ID:%03d] ping error",motors[i].id);
00193 ros::Rate(5).sleep();
00194 if(err_cnt++==5) {
00195 ROS_ERROR("[ID:%03d] too many ping errors, shuting down",motors[i].id);
00196 ros::shutdown();
00197 exit(-1);
00198 }
00199 }
00200 #ifdef DEBUG_PRINTS
00201 printf("[ID:%03d] Ping OK, model: %d\n", motors[i].id, motors[i].model);
00202 #endif
00203
00204 bool success = _modelSpec.find(motors[i].model) != _modelSpec.end();
00205 if (success) {
00206 motors[i].cpr=_modelSpec[motors[i].model].cpr;
00207 motors[i].rpm_scale_factor=_modelSpec[motors[i].model].rpm_scale_factor;
00208 motors[i].torque_constant_a=_modelSpec[motors[i].model].torque_constant_a;
00209 motors[i].torque_constant_b=_modelSpec[motors[i].model].torque_constant_b;
00210 }
00211
00212 }
00213 if (!ros::ok()) ros::shutdown();
00214
00215 ROS_INFO("Enabling motors torque...");
00216 for (int i = 0; i<NUM_ARM_MOTORS; i++) {
00217 int err_cnt=0;
00218 while (!setTorque(motors[i], true) && ros::ok()) {
00219 ROS_ERROR("[ID:%03d] setTorque error",motors[i].id);
00220 ros::Rate(5).sleep();
00221 if(err_cnt++==5) {
00222 ROS_ERROR("[ID:%03d] too many setTorque errors, shuting down",motors[i].id);
00223 ros::shutdown();
00224 exit(-1);
00225 }
00226 }
00227 #ifdef DEBUG_PRINTS
00228 printf("[ID:%03d] Torque ON\n", i);
00229 #endif
00230 motors[i].torque = true;
00231 }
00232
00233 if (!ros::ok()) ros::shutdown();
00234
00235 ROS_INFO("Armadillo2 Hardware Interface loop launched successfully");
00236
00237 _time = ros::Time::now();
00238
00239 }
00240
00241
00242 double ticks2rads(int32_t ticks, struct motor &motor) {
00243 if (motor.protocol_ver == 2.0) {
00244
00245 if (motor.model==1040) {
00246 const double FromTicks = 1.0 / (motor.cpr / 2.0);
00247 return static_cast<double>(M_PI-(ticks) * FromTicks * M_PI);
00248 }
00249 else if (motor.model==30) {
00250 double cprDev2 = motor.cpr / 2.0f;
00251 return (static_cast<double>(ticks) - cprDev2) * M_PI / cprDev2;
00252 }
00253 else {
00254 const double FromTicks = 1.0 / (motor.cpr / 2.0);
00255 return static_cast<double>((ticks) * FromTicks * M_PI);
00256 }
00257 }
00258 else {
00259 double cprDev2 = motor.cpr / 2.0f;
00260 return (static_cast<double>(ticks) - cprDev2) * M_PI / cprDev2;
00261 }
00262 }
00263
00264 int32_t rads2ticks(double rads, struct motor &motor) {
00265
00266 if (motor.protocol_ver == 2.0) {
00267 if (motor.model==1040) {
00268 return static_cast<int32_t>(round((-rads *180.0/ M_PI+180.0)/ 0.088));
00269 }
00270 else if (motor.model==30) {
00271 double cprDev2 = motor.cpr / 2.0f;
00272 return static_cast<int32_t>(round(cprDev2 + (rads * cprDev2 / M_PI)));
00273 }
00274 else {
00275 double cprDev2 = motor.cpr / 2.0f;
00276 return static_cast<int32_t>(round((rads / M_PI) * cprDev2));
00277 }
00278 }
00279 else {
00280 double cprDev2 = motor.cpr / 2.0f;
00281 return static_cast<int32_t>(round(cprDev2 + (rads * cprDev2 / M_PI)));
00282 }
00283 }
00284
00285 int32_t rad_s2ticks_s(double rads, struct motor &motor) {
00286
00287 if (motor.protocol_ver == 2.0)
00288 return static_cast<int32_t >(rads / 2.0 / M_PI * 60.0 / motor.rpm_scale_factor);
00289
00290 else {
00291
00292 return static_cast<int32_t >(83.49f * (rads)-0.564f);
00293 }
00294
00295 }
00296
00297 double ticks_s2rad_s(int32_t ticks, struct motor &motor) {
00298 if (motor.protocol_ver == 2.0) {
00299 return ((double)ticks) * 2.0 * M_PI / 60.0 / motor.rpm_scale_factor;
00300 }
00301 else {
00302 return (100.0f / 8349.0f) * ((double)ticks) + (94.0f / 13915.0f);
00303 }
00304 }
00305
00306 bool ping(struct motor &motor) {
00307
00308 int dxl_comm_result = COMM_TX_FAIL;
00309 uint8_t dxl_error = 0;
00310
00311
00312
00313 dxl_comm_result = packetHandler->ping(portHandler, motor.id, &(motor.model), &dxl_error);
00314 if (dxl_comm_result != COMM_SUCCESS)
00315 {
00316
00317
00318 return false;
00319 }
00320 else if (dxl_error != 0)
00321 {
00322
00323
00324 return false;
00325
00326 }
00327 else {
00328
00329 return true;
00330 }
00331
00332 }
00333
00334
00335 bool setTorque(struct motor &motor, bool onoff)
00336 {
00337
00338
00339 uint8_t dxl_error = 0;
00340 int dxl_comm_result = COMM_TX_FAIL;
00341 uint16_t addr = ADDR_PRO_TORQUE_ENABLE;
00342 if (motor.model == 1040) addr = ADDR_XH_TORQUE_ENABLE;
00343 else if (motor.model == 30) addr = ADDR_MX_TORQUE_ENABLE;
00344
00345
00346 dxl_comm_result = packetHandler->write1ByteTxRx(portHandler, motor.id, addr, onoff, &dxl_error);
00347
00348
00349 if (dxl_comm_result != COMM_SUCCESS) {
00350
00351 return false;
00352 }
00353 else if (dxl_error != 0) {
00354
00355 return false;
00356 }
00357 else {
00358 return true;
00359 }
00360 }
00361
00362 bool bulk_write() {
00363
00364
00365 int8_t dxl_comm_result_ = 0;
00366
00367
00368 dynamixel::GroupBulkWrite GroupBulkWrite(portHandler, packetHandler);
00369
00370
00371 for (int i = 0; i < NUM_ARM_MOTORS; i++) {
00372 if (motors[i].first_read==false) continue;
00373 bool dxl_addparam_result = false;
00374 uint16_t addr = ADDR_PRO_GOAL_SPEED;
00375 if (motors[i].model == 1040) addr = ADDR_XH_PROFILE_VELOCITY;
00376 else if (motors[i].model == 30) addr = ADDR_MX_PROFILE_VELOCITY;
00377 if (motors[i].command_velocity==0) {
00378
00379 motors[i].command_velocity= motors[i].pre_command_velocity;
00380
00381 }
00382
00383 motors[i].pre_command_velocity=motors[i].command_velocity;
00384 int32_t vel = rad_s2ticks_s(motors[i].command_velocity, motors[i]);
00385
00386 dxl_addparam_result = GroupBulkWrite.addParam(motors[i].id, addr, 4, (uint8_t*)&vel);
00387 if (dxl_addparam_result != true)
00388 {
00389 printf("[ID:%03d] 2GroupBulkWrite addparam failed", motors[i].id);
00390 return false;
00391
00392 }
00393 }
00394 dxl_comm_result_ = GroupBulkWrite.txPacket();
00395
00396 if (dxl_comm_result_ != COMM_SUCCESS)
00397 {
00398
00399
00400 return false;
00401 }
00402
00403 GroupBulkWrite.clearParam();
00404
00405
00406 for (int i = 0; i<NUM_ARM_MOTORS; i++) {
00407 if (motors[i].first_read==false) continue;
00408 bool dxl_addparam_result = false;
00409 uint16_t addr = ADDR_PRO_GOAL_POSITION;
00410 if (motors[i].model == 1040) addr = ADDR_XH_GOAL_POSITION;
00411 else if (motors[i].model == 30) addr = ADDR_MX_GOAL_POSITION;
00412 int32_t pos = rads2ticks(motors[i].command_position, motors[i]);
00413 dxl_addparam_result = GroupBulkWrite.addParam(motors[i].id, addr, 4, (uint8_t*)&pos);
00414 if (dxl_addparam_result != true)
00415 {
00416 printf("[ID:%03d] 1GroupBulkWrite addparam failed", motors[i].id);
00417 return false;
00418 }
00419
00420
00421
00422
00423
00424 }
00425
00426 dxl_comm_result_ = GroupBulkWrite.txPacket();
00427
00428 if (dxl_comm_result_ != COMM_SUCCESS)
00429 {
00430
00431
00432 return false;
00433 }
00434
00435 GroupBulkWrite.clearParam();
00436
00437
00438
00439 return true;
00440
00441 }
00442
00443 bool bulk_read_err() {
00444
00445
00446 dynamixel::GroupBulkRead GroupBulkRead(portHandler, packetHandler);
00447 for (int i = 0; i<NUM_ARM_MOTORS; i++) {
00448 bool dxl_addparam_result = false;
00449 uint16_t addr = ADDR_PRO_HARDWARE_ERROR;
00450 if (motors[i].model == 1040) addr = ADDR_XH_HARDWARE_ERROR;
00451 else if (motors[i].model == 30) addr = ADDR_MX_HARDWARE_ERROR;
00452 dxl_addparam_result = GroupBulkRead.addParam(motors[i].id, addr, 1);
00453 if (dxl_addparam_result != true)
00454 {
00455
00456 return false;
00457 }
00458 }
00459
00460 int dxl_comm_result = COMM_TX_FAIL;
00461 dxl_comm_result = GroupBulkRead.txRxPacket();
00462 if (dxl_comm_result != COMM_SUCCESS)
00463 {
00464
00465
00466 return false;
00467 }
00468
00469 for (int i = 0; i<NUM_ARM_MOTORS; i++) {
00470 bool dxl_getdata_result = false;
00471
00472 uint16_t addr = ADDR_PRO_HARDWARE_ERROR;
00473 if (motors[i].model == 1040) addr = ADDR_XH_HARDWARE_ERROR;
00474 else if (motors[i].model == 30) addr = ADDR_MX_HARDWARE_ERROR;
00475 dxl_getdata_result = GroupBulkRead.isAvailable(motors[i].id, addr, 1);
00476 if (dxl_getdata_result != true)
00477 {
00478
00479 return false;
00480 }
00481 else {
00482 uint16_t addr = ADDR_PRO_HARDWARE_ERROR;
00483 if (motors[i].model == 1040) addr = ADDR_XH_HARDWARE_ERROR;
00484 else if (motors[i].model == 30) addr = ADDR_MX_HARDWARE_ERROR;
00485 motors[i].error = GroupBulkRead.getData(motors[i].id, addr, 1);
00486 if (motors[i].error!=0) ROS_ERROR("[ID:%03d] HARDWARE ERROR: %d",motors[i].id,motors[i].error);
00487
00488 }
00489 }
00490
00491 return true;
00492 }
00493
00494 bool bulk_read_pos() {
00495
00496
00497 dynamixel::GroupBulkRead GroupBulkRead(portHandler, packetHandler);
00498 for (int i = 0; i<NUM_ARM_MOTORS; i++) {
00499 bool dxl_addparam_result = false;
00500 uint16_t addr = ADDR_PRO_PRESENT_POSITION;
00501 if (motors[i].model == 1040) addr = ADDR_XH_PRESENT_POSITION;
00502 else if (motors[i].model == 30) addr = ADDR_MX_PRESENT_POSITION;
00503 dxl_addparam_result = GroupBulkRead.addParam(motors[i].id, addr, 4);
00504 if (dxl_addparam_result != true)
00505 {
00506
00507 return false;
00508 }
00509 }
00510
00511 int dxl_comm_result = COMM_TX_FAIL;
00512 dxl_comm_result = GroupBulkRead.txRxPacket();
00513 if (dxl_comm_result != COMM_SUCCESS)
00514 {
00515
00516 packetHandler->printTxRxResult(dxl_comm_result);
00517 return false;
00518 }
00519
00520 for (int i = 0; i<NUM_ARM_MOTORS; i++) {
00521 bool dxl_getdata_result = false;
00522
00523 uint16_t addr = ADDR_PRO_PRESENT_POSITION;
00524 if (motors[i].model == 1040) addr = ADDR_XH_PRESENT_POSITION;
00525 else if (motors[i].model == 30) addr = ADDR_MX_PRESENT_POSITION;
00526 dxl_getdata_result = GroupBulkRead.isAvailable(motors[i].id, addr, 4);
00527 if (dxl_getdata_result != true)
00528 {
00529
00530 return false;
00531 }
00532 else {
00533 uint16_t addr = ADDR_PRO_PRESENT_POSITION;
00534 if (motors[i].model == 1040) addr = ADDR_XH_PRESENT_POSITION;
00535 else if (motors[i].model == 30) addr = ADDR_MX_PRESENT_POSITION;
00536 motors[i].position = ticks2rads(GroupBulkRead.getData(motors[i].id, addr, 4), motors[i]);
00537 if (motors[i].first_read==false) {
00538 motors[i].first_read=true;
00539 motors[i].command_position = motors[i].position;
00540
00541 if (motors[i].joint_name == "head_pan_joint" || motors[i].joint_name == "head_tilt_joint") {
00542 motors[i].command_position=0;
00543 ROS_WARN("Centering %s",motors[i].joint_name.c_str());
00544 }
00545 }
00546
00547
00548 }
00549 }
00550
00551 return true;
00552 }
00553
00554 bool bulk_read_vel() {
00555
00556
00557 dynamixel::GroupBulkRead GroupBulkRead(portHandler, packetHandler);
00558 for (int i = 0; i<NUM_ARM_MOTORS; i++) {
00559 bool dxl_addparam_result = false;
00560 uint16_t addr = ADDR_PRO_PRESENT_SPEED;
00561 if (motors[i].model == 1040) addr = ADDR_XH_PRESENT_SPEED;
00562 else if (motors[i].model == 30) addr = ADDR_MX_PRESENT_SPEED;
00563 dxl_addparam_result = GroupBulkRead.addParam(motors[i].id, addr, 4);
00564 if (dxl_addparam_result != true)
00565 {
00566
00567 return false;
00568 }
00569 }
00570
00571 int dxl_comm_result = COMM_TX_FAIL;
00572 dxl_comm_result = GroupBulkRead.txRxPacket();
00573 if (dxl_comm_result != COMM_SUCCESS)
00574 {
00575
00576
00577 return false;
00578 }
00579
00580 for (int i = 0; i<NUM_ARM_MOTORS; i++) {
00581 bool dxl_getdata_result = false;
00582
00583 uint16_t addr = ADDR_PRO_PRESENT_SPEED;
00584 if (motors[i].model == 1040) addr = ADDR_XH_PRESENT_SPEED;
00585 else if (motors[i].model == 30) addr = ADDR_MX_PRESENT_SPEED;
00586 dxl_getdata_result = GroupBulkRead.isAvailable(motors[i].id, addr, 4);
00587 if (dxl_getdata_result != true)
00588 {
00589
00590 return false;
00591 }
00592 else {
00593 uint16_t addr = ADDR_PRO_PRESENT_SPEED;
00594 if (motors[i].model == 1040) addr = ADDR_XH_PRESENT_SPEED;
00595 else if (motors[i].model == 30) addr = ADDR_MX_PRESENT_SPEED;
00596 motors[i].velocity = ticks_s2rad_s(GroupBulkRead.getData(motors[i].id, addr, 4), motors[i]);
00597
00598
00599
00600 }
00601 }
00602
00603 return true;
00604 }
00605
00606 bool bulk_read_load() {
00607
00608
00609 dynamixel::GroupBulkRead GroupBulkRead(portHandler, packetHandler);
00610 for (int i = 0; i<NUM_ARM_MOTORS; i++) {
00611 bool dxl_addparam_result = false;
00612 uint16_t addr = ADDR_PRO_PRESENT_CURRENT;
00613 if (motors[i].model == 1040) addr = ADDR_XH_PRESENT_CURRENT;
00614 else if (motors[i].model == 30) addr = ADDR_MX_PRESENT_LOAD;
00615 dxl_addparam_result = GroupBulkRead.addParam(motors[i].id, addr, 2);
00616 if (dxl_addparam_result != true)
00617 {
00618
00619 return false;
00620 }
00621 }
00622
00623 int dxl_comm_result = COMM_TX_FAIL;
00624 dxl_comm_result = GroupBulkRead.txRxPacket();
00625 if (dxl_comm_result != COMM_SUCCESS)
00626 {
00627
00628
00629 return false;
00630 }
00631
00632 for (int i = 0; i<NUM_ARM_MOTORS; i++) {
00633 bool dxl_getdata_result = false;
00634
00635 uint16_t addr = ADDR_PRO_PRESENT_CURRENT;
00636 if (motors[i].model == 1040) addr = ADDR_XH_PRESENT_CURRENT;
00637 else if (motors[i].model == 30) addr = ADDR_MX_PRESENT_LOAD;
00638 dxl_getdata_result = GroupBulkRead.isAvailable(motors[i].id, addr, 2);
00639 if (dxl_getdata_result != true)
00640 {
00641
00642 return false;
00643 }
00644 else {
00645 uint16_t addr = ADDR_PRO_PRESENT_CURRENT;
00646 if (motors[i].model == 1040) addr = ADDR_XH_PRESENT_CURRENT;
00647 else if (motors[i].model == 30) addr = ADDR_MX_PRESENT_LOAD;
00648 motors[i].current = (int16_t)GroupBulkRead.getData(motors[i].id, addr, 2) ;
00649 if (motors[i].model == 53768 || motors[i].model == 54024) motors[i].current *= 33000.0 / 2048.0 / 1000.0;
00650 else if (motors[i].model == 51200) motors[i].current *= 8250.0 / 2048.0 / 1000.0;
00651 else if (motors[i].model == 1040) motors[i].current *= 2.69/1000.0;
00652 else if (motors[i].model == 30) motors[i].current *= 0.1;
00653
00654 motors[i].effort=motors[i].torque_constant_a*motors[i].current+motors[i].torque_constant_b;
00655
00656
00657
00658 }
00659 }
00660
00661 return true;
00662 }
00663
00664 ~Armadillo2Robot() {
00665 portHandler->closePort();
00666 _boardManager.disconnect();
00667
00668 }
00669
00670 void read() {
00671 bool read_ok = bulk_read_pos() && bulk_read_vel() && bulk_read_load() && bulk_read_err();
00672 if (read_ok) {
00673 #ifdef DEBUG_PRINTS
00674
00675 printf("POS: ");
00676 for (int i = 0; i<NUM_ARM_MOTORS; i++) {
00677 printf("%.3f, ", motors[i].position);
00678 }
00679 puts("");
00680 printf("VEL: ");
00681 for (int i = 0; i<NUM_ARM_MOTORS; i++) {
00682 printf("%.3f, ", motors[i].velocity);
00683 }
00684 puts("");
00685 printf("EFF: ");
00686 for (int i = 0; i<NUM_ARM_MOTORS; i++) {
00687 printf("%.3f, ", motors[i].effort);
00688 }
00689 puts("");
00690 printf("ERR: ");
00691 for (int i = 0; i<NUM_ARM_MOTORS; i++) {
00692 printf("%d, ", motors[i].error);
00693 }
00694 puts("");
00695 #endif
00696 }
00697 else {
00698
00699 ROS_ERROR("Read error");
00700
00701
00702 }
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712 }
00713
00714 void write() {
00715
00716 _boardManager.write();
00717
00718
00719
00720
00721
00722
00723
00724 #ifdef DEBUG_PRINTS
00725
00726 printf("DIF: ");
00727 for (int i = 0; i<NUM_ARM_MOTORS; i++) {
00728 printf("%.3f, ", motors[i].command_position-motors[i].position);
00729 }
00730 puts("");
00731 #endif
00732
00733 bool write_ok = bulk_write();
00734 if (write_ok) {
00735
00736 }
00737 else ROS_ERROR("Write error");
00738
00739 }
00740 ros::Time getTime() {
00741 return ros::Time::now();
00742 }
00743
00744 ros::Duration getPeriod() {
00745 ros::Time now = ros::Time::now();
00746 ros::Duration period = now - _time;
00747 _time = now;
00748 return period;
00749 }
00750
00751
00752 void initSpecFile() {
00753 std::string path = ros::package::getPath("robotican_hardware_interface");
00754 path += "/config/motor_data.yaml";
00755 YAML::Node doc;
00756
00757 #ifdef HAVE_NEW_YAMLCPP
00758 doc = YAML::LoadFile(path);
00759 #else
00760 ifstream fin(path.c_str());
00761 YAML::Parser parser(fin);
00762 parser.GetNextDocument(doc);
00763 #endif
00764 for (int i = 0; i < doc.size(); i++)
00765 {
00766 dynamixel_spec spec;
00767
00768
00769 doc[i]["name"] >> spec.name;
00770 doc[i]["model_number"] >> spec.model_number;
00771 doc[i]["cpr"] >> spec.cpr;
00772 doc[i]["rpm_scale_factor"] >> spec.rpm_scale_factor;
00773 doc[i]["torque_constant_a"] >> spec.torque_constant_a;
00774 doc[i]["torque_constant_b"] >> spec.torque_constant_b;
00775
00776
00777 _modelSpec[spec.model_number] = spec;
00778 }
00779
00780 }
00781
00782
00783 private:
00784
00785
00786
00787
00788
00789 bool first;
00790 ros::Time _time;
00791
00792 hardware_interface::JointStateInterface jnt_state_interface;
00793 hardware_interface::PosVelJointInterface jnt_posvel_interface;
00794 hardware_interface::PositionJointInterface jnt_pos_interface;
00795 hardware_interface::VelocityJointInterface jnt_vel_interface;
00796
00797 dynamixel::PacketHandler *packetHandler;
00798
00799 dynamixel::PortHandler *portHandler;
00800 std::vector<struct motor> motors;
00801 std::vector<hardware_interface::JointStateHandle> state_handles;
00802 std::vector<hardware_interface::PosVelJointHandle> posvel_handles;
00803 std::vector<hardware_interface::JointHandle> pos_handles,vel_handles;
00804
00805
00806 std::map<uint16_t, dynamixel_spec> _modelSpec;
00807 int NUM_ARM_MOTORS;
00808
00809 std::string device_name;
00810 int device_baudrate;
00811
00812
00813
00814
00815
00816 };
00817
00818 main(int argc, char **argv)
00819 {
00820 ros::init(argc, argv, "armadillo2_hardware_interface_node");
00821 ros::NodeHandle nodeHandle;
00822 Armadillo2Robot robot(nodeHandle);
00823 controller_manager::ControllerManager cm(&robot);
00824 ros::AsyncSpinner asyncSpinner(2);
00825 asyncSpinner.start();
00826 ros::Rate loop(100);
00827 while (ros::ok()) {
00828 robot.read();
00829 cm.update(robot.getTime(), robot.getPeriod());
00830 loop.sleep();
00831 robot.write();
00832 loop.sleep();
00833 }
00834 }