moveit2
The MoveIt Motion Planning Framework for ROS 2.
trajectory_visualization.hpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2023, PickNik Inc.
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 PickNik Inc. 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 
40 #pragma once
41 
44 
47 #include <std_msgs/msg/color_rgba.hpp>
48 #include <tf2_eigen/tf2_eigen.hpp>
49 #include <visualization_msgs/msg/marker.hpp>
50 #include <visualization_msgs/msg/marker_array.hpp>
51 
52 namespace stomp_moveit
53 {
54 namespace visualization
55 {
56 
57 namespace
58 {
59 const auto GREEN = [](double a) {
60  std_msgs::msg::ColorRGBA color;
61  color.r = 0.1;
62  color.g = 0.8;
63  color.b = 0.1;
64  color.a = a;
65  return color;
66 };
67 
76 visualization_msgs::msg::MarkerArray
77 createTrajectoryMarkerArray(const robot_trajectory::RobotTrajectory& robot_trajectory,
78  const moveit::core::LinkModel* ee_parent_link,
79  const std_msgs::msg::ColorRGBA& color = GREEN(1.0))
80 {
81  visualization_msgs::msg::MarkerArray markers_array;
82 
83  // Initialize Sphere Marker
84  visualization_msgs::msg::Marker sphere_marker;
85  sphere_marker.header.frame_id = robot_trajectory.getRobotModel()->getModelFrame();
86  sphere_marker.ns = "Path";
87  sphere_marker.type = visualization_msgs::msg::Marker::SPHERE;
88  sphere_marker.action = visualization_msgs::msg::Marker::ADD;
89  sphere_marker.lifetime = rclcpp::Duration(0, 0); // Infinite lifetime
90  sphere_marker.scale.x = 0.01;
91  sphere_marker.scale.y = 0.01;
92  sphere_marker.scale.z = 0.01;
93  sphere_marker.color = color;
94  sphere_marker.frame_locked = false;
95 
96  // Visualize end effector positions of Cartesian path as sphere markers
97  for (std::size_t index = 0; index < robot_trajectory.getWayPointCount(); index++)
98  {
99  const Eigen::Isometry3d& tip_pose = robot_trajectory.getWayPoint(index).getGlobalLinkTransform(ee_parent_link);
100  sphere_marker.pose = tf2::toMsg(tip_pose);
101  sphere_marker.id = index;
102 
103  markers_array.markers.push_back(sphere_marker);
104  }
105 
106  return markers_array;
107 }
108 } // namespace
109 
120 getIterationPathPublisher(const rclcpp::Publisher<visualization_msgs::msg::MarkerArray>::SharedPtr& marker_publisher,
121  const std::shared_ptr<const planning_scene::PlanningScene>& planning_scene,
122  const moveit::core::JointModelGroup* group)
123 {
124  assert(group != nullptr);
125 
126  if (marker_publisher == nullptr)
127  {
128  return [](int /*iteration_number*/, double /*cost*/, const Eigen::MatrixXd& /*values*/) {
129  // Do nothing
130  };
131  }
132 
133  auto path_publisher = [marker_publisher, group,
134  reference_state = moveit::core::RobotState(planning_scene->getCurrentState())](
135  int /*iteration_number*/, double /*cost*/, const Eigen::MatrixXd& values) {
136  static thread_local robot_trajectory::RobotTrajectory trajectory(reference_state.getRobotModel(), group);
137  fillRobotTrajectory(values, reference_state, trajectory);
138 
139  const moveit::core::LinkModel* ee_parent_link = group->getOnlyOneEndEffectorTip();
140 
141  if (ee_parent_link != nullptr && !trajectory.empty())
142  {
143  marker_publisher->publish(createTrajectoryMarkerArray(trajectory, ee_parent_link, GREEN(0.5)));
144  }
145  };
146 
147  return path_publisher;
148 }
149 
159 DoneFn
160 getSuccessTrajectoryPublisher(const rclcpp::Publisher<visualization_msgs::msg::MarkerArray>::SharedPtr& marker_publisher,
161  const std::shared_ptr<const planning_scene::PlanningScene>& planning_scene,
162  const moveit::core::JointModelGroup* group)
163 {
164  assert(group != nullptr);
165 
166  if (marker_publisher == nullptr)
167  {
168  return [](bool /*success*/, int /*total_iterations*/, double /*final_cost*/, const Eigen::MatrixXd& /*values*/) {
169  // Do nothing
170  };
171  }
172 
173  auto path_publisher =
174  [marker_publisher, group, reference_state = moveit::core::RobotState(planning_scene->getCurrentState())](
175  bool success, int /*total_iterations*/, double /*final_cost*/, const Eigen::MatrixXd& values) {
176  static thread_local robot_trajectory::RobotTrajectory trajectory(reference_state.getRobotModel(), group);
177  if (success)
178  {
179  fillRobotTrajectory(values, reference_state, trajectory);
180 
181  const moveit::core::LinkModel* ee_parent_link = group->getOnlyOneEndEffectorTip();
182 
183  if (ee_parent_link != nullptr && !trajectory.empty())
184  {
185  marker_publisher->publish(createTrajectoryMarkerArray(trajectory, ee_parent_link));
186  }
187  }
188  };
189 
190  return path_publisher;
191 }
192 } // namespace visualization
193 } // namespace stomp_moveit
const moveit::core::LinkModel * getOnlyOneEndEffectorTip() const
Get one end effector tip, throwing an error if there ends up being more in the joint model group This...
A link from the robot. Contains the constant transform applied to the link and its geometry.
Definition: link_model.h:72
Representation of a robot's state. This includes position, velocity, acceleration and effort.
Definition: robot_state.h:90
Maintain a sequence of waypoints and the time durations between these waypoints.
Helper functions for converting between MoveIt types and plain Eigen types.
This namespace includes the central class for representing planning contexts.
PostIterationFn getIterationPathPublisher(const rclcpp::Publisher< visualization_msgs::msg::MarkerArray >::SharedPtr &marker_publisher, const std::shared_ptr< const planning_scene::PlanningScene > &planning_scene, const moveit::core::JointModelGroup *group)
Get post iteration function that publishes the EE path of the generated trajectory.
DoneFn getSuccessTrajectoryPublisher(const rclcpp::Publisher< visualization_msgs::msg::MarkerArray >::SharedPtr &marker_publisher, const std::shared_ptr< const planning_scene::PlanningScene > &planning_scene, const moveit::core::JointModelGroup *group)
Get Done function that publishes the EE path of the generated trajectory.
std::function< void(bool success, int total_iterations, double final_cost, const Eigen::MatrixXd &values)> DoneFn
void fillRobotTrajectory(const Eigen::MatrixXd &trajectory_values, const moveit::core::RobotState &reference_state, robot_trajectory::RobotTrajectory &trajectory)
std::function< void(int iteration_number, double cost, const Eigen::MatrixXd &values)> PostIterationFn
A STOMP task definition that allows injecting custom functions for planning.