00001 #include <moveit_object_handling/MoveItHelpers.h>
00002 #include <geometric_shapes/solid_primitive_dims.h>
00003 
00004 using moveit_object_handling::MoveItHelpers;
00005 
00006 std::ostream& operator<<(std::ostream& o, const Eigen::Quaterniond& q)
00007 {
00008     o << q.x() << "," << q.y() << "," << q.z() << "," << q.w();
00009     return o;
00010 }
00011 std::ostream& operator<<(std::ostream& o, const Eigen::Vector3d& v)
00012 {
00013     o << v.x() << "," << v.y() << "," << v.z();
00014     return o;
00015 }
00016 
00017 
00018 shape_msgs::SolidPrimitive getCone(const double& height, const double& radius)
00019 {
00020     shape_msgs::SolidPrimitive bv;
00021     bv.type = shape_msgs::SolidPrimitive::CONE;
00022     bv.dimensions.resize(geometric_shapes::SolidPrimitiveDimCount<shape_msgs::SolidPrimitive::CONE>::value);
00023     bv.dimensions[shape_msgs::SolidPrimitive::CONE_HEIGHT] = height;
00024     bv.dimensions[shape_msgs::SolidPrimitive::CONE_RADIUS] = radius;
00025     return bv;
00026 
00027 }
00028 
00029 shape_msgs::SolidPrimitive getCylinder(const double& height, const double& radius)
00030 {
00031     shape_msgs::SolidPrimitive bv;
00032     bv.type = shape_msgs::SolidPrimitive::CYLINDER;
00033     bv.dimensions.resize(geometric_shapes::SolidPrimitiveDimCount<shape_msgs::SolidPrimitive::CYLINDER>::value);
00034     bv.dimensions[shape_msgs::SolidPrimitive::CYLINDER_HEIGHT] = height;
00035     bv.dimensions[shape_msgs::SolidPrimitive::CYLINDER_RADIUS] = radius;
00036     return bv;
00037 
00038 }
00039 
00040 shape_msgs::SolidPrimitive getBox(const double& x, const  double& y, const  double& z)
00041 {
00042     shape_msgs::SolidPrimitive bv;
00043     bv.type = shape_msgs::SolidPrimitive::BOX;
00044     bv.dimensions.resize(geometric_shapes::SolidPrimitiveDimCount<shape_msgs::SolidPrimitive::BOX>::value);
00045     bv.dimensions[shape_msgs::SolidPrimitive::BOX_X] = x;
00046     bv.dimensions[shape_msgs::SolidPrimitive::BOX_Y] = y;
00047     bv.dimensions[shape_msgs::SolidPrimitive::BOX_Z] = z;
00048     return bv;
00049 
00050 }
00051 shape_msgs::SolidPrimitive getSphere(const double& radius)
00052 {
00053     shape_msgs::SolidPrimitive bv;
00054     bv.type = shape_msgs::SolidPrimitive::SPHERE;
00055     bv.dimensions.resize(geometric_shapes::SolidPrimitiveDimCount<shape_msgs::SolidPrimitive::SPHERE>::value);
00056     bv.dimensions[shape_msgs::SolidPrimitive::SPHERE_RADIUS] = radius;
00057     return bv;
00058 }
00059 
00060 moveit_msgs::PositionConstraint moveit_object_handling::MoveItHelpers::getBoxConstraint(const std::string &link_name,
00061         const geometry_msgs::PoseStamped& boxOrigin, const double& x, const double& y, const double& z)
00062 {
00063 
00064     moveit_msgs::PositionConstraint pc;
00065     pc.link_name = link_name;
00066     pc.target_point_offset.x = 0;
00067     pc.target_point_offset.y = 0;
00068     pc.target_point_offset.z = 0;
00069 
00070     pc.header = boxOrigin.header;
00071 
00072     pc.constraint_region.primitives.resize(1);
00073     shape_msgs::SolidPrimitive &bv = pc.constraint_region.primitives[0];
00074     bv = getBox(x, y, z);
00075 
00076     pc.constraint_region.primitive_poses.resize(1);
00077     geometry_msgs::Pose& pose = pc.constraint_region.primitive_poses[0];
00078     pose = boxOrigin.pose;
00079 
00080     pc.weight = 1.0;
00081 
00082     return pc;
00083 }
00084 
00085 #if 0
00086 bool moveit_object_handling::MoveItHelpers::getCylinderConstraint(const std::string &link_name,
00087         const geometry_msgs::PoseStamped& from, const geometry_msgs::PoseStamped& to,
00088         const double& radius, moveit_msgs::PositionConstraint& result)
00089 {
00090 
00091     geometry_msgs::PoseStamped target;
00092     if (CapabilityHelpers::Singleton()->transformPose(to, from.header.frame_id, target, -1, true) < 0)
00093     {
00094         ROS_ERROR("Can't transform between poses");
00095         return false;
00096     }
00097 
00098     Eigen::Vector3d _from, _to;
00099     tf::pointMsgToEigen(from.pose.position, _from);
00100     tf::pointMsgToEigen(target.pose.position, _to);
00101 
00102     Eigen::Vector3d _diff = _to - _from;
00103     geometry_msgs::Vector3 diff;
00104     tf::vectorEigenToMsg(_diff, diff);
00105 
00106 
00107     result = getCylinderConstraint(link_name, from, diff, radius);
00108 
00109     return true;
00110 
00111 }
00112 #endif
00113 
00114 moveit_object_handling::MoveItHelpers::SolidPrimitivePtr moveit_object_handling::MoveItHelpers::getCylinderBV(
00115     const Eigen::Vector3d& _fromPose, const Eigen::Quaterniond& _fromOrientation,
00116     const Eigen::Vector3d& _direction, const double& radius,
00117     Eigen::Vector3d& bv_pose, Eigen::Quaterniond& bv_orientation)
00118 {
00119 
00120     if (_direction.norm() < 1e-06)
00121     {
00122         ROS_ERROR("Cone direction can't be 0 length!");
00123         return SolidPrimitivePtr((shape_msgs::SolidPrimitive*)NULL);
00124     }
00125 
00126     bv_pose = _fromPose;
00127     bv_orientation = _fromOrientation;
00128 
00129     
00130     
00131     Eigen::Vector3d _z = bv_orientation * Eigen::Vector3d(0, 0, 1);
00132     Eigen::Quaterniond quat;
00133     quat.setFromTwoVectors(_z, _direction);
00134     quat.normalize();
00135     bv_orientation *= quat;
00136 
00137     float height = _direction.norm();
00138 
00139     
00140     
00141 
00142     SolidPrimitivePtr bv(new shape_msgs::SolidPrimitive());
00143     *bv = getCylinder(height, radius);
00144 
00145     return bv;
00146 }
00147 
00148 
00149 
00150 
00151 
00152 
00153 
00154 
00155 
00156 
00157 
00158 
00159 
00160 
00161 
00162 
00163 
00164 
00165 
00166 
00167 
00168 
00169 
00170 
00171 
00172 
00173 
00174 
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182 
00183 
00184 
00185 
00186 
00187 
00188 
00189 
00190 
00191 
00192 
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 
00201 
00202 
00203 
00204 moveit_object_handling::MoveItHelpers::SolidPrimitivePtr moveit_object_handling::MoveItHelpers::getConeBV(
00205     const Eigen::Vector3d& _fromPose, const Eigen::Quaterniond& _fromOrientation,
00206     const Eigen::Vector3d& _direction, const double& radius_start, const double& radius_end,
00207     Eigen::Vector3d& bv_pose, Eigen::Quaterniond& bv_orientation)
00208 {
00209 
00210     if (_direction.norm() < 1e-06)
00211     {
00212         ROS_ERROR("Cone direction can't be 0 length!");
00213         return SolidPrimitivePtr((shape_msgs::SolidPrimitive*)NULL);
00214     }
00215 
00216     if (fabs(radius_start - radius_end) < 1e-06)
00217     {
00218         ROS_INFO("Radius are equal, hence this is a cylinder");
00219         return getCylinderBV(_fromPose, _fromOrientation, _direction, radius_start, bv_pose, bv_orientation);
00220     }
00221 
00222     bool startIsTip = radius_start < radius_end;
00223 
00224     bv_pose = _fromPose;
00225     bv_orientation = _fromOrientation;
00226 
00227 
00228     ROS_INFO_STREAM("Getting CONE for inital pose " << bv_pose << ", ori " << bv_orientation
00229                     << " (cone direction " << _direction << "), radius " << radius_start << ".." << radius_end);
00230 
00231     
00232     
00233     
00234     Eigen::Vector3d _z = bv_orientation * Eigen::Vector3d(0, 0, 1);
00235 
00236     Eigen::Quaterniond quat;
00237     Eigen::Vector3d _negDir = -_direction;
00238     quat.setFromTwoVectors(_z, startIsTip ? _negDir : _direction);
00239     quat.normalize();
00240     bv_orientation *= quat;
00241 
00242     ROS_INFO_STREAM("Rotated orientation: " << bv_orientation);
00243 
00244 
00245     float dist = _direction.norm();
00246     
00247     
00248     float addDist = 0;
00249     if (startIsTip) addDist = (radius_start * dist) / (radius_end - radius_start);
00250     else addDist = (radius_end * dist) / (radius_start - radius_end);
00251 
00252 
00253     if (startIsTip)
00254     {
00255         
00256         
00257         Eigen::Vector3d addDir = _direction;
00258         addDir.normalize();
00259         addDir *= addDist;
00260 
00261         Eigen::Vector3d addToFrom = _direction + addDir;
00262 
00263         
00264         
00265         bv_pose += addToFrom;
00266     }
00267 
00268     
00269     float height = dist + addDist;
00270     float radius = startIsTip ? radius_end : radius_start;
00271 
00272     
00273 
00274     SolidPrimitivePtr bv(new shape_msgs::SolidPrimitive());
00275     *bv = getCone(height, radius);
00276 
00277     
00278 
00279     return bv;
00280 }
00281 
00282 
00283 
00284 
00285 
00286 
00287 
00288 
00289 
00290 
00291 
00292 
00293 
00294 
00295 
00296 
00297 
00298 
00299 
00300 
00301 
00302 
00303 
00304 
00305 
00306 
00307 
00308 
00309 
00310 
00311 
00312 
00313 
00314 
00315 
00316 
00317 
00318 
00319 
00320 
00321 
00322 
00323 
00324 
00325 
00326 
00327 
00328 
00329 
00330 
00331 
00332 
00333 
00334 
00335 
00336 
00337 
00338 
00339 
00340 
00341 
00342 
00343 
00344 
00345 
00346 
00347 
00348 
00349 
00350 
00351 
00352 
00353 
00354 
00355 
00356 
00357 
00358 
00359 
00360 
00361 
00362 
00363 
00364 
00365 moveit_msgs::Constraints moveit_object_handling::MoveItHelpers::getJointConstraint(const std::string& link_name,
00366         const sensor_msgs::JointState& js, const float& joint_tolerance)
00367 {
00368 
00369     moveit_msgs::Constraints c;
00370     for (int i = 0; i < js.name.size(); ++i)
00371     {
00372         moveit_msgs::JointConstraint jc;
00373         jc.joint_name = js.name[i];
00374         jc.position = js.position[i];
00375         jc.tolerance_above = joint_tolerance;
00376         jc.tolerance_below = joint_tolerance;
00377         jc.weight = 1.0;
00378         c.joint_constraints.push_back(jc);
00379     }
00380     return c;
00381 
00382 }
00383 
00384 
00385 moveit_msgs::OrientationConstraint moveit_object_handling::MoveItHelpers::getOrientationConstraint(const std::string& link_name,
00386         const geometry_msgs::QuaternionStamped& quat,
00387         const float& x_tolerance,
00388         const float& y_tolerance,
00389         const float& z_tolerance)
00390 {
00391     moveit_msgs::OrientationConstraint ocm;
00392     ocm.link_name = link_name;
00393     ocm.header = quat.header;
00394     ocm.orientation = quat.quaternion;
00395     ocm.absolute_x_axis_tolerance = x_tolerance;
00396     ocm.absolute_y_axis_tolerance = y_tolerance;
00397     ocm.absolute_z_axis_tolerance = z_tolerance;
00398     ocm.weight = 1.0;
00399     return ocm;
00400 }
00401 
00402 moveit_object_handling::MoveItHelpers::PositionConstraintPtr moveit_object_handling::MoveItHelpers::getSpherePoseConstraint(
00403     const std::string &link_name,
00404     const geometry_msgs::PoseStamped &target_pose1,
00405     float maxArmReachDistance)
00406 {
00407 
00408     
00409     
00410 
00411     PositionConstraintPtr pc(new moveit_msgs::PositionConstraint());
00412     pc->link_name = link_name;
00413     pc->weight = 1.0;
00414     pc->target_point_offset.x = 0;
00415     pc->target_point_offset.y = 0;
00416     pc->target_point_offset.z = 0;
00417     pc->header = target_pose1.header;
00418 
00419     pc->constraint_region.primitives.resize(1);
00420     pc->constraint_region.primitive_poses.resize(1);
00421 
00422     shape_msgs::SolidPrimitive &bv1 = pc->constraint_region.primitives[0];
00423     geometry_msgs::Pose& pose1 = pc->constraint_region.primitive_poses[0];
00424 
00425     geometry_msgs::Pose sphereOrigin = target_pose1.pose;
00426     pose1 = sphereOrigin;
00427     bv1 = getSphere(maxArmReachDistance);
00428     return pc;
00429 }
00430 
00431 #if 0
00432 moveit_object_handling::MoveItHelpers::PositionConstraintPtr moveit_object_handling::MoveItHelpers::getCombinedPoseConstraint(
00433     const std::string &link_name,
00434     const geometry_msgs::PoseStamped &target_pose1,
00435     float tolerance_pos1,
00436     const geometry_msgs::PoseStamped& target_pose2,
00437     float tolerance_pos2,
00438     float maxArmReachDistance)
00439 {
00440 
00441 
00442     
00443     geometry_msgs::Pose target1_to_target2;
00444     int rel = CapabilityHelpers::Singleton()->relativePose(target_pose1, target_pose2, target1_to_target2, true, 0.2, true);
00445 
00446     if (rel < 0)
00447     {
00448         ROS_ERROR("Could not get transform between frames %s and %s: error %i", target_pose1.header.frame_id.c_str(), target_pose2.header.frame_id.c_str(), rel);
00449         return PositionConstraintPtr((moveit_msgs::PositionConstraint*)NULL);
00450     }
00451 
00452     Eigen::Vector3d _target1_to_target2;
00453     tf::pointMsgToEigen(target1_to_target2.position, _target1_to_target2);
00454 
00455     Eigen::Vector3d _target_pose1;
00456     tf::pointMsgToEigen(target_pose1.pose.position, _target_pose1);
00457 
00458     Eigen::Quaterniond _target1_orientation;
00459     tf::quaternionMsgToEigen(target_pose1.pose.orientation, _target1_orientation);
00460 
00461     
00462     
00463 
00464 
00465     Eigen::Vector3d _target1_to_target2_orig = _target1_to_target2; 
00466     _target1_to_target2.normalize();
00467 
00468     Eigen::Vector3d _maxArmReachCenter = _target_pose1 + _target1_to_target2 * (-maxArmReachDistance);
00469 
00470     PositionConstraintPtr pc(new moveit_msgs::PositionConstraint());
00471     pc->link_name = link_name;
00472     pc->weight = 1.0;
00473     pc->target_point_offset.x = 0;
00474     pc->target_point_offset.y = 0;
00475     pc->target_point_offset.z = 0;
00476     pc->header = target_pose1.header;
00477 
00478     pc->constraint_region.primitives.resize(2);
00479     pc->constraint_region.primitive_poses.resize(2);
00480 
00481     
00482     shape_msgs::SolidPrimitive &bv1 = pc->constraint_region.primitives[0];
00483     shape_msgs::SolidPrimitive &bv2 = pc->constraint_region.primitives[1];
00484     geometry_msgs::Pose& pose1 = pc->constraint_region.primitive_poses[0];
00485     geometry_msgs::Pose& pose2 = pc->constraint_region.primitive_poses[1];
00486 
00487     float doubleArmReach = 2 * maxArmReachDistance;
00488     bv1 = getBox(doubleArmReach, doubleArmReach, doubleArmReach);
00489 
00490     
00491     
00492     
00493     Eigen::Quaterniond _ori1 = _target1_orientation;
00494     Eigen::Vector3d _z1 = _ori1 * Eigen::Vector3d(0, 0, 1);
00495     Eigen::Quaterniond quat;
00496     quat.setFromTwoVectors(_z1, _target1_to_target2);
00497     _ori1 *= quat;
00498     geometry_msgs::Pose boxOrigin = target_pose1.pose;
00499     tf::quaternionEigenToMsg(_ori1, boxOrigin.orientation);
00500     boxOrigin.position.x = _maxArmReachCenter.x();
00501     boxOrigin.position.y = _maxArmReachCenter.y();
00502     boxOrigin.position.z = _maxArmReachCenter.z();
00503     pose1 = boxOrigin;
00504 
00505 
00506     
00507     Eigen::Vector3d cone_pose;
00508     Eigen::Quaterniond cone_orientation;
00509     SolidPrimitivePtr cone = getConeBV(_target_pose1, _target1_orientation, _target1_to_target2_orig,
00510                                        tolerance_pos1, tolerance_pos2, cone_pose, cone_orientation);
00511     if (!cone.get())
00512     {
00513         ROS_ERROR("Could not get cone BoundingVolume");
00514         return PositionConstraintPtr((moveit_msgs::PositionConstraint*)NULL);
00515     }
00516 
00517 
00518     geometry_msgs::Pose coneOrigin = target_pose1.pose;
00519     tf::pointEigenToMsg(cone_pose, coneOrigin.position);
00520     tf::quaternionEigenToMsg(cone_orientation, coneOrigin.orientation);
00521     bv2 = *cone;
00522     pose2 = coneOrigin;
00523 
00524     ROS_INFO_STREAM("Cone origin and orientation" << std::endl << bv2);
00525     ROS_INFO_STREAM(pose2);
00526 
00527     return pc;
00528 }
00529 #endif
00530 
00531 moveit_msgs::Constraints moveit_object_handling::MoveItHelpers::getPoseConstraint(const std::string &link_name,
00532         const geometry_msgs::PoseStamped &pose, double tolerance_pos, double tolerance_angle, int type)
00533 {
00534 
00535     moveit_msgs::Constraints goal;
00536 
00537     if (type <= 1)
00538     {
00539         goal.position_constraints.resize(1);
00540         moveit_msgs::PositionConstraint &pcm = goal.position_constraints[0];
00541         pcm.link_name = link_name;
00542         pcm.target_point_offset.x = 0;
00543         pcm.target_point_offset.y = 0;
00544         pcm.target_point_offset.z = 0;
00545         pcm.constraint_region.primitives.resize(1);
00546         shape_msgs::SolidPrimitive &bv = pcm.constraint_region.primitives[0];
00547         bv = getSphere(tolerance_pos);
00548 
00549         pcm.header = pose.header;
00550         pcm.constraint_region.primitive_poses.resize(1);
00551         pcm.constraint_region.primitive_poses[0].position = pose.pose.position;
00552 
00553         
00554         pcm.constraint_region.primitive_poses[0].orientation.x = 0.0;
00555         pcm.constraint_region.primitive_poses[0].orientation.y = 0.0;
00556         pcm.constraint_region.primitive_poses[0].orientation.z = 0.0;
00557         pcm.constraint_region.primitive_poses[0].orientation.w = 1.0;
00558         pcm.weight = 1.0;
00559     }
00560 
00561     if ((type == 1) || (type == 2))
00562     {
00563         goal.orientation_constraints.resize(1);
00564         moveit_msgs::OrientationConstraint &ocm = goal.orientation_constraints[0];
00565         ocm.link_name = link_name;
00566         ocm.header = pose.header;
00567         ocm.orientation = pose.pose.orientation;
00568         ocm.absolute_x_axis_tolerance = tolerance_angle;
00569         ocm.absolute_y_axis_tolerance = tolerance_angle;
00570         ocm.absolute_z_axis_tolerance = tolerance_angle;
00571         ocm.weight = 1.0;
00572     }
00573 
00574 
00575     return goal;
00576 }