@@ -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 .
472473bool 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).
0 commit comments