moveit_visual_tools.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2015, University of Colorado, Boulder
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of the Univ of CO, Boulder nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *********************************************************************/
34 
35 // Author: Dave Coleman
36 // Desc: Simple tools for showing parts of a robot in Rviz, such as the gripper or arm
37 
39 
40 // MoveIt Messages
41 #include <moveit_msgs/CollisionObject.h>
42 
43 // MoveIt
47 
48 // Conversions
49 #include <tf2_eigen/tf2_eigen.h>
50 
51 // Transforms
53 
54 // Shape tools
57 
58 // C++
59 #include <string>
60 #include <algorithm>
61 #include <utility>
62 #include <vector>
63 #include <set>
64 #include <limits>
65 
66 namespace moveit_visual_tools
67 {
68 const std::string LOGNAME = "visual_tools";
69 
70 MoveItVisualTools::MoveItVisualTools(const std::string& base_frame, const std::string& marker_topic,
71  planning_scene_monitor::PlanningSceneMonitorPtr psm)
72  : RvizVisualTools::RvizVisualTools(base_frame, marker_topic)
73  , psm_(std::move(psm))
74  , robot_state_topic_(DISPLAY_ROBOT_STATE_TOPIC)
75  , planning_scene_topic_(PLANNING_SCENE_TOPIC)
76 {
77 }
78 
79 MoveItVisualTools::MoveItVisualTools(const std::string& base_frame, const std::string& marker_topic,
80  robot_model::RobotModelConstPtr robot_model)
81  : RvizVisualTools::RvizVisualTools(base_frame, marker_topic), robot_model_(std::move(robot_model))
82 {
83 }
84 
86 {
87  // Check if we already have one
88  if (psm_)
89  {
90  ROS_WARN_STREAM_NAMED(LOGNAME, "Will not load a new planning scene monitor when one has "
91  "already been set for Visual Tools");
92  return false;
93  }
94  ROS_DEBUG_STREAM_NAMED(LOGNAME, "Loading planning scene monitor");
95 
96  // Create tf transform buffer and listener
97  std::shared_ptr<tf2_ros::Buffer> tf_buffer = std::make_shared<tf2_ros::Buffer>();
98  std::shared_ptr<tf2_ros::TransformListener> tf_listener = std::make_shared<tf2_ros::TransformListener>(*tf_buffer);
99 
100  // Regular version b/c the other one causes problems with recognizing end effectors
101  psm_.reset(new planning_scene_monitor::PlanningSceneMonitor(ROBOT_DESCRIPTION, tf_buffer, "visual_tools_scene"));
102 
103  ros::spinOnce();
104  ros::Duration(0.1).sleep();
105  ros::spinOnce();
106 
107  if (psm_->getPlanningScene())
108  {
109  // Optional monitors to start:
110  // psm_->startWorldGeometryMonitor();
111  // psm_->startSceneMonitor("/move_group/monitored_planning_scene");
112  // psm_->startStateMonitor("/joint_states", "/attached_collision_object");
113 
116  ROS_DEBUG_STREAM_NAMED(LOGNAME, "Publishing planning scene on " << planning_scene_topic_);
117 
119  planning_scene->setName("visual_tools_scene");
120  }
121  else
122  {
123  ROS_ERROR_STREAM_NAMED(LOGNAME, "Planning scene not configured");
124  return false;
125  }
126 
127  return true;
128 }
129 
130 bool MoveItVisualTools::processCollisionObjectMsg(const moveit_msgs::CollisionObject& msg,
131  const rviz_visual_tools::colors& color)
132 {
133  // Apply command directly to planning scene to avoid a ROS msg call
134  {
136  scene->getCurrentStateNonConst().update(); // TODO: remove hack to prevent bad transforms
137  scene->processCollisionObjectMsg(msg);
138  scene->setObjectColor(msg.id, getColor(color));
139  }
140  // Trigger an update
142  {
144  }
145 
146  return true;
147 }
148 
149 bool MoveItVisualTools::processAttachedCollisionObjectMsg(const moveit_msgs::AttachedCollisionObject& msg)
150 {
151  // Apply command directly to planning scene to avoid a ROS msg call
152  {
154  // scene->getCurrentStateNonConst().update(); // hack to prevent bad transforms
155  scene->processAttachedCollisionObjectMsg(msg);
156  }
157 
158  // Trigger an update
160  {
162  }
163 
164  return true;
165 }
166 
167 bool MoveItVisualTools::moveCollisionObject(const Eigen::Isometry3d& pose, const std::string& name,
168  const rviz_visual_tools::colors& color)
169 {
170  return moveCollisionObject(convertPose(pose), name, color);
171 }
172 
173 bool MoveItVisualTools::moveCollisionObject(const geometry_msgs::Pose& pose, const std::string& name,
174  const rviz_visual_tools::colors& color)
175 {
176  moveit_msgs::CollisionObject collision_obj;
177  collision_obj.header.stamp = ros::Time::now();
178  collision_obj.header.frame_id = base_frame_;
179  collision_obj.id = name;
180  collision_obj.operation = moveit_msgs::CollisionObject::MOVE;
181 
182  collision_obj.primitive_poses.resize(1);
183  collision_obj.primitive_poses[0] = pose;
184 
185  // ROS_INFO_STREAM_NAMED(LOGNAME,"CollisionObject: \n " << collision_obj);
186  // ROS_DEBUG_STREAM_NAMED(LOGNAME,"Published collision object " << name);
187  return processCollisionObjectMsg(collision_obj, color);
188 }
189 
191 {
192  // TODO(davetcoleman): perhaps switch to using the service call?
194 
195  return true;
196 }
197 
199 {
200  // Get robot state
201  if (!shared_robot_state_)
202  {
203  // Check if a robot model was passed in
204  if (!robot_model_)
205  {
206  // Fall back on using planning scene monitor.
207  robot_model_ = getPlanningSceneMonitor()->getRobotModel();
208  }
209  shared_robot_state_.reset(new robot_state::RobotState(robot_model_));
210 
211  // TODO(davetcoleman): this seems to be a work around for a weird NaN bug
212  shared_robot_state_->setToDefaultValues();
213  shared_robot_state_->update(true);
214 
215  // hidden_robot_state_.reset(new robot_state::RobotState(robot_model_));
216  // hidden_robot_state_->setToDefaultValues();
217  // hidden_robot_state_->update(true);
218 
219  hidden_robot_state_.reset(new robot_state::RobotState(*shared_robot_state_));
220  root_robot_state_.reset(new robot_state::RobotState(*shared_robot_state_));
221  }
222 
223  return !(shared_robot_state_ == nullptr);
224 }
225 
226 moveit::core::RobotStatePtr& MoveItVisualTools::getSharedRobotState()
227 {
228  // Always load the robot state before using
230  return shared_robot_state_;
231 }
232 
233 moveit::core::RobotModelConstPtr MoveItVisualTools::getRobotModel()
234 {
235  // Always load the robot state before using
237  return shared_robot_state_->getRobotModel();
238 }
239 
240 bool MoveItVisualTools::loadEEMarker(const robot_model::JointModelGroup* ee_jmg,
241  const std::vector<double>& ee_joint_pos)
242 {
243  // Get joint state group
244  if (ee_jmg == nullptr) // make sure EE_GROUP exists
245  {
246  ROS_ERROR_STREAM_NAMED(LOGNAME, "Unable to find joint model group with address" << ee_jmg);
247  return false;
248  }
249 
250  // Always load the robot state before using
252  shared_robot_state_->setToDefaultValues();
253  shared_robot_state_->update();
254 
255  if (!ee_joint_pos.empty())
256  {
257  if (ee_joint_pos.size() != ee_jmg->getActiveJointModels().size())
258  {
259  ROS_ERROR_STREAM_NAMED(LOGNAME, "The number of joint positions given ("
260  << ee_joint_pos.size() << ") does not match the number of active joints in "
261  << ee_jmg->getName() << "(" << ee_jmg->getActiveJointModels().size() << ")");
262  return false;
263  }
264  shared_robot_state_->setJointGroupPositions(ee_jmg, ee_joint_pos);
265  shared_robot_state_->update(true);
266  }
267 
268  // Clear old EE markers and EE poses
269  ee_markers_map_[ee_jmg].markers.clear();
270  ee_poses_map_[ee_jmg].clear();
271 
272  // Remember joint state
273  ee_joint_pos_map_[ee_jmg] = ee_joint_pos;
274 
275  // Keep track of how many unique markers we have between different EEs
276  static std::size_t marker_id_offset = 0;
277 
278  // -----------------------------------------------------------------------------------------------
279  // Get end effector group
280 
281  // Create color to use for EE markers
282  std_msgs::ColorRGBA marker_color = getColor(rviz_visual_tools::GREY);
283 
284  // Get link names that are in end effector
285  const std::vector<std::string>& ee_link_names = ee_jmg->getLinkModelNames();
286 
287  // -----------------------------------------------------------------------------------------------
288  // Get EE link markers for Rviz
289 
290  shared_robot_state_->getRobotMarkers(ee_markers_map_[ee_jmg], ee_link_names, marker_color, ee_jmg->getName(),
291  ros::Duration());
292  ROS_DEBUG_STREAM_NAMED(LOGNAME, "Number of rviz markers in end effector: " << ee_markers_map_[ee_jmg].markers.size());
293 
294  const std::string& ee_parent_link_name = ee_jmg->getEndEffectorParentGroup().second;
295  // ROS_DEBUG_STREAM_NAMED(LOGNAME,"EE Parent link: " << ee_parent_link_name);
296  const moveit::core::LinkModel* ee_parent_link = robot_model_->getLinkModel(ee_parent_link_name);
297 
298  Eigen::Isometry3d ee_marker_global_transform = shared_robot_state_->getGlobalLinkTransform(ee_parent_link);
299  Eigen::Isometry3d ee_marker_pose;
300 
301  // Process each link of the end effector
302  for (std::size_t i = 0; i < ee_markers_map_[ee_jmg].markers.size(); ++i)
303  {
304  // Header
305  ee_markers_map_[ee_jmg].markers[i].header.frame_id = base_frame_;
306 
307  // Options for meshes
308  if (ee_markers_map_[ee_jmg].markers[i].type == visualization_msgs::Marker::MESH_RESOURCE)
309  {
310  ee_markers_map_[ee_jmg].markers[i].mesh_use_embedded_materials = true;
311  }
312 
313  // Unique id
314  ee_markers_map_[ee_jmg].markers[i].id += marker_id_offset;
315 
316  // Copy original marker poses to a vector
317  ee_marker_pose = ee_marker_global_transform.inverse() * convertPose(ee_markers_map_[ee_jmg].markers[i].pose);
318  ee_poses_map_[ee_jmg].push_back(ee_marker_pose);
319  }
320 
321  marker_id_offset += ee_markers_map_[ee_jmg].markers.size();
322 
323  return true;
324 }
325 
326 void MoveItVisualTools::loadTrajectoryPub(const std::string& display_planned_path_topic, bool blocking)
327 {
328  if (pub_display_path_)
329  return;
330 
331  // Trajectory paths
332  pub_display_path_ = nh_.advertise<moveit_msgs::DisplayTrajectory>(display_planned_path_topic, 10, false);
333  ROS_DEBUG_STREAM_NAMED(LOGNAME, "Publishing MoveIt trajectory on topic " << pub_display_path_.getTopic());
334 
335  // Wait for topic to be ready
336  if (blocking)
338 }
339 
340 void MoveItVisualTools::loadRobotStatePub(const std::string& robot_state_topic, bool blocking)
341 {
342  if (pub_robot_state_)
343  return;
344 
345  // Update global var if new topic was passed in
346  if (!robot_state_topic.empty())
347  robot_state_topic_ = robot_state_topic;
348 
349  // RobotState Message
350  pub_robot_state_ = nh_.advertise<moveit_msgs::DisplayRobotState>(robot_state_topic_, 1);
351  ROS_DEBUG_STREAM_NAMED(LOGNAME, "Publishing MoveIt robot state on topic " << pub_robot_state_.getTopic());
352 
353  // Wait for topic to be ready
354  if (blocking)
356 }
357 
358 bool MoveItVisualTools::publishEEMarkers(const geometry_msgs::Pose& pose, const robot_model::JointModelGroup* ee_jmg,
359  const std::vector<double>& ee_joint_pos,
360  const rviz_visual_tools::colors& color, const std::string& ns)
361 {
362  // Check if we have not loaded the EE markers
363  if (ee_markers_map_[ee_jmg].markers.empty() || ee_poses_map_[ee_jmg].empty() ||
364  ee_joint_pos_map_[ee_jmg] != ee_joint_pos)
365  {
366  if (!loadEEMarker(ee_jmg, ee_joint_pos))
367  {
368  ROS_ERROR_STREAM_NAMED(LOGNAME, "Unable to publish EE marker, unable to load EE markers");
369  return false;
370  }
371  }
372 
373  Eigen::Isometry3d eigen_goal_ee_pose = convertPose(pose);
374  Eigen::Isometry3d eigen_this_marker;
375 
376  // publishArrow( pose, rviz_visual_tools::RED, rviz_visual_tools::LARGE );
377 
378  // -----------------------------------------------------------------------------------------------
379  // Process each link of the end effector
380  for (std::size_t i = 0; i < ee_markers_map_[ee_jmg].markers.size(); ++i)
381  {
382  // Make sure ROS is still spinning
383  if (!ros::ok())
384  break;
385 
386  // Header
387  ee_markers_map_[ee_jmg].markers[i].header.stamp = ros::Time::now();
388 
389  // Namespace
390  ee_markers_map_[ee_jmg].markers[i].ns = ns;
391 
392  // Lifetime
393  ee_markers_map_[ee_jmg].markers[i].lifetime = marker_lifetime_;
394 
395  // Color
396  ee_markers_map_[ee_jmg].markers[i].color = getColor(color);
397 
398  // Convert pose
399  eigen_this_marker = eigen_goal_ee_pose * ee_poses_map_[ee_jmg][i];
400  ee_markers_map_[ee_jmg].markers[i].pose = convertPose(eigen_this_marker);
401  }
402 
403  // Helper for publishing rviz markers
404  return publishMarkers(ee_markers_map_[ee_jmg]);
405 }
406 
407 bool MoveItVisualTools::publishGrasps(const std::vector<moveit_msgs::Grasp>& possible_grasps,
408  const robot_model::JointModelGroup* ee_jmg, double animate_speed)
409 {
410  ROS_DEBUG_STREAM_NAMED(LOGNAME, "Visualizing " << possible_grasps.size() << " grasps with EE joint model group "
411  << ee_jmg->getName());
412 
413  // Loop through all grasps
414  for (std::size_t i = 0; i < possible_grasps.size(); ++i)
415  {
416  if (!ros::ok()) // Check that ROS is still ok and that user isn't trying to quit
417  break;
418 
419  publishEEMarkers(possible_grasps[i].grasp_pose.pose, ee_jmg);
420 
421  ros::Duration(animate_speed).sleep();
422  }
423 
424  return true;
425 }
426 
427 bool MoveItVisualTools::publishAnimatedGrasps(const std::vector<moveit_msgs::Grasp>& possible_grasps,
428  const robot_model::JointModelGroup* ee_jmg, double animate_speed)
429 {
430  ROS_DEBUG_STREAM_NAMED(LOGNAME, "Visualizing " << possible_grasps.size() << " grasps with joint model group "
431  << ee_jmg->getName() << " at speed " << animate_speed);
432 
433  // Loop through all grasps
434  for (std::size_t i = 0; i < possible_grasps.size(); ++i)
435  {
436  if (!ros::ok()) // Check that ROS is still ok and that user isn't trying to quit
437  break;
438 
439  publishAnimatedGrasp(possible_grasps[i], ee_jmg, animate_speed);
440  ros::Duration(animate_speed).sleep();
441  }
442 
443  return true;
444 }
445 
446 bool MoveItVisualTools::publishAnimatedGrasp(const moveit_msgs::Grasp& grasp,
447  const robot_model::JointModelGroup* ee_jmg, double animate_speed)
448 {
449  // Grasp Pose Variables
450  geometry_msgs::Pose grasp_pose = grasp.grasp_pose.pose;
451 
452 #if 0 // Debug
454  publishEEMarkers(grasp_pose, ee_jmg);
455  ros::Duration(0.5).sleep();
456 #endif
457 
458  Eigen::Isometry3d grasp_pose_eigen;
459  tf2::fromMsg(grasp_pose, grasp_pose_eigen);
460 
461  // Pre-grasp pose variables
462  geometry_msgs::Pose pre_grasp_pose;
463  Eigen::Isometry3d pre_grasp_pose_eigen;
464 
465  // Approach direction variables
466  Eigen::Vector3d pre_grasp_approach_direction_local;
467 
468  // Display Grasp Score
469  // std::string text = "Grasp Quality: " +
470  // boost::lexical_cast<std::string>(int(grasp.grasp_quality*100)) + "%";
471  // publishText(grasp_pose, text);
472 
473  // Convert the grasp pose into the frame of reference of the approach/retreat frame_id
474 
475  // Animate the movement - for ee approach direction
476  double animation_resulution = 0.1; // the lower the better the resolution
477  for (double percent = 0; percent < 1; percent += animation_resulution)
478  {
479  if (!ros::ok()) // Check that ROS is still ok and that user isn't trying to quit
480  break;
481 
482  // Copy original grasp pose to pre-grasp pose
483  pre_grasp_pose_eigen = grasp_pose_eigen;
484 
485  // The direction of the pre-grasp
486  // Calculate the current animation position based on the percent
487  Eigen::Vector3d pre_grasp_approach_direction = Eigen::Vector3d(
488  -1 * grasp.pre_grasp_approach.direction.vector.x * grasp.pre_grasp_approach.min_distance * (1 - percent),
489  -1 * grasp.pre_grasp_approach.direction.vector.y * grasp.pre_grasp_approach.min_distance * (1 - percent),
490  -1 * grasp.pre_grasp_approach.direction.vector.z * grasp.pre_grasp_approach.min_distance * (1 - percent));
491 
492  // Decide if we need to change the approach_direction to the local frame of the end effector
493  // orientation
494  const std::string& ee_parent_link_name = ee_jmg->getEndEffectorParentGroup().second;
495 
496  if (grasp.pre_grasp_approach.direction.header.frame_id == ee_parent_link_name)
497  {
498  // Apply/compute the approach_direction vector in the local frame of the grasp_pose
499  // orientation
500  pre_grasp_approach_direction_local = grasp_pose_eigen.rotation() * pre_grasp_approach_direction;
501  }
502  else
503  {
504  pre_grasp_approach_direction_local = pre_grasp_approach_direction; // grasp_pose_eigen.rotation() *
505  // pre_grasp_approach_direction;
506  }
507 
508  // Update the grasp pose usign the new locally-framed approach_direction
509  pre_grasp_pose_eigen.translation() += pre_grasp_approach_direction_local;
510 
511  // Convert eigen pre-grasp position back to regular message
512  pre_grasp_pose = tf2::toMsg(pre_grasp_pose_eigen);
513 
514  // publishArrow(pre_grasp_pose, moveit_visual_tools::BLUE);
515  publishEEMarkers(pre_grasp_pose, ee_jmg);
517  trigger();
518  ros::Duration(animate_speed).sleep();
519 
520  // Pause more at initial pose for debugging purposes
521  if (percent == 0)
522  ros::Duration(animate_speed * 2).sleep();
523  }
524  return true;
525 }
526 
527 bool MoveItVisualTools::publishIKSolutions(const std::vector<trajectory_msgs::JointTrajectoryPoint>& ik_solutions,
528  const robot_model::JointModelGroup* arm_jmg, double display_time)
529 {
530  if (ik_solutions.empty())
531  {
532  ROS_WARN_STREAM_NAMED(LOGNAME, "Empty ik_solutions vector passed into publishIKSolutions()");
533  return false;
534  }
535 
537 
538  ROS_DEBUG_STREAM_NAMED(LOGNAME, "Visualizing " << ik_solutions.size() << " inverse kinematic solutions");
539 
540  // Apply the time to the trajectory
541  trajectory_msgs::JointTrajectoryPoint trajectory_pt_timed;
542 
543  // Create a trajectory with one point
544  moveit_msgs::RobotTrajectory trajectory_msg;
545  trajectory_msg.joint_trajectory.header.frame_id = base_frame_;
546  trajectory_msg.joint_trajectory.joint_names = arm_jmg->getActiveJointModelNames();
547 
548  // Overall length of trajectory
549  double running_time = 0;
550 
551  // Loop through all inverse kinematic solutions
552  for (std::size_t i = 0; i < ik_solutions.size(); ++i)
553  {
554  trajectory_pt_timed = ik_solutions[i];
555  trajectory_pt_timed.time_from_start = ros::Duration(running_time);
556  trajectory_msg.joint_trajectory.points.push_back(trajectory_pt_timed);
557 
558  running_time += display_time;
559  }
560 
561  // Re-add final position so the last point is displayed fully
562  trajectory_pt_timed = trajectory_msg.joint_trajectory.points.back();
563  trajectory_pt_timed.time_from_start = ros::Duration(running_time);
564  trajectory_msg.joint_trajectory.points.push_back(trajectory_pt_timed);
565 
566  return publishTrajectoryPath(trajectory_msg, shared_robot_state_, true);
567 }
568 
570 {
571  // Apply command directly to planning scene to avoid a ROS msg call
572  {
574  scene->removeAllCollisionObjects();
575  }
576 
577  return true;
578 }
579 
580 bool MoveItVisualTools::cleanupCO(const std::string& name)
581 {
582  // Clean up old collision objects
583  moveit_msgs::CollisionObject co;
584  co.header.stamp = ros::Time::now();
585  co.header.frame_id = base_frame_;
586  co.id = name;
587  co.operation = moveit_msgs::CollisionObject::REMOVE;
588 
589  return processCollisionObjectMsg(co);
590 }
591 
592 bool MoveItVisualTools::cleanupACO(const std::string& name)
593 {
594  // Clean up old attached collision object
595  moveit_msgs::AttachedCollisionObject aco;
596  aco.object.header.stamp = ros::Time::now();
597  aco.object.header.frame_id = base_frame_;
598 
599  // aco.object.id = name;
600  aco.object.operation = moveit_msgs::CollisionObject::REMOVE;
601 
603 }
604 
605 bool MoveItVisualTools::attachCO(const std::string& name, const std::string& ee_parent_link)
606 {
607  // Attach a collision object
608  moveit_msgs::AttachedCollisionObject aco;
609  aco.object.header.stamp = ros::Time::now();
610  aco.object.header.frame_id = base_frame_;
611 
612  aco.object.id = name;
613  aco.object.operation = moveit_msgs::CollisionObject::ADD;
614 
615  // Link to attach the object to
616  aco.link_name = ee_parent_link;
617 
619 }
620 
621 bool MoveItVisualTools::publishCollisionBlock(const geometry_msgs::Pose& block_pose, const std::string& name,
622  double block_size, const rviz_visual_tools::colors& color)
623 {
624  moveit_msgs::CollisionObject collision_obj;
625  collision_obj.header.stamp = ros::Time::now();
626  collision_obj.header.frame_id = base_frame_;
627  collision_obj.id = name;
628  collision_obj.operation = moveit_msgs::CollisionObject::ADD;
629 
630  collision_obj.primitives.resize(1);
631  collision_obj.primitives[0].type = shape_msgs::SolidPrimitive::BOX;
632  collision_obj.primitives[0].dimensions.resize(
634  collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_X] = block_size;
635  collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_Y] = block_size;
636  collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_Z] = block_size;
637  collision_obj.primitive_poses.resize(1);
638  collision_obj.primitive_poses[0] = block_pose;
639 
640  // ROS_INFO_STREAM_NAMED(LOGNAME,"CollisionObject: \n " << collision_obj);
641  // ROS_DEBUG_STREAM_NAMED(LOGNAME,"Published collision object " << name);
642  return processCollisionObjectMsg(collision_obj, color);
643 }
644 
645 bool MoveItVisualTools::publishCollisionCuboid(const Eigen::Vector3d& point1, const Eigen::Vector3d& point2,
646  const std::string& name, const rviz_visual_tools::colors& color)
647 {
648  return publishCollisionCuboid(convertPoint(point1), convertPoint(point2), name, color);
649 }
650 
651 bool MoveItVisualTools::publishCollisionCuboid(const geometry_msgs::Point& point1, const geometry_msgs::Point& point2,
652  const std::string& name, const rviz_visual_tools::colors& color)
653 {
654  moveit_msgs::CollisionObject collision_obj;
655  collision_obj.header.stamp = ros::Time::now();
656  collision_obj.header.frame_id = base_frame_;
657  collision_obj.id = name;
658  collision_obj.operation = moveit_msgs::CollisionObject::ADD;
659 
660  // Calculate center pose
661  collision_obj.primitive_poses.resize(1);
662  collision_obj.primitive_poses[0].position.x = (point1.x - point2.x) / 2.0 + point2.x;
663  collision_obj.primitive_poses[0].position.y = (point1.y - point2.y) / 2.0 + point2.y;
664  collision_obj.primitive_poses[0].position.z = (point1.z - point2.z) / 2.0 + point2.z;
665 
666  // Calculate scale
667  collision_obj.primitives.resize(1);
668  collision_obj.primitives[0].type = shape_msgs::SolidPrimitive::BOX;
669  collision_obj.primitives[0].dimensions.resize(
671  collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_X] = fabs(point1.x - point2.x);
672  collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_Y] = fabs(point1.y - point2.y);
673  collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_Z] = fabs(point1.z - point2.z);
674 
675  // Prevent scale from being zero
676  if (!collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_X])
677  collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_X] = rviz_visual_tools::SMALL_SCALE;
678  if (!collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_Y])
679  collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_Y] = rviz_visual_tools::SMALL_SCALE;
680  if (!collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_Z])
681  collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_Z] = rviz_visual_tools::SMALL_SCALE;
682 
683  // ROS_INFO_STREAM_NAMED(LOGNAME,"CollisionObject: \n " << collision_obj);
684  return processCollisionObjectMsg(collision_obj, color);
685 }
686 
687 bool MoveItVisualTools::publishCollisionCuboid(const Eigen::Isometry3d& pose, double width, double depth, double height,
688  const std::string& name, const rviz_visual_tools::colors& color)
689 {
690  geometry_msgs::Pose pose_msg = tf2::toMsg(pose);
691  return publishCollisionCuboid(pose_msg, width, depth, height, name, color);
692 }
693 
694 bool MoveItVisualTools::publishCollisionCuboid(const geometry_msgs::Pose& pose, double width, double depth,
695  double height, const std::string& name,
696  const rviz_visual_tools::colors& color)
697 {
698  moveit_msgs::CollisionObject collision_obj;
699  collision_obj.header.stamp = ros::Time::now();
700  collision_obj.header.frame_id = base_frame_;
701  collision_obj.id = name;
702  collision_obj.operation = moveit_msgs::CollisionObject::ADD;
703 
704  // Calculate center pose
705  collision_obj.primitive_poses.resize(1);
706  collision_obj.primitive_poses[0] = pose;
707 
708  // Calculate scale
709  collision_obj.primitives.resize(1);
710  collision_obj.primitives[0].type = shape_msgs::SolidPrimitive::BOX;
711  collision_obj.primitives[0].dimensions.resize(
713  collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_X] = width;
714  collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_Y] = depth;
715  collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_Z] = height;
716 
717  // Prevent scale from being zero
718  if (!collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_X])
719  collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_X] = rviz_visual_tools::SMALL_SCALE;
720  if (!collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_Y])
721  collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_Y] = rviz_visual_tools::SMALL_SCALE;
722  if (!collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_Z])
723  collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_Z] = rviz_visual_tools::SMALL_SCALE;
724 
725  return processCollisionObjectMsg(collision_obj, color);
726 }
727 
728 bool MoveItVisualTools::publishCollisionFloor(double z, const std::string& plane_name,
729  const rviz_visual_tools::colors& color)
730 {
731  // Instead just generate a rectangle
732  geometry_msgs::Point point1;
733  geometry_msgs::Point point2;
734 
737  point1.z = z;
738 
739  point2.x = -rviz_visual_tools::LARGE_SCALE;
740  point2.y = -rviz_visual_tools::LARGE_SCALE;
741  point2.z = z - rviz_visual_tools::SMALL_SCALE;
742 
743  return publishCollisionCuboid(point1, point2, plane_name, color);
744 }
745 
746 bool MoveItVisualTools::publishCollisionCylinder(const geometry_msgs::Point& a, const geometry_msgs::Point& b,
747  const std::string& object_name, double radius,
748  const rviz_visual_tools::colors& color)
749 {
750  return publishCollisionCylinder(convertPoint(a), convertPoint(b), object_name, radius, color);
751 }
752 
753 bool MoveItVisualTools::publishCollisionCylinder(const Eigen::Vector3d& a, const Eigen::Vector3d& b,
754  const std::string& object_name, double radius,
755  const rviz_visual_tools::colors& color)
756 {
757  // Distance between two points
758  double height = (a - b).lpNorm<2>();
759 
760  // Find center point
761  Eigen::Vector3d pt_center = getCenterPoint(a, b);
762 
763  // Create vector
764  Eigen::Isometry3d pose;
765  pose = getVectorBetweenPoints(pt_center, b);
766 
767  // Convert pose to be normal to cylindar axis
768  Eigen::Isometry3d rotation;
769  rotation = Eigen::AngleAxisd(0.5 * M_PI, Eigen::Vector3d::UnitY());
770  pose = pose * rotation;
771 
772  return publishCollisionCylinder(pose, object_name, radius, height, color);
773 }
774 
775 bool MoveItVisualTools::publishCollisionCylinder(const Eigen::Isometry3d& object_pose, const std::string& object_name,
776  double radius, double height, const rviz_visual_tools::colors& color)
777 {
778  return publishCollisionCylinder(convertPose(object_pose), object_name, radius, height, color);
779 }
780 
781 bool MoveItVisualTools::publishCollisionCylinder(const geometry_msgs::Pose& object_pose, const std::string& object_name,
782  double radius, double height, const rviz_visual_tools::colors& color)
783 {
784  moveit_msgs::CollisionObject collision_obj;
785  collision_obj.header.stamp = ros::Time::now();
786  collision_obj.header.frame_id = base_frame_;
787  collision_obj.id = object_name;
788  collision_obj.operation = moveit_msgs::CollisionObject::ADD;
789  collision_obj.primitives.resize(1);
790  collision_obj.primitives[0].type = shape_msgs::SolidPrimitive::CYLINDER;
791  collision_obj.primitives[0].dimensions.resize(
793  collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::CYLINDER_HEIGHT] = height;
794  collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::CYLINDER_RADIUS] = radius;
795  collision_obj.primitive_poses.resize(1);
796  collision_obj.primitive_poses[0] = object_pose;
797 
798  // ROS_INFO_STREAM_NAMED(LOGNAME,"CollisionObject: \n " << collision_obj);
799  return processCollisionObjectMsg(collision_obj, color);
800 }
801 
802 bool MoveItVisualTools::publishCollisionMesh(const Eigen::Isometry3d& object_pose, const std::string& object_name,
803  const std::string& mesh_path, const rviz_visual_tools::colors& color)
804 {
805  return publishCollisionMesh(convertPose(object_pose), object_name, mesh_path, color);
806 }
807 
808 bool MoveItVisualTools::publishCollisionMesh(const geometry_msgs::Pose& object_pose, const std::string& object_name,
809  const std::string& mesh_path, const rviz_visual_tools::colors& color)
810 {
811  shapes::Shape* mesh = shapes::createMeshFromResource(mesh_path); // make sure its prepended by file://
812  shapes::ShapeMsg shape_msg; // this is a boost::variant type from shape_messages.h
813  if (!mesh || !shapes::constructMsgFromShape(mesh, shape_msg))
814  {
815  ROS_ERROR_STREAM_NAMED(LOGNAME, "Unable to create mesh shape message from resource " << mesh_path);
816  return false;
817  }
818 
819  if (!publishCollisionMesh(object_pose, object_name, boost::get<shape_msgs::Mesh>(shape_msg), color))
820  return false;
821 
822  ROS_DEBUG_NAMED(LOGNAME, "Loaded mesh from '%s'", mesh_path.c_str());
823  return true;
824 }
825 
826 bool MoveItVisualTools::publishCollisionMesh(const Eigen::Isometry3d& object_pose, const std::string& object_name,
827  const shape_msgs::Mesh& mesh_msg, const rviz_visual_tools::colors& color)
828 {
829  return publishCollisionMesh(convertPose(object_pose), object_name, mesh_msg, color);
830 }
831 
832 bool MoveItVisualTools::publishCollisionMesh(const geometry_msgs::Pose& object_pose, const std::string& object_name,
833  const shape_msgs::Mesh& mesh_msg, const rviz_visual_tools::colors& color)
834 {
835  // Create collision message
836  moveit_msgs::CollisionObject collision_obj;
837  collision_obj.header.stamp = ros::Time::now();
838  collision_obj.header.frame_id = base_frame_;
839  collision_obj.id = object_name;
840  collision_obj.operation = moveit_msgs::CollisionObject::ADD;
841  collision_obj.mesh_poses.resize(1);
842  collision_obj.mesh_poses[0] = object_pose;
843  collision_obj.meshes.resize(1);
844  collision_obj.meshes[0] = mesh_msg;
845 
846  return processCollisionObjectMsg(collision_obj, color);
847 }
848 
849 bool MoveItVisualTools::publishCollisionGraph(const graph_msgs::GeometryGraph& graph, const std::string& object_name,
850  double radius, const rviz_visual_tools::colors& color)
851 {
852  ROS_INFO_STREAM_NAMED("publishCollisionGraph", "Preparing to create collision graph");
853 
854  // The graph is one collision object with many primitives
855  moveit_msgs::CollisionObject collision_obj;
856  collision_obj.header.stamp = ros::Time::now();
857  collision_obj.header.frame_id = base_frame_;
858  collision_obj.id = object_name;
859  collision_obj.operation = moveit_msgs::CollisionObject::ADD;
860 
861  // Track which pairs of nodes we've already connected since graph is bi-directional
862  typedef std::pair<std::size_t, std::size_t> node_ids;
863  std::set<node_ids> added_edges;
864  std::pair<std::set<node_ids>::iterator, bool> return_value;
865 
866  Eigen::Vector3d a, b;
867  for (std::size_t i = 0; i < graph.nodes.size(); ++i)
868  {
869  for (std::size_t j = 0; j < graph.edges[i].node_ids.size(); ++j)
870  {
871  // Check if we've already added this pair of nodes (edge)
872  return_value = added_edges.insert(node_ids(i, j));
873  if (!return_value.second)
874  {
875  // Element already existed in set, so don't add a new collision object
876  }
877  else
878  {
879  // Create a cylinder from two points
880  a = convertPoint(graph.nodes[i]);
881  b = convertPoint(graph.nodes[graph.edges[i].node_ids[j]]);
882 
883  // add other direction of edge
884  added_edges.insert(node_ids(j, i));
885 
886  // Distance between two points
887  double height = (a - b).lpNorm<2>();
888 
889  // Find center point
890  Eigen::Vector3d pt_center = getCenterPoint(a, b);
891 
892  // Create vector
893  Eigen::Isometry3d pose;
894  pose = getVectorBetweenPoints(pt_center, b);
895 
896  // Convert pose to be normal to cylindar axis
897  Eigen::Isometry3d rotation;
898  rotation = Eigen::AngleAxisd(0.5 * M_PI, Eigen::Vector3d::UnitY());
899  pose = pose * rotation;
900 
901  // Create the solid primitive
902  shape_msgs::SolidPrimitive cylinder;
903  cylinder.type = shape_msgs::SolidPrimitive::CYLINDER;
904  cylinder.dimensions.resize(
906  cylinder.dimensions[shape_msgs::SolidPrimitive::CYLINDER_HEIGHT] = height;
907  cylinder.dimensions[shape_msgs::SolidPrimitive::CYLINDER_RADIUS] = radius;
908 
909  // Add to the collision object
910  collision_obj.primitives.push_back(cylinder);
911 
912  // Add the pose
913  collision_obj.primitive_poses.push_back(convertPose(pose));
914  }
915  }
916  }
917 
918  return processCollisionObjectMsg(collision_obj, color);
919 }
920 
921 void MoveItVisualTools::getCollisionWallMsg(double x, double y, double z, double angle, double width, double height,
922  const std::string& name, moveit_msgs::CollisionObject& collision_obj)
923 {
924  collision_obj.header.stamp = ros::Time::now();
925  collision_obj.header.frame_id = base_frame_;
926  collision_obj.operation = moveit_msgs::CollisionObject::ADD;
927  collision_obj.primitives.resize(1);
928  collision_obj.primitives[0].type = shape_msgs::SolidPrimitive::BOX;
929  collision_obj.primitives[0].dimensions.resize(
931 
932  geometry_msgs::Pose rec_pose;
933 
934  // ----------------------------------------------------------------------------------
935  // Name
936  collision_obj.id = name;
937 
938  double depth = 0.1;
939 
940  // Position
941  rec_pose.position.x = x;
942  rec_pose.position.y = y;
943  rec_pose.position.z = height / 2 + z;
944 
945  // Size
946  collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_X] = depth;
947  collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_Y] = width;
948  collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_Z] = height;
949  // ----------------------------------------------------------------------------------
950 
951  Eigen::Quaterniond quat(Eigen::AngleAxis<double>(static_cast<double>(angle), Eigen::Vector3d::UnitZ()));
952  rec_pose.orientation.x = quat.x();
953  rec_pose.orientation.y = quat.y();
954  rec_pose.orientation.z = quat.z();
955  rec_pose.orientation.w = quat.w();
956 
957  collision_obj.primitive_poses.resize(1);
958  collision_obj.primitive_poses[0] = rec_pose;
959 }
960 
961 bool MoveItVisualTools::publishCollisionWall(double x, double y, double angle, double width, double height,
962  const std::string& name, const rviz_visual_tools::colors& color)
963 {
964  return publishCollisionWall(x, y, 0.0, angle, width, height, name, color);
965 }
966 
967 bool MoveItVisualTools::publishCollisionWall(double x, double y, double z, double angle, double width, double height,
968  const std::string& name, const rviz_visual_tools::colors& color)
969 {
970  moveit_msgs::CollisionObject collision_obj;
971  getCollisionWallMsg(x, y, z, angle, width, height, name, collision_obj);
972 
973  return processCollisionObjectMsg(collision_obj, color);
974 }
975 
976 bool MoveItVisualTools::publishCollisionTable(double x, double y, double z, double angle, double width, double height,
977  double depth, const std::string& name,
978  const rviz_visual_tools::colors& color)
979 {
980  geometry_msgs::Pose table_pose;
981 
982  // Center of table
983  table_pose.position.x = x;
984  table_pose.position.y = y;
985  table_pose.position.z = z + height / 2.0;
986 
987  // Orientation
988  Eigen::Quaterniond quat(Eigen::AngleAxis<double>(static_cast<double>(angle), Eigen::Vector3d::UnitZ()));
989  table_pose.orientation.x = quat.x();
990  table_pose.orientation.y = quat.y();
991  table_pose.orientation.z = quat.z();
992  table_pose.orientation.w = quat.w();
993 
994  moveit_msgs::CollisionObject collision_obj;
995  collision_obj.header.stamp = ros::Time::now();
996  collision_obj.header.frame_id = base_frame_;
997  collision_obj.id = name;
998  collision_obj.operation = moveit_msgs::CollisionObject::ADD;
999  collision_obj.primitives.resize(1);
1000  collision_obj.primitives[0].type = shape_msgs::SolidPrimitive::BOX;
1001  collision_obj.primitives[0].dimensions.resize(
1003 
1004  // Size
1005  collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_X] = depth;
1006  collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_Y] = width;
1007  collision_obj.primitives[0].dimensions[shape_msgs::SolidPrimitive::BOX_Z] = height;
1008 
1009  collision_obj.primitive_poses.resize(1);
1010  collision_obj.primitive_poses[0] = table_pose;
1011  return processCollisionObjectMsg(collision_obj, color);
1012 }
1013 
1015 {
1016  return loadCollisionSceneFromFile(path, Eigen::Isometry3d::Identity());
1017 }
1018 
1019 bool MoveItVisualTools::loadCollisionSceneFromFile(const std::string& path, const Eigen::Isometry3d& offset)
1020 {
1021  // Open file
1022  std::ifstream fin(path.c_str());
1023  if (fin.good())
1024  {
1025  // Load directly to the planning scene
1027  {
1028  if (scene)
1029  {
1030  scene->loadGeometryFromStream(fin, offset);
1031  }
1032  else
1033  {
1034  ROS_WARN_STREAM_NAMED(LOGNAME, "Unable to get locked planning scene RW");
1035  return false;
1036  }
1037  }
1038  ROS_INFO_NAMED(LOGNAME, "Loaded scene geometry from '%s'", path.c_str());
1039  }
1040  else
1041  ROS_WARN_NAMED(LOGNAME, "Unable to load scene geometry from '%s'", path.c_str());
1042 
1043  fin.close();
1044 
1045  return triggerPlanningSceneUpdate();
1046 }
1047 
1048 bool MoveItVisualTools::publishWorkspaceParameters(const moveit_msgs::WorkspaceParameters& params)
1049 {
1050  return publishCuboid(convertPoint(params.min_corner), convertPoint(params.max_corner), rviz_visual_tools::TRANSLUCENT,
1051  "Planning_Workspace", 1);
1052 }
1053 
1056  const rviz_visual_tools::colors& highlight_link_color,
1057  const rviz_visual_tools::colors& contact_point_color)
1058 {
1059  // Compute the contacts if any
1062  c_req.contacts = true;
1063  c_req.max_contacts = 10;
1064  c_req.max_contacts_per_pair = 3;
1065  c_req.verbose = true;
1066 
1067  // Check for collisions
1068  planning_scene->checkCollision(c_req, c_res, robot_state);
1069  std::vector<std::string> highlight_links;
1070  for (const auto& contact : c_res.contacts)
1071  {
1072  highlight_links.push_back(contact.first.first);
1073  highlight_links.push_back(contact.first.second);
1074  }
1075 
1076  publishRobotState(robot_state, highlight_link_color, highlight_links);
1077  publishContactPoints(c_res.contacts, planning_scene, contact_point_color);
1078  return c_res.collision;
1079 }
1080 
1083  const rviz_visual_tools::colors& color)
1084 {
1085  // Compute the contacts if any
1088  c_req.contacts = true;
1089  c_req.max_contacts = 10;
1090  c_req.max_contacts_per_pair = 3;
1091  c_req.verbose = true;
1092 
1093  // Check for collisions
1094  planning_scene->checkCollision(c_req, c_res, robot_state);
1095  return publishContactPoints(c_res.contacts, planning_scene, color);
1096 }
1097 
1100  const rviz_visual_tools::colors& color)
1101 {
1102  // Display
1103  if (!contacts.empty())
1104  {
1105  visualization_msgs::MarkerArray arr;
1107  ROS_INFO_STREAM_NAMED(LOGNAME, "Completed listing of explanations for invalid states.");
1108 
1109  // Check for markers
1110  if (arr.markers.empty())
1111  return true;
1112 
1113  // Convert markers to same namespace and other custom stuff
1114  for (std::size_t i = 0; i < arr.markers.size(); ++i)
1115  {
1116  arr.markers[i].ns = "Collision";
1117  arr.markers[i].id = i;
1118  arr.markers[i].scale.x = 0.04;
1119  arr.markers[i].scale.y = 0.04;
1120  arr.markers[i].scale.z = 0.04;
1121  arr.markers[i].color = getColor(color);
1122  }
1123 
1124  return publishMarkers(arr);
1125  }
1126  return true;
1127 }
1128 
1129 bool MoveItVisualTools::publishTrajectoryPoint(const trajectory_msgs::JointTrajectoryPoint& trajectory_pt,
1130  const std::string& planning_group, double display_time)
1131 {
1132  // Get joint state group
1133  const robot_model::JointModelGroup* jmg = robot_model_->getJointModelGroup(planning_group);
1134 
1135  if (jmg == nullptr) // not found
1136  {
1137  ROS_ERROR_STREAM_NAMED("publishTrajectoryPoint", "Could not find joint model group " << planning_group);
1138  return false;
1139  }
1140 
1141  // Apply the time to the trajectory
1142  trajectory_msgs::JointTrajectoryPoint trajectory_pt_timed = trajectory_pt;
1143  trajectory_pt_timed.time_from_start = ros::Duration(display_time);
1144 
1145  // Create a trajectory with one point
1146  moveit_msgs::RobotTrajectory trajectory_msg;
1147  trajectory_msg.joint_trajectory.header.frame_id = base_frame_;
1148  trajectory_msg.joint_trajectory.joint_names = jmg->getJointModelNames();
1149  trajectory_msg.joint_trajectory.points.push_back(trajectory_pt);
1150  trajectory_msg.joint_trajectory.points.push_back(trajectory_pt_timed);
1151 
1152  return publishTrajectoryPath(trajectory_msg, shared_robot_state_, true);
1153 }
1154 
1155 bool MoveItVisualTools::publishTrajectoryPath(const std::vector<robot_state::RobotStatePtr>& trajectory,
1156  const moveit::core::JointModelGroup* jmg, double speed, bool blocking)
1157 {
1158  // Copy the vector of RobotStates to a RobotTrajectory
1159  robot_trajectory::RobotTrajectoryPtr robot_trajectory(
1161 
1162  double duration_from_previous = 0;
1163  for (std::size_t k = 0; k < trajectory.size(); ++k)
1164  {
1165  duration_from_previous += speed;
1166  robot_trajectory->addSuffixWayPoint(trajectory[k], duration_from_previous);
1167  }
1168 
1169  // Convert trajectory to a message
1170  moveit_msgs::RobotTrajectory trajectory_msg;
1171  robot_trajectory->getRobotTrajectoryMsg(trajectory_msg);
1172 
1173  // Use first trajectory point as reference state
1174  moveit_msgs::RobotState robot_state_msg;
1175  if (!trajectory.empty())
1176  robot_state::robotStateToRobotStateMsg(*trajectory[0], robot_state_msg);
1177 
1178  return publishTrajectoryPath(trajectory_msg, robot_state_msg, blocking);
1179 }
1180 
1181 bool MoveItVisualTools::publishTrajectoryPath(const robot_trajectory::RobotTrajectoryPtr& trajectory, bool blocking)
1182 {
1183  return publishTrajectoryPath(*trajectory, blocking);
1184 }
1185 
1187 {
1188  moveit_msgs::RobotTrajectory trajectory_msg;
1189  trajectory.getRobotTrajectoryMsg(trajectory_msg);
1190 
1191  // Add time from start if none specified
1192  if (trajectory_msg.joint_trajectory.points.size() > 1)
1193  {
1194  if (trajectory_msg.joint_trajectory.points[1].time_from_start == ros::Duration(0)) // assume no timestamps exist
1195  {
1196  for (std::size_t i = 0; i < trajectory_msg.joint_trajectory.points.size(); ++i)
1197  {
1198  trajectory_msg.joint_trajectory.points[i].time_from_start = ros::Duration(i * 2); // 1 hz
1199  }
1200  }
1201  }
1202 
1203  // Use first trajectory point as reference state
1204  moveit_msgs::RobotState robot_state_msg;
1205  if (!trajectory.empty())
1206  robot_state::robotStateToRobotStateMsg(trajectory.getFirstWayPoint(), robot_state_msg);
1207 
1208  return publishTrajectoryPath(trajectory_msg, robot_state_msg, blocking);
1209 }
1210 
1211 bool MoveItVisualTools::publishTrajectoryPath(const moveit_msgs::RobotTrajectory& trajectory_msg,
1212  const robot_state::RobotStateConstPtr& robot_state, bool blocking)
1213 {
1214  return publishTrajectoryPath(trajectory_msg, *robot_state, blocking);
1215 }
1216 
1217 bool MoveItVisualTools::publishTrajectoryPath(const moveit_msgs::RobotTrajectory& trajectory_msg,
1218  const moveit::core::RobotState& robot_state, bool blocking)
1219 {
1220  // Convert the robot state to a ROS message
1221  moveit_msgs::RobotState robot_state_msg;
1222  robot_state::robotStateToRobotStateMsg(robot_state, robot_state_msg);
1223  return publishTrajectoryPath(trajectory_msg, robot_state_msg, blocking);
1224 }
1225 
1226 bool MoveItVisualTools::publishTrajectoryPath(const moveit_msgs::RobotTrajectory& trajectory_msg,
1227  const moveit_msgs::RobotState& robot_state, bool blocking)
1228 {
1229  // Check if we have enough points
1230  if (trajectory_msg.joint_trajectory.points.empty())
1231  {
1232  ROS_WARN_STREAM_NAMED(LOGNAME, "Unable to publish trajectory path because trajectory has zero points");
1233  return false;
1234  }
1235 
1236  // Create the message
1237  moveit_msgs::DisplayTrajectory display_trajectory_msg;
1238  display_trajectory_msg.model_id = robot_model_->getName();
1239  display_trajectory_msg.trajectory.resize(1);
1240  display_trajectory_msg.trajectory[0] = trajectory_msg;
1241  display_trajectory_msg.trajectory_start = robot_state;
1242 
1243  publishTrajectoryPath(display_trajectory_msg);
1244 
1245  // Wait the duration of the trajectory
1246  if (blocking)
1247  {
1248  double duration = trajectory_msg.joint_trajectory.points.back().time_from_start.toSec();
1249 
1250  // If trajectory has not been parameterized, assume each waypoint takes 0.05 seconds (based on Rviz)
1251  if (duration < std::numeric_limits<double>::epsilon())
1252  {
1253  duration = 0.05 * trajectory_msg.joint_trajectory.points.size();
1254  }
1255  ROS_DEBUG_STREAM_NAMED(LOGNAME, "Waiting for trajectory animation " << duration << " seconds");
1256 
1257  // Check if ROS is ok in intervals
1258  double counter = 0;
1259  static const double CHECK_TIME_INTERVAL = 0.25; // check every fourth second
1260  while (ros::ok() && counter <= duration)
1261  {
1262  counter += CHECK_TIME_INTERVAL;
1263  ros::Duration(CHECK_TIME_INTERVAL).sleep();
1264  }
1265  }
1266 
1267  return true;
1268 }
1269 
1270 void MoveItVisualTools::publishTrajectoryPath(const moveit_msgs::DisplayTrajectory& display_trajectory_msg)
1271 {
1272  // Publish message
1273  loadTrajectoryPub(); // always call this before publishing
1274  pub_display_path_.publish(display_trajectory_msg);
1275  ros::spinOnce();
1276 }
1277 
1278 bool MoveItVisualTools::publishTrajectoryLine(const moveit_msgs::RobotTrajectory& trajectory_msg,
1279  const moveit::core::LinkModel* ee_parent_link,
1280  const robot_model::JointModelGroup* arm_jmg,
1281  const rviz_visual_tools::colors& color)
1282 {
1283  // Error check
1284  if (!arm_jmg)
1285  {
1286  ROS_FATAL_STREAM_NAMED(LOGNAME, "arm_jmg is NULL");
1287  return false;
1288  }
1289 
1290  // Always load the robot state before using
1292 
1293  // Convert trajectory into a series of RobotStates
1294  robot_trajectory::RobotTrajectoryPtr robot_trajectory(
1295  new robot_trajectory::RobotTrajectory(robot_model_, arm_jmg->getName()));
1296  robot_trajectory->setRobotTrajectoryMsg(*shared_robot_state_, trajectory_msg);
1297 
1298  return publishTrajectoryLine(robot_trajectory, ee_parent_link, color);
1299 }
1300 
1301 bool MoveItVisualTools::publishTrajectoryLine(const robot_trajectory::RobotTrajectoryPtr& robot_trajectory,
1302  const moveit::core::LinkModel* ee_parent_link,
1303  const rviz_visual_tools::colors& color)
1304 {
1305  return publishTrajectoryLine(*robot_trajectory, ee_parent_link, color);
1306 }
1307 
1309  const moveit::core::LinkModel* ee_parent_link,
1310  const rviz_visual_tools::colors& color)
1311 {
1312  // Error check
1313  if (!ee_parent_link)
1314  {
1315  ROS_FATAL_STREAM_NAMED(LOGNAME, "ee_parent_link is NULL");
1316  return false;
1317  }
1318 
1319  // Point location datastructure
1321 
1322  // Visualize end effector position of cartesian path
1323  for (std::size_t i = 0; i < robot_trajectory.getWayPointCount(); ++i)
1324  {
1325  const Eigen::Isometry3d& tip_pose = robot_trajectory.getWayPoint(i).getGlobalLinkTransform(ee_parent_link);
1326 
1327  // Error Check
1328  if (tip_pose.translation().x() != tip_pose.translation().x())
1329  {
1330  ROS_ERROR_STREAM_NAMED(LOGNAME, "NAN DETECTED AT TRAJECTORY POINT i=" << i);
1331  return false;
1332  }
1333 
1334  path.push_back(tip_pose.translation());
1335  publishSphere(tip_pose, color, rviz_visual_tools::MEDIUM);
1336  }
1337 
1338  const double radius = 0.005;
1339  publishPath(path, color, radius);
1340 
1341  return true;
1342 }
1343 
1344 bool MoveItVisualTools::publishTrajectoryLine(const moveit_msgs::RobotTrajectory& trajectory_msg,
1345  const robot_model::JointModelGroup* arm_jmg,
1346  const rviz_visual_tools::colors& color)
1347 {
1348  std::vector<const moveit::core::LinkModel*> tips;
1349  if (!arm_jmg->getEndEffectorTips(tips))
1350  {
1351  ROS_ERROR_STREAM_NAMED(LOGNAME, "Unable to get end effector tips from jmg");
1352  return false;
1353  }
1354 
1355  // For each end effector
1356  for (const moveit::core::LinkModel* ee_parent_link : tips)
1357  {
1358  if (!publishTrajectoryLine(trajectory_msg, ee_parent_link, arm_jmg, color))
1359  return false;
1360  }
1361 
1362  return true;
1363 }
1364 
1365 bool MoveItVisualTools::publishTrajectoryLine(const robot_trajectory::RobotTrajectoryPtr& robot_trajectory,
1366  const robot_model::JointModelGroup* arm_jmg,
1367  const rviz_visual_tools::colors& color)
1368 {
1369  return publishTrajectoryLine(*robot_trajectory, arm_jmg, color);
1370 }
1371 
1373  const robot_model::JointModelGroup* arm_jmg,
1374  const rviz_visual_tools::colors& color)
1375 {
1376  std::vector<const moveit::core::LinkModel*> tips;
1377  if (!arm_jmg->getEndEffectorTips(tips))
1378  {
1379  ROS_ERROR_STREAM_NAMED(LOGNAME, "Unable to get end effector tips from jmg");
1380  return false;
1381  }
1382 
1383  // For each end effector
1384  for (const moveit::core::LinkModel* ee_parent_link : tips)
1385  {
1386  if (!publishTrajectoryLine(robot_trajectory, ee_parent_link, color))
1387  return false;
1388  }
1389 
1390  return true;
1391 }
1392 
1393 bool MoveItVisualTools::publishTrajectoryPoints(const std::vector<robot_state::RobotStatePtr>& robot_state_trajectory,
1394  const moveit::core::LinkModel* ee_parent_link,
1395  const rviz_visual_tools::colors& color)
1396 {
1397  // Visualize end effector position of cartesian path
1398  for (std::size_t i = 0; i < robot_state_trajectory.size(); ++i)
1399  {
1400  const Eigen::Isometry3d& tip_pose = robot_state_trajectory[i]->getGlobalLinkTransform(ee_parent_link);
1401 
1402  publishSphere(tip_pose, color);
1403  }
1404  return true;
1405 }
1406 
1407 void MoveItVisualTools::enableRobotStateRootOffet(const Eigen::Isometry3d& offset)
1408 {
1410  robot_state_root_offset_ = offset;
1411 }
1412 
1414 {
1416 }
1417 
1418 bool MoveItVisualTools::publishRobotState(const trajectory_msgs::JointTrajectoryPoint& trajectory_pt,
1419  const robot_model::JointModelGroup* jmg,
1420  const rviz_visual_tools::colors& color)
1421 {
1422  return publishRobotState(trajectory_pt.positions, jmg, color);
1423 }
1424 
1425 bool MoveItVisualTools::publishRobotState(const std::vector<double>& joint_positions,
1426  const robot_model::JointModelGroup* jmg,
1427  const rviz_visual_tools::colors& color)
1428 {
1429  // Always load the robot state before using
1431 
1432  // Set robot state
1433  shared_robot_state_->setToDefaultValues(); // reset the state just in case
1434  shared_robot_state_->setJointGroupPositions(jmg, joint_positions);
1435 
1436  // Publish robot state
1437  return publishRobotState(*shared_robot_state_, color);
1438 }
1439 
1440 bool MoveItVisualTools::publishRobotState(const robot_state::RobotStatePtr& robot_state,
1441  const rviz_visual_tools::colors& color,
1442  const std::vector<std::string>& highlight_links)
1443 {
1444  return publishRobotState(*robot_state.get(), color, highlight_links);
1445 }
1446 
1447 bool MoveItVisualTools::publishRobotState(const robot_state::RobotState& robot_state,
1448  const rviz_visual_tools::colors& color,
1449  const std::vector<std::string>& highlight_links)
1450 {
1451  // when only a subset of links should be colored, the default message is used rather than the cached solid robot
1452  // messages
1453  rviz_visual_tools::colors base_color = color;
1454  if (!highlight_links.empty())
1455  base_color = rviz_visual_tools::DEFAULT;
1456 
1457  // Reference to the correctly colored version of message (they are cached)
1458  // May not exist yet but this will create it
1459  moveit_msgs::DisplayRobotState& display_robot_msg = display_robot_msgs_[base_color];
1460 
1461  // Check if a robot state message already exists for this color
1462  if (display_robot_msg.highlight_links.empty()) // has not been colored yet, lets create that
1463  {
1464  if (color != rviz_visual_tools::DEFAULT) // ignore color highlights when set to default
1465  {
1466  // Get links names
1467  const std::vector<std::string>& link_names =
1468  highlight_links.empty() ? robot_state.getRobotModel()->getLinkModelNamesWithCollisionGeometry() :
1469  highlight_links;
1470  display_robot_msg.highlight_links.resize(link_names.size());
1471 
1472  // Get color
1473  const std_msgs::ColorRGBA& color_rgba = getColor(color);
1474 
1475  // Color every link
1476  for (std::size_t i = 0; i < link_names.size(); ++i)
1477  {
1478  display_robot_msg.highlight_links[i].id = link_names[i];
1479  display_robot_msg.highlight_links[i].color = color_rgba;
1480  }
1481  }
1482  }
1483 
1484  // Apply the offset
1486  {
1488 
1489  // Copy robot state
1490  *shared_robot_state_ = robot_state;
1491 
1493 
1494  // Convert state to message
1495  robot_state::robotStateToRobotStateMsg(*shared_robot_state_, display_robot_msg.state);
1496  }
1497  else
1498  {
1499  // Convert state to message
1500  robot_state::robotStateToRobotStateMsg(robot_state, display_robot_msg.state);
1501  }
1502 
1503  // Publish
1504  publishRobotState(display_robot_msg);
1505 
1506  // remove highlight links from default message
1507  if (!highlight_links.empty())
1508  display_robot_msg.highlight_links.clear();
1509 
1510  return true;
1511 }
1512 
1513 void MoveItVisualTools::publishRobotState(const moveit_msgs::DisplayRobotState& robot_state_msg)
1514 {
1516  pub_robot_state_.publish(robot_state_msg);
1517  ros::spinOnce();
1518 }
1519 
1521 {
1522  static const std::string VJOINT_NAME = "virtual_joint";
1523 
1524  // Always load the robot state before using
1526 
1527  // Apply transform
1528  Eigen::Isometry3d offset;
1529  offset.translation().x() = rviz_visual_tools::LARGE_SCALE;
1530  offset.translation().y() = rviz_visual_tools::LARGE_SCALE;
1531  offset.translation().z() = rviz_visual_tools::LARGE_SCALE;
1533 
1534  // Publish
1536 }
1537 
1538 void MoveItVisualTools::showJointLimits(const robot_state::RobotStatePtr& robot_state)
1539 {
1540  const std::vector<const moveit::core::JointModel*>& joints = robot_model_->getActiveJointModels();
1541 
1542  // Loop through joints
1543  for (std::size_t i = 0; i < joints.size(); ++i)
1544  {
1545  // Assume all joints have only one variable
1546  if (joints[i]->getVariableCount() > 1)
1547  {
1548  // ROS_WARN_STREAM_NAMED(LOGNAME, "Unable to handle joints with more than one var, skipping '"
1549  //<< joints[i]->getName() << "'");
1550  continue;
1551  }
1552 
1553  double current_value = robot_state->getVariablePosition(joints[i]->getName());
1554 
1555  // check if bad position
1556  bool out_of_bounds = !robot_state->satisfiesBounds(joints[i]);
1557 
1558  const moveit::core::VariableBounds& bound = joints[i]->getVariableBounds()[0];
1559 
1560  if (out_of_bounds)
1561  std::cout << MOVEIT_CONSOLE_COLOR_RED;
1562 
1563  std::cout << " " << std::fixed << std::setprecision(5) << bound.min_position_ << "\t";
1564  double delta = bound.max_position_ - bound.min_position_;
1565  // std::cout << "delta: " << delta << " ";
1566  double step = delta / 20.0;
1567 
1568  bool marker_shown = false;
1569  for (double value = bound.min_position_; value < bound.max_position_; value += step)
1570  {
1571  // show marker of current value
1572  if (!marker_shown && current_value < value)
1573  {
1574  std::cout << "|";
1575  marker_shown = true;
1576  }
1577  else
1578  std::cout << "-";
1579  }
1580  // show max position
1581  std::cout << " \t" << std::fixed << std::setprecision(5) << bound.max_position_ << " \t" << joints[i]->getName()
1582  << " current: " << std::fixed << std::setprecision(5) << current_value << std::endl;
1583 
1584  if (out_of_bounds)
1585  std::cout << MOVEIT_CONSOLE_COLOR_RESET;
1586  }
1587 }
1588 
1595 planning_scene_monitor::PlanningSceneMonitorPtr MoveItVisualTools::getPlanningSceneMonitor()
1596 {
1597  if (!psm_)
1598  {
1599  ROS_INFO_STREAM_NAMED(LOGNAME, "No planning scene passed into moveit_visual_tools, creating one.");
1601  ros::spinOnce();
1602  ros::Duration(1).sleep(); // TODO: is this necessary?
1603  }
1604  return psm_;
1605 }
1606 
1608 {
1609  static const std::string VJOINT_NAME = "virtual_joint";
1610 
1611  // Check if joint exists
1612  if (!robot_state.getRobotModel()->hasJointModel(VJOINT_NAME))
1613  {
1614  ROS_WARN_STREAM_NAMED("moveit_visual_tools", "Joint '" << VJOINT_NAME << "' does not exist.");
1615  return false;
1616  }
1617 
1618  // Check if variables exist
1619  if (!robot_state.getRobotModel()->getJointModel(VJOINT_NAME)->hasVariable(VJOINT_NAME + "/trans_x"))
1620  {
1621  // Debug
1622  ROS_WARN_STREAM_NAMED("moveit_visual_tools", "Variables for joint '" << VJOINT_NAME
1623  << "' do not exist. Try making this vjoint "
1624  "floating");
1625  ROS_WARN_STREAM_NAMED("moveit_visual_tools", "The only available joint variables are:");
1626  const std::vector<std::string>& var_names =
1627  robot_state.getRobotModel()->getJointModel(VJOINT_NAME)->getVariableNames();
1628  std::copy(var_names.begin(), var_names.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
1629  return false;
1630  }
1631 
1632  return true;
1633 }
1634 
1636  const Eigen::Isometry3d& offset)
1637 {
1638  static const std::string VJOINT_NAME = "virtual_joint";
1639 
1640  // Error check
1641  if (!checkForVirtualJoint(robot_state))
1642  {
1643  ROS_WARN_STREAM_NAMED("moveit_visual_tools", "Unable to apply virtual joint transform, hideRobot() functionality "
1644  "is disabled");
1645  return false;
1646  }
1647 
1648  // Apply translation
1649  robot_state.setVariablePosition(VJOINT_NAME + "/trans_x", offset.translation().x());
1650  robot_state.setVariablePosition(VJOINT_NAME + "/trans_y", offset.translation().y());
1651  robot_state.setVariablePosition(VJOINT_NAME + "/trans_z", offset.translation().z());
1652 
1653  // Apply rotation
1654  Eigen::Quaterniond q(offset.rotation());
1655  robot_state.setVariablePosition(VJOINT_NAME + "/rot_x", q.x());
1656  robot_state.setVariablePosition(VJOINT_NAME + "/rot_y", q.y());
1657  robot_state.setVariablePosition(VJOINT_NAME + "/rot_z", q.z());
1658  robot_state.setVariablePosition(VJOINT_NAME + "/rot_w", q.w());
1659 
1660  return true;
1661 }
1662 
1663 } // namespace moveit_visual_tools
static const std::string DISPLAY_ROBOT_STATE_TOPIC
bool hideRobot()
Fake removing a Robot State display in Rviz by simply moving it very far away.
#define ROS_INFO_NAMED(name,...)
#define MOVEIT_CONSOLE_COLOR_RESET
#define ROS_DEBUG_STREAM_NAMED(name, args)
bool publishCollisionCylinder(const geometry_msgs::Point &a, const geometry_msgs::Point &b, const std::string &object_name, double radius, const rviz_visual_tools::colors &color=rviz_visual_tools::GREEN)
Create a MoveIt Collision cylinder between two points.
#define ROS_ERROR_STREAM_NAMED(name, args)
bool publishCuboid(const Eigen::Vector3d &point1, const Eigen::Vector3d &point2, colors color=BLUE)
#define ROS_WARN_NAMED(name,...)
planning_scene_monitor::PlanningSceneMonitorPtr getPlanningSceneMonitor()
Get the planning scene monitor that this class is using.
std::vector< Eigen::Vector3d, Eigen::aligned_allocator< Eigen::Vector3d > > vector_Vector3d
bool waitForSubscriber(const ros::Publisher &pub, double wait_time=0.5, bool blocking=false)
bool publishTrajectoryLine(const moveit_msgs::RobotTrajectory &trajectory_msg, const moveit::core::LinkModel *ee_parent_link, const robot_model::JointModelGroup *arm_jmg, const rviz_visual_tools::colors &color=rviz_visual_tools::LIME_GREEN)
Display a line of the end effector path from a robot trajectory path.
MoveItVisualTools(const std::string &base_frame, const std::string &marker_topic, planning_scene_monitor::PlanningSceneMonitorPtr psm)
Constructor.
void getCollisionWallMsg(double x, double y, double z, double angle, double width, double height, const std::string &name, moveit_msgs::CollisionObject &collision_obj)
Helper for publishCollisionWall.
void getCollisionMarkersFromContacts(visualization_msgs::MarkerArray &arr, const std::string &frame_id, const CollisionResult::ContactMap &con, const std_msgs::ColorRGBA &color, const ros::Duration &lifetime, const double radius=0.035)
Eigen::Vector3d getCenterPoint(const Eigen::Vector3d &a, const Eigen::Vector3d &b) const
bool publishArrow(const Eigen::Isometry3d &pose, colors color=BLUE, scales scale=MEDIUM, double length=0.0, std::size_t id=0)
moveit::core::RobotModelConstPtr robot_model_
moveit::core::RobotStatePtr root_robot_state_
bool attachCO(const std::string &name, const std::string &ee_parent_link)
Attach a collision object from the planning scene.
void showJointLimits(const moveit::core::RobotStatePtr &robot_state)
Print to console the current robot state&#39;s joint values within its limits visually.
Eigen::Isometry3d getVectorBetweenPoints(const Eigen::Vector3d &a, const Eigen::Vector3d &b) const
ROSCONSOLE_CONSOLE_IMPL_DECL std::string getName(void *handle)
bool publishTrajectoryPath(const std::vector< moveit::core::RobotStatePtr > &trajectory, const moveit::core::JointModelGroup *jmg, double speed=0.01, bool blocking=false)
Animate trajectory in rviz. These functions do not need a trigger() called because use different publ...
void enableRobotStateRootOffet(const Eigen::Isometry3d &offset)
All published robot states will have their virtual joint moved by offset.
bool publishCollisionMesh(const geometry_msgs::Pose &object_pose, const std::string &object_name, const std::string &mesh_path, const rviz_visual_tools::colors &color=rviz_visual_tools::GREEN)
Create a collision object using a mesh.
bool loadCollisionSceneFromFile(const std::string &path)
Load a planning scene to a planning_scene_monitor from file.
#define ROS_INFO_STREAM_NAMED(name, args)
#define M_PI
bool processCollisionObjectMsg(const moveit_msgs::CollisionObject &msg, const rviz_visual_tools::colors &color=rviz_visual_tools::GREEN)
Skip a ROS message call by sending directly to planning scene monitor.
bool publishEEMarkers(const Eigen::Isometry3d &pose, const robot_model::JointModelGroup *ee_jmg, const std::vector< double > &ee_joint_pos, const rviz_visual_tools::colors &color=rviz_visual_tools::CLEAR, const std::string &ns="end_effector")
Publish an end effector to rviz.
bool cleanupACO(const std::string &name)
Remove an active collision object from the planning scene.
std::map< rviz_visual_tools::colors, moveit_msgs::DisplayRobotState > display_robot_msgs_
std::map< const robot_model::JointModelGroup *, std::vector< double > > ee_joint_pos_map_
std::size_t getWayPointCount() const
bool publishTrajectoryPoint(const trajectory_msgs::JointTrajectoryPoint &trajectory_pt, const std::string &planning_group, double display_time=0.1)
Move a joint group in MoveIt for visualization make sure you have already set the planning group name...
std::map< const robot_model::JointModelGroup *, visualization_msgs::MarkerArray > ee_markers_map_
bool publishCollisionWall(double x, double y, double angle=0.0, double width=2.0, double height=1.5, const std::string &name="wall", const rviz_visual_tools::colors &color=rviz_visual_tools::GREEN)
Publish a typical room wall.
bool loadEEMarker(const robot_model::JointModelGroup *ee_jmg, const std::vector< double > &ee_joint_pos={})
Call this once at begining to load the end effector markers and then whenever a joint changes...
planning_scene_monitor::PlanningSceneMonitorPtr psm_
moveit::core::RobotStatePtr hidden_robot_state_
std::map< std::pair< std::string, std::string >, std::vector< Contact > > ContactMap
bool publishWorkspaceParameters(const moveit_msgs::WorkspaceParameters &params)
Display size of workspace used for planning with OMPL, etc. Important for virtual joints...
static bool applyVirtualJointTransform(moveit::core::RobotState &robot_state, const Eigen::Isometry3d &offset)
Before publishing a robot state, optionally change its root transform.
#define ROS_DEBUG_NAMED(name,...)
bool publishCollisionBlock(const geometry_msgs::Pose &block_pose, const std::string &block_name="block", double block_size=0.1, const rviz_visual_tools::colors &color=rviz_visual_tools::GREEN)
Create a MoveIt Collision block at the given pose.
void publish(const boost::shared_ptr< M > &message) const
bool loadPlanningSceneMonitor()
Load a planning scene monitor if one was not passed into the constructor.
std::map< const robot_model::JointModelGroup *, EigenSTL::vector_Isometry3d > ee_poses_map_
bool publishAnimatedGrasp(const moveit_msgs::Grasp &grasp, const robot_model::JointModelGroup *ee_jmg, double animate_speed)
Animate a single grasp in its movement direction.
bool processAttachedCollisionObjectMsg(const moveit_msgs::AttachedCollisionObject &msg)
Skip a ROS message call by sending directly to planning scene monitor.
#define ROS_FATAL_STREAM_NAMED(name, args)
static const double SMALL_SCALE
static bool checkForVirtualJoint(const moveit::core::RobotState &robot_state)
Error check that the robot&#39;s SRDF was properly setup with a virtual joint that was named a certain wa...
bool publishAnimatedGrasps(const std::vector< moveit_msgs::Grasp > &possible_grasps, const robot_model::JointModelGroup *ee_jmg, double animate_speed=0.01)
Display an animated vector of grasps including its approach movement in Rviz.
bool checkAndPublishCollision(const moveit::core::RobotState &robot_state, const planning_scene::PlanningScene *planning_scene, const rviz_visual_tools::colors &highlight_link_color=rviz_visual_tools::RED, const rviz_visual_tools::colors &contact_point_color=rviz_visual_tools::PURPLE)
Check if the robot state is in collision inside the planning scene and visualize the result...
void checkCollision(const collision_detection::CollisionRequest &req, collision_detection::CollisionResult &res)
const std::string LOGNAME
void fromMsg(const A &, B &b)
const std::string & getName() const
ROSCPP_DECL bool ok()
bool removeAllCollisionObjects()
Remove all collision objects that this class has added to the MoveIt planning scene Communicates dire...
moveit::core::RobotModelConstPtr getRobotModel()
Get a pointer to the robot model.
const RobotModelConstPtr & getRobotModel() const
bool publishPath(const std::vector< geometry_msgs::Pose > &path, colors color=RED, scales scale=MEDIUM, const std::string &ns="Path")
moveit::core::RobotStatePtr & getSharedRobotState()
Allow robot state to be altered.
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
const std::string & getPlanningFrame() const
#define MOVEIT_CONSOLE_COLOR_RED
static const double LARGE_SCALE
bool publishIKSolutions(const std::vector< trajectory_msgs::JointTrajectoryPoint > &ik_solutions, const robot_model::JointModelGroup *arm_jmg, double display_time=0.4)
Display an vector of inverse kinematic solutions for the IK service in Rviz Note: this is published t...
bool cleanupCO(const std::string &name)
Remove a collision object from the planning scene.
B toMsg(const A &a)
unsigned int step
bool publishContactPoints(const moveit::core::RobotState &robot_state, const planning_scene::PlanningScene *planning_scene, const rviz_visual_tools::colors &color=rviz_visual_tools::RED)
Given a planning scene and robot state, publish any collisions.
void loadRobotStatePub(const std::string &robot_state_topic="", bool blocking=true)
std::string getTopic() const
tf2_ros::Buffer * tf_buffer
moveit::core::RobotStatePtr shared_robot_state_
bool constructMsgFromShape(const Shape *shape, ShapeMsg &shape_msg)
Mesh * createMeshFromResource(const std::string &resource)
bool publishCollisionGraph(const graph_msgs::GeometryGraph &graph, const std::string &object_name, double radius, const rviz_visual_tools::colors &color=rviz_visual_tools::GREEN)
Publish a connected birectional graph.
bool publishTrajectoryPoints(const std::vector< moveit::core::RobotStatePtr > &robot_state_trajectory, const moveit::core::LinkModel *ee_parent_link, const rviz_visual_tools::colors &color=rviz_visual_tools::YELLOW)
Display trajectory as series of end effector position points.
std_msgs::ColorRGBA getColor(colors color) const
static Eigen::Vector3d convertPoint(const geometry_msgs::Point &point)
bool moveCollisionObject(const Eigen::Isometry3d &pose, const std::string &name, const rviz_visual_tools::colors &color)
Move an already published collision object to a new locaiton in space.
static Time now()
RVIZ_VISUAL_TOOLS_DEPRECATED bool publishCollisionTable(double x, double y, double angle, double width, double height, double depth, const std::string name, const rviz_visual_tools::colors &color=rviz_visual_tools::GREEN)
Publish a typical room table.
static const std::string ROBOT_DESCRIPTION
static const std::string PLANNING_SCENE_TOPIC
bool publishSphere(const Eigen::Isometry3d &pose, colors color=BLUE, scales scale=MEDIUM, const std::string &ns="Sphere", std::size_t id=0)
bool sleep() const
bool publishCollisionFloor(double z=0.0, const std::string &plane_name="Floor", const rviz_visual_tools::colors &color=rviz_visual_tools::GREEN)
Make the floor a collision object.
void setVariablePosition(const std::string &variable, double value)
void loadTrajectoryPub(const std::string &display_planned_path_topic=DISPLAY_PLANNED_PATH_TOPIC, bool blocking=true)
Load publishers as needed.
bool publishRobotState(const trajectory_msgs::JointTrajectoryPoint &trajectory_pt, const robot_model::JointModelGroup *jmg, const rviz_visual_tools::colors &color=rviz_visual_tools::DEFAULT)
Publish a MoveIt robot state to a topic that the Rviz "RobotState" display can show.
bool publishMarkers(visualization_msgs::MarkerArray &markers)
ROSCPP_DECL void spinOnce()
const robot_state::RobotState & getWayPoint(std::size_t index) const
RvizVisualTools(std::string base_frame, std::string marker_topic=RVIZ_MARKER_TOPIC, ros::NodeHandle nh=ros::NodeHandle("~"))
void disableRobotStateRootOffet()
Turn off the root offset feature.
void getRobotTrajectoryMsg(moveit_msgs::RobotTrajectory &trajectory, const std::vector< std::string > &joint_filter=std::vector< std::string >()) const
bool loadSharedRobotState()
Load robot state only as needed.
static geometry_msgs::Pose convertPose(const Eigen::Isometry3d &pose)
bool triggerPlanningSceneUpdate()
When mannual_trigger_update_ is true, use this to tell the planning scene to send an update out...
const robot_state::RobotState & getFirstWayPoint() const
bool publishGrasps(const std::vector< moveit_msgs::Grasp > &possible_grasps, const robot_model::JointModelGroup *ee_jmg, double animate_speed=0.1)
Show grasps generated from moveit_simple_grasps or other MoveIt Grasp message sources.
boost::variant< shape_msgs::SolidPrimitive, shape_msgs::Mesh, shape_msgs::Plane > ShapeMsg
#define ROS_WARN_STREAM_NAMED(name, args)
bool publishCollisionCuboid(const Eigen::Vector3d &point1, const Eigen::Vector3d &point2, const std::string &name, const rviz_visual_tools::colors &color=rviz_visual_tools::GREEN)
Create a MoveIt collision rectangular cuboid at the given pose.


moveit_visual_tools
Author(s): Dave Coleman
autogenerated on Mon Feb 28 2022 22:51:25