53 #include <QMessageBox> 54 #include <QInputDialog> 55 #include <QFileDialog> 57 #include "ui_motion_planning_rviz_plugin_frame.h" 63 QString path = QFileDialog::getOpenFileName(
this, tr(
"Import Object"));
71 QString url = QInputDialog::getText(
this, tr(
"Import Object"), tr(
"URL for file to import:"), QLineEdit::Normal,
72 QString(
"http://"), &ok);
73 if (ok && !url.isEmpty())
82 ps->getWorldNonConst()->clearObjects();
83 ps->getCurrentStateNonConst().clearAttachedBodies();
84 moveit_msgs::PlanningScene msg;
85 ps->getPlanningSceneMsg(msg);
105 s->
scale((
double)value / 100.0);
121 QList<QListWidgetItem*> sel =
ui_->collision_objects_list->selectedItems();
137 ui_->scene_scale->setSliderPosition(100);
142 QList<QListWidgetItem*> sel =
ui_->collision_objects_list->selectedItems();
148 for (
int i = 0; i < sel.count(); ++i)
149 if (sel[i]->checkState() == Qt::Unchecked)
150 ps->getWorldNonConst()->removeObject(sel[i]->
text().toStdString());
152 ps->getCurrentStateNonConst().clearAttachedBody(sel[i]->
text().toStdString());
161 QString status_text =
"'" + QString::fromStdString(obj->id_) +
"' is a collision object with ";
162 if (obj->shapes_.empty())
163 status_text +=
"no geometry";
166 std::vector<QString> shape_names;
167 for (std::size_t i = 0; i < obj->shapes_.size(); ++i)
169 if (shape_names.size() == 1)
170 status_text +=
"one " + shape_names[0];
173 status_text += QString::fromStdString(boost::lexical_cast<std::string>(shape_names.size())) +
" shapes:";
174 for (std::size_t i = 0; i < shape_names.size(); ++i)
175 status_text +=
" " + shape_names[i];
183 QString status_text =
"'" + QString::fromStdString(attached_body->getName()) +
"' is attached to '" +
184 QString::fromStdString(attached_body->getAttachedLinkName()) +
"'";
190 QList<QListWidgetItem*> sel =
ui_->collision_objects_list->selectedItems();
193 bool oldState =
ui_->object_x->blockSignals(
true);
194 ui_->object_x->setValue(0.0);
195 ui_->object_x->blockSignals(oldState);
197 oldState =
ui_->object_y->blockSignals(
true);
198 ui_->object_y->setValue(0.0);
199 ui_->object_y->blockSignals(oldState);
201 oldState =
ui_->object_z->blockSignals(
true);
202 ui_->object_z->setValue(0.0);
203 ui_->object_z->blockSignals(oldState);
205 oldState =
ui_->object_rx->blockSignals(
true);
206 ui_->object_rx->setValue(0.0);
207 ui_->object_rx->blockSignals(oldState);
209 oldState =
ui_->object_ry->blockSignals(
true);
210 ui_->object_ry->setValue(0.0);
211 ui_->object_ry->blockSignals(oldState);
213 oldState =
ui_->object_rz->blockSignals(
true);
214 ui_->object_rz->setValue(0.0);
215 ui_->object_rz->blockSignals(oldState);
217 ui_->object_status->setText(
"");
219 ui_->scene_scale->setEnabled(
false);
224 if (sel[0]->checkState() == Qt::Unchecked)
226 ui_->scene_scale->setEnabled(
true);
227 bool update_scene_marker =
false;
228 Eigen::Affine3d obj_pose;
232 ps->getWorld()->getObject(sel[0]->
text().toStdString());
237 if (obj->shapes_.size() == 1)
239 obj_pose = obj->shape_poses_[0];
240 Eigen::Vector3d xyz = obj_pose.linear().eulerAngles(0, 1, 2);
241 update_scene_marker =
true;
243 bool oldState =
ui_->object_x->blockSignals(
true);
244 ui_->object_x->setValue(obj_pose.translation()[0]);
245 ui_->object_x->blockSignals(oldState);
247 oldState =
ui_->object_y->blockSignals(
true);
248 ui_->object_y->setValue(obj_pose.translation()[1]);
249 ui_->object_y->blockSignals(oldState);
251 oldState =
ui_->object_z->blockSignals(
true);
252 ui_->object_z->setValue(obj_pose.translation()[2]);
253 ui_->object_z->blockSignals(oldState);
255 oldState =
ui_->object_rx->blockSignals(
true);
256 ui_->object_rx->setValue(xyz[0]);
257 ui_->object_rx->blockSignals(oldState);
259 oldState =
ui_->object_ry->blockSignals(
true);
260 ui_->object_ry->setValue(xyz[1]);
261 ui_->object_ry->blockSignals(oldState);
263 oldState =
ui_->object_rz->blockSignals(
true);
264 ui_->object_rz->setValue(xyz[2]);
265 ui_->object_rz->blockSignals(oldState);
269 ui_->object_status->setText(
"ERROR: '" + sel[0]->
text() +
"' should be a collision object but it is not");
271 if (update_scene_marker &&
ui_->tabWidget->tabText(
ui_->tabWidget->currentIndex()).toStdString() ==
TAB_OBJECTS)
278 ui_->scene_scale->setEnabled(
false);
282 const robot_state::AttachedBody* attached_body =
283 ps->getCurrentState().getAttachedBody(sel[0]->
text().toStdString());
287 ui_->object_status->setText(
"ERROR: '" + sel[0]->
text() +
"' should be an attached object but it is not");
299 QList<QListWidgetItem*> sel =
ui_->collision_objects_list->selectedItems();
306 if (obj && obj->shapes_.size() == 1)
309 p.translation()[0] =
ui_->object_x->value();
310 p.translation()[1] =
ui_->object_y->value();
311 p.translation()[2] =
ui_->object_z->value();
313 p = Eigen::Translation3d(p.translation()) *
314 (Eigen::AngleAxisd(
ui_->object_rx->value(), Eigen::Vector3d::UnitX()) *
315 Eigen::AngleAxisd(
ui_->object_ry->value(), Eigen::Vector3d::UnitY()) *
316 Eigen::AngleAxisd(
ui_->object_rz->value(), Eigen::Vector3d::UnitZ()));
318 ps->getWorldNonConst()->moveShapeInObject(obj->id_, obj->shapes_[0], p);
324 Eigen::Quaterniond eq(p.linear());
325 scene_marker_->setPose(Ogre::Vector3(
ui_->object_x->value(),
ui_->object_y->value(),
ui_->object_z->value()),
326 Ogre::Quaternion(eq.w(), eq.x(), eq.y(), eq.z()),
"");
341 bool checked = item->checkState() == Qt::Checked;
351 bool oldState =
ui_->object_x->blockSignals(
true);
352 ui_->object_x->setValue(feedback.pose.position.x);
353 ui_->object_x->blockSignals(oldState);
355 oldState =
ui_->object_y->blockSignals(
true);
356 ui_->object_y->setValue(feedback.pose.position.y);
357 ui_->object_y->blockSignals(oldState);
359 oldState =
ui_->object_z->blockSignals(
true);
360 ui_->object_z->setValue(feedback.pose.position.z);
361 ui_->object_z->blockSignals(oldState);
363 Eigen::Quaterniond
q;
365 Eigen::Vector3d xyz = q.matrix().eulerAngles(0, 1, 2);
367 oldState =
ui_->object_rx->blockSignals(
true);
368 ui_->object_rx->setValue(xyz[0]);
369 ui_->object_rx->blockSignals(oldState);
371 oldState =
ui_->object_ry->blockSignals(
true);
372 ui_->object_ry->setValue(xyz[1]);
373 ui_->object_ry->blockSignals(oldState);
375 oldState =
ui_->object_rz->blockSignals(
true);
376 ui_->object_rz->setValue(xyz[2]);
377 ui_->object_rz->blockSignals(oldState);
384 QList<QListWidgetItem*> sel =
ui_->collision_objects_list->selectedItems();
392 for (
int i = 0; i < sel.size(); ++i)
394 std::string
name = sel[i]->text().toStdString();
400 name =
"Copy of " + name;
401 if (ps->getWorld()->hasObject(name))
405 while (ps->getWorld()->hasObject(name + boost::lexical_cast<std::string>(n)))
407 name += boost::lexical_cast<std::string>(n);
409 ps->getWorldNonConst()->addToObject(name, obj->shapes_, obj->shape_poses_);
410 ROS_DEBUG(
"Copied collision object to '%s'", name.c_str());
419 moveit_msgs::PlanningScene msg;
426 catch (std::exception& ex)
437 moveit_msgs::MotionPlanRequest mreq;
443 if (!query_name.empty())
447 catch (std::exception& ex)
460 QList<QTreeWidgetItem*> sel =
ui_->planning_scene_tree->selectedItems();
463 QTreeWidgetItem*
s = sel.front();
466 std::string scene = s->text(0).toStdString();
471 catch (std::exception& ex)
479 std::string scene = s->parent()->text(0).toStdString();
484 catch (std::exception& ex)
498 QList<QTreeWidgetItem*> sel =
ui_->planning_scene_tree->selectedItems();
501 QTreeWidgetItem*
s = sel.front();
504 std::string scene = s->parent()->text(0).toStdString();
505 std::string query_name = s->text(0).toStdString();
510 catch (std::exception& ex)
523 ui_->planning_scene_tree->setUpdatesEnabled(
false);
524 s->parent()->removeChild(s);
525 ui_->planning_scene_tree->setUpdatesEnabled(
true);
530 QList<QTreeWidgetItem*> sel =
ui_->planning_scene_tree->selectedItems();
533 ui_->load_scene_button->setEnabled(
false);
534 ui_->load_query_button->setEnabled(
false);
535 ui_->save_query_button->setEnabled(
false);
536 ui_->delete_scene_button->setEnabled(
false);
540 ui_->save_query_button->setEnabled(
true);
542 QTreeWidgetItem*
s = sel.front();
547 ui_->load_scene_button->setEnabled(
true);
548 ui_->load_query_button->setEnabled(
false);
549 ui_->delete_scene_button->setEnabled(
true);
550 ui_->delete_query_button->setEnabled(
false);
551 ui_->save_query_button->setEnabled(
true);
556 ui_->load_scene_button->setEnabled(
false);
557 ui_->load_query_button->setEnabled(
true);
558 ui_->delete_scene_button->setEnabled(
false);
559 ui_->delete_query_button->setEnabled(
true);
568 QList<QTreeWidgetItem*> sel =
ui_->planning_scene_tree->selectedItems();
571 QTreeWidgetItem*
s = sel.front();
574 std::string scene = s->text(0).toStdString();
575 ROS_DEBUG(
"Attempting to load scene '%s'", scene.c_str());
582 catch (std::exception& ex)
589 ROS_INFO(
"Loaded scene '%s'", scene.c_str());
594 ROS_INFO(
"Scene '%s' was saved for robot '%s' but we are using robot '%s'. Using scene geometry only",
595 scene.c_str(), scene_m->robot_model_name.c_str(),
599 moveit_msgs::PlanningScene diff;
601 diff.name = scene_m->name;
611 ROS_WARN(
"Failed to load scene '%s'. Has the message format changed since the scene was saved?",
622 QList<QTreeWidgetItem*> sel =
ui_->planning_scene_tree->selectedItems();
625 QTreeWidgetItem*
s = sel.front();
628 std::string scene = s->parent()->text(0).toStdString();
629 std::string query_name = s->text(0).toStdString();
636 catch (std::exception& ex)
645 mp->start_state, *start_state);
649 for (std::size_t i = 0; i < mp->goal_constraints.size(); ++i)
650 if (mp->goal_constraints[i].joint_constraints.size() > 0)
652 std::map<std::string, double> vals;
653 for (std::size_t j = 0; j < mp->goal_constraints[i].joint_constraints.size(); ++j)
654 vals[mp->goal_constraints[i].joint_constraints[j].joint_name] =
655 mp->goal_constraints[i].joint_constraints[j].position;
656 goal_state->setVariablePositions(vals);
662 ROS_ERROR(
"Failed to load planning query '%s'. Has the message format changed since the query was saved?",
672 world->addToObject(
id, shape, pose);
685 QList<QListWidgetItem*> sel =
ui_->collision_objects_list->selectedItems();
694 ps->getWorld()->getObject(sel[0]->
text().toStdString());
695 if (obj && obj->shapes_.size() == 1)
697 Eigen::Quaterniond eq(obj->shape_poses_[0].linear());
698 geometry_msgs::PoseStamped shape_pose;
699 shape_pose.pose.position.x = obj->shape_poses_[0].translation()[0];
700 shape_pose.pose.position.y = obj->shape_poses_[0].translation()[1];
701 shape_pose.pose.position.z = obj->shape_poses_[0].translation()[2];
702 shape_pose.pose.orientation.x = eq.x();
703 shape_pose.pose.orientation.y = eq.y();
704 shape_pose.pose.orientation.z = eq.z();
705 shape_pose.pose.orientation.w = eq.w();
708 visualization_msgs::InteractiveMarker int_marker =
711 int_marker.description = sel[0]->text().toStdString();
720 connect(imarker, SIGNAL(userFeedback(visualization_msgs::InteractiveMarkerFeedback&)),
this,
732 if (item->text().isEmpty())
734 QMessageBox::warning(
this,
"Invalid object name",
"Cannot set an empty object name.");
740 std::string item_text = item->text().toStdString();
746 QMessageBox::warning(
this,
"Duplicate object name",
747 QString(
"The name '")
749 .
append(
"' already exists. Not renaming object ")
756 if (item->checkState() == Qt::Unchecked)
764 ps->getWorldNonConst()->removeObject(obj->id_);
778 robot_state::RobotState& cs = ps->getCurrentStateNonConst();
783 robot_state::AttachedBody* new_ab =
new robot_state::AttachedBody(
785 ab->getFixedTransforms(), ab->getTouchLinks(), ab->getDetachPosture());
786 cs.clearAttachedBody(ab->getName());
787 cs.attachBody(new_ab);
795 bool checked = item->checkState() == Qt::Checked;
797 moveit_msgs::AttachedCollisionObject aco;
803 for (std::size_t i = 0; i < links_std.size(); ++i)
804 links.append(QString::fromStdString(links_std[i]));
807 QInputDialog::getItem(
this, tr(
"Select Link Name"), tr(
"Choose the link to attach to:"), links, 0,
false, &ok);
811 item->setCheckState(Qt::Unchecked);
814 aco.link_name = response.toStdString();
815 aco.object.id = data.first;
816 aco.object.operation = moveit_msgs::CollisionObject::ADD;
821 const robot_state::AttachedBody* attached_body = ps->getCurrentState().getAttachedBody(data.first);
824 aco.link_name = attached_body->getAttachedLinkName();
825 aco.object.id = attached_body->getName();
826 aco.object.operation = moveit_msgs::CollisionObject::REMOVE;
838 ps->processAttachedCollisionObjectMsg(aco);
847 ui_->collision_objects_list->setUpdatesEnabled(
false);
848 bool oldState =
ui_->collision_objects_list->blockSignals(
true);
851 QList<QListWidgetItem*> sel =
ui_->collision_objects_list->selectedItems();
852 std::set<std::string> to_select;
853 for (
int i = 0; i < sel.size(); ++i)
854 to_select.insert(sel[i]->text().toStdString());
855 ui_->collision_objects_list->clear();
862 const std::vector<std::string>& collision_object_names = ps->getWorld()->getObjectIds();
863 for (std::size_t i = 0; i < collision_object_names.size(); ++i)
868 QListWidgetItem* item =
869 new QListWidgetItem(QString::fromStdString(collision_object_names[i]),
ui_->collision_objects_list, (
int)i);
870 item->setFlags(item->flags() | Qt::ItemIsEditable);
871 item->setToolTip(item->text());
872 item->setCheckState(Qt::Unchecked);
873 if (to_select.find(collision_object_names[i]) != to_select.end())
874 item->setSelected(
true);
875 ui_->collision_objects_list->addItem(item);
879 const robot_state::RobotState& cs = ps->getCurrentState();
880 std::vector<const robot_state::AttachedBody*> attached_bodies;
881 cs.getAttachedBodies(attached_bodies);
882 for (std::size_t i = 0; i < attached_bodies.size(); ++i)
884 QListWidgetItem* item =
885 new QListWidgetItem(QString::fromStdString(attached_bodies[i]->
getName()),
ui_->collision_objects_list,
886 (
int)(i + collision_object_names.size()));
887 item->setFlags(item->flags() | Qt::ItemIsEditable);
888 item->setToolTip(item->text());
889 item->setCheckState(Qt::Checked);
890 if (to_select.find(attached_bodies[i]->getName()) != to_select.end())
891 item->setSelected(
true);
892 ui_->collision_objects_list->addItem(item);
898 ui_->collision_objects_list->blockSignals(oldState);
899 ui_->collision_objects_list->setUpdatesEnabled(
true);
906 QFileDialog::getSaveFileName(
this, tr(
"Export Scene Geometry"), tr(
""), tr(
"Scene Geometry (*.scene)"));
917 std::string p = (path.length() < 7 || path.substr(path.length() - 6) !=
".scene") ? path +
".scene" : path;
918 std::ofstream fout(p.c_str());
921 ps->saveGeometryToStream(fout);
923 ROS_INFO(
"Saved current scene geometry to '%s'", p.c_str());
926 ROS_WARN(
"Unable to save current scene geometry to '%s'", p.c_str());
935 std::ifstream fin(path.c_str());
938 ps->loadGeometryFromStream(fin);
940 ROS_INFO(
"Loaded scene geometry from '%s'", path.c_str());
945 ROS_WARN(
"Unable to load scene geometry from '%s'", path.c_str());
952 QFileDialog::getOpenFileName(
this, tr(
"Import Scene Geometry"), tr(
""), tr(
"Scene Geometry (*.scene)"));
static const int ITEM_TYPE_QUERY
void updateCollisionObjectPose(bool update_marker_position)
const planning_scene_monitor::PlanningSceneMonitorPtr & getPlanningSceneMonitor()
long unsigned int known_collision_objects_version_
planning_scene_monitor::LockedPlanningSceneRW getPlanningSceneRW()
get write access to planning scene
void sceneScaleStartChange()
void collisionObjectChanged(QListWidgetItem *item)
void publish(const boost::shared_ptr< M > &message) const
void selectedCollisionObjectChanged()
void sceneScaleEndChange()
static QString decideStatusText(const collision_detection::CollisionWorld::ObjectConstPtr &obj)
Ogre::SceneNode * getSceneNode() const
static const std::string TAB_OBJECTS
void computeSaveQueryButtonClicked(const std::string &scene, const std::string &query_name)
void sceneScaleChanged(int value)
void createSceneInteractiveMarker()
void checkPlanningSceneTreeEnabledButtons()
std::string getName(void *handle)
void populatePlanningSceneTreeView()
robot_state::RobotStateConstPtr getQueryStartState() const
void constructPlanningRequest(moveit_msgs::MotionPlanRequest &mreq)
void computeExportAsText(const std::string &path)
INTERACTIVE_MARKERS_PUBLIC void autoComplete(visualization_msgs::InteractiveMarker &msg, bool enable_autocomplete_transparency=true)
void setQueryStartState(const robot_state::RobotState &start)
static const int ITEM_TYPE_SCENE
static const std::string OCTOMAP_NS
void computeSaveSceneButtonClicked()
void computeLoadSceneButtonClicked()
void removeObjectButtonClicked()
void setQueryGoalState(const robot_state::RobotState &goal)
World::ObjectConstPtr ObjectConstPtr
void attachDetachCollisionObject(QListWidgetItem *item)
void computeDeleteQueryButtonClickedHelper(QTreeWidgetItem *s)
void objectPoseValueChanged(double value)
void addBackgroundJob(const boost::function< void()> &job, const std::string &name)
void computeDeleteQueryButtonClicked()
void setItemSelectionInList(const std::string &item_name, bool selection, QListWidget *list)
void importFromTextButtonClicked()
void importResource(const std::string &path)
void renameCollisionObject(QListWidgetItem *item)
bool processMessage(const visualization_msgs::InteractiveMarker &message)
void importUrlButtonClicked()
void exportAsTextButtonClicked()
void imProcessFeedback(visualization_msgs::InteractiveMarkerFeedback &feedback)
void queueRenderSceneGeometry()
void clearSceneButtonClicked()
robot_state::RobotStateConstPtr getQueryGoalState() const
MotionPlanningDisplay * planning_display_
void importFileButtonClicked()
const std::string & shapeStringName(const Shape *shape)
Ui::MotionPlanningUI * ui_
void computeLoadQueryButtonClicked()
void addMainLoopJob(const boost::function< void()> &job)
queue the execution of this function for the next time the main update() loop gets called ...
const robot_model::RobotModelConstPtr & getRobotModel() const
std::vector< std::pair< std::string, bool > > known_collision_objects_
std::shared_ptr< rviz::InteractiveMarker > scene_marker_
ROSCPP_DECL std::string append(const std::string &left, const std::string &right)
void quaternionMsgToEigen(const geometry_msgs::Quaternion &m, Eigen::Quaterniond &e)
void setShowAxes(bool show)
ros::Publisher planning_scene_world_publisher_
rviz::DisplayContext * context_
void copySelectedCollisionObject()
collision_detection::CollisionWorld::ObjectConstPtr scaled_object_
void computeDeleteSceneButtonClicked()
void populateCollisionObjectsList()
moveit_warehouse::PlanningSceneStoragePtr planning_scene_storage_
visualization_msgs::InteractiveMarker make6DOFMarker(const std::string &name, const geometry_msgs::PoseStamped &stamped, double scale, bool orientation_fixed=false)
ros::Publisher planning_scene_publisher_
void addObject(const collision_detection::WorldPtr &world, const std::string &id, const shapes::ShapeConstPtr &shape, const Eigen::Affine3d &pose)
planning_scene_monitor::LockedPlanningSceneRO getPlanningSceneRO() const
get read-only access to planning scene
std::shared_ptr< const Shape > ShapeConstPtr
void computeImportFromText(const std::string &path)