moveit2
The MoveIt Motion Planning Framework for ROS 2.
unittest_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 
35 #include <gtest/gtest.h>
36 
37 #include <map>
38 #include <math.h>
39 #include <string>
40 #include <vector>
41 
42 #include <Eigen/Geometry>
43 #include <kdl/frames.hpp>
44 #include <kdl/path_roundedcomposite.hpp>
45 #include <kdl/rotational_interpolation_sa.hpp>
46 #include <kdl/trajectory.hpp>
47 #include <kdl/trajectory_segment.hpp>
48 #include <kdl/velocityprofile_trap.hpp>
53 #include <tf2_eigen/tf2_eigen.hpp>
54 #include <tf2_geometry_msgs/tf2_geometry_msgs.hpp>
55 
60 #include "test_utils.h"
61 
62 #define _USE_MATH_DEFINES
63 
64 static constexpr double EPSILON{ 1.0e-6 };
65 static constexpr double IK_SEED_OFFSET{ 0.1 };
66 static constexpr double L0{ 0.2604 }; // Height of foot
67 static constexpr double L1{ 0.3500 }; // Height of first connector
68 static constexpr double L2{ 0.3070 }; // Height of second connector
69 static constexpr double L3{ 0.0840 }; // Distance last joint to flange
70 
71 // parameters from parameter server
72 const std::string PARAM_PLANNING_GROUP_NAME("planning_group");
73 const std::string GROUP_TIP_LINK_NAME("group_tip_link");
74 const std::string ROBOT_TCP_LINK_NAME("tcp_link");
75 const std::string IK_FAST_LINK_NAME("ik_fast_link");
76 const std::string RANDOM_TEST_NUMBER("random_test_number");
77 
81 class TrajectoryFunctionsTestBase : public testing::Test
82 {
83 protected:
88  void SetUp() override
89  {
90  rclcpp::NodeOptions node_options;
91  node_options.automatically_declare_parameters_from_overrides(true);
92  node_ = rclcpp::Node::make_shared("unittest_trajectory_functions", node_options);
93 
94  // load robot model
95  rm_loader_ = std::make_unique<robot_model_loader::RobotModelLoader>(node_);
96  robot_model_ = rm_loader_->getModel();
97  ASSERT_TRUE(bool(robot_model_)) << "Failed to load robot model";
98  robot_state_ = std::make_shared<moveit::core::RobotState>(robot_model_);
99  planning_scene_ = std::make_shared<planning_scene::PlanningScene>(robot_model_);
100 
101  // get parameters
102  ASSERT_TRUE(node_->has_parameter("planning_group"));
103  node_->get_parameter<std::string>("planning_group", planning_group_);
104  ASSERT_TRUE(node_->has_parameter("group_tip_link"));
105  node_->get_parameter<std::string>("group_tip_link", group_tip_link_);
106  ASSERT_TRUE(node_->has_parameter("tcp_link"));
107  node_->get_parameter<std::string>("tcp_link", tcp_link_);
108  ASSERT_TRUE(node_->has_parameter("ik_fast_link"));
109  node_->get_parameter<std::string>("ik_fast_link", ik_fast_link_);
110  ASSERT_TRUE(node_->has_parameter("random_test_number"));
111  node_->get_parameter<int>("random_test_number", random_test_number_);
112 
113  // check robot model
115 
116  // initialize the zero state configurationg and test joint state
117  joint_names_ = robot_model_->getJointModelGroup(planning_group_)->getActiveJointModelNames();
118  for (const auto& joint_name : joint_names_)
119  {
120  zero_state_[joint_name] = 0.0;
121  }
122  }
123 
124  void TearDown() override
125  {
126  robot_model_.reset();
127  }
128 
136  bool tfNear(const Eigen::Isometry3d& pose1, const Eigen::Isometry3d& pose2, const double& epsilon);
137 
145  bool jointsNear(const std::vector<double>& joints1, const std::vector<double>& joints2, double epsilon);
146 
153  std::vector<double> getJoints(const moveit::core::JointModelGroup* jmg, const moveit::core::RobotState& state);
154 
164  const std::string& object_name, const Eigen::Isometry3d& object_pose,
165  const moveit::core::FixedTransformsMap& subframes);
166 
167 protected:
168  // ros stuff
169  rclcpp::Node::SharedPtr node_;
170  moveit::core::RobotModelConstPtr robot_model_;
171  moveit::core::RobotStatePtr robot_state_;
172  std::unique_ptr<robot_model_loader::RobotModelLoader> rm_loader_;
173  planning_scene::PlanningSceneConstPtr planning_scene_;
174 
175  // test parameters from parameter server
178  std::vector<std::string> joint_names_;
179  std::map<std::string, double> zero_state_;
180 
181  // random seed
182  uint32_t random_seed_{ 100 };
183  random_numbers::RandomNumberGenerator rng_{ random_seed_ };
184 };
185 
186 bool TrajectoryFunctionsTestBase::tfNear(const Eigen::Isometry3d& pose1, const Eigen::Isometry3d& pose2,
187  const double& epsilon)
188 {
189  for (std::size_t i = 0; i < 3; ++i)
190  for (std::size_t j = 0; j < 4; ++j)
191  {
192  if (fabs(pose1(i, j) - pose2(i, j)) > fabs(epsilon))
193  return false;
194  }
195  return true;
196 }
197 
198 bool TrajectoryFunctionsTestBase::jointsNear(const std::vector<double>& joints1, const std::vector<double>& joints2,
199  double epsilon)
200 {
201  if (joints1.size() != joints2.size())
202  {
203  return false;
204  }
205  for (std::size_t i = 0; i < joints1.size(); ++i)
206  {
207  if (fabs(joints1.at(i) - joints2.at(i)) > fabs(epsilon))
208  {
209  return false;
210  }
211  }
212  return true;
213 }
214 
216  const moveit::core::RobotState& state)
217 {
218  std::vector<double> joints;
219  for (const auto& name : jmg->getActiveJointModelNames())
220  {
221  joints.push_back(state.getVariablePosition(name));
222  }
223  return joints;
224 }
225 
227  const std::string& object_name, const Eigen::Isometry3d& object_pose,
228  const moveit::core::FixedTransformsMap& subframes)
229 {
230  state.attachBody(std::make_unique<moveit::core::AttachedBody>(
231  link, object_name, object_pose, std::vector<shapes::ShapeConstPtr>{}, EigenSTL::vector_Isometry3d{},
232  std::set<std::string>{}, trajectory_msgs::msg::JointTrajectory{}, subframes));
233 }
234 
239 {
240 };
241 
242 // TODO(henningkayser): re-enable gripper tests
243 // /**
244 // * @brief Parametrized class for tests, that only run with a gripper
245 // */
246 // class TrajectoryFunctionsTestOnlyGripper : public TrajectoryFunctionsTestBase
247 // {
248 // };
249 
256 {
257  Eigen::Isometry3d tip_pose;
258  std::map<std::string, double> test_state = zero_state_;
259  EXPECT_TRUE(pilz_industrial_motion_planner::computeLinkFK(*robot_state_, group_tip_link_, test_state, tip_pose));
260  EXPECT_NEAR(tip_pose(0, 3), 0, EPSILON);
261  EXPECT_NEAR(tip_pose(1, 3), 0, EPSILON);
262  EXPECT_NEAR(tip_pose(2, 3), L0 + L1 + L2 + L3, EPSILON);
263 
264  test_state[joint_names_.at(1)] = M_PI_2;
265  EXPECT_TRUE(pilz_industrial_motion_planner::computeLinkFK(*robot_state_, group_tip_link_, test_state, tip_pose));
266  EXPECT_NEAR(tip_pose(0, 3), L1 + L2 + L3, EPSILON);
267  EXPECT_NEAR(tip_pose(1, 3), 0, EPSILON);
268  EXPECT_NEAR(tip_pose(2, 3), L0, EPSILON);
269 
270  test_state[joint_names_.at(1)] = -M_PI_2;
271  test_state[joint_names_.at(2)] = M_PI_2;
272  EXPECT_TRUE(pilz_industrial_motion_planner::computeLinkFK(*robot_state_, group_tip_link_, test_state, tip_pose));
273  EXPECT_NEAR(tip_pose(0, 3), -L1, EPSILON);
274  EXPECT_NEAR(tip_pose(1, 3), 0, EPSILON);
275  EXPECT_NEAR(tip_pose(2, 3), L0 - L2 - L3, EPSILON);
276 
277  // wrong link name
278  std::string link_name = "wrong_link_name";
279  EXPECT_FALSE(pilz_industrial_motion_planner::computeLinkFK(*robot_state_, link_name, test_state, tip_pose));
280 }
281 
286 {
287  // Load solver
288  const moveit::core::JointModelGroup* jmg = robot_model_->getJointModelGroup(planning_group_);
289  const kinematics::KinematicsBaseConstPtr& solver = jmg->getSolverInstance();
290 
291  if (!solver)
292  {
293  throw("No IK solver configured for group '" + planning_group_ + "'");
294  }
295  // robot state
296  moveit::core::RobotState rstate(robot_model_);
297 
298  while (random_test_number_ > 0)
299  {
300  // sample random robot state
301  rstate.setToRandomPositions(jmg, rng_);
302  rstate.update();
303  geometry_msgs::msg::Pose pose_expect = tf2::toMsg(rstate.getFrameTransform(ik_fast_link_));
304 
305  // prepare inverse kinematics
306  std::vector<geometry_msgs::msg::Pose> ik_poses;
307  ik_poses.push_back(pose_expect);
308  std::vector<double> ik_seed, ik_expect, ik_actual;
309  for (const auto& joint_name : jmg->getActiveJointModelNames())
310  {
311  ik_expect.push_back(rstate.getVariablePosition(joint_name));
312  if (rstate.getVariablePosition(joint_name) > 0)
313  ik_seed.push_back(rstate.getVariablePosition(joint_name) - IK_SEED_OFFSET);
314  else
315  ik_seed.push_back(rstate.getVariablePosition(joint_name) + IK_SEED_OFFSET);
316  }
317 
318  std::vector<std::vector<double>> ik_solutions;
320  moveit_msgs::msg::MoveItErrorCodes err_code;
322 
323  // compute all ik solutions
324  EXPECT_TRUE(solver->getPositionIK(ik_poses, ik_seed, ik_solutions, ik_result, options));
325 
326  // compute one ik solution
327  EXPECT_TRUE(solver->getPositionIK(pose_expect, ik_seed, ik_actual, err_code));
328 
329  ASSERT_EQ(ik_expect.size(), ik_actual.size());
330 
331  for (std::size_t i = 0; i < ik_expect.size(); ++i)
332  {
333  EXPECT_NEAR(ik_actual.at(i), ik_expect.at(i), 4 * IK_SEED_OFFSET);
334  }
335 
336  --random_test_number_;
337  }
338 }
339 
345 {
346  // robot state
347  moveit::core::RobotState rstate(robot_model_);
348  const moveit::core::JointModelGroup* jmg = robot_model_->getJointModelGroup(planning_group_);
349 
350  while (random_test_number_ > 0)
351  {
352  // sample random robot state
353  rstate.setToRandomPositions(jmg, rng_);
354 
355  Eigen::Isometry3d pose_expect = rstate.getFrameTransform(tcp_link_);
356 
357  // copy the random state and set ik seed
358  std::map<std::string, double> ik_seed, ik_expect;
359  for (const auto& joint_name : joint_names_)
360  {
361  ik_expect[joint_name] = rstate.getVariablePosition(joint_name);
362  if (rstate.getVariablePosition(joint_name) > 0)
363  ik_seed[joint_name] = rstate.getVariablePosition(joint_name) - IK_SEED_OFFSET;
364  else
365  ik_seed[joint_name] = rstate.getVariablePosition(joint_name) + IK_SEED_OFFSET;
366  }
367 
368  rstate.setVariablePositions(ik_seed);
369  rstate.update();
370 
371  // compute the ik
372  std::map<std::string, double> ik_actual;
373 
374  EXPECT_TRUE(rstate.setFromIK(robot_model_->getJointModelGroup(planning_group_), pose_expect, tcp_link_));
375 
376  for (const auto& joint_name : joint_names_)
377  {
378  ik_actual[joint_name] = rstate.getVariablePosition(joint_name);
379  }
380 
381  // compare ik solution and expected value
382  for (const auto& joint_pair : ik_actual)
383  {
384  EXPECT_NEAR(joint_pair.second, ik_expect.at(joint_pair.first), 4 * IK_SEED_OFFSET);
385  }
386 
387  // compute the pose from ik_solution
388  rstate.setVariablePositions(ik_actual);
389  rstate.update();
390  Eigen::Isometry3d pose_actual = rstate.getFrameTransform(tcp_link_);
391 
392  EXPECT_TRUE(tfNear(pose_expect, pose_actual, EPSILON));
393 
394  --random_test_number_;
395  }
396 }
397 
398 TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testIKRobotStateWithIdentityCollisionObject)
399 {
400  // Set up a default robot
401  moveit::core::RobotState state(robot_model_);
402  state.setToDefaultValues();
403  const moveit::core::JointModelGroup* jmg = robot_model_->getJointModelGroup(planning_group_);
404 
405  std::vector<double> default_joints = getJoints(jmg, state);
406  const moveit::core::LinkModel* tip_link = robot_model_->getLinkModel(tcp_link_);
407  Eigen::Isometry3d tip_pose_in_base = state.getFrameTransform(tcp_link_);
408 
409  // Attach an object with an ignored subframe, and no transform
410  Eigen::Isometry3d object_pose_in_tip = Eigen::Isometry3d::Identity();
411  moveit::core::FixedTransformsMap subframes({ { "ignored", Eigen::Isometry3d::Identity() } });
412  attachToLink(state, tip_link, "object", object_pose_in_tip, subframes);
413 
414  // The RobotState should be able to use an object pose to set the joints
415  Eigen::Isometry3d object_pose_in_base = tip_pose_in_base * object_pose_in_tip;
416  bool success = state.setFromIK(jmg, object_pose_in_base, "object");
417  EXPECT_TRUE(success);
418 
419  // Given the target pose is the default pose of the object, the joints should be unchanged
420  std::vector<double> ik_joints = getJoints(jmg, state);
421  EXPECT_TRUE(jointsNear(ik_joints, default_joints, 4 * IK_SEED_OFFSET));
422 }
423 
424 TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testIKRobotStateWithTransformedCollisionObject)
425 {
426  // Set up a default robot
427  moveit::core::RobotState state(robot_model_);
428  state.setToDefaultValues();
429  const moveit::core::JointModelGroup* jmg = robot_model_->getJointModelGroup(planning_group_);
430 
431  std::vector<double> default_joints = getJoints(jmg, state);
432  const moveit::core::LinkModel* tip_link = robot_model_->getLinkModel(tcp_link_);
433  Eigen::Isometry3d tip_pose_in_base = state.getFrameTransform(tcp_link_);
434 
435  // Attach an object with no subframes, and a non-trivial transform
436  Eigen::Isometry3d object_pose_in_tip;
437  object_pose_in_tip = Eigen::Translation3d(1, 2, 3);
438  object_pose_in_tip *= Eigen::AngleAxis(M_PI_2, Eigen::Vector3d::UnitX());
439  moveit::core::FixedTransformsMap subframes({ { "ignored", Eigen::Isometry3d::Identity() } });
440  attachToLink(state, tip_link, "object", object_pose_in_tip, subframes);
441 
442  // The RobotState should be able to use an object pose to set the joints
443  Eigen::Isometry3d object_pose_in_base = tip_pose_in_base * object_pose_in_tip;
444  bool success = state.setFromIK(jmg, object_pose_in_base, "object");
445  EXPECT_TRUE(success);
446 
447  // Given the target pose is the default pose of the object, the joints should be unchanged
448  std::vector<double> ik_joints = getJoints(jmg, state);
449  EXPECT_TRUE(jointsNear(ik_joints, default_joints, 4 * IK_SEED_OFFSET));
450 }
451 
452 TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testIKRobotStateWithIdentitySubframe)
453 {
454  // Set up a default robot
455  moveit::core::RobotState state(robot_model_);
456  state.setToDefaultValues();
457  const moveit::core::JointModelGroup* jmg = robot_model_->getJointModelGroup(planning_group_);
458 
459  std::vector<double> default_joints = getJoints(jmg, state);
460  const moveit::core::LinkModel* tip_link = robot_model_->getLinkModel(tcp_link_);
461  Eigen::Isometry3d tip_pose_in_base = state.getFrameTransform(tcp_link_);
462 
463  // Attach an object and subframe with no transforms
464  Eigen::Isometry3d object_pose_in_tip = Eigen::Isometry3d::Identity();
465  Eigen::Isometry3d subframe_pose_in_object = Eigen::Isometry3d::Identity();
466  moveit::core::FixedTransformsMap subframes({ { "subframe", subframe_pose_in_object } });
467  attachToLink(state, tip_link, "object", object_pose_in_tip, subframes);
468 
469  // The RobotState should be able to use a subframe pose to set the joints
470  Eigen::Isometry3d subframe_pose_in_base = tip_pose_in_base * object_pose_in_tip * subframe_pose_in_object;
471  bool success = state.setFromIK(jmg, subframe_pose_in_base, "object/subframe");
472  EXPECT_TRUE(success);
473 
474  // Given the target pose is the default pose of the subframe, the joints should be unchanged
475  std::vector<double> ik_joints = getJoints(jmg, state);
476  EXPECT_TRUE(jointsNear(ik_joints, default_joints, 4 * IK_SEED_OFFSET));
477 }
478 
479 TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testIKRobotStateWithTransformedSubframe)
480 {
481  // Set up a default robot
482  moveit::core::RobotState state(robot_model_);
483  state.setToDefaultValues();
484  const moveit::core::JointModelGroup* jmg = robot_model_->getJointModelGroup(planning_group_);
485 
486  std::vector<double> default_joints = getJoints(jmg, state);
487  const moveit::core::LinkModel* tip_link = robot_model_->getLinkModel(tcp_link_);
488  Eigen::Isometry3d tip_pose_in_base = state.getFrameTransform(tcp_link_);
489 
490  // Attach an object and subframe with non-trivial transforms
491  Eigen::Isometry3d object_pose_in_tip;
492  object_pose_in_tip = Eigen::Translation3d(1, 2, 3);
493  object_pose_in_tip *= Eigen::AngleAxis(M_PI_2, Eigen::Vector3d::UnitX());
494 
495  Eigen::Isometry3d subframe_pose_in_object;
496  subframe_pose_in_object = Eigen::Translation3d(4, 5, 6);
497  subframe_pose_in_object *= Eigen::AngleAxis(M_PI_2, Eigen::Vector3d::UnitY());
498 
499  moveit::core::FixedTransformsMap subframes({ { "subframe", subframe_pose_in_object } });
500  attachToLink(state, tip_link, "object", object_pose_in_tip, subframes);
501 
502  // The RobotState should be able to use a subframe pose to set the joints
503  Eigen::Isometry3d subframe_pose_in_base = tip_pose_in_base * object_pose_in_tip * subframe_pose_in_object;
504  bool success = state.setFromIK(jmg, subframe_pose_in_base, "object/subframe");
505  EXPECT_TRUE(success);
506 
507  // Given the target pose is the default pose of the subframe, the joints should be unchanged
508  std::vector<double> ik_joints = getJoints(jmg, state);
509  EXPECT_TRUE(jointsNear(ik_joints, default_joints, 4 * IK_SEED_OFFSET));
510 }
511 
517 {
518  // robot state
519  moveit::core::RobotState rstate(robot_model_);
520 
521  const std::string frame_id = robot_model_->getModelFrame();
522  const moveit::core::JointModelGroup* jmg = robot_model_->getJointModelGroup(planning_group_);
523 
524  while (random_test_number_ > 0)
525  {
526  // sample random robot state
527  rstate.setToRandomPositions(jmg, rng_);
528 
529  Eigen::Isometry3d pose_expect = rstate.getFrameTransform(tcp_link_);
530 
531  // copy the random state and set ik seed
532  std::map<std::string, double> ik_seed, ik_expect;
533  for (const auto& joint_name : robot_model_->getJointModelGroup(planning_group_)->getActiveJointModelNames())
534  {
535  ik_expect[joint_name] = rstate.getVariablePosition(joint_name);
536  if (rstate.getVariablePosition(joint_name) > 0)
537  {
538  ik_seed[joint_name] = rstate.getVariablePosition(joint_name) - IK_SEED_OFFSET;
539  }
540  else
541  {
542  ik_seed[joint_name] = rstate.getVariablePosition(joint_name) + IK_SEED_OFFSET;
543  }
544  }
545 
546  // compute the ik
547  std::map<std::string, double> ik_actual;
548  EXPECT_TRUE(pilz_industrial_motion_planner::computePoseIK(planning_scene_, planning_group_, tcp_link_, pose_expect,
549  frame_id, ik_seed, ik_actual, false));
550 
551  // compare ik solution and expected value
552  for (const auto& joint_pair : ik_actual)
553  {
554  EXPECT_NEAR(joint_pair.second, ik_expect.at(joint_pair.first), 4 * IK_SEED_OFFSET);
555  }
556 
557  --random_test_number_;
558  }
559 }
560 
564 TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testComputePoseIKInvalidGroupName)
565 {
566  const std::string frame_id = robot_model_->getModelFrame();
567  Eigen::Isometry3d pose_expect;
568 
569  std::map<std::string, double> ik_seed;
570 
571  // compute the ik
572  std::map<std::string, double> ik_actual;
573  EXPECT_FALSE(pilz_industrial_motion_planner::computePoseIK(planning_scene_, "InvalidGroupName", tcp_link_,
574  pose_expect, frame_id, ik_seed, ik_actual, false));
575 }
576 
580 TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testComputePoseIKInvalidLinkName)
581 {
582  const std::string frame_id = robot_model_->getModelFrame();
583  Eigen::Isometry3d pose_expect;
584 
585  std::map<std::string, double> ik_seed;
586 
587  // compute the ik
588  std::map<std::string, double> ik_actual;
589  EXPECT_FALSE(pilz_industrial_motion_planner::computePoseIK(planning_scene_, planning_group_, "WrongLink", pose_expect,
590  frame_id, ik_seed, ik_actual, false));
591 }
592 
598 TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testComputePoseIKInvalidFrameId)
599 {
600  Eigen::Isometry3d pose_expect;
601 
602  std::map<std::string, double> ik_seed;
603 
604  // compute the ik
605  std::map<std::string, double> ik_actual;
606  EXPECT_FALSE(pilz_industrial_motion_planner::computePoseIK(planning_scene_, planning_group_, tcp_link_, pose_expect,
607  "InvalidFrameId", ik_seed, ik_actual, false));
608 }
609 
610 // /**
611 // * @brief Test if activated self collision for a pose that would be in self
612 // * collision without the check results in a
613 // * valid ik solution.
614 // */
615 // TEST_F(TrajectoryFunctionsTestOnlyGripper, testComputePoseIKSelfCollisionForValidPosition)
616 // {
617 // const std::string frame_id = robot_model_->getModelFrame();
618 // const moveit::core::JointModelGroup* jmg = robot_model_->getJointModelGroup(planning_group_);
619 //
620 // // create seed
621 // std::vector<double> ik_seed_states = { -0.553, 0.956, 1.758, 0.146, -1.059, 1.247 };
622 // auto joint_names = jmg->getActiveJointModelNames();
623 //
624 // std::map<std::string, double> ik_seed;
625 // for (unsigned int i = 0; i < ik_seed_states.size(); ++i)
626 // {
627 // ik_seed[joint_names[i]] = ik_seed_states[i];
628 // }
629 //
630 // // create expected pose
631 // geometry_msgs::msg::Pose pose;
632 // pose.position.x = -0.454;
633 // pose.position.y = -0.15;
634 // pose.position.z = 0.431;
635 // pose.orientation.y = 0.991562;
636 // pose.orientation.w = -0.1296328;
637 // Eigen::Isometry3d pose_expect;
638 // normalizeQuaternion(pose.orientation);
639 // tf2::fromMsg(pose, pose_expect);
640 //
641 // // compute the ik without self collision check and expect the resulting pose
642 // // to be in self collision.
643 // std::map<std::string, double> ik_actual1;
644 // EXPECT_TRUE(pilz_industrial_motion_planner::computePoseIK(planning_scene_, planning_group_, tcp_link_, pose_expect,
645 // frame_id, ik_seed, ik_actual1, false));
646 //
647 // moveit::core::RobotState rstate(robot_model_);
648 // planning_scene::PlanningScene rscene(robot_model_);
649 //
650 // std::vector<double> ik_state;
651 // std::transform(ik_actual1.begin(), ik_actual1.end(), std::back_inserter(ik_state),
652 // [](const auto& pair) { return pair.second; });
653 //
654 // rstate.setJointGroupPositions(jmg, ik_state);
655 // rstate.update();
656 //
657 // collision_detection::CollisionRequest collision_req;
658 // collision_req.group_name = jmg->getName();
659 // collision_detection::CollisionResult collision_res;
660 //
661 // rscene.checkSelfCollision(collision_req, collision_res, rstate);
662 //
663 // EXPECT_TRUE(collision_res.collision);
664 //
665 // // compute the ik with collision detection activated and expect the resulting
666 // // pose to be without self collision.
667 // std::map<std::string, double> ik_actual2;
668 // EXPECT_TRUE(pilz_industrial_motion_planner::computePoseIK(robot_model_, planning_group_, tcp_link_, pose_expect,
669 // frame_id, ik_seed, ik_actual2, true));
670 //
671 // std::vector<double> ik_state2;
672 // std::transform(ik_actual2.begin(), ik_actual2.end(), std::back_inserter(ik_state2),
673 // [](const auto& pair) { return pair.second; });
674 // rstate.setJointGroupPositions(jmg, ik_state2);
675 // rstate.update();
676 //
677 // collision_detection::CollisionResult collision_res2;
678 // rscene.checkSelfCollision(collision_req, collision_res2, rstate);
679 //
680 // EXPECT_FALSE(collision_res2.collision);
681 // }
682 
687 TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testComputePoseIKSelfCollisionForInvalidPose)
688 {
689  // robot state
690  moveit::core::RobotState rstate(robot_model_);
691 
692  const std::string frame_id = robot_model_->getModelFrame();
693  const moveit::core::JointModelGroup* jmg = robot_model_->getJointModelGroup(planning_group_);
694 
695  // create seed
696  std::map<std::string, double> ik_seed;
697  for (const auto& joint_name : jmg->getActiveJointModelNames())
698  {
699  ik_seed[joint_name] = 0;
700  }
701 
702  // create goal
703  std::vector<double> ik_goal = { 0, 2.3, -2.3, 0, 0, 0 };
704 
705  rstate.setJointGroupPositions(jmg, ik_goal);
706 
707  Eigen::Isometry3d pose_expect = rstate.getFrameTransform(tcp_link_);
708 
709  // compute the ik with disabled collision check
710  std::map<std::string, double> ik_actual;
711  EXPECT_TRUE(pilz_industrial_motion_planner::computePoseIK(planning_scene_, planning_group_, tcp_link_, pose_expect,
712  frame_id, ik_seed, ik_actual, false));
713 
714  // compute the ik with enabled collision check
715  EXPECT_FALSE(pilz_industrial_motion_planner::computePoseIK(planning_scene_, planning_group_, tcp_link_, pose_expect,
716  frame_id, ik_seed, ik_actual, true));
717 }
718 
729 TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testVerifySampleJointLimitsWithSmallDuration)
730 {
731  const std::map<std::string, double> position_last, velocity_last, position_current;
732  double duration_last{ 0.0 };
734 
735  double duration_current = 10e-7;
736 
737  EXPECT_FALSE(pilz_industrial_motion_planner::verifySampleJointLimits(position_last, velocity_last, position_current,
738  duration_last, duration_current, joint_limits));
739 }
740 
751 TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testVerifySampleJointLimitsVelocityViolation)
752 {
753  const std::string test_joint_name{ "joint" };
754 
755  std::map<std::string, double> position_last{ { test_joint_name, 2.0 } };
756  std::map<std::string, double> position_current{ { test_joint_name, 10.0 } };
757  std::map<std::string, double> velocity_last;
758  double duration_current{ 1.0 };
759  double duration_last{ 0.0 };
761 
763  // Calculate the max allowed velocity in such a way that it is always smaller
764  // than the current velocity.
765  test_joint_limits.max_velocity =
766  ((position_current.at(test_joint_name) - position_last.at(test_joint_name)) / duration_current) - 1.0;
767  test_joint_limits.has_velocity_limits = true;
768  joint_limits.addLimit(test_joint_name, test_joint_limits);
769 
770  EXPECT_FALSE(pilz_industrial_motion_planner::verifySampleJointLimits(position_last, velocity_last, position_current,
771  duration_last, duration_current, joint_limits));
772 }
773 
784 TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testVerifySampleJointLimitsAccelerationViolation)
785 {
786  const std::string test_joint_name{ "joint" };
787 
788  double duration_current = 1.0;
789  double duration_last = 1.0;
790 
791  std::map<std::string, double> position_last{ { test_joint_name, 2.0 } };
792  std::map<std::string, double> position_current{ { test_joint_name, 20.0 } };
793  double velocity_current =
794  ((position_current.at(test_joint_name) - position_last.at(test_joint_name)) / duration_current);
795  std::map<std::string, double> velocity_last{ { test_joint_name, 9.0 } };
797 
799  // Calculate the max allowed velocity in such a way that it is always bigger
800  // than the current velocity.
801  test_joint_limits.max_velocity = velocity_current + 1.0;
802  test_joint_limits.has_velocity_limits = true;
803 
804  double acceleration_current =
805  (velocity_current - velocity_last.at(test_joint_name)) / (duration_last + duration_current) * 2;
806  // Calculate the max allowed acceleration in such a way that it is always
807  // smaller than the current acceleration.
808  test_joint_limits.max_acceleration = acceleration_current - 1.0;
809  test_joint_limits.has_acceleration_limits = true;
810 
811  joint_limits.addLimit(test_joint_name, test_joint_limits);
812 
813  EXPECT_FALSE(pilz_industrial_motion_planner::verifySampleJointLimits(position_last, velocity_last, position_current,
814  duration_last, duration_current, joint_limits));
815 }
816 
827 TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testVerifySampleJointLimitsDecelerationViolation)
828 {
829  const std::string test_joint_name{ "joint" };
830 
831  double duration_current = 1.0;
832  double duration_last = 1.0;
833 
834  std::map<std::string, double> position_last{ { test_joint_name, 20.0 } };
835  std::map<std::string, double> position_current{ { test_joint_name, 2.0 } };
836  double velocity_current =
837  ((position_current.at(test_joint_name) - position_last.at(test_joint_name)) / duration_current);
838  std::map<std::string, double> velocity_last{ { test_joint_name, 19.0 } };
840 
842  // Calculate the max allowed velocity in such a way that it is always bigger
843  // than the current velocity.
844  test_joint_limits.max_velocity = fabs(velocity_current) + 1.0;
845  test_joint_limits.has_velocity_limits = true;
846 
847  double acceleration_current =
848  (velocity_current - velocity_last.at(test_joint_name)) / (duration_last + duration_current) * 2;
849  // Calculate the max allowed deceleration in such a way that it is always
850  // bigger than the current acceleration.
851  test_joint_limits.max_deceleration = acceleration_current + 1.0;
852  test_joint_limits.has_deceleration_limits = true;
853 
854  joint_limits.addLimit(test_joint_name, test_joint_limits);
855 
856  EXPECT_FALSE(pilz_industrial_motion_planner::verifySampleJointLimits(position_last, velocity_last, position_current,
857  duration_last, duration_current, joint_limits));
858 }
859 
874 TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testGenerateJointTrajectoryWithInvalidCartesianTrajectory)
875 {
876  // Create random test trajectory
877  // Note: 'path' is deleted by KDL::Trajectory_Segment
878  KDL::Path_RoundedComposite* path =
879  new KDL::Path_RoundedComposite(0.2, 0.01, new KDL::RotationalInterpolation_SingleAxis());
880  path->Add(KDL::Frame(KDL::Rotation::RPY(0, 0, 0), KDL::Vector(-1, 0, 0)));
881  path->Finish();
882  // Note: 'velprof' is deleted by KDL::Trajectory_Segment
883  KDL::VelocityProfile* vel_prof = new KDL::VelocityProfile_Trap(0.5, 0.1);
884  vel_prof->SetProfile(0, path->PathLength());
885  KDL::Trajectory_Segment kdl_trajectory(path, vel_prof);
886 
888  std::string group_name{ "invalid_group_name" };
889  std::map<std::string, double> initial_joint_position;
890  double sampling_time{ 0.1 };
891  trajectory_msgs::msg::JointTrajectory joint_trajectory;
892  moveit_msgs::msg::MoveItErrorCodes error_code;
893  bool check_self_collision{ false };
894 
896  planning_scene_, joint_limits, kdl_trajectory, group_name, tcp_link_, initial_joint_position, sampling_time,
897  joint_trajectory, error_code, check_self_collision));
898 
899  std::map<std::string, double> initial_joint_velocity;
900 
902  cart_traj.group_name = group_name;
903  cart_traj.link_name = tcp_link_;
905  cart_traj.points.push_back(cart_traj_point);
906 
908  planning_scene_, joint_limits, cart_traj, group_name, tcp_link_, initial_joint_position, initial_joint_velocity,
909  joint_trajectory, error_code, check_self_collision));
910 }
911 
923 TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testDetermineAndCheckSamplingTimeInvalidVectorSize)
924 {
925  robot_trajectory::RobotTrajectoryPtr first_trajectory =
926  std::make_shared<robot_trajectory::RobotTrajectory>(robot_model_, planning_group_);
927  robot_trajectory::RobotTrajectoryPtr second_trajectory =
928  std::make_shared<robot_trajectory::RobotTrajectory>(robot_model_, planning_group_);
929  double epsilon{ 0.0 };
930  double sampling_time{ 0.0 };
931 
932  moveit::core::RobotState rstate(robot_model_);
933  first_trajectory->insertWayPoint(0, rstate, 0.1);
934  second_trajectory->insertWayPoint(0, rstate, 0.1);
935 
936  EXPECT_FALSE(pilz_industrial_motion_planner::determineAndCheckSamplingTime(first_trajectory, second_trajectory,
937  epsilon, sampling_time));
938 }
939 
951 TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testDetermineAndCheckSamplingTimeCorrectSamplingTime)
952 {
953  robot_trajectory::RobotTrajectoryPtr first_trajectory =
954  std::make_shared<robot_trajectory::RobotTrajectory>(robot_model_, planning_group_);
955  robot_trajectory::RobotTrajectoryPtr second_trajectory =
956  std::make_shared<robot_trajectory::RobotTrajectory>(robot_model_, planning_group_);
957  double epsilon{ 0.0001 };
958  double sampling_time{ 0.0 };
959  double expected_sampling_time{ 0.1 };
960 
961  moveit::core::RobotState rstate(robot_model_);
962  first_trajectory->insertWayPoint(0, rstate, expected_sampling_time);
963  first_trajectory->insertWayPoint(1, rstate, expected_sampling_time);
964 
965  second_trajectory->insertWayPoint(0, rstate, expected_sampling_time);
966  second_trajectory->insertWayPoint(1, rstate, expected_sampling_time);
967  second_trajectory->insertWayPoint(2, rstate, expected_sampling_time);
968 
969  EXPECT_TRUE(pilz_industrial_motion_planner::determineAndCheckSamplingTime(first_trajectory, second_trajectory,
970  epsilon, sampling_time));
971  EXPECT_EQ(expected_sampling_time, sampling_time);
972 }
973 
985 TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testDetermineAndCheckSamplingTimeViolateSamplingTime)
986 {
987  robot_trajectory::RobotTrajectoryPtr first_trajectory =
988  std::make_shared<robot_trajectory::RobotTrajectory>(robot_model_, planning_group_);
989  robot_trajectory::RobotTrajectoryPtr second_trajectory =
990  std::make_shared<robot_trajectory::RobotTrajectory>(robot_model_, planning_group_);
991  double epsilon{ 0.0001 };
992  double sampling_time{ 0.0 };
993  double expected_sampling_time{ 0.1 };
994 
995  moveit::core::RobotState rstate(robot_model_);
996  first_trajectory->insertWayPoint(0, rstate, expected_sampling_time);
997  first_trajectory->insertWayPoint(1, rstate, expected_sampling_time);
998  first_trajectory->insertWayPoint(2, rstate, expected_sampling_time);
999  // Violate sampling time
1000  first_trajectory->insertWayPoint(2, rstate, expected_sampling_time + 1.0);
1001  first_trajectory->insertWayPoint(3, rstate, expected_sampling_time);
1002 
1003  second_trajectory->insertWayPoint(0, rstate, expected_sampling_time);
1004  second_trajectory->insertWayPoint(1, rstate, expected_sampling_time);
1005  second_trajectory->insertWayPoint(2, rstate, expected_sampling_time);
1006  second_trajectory->insertWayPoint(3, rstate, expected_sampling_time);
1007 
1008  EXPECT_FALSE(pilz_industrial_motion_planner::determineAndCheckSamplingTime(first_trajectory, second_trajectory,
1009  epsilon, sampling_time));
1010  EXPECT_EQ(expected_sampling_time, sampling_time);
1011 }
1012 
1024 TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testIsRobotStateEqualPositionUnequal)
1025 {
1026  moveit::core::RobotState rstate_1 = moveit::core::RobotState(robot_model_);
1027  moveit::core::RobotState rstate_2 = moveit::core::RobotState(robot_model_);
1028 
1029  double default_joint_position[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
1030  rstate_1.setJointGroupPositions(planning_group_, default_joint_position);
1031  // Ensure that the joint positions of both robot states are different
1032  default_joint_position[0] = default_joint_position[0] + 70.0;
1033  rstate_2.setJointGroupPositions(planning_group_, default_joint_position);
1034 
1035  double epsilon{ 0.0001 };
1036  EXPECT_FALSE(pilz_industrial_motion_planner::isRobotStateEqual(rstate_1, rstate_2, planning_group_, epsilon));
1037 }
1038 
1050 TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testIsRobotStateEqualVelocityUnequal)
1051 {
1052  moveit::core::RobotState rstate_1 = moveit::core::RobotState(robot_model_);
1053  moveit::core::RobotState rstate_2 = moveit::core::RobotState(robot_model_);
1054 
1055  // Ensure that the joint positions of both robot state are equal
1056  double default_joint_position[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
1057  rstate_1.setJointGroupPositions(planning_group_, default_joint_position);
1058  rstate_2.setJointGroupPositions(planning_group_, default_joint_position);
1059 
1060  double default_joint_velocity[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
1061  rstate_1.setJointGroupVelocities(planning_group_, default_joint_velocity);
1062  // Ensure that the joint velocites of both robot states are different
1063  default_joint_velocity[1] = default_joint_velocity[1] + 10.0;
1064  rstate_2.setJointGroupVelocities(planning_group_, default_joint_velocity);
1065 
1066  double epsilon{ 0.0001 };
1067  EXPECT_FALSE(pilz_industrial_motion_planner::isRobotStateEqual(rstate_1, rstate_2, planning_group_, epsilon));
1068 }
1069 
1081 TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testIsRobotStateEqualAccelerationUnequal)
1082 {
1083  moveit::core::RobotState rstate_1 = moveit::core::RobotState(robot_model_);
1084  moveit::core::RobotState rstate_2 = moveit::core::RobotState(robot_model_);
1085 
1086  // Ensure that the joint positions of both robot state are equal
1087  double default_joint_position[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
1088  rstate_1.setJointGroupPositions(planning_group_, default_joint_position);
1089  rstate_2.setJointGroupPositions(planning_group_, default_joint_position);
1090 
1091  // Ensure that the joint velocities of both robot state are equal
1092  double default_joint_velocity[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
1093  rstate_1.setJointGroupVelocities(planning_group_, default_joint_velocity);
1094  rstate_2.setJointGroupVelocities(planning_group_, default_joint_velocity);
1095 
1096  double default_joint_acceleration[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
1097  rstate_1.setJointGroupAccelerations(planning_group_, default_joint_acceleration);
1098  // Ensure that the joint accelerations of both robot states are different
1099  default_joint_acceleration[1] = default_joint_acceleration[1] + 10.0;
1100  rstate_2.setJointGroupAccelerations(planning_group_, default_joint_acceleration);
1101 
1102  double epsilon{ 0.0001 };
1103  EXPECT_FALSE(pilz_industrial_motion_planner::isRobotStateEqual(rstate_1, rstate_2, planning_group_, epsilon));
1104 }
1105 
1117 TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testIsRobotStateStationaryVelocityUnequal)
1118 {
1119  moveit::core::RobotState rstate_1 = moveit::core::RobotState(robot_model_);
1120 
1121  // Ensure that the joint velocities are NOT zero
1122  double default_joint_velocity[6] = { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
1123  rstate_1.setJointGroupVelocities(planning_group_, default_joint_velocity);
1124 
1125  double epsilon{ 0.0001 };
1126  EXPECT_FALSE(pilz_industrial_motion_planner::isRobotStateStationary(rstate_1, planning_group_, epsilon));
1127 }
1128 
1140 TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testIsRobotStateStationaryAccelerationUnequal)
1141 {
1142  moveit::core::RobotState rstate_1 = moveit::core::RobotState(robot_model_);
1143 
1144  // Ensure that the joint velocities are zero
1145  double default_joint_velocity[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
1146  rstate_1.setJointGroupVelocities(planning_group_, default_joint_velocity);
1147 
1148  // Ensure that the joint acceleration are NOT zero
1149  double default_joint_acceleration[6] = { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
1150  rstate_1.setJointGroupAccelerations(planning_group_, default_joint_acceleration);
1151 
1152  double epsilon{ 0.0001 };
1153  EXPECT_FALSE(pilz_industrial_motion_planner::isRobotStateStationary(rstate_1, planning_group_, epsilon));
1154 }
1155 
1156 int main(int argc, char** argv)
1157 {
1158  rclcpp::init(argc, argv);
1159  testing::InitGoogleTest(&argc, argv);
1160  return RUN_ALL_TESTS();
1161 }
std::unique_ptr< robot_model_loader::RobotModelLoader > rm_loader_
std::vector< double > getJoints(const moveit::core::JointModelGroup *jmg, const moveit::core::RobotState &state)
get the current joint values of the robot state
void SetUp() override
Create test scenario for trajectory functions.
random_numbers::RandomNumberGenerator rng_
void attachToLink(moveit::core::RobotState &state, const moveit::core::LinkModel *link, const std::string &object_name, const Eigen::Isometry3d &object_pose, const moveit::core::FixedTransformsMap &subframes)
attach a collision object and subframes to a link
moveit::core::RobotModelConstPtr robot_model_
std::map< std::string, double > zero_state_
planning_scene::PlanningSceneConstPtr planning_scene_
bool tfNear(const Eigen::Isometry3d &pose1, const Eigen::Isometry3d &pose2, const double &epsilon)
check if two transformations are close
bool jointsNear(const std::vector< double > &joints1, const std::vector< double > &joints2, double epsilon)
check if two sets of joint positions are close
moveit::core::RobotStatePtr robot_state_
Parametrized class for tests with and without gripper.
const kinematics::KinematicsBaseConstPtr getSolverInstance() const
const std::vector< std::string > & getActiveJointModelNames() const
Get the names of the active joints in this group. These are the names of the joints returned by getJo...
A link from the robot. Contains the constant transform applied to the link and its geometry.
Definition: link_model.h:72
Representation of a robot's state. This includes position, velocity, acceleration and effort.
Definition: robot_state.h:90
void setVariablePositions(const double *position)
It is assumed positions is an array containing the new positions for all variables in this state....
void attachBody(std::unique_ptr< AttachedBody > attached_body)
Add an attached body to this state.
void setJointGroupAccelerations(const std::string &joint_group_name, const double *gstate)
Given accelerations for the variables that make up a group, in the order found in the group (includin...
Definition: robot_state.h:848
void setJointGroupVelocities(const std::string &joint_group_name, const double *gstate)
Given velocities for the variables that make up a group, in the order found in the group (including v...
Definition: robot_state.h:748
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
const Eigen::Isometry3d & getFrameTransform(const std::string &frame_id, bool *frame_found=nullptr)
Get the transformation matrix from the model frame (root of model) to the frame identified by frame_i...
void setToRandomPositions()
Set all joints to random values. Values will be within default bounds.
double getVariablePosition(const std::string &variable) const
Get the position of a particular variable. An exception is thrown if the variable is not known.
Definition: robot_state.h:207
void update(bool force=false)
Update all transforms.
void setToDefaultValues()
Set all joints to their default positions. The default position is 0, or if that is not within bounds...
bool setFromIK(const JointModelGroup *group, const geometry_msgs::msg::Pose &pose, double timeout=0.0, const GroupStateValidityCallbackFn &constraint=GroupStateValidityCallbackFn(), const kinematics::KinematicsQueryOptions &options=kinematics::KinematicsQueryOptions(), const kinematics::KinematicsBase::IKCostFn &cost_function=kinematics::KinematicsBase::IKCostFn())
If the group this state corresponds to is a chain and a solver is available, then the joint values ca...
Container for JointLimits, essentially a map with convenience functions. Adds the ability to as for l...
std::map< std::string, Eigen::Isometry3d, std::less< std::string >, Eigen::aligned_allocator< std::pair< const std::string, Eigen::Isometry3d > > > FixedTransformsMap
Map frame names to the transformation matrix that can transform objects from the frame name to the pl...
Definition: transforms.h:53
frame_id
Definition: pick.py:63
bool computeLinkFK(moveit::core::RobotState &robot_state, const std::string &link_name, const std::map< std::string, double > &joint_state, Eigen::Isometry3d &pose)
compute the pose of a link at a given robot state
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 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 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.
name
Definition: setup.py:7
void checkRobotModel(const moveit::core::RobotModelConstPtr &robot_model, const std::string &group_name, const std::string &link_name)
A set of options for the kinematics solver.
std::vector< CartesianTrajectoryPoint > points
Extends joint_limits_interface::JointLimits with a deceleration parameter.
double max_deceleration
maximum deceleration MUST(!) be negative
const std::string PARAM_PLANNING_GROUP_NAME("planning_group")
const std::string RANDOM_TEST_NUMBER("random_test_number")
int main(int argc, char **argv)
const std::string IK_FAST_LINK_NAME("ik_fast_link")
TEST_F(TrajectoryFunctionsTestFlangeAndGripper, TipLinkFK)
Test the forward kinematics function with simple robot poses for robot tip link using robot model wit...
const std::string ROBOT_TCP_LINK_NAME("tcp_link")
const std::string GROUP_TIP_LINK_NAME("group_tip_link")