41 #include <boost/lexical_cast.hpp>
47 const std::string
LOGNAME =
"robot_state";
55 static bool _jointStateToRobotState(
const sensor_msgs::JointState& joint_state, RobotState& state)
57 if (joint_state.name.size() != joint_state.position.size())
60 joint_state.name.size(), joint_state.position.size());
64 state.setVariableValues(joint_state);
69 static bool _multiDOFJointsToRobotState(
const sensor_msgs::MultiDOFJointState& mjs, RobotState& state,
72 std::size_t nj = mjs.joint_names.size();
73 if (nj != mjs.transforms.size())
80 Eigen::Isometry3d inv_t;
81 bool use_inv_t =
false;
89 const Eigen::Isometry3d& t2fixed_frame =
tf->getTransform(mjs.header.frame_id);
92 inv_t = t2fixed_frame.inverse();
95 catch (std::exception& ex)
105 "The transform for multi-dof joints was specified in frame '%s' "
106 "but it was not possible to transform that to frame '%s'",
107 mjs.header.frame_id.c_str(), state.getRobotModel()->getModelFrame().c_str());
110 for (std::size_t i = 0; i < nj; ++i)
112 const std::string& joint_name = mjs.joint_names[i];
113 if (!state.getRobotModel()->hasJointModel(joint_name))
122 transf = transf * inv_t;
124 state.setJointPositions(joint_name, transf);
130 static inline void _robotStateToMultiDOFJointState(
const RobotState& state, sensor_msgs::MultiDOFJointState& mjs)
132 const std::vector<const JointModel*>& js = state.getRobotModel()->getMultiDOFJointModels();
133 mjs.joint_names.clear();
134 mjs.transforms.clear();
135 for (
const JointModel* joint_model : js)
137 geometry_msgs::TransformStamped p;
138 if (state.dirtyJointTransform(joint_model))
142 joint_model->computeTransform(state.getJointPositions(joint_model), t);
147 mjs.joint_names.push_back(joint_model->getName());
148 mjs.transforms.push_back(p.transform);
150 mjs.header.frame_id = state.getRobotModel()->getModelFrame();
153 class ShapeVisitorAddToCollisionObject :
public boost::static_visitor<void>
156 ShapeVisitorAddToCollisionObject(moveit_msgs::CollisionObject* obj) :
boost::static_visitor<void>(),
obj_(
obj)
160 void addToObject(
const shapes::ShapeMsg& sm,
const geometry_msgs::Pose& pose)
163 boost::apply_visitor(*
this, sm);
166 void operator()(
const shape_msgs::Plane& shape_msg)
const
168 obj_->planes.push_back(shape_msg);
172 void operator()(
const shape_msgs::Mesh& shape_msg)
const
174 obj_->meshes.push_back(shape_msg);
178 void operator()(
const shape_msgs::SolidPrimitive& shape_msg)
const
180 obj_->primitives.push_back(shape_msg);
185 moveit_msgs::CollisionObject*
obj_;
186 const geometry_msgs::Pose*
pose_;
189 static void _attachedBodyToMsg(
const AttachedBody& attached_body, moveit_msgs::AttachedCollisionObject& aco)
191 aco.link_name = attached_body.getAttachedLinkName();
192 aco.detach_posture = attached_body.getDetachPosture();
193 const std::set<std::string>& touch_links = attached_body.getTouchLinks();
194 aco.touch_links.clear();
195 for (
const std::string& touch_link : touch_links)
196 aco.touch_links.push_back(touch_link);
197 aco.object.header.frame_id = aco.link_name;
198 aco.object.id = attached_body.getName();
200 aco.object.operation = moveit_msgs::CollisionObject::ADD;
201 const std::vector<shapes::ShapeConstPtr>& ab_shapes = attached_body.getShapes();
202 const EigenSTL::vector_Isometry3d& ab_tf = attached_body.getFixedTransforms();
203 ShapeVisitorAddToCollisionObject sv(&aco.object);
204 aco.object.primitives.clear();
205 aco.object.meshes.clear();
206 aco.object.planes.clear();
207 aco.object.primitive_poses.clear();
208 aco.object.mesh_poses.clear();
209 aco.object.plane_poses.clear();
210 for (std::size_t j = 0; j < ab_shapes.size(); ++j)
215 geometry_msgs::Pose p;
217 sv.addToObject(sm, p);
220 aco.object.subframe_names.clear();
221 aco.object.subframe_poses.clear();
222 for (
const auto& frame_pair : attached_body.getSubframeTransforms())
224 aco.object.subframe_names.push_back(frame_pair.first);
225 geometry_msgs::Pose pose;
227 aco.object.subframe_poses.push_back(pose);
231 static void _msgToAttachedBody(
const Transforms*
tf,
const moveit_msgs::AttachedCollisionObject& aco, RobotState& state)
233 if (aco.object.operation == moveit_msgs::CollisionObject::ADD)
235 if (!aco.object.primitives.empty() || !aco.object.meshes.empty() || !aco.object.planes.empty())
237 if (aco.object.primitives.size() != aco.object.primitive_poses.size())
240 "number of poses in collision object message");
244 if (aco.object.meshes.size() != aco.object.mesh_poses.size())
250 if (aco.object.planes.size() != aco.object.plane_poses.size())
256 if (aco.object.subframe_poses.size() != aco.object.subframe_names.size())
262 const LinkModel* lm = state.getLinkModel(aco.link_name);
265 std::vector<shapes::ShapeConstPtr>
shapes;
266 EigenSTL::vector_Isometry3d poses;
268 for (std::size_t i = 0; i < aco.object.primitives.size(); ++i)
279 for (std::size_t i = 0; i < aco.object.meshes.size(); ++i)
290 for (std::size_t i = 0; i < aco.object.planes.size(); ++i)
304 for (std::size_t i = 0; i < aco.object.subframe_poses.size(); ++i)
308 std::string
name = aco.object.subframe_names[i];
309 subframe_poses[
name] = p;
315 bool frame_found =
false;
316 Eigen::Isometry3d t0;
317 t0 = state.getFrameTransform(aco.object.header.frame_id, &frame_found);
320 if (
tf &&
tf->canTransform(aco.object.header.frame_id))
321 t0 =
tf->getTransform(aco.object.header.frame_id);
326 "Cannot properly transform from frame '%s'. "
327 "The pose of the attached body may be incorrect",
328 aco.object.header.frame_id.c_str());
331 Eigen::Isometry3d
t = state.getGlobalLinkTransform(lm).inverse() * t0;
332 for (Eigen::Isometry3d& pose : poses)
334 for (
auto& subframe_pose : subframe_poses)
335 subframe_pose.second =
t * subframe_pose.second;
340 aco.link_name.c_str(), aco.object.id.c_str());
343 if (state.clearAttachedBody(aco.object.id))
345 "The robot state already had an object named '%s' attached to link '%s'. "
346 "The object was replaced.",
347 aco.object.id.c_str(), aco.link_name.c_str());
348 state.attachBody(aco.object.id,
shapes, poses, aco.touch_links, aco.link_name, aco.detach_posture,
350 ROS_DEBUG_NAMED(
LOGNAME,
"Attached object '%s' to link '%s'", aco.object.id.c_str(), aco.link_name.c_str());
357 else if (aco.object.operation == moveit_msgs::CollisionObject::REMOVE)
359 if (!state.clearAttachedBody(aco.object.id))
361 aco.link_name.c_str());
367 static bool _robotStateMsgToRobotStateHelper(
const Transforms*
tf,
const moveit_msgs::RobotState&
robot_state,
368 RobotState& state,
bool copy_attached_bodies)
373 if (!rs.is_diff && rs.joint_state.name.empty() && rs.multi_dof_joint_state.joint_names.empty())
379 bool result1 = _jointStateToRobotState(
robot_state.joint_state, state);
380 bool result2 = _multiDOFJointsToRobotState(
robot_state.multi_dof_joint_state, state,
tf);
381 valid = result1 || result2;
383 if (valid && copy_attached_bodies)
386 state.clearAttachedBodies();
387 for (
const moveit_msgs::AttachedCollisionObject& attached_collision_object :
robot_state.attached_collision_objects)
388 _msgToAttachedBody(
tf, attached_collision_object, state);
403 bool result = _jointStateToRobotState(joint_state, state);
410 bool result = _robotStateMsgToRobotStateHelper(
nullptr,
robot_state, state, copy_attached_bodies);
416 bool copy_attached_bodies)
418 bool result = _robotStateMsgToRobotStateHelper(&
tf,
robot_state, state, copy_attached_bodies);
427 _robotStateToMultiDOFJointState(state,
robot_state.multi_dof_joint_state);
429 if (copy_attached_bodies)
431 std::vector<const AttachedBody*> attached_bodies;
432 state.getAttachedBodies(attached_bodies);
438 const std::vector<const AttachedBody*>& attached_bodies,
439 std::vector<moveit_msgs::AttachedCollisionObject>& attached_collision_objs)
441 attached_collision_objs.resize(attached_bodies.size());
442 for (std::size_t i = 0; i < attached_bodies.size(); ++i)
443 _attachedBodyToMsg(*attached_bodies[i], attached_collision_objs[i]);
448 const std::vector<const JointModel*>& js = state.getRobotModel()->getSingleDOFJointModels();
449 joint_state = sensor_msgs::JointState();
451 for (
const JointModel* joint_model : js)
453 joint_state.name.push_back(joint_model->getName());
454 joint_state.position.push_back(state.getVariablePosition(joint_model->getFirstVariableIndex()));
455 if (state.hasVelocities())
456 joint_state.velocity.push_back(state.getVariableVelocity(joint_model->getFirstVariableIndex()));
460 if (joint_state.velocity.size() != joint_state.position.size())
461 joint_state.velocity.clear();
463 joint_state.header.frame_id = state.getRobotModel()->getModelFrame();
469 if (trajectory.points.empty() || point_id > trajectory.points.size() - 1)
474 if (trajectory.joint_names.empty())
481 if (!trajectory.points[point_id].velocities.empty())
483 if (!trajectory.points[point_id].accelerations.empty())
485 if (!trajectory.points[point_id].effort.empty())
486 state.
setVariableEffort(trajectory.joint_names, trajectory.points[point_id].effort);
491 void robotStateToStream(
const RobotState& state, std::ostream& out,
bool include_header,
const std::string& separator)
496 for (std::size_t i = 0; i < state.getVariableCount(); ++i)
498 out << state.getVariableNames()[i];
501 if (i < state.getVariableCount() - 1)
508 for (std::size_t i = 0; i < state.getVariableCount(); ++i)
510 out << state.getVariablePositions()[i];
513 if (i < state.getVariableCount() - 1)
520 const std::vector<std::string>& joint_groups_ordering,
bool include_header,
521 const std::string& separator)
523 std::stringstream headers;
524 std::stringstream joints;
526 for (
const std::string& joint_group_id : joint_groups_ordering)
528 const JointModelGroup* jmg = state.getRobotModel()->getJointModelGroup(joint_group_id);
533 for (std::size_t i = 0; i < jmg->getVariableCount(); ++i)
535 headers << jmg->getVariableNames()[i] << separator;
540 std::vector<double> group_variable_positions;
541 state.copyJointGroupPositions(jmg, group_variable_positions);
544 for (std::size_t i = 0; i < jmg->getVariableCount(); ++i)
546 joints << group_variable_positions[i] << separator;
552 out << headers.str() << std::endl;
553 out << joints.str() << std::endl;
556 void streamToRobotState(RobotState& state,
const std::string& line,
const std::string& separator)
558 std::stringstream line_stream(line);
562 for (std::size_t i = 0; i < state.getVariableCount(); ++i)
565 if (!std::getline(line_stream, cell, separator[0]))
568 state.getVariablePositions()[i] = boost::lexical_cast<double>(cell.c_str());