28#include <warehouse_ros/message_collection.h>
31#include <moveit_msgs/msg/motion_plan_request.hpp>
32#include <moveit_msgs/msg/robot_trajectory.hpp>
33#include <moveit_msgs/srv/get_cartesian_path.hpp>
43namespace trajectory_cache
46using ::warehouse_ros::MessageCollection;
47using ::warehouse_ros::MessageWithMetadata;
48using ::warehouse_ros::Metadata;
49using ::warehouse_ros::Query;
51using ::moveit::core::MoveItErrorCode;
52using ::moveit::planning_interface::MoveGroupInterface;
54using ::moveit_msgs::msg::MotionPlanRequest;
55using ::moveit_msgs::msg::RobotTrajectory;
56using ::moveit_msgs::srv::GetCartesianPath;
58using ::moveit_ros::trajectory_cache::FeaturesInterface;
63const std::string EXECUTION_TIME =
"execution_time_s";
64const std::string FRACTION =
"fraction";
65const std::string PLANNING_TIME =
"planning_time_s";
80std::vector<std::unique_ptr<FeaturesInterface<MotionPlanRequest>>>
83 std::vector<std::unique_ptr<FeaturesInterface<MotionPlanRequest>>> out;
87 out.push_back(std::make_unique<WorkspaceFeatures>());
88 out.push_back(std::make_unique<StartStateJointStateFeatures>(start_tolerance));
91 out.push_back(std::make_unique<MaxSpeedAndAccelerationFeatures>());
92 out.push_back(std::make_unique<GoalConstraintsFeatures>(goal_tolerance));
93 out.push_back(std::make_unique<PathConstraintsFeatures>(goal_tolerance));
94 out.push_back(std::make_unique<TrajectoryConstraintsFeatures>(goal_tolerance));
105 const MessageCollection<RobotTrajectory>& ,
106 const MotionPlanRequest& key,
107 const MoveGroupInterface::Plan& value)
112 if (frame_id.empty())
114 return MoveItErrorCode(MoveItErrorCode::INVALID_MOTION_PLAN,
115 name_ +
": Skipping insert: Workspace frame ID cannot be empty.");
117 if (key.goal_constraints.empty())
119 return MoveItErrorCode(MoveItErrorCode::INVALID_MOTION_PLAN, name_ +
": Skipping insert: No goal.");
123 if (value.trajectory.joint_trajectory.points.empty())
125 return MoveItErrorCode(MoveItErrorCode::INVALID_MOTION_PLAN, name_ +
": Empty joint trajectory points.");
127 if (value.trajectory.joint_trajectory.joint_names.empty())
129 return MoveItErrorCode(MoveItErrorCode::INVALID_MOTION_PLAN,
130 name_ +
": Skipping insert: Empty joint trajectory joint names.");
132 if (!value.trajectory.multi_dof_joint_trajectory.points.empty())
134 return MoveItErrorCode(MoveItErrorCode::INVALID_MOTION_PLAN,
135 name_ +
": Skipping insert: Multi-DOF trajectory plans are not supported.");
137 if (value.trajectory.joint_trajectory.header.frame_id.empty())
139 return MoveItErrorCode(MoveItErrorCode::INVALID_MOTION_PLAN,
140 name_ +
": Skipping insert: Trajectory frame ID cannot be empty.");
142 if (frame_id != value.trajectory.joint_trajectory.header.frame_id)
144 std::stringstream ss;
145 ss <<
"Skipping insert: Plan request frame `" << frame_id <<
"` does not match plan frame `"
146 << value.trajectory.joint_trajectory.header.frame_id <<
"`.";
147 return MoveItErrorCode(MoveItErrorCode::INVALID_MOTION_PLAN, ss.str());
150 return MoveItErrorCode::SUCCESS;
154 const MoveGroupInterface&
move_group,
const MessageCollection<RobotTrajectory>& coll,
const MotionPlanRequest& key,
155 const MoveGroupInterface::Plan& ,
double exact_match_precision)
157 Query::Ptr query = coll.createQuery();
158 for (
const auto& feature : exact_matching_supported_features_)
160 if (MoveItErrorCode ret = feature->appendFeaturesAsExactFetchQuery(*query, key,
move_group, exact_match_precision);
166 return coll.queryList(query,
true);
170 const MoveGroupInterface& ,
const MotionPlanRequest& ,
171 const MoveGroupInterface::Plan& ,
const MessageWithMetadata<RobotTrajectory>::ConstPtr& ,
174 if (reason !=
nullptr)
176 *reason =
"Never prune.";
182 const MotionPlanRequest& ,
183 const MoveGroupInterface::Plan& , std::string* reason)
185 if (reason !=
nullptr)
187 *reason =
"Always insert.";
194 const MotionPlanRequest& key,
195 const MoveGroupInterface::Plan& value)
197 for (
const auto& feature : exact_matching_supported_features_)
199 if (MoveItErrorCode ret = feature->appendFeaturesAsInsertMetadata(metadata, key,
move_group); !ret)
207 metadata.append(PLANNING_TIME, value.planning_time);
209 return MoveItErrorCode::SUCCESS;
223 : name_(
"CartesianAlwaysInsertNeverPrunePolicy")
225 exact_matching_supported_features_ =
230std::vector<std::unique_ptr<FeaturesInterface<GetCartesianPath::Request>>>
234 std::vector<std::unique_ptr<FeaturesInterface<GetCartesianPath::Request>>> out;
238 out.push_back(std::make_unique<CartesianWorkspaceFeatures>());
239 out.push_back(std::make_unique<CartesianStartStateJointStateFeatures>(start_tolerance));
242 out.push_back(std::make_unique<CartesianMaxSpeedAndAccelerationFeatures>());
243 out.push_back(std::make_unique<CartesianMaxStepAndJumpThresholdFeatures>());
244 out.push_back(std::make_unique<CartesianWaypointsFeatures>(goal_tolerance));
245 out.push_back(std::make_unique<CartesianPathConstraintsFeatures>(goal_tolerance));
259 const MoveGroupInterface&
move_group,
const MessageCollection<RobotTrajectory>& ,
260 const GetCartesianPath::Request& key,
const GetCartesianPath::Response& value)
265 if (frame_id.empty())
267 return MoveItErrorCode(MoveItErrorCode::INVALID_MOTION_PLAN,
268 name_ +
": Skipping insert: Workspace frame ID cannot be empty.");
270 if (key.waypoints.empty())
272 return MoveItErrorCode(MoveItErrorCode::INVALID_MOTION_PLAN, name_ +
": Skipping insert: No waypoints.");
276 if (value.solution.joint_trajectory.points.empty())
278 return MoveItErrorCode(MoveItErrorCode::INVALID_MOTION_PLAN, name_ +
": Empty joint trajectory points.");
280 if (value.solution.joint_trajectory.joint_names.empty())
282 return MoveItErrorCode(MoveItErrorCode::INVALID_MOTION_PLAN,
283 name_ +
": Skipping insert: Empty joint trajectory joint names.");
285 if (!value.solution.multi_dof_joint_trajectory.points.empty())
287 return MoveItErrorCode(MoveItErrorCode::INVALID_MOTION_PLAN,
288 name_ +
": Skipping insert: Multi-DOF trajectory plans are not supported.");
290 if (value.solution.joint_trajectory.header.frame_id.empty())
292 return MoveItErrorCode(MoveItErrorCode::INVALID_MOTION_PLAN,
293 name_ +
": Skipping insert: Trajectory frame ID cannot be empty.");
295 if (frame_id != value.solution.joint_trajectory.header.frame_id)
297 std::stringstream ss;
298 ss <<
"Skipping insert: Plan request frame `" << frame_id <<
"` does not match plan frame `"
299 << value.solution.joint_trajectory.header.frame_id <<
"`.";
300 return MoveItErrorCode(MoveItErrorCode::INVALID_MOTION_PLAN, ss.str());
303 return MoveItErrorCode::SUCCESS;
307 const MoveGroupInterface&
move_group,
const MessageCollection<RobotTrajectory>& coll,
308 const GetCartesianPath::Request& key,
const GetCartesianPath::Response& ,
double exact_match_precision)
310 Query::Ptr query = coll.createQuery();
311 for (
const auto& feature : exact_matching_supported_features_)
313 if (MoveItErrorCode ret = feature->appendFeaturesAsExactFetchQuery(*query, key,
move_group, exact_match_precision);
319 return coll.queryList(query,
true);
323 const MoveGroupInterface& ,
const GetCartesianPath::Request& ,
324 const GetCartesianPath::Response& ,
325 const MessageWithMetadata<RobotTrajectory>::ConstPtr& , std::string* reason)
327 if (reason !=
nullptr)
329 *reason =
"Never prune.";
335 const GetCartesianPath::Request& ,
336 const GetCartesianPath::Response& ,
339 if (reason !=
nullptr)
341 *reason =
"Always insert.";
348 const GetCartesianPath::Request& key,
349 const GetCartesianPath::Response& value)
351 for (
const auto& feature : exact_matching_supported_features_)
353 if (MoveItErrorCode ret = feature->appendFeaturesAsInsertMetadata(metadata, key,
move_group); !ret)
361 metadata.append(FRACTION, value.fraction);
363 return MoveItErrorCode::SUCCESS;
A cache insertion policy that always decides to insert and never decides to prune.
std::vector< warehouse_ros::MessageWithMetadata< moveit_msgs::msg::RobotTrajectory >::ConstPtr > fetchMatchingEntries(const moveit::planning_interface::MoveGroupInterface &move_group, const warehouse_ros::MessageCollection< moveit_msgs::msg::RobotTrajectory > &coll, const moveit_msgs::msg::MotionPlanRequest &key, const moveit::planning_interface::MoveGroupInterface::Plan &value, double exact_match_precision) override
Fetches all "matching" cache entries for comparison for pruning.
moveit::core::MoveItErrorCode checkCacheInsertInputs(const moveit::planning_interface::MoveGroupInterface &move_group, const warehouse_ros::MessageCollection< moveit_msgs::msg::RobotTrajectory > &coll, const moveit_msgs::msg::MotionPlanRequest &key, const moveit::planning_interface::MoveGroupInterface::Plan &value) override
Checks inputs to the cache insert call to see if we should abort instead.
AlwaysInsertNeverPrunePolicy()
bool shouldPruneMatchingEntry(const moveit::planning_interface::MoveGroupInterface &move_group, const moveit_msgs::msg::MotionPlanRequest &key, const moveit::planning_interface::MoveGroupInterface::Plan &value, const warehouse_ros::MessageWithMetadata< moveit_msgs::msg::RobotTrajectory >::ConstPtr &matching_entry, std::string *reason=nullptr) override
bool shouldInsert(const moveit::planning_interface::MoveGroupInterface &move_group, const moveit_msgs::msg::MotionPlanRequest &key, const moveit::planning_interface::MoveGroupInterface::Plan &value, std::string *reason=nullptr) override
Returns whether the insertion candidate should be inserted into the cache.
static std::vector< std::unique_ptr< FeaturesInterface< moveit_msgs::msg::MotionPlanRequest > > > getSupportedFeatures(double start_tolerance, double goal_tolerance)
Configures and returns a vector of feature extractors that can be used with this policy.
std::string getName() const override
Gets the name of the cache insert policy.
void reset() override
Resets the state of the policy.
moveit::core::MoveItErrorCode appendInsertMetadata(warehouse_ros::Metadata &metadata, const moveit::planning_interface::MoveGroupInterface &move_group, const moveit_msgs::msg::MotionPlanRequest &key, const moveit::planning_interface::MoveGroupInterface::Plan &value) override
Appends the insert metadata with the features supported by the policy.
std::string getName() const override
Gets the name of the cache insert policy.
static std::vector< std::unique_ptr< FeaturesInterface< moveit_msgs::srv::GetCartesianPath::Request > > > getSupportedFeatures(double start_tolerance, double goal_tolerance, double min_fraction)
Configures and returns a vector of feature extractors that can be used with this policy.
bool shouldInsert(const moveit::planning_interface::MoveGroupInterface &move_group, const moveit_msgs::srv::GetCartesianPath::Request &key, const moveit_msgs::srv::GetCartesianPath::Response &value, std::string *reason=nullptr) override
Returns whether the insertion candidate should be inserted into the cache.
moveit::core::MoveItErrorCode appendInsertMetadata(warehouse_ros::Metadata &metadata, const moveit::planning_interface::MoveGroupInterface &move_group, const moveit_msgs::srv::GetCartesianPath::Request &key, const moveit_msgs::srv::GetCartesianPath::Response &value) override
Appends the insert metadata with the features supported by the policy.
std::vector< warehouse_ros::MessageWithMetadata< moveit_msgs::msg::RobotTrajectory >::ConstPtr > fetchMatchingEntries(const moveit::planning_interface::MoveGroupInterface &move_group, const warehouse_ros::MessageCollection< moveit_msgs::msg::RobotTrajectory > &coll, const moveit_msgs::srv::GetCartesianPath::Request &key, const moveit_msgs::srv::GetCartesianPath::Response &value, double exact_match_precision) override
Fetches all "matching" cache entries for comparison for pruning.
bool shouldPruneMatchingEntry(const moveit::planning_interface::MoveGroupInterface &move_group, const moveit_msgs::srv::GetCartesianPath::Request &key, const moveit_msgs::srv::GetCartesianPath::Response &value, const warehouse_ros::MessageWithMetadata< moveit_msgs::msg::RobotTrajectory >::ConstPtr &matching_entry, std::string *reason=nullptr) override
CartesianAlwaysInsertNeverPrunePolicy()
moveit::core::MoveItErrorCode checkCacheInsertInputs(const moveit::planning_interface::MoveGroupInterface &move_group, const warehouse_ros::MessageCollection< moveit_msgs::msg::RobotTrajectory > &coll, const moveit_msgs::srv::GetCartesianPath::Request &key, const moveit_msgs::srv::GetCartesianPath::Response &value) override
Checks inputs to the cache insert call to see if we should abort instead.
void reset() override
Resets the state of the policy.
User-specified constant features to key the trajectory cache on.
moveit_msgs::srv::GetCartesianPath::Request features to key the trajectory cache on.
moveit_msgs::msg::MotionPlanRequest features to key the trajectory cache on.
Utilities used by the trajectory_cache package.
std::string getWorkspaceFrameId(const moveit::planning_interface::MoveGroupInterface &move_group, const moveit_msgs::msg::WorkspaceParameters &workspace_parameters)
Gets workspace frame ID. If workspace_parameters has no frame ID, fetch it from move_group.
double getExecutionTime(const moveit_msgs::msg::RobotTrajectory &trajectory)
Returns the execution time of the trajectory in double seconds.
std::string getCartesianPathRequestFrameId(const moveit::planning_interface::MoveGroupInterface &move_group, const moveit_msgs::srv::GetCartesianPath::Request &path_request)
Gets cartesian path request frame ID. If path_request has no frame ID, fetch it from move_group.