Package Summary
| Version | 0.1.0 |
| License | Apache 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | |
| Checkout URI | https://github.com/WATonomous/wato_monorepo.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-15 |
| Dev Status | DEVELOPED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- WATonomous
Authors
Ackermann Pure Pursuit
ROS2 lifecycle node that tracks a trajectory using the pure pursuit algorithm, publishing Ackermann drive commands for vehicle steering and speed control.
Overview
The pure pursuit node receives a planned trajectory, transforms each waypoint into the vehicle’s rear-axle reference frame (once per cycle), selects a lookahead point, and computes the steering angle and speed via the pure pursuit geometric algorithm. The lookahead distance is adapted to speed and path curvature, speed is limited by a lateral-acceleration budget, and the steering/speed commands are rate-limited for smoothness. Each cycle it measures cross-track and heading error and, if either exceeds a tunable threshold for a sustained window, raises a disengage recommendation in its ControllerStatus telemetry. This is advisory only: the controller keeps tracking normally and does not alter its command, yield the mux, or talk to the OSCC layer — acting on the recommendation is left to a higher-level supervisor. It publishes an idle signal and standby Ackermann commands when no valid trajectory is available, the trajectory has gone stale, or the behaviour tree requests standby.
Current Status: Adaptive pure pursuit controller with rear-axle geometry, TF-based wheelbase measurement, model-aware variable lookahead, curvature/accel-limited speed control, command-rate limiting, an optional low-speed Stanley cross-track blend, a debounced disengage monitor, and live-reconfigurable parameters.
ROS Interface
Subscribed Topics
| Topic | Type | Description |
|---|---|---|
trajectory |
wato_trajectory_msgs/Trajectory |
Planned trajectory from the freeroam planner |
execute_behaviour |
behaviour_msgs/ExecuteBehaviour |
Requested behaviour from the behaviour tree |
Published Topics
| Topic | Type | Description |
|---|---|---|
/action/ackermann |
ackermann_msgs/AckermannDriveStamped |
Steering angle and speed command |
/action/is_idle |
std_msgs/Bool |
true when idle or in standby (the disengage monitor does not raise this) |
controller_status |
wato_trajectory_msgs/ControllerStatus |
Per-cycle tracking error, effective lookahead, path curvature, commands, and disengage state/reason |
Also subscribes to odom (nav_msgs/Odometry) for the current longitudinal speed used by the adaptive lookahead and speed scheduling.
Configuration
Parameters are loaded from config/params.yaml under the namespace action/pure_pursuit_node/ros__parameters.
Parameters are read once in on_configure. To change them at runtime, transition the lifecycle node back through cleanup → configure (which reloads config/params.yaml), as with the other action nodes.
Topics / frames
| Parameter | Type | Default | Description |
|---|---|---|---|
controller_status_topic |
string | "controller_status" |
Topic for the ControllerStatus telemetry |
base_frame |
string | "base_footprint" |
Frame stamped on published Ackermann commands |
rear_axle_frame |
string | "rear_axle" |
Frame the pure-pursuit geometry and tracking error are computed in; also one end of the TF wheelbase measurement |
front_axle_frame |
string | "front_axle" |
Other end of the TF wheelbase measurement |
standby_msg |
string | "standby" |
Behaviour string that triggers standby output |
Adaptive lookahead
| Parameter | Type | Default | Description |
|---|---|---|---|
lookahead_distance |
double | 5.0 |
Maximum lookahead distance (m) |
min_lookahead_distance |
double | 2.0 |
Minimum lookahead distance (m) |
lookahead_time |
double | 1.5 |
Time-headway: ld = lookahead_time · speed, clamped to min/max (s) |
curvature_lookahead_gain |
double | 2.0 |
Shrinks lookahead in curves: ld_eff = ld / (1 + gain·|κ|)
|
speed_lookahead_distance |
double | 1.0 |
Minimum distance ahead used to sample target speed (m) |
speed_lookahead_time |
double | 2.0 |
Time-headway for the (decoupled, longer) speed sample horizon (s) |
Steering & speed
| Parameter | Type | Default | Description |
|---|---|---|---|
steering_angle_gain |
double | 1.0 |
Gain on the pure-pursuit steering output |
max_steering_angle |
double | 0.5 |
Maximum steering magnitude (rad) |
max_steering_rate |
double | 1.0 |
Steering slew-rate limit (rad/s) |
max_speed / min_speed
|
double |
5.0 / 0.0
|
Commanded speed bounds while tracking (m/s) |
max_lateral_accel |
double | 2.5 |
Cornering-speed budget: v ≤ sqrt(a_lat/|κ|) (m/s²) |
max_accel / max_decel
|
double |
1.5 / 3.0
|
Command accel/decel slew limits (m/s²) |
Low-speed cross-track blend (Stanley)
| Parameter | Type | Default | Description |
|---|---|---|---|
enable_stanley_blend |
bool | false |
Blend a cross-track feedback term into steering at low speed |
stanley_gain |
double | 0.5 |
Cross-track feedback gain k_e
|
stanley_softening |
double | 1.0 |
Softening constant k_soft (avoids blow-up near zero speed) |
stanley_speed_threshold |
double | 2.0 |
Blend weight ramps from 1 (at 0) to 0 at this speed (m/s) |
Disengage monitor
| Parameter | Type | Default | Description |
|---|---|---|---|
enable_disengage |
bool | true |
Enable the tracking-threshold disengage monitor |
max_cross_track_error |
double | 1.5 |
Cross-track error that (sustained) trips a disengage (m) |
max_heading_error |
double | 0.6 |
Heading error that (sustained) trips a disengage (rad) |
disengage_debounce_sec |
double | 0.5 |
How long the error must be exceeded before tripping (s) |
disengage_latch |
bool | false |
true = stay disengaged until reconfigured; false = auto-recover |
disengage_speed |
double | 0.0 |
Safe speed commanded when no valid lookahead point exists (m/s) |
Standby / misc
| Parameter | Type | Default | Description |
|---|---|---|---|
standby_speed |
double | -0.5 |
Speed commanded during standby (m/s) |
standby_steering |
double | 0.0 |
Steering commanded during standby (rad) |
control_rate_hz |
double | 20.0 |
Control publish rate (Hz) |
wheelbase_fallback |
double | 2.5667 |
Fallback wheelbase if the TF lookup fails (m) |
idle_timeout_sec |
double | 2.0 |
Time since last trajectory before declaring idle (s) |
invert_steering |
bool | true |
Invert steering sign — true means positive angle = clockwise |
disable_standby |
bool | false |
Bypass standby and track even when standby_msg is received |
Algorithm Details
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| wato_test | |
| rclcpp | |
| rclcpp_lifecycle | |
| behaviour_msgs | |
| geometry_msgs | |
| nav_msgs | |
| std_msgs | |
| ackermann_msgs | |
| tf2 | |
| tf2_ros | |
| tf2_geometry_msgs | |
| wato_trajectory_msgs |
System Dependencies
Dependant Packages
| Name | Deps |
|---|---|
| action_bringup |
Launch files
Messages
Services
Plugins
Recent questions tagged ackermann_pure_pursuit at Robotics Stack Exchange
Package Summary
| Version | 0.1.0 |
| License | Apache 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | |
| Checkout URI | https://github.com/WATonomous/wato_monorepo.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-15 |
| Dev Status | DEVELOPED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- WATonomous
Authors
Ackermann Pure Pursuit
ROS2 lifecycle node that tracks a trajectory using the pure pursuit algorithm, publishing Ackermann drive commands for vehicle steering and speed control.
Overview
The pure pursuit node receives a planned trajectory, transforms each waypoint into the vehicle’s rear-axle reference frame (once per cycle), selects a lookahead point, and computes the steering angle and speed via the pure pursuit geometric algorithm. The lookahead distance is adapted to speed and path curvature, speed is limited by a lateral-acceleration budget, and the steering/speed commands are rate-limited for smoothness. Each cycle it measures cross-track and heading error and, if either exceeds a tunable threshold for a sustained window, raises a disengage recommendation in its ControllerStatus telemetry. This is advisory only: the controller keeps tracking normally and does not alter its command, yield the mux, or talk to the OSCC layer — acting on the recommendation is left to a higher-level supervisor. It publishes an idle signal and standby Ackermann commands when no valid trajectory is available, the trajectory has gone stale, or the behaviour tree requests standby.
Current Status: Adaptive pure pursuit controller with rear-axle geometry, TF-based wheelbase measurement, model-aware variable lookahead, curvature/accel-limited speed control, command-rate limiting, an optional low-speed Stanley cross-track blend, a debounced disengage monitor, and live-reconfigurable parameters.
ROS Interface
Subscribed Topics
| Topic | Type | Description |
|---|---|---|
trajectory |
wato_trajectory_msgs/Trajectory |
Planned trajectory from the freeroam planner |
execute_behaviour |
behaviour_msgs/ExecuteBehaviour |
Requested behaviour from the behaviour tree |
Published Topics
| Topic | Type | Description |
|---|---|---|
/action/ackermann |
ackermann_msgs/AckermannDriveStamped |
Steering angle and speed command |
/action/is_idle |
std_msgs/Bool |
true when idle or in standby (the disengage monitor does not raise this) |
controller_status |
wato_trajectory_msgs/ControllerStatus |
Per-cycle tracking error, effective lookahead, path curvature, commands, and disengage state/reason |
Also subscribes to odom (nav_msgs/Odometry) for the current longitudinal speed used by the adaptive lookahead and speed scheduling.
Configuration
Parameters are loaded from config/params.yaml under the namespace action/pure_pursuit_node/ros__parameters.
Parameters are read once in on_configure. To change them at runtime, transition the lifecycle node back through cleanup → configure (which reloads config/params.yaml), as with the other action nodes.
Topics / frames
| Parameter | Type | Default | Description |
|---|---|---|---|
controller_status_topic |
string | "controller_status" |
Topic for the ControllerStatus telemetry |
base_frame |
string | "base_footprint" |
Frame stamped on published Ackermann commands |
rear_axle_frame |
string | "rear_axle" |
Frame the pure-pursuit geometry and tracking error are computed in; also one end of the TF wheelbase measurement |
front_axle_frame |
string | "front_axle" |
Other end of the TF wheelbase measurement |
standby_msg |
string | "standby" |
Behaviour string that triggers standby output |
Adaptive lookahead
| Parameter | Type | Default | Description |
|---|---|---|---|
lookahead_distance |
double | 5.0 |
Maximum lookahead distance (m) |
min_lookahead_distance |
double | 2.0 |
Minimum lookahead distance (m) |
lookahead_time |
double | 1.5 |
Time-headway: ld = lookahead_time · speed, clamped to min/max (s) |
curvature_lookahead_gain |
double | 2.0 |
Shrinks lookahead in curves: ld_eff = ld / (1 + gain·|κ|)
|
speed_lookahead_distance |
double | 1.0 |
Minimum distance ahead used to sample target speed (m) |
speed_lookahead_time |
double | 2.0 |
Time-headway for the (decoupled, longer) speed sample horizon (s) |
Steering & speed
| Parameter | Type | Default | Description |
|---|---|---|---|
steering_angle_gain |
double | 1.0 |
Gain on the pure-pursuit steering output |
max_steering_angle |
double | 0.5 |
Maximum steering magnitude (rad) |
max_steering_rate |
double | 1.0 |
Steering slew-rate limit (rad/s) |
max_speed / min_speed
|
double |
5.0 / 0.0
|
Commanded speed bounds while tracking (m/s) |
max_lateral_accel |
double | 2.5 |
Cornering-speed budget: v ≤ sqrt(a_lat/|κ|) (m/s²) |
max_accel / max_decel
|
double |
1.5 / 3.0
|
Command accel/decel slew limits (m/s²) |
Low-speed cross-track blend (Stanley)
| Parameter | Type | Default | Description |
|---|---|---|---|
enable_stanley_blend |
bool | false |
Blend a cross-track feedback term into steering at low speed |
stanley_gain |
double | 0.5 |
Cross-track feedback gain k_e
|
stanley_softening |
double | 1.0 |
Softening constant k_soft (avoids blow-up near zero speed) |
stanley_speed_threshold |
double | 2.0 |
Blend weight ramps from 1 (at 0) to 0 at this speed (m/s) |
Disengage monitor
| Parameter | Type | Default | Description |
|---|---|---|---|
enable_disengage |
bool | true |
Enable the tracking-threshold disengage monitor |
max_cross_track_error |
double | 1.5 |
Cross-track error that (sustained) trips a disengage (m) |
max_heading_error |
double | 0.6 |
Heading error that (sustained) trips a disengage (rad) |
disengage_debounce_sec |
double | 0.5 |
How long the error must be exceeded before tripping (s) |
disengage_latch |
bool | false |
true = stay disengaged until reconfigured; false = auto-recover |
disengage_speed |
double | 0.0 |
Safe speed commanded when no valid lookahead point exists (m/s) |
Standby / misc
| Parameter | Type | Default | Description |
|---|---|---|---|
standby_speed |
double | -0.5 |
Speed commanded during standby (m/s) |
standby_steering |
double | 0.0 |
Steering commanded during standby (rad) |
control_rate_hz |
double | 20.0 |
Control publish rate (Hz) |
wheelbase_fallback |
double | 2.5667 |
Fallback wheelbase if the TF lookup fails (m) |
idle_timeout_sec |
double | 2.0 |
Time since last trajectory before declaring idle (s) |
invert_steering |
bool | true |
Invert steering sign — true means positive angle = clockwise |
disable_standby |
bool | false |
Bypass standby and track even when standby_msg is received |
Algorithm Details
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| wato_test | |
| rclcpp | |
| rclcpp_lifecycle | |
| behaviour_msgs | |
| geometry_msgs | |
| nav_msgs | |
| std_msgs | |
| ackermann_msgs | |
| tf2 | |
| tf2_ros | |
| tf2_geometry_msgs | |
| wato_trajectory_msgs |
System Dependencies
Dependant Packages
| Name | Deps |
|---|---|
| action_bringup |
Launch files
Messages
Services
Plugins
Recent questions tagged ackermann_pure_pursuit at Robotics Stack Exchange
Package Summary
| Version | 0.1.0 |
| License | Apache 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | |
| Checkout URI | https://github.com/WATonomous/wato_monorepo.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-15 |
| Dev Status | DEVELOPED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- WATonomous
Authors
Ackermann Pure Pursuit
ROS2 lifecycle node that tracks a trajectory using the pure pursuit algorithm, publishing Ackermann drive commands for vehicle steering and speed control.
Overview
The pure pursuit node receives a planned trajectory, transforms each waypoint into the vehicle’s rear-axle reference frame (once per cycle), selects a lookahead point, and computes the steering angle and speed via the pure pursuit geometric algorithm. The lookahead distance is adapted to speed and path curvature, speed is limited by a lateral-acceleration budget, and the steering/speed commands are rate-limited for smoothness. Each cycle it measures cross-track and heading error and, if either exceeds a tunable threshold for a sustained window, raises a disengage recommendation in its ControllerStatus telemetry. This is advisory only: the controller keeps tracking normally and does not alter its command, yield the mux, or talk to the OSCC layer — acting on the recommendation is left to a higher-level supervisor. It publishes an idle signal and standby Ackermann commands when no valid trajectory is available, the trajectory has gone stale, or the behaviour tree requests standby.
Current Status: Adaptive pure pursuit controller with rear-axle geometry, TF-based wheelbase measurement, model-aware variable lookahead, curvature/accel-limited speed control, command-rate limiting, an optional low-speed Stanley cross-track blend, a debounced disengage monitor, and live-reconfigurable parameters.
ROS Interface
Subscribed Topics
| Topic | Type | Description |
|---|---|---|
trajectory |
wato_trajectory_msgs/Trajectory |
Planned trajectory from the freeroam planner |
execute_behaviour |
behaviour_msgs/ExecuteBehaviour |
Requested behaviour from the behaviour tree |
Published Topics
| Topic | Type | Description |
|---|---|---|
/action/ackermann |
ackermann_msgs/AckermannDriveStamped |
Steering angle and speed command |
/action/is_idle |
std_msgs/Bool |
true when idle or in standby (the disengage monitor does not raise this) |
controller_status |
wato_trajectory_msgs/ControllerStatus |
Per-cycle tracking error, effective lookahead, path curvature, commands, and disengage state/reason |
Also subscribes to odom (nav_msgs/Odometry) for the current longitudinal speed used by the adaptive lookahead and speed scheduling.
Configuration
Parameters are loaded from config/params.yaml under the namespace action/pure_pursuit_node/ros__parameters.
Parameters are read once in on_configure. To change them at runtime, transition the lifecycle node back through cleanup → configure (which reloads config/params.yaml), as with the other action nodes.
Topics / frames
| Parameter | Type | Default | Description |
|---|---|---|---|
controller_status_topic |
string | "controller_status" |
Topic for the ControllerStatus telemetry |
base_frame |
string | "base_footprint" |
Frame stamped on published Ackermann commands |
rear_axle_frame |
string | "rear_axle" |
Frame the pure-pursuit geometry and tracking error are computed in; also one end of the TF wheelbase measurement |
front_axle_frame |
string | "front_axle" |
Other end of the TF wheelbase measurement |
standby_msg |
string | "standby" |
Behaviour string that triggers standby output |
Adaptive lookahead
| Parameter | Type | Default | Description |
|---|---|---|---|
lookahead_distance |
double | 5.0 |
Maximum lookahead distance (m) |
min_lookahead_distance |
double | 2.0 |
Minimum lookahead distance (m) |
lookahead_time |
double | 1.5 |
Time-headway: ld = lookahead_time · speed, clamped to min/max (s) |
curvature_lookahead_gain |
double | 2.0 |
Shrinks lookahead in curves: ld_eff = ld / (1 + gain·|κ|)
|
speed_lookahead_distance |
double | 1.0 |
Minimum distance ahead used to sample target speed (m) |
speed_lookahead_time |
double | 2.0 |
Time-headway for the (decoupled, longer) speed sample horizon (s) |
Steering & speed
| Parameter | Type | Default | Description |
|---|---|---|---|
steering_angle_gain |
double | 1.0 |
Gain on the pure-pursuit steering output |
max_steering_angle |
double | 0.5 |
Maximum steering magnitude (rad) |
max_steering_rate |
double | 1.0 |
Steering slew-rate limit (rad/s) |
max_speed / min_speed
|
double |
5.0 / 0.0
|
Commanded speed bounds while tracking (m/s) |
max_lateral_accel |
double | 2.5 |
Cornering-speed budget: v ≤ sqrt(a_lat/|κ|) (m/s²) |
max_accel / max_decel
|
double |
1.5 / 3.0
|
Command accel/decel slew limits (m/s²) |
Low-speed cross-track blend (Stanley)
| Parameter | Type | Default | Description |
|---|---|---|---|
enable_stanley_blend |
bool | false |
Blend a cross-track feedback term into steering at low speed |
stanley_gain |
double | 0.5 |
Cross-track feedback gain k_e
|
stanley_softening |
double | 1.0 |
Softening constant k_soft (avoids blow-up near zero speed) |
stanley_speed_threshold |
double | 2.0 |
Blend weight ramps from 1 (at 0) to 0 at this speed (m/s) |
Disengage monitor
| Parameter | Type | Default | Description |
|---|---|---|---|
enable_disengage |
bool | true |
Enable the tracking-threshold disengage monitor |
max_cross_track_error |
double | 1.5 |
Cross-track error that (sustained) trips a disengage (m) |
max_heading_error |
double | 0.6 |
Heading error that (sustained) trips a disengage (rad) |
disengage_debounce_sec |
double | 0.5 |
How long the error must be exceeded before tripping (s) |
disengage_latch |
bool | false |
true = stay disengaged until reconfigured; false = auto-recover |
disengage_speed |
double | 0.0 |
Safe speed commanded when no valid lookahead point exists (m/s) |
Standby / misc
| Parameter | Type | Default | Description |
|---|---|---|---|
standby_speed |
double | -0.5 |
Speed commanded during standby (m/s) |
standby_steering |
double | 0.0 |
Steering commanded during standby (rad) |
control_rate_hz |
double | 20.0 |
Control publish rate (Hz) |
wheelbase_fallback |
double | 2.5667 |
Fallback wheelbase if the TF lookup fails (m) |
idle_timeout_sec |
double | 2.0 |
Time since last trajectory before declaring idle (s) |
invert_steering |
bool | true |
Invert steering sign — true means positive angle = clockwise |
disable_standby |
bool | false |
Bypass standby and track even when standby_msg is received |
Algorithm Details
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| wato_test | |
| rclcpp | |
| rclcpp_lifecycle | |
| behaviour_msgs | |
| geometry_msgs | |
| nav_msgs | |
| std_msgs | |
| ackermann_msgs | |
| tf2 | |
| tf2_ros | |
| tf2_geometry_msgs | |
| wato_trajectory_msgs |
System Dependencies
Dependant Packages
| Name | Deps |
|---|---|
| action_bringup |
Launch files
Messages
Services
Plugins
Recent questions tagged ackermann_pure_pursuit at Robotics Stack Exchange
Package Summary
| Version | 0.1.0 |
| License | Apache 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | |
| Checkout URI | https://github.com/WATonomous/wato_monorepo.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-15 |
| Dev Status | DEVELOPED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- WATonomous
Authors
Ackermann Pure Pursuit
ROS2 lifecycle node that tracks a trajectory using the pure pursuit algorithm, publishing Ackermann drive commands for vehicle steering and speed control.
Overview
The pure pursuit node receives a planned trajectory, transforms each waypoint into the vehicle’s rear-axle reference frame (once per cycle), selects a lookahead point, and computes the steering angle and speed via the pure pursuit geometric algorithm. The lookahead distance is adapted to speed and path curvature, speed is limited by a lateral-acceleration budget, and the steering/speed commands are rate-limited for smoothness. Each cycle it measures cross-track and heading error and, if either exceeds a tunable threshold for a sustained window, raises a disengage recommendation in its ControllerStatus telemetry. This is advisory only: the controller keeps tracking normally and does not alter its command, yield the mux, or talk to the OSCC layer — acting on the recommendation is left to a higher-level supervisor. It publishes an idle signal and standby Ackermann commands when no valid trajectory is available, the trajectory has gone stale, or the behaviour tree requests standby.
Current Status: Adaptive pure pursuit controller with rear-axle geometry, TF-based wheelbase measurement, model-aware variable lookahead, curvature/accel-limited speed control, command-rate limiting, an optional low-speed Stanley cross-track blend, a debounced disengage monitor, and live-reconfigurable parameters.
ROS Interface
Subscribed Topics
| Topic | Type | Description |
|---|---|---|
trajectory |
wato_trajectory_msgs/Trajectory |
Planned trajectory from the freeroam planner |
execute_behaviour |
behaviour_msgs/ExecuteBehaviour |
Requested behaviour from the behaviour tree |
Published Topics
| Topic | Type | Description |
|---|---|---|
/action/ackermann |
ackermann_msgs/AckermannDriveStamped |
Steering angle and speed command |
/action/is_idle |
std_msgs/Bool |
true when idle or in standby (the disengage monitor does not raise this) |
controller_status |
wato_trajectory_msgs/ControllerStatus |
Per-cycle tracking error, effective lookahead, path curvature, commands, and disengage state/reason |
Also subscribes to odom (nav_msgs/Odometry) for the current longitudinal speed used by the adaptive lookahead and speed scheduling.
Configuration
Parameters are loaded from config/params.yaml under the namespace action/pure_pursuit_node/ros__parameters.
Parameters are read once in on_configure. To change them at runtime, transition the lifecycle node back through cleanup → configure (which reloads config/params.yaml), as with the other action nodes.
Topics / frames
| Parameter | Type | Default | Description |
|---|---|---|---|
controller_status_topic |
string | "controller_status" |
Topic for the ControllerStatus telemetry |
base_frame |
string | "base_footprint" |
Frame stamped on published Ackermann commands |
rear_axle_frame |
string | "rear_axle" |
Frame the pure-pursuit geometry and tracking error are computed in; also one end of the TF wheelbase measurement |
front_axle_frame |
string | "front_axle" |
Other end of the TF wheelbase measurement |
standby_msg |
string | "standby" |
Behaviour string that triggers standby output |
Adaptive lookahead
| Parameter | Type | Default | Description |
|---|---|---|---|
lookahead_distance |
double | 5.0 |
Maximum lookahead distance (m) |
min_lookahead_distance |
double | 2.0 |
Minimum lookahead distance (m) |
lookahead_time |
double | 1.5 |
Time-headway: ld = lookahead_time · speed, clamped to min/max (s) |
curvature_lookahead_gain |
double | 2.0 |
Shrinks lookahead in curves: ld_eff = ld / (1 + gain·|κ|)
|
speed_lookahead_distance |
double | 1.0 |
Minimum distance ahead used to sample target speed (m) |
speed_lookahead_time |
double | 2.0 |
Time-headway for the (decoupled, longer) speed sample horizon (s) |
Steering & speed
| Parameter | Type | Default | Description |
|---|---|---|---|
steering_angle_gain |
double | 1.0 |
Gain on the pure-pursuit steering output |
max_steering_angle |
double | 0.5 |
Maximum steering magnitude (rad) |
max_steering_rate |
double | 1.0 |
Steering slew-rate limit (rad/s) |
max_speed / min_speed
|
double |
5.0 / 0.0
|
Commanded speed bounds while tracking (m/s) |
max_lateral_accel |
double | 2.5 |
Cornering-speed budget: v ≤ sqrt(a_lat/|κ|) (m/s²) |
max_accel / max_decel
|
double |
1.5 / 3.0
|
Command accel/decel slew limits (m/s²) |
Low-speed cross-track blend (Stanley)
| Parameter | Type | Default | Description |
|---|---|---|---|
enable_stanley_blend |
bool | false |
Blend a cross-track feedback term into steering at low speed |
stanley_gain |
double | 0.5 |
Cross-track feedback gain k_e
|
stanley_softening |
double | 1.0 |
Softening constant k_soft (avoids blow-up near zero speed) |
stanley_speed_threshold |
double | 2.0 |
Blend weight ramps from 1 (at 0) to 0 at this speed (m/s) |
Disengage monitor
| Parameter | Type | Default | Description |
|---|---|---|---|
enable_disengage |
bool | true |
Enable the tracking-threshold disengage monitor |
max_cross_track_error |
double | 1.5 |
Cross-track error that (sustained) trips a disengage (m) |
max_heading_error |
double | 0.6 |
Heading error that (sustained) trips a disengage (rad) |
disengage_debounce_sec |
double | 0.5 |
How long the error must be exceeded before tripping (s) |
disengage_latch |
bool | false |
true = stay disengaged until reconfigured; false = auto-recover |
disengage_speed |
double | 0.0 |
Safe speed commanded when no valid lookahead point exists (m/s) |
Standby / misc
| Parameter | Type | Default | Description |
|---|---|---|---|
standby_speed |
double | -0.5 |
Speed commanded during standby (m/s) |
standby_steering |
double | 0.0 |
Steering commanded during standby (rad) |
control_rate_hz |
double | 20.0 |
Control publish rate (Hz) |
wheelbase_fallback |
double | 2.5667 |
Fallback wheelbase if the TF lookup fails (m) |
idle_timeout_sec |
double | 2.0 |
Time since last trajectory before declaring idle (s) |
invert_steering |
bool | true |
Invert steering sign — true means positive angle = clockwise |
disable_standby |
bool | false |
Bypass standby and track even when standby_msg is received |
Algorithm Details
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| wato_test | |
| rclcpp | |
| rclcpp_lifecycle | |
| behaviour_msgs | |
| geometry_msgs | |
| nav_msgs | |
| std_msgs | |
| ackermann_msgs | |
| tf2 | |
| tf2_ros | |
| tf2_geometry_msgs | |
| wato_trajectory_msgs |
System Dependencies
Dependant Packages
| Name | Deps |
|---|---|
| action_bringup |
Launch files
Messages
Services
Plugins
Recent questions tagged ackermann_pure_pursuit at Robotics Stack Exchange
Package Summary
| Version | 0.1.0 |
| License | Apache 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | |
| Checkout URI | https://github.com/WATonomous/wato_monorepo.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-15 |
| Dev Status | DEVELOPED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- WATonomous
Authors
Ackermann Pure Pursuit
ROS2 lifecycle node that tracks a trajectory using the pure pursuit algorithm, publishing Ackermann drive commands for vehicle steering and speed control.
Overview
The pure pursuit node receives a planned trajectory, transforms each waypoint into the vehicle’s rear-axle reference frame (once per cycle), selects a lookahead point, and computes the steering angle and speed via the pure pursuit geometric algorithm. The lookahead distance is adapted to speed and path curvature, speed is limited by a lateral-acceleration budget, and the steering/speed commands are rate-limited for smoothness. Each cycle it measures cross-track and heading error and, if either exceeds a tunable threshold for a sustained window, raises a disengage recommendation in its ControllerStatus telemetry. This is advisory only: the controller keeps tracking normally and does not alter its command, yield the mux, or talk to the OSCC layer — acting on the recommendation is left to a higher-level supervisor. It publishes an idle signal and standby Ackermann commands when no valid trajectory is available, the trajectory has gone stale, or the behaviour tree requests standby.
Current Status: Adaptive pure pursuit controller with rear-axle geometry, TF-based wheelbase measurement, model-aware variable lookahead, curvature/accel-limited speed control, command-rate limiting, an optional low-speed Stanley cross-track blend, a debounced disengage monitor, and live-reconfigurable parameters.
ROS Interface
Subscribed Topics
| Topic | Type | Description |
|---|---|---|
trajectory |
wato_trajectory_msgs/Trajectory |
Planned trajectory from the freeroam planner |
execute_behaviour |
behaviour_msgs/ExecuteBehaviour |
Requested behaviour from the behaviour tree |
Published Topics
| Topic | Type | Description |
|---|---|---|
/action/ackermann |
ackermann_msgs/AckermannDriveStamped |
Steering angle and speed command |
/action/is_idle |
std_msgs/Bool |
true when idle or in standby (the disengage monitor does not raise this) |
controller_status |
wato_trajectory_msgs/ControllerStatus |
Per-cycle tracking error, effective lookahead, path curvature, commands, and disengage state/reason |
Also subscribes to odom (nav_msgs/Odometry) for the current longitudinal speed used by the adaptive lookahead and speed scheduling.
Configuration
Parameters are loaded from config/params.yaml under the namespace action/pure_pursuit_node/ros__parameters.
Parameters are read once in on_configure. To change them at runtime, transition the lifecycle node back through cleanup → configure (which reloads config/params.yaml), as with the other action nodes.
Topics / frames
| Parameter | Type | Default | Description |
|---|---|---|---|
controller_status_topic |
string | "controller_status" |
Topic for the ControllerStatus telemetry |
base_frame |
string | "base_footprint" |
Frame stamped on published Ackermann commands |
rear_axle_frame |
string | "rear_axle" |
Frame the pure-pursuit geometry and tracking error are computed in; also one end of the TF wheelbase measurement |
front_axle_frame |
string | "front_axle" |
Other end of the TF wheelbase measurement |
standby_msg |
string | "standby" |
Behaviour string that triggers standby output |
Adaptive lookahead
| Parameter | Type | Default | Description |
|---|---|---|---|
lookahead_distance |
double | 5.0 |
Maximum lookahead distance (m) |
min_lookahead_distance |
double | 2.0 |
Minimum lookahead distance (m) |
lookahead_time |
double | 1.5 |
Time-headway: ld = lookahead_time · speed, clamped to min/max (s) |
curvature_lookahead_gain |
double | 2.0 |
Shrinks lookahead in curves: ld_eff = ld / (1 + gain·|κ|)
|
speed_lookahead_distance |
double | 1.0 |
Minimum distance ahead used to sample target speed (m) |
speed_lookahead_time |
double | 2.0 |
Time-headway for the (decoupled, longer) speed sample horizon (s) |
Steering & speed
| Parameter | Type | Default | Description |
|---|---|---|---|
steering_angle_gain |
double | 1.0 |
Gain on the pure-pursuit steering output |
max_steering_angle |
double | 0.5 |
Maximum steering magnitude (rad) |
max_steering_rate |
double | 1.0 |
Steering slew-rate limit (rad/s) |
max_speed / min_speed
|
double |
5.0 / 0.0
|
Commanded speed bounds while tracking (m/s) |
max_lateral_accel |
double | 2.5 |
Cornering-speed budget: v ≤ sqrt(a_lat/|κ|) (m/s²) |
max_accel / max_decel
|
double |
1.5 / 3.0
|
Command accel/decel slew limits (m/s²) |
Low-speed cross-track blend (Stanley)
| Parameter | Type | Default | Description |
|---|---|---|---|
enable_stanley_blend |
bool | false |
Blend a cross-track feedback term into steering at low speed |
stanley_gain |
double | 0.5 |
Cross-track feedback gain k_e
|
stanley_softening |
double | 1.0 |
Softening constant k_soft (avoids blow-up near zero speed) |
stanley_speed_threshold |
double | 2.0 |
Blend weight ramps from 1 (at 0) to 0 at this speed (m/s) |
Disengage monitor
| Parameter | Type | Default | Description |
|---|---|---|---|
enable_disengage |
bool | true |
Enable the tracking-threshold disengage monitor |
max_cross_track_error |
double | 1.5 |
Cross-track error that (sustained) trips a disengage (m) |
max_heading_error |
double | 0.6 |
Heading error that (sustained) trips a disengage (rad) |
disengage_debounce_sec |
double | 0.5 |
How long the error must be exceeded before tripping (s) |
disengage_latch |
bool | false |
true = stay disengaged until reconfigured; false = auto-recover |
disengage_speed |
double | 0.0 |
Safe speed commanded when no valid lookahead point exists (m/s) |
Standby / misc
| Parameter | Type | Default | Description |
|---|---|---|---|
standby_speed |
double | -0.5 |
Speed commanded during standby (m/s) |
standby_steering |
double | 0.0 |
Steering commanded during standby (rad) |
control_rate_hz |
double | 20.0 |
Control publish rate (Hz) |
wheelbase_fallback |
double | 2.5667 |
Fallback wheelbase if the TF lookup fails (m) |
idle_timeout_sec |
double | 2.0 |
Time since last trajectory before declaring idle (s) |
invert_steering |
bool | true |
Invert steering sign — true means positive angle = clockwise |
disable_standby |
bool | false |
Bypass standby and track even when standby_msg is received |
Algorithm Details
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| wato_test | |
| rclcpp | |
| rclcpp_lifecycle | |
| behaviour_msgs | |
| geometry_msgs | |
| nav_msgs | |
| std_msgs | |
| ackermann_msgs | |
| tf2 | |
| tf2_ros | |
| tf2_geometry_msgs | |
| wato_trajectory_msgs |
System Dependencies
Dependant Packages
| Name | Deps |
|---|---|
| action_bringup |
Launch files
Messages
Services
Plugins
Recent questions tagged ackermann_pure_pursuit at Robotics Stack Exchange
Package Summary
| Version | 0.1.0 |
| License | Apache 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | |
| Checkout URI | https://github.com/watonomous/wato_monorepo.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-15 |
| Dev Status | UNKNOWN |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- WATonomous
Authors
Ackermann Pure Pursuit
ROS2 lifecycle node that tracks a trajectory using the pure pursuit algorithm, publishing Ackermann drive commands for vehicle steering and speed control.
Overview
The pure pursuit node receives a planned trajectory, transforms each waypoint into the vehicle’s rear-axle reference frame (once per cycle), selects a lookahead point, and computes the steering angle and speed via the pure pursuit geometric algorithm. The lookahead distance is adapted to speed and path curvature, speed is limited by a lateral-acceleration budget, and the steering/speed commands are rate-limited for smoothness. Each cycle it measures cross-track and heading error and, if either exceeds a tunable threshold for a sustained window, raises a disengage recommendation in its ControllerStatus telemetry. This is advisory only: the controller keeps tracking normally and does not alter its command, yield the mux, or talk to the OSCC layer — acting on the recommendation is left to a higher-level supervisor. It publishes an idle signal and standby Ackermann commands when no valid trajectory is available, the trajectory has gone stale, or the behaviour tree requests standby.
Current Status: Adaptive pure pursuit controller with rear-axle geometry, TF-based wheelbase measurement, model-aware variable lookahead, curvature/accel-limited speed control, command-rate limiting, an optional low-speed Stanley cross-track blend, a debounced disengage monitor, and live-reconfigurable parameters.
ROS Interface
Subscribed Topics
| Topic | Type | Description |
|---|---|---|
trajectory |
wato_trajectory_msgs/Trajectory |
Planned trajectory from the freeroam planner |
execute_behaviour |
behaviour_msgs/ExecuteBehaviour |
Requested behaviour from the behaviour tree |
Published Topics
| Topic | Type | Description |
|---|---|---|
/action/ackermann |
ackermann_msgs/AckermannDriveStamped |
Steering angle and speed command |
/action/is_idle |
std_msgs/Bool |
true when idle or in standby (the disengage monitor does not raise this) |
controller_status |
wato_trajectory_msgs/ControllerStatus |
Per-cycle tracking error, effective lookahead, path curvature, commands, and disengage state/reason |
Also subscribes to odom (nav_msgs/Odometry) for the current longitudinal speed used by the adaptive lookahead and speed scheduling.
Configuration
Parameters are loaded from config/params.yaml under the namespace action/pure_pursuit_node/ros__parameters.
Parameters are read once in on_configure. To change them at runtime, transition the lifecycle node back through cleanup → configure (which reloads config/params.yaml), as with the other action nodes.
Topics / frames
| Parameter | Type | Default | Description |
|---|---|---|---|
controller_status_topic |
string | "controller_status" |
Topic for the ControllerStatus telemetry |
base_frame |
string | "base_footprint" |
Frame stamped on published Ackermann commands |
rear_axle_frame |
string | "rear_axle" |
Frame the pure-pursuit geometry and tracking error are computed in; also one end of the TF wheelbase measurement |
front_axle_frame |
string | "front_axle" |
Other end of the TF wheelbase measurement |
standby_msg |
string | "standby" |
Behaviour string that triggers standby output |
Adaptive lookahead
| Parameter | Type | Default | Description |
|---|---|---|---|
lookahead_distance |
double | 5.0 |
Maximum lookahead distance (m) |
min_lookahead_distance |
double | 2.0 |
Minimum lookahead distance (m) |
lookahead_time |
double | 1.5 |
Time-headway: ld = lookahead_time · speed, clamped to min/max (s) |
curvature_lookahead_gain |
double | 2.0 |
Shrinks lookahead in curves: ld_eff = ld / (1 + gain·|κ|)
|
speed_lookahead_distance |
double | 1.0 |
Minimum distance ahead used to sample target speed (m) |
speed_lookahead_time |
double | 2.0 |
Time-headway for the (decoupled, longer) speed sample horizon (s) |
Steering & speed
| Parameter | Type | Default | Description |
|---|---|---|---|
steering_angle_gain |
double | 1.0 |
Gain on the pure-pursuit steering output |
max_steering_angle |
double | 0.5 |
Maximum steering magnitude (rad) |
max_steering_rate |
double | 1.0 |
Steering slew-rate limit (rad/s) |
max_speed / min_speed
|
double |
5.0 / 0.0
|
Commanded speed bounds while tracking (m/s) |
max_lateral_accel |
double | 2.5 |
Cornering-speed budget: v ≤ sqrt(a_lat/|κ|) (m/s²) |
max_accel / max_decel
|
double |
1.5 / 3.0
|
Command accel/decel slew limits (m/s²) |
Low-speed cross-track blend (Stanley)
| Parameter | Type | Default | Description |
|---|---|---|---|
enable_stanley_blend |
bool | false |
Blend a cross-track feedback term into steering at low speed |
stanley_gain |
double | 0.5 |
Cross-track feedback gain k_e
|
stanley_softening |
double | 1.0 |
Softening constant k_soft (avoids blow-up near zero speed) |
stanley_speed_threshold |
double | 2.0 |
Blend weight ramps from 1 (at 0) to 0 at this speed (m/s) |
Disengage monitor
| Parameter | Type | Default | Description |
|---|---|---|---|
enable_disengage |
bool | true |
Enable the tracking-threshold disengage monitor |
max_cross_track_error |
double | 1.5 |
Cross-track error that (sustained) trips a disengage (m) |
max_heading_error |
double | 0.6 |
Heading error that (sustained) trips a disengage (rad) |
disengage_debounce_sec |
double | 0.5 |
How long the error must be exceeded before tripping (s) |
disengage_latch |
bool | false |
true = stay disengaged until reconfigured; false = auto-recover |
disengage_speed |
double | 0.0 |
Safe speed commanded when no valid lookahead point exists (m/s) |
Standby / misc
| Parameter | Type | Default | Description |
|---|---|---|---|
standby_speed |
double | -0.5 |
Speed commanded during standby (m/s) |
standby_steering |
double | 0.0 |
Steering commanded during standby (rad) |
control_rate_hz |
double | 20.0 |
Control publish rate (Hz) |
wheelbase_fallback |
double | 2.5667 |
Fallback wheelbase if the TF lookup fails (m) |
idle_timeout_sec |
double | 2.0 |
Time since last trajectory before declaring idle (s) |
invert_steering |
bool | true |
Invert steering sign — true means positive angle = clockwise |
disable_standby |
bool | false |
Bypass standby and track even when standby_msg is received |
Algorithm Details
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| wato_test | |
| rclcpp | |
| rclcpp_lifecycle | |
| behaviour_msgs | |
| geometry_msgs | |
| nav_msgs | |
| std_msgs | |
| ackermann_msgs | |
| tf2 | |
| tf2_ros | |
| tf2_geometry_msgs | |
| wato_trajectory_msgs |
System Dependencies
Dependant Packages
| Name | Deps |
|---|---|
| action_bringup |
Launch files
Messages
Services
Plugins
Recent questions tagged ackermann_pure_pursuit at Robotics Stack Exchange
Package Summary
| Version | 0.1.0 |
| License | Apache 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | |
| Checkout URI | https://github.com/WATonomous/wato_monorepo.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-15 |
| Dev Status | DEVELOPED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- WATonomous
Authors
Ackermann Pure Pursuit
ROS2 lifecycle node that tracks a trajectory using the pure pursuit algorithm, publishing Ackermann drive commands for vehicle steering and speed control.
Overview
The pure pursuit node receives a planned trajectory, transforms each waypoint into the vehicle’s rear-axle reference frame (once per cycle), selects a lookahead point, and computes the steering angle and speed via the pure pursuit geometric algorithm. The lookahead distance is adapted to speed and path curvature, speed is limited by a lateral-acceleration budget, and the steering/speed commands are rate-limited for smoothness. Each cycle it measures cross-track and heading error and, if either exceeds a tunable threshold for a sustained window, raises a disengage recommendation in its ControllerStatus telemetry. This is advisory only: the controller keeps tracking normally and does not alter its command, yield the mux, or talk to the OSCC layer — acting on the recommendation is left to a higher-level supervisor. It publishes an idle signal and standby Ackermann commands when no valid trajectory is available, the trajectory has gone stale, or the behaviour tree requests standby.
Current Status: Adaptive pure pursuit controller with rear-axle geometry, TF-based wheelbase measurement, model-aware variable lookahead, curvature/accel-limited speed control, command-rate limiting, an optional low-speed Stanley cross-track blend, a debounced disengage monitor, and live-reconfigurable parameters.
ROS Interface
Subscribed Topics
| Topic | Type | Description |
|---|---|---|
trajectory |
wato_trajectory_msgs/Trajectory |
Planned trajectory from the freeroam planner |
execute_behaviour |
behaviour_msgs/ExecuteBehaviour |
Requested behaviour from the behaviour tree |
Published Topics
| Topic | Type | Description |
|---|---|---|
/action/ackermann |
ackermann_msgs/AckermannDriveStamped |
Steering angle and speed command |
/action/is_idle |
std_msgs/Bool |
true when idle or in standby (the disengage monitor does not raise this) |
controller_status |
wato_trajectory_msgs/ControllerStatus |
Per-cycle tracking error, effective lookahead, path curvature, commands, and disengage state/reason |
Also subscribes to odom (nav_msgs/Odometry) for the current longitudinal speed used by the adaptive lookahead and speed scheduling.
Configuration
Parameters are loaded from config/params.yaml under the namespace action/pure_pursuit_node/ros__parameters.
Parameters are read once in on_configure. To change them at runtime, transition the lifecycle node back through cleanup → configure (which reloads config/params.yaml), as with the other action nodes.
Topics / frames
| Parameter | Type | Default | Description |
|---|---|---|---|
controller_status_topic |
string | "controller_status" |
Topic for the ControllerStatus telemetry |
base_frame |
string | "base_footprint" |
Frame stamped on published Ackermann commands |
rear_axle_frame |
string | "rear_axle" |
Frame the pure-pursuit geometry and tracking error are computed in; also one end of the TF wheelbase measurement |
front_axle_frame |
string | "front_axle" |
Other end of the TF wheelbase measurement |
standby_msg |
string | "standby" |
Behaviour string that triggers standby output |
Adaptive lookahead
| Parameter | Type | Default | Description |
|---|---|---|---|
lookahead_distance |
double | 5.0 |
Maximum lookahead distance (m) |
min_lookahead_distance |
double | 2.0 |
Minimum lookahead distance (m) |
lookahead_time |
double | 1.5 |
Time-headway: ld = lookahead_time · speed, clamped to min/max (s) |
curvature_lookahead_gain |
double | 2.0 |
Shrinks lookahead in curves: ld_eff = ld / (1 + gain·|κ|)
|
speed_lookahead_distance |
double | 1.0 |
Minimum distance ahead used to sample target speed (m) |
speed_lookahead_time |
double | 2.0 |
Time-headway for the (decoupled, longer) speed sample horizon (s) |
Steering & speed
| Parameter | Type | Default | Description |
|---|---|---|---|
steering_angle_gain |
double | 1.0 |
Gain on the pure-pursuit steering output |
max_steering_angle |
double | 0.5 |
Maximum steering magnitude (rad) |
max_steering_rate |
double | 1.0 |
Steering slew-rate limit (rad/s) |
max_speed / min_speed
|
double |
5.0 / 0.0
|
Commanded speed bounds while tracking (m/s) |
max_lateral_accel |
double | 2.5 |
Cornering-speed budget: v ≤ sqrt(a_lat/|κ|) (m/s²) |
max_accel / max_decel
|
double |
1.5 / 3.0
|
Command accel/decel slew limits (m/s²) |
Low-speed cross-track blend (Stanley)
| Parameter | Type | Default | Description |
|---|---|---|---|
enable_stanley_blend |
bool | false |
Blend a cross-track feedback term into steering at low speed |
stanley_gain |
double | 0.5 |
Cross-track feedback gain k_e
|
stanley_softening |
double | 1.0 |
Softening constant k_soft (avoids blow-up near zero speed) |
stanley_speed_threshold |
double | 2.0 |
Blend weight ramps from 1 (at 0) to 0 at this speed (m/s) |
Disengage monitor
| Parameter | Type | Default | Description |
|---|---|---|---|
enable_disengage |
bool | true |
Enable the tracking-threshold disengage monitor |
max_cross_track_error |
double | 1.5 |
Cross-track error that (sustained) trips a disengage (m) |
max_heading_error |
double | 0.6 |
Heading error that (sustained) trips a disengage (rad) |
disengage_debounce_sec |
double | 0.5 |
How long the error must be exceeded before tripping (s) |
disengage_latch |
bool | false |
true = stay disengaged until reconfigured; false = auto-recover |
disengage_speed |
double | 0.0 |
Safe speed commanded when no valid lookahead point exists (m/s) |
Standby / misc
| Parameter | Type | Default | Description |
|---|---|---|---|
standby_speed |
double | -0.5 |
Speed commanded during standby (m/s) |
standby_steering |
double | 0.0 |
Steering commanded during standby (rad) |
control_rate_hz |
double | 20.0 |
Control publish rate (Hz) |
wheelbase_fallback |
double | 2.5667 |
Fallback wheelbase if the TF lookup fails (m) |
idle_timeout_sec |
double | 2.0 |
Time since last trajectory before declaring idle (s) |
invert_steering |
bool | true |
Invert steering sign — true means positive angle = clockwise |
disable_standby |
bool | false |
Bypass standby and track even when standby_msg is received |
Algorithm Details
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| wato_test | |
| rclcpp | |
| rclcpp_lifecycle | |
| behaviour_msgs | |
| geometry_msgs | |
| nav_msgs | |
| std_msgs | |
| ackermann_msgs | |
| tf2 | |
| tf2_ros | |
| tf2_geometry_msgs | |
| wato_trajectory_msgs |
System Dependencies
Dependant Packages
| Name | Deps |
|---|---|
| action_bringup |
Launch files
Messages
Services
Plugins
Recent questions tagged ackermann_pure_pursuit at Robotics Stack Exchange
Package Summary
| Version | 0.1.0 |
| License | Apache 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | |
| Checkout URI | https://github.com/WATonomous/wato_monorepo.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-15 |
| Dev Status | DEVELOPED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- WATonomous
Authors
Ackermann Pure Pursuit
ROS2 lifecycle node that tracks a trajectory using the pure pursuit algorithm, publishing Ackermann drive commands for vehicle steering and speed control.
Overview
The pure pursuit node receives a planned trajectory, transforms each waypoint into the vehicle’s rear-axle reference frame (once per cycle), selects a lookahead point, and computes the steering angle and speed via the pure pursuit geometric algorithm. The lookahead distance is adapted to speed and path curvature, speed is limited by a lateral-acceleration budget, and the steering/speed commands are rate-limited for smoothness. Each cycle it measures cross-track and heading error and, if either exceeds a tunable threshold for a sustained window, raises a disengage recommendation in its ControllerStatus telemetry. This is advisory only: the controller keeps tracking normally and does not alter its command, yield the mux, or talk to the OSCC layer — acting on the recommendation is left to a higher-level supervisor. It publishes an idle signal and standby Ackermann commands when no valid trajectory is available, the trajectory has gone stale, or the behaviour tree requests standby.
Current Status: Adaptive pure pursuit controller with rear-axle geometry, TF-based wheelbase measurement, model-aware variable lookahead, curvature/accel-limited speed control, command-rate limiting, an optional low-speed Stanley cross-track blend, a debounced disengage monitor, and live-reconfigurable parameters.
ROS Interface
Subscribed Topics
| Topic | Type | Description |
|---|---|---|
trajectory |
wato_trajectory_msgs/Trajectory |
Planned trajectory from the freeroam planner |
execute_behaviour |
behaviour_msgs/ExecuteBehaviour |
Requested behaviour from the behaviour tree |
Published Topics
| Topic | Type | Description |
|---|---|---|
/action/ackermann |
ackermann_msgs/AckermannDriveStamped |
Steering angle and speed command |
/action/is_idle |
std_msgs/Bool |
true when idle or in standby (the disengage monitor does not raise this) |
controller_status |
wato_trajectory_msgs/ControllerStatus |
Per-cycle tracking error, effective lookahead, path curvature, commands, and disengage state/reason |
Also subscribes to odom (nav_msgs/Odometry) for the current longitudinal speed used by the adaptive lookahead and speed scheduling.
Configuration
Parameters are loaded from config/params.yaml under the namespace action/pure_pursuit_node/ros__parameters.
Parameters are read once in on_configure. To change them at runtime, transition the lifecycle node back through cleanup → configure (which reloads config/params.yaml), as with the other action nodes.
Topics / frames
| Parameter | Type | Default | Description |
|---|---|---|---|
controller_status_topic |
string | "controller_status" |
Topic for the ControllerStatus telemetry |
base_frame |
string | "base_footprint" |
Frame stamped on published Ackermann commands |
rear_axle_frame |
string | "rear_axle" |
Frame the pure-pursuit geometry and tracking error are computed in; also one end of the TF wheelbase measurement |
front_axle_frame |
string | "front_axle" |
Other end of the TF wheelbase measurement |
standby_msg |
string | "standby" |
Behaviour string that triggers standby output |
Adaptive lookahead
| Parameter | Type | Default | Description |
|---|---|---|---|
lookahead_distance |
double | 5.0 |
Maximum lookahead distance (m) |
min_lookahead_distance |
double | 2.0 |
Minimum lookahead distance (m) |
lookahead_time |
double | 1.5 |
Time-headway: ld = lookahead_time · speed, clamped to min/max (s) |
curvature_lookahead_gain |
double | 2.0 |
Shrinks lookahead in curves: ld_eff = ld / (1 + gain·|κ|)
|
speed_lookahead_distance |
double | 1.0 |
Minimum distance ahead used to sample target speed (m) |
speed_lookahead_time |
double | 2.0 |
Time-headway for the (decoupled, longer) speed sample horizon (s) |
Steering & speed
| Parameter | Type | Default | Description |
|---|---|---|---|
steering_angle_gain |
double | 1.0 |
Gain on the pure-pursuit steering output |
max_steering_angle |
double | 0.5 |
Maximum steering magnitude (rad) |
max_steering_rate |
double | 1.0 |
Steering slew-rate limit (rad/s) |
max_speed / min_speed
|
double |
5.0 / 0.0
|
Commanded speed bounds while tracking (m/s) |
max_lateral_accel |
double | 2.5 |
Cornering-speed budget: v ≤ sqrt(a_lat/|κ|) (m/s²) |
max_accel / max_decel
|
double |
1.5 / 3.0
|
Command accel/decel slew limits (m/s²) |
Low-speed cross-track blend (Stanley)
| Parameter | Type | Default | Description |
|---|---|---|---|
enable_stanley_blend |
bool | false |
Blend a cross-track feedback term into steering at low speed |
stanley_gain |
double | 0.5 |
Cross-track feedback gain k_e
|
stanley_softening |
double | 1.0 |
Softening constant k_soft (avoids blow-up near zero speed) |
stanley_speed_threshold |
double | 2.0 |
Blend weight ramps from 1 (at 0) to 0 at this speed (m/s) |
Disengage monitor
| Parameter | Type | Default | Description |
|---|---|---|---|
enable_disengage |
bool | true |
Enable the tracking-threshold disengage monitor |
max_cross_track_error |
double | 1.5 |
Cross-track error that (sustained) trips a disengage (m) |
max_heading_error |
double | 0.6 |
Heading error that (sustained) trips a disengage (rad) |
disengage_debounce_sec |
double | 0.5 |
How long the error must be exceeded before tripping (s) |
disengage_latch |
bool | false |
true = stay disengaged until reconfigured; false = auto-recover |
disengage_speed |
double | 0.0 |
Safe speed commanded when no valid lookahead point exists (m/s) |
Standby / misc
| Parameter | Type | Default | Description |
|---|---|---|---|
standby_speed |
double | -0.5 |
Speed commanded during standby (m/s) |
standby_steering |
double | 0.0 |
Steering commanded during standby (rad) |
control_rate_hz |
double | 20.0 |
Control publish rate (Hz) |
wheelbase_fallback |
double | 2.5667 |
Fallback wheelbase if the TF lookup fails (m) |
idle_timeout_sec |
double | 2.0 |
Time since last trajectory before declaring idle (s) |
invert_steering |
bool | true |
Invert steering sign — true means positive angle = clockwise |
disable_standby |
bool | false |
Bypass standby and track even when standby_msg is received |
Algorithm Details
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| wato_test | |
| rclcpp | |
| rclcpp_lifecycle | |
| behaviour_msgs | |
| geometry_msgs | |
| nav_msgs | |
| std_msgs | |
| ackermann_msgs | |
| tf2 | |
| tf2_ros | |
| tf2_geometry_msgs | |
| wato_trajectory_msgs |
System Dependencies
Dependant Packages
| Name | Deps |
|---|---|
| action_bringup |
Launch files
Messages
Services
Plugins
Recent questions tagged ackermann_pure_pursuit at Robotics Stack Exchange
Package Summary
| Version | 0.1.0 |
| License | Apache 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | |
| Checkout URI | https://github.com/WATonomous/wato_monorepo.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-15 |
| Dev Status | DEVELOPED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- WATonomous
Authors
Ackermann Pure Pursuit
ROS2 lifecycle node that tracks a trajectory using the pure pursuit algorithm, publishing Ackermann drive commands for vehicle steering and speed control.
Overview
The pure pursuit node receives a planned trajectory, transforms each waypoint into the vehicle’s rear-axle reference frame (once per cycle), selects a lookahead point, and computes the steering angle and speed via the pure pursuit geometric algorithm. The lookahead distance is adapted to speed and path curvature, speed is limited by a lateral-acceleration budget, and the steering/speed commands are rate-limited for smoothness. Each cycle it measures cross-track and heading error and, if either exceeds a tunable threshold for a sustained window, raises a disengage recommendation in its ControllerStatus telemetry. This is advisory only: the controller keeps tracking normally and does not alter its command, yield the mux, or talk to the OSCC layer — acting on the recommendation is left to a higher-level supervisor. It publishes an idle signal and standby Ackermann commands when no valid trajectory is available, the trajectory has gone stale, or the behaviour tree requests standby.
Current Status: Adaptive pure pursuit controller with rear-axle geometry, TF-based wheelbase measurement, model-aware variable lookahead, curvature/accel-limited speed control, command-rate limiting, an optional low-speed Stanley cross-track blend, a debounced disengage monitor, and live-reconfigurable parameters.
ROS Interface
Subscribed Topics
| Topic | Type | Description |
|---|---|---|
trajectory |
wato_trajectory_msgs/Trajectory |
Planned trajectory from the freeroam planner |
execute_behaviour |
behaviour_msgs/ExecuteBehaviour |
Requested behaviour from the behaviour tree |
Published Topics
| Topic | Type | Description |
|---|---|---|
/action/ackermann |
ackermann_msgs/AckermannDriveStamped |
Steering angle and speed command |
/action/is_idle |
std_msgs/Bool |
true when idle or in standby (the disengage monitor does not raise this) |
controller_status |
wato_trajectory_msgs/ControllerStatus |
Per-cycle tracking error, effective lookahead, path curvature, commands, and disengage state/reason |
Also subscribes to odom (nav_msgs/Odometry) for the current longitudinal speed used by the adaptive lookahead and speed scheduling.
Configuration
Parameters are loaded from config/params.yaml under the namespace action/pure_pursuit_node/ros__parameters.
Parameters are read once in on_configure. To change them at runtime, transition the lifecycle node back through cleanup → configure (which reloads config/params.yaml), as with the other action nodes.
Topics / frames
| Parameter | Type | Default | Description |
|---|---|---|---|
controller_status_topic |
string | "controller_status" |
Topic for the ControllerStatus telemetry |
base_frame |
string | "base_footprint" |
Frame stamped on published Ackermann commands |
rear_axle_frame |
string | "rear_axle" |
Frame the pure-pursuit geometry and tracking error are computed in; also one end of the TF wheelbase measurement |
front_axle_frame |
string | "front_axle" |
Other end of the TF wheelbase measurement |
standby_msg |
string | "standby" |
Behaviour string that triggers standby output |
Adaptive lookahead
| Parameter | Type | Default | Description |
|---|---|---|---|
lookahead_distance |
double | 5.0 |
Maximum lookahead distance (m) |
min_lookahead_distance |
double | 2.0 |
Minimum lookahead distance (m) |
lookahead_time |
double | 1.5 |
Time-headway: ld = lookahead_time · speed, clamped to min/max (s) |
curvature_lookahead_gain |
double | 2.0 |
Shrinks lookahead in curves: ld_eff = ld / (1 + gain·|κ|)
|
speed_lookahead_distance |
double | 1.0 |
Minimum distance ahead used to sample target speed (m) |
speed_lookahead_time |
double | 2.0 |
Time-headway for the (decoupled, longer) speed sample horizon (s) |
Steering & speed
| Parameter | Type | Default | Description |
|---|---|---|---|
steering_angle_gain |
double | 1.0 |
Gain on the pure-pursuit steering output |
max_steering_angle |
double | 0.5 |
Maximum steering magnitude (rad) |
max_steering_rate |
double | 1.0 |
Steering slew-rate limit (rad/s) |
max_speed / min_speed
|
double |
5.0 / 0.0
|
Commanded speed bounds while tracking (m/s) |
max_lateral_accel |
double | 2.5 |
Cornering-speed budget: v ≤ sqrt(a_lat/|κ|) (m/s²) |
max_accel / max_decel
|
double |
1.5 / 3.0
|
Command accel/decel slew limits (m/s²) |
Low-speed cross-track blend (Stanley)
| Parameter | Type | Default | Description |
|---|---|---|---|
enable_stanley_blend |
bool | false |
Blend a cross-track feedback term into steering at low speed |
stanley_gain |
double | 0.5 |
Cross-track feedback gain k_e
|
stanley_softening |
double | 1.0 |
Softening constant k_soft (avoids blow-up near zero speed) |
stanley_speed_threshold |
double | 2.0 |
Blend weight ramps from 1 (at 0) to 0 at this speed (m/s) |
Disengage monitor
| Parameter | Type | Default | Description |
|---|---|---|---|
enable_disengage |
bool | true |
Enable the tracking-threshold disengage monitor |
max_cross_track_error |
double | 1.5 |
Cross-track error that (sustained) trips a disengage (m) |
max_heading_error |
double | 0.6 |
Heading error that (sustained) trips a disengage (rad) |
disengage_debounce_sec |
double | 0.5 |
How long the error must be exceeded before tripping (s) |
disengage_latch |
bool | false |
true = stay disengaged until reconfigured; false = auto-recover |
disengage_speed |
double | 0.0 |
Safe speed commanded when no valid lookahead point exists (m/s) |
Standby / misc
| Parameter | Type | Default | Description |
|---|---|---|---|
standby_speed |
double | -0.5 |
Speed commanded during standby (m/s) |
standby_steering |
double | 0.0 |
Steering commanded during standby (rad) |
control_rate_hz |
double | 20.0 |
Control publish rate (Hz) |
wheelbase_fallback |
double | 2.5667 |
Fallback wheelbase if the TF lookup fails (m) |
idle_timeout_sec |
double | 2.0 |
Time since last trajectory before declaring idle (s) |
invert_steering |
bool | true |
Invert steering sign — true means positive angle = clockwise |
disable_standby |
bool | false |
Bypass standby and track even when standby_msg is received |
Algorithm Details
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| wato_test | |
| rclcpp | |
| rclcpp_lifecycle | |
| behaviour_msgs | |
| geometry_msgs | |
| nav_msgs | |
| std_msgs | |
| ackermann_msgs | |
| tf2 | |
| tf2_ros | |
| tf2_geometry_msgs | |
| wato_trajectory_msgs |
System Dependencies
Dependant Packages
| Name | Deps |
|---|---|
| action_bringup |
Launch files
Messages
Services
Plugins
Recent questions tagged ackermann_pure_pursuit at Robotics Stack Exchange
Package Summary
| Version | 0.1.0 |
| License | Apache 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | |
| Checkout URI | https://github.com/WATonomous/wato_monorepo.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-15 |
| Dev Status | DEVELOPED |
| Released | UNRELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- WATonomous
Authors
Ackermann Pure Pursuit
ROS2 lifecycle node that tracks a trajectory using the pure pursuit algorithm, publishing Ackermann drive commands for vehicle steering and speed control.
Overview
The pure pursuit node receives a planned trajectory, transforms each waypoint into the vehicle’s rear-axle reference frame (once per cycle), selects a lookahead point, and computes the steering angle and speed via the pure pursuit geometric algorithm. The lookahead distance is adapted to speed and path curvature, speed is limited by a lateral-acceleration budget, and the steering/speed commands are rate-limited for smoothness. Each cycle it measures cross-track and heading error and, if either exceeds a tunable threshold for a sustained window, raises a disengage recommendation in its ControllerStatus telemetry. This is advisory only: the controller keeps tracking normally and does not alter its command, yield the mux, or talk to the OSCC layer — acting on the recommendation is left to a higher-level supervisor. It publishes an idle signal and standby Ackermann commands when no valid trajectory is available, the trajectory has gone stale, or the behaviour tree requests standby.
Current Status: Adaptive pure pursuit controller with rear-axle geometry, TF-based wheelbase measurement, model-aware variable lookahead, curvature/accel-limited speed control, command-rate limiting, an optional low-speed Stanley cross-track blend, a debounced disengage monitor, and live-reconfigurable parameters.
ROS Interface
Subscribed Topics
| Topic | Type | Description |
|---|---|---|
trajectory |
wato_trajectory_msgs/Trajectory |
Planned trajectory from the freeroam planner |
execute_behaviour |
behaviour_msgs/ExecuteBehaviour |
Requested behaviour from the behaviour tree |
Published Topics
| Topic | Type | Description |
|---|---|---|
/action/ackermann |
ackermann_msgs/AckermannDriveStamped |
Steering angle and speed command |
/action/is_idle |
std_msgs/Bool |
true when idle or in standby (the disengage monitor does not raise this) |
controller_status |
wato_trajectory_msgs/ControllerStatus |
Per-cycle tracking error, effective lookahead, path curvature, commands, and disengage state/reason |
Also subscribes to odom (nav_msgs/Odometry) for the current longitudinal speed used by the adaptive lookahead and speed scheduling.
Configuration
Parameters are loaded from config/params.yaml under the namespace action/pure_pursuit_node/ros__parameters.
Parameters are read once in on_configure. To change them at runtime, transition the lifecycle node back through cleanup → configure (which reloads config/params.yaml), as with the other action nodes.
Topics / frames
| Parameter | Type | Default | Description |
|---|---|---|---|
controller_status_topic |
string | "controller_status" |
Topic for the ControllerStatus telemetry |
base_frame |
string | "base_footprint" |
Frame stamped on published Ackermann commands |
rear_axle_frame |
string | "rear_axle" |
Frame the pure-pursuit geometry and tracking error are computed in; also one end of the TF wheelbase measurement |
front_axle_frame |
string | "front_axle" |
Other end of the TF wheelbase measurement |
standby_msg |
string | "standby" |
Behaviour string that triggers standby output |
Adaptive lookahead
| Parameter | Type | Default | Description |
|---|---|---|---|
lookahead_distance |
double | 5.0 |
Maximum lookahead distance (m) |
min_lookahead_distance |
double | 2.0 |
Minimum lookahead distance (m) |
lookahead_time |
double | 1.5 |
Time-headway: ld = lookahead_time · speed, clamped to min/max (s) |
curvature_lookahead_gain |
double | 2.0 |
Shrinks lookahead in curves: ld_eff = ld / (1 + gain·|κ|)
|
speed_lookahead_distance |
double | 1.0 |
Minimum distance ahead used to sample target speed (m) |
speed_lookahead_time |
double | 2.0 |
Time-headway for the (decoupled, longer) speed sample horizon (s) |
Steering & speed
| Parameter | Type | Default | Description |
|---|---|---|---|
steering_angle_gain |
double | 1.0 |
Gain on the pure-pursuit steering output |
max_steering_angle |
double | 0.5 |
Maximum steering magnitude (rad) |
max_steering_rate |
double | 1.0 |
Steering slew-rate limit (rad/s) |
max_speed / min_speed
|
double |
5.0 / 0.0
|
Commanded speed bounds while tracking (m/s) |
max_lateral_accel |
double | 2.5 |
Cornering-speed budget: v ≤ sqrt(a_lat/|κ|) (m/s²) |
max_accel / max_decel
|
double |
1.5 / 3.0
|
Command accel/decel slew limits (m/s²) |
Low-speed cross-track blend (Stanley)
| Parameter | Type | Default | Description |
|---|---|---|---|
enable_stanley_blend |
bool | false |
Blend a cross-track feedback term into steering at low speed |
stanley_gain |
double | 0.5 |
Cross-track feedback gain k_e
|
stanley_softening |
double | 1.0 |
Softening constant k_soft (avoids blow-up near zero speed) |
stanley_speed_threshold |
double | 2.0 |
Blend weight ramps from 1 (at 0) to 0 at this speed (m/s) |
Disengage monitor
| Parameter | Type | Default | Description |
|---|---|---|---|
enable_disengage |
bool | true |
Enable the tracking-threshold disengage monitor |
max_cross_track_error |
double | 1.5 |
Cross-track error that (sustained) trips a disengage (m) |
max_heading_error |
double | 0.6 |
Heading error that (sustained) trips a disengage (rad) |
disengage_debounce_sec |
double | 0.5 |
How long the error must be exceeded before tripping (s) |
disengage_latch |
bool | false |
true = stay disengaged until reconfigured; false = auto-recover |
disengage_speed |
double | 0.0 |
Safe speed commanded when no valid lookahead point exists (m/s) |
Standby / misc
| Parameter | Type | Default | Description |
|---|---|---|---|
standby_speed |
double | -0.5 |
Speed commanded during standby (m/s) |
standby_steering |
double | 0.0 |
Steering commanded during standby (rad) |
control_rate_hz |
double | 20.0 |
Control publish rate (Hz) |
wheelbase_fallback |
double | 2.5667 |
Fallback wheelbase if the TF lookup fails (m) |
idle_timeout_sec |
double | 2.0 |
Time since last trajectory before declaring idle (s) |
invert_steering |
bool | true |
Invert steering sign — true means positive angle = clockwise |
disable_standby |
bool | false |
Bypass standby and track even when standby_msg is received |
Algorithm Details
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| wato_test | |
| rclcpp | |
| rclcpp_lifecycle | |
| behaviour_msgs | |
| geometry_msgs | |
| nav_msgs | |
| std_msgs | |
| ackermann_msgs | |
| tf2 | |
| tf2_ros | |
| tf2_geometry_msgs | |
| wato_trajectory_msgs |
System Dependencies
Dependant Packages
| Name | Deps |
|---|---|
| action_bringup |