00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00024 #include <sr_ronex_drivers/sr_board_adc16.hpp>
00025 #include <ros_ethercat_model/robot_state.hpp>
00026 #include <ros_ethercat_hardware/ethercat_hardware.h>
00027
00028 #include <sstream>
00029 #include <iomanip>
00030 #include <boost/lexical_cast.hpp>
00031 #include <math.h>
00032 #include <string>
00033
00034 #include "sr_ronex_drivers/ronex_utils.hpp"
00035
00036 PLUGINLIB_EXPORT_CLASS(SrBoardADC16, EthercatDevice);
00037
00038 const std::string SrBoardADC16::product_alias_ = "adc16";
00039 using boost::lexical_cast;
00040
00041
00042 SrBoardADC16::SrBoardADC16() :
00043 node_("~"), cycle_count_(0), has_stacker_(false)
00044 {}
00045
00046 SrBoardADC16::~SrBoardADC16()
00047 {
00048
00049 string device_id = "/ronex/devices/" + lexical_cast<string>(parameter_id_);
00050 ros::param::del(device_id);
00051
00052 string adc16_device_name = "/ronex/adc16/" + serial_number_;
00053 ros::param::del(adc16_device_name);
00054
00055 string controller_name = "/ronex_" + serial_number_ + "_passthrough";
00056 }
00057
00058 void SrBoardADC16::construct(EtherCAT_SlaveHandler *sh, int &start_address)
00059 {
00060 sh_ = sh;
00061 serial_number_ = ronex::get_serial_number(sh);
00062
00063
00064 std::string path_to_alias, alias;
00065 path_to_alias = "/ronex/mapping/" + serial_number_;
00066 if ( ros::param::get(path_to_alias, alias))
00067 {
00068 ronex_id_ = alias;
00069 }
00070 else
00071 {
00072
00073 ronex_id_ = serial_number_;
00074 }
00075
00076 device_name_ = ronex::build_name(product_alias_, ronex_id_);
00077
00078 command_base_ = start_address;
00079 command_size_ = COMMAND_ARRAY_SIZE_BYTES;
00080
00081 start_address += command_size_;
00082 status_base_ = start_address;
00083 status_size_ = STATUS_ARRAY_SIZE_BYTES;
00084
00085 start_address += status_size_;
00086
00087
00088
00089
00090
00091
00092 if ( (PROTOCOL_TYPE) == (EC_BUFFERED) )
00093 {
00094 ROS_INFO("Using EC_BUFFERED");
00095 }
00096 else if ( (PROTOCOL_TYPE) == (EC_QUEUED) )
00097 {
00098 ROS_INFO("Using EC_QUEUED");
00099 }
00100
00101 ROS_INFO("First FMMU (command) : Logical address: 0x%08X ; size: %3d bytes ; ET1200 address: 0x%08X", command_base_,
00102 command_size_, static_cast<int>(COMMAND_ADDRESS) );
00103 EC_FMMU *commandFMMU = new EC_FMMU( command_base_,
00104 command_size_,
00105 0x00,
00106 0x07,
00107 COMMAND_ADDRESS,
00108 0x00,
00109 false,
00110 true,
00111 true);
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 ROS_INFO("Second FMMU (status) : Logical address: 0x%08X ; size: %3d bytes ; ET1200 address: 0x%08X", status_base_,
00126 status_size_, static_cast<int>(STATUS_ADDRESS) );
00127 EC_FMMU *statusFMMU = new EC_FMMU( status_base_,
00128 status_size_,
00129 0x00,
00130 0x07,
00131 STATUS_ADDRESS,
00132 0x00,
00133 true,
00134 false,
00135 true);
00136
00137
00138 EtherCAT_FMMU_Config *fmmu = new EtherCAT_FMMU_Config(2);
00139
00140 (*fmmu)[0] = *commandFMMU;
00141 (*fmmu)[1] = *statusFMMU;
00142
00143 sh->set_fmmu_config(fmmu);
00144
00145 EtherCAT_PD_Config *pd = new EtherCAT_PD_Config(2);
00146
00147
00148 (*pd)[0] = EC_SyncMan(COMMAND_ADDRESS, command_size_, PROTOCOL_TYPE, EC_WRITTEN_FROM_MASTER);
00149 (*pd)[1] = EC_SyncMan(STATUS_ADDRESS, status_size_, PROTOCOL_TYPE);
00150
00151
00152 (*pd)[0].ChannelEnable = true;
00153 (*pd)[0].ALEventEnable = true;
00154 (*pd)[0].WriteEvent = true;
00155
00156 (*pd)[1].ChannelEnable = true;
00157
00158 sh->set_pd_config(pd);
00159
00160 ROS_INFO("Finished constructing the SrBoardADC16 driver");
00161 }
00162
00163 int SrBoardADC16::initialize(hardware_interface::HardwareInterface *hw, bool allow_unprogrammed)
00164 {
00165 digital_commands_ = 0;
00166 ROS_INFO("Device #%02d: Product code: %u (%#010X) , Serial #: %u (%#010X)",
00167 sh_->get_ring_position(),
00168 sh_->get_product_code(),
00169 sh_->get_product_code(),
00170 sh_->get_serial(),
00171 sh_->get_serial());
00172
00173 device_offset_ = sh_->get_ring_position();
00174
00175
00176 ros_ethercat_model::RobotState *robot_state = static_cast<ros_ethercat_model::RobotState*>(hw);
00177 robot_state->custom_hws_.insert(device_name_, new ronex::ADC16());
00178 adc16_ = static_cast<ronex::ADC16*>(robot_state->getCustomHW(device_name_));
00179
00180 build_topics_();
00181
00182 ROS_INFO_STREAM("Adding an ADC16 RoNeX module to the hardware interface: " << device_name_);
00183
00184 feedback_flag_ = 0;
00185
00186 return 0;
00187 }
00188
00189 void SrBoardADC16::packCommand(unsigned char *buffer, bool halt, bool reset)
00190 {
00191 RONEX_COMMAND_02000008* command = reinterpret_cast<RONEX_COMMAND_02000008*>(buffer);
00192
00193 if (!config_received_)
00194 {
00195 command->command_type = RONEX_COMMAND_02000008_COMMAND_TYPE_GET_CONFIG_INFO;
00196 }
00197 else if (reg_flag_)
00198 {
00199 switch (reg_state_)
00200 {
00201 case 0:
00202 if (!command_queue_.empty())
00203 {
00204 command->command_type = RONEX_COMMAND_02000008_COMMAND_TYPE_SET_REG_VAL;
00205 command->address = command_queue_.front().address;
00206 for (int i = 0; i < 3; ++i)
00207 {
00208 command->values[i] = command_queue_.front().values[i];
00209 }
00210 feedback_flag_ += 1;
00211 command_queue_.pop();
00212 }
00213 else
00214 {
00215 command->command_type = RONEX_COMMAND_02000008_COMMAND_TYPE_WRITE_REGS;
00216 reg_state_ = 1;
00217 feedback_flag_ += 1;
00218 }
00219 break;
00220 case 1:
00221 command->command_type = RONEX_COMMAND_02000008_COMMAND_TYPE_NORMAL;
00222 reg_flag_ = false;
00223 break;
00224 }
00225 }
00226
00227 else
00228 {
00229 command->command_type = RONEX_COMMAND_02000008_COMMAND_TYPE_NORMAL;
00230
00231 feedback_flag_ = 0;
00232 for (size_t i = 0; i < adc16_->command_.digital_.size(); ++i)
00233 {
00234 if (input_mode_[i])
00235 {
00236
00237 ronex::set_bit(digital_commands_, i*2, 1);
00238 }
00239 else
00240 {
00241 ronex::set_bit(digital_commands_, i*2, 0);
00242 ronex::set_bit(digital_commands_, i*2+1, adc16_->command_.digital_[i]);
00243 }
00244 }
00245 command->pin_output_states = static_cast<int32u>(digital_commands_);
00246 }
00247 }
00248
00249 bool SrBoardADC16::unpackState(unsigned char *this_buffer, unsigned char *prev_buffer)
00250 {
00251 RONEX_STATUS_02000008* status_data = reinterpret_cast<RONEX_STATUS_02000008 *>(this_buffer+ command_size_);
00252
00253
00254
00255
00256
00257
00258
00259 if (status_data->command_type == RONEX_COMMAND_02000008_COMMAND_TYPE_NORMAL)
00260 {
00261 for (size_t i = 0; i < adc16_->state_.analogue_.size(); ++i)
00262 {
00263 adc16_->state_.analogue_[i] = status_data->info_type.status_data.analogue_in[i];
00264 }
00265
00266 for (size_t i = 0; i < adc16_->state_.digital_.size(); ++i)
00267 {
00268 adc16_->state_.digital_[i] = ronex::check_bit(status_data->info_type.status_data.pin_input_states_DIO, i);
00269 }
00270
00271 int mask = 1;
00272 int count = 15;
00273 int bits_count = 0;
00274
00275
00276 for (int j = 0; j < stack; j++)
00277 {
00278 uint16_t differential = values_d_[j];
00279 uint16_t single_ended = (values_s1_[j] << 8) | values_s0_[j];
00280 uint16_t padded_single_ended = (padded_s1_[j] << 8) | padded_s0_[j];
00281 for (int n = 0; n < 8; n++)
00282 {
00283 if (differential & mask << n)
00284 {
00285 adc16_->state_.adc_[count] = status_data->info_type.status_data.adc16[bits_count].U16;
00286 adc16_->state_.adc_[count -1] = status_data->info_type.status_data.adc16[bits_count].U16;
00287 bits_count += 1;
00288 }
00289 count = count -2;
00290 }
00291 count = ((j + 1) * 16) - 1;
00292 for (int n = 0; n < 16; n++)
00293 {
00294 if (single_ended & mask << n)
00295 {
00296 adc16_->state_.adc_[count] = status_data->info_type.status_data.adc16[bits_count].U16;
00297 bits_count += 1;
00298 }
00299 else if (padded_single_ended & mask << n)
00300 {
00301 bits_count += 1;
00302 }
00303 count -= 1;
00304 }
00305 }
00306 }
00307 else if (status_data->command_type == RONEX_COMMAND_02000008_COMMAND_TYPE_SET_REG_VAL)
00308 {
00309 adc16_->state_.address_ = status_data->info_type.register_feedback.address;
00310
00311
00312 if (((feedback_flag_ == 2) & (adc16_->state_.address_ != 4)) | ((feedback_flag_ == 3) &
00313 (adc16_->state_.address_ != 5)) | ((feedback_flag_ == 4) & (adc16_->state_.address_ != 3)))
00314 {
00315 reg_state_ = 0;
00316 command_queue_ = queue_backup_;
00317 }
00318 }
00319 else if (status_data->command_type == RONEX_COMMAND_02000008_COMMAND_TYPE_GET_CONFIG_INFO)
00320 {
00321 if (adc16_->state_.analogue_.empty())
00322 {
00323 size_t nb_adc_pub;
00324
00325
00326
00327 if (status_data->info_type.config_info.flags & RONEX_02000008_FLAGS_STACKER_0_PRESENT)
00328 {
00329 has_stacker_ = true;
00330 nb_adc_pub = NUM_ADC16_INPUTS / 3;
00331 }
00332 if (status_data->info_type.config_info.flags & RONEX_02000008_FLAGS_STACKER_1_PRESENT)
00333 {
00334 has_stacker_ = true;
00335 nb_adc_pub = (NUM_ADC16_INPUTS * 2) / 3;
00336 }
00337 if (status_data->info_type.config_info.flags & RONEX_02000008_FLAGS_STACKER_2_PRESENT)
00338 {
00339 has_stacker_ = true;
00340 nb_adc_pub = NUM_ADC16_INPUTS;
00341 }
00342
00343
00344 adc16_->state_.analogue_.resize(NUM_ANALOGUE_INPUTS);
00345 adc16_->state_.digital_.resize(NUM_DIGITAL_IO);
00346 adc16_->state_.adc_.resize(nb_adc_pub);
00347 adc16_->command_.digital_.resize(NUM_DIGITAL_IO);
00348
00349 input_mode_.assign(NUM_DIGITAL_IO, true);
00350 pin_mode_.assign(nb_adc_pub, 0);
00351
00352
00353 state_msg_.analogue.resize(NUM_ANALOGUE_INPUTS);
00354 state_msg_.digital.resize(NUM_DIGITAL_IO);
00355 state_msg_.adc.resize(nb_adc_pub);
00356 state_msg_.input_mode.resize(NUM_DIGITAL_IO);
00357
00358
00359
00360
00361 dynamic_reconfigure_server_.reset(
00362 new dynamic_reconfigure::Server<sr_ronex_drivers::ADC16Config>(ros::NodeHandle(device_name_)));
00363 function_cb_ = boost::bind(&SrBoardADC16::dynamic_reconfigure_cb, this, _1, _2);
00364 dynamic_reconfigure_server_->setCallback(function_cb_);
00365 }
00366
00367 config_received_ = true;
00368 }
00369
00370 adc16_->state_.command_type_ = status_data->command_type;
00371
00372
00373 if (cycle_count_ > 9)
00374 {
00375 state_msg_.header.stamp = ros::Time::now();
00376
00377
00378 for (size_t i = 0; i < adc16_->state_.analogue_.size(); ++i)
00379 {
00380 state_msg_.analogue[i] = adc16_->state_.analogue_[i];
00381 }
00382
00383 for (size_t i = 0; i < adc16_->state_.digital_.size(); ++i)
00384 {
00385 state_msg_.digital[i] = adc16_->state_.digital_[i];
00386 state_msg_.input_mode[i] = input_mode_[i];
00387 }
00388 for (size_t i = 0; i < adc16_->state_.adc_.size(); ++i)
00389 {
00390 state_msg_.adc[i] = adc16_->state_.adc_[i];
00391 }
00392
00393 state_msg_.command_type = adc16_->state_.command_type_;
00394
00395
00396 if ( state_publisher_->trylock() )
00397 {
00398 state_publisher_->msg_ = state_msg_;
00399 state_publisher_->unlockAndPublish();
00400 }
00401
00402 cycle_count_ = 0;
00403 }
00404
00405 cycle_count_++;
00406 return true;
00407 }
00408
00409 void SrBoardADC16::diagnostics(diagnostic_updater::DiagnosticStatusWrapper &d, unsigned char *buffer)
00410 {
00411 d.name = device_name_;
00412 d.summary(d.OK, "OK");
00413 d.hardware_id = serial_number_;
00414
00415 d.clear();
00416 if (has_stacker_)
00417 d.addf("Stacker Board", "True");
00418 else
00419 d.addf("Stacker Board", "False");
00420 }
00421
00422 void SrBoardADC16::dynamic_reconfigure_cb(sr_ronex_drivers::ADC16Config &config, uint32_t level)
00423 {
00424
00425
00426 if (adc16_->command_.digital_.size() > 0)
00427 input_mode_[0] = config.input_mode_0;
00428 if (adc16_->command_.digital_.size() > 1)
00429 input_mode_[1] = config.input_mode_1;
00430 if (adc16_->command_.digital_.size() > 2)
00431 input_mode_[2] = config.input_mode_2;
00432 if (adc16_->command_.digital_.size() > 3)
00433 input_mode_[3] = config.input_mode_3;
00434 if (adc16_->command_.digital_.size() > 4)
00435 input_mode_[4] = config.input_mode_4;
00436 if (adc16_->command_.digital_.size() > 5)
00437 input_mode_[5] = config.input_mode_5;
00438
00439 stack = 0;
00440
00441
00442 if (adc16_->state_.adc_.size() >= 16)
00443 {
00444 pin_mode_[0] = config.pins_0_1;
00445 pin_mode_[1] = config.pins_2_3;
00446 pin_mode_[2] = config.pins_4_5;
00447 pin_mode_[3] = config.pins_6_7;
00448 pin_mode_[4] = config.pins_8_9;
00449 pin_mode_[5] = config.pins_10_11;
00450 pin_mode_[6] = config.pins_12_13;
00451 pin_mode_[7] = config.pins_14_15;
00452 stack = 1;
00453 }
00454 if (adc16_->state_.adc_.size() >= 32)
00455 {
00456 pin_mode_[8] = config.pins_16_17;
00457 pin_mode_[9] = config.pins_18_19;
00458 pin_mode_[10] = config.pins_20_21;
00459 pin_mode_[11] = config.pins_22_23;
00460 pin_mode_[12] = config.pins_24_25;
00461 pin_mode_[13] = config.pins_26_27;
00462 pin_mode_[14] = config.pins_28_29;
00463 pin_mode_[15] = config.pins_30_31;
00464 stack = 2;
00465 }
00466 if (adc16_->state_.adc_.size() == 48)
00467 {
00468 pin_mode_[16] = config.pins_32_33;
00469 pin_mode_[17] = config.pins_34_35;
00470 pin_mode_[18] = config.pins_36_37;
00471 pin_mode_[19] = config.pins_38_39;
00472 pin_mode_[20] = config.pins_40_41;
00473 pin_mode_[21] = config.pins_42_43;
00474 pin_mode_[22] = config.pins_44_45;
00475 pin_mode_[23] = config.pins_46_47;
00476 stack = 3;
00477 }
00478
00479
00480 values_s0_.assign(3, 0);
00481 values_s1_.assign(3, 0);
00482 values_d_.assign(3, 0);
00483
00484 fake_values_s0_.assign(3, 0);
00485 fake_values_s1_.assign(3, 0);
00486
00487 padded_s0_.assign(3, 0);
00488 padded_s1_.assign(3, 0);
00489
00490 int bit = 1;
00491 int pin_count = (adc16_->state_.adc_.size()/(stack*2)) -1;
00492
00493
00494
00495
00496 for (int i = 0; i < stack; i++)
00497 {
00498 for (signed int pin = 0; pin <= pin_count; pin++)
00499 {
00500 if (pin <= pin_count - 4)
00501 {
00502 if (pin_mode_[pin] == 0)
00503 {
00504 values_s1_[i] <<=2;
00505 values_d_[i] <<=1;
00506 fake_values_s1_[i] <<=2;
00507 fake_values_s1_[i] |= bit * 3;
00508 }
00509 else if (pin_mode_[pin] == 1)
00510 {
00511 values_s1_[i] <<=2;
00512 values_d_[i] <<=1;
00513 fake_values_s1_[i] <<=2;
00514 values_s1_[i] |= bit * 3;
00515 }
00516 else
00517 {
00518 values_s1_[i] <<=2;
00519 values_d_[i] <<=1;
00520 fake_values_s1_[i] <<=1;
00521 values_d_[i] |= bit;
00522 fake_values_s1_[i] |= bit;
00523 }
00524 }
00525
00526
00527 else if (pin <= pin_count)
00528 {
00529 if (pin_mode_[pin] == 0)
00530 {
00531 values_s0_[i] <<=2;
00532 values_d_[i] <<=1;
00533 fake_values_s0_[i] <<=2;
00534 fake_values_s0_[i] |= bit * 3;
00535 }
00536 else if (pin_mode_[pin] == 1)
00537 {
00538 values_s0_[i] <<=2;
00539 values_d_[i] <<=1;
00540 fake_values_s0_[i] <<=2;
00541 values_s0_[i] |= bit * 3;
00542 }
00543 else
00544 {
00545 values_s0_[i] <<=2;
00546 values_d_[i] <<=1;
00547 fake_values_s0_[i] <<=1;
00548 values_d_[i] |= bit;
00549 fake_values_s0_[i] |= bit;
00550 }
00551 }
00552 }
00553 pin_count = pin_count + 8;
00554 padded_s0_[i] = values_s0_[i] | fake_values_s0_[i];
00555 padded_s1_[i] = values_s1_[i] | fake_values_s1_[i];
00556 }
00557
00558
00559 reg_flag_ = true;
00560 reg_state_ = 0;
00561
00562 RONEX_COMMAND_02000008 command;
00563
00564
00565 command.address = RONEX_02000008_ADS1158_REGISTER_MUXSG0;
00566 command.values[0] = padded_s0_[0];
00567 command.values[1] = padded_s0_[1];
00568 command.values[2] = padded_s0_[2];
00569
00570 command_queue_.push(command);
00571
00572 command.address = RONEX_02000008_ADS1158_REGISTER_MUXSG1;
00573 command.values[0] = padded_s1_[0];
00574 command.values[1] = padded_s1_[1];
00575 command.values[2] = padded_s1_[2];
00576
00577 command_queue_.push(command);
00578
00579 command.address = RONEX_02000008_ADS1158_REGISTER_MUXDIF;
00580 command.values[0] = values_d_[0];
00581 command.values[1] = values_d_[1];
00582 command.values[2] = values_d_[2];
00583
00584
00585 command_queue_.push(command);
00586 command_queue_.push(command);
00587
00588
00589 queue_backup_ = command_queue_;
00590 }
00591
00592
00593 void SrBoardADC16::build_topics_()
00594 {
00595
00596 parameter_id_ = ronex::get_ronex_param_id("");
00597 std::stringstream param_path, tmp_param;
00598 param_path << "/ronex/devices/" << parameter_id_ << "/";
00599 tmp_param << ronex::get_product_code(sh_);
00600 ros::param::set(param_path.str() + "product_id", tmp_param.str());
00601 ros::param::set(param_path.str() + "product_name", product_alias_);
00602 ros::param::set(param_path.str() + "ronex_id", ronex_id_);
00603
00604
00605 ros::param::set(param_path.str() + "path", device_name_);
00606 ros::param::set(param_path.str() + "serial", serial_number_);
00607
00608
00609 state_publisher_.reset(new realtime_tools::RealtimePublisher<sr_ronex_msgs::ADC16State>(node_, device_name_ +
00610 "/state", 1));
00611 }
00612
00613
00614
00615
00616
00617