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_visual_tools/visual_tools.h>
00039 #include <moveit/robot_interaction/robot_interaction.h>
00040
00041
00042 #include <moveit_msgs/DisplayTrajectory.h>
00043 #include <moveit_msgs/CollisionObject.h>
00044
00045
00046 #include <moveit/robot_state/conversions.h>
00047
00048
00049 #include <tf_conversions/tf_eigen.h>
00050
00051 #include <eigen_conversions/eigen_msg.h>
00052
00053 #include <shape_tools/solid_primitive_dims.h>
00054
00055 namespace moveit_visual_tools
00056 {
00057
00058 VisualTools::VisualTools(const std::string& base_frame,
00059 const std::string& marker_topic,
00060 planning_scene_monitor::PlanningSceneMonitorPtr planning_scene_monitor)
00061 : nh_("~"),
00062 planning_scene_monitor_(planning_scene_monitor),
00063 marker_topic_(marker_topic),
00064 base_frame_(base_frame)
00065 {
00066 initialize();
00067 }
00068
00069 VisualTools::VisualTools(const std::string& base_frame,
00070 const std::string& marker_topic,
00071 robot_model::RobotModelConstPtr robot_model)
00072 : nh_("~"),
00073 robot_model_(robot_model),
00074 marker_topic_(marker_topic),
00075 base_frame_(base_frame)
00076 {
00077 initialize();
00078 }
00079
00080 void VisualTools::initialize()
00081 {
00082 floor_to_base_height_ = 0;
00083 marker_lifetime_ = ros::Duration(0.0);
00084 muted_ = false;
00085 alpha_ = 0.8;
00086 global_scale_ = 1.0;
00087
00088 loadRvizMarkers();
00089 }
00090
00091 void VisualTools::deleteAllMarkers()
00092 {
00093 loadMarkerPub();
00094 pub_rviz_marker_.publish( reset_marker_ );
00095 ros::spinOnce();
00096 }
00097
00098 void VisualTools::resetMarkerCounts()
00099 {
00100 arrow_marker_.id++;
00101 sphere_marker_.id++;
00102 block_marker_.id++;
00103 cylinder_marker_.id++;
00104 text_marker_.id++;
00105 rectangle_marker_.id++;
00106 line_marker_.id++;
00107 path_marker_.id++;
00108 spheres_marker_.id++;
00109 }
00110
00111 bool VisualTools::loadRvizMarkers()
00112 {
00113
00114 reset_marker_.header.frame_id = base_frame_;
00115 reset_marker_.header.stamp = ros::Time();
00116 reset_marker_.action = 3;
00117
00118
00119
00120 arrow_marker_.header.frame_id = base_frame_;
00121
00122 arrow_marker_.ns = "Arrow";
00123
00124 arrow_marker_.type = visualization_msgs::Marker::ARROW;
00125
00126 arrow_marker_.action = visualization_msgs::Marker::ADD;
00127
00128 arrow_marker_.lifetime = marker_lifetime_;
00129
00130
00131
00132 rectangle_marker_.header.frame_id = base_frame_;
00133
00134 rectangle_marker_.ns = "Rectangle";
00135
00136 rectangle_marker_.type = visualization_msgs::Marker::CUBE;
00137
00138 rectangle_marker_.action = visualization_msgs::Marker::ADD;
00139
00140 rectangle_marker_.lifetime = marker_lifetime_;
00141
00142
00143
00144 line_marker_.header.frame_id = base_frame_;
00145
00146 line_marker_.ns = "Line";
00147
00148 line_marker_.type = visualization_msgs::Marker::LINE_STRIP;
00149
00150 line_marker_.action = visualization_msgs::Marker::ADD;
00151
00152 line_marker_.lifetime = marker_lifetime_;
00153
00154
00155
00156 path_marker_.header.frame_id = base_frame_;
00157
00158 path_marker_.ns = "Path";
00159
00160 path_marker_.type = visualization_msgs::Marker::LINE_LIST;
00161
00162 path_marker_.action = visualization_msgs::Marker::ADD;
00163
00164 path_marker_.lifetime = marker_lifetime_;
00165
00166 path_marker_.pose.position.x = 0.0;
00167 path_marker_.pose.position.y = 0.0;
00168 path_marker_.pose.position.z = 0.0;
00169
00170 path_marker_.pose.orientation.x = 0.0;
00171 path_marker_.pose.orientation.y = 0.0;
00172 path_marker_.pose.orientation.z = 0.0;
00173 path_marker_.pose.orientation.w = 1.0;
00174
00175
00176
00177 spheres_marker_.header.frame_id = base_frame_;
00178
00179 spheres_marker_.ns = "Spheres";
00180
00181 spheres_marker_.type = visualization_msgs::Marker::SPHERE_LIST;
00182
00183 spheres_marker_.action = visualization_msgs::Marker::ADD;
00184
00185 spheres_marker_.lifetime = marker_lifetime_;
00186
00187 spheres_marker_.pose.position.x = 0.0;
00188 spheres_marker_.pose.position.y = 0.0;
00189 spheres_marker_.pose.position.z = 0.0;
00190
00191 spheres_marker_.pose.orientation.x = 0.0;
00192 spheres_marker_.pose.orientation.y = 0.0;
00193 spheres_marker_.pose.orientation.z = 0.0;
00194 spheres_marker_.pose.orientation.w = 1.0;
00195
00196
00197 block_marker_.header.frame_id = base_frame_;
00198
00199 block_marker_.ns = "Block";
00200
00201 block_marker_.action = visualization_msgs::Marker::ADD;
00202
00203 block_marker_.type = visualization_msgs::Marker::CUBE;
00204
00205 block_marker_.lifetime = marker_lifetime_;
00206
00207
00208 cylinder_marker_.header.frame_id = base_frame_;
00209
00210 cylinder_marker_.ns = "Cylinder";
00211
00212 cylinder_marker_.action = visualization_msgs::Marker::ADD;
00213
00214 cylinder_marker_.type = visualization_msgs::Marker::CYLINDER;
00215
00216 cylinder_marker_.lifetime = marker_lifetime_;
00217
00218
00219 sphere_marker_.header.frame_id = base_frame_;
00220
00221 sphere_marker_.ns = "Sphere";
00222
00223 sphere_marker_.type = visualization_msgs::Marker::SPHERE_LIST;
00224
00225 sphere_marker_.action = visualization_msgs::Marker::ADD;
00226
00227 sphere_marker_.pose.position.x = 0;
00228 sphere_marker_.pose.position.y = 0;
00229 sphere_marker_.pose.position.z = 0;
00230 sphere_marker_.pose.orientation.x = 0.0;
00231 sphere_marker_.pose.orientation.y = 0.0;
00232 sphere_marker_.pose.orientation.z = 0.0;
00233 sphere_marker_.pose.orientation.w = 1.0;
00234
00235 geometry_msgs::Point point_a;
00236
00237 sphere_marker_.points.push_back( point_a );
00238 sphere_marker_.colors.push_back( getColor( BLUE ) );
00239
00240 sphere_marker_.lifetime = marker_lifetime_;
00241
00242
00243 text_marker_.header.frame_id = base_frame_;
00244
00245 text_marker_.ns = "Text";
00246
00247 text_marker_.action = visualization_msgs::Marker::ADD;
00248
00249 text_marker_.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
00250
00251 text_marker_.lifetime = marker_lifetime_;
00252
00253 return true;
00254 }
00255
00256 bool VisualTools::loadPlanningSceneMonitor()
00257 {
00258
00259 if (planning_scene_monitor_)
00260 {
00261 ROS_WARN_STREAM_NAMED("visual_tools","Will not load a new planning scene monitor when one has already been set for Visual Tools");
00262 return false;
00263 }
00264 ROS_DEBUG_STREAM_NAMED("visual_tools","Loading planning scene monitor");
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 planning_scene_monitor_.reset(new planning_scene_monitor::PlanningSceneMonitor(ROBOT_DESCRIPTION));
00286
00287 ros::spinOnce();
00288 ros::Duration(0.1).sleep();
00289 ros::spinOnce();
00290
00291 if (planning_scene_monitor_->getPlanningScene())
00292 {
00293
00294
00295
00296
00297
00298 }
00299 else
00300 {
00301 ROS_ERROR_STREAM_NAMED("visual_tools","Planning scene not configured");
00302 return false;
00303 }
00304
00305 return true;
00306 }
00307
00308 bool VisualTools::processCollisionObjectMsg(moveit_msgs::CollisionObject msg)
00309 {
00310
00311 {
00312 planning_scene_monitor::LockedPlanningSceneRW scene(getPlanningSceneMonitor());
00313 scene->processCollisionObjectMsg(msg);
00314 }
00315
00316
00317 getPlanningSceneMonitor()->triggerSceneUpdateEvent(planning_scene_monitor::PlanningSceneMonitor::UPDATE_SCENE);
00318
00319 return true;
00320 }
00321
00322 bool VisualTools::loadRobotMarkers()
00323 {
00324
00325 loadSharedRobotState();
00326
00327
00328 const std::vector<std::string> &link_names = shared_robot_state_->getRobotModel()->getLinkModelNames();;
00329
00330 ROS_DEBUG_STREAM_NAMED("visual_tools","Number of links in robot: " << link_names.size());
00331
00332
00333
00334 visualization_msgs::MarkerArray robot_marker_array;
00335 shared_robot_state_->getRobotMarkers(robot_marker_array, link_names, getColor( GREY ), "test", ros::Duration());
00336
00337 ROS_DEBUG_STREAM_NAMED("visual_tools","Number of rviz markers: " << robot_marker_array.markers.size());
00338
00339
00340 for (std::size_t i = 0 ; i < robot_marker_array.markers.size() ; ++i)
00341 {
00342
00343 if( !ros::ok() )
00344 break;
00345
00346
00347 robot_marker_array.markers[i].header.frame_id = base_frame_;
00348 robot_marker_array.markers[i].header.stamp = ros::Time::now();
00349
00350
00351 if( robot_marker_array.markers[i].type == visualization_msgs::Marker::MESH_RESOURCE )
00352 robot_marker_array.markers[i].mesh_use_embedded_materials = true;
00353
00354 loadMarkerPub();
00355 pub_rviz_marker_.publish( robot_marker_array.markers[i] );
00356 ros::spinOnce();
00357 }
00358
00359 return true;
00360 }
00361
00362 bool VisualTools::loadEEMarker(const std::string& ee_group_name, const std::string& planning_group)
00363 {
00364
00365 loadSharedRobotState();
00366
00367
00368
00369
00370
00371 std_msgs::ColorRGBA marker_color = getColor( GREY );
00372
00373
00374 robot_model::RobotModelConstPtr robot_model = shared_robot_state_->getRobotModel();
00375
00376 const robot_model::JointModelGroup* joint_model_group = robot_model->getJointModelGroup(ee_group_name);
00377 if( joint_model_group == NULL )
00378 {
00379 ROS_ERROR_STREAM_NAMED("visual_tools","Unable to find joint model group '" << ee_group_name << "'");
00380 return false;
00381 }
00382
00383 const std::vector<std::string> &ee_link_names = joint_model_group->getLinkModelNames();
00384
00385
00386
00387
00388 robot_interaction::RobotInteraction robot_interaction( robot_model );
00389
00390
00391 robot_interaction.decideActiveComponents(planning_group);
00392
00393
00394 std::vector<robot_interaction::RobotInteraction::EndEffector> active_eef =
00395 robot_interaction.getActiveEndEffectors();
00396
00397 ROS_DEBUG_STREAM_NAMED("visual_tools","Number of active end effectors: " << active_eef.size());
00398 if( !active_eef.size() )
00399 {
00400 ROS_ERROR_STREAM_NAMED("visual_tools","No active end effectors found! Make sure kinematics.yaml is loaded in this node's namespace!");
00401 return false;
00402 }
00403
00404
00405 robot_interaction::RobotInteraction::EndEffector eef = active_eef[0];
00406
00407
00408
00409
00410 shared_robot_state_->getRobotMarkers(ee_marker_array_, ee_link_names, marker_color, eef.eef_group, ros::Duration());
00411 ROS_DEBUG_STREAM_NAMED("visual_tools","Number of rviz markers in end effector: " << ee_marker_array_.markers.size());
00412
00413
00414 try
00415 {
00416
00417 tf::poseEigenToTF(shared_robot_state_->getGlobalLinkTransform(eef.parent_link), tf_root_to_link_);
00418 }
00419 catch(...)
00420 {
00421 ROS_ERROR_STREAM_NAMED("visual_tools","Didn't find link state for " << eef.parent_link);
00422 }
00423
00424
00425 for (std::size_t i = 0 ; i < ee_marker_array_.markers.size() ; ++i)
00426 {
00427 marker_poses_.push_back( ee_marker_array_.markers[i].pose );
00428 }
00429
00430 return true;
00431 }
00432
00433 void VisualTools::loadMarkerPub()
00434 {
00435 if (pub_rviz_marker_)
00436 return;
00437
00438
00439 pub_rviz_marker_ = nh_.advertise<visualization_msgs::Marker>(marker_topic_, 10);
00440 ROS_DEBUG_STREAM_NAMED("visual_tools","Publishing Rviz markers on topic " << pub_rviz_marker_.getTopic());
00441
00442 ros::spinOnce();
00443 ros::Duration(0.2).sleep();
00444 ros::spinOnce();
00445 }
00446
00447 void VisualTools::loadCollisionPub()
00448 {
00449 if (pub_collision_obj_)
00450 return;
00451
00452
00453 pub_collision_obj_ = nh_.advertise<moveit_msgs::CollisionObject>(COLLISION_TOPIC, 10);
00454 ROS_DEBUG_STREAM_NAMED("visual_tools","Publishing collision objects on topic " << pub_collision_obj_.getTopic());
00455
00456 ros::spinOnce();
00457 ros::Duration(0.2).sleep();
00458 ros::spinOnce();
00459 }
00460
00461 void VisualTools::loadAttachedPub()
00462 {
00463 if (pub_attach_collision_obj_)
00464 return;
00465
00466
00467 pub_attach_collision_obj_ = nh_.advertise<moveit_msgs::AttachedCollisionObject>(ATTACHED_COLLISION_TOPIC, 10);
00468 ROS_DEBUG_STREAM_NAMED("visual_tools","Publishing attached collision objects on topic " << pub_attach_collision_obj_.getTopic());
00469
00470 ros::spinOnce();
00471 ros::Duration(0.2).sleep();
00472 ros::spinOnce();
00473 }
00474
00475 void VisualTools::loadPlanningPub()
00476 {
00477 if (pub_planning_scene_diff_)
00478 return;
00479
00480
00481 pub_planning_scene_diff_ = nh_.advertise<moveit_msgs::PlanningScene>(PLANNING_SCENE_TOPIC, 1);
00482 ROS_DEBUG_STREAM_NAMED("visual_tools","Publishing planning scene on topic " << pub_planning_scene_diff_.getTopic());
00483
00484 ros::spinOnce();
00485 ros::Duration(0.2).sleep();
00486 ros::spinOnce();
00487 }
00488
00489 void VisualTools::loadTrajectoryPub()
00490 {
00491 if (pub_display_path_)
00492 return;
00493
00494
00495 pub_display_path_ = nh_.advertise<moveit_msgs::DisplayTrajectory>(DISPLAY_PLANNED_PATH_TOPIC, 10, false);
00496 ROS_DEBUG_STREAM_NAMED("visual_tools","Publishing MoveIt trajectory on topic " << pub_display_path_.getTopic());
00497
00498 ros::spinOnce();
00499 ros::Duration(0.2).sleep();
00500 ros::spinOnce();
00501 }
00502
00503 void VisualTools::loadRobotStatePub(const std::string &marker_topic)
00504 {
00505 if (pub_robot_state_)
00506 return;
00507
00508
00509 pub_robot_state_ = nh_.advertise<moveit_msgs::DisplayRobotState>(marker_topic, 1 );
00510 ROS_DEBUG_STREAM_NAMED("visual_tools","Publishing MoveIt robot state on topic " << pub_robot_state_.getTopic());
00511
00512 ros::spinOnce();
00513 ros::Duration(0.2).sleep();
00514 ros::spinOnce();
00515 }
00516
00517 void VisualTools::setFloorToBaseHeight(double floor_to_base_height)
00518 {
00519 floor_to_base_height_ = floor_to_base_height;
00520 }
00521
00522 void VisualTools::setGraspPoseToEEFPose(geometry_msgs::Pose grasp_pose_to_eef_pose)
00523 {
00524 grasp_pose_to_eef_pose_ = grasp_pose_to_eef_pose;
00525 }
00526
00527 void VisualTools::setLifetime(double lifetime)
00528 {
00529 marker_lifetime_ = ros::Duration(lifetime);
00530
00531
00532 arrow_marker_.lifetime = marker_lifetime_;
00533 rectangle_marker_.lifetime = marker_lifetime_;
00534 line_marker_.lifetime = marker_lifetime_;
00535 sphere_marker_.lifetime = marker_lifetime_;
00536 block_marker_.lifetime = marker_lifetime_;
00537 cylinder_marker_.lifetime = marker_lifetime_;
00538 text_marker_.lifetime = marker_lifetime_;
00539 }
00540
00541 const rviz_colors VisualTools::getRandColor()
00542 {
00543 std::vector<rviz_colors> all_colors;
00544
00545 all_colors.push_back(RED);
00546 all_colors.push_back(GREEN);
00547 all_colors.push_back(BLUE);
00548 all_colors.push_back(GREY);
00549 all_colors.push_back(WHITE);
00550 all_colors.push_back(ORANGE);
00551 all_colors.push_back(BLACK);
00552 all_colors.push_back(YELLOW);
00553 all_colors.push_back(PURPLE);
00554
00555 return all_colors[ rand() % all_colors.size() ];
00556 }
00557
00558 std_msgs::ColorRGBA VisualTools::getColor(const rviz_colors &color)
00559 {
00560 std_msgs::ColorRGBA result;
00561 result.a = alpha_;
00562 switch(color)
00563 {
00564 case RED:
00565 result.r = 0.8;
00566 result.g = 0.1;
00567 result.b = 0.1;
00568 break;
00569 case GREEN:
00570 result.r = 0.1;
00571 result.g = 0.8;
00572 result.b = 0.1;
00573 break;
00574 case GREY:
00575 result.r = 0.9;
00576 result.g = 0.9;
00577 result.b = 0.9;
00578 break;
00579 case WHITE:
00580 result.r = 1.0;
00581 result.g = 1.0;
00582 result.b = 1.0;
00583 break;
00584 case ORANGE:
00585 result.r = 1.0;
00586 result.g = 0.5;
00587 result.b = 0.0;
00588 break;
00589 case TRANSLUCENT:
00590 result.r = 0.1;
00591 result.g = 0.1;
00592 result.b = 0.8;
00593 result.a = 0.3;
00594 break;
00595 case TRANSLUCENT2:
00596 result.r = 0.1;
00597 result.g = 0.1;
00598 result.b = 0.1;
00599 result.a = 0.1;
00600 break;
00601 case BLACK:
00602 result.r = 0.0;
00603 result.g = 0.0;
00604 result.b = 0.0;
00605 break;
00606 case YELLOW:
00607 result.r = 1.0;
00608 result.g = 1.0;
00609 result.b = 0.0;
00610 break;
00611 case PURPLE:
00612 result.r = 0.597;
00613 result.g = 0.0;
00614 result.b = 0.597;
00615 break;
00616 case RAND:
00617
00618 do
00619 {
00620 result.r = fRand(0.0,1.0);
00621 result.g = fRand(0.0,1.0);
00622 result.b = fRand(0.0,1.0);
00623 } while (result.r + result.g + result.b < 1.5);
00624 break;
00625 case BLUE:
00626 default:
00627 result.r = 0.1;
00628 result.g = 0.1;
00629 result.b = 0.8;
00630 }
00631
00632 return result;
00633 }
00634
00635 geometry_msgs::Vector3 VisualTools::getScale(const rviz_scales &scale, bool arrow_scale, double marker_scale)
00636 {
00637 geometry_msgs::Vector3 result;
00638 double val(0.0);
00639 switch(scale)
00640 {
00641 case XXSMALL:
00642 val = 0.005;
00643 break;
00644 case XSMALL:
00645 val = 0.01;
00646 break;
00647 case SMALL:
00648 val = 0.03;
00649 break;
00650 case REGULAR:
00651 val = 0.05;
00652 break;
00653 case LARGE:
00654 val = 0.1;
00655 break;
00656 case xLARGE:
00657 val = 0.2;
00658 break;
00659 case xxLARGE:
00660 val = 0.3;
00661 break;
00662 case xxxLARGE:
00663 val = 0.4;
00664 break;
00665 case XLARGE:
00666 val = 0.5;
00667 break;
00668 case XXLARGE:
00669 val = 1.0;
00670 break;
00671 default:
00672 ROS_ERROR_STREAM_NAMED("visualization_tools","Not implemented yet");
00673 break;
00674 }
00675
00676
00677 result.x = val * marker_scale * global_scale_;
00678 result.y = val * marker_scale * global_scale_;
00679 result.z = val * marker_scale * global_scale_;
00680
00681
00682 if (arrow_scale)
00683 {
00684 result.y *= 0.1;
00685 result.z *= 0.1;
00686 }
00687
00688 return result;
00689 }
00690
00691 planning_scene_monitor::PlanningSceneMonitorPtr VisualTools::getPlanningSceneMonitor()
00692 {
00693 if( !planning_scene_monitor_ )
00694 {
00695 loadPlanningSceneMonitor();
00696 ros::spinOnce();
00697 ros::Duration(1).sleep();
00698 }
00699 return planning_scene_monitor_;
00700 }
00701
00702 bool VisualTools::loadSharedRobotState()
00703 {
00704
00705 if (!shared_robot_state_)
00706 {
00707
00708 if (!robot_model_)
00709 {
00710
00711
00712 ROS_WARN_STREAM_NAMED("temp","Falling back to using planning scene monitor for loading a robot state");
00713 planning_scene_monitor::PlanningSceneMonitorPtr psm = getPlanningSceneMonitor();
00714 robot_model_ = psm->getRobotModel();
00715 }
00716 shared_robot_state_.reset(new robot_state::RobotState(robot_model_));
00717 }
00718
00719 return true;
00720 }
00721
00722 Eigen::Vector3d VisualTools::getCenterPoint(Eigen::Vector3d a, Eigen::Vector3d b)
00723 {
00724 Eigen::Vector3d center;
00725 center[0] = (a[0] + b[0]) / 2;
00726 center[1] = (a[1] + b[1]) / 2;
00727 center[2] = (a[2] + b[2]) / 2;
00728 return center;
00729 }
00730
00731 Eigen::Affine3d VisualTools::getVectorBetweenPoints(Eigen::Vector3d a, Eigen::Vector3d b)
00732 {
00733
00734
00735
00736 Eigen::Quaterniond q;
00737
00738 Eigen::Vector3d axis_vector = b - a;
00739 axis_vector.normalize();
00740
00741 Eigen::Vector3d up_vector(0.0, 0.0, 1.0);
00742 Eigen::Vector3d right_axis_vector = axis_vector.cross(up_vector);
00743 right_axis_vector.normalized();
00744 double theta = axis_vector.dot(up_vector);
00745 double angle_rotation = -1.0*acos(theta);
00746
00747
00748
00749
00750 tf::Vector3 tf_right_axis_vector;
00751 tf::vectorEigenToTF(right_axis_vector, tf_right_axis_vector);
00752
00753
00754 tf::Quaternion tf_q(tf_right_axis_vector, angle_rotation);
00755
00756
00757 tf::quaternionTFToEigen(tf_q, q);
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768 Eigen::Affine3d pose;
00769 q.normalize();
00770 pose = q * Eigen::AngleAxisd(-0.5*M_PI, Eigen::Vector3d::UnitY());
00771 pose.translation() = a;
00772
00773 return pose;
00774 }
00775
00776 bool VisualTools::publishEEMarkers(const geometry_msgs::Pose &pose, const rviz_colors &color, const std::string &ns)
00777 {
00778 if(muted_)
00779 return true;
00780
00781
00782 if( ee_marker_array_.markers.empty() )
00783 {
00784 ROS_ERROR_STREAM_NAMED("visual_tools","Unable to publish EE marker because marker has not been loaded yet");
00785 return false;
00786 }
00787
00788
00789
00790
00791
00792 Eigen::Affine3d ee_pose_eigen;
00793 Eigen::Affine3d eef_conversion_pose;
00794 tf::poseMsgToEigen(pose, ee_pose_eigen);
00795 tf::poseMsgToEigen(grasp_pose_to_eef_pose_, eef_conversion_pose);
00796
00797
00798 ee_pose_eigen = ee_pose_eigen * eef_conversion_pose;
00799
00800
00801 geometry_msgs::Pose ee_pose = convertPose(ee_pose_eigen);
00802
00803
00804
00805 for (std::size_t i = 0 ; i < ee_marker_array_.markers.size() ; ++i)
00806 {
00807
00808 if( !ros::ok() )
00809 break;
00810
00811
00812 ee_marker_array_.markers[i].header.frame_id = base_frame_;
00813 ee_marker_array_.markers[i].header.stamp = ros::Time::now();
00814
00815
00816 ee_marker_array_.markers[i].ns = ns;
00817
00818
00819 ee_marker_array_.markers[i].lifetime = marker_lifetime_;
00820
00821
00822 ee_marker_array_.markers[i].color = getColor( color );
00823
00824
00825 if( ee_marker_array_.markers[i].type == visualization_msgs::Marker::MESH_RESOURCE )
00826 {
00827 ee_marker_array_.markers[i].mesh_use_embedded_materials = true;
00828 }
00829
00830
00831
00832
00833
00834
00835 tf::Pose tf_root_to_marker;
00836 tf::Pose tf_root_to_mesh;
00837 tf::Pose tf_pose_to_eef;
00838
00839
00840 tf::poseMsgToTF(pose, tf_root_to_marker);
00841 tf::poseMsgToTF(marker_poses_[i], tf_root_to_mesh);
00842
00843
00844 tf::Pose tf_eef_to_mesh = tf_root_to_link_.inverse() * tf_root_to_mesh;
00845 tf::Pose tf_root_to_mesh_new = tf_root_to_marker * tf_eef_to_mesh;
00846 tf::poseTFToMsg(tf_root_to_mesh_new, ee_marker_array_.markers[i].pose);
00847
00848
00849
00850
00851 loadMarkerPub();
00852 pub_rviz_marker_.publish( ee_marker_array_.markers[i] );
00853 ros::spinOnce();
00854 }
00855
00856 return true;
00857 }
00858
00859 bool VisualTools::publishSphere(const Eigen::Affine3d &pose, const rviz_colors color, const rviz_scales scale, const std::string& ns)
00860 {
00861 return publishSphere(convertPose(pose), color, scale, ns);
00862 }
00863
00864 bool VisualTools::publishSphere(const Eigen::Vector3d &point, const rviz_colors color, const rviz_scales scale, const std::string& ns)
00865 {
00866 geometry_msgs::Pose pose_msg;
00867 tf::pointEigenToMsg(point, pose_msg.position);
00868 return publishSphere(pose_msg, color, scale, ns);
00869 }
00870
00871 bool VisualTools::publishSphere(const geometry_msgs::Point &point, const rviz_colors color, const rviz_scales scale, const std::string& ns)
00872 {
00873 geometry_msgs::Pose pose_msg;
00874 pose_msg.position = point;
00875 return publishSphere(pose_msg, color, scale, ns);
00876 }
00877
00878 bool VisualTools::publishSphere(const geometry_msgs::Pose &pose, const rviz_colors color, const rviz_scales scale, const std::string& ns)
00879 {
00880 return publishSphere(pose, color, getScale(scale, false, 0.1), ns);
00881 }
00882
00883 bool VisualTools::publishSphere(const geometry_msgs::Pose &pose, const rviz_colors color, double scale, const std::string& ns)
00884 {
00885 geometry_msgs::Vector3 scale_msg;
00886 scale_msg.x = scale;
00887 scale_msg.y = scale;
00888 scale_msg.z = scale;
00889 return publishSphere(pose, color, scale_msg, ns);
00890 }
00891 bool VisualTools::publishSphere(const geometry_msgs::Pose &pose, const rviz_colors color, const geometry_msgs::Vector3 scale, const std::string& ns)
00892 {
00893 if(muted_)
00894 return true;
00895
00896
00897 sphere_marker_.header.stamp = ros::Time::now();
00898
00899 sphere_marker_.id++;
00900 sphere_marker_.color = getColor(color);
00901 sphere_marker_.scale = scale;
00902 sphere_marker_.ns = ns;
00903
00904
00905 sphere_marker_.points[0] = pose.position;
00906 sphere_marker_.colors[0] = getColor(color);
00907
00908
00909 loadMarkerPub();
00910 pub_rviz_marker_.publish( sphere_marker_ );
00911 ros::spinOnce();
00912
00913 return true;
00914 }
00915
00916 bool VisualTools::publishArrow(const Eigen::Affine3d &pose, const rviz_colors color, const rviz_scales scale)
00917 {
00918 return publishArrow(convertPose(pose), color, scale);
00919 }
00920
00921 bool VisualTools::publishArrow(const geometry_msgs::Pose &pose, const rviz_colors color, const rviz_scales scale)
00922 {
00923 if(muted_)
00924 return true;
00925
00926
00927 arrow_marker_.header.stamp = ros::Time::now();
00928
00929 arrow_marker_.id++;
00930 arrow_marker_.pose = pose;
00931 arrow_marker_.color = getColor(color);
00932 arrow_marker_.scale = getScale(scale, true);
00933
00934 loadMarkerPub();
00935 pub_rviz_marker_.publish( arrow_marker_ );
00936 ros::spinOnce();
00937
00938 return true;
00939 }
00940
00941 bool VisualTools::publishBlock(const geometry_msgs::Pose &pose, const rviz_colors color, const double &block_size)
00942 {
00943 if(muted_)
00944 return true;
00945
00946
00947 block_marker_.header.stamp = ros::Time::now();
00948
00949 block_marker_.id++;
00950
00951
00952 block_marker_.pose = pose;
00953
00954
00955 block_marker_.scale.x = block_size;
00956 block_marker_.scale.y = block_size;
00957 block_marker_.scale.z = block_size;
00958
00959
00960 block_marker_.color = getColor( color );
00961
00962 loadMarkerPub();
00963 pub_rviz_marker_.publish( block_marker_ );
00964 ros::spinOnce();
00965
00966 return true;
00967 }
00968
00969 bool VisualTools::publishCylinder(const geometry_msgs::Pose &pose, const rviz_colors color, double height, double radius)
00970 {
00971 if(muted_)
00972 return true;
00973
00974
00975 cylinder_marker_.header.stamp = ros::Time::now();
00976
00977 cylinder_marker_.id++;
00978
00979
00980 cylinder_marker_.pose = pose;
00981
00982
00983 cylinder_marker_.scale.x = radius;
00984 cylinder_marker_.scale.y = radius;
00985 cylinder_marker_.scale.z = height;
00986
00987
00988 cylinder_marker_.color = getColor( color );
00989
00990 loadMarkerPub();
00991 pub_rviz_marker_.publish( cylinder_marker_ );
00992 ros::spinOnce();
00993
00994 return true;
00995 }
00996
00997 bool VisualTools::publishGraph(const graph_msgs::GeometryGraph &graph, const rviz_colors color, double radius)
00998 {
00999 if(muted_)
01000 return true;
01001
01002
01003 typedef std::pair<std::size_t, std::size_t> node_ids;
01004 std::set<node_ids> added_edges;
01005 std::pair<std::set<node_ids>::iterator,bool> return_value;
01006
01007 Eigen::Vector3d a, b;
01008 for (std::size_t i = 0; i < graph.nodes.size(); ++i)
01009 {
01010 for (std::size_t j = 0; j < graph.edges[i].node_ids.size(); ++j)
01011 {
01012
01013 return_value = added_edges.insert( node_ids(i,j) );
01014 if (return_value.second == false)
01015 {
01016
01017 }
01018 else
01019 {
01020
01021 a = convertPoint(graph.nodes[i]);
01022 b = convertPoint(graph.nodes[graph.edges[i].node_ids[j]]);
01023
01024
01025 added_edges.insert( node_ids(j,i) );
01026
01027
01028 double height = (a - b).lpNorm<2>();
01029
01030
01031 Eigen::Vector3d pt_center = getCenterPoint(a, b);
01032
01033
01034 Eigen::Affine3d pose;
01035 pose = getVectorBetweenPoints(pt_center, b);
01036
01037
01038 Eigen::Affine3d rotation;
01039 rotation = Eigen::AngleAxisd(0.5*M_PI, Eigen::Vector3d::UnitY());
01040 pose = pose * rotation;
01041
01042
01043 publishCylinder(convertPose(pose), color, height, radius);
01044 }
01045 }
01046 }
01047
01048 return true;
01049 }
01050
01051 bool VisualTools::publishRectangle(const geometry_msgs::Point &point1, const geometry_msgs::Point &point2, const rviz_colors color)
01052 {
01053 if(muted_)
01054 return true;
01055
01056
01057 rectangle_marker_.header.stamp = ros::Time::now();
01058
01059 rectangle_marker_.id++;
01060 rectangle_marker_.color = getColor(color);
01061
01062
01063 geometry_msgs::Pose pose;
01064 pose.position.x = (point1.x - point2.x) / 2.0 + point2.x;
01065 pose.position.y = (point1.y - point2.y) / 2.0 + point2.y;
01066 pose.position.z = (point1.z - point2.z) / 2.0 + point2.z;
01067 rectangle_marker_.pose = pose;
01068
01069
01070 rectangle_marker_.scale.x = fabs(point1.x - point2.x);
01071 rectangle_marker_.scale.y = fabs(point1.y - point2.y);
01072 rectangle_marker_.scale.z = fabs(point1.z - point2.z);
01073
01074 loadMarkerPub();
01075 pub_rviz_marker_.publish( rectangle_marker_ );
01076 ros::spinOnce();
01077
01078 return true;
01079 }
01080
01081 bool VisualTools::publishLine(const geometry_msgs::Point &point1, const geometry_msgs::Point &point2,
01082 const rviz_colors color, const rviz_scales scale)
01083 {
01084 if(muted_)
01085 return true;
01086
01087
01088 line_marker_.header.stamp = ros::Time::now();
01089
01090 line_marker_.id++;
01091 line_marker_.color = getColor(color);
01092 line_marker_.scale = getScale( scale, false, 0.1 );
01093
01094 line_marker_.points.clear();
01095 line_marker_.points.push_back(point1);
01096 line_marker_.points.push_back(point2);
01097
01098 loadMarkerPub();
01099 pub_rviz_marker_.publish( line_marker_ );
01100 ros::spinOnce();
01101
01102 return true;
01103 }
01104
01105 bool VisualTools::publishPath(const std::vector<geometry_msgs::Point> &path, const rviz_colors color, const rviz_scales scale, const std::string& ns)
01106 {
01107 if(muted_)
01108 return true;
01109
01110 if (path.size() < 2)
01111 {
01112 ROS_WARN_STREAM_NAMED("publishPath","Skipping path because " << path.size() << " points passed in.");
01113 return true;
01114 }
01115
01116 path_marker_.header.stamp = ros::Time();
01117 path_marker_.ns = ns;
01118
01119
01120 path_marker_.id++;
01121
01122 std_msgs::ColorRGBA this_color = getColor( color );
01123 path_marker_.scale = getScale(scale, false, 0.25);
01124 path_marker_.color = this_color;
01125 path_marker_.points.clear();
01126 path_marker_.colors.clear();
01127
01128
01129 for( std::size_t i = 1; i < path.size(); ++i )
01130 {
01131
01132 path_marker_.points.push_back( path[i-1] );
01133 path_marker_.points.push_back( path[i] );
01134 path_marker_.colors.push_back( this_color );
01135 path_marker_.colors.push_back( this_color );
01136 }
01137
01138
01139 loadMarkerPub();
01140 pub_rviz_marker_.publish( path_marker_ );
01141 ros::spinOnce();
01142
01143 return true;
01144 }
01145
01146 bool VisualTools::publishPolygon(const geometry_msgs::Polygon &polygon, const rviz_colors color, const rviz_scales scale, const std::string& ns)
01147 {
01148 std::vector<geometry_msgs::Point> points;
01149 geometry_msgs::Point temp;
01150 geometry_msgs::Point first;
01151 for (std::size_t i = 0; i < polygon.points.size(); ++i)
01152 {
01153 temp.x = polygon.points[i].x;
01154 temp.y = polygon.points[i].y;
01155 temp.z = polygon.points[i].z;
01156 if (i == 0)
01157 first = temp;
01158 points.push_back(temp);
01159 }
01160 points.push_back(first);
01161
01162 publishPath(points, color, scale, ns);
01163 }
01164
01165 bool VisualTools::publishSpheres(const std::vector<geometry_msgs::Point> &points, const rviz_colors color, const rviz_scales scale, const std::string& ns)
01166 {
01167 if(muted_)
01168 return true;
01169
01170 spheres_marker_.header.stamp = ros::Time();
01171 spheres_marker_.ns = ns;
01172
01173
01174 spheres_marker_.id++;
01175
01176 std_msgs::ColorRGBA this_color = getColor( color );
01177 spheres_marker_.scale = getScale(scale, false, 0.25);
01178 spheres_marker_.color = this_color;
01179
01180 spheres_marker_.colors.clear();
01181
01182 spheres_marker_.points = points;
01183
01184
01185 for( std::size_t i = 0; i < points.size(); ++i )
01186 {
01187 spheres_marker_.colors.push_back( this_color );
01188 }
01189
01190
01191 loadMarkerPub();
01192 pub_rviz_marker_.publish( spheres_marker_ );
01193 ros::spinOnce();
01194
01195 return true;
01196 }
01197
01198 bool VisualTools::publishText(const geometry_msgs::Pose &pose, const std::string &text, const rviz_colors &color, const rviz_scales scale)
01199 {
01200 publishText(pose, text, color, getScale(scale));
01201 }
01202
01203 bool VisualTools::publishText(const geometry_msgs::Pose &pose, const std::string &text, const rviz_colors &color, const geometry_msgs::Vector3 scale, bool static_id)
01204 {
01205 if(muted_)
01206 return true;
01207
01208
01209 double temp_id = text_marker_.id;
01210 if (static_id)
01211 {
01212 text_marker_.id = 0;
01213 }
01214 else
01215 {
01216 text_marker_.id++;
01217 }
01218
01219 text_marker_.header.stamp = ros::Time::now();
01220 text_marker_.text = text;
01221 text_marker_.pose = pose;
01222 text_marker_.color = getColor( color );
01223 text_marker_.scale = scale;
01224
01225 loadMarkerPub();
01226 pub_rviz_marker_.publish( text_marker_ );
01227 ros::spinOnce();
01228
01229
01230 if (static_id)
01231 text_marker_.id = temp_id;
01232
01233 return true;
01234 }
01235
01236 bool VisualTools::publishMarker(const visualization_msgs::Marker &marker)
01237 {
01238 if(muted_)
01239 return true;
01240
01241 loadMarkerPub();
01242 pub_rviz_marker_.publish( marker );
01243 ros::spinOnce();
01244
01245 return true;
01246 }
01247
01248 bool VisualTools::publishGrasps(const std::vector<moveit_msgs::Grasp>& possible_grasps,
01249 const std::string &ee_parent_link)
01250 {
01251 if(muted_)
01252 {
01253 ROS_DEBUG_STREAM_NAMED("visual_tools","Not visualizing grasps - muted.");
01254 return false;
01255 }
01256
01257 ROS_DEBUG_STREAM_NAMED("visual_tools","Visualizing " << possible_grasps.size() << " grasps with parent link "
01258 << ee_parent_link);
01259
01260
01261 for (std::size_t i = 0; i < possible_grasps.size(); ++i)
01262 {
01263 if( !ros::ok() )
01264 break;
01265
01266 ROS_DEBUG_STREAM_NAMED("grasp","Visualizing grasp pose " << i);
01267
01268 publishEEMarkers(possible_grasps[i].grasp_pose.pose);
01269
01270 ros::Duration(0.1).sleep();
01271 }
01272
01273 return true;
01274 }
01275
01276 bool VisualTools::publishAnimatedGrasps(const std::vector<moveit_msgs::Grasp>& possible_grasps,
01277 const std::string &ee_parent_link, double animate_speed)
01278 {
01279 if(muted_)
01280 {
01281 ROS_DEBUG_STREAM_NAMED("visual_tools","Not visualizing grasps - muted.");
01282 return false;
01283 }
01284
01285 ROS_DEBUG_STREAM_NAMED("visual_tools","Visualizing " << possible_grasps.size() << " grasps with parent link "
01286 << ee_parent_link << " at speed " << animate_speed);
01287
01288
01289 for (std::size_t i = 0; i < possible_grasps.size(); ++i)
01290 {
01291 if( !ros::ok() )
01292 break;
01293
01294 publishAnimatedGrasp(possible_grasps[i], ee_parent_link, animate_speed);
01295
01296 ros::Duration(0.1).sleep();
01297 }
01298
01299 return true;
01300 }
01301
01302 bool VisualTools::publishAnimatedGrasp(const moveit_msgs::Grasp &grasp, const std::string &ee_parent_link, double animate_speed)
01303 {
01304 if(muted_)
01305 return true;
01306
01307
01308 geometry_msgs::Pose grasp_pose = grasp.grasp_pose.pose;
01309 Eigen::Affine3d grasp_pose_eigen;
01310 tf::poseMsgToEigen(grasp_pose, grasp_pose_eigen);
01311
01312
01313 geometry_msgs::Pose pre_grasp_pose;
01314 Eigen::Affine3d pre_grasp_pose_eigen;
01315
01316
01317 Eigen::Vector3d pre_grasp_approach_direction_local;
01318
01319
01320 std::string text = "Grasp Quality: " + boost::lexical_cast<std::string>(int(grasp.grasp_quality*100)) + "%";
01321 publishText(grasp_pose, text);
01322
01323
01324
01325
01326 double animation_resulution = 0.1;
01327 for(double percent = 0; percent < 1; percent += animation_resulution)
01328 {
01329 if( !ros::ok() )
01330 break;
01331
01332
01333 pre_grasp_pose_eigen = grasp_pose_eigen;
01334
01335
01336
01337 Eigen::Vector3d pre_grasp_approach_direction = Eigen::Vector3d(
01338 -1 * grasp.pre_grasp_approach.direction.vector.x * grasp.pre_grasp_approach.desired_distance * (1-percent),
01339 -1 * grasp.pre_grasp_approach.direction.vector.y * grasp.pre_grasp_approach.desired_distance * (1-percent),
01340 -1 * grasp.pre_grasp_approach.direction.vector.z * grasp.pre_grasp_approach.desired_distance * (1-percent)
01341 );
01342
01343
01344 if( grasp.pre_grasp_approach.direction.header.frame_id == ee_parent_link )
01345 {
01346
01347 pre_grasp_approach_direction_local = grasp_pose_eigen.rotation() * pre_grasp_approach_direction;
01348 }
01349 else
01350 {
01351 pre_grasp_approach_direction_local = pre_grasp_approach_direction;
01352 }
01353
01354
01355 pre_grasp_pose_eigen.translation() += pre_grasp_approach_direction_local;
01356
01357
01358 tf::poseEigenToMsg(pre_grasp_pose_eigen, pre_grasp_pose);
01359
01360
01361 publishEEMarkers(pre_grasp_pose);
01362
01363 ros::Duration(animate_speed).sleep();
01364 }
01365 return true;
01366 }
01367
01368 bool VisualTools::publishIKSolutions(const std::vector<trajectory_msgs::JointTrajectoryPoint> &ik_solutions,
01369 const std::string& planning_group, double display_time)
01370 {
01371 if(muted_)
01372 {
01373 ROS_DEBUG_STREAM_NAMED("visual_tools","Not visualizing inverse kinematic solutions - muted.");
01374 return false;
01375 }
01376
01377 if (ik_solutions.empty())
01378 {
01379 ROS_WARN_STREAM_NAMED("visual_tools","Empty ik_solutions vector passed into publishIKSolutions()");
01380 return false;
01381 }
01382
01383 loadSharedRobotState();
01384
01385 ROS_DEBUG_STREAM_NAMED("visual_tools","Visualizing " << ik_solutions.size() << " inverse kinematic solutions");
01386
01387
01388 robot_model::RobotModelConstPtr robot_model = shared_robot_state_->getRobotModel();
01389
01390 const robot_model::JointModelGroup* joint_model_group = robot_model->getJointModelGroup(planning_group);
01391
01392 if (joint_model_group == NULL)
01393 {
01394 ROS_ERROR_STREAM_NAMED("publishIKSolutions","Could not find joint model group " << planning_group);
01395 return false;
01396 }
01397
01398
01399 trajectory_msgs::JointTrajectoryPoint trajectory_pt_timed;
01400
01401
01402 moveit_msgs::RobotTrajectory trajectory_msg;
01403 trajectory_msg.joint_trajectory.header.frame_id = base_frame_;
01404 trajectory_msg.joint_trajectory.joint_names = joint_model_group->getJointModelNames();
01405
01406
01407 double running_time = 0;
01408
01409
01410 for (std::size_t i = 0; i < ik_solutions.size(); ++i)
01411 {
01412 if( !ros::ok() )
01413 break;
01414
01415 trajectory_pt_timed = ik_solutions[i];
01416 trajectory_pt_timed.time_from_start = ros::Duration(running_time);
01417 trajectory_msg.joint_trajectory.points.push_back(trajectory_pt_timed);
01418
01419 running_time += display_time;
01420
01421
01422 }
01423
01424
01425 trajectory_pt_timed = trajectory_msg.joint_trajectory.points.back();
01426 trajectory_pt_timed.time_from_start = ros::Duration(running_time);
01427 trajectory_msg.joint_trajectory.points.push_back(trajectory_pt_timed);
01428
01429 return publishTrajectoryPath(trajectory_msg, true);
01430 }
01431
01432 bool VisualTools::publishRemoveAllCollisionObjects()
01433 {
01434
01435
01436 moveit_msgs::PlanningScene planning_scene;
01437 planning_scene.is_diff = true;
01438 planning_scene.world.collision_objects.clear();
01439
01440
01441 moveit_msgs::CollisionObject remove_object;
01442 remove_object.header.frame_id = base_frame_;
01443 remove_object.operation = moveit_msgs::CollisionObject::REMOVE;
01444
01445 planning_scene.world.collision_objects.push_back(remove_object);
01446
01447
01448 loadPlanningPub();
01449 pub_planning_scene_diff_.publish(planning_scene);
01450 ros::spinOnce();
01451
01452 return true;
01453 }
01454
01455 bool VisualTools::removeAllCollisionObjectsPS()
01456 {
01457
01458 moveit_msgs::CollisionObject remove_object;
01459 remove_object.header.frame_id = base_frame_;
01460 remove_object.operation = moveit_msgs::CollisionObject::REMOVE;
01461
01462 processCollisionObjectMsg(remove_object);
01463 }
01464
01465 bool VisualTools::cleanupCO(std::string name)
01466 {
01467
01468 moveit_msgs::CollisionObject co;
01469 co.header.stamp = ros::Time::now();
01470 co.header.frame_id = base_frame_;
01471 co.id = name;
01472 co.operation = moveit_msgs::CollisionObject::REMOVE;
01473
01474 loadCollisionPub();
01475 pub_collision_obj_.publish(co);
01476 ros::spinOnce();
01477 return true;
01478 }
01479
01480 bool VisualTools::cleanupACO(const std::string& name)
01481 {
01482
01483 moveit_msgs::AttachedCollisionObject aco;
01484 aco.object.header.stamp = ros::Time::now();
01485 aco.object.header.frame_id = base_frame_;
01486
01487
01488 aco.object.operation = moveit_msgs::CollisionObject::REMOVE;
01489
01490
01491
01492 loadAttachedPub();
01493 pub_attach_collision_obj_.publish(aco);
01494 ros::spinOnce();
01495 return true;
01496 }
01497
01498 bool VisualTools::attachCO(const std::string& name, const std::string& ee_parent_link)
01499 {
01500
01501 moveit_msgs::AttachedCollisionObject aco;
01502 aco.object.header.stamp = ros::Time::now();
01503 aco.object.header.frame_id = base_frame_;
01504
01505 aco.object.id = name;
01506 aco.object.operation = moveit_msgs::CollisionObject::ADD;
01507
01508
01509 aco.link_name = ee_parent_link;
01510
01511 loadAttachedPub();
01512 pub_attach_collision_obj_.publish(aco);
01513 ros::spinOnce();
01514 return true;
01515 }
01516
01517 bool VisualTools::publishCollisionFloor(double z, std::string plane_name)
01518 {
01519 moveit_msgs::CollisionObject collision_obj;
01520 collision_obj.header.stamp = ros::Time::now();
01521 collision_obj.header.frame_id = base_frame_;
01522 collision_obj.id = plane_name;
01523 collision_obj.operation = moveit_msgs::CollisionObject::ADD;
01524 collision_obj.planes.resize(1);
01525
01526 collision_obj.planes[0].coef[0] = 0;
01527 collision_obj.planes[0].coef[1] = 0;
01528 collision_obj.planes[0].coef[2] = 0;
01529 collision_obj.planes[0].coef[3] = 0;
01530
01531 geometry_msgs::Pose floor_pose;
01532
01533
01534 floor_pose.position.x = 0;
01535 floor_pose.position.y = 0;
01536 floor_pose.position.z = z;
01537
01538
01539 Eigen::Quaterniond quat(Eigen::AngleAxis<double>(0.0, Eigen::Vector3d::UnitZ()));
01540 floor_pose.orientation.x = quat.x();
01541 floor_pose.orientation.y = quat.y();
01542 floor_pose.orientation.z = quat.z();
01543 floor_pose.orientation.w = quat.w();
01544
01545 collision_obj.plane_poses.resize(1);
01546 collision_obj.plane_poses[0] = floor_pose;
01547
01548 ROS_INFO_STREAM_NAMED("pick_place","CollisionObject: \n " << collision_obj);
01549
01550 processCollisionObjectMsg(collision_obj);
01551
01552 ROS_DEBUG_STREAM_NAMED("visual_tools","Published collision object " << plane_name);
01553 return true;
01554 }
01555
01556 bool VisualTools::publishCollisionBlock(geometry_msgs::Pose block_pose, std::string block_name, double block_size)
01557 {
01558 moveit_msgs::CollisionObject collision_obj;
01559 collision_obj.header.stamp = ros::Time::now();
01560 collision_obj.header.frame_id = base_frame_;
01561 collision_obj.id = block_name;
01562 collision_obj.operation = moveit_msgs::CollisionObject::ADD;
01563 collision_obj.primitives.resize(1);
01564 collision_obj.primitives[0].type = shape_msgs::SolidPrimitive::BOX;
01565 collision_obj.primitives[0].dimensions.resize(shape_tools::SolidPrimitiveDimCount<shape_msgs::SolidPrimitive::BOX>::value);
01566 collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_X] = block_size;
01567 collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_Y] = block_size;
01568 collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_Z] = block_size;
01569 collision_obj.primitive_poses.resize(1);
01570 collision_obj.primitive_poses[0] = block_pose;
01571
01572
01573
01574 loadCollisionPub();
01575 pub_collision_obj_.publish(collision_obj);
01576 ros::spinOnce();
01577
01578 ROS_DEBUG_STREAM_NAMED("visual_tools","Published collision object " << block_name);
01579 return true;
01580 }
01581
01582 bool VisualTools::publishCollisionCylinder(geometry_msgs::Point a, geometry_msgs::Point b, std::string object_name, double radius)
01583 {
01584 return publishCollisionCylinder(convertPoint(a), convertPoint(b), object_name, radius);
01585 }
01586
01587 bool VisualTools::publishCollisionCylinder(Eigen::Vector3d a, Eigen::Vector3d b, std::string object_name, double radius)
01588 {
01589
01590 double height = (a - b).lpNorm<2>();
01591
01592
01593 Eigen::Vector3d pt_center = getCenterPoint(a, b);
01594
01595
01596 Eigen::Affine3d pose;
01597 pose = getVectorBetweenPoints(pt_center, b);
01598
01599
01600 Eigen::Affine3d rotation;
01601 rotation = Eigen::AngleAxisd(0.5*M_PI, Eigen::Vector3d::UnitY());
01602 pose = pose * rotation;
01603
01604 return publishCollisionCylinder(pose, object_name, radius, height);
01605 }
01606
01607 bool VisualTools::publishCollisionCylinder(Eigen::Affine3d object_pose, std::string object_name, double radius, double height)
01608 {
01609 return publishCollisionCylinder(convertPose(object_pose), object_name, radius, height);
01610 }
01611
01612 bool VisualTools::publishCollisionCylinder(geometry_msgs::Pose object_pose, std::string object_name, double radius, double height)
01613 {
01614 moveit_msgs::CollisionObject collision_obj;
01615 collision_obj.header.stamp = ros::Time::now();
01616 collision_obj.header.frame_id = base_frame_;
01617 collision_obj.id = object_name;
01618 collision_obj.operation = moveit_msgs::CollisionObject::ADD;
01619 collision_obj.primitives.resize(1);
01620 collision_obj.primitives[0].type = shape_msgs::SolidPrimitive::CYLINDER;
01621 collision_obj.primitives[0].dimensions.resize(shape_tools::SolidPrimitiveDimCount<shape_msgs::SolidPrimitive::CYLINDER>::value);
01622 collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::CYLINDER_HEIGHT] = height;
01623 collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::CYLINDER_RADIUS] = radius;
01624 collision_obj.primitive_poses.resize(1);
01625 collision_obj.primitive_poses[0] = object_pose;
01626
01627
01628
01629 loadCollisionPub();
01630 pub_collision_obj_.publish(collision_obj);
01631 ros::spinOnce();
01632
01633
01634 return true;
01635 }
01636
01637 bool VisualTools::publishCollisionGraph(const graph_msgs::GeometryGraph &graph, const std::string &object_name, double radius)
01638 {
01639 ROS_INFO_STREAM_NAMED("publishCollisionGraph","Preparing to create collision graph");
01640
01641
01642 moveit_msgs::CollisionObject collision_obj;
01643 collision_obj.header.stamp = ros::Time::now();
01644 collision_obj.header.frame_id = base_frame_;
01645 collision_obj.id = object_name;
01646 collision_obj.operation = moveit_msgs::CollisionObject::ADD;
01647
01648
01649 typedef std::pair<std::size_t, std::size_t> node_ids;
01650 std::set<node_ids> added_edges;
01651 std::pair<std::set<node_ids>::iterator,bool> return_value;
01652
01653 Eigen::Vector3d a, b;
01654 for (std::size_t i = 0; i < graph.nodes.size(); ++i)
01655 {
01656 for (std::size_t j = 0; j < graph.edges[i].node_ids.size(); ++j)
01657 {
01658
01659 return_value = added_edges.insert( node_ids(i,j) );
01660 if (return_value.second == false)
01661 {
01662
01663 }
01664 else
01665 {
01666
01667 a = convertPoint(graph.nodes[i]);
01668 b = convertPoint(graph.nodes[graph.edges[i].node_ids[j]]);
01669
01670
01671 added_edges.insert( node_ids(j,i) );
01672
01673
01674 double height = (a - b).lpNorm<2>();
01675
01676
01677 Eigen::Vector3d pt_center = getCenterPoint(a, b);
01678
01679
01680 Eigen::Affine3d pose;
01681 pose = getVectorBetweenPoints(pt_center, b);
01682
01683
01684 Eigen::Affine3d rotation;
01685 rotation = Eigen::AngleAxisd(0.5*M_PI, Eigen::Vector3d::UnitY());
01686 pose = pose * rotation;
01687
01688
01689 shape_msgs::SolidPrimitive cylinder;
01690 cylinder.type = shape_msgs::SolidPrimitive::CYLINDER;
01691 cylinder.dimensions.resize(shape_tools::SolidPrimitiveDimCount<shape_msgs::SolidPrimitive::CYLINDER>::value);
01692 cylinder.dimensions[shape_msgs::SolidPrimitive::CYLINDER_HEIGHT] = height;
01693 cylinder.dimensions[shape_msgs::SolidPrimitive::CYLINDER_RADIUS] = radius;
01694
01695
01696 collision_obj.primitives.push_back(cylinder);
01697
01698
01699 collision_obj.primitive_poses.push_back(convertPose(pose));
01700 }
01701 }
01702 }
01703
01704 loadCollisionPub();
01705 pub_collision_obj_.publish(collision_obj);
01706 ros::spinOnce();
01707
01708 return true;
01709 }
01710
01711 void VisualTools::getCollisionWallMsg(double x, double y, double angle, double width, const std::string name,
01712 moveit_msgs::CollisionObject &collision_obj)
01713 {
01714 collision_obj.header.stamp = ros::Time::now();
01715 collision_obj.header.frame_id = base_frame_;
01716 collision_obj.operation = moveit_msgs::CollisionObject::ADD;
01717 collision_obj.primitives.resize(1);
01718 collision_obj.primitives[0].type = shape_msgs::SolidPrimitive::BOX;
01719 collision_obj.primitives[0].dimensions.resize(shape_tools::SolidPrimitiveDimCount<shape_msgs::SolidPrimitive::BOX>::value);
01720
01721 geometry_msgs::Pose rec_pose;
01722
01723
01724
01725 collision_obj.id = name;
01726
01727 double depth = 0.1;
01728 double height = 2.5;
01729
01730
01731 rec_pose.position.x = x;
01732 rec_pose.position.y = y;
01733 rec_pose.position.z = height / 2 + floor_to_base_height_;
01734
01735
01736 collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_X] = depth;
01737 collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_Y] = width;
01738 collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_Z] = height;
01739
01740
01741 Eigen::Quaterniond quat(Eigen::AngleAxis<double>(double(angle), Eigen::Vector3d::UnitZ()));
01742 rec_pose.orientation.x = quat.x();
01743 rec_pose.orientation.y = quat.y();
01744 rec_pose.orientation.z = quat.z();
01745 rec_pose.orientation.w = quat.w();
01746
01747 collision_obj.primitive_poses.resize(1);
01748 collision_obj.primitive_poses[0] = rec_pose;
01749 }
01750
01751 bool VisualTools::publishCollisionWall(double x, double y, double angle, double width, const std::string name)
01752 {
01753 moveit_msgs::CollisionObject collision_obj;
01754 getCollisionWallMsg(x, y, angle, width, name, collision_obj);
01755
01756 loadCollisionPub();
01757 pub_collision_obj_.publish(collision_obj);
01758 ros::spinOnce();
01759
01760 return true;
01761 }
01762
01763 bool VisualTools::publishCollisionTable(double x, double y, double angle, double width, double height,
01764 double depth, const std::string name)
01765 {
01766 geometry_msgs::Pose table_pose;
01767
01768
01769 table_pose.position.x = x;
01770 table_pose.position.y = y;
01771 table_pose.position.z = height / 2 + floor_to_base_height_;
01772
01773
01774 Eigen::Quaterniond quat(Eigen::AngleAxis<double>(double(angle), Eigen::Vector3d::UnitZ()));
01775 table_pose.orientation.x = quat.x();
01776 table_pose.orientation.y = quat.y();
01777 table_pose.orientation.z = quat.z();
01778 table_pose.orientation.w = quat.w();
01779
01780 moveit_msgs::CollisionObject collision_obj;
01781 collision_obj.header.stamp = ros::Time::now();
01782 collision_obj.header.frame_id = base_frame_;
01783 collision_obj.id = name;
01784 collision_obj.operation = moveit_msgs::CollisionObject::ADD;
01785 collision_obj.primitives.resize(1);
01786 collision_obj.primitives[0].type = shape_msgs::SolidPrimitive::BOX;
01787 collision_obj.primitives[0].dimensions.resize(shape_tools::SolidPrimitiveDimCount<shape_msgs::SolidPrimitive::BOX>::value);
01788
01789
01790 collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_X] = depth;
01791 collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_Y] = width;
01792 collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_Z] = height;
01793
01794 collision_obj.primitive_poses.resize(1);
01795 collision_obj.primitive_poses[0] = table_pose;
01796
01797 loadCollisionPub();
01798 pub_collision_obj_.publish(collision_obj);
01799 ros::spinOnce();
01800
01801 return true;
01802 }
01803
01804 bool VisualTools::loadCollisionSceneFromFile(const std::string &path)
01805 {
01806 {
01807
01808 planning_scene_monitor::LockedPlanningSceneRW scene(getPlanningSceneMonitor());
01809 if (scene)
01810 {
01811
01812 std::ifstream fin(path.c_str());
01813 if (fin.good())
01814 {
01815 scene->loadGeometryFromStream(fin);
01816 fin.close();
01817 ROS_INFO("Loaded scene geometry from '%s'", path.c_str());
01818 }
01819 else
01820 ROS_WARN("Unable to load scene geometry from '%s'", path.c_str());
01821 }
01822 else
01823 ROS_WARN_STREAM_NAMED("temp","Unable to get locked planning scene RW");
01824 }
01825 getPlanningSceneMonitor()->triggerSceneUpdateEvent(planning_scene_monitor::PlanningSceneMonitor::UPDATE_SCENE);
01826 }
01827
01828 bool VisualTools::publishTrajectoryPoint(const trajectory_msgs::JointTrajectoryPoint& trajectory_pt,
01829 const std::string &group_name, double display_time)
01830 {
01831 loadSharedRobotState();
01832
01833
01834 robot_model::RobotModelConstPtr robot_model = shared_robot_state_->getRobotModel();
01835
01836 const robot_model::JointModelGroup* joint_model_group = robot_model->getJointModelGroup(group_name);
01837
01838 if (joint_model_group == NULL)
01839 {
01840 ROS_ERROR_STREAM_NAMED("publishTrajectoryPoint","Could not find joint model group " << group_name);
01841 return false;
01842 }
01843
01844
01845 trajectory_msgs::JointTrajectoryPoint trajectory_pt_timed = trajectory_pt;
01846 trajectory_pt_timed.time_from_start = ros::Duration(display_time);
01847
01848
01849 moveit_msgs::RobotTrajectory trajectory_msg;
01850 trajectory_msg.joint_trajectory.header.frame_id = base_frame_;
01851 trajectory_msg.joint_trajectory.joint_names = joint_model_group->getJointModelNames();
01852 trajectory_msg.joint_trajectory.points.push_back(trajectory_pt);
01853 trajectory_msg.joint_trajectory.points.push_back(trajectory_pt_timed);
01854
01855 return publishTrajectoryPath(trajectory_msg, true);
01856 }
01857
01858 bool VisualTools::publishTrajectoryPath(const robot_trajectory::RobotTrajectory& trajectory, bool blocking)
01859 {
01860 moveit_msgs::RobotTrajectory trajectory_msg;
01861 trajectory.getRobotTrajectoryMsg(trajectory_msg);
01862
01863
01864 if (trajectory_msg.joint_trajectory.points.size() > 1)
01865 {
01866 if (trajectory_msg.joint_trajectory.points[1].time_from_start == ros::Duration(0))
01867 {
01868 for (std::size_t i = 0; i < trajectory_msg.joint_trajectory.points.size(); ++i)
01869 {
01870 trajectory_msg.joint_trajectory.points[i].time_from_start = ros::Duration(i*2);
01871 }
01872 }
01873 }
01874
01875
01876
01877 publishTrajectoryPath(trajectory_msg, blocking);
01878 }
01879
01880 bool VisualTools::publishTrajectoryPath(const moveit_msgs::RobotTrajectory& trajectory_msg, bool blocking)
01881 {
01882 loadSharedRobotState();
01883
01884
01885 if (!trajectory_msg.joint_trajectory.points.size())
01886 {
01887 ROS_WARN_STREAM_NAMED("temp","Unable to publish trajectory path because trajectory has zero points");
01888 return false;
01889 }
01890
01891
01892 moveit_msgs::DisplayTrajectory display_trajectory_msg;
01893 display_trajectory_msg.model_id = robot_model_->getName();
01894
01895
01896 display_trajectory_msg.trajectory.resize(1);
01897 display_trajectory_msg.trajectory[0] = trajectory_msg;
01898
01899
01900 loadTrajectoryPub();
01901
01902 pub_display_path_.publish(display_trajectory_msg);
01903 ros::spinOnce();
01904
01905
01906 if( blocking )
01907 {
01908 ROS_INFO_STREAM_NAMED("visual_tools","Waiting for trajectory animation "
01909 << trajectory_msg.joint_trajectory.points.back().time_from_start << " seconds");
01910
01911
01912 double counter = 0;
01913 while (ros::ok() && counter < trajectory_msg.joint_trajectory.points.back().time_from_start.toSec())
01914 {
01915 counter += 0.25;
01916 ros::Duration(0.25).sleep();
01917 }
01918 }
01919
01920 return true;
01921 }
01922
01923 bool VisualTools::publishRobotState(const robot_state::RobotStatePtr &robot_state)
01924 {
01925 publishRobotState(*robot_state.get());
01926 }
01927
01928 bool VisualTools::publishRobotState(const robot_state::RobotState &robot_state)
01929 {
01930 robot_state::robotStateToRobotStateMsg(robot_state, display_robot_msg_.state);
01931
01932 loadRobotStatePub();
01933 pub_robot_state_.publish( display_robot_msg_ );
01934 ros::spinOnce();
01935
01936 return true;
01937 }
01938
01939 bool VisualTools::publishRobotState(const trajectory_msgs::JointTrajectoryPoint& trajectory_pt,
01940 const std::string &group_name)
01941 {
01942
01943 loadSharedRobotState();
01944
01945
01946 shared_robot_state_->setToDefaultValues();
01947 shared_robot_state_->setJointGroupPositions(group_name, trajectory_pt.positions);
01948
01949
01950 publishRobotState(*shared_robot_state_);
01951
01952 return true;
01953 }
01954
01955 bool VisualTools::hideRobot()
01956 {
01957
01958 loadSharedRobotState();
01959
01960 shared_robot_state_->setVariablePosition("virtual_joint/trans_x", 10);
01961 shared_robot_state_->setVariablePosition("virtual_joint/trans_y", 10);
01962 shared_robot_state_->setVariablePosition("virtual_joint/trans_z", 10);
01963
01964 publishRobotState(shared_robot_state_);
01965 }
01966
01967 bool VisualTools::publishTest()
01968 {
01969
01970 geometry_msgs::Pose pose;
01971 generateRandomPose(pose);
01972
01973
01974 ROS_INFO_STREAM_NAMED("test","Publishing Arrow");
01975 publishArrow(pose, moveit_visual_tools::RED, moveit_visual_tools::LARGE);
01976
01977 return true;
01978 }
01979
01980 geometry_msgs::Pose VisualTools::convertPose(const Eigen::Affine3d &pose)
01981 {
01982 geometry_msgs::Pose pose_msg;
01983 tf::poseEigenToMsg(pose, pose_msg);
01984 return pose_msg;
01985 }
01986
01987 Eigen::Affine3d VisualTools::convertPose(const geometry_msgs::Pose &pose)
01988 {
01989 Eigen::Affine3d pose_eigen;
01990 tf::poseMsgToEigen(pose, pose_eigen);
01991 return pose_eigen;
01992 }
01993
01994 Eigen::Affine3d VisualTools::convertPoint32ToPose(const geometry_msgs::Point32 &point)
01995 {
01996 Eigen::Affine3d pose_eigen = Eigen::Affine3d::Identity();
01997 pose_eigen.translation().x() = point.x;
01998 pose_eigen.translation().y() = point.y;
01999 pose_eigen.translation().z() = point.z;
02000 return pose_eigen;
02001 }
02002
02003 geometry_msgs::Pose VisualTools::convertPointToPose(const geometry_msgs::Point &point)
02004 {
02005 geometry_msgs::Pose pose_msg;
02006 pose_msg.position = point;
02007 return pose_msg;
02008 }
02009
02010 geometry_msgs::Point convertPoseToPoint(const Eigen::Affine3d &pose)
02011 {
02012 geometry_msgs::Pose pose_msg;
02013 tf::poseEigenToMsg(pose, pose_msg);
02014 return pose_msg.position;
02015 }
02016
02017 Eigen::Vector3d VisualTools::convertPoint(const geometry_msgs::Point &point)
02018 {
02019 Eigen::Vector3d point_eigen;
02020 point_eigen[0] = point.x;
02021 point_eigen[1] = point.y;
02022 point_eigen[2] = point.z;
02023 return point_eigen;
02024 }
02025
02026 Eigen::Vector3d VisualTools::convertPoint32(const geometry_msgs::Point32 &point)
02027 {
02028 Eigen::Vector3d point_eigen;
02029 point_eigen[0] = point.x;
02030 point_eigen[1] = point.y;
02031 point_eigen[2] = point.z;
02032 return point_eigen;
02033 }
02034
02035 geometry_msgs::Point32 VisualTools::convertPoint32(const Eigen::Vector3d &point)
02036 {
02037 geometry_msgs::Point32 point_msg;
02038 point_msg.x = point[0];
02039 point_msg.y = point[1];
02040 point_msg.z = point[2];
02041 return point_msg;
02042 }
02043
02044 void VisualTools::generateRandomPose(geometry_msgs::Pose& pose)
02045 {
02046
02047 pose.position.x = dRand(0, 1);
02048 pose.position.y = dRand(0, 1);
02049 pose.position.z = dRand(0, 1);
02050
02051
02052 double angle = M_PI * dRand(0.1,1.0);
02053 Eigen::Quaterniond quat(Eigen::AngleAxis<double>(double(angle), Eigen::Vector3d::UnitZ()));
02054 pose.orientation.x = quat.x();
02055 pose.orientation.y = quat.y();
02056 pose.orientation.z = quat.z();
02057 pose.orientation.w = quat.w();
02058 }
02059
02060 double VisualTools::dRand(double dMin, double dMax)
02061 {
02062 double d = (double)rand() / RAND_MAX;
02063 return dMin + d * (dMax - dMin);
02064 }
02065
02066 float VisualTools::fRand(float dMin, float dMax)
02067 {
02068 float d = (float)rand() / RAND_MAX;
02069 return dMin + d * (dMax - dMin);
02070 }
02071
02072 int VisualTools::iRand(int dMin, int dMax)
02073 {
02074 int d = (int)rand() / RAND_MAX;
02075 return dMin + d * (dMax - dMin);
02076 }
02077
02078 void VisualTools::print()
02079 {
02080 ROS_WARN_STREAM_NAMED("visual_tools","Debug Visual Tools variable values:");
02081 std::cout << "marker_topic_: " << marker_topic_ << std::endl;
02082 std::cout << "base_frame_: " << base_frame_ << std::endl;
02083 std::cout << "floor_to_base_height_: " << floor_to_base_height_ << std::endl;
02084 std::cout << "marker_lifetime_: " << marker_lifetime_.toSec() << std::endl;
02085 std::cout << "muted_: " << muted_ << std::endl;
02086 std::cout << "alpha_: " << alpha_ << std::endl;
02087 }
02088
02089 }
02090
02091
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121