|
|
|
@ -4,6 +4,7 @@ from cereal import log |
|
|
|
|
from common.numpy_fast import interp |
|
|
|
|
from selfdrive.controls.lib.latcontrol import LatControl, MIN_STEER_SPEED |
|
|
|
|
from selfdrive.controls.lib.pid import PIDController |
|
|
|
|
from selfdrive.controls.lib.drive_helpers import apply_deadzone |
|
|
|
|
from selfdrive.controls.lib.vehicle_model import ACCELERATION_DUE_TO_GRAVITY |
|
|
|
|
|
|
|
|
|
# At higher speeds (25+mph) we can assume: |
|
|
|
@ -22,13 +23,14 @@ LOW_SPEED_FACTOR = 200 |
|
|
|
|
JERK_THRESHOLD = 0.2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def set_torque_tune(tune, MAX_LAT_ACCEL=2.5, FRICTION=0.01): |
|
|
|
|
def set_torque_tune(tune, MAX_LAT_ACCEL=2.5, FRICTION=0.01, steering_angle_deadzone_deg=0.0): |
|
|
|
|
tune.init('torque') |
|
|
|
|
tune.torque.useSteeringAngle = True |
|
|
|
|
tune.torque.kp = 1.0 / MAX_LAT_ACCEL |
|
|
|
|
tune.torque.kf = 1.0 / MAX_LAT_ACCEL |
|
|
|
|
tune.torque.ki = 0.1 / MAX_LAT_ACCEL |
|
|
|
|
tune.torque.friction = FRICTION |
|
|
|
|
tune.torque.steeringAngleDeadzoneDeg = steering_angle_deadzone_deg |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class LatControlTorque(LatControl): |
|
|
|
@ -40,10 +42,7 @@ class LatControlTorque(LatControl): |
|
|
|
|
self.use_steering_angle = CP.lateralTuning.torque.useSteeringAngle |
|
|
|
|
self.friction = CP.lateralTuning.torque.friction |
|
|
|
|
self.kf = CP.lateralTuning.torque.kf |
|
|
|
|
|
|
|
|
|
def reset(self): |
|
|
|
|
super().reset() |
|
|
|
|
self.pid.reset() |
|
|
|
|
self.steering_angle_deadzone_deg = CP.lateralTuning.torque.steeringAngleDeadzoneDeg |
|
|
|
|
|
|
|
|
|
def update(self, active, CS, VM, params, last_actuators, desired_curvature, desired_curvature_rate, llk): |
|
|
|
|
pid_log = log.ControlsState.LateralTorqueState.new_message() |
|
|
|
@ -54,24 +53,27 @@ class LatControlTorque(LatControl): |
|
|
|
|
else: |
|
|
|
|
if self.use_steering_angle: |
|
|
|
|
actual_curvature = -VM.calc_curvature(math.radians(CS.steeringAngleDeg - params.angleOffsetDeg), CS.vEgo, params.roll) |
|
|
|
|
curvature_deadzone = abs(VM.calc_curvature(math.radians(self.steering_angle_deadzone_deg), CS.vEgo, 0.0)) |
|
|
|
|
else: |
|
|
|
|
actual_curvature_vm = -VM.calc_curvature(math.radians(CS.steeringAngleDeg - params.angleOffsetDeg), CS.vEgo, params.roll) |
|
|
|
|
actual_curvature_llk = llk.angularVelocityCalibrated.value[2] / CS.vEgo |
|
|
|
|
actual_curvature = interp(CS.vEgo, [2.0, 5.0], [actual_curvature_vm, actual_curvature_llk]) |
|
|
|
|
curvature_deadzone = 0.0 |
|
|
|
|
desired_lateral_accel = desired_curvature * CS.vEgo ** 2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# desired rate is the desired rate of change in the setpoint, not the absolute desired curvature |
|
|
|
|
desired_lateral_jerk = desired_curvature_rate * CS.vEgo ** 2 |
|
|
|
|
#desired_lateral_jerk = desired_curvature_rate * CS.vEgo ** 2 |
|
|
|
|
actual_lateral_accel = actual_curvature * CS.vEgo ** 2 |
|
|
|
|
lateral_accel_deadzone = curvature_deadzone * CS.vEgo ** 2 |
|
|
|
|
|
|
|
|
|
setpoint = desired_lateral_accel + LOW_SPEED_FACTOR * desired_curvature |
|
|
|
|
measurement = actual_lateral_accel + LOW_SPEED_FACTOR * actual_curvature |
|
|
|
|
error = setpoint - measurement |
|
|
|
|
error = apply_deadzone(setpoint - measurement, lateral_accel_deadzone) |
|
|
|
|
pid_log.error = error |
|
|
|
|
|
|
|
|
|
ff = desired_lateral_accel - params.roll * ACCELERATION_DUE_TO_GRAVITY |
|
|
|
|
# convert friction into lateral accel units for feedforward |
|
|
|
|
friction_compensation = interp(desired_lateral_jerk, [-JERK_THRESHOLD, JERK_THRESHOLD], [-self.friction, self.friction]) |
|
|
|
|
friction_compensation = interp(error, [-JERK_THRESHOLD, JERK_THRESHOLD], [-self.friction, self.friction]) |
|
|
|
|
ff += friction_compensation / self.kf |
|
|
|
|
freeze_integrator = CS.steeringRateLimited or CS.steeringPressed or CS.vEgo < 5 |
|
|
|
|
output_torque = self.pid.update(error, |
|
|
|
|