joint_feedback_relay_handler.cpp
Go to the documentation of this file.
1 /*
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2013, Southwest Research Institute
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of the Southwest Research Institute, nor the names
16 * of its contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31 
34 #include <algorithm>
35 #include <map>
36 #include <string>
37 #include <vector>
38 
42 
44 {
45 namespace joint_feedback_relay_handler
46 {
47 
49  std::map<int, RobotGroup> &robot_groups)
50 {
51  this->version_0_ = false;
52  bool rtn = JointRelayHandler::init(connection, static_cast<int>(StandardMsgTypes::JOINT_FEEDBACK), robot_groups);
53  // try to read robot_id parameter, if none specified
54  if ((robot_id_ < 0))
55  node_.param("robot_id", robot_id_, 0);
56  return rtn;
57 }
58 
60  std::vector<std::string> &joint_names)
61 {
62  this->version_0_ = true;
63  bool rtn = JointRelayHandler::init(connection, static_cast<int>(StandardMsgTypes::JOINT_FEEDBACK), joint_names);
64 
65  // try to read robot_id parameter, if none specified
66  if ((robot_id_ < 0))
67  node_.param("robot_id", robot_id_, 0);
68 
69  return rtn;
70 }
71 
72 
74  control_msgs::FollowJointTrajectoryFeedback* control_state,
75  sensor_msgs::JointState* sensor_state)
76 {
77  // inspect robot_id field first, to avoid "Failed to Convert" message
78  JointFeedbackMessage tmp_msg;
79 
80  tmp_msg.init(msg_in);
81 
82  if (this->version_0_)
83  return JointRelayHandler::create_messages(msg_in, control_state, sensor_state);
84  else
85  return JointFeedbackRelayHandler::create_messages(msg_in, control_state, sensor_state, tmp_msg.getRobotID());
86 }
87 
89  control_msgs::FollowJointTrajectoryFeedback* control_state,
90  sensor_msgs::JointState* sensor_state, int robot_id)
91 {
92  DynamicJointsGroup all_joint_state;
93  if (!convert_message(msg_in, &all_joint_state, robot_id))
94  {
95  LOG_ERROR("Failed to convert SimpleMessage");
96  return false;
97  }
98  // apply transform, if required
99  DynamicJointsGroup xform_joint_state;
100  if (!transform(all_joint_state, &xform_joint_state))
101  {
102  LOG_ERROR("Failed to transform joint state");
103  return false;
104  }
105 
106  // select specific joints for publishing
107  DynamicJointsGroup pub_joint_state;
108  std::vector<std::string> pub_joint_names;
109  if (!select(xform_joint_state, robot_groups_[robot_id].get_joint_names(), &pub_joint_state, &pub_joint_names))
110  {
111  LOG_ERROR("Failed to select joints for publishing");
112  return false;
113  }
114  // assign values to messages
115  *control_state = control_msgs::FollowJointTrajectoryFeedback(); // always start with a "clean" message
116  control_state->header.stamp = ros::Time::now();
117  control_state->joint_names = pub_joint_names;
118  control_state->actual.positions = pub_joint_state.positions;
119  control_state->actual.velocities = pub_joint_state.velocities;
120  control_state->actual.accelerations = pub_joint_state.accelerations;
121  control_state->actual.time_from_start = pub_joint_state.time_from_start;
122 
123  *sensor_state = sensor_msgs::JointState(); // always start with a "clean" message
124  sensor_state->header.stamp = ros::Time::now();
125  sensor_state->name = pub_joint_names;
126  sensor_state->position = pub_joint_state.positions;
127  sensor_state->velocity = pub_joint_state.velocities;
128 
129  this->pub_controls_[robot_id].publish(*control_state);
130  this->pub_states_[robot_id].publish(*sensor_state);
131 
132  return true;
133 }
134 
135 bool JointFeedbackRelayHandler::convert_message(SimpleMessage& msg_in, DynamicJointsGroup* joint_state, int robot_id)
136 {
137  JointFeedbackMessage joint_feedback_msg;
138  if (!joint_feedback_msg.init(msg_in))
139  {
140  LOG_ERROR("Failed to initialize joint feedback message");
141  return false;
142  }
143 
144  return convert_message(joint_feedback_msg, joint_state, robot_id);
145 }
146 
147 bool JointFeedbackRelayHandler::convert_message(SimpleMessage& msg_in, JointTrajectoryPoint* joint_state)
148 {
149  JointFeedbackMessage joint_feedback_msg;
150  if (!joint_feedback_msg.init(msg_in))
151  {
152  LOG_ERROR("Failed to initialize joint feedback message");
153  return false;
154  }
155 
156  return convert_message(joint_feedback_msg, joint_state);
157 }
158 
160  std::vector<double> &vec,
161  int len)
162 {
163  if ((len < 0) || (len > joints.getMaxNumJoints()))
164  {
165  LOG_ERROR("Failed to copy JointData. Len (%d) out of range (0 to %d)",
166  len, joints.getMaxNumJoints());
167  return false;
168  }
169 
170  vec.resize(len);
171  for (int i = 0; i < len; ++i)
172  vec[i] = joints.getJoint(i);
173 
174  return true;
175 }
176 
177 bool JointFeedbackRelayHandler::convert_message(JointFeedbackMessage& msg_in, DynamicJointsGroup* joint_state,
178  int robot_id)
179 {
181  int num_jnts = robot_groups_[robot_id].get_joint_names().size();
182  // copy position data
183  if (msg_in.getPositions(values))
184  {
185  if (!JointDataToVector(values, joint_state->positions, num_jnts))
186  {
187  LOG_ERROR("Failed to parse position data from JointFeedbackMessage");
188  return false;
189  }
190  }
191  else
192  joint_state->positions.clear();
193 
194  // copy velocity data
195  if (msg_in.getVelocities(values))
196  {
197  if (!JointDataToVector(values, joint_state->velocities, num_jnts))
198  {
199  LOG_ERROR("Failed to parse velocity data from JointFeedbackMessage");
200  return false;
201  }
202  }
203  else
204  joint_state->velocities.clear();
205 
206  // copy acceleration data
207  if (msg_in.getAccelerations(values))
208  {
209  if (!JointDataToVector(values, joint_state->accelerations, num_jnts))
210  {
211  LOG_ERROR("Failed to parse acceleration data from JointFeedbackMessage");
212  return false;
213  }
214  }
215  else
216  joint_state->accelerations.clear();
217 
218  // copy timestamp data
220  if (msg_in.getTime(value))
221  joint_state->time_from_start = ros::Duration(value);
222  else
223  joint_state->time_from_start = ros::Duration(0);
224 
225  return true;
226 }
227 
228 bool JointFeedbackRelayHandler::convert_message(JointFeedbackMessage& msg_in, JointTrajectoryPoint* joint_state)
229 {
231  int num_jnts = all_joint_names_.size();
232 
233  // copy position data
234  if (msg_in.getPositions(values))
235  {
236  if (!JointDataToVector(values, joint_state->positions, num_jnts))
237  {
238  LOG_ERROR("Failed to parse position data from JointFeedbackMessage");
239  return false;
240  }
241  }
242  else
243  joint_state->positions.clear();
244 
245  // copy velocity data
246  if (msg_in.getVelocities(values))
247  {
248  if (!JointDataToVector(values, joint_state->velocities, num_jnts))
249  {
250  LOG_ERROR("Failed to parse velocity data from JointFeedbackMessage");
251  return false;
252  }
253  }
254  else
255  joint_state->velocities.clear();
256 
257  // copy acceleration data
258  if (msg_in.getAccelerations(values))
259  {
260  if (!JointDataToVector(values, joint_state->accelerations, num_jnts))
261  {
262  LOG_ERROR("Failed to parse acceleration data from JointFeedbackMessage");
263  return false;
264  }
265  }
266  else
267  joint_state->accelerations.clear();
268 
269  // copy timestamp data
271  if (msg_in.getTime(value))
272  joint_state->time_from_start = ros::Duration(value);
273  else
274  joint_state->time_from_start = ros::Duration(0);
275 
276  return true;
277 }
278 
279 bool JointFeedbackRelayHandler::select(const DynamicJointsGroup& all_joint_state,
280  const std::vector<std::string>& all_joint_names,
281  DynamicJointsGroup* pub_joint_state, std::vector<std::string>* pub_joint_names)
282 {
283  ROS_ASSERT(all_joint_state.positions.size() == all_joint_names.size());
284 
285  *pub_joint_state = DynamicJointsGroup(); // start with a "clean" message
286  pub_joint_names->clear();
287 
288  // skip over "blank" joint names
289  for (size_t i = 0; i < all_joint_names.size(); ++i)
290  {
291  if (all_joint_names[i].empty())
292  continue;
293  pub_joint_names->push_back(all_joint_names[i]);
294  if (!all_joint_state.positions.empty())
295  pub_joint_state->positions.push_back(all_joint_state.positions[i]);
296  if (!all_joint_state.velocities.empty())
297  pub_joint_state->velocities.push_back(all_joint_state.velocities[i]);
298  if (!all_joint_state.accelerations.empty())
299  pub_joint_state->accelerations.push_back(all_joint_state.accelerations[i]);
300  }
301  pub_joint_state->time_from_start = all_joint_state.time_from_start;
302 
303  return true;
304 }
305 
306 } // namespace joint_feedback_relay_handler
307 } // namespace industrial_robot_client
308 
309 
310 
311 
virtual bool transform(const DynamicJointsGroup &state_in, DynamicJointsGroup *state_out)
Transform joint state before publishing. Can be overridden to implement, e.g. robot-specific joint co...
industrial::shared_types::shared_int getRobotID()
bool init(industrial::smpl_msg_connection::SmplMsgConnection *connection, std::vector< std::string > &joint_names)
bool getPositions(industrial::joint_data::JointData &dest)
bool create_messages(SimpleMessage &msg_in, control_msgs::FollowJointTrajectoryFeedback *control_state, sensor_msgs::JointState *sensor_state)
Convert joint message into publish message-types.
std::vector< double > values
virtual bool create_messages(JointMessage &msg_in, control_msgs::FollowJointTrajectoryFeedback *control_state, sensor_msgs::JointState *sensor_state)
bool init(industrial::simple_message::SimpleMessage &msg)
virtual bool convert_message(SimpleMessage &msg_in, JointTrajectoryPoint *joint_state)
Convert joint message into intermediate message-type.
UINT32 value
static bool JointDataToVector(const industrial::joint_data::JointData &joints, std::vector< double > &vec, int len)
#define LOG_ERROR(format,...)
bool getJoint(industrial::shared_types::shared_int index, industrial::shared_types::shared_real &value) const
bool getTime(industrial::shared_types::shared_real &time)
virtual bool select(const DynamicJointsGroup &all_joint_state, const std::vector< std::string > &all_joint_names, DynamicJointsGroup *pub_joint_state, std::vector< std::string > *pub_joint_names)
bool getVelocities(industrial::joint_data::JointData &dest)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
virtual bool init(SmplMsgConnection *connection, std::vector< std::string > &joint_names)
Class initializer.
static Time now()
#define ROS_ASSERT(cond)
bool getAccelerations(industrial::joint_data::JointData &dest)


motoman_driver
Author(s): Jeremy Zoss (Southwest Research Institute), Ted Miller (MotoROS) (Yaskawa Motoman), Eric Marcil (MotoROS) (Yaskawa Motoman)
autogenerated on Sat May 8 2021 02:27:43