moveit2
The MoveIt Motion Planning Framework for ROS 2.
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 
38 #include <moveit/utils/logger.hpp>
39 
40 using moveit::getLogger;
41 using namespace moveit_ros_benchmarks;
42 
43 namespace
44 {
45 rclcpp::Logger getLogger()
46 {
47  return moveit::getLogger("moveit.benchmarks.options");
48 }
49 } // namespace
50 
51 BenchmarkOptions::BenchmarkOptions(const rclcpp::Node::SharedPtr& node)
52 {
53  if (!readBenchmarkOptions(node))
54  {
55  throw(std::runtime_error("Failed to initialize BenchmarkOptions"));
56  }
57 }
58 
59 bool 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 
163 void 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 
172 bool 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