Skip to content

Steering is frozen during emergency stop: can cause lane departure when triggered mid-corner #13012

Description

@ismetatabay

Checklist

  • I've read the contribution guidelines.
  • I've searched other issues and no duplicate issues were found.
  • I'm convinced that this is not my fault but a bug.

Description

During an emergency stop, vehicle_cmd_gate freezes the lateral (steering) command at the value that was active at the moment the emergency was triggered, while only the longitudinal command is driven to a stop. If the emergency is triggered while the vehicle is entering or negotiating a curve — before the steering angle has fully developed — the frozen angle no longer matches the path curvature. Because the vehicle keeps moving for the whole stopping distance, the lateral deviation grows and, in the worst case, the vehicle can drift out of its lane before it comes to rest.

Expected behavior

When an emergency stop is triggered, the vehicle should keep following the planned path laterally while it decelerates, so that it comes to a stop within its lane. The steering command should continue to track the trajectory (as the trajectory follower keeps producing valid commands during the emergency) rather than being frozen at the angle that happened to be active at the moment of activation. This is especially important when the emergency is triggered mid-corner, where a frozen steering angle causes the vehicle to drift out of the lane during the stopping distance.


Is freezing the steering during an emergency stop an intentional design decision, and if so, what is the rationale?

A few possibilities I can think of:

  • Hold-the-wheel is safe and predictable when the emergency is triggered on a straight, and simpler than trusting a controller that may itself be part of the failure.
  • During certain fail-safe conditions (e.g. the trajectory follower or its inputs are unreliable) the last-known steering is the only value that can be trusted.

If one of these is the reason, that argues for keeping the freeze as the default and making the "keep tracking" behavior opt-in — which is what I propose below.

Actual behavior

Both emergency paths in vehicle_cmd_gate freeze the lateral command:

  1. System emergency (MRM), in publishControlCommands()
if (use_emergency_handling_ && is_system_emergency_) {
  filtered_control = emergency_commands_.control;   // full replacement, incl. lateral
}

The emergency_commands_.control come from the MRM emergency stop operator, whose calcTargetAcceleration() modifies only the longitudinal fields and copies the lateral command unchanged from the last command received before the MRM started. As a result the steering angle is effectively frozen for the duration of the maneuver.

  1. External emergency stop, in createEmergencyStopControlCmd()
cmd.lateral.steering_tire_angle          = prev_control_cmd_.lateral.steering_tire_angle;
cmd.lateral.steering_tire_rotation_rate  = prev_control_cmd_.lateral.steering_tire_rotation_rate;
cmd.longitudinal.velocity     = 0.0;
cmd.longitudinal.acceleration = emergency_acceleration_;

Here prev_control_cmd_ is the last published command before the emergency, and it is not updated while the emergency-stop command is being published, so the steering stays fixed.

Steps to reproduce

  1. launch vehicle
  2. Send an emergency command or trigger MRM on curvature
  3. Observe and record control_cmd output from vehicle_cmd_gate

Versions

No response

Possible causes

No response

Additional context

No response

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    component:controlVehicle control algorithms and mechanisms. (auto-assigned)

    Type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions