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