00001
00027 #include <ros/ros.h>
00028
00029 #include "sr_hand/hand/real_shadowhand.h"
00030
00031 #include <robot/config.h>
00032 #include <robot/robot.h>
00033 #include <robot/hand_protocol.h>
00034 #include <robot/hand.h>
00035 #ifdef FINGER
00036 #define LAST_HAND_JOINT NUM_FINGER_JOINTS
00037 #else
00038 #define LAST_HAND_JOINT START_OF_ARM
00039 #endif
00040
00041 namespace shadowrobot
00042 {
00043 RealShadowhand::RealShadowhand() :
00044 SRArticulatedRobot()
00045 {
00046
00047 if( robot_init() < 0 )
00048 {
00049 ROS_FATAL("Robot interface broken\n");
00050 ROS_BREAK();
00051 }
00052
00053
00054 if( hand_init() < 0 )
00055 {
00056 ROS_FATAL("Hand interface broken\n");
00057 ROS_BREAK();
00058 }
00059
00060 initializeMap();
00061
00062 self_test = boost::shared_ptr<self_test::TestRunner>(new self_test::TestRunner());
00063
00064 self_test->add("Pretest", this, &RealShadowhand::pretest);
00065 self_test->add("Number of messages Received", this, &RealShadowhand::test_messages);
00066 self_test->add("Posttest", this, &RealShadowhand::posttest);
00067 }
00068
00069 RealShadowhand::~RealShadowhand()
00070 {
00071 }
00072
00073 void RealShadowhand::initializeMap()
00074 {
00075 joints_map_mutex.lock();
00076 parameters_map_mutex.lock();
00077
00078 JointData tmpData;
00079
00080 tmpData.position = 0.0;
00081 tmpData.target = 0.0;
00082 tmpData.temperature = 0.0;
00083 tmpData.current = 0.0;
00084 tmpData.force = 0.0;
00085 tmpData.flags = "";
00086
00087 for( unsigned int i = 0; i < LAST_HAND_JOINT; i++ )
00088 {
00089 std::string name = hand_joints[i].joint_name;
00090 tmpData.jointIndex = i;
00091
00092 joints_map[name] = tmpData;
00093
00094 ROS_DEBUG("NAME[%d]: %s ", i, name.c_str());
00095 }
00096
00097 parameters_map["d"] = PARAM_d;
00098 parameters_map["i"] = PARAM_i;
00099 parameters_map["p"] = PARAM_p;
00100 parameters_map["target"] = PARAM_target;
00101 parameters_map["sensor"] = PARAM_sensor;
00102
00103 parameters_map["valve"] = PARAM_valve;
00104 parameters_map["dead"] = PARAM_deadband;
00105 parameters_map["deadband"] = PARAM_deadband;
00106 parameters_map["imax"] = PARAM_imax;
00107 parameters_map["offset"] = PARAM_output_offset;
00108 parameters_map["shift"] = PARAM_shift;
00109 parameters_map["max"] = PARAM_output_max;
00110
00112 parameters_map["motor_maxforce"] = PARAM_motor_maxforce;
00113 parameters_map["motor_safeforce"] = PARAM_motor_safeforce;
00114
00115 parameters_map["force_p"] = PARAM_force_p;
00116 parameters_map["force_i"] = PARAM_force_i;
00117 parameters_map["force_d"] = PARAM_force_d;
00118
00119 parameters_map["force_imax"] = PARAM_force_imax;
00120 parameters_map["force_out_shift"] = PARAM_force_out_shift;
00121 parameters_map["force_deadband"] = PARAM_force_deadband;
00122 parameters_map["force_offset"] = PARAM_force_offset;
00123
00124 parameters_map["sensor_imax"] = PARAM_sensor_imax;
00125 parameters_map["sensor_out_shift"] = PARAM_sensor_out_shift;
00126 parameters_map["sensor_deadband"] = PARAM_sensor_deadband;
00127 parameters_map["sensor_offset"] = PARAM_sensor_offset;
00128 parameters_map["max_temp"] = PARAM_max_temperature;
00129 parameters_map["max_temperature"] = PARAM_max_temperature;
00130 parameters_map["max_current"] = PARAM_max_current;
00131
00132 parameters_map_mutex.unlock();
00133 joints_map_mutex.unlock();
00134 }
00135
00136 short RealShadowhand::sendupdate( std::string joint_name, double target )
00137 {
00138 joints_map_mutex.lock();
00139
00140
00141 JointsMap::iterator iter = joints_map.find(joint_name);
00142
00143 if( iter != joints_map.end() )
00144 {
00145 JointData tmpData = joints_map.find(joint_name)->second;
00146 int index_hand_joints = tmpData.jointIndex;
00147
00148
00149 if( target < hand_joints[index_hand_joints].min_angle )
00150 target = hand_joints[index_hand_joints].min_angle;
00151 if( target > hand_joints[index_hand_joints].max_angle )
00152 target = hand_joints[index_hand_joints].max_angle;
00153
00154
00155 robot_update_sensor(&hand_joints[index_hand_joints].joint_target, target);
00156 joints_map_mutex.unlock();
00157 return 0;
00158 }
00159
00160 ROS_DEBUG("Joint %s not found", joint_name.c_str());
00161
00162 joints_map_mutex.unlock();
00163 return -1;
00164 }
00165
00166 JointData RealShadowhand::getJointData( std::string joint_name )
00167 {
00168 joints_map_mutex.lock();
00169
00170 JointsMap::iterator iter = joints_map.find(joint_name);
00171
00172
00173 if( iter == joints_map.end() )
00174 {
00175 ROS_ERROR("Joint %s not found.", joint_name.c_str());
00176 JointData noData;
00177 noData.position = 0.0;
00178 noData.target = 0.0;
00179 noData.temperature = 0.0;
00180 noData.current = 0.0;
00181 noData.force = 0.0;
00182 noData.flags = "";
00183 noData.jointIndex = 0;
00184
00185 joints_map_mutex.unlock();
00186 return noData;
00187 }
00188
00189
00190 JointData tmpData = iter->second;
00191 int index = tmpData.jointIndex;
00192
00193 tmpData.position = robot_read_sensor(&hand_joints[index].position);
00194 tmpData.target = robot_read_sensor(&hand_joints[index].joint_target);
00195
00196
00197 if( hand_joints[index].a.smartmotor.has_sensors )
00198 {
00199 tmpData.temperature = robot_read_sensor(&hand_joints[index].a.smartmotor.temperature);
00200 tmpData.current = robot_read_sensor(&hand_joints[index].a.smartmotor.current);
00201 tmpData.force = robot_read_sensor(&hand_joints[index].a.smartmotor.torque);
00202 tmpData.flags = "";
00203 }
00204
00205 joints_map[joint_name] = tmpData;
00206
00207 joints_map_mutex.unlock();
00208 return tmpData;
00209 }
00210
00211 SRArticulatedRobot::JointsMap RealShadowhand::getAllJointsData()
00212 {
00213
00214 for( JointsMap::const_iterator it = joints_map.begin(); it != joints_map.end(); ++it )
00215 getJointData(it->first);
00216
00217
00218
00219 joints_map_mutex.lock();
00220
00221 std::string fingername("FF");
00222
00223 JointsMap::iterator it_j0 = joints_map.find(fingername+"J0");
00224 JointsMap::iterator it_j1 = joints_map.find(fingername+"J1");
00225 JointsMap::iterator it_j2 = joints_map.find(fingername+"J2");
00226 it_j1->second.target = it_j0->second.target/2.0;
00227 it_j2->second.target = it_j0->second.target/2.0;
00228
00229 fingername.assign("MF");
00230 it_j0 = joints_map.find(fingername+"J0");
00231 it_j1 = joints_map.find(fingername+"J1");
00232 it_j2 = joints_map.find(fingername+"J2");
00233 it_j1->second.target = it_j0->second.target/2.0;
00234 it_j2->second.target = it_j0->second.target/2.0;
00235
00236 fingername.assign("RF");
00237 it_j0 = joints_map.find(fingername+"J0");
00238 it_j1 = joints_map.find(fingername+"J1");
00239 it_j2 = joints_map.find(fingername+"J2");
00240 it_j1->second.target = it_j0->second.target/2.0;
00241 it_j2->second.target = it_j0->second.target/2.0;
00242
00243 fingername.assign("LF");
00244 it_j0 = joints_map.find(fingername+"J0");
00245 it_j1 = joints_map.find(fingername+"J1");
00246 it_j2 = joints_map.find(fingername+"J2");
00247 it_j1->second.target = it_j0->second.target/2.0;
00248 it_j2->second.target = it_j0->second.target/2.0;
00249
00250 joints_map_mutex.unlock();
00251
00252 JointsMap tmp = JointsMap(joints_map);
00253
00254
00255 return tmp;
00256 }
00257
00258 short RealShadowhand::setContrl( std::string contrlr_name, JointControllerData ctrlr_data )
00259 {
00260 parameters_map_mutex.lock();
00261
00262 struct controller_config myConfig;
00263 memset(&myConfig, 0, sizeof(myConfig));
00264
00265
00266 myConfig.nodename = contrlr_name.c_str();
00267
00268 controller_read_from_hardware(&myConfig);
00269 ROS_DEBUG("%s", controller_to_string(&myConfig));
00270
00271 for( unsigned int i = 0; i < ctrlr_data.data.size(); ++i )
00272 {
00273 std::string name = ctrlr_data.data[i].name;
00274 ParametersMap::iterator iter = parameters_map.find(name);
00275
00276
00277 if( iter == parameters_map.end() )
00278 {
00279 ROS_ERROR("Parameter %s not found.", name.c_str());
00280 continue;
00281 }
00282
00283
00284 controller_update_param(&myConfig, (controller_param)iter->second, ctrlr_data.data[i].value.c_str());
00285 }
00286
00287 parameters_map_mutex.unlock();
00288
00289 int result_ctrlr = controller_write_to_hardware(&myConfig);
00290 if( result_ctrlr )
00291 {
00292 ROS_ERROR("Failed to update contrlr (%s)", myConfig.nodename );
00293 return -1;
00294 }
00295
00296 return 0;
00297 }
00298
00299 JointControllerData RealShadowhand::getContrl( std::string contrlr_name )
00300 {
00301 struct controller_config myConfig;
00302 memset(&myConfig, 0, sizeof(myConfig));
00303
00304
00305 myConfig.nodename = contrlr_name.c_str();
00306
00307 controller_read_from_hardware(&myConfig);
00308
00309 JointControllerData tmp_data;
00310
00311 ROS_WARN("The get contrlr function is not implemented in the real shadowhand.");
00312
00313 return tmp_data;
00314
00315 }
00316
00317 short RealShadowhand::setConfig( std::vector<std::string> myConfig )
00318 {
00319 ROS_WARN("The set config function is not implemented in the real shadowhand.");
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 return 0;
00334 }
00335
00336 void RealShadowhand::getConfig( std::string joint_name )
00337 {
00338 ROS_WARN("The get config function is not yet implement in the real shadow hand.");
00339 }
00340
00341 std::vector<DiagnosticData> RealShadowhand::getDiagnostics()
00342 {
00343
00344 self_test->checkTest();
00345
00346 std::vector<DiagnosticData> returnVector;
00347
00348 DiagnosticData tmpData;
00349 std::stringstream ss;
00350
00351
00352 for( unsigned int index = 0; index < START_OF_ARM; ++index )
00353 {
00354 tmpData.joint_name = std::string(hand_joints[index].joint_name);
00355 tmpData.level = 0;
00356
00357 tmpData.position = robot_read_sensor(&hand_joints[index].position);
00358 tmpData.target = robot_read_sensor(&hand_joints[index].joint_target);
00359
00360
00361 if( hand_joints[index].a.smartmotor.has_sensors )
00362 {
00363
00364 int res;
00365 if( *(&hand_joints[index].a.smartmotor.debug_nodename) != NULL)
00366 {
00367 std::string debug_node_name = *(&hand_joints[index].a.smartmotor.debug_nodename);
00368
00369
00370 std::map<const std::string, const unsigned int>::const_iterator iter;
00371 for(iter = debug_values::names_and_offsets.begin();
00372 iter != debug_values::names_and_offsets.end(); ++iter)
00373 {
00374 struct sensor sensor_tmp;
00375
00376 res = robot_channel_to_sensor(debug_node_name.c_str(), iter->second, &sensor_tmp);
00377 tmpData.debug_values[iter->first] = robot_read_incoming(&sensor_tmp);
00378 }
00379 }
00380
00381
00382
00383 tmpData.temperature = robot_read_sensor(&hand_joints[index].a.smartmotor.temperature);
00384 tmpData.current = robot_read_sensor(&hand_joints[index].a.smartmotor.current);
00385 tmpData.force = robot_read_sensor(&hand_joints[index].a.smartmotor.torque);
00386
00387
00388
00389 struct hand_protocol_flags fl;
00390 uint64_t uuid = robot_node_id(hand_joints[index].a.smartmotor.nodename);
00391 fl = hand_protocol_get_status_flags(uuid);
00392 if( fl.valid )
00393 {
00394 ss.clear();
00395 struct hand_protocol_flags_smart_motor f;
00396 f = fl.u.smart_motor;
00397
00398 bool at_least_one_error_flag = false;
00399 if( f.nfault_pin )
00400 {
00401 at_least_one_error_flag = true;
00402 ss << "NFAULT ";
00403 ROS_WARN( "[%s]: NFAULT", hand_joints[index].joint_name );
00404 }
00405 if( f.temperature_cutout )
00406 {
00407 at_least_one_error_flag = true;
00408 ss << "TEMP ";
00409 }
00410 if( f.current_throttle )
00411 {
00412 at_least_one_error_flag = true;
00413 ss << "CURRENT ";
00414 }
00415 if( f.force_hard_limit )
00416 {
00417 at_least_one_error_flag = true;
00418 ss << "FORCE ";
00419 }
00420 if( hand_protocol_dead(uuid) )
00421 {
00422 at_least_one_error_flag = true;
00423 ss << "DEAD ";
00424 }
00425
00426
00427 if( at_least_one_error_flag )
00428 {
00429 ROS_WARN( "[%s]: %s", hand_joints[index].joint_name, (ss.str()).c_str());
00430 tmpData.level = 1;
00431 }
00432
00433 tmpData.flags = ss.str();
00434 }
00435 }
00436
00437 returnVector.push_back(tmpData);
00438 }
00439 return returnVector;
00440 }
00441
00443
00445 void RealShadowhand::pretest(diagnostic_updater::DiagnosticStatusWrapper& status)
00446 {
00447 ROS_INFO("Preparing the environment to run self tests.");
00448
00449
00450 joints_map_mutex.lock();
00451 parameters_map_mutex.lock();
00452 controllers_map_mutex.lock();
00453
00454
00455
00456 sleep(1);
00457
00458 status.summary(diagnostic_msgs::DiagnosticStatus::OK, "Pretest completed successfully.");
00459 }
00460
00461 void RealShadowhand::posttest(diagnostic_updater::DiagnosticStatusWrapper& status)
00462 {
00463 ROS_INFO("Restoring the environment after the self tests.");
00464
00465
00466 joints_map_mutex.unlock();
00467 parameters_map_mutex.unlock();
00468 controllers_map_mutex.unlock();
00469
00470
00471
00472 status.summary(diagnostic_msgs::DiagnosticStatus::OK, "Postest completed successfully.");
00473 }
00474
00475 void RealShadowhand::test_messages(diagnostic_updater::DiagnosticStatusWrapper& status)
00476 {
00477 ROS_WARN("Starting the test: Number of messages Received");
00478
00479 std::pair<unsigned char, std::string> test_result;
00480 test_result.first = diagnostic_msgs::DiagnosticStatus::OK;
00481
00482 for(unsigned int index_freq=0; index_freq < sr_self_tests::msgs_frequency_size; ++index_freq)
00483 {
00484 ros::Rate test_rate(sr_self_tests::msgs_frequency[index_freq]);
00485 for(unsigned int index_joint=0; index_joint < sr_self_tests::joints_to_test_size; ++index_joint)
00486 {
00487 std::pair<unsigned char, std::string> tmp_test_result;
00488 tmp_test_result = test_messages_routine(sr_self_tests::joints_to_test[index_joint], sr_self_tests::nb_targets_to_send, test_rate);
00489
00490 if( tmp_test_result.first == diagnostic_msgs::DiagnosticStatus::ERROR)
00491 test_result.first = diagnostic_msgs::DiagnosticStatus::ERROR;
00492
00493 std::stringstream ss;
00494 ss << "\n[" << sr_self_tests::msgs_frequency[index_freq] << "Hz]: ";
00495 ss << tmp_test_result.second;
00496
00497 test_result.second += ss.str();
00498 }
00499 }
00500 status.summary(test_result.first, test_result.second);
00501 }
00502
00503 std::pair<unsigned char, std::string> RealShadowhand::test_messages_routine(std::string joint_name, unsigned int repeat, ros::Rate rate)
00504 {
00505 std::pair<unsigned char, std::string> test_result;
00506
00507
00508 std::string ID = "1";
00509 self_test->setID(ID.c_str());
00510
00511 unsigned int nb_msgs_sent = 0;
00512 unsigned int nb_msgs_received = 0;
00513
00514
00515 JointsMap::iterator iter_joints_map = joints_map.find(joint_name);
00516
00517 struct sensor sensor_msgs_received;
00518
00519 if( iter_joints_map == joints_map.end() )
00520 {
00521 std::stringstream ss;
00522 ss << "No messages sent: couldn't find joint "<<joint_name;
00523
00524 test_result.first = diagnostic_msgs::DiagnosticStatus::ERROR;
00525 test_result.second = ss.str();
00526 return test_result;
00527 }
00528
00529
00530 JointData tmpData = joints_map.find(joint_name)->second;
00531 int index_hand_joints = tmpData.jointIndex;
00532 float target = hand_joints[index_hand_joints].min_angle;
00533
00534
00535 if( !hand_joints[index_hand_joints].a.smartmotor.has_sensors )
00536 {
00537 std::stringstream ss;
00538 ss << "No messages sent: joint["<<joint_name<<"] doesn't have any motor attached";
00539
00540 test_result.first = diagnostic_msgs::DiagnosticStatus::ERROR;
00541 test_result.second = ss.str();
00542 return test_result;
00543 }
00544
00545 ROS_DEBUG("Checking the current number of received messages");
00546
00547 int res;
00548 std::string debug_node_name = *(&hand_joints[index_hand_joints].a.smartmotor.debug_nodename);
00549 std::map<const std::string, const unsigned int>::const_iterator iter_debug_values = debug_values::names_and_offsets.find("Num sensor Msgs received");
00550
00551 res = robot_channel_to_sensor(debug_node_name.c_str(), iter_debug_values->second, &sensor_msgs_received);
00552
00553
00554 nb_msgs_received = robot_read_incoming(&sensor_msgs_received) - nb_msgs_received;
00555
00556 sleep(1);
00557
00558
00559 if( nb_msgs_received != robot_read_incoming(&sensor_msgs_received))
00560 {
00561 std::stringstream ss;
00562 ss << "New messages were received on the joint[" << joint_name.c_str() << "]." ;
00563 test_result.first = diagnostic_msgs::DiagnosticStatus::ERROR;
00564 test_result.second = ss.str();
00565
00566 return test_result;
00567 }
00568
00569
00570 ROS_DEBUG("Sending lots of messages.");
00571
00572 for(; nb_msgs_sent < repeat; ++nb_msgs_sent)
00573 {
00574
00575 robot_update_sensor(&hand_joints[index_hand_joints].joint_target, target);
00576 rate.sleep();
00577 ROS_DEBUG_STREAM("msg "<< nb_msgs_sent<< "/"<<sr_self_tests::nb_targets_to_send);
00578 }
00579
00580 ROS_DEBUG("Done sending the messages.");
00581
00582 sleep(0.5);
00583
00584 ROS_DEBUG("Reading the number of received messages.");
00585
00586 nb_msgs_received = robot_read_incoming(&sensor_msgs_received) - nb_msgs_received;
00587
00588 if( nb_msgs_sent == nb_msgs_received)
00589 {
00590 std::stringstream ss;
00591 ss << nb_msgs_sent << " messages sent, all received";
00592 test_result.first = diagnostic_msgs::DiagnosticStatus::OK;
00593 test_result.second = ss.str();
00594 return test_result;
00595 }
00596 else
00597 {
00598 std::stringstream ss;
00599 ss << nb_msgs_sent << " messages sent, "<<nb_msgs_received << " messages received";
00600 test_result.first = diagnostic_msgs::DiagnosticStatus::ERROR;
00601 test_result.second = ss.str();
00602 return test_result;
00603 }
00604 }
00605 }
00606
00607
00608
00609
00610
00611