armadillo2_hardware_interface.cpp
Go to the documentation of this file.
00001 
00002 #include <robotican_hardware_interface/armadillo2_hardware_interface.h>
00003 
00004 //#define DEBUG_PRINTS
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         // connect and register the joint state interface
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         //pan tilt torso
00112       //  state_handles.push_back( hardware_interface::JointStateHandle("head_pan_joint", &pan_position, &pan_velocity, &pan_effort));
00113      //   jnt_state_interface.registerHandle(state_handles[state_handles.size()-1]);
00114       //  state_handles.push_back( hardware_interface::JointStateHandle("head_tilt_joint", &tilt_position, &tilt_velocity, &tilt_effort));
00115      //   jnt_state_interface.registerHandle(state_handles[state_handles.size()-1]);
00116        // state_handles.push_back( hardware_interface::JointStateHandle("torso_joint", &torso_position, &torso_velocity, &torso_effort));
00117         //jnt_state_interface.registerHandle(state_handles[state_handles.size()-1]);
00118 
00119         //wheels
00120 
00121        // state_handles.push_back( hardware_interface::JointStateHandle("left_wheel_joint", &left_wheel_position, &left_wheel_velocity, &left_wheel_effort));
00122        // jnt_state_interface.registerHandle(state_handles[state_handles.size()-1]);
00123         //state_handles.push_back( hardware_interface::JointStateHandle("right_wheel_joint", &right_wheel_position, &right_wheel_velocity, &right_wheel_effort));
00124        // jnt_state_interface.registerHandle(state_handles[state_handles.size()-1]);
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              //   ROS_WARN("posvel     id: %d      %s",motors[i].id,motors[i].joint_name.c_str());
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              //   ROS_WARN("pos     id: %d      %s",motors[i].id,motors[i].joint_name.c_str());
00140                 jnt_pos_interface.registerHandle(pos_handles[pos_handles.size()-1]);
00141 
00142             }
00143         }
00144 
00145         //pan tilt torso
00146    //     pos_handles.push_back( hardware_interface::JointHandle(jnt_state_interface.getHandle("head_pan_joint"), &pan_command_position));
00147 // jnt_pos_interface.registerHandle(pos_handles[pos_handles.size()-1]);
00148 //pos_handles.push_back( hardware_interface::JointHandle(jnt_state_interface.getHandle("head_tilt_joint"), &tilt_command_position));
00149 //jnt_pos_interface.registerHandle(pos_handles[pos_handles.size()-1]);
00150 //pos_handles.push_back( hardware_interface::JointHandle(jnt_state_interface.getHandle("torso_joint"), &torso_command_position));
00151 //jnt_pos_interface.registerHandle(pos_handles[pos_handles.size()-1]);
00152 
00153 
00154 //wheels
00155 //vel_handles.push_back( hardware_interface::JointHandle(jnt_state_interface.getHandle("left_wheel_joint"), &left_wheel_command_velocity));
00156 //jnt_vel_interface.registerHandle(vel_handles[vel_handles.size()-1]);
00157 //vel_handles.push_back( hardware_interface::JointHandle(jnt_state_interface.getHandle("right_wheel_joint"), &right_wheel_command_velocity));
00158 //jnt_vel_interface.registerHandle(vel_handles[vel_handles.size()-1]);
00159 
00160 
00161         registerInterface(&jnt_posvel_interface);
00162         registerInterface(&jnt_pos_interface);
00163         registerInterface(&jnt_vel_interface);
00164 
00165 
00166         //BUILD DYNAMIXEL MOTORS
00167 
00168         packetHandler = dynamixel::PacketHandler::getPacketHandler(PROTOCOL_VERSION2);
00169 // packetHandler1 = dynamixel::PacketHandler::getPacketHandler(PROTOCOL_VERSION1);
00170 
00171         portHandler = dynamixel::PortHandler::getPortHandler(device_name.c_str());
00172 
00173         // Open port
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     // DYNAMIXEL MOTORS FUNCTIONS
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 //if (motor.id==7) printf("[7] rad/s: %f\n",rads);
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);//TODO: Verify
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;             // Communication result
00309         uint8_t dxl_error = 0;                          // Dynamixel error
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             // ROS_ERROR("[ID:%03d] Ping TXRX error: ",id);
00317             //  packetHandler->printTxRxResult(dxl_comm_result);
00318             return false;
00319         }
00320         else if (dxl_error != 0)
00321         {
00322             // ROS_ERROR("[ID:%03d] Ping error: ",id);
00323             //  packetHandler->printRxPacketError(dxl_error);
00324             return false;
00325 
00326         }
00327         else {
00328             //  printf("[ID:%03d] ping Succeeded.  model: %d\n", motor.id,motor.model);
00329             return true;
00330         }
00331 
00332     }
00333 
00334 
00335     bool setTorque(struct motor &motor, bool onoff)
00336     {
00337 
00338 // if (motor.model == 30) return true;
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 //printf("addr: %d\n",addr);
00346  dxl_comm_result = packetHandler->write1ByteTxRx(portHandler, motor.id, addr, onoff, &dxl_error);
00347 
00348 
00349         if (dxl_comm_result != COMM_SUCCESS) {
00350             //packetHandler->printTxRxResult(dxl_comm_result);
00351             return false;
00352         }
00353         else if (dxl_error != 0) {
00354             // packetHandler->printRxPacketError(dxl_error);
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              //   if (motors[i].id==2) ROS_ERROR("command_velocity==0     pre_rad_s: %f",pre_rad_s);
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             //  if (motors[i].id==2) ROS_INFO("[2] command_velocity: %f     vel: %d",motors[i].command_velocity,(int)vel);
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             // ROS_ERROR("txPacket Error");
00399             // packetHandler->printTxRxResult(dxl_comm_result_);
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;                // addParam result
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            // if (motors[i].id==7||motors[i].id==8) {
00420             //     printf("[ID:%03d] write pos %f\n", motors[i].id,motors[i].command_position);
00421             //}
00422             //_sleep(100);
00423 
00424         }
00425 
00426         dxl_comm_result_ = GroupBulkWrite.txPacket();
00427 
00428         if (dxl_comm_result_ != COMM_SUCCESS)
00429         {
00430             // ROS_ERROR("txPacket Error");
00431             // packetHandler->printTxRxResult(dxl_comm_result_);
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;                // addParam result
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                 //ROS_ERROR("[ID:%03d] groupSyncRead addparam failed", i);
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             // ROS_ERROR("txRxPacket Error");
00465             //  packetHandler->printTxRxResult(dxl_comm_result);
00466             return false;
00467         }
00468 
00469         for (int i = 0; i<NUM_ARM_MOTORS; i++) {
00470             bool dxl_getdata_result = false; // GetParam result
00471             // Check if groupsyncread data of Dynamixels are available
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                 // ROS_ERROR("[ID:%03d] groupSyncRead isAvailable failed\n", i);
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 //puts("--err ok");
00491         return true;
00492     }
00493 
00494     bool bulk_read_pos() {
00495 
00496 //puts("--pos start");
00497         dynamixel::GroupBulkRead GroupBulkRead(portHandler, packetHandler);
00498         for (int i = 0; i<NUM_ARM_MOTORS; i++) {
00499             bool dxl_addparam_result = false;                // addParam result
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                // ROS_ERROR("[ID:%03d] groupSyncRead addparam failed", motors[i].id);
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             // ROS_ERROR("txRxPacket Error");
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; // GetParam result
00522             // Check if groupsyncread data of Dynamixels are available
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                //  ROS_ERROR("[ID:%03d] groupSyncRead isAvailable failed\n", motors[i].id);
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          //        ROS_INFO("[ID:%03d] Read bulk pos value: %f",motors[i].id,motors[i].position);
00547 
00548             }
00549         }
00550 //puts("--pos ok");
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;                // addParam result
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                 //ROS_ERROR("[ID:%03d] groupSyncRead addparam failed", i);
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             // ROS_ERROR("txRxPacket Error");
00576             //  packetHandler->printTxRxResult(dxl_comm_result);
00577             return false;
00578         }
00579 
00580         for (int i = 0; i<NUM_ARM_MOTORS; i++) {
00581             bool dxl_getdata_result = false; // GetParam result
00582             // Check if groupsyncread data of Dynamixels are available
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                 // ROS_ERROR("[ID:%03d] groupSyncRead isAvailable failed\n", i);
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 //ROS_INFO("[ID:%03d] Read bulk vel value: %f",motors[i].id,motors[i].velocity);
00598                 // ROS_INFO("[ID:%03d] Read sync pos value: %d",i,value);
00599 
00600             }
00601         }
00602 //puts("--vel ok");
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;                // addParam result
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                 //ROS_ERROR("[ID:%03d] groupSyncRead addparam failed", i);
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             // ROS_ERROR("txRxPacket Error");
00628             //  packetHandler->printTxRxResult(dxl_comm_result);
00629             return false;
00630         }
00631 
00632         for (int i = 0; i<NUM_ARM_MOTORS; i++) {
00633             bool dxl_getdata_result = false; // GetParam result
00634             // Check if groupsyncread data of Dynamixels are available
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                 // ROS_ERROR("[ID:%03d] groupSyncRead isAvailable failed\n", i);
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; //percentage -100 ~ 100 %
00653 
00654                 motors[i].effort=motors[i].torque_constant_a*motors[i].current+motors[i].torque_constant_b;
00655                 // ROS_INFO("[ID:%03d] Read sync pos value: %d",i,value);33,000 /  2,048
00656 //ROS_INFO("[ID:%03d] Read bulk load value: %f",motors[i].id,motors[i].effort);
00657 
00658             }
00659         }
00660 //puts("--load ok");
00661         return true;
00662     }
00663 
00664     ~Armadillo2Robot() {
00665         portHandler->closePort();
00666          _boardManager.disconnect();
00667         //  free(motors);
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             //ROS_INFO("Read OK");
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            // if (first) return;
00702         }
00703 
00704 
00705 
00706        // pan_position=pan_command_position;
00707        // tilt_position=tilt_command_position;
00708         //right_wheel_velocity=right_wheel_command_velocity;
00709         //left_wheel_velocity=left_wheel_command_velocity;
00710 
00711 
00712     }
00713 
00714     void write() {
00715 
00716          _boardManager.write();
00717         /* static float s = 1;
00718         for (int i = 0; i < NUM_ARM_MOTORS; i++) {
00719             motors[i].command_position+= 0.0005*s;
00720             if (motors[i].command_position > 0.1) s = -1;
00721             else if (motors[i].command_position < -0.1) s = 1;
00722         }
00723         */
00724 #ifdef DEBUG_PRINTS
00725         //  printf("command= %.3f\n", motors[0].command_position);
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             //ROS_INFO("Write OK");
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             // Load the basic specs of this motor type
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  //dynamixel::PacketHandler *packetHandler1;
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 //double pan_position,pan_velocity,pan_effort,pan_command_position;
00814 //double tilt_position,tilt_velocity,tilt_effort,tilt_command_position;
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 }


robotican_hardware_interface
Author(s):
autogenerated on Fri Oct 27 2017 03:02:48