|
|
|
@ -1,8 +1,8 @@ |
|
|
|
|
from cereal import car |
|
|
|
|
from common.numpy_fast import clip, interp |
|
|
|
|
from common.realtime import DT_CTRL |
|
|
|
|
from selfdrive.controls.lib.pid import PIDController |
|
|
|
|
from selfdrive.controls.lib.drive_helpers import CONTROL_N |
|
|
|
|
from selfdrive.controls.lib.pid import PIDController |
|
|
|
|
from selfdrive.modeld.constants import T_IDXS |
|
|
|
|
|
|
|
|
|
LongCtrlState = car.CarControl.Actuators.LongControlState |
|
|
|
@ -50,12 +50,13 @@ def long_control_state_trans(CP, active, long_control_state, v_ego, v_target, |
|
|
|
|
return long_control_state |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class LongControl(): |
|
|
|
|
class LongControl: |
|
|
|
|
def __init__(self, CP): |
|
|
|
|
self.CP = CP |
|
|
|
|
self.long_control_state = LongCtrlState.off # initialized to off |
|
|
|
|
self.pid = PIDController((CP.longitudinalTuning.kpBP, CP.longitudinalTuning.kpV), |
|
|
|
|
(CP.longitudinalTuning.kiBP, CP.longitudinalTuning.kiV), |
|
|
|
|
k_f = CP.longitudinalTuning.kf, rate=1 / DT_CTRL) |
|
|
|
|
k_f=CP.longitudinalTuning.kf, rate=1 / DT_CTRL) |
|
|
|
|
self.v_pid = 0.0 |
|
|
|
|
self.last_output_accel = 0.0 |
|
|
|
|
|
|
|
|
@ -64,7 +65,7 @@ class LongControl(): |
|
|
|
|
self.pid.reset() |
|
|
|
|
self.v_pid = v_pid |
|
|
|
|
|
|
|
|
|
def update(self, active, CS, CP, long_plan, accel_limits, t_since_plan): |
|
|
|
|
def update(self, active, CS, long_plan, accel_limits, t_since_plan): |
|
|
|
|
"""Update longitudinal control. This updates the state machine and runs a PID loop""" |
|
|
|
|
# Interp control trajectory |
|
|
|
|
speeds = long_plan.speeds |
|
|
|
@ -72,11 +73,11 @@ class LongControl(): |
|
|
|
|
v_target = interp(t_since_plan, T_IDXS[:CONTROL_N], speeds) |
|
|
|
|
a_target = interp(t_since_plan, T_IDXS[:CONTROL_N], long_plan.accels) |
|
|
|
|
|
|
|
|
|
v_target_lower = interp(CP.longitudinalActuatorDelayLowerBound + t_since_plan, T_IDXS[:CONTROL_N], speeds) |
|
|
|
|
a_target_lower = 2 * (v_target_lower - v_target) / CP.longitudinalActuatorDelayLowerBound - a_target |
|
|
|
|
v_target_lower = interp(self.CP.longitudinalActuatorDelayLowerBound + t_since_plan, T_IDXS[:CONTROL_N], speeds) |
|
|
|
|
a_target_lower = 2 * (v_target_lower - v_target) / self.CP.longitudinalActuatorDelayLowerBound - a_target |
|
|
|
|
|
|
|
|
|
v_target_upper = interp(CP.longitudinalActuatorDelayUpperBound + t_since_plan, T_IDXS[:CONTROL_N], speeds) |
|
|
|
|
a_target_upper = 2 * (v_target_upper - v_target) / CP.longitudinalActuatorDelayUpperBound - a_target |
|
|
|
|
v_target_upper = interp(self.CP.longitudinalActuatorDelayUpperBound + t_since_plan, T_IDXS[:CONTROL_N], speeds) |
|
|
|
|
a_target_upper = 2 * (v_target_upper - v_target) / self.CP.longitudinalActuatorDelayUpperBound - a_target |
|
|
|
|
a_target = min(a_target_lower, a_target_upper) |
|
|
|
|
|
|
|
|
|
v_target_future = speeds[-1] |
|
|
|
@ -93,7 +94,7 @@ class LongControl(): |
|
|
|
|
|
|
|
|
|
# Update state machine |
|
|
|
|
output_accel = self.last_output_accel |
|
|
|
|
self.long_control_state = long_control_state_trans(CP, active, self.long_control_state, CS.vEgo, |
|
|
|
|
self.long_control_state = long_control_state_trans(self.CP, active, self.long_control_state, CS.vEgo, |
|
|
|
|
v_target, v_target_future, CS.brakePressed, |
|
|
|
|
CS.cruiseState.standstill) |
|
|
|
|
|
|
|
|
@ -107,8 +108,8 @@ class LongControl(): |
|
|
|
|
|
|
|
|
|
# Toyota starts braking more when it thinks you want to stop |
|
|
|
|
# Freeze the integrator so we don't accelerate to compensate, and don't allow positive acceleration |
|
|
|
|
prevent_overshoot = not CP.stoppingControl and CS.vEgo < 1.5 and v_target_future < 0.7 and v_target_future < self.v_pid |
|
|
|
|
deadzone = interp(CS.vEgo, CP.longitudinalTuning.deadzoneBP, CP.longitudinalTuning.deadzoneV) |
|
|
|
|
prevent_overshoot = not self.CP.stoppingControl and CS.vEgo < 1.5 and v_target_future < 0.7 and v_target_future < self.v_pid |
|
|
|
|
deadzone = interp(CS.vEgo, self.CP.longitudinalTuning.deadzoneBP, self.CP.longitudinalTuning.deadzoneV) |
|
|
|
|
freeze_integrator = prevent_overshoot |
|
|
|
|
|
|
|
|
|
error = self.v_pid - CS.vEgo |
|
|
|
@ -121,8 +122,8 @@ class LongControl(): |
|
|
|
|
# Intention is to stop, switch to a different brake control until we stop |
|
|
|
|
elif self.long_control_state == LongCtrlState.stopping: |
|
|
|
|
# Keep applying brakes until the car is stopped |
|
|
|
|
if not CS.standstill or output_accel > CP.stopAccel: |
|
|
|
|
output_accel -= CP.stoppingDecelRate * DT_CTRL |
|
|
|
|
if not CS.standstill or output_accel > self.CP.stopAccel: |
|
|
|
|
output_accel -= self.CP.stoppingDecelRate * DT_CTRL |
|
|
|
|
output_accel = clip(output_accel, accel_limits[0], accel_limits[1]) |
|
|
|
|
self.reset(CS.vEgo) |
|
|
|
|
|
|
|
|
|