trajectory_execution_manager.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 
39 #include <moveit_ros_planning/TrajectoryExecutionDynamicReconfigureConfig.h>
41 #include <dynamic_reconfigure/server.h>
42 #include <tf2_eigen/tf2_eigen.h>
43 
44 // Name of this class for logging
45 static const std::string LOGNAME = "trajectory_execution_manager";
46 
48 {
49 const std::string TrajectoryExecutionManager::EXECUTION_EVENT_TOPIC = "trajectory_execution_event";
50 
52 static const double DEFAULT_CONTROLLER_GOAL_DURATION_MARGIN = 0.5; // allow 0.5s more than the expected execution time
53  // before triggering a trajectory cancel (applied
54  // after scaling)
56  1.1; // allow the execution of a trajectory to take more time than expected (scaled by a value > 1)
57 
58 using namespace moveit_ros_planning;
59 
61 {
62 public:
64  : owner_(owner), dynamic_reconfigure_server_(ros::NodeHandle("~/trajectory_execution"))
65  {
66  dynamic_reconfigure_server_.setCallback(
67  [this](const auto& config, uint32_t level) { dynamicReconfigureCallback(config, level); });
68  }
69 
70 private:
71  void dynamicReconfigureCallback(const TrajectoryExecutionDynamicReconfigureConfig& config, uint32_t /*level*/)
72  {
73  owner_->enableExecutionDurationMonitoring(config.execution_duration_monitoring);
74  owner_->setAllowedExecutionDurationScaling(config.allowed_execution_duration_scaling);
75  owner_->setAllowedGoalDurationMargin(config.allowed_goal_duration_margin);
76  owner_->setExecutionVelocityScaling(config.execution_velocity_scaling);
77  owner_->setAllowedStartTolerance(config.allowed_start_tolerance);
78  owner_->setWaitForTrajectoryCompletion(config.wait_for_trajectory_completion);
79  }
80 
82  dynamic_reconfigure::Server<TrajectoryExecutionDynamicReconfigureConfig> dynamic_reconfigure_server_;
83 };
84 
85 TrajectoryExecutionManager::TrajectoryExecutionManager(const moveit::core::RobotModelConstPtr& robot_model,
86  const planning_scene_monitor::CurrentStateMonitorPtr& csm)
87  : robot_model_(robot_model), csm_(csm), node_handle_("~")
88 {
89  if (!node_handle_.getParam("moveit_manage_controllers", manage_controllers_))
90  manage_controllers_ = false;
91 
92  initialize();
93 }
94 
95 TrajectoryExecutionManager::TrajectoryExecutionManager(const moveit::core::RobotModelConstPtr& robot_model,
96  const planning_scene_monitor::CurrentStateMonitorPtr& csm,
97  bool manage_controllers)
98  : robot_model_(robot_model), csm_(csm), node_handle_("~"), manage_controllers_(manage_controllers)
99 {
100  initialize();
101 }
102 
104 {
105  stopExecution(true);
106  delete reconfigure_impl_;
107 }
108 
110 {
111  reconfigure_impl_ = nullptr;
112  verbose_ = false;
113  execution_complete_ = true;
114  current_context_ = -1;
119 
122 
123  // load controller-specific values for allowed_execution_duration_scaling and allowed_goal_duration_margin
125 
126  // load the controller manager plugin
127  try
128  {
130  std::make_unique<pluginlib::ClassLoader<moveit_controller_manager::MoveItControllerManager>>(
131  "moveit_core", "moveit_controller_manager::MoveItControllerManager");
132  }
134  {
135  ROS_FATAL_STREAM_NAMED(LOGNAME, "Exception while creating controller manager plugin loader: " << ex.what());
136  return;
137  }
138 
140  {
141  std::string controller;
142  if (!node_handle_.getParam("moveit_controller_manager", controller))
143  {
144  const std::vector<std::string>& classes = controller_manager_loader_->getDeclaredClasses();
145  if (classes.size() == 1)
146  {
147  controller = classes[0];
149  "Parameter '~moveit_controller_manager' is not specified but only one "
150  "matching plugin was found: '%s'. Using that one.",
151  controller.c_str());
152  }
153  else
154  ROS_FATAL_NAMED(LOGNAME, "Parameter '~moveit_controller_manager' not specified. This is needed to "
155  "identify the plugin to use for interacting with controllers. No paths can "
156  "be executed.");
157  }
158 
159  if (!controller.empty())
160  try
161  {
162  controller_manager_ = controller_manager_loader_->createUniqueInstance(controller);
163  }
165  {
167  "Exception while loading controller manager '" << controller << "': " << ex.what());
168  }
169  }
170 
171  // other configuration steps
173 
176 
178 
180  ROS_INFO_NAMED(LOGNAME, "Trajectory execution is managing controllers");
181  else
182  ROS_INFO_NAMED(LOGNAME, "Trajectory execution is not managing controllers");
183 }
184 
186 {
188 }
189 
191 {
193 }
194 
196 {
198 }
199 
201 {
202  execution_velocity_scaling_ = scaling;
203 }
204 
206 {
208 }
209 
211 {
213 }
214 
216 {
217  return manage_controllers_;
218 }
219 
220 const moveit_controller_manager::MoveItControllerManagerPtr& TrajectoryExecutionManager::getControllerManager() const
221 {
222  return controller_manager_;
223 }
224 
225 void TrajectoryExecutionManager::processEvent(const std::string& event)
226 {
227  if (event == "stop")
228  stopExecution(true);
229  else
230  ROS_WARN_STREAM_NAMED(LOGNAME, "Unknown event type: '" << event << "'");
231 }
232 
233 void TrajectoryExecutionManager::receiveEvent(const std_msgs::StringConstPtr& event)
234 {
235  ROS_INFO_STREAM_NAMED(LOGNAME, "Received event '" << event->data << "'");
236  processEvent(event->data);
237 }
238 
239 bool TrajectoryExecutionManager::push(const moveit_msgs::RobotTrajectory& trajectory, const std::string& controller)
240 {
241  if (controller.empty())
242  return push(trajectory, std::vector<std::string>());
243  else
244  return push(trajectory, std::vector<std::string>(1, controller));
245 }
246 
247 bool TrajectoryExecutionManager::push(const trajectory_msgs::JointTrajectory& trajectory, const std::string& controller)
248 {
249  if (controller.empty())
250  return push(trajectory, std::vector<std::string>());
251  else
252  return push(trajectory, std::vector<std::string>(1, controller));
253 }
254 
255 bool TrajectoryExecutionManager::push(const trajectory_msgs::JointTrajectory& trajectory,
256  const std::vector<std::string>& controllers)
257 {
258  moveit_msgs::RobotTrajectory traj;
259  traj.joint_trajectory = trajectory;
260  return push(traj, controllers);
261 }
262 
263 bool TrajectoryExecutionManager::push(const moveit_msgs::RobotTrajectory& trajectory,
264  const std::vector<std::string>& controllers)
265 {
266  if (!execution_complete_)
267  {
268  ROS_ERROR_NAMED(LOGNAME, "Cannot push a new trajectory while another is being executed");
269  return false;
270  }
271 
273  if (configure(*context, trajectory, controllers))
274  {
275  if (verbose_)
276  {
277  std::stringstream ss;
278  ss << "Pushed trajectory for execution using controllers [ ";
279  for (const std::string& controller : context->controllers_)
280  ss << controller << " ";
281  ss << "]:" << std::endl;
282  for (const moveit_msgs::RobotTrajectory& trajectory_part : context->trajectory_parts_)
283  ss << trajectory_part << std::endl;
284  ROS_INFO_NAMED(LOGNAME, "%s", ss.str().c_str());
285  }
286  trajectories_.push_back(context);
287  return true;
288  }
289  else
290  {
291  delete context;
293  }
294 
295  return false;
296 }
297 
299 {
300  known_controllers_.clear();
302  {
303  std::vector<std::string> names;
304  controller_manager_->getControllersList(names);
305  for (const std::string& name : names)
306  {
307  std::vector<std::string> joints;
308  controller_manager_->getControllerJoints(name, joints);
310  ci.name_ = name;
311  ci.joints_.insert(joints.begin(), joints.end());
312  known_controllers_[ci.name_] = ci;
313  }
314 
315  for (std::map<std::string, ControllerInformation>::iterator it = known_controllers_.begin();
316  it != known_controllers_.end(); ++it)
317  for (std::map<std::string, ControllerInformation>::iterator jt = known_controllers_.begin();
318  jt != known_controllers_.end(); ++jt)
319  if (it != jt)
320  {
321  std::vector<std::string> intersect;
322  std::set_intersection(it->second.joints_.begin(), it->second.joints_.end(), jt->second.joints_.begin(),
323  jt->second.joints_.end(), std::back_inserter(intersect));
324  if (!intersect.empty())
325  {
326  it->second.overlapping_controllers_.insert(jt->first);
327  jt->second.overlapping_controllers_.insert(it->first);
328  }
329  }
330  }
331 }
332 
333 void TrajectoryExecutionManager::updateControllerState(const std::string& controller, const ros::Duration& age)
334 {
335  std::map<std::string, ControllerInformation>::iterator it = known_controllers_.find(controller);
336  if (it != known_controllers_.end())
337  updateControllerState(it->second, age);
338  else
339  ROS_ERROR_NAMED(LOGNAME, "Controller '%s' is not known.", controller.c_str());
340 }
341 
343 {
344  if (ros::Time::now() - ci.last_update_ >= age)
345  {
347  {
348  if (verbose_)
349  ROS_INFO_NAMED(LOGNAME, "Updating information for controller '%s'.", ci.name_.c_str());
350  ci.state_ = controller_manager_->getControllerState(ci.name_);
352  }
353  }
354  else if (verbose_)
355  ROS_INFO_NAMED(LOGNAME, "Information for controller '%s' is assumed to be up to date.", ci.name_.c_str());
356 }
357 
359 {
360  for (std::pair<const std::string, ControllerInformation>& known_controller : known_controllers_)
361  updateControllerState(known_controller.second, age);
362 }
363 
364 bool TrajectoryExecutionManager::checkControllerCombination(std::vector<std::string>& selected,
365  const std::set<std::string>& actuated_joints)
366 {
367  std::set<std::string> combined_joints;
368  for (const std::string& controller : selected)
369  {
370  const ControllerInformation& ci = known_controllers_[controller];
371  combined_joints.insert(ci.joints_.begin(), ci.joints_.end());
372  }
373 
374  if (verbose_)
375  {
376  std::stringstream ss, saj, sac;
377  for (const std::string& controller : selected)
378  ss << controller << " ";
379  for (const std::string& actuated_joint : actuated_joints)
380  saj << actuated_joint << " ";
381  for (const std::string& combined_joint : combined_joints)
382  sac << combined_joint << " ";
383  ROS_INFO_NAMED(LOGNAME, "Checking if controllers [ %s] operating on joints [ %s] cover joints [ %s]",
384  ss.str().c_str(), sac.str().c_str(), saj.str().c_str());
385  }
386 
387  return std::includes(combined_joints.begin(), combined_joints.end(), actuated_joints.begin(), actuated_joints.end());
388 }
389 
390 void TrajectoryExecutionManager::generateControllerCombination(std::size_t start_index, std::size_t controller_count,
391  const std::vector<std::string>& available_controllers,
392  std::vector<std::string>& selected_controllers,
393  std::vector<std::vector<std::string>>& selected_options,
394  const std::set<std::string>& actuated_joints)
395 {
396  if (selected_controllers.size() == controller_count)
397  {
398  if (checkControllerCombination(selected_controllers, actuated_joints))
399  selected_options.push_back(selected_controllers);
400  return;
401  }
402 
403  for (std::size_t i = start_index; i < available_controllers.size(); ++i)
404  {
405  bool overlap = false;
406  const ControllerInformation& ci = known_controllers_[available_controllers[i]];
407  for (std::size_t j = 0; j < selected_controllers.size() && !overlap; ++j)
408  {
409  if (ci.overlapping_controllers_.find(selected_controllers[j]) != ci.overlapping_controllers_.end())
410  overlap = true;
411  }
412  if (overlap)
413  continue;
414  selected_controllers.push_back(available_controllers[i]);
415  generateControllerCombination(i + 1, controller_count, available_controllers, selected_controllers,
416  selected_options, actuated_joints);
417  selected_controllers.pop_back();
418  }
419 }
420 
421 namespace
422 {
423 struct OrderPotentialControllerCombination
424 {
425  bool operator()(const std::size_t a, const std::size_t b) const
426  {
427  // preference is given to controllers marked as default
428  if (nrdefault[a] > nrdefault[b])
429  return true;
430  if (nrdefault[a] < nrdefault[b])
431  return false;
432 
433  // and then to ones that operate on fewer joints
434  if (nrjoints[a] < nrjoints[b])
435  return true;
436  if (nrjoints[a] > nrjoints[b])
437  return false;
438 
439  // and then to active ones
440  if (nractive[a] < nractive[b])
441  return true;
442  if (nractive[a] > nractive[b])
443  return false;
444 
445  return false;
446  }
447 
448  std::vector<std::vector<std::string>> selected_options;
449  std::vector<std::size_t> nrdefault;
450  std::vector<std::size_t> nrjoints;
451  std::vector<std::size_t> nractive;
452 };
453 } // namespace
454 
455 bool TrajectoryExecutionManager::findControllers(const std::set<std::string>& actuated_joints,
456  std::size_t controller_count,
457  const std::vector<std::string>& available_controllers,
458  std::vector<std::string>& selected_controllers)
459 {
460  // generate all combinations of controller_count controllers that operate on disjoint sets of joints
461  std::vector<std::string> work_area;
462  OrderPotentialControllerCombination order;
463  std::vector<std::vector<std::string>>& selected_options = order.selected_options;
464  generateControllerCombination(0, controller_count, available_controllers, work_area, selected_options,
465  actuated_joints);
466 
467  if (verbose_)
468  {
469  std::stringstream saj;
470  std::stringstream sac;
471  for (const std::string& available_controller : available_controllers)
472  sac << available_controller << " ";
473  for (const std::string& actuated_joint : actuated_joints)
474  saj << actuated_joint << " ";
475  ROS_INFO_NAMED(LOGNAME, "Looking for %zu controllers among [ %s] that cover joints [ %s]. Found %zd options.",
476  controller_count, sac.str().c_str(), saj.str().c_str(), selected_options.size());
477  }
478 
479  // if none was found, this is a problem
480  if (selected_options.empty())
481  return false;
482 
483  // if only one was found, return it
484  if (selected_options.size() == 1)
485  {
486  selected_controllers.swap(selected_options[0]);
487  return true;
488  }
489 
490  // if more options were found, evaluate them all and return the best one
491 
492  // count how many default controllers are used in each reported option, and how many joints are actuated in total by
493  // the selected controllers,
494  // to use that in the ranking of the options
495  order.nrdefault.resize(selected_options.size(), 0);
496  order.nrjoints.resize(selected_options.size(), 0);
497  order.nractive.resize(selected_options.size(), 0);
498  for (std::size_t i = 0; i < selected_options.size(); ++i)
499  {
500  for (std::size_t k = 0; k < selected_options[i].size(); ++k)
501  {
504 
505  if (ci.state_.default_)
506  order.nrdefault[i]++;
507  if (ci.state_.active_)
508  order.nractive[i]++;
509  order.nrjoints[i] += ci.joints_.size();
510  }
511  }
512 
513  // define a bijection to compute the raking of the found options
514  std::vector<std::size_t> bijection(selected_options.size(), 0);
515  for (std::size_t i = 0; i < selected_options.size(); ++i)
516  bijection[i] = i;
517 
518  // sort the options
519  std::sort(bijection.begin(), bijection.end(), order);
520 
521  // depending on whether we are allowed to load & unload controllers,
522  // we have different preference on deciding between options
523  if (!manage_controllers_)
524  {
525  // if we can't load different options at will, just choose one that is already loaded
526  for (std::size_t i = 0; i < selected_options.size(); ++i)
527  if (areControllersActive(selected_options[bijection[i]]))
528  {
529  selected_controllers.swap(selected_options[bijection[i]]);
530  return true;
531  }
532  }
533 
534  // otherwise, just use the first valid option
535  selected_controllers.swap(selected_options[bijection[0]]);
536  return true;
537 }
538 
539 bool TrajectoryExecutionManager::isControllerActive(const std::string& controller)
540 {
541  return areControllersActive(std::vector<std::string>(1, controller));
542 }
543 
544 bool TrajectoryExecutionManager::areControllersActive(const std::vector<std::string>& controllers)
545 {
546  for (const std::string& controller : controllers)
547  {
549  std::map<std::string, ControllerInformation>::iterator it = known_controllers_.find(controller);
550  if (it == known_controllers_.end() || !it->second.state_.active_)
551  return false;
552  }
553  return true;
554 }
555 
556 bool TrajectoryExecutionManager::selectControllers(const std::set<std::string>& actuated_joints,
557  const std::vector<std::string>& available_controllers,
558  std::vector<std::string>& selected_controllers)
559 {
560  for (std::size_t i = 1; i <= available_controllers.size(); ++i)
561  if (findControllers(actuated_joints, i, available_controllers, selected_controllers))
562  {
563  // if we are not managing controllers, prefer to use active controllers even if there are more of them
564  if (!manage_controllers_ && !areControllersActive(selected_controllers))
565  {
566  std::vector<std::string> other_option;
567  for (std::size_t j = i + 1; j <= available_controllers.size(); ++j)
568  if (findControllers(actuated_joints, j, available_controllers, other_option))
569  {
570  if (areControllersActive(other_option))
571  {
572  selected_controllers = other_option;
573  break;
574  }
575  }
576  }
577  return true;
578  }
579  return false;
580 }
581 
582 bool TrajectoryExecutionManager::distributeTrajectory(const moveit_msgs::RobotTrajectory& trajectory,
583  const std::vector<std::string>& controllers,
584  std::vector<moveit_msgs::RobotTrajectory>& parts)
585 {
586  parts.clear();
587  parts.resize(controllers.size());
588 
589  std::set<std::string> actuated_joints_mdof;
590  actuated_joints_mdof.insert(trajectory.multi_dof_joint_trajectory.joint_names.begin(),
591  trajectory.multi_dof_joint_trajectory.joint_names.end());
592  std::set<std::string> actuated_joints_single;
593  for (const std::string& joint_name : trajectory.joint_trajectory.joint_names)
594  {
595  const moveit::core::JointModel* jm = robot_model_->getJointModel(joint_name);
596  if (jm)
597  {
598  if (jm->isPassive() || jm->getMimic() != nullptr || jm->getType() == moveit::core::JointModel::FIXED)
599  continue;
600  actuated_joints_single.insert(jm->getName());
601  }
602  }
603 
604  for (std::size_t i = 0; i < controllers.size(); ++i)
605  {
606  std::map<std::string, ControllerInformation>::iterator it = known_controllers_.find(controllers[i]);
607  if (it == known_controllers_.end())
608  {
609  ROS_ERROR_STREAM_NAMED(LOGNAME, "Controller " << controllers[i] << " not found.");
610  return false;
611  }
612  std::vector<std::string> intersect_mdof;
613  std::set_intersection(it->second.joints_.begin(), it->second.joints_.end(), actuated_joints_mdof.begin(),
614  actuated_joints_mdof.end(), std::back_inserter(intersect_mdof));
615  std::vector<std::string> intersect_single;
616  std::set_intersection(it->second.joints_.begin(), it->second.joints_.end(), actuated_joints_single.begin(),
617  actuated_joints_single.end(), std::back_inserter(intersect_single));
618  if (intersect_mdof.empty() && intersect_single.empty())
619  ROS_WARN_STREAM_NAMED(LOGNAME, "No joints to be distributed for controller " << controllers[i]);
620  {
621  if (!intersect_mdof.empty())
622  {
623  std::vector<std::string>& jnames = parts[i].multi_dof_joint_trajectory.joint_names;
624  jnames.insert(jnames.end(), intersect_mdof.begin(), intersect_mdof.end());
625  std::map<std::string, std::size_t> index;
626  for (std::size_t j = 0; j < trajectory.multi_dof_joint_trajectory.joint_names.size(); ++j)
627  index[trajectory.multi_dof_joint_trajectory.joint_names[j]] = j;
628  std::vector<std::size_t> bijection(jnames.size());
629  for (std::size_t j = 0; j < jnames.size(); ++j)
630  bijection[j] = index[jnames[j]];
631 
632  parts[i].multi_dof_joint_trajectory.points.resize(trajectory.multi_dof_joint_trajectory.points.size());
633  for (std::size_t j = 0; j < trajectory.multi_dof_joint_trajectory.points.size(); ++j)
634  {
635  parts[i].multi_dof_joint_trajectory.points[j].time_from_start =
636  trajectory.multi_dof_joint_trajectory.points[j].time_from_start;
637  parts[i].multi_dof_joint_trajectory.points[j].transforms.resize(bijection.size());
638  for (std::size_t k = 0; k < bijection.size(); ++k)
639  {
640  parts[i].multi_dof_joint_trajectory.points[j].transforms[k] =
641  trajectory.multi_dof_joint_trajectory.points[j].transforms[bijection[k]];
642 
643  if (!trajectory.multi_dof_joint_trajectory.points[j].velocities.empty())
644  {
645  parts[i].multi_dof_joint_trajectory.points[j].velocities.resize(bijection.size());
646 
647  parts[i].multi_dof_joint_trajectory.points[j].velocities[0].linear.x =
648  trajectory.multi_dof_joint_trajectory.points[j].velocities[0].linear.x * execution_velocity_scaling_;
649 
650  parts[i].multi_dof_joint_trajectory.points[j].velocities[0].linear.y =
651  trajectory.multi_dof_joint_trajectory.points[j].velocities[0].linear.y * execution_velocity_scaling_;
652 
653  parts[i].multi_dof_joint_trajectory.points[j].velocities[0].linear.z =
654  trajectory.multi_dof_joint_trajectory.points[j].velocities[0].linear.z * execution_velocity_scaling_;
655 
656  parts[i].multi_dof_joint_trajectory.points[j].velocities[0].angular.x =
657  trajectory.multi_dof_joint_trajectory.points[j].velocities[0].angular.x * execution_velocity_scaling_;
658 
659  parts[i].multi_dof_joint_trajectory.points[j].velocities[0].angular.y =
660  trajectory.multi_dof_joint_trajectory.points[j].velocities[0].angular.y * execution_velocity_scaling_;
661 
662  parts[i].multi_dof_joint_trajectory.points[j].velocities[0].angular.z =
663  trajectory.multi_dof_joint_trajectory.points[j].velocities[0].angular.z * execution_velocity_scaling_;
664  }
665  }
666  }
667  }
668  if (!intersect_single.empty())
669  {
670  std::vector<std::string>& jnames = parts[i].joint_trajectory.joint_names;
671  jnames.insert(jnames.end(), intersect_single.begin(), intersect_single.end());
672  parts[i].joint_trajectory.header = trajectory.joint_trajectory.header;
673  std::map<std::string, std::size_t> index;
674  for (std::size_t j = 0; j < trajectory.joint_trajectory.joint_names.size(); ++j)
675  index[trajectory.joint_trajectory.joint_names[j]] = j;
676  std::vector<std::size_t> bijection(jnames.size());
677  for (std::size_t j = 0; j < jnames.size(); ++j)
678  bijection[j] = index[jnames[j]];
679  parts[i].joint_trajectory.points.resize(trajectory.joint_trajectory.points.size());
680  for (std::size_t j = 0; j < trajectory.joint_trajectory.points.size(); ++j)
681  {
682  parts[i].joint_trajectory.points[j].time_from_start = trajectory.joint_trajectory.points[j].time_from_start;
683  if (!trajectory.joint_trajectory.points[j].positions.empty())
684  {
685  parts[i].joint_trajectory.points[j].positions.resize(bijection.size());
686  for (std::size_t k = 0; k < bijection.size(); ++k)
687  parts[i].joint_trajectory.points[j].positions[k] =
688  trajectory.joint_trajectory.points[j].positions[bijection[k]];
689  }
690  if (!trajectory.joint_trajectory.points[j].velocities.empty())
691  {
692  parts[i].joint_trajectory.points[j].velocities.resize(bijection.size());
693  for (std::size_t k = 0; k < bijection.size(); ++k)
694  parts[i].joint_trajectory.points[j].velocities[k] =
695  trajectory.joint_trajectory.points[j].velocities[bijection[k]] * execution_velocity_scaling_;
696  }
697  if (!trajectory.joint_trajectory.points[j].accelerations.empty())
698  {
699  parts[i].joint_trajectory.points[j].accelerations.resize(bijection.size());
700  for (std::size_t k = 0; k < bijection.size(); ++k)
701  parts[i].joint_trajectory.points[j].accelerations[k] =
702  trajectory.joint_trajectory.points[j].accelerations[bijection[k]];
703  }
704  if (!trajectory.joint_trajectory.points[j].effort.empty())
705  {
706  parts[i].joint_trajectory.points[j].effort.resize(bijection.size());
707  for (std::size_t k = 0; k < bijection.size(); ++k)
708  parts[i].joint_trajectory.points[j].effort[k] =
709  trajectory.joint_trajectory.points[j].effort[bijection[k]];
710  }
711  }
712  }
713  }
714  }
715  return true;
716 }
717 
719 {
720  if (allowed_start_tolerance_ == 0) // skip validation on this magic number
721  return true;
722 
723  ROS_DEBUG_NAMED(LOGNAME, "Validating trajectory with allowed_start_tolerance %g", allowed_start_tolerance_);
724 
725  moveit::core::RobotStatePtr current_state;
726  if (!csm_->waitForCurrentState(ros::Time::now()) || !(current_state = csm_->getCurrentState()))
727  {
728  ROS_WARN_NAMED(LOGNAME, "Failed to validate trajectory: couldn't receive full current joint state within 1s");
729  return false;
730  }
731 
732  for (const auto& trajectory : context.trajectory_parts_)
733  {
734  if (!trajectory.joint_trajectory.points.empty())
735  {
736  // Check single-dof trajectory
737  const std::vector<double>& positions = trajectory.joint_trajectory.points.front().positions;
738  const std::vector<std::string>& joint_names = trajectory.joint_trajectory.joint_names;
739  if (positions.size() != joint_names.size())
740  {
741  ROS_ERROR_NAMED(LOGNAME, "Wrong trajectory: #joints: %zu != #positions: %zu", joint_names.size(),
742  positions.size());
743  return false;
744  }
745 
746  for (std::size_t i = 0, end = joint_names.size(); i < end; ++i)
747  {
748  const moveit::core::JointModel* jm = current_state->getJointModel(joint_names[i]);
749  if (!jm)
750  {
751  ROS_ERROR_STREAM_NAMED(LOGNAME, "Unknown joint in trajectory: " << joint_names[i]);
752  return false;
753  }
754 
755  double cur_position = current_state->getJointPositions(jm)[0];
756  double traj_position = positions[i];
757  // normalize positions and compare
758  jm->enforcePositionBounds(&cur_position);
759  jm->enforcePositionBounds(&traj_position);
760  if (jm->distance(&cur_position, &traj_position) > allowed_start_tolerance_)
761  {
763  "\nInvalid Trajectory: start point deviates from current robot state more than %g"
764  "\njoint '%s': expected: %g, current: %g",
765  allowed_start_tolerance_, joint_names[i].c_str(), traj_position, cur_position);
766  return false;
767  }
768  }
769  }
770  if (!trajectory.multi_dof_joint_trajectory.points.empty())
771  {
772  // Check multi-dof trajectory
773  const std::vector<geometry_msgs::Transform>& transforms =
774  trajectory.multi_dof_joint_trajectory.points.front().transforms;
775  const std::vector<std::string>& joint_names = trajectory.multi_dof_joint_trajectory.joint_names;
776  if (transforms.size() != joint_names.size())
777  {
778  ROS_ERROR_NAMED(LOGNAME, "Wrong trajectory: #joints: %zu != #transforms: %zu", joint_names.size(),
779  transforms.size());
780  return false;
781  }
782 
783  for (std::size_t i = 0, end = joint_names.size(); i < end; ++i)
784  {
785  const moveit::core::JointModel* jm = current_state->getJointModel(joint_names[i]);
786  if (!jm)
787  {
788  ROS_ERROR_STREAM_NAMED(LOGNAME, "Unknown joint in trajectory: " << joint_names[i]);
789  return false;
790  }
791 
792  // compute difference (offset vector and rotation angle) between current transform
793  // and start transform in trajectory
794  Eigen::Isometry3d cur_transform, start_transform;
795  // computeTransform() computes a valid isometry by contract
796  jm->computeTransform(current_state->getJointPositions(jm), cur_transform);
797  start_transform = tf2::transformToEigen(transforms[i]);
798  ASSERT_ISOMETRY(start_transform) // unsanitized input, could contain a non-isometry
799  Eigen::Vector3d offset = cur_transform.translation() - start_transform.translation();
800  Eigen::AngleAxisd rotation;
801  rotation.fromRotationMatrix(cur_transform.linear().transpose() * start_transform.linear());
802  if ((offset.array() > allowed_start_tolerance_).any() || rotation.angle() > allowed_start_tolerance_)
803  {
805  "\nInvalid Trajectory: start point deviates from current robot state more than "
806  << allowed_start_tolerance_ << "\nmulti-dof joint '" << joint_names[i]
807  << "': pos delta: " << offset.transpose() << " rot delta: " << rotation.angle());
808  return false;
809  }
810  }
811  }
812  }
813  return true;
814 }
815 
817  const moveit_msgs::RobotTrajectory& trajectory,
818  const std::vector<std::string>& controllers)
819 {
820  // empty trajectories don't need to configure anything
821  if (trajectory.multi_dof_joint_trajectory.points.empty() && trajectory.joint_trajectory.points.empty())
822  return true;
823 
824  // zero-duration trajectory (start-time stamp + overall duration == 0) causes controller issues
825  if ((trajectory.joint_trajectory.header.stamp + trajectory.joint_trajectory.points.back().time_from_start).isZero())
826  {
827  // https://github.com/ros-planning/moveit/pull/3362
828  ROS_DEBUG_STREAM_NAMED(LOGNAME, "Skipping zero-duration trajectory");
829  return true;
830  }
831 
832  std::set<std::string> actuated_joints;
833 
834  auto is_actuated = [this](const std::string& joint_name) -> bool {
835  const moveit::core::JointModel* jm = robot_model_->getJointModel(joint_name);
836  return (jm && !jm->isPassive() && !jm->getMimic() && jm->getType() != moveit::core::JointModel::FIXED);
837  };
838  for (const std::string& joint_name : trajectory.multi_dof_joint_trajectory.joint_names)
839  if (is_actuated(joint_name))
840  actuated_joints.insert(joint_name);
841  for (const std::string& joint_name : trajectory.joint_trajectory.joint_names)
842  if (is_actuated(joint_name))
843  actuated_joints.insert(joint_name);
844 
845  if (actuated_joints.empty())
846  {
847  ROS_WARN_NAMED(LOGNAME, "The trajectory to execute specifies no joints");
848  return false;
849  }
850 
851  if (controllers.empty())
852  {
853  bool retry = true;
854  bool reloaded = false;
855  while (retry)
856  {
857  retry = false;
858  std::vector<std::string> all_controller_names;
859  for (std::map<std::string, ControllerInformation>::const_iterator it = known_controllers_.begin();
860  it != known_controllers_.end(); ++it)
861  all_controller_names.push_back(it->first);
862  if (selectControllers(actuated_joints, all_controller_names, context.controllers_))
863  {
864  if (distributeTrajectory(trajectory, context.controllers_, context.trajectory_parts_))
865  return true;
866  }
867  else
868  {
869  // maybe we failed because we did not have a complete list of controllers
870  if (!reloaded)
871  {
873  reloaded = true;
874  retry = true;
875  }
876  }
877  }
878  }
879  else
880  {
881  // check if the specified controllers are valid names;
882  // if they appear not to be, try to reload the controller information, just in case they are new in the system
883  bool reloaded = false;
884  for (const std::string& controller : controllers)
885  if (known_controllers_.find(controller) == known_controllers_.end())
886  {
888  reloaded = true;
889  break;
890  }
891  if (reloaded)
892  for (const std::string& controller : controllers)
893  if (known_controllers_.find(controller) == known_controllers_.end())
894  {
895  ROS_ERROR_NAMED(LOGNAME, "Controller '%s' is not known", controller.c_str());
896  return false;
897  }
898  if (selectControllers(actuated_joints, controllers, context.controllers_))
899  {
900  if (distributeTrajectory(trajectory, context.controllers_, context.trajectory_parts_))
901  return true;
902  }
903  }
904  std::stringstream ss;
905  for (const std::string& actuated_joint : actuated_joints)
906  ss << actuated_joint << " ";
907  ROS_ERROR_NAMED(LOGNAME, "Unable to identify any set of controllers that can actuate the specified joints: [ %s]",
908  ss.str().c_str());
909 
910  std::stringstream ss2;
911  std::map<std::string, ControllerInformation>::const_iterator mi;
912  for (mi = known_controllers_.begin(); mi != known_controllers_.end(); mi++)
913  {
914  ss2 << "controller '" << mi->second.name_ << "' controls joints:\n";
915 
916  std::set<std::string>::const_iterator ji;
917  for (ji = mi->second.joints_.begin(); ji != mi->second.joints_.end(); ji++)
918  {
919  ss2 << " " << *ji << std::endl;
920  }
921  }
922  ROS_ERROR_NAMED(LOGNAME, "Known controllers and their joints:\n%s", ss2.str().c_str());
923  return false;
924 }
925 
927 {
928  execute(ExecutionCompleteCallback(), auto_clear);
929  return waitForExecution();
930 }
931 
933 {
934  // execution_state_mutex_ needs to have been locked by the caller
935  for (moveit_controller_manager::MoveItControllerHandlePtr& active_handle : active_handles_)
936  try
937  {
938  active_handle->cancelExecution();
939  }
940  catch (std::exception& ex)
941  {
942  ROS_ERROR_NAMED(LOGNAME, "Caught %s when canceling execution.", ex.what());
943  }
944 }
945 
947 {
948  if (!execution_complete_)
949  {
950  execution_state_mutex_.lock();
951  if (!execution_complete_)
952  {
953  // we call cancel for all active handles; we know these are not being modified as we loop through them because of
954  // the lock
955  // we mark execution_complete_ as true ahead of time. Using this flag, executePart() will know that an external
956  // trigger to stop has been received
957  execution_complete_ = true;
959 
960  // we set the status here; executePart() will not set status when execution_complete_ is true ahead of time
962  execution_state_mutex_.unlock();
963  ROS_INFO_NAMED(LOGNAME, "Stopped trajectory execution.");
964 
965  // wait for the execution thread to finish
966  boost::mutex::scoped_lock lock(execution_thread_mutex_);
967  if (execution_thread_)
968  {
969  execution_thread_->join();
970  execution_thread_.reset();
971  }
972 
973  if (auto_clear)
974  clear();
975  }
976  else
977  execution_state_mutex_.unlock();
978  }
979  else if (execution_thread_) // just in case we have some thread waiting to be joined from some point in the past, we
980  // join it now
981  {
982  boost::mutex::scoped_lock lock(execution_thread_mutex_);
983  if (execution_thread_)
984  {
985  execution_thread_->join();
986  execution_thread_.reset();
987  }
988  }
989 }
990 
992 {
993  execute(callback, PathSegmentCompleteCallback(), auto_clear);
994 }
995 
997  const PathSegmentCompleteCallback& part_callback, bool auto_clear)
998 {
999  // skip execution if no trajectory have been pushed
1000  // it crashes otherwise
1001  if (trajectories_.empty())
1002  return;
1003 
1004  stopExecution(false);
1005 
1006  // check whether first trajectory starts at current robot state
1007  if (!trajectories_.empty() && !validate(*trajectories_.front()))
1008  {
1010  if (auto_clear)
1011  clear();
1012  if (callback)
1013  callback(last_execution_status_);
1014  return;
1015  }
1016 
1017  // start the execution thread
1018  execution_complete_ = false;
1019  execution_thread_ = std::make_unique<boost::thread>(&TrajectoryExecutionManager::executeThread, this, callback,
1020  part_callback, auto_clear);
1021 }
1022 
1024 {
1025  {
1026  boost::unique_lock<boost::mutex> ulock(execution_state_mutex_);
1027  while (!execution_complete_)
1028  execution_complete_condition_.wait(ulock);
1029  }
1030 
1031  // this will join the thread for executing sequences of trajectories
1032  stopExecution(false);
1033 
1034  return last_execution_status_;
1035 }
1036 
1038 {
1039  if (execution_complete_)
1040  {
1041  for (TrajectoryExecutionContext* trajectory : trajectories_)
1042  delete trajectory;
1043  trajectories_.clear();
1044  }
1045  else
1046  ROS_ERROR_NAMED(LOGNAME, "Cannot push a new trajectory while another is being executed");
1047 }
1048 
1050  const PathSegmentCompleteCallback& part_callback, bool auto_clear)
1051 {
1052  // if we already got a stop request before we even started anything, we abort
1053  if (execution_complete_)
1054  {
1056  if (callback)
1057  callback(last_execution_status_);
1058  return;
1059  }
1060 
1061  ROS_DEBUG_NAMED(LOGNAME, "Starting trajectory execution ...");
1062  // assume everything will be OK
1064 
1065  // execute each trajectory, one after the other (executePart() is blocking) or until one fails.
1066  // on failure, the status is set by executePart(). Otherwise, it will remain as set above (success)
1067  std::size_t i = 0;
1068  for (; i < trajectories_.size(); ++i)
1069  {
1070  bool epart = executePart(i);
1071  if (epart && part_callback)
1072  part_callback(i);
1073  if (!epart || execution_complete_)
1074  {
1075  ++i;
1076  break;
1077  }
1078  }
1079 
1080  // only report that execution finished successfully when the robot actually stopped moving
1083 
1084  ROS_INFO_NAMED(LOGNAME, "Completed trajectory execution with status %s ...",
1085  last_execution_status_.asString().c_str());
1086 
1087  // notify whoever is waiting for the event of trajectory completion
1088  execution_state_mutex_.lock();
1089  execution_complete_ = true;
1090  execution_state_mutex_.unlock();
1091  execution_complete_condition_.notify_all();
1092 
1093  // clear the paths just executed, if needed
1094  if (auto_clear)
1095  clear();
1096 
1097  // call user-specified callback
1098  if (callback)
1099  callback(last_execution_status_);
1100 }
1101 
1102 bool TrajectoryExecutionManager::executePart(std::size_t part_index)
1103 {
1104  TrajectoryExecutionContext& context = *trajectories_[part_index];
1105 
1106  // first make sure desired controllers are active
1108  {
1109  // stop if we are already asked to do so
1110  if (execution_complete_)
1111  return false;
1112 
1113  std::vector<moveit_controller_manager::MoveItControllerHandlePtr> handles;
1114  {
1115  boost::mutex::scoped_lock slock(execution_state_mutex_);
1116  if (!execution_complete_)
1117  {
1118  // time indexing uses this member too, so we lock this mutex as well
1119  time_index_mutex_.lock();
1120  current_context_ = part_index;
1121  time_index_mutex_.unlock();
1122  active_handles_.resize(context.controllers_.size());
1123  for (std::size_t i = 0; i < context.controllers_.size(); ++i)
1124  {
1125  moveit_controller_manager::MoveItControllerHandlePtr h;
1126  try
1127  {
1128  h = controller_manager_->getControllerHandle(context.controllers_[i]);
1129  }
1130  catch (std::exception& ex)
1131  {
1132  ROS_ERROR_NAMED(LOGNAME, "Caught %s when retrieving controller handle", ex.what());
1133  }
1134  if (!h)
1135  {
1136  active_handles_.clear();
1137  current_context_ = -1;
1139  ROS_ERROR_NAMED(LOGNAME, "No controller handle for controller '%s'. Aborting.",
1140  context.controllers_[i].c_str());
1141  return false;
1142  }
1143  active_handles_[i] = h;
1144  }
1145  handles = active_handles_; // keep a copy for later, to avoid thread safety issues
1146  for (std::size_t i = 0; i < context.trajectory_parts_.size(); ++i)
1147  {
1148  bool ok = false;
1149  try
1150  {
1151  ok = active_handles_[i]->sendTrajectory(context.trajectory_parts_[i]);
1152  }
1153  catch (std::exception& ex)
1154  {
1155  ROS_ERROR_NAMED(LOGNAME, "Caught %s when sending trajectory to controller", ex.what());
1156  }
1157  if (!ok)
1158  {
1159  for (std::size_t j = 0; j < i; ++j)
1160  try
1161  {
1162  active_handles_[j]->cancelExecution();
1163  }
1164  catch (std::exception& ex)
1165  {
1166  ROS_ERROR_NAMED(LOGNAME, "Caught %s when canceling execution", ex.what());
1167  }
1168  ROS_ERROR_NAMED(LOGNAME, "Failed to send trajectory part %zu of %zu to controller %s", i + 1,
1169  context.trajectory_parts_.size(), active_handles_[i]->getName().c_str());
1170  if (i > 0)
1171  ROS_ERROR_NAMED(LOGNAME, "Cancelling previously sent trajectory parts");
1172  active_handles_.clear();
1173  current_context_ = -1;
1175  return false;
1176  }
1177  }
1178  }
1179  }
1180 
1181  // compute the expected duration of the trajectory and find the part of the trajectory that takes longest to execute
1182  ros::Time current_time = ros::Time::now();
1183  ros::Duration expected_trajectory_duration(0.0);
1184  int longest_part = -1;
1185  for (std::size_t i = 0; i < context.trajectory_parts_.size(); ++i)
1186  {
1187  ros::Duration d(0.0);
1188  if (!(context.trajectory_parts_[i].joint_trajectory.points.empty() &&
1189  context.trajectory_parts_[i].multi_dof_joint_trajectory.points.empty()))
1190  {
1191  if (context.trajectory_parts_[i].joint_trajectory.header.stamp > current_time)
1192  d = context.trajectory_parts_[i].joint_trajectory.header.stamp - current_time;
1193  if (context.trajectory_parts_[i].multi_dof_joint_trajectory.header.stamp > current_time)
1194  d = std::max(d, context.trajectory_parts_[i].multi_dof_joint_trajectory.header.stamp - current_time);
1195  d += std::max(context.trajectory_parts_[i].joint_trajectory.points.empty() ?
1196  ros::Duration(0.0) :
1197  context.trajectory_parts_[i].joint_trajectory.points.back().time_from_start,
1198  context.trajectory_parts_[i].multi_dof_joint_trajectory.points.empty() ?
1199  ros::Duration(0.0) :
1200  context.trajectory_parts_[i].multi_dof_joint_trajectory.points.back().time_from_start);
1201 
1202  if (longest_part < 0 ||
1203  std::max(context.trajectory_parts_[i].joint_trajectory.points.size(),
1204  context.trajectory_parts_[i].multi_dof_joint_trajectory.points.size()) >
1205  std::max(context.trajectory_parts_[longest_part].joint_trajectory.points.size(),
1206  context.trajectory_parts_[longest_part].multi_dof_joint_trajectory.points.size()))
1207  longest_part = i;
1208  }
1209 
1210  // prefer controller-specific values over global ones if defined
1211  // TODO: the controller-specific parameters are static, but override
1212  // the global ones are configurable via dynamic reconfigure
1213  std::map<std::string, double>::const_iterator scaling_it =
1215  const double current_scaling = scaling_it != controller_allowed_execution_duration_scaling_.end() ?
1216  scaling_it->second :
1218 
1219  std::map<std::string, double>::const_iterator margin_it =
1221  const double current_margin = margin_it != controller_allowed_goal_duration_margin_.end() ?
1222  margin_it->second :
1224 
1225  // expected duration is the duration of the longest part
1226  expected_trajectory_duration =
1227  std::max(d * current_scaling + ros::Duration(current_margin), expected_trajectory_duration);
1228  }
1229 
1230  // construct a map from expected time to state index, for easy access to expected state location
1231  if (longest_part >= 0)
1232  {
1233  boost::mutex::scoped_lock slock(time_index_mutex_);
1234 
1235  if (context.trajectory_parts_[longest_part].joint_trajectory.points.size() >=
1236  context.trajectory_parts_[longest_part].multi_dof_joint_trajectory.points.size())
1237  {
1238  ros::Duration d(0.0);
1239  if (context.trajectory_parts_[longest_part].joint_trajectory.header.stamp > current_time)
1240  d = context.trajectory_parts_[longest_part].joint_trajectory.header.stamp - current_time;
1241  for (trajectory_msgs::JointTrajectoryPoint& point :
1242  context.trajectory_parts_[longest_part].joint_trajectory.points)
1243  time_index_.push_back(current_time + d + point.time_from_start);
1244  }
1245  else
1246  {
1247  ros::Duration d(0.0);
1248  if (context.trajectory_parts_[longest_part].multi_dof_joint_trajectory.header.stamp > current_time)
1249  d = context.trajectory_parts_[longest_part].multi_dof_joint_trajectory.header.stamp - current_time;
1250  for (trajectory_msgs::MultiDOFJointTrajectoryPoint& point :
1251  context.trajectory_parts_[longest_part].multi_dof_joint_trajectory.points)
1252  time_index_.push_back(current_time + d + point.time_from_start);
1253  }
1254  }
1255 
1256  bool result = true;
1257  for (moveit_controller_manager::MoveItControllerHandlePtr& handle : handles)
1258  {
1260  {
1261  if (!handle->waitForExecution(expected_trajectory_duration))
1262  if (!execution_complete_ && ros::Time::now() - current_time > expected_trajectory_duration)
1263  {
1265  "Controller is taking too long to execute trajectory (the expected upper "
1266  "bound for the trajectory execution was %lf seconds). Stopping trajectory.",
1267  expected_trajectory_duration.toSec());
1268  {
1269  boost::mutex::scoped_lock slock(execution_state_mutex_);
1270  stopExecutionInternal(); // this is really tricky. we can't call stopExecution() here, so we call the
1271  // internal function only
1272  }
1274  result = false;
1275  break;
1276  }
1277  }
1278  else
1279  handle->waitForExecution();
1280 
1281  // if something made the trajectory stop, we stop this thread too
1282  if (execution_complete_)
1283  {
1284  result = false;
1285  break;
1286  }
1287  else if (handle->getLastExecutionStatus() != moveit_controller_manager::ExecutionStatus::SUCCEEDED)
1288  {
1289  ROS_WARN_STREAM_NAMED(LOGNAME, "Controller handle " << handle->getName() << " reports status "
1290  << handle->getLastExecutionStatus().asString());
1291  last_execution_status_ = handle->getLastExecutionStatus();
1292  result = false;
1293  }
1294  }
1295 
1296  // clear the active handles
1297  execution_state_mutex_.lock();
1298  active_handles_.clear();
1299 
1300  // clear the time index
1301  time_index_mutex_.lock();
1302  time_index_.clear();
1303  current_context_ = -1;
1304  time_index_mutex_.unlock();
1305 
1306  execution_state_mutex_.unlock();
1307  return result;
1308  }
1309  else
1310  {
1312  return false;
1313  }
1314 }
1315 
1317 {
1318  // skip waiting for convergence?
1320  {
1321  ROS_DEBUG_NAMED(LOGNAME, "Not waiting for trajectory completion");
1322  return true;
1323  }
1324 
1326  double time_remaining = wait_time;
1327 
1328  moveit::core::RobotStatePtr prev_state, cur_state;
1329  prev_state = csm_->getCurrentState();
1330  prev_state->enforceBounds();
1331 
1332  // assume robot stopped when 3 consecutive checks yield the same robot state
1333  unsigned int no_motion_count = 0; // count iterations with no motion
1334  while (time_remaining > 0. && no_motion_count < 3)
1335  {
1336  if (!csm_->waitForCurrentState(ros::Time::now(), time_remaining) || !(cur_state = csm_->getCurrentState()))
1337  {
1338  ROS_WARN_NAMED(LOGNAME, "Failed to receive current joint state");
1339  return false;
1340  }
1341  cur_state->enforceBounds();
1342  time_remaining = wait_time - (ros::WallTime::now() - start).toSec(); // remaining wait_time
1343 
1344  // check for motion in effected joints of execution context
1345  bool moved = false;
1346  for (const auto& trajectory : context.trajectory_parts_)
1347  {
1348  const std::vector<std::string>& joint_names = trajectory.joint_trajectory.joint_names;
1349  const std::size_t n = joint_names.size();
1350 
1351  for (std::size_t i = 0; i < n && !moved; ++i)
1352  {
1353  const moveit::core::JointModel* jm = cur_state->getJointModel(joint_names[i]);
1354  if (!jm)
1355  continue; // joint vanished from robot state (shouldn't happen), but we don't care
1356 
1357  if (fabs(cur_state->getJointPositions(jm)[0] - prev_state->getJointPositions(jm)[0]) > allowed_start_tolerance_)
1358  {
1359  moved = true;
1360  no_motion_count = 0;
1361  break;
1362  }
1363  }
1364  }
1365 
1366  if (!moved)
1367  ++no_motion_count;
1368 
1369  std::swap(prev_state, cur_state);
1370  }
1371 
1372  return time_remaining > 0;
1373 }
1374 
1376 {
1377  boost::mutex::scoped_lock slock(time_index_mutex_);
1378  if (current_context_ < 0)
1379  return std::make_pair(-1, -1);
1380  if (time_index_.empty())
1381  return std::make_pair((int)current_context_, -1);
1382  std::vector<ros::Time>::const_iterator time_index_it =
1383  std::lower_bound(time_index_.begin(), time_index_.end(), ros::Time::now());
1384  int pos = time_index_it - time_index_.begin();
1385  return std::make_pair((int)current_context_, pos);
1386 }
1387 
1388 const std::vector<TrajectoryExecutionManager::TrajectoryExecutionContext*>&
1390 {
1391  return trajectories_;
1392 }
1393 
1395 {
1396  return last_execution_status_;
1397 }
1398 
1400 {
1401  const moveit::core::JointModelGroup* joint_model_group = robot_model_->getJointModelGroup(group);
1402  if (joint_model_group)
1403  return ensureActiveControllersForJoints(joint_model_group->getJointModelNames());
1404  else
1405  return false;
1406 }
1407 
1408 bool TrajectoryExecutionManager::ensureActiveControllersForJoints(const std::vector<std::string>& joints)
1409 {
1410  std::vector<std::string> all_controller_names;
1411  for (std::map<std::string, ControllerInformation>::const_iterator it = known_controllers_.begin();
1412  it != known_controllers_.end(); ++it)
1413  all_controller_names.push_back(it->first);
1414  std::vector<std::string> selected_controllers;
1415  std::set<std::string> jset;
1416  for (const std::string& joint : joints)
1417  {
1418  const moveit::core::JointModel* jm = robot_model_->getJointModel(joint);
1419  if (jm)
1420  {
1421  if (jm->isPassive() || jm->getMimic() != nullptr || jm->getType() == moveit::core::JointModel::FIXED)
1422  continue;
1423  jset.insert(joint);
1424  }
1425  }
1426 
1427  if (selectControllers(jset, all_controller_names, selected_controllers))
1428  return ensureActiveControllers(selected_controllers);
1429  else
1430  return false;
1431 }
1432 
1433 bool TrajectoryExecutionManager::ensureActiveController(const std::string& controller)
1434 {
1435  return ensureActiveControllers(std::vector<std::string>(1, controller));
1436 }
1437 
1438 bool TrajectoryExecutionManager::ensureActiveControllers(const std::vector<std::string>& controllers)
1439 {
1441 
1442  if (manage_controllers_)
1443  {
1444  std::vector<std::string> controllers_to_activate;
1445  std::vector<std::string> controllers_to_deactivate;
1446  std::set<std::string> joints_to_be_activated;
1447  std::set<std::string> joints_to_be_deactivated;
1448  for (const std::string& controller : controllers)
1449  {
1450  std::map<std::string, ControllerInformation>::const_iterator it = known_controllers_.find(controller);
1451  if (it == known_controllers_.end())
1452  {
1453  ROS_ERROR_STREAM_NAMED(LOGNAME, "Controller " << controller << " is not known");
1454  return false;
1455  }
1456  if (!it->second.state_.active_)
1457  {
1458  ROS_DEBUG_STREAM_NAMED(LOGNAME, "Need to activate " << controller);
1459  controllers_to_activate.push_back(controller);
1460  joints_to_be_activated.insert(it->second.joints_.begin(), it->second.joints_.end());
1461  for (const std::string& overlapping_controller : it->second.overlapping_controllers_)
1462  {
1463  const ControllerInformation& ci = known_controllers_[overlapping_controller];
1464  if (ci.state_.active_)
1465  {
1466  controllers_to_deactivate.push_back(overlapping_controller);
1467  joints_to_be_deactivated.insert(ci.joints_.begin(), ci.joints_.end());
1468  }
1469  }
1470  }
1471  else
1472  ROS_DEBUG_STREAM_NAMED(LOGNAME, "Controller " << controller << " is already active");
1473  }
1474  std::set<std::string> diff;
1475  std::set_difference(joints_to_be_deactivated.begin(), joints_to_be_deactivated.end(),
1476  joints_to_be_activated.begin(), joints_to_be_activated.end(), std::inserter(diff, diff.end()));
1477  if (!diff.empty())
1478  {
1479  // find the set of controllers that do not overlap with the ones we want to activate so far
1480  std::vector<std::string> possible_additional_controllers;
1481  for (std::map<std::string, ControllerInformation>::const_iterator it = known_controllers_.begin();
1482  it != known_controllers_.end(); ++it)
1483  {
1484  bool ok = true;
1485  for (const std::string& controller_to_activate : controllers_to_activate)
1486  if (it->second.overlapping_controllers_.find(controller_to_activate) !=
1487  it->second.overlapping_controllers_.end())
1488  {
1489  ok = false;
1490  break;
1491  }
1492  if (ok)
1493  possible_additional_controllers.push_back(it->first);
1494  }
1495 
1496  // out of the allowable controllers, try to find a subset of controllers that covers the joints to be actuated
1497  std::vector<std::string> additional_controllers;
1498  if (selectControllers(diff, possible_additional_controllers, additional_controllers))
1499  controllers_to_activate.insert(controllers_to_activate.end(), additional_controllers.begin(),
1500  additional_controllers.end());
1501  else
1502  return false;
1503  }
1504  if (!controllers_to_activate.empty() || !controllers_to_deactivate.empty())
1505  {
1506  if (controller_manager_)
1507  {
1508  // load controllers to be activated, if needed, and reset the state update cache
1509  for (const std::string& controller_to_activate : controllers_to_activate)
1510  {
1511  ControllerInformation& ci = known_controllers_[controller_to_activate];
1512  ci.last_update_ = ros::Time();
1513  }
1514  // reset the state update cache
1515  for (const std::string& controller_to_activate : controllers_to_deactivate)
1516  known_controllers_[controller_to_activate].last_update_ = ros::Time();
1517  return controller_manager_->switchControllers(controllers_to_activate, controllers_to_deactivate);
1518  }
1519  else
1520  return false;
1521  }
1522  else
1523  return true;
1524  }
1525  else
1526  {
1527  std::set<std::string> originally_active;
1528  for (std::map<std::string, ControllerInformation>::const_iterator it = known_controllers_.begin();
1529  it != known_controllers_.end(); ++it)
1530  if (it->second.state_.active_)
1531  originally_active.insert(it->first);
1532  return std::includes(originally_active.begin(), originally_active.end(), controllers.begin(), controllers.end());
1533  }
1534 }
1535 
1537 {
1538  XmlRpc::XmlRpcValue controller_list;
1539  if (node_handle_.getParam("controller_list", controller_list) &&
1540  controller_list.getType() == XmlRpc::XmlRpcValue::TypeArray)
1541  {
1542  for (int i = 0; i < controller_list.size(); ++i) // NOLINT(modernize-loop-convert)
1543  {
1544  XmlRpc::XmlRpcValue& controller = controller_list[i];
1545  if (controller.hasMember("name"))
1546  {
1547  if (controller.hasMember("allowed_execution_duration_scaling"))
1548  controller_allowed_execution_duration_scaling_[std::string(controller["name"])] =
1549  controller["allowed_execution_duration_scaling"];
1550  if (controller.hasMember("allowed_goal_duration_margin"))
1551  controller_allowed_goal_duration_margin_[std::string(controller["name"])] =
1552  controller["allowed_goal_duration_margin"];
1553  }
1554  }
1555  }
1556 }
1557 } // namespace trajectory_execution_manager
XmlRpc::XmlRpcValue::size
int size() const
trajectory_execution_manager::TrajectoryExecutionManager::time_index_
std::vector< ros::Time > time_index_
Definition: trajectory_execution_manager.h:321
trajectory_execution_manager::TrajectoryExecutionManager::validate
bool validate(const TrajectoryExecutionContext &context) const
Validate first point of trajectory matches current robot state.
Definition: trajectory_execution_manager.cpp:718
moveit::core::JointModel::enforcePositionBounds
bool enforcePositionBounds(double *values) const
trajectory_execution_manager::TrajectoryExecutionManager::verbose_
bool verbose_
Definition: trajectory_execution_manager.h:330
trajectory_execution_manager::TrajectoryExecutionManager::ExecutionCompleteCallback
boost::function< void(const moveit_controller_manager::ExecutionStatus &)> ExecutionCompleteCallback
Definition: trajectory_execution_manager.h:98
trajectory_execution_manager::TrajectoryExecutionManager::execution_velocity_scaling_
double execution_velocity_scaling_
Definition: trajectory_execution_manager.h:345
trajectory_execution_manager::TrajectoryExecutionManager::execution_complete_condition_
boost::condition_variable execution_complete_condition_
Definition: trajectory_execution_manager.h:316
trajectory_execution_manager::DEFAULT_CONTROLLER_INFORMATION_VALIDITY_AGE
static const ros::Duration DEFAULT_CONTROLLER_INFORMATION_VALIDITY_AGE(1.0)
trajectory_execution_manager::TrajectoryExecutionManager
Definition: trajectory_execution_manager.h:91
trajectory_execution_manager::TrajectoryExecutionManager::executeAndWait
moveit_controller_manager::ExecutionStatus executeAndWait(bool auto_clear=true)
Definition: trajectory_execution_manager.cpp:926
moveit_controller_manager::ExecutionStatus::PREEMPTED
PREEMPTED
nrjoints
std::vector< std::size_t > nrjoints
Definition: trajectory_execution_manager.cpp:450
trajectory_execution_manager::TrajectoryExecutionManager::controller_manager_loader_
std::unique_ptr< pluginlib::ClassLoader< moveit_controller_manager::MoveItControllerManager > > controller_manager_loader_
Definition: trajectory_execution_manager.h:327
trajectory_execution_manager::TrajectoryExecutionManager::stopExecution
void stopExecution(bool auto_clear=true)
Stop whatever executions are active, if any.
Definition: trajectory_execution_manager.cpp:946
tf2_eigen.h
moveit_controller_manager::ExecutionStatus::ABORTED
ABORTED
trajectory_execution_manager::TrajectoryExecutionManager::setWaitForTrajectoryCompletion
void setWaitForTrajectoryCompletion(bool flag)
Enable or disable waiting for trajectory completion.
Definition: trajectory_execution_manager.cpp:210
ROS_DEBUG_STREAM_NAMED
#define ROS_DEBUG_STREAM_NAMED(name, args)
ros
ros::NodeHandle::getParam
bool getParam(const std::string &key, bool &b) const
trajectory_execution_manager::TrajectoryExecutionManager::manage_controllers_
bool manage_controllers_
Definition: trajectory_execution_manager.h:307
check_isometry.h
trajectory_execution_manager::TrajectoryExecutionManager::ensureActiveController
bool ensureActiveController(const std::string &controller)
Make sure a particular controller is active.
Definition: trajectory_execution_manager.cpp:1433
trajectory_execution_manager::TrajectoryExecutionManager::selectControllers
bool selectControllers(const std::set< std::string > &actuated_joints, const std::vector< std::string > &available_controllers, std::vector< std::string > &selected_controllers)
Definition: trajectory_execution_manager.cpp:556
trajectory_execution_manager::TrajectoryExecutionManager::execution_complete_
bool execution_complete_
Definition: trajectory_execution_manager.h:323
trajectory_execution_manager::TrajectoryExecutionManager::setExecutionVelocityScaling
void setExecutionVelocityScaling(double scaling)
Definition: trajectory_execution_manager.cpp:200
moveit::core::JointModel::getName
const std::string & getName() const
trajectory_execution_manager::TrajectoryExecutionManager::csm_
planning_scene_monitor::CurrentStateMonitorPtr csm_
Definition: trajectory_execution_manager.h:301
moveit_controller_manager::MoveItControllerManager::ControllerState::active_
bool active_
moveit_controller_manager::ExecutionStatus::TIMED_OUT
TIMED_OUT
trajectory_execution_manager::TrajectoryExecutionManager::node_handle_
ros::NodeHandle node_handle_
Definition: trajectory_execution_manager.h:302
trajectory_execution_manager::TrajectoryExecutionManager::ensureActiveControllersForJoints
bool ensureActiveControllersForJoints(const std::vector< std::string > &joints)
Make sure the active controllers are such that trajectories that actuate joints in the specified set ...
Definition: trajectory_execution_manager.cpp:1408
trajectory_execution_manager::TrajectoryExecutionManager::current_context_
int current_context_
Definition: trajectory_execution_manager.h:320
trajectory_execution_manager::TrajectoryExecutionManager::getLastExecutionStatus
moveit_controller_manager::ExecutionStatus getLastExecutionStatus() const
Return the controller status for the last attempted execution.
Definition: trajectory_execution_manager.cpp:1394
trajectory_execution_manager::TrajectoryExecutionManager::isControllerActive
bool isControllerActive(const std::string &controller)
Check if a controller is active.
Definition: trajectory_execution_manager.cpp:539
nractive
std::vector< std::size_t > nractive
Definition: trajectory_execution_manager.cpp:451
trajectory_execution_manager::TrajectoryExecutionManager::last_execution_status_
moveit_controller_manager::ExecutionStatus last_execution_status_
Definition: trajectory_execution_manager.h:318
ROS_ERROR_NAMED
#define ROS_ERROR_NAMED(name,...)
robot_state.h
trajectory_execution_manager::TrajectoryExecutionManager::initialize
void initialize()
Definition: trajectory_execution_manager.cpp:109
trajectory_execution_manager::TrajectoryExecutionManager::ensureActiveControllers
bool ensureActiveControllers(const std::vector< std::string > &controllers)
Make sure a particular set of controllers are active.
Definition: trajectory_execution_manager.cpp:1438
trajectory_execution_manager::TrajectoryExecutionManager::checkControllerCombination
bool checkControllerCombination(std::vector< std::string > &controllers, const std::set< std::string > &actuated_joints)
Definition: trajectory_execution_manager.cpp:364
trajectory_execution_manager::TrajectoryExecutionManager::setAllowedExecutionDurationScaling
void setAllowedExecutionDurationScaling(double scaling)
Definition: trajectory_execution_manager.cpp:190
ROS_FATAL_NAMED
#define ROS_FATAL_NAMED(name,...)
trajectory_execution_manager::TrajectoryExecutionManager::controller_allowed_goal_duration_margin_
std::map< std::string, double > controller_allowed_goal_duration_margin_
Definition: trajectory_execution_manager.h:342
overlap
bool overlap(S a1, S a2, S b1, S b2)
trajectory_execution_manager::TrajectoryExecutionManager::receiveEvent
void receiveEvent(const std_msgs::StringConstPtr &event)
Definition: trajectory_execution_manager.cpp:233
ok
ROSCPP_DECL bool ok()
trajectory_execution_manager::TrajectoryExecutionManager::getTrajectories
const std::vector< TrajectoryExecutionContext * > & getTrajectories() const
Get the trajectories to be executed.
Definition: trajectory_execution_manager.cpp:1389
trajectory_execution_manager::TrajectoryExecutionManager::DynamicReconfigureImpl::dynamicReconfigureCallback
void dynamicReconfigureCallback(const TrajectoryExecutionDynamicReconfigureConfig &config, uint32_t)
Definition: trajectory_execution_manager.cpp:71
trajectory_execution_manager::TrajectoryExecutionManager::controller_manager_
moveit_controller_manager::MoveItControllerManagerPtr controller_manager_
Definition: trajectory_execution_manager.h:328
trajectory_execution_manager::TrajectoryExecutionManager::execution_duration_monitoring_
bool execution_duration_monitoring_
Definition: trajectory_execution_manager.h:335
trajectory_execution_manager::TrajectoryExecutionManager::stopExecutionInternal
void stopExecutionInternal()
Definition: trajectory_execution_manager.cpp:932
moveit::core::JointModel::getType
JointType getType() const
trajectory_execution_manager::TrajectoryExecutionManager::TrajectoryExecutionContext::trajectory_parts_
std::vector< moveit_msgs::RobotTrajectory > trajectory_parts_
Definition: trajectory_execution_manager.h:112
LOGNAME
static const std::string LOGNAME
Definition: trajectory_execution_manager.cpp:45
pluginlib::PluginlibException
trajectory_execution_manager::TrajectoryExecutionManager::ControllerInformation::name_
std::string name_
Definition: trajectory_execution_manager.h:246
trajectory_execution_manager::TrajectoryExecutionManager::reconfigure_impl_
DynamicReconfigureImpl * reconfigure_impl_
Definition: trajectory_execution_manager.h:332
trajectory_execution_manager::TrajectoryExecutionManager::root_node_handle_
ros::NodeHandle root_node_handle_
Definition: trajectory_execution_manager.h:303
trajectory_execution_manager::TrajectoryExecutionManager::executePart
bool executePart(std::size_t part_index)
Definition: trajectory_execution_manager.cpp:1102
trajectory_execution_manager::TrajectoryExecutionManager::allowed_start_tolerance_
double allowed_start_tolerance_
Definition: trajectory_execution_manager.h:344
trajectory_execution_manager::TrajectoryExecutionManager::generateControllerCombination
void generateControllerCombination(std::size_t start_index, std::size_t controller_count, const std::vector< std::string > &available_controllers, std::vector< std::string > &selected_controllers, std::vector< std::vector< std::string > > &selected_options, const std::set< std::string > &actuated_joints)
Definition: trajectory_execution_manager.cpp:390
name
std::string name
trajectory_execution_manager::TrajectoryExecutionManager::ControllerInformation
Definition: trajectory_execution_manager.h:244
ROS_INFO_NAMED
#define ROS_INFO_NAMED(name,...)
trajectory_execution_manager::TrajectoryExecutionManager::DynamicReconfigureImpl
Definition: trajectory_execution_manager.cpp:60
ROS_FATAL_STREAM_NAMED
#define ROS_FATAL_STREAM_NAMED(name, args)
ROS_DEBUG_NAMED
#define ROS_DEBUG_NAMED(name,...)
moveit_controller_manager::ExecutionStatus::SUCCEEDED
SUCCEEDED
ros::WallTime::now
static WallTime now()
ROS_ERROR_STREAM_NAMED
#define ROS_ERROR_STREAM_NAMED(name, args)
moveit::core::JointModelGroup::getJointModelNames
const std::vector< std::string > & getJointModelNames() const
ASSERT_ISOMETRY
#define ASSERT_ISOMETRY(transform)
trajectory_execution_manager::TrajectoryExecutionManager::execute
void execute(const ExecutionCompleteCallback &callback=ExecutionCompleteCallback(), bool auto_clear=true)
Start the execution of pushed trajectories; this does not wait for completion, but calls a callback w...
Definition: trajectory_execution_manager.cpp:991
trajectory_execution_manager::TrajectoryExecutionManager::trajectories_
std::vector< TrajectoryExecutionContext * > trajectories_
Definition: trajectory_execution_manager.h:325
trajectory_execution_manager
Definition: trajectory_execution_manager.h:52
trajectory_execution_manager::TrajectoryExecutionManager::DynamicReconfigureImpl::dynamic_reconfigure_server_
dynamic_reconfigure::Server< TrajectoryExecutionDynamicReconfigureConfig > dynamic_reconfigure_server_
Definition: trajectory_execution_manager.cpp:82
trajectory_execution_manager::TrajectoryExecutionManager::areControllersActive
bool areControllersActive(const std::vector< std::string > &controllers)
Check if a set of controllers are active.
Definition: trajectory_execution_manager.cpp:544
nrdefault
std::vector< std::size_t > nrdefault
Definition: trajectory_execution_manager.cpp:449
trajectory_execution_manager::TrajectoryExecutionManager::active_handles_
std::vector< moveit_controller_manager::MoveItControllerHandlePtr > active_handles_
Definition: trajectory_execution_manager.h:319
d
d
trajectory_execution_manager::TrajectoryExecutionManager::TrajectoryExecutionContext::controllers_
std::vector< std::string > controllers_
The controllers to use for executing the different trajectory parts;.
Definition: trajectory_execution_manager.h:108
ros::NodeHandle::subscribe
Subscriber subscribe(const std::string &topic, uint32_t queue_size, const boost::function< void(C)> &callback, const VoidConstPtr &tracked_object=VoidConstPtr(), const TransportHints &transport_hints=TransportHints())
trajectory_execution_manager::TrajectoryExecutionManager::EXECUTION_EVENT_TOPIC
static const std::string EXECUTION_EVENT_TOPIC
Definition: trajectory_execution_manager.h:94
trajectory_execution_manager::TrajectoryExecutionManager::ControllerInformation::overlapping_controllers_
std::set< std::string > overlapping_controllers_
Definition: trajectory_execution_manager.h:248
ros::WallTime
trajectory_execution_manager::TrajectoryExecutionManager::getControllerManager
const moveit_controller_manager::MoveItControllerManagerPtr & getControllerManager() const
Get the instance of the controller manager used (this is the plugin instance loaded)
Definition: trajectory_execution_manager.cpp:220
trajectory_execution_manager::TrajectoryExecutionManager::processEvent
void processEvent(const std::string &event)
Execute a named event (e.g., 'stop')
Definition: trajectory_execution_manager.cpp:225
trajectory_execution_manager::DEFAULT_CONTROLLER_GOAL_DURATION_SCALING
static const double DEFAULT_CONTROLLER_GOAL_DURATION_SCALING
Definition: trajectory_execution_manager.cpp:55
trajectory_execution_manager::TrajectoryExecutionManager::setAllowedGoalDurationMargin
void setAllowedGoalDurationMargin(double margin)
Definition: trajectory_execution_manager.cpp:195
XmlRpc::XmlRpcValue::getType
const Type & getType() const
tf2::transformToEigen
Eigen::Isometry3d transformToEigen(const geometry_msgs::Transform &t)
trajectory_execution_manager::TrajectoryExecutionManager::findControllers
bool findControllers(const std::set< std::string > &actuated_joints, std::size_t controller_count, const std::vector< std::string > &available_controllers, std::vector< std::string > &selected_controllers)
Definition: trajectory_execution_manager.cpp:455
trajectory_execution_manager::TrajectoryExecutionManager::ControllerInformation::state_
moveit_controller_manager::MoveItControllerManager::ControllerState state_
Definition: trajectory_execution_manager.h:249
ROS_WARN_STREAM_NAMED
#define ROS_WARN_STREAM_NAMED(name, args)
point
std::chrono::system_clock::time_point point
XmlRpc::XmlRpcValue::TypeArray
TypeArray
trajectory_execution_manager::TrajectoryExecutionManager::execution_thread_mutex_
boost::mutex execution_thread_mutex_
Definition: trajectory_execution_manager.h:313
trajectory_execution_manager::TrajectoryExecutionManager::updateControllerState
void updateControllerState(const std::string &controller, const ros::Duration &age)
Definition: trajectory_execution_manager.cpp:333
start
ROSCPP_DECL void start()
trajectory_execution_manager::TrajectoryExecutionManager::reloadControllerInformation
void reloadControllerInformation()
Definition: trajectory_execution_manager.cpp:298
XmlRpc::XmlRpcValue::hasMember
bool hasMember(const std::string &name) const
trajectory_execution_manager::TrajectoryExecutionManager::updateControllersState
void updateControllersState(const ros::Duration &age)
Definition: trajectory_execution_manager.cpp:358
moveit::core::JointModel::computeTransform
virtual void computeTransform(const double *joint_values, Eigen::Isometry3d &transf) const=0
trajectory_execution_manager::TrajectoryExecutionManager::getCurrentExpectedTrajectoryIndex
std::pair< int, int > getCurrentExpectedTrajectoryIndex() const
Definition: trajectory_execution_manager.cpp:1375
ros::Time
moveit::core::JointModel::getMimic
const JointModel * getMimic() const
selected_options
std::vector< std::vector< std::string > > selected_options
Definition: trajectory_execution_manager.cpp:448
trajectory_execution_manager::DEFAULT_CONTROLLER_GOAL_DURATION_MARGIN
static const double DEFAULT_CONTROLLER_GOAL_DURATION_MARGIN
Definition: trajectory_execution_manager.cpp:52
trajectory_execution_manager::TrajectoryExecutionManager::ControllerInformation::joints_
std::set< std::string > joints_
Definition: trajectory_execution_manager.h:247
trajectory_execution_manager.h
trajectory_execution_manager::TrajectoryExecutionManager::robot_model_
moveit::core::RobotModelConstPtr robot_model_
Definition: trajectory_execution_manager.h:300
trajectory_execution_manager::TrajectoryExecutionManager::executeThread
void executeThread(const ExecutionCompleteCallback &callback, const PathSegmentCompleteCallback &part_callback, bool auto_clear)
Definition: trajectory_execution_manager.cpp:1049
trajectory_execution_manager::TrajectoryExecutionManager::waitForExecution
moveit_controller_manager::ExecutionStatus waitForExecution()
Definition: trajectory_execution_manager.cpp:1023
trajectory_execution_manager::TrajectoryExecutionManager::~TrajectoryExecutionManager
~TrajectoryExecutionManager()
Destructor. Cancels all running trajectories (if any)
Definition: trajectory_execution_manager.cpp:103
moveit::core::JointModel::distance
virtual double distance(const double *value1, const double *value2) const=0
ROS_WARN_NAMED
#define ROS_WARN_NAMED(name,...)
moveit::core::JointModelGroup
index
unsigned int index
trajectory_execution_manager::TrajectoryExecutionManager::TrajectoryExecutionManager
TrajectoryExecutionManager(const moveit::core::RobotModelConstPtr &robot_model, const planning_scene_monitor::CurrentStateMonitorPtr &csm)
Load the controller manager plugin, start listening for events on a topic.
Definition: trajectory_execution_manager.cpp:85
tolerance
S tolerance()
ROS_INFO_STREAM_NAMED
#define ROS_INFO_STREAM_NAMED(name, args)
trajectory_execution_manager::TrajectoryExecutionManager::configure
bool configure(TrajectoryExecutionContext &context, const moveit_msgs::RobotTrajectory &trajectory, const std::vector< std::string > &controllers)
Definition: trajectory_execution_manager.cpp:816
trajectory_execution_manager::TrajectoryExecutionManager::ensureActiveControllersForGroup
bool ensureActiveControllersForGroup(const std::string &group)
Make sure the active controllers are such that trajectories that actuate joints in the specified grou...
Definition: trajectory_execution_manager.cpp:1399
trajectory_execution_manager::TrajectoryExecutionManager::wait_for_trajectory_completion_
bool wait_for_trajectory_completion_
Definition: trajectory_execution_manager.h:346
trajectory_execution_manager::TrajectoryExecutionManager::ControllerInformation::last_update_
ros::Time last_update_
Definition: trajectory_execution_manager.h:250
DurationBase< Duration >::toSec
double toSec() const
trajectory_execution_manager::TrajectoryExecutionManager::DynamicReconfigureImpl::DynamicReconfigureImpl
DynamicReconfigureImpl(TrajectoryExecutionManager *owner)
Definition: trajectory_execution_manager.cpp:63
trajectory_execution_manager::TrajectoryExecutionManager::allowed_goal_duration_margin_
double allowed_goal_duration_margin_
Definition: trajectory_execution_manager.h:338
trajectory_execution_manager::TrajectoryExecutionManager::distributeTrajectory
bool distributeTrajectory(const moveit_msgs::RobotTrajectory &trajectory, const std::vector< std::string > &controllers, std::vector< moveit_msgs::RobotTrajectory > &parts)
Definition: trajectory_execution_manager.cpp:582
trajectory_execution_manager::TrajectoryExecutionManager::clear
void clear()
Clear the trajectories to execute.
Definition: trajectory_execution_manager.cpp:1037
trajectory_execution_manager::TrajectoryExecutionManager::execution_state_mutex_
boost::mutex execution_state_mutex_
Definition: trajectory_execution_manager.h:312
trajectory_execution_manager::TrajectoryExecutionManager::push
bool push(const moveit_msgs::RobotTrajectory &trajectory, const std::string &controller="")
Definition: trajectory_execution_manager.cpp:239
trajectory_execution_manager::TrajectoryExecutionManager::execution_thread_
std::unique_ptr< boost::thread > execution_thread_
Definition: trajectory_execution_manager.h:310
trajectory_execution_manager::TrajectoryExecutionManager::time_index_mutex_
boost::mutex time_index_mutex_
Definition: trajectory_execution_manager.h:322
trajectory_execution_manager::TrajectoryExecutionManager::controller_allowed_execution_duration_scaling_
std::map< std::string, double > controller_allowed_execution_duration_scaling_
Definition: trajectory_execution_manager.h:341
moveit::core::JointModel::FIXED
FIXED
trajectory_execution_manager::TrajectoryExecutionManager::isManagingControllers
bool isManagingControllers() const
If this function returns true, then this instance of the manager is allowed to load/unload/switch con...
Definition: trajectory_execution_manager.cpp:215
trajectory_execution_manager::TrajectoryExecutionManager::event_topic_subscriber_
ros::Subscriber event_topic_subscriber_
Definition: trajectory_execution_manager.h:304
trajectory_execution_manager::TrajectoryExecutionManager::allowed_execution_duration_scaling_
double allowed_execution_duration_scaling_
Definition: trajectory_execution_manager.h:337
trajectory_execution_manager::TrajectoryExecutionManager::enableExecutionDurationMonitoring
void enableExecutionDurationMonitoring(bool flag)
Definition: trajectory_execution_manager.cpp:185
ros::Duration
trajectory_execution_manager::TrajectoryExecutionManager::waitForRobotToStop
bool waitForRobotToStop(const TrajectoryExecutionContext &context, double wait_time=1.0)
Definition: trajectory_execution_manager.cpp:1316
trajectory_execution_manager::TrajectoryExecutionManager::TrajectoryExecutionContext
Data structure that represents information necessary to execute a trajectory.
Definition: trajectory_execution_manager.h:105
moveit_controller_manager::ExecutionStatus
moveit::core::JointModel::isPassive
bool isPassive() const
trajectory_execution_manager::TrajectoryExecutionManager::PathSegmentCompleteCallback
boost::function< void(std::size_t)> PathSegmentCompleteCallback
Definition: trajectory_execution_manager.h:102
moveit::core::JointModel
XmlRpc::XmlRpcValue
trajectory_execution_manager::TrajectoryExecutionManager::known_controllers_
std::map< std::string, ControllerInformation > known_controllers_
Definition: trajectory_execution_manager.h:306
trajectory_execution_manager::TrajectoryExecutionManager::setAllowedStartTolerance
void setAllowedStartTolerance(double tolerance)
Set joint-value tolerance for validating trajectory's start point against current robot state.
Definition: trajectory_execution_manager.cpp:205
trajectory_execution_manager::TrajectoryExecutionManager::loadControllerParams
void loadControllerParams()
Definition: trajectory_execution_manager.cpp:1536
trajectory_execution_manager::TrajectoryExecutionManager::DynamicReconfigureImpl::owner_
TrajectoryExecutionManager * owner_
Definition: trajectory_execution_manager.cpp:81
ros::Time::now
static Time now()
moveit_controller_manager::ExecutionStatus::asString
std::string asString() const
moveit_controller_manager::MoveItControllerManager::ControllerState::default_
bool default_


planning
Author(s): Ioan Sucan , Sachin Chitta
autogenerated on Wed Feb 21 2024 03:25:45