openpilot is an open source driver assistance system. openpilot performs the functions of Automated Lane Centering and Adaptive Cruise Control for over 200 supported car makes and models.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

154 lines
4.0 KiB

9 months ago
from dataclasses import dataclass, fields, is_dataclass
from enum import Enum, StrEnum as _StrEnum, auto
# from typing import Type, TypeVar
from typing import Type, TypeVar, TYPE_CHECKING, Any, get_type_hints, get_origin
if TYPE_CHECKING:
from _typeshed import DataclassInstance
#
# DataclassT = TypeVar("DataclassT", bound="DataclassInstance")
#
# T = TypeVar('T', bound='Struct')
class StrEnum(_StrEnum):
@staticmethod
def _generate_next_value_(name, *args):
# auto() defaults to name.lower()
return name
9 months ago
# class Struct:
# @classmethod
# def new_message(cls, **kwargs):
# init_values = {}
# for f in fields(cls):
# init_values[f.name] = kwargs.get(f.name, f.type())
#
# return cls(**init_values)
T = TypeVar('T', bound='DataclassInstance')
class Struct:
@classmethod
def new_message(cls: Type[T], **kwargs: Any) -> T:
if not is_dataclass(cls):
raise TypeError(f"{cls.__name__} is not a dataclass")
init_values = {}
type_hints = get_type_hints(cls)
print(type_hints)
for f in fields(cls):
field_type = type_hints[f.name]
print(f.name, f.type, field_type)
print(issubclass(field_type, Enum))
if issubclass(field_type, Enum):
init_values[f.name] = kwargs.get(f.name, list(field_type)[0])
# TODO: fix this
# assert issubclass(init_values[f.name], type(field_type)), f"Expected {field_type} for {f.name}, got {type(init_values[f.name])}"
else:
# FIXME: typing check hack since mypy doesn't catch anything
init_values[f.name] = kwargs.get(f.name, field_type())
print('field_type', field_type, f.type)
# TODO: this is so bad
assert isinstance(init_values[f.name], get_origin(f.type) or f.type), f"Expected {field_type} for {f.name}, got {type(init_values[f.name])}"
return cls(**init_values)
@dataclass
9 months ago
class RadarData(Struct):
errors: list['Error']
points: list['RadarPoint']
class Error(StrEnum):
canError = auto()
fault = auto()
wrongConfig = auto()
@dataclass
class RadarPoint(Struct):
trackId: int # no trackId reuse
# these 3 are the minimum required
dRel: float # m from the front bumper of the car
yRel: float # m
vRel: float # m/s
# these are optional and valid if they are not NaN
aRel: float # m/s^2
yvRel: float # m/s
# some radars flag measurements VS estimates
measured: bool
@dataclass
class CarParams(Struct):
carName: str
carFingerprint: str
fuzzyFingerprint: bool
notCar: bool # flag for non-car robotics platforms
9 months ago
carFw: list['CarFw']
class SteerControlType(StrEnum):
torque = auto()
angle = auto()
9 months ago
@dataclass
class CarFw(Struct):
ecu: 'CarParams.Ecu'
fwVersion: bytes
address: int
subAddress: int
responseAddress: int
request: list[bytes]
brand: str
bus: int
logging: bool
obdMultiplexing: bool
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()
9 months ago
# CP: CarParams = CarParams.new_message(carName='toyota', fuzzyFingerprint=123)
# CP: CarParams = CarParams(carName='toyota', fuzzyFingerprint=123)
import ast
# test = ast.literal_eval('CarParams.CarFw')