ros2_canopen  master
C++ ROS CANopen Library
node_canopen_402_driver_impl.hpp
Go to the documentation of this file.
1 #ifndef NODE_CANOPEN_402_DRIVER_IMPL_HPP_
2 #define NODE_CANOPEN_402_DRIVER_IMPL_HPP_
3 
6 
7 #include <optional>
8 
9 using namespace ros2_canopen::node_interfaces;
10 using namespace std::placeholders;
11 
12 template <class NODETYPE>
14 : ros2_canopen::node_interfaces::NodeCanopenProxyDriver<NODETYPE>(node)
15 {
16 }
17 
18 template <class NODETYPE>
19 void NodeCanopen402Driver<NODETYPE>::init(bool called_from_base)
20 {
21  RCLCPP_ERROR(this->node_->get_logger(), "Not init implemented.");
22 }
23 
24 template <>
25 void NodeCanopen402Driver<rclcpp::Node>::init(bool called_from_base)
26 {
28  publish_joint_state =
29  this->node_->create_publisher<sensor_msgs::msg::JointState>("~/joint_states", 1);
30  handle_init_service = this->node_->create_service<std_srvs::srv::Trigger>(
31  std::string(this->node_->get_name()).append("/init").c_str(),
32  std::bind(&NodeCanopen402Driver<rclcpp::Node>::handle_init, this, _1, _2));
33 
34  handle_halt_service = this->node_->create_service<std_srvs::srv::Trigger>(
35  std::string(this->node_->get_name()).append("/halt").c_str(),
36  std::bind(&NodeCanopen402Driver<rclcpp::Node>::handle_halt, this, _1, _2));
37 
38  handle_recover_service = this->node_->create_service<std_srvs::srv::Trigger>(
39  std::string(this->node_->get_name()).append("/recover").c_str(),
40  std::bind(&NodeCanopen402Driver<rclcpp::Node>::handle_recover, this, _1, _2));
41 
42  handle_set_mode_position_service = this->node_->create_service<std_srvs::srv::Trigger>(
43  std::string(this->node_->get_name()).append("/position_mode").c_str(),
45 
46  handle_set_mode_velocity_service = this->node_->create_service<std_srvs::srv::Trigger>(
47  std::string(this->node_->get_name()).append("/velocity_mode").c_str(),
49 
50  handle_set_mode_cyclic_velocity_service = this->node_->create_service<std_srvs::srv::Trigger>(
51  std::string(this->node_->get_name()).append("/cyclic_velocity_mode").c_str(),
53 
54  handle_set_mode_cyclic_position_service = this->node_->create_service<std_srvs::srv::Trigger>(
55  std::string(this->node_->get_name()).append("/cyclic_position_mode").c_str(),
57 
58  handle_set_mode_interpolated_position_service =
59  this->node_->create_service<std_srvs::srv::Trigger>(
60  std::string(this->node_->get_name()).append("/interpolated_position_mode").c_str(),
61  std::bind(
63 
64  handle_set_mode_torque_service = this->node_->create_service<std_srvs::srv::Trigger>(
65  std::string(this->node_->get_name()).append("/torque_mode").c_str(),
67 
68  handle_set_target_service = this->node_->create_service<canopen_interfaces::srv::COTargetDouble>(
69  std::string(this->node_->get_name()).append("/target").c_str(),
71 }
72 
73 template <>
75 {
77  publish_joint_state =
78  this->node_->create_publisher<sensor_msgs::msg::JointState>("~/joint_states", 10);
79  handle_init_service = this->node_->create_service<std_srvs::srv::Trigger>(
80  std::string(this->node_->get_name()).append("/init").c_str(),
82 
83  handle_halt_service = this->node_->create_service<std_srvs::srv::Trigger>(
84  std::string(this->node_->get_name()).append("/halt").c_str(),
86 
87  handle_recover_service = this->node_->create_service<std_srvs::srv::Trigger>(
88  std::string(this->node_->get_name()).append("/recover").c_str(),
89  std::bind(
91 
92  handle_set_mode_position_service = this->node_->create_service<std_srvs::srv::Trigger>(
93  std::string(this->node_->get_name()).append("/position_mode").c_str(),
94  std::bind(
96  _2));
97 
98  handle_set_mode_velocity_service = this->node_->create_service<std_srvs::srv::Trigger>(
99  std::string(this->node_->get_name()).append("/velocity_mode").c_str(),
100  std::bind(
102  _2));
103 
104  handle_set_mode_cyclic_velocity_service = this->node_->create_service<std_srvs::srv::Trigger>(
105  std::string(this->node_->get_name()).append("/cyclic_velocity_mode").c_str(),
106  std::bind(
108  _1, _2));
109 
110  handle_set_mode_cyclic_position_service = this->node_->create_service<std_srvs::srv::Trigger>(
111  std::string(this->node_->get_name()).append("/cyclic_position_mode").c_str(),
112  std::bind(
114  _1, _2));
115 
116  handle_set_mode_interpolated_position_service = this->node_->create_service<
117  std_srvs::srv::Trigger>(
118  std::string(this->node_->get_name()).append("/interpolated_position_mode").c_str(),
119  std::bind(
121  this, _1, _2));
122 
123  handle_set_mode_torque_service = this->node_->create_service<std_srvs::srv::Trigger>(
124  std::string(this->node_->get_name()).append("/torque_mode").c_str(),
125  std::bind(
127  _2));
128 
129  handle_set_target_service = this->node_->create_service<canopen_interfaces::srv::COTargetDouble>(
130  std::string(this->node_->get_name()).append("/target").c_str(),
131  std::bind(
133 }
134 
135 template <>
137 {
139  std::optional<double> scale_pos_to_dev;
140  std::optional<double> scale_pos_from_dev;
141  std::optional<double> scale_vel_to_dev;
142  std::optional<double> scale_vel_from_dev;
143  std::optional<int> switching_state;
144  try
145  {
146  scale_pos_to_dev = std::optional(this->config_["scale_pos_to_dev"].as<double>());
147  }
148  catch (...)
149  {
150  }
151  try
152  {
153  scale_pos_from_dev = std::optional(this->config_["scale_pos_from_dev"].as<double>());
154  }
155  catch (...)
156  {
157  }
158  try
159  {
160  scale_vel_to_dev = std::optional(this->config_["scale_vel_to_dev"].as<double>());
161  }
162  catch (...)
163  {
164  }
165  try
166  {
167  scale_vel_from_dev = std::optional(this->config_["scale_vel_from_dev"].as<double>());
168  }
169  catch (...)
170  {
171  }
172  try
173  {
174  switching_state = std::optional(this->config_["switching_state"].as<int>());
175  }
176  catch (...)
177  {
178  }
179 
180  // auto period = this->config_["scale_eff_to_dev"].as<double>();
181  // auto period = this->config_["scale_eff_from_dev"].as<double>();
182  scale_pos_to_dev_ = scale_pos_to_dev.value_or(1000.0);
183  scale_pos_from_dev_ = scale_pos_from_dev.value_or(0.001);
184  scale_vel_to_dev_ = scale_vel_to_dev.value_or(1000.0);
185  scale_vel_from_dev_ = scale_vel_from_dev.value_or(0.001);
186  switching_state_ = (ros2_canopen::State402::InternalState)switching_state.value_or(
187  (int)ros2_canopen::State402::InternalState::Operation_Enable);
188  RCLCPP_INFO(
189  this->node_->get_logger(),
190  "scale_pos_to_dev_ %f\nscale_pos_from_dev_ %f\nscale_vel_to_dev_ %f\nscale_vel_from_dev_ %f\n",
191  scale_pos_to_dev_, scale_pos_from_dev_, scale_vel_to_dev_, scale_vel_from_dev_);
192 }
193 
194 template <>
195 void NodeCanopen402Driver<rclcpp::Node>::configure(bool called_from_base)
196 {
198  std::optional<double> scale_pos_to_dev;
199  std::optional<double> scale_pos_from_dev;
200  std::optional<double> scale_vel_to_dev;
201  std::optional<double> scale_vel_from_dev;
202  std::optional<int> switching_state;
203  try
204  {
205  scale_pos_to_dev = std::optional(this->config_["scale_pos_to_dev"].as<double>());
206  }
207  catch (...)
208  {
209  }
210  try
211  {
212  scale_pos_from_dev = std::optional(this->config_["scale_pos_from_dev"].as<double>());
213  }
214  catch (...)
215  {
216  }
217  try
218  {
219  scale_vel_to_dev = std::optional(this->config_["scale_vel_to_dev"].as<double>());
220  }
221  catch (...)
222  {
223  }
224  try
225  {
226  scale_vel_from_dev = std::optional(this->config_["scale_vel_from_dev"].as<double>());
227  }
228  catch (...)
229  {
230  }
231  try
232  {
233  switching_state = std::optional(this->config_["switching_state"].as<int>());
234  }
235  catch (...)
236  {
237  }
238 
239  // auto period = this->config_["scale_eff_to_dev"].as<double>();
240  // auto period = this->config_["scale_eff_from_dev"].as<double>();
241  scale_pos_to_dev_ = scale_pos_to_dev.value_or(1000.0);
242  scale_pos_from_dev_ = scale_pos_from_dev.value_or(0.001);
243  scale_vel_to_dev_ = scale_vel_to_dev.value_or(1000.0);
244  scale_vel_from_dev_ = scale_vel_from_dev.value_or(0.001);
245  switching_state_ = (ros2_canopen::State402::InternalState)switching_state.value_or(
246  (int)ros2_canopen::State402::InternalState::Operation_Enable);
247  RCLCPP_INFO(
248  this->node_->get_logger(),
249  "scale_pos_to_dev_ %f\nscale_pos_from_dev_ %f\nscale_vel_to_dev_ %f\nscale_vel_from_dev_ %f\n",
250  scale_pos_to_dev_, scale_pos_from_dev_, scale_vel_to_dev_, scale_vel_from_dev_);
251 }
252 
253 template <class NODETYPE>
254 void NodeCanopen402Driver<NODETYPE>::activate(bool called_from_base)
255 {
257  motor_->registerDefaultModes();
258 }
259 
260 template <class NODETYPE>
262 {
264  timer_->cancel();
265 }
266 
267 template <class NODETYPE>
269 {
271  motor_->handleRead();
272  motor_->handleWrite();
273  publish();
274 }
275 
276 template <class NODETYPE>
278 {
279  sensor_msgs::msg::JointState js_msg;
280  js_msg.name.push_back(this->node_->get_name());
281  js_msg.position.push_back(motor_->get_position() * scale_pos_from_dev_);
282  js_msg.velocity.push_back(motor_->get_speed() * scale_vel_from_dev_);
283  js_msg.effort.push_back(0.0);
284  publish_joint_state->publish(js_msg);
285 }
286 
287 template <class NODETYPE>
289 {
291  motor_ = std::make_shared<Motor402>(this->lely_driver_, switching_state_);
292 }
293 
294 template <class NODETYPE>
296  const std_srvs::srv::Trigger::Request::SharedPtr request,
297  std_srvs::srv::Trigger::Response::SharedPtr response)
298 {
299  if (this->activated_.load())
300  {
301  bool temp = motor_->handleInit();
302  response->success = temp;
303  }
304 }
305 template <class NODETYPE>
307  const std_srvs::srv::Trigger::Request::SharedPtr request,
308  std_srvs::srv::Trigger::Response::SharedPtr response)
309 {
310  if (this->activated_.load())
311  {
312  response->success = motor_->handleRecover();
313  }
314 }
315 template <class NODETYPE>
317  const std_srvs::srv::Trigger::Request::SharedPtr request,
318  std_srvs::srv::Trigger::Response::SharedPtr response)
319 {
320  if (this->activated_.load())
321  {
322  response->success = motor_->handleHalt();
323  }
324 }
325 template <class NODETYPE>
327  const std_srvs::srv::Trigger::Request::SharedPtr request,
328  std_srvs::srv::Trigger::Response::SharedPtr response)
329 {
330  response->success = set_mode_position();
331 }
332 
333 template <class NODETYPE>
335  const std_srvs::srv::Trigger::Request::SharedPtr request,
336  std_srvs::srv::Trigger::Response::SharedPtr response)
337 {
338  response->success = set_mode_velocity();
339 }
340 
341 template <class NODETYPE>
343  const std_srvs::srv::Trigger::Request::SharedPtr request,
344  std_srvs::srv::Trigger::Response::SharedPtr response)
345 {
346  response->success = set_mode_cyclic_position();
347 }
348 
349 template <class NODETYPE>
351  const std_srvs::srv::Trigger::Request::SharedPtr request,
352  std_srvs::srv::Trigger::Response::SharedPtr response)
353 {
354  response->success = set_mode_interpolated_position();
355 }
356 
357 template <class NODETYPE>
359  const std_srvs::srv::Trigger::Request::SharedPtr request,
360  std_srvs::srv::Trigger::Response::SharedPtr response)
361 {
362  response->success = set_mode_cyclic_velocity();
363 }
364 template <class NODETYPE>
366  const std_srvs::srv::Trigger::Request::SharedPtr request,
367  std_srvs::srv::Trigger::Response::SharedPtr response)
368 {
369  response->success = set_mode_torque();
370 }
371 
372 template <class NODETYPE>
374  const canopen_interfaces::srv::COTargetDouble::Request::SharedPtr request,
375  canopen_interfaces::srv::COTargetDouble::Response::SharedPtr response)
376 {
377  if (this->activated_.load())
378  {
379  auto mode = motor_->getMode();
380  double target;
381  if (
384  {
385  target = request->target * scale_pos_to_dev_;
386  }
387  else if (
388  (mode == MotorBase::Velocity) or (mode == MotorBase::Profiled_Velocity) or
390  {
391  target = request->target * scale_vel_to_dev_;
392  }
393  else
394  {
395  target = request->target;
396  }
397 
398  response->success = motor_->setTarget(target);
399  }
400 }
401 
402 template <class NODETYPE>
404 {
405  if (this->activated_.load())
406  {
407  bool temp = motor_->handleInit();
408  return temp;
409  }
410  else
411  {
412  RCLCPP_INFO(this->node_->get_logger(), "Initialisation failed.");
413  return false;
414  }
415 }
416 
417 template <class NODETYPE>
419 {
420  if (this->activated_.load())
421  {
422  return motor_->handleRecover();
423  }
424  else
425  {
426  return false;
427  }
428 }
429 
430 template <class NODETYPE>
432 {
433  if (this->activated_.load())
434  {
435  return motor_->handleHalt();
436  }
437  else
438  {
439  return false;
440  }
441 }
442 
443 template <class NODETYPE>
445 {
446  if (this->activated_.load())
447  {
448  return motor_->enterModeAndWait(mode);
449  }
450  return false;
451 }
452 
453 template <class NODETYPE>
455 {
456  if (this->activated_.load())
457  {
458  if (motor_->getMode() != MotorBase::Profiled_Position)
459  {
460  return motor_->enterModeAndWait(MotorBase::Profiled_Position);
461  }
462  else
463  {
464  return false;
465  }
466  }
467  else
468  {
469  return false;
470  }
471 }
472 
473 template <class NODETYPE>
475 {
476  if (this->activated_.load())
477  {
478  if (motor_->getMode() != MotorBase::Interpolated_Position)
479  {
480  return motor_->enterModeAndWait(MotorBase::Interpolated_Position);
481  }
482  else
483  {
484  return false;
485  }
486  }
487  else
488  {
489  return false;
490  }
491 }
492 
493 template <class NODETYPE>
495 {
496  if (this->activated_.load())
497  {
498  if (motor_->getMode() != MotorBase::Profiled_Velocity)
499  {
500  return motor_->enterModeAndWait(MotorBase::Profiled_Velocity);
501  }
502  else
503  {
504  return false;
505  }
506  }
507  else
508  {
509  return false;
510  }
511 }
512 
513 template <class NODETYPE>
515 {
516  if (this->activated_.load())
517  {
518  if (motor_->getMode() != MotorBase::Cyclic_Synchronous_Position)
519  {
520  return motor_->enterModeAndWait(MotorBase::Cyclic_Synchronous_Position);
521  }
522  else
523  {
524  return false;
525  }
526  }
527  else
528  {
529  return false;
530  }
531 }
532 
533 template <class NODETYPE>
535 {
536  if (this->activated_.load())
537  {
538  if (motor_->getMode() != MotorBase::Cyclic_Synchronous_Velocity)
539  {
540  return motor_->enterModeAndWait(MotorBase::Cyclic_Synchronous_Velocity);
541  }
542  else
543  {
544  return false;
545  }
546  }
547  else
548  {
549  return false;
550  }
551 }
552 
553 template <class NODETYPE>
555 {
556  if (this->activated_.load())
557  {
558  if (motor_->getMode() != MotorBase::Profiled_Torque)
559  {
560  return motor_->enterModeAndWait(MotorBase::Profiled_Torque);
561  }
562  else
563  {
564  return false;
565  }
566  }
567  else
568  {
569  return false;
570  }
571 }
572 
573 template <class NODETYPE>
575 {
576  if (this->activated_.load())
577  {
578  auto mode = motor_->getMode();
579  double scaled_target;
580  if (
583  {
584  scaled_target = target * scale_pos_to_dev_;
585  }
586  else if (
587  (mode == MotorBase::Velocity) or (mode == MotorBase::Profiled_Velocity) or
589  {
590  scaled_target = target * scale_vel_to_dev_;
591  }
592  else
593  {
594  scaled_target = target;
595  }
596  // RCLCPP_INFO(this->node_->get_logger(), "Scaled target %f", scaled_target);
597  return motor_->setTarget(scaled_target);
598  }
599  else
600  {
601  return false;
602  }
603 }
604 
605 #endif
@ Profiled_Velocity
Definition: base.hpp:26
@ Cyclic_Synchronous_Velocity
Definition: base.hpp:32
@ Cyclic_Synchronous_Position
Definition: base.hpp:31
@ Profiled_Position
Definition: base.hpp:24
@ Profiled_Torque
Definition: base.hpp:27
@ Interpolated_Position
Definition: base.hpp:30
@ Velocity
Definition: base.hpp:25
InternalState
Definition: state.hpp:33
Definition: node_canopen_402_driver.hpp:17
void handle_set_mode_cyclic_velocity(const std_srvs::srv::Trigger::Request::SharedPtr request, std_srvs::srv::Trigger::Response::SharedPtr response)
Service Callback to set cyclic velocity mode.
Definition: node_canopen_402_driver_impl.hpp:358
void handle_halt(const std_srvs::srv::Trigger::Request::SharedPtr request, std_srvs::srv::Trigger::Response::SharedPtr response)
Service Callback to halt device.
Definition: node_canopen_402_driver_impl.hpp:316
void handle_init(const std_srvs::srv::Trigger::Request::SharedPtr request, std_srvs::srv::Trigger::Response::SharedPtr response)
Service Callback to initialise device.
Definition: node_canopen_402_driver_impl.hpp:295
bool set_target(double target)
Method to set target.
Definition: node_canopen_402_driver_impl.hpp:574
bool set_mode_velocity()
Method to set profiled velocity mode.
Definition: node_canopen_402_driver_impl.hpp:494
bool set_mode_torque()
Method to set profiled torque mode.
Definition: node_canopen_402_driver_impl.hpp:554
void handle_set_target(const canopen_interfaces::srv::COTargetDouble::Request::SharedPtr request, canopen_interfaces::srv::COTargetDouble::Response::SharedPtr response)
Service Callback to set target.
Definition: node_canopen_402_driver_impl.hpp:373
void handle_set_mode_velocity(const std_srvs::srv::Trigger::Request::SharedPtr request, std_srvs::srv::Trigger::Response::SharedPtr response)
Service Callback to set profiled velocity mode.
Definition: node_canopen_402_driver_impl.hpp:334
void handle_set_mode_interpolated_position(const std_srvs::srv::Trigger::Request::SharedPtr request, std_srvs::srv::Trigger::Response::SharedPtr response)
Service Callback to set interpolated position mode.
Definition: node_canopen_402_driver_impl.hpp:350
void handle_set_mode_torque(const std_srvs::srv::Trigger::Request::SharedPtr request, std_srvs::srv::Trigger::Response::SharedPtr response)
Service Callback to set profiled torque mode.
Definition: node_canopen_402_driver_impl.hpp:365
void handle_set_mode_cyclic_position(const std_srvs::srv::Trigger::Request::SharedPtr request, std_srvs::srv::Trigger::Response::SharedPtr response)
Service Callback to set cyclic position mode.
Definition: node_canopen_402_driver_impl.hpp:342
virtual void poll_timer_callback() override
Definition: node_canopen_402_driver_impl.hpp:268
bool set_mode_interpolated_position()
Method to set interpolated position mode.
Definition: node_canopen_402_driver_impl.hpp:474
void handle_set_mode_position(const std_srvs::srv::Trigger::Request::SharedPtr request, std_srvs::srv::Trigger::Response::SharedPtr response)
Service Callback to set profiled position mode.
Definition: node_canopen_402_driver_impl.hpp:326
void handle_recover(const std_srvs::srv::Trigger::Request::SharedPtr request, std_srvs::srv::Trigger::Response::SharedPtr response)
Service Callback to recover device.
Definition: node_canopen_402_driver_impl.hpp:306
bool halt_motor()
Method to halt device.
Definition: node_canopen_402_driver_impl.hpp:431
bool set_mode_position()
Method to set profiled position mode.
Definition: node_canopen_402_driver_impl.hpp:454
bool init_motor()
Method to initialise device.
Definition: node_canopen_402_driver_impl.hpp:403
bool recover_motor()
Method to recover device.
Definition: node_canopen_402_driver_impl.hpp:418
NodeCanopen402Driver(NODETYPE *node)
Definition: node_canopen_402_driver_impl.hpp:13
void publish()
Definition: node_canopen_402_driver_impl.hpp:277
bool set_operation_mode(uint16_t mode)
Definition: node_canopen_402_driver_impl.hpp:444
bool set_mode_cyclic_velocity()
Method to set cyclic velocity mode.
Definition: node_canopen_402_driver_impl.hpp:534
bool set_mode_cyclic_position()
Method to set cyclic position mode.
Definition: node_canopen_402_driver_impl.hpp:514
virtual void add_to_master() override
Add the driver to master.
Definition: node_canopen_402_driver_impl.hpp:288
virtual void add_to_master()
Add the driver to master.
Definition: node_canopen_base_driver_impl.hpp:111
virtual void poll_timer_callback()
Definition: node_canopen_base_driver_impl.hpp:243
void deactivate()
Deactivate the driver.
Definition: node_canopen_driver.hpp:251
void activate()
Activate the driver.
Definition: node_canopen_driver.hpp:209
void init()
Initialise the driver.
Definition: node_canopen_driver.hpp:113
void configure()
Configure the driver.
Definition: node_canopen_driver.hpp:161
Definition: node_canopen_proxy_driver.hpp:12
Definition: node_canopen_driver.hpp:32
Definition: configuration_manager.hpp:28