SchunkCanopenHardwareInterface.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 #include <urdf_parser/urdf_parser.h>
25 #include <urdf_model/model.h>
26 #include <urdf/model.h>
27 
29 
31 
32 using namespace hardware_interface;
37 
40  : m_node_handle (nh),
41  m_canopen_controller (canopen)
42 {
43  init();
44 }
45 
47 {
48  m_node_ids = m_canopen_controller->getNodeList();
49  size_t num_nodes = m_node_ids.size();
50  m_joint_position_commands.resize(num_nodes);
51  m_joint_position_commands_last.resize(num_nodes);
52  m_joint_positions.resize(num_nodes);
53  m_joint_velocity.resize(num_nodes);
54  m_joint_effort.resize(num_nodes);
55  m_joint_names.clear();
56  m_nodes_in_fault.resize(num_nodes, false);
57 
58  bool rosparam_limits_ok = true;
59 // bool urdf_limits_ok = true;
60 // bool urdf_soft_limits_ok = true;
61 
62 
63 
64 // boost::shared_ptr<urdf::ModelInterface> urdf = urdf::parseURDF("robot_description");
65 
66  urdf::Model urdf_model;
67  if(!m_node_handle.hasParam("robot_description"))
68  {
69  ROS_ERROR("robot description not found!!");
70  }
71  if(!urdf_model.initParam("robot_description"))
72  {
73  ROS_ERROR("robot description parsing error!!");
74  }
75 
76 
77 
78  // Initialize controller
79  for (std::size_t i = 0; i < num_nodes; ++i) {
80  std::string joint_name = "";
81  std::string mapping_key = "~node_mapping_" + boost::lexical_cast<std::string>(static_cast<int>(m_node_ids[i]));
82  ros::param::get(mapping_key, joint_name);
83  m_joint_names.push_back(joint_name);
84  ROS_DEBUG_STREAM("Controller Hardware interface: Loading joint with id " << static_cast<int>(m_node_ids[i]) << " named " << joint_name);
85  if (joint_name == "")
86  {
87  ROS_ERROR_STREAM ("Could not find joint name for canopen device " << static_cast<int>(m_node_ids[i]) <<
88  ". You will not be able to use this device with the controller!");
89  }
90  else
91  {
92  // Create joint state interface
96 
97  // Create position joint interface
102 
103  // Create a joint_limit_interface:
104 
105  // Populate (soft) joint limits from the ros parameter server
106  rosparam_limits_ok = getJointLimits(joint_name, m_node_handle, m_joint_limits);
107  if(!rosparam_limits_ok) {
108  ROS_ERROR_STREAM ("Could not set the joint limits for joint " << joint_name << "!");
109  }
110 
111  // Populate (soft) joint limits from URDF
112  // Limits specified in URDF overwrite existing values in 'limits' and 'soft_limits'
113  // Limits not specified in URDF preserve their existing values
114 /* boost::shared_ptr<const urdf::Joint> urdf_joint = urdf_model.getJoint(joint_name);
115  urdf_limits_ok = getJointLimits(urdf_joint, m_joint_limits);
116  if(!urdf_limits_ok) {
117  ROS_ERROR_STREAM ("Could not set the joint limits for joint " << joint_name << "!");
118  }
119  urdf_soft_limits_ok = getSoftJointLimits(urdf_joint, m_joint_soft_limits);
120  if(!urdf_soft_limits_ok) {
121  ROS_ERROR_STREAM ("Could not set the joint soft limits for joint " << joint_name << "!");
122  }*/
123 
124  // Register handle in joint limits interface
125  PositionJointSoftLimitsHandle limits_handle(hwi_handle, // We read the state and read/write the command
126  m_joint_limits, // Limits spec
127  m_joint_soft_limits); // Soft limits spec
128 
129  m_jnt_limits_interface.registerHandle(limits_handle);
130  }
131  }
132 
133 
134  registerInterface(&m_joint_state_interface); // From RobotHW base class.
135  registerInterface(&m_position_joint_interface); // From RobotHW base class.
136 }
137 
139 {
140  m_is_fault = false;
141  m_joint_positions.resize(m_node_ids.size());
143  for (size_t i = 0; i < m_node_ids.size(); ++i)
144  {
146  m_joint_positions[i] = node->getTargetFeedback();
147  ds402::Statusword node_status = node->getStatus();
148  m_is_fault |= node_status.bit.fault;
149  if (node_status.bit.fault)
150  {
151  if (!m_nodes_in_fault[i])
152  {
153  ROS_ERROR_STREAM ("Node " << static_cast<int>(m_node_ids[i]) << " is in FAULT state");
154  }
155  m_nodes_in_fault[i] = true;
156  }
157  else
158  {
159  m_nodes_in_fault[i] = false;
160  }
161  }
162 }
163 
165 {
166  if (m_node_ids.size() == m_joint_position_commands.size())
167  {
168  // For this position based interface, only the joint limits in degree and velocity are enforced. Acceleration is ignored.
170 
171  std::stringstream commanded_positions;
173  for (size_t i = 0; i < m_node_ids.size(); ++i)
174  {
175  const uint8_t& nr = m_node_ids[i];
176  float pos = m_joint_position_commands[i];
177  try
178  {
179  node = m_canopen_controller->getNode<SchunkPowerBallNode>(nr);
180  }
181  catch (const NotFoundException& e)
182  {
183  ROS_ERROR_STREAM ("One or more nodes could not be found in the controller. " << e.what());
184  return;
185  }
186  m_canopen_controller->getNode<SchunkPowerBallNode>(nr)->setTarget(pos);
187  commanded_positions << pos << " ";
188  }
190  {
191  ROS_DEBUG_STREAM ("Commanded positions: " << commanded_positions.str());
193  }
194  }
195  else
196  {
197  ROS_ERROR ("Number of known joints and number of commanded joints do not match!");
198  }
199 }
200 
201 bool SchunkCanopenHardwareInterface::prepareSwitch(const std::list< hardware_interface::ControllerInfo >& start_list, const std::list< hardware_interface::ControllerInfo >& stop_list)
202 {
203  return hardware_interface::RobotHW::prepareSwitch(start_list, stop_list);
204 }
205 
206 void SchunkCanopenHardwareInterface::doSwitch(const std::list< hardware_interface::ControllerInfo >& start_list, const std::list< hardware_interface::ControllerInfo >& stop_list)
207 {
208  hardware_interface::RobotHW::doSwitch(start_list, stop_list);
209 }
210 
212 {
213  sensor_msgs::JointState joint_msg;
214  joint_msg.name = m_joint_names;
215  joint_msg.header.stamp = ros::Time::now();
216  joint_msg.position = m_joint_positions;
217  joint_msg.velocity = m_joint_velocity;
218  joint_msg.effort = m_joint_effort;
219 
220  return joint_msg;
221 }
222 
223 
virtual void doSwitch(const std::list< hardware_interface::ControllerInfo > &start_list, const std::list< hardware_interface::ControllerInfo > &stop_list)
virtual void doSwitch(const std::list< ControllerInfo > &, const std::list< ControllerInfo > &)
virtual const char * what() const _GLIBCXX_USE_NOEXCEPT
Definition: exceptions.h:168
sensor_msgs::JointState getJointMessage()
Creates a joint_state message from the current joint angles and returns it.
virtual void init()
Initialize the hardware interface.
data union for access to DSP 402 6041 statusword,
Definition: ds402.h:136
This class gives a device specific interface for Schunk Powerballs, as they need some "special" treat...
boost::shared_ptr< CanOpenController > m_canopen_controller
virtual bool prepareSwitch(const std::list< hardware_interface::ControllerInfo > &start_list, const std::list< hardware_interface::ControllerInfo > &stop_list)
void enforceLimits(const ros::Duration &period)
virtual bool prepareSwitch(const std::list< ControllerInfo > &start_list, const std::list< ControllerInfo > &stop_list)
unsigned char uint8_t
This exception is thrown if a requested node or node group does not exist.
Definition: exceptions.h:159
bool getJointLimits(const std::string &joint_name, const ros::NodeHandle &nh, JointLimits &limits)
hardware_interface::PositionJointInterface m_position_joint_interface
hardware_interface::JointStateInterface m_joint_state_interface
joint_limits_interface::JointLimits m_joint_limits
ROSCPP_DECL bool get(const std::string &key, std::string &s)
joint_limits_interface::SoftJointLimits m_joint_soft_limits
SchunkCanopenHardwareInterface(ros::NodeHandle &nh, boost::shared_ptr< CanOpenController > &canopen)
URDF_EXPORT bool initParam(const std::string &param)
joint_limits_interface::PositionJointSoftLimitsInterface m_jnt_limits_interface
#define ROS_DEBUG_STREAM(args)
void registerHandle(const JointStateHandle &handle)
virtual void write(ros::Time time, ros::Duration period)
write the command to the robot hardware.
JointStateHandle getHandle(const std::string &name)
static Time now()
bool hasParam(const std::string &key) const
#define ROS_ERROR_STREAM(args)
#define ROS_ERROR(...)
virtual void read()
Read the state from the robot hardware.


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