moveit2
The MoveIt Motion Planning Framework for ROS 2.
Loading...
Searching...
No Matches
BenchmarkOptions.cpp
Go to the documentation of this file.
1/*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2015, Rice University
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 the Rice University 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/* Author: Ryan Luna */
36
39
41using namespace moveit_ros_benchmarks;
42
43namespace
44{
45rclcpp::Logger getLogger()
46{
47 return moveit::getLogger("moveit.benchmarks.options");
48}
49} // namespace
50
51BenchmarkOptions::BenchmarkOptions(const rclcpp::Node::SharedPtr& node)
52{
53 if (!readBenchmarkOptions(node))
54 {
55 throw(std::runtime_error("Failed to initialize BenchmarkOptions"));
56 }
57}
58
59bool BenchmarkOptions::readBenchmarkOptions(const rclcpp::Node::SharedPtr& node)
60{
61 if (node->has_parameter("benchmark_config.parameters.name"))
62 {
63 // Read warehouse options
64 node->get_parameter_or(std::string("benchmark_config.warehouse.host"), hostname, std::string("127.0.0.1"));
65 node->get_parameter_or(std::string("benchmark_config.warehouse.port"), port, 33829);
66
67 if (!node->get_parameter("benchmark_config.warehouse.scene_name", scene_name))
68 {
69 RCLCPP_WARN(getLogger(), "Benchmark scene_name NOT specified");
70 }
71
72 RCLCPP_INFO(getLogger(), "Benchmark host: %s", hostname.c_str());
73 RCLCPP_INFO(getLogger(), "Benchmark port: %d", port);
74 RCLCPP_INFO(getLogger(), "Benchmark scene: %s", scene_name.c_str());
75 // Read benchmark parameters
76 node->get_parameter_or(std::string("benchmark_config.parameters.name"), benchmark_name, std::string(""));
77 node->get_parameter_or(std::string("benchmark_config.parameters.runs"), runs, 10);
78 node->get_parameter_or(std::string("benchmark_config.parameters.timeout"), timeout, 10.0);
79 node->get_parameter_or(std::string("benchmark_config.parameters.output_directory"), output_directory,
80 std::string(""));
81 node->get_parameter_or(std::string("benchmark_config.parameters.queries_regex"), query_regex, std::string(".*"));
82 node->get_parameter_or(std::string("benchmark_config.parameters.start_states_regex"), start_state_regex,
83 std::string(""));
84 node->get_parameter_or(std::string("benchmark_config.parameters.goal_constraints_regex"), goal_constraint_regex,
85 std::string(""));
86 node->get_parameter_or(std::string("benchmark_config.parameters.path_constraints_regex"), path_constraint_regex,
87 std::string(""));
88 node->get_parameter_or(std::string("benchmark_config.parameters.trajectory_constraints_regex"),
89 trajectory_constraint_regex, std::string(""));
90 node->get_parameter_or(std::string("benchmark_config.parameters.predefined_poses"), predefined_poses, {});
91 node->get_parameter_or(std::string("benchmark_config.parameters.predefined_poses_group"), predefined_poses_group,
92 std::string(""));
93
94 if (!node->get_parameter(std::string("benchmark_config.parameters.group"), group_name))
95 {
96 RCLCPP_WARN(getLogger(), "Benchmark group NOT specified");
97 }
98
99 if (node->has_parameter("benchmark_config.parameters.workspace"))
100 {
101 // Read workspace parameters
102 // Make sure all params exist
103 if (!node->get_parameter("benchmark_config.parameters.workspace.frame_id", workspace.header.frame_id))
104 {
105 RCLCPP_WARN(getLogger(), "Workspace frame_id not specified in benchmark config");
106 }
107
108 node->get_parameter_or(std::string("benchmark_config.parameters.workspace.min_corner.x"), workspace.min_corner.x,
109 0.0);
110 node->get_parameter_or(std::string("benchmark_config.parameters.workspace.min_corner.y"), workspace.min_corner.y,
111 0.0);
112 node->get_parameter_or(std::string("benchmark_config.parameters.workspace.min_corner.z"), workspace.min_corner.z,
113 0.0);
114
115 node->get_parameter_or(std::string("benchmark_config.parameters.workspace.max_corner.x"), workspace.max_corner.x,
116 0.0);
117 node->get_parameter_or(std::string("benchmark_config.parameters.workspace.max_corner.y"), workspace.max_corner.y,
118 0.0);
119 node->get_parameter_or(std::string("benchmark_config.parameters.workspace.max_corner.z"), workspace.max_corner.z,
120 0.0);
121
122 workspace.header.stamp = rclcpp::Clock().now();
123 }
124
125 // Reading in goal_offset (or defaulting to zero)
126 node->get_parameter_or(std::string("benchmark_config.parameters.goal_offset.x"), goal_offsets.at(0), 0.0);
127 node->get_parameter_or(std::string("benchmark_config.parameters.goal_offset.y"), goal_offsets.at(1), 0.0);
128 node->get_parameter_or(std::string("benchmark_config.parameters.goal_offset.z"), goal_offsets.at(2), 0.0);
129 node->get_parameter_or(std::string("benchmark_config.parameters.goal_offset.roll"), goal_offsets.at(3), 0.0);
130 node->get_parameter_or(std::string("benchmark_config.parameters.goal_offset.pitch"), goal_offsets.at(4), 0.0);
131 node->get_parameter_or(std::string("benchmark_config.parameters.goal_offset.yaw"), goal_offsets.at(5), 0.0);
132
133 RCLCPP_INFO(getLogger(), "Benchmark name: '%s'", benchmark_name.c_str());
134 RCLCPP_INFO(getLogger(), "Benchmark #runs: %d", runs);
135 RCLCPP_INFO(getLogger(), "Benchmark timeout: %f secs", timeout);
136 RCLCPP_INFO(getLogger(), "Benchmark group: %s", group_name.c_str());
137 RCLCPP_INFO(getLogger(), "Benchmark query regex: '%s'", query_regex.c_str());
138 RCLCPP_INFO(getLogger(), "Benchmark start state regex: '%s':", start_state_regex.c_str());
139 RCLCPP_INFO(getLogger(), "Benchmark goal constraint regex: '%s':", goal_constraint_regex.c_str());
140 RCLCPP_INFO(getLogger(), "Benchmark path constraint regex: '%s':", path_constraint_regex.c_str());
141 RCLCPP_INFO(getLogger(), "Benchmark goal offsets (%f %f %f, %f %f %f)", goal_offsets.at(0), goal_offsets.at(1),
142 goal_offsets.at(2), goal_offsets.at(3), goal_offsets.at(4), goal_offsets.at(5));
143 RCLCPP_INFO(getLogger(), "Benchmark output directory: %s", output_directory.c_str());
144 RCLCPP_INFO_STREAM(getLogger(), "Benchmark workspace: min_corner: ["
145 << workspace.min_corner.x << ", " << workspace.min_corner.y << ", "
146 << workspace.min_corner.z << "], "
147 << "max_corner: [" << workspace.max_corner.x << ", " << workspace.max_corner.y
148 << ", " << workspace.max_corner.z << ']');
149 // Read planner configuration
150 if (!readPlannerConfigs(node))
151 {
152 return false;
153 }
154 }
155 else
156 {
157 RCLCPP_ERROR(getLogger(), "No benchmark_config found on param server");
158 return false;
159 }
160 return true;
161}
162
163void BenchmarkOptions::getPlanningPipelineNames(std::vector<std::string>& planning_pipeline_names) const
164{
165 planning_pipeline_names.clear();
166 for (const std::pair<const std::string, std::vector<std::string>>& planning_pipeline : planning_pipelines)
167 {
168 planning_pipeline_names.push_back(planning_pipeline.first);
169 }
170}
171
172bool BenchmarkOptions::readPlannerConfigs(const rclcpp::Node::SharedPtr& node)
173{
174 const std::string ns = "benchmark_config.planning_pipelines";
175 // pipelines
176 planning_pipelines.clear();
177
178 std::vector<std::string> pipelines;
179 if (!node->get_parameter(ns + ".pipelines", pipelines))
180 {
181 RCLCPP_WARN(getLogger(), "No single planning pipeline namespace `%s` configured.", (ns + ".pipelines").c_str());
182 }
183
184 for (const std::string& pipeline : pipelines)
185 {
186 if (!pipeline.empty())
187 {
188 std::string pipeline_name;
189 const std::string pipeline_parameter_name = std::string(ns).append(".").append(pipeline).append(".name");
190 if (!node->get_parameter(pipeline_parameter_name, pipeline_name))
191 {
192 RCLCPP_ERROR(getLogger(), "Fail to get the parameter in `%s` namespace.", pipeline_parameter_name.c_str());
193 return false;
194 }
195
196 RCLCPP_INFO(getLogger(), "Reading in planner names for planning pipeline '%s'", pipeline_name.c_str());
197
198 std::vector<std::string> planners;
199 const std::string pipeline_parameter_planners = std::string(ns).append(".").append(pipeline).append(".planners");
200 if (!node->get_parameter(pipeline_parameter_planners, planners))
201 {
202 RCLCPP_ERROR(getLogger(), "Fail to get the parameter in `%s` namespace.", pipeline_parameter_planners.c_str());
203 return false;
204 }
205
206 for (const std::string& planner : planners)
207 {
208 RCLCPP_INFO(getLogger(), " %s", planner.c_str());
209 }
210
211 planning_pipelines[pipeline_name] = planners;
212 }
213 }
214 // parallel pipelines
216
217 std::vector<std::string> parallel_pipelines;
218 if (!node->get_parameter(ns + ".parallel_pipelines", parallel_pipelines))
219 {
220 RCLCPP_WARN(getLogger(), "No parallel planning pipeline namespace `%s` configured.",
221 (ns + ".parallel_pipelines").c_str());
222 }
223
224 for (const std::string& parallel_pipeline : parallel_pipelines)
225 {
226 if (!parallel_pipeline.empty())
227 { // Read pipelines
228 RCLCPP_INFO(getLogger(), "Reading in parameters for parallel planning pipeline '%s'", parallel_pipeline.c_str());
229
230 // Read pipelines
231 std::vector<std::string> pipelines;
232 const std::string pipelines_parameter =
233 std::string(ns).append(".").append(parallel_pipeline).append(".pipelines");
234 if (!node->get_parameter(pipelines_parameter, pipelines))
235 {
236 RCLCPP_ERROR(getLogger(), "Fail to get the parameter in `%s` namespace.", pipelines_parameter.c_str());
237 return false;
238 }
239
240 // Read planner_ids
241 std::vector<std::string> planner_ids;
242 const std::string pipeline_planner_ids_parameter =
243 std::string(ns).append(".").append(parallel_pipeline).append(".planner_ids");
244 if (!node->get_parameter(pipeline_planner_ids_parameter, planner_ids))
245 {
246 RCLCPP_ERROR(getLogger(), "Fail to get the parameter in `%s` namespace.",
247 pipeline_planner_ids_parameter.c_str());
248 return false;
249 }
250
251 if (pipelines.size() != planner_ids.size())
252 {
253 RCLCPP_ERROR(getLogger(), "Number of planner ids is unequal to the number of pipelines in %s.",
254 parallel_pipeline.c_str());
255 return false;
256 }
257
258 std::vector<std::pair<std::string, std::string>> pipeline_planner_id_pairs;
259 for (size_t i = 0; i < pipelines.size(); ++i)
260 {
261 pipeline_planner_id_pairs.push_back(std::pair<std::string, std::string>(pipelines.at(i), planner_ids.at(i)));
262 }
263
264 parallel_planning_pipelines[parallel_pipeline] = pipeline_planner_id_pairs;
265
266 for (const auto& entry : parallel_planning_pipelines)
267 {
268 RCLCPP_INFO(getLogger(), "Parallel planning pipeline '%s'", entry.first.c_str());
269 for (const auto& pair : entry.second)
270 {
271 RCLCPP_INFO(getLogger(), " '%s': '%s'", pair.first.c_str(), pair.second.c_str());
272 }
273 }
274 }
275 }
276 if (pipelines.empty() && parallel_pipelines.empty())
277 {
278 RCLCPP_ERROR(getLogger(), "No single or parallel planning pipelines configured for benchmarking.");
279 return false;
280 }
281 return true;
282}
rclcpp::Logger getLogger(const std::string &name)
Creates a namespaced logger.
Definition logger.cpp:79
BenchmarkOptions(const rclcpp::Node::SharedPtr &node)
Constructor.
std::map< std::string, std::vector< std::string > > planning_pipelines
planner configurations
moveit_msgs::msg::WorkspaceParameters workspace
std::map< std::string, std::vector< std::pair< std::string, std::string > > > parallel_planning_pipelines
void getPlanningPipelineNames(std::vector< std::string > &planning_pipeline_names) const
Get all planning pipeline names.
bool readBenchmarkOptions(const rclcpp::Node::SharedPtr &node)
std::string hostname
Warehouse parameters.
bool readPlannerConfigs(const rclcpp::Node::SharedPtr &node)
std::vector< std::string > predefined_poses