moveit2
The MoveIt Motion Planning Framework for ROS 2.
Loading...
Searching...
No Matches
motion_planning_frame_planning.cpp
Go to the documentation of this file.
1/*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2012, 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 */
36
40
43
44#include <std_srvs/srv/empty.hpp>
45#include <moveit_msgs/msg/robot_state.hpp>
46#include <tf2_eigen/tf2_eigen.hpp>
48
49#include "ui_motion_planning_rviz_plugin_frame.h"
50
51namespace moveit_rviz_plugin
52{
53
54void MotionPlanningFrame::planButtonClicked()
55{
56 publishSceneIfNeeded();
57 planning_display_->addBackgroundJob([this] { computePlanButtonClicked(); }, "compute plan");
58}
59
60void MotionPlanningFrame::executeButtonClicked()
61{
62 ui_->execute_button->setEnabled(false);
63 // execution is done in a separate thread, to not block other background jobs by blocking for synchronous execution
64 planning_display_->spawnBackgroundJob([this] { computeExecuteButtonClicked(); });
65}
66
67void MotionPlanningFrame::planAndExecuteButtonClicked()
68{
69 publishSceneIfNeeded();
70 ui_->plan_and_execute_button->setEnabled(false);
71 ui_->execute_button->setEnabled(false);
72 // execution is done in a separate thread, to not block other background jobs by blocking for synchronous execution
73 planning_display_->spawnBackgroundJob([this] { computePlanAndExecuteButtonClicked(); });
74}
75
76void MotionPlanningFrame::stopButtonClicked()
77{
78 ui_->stop_button->setEnabled(false); // avoid clicking again
79 planning_display_->addBackgroundJob([this] { computeStopButtonClicked(); }, "stop");
80}
81
82void MotionPlanningFrame::allowReplanningToggled(bool checked)
83{
84 if (move_group_)
85 move_group_->allowReplanning(checked);
86}
87
88void MotionPlanningFrame::allowLookingToggled(bool checked)
89{
90 if (move_group_)
91 move_group_->allowLooking(checked);
92}
93
94void MotionPlanningFrame::pathConstraintsIndexChanged(int index)
95{
96 if (move_group_)
97 {
98 if (index > 0)
99 {
100 std::string c = ui_->path_constraints_combo_box->itemText(index).toStdString();
101 if (!move_group_->setPathConstraints(c))
102 {
103 RCLCPP_WARN_STREAM(logger_, "Unable to set the path constraints: " << c);
104 }
105 }
106 else
107 {
108 move_group_->clearPathConstraints();
109 }
110 }
111}
112
113void MotionPlanningFrame::onClearOctomapClicked()
114{
115 auto req = std::make_shared<std_srvs::srv::Empty::Request>();
116 auto result = clear_octomap_service_client_->async_send_request(req);
117
118 if (result.wait_for(std::chrono::seconds(0)) != std::future_status::ready)
119 {
120 RCLCPP_ERROR(logger_, "Failed to call clear_octomap_service");
121 }
122 ui_->clear_octomap_button->setEnabled(false);
123}
124
125bool MotionPlanningFrame::computeCartesianPlan()
126{
127 rclcpp::Time start = rclcpp::Clock().now();
128 // get goal pose
129 moveit::core::RobotState goal = *planning_display_->getQueryGoalState();
130 std::vector<geometry_msgs::msg::Pose> waypoints;
131 const std::string& link_name = move_group_->getEndEffectorLink();
132 const moveit::core::LinkModel* link = move_group_->getRobotModel()->getLinkModel(link_name);
133 if (!link)
134 {
135 RCLCPP_ERROR_STREAM(logger_, "Failed to determine unique end-effector link: " << link_name);
136 return false;
137 }
138 waypoints.push_back(tf2::toMsg(goal.getGlobalLinkTransform(link)));
139
140 // setup default params
141 double cart_step_size = 0.01;
142 bool avoid_collisions = true;
143
144 // compute trajectory
145 moveit_msgs::msg::RobotTrajectory trajectory;
146 double fraction = move_group_->computeCartesianPath(waypoints, cart_step_size, trajectory, avoid_collisions);
147
148 if (fraction >= 1.0)
149 {
150 RCLCPP_INFO(logger_, "Achieved %f %% of Cartesian path", fraction * 100.);
151
152 // Compute time parameterization to also provide velocities
153 // https://groups.google.com/forum/#!topic/moveit-users/MOoFxy2exT4
154 robot_trajectory::RobotTrajectory rt(move_group_->getRobotModel(), move_group_->getName());
155 rt.setRobotTrajectoryMsg(*move_group_->getCurrentState(), trajectory);
156 trajectory_processing::TimeOptimalTrajectoryGeneration time_parameterization;
157 bool success = time_parameterization.computeTimeStamps(rt, ui_->velocity_scaling_factor->value(),
158 ui_->acceleration_scaling_factor->value());
159 RCLCPP_INFO(logger_, "Computing time stamps %s", success ? "SUCCEEDED" : "FAILED");
160
161 // Store trajectory in current_plan_
162 current_plan_ = std::make_shared<moveit::planning_interface::MoveGroupInterface::Plan>();
163 rt.getRobotTrajectoryMsg(current_plan_->trajectory);
164 current_plan_->planning_time = (rclcpp::Clock().now() - start).seconds();
165 return success;
166 }
167 return false;
168}
169
170bool MotionPlanningFrame::computeJointSpacePlan()
171{
172 current_plan_ = std::make_shared<moveit::planning_interface::MoveGroupInterface::Plan>();
173 return move_group_->plan(*current_plan_) == moveit::core::MoveItErrorCode::SUCCESS;
174}
175
176void MotionPlanningFrame::computePlanButtonClicked()
177{
178 if (!move_group_)
179 return;
180
181 // Clear status
182 ui_->result_label->setText("Planning...");
183
184 configureForPlanning();
185 planning_display_->rememberPreviousStartState();
186 bool success = (ui_->use_cartesian_path->isEnabled() && ui_->use_cartesian_path->checkState()) ?
187 computeCartesianPlan() :
188 computeJointSpacePlan();
189
190 if (success)
191 {
192 ui_->execute_button->setEnabled(true);
193 ui_->result_label->setText(QString("Time: ").append(QString::number(current_plan_->planning_time, 'f', 3)));
194 }
195 else
196 {
197 current_plan_.reset();
198 ui_->result_label->setText("Failed");
199 }
200 Q_EMIT planningFinished();
201}
202
203void MotionPlanningFrame::computeExecuteButtonClicked()
204{
205 // ensures the MoveGroupInterface is not destroyed while executing
206 moveit::planning_interface::MoveGroupInterfacePtr mgi(move_group_);
207 if (mgi && current_plan_)
208 {
209 ui_->stop_button->setEnabled(true); // enable stopping
210 bool success = mgi->execute(*current_plan_) == moveit::core::MoveItErrorCode::SUCCESS;
211 onFinishedExecution(success);
212 }
213}
214
215void MotionPlanningFrame::computePlanAndExecuteButtonClicked()
216{
217 // ensures the MoveGroupInterface is not destroyed while executing
218 moveit::planning_interface::MoveGroupInterfacePtr mgi(move_group_);
219 if (!mgi)
220 return;
221 configureForPlanning();
222 planning_display_->rememberPreviousStartState();
223 // move_group::move() on the server side, will always start from the current state
224 // to suppress a warning, we pass an empty state (which encodes "start from current state")
225 mgi->setStartStateToCurrentState();
226 ui_->stop_button->setEnabled(true);
227 if (ui_->use_cartesian_path->isEnabled() && ui_->use_cartesian_path->checkState())
228 {
229 if (computeCartesianPlan())
230 computeExecuteButtonClicked();
231 }
232 else
233 {
234 bool success = mgi->move() == moveit::core::MoveItErrorCode::SUCCESS;
235 onFinishedExecution(success);
236 }
237 ui_->plan_and_execute_button->setEnabled(true);
238}
239
240void MotionPlanningFrame::computeStopButtonClicked()
241{
242 if (move_group_)
243 move_group_->stop();
244}
245
246void MotionPlanningFrame::onFinishedExecution(bool success)
247{
248 // visualize result of execution
249 if (success)
250 {
251 ui_->result_label->setText("Executed");
252 }
253 else
254 {
255 ui_->result_label->setText(!ui_->stop_button->isEnabled() ? "Stopped" : "Failed");
256 }
257 // disable stop button
258 ui_->stop_button->setEnabled(false);
259
260 // update query start state to current if necessary
261 if (ui_->start_state_combo_box->currentText() == "<current>")
262 startStateTextChanged(ui_->start_state_combo_box->currentText());
263
264 // auto-update goal to stored previous state (but only on success)
265 // on failure, the user must update the goal to the previous state himself
266 if (ui_->goal_state_combo_box->currentText() == "<previous>")
267 goalStateTextChanged(ui_->goal_state_combo_box->currentText());
268}
269
270void MotionPlanningFrame::onNewPlanningSceneState()
271{
272 moveit::core::RobotState current(planning_display_->getPlanningSceneRO()->getCurrentState());
273 if (ui_->start_state_combo_box->currentText() == "<current>")
274 {
275 planning_display_->setQueryStartState(current);
276 planning_display_->rememberPreviousStartState();
277 }
278 if (ui_->goal_state_combo_box->currentText() == "<current>")
279 planning_display_->setQueryGoalState(current);
280}
281
282void MotionPlanningFrame::startStateTextChanged(const QString& start_state)
283{
284 // use background job: fetching the current state might take up to a second
285 planning_display_->addBackgroundJob([this, state = start_state.toStdString()] { startStateTextChangedExec(state); },
286 "update start state");
287}
288
289void MotionPlanningFrame::startStateTextChangedExec(const std::string& start_state)
290{
291 moveit::core::RobotState start = *planning_display_->getQueryStartState();
292 updateQueryStateHelper(start, start_state);
293 planning_display_->setQueryStartState(start);
294}
295
296void MotionPlanningFrame::goalStateTextChanged(const QString& goal_state)
297{
298 // use background job: fetching the current state might take up to a second
299 planning_display_->addBackgroundJob([this, state = goal_state.toStdString()] { goalStateTextChangedExec(state); },
300 "update goal state");
301}
302
303void MotionPlanningFrame::goalStateTextChangedExec(const std::string& goal_state)
304{
305 moveit::core::RobotState goal = *planning_display_->getQueryGoalState();
306 updateQueryStateHelper(goal, goal_state);
307 planning_display_->setQueryGoalState(goal);
308}
309
310void MotionPlanningFrame::planningGroupTextChanged(const QString& planning_group)
311{
312 planning_display_->changePlanningGroup(planning_group.toStdString());
313}
314
315void MotionPlanningFrame::updateQueryStateHelper(moveit::core::RobotState& state, const std::string& v)
316{
317 if (v == "<random>")
318 {
319 configureWorkspace();
320 if (const moveit::core::JointModelGroup* jmg =
321 state.getJointModelGroup(planning_display_->getCurrentPlanningGroup()))
322 state.setToRandomPositions(jmg);
323 return;
324 }
325
326 if (v == "<random valid>")
327 {
328 configureWorkspace();
329
330 if (const moveit::core::JointModelGroup* jmg =
331 state.getJointModelGroup(planning_display_->getCurrentPlanningGroup()))
332 {
333 // Loop until a collision free state is found
334 static const int MAX_ATTEMPTS = 100;
335 int attempt_count = 0; // prevent loop for going forever
336 while (attempt_count < MAX_ATTEMPTS)
337 {
338 // Generate random state
339 state.setToRandomPositions(jmg);
340
341 state.update(); // prevent dirty transforms
342
343 // Test for collision
344 if (planning_display_->getPlanningSceneRO()->isStateValid(state, "", false))
345 break;
346
347 attempt_count++;
348 }
349 // Explain if no valid rand state found
350 if (attempt_count >= MAX_ATTEMPTS)
351 RCLCPP_WARN(logger_, "Unable to find a random collision free configuration after %d attempts", MAX_ATTEMPTS);
352 }
353 else
354 {
355 RCLCPP_WARN_STREAM(logger_, "Unable to get joint model group " << planning_display_->getCurrentPlanningGroup());
356 }
357 return;
358 }
359
360 if (v == "<current>")
361 {
362 rclcpp::Time t = node_->now();
363 planning_display_->waitForCurrentRobotState(t);
364 const planning_scene_monitor::LockedPlanningSceneRO& ps = planning_display_->getPlanningSceneRO();
365 if (ps)
366 state = ps->getCurrentState();
367 return;
368 }
369
370 if (v == "<same as goal>")
371 {
372 state = *planning_display_->getQueryGoalState();
373 return;
374 }
375
376 if (v == "<same as start>")
377 {
378 state = *planning_display_->getQueryStartState();
379 return;
380 }
381
382 if (v == "<previous>")
383 {
384 state = planning_display_->getPreviousState();
385 return;
386 }
387
388 // maybe it is a named state
389 if (const moveit::core::JointModelGroup* jmg = state.getJointModelGroup(planning_display_->getCurrentPlanningGroup()))
390 state.setToDefaultValues(jmg, v);
391}
392
393void MotionPlanningFrame::populatePlannersList(const std::vector<moveit_msgs::msg::PlannerInterfaceDescription>& desc)
394{
395 ui_->planning_pipeline_combo_box->clear();
396
398 size_t default_planner_index = 0;
399 for (auto& d : planner_descriptions_)
400 {
401 QString item_text(d.pipeline_id.c_str());
402 // Check for default planning pipeline
403 if (d.pipeline_id == default_planning_pipeline_)
404 {
405 if (item_text.isEmpty())
406 item_text = QString::fromStdString(d.name);
407 default_planner_index = ui_->planning_pipeline_combo_box->count();
408 }
409 ui_->planning_pipeline_combo_box->addItem(item_text);
410 }
411 QFont font;
412 font.setBold(true);
413 ui_->planning_pipeline_combo_box->setItemData(default_planner_index, font, Qt::FontRole);
414
415 // Select default pipeline - triggers populatePlannerDescription() via callback
416 if (!planner_descriptions_.empty())
417 ui_->planning_pipeline_combo_box->setCurrentIndex(default_planner_index);
418}
419
420void MotionPlanningFrame::populatePlannerDescription(const moveit_msgs::msg::PlannerInterfaceDescription& desc)
421{
422 std::string group = planning_display_->getCurrentPlanningGroup();
423 RCLCPP_DEBUG(logger_, "Found %zu planners for group '%s' and pipeline '%s'", desc.planner_ids.size(), group.c_str(),
424 desc.pipeline_id.c_str());
425 ui_->planning_algorithm_combo_box->clear();
426
427 // set the label for the planning library
428 ui_->library_label->setText(QString::fromStdString(desc.name));
429 ui_->library_label->setStyleSheet("QLabel { color : green; font: bold }");
430
431 bool found_group = false;
432 // the name of a planner is either "GROUP[planner_id]" or "planner_id"
433 if (!group.empty())
434 {
435 for (const std::string& planner_id : desc.planner_ids)
436 {
437 RCLCPP_DEBUG(logger_, "planner id: %s", planner_id.c_str());
438 if (planner_id == group)
439 {
440 found_group = true;
441 }
442 else if (planner_id.substr(0, group.length()) == group)
443 {
444 if (planner_id.size() > group.length() && planner_id[group.length()] == '[')
445 {
446 std::string id = planner_id.substr(group.length());
447 if (id.size() > 2)
448 {
449 id.resize(id.length() - 1);
450 ui_->planning_algorithm_combo_box->addItem(QString::fromStdString(id.substr(1)));
451 }
452 }
453 }
454 }
455 }
456 if (ui_->planning_algorithm_combo_box->count() == 0 && !found_group)
457 {
458 for (const std::string& planner_id : desc.planner_ids)
459 ui_->planning_algorithm_combo_box->addItem(QString::fromStdString(planner_id));
460 }
461
462 ui_->planning_algorithm_combo_box->insertItem(0, "<unspecified>");
463
464 // retrieve default planner config from parameter server
465 const std::string& default_planner_config = move_group_->getDefaultPlannerId(found_group ? group : std::string());
466 int default_index = ui_->planning_algorithm_combo_box->findText(QString::fromStdString(default_planner_config));
467 if (default_index < 0)
468 default_index = 0; // 0 is <unspecified> fallback
469 ui_->planning_algorithm_combo_box->setCurrentIndex(default_index);
470
471 QFont font;
472 font.setBold(true);
473 ui_->planning_algorithm_combo_box->setItemData(default_index, font, Qt::FontRole);
474}
475
476void MotionPlanningFrame::populateConstraintsList()
477{
478 if (move_group_)
479 planning_display_->addMainLoopJob([this]() { populateConstraintsList(move_group_->getKnownConstraints()); });
480}
481
482void MotionPlanningFrame::populateConstraintsList(const std::vector<std::string>& constr)
483{
484 ui_->path_constraints_combo_box->clear();
485 ui_->path_constraints_combo_box->addItem("None");
486 for (const std::string& constraint : constr)
487 ui_->path_constraints_combo_box->addItem(QString::fromStdString(constraint));
488}
489
490void MotionPlanningFrame::constructPlanningRequest(moveit_msgs::msg::MotionPlanRequest& mreq)
491{
492 mreq.group_name = planning_display_->getCurrentPlanningGroup();
493 mreq.num_planning_attempts = ui_->planning_attempts->value();
494 mreq.allowed_planning_time = ui_->planning_time->value();
495 mreq.max_velocity_scaling_factor = ui_->velocity_scaling_factor->value();
496 mreq.max_acceleration_scaling_factor = ui_->acceleration_scaling_factor->value();
497 moveit::core::robotStateToRobotStateMsg(*planning_display_->getQueryStartState(), mreq.start_state);
498 mreq.workspace_parameters.min_corner.x = ui_->wcenter_x->value() - ui_->wsize_x->value() / 2.0;
499 mreq.workspace_parameters.min_corner.y = ui_->wcenter_y->value() - ui_->wsize_y->value() / 2.0;
500 mreq.workspace_parameters.min_corner.z = ui_->wcenter_z->value() - ui_->wsize_z->value() / 2.0;
501 mreq.workspace_parameters.max_corner.x = ui_->wcenter_x->value() + ui_->wsize_x->value() / 2.0;
502 mreq.workspace_parameters.max_corner.y = ui_->wcenter_y->value() + ui_->wsize_y->value() / 2.0;
503 mreq.workspace_parameters.max_corner.z = ui_->wcenter_z->value() + ui_->wsize_z->value() / 2.0;
504 moveit::core::RobotStateConstPtr s = planning_display_->getQueryGoalState();
505 const moveit::core::JointModelGroup* jmg = s->getJointModelGroup(mreq.group_name);
506 if (jmg)
507 {
508 mreq.goal_constraints.resize(1);
509 mreq.goal_constraints[0] = kinematic_constraints::constructGoalConstraints(*s, jmg);
510 }
511}
512
513void MotionPlanningFrame::configureWorkspace()
514{
517
519 bx.min_position_ = ui_->wcenter_x->value() - ui_->wsize_x->value() / 2.0;
520 bx.max_position_ = ui_->wcenter_x->value() + ui_->wsize_x->value() / 2.0;
521 by.min_position_ = ui_->wcenter_y->value() - ui_->wsize_y->value() / 2.0;
522 by.max_position_ = ui_->wcenter_y->value() + ui_->wsize_y->value() / 2.0;
523 bz.min_position_ = ui_->wcenter_z->value() - ui_->wsize_z->value() / 2.0;
524 bz.max_position_ = ui_->wcenter_z->value() + ui_->wsize_z->value() / 2.0;
525
526 if (move_group_)
527 {
529 bz.max_position_);
530 }
531 planning_scene_monitor::PlanningSceneMonitorPtr psm = planning_display_->getPlanningSceneMonitor();
532 // get non-const access to the robot_model and update planar & floating joints as indicated by the workspace settings
533 if (psm && psm->getRobotModelLoader() && psm->getRobotModelLoader()->getModel())
534 {
535 const moveit::core::RobotModelPtr& robot_model = psm->getRobotModelLoader()->getModel();
536 const std::vector<moveit::core::JointModel*>& jm = robot_model->getJointModels();
537 for (moveit::core::JointModel* joint : jm)
538 {
539 if (joint->getType() == moveit::core::JointModel::PLANAR)
540 {
541 joint->setVariableBounds(joint->getName() + "/" + joint->getLocalVariableNames()[0], bx);
542 joint->setVariableBounds(joint->getName() + "/" + joint->getLocalVariableNames()[1], by);
543 }
544 else if (joint->getType() == moveit::core::JointModel::FLOATING)
545 {
546 joint->setVariableBounds(joint->getName() + "/" + joint->getLocalVariableNames()[0], bx);
547 joint->setVariableBounds(joint->getName() + "/" + joint->getLocalVariableNames()[1], by);
548 joint->setVariableBounds(joint->getName() + "/" + joint->getLocalVariableNames()[2], bz);
549 }
550 }
551 }
552}
553
554void MotionPlanningFrame::configureForPlanning()
555{
556 move_group_->setStartState(*planning_display_->getQueryStartState());
557 move_group_->setJointValueTarget(*planning_display_->getQueryGoalState());
558 move_group_->setPlanningTime(ui_->planning_time->value());
559 move_group_->setNumPlanningAttempts(ui_->planning_attempts->value());
560 move_group_->setMaxVelocityScalingFactor(ui_->velocity_scaling_factor->value());
561 move_group_->setMaxAccelerationScalingFactor(ui_->acceleration_scaling_factor->value());
562 configureWorkspace();
563 if (static_cast<bool>(planning_display_))
564 planning_display_->dropVisualizedTrajectory();
565}
566
567void MotionPlanningFrame::remotePlanCallback(const std_msgs::msg::Empty::ConstSharedPtr& /*msg*/)
568{
569 planButtonClicked();
570}
571
572void MotionPlanningFrame::remoteExecuteCallback(const std_msgs::msg::Empty::ConstSharedPtr& /*msg*/)
573{
574 executeButtonClicked();
575}
576
577void MotionPlanningFrame::remoteStopCallback(const std_msgs::msg::Empty::ConstSharedPtr& /*msg*/)
578{
579 stopButtonClicked();
580}
581
582void MotionPlanningFrame::remoteUpdateStartStateCallback(const std_msgs::msg::Empty::ConstSharedPtr& /*msg*/)
583{
585 {
586 planning_display_->waitForCurrentRobotState(node_->get_clock()->now());
587 const planning_scene_monitor::LockedPlanningSceneRO& ps = planning_display_->getPlanningSceneRO();
588 if (ps)
589 {
590 moveit::core::RobotState state = ps->getCurrentState();
591 planning_display_->setQueryStartState(state);
592 }
593 }
594}
595
596void MotionPlanningFrame::remoteUpdateGoalStateCallback(const std_msgs::msg::Empty::ConstSharedPtr& /*msg*/)
597{
599 {
600 planning_display_->waitForCurrentRobotState(node_->get_clock()->now());
601 const planning_scene_monitor::LockedPlanningSceneRO& ps = planning_display_->getPlanningSceneRO();
602 if (ps)
603 {
604 moveit::core::RobotState state = ps->getCurrentState();
605 planning_display_->setQueryGoalState(state);
606 }
607 }
608}
609
610void MotionPlanningFrame::remoteUpdateCustomStartStateCallback(const moveit_msgs::msg::RobotState::ConstSharedPtr& msg)
611{
612 moveit_msgs::msg::RobotState msg_no_attached(*msg);
613 msg_no_attached.attached_collision_objects.clear();
614 msg_no_attached.is_diff = true;
616 {
617 planning_display_->waitForCurrentRobotState(node_->get_clock()->now());
618 const planning_scene_monitor::LockedPlanningSceneRO& ps = planning_display_->getPlanningSceneRO();
619 if (ps)
620 {
621 auto state = std::make_shared<moveit::core::RobotState>(ps->getCurrentState());
622 moveit::core::robotStateMsgToRobotState(ps->getTransforms(), msg_no_attached, *state);
623 planning_display_->setQueryStartState(*state);
624 }
625 }
626}
627
628void MotionPlanningFrame::remoteUpdateCustomGoalStateCallback(const moveit_msgs::msg::RobotState::ConstSharedPtr& msg)
629{
630 moveit_msgs::msg::RobotState msg_no_attached(*msg);
631 msg_no_attached.attached_collision_objects.clear();
632 msg_no_attached.is_diff = true;
634 {
635 planning_display_->waitForCurrentRobotState(node_->get_clock()->now());
636 const planning_scene_monitor::LockedPlanningSceneRO& ps = planning_display_->getPlanningSceneRO();
637 if (ps)
638 {
639 auto state = std::make_shared<moveit::core::RobotState>(ps->getCurrentState());
640 moveit::core::robotStateMsgToRobotState(ps->getTransforms(), msg_no_attached, *state);
641 planning_display_->setQueryGoalState(*state);
642 }
643 }
644}
645} // namespace moveit_rviz_plugin
A joint from the robot. Models the transform that this joint applies in the kinematic chain....
std::vector< VariableBounds > Bounds
The datatype for the joint bounds.
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...
const Eigen::Isometry3d & getGlobalLinkTransform(const std::string &link_name)
Get the link transform w.r.t. the root link (model frame) of the RobotModel. This is typically the ro...
moveit::planning_interface::MoveGroupInterface::PlanPtr current_plan_
std::vector< moveit_msgs::msg::PlannerInterfaceDescription > planner_descriptions_
moveit::planning_interface::MoveGroupInterfacePtr move_group_
void constructPlanningRequest(moveit_msgs::msg::MotionPlanRequest &mreq)
const planning_scene_monitor::PlanningSceneMonitorPtr & getPlanningSceneMonitor()
bool computeTimeStamps(robot_trajectory::RobotTrajectory &trajectory, const double max_velocity_scaling_factor=1.0, const double max_acceleration_scaling_factor=1.0) const override
Compute a trajectory with waypoints spaced equally in time (according to resample_dt_)....
moveit_msgs::msg::Constraints constructGoalConstraints(const moveit::core::RobotState &state, const moveit::core::JointModelGroup *jmg, double tolerance_below, double tolerance_above)
Generates a constraint message intended to be used as a goal constraint for a joint group....
Definition utils.cpp:152
void robotStateToRobotStateMsg(const RobotState &state, moveit_msgs::msg::RobotState &robot_state, bool copy_attached_bodies=true)
Convert a MoveIt robot state to a robot state message.
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.
std::string append(const std::string &left, const std::string &right)