Skip to content

Commit 487a254

Browse files
committed
AP_Math: limit_accel_corner_xy: Improve post corner crosstrack behavior
1 parent 286742c commit 487a254

File tree

2 files changed

+49
-29
lines changed

2 files changed

+49
-29
lines changed

libraries/AP_Math/control.cpp

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -461,14 +461,15 @@ bool limit_accel_xy(const Vector2f& vel, Vector2f& accel, float accel_max)
461461
return false;
462462
}
463463

464-
// Limits a 2D acceleration vector while prioritising along-track deceleration.
465-
// - Splits acceleration into components parallel and perpendicular to the current velocity direction.
466-
// - Only the decelerating (braking) along-track component is prioritised; accelerating along-track
467-
// components are treated as "no braking" and fall back to a simple magnitude limit.
468-
// - When braking is requested, cross-track acceleration is limited to the remaining magnitude
469-
// budget after reserving the braking component.
464+
// Limits a 2D acceleration vector with direction-dependent prioritisation.
465+
// - Acceleration is decomposed into along-track (parallel to velocity) and cross-track components.
466+
// - If braking is requested (negative along-track component), braking is prioritised and the
467+
// remaining acceleration budget is allocated to cross-track.
468+
// - If no braking is requested (along-track acceleration or zero), cross-track acceleration
469+
// is prioritised and the remaining budget is allocated to along-track.
470+
// - Ensures the final acceleration magnitude does not exceed accel_max.
470471
// - If velocity is zero (no defined direction), a simple magnitude limit is applied.
471-
// Returns true if the acceleration vector was modified.
472+
// Returns true if the limiting logic was applied.
472473
bool limit_accel_corner_xy(const Vector2f& vel, Vector2f& accel, float accel_max)
473474
{
474475
// Check accel_max is defined.
@@ -489,24 +490,42 @@ bool limit_accel_corner_xy(const Vector2f& vel, Vector2f& accel, float accel_max
489490
// Unit velocity direction defines the along-track axis.
490491
const Vector2f vel_unit = vel.normalized();
491492

492-
// Extract the along-track braking component (negative projection only),
493-
// limited to the maximum allowed along-track deceleration magnitude.
494-
const float accel_brake = constrain_float(accel.dot(vel_unit), -accel_max, 0.0);
495-
496-
// If no braking is requested, fall back to a simple magnitude limit.
497-
if (!is_negative(accel_brake)) {
498-
return accel.limit_length(accel_max);
499-
}
493+
// Signed scalar projection of acceleration onto the velocity direction.
494+
// Negative values correspond to braking.
495+
float accel_dir_scalar = accel.dot(vel_unit);
500496

501-
// Allocate remaining acceleration budget to cross-track after reserving braking.
502-
// Ensures the final accel magnitude does not exceed accel_max.
503-
const float accel_max_cross = safe_sqrt(sq(accel_max) - sq(accel_brake));
504-
const Vector2f accel_dir = vel_unit * accel_brake;
497+
// Along-track and cross-track acceleration components.
498+
Vector2f accel_dir = vel_unit * accel_dir_scalar;
505499
Vector2f accel_cross = accel - accel_dir;
506-
accel_cross.limit_length(accel_max_cross);
507500

508-
accel = accel_cross + accel_dir;
509-
return true;
501+
if (!is_negative(accel_dir_scalar)) {
502+
// Non-braking regime
503+
// Prioritise cross-track acceleration and allocate the remaining budget to along-track.
504+
505+
// Limit cross-track magnitude first.
506+
const float accel_cross_mag = MAX(accel_cross.length(), accel_max);
507+
const float accel_along_max = safe_sqrt(sq(accel_max) - sq(accel_cross_mag));
508+
509+
accel_cross.limit_length(accel_max);
510+
accel_dir.limit_length(accel_along_max);
511+
512+
accel = accel_cross + accel_dir;
513+
return true;
514+
} else {
515+
// Braking regime
516+
// Prioritise along-track deceleration and allocate the remaining budget to cross-track.
517+
518+
// Limit braking magnitude.
519+
accel_dir_scalar = constrain_float(accel_dir_scalar, -accel_max, 0.0);
520+
accel_dir = vel_unit * accel_dir_scalar;
521+
522+
// Allocate remaining acceleration budget to cross-track.
523+
const float accel_cross_max = safe_sqrt(sq(accel_max) - sq(accel_dir_scalar));
524+
accel_cross.limit_length(accel_cross_max);
525+
526+
accel = accel_cross + accel_dir;
527+
return true;
528+
}
510529
}
511530

512531
// Piecewise square-root + linear controller that limits second-order response (acceleration).

libraries/AP_Math/control.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -138,14 +138,15 @@ void shape_angle_vel_accel(float angle_desired, float angle_vel_desired, float a
138138
// Returns true if the acceleration vector was modified.
139139
bool limit_accel_xy(const Vector2f& vel, Vector2f& accel, float accel_max);
140140

141-
// Limits a 2D acceleration vector while prioritising along-track deceleration.
142-
// - Splits acceleration into components parallel and perpendicular to the current velocity direction.
143-
// - Only the decelerating (braking) along-track component is prioritised; accelerating along-track
144-
// components are treated as "no braking" and fall back to a simple magnitude limit.
145-
// - When braking is requested, cross-track acceleration is limited to the remaining magnitude
146-
// budget after reserving the braking component.
141+
// Limits a 2D acceleration vector with direction-dependent prioritisation.
142+
// - Acceleration is decomposed into along-track (parallel to velocity) and cross-track components.
143+
// - If braking is requested (negative along-track component), braking is prioritised and the
144+
// remaining acceleration budget is allocated to cross-track.
145+
// - If no braking is requested (along-track acceleration or zero), cross-track acceleration
146+
// is prioritised and the remaining budget is allocated to along-track.
147+
// - Ensures the final acceleration magnitude does not exceed accel_max.
147148
// - If velocity is zero (no defined direction), a simple magnitude limit is applied.
148-
// Returns true if the acceleration vector was modified.
149+
// Returns true if the limiting logic was applied.
149150
bool limit_accel_corner_xy(const Vector2f& vel, Vector2f& accel, float accel_max);
150151

151152
// Piecewise square-root + linear controller that limits second-order response (acceleration).

0 commit comments

Comments
 (0)