Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <moveit/motion_planning_rviz_plugin/motion_planning_frame.h>
00038 #include <moveit/motion_planning_rviz_plugin/motion_planning_display.h>
00039
00040 #include <moveit/kinematic_constraints/utils.h>
00041 #include <moveit/robot_state/conversions.h>
00042
00043 #include <std_srvs/Empty.h>
00044
00045 #include "ui_motion_planning_rviz_plugin_frame.h"
00046
00047 namespace moveit_rviz_plugin
00048 {
00049 void MotionPlanningFrame::planButtonClicked()
00050 {
00051 planning_display_->addBackgroundJob(boost::bind(&MotionPlanningFrame::computePlanButtonClicked, this), "compute "
00052 "plan");
00053 }
00054
00055 void MotionPlanningFrame::executeButtonClicked()
00056 {
00057 ui_->execute_button->setEnabled(false);
00058
00059 planning_display_->spawnBackgroundJob(boost::bind(&MotionPlanningFrame::computeExecuteButtonClicked, this));
00060 }
00061
00062 void MotionPlanningFrame::planAndExecuteButtonClicked()
00063 {
00064 ui_->plan_and_execute_button->setEnabled(false);
00065 ui_->execute_button->setEnabled(false);
00066
00067 planning_display_->spawnBackgroundJob(boost::bind(&MotionPlanningFrame::computePlanAndExecuteButtonClicked, this));
00068 }
00069
00070 void MotionPlanningFrame::stopButtonClicked()
00071 {
00072 ui_->stop_button->setEnabled(false);
00073 planning_display_->addBackgroundJob(boost::bind(&MotionPlanningFrame::computeStopButtonClicked, this), "stop");
00074 }
00075
00076 void MotionPlanningFrame::allowReplanningToggled(bool checked)
00077 {
00078 if (move_group_)
00079 move_group_->allowReplanning(checked);
00080 }
00081
00082 void MotionPlanningFrame::allowLookingToggled(bool checked)
00083 {
00084 if (move_group_)
00085 move_group_->allowLooking(checked);
00086 }
00087
00088 void MotionPlanningFrame::pathConstraintsIndexChanged(int index)
00089 {
00090 if (move_group_)
00091 {
00092 if (index > 0)
00093 {
00094 std::string c = ui_->path_constraints_combo_box->itemText(index).toStdString();
00095 if (!move_group_->setPathConstraints(c))
00096 ROS_WARN_STREAM("Unable to set the path constraints: " << c);
00097 }
00098 else
00099 move_group_->clearPathConstraints();
00100 }
00101 }
00102
00103 void MotionPlanningFrame::onClearOctomapClicked()
00104 {
00105 std_srvs::Empty srv;
00106 clear_octomap_service_client_.call(srv);
00107 }
00108
00109 void MotionPlanningFrame::computePlanButtonClicked()
00110 {
00111 if (!move_group_)
00112 return;
00113
00114
00115 ui_->result_label->setText("Planning...");
00116
00117 configureForPlanning();
00118 current_plan_.reset(new moveit::planning_interface::MoveGroup::Plan());
00119 if (move_group_->plan(*current_plan_))
00120 {
00121 ui_->execute_button->setEnabled(true);
00122
00123
00124 ui_->result_label->setText(QString("Time: ").append(QString::number(current_plan_->planning_time_, 'f', 3)));
00125 }
00126 else
00127 {
00128 current_plan_.reset();
00129
00130
00131 ui_->result_label->setText("Failed");
00132 }
00133 Q_EMIT planningFinished();
00134 }
00135
00136 void MotionPlanningFrame::computeExecuteButtonClicked()
00137 {
00138 if (move_group_ && current_plan_)
00139 {
00140 ui_->stop_button->setEnabled(true);
00141 bool success = move_group_->execute(*current_plan_);
00142 onFinishedExecution(success);
00143 }
00144 }
00145
00146 void MotionPlanningFrame::computePlanAndExecuteButtonClicked()
00147 {
00148 if (!move_group_)
00149 return;
00150 configureForPlanning();
00151
00152
00153 move_group_->setStartStateToCurrentState();
00154 ui_->stop_button->setEnabled(true);
00155 bool success = move_group_->move();
00156 onFinishedExecution(success);
00157 ui_->plan_and_execute_button->setEnabled(true);
00158 }
00159
00160 void MotionPlanningFrame::computeStopButtonClicked()
00161 {
00162 if (move_group_)
00163 move_group_->stop();
00164 }
00165
00166 void MotionPlanningFrame::onFinishedExecution(bool success)
00167 {
00168
00169 if (success)
00170 ui_->result_label->setText("Executed");
00171 else
00172 ui_->result_label->setText(!ui_->stop_button->isEnabled() ? "Stopped" : "Failed");
00173
00174 ui_->stop_button->setEnabled(false);
00175
00176
00177 if (ui_->start_state_selection->currentText() == "<current>")
00178 {
00179 ros::Duration(1).sleep();
00180 useStartStateButtonClicked();
00181 }
00182 }
00183
00184 void MotionPlanningFrame::useStartStateButtonClicked()
00185 {
00186 robot_state::RobotState start = *planning_display_->getQueryStartState();
00187 updateQueryStateHelper(start, ui_->start_state_selection->currentText().toStdString());
00188 planning_display_->setQueryStartState(start);
00189 }
00190
00191 void MotionPlanningFrame::useGoalStateButtonClicked()
00192 {
00193 robot_state::RobotState goal = *planning_display_->getQueryGoalState();
00194 updateQueryStateHelper(goal, ui_->goal_state_selection->currentText().toStdString());
00195 planning_display_->setQueryGoalState(goal);
00196 }
00197
00198 void MotionPlanningFrame::updateQueryStateHelper(robot_state::RobotState& state, const std::string& v)
00199 {
00200 if (v == "<random>")
00201 {
00202 configureWorkspace();
00203 if (const robot_model::JointModelGroup* jmg =
00204 state.getJointModelGroup(planning_display_->getCurrentPlanningGroup()))
00205 state.setToRandomPositions(jmg);
00206 return;
00207 }
00208
00209 if (v == "<random valid>")
00210 {
00211 configureWorkspace();
00212
00213 if (const robot_model::JointModelGroup* jmg =
00214 state.getJointModelGroup(planning_display_->getCurrentPlanningGroup()))
00215 {
00216
00217 static const int MAX_ATTEMPTS = 100;
00218 int attempt_count = 0;
00219 while (attempt_count < MAX_ATTEMPTS)
00220 {
00221
00222 state.setToRandomPositions(jmg);
00223
00224 state.update();
00225
00226
00227 if (planning_display_->getPlanningSceneRO()->isStateValid(state, "", false))
00228 break;
00229
00230 attempt_count++;
00231 }
00232
00233 if (attempt_count >= MAX_ATTEMPTS)
00234 ROS_WARN("Unable to find a random collision free configuration after %d attempts", MAX_ATTEMPTS);
00235 }
00236 else
00237 {
00238 ROS_WARN_STREAM("Unable to get joint model group " << planning_display_->getCurrentPlanningGroup());
00239 }
00240 return;
00241 }
00242
00243 if (v == "<current>")
00244 {
00245 const planning_scene_monitor::LockedPlanningSceneRO& ps = planning_display_->getPlanningSceneRO();
00246 if (ps)
00247 state = ps->getCurrentState();
00248 return;
00249 }
00250
00251 if (v == "<same as goal>")
00252 {
00253 state = *planning_display_->getQueryGoalState();
00254 return;
00255 }
00256
00257 if (v == "<same as start>")
00258 {
00259 state = *planning_display_->getQueryStartState();
00260 return;
00261 }
00262
00263
00264 if (const robot_model::JointModelGroup* jmg = state.getJointModelGroup(planning_display_->getCurrentPlanningGroup()))
00265 state.setToDefaultValues(jmg, v);
00266 }
00267
00268 void MotionPlanningFrame::populatePlannersList(const moveit_msgs::PlannerInterfaceDescription& desc)
00269 {
00270 std::string group = planning_display_->getCurrentPlanningGroup();
00271 ui_->planning_algorithm_combo_box->clear();
00272
00273
00274 ui_->library_label->setText(QString::fromStdString(desc.name));
00275 ui_->library_label->setStyleSheet("QLabel { color : green; font: bold }");
00276
00277 bool found_group = false;
00278
00279 if (!group.empty())
00280 for (std::size_t i = 0; i < desc.planner_ids.size(); ++i)
00281 if (desc.planner_ids[i] == group)
00282 found_group = true;
00283 else if (desc.planner_ids[i].substr(0, group.length()) == group)
00284 {
00285 if (desc.planner_ids[i].size() > group.length() && desc.planner_ids[i][group.length()] == '[')
00286 {
00287 std::string id = desc.planner_ids[i].substr(group.length());
00288 if (id.size() > 2)
00289 {
00290 id.resize(id.length() - 1);
00291 ui_->planning_algorithm_combo_box->addItem(QString::fromStdString(id.substr(1)));
00292 }
00293 }
00294 }
00295 if (ui_->planning_algorithm_combo_box->count() == 0 && !found_group)
00296 for (std::size_t i = 0; i < desc.planner_ids.size(); ++i)
00297 ui_->planning_algorithm_combo_box->addItem(QString::fromStdString(desc.planner_ids[i]));
00298 ui_->planning_algorithm_combo_box->insertItem(0, "<unspecified>");
00299
00300
00301 const std::string& default_planner_config = move_group_->getDefaultPlannerId(found_group ? group : std::string());
00302 int defaultIndex = ui_->planning_algorithm_combo_box->findText(QString::fromStdString(default_planner_config));
00303 if (defaultIndex < 0)
00304 defaultIndex = 0;
00305 ui_->planning_algorithm_combo_box->setCurrentIndex(defaultIndex);
00306 }
00307
00308 void MotionPlanningFrame::populateConstraintsList()
00309 {
00310 if (move_group_)
00311 planning_display_->addMainLoopJob(
00312 boost::bind(&MotionPlanningFrame::populateConstraintsList, this, move_group_->getKnownConstraints()));
00313 }
00314
00315 void MotionPlanningFrame::populateConstraintsList(const std::vector<std::string>& constr)
00316 {
00317 ui_->path_constraints_combo_box->clear();
00318 ui_->path_constraints_combo_box->addItem("None");
00319 for (std::size_t i = 0; i < constr.size(); ++i)
00320 ui_->path_constraints_combo_box->addItem(QString::fromStdString(constr[i]));
00321 }
00322
00323 void MotionPlanningFrame::constructPlanningRequest(moveit_msgs::MotionPlanRequest& mreq)
00324 {
00325 mreq.group_name = planning_display_->getCurrentPlanningGroup();
00326 mreq.num_planning_attempts = ui_->planning_attempts->value();
00327 mreq.allowed_planning_time = ui_->planning_time->value();
00328 mreq.max_velocity_scaling_factor = ui_->velocity_scaling_factor->value();
00329 mreq.max_acceleration_scaling_factor = ui_->acceleration_scaling_factor->value();
00330 robot_state::robotStateToRobotStateMsg(*planning_display_->getQueryStartState(), mreq.start_state);
00331 mreq.workspace_parameters.min_corner.x = ui_->wcenter_x->value() - ui_->wsize_x->value() / 2.0;
00332 mreq.workspace_parameters.min_corner.y = ui_->wcenter_y->value() - ui_->wsize_y->value() / 2.0;
00333 mreq.workspace_parameters.min_corner.z = ui_->wcenter_z->value() - ui_->wsize_z->value() / 2.0;
00334 mreq.workspace_parameters.max_corner.x = ui_->wcenter_x->value() + ui_->wsize_x->value() / 2.0;
00335 mreq.workspace_parameters.max_corner.y = ui_->wcenter_y->value() + ui_->wsize_y->value() / 2.0;
00336 mreq.workspace_parameters.max_corner.z = ui_->wcenter_z->value() + ui_->wsize_z->value() / 2.0;
00337 robot_state::RobotStateConstPtr s = planning_display_->getQueryGoalState();
00338 const robot_state::JointModelGroup* jmg = s->getJointModelGroup(mreq.group_name);
00339 if (jmg)
00340 {
00341 mreq.goal_constraints.resize(1);
00342 mreq.goal_constraints[0] = kinematic_constraints::constructGoalConstraints(*s, jmg);
00343 }
00344 }
00345
00346 void MotionPlanningFrame::configureWorkspace()
00347 {
00348 robot_model::VariableBounds bx, by, bz;
00349 bx.position_bounded_ = by.position_bounded_ = bz.position_bounded_ = true;
00350
00351 robot_model::JointModel::Bounds b(3);
00352 bx.min_position_ = ui_->wcenter_x->value() - ui_->wsize_x->value() / 2.0;
00353 bx.max_position_ = ui_->wcenter_x->value() + ui_->wsize_x->value() / 2.0;
00354 by.min_position_ = ui_->wcenter_y->value() - ui_->wsize_y->value() / 2.0;
00355 by.max_position_ = ui_->wcenter_y->value() + ui_->wsize_y->value() / 2.0;
00356 bz.min_position_ = ui_->wcenter_z->value() - ui_->wsize_z->value() / 2.0;
00357 bz.max_position_ = ui_->wcenter_z->value() + ui_->wsize_z->value() / 2.0;
00358
00359 if (move_group_)
00360 move_group_->setWorkspace(bx.min_position_, by.min_position_, bz.min_position_, bx.max_position_, by.max_position_,
00361 bz.max_position_);
00362 planning_scene_monitor::PlanningSceneMonitorPtr psm = planning_display_->getPlanningSceneMonitor();
00363
00364 if (psm && psm->getRobotModelLoader() && psm->getRobotModelLoader()->getModel())
00365 {
00366 const robot_model::RobotModelPtr& kmodel = psm->getRobotModelLoader()->getModel();
00367 const std::vector<robot_model::JointModel*>& jm = kmodel->getJointModels();
00368 for (std::size_t i = 0; i < jm.size(); ++i)
00369 if (jm[i]->getType() == robot_model::JointModel::PLANAR)
00370 {
00371 jm[i]->setVariableBounds(jm[i]->getName() + "/" + jm[i]->getLocalVariableNames()[0], bx);
00372 jm[i]->setVariableBounds(jm[i]->getName() + "/" + jm[i]->getLocalVariableNames()[1], by);
00373 }
00374 else if (jm[i]->getType() == robot_model::JointModel::FLOATING)
00375 {
00376 jm[i]->setVariableBounds(jm[i]->getName() + "/" + jm[i]->getLocalVariableNames()[0], bx);
00377 jm[i]->setVariableBounds(jm[i]->getName() + "/" + jm[i]->getLocalVariableNames()[1], by);
00378 jm[i]->setVariableBounds(jm[i]->getName() + "/" + jm[i]->getLocalVariableNames()[2], bz);
00379 }
00380 }
00381 }
00382
00383 void MotionPlanningFrame::configureForPlanning()
00384 {
00385 move_group_->setStartState(*planning_display_->getQueryStartState());
00386 move_group_->setJointValueTarget(*planning_display_->getQueryGoalState());
00387 move_group_->setPlanningTime(ui_->planning_time->value());
00388 move_group_->setNumPlanningAttempts(ui_->planning_attempts->value());
00389 move_group_->setMaxVelocityScalingFactor(ui_->velocity_scaling_factor->value());
00390 move_group_->setMaxAccelerationScalingFactor(ui_->acceleration_scaling_factor->value());
00391 configureWorkspace();
00392 if (static_cast<bool>(planning_display_))
00393 planning_display_->dropVisualizedTrajectory();
00394 }
00395
00396 void MotionPlanningFrame::remotePlanCallback(const std_msgs::EmptyConstPtr& msg)
00397 {
00398 planButtonClicked();
00399 }
00400
00401 void MotionPlanningFrame::remoteExecuteCallback(const std_msgs::EmptyConstPtr& msg)
00402 {
00403 executeButtonClicked();
00404 }
00405
00406 void MotionPlanningFrame::remoteUpdateStartStateCallback(const std_msgs::EmptyConstPtr& msg)
00407 {
00408 if (move_group_ && planning_display_)
00409 {
00410 robot_state::RobotState state = *planning_display_->getQueryStartState();
00411 const planning_scene_monitor::LockedPlanningSceneRO& ps = planning_display_->getPlanningSceneRO();
00412 if (ps)
00413 {
00414 state = ps->getCurrentState();
00415 planning_display_->setQueryStartState(state);
00416 }
00417 }
00418 }
00419
00420 void MotionPlanningFrame::remoteUpdateGoalStateCallback(const std_msgs::EmptyConstPtr& msg)
00421 {
00422 if (move_group_ && planning_display_)
00423 {
00424 robot_state::RobotState state = *planning_display_->getQueryStartState();
00425 const planning_scene_monitor::LockedPlanningSceneRO& ps = planning_display_->getPlanningSceneRO();
00426 if (ps)
00427 {
00428 state = ps->getCurrentState();
00429 planning_display_->setQueryGoalState(state);
00430 }
00431 }
00432 }
00433 }