Skip to content

Commit 0e52d90

Browse files
The smac planner max_planning_time parameter can timeout the A* planning stage (#2586)
- Until now the max_planning_time parameter only had an effect on the smoothing and sampling stages of the planner, so the actual A* planning could possibly take a lot longer
1 parent 0513db1 commit 0e52d90

File tree

5 files changed

+34
-4
lines changed

5 files changed

+34
-4
lines changed

‎nav2_smac_planner/include/nav2_smac_planner/a_star.hpp‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,14 @@ class AStarAlgorithm
105105
* @param max_on_approach_iterations Maximum number of iterations before returning a valid
106106
* path once within thresholds to refine path
107107
* comes at more compute time but smoother paths.
108+
* @param max_planning_time Maximum time (in seconds) to wait for a plan, createPath returns
109+
* false after this timeout
108110
*/
109111
void initialize(
110112
const bool & allow_unknown,
111113
int & max_iterations,
112114
const int & max_on_approach_iterations,
115+
const double & max_planning_time,
113116
const float & lookup_table_size,
114117
const unsigned int & dim_3_size);
115118

@@ -283,9 +286,12 @@ class AStarAlgorithm
283286
*/
284287
NodePtr setAnalyticPath(const NodePtr & node, const AnalyticExpansionNodes & expanded_nodes);
285288

289+
int _timing_interval = 5000;
290+
286291
bool _traverse_unknown;
287292
int _max_iterations;
288293
int _max_on_approach_iterations;
294+
double _max_planning_time;
289295
float _tolerance;
290296
unsigned int _x_size;
291297
unsigned int _y_size;

‎nav2_smac_planner/src/a_star.cpp‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ AStarAlgorithm<NodeT>::AStarAlgorithm(
4242
const SearchInfo & search_info)
4343
: _traverse_unknown(true),
4444
_max_iterations(0),
45+
_max_planning_time(0),
4546
_x_size(0),
4647
_y_size(0),
4748
_search_info(search_info),
@@ -63,12 +64,14 @@ void AStarAlgorithm<NodeT>::initialize(
6364
const bool & allow_unknown,
6465
int & max_iterations,
6566
const int & max_on_approach_iterations,
67+
const double & max_planning_time,
6668
const float & lookup_table_size,
6769
const unsigned int & dim_3_size)
6870
{
6971
_traverse_unknown = allow_unknown;
7072
_max_iterations = max_iterations;
7173
_max_on_approach_iterations = max_on_approach_iterations;
74+
_max_planning_time = max_planning_time;
7275
NodeT::precomputeDistanceHeuristic(lookup_table_size, _motion_model, dim_3_size, _search_info);
7376
_dim3_size = dim_3_size;
7477
}
@@ -78,12 +81,14 @@ void AStarAlgorithm<Node2D>::initialize(
7881
const bool & allow_unknown,
7982
int & max_iterations,
8083
const int & max_on_approach_iterations,
84+
const double & max_planning_time,
8185
const float & /*lookup_table_size*/,
8286
const unsigned int & dim_3_size)
8387
{
8488
_traverse_unknown = allow_unknown;
8589
_max_iterations = max_iterations;
8690
_max_on_approach_iterations = max_on_approach_iterations;
91+
_max_planning_time = max_planning_time;
8792

8893
if (dim_3_size != 1) {
8994
throw std::runtime_error("Node type Node2D cannot be given non-1 dim 3 quantization.");
@@ -211,6 +216,7 @@ bool AStarAlgorithm<NodeT>::createPath(
211216
CoordinateVector & path, int & iterations,
212217
const float & tolerance)
213218
{
219+
steady_clock::time_point start_time = steady_clock::now();
214220
_tolerance = tolerance;
215221
_best_heuristic_node = {std::numeric_limits<float>::max(), 0};
216222
clearQueue();
@@ -248,6 +254,15 @@ bool AStarAlgorithm<NodeT>::createPath(
248254
};
249255

250256
while (iterations < getMaxIterations() && !_queue.empty()) {
257+
// Check for planning timeout only on every Nth iteration
258+
if (iterations % _timing_interval == 0) {
259+
std::chrono::duration<double> planning_duration =
260+
std::chrono::duration_cast<std::chrono::duration<double>>(steady_clock::now() - start_time);
261+
if (static_cast<double>(planning_duration.count()) >= _max_planning_time) {
262+
return false;
263+
}
264+
}
265+
251266
// 1) Pick Nbest from O s.t. min(f(Nbest)), remove from queue
252267
current_node = getNextNode();
253268

‎nav2_smac_planner/src/smac_planner_2d.cpp‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ void SmacPlanner2D::configure(
128128
_allow_unknown,
129129
_max_iterations,
130130
_max_on_approach_iterations,
131+
_max_planning_time,
131132
0.0 /*unused for 2D*/,
132133
1.0 /*unused for 2D*/);
133134

@@ -355,6 +356,7 @@ SmacPlanner2D::dynamicParametersCallback(std::vector<rclcpp::Parameter> paramete
355356
reinit_a_star = true;
356357
_search_info.cost_penalty = parameter.as_double();
357358
} else if (name == _name + ".max_planning_time") {
359+
reinit_a_star = true;
358360
_max_planning_time = parameter.as_double();
359361
}
360362
} else if (type == ParameterType::PARAMETER_BOOL) {
@@ -414,6 +416,7 @@ SmacPlanner2D::dynamicParametersCallback(std::vector<rclcpp::Parameter> paramete
414416
_allow_unknown,
415417
_max_iterations,
416418
_max_on_approach_iterations,
419+
_max_planning_time,
417420
0.0 /*unused for 2D*/,
418421
1.0 /*unused for 2D*/);
419422
}

‎nav2_smac_planner/src/smac_planner_hybrid.cpp‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ void SmacPlannerHybrid::configure(
164164
_allow_unknown,
165165
_max_iterations,
166166
std::numeric_limits<int>::max(),
167+
_max_planning_time,
167168
_lookup_table_dim,
168169
_angle_quantizations);
169170

@@ -375,6 +376,7 @@ void SmacPlannerHybrid::on_parameter_event_callback(
375376

376377
if (type == ParameterType::PARAMETER_DOUBLE) {
377378
if (name == _name + ".max_planning_time") {
379+
reinit_a_star = true;
378380
_max_planning_time = value.double_value;
379381
} else if (name == _name + ".lookup_table_size") {
380382
reinit_a_star = true;
@@ -475,6 +477,7 @@ void SmacPlannerHybrid::on_parameter_event_callback(
475477
_allow_unknown,
476478
_max_iterations,
477479
std::numeric_limits<int>::max(),
480+
_max_planning_time,
478481
_lookup_table_dim,
479482
_angle_quantizations);
480483
}

‎nav2_smac_planner/test/test_a_star.cpp‎

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,10 @@ TEST(AStarTest, test_a_star_2d)
4343
float tolerance = 0.0;
4444
float some_tolerance = 20.0;
4545
int it_on_approach = 10;
46+
double max_planning_time = 120.0;
4647
int num_it = 0;
4748

48-
a_star.initialize(false, max_iterations, it_on_approach, 0.0, 1);
49+
a_star.initialize(false, max_iterations, it_on_approach, max_planning_time, 0.0, 1);
4950

5051
nav2_costmap_2d::Costmap2D * costmapA =
5152
new nav2_costmap_2d::Costmap2D(100, 100, 0.1, 0.0, 0.0, 0);
@@ -81,7 +82,7 @@ TEST(AStarTest, test_a_star_2d)
8182
// failure cases with invalid inputs
8283
nav2_smac_planner::AStarAlgorithm<nav2_smac_planner::Node2D> a_star_2(
8384
nav2_smac_planner::MotionModel::VON_NEUMANN, info);
84-
a_star_2.initialize(false, max_iterations, it_on_approach, 0, 1);
85+
a_star_2.initialize(false, max_iterations, it_on_approach, max_planning_time, 0, 1);
8586
num_it = 0;
8687
EXPECT_THROW(a_star_2.createPath(path, num_it, tolerance), std::runtime_error);
8788
a_star_2.setCollisionChecker(checker.get());
@@ -130,9 +131,10 @@ TEST(AStarTest, test_a_star_se2)
130131
int max_iterations = 10000;
131132
float tolerance = 10.0;
132133
int it_on_approach = 10;
134+
double max_planning_time = 120.0;
133135
int num_it = 0;
134136

135-
a_star.initialize(false, max_iterations, it_on_approach, 401, size_theta);
137+
a_star.initialize(false, max_iterations, it_on_approach, max_planning_time, 401, size_theta);
136138

137139
nav2_costmap_2d::Costmap2D * costmapA =
138140
new nav2_costmap_2d::Costmap2D(100, 100, 0.1, 0.0, 0.0, 0);
@@ -178,9 +180,10 @@ TEST(AStarTest, test_se2_single_pose_path)
178180
int max_iterations = 100;
179181
float tolerance = 10.0;
180182
int it_on_approach = 10;
183+
double max_planning_time = 120.0;
181184
int num_it = 0;
182185

183-
a_star.initialize(false, max_iterations, it_on_approach, 401, size_theta);
186+
a_star.initialize(false, max_iterations, it_on_approach, max_planning_time, 401, size_theta);
184187

185188
nav2_costmap_2d::Costmap2D * costmapA =
186189
new nav2_costmap_2d::Costmap2D(100, 100, 0.1, 0.0, 0.0, 0);

0 commit comments

Comments
 (0)