selfdrive/car: ban cereal and capnp (#33208)
* ban cereal and msgq * common too * do toyota/values.py * do all fingerprints * example without builder * this still works, but no type checking anymore * stash * wtf, how does this work * okay actually not bad * safe * epic! * stash data_structures.py * some clean up * hell yeah * clean up old file * add to delete * delete This reverts commitpull/33386/head90239b7797
. * switch more CarParams stuff over remove unused * fix car tests by removing cereal! mypy forgets about dataclass if we wrap it :( * fix this too * fix this too * remove more cereal and add some good hyundai tests * bunch more typing * override default with 20hz radar * temp capnp converter helper * more lateralTuning * small union replicator is better than what i was trying, and fixes mypy dynamic typing issues * can keep all this the same now! * type ret: CarParams, add more missing structs, revert lateralTuning changes (smaller diff!) * revert more * get first enum automatically, but ofc mypy doesn't pick up the new metaclass so can't use :( would have been `CarParams.NetworkLocation()` * Revert "get first enum automatically, but ofc mypy doesn't pick up the new metaclass so can't use :(" This reverts commitbb28b228be
. * remove cereal from car_helpers (TODO: caching) * remove a bunch of temp lines * use dataclass_transform! * remove some car.CarParams from the interfaces * remove rest of car.CarParams from the interfaces * same which() API * sort * from cereal/cache from fingerprinting! * more typing * dataclass to capnp helper for CarParams, cached it since it's kinda slow * (partial) fix process replay fingerprintig for new API * latcontrollers take capnp * forgot this * fix test_models * fix unit tests * not here * VehicleModel and controller still takes capnp CP since they get it from Params() * fix modeld test * more fix * need to namespace to structs, since CarState is both class and struct * this was never in the base class?! * clean that up again * fix import error fix import error * cmts and more structs * remove some more cereal from toyota + convert CarState to capnp * bruh this was wrong * replace more cereal * EventName is one of the last things... * replace a bunch more cereal.car * missing imports * more * can fix this typing now * proper toyota+others CS typing! * mypy can detect return type of CS.update() now * fix redeclaration of cruise_buttons type * mypy is only complaining about events now * temp fix * add carControl struct * replace CarControl i hope there's no circular imports in hyundai's CC * fine now * lol this was wrong too * fix crash * include my failed attempts at recursively converting to dataclass (doesn't implicitly convert types/recursively :( ) but attrs does, maybe will switch in the future * clean up * try out attr.s for its converter (doesn't work recursively yet, but interesting!) * Revert "try out attr.s for its converter (doesn't work recursively yet, but interesting!)" This reverts commitff2434f7bb
. * test processes doesn't fail anymore (on toyota)! * fix honda crash * stash * Revert "stash" This reverts commitc1762af4e7
. * remove a bunch more cereal! * LET'S GOOO * fix these tests * and these * and that * stash, something is wrong with hyundai enable * Revert "stash, something is wrong with hyundai enable" This reverts commit39cf327def
. * forgot these * remove cereal from fw_versions * Revert "remove cereal from fw_versions" This reverts commit232b37cd40
. * remove rest of the cereal exceptions! * fix that * add typing to radard since I didn't realize RI.update() switched from cereal to structs * and here too! * add TODO for slots * needed CS to be capnp, fix comparisons, and type hint car_specific so it's easier to catch type issues (capnp isn't detected by mypy :( ) * remove the struct converter * save ~4-5% CPU at 100hz, we don't modify after so no need to deepcopy btw pickle.loads(pickle.dumps()) is faster by ~1% CPU * deepcopy -> copy: we can technically make a reference, but copy is almost free and less error-prone saves ~1% CPU * add non-copying asdict function * should save ~3% CPU (still 4% above baseline) * fix that, no dict support * ~27% decrease in time for 20k iterations on 3X (3.37857 -> 2.4821s) * give a better name * fix * dont support none, capitalize * sheesh, this called type() on every field * remove CS.events, clean up * bump card % * this was a bug on master! * add a which enum * default to pid * revert * update refs * not needed, but consistent * just Ecu * don't need to do this in this pr * clean up * no cast * consistent typing * rm * fix * can do this if we're desperate for the last few % * Revert "can do this if we're desperate for the last few %" This reverts commit18e11ac788
. * type this * don't need to convert carControl * i guess don't support set either * fix CP type hint * simplify that old-commit-hash:6a15c42143
parent
8315623257
commit
95224db413
98 changed files with 1051 additions and 485 deletions
@ -1,30 +1,28 @@ |
|||||||
#!/usr/bin/env python3 |
#!/usr/bin/env python3 |
||||||
from collections import defaultdict |
from collections import defaultdict |
||||||
|
|
||||||
from cereal import car |
from openpilot.selfdrive.car.structs import CarParams |
||||||
from openpilot.selfdrive.car.ford.values import get_platform_codes |
from openpilot.selfdrive.car.ford.values import get_platform_codes |
||||||
from openpilot.selfdrive.car.ford.fingerprints import FW_VERSIONS |
from openpilot.selfdrive.car.ford.fingerprints import FW_VERSIONS |
||||||
|
|
||||||
Ecu = car.CarParams.Ecu |
Ecu = CarParams.Ecu |
||||||
ECU_NAME = {v: k for k, v in Ecu.schema.enumerants.items()} |
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__": |
if __name__ == "__main__": |
||||||
cars_for_code: defaultdict = defaultdict(lambda: defaultdict(set)) |
cars_for_code: defaultdict = defaultdict(lambda: defaultdict(set)) |
||||||
|
|
||||||
for car_model, ecus in FW_VERSIONS.items(): |
for car_model, ecus in FW_VERSIONS.items(): |
||||||
print(car_model) |
print(car_model) |
||||||
for ecu in sorted(ecus, key=lambda x: int(x[0])): |
for ecu in sorted(ecus): |
||||||
platform_codes = get_platform_codes(ecus[ecu]) |
platform_codes = get_platform_codes(ecus[ecu]) |
||||||
for code in platform_codes: |
for code in platform_codes: |
||||||
cars_for_code[ecu][code].add(car_model) |
cars_for_code[ecu][code].add(car_model) |
||||||
|
|
||||||
print(f' (Ecu.{ECU_NAME[ecu[0]]}, {hex(ecu[1])}, {ecu[2]}):') |
print(f' (Ecu.{ecu[0]}, {hex(ecu[1])}, {ecu[2]}):') |
||||||
print(f' Codes: {sorted(platform_codes)}') |
print(f' Codes: {sorted(platform_codes)}') |
||||||
print() |
print() |
||||||
|
|
||||||
print('\nCar models vs. platform codes:') |
print('\nCar models vs. platform codes:') |
||||||
for ecu, codes in cars_for_code.items(): |
for ecu, codes in cars_for_code.items(): |
||||||
print(f' (Ecu.{ECU_NAME[ecu[0]]}, {hex(ecu[1])}, {ecu[2]}):') |
print(f' (Ecu.{ecu[0]}, {hex(ecu[1])}, {ecu[2]}):') |
||||||
for code, cars in codes.items(): |
for code, cars in codes.items(): |
||||||
print(f' {code!r}: {sorted(map(str, cars))}') |
print(f' {code!r}: {sorted(map(str, cars))}') |
||||||
|
@ -1,22 +1,21 @@ |
|||||||
#!/usr/bin/env python3 |
#!/usr/bin/env python3 |
||||||
from cereal import car |
from openpilot.selfdrive.car.structs import CarParams |
||||||
from openpilot.selfdrive.car.hyundai.values import PLATFORM_CODE_ECUS, get_platform_codes |
from openpilot.selfdrive.car.hyundai.values import PLATFORM_CODE_ECUS, get_platform_codes |
||||||
from openpilot.selfdrive.car.hyundai.fingerprints import FW_VERSIONS |
from openpilot.selfdrive.car.hyundai.fingerprints import FW_VERSIONS |
||||||
|
|
||||||
Ecu = car.CarParams.Ecu |
Ecu = CarParams.Ecu |
||||||
ECU_NAME = {v: k for k, v in Ecu.schema.enumerants.items()} |
|
||||||
|
|
||||||
if __name__ == "__main__": |
if __name__ == "__main__": |
||||||
for car_model, ecus in FW_VERSIONS.items(): |
for car_model, ecus in FW_VERSIONS.items(): |
||||||
print() |
print() |
||||||
print(car_model) |
print(car_model) |
||||||
for ecu in sorted(ecus, key=lambda x: int(x[0])): |
for ecu in sorted(ecus): |
||||||
if ecu[0] not in PLATFORM_CODE_ECUS: |
if ecu[0] not in PLATFORM_CODE_ECUS: |
||||||
continue |
continue |
||||||
|
|
||||||
platform_codes = get_platform_codes(ecus[ecu]) |
platform_codes = get_platform_codes(ecus[ecu]) |
||||||
codes = {code for code, _ in platform_codes} |
codes = {code for code, _ in platform_codes} |
||||||
dates = {date for _, date in platform_codes if date is not None} |
dates = {date for _, date in platform_codes if date is not None} |
||||||
print(f' (Ecu.{ECU_NAME[ecu[0]]}, {hex(ecu[1])}, {ecu[2]}):') |
print(f' (Ecu.{ecu[0]}, {hex(ecu[1])}, {ecu[2]}):') |
||||||
print(f' Codes: {codes}') |
print(f' Codes: {codes}') |
||||||
print(f' Dates: {dates}') |
print(f' Dates: {dates}') |
||||||
|
@ -1,5 +1,6 @@ |
|||||||
from openpilot.selfdrive.car.interfaces import CarControllerBase |
from openpilot.selfdrive.car.interfaces import CarControllerBase |
||||||
|
|
||||||
|
|
||||||
class CarController(CarControllerBase): |
class CarController(CarControllerBase): |
||||||
def update(self, CC, CS, now_nanos): |
def update(self, CC, CS, now_nanos): |
||||||
return CC.actuators.as_builder(), [] |
return CC.actuators, [] |
||||||
|
@ -1,7 +1,7 @@ |
|||||||
from cereal import car |
from openpilot.selfdrive.car import structs |
||||||
from openpilot.selfdrive.car.interfaces import CarStateBase |
from openpilot.selfdrive.car.interfaces import CarStateBase |
||||||
|
|
||||||
|
|
||||||
class CarState(CarStateBase): |
class CarState(CarStateBase): |
||||||
def update(self, *_) -> car.CarState: |
def update(self, *_) -> structs.CarState: |
||||||
return car.CarState.new_message() |
return structs.CarState() |
||||||
|
@ -0,0 +1,499 @@ |
|||||||
|
from dataclasses import dataclass as _dataclass, field, is_dataclass |
||||||
|
from enum import Enum, StrEnum as _StrEnum, auto |
||||||
|
from typing import dataclass_transform, get_origin |
||||||
|
|
||||||
|
AUTO_OBJ = object() |
||||||
|
|
||||||
|
|
||||||
|
def auto_field(): |
||||||
|
return AUTO_OBJ |
||||||
|
|
||||||
|
|
||||||
|
@dataclass_transform() |
||||||
|
def auto_dataclass(cls=None, /, **kwargs): |
||||||
|
cls_annotations = cls.__dict__.get('__annotations__', {}) |
||||||
|
for name, typ in cls_annotations.items(): |
||||||
|
current_value = getattr(cls, name) |
||||||
|
if current_value is AUTO_OBJ: |
||||||
|
origin_typ = get_origin(typ) or typ |
||||||
|
if isinstance(origin_typ, str): |
||||||
|
raise TypeError(f"Forward references are not supported for auto_field: '{origin_typ}'. Use a default_factory with lambda instead.") |
||||||
|
elif origin_typ in (int, float, str, bytes, list, tuple, bool) or is_dataclass(origin_typ): |
||||||
|
setattr(cls, name, field(default_factory=origin_typ)) |
||||||
|
elif issubclass(origin_typ, Enum): # first enum is the default |
||||||
|
setattr(cls, name, field(default=next(iter(origin_typ)))) |
||||||
|
else: |
||||||
|
raise TypeError(f"Unsupported type for auto_field: {origin_typ}") |
||||||
|
|
||||||
|
# TODO: use slots, this prevents accidentally setting attributes that don't exist |
||||||
|
return _dataclass(cls, **kwargs) |
||||||
|
|
||||||
|
|
||||||
|
class StrEnum(_StrEnum): |
||||||
|
@staticmethod |
||||||
|
def _generate_next_value_(name, *args): |
||||||
|
# auto() defaults to name.lower() |
||||||
|
return name |
||||||
|
|
||||||
|
|
||||||
|
@auto_dataclass |
||||||
|
class CarState: |
||||||
|
# CAN health |
||||||
|
canValid: bool = auto_field() # invalid counter/checksums |
||||||
|
canTimeout: bool = auto_field() # CAN bus dropped out |
||||||
|
canErrorCounter: int = auto_field() |
||||||
|
|
||||||
|
# car speed |
||||||
|
vEgo: float = auto_field() # best estimate of speed |
||||||
|
aEgo: float = auto_field() # best estimate of acceleration |
||||||
|
vEgoRaw: float = auto_field() # unfiltered speed from CAN sensors |
||||||
|
vEgoCluster: float = auto_field() # best estimate of speed shown on car's instrument cluster, used for UI |
||||||
|
|
||||||
|
yawRate: float = auto_field() # best estimate of yaw rate |
||||||
|
standstill: bool = auto_field() |
||||||
|
wheelSpeeds: 'CarState.WheelSpeeds' = field(default_factory=lambda: CarState.WheelSpeeds()) |
||||||
|
|
||||||
|
# gas pedal, 0.0-1.0 |
||||||
|
gas: float = auto_field() # this is user pedal only |
||||||
|
gasPressed: bool = auto_field() # this is user pedal only |
||||||
|
|
||||||
|
engineRpm: float = auto_field() |
||||||
|
|
||||||
|
# brake pedal, 0.0-1.0 |
||||||
|
brake: float = auto_field() # this is user pedal only |
||||||
|
brakePressed: bool = auto_field() # this is user pedal only |
||||||
|
regenBraking: bool = auto_field() # this is user pedal only |
||||||
|
parkingBrake: bool = auto_field() |
||||||
|
brakeHoldActive: bool = auto_field() |
||||||
|
|
||||||
|
# steering wheel |
||||||
|
steeringAngleDeg: float = auto_field() |
||||||
|
steeringAngleOffsetDeg: float = auto_field() # Offset betweens sensors in case there multiple |
||||||
|
steeringRateDeg: float = auto_field() |
||||||
|
steeringTorque: float = auto_field() # TODO: standardize units |
||||||
|
steeringTorqueEps: float = auto_field() # TODO: standardize units |
||||||
|
steeringPressed: bool = auto_field() # if the user is using the steering wheel |
||||||
|
steerFaultTemporary: bool = auto_field() # temporary EPS fault |
||||||
|
steerFaultPermanent: bool = auto_field() # permanent EPS fault |
||||||
|
stockAeb: bool = auto_field() |
||||||
|
stockFcw: bool = auto_field() |
||||||
|
espDisabled: bool = auto_field() |
||||||
|
accFaulted: bool = auto_field() |
||||||
|
carFaultedNonCritical: bool = auto_field() # some ECU is faulted, but car remains controllable |
||||||
|
espActive: bool = auto_field() |
||||||
|
vehicleSensorsInvalid: bool = auto_field() # invalid steering angle readings, etc. |
||||||
|
|
||||||
|
# cruise state |
||||||
|
cruiseState: 'CarState.CruiseState' = field(default_factory=lambda: CarState.CruiseState()) |
||||||
|
|
||||||
|
# gear |
||||||
|
gearShifter: 'CarState.GearShifter' = field(default_factory=lambda: CarState.GearShifter.unknown) |
||||||
|
|
||||||
|
# button presses |
||||||
|
buttonEvents: list['CarState.ButtonEvent'] = auto_field() |
||||||
|
leftBlinker: bool = auto_field() |
||||||
|
rightBlinker: bool = auto_field() |
||||||
|
genericToggle: bool = auto_field() |
||||||
|
|
||||||
|
# lock info |
||||||
|
doorOpen: bool = auto_field() |
||||||
|
seatbeltUnlatched: bool = auto_field() |
||||||
|
|
||||||
|
# clutch (manual transmission only) |
||||||
|
clutchPressed: bool = auto_field() |
||||||
|
|
||||||
|
# blindspot sensors |
||||||
|
leftBlindspot: bool = auto_field() # Is there something blocking the left lane change |
||||||
|
rightBlindspot: bool = auto_field() # Is there something blocking the right lane change |
||||||
|
|
||||||
|
fuelGauge: float = auto_field() # battery or fuel tank level from 0.0 to 1.0 |
||||||
|
charging: bool = auto_field() |
||||||
|
|
||||||
|
# process meta |
||||||
|
cumLagMs: float = auto_field() |
||||||
|
|
||||||
|
@auto_dataclass |
||||||
|
class WheelSpeeds: |
||||||
|
# optional wheel speeds |
||||||
|
fl: float = auto_field() |
||||||
|
fr: float = auto_field() |
||||||
|
rl: float = auto_field() |
||||||
|
rr: float = auto_field() |
||||||
|
|
||||||
|
@auto_dataclass |
||||||
|
class CruiseState: |
||||||
|
enabled: bool = auto_field() |
||||||
|
speed: float = auto_field() |
||||||
|
speedCluster: float = auto_field() # Set speed as shown on instrument cluster |
||||||
|
available: bool = auto_field() |
||||||
|
speedOffset: float = auto_field() |
||||||
|
standstill: bool = auto_field() |
||||||
|
nonAdaptive: bool = auto_field() |
||||||
|
|
||||||
|
class GearShifter(StrEnum): |
||||||
|
unknown = auto() |
||||||
|
park = auto() |
||||||
|
drive = auto() |
||||||
|
neutral = auto() |
||||||
|
reverse = auto() |
||||||
|
sport = auto() |
||||||
|
low = auto() |
||||||
|
brake = auto() |
||||||
|
eco = auto() |
||||||
|
manumatic = auto() |
||||||
|
|
||||||
|
# send on change |
||||||
|
@auto_dataclass |
||||||
|
class ButtonEvent: |
||||||
|
pressed: bool = auto_field() |
||||||
|
type: 'CarState.ButtonEvent.Type' = field(default_factory=lambda: CarState.ButtonEvent.Type.unknown) |
||||||
|
|
||||||
|
class Type(StrEnum): |
||||||
|
unknown = auto() |
||||||
|
leftBlinker = auto() |
||||||
|
rightBlinker = auto() |
||||||
|
accelCruise = auto() |
||||||
|
decelCruise = auto() |
||||||
|
cancel = auto() |
||||||
|
altButton1 = auto() |
||||||
|
altButton2 = auto() |
||||||
|
altButton3 = auto() |
||||||
|
setCruise = auto() |
||||||
|
resumeCruise = auto() |
||||||
|
gapAdjustCruise = auto() |
||||||
|
|
||||||
|
|
||||||
|
@auto_dataclass |
||||||
|
class RadarData: |
||||||
|
errors: list['Error'] = auto_field() |
||||||
|
points: list['RadarPoint'] = auto_field() |
||||||
|
|
||||||
|
class Error(StrEnum): |
||||||
|
canError = auto() |
||||||
|
fault = auto() |
||||||
|
wrongConfig = auto() |
||||||
|
|
||||||
|
@auto_dataclass |
||||||
|
class RadarPoint: |
||||||
|
trackId: int = auto_field() # no trackId reuse |
||||||
|
|
||||||
|
# these 3 are the minimum required |
||||||
|
dRel: float = auto_field() # m from the front bumper of the car |
||||||
|
yRel: float = auto_field() # m |
||||||
|
vRel: float = auto_field() # m/s |
||||||
|
|
||||||
|
# these are optional and valid if they are not NaN |
||||||
|
aRel: float = auto_field() # m/s^2 |
||||||
|
yvRel: float = auto_field() # m/s |
||||||
|
|
||||||
|
# some radars flag measurements VS estimates |
||||||
|
measured: bool = auto_field() |
||||||
|
|
||||||
|
|
||||||
|
@auto_dataclass |
||||||
|
class CarControl: |
||||||
|
# must be true for any actuator commands to work |
||||||
|
enabled: bool = auto_field() |
||||||
|
latActive: bool = auto_field() |
||||||
|
longActive: bool = auto_field() |
||||||
|
|
||||||
|
# Actuator commands as computed by controlsd |
||||||
|
actuators: 'CarControl.Actuators' = field(default_factory=lambda: CarControl.Actuators()) |
||||||
|
|
||||||
|
leftBlinker: bool = auto_field() |
||||||
|
rightBlinker: bool = auto_field() |
||||||
|
|
||||||
|
orientationNED: list[float] = auto_field() |
||||||
|
angularVelocity: list[float] = auto_field() |
||||||
|
|
||||||
|
cruiseControl: 'CarControl.CruiseControl' = field(default_factory=lambda: CarControl.CruiseControl()) |
||||||
|
hudControl: 'CarControl.HUDControl' = field(default_factory=lambda: CarControl.HUDControl()) |
||||||
|
|
||||||
|
@auto_dataclass |
||||||
|
class Actuators: |
||||||
|
# range from 0.0 - 1.0 |
||||||
|
gas: float = auto_field() |
||||||
|
brake: float = auto_field() |
||||||
|
# range from -1.0 - 1.0 |
||||||
|
steer: float = auto_field() |
||||||
|
# value sent over can to the car |
||||||
|
steerOutputCan: float = auto_field() |
||||||
|
steeringAngleDeg: float = auto_field() |
||||||
|
|
||||||
|
curvature: float = auto_field() |
||||||
|
|
||||||
|
speed: float = auto_field() # m/s |
||||||
|
accel: float = auto_field() # m/s^2 |
||||||
|
longControlState: 'CarControl.Actuators.LongControlState' = field(default_factory=lambda: CarControl.Actuators.LongControlState.off) |
||||||
|
|
||||||
|
class LongControlState(StrEnum): |
||||||
|
off = auto() |
||||||
|
pid = auto() |
||||||
|
stopping = auto() |
||||||
|
starting = auto() |
||||||
|
|
||||||
|
@auto_dataclass |
||||||
|
class CruiseControl: |
||||||
|
cancel: bool = auto_field() |
||||||
|
resume: bool = auto_field() |
||||||
|
override: bool = auto_field() |
||||||
|
|
||||||
|
@auto_dataclass |
||||||
|
class HUDControl: |
||||||
|
speedVisible: bool = auto_field() |
||||||
|
setSpeed: float = auto_field() |
||||||
|
lanesVisible: bool = auto_field() |
||||||
|
leadVisible: bool = auto_field() |
||||||
|
visualAlert: 'CarControl.HUDControl.VisualAlert' = field(default_factory=lambda: CarControl.HUDControl.VisualAlert.none) |
||||||
|
audibleAlert: 'CarControl.HUDControl.AudibleAlert' = field(default_factory=lambda: CarControl.HUDControl.AudibleAlert.none) |
||||||
|
rightLaneVisible: bool = auto_field() |
||||||
|
leftLaneVisible: bool = auto_field() |
||||||
|
rightLaneDepart: bool = auto_field() |
||||||
|
leftLaneDepart: bool = auto_field() |
||||||
|
leadDistanceBars: int = auto_field() # 1-3: 1 is closest, 3 is farthest. some ports may utilize 2-4 bars instead |
||||||
|
|
||||||
|
class VisualAlert(StrEnum): |
||||||
|
# these are the choices from the Honda |
||||||
|
# map as good as you can for your car |
||||||
|
none = auto() |
||||||
|
fcw = auto() |
||||||
|
steerRequired = auto() |
||||||
|
brakePressed = auto() |
||||||
|
wrongGear = auto() |
||||||
|
seatbeltUnbuckled = auto() |
||||||
|
speedTooHigh = auto() |
||||||
|
ldw = auto() |
||||||
|
|
||||||
|
class AudibleAlert(StrEnum): |
||||||
|
none = auto() |
||||||
|
|
||||||
|
engage = auto() |
||||||
|
disengage = auto() |
||||||
|
refuse = auto() |
||||||
|
|
||||||
|
warningSoft = auto() |
||||||
|
warningImmediate = auto() |
||||||
|
|
||||||
|
prompt = auto() |
||||||
|
promptRepeat = auto() |
||||||
|
promptDistracted = auto() |
||||||
|
|
||||||
|
|
||||||
|
@auto_dataclass |
||||||
|
class CarParams: |
||||||
|
carName: str = auto_field() |
||||||
|
carFingerprint: str = auto_field() |
||||||
|
fuzzyFingerprint: bool = auto_field() |
||||||
|
|
||||||
|
notCar: bool = auto_field() # flag for non-car robotics platforms |
||||||
|
|
||||||
|
pcmCruise: bool = auto_field() # is openpilot's state tied to the PCM's cruise state? |
||||||
|
enableDsu: bool = auto_field() # driving support unit |
||||||
|
enableBsm: bool = auto_field() # blind spot monitoring |
||||||
|
flags: int = auto_field() # flags for car specific quirks |
||||||
|
experimentalLongitudinalAvailable: bool = auto_field() |
||||||
|
|
||||||
|
minEnableSpeed: float = auto_field() |
||||||
|
minSteerSpeed: float = auto_field() |
||||||
|
safetyConfigs: list['CarParams.SafetyConfig'] = auto_field() |
||||||
|
alternativeExperience: int = auto_field() # panda flag for features like no disengage on gas |
||||||
|
|
||||||
|
maxLateralAccel: float = auto_field() |
||||||
|
autoResumeSng: bool = auto_field() # describes whether car can resume from a stop automatically |
||||||
|
|
||||||
|
mass: float = auto_field() # [kg] curb weight: all fluids no cargo |
||||||
|
wheelbase: float = auto_field() # [m] distance from rear axle to front axle |
||||||
|
centerToFront: float = auto_field() # [m] distance from center of mass to front axle |
||||||
|
steerRatio: float = auto_field() # [] ratio of steering wheel angle to front wheel angle |
||||||
|
steerRatioRear: float = auto_field() # [] ratio of steering wheel angle to rear wheel angle (usually 0) |
||||||
|
|
||||||
|
rotationalInertia: float = auto_field() # [kg*m2] body rotational inertia |
||||||
|
tireStiffnessFactor: float = auto_field() # scaling factor used in calculating tireStiffness[Front,Rear] |
||||||
|
tireStiffnessFront: float = auto_field() # [N/rad] front tire coeff of stiff |
||||||
|
tireStiffnessRear: float = auto_field() # [N/rad] rear tire coeff of stiff |
||||||
|
|
||||||
|
longitudinalTuning: 'CarParams.LongitudinalPIDTuning' = field(default_factory=lambda: CarParams.LongitudinalPIDTuning()) |
||||||
|
lateralParams: 'CarParams.LateralParams' = field(default_factory=lambda: CarParams.LateralParams()) |
||||||
|
lateralTuning: 'CarParams.LateralTuning' = field(default_factory=lambda: CarParams.LateralTuning()) |
||||||
|
|
||||||
|
@auto_dataclass |
||||||
|
class LateralTuning: |
||||||
|
def init(self, which: str): |
||||||
|
self.which = CarParams.LateralTuning.Which(which) |
||||||
|
|
||||||
|
class Which(StrEnum): |
||||||
|
pid = auto() |
||||||
|
torque = auto() |
||||||
|
|
||||||
|
def __call__(self): |
||||||
|
return self.value |
||||||
|
|
||||||
|
which: 'CarParams.LateralTuning.Which' = field(default_factory=lambda: CarParams.LateralTuning.Which.pid) |
||||||
|
|
||||||
|
pid: 'CarParams.LateralPIDTuning' = field(default_factory=lambda: CarParams.LateralPIDTuning()) |
||||||
|
torque: 'CarParams.LateralTorqueTuning' = field(default_factory=lambda: CarParams.LateralTorqueTuning()) |
||||||
|
|
||||||
|
@auto_dataclass |
||||||
|
class SafetyConfig: |
||||||
|
safetyModel: 'CarParams.SafetyModel' = field(default_factory=lambda: CarParams.SafetyModel.silent) |
||||||
|
safetyParam: int = auto_field() |
||||||
|
|
||||||
|
@auto_dataclass |
||||||
|
class LateralParams: |
||||||
|
torqueBP: list[int] = auto_field() |
||||||
|
torqueV: list[int] = auto_field() |
||||||
|
|
||||||
|
@auto_dataclass |
||||||
|
class LateralPIDTuning: |
||||||
|
kpBP: list[float] = auto_field() |
||||||
|
kpV: list[float] = auto_field() |
||||||
|
kiBP: list[float] = auto_field() |
||||||
|
kiV: list[float] = auto_field() |
||||||
|
kf: float = auto_field() |
||||||
|
|
||||||
|
@auto_dataclass |
||||||
|
class LateralTorqueTuning: |
||||||
|
useSteeringAngle: bool = auto_field() |
||||||
|
kp: float = auto_field() |
||||||
|
ki: float = auto_field() |
||||||
|
friction: float = auto_field() |
||||||
|
kf: float = auto_field() |
||||||
|
steeringAngleDeadzoneDeg: float = auto_field() |
||||||
|
latAccelFactor: float = auto_field() |
||||||
|
latAccelOffset: float = auto_field() |
||||||
|
|
||||||
|
steerLimitAlert: bool = auto_field() |
||||||
|
steerLimitTimer: float = auto_field() # time before steerLimitAlert is issued |
||||||
|
|
||||||
|
vEgoStopping: float = auto_field() # Speed at which the car goes into stopping state |
||||||
|
vEgoStarting: float = auto_field() # Speed at which the car goes into starting state |
||||||
|
stoppingControl: bool = auto_field() # Does the car allow full control even at lows speeds when stopping |
||||||
|
steerControlType: 'CarParams.SteerControlType' = field(default_factory=lambda: CarParams.SteerControlType.torque) |
||||||
|
radarUnavailable: bool = auto_field() # True when radar objects aren't visible on CAN or aren't parsed out |
||||||
|
stopAccel: float = auto_field() # Required acceleration to keep vehicle stationary |
||||||
|
stoppingDecelRate: float = auto_field() # m/s^2/s while trying to stop |
||||||
|
startAccel: float = auto_field() # Required acceleration to get car moving |
||||||
|
startingState: bool = auto_field() # Does this car make use of special starting state |
||||||
|
|
||||||
|
steerActuatorDelay: float = auto_field() # Steering wheel actuator delay in seconds |
||||||
|
longitudinalActuatorDelay: float = auto_field() # Gas/Brake actuator delay in seconds |
||||||
|
openpilotLongitudinalControl: bool = auto_field() # is openpilot doing the longitudinal control? |
||||||
|
carVin: str = auto_field() # VIN number queried during fingerprinting |
||||||
|
dashcamOnly: bool = auto_field() |
||||||
|
passive: bool = auto_field() # is openpilot in control? |
||||||
|
transmissionType: 'CarParams.TransmissionType' = field(default_factory=lambda: CarParams.TransmissionType.unknown) |
||||||
|
carFw: list['CarParams.CarFw'] = auto_field() |
||||||
|
|
||||||
|
radarTimeStep: float = 0.05 # time delta between radar updates, 20Hz is very standard |
||||||
|
fingerprintSource: 'CarParams.FingerprintSource' = field(default_factory=lambda: CarParams.FingerprintSource.can) |
||||||
|
# Where Panda/C2 is integrated into the car's CAN network |
||||||
|
networkLocation: 'CarParams.NetworkLocation' = field(default_factory=lambda: CarParams.NetworkLocation.fwdCamera) |
||||||
|
|
||||||
|
wheelSpeedFactor: float = auto_field() # Multiplier on wheels speeds to computer actual speeds |
||||||
|
|
||||||
|
@auto_dataclass |
||||||
|
class LongitudinalPIDTuning: |
||||||
|
kpBP: list[float] = auto_field() |
||||||
|
kpV: list[float] = auto_field() |
||||||
|
kiBP: list[float] = auto_field() |
||||||
|
kiV: list[float] = auto_field() |
||||||
|
kf: float = auto_field() |
||||||
|
|
||||||
|
class SafetyModel(StrEnum): |
||||||
|
silent = auto() |
||||||
|
hondaNidec = auto() |
||||||
|
toyota = auto() |
||||||
|
elm327 = auto() |
||||||
|
gm = auto() |
||||||
|
hondaBoschGiraffe = auto() |
||||||
|
ford = auto() |
||||||
|
cadillac = auto() |
||||||
|
hyundai = auto() |
||||||
|
chrysler = auto() |
||||||
|
tesla = auto() |
||||||
|
subaru = auto() |
||||||
|
gmPassive = auto() |
||||||
|
mazda = auto() |
||||||
|
nissan = auto() |
||||||
|
volkswagen = auto() |
||||||
|
toyotaIpas = auto() |
||||||
|
allOutput = auto() |
||||||
|
gmAscm = auto() |
||||||
|
noOutput = auto() # like silent but without silent CAN TXs |
||||||
|
hondaBosch = auto() |
||||||
|
volkswagenPq = auto() |
||||||
|
subaruPreglobal = auto() # pre-Global platform |
||||||
|
hyundaiLegacy = auto() |
||||||
|
hyundaiCommunity = auto() |
||||||
|
volkswagenMlb = auto() |
||||||
|
hongqi = auto() |
||||||
|
body = auto() |
||||||
|
hyundaiCanfd = auto() |
||||||
|
volkswagenMqbEvo = auto() |
||||||
|
chryslerCusw = auto() |
||||||
|
psa = auto() |
||||||
|
|
||||||
|
class SteerControlType(StrEnum): |
||||||
|
torque = auto() |
||||||
|
angle = auto() |
||||||
|
|
||||||
|
class TransmissionType(StrEnum): |
||||||
|
unknown = auto() |
||||||
|
automatic = auto() # Traditional auto, including DSG |
||||||
|
manual = auto() # True "stick shift" only |
||||||
|
direct = auto() # Electric vehicle or other direct drive |
||||||
|
cvt = auto() |
||||||
|
|
||||||
|
@auto_dataclass |
||||||
|
class CarFw: |
||||||
|
ecu: 'CarParams.Ecu' = field(default_factory=lambda: CarParams.Ecu.unknown) |
||||||
|
fwVersion: bytes = auto_field() |
||||||
|
address: int = auto_field() |
||||||
|
subAddress: int = auto_field() |
||||||
|
responseAddress: int = auto_field() |
||||||
|
request: list[bytes] = auto_field() |
||||||
|
brand: str = auto_field() |
||||||
|
bus: int = auto_field() |
||||||
|
logging: bool = auto_field() |
||||||
|
obdMultiplexing: bool = auto_field() |
||||||
|
|
||||||
|
class Ecu(StrEnum): |
||||||
|
eps = auto() |
||||||
|
abs = auto() |
||||||
|
fwdRadar = auto() |
||||||
|
fwdCamera = auto() |
||||||
|
engine = auto() |
||||||
|
unknown = auto() |
||||||
|
transmission = auto() # Transmission Control Module |
||||||
|
hybrid = auto() # hybrid control unit, e.g. Chrysler's HCP, Honda's IMA Control Unit, Toyota's hybrid control computer |
||||||
|
srs = auto() # airbag |
||||||
|
gateway = auto() # can gateway |
||||||
|
hud = auto() # heads up display |
||||||
|
combinationMeter = auto() # instrument cluster |
||||||
|
electricBrakeBooster = auto() |
||||||
|
shiftByWire = auto() |
||||||
|
adas = auto() |
||||||
|
cornerRadar = auto() |
||||||
|
hvac = auto() |
||||||
|
parkingAdas = auto() # parking assist system ECU, e.g. Toyota's IPAS, Hyundai's RSPA, etc. |
||||||
|
epb = auto() # electronic parking brake |
||||||
|
telematics = auto() |
||||||
|
body = auto() # body control module |
||||||
|
|
||||||
|
# Toyota only |
||||||
|
dsu = auto() |
||||||
|
|
||||||
|
# Honda only |
||||||
|
vsa = auto() # Vehicle Stability Assist |
||||||
|
programmedFuelInjection = auto() |
||||||
|
|
||||||
|
debug = auto() |
||||||
|
|
||||||
|
class FingerprintSource(StrEnum): |
||||||
|
can = auto() |
||||||
|
fw = auto() |
||||||
|
fixed = auto() |
||||||
|
|
||||||
|
class NetworkLocation(StrEnum): |
||||||
|
fwdCamera = auto() # Standard/default integration at LKAS camera |
||||||
|
gateway = auto() # Integration at vehicle's CAN gateway |
@ -1 +1 @@ |
|||||||
d768496a1a85bfe5b74c99a79203affdf9a0a065 |
fa4965a27dee4449ad8b255f9f7674d69327b6f7 |
Loading…
Reference in new issue