Checklist
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:
- 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.
- 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
- launch vehicle
- Send an emergency command or trigger MRM on curvature
- Observe and record control_cmd output from vehicle_cmd_gate
Versions
No response
Possible causes
No response
Additional context
No response
Checklist
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:
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:
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.
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
Versions
No response
Possible causes
No response
Additional context
No response