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