22#include <gtest/gtest.h>
23#include <warehouse_ros/message_collection.h>
26#include <moveit_msgs/msg/motion_plan_request.hpp>
27#include <moveit_msgs/msg/robot_trajectory.hpp>
28#include <moveit_msgs/srv/get_cartesian_path.hpp>
34#include "../fixtures/move_group_fixture.hpp"
39using ::warehouse_ros::MessageCollection;
40using ::warehouse_ros::MessageWithMetadata;
41using ::warehouse_ros::Metadata;
42using ::warehouse_ros::Query;
44using ::moveit::core::MoveItErrorCode;
45using ::moveit::planning_interface::MoveGroupInterface;
47using ::moveit_msgs::msg::MotionPlanRequest;
48using ::moveit_msgs::msg::RobotTrajectory;
49using ::moveit_msgs::srv::GetCartesianPath;
51using ::moveit_ros::trajectory_cache::BestSeenExecutionTimePolicy;
52using ::moveit_ros::trajectory_cache::CartesianBestSeenExecutionTimePolicy;
53using ::moveit_ros::trajectory_cache::constructGetCartesianPathRequest;
54using ::moveit_ros::trajectory_cache::FeaturesInterface;
63 BestSeenExecutionTimePolicy policy;
65 MessageCollection<RobotTrajectory> coll = db_->openCollection<RobotTrajectory>(
"test_db", policy.getName());
68 MoveGroupInterface::Plan valid_plan;
72 valid_msg.workspace_parameters.header.frame_id =
"panda_link0";
73 valid_msg.goal_constraints.emplace_back();
75 valid_plan.trajectory.joint_trajectory.header.frame_id =
"panda_link0";
76 valid_plan.trajectory.joint_trajectory.joint_names.emplace_back();
77 valid_plan.trajectory.joint_trajectory.points.emplace_back();
79 MoveItErrorCode ret = policy.checkCacheInsertInputs(*move_group_, coll, valid_msg, valid_plan);
80 ASSERT_TRUE(ret) << ret.message;
89 msg.goal_constraints.clear();
90 EXPECT_FALSE(policy.checkCacheInsertInputs(*move_group_, coll, msg, valid_plan));
95 MoveGroupInterface::Plan
plan = valid_plan;
97 EXPECT_FALSE(policy.checkCacheInsertInputs(*move_group_, coll, valid_msg, plan));
102 MoveGroupInterface::Plan
plan = valid_plan;
104 EXPECT_FALSE(policy.checkCacheInsertInputs(*move_group_, coll, valid_msg, plan));
109 MoveGroupInterface::Plan
plan = valid_plan;
111 EXPECT_FALSE(policy.checkCacheInsertInputs(*move_group_, coll, valid_msg, plan));
116 MoveGroupInterface::Plan
plan = valid_plan;
118 EXPECT_FALSE(policy.checkCacheInsertInputs(*move_group_, coll, valid_msg, plan));
124 MoveGroupInterface::Plan
plan = valid_plan;
125 msg.workspace_parameters.header.frame_id =
"panda_link0";
126 plan.
trajectory.joint_trajectory.header.frame_id =
"clearly_a_different_frame";
127 EXPECT_FALSE(policy.checkCacheInsertInputs(*move_group_, coll, msg, plan));
133 BestSeenExecutionTimePolicy policy;
135 MessageCollection<RobotTrajectory> coll = db_->openCollection<RobotTrajectory>(
"test_db", policy.getName());
136 ASSERT_EQ(coll.count(), 0);
140 MoveGroupInterface::Plan
plan;
141 MoveItErrorCode ret = MoveItErrorCode::FAILURE;
144 MoveGroupInterface::Plan another_plan;
145 MoveItErrorCode another_ret = MoveItErrorCode::FAILURE;
149 ASSERT_TRUE(move_group_->setPoseTarget(move_group_->getRandomPose()));
150 move_group_->constructMotionPlanRequest(msg);
151 ret = move_group_->plan(plan);
152 }
while (!ret ||
plan.
trajectory.joint_trajectory.points.empty());
156 ASSERT_TRUE(move_group_->setPoseTarget(move_group_->getRandomPose()));
157 move_group_->constructMotionPlanRequest(another_msg);
158 another_ret = move_group_->plan(another_plan);
159 }
while (another_msg == msg || !another_ret ||
160 another_plan.trajectory.joint_trajectory.points
165 MoveItErrorCode ret = policy.checkCacheInsertInputs(*move_group_, coll, msg, plan);
166 ASSERT_TRUE(ret) << ret.message;
169 MoveItErrorCode ret = policy.checkCacheInsertInputs(*move_group_, coll, another_msg, another_plan);
170 ASSERT_TRUE(ret) << ret.message;
178 plan.
trajectory.joint_trajectory.points.back().time_from_start.sec = 10;
179 plan.
trajectory.joint_trajectory.points.back().time_from_start.nanosec = 0;
180 another_plan.trajectory.joint_trajectory.points.back().time_from_start.sec = 10;
181 another_plan.trajectory.joint_trajectory.points.back().time_from_start.nanosec = 0;
185 for (
const auto& msg_plan_pair : { std::make_pair(msg, plan), std::make_pair(another_msg, another_plan) })
187 Metadata::Ptr metadata = coll.createMetadata();
188 EXPECT_TRUE(policy.appendInsertMetadata(*metadata, *move_group_, msg_plan_pair.first, msg_plan_pair.second));
189 EXPECT_TRUE(metadata->lookupField(
"execution_time_s"));
190 EXPECT_TRUE(metadata->lookupField(
"planning_time_s"));
193 coll.insert(msg_plan_pair.second.trajectory, metadata);
194 coll.insert(msg_plan_pair.second.trajectory, metadata);
196 ASSERT_EQ(coll.count(), count);
203 std::vector<std::unique_ptr<FeaturesInterface<MotionPlanRequest>>> features =
204 BestSeenExecutionTimePolicy::getSupportedFeatures(0.025, 0.001);
206 for (
const auto& msg_plan_pair : { std::make_pair(msg, plan), std::make_pair(another_msg, another_plan) })
208 Query::Ptr query = coll.createQuery();
209 for (
const auto& feature : features)
211 ASSERT_TRUE(feature->appendFeaturesAsExactFetchQuery(*query, msg_plan_pair.first, *move_group_,
215 std::vector<MessageWithMetadata<RobotTrajectory>::ConstPtr> feature_fetch =
216 coll.queryList(query,
true);
217 std::vector<MessageWithMetadata<RobotTrajectory>::ConstPtr> policy_fetch = policy.fetchMatchingEntries(
218 *move_group_, coll, msg_plan_pair.first, msg_plan_pair.second, 0.0001);
220 ASSERT_EQ(feature_fetch.size(), 2);
221 ASSERT_EQ(policy_fetch.size(), 2);
222 for (
size_t i = 0; i < feature_fetch.size(); ++i)
224 ASSERT_EQ(*feature_fetch[i], *policy_fetch[i]);
227 auto longer_plan = msg_plan_pair.second;
228 longer_plan.trajectory.joint_trajectory.points.back().time_from_start.sec = 100;
229 longer_plan.trajectory.joint_trajectory.points.back().time_from_start.nanosec = 0;
231 auto shorter_plan = msg_plan_pair.second;
232 shorter_plan.trajectory.joint_trajectory.points.back().time_from_start.sec = 0;
233 shorter_plan.trajectory.joint_trajectory.points.back().time_from_start.nanosec = 100;
236 EXPECT_FALSE(policy.shouldPruneMatchingEntry(*move_group_, msg_plan_pair.first, longer_plan, policy_fetch[i]));
237 EXPECT_TRUE(policy.shouldPruneMatchingEntry(*move_group_, msg_plan_pair.first, shorter_plan, policy_fetch[i]));
240 EXPECT_FALSE(policy.shouldInsert(*move_group_, msg_plan_pair.first, longer_plan));
241 EXPECT_TRUE(policy.shouldInsert(*move_group_, msg_plan_pair.first, shorter_plan));
255 CartesianBestSeenExecutionTimePolicy policy;
257 MessageCollection<RobotTrajectory> coll = db_->openCollection<RobotTrajectory>(
"test_db", policy.getName());
259 GetCartesianPath::Request valid_msg;
260 GetCartesianPath::Response valid_plan;
261 valid_plan.fraction = -1;
265 std::vector<geometry_msgs::msg::Pose> waypoints;
266 waypoints.push_back(move_group_->getCurrentPose().pose);
267 waypoints.push_back(move_group_->getRandomPose().pose);
271#pragma GCC diagnostic push
272#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
273 valid_plan.fraction = move_group_->computeCartesianPath(valid_msg.waypoints, valid_msg.max_step,
274 valid_msg.jump_threshold, valid_plan.solution);
275#pragma GCC diagnostic pop
276 }
while (valid_plan.fraction <= 0 &&
277 valid_plan.solution.joint_trajectory.points.size() < 2);
281 MoveItErrorCode ret = policy.checkCacheInsertInputs(*move_group_, coll, valid_msg, valid_plan);
282 ASSERT_TRUE(ret) << ret.message;
290 GetCartesianPath::Request msg = valid_msg;
291 msg.waypoints.clear();
292 EXPECT_FALSE(policy.checkCacheInsertInputs(*move_group_, coll, msg, valid_plan));
297 GetCartesianPath::Response
plan = valid_plan;
298 plan.solution.joint_trajectory.points.clear();
299 EXPECT_FALSE(policy.checkCacheInsertInputs(*move_group_, coll, valid_msg, plan));
304 GetCartesianPath::Response
plan = valid_plan;
305 plan.solution.joint_trajectory.joint_names.clear();
306 EXPECT_FALSE(policy.checkCacheInsertInputs(*move_group_, coll, valid_msg, plan));
311 GetCartesianPath::Response
plan = valid_plan;
312 plan.solution.multi_dof_joint_trajectory.points.emplace_back();
313 EXPECT_FALSE(policy.checkCacheInsertInputs(*move_group_, coll, valid_msg, plan));
318 GetCartesianPath::Response
plan = valid_plan;
319 plan.solution.joint_trajectory.header.frame_id =
"";
320 EXPECT_FALSE(policy.checkCacheInsertInputs(*move_group_, coll, valid_msg, plan));
325 GetCartesianPath::Request msg = valid_msg;
326 GetCartesianPath::Response
plan = valid_plan;
327 msg.header.frame_id =
"panda_link0";
328 plan.solution.joint_trajectory.header.frame_id =
"clearly_a_different_frame";
329 EXPECT_FALSE(policy.checkCacheInsertInputs(*move_group_, coll, msg, plan));
335 CartesianBestSeenExecutionTimePolicy policy;
337 MessageCollection<RobotTrajectory> coll = db_->openCollection<RobotTrajectory>(
"test_db", policy.getName());
338 ASSERT_EQ(coll.count(), 0);
341 GetCartesianPath::Request msg;
342 GetCartesianPath::Response
plan;
345 GetCartesianPath::Request another_msg;
346 GetCartesianPath::Response another_plan;
347 another_plan.fraction = -1;
351 std::vector<geometry_msgs::msg::Pose> waypoints;
352 waypoints.push_back(move_group_->getCurrentPose().pose);
353 waypoints.push_back(move_group_->getRandomPose().pose);
357#pragma GCC diagnostic push
358#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
359 plan.fraction = move_group_->computeCartesianPath(msg.waypoints, msg.max_step, msg.jump_threshold,
plan.solution);
360#pragma GCC diagnostic pop
361 }
while (
plan.fraction <= 0 &&
362 plan.solution.joint_trajectory.points.size() < 2);
366 std::vector<geometry_msgs::msg::Pose> waypoints;
367 waypoints.push_back(move_group_->getCurrentPose().pose);
368 waypoints.push_back(move_group_->getRandomPose().pose);
372#pragma GCC diagnostic push
373#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
374 another_plan.fraction = move_group_->computeCartesianPath(another_msg.waypoints, another_msg.max_step,
375 another_msg.jump_threshold, another_plan.solution);
376#pragma GCC diagnostic pop
377 }
while (another_plan.fraction <= 0 &&
378 another_plan.solution.joint_trajectory.points.size() < 2);
382 MoveItErrorCode ret = policy.checkCacheInsertInputs(*move_group_, coll, msg, plan);
383 ASSERT_TRUE(ret) << ret.message;
386 MoveItErrorCode ret = policy.checkCacheInsertInputs(*move_group_, coll, another_msg, another_plan);
387 ASSERT_TRUE(ret) << ret.message;
395 plan.solution.joint_trajectory.points.back().time_from_start.sec = 10;
396 plan.solution.joint_trajectory.points.back().time_from_start.nanosec = 0;
397 another_plan.solution.joint_trajectory.points.back().time_from_start.sec = 10;
398 another_plan.solution.joint_trajectory.points.back().time_from_start.nanosec = 0;
402 for (
const auto& msg_plan_pair : { std::make_pair(msg, plan), std::make_pair(another_msg, another_plan) })
404 Metadata::Ptr metadata = coll.createMetadata();
405 EXPECT_TRUE(policy.appendInsertMetadata(*metadata, *move_group_, msg_plan_pair.first, msg_plan_pair.second));
406 EXPECT_TRUE(metadata->lookupField(
"execution_time_s"));
407 EXPECT_TRUE(metadata->lookupField(
"fraction"));
410 coll.insert(msg_plan_pair.second.solution, metadata);
411 coll.insert(msg_plan_pair.second.solution, metadata);
413 ASSERT_EQ(coll.count(), count);
420 std::vector<std::unique_ptr<FeaturesInterface<GetCartesianPath::Request>>> features =
421 CartesianBestSeenExecutionTimePolicy::getSupportedFeatures(0.025,
425 for (
const auto& msg_plan_pair : { std::make_pair(msg, plan), std::make_pair(another_msg, another_plan) })
427 Query::Ptr query = coll.createQuery();
428 for (
const auto& feature : features)
430 ASSERT_TRUE(feature->appendFeaturesAsExactFetchQuery(*query, msg_plan_pair.first, *move_group_,
434 std::vector<MessageWithMetadata<RobotTrajectory>::ConstPtr> feature_fetch =
435 coll.queryList(query,
true);
436 std::vector<MessageWithMetadata<RobotTrajectory>::ConstPtr> policy_fetch = policy.fetchMatchingEntries(
437 *move_group_, coll, msg_plan_pair.first, msg_plan_pair.second, 0.0001);
439 ASSERT_EQ(feature_fetch.size(), 2);
440 ASSERT_EQ(policy_fetch.size(), 2);
441 for (
size_t i = 0; i < feature_fetch.size(); ++i)
443 ASSERT_EQ(*feature_fetch[i], *policy_fetch[i]);
446 auto longer_plan = msg_plan_pair.second;
447 longer_plan.solution.joint_trajectory.points.back().time_from_start.sec = 100;
448 longer_plan.solution.joint_trajectory.points.back().time_from_start.nanosec = 0;
450 auto shorter_plan = msg_plan_pair.second;
451 shorter_plan.solution.joint_trajectory.points.back().time_from_start.sec = 0;
452 shorter_plan.solution.joint_trajectory.points.back().time_from_start.nanosec = 100;
455 std::string longer_prune_reason;
456 std::string shorter_prune_reason;
458 EXPECT_FALSE(policy.shouldPruneMatchingEntry(*move_group_, msg_plan_pair.first, longer_plan, policy_fetch[i],
459 &longer_prune_reason));
460 EXPECT_TRUE(policy.shouldPruneMatchingEntry(*move_group_, msg_plan_pair.first, shorter_plan, policy_fetch[i],
461 &shorter_prune_reason));
463 EXPECT_FALSE(longer_prune_reason.empty());
464 EXPECT_FALSE(shorter_prune_reason.empty());
467 std::string longer_insert_reason;
468 std::string shorter_insert_reason;
470 EXPECT_FALSE(policy.shouldInsert(*move_group_, msg_plan_pair.first, longer_plan, &longer_insert_reason));
471 EXPECT_TRUE(policy.shouldInsert(*move_group_, msg_plan_pair.first, shorter_plan, &shorter_insert_reason));
473 EXPECT_FALSE(longer_insert_reason.empty());
474 EXPECT_FALSE(shorter_insert_reason.empty());
485 rclcpp::init(argc, argv);
486 ::testing::InitGoogleTest(&argc, argv);
487 int result = RUN_ALL_TESTS();
A cache insertion policy that only decides to insert if the motion plan is the one with the shortest ...
Test fixture to spin up a node to start a move group with.
Abstract template class for extracting features from some FeatureSourceT.
Utilities used by the trajectory_cache package.
planning_interface::MotionPlanResponse plan(std::shared_ptr< moveit_cpp::PlanningComponent > &planning_component, std::shared_ptr< moveit_cpp::PlanningComponent::PlanRequestParameters > &single_plan_parameters, std::shared_ptr< moveit_cpp::PlanningComponent::MultiPipelinePlanRequestParameters > &multi_plan_parameters, std::shared_ptr< planning_scene::PlanningScene > &planning_scene, std::optional< const moveit::planning_pipeline_interfaces::SolutionSelectionFunction > solution_selection_function, std::optional< moveit::planning_pipeline_interfaces::StoppingCriterionFunction > stopping_criterion_callback)
moveit_msgs::srv::GetCartesianPath::Request constructGetCartesianPathRequest(moveit::planning_interface::MoveGroupInterface &move_group, const std::vector< geometry_msgs::msg::Pose > &waypoints, double max_step, double jump_threshold, bool avoid_collisions=true)
Constructs a GetCartesianPath request.
moveit_msgs::msg::MotionPlanRequest MotionPlanRequest
robot_trajectory::RobotTrajectoryPtr trajectory
int main(int argc, char **argv)
TEST_F(BulletCollisionDetectionTester, DISABLED_ContinuousCollisionSelf)
Continuous self collision checks are not supported yet by the bullet integration.