2025-01-29 09:09:58 +00:00
|
|
|
import numpy as np
|
|
|
|
from cereal import log
|
2024-09-03 16:09:00 +09:00
|
|
|
from openpilot.common.realtime import DT_CTRL, DT_MDL
|
|
|
|
from openpilot.selfdrive.modeld.constants import ModelConstants
|
|
|
|
import numpy as np
|
2023-09-27 15:45:31 -07:00
|
|
|
|
|
|
|
MIN_SPEED = 1.0
|
|
|
|
CONTROL_N = 17
|
|
|
|
CAR_ROTATION_RADIUS = 0.0
|
2025-01-29 09:09:58 +00:00
|
|
|
# This is a turn radius smaller than most cars can achieve
|
|
|
|
MAX_CURVATURE = 0.2
|
2023-09-27 15:45:31 -07:00
|
|
|
|
|
|
|
# EU guidelines
|
|
|
|
MAX_LATERAL_JERK = 5.0
|
|
|
|
MAX_VEL_ERR = 5.0
|
|
|
|
|
2024-09-03 16:09:00 +09:00
|
|
|
def apply_deadzone(error, deadzone):
|
|
|
|
if error > deadzone:
|
|
|
|
error -= deadzone
|
|
|
|
elif error < - deadzone:
|
|
|
|
error += deadzone
|
|
|
|
else:
|
|
|
|
error = 0.
|
|
|
|
return error
|
|
|
|
|
2025-02-08 17:41:36 +09:00
|
|
|
def get_lag_adjusted_curvature(CP, v_ego, psis, curvatures, steer_actuator_delay):
|
2024-09-03 16:09:00 +09:00
|
|
|
if len(psis) != CONTROL_N:
|
|
|
|
psis = [0.0]*CONTROL_N
|
|
|
|
curvatures = [0.0]*CONTROL_N
|
|
|
|
v_ego = max(MIN_SPEED, v_ego)
|
|
|
|
|
|
|
|
# TODO this needs more thought, use .2s extra for now to estimate other delays
|
|
|
|
delay = max(0.01, steer_actuator_delay)
|
|
|
|
|
|
|
|
# MPC can plan to turn the wheel and turn back before t_delay. This means
|
|
|
|
# in high delay cases some corrections never even get commanded. So just use
|
|
|
|
# psi to calculate a simple linearization of desired curvature
|
|
|
|
current_curvature_desired = curvatures[0]
|
|
|
|
psi = np.interp(delay, ModelConstants.T_IDXS[:CONTROL_N], psis)
|
|
|
|
average_curvature_desired = psi / (v_ego * delay)
|
|
|
|
desired_curvature = 2 * average_curvature_desired - current_curvature_desired
|
|
|
|
|
|
|
|
# This is the "desired rate of the setpoint" not an actual desired rate
|
|
|
|
max_curvature_rate = MAX_LATERAL_JERK / (v_ego**2) # inexact calculation, check https://github.com/commaai/openpilot/pull/24755
|
|
|
|
safe_desired_curvature = np.clip(desired_curvature,
|
|
|
|
current_curvature_desired - max_curvature_rate * DT_MDL,
|
|
|
|
current_curvature_desired + max_curvature_rate * DT_MDL)
|
|
|
|
return safe_desired_curvature
|
|
|
|
|
2024-02-21 23:02:43 +00:00
|
|
|
def clip_curvature(v_ego, prev_curvature, new_curvature):
|
2025-01-29 09:09:58 +00:00
|
|
|
new_curvature = np.clip(new_curvature, -MAX_CURVATURE, MAX_CURVATURE)
|
2023-09-27 15:45:31 -07:00
|
|
|
v_ego = max(MIN_SPEED, v_ego)
|
|
|
|
max_curvature_rate = MAX_LATERAL_JERK / (v_ego**2) # inexact calculation, check https://github.com/commaai/openpilot/pull/24755
|
2025-01-29 09:09:58 +00:00
|
|
|
safe_desired_curvature = np.clip(new_curvature,
|
2024-02-21 23:02:43 +00:00
|
|
|
prev_curvature - max_curvature_rate * DT_CTRL,
|
|
|
|
prev_curvature + max_curvature_rate * DT_CTRL)
|
|
|
|
|
|
|
|
return safe_desired_curvature
|
2023-09-27 15:45:31 -07:00
|
|
|
|
|
|
|
|
|
|
|
def get_speed_error(modelV2: log.ModelDataV2, v_ego: float) -> float:
|
|
|
|
# ToDo: Try relative error, and absolute speed
|
|
|
|
if len(modelV2.temporalPose.trans):
|
2025-01-29 09:09:58 +00:00
|
|
|
vel_err = np.clip(modelV2.temporalPose.trans[0] - v_ego, -MAX_VEL_ERR, MAX_VEL_ERR)
|
2023-09-27 15:45:31 -07:00
|
|
|
return float(vel_err)
|
|
|
|
return 0.0
|