from dataclasses import dataclass , fields , field , is_dataclass
from enum import Enum , StrEnum as _StrEnum , auto
# from typing import Type, TypeVar
from typing import TypeVar , TYPE_CHECKING , Any , get_type_hints , get_origin
from selfdrive . car . data_test_kinda_works_chatgpt import auto_field , apply_auto_fields
if TYPE_CHECKING :
from _typeshed import DataclassInstance
#
# DataclassT = TypeVar("DataclassT", bound="DataclassInstance")
#
# T = TypeVar('T', bound='Struct')
_FIELDS = ' __dataclass_fields__ '
class StrEnum ( _StrEnum ) :
@staticmethod
def _generate_next_value_ ( name , * args ) :
# auto() defaults to name.lower()
return name
# 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
class RadarData :
errors : list [ ' Error ' ]
points : list [ ' RadarPoint ' ]
class Error ( StrEnum ) :
canError = auto ( )
fault = auto ( )
wrongConfig = auto ( )
@dataclass
class RadarPoint :
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
@apply_auto_fields
class CarParams :
carName : str = auto_field ( )
carFingerprint : str = auto_field ( )
fuzzyFingerprint : bool = auto_field ( )
notCar : bool = auto_field ( ) # flag for non-car robotics platforms
carFw : list [ ' CarParams.CarFw ' ] = auto_field ( )
class SteerControlType ( StrEnum ) :
torque = auto ( )
angle = auto ( )
@dataclass
@apply_auto_fields
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 ( )
# # CP: CarParams = CarParams.new_message(carName='toyota', fuzzyFingerprint=123)
# # CP: CarParams = CarParams(carName='toyota', fuzzyFingerprint=123)
#
# # import ast
#
#
# # test = ast.literal_eval('CarParams.CarFw')
#
# def mywrapper(cls):
#
# cls_annotations = cls.__dict__.get('__annotations__', {})
# fields = {}
# for name, _type in cls_annotations.items():
# f = field(default_factory=_type)
# setattr(cls, name, f)
# fields[name] = f
#
# setattr(cls, _FIELDS, fields)
#
# print('cls_annotations', cls_annotations)
# # cls.hi = 123
#
# return cls
#
#
# # def mywrapper2(cls):
# # class Test:
# # pass
# # return Test
#
#
# @dataclass
# class CarControl1:
# enabled: bool
#
# @dataclass
# class CarControl2:
# enabled: bool = field(default_factory=bool)
#
#
# # @mywrapper2
# @dataclass()
# @mywrapper
# class CarControl:
# # enabled: bool = field(default_factory=bool)
# enabled: bool = None
# pts: list[int] = None
# logMonoTime: int = None
#
#
# CC = CarControl()
@dataclass
@apply_auto_fields
class CarControl :
enabled : bool = auto_field ( )
pts : list [ int ] = auto_field ( )
logMonoTime : int = auto_field ( )
test : None = auto_field ( )
# testing: if origin_typ in (int, float, str, bytes, list, tuple, set, dict, bool):
@dataclass
@apply_auto_fields
class Test997 :
a : int = auto_field ( )
b : float = auto_field ( )
c : str = auto_field ( )
d : bytes = auto_field ( )
e : list [ int ] = auto_field ( )
f : tuple [ int ] = auto_field ( )
g : set [ int ] = auto_field ( )
h : dict [ str , int ] = auto_field ( )
i : bool = auto_field ( )
ecu : CarParams . Ecu = auto_field ( )
carFw : CarParams . CarFw = auto_field ( )
# Out[4]: Test997(a=0, b=0.0, c='', d=b'', e=[], f=(), g=set(), h={}, i=False)
CarControl ( )
CP = CarParams ( )
CP . carFw = [ CarParams . CarFw ( ) ]
CP . carFw = [ CarParams . Ecu . eps ]