moveit2
The MoveIt Motion Planning Framework for ROS 2.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
motion_planning_display.cpp
Go to the documentation of this file.
1/*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2008, Willow Garage, 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 Willow Garage 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: Ioan Sucan, Dave Coleman, Adam Leeper, Sachin Chitta */
36
42
43#include <rviz_default_plugins/robot/robot.hpp>
44#include <rviz_default_plugins/robot/robot_link.hpp>
46
47#include <rviz_common/properties/property.hpp>
48#include <rviz_common/properties/string_property.hpp>
49#include <rviz_common/properties/bool_property.hpp>
50#include <rviz_common/properties/float_property.hpp>
51#include <rviz_common/properties/ros_topic_property.hpp>
52#include <rviz_common/properties/editable_enum_property.hpp>
53#include <rviz_common/properties/color_property.hpp>
54#include <rviz_common/display_context.hpp>
55#include <rviz_common/frame_manager_iface.hpp>
56#include <rviz_common/panel_dock_widget.hpp>
57#include <rviz_common/window_manager_interface.hpp>
58#include <rviz_common/display.hpp>
59#include <rviz_rendering/objects/movable_text.hpp>
60
61#include <OgreSceneManager.h>
62#include <OgreSceneNode.h>
63#include <rviz_rendering/objects/shape.hpp>
64
67
68#include <QShortcut>
69
70#include "ui_motion_planning_rviz_plugin_frame.h"
73
74#include <rclcpp/qos.hpp>
75
76namespace moveit_rviz_plugin
77{
78
79// ******************************************************************************************
80// Base class constructor
81// ******************************************************************************************
84 , text_to_display_(nullptr)
85 , frame_(nullptr)
86 , frame_dock_(nullptr)
87 , menu_handler_start_(std::make_shared<interactive_markers::MenuHandler>())
88 , menu_handler_goal_(std::make_shared<interactive_markers::MenuHandler>())
89 , int_marker_display_(nullptr)
90{
91 // Category Groups
92 plan_category_ = new rviz_common::properties::Property("Planning Request", QVariant(), "", this);
93 metrics_category_ = new rviz_common::properties::Property("Planning Metrics", QVariant(), "", this);
94 path_category_ = new rviz_common::properties::Property("Planned Path", QVariant(), "", this);
95
96 // Metrics category -----------------------------------------------------------------------------------------
98 new rviz_common::properties::BoolProperty("Show Weight Limit", false,
99 "Shows the weight limit at a particular pose for an end-effector",
100 metrics_category_, SLOT(changedShowWeightLimit()), this);
101
103 new rviz_common::properties::BoolProperty("Show Manipulability Index", false,
104 "Shows the manipulability index for an end-effector", metrics_category_,
105 SLOT(changedShowManipulabilityIndex()), this);
106
108 new rviz_common::properties::BoolProperty("Show Manipulability", false,
109 "Shows the manipulability for an end-effector", metrics_category_,
110 SLOT(changedShowManipulability()), this);
111
113 new rviz_common::properties::BoolProperty("Show Joint Torques", false,
114 "Shows the joint torques for a given configuration and payload",
115 metrics_category_, SLOT(changedShowJointTorques()), this);
116
118 new rviz_common::properties::FloatProperty("Payload", 1.0f, "Specify the payload at the end effector (kg)",
119 metrics_category_, SLOT(changedMetricsSetPayload()), this);
121
122 metrics_text_height_property_ = new rviz_common::properties::FloatProperty(
123 "TextHeight", 0.08f, "Text height", metrics_category_, SLOT(changedMetricsTextHeight()), this);
124 metrics_text_height_property_->setMin(0.001);
125
126 // Planning request category -----------------------------------------------------------------------------------------
127
128 planning_group_property_ = new rviz_common::properties::EditableEnumProperty(
129 "Planning Group", "", "The name of the group of links to plan for (from the ones defined in the SRDF)",
130 plan_category_, SLOT(changedPlanningGroup()), this);
131 show_workspace_property_ = new rviz_common::properties::BoolProperty("Show Workspace", false,
132 "Shows the axis-aligned bounding box for "
133 "the workspace allowed for planning",
134 plan_category_, SLOT(changedWorkspace()), this);
136 new rviz_common::properties::BoolProperty("Query Start State", false,
137 "Set a custom start state for the motion planning query",
138 plan_category_, SLOT(changedQueryStartState()), this);
140 new rviz_common::properties::BoolProperty("Query Goal State", true,
141 "Shows the goal state for the motion planning query", plan_category_,
142 SLOT(changedQueryGoalState()), this);
143 query_marker_scale_property_ = new rviz_common::properties::FloatProperty(
144 "Interactive Marker Size", 0.0f,
145 "Specifies scale of the interactive marker overlaid on the robot. 0 is auto scale.", plan_category_,
146 SLOT(changedQueryMarkerScale()), this);
147 query_marker_scale_property_->setMin(0.0f);
148
150 new rviz_common::properties::ColorProperty("Start State Color", QColor(0, 255, 0),
151 "The highlight color for the start state", plan_category_,
152 SLOT(changedQueryStartColor()), this);
154 new rviz_common::properties::FloatProperty("Start State Alpha", 1.0f, "Specifies the alpha for the robot links",
155 plan_category_, SLOT(changedQueryStartAlpha()), this);
156 query_start_alpha_property_->setMin(0.0);
157 query_start_alpha_property_->setMax(1.0);
158
160 new rviz_common::properties::ColorProperty("Goal State Color", QColor(250, 128, 0),
161 "The highlight color for the goal state", plan_category_,
162 SLOT(changedQueryGoalColor()), this);
163
165 new rviz_common::properties::FloatProperty("Goal State Alpha", 1.0f, "Specifies the alpha for the robot links",
166 plan_category_, SLOT(changedQueryGoalAlpha()), this);
167 query_goal_alpha_property_->setMin(0.0);
168 query_goal_alpha_property_->setMax(1.0);
169
171 new rviz_common::properties::ColorProperty("Colliding Link Color", QColor(255, 0, 0),
172 "The highlight color for colliding links", plan_category_,
173 SLOT(changedQueryCollidingLinkColor()), this);
174
175 query_outside_joint_limits_link_color_property_ = new rviz_common::properties::ColorProperty(
176 "Joint Violation Color", QColor(255, 0, 255),
177 "The highlight color for child links of joints that are outside bounds", plan_category_,
178 SLOT(changedQueryJointViolationColor()), this);
179
180 // Trajectory playback / planned path category ---------------------------------------------
181 trajectory_visual_ = std::make_shared<TrajectoryVisualization>(path_category_, this);
182
183 // Start background jobs
185 const std::string& name) { backgroundJobUpdate(event, name); });
186}
187
188// ******************************************************************************************
189// Deconstructor
190// ******************************************************************************************
203
205{
207
208 // Planned Path Display
209 trajectory_visual_->onInitialize(node_, planning_scene_node_, context_);
210 QColor qcolor = attached_body_color_property_->getColor();
211 trajectory_visual_->setDefaultAttachedObjectColor(qcolor);
212
214 std::make_shared<RobotStateVisualization>(planning_scene_node_, context_, "Planning Request Start", nullptr);
215 query_robot_start_->setCollisionVisible(false);
216 query_robot_start_->setVisualVisible(true);
217 query_robot_start_->setVisible(query_start_state_property_->getBool());
218 std_msgs::msg::ColorRGBA color;
219 qcolor = query_start_color_property_->getColor();
220 color.r = qcolor.redF();
221 color.g = qcolor.greenF();
222 color.b = qcolor.blueF();
223 color.a = 1.0f;
224 query_robot_start_->setDefaultAttachedObjectColor(color);
225
227 std::make_shared<RobotStateVisualization>(planning_scene_node_, context_, "Planning Request Goal", nullptr);
228 query_robot_goal_->setCollisionVisible(false);
229 query_robot_goal_->setVisualVisible(true);
230 query_robot_goal_->setVisible(query_goal_state_property_->getBool());
231 qcolor = query_goal_color_property_->getColor();
232 color.r = qcolor.redF();
233 color.g = qcolor.greenF();
234 color.b = qcolor.blueF();
235 query_robot_goal_->setDefaultAttachedObjectColor(color);
236
237 rviz_common::WindowManagerInterface* window_context = context_->getWindowManager();
238 frame_ = new MotionPlanningFrame(this, context_, window_context ? window_context->getParentWindow() : nullptr);
239
240 connect(frame_, SIGNAL(configChanged()), getModel(), SIGNAL(configChanged()));
242 addStatusText("Initialized.");
243
244 // immediately switch to next trajectory display after planning
245 connect(frame_, SIGNAL(planningFinished()), trajectory_visual_.get(), SLOT(interruptCurrentDisplay()));
246
247 if (window_context)
248 {
249 frame_dock_ = window_context->addPane(getName(), frame_);
250 connect(frame_dock_, SIGNAL(visibilityChanged(bool)), this, SLOT(motionPanelVisibilityChange(bool)));
251 frame_dock_->setIcon(getIcon());
252 }
253
255 int_marker_display_->initialize(context_);
256
257 text_display_scene_node_ = planning_scene_node_->createChildSceneNode();
258 text_to_display_ = new rviz_rendering::MovableText("EMPTY");
259 text_to_display_->setTextAlignment(rviz_rendering::MovableText::H_CENTER, rviz_rendering::MovableText::V_CENTER);
260 text_to_display_->setCharacterHeight(metrics_text_height_property_->getFloat());
261 text_to_display_->showOnTop();
262 text_to_display_->setVisible(false);
265
266 if (context_ && context_->getWindowManager() && context_->getWindowManager()->getParentWindow())
267 {
268 QShortcut* im_reset_shortcut =
269 new QShortcut(QKeySequence("Ctrl+I"), context_->getWindowManager()->getParentWindow());
270 connect(im_reset_shortcut, SIGNAL(activated()), this, SLOT(resetInteractiveMarkers()));
271 }
272}
273
274void MotionPlanningDisplay::motionPanelVisibilityChange(bool enable)
275{
276 if (enable)
277 setEnabled(true);
278}
279
281{
282 if (enable)
283 {
284 planning_group_sub_ = node_->create_subscription<std_msgs::msg::String>(
285 "/rviz/moveit/select_planning_group", rclcpp::ServicesQoS(),
286 [this](const std_msgs::msg::String::ConstSharedPtr& msg) { return selectPlanningGroupCallback(msg); });
287 }
288 else
289 {
290 planning_group_sub_.reset();
291 }
292}
293
294void MotionPlanningDisplay::selectPlanningGroupCallback(const std_msgs::msg::String::ConstSharedPtr& msg)
295{
296 // synchronize ROS callback with main loop
297 addMainLoopJob([this, group = msg->data] { changePlanningGroup(group); });
298}
299
301{
302 text_to_display_->setVisible(false);
303
304 query_robot_start_->clear();
305 query_robot_goal_->clear();
306
308
309 // Planned Path Display
310 trajectory_visual_->reset();
311
312 bool enabled = isEnabled();
313 frame_->disable();
314 if (enabled)
315 {
316 frame_->enable();
317 query_robot_start_->setVisible(query_start_state_property_->getBool());
318 query_robot_goal_->setVisible(query_goal_state_property_->getBool());
319 }
320}
321
327
329{
330 if (!frame_)
331 return;
332 QProgressBar* p = frame_->ui_->background_job_progress;
334
335 if (n == 0)
336 {
337 p->hide();
338 p->setMaximum(0);
339 p->setValue(0);
340 }
341 else
342 {
343 if (p->maximum() < n) // increase max
344 {
345 p->setMaximum(n);
346 if (n > 1) // only show bar if there will be a progress to show
347 p->show();
348 }
349 else // progress
350 p->setValue(p->maximum() - n);
351 p->update();
352 }
353}
354
355void MotionPlanningDisplay::changedShowWeightLimit()
356{
358 {
359 if (query_start_state_property_->getBool())
360 displayMetrics(true);
361 }
362 else
363 {
364 if (query_goal_state_property_->getBool())
365 displayMetrics(false);
366 }
367}
368
369void MotionPlanningDisplay::changedShowManipulabilityIndex()
370{
372 {
373 if (query_start_state_property_->getBool())
374 displayMetrics(true);
375 }
376 else
377 {
378 if (query_goal_state_property_->getBool())
379 displayMetrics(false);
380 }
381}
382
383void MotionPlanningDisplay::changedShowManipulability()
384{
386 {
387 if (query_start_state_property_->getBool())
388 displayMetrics(true);
389 }
390 else
391 {
392 if (query_goal_state_property_->getBool())
393 displayMetrics(false);
394 }
395}
396
397void MotionPlanningDisplay::changedShowJointTorques()
398{
400 {
401 if (query_start_state_property_->getBool())
402 displayMetrics(true);
403 }
404 else
405 {
406 if (query_goal_state_property_->getBool())
407 displayMetrics(false);
408 }
409}
410
411void MotionPlanningDisplay::changedMetricsSetPayload()
412{
414 {
415 if (query_start_state_property_->getBool())
416 displayMetrics(true);
417 }
418 else
419 {
420 if (query_goal_state_property_->getBool())
421 displayMetrics(false);
422 }
423}
424
425void MotionPlanningDisplay::changedMetricsTextHeight()
426{
427 text_to_display_->setCharacterHeight(metrics_text_height_property_->getFloat());
428}
429
430void MotionPlanningDisplay::displayTable(const std::map<std::string, double>& values, const Ogre::ColourValue& color,
431 const Ogre::Vector3& pos, const Ogre::Quaternion& orient)
432{
433 if (values.empty())
434 {
435 text_to_display_->setVisible(false);
436 return;
437 }
438
439 // the line we want to render
440 std::stringstream ss;
441 ss.setf(std::ios_base::fixed);
442 ss.precision(2);
443
444 for (const auto& [label, value] : values)
445 ss << label << ':' << value << '\n';
446
447 text_to_display_->setCaption(ss.str());
448 text_to_display_->setColor(color);
449 text_display_scene_node_->setPosition(pos);
450 text_display_scene_node_->setOrientation(orient);
451
452 // make sure the node is visible
453 text_to_display_->setVisible(true);
454}
455
457{
458 if (!frame_ || !show_workspace_property_->getBool())
459 {
460 if (workspace_box_)
461 workspace_box_.reset();
462 return;
463 }
464
465 if (!workspace_box_)
466 {
467 workspace_box_ = std::make_unique<rviz_rendering::Shape>(rviz_rendering::Shape::Cube, context_->getSceneManager(),
469 workspace_box_->setColor(0.0f, 0.0f, 0.6f, 0.3f);
470 }
471
472 Ogre::Vector3 center(frame_->ui_->wcenter_x->value(), frame_->ui_->wcenter_y->value(),
473 frame_->ui_->wcenter_z->value());
474 Ogre::Vector3 extents(frame_->ui_->wsize_x->value(), frame_->ui_->wsize_y->value(), frame_->ui_->wsize_z->value());
475 workspace_box_->setScale(extents);
476 workspace_box_->setPosition(center);
477}
478
479void MotionPlanningDisplay::computeMetrics(bool start, const std::string& group, double payload)
480{
482 return;
483 const std::vector<robot_interaction::EndEffectorInteraction>& eef = robot_interaction_->getActiveEndEffectors();
484 if (eef.empty())
485 return;
486 std::scoped_lock slock(update_metrics_lock_);
487
488 moveit::core::RobotStateConstPtr state = start ? getQueryStartState() : getQueryGoalState();
490 {
491 if (ee.parent_group == group)
492 computeMetricsInternal(computed_metrics_[std::make_pair(start, group)], ee, *state, payload);
493 }
494}
495
496void MotionPlanningDisplay::computeMetricsInternal(std::map<std::string, double>& metrics,
498 const moveit::core::RobotState& state, double payload)
499{
500 metrics.clear();
501 dynamics_solver::DynamicsSolverPtr ds;
502 std::map<std::string, dynamics_solver::DynamicsSolverPtr>::const_iterator it = dynamics_solver_.find(ee.parent_group);
503 if (it != dynamics_solver_.end())
504 ds = it->second;
505
506 // Max payload
507 if (ds)
508 {
509 double max_payload;
510 unsigned int saturated_joint;
511 std::vector<double> joint_values;
512 state.copyJointGroupPositions(ee.parent_group, joint_values);
513 if (ds->getMaxPayload(joint_values, max_payload, saturated_joint))
514 {
515 metrics["max_payload"] = max_payload;
516 metrics["saturated_joint"] = saturated_joint;
517 }
518 std::vector<double> joint_torques;
519 joint_torques.resize(joint_values.size());
520 if (ds->getPayloadTorques(joint_values, payload, joint_torques))
521 {
522 for (std::size_t i = 0; i < joint_torques.size(); ++i)
523 {
524 std::stringstream stream;
525 stream << "torque[" << i << ']';
526 metrics[stream.str()] = joint_torques[i];
527 }
528 }
529 }
530
532 {
534 node_->get_parameter_or(ee.parent_group + ".position_only_ik", position_only_ik_[ee.parent_group], false);
535
536 double manipulability_index, manipulability;
537 bool position_ik = position_only_ik_[ee.parent_group];
538 if (kinematics_metrics_->getManipulabilityIndex(state, ee.parent_group, manipulability_index, position_ik))
539 metrics["manipulability_index"] = manipulability_index;
540 if (kinematics_metrics_->getManipulability(state, ee.parent_group, manipulability))
541 metrics["manipulability"] = manipulability;
542 }
543}
544
545namespace
546{
547inline void copyItemIfExists(const std::map<std::string, double>& source, std::map<std::string, double>& dest,
548 const std::string& key)
549{
550 std::map<std::string, double>::const_iterator it = source.find(key);
551 if (it != source.end())
552 dest[key] = it->second;
553}
554} // namespace
555
557{
559 return;
560
561 static const Ogre::Quaternion ORIENTATION(1.0, 0.0, 0.0, 0.0);
562 const std::vector<robot_interaction::EndEffectorInteraction>& eef = robot_interaction_->getActiveEndEffectors();
563 if (eef.empty())
564 return;
565
566 moveit::core::RobotStateConstPtr state = start ? getQueryStartState() : getQueryGoalState();
567
569 {
570 Ogre::Vector3 position(0.0, 0.0, 0.0);
571 std::map<std::string, double> text_table;
572 const std::map<std::string, double>& metrics_table = computed_metrics_[std::make_pair(start, ee.parent_group)];
573 if (compute_weight_limit_property_->getBool())
574 {
575 copyItemIfExists(metrics_table, text_table, "max_payload");
576 copyItemIfExists(metrics_table, text_table, "saturated_joint");
577 }
579 copyItemIfExists(metrics_table, text_table, "manipulability_index");
580 if (show_manipulability_property_->getBool())
581 copyItemIfExists(metrics_table, text_table, "manipulability");
582 if (show_joint_torques_property_->getBool())
583 {
584 std::size_t nj = getRobotModel()->getJointModelGroup(ee.parent_group)->getJointModelNames().size();
585 for (size_t j = 0; j < nj; ++j)
586 {
587 std::stringstream stream;
588 stream << "torque[" << j << ']';
589 copyItemIfExists(metrics_table, text_table, stream.str());
590 }
591 }
592
593 const moveit::core::LinkModel* lm = nullptr;
594 const moveit::core::JointModelGroup* jmg = getRobotModel()->getJointModelGroup(ee.parent_group);
595 if (jmg)
596 {
597 if (!jmg->getLinkModelNames().empty())
598 lm = state->getLinkModel(jmg->getLinkModelNames().back());
599 }
600 if (lm)
601 {
602 const Eigen::Vector3d& t = state->getGlobalLinkTransform(lm).translation();
603 position[0] = t.x();
604 position[1] = t.y();
605 position[2] = t.z() + 0.2; // \todo this should be a param
606 }
607 if (start)
608 {
609 displayTable(text_table, query_start_color_property_->getOgreColor(), position, ORIENTATION);
610 }
611 else
612 {
613 displayTable(text_table, query_goal_color_property_->getOgreColor(), position, ORIENTATION);
614 }
616 }
617}
618
620{
622 return;
623
624 if (query_start_state_property_->getBool())
625 {
626 if (isEnabled())
627 {
628 moveit::core::RobotStateConstPtr state = getQueryStartState();
629
630 // update link poses
631 query_robot_start_->update(state);
632 query_robot_start_->setVisible(true);
633
634 // update link colors
635 std::vector<std::string> collision_links;
636 getPlanningSceneRO()->getCollidingLinks(collision_links, *state);
637 status_links_start_.clear();
638 for (const std::string& collision_link : collision_links)
639 status_links_start_[collision_link] = COLLISION_LINK;
640 if (!collision_links.empty())
641 {
643 getPlanningSceneRO()->getCollidingPairs(pairs, *state);
645 addStatusText("Start state colliding links:");
646 for (collision_detection::CollisionResult::ContactMap::const_iterator it = pairs.begin(); it != pairs.end();
647 ++it)
648 addStatusText(it->first.first + " - " + it->first.second);
649 addStatusText(".");
650 }
651 if (!getCurrentPlanningGroup().empty())
652 {
653 const moveit::core::JointModelGroup* jmg = state->getJointModelGroup(getCurrentPlanningGroup());
654 if (jmg)
655 {
656 std::vector<std::string> outside_bounds;
657 const std::vector<const moveit::core::JointModel*>& jmodels = jmg->getActiveJointModels();
658 for (const moveit::core::JointModel* jmodel : jmodels)
659 {
660 if (!state->satisfiesBounds(jmodel, jmodel->getMaximumExtent() * 1e-2))
661 {
662 outside_bounds.push_back(jmodel->getChildLinkModel()->getName());
663 status_links_start_[outside_bounds.back()] = OUTSIDE_BOUNDS_LINK;
664 }
665 }
666 if (!outside_bounds.empty())
667 {
669 addStatusText("Links descending from joints that are outside bounds in start state:");
670 addStatusText(outside_bounds);
671 }
672 }
673 }
675 // update metrics text
676 displayMetrics(true);
677 }
678 }
679 else
680 query_robot_start_->setVisible(false);
681 context_->queueRender();
682}
683
688
690{
691 if (frame_)
692 frame_->ui_->status_text->setTextColor(color);
693}
694
695void MotionPlanningDisplay::addStatusText(const std::string& text)
696{
697 if (frame_)
698 frame_->ui_->status_text->append(QString::fromStdString(text));
699}
700
701void MotionPlanningDisplay::addStatusText(const std::vector<std::string>& text)
702{
703 for (const std::string& it : text)
704 addStatusText(it);
705}
706
708{
709 std::string group = planning_group_property_->getStdString();
710 if (!group.empty())
711 computeMetrics(true, group, metrics_set_payload_property_->getFloat());
712}
713
715{
716 std::string group = planning_group_property_->getStdString();
717 if (!group.empty())
718 computeMetrics(false, group, metrics_set_payload_property_->getFloat());
719}
720
721void MotionPlanningDisplay::changedQueryStartState()
722{
724 return;
726 addStatusText("Changed start state");
728 addBackgroundJob([this] { publishInteractiveMarkers(true); }, "publishInteractiveMarkers");
729}
730
731void MotionPlanningDisplay::changedQueryGoalState()
732{
734 return;
736 addStatusText("Changed goal state");
738 addBackgroundJob([this] { publishInteractiveMarkers(true); }, "publishInteractiveMarkers");
739}
740
742{
744 return;
745 if (query_goal_state_property_->getBool())
746 {
747 if (isEnabled())
748 {
749 moveit::core::RobotStateConstPtr state = getQueryGoalState();
750
751 // update link poses
752 query_robot_goal_->update(state);
753 query_robot_goal_->setVisible(true);
754
755 // update link colors
756 std::vector<std::string> collision_links;
757 getPlanningSceneRO()->getCollidingLinks(collision_links, *state);
758 status_links_goal_.clear();
759 for (const std::string& collision_link : collision_links)
760 status_links_goal_[collision_link] = COLLISION_LINK;
761 if (!collision_links.empty())
762 {
764 getPlanningSceneRO()->getCollidingPairs(pairs, *state);
766 addStatusText("Goal state colliding links:");
767 for (collision_detection::CollisionResult::ContactMap::const_iterator it = pairs.begin(); it != pairs.end();
768 ++it)
769 addStatusText(it->first.first + " - " + it->first.second);
770 addStatusText(".");
771 }
772
773 if (!getCurrentPlanningGroup().empty())
774 {
775 const moveit::core::JointModelGroup* jmg = state->getJointModelGroup(getCurrentPlanningGroup());
776 if (jmg)
777 {
778 const std::vector<const moveit::core::JointModel*>& jmodels = jmg->getActiveJointModels();
779 std::vector<std::string> outside_bounds;
780 for (const moveit::core::JointModel* jmodel : jmodels)
781 {
782 if (!state->satisfiesBounds(jmodel, jmodel->getMaximumExtent() * 1e-2))
783 {
784 outside_bounds.push_back(jmodel->getChildLinkModel()->getName());
785 status_links_goal_[outside_bounds.back()] = OUTSIDE_BOUNDS_LINK;
786 }
787 }
788
789 if (!outside_bounds.empty())
790 {
792 addStatusText("Links descending from joints that are outside bounds in goal state:");
793 addStatusText(outside_bounds);
794 }
795 }
796 }
798
799 // update metrics text
800 displayMetrics(false);
801 }
802 }
803 else
804 query_robot_goal_->setVisible(false);
805 context_->queueRender();
806}
807
808void MotionPlanningDisplay::resetInteractiveMarkers()
809{
810 query_start_state_->clearError();
811 query_goal_state_->clearError();
812 addBackgroundJob([this] { publishInteractiveMarkers(false); }, "publishInteractiveMarkers");
813}
814
816{
818 {
819 if (pose_update &&
822 {
823 if (query_start_state_property_->getBool())
824 robot_interaction_->updateInteractiveMarkers(query_start_state_);
825 if (query_goal_state_property_->getBool())
826 robot_interaction_->updateInteractiveMarkers(query_goal_state_);
827 }
828 else
829 {
830 robot_interaction_->clearInteractiveMarkers();
831 if (query_start_state_property_->getBool())
832 robot_interaction_->addInteractiveMarkers(query_start_state_, query_marker_scale_property_->getFloat());
833 if (query_goal_state_property_->getBool())
834 robot_interaction_->addInteractiveMarkers(query_goal_state_, query_marker_scale_property_->getFloat());
835 robot_interaction_->publishInteractiveMarkers();
836 }
837 if (frame_)
838 {
840 }
841 }
842}
843
844void MotionPlanningDisplay::changedQueryStartColor()
845{
846 std_msgs::msg::ColorRGBA color;
847 QColor qcolor = query_start_color_property_->getColor();
848 color.r = qcolor.redF();
849 color.g = qcolor.greenF();
850 color.b = qcolor.blueF();
851 color.a = 1.0f;
852 query_robot_start_->setDefaultAttachedObjectColor(color);
853 changedQueryStartState();
854}
855
856void MotionPlanningDisplay::changedQueryStartAlpha()
857{
858 query_robot_start_->setAlpha(query_start_alpha_property_->getFloat());
859 changedQueryStartState();
860}
861
862void MotionPlanningDisplay::changedQueryMarkerScale()
863{
865 return;
866
867 if (isEnabled())
868 {
869 // Clear the interactive markers and re-add them:
871 }
872}
873
874void MotionPlanningDisplay::changedQueryGoalColor()
875{
876 std_msgs::msg::ColorRGBA color;
877 QColor qcolor = query_goal_color_property_->getColor();
878 color.r = qcolor.redF();
879 color.g = qcolor.greenF();
880 color.b = qcolor.blueF();
881 color.a = 1.0f;
882 query_robot_goal_->setDefaultAttachedObjectColor(color);
883 changedQueryGoalState();
884}
885
886void MotionPlanningDisplay::changedQueryGoalAlpha()
887{
888 query_robot_goal_->setAlpha(query_goal_alpha_property_->getFloat());
889 changedQueryGoalState();
890}
891
892void MotionPlanningDisplay::changedQueryCollidingLinkColor()
893{
894 changedQueryStartState();
895 changedQueryGoalState();
896}
897
898void MotionPlanningDisplay::changedQueryJointViolationColor()
899{
900 changedQueryStartState();
901 changedQueryGoalState();
902}
903
904void MotionPlanningDisplay::changedAttachedBodyColor()
905{
907 // forward color to TrajectoryVisualization
908 const QColor& color = attached_body_color_property_->getColor();
909 trajectory_visual_->setDefaultAttachedObjectColor(color);
910}
911
913 bool error_state_changed)
914{
916 return;
917 addBackgroundJob([this, pose_update = !error_state_changed] { publishInteractiveMarkers(pose_update); },
918 "publishInteractiveMarkers");
920}
921
923 bool error_state_changed)
924{
926 return;
927 addBackgroundJob([this, pose_update = !error_state_changed] { publishInteractiveMarkers(pose_update); },
928 "publishInteractiveMarkers");
930}
931
933{
936 addMainLoopJob([this] { changedQueryStartState(); });
937 context_->queueRender();
938}
939
941{
944 addMainLoopJob([this] { changedQueryGoalState(); });
945 context_->queueRender();
946}
947
952
958
964
976
979 const double* ik_solution) const
980{
981 if (frame_->ui_->collision_aware_ik->isChecked() && planning_scene_monitor_)
982 {
983 state->setJointGroupPositions(group, ik_solution);
984 state->update();
985 bool res = !getPlanningSceneRO()->isStateColliding(*state, group->getName());
986 return res;
987 }
988 else
989 return true;
990}
991
993{
995 unsetAllColors(&query_robot_goal_->getRobot());
996 std::string group = planning_group_property_->getStdString();
997 if (!group.empty())
998 {
999 setGroupColor(&query_robot_start_->getRobot(), group, query_start_color_property_->getColor());
1000 setGroupColor(&query_robot_goal_->getRobot(), group, query_goal_color_property_->getColor());
1001
1002 for (std::map<std::string, LinkDisplayStatus>::const_iterator it = status_links_start_.begin();
1003 it != status_links_start_.end(); ++it)
1004 {
1005 if (it->second == COLLISION_LINK)
1006 {
1007 setLinkColor(&query_robot_start_->getRobot(), it->first, query_colliding_link_color_property_->getColor());
1008 }
1009 else
1010 {
1011 setLinkColor(&query_robot_start_->getRobot(), it->first,
1013 }
1014 }
1015
1016 for (std::map<std::string, LinkDisplayStatus>::const_iterator it = status_links_goal_.begin();
1017 it != status_links_goal_.end(); ++it)
1018 {
1019 if (it->second == COLLISION_LINK)
1020 {
1021 setLinkColor(&query_robot_goal_->getRobot(), it->first, query_colliding_link_color_property_->getColor());
1022 }
1023 else
1024 {
1025 setLinkColor(&query_robot_goal_->getRobot(), it->first,
1027 }
1028 }
1029 }
1030}
1031
1033{
1035 return;
1036
1037 if (getRobotModel()->hasJointModelGroup(group))
1038 {
1039 planning_group_property_->setStdString(group);
1040 }
1041 else
1042 {
1043 RCLCPP_ERROR(moveit::getLogger("moveit.ros.motion_planning_display"), "Group [%s] not found in the robot model.",
1044 group.c_str());
1045 }
1046}
1047
1048void MotionPlanningDisplay::changedPlanningGroup()
1049{
1051 return;
1052
1053 if (!planning_group_property_->getStdString().empty() &&
1054 !getRobotModel()->hasJointModelGroup(planning_group_property_->getStdString()))
1055 {
1056 planning_group_property_->setStdString("");
1057 return;
1058 }
1059 modified_groups_.insert(planning_group_property_->getStdString());
1060
1061 robot_interaction_->decideActiveComponents(planning_group_property_->getStdString());
1062
1066
1067 if (frame_)
1069 addBackgroundJob([this] { publishInteractiveMarkers(false); }, "publishInteractiveMarkers");
1070}
1071
1072void MotionPlanningDisplay::changedWorkspace()
1073{
1075}
1076
1078{
1079 return planning_group_property_->getStdString();
1080}
1081
1082void MotionPlanningDisplay::setQueryStateHelper(bool use_start_state, const std::string& state_name)
1083{
1084 moveit::core::RobotState state = use_start_state ? *getQueryStartState() : *getQueryGoalState();
1085
1086 std::string v = "<" + state_name + ">";
1087
1088 if (v == "<random>")
1089 {
1091 state.setToRandomPositions(jmg);
1092 }
1093 else if (v == "<current>")
1094 {
1096 if (ps)
1097 state = ps->getCurrentState();
1098 }
1099 else if (v == "<same as goal>")
1100 {
1101 state = *getQueryGoalState();
1102 }
1103 else if (v == "<same as start>")
1104 {
1105 state = *getQueryStartState();
1106 }
1107 else
1108 {
1109 // maybe it is a named state
1111 state.setToDefaultValues(jmg, state_name);
1112 }
1113
1114 use_start_state ? setQueryStartState(state) : setQueryGoalState(state);
1115}
1116
1117void MotionPlanningDisplay::populateMenuHandler(std::shared_ptr<interactive_markers::MenuHandler>& mh)
1118{
1119 typedef interactive_markers::MenuHandler immh;
1120 std::vector<std::string> state_names;
1121 state_names.push_back("random");
1122 state_names.push_back("current");
1123 state_names.push_back("same as start");
1124 state_names.push_back("same as goal");
1125
1126 // hacky way to distinguish between the start and goal handlers...
1127 bool is_start = (mh.get() == menu_handler_start_.get());
1128
1129 // Commands for changing the state
1130 immh::EntryHandle menu_states =
1131 mh->insert(is_start ? "Set start state to" : "Set goal state to", immh::FeedbackCallback());
1132 for (const std::string& state_name : state_names)
1133 {
1134 // Don't add "same as start" to the start state handler, and vice versa.
1135 if ((state_name == "same as start" && is_start) || (state_name == "same as goal" && !is_start))
1136 continue;
1137 mh->insert(menu_states, state_name,
1138 [this, is_start, state_name](auto&&) { setQueryStateHelper(is_start, state_name); });
1139 }
1140
1141 // // Group commands, which end up being the same for both interaction handlers
1142 // const std::vector<std::string>& group_names = getRobotModel()->getJointModelGroupNames();
1143 // immh::EntryHandle menu_groups = mh->insert("Planning Group", immh::FeedbackCallback());
1144 // for (int i = 0; i < group_names.size(); ++i)
1145 // mh->insert(menu_groups, group_names[i],
1146 // [this, &name = group_names[i]] { changePlanningGroup(name); });
1147}
1148
1150{
1151 // Invalidate all references to the RobotModel ...
1152 if (frame_)
1155 trajectory_visual_->clearRobotModel();
1156 previous_state_.reset();
1157 query_start_state_.reset();
1158 query_goal_state_.reset();
1159 kinematics_metrics_.reset();
1160 robot_interaction_.reset();
1161 dynamics_solver_.clear();
1162 // ... before calling the parent's method, which finally destroys the creating RobotModelLoader.
1164}
1165
1167{
1169 trajectory_visual_->onRobotModelLoaded(getRobotModel());
1170
1171 robot_interaction_ = std::make_shared<robot_interaction::RobotInteraction>(
1172 getRobotModel(), node_, rclcpp::names::append(getMoveGroupNS(), "rviz_moveit_motion_planning_display"));
1174 o.state_validity_callback_ = [this](moveit::core::RobotState* robot_state,
1175 const moveit::core::JointModelGroup* joint_group,
1176 const double* joint_group_variable_values) {
1177 return isIKSolutionCollisionFree(robot_state, joint_group, joint_group_variable_values);
1178 };
1179 robot_interaction_->getKinematicOptionsMap()->setOptions(
1181
1182 int_marker_display_->subProp("Interactive Markers Namespace")
1183 ->setValue(QString::fromStdString(robot_interaction_->getServerTopic()));
1184 query_robot_start_->load(*getRobotModel()->getURDF());
1185 query_robot_goal_->load(*getRobotModel()->getURDF());
1186
1187 // initialize previous state, start state, and goal state to current state
1188 previous_state_ = std::make_shared<moveit::core::RobotState>(getPlanningSceneRO()->getCurrentState());
1189 query_start_state_ = std::make_shared<robot_interaction::InteractionHandler>(
1191 query_goal_state_ = std::make_shared<robot_interaction::InteractionHandler>(
1193 query_start_state_->setUpdateCallback(
1194 [this](robot_interaction::InteractionHandler* handler, bool error_state_changed) {
1195 scheduleDrawQueryStartState(handler, error_state_changed);
1196 });
1197 query_goal_state_->setUpdateCallback([this](robot_interaction::InteractionHandler* handler, bool error_state_changed) {
1198 scheduleDrawQueryGoalState(handler, error_state_changed);
1199 });
1200
1201 // Interactive marker menus
1204 query_start_state_->setMenuHandler(menu_handler_start_);
1205 query_goal_state_->setMenuHandler(menu_handler_goal_);
1206
1207 if (!planning_group_property_->getStdString().empty())
1208 {
1209 if (!getRobotModel()->hasJointModelGroup(planning_group_property_->getStdString()))
1210 planning_group_property_->setStdString("");
1211 }
1212
1213 const std::vector<std::string>& groups = getRobotModel()->getJointModelGroupNames();
1214 planning_group_property_->clearOptions();
1215 for (const std::string& group : groups)
1216 planning_group_property_->addOptionStd(group);
1217 planning_group_property_->sortOptions();
1218 if (!groups.empty() && planning_group_property_->getStdString().empty())
1219 planning_group_property_->setStdString(groups[0]);
1220
1221 modified_groups_.clear();
1222 kinematics_metrics_ = std::make_shared<kinematics_metrics::KinematicsMetrics>(getRobotModel());
1223
1224 geometry_msgs::msg::Vector3 gravity_vector;
1225 gravity_vector.x = 0.0;
1226 gravity_vector.y = 0.0;
1227 gravity_vector.z = 9.81;
1228
1229 dynamics_solver_.clear();
1230 for (const std::string& group : groups)
1231 {
1232 if (getRobotModel()->getJointModelGroup(group)->isChain())
1233 {
1234 dynamics_solver_[group] =
1235 std::make_shared<dynamics_solver::DynamicsSolver>(getRobotModel(), group, gravity_vector);
1236 }
1237 }
1238
1239 if (frame_)
1240 frame_->fillPlanningGroupOptions();
1241 changedPlanningGroup();
1242}
1244{
1245 frame_->onNewPlanningSceneState();
1246}
1247
1249 const moveit::core::RobotState& src)
1250{
1251 moveit::core::RobotState src_copy = src;
1252 for (const std::string& modified_group : modified_groups_)
1253 {
1254 const moveit::core::JointModelGroup* jmg = dest.getJointModelGroup(modified_group);
1255 if (jmg)
1256 {
1257 std::vector<double> values_to_keep;
1258 dest.copyJointGroupPositions(jmg, values_to_keep);
1259 src_copy.setJointGroupPositions(jmg, values_to_keep);
1260 }
1261 }
1262
1263 // overwrite the destination state
1264 dest = src_copy;
1265}
1266
1268{
1269 std::string group = planning_group_property_->getStdString();
1270
1271 if (query_start_state_ && query_start_state_property_->getBool() && !group.empty())
1272 {
1274 updateStateExceptModified(start, current_state);
1275 setQueryStartState(start);
1276 }
1277
1278 if (query_goal_state_ && query_goal_state_property_->getBool() && !group.empty())
1279 {
1281 updateStateExceptModified(goal, current_state);
1282 setQueryGoalState(goal);
1283 }
1284}
1285
1294
1295// ******************************************************************************************
1296// Enable
1297// ******************************************************************************************
1299{
1301
1302 // Planned Path Display
1303 trajectory_visual_->onEnable();
1304
1305 text_to_display_->setVisible(false);
1306
1307 query_robot_start_->setVisible(query_start_state_property_->getBool());
1308 query_robot_goal_->setVisible(query_goal_state_property_->getBool());
1309
1310 int_marker_display_->setEnabled(true);
1311 int_marker_display_->setFixedFrame(fixed_frame_);
1312
1313 frame_->enable();
1314}
1315
1316// ******************************************************************************************
1317// Disable
1318// ******************************************************************************************
1320{
1322 robot_interaction_->clear();
1323 int_marker_display_->setEnabled(false);
1324
1325 query_robot_start_->setVisible(false);
1326 query_robot_goal_->setVisible(false);
1327 text_to_display_->setVisible(false);
1328
1330
1331 // Planned Path Display
1332 trajectory_visual_->onDisable();
1333
1334 frame_->disable();
1335}
1336
1337// ******************************************************************************************
1338// Update
1339// ******************************************************************************************
1340void MotionPlanningDisplay::update(float wall_dt, float ros_dt)
1341{
1343 int_marker_display_->update(wall_dt, ros_dt);
1344 if (frame_)
1345 frame_->updateSceneMarkers(wall_dt, ros_dt);
1346
1347 PlanningSceneDisplay::update(wall_dt, ros_dt);
1348}
1349
1350void MotionPlanningDisplay::updateInternal(double wall_dt, double ros_dt)
1351{
1352 PlanningSceneDisplay::updateInternal(wall_dt, ros_dt);
1353
1354 // Planned Path Display
1355 trajectory_visual_->update(wall_dt, ros_dt);
1356
1358}
1359
1360void MotionPlanningDisplay::load(const rviz_common::Config& config)
1361{
1363 if (frame_)
1364 {
1365 float d;
1366 if (config.mapGetFloat("MoveIt_Planning_Time", &d))
1367 frame_->ui_->planning_time->setValue(d);
1368 int attempts;
1369 if (config.mapGetInt("MoveIt_Planning_Attempts", &attempts))
1370 frame_->ui_->planning_attempts->setValue(attempts);
1371 if (config.mapGetFloat("Velocity_Scaling_Factor", &d))
1372 frame_->ui_->velocity_scaling_factor->setValue(d);
1373 if (config.mapGetFloat("Acceleration_Scaling_Factor", &d))
1374 frame_->ui_->acceleration_scaling_factor->setValue(d);
1375
1376 bool b;
1377 if (config.mapGetBool("MoveIt_Allow_Replanning", &b))
1378 frame_->ui_->allow_replanning->setChecked(b);
1379 if (config.mapGetBool("MoveIt_Allow_Sensor_Positioning", &b))
1380 frame_->ui_->allow_looking->setChecked(b);
1381 if (config.mapGetBool("MoveIt_Allow_External_Program", &b))
1382 frame_->ui_->allow_external_program->setChecked(b);
1383 if (config.mapGetBool("MoveIt_Use_Cartesian_Path", &b))
1384 frame_->ui_->use_cartesian_path->setChecked(b);
1385 if (config.mapGetBool("MoveIt_Use_Constraint_Aware_IK", &b))
1386 frame_->ui_->collision_aware_ik->setChecked(b);
1387 if (config.mapGetBool("MoveIt_Allow_Approximate_IK", &b))
1388 frame_->ui_->approximate_ik->setChecked(b);
1389
1390 rviz_common::Config workspace = config.mapGetChild("MoveIt_Workspace");
1391 rviz_common::Config ws_center = workspace.mapGetChild("Center");
1392 float val;
1393 if (ws_center.mapGetFloat("X", &val))
1394 frame_->ui_->wcenter_x->setValue(val);
1395 if (ws_center.mapGetFloat("Y", &val))
1396 frame_->ui_->wcenter_y->setValue(val);
1397 if (ws_center.mapGetFloat("Z", &val))
1398 frame_->ui_->wcenter_z->setValue(val);
1399
1400 rviz_common::Config ws_size = workspace.mapGetChild("Size");
1401 if (ws_size.isValid())
1402 {
1403 if (ws_size.mapGetFloat("X", &val))
1404 frame_->ui_->wsize_x->setValue(val);
1405 if (ws_size.mapGetFloat("Y", &val))
1406 frame_->ui_->wsize_y->setValue(val);
1407 if (ws_size.mapGetFloat("Z", &val))
1408 frame_->ui_->wsize_z->setValue(val);
1409 }
1410 else
1411 {
1412 double val;
1413 if (node_->get_parameter("default_workspace_bounds", val))
1414 {
1415 frame_->ui_->wsize_x->setValue(val);
1416 frame_->ui_->wsize_y->setValue(val);
1417 frame_->ui_->wsize_z->setValue(val);
1418 }
1419 }
1420 }
1421}
1422
1423void MotionPlanningDisplay::save(rviz_common::Config config) const
1424{
1426 if (frame_)
1427 {
1428 // "Options" Section
1429 config.mapSetValue("MoveIt_Planning_Time", frame_->ui_->planning_time->value());
1430 config.mapSetValue("MoveIt_Planning_Attempts", frame_->ui_->planning_attempts->value());
1431 config.mapSetValue("Velocity_Scaling_Factor", frame_->ui_->velocity_scaling_factor->value());
1432 config.mapSetValue("Acceleration_Scaling_Factor", frame_->ui_->acceleration_scaling_factor->value());
1433
1434 config.mapSetValue("MoveIt_Allow_Replanning", frame_->ui_->allow_replanning->isChecked());
1435 config.mapSetValue("MoveIt_Allow_Sensor_Positioning", frame_->ui_->allow_looking->isChecked());
1436 config.mapSetValue("MoveIt_Allow_External_Program", frame_->ui_->allow_external_program->isChecked());
1437 config.mapSetValue("MoveIt_Use_Cartesian_Path", frame_->ui_->use_cartesian_path->isChecked());
1438 config.mapSetValue("MoveIt_Use_Constraint_Aware_IK", frame_->ui_->collision_aware_ik->isChecked());
1439 config.mapSetValue("MoveIt_Allow_Approximate_IK", frame_->ui_->approximate_ik->isChecked());
1440
1441 rviz_common::Config workspace = config.mapMakeChild("MoveIt_Workspace");
1442 rviz_common::Config ws_center = workspace.mapMakeChild("Center");
1443 ws_center.mapSetValue("X", frame_->ui_->wcenter_x->value());
1444 ws_center.mapSetValue("Y", frame_->ui_->wcenter_y->value());
1445 ws_center.mapSetValue("Z", frame_->ui_->wcenter_z->value());
1446 rviz_common::Config ws_size = workspace.mapMakeChild("Size");
1447 ws_size.mapSetValue("X", frame_->ui_->wsize_x->value());
1448 ws_size.mapSetValue("Y", frame_->ui_->wsize_y->value());
1449 ws_size.mapSetValue("Z", frame_->ui_->wsize_z->value());
1450 }
1451}
1452
1454{
1457 int_marker_display_->setFixedFrame(fixed_frame_);
1458 // When the fixed frame changes we need to tell RViz to update the rendered interactive marker display
1459 if (frame_ && frame_->scene_marker_)
1460 {
1461 frame_->scene_marker_->requestPoseUpdate(frame_->scene_marker_->getPosition(),
1462 frame_->scene_marker_->getOrientation());
1463 }
1464 changedPlanningGroup();
1465}
1466
1467// Pick and place
1469{
1470 for (std::shared_ptr<rviz_rendering::Shape>& place_location_shape : place_locations_display_)
1471 place_location_shape.reset();
1473}
1474
1475void MotionPlanningDisplay::visualizePlaceLocations(const std::vector<geometry_msgs::msg::PoseStamped>& place_poses)
1476{
1478 place_locations_display_.resize(place_poses.size());
1479 for (std::size_t i = 0; i < place_poses.size(); ++i)
1480 {
1482 std::make_shared<rviz_rendering::Shape>(rviz_rendering::Shape::Sphere, context_->getSceneManager());
1483 place_locations_display_[i]->setColor(1.0f, 0.0f, 0.0f, 0.3f);
1484 Ogre::Vector3 center(place_poses[i].pose.position.x, place_poses[i].pose.position.y, place_poses[i].pose.position.z);
1485 Ogre::Vector3 extents(0.02, 0.02, 0.02);
1486 place_locations_display_[i]->setScale(extents);
1487 place_locations_display_[i]->setPosition(center);
1488 }
1489}
1490
1491} // namespace moveit_rviz_plugin
const std::string & getName() const
Get the name of the joint group.
const std::vector< const JointModel * > & getActiveJointModels() const
Get the active joints in this group (that have controllable DOF). This does not include mimic joints.
const std::vector< std::string > & getLinkModelNames() const
Get the names of the links that are part of this joint group.
A joint from the robot. Models the transform that this joint applies in the kinematic chain....
A link from the robot. Contains the constant transform applied to the link and its geometry.
Representation of a robot's state. This includes position, velocity, acceleration and effort.
void setJointGroupPositions(const std::string &joint_group_name, const double *gstate)
Given positions for the variables that make up a group, in the order found in the group (including va...
void copyJointGroupPositions(const std::string &joint_group_name, std::vector< double > &gstate) const
For a given group, copy the position values of the variables that make up the group into another loca...
const JointModelGroup * getJointModelGroup(const std::string &group) const
Get the model of a particular joint group.
void setToRandomPositions()
Set all joints to random values. Values will be within default bounds.
void update(bool force=false)
Update all transforms.
void setToDefaultValues()
Set all joints to their default positions. The default position is 0, or if that is not within bounds...
void clearJobUpdateEvent()
Clear the callback to be triggered when events in JobEvent take place.
void setJobUpdateEvent(const JobUpdateCallback &event)
Set the callback to be triggered when events in JobEvent take place.
std::size_t getJobCount() const
Get the size of the queue of jobs (includes currently processed job).
void populateMenuHandler(std::shared_ptr< interactive_markers::MenuHandler > &mh)
RobotStateVisualizationPtr query_robot_start_
Handles drawing the robot at the start configuration.
void scheduleDrawQueryGoalState(robot_interaction::InteractionHandler *handler, bool error_state_changed)
kinematics_metrics::KinematicsMetricsPtr kinematics_metrics_
rviz_common::properties::FloatProperty * metrics_text_height_property_
void onNewPlanningSceneState() override
This is called upon successful retrieval of the (initial) planning scene state.
void save(rviz_common::Config config) const override
moveit::core::RobotStatePtr previous_state_
remember previous start state (updated before starting execution)
void updateInternal(double wall_dt, double ros_dt) override
void backgroundJobUpdate(moveit::tools::BackgroundProcessing::JobEvent event, const std::string &jobname)
rviz_common::properties::BoolProperty * show_joint_torques_property_
void displayTable(const std::map< std::string, double > &values, const Ogre::ColourValue &color, const Ogre::Vector3 &pos, const Ogre::Quaternion &orient)
rviz_common::properties::FloatProperty * query_marker_scale_property_
void updateStateExceptModified(moveit::core::RobotState &dest, const moveit::core::RobotState &src)
bool text_display_for_start_
indicates whether the text display is for the start state or not
robot_interaction::RobotInteractionPtr robot_interaction_
rviz_common::properties::BoolProperty * show_manipulability_property_
void setQueryGoalState(const moveit::core::RobotState &goal)
robot_interaction::InteractionHandlerPtr query_start_state_
std::map< std::string, LinkDisplayStatus > status_links_goal_
void setQueryStartState(const moveit::core::RobotState &start)
rviz_common::properties::ColorProperty * query_outside_joint_limits_link_color_property_
rviz_common::properties::FloatProperty * query_goal_alpha_property_
rviz_common::properties::ColorProperty * query_start_color_property_
void computeMetricsInternal(std::map< std::string, double > &metrics, const robot_interaction::EndEffectorInteraction &eef, const moveit::core::RobotState &state, double payload)
void computeMetrics(bool start, const std::string &group, double payload)
rviz_common::properties::Property * path_category_
rviz_common::properties::FloatProperty * metrics_set_payload_property_
void setQueryStateHelper(bool use_start_state, const std::string &v)
std::map< std::string, bool > position_only_ik_
Some groups use position only ik, calls to the metrics have to be modified appropriately.
rviz_common::properties::ColorProperty * query_goal_color_property_
rviz_common::properties::BoolProperty * compute_weight_limit_property_
std::unique_ptr< rviz_rendering::Shape > workspace_box_
std::map< std::pair< bool, std::string >, std::map< std::string, double > > computed_metrics_
std::map< std::string, LinkDisplayStatus > status_links_start_
Ogre::SceneNode * text_display_scene_node_
displays texts
void updateQueryStates(const moveit::core::RobotState &current_state)
rviz_common::properties::EditableEnumProperty * planning_group_property_
rviz_common::properties::BoolProperty * show_manipulability_index_property_
rviz_common::properties::Property * metrics_category_
std::shared_ptr< interactive_markers::MenuHandler > menu_handler_start_
void scheduleDrawQueryStartState(robot_interaction::InteractionHandler *handler, bool error_state_changed)
std::map< std::string, dynamics_solver::DynamicsSolverPtr > dynamics_solver_
moveit::core::RobotStateConstPtr getQueryStartState() const
rviz_common::properties::BoolProperty * show_workspace_property_
rviz_common::properties::BoolProperty * query_goal_state_property_
void load(const rviz_common::Config &config) override
bool isIKSolutionCollisionFree(moveit::core::RobotState *state, const moveit::core::JointModelGroup *group, const double *ik_solution) const
rviz_common::properties::FloatProperty * query_start_alpha_property_
std::vector< std::shared_ptr< rviz_rendering::Shape > > place_locations_display_
RobotStateVisualizationPtr query_robot_goal_
Handles drawing the robot at the goal configuration.
void onSceneMonitorReceivedUpdate(planning_scene_monitor::PlanningSceneMonitor::SceneUpdateType update_type) override
void update(float wall_dt, float ros_dt) override
rviz_common::properties::BoolProperty * query_start_state_property_
rviz_common::properties::Property * plan_category_
std::shared_ptr< interactive_markers::MenuHandler > menu_handler_goal_
rclcpp::Subscription< std_msgs::msg::String >::SharedPtr planning_group_sub_
void selectPlanningGroupCallback(const std_msgs::msg::String::ConstSharedPtr &msg)
void onRobotModelLoaded() override
This is an event called by loadRobotModel() in the MainLoop; do not call directly.
rviz_common::properties::ColorProperty * query_colliding_link_color_property_
void visualizePlaceLocations(const std::vector< geometry_msgs::msg::PoseStamped > &place_poses)
moveit::core::RobotStateConstPtr getQueryGoalState() const
robot_interaction::InteractionHandlerPtr query_goal_state_
std::shared_ptr< rviz_default_plugins::displays::InteractiveMarker > scene_marker_
void updateSceneMarkers(double wall_dt, double ros_dt)
void sceneUpdate(planning_scene_monitor::PlanningSceneMonitor::SceneUpdateType update_type)
planning_scene_monitor::LockedPlanningSceneRO getPlanningSceneRO() const
get read-only access to planning scene
rviz_common::properties::ColorProperty * attached_body_color_property_
void setLinkColor(const std::string &link_name, const QColor &color)
void save(rviz_common::Config config) const override
virtual void updateInternal(double wall_dt, double ros_dt)
virtual void onRobotModelLoaded()
This is an event called by loadRobotModel() in the MainLoop; do not call directly.
void setGroupColor(rviz_default_plugins::robot::Robot *robot, const std::string &group_name, const QColor &color)
virtual void onSceneMonitorReceivedUpdate(planning_scene_monitor::PlanningSceneMonitor::SceneUpdateType update_type)
void addMainLoopJob(const std::function< void()> &job)
queue the execution of this function for the next time the main update() loop gets called
planning_scene_monitor::PlanningSceneMonitorPtr planning_scene_monitor_
const moveit::core::RobotModelConstPtr & getRobotModel() const
void addBackgroundJob(const std::function< void()> &job, const std::string &name)
void update(float wall_dt, float ros_dt) override
void unsetAllColors(rviz_default_plugins::robot::Robot *robot)
Ogre::SceneNode * planning_scene_node_
displays planning scene with everything in it
moveit::tools::BackgroundProcessing background_process_
void load(const rviz_common::Config &config) override
This is a convenience class for obtaining access to an instance of a locked PlanningScene.
static const std::string DEFAULT
When used as key this means the default value.
static const std::string ALL
When used as key this means set ALL keys (including default)
rclcpp::Logger getLogger(const std::string &name)
Creates a namespaced logger.
Definition logger.cpp:79
std::string append(const std::string &left, const std::string &right)
std::map< std::pair< std::string, std::string >, std::vector< Contact > > ContactMap
A map returning the pairs of body ids in contact, plus their contact details.
std::string parent_group
The name of the group that sustains the end-effector (usually an arm)
kinematics::KinematicsQueryOptions options_
other options
moveit::core::GroupStateValidityCallbackFn state_validity_callback_
This is called to determine if the state is valid.