roboteq.cpp
Go to the documentation of this file.
1 
32 #include "roboteq/roboteq.h"
33 
34 namespace roboteq
35 {
36 
38  : DiagnosticTask("Roboteq")
39  , mNh(nh)
40  , private_mNh(private_nh)
41  , mSerial(serial)
42 {
43  // First run dynamic reconfigurator
44  setup_controller = false;
45  // Initialize GPIO reading
46  _isGPIOreading = false;
47  // Load default configuration roboteq board
49 
50  //Services
52 
53  _first = false;
54  std::vector<std::string> joint_list;
55  if(private_nh.hasParam("joint"))
56  {
57  private_nh.getParam("joint", joint_list);
58  }
59  else
60  {
61  //ROS_WARN("No joint list!");
62  joint_list.push_back("right_wheel_joint");
63  joint_list.push_back("left_wheel_joint");
64  private_nh.setParam("joint", joint_list);
65  }
66  // Disable ECHO
67  mSerial->echo(false);
68  // Disable Script and wait to load all parameters
69  mSerial->script(false);
70 
71 
72  // Initialize Joints
73  for(unsigned i=0; i < joint_list.size(); ++i)
74  {
75  string motor_name = joint_list.at(i);
76  int number = i + 1;
77 
78  //if(!private_nh.hasParam(motor_name))
79  //{
80  _first = true;
81  //ROS_WARN_STREAM("Load " << motor_name << " parameters from Roboteq board");
82  //}
83 
84  if(private_nh.hasParam(motor_name + "/number"))
85  {
86  private_nh.getParam(motor_name + "/number", number);
87  }
88  else
89  {
90  //ROS_WARN_STREAM("Default number selected for Motor: " << motor_name << " is " << number);
91  private_nh.setParam(motor_name + "/number", number);
92  }
93 
94  ROS_INFO_STREAM("Motor[" << number << "] name: " << motor_name);
95  //mMotor[motor_name] = new Motor(private_mNh, serial, motor_name, number);
96  mMotor.push_back(new Motor(private_mNh, serial, motor_name, number));
97  }
98 
99  // Launch initialization input/output
100  for(int i = 0; i < 6; ++i)
101  {
102  _param_pulse.push_back(new GPIOPulseConfigurator(private_mNh, serial, mMotor, "/InOut", i+1));
103  }
104  for(int i = 0; i < 6; ++i)
105  {
106  _param_analog.push_back(new GPIOAnalogConfigurator(private_mNh, serial, mMotor, "/InOut", i+1));
107  }
108  for(int i = 0; i < 2; ++i)
109  {
110  _param_encoder.push_back(new GPIOEncoderConfigurator(private_mNh, serial, mMotor, "/InOut", i+1));
111  }
112 
113  // Add subscriber stop
114  sub_stop = private_mNh.subscribe("emergency_stop", 1, &Roboteq::stop_Callback, this);
115  // Initialize the peripheral publisher
116  pub_peripheral = private_mNh.advertise<roboteq_control::Peripheral>("peripheral", 10,
117  boost::bind(&Roboteq::connectionCallback, this, _1), boost::bind(&Roboteq::connectionCallback, this, _1));
118 
119 }
120 
122  // Information about the subscriber
123  //ROS_INFO_STREAM("Update: " << pub.getSubscriberName() << " - " << pub.getTopic());
124  // Check if some subscriber is connected with peripheral publisher
126 }
127 
128 void Roboteq::stop_Callback(const std_msgs::Bool::ConstPtr& msg)
129 {
130  bool status = (int)msg.get()->data;
131  if(status)
132  {
133  // Send emergency stop
134  mSerial->command("EX");
135  ROS_WARN_STREAM("[roboteq_interface]: Emergency stop");
136  } else
137  {
138  // Safety release
139  mSerial->command("MG");
140  ROS_WARN_STREAM("roboteq_interface]: Safety release");
141  }
142 
143 }
144 
146 {
147  // Load model roboeq board
148  string trn = mSerial->getQuery("TRN");
149  std::vector<std::string> fields;
150  boost::split(fields, trn, boost::algorithm::is_any_of(":"));
151  _type = fields[0];
152  _model = fields[1];
153  // ROS_INFO_STREAM("Model " << _model);
154  // Load firmware version
155  _version = mSerial->getQuery("FID");
156  // Load UID
157  _uid = mSerial->getQuery("UID");
158 }
159 
161 {
162  // ROS_INFO_STREAM("Script: " << script(false));
163 }
164 
166 {
167  // Check if is required load paramers
168  if(_first)
169  {
170  // Load parameters from roboteq
172  }
173 
174  // Initialize parameter dynamic reconfigure
175  ds_controller = new dynamic_reconfigure::Server<roboteq_control::RoboteqControllerConfig>(private_mNh);
176  dynamic_reconfigure::Server<roboteq_control::RoboteqControllerConfig>::CallbackType cb_controller = boost::bind(&Roboteq::reconfigureCBController, this, _1, _2);
177  ds_controller->setCallback(cb_controller);
178 
179  // Launch initialization GPIO
180  for (vector<GPIOPulseConfigurator*>::iterator it = _param_pulse.begin() ; it != _param_pulse.end(); ++it)
181  {
182  ((GPIOPulseConfigurator*)(*it))->initConfigurator(true);
183  }
184  for (vector<GPIOAnalogConfigurator*>::iterator it = _param_analog.begin() ; it != _param_analog.end(); ++it)
185  {
186  ((GPIOAnalogConfigurator*)(*it))->initConfigurator(true);
187  }
188  for (vector<GPIOEncoderConfigurator*>::iterator it = _param_encoder.begin() ; it != _param_encoder.end(); ++it)
189  {
190  ((GPIOEncoderConfigurator*)(*it))->initConfigurator(true);
191  }
192 
193  // Initialize all motors in list
194  for (vector<Motor*>::iterator it = mMotor.begin() ; it != mMotor.end(); ++it)
195  {
196  Motor* motor = ((Motor*)(*it));
197  // Launch initialization motors
198  motor->initializeMotor(_first);
199  ROS_DEBUG_STREAM("Motor [" << motor->getName() << "] Initialized");
200  }
201 }
202 
204  hardware_interface::VelocityJointInterface &velocity_joint_interface)
205 {
206  // Initialize the diagnostic from the primitive object
208 
209  if (!model.initParam("/robot_description")){
210  //ROS_ERROR("Failed to parse urdf file");
211  }
212  else
213  {
214  //ROS_INFO_STREAM("/robot_description found! " << model.name_ << " parsed!");
215  }
216 
217  for (vector<Motor*>::iterator it = mMotor.begin() ; it != mMotor.end(); ++it)
218  {
219  Motor* motor = ((Motor*)(*it));
221  joint_state_interface.registerHandle(motor->joint_state_handle);
223  velocity_joint_interface.registerHandle(motor->joint_handle);
224 
225  // Setup limits
226  motor->setupLimits(model);
227 
228  // reset position joint
229  //double position = 0;
230  //ROS_DEBUG_STREAM("Motor [" << motor->getName() << "] reset position to: " << position);
231  //motor->resetPosition(position);
232 
233  // Stop motors
234  /*ROS_ERROR("HERE");
235  bool stop_motor = mSerial->command("EX"); //set emergency
236  mSerial->command("!C 1 0"); //reset counters
237  mSerial->command("!C 2 0"); //reset counters
238  mSerial->command("MG"); //release emergency*/
239 
240  //ROS_DEBUG_STREAM("Stop motor: " << (stop_motor ? "true" : "false"));
241 
242  //Add motor in diagnostic updater
243  diagnostic_updater.add(*(motor));
244  //ROS_DEBUG_STREAM("Motor [" << motor->getName() << "] Registered");
245  }
246 
247  //ROS_DEBUG_STREAM("Send all Constraint configuration");
248 
250  //registerInterface(&joint_state_interface);
251  //registerInterface(&velocity_joint_interface);
252 }
253 
255 {
256  ROS_INFO_STREAM("Roboteq " << _type << ":" << _model << "version: " << _version);
257 
258  diagnostic_updater.setHardwareID(_model);
259 
260  // Initialize this diagnostic interface
261  diagnostic_updater.add(*this);
262 }
263 
265 {
266  // ROS_DEBUG_STREAM("Update diagnostic");
267 
268  // Scale factors as outlined in the relevant portions of the user manual, please
269  // see mbs/script.mbs for URL and specific page references.
270  try
271  {
272  // Fault flag [pag. 245]
273  string fault_flag = mSerial->getQuery("FF");
274  unsigned char fault = boost::lexical_cast<unsigned int>(fault_flag);
275  memcpy(&_fault, &fault, sizeof(fault));
276  // Status flag [pag. 247]
277  string status_flag = mSerial->getQuery("FS");
278  unsigned char status = boost::lexical_cast<unsigned int>(status_flag);
279  memcpy(&_flag, &status, sizeof(status));
280  // power supply voltage
281  string supply_voltage_1 = mSerial->getQuery("V", "1");
282  _volts_internal = boost::lexical_cast<double>(supply_voltage_1) / 10;
283  string supply_voltage_3 = mSerial->getQuery("V", "3");
284  _volts_five = boost::lexical_cast<double>(supply_voltage_3) / 1000;
285  // temperature channels [pag. 259]
286  string temperature_1 = mSerial->getQuery("T", "1");
287  _temp_mcu = boost::lexical_cast<double>(temperature_1);
288  string temperature_2 = mSerial->getQuery("T", "2");
289  _temp_bridge = boost::lexical_cast<double>(temperature_2);
290  }
291  catch (std::bad_cast& e)
292  {
293  ROS_WARN("Failure parsing feedback data. Dropping message.");
294  return;
295  }
296 
297  // Force update all diagnostic parts
298  diagnostic_updater.force_update();
299 }
300 
301 void Roboteq::read(const ros::Time& time, const ros::Duration& period) {
302  //ROS_DEBUG_STREAM("Get measure from Roboteq");
303 
304  std::vector<std::string> motors[mMotor.size()];
305  std::vector<std::string> fields;
306 
307  // Read status motor
308  // motor status flags [pag. 246]
309  string str_status = mSerial->getQuery("FM");
310  // ROS_INFO_STREAM("FM=" << str_status);
311  boost::split(fields, str_status, boost::algorithm::is_any_of(":"));
312  for(int i = 0; i < fields.size(); ++i) {
313  motors[i].push_back(fields[i]);
314  }
315  // motor command [pag. 250]
316  string str_motor = mSerial->getQuery("M");
317  // ROS_INFO_STREAM("M =" << str_motor);
318  boost::split(fields, str_motor, boost::algorithm::is_any_of(":"));
319  for(int i = 0; i < fields.size(); ++i) {
320  motors[i].push_back(fields[i]);
321  }
322  // motor feedback [pag. 244]
323  string str_feedback = mSerial->getQuery("F");
324  //ROS_INFO_STREAM("F =" << str_feedback);
325  boost::split(fields, str_feedback, boost::algorithm::is_any_of(":"));
326  for(int i = 0; i < fields.size(); ++i) {
327  motors[i].push_back(fields[i]);
328  }
329  // motor loop error [pag. 244]
330  string str_loop_error = mSerial->getQuery("E");
331  // ROS_INFO_STREAM("E =" << str_loop_error);
332  boost::split(fields, str_loop_error, boost::algorithm::is_any_of(":"));
333  for(int i = 0; i < fields.size(); ++i) {
334  motors[i].push_back(fields[i]);
335  }
336  // motor power [pag. 255]
337  string str_motor_power = mSerial->getQuery("P");
338  // ROS_INFO_STREAM("P =" << str_motor_power);
339  boost::split(fields, str_motor_power, boost::algorithm::is_any_of(":"));
340  for(int i = 0; i < fields.size(); ++i) {
341  motors[i].push_back(fields[i]);
342  }
343  // power supply voltage [pag. 262]
344  string str_voltage_supply = mSerial->getQuery("V", "2");
345  //ROS_INFO_STREAM("V2=" << str_voltage_supply);
346  for(int i = 0; i < fields.size(); ++i) {
347  motors[i].push_back(str_voltage_supply);
348  }
349  // motor Amps [pag. 230]
350  string str_motor_amps = mSerial->getQuery("A");
351  //ROS_INFO_STREAM("A =" << str_motor_amps);
352  boost::split(fields, str_motor_amps, boost::algorithm::is_any_of(":"));
353  for(int i = 0; i < fields.size(); ++i) {
354  motors[i].push_back(fields[i]);
355  }
356  // motor battery amps [pag. 233]
357  string str_motor_battery_amps = mSerial->getQuery("BA");
358  //ROS_INFO_STREAM("BA=" << str_motor_battery_amps);
359  boost::split(fields, str_motor_battery_amps, boost::algorithm::is_any_of(":"));
360  for(int i = 0; i < fields.size(); ++i) {
361  motors[i].push_back(fields[i]);
362  }
363  // position encoder value [pag. 236]
364  string str_position_encoder_absolute = mSerial->getQuery("C");
365  //ROS_INFO_STREAM("C =" << str_position_encoder_absolute);
366  boost::split(fields, str_position_encoder_absolute, boost::algorithm::is_any_of(":"));
367  for(int i = 0; i < fields.size(); ++i) {
368  motors[i].push_back(fields[i]);
369  }
370  // motor track [pag. 260]
371  string str_motor_track = mSerial->getQuery("TR");
372  //ROS_INFO_STREAM("TR=" << str_motor_track);
373  boost::split(fields, str_motor_track, boost::algorithm::is_any_of(":"));
374  for(int i = 0; i < fields.size(); ++i) {
375  motors[i].push_back(fields[i]);
376  }
377 
378 
379  // send list
380  for(int i = 0; i < mMotor.size(); ++i) {
381  //get number motor initialization
382  unsigned int idx = mMotor[i]->mNumber-1;
383  // Read and decode vector
384  mMotor[i]->readVector(motors[idx]);
385 
386  if (first_read_)
387  first_read_pos_[i] = mMotor[i]->position;
388 
389  mMotor[i]->position = mMotor[i]->position - first_read_pos_[i];
390  }
391  if (first_read_)
392  first_read_ = false;
393 
394  // Read data from GPIO
395  if(_isGPIOreading)
396  {
397  msg_peripheral.header.stamp = ros::Time::now();
398  std::vector<std::string> fields;
399  // Get Pulse in status [pag. 256]
400  string pulse_in = mSerial->getQuery("PI");
401  boost::split(fields, pulse_in, boost::algorithm::is_any_of(":"));
402  // Clear msg list
403  msg_peripheral.pulse_in.clear();
404  for(int i = 0; i < fields.size(); ++i)
405  {
406  try
407  {
408  msg_peripheral.pulse_in.push_back(boost::lexical_cast<unsigned int>(fields[i]));
409  }
410  catch (std::bad_cast& e)
411  {
412  msg_peripheral.pulse_in.push_back(0);
413  }
414  }
415  // Get analog input values [pag. 231]
416  string analog = mSerial->getQuery("AI");
417  boost::split(fields, analog, boost::algorithm::is_any_of(":"));
418  // Clear msg list
419  msg_peripheral.analog.clear();
420  for(int i = 0; i < fields.size(); ++i)
421  {
422  try
423  {
424  msg_peripheral.analog.push_back(boost::lexical_cast<double>(fields[i]) / 1000.0);
425  }
426  catch (std::bad_cast& e)
427  {
428  msg_peripheral.analog.push_back(0);
429  }
430  }
431 
432  // Get Digital input values [pag. 242]
433  string digital_in = mSerial->getQuery("DI");
434  boost::split(fields, digital_in, boost::algorithm::is_any_of(":"));
435  // Clear msg list
436  msg_peripheral.digital_in.clear();
437  for(int i = 0; i < fields.size(); ++i)
438  {
439  try
440  {
441  msg_peripheral.digital_in.push_back(boost::lexical_cast<unsigned int>(fields[i]));
442  }
443  catch (std::bad_cast& e)
444  {
445  msg_peripheral.digital_in.push_back(0);
446  }
447  }
448 
449  string digital_out = mSerial->getQuery("DO");
450  unsigned int num = 0;
451  try
452  {
453  num = boost::lexical_cast<unsigned int>(digital_out);
454  }
455  catch (std::bad_cast& e)
456  {
457  num = 0;
458  }
459  int mask = 0x0;
460  // Clear msg list
461  msg_peripheral.digital_out.clear();
462  for(int i = 0; i < 8; ++i)
463  {
464  msg_peripheral.digital_out.push_back((mask & num));
465  mask <<= 1;
466  }
467 
468  // Send GPIO status
470  }
471 }
472 
473 void Roboteq::write(const ros::Time& time, const ros::Duration& period) {
474  //ROS_DEBUG_STREAM("Write command to Roboteq");
475 
476  for (vector<Motor*>::iterator it = mMotor.begin() ; it != mMotor.end(); ++it)
477  {
478  Motor* motor = ((Motor*)(*it));
479  // Launch initialization motors
480  motor->writeCommandsToHardware(period);
481  //ROS_DEBUG_STREAM("Motor [" << motor->getName() << "] Send commands");
482  }
483 }
484 
485 bool Roboteq::prepareSwitch(const std::list<hardware_interface::ControllerInfo>& start_list, const std::list<hardware_interface::ControllerInfo>& stop_list)
486 {
487  //ROS_INFO_STREAM("Prepare to switch!");
488  return true;
489 }
490 
491 void Roboteq::doSwitch(const std::list<hardware_interface::ControllerInfo>& start_list, const std::list<hardware_interface::ControllerInfo>& stop_list)
492 {
493  // Stop all controller in list
494  for(std::list<hardware_interface::ControllerInfo>::const_iterator it = stop_list.begin(); it != stop_list.end(); ++it)
495  {
496  //ROS_INFO_STREAM("DO SWITCH STOP name: " << it->name << " - type: " << it->type);
497  const hardware_interface::InterfaceResources& iface_res = it->claimed_resources.front();
498  for (std::set<std::string>::const_iterator res_it = iface_res.resources.begin(); res_it != iface_res.resources.end(); ++res_it)
499  {
500  //ROS_INFO_STREAM(it->name << "[" << *res_it << "] STOP");
501 
502  for (vector<Motor*>::iterator m_it = mMotor.begin() ; m_it != mMotor.end(); ++m_it)
503  {
504  Motor* motor = ((Motor*)(*m_it));
505  if(motor->getName().compare(*res_it) == 0)
506  {
507  // switch initialization motors
508  motor->switchController("disable");
509  break;
510  }
511  }
512  }
513  }
514  // Stop motors
515  mSerial->command("EX");
516  // Run all new controllers
517  for(std::list<hardware_interface::ControllerInfo>::const_iterator it = start_list.begin(); it != start_list.end(); ++it)
518  {
519  //ROS_INFO_STREAM("DO SWITCH START name: " << it->name << " - type: " << it->type);
520  const hardware_interface::InterfaceResources& iface_res = it->claimed_resources.front();
521  for (std::set<std::string>::const_iterator res_it = iface_res.resources.begin(); res_it != iface_res.resources.end(); ++res_it)
522  {
523  //ROS_INFO_STREAM(it->name << "[" << *res_it << "] START");
524 
525  for (vector<Motor*>::iterator m_it = mMotor.begin() ; m_it != mMotor.end(); ++m_it)
526  {
527  Motor* motor = ((Motor*)(*m_it));
528  if(motor->getName().compare(*res_it) == 0)
529  {
530  // switch initialization motors
531  motor->switchController(it->type);
532  break;
533  }
534  }
535  }
536  }
537  // Enable motor
538  mSerial->command("MG");
539 }
540 
542 {
543  stat.add("Type board", _type);
544  stat.add("Name board", _model);
545  stat.add("Version", _version);
546  stat.add("UID", _uid);
547 
548  stat.add("Temp MCU (deg)", _temp_mcu);
549  stat.add("Temp Bridge (deg)", _temp_bridge);
550 
551  stat.add("Internal (V)", _volts_internal);
552  stat.add("5v regulator (V)", _volts_five);
553 
554  string mode = "[ ";
555  if(_flag.serial_mode)
556  mode += "serial ";
557  if(_flag.pulse_mode)
558  mode += "pulse ";
559  if(_flag.analog_mode)
560  mode += "analog ";
561  mode += "]";
562  // Mode roboteq board
563  stat.add("Mode", mode);
564  // Spectrum
565  stat.add("Spectrum", (bool)_flag.spectrum);
566  // Microbasic
567  stat.add("Micro basic running", (bool)_flag.microbasic_running);
568 
569  stat.summary(diagnostic_msgs::DiagnosticStatus::OK, "Board ready!");
570 
572  {
573  stat.mergeSummary(diagnostic_msgs::DiagnosticStatus::WARN, "Power stage OFF");
574  }
575 
576  if(_flag.stall_detect)
577  {
578  stat.mergeSummary(diagnostic_msgs::DiagnosticStatus::ERROR, "Stall detect");
579  }
580 
581  if(_flag.at_limit)
582  {
583  stat.mergeSummary(diagnostic_msgs::DiagnosticStatus::ERROR, "At limit");
584  }
585 
587  {
588  stat.mergeSummary(diagnostic_msgs::DiagnosticStatus::ERROR, "Brushless sensor fault");
589  }
590 
592  {
593  stat.mergeSummary(diagnostic_msgs::DiagnosticStatus::WARN, "Emergency stop");
594  }
595 
597  {
598  stat.mergeSummary(diagnostic_msgs::DiagnosticStatus::ERROR, "MOSFET failure");
599  }
600 
601  if(_fault.overheat)
602  {
603  stat.mergeSummaryf(diagnostic_msgs::DiagnosticStatus::ERROR, "Over heat MCU=%f, Bridge=%f", _temp_mcu, _temp_bridge);
604  }
605 
606  if(_fault.overvoltage)
607  {
608  stat.mergeSummary(diagnostic_msgs::DiagnosticStatus::ERROR, "Over voltage");
609  }
610 
611  if(_fault.undervoltage)
612  {
613  stat.mergeSummary(diagnostic_msgs::DiagnosticStatus::ERROR, "Under voltage");
614  }
615 
617  {
618  stat.mergeSummary(diagnostic_msgs::DiagnosticStatus::ERROR, "Short circuit");
619  }
620 }
621 
623 {
624  try
625  {
626  // Get PWM frequency PWMF [pag. 327]
627  string str_pwm = mSerial->getParam("PWMF");
628  unsigned int tmp_pwm = boost::lexical_cast<unsigned int>(str_pwm);
629  double pwm = ((double) tmp_pwm) / 10.0;
630  // Set params
631  private_mNh.setParam("pwm_frequency", pwm);
632 
633  // Get over voltage limit OVL [pag. 326]
634  string str_ovl = mSerial->getParam("OVL");
635  unsigned int tmp_ovl = boost::lexical_cast<unsigned int>(str_ovl);
636  double ovl = ((double) tmp_ovl) / 10.0;
637  // Set params
638  private_mNh.setParam("over_voltage_limit", ovl);
639 
640  // Get over voltage hystersis OVH [pag. 326]
641  string str_ovh = mSerial->getParam("OVH");
642  unsigned int tmp_ovh = boost::lexical_cast<unsigned int>(str_ovh);
643  double ovh = ((double) tmp_ovh) / 10.0;
644  // Set params
645  private_mNh.setParam("over_voltage_hysteresis", ovh);
646 
647  // Get under voltage limit UVL [pag. 328]
648  string str_uvl = mSerial->getParam("UVL");
649  unsigned int tmp_uvl = boost::lexical_cast<unsigned int>(str_uvl);
650  double uvl = ((double) tmp_uvl) / 10.0;
651  // Set params
652  private_mNh.setParam("under_voltage_limit", uvl);
653 
654  // Get brake activation delay BKD [pag. 309]
655  string str_break = mSerial->getParam("BKD");
656  int break_delay = boost::lexical_cast<unsigned int>(str_break);
657  // Set params
658  private_mNh.setParam("break_delay", break_delay);
659 
660  // Get Mixing mode MXMD [pag. 322]
661  string str_mxd = mSerial->getParam("MXMD", "1");
662  // ROS_INFO_STREAM("MXMD "<< str_mxd);
663  int mixed = boost::lexical_cast<unsigned int>(str_mxd);
664  // Set params
665  private_mNh.setParam("mixing", mixed);
666 
667  } catch (std::bad_cast& e)
668  {
669  ROS_WARN_STREAM("Failure parsing feedback data. Dropping message." << e.what());
670  }
671 }
672 
673 void Roboteq::reconfigureCBController(roboteq_control::RoboteqControllerConfig &config, uint32_t level)
674 {
675  //The first time we're called, we just want to make sure we have the
676  //original configuration
677  if(!setup_controller)
678  {
679  _last_controller_config = config;
681  setup_controller = true;
682  return;
683  }
684 
685  if(config.restore_defaults)
686  {
687  //if someone sets restore defaults on the parameter server, prevent looping
688  config.restore_defaults = false;
689  // Overload config with default
690  config = default_controller_config;
691  }
692 
693  if(config.factory_reset)
694  {
695  //if someone sets restore defaults on the parameter server, prevent looping
696  config.factory_reset = false;
698  // Enable load from roboteq board
699  config.load_roboteq = true;
700  }
701 
702  if(config.load_from_eeprom)
703  {
704  //if someone sets again the request on the parameter server, prevent looping
705  config.load_from_eeprom = false;
707  // Enable load from roboteq board
708  config.load_roboteq = true;
709  }
710 
711  if(config.load_roboteq)
712  {
713  //if someone sets again the request on the parameter server, prevent looping
714  config.load_roboteq = false;
715  // Launch param load
717  // Skip other read
718  return;
719  }
720 
721  if(config.store_in_eeprom)
722  {
723  //if someone sets again the request on the parameter server, prevent looping
724  config.store_in_eeprom = false;
725  // Save all data in eeprom
727  }
728 
729  // Set PWM frequency PWMF [pag. 327]
730  if(_last_controller_config.pwm_frequency != config.pwm_frequency)
731  {
732  // Update PWM
733  int pwm = config.pwm_frequency * 10;
734  mSerial->setParam("PWMF", std::to_string(pwm));
735  }
736  // Set over voltage limit OVL [pag. 326]
737  if(_last_controller_config.over_voltage_limit != config.over_voltage_limit)
738  {
739  // Update over voltage limit
740  int ovl = config.over_voltage_limit * 10;
741  mSerial->setParam("OVL", std::to_string(ovl));
742  }
743  // Set over voltage hystersis OVH [pag. 326]
744  if(_last_controller_config.over_voltage_hysteresis != config.over_voltage_hysteresis)
745  {
746  // Update over voltage hysteresis
747  int ovh = config.over_voltage_hysteresis * 10;
748  mSerial->setParam("OVH", std::to_string(ovh));
749  }
750  // Set under voltage limit UVL [pag. 328]
751  if(_last_controller_config.under_voltage_limit != config.under_voltage_limit)
752  {
753  // Update under voltage limit
754  int uvl = config.under_voltage_limit * 10;
755  mSerial->setParam("UVL", std::to_string(uvl));
756  }
757  // Set brake activation delay BKD [pag. 309]
758  if(_last_controller_config.break_delay != config.break_delay)
759  {
760  // Update brake activation delay
761  mSerial->setParam("BKD", std::to_string(config.break_delay));
762  }
763 
764  // Set Mixing mode MXMD [pag. 322]
765  if(_last_controller_config.mixing != config.mixing)
766  {
767  // Update brake activation delay
768  mSerial->setParam("MXMD", std::to_string(config.mixing) + ":0");
769  }
770 
771  // Update last configuration
772  _last_controller_config = config;
773 }
774 
775 bool Roboteq::service_Callback(roboteq_control::Service::Request &req, roboteq_control::Service::Response &msg) {
776  // Convert to lower case
777  std::transform(req.service.begin(), req.service.end(), req.service.begin(), ::tolower);
778  //ROS_INFO_STREAM("Name request: " << req.service);
779  if(req.service.compare("info") == 0)
780  {
781  msg.information = "\nBoard type: " + _type + "\n"
782  "Name board: " + _model + "\n"
783  "Version: " + _version + "\n"
784  "UID: " + _uid + "\n";
785  }
786  else if(req.service.compare("reset") == 0)
787  {
788  // Launch reset command
789  mSerial->reset();
790  // return message
791  msg.information = "System reset";
792  }
793  else if(req.service.compare("save") == 0)
794  {
795  // Launch reset command
797  // return message
798  msg.information = "Parameters saved";
799  }
800  else
801  {
802  msg.information = "\nList of commands availabes: \n"
803  "* info - information about this board \n"
804  "* reset - " + _model + " board software reset\n"
805  "* save - Save all paramters in EEPROM \n"
806  "* help - this help.";
807  }
808  return true;
809 }
810 
811 }
bool script(bool status)
script Run and stop the script inside the Roboteq
ros::Subscriber sub_stop
Definition: roboteq.h:145
uint8_t power_stage_off
Definition: roboteq.h:73
serial_controller * mSerial
Definition: roboteq.h:139
void read(const ros::Time &time, const ros::Duration &period)
Definition: roboteq.cpp:301
bool setParam(string msg, string params="")
Roboteq(const ros::NodeHandle &nh, const ros::NodeHandle &private_nh, serial_controller *serial)
Roboteq The Roboteq board controller write and read messages about the motor state.
Definition: roboteq.cpp:37
void publish(const boost::shared_ptr< M > &message) const
double _volts_internal
Definition: roboteq.h:170
void summary(unsigned char lvl, const std::string s)
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
void doSwitch(const std::list< hardware_interface::ControllerInfo > &start_list, const std::list< hardware_interface::ControllerInfo > &stop_list)
Definition: roboteq.cpp:491
std::set< std::string > resources
uint8_t stall_detect
Definition: roboteq.h:74
hardware_interface::JointStateHandle joint_state_handle
Definition: motor.h:139
std::vector< GPIOAnalogConfigurator * > _param_analog
Definition: roboteq.h:180
double first_read_pos_[2]
Definition: roboteq.h:175
ros::Publisher pub_peripheral
Definition: roboteq.h:143
void reconfigureCBController(roboteq_control::RoboteqControllerConfig &config, uint32_t level)
reconfigureCBEncoder when the dynamic reconfigurator change some values start this method ...
Definition: roboteq.cpp:673
uint8_t undervoltage
Definition: roboteq.h:82
hardware_interface::JointHandle joint_handle
Definition: motor.h:140
uint8_t serial_mode
Definition: roboteq.h:69
roboteq_control::Peripheral msg_peripheral
Definition: roboteq.h:179
uint8_t brushless_sensor_fault
Definition: roboteq.h:85
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
urdf::Model model
URDF information about robot.
Definition: roboteq.h:150
#define ROS_WARN(...)
void write(const ros::Time &time, const ros::Duration &period)
Definition: roboteq.cpp:473
bool echo(bool type)
echo Enable or disable the echo message
uint8_t emergency_stop
Definition: roboteq.h:84
bool service_Callback(roboteq_control::Service::Request &req, roboteq_control::Service::Response &msg_system)
service_Callback Internal service to require information from the board connected ...
Definition: roboteq.cpp:775
void initializeDiagnostic()
Definition: roboteq.cpp:254
bool factoryReset()
factoryReset Factory reset of Roboteq board
std::vector< GPIOEncoderConfigurator * > _param_encoder
Definition: roboteq.h:183
string getName()
getName the name of the motor
Definition: motor.h:122
bool _isGPIOreading
Definition: roboteq.h:178
uint8_t microbasic_running
Definition: roboteq.h:76
roboteq_control::RoboteqControllerConfig _last_controller_config
Definition: roboteq.h:206
void updateDiagnostics()
updateDiagnostics
Definition: roboteq.cpp:264
void writeCommandsToHardware(ros::Duration period)
writeCommandsToHardware Write a command to the hardware interface
Definition: motor.cpp:334
void getRoboteqInformation()
getRoboteqInformation Load basic information from roboteq board
Definition: roboteq.cpp:145
status
std::vector< Motor * > mMotor
Definition: roboteq.h:160
string _model
Definition: roboteq.h:162
string _type
Definition: roboteq.h:162
ros::NodeHandle private_mNh
Definition: roboteq.h:137
bool _first
ROS Control interfaces.
Definition: roboteq.h:157
void reset()
reset Reset the Roboteq board
uint8_t analog_mode
Definition: roboteq.h:71
void getControllerFromRoboteq()
getPIDFromRoboteq Load PID parameters from Roboteq board
Definition: roboteq.cpp:622
bool setup_controller
Setup variable.
Definition: roboteq.h:194
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
bool initParam(const std::string &param)
#define ROS_WARN_STREAM(args)
string _version
Definition: roboteq.h:163
#define ROS_DEBUG_STREAM(args)
void registerHandle(const JointStateHandle &handle)
void connectionCallback(const ros::SingleSubscriberPublisher &pub)
connectionCallback Check how many subscribers are connected
Definition: roboteq.cpp:121
string getParam(string msg, string params="")
void mergeSummary(unsigned char lvl, const std::string s)
void setupLimits(urdf::Model model)
setupLimits setup the maximum velocity, positio and effort
Definition: motor.cpp:140
bool command(string msg, string params="", string type="!")
uint32_t getNumSubscribers() const
#define ROS_INFO_STREAM(args)
Definition: motor.h:51
bool first_read_
Definition: roboteq.h:174
bool prepareSwitch(const std::list< hardware_interface::ControllerInfo > &start_list, const std::list< hardware_interface::ControllerInfo > &stop_list)
Definition: roboteq.cpp:485
uint8_t short_circuit
Definition: roboteq.h:83
uint8_t pulse_mode
Definition: roboteq.h:70
roboteq_control::RoboteqControllerConfig default_controller_config
Definition: roboteq.h:206
status_flag_t _flag
Definition: roboteq.h:166
bool getParam(const std::string &key, std::string &s) const
std::vector< GPIOPulseConfigurator * > _param_pulse
Definition: roboteq.h:181
bool loadFromEEPROM()
loadFromEEPROM
string getQuery(string msg, string params="")
uint8_t mosfet_failure
Definition: roboteq.h:86
void initialize()
initialize the roboteq controller
Definition: roboteq.cpp:165
static Time now()
bool saveInEEPROM()
saveInEEPROM The EESAV it&#39;s a real-time Command must be used to copy the RAM array to Flash...
void initializeInterfaces(hardware_interface::JointStateInterface &joint_state_interface, hardware_interface::VelocityJointInterface &velocity_joint_interface)
initializeInterfaces Initialize all motors. Add all Control Interface availbles and add in diagnostic...
Definition: roboteq.cpp:203
void mergeSummaryf(unsigned char lvl, const char *format,...)
~Roboteq()
The deconstructor.
Definition: roboteq.cpp:160
void add(const std::string &key, const T &val)
bool hasParam(const std::string &key) const
void run(diagnostic_updater::DiagnosticStatusWrapper &stat)
run Diagnostic thread called every request
Definition: roboteq.cpp:541
void switchController(string type)
switchController Switch the controller from different type of ros controller
Definition: motor.cpp:306
void initializeMotor(bool load_from_board)
initializeMotor Initialization oh motor, this routine load parameter from ros server or load from rob...
Definition: motor.cpp:79
status_fault_t _fault
Definition: roboteq.h:168
void setParam(const std::string &key, const XmlRpc::XmlRpcValue &v) const
double _temp_bridge
Definition: roboteq.h:172
void stop_Callback(const std_msgs::Bool::ConstPtr &msg)
Definition: roboteq.cpp:128
double _temp_mcu
Definition: roboteq.h:172
double _volts_five
Definition: roboteq.h:170
dynamic_reconfigure::Server< roboteq_control::RoboteqControllerConfig > * ds_controller
Dynamic reconfigure PID.
Definition: roboteq.h:197
ros::ServiceServer srv_board
Definition: roboteq.h:147


roboteq_control
Author(s): Raffaello Bonghi
autogenerated on Wed Jan 3 2018 03:48:23