00001
00027 #include "sr_robot_lib/sr_hand_lib.hpp"
00028 #include <string>
00029 #include <boost/foreach.hpp>
00030
00031 #include <sys/time.h>
00032
00033 #include <ros/ros.h>
00034
00035 #include "sr_robot_lib/shadow_PSTs.hpp"
00036 #include "sr_robot_lib/biotac.hpp"
00037 #include <pr2_mechanism_msgs/ListControllers.h>
00038
00039 namespace shadow_robot
00040 {
00041 #ifdef DEBUG_PUBLISHER
00042
00043 const int SrRobotLib::nb_debug_publishers_const = 20;
00044 const int SrRobotLib::debug_mutex_lock_wait_time = 100;
00045 #endif
00046
00047 SrRobotLib::SrRobotLib(pr2_hardware_interface::HardwareInterface *hw)
00048 : main_pic_idle_time(0), main_pic_idle_time_min(1000), nullify_demand_(false), motor_current_state(
00049 operation_mode::device_update_state::INITIALIZATION), tactile_current_state(operation_mode::device_update_state::INITIALIZATION),
00050 config_index(MOTOR_CONFIG_FIRST_VALUE),
00051 control_type_changed_flag_(false),
00052 nh_tilde("~")
00053 {
00054 lock_command_sending_ = boost::shared_ptr<boost::mutex>(new boost::mutex());
00055
00056
00057
00058 nullify_demand_server_ = nh_tilde.advertiseService("nullify_demand", &SrRobotLib::nullify_demand_callback, this);
00059
00060
00061
00062 control_type_.control_type = sr_robot_msgs::ControlType::FORCE;
00063 std::string default_control_mode;
00064 nh_tilde.param<std::string>("default_control_mode", default_control_mode, "FORCE");
00065 if( default_control_mode.compare("PWM") == 0 )
00066 {
00067 ROS_INFO("Using PWM control.");
00068 control_type_.control_type = sr_robot_msgs::ControlType::PWM;
00069 }
00070 else
00071 {
00072 ROS_INFO("Using TORQUE control.");
00073 }
00074
00075
00076 change_control_type_ = nh_tilde.advertiseService( "change_control_type", &SrRobotLib::change_control_type_callback_, this);
00077
00079 motor_system_control_server_ = nh_tilde.advertiseService( "change_motor_system_controls", &SrRobotLib::motor_system_controls_callback_, this);
00080
00081 #ifdef DEBUG_PUBLISHER
00082 debug_motor_indexes_and_data.resize(nb_debug_publishers_const);
00083 for( int i = 0; i < nb_debug_publishers_const; ++i )
00084 {
00085 std::stringstream ss;
00086 ss << "srh/debug_" << i;
00087 debug_publishers.push_back(node_handle.advertise<std_msgs::Int16>(ss.str().c_str(),100));
00088 }
00089 #endif
00090
00091 }
00092
00093 void SrRobotLib::update(ETHERCAT_DATA_STRUCTURE_0200_PALM_EDC_STATUS* status_data)
00094 {
00095 this->status_data = status_data;
00096
00097
00098 main_pic_idle_time = status_data->idle_time_us;
00099 if (status_data->idle_time_us < main_pic_idle_time_min)
00100 main_pic_idle_time_min = status_data->idle_time_us;
00101
00102
00103 struct timeval tv;
00104 double timestamp = 0.0;
00105 if (gettimeofday(&tv, NULL))
00106 {
00107 ROS_WARN("SrRobotLib: Failed to get system time, timestamp in state will be zero");
00108 }
00109 else
00110 {
00111 timestamp = double(tv.tv_sec) + double(tv.tv_usec) / 1.0e+6;
00112 }
00113
00114
00115 boost::ptr_vector<shadow_joints::Joint>::iterator joint_tmp = joints_vector.begin();
00116 for (; joint_tmp != joints_vector.end(); ++joint_tmp)
00117 {
00118 actuator = (joint_tmp->motor->actuator);
00119
00120 motor_index_full = joint_tmp->motor->motor_id;
00121 actuator->state_.is_enabled_ = 1;
00122 actuator->state_.device_id_ = motor_index_full;
00123 actuator->state_.halted_ = false;
00124
00125
00126 if( tactiles != NULL )
00127 actuator->state_.tactiles_ = tactiles->get_tactile_data();
00128
00129
00130 calibrate_joint(joint_tmp);
00131
00132
00133 joint_tmp->motor->actuator->state_.timestamp_ = timestamp;
00134
00135
00136 std::pair<double, double> pos_and_velocity = joint_tmp->pos_filter.compute(
00137 joint_tmp->motor->actuator->state_.position_unfiltered_, timestamp);
00138
00139 joint_tmp->motor->actuator->state_.position_ = pos_and_velocity.first;
00140
00141 joint_tmp->motor->actuator->state_.velocity_ = pos_and_velocity.second;
00142
00143
00144 std::pair<double, double> effort_and_effort_d = joint_tmp->effort_filter.compute(
00145 joint_tmp->motor->actuator->state_.force_unfiltered_, timestamp);
00146 joint_tmp->motor->actuator->state_.last_measured_effort_ = effort_and_effort_d.first;
00147
00148
00149 if ((motor_index_full == -1))
00150 continue;
00151
00152
00153 bool read_motor_info = false;
00154
00155 if (status_data->which_motors == 0)
00156 {
00157
00158 if (motor_index_full % 2 == 0)
00159 read_motor_info = true;
00160 }
00161 else
00162 {
00163
00164 if (motor_index_full % 2 == 1)
00165 read_motor_info = true;
00166 }
00167
00168
00169
00170
00171
00172
00173 index_motor_in_msg = motor_index_full / 2;
00174
00175
00176
00177 joint_tmp->motor->msg_motor_id = index_motor_in_msg;
00178
00179
00180 if (read_motor_info)
00181 read_additional_data(joint_tmp);
00182 }
00183
00184
00185 if (tactile_current_state == operation_mode::device_update_state::INITIALIZATION)
00186 {
00187 if( tactiles_init != NULL )
00188 tactiles_init->update(status_data);
00189 }
00190 else
00191 {
00192 if( tactiles != NULL )
00193 tactiles->update(status_data);
00194 }
00195 }
00196
00197 void SrRobotLib::build_motor_command(ETHERCAT_DATA_STRUCTURE_0200_PALM_EDC_COMMAND* command)
00198 {
00199
00200 boost::mutex::scoped_lock l(*lock_command_sending_);
00201
00202 if(control_type_changed_flag_)
00203 {
00204 if(!change_control_parameters(control_type_.control_type))
00205 {
00206 ROS_FATAL("Changing control parameters failed. Stopping real time loop to protect the robot.");
00207 exit(EXIT_FAILURE);
00208 }
00209
00210 control_type_changed_flag_ = false;
00211 }
00212
00213 if (motor_current_state == operation_mode::device_update_state::INITIALIZATION)
00214 {
00215 motor_current_state = motor_updater_->build_init_command(command);
00216 }
00217 else
00218 {
00219
00220 motor_current_state = motor_updater_->build_command(command);
00221 }
00222
00223 if (tactile_current_state == operation_mode::device_update_state::INITIALIZATION)
00224 {
00225 if (tactiles_init->sensor_updater->build_init_command(command)
00226 != operation_mode::device_update_state::INITIALIZATION)
00227 {
00228 tactile_current_state = operation_mode::device_update_state::OPERATION;
00229
00230 switch (tactiles_init->tactiles_vector->at(0).which_sensor)
00231 {
00232 case TACTILE_SENSOR_PROTOCOL_TYPE_PST3:
00233 tactiles = boost::shared_ptr<tactiles::ShadowPSTs>(
00234 new tactiles::ShadowPSTs(pst3_sensor_update_rate_configs_vector,
00235 operation_mode::device_update_state::OPERATION,
00236 tactiles_init->tactiles_vector));
00237
00238 ROS_INFO("PST3 tactiles initialized");
00239 break;
00240
00241 case TACTILE_SENSOR_PROTOCOL_TYPE_BIOTAC_2_3:
00242 tactiles = boost::shared_ptr<tactiles::Biotac>(
00243 new tactiles::Biotac(biotac_sensor_update_rate_configs_vector, operation_mode::device_update_state::OPERATION,
00244 tactiles_init->tactiles_vector));
00245
00246 ROS_INFO("Biotac tactiles initialized");
00247 break;
00248
00249 case TACTILE_SENSOR_PROTOCOL_TYPE_INVALID:
00250 ROS_WARN_STREAM("TACTILE_SENSOR_PROTOCOL_TYPE_INVALID!!");
00251 break;
00252 case TACTILE_SENSOR_PROTOCOL_TYPE_CONFLICTING:
00253 ROS_WARN_STREAM("TACTILE_SENSOR_PROTOCOL_TYPE_CONFLICTING!!");
00254 break;
00255 }
00256 }
00257 }
00258 else
00259 tactile_current_state = tactiles->sensor_updater->build_command(command);
00260
00262
00263
00264
00265
00266
00267
00268 if ( reconfig_queue.empty() && reset_motors_queue.empty()
00269 && motor_system_control_flags_.empty() )
00270 {
00271
00272 switch( control_type_.control_type )
00273 {
00274 case sr_robot_msgs::ControlType::FORCE:
00275 command->to_motor_data_type = MOTOR_DEMAND_TORQUE;
00276 break;
00277 case sr_robot_msgs::ControlType::PWM:
00278 command->to_motor_data_type = MOTOR_DEMAND_PWM;
00279 break;
00280
00281 default:
00282 command->to_motor_data_type = MOTOR_DEMAND_TORQUE;
00283 break;
00284 }
00285
00286
00287 boost::ptr_vector<shadow_joints::Joint>::iterator joint_tmp = joints_vector.begin();
00288 for (; joint_tmp != joints_vector.end(); ++joint_tmp)
00289 {
00290 if (joint_tmp->has_motor)
00291 {
00292 if( !nullify_demand_ )
00293 {
00294
00295 command->motor_data[joint_tmp->motor->motor_id] = joint_tmp->motor->actuator->command_.effort_;
00296 }
00297 else
00298 {
00299
00300 command->motor_data[joint_tmp->motor->motor_id] = 0;
00301 }
00302
00303 #ifdef DEBUG_PUBLISHER
00304
00305
00306
00307 int publisher_index = 0;
00308 boost::shared_ptr<std::pair<int,int> > debug_pair;
00309 if( debug_mutex.try_lock() )
00310 {
00311 BOOST_FOREACH(debug_pair, debug_motor_indexes_and_data)
00312 {
00313 if( debug_pair != NULL )
00314 {
00315
00316 if( debug_pair->first == joint_tmp->motor->motor_id )
00317 {
00318
00319 if( debug_pair->second == -1 )
00320 {
00321 msg_debug.data = joint_tmp->motor->actuator->command_.effort_;
00322 debug_publishers[publisher_index].publish(msg_debug);
00323 }
00324 }
00325 }
00326 publisher_index ++;
00327 }
00328
00329 debug_mutex.unlock();
00330 }
00331 #endif
00332
00333 joint_tmp->motor->actuator->state_.last_commanded_effort_ = joint_tmp->motor->actuator->command_.effort_;
00334 }
00335 }
00336 }
00337 else
00338 {
00339 if ( !motor_system_control_flags_.empty() )
00340 {
00341
00342 std::vector<sr_robot_msgs::MotorSystemControls> system_controls_to_send;
00343 system_controls_to_send = motor_system_control_flags_.front();
00344 motor_system_control_flags_.pop();
00345
00346
00347 command->to_motor_data_type = MOTOR_SYSTEM_CONTROLS;
00348
00349 std::vector<sr_robot_msgs::MotorSystemControls>::iterator it;
00350 for( it = system_controls_to_send.begin(); it != system_controls_to_send.end(); ++it)
00351 {
00352 short combined_flags = 0;
00353 if( it->enable_backlash_compensation )
00354 combined_flags |= MOTOR_SYSTEM_CONTROL_BACKLASH_COMPENSATION_ENABLE;
00355 else
00356 combined_flags |= MOTOR_SYSTEM_CONTROL_BACKLASH_COMPENSATION_DISABLE;
00357
00358 if( it->increase_sgl_tracking )
00359 combined_flags |= MOTOR_SYSTEM_CONTROL_SGL_TRACKING_INC;
00360 if( it->decrease_sgl_tracking )
00361 combined_flags |= MOTOR_SYSTEM_CONTROL_SGL_TRACKING_DEC;
00362
00363 if( it->increase_sgr_tracking )
00364 combined_flags |= MOTOR_SYSTEM_CONTROL_SGR_TRACKING_INC;
00365 if( it->decrease_sgr_tracking )
00366 combined_flags |= MOTOR_SYSTEM_CONTROL_SGR_TRACKING_DEC;
00367
00368 if( it->initiate_jiggling )
00369 combined_flags |= MOTOR_SYSTEM_CONTROL_INITIATE_JIGGLING;
00370
00371 if( it->write_config_to_eeprom )
00372 combined_flags |= MOTOR_SYSTEM_CONTROL_EEPROM_WRITE;
00373
00374 command->motor_data[ it->motor_id ] = combined_flags;
00375 }
00376 }
00377 else
00378 {
00379 if (!reset_motors_queue.empty())
00380 {
00381
00382 short motor_id = reset_motors_queue.front();
00383 boost::ptr_vector<shadow_joints::Joint>::iterator joint_tmp = joints_vector.begin();
00384 for (; joint_tmp != joints_vector.end(); ++joint_tmp)
00385 {
00386 if( joint_tmp->motor->motor_id == motor_id )
00387 {
00388 joint_tmp->motor->actuator->state_.can_msgs_transmitted_ = 0;
00389 joint_tmp->motor->actuator->state_.can_msgs_received_ = 0;
00390 }
00391 }
00392
00393
00394
00395 command->to_motor_data_type = MOTOR_SYSTEM_RESET;
00396
00397 while (!reset_motors_queue.empty())
00398 {
00399 motor_id = reset_motors_queue.front();
00400 reset_motors_queue.pop();
00401
00402
00403
00404 crc_unions::union16 to_send;
00405 to_send.byte[1] = MOTOR_SYSTEM_RESET_KEY >> 8;
00406 if (motor_id > 9)
00407 to_send.byte[0] = motor_id - 10;
00408 else
00409 to_send.byte[0] = motor_id;
00410
00411 command->motor_data[motor_id] = to_send.word;
00412 }
00413 }
00414 else
00415 {
00416 if (!reconfig_queue.empty())
00417 {
00418
00419
00420
00421
00422
00423
00424
00425 command->to_motor_data_type = static_cast<TO_MOTOR_DATA_TYPE>(config_index);
00426
00427
00428 int motor_index = reconfig_queue.front().first;
00429
00430
00431 command->motor_data[motor_index] = reconfig_queue.front().second[config_index].word;
00432
00433
00434
00435
00436
00437
00438
00439
00440 if (config_index == static_cast<int>(MOTOR_CONFIG_CRC))
00441 {
00442
00443
00444 for (int i = 0; i < NUM_MOTORS; ++i)
00445 {
00446 if (i != motor_index)
00447 command->motor_data[i] = 0;
00448 }
00449
00450
00451
00452 reconfig_queue.pop();
00453 config_index = MOTOR_CONFIG_FIRST_VALUE;
00454 }
00455 else
00456 ++config_index;
00457 }
00458 }
00459 }
00460 }
00461 }
00462
00463 void SrRobotLib::add_diagnostics(std::vector<diagnostic_msgs::DiagnosticStatus> &vec,
00464 diagnostic_updater::DiagnosticStatusWrapper &d)
00465 {
00466 boost::ptr_vector<shadow_joints::Joint>::iterator joint = joints_vector.begin();
00467 for (; joint != joints_vector.end(); ++joint)
00468 {
00469 std::stringstream name;
00470 name.str("");
00471 name << "SRDMotor " << joint->joint_name;
00472 d.name = name.str();
00473
00474 if (joint->has_motor)
00475 {
00476 const sr_actuator::SrActuatorState *state(&(joint->motor->actuator)->state_);
00477
00478 if (joint->motor->motor_ok)
00479 {
00480 if (joint->motor->bad_data)
00481 {
00482 d.summary(d.WARN, "WARNING, bad CAN data received");
00483
00484 d.clear();
00485 d.addf("Motor ID", "%d", joint->motor->motor_id);
00486 }
00487 else
00488 {
00489 d.summary(d.OK, "OK");
00490
00491 d.clear();
00492 d.addf("Motor ID", "%d", joint->motor->motor_id);
00493 d.addf("Motor ID in message", "%d", joint->motor->msg_motor_id);
00494 d.addf("Serial Number", "%d", state->serial_number );
00495 d.addf("Assembly date", "%d / %d / %d", state->assembly_data_day, state->assembly_data_month, state->assembly_data_year );
00496
00497 d.addf("Strain Gauge Left", "%d", state->strain_gauge_left_);
00498 d.addf("Strain Gauge Right", "%d", state->strain_gauge_right_);
00499
00500
00501 std::stringstream ss;
00502 if (state->flags_.size() > 0)
00503 {
00504 int flags_seriousness = d.OK;
00505 std::pair<std::string, bool> flag;
00506 BOOST_FOREACH(flag, state->flags_)
00507 {
00508
00509 if (flag.second)
00510 flags_seriousness = d.ERROR;
00511
00512 if (flags_seriousness != d.ERROR)
00513 flags_seriousness = d.WARN;
00514 ss << flag.first << " | ";
00515 }
00516 d.summary(flags_seriousness, ss.str().c_str());
00517 }
00518 else
00519 ss << " None";
00520 d.addf("Motor Flags", "%s", ss.str().c_str());
00521
00522 d.addf("Measured PWM", "%d", state->pwm_);
00523 d.addf("Measured Current", "%f", state->last_measured_current_);
00524 d.addf("Measured Voltage", "%f", state->motor_voltage_);
00525 d.addf("Measured Effort", "%f", state->last_measured_effort_);
00526 d.addf("Temperature", "%f", state->temperature_);
00527
00528 d.addf("Unfiltered position", "%f", state->position_unfiltered_);
00529 d.addf("Unfiltered force", "%f", state->force_unfiltered_);
00530
00531 d.addf("Gear Ratio", "%d", state->motor_gear_ratio);
00532
00533 d.addf("Number of CAN messages received", "%lld", state->can_msgs_received_);
00534 d.addf("Number of CAN messages transmitted", "%lld", state->can_msgs_transmitted_);
00535
00536 d.addf("Force control Pterm", "%d", state->force_control_pterm);
00537 d.addf("Force control Iterm", "%d", state->force_control_iterm);
00538 d.addf("Force control Dterm", "%d", state->force_control_dterm);
00539
00540 d.addf("Force control F", "%d", state->force_control_f_);
00541 d.addf("Force control P", "%d", state->force_control_p_);
00542 d.addf("Force control I", "%d", state->force_control_i_);
00543 d.addf("Force control D", "%d", state->force_control_d_);
00544 d.addf("Force control Imax", "%d", state->force_control_imax_);
00545 d.addf("Force control Deadband", "%d", state->force_control_deadband_);
00546 d.addf("Force control Frequency", "%d", state->force_control_frequency_);
00547
00548 if (state->force_control_sign_ == 0)
00549 d.addf("Force control Sign", "+");
00550 else
00551 d.addf("Force control Sign", "-");
00552
00553 d.addf("Last Commanded Effort", "%f", state->last_commanded_effort_);
00554
00555 d.addf("Encoder Position", "%f", state->position_);
00556
00557 if (state->firmware_modified_)
00558 d.addf("Firmware svn revision (server / pic / modified)", "%d / %d / True",
00559 state->server_firmware_svn_revision_, state->pic_firmware_svn_revision_);
00560 else
00561 d.addf("Firmware svn revision (server / pic / modified)", "%d / %d / False",
00562 state->server_firmware_svn_revision_, state->pic_firmware_svn_revision_);
00563 }
00564 }
00565 else
00566 {
00567 d.summary(d.ERROR, "Motor error");
00568 d.clear();
00569 d.addf("Motor ID", "%d", joint->motor->motor_id);
00570 }
00571 }
00572 else
00573 {
00574 d.summary(d.OK, "No motor associated to this joint");
00575 d.clear();
00576 }
00577 vec.push_back(d);
00578
00579 }
00580
00581 }
00582
00583 void SrRobotLib::calibrate_joint(boost::ptr_vector<shadow_joints::Joint>::iterator joint_tmp)
00584 {
00585 actuator->state_.raw_sensor_values_.clear();
00586 actuator->state_.calibrated_sensor_values_.clear();
00587
00588 if (joint_tmp->joint_to_sensor.calibrate_after_combining_sensors)
00589 {
00590
00591
00592
00593 double raw_position = 0.0;
00594
00595
00596 BOOST_FOREACH(shadow_joints::PartialJointToSensor joint_to_sensor, joint_tmp->joint_to_sensor.joint_to_sensor_vector)
00597 {
00598 int tmp_raw = status_data->sensors[joint_to_sensor.sensor_id];
00599 actuator->state_.raw_sensor_values_.push_back(tmp_raw);
00600 raw_position += static_cast<double>(tmp_raw) * joint_to_sensor.coeff;
00601 }
00602
00603
00604 calibration_tmp = calibration_map.find(joint_tmp->joint_name);
00605 actuator->state_.position_unfiltered_ = calibration_tmp->compute(static_cast<double>(raw_position));
00606 }
00607 else
00608 {
00609
00610
00611 double calibrated_position = 0.0;
00612 shadow_joints::PartialJointToSensor joint_to_sensor;
00613 std::string sensor_name;
00614
00615 ROS_DEBUG_STREAM("Combining actuator " << joint_tmp->joint_name);
00616
00617 for (unsigned int index_joint_to_sensor = 0;
00618 index_joint_to_sensor < joint_tmp->joint_to_sensor.joint_to_sensor_vector.size(); ++index_joint_to_sensor)
00619 {
00620 joint_to_sensor = joint_tmp->joint_to_sensor.joint_to_sensor_vector[index_joint_to_sensor];
00621 sensor_name = joint_tmp->joint_to_sensor.sensor_names[index_joint_to_sensor];
00622
00623
00624 int raw_pos = status_data->sensors[joint_to_sensor.sensor_id];
00625
00626 actuator->state_.raw_sensor_values_.push_back(raw_pos);
00627
00628
00629 calibration_tmp = calibration_map.find(sensor_name);
00630 double tmp_cal_value = calibration_tmp->compute(static_cast<double>(raw_pos));
00631
00632
00633 actuator->state_.calibrated_sensor_values_.push_back(tmp_cal_value);
00634
00635 calibrated_position += tmp_cal_value * joint_to_sensor.coeff;
00636
00637 ROS_DEBUG_STREAM(" -> "<< sensor_name<< " raw = " << raw_pos << " calibrated = " << calibrated_position);
00638 }
00639 actuator->state_.position_unfiltered_ = calibrated_position;
00640 ROS_DEBUG_STREAM(" => "<< actuator->state_.position_unfiltered_);
00641 }
00642 }
00643
00644 void SrRobotLib::read_additional_data(boost::ptr_vector<shadow_joints::Joint>::iterator joint_tmp)
00645 {
00646
00647
00648 joint_tmp->motor->motor_ok = sr_math_utils::is_bit_mask_index_true(status_data->which_motor_data_arrived,
00649 motor_index_full);
00650
00651
00652
00653 joint_tmp->motor->bad_data = sr_math_utils::is_bit_mask_index_true(status_data->which_motor_data_had_errors,
00654 index_motor_in_msg);
00655
00656 crc_unions::union16 tmp_value;
00657
00658 if (joint_tmp->motor->motor_ok && !(joint_tmp->motor->bad_data))
00659 {
00660 #ifdef DEBUG_PUBLISHER
00661 int publisher_index = 0;
00662
00663
00664
00665 boost::shared_ptr<std::pair<int,int> > debug_pair;
00666
00667 if( debug_mutex.try_lock() )
00668 {
00669 BOOST_FOREACH(debug_pair, debug_motor_indexes_and_data)
00670 {
00671 if( debug_pair != NULL )
00672 {
00673
00674 if( debug_pair->first == joint_tmp->motor->motor_id )
00675 {
00676
00677 if( debug_pair->second > 0 )
00678 {
00679
00680 if( debug_pair->second == status_data->motor_data_type )
00681 {
00682 msg_debug.data = status_data->motor_data_packet[index_motor_in_msg].misc;
00683 debug_publishers[publisher_index].publish(msg_debug);
00684 }
00685 }
00686 }
00687 }
00688 publisher_index ++;
00689 }
00690
00691 debug_mutex.unlock();
00692 }
00693 #endif
00694
00695
00696 bool read_torque = true;
00697 switch (status_data->motor_data_type)
00698 {
00699 case MOTOR_DATA_SGL:
00700 actuator->state_.strain_gauge_left_ =
00701 static_cast<int16s>(status_data->motor_data_packet[index_motor_in_msg].misc);
00702
00703 #ifdef DEBUG_PUBLISHER
00704 if( joint_tmp->motor->motor_id == 8 )
00705 {
00706
00707 msg_debug.data = actuator->state_.strain_gauge_left_;
00708 debug_publishers[0].publish(msg_debug);
00709 }
00710 #endif
00711 break;
00712 case MOTOR_DATA_SGR:
00713 actuator->state_.strain_gauge_right_ =
00714 static_cast<int16s>(status_data->motor_data_packet[index_motor_in_msg].misc);
00715
00716 #ifdef DEBUG_PUBLISHER
00717 if( joint_tmp->motor->motor_id == 8 )
00718 {
00719
00720 msg_debug.data = actuator->state_.strain_gauge_right_;
00721 debug_publishers[1].publish(msg_debug);
00722 }
00723 #endif
00724 break;
00725 case MOTOR_DATA_PWM:
00726 actuator->state_.pwm_ =
00727 static_cast<int>(static_cast<int16s>(status_data->motor_data_packet[index_motor_in_msg].misc));
00728 break;
00729 case MOTOR_DATA_FLAGS:
00730 actuator->state_.flags_ = humanize_flags(status_data->motor_data_packet[index_motor_in_msg].misc);
00731 break;
00732 case MOTOR_DATA_CURRENT:
00733
00734 actuator->state_.last_measured_current_ =
00735 static_cast<double>(static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].misc))
00736 / 1000.0;
00737
00738 #ifdef DEBUG_PUBLISHER
00739 if( joint_tmp->motor->motor_id == 8 )
00740 {
00741
00742 msg_debug.data = static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].misc);
00743 debug_publishers[2].publish(msg_debug);
00744 }
00745 #endif
00746 break;
00747 case MOTOR_DATA_VOLTAGE:
00748 actuator->state_.motor_voltage_ =
00749 static_cast<double>(static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].misc)) / 256.0;
00750
00751 #ifdef DEBUG_PUBLISHER
00752 if( joint_tmp->motor->motor_id == 8 )
00753 {
00754
00755 msg_debug.data = static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].misc);
00756 debug_publishers[3].publish(msg_debug);
00757 }
00758 #endif
00759 break;
00760 case MOTOR_DATA_TEMPERATURE:
00761 actuator->state_.temperature_ =
00762 static_cast<double>(static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].misc)) / 256.0;
00763 break;
00764 case MOTOR_DATA_CAN_NUM_RECEIVED:
00765
00766
00767 actuator->state_.can_msgs_received_ = sr_math_utils::counter_with_overflow(
00768 actuator->state_.can_msgs_received_,
00769 static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].misc));
00770 break;
00771 case MOTOR_DATA_CAN_NUM_TRANSMITTED:
00772
00773
00774 actuator->state_.can_msgs_transmitted_ = sr_math_utils::counter_with_overflow(
00775 actuator->state_.can_msgs_received_,
00776 static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].misc));
00777 break;
00778
00779 case MOTOR_DATA_SLOW_MISC:
00780
00781
00782
00783
00784 read_torque = false;
00785
00786 switch (static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].torque))
00787 {
00788 case MOTOR_SLOW_DATA_SVN_REVISION:
00789 actuator->state_.pic_firmware_svn_revision_ =
00790 static_cast<unsigned int>(static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].misc));
00791 break;
00792 case MOTOR_SLOW_DATA_SVN_SERVER_REVISION:
00793 actuator->state_.server_firmware_svn_revision_ =
00794 static_cast<unsigned int>(static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].misc));
00795 break;
00796 case MOTOR_SLOW_DATA_SVN_MODIFIED:
00797 actuator->state_.firmware_modified_ =
00798 static_cast<bool>(static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].misc));
00799 break;
00800 case MOTOR_SLOW_DATA_SERIAL_NUMBER_LOW:
00801 actuator->state_.set_serial_number_low (
00802 static_cast<unsigned int>(static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].misc)) );
00803 break;
00804 case MOTOR_SLOW_DATA_SERIAL_NUMBER_HIGH:
00805 actuator->state_.set_serial_number_high (
00806 static_cast<unsigned int>(static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].misc)) );
00807 break;
00808 case MOTOR_SLOW_DATA_GEAR_RATIO:
00809 actuator->state_.motor_gear_ratio =
00810 static_cast<unsigned int>(static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].misc));
00811 break;
00812 case MOTOR_SLOW_DATA_ASSEMBLY_DATE_YYYY:
00813 actuator->state_.assembly_data_year =
00814 static_cast<unsigned int>(static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].misc));
00815 break;
00816 case MOTOR_SLOW_DATA_ASSEMBLY_DATE_MMDD:
00817 actuator->state_.assembly_data_month =
00818 static_cast<unsigned int>(static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].misc)
00819 >> 8);
00820 actuator->state_.assembly_data_day =
00821 static_cast<unsigned int>(static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].misc)
00822 && 0x00FF);
00823 break;
00824 case MOTOR_SLOW_DATA_CONTROLLER_F:
00825 actuator->state_.force_control_f_ =
00826 static_cast<unsigned int>(static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].misc));
00827 break;
00828 case MOTOR_SLOW_DATA_CONTROLLER_P:
00829 actuator->state_.force_control_p_ =
00830 static_cast<unsigned int>(static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].misc));
00831 break;
00832 case MOTOR_SLOW_DATA_CONTROLLER_I:
00833 actuator->state_.force_control_i_ =
00834 static_cast<unsigned int>(static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].misc));
00835 break;
00836 case MOTOR_SLOW_DATA_CONTROLLER_D:
00837 actuator->state_.force_control_d_ =
00838 static_cast<unsigned int>(static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].misc));
00839 break;
00840 case MOTOR_SLOW_DATA_CONTROLLER_IMAX:
00841 actuator->state_.force_control_imax_ =
00842 static_cast<unsigned int>(static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].misc));
00843 break;
00844 case MOTOR_SLOW_DATA_CONTROLLER_DEADSIGN:
00845 tmp_value.word = status_data->motor_data_packet[index_motor_in_msg].misc;
00846 actuator->state_.force_control_deadband_ = static_cast<int>(tmp_value.byte[0]);
00847 actuator->state_.force_control_sign_ = static_cast<int>(tmp_value.byte[1]);
00848 break;
00849 case MOTOR_SLOW_DATA_CONTROLLER_FREQUENCY:
00850 actuator->state_.force_control_frequency_ =
00851 static_cast<unsigned int>(static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].misc));
00852 break;
00853
00854 default:
00855 break;
00856 }
00857 break;
00858
00859 case MOTOR_DATA_CAN_ERROR_COUNTERS:
00860 actuator->state_.can_error_counters =
00861 static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].misc);
00862 break;
00863 case MOTOR_DATA_PTERM:
00864 actuator->state_.force_control_pterm =
00865 static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].misc);
00866 break;
00867 case MOTOR_DATA_ITERM:
00868 actuator->state_.force_control_iterm =
00869 static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].misc);
00870 break;
00871 case MOTOR_DATA_DTERM:
00872 actuator->state_.force_control_dterm =
00873 static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].misc);
00874 break;
00875
00876 default:
00877 break;
00878 }
00879
00880 if (read_torque)
00881 {
00882 actuator->state_.force_unfiltered_ =
00883 static_cast<double>(static_cast<int16s>(status_data->motor_data_packet[index_motor_in_msg].torque));
00884
00885 #ifdef DEBUG_PUBLISHER
00886 if( joint_tmp->motor->motor_id == 8 )
00887 {
00888 msg_debug.data = static_cast<int16s>(status_data->motor_data_packet[index_motor_in_msg].torque);
00889 debug_publishers[4].publish(msg_debug);
00890 }
00891 #endif
00892 }
00893
00894
00895 if (motor_current_state == operation_mode::device_update_state::INITIALIZATION)
00896 {
00897 if (motor_data_checker->check_message(
00898 joint_tmp, status_data->motor_data_type,
00899 static_cast<int16u>(status_data->motor_data_packet[index_motor_in_msg].torque)))
00900 {
00901 motor_updater_->update_state = operation_mode::device_update_state::OPERATION;
00902 motor_current_state = operation_mode::device_update_state::OPERATION;
00903
00904 ROS_INFO("All motors were initialized.");
00905 }
00906 }
00907 }
00908 }
00909
00910 std::vector<std::pair<std::string, bool> > SrRobotLib::humanize_flags(int flag)
00911 {
00912 std::vector<std::pair<std::string, bool> > flags;
00913
00914
00915 for (unsigned int i = 0; i < 16; ++i)
00916 {
00917 std::pair<std::string, bool> new_flag;
00918
00919 if (sr_math_utils::is_bit_mask_index_true(flag, i))
00920 {
00921 if (sr_math_utils::is_bit_mask_index_true(SERIOUS_ERROR_FLAGS, i))
00922 new_flag.second = true;
00923 else
00924 new_flag.second = false;
00925
00926 new_flag.first = error_flag_names[i];
00927 flags.push_back(new_flag);
00928 }
00929 }
00930 return flags;
00931 }
00932
00933 void SrRobotLib::generate_force_control_config(int motor_index, int max_pwm, int sg_left, int sg_right, int f, int p,
00934 int i, int d, int imax, int deadband, int sign)
00935 {
00936 ROS_INFO_STREAM(
00937 "Setting new pid values for motor" << motor_index << ": max_pwm="<< max_pwm <<" sgleftref=" << sg_left << " sgrightref=" << sg_right << " f=" << f << " p=" << p << " i=" << i << " d="<< d << " imax=" << imax << " deadband="<< deadband << " sign=" << sign);
00938
00939
00940
00941
00942 std::vector<crc_unions::union16> full_config(MOTOR_CONFIG_CRC + 1);
00943 crc_unions::union16 value;
00944
00945 value.word = max_pwm;
00946 full_config.at(MOTOR_CONFIG_MAX_PWM) = value;
00947
00948 value.byte[0] = sg_left;
00949 value.byte[1] = sg_right;
00950 full_config.at(MOTOR_CONFIG_SG_REFS) = value;
00951
00952 value.word = f;
00953 full_config.at(MOTOR_CONFIG_F) = value;
00954
00955 value.word = p;
00956 full_config.at(MOTOR_CONFIG_P) = value;
00957
00958 value.word = i;
00959 full_config.at(MOTOR_CONFIG_I) = value;
00960
00961 value.word = d;
00962 full_config.at(MOTOR_CONFIG_D) = value;
00963
00964 value.word = imax;
00965 full_config.at(MOTOR_CONFIG_IMAX) = value;
00966
00967 value.byte[0] = deadband;
00968 value.byte[1] = sign;
00969 full_config.at(MOTOR_CONFIG_DEADBAND_SIGN) = value;
00970 ROS_DEBUG_STREAM(
00971 "deadband: " << static_cast<int>(static_cast<int8u>(value.byte[0]) ) << " value: " << static_cast<int16u>(value.word));
00972
00973
00974 crc_result = 0;
00975 for (unsigned int i = MOTOR_CONFIG_FIRST_VALUE; i <= MOTOR_CONFIG_LAST_VALUE; ++i)
00976 {
00977 crc_byte = full_config.at(i).byte[0];
00978 INSERT_CRC_CALCULATION_HERE;
00979
00980 crc_byte = full_config.at(i).byte[1];
00981 INSERT_CRC_CALCULATION_HERE;
00982 }
00983
00984
00985
00986
00987 if (crc_result == 0)
00988 crc_result = 1;
00989 value.word = crc_result;
00990 full_config.at(MOTOR_CONFIG_CRC) = value;
00991
00992 ForceConfig config;
00993 config.first = motor_index;
00994 config.second = full_config;
00995
00996 reconfig_queue.push(config);
00997 }
00998
00999 void SrRobotLib::reinitialize_motors()
01000 {
01001
01002 motor_updater_ = boost::shared_ptr<generic_updater::MotorUpdater>(new generic_updater::MotorUpdater(motor_update_rate_configs_vector, operation_mode::device_update_state::INITIALIZATION));
01003 motor_current_state = operation_mode::device_update_state::INITIALIZATION;
01004
01005 motor_data_checker = boost::shared_ptr<generic_updater::MotorDataChecker>(new generic_updater::MotorDataChecker(joints_vector, motor_updater_->initialization_configs_vector));
01006 }
01007
01008 void SrRobotLib::reinitialize_sensors()
01009 {
01010
01011 tactiles_init = boost::shared_ptr<tactiles::GenericTactiles>( new tactiles::GenericTactiles(generic_sensor_update_rate_configs_vector, operation_mode::device_update_state::INITIALIZATION) );
01012 tactile_current_state = operation_mode::device_update_state::INITIALIZATION;
01013 }
01014
01015 bool SrRobotLib::nullify_demand_callback( sr_robot_msgs::NullifyDemand::Request& request,
01016 sr_robot_msgs::NullifyDemand::Response& response )
01017 {
01018 if( request.nullify_demand )
01019 ROS_INFO_STREAM("Nullifying the demand sent to the motor. Will ignore the values computed by the controllers and send 0.");
01020 else
01021 ROS_INFO_STREAM("Using the value computed by the controllers to send the demands to the motors.");
01022
01023 nullify_demand_ = request.nullify_demand;
01024 return true;
01025 }
01026
01027 bool SrRobotLib::change_control_type_callback_( sr_robot_msgs::ChangeControlType::Request& request,
01028 sr_robot_msgs::ChangeControlType::Response& response )
01029 {
01030 if( (request.control_type.control_type != sr_robot_msgs::ControlType::PWM) &&
01031 (request.control_type.control_type != sr_robot_msgs::ControlType::FORCE) )
01032 {
01033 std::string ctrl_type_text = "";
01034 if(control_type_.control_type == sr_robot_msgs::ControlType::FORCE)
01035 ctrl_type_text = "FORCE";
01036 else
01037 ctrl_type_text = "PWM";
01038
01039 ROS_ERROR_STREAM(" The value you specified for the control type (" << request.control_type
01040 << ") is incorrect. Using " << ctrl_type_text << " control.");
01041
01042 response.result = control_type_;
01043 return false;
01044 }
01045
01046 if(control_type_.control_type != request.control_type.control_type)
01047 {
01048
01049 boost::mutex::scoped_lock l(*lock_command_sending_);
01050
01051 ROS_WARN("Changing control type");
01052
01053 control_type_ = request.control_type;
01054
01055
01056
01057
01058
01059
01060 control_type_changed_flag_ = true;
01061 }
01062
01063 response.result = control_type_;
01064 return true;
01065 }
01066
01067 bool SrRobotLib::change_control_parameters(int16_t control_type)
01068 {
01069 bool success = true;
01070 std::string env_variable;
01071 std::string param_value;
01072
01073 if( control_type == sr_robot_msgs::ControlType::PWM)
01074 {
01075 env_variable = "PWM_CONTROL=1";
01076 param_value = "PWM";
01077 }
01078 else
01079 {
01080 env_variable = "PWM_CONTROL=0";
01081 param_value = "FORCE";
01082 }
01083
01084 int result = system((env_variable + " roslaunch sr_ethercat_hand_config sr_edc_default_controllers.launch").c_str());
01085
01086 if(result == 0)
01087 {
01088 ROS_WARN("New parameters loaded successfully on Parameter Server");
01089
01090 nh_tilde.setParam("default_control_mode", param_value);
01091
01092 ros::ServiceClient list_ctrl_client = nh_tilde.serviceClient<pr2_mechanism_msgs::ListControllers>("/pr2_controller_manager/list_controllers");
01093 pr2_mechanism_msgs::ListControllers controllers_list;
01094
01095 if (list_ctrl_client.call(controllers_list))
01096 {
01097 for(unsigned int i=0; i < controllers_list.response.controllers.size(); ++i)
01098 {
01099 ros::ServiceClient reset_gains_client = nh_tilde.serviceClient<std_srvs::Empty>("/" + controllers_list.response.controllers.at(i) + "/reset_gains");
01100 std_srvs::Empty empty_message;
01101 if (!reset_gains_client.call(empty_message))
01102 {
01103 ROS_ERROR_STREAM("Failed to reset gains for controller: " << controllers_list.response.controllers.at(i));
01104 return false;
01105 }
01106 }
01107 }
01108 else
01109 {
01110 return false;
01111 }
01112 }
01113 else
01114 {
01115 return false;
01116 }
01117
01118 return success;
01119 }
01120
01121 bool SrRobotLib::motor_system_controls_callback_( sr_robot_msgs::ChangeMotorSystemControls::Request& request,
01122 sr_robot_msgs::ChangeMotorSystemControls::Response& response )
01123 {
01124 std::vector<sr_robot_msgs::MotorSystemControls> tmp_motor_controls;
01125
01126 response.result = sr_robot_msgs::ChangeMotorSystemControls::Response::SUCCESS;
01127 bool no_motor_id_out_of_range = true;
01128
01129 for( unsigned int i=0; i < request.motor_system_controls.size(); ++i)
01130 {
01131 if( request.motor_system_controls[i].motor_id >= NUM_MOTORS ||
01132 request.motor_system_controls[i].motor_id < 0)
01133 {
01134 response.result = sr_robot_msgs::ChangeMotorSystemControls::Response::MOTOR_ID_OUT_OF_RANGE;
01135 no_motor_id_out_of_range = false;
01136 }
01137 else
01138 {
01139
01140 tmp_motor_controls.push_back( request.motor_system_controls[i] );
01141 }
01142 }
01143
01144
01145 if( tmp_motor_controls.size() > 0 )
01146 motor_system_control_flags_.push( tmp_motor_controls );
01147
01148 return no_motor_id_out_of_range;
01149 }
01150
01151 }
01152
01153
01154
01155
01156
01157