joint_feedback_ex_relay_handler.cpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2014, Fraunhofer IPA
5  * Author: Thiago de Freitas
6  *
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the distribution.
17  * * Neither the name of the Southwest Research Institute, nor the names
18  * of its contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include <vector>
35 #include <map>
36 #include <algorithm>
37 #include <string>
41 
46 
48 {
49 namespace joint_feedback_ex_relay_handler
50 {
52  std::map<int, RobotGroup> &robot_groups)
53 {
54  ROS_INFO_STREAM("Creating joint_feedback_ex_relay_handler with " << robot_groups.size() << " groups");
56  this->node_.advertise<control_msgs::FollowJointTrajectoryFeedback>("feedback_states", 1);
58  this->node_.advertise<motoman_msgs::DynamicJointTrajectoryFeedback>("dynamic_feedback_states", 1);
59 
60  this->pub_joint_sensor_state_ = this->node_.advertise<sensor_msgs::JointState>("joint_states", 1);
61 
62  this->robot_groups_ = robot_groups;
63  this->version_0_ = false;
64  bool rtn = JointRelayHandler::init(connection, static_cast<int>(MotomanMsgTypes::ROS_MSG_MOTO_JOINT_FEEDBACK_EX),
65  robot_groups);
66  // try to read groups_number parameter, if none specified
67  if ((groups_number_ < 0))
68  node_.param("groups_number", groups_number_, 0);
69  return rtn;
70 }
71 
73  std::vector<std::string> &joint_names)
74 {
75  this->version_0_ = true;
76  bool rtn = JointRelayHandler::init(connection, static_cast<int>(MotomanMsgTypes::ROS_MSG_MOTO_JOINT_FEEDBACK_EX),
77  joint_names);
78  // try to read groups_number parameter, if none specified
79  if ((groups_number_ < 0))
80  node_.param("groups_number", groups_number_, 0);
81  return rtn;
82 }
83 
84 
86  control_msgs::FollowJointTrajectoryFeedback* control_state,
87  sensor_msgs::JointState* sensor_state)
88 {
89  // inspect groups_number field first, to avoid "Failed to Convert" message
90  JointFeedbackExMessage tmp_msg;
91  tmp_msg.init(msg_in);
92  motoman_msgs::DynamicJointTrajectoryFeedback dynamic_control_state;
93 
94  for (size_t i = 0; i < tmp_msg.getJointMessages().size(); i++)
95  {
96  int group_number = tmp_msg.getJointMessages()[i].getRobotID();
97 
98  if (!create_messages(tmp_msg.getJointMessages()[i], control_state, sensor_state, group_number))
99  {
100  return false;
101  }
102  motoman_msgs::DynamicJointState dyn_joint_state;
103  dyn_joint_state.num_joints = control_state->joint_names.size();
104  dyn_joint_state.group_number = group_number;
105  dyn_joint_state.valid_fields = this->valid_fields_from_message_;
106  dyn_joint_state.positions = control_state->actual.positions;
107  dyn_joint_state.velocities = control_state->actual.velocities;
108  dyn_joint_state.accelerations = control_state->actual.accelerations;
109  dynamic_control_state.joint_feedbacks.push_back(dyn_joint_state);
110  }
111  dynamic_control_state.header.stamp = ros::Time::now();
112  dynamic_control_state.num_groups = tmp_msg.getGroupsNumber();
113  this->dynamic_pub_joint_control_state_.publish(dynamic_control_state);
114 
115  return true;
116 }
117 
119  control_msgs::FollowJointTrajectoryFeedback* control_state,
120  sensor_msgs::JointState* sensor_state, int robot_id)
121 {
122  DynamicJointsGroup all_joint_state;
123  if (!JointFeedbackExRelayHandler::convert_message(msg_in, &all_joint_state, robot_id))
124  {
125  LOG_ERROR("Failed to convert SimpleMessage");
126  return false;
127  }
128  // apply transform, if required
129  DynamicJointsGroup xform_joint_state;
130  if (!transform(all_joint_state, &xform_joint_state))
131  {
132  LOG_ERROR("Failed to transform joint state");
133  return false;
134  }
135 
136  // select specific joints for publishing
137  DynamicJointsGroup pub_joint_state;
138  std::vector<std::string> pub_joint_names;
139  if (!select(xform_joint_state, robot_groups_[robot_id].get_joint_names(), &pub_joint_state, &pub_joint_names))
140  {
141  LOG_ERROR("Failed to select joints for publishing");
142  return false;
143  }
144 
145 
146  // assign values to messages
147  *control_state = control_msgs::FollowJointTrajectoryFeedback(); // always start with a "clean" message
148  control_state->header.stamp = ros::Time::now();
149  control_state->joint_names = pub_joint_names;
150  control_state->actual.positions = pub_joint_state.positions;
151  control_state->actual.velocities = pub_joint_state.velocities;
152  control_state->actual.accelerations = pub_joint_state.accelerations;
153  control_state->actual.time_from_start = pub_joint_state.time_from_start;
154 
155  this->pub_joint_control_state_.publish(*control_state);
156 
157  *sensor_state = sensor_msgs::JointState(); // always start with a "clean" message
158  sensor_state->header.stamp = ros::Time::now();
159  sensor_state->name = pub_joint_names;
160  sensor_state->position = pub_joint_state.positions;
161  sensor_state->velocity = pub_joint_state.velocities;
162 
163  this->pub_joint_sensor_state_.publish(*sensor_state);
164 
165  return true;
166 }
167 
168 bool JointFeedbackExRelayHandler::convert_message(JointFeedbackMessage& msg_in, DynamicJointsGroup* joint_state,
169  int robot_id)
170 {
172 
173  int num_jnts = robot_groups_[robot_id].get_joint_names().size();
174 
175  // copy position data
176  bool position_field = msg_in.getPositions(values);
177  if (position_field)
178  {
179  this->valid_fields_from_message_ |= ValidFieldTypes::POSITION;
180  if (!JointDataToVector(values, joint_state->positions, num_jnts))
181  {
182  LOG_ERROR("Failed to parse position data from JointFeedbackMessage");
183  return false;
184  }
185  }
186  else
187  {
188  joint_state->positions.clear();
189  this->valid_fields_from_message_ &= ~ValidFieldTypes::POSITION;
190  }
191 
192  // copy velocity data
193  bool velocity_field = msg_in.getVelocities(values);
194  if (velocity_field)
195  {
196  this->valid_fields_from_message_ |= ValidFieldTypes::VELOCITY;
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  {
205  joint_state->velocities.clear();
206  this->valid_fields_from_message_ &= ~ValidFieldTypes::VELOCITY;
207  }
208 
209  // copy acceleration data
210  bool acceleration_field = msg_in.getAccelerations(values);
211  if (acceleration_field)
212  {
213  this->valid_fields_from_message_ |= ValidFieldTypes::ACCELERATION;
214  if (!JointDataToVector(values, joint_state->accelerations, num_jnts))
215  {
216  LOG_ERROR("Failed to parse acceleration data from JointFeedbackMessage");
217  return false;
218  }
219  }
220  else
221  {
222  joint_state->accelerations.clear();
223  this->valid_fields_from_message_ &= ~ValidFieldTypes::ACCELERATION;
224  }
225 
226  // copy timestamp data
228  bool time_field = msg_in.getTime(value);
229  if (time_field)
230  {
231  this->valid_fields_from_message_ |= ValidFieldTypes::TIME;
232  joint_state->time_from_start = ros::Duration(value);
233  }
234  else
235  {
236  joint_state->time_from_start = ros::Duration(0);
238  }
239 
240  return true;
241 }
242 
244  std::vector<double> &vec,
245  int len)
246 {
247  if ((len < 0) || (len > joints.getMaxNumJoints()))
248  {
249  LOG_ERROR("Failed to copy JointData. Len (%d) out of range (0 to %d)",
250  len, joints.getMaxNumJoints());
251  return false;
252  }
253 
254  vec.resize(len);
255  for (int i = 0; i < len; ++i)
256  vec[i] = joints.getJoint(i);
257 
258  return true;
259 }
260 
261 
262 } // namespace joint_feedback_ex_relay_handler
263 } // namespace industrial_robot_client
bool init(industrial::smpl_msg_connection::SmplMsgConnection *connection, std::vector< std::string > &joint_names)
bool getPositions(industrial::joint_data::JointData &dest)
void publish(const boost::shared_ptr< M > &message) const
std::vector< double > values
virtual bool init(SmplMsgConnection *connection, std::vector< std::string > &joint_names)
Class initializer.
virtual bool transform(const std::vector< double > &pos_in, std::vector< double > *pos_out)
UINT32 value
virtual bool select(const std::vector< double > &all_joint_pos, const std::vector< std::string > &all_joint_names, std::vector< double > *pub_joint_pos, std::vector< std::string > *pub_joint_names)
Class encapsulated joint feedback ex message generation methods (either to or from a industrial::simp...
virtual bool convert_message(JointFeedbackMessage &msg_in, DynamicJointsGroup *joint_state, int robot_id)
Convert joint message into intermediate message-type.
#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)
static bool JointDataToVector(const industrial::joint_data::JointData &joints, std::vector< double > &vec, int len)
bool getVelocities(industrial::joint_data::JointData &dest)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
industrial::shared_types::shared_int valid_fields_from_message_
bit-mask of (optional) fields that have been initialized with valid data
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
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< industrial::joint_feedback_message::JointFeedbackMessage > getJointMessages()
#define ROS_INFO_STREAM(args)
static Time now()
bool getAccelerations(industrial::joint_data::JointData &dest)
bool init(industrial::simple_message::SimpleMessage &msg)
Initializes message from a simple message.
Enumeration of motoman-specific message types. See simple_message.h for a listing of "standard" messa...


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