SchunkCanopenNode.cpp
Go to the documentation of this file.
1 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*-
2 
3 // -- BEGIN LICENSE BLOCK ----------------------------------------------
4 // This file is part of the SCHUNK Canopen Driver suite.
5 //
6 // This program is free software licensed under the LGPL
7 // (GNU LESSER GENERAL PUBLIC LICENSE Version 3).
8 // You can find a copy of this license in LICENSE folder in the top
9 // directory of the source code.
10 //
11 // © Copyright 2016 SCHUNK GmbH, Lauffen/Neckar Germany
12 // © Copyright 2016 FZI Forschungszentrum Informatik, Karlsruhe, Germany
13 // -- END LICENSE BLOCK ------------------------------------------------
14 
15 //----------------------------------------------------------------------
22 //----------------------------------------------------------------------
23 
24 
25 #include "control_msgs/FollowJointTrajectoryActionFeedback.h"
26 #include "ros/service_server.h"
27 #include "std_msgs/Int16MultiArray.h"
28 
29 
32 #include "icl_core_logging/Logging.h"
33 
34 
35 
36 
38  : m_priv_nh("~"),
39  m_action_server(m_priv_nh, "follow_joint_trajectory",
40  boost::bind(&SchunkCanopenNode::goalCB, this, _1),
41  boost::bind(&SchunkCanopenNode::cancelCB, this, _1), false),
42  m_has_goal(false),
43  m_use_ros_control(false),
44  m_was_disabled(false),
45  m_is_enabled(false),
46  m_homing_active(false),
47  m_nodes_initialized(false)
48 {
49  std::string can_device_name;
50  int frequency = 30;
51  std::vector<std::string> chain_names;
52  std::map<std::string, std::vector<int> > chain_configuratuions;
53  m_chain_handles.clear();
54  sensor_msgs::JointState joint_msg;
55  bool autostart = true;
56 
57  m_priv_nh.getParam("chain_names", chain_names);
58  ros::param::get("~use_ros_control", m_use_ros_control);
59  m_priv_nh.param<std::string>("can_device_name", can_device_name, "auto");
60  m_priv_nh.param<float> ("ppm_profile_velocity", m_ppm_config.profile_velocity, 0.2);
61  m_priv_nh.param<float> ("ppm_profile_acceleration", m_ppm_config.profile_acceleration, 0.2);
62  m_priv_nh.param<bool> ("ppm_use_relative_targets", m_ppm_config.use_relative_targets, false);
63  m_priv_nh.param<bool> ("ppm_change_set_immediately", m_ppm_config.change_set_immediately, true);
64  m_priv_nh.param<bool> ("ppm_use_blending", m_ppm_config.use_blending, true);
65  m_priv_nh.param<bool> ("autostart", autostart, true);
66  m_priv_nh.param<std::string>("traj_controller_name", m_traj_controller_name, "pos_based_pos_traj_controller");
67 
68  // Create a canopen controller
69  try
70  {
71  m_controller = boost::make_shared<CanOpenController>(can_device_name);
72  }
73  catch (const DeviceException& e)
74  {
75  ROS_ERROR_STREAM ("Initializing CAN device failed. Reason: " << e.what());
76  ROS_INFO ("Shutting down now.");
77  return;
78  }
79 
80  // Load SCHUNK powerball specific error codes
81  char const* tmp = std::getenv("CANOPEN_RESOURCE_PATH");
82  if (tmp == NULL)
83  {
85  CanOpen,
87  "The environment variable 'CANOPEN_RESOURCE_PATH' could not be read. No Schunk specific error codes will be used." << endl);
88  }
89  else
90  {
91  std::string emcy_emergency_errors_filename = boost::filesystem::path(tmp / boost::filesystem::path("EMCY_schunk.ini")).string();
92  EMCY::addEmergencyErrorMap( emcy_emergency_errors_filename, "schunk_error_codes");
93  }
94 
95 
96  // Get chain configuration from parameter server
97  ROS_INFO_STREAM ("Can device identifier: " << can_device_name);
98  ROS_INFO_STREAM ("Found " << chain_names.size() << " chains");
99 
100  for (size_t i = 0; i < chain_names.size(); ++i)
101  {
102  std::string name = "chain_" + chain_names[i];
103  m_controller->addGroup<DS402Group>(chain_names[i]);
104  m_chain_handles.push_back(m_controller->getGroup<DS402Group>(chain_names[i]));
105  std::vector<int> chain;
106  try
107  {
108  m_priv_nh.getParam(name, chain);
109  }
110  catch (ros::InvalidNameException e)
111  {
112  ROS_ERROR_STREAM("Parameter Error!");
113  }
114  if (chain.size() == 0)
115  {
116  ROS_ERROR_STREAM("Did not find device list for chain " << chain_names[i] << ". Make sure, that an entry " << name << " exists.");
117  continue;
118  }
119 
120  // Get the chain type
121  name = "chain_" + chain_names[i] + "_type";
122  std::string chain_type = "PowerBall";
123  try
124  {
125  m_priv_nh.getParam(name, chain_type);
126  }
127  catch (ros::InvalidNameException e)
128  {
129  ROS_ERROR_STREAM("Parameter Error!");
130  }
131 
132  // Get the chain transmission factor
133  name = "chain_" + chain_names[i] + "_transmission_factor";
134  double transmission_factor = 1.0;
135  try
136  {
137  m_priv_nh.getParam(name, transmission_factor);
138  if (chain_type != "PowerBall")
139  {
140  ROS_INFO_STREAM ("Chain transmission factor is " << transmission_factor);
141  }
142  }
143  catch (ros::InvalidNameException e)
144  {
145  ROS_ERROR_STREAM("Parameter Error!");
146  }
147 
148 
149  ROS_INFO_STREAM ("Found chain with name " << chain_names[i] << " of type " << chain_type << " containing " << chain.size() << " nodes.");
150  chain_configuratuions[name] = chain;
151  for (size_t j = 0; j < chain.size(); ++j)
152  {
153  if (chain_type == "DS402")
154  {
155  m_controller->addNode<DS402Node>(chain[j], chain_names[i]);
156  m_controller->getNode<DS402Node>(chain[j])->setTransmissionFactor(transmission_factor);
157  }
158  else
159  {
160  m_controller->addNode<SchunkPowerBallNode>(chain[j], chain_names[i]);
161  }
162 
163  std::string joint_name = "";
164  std::string mapping_key = "~node_mapping_" + boost::lexical_cast<std::string>( chain[j]);
165  ros::param::get(mapping_key, joint_name);
166 
167  m_joint_name_mapping[joint_name] = static_cast<uint8_t>(chain[j]);
168  joint_msg.name.push_back(joint_name);
169  }
170  }
171 
172  if (autostart)
173  {
174  initDevices();
175  }
176  else
177  {
178  m_init_service = m_priv_nh.advertiseService("init_devices",
180  }
181 
182 
183  ros::Rate loop_rate(frequency);
184 
185  DS402Node::Ptr node;
186  std_msgs::Int16MultiArray currents;
187 
188  // The robot's status (joint values and currents) will be published periodically in here
189  while (ros::ok())
190  {
191  ros::spinOnce();
192 
194  {
195  joint_msg.position.clear();
196  currents.data.clear();
197  // TODO: Go over all groups. to handle different things. For example, we might not want to
198  // read the current from a gripper...
199  for (std::map<std::string, uint8_t>::iterator it = m_joint_name_mapping.begin();
200  it != m_joint_name_mapping.end();
201  ++it)
202  {
203  const uint8_t& nr = it->second;
204  node = m_controller->getNode<DS402Node>(nr);
205  joint_msg.position.push_back(node->getTargetFeedback());
206 
207  // Schunk nodes write currents into the torque_actual register
208  try
209  {
210  currents.data.push_back(node->getTPDOValue<int16_t>("measured_torque"));
211  }
212  catch (PDOException& e)
213  {
214  ROS_ERROR_STREAM(e.what());
215  currents.data.push_back(0);
216  }
217  }
218  joint_msg.header.stamp = ros::Time::now();
219  m_joint_pub.publish(joint_msg);
220 
221  m_current_pub.publish(currents);
222  }
223  loop_rate.sleep();
224  }
225 }
226 
227 
228 bool SchunkCanopenNode::initDevicesCb(std_srvs::TriggerRequest& req,
229  std_srvs::TriggerResponse& resp)
230 {
231  initDevices();
232  resp.success = true;
233  return resp.success;
234 }
235 
236 
238 {
239 
240  // initialize all nodes, by default this will start ProfilePosition mode, so we're good to enable nodes
241  try {
242  m_controller->initNodes();
243  }
244  catch (const ProtocolException& e)
245  {
246  ROS_ERROR_STREAM ("Caught ProtocolException while initializing devices: " << e.what());
247  ROS_INFO ("Going to shut down now");
248  exit (-1);
249  }
250  catch (const PDOException& e)
251  {
252  ROS_ERROR_STREAM ("Caught PDOException while initializing devices: " << e.what());
253  ROS_INFO ("Going to shut down now");
254  exit (-1);
255  }
256 
258  if (m_use_ros_control)
259  {
261  m_hardware_interface.reset(
263  m_controller_manager.reset(
265 
266  }
267 
268  // Start interface (either action server or ros_control)
269 
270  if (m_use_ros_control)
271  {
273  }
274  else
275  {
276  for (size_t i = 0; i < m_chain_handles.size(); ++i)
277  {
278  try {
279  m_chain_handles[i]->setupProfilePositionMode(m_ppm_config);
280  m_chain_handles[i]->enableNodes(mode);
281  }
282  catch (const ProtocolException& e)
283  {
284  ROS_ERROR_STREAM ("Caught ProtocolException while enabling nodes from chain " <<
285  m_chain_handles[i]->getName() << ". Nodes from this group won't be enabled.");
286  continue;
287  }
288  ROS_INFO_STREAM ("Enabled nodes from chain " << m_chain_handles[i]->getName());
289  }
291  }
292 
293  // Create joint state publisher
294  m_joint_pub = m_pub_nh.advertise<sensor_msgs::JointState>("joint_states", 1);
295  m_current_pub = m_pub_nh.advertise<std_msgs::Int16MultiArray>("joint_currents", 1);
296 
297  // services
301  m_quick_stop_service = m_priv_nh.advertiseService("quick_stop_nodes",
303  m_home_service_all = m_priv_nh.advertiseService("home_reset_offset_all",
305  m_home_service_joint_names = m_priv_nh.advertiseService("home_reset_offset_by_id",
307  m_home_service_canopen_ids = m_priv_nh.advertiseService("home_reset_offset_by_name",
309 
310  m_nodes_initialized = true;
311 }
312 
313 
315 {
316  ROS_INFO ("Executing Trajectory action");
317 
318  /* TODO: Catch errors:
319  * - Joint not enabled
320  * - EmergencyStopState
321  * - Overwriting trajectory
322  * - invalid positions
323  */
324 
325 
326  if (gh.getGoal()->trajectory.joint_names.size() != gh.getGoal()->trajectory.points[0].positions.size())
327  {
328  ROS_ERROR_STREAM ("Number of given joint names (" << gh.getGoal()->trajectory.joint_names.size() <<
329  ") and joint states (" << gh.getGoal()->trajectory.points.size() << ") do not match! Aborting goal!");
330  return;
331  }
332 
333  if (m_has_goal)
334  {
335  ROS_WARN_STREAM ("Sent a new goal while another goal was still running. Depending on the " <<
336  "device configuration this will either result in a queuing or the current trajectory " <<
337  "will be overwritten."
338  );
339  }
340 
341 
342  gh.setAccepted();
343  m_has_goal = true;
344  m_traj_thread = boost::thread(&SchunkCanopenNode::trajThread, this, gh);
345 
346 }
347 
349 {
350  control_msgs::FollowJointTrajectoryActionResult result;
351  control_msgs::FollowJointTrajectoryActionFeedback feedback;
352  feedback.feedback.header = gh.getGoal()->trajectory.header;
353  result.header = gh.getGoal()->trajectory.header;
354 
355  ros::Time start = ros::Time::now();
356  bool targets_reached = true;
357 
358  for (size_t waypoint = 0; waypoint < gh.getGoal()->trajectory.points.size(); ++waypoint)
359  {
360  feedback.feedback.desired.positions.clear();
361  feedback.feedback.joint_names.clear();
362  feedback.feedback.actual.positions.clear();
363  for (size_t i = 0; i < gh.getGoal()->trajectory.joint_names.size(); ++i)
364  {
365 
366  uint8_t nr = m_joint_name_mapping[gh.getGoal()->trajectory.joint_names[i]];
367  float pos = boost::lexical_cast<float>(gh.getGoal()->trajectory.points[waypoint].positions[i]);
368  ROS_INFO_STREAM ("Joint " << static_cast<int>(nr) << ": " << pos);
370  try
371  {
372  node = m_controller->getNode<SchunkPowerBallNode>(nr);
373  }
374  catch (const NotFoundException& e)
375  {
376  ROS_ERROR_STREAM ("One or more nodes could not be found in the controller. " << e.what());
377  result.result.error_code = -2;
378  result.result.error_string = e.what();
379  gh.setAborted(result.result);
380  return;
381  }
382  m_controller->getNode<SchunkPowerBallNode>(nr)->setTarget(pos);
383  feedback.feedback.desired.positions.push_back(pos);
384  feedback.feedback.joint_names.push_back(gh.getGoal()->trajectory.joint_names[i]);
385 
386 
387  pos = node->getTargetFeedback();
388  feedback.feedback.actual.positions.push_back(pos);
389  }
390 
391  m_controller->syncAll();
392  m_controller->enablePPMotion();
393 
394  ros::Duration max_time = gh.getGoal()->goal_time_tolerance;
395 
396  ros::Duration spent_time = start - start;
397  std::vector<bool> reached_vec;
398 
399  // Give the brakes time to open up
400  sleep(1);
401 
402  while ( spent_time < max_time || max_time.isZero() )
403  {
404  try {
405  m_controller->syncAll();
406  }
407  catch (const std::exception& e)
408  {
409  ROS_ERROR_STREAM (e.what());
410  gh.setAborted();
411  return;
412  }
413  usleep(10000);
414 
415  bool waypoint_reached = true;
416  for (size_t i = 0; i < gh.getGoal()->trajectory.joint_names.size(); ++i)
417  {
418  uint8_t nr = m_joint_name_mapping[gh.getGoal()->trajectory.joint_names[i]];
420  waypoint_reached &= node->isTargetReached();
421  float pos = node->getTargetFeedback();
422  // ROS_INFO_STREAM ("Node " << nr << " target reached: " << waypoint_reached <<
423  // ", position is: " << pos
424  // );
425  feedback.feedback.actual.time_from_start = spent_time;
426  feedback.feedback.actual.positions.at(i) = (pos);
427  }
428 
429 
430  gh.publishFeedback(feedback.feedback);
431  targets_reached = waypoint_reached;
432 
433 
434 
435  if (waypoint_reached)
436  {
437  ROS_INFO_STREAM ("Waypoint " << waypoint <<" reached" );
438  break;
439  }
440  spent_time = ros::Time::now() - start;
441  if (spent_time > max_time && !max_time.isZero())
442  {
443  result.result.error_code = -5;
444  result.result.error_string = "Did not reach targets in specified time";
445  gh.setAborted();
446  m_has_goal = false;
447  return;
448  }
449  if (boost::this_thread::interruption_requested() )
450  {
451  ROS_ERROR ("Interruption requested");
452  m_has_goal = false;
453  return;
454  }
455  }
456  }
457 
458  if (targets_reached)
459  {
460  ROS_INFO ("All targets reached" );
461  result.result.error_code = 0;
462  result.result.error_string = "All targets successfully reached";
463  gh.setSucceeded(result.result);
464  }
465  else
466  {
467  ROS_INFO ("Not all targets reached" );
468  result.result.error_code = -5;
469  result.result.error_string = "Did not reach targets in specified time";
470  gh.setAborted();
471  }
472  m_has_goal = false;
473 }
474 
475 
477 {
478  m_is_enabled = false;
479  ROS_INFO ("Canceling Trajectory action");
480 
481  m_traj_thread.interrupt();
482  ROS_INFO ("Stopped trajectory thread");
483 
484  for (size_t i = 0; i < m_chain_handles.size(); ++i)
485  {
486  m_chain_handles[i]->quickStop();
487  }
488  ROS_INFO ("Device stopped");
489  sleep(1);
490  for (size_t i = 0; i < m_chain_handles.size(); ++i)
491  {
492  m_chain_handles[i]->enableNodes();
493  m_is_enabled = true;
494  }
495 
496  control_msgs::FollowJointTrajectoryActionResult result;
497  result.result.error_code = 0;
498  result.result.error_string = "Trajectory preempted by user";
499 
500  gh.setCanceled(result.result);
501 }
502 
504 {
505  ros::Duration elapsed_time;
506  ros::Time last_time = ros::Time::now();
507  ros::Time current_time = ros::Time::now();
508 
509  m_controller->syncAll();
510  sleep(0.5);
511 
512  for (size_t i = 0; i < m_chain_handles.size(); ++i)
513  {
514  try {
516  }
517  catch (const ProtocolException& e)
518  {
519  ROS_ERROR_STREAM ("Caught ProtocolException while enabling nodes");
520  continue;
521  }
522  m_controller->syncAll();
523  }
524  m_is_enabled = true;
525 
526  size_t counter = 0;
527 
528  while (ros::ok() && !m_homing_active) {
529  current_time = ros::Time::now();
530  elapsed_time = current_time - last_time;
531  last_time = current_time;
532  // Input
533  m_hardware_interface->read();
534  sensor_msgs::JointState joint_msg = m_hardware_interface->getJointMessage();
535  if (m_joint_pub)
536  {
537  m_joint_pub.publish (joint_msg);
538  }
539  if (m_hardware_interface->isFault() && m_is_enabled)
540  {
541  m_controller_manager->getControllerByName(m_traj_controller_name)->stopRequest(ros::Time::now());
542  ROS_ERROR ("Some nodes are in FAULT state! No commands will be sent. Once the fault is removed, call the enable_nodes service.");
543  m_is_enabled = false;
544  }
545  // Control
546  m_controller->syncAll();
548  {
549  ROS_INFO ("Recovering from FAULT state. Resetting controller");
550  m_controller_manager->update(current_time, elapsed_time, true);
551  m_was_disabled = false;
552  }
553  else if (m_is_enabled)
554  {
555  m_controller_manager->update(current_time, elapsed_time);
556  /* Give the controller some time, otherwise it will send a 0 waypoint vector which
557  * might lead into a following error, if joints are not at 0
558  * TODO: Find a better solution for that.
559  */
560  if (counter > 20)
561  {
562  // Output
563  m_hardware_interface->write(current_time, elapsed_time);
564  }
565  else
566  {
567  for (size_t i = 0; i < m_chain_handles.size(); ++i)
568  {
569  m_chain_handles[i]->setTarget(std::vector<float>(joint_msg.position.begin(), joint_msg.position.end()));
570  }
571  }
572  }
573 
574 // node->printStatus();
575 
576 
577  ++counter;
578  usleep(10000);
579  }
580 
581  ROS_INFO ("Shutting down ros_control_loop thread.");
582 }
583 
584 bool SchunkCanopenNode::enableNodes(std_srvs::TriggerRequest& req, std_srvs::TriggerResponse& resp)
585 {
586  m_controller_manager->getControllerByName(m_traj_controller_name)->startRequest(ros::Time::now());
587  try
588  {
589  for (size_t i = 0; i < m_chain_handles.size(); ++i)
590  {
591  m_chain_handles[i]->enableNodes();
592  }
593  }
594  catch (const ProtocolException& e)
595  {
596  ROS_ERROR_STREAM ( "Error while enabling nodes: " << e.what());
597  }
598  m_was_disabled = true;
599  m_is_enabled = true;
600  resp.success = true;
601  return true;
602 }
603 
604 bool SchunkCanopenNode::closeBrakes(std_srvs::TriggerRequest& req, std_srvs::TriggerResponse& resp)
605 {
606  try
607  {
608  for (size_t i = 0; i < m_chain_handles.size(); ++i)
609  {
610  m_chain_handles[i]->closeBrakes();
611  }
612  }
613  catch (const ProtocolException& e)
614  {
615  ROS_ERROR_STREAM ( "Error while enabling nodes: " << e.what());
616  }
617  resp.success = true;
618  m_was_disabled = true;
619  m_is_enabled = false;
620  m_controller_manager->getControllerByName(m_traj_controller_name)->stopRequest(ros::Time::now());
621 
622  ROS_INFO ("Closed brakes for all nodes. For reenabling, please use the enable_nodes service. Thank you for your attention.");
623  return true;
624 }
625 
626 bool SchunkCanopenNode::quickStopNodes(std_srvs::TriggerRequest& req, std_srvs::TriggerResponse& resp)
627 {
628  m_is_enabled = false;
629  if (!m_use_ros_control)
630  {
631  m_traj_thread.interrupt();
632  ROS_INFO ("Stopped trajectory thread");
633  }
634 
635  try
636  {
637  for (size_t i = 0; i < m_chain_handles.size(); ++i)
638  {
639  m_chain_handles[i]->quickStop();
640  }
641  }
642  catch (const ProtocolException& e)
643  {
644  ROS_ERROR_STREAM ( "Error while quick stopping nodes: " << e.what());
645  }
646  resp.success = true;
647  m_was_disabled = false;
648  m_controller_manager->getControllerByName(m_traj_controller_name)->stopRequest(ros::Time::now());
649  ROS_INFO ("Quick stopped all nodes. For reenabling, please use the enable_nodes service. Thank you for your attention.");
650  return true;
651 }
652 
653 bool SchunkCanopenNode::homeAllNodes(schunk_canopen_driver::HomeAllRequest& req,
654  schunk_canopen_driver::HomeAllResponse& resp)
655 {
656  schunk_canopen_driver::HomeWithIDsRequest req_fwd;
657  schunk_canopen_driver::HomeWithIDsResponse resp_fwd;
658  req_fwd.node_ids = m_controller->getNodeList();
659 
660 
661  homeNodesCanIds (req_fwd, resp_fwd);
662  resp.success = resp_fwd.success;
663  return resp.success;
664 }
665 
666 
667 bool SchunkCanopenNode::homeNodesJointNames(schunk_canopen_driver::HomeWithJointNamesRequest& req,
668  schunk_canopen_driver::HomeWithJointNamesResponse& resp)
669 {
670  schunk_canopen_driver::HomeWithIDsRequest req_fwd;
671  schunk_canopen_driver::HomeWithIDsResponse resp_fwd;
672  for (std::vector<std::string>::iterator it = req.joint_names.begin();
673  it != req.joint_names.end();
674  ++it)
675  {
676  if (m_joint_name_mapping.find(*it) != m_joint_name_mapping.end())
677  {
678  req_fwd.node_ids.push_back(m_joint_name_mapping[*it]);
679  }
680  else
681  {
682  ROS_ERROR_STREAM ("Could not find joint " << *it << ". No homing will be performed for this joint.");
683  }
684  }
685  homeNodesCanIds (req_fwd, resp_fwd);
686  resp.success = resp_fwd.success;
687  return resp.success;
688 }
689 
690 
691 bool SchunkCanopenNode::homeNodesCanIds(schunk_canopen_driver::HomeWithIDsRequest& req,
692  schunk_canopen_driver::HomeWithIDsResponse& resp)
693 {
694  try
695  {
696  for (size_t i = 0; i < m_chain_handles.size(); ++i)
697  {
698  m_chain_handles[i]->disableNodes();
699  }
700  }
701  catch (const ProtocolException& e)
702  {
703  ROS_ERROR_STREAM ( "Error while stopping nodes: " << e.what());
704  }
705 
706  m_homing_active = true;
707  m_is_enabled = false;
708 
709  for (std::vector<uint8_t>::iterator it = req.node_ids.begin(); it != req.node_ids.end(); ++it)
710  {
711  const uint8_t& id = *it;
713  try
714  {
715  node->home();
716  }
717  catch (const DeviceException& e)
718  {
719  ROS_ERROR_STREAM ( "Error while homing node " << static_cast<int>(id) << ": " << e.what());
720  }
721  }
722 
723  if (m_use_ros_control)
724  {
726  }
727 
728  m_homing_active = false;
729  m_was_disabled = true;
730  m_is_enabled = true;
731  resp.success = true;
732  return resp.success;
733 }
734 
735 
736 int main(int argc, char **argv)
737 {
738  ros::init(argc, argv, "schunk_chain");
739  icl_core::logging::initialize(argc, argv);
740 
741  SchunkCanopenNode my_schunk_node;
742 
743  return 0;
744 }
void publishFeedback(const Feedback &feedback)
bool initialize(int &argc, char *argv[], bool remove_read_arguments)
bool homeAllNodes(schunk_canopen_driver::HomeAllRequest &req, schunk_canopen_driver::HomeAllResponse &resp)
Perform a reset offset for all nodes. You should call this service, after driving the devices to thei...
virtual const char * what() const _GLIBCXX_USE_NOEXCEPT
Definition: exceptions.h:168
void publish(const boost::shared_ptr< M > &message) const
CanOpenController::Ptr m_controller
ros::ServiceServer m_enable_service
void goalCB(actionlib::ServerGoalHandle< control_msgs::FollowJointTrajectoryAction > gh)
actionlib::ActionServer< control_msgs::FollowJointTrajectoryAction > m_action_server
Basic CanOpen exception that contains the Object dictionary index and subindex.
Definition: exceptions.h:37
std::vector< DS402Group::Ptr > m_chain_handles
This class gives a device specific interface for Schunk Powerballs, as they need some "special" treat...
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
std::string getName(void *handle)
boost::shared_ptr< SchunkCanopenHardwareInterface > m_hardware_interface
boost::shared_ptr< const Goal > getGoal() const
virtual const char * what() const _GLIBCXX_USE_NOEXCEPT
Definition: exceptions.h:144
bool closeBrakes(std_srvs::TriggerRequest &req, std_srvs::TriggerResponse &resp)
Close the brakes on all nodes. Use this when the device is standing still for a longer time to reduce...
bool homeNodesCanIds(schunk_canopen_driver::HomeWithIDsRequest &req, schunk_canopen_driver::HomeWithIDsResponse &resp)
Perform a reset offset for a given list of nodes. You should call this service, after driving the dev...
The DS402Group class is the base class for canOpen devices implementing the DS402 device protocol (mo...
Definition: DS402Group.h:45
boost::thread m_ros_control_thread
bool quickStopNodes(std_srvs::TriggerRequest &req, std_srvs::TriggerResponse &resp)
Performs a quick stop on all nodes. You should prefer this service call to aborting the followJointTr...
void trajThread(actionlib::ServerGoalHandle< control_msgs::FollowJointTrajectoryAction > &gh)
Control loop thread when not using ros_control.
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
ros::ServiceServer m_quick_stop_service
bool use_blending
If set to true, the device will blend over to a new setpoint. Defaults to true.
Definition: ds402.h:213
PDO related exceptions go here.
Definition: exceptions.h:114
void initDevices()
Function that actually initializes the devices. Will get called either on startup (if autostart is al...
void setCanceled(const Result &result=Result(), const std::string &text=std::string(""))
#define LOGGING_WARNING_C(streamname, classname, arg)
unsigned int sleep(unsigned int seconds)
The CanOpenController class is the main entry point for any calls to the canOpen System.
void setAccepted(const std::string &text=std::string(""))
ds402::ProfilePositionModeConfiguration m_ppm_config
bool initDevicesCb(std_srvs::TriggerRequest &req, std_srvs::TriggerResponse &resp)
Triggers initialization of the canopen devices.
int main(int argc, char **argv)
unsigned char uint8_t
void setSucceeded(const Result &result=Result(), const std::string &text=std::string(""))
bool use_relative_targets
This parameter influences the interpretation of new set points. If set to true, new set point positio...
Definition: ds402.h:207
This exception is thrown if a requested node or node group does not exist.
Definition: exceptions.h:159
float profile_acceleration
This will be used for both acceleration ramps.
Definition: ds402.h:179
ROSCPP_DECL bool get(const std::string &key, std::string &s)
ThreadStream & endl(ThreadStream &stream)
#define ROS_INFO(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
ROSCPP_DECL bool ok()
ros::Publisher m_joint_pub
std::map< std::string, uint8_t > m_joint_name_mapping
ros::ServiceServer m_home_service_all
ros::ServiceServer m_init_service
ros::ServiceServer m_close_brakes_service
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
bool enableNodes(std_srvs::TriggerRequest &req, std_srvs::TriggerResponse &resp)
This service call enables the devices after a fault, a quick stop or simply when the brakes have been...
If something goes wrong with the host&#39;s CAN controller, this exception will be used.
Definition: exceptions.h:135
#define ROS_WARN_STREAM(args)
bool sleep()
ros::ServiceServer m_home_service_canopen_ids
void setAborted(const Result &result=Result(), const std::string &text=std::string(""))
void cancelCB(actionlib::ServerGoalHandle< control_msgs::FollowJointTrajectoryAction > gh)
boost::shared_ptr< controller_manager::ControllerManager > m_controller_manager
virtual const char * what() const _GLIBCXX_USE_NOEXCEPT
Definition: exceptions.h:123
ros::Publisher m_current_pub
#define ROS_INFO_STREAM(args)
This class defines a ros-control hardware interface.
signed short int16_t
bool getParam(const std::string &key, std::string &s) const
static Time now()
std::string m_traj_controller_name
bool homeNodesJointNames(schunk_canopen_driver::HomeWithJointNamesRequest &req, schunk_canopen_driver::HomeWithJointNamesResponse &resp)
Perform a reset offset for a given list of nodes. You should call this service, after driving the dev...
ros::ServiceServer m_home_service_joint_names
virtual const char * what() const _GLIBCXX_USE_NOEXCEPT
Definition: exceptions.h:50
#define ROS_ERROR_STREAM(args)
void rosControlLoop()
When using ros_control this will perform the control loop in a separate thread.
bool change_set_immediately
If this is set to true the device will not ramp down at a setpoint if a following one is given...
Definition: ds402.h:199
ROSCPP_DECL void spinOnce()
ros::NodeHandle m_pub_nh
#define ROS_ERROR(...)
Class that holds devices according to the DS402 (drives and motion control) specification.
Definition: DS402Node.h:43
ros::NodeHandle m_priv_nh
boost::thread m_traj_thread
int usleep(unsigned long useconds)


schunk_canopen_driver
Author(s): Felix Mauch , Georg Heppner
autogenerated on Mon Jun 10 2019 15:07:49