45 int start = include_edges ? 0 : 1;
46 unsigned int x_max = include_edges ? info.
width : info.
width - 1;
47 unsigned int y_max = include_edges ? info.
height : info.
height - 1;
48 nav_2d_msgs::Pose2DStamped pose;
49 pose.header.frame_id = info.
frame_id;
51 for (
unsigned int i =
start; i < x_max; i++)
53 for (
unsigned int j =
start; j < y_max; j++)
56 unsigned char cost = costmap(i, j);
59 free_cells.push_back(pose);
63 occupied_cells.push_back(pose);
72 double ox = costmap.getOriginX(), oy = costmap.getOriginY();
73 double res = costmap.getResolution();
74 double w = costmap.getWidth() * res, h = costmap.getHeight() * res;
75 double offset = 3.0 * res;
76 nav_2d_msgs::Pose2DStamped pose;
77 pose.header.frame_id = costmap.getFrameId();
78 pose.pose.x = ox - offset;
79 pose.pose.y = oy - offset;
80 poses.push_back(pose);
81 pose.pose.y = oy + h + offset;
82 poses.push_back(pose);
83 pose.pose.x = ox + w + offset;
84 poses.push_back(pose);
85 pose.pose.y = oy - offset;
86 poses.push_back(pose);
93 if (cells.size() == 0 || num_cells == 0)
98 if (cells.size() <= num_cells)
101 while (subset.size() < num_cells)
103 subset.push_back(cells[i++]);
104 if (i >= cells.size())
112 double inc = cells.size() /
static_cast<double>(num_cells);
114 while (subset.size() < num_cells)
116 subset.push_back(cells[
static_cast<int>(i)]);
138 bool verbose,
bool quit_early)
140 int passing_plans = 0, total_plans = 0;
141 for (nav_2d_msgs::Pose2DStamped start_pose : free_cells)
143 for (nav_2d_msgs::Pose2DStamped goal_pose : free_cells)
147 if (
planExists(planner, start_pose, goal_pose))
153 ROS_INFO(
"Failed to find a path between %.2f %.2f and %.2f %.2f",
154 start_pose.pose.x, start_pose.pose.y, goal_pose.pose.x, goal_pose.pose.y);
162 ROS_INFO(
"%d/%d valid plans found.", passing_plans, total_plans);
164 return passing_plans == total_plans;
169 const std::string& test_name,
170 bool check_exception_type,
bool verbose,
bool quit_early,
bool invalid_starts)
172 int passing_plans = 0, total_plans = 0;
174 for (nav_2d_msgs::Pose2DStamped start_pose : start_cells)
176 for (nav_2d_msgs::Pose2DStamped goal_pose : goal_cells)
182 planner.
makePlan(start_pose, goal_pose);
186 ROS_INFO(
"Found an unexpected valid %s path between %.2f %.2f and %.2f %.2f", test_name.c_str(),
187 start_pose.pose.x, start_pose.pose.y, goal_pose.pose.x, goal_pose.pose.y);
194 if (check_exception_type)
195 valid = invalid_starts;
199 if (check_exception_type)
200 valid = !invalid_starts;
204 valid = !check_exception_type;
212 ROS_INFO(
"An unexpected exception was thrown attempting a %s path between %.2f %.2f and %.2f %.2f",
213 test_name.c_str(), start_pose.pose.x, start_pose.pose.y, goal_pose.pose.x, goal_pose.pose.y);
220 ROS_INFO(
"%d/%d %s plans correctly aborted.", passing_plans, total_plans, test_name.c_str());
221 return passing_plans == total_plans;
226 const std::string& test_name,
227 bool check_exception_type,
bool verbose,
bool quit_early,
bool invalid_starts)
229 int passing_plans = 0, total_plans = 0;
231 for (nav_2d_msgs::Pose2DStamped start_pose : start_cells)
233 for (nav_2d_msgs::Pose2DStamped goal_pose : goal_cells)
239 planner.
makePlan(start_pose, goal_pose);
243 ROS_INFO(
"Found an unexpected valid %s path between %.2f %.2f and %.2f %.2f", test_name.c_str(),
244 start_pose.pose.x, start_pose.pose.y, goal_pose.pose.x, goal_pose.pose.y);
251 if (check_exception_type)
252 valid = invalid_starts;
256 if (check_exception_type)
257 valid = !invalid_starts;
261 valid = !check_exception_type;
269 ROS_INFO(
"An unexpected exception was thrown attempting a %s path between %.2f %.2f and %.2f %.2f",
270 test_name.c_str(), start_pose.pose.x, start_pose.pose.y, goal_pose.pose.x, goal_pose.pose.y);
277 ROS_INFO(
"%d/%d %s plans correctly aborted.", passing_plans, total_plans, test_name.c_str());
278 return passing_plans == total_plans;
283 bool check_exception_type,
bool verbose,
bool quit_early)
285 PoseList free_cells, occupied_cells;
286 groupCells(costmap, free_cells, occupied_cells);
289 if (!ret && quit_early)
293 if (max_failure_cases >= 0)
296 occupied_cells =
subsetPoseList(occupied_cells, max_failure_cases);
300 check_exception_type, verbose, quit_early,
false) && ret;
301 if (!ret && quit_early)
307 check_exception_type, verbose, quit_early,
true) && ret;
308 if (!ret && quit_early)
314 false, verbose, quit_early) && ret;
315 if (!ret && quit_early)
322 check_exception_type, verbose, quit_early,
false) && ret;
323 if (!ret && quit_early)
329 check_exception_type, verbose, quit_early,
true) && ret;
330 if (!ret && quit_early)
336 false, verbose, quit_early) && ret;
337 if (!ret && quit_early)
346 bool check_exception_type,
bool verbose,
bool quit_early)
348 PoseList free_cells, occupied_cells;
349 groupCells(costmap, free_cells, occupied_cells);
350 int passing_plans = 0, total_plans = 0;
352 unsigned int n = free_cells.size();
353 for (
unsigned int i = 0; i < n; i++)
355 for (
unsigned int j = 0; j < n; j++)
357 if (i == j)
continue;
362 planner.
makePlan(free_cells[i], free_cells[j]);
366 ROS_INFO(
"Found an unexpected valid path between %.2f %.2f and %.2f %.2f",
367 free_cells[i].pose.x, free_cells[i].pose.y, free_cells[j].pose.x, free_cells[j].pose.y);
378 valid = !check_exception_type;
386 ROS_INFO(
"An unexpected exception was thrown attempting to plan between %.2f %.2f and %.2f %.2f",
387 free_cells[i].pose.x, free_cells[i].pose.y, free_cells[j].pose.x, free_cells[j].pose.y);
394 ROS_INFO(
"%d/%d correctly aborted for having no path.", passing_plans, total_plans);
395 return passing_plans == total_plans;