Files
dragonpilot/selfdrive/car/interfaces.py
T
Shane Smiskol f1f40c117a Add Disengage on Accelerator Toggle (#23977)
* Squashed commit of the following:

commit 953bcf0ecf8d03f0fec9ce0d5442cc660ae2347d
Merge: b4198608d 333257bad
Author: Shane Smiskol <shane@smiskol.com>
Date:   Fri Apr 1 19:58:06 2022 -0700

    Merge remote-tracking branch 'upstream/master' into disengage-on-gas

commit b4198608dac9595bfeb9443f95cd6c5d385cd62d
Merge: 24f90b2c8 0b9790dd2
Author: Shane Smiskol <shane@smiskol.com>
Date:   Fri Apr 1 14:32:54 2022 -0700

    Merge remote-tracking branch 'upstream/master' into disengage-on-gas

commit 24f90b2c8d6ae509c0776b6e33b743467aa08dee
Author: Shane Smiskol <shane@smiskol.com>
Date:   Thu Mar 31 14:07:52 2022 -0700

    revert changes and get ready for override

commit aa514df6b5e8431f0faa07f6b25eb5cb6c9f2749
Author: Shane Smiskol <shane@smiskol.com>
Date:   Wed Mar 30 20:52:24 2022 -0700

    temporary

commit c874e10c2555968c683f629c4582ab22e51d431f
Author: Shane Smiskol <shane@smiskol.com>
Date:   Wed Mar 30 00:30:13 2022 -0700

    move gasPressed to controlsd

commit fe670439dff5bc6dfc5963d79ca2febe0c5920c7
Merge: 49d3b6d11 81862fce7
Author: Shane Smiskol <shane@smiskol.com>
Date:   Wed Mar 30 00:15:48 2022 -0700

    Merge remote-tracking branch 'upstream/master' into disengage-on-gas

commit 49d3b6d1162893fa94b2294152f0718eeb4698ed
Merge: 475b27e74 d60c44e03
Author: Shane Smiskol <shane@smiskol.com>
Date:   Mon Mar 28 13:06:08 2022 -0700

    Merge remote-tracking branch 'upstream/master' into disengage-on-gas

commit 475b27e74fd6479f1d148e9ded1eca6ee476865c
Author: Shane Smiskol <shane@smiskol.com>
Date:   Thu Mar 24 20:24:59 2022 -0700

    update SAFETY.md

commit 0798eadb82749e12ecbaa86f4e57b21bd3dbc7e8
Author: Shane Smiskol <shane@smiskol.com>
Date:   Thu Mar 24 17:52:06 2022 -0700

     ➡️ 🔋

    bump

commit d2b64b89cf8d7265bc90848b4e3a2276c9a4cb78
Author: Shane Smiskol <shane@smiskol.com>
Date:   Thu Mar 24 16:19:34 2022 -0700

    these changes will be in border PR

    these changes will be border PR

commit bed31e63de2244c161729773978fef8a9246ddb5
Merge: 491417640 e91613bc6
Author: Shane Smiskol <shane@smiskol.com>
Date:   Thu Mar 24 16:17:31 2022 -0700

    Merge remote-tracking branch 'upstream/master' into disengage-on-gas

commit 49141764098e3a701ff123ead52de4656b31db4d
Merge: 9291e9f00 c88ced1f1
Author: Shane Smiskol <shane@smiskol.com>
Date:   Wed Mar 23 19:00:26 2022 -0700

    Merge remote-tracking branch 'upstream/master' into disengage-on-gas

commit 9291e9f0045780669b2ffa7f08fb10373c03b070
Merge: 2aed64157 99c02bdd2
Author: Shane Smiskol <shane@smiskol.com>
Date:   Fri Mar 18 19:03:13 2022 -0700

    Merge remote-tracking branch 'upstream/master' into disengage-on-gas

commit 2aed64157d6e9dc993d103a2c6abf7e643410562
Author: Shane Smiskol <shane@smiskol.com>
Date:   Fri Mar 18 19:03:03 2022 -0700

    Revert "send pre-enable state when gas is pressed"

    This reverts commit 8d82e697dc2efade307413e767d14b56b4d2d079.

commit a219defe5342efa731a957b2ff4fd86292c1f239
Author: Shane Smiskol <shane@smiskol.com>
Date:   Thu Mar 17 12:50:46 2022 -0700

    bump cereal

commit 8d82e697dc2efade307413e767d14b56b4d2d079
Author: Shane Smiskol <shane@smiskol.com>
Date:   Wed Mar 16 22:40:13 2022 -0700

    send pre-enable state when gas is pressed

    formatting and it's out

    forgot one

    allow gas press

    show toggle

    revert changes

    revert changes

commit 5eb4d1ab1b77ac65bdd901f692ebfb848d5187ca
Merge: bad1bdc74 db7b49c71
Author: Shane Smiskol <shane@smiskol.com>
Date:   Wed Mar 16 22:29:43 2022 -0700

    Merge remote-tracking branch 'upstream/master' into disengage-on-gas

commit bad1bdc7428c5d8a4a765b259da504f0ade84424
Author: Shane Smiskol <shane@smiskol.com>
Date:   Tue Mar 15 23:03:56 2022 -0700

    clean up a bit

commit 7516ed9b786536a07f00a92b9c1742ca252a01d1
Author: Shane Smiskol <shane@smiskol.com>
Date:   Tue Mar 15 22:55:09 2022 -0700

    these are null checks right now

commit 408f5f1d633521b29b08d966c9b387fa79dff0d6
Author: Shane Smiskol <shane@smiskol.com>
Date:   Tue Mar 15 22:51:14 2022 -0700

    should work

commit be1978e29c03d8843cf073cc9ddf84020fd2b378
Author: Shane Smiskol <shane@smiskol.com>
Date:   Tue Mar 15 22:36:16 2022 -0700

    stash

commit f0bd4c47e9d27061c6cd3b88765a7c10995f42db
Author: Shane Smiskol <shane@smiskol.com>
Date:   Tue Mar 15 22:26:24 2022 -0700

    this was flipped

commit d5b6e30389a727e8559331acd706422e1b246f60
Merge: 820b19894 5fe00fb77
Author: Shane Smiskol <shane@smiskol.com>
Date:   Tue Mar 15 22:25:49 2022 -0700

    Merge remote-tracking branch 'upstream/master' into disengage-on-gas

commit 820b1989496225df1f66f39b477f1e9402db1b19
Merge: 91763f9ff d7c758d4b
Author: Shane Smiskol <shane@smiskol.com>
Date:   Mon Mar 14 23:39:34 2022 -0700

    Merge remote-tracking branch 'upstream/master' into disengage-on-gas

commit 91763f9ff4321986babce1a7b1272fcf64c8f753
Author: Shane Smiskol <shane@smiskol.com>
Date:   Thu Feb 24 20:15:26 2022 -0800

    add icon from jozef 🔥

commit 1885c9e2bacd9351c7e421b1436dcbfbde238436
Merge: 1f591736a 9c70e8bca
Author: Shane Smiskol <shane@smiskol.com>
Date:   Thu Feb 24 20:08:07 2022 -0800

    Merge remote-tracking branch 'upstream/master' into disengage-on-gas

commit 1f591736a2767b1ed892c29ec5000cc7348f01c7
Merge: 465811f0b 7410160d0
Author: Jason Wen <47793918+sunnyhaibin@users.noreply.github.com>
Date:   Sat Feb 12 10:24:29 2022 -0500

    Merge branch 'master' into disengage-on-gas

commit 465811f0b4776e43a289398e4d4369362b7da58c
Author: Jason Wen <haibin.wen3@gmail.com>
Date:   Fri Feb 11 11:20:32 2022 -0500

    Add param to process replay

commit 0344363a533505435cff87eb33356b2364a4156f
Merge: 700efcb3f 3e915cf62
Author: Jason Wen <47793918+sunnyhaibin@users.noreply.github.com>
Date:   Fri Feb 11 11:07:31 2022 -0500

    Merge branch 'master' into disengage-on-gas

commit 700efcb3f444092f99ef10e9908f83402429d742
Author: Jason Wen <haibin.wen3@gmail.com>
Date:   Fri Feb 11 11:04:39 2022 -0500

    Add param to unsafeMode

commit 220ce272fee1f7f5ace2a04052605a6e4f95712b
Author: Jason Wen <haibin.wen3@gmail.com>
Date:   Fri Feb 11 10:54:16 2022 -0500

    Add param to unsafeMode

commit d273bb78acbc23ee5255e461fa71b2f0400a5e03
Author: Jason Wen <haibin.wen3@gmail.com>
Date:   Fri Feb 11 10:52:22 2022 -0500

    Resolve conflicts

commit 1a85afd60c2f0d3140dfa8e7cd574d6b88abd5e3
Author: Jason Wen <haibin.wen3@gmail.com>
Date:   Fri Feb 11 10:51:50 2022 -0500

    Resolve conflicts

commit e3be32afc2bb2423d29e2b4f85b3cff3fe72aab9
Author: Jason Wen <haibin.wen3@gmail.com>
Date:   Fri Feb 11 10:51:08 2022 -0500

    Resolve conflicts

commit f27203af3afe612173bf9a63e15c57118598b5b8
Author: Jason Wen <haibin.wen3@gmail.com>
Date:   Wed Jan 19 00:30:09 2022 -0500

    Add param to process replay

commit 04c0ad1a54f4fea5efe74b3203d9bdbd693b64a6
Author: Jason Wen <47793918+sunnyhaibin@users.noreply.github.com>
Date:   Wed Jan 19 00:28:49 2022 -0500

    Update interfaces.py

    Co-authored-by: Willem Melching <willem.melching@gmail.com>

commit 99cf13caeb4d9f2c95c25e1e78b6e353ea508cb6
Author: Jason Wen <haibin.wen3@gmail.com>
Date:   Sat Jan 15 00:03:38 2022 -0500

    Fix missing params lib

commit 2230254ca709625d591b0c73d1a6022c450f6ef6
Author: Jason Wen <haibin.wen3@gmail.com>
Date:   Fri Jan 14 23:38:46 2022 -0500

    Disengage on gas toggle

commit 87475e02cb63cc39c9b16edc67f303e02d17e6ef
Author: Jason Wen <haibin.wen3@gmail.com>
Date:   Fri Jan 14 23:24:00 2022 -0500

    Disengage on gas toggle

* bump

* use ALTERNATIVE_EXPERIENCE

* or it

* de-bump

* update refs

* update refs!

* you can just ctrl+click ALTERNATIVE_EXPERIENCE!

* already have a params

* update text
2022-04-04 21:59:52 -07:00

265 lines
9.2 KiB
Python

import os
import time
from abc import abstractmethod, ABC
from typing import Dict, Tuple, List
from cereal import car
from common.kalman.simple_kalman import KF1D
from common.realtime import DT_CTRL
from selfdrive.car import gen_empty_fingerprint
from common.conversions import Conversions as CV
from selfdrive.controls.lib.drive_helpers import V_CRUISE_MAX
from selfdrive.controls.lib.events import Events
from selfdrive.controls.lib.vehicle_model import VehicleModel
GearShifter = car.CarState.GearShifter
EventName = car.CarEvent.EventName
MAX_CTRL_SPEED = (V_CRUISE_MAX + 4) * CV.KPH_TO_MS
ACCEL_MAX = 2.0
ACCEL_MIN = -3.5
# generic car and radar interfaces
class CarInterfaceBase(ABC):
def __init__(self, CP, CarController, CarState):
self.CP = CP
self.VM = VehicleModel(CP)
self.frame = 0
self.steering_unpressed = 0
self.low_speed_alert = False
self.silent_steer_warning = True
if CarState is not None:
self.CS = CarState(CP)
self.cp = self.CS.get_can_parser(CP)
self.cp_cam = self.CS.get_cam_can_parser(CP)
self.cp_body = self.CS.get_body_can_parser(CP)
self.cp_loopback = self.CS.get_loopback_can_parser(CP)
self.CC = None
if CarController is not None:
self.CC = CarController(self.cp.dbc_name, CP, self.VM)
@staticmethod
def get_pid_accel_limits(CP, current_speed, cruise_speed):
return ACCEL_MIN, ACCEL_MAX
@staticmethod
@abstractmethod
def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None, disable_radar=False):
pass
@staticmethod
def init(CP, logcan, sendcan):
pass
@staticmethod
def get_steer_feedforward_default(desired_angle, v_ego):
# Proportional to realigning tire momentum: lateral acceleration.
# TODO: something with lateralPlan.curvatureRates
return desired_angle * (v_ego**2)
@classmethod
def get_steer_feedforward_function(cls):
return cls.get_steer_feedforward_default
# returns a set of default params to avoid repetition in car specific params
@staticmethod
def get_std_params(candidate, fingerprint):
ret = car.CarParams.new_message()
ret.carFingerprint = candidate
# standard ALC params
ret.steerControlType = car.CarParams.SteerControlType.torque
ret.minSteerSpeed = 0.
ret.wheelSpeedFactor = 1.0
ret.pcmCruise = True # openpilot's state is tied to the PCM's cruise state on most cars
ret.minEnableSpeed = -1. # enable is done by stock ACC, so ignore this
ret.steerRatioRear = 0. # no rear steering, at least on the listed cars aboveA
ret.openpilotLongitudinalControl = False
ret.stopAccel = -2.0
ret.stoppingDecelRate = 0.8 # brake_travel/s while trying to stop
ret.vEgoStopping = 0.5
ret.vEgoStarting = 0.5
ret.stoppingControl = True
ret.longitudinalTuning.deadzoneBP = [0.]
ret.longitudinalTuning.deadzoneV = [0.]
ret.longitudinalTuning.kf = 1.
ret.longitudinalTuning.kpBP = [0.]
ret.longitudinalTuning.kpV = [1.]
ret.longitudinalTuning.kiBP = [0.]
ret.longitudinalTuning.kiV = [1.]
# TODO estimate car specific lag, use .15s for now
ret.longitudinalActuatorDelayLowerBound = 0.15
ret.longitudinalActuatorDelayUpperBound = 0.15
ret.steerLimitTimer = 1.0
return ret
@abstractmethod
def update(self, c: car.CarControl, can_strings: List[bytes]) -> car.CarState:
pass
@abstractmethod
def apply(self, c: car.CarControl) -> Tuple[car.CarControl.Actuators, List[bytes]]:
pass
def create_common_events(self, cs_out, extra_gears=None, pcm_enable=True):
events = Events()
if cs_out.doorOpen:
events.add(EventName.doorOpen)
if cs_out.seatbeltUnlatched:
events.add(EventName.seatbeltNotLatched)
if cs_out.gearShifter != GearShifter.drive and (extra_gears is None or
cs_out.gearShifter not in extra_gears):
events.add(EventName.wrongGear)
if cs_out.gearShifter == GearShifter.reverse:
events.add(EventName.reverseGear)
if not cs_out.cruiseState.available:
events.add(EventName.wrongCarMode)
if cs_out.espDisabled:
events.add(EventName.espDisabled)
if cs_out.stockFcw:
events.add(EventName.stockFcw)
if cs_out.stockAeb:
events.add(EventName.stockAeb)
if cs_out.vEgo > MAX_CTRL_SPEED:
events.add(EventName.speedTooHigh)
if cs_out.cruiseState.nonAdaptive:
events.add(EventName.wrongCruiseMode)
if cs_out.brakeHoldActive and self.CP.openpilotLongitudinalControl:
events.add(EventName.brakeHold)
if cs_out.parkingBrake:
events.add(EventName.parkBrake)
# Handle permanent and temporary steering faults
self.steering_unpressed = 0 if cs_out.steeringPressed else self.steering_unpressed + 1
if cs_out.steerFaultTemporary:
# if the user overrode recently, show a less harsh alert
if self.silent_steer_warning or cs_out.standstill or self.steering_unpressed < int(1.5 / DT_CTRL):
self.silent_steer_warning = True
events.add(EventName.steerTempUnavailableSilent)
else:
events.add(EventName.steerTempUnavailable)
else:
self.silent_steer_warning = False
if cs_out.steerFaultPermanent:
events.add(EventName.steerUnavailable)
# we engage when pcm is active (rising edge)
if pcm_enable:
if cs_out.cruiseState.enabled and not self.CS.out.cruiseState.enabled:
events.add(EventName.pcmEnable)
elif not cs_out.cruiseState.enabled:
events.add(EventName.pcmDisable)
return events
class RadarInterfaceBase(ABC):
def __init__(self, CP):
self.pts = {}
self.delay = 0
self.radar_ts = CP.radarTimeStep
self.no_radar_sleep = 'NO_RADAR_SLEEP' in os.environ
def update(self, can_strings):
ret = car.RadarData.new_message()
if not self.no_radar_sleep:
time.sleep(self.radar_ts) # radard runs on RI updates
return ret
class CarStateBase(ABC):
def __init__(self, CP):
self.CP = CP
self.car_fingerprint = CP.carFingerprint
self.out = car.CarState.new_message()
self.cruise_buttons = 0
self.left_blinker_cnt = 0
self.right_blinker_cnt = 0
self.left_blinker_prev = False
self.right_blinker_prev = False
# Q = np.matrix([[10.0, 0.0], [0.0, 100.0]])
# R = 1e3
self.v_ego_kf = KF1D(x0=[[0.0], [0.0]],
A=[[1.0, DT_CTRL], [0.0, 1.0]],
C=[1.0, 0.0],
K=[[0.12287673], [0.29666309]])
def update_speed_kf(self, v_ego_raw):
if abs(v_ego_raw - self.v_ego_kf.x[0][0]) > 2.0: # Prevent large accelerations when car starts at non zero speed
self.v_ego_kf.x = [[v_ego_raw], [0.0]]
v_ego_x = self.v_ego_kf.update(v_ego_raw)
return float(v_ego_x[0]), float(v_ego_x[1])
def get_wheel_speeds(self, fl, fr, rl, rr, unit=CV.KPH_TO_MS):
factor = unit * self.CP.wheelSpeedFactor
wheelSpeeds = car.CarState.WheelSpeeds.new_message()
wheelSpeeds.fl = fl * factor
wheelSpeeds.fr = fr * factor
wheelSpeeds.rl = rl * factor
wheelSpeeds.rr = rr * factor
return wheelSpeeds
def update_blinker_from_lamp(self, blinker_time: int, left_blinker_lamp: bool, right_blinker_lamp: bool):
"""Update blinkers from lights. Enable output when light was seen within the last `blinker_time`
iterations"""
# TODO: Handle case when switching direction. Now both blinkers can be on at the same time
self.left_blinker_cnt = blinker_time if left_blinker_lamp else max(self.left_blinker_cnt - 1, 0)
self.right_blinker_cnt = blinker_time if right_blinker_lamp else max(self.right_blinker_cnt - 1, 0)
return self.left_blinker_cnt > 0, self.right_blinker_cnt > 0
def update_blinker_from_stalk(self, blinker_time: int, left_blinker_stalk: bool, right_blinker_stalk: bool):
"""Update blinkers from stalk position. When stalk is seen the blinker will be on for at least blinker_time,
or until the stalk is turned off, whichever is longer. If the opposite stalk direction is seen the blinker
is forced to the other side. On a rising edge of the stalk the timeout is reset."""
if left_blinker_stalk:
self.right_blinker_cnt = 0
if not self.left_blinker_prev:
self.left_blinker_cnt = blinker_time
if right_blinker_stalk:
self.left_blinker_cnt = 0
if not self.right_blinker_prev:
self.right_blinker_cnt = blinker_time
self.left_blinker_cnt = max(self.left_blinker_cnt - 1, 0)
self.right_blinker_cnt = max(self.right_blinker_cnt - 1, 0)
self.left_blinker_prev = left_blinker_stalk
self.right_blinker_prev = right_blinker_stalk
return bool(left_blinker_stalk or self.left_blinker_cnt > 0), bool(right_blinker_stalk or self.right_blinker_cnt > 0)
@staticmethod
def parse_gear_shifter(gear: str) -> car.CarState.GearShifter:
d: Dict[str, car.CarState.GearShifter] = {
'P': GearShifter.park, 'R': GearShifter.reverse, 'N': GearShifter.neutral,
'E': GearShifter.eco, 'T': GearShifter.manumatic, 'D': GearShifter.drive,
'S': GearShifter.sport, 'L': GearShifter.low, 'B': GearShifter.brake
}
return d.get(gear, GearShifter.unknown)
@staticmethod
def get_cam_can_parser(CP):
return None
@staticmethod
def get_body_can_parser(CP):
return None
@staticmethod
def get_loopback_can_parser(CP):
return None