43#include <interactive_markers/tools.hpp>
45#include <rviz_common/display_context.hpp>
46#include <rviz_common/frame_manager_iface.hpp>
47#include <rviz_common/window_manager_interface.hpp>
49#include <tf2_eigen/tf2_eigen.hpp>
50#include <geometric_shapes/shape_operations.h>
53#include <QInputDialog>
56#include "ui_motion_planning_rviz_plugin_frame.h"
62 QString status_text =
"\nIt has the subframes '";
63 for (
const auto& subframe : subframes)
65 status_text += QString::fromStdString(subframe.first) +
"', '";
76void MotionPlanningFrame::shapesComboBoxChanged(
const QString& )
78 switch (
ui_->shapes_combo_box->currentData().toInt())
81 ui_->shape_size_x_spin_box->setEnabled(
true);
82 ui_->shape_size_y_spin_box->setEnabled(
true);
83 ui_->shape_size_z_spin_box->setEnabled(
true);
86 ui_->shape_size_x_spin_box->setEnabled(
true);
87 ui_->shape_size_y_spin_box->setEnabled(
false);
88 ui_->shape_size_z_spin_box->setEnabled(
false);
90 case shapes::CYLINDER:
92 ui_->shape_size_x_spin_box->setEnabled(
true);
93 ui_->shape_size_y_spin_box->setEnabled(
false);
94 ui_->shape_size_z_spin_box->setEnabled(
true);
97 ui_->shape_size_x_spin_box->setEnabled(
false);
98 ui_->shape_size_y_spin_box->setEnabled(
false);
99 ui_->shape_size_z_spin_box->setEnabled(
false);
106void MotionPlanningFrame::setLocalSceneEdited(
bool dirty)
108 ui_->publish_current_scene_button->setEnabled(dirty);
111bool MotionPlanningFrame::isLocalSceneDirty()
const
113 return ui_->publish_current_scene_button->isEnabled();
116void MotionPlanningFrame::publishScene()
118 const planning_scene_monitor::LockedPlanningSceneRO& ps =
planning_display_->getPlanningSceneRO();
121 moveit_msgs::msg::PlanningScene msg;
122 ps->getPlanningSceneMsg(msg);
123 planning_scene_publisher_->publish(msg);
124 setLocalSceneEdited(
false);
128void MotionPlanningFrame::publishSceneIfNeeded()
130 if (isLocalSceneDirty() &&
131 QMessageBox::question(
this,
"Update PlanningScene",
132 "You have local changes to your planning scene.\n"
133 "Publish them to the move_group node?",
134 QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes)
138void MotionPlanningFrame::clearScene()
140 planning_scene_monitor::LockedPlanningSceneRW ps =
planning_display_->getPlanningSceneRW();
143 ps->getWorldNonConst()->clearObjects();
144 ps->getCurrentStateNonConst().clearAttachedBodies();
145 moveit_msgs::msg::PlanningScene msg;
146 ps->getPlanningSceneMsg(msg);
147 planning_scene_publisher_->publish(msg);
148 setLocalSceneEdited(
false);
154void MotionPlanningFrame::sceneScaleChanged(
int value)
156 const double scaling_factor =
static_cast<double>(value) / 100.0;
159 planning_scene_monitor::LockedPlanningSceneRW ps =
planning_display_->getPlanningSceneRW();
162 if (ps->getWorld()->hasObject(scaled_object_->id_))
164 ps->getWorldNonConst()->removeObject(scaled_object_->id_);
165 for (std::size_t i = 0; i < scaled_object_->shapes_.size(); ++i)
167 shapes::Shape* s = scaled_object_->shapes_[i]->clone();
168 s->scale(scaling_factor);
170 Eigen::Isometry3d scaled_shape_pose = scaled_object_->shape_poses_[i];
171 scaled_shape_pose.translation() *= scaling_factor;
173 ps->getWorldNonConst()->addToObject(scaled_object_->id_, scaled_object_->pose_, shapes::ShapeConstPtr(s),
177 for (
auto& subframe_pair : scaled_subframes)
178 subframe_pair.second.translation() *= scaling_factor;
180 ps->getWorldNonConst()->setSubframesOfObject(scaled_object_->id_, scaled_subframes);
181 setLocalSceneEdited();
182 scene_marker_->processMessage(createObjectMarkerMsg(ps->getWorld()->getObject(scaled_object_->id_)));
187 scaled_object_.reset();
192 scaled_object_.reset();
197void MotionPlanningFrame::sceneScaleStartChange()
199 QList<QListWidgetItem*> sel =
ui_->collision_objects_list->selectedItems();
202 if (
planning_display_->getPlanningSceneMonitor() && sel[0]->checkState() == Qt::Unchecked)
204 planning_scene_monitor::LockedPlanningSceneRW ps =
planning_display_->getPlanningSceneRW();
207 scaled_object_ = ps->getWorld()->getObject(sel[0]->
text().toStdString());
208 scaled_object_subframes_ = scaled_object_->subframe_poses_;
209 scaled_object_shape_poses_ = scaled_object_->shape_poses_;
214void MotionPlanningFrame::sceneScaleEndChange()
216 scaled_object_.reset();
217 ui_->scene_scale->setSliderPosition(100);
220void MotionPlanningFrame::removeSceneObject()
222 QList<QListWidgetItem*> sel =
ui_->collision_objects_list->selectedItems();
225 planning_scene_monitor::LockedPlanningSceneRW ps =
planning_display_->getPlanningSceneRW();
228 for (
int i = 0; i < sel.count(); ++i)
230 if (sel[i]->checkState() == Qt::Unchecked)
232 ps->getWorldNonConst()->removeObject(sel[i]->
text().toStdString());
236 ps->getCurrentStateNonConst().clearAttachedBody(sel[i]->
text().toStdString());
240 setLocalSceneEdited();
248 QString status_text =
"'" + QString::fromStdString(obj->id_) +
"' is a collision object with ";
249 if (obj->shapes_.empty())
251 status_text +=
"no geometry";
255 std::vector<QString> shape_names;
256 for (
const shapes::ShapeConstPtr& shape : obj->shapes_)
257 shape_names.push_back(QString::fromStdString(shapes::shapeStringName(shape.get())));
258 if (shape_names.size() == 1)
260 status_text +=
"one " + shape_names[0];
264 status_text += QString::fromStdString(std::to_string(shape_names.size())) +
" shapes:";
265 for (
const QString& shape_name : shape_names)
266 status_text +=
" " + shape_name;
270 if (!obj->subframe_poses_.empty())
272 status_text += subframePosesToQstring(obj->subframe_poses_);
277static QString decideStatusText(
const moveit::core::AttachedBody* attached_body)
279 QString status_text =
"'" + QString::fromStdString(attached_body->
getName()) +
"' is attached to '" +
283 status_text += subframePosesToQstring(attached_body->
getSubframes());
288void MotionPlanningFrame::selectedCollisionObjectChanged()
290 QList<QListWidgetItem*> sel =
ui_->collision_objects_list->selectedItems();
293 bool old_state =
ui_->object_x->blockSignals(
true);
294 ui_->object_x->setValue(0.0);
295 ui_->object_x->blockSignals(old_state);
297 old_state =
ui_->object_y->blockSignals(
true);
298 ui_->object_y->setValue(0.0);
299 ui_->object_y->blockSignals(old_state);
301 old_state =
ui_->object_z->blockSignals(
true);
302 ui_->object_z->setValue(0.0);
303 ui_->object_z->blockSignals(old_state);
305 old_state =
ui_->object_rx->blockSignals(
true);
306 ui_->object_rx->setValue(0.0);
307 ui_->object_rx->blockSignals(old_state);
309 old_state =
ui_->object_ry->blockSignals(
true);
310 ui_->object_ry->setValue(0.0);
311 ui_->object_ry->blockSignals(old_state);
313 old_state =
ui_->object_rz->blockSignals(
true);
314 ui_->object_rz->setValue(0.0);
315 ui_->object_rz->blockSignals(old_state);
317 ui_->object_status->setText(
"");
319 ui_->pose_scale_group_box->setEnabled(
false);
324 if (sel[0]->checkState() == Qt::Unchecked)
326 ui_->pose_scale_group_box->setEnabled(
true);
327 bool update_scene_marker =
false;
328 Eigen::Isometry3d obj_pose;
330 const planning_scene_monitor::LockedPlanningSceneRO& ps =
planning_display_->getPlanningSceneRO();
332 ps->getWorld()->getObject(sel[0]->
text().toStdString());
335 ui_->object_status->setText(decideStatusText(obj));
337 if (obj->shapes_.size() == 1)
339 obj_pose = obj->pose_;
340 Eigen::Vector3d xyz = obj_pose.linear().eulerAngles(0, 1, 2);
341 update_scene_marker =
true;
343 bool old_state =
ui_->object_x->blockSignals(
true);
344 ui_->object_x->setValue(obj_pose.translation()[0]);
345 ui_->object_x->blockSignals(old_state);
347 old_state =
ui_->object_y->blockSignals(
true);
348 ui_->object_y->setValue(obj_pose.translation()[1]);
349 ui_->object_y->blockSignals(old_state);
351 old_state =
ui_->object_z->blockSignals(
true);
352 ui_->object_z->setValue(obj_pose.translation()[2]);
353 ui_->object_z->blockSignals(old_state);
355 old_state =
ui_->object_rx->blockSignals(
true);
356 ui_->object_rx->setValue(xyz[0]);
357 ui_->object_rx->blockSignals(old_state);
359 old_state =
ui_->object_ry->blockSignals(
true);
360 ui_->object_ry->setValue(xyz[1]);
361 ui_->object_ry->blockSignals(old_state);
363 old_state =
ui_->object_rz->blockSignals(
true);
364 ui_->object_rz->setValue(xyz[2]);
365 ui_->object_rz->blockSignals(old_state);
370 ui_->object_status->setText(
"ERROR: '" + sel[0]->
text() +
"' should be a collision object but it is not");
373 if (update_scene_marker &&
ui_->tabWidget->tabText(
ui_->tabWidget->currentIndex()).toStdString() == TAB_OBJECTS)
375 createSceneInteractiveMarker();
380 ui_->pose_scale_group_box->setEnabled(
false);
383 const planning_scene_monitor::LockedPlanningSceneRO& ps =
planning_display_->getPlanningSceneRO();
384 const moveit::core::AttachedBody* attached_body =
385 ps->getCurrentState().getAttachedBody(sel[0]->
text().toStdString());
388 ui_->object_status->setText(decideStatusText(attached_body));
392 ui_->object_status->setText(
"ERROR: '" + sel[0]->
text() +
"' should be an attached object but it is not");
398void MotionPlanningFrame::objectPoseValueChanged(
double )
400 updateCollisionObjectPose(
true);
403void MotionPlanningFrame::updateCollisionObjectPose(
bool update_marker_position)
405 QList<QListWidgetItem*> sel =
ui_->collision_objects_list->selectedItems();
408 planning_scene_monitor::LockedPlanningSceneRW ps =
planning_display_->getPlanningSceneRW();
415 p.translation()[0] =
ui_->object_x->value();
416 p.translation()[1] =
ui_->object_y->value();
417 p.translation()[2] =
ui_->object_z->value();
419 p = Eigen::Translation3d(p.translation()) *
420 (Eigen::AngleAxisd(
ui_->object_rx->value(), Eigen::Vector3d::UnitX()) *
421 Eigen::AngleAxisd(
ui_->object_ry->value(), Eigen::Vector3d::UnitY()) *
422 Eigen::AngleAxisd(
ui_->object_rz->value(), Eigen::Vector3d::UnitZ()));
424 ps->getWorldNonConst()->setObjectPose(obj->id_, p);
426 setLocalSceneEdited();
432 Eigen::Quaterniond eq(p.linear());
433 scene_marker_->setPose(Ogre::Vector3(
ui_->object_x->value(),
ui_->object_y->value(),
ui_->object_z->value()),
434 Ogre::Quaternion(eq.w(), eq.x(), eq.y(), eq.z()),
"");
440void MotionPlanningFrame::collisionObjectChanged(QListWidgetItem* item)
442 if (item->type() <
static_cast<int>(known_collision_objects_.size()) &&
planning_display_->getPlanningSceneMonitor())
445 if (known_collision_objects_[item->type()].first != item->text().toStdString())
447 renameCollisionObject(item);
451 bool checked = item->checkState() == Qt::Checked;
452 if (known_collision_objects_[item->type()].second != checked)
453 attachDetachCollisionObject(item);
459void MotionPlanningFrame::imProcessFeedback(visualization_msgs::msg::InteractiveMarkerFeedback& feedback)
461 if (!
planning_display_->getPlanningSceneRO()->knowsFrameTransform(feedback.header.frame_id))
463 RCLCPP_ERROR_STREAM(logger_,
464 "Frame `" << feedback.header.frame_id <<
"` unknown doesn't exists in the planning scene");
466 Eigen::Isometry3d fixed_frame_t_scene_marker;
467 tf2::fromMsg(feedback.pose, fixed_frame_t_scene_marker);
468 Eigen::Isometry3d model_frame_t_scene_marker =
469 planning_display_->getPlanningSceneRO()->getFrameTransform(feedback.header.frame_id) * fixed_frame_t_scene_marker;
471 bool old_state =
ui_->object_x->blockSignals(
true);
472 ui_->object_x->setValue(model_frame_t_scene_marker.translation().x());
473 ui_->object_x->blockSignals(old_state);
475 old_state =
ui_->object_y->blockSignals(
true);
476 ui_->object_y->setValue(model_frame_t_scene_marker.translation().y());
477 ui_->object_y->blockSignals(old_state);
479 old_state =
ui_->object_z->blockSignals(
true);
480 ui_->object_z->setValue(model_frame_t_scene_marker.translation().z());
481 ui_->object_z->blockSignals(old_state);
483 Eigen::Vector3d xyz = model_frame_t_scene_marker.linear().eulerAngles(0, 1, 2);
485 old_state =
ui_->object_rx->blockSignals(
true);
486 ui_->object_rx->setValue(xyz[0]);
487 ui_->object_rx->blockSignals(old_state);
489 old_state =
ui_->object_ry->blockSignals(
true);
490 ui_->object_ry->setValue(xyz[1]);
491 ui_->object_ry->blockSignals(old_state);
493 old_state =
ui_->object_rz->blockSignals(
true);
494 ui_->object_rz->setValue(xyz[2]);
495 ui_->object_rz->blockSignals(old_state);
497 updateCollisionObjectPose(
false);
500void MotionPlanningFrame::copySelectedCollisionObject()
502 QList<QListWidgetItem*> sel =
ui_->collision_objects_list->selectedItems();
506 planning_scene_monitor::LockedPlanningSceneRW ps =
planning_display_->getPlanningSceneRW();
510 for (
const QListWidgetItem* item : sel)
512 std::string
name = item->text().toStdString();
518 name.insert(0,
"Copy of ");
519 if (ps->getWorld()->hasObject(name))
523 while (ps->getWorld()->hasObject(name + std::to_string(n)))
525 name += std::to_string(n);
527 ps->getWorldNonConst()->addToObject(name, obj->shapes_, obj->shape_poses_);
528 RCLCPP_DEBUG(logger_,
"Copied collision object to '%s'",
name.c_str());
530 setLocalSceneEdited();
534void MotionPlanningFrame::computeSaveSceneButtonClicked()
538 moveit_msgs::msg::PlanningScene msg;
545 catch (std::exception& ex)
547 RCLCPP_ERROR(logger_,
"%s", ex.what());
554void MotionPlanningFrame::computeSaveQueryButtonClicked(
const std::string& scene,
const std::string& query_name)
556 moveit_msgs::msg::MotionPlanRequest mreq;
562 if (!query_name.empty())
566 catch (std::exception& ex)
568 RCLCPP_ERROR(logger_,
"%s", ex.what());
575void MotionPlanningFrame::computeDeleteSceneButtonClicked()
579 QList<QTreeWidgetItem*> sel =
ui_->planning_scene_tree->selectedItems();
582 QTreeWidgetItem* s = sel.front();
585 std::string scene = s->text(0).toStdString();
590 catch (std::exception& ex)
592 RCLCPP_ERROR(logger_,
"%s", ex.what());
598 std::string scene = s->parent()->text(0).toStdString();
603 catch (std::exception& ex)
605 RCLCPP_ERROR(logger_,
"%s", ex.what());
613void MotionPlanningFrame::computeDeleteQueryButtonClicked()
617 QList<QTreeWidgetItem*> sel =
ui_->planning_scene_tree->selectedItems();
620 QTreeWidgetItem* s = sel.front();
623 std::string scene = s->parent()->text(0).toStdString();
624 std::string query_name = s->text(0).toStdString();
629 catch (std::exception& ex)
631 RCLCPP_ERROR(logger_,
"%s", ex.what());
633 planning_display_->addMainLoopJob([
this, s] { computeDeleteQueryButtonClickedHelper(s); });
639void MotionPlanningFrame::computeDeleteQueryButtonClickedHelper(QTreeWidgetItem* s)
641 ui_->planning_scene_tree->setUpdatesEnabled(
false);
642 s->parent()->removeChild(s);
643 ui_->planning_scene_tree->setUpdatesEnabled(
true);
646void MotionPlanningFrame::checkPlanningSceneTreeEnabledButtons()
648 QList<QTreeWidgetItem*> sel =
ui_->planning_scene_tree->selectedItems();
651 ui_->load_scene_button->setEnabled(
false);
652 ui_->load_query_button->setEnabled(
false);
653 ui_->save_query_button->setEnabled(
false);
654 ui_->delete_scene_button->setEnabled(
false);
658 ui_->save_query_button->setEnabled(
true);
660 QTreeWidgetItem* s = sel.front();
665 ui_->load_scene_button->setEnabled(
true);
666 ui_->load_query_button->setEnabled(
false);
667 ui_->delete_scene_button->setEnabled(
true);
668 ui_->delete_query_button->setEnabled(
false);
669 ui_->save_query_button->setEnabled(
true);
674 ui_->load_scene_button->setEnabled(
false);
675 ui_->load_query_button->setEnabled(
true);
676 ui_->delete_scene_button->setEnabled(
false);
677 ui_->delete_query_button->setEnabled(
true);
682void MotionPlanningFrame::computeLoadSceneButtonClicked()
686 QList<QTreeWidgetItem*> sel =
ui_->planning_scene_tree->selectedItems();
689 QTreeWidgetItem* s = sel.front();
692 std::string scene = s->text(0).toStdString();
693 RCLCPP_DEBUG(logger_,
"Attempting to load scene '%s'", scene.c_str());
701 catch (std::exception& ex)
703 RCLCPP_ERROR(logger_,
"%s", ex.what());
708 RCLCPP_INFO(logger_,
"Loaded scene '%s'", scene.c_str());
714 "Scene '%s' was saved for robot '%s' but we are using robot '%s'. Using scene geometry only",
715 scene.c_str(), scene_m->robot_model_name.c_str(),
717 planning_scene_world_publisher_->publish(scene_m->world);
719 moveit_msgs::msg::PlanningScene diff;
721 diff.name = scene_m->name;
722 planning_scene_publisher_->publish(diff);
726 planning_scene_publisher_->publish(
static_cast<const moveit_msgs::msg::PlanningScene&
>(*scene_m));
731 planning_scene_publisher_->publish(
static_cast<const moveit_msgs::msg::PlanningScene&
>(*scene_m));
736 RCLCPP_WARN(logger_,
"Failed to load scene '%s'. Has the message format changed since the scene was saved?",
744void MotionPlanningFrame::computeLoadQueryButtonClicked()
748 QList<QTreeWidgetItem*> sel =
ui_->planning_scene_tree->selectedItems();
751 QTreeWidgetItem* s = sel.front();
754 std::string scene = s->parent()->text(0).toStdString();
755 std::string query_name = s->text(0).toStdString();
763 catch (std::exception& ex)
765 RCLCPP_ERROR(logger_,
"%s", ex.what());
770 moveit::core::RobotStatePtr start_state(
773 mp->start_state, *start_state);
776 auto goal_state = std::make_shared<moveit::core::RobotState>(*
planning_display_->getQueryGoalState());
777 for (
const moveit_msgs::msg::Constraints& goal_constraint : mp->goal_constraints)
779 if (!goal_constraint.joint_constraints.empty())
781 std::map<std::string, double> vals;
782 for (
const moveit_msgs::msg::JointConstraint& joint_constraint : goal_constraint.joint_constraints)
783 vals[joint_constraint.joint_name] = joint_constraint.position;
784 goal_state->setVariablePositions(vals);
792 RCLCPP_ERROR(logger_,
793 "Failed to load planning query '%s'. Has the message format changed since the query was saved?",
801visualization_msgs::msg::InteractiveMarker
804 Eigen::Vector3d center;
806 shapes::computeShapeBoundingSphere(obj->shapes_[0].get(), center, scale);
807 geometry_msgs::msg::PoseStamped shape_pose = tf2::toMsg(tf2::Stamped<Eigen::Isometry3d>(
808 obj->pose_, std::chrono::system_clock::now(),
planning_display_->getRobotModel()->getModelFrame()));
813 scale = (scale + center.cwiseAbs().maxCoeff()) * 2.0 * 1.2;
816 visualization_msgs::msg::InteractiveMarker imarker =
818 imarker.description = obj->id_;
819 interactive_markers::autoComplete(imarker);
823void MotionPlanningFrame::createSceneInteractiveMarker()
825 QList<QListWidgetItem*> sel =
ui_->collision_objects_list->selectedItems();
829 const planning_scene_monitor::LockedPlanningSceneRO& ps =
planning_display_->getPlanningSceneRO();
834 ps->getWorld()->getObject(sel[0]->
text().toStdString());
835 if (obj && obj->shapes_.size() == 1)
837 scene_marker_ = std::make_shared<rviz_default_plugins::displays::InteractiveMarker>(
843 connect(
scene_marker_.get(), SIGNAL(userFeedback(visualization_msgs::msg::InteractiveMarkerFeedback&)),
this,
844 SLOT(imProcessFeedback(visualization_msgs::msg::InteractiveMarkerFeedback&)));
852void MotionPlanningFrame::renameCollisionObject(QListWidgetItem* item)
854 long unsigned int version = known_collision_objects_version_;
855 if (item->text().isEmpty())
857 QMessageBox::warning(
this,
"Invalid object name",
"Cannot set an empty object name.");
858 if (version == known_collision_objects_version_)
859 item->setText(QString::fromStdString(known_collision_objects_[item->type()].first));
863 std::string item_text = item->text().toStdString();
864 bool already_exists =
planning_display_->getPlanningSceneRO()->getWorld()->hasObject(item_text);
866 already_exists =
planning_display_->getPlanningSceneRO()->getCurrentState().hasAttachedBody(item_text);
869 QMessageBox::warning(
this,
"Duplicate object name",
870 QString(
"The name '")
872 .append(
"' already exists. Not renaming object ")
873 .append((known_collision_objects_[item->type()].first.c_str())));
874 if (version == known_collision_objects_version_)
875 item->setText(QString::fromStdString(known_collision_objects_[item->type()].first));
879 if (item->checkState() == Qt::Unchecked)
881 planning_scene_monitor::LockedPlanningSceneRW ps =
planning_display_->getPlanningSceneRW();
883 ps->getWorld()->getObject(known_collision_objects_[item->type()].first);
886 known_collision_objects_[item->type()].first = item_text;
887 ps->getWorldNonConst()->removeObject(obj->id_);
888 ps->getWorldNonConst()->addToObject(known_collision_objects_[item->type()].first, obj->pose_, obj->shapes_,
890 ps->getWorldNonConst()->setSubframesOfObject(obj->id_, obj->subframe_poses_);
901 planning_scene_monitor::LockedPlanningSceneRW ps =
planning_display_->getPlanningSceneRW();
902 moveit::core::RobotState& cs = ps->getCurrentStateNonConst();
903 const moveit::core::AttachedBody* ab = cs.
getAttachedBody(known_collision_objects_[item->type()].first);
906 known_collision_objects_[item->type()].first = item_text;
907 auto new_ab = std::make_unique<moveit::core::AttachedBody>(
914 setLocalSceneEdited();
917void MotionPlanningFrame::attachDetachCollisionObject(QListWidgetItem* item)
919 long unsigned int version = known_collision_objects_version_;
920 bool checked = item->checkState() == Qt::Checked;
921 std::pair<std::string, bool> data = known_collision_objects_[item->type()];
922 moveit_msgs::msg::AttachedCollisionObject aco;
927 const std::vector<std::string>& links_std =
planning_display_->getRobotModel()->getLinkModelNames();
928 for (
const std::string& link : links_std)
929 links.append(QString::fromStdString(link));
932 QInputDialog::getItem(
this, tr(
"Select Link Name"), tr(
"Choose the link to attach to:"), links, 0,
false, &ok);
935 if (version == known_collision_objects_version_)
936 item->setCheckState(Qt::Unchecked);
939 aco.link_name = response.toStdString();
940 aco.object.id = data.first;
941 aco.object.operation = moveit_msgs::msg::CollisionObject::ADD;
945 const planning_scene_monitor::LockedPlanningSceneRO& ps =
planning_display_->getPlanningSceneRO();
946 const moveit::core::AttachedBody* attached_body = ps->getCurrentState().getAttachedBody(data.first);
950 aco.object.id = attached_body->
getName();
951 aco.object.operation = moveit_msgs::msg::CollisionObject::REMOVE;
957 planning_scene_monitor::LockedPlanningSceneRW ps =
planning_display_->getPlanningSceneRW();
959 for (std::pair<std::string, bool>& known_collision_object : known_collision_objects_)
961 if (known_collision_object.first == data.first)
963 known_collision_object.second = checked;
967 ps->processAttachedCollisionObjectMsg(aco);
968 rs = ps->getCurrentState();
971 selectedCollisionObjectChanged();
972 setLocalSceneEdited();
977void MotionPlanningFrame::populateCollisionObjectsList()
979 ui_->collision_objects_list->setUpdatesEnabled(
false);
980 bool old_state =
ui_->collision_objects_list->blockSignals(
true);
981 bool octomap_in_scene =
false;
984 QList<QListWidgetItem*> sel =
ui_->collision_objects_list->selectedItems();
985 std::set<std::string> to_select;
986 for (QListWidgetItem* item : sel)
987 to_select.insert(item->text().toStdString());
988 ui_->collision_objects_list->clear();
989 known_collision_objects_.clear();
990 known_collision_objects_version_++;
992 planning_scene_monitor::LockedPlanningSceneRO ps =
planning_display_->getPlanningSceneRO();
995 const std::vector<std::string>& collision_object_names = ps->getWorld()->getObjectIds();
996 for (std::size_t i = 0; i < collision_object_names.size(); ++i)
1000 octomap_in_scene =
true;
1004 QListWidgetItem* item =
new QListWidgetItem(QString::fromStdString(collision_object_names[i]),
1005 ui_->collision_objects_list,
static_cast<int>(i));
1006 item->setFlags(item->flags() | Qt::ItemIsEditable);
1007 item->setToolTip(item->text());
1008 item->setCheckState(Qt::Unchecked);
1009 if (to_select.find(collision_object_names[i]) != to_select.end())
1010 item->setSelected(
true);
1011 ui_->collision_objects_list->addItem(item);
1012 known_collision_objects_.push_back(std::make_pair(collision_object_names[i],
false));
1015 const moveit::core::RobotState& cs = ps->getCurrentState();
1016 std::vector<const moveit::core::AttachedBody*> attached_bodies;
1018 for (std::size_t i = 0; i < attached_bodies.size(); ++i)
1020 QListWidgetItem* item =
1021 new QListWidgetItem(QString::fromStdString(attached_bodies[i]->getName()),
ui_->collision_objects_list,
1022 static_cast<int>(i + collision_object_names.size()));
1023 item->setFlags(item->flags() | Qt::ItemIsEditable);
1024 item->setToolTip(item->text());
1025 item->setCheckState(Qt::Checked);
1026 if (to_select.find(attached_bodies[i]->getName()) != to_select.end())
1027 item->setSelected(
true);
1028 ui_->collision_objects_list->addItem(item);
1029 known_collision_objects_.push_back(std::make_pair(attached_bodies[i]->getName(),
true));
1034 ui_->clear_octomap_button->setEnabled(octomap_in_scene);
1035 ui_->collision_objects_list->blockSignals(old_state);
1036 ui_->collision_objects_list->setUpdatesEnabled(
true);
1037 selectedCollisionObjectChanged();
1040void MotionPlanningFrame::exportGeometryAsTextButtonClicked()
1043 QFileDialog::getSaveFileName(
this, tr(
"Export Scene Geometry"), tr(
""), tr(
"Scene Geometry (*.scene)"));
1044 if (!path.isEmpty())
1046 planning_display_->addBackgroundJob([
this, path = path.toStdString()] { computeExportGeometryAsText(path); },
1051void MotionPlanningFrame::computeExportGeometryAsText(
const std::string& path)
1053 planning_scene_monitor::LockedPlanningSceneRO ps =
planning_display_->getPlanningSceneRO();
1056 std::string p = (path.length() < 7 || path.substr(path.length() - 6) !=
".scene") ? path +
".scene" : path;
1057 std::ofstream fout(p.c_str());
1060 ps->saveGeometryToStream(fout);
1062 RCLCPP_INFO(logger_,
"Saved current scene geometry to '%s'", p.c_str());
1066 RCLCPP_WARN(logger_,
"Unable to save current scene geometry to '%s'", p.c_str());
1071void MotionPlanningFrame::computeImportGeometryFromText(
const std::string& path)
1073 planning_scene_monitor::LockedPlanningSceneRW ps =
planning_display_->getPlanningSceneRW();
1076 std::ifstream fin(path.c_str());
1077 if (ps->loadGeometryFromStream(fin))
1079 RCLCPP_INFO(logger_,
"Loaded scene geometry from '%s'", path.c_str());
1082 setLocalSceneEdited();
1086 QMessageBox::warning(
nullptr,
"Loading scene geometry",
1087 "Failed to load scene geometry.\n"
1088 "See console output for more details.");
1093void MotionPlanningFrame::importGeometryFromTextButtonClicked()
1096 QFileDialog::getOpenFileName(
this, tr(
"Import Scene Geometry"), tr(
""), tr(
"Scene Geometry (*.scene)"));
1097 if (!path.isEmpty())
1099 planning_display_->addBackgroundJob([
this, path = path.toStdString()] { computeImportGeometryFromText(path); },
1100 "import from text");
World::ObjectConstPtr ObjectConstPtr
const Eigen::Isometry3d & getPose() const
Get the pose of the attached body relative to the parent link.
const LinkModel * getAttachedLink() const
Get the model of the link this body is attached to.
const moveit::core::FixedTransformsMap & getSubframes() const
Get subframes of this object (relative to the object pose). The returned transforms are guaranteed to...
const std::set< std::string > & getTouchLinks() const
Get the links that the attached body is allowed to touch.
const EigenSTL::vector_Isometry3d & getShapePoses() const
Get the shape poses (the transforms to the shapes of this body, relative to the pose)....
const std::string & getName() const
Get the name of the attached body.
const std::string & getAttachedLinkName() const
Get the name of the link this body is attached to.
const std::vector< shapes::ShapeConstPtr > & getShapes() const
Get the shapes that make up this attached body.
const trajectory_msgs::msg::JointTrajectory & getDetachPosture() const
Return the posture that is necessary for the object to be released, (if any). This is useful for exam...
void attachBody(std::unique_ptr< AttachedBody > attached_body)
Add an attached body to this state.
void getAttachedBodies(std::vector< const AttachedBody * > &attached_bodies) const
Get all bodies attached to the model corresponding to this state.
bool clearAttachedBody(const std::string &id)
Remove the attached body named id. Return false if the object was not found (and thus not removed)....
const AttachedBody * getAttachedBody(const std::string &name) const
Get the attached body named name. Return nullptr if not found.
moveit_warehouse::PlanningSceneStoragePtr planning_scene_storage_
static const int ITEM_TYPE_SCENE
std::shared_ptr< rviz_default_plugins::displays::InteractiveMarker > scene_marker_
rviz_common::DisplayContext * context_
Ui::MotionPlanningUI * ui_
static const int ITEM_TYPE_QUERY
void constructPlanningRequest(moveit_msgs::msg::MotionPlanRequest &mreq)
MotionPlanningDisplay * planning_display_
static const std::string OCTOMAP_NS
std::map< std::string, Eigen::Isometry3d, std::less< std::string >, Eigen::aligned_allocator< std::pair< const std::string, Eigen::Isometry3d > > > FixedTransformsMap
Map frame names to the transformation matrix that can transform objects from the frame name to the pl...
bool robotStateMsgToRobotState(const Transforms &tf, const moveit_msgs::msg::RobotState &robot_state, RobotState &state, bool copy_attached_bodies=true)
Convert a robot state msg (with accompanying extra transforms) to a MoveIt robot state.
warehouse_ros::MessageWithMetadata< moveit_msgs::msg::PlanningScene >::ConstPtr PlanningSceneWithMetadata
warehouse_ros::MessageWithMetadata< moveit_msgs::msg::MotionPlanRequest >::ConstPtr MotionPlanRequestWithMetadata
std::string append(const std::string &left, const std::string &right)
visualization_msgs::msg::InteractiveMarker make6DOFMarker(const std::string &name, const geometry_msgs::msg::PoseStamped &stamped, double scale, bool orientation_fixed=false)