moveit2
The MoveIt Motion Planning Framework for ROS 2.
trajectory_functions.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2018 Pilz GmbH & Co. KG
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 Pilz GmbH & Co. KG 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 
36 
38 #include <tf2/LinearMath/Quaternion.h>
39 #include <tf2_eigen_kdl/tf2_eigen_kdl.hpp>
40 #include <tf2_eigen/tf2_eigen.hpp>
41 #include <tf2_geometry_msgs/tf2_geometry_msgs.hpp>
42 
43 namespace
44 {
45 static const rclcpp::Logger LOGGER = rclcpp::get_logger("moveit.pilz_industrial_motion_planner.trajectory_functions");
46 }
47 
48 bool pilz_industrial_motion_planner::computePoseIK(const planning_scene::PlanningSceneConstPtr& scene,
49  const std::string& group_name, const std::string& link_name,
50  const Eigen::Isometry3d& pose, const std::string& frame_id,
51  const std::map<std::string, double>& seed,
52  std::map<std::string, double>& solution, bool check_self_collision,
53  const double timeout)
54 {
55  const moveit::core::RobotModelConstPtr& robot_model = scene->getRobotModel();
56  if (!robot_model->hasJointModelGroup(group_name))
57  {
58  RCLCPP_ERROR_STREAM(LOGGER, "Robot model has no planning group named as " << group_name);
59  return false;
60  }
61 
62  if (!robot_model->getJointModelGroup(group_name)->canSetStateFromIK(link_name))
63  {
64  RCLCPP_ERROR_STREAM(LOGGER, "No valid IK solver exists for " << link_name << " in planning group " << group_name);
65  return false;
66  }
67 
68  if (frame_id != robot_model->getModelFrame())
69  {
70  RCLCPP_ERROR_STREAM(LOGGER, "Given frame (" << frame_id << ") is unequal to model frame("
71  << robot_model->getModelFrame() << ")");
72  return false;
73  }
74 
75  moveit::core::RobotState rstate{ scene->getCurrentState() };
76  rstate.setVariablePositions(seed);
77 
78  moveit::core::GroupStateValidityCallbackFn ik_constraint_function;
79  ik_constraint_function = [check_self_collision, scene](moveit::core::RobotState* robot_state,
80  const moveit::core::JointModelGroup* joint_group,
81  const double* joint_group_variable_values) {
82  return pilz_industrial_motion_planner::isStateColliding(check_self_collision, scene, robot_state, joint_group,
83  joint_group_variable_values);
84  };
85 
86  // call ik
87  if (rstate.setFromIK(robot_model->getJointModelGroup(group_name), pose, link_name, timeout, ik_constraint_function))
88  {
89  // copy the solution
90  for (const auto& joint_name : robot_model->getJointModelGroup(group_name)->getActiveJointModelNames())
91  {
92  solution[joint_name] = rstate.getVariablePosition(joint_name);
93  }
94  return true;
95  }
96  else
97  {
98  RCLCPP_ERROR(LOGGER, "Unable to find IK solution.");
99  // TODO(henning): Re-enable logging error
100  // RCLCPP_ERROR_STREAM(LOGGER, "Inverse kinematics for pose \n" << pose.translation() << " has no solution.");
101  return false;
102  }
103 }
104 
105 bool pilz_industrial_motion_planner::computePoseIK(const planning_scene::PlanningSceneConstPtr& scene,
106  const std::string& group_name, const std::string& link_name,
107  const geometry_msgs::msg::Pose& pose, const std::string& frame_id,
108  const std::map<std::string, double>& seed,
109  std::map<std::string, double>& solution, bool check_self_collision,
110  const double timeout)
111 {
112  Eigen::Isometry3d pose_eigen;
113  tf2::convert<geometry_msgs::msg::Pose, Eigen::Isometry3d>(pose, pose_eigen);
114  return computePoseIK(scene, group_name, link_name, pose_eigen, frame_id, seed, solution, check_self_collision,
115  timeout);
116 }
117 
118 bool pilz_industrial_motion_planner::computeLinkFK(const planning_scene::PlanningSceneConstPtr& scene,
119  const std::string& link_name,
120  const std::map<std::string, double>& joint_state,
121  Eigen::Isometry3d& pose)
122 { // take robot state from the current scene
123  moveit::core::RobotState rstate{ scene->getCurrentState() };
124 
125  // check the reference frame of the target pose
126  if (!rstate.knowsFrameTransform(link_name))
127  {
128  RCLCPP_ERROR_STREAM(LOGGER, "The target link " << link_name << " is not known by robot.");
129  return false;
130  }
131 
132  rstate.setVariablePositions(joint_state);
133 
134  // update the frame
135  rstate.update();
136  pose = rstate.getFrameTransform(link_name);
137 
138  return true;
139 }
140 
142  const std::map<std::string, double>& position_last, const std::map<std::string, double>& velocity_last,
143  const std::map<std::string, double>& position_current, double duration_last, double duration_current,
145 {
146  const double epsilon = 10e-6;
147  if (duration_current <= epsilon)
148  {
149  RCLCPP_ERROR(LOGGER, "Sample duration too small, cannot compute the velocity");
150  return false;
151  }
152 
153  double velocity_current, acceleration_current;
154 
155  for (const auto& pos : position_current)
156  {
157  velocity_current = (pos.second - position_last.at(pos.first)) / duration_current;
158 
159  if (!joint_limits.verifyVelocityLimit(pos.first, velocity_current))
160  {
161  RCLCPP_ERROR_STREAM(LOGGER, "Joint velocity limit of "
162  << pos.first << " violated. Set the velocity scaling factor lower!"
163  << " Actual joint velocity is " << velocity_current << ", while the limit is "
164  << joint_limits.getLimit(pos.first).max_velocity << ". ");
165  return false;
166  }
167 
168  acceleration_current = (velocity_current - velocity_last.at(pos.first)) / (duration_last + duration_current) * 2;
169  // acceleration case
170  if (fabs(velocity_last.at(pos.first)) <= fabs(velocity_current))
171  {
172  if (joint_limits.getLimit(pos.first).has_acceleration_limits &&
173  fabs(acceleration_current) > fabs(joint_limits.getLimit(pos.first).max_acceleration))
174  {
175  RCLCPP_ERROR_STREAM(LOGGER, "Joint acceleration limit of "
176  << pos.first << " violated. Set the acceleration scaling factor lower!"
177  << " Actual joint acceleration is " << acceleration_current
178  << ", while the limit is " << joint_limits.getLimit(pos.first).max_acceleration
179  << ". ");
180  return false;
181  }
182  }
183  // deceleration case
184  else
185  {
186  if (joint_limits.getLimit(pos.first).has_deceleration_limits &&
187  fabs(acceleration_current) > fabs(joint_limits.getLimit(pos.first).max_deceleration))
188  {
189  RCLCPP_ERROR_STREAM(LOGGER, "Joint deceleration limit of "
190  << pos.first << " violated. Set the acceleration scaling factor lower!"
191  << " Actual joint deceleration is " << acceleration_current
192  << ", while the limit is " << joint_limits.getLimit(pos.first).max_deceleration
193  << ". ");
194  return false;
195  }
196  }
197  }
198 
199  return true;
200 }
201 
203  const planning_scene::PlanningSceneConstPtr& scene,
204  const pilz_industrial_motion_planner::JointLimitsContainer& joint_limits, const KDL::Trajectory& trajectory,
205  const std::string& group_name, const std::string& link_name,
206  const std::map<std::string, double>& initial_joint_position, const double& sampling_time,
207  trajectory_msgs::msg::JointTrajectory& joint_trajectory, moveit_msgs::msg::MoveItErrorCodes& error_code,
208  bool check_self_collision)
209 {
210  RCLCPP_DEBUG(LOGGER, "Generate joint trajectory from a Cartesian trajectory.");
211 
212  const moveit::core::RobotModelConstPtr& robot_model = scene->getRobotModel();
213  rclcpp::Clock clock;
214  rclcpp::Time generation_begin = clock.now();
215 
216  // generate the time samples
217  const double epsilon = 10e-06; // avoid adding the last time sample twice
218  std::vector<double> time_samples;
219  for (double t_sample = 0.0; t_sample < trajectory.Duration() - epsilon; t_sample += sampling_time)
220  {
221  time_samples.push_back(t_sample);
222  }
223  time_samples.push_back(trajectory.Duration());
224 
225  // sample the trajectory and solve the inverse kinematics
226  Eigen::Isometry3d pose_sample;
227  std::map<std::string, double> ik_solution_last, ik_solution, joint_velocity_last;
228  ik_solution_last = initial_joint_position;
229  for (const auto& item : ik_solution_last)
230  {
231  joint_velocity_last[item.first] = 0.0;
232  }
233 
234  for (std::vector<double>::const_iterator time_iter = time_samples.begin(); time_iter != time_samples.end();
235  ++time_iter)
236  {
237  tf2::transformKDLToEigen(trajectory.Pos(*time_iter), pose_sample);
238 
239  if (!computePoseIK(scene, group_name, link_name, pose_sample, robot_model->getModelFrame(), ik_solution_last,
240  ik_solution, check_self_collision))
241  {
242  RCLCPP_ERROR(LOGGER, "Failed to compute inverse kinematics solution for sampled Cartesian pose.");
243  error_code.val = moveit_msgs::msg::MoveItErrorCodes::NO_IK_SOLUTION;
244  joint_trajectory.points.clear();
245  return false;
246  }
247 
248  // check the joint limits
249  double duration_current_sample = sampling_time;
250  // last interval can be shorter than the sampling time
251  if (time_iter == (time_samples.end() - 1) && time_samples.size() > 1)
252  {
253  duration_current_sample = *time_iter - *(time_iter - 1);
254  }
255  if (time_samples.size() == 1)
256  {
257  duration_current_sample = *time_iter;
258  }
259 
260  // skip the first sample with zero time from start for limits checking
261  if (time_iter != time_samples.begin() &&
262  !verifySampleJointLimits(ik_solution_last, joint_velocity_last, ik_solution, sampling_time,
263  duration_current_sample, joint_limits))
264  {
265  RCLCPP_ERROR_STREAM(LOGGER, "Inverse kinematics solution at "
266  << *time_iter
267  << "s violates the joint velocity/acceleration/deceleration limits.");
268  error_code.val = moveit_msgs::msg::MoveItErrorCodes::PLANNING_FAILED;
269  joint_trajectory.points.clear();
270  return false;
271  }
272 
273  // fill the point with joint values
274  trajectory_msgs::msg::JointTrajectoryPoint point;
275 
276  // set joint names
277  joint_trajectory.joint_names.clear();
278  for (const auto& start_joint : initial_joint_position)
279  {
280  joint_trajectory.joint_names.push_back(start_joint.first);
281  }
282 
283  point.time_from_start = rclcpp::Duration::from_seconds(*time_iter);
284  for (const auto& joint_name : joint_trajectory.joint_names)
285  {
286  point.positions.push_back(ik_solution.at(joint_name));
287 
288  if (time_iter != time_samples.begin() && time_iter != time_samples.end() - 1)
289  {
290  double joint_velocity =
291  (ik_solution.at(joint_name) - ik_solution_last.at(joint_name)) / duration_current_sample;
292  point.velocities.push_back(joint_velocity);
293  point.accelerations.push_back((joint_velocity - joint_velocity_last.at(joint_name)) /
294  (duration_current_sample + sampling_time) * 2);
295  joint_velocity_last[joint_name] = joint_velocity;
296  }
297  else
298  {
299  point.velocities.push_back(0.);
300  point.accelerations.push_back(0.);
301  joint_velocity_last[joint_name] = 0.;
302  }
303  }
304 
305  // update joint trajectory
306  joint_trajectory.points.push_back(point);
307  ik_solution_last = ik_solution;
308  }
309 
310  error_code.val = moveit_msgs::msg::MoveItErrorCodes::SUCCESS;
311  double duration_ms = (clock.now() - generation_begin).seconds() * 1000;
312  RCLCPP_DEBUG_STREAM(LOGGER, "Generate trajectory (N-Points: "
313  << joint_trajectory.points.size() << ") took " << duration_ms << " ms | "
314  << duration_ms / joint_trajectory.points.size() << " ms per Point");
315 
316  return true;
317 }
318 
320  const planning_scene::PlanningSceneConstPtr& scene,
322  const pilz_industrial_motion_planner::CartesianTrajectory& trajectory, const std::string& group_name,
323  const std::string& link_name, const std::map<std::string, double>& initial_joint_position,
324  const std::map<std::string, double>& initial_joint_velocity,
325  trajectory_msgs::msg::JointTrajectory& joint_trajectory, moveit_msgs::msg::MoveItErrorCodes& error_code,
326  bool check_self_collision)
327 {
328  RCLCPP_DEBUG(LOGGER, "Generate joint trajectory from a Cartesian trajectory.");
329 
330  const moveit::core::RobotModelConstPtr& robot_model = scene->getRobotModel();
331  rclcpp::Clock clock;
332  rclcpp::Time generation_begin = clock.now();
333 
334  std::map<std::string, double> ik_solution_last = initial_joint_position;
335  std::map<std::string, double> joint_velocity_last = initial_joint_velocity;
336  double duration_last = 0;
337  double duration_current = 0;
338  joint_trajectory.joint_names.clear();
339  for (const auto& joint_position : ik_solution_last)
340  {
341  joint_trajectory.joint_names.push_back(joint_position.first);
342  }
343  std::map<std::string, double> ik_solution;
344  for (size_t i = 0; i < trajectory.points.size(); ++i)
345  {
346  // compute inverse kinematics
347  if (!computePoseIK(scene, group_name, link_name, trajectory.points.at(i).pose, robot_model->getModelFrame(),
348  ik_solution_last, ik_solution, check_self_collision))
349  {
350  RCLCPP_ERROR(LOGGER, "Failed to compute inverse kinematics solution for sampled "
351  "Cartesian pose.");
352  error_code.val = moveit_msgs::msg::MoveItErrorCodes::NO_IK_SOLUTION;
353  joint_trajectory.points.clear();
354  return false;
355  }
356 
357  // verify the joint limits
358  if (i == 0)
359  {
360  duration_current = trajectory.points.front().time_from_start.seconds();
361  duration_last = duration_current;
362  }
363  else
364  {
365  duration_current =
366  trajectory.points.at(i).time_from_start.seconds() - trajectory.points.at(i - 1).time_from_start.seconds();
367  }
368 
369  if (!verifySampleJointLimits(ik_solution_last, joint_velocity_last, ik_solution, duration_last, duration_current,
370  joint_limits))
371  {
372  // LCOV_EXCL_START since the same code was captured in a test in the other
373  // overload generateJointTrajectory(...,
374  // KDL::Trajectory, ...)
375  // TODO: refactor to avoid code duplication.
376  RCLCPP_ERROR_STREAM(LOGGER, "Inverse kinematics solution of the "
377  << i
378  << "th sample violates the joint "
379  "velocity/acceleration/deceleration limits.");
380  error_code.val = moveit_msgs::msg::MoveItErrorCodes::PLANNING_FAILED;
381  joint_trajectory.points.clear();
382  return false;
383  // LCOV_EXCL_STOP
384  }
385 
386  // compute the waypoint
387  trajectory_msgs::msg::JointTrajectoryPoint waypoint_joint;
388  waypoint_joint.time_from_start = trajectory.points.at(i).time_from_start;
389  for (const auto& joint_name : joint_trajectory.joint_names)
390  {
391  waypoint_joint.positions.push_back(ik_solution.at(joint_name));
392  double joint_velocity = (ik_solution.at(joint_name) - ik_solution_last.at(joint_name)) / duration_current;
393  waypoint_joint.velocities.push_back(joint_velocity);
394  waypoint_joint.accelerations.push_back((joint_velocity - joint_velocity_last.at(joint_name)) /
395  (duration_current + duration_last) * 2);
396  // update the joint velocity
397  joint_velocity_last[joint_name] = joint_velocity;
398  }
399 
400  // update joint trajectory
401  joint_trajectory.points.push_back(waypoint_joint);
402  ik_solution_last = ik_solution;
403  duration_last = duration_current;
404  }
405 
406  error_code.val = moveit_msgs::msg::MoveItErrorCodes::SUCCESS;
407 
408  double duration_ms = (clock.now() - generation_begin).seconds() * 1000;
409  RCLCPP_DEBUG_STREAM(LOGGER, "Generate trajectory (N-Points: "
410  << joint_trajectory.points.size() << ") took " << duration_ms << " ms | "
411  << duration_ms / joint_trajectory.points.size() << " ms per Point");
412 
413  return true;
414 }
415 
417  const robot_trajectory::RobotTrajectoryPtr& first_trajectory,
418  const robot_trajectory::RobotTrajectoryPtr& second_trajectory, double epsilon, double& sampling_time)
419 {
420  // The last sample is ignored because it is allowed to violate the sampling
421  // time.
422  std::size_t n1 = first_trajectory->getWayPointCount() - 1;
423  std::size_t n2 = second_trajectory->getWayPointCount() - 1;
424  if ((n1 < 2) && (n2 < 2))
425  {
426  RCLCPP_ERROR_STREAM(LOGGER, "Both trajectories do not have enough points to determine sampling time.");
427  return false;
428  }
429 
430  if (n1 >= 2)
431  {
432  sampling_time = first_trajectory->getWayPointDurationFromPrevious(1);
433  }
434  else
435  {
436  sampling_time = second_trajectory->getWayPointDurationFromPrevious(1);
437  }
438 
439  for (std::size_t i = 1; i < std::max(n1, n2); ++i)
440  {
441  if (i < n1)
442  {
443  if (fabs(sampling_time - first_trajectory->getWayPointDurationFromPrevious(i)) > epsilon)
444  {
445  RCLCPP_ERROR_STREAM(LOGGER, "First trajectory violates sampline time " << sampling_time << " between points "
446  << (i - 1) << "and " << i
447  << " (indices).");
448  return false;
449  }
450  }
451 
452  if (i < n2)
453  {
454  if (fabs(sampling_time - second_trajectory->getWayPointDurationFromPrevious(i)) > epsilon)
455  {
456  RCLCPP_ERROR_STREAM(LOGGER, "Second trajectory violates sampline time " << sampling_time << " between points "
457  << (i - 1) << "and " << i
458  << " (indices).");
459  return false;
460  }
461  }
462  }
463 
464  return true;
465 }
466 
468  const moveit::core::RobotState& state2,
469  const std::string& joint_group_name, double epsilon)
470 {
471  Eigen::VectorXd joint_position_1, joint_position_2;
472 
473  state1.copyJointGroupPositions(joint_group_name, joint_position_1);
474  state2.copyJointGroupPositions(joint_group_name, joint_position_2);
475 
476  if ((joint_position_1 - joint_position_2).norm() > epsilon)
477  {
478  RCLCPP_DEBUG_STREAM(LOGGER, "Joint positions of the two states are different. state1: "
479  << joint_position_1 << " state2: " << joint_position_2);
480  return false;
481  }
482 
483  Eigen::VectorXd joint_velocity_1, joint_velocity_2;
484 
485  state1.copyJointGroupVelocities(joint_group_name, joint_velocity_1);
486  state2.copyJointGroupVelocities(joint_group_name, joint_velocity_2);
487 
488  if ((joint_velocity_1 - joint_velocity_2).norm() > epsilon)
489  {
490  RCLCPP_DEBUG_STREAM(LOGGER, "Joint velocities of the two states are different. state1: "
491  << joint_velocity_1 << " state2: " << joint_velocity_2);
492  return false;
493  }
494 
495  Eigen::VectorXd joint_acc_1, joint_acc_2;
496 
497  state1.copyJointGroupAccelerations(joint_group_name, joint_acc_1);
498  state2.copyJointGroupAccelerations(joint_group_name, joint_acc_2);
499 
500  if ((joint_acc_1 - joint_acc_2).norm() > epsilon)
501  {
502  RCLCPP_DEBUG_STREAM(LOGGER, "Joint accelerations of the two states are different. state1: "
503  << joint_acc_1 << " state2: " << joint_acc_2);
504  return false;
505  }
506 
507  return true;
508 }
509 
511  const std::string& group, double EPSILON)
512 {
513  Eigen::VectorXd joint_variable;
514  state.copyJointGroupVelocities(group, joint_variable);
515  if (joint_variable.norm() > EPSILON)
516  {
517  RCLCPP_DEBUG(LOGGER, "Joint velocities are not zero.");
518  return false;
519  }
520  state.copyJointGroupAccelerations(group, joint_variable);
521  if (joint_variable.norm() > EPSILON)
522  {
523  RCLCPP_DEBUG(LOGGER, "Joint accelerations are not zero.");
524  return false;
525  }
526  return true;
527 }
528 
530  const Eigen::Vector3d& center_position,
531  const double& r,
532  const robot_trajectory::RobotTrajectoryPtr& traj,
533  bool inverseOrder, std::size_t& index)
534 {
535  RCLCPP_DEBUG(LOGGER, "Start linear search for intersection point.");
536 
537  const size_t waypoint_num = traj->getWayPointCount();
538 
539  if (inverseOrder)
540  {
541  for (size_t i = waypoint_num - 1; i > 0; --i)
542  {
543  if (intersectionFound(center_position, traj->getWayPointPtr(i)->getFrameTransform(link_name).translation(),
544  traj->getWayPointPtr(i - 1)->getFrameTransform(link_name).translation(), r))
545  {
546  index = i;
547  return true;
548  }
549  }
550  }
551  else
552  {
553  for (size_t i = 0; i < waypoint_num - 1; ++i)
554  {
555  if (intersectionFound(center_position, traj->getWayPointPtr(i)->getFrameTransform(link_name).translation(),
556  traj->getWayPointPtr(i + 1)->getFrameTransform(link_name).translation(), r))
557  {
558  index = i;
559  return true;
560  }
561  }
562  }
563 
564  return false;
565 }
566 
568  const Eigen::Vector3d& p_current, const Eigen::Vector3d& p_next,
569  const double& r)
570 {
571  return ((p_current - p_center).norm() <= r) && ((p_next - p_center).norm() >= r);
572 }
573 
574 bool pilz_industrial_motion_planner::isStateColliding(const bool test_for_self_collision,
575  const planning_scene::PlanningSceneConstPtr& scene,
576  moveit::core::RobotState* rstate,
578  const double* const ik_solution)
579 {
580  if (!test_for_self_collision)
581  {
582  return true;
583  }
584 
585  rstate->setJointGroupPositions(group, ik_solution);
586  rstate->update();
588  collision_req.group_name = group->getName();
589  collision_req.verbose = true;
591  scene->checkSelfCollision(collision_req, collision_res, *rstate);
592  return !collision_res.collision;
593 }
594 
595 void normalizeQuaternion(geometry_msgs::msg::Quaternion& quat)
596 {
597  tf2::Quaternion q;
598  tf2::convert<geometry_msgs::msg::Quaternion, tf2::Quaternion>(quat, q);
599  quat = tf2::toMsg(q.normalized());
600 }
601 
602 Eigen::Isometry3d getConstraintPose(const geometry_msgs::msg::Point& position,
603  const geometry_msgs::msg::Quaternion& orientation,
604  const geometry_msgs::msg::Vector3& offset)
605 {
606  Eigen::Quaterniond quat;
607  tf2::fromMsg(orientation, quat);
608  quat.normalize();
609  Eigen::Vector3d v;
610  tf2::fromMsg(position, v);
611 
612  Eigen::Isometry3d pose = Eigen::Translation3d(v) * quat;
613 
614  tf2::fromMsg(offset, v);
615  pose.translation() -= quat * v;
616  return pose;
617 }
618 
619 Eigen::Isometry3d getConstraintPose(const moveit_msgs::msg::Constraints& goal)
620 {
621  return getConstraintPose(goal.position_constraints.front().constraint_region.primitive_poses.front().position,
622  goal.orientation_constraints.front().orientation,
623  goal.position_constraints.front().target_point_offset);
624 }
Representation of a robot's state. This includes position, velocity, acceleration and effort.
Definition: robot_state.h:90
void copyJointGroupVelocities(const std::string &joint_group_name, std::vector< double > &gstate) const
For a given group, copy the velocity values of the variables that make up the group into another loca...
Definition: robot_state.h:791
void setJointGroupPositions(const std::string &joint_group_name, const double *gstate)
Given positions for the variables that make up a group, in the order found in the group (including va...
Definition: robot_state.h:605
void copyJointGroupPositions(const std::string &joint_group_name, std::vector< double > &gstate) const
For a given group, copy the position values of the variables that make up the group into another loca...
Definition: robot_state.h:691
void update(bool force=false)
Update all transforms.
void copyJointGroupAccelerations(const std::string &joint_group_name, std::vector< double > &gstate) const
For a given group, copy the acceleration values of the variables that make up the group into another ...
Definition: robot_state.h:891
Container for JointLimits, essentially a map with convenience functions. Adds the ability to as for l...
Vec3fX< details::Vec3Data< double > > Vector3d
Definition: fcl_compat.h:89
std::function< bool(RobotState *robot_state, const JointModelGroup *joint_group, const double *joint_group_variable_values)> GroupStateValidityCallbackFn
Signature for functions that can verify that if the group joint_group in robot_state is set to joint_...
Definition: robot_state.h:70
frame_id
Definition: pick.py:63
scene
Definition: pick.py:52
bool isStateColliding(const bool test_for_self_collision, const planning_scene::PlanningSceneConstPtr &scene, moveit::core::RobotState *state, const moveit::core::JointModelGroup *const group, const double *const ik_solution)
Checks if current robot state is in self collision.
bool generateJointTrajectory(const planning_scene::PlanningSceneConstPtr &scene, const JointLimitsContainer &joint_limits, const KDL::Trajectory &trajectory, const std::string &group_name, const std::string &link_name, const std::map< std::string, double > &initial_joint_position, const double &sampling_time, trajectory_msgs::msg::JointTrajectory &joint_trajectory, moveit_msgs::msg::MoveItErrorCodes &error_code, bool check_self_collision=false)
Generate joint trajectory from a KDL Cartesian trajectory.
bool linearSearchIntersectionPoint(const std::string &link_name, const Eigen::Vector3d &center_position, const double &r, const robot_trajectory::RobotTrajectoryPtr &traj, bool inverseOrder, std::size_t &index)
Performs a linear search for the intersection point of the trajectory with the blending radius.
bool isRobotStateStationary(const moveit::core::RobotState &state, const std::string &group, double EPSILON)
check if the robot state have zero velocity/acceleration
bool determineAndCheckSamplingTime(const robot_trajectory::RobotTrajectoryPtr &first_trajectory, const robot_trajectory::RobotTrajectoryPtr &second_trajectory, double EPSILON, double &sampling_time)
Determines the sampling time and checks that both trajectroies use the same sampling time.
bool verifySampleJointLimits(const std::map< std::string, double > &position_last, const std::map< std::string, double > &velocity_last, const std::map< std::string, double > &position_current, double duration_last, double duration_current, const JointLimitsContainer &joint_limits)
verify the velocity/acceleration limits of current sample (based on backward difference computation) ...
bool intersectionFound(const Eigen::Vector3d &p_center, const Eigen::Vector3d &p_current, const Eigen::Vector3d &p_next, const double &r)
bool computePoseIK(const planning_scene::PlanningSceneConstPtr &scene, const std::string &group_name, const std::string &link_name, const Eigen::Isometry3d &pose, const std::string &frame_id, const std::map< std::string, double > &seed, std::map< std::string, double > &solution, bool check_self_collision=true, const double timeout=0.0)
compute the inverse kinematics of a given pose, also check robot self collision
bool isRobotStateEqual(const moveit::core::RobotState &state1, const moveit::core::RobotState &state2, const std::string &joint_group_name, double epsilon)
Check if the two robot states have the same joint position/velocity/acceleration.
bool computeLinkFK(const planning_scene::PlanningSceneConstPtr &scene, const std::string &link_name, const std::map< std::string, double > &joint_state, Eigen::Isometry3d &pose)
compute the pose of a link at give robot state
r
Definition: plan.py:56
const rclcpp::Logger LOGGER
Definition: async_test.h:31
Representation of a collision checking request.
std::string group_name
The group name to check collisions for (optional; if empty, assume the complete robot)
bool verbose
Flag indicating whether information about detected collisions should be reported.
Representation of a collision checking result.
bool collision
True if collision was found, false otherwise.
std::vector< CartesianTrajectoryPoint > points
void normalizeQuaternion(geometry_msgs::msg::Quaternion &quat)
Eigen::Isometry3d getConstraintPose(const geometry_msgs::msg::Point &position, const geometry_msgs::msg::Quaternion &orientation, const geometry_msgs::msg::Vector3 &offset)
Adapt goal pose, defined by position+orientation, to consider offset.