39 #include <moveit/version.h>
40 #include <tf2_eigen/tf2_eigen.hpp>
45 #define BOOST_ALLOW_DEPRECATED_HEADERS
46 #include <boost/regex.hpp>
47 #include <boost/progress.hpp>
48 #undef BOOST_ALLOW_DEPRECATED_HEADERS
49 #include <boost/date_time/posix_time/posix_time.hpp>
63 static const rclcpp::Logger LOGGER = rclcpp::get_logger(
"moveit.ros.benchmarks.BenchmarkExecutor");
65 template <
class Clock,
class Duration>
66 boost::posix_time::ptime
toBoost(
const std::chrono::time_point<Clock, Duration>& from)
68 typedef std::chrono::nanoseconds duration_t;
70 rep_t
d = std::chrono::duration_cast<duration_t>(from.time_since_epoch()).count();
71 rep_t sec =
d / 1000000000;
72 rep_t nsec =
d % 1000000000;
73 namespace pt = boost::posix_time;
74 #ifdef BOOST_DATE_TIME_HAS_NANOSECONDS
75 return pt::from_time_t(sec) + pt::nanoseconds(nsec)
77 return pt::from_time_t(sec) + pt::microseconds(nsec / 1000);
81 static std::string getHostname()
83 static const int BUF_SIZE = 1024;
84 char buffer[BUF_SIZE];
85 int err = gethostname(buffer,
sizeof(buffer));
90 buffer[BUF_SIZE - 1] =
'\0';
91 return std::string(buffer);
96 : node_(node), dbloader(node)
122 std::string parent_node_name =
node_->get_name();
123 for (
const std::string& planning_pipeline_name : planning_pipeline_names)
126 static rclcpp::Node::SharedPtr child_node = rclcpp::Node::make_shared(planning_pipeline_name, parent_node_name);
128 planning_scene_->getRobotModel(), child_node,
"planning_plugin",
"request_adapters"));
131 if (!pipeline->getPlannerManager())
133 RCLCPP_ERROR(LOGGER,
"Failed to initialize planning pipeline '%s'", planning_pipeline_name.c_str());
138 pipeline->displayComputedMotionPlans(
false);
139 pipeline->checkSolutionPaths(
false);
145 RCLCPP_ERROR(LOGGER,
"No planning pipelines have been loaded. Nothing to do for the benchmarking service.");
148 RCLCPP_INFO(LOGGER,
"Available planning pipelines:");
149 for (
const std::pair<const std::string, planning_pipeline::PlanningPipelinePtr>& entry :
planning_pipelines_)
150 RCLCPP_INFO_STREAM(LOGGER,
"Pipeline: " << entry.first <<
", Planner: " << entry.second->getPlannerPluginName());
225 RCLCPP_ERROR(LOGGER,
"No planning pipelines configured. Did you call BenchmarkExecutor::initialize?");
229 std::vector<BenchmarkRequest> queries;
230 moveit_msgs::msg::PlanningScene scene_msg;
237 for (std::size_t i = 0; i < queries.size(); ++i)
240 if (scene_msg.robot_model_name !=
planning_scene_->getRobotModel()->getName())
256 RCLCPP_INFO(LOGGER,
"Benchmarking query '%s' (%lu of %lu)", queries[i].
name.c_str(), i + 1, queries.size());
257 std::chrono::system_clock::time_point start_time = std::chrono::system_clock::now();
259 std::chrono::duration<double> dt = std::chrono::system_clock::now() - start_time;
260 double duration = dt.count();
265 writeOutput(queries[i], boost::posix_time::to_iso_extended_string(
toBoost(start_time)), duration);
274 const std::map<std::string, std::vector<std::string>>& )
277 for (
const std::pair<const std::string, planning_pipeline::PlanningPipelinePtr>& pipeline_entry :
planning_pipelines_)
281 if (!pipeline_entry.second->getPlannerManager()->canServiceRequest(request.request))
283 RCLCPP_ERROR(LOGGER,
"Interface '%s' in pipeline '%s' cannot service the benchmark request '%s'",
284 pipeline_entry.second->getPlannerPluginName().c_str(), pipeline_entry.first.c_str(),
285 request.name.c_str());
295 std::vector<BenchmarkRequest>& requests)
300 std::vector<StartState> start_states;
302 std::vector<PathConstraints> goal_constraints;
303 std::vector<TrajectoryConstraints> traj_constraints;
304 std::vector<BenchmarkRequest> queries;
309 RCLCPP_ERROR(LOGGER,
"Failed to load benchmark query data");
315 "Benchmark loaded %lu starts, %lu goals, %lu path constraints, %lu trajectory constraints, and %lu queries",
316 start_states.size(), goal_constraints.size(),
path_constraints.size(), traj_constraints.size(), queries.size());
320 if (workspace_parameters.min_corner.x == workspace_parameters.max_corner.x &&
321 workspace_parameters.min_corner.x == 0.0 &&
322 workspace_parameters.min_corner.y == workspace_parameters.max_corner.y &&
323 workspace_parameters.min_corner.y == 0.0 &&
324 workspace_parameters.min_corner.z == workspace_parameters.max_corner.z &&
325 workspace_parameters.min_corner.z == 0.0)
327 workspace_parameters.min_corner.x = workspace_parameters.min_corner.y = workspace_parameters.min_corner.z = -5.0;
329 workspace_parameters.max_corner.x = workspace_parameters.max_corner.y = workspace_parameters.max_corner.z = 5.0;
332 std::vector<double> goal_offset;
343 brequest.
name = goal_constraint.name;
344 brequest.
request.workspace_parameters = workspace_parameters;
345 brequest.
request.goal_constraints = goal_constraint.constraints;
348 brequest.
request.num_planning_attempts = 1;
350 if (brequest.
request.goal_constraints.size() == 1 &&
351 brequest.
request.goal_constraints[0].position_constraints.size() == 1 &&
352 brequest.
request.goal_constraints[0].orientation_constraints.size() == 1 &&
353 brequest.
request.goal_constraints[0].visibility_constraints.empty() &&
354 brequest.
request.goal_constraints[0].joint_constraints.empty())
357 std::vector<BenchmarkRequest> request_combos;
359 requests.insert(requests.end(), request_combos.begin(), request_combos.end());
368 brequest.
name = query.name;
369 brequest.
request = query.request;
372 brequest.
request.num_planning_attempts = 1;
375 if (brequest.
request.workspace_parameters.min_corner.x == brequest.
request.workspace_parameters.max_corner.x &&
376 brequest.
request.workspace_parameters.min_corner.x == 0.0 &&
377 brequest.
request.workspace_parameters.min_corner.y == brequest.
request.workspace_parameters.max_corner.y &&
378 brequest.
request.workspace_parameters.min_corner.y == 0.0 &&
379 brequest.
request.workspace_parameters.min_corner.z == brequest.
request.workspace_parameters.max_corner.z &&
380 brequest.
request.workspace_parameters.min_corner.z == 0.0)
383 brequest.
request.workspace_parameters = workspace_parameters;
387 std::vector<BenchmarkRequest> request_combos;
389 requests.insert(requests.end(), request_combos.begin(), request_combos.end());
397 brequest.
name = traj_constraint.name;
398 brequest.
request.trajectory_constraints = traj_constraint.constraints;
401 brequest.
request.num_planning_attempts = 1;
403 if (brequest.
request.trajectory_constraints.constraints.size() == 1 &&
404 brequest.
request.trajectory_constraints.constraints[0].position_constraints.size() == 1 &&
405 brequest.
request.trajectory_constraints.constraints[0].orientation_constraints.size() == 1 &&
406 brequest.
request.trajectory_constraints.constraints[0].visibility_constraints.empty() &&
407 brequest.
request.trajectory_constraints.constraints[0].joint_constraints.empty())
410 std::vector<BenchmarkRequest> request_combos;
411 std::vector<PathConstraints> no_path_constraints;
413 requests.insert(requests.end(), request_combos.begin(), request_combos.end());
421 std::vector<StartState>& start_states,
423 std::vector<PathConstraints>& goal_constraints,
424 std::vector<TrajectoryConstraints>& traj_constraints,
425 std::vector<BenchmarkRequest>& queries)
429 warehouse_ros::DatabaseConnection::Ptr warehouse_connection =
dbloader.loadDatabase();
431 if (warehouse_connection->connect())
441 RCLCPP_ERROR(LOGGER,
"Failed to connect to DB");
445 catch (std::exception& e)
447 RCLCPP_ERROR(LOGGER,
"Failed to initialize benchmark server: '%s'", e.what());
460 const std::vector<double>& offset)
462 Eigen::Isometry3d offset_tf(Eigen::AngleAxis<double>(offset[3], Eigen::Vector3d::UnitX()) *
463 Eigen::AngleAxis<double>(offset[4], Eigen::Vector3d::UnitY()) *
464 Eigen::AngleAxis<double>(offset[5], Eigen::Vector3d::UnitZ()));
465 offset_tf.translation() =
Eigen::Vector3d(offset[0], offset[1], offset[2]);
467 geometry_msgs::msg::Pose constraint_pose_msg;
468 constraint_pose_msg.position = constraints.position_constraints[0].constraint_region.primitive_poses[0].position;
469 constraint_pose_msg.orientation = constraints.orientation_constraints[0].orientation;
470 Eigen::Isometry3d constraint_pose;
471 tf2::fromMsg(constraint_pose_msg, constraint_pose);
473 Eigen::Isometry3d new_pose = constraint_pose * offset_tf;
474 geometry_msgs::msg::Pose new_pose_msg;
475 new_pose_msg = tf2::toMsg(new_pose);
477 constraints.position_constraints[0].constraint_region.primitive_poses[0].position = new_pose_msg.position;
478 constraints.orientation_constraints[0].orientation = new_pose_msg.orientation;
482 const std::vector<StartState>& start_states,
484 std::vector<BenchmarkRequest>& requests)
487 if (start_states.empty())
493 new_brequest.
request.path_constraints = path_constraint.constraints[0];
494 new_brequest.
name = brequest.
name +
"_" + path_constraint.name;
495 requests.push_back(new_brequest);
499 requests.push_back(brequest);
503 for (
const StartState& start_state : start_states)
506 if (start_state.name == brequest.
name)
510 new_brequest.
request.start_state = start_state.state;
515 new_brequest.
request.path_constraints = path_constraint.constraints[0];
516 new_brequest.
name = start_state.name +
"_" + new_brequest.
name +
"_" + path_constraint.name;
517 requests.push_back(new_brequest);
522 new_brequest.
name = start_state.name +
"_" + brequest.
name;
523 requests.push_back(new_brequest);
530 const std::map<std::string, std::vector<std::string>>& pipeline_configurations,
const std::string& group_name)
533 for (
const std::pair<
const std::string, std::vector<std::string>>& pipeline_config_entry : pipeline_configurations)
535 bool pipeline_exists =
false;
536 for (
const std::pair<const std::string, planning_pipeline::PlanningPipelinePtr>& pipeline_entry :
539 pipeline_exists = pipeline_entry.first == pipeline_config_entry.first;
544 if (!pipeline_exists)
546 RCLCPP_ERROR(LOGGER,
"Planning pipeline '%s' does NOT exist", pipeline_config_entry.first.c_str());
552 for (
const std::pair<
const std::string, std::vector<std::string>>& entry : pipeline_configurations)
554 planning_interface::PlannerManagerPtr pm =
planning_pipelines_[entry.first]->getPlannerManager();
560 if (pm->getDescription().compare(
"stomp") || pm->getDescription().compare(
"chomp"))
563 for (std::size_t i = 0; i < entry.second.size(); ++i)
565 bool planner_exists =
false;
566 for (
const std::pair<const std::string, planning_interface::PlannerConfigurationSettings>& config_entry :
569 std::string planner_name = group_name +
"[" + entry.second[i] +
"]";
570 planner_exists = (config_entry.second.group == group_name && config_entry.second.name == planner_name);
575 RCLCPP_ERROR(LOGGER,
"Planner '%s' does NOT exist for group '%s' in pipeline '%s'", entry.second[i].c_str(),
576 group_name.c_str(), entry.first.c_str());
577 std::cout <<
"There are " << config_map.size() <<
" planner entries: " <<
'\n';
578 for (
const auto& config_map_entry : config_map)
579 std::cout << config_map_entry.second.name <<
'\n';
597 scene_msg =
static_cast<moveit_msgs::msg::PlanningScene
>(*pswm);
600 RCLCPP_ERROR(LOGGER,
"Failed to load planning scene '%s'", scene_name.c_str());
606 scene_msg.world =
static_cast<moveit_msgs::msg::PlanningSceneWorld
>(*pswwm);
607 scene_msg.robot_model_name =
608 "NO ROBOT INFORMATION. ONLY WORLD GEOMETRY";
611 RCLCPP_ERROR(LOGGER,
"Failed to load planning scene '%s'", scene_name.c_str());
614 RCLCPP_ERROR(LOGGER,
"Failed to find planning scene '%s'", scene_name.c_str());
616 catch (std::exception& ex)
618 RCLCPP_ERROR(LOGGER,
"Error loading planning scene: %s", ex.what());
620 RCLCPP_INFO(LOGGER,
"Loaded planning scene successfully");
625 std::vector<BenchmarkRequest>& queries)
630 std::vector<std::string> query_names;
635 catch (std::exception& ex)
637 RCLCPP_ERROR(LOGGER,
"Error loading motion planning queries: %s", ex.what());
641 if (query_names.empty())
643 RCLCPP_ERROR(LOGGER,
"Scene '%s' has no associated queries", scene_name.c_str());
647 for (
const std::string& query_name : query_names)
654 catch (std::exception& ex)
656 RCLCPP_ERROR(LOGGER,
"Error loading motion planning query '%s': %s", query_name.c_str(), ex.what());
661 query.
name = query_name;
663 queries.push_back(query);
665 RCLCPP_INFO(LOGGER,
"Loaded queries successfully");
673 std::regex start_regex(regex);
674 std::vector<std::string> state_names;
676 for (
const std::string& state_name : state_names)
679 if (std::regex_match(state_name, match, start_regex))
687 start_state.
state = moveit_msgs::msg::RobotState(*robot_state);
688 start_state.
name = state_name;
689 start_states.push_back(start_state);
692 catch (std::exception& ex)
694 RCLCPP_ERROR(LOGGER,
"Runtime error when loading state '%s': %s", state_name.c_str(), ex.what());
700 if (start_states.empty())
701 RCLCPP_WARN(LOGGER,
"No stored states matched the provided start state regex: '%s'", regex.c_str());
703 RCLCPP_INFO(LOGGER,
"Loaded states successfully");
711 std::vector<std::string> cnames;
714 for (
const std::string& cname : cnames)
723 constraint.
name = cname;
724 constraints.push_back(constraint);
727 catch (std::exception& ex)
729 RCLCPP_ERROR(LOGGER,
"Runtime error when loading path constraint '%s': %s", cname.c_str(), ex.what());
734 if (constraints.empty())
735 RCLCPP_WARN(LOGGER,
"No path constraints found that match regex: '%s'", regex.c_str());
737 RCLCPP_INFO(LOGGER,
"Loaded path constraints successfully");
743 std::vector<TrajectoryConstraints>& constraints)
747 std::vector<std::string> cnames;
750 for (
const std::string& cname : cnames)
759 constraint.
name = cname;
760 constraints.push_back(constraint);
763 catch (std::exception& ex)
765 RCLCPP_ERROR(LOGGER,
"Runtime error when loading trajectory constraint '%s': %s", cname.c_str(), ex.what());
770 if (constraints.empty())
771 RCLCPP_WARN(LOGGER,
"No trajectory constraints found that match regex: '%s'", regex.c_str());
773 RCLCPP_INFO(LOGGER,
"Loaded trajectory constraints successfully");
779 const std::map<std::string, std::vector<std::string>>& pipeline_map,
int runs)
783 unsigned int num_planners = 0;
784 for (
const std::pair<
const std::string, std::vector<std::string>>& pipeline_entry : pipeline_map)
785 num_planners += pipeline_entry.second.size();
787 boost::progress_display progress(num_planners * runs, std::cout);
790 for (
const std::pair<
const std::string, std::vector<std::string>>& pipeline_entry : pipeline_map)
796 for (
const std::string& planner_id : pipeline_entry.second)
801 std::vector<planning_interface::MotionPlanDetailedResponse> responses(runs);
802 std::vector<bool> solved(runs);
804 request.planner_id = planner_id;
808 planner_start_fn(request, planner_data);
810 planning_interface::PlanningContextPtr planning_context;
811 if (use_planning_context)
815 for (
int j = 0; j < runs; ++j)
819 pre_event_fn(request);
822 std::chrono::system_clock::time_point start = std::chrono::system_clock::now();
823 if (use_planning_context)
825 solved[j] = planning_context->solve(responses[j]);
835 responses[j].description_.push_back(
"plan");
836 responses[j].trajectory_.push_back(response.
trajectory_);
840 std::chrono::duration<double> dt = std::chrono::system_clock::now() - start;
841 double total_time = dt.count();
844 start = std::chrono::system_clock::now();
848 post_event_fn(request, responses[j], planner_data[j]);
849 collectMetrics(planner_data[j], responses[j], solved[j], total_time);
850 dt = std::chrono::system_clock::now() - start;
851 double metrics_time = dt.count();
852 RCLCPP_DEBUG(LOGGER,
"Spent %lf seconds collecting metrics", metrics_time);
861 planner_completion_fn(request, planner_data);
873 metrics[
"solved BOOLEAN"] = solved ?
"true" :
"false";
878 double traj_len = 0.0;
879 double clearance = 0.0;
882 double process_time = total_time;
883 for (std::size_t j = 0; j < mp_res.
trajectory_.size(); ++j)
895 for (std::size_t k = 0; k <
p.getWayPointCount(); ++k)
901 if (!
p.getWayPoint(k).satisfiesBounds())
907 clearance /= (double)
p.getWayPointCount();
912 return s.has_value() ? s.value() : 0.0;
915 metrics[
"path_" + mp_res.
description_[j] +
"_correct BOOLEAN"] = correct ?
"true" :
"false";
923 metrics[
"final_path_correct BOOLEAN"] = correct ?
"true" :
"false";
931 if (process_time <= 0.0)
938 PlannerBenchmarkData& planner_data,
const std::vector<planning_interface::MotionPlanDetailedResponse>& responses,
939 const std::vector<bool>& solved)
941 RCLCPP_INFO(LOGGER,
"Computing result path similarity");
942 const size_t result_count = planner_data.size();
943 size_t unsolved = std::count_if(solved.begin(), solved.end(), [](
bool s) { return !s; });
944 std::vector<double> average_distances(responses.size());
945 for (
size_t first_traj_i = 0; first_traj_i < result_count; ++first_traj_i)
948 if (!solved[first_traj_i])
950 average_distances[first_traj_i] = std::numeric_limits<double>::max();
954 for (
size_t second_traj_i = first_traj_i + 1; second_traj_i < result_count; ++second_traj_i)
957 if (!solved[second_traj_i])
965 double trajectory_distance;
970 average_distances[first_traj_i] += trajectory_distance;
971 average_distances[second_traj_i] += trajectory_distance;
974 average_distances[first_traj_i] /= result_count - unsolved - 1;
978 for (
size_t i = 0; i < result_count; ++i)
984 double& result_distance)
987 if (traj_first.
empty() || traj_second.
empty())
991 size_t pos_first = 0;
992 size_t pos_second = 0;
1002 double total_distance = 0;
1008 total_distance += current_distance;
1010 if (pos_first == max_pos_first && pos_second == max_pos_second)
1014 bool can_up_first = pos_first < max_pos_first;
1015 bool can_up_second = pos_second < max_pos_second;
1016 bool can_up_both = can_up_first && can_up_second;
1019 double up_both = std::numeric_limits<double>::max();
1020 double up_first = std::numeric_limits<double>::max();
1021 double up_second = std::numeric_limits<double>::max();
1030 if (can_up_both && up_both < up_first && up_both < up_second)
1034 current_distance = up_both;
1036 else if ((can_up_first && up_first < up_second) || !can_up_second)
1039 current_distance = up_first;
1041 else if (can_up_second)
1044 current_distance = up_second;
1048 result_distance = total_distance /
static_cast<double>(steps);
1053 double benchmark_duration)
1057 size_t num_planners = 0;
1058 for (
const std::pair<
const std::string, std::vector<std::string>>& pipeline : pipelines)
1059 num_planners += pipeline.second.size();
1061 std::string hostname = getHostname();
1062 if (hostname.empty())
1063 hostname =
"UNKNOWN";
1066 if (!filename.empty() && filename[filename.size() - 1] !=
'/')
1067 filename.append(
"/");
1070 std::filesystem::create_directories(filename);
1073 getHostname() +
"_" + start_time +
".log";
1074 std::ofstream out(filename.c_str());
1077 RCLCPP_ERROR(LOGGER,
"Failed to open '%s' for benchmark output", filename.c_str());
1081 out <<
"MoveIt version " << MOVEIT_VERSION_STR <<
'\n';
1082 out <<
"Experiment " << brequest.
name <<
'\n';
1083 out <<
"Running on " << hostname <<
'\n';
1084 out <<
"Starting at " << start_time <<
'\n';
1087 moveit_msgs::msg::PlanningScene scene_msg;
1089 out <<
"<<<|" <<
'\n';
1093 out <<
"Motion plan request:" <<
'\n'
1094 <<
" planner_id: " << brequest.
request.planner_id <<
'\n'
1095 <<
" group_name: " << brequest.
request.group_name <<
'\n'
1096 <<
" num_planning_attempts: " << brequest.
request.num_planning_attempts <<
'\n'
1097 <<
" allowed_planning_time: " << brequest.
request.allowed_planning_time <<
'\n';
1098 out <<
"Planning scene:" <<
'\n'
1099 <<
" scene_name: " << scene_msg.name <<
'\n'
1100 <<
" robot_model_name: " << scene_msg.robot_model_name <<
'\n'
1106 out <<
"0 is the random seed" <<
'\n';
1107 out << brequest.
request.allowed_planning_time <<
" seconds per run" <<
'\n';
1109 out <<
"-1 MB per run" <<
'\n';
1111 out << benchmark_duration <<
" seconds spent to collect the data" <<
'\n';
1114 out <<
"0 enum types" <<
'\n';
1116 out << num_planners <<
" planners" <<
'\n';
1119 for (
const std::pair<
const std::string, std::vector<std::string>>& pipeline : pipelines)
1121 for (std::size_t i = 0; i < pipeline.second.size(); ++i, ++run_id)
1124 out << pipeline.second[i] <<
" (" << pipeline.first <<
")" <<
'\n';
1128 out <<
"0 common properties" <<
'\n';
1131 std::set<std::string> properties_set;
1133 for (PlannerRunData::const_iterator pit = planner_run_data.begin(); pit != planner_run_data.end();
1135 properties_set.insert(pit->first);
1138 out << properties_set.size() <<
" properties for each run" <<
'\n';
1139 for (
const std::string& property : properties_set)
1140 out <<
property <<
'\n';
1149 for (
const std::string& property : properties_set)
1152 PlannerRunData::const_iterator runit = planner_run_data.find(property);
1153 if (runit != planner_run_data.end())
1154 out << runit->second;
1164 RCLCPP_INFO(LOGGER,
"Benchmark results saved to '%s'", filename.c_str());
boost::posix_time::ptime toBoost(const std::chrono::time_point< Clock, Duration > &from)
double distance(const RobotState &other) const
Return the sum of joint distances to "other" state. An L1 norm. Only considers active joints.
bool loadPlanningScene(const std::string &scene_name, moveit_msgs::msg::PlanningScene &scene_msg)
Load the planning scene with the given name from the warehouse.
void computeAveragePathSimilarities(PlannerBenchmarkData &planner_data, const std::vector< planning_interface::MotionPlanDetailedResponse > &responses, const std::vector< bool > &solved)
virtual bool runBenchmarks(const BenchmarkOptions &opts)
bool loadQueries(const std::string ®ex, const std::string &scene_name, std::vector< BenchmarkRequest > &queries)
Load all motion plan requests matching the given regular expression from the warehouse.
std::vector< PlannerRunData > PlannerBenchmarkData
Structure to hold information for a single planner's benchmark data.
virtual bool loadBenchmarkQueryData(const BenchmarkOptions &opts, moveit_msgs::msg::PlanningScene &scene_msg, std::vector< StartState > &start_states, std::vector< PathConstraints > &path_constraints, std::vector< PathConstraints > &goal_constraints, std::vector< TrajectoryConstraints > &traj_constraints, std::vector< BenchmarkRequest > &queries)
Initialize benchmark query data from start states and constraints.
void initialize(const std::vector< std::string > &plugin_classes)
rclcpp::Node::SharedPtr node_
planning_scene::PlanningScenePtr planning_scene_
moveit_warehouse::ConstraintsStorage * cs_
bool computeTrajectoryDistance(const robot_trajectory::RobotTrajectory &traj_first, const robot_trajectory::RobotTrajectory &traj_second, double &result_distance)
void addQueryStartEvent(const QueryStartEventFunction &func)
std::vector< PostRunEventFunction > post_event_fns_
std::vector< QueryCompletionEventFunction > query_end_fns_
moveit_warehouse::RobotStateStorage * rs_
bool plannerConfigurationsExist(const std::map< std::string, std::vector< std::string >> &planners, const std::string &group_name)
Check that the desired planner plugins and algorithms exist for the given group.
std::function< void(const moveit_msgs::msg::MotionPlanRequest &request, PlannerBenchmarkData &benchmark_data)> PlannerCompletionEventFunction
std::function< void(const moveit_msgs::msg::MotionPlanRequest &request, planning_scene::PlanningScenePtr)> QueryCompletionEventFunction
Definition of a query-end benchmark event function. Invoked after a query has finished benchmarking.
moveit_warehouse::PlanningSceneStorage * pss_
BenchmarkOptions options_
bool loadPathConstraints(const std::string ®ex, std::vector< PathConstraints > &constraints)
Load all constraints matching the given regular expression from the warehouse.
void addPreRunEvent(const PreRunEventFunction &func)
planning_scene_monitor::PlanningSceneMonitor * psm_
BenchmarkExecutor(const rclcpp::Node::SharedPtr &node, const std::string &robot_description_param="robot_description")
bool queriesAndPlannersCompatible(const std::vector< BenchmarkRequest > &requests, const std::map< std::string, std::vector< std::string >> &planners)
Check that the given requests can be run on the set of planner plugins and algorithms.
std::vector< PlannerBenchmarkData > benchmark_data_
virtual void collectMetrics(PlannerRunData &metrics, const planning_interface::MotionPlanDetailedResponse &mp_res, bool solved, double total_time)
std::map< std::string, planning_pipeline::PlanningPipelinePtr > planning_pipelines_
std::vector< QueryStartEventFunction > query_start_fns_
moveit_warehouse::TrajectoryConstraintsStorage * tcs_
void addPlannerCompletionEvent(const PlannerCompletionEventFunction &func)
void addPlannerStartEvent(const PlannerStartEventFunction &func)
void addQueryCompletionEvent(const QueryCompletionEventFunction &func)
bool loadStates(const std::string ®ex, std::vector< StartState > &start_states)
Load all states matching the given regular expression from the warehouse.
std::function< void(const moveit_msgs::msg::MotionPlanRequest &request, const planning_interface::MotionPlanDetailedResponse &response, PlannerRunData &run_data)> PostRunEventFunction
Definition of a post-run benchmark event function. Invoked immediately after each planner calls solve...
void runBenchmark(moveit_msgs::msg::MotionPlanRequest request, const std::map< std::string, std::vector< std::string >> &planners, int runs)
Execute the given motion plan request on the set of planners for the set number of runs.
std::function< void(moveit_msgs::msg::MotionPlanRequest &request)> PreRunEventFunction
Definition of a pre-run benchmark event function. Invoked immediately before each planner calls solve...
void createRequestCombinations(const BenchmarkRequest &brequest, const std::vector< StartState > &start_states, const std::vector< PathConstraints > &path_constraints, std::vector< BenchmarkRequest > &combos)
Duplicate the given benchmark request for all combinations of start states and path constraints.
moveit_warehouse::PlanningSceneWorldStorage * psws_
virtual void writeOutput(const BenchmarkRequest &brequest, const std::string &start_time, double benchmark_duration)
warehouse_ros::DatabaseLoader dbloader
std::vector< PlannerStartEventFunction > planner_start_fns_
virtual ~BenchmarkExecutor()
std::vector< PreRunEventFunction > pre_event_fns_
std::function< void(const moveit_msgs::msg::MotionPlanRequest &request, planning_scene::PlanningScenePtr)> QueryStartEventFunction
Definition of a query-start benchmark event function. Invoked before a new query is benchmarked.
virtual bool initializeBenchmarks(const BenchmarkOptions &opts, moveit_msgs::msg::PlanningScene &scene_msg, std::vector< BenchmarkRequest > &queries)
std::function< void(const moveit_msgs::msg::MotionPlanRequest &request, PlannerBenchmarkData &benchmark_data)> PlannerStartEventFunction
bool loadTrajectoryConstraints(const std::string ®ex, std::vector< TrajectoryConstraints > &constraints)
Load all trajectory constraints from the warehouse that match the given regular expression.
void addPostRunEvent(const PostRunEventFunction &func)
std::vector< PlannerCompletionEventFunction > planner_completion_fns_
void shiftConstraintsByOffset(moveit_msgs::msg::Constraints &constraints, const std::vector< double > &offset)
std::map< std::string, std::string > PlannerRunData
Structure to hold information for a single run of a planner.
const moveit_msgs::msg::WorkspaceParameters & getWorkspaceParameters() const
const std::string & getPathConstraintRegex() const
Get the regex expression for matching the names of all path constraints to plan with.
const std::map< std::string, std::vector< std::string > > & getPlanningPipelineConfigurations() const
Get all planning pipeline names mapped to their parameter configuration.
const std::string & getBenchmarkName() const
Get the reference name of the benchmark.
int getNumRuns() const
Get the specified number of benchmark query runs.
double getTimeout() const
Get the maximum timeout per planning attempt.
const std::string & getHostName() const
Set the ROS namespace the node handle should use for parameter lookup.
int getPort() const
Get the port of the warehouse database host server.
void getGoalOffsets(std::vector< double > &offsets) const
Get the constant position/orientation offset to be used for shifting all goal constraints.
const std::string & getQueryRegex() const
Get the regex expression for matching the names of all queries to run.
const std::string & getGroupName() const
Get the name of the planning group to run the benchmark with.
const std::string & getGoalConstraintRegex() const
Get the regex expression for matching the names of all goal constraints to plan to.
const std::string & getStartStateRegex() const
Get the regex expression for matching the names of all start states to plan from.
const std::string & getSceneName() const
Get the reference name of the planning scene stored inside the warehouse database.
const std::string & getOutputDirectory() const
Get the target directory for the generated benchmark result data.
const std::string & getTrajectoryConstraintRegex() const
Get the regex expression for matching the names of all trajectory constraints to plan with.
bool getConstraints(ConstraintsWithMetadata &msg_m, const std::string &name, const std::string &robot="", const std::string &group="") const
Get the constraints named name. Return false on failure.
void getKnownConstraints(std::vector< std::string > &names, const std::string &robot="", const std::string &group="") const
bool getPlanningQuery(MotionPlanRequestWithMetadata &query_m, const std::string &scene_name, const std::string &query_name)
void getPlanningQueriesNames(std::vector< std::string > &query_names, const std::string &scene_name) const
bool hasPlanningScene(const std::string &name) const
bool getPlanningScene(PlanningSceneWithMetadata &scene_m, const std::string &scene_name) const
Get the latest planning scene named scene_name.
bool hasPlanningSceneWorld(const std::string &name) const
bool getPlanningSceneWorld(PlanningSceneWorldWithMetadata &msg_m, const std::string &name) const
Get the constraints named name. Return false on failure.
void getKnownRobotStates(std::vector< std::string > &names, const std::string &robot="") const
bool getRobotState(RobotStateWithMetadata &msg_m, const std::string &name, const std::string &robot="") const
Get the constraints named name. Return false on failure.
void getKnownTrajectoryConstraints(std::vector< std::string > &names, const std::string &robot="", const std::string &group="") const
bool getTrajectoryConstraints(TrajectoryConstraintsWithMetadata &msg_m, const std::string &name, const std::string &robot="", const std::string &group="") const
Get the constraints named name. Return false on failure.
This class facilitates loading planning plugins and planning request adapted plugins....
PlanningSceneMonitor Subscribes to the topic planning_scene.
const planning_scene::PlanningScenePtr & getPlanningScene()
Avoid this function! Returns an unsafe pointer to the current planning scene.
Maintain a sequence of waypoints and the time durations between these waypoints.
std::size_t getWayPointCount() const
const moveit::core::RobotState & getWayPoint(std::size_t index) const
locale-agnostic conversion functions from floating point numbers to strings
Vec3fX< details::Vec3Data< double > > Vector3d
std::string toString(double d)
Convert a double to std::string using the classic C locale.
warehouse_ros::MessageWithMetadata< moveit_msgs::msg::RobotState >::ConstPtr RobotStateWithMetadata
warehouse_ros::MessageWithMetadata< moveit_msgs::msg::PlanningScene >::ConstPtr PlanningSceneWithMetadata
warehouse_ros::MessageWithMetadata< moveit_msgs::msg::TrajectoryConstraints >::ConstPtr TrajectoryConstraintsWithMetadata
warehouse_ros::MessageWithMetadata< moveit_msgs::msg::PlanningSceneWorld >::ConstPtr PlanningSceneWorldWithMetadata
warehouse_ros::MessageWithMetadata< moveit_msgs::msg::MotionPlanRequest >::ConstPtr MotionPlanRequestWithMetadata
warehouse_ros::MessageWithMetadata< moveit_msgs::msg::Constraints >::ConstPtr ConstraintsWithMetadata
std::map< std::string, PlannerConfigurationSettings > PlannerConfigurationMap
Map from PlannerConfigurationSettings.name to PlannerConfigurationSettings.
moveit_msgs::msg::MotionPlanRequest MotionPlanRequest
double path_length(RobotTrajectory const &trajectory)
Calculate the path length of a given trajectory based on the accumulated robot state distances....
std::optional< double > smoothness(RobotTrajectory const &trajectory)
Calculate the smoothness of a given trajectory.
Representation of a collision checking request.
Representation of a collision checking result.
bool collision
True if collision was found, false otherwise.
moveit_msgs::msg::MotionPlanRequest request
std::vector< moveit_msgs::msg::Constraints > constraints
moveit_msgs::msg::RobotState state
moveit_msgs::msg::TrajectoryConstraints constraints
std::vector< robot_trajectory::RobotTrajectoryPtr > trajectory_
std::vector< double > processing_time_
std::vector< std::string > description_
robot_trajectory::RobotTrajectoryPtr trajectory_
moveit_msgs::msg::MoveItErrorCodes error_code_