00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <moveit/robot_state/conversions.h>
00039 #include <geometric_shapes/shape_operations.h>
00040 #include <eigen_conversions/eigen_msg.h>
00041
00042 namespace moveit
00043 {
00044 namespace core
00045 {
00046
00047
00048
00049
00050
00051 namespace
00052 {
00053
00054 static bool _jointStateToRobotState(const sensor_msgs::JointState &joint_state, RobotState& state)
00055 {
00056 if (joint_state.name.size() != joint_state.position.size())
00057 {
00058 logError("Different number of names and positions in JointState message: %u, %u",
00059 (unsigned int)joint_state.name.size(), (unsigned int)joint_state.position.size());
00060 return false;
00061 }
00062
00063 state.setVariableValues(joint_state);
00064
00065 return true;
00066 }
00067
00068 static bool _multiDOFJointsToRobotState(const sensor_msgs::MultiDOFJointState &mjs, RobotState& state, const Transforms *tf)
00069 {
00070 std::size_t nj = mjs.joint_names.size();
00071 if (nj != mjs.transforms.size())
00072 {
00073 logError("Different number of names, values or frames in MultiDOFJointState message.");
00074 return false;
00075 }
00076
00077 bool error = false;
00078 Eigen::Affine3d inv_t;
00079 bool use_inv_t = false;
00080
00081 if (nj > 0 && !Transforms::sameFrame(mjs.header.frame_id, state.getRobotModel()->getModelFrame()))
00082 {
00083 if (tf)
00084 try
00085 {
00086
00087 const Eigen::Affine3d &t2fixed_frame = tf->getTransform(mjs.header.frame_id);
00088
00089 inv_t = t2fixed_frame.inverse();
00090 use_inv_t = true;
00091 }
00092 catch (std::runtime_error&)
00093 {
00094 error = true;
00095 }
00096 else
00097 error = true;
00098
00099 if (error)
00100 logWarn("The transform for multi-dof joints was specified in frame '%s' but it was not possible to transform that to frame '%s'",
00101 mjs.header.frame_id.c_str(), state.getRobotModel()->getModelFrame().c_str());
00102 }
00103
00104 for (std::size_t i = 0 ; i < nj ; ++i)
00105 {
00106 const std::string &joint_name = mjs.joint_names[i];
00107 if (!state.getRobotModel()->hasJointModel(joint_name))
00108 {
00109 logWarn("No joint matching multi-dof joint '%s'", joint_name.c_str());
00110 error = true;
00111 continue;
00112 }
00113 Eigen::Affine3d transf;
00114 tf::transformMsgToEigen(mjs.transforms[i], transf);
00115
00116 if (use_inv_t)
00117 transf = transf * inv_t;
00118
00119 state.setJointPositions(joint_name, transf);
00120 }
00121
00122 return !error;
00123 }
00124
00125 static inline void _robotStateToMultiDOFJointState(const RobotState& state, sensor_msgs::MultiDOFJointState &mjs)
00126 {
00127 const std::vector<const JointModel*> &js = state.getRobotModel()->getMultiDOFJointModels();
00128 mjs.joint_names.clear();
00129 mjs.transforms.clear();
00130 for (std::size_t i = 0 ; i < js.size() ; ++i)
00131 {
00132 geometry_msgs::Transform p;
00133 if (state.dirtyJointTransform(js[i]))
00134 {
00135 Eigen::Affine3d t;
00136 t.setIdentity();
00137 js[i]->computeTransform(state.getJointPositions(js[i]), t);
00138 tf::transformEigenToMsg(t, p);
00139 }
00140 else
00141 tf::transformEigenToMsg(state.getJointTransform(js[i]), p);
00142 mjs.joint_names.push_back(js[i]->getName());
00143 mjs.transforms.push_back(p);
00144 }
00145 mjs.header.frame_id = state.getRobotModel()->getModelFrame();
00146 }
00147
00148 class ShapeVisitorAddToCollisionObject : public boost::static_visitor<void>
00149 {
00150 public:
00151
00152 ShapeVisitorAddToCollisionObject(moveit_msgs::CollisionObject *obj) :
00153 boost::static_visitor<void>(), obj_(obj)
00154 {
00155 }
00156
00157 void addToObject(const shapes::ShapeMsg &sm, const geometry_msgs::Pose &pose)
00158 {
00159 pose_ = &pose;
00160 boost::apply_visitor(*this, sm);
00161 }
00162
00163 void operator()(const shape_msgs::Plane &shape_msg) const
00164 {
00165 obj_->planes.push_back(shape_msg);
00166 obj_->plane_poses.push_back(*pose_);
00167 }
00168
00169 void operator()(const shape_msgs::Mesh &shape_msg) const
00170 {
00171 obj_->meshes.push_back(shape_msg);
00172 obj_->mesh_poses.push_back(*pose_);
00173 }
00174
00175 void operator()(const shape_msgs::SolidPrimitive &shape_msg) const
00176 {
00177 obj_->primitives.push_back(shape_msg);
00178 obj_->primitive_poses.push_back(*pose_);
00179 }
00180
00181 private:
00182
00183 moveit_msgs::CollisionObject *obj_;
00184 const geometry_msgs::Pose *pose_;
00185 };
00186
00187 static void _attachedBodyToMsg(const AttachedBody &attached_body, moveit_msgs::AttachedCollisionObject &aco)
00188 {
00189 aco.link_name = attached_body.getAttachedLinkName();
00190 aco.detach_posture = attached_body.getDetachPosture();
00191 const std::set<std::string> &touch_links = attached_body.getTouchLinks();
00192 aco.touch_links.clear();
00193 for (std::set<std::string>::const_iterator it = touch_links.begin() ; it != touch_links.end() ; ++it)
00194 aco.touch_links.push_back(*it);
00195 aco.object.header.frame_id = aco.link_name;
00196 aco.object.id = attached_body.getName();
00197
00198 aco.object.operation = moveit_msgs::CollisionObject::ADD;
00199 const std::vector<shapes::ShapeConstPtr>& ab_shapes = attached_body.getShapes();
00200 const EigenSTL::vector_Affine3d& ab_tf = attached_body.getFixedTransforms();
00201 ShapeVisitorAddToCollisionObject sv(&aco.object);
00202 aco.object.primitives.clear();
00203 aco.object.meshes.clear();
00204 aco.object.planes.clear();
00205 aco.object.primitive_poses.clear();
00206 aco.object.mesh_poses.clear();
00207 aco.object.plane_poses.clear();
00208 for (std::size_t j = 0 ; j < ab_shapes.size() ; ++j)
00209 {
00210 shapes::ShapeMsg sm;
00211 if (shapes::constructMsgFromShape(ab_shapes[j].get(), sm))
00212 {
00213 geometry_msgs::Pose p;
00214 tf::poseEigenToMsg(ab_tf[j], p);
00215 sv.addToObject(sm, p);
00216 }
00217 }
00218 }
00219
00220 static void _msgToAttachedBody(const Transforms *tf, const moveit_msgs::AttachedCollisionObject &aco, RobotState& state)
00221 {
00222 if (aco.object.operation == moveit_msgs::CollisionObject::ADD)
00223 {
00224 if (!aco.object.primitives.empty() || !aco.object.meshes.empty() || !aco.object.planes.empty())
00225 {
00226 if (aco.object.primitives.size() != aco.object.primitive_poses.size())
00227 {
00228 logError("Number of primitive shapes does not match number of poses in collision object message");
00229 return;
00230 }
00231
00232 if (aco.object.meshes.size() != aco.object.mesh_poses.size())
00233 {
00234 logError("Number of meshes does not match number of poses in collision object message");
00235 return;
00236 }
00237
00238 if (aco.object.planes.size() != aco.object.plane_poses.size())
00239 {
00240 logError("Number of planes does not match number of poses in collision object message");
00241 return;
00242 }
00243
00244 const LinkModel *lm = state.getLinkModel(aco.link_name);
00245 if (lm)
00246 {
00247 std::vector<shapes::ShapeConstPtr> shapes;
00248 EigenSTL::vector_Affine3d poses;
00249
00250 for (std::size_t i = 0 ; i < aco.object.primitives.size() ; ++i)
00251 {
00252 shapes::Shape *s = shapes::constructShapeFromMsg(aco.object.primitives[i]);
00253 if (s)
00254 {
00255 Eigen::Affine3d p;
00256 tf::poseMsgToEigen(aco.object.primitive_poses[i], p);
00257 shapes.push_back(shapes::ShapeConstPtr(s));
00258 poses.push_back(p);
00259 }
00260 }
00261 for (std::size_t i = 0 ; i < aco.object.meshes.size() ; ++i)
00262 {
00263 shapes::Shape *s = shapes::constructShapeFromMsg(aco.object.meshes[i]);
00264 if (s)
00265 {
00266 Eigen::Affine3d p;
00267 tf::poseMsgToEigen(aco.object.mesh_poses[i], p);
00268 shapes.push_back(shapes::ShapeConstPtr(s));
00269 poses.push_back(p);
00270 }
00271 }
00272 for (std::size_t i = 0 ; i < aco.object.planes.size() ; ++i)
00273 {
00274 shapes::Shape *s = shapes::constructShapeFromMsg(aco.object.planes[i]);
00275 if (s)
00276 {
00277 Eigen::Affine3d p;
00278 tf::poseMsgToEigen(aco.object.plane_poses[i], p);
00279
00280 shapes.push_back(shapes::ShapeConstPtr(s));
00281 poses.push_back(p);
00282 }
00283 }
00284
00285
00286 if (!Transforms::sameFrame(aco.object.header.frame_id, aco.link_name))
00287 {
00288 Eigen::Affine3d t0;
00289 if (state.knowsFrameTransform(aco.object.header.frame_id))
00290 t0 = state.getFrameTransform(aco.object.header.frame_id);
00291 else
00292 if (tf && tf->canTransform(aco.object.header.frame_id))
00293 t0 = tf->getTransform(aco.object.header.frame_id);
00294 else
00295 {
00296 t0.setIdentity();
00297 logError("Cannot properly transform from frame '%s'. The pose of the attached body may be incorrect", aco.object.header.frame_id.c_str());
00298 }
00299 Eigen::Affine3d t = state.getGlobalLinkTransform(lm).inverse() * t0;
00300 for (std::size_t i = 0 ; i < poses.size() ; ++i)
00301 poses[i] = t * poses[i];
00302 }
00303
00304 if (shapes.empty())
00305 logError("There is no geometry to attach to link '%s' as part of attached body '%s'", aco.link_name.c_str(), aco.object.id.c_str());
00306 else
00307 {
00308 if (state.clearAttachedBody(aco.object.id))
00309 logDebug("The robot state already had an object named '%s' attached to link '%s'. The object was replaced.",
00310 aco.object.id.c_str(), aco.link_name.c_str());
00311 state.attachBody(aco.object.id, shapes, poses, aco.touch_links, aco.link_name, aco.detach_posture);
00312 logDebug("Attached object '%s' to link '%s'", aco.object.id.c_str(), aco.link_name.c_str());
00313 }
00314 }
00315 }
00316 else
00317 logError("The attached body for link '%s' has no geometry", aco.link_name.c_str());
00318 }
00319 else
00320 if (aco.object.operation == moveit_msgs::CollisionObject::REMOVE)
00321 {
00322 state.clearAttachedBody(aco.object.id);
00323 }
00324 else
00325 logError("Unknown collision object operation: %d", aco.object.operation);
00326 }
00327
00328 static bool _robotStateMsgToRobotStateHelper(const Transforms *tf, const moveit_msgs::RobotState &robot_state, RobotState& state, bool copy_attached_bodies)
00329 {
00330 bool result1 = _jointStateToRobotState(robot_state.joint_state, state);
00331 bool result2 = _multiDOFJointsToRobotState(robot_state.multi_dof_joint_state, state, tf);
00332
00333 if (copy_attached_bodies)
00334 {
00335 if (!robot_state.is_diff)
00336 state.clearAttachedBodies();
00337 for (std::size_t i = 0 ; i < robot_state.attached_collision_objects.size() ; ++i)
00338 _msgToAttachedBody(tf, robot_state.attached_collision_objects[i], state);
00339 }
00340
00341 return result1 && result2;
00342 }
00343
00344 }
00345 }
00346 }
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357 bool moveit::core::jointStateToRobotState(const sensor_msgs::JointState &joint_state, RobotState& state)
00358 {
00359 bool result = _jointStateToRobotState(joint_state, state);
00360 state.update();
00361 return result;
00362 }
00363
00364 bool moveit::core::robotStateMsgToRobotState(const moveit_msgs::RobotState &robot_state, RobotState& state, bool copy_attached_bodies)
00365 {
00366 bool result = _robotStateMsgToRobotStateHelper(NULL, robot_state, state, copy_attached_bodies);
00367 state.update();
00368 return result;
00369 }
00370
00371 bool moveit::core::robotStateMsgToRobotState(const Transforms &tf, const moveit_msgs::RobotState &robot_state, RobotState& state, bool copy_attached_bodies)
00372 {
00373 bool result = _robotStateMsgToRobotStateHelper(&tf, robot_state, state, copy_attached_bodies);
00374 state.update();
00375 return result;
00376 }
00377
00378 void moveit::core::robotStateToRobotStateMsg(const RobotState& state, moveit_msgs::RobotState &robot_state, bool copy_attached_bodies)
00379 {
00380 robotStateToJointStateMsg(state, robot_state.joint_state);
00381 _robotStateToMultiDOFJointState(state, robot_state.multi_dof_joint_state);
00382 if (copy_attached_bodies)
00383 {
00384 std::vector<const AttachedBody*> attached_bodies;
00385 state.getAttachedBodies(attached_bodies);
00386 robot_state.attached_collision_objects.resize(attached_bodies.size());
00387 for (std::size_t i = 0 ; i < attached_bodies.size() ; ++i)
00388 _attachedBodyToMsg(*attached_bodies[i], robot_state.attached_collision_objects[i]);
00389 }
00390 }
00391
00392 void moveit::core::robotStateToJointStateMsg(const RobotState& state, sensor_msgs::JointState &joint_state)
00393 {
00394 const std::vector<const JointModel*> &js = state.getRobotModel()->getSingleDOFJointModels();
00395 joint_state = sensor_msgs::JointState();
00396
00397 for (std::size_t i = 0 ; i < js.size() ; ++i)
00398 {
00399 joint_state.name.push_back(js[i]->getName());
00400 joint_state.position.push_back(state.getVariablePosition(js[i]->getFirstVariableIndex()));
00401 if (state.hasVelocities())
00402 joint_state.velocity.push_back(state.getVariableVelocity(js[i]->getFirstVariableIndex()));
00403 }
00404
00405
00406 if (joint_state.velocity.size() != joint_state.position.size())
00407 joint_state.velocity.clear();
00408
00409 joint_state.header.frame_id = state.getRobotModel()->getModelFrame();
00410 }
00411
00412 void moveit::core::robotStateToStream(const RobotState& state, std::ostream &out, bool include_header, const std::string& separator)
00413 {
00414
00415 if (include_header)
00416 {
00417 for (std::size_t i = 0; i < state.getVariableCount(); ++i)
00418 {
00419 out << state.getVariableNames()[i];
00420
00421
00422 if (i < state.getVariableCount() - 1)
00423 out << separator;
00424 }
00425 out << std::endl;
00426 }
00427
00428
00429 for (std::size_t i = 0; i < state.getVariableCount(); ++i)
00430 {
00431 out << state.getVariablePositions()[i];
00432
00433
00434 if (i < state.getVariableCount() - 1)
00435 out << separator;
00436 }
00437 out << std::endl;
00438 }
00439
00440 void moveit::core::robotStateToStream(const RobotState& state, std::ostream &out, const std::vector<std::string> &joint_groups_ordering,
00441 bool include_header, const std::string& separator)
00442 {
00443 std::stringstream headers;
00444 std::stringstream joints;
00445
00446 for (std::size_t j = 0; j < joint_groups_ordering.size(); ++j)
00447 {
00448 const JointModelGroup *jmg = state.getRobotModel()->getJointModelGroup(joint_groups_ordering[j]);
00449
00450
00451 if (include_header)
00452 {
00453 for (std::size_t i = 0; i < jmg->getVariableCount(); ++i)
00454 {
00455 headers << jmg->getVariableNames()[i] << separator;
00456 }
00457 }
00458
00459
00460 std::vector<double> group_variable_positions;
00461 state.copyJointGroupPositions(jmg, group_variable_positions);
00462
00463
00464 for (std::size_t i = 0; i < jmg->getVariableCount(); ++i)
00465 {
00466 joints << group_variable_positions[i] << separator;
00467 }
00468 }
00469
00470
00471 if (include_header)
00472 out << headers.str() << std::endl;
00473 out << joints.str() << std::endl;
00474 }