37#include <boost/algorithm/string.hpp>
38#include <boost/algorithm/string/replace.hpp>
44#include <rviz_default_plugins/robot/robot.hpp>
47#include <rviz_common/display_context.hpp>
48#include <rviz_common/properties/bool_property.hpp>
49#include <rviz_common/properties/color_property.hpp>
50#include <rviz_common/properties/editable_enum_property.hpp>
51#include <rviz_common/properties/float_property.hpp>
52#include <rviz_common/properties/int_property.hpp>
53#include <rviz_common/properties/property.hpp>
54#include <rviz_common/properties/ros_topic_property.hpp>
55#include <rviz_common/properties/string_property.hpp>
56#include <rviz_default_plugins/robot/robot_link.hpp>
57#include <rviz_common/window_manager_interface.hpp>
59#include <rclcpp/qos.hpp>
64using namespace std::placeholders;
70 rviz_common::Display* display)
71 : animating_path_(false)
72 , drop_displaying_trajectory_(false)
76 , trajectory_slider_panel_(nullptr)
77 , trajectory_slider_dock_panel_(nullptr)
78 , logger_(
moveit::getLogger(
"moveit.ros.trajectory_visualization"))
81 "Trajectory Topic",
"/display_planned_path",
82 rosidl_generator_traits::data_type<moveit_msgs::msg::DisplayTrajectory>(),
83 "The topic on which the moveit_msgs::msg::DisplayTrajectory messages are received", widget,
84 SLOT(changedTrajectoryTopic()),
this);
87 new rviz_common::properties::BoolProperty(
"Show Robot Visual",
true,
88 "Indicates whether the geometry of the robot as defined for "
89 "visualisation purposes should be displayed",
90 widget, SLOT(changedDisplayPathVisualEnabled()),
this);
93 new rviz_common::properties::BoolProperty(
"Show Robot Collision",
false,
94 "Indicates whether the geometry of the robot as defined "
95 "for collision detection purposes should be displayed",
96 widget, SLOT(changedDisplayPathCollisionEnabled()),
this);
99 "Robot Alpha", 0.5f,
"Specifies the alpha for the robot links", widget, SLOT(changedRobotPathAlpha()),
this);
104 new rviz_common::properties::EditableEnumProperty(
"State Display Time",
"3x",
105 "Replay speed of trajectory. Either as factor of its time"
106 "parameterization or as constant time (s) per waypoint.",
107 widget, SLOT(changedStateDisplayTime()),
this);
116 "Use Sim Time",
false,
"Indicates whether simulation time or wall-time is used for state display timing.", widget,
120 "Indicates whether the last received path "
121 "is to be animated in a loop",
122 widget, SLOT(changedLoopDisplay()),
this);
124 trail_display_property_ =
new rviz_common::properties::BoolProperty(
"Show Trail",
false,
"Show a path trail", widget,
125 SLOT(changedShowTrail()),
this);
128 "Specifies the step size of the samples "
129 "shown in the trajectory trail.",
130 widget, SLOT(changedTrailStepSize()),
this);
134 "Interrupt Display",
false,
135 "Immediately show newly planned trajectory, interrupting the currently displayed one.", widget);
138 "Robot Color", QColor(150, 50, 150),
"The color of the animated robot", widget, SLOT(changedRobotColor()),
this);
141 "Color Enabled",
false,
"Specifies whether robot coloring is enabled", widget, SLOT(enabledRobotColor()),
this);
156 rviz_common::DisplayContext* context)
163 auto ros_node_abstraction =
context_->getRosNodeAbstraction().lock();
164 if (!ros_node_abstraction)
166 RVIZ_COMMON_LOG_WARNING(
"Unable to lock weak_ptr from DisplayContext in TrajectoryVisualization constructor");
177 rviz_common::WindowManagerInterface* window_context =
context_->getWindowManager();
185 SLOT(trajectorySliderPanelVisibilityChange(
bool)));
207 RCLCPP_ERROR_STREAM(
logger_,
"No robot model found");
221 changedTrajectoryTopic();
241void TrajectoryVisualization::changedLoopDisplay()
248void TrajectoryVisualization::changedShowTrail()
263 static_cast<int>(std::ceil((t->getWayPointCount() + stepsize - 1) /
static_cast<float>(stepsize))));
266 int waypoint_i = std::min(i * stepsize, t->getWayPointCount() - 1);
268 std::make_unique<RobotStateVisualization>(
scene_node_,
context_,
"Trail Robot " + std::to_string(i),
nullptr);
282void TrajectoryVisualization::changedTrailStepSize()
288void TrajectoryVisualization::changedRobotPathAlpha()
295void TrajectoryVisualization::changedTrajectoryTopic()
302 [
this](
const moveit_msgs::msg::DisplayTrajectory::ConstSharedPtr& msg) {
308void TrajectoryVisualization::changedDisplayPathVisualEnabled()
319void TrajectoryVisualization::changedStateDisplayTime()
323void TrajectoryVisualization::changedDisplayPathCollisionEnabled()
336 changedRobotPathAlpha();
348 changedTrajectoryTopic();
355 r->setVisible(
false);
373 constexpr char default_time_string[] =
"3x";
374 constexpr double default_time_value = -3.0;
381 if (tm.back() ==
'x')
385 else if (tm.back() ==
's')
392 return default_time_value;
395 tm.resize(tm.size() - 1);
396 boost::trim_right(tm);
401 value = std::stof(tm);
403 catch (
const std::invalid_argument& ex)
406 return default_time_value;
412 return default_time_value;
479 current_state_time_ += std::chrono::duration_cast<std::chrono::duration<double>>(sim_dt).count();
483 current_state_time_ += std::chrono::duration_cast<std::chrono::duration<double>>(wall_dt).count();
500 const double rt_factor = -tm;
555 update(std::chrono::nanoseconds(std::lround(wall_dt)), std::chrono::nanoseconds(std::lround(sim_dt)));
563 RCLCPP_ERROR_STREAM(
logger_,
"No robot state or robot model loaded");
567 if (!msg->model_id.empty() && msg->model_id !=
robot_model_->getName())
569 RCLCPP_WARN(
logger_,
"Received a trajectory to display for model '%s' but model '%s' was expected",
570 msg->model_id.c_str(),
robot_model_->getName().c_str());
575 auto t = std::make_shared<robot_trajectory::RobotTrajectory>(
robot_model_,
"");
578 for (std::size_t i = 0; i < msg->trajectory.size(); ++i)
582 t->setRobotTrajectoryMsg(*
robot_state_, msg->trajectory_start, msg->trajectory[i]);
591 display_->setStatus(rviz_common::properties::StatusProperty::Ok,
"Trajectory",
"");
595 display_->setStatus(rviz_common::properties::StatusProperty::Error,
"Trajectory", e.what());
608void TrajectoryVisualization::changedRobotColor()
614void TrajectoryVisualization::enabledRobotColor()
628 for (
auto& link : robot->getLinks())
629 link.second->unsetColor();
650 for (
auto& link : robot->getLinks())
651 robot->getLink(link.first)->setColor(color.redF(), color.greenF(), color.blueF());
654void TrajectoryVisualization::trajectorySliderPanelVisibilityChange(
bool enable)
This may be thrown if unrecoverable errors occur.
void onInitialize() override
void setSliderPosition(int position)
int getSliderPosition() const
void pauseButton(bool check)
void update(int way_point_count)
rviz_common::properties::BoolProperty * enable_robot_color_property_
void clearTrajectoryTrail()
void incomingDisplayTrajectory(const moveit_msgs::msg::DisplayTrajectory::ConstSharedPtr &msg)
ROS callback for an incoming path message.
Ogre::SceneNode * scene_node_
rviz_common::DisplayContext * context_
rviz_common::properties::BoolProperty * display_path_visual_enabled_property_
void setName(const QString &name)
rviz_common::properties::BoolProperty * interrupt_display_property_
robot_trajectory::RobotTrajectoryPtr trajectory_message_to_display_
robot_trajectory::RobotTrajectoryPtr displaying_trajectory_message_
std::mutex update_trajectory_message_
rviz_common::PanelDockWidget * trajectory_slider_dock_panel_
void onInitialize(const rclcpp::Node::SharedPtr &node, Ogre::SceneNode *scene_node, rviz_common::DisplayContext *context)
rviz_common::properties::BoolProperty * trail_display_property_
virtual void update(std::chrono::nanoseconds wall_dt, std::chrono::nanoseconds sim_dt)
TrajectoryPanel * trajectory_slider_panel_
rviz_common::properties::BoolProperty * display_path_collision_enabled_property_
moveit::core::RobotStatePtr robot_state_
rviz_common::properties::RosTopicProperty * trajectory_topic_property_
moveit::core::RobotModelConstPtr robot_model_
rviz_common::properties::BoolProperty * use_sim_time_property_
TrajectoryVisualization(rviz_common::properties::Property *widget, rviz_common::Display *display)
Playback a trajectory from a planned path.
std_msgs::msg::ColorRGBA default_attached_object_color_
rviz_common::properties::Property * widget_
rviz_common::properties::BoolProperty * loop_display_property_
rviz_common::properties::ColorProperty * robot_color_property_
void setRobotColor(rviz_default_plugins::robot::Robot *robot, const QColor &color)
double current_state_time_
rclcpp::Node::SharedPtr node_
rviz_common::properties::EditableEnumProperty * state_display_time_property_
void setDefaultAttachedObjectColor(const QColor &color)
rviz_common::properties::IntProperty * trail_step_size_property_
void interruptCurrentDisplay()
rviz_common::Display * display_
std::vector< RobotStateVisualizationUniquePtr > trajectory_trail_
void unsetRobotColor(rviz_default_plugins::robot::Robot *robot)
~TrajectoryVisualization() override
void onRobotModelLoaded(const moveit::core::RobotModelConstPtr &robot_model)
RobotStateVisualizationPtr display_path_robot_
rviz_common::properties::FloatProperty * robot_path_alpha_property_
bool drop_displaying_trajectory_
rclcpp::Subscription< moveit_msgs::msg::DisplayTrajectory >::SharedPtr trajectory_topic_sub_
double getStateDisplayTime()
get time to show each single robot state
Maintain a sequence of waypoints and the time durations between these waypoints.
RobotTrajectory & setRobotTrajectoryMsg(const moveit::core::RobotState &reference_state, const trajectory_msgs::msg::JointTrajectory &trajectory)
Copy the content of the trajectory message into this class. The trajectory message itself is not requ...
RobotTrajectory & append(const RobotTrajectory &source, double dt, size_t start_index=0, size_t end_index=std::numeric_limits< std::size_t >::max())
Add a specified part of a trajectory to the end of the current trajectory. The default (when start_in...
Main namespace for MoveIt.