00001
00028 #include "sr_robot_lib/sr_muscle_robot_lib.hpp"
00029 #include <string>
00030 #include <boost/foreach.hpp>
00031
00032 #include <sys/time.h>
00033
00034 #include <ros/ros.h>
00035
00036 #include <pr2_mechanism_msgs/ListControllers.h>
00037
00038 #define SERIOUS_ERROR_FLAGS PALM_0300_EDC_SERIOUS_ERROR_FLAGS
00039 #define error_flag_names palm_0300_edc_error_flag_names
00040
00041
00042 namespace shadow_robot
00043 {
00044 template <class StatusType, class CommandType>
00045 const double SrMuscleRobotLib<StatusType, CommandType>::timeout = 5.0;
00046
00047 template <class StatusType, class CommandType>
00048 SrMuscleRobotLib<StatusType, CommandType>::SrMuscleRobotLib(pr2_hardware_interface::HardwareInterface *hw)
00049 : SrRobotLib<StatusType, CommandType>(hw),
00050 muscle_current_state(operation_mode::device_update_state::INITIALIZATION), init_max_duration(timeout)
00051 {
00052 #ifdef DEBUG_PUBLISHER
00053 this->debug_motor_indexes_and_data.resize(this->nb_debug_publishers_const);
00054 for( int i = 0; i < this->nb_debug_publishers_const; ++i )
00055 {
00056 std::stringstream ss;
00057 ss << "srh/debug_" << i;
00058 this->debug_publishers.push_back(this->node_handle.template advertise<std_msgs::Int16>(ss.str().c_str(),100));
00059 }
00060 #endif
00061 lock_init_timeout_ = boost::shared_ptr<boost::mutex>(new boost::mutex());
00062
00063 check_init_timeout_timer = this->nh_tilde.createTimer(init_max_duration,
00064 boost::bind(&SrMuscleRobotLib<StatusType, CommandType>::init_timer_callback, this, _1), true);
00065
00066 this->pressure_calibration_map_ = this->read_pressure_calibration();
00067 }
00068
00069 template <class StatusType, class CommandType>
00070 shadow_joints::CalibrationMap SrMuscleRobotLib<StatusType, CommandType>::read_pressure_calibration()
00071 {
00072 ROS_INFO("Reading pressure calibration");
00073 shadow_joints::CalibrationMap pressure_calibration;
00074 std::string param_name = "sr_pressure_calibrations";
00075
00076 XmlRpc::XmlRpcValue calib;
00077 this->nodehandle_.getParam(param_name, calib);
00078 ROS_ASSERT(calib.getType() == XmlRpc::XmlRpcValue::TypeArray);
00079
00080 for(int32_t index_cal = 0; index_cal < calib.size(); ++index_cal)
00081 {
00082
00083
00084 ROS_ASSERT(calib[index_cal][0].getType() == XmlRpc::XmlRpcValue::TypeString);
00085 ROS_ASSERT(calib[index_cal][1].getType() == XmlRpc::XmlRpcValue::TypeArray);
00086
00087 std::string joint_name = static_cast<std::string> (calib[index_cal][0]);
00088 std::vector<joint_calibration::Point> calib_table_tmp;
00089
00090
00091 for(int32_t index_table=0; index_table < calib[index_cal][1].size(); ++index_table)
00092 {
00093 ROS_ASSERT(calib[index_cal][1][index_table].getType() == XmlRpc::XmlRpcValue::TypeArray);
00094
00095 ROS_ASSERT(calib[index_cal][1][index_table].size() == 2);
00096 ROS_ASSERT(calib[index_cal][1][index_table][0].getType() == XmlRpc::XmlRpcValue::TypeDouble);
00097 ROS_ASSERT(calib[index_cal][1][index_table][1].getType() == XmlRpc::XmlRpcValue::TypeDouble);
00098
00099
00100 joint_calibration::Point point_tmp;
00101 point_tmp.raw_value = static_cast<double> (calib[index_cal][1][index_table][0]);
00102 point_tmp.calibrated_value = static_cast<double> (calib[index_cal][1][index_table][1]);
00103 calib_table_tmp.push_back(point_tmp);
00104 }
00105
00106 pressure_calibration.insert(joint_name, boost::shared_ptr<shadow_robot::JointCalibration>(new shadow_robot::JointCalibration(calib_table_tmp)) );
00107 }
00108
00109 return pressure_calibration;
00110 }
00111
00112 template <class StatusType, class CommandType>
00113 void SrMuscleRobotLib<StatusType, CommandType>::update(StatusType* status_data)
00114 {
00115
00116 this->main_pic_idle_time = status_data->idle_time_us;
00117 if (status_data->idle_time_us < this->main_pic_idle_time_min)
00118 this->main_pic_idle_time_min = status_data->idle_time_us;
00119
00120
00121 struct timeval tv;
00122 double timestamp = 0.0;
00123 if (gettimeofday(&tv, NULL))
00124 {
00125 ROS_WARN("SrMuscleRobotLib: Failed to get system time, timestamp in state will be zero");
00126 }
00127 else
00128 {
00129 timestamp = double(tv.tv_sec) + double(tv.tv_usec) / 1.0e+6;
00130 }
00131
00132
00133 this->update_tactile_info(status_data);
00134
00135
00136 boost::ptr_vector<shadow_joints::MuscleDriver>::iterator muscle_driver_tmp = this->muscle_drivers_vector_.begin();
00137 for (; muscle_driver_tmp != this->muscle_drivers_vector_.end(); ++muscle_driver_tmp)
00138 {
00139 read_muscle_driver_data(muscle_driver_tmp, status_data);
00140 }
00141
00142
00143 boost::ptr_vector<shadow_joints::Joint>::iterator joint_tmp = this->joints_vector.begin();
00144 for (; joint_tmp != this->joints_vector.end(); ++joint_tmp)
00145 {
00146 sr_actuator::SrActuatorState* actuator_state = this->get_joint_actuator_state(joint_tmp);
00147
00148 boost::shared_ptr<shadow_joints::MuscleWrapper> muscle_wrapper = boost::static_pointer_cast<shadow_joints::MuscleWrapper>(joint_tmp->actuator_wrapper);
00149
00150 actuator_state->is_enabled_ = 1;
00151
00152 actuator_state->halted_ = false;
00153
00154
00155 if( this->tactiles != NULL )
00156 actuator_state->tactiles_ = this->tactiles->get_tactile_data();
00157
00158 this->process_position_sensor_data(joint_tmp, status_data, timestamp);
00159
00160
00161 if ((muscle_wrapper->muscle_driver_id[0] == -1))
00162 continue;
00163
00164 read_additional_muscle_data(joint_tmp, status_data);
00165 }
00166 }
00167
00168 template <class StatusType, class CommandType>
00169 void SrMuscleRobotLib<StatusType, CommandType>::build_command(CommandType* command)
00170 {
00171 if (muscle_current_state == operation_mode::device_update_state::INITIALIZATION)
00172 {
00173 muscle_current_state = muscle_updater_->build_init_command(command);
00174 }
00175 else
00176 {
00177
00178 muscle_current_state = muscle_updater_->build_command(command);
00179 }
00180
00181
00182 this->build_tactile_command(command);
00183
00185
00186
00187
00188 if ( reset_muscle_driver_queue.empty() )
00189 {
00190 command->to_muscle_data_type = MUSCLE_DEMAND_VALVES;
00191
00192
00193 boost::ptr_vector<shadow_joints::Joint>::iterator joint_tmp = this->joints_vector.begin();
00194 for (; joint_tmp != this->joints_vector.end(); ++joint_tmp)
00195 {
00196 boost::shared_ptr<shadow_joints::MuscleWrapper> muscle_wrapper = boost::static_pointer_cast<shadow_joints::MuscleWrapper>(joint_tmp->actuator_wrapper);
00197 sr_actuator::SrMuscleActuator* muscle_actuator = static_cast<sr_actuator::SrMuscleActuator*>(muscle_wrapper->actuator);
00198
00199 unsigned int muscle_driver_id_0 = muscle_wrapper->muscle_driver_id[0];
00200 unsigned int muscle_driver_id_1 = muscle_wrapper->muscle_driver_id[1];
00201 unsigned int muscle_id_0 = muscle_wrapper->muscle_id[0];
00202 unsigned int muscle_id_1 = muscle_wrapper->muscle_id[1];
00203
00204 if (joint_tmp->has_actuator)
00205 {
00206 if( !this->nullify_demand_ )
00207 {
00208 set_valve_demand(&(command->muscle_data[(muscle_driver_id_0 * 10 + muscle_id_0) / 2]), muscle_actuator->command_.valve_[0], ((uint8_t)muscle_id_0) & 0x01);
00209 set_valve_demand(&(command->muscle_data[(muscle_driver_id_1 * 10 + muscle_id_1) / 2]), muscle_actuator->command_.valve_[1], ((uint8_t)muscle_id_1) & 0x01);
00210
00211 muscle_actuator->state_.last_commanded_valve_[0] = muscle_actuator->command_.valve_[0];
00212 muscle_actuator->state_.last_commanded_valve_[1] = muscle_actuator->command_.valve_[1];
00213 }
00214 else
00215 {
00216
00217 set_valve_demand(&(command->muscle_data[(muscle_driver_id_0 * 10 + muscle_id_0) / 2]), 0, ((uint8_t)muscle_id_0) & 0x01);
00218 set_valve_demand(&(command->muscle_data[(muscle_driver_id_1 * 10 + muscle_id_1) / 2]), 0, ((uint8_t)muscle_id_1) & 0x01);
00219
00220 muscle_actuator->state_.last_commanded_valve_[0] = 0;
00221 muscle_actuator->state_.last_commanded_valve_[1] = 0;
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255 }
00256 }
00257 }
00258 else
00259 {
00260
00261
00262 command->to_muscle_data_type = MUSCLE_SYSTEM_RESET;
00263
00264 while (!reset_muscle_driver_queue.empty())
00265 {
00266 short muscle_driver_id = reset_muscle_driver_queue.front();
00267 reset_muscle_driver_queue.pop();
00268
00269
00270 boost::ptr_vector<shadow_joints::MuscleDriver>::iterator driver = this->muscle_drivers_vector_.begin();
00271 for (; driver != this->muscle_drivers_vector_.end(); ++driver)
00272 {
00273 if( driver->muscle_driver_id == muscle_driver_id)
00274 {
00275 driver->can_msgs_transmitted_ = 0;
00276 driver->can_msgs_received_ = 0;
00277 }
00278 }
00279
00280
00281
00282 crc_unions::union16 to_send;
00283 to_send.byte[1] = MUSCLE_SYSTEM_RESET_KEY >> 8;
00284 if (muscle_driver_id > 1)
00285 to_send.byte[0] = muscle_driver_id - 2;
00286 else
00287 to_send.byte[0] = muscle_driver_id;
00288
00289 command->muscle_data[muscle_driver_id * 5] = to_send.byte[0];
00290 command->muscle_data[muscle_driver_id * 5 + 1] = to_send.byte[1];
00291 }
00292 }
00293 }
00294
00295 template <class StatusType, class CommandType>
00296 inline void SrMuscleRobotLib<StatusType, CommandType>::set_valve_demand(uint8_t *muscle_data_byte_to_set, int8_t valve_value, uint8_t shift)
00297 {
00298 uint8_t tmp_valve = 0;
00299
00300
00301
00302 if (valve_value < 0)
00303 {
00304
00305 tmp_valve = -valve_value;
00306
00307 tmp_valve = (~tmp_valve) & 0x0F;
00308
00309 tmp_valve = tmp_valve + 1;
00310 }
00311 else
00312 {
00313 tmp_valve = valve_value & 0x0F;
00314 }
00315
00316
00317
00318
00319
00320 *muscle_data_byte_to_set &= (0xF0 >> (shift * 4) );
00321
00322 *muscle_data_byte_to_set |= (tmp_valve << (shift * 4) );
00323 }
00324
00325 template <class StatusType, class CommandType>
00326 void SrMuscleRobotLib<StatusType, CommandType>::add_diagnostics(std::vector<diagnostic_msgs::DiagnosticStatus> &vec,
00327 diagnostic_updater::DiagnosticStatusWrapper &d)
00328 {
00329 boost::ptr_vector<shadow_joints::Joint>::iterator joint = this->joints_vector.begin();
00330 for (; joint != this->joints_vector.end(); ++joint)
00331 {
00332 std::stringstream name;
00333 name.str("");
00334 name << "SRDMotor " << joint->joint_name;
00335 d.name = name.str();
00336
00337 boost::shared_ptr<shadow_joints::MuscleWrapper> actuator_wrapper = boost::static_pointer_cast<shadow_joints::MuscleWrapper>(joint->actuator_wrapper);
00338
00339 if (joint->has_actuator)
00340 {
00341 const sr_actuator::SrMuscleActuator* sr_muscle_actuator = static_cast<sr_actuator::SrMuscleActuator*>(actuator_wrapper->actuator);
00342 const sr_actuator::SrMuscleActuatorState* state = &(sr_muscle_actuator->state_);
00343
00344 if (actuator_wrapper->actuator_ok)
00345 {
00346 if (actuator_wrapper->bad_data)
00347 {
00348 d.summary(d.WARN, "WARNING, bad CAN data received");
00349
00350 d.clear();
00351 d.addf("Muscle ID 0", "%d", actuator_wrapper->muscle_id[0]);
00352 d.addf("Muscle driver ID 0", "%d", actuator_wrapper->muscle_driver_id[0]);
00353 d.addf("Muscle ID 1", "%d", actuator_wrapper->muscle_id[1]);
00354 d.addf("Muscle driver ID 1", "%d", actuator_wrapper->muscle_driver_id[1]);
00355 }
00356 else
00357 {
00358 d.summary(d.OK, "OK");
00359
00360 d.clear();
00361 d.addf("Muscle ID 0", "%d", actuator_wrapper->muscle_id[0]);
00362 d.addf("Muscle driver ID 0", "%d", actuator_wrapper->muscle_driver_id[0]);
00363 d.addf("Muscle ID 1", "%d", actuator_wrapper->muscle_id[1]);
00364 d.addf("Muscle driver ID 1", "%d", actuator_wrapper->muscle_driver_id[1]);
00365
00366 d.addf("Unfiltered position", "%f", state->position_unfiltered_);
00367
00368 d.addf("Last Commanded Valve 0", "%d", state->last_commanded_valve_[0]);
00369 d.addf("Last Commanded Valve 1", "%d", state->last_commanded_valve_[1]);
00370
00371 d.addf("Unfiltered Pressure 0", "%u", state->pressure_[0]);
00372 d.addf("Unfiltered Pressure 1", "%u", state->pressure_[1]);
00373
00374 d.addf("Position", "%f", state->position_);
00375 }
00376 }
00377 else
00378 {
00379 d.summary(d.ERROR, "Motor error");
00380 d.clear();
00381 d.addf("Muscle ID 0", "%d", actuator_wrapper->muscle_id[0]);
00382 d.addf("Muscle driver ID 0", "%d", actuator_wrapper->muscle_driver_id[0]);
00383 d.addf("Muscle ID 1", "%d", actuator_wrapper->muscle_id[1]);
00384 d.addf("Muscle driver ID 1", "%d", actuator_wrapper->muscle_driver_id[1]);
00385 }
00386 }
00387 else
00388 {
00389 d.summary(d.OK, "No motor associated to this joint");
00390 d.clear();
00391 }
00392 vec.push_back(d);
00393
00394 }
00395
00396
00397 boost::ptr_vector<shadow_joints::MuscleDriver>::iterator muscle_driver = this->muscle_drivers_vector_.begin();
00398 for (; muscle_driver != this->muscle_drivers_vector_.end(); ++muscle_driver)
00399 {
00400 std::stringstream name;
00401 name.str("");
00402 name << "Muscle driver " << muscle_driver->muscle_driver_id;
00403 d.name = name.str();
00404
00405 if (muscle_driver->driver_ok)
00406 {
00407 if (muscle_driver->bad_data)
00408 {
00409 d.summary(d.WARN, "WARNING, bad CAN data received");
00410
00411 d.clear();
00412 d.addf("Muscle Driver ID", "%d", muscle_driver->muscle_driver_id);
00413 }
00414 else
00415 {
00416 d.summary(d.OK, "OK");
00417
00418 d.clear();
00419 d.addf("Muscle Driver ID", "%d", muscle_driver->muscle_driver_id);
00420 d.addf("Serial Number", "%d", muscle_driver->serial_number );
00421 d.addf("Assembly date", "%d / %d / %d", muscle_driver->assembly_date_day, muscle_driver->assembly_date_month, muscle_driver->assembly_date_year );
00422
00423 d.addf("Number of CAN messages received", "%lld", muscle_driver->can_msgs_received_);
00424 d.addf("Number of CAN messages transmitted", "%lld", muscle_driver->can_msgs_transmitted_);
00425
00426 if (muscle_driver->firmware_modified_)
00427 d.addf("Firmware svn revision (server / pic / modified)", "%d / %d / True",
00428 muscle_driver->server_firmware_svn_revision_, muscle_driver->pic_firmware_svn_revision_);
00429 else
00430 d.addf("Firmware svn revision (server / pic / modified)", "%d / %d / False",
00431 muscle_driver->server_firmware_svn_revision_, muscle_driver->pic_firmware_svn_revision_);
00432 }
00433 }
00434 else
00435 {
00436 d.summary(d.ERROR, "Muscle Driver error");
00437 d.clear();
00438 d.addf("Muscle Driver ID", "%d", muscle_driver->muscle_driver_id);
00439 }
00440
00441 vec.push_back(d);
00442 }
00443
00444 }
00445
00446
00447 template <class StatusType, class CommandType>
00448 void SrMuscleRobotLib<StatusType, CommandType>::read_additional_muscle_data(boost::ptr_vector<shadow_joints::Joint>::iterator joint_tmp, StatusType* status_data)
00449 {
00450 int packet_offset_muscle_0 = 0;
00451 int packet_offset_muscle_1 = 0;
00452
00453 boost::shared_ptr<shadow_joints::MuscleWrapper> muscle_wrapper = boost::static_pointer_cast<shadow_joints::MuscleWrapper>(joint_tmp->actuator_wrapper);
00454
00455
00456 if (muscle_wrapper->muscle_id[0] >= NUM_PRESSURE_SENSORS_PER_MESSAGE)
00457 {
00458 packet_offset_muscle_0 = 1;
00459 }
00460
00461 if (muscle_wrapper->muscle_id[1] >= NUM_PRESSURE_SENSORS_PER_MESSAGE)
00462 {
00463 packet_offset_muscle_1 = 1;
00464 }
00465
00466
00467
00468
00469 muscle_wrapper->actuator_ok = sr_math_utils::is_bit_mask_index_true(status_data->which_muscle_data_arrived,
00470 muscle_wrapper->muscle_driver_id[0] * 2 + packet_offset_muscle_0)
00471 && sr_math_utils::is_bit_mask_index_true(status_data->which_muscle_data_arrived,
00472 muscle_wrapper->muscle_driver_id[1] * 2 + packet_offset_muscle_1);
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483 if (muscle_wrapper->actuator_ok)
00484 {
00485 sr_actuator::SrMuscleActuator* actuator = static_cast<sr_actuator::SrMuscleActuator*>(joint_tmp->actuator_wrapper->actuator);
00486 shadow_joints::MuscleWrapper* actuator_wrapper = static_cast<shadow_joints::MuscleWrapper*>(joint_tmp->actuator_wrapper.get());
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526 unsigned int p1 = 0;
00527 switch (status_data->muscle_data_type)
00528 {
00529 case MUSCLE_DATA_PRESSURE:
00530
00531 for (int i=0; i<2; ++i)
00532 {
00533 p1 = get_muscle_pressure(muscle_wrapper->muscle_driver_id[i], muscle_wrapper->muscle_id[i], status_data);
00534 std::string name = joint_tmp->joint_name + "_" + boost::lexical_cast<std::string>(i);
00535
00536
00537 pressure_calibration_tmp_ = pressure_calibration_map_.find(name);
00538 double bar = pressure_calibration_tmp_->compute(static_cast<double>(p1));
00539 if (bar < 0.0)
00540 bar = 0.0;
00541 actuator->state_.pressure_[i] = static_cast<int16u>(bar);
00542 }
00543
00544
00545
00546
00547
00548
00549 #ifdef DEBUG_PUBLISHER
00550 if( actuator_wrapper->muscle_id[0] == 8 )
00551 {
00552
00553
00554
00555 }
00556 #endif
00557 break;
00558
00559
00560 default:
00561 break;
00562 }
00563 }
00564 }
00565
00566
00567 template <class StatusType, class CommandType>
00568 unsigned int SrMuscleRobotLib<StatusType, CommandType>::get_muscle_pressure(int muscle_driver_id, int muscle_id, StatusType *status_data)
00569 {
00570 unsigned int muscle_pressure = 0;
00571 int packet_offset = 0;
00572 int muscle_index = muscle_id;
00573
00574
00575 if (muscle_id >= NUM_PRESSURE_SENSORS_PER_MESSAGE)
00576 {
00577 packet_offset = 1;
00578 muscle_index = muscle_id - NUM_PRESSURE_SENSORS_PER_MESSAGE;
00579 }
00580
00581 switch(muscle_index)
00582 {
00583 case 0:
00584 muscle_pressure = (status_data->muscle_data_packet[muscle_driver_id * 2 + packet_offset].packed.pressure0_H << 8)
00585 + (status_data->muscle_data_packet[muscle_driver_id * 2 + packet_offset].packed.pressure0_M << 4)
00586 + status_data->muscle_data_packet[muscle_driver_id * 2 + packet_offset].packed.pressure0_L;
00587 break;
00588
00589 case 1:
00590 muscle_pressure = (status_data->muscle_data_packet[muscle_driver_id * 2 + packet_offset].packed.pressure1_H << 8)
00591 + (status_data->muscle_data_packet[muscle_driver_id * 2 + packet_offset].packed.pressure1_M << 4)
00592 + status_data->muscle_data_packet[muscle_driver_id * 2 + packet_offset].packed.pressure1_L;
00593 break;
00594
00595 case 2:
00596 muscle_pressure = (status_data->muscle_data_packet[muscle_driver_id * 2 + packet_offset].packed.pressure2_H << 8)
00597 + (status_data->muscle_data_packet[muscle_driver_id * 2 + packet_offset].packed.pressure2_M << 4)
00598 + status_data->muscle_data_packet[muscle_driver_id * 2 + packet_offset].packed.pressure2_L;
00599 break;
00600
00601 case 3:
00602 muscle_pressure = (status_data->muscle_data_packet[muscle_driver_id * 2 + packet_offset].packed.pressure3_H << 8)
00603 + (status_data->muscle_data_packet[muscle_driver_id * 2 + packet_offset].packed.pressure3_M << 4)
00604 + status_data->muscle_data_packet[muscle_driver_id * 2 + packet_offset].packed.pressure3_L;
00605 break;
00606
00607 case 4:
00608 muscle_pressure = (status_data->muscle_data_packet[muscle_driver_id * 2 + packet_offset].packed.pressure4_H << 8)
00609 + (status_data->muscle_data_packet[muscle_driver_id * 2 + packet_offset].packed.pressure4_M << 4)
00610 + status_data->muscle_data_packet[muscle_driver_id * 2 + packet_offset].packed.pressure4_L;
00611 break;
00612
00613 default:
00614 ROS_ERROR("Incorrect muscle index: %d", muscle_index);
00615 break;
00616 }
00617
00618 return muscle_pressure;
00619 }
00620
00621 template <class StatusType, class CommandType>
00622 void SrMuscleRobotLib<StatusType, CommandType>::read_muscle_driver_data(boost::ptr_vector<shadow_joints::MuscleDriver>::iterator muscle_driver_tmp, StatusType* status_data)
00623 {
00624
00625
00626 muscle_driver_tmp->driver_ok = sr_math_utils::is_bit_mask_index_true(status_data->which_muscle_data_arrived,
00627 muscle_driver_tmp->muscle_driver_id * 2 );
00628
00629
00630
00631
00632
00633
00634
00635 if (muscle_driver_tmp->driver_ok)
00636 {
00637
00638 set_muscle_driver_data_received_flags(status_data->muscle_data_type, muscle_driver_tmp->muscle_driver_id);
00639
00640 switch (status_data->muscle_data_type)
00641 {
00642 case MUSCLE_DATA_PRESSURE:
00643
00644 break;
00645
00646 case MUSCLE_DATA_CAN_STATS:
00647
00648
00649
00650 muscle_driver_tmp->can_msgs_received_ = sr_math_utils::counter_with_overflow(
00651 muscle_driver_tmp->can_msgs_received_,
00652 static_cast<int16u>(status_data->muscle_data_packet[muscle_driver_tmp->muscle_driver_id * 2].misc.can_msgs_rx));
00653 muscle_driver_tmp->can_msgs_transmitted_ = sr_math_utils::counter_with_overflow(
00654 muscle_driver_tmp->can_msgs_transmitted_,
00655 static_cast<int16u>(status_data->muscle_data_packet[muscle_driver_tmp->muscle_driver_id * 2].misc.can_msgs_tx));
00656
00657
00658 muscle_driver_tmp->can_err_rx = static_cast<unsigned int>(status_data->muscle_data_packet[muscle_driver_tmp->muscle_driver_id * 2].misc.can_err_rx);
00659 muscle_driver_tmp->can_err_tx = static_cast<unsigned int>(status_data->muscle_data_packet[muscle_driver_tmp->muscle_driver_id * 2].misc.can_err_tx);
00660 break;
00661
00662 case MUSCLE_DATA_SLOW_MISC:
00663
00664
00665
00666
00667 muscle_driver_tmp->pic_firmware_svn_revision_ = static_cast<unsigned int>(status_data->muscle_data_packet[muscle_driver_tmp->muscle_driver_id * 2].slow_0.SVN_revision);
00668 muscle_driver_tmp->server_firmware_svn_revision_ = static_cast<unsigned int>(status_data->muscle_data_packet[muscle_driver_tmp->muscle_driver_id * 2].slow_0.SVN_server);
00669 muscle_driver_tmp->firmware_modified_ = static_cast<bool>(static_cast<unsigned int>(status_data->muscle_data_packet[muscle_driver_tmp->muscle_driver_id * 2].slow_0.SVN_modified));
00670
00671 muscle_driver_tmp->serial_number = static_cast<unsigned int>(status_data->muscle_data_packet[muscle_driver_tmp->muscle_driver_id * 2 + 1].slow_1.serial_number);
00672 muscle_driver_tmp->assembly_date_year = static_cast<unsigned int>(status_data->muscle_data_packet[muscle_driver_tmp->muscle_driver_id * 2 + 1].slow_1.assembly_date_YYYY);
00673 muscle_driver_tmp->assembly_date_month = static_cast<unsigned int>(status_data->muscle_data_packet[muscle_driver_tmp->muscle_driver_id * 2 + 1].slow_1.assembly_date_MM);
00674 muscle_driver_tmp->assembly_date_day = static_cast<unsigned int>(status_data->muscle_data_packet[muscle_driver_tmp->muscle_driver_id * 2 + 1].slow_1.assembly_date_DD);
00675 break;
00676
00677 default:
00678 break;
00679 }
00680
00681
00682 boost::mutex::scoped_lock l(*lock_init_timeout_);
00683
00684
00685 if (muscle_current_state == operation_mode::device_update_state::INITIALIZATION)
00686 {
00687 if ((check_muscle_driver_data_received_flags())
00688 || (muscle_updater_->update_state == operation_mode::device_update_state::OPERATION))
00689 {
00690 muscle_updater_->update_state = operation_mode::device_update_state::OPERATION;
00691 muscle_current_state = operation_mode::device_update_state::OPERATION;
00692
00693 check_init_timeout_timer.stop();
00694
00695 ROS_INFO("All muscle data initialized.");
00696 }
00697 }
00698 }
00699 }
00700
00701 template <class StatusType, class CommandType>
00702 inline void SrMuscleRobotLib<StatusType, CommandType>::set_muscle_driver_data_received_flags(unsigned int msg_type, int muscle_driver_id)
00703 {
00704 if (muscle_current_state == operation_mode::device_update_state::INITIALIZATION)
00705 {
00706 std::map<unsigned int, unsigned int>::iterator it = from_muscle_driver_data_received_flags_.find(msg_type);
00707 if (it != from_muscle_driver_data_received_flags_.end())
00708 {
00709 it->second = it->second | (1 << muscle_driver_id);
00710 }
00711 }
00712 }
00713
00714 template <class StatusType, class CommandType>
00715 inline bool SrMuscleRobotLib<StatusType, CommandType>::check_muscle_driver_data_received_flags()
00716 {
00717 std::map<unsigned int, unsigned int>::iterator it = from_muscle_driver_data_received_flags_.begin();
00718 for (;it != from_muscle_driver_data_received_flags_.end(); ++it)
00719 {
00720
00721 if (it->second != (1 << NUM_MUSCLE_DRIVERS) -1)
00722 return false;
00723 }
00724 return true;
00725 }
00726
00727 template <class StatusType, class CommandType>
00728 std::vector<std::pair<std::string, bool> > SrMuscleRobotLib<StatusType, CommandType>::humanize_flags(int flag)
00729 {
00730 std::vector<std::pair<std::string, bool> > flags;
00731
00732
00733 for (unsigned int i = 0; i < 16; ++i)
00734 {
00735 std::pair<std::string, bool> new_flag;
00736
00737 if (sr_math_utils::is_bit_mask_index_true(flag, i))
00738 {
00739 if (sr_math_utils::is_bit_mask_index_true(SERIOUS_ERROR_FLAGS, i))
00740 new_flag.second = true;
00741 else
00742 new_flag.second = false;
00743
00744 new_flag.first = error_flag_names[i];
00745 flags.push_back(new_flag);
00746 }
00747 }
00748 return flags;
00749 }
00750
00751 template <class StatusType, class CommandType>
00752 void SrMuscleRobotLib<StatusType, CommandType>::reinitialize_motors()
00753 {
00754
00755 boost::mutex::scoped_lock l(*lock_init_timeout_);
00756
00757
00758 check_init_timeout_timer.stop();
00759
00760 muscle_updater_ = boost::shared_ptr<generic_updater::MuscleUpdater<CommandType> >(new generic_updater::MuscleUpdater<CommandType>(muscle_update_rate_configs_vector, operation_mode::device_update_state::INITIALIZATION));
00761 muscle_current_state = operation_mode::device_update_state::INITIALIZATION;
00762
00763 check_init_timeout_timer.setPeriod(init_max_duration);
00764 check_init_timeout_timer.start();
00765 }
00766
00767 template <class StatusType, class CommandType>
00768 void SrMuscleRobotLib<StatusType, CommandType>::init_timer_callback(const ros::TimerEvent& event)
00769 {
00770
00771 boost::mutex::scoped_lock l(*lock_init_timeout_);
00772
00773 if(muscle_current_state == operation_mode::device_update_state::INITIALIZATION)
00774 {
00775 muscle_updater_->update_state = operation_mode::device_update_state::OPERATION;
00776 muscle_current_state = operation_mode::device_update_state::OPERATION;
00777 ROS_ERROR_STREAM("Muscle Initialization Timeout: the static information in the diagnostics may not be up to date.");
00778 }
00779 }
00780
00781
00782 template class SrMuscleRobotLib<ETHERCAT_DATA_STRUCTURE_0300_PALM_EDC_STATUS, ETHERCAT_DATA_STRUCTURE_0300_PALM_EDC_COMMAND>;
00783 }
00784
00785
00786
00787
00788
00789