moveit2
The MoveIt Motion Planning Framework for ROS 2.
Loading...
Searching...
No Matches
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 <cstdint>
36#include <gtest/gtest.h>
37
38#include <map>
39#include <math.h>
40#include <string>
41#include <vector>
42
43#include <Eigen/Geometry>
44#include <kdl/frames.hpp>
45#include <kdl/path_roundedcomposite.hpp>
46#include <kdl/rotational_interpolation_sa.hpp>
47#include <kdl/trajectory.hpp>
48#include <kdl/trajectory_segment.hpp>
49#include <kdl/velocityprofile_trap.hpp>
54#include <tf2_eigen/tf2_eigen.hpp>
55#include <tf2_geometry_msgs/tf2_geometry_msgs.hpp>
56
61#include "test_utils.hpp"
62
63#define _USE_MATH_DEFINES
64
65static constexpr double EPSILON{ 1.0e-6 };
66static constexpr double IK_SEED_OFFSET{ 0.1 };
67static constexpr double L0{ 0.2604 }; // Height of foot
68static constexpr double L1{ 0.3500 }; // Height of first connector
69static constexpr double L2{ 0.3070 }; // Height of second connector
70static constexpr double L3{ 0.0840 }; // Distance last joint to flange
71
72// parameters from parameter server
73const std::string RANDOM_TEST_NUMBER("random_test_number");
74
78class TrajectoryFunctionsTestBase : public testing::Test
79{
80protected:
85 void SetUp() override
86 {
87 rclcpp::NodeOptions node_options;
88 node_options.automatically_declare_parameters_from_overrides(true);
89 node_ = rclcpp::Node::make_shared("unittest_trajectory_functions", node_options);
90
91 // load robot model
92 rm_loader_ = std::make_unique<robot_model_loader::RobotModelLoader>(node_);
93 robot_model_ = rm_loader_->getModel();
94 ASSERT_TRUE(bool(robot_model_)) << "Failed to load robot model";
95 robot_state_ = std::make_shared<moveit::core::RobotState>(robot_model_);
96 planning_scene_ = std::make_shared<planning_scene::PlanningScene>(robot_model_);
97
98 // get parameters
99 ASSERT_TRUE(node_->has_parameter("planning_group"));
100 node_->get_parameter<std::string>("planning_group", planning_group_);
101 ASSERT_TRUE(node_->has_parameter("group_tip_link"));
102 node_->get_parameter<std::string>("group_tip_link", group_tip_link_);
103 ASSERT_TRUE(node_->has_parameter("tcp_link"));
104 node_->get_parameter<std::string>("tcp_link", tcp_link_);
105 ASSERT_TRUE(node_->has_parameter("ik_fast_link"));
106 node_->get_parameter<std::string>("ik_fast_link", ik_fast_link_);
107 ASSERT_TRUE(node_->has_parameter("random_test_number"));
108 node_->get_parameter<int>("random_test_number", random_test_number_);
109
110 // check robot model
112
113 // initialize the zero state configurationg and test joint state
114 joint_names_ = robot_model_->getJointModelGroup(planning_group_)->getActiveJointModelNames();
115 for (const auto& joint_name : joint_names_)
116 {
117 zero_state_[joint_name] = 0.0;
118 }
119 }
120
121 void TearDown() override
122 {
123 robot_model_.reset();
124 }
125
133 bool tfNear(const Eigen::Isometry3d& pose1, const Eigen::Isometry3d& pose2, double epsilon);
134
142 bool jointsNear(const std::vector<double>& joints1, const std::vector<double>& joints2, double epsilon);
143
150 std::vector<double> getJoints(const moveit::core::JointModelGroup* jmg, const moveit::core::RobotState& state);
151
161 const std::string& object_name, const Eigen::Isometry3d& object_pose,
162 const moveit::core::FixedTransformsMap& subframes);
163
164protected:
165 // ros stuff
166 rclcpp::Node::SharedPtr node_;
167 moveit::core::RobotModelConstPtr robot_model_;
168 moveit::core::RobotStatePtr robot_state_;
169 std::unique_ptr<robot_model_loader::RobotModelLoader> rm_loader_;
170 planning_scene::PlanningSceneConstPtr planning_scene_;
171
172 // test parameters from parameter server
175 std::vector<std::string> joint_names_;
176 std::map<std::string, double> zero_state_;
177
178 // random seed
179 uint32_t random_seed_{ 100 };
180 random_numbers::RandomNumberGenerator rng_{ random_seed_ };
181};
182
183bool TrajectoryFunctionsTestBase::tfNear(const Eigen::Isometry3d& pose1, const Eigen::Isometry3d& pose2, double epsilon)
184{
185 for (std::size_t i = 0; i < 3; ++i)
186 {
187 for (std::size_t j = 0; j < 4; ++j)
188 {
189 if (fabs(pose1(i, j) - pose2(i, j)) > fabs(epsilon))
190 return false;
191 }
192 }
193 return true;
194}
195
196bool TrajectoryFunctionsTestBase::jointsNear(const std::vector<double>& joints1, const std::vector<double>& joints2,
197 double epsilon)
198{
199 if (joints1.size() != joints2.size())
200 {
201 return false;
202 }
203 for (std::size_t i = 0; i < joints1.size(); ++i)
204 {
205 if (fabs(joints1.at(i) - joints2.at(i)) > fabs(epsilon))
206 {
207 return false;
208 }
209 }
210 return true;
211}
212
214 const moveit::core::RobotState& state)
215{
216 std::vector<double> joints;
217 for (const auto& name : jmg->getActiveJointModelNames())
218 {
219 joints.push_back(state.getVariablePosition(name));
220 }
221 return joints;
222}
223
225 const std::string& object_name, const Eigen::Isometry3d& object_pose,
226 const moveit::core::FixedTransformsMap& subframes)
227{
228 state.attachBody(std::make_unique<moveit::core::AttachedBody>(
229 link, object_name, object_pose, std::vector<shapes::ShapeConstPtr>{}, EigenSTL::vector_Isometry3d{},
230 std::set<std::string>{}, trajectory_msgs::msg::JointTrajectory{}, subframes));
231}
232
239
240// TODO(henningkayser): re-enable gripper tests
241// /**
242// * @brief Parametrized class for tests, that only run with a gripper
243// */
244// class TrajectoryFunctionsTestOnlyGripper : public TrajectoryFunctionsTestBase
245// {
246// };
247
254{
255 Eigen::Isometry3d tip_pose;
256 std::map<std::string, double> test_state = zero_state_;
257 EXPECT_TRUE(pilz_industrial_motion_planner::computeLinkFK(*robot_state_, group_tip_link_, test_state, tip_pose));
258 EXPECT_NEAR(tip_pose(0, 3), 0, EPSILON);
259 EXPECT_NEAR(tip_pose(1, 3), 0, EPSILON);
260 EXPECT_NEAR(tip_pose(2, 3), L0 + L1 + L2 + L3, EPSILON);
261
262 test_state[joint_names_.at(1)] = M_PI_2;
263 EXPECT_TRUE(pilz_industrial_motion_planner::computeLinkFK(*robot_state_, group_tip_link_, test_state, tip_pose));
264 EXPECT_NEAR(tip_pose(0, 3), L1 + L2 + L3, EPSILON);
265 EXPECT_NEAR(tip_pose(1, 3), 0, EPSILON);
266 EXPECT_NEAR(tip_pose(2, 3), L0, EPSILON);
267
268 test_state[joint_names_.at(1)] = -M_PI_2;
269 test_state[joint_names_.at(2)] = M_PI_2;
270 EXPECT_TRUE(pilz_industrial_motion_planner::computeLinkFK(*robot_state_, group_tip_link_, test_state, tip_pose));
271 EXPECT_NEAR(tip_pose(0, 3), -L1, EPSILON);
272 EXPECT_NEAR(tip_pose(1, 3), 0, EPSILON);
273 EXPECT_NEAR(tip_pose(2, 3), L0 - L2 - L3, EPSILON);
274
275 // wrong link name
276 std::string link_name = "wrong_link_name";
277 EXPECT_FALSE(pilz_industrial_motion_planner::computeLinkFK(*robot_state_, link_name, test_state, tip_pose));
278}
279
284{
285 // Load solver
286 const moveit::core::JointModelGroup* jmg = robot_model_->getJointModelGroup(planning_group_);
287 const kinematics::KinematicsBaseConstPtr& solver = jmg->getSolverInstance();
288
289 if (!solver)
290 {
291 throw("No IK solver configured for group '" + planning_group_ + "'");
292 }
293 // robot state
294 moveit::core::RobotState rstate(robot_model_);
295
296 while (random_test_number_ > 0)
297 {
298 // sample random robot state
299 rstate.setToRandomPositions(jmg, rng_);
300 rstate.update();
301 geometry_msgs::msg::Pose pose_expect = tf2::toMsg(rstate.getFrameTransform(ik_fast_link_));
302
303 // prepare inverse kinematics
304 std::vector<geometry_msgs::msg::Pose> ik_poses;
305 ik_poses.push_back(pose_expect);
306 std::vector<double> ik_seed, ik_expect, ik_actual;
307 for (const auto& joint_name : jmg->getActiveJointModelNames())
308 {
309 ik_expect.push_back(rstate.getVariablePosition(joint_name));
310 if (rstate.getVariablePosition(joint_name) > 0)
311 {
312 ik_seed.push_back(rstate.getVariablePosition(joint_name) - IK_SEED_OFFSET);
313 }
314 else
315 {
316 ik_seed.push_back(rstate.getVariablePosition(joint_name) + IK_SEED_OFFSET);
317 }
318 }
319
320 std::vector<std::vector<double>> ik_solutions;
322 moveit_msgs::msg::MoveItErrorCodes err_code;
324
325 // compute all ik solutions
326 EXPECT_TRUE(solver->getPositionIK(ik_poses, ik_seed, ik_solutions, ik_result, options));
327
328 // compute one ik solution
329 EXPECT_TRUE(solver->getPositionIK(pose_expect, ik_seed, ik_actual, err_code));
330
331 ASSERT_EQ(ik_expect.size(), ik_actual.size());
332
333 for (std::size_t i = 0; i < ik_expect.size(); ++i)
334 {
335 EXPECT_NEAR(ik_actual.at(i), ik_expect.at(i), 4 * IK_SEED_OFFSET);
336 }
337
338 --random_test_number_;
339 }
340}
341
347{
348 // robot state
349 moveit::core::RobotState rstate(robot_model_);
350 const moveit::core::JointModelGroup* jmg = robot_model_->getJointModelGroup(planning_group_);
351
352 while (random_test_number_ > 0)
353 {
354 // sample random robot state
355 rstate.setToRandomPositions(jmg, rng_);
356
357 Eigen::Isometry3d pose_expect = rstate.getFrameTransform(tcp_link_);
358
359 // copy the random state and set ik seed
360 std::map<std::string, double> ik_seed, ik_expect;
361 for (const auto& joint_name : joint_names_)
362 {
363 ik_expect[joint_name] = rstate.getVariablePosition(joint_name);
364 if (rstate.getVariablePosition(joint_name) > 0)
365 {
366 ik_seed[joint_name] = rstate.getVariablePosition(joint_name) - IK_SEED_OFFSET;
367 }
368 else
369 {
370 ik_seed[joint_name] = rstate.getVariablePosition(joint_name) + IK_SEED_OFFSET;
371 }
372 }
373
374 rstate.setVariablePositions(ik_seed);
375 rstate.update();
376
377 // compute the ik
378 std::map<std::string, double> ik_actual;
379
380 EXPECT_TRUE(rstate.setFromIK(robot_model_->getJointModelGroup(planning_group_), pose_expect, tcp_link_));
381
382 for (const auto& joint_name : joint_names_)
383 {
384 ik_actual[joint_name] = rstate.getVariablePosition(joint_name);
385 }
386
387 // compare ik solution and expected value
388 for (const auto& joint_pair : ik_actual)
389 {
390 EXPECT_NEAR(joint_pair.second, ik_expect.at(joint_pair.first), 4 * IK_SEED_OFFSET);
391 }
392
393 // compute the pose from ik_solution
394 rstate.setVariablePositions(ik_actual);
395 rstate.update();
396 Eigen::Isometry3d pose_actual = rstate.getFrameTransform(tcp_link_);
397
398 EXPECT_TRUE(tfNear(pose_expect, pose_actual, EPSILON));
399
400 --random_test_number_;
401 }
402}
403
404TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testIKRobotStateWithIdentityCollisionObject)
405{
406 // Set up a default robot
407 moveit::core::RobotState state(robot_model_);
408 state.setToDefaultValues();
409 const moveit::core::JointModelGroup* jmg = robot_model_->getJointModelGroup(planning_group_);
410
411 std::vector<double> default_joints = getJoints(jmg, state);
412 const moveit::core::LinkModel* tip_link = robot_model_->getLinkModel(tcp_link_);
413 Eigen::Isometry3d tip_pose_in_base = state.getFrameTransform(tcp_link_);
414
415 // Attach an object with ignored subframes, and no transform
416 Eigen::Isometry3d object_pose_in_tip = Eigen::Isometry3d::Identity();
417 moveit::core::FixedTransformsMap subframes({ { "ignored", Eigen::Isometry3d::Identity() } });
418 attachToLink(state, tip_link, "object", object_pose_in_tip, subframes);
419
420 // The RobotState should be able to use an object pose to set the joints
421 Eigen::Isometry3d object_pose_in_base = tip_pose_in_base * object_pose_in_tip;
422 bool success = state.setFromIK(jmg, object_pose_in_base, "object");
423 EXPECT_TRUE(success);
424
425 // Given the target pose is the default pose of the object, the joints should be unchanged
426 std::vector<double> ik_joints = getJoints(jmg, state);
427 EXPECT_TRUE(jointsNear(ik_joints, default_joints, 4 * IK_SEED_OFFSET));
428}
429
430TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testIKRobotStateWithTransformedCollisionObject)
431{
432 // Set up a default robot
433 moveit::core::RobotState state(robot_model_);
434 state.setToDefaultValues();
435 const moveit::core::JointModelGroup* jmg = robot_model_->getJointModelGroup(planning_group_);
436
437 std::vector<double> default_joints = getJoints(jmg, state);
438 const moveit::core::LinkModel* tip_link = robot_model_->getLinkModel(tcp_link_);
439 Eigen::Isometry3d tip_pose_in_base = state.getFrameTransform(tcp_link_);
440
441 // Attach an object with ignored subframes, and a non-trivial transform
442 Eigen::Isometry3d object_pose_in_tip;
443 object_pose_in_tip = Eigen::Translation3d(1, 2, 3);
444 object_pose_in_tip *= Eigen::AngleAxis(M_PI_2, Eigen::Vector3d::UnitX());
445 moveit::core::FixedTransformsMap subframes({ { "ignored", Eigen::Isometry3d::Identity() } });
446 attachToLink(state, tip_link, "object", object_pose_in_tip, subframes);
447
448 // The RobotState should be able to use an object pose to set the joints
449 Eigen::Isometry3d object_pose_in_base = tip_pose_in_base * object_pose_in_tip;
450 bool success = state.setFromIK(jmg, object_pose_in_base, "object");
451 EXPECT_TRUE(success);
452
453 // Given the target pose is the default pose of the object, the joints should be unchanged
454 std::vector<double> ik_joints = getJoints(jmg, state);
455 EXPECT_TRUE(jointsNear(ik_joints, default_joints, 4 * IK_SEED_OFFSET));
456}
457
458TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testIKRobotStateWithIdentitySubframe)
459{
460 // Set up a default robot
461 moveit::core::RobotState state(robot_model_);
462 state.setToDefaultValues();
463 const moveit::core::JointModelGroup* jmg = robot_model_->getJointModelGroup(planning_group_);
464
465 std::vector<double> default_joints = getJoints(jmg, state);
466 const moveit::core::LinkModel* tip_link = robot_model_->getLinkModel(tcp_link_);
467 Eigen::Isometry3d tip_pose_in_base = state.getFrameTransform(tcp_link_);
468
469 // Attach an object and subframe with no transforms
470 Eigen::Isometry3d object_pose_in_tip = Eigen::Isometry3d::Identity();
471 Eigen::Isometry3d subframe_pose_in_object = Eigen::Isometry3d::Identity();
472 moveit::core::FixedTransformsMap subframes({ { "subframe", subframe_pose_in_object } });
473 attachToLink(state, tip_link, "object", object_pose_in_tip, subframes);
474
475 // The RobotState should be able to use a subframe pose to set the joints
476 Eigen::Isometry3d subframe_pose_in_base = tip_pose_in_base * object_pose_in_tip * subframe_pose_in_object;
477 bool success = state.setFromIK(jmg, subframe_pose_in_base, "object/subframe");
478 EXPECT_TRUE(success);
479
480 // Given the target pose is the default pose of the subframe, the joints should be unchanged
481 std::vector<double> ik_joints = getJoints(jmg, state);
482 EXPECT_TRUE(jointsNear(ik_joints, default_joints, 4 * IK_SEED_OFFSET));
483}
484
485TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testIKRobotStateWithTransformedSubframe)
486{
487 // Set up a default robot
488 moveit::core::RobotState state(robot_model_);
489 state.setToDefaultValues();
490 const moveit::core::JointModelGroup* jmg = robot_model_->getJointModelGroup(planning_group_);
491
492 std::vector<double> default_joints = getJoints(jmg, state);
493 const moveit::core::LinkModel* tip_link = robot_model_->getLinkModel(tcp_link_);
494 Eigen::Isometry3d tip_pose_in_base = state.getFrameTransform(tcp_link_);
495
496 // Attach an object and subframe with non-trivial transforms
497 Eigen::Isometry3d object_pose_in_tip;
498 object_pose_in_tip = Eigen::Translation3d(1, 2, 3);
499 object_pose_in_tip *= Eigen::AngleAxis(M_PI_2, Eigen::Vector3d::UnitX());
500
501 Eigen::Isometry3d subframe_pose_in_object;
502 subframe_pose_in_object = Eigen::Translation3d(4, 5, 6);
503 subframe_pose_in_object *= Eigen::AngleAxis(M_PI_2, Eigen::Vector3d::UnitY());
504
505 moveit::core::FixedTransformsMap subframes({ { "subframe", subframe_pose_in_object } });
506 attachToLink(state, tip_link, "object", object_pose_in_tip, subframes);
507
508 // The RobotState should be able to use a subframe pose to set the joints
509 Eigen::Isometry3d subframe_pose_in_base = tip_pose_in_base * object_pose_in_tip * subframe_pose_in_object;
510 bool success = state.setFromIK(jmg, subframe_pose_in_base, "object/subframe");
511 EXPECT_TRUE(success);
512
513 // Given the target pose is the default pose of the subframe, the joints should be unchanged
514 std::vector<double> ik_joints = getJoints(jmg, state);
515 EXPECT_TRUE(jointsNear(ik_joints, default_joints, 4 * IK_SEED_OFFSET));
516}
517
523{
524 // robot state
525 moveit::core::RobotState rstate(robot_model_);
526
527 const std::string frame_id = robot_model_->getModelFrame();
528 const moveit::core::JointModelGroup* jmg = robot_model_->getJointModelGroup(planning_group_);
529
530 while (random_test_number_ > 0)
531 {
532 // sample random robot state
533 rstate.setToRandomPositions(jmg, rng_);
534
535 Eigen::Isometry3d pose_expect = rstate.getFrameTransform(tcp_link_);
536
537 // copy the random state and set ik seed
538 std::map<std::string, double> ik_seed, ik_expect;
539 for (const auto& joint_name : robot_model_->getJointModelGroup(planning_group_)->getActiveJointModelNames())
540 {
541 ik_expect[joint_name] = rstate.getVariablePosition(joint_name);
542 if (rstate.getVariablePosition(joint_name) > 0)
543 {
544 ik_seed[joint_name] = rstate.getVariablePosition(joint_name) - IK_SEED_OFFSET;
545 }
546 else
547 {
548 ik_seed[joint_name] = rstate.getVariablePosition(joint_name) + IK_SEED_OFFSET;
549 }
550 }
551
552 // compute the ik
553 std::map<std::string, double> ik_actual;
554 EXPECT_TRUE(pilz_industrial_motion_planner::computePoseIK(planning_scene_, planning_group_, tcp_link_, pose_expect,
555 frame_id, ik_seed, ik_actual, false));
556
557 // compare ik solution and expected value
558 for (const auto& joint_pair : ik_actual)
559 {
560 EXPECT_NEAR(joint_pair.second, ik_expect.at(joint_pair.first), 4 * IK_SEED_OFFSET);
561 }
562
563 --random_test_number_;
564 }
565}
566
570TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testComputePoseIKInvalidGroupName)
571{
572 const std::string frame_id = robot_model_->getModelFrame();
573 Eigen::Isometry3d pose_expect;
574
575 std::map<std::string, double> ik_seed;
576
577 // compute the ik
578 std::map<std::string, double> ik_actual;
579 EXPECT_FALSE(pilz_industrial_motion_planner::computePoseIK(planning_scene_, "InvalidGroupName", tcp_link_,
580 pose_expect, frame_id, ik_seed, ik_actual, false));
581}
582
586TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testComputePoseIKInvalidLinkName)
587{
588 const std::string frame_id = robot_model_->getModelFrame();
589 Eigen::Isometry3d pose_expect;
590
591 std::map<std::string, double> ik_seed;
592
593 // compute the ik
594 std::map<std::string, double> ik_actual;
595 EXPECT_FALSE(pilz_industrial_motion_planner::computePoseIK(planning_scene_, planning_group_, "WrongLink", pose_expect,
596 frame_id, ik_seed, ik_actual, false));
597}
598
604TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testComputePoseIKInvalidFrameId)
605{
606 Eigen::Isometry3d pose_expect;
607
608 std::map<std::string, double> ik_seed;
609
610 // compute the ik
611 std::map<std::string, double> ik_actual;
612 EXPECT_FALSE(pilz_industrial_motion_planner::computePoseIK(planning_scene_, planning_group_, tcp_link_, pose_expect,
613 "InvalidFrameId", ik_seed, ik_actual, false));
614}
615
616// /**
617// * @brief Test if activated self collision for a pose that would be in self
618// * collision without the check results in a
619// * valid ik solution.
620// */
621// TEST_F(TrajectoryFunctionsTestOnlyGripper, testComputePoseIKSelfCollisionForValidPosition)
622// {
623// const std::string frame_id = robot_model_->getModelFrame();
624// const moveit::core::JointModelGroup* jmg = robot_model_->getJointModelGroup(planning_group_);
625//
626// // create seed
627// std::vector<double> ik_seed_states = { -0.553, 0.956, 1.758, 0.146, -1.059, 1.247 };
628// auto joint_names = jmg->getActiveJointModelNames();
629//
630// std::map<std::string, double> ik_seed;
631// for (unsigned int i = 0; i < ik_seed_states.size(); ++i)
632// {
633// ik_seed[joint_names[i]] = ik_seed_states[i];
634// }
635//
636// // create expected pose
637// geometry_msgs::msg::Pose pose;
638// pose.position.x = -0.454;
639// pose.position.y = -0.15;
640// pose.position.z = 0.431;
641// pose.orientation.y = 0.991562;
642// pose.orientation.w = -0.1296328;
643// Eigen::Isometry3d pose_expect;
644// normalizeQuaternion(pose.orientation);
645// tf2::fromMsg(pose, pose_expect);
646//
647// // compute the ik without self collision check and expect the resulting pose
648// // to be in self collision.
649// std::map<std::string, double> ik_actual1;
650// EXPECT_TRUE(pilz_industrial_motion_planner::computePoseIK(planning_scene_, planning_group_, tcp_link_, pose_expect,
651// frame_id, ik_seed, ik_actual1, false));
652//
653// moveit::core::RobotState rstate(robot_model_);
654// planning_scene::PlanningScene rscene(robot_model_);
655//
656// std::vector<double> ik_state;
657// std::transform(ik_actual1.begin(), ik_actual1.end(), std::back_inserter(ik_state),
658// [](const auto& pair) { return pair.second; });
659//
660// rstate.setJointGroupPositions(jmg, ik_state);
661// rstate.update();
662//
663// collision_detection::CollisionRequest collision_req;
664// collision_req.group_name = jmg->getName();
665// collision_detection::CollisionResult collision_res;
666//
667// rscene.checkSelfCollision(collision_req, collision_res, rstate);
668//
669// EXPECT_TRUE(collision_res.collision);
670//
671// // compute the ik with collision detection activated and expect the resulting
672// // pose to be without self collision.
673// std::map<std::string, double> ik_actual2;
674// EXPECT_TRUE(pilz_industrial_motion_planner::computePoseIK(robot_model_, planning_group_, tcp_link_, pose_expect,
675// frame_id, ik_seed, ik_actual2, true));
676//
677// std::vector<double> ik_state2;
678// std::transform(ik_actual2.begin(), ik_actual2.end(), std::back_inserter(ik_state2),
679// [](const auto& pair) { return pair.second; });
680// rstate.setJointGroupPositions(jmg, ik_state2);
681// rstate.update();
682//
683// collision_detection::CollisionResult collision_res2;
684// rscene.checkSelfCollision(collision_req, collision_res2, rstate);
685//
686// EXPECT_FALSE(collision_res2.collision);
687// }
688
693TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testComputePoseIKSelfCollisionForInvalidPose)
694{
695 // robot state
696 moveit::core::RobotState rstate(robot_model_);
697
698 const std::string frame_id = robot_model_->getModelFrame();
699 const moveit::core::JointModelGroup* jmg = robot_model_->getJointModelGroup(planning_group_);
700
701 // create seed
702 std::map<std::string, double> ik_seed;
703 for (const auto& joint_name : jmg->getActiveJointModelNames())
704 {
705 ik_seed[joint_name] = 0;
706 }
707
708 // create goal
709 std::vector<double> ik_goal = { 0, 2.3, -2.3, 0, 0, 0 };
710
711 rstate.setJointGroupPositions(jmg, ik_goal);
712
713 Eigen::Isometry3d pose_expect = rstate.getFrameTransform(tcp_link_);
714
715 // compute the ik with disabled collision check
716 std::map<std::string, double> ik_actual;
717 EXPECT_TRUE(pilz_industrial_motion_planner::computePoseIK(planning_scene_, planning_group_, tcp_link_, pose_expect,
718 frame_id, ik_seed, ik_actual, false));
719
720 // compute the ik with enabled collision check
721 EXPECT_FALSE(pilz_industrial_motion_planner::computePoseIK(planning_scene_, planning_group_, tcp_link_, pose_expect,
722 frame_id, ik_seed, ik_actual, true));
723}
724
735TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testVerifySampleJointLimitsWithSmallDuration)
736{
737 const std::map<std::string, double> position_last, velocity_last, position_current;
738 double duration_last{ 0.0 };
740
741 double duration_current = 10e-7;
742
743 EXPECT_FALSE(pilz_industrial_motion_planner::verifySampleJointLimits(position_last, velocity_last, position_current,
744 duration_last, duration_current, joint_limits));
745}
746
757TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testVerifySampleJointLimitsVelocityViolation)
758{
759 const std::string test_joint_name{ "joint" };
760
761 std::map<std::string, double> position_last{ { test_joint_name, 2.0 } };
762 std::map<std::string, double> position_current{ { test_joint_name, 10.0 } };
763 std::map<std::string, double> velocity_last;
764 double duration_current{ 1.0 };
765 double duration_last{ 0.0 };
767
769 // Calculate the max allowed velocity in such a way that it is always smaller
770 // than the current velocity.
771 test_joint_limits.max_velocity =
772 ((position_current.at(test_joint_name) - position_last.at(test_joint_name)) / duration_current) - 1.0;
773 test_joint_limits.has_velocity_limits = true;
774 joint_limits.addLimit(test_joint_name, test_joint_limits);
775
776 EXPECT_FALSE(pilz_industrial_motion_planner::verifySampleJointLimits(position_last, velocity_last, position_current,
777 duration_last, duration_current, joint_limits));
778}
779
790TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testVerifySampleJointLimitsAccelerationViolation)
791{
792 const std::string test_joint_name{ "joint" };
793
794 double duration_current = 1.0;
795 double duration_last = 1.0;
796
797 std::map<std::string, double> position_last{ { test_joint_name, 2.0 } };
798 std::map<std::string, double> position_current{ { test_joint_name, 20.0 } };
799 double velocity_current =
800 ((position_current.at(test_joint_name) - position_last.at(test_joint_name)) / duration_current);
801 std::map<std::string, double> velocity_last{ { test_joint_name, 9.0 } };
803
805 // Calculate the max allowed velocity in such a way that it is always bigger
806 // than the current velocity.
807 test_joint_limits.max_velocity = velocity_current + 1.0;
808 test_joint_limits.has_velocity_limits = true;
809
810 double acceleration_current =
811 (velocity_current - velocity_last.at(test_joint_name)) / (duration_last + duration_current) * 2;
812 // Calculate the max allowed acceleration in such a way that it is always
813 // smaller than the current acceleration.
814 test_joint_limits.max_acceleration = acceleration_current - 1.0;
815 test_joint_limits.has_acceleration_limits = true;
816
817 joint_limits.addLimit(test_joint_name, test_joint_limits);
818
819 EXPECT_FALSE(pilz_industrial_motion_planner::verifySampleJointLimits(position_last, velocity_last, position_current,
820 duration_last, duration_current, joint_limits));
821}
822
833TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testVerifySampleJointLimitsDecelerationViolation)
834{
835 const std::string test_joint_name{ "joint" };
836
837 double duration_current = 1.0;
838 double duration_last = 1.0;
839
840 std::map<std::string, double> position_last{ { test_joint_name, 20.0 } };
841 std::map<std::string, double> position_current{ { test_joint_name, 2.0 } };
842 double velocity_current =
843 ((position_current.at(test_joint_name) - position_last.at(test_joint_name)) / duration_current);
844 std::map<std::string, double> velocity_last{ { test_joint_name, 19.0 } };
846
848 // Calculate the max allowed velocity in such a way that it is always bigger
849 // than the current velocity.
850 test_joint_limits.max_velocity = fabs(velocity_current) + 1.0;
851 test_joint_limits.has_velocity_limits = true;
852
853 double acceleration_current =
854 (velocity_current - velocity_last.at(test_joint_name)) / (duration_last + duration_current) * 2;
855 // Calculate the max allowed deceleration in such a way that it is always
856 // bigger than the current acceleration.
857 test_joint_limits.max_deceleration = acceleration_current + 1.0;
858 test_joint_limits.has_deceleration_limits = true;
859
860 joint_limits.addLimit(test_joint_name, test_joint_limits);
861
862 EXPECT_FALSE(pilz_industrial_motion_planner::verifySampleJointLimits(position_last, velocity_last, position_current,
863 duration_last, duration_current, joint_limits));
864}
865
880TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testGenerateJointTrajectoryWithInvalidCartesianTrajectory)
881{
882 // Create random test trajectory
883 // Note: 'path' is deleted by KDL::Trajectory_Segment
884 KDL::Path_RoundedComposite* path =
885 new KDL::Path_RoundedComposite(0.2, 0.01, new KDL::RotationalInterpolation_SingleAxis());
886 path->Add(KDL::Frame(KDL::Rotation::RPY(0, 0, 0), KDL::Vector(-1, 0, 0)));
887 path->Finish();
888 // Note: 'velprof' is deleted by KDL::Trajectory_Segment
889 KDL::VelocityProfile* vel_prof = new KDL::VelocityProfile_Trap(0.5, 0.1);
890 vel_prof->SetProfile(0, path->PathLength());
891 KDL::Trajectory_Segment kdl_trajectory(path, vel_prof);
892
894 std::string group_name{ "invalid_group_name" };
895 std::map<std::string, double> initial_joint_position;
896 double sampling_time{ 0.1 };
897 trajectory_msgs::msg::JointTrajectory joint_trajectory;
898 moveit_msgs::msg::MoveItErrorCodes error_code;
899 bool check_self_collision{ false };
900
902 planning_scene_, joint_limits, kdl_trajectory, group_name, tcp_link_, initial_joint_position, sampling_time,
903 joint_trajectory, error_code, check_self_collision));
904
905 std::map<std::string, double> initial_joint_velocity;
906
908 cart_traj.group_name = group_name;
909 cart_traj.link_name = tcp_link_;
911 cart_traj.points.push_back(cart_traj_point);
912
914 planning_scene_, joint_limits, cart_traj, group_name, tcp_link_, initial_joint_position, initial_joint_velocity,
915 joint_trajectory, error_code, check_self_collision));
916}
917
929TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testDetermineAndCheckSamplingTimeInvalidVectorSize)
930{
931 robot_trajectory::RobotTrajectoryPtr first_trajectory =
932 std::make_shared<robot_trajectory::RobotTrajectory>(robot_model_, planning_group_);
933 robot_trajectory::RobotTrajectoryPtr second_trajectory =
934 std::make_shared<robot_trajectory::RobotTrajectory>(robot_model_, planning_group_);
935 double epsilon{ 0.0 };
936 double sampling_time{ 0.0 };
937
938 moveit::core::RobotState rstate(robot_model_);
939 first_trajectory->insertWayPoint(0, rstate, 0.1);
940 second_trajectory->insertWayPoint(0, rstate, 0.1);
941
942 EXPECT_FALSE(pilz_industrial_motion_planner::determineAndCheckSamplingTime(first_trajectory, second_trajectory,
943 epsilon, sampling_time));
944}
945
957TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testDetermineAndCheckSamplingTimeCorrectSamplingTime)
958{
959 robot_trajectory::RobotTrajectoryPtr first_trajectory =
960 std::make_shared<robot_trajectory::RobotTrajectory>(robot_model_, planning_group_);
961 robot_trajectory::RobotTrajectoryPtr second_trajectory =
962 std::make_shared<robot_trajectory::RobotTrajectory>(robot_model_, planning_group_);
963 double epsilon{ 0.0001 };
964 double sampling_time{ 0.0 };
965 double expected_sampling_time{ 0.1 };
966
967 moveit::core::RobotState rstate(robot_model_);
968 first_trajectory->insertWayPoint(0, rstate, expected_sampling_time);
969 first_trajectory->insertWayPoint(1, rstate, expected_sampling_time);
970
971 second_trajectory->insertWayPoint(0, rstate, expected_sampling_time);
972 second_trajectory->insertWayPoint(1, rstate, expected_sampling_time);
973 second_trajectory->insertWayPoint(2, rstate, expected_sampling_time);
974
975 EXPECT_TRUE(pilz_industrial_motion_planner::determineAndCheckSamplingTime(first_trajectory, second_trajectory,
976 epsilon, sampling_time));
977 EXPECT_EQ(expected_sampling_time, sampling_time);
978}
979
991TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testDetermineAndCheckSamplingTimeViolateSamplingTime)
992{
993 robot_trajectory::RobotTrajectoryPtr first_trajectory =
994 std::make_shared<robot_trajectory::RobotTrajectory>(robot_model_, planning_group_);
995 robot_trajectory::RobotTrajectoryPtr second_trajectory =
996 std::make_shared<robot_trajectory::RobotTrajectory>(robot_model_, planning_group_);
997 double epsilon{ 0.0001 };
998 double sampling_time{ 0.0 };
999 double expected_sampling_time{ 0.1 };
1000
1001 moveit::core::RobotState rstate(robot_model_);
1002 first_trajectory->insertWayPoint(0, rstate, expected_sampling_time);
1003 first_trajectory->insertWayPoint(1, rstate, expected_sampling_time);
1004 first_trajectory->insertWayPoint(2, rstate, expected_sampling_time);
1005 // Violate sampling time
1006 first_trajectory->insertWayPoint(2, rstate, expected_sampling_time + 1.0);
1007 first_trajectory->insertWayPoint(3, rstate, expected_sampling_time);
1008
1009 second_trajectory->insertWayPoint(0, rstate, expected_sampling_time);
1010 second_trajectory->insertWayPoint(1, rstate, expected_sampling_time);
1011 second_trajectory->insertWayPoint(2, rstate, expected_sampling_time);
1012 second_trajectory->insertWayPoint(3, rstate, expected_sampling_time);
1013
1014 EXPECT_FALSE(pilz_industrial_motion_planner::determineAndCheckSamplingTime(first_trajectory, second_trajectory,
1015 epsilon, sampling_time));
1016 EXPECT_EQ(expected_sampling_time, sampling_time);
1017}
1018
1030TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testIsRobotStateEqualPositionUnequal)
1031{
1032 moveit::core::RobotState rstate_1 = moveit::core::RobotState(robot_model_);
1033 moveit::core::RobotState rstate_2 = moveit::core::RobotState(robot_model_);
1034
1035 double default_joint_position[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
1036 rstate_1.setJointGroupPositions(planning_group_, default_joint_position);
1037 // Ensure that the joint positions of both robot states are different
1038 default_joint_position[0] = default_joint_position[0] + 70.0;
1039 rstate_2.setJointGroupPositions(planning_group_, default_joint_position);
1040
1041 double epsilon{ 0.0001 };
1042 EXPECT_FALSE(pilz_industrial_motion_planner::isRobotStateEqual(rstate_1, rstate_2, planning_group_, epsilon));
1043}
1044
1056TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testIsRobotStateEqualVelocityUnequal)
1057{
1058 moveit::core::RobotState rstate_1 = moveit::core::RobotState(robot_model_);
1059 moveit::core::RobotState rstate_2 = moveit::core::RobotState(robot_model_);
1060
1061 // Ensure that the joint positions of both robot state are equal
1062 double default_joint_position[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
1063 rstate_1.setJointGroupPositions(planning_group_, default_joint_position);
1064 rstate_2.setJointGroupPositions(planning_group_, default_joint_position);
1065
1066 double default_joint_velocity[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
1067 rstate_1.setJointGroupVelocities(planning_group_, default_joint_velocity);
1068 // Ensure that the joint velocites of both robot states are different
1069 default_joint_velocity[1] = default_joint_velocity[1] + 10.0;
1070 rstate_2.setJointGroupVelocities(planning_group_, default_joint_velocity);
1071
1072 double epsilon{ 0.0001 };
1073 EXPECT_FALSE(pilz_industrial_motion_planner::isRobotStateEqual(rstate_1, rstate_2, planning_group_, epsilon));
1074}
1075
1087TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testIsRobotStateEqualAccelerationUnequal)
1088{
1089 moveit::core::RobotState rstate_1 = moveit::core::RobotState(robot_model_);
1090 moveit::core::RobotState rstate_2 = moveit::core::RobotState(robot_model_);
1091
1092 // Ensure that the joint positions of both robot state are equal
1093 double default_joint_position[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
1094 rstate_1.setJointGroupPositions(planning_group_, default_joint_position);
1095 rstate_2.setJointGroupPositions(planning_group_, default_joint_position);
1096
1097 // Ensure that the joint velocities of both robot state are equal
1098 double default_joint_velocity[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
1099 rstate_1.setJointGroupVelocities(planning_group_, default_joint_velocity);
1100 rstate_2.setJointGroupVelocities(planning_group_, default_joint_velocity);
1101
1102 double default_joint_acceleration[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
1103 rstate_1.setJointGroupAccelerations(planning_group_, default_joint_acceleration);
1104 // Ensure that the joint accelerations of both robot states are different
1105 default_joint_acceleration[1] = default_joint_acceleration[1] + 10.0;
1106 rstate_2.setJointGroupAccelerations(planning_group_, default_joint_acceleration);
1107
1108 double epsilon{ 0.0001 };
1109 EXPECT_FALSE(pilz_industrial_motion_planner::isRobotStateEqual(rstate_1, rstate_2, planning_group_, epsilon));
1110}
1111
1123TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testIsRobotStateStationaryVelocityUnequal)
1124{
1125 moveit::core::RobotState rstate_1 = moveit::core::RobotState(robot_model_);
1126
1127 // Ensure that the joint velocities are NOT zero
1128 double default_joint_velocity[6] = { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
1129 rstate_1.setJointGroupVelocities(planning_group_, default_joint_velocity);
1130
1131 double epsilon{ 0.0001 };
1132 EXPECT_FALSE(pilz_industrial_motion_planner::isRobotStateStationary(rstate_1, planning_group_, epsilon));
1133}
1134
1146TEST_F(TrajectoryFunctionsTestFlangeAndGripper, testIsRobotStateStationaryAccelerationUnequal)
1147{
1148 moveit::core::RobotState rstate_1 = moveit::core::RobotState(robot_model_);
1149
1150 // Ensure that the joint velocities are zero
1151 double default_joint_velocity[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
1152 rstate_1.setJointGroupVelocities(planning_group_, default_joint_velocity);
1153
1154 // Ensure that the joint acceleration are NOT zero
1155 double default_joint_acceleration[6] = { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
1156 rstate_1.setJointGroupAccelerations(planning_group_, default_joint_acceleration);
1157
1158 double epsilon{ 0.0001 };
1159 EXPECT_FALSE(pilz_industrial_motion_planner::isRobotStateStationary(rstate_1, planning_group_, epsilon));
1160}
1161
1162int main(int argc, char** argv)
1163{
1164 rclcpp::init(argc, argv);
1165 testing::InitGoogleTest(&argc, argv);
1166 return RUN_ALL_TESTS();
1167}
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, 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
Parametrized class for tests with and without gripper.
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...
const kinematics::KinematicsBaseConstPtr getSolverInstance() const
A link from the robot. Contains the constant transform applied to the link and its geometry.
Representation of a robot's state. This includes position, velocity, acceleration and effort.
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...
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...
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...
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.
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...
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
joint_limits_interface::JointLimits JointLimit
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 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, 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 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.
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.
const std::string RANDOM_TEST_NUMBER("random_test_number")
int main(int argc, char **argv)
TEST_F(TrajectoryFunctionsTestFlangeAndGripper, TipLinkFK)
Parametrized class for tests, that only run with a gripper.