moveit2
The MoveIt Motion Planning Framework for ROS 2.
Loading...
Searching...
No Matches
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
52namespace stomp_moveit
53{
54namespace visualization
55{
56
57namespace
58{
59const 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
76visualization_msgs::msg::MarkerArray
77createTrajectoryMarkerArray(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
120getIterationPathPublisher(const rclcpp::Publisher<visualization_msgs::msg::MarkerArray>::SharedPtr& marker_publisher,
121 const std::shared_ptr<const planning_scene::PlanningScene>& planning_scene,
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
159DoneFn
160getSuccessTrajectoryPublisher(const rclcpp::Publisher<visualization_msgs::msg::MarkerArray>::SharedPtr& marker_publisher,
161 const std::shared_ptr<const planning_scene::PlanningScene>& planning_scene,
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.