36 #include <boost/foreach.hpp> 37 #include <std_msgs/Int16.h> 42 #include <sr_utilities/sr_math_utils.hpp> 45 using std::stringstream;
50 #include <boost/static_assert.hpp> 59 #define ETHERCAT_STATUS_DATA_SIZE sizeof(ETHERCAT_DATA_STRUCTURE_0240_PALM_EDC_STATUS) 60 #define ETHERCAT_COMMAND_DATA_SIZE sizeof(ETHERCAT_DATA_STRUCTURE_0240_PALM_EDC_COMMAND) 62 #define ETHERCAT_CAN_BRIDGE_DATA_SIZE sizeof(ETHERCAT_CAN_BRIDGE_DATA) 64 #define ETHERCAT_COMMAND_DATA_ADDRESS PALM_0240_ETHERCAT_COMMAND_DATA_ADDRESS 65 #define ETHERCAT_STATUS_DATA_ADDRESS PALM_0240_ETHERCAT_STATUS_DATA_ADDRESS 66 #define ETHERCAT_CAN_BRIDGE_DATA_COMMAND_ADDRESS PALM_0240_ETHERCAT_CAN_BRIDGE_DATA_COMMAND_ADDRESS 67 #define ETHERCAT_CAN_BRIDGE_DATA_STATUS_ADDRESS PALM_0240_ETHERCAT_CAN_BRIDGE_DATA_STATUS_ADDRESS 79 : zero_buffer_read(0),
81 imu_scale_change_(false)
133 ROS_INFO(
"Finished constructing the SR09 driver");
147 hw_ =
static_cast<ros_ethercat_model::RobotState *
> (hw);
150 ETHERCAT_DATA_STRUCTURE_0240_PALM_EDC_COMMAND> >(
173 <sr_robot_msgs::SetImuScale::Request, sr_robot_msgs::SetImuScale::Response>
176 <sr_robot_msgs::SetImuScale::Request, sr_robot_msgs::SetImuScale::Response>
179 ros::param::param<int>(
"/" + imu_name +
"/acc_scale",
imu_scale_acc_, 0);
180 ros::param::param<int>(
"/" + imu_name +
"/gyr_scale",
imu_scale_gyr_, 0);
188 sr_robot_msgs::SetImuScale::Response & response,
191 if (request.scale == 0 || request.scale == 1 || request.scale == 2)
197 else if (which ==
"gyr")
207 ROS_WARN_STREAM(
"Tried to set illegal value: " << (
int) request.scale);
225 d.name = prefix +
"EtherCAT Dual CAN Palm";
228 hwid << sh_->get_product_code() <<
"-" << sh_->get_serial();
229 d.hardware_id = hwid.str();
232 d.
addf(
"Position",
"%02d", sh_->get_ring_position());
233 d.
addf(
"Product Code",
"%d", sh_->get_product_code());
234 d.
addf(
"Serial Number",
"%d", sh_->get_serial());
235 d.
addf(
"Revision",
"%d", sh_->get_revision());
238 d.
addf(
"PIC idle time (in microsecs)",
"%d",
sr_hand_lib->main_pic_idle_time);
239 d.
addf(
"Min PIC idle time (since last diagnostics)",
"%d",
sr_hand_lib->main_pic_idle_time_min);
243 this->ethercatDiagnostics(d, 2);
273 SrEdc::packCommand(buffer, halt, reset);
275 ETHERCAT_DATA_STRUCTURE_0240_PALM_EDC_COMMAND *
command =
276 reinterpret_cast<ETHERCAT_DATA_STRUCTURE_0240_PALM_EDC_COMMAND *
>(buffer);
305 ROS_DEBUG(
"Sending command : Type : 0x%02X ; data : 0x%04X 0x%04X 0x%04X 0x%04X 0x%04X 0x%04X 0x%04X 0x%04X 0x%04X " 306 "0x%04X 0x%04X 0x%04X 0x%04X 0x%04X 0x%04X 0x%04X 0x%04X 0x%04X 0x%04X 0x%04X",
307 command->to_motor_data_type,
308 command->motor_data[0],
309 command->motor_data[1],
310 command->motor_data[2],
311 command->motor_data[3],
312 command->motor_data[4],
313 command->motor_data[5],
314 command->motor_data[6],
315 command->motor_data[7],
316 command->motor_data[8],
317 command->motor_data[9],
318 command->motor_data[10],
319 command->motor_data[11],
320 command->motor_data[12],
321 command->motor_data[13],
322 command->motor_data[14],
323 command->motor_data[15],
324 command->motor_data[16],
325 command->motor_data[17],
326 command->motor_data[18],
327 command->motor_data[19]);
334 void SR09::readImu(ETHERCAT_DATA_STRUCTURE_0240_PALM_EDC_STATUS * status_data)
344 for (
size_t x = 0; x < 2; ++x)
346 if (status_data->sensors[
ACCX + 0] == 0)
350 if (status_data->sensors[
GYRX + 0] == 0)
357 imu_state_->data_.linear_acceleration[0] = acc_multiplier *
static_cast<int16s>(status_data->sensors[
ACCX]);
358 imu_state_->data_.linear_acceleration[1] = acc_multiplier *
static_cast<int16s>(status_data->sensors[
ACCY]);
359 imu_state_->data_.linear_acceleration[2] = acc_multiplier *
static_cast<int16s>(status_data->sensors[
ACCZ]);
361 imu_state_->data_.angular_velocity[0] = gyr_multiplier *
static_cast<int16s>(status_data->sensors[
GYRX]);
362 imu_state_->data_.angular_velocity[1] = gyr_multiplier *
static_cast<int16s>(status_data->sensors[
GYRY]);
363 imu_state_->data_.angular_velocity[2] = gyr_multiplier *
static_cast<int16s>(status_data->sensors[
GYRZ]);
365 for (
size_t x = 0; x < 9; ++x)
367 imu_state_->data_.linear_acceleration_covariance[x] = 0.0;
368 imu_state_->data_.angular_velocity_covariance[x] = 0.0;
369 imu_state_->data_.orientation_covariance[x] = 0.0;
395 ETHERCAT_DATA_STRUCTURE_0240_PALM_EDC_STATUS *status_data =
396 reinterpret_cast<ETHERCAT_DATA_STRUCTURE_0240_PALM_EDC_STATUS *
>(this_buffer + command_size_);
397 ETHERCAT_CAN_BRIDGE_DATA *can_data =
reinterpret_cast<ETHERCAT_CAN_BRIDGE_DATA *
>(this_buffer + command_size_ +
400 static unsigned int num_rxed_packets = 0;
417 debug_publisher->msg_.motor_data_type.data =
static_cast<int> (status_data->motor_data_type);
419 debug_publisher->msg_.which_motor_data_arrived = status_data->which_motor_data_arrived;
420 debug_publisher->msg_.which_motor_data_had_errors = status_data->which_motor_data_had_errors;
424 for (
unsigned int i = 0; i < 10; ++i)
426 debug_publisher->msg_.motor_data_packet_torque.push_back(status_data->motor_data_packet[i].torque);
427 debug_publisher->msg_.motor_data_packet_misc.push_back(status_data->motor_data_packet[i].misc);
431 static_cast<int32u>(status_data->tactile_data_type));
433 static_cast<int16u> (status_data->tactile_data_valid));
435 for (
unsigned int i = 0; i < 5; ++i)
438 static_cast<unsigned int> (static_cast<int16u> (status_data->tactile[i].word[0])));
450 float percentage_packet_loss = 100.f * (
static_cast<float>(
zero_buffer_read) /
451 static_cast<float>(num_rxed_packets));
453 ROS_DEBUG(
"Reception error detected : %d errors out of %d rxed packets (%2.3f%%) ; idle time %dus",
454 zero_buffer_read, num_rxed_packets, percentage_packet_loss, status_data->idle_time_us);
473 std_msgs::Float64MultiArray extra_analog_msg;
474 extra_analog_msg.layout.dim.resize(3);
475 extra_analog_msg.data.resize(3 + 3 + 4);
476 std::vector<double>
data;
478 extra_analog_msg.layout.dim[0].label =
"accelerometer";
479 extra_analog_msg.layout.dim[0].size = 3;
480 extra_analog_msg.data[0] = status_data->sensors[
ACCX];
481 extra_analog_msg.data[1] = status_data->sensors[
ACCY];
482 extra_analog_msg.data[2] = status_data->sensors[
ACCZ];
484 extra_analog_msg.layout.dim[1].label =
"gyrometer";
485 extra_analog_msg.layout.dim[1].size = 3;
486 extra_analog_msg.data[3] = status_data->sensors[
GYRX];
487 extra_analog_msg.data[4] = status_data->sensors[
GYRY];
488 extra_analog_msg.data[5] = status_data->sensors[
GYRZ];
490 extra_analog_msg.layout.dim[2].label =
"analog_inputs";
491 extra_analog_msg.layout.dim[2].size = 4;
492 extra_analog_msg.data[6] = status_data->sensors[
ANA0];
493 extra_analog_msg.data[7] = status_data->sensors[
ANA1];
494 extra_analog_msg.data[8] = status_data->sensors[
ANA2];
495 extra_analog_msg.data[9] = status_data->sensors[
ANA3];
531 int motor_id_tmp = board_id;
532 if (motor_id_tmp > 9)
542 *board_can_id = motor_id_tmp;
ros::NodeHandle nh_tilde_
virtual int initialize(hardware_interface::HardwareInterface *hw, bool allow_unprogrammed=true)
void summary(unsigned char lvl, const std::string s)
ros::ServiceServer imu_gyr_scale_server_
boost::shared_ptr< shadow_robot::SrMotorHandLib< ETHERCAT_DATA_STRUCTURE_0240_PALM_EDC_STATUS, ETHERCAT_DATA_STRUCTURE_0240_PALM_EDC_COMMAND > > sr_hand_lib
virtual void construct(EtherCAT_SlaveHandler *sh, int &start_address)
Construct function, run at startup to set SyncManagers and FMMUs.
unsigned int zero_buffer_read
This is a ROS driver for Shadow Robot #9 EtherCAT product ID.
ros_ethercat_model::RobotState * hw_
#define ETHERCAT_STATUS_DATA_SIZE
ros::ServiceServer imu_acc_scale_server_
virtual void packCommand(unsigned char *buffer, bool halt, bool reset)
packs the commands before sending them to the EtherCAT bus
virtual void multiDiagnostics(vector< diagnostic_msgs::DiagnosticStatus > &vec, unsigned char *buffer)
This function gives some diagnostics data.
virtual void reinitialize_boards()
This function will call the reinitialization function for the boards attached to the CAN bus...
void addf(const std::string &key, const char *format,...)
virtual void get_board_id_and_can_bus(int board_id, int *can_bus, unsigned int *board_can_id)
boost::shared_ptr< realtime_tools::RealtimePublisher< sr_robot_msgs::EthercatDebug > > debug_publisher
Debug real time publisher: publishes the raw ethercat data.
BOOST_STATIC_ASSERT(sizeof(EDC_COMMAND)==4)
#define ETHERCAT_COMMAND_DATA_ADDRESS
EDC_COMMAND_CAN_DIRECT_MODE
virtual void construct(EtherCAT_SlaveHandler *sh, int &start_address, unsigned int ethercat_command_data_size, unsigned int ethercat_status_data_size, unsigned int ethercat_can_bridge_data_size, unsigned int ethercat_command_data_address, unsigned int ethercat_status_data_address, unsigned int ethercat_can_bridge_data_command_address, unsigned int ethercat_can_bridge_data_status_address)
Construct function, run at startup to set SyncManagers and FMMUs.
ROSLIB_DECL std::string command(const std::string &cmd)
PLUGINLIB_EXPORT_CLASS(SR09, EthercatDevice)
virtual bool unpackState(unsigned char *this_buffer, unsigned char *prev_buffer)
This functions receives data from the EtherCAT bus.
ros::NodeHandle nodehandle_
#define IMU_COMMAND_SET_SCALE
virtual int initialize(hardware_interface::HardwareInterface *hw, bool allow_unprogrammed=true)
#define ETHERCAT_COMMAND_DATA_SIZE
SR09()
Constructor of the SR09 driver.
void build_CAN_message(ETHERCAT_CAN_BRIDGE_DATA *message)
#define ROS_WARN_STREAM(args)
#define ETHERCAT_CAN_BRIDGE_DATA_COMMAND_ADDRESS
bool can_data_is_ack(ETHERCAT_CAN_BRIDGE_DATA *packet)
This function checks if the can packet in the unpackState() this_buffer is an ACK.
void readImu(ETHERCAT_DATA_STRUCTURE_0240_PALM_EDC_STATUS *status)
This funcion reads the ethercat status and fills the imu_state with the relevant values.
ros_ethercat_model::ImuState * imu_state_
#define ETHERCAT_CAN_BRIDGE_DATA_SIZE
boost::shared_ptr< realtime_tools::RealtimePublisher< std_msgs::Float64MultiArray > > extra_analog_inputs_publisher
Extra analog inputs real time publisher (+ accelerometer and gyroscope)
std::string device_joint_prefix_
#define ETHERCAT_STATUS_DATA_ADDRESS
#define ETHERCAT_CAN_BRIDGE_DATA_STATUS_ADDRESS
bool imu_scale_callback_(sr_robot_msgs::SetImuScale::Request &request, sr_robot_msgs::SetImuScale::Response &response, const char *which)