mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-08-31 13:13:44 +08:00
Compare commits
25 Commits
Scotty
...
SunnyMerge
| Author | SHA1 | Date | |
|---|---|---|---|
| 3a5b3411bc | |||
| 0724c290f2 | |||
| 076fbbe102 | |||
| f56b049010 | |||
| eb1e70d9c7 | |||
| 039e89d92a | |||
| 42b6ecb535 | |||
| 827c9cede9 | |||
| 6753b8f490 | |||
| 34894ffeab | |||
| 0a9046c594 | |||
| 8b47b3c1f8 | |||
| f13335fe67 | |||
| edf384d37e | |||
| 09ef4b64ff | |||
| fef711a206 | |||
| b5cf8a520d | |||
| bd4ed9d316 | |||
| f047a7d008 | |||
| 2e884610c1 | |||
| 87c29b0ee1 | |||
| c5113e8ea6 | |||
| 88f7cb5f05 | |||
| 14b3d0ca38 | |||
| d52a823fa3 |
+1
-1
Submodule opendbc_repo updated: 5da91a7ae6...648deb3a4b
@@ -1,6 +1,7 @@
|
|||||||
from cereal import car, log, custom
|
from cereal import car, log, custom
|
||||||
import cereal.messaging as messaging
|
import cereal.messaging as messaging
|
||||||
from opendbc.car import DT_CTRL, structs
|
from opendbc.car import DT_CTRL, structs
|
||||||
|
from opendbc.car.gm.values import GMFlags
|
||||||
from opendbc.car.interfaces import MAX_CTRL_SPEED
|
from opendbc.car.interfaces import MAX_CTRL_SPEED
|
||||||
|
|
||||||
from openpilot.selfdrive.selfdrived.events import Events
|
from openpilot.selfdrive.selfdrived.events import Events
|
||||||
@@ -103,13 +104,26 @@ class CarSpecificEvents:
|
|||||||
if CS.vEgo < self.CP.minEnableSpeed and not (CS.standstill and CS.brake >= 20 and
|
if CS.vEgo < self.CP.minEnableSpeed and not (CS.standstill and CS.brake >= 20 and
|
||||||
self.CP.networkLocation == NetworkLocation.fwdCamera):
|
self.CP.networkLocation == NetworkLocation.fwdCamera):
|
||||||
events.add(EventName.belowEngageSpeed)
|
events.add(EventName.belowEngageSpeed)
|
||||||
if CS.cruiseState.standstill:
|
if CS.cruiseState.standstill and not self.CP.autoResumeSng:
|
||||||
events.add(EventName.resumeRequired)
|
events.add(EventName.resumeRequired)
|
||||||
|
if CS.vEgo < self.CP.minSteerSpeed:
|
||||||
|
events.add(EventName.belowSteerSpeed)
|
||||||
|
|
||||||
|
if (self.CP.flags & GMFlags.CC_LONG) and CS.vEgo < self.CP.minEnableSpeed and CS.cruiseState.enabled:
|
||||||
|
events.add(EventName.speedTooLow)
|
||||||
|
|
||||||
elif self.CP.brand == 'volkswagen':
|
elif self.CP.brand == 'volkswagen':
|
||||||
events = self.create_common_events(CS, CS_prev, extra_gears=[GearShifter.eco, GearShifter.sport, GearShifter.manumatic],
|
events = self.create_common_events(CS, CS_prev, extra_gears=[GearShifter.eco, GearShifter.sport, GearShifter.manumatic],
|
||||||
pcm_enable=self.CP.pcmCruise)
|
pcm_enable=self.CP.pcmCruise)
|
||||||
|
|
||||||
|
# Low speed steer alert hysteresis logic
|
||||||
|
if (self.CP.minSteerSpeed - 1e-3) > VWCarControllerParams.DEFAULT_MIN_STEER_SPEED and CS.vEgo < (self.CP.minSteerSpeed + 1.):
|
||||||
|
self.low_speed_alert = True
|
||||||
|
elif CS.vEgo > (self.CP.minSteerSpeed + 2.):
|
||||||
|
self.low_speed_alert = False
|
||||||
|
if self.low_speed_alert:
|
||||||
|
events.add(EventName.belowSteerSpeed)
|
||||||
|
|
||||||
if self.CP.openpilotLongitudinalControl:
|
if self.CP.openpilotLongitudinalControl:
|
||||||
if CS.vEgo < self.CP.minEnableSpeed + 0.5:
|
if CS.vEgo < self.CP.minEnableSpeed + 0.5:
|
||||||
events.add(EventName.belowEngageSpeed)
|
events.add(EventName.belowEngageSpeed)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ from openpilot.common.params import Params
|
|||||||
from openpilot.common.realtime import config_realtime_process, Priority, Ratekeeper
|
from openpilot.common.realtime import config_realtime_process, Priority, Ratekeeper
|
||||||
from openpilot.common.swaglog import cloudlog, ForwardingHandler
|
from openpilot.common.swaglog import cloudlog, ForwardingHandler
|
||||||
|
|
||||||
from opendbc.car import DT_CTRL, structs
|
from opendbc.car import DT_CTRL, structs, ButtonType
|
||||||
from opendbc.car.can_definitions import CanData, CanRecvCallable, CanSendCallable
|
from opendbc.car.can_definitions import CanData, CanRecvCallable, CanSendCallable
|
||||||
from opendbc.car.carlog import carlog
|
from opendbc.car.carlog import carlog
|
||||||
from opendbc.car.fw_versions import ObdCallback
|
from opendbc.car.fw_versions import ObdCallback
|
||||||
@@ -80,6 +80,7 @@ class Car:
|
|||||||
self.CS_prev = car.CarState.new_message()
|
self.CS_prev = car.CarState.new_message()
|
||||||
self.CS_SP_prev = custom.CarStateSP.new_message()
|
self.CS_SP_prev = custom.CarStateSP.new_message()
|
||||||
self.initialized_prev = False
|
self.initialized_prev = False
|
||||||
|
self.resume_prev_button = False
|
||||||
|
|
||||||
self.last_actuators_output = structs.CarControl.Actuators()
|
self.last_actuators_output = structs.CarControl.Actuators()
|
||||||
|
|
||||||
@@ -217,12 +218,17 @@ class Car:
|
|||||||
self.v_cruise_helper.update_v_cruise(CS, self.sm['carControl'].enabled, self.is_metric)
|
self.v_cruise_helper.update_v_cruise(CS, self.sm['carControl'].enabled, self.is_metric)
|
||||||
if self.sm['carControl'].enabled and not self.CC_prev.enabled:
|
if self.sm['carControl'].enabled and not self.CC_prev.enabled:
|
||||||
# Use CarState w/ buttons from the step selfdrived enables on
|
# Use CarState w/ buttons from the step selfdrived enables on
|
||||||
self.v_cruise_helper.initialize_v_cruise(self.CS_prev, self.experimental_mode, self.dynamic_experimental_control)
|
self.v_cruise_helper.initialize_v_cruise(self.CS_prev, self.experimental_mode, self.dynamic_experimental_control, self.resume_prev_button)
|
||||||
|
|
||||||
# TODO: mirror the carState.cruiseState struct?
|
# TODO: mirror the carState.cruiseState struct?
|
||||||
CS.vCruise = float(self.v_cruise_helper.v_cruise_kph)
|
CS.vCruise = float(self.v_cruise_helper.v_cruise_kph)
|
||||||
CS.vCruiseCluster = float(self.v_cruise_helper.v_cruise_cluster_kph)
|
CS.vCruiseCluster = float(self.v_cruise_helper.v_cruise_cluster_kph)
|
||||||
|
|
||||||
|
if any(be.type in (ButtonType.accelCruise, ButtonType.resumeCruise) for be in CS.buttonEvents):
|
||||||
|
self.resume_prev_button = True
|
||||||
|
elif any(be.type in (ButtonType.decelCruise, ButtonType.setCruise) for be in CS.buttonEvents):
|
||||||
|
self.resume_prev_button = False
|
||||||
|
|
||||||
return CS, CS_SP, RD
|
return CS, CS_SP, RD
|
||||||
|
|
||||||
def state_publish(self, CS: car.CarState, CS_SP: custom.CarStateSP, RD: structs.RadarDataT | None):
|
def state_publish(self, CS: car.CarState, CS_SP: custom.CarStateSP, RD: structs.RadarDataT | None):
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import math
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from cereal import car
|
from cereal import car
|
||||||
|
from opendbc.car.gm.values import CC_ONLY_CAR, GMFlags
|
||||||
from openpilot.common.constants import CV
|
from openpilot.common.constants import CV
|
||||||
from openpilot.sunnypilot.selfdrive.car.cruise_ext import VCruiseHelperSP
|
from openpilot.sunnypilot.selfdrive.car.cruise_ext import VCruiseHelperSP
|
||||||
|
|
||||||
@@ -33,6 +34,7 @@ class VCruiseHelper(VCruiseHelperSP):
|
|||||||
def __init__(self, CP):
|
def __init__(self, CP):
|
||||||
VCruiseHelperSP.__init__(self)
|
VCruiseHelperSP.__init__(self)
|
||||||
self.CP = CP
|
self.CP = CP
|
||||||
|
self.gm_cc_only = self.CP.carFingerprint in CC_ONLY_CAR and self.CP.flags & GMFlags.CC_LONG.value
|
||||||
self.v_cruise_kph = V_CRUISE_UNSET
|
self.v_cruise_kph = V_CRUISE_UNSET
|
||||||
self.v_cruise_cluster_kph = V_CRUISE_UNSET
|
self.v_cruise_cluster_kph = V_CRUISE_UNSET
|
||||||
self.v_cruise_kph_last = 0
|
self.v_cruise_kph_last = 0
|
||||||
@@ -47,7 +49,7 @@ class VCruiseHelper(VCruiseHelperSP):
|
|||||||
self.v_cruise_kph_last = self.v_cruise_kph
|
self.v_cruise_kph_last = self.v_cruise_kph
|
||||||
|
|
||||||
if CS.cruiseState.available:
|
if CS.cruiseState.available:
|
||||||
if not self.CP.pcmCruise:
|
if self.gm_cc_only or not self.CP.pcmCruise:
|
||||||
# if stock cruise is completely disabled, then we can use our own set speed logic
|
# if stock cruise is completely disabled, then we can use our own set speed logic
|
||||||
self._update_v_cruise_non_pcm(CS, enabled, is_metric)
|
self._update_v_cruise_non_pcm(CS, enabled, is_metric)
|
||||||
self.v_cruise_cluster_kph = self.v_cruise_kph
|
self.v_cruise_cluster_kph = self.v_cruise_kph
|
||||||
@@ -125,15 +127,16 @@ class VCruiseHelper(VCruiseHelperSP):
|
|||||||
self.button_timers[b.type.raw] = 1 if b.pressed else 0
|
self.button_timers[b.type.raw] = 1 if b.pressed else 0
|
||||||
self.button_change_states[b.type.raw] = {"standstill": CS.cruiseState.standstill, "enabled": enabled}
|
self.button_change_states[b.type.raw] = {"standstill": CS.cruiseState.standstill, "enabled": enabled}
|
||||||
|
|
||||||
def initialize_v_cruise(self, CS, experimental_mode: bool, dynamic_experimental_control: bool) -> None:
|
def initialize_v_cruise(self, CS, experimental_mode: bool, dynamic_experimental_control, resume_prev_button: bool) -> None:
|
||||||
# initializing is handled by the PCM
|
# initializing is handled by the PCM
|
||||||
if self.CP.pcmCruise:
|
if self.CP.pcmCruise and not self.gm_cc_only:
|
||||||
return
|
return
|
||||||
|
|
||||||
initial_experimental_mode = experimental_mode and not dynamic_experimental_control
|
initial_experimental_mode = experimental_mode and not dynamic_experimental_control
|
||||||
initial = V_CRUISE_INITIAL_EXPERIMENTAL_MODE if initial_experimental_mode else V_CRUISE_INITIAL
|
initial = V_CRUISE_INITIAL_EXPERIMENTAL_MODE if initial_experimental_mode else V_CRUISE_INITIAL
|
||||||
|
|
||||||
if any(b.type in (ButtonType.accelCruise, ButtonType.resumeCruise) for b in CS.buttonEvents) and self.v_cruise_initialized:
|
if (any(b.type in (ButtonType.accelCruise, ButtonType.resumeCruise) for b in CS.buttonEvents)
|
||||||
|
and self.v_cruise_initialized or (self.gm_cc_only and resume_prev_button)):
|
||||||
self.v_cruise_kph = self.v_cruise_kph_last
|
self.v_cruise_kph = self.v_cruise_kph_last
|
||||||
else:
|
else:
|
||||||
self.v_cruise_kph = int(round(np.clip(CS.vEgo * CV.MS_TO_KPH, initial, V_CRUISE_MAX)))
|
self.v_cruise_kph = int(round(np.clip(CS.vEgo * CV.MS_TO_KPH, initial, V_CRUISE_MAX)))
|
||||||
|
|||||||
@@ -133,6 +133,9 @@ class Controls(ControlsExt, ModelStateBase):
|
|||||||
pid_accel_limits = self.CI.get_pid_accel_limits(self.CP, CS.vEgo, CS.vCruise * CV.KPH_TO_MS)
|
pid_accel_limits = self.CI.get_pid_accel_limits(self.CP, CS.vEgo, CS.vCruise * CV.KPH_TO_MS)
|
||||||
actuators.accel = float(self.LoC.update(CC.longActive, CS, long_plan.aTarget, long_plan.shouldStop, pid_accel_limits))
|
actuators.accel = float(self.LoC.update(CC.longActive, CS, long_plan.aTarget, long_plan.shouldStop, pid_accel_limits))
|
||||||
|
|
||||||
|
if len(long_plan.speeds):
|
||||||
|
actuators.speed = long_plan.speeds[-1]
|
||||||
|
|
||||||
# Steering PID loop and lateral MPC
|
# Steering PID loop and lateral MPC
|
||||||
# Reset desired curvature to current to avoid violating the limits on engage
|
# Reset desired curvature to current to avoid violating the limits on engage
|
||||||
new_desired_curvature = model_v2.action.desiredCurvature if CC.latActive else self.curvature
|
new_desired_curvature = model_v2.action.desiredCurvature if CC.latActive else self.curvature
|
||||||
|
|||||||
@@ -63,3 +63,24 @@ def get_curvature_from_plan(yaws, yaw_rates, t_idxs, vego, action_t):
|
|||||||
psi_target = np.interp(action_t, t_idxs, yaws)
|
psi_target = np.interp(action_t, t_idxs, yaws)
|
||||||
psi_rate = yaw_rates[0]
|
psi_rate = yaw_rates[0]
|
||||||
return curv_from_psis(psi_target, psi_rate, vego, action_t)
|
return curv_from_psis(psi_target, psi_rate, vego, action_t)
|
||||||
|
|
||||||
|
def interp(x, xp, fp):
|
||||||
|
N = len(xp)
|
||||||
|
def get_interp(xv):
|
||||||
|
hi = 0
|
||||||
|
while hi < N and xv > xp[hi]:
|
||||||
|
hi += 1
|
||||||
|
low = hi - 1
|
||||||
|
return fp[-1] if hi == N and xv > xp[low] else (
|
||||||
|
fp[0] if hi == 0 else
|
||||||
|
(xv - xp[low]) * (fp[hi] - fp[low]) / (xp[hi] - xp[low]) + fp[low])
|
||||||
|
return [get_interp(v) for v in x] if hasattr(x, '__iter__') else get_interp(x)
|
||||||
|
|
||||||
|
def apply_deadzone(error, deadzone):
|
||||||
|
if error > deadzone:
|
||||||
|
error -= deadzone
|
||||||
|
elif error < -deadzone:
|
||||||
|
error += deadzone
|
||||||
|
else:
|
||||||
|
error = 0.
|
||||||
|
return error
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
from cereal import car
|
from cereal import car
|
||||||
from openpilot.common.realtime import DT_CTRL
|
from openpilot.common.realtime import DT_CTRL
|
||||||
from openpilot.selfdrive.controls.lib.drive_helpers import CONTROL_N
|
from openpilot.selfdrive.controls.lib.drive_helpers import CONTROL_N, apply_deadzone, interp
|
||||||
from openpilot.common.pid import PIDController
|
from openpilot.common.pid import PIDController
|
||||||
from openpilot.selfdrive.modeld.constants import ModelConstants
|
from openpilot.selfdrive.modeld.constants import ModelConstants
|
||||||
|
|
||||||
@@ -80,8 +80,10 @@ class LongControl:
|
|||||||
self.reset()
|
self.reset()
|
||||||
|
|
||||||
else: # LongCtrlState.pid
|
else: # LongCtrlState.pid
|
||||||
|
deadzone = interp(CS.vEgo, self.CP.longitudinalTuning.deadzoneBPDEPRECATED, self.CP.longitudinalTuning.deadzoneVDEPRECATED)
|
||||||
error = a_target - CS.aEgo
|
error = a_target - CS.aEgo
|
||||||
output_accel = self.pid.update(error, speed=CS.vEgo,
|
error_deadzone = apply_deadzone(error, deadzone)
|
||||||
|
output_accel = self.pid.update(error_deadzone, speed=CS.vEgo,
|
||||||
feedforward=a_target)
|
feedforward=a_target)
|
||||||
|
|
||||||
self.last_output_accel = np.clip(output_accel, accel_limits[0], accel_limits[1])
|
self.last_output_accel = np.clip(output_accel, accel_limits[0], accel_limits[1])
|
||||||
|
|||||||
Reference in New Issue
Block a user