motion_planning_frame.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2012, Willow Garage, Inc.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of Willow Garage nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *********************************************************************/
00034 
00035 /* Author: Ioan Sucan */
00036 
00037 #include <moveit/motion_planning_rviz_plugin/motion_planning_frame.h>
00038 #include <moveit/motion_planning_rviz_plugin/motion_planning_display.h>
00039 #include <moveit/move_group/capability_names.h>
00040 
00041 #include <geometric_shapes/shape_operations.h>
00042 
00043 #include <rviz/display_context.h>
00044 #include <rviz/frame_manager.h>
00045 
00046 #include <std_srvs/Empty.h>
00047 
00048 #include <QMessageBox>
00049 #include <QInputDialog>
00050 #include <QShortcut>
00051 
00052 #include "ui_motion_planning_rviz_plugin_frame.h"
00053 
00054 namespace moveit_rviz_plugin
00055 {
00056 MotionPlanningFrame::MotionPlanningFrame(MotionPlanningDisplay* pdisplay, rviz::DisplayContext* context,
00057                                          QWidget* parent)
00058   : QWidget(parent)
00059   , planning_display_(pdisplay)
00060   , context_(context)
00061   , ui_(new Ui::MotionPlanningUI())
00062   , first_time_(true)
00063   , clear_octomap_service_client_(nh_.serviceClient<std_srvs::Empty>(move_group::CLEAR_OCTOMAP_SERVICE_NAME))
00064 {
00065   // set up the GUI
00066   ui_->setupUi(this);
00067 
00068   // connect bottons to actions; each action usually registers the function pointer for the actual computation,
00069   // to keep the GUI more responsive (using the background job processing)
00070   connect(ui_->plan_button, SIGNAL(clicked()), this, SLOT(planButtonClicked()));
00071   connect(ui_->execute_button, SIGNAL(clicked()), this, SLOT(executeButtonClicked()));
00072   connect(ui_->plan_and_execute_button, SIGNAL(clicked()), this, SLOT(planAndExecuteButtonClicked()));
00073   connect(ui_->stop_button, SIGNAL(clicked()), this, SLOT(stopButtonClicked()));
00074   connect(ui_->use_start_state_button, SIGNAL(clicked()), this, SLOT(useStartStateButtonClicked()));
00075   connect(ui_->use_goal_state_button, SIGNAL(clicked()), this, SLOT(useGoalStateButtonClicked()));
00076   connect(ui_->database_connect_button, SIGNAL(clicked()), this, SLOT(databaseConnectButtonClicked()));
00077   connect(ui_->save_scene_button, SIGNAL(clicked()), this, SLOT(saveSceneButtonClicked()));
00078   connect(ui_->save_query_button, SIGNAL(clicked()), this, SLOT(saveQueryButtonClicked()));
00079   connect(ui_->delete_scene_button, SIGNAL(clicked()), this, SLOT(deleteSceneButtonClicked()));
00080   connect(ui_->delete_query_button, SIGNAL(clicked()), this, SLOT(deleteQueryButtonClicked()));
00081   connect(ui_->planning_scene_tree, SIGNAL(itemSelectionChanged()), this, SLOT(planningSceneItemClicked()));
00082   connect(ui_->load_scene_button, SIGNAL(clicked()), this, SLOT(loadSceneButtonClicked()));
00083   connect(ui_->load_query_button, SIGNAL(clicked()), this, SLOT(loadQueryButtonClicked()));
00084   connect(ui_->allow_looking, SIGNAL(toggled(bool)), this, SLOT(allowLookingToggled(bool)));
00085   connect(ui_->allow_replanning, SIGNAL(toggled(bool)), this, SLOT(allowReplanningToggled(bool)));
00086   connect(ui_->allow_external_program, SIGNAL(toggled(bool)), this, SLOT(allowExternalProgramCommunication(bool)));
00087   connect(ui_->planning_algorithm_combo_box, SIGNAL(currentIndexChanged(int)), this,
00088           SLOT(planningAlgorithmIndexChanged(int)));
00089   connect(ui_->import_file_button, SIGNAL(clicked()), this, SLOT(importFileButtonClicked()));
00090   connect(ui_->import_url_button, SIGNAL(clicked()), this, SLOT(importUrlButtonClicked()));
00091   connect(ui_->clear_scene_button, SIGNAL(clicked()), this, SLOT(clearSceneButtonClicked()));
00092   connect(ui_->scene_scale, SIGNAL(valueChanged(int)), this, SLOT(sceneScaleChanged(int)));
00093   connect(ui_->scene_scale, SIGNAL(sliderPressed()), this, SLOT(sceneScaleStartChange()));
00094   connect(ui_->scene_scale, SIGNAL(sliderReleased()), this, SLOT(sceneScaleEndChange()));
00095   connect(ui_->remove_object_button, SIGNAL(clicked()), this, SLOT(removeObjectButtonClicked()));
00096   connect(ui_->object_x, SIGNAL(valueChanged(double)), this, SLOT(objectPoseValueChanged(double)));
00097   connect(ui_->object_y, SIGNAL(valueChanged(double)), this, SLOT(objectPoseValueChanged(double)));
00098   connect(ui_->object_z, SIGNAL(valueChanged(double)), this, SLOT(objectPoseValueChanged(double)));
00099   connect(ui_->object_rx, SIGNAL(valueChanged(double)), this, SLOT(objectPoseValueChanged(double)));
00100   connect(ui_->object_ry, SIGNAL(valueChanged(double)), this, SLOT(objectPoseValueChanged(double)));
00101   connect(ui_->object_rz, SIGNAL(valueChanged(double)), this, SLOT(objectPoseValueChanged(double)));
00102   connect(ui_->publish_current_scene_button, SIGNAL(clicked()), this, SLOT(publishSceneButtonClicked()));
00103   connect(ui_->collision_objects_list, SIGNAL(itemSelectionChanged()), this, SLOT(selectedCollisionObjectChanged()));
00104   connect(ui_->collision_objects_list, SIGNAL(itemChanged(QListWidgetItem*)), this,
00105           SLOT(collisionObjectChanged(QListWidgetItem*)));
00106   connect(ui_->path_constraints_combo_box, SIGNAL(currentIndexChanged(int)), this,
00107           SLOT(pathConstraintsIndexChanged(int)));
00108   connect(ui_->clear_octomap_button, SIGNAL(clicked()), this, SLOT(onClearOctomapClicked()));
00109   connect(ui_->planning_scene_tree, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this,
00110           SLOT(warehouseItemNameChanged(QTreeWidgetItem*, int)));
00111   connect(ui_->reset_db_button, SIGNAL(clicked()), this, SLOT(resetDbButtonClicked()));
00112   connect(ui_->export_scene_text_button, SIGNAL(clicked()), this, SLOT(exportAsTextButtonClicked()));
00113   connect(ui_->import_scene_text_button, SIGNAL(clicked()), this, SLOT(importFromTextButtonClicked()));
00114   connect(ui_->load_state_button, SIGNAL(clicked()), this, SLOT(loadStateButtonClicked()));
00115   connect(ui_->save_start_state_button, SIGNAL(clicked()), this, SLOT(saveStartStateButtonClicked()));
00116   connect(ui_->save_goal_state_button, SIGNAL(clicked()), this, SLOT(saveGoalStateButtonClicked()));
00117   connect(ui_->set_as_start_state_button, SIGNAL(clicked()), this, SLOT(setAsStartStateButtonClicked()));
00118   connect(ui_->set_as_goal_state_button, SIGNAL(clicked()), this, SLOT(setAsGoalStateButtonClicked()));
00119   connect(ui_->remove_state_button, SIGNAL(clicked()), this, SLOT(removeStateButtonClicked()));
00120   connect(ui_->clear_states_button, SIGNAL(clicked()), this, SLOT(clearStatesButtonClicked()));
00121   connect(ui_->approximate_ik, SIGNAL(stateChanged(int)), this, SLOT(approximateIKChanged(int)));
00122 
00123   connect(ui_->detect_objects_button, SIGNAL(clicked()), this, SLOT(detectObjectsButtonClicked()));
00124   connect(ui_->pick_button, SIGNAL(clicked()), this, SLOT(pickObjectButtonClicked()));
00125   connect(ui_->place_button, SIGNAL(clicked()), this, SLOT(placeObjectButtonClicked()));
00126   connect(ui_->detected_objects_list, SIGNAL(itemSelectionChanged()), this, SLOT(selectedDetectedObjectChanged()));
00127   connect(ui_->detected_objects_list, SIGNAL(itemChanged(QListWidgetItem*)), this,
00128           SLOT(detectedObjectChanged(QListWidgetItem*)));
00129   connect(ui_->support_surfaces_list, SIGNAL(itemSelectionChanged()), this, SLOT(selectedSupportSurfaceChanged()));
00130 
00131   connect(ui_->tabWidget, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int)));
00132 
00133   QShortcut* copy_object_shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_C), ui_->collision_objects_list);
00134   connect(copy_object_shortcut, SIGNAL(activated()), this, SLOT(copySelectedCollisionObject()));
00135 
00136   ui_->reset_db_button->hide();
00137   ui_->background_job_progress->hide();
00138   ui_->background_job_progress->setMaximum(0);
00139 
00140   ui_->tabWidget->setCurrentIndex(0);
00141 
00142   known_collision_objects_version_ = 0;
00143 
00144   planning_scene_publisher_ = nh_.advertise<moveit_msgs::PlanningScene>("planning_scene", 1);
00145   planning_scene_world_publisher_ = nh_.advertise<moveit_msgs::PlanningSceneWorld>("planning_scene_world", 1);
00146 
00147   //  object_recognition_trigger_publisher_ = nh_.advertise<std_msgs::Bool>("recognize_objects_switch", 1);
00148   object_recognition_client_.reset(new actionlib::SimpleActionClient<object_recognition_msgs::ObjectRecognitionAction>(
00149       OBJECT_RECOGNITION_ACTION, false));
00150   object_recognition_subscriber_ =
00151       nh_.subscribe("recognized_object_array", 1, &MotionPlanningFrame::listenDetectedObjects, this);
00152 
00153   if (object_recognition_client_)
00154   {
00155     try
00156     {
00157       waitForAction(object_recognition_client_, nh_, ros::Duration(3.0), OBJECT_RECOGNITION_ACTION);
00158     }
00159     catch (std::runtime_error& ex)
00160     {
00161       //      ROS_ERROR("Object recognition action: %s", ex.what());
00162       object_recognition_client_.reset();
00163     }
00164   }
00165   try
00166   {
00167     planning_scene_interface_.reset(new moveit::planning_interface::PlanningSceneInterface());
00168   }
00169   catch (std::runtime_error& ex)
00170   {
00171     ROS_ERROR("%s", ex.what());
00172   }
00173 
00174   try
00175   {
00176     const planning_scene_monitor::LockedPlanningSceneRO& ps = planning_display_->getPlanningSceneRO();
00177     if (ps)
00178     {
00179       semantic_world_.reset(new moveit::semantic_world::SemanticWorld(ps));
00180     }
00181     else
00182       semantic_world_.reset();
00183     if (semantic_world_)
00184     {
00185       semantic_world_->addTableCallback(boost::bind(&MotionPlanningFrame::updateTables, this));
00186     }
00187   }
00188   catch (std::runtime_error& ex)
00189   {
00190     ROS_ERROR("%s", ex.what());
00191   }
00192 }
00193 
00194 MotionPlanningFrame::~MotionPlanningFrame()
00195 {
00196 }
00197 
00198 void MotionPlanningFrame::approximateIKChanged(int state)
00199 {
00200   planning_display_->useApproximateIK(state == Qt::Checked);
00201 }
00202 
00203 void MotionPlanningFrame::setItemSelectionInList(const std::string& item_name, bool selection, QListWidget* list)
00204 {
00205   QList<QListWidgetItem*> found_items = list->findItems(QString(item_name.c_str()), Qt::MatchExactly);
00206   for (std::size_t i = 0; i < found_items.size(); ++i)
00207     found_items[i]->setSelected(selection);
00208 }
00209 
00210 void MotionPlanningFrame::allowExternalProgramCommunication(bool enable)
00211 {
00212   planning_display_->getRobotInteraction()->toggleMoveInteractiveMarkerTopic(enable);
00213   planning_display_->toggleSelectPlanningGroupSubscription(enable);
00214   if (enable)
00215   {
00216     ros::NodeHandle nh;
00217     plan_subscriber_ = nh.subscribe("/rviz/moveit/plan", 1, &MotionPlanningFrame::remotePlanCallback, this);
00218     execute_subscriber_ = nh.subscribe("/rviz/moveit/execute", 1, &MotionPlanningFrame::remoteExecuteCallback, this);
00219     update_start_state_subscriber_ =
00220         nh.subscribe("/rviz/moveit/update_start_state", 1, &MotionPlanningFrame::remoteUpdateStartStateCallback, this);
00221     update_goal_state_subscriber_ =
00222         nh.subscribe("/rviz/moveit/update_goal_state", 1, &MotionPlanningFrame::remoteUpdateGoalStateCallback, this);
00223   }
00224   else
00225   {  // disable
00226     plan_subscriber_.shutdown();
00227     execute_subscriber_.shutdown();
00228     update_start_state_subscriber_.shutdown();
00229     update_goal_state_subscriber_.shutdown();
00230   }
00231 }
00232 
00233 void MotionPlanningFrame::fillStateSelectionOptions()
00234 {
00235   ui_->start_state_selection->clear();
00236   ui_->goal_state_selection->clear();
00237 
00238   if (!planning_display_->getPlanningSceneMonitor())
00239     return;
00240 
00241   const robot_model::RobotModelConstPtr& kmodel = planning_display_->getRobotModel();
00242   std::string group = planning_display_->getCurrentPlanningGroup();
00243   if (group.empty())
00244     return;
00245   const robot_model::JointModelGroup* jmg = kmodel->getJointModelGroup(group);
00246   if (jmg)
00247   {
00248     ui_->start_state_selection->addItem(QString("<random valid>"));
00249     ui_->start_state_selection->addItem(QString("<random>"));
00250     ui_->start_state_selection->addItem(QString("<current>"));
00251     ui_->start_state_selection->addItem(QString("<same as goal>"));
00252 
00253     ui_->goal_state_selection->addItem(QString("<random valid>"));
00254     ui_->goal_state_selection->addItem(QString("<random>"));
00255     ui_->goal_state_selection->addItem(QString("<current>"));
00256     ui_->goal_state_selection->addItem(QString("<same as start>"));
00257 
00258     const std::vector<std::string>& known_states = jmg->getDefaultStateNames();
00259     if (!known_states.empty())
00260     {
00261       ui_->start_state_selection->insertSeparator(ui_->start_state_selection->count());
00262       ui_->goal_state_selection->insertSeparator(ui_->goal_state_selection->count());
00263       for (std::size_t i = 0; i < known_states.size(); ++i)
00264       {
00265         ui_->start_state_selection->addItem(QString::fromStdString(known_states[i]));
00266         ui_->goal_state_selection->addItem(QString::fromStdString(known_states[i]));
00267       }
00268     }
00269     ui_->start_state_selection->setCurrentIndex(2);  // default to 'current'
00270     ui_->goal_state_selection->setCurrentIndex(0);   // default to 'random valid'
00271   }
00272 }
00273 
00274 void MotionPlanningFrame::changePlanningGroupHelper()
00275 {
00276   if (!planning_display_->getPlanningSceneMonitor())
00277     return;
00278 
00279   planning_display_->addMainLoopJob(boost::bind(&MotionPlanningFrame::fillStateSelectionOptions, this));
00280   planning_display_->addMainLoopJob(
00281       boost::bind(&MotionPlanningFrame::populateConstraintsList, this, std::vector<std::string>()));
00282 
00283   const robot_model::RobotModelConstPtr& kmodel = planning_display_->getRobotModel();
00284   std::string group = planning_display_->getCurrentPlanningGroup();
00285 
00286   if (!group.empty() && kmodel)
00287   {
00288     if (move_group_ && move_group_->getName() == group)
00289       return;
00290     ROS_INFO("Constructing new MoveGroup connection for group '%s' in namespace '%s'", group.c_str(),
00291              planning_display_->getMoveGroupNS().c_str());
00292     moveit::planning_interface::MoveGroup::Options opt(group);
00293     opt.robot_model_ = kmodel;
00294     opt.robot_description_.clear();
00295     opt.node_handle_ = ros::NodeHandle(planning_display_->getMoveGroupNS());
00296     try
00297     {
00298       move_group_.reset(new moveit::planning_interface::MoveGroup(opt, context_->getFrameManager()->getTFClientPtr(),
00299                                                                   ros::WallDuration(30, 0)));
00300       if (planning_scene_storage_)
00301         move_group_->setConstraintsDatabase(ui_->database_host->text().toStdString(), ui_->database_port->value());
00302     }
00303     catch (std::runtime_error& ex)
00304     {
00305       ROS_ERROR("%s", ex.what());
00306     }
00307     if (move_group_)
00308     {
00309       move_group_->allowLooking(ui_->allow_looking->isChecked());
00310       move_group_->allowReplanning(ui_->allow_replanning->isChecked());
00311       moveit_msgs::PlannerInterfaceDescription desc;
00312       if (move_group_->getInterfaceDescription(desc))
00313         planning_display_->addMainLoopJob(boost::bind(&MotionPlanningFrame::populatePlannersList, this, desc));
00314       planning_display_->addBackgroundJob(boost::bind(&MotionPlanningFrame::populateConstraintsList, this),
00315                                           "populateConstraintsList");
00316 
00317       if (first_time_)
00318       {
00319         first_time_ = false;
00320         const planning_scene_monitor::LockedPlanningSceneRO& ps = planning_display_->getPlanningSceneRO();
00321         if (ps)
00322         {
00323           planning_display_->setQueryStartState(ps->getCurrentState());
00324           planning_display_->setQueryGoalState(ps->getCurrentState());
00325         }
00326       }
00327     }
00328   }
00329 }
00330 
00331 void MotionPlanningFrame::changePlanningGroup()
00332 {
00333   planning_display_->addBackgroundJob(boost::bind(&MotionPlanningFrame::changePlanningGroupHelper, this),
00334                                       "Frame::changePlanningGroup");
00335 }
00336 
00337 void MotionPlanningFrame::sceneUpdate(planning_scene_monitor::PlanningSceneMonitor::SceneUpdateType update_type)
00338 {
00339   if (update_type & planning_scene_monitor::PlanningSceneMonitor::UPDATE_GEOMETRY)
00340     planning_display_->addMainLoopJob(boost::bind(&MotionPlanningFrame::populateCollisionObjectsList, this));
00341 }
00342 
00343 void MotionPlanningFrame::importResource(const std::string& path)
00344 {
00345   if (planning_display_->getPlanningSceneMonitor())
00346   {
00347     shapes::Mesh* mesh = shapes::createMeshFromResource(path);
00348     if (mesh)
00349     {
00350       std::size_t slash = path.find_last_of("/\\");
00351       std::string name = path.substr(slash + 1);
00352       shapes::ShapeConstPtr shape(mesh);
00353       Eigen::Affine3d pose;
00354       pose.setIdentity();
00355 
00356       if (planning_display_->getPlanningSceneRO()->getCurrentState().hasAttachedBody(name))
00357       {
00358         QMessageBox::warning(this, QString("Duplicate names"), QString("An attached object named '")
00359                                                                    .append(name.c_str())
00360                                                                    .append("' already exists. Please rename the "
00361                                                                            "attached object before importing."));
00362         return;
00363       }
00364 
00365       // If the object already exists, ask the user whether to overwrite or rename
00366       if (planning_display_->getPlanningSceneRO()->getWorld()->hasObject(name))
00367       {
00368         QMessageBox msgBox;
00369         msgBox.setText("There exists another object with the same name.");
00370         msgBox.setInformativeText("Would you like to overwrite it?");
00371         msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
00372         msgBox.setDefaultButton(QMessageBox::No);
00373         int ret = msgBox.exec();
00374 
00375         switch (ret)
00376         {
00377           case QMessageBox::Yes:
00378             // Overwrite was clicked
00379             {
00380               planning_scene_monitor::LockedPlanningSceneRW ps = planning_display_->getPlanningSceneRW();
00381               if (ps)
00382               {
00383                 ps->getWorldNonConst()->removeObject(name);
00384                 addObject(ps->getWorldNonConst(), name, shape, pose);
00385               }
00386             }
00387             break;
00388           case QMessageBox::No:
00389           {
00390             // Don't overwrite was clicked. Ask for another name
00391             bool ok = false;
00392             QString text = QInputDialog::getText(
00393                 this, tr("Choose a new name"), tr("Import the new object under the name:"), QLineEdit::Normal,
00394                 QString::fromStdString(name + "-" + boost::lexical_cast<std::string>(
00395                                                         planning_display_->getPlanningSceneRO()->getWorld()->size())),
00396                 &ok);
00397             if (ok)
00398             {
00399               if (!text.isEmpty())
00400               {
00401                 name = text.toStdString();
00402                 planning_scene_monitor::LockedPlanningSceneRW ps = planning_display_->getPlanningSceneRW();
00403                 if (ps)
00404                 {
00405                   if (ps->getWorld()->hasObject(name))
00406                     QMessageBox::warning(
00407                         this, "Name already exists",
00408                         QString("The name '").append(name.c_str()).append("' already exists. Not importing object."));
00409                   else
00410                     addObject(ps->getWorldNonConst(), name, shape, pose);
00411                 }
00412               }
00413               else
00414                 QMessageBox::warning(this, "Object not imported", "Cannot use an empty name for an imported object");
00415             }
00416             break;
00417           }
00418           default:
00419             // Pressed cancel, do nothing
00420             break;
00421         }
00422       }
00423       else
00424       {
00425         planning_scene_monitor::LockedPlanningSceneRW ps = planning_display_->getPlanningSceneRW();
00426         if (ps)
00427           addObject(ps->getWorldNonConst(), name, shape, pose);
00428       }
00429     }
00430     else
00431     {
00432       QMessageBox::warning(this, QString("Import error"), QString("Unable to import scene"));
00433       return;
00434     }
00435   }
00436 }
00437 
00438 void MotionPlanningFrame::enable()
00439 {
00440   ui_->planning_algorithm_combo_box->clear();
00441   ui_->library_label->setText("NO PLANNING LIBRARY LOADED");
00442   ui_->library_label->setStyleSheet("QLabel { color : red; font: bold }");
00443   ui_->object_status->setText("");
00444 
00445   // activate the frame
00446   parentWidget()->show();
00447   show();
00448 }
00449 
00450 void MotionPlanningFrame::disable()
00451 {
00452   move_group_.reset();
00453   parentWidget()->hide();
00454   hide();
00455 }
00456 
00457 void MotionPlanningFrame::tabChanged(int index)
00458 {
00459   if (scene_marker_ && ui_->tabWidget->tabText(index).toStdString() != TAB_OBJECTS)
00460     scene_marker_.reset();
00461   else if (ui_->tabWidget->tabText(index).toStdString() == TAB_OBJECTS)
00462     selectedCollisionObjectChanged();
00463 }
00464 
00465 void MotionPlanningFrame::updateSceneMarkers(float wall_dt, float ros_dt)
00466 {
00467   if (scene_marker_)
00468     scene_marker_->update(wall_dt);
00469 }
00470 
00471 void MotionPlanningFrame::updateExternalCommunication()
00472 {
00473   if (ui_->allow_external_program->isChecked())
00474   {
00475     planning_display_->getRobotInteraction()->toggleMoveInteractiveMarkerTopic(true);
00476   }
00477 }
00478 
00479 }  // namespace


visualization
Author(s): Ioan Sucan , Dave Coleman , Sachin Chitta
autogenerated on Wed Jun 19 2019 19:24:59