Skip to content

Port of Regulated Pure Pursuit#69

Open
fmrico wants to merge 3 commits into
rollingfrom
pure_pursuit
Open

Port of Regulated Pure Pursuit#69
fmrico wants to merge 3 commits into
rollingfrom
pure_pursuit

Conversation

@fmrico

@fmrico fmrico commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Hi,

This PR contains a port of the Nav2 Regulated Pure Pursuit Controller to the EasyNav plugin architecture (easynav::ControllerMethodBase), including its optional
Dynamic Window Pure Pursuit (DWPP) extension.

  • S. Macenski, S. Singh, F. Martin, J. Gines, Regulated Pure Pursuit for Robot Path Tracking. Autonomous Robots, 2023.
  • Fumiya Ohnishi and Masaki Takahashi, DWPP: Dynamic Window Pure Pursuit Considering Velocity and Acceleration Constraints, arXiv:2601.15006, 2026.

Summary

  • Adds easynav_regulated_pp_controller, a new controller plugin under
    easynav_plugins/controllers: a port of Nav2's Regulated Pure Pursuit
    Controller to EasyNav's ControllerMethodBase / update_rt(NavState&) plugin design.
  • Includes the optional Dynamic Window Pure Pursuit (DWPP) extension
    for kinematically-feasible velocity/acceleration limited commands.
  • Ports all regulation heuristics: velocity-scaled lookahead distance,
    curvature-based slow-down, approach-to-goal slow-down, and
    rotate-to-rough-heading / rotate-to-goal-heading.

Adaptations vs. the Nav2 version

EasyNav has no costmap, no per-controller collision-arc checking, and no
separate goal-checker/TF-transform plugins, so:

  • Costmap-based velocity regulation is replaced by an equivalent term driven
    by the nearest point in the fused point-cloud perception
    (use_obstacle_regulated_linear_velocity_scaling).
  • Collision safety relies on the shared colision_checker.* logic already
    present in ControllerMethodBase, instead of duplicating an arc-based check.
  • Goal-reached checks use goal_tolerance.* from NavState (or fallback
    parameters), matching the convention used by other EasyNav controllers.
  • The path-to-robot-frame conversion is done analytically from the robot
    pose, since path and robot_pose already share a frame in EasyNav.
  • The carrot-point search explicitly starts from the path pose closest to
    the robot (findClosestPoseIndex), since EasyNav delivers the full,
    un-pruned global path rather than a plan already pruned to a local window
    around the robot.

Signed-off-by: Francisco Martín Rico <fmrico@gmail.com>
Copilot AI review requested due to automatic review settings July 16, 2026 07:59

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new EasyNav controller plugin implementing Nav2’s Regulated Pure Pursuit controller (including the optional Dynamic Window Pure Pursuit extension), adapted to EasyNav’s ControllerMethodBase / update_rt(NavState&) architecture and perception-based obstacle regulation.

Changes:

  • Introduces RegulatedPurePursuitController implementation + pluginlib registration for EasyNav.
  • Adds pure helper/heuristic headers for regulation terms and DWPP dynamic-window velocity selection.
  • Adds initial unit tests + README documenting algorithm, adaptations, parameters, and example config.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
controllers/easynav_regulated_pp_controller/CMakeLists.txt Builds/exports the new controller shared library and registers the plugin.
controllers/easynav_regulated_pp_controller/package.xml Declares package metadata and dependencies for the new controller plugin.
controllers/easynav_regulated_pp_controller/easynav_regulated_pp_controller_plugins.xml Pluginlib description for loading the controller via class name.
controllers/easynav_regulated_pp_controller/include/easynav_regulated_pp_controller/RegulatedPurePursuitController.hpp Public controller API, parameters, and helper method declarations.
controllers/easynav_regulated_pp_controller/src/easynav_regulated_pp_controller/RegulatedPurePursuitController.cpp Core control loop, lookahead/carrot logic, regulation, rotation behaviors, and DWPP integration.
controllers/easynav_regulated_pp_controller/include/easynav_regulated_pp_controller/regulation_functions.hpp Pure math heuristics for curvature/obstacle/approach velocity regulation.
controllers/easynav_regulated_pp_controller/include/easynav_regulated_pp_controller/dynamic_window_pure_pursuit_functions.hpp DWPP math utilities for dynamic-window computation and optimal (v, w) selection.
controllers/easynav_regulated_pp_controller/README.md Documentation of algorithm, adaptations from Nav2, parameters, and tuning notes.
controllers/easynav_regulated_pp_controller/tests/CMakeLists.txt Adds a gtest target for the new controller tests.
controllers/easynav_regulated_pp_controller/tests/regulated_pp_controller_tests.cpp Unit tests for heuristics, DWPP window logic, and controller geometry helpers.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +88 to +92
if (current_vel > Eps) {
// if the current velocity is positive, acceleration means an increase in speed
candidate_max_vel = current_vel + max_accel * dt;
candidate_min_vel = current_vel + max_decel * dt;
} else if (current_vel < -Eps) {
Comment on lines +288 to +296
const double min_feasible = last_angular_vel_ - max_angular_accel_ * dt;
const double max_feasible = last_angular_vel_ + max_angular_accel_ * dt;
angular_vel = std::clamp(angular_vel, min_feasible, max_feasible);

// Slow down to avoid overshooting the target angle.
const double max_vel_to_stop = std::sqrt(2.0 * max_angular_accel_ * std::fabs(angle_to_target));
if (std::fabs(angular_vel) > max_vel_to_stop) {
angular_vel = sign * max_vel_to_stop;
}
Comment on lines +253 to +257
int main(int argc, char ** argv)
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Comment on lines +161 to +165
- For Adaptive Pure Pursuit behavior, disable all boolean regulation parameters except
`use_velocity_scaled_lookahead_dist`, and tune `lookahead_time`, `min_lookahead_dist` and
`max_lookahead_dist`.
- For plain Pure Pursuit behavior, disable all boolean parameters and tune `lookahead_dist`.
- `use_obstacle_regulated_linear_velocity_scaling` can over-trigger in tightly cluttered
fmrico added 2 commits July 17, 2026 07:44
Signed-off-by: Francisco Martín Rico <fmrico@gmail.com>
Signed-off-by: Francisco Martín Rico <fmrico@gmail.com>
@Butakus

Butakus commented Jul 18, 2026

Copy link
Copy Markdown
Member

Hi @fmrico,

Your pure_pursuit branch is 4 commits behind rolling. It was created before fixing the CI and some errors related to get_package_share_directory deprecation.

Do you mind updating your branch so we can run the CI again?

BTW, the controller looks amazing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants