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 }