|
|
|
@ -4,7 +4,6 @@ import numpy as np |
|
|
|
|
from common.numpy_fast import clip |
|
|
|
|
from common.realtime import DT_CTRL |
|
|
|
|
from cereal import log |
|
|
|
|
from selfdrive.controls.lib.drive_helpers import get_steer_max |
|
|
|
|
from selfdrive.controls.lib.latcontrol import LatControl, MIN_STEER_SPEED |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -34,7 +33,6 @@ class LatControlLQR(LatControl): |
|
|
|
|
def update(self, active, CS, CP, VM, params, last_actuators, desired_curvature, desired_curvature_rate): |
|
|
|
|
lqr_log = log.ControlsState.LateralLQRState.new_message() |
|
|
|
|
|
|
|
|
|
steers_max = get_steer_max(CP, CS.vEgo) |
|
|
|
|
torque_scale = (0.45 + CS.vEgo / 60.0)**2 # Scale actuator model with speed |
|
|
|
|
|
|
|
|
|
# Subtract offset. Zero angle should correspond to zero torque |
|
|
|
@ -71,16 +69,16 @@ class LatControlLQR(LatControl): |
|
|
|
|
i = self.i_lqr + self.ki * self.i_rate * error |
|
|
|
|
control = lqr_output + i |
|
|
|
|
|
|
|
|
|
if (error >= 0 and (control <= steers_max or i < 0.0)) or \ |
|
|
|
|
(error <= 0 and (control >= -steers_max or i > 0.0)): |
|
|
|
|
if (error >= 0 and (control <= self.steer_max or i < 0.0)) or \ |
|
|
|
|
(error <= 0 and (control >= -self.steer_max or i > 0.0)): |
|
|
|
|
self.i_lqr = i |
|
|
|
|
|
|
|
|
|
output_steer = lqr_output + self.i_lqr |
|
|
|
|
output_steer = clip(output_steer, -steers_max, steers_max) |
|
|
|
|
output_steer = clip(output_steer, -self.steer_max, self.steer_max) |
|
|
|
|
|
|
|
|
|
lqr_log.steeringAngleDeg = angle_steers_k |
|
|
|
|
lqr_log.i = self.i_lqr |
|
|
|
|
lqr_log.output = output_steer |
|
|
|
|
lqr_log.lqrOutput = lqr_output |
|
|
|
|
lqr_log.saturated = self._check_saturation(steers_max - abs(output_steer) < 1e-3, CS) |
|
|
|
|
lqr_log.saturated = self._check_saturation(self.steer_max - abs(output_steer) < 1e-3, CS) |
|
|
|
|
return output_steer, desired_angle, lqr_log |
|
|
|
|