mirror of https://github.com/commaai/openpilot.git
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 commit90239b7797
. * 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
This commit is contained in:
parent
51fae363e4
commit
6a15c42143
|
@ -1,6 +1,8 @@
|
|||
[importlinter]
|
||||
root_packages =
|
||||
openpilot
|
||||
cereal
|
||||
capnp
|
||||
|
||||
[importlinter:contract:1]
|
||||
name = Forbid imports from openpilot.selfdrive.car to openpilot.system
|
||||
|
@ -8,6 +10,8 @@ type = forbidden
|
|||
source_modules =
|
||||
openpilot.selfdrive.car
|
||||
forbidden_modules =
|
||||
cereal
|
||||
capnp
|
||||
openpilot.common
|
||||
openpilot.selfdrive.controls
|
||||
openpilot.selfdrive.debug
|
||||
|
@ -44,5 +48,16 @@ ignore_imports =
|
|||
openpilot.selfdrive.car.tests.test_car_interfaces -> openpilot.selfdrive.pandad
|
||||
openpilot.selfdrive.car.tests.test_models -> openpilot.selfdrive.pandad
|
||||
openpilot.selfdrive.car.tests.test_car_interfaces -> openpilot.selfdrive.test.fuzzy_generation
|
||||
openpilot.selfdrive.car.tests.test_models -> capnp
|
||||
openpilot.selfdrive.car.tests.test_car_interfaces -> cereal
|
||||
openpilot.selfdrive.car.tests.test_car_interfaces -> cereal.messaging
|
||||
openpilot.selfdrive.car.tests.test_car_interfaces -> openpilot.selfdrive.test.fuzzy_generation
|
||||
openpilot.selfdrive.car.tests.test_models -> cereal
|
||||
openpilot.selfdrive.car.tests.test_models -> cereal.messaging
|
||||
openpilot.selfdrive.car.card -> cereal
|
||||
openpilot.selfdrive.car.card -> cereal.messaging
|
||||
openpilot.selfdrive.car.car_specific -> openpilot.selfdrive.controls.lib.events
|
||||
openpilot.selfdrive.car.car_specific -> cereal
|
||||
openpilot.selfdrive.car.car_specific -> cereal.messaging
|
||||
openpilot.selfdrive.car.card -> capnp
|
||||
unmatched_ignore_imports_alerting = warn
|
||||
|
|
|
@ -5,10 +5,8 @@ from dataclasses import dataclass
|
|||
from enum import IntFlag, ReprEnum, EnumType
|
||||
from dataclasses import replace
|
||||
|
||||
import capnp
|
||||
|
||||
from cereal import car
|
||||
from panda.python.uds import SERVICE_TYPE
|
||||
from openpilot.selfdrive.car import structs
|
||||
from openpilot.selfdrive.car.can_definitions import CanData
|
||||
from openpilot.selfdrive.car.docs_definitions import CarDocs
|
||||
from openpilot.selfdrive.car.common.numpy_fast import clip, interp
|
||||
|
@ -23,7 +21,7 @@ DT_CTRL = 0.01 # car state and control loop timestep (s)
|
|||
# kg of standard extra cargo to count for drive, gas, etc...
|
||||
STD_CARGO_KG = 136.
|
||||
|
||||
ButtonType = car.CarState.ButtonEvent.Type
|
||||
ButtonType = structs.CarState.ButtonEvent.Type
|
||||
AngleRateLimit = namedtuple('AngleRateLimit', ['speed_bp', 'angle_v'])
|
||||
|
||||
|
||||
|
@ -35,9 +33,9 @@ def apply_hysteresis(val: float, val_steady: float, hyst_gap: float) -> float:
|
|||
return val_steady
|
||||
|
||||
|
||||
def create_button_events(cur_btn: int, prev_btn: int, buttons_dict: dict[int, capnp.lib.capnp._EnumModule],
|
||||
unpressed_btn: int = 0) -> list[capnp.lib.capnp._DynamicStructBuilder]:
|
||||
events: list[capnp.lib.capnp._DynamicStructBuilder] = []
|
||||
def create_button_events(cur_btn: int, prev_btn: int, buttons_dict: dict[int, structs.CarState.ButtonEvent.Type],
|
||||
unpressed_btn: int = 0) -> list[structs.CarState.ButtonEvent]:
|
||||
events: list[structs.CarState.ButtonEvent] = []
|
||||
|
||||
if cur_btn == prev_btn:
|
||||
return events
|
||||
|
@ -45,8 +43,8 @@ def create_button_events(cur_btn: int, prev_btn: int, buttons_dict: dict[int, ca
|
|||
# Add events for button presses, multiple when a button switches without going to unpressed
|
||||
for pressed, btn in ((False, prev_btn), (True, cur_btn)):
|
||||
if btn != unpressed_btn:
|
||||
events.append(car.CarState.ButtonEvent(pressed=pressed,
|
||||
type=buttons_dict.get(btn, ButtonType.unknown)))
|
||||
events.append(structs.CarState.ButtonEvent(pressed=pressed,
|
||||
type=buttons_dict.get(btn, ButtonType.unknown)))
|
||||
return events
|
||||
|
||||
|
||||
|
@ -183,7 +181,7 @@ def rate_limit(new_value, last_value, dw_step, up_step):
|
|||
|
||||
|
||||
def get_friction(lateral_accel_error: float, lateral_accel_deadzone: float, friction_threshold: float,
|
||||
torque_params: car.CarParams.LateralTorqueTuning, friction_compensation: bool) -> float:
|
||||
torque_params: structs.CarParams.LateralTorqueTuning, friction_compensation: bool) -> float:
|
||||
friction_interp = interp(
|
||||
apply_center_deadzone(lateral_accel_error, lateral_accel_deadzone),
|
||||
[-friction_threshold, friction_threshold],
|
||||
|
@ -203,8 +201,8 @@ def make_tester_present_msg(addr, bus, subaddr=None, suppress_response=False):
|
|||
return CanData(addr, bytes(dat), bus)
|
||||
|
||||
|
||||
def get_safety_config(safety_model, safety_param = None):
|
||||
ret = car.CarParams.SafetyConfig.new_message()
|
||||
def get_safety_config(safety_model: structs.CarParams.SafetyModel, safety_param: int = None) -> structs.CarParams.SafetyConfig:
|
||||
ret = structs.CarParams.SafetyConfig()
|
||||
ret.safetyModel = safety_model
|
||||
if safety_param is not None:
|
||||
ret.safetyParam = safety_param
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import copy
|
||||
import numpy as np
|
||||
from numbers import Number
|
||||
|
||||
|
@ -132,7 +133,7 @@ class CarController(CarControllerBase):
|
|||
can_sends = []
|
||||
can_sends.append(bodycan.create_control(self.packer, torque_l, torque_r))
|
||||
|
||||
new_actuators = CC.actuators.as_builder()
|
||||
new_actuators = copy.copy(CC.actuators)
|
||||
new_actuators.accel = torque_l
|
||||
new_actuators.steer = torque_r
|
||||
new_actuators.steerOutputCan = torque_r
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
from cereal import car
|
||||
from opendbc.can.parser import CANParser
|
||||
from openpilot.selfdrive.car import structs
|
||||
from openpilot.selfdrive.car.interfaces import CarStateBase
|
||||
from openpilot.selfdrive.car.body.values import DBC
|
||||
|
||||
|
||||
class CarState(CarStateBase):
|
||||
def update(self, cp, *_):
|
||||
ret = car.CarState.new_message()
|
||||
def update(self, cp, *_) -> structs.CarState:
|
||||
ret = structs.CarState()
|
||||
|
||||
ret.wheelSpeeds.fl = cp.vl['MOTORS_DATA']['SPEED_L']
|
||||
ret.wheelSpeeds.fr = cp.vl['MOTORS_DATA']['SPEED_R']
|
||||
|
@ -23,7 +23,7 @@ class CarState(CarStateBase):
|
|||
ret.fuelGauge = cp.vl["BODY_DATA"]["BATT_PERCENTAGE"] / 100
|
||||
|
||||
# irrelevant for non-car
|
||||
ret.gearShifter = car.CarState.GearShifter.drive
|
||||
ret.gearShifter = structs.CarState.GearShifter.drive
|
||||
ret.cruiseState.enabled = True
|
||||
ret.cruiseState.available = True
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# ruff: noqa: E501
|
||||
from cereal import car
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.body.values import CAR
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
Ecu = CarParams.Ecu
|
||||
|
||||
# debug ecu fw version is the git hash of the firmware
|
||||
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
import math
|
||||
from cereal import car
|
||||
from openpilot.selfdrive.car import get_safety_config
|
||||
from openpilot.selfdrive.car import get_safety_config, structs
|
||||
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
|
||||
from openpilot.selfdrive.car.body.values import SPEED_FROM_RPM
|
||||
|
||||
|
||||
class CarInterface(CarInterfaceBase):
|
||||
@staticmethod
|
||||
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
|
||||
def _get_params(ret: structs.CarParams, candidate, fingerprint, car_fw, experimental_long, docs) -> structs.CarParams:
|
||||
ret.notCar = True
|
||||
ret.carName = "body"
|
||||
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.body)]
|
||||
ret.safetyConfigs = [get_safety_config(structs.CarParams.SafetyModel.body)]
|
||||
|
||||
ret.minSteerSpeed = -math.inf
|
||||
ret.maxLateralAccel = math.inf # TODO: set to a reasonable value
|
||||
|
@ -21,6 +20,6 @@ class CarInterface(CarInterfaceBase):
|
|||
|
||||
ret.radarUnavailable = True
|
||||
ret.openpilotLongitudinalControl = True
|
||||
ret.steerControlType = car.CarParams.SteerControlType.angle
|
||||
ret.steerControlType = structs.CarParams.SteerControlType.angle
|
||||
|
||||
return ret
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from cereal import car
|
||||
from openpilot.selfdrive.car import CarSpecs, PlatformConfig, Platforms, dbc_dict
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.docs_definitions import CarDocs
|
||||
from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
Ecu = CarParams.Ecu
|
||||
|
||||
SPEED_FROM_RPM = 0.008587
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import os
|
||||
import time
|
||||
|
||||
from cereal import car
|
||||
from openpilot.selfdrive.car import carlog, gen_empty_fingerprint
|
||||
from openpilot.selfdrive.car.can_definitions import CanRecvCallable, CanSendCallable
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.fingerprints import eliminate_incompatible_cars, all_legacy_fingerprint_cars
|
||||
from openpilot.selfdrive.car.fw_versions import ObdCallback, get_fw_versions_ordered, get_present_ecus, match_fw_to_car
|
||||
from openpilot.selfdrive.car.interfaces import get_interface_attr
|
||||
|
@ -82,7 +82,7 @@ def can_fingerprint(can_recv: CanRecvCallable) -> tuple[str | None, dict[int, di
|
|||
|
||||
# **** for use live only ****
|
||||
def fingerprint(can_recv: CanRecvCallable, can_send: CanSendCallable, set_obd_multiplexing: ObdCallback, num_pandas: int,
|
||||
cached_params: type[car.CarParams] | None) -> tuple[str | None, dict, str, list, int, bool]:
|
||||
cached_params: CarParams | None) -> tuple[str | None, dict, str, list[CarParams.CarFw], CarParams.FingerprintSource, bool]:
|
||||
fixed_fingerprint = os.environ.get('FINGERPRINT', "")
|
||||
skip_fw_query = os.environ.get('SKIP_FW_QUERY', False)
|
||||
disable_fw_cache = os.environ.get('DISABLE_FW_CACHE', False)
|
||||
|
@ -129,17 +129,17 @@ def fingerprint(can_recv: CanRecvCallable, can_send: CanSendCallable, set_obd_mu
|
|||
car_fingerprint, finger = can_fingerprint(can_recv)
|
||||
|
||||
exact_match = True
|
||||
source = car.CarParams.FingerprintSource.can
|
||||
source = CarParams.FingerprintSource.can
|
||||
|
||||
# If FW query returns exactly 1 candidate, use it
|
||||
if len(fw_candidates) == 1:
|
||||
car_fingerprint = list(fw_candidates)[0]
|
||||
source = car.CarParams.FingerprintSource.fw
|
||||
source = CarParams.FingerprintSource.fw
|
||||
exact_match = exact_fw_match
|
||||
|
||||
if fixed_fingerprint:
|
||||
car_fingerprint = fixed_fingerprint
|
||||
source = car.CarParams.FingerprintSource.fixed
|
||||
source = CarParams.FingerprintSource.fixed
|
||||
|
||||
carlog.error({"event": "fingerprinted", "car_fingerprint": str(car_fingerprint), "source": source, "fuzzy": not exact_match,
|
||||
"cached": cached, "fw_count": len(car_fw), "ecu_responses": list(ecu_rx_addrs), "vin_rx_addr": vin_rx_addr,
|
||||
|
@ -148,13 +148,13 @@ def fingerprint(can_recv: CanRecvCallable, can_send: CanSendCallable, set_obd_mu
|
|||
return car_fingerprint, finger, vin, car_fw, source, exact_match
|
||||
|
||||
|
||||
def get_car_interface(CP):
|
||||
def get_car_interface(CP: CarParams):
|
||||
CarInterface, CarController, CarState = interfaces[CP.carFingerprint]
|
||||
return CarInterface(CP, CarController, CarState)
|
||||
|
||||
|
||||
def get_car(can_recv: CanRecvCallable, can_send: CanSendCallable, set_obd_multiplexing: ObdCallback, experimental_long_allowed: bool,
|
||||
num_pandas: int = 1, cached_params: type[car.CarParams] | None = None):
|
||||
num_pandas: int = 1, cached_params: CarParams | None = None):
|
||||
candidate, fingerprints, vin, car_fw, source, exact_match = fingerprint(can_recv, can_send, set_obd_multiplexing, num_pandas, cached_params)
|
||||
|
||||
if candidate is None:
|
||||
|
@ -162,7 +162,7 @@ def get_car(can_recv: CanRecvCallable, can_send: CanSendCallable, set_obd_multip
|
|||
candidate = "MOCK"
|
||||
|
||||
CarInterface, _, _ = interfaces[candidate]
|
||||
CP = CarInterface.get_params(candidate, fingerprints, car_fw, experimental_long_allowed, docs=False)
|
||||
CP: CarParams = CarInterface.get_params(candidate, fingerprints, car_fw, experimental_long_allowed, docs=False)
|
||||
CP.carVin = vin
|
||||
CP.carFw = car_fw
|
||||
CP.fingerprintSource = source
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
from cereal import car
|
||||
import cereal.messaging as messaging
|
||||
from openpilot.selfdrive.car import DT_CTRL
|
||||
from openpilot.selfdrive.car.interfaces import MAX_CTRL_SPEED
|
||||
from openpilot.selfdrive.car import DT_CTRL, structs
|
||||
from openpilot.selfdrive.car.interfaces import MAX_CTRL_SPEED, CarStateBase, CarControllerBase
|
||||
from openpilot.selfdrive.car.volkswagen.values import CarControllerParams as VWCarControllerParams
|
||||
from openpilot.selfdrive.car.hyundai.interface import ENABLE_BUTTONS as HYUNDAI_ENABLE_BUTTONS
|
||||
|
||||
from openpilot.selfdrive.controls.lib.events import Events
|
||||
|
||||
ButtonType = car.CarState.ButtonEvent.Type
|
||||
GearShifter = car.CarState.GearShifter
|
||||
ButtonType = structs.CarState.ButtonEvent.Type
|
||||
GearShifter = structs.CarState.GearShifter
|
||||
EventName = car.CarEvent.EventName
|
||||
NetworkLocation = car.CarParams.NetworkLocation
|
||||
NetworkLocation = structs.CarParams.NetworkLocation
|
||||
|
||||
|
||||
# TODO: the goal is to abstract this file into the CarState struct and make events generic
|
||||
|
@ -29,7 +29,7 @@ class MockCarState:
|
|||
|
||||
|
||||
class CarSpecificEvents:
|
||||
def __init__(self, CP: car.CarParams):
|
||||
def __init__(self, CP: structs.CarParams):
|
||||
self.CP = CP
|
||||
|
||||
self.steering_unpressed = 0
|
||||
|
@ -37,7 +37,7 @@ class CarSpecificEvents:
|
|||
self.no_steer_warning = False
|
||||
self.silent_steer_warning = True
|
||||
|
||||
def update(self, CS, CS_prev, CC, CC_prev):
|
||||
def update(self, CS: CarStateBase, CS_prev: car.CarState, CC: CarControllerBase, CC_prev: car.CarControl):
|
||||
if self.CP.carName in ('body', 'mock'):
|
||||
events = Events()
|
||||
|
||||
|
@ -50,15 +50,15 @@ class CarSpecificEvents:
|
|||
elif self.CP.carName == 'nissan':
|
||||
events = self.create_common_events(CS.out, CS_prev, extra_gears=[GearShifter.brake])
|
||||
|
||||
if CS.lkas_enabled:
|
||||
if CS.lkas_enabled: # type: ignore[attr-defined]
|
||||
events.add(EventName.invalidLkasSetting)
|
||||
|
||||
elif self.CP.carName == 'mazda':
|
||||
events = self.create_common_events(CS.out, CS_prev)
|
||||
|
||||
if CS.lkas_disabled:
|
||||
if CS.lkas_disabled: # type: ignore[attr-defined]
|
||||
events.add(EventName.lkasDisabled)
|
||||
elif CS.low_speed_alert:
|
||||
elif CS.low_speed_alert: # type: ignore[attr-defined]
|
||||
events.add(EventName.belowSteerSpeed)
|
||||
|
||||
elif self.CP.carName == 'chrysler':
|
||||
|
@ -99,7 +99,7 @@ class CarSpecificEvents:
|
|||
if self.CP.openpilotLongitudinalControl:
|
||||
if CS.out.cruiseState.standstill and not CS.out.brakePressed:
|
||||
events.add(EventName.resumeRequired)
|
||||
if CS.low_speed_lockout:
|
||||
if CS.low_speed_lockout: # type: ignore[attr-defined]
|
||||
events.add(EventName.lowSpeedLockout)
|
||||
if CS.out.vEgo < self.CP.minEnableSpeed:
|
||||
events.add(EventName.belowEngageSpeed)
|
||||
|
@ -121,7 +121,7 @@ class CarSpecificEvents:
|
|||
|
||||
# Enabling at a standstill with brake is allowed
|
||||
# TODO: verify 17 Volt can enable for the first time at a stop and allow for all GMs
|
||||
below_min_enable_speed = CS.out.vEgo < self.CP.minEnableSpeed or CS.moving_backward
|
||||
below_min_enable_speed = CS.out.vEgo < self.CP.minEnableSpeed or CS.moving_backward # type: ignore[attr-defined]
|
||||
if below_min_enable_speed and not (CS.out.standstill and CS.out.brake >= 20 and
|
||||
self.CP.networkLocation == NetworkLocation.fwdCamera):
|
||||
events.add(EventName.belowEngageSpeed)
|
||||
|
@ -149,14 +149,14 @@ class CarSpecificEvents:
|
|||
if CC_prev.enabled and CS.out.vEgo < self.CP.minEnableSpeed:
|
||||
events.add(EventName.speedTooLow)
|
||||
|
||||
if CC.eps_timer_soft_disable_alert:
|
||||
if CC.eps_timer_soft_disable_alert: # type: ignore[attr-defined]
|
||||
events.add(EventName.steerTimeLimit)
|
||||
|
||||
elif self.CP.carName == 'hyundai':
|
||||
# On some newer model years, the CANCEL button acts as a pause/resume button based on the PCM state
|
||||
# To avoid re-engaging when openpilot cancels, check user engagement intention via buttons
|
||||
# Main button also can trigger an engagement on these cars
|
||||
allow_enable = any(btn in HYUNDAI_ENABLE_BUTTONS for btn in CS.cruise_buttons) or any(CS.main_buttons)
|
||||
allow_enable = any(btn in HYUNDAI_ENABLE_BUTTONS for btn in CS.cruise_buttons) or any(CS.main_buttons) # type: ignore[attr-defined]
|
||||
events = self.create_common_events(CS.out, CS_prev, pcm_enable=self.CP.pcmCruise, allow_enable=allow_enable)
|
||||
|
||||
# low speed steer alert hysteresis logic (only for cars with steer cut off above 10 m/s)
|
||||
|
@ -172,8 +172,8 @@ class CarSpecificEvents:
|
|||
|
||||
return events
|
||||
|
||||
def create_common_events(self, CS, CS_prev, extra_gears=None, pcm_enable=True, allow_enable=True,
|
||||
enable_buttons=(ButtonType.accelCruise, ButtonType.decelCruise)):
|
||||
def create_common_events(self, CS: structs.CarState, CS_prev: car.CarState, extra_gears=None, pcm_enable=True,
|
||||
allow_enable=True, enable_buttons=(ButtonType.accelCruise, ButtonType.decelCruise)):
|
||||
events = Events()
|
||||
|
||||
if CS.doorOpen:
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
import capnp
|
||||
import os
|
||||
import time
|
||||
from typing import Any
|
||||
|
||||
import cereal.messaging as messaging
|
||||
|
||||
|
@ -13,7 +15,7 @@ from openpilot.common.realtime import config_realtime_process, Priority, Ratekee
|
|||
from openpilot.common.swaglog import cloudlog, ForwardingHandler
|
||||
|
||||
from openpilot.selfdrive.pandad import can_capnp_to_list, can_list_to_can_capnp
|
||||
from openpilot.selfdrive.car import DT_CTRL, carlog
|
||||
from openpilot.selfdrive.car import DT_CTRL, carlog, structs
|
||||
from openpilot.selfdrive.car.can_definitions import CanData, CanRecvCallable, CanSendCallable
|
||||
from openpilot.selfdrive.car.car_specific import CarSpecificEvents, MockCarState
|
||||
from openpilot.selfdrive.car.fw_versions import ObdCallback
|
||||
|
@ -22,6 +24,7 @@ from openpilot.selfdrive.car.interfaces import CarInterfaceBase
|
|||
from openpilot.selfdrive.controls.lib.events import Events
|
||||
|
||||
REPLAY = "REPLAY" in os.environ
|
||||
_FIELDS = '__dataclass_fields__' # copy of dataclasses._FIELDS
|
||||
|
||||
EventName = car.CarEvent.EventName
|
||||
|
||||
|
@ -58,8 +61,74 @@ def can_comm_callbacks(logcan: messaging.SubSocket, sendcan: messaging.PubSocket
|
|||
return can_recv, can_send
|
||||
|
||||
|
||||
def is_dataclass(obj):
|
||||
"""Similar to dataclasses.is_dataclass without instance type check checking"""
|
||||
return hasattr(obj, _FIELDS)
|
||||
|
||||
|
||||
def asdictref(obj) -> dict[str, Any]:
|
||||
"""
|
||||
Similar to dataclasses.asdict without recursive type checking and copy.deepcopy
|
||||
Note that the resulting dict will contain references to the original struct as a result
|
||||
"""
|
||||
if not is_dataclass(obj):
|
||||
raise TypeError("asdictref() should be called on dataclass instances")
|
||||
|
||||
def _asdictref_inner(obj) -> dict[str, Any] | Any:
|
||||
if is_dataclass(obj):
|
||||
ret = {}
|
||||
for field in getattr(obj, _FIELDS): # similar to dataclasses.fields()
|
||||
ret[field] = _asdictref_inner(getattr(obj, field))
|
||||
return ret
|
||||
elif isinstance(obj, (tuple, list)):
|
||||
return type(obj)(_asdictref_inner(v) for v in obj)
|
||||
else:
|
||||
return obj
|
||||
|
||||
return _asdictref_inner(obj)
|
||||
|
||||
|
||||
def convert_to_capnp(struct: structs.CarParams | structs.CarState | structs.CarControl.Actuators) -> capnp.lib.capnp._DynamicStructBuilder:
|
||||
struct_dict = asdictref(struct)
|
||||
|
||||
if isinstance(struct, structs.CarParams):
|
||||
del struct_dict['lateralTuning']
|
||||
struct_capnp = car.CarParams.new_message(**struct_dict)
|
||||
|
||||
# this is the only union, special handling
|
||||
which = struct.lateralTuning.which()
|
||||
struct_capnp.lateralTuning.init(which)
|
||||
lateralTuning_dict = asdictref(getattr(struct.lateralTuning, which))
|
||||
setattr(struct_capnp.lateralTuning, which, lateralTuning_dict)
|
||||
elif isinstance(struct, structs.CarState):
|
||||
struct_capnp = car.CarState.new_message(**struct_dict)
|
||||
elif isinstance(struct, structs.CarControl.Actuators):
|
||||
struct_capnp = car.CarControl.Actuators.new_message(**struct_dict)
|
||||
else:
|
||||
raise ValueError(f"Unsupported struct type: {type(struct)}")
|
||||
|
||||
return struct_capnp
|
||||
|
||||
|
||||
def convert_carControl(struct: capnp.lib.capnp._DynamicStructReader) -> structs.CarControl:
|
||||
# TODO: recursively handle any car struct as needed
|
||||
def remove_deprecated(s: dict) -> dict:
|
||||
return {k: v for k, v in s.items() if not k.endswith('DEPRECATED')}
|
||||
|
||||
struct_dict = struct.to_dict()
|
||||
struct_dataclass = structs.CarControl(**remove_deprecated({k: v for k, v in struct_dict.items() if not isinstance(k, dict)}))
|
||||
|
||||
struct_dataclass.actuators = structs.CarControl.Actuators(**remove_deprecated(struct_dict.get('actuators', {})))
|
||||
struct_dataclass.cruiseControl = structs.CarControl.CruiseControl(**remove_deprecated(struct_dict.get('cruiseControl', {})))
|
||||
struct_dataclass.hudControl = structs.CarControl.HUDControl(**remove_deprecated(struct_dict.get('hudControl', {})))
|
||||
|
||||
return struct_dataclass
|
||||
|
||||
|
||||
class Car:
|
||||
CI: CarInterfaceBase
|
||||
CP: structs.CarParams
|
||||
CP_capnp: car.CarParams
|
||||
|
||||
def __init__(self, CI=None) -> None:
|
||||
self.can_sock = messaging.sub_sock('can', timeout=20)
|
||||
|
@ -72,7 +141,7 @@ class Car:
|
|||
self.CS_prev = car.CarState.new_message()
|
||||
self.initialized_prev = False
|
||||
|
||||
self.last_actuators_output = car.CarControl.Actuators.new_message()
|
||||
self.last_actuators_output = structs.CarControl.Actuators()
|
||||
|
||||
self.params = Params()
|
||||
|
||||
|
@ -93,7 +162,7 @@ class Car:
|
|||
cached_params_raw = self.params.get("CarParamsCache")
|
||||
if cached_params_raw is not None:
|
||||
with car.CarParams.from_bytes(cached_params_raw) as _cached_params:
|
||||
cached_params = _cached_params
|
||||
cached_params = structs.CarParams(carName=_cached_params.carName, carFw=_cached_params.carFw, carVin=_cached_params.carVin)
|
||||
|
||||
self.CI = get_car(*self.can_callbacks, obd_callback(self.params), experimental_long_allowed, num_pandas, cached_params)
|
||||
self.CP = self.CI.CP
|
||||
|
@ -115,8 +184,8 @@ class Car:
|
|||
|
||||
self.CP.passive = not controller_available or self.CP.dashcamOnly
|
||||
if self.CP.passive:
|
||||
safety_config = car.CarParams.SafetyConfig.new_message()
|
||||
safety_config.safetyModel = car.CarParams.SafetyModel.noOutput
|
||||
safety_config = structs.CarParams.SafetyConfig()
|
||||
safety_config.safetyModel = structs.CarParams.SafetyModel.noOutput
|
||||
self.CP.safetyConfigs = [safety_config]
|
||||
|
||||
# Write previous route's CarParams
|
||||
|
@ -125,7 +194,9 @@ class Car:
|
|||
self.params.put("CarParamsPrevRoute", prev_cp)
|
||||
|
||||
# Write CarParams for controls and radard
|
||||
cp_bytes = self.CP.to_bytes()
|
||||
# convert to pycapnp representation for caching and logging
|
||||
self.CP_capnp = convert_to_capnp(self.CP)
|
||||
cp_bytes = self.CP_capnp.to_bytes()
|
||||
self.params.put("CarParams", cp_bytes)
|
||||
self.params.put_nonblocking("CarParamsCache", cp_bytes)
|
||||
self.params.put_nonblocking("CarParamsPersistent", cp_bytes)
|
||||
|
@ -143,7 +214,7 @@ class Car:
|
|||
|
||||
# Update carState from CAN
|
||||
can_strs = messaging.drain_sock_raw(self.can_sock, wait_for_one=True)
|
||||
CS = self.CI.update(can_capnp_to_list(can_strs))
|
||||
CS = convert_to_capnp(self.CI.update(can_capnp_to_list(can_strs)))
|
||||
|
||||
if self.CP.carName == 'mock':
|
||||
CS = self.mock_carstate.update(CS)
|
||||
|
@ -189,13 +260,13 @@ class Car:
|
|||
if self.sm.frame % int(50. / DT_CTRL) == 0:
|
||||
cp_send = messaging.new_message('carParams')
|
||||
cp_send.valid = True
|
||||
cp_send.carParams = self.CP
|
||||
cp_send.carParams = self.CP_capnp
|
||||
self.pm.send('carParams', cp_send)
|
||||
|
||||
# publish new carOutput
|
||||
co_send = messaging.new_message('carOutput')
|
||||
co_send.valid = self.sm.all_checks(['carControl'])
|
||||
co_send.carOutput.actuatorsOutput = self.last_actuators_output
|
||||
co_send.carOutput.actuatorsOutput = convert_to_capnp(self.last_actuators_output)
|
||||
self.pm.send('carOutput', co_send)
|
||||
|
||||
# kick off controlsd step while we actuate the latest carControl packet
|
||||
|
@ -219,7 +290,7 @@ class Car:
|
|||
if self.sm.all_alive(['carControl']):
|
||||
# send car controls over can
|
||||
now_nanos = self.can_log_mono_time if REPLAY else int(time.monotonic() * 1e9)
|
||||
self.last_actuators_output, can_sends = self.CI.apply(CC, now_nanos)
|
||||
self.last_actuators_output, can_sends = self.CI.apply(convert_carControl(CC), now_nanos)
|
||||
self.pm.send('sendcan', can_list_to_can_capnp(can_sends, msgtype='sendcan', valid=CS.canValid))
|
||||
|
||||
self.CC_prev = CC
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import copy
|
||||
from opendbc.can.packer import CANPacker
|
||||
from openpilot.selfdrive.car import DT_CTRL, apply_meas_steer_torque_limits
|
||||
from openpilot.selfdrive.car.chrysler import chryslercan
|
||||
|
@ -76,7 +77,7 @@ class CarController(CarControllerBase):
|
|||
|
||||
self.frame += 1
|
||||
|
||||
new_actuators = CC.actuators.as_builder()
|
||||
new_actuators = copy.copy(CC.actuators)
|
||||
new_actuators.steer = self.apply_steer_last / self.params.STEER_MAX
|
||||
new_actuators.steerOutputCan = self.apply_steer_last
|
||||
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
from cereal import car
|
||||
from opendbc.can.parser import CANParser
|
||||
from opendbc.can.can_define import CANDefine
|
||||
from openpilot.selfdrive.car import create_button_events
|
||||
from openpilot.selfdrive.car import create_button_events, structs
|
||||
from openpilot.selfdrive.car.chrysler.values import DBC, STEER_THRESHOLD, RAM_CARS
|
||||
from openpilot.selfdrive.car.conversions import Conversions as CV
|
||||
from openpilot.selfdrive.car.interfaces import CarStateBase
|
||||
|
||||
ButtonType = car.CarState.ButtonEvent.Type
|
||||
ButtonType = structs.CarState.ButtonEvent.Type
|
||||
|
||||
|
||||
class CarState(CarStateBase):
|
||||
|
@ -26,9 +25,9 @@ class CarState(CarStateBase):
|
|||
|
||||
self.distance_button = 0
|
||||
|
||||
def update(self, cp, cp_cam, *_):
|
||||
def update(self, cp, cp_cam, *_) -> structs.CarState:
|
||||
|
||||
ret = car.CarState.new_message()
|
||||
ret = structs.CarState()
|
||||
|
||||
prev_distance_button = self.distance_button
|
||||
self.distance_button = cp.vl["CRUISE_BUTTONS"]["ACC_Distance_Dec"]
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
from cereal import car
|
||||
from openpilot.selfdrive.car import structs
|
||||
from openpilot.selfdrive.car.chrysler.values import RAM_CARS
|
||||
|
||||
GearShifter = car.CarState.GearShifter
|
||||
VisualAlert = car.CarControl.HUDControl.VisualAlert
|
||||
GearShifter = structs.CarState.GearShifter
|
||||
VisualAlert = structs.CarControl.HUDControl.VisualAlert
|
||||
|
||||
def create_lkas_hud(packer, CP, lkas_active, hud_alert, hud_count, car_model, auto_high_beam):
|
||||
# LKAS_HUD - Controls what lane-keeping icon is displayed
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from cereal import car
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.chrysler.values import CAR
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
Ecu = CarParams.Ecu
|
||||
|
||||
FW_VERSIONS = {
|
||||
CAR.CHRYSLER_PACIFICA_2018: {
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
#!/usr/bin/env python3
|
||||
from cereal import car
|
||||
from panda import Panda
|
||||
from openpilot.selfdrive.car import get_safety_config
|
||||
from openpilot.selfdrive.car import get_safety_config, structs
|
||||
from openpilot.selfdrive.car.chrysler.values import CAR, RAM_HD, RAM_DT, RAM_CARS, ChryslerFlags
|
||||
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
|
||||
|
||||
|
||||
class CarInterface(CarInterfaceBase):
|
||||
@staticmethod
|
||||
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
|
||||
def _get_params(ret: structs.CarParams, candidate, fingerprint, car_fw, experimental_long, docs) -> structs.CarParams:
|
||||
ret.carName = "chrysler"
|
||||
ret.dashcamOnly = candidate in RAM_HD
|
||||
|
||||
|
@ -18,7 +17,7 @@ class CarInterface(CarInterfaceBase):
|
|||
ret.steerLimitTimer = 0.4
|
||||
|
||||
# safety config
|
||||
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.chrysler)]
|
||||
ret.safetyConfigs = [get_safety_config(structs.CarParams.SafetyModel.chrysler)]
|
||||
if candidate in RAM_HD:
|
||||
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_CHRYSLER_RAM_HD
|
||||
elif candidate in RAM_DT:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
from opendbc.can.parser import CANParser
|
||||
from cereal import car
|
||||
from openpilot.selfdrive.car import structs
|
||||
from openpilot.selfdrive.car.interfaces import RadarInterfaceBase
|
||||
from openpilot.selfdrive.car.chrysler.values import DBC
|
||||
|
||||
|
@ -53,7 +53,7 @@ class RadarInterface(RadarInterfaceBase):
|
|||
if self.trigger_msg not in self.updated_messages:
|
||||
return None
|
||||
|
||||
ret = car.RadarData.new_message()
|
||||
ret = structs.RadarData()
|
||||
errors = []
|
||||
if not self.rcp.can_valid:
|
||||
errors.append("canError")
|
||||
|
@ -64,7 +64,7 @@ class RadarInterface(RadarInterfaceBase):
|
|||
trackId = _address_to_track(ii)
|
||||
|
||||
if trackId not in self.pts:
|
||||
self.pts[trackId] = car.RadarData.RadarPoint.new_message()
|
||||
self.pts[trackId] = structs.RadarData.RadarPoint()
|
||||
self.pts[trackId].trackId = trackId
|
||||
self.pts[trackId].aRel = float('nan')
|
||||
self.pts[trackId].yvRel = float('nan')
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
from enum import IntFlag
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
from cereal import car
|
||||
from panda.python import uds
|
||||
from openpilot.selfdrive.car import CarSpecs, DbcDict, PlatformConfig, Platforms, dbc_dict
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.docs_definitions import CarHarness, CarDocs, CarParts
|
||||
from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, p16
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
Ecu = CarParams.Ecu
|
||||
|
||||
|
||||
class ChryslerFlags(IntFlag):
|
||||
|
|
|
@ -3,8 +3,8 @@ import jinja2
|
|||
from enum import Enum
|
||||
from natsort import natsorted
|
||||
|
||||
from cereal import car
|
||||
from openpilot.selfdrive.car import gen_empty_fingerprint
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.docs_definitions import CarDocs, Column, CommonFootnote, PartType
|
||||
from openpilot.selfdrive.car.car_helpers import interfaces, get_interface_attr
|
||||
from openpilot.selfdrive.car.values import PLATFORMS
|
||||
|
@ -24,7 +24,7 @@ def get_all_car_docs() -> list[CarDocs]:
|
|||
car_docs = platform.config.car_docs
|
||||
# If available, uses experimental longitudinal limits for the docs
|
||||
CP = interfaces[model][0].get_params(platform, fingerprint=gen_empty_fingerprint(),
|
||||
car_fw=[car.CarParams.CarFw(ecu="unknown")], experimental_long=True, docs=True)
|
||||
car_fw=[CarParams.CarFw(ecu=CarParams.Ecu.unknown)], experimental_long=True, docs=True)
|
||||
|
||||
if CP.dashcamOnly or not len(car_docs):
|
||||
continue
|
||||
|
|
|
@ -4,8 +4,8 @@ import copy
|
|||
from dataclasses import dataclass, field
|
||||
from enum import Enum
|
||||
|
||||
from cereal import car
|
||||
from openpilot.selfdrive.car.conversions import Conversions as CV
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
|
||||
GOOD_TORQUE_THRESHOLD = 1.0 # m/s^2
|
||||
MODEL_YEARS_RE = r"(?<= )((\d{4}-\d{2})|(\d{4}))(,|$)"
|
||||
|
@ -248,7 +248,7 @@ class CarDocs:
|
|||
self.make, self.model, self.years = split_name(self.name)
|
||||
self.year_list = get_year_list(self.years)
|
||||
|
||||
def init(self, CP: car.CarParams, all_footnotes: dict[Enum, int]):
|
||||
def init(self, CP: CarParams, all_footnotes: dict[Enum, int]):
|
||||
self.car_name = CP.carName
|
||||
self.car_fingerprint = CP.carFingerprint
|
||||
|
||||
|
@ -316,7 +316,7 @@ class CarDocs:
|
|||
|
||||
return self
|
||||
|
||||
def init_make(self, CP: car.CarParams):
|
||||
def init_make(self, CP: CarParams):
|
||||
"""CarDocs subclasses can add make-specific logic for harness selection, footnotes, etc."""
|
||||
|
||||
def get_detail_sentence(self, CP):
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
from cereal import car
|
||||
import copy
|
||||
from opendbc.can.packer import CANPacker
|
||||
from openpilot.selfdrive.car import apply_std_steer_angle_limits
|
||||
from openpilot.selfdrive.car import apply_std_steer_angle_limits, structs
|
||||
from openpilot.selfdrive.car.ford import fordcan
|
||||
from openpilot.selfdrive.car.ford.values import CarControllerParams, FordFlags
|
||||
from openpilot.selfdrive.car.common.numpy_fast import clip
|
||||
from openpilot.selfdrive.car.interfaces import CarControllerBase, V_CRUISE_MAX
|
||||
|
||||
LongCtrlState = car.CarControl.Actuators.LongControlState
|
||||
VisualAlert = car.CarControl.HUDControl.VisualAlert
|
||||
LongCtrlState = structs.CarControl.Actuators.LongControlState
|
||||
VisualAlert = structs.CarControl.HUDControl.VisualAlert
|
||||
|
||||
|
||||
def apply_ford_curvature_limits(apply_curvature, apply_curvature_last, current_curvature, v_ego_raw):
|
||||
|
@ -111,7 +111,7 @@ class CarController(CarControllerBase):
|
|||
self.steer_alert_last = steer_alert
|
||||
self.lead_distance_bars_last = hud_control.leadDistanceBars
|
||||
|
||||
new_actuators = actuators.as_builder()
|
||||
new_actuators = copy.copy(actuators)
|
||||
new_actuators.curvature = self.apply_curvature_last
|
||||
|
||||
self.frame += 1
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
from cereal import car
|
||||
from opendbc.can.can_define import CANDefine
|
||||
from opendbc.can.parser import CANParser
|
||||
from openpilot.selfdrive.car import create_button_events
|
||||
from openpilot.selfdrive.car import create_button_events, structs
|
||||
from openpilot.selfdrive.car.conversions import Conversions as CV
|
||||
from openpilot.selfdrive.car.ford.fordcan import CanBus
|
||||
from openpilot.selfdrive.car.ford.values import DBC, CarControllerParams, FordFlags
|
||||
from openpilot.selfdrive.car.interfaces import CarStateBase
|
||||
|
||||
ButtonType = car.CarState.ButtonEvent.Type
|
||||
GearShifter = car.CarState.GearShifter
|
||||
TransmissionType = car.CarParams.TransmissionType
|
||||
ButtonType = structs.CarState.ButtonEvent.Type
|
||||
GearShifter = structs.CarState.GearShifter
|
||||
TransmissionType = structs.CarParams.TransmissionType
|
||||
|
||||
|
||||
class CarState(CarStateBase):
|
||||
|
@ -21,8 +20,8 @@ class CarState(CarStateBase):
|
|||
|
||||
self.distance_button = 0
|
||||
|
||||
def update(self, cp, cp_cam, *_):
|
||||
ret = car.CarState.new_message()
|
||||
def update(self, cp, cp_cam, *_) -> structs.CarState:
|
||||
ret = structs.CarState()
|
||||
|
||||
# Occasionally on startup, the ABS module recalibrates the steering pinion offset, so we need to block engagement
|
||||
# The vehicle usually recovers out of this state within a minute of normal driving
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from cereal import car
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.ford.values import CAR
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
Ecu = CarParams.Ecu
|
||||
|
||||
FW_VERSIONS = {
|
||||
CAR.FORD_BRONCO_SPORT_MK1: {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
from cereal import car
|
||||
from openpilot.selfdrive.car import CanBusBase
|
||||
from openpilot.selfdrive.car import CanBusBase, structs
|
||||
|
||||
HUDControl = car.CarControl.HUDControl
|
||||
HUDControl = structs.CarControl.HUDControl
|
||||
|
||||
|
||||
class CanBus(CanBusBase):
|
||||
|
|
|
@ -1,29 +1,28 @@
|
|||
from cereal import car
|
||||
from panda import Panda
|
||||
from openpilot.selfdrive.car import get_safety_config
|
||||
from openpilot.selfdrive.car import get_safety_config, structs
|
||||
from openpilot.selfdrive.car.conversions import Conversions as CV
|
||||
from openpilot.selfdrive.car.ford.fordcan import CanBus
|
||||
from openpilot.selfdrive.car.ford.values import Ecu, FordFlags
|
||||
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
|
||||
|
||||
TransmissionType = car.CarParams.TransmissionType
|
||||
TransmissionType = structs.CarParams.TransmissionType
|
||||
|
||||
|
||||
class CarInterface(CarInterfaceBase):
|
||||
@staticmethod
|
||||
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
|
||||
def _get_params(ret: structs.CarParams, candidate, fingerprint, car_fw, experimental_long, docs) -> structs.CarParams:
|
||||
ret.carName = "ford"
|
||||
ret.dashcamOnly = bool(ret.flags & FordFlags.CANFD)
|
||||
|
||||
ret.radarUnavailable = True
|
||||
ret.steerControlType = car.CarParams.SteerControlType.angle
|
||||
ret.steerControlType = structs.CarParams.SteerControlType.angle
|
||||
ret.steerActuatorDelay = 0.2
|
||||
ret.steerLimitTimer = 1.0
|
||||
|
||||
CAN = CanBus(fingerprint=fingerprint)
|
||||
cfgs = [get_safety_config(car.CarParams.SafetyModel.ford)]
|
||||
cfgs = [get_safety_config(structs.CarParams.SafetyModel.ford)]
|
||||
if CAN.main >= 4:
|
||||
cfgs.insert(0, get_safety_config(car.CarParams.SafetyModel.noOutput))
|
||||
cfgs.insert(0, get_safety_config(structs.CarParams.SafetyModel.noOutput))
|
||||
ret.safetyConfigs = cfgs
|
||||
|
||||
ret.experimentalLongitudinalAvailable = True
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from math import cos, sin
|
||||
from cereal import car
|
||||
from opendbc.can.parser import CANParser
|
||||
from openpilot.selfdrive.car import structs
|
||||
from openpilot.selfdrive.car.conversions import Conversions as CV
|
||||
from openpilot.selfdrive.car.ford.fordcan import CanBus
|
||||
from openpilot.selfdrive.car.ford.values import DBC, RADAR
|
||||
|
@ -58,7 +58,7 @@ class RadarInterface(RadarInterfaceBase):
|
|||
if self.trigger_msg not in self.updated_messages:
|
||||
return None
|
||||
|
||||
ret = car.RadarData.new_message()
|
||||
ret = structs.RadarData()
|
||||
errors = []
|
||||
if not self.rcp.can_valid:
|
||||
errors.append("canError")
|
||||
|
@ -89,7 +89,7 @@ class RadarInterface(RadarInterfaceBase):
|
|||
# radar point only valid if there have been enough valid measurements
|
||||
if self.valid_cnt[ii] > 0:
|
||||
if ii not in self.pts:
|
||||
self.pts[ii] = car.RadarData.RadarPoint.new_message()
|
||||
self.pts[ii] = structs.RadarData.RadarPoint()
|
||||
self.pts[ii].trackId = self.track_id
|
||||
self.track_id += 1
|
||||
self.pts[ii].dRel = cpt['X_Rel'] # from front of car
|
||||
|
@ -112,7 +112,7 @@ class RadarInterface(RadarInterfaceBase):
|
|||
i = (ii - 1) * 4 + scanIndex
|
||||
|
||||
if i not in self.pts:
|
||||
self.pts[i] = car.RadarData.RadarPoint.new_message()
|
||||
self.pts[i] = structs.RadarData.RadarPoint()
|
||||
self.pts[i].trackId = self.track_id
|
||||
self.pts[i].aRel = float('nan')
|
||||
self.pts[i].yvRel = float('nan')
|
||||
|
|
|
@ -1,30 +1,28 @@
|
|||
#!/usr/bin/env python3
|
||||
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.fingerprints import FW_VERSIONS
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
ECU_NAME = {v: k for k, v in Ecu.schema.enumerants.items()}
|
||||
|
||||
Ecu = CarParams.Ecu
|
||||
|
||||
if __name__ == "__main__":
|
||||
cars_for_code: defaultdict = defaultdict(lambda: defaultdict(set))
|
||||
|
||||
for car_model, ecus in FW_VERSIONS.items():
|
||||
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])
|
||||
for code in platform_codes:
|
||||
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()
|
||||
|
||||
print('\nCar models vs. platform codes:')
|
||||
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():
|
||||
print(f' {code!r}: {sorted(map(str, cars))}')
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
import random
|
||||
from collections.abc import Iterable
|
||||
|
||||
import capnp
|
||||
from hypothesis import settings, given, strategies as st
|
||||
from parameterized import parameterized
|
||||
|
||||
from cereal import car
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.fw_versions import build_fw_dict
|
||||
from openpilot.selfdrive.car.ford.values import CAR, FW_QUERY_CONFIG, FW_PATTERN, get_platform_codes
|
||||
from openpilot.selfdrive.car.ford.fingerprints import FW_VERSIONS
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
Ecu = CarParams.Ecu
|
||||
|
||||
|
||||
ECU_ADDRESSES = {
|
||||
|
@ -49,7 +48,7 @@ class TestFordFW:
|
|||
assert subaddr is None, "Unexpected ECU subaddress"
|
||||
|
||||
@parameterized.expand(FW_VERSIONS.items())
|
||||
def test_fw_versions(self, car_model: str, fw_versions: dict[tuple[capnp.lib.capnp._EnumModule, int, int | None], Iterable[bytes]]):
|
||||
def test_fw_versions(self, car_model: str, fw_versions: dict[tuple[Ecu, int, int | None], Iterable[bytes]]):
|
||||
for (ecu, addr, subaddr), fws in fw_versions.items():
|
||||
assert ecu in ECU_PART_NUMBER, "Unexpected ECU"
|
||||
assert addr == ECU_ADDRESSES[ecu], "ECU address mismatch"
|
||||
|
@ -93,10 +92,10 @@ class TestFordFW:
|
|||
for ecu, fw_versions in fw_by_addr.items():
|
||||
ecu_name, addr, sub_addr = ecu
|
||||
fw = random.choice(fw_versions)
|
||||
car_fw.append({"ecu": ecu_name, "fwVersion": fw, "address": addr,
|
||||
"subAddress": 0 if sub_addr is None else sub_addr})
|
||||
car_fw.append(CarParams.CarFw(ecu=ecu_name, fwVersion=fw, address=addr,
|
||||
subAddress=0 if sub_addr is None else sub_addr))
|
||||
|
||||
CP = car.CarParams.new_message(carFw=car_fw)
|
||||
CP = CarParams(carFw=car_fw)
|
||||
matches = FW_QUERY_CONFIG.match_fw_to_car_fuzzy(build_fw_dict(CP.carFw), CP.carVin, FW_VERSIONS)
|
||||
assert matches == {platform}
|
||||
|
||||
|
|
|
@ -4,13 +4,13 @@ from dataclasses import dataclass, field, replace
|
|||
from enum import Enum, IntFlag
|
||||
|
||||
import panda.python.uds as uds
|
||||
from cereal import car
|
||||
from openpilot.selfdrive.car import AngleRateLimit, CarSpecs, dbc_dict, DbcDict, PlatformConfig, Platforms
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column, \
|
||||
Device
|
||||
from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, LiveFwVersions, OfflineFwVersions, Request, StdQueries, p16
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
Ecu = CarParams.Ecu
|
||||
|
||||
|
||||
class CarControllerParams:
|
||||
|
@ -65,7 +65,7 @@ class FordCarDocs(CarDocs):
|
|||
hybrid: bool = False
|
||||
plug_in_hybrid: bool = False
|
||||
|
||||
def init_make(self, CP: car.CarParams):
|
||||
def init_make(self, CP: CarParams):
|
||||
harness = CarHarness.ford_q4 if CP.flags & FordFlags.CANFD else CarHarness.ford_q3
|
||||
if CP.carFingerprint in (CAR.FORD_BRONCO_SPORT_MK1, CAR.FORD_MAVERICK_MK1, CAR.FORD_F_150_MK14, CAR.FORD_F_150_LIGHTNING_MK1):
|
||||
self.car_parts = CarParts([Device.threex_angled_mount, harness])
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import capnp
|
||||
import copy
|
||||
from dataclasses import dataclass, field
|
||||
import struct
|
||||
|
@ -6,9 +5,11 @@ from collections.abc import Callable
|
|||
|
||||
import panda.python.uds as uds
|
||||
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
|
||||
AddrType = tuple[int, int | None]
|
||||
EcuAddrBusType = tuple[int, int | None, int]
|
||||
EcuAddrSubAddr = tuple[int, int, int | None]
|
||||
EcuAddrSubAddr = tuple[CarParams.Ecu, int, int | None]
|
||||
|
||||
LiveFwVersions = dict[AddrType, set[bytes]]
|
||||
OfflineFwVersions = dict[str, dict[EcuAddrSubAddr, list[bytes]]]
|
||||
|
@ -77,7 +78,7 @@ class StdQueries:
|
|||
class Request:
|
||||
request: list[bytes]
|
||||
response: list[bytes]
|
||||
whitelist_ecus: list[int] = field(default_factory=list)
|
||||
whitelist_ecus: list[CarParams.Ecu] = field(default_factory=list)
|
||||
rx_offset: int = 0x8
|
||||
bus: int = 1
|
||||
# Whether this query should be run on the first auxiliary panda (CAN FD cars for example)
|
||||
|
@ -93,9 +94,9 @@ class FwQueryConfig:
|
|||
requests: list[Request]
|
||||
# TODO: make this automatic and remove hardcoded lists, or do fingerprinting with ecus
|
||||
# Overrides and removes from essential ecus for specific models and ecus (exact matching)
|
||||
non_essential_ecus: dict[capnp.lib.capnp._EnumModule, list[str]] = field(default_factory=dict)
|
||||
non_essential_ecus: dict[CarParams.Ecu, list[str]] = field(default_factory=dict)
|
||||
# Ecus added for data collection, not to be fingerprinted on
|
||||
extra_ecus: list[tuple[capnp.lib.capnp._EnumModule, int, int | None]] = field(default_factory=list)
|
||||
extra_ecus: list[tuple[CarParams.Ecu, int, int | None]] = field(default_factory=list)
|
||||
# Function a brand can implement to provide better fuzzy matching. Takes in FW versions and VIN,
|
||||
# returns set of candidates. Only will match if one candidate is returned
|
||||
match_fw_to_car_fuzzy: Callable[[LiveFwVersions, str, OfflineFwVersions], set[str]] | None = None
|
||||
|
|
|
@ -3,19 +3,18 @@ from collections.abc import Callable, Iterator
|
|||
from typing import Protocol, TypeVar
|
||||
|
||||
from tqdm import tqdm
|
||||
import capnp
|
||||
|
||||
import panda.python.uds as uds
|
||||
from cereal import car
|
||||
from openpilot.selfdrive.car import carlog
|
||||
from openpilot.selfdrive.car.can_definitions import CanRecvCallable, CanSendCallable
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.ecu_addrs import get_ecu_addrs
|
||||
from openpilot.selfdrive.car.fingerprints import FW_VERSIONS
|
||||
from openpilot.selfdrive.car.can_definitions import CanRecvCallable, CanSendCallable
|
||||
from openpilot.selfdrive.car.fw_query_definitions import AddrType, EcuAddrBusType, FwQueryConfig, LiveFwVersions, OfflineFwVersions
|
||||
from openpilot.selfdrive.car.interfaces import get_interface_attr
|
||||
from openpilot.selfdrive.car.isotp_parallel_query import IsoTpParallelQuery
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
Ecu = CarParams.Ecu
|
||||
ESSENTIAL_ECUS = [Ecu.engine, Ecu.eps, Ecu.abs, Ecu.fwdRadar, Ecu.fwdCamera, Ecu.vsa]
|
||||
FUZZY_EXCLUDE_ECUS = [Ecu.fwdCamera, Ecu.fwdRadar, Ecu.eps, Ecu.debug]
|
||||
|
||||
|
@ -39,7 +38,7 @@ def is_brand(brand: str, filter_brand: str | None) -> bool:
|
|||
return filter_brand is None or brand == filter_brand
|
||||
|
||||
|
||||
def build_fw_dict(fw_versions: list[capnp.lib.capnp._DynamicStructBuilder], filter_brand: str = None) -> dict[AddrType, set[bytes]]:
|
||||
def build_fw_dict(fw_versions: list[CarParams.CarFw], filter_brand: str = None) -> dict[AddrType, set[bytes]]:
|
||||
fw_versions_dict: defaultdict[AddrType, set[bytes]] = defaultdict(set)
|
||||
for fw in fw_versions:
|
||||
if is_brand(fw.brand, filter_brand) and not fw.logging:
|
||||
|
@ -144,8 +143,8 @@ def match_fw_to_car_exact(live_fw_versions: LiveFwVersions, match_brand: str = N
|
|||
return set(candidates.keys()) - invalid
|
||||
|
||||
|
||||
def match_fw_to_car(fw_versions: list[capnp.lib.capnp._DynamicStructBuilder], vin: str,
|
||||
allow_exact: bool = True, allow_fuzzy: bool = True, log: bool = True) -> tuple[bool, set[str]]:
|
||||
def match_fw_to_car(fw_versions: list[CarParams.CarFw], vin: str, allow_exact: bool = True,
|
||||
allow_fuzzy: bool = True, log: bool = True) -> tuple[bool, set[str]]:
|
||||
# Try exact matching first
|
||||
exact_matches: list[tuple[bool, MatchFwToCar]] = []
|
||||
if allow_exact:
|
||||
|
@ -229,7 +228,7 @@ def get_brand_ecu_matches(ecu_rx_addrs: set[EcuAddrBusType]) -> dict[str, set[Ad
|
|||
|
||||
def get_fw_versions_ordered(can_recv: CanRecvCallable, can_send: CanSendCallable, set_obd_multiplexing: ObdCallback, vin: str,
|
||||
ecu_rx_addrs: set[EcuAddrBusType], timeout: float = 0.1, num_pandas: int = 1, debug: bool = False,
|
||||
progress: bool = False) -> list[capnp.lib.capnp._DynamicStructBuilder]:
|
||||
progress: bool = False) -> list[CarParams.CarFw]:
|
||||
"""Queries for FW versions ordering brands by likelihood, breaks when exact match is found"""
|
||||
|
||||
all_car_fw = []
|
||||
|
@ -254,7 +253,7 @@ def get_fw_versions_ordered(can_recv: CanRecvCallable, can_send: CanSendCallable
|
|||
|
||||
def get_fw_versions(can_recv: CanRecvCallable, can_send: CanSendCallable, set_obd_multiplexing: ObdCallback, query_brand: str = None,
|
||||
extra: OfflineFwVersions = None, timeout: float = 0.1, num_pandas: int = 1, debug: bool = False,
|
||||
progress: bool = False) -> list[capnp.lib.capnp._DynamicStructBuilder]:
|
||||
progress: bool = False) -> list[CarParams.CarFw]:
|
||||
versions = VERSIONS.copy()
|
||||
|
||||
if query_brand is not None:
|
||||
|
@ -306,7 +305,7 @@ def get_fw_versions(can_recv: CanRecvCallable, can_send: CanSendCallable, set_ob
|
|||
if query_addrs:
|
||||
query = IsoTpParallelQuery(can_send, can_recv, r.bus, query_addrs, r.request, r.response, r.rx_offset, debug=debug)
|
||||
for (tx_addr, sub_addr), version in query.get_data(timeout).items():
|
||||
f = car.CarParams.CarFw.new_message()
|
||||
f = CarParams.CarFw()
|
||||
|
||||
f.ecu = ecu_types.get((brand, tx_addr, sub_addr), Ecu.unknown)
|
||||
f.fwVersion = version
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
from cereal import car
|
||||
import copy
|
||||
from opendbc.can.packer import CANPacker
|
||||
from openpilot.selfdrive.car import DT_CTRL, apply_driver_steer_torque_limits
|
||||
from openpilot.selfdrive.car.conversions import Conversions as CV
|
||||
from openpilot.selfdrive.car import DT_CTRL, apply_driver_steer_torque_limits, structs
|
||||
from openpilot.selfdrive.car.gm import gmcan
|
||||
from openpilot.selfdrive.car.conversions import Conversions as CV
|
||||
from openpilot.selfdrive.car.gm.values import DBC, CanBus, CarControllerParams, CruiseButtons
|
||||
from openpilot.selfdrive.car.common.numpy_fast import interp
|
||||
from openpilot.selfdrive.car.interfaces import CarControllerBase
|
||||
|
||||
VisualAlert = car.CarControl.HUDControl.VisualAlert
|
||||
NetworkLocation = car.CarParams.NetworkLocation
|
||||
LongCtrlState = car.CarControl.Actuators.LongControlState
|
||||
VisualAlert = structs.CarControl.HUDControl.VisualAlert
|
||||
NetworkLocation = structs.CarParams.NetworkLocation
|
||||
LongCtrlState = structs.CarControl.Actuators.LongControlState
|
||||
|
||||
# Camera cancels up to 0.1s after brake is pressed, ECM allows 0.5s
|
||||
CAMERA_CANCEL_DELAY_FRAMES = 10
|
||||
|
@ -153,7 +153,7 @@ class CarController(CarControllerBase):
|
|||
if self.frame % 10 == 0:
|
||||
can_sends.append(gmcan.create_pscm_status(self.packer_pt, CanBus.CAMERA, CS.pscm_status))
|
||||
|
||||
new_actuators = actuators.as_builder()
|
||||
new_actuators = copy.copy(actuators)
|
||||
new_actuators.steer = self.apply_steer_last / self.params.STEER_MAX
|
||||
new_actuators.steerOutputCan = self.apply_steer_last
|
||||
new_actuators.gas = self.apply_gas
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
import copy
|
||||
from cereal import car
|
||||
from opendbc.can.can_define import CANDefine
|
||||
from opendbc.can.parser import CANParser
|
||||
from openpilot.selfdrive.car import create_button_events
|
||||
from openpilot.selfdrive.car import create_button_events, structs
|
||||
from openpilot.selfdrive.car.conversions import Conversions as CV
|
||||
from openpilot.selfdrive.car.common.numpy_fast import mean
|
||||
from openpilot.selfdrive.car.interfaces import CarStateBase
|
||||
from openpilot.selfdrive.car.gm.values import DBC, AccState, CanBus, CruiseButtons, STEER_THRESHOLD
|
||||
|
||||
ButtonType = car.CarState.ButtonEvent.Type
|
||||
TransmissionType = car.CarParams.TransmissionType
|
||||
NetworkLocation = car.CarParams.NetworkLocation
|
||||
ButtonType = structs.CarState.ButtonEvent.Type
|
||||
TransmissionType = structs.CarParams.TransmissionType
|
||||
NetworkLocation = structs.CarParams.NetworkLocation
|
||||
|
||||
STANDSTILL_THRESHOLD = 10 * 0.0311 * CV.KPH_TO_MS
|
||||
|
||||
|
@ -34,8 +33,8 @@ class CarState(CarStateBase):
|
|||
|
||||
self.distance_button = 0
|
||||
|
||||
def update(self, pt_cp, cam_cp, _, __, loopback_cp):
|
||||
ret = car.CarState.new_message()
|
||||
def update(self, pt_cp, cam_cp, _, __, loopback_cp) -> structs.CarState:
|
||||
ret = structs.CarState()
|
||||
|
||||
prev_cruise_buttons = self.cruise_buttons
|
||||
prev_distance_button = self.distance_button
|
||||
|
|
|
@ -1,18 +1,17 @@
|
|||
#!/usr/bin/env python3
|
||||
import os
|
||||
from cereal import car
|
||||
from math import fabs, exp
|
||||
from panda import Panda
|
||||
|
||||
from openpilot.selfdrive.car import get_safety_config, get_friction
|
||||
from openpilot.selfdrive.car import get_safety_config, get_friction, structs
|
||||
from openpilot.selfdrive.car.common.basedir import BASEDIR
|
||||
from openpilot.selfdrive.car.conversions import Conversions as CV
|
||||
from openpilot.selfdrive.car.gm.radar_interface import RADAR_HEADER_MSG
|
||||
from openpilot.selfdrive.car.gm.values import CAR, CarControllerParams, EV_CAR, CAMERA_ACC_CAR, CanBus
|
||||
from openpilot.selfdrive.car.interfaces import CarInterfaceBase, TorqueFromLateralAccelCallbackType, FRICTION_THRESHOLD, LatControlInputs, NanoFFModel
|
||||
|
||||
TransmissionType = car.CarParams.TransmissionType
|
||||
NetworkLocation = car.CarParams.NetworkLocation
|
||||
TransmissionType = structs.CarParams.TransmissionType
|
||||
NetworkLocation = structs.CarParams.NetworkLocation
|
||||
|
||||
NON_LINEAR_TORQUE_PARAMS = {
|
||||
CAR.CHEVROLET_BOLT_EUV: [2.6531724862969748, 1.0, 0.1919764879840985, 0.009054123646805178],
|
||||
|
@ -41,8 +40,8 @@ class CarInterface(CarInterfaceBase):
|
|||
else:
|
||||
return CarInterfaceBase.get_steer_feedforward_default
|
||||
|
||||
def torque_from_lateral_accel_siglin(self, latcontrol_inputs: LatControlInputs, torque_params: car.CarParams.LateralTorqueTuning, lateral_accel_error: float,
|
||||
lateral_accel_deadzone: float, friction_compensation: bool, gravity_adjusted: bool) -> float:
|
||||
def torque_from_lateral_accel_siglin(self, latcontrol_inputs: LatControlInputs, torque_params: structs.CarParams.LateralTorqueTuning,
|
||||
lateral_accel_error: float, lateral_accel_deadzone: float, friction_compensation: bool, gravity_adjusted: bool) -> float:
|
||||
friction = get_friction(lateral_accel_error, lateral_accel_deadzone, FRICTION_THRESHOLD, torque_params, friction_compensation)
|
||||
|
||||
def sig(val):
|
||||
|
@ -57,14 +56,14 @@ class CarInterface(CarInterfaceBase):
|
|||
# An important thing to consider is that the slope at 0 should be > 0 (ideally >1)
|
||||
# This has big effect on the stability about 0 (noise when going straight)
|
||||
# ToDo: To generalize to other GMs, explore tanh function as the nonlinear
|
||||
non_linear_torque_params = NON_LINEAR_TORQUE_PARAMS.get(self.CP.carFingerprint)
|
||||
non_linear_torque_params = NON_LINEAR_TORQUE_PARAMS.get(self.CP.carFingerprint) # type: ignore[call-overload]
|
||||
assert non_linear_torque_params, "The params are not defined"
|
||||
a, b, c, _ = non_linear_torque_params
|
||||
steer_torque = (sig(latcontrol_inputs.lateral_acceleration * a) * b) + (latcontrol_inputs.lateral_acceleration * c)
|
||||
return float(steer_torque) + friction
|
||||
|
||||
def torque_from_lateral_accel_neural(self, latcontrol_inputs: LatControlInputs, torque_params: car.CarParams.LateralTorqueTuning, lateral_accel_error: float,
|
||||
lateral_accel_deadzone: float, friction_compensation: bool, gravity_adjusted: bool) -> float:
|
||||
def torque_from_lateral_accel_neural(self, latcontrol_inputs: LatControlInputs, torque_params: structs.CarParams.LateralTorqueTuning,
|
||||
lateral_accel_error: float, lateral_accel_deadzone: float, friction_compensation: bool, gravity_adjusted: bool) -> float:
|
||||
friction = get_friction(lateral_accel_error, lateral_accel_deadzone, FRICTION_THRESHOLD, torque_params, friction_compensation)
|
||||
inputs = list(latcontrol_inputs)
|
||||
if gravity_adjusted:
|
||||
|
@ -81,9 +80,9 @@ class CarInterface(CarInterfaceBase):
|
|||
return self.torque_from_lateral_accel_linear
|
||||
|
||||
@staticmethod
|
||||
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
|
||||
def _get_params(ret: structs.CarParams, candidate, fingerprint, car_fw, experimental_long, docs) -> structs.CarParams:
|
||||
ret.carName = "gm"
|
||||
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.gm)]
|
||||
ret.safetyConfigs = [get_safety_config(structs.CarParams.SafetyModel.gm)]
|
||||
ret.autoResumeSng = False
|
||||
ret.enableBsm = 0x142 in fingerprint[CanBus.POWERTRAIN]
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
import math
|
||||
from cereal import car
|
||||
from opendbc.can.parser import CANParser
|
||||
from openpilot.selfdrive.car import structs
|
||||
from openpilot.selfdrive.car.conversions import Conversions as CV
|
||||
from openpilot.selfdrive.car.gm.values import DBC, CanBus
|
||||
from openpilot.selfdrive.car.interfaces import RadarInterfaceBase
|
||||
|
@ -52,7 +52,7 @@ class RadarInterface(RadarInterfaceBase):
|
|||
if self.trigger_msg not in self.updated_messages:
|
||||
return None
|
||||
|
||||
ret = car.RadarData.new_message()
|
||||
ret = structs.RadarData()
|
||||
header = self.rcp.vl[RADAR_HEADER_MSG]
|
||||
fault = header['FLRRSnsrBlckd'] or header['FLRRSnstvFltPrsntInt'] or \
|
||||
header['FLRRYawRtPlsblityFlt'] or header['FLRRHWFltPrsntInt'] or \
|
||||
|
@ -82,7 +82,7 @@ class RadarInterface(RadarInterfaceBase):
|
|||
targetId = cpt['TrkObjectID']
|
||||
currentTargets.add(targetId)
|
||||
if targetId not in self.pts:
|
||||
self.pts[targetId] = car.RadarData.RadarPoint.new_message()
|
||||
self.pts[targetId] = structs.RadarData.RadarPoint()
|
||||
self.pts[targetId].trackId = targetId
|
||||
distance = cpt['TrkRange']
|
||||
self.pts[targetId].dRel = distance # from front of car
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
from dataclasses import dataclass, field
|
||||
|
||||
from cereal import car
|
||||
from openpilot.selfdrive.car import dbc_dict, PlatformConfig, DbcDict, Platforms, CarSpecs
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.docs_definitions import CarHarness, CarDocs, CarParts
|
||||
from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
Ecu = CarParams.Ecu
|
||||
|
||||
|
||||
class CarControllerParams:
|
||||
|
@ -63,8 +63,8 @@ class CarControllerParams:
|
|||
class GMCarDocs(CarDocs):
|
||||
package: str = "Adaptive Cruise Control (ACC)"
|
||||
|
||||
def init_make(self, CP: car.CarParams):
|
||||
if CP.networkLocation == car.CarParams.NetworkLocation.fwdCamera:
|
||||
def init_make(self, CP: CarParams):
|
||||
if CP.networkLocation == CarParams.NetworkLocation.fwdCamera:
|
||||
self.car_parts = CarParts.common([CarHarness.gm])
|
||||
else:
|
||||
self.car_parts = CarParts.common([CarHarness.obd_ii])
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import copy
|
||||
from collections import namedtuple
|
||||
|
||||
from cereal import car
|
||||
from opendbc.can.packer import CANPacker
|
||||
from openpilot.selfdrive.car import DT_CTRL, rate_limit, make_tester_present_msg
|
||||
from openpilot.selfdrive.car import DT_CTRL, rate_limit, make_tester_present_msg, structs
|
||||
from openpilot.selfdrive.car.common.numpy_fast import clip, interp
|
||||
from openpilot.selfdrive.car.honda import hondacan
|
||||
from openpilot.selfdrive.car.honda.values import CruiseButtons, VISUAL_HUD, HONDA_BOSCH, HONDA_BOSCH_RADARLESS, HONDA_NIDEC_ALT_PCM_ACCEL, CarControllerParams
|
||||
from openpilot.selfdrive.car.interfaces import CarControllerBase
|
||||
|
||||
VisualAlert = car.CarControl.HUDControl.VisualAlert
|
||||
LongCtrlState = car.CarControl.Actuators.LongControlState
|
||||
VisualAlert = structs.CarControl.HUDControl.VisualAlert
|
||||
LongCtrlState = structs.CarControl.Actuators.LongControlState
|
||||
|
||||
|
||||
def compute_gb_honda_bosch(accel, speed):
|
||||
|
@ -83,11 +83,11 @@ def process_hud_alert(hud_alert):
|
|||
|
||||
# priority is: FCW, steer required, all others
|
||||
if hud_alert == VisualAlert.fcw:
|
||||
fcw_display = VISUAL_HUD[hud_alert.raw]
|
||||
fcw_display = VISUAL_HUD[hud_alert]
|
||||
elif hud_alert in (VisualAlert.steerRequired, VisualAlert.ldw):
|
||||
steer_required = VISUAL_HUD[hud_alert.raw]
|
||||
steer_required = VISUAL_HUD[hud_alert]
|
||||
else:
|
||||
acc_alert = VISUAL_HUD[hud_alert.raw]
|
||||
acc_alert = VISUAL_HUD[hud_alert]
|
||||
|
||||
return fcw_display, steer_required, acc_alert
|
||||
|
||||
|
@ -242,7 +242,7 @@ class CarController(CarControllerBase):
|
|||
self.speed = pcm_speed
|
||||
self.gas = pcm_accel / self.params.NIDEC_GAS_MAX
|
||||
|
||||
new_actuators = actuators.as_builder()
|
||||
new_actuators = copy.copy(actuators)
|
||||
new_actuators.speed = self.speed
|
||||
new_actuators.accel = self.accel
|
||||
new_actuators.gas = self.gas
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
from collections import defaultdict
|
||||
|
||||
from cereal import car
|
||||
from opendbc.can.can_define import CANDefine
|
||||
from opendbc.can.parser import CANParser
|
||||
from openpilot.selfdrive.car import create_button_events
|
||||
from openpilot.selfdrive.car import create_button_events, structs
|
||||
from openpilot.selfdrive.car.conversions import Conversions as CV
|
||||
from openpilot.selfdrive.car.common.numpy_fast import interp
|
||||
from openpilot.selfdrive.car.honda.hondacan import CanBus, get_cruise_speed_conversion
|
||||
|
@ -12,8 +11,8 @@ from openpilot.selfdrive.car.honda.values import CAR, DBC, STEER_THRESHOLD, HOND
|
|||
HondaFlags, CruiseButtons, CruiseSettings
|
||||
from openpilot.selfdrive.car.interfaces import CarStateBase
|
||||
|
||||
TransmissionType = car.CarParams.TransmissionType
|
||||
ButtonType = car.CarState.ButtonEvent.Type
|
||||
TransmissionType = structs.CarParams.TransmissionType
|
||||
ButtonType = structs.CarState.ButtonEvent.Type
|
||||
|
||||
BUTTONS_DICT = {CruiseButtons.RES_ACCEL: ButtonType.accelCruise, CruiseButtons.DECEL_SET: ButtonType.decelCruise,
|
||||
CruiseButtons.MAIN: ButtonType.altButton3, CruiseButtons.CANCEL: ButtonType.cancel}
|
||||
|
@ -110,8 +109,8 @@ class CarState(CarStateBase):
|
|||
# However, on cars without a digital speedometer this is not always present (HRV, FIT, CRV 2016, ILX and RDX)
|
||||
self.dash_speed_seen = False
|
||||
|
||||
def update(self, cp, cp_cam, _, cp_body, __):
|
||||
ret = car.CarState.new_message()
|
||||
def update(self, cp, cp_cam, _, cp_body, __) -> structs.CarState:
|
||||
ret = structs.CarState()
|
||||
|
||||
# car params
|
||||
v_weight_v = [0., 1.] # don't trust smooth speed at low values to avoid premature zero snapping
|
||||
|
@ -198,7 +197,7 @@ class CarState(CarStateBase):
|
|||
|
||||
ret.steeringTorque = cp.vl["STEER_STATUS"]["STEER_TORQUE_SENSOR"]
|
||||
ret.steeringTorqueEps = cp.vl["STEER_MOTOR_TORQUE"]["MOTOR_TORQUE"]
|
||||
ret.steeringPressed = abs(ret.steeringTorque) > STEER_THRESHOLD.get(self.CP.carFingerprint, 1200)
|
||||
ret.steeringPressed = abs(ret.steeringTorque) > STEER_THRESHOLD.get(self.CP.carFingerprint, 1200) # type: ignore[call-overload]
|
||||
|
||||
if self.CP.carFingerprint in HONDA_BOSCH:
|
||||
# The PCM always manages its own cruise control state, but doesn't publish it
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from cereal import car
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.honda.values import CAR
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
Ecu = CarParams.Ecu
|
||||
|
||||
# Modified FW can be identified by the second dash being replaced by a comma
|
||||
# For example: `b'39990-TVA,A150\x00\x00'`
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
#!/usr/bin/env python3
|
||||
from cereal import car
|
||||
from panda import Panda
|
||||
from openpilot.selfdrive.car import get_safety_config, structs
|
||||
from openpilot.selfdrive.car.conversions import Conversions as CV
|
||||
from openpilot.selfdrive.car.common.numpy_fast import interp
|
||||
from openpilot.selfdrive.car.honda.hondacan import CanBus
|
||||
from openpilot.selfdrive.car.honda.values import CarControllerParams, HondaFlags, CAR, HONDA_BOSCH, \
|
||||
HONDA_NIDEC_ALT_SCM_MESSAGES, HONDA_BOSCH_RADARLESS
|
||||
from openpilot.selfdrive.car import get_safety_config
|
||||
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
|
||||
from openpilot.selfdrive.car.disable_ecu import disable_ecu
|
||||
|
||||
TransmissionType = car.CarParams.TransmissionType
|
||||
TransmissionType = structs.CarParams.TransmissionType
|
||||
|
||||
|
||||
class CarInterface(CarInterfaceBase):
|
||||
|
@ -26,13 +25,13 @@ class CarInterface(CarInterfaceBase):
|
|||
return CarControllerParams.NIDEC_ACCEL_MIN, interp(current_speed, ACCEL_MAX_BP, ACCEL_MAX_VALS)
|
||||
|
||||
@staticmethod
|
||||
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
|
||||
def _get_params(ret: structs.CarParams, candidate, fingerprint, car_fw, experimental_long, docs) -> structs.CarParams:
|
||||
ret.carName = "honda"
|
||||
|
||||
CAN = CanBus(ret, fingerprint)
|
||||
|
||||
if candidate in HONDA_BOSCH:
|
||||
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.hondaBosch)]
|
||||
ret.safetyConfigs = [get_safety_config(structs.CarParams.SafetyModel.hondaBosch)]
|
||||
ret.radarUnavailable = True
|
||||
# Disable the radar and let openpilot control longitudinal
|
||||
# WARNING: THIS DISABLES AEB!
|
||||
|
@ -41,7 +40,7 @@ class CarInterface(CarInterfaceBase):
|
|||
ret.openpilotLongitudinalControl = experimental_long
|
||||
ret.pcmCruise = not ret.openpilotLongitudinalControl
|
||||
else:
|
||||
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.hondaNidec)]
|
||||
ret.safetyConfigs = [get_safety_config(structs.CarParams.SafetyModel.hondaNidec)]
|
||||
ret.openpilotLongitudinalControl = True
|
||||
|
||||
ret.pcmCruise = True
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
from cereal import car
|
||||
from opendbc.can.parser import CANParser
|
||||
from openpilot.selfdrive.car import structs
|
||||
from openpilot.selfdrive.car.interfaces import RadarInterfaceBase
|
||||
from openpilot.selfdrive.car.honda.values import DBC
|
||||
|
||||
|
@ -47,7 +47,7 @@ class RadarInterface(RadarInterfaceBase):
|
|||
return rr
|
||||
|
||||
def _update(self, updated_messages):
|
||||
ret = car.RadarData.new_message()
|
||||
ret = structs.RadarData()
|
||||
|
||||
for ii in sorted(updated_messages):
|
||||
cpt = self.rcp.vl[ii]
|
||||
|
@ -57,7 +57,7 @@ class RadarInterface(RadarInterfaceBase):
|
|||
self.radar_wrong_config = cpt['RADAR_STATE'] == 0x69
|
||||
elif cpt['LONG_DIST'] < 255:
|
||||
if ii not in self.pts or cpt['NEW_TRACK']:
|
||||
self.pts[ii] = car.RadarData.RadarPoint.new_message()
|
||||
self.pts[ii] = structs.RadarData.RadarPoint()
|
||||
self.pts[ii].trackId = self.track_id
|
||||
self.track_id += 1
|
||||
self.pts[ii].dRel = cpt['LONG_DIST'] # from front of car
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
from dataclasses import dataclass
|
||||
from enum import Enum, IntFlag
|
||||
|
||||
from cereal import car
|
||||
from panda.python import uds
|
||||
from openpilot.selfdrive.car import CarSpecs, PlatformConfig, Platforms, dbc_dict
|
||||
from openpilot.selfdrive.car import CarSpecs, PlatformConfig, Platforms, dbc_dict, structs
|
||||
from openpilot.selfdrive.car.conversions import Conversions as CV
|
||||
from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column
|
||||
from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries, p16
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
VisualAlert = car.CarControl.HUDControl.VisualAlert
|
||||
Ecu = structs.CarParams.Ecu
|
||||
VisualAlert = structs.CarControl.HUDControl.VisualAlert
|
||||
|
||||
|
||||
class CarControllerParams:
|
||||
|
@ -90,7 +89,7 @@ VISUAL_HUD = {
|
|||
class HondaCarDocs(CarDocs):
|
||||
package: str = "Honda Sensing"
|
||||
|
||||
def init_make(self, CP: car.CarParams):
|
||||
def init_make(self, CP: structs.CarParams):
|
||||
if CP.flags & HondaFlags.BOSCH:
|
||||
self.car_parts = CarParts.common([CarHarness.bosch_b]) if CP.flags & HondaFlags.BOSCH_RADARLESS else CarParts.common([CarHarness.bosch_a])
|
||||
else:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from cereal import car
|
||||
import copy
|
||||
from opendbc.can.packer import CANPacker
|
||||
from openpilot.selfdrive.car import DT_CTRL, apply_driver_steer_torque_limits, common_fault_avoidance, make_tester_present_msg
|
||||
from openpilot.selfdrive.car import DT_CTRL, apply_driver_steer_torque_limits, common_fault_avoidance, make_tester_present_msg, structs
|
||||
from openpilot.selfdrive.car.conversions import Conversions as CV
|
||||
from openpilot.selfdrive.car.common.numpy_fast import clip
|
||||
from openpilot.selfdrive.car.hyundai import hyundaicanfd, hyundaican
|
||||
|
@ -9,8 +9,8 @@ from openpilot.selfdrive.car.hyundai.hyundaicanfd import CanBus
|
|||
from openpilot.selfdrive.car.hyundai.values import HyundaiFlags, Buttons, CarControllerParams, CANFD_CAR, CAR
|
||||
from openpilot.selfdrive.car.interfaces import CarControllerBase
|
||||
|
||||
VisualAlert = car.CarControl.HUDControl.VisualAlert
|
||||
LongCtrlState = car.CarControl.Actuators.LongControlState
|
||||
VisualAlert = structs.CarControl.HUDControl.VisualAlert
|
||||
LongCtrlState = structs.CarControl.Actuators.LongControlState
|
||||
|
||||
# EPS faults if you apply torque while the steering angle is above 90 degrees for more than 1 second
|
||||
# All slightly below EPS thresholds to avoid fault
|
||||
|
@ -162,7 +162,7 @@ class CarController(CarControllerBase):
|
|||
if self.frame % 50 == 0 and self.CP.openpilotLongitudinalControl:
|
||||
can_sends.append(hyundaican.create_frt_radar_opt(self.packer))
|
||||
|
||||
new_actuators = actuators.as_builder()
|
||||
new_actuators = copy.copy(actuators)
|
||||
new_actuators.steer = apply_steer / self.params.STEER_MAX
|
||||
new_actuators.steerOutputCan = apply_steer
|
||||
new_actuators.accel = accel
|
||||
|
@ -170,7 +170,7 @@ class CarController(CarControllerBase):
|
|||
self.frame += 1
|
||||
return new_actuators, can_sends
|
||||
|
||||
def create_button_messages(self, CC: car.CarControl, CS: CarState, use_clu11: bool):
|
||||
def create_button_messages(self, CC: structs.CarControl, CS: CarState, use_clu11: bool):
|
||||
can_sends = []
|
||||
if use_clu11:
|
||||
if CC.cruiseControl.cancel:
|
||||
|
|
|
@ -2,17 +2,16 @@ from collections import deque
|
|||
import copy
|
||||
import math
|
||||
|
||||
from cereal import car
|
||||
from opendbc.can.parser import CANParser
|
||||
from opendbc.can.can_define import CANDefine
|
||||
from openpilot.selfdrive.car import create_button_events
|
||||
from openpilot.selfdrive.car import create_button_events, structs
|
||||
from openpilot.selfdrive.car.conversions import Conversions as CV
|
||||
from openpilot.selfdrive.car.hyundai.hyundaicanfd import CanBus
|
||||
from openpilot.selfdrive.car.hyundai.values import HyundaiFlags, CAR, DBC, CAN_GEARS, CAMERA_SCC_CAR, \
|
||||
CANFD_CAR, Buttons, CarControllerParams
|
||||
from openpilot.selfdrive.car.interfaces import CarStateBase
|
||||
|
||||
ButtonType = car.CarState.ButtonEvent.Type
|
||||
ButtonType = structs.CarState.ButtonEvent.Type
|
||||
|
||||
PREV_BUTTON_SAMPLES = 8
|
||||
CLUSTER_SAMPLE_RATE = 20 # frames
|
||||
|
@ -58,11 +57,11 @@ class CarState(CarStateBase):
|
|||
|
||||
self.params = CarControllerParams(CP)
|
||||
|
||||
def update(self, cp, cp_cam, *_):
|
||||
def update(self, cp, cp_cam, *_) -> structs.CarState:
|
||||
if self.CP.carFingerprint in CANFD_CAR:
|
||||
return self.update_canfd(cp, cp_cam)
|
||||
|
||||
ret = car.CarState.new_message()
|
||||
ret = structs.CarState()
|
||||
cp_cruise = cp_cam if self.CP.carFingerprint in CAMERA_SCC_CAR else cp
|
||||
self.is_metric = cp.vl["CLU11"]["CF_Clu_SPEED_UNIT"] == 0
|
||||
speed_conv = CV.KPH_TO_MS if self.is_metric else CV.MPH_TO_MS
|
||||
|
@ -177,8 +176,8 @@ class CarState(CarStateBase):
|
|||
|
||||
return ret
|
||||
|
||||
def update_canfd(self, cp, cp_cam):
|
||||
ret = car.CarState.new_message()
|
||||
def update_canfd(self, cp, cp_cam) -> structs.CarState:
|
||||
ret = structs.CarState()
|
||||
|
||||
self.is_metric = cp.vl["CRUISE_BUTTONS_ALT"]["DISTANCE_UNIT"] != 1
|
||||
speed_factor = CV.KPH_TO_MS if self.is_metric else CV.MPH_TO_MS
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from cereal import car
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.hyundai.values import CAR
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
Ecu = CarParams.Ecu
|
||||
|
||||
# The existence of SCC or RDR in the fwdRadar FW usually determines the radar's function,
|
||||
# i.e. if it sends the SCC messages or if another ECU like the camera or ADAS Driving ECU does
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
from cereal import car
|
||||
from panda import Panda
|
||||
from openpilot.selfdrive.car import get_safety_config
|
||||
from openpilot.selfdrive.car import get_safety_config, structs
|
||||
from openpilot.selfdrive.car.hyundai.hyundaicanfd import CanBus
|
||||
from openpilot.selfdrive.car.hyundai.values import HyundaiFlags, CAR, DBC, CANFD_CAR, CAMERA_SCC_CAR, CANFD_RADAR_SCC_CAR, \
|
||||
CANFD_UNSUPPORTED_LONGITUDINAL_CAR, EV_CAR, HYBRID_CAR, LEGACY_SAFETY_MODE_CAR, \
|
||||
|
@ -9,14 +8,14 @@ from openpilot.selfdrive.car.hyundai.radar_interface import RADAR_START_ADDR
|
|||
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
|
||||
from openpilot.selfdrive.car.disable_ecu import disable_ecu
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
Ecu = structs.CarParams.Ecu
|
||||
|
||||
ENABLE_BUTTONS = (Buttons.RES_ACCEL, Buttons.SET_DECEL, Buttons.CANCEL)
|
||||
|
||||
|
||||
class CarInterface(CarInterfaceBase):
|
||||
@staticmethod
|
||||
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
|
||||
def _get_params(ret: structs.CarParams, candidate, fingerprint, car_fw, experimental_long, docs) -> structs.CarParams:
|
||||
ret.carName = "hyundai"
|
||||
ret.radarUnavailable = RADAR_START_ADDR not in fingerprint[1] or DBC[ret.carFingerprint]["radar"] is None
|
||||
|
||||
|
@ -97,9 +96,9 @@ class CarInterface(CarInterfaceBase):
|
|||
|
||||
# *** panda safety config ***
|
||||
if candidate in CANFD_CAR:
|
||||
cfgs = [get_safety_config(car.CarParams.SafetyModel.hyundaiCanfd), ]
|
||||
cfgs = [get_safety_config(structs.CarParams.SafetyModel.hyundaiCanfd), ]
|
||||
if CAN.ECAN >= 4:
|
||||
cfgs.insert(0, get_safety_config(car.CarParams.SafetyModel.noOutput))
|
||||
cfgs.insert(0, get_safety_config(structs.CarParams.SafetyModel.noOutput))
|
||||
ret.safetyConfigs = cfgs
|
||||
|
||||
if ret.flags & HyundaiFlags.CANFD_HDA2:
|
||||
|
@ -113,9 +112,9 @@ class CarInterface(CarInterfaceBase):
|
|||
else:
|
||||
if candidate in LEGACY_SAFETY_MODE_CAR:
|
||||
# these cars require a special panda safety mode due to missing counters and checksums in the messages
|
||||
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.hyundaiLegacy)]
|
||||
ret.safetyConfigs = [get_safety_config(structs.CarParams.SafetyModel.hyundaiLegacy)]
|
||||
else:
|
||||
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.hyundai, 0)]
|
||||
ret.safetyConfigs = [get_safety_config(structs.CarParams.SafetyModel.hyundai, 0)]
|
||||
|
||||
if candidate in CAMERA_SCC_CAR:
|
||||
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_HYUNDAI_CAMERA_SCC
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import math
|
||||
|
||||
from cereal import car
|
||||
from opendbc.can.parser import CANParser
|
||||
from openpilot.selfdrive.car import structs
|
||||
from openpilot.selfdrive.car.interfaces import RadarInterfaceBase
|
||||
from openpilot.selfdrive.car.hyundai.values import DBC
|
||||
|
||||
|
@ -44,7 +44,7 @@ class RadarInterface(RadarInterfaceBase):
|
|||
return rr
|
||||
|
||||
def _update(self, updated_messages):
|
||||
ret = car.RadarData.new_message()
|
||||
ret = structs.RadarData()
|
||||
if self.rcp is None:
|
||||
return ret
|
||||
|
||||
|
@ -58,7 +58,7 @@ class RadarInterface(RadarInterfaceBase):
|
|||
msg = self.rcp.vl[f"RADAR_TRACK_{addr:x}"]
|
||||
|
||||
if addr not in self.pts:
|
||||
self.pts[addr] = car.RadarData.RadarPoint.new_message()
|
||||
self.pts[addr] = structs.RadarData.RadarPoint()
|
||||
self.pts[addr].trackId = self.track_id
|
||||
self.track_id += 1
|
||||
|
||||
|
|
|
@ -1,22 +1,21 @@
|
|||
#!/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.fingerprints import FW_VERSIONS
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
ECU_NAME = {v: k for k, v in Ecu.schema.enumerants.items()}
|
||||
Ecu = CarParams.Ecu
|
||||
|
||||
if __name__ == "__main__":
|
||||
for car_model, ecus in FW_VERSIONS.items():
|
||||
print()
|
||||
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:
|
||||
continue
|
||||
|
||||
platform_codes = get_platform_codes(ecus[ecu])
|
||||
codes = {code for code, _ in platform_codes}
|
||||
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' Dates: {dates}')
|
||||
|
|
|
@ -2,8 +2,8 @@ from hypothesis import settings, given, strategies as st
|
|||
|
||||
import pytest
|
||||
|
||||
from cereal import car
|
||||
from openpilot.selfdrive.car import gen_empty_fingerprint
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.fw_versions import build_fw_dict
|
||||
from openpilot.selfdrive.car.hyundai.interface import CarInterface
|
||||
from openpilot.selfdrive.car.hyundai.radar_interface import RADAR_START_ADDR
|
||||
|
@ -13,8 +13,7 @@ from openpilot.selfdrive.car.hyundai.values import CAMERA_SCC_CAR, CANFD_CAR, CA
|
|||
HyundaiFlags, get_platform_codes
|
||||
from openpilot.selfdrive.car.hyundai.fingerprints import FW_VERSIONS
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
ECU_NAME = {v: k for k, v in Ecu.schema.enumerants.items()}
|
||||
Ecu = CarParams.Ecu
|
||||
|
||||
# Some platforms have date codes in a different format we don't yet parse (or are missing).
|
||||
# For now, assert list of expected missing date cars
|
||||
|
@ -46,7 +45,7 @@ class TestHyundaiFingerprint:
|
|||
def test_feature_detection(self):
|
||||
# HDA2
|
||||
for has_adas in (True, False):
|
||||
car_fw = [car.CarParams.CarFw(ecu=Ecu.adas if has_adas else Ecu.fwdCamera)]
|
||||
car_fw = [CarParams.CarFw(ecu=Ecu.adas if has_adas else Ecu.fwdCamera)]
|
||||
CP = CarInterface.get_params(CAR.KIA_EV6, gen_empty_fingerprint(), car_fw, False, False)
|
||||
assert bool(CP.flags & HyundaiFlags.CANFD_HDA2) == has_adas
|
||||
|
||||
|
@ -76,7 +75,7 @@ class TestHyundaiFingerprint:
|
|||
for car_model in CANFD_CAR:
|
||||
ecus = {fw[0] for fw in FW_VERSIONS[car_model].keys()}
|
||||
ecus_not_in_whitelist = ecus - CANFD_EXPECTED_ECUS
|
||||
ecu_strings = ", ".join([f"Ecu.{ECU_NAME[ecu]}" for ecu in ecus_not_in_whitelist])
|
||||
ecu_strings = ", ".join([f"Ecu.{ecu}" for ecu in ecus_not_in_whitelist])
|
||||
assert len(ecus_not_in_whitelist) == 0, \
|
||||
f"{car_model}: Car model has unexpected ECUs: {ecu_strings}"
|
||||
|
||||
|
@ -223,10 +222,10 @@ class TestHyundaiFingerprint:
|
|||
for ecu, fw_versions in fw_by_addr.items():
|
||||
ecu_name, addr, sub_addr = ecu
|
||||
for fw in fw_versions:
|
||||
car_fw.append({"ecu": ecu_name, "fwVersion": fw, "address": addr,
|
||||
"subAddress": 0 if sub_addr is None else sub_addr})
|
||||
car_fw.append(CarParams.CarFw(ecu=ecu_name, fwVersion=fw, address=addr,
|
||||
subAddress=0 if sub_addr is None else sub_addr))
|
||||
|
||||
CP = car.CarParams.new_message(carFw=car_fw)
|
||||
CP = CarParams(carFw=car_fw)
|
||||
matches = FW_QUERY_CONFIG.match_fw_to_car_fuzzy(build_fw_dict(CP.carFw), CP.carVin, FW_VERSIONS)
|
||||
if len(matches) == 1:
|
||||
assert list(matches)[0] == platform
|
||||
|
|
|
@ -2,14 +2,14 @@ import re
|
|||
from dataclasses import dataclass, field
|
||||
from enum import Enum, IntFlag
|
||||
|
||||
from cereal import car
|
||||
from panda.python import uds
|
||||
from openpilot.selfdrive.car import CarSpecs, DbcDict, PlatformConfig, Platforms, dbc_dict
|
||||
from openpilot.selfdrive.car.conversions import Conversions as CV
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column
|
||||
from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, p16
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
Ecu = CarParams.Ecu
|
||||
|
||||
|
||||
class CarControllerParams:
|
||||
|
@ -107,7 +107,7 @@ class Footnote(Enum):
|
|||
class HyundaiCarDocs(CarDocs):
|
||||
package: str = "Smart Cruise Control (SCC)"
|
||||
|
||||
def init_make(self, CP: car.CarParams):
|
||||
def init_make(self, CP: CarParams):
|
||||
if CP.flags & HyundaiFlags.CANFD:
|
||||
self.footnotes.insert(0, Footnote.CANFD)
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@ from typing import Any, NamedTuple
|
|||
from collections.abc import Callable
|
||||
from functools import cache
|
||||
|
||||
from cereal import car
|
||||
from openpilot.selfdrive.car import DT_CTRL, apply_hysteresis, gen_empty_fingerprint, scale_rot_inertia, scale_tire_stiffness, get_friction, STD_CARGO_KG
|
||||
from openpilot.selfdrive.car import structs
|
||||
from openpilot.selfdrive.car.can_definitions import CanData, CanRecvCallable, CanSendCallable
|
||||
from openpilot.selfdrive.car.common.basedir import BASEDIR
|
||||
from openpilot.selfdrive.car.conversions import Conversions as CV
|
||||
|
@ -17,7 +17,7 @@ from openpilot.selfdrive.car.common.simple_kalman import KF1D, get_kalman_gain
|
|||
from openpilot.selfdrive.car.common.numpy_fast import clip
|
||||
from openpilot.selfdrive.car.values import PLATFORMS
|
||||
|
||||
GearShifter = car.CarState.GearShifter
|
||||
GearShifter = structs.CarState.GearShifter
|
||||
|
||||
V_CRUISE_MAX = 145
|
||||
MAX_CTRL_SPEED = (V_CRUISE_MAX + 4) * CV.KPH_TO_MS
|
||||
|
@ -29,7 +29,7 @@ TORQUE_PARAMS_PATH = os.path.join(BASEDIR, 'torque_data/params.toml')
|
|||
TORQUE_OVERRIDE_PATH = os.path.join(BASEDIR, 'torque_data/override.toml')
|
||||
TORQUE_SUBSTITUTE_PATH = os.path.join(BASEDIR, 'torque_data/substitute.toml')
|
||||
|
||||
GEAR_SHIFTER_MAP: dict[str, car.CarState.GearShifter] = {
|
||||
GEAR_SHIFTER_MAP: dict[str, GearShifter] = {
|
||||
'P': GearShifter.park, 'PARK': GearShifter.park,
|
||||
'R': GearShifter.reverse, 'REVERSE': GearShifter.reverse,
|
||||
'N': GearShifter.neutral, 'NEUTRAL': GearShifter.neutral,
|
||||
|
@ -49,7 +49,7 @@ class LatControlInputs(NamedTuple):
|
|||
aego: float
|
||||
|
||||
|
||||
TorqueFromLateralAccelCallbackType = Callable[[LatControlInputs, car.CarParams.LateralTorqueTuning, float, float, bool, bool], float]
|
||||
TorqueFromLateralAccelCallbackType = Callable[[LatControlInputs, structs.CarParams.LateralTorqueTuning, float, float, bool, bool], float]
|
||||
|
||||
|
||||
@cache
|
||||
|
@ -84,7 +84,7 @@ def get_torque_params():
|
|||
# generic car and radar interfaces
|
||||
|
||||
class CarInterfaceBase(ABC):
|
||||
def __init__(self, CP: car.CarParams, CarController, CarState):
|
||||
def __init__(self, CP: structs.CarParams, CarController, CarState):
|
||||
self.CP = CP
|
||||
|
||||
self.frame = 0
|
||||
|
@ -101,7 +101,7 @@ class CarInterfaceBase(ABC):
|
|||
dbc_name = "" if self.cp is None else self.cp.dbc_name
|
||||
self.CC: CarControllerBase = CarController(dbc_name, CP)
|
||||
|
||||
def apply(self, c: car.CarControl, now_nanos: int) -> tuple[car.CarControl.Actuators, list[CanData]]:
|
||||
def apply(self, c: structs.CarControl, now_nanos: int) -> tuple[structs.CarControl.Actuators, list[CanData]]:
|
||||
return self.CC.update(c, self.CS, now_nanos)
|
||||
|
||||
@staticmethod
|
||||
|
@ -109,14 +109,15 @@ class CarInterfaceBase(ABC):
|
|||
return ACCEL_MIN, ACCEL_MAX
|
||||
|
||||
@classmethod
|
||||
def get_non_essential_params(cls, candidate: str) -> car.CarParams:
|
||||
def get_non_essential_params(cls, candidate: str) -> structs.CarParams:
|
||||
"""
|
||||
Parameters essential to controlling the car may be incomplete or wrong without FW versions or fingerprints.
|
||||
"""
|
||||
return cls.get_params(candidate, gen_empty_fingerprint(), list(), False, False)
|
||||
|
||||
@classmethod
|
||||
def get_params(cls, candidate: str, fingerprint: dict[int, dict[int, int]], car_fw: list[car.CarParams.CarFw], experimental_long: bool, docs: bool):
|
||||
def get_params(cls, candidate: str, fingerprint: dict[int, dict[int, int]], car_fw: list[structs.CarParams.CarFw],
|
||||
experimental_long: bool, docs: bool) -> structs.CarParams:
|
||||
ret = CarInterfaceBase.get_std_params(candidate)
|
||||
|
||||
platform = PLATFORMS[candidate]
|
||||
|
@ -143,12 +144,12 @@ class CarInterfaceBase(ABC):
|
|||
|
||||
@staticmethod
|
||||
@abstractmethod
|
||||
def _get_params(ret: car.CarParams, candidate, fingerprint: dict[int, dict[int, int]],
|
||||
car_fw: list[car.CarParams.CarFw], experimental_long: bool, docs: bool) -> car.CarParams:
|
||||
def _get_params(ret: structs.CarParams, candidate, fingerprint: dict[int, dict[int, int]],
|
||||
car_fw: list[structs.CarParams.CarFw], experimental_long: bool, docs: bool) -> structs.CarParams:
|
||||
raise NotImplementedError
|
||||
|
||||
@staticmethod
|
||||
def init(CP: car.CarParams, can_recv: CanRecvCallable, can_send: CanSendCallable):
|
||||
def init(CP: structs.CarParams, can_recv: CanRecvCallable, can_send: CanSendCallable):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
|
@ -159,7 +160,7 @@ class CarInterfaceBase(ABC):
|
|||
def get_steer_feedforward_function(self):
|
||||
return self.get_steer_feedforward_default
|
||||
|
||||
def torque_from_lateral_accel_linear(self, latcontrol_inputs: LatControlInputs, torque_params: car.CarParams.LateralTorqueTuning,
|
||||
def torque_from_lateral_accel_linear(self, latcontrol_inputs: LatControlInputs, torque_params: structs.CarParams.LateralTorqueTuning,
|
||||
lateral_accel_error: float, lateral_accel_deadzone: float, friction_compensation: bool, gravity_adjusted: bool) -> float:
|
||||
# The default is a linear relationship between torque and lateral acceleration (accounting for road roll and steering friction)
|
||||
friction = get_friction(lateral_accel_error, lateral_accel_deadzone, FRICTION_THRESHOLD, torque_params, friction_compensation)
|
||||
|
@ -170,8 +171,8 @@ class CarInterfaceBase(ABC):
|
|||
|
||||
# returns a set of default params to avoid repetition in car specific params
|
||||
@staticmethod
|
||||
def get_std_params(candidate):
|
||||
ret = car.CarParams.new_message()
|
||||
def get_std_params(candidate: str) -> structs.CarParams:
|
||||
ret = structs.CarParams()
|
||||
ret.carFingerprint = candidate
|
||||
|
||||
# Car docs fields
|
||||
|
@ -180,7 +181,7 @@ class CarInterfaceBase(ABC):
|
|||
|
||||
# standard ALC params
|
||||
ret.tireStiffnessFactor = 1.0
|
||||
ret.steerControlType = car.CarParams.SteerControlType.torque
|
||||
ret.steerControlType = structs.CarParams.SteerControlType.torque
|
||||
ret.minSteerSpeed = 0.
|
||||
ret.wheelSpeedFactor = 1.0
|
||||
|
||||
|
@ -204,7 +205,7 @@ class CarInterfaceBase(ABC):
|
|||
return ret
|
||||
|
||||
@staticmethod
|
||||
def configure_torque_tune(candidate: str, tune: car.CarParams.LateralTuning, steering_angle_deadzone_deg: float = 0.0, use_steering_angle: bool = True):
|
||||
def configure_torque_tune(candidate: str, tune: structs.CarParams.LateralTuning, steering_angle_deadzone_deg: float = 0.0, use_steering_angle: bool = True):
|
||||
params = get_torque_params()[candidate]
|
||||
|
||||
tune.init('torque')
|
||||
|
@ -217,10 +218,10 @@ class CarInterfaceBase(ABC):
|
|||
tune.torque.latAccelOffset = 0.0
|
||||
tune.torque.steeringAngleDeadzoneDeg = steering_angle_deadzone_deg
|
||||
|
||||
def _update(self) -> car.CarState:
|
||||
def _update(self) -> structs.CarState:
|
||||
return self.CS.update(*self.can_parsers)
|
||||
|
||||
def update(self, can_packets: list[tuple[int, list[CanData]]]) -> car.CarState:
|
||||
def update(self, can_packets: list[tuple[int, list[CanData]]]) -> structs.CarState:
|
||||
# parse can
|
||||
for cp in self.can_parsers:
|
||||
if cp is not None:
|
||||
|
@ -245,33 +246,33 @@ class CarInterfaceBase(ABC):
|
|||
if ret.cruiseState.speedCluster == 0:
|
||||
ret.cruiseState.speedCluster = ret.cruiseState.speed
|
||||
|
||||
# copy back for next iteration
|
||||
self.CS.out = ret.as_reader()
|
||||
# save for next iteration
|
||||
self.CS.out = ret
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
class RadarInterfaceBase(ABC):
|
||||
def __init__(self, CP: car.CarParams):
|
||||
def __init__(self, CP: structs.CarParams):
|
||||
self.CP = CP
|
||||
self.rcp = None
|
||||
self.pts: dict[int, car.RadarData.RadarPoint] = {}
|
||||
self.pts: dict[int, structs.RadarData.RadarPoint] = {}
|
||||
self.delay = 0
|
||||
self.radar_ts = CP.radarTimeStep
|
||||
self.frame = 0
|
||||
|
||||
def update(self, can_strings):
|
||||
def update(self, can_strings) -> structs.RadarData | None:
|
||||
self.frame += 1
|
||||
if (self.frame % int(100 * self.radar_ts)) == 0:
|
||||
return car.RadarData.new_message()
|
||||
return structs.RadarData()
|
||||
return None
|
||||
|
||||
|
||||
class CarStateBase(ABC):
|
||||
def __init__(self, CP: car.CarParams):
|
||||
def __init__(self, CP: structs.CarParams):
|
||||
self.CP = CP
|
||||
self.car_fingerprint = CP.carFingerprint
|
||||
self.out = car.CarState.new_message()
|
||||
self.out = structs.CarState()
|
||||
|
||||
self.cruise_buttons = 0
|
||||
self.left_blinker_cnt = 0
|
||||
|
@ -291,7 +292,7 @@ class CarStateBase(ABC):
|
|||
self.v_ego_kf = KF1D(x0=x0, A=A, C=C[0], K=K)
|
||||
|
||||
@abstractmethod
|
||||
def update(self, cp, cp_cam, cp_adas, cp_body, cp_loopback) -> car.CarState:
|
||||
def update(self, cp, cp_cam, cp_adas, cp_body, cp_loopback) -> structs.CarState:
|
||||
pass
|
||||
|
||||
def update_speed_kf(self, v_ego_raw):
|
||||
|
@ -304,7 +305,7 @@ class CarStateBase(ABC):
|
|||
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 = structs.CarState.WheelSpeeds()
|
||||
wheelSpeeds.fl = fl * factor
|
||||
wheelSpeeds.fr = fr * factor
|
||||
wheelSpeeds.rl = rl * factor
|
||||
|
@ -349,7 +350,7 @@ class CarStateBase(ABC):
|
|||
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 | None) -> car.CarState.GearShifter:
|
||||
def parse_gear_shifter(gear: str | None) -> GearShifter:
|
||||
if gear is None:
|
||||
return GearShifter.unknown
|
||||
return GEAR_SHIFTER_MAP.get(gear.upper(), GearShifter.unknown)
|
||||
|
@ -376,12 +377,12 @@ class CarStateBase(ABC):
|
|||
|
||||
|
||||
class CarControllerBase(ABC):
|
||||
def __init__(self, dbc_name: str, CP: car.CarParams):
|
||||
def __init__(self, dbc_name: str, CP: structs.CarParams):
|
||||
self.CP = CP
|
||||
self.frame = 0
|
||||
|
||||
@abstractmethod
|
||||
def update(self, CC: car.CarControl, CS: CarStateBase, now_nanos: int) -> tuple[car.CarControl.Actuators, list[CanData]]:
|
||||
def update(self, CC: structs.CarControl, CS: CarStateBase, now_nanos: int) -> tuple[structs.CarControl.Actuators, list[CanData]]:
|
||||
pass
|
||||
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
from cereal import car
|
||||
import copy
|
||||
from opendbc.can.packer import CANPacker
|
||||
from openpilot.selfdrive.car import apply_driver_steer_torque_limits
|
||||
from openpilot.selfdrive.car import apply_driver_steer_torque_limits, structs
|
||||
from openpilot.selfdrive.car.interfaces import CarControllerBase
|
||||
from openpilot.selfdrive.car.mazda import mazdacan
|
||||
from openpilot.selfdrive.car.mazda.values import CarControllerParams, Buttons
|
||||
|
||||
VisualAlert = car.CarControl.HUDControl.VisualAlert
|
||||
VisualAlert = structs.CarControl.HUDControl.VisualAlert
|
||||
|
||||
|
||||
class CarController(CarControllerBase):
|
||||
|
@ -57,7 +57,7 @@ class CarController(CarControllerBase):
|
|||
can_sends.append(mazdacan.create_steering_control(self.packer, self.CP,
|
||||
self.frame, apply_steer, CS.cam_lkas))
|
||||
|
||||
new_actuators = CC.actuators.as_builder()
|
||||
new_actuators = copy.copy(CC.actuators)
|
||||
new_actuators.steer = apply_steer / CarControllerParams.STEER_MAX
|
||||
new_actuators.steerOutputCan = apply_steer
|
||||
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
from cereal import car
|
||||
from opendbc.can.can_define import CANDefine
|
||||
from opendbc.can.parser import CANParser
|
||||
from openpilot.selfdrive.car import create_button_events
|
||||
from openpilot.selfdrive.car import create_button_events, structs
|
||||
from openpilot.selfdrive.car.conversions import Conversions as CV
|
||||
from openpilot.selfdrive.car.interfaces import CarStateBase
|
||||
from openpilot.selfdrive.car.mazda.values import DBC, LKAS_LIMITS, MazdaFlags
|
||||
|
||||
ButtonType = car.CarState.ButtonEvent.Type
|
||||
ButtonType = structs.CarState.ButtonEvent.Type
|
||||
|
||||
|
||||
class CarState(CarStateBase):
|
||||
|
@ -24,9 +23,9 @@ class CarState(CarStateBase):
|
|||
|
||||
self.distance_button = 0
|
||||
|
||||
def update(self, cp, cp_cam, *_):
|
||||
def update(self, cp, cp_cam, *_) -> structs.CarState:
|
||||
|
||||
ret = car.CarState.new_message()
|
||||
ret = structs.CarState()
|
||||
|
||||
prev_distance_button = self.distance_button
|
||||
self.distance_button = cp.vl["CRZ_BTNS"]["DISTANCE_LESS"]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from cereal import car
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.mazda.values import CAR
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
Ecu = CarParams.Ecu
|
||||
|
||||
FW_VERSIONS = {
|
||||
CAR.MAZDA_CX5_2022: {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#!/usr/bin/env python3
|
||||
from cereal import car
|
||||
from openpilot.selfdrive.car import get_safety_config
|
||||
from openpilot.selfdrive.car import get_safety_config, structs
|
||||
from openpilot.selfdrive.car.conversions import Conversions as CV
|
||||
from openpilot.selfdrive.car.mazda.values import CAR, LKAS_LIMITS
|
||||
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
|
||||
|
@ -10,9 +9,9 @@ from openpilot.selfdrive.car.interfaces import CarInterfaceBase
|
|||
class CarInterface(CarInterfaceBase):
|
||||
|
||||
@staticmethod
|
||||
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
|
||||
def _get_params(ret: structs.CarParams, candidate, fingerprint, car_fw, experimental_long, docs) -> structs.CarParams:
|
||||
ret.carName = "mazda"
|
||||
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.mazda)]
|
||||
ret.safetyConfigs = [get_safety_config(structs.CarParams.SafetyModel.mazda)]
|
||||
ret.radarUnavailable = True
|
||||
|
||||
ret.dashcamOnly = candidate not in (CAR.MAZDA_CX5_2022, CAR.MAZDA_CX9_2021)
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
from dataclasses import dataclass, field
|
||||
from enum import IntFlag
|
||||
|
||||
from cereal import car
|
||||
from openpilot.selfdrive.car import CarSpecs, DbcDict, PlatformConfig, Platforms, dbc_dict
|
||||
from openpilot.selfdrive.car.conversions import Conversions as CV
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.docs_definitions import CarHarness, CarDocs, CarParts
|
||||
from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
Ecu = CarParams.Ecu
|
||||
|
||||
|
||||
# Steer torque limits
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from openpilot.selfdrive.car.interfaces import CarControllerBase
|
||||
|
||||
|
||||
class CarController(CarControllerBase):
|
||||
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
|
||||
|
||||
|
||||
class CarState(CarStateBase):
|
||||
def update(self, *_) -> car.CarState:
|
||||
return car.CarState.new_message()
|
||||
def update(self, *_) -> structs.CarState:
|
||||
return structs.CarState()
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#!/usr/bin/env python3
|
||||
from openpilot.selfdrive.car import structs
|
||||
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
|
||||
|
||||
|
||||
|
@ -6,7 +7,7 @@ from openpilot.selfdrive.car.interfaces import CarInterfaceBase
|
|||
class CarInterface(CarInterfaceBase):
|
||||
|
||||
@staticmethod
|
||||
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
|
||||
def _get_params(ret: structs.CarParams, candidate, fingerprint, car_fw, experimental_long, docs) -> structs.CarParams:
|
||||
ret.carName = "mock"
|
||||
ret.mass = 1700.
|
||||
ret.wheelbase = 2.70
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
from cereal import car
|
||||
import copy
|
||||
from opendbc.can.packer import CANPacker
|
||||
from openpilot.selfdrive.car import apply_std_steer_angle_limits
|
||||
from openpilot.selfdrive.car import apply_std_steer_angle_limits, structs
|
||||
from openpilot.selfdrive.car.interfaces import CarControllerBase
|
||||
from openpilot.selfdrive.car.nissan import nissancan
|
||||
from openpilot.selfdrive.car.nissan.values import CAR, CarControllerParams
|
||||
|
||||
VisualAlert = car.CarControl.HUDControl.VisualAlert
|
||||
VisualAlert = structs.CarControl.HUDControl.VisualAlert
|
||||
|
||||
|
||||
class CarController(CarControllerBase):
|
||||
|
@ -74,7 +74,7 @@ class CarController(CarControllerBase):
|
|||
self.packer, CS.lkas_hud_info_msg, steer_hud_alert
|
||||
))
|
||||
|
||||
new_actuators = actuators.as_builder()
|
||||
new_actuators = copy.copy(actuators)
|
||||
new_actuators.steeringAngleDeg = apply_angle
|
||||
|
||||
self.frame += 1
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
import copy
|
||||
from collections import deque
|
||||
from cereal import car
|
||||
from opendbc.can.can_define import CANDefine
|
||||
from opendbc.can.parser import CANParser
|
||||
from openpilot.selfdrive.car import create_button_events
|
||||
from openpilot.selfdrive.car import create_button_events, structs
|
||||
from openpilot.selfdrive.car.conversions import Conversions as CV
|
||||
from openpilot.selfdrive.car.interfaces import CarStateBase
|
||||
from openpilot.selfdrive.car.nissan.values import CAR, DBC, CarControllerParams
|
||||
|
||||
ButtonType = car.CarState.ButtonEvent.Type
|
||||
ButtonType = structs.CarState.ButtonEvent.Type
|
||||
|
||||
TORQUE_SAMPLES = 12
|
||||
|
||||
|
@ -26,8 +25,8 @@ class CarState(CarStateBase):
|
|||
|
||||
self.distance_button = 0
|
||||
|
||||
def update(self, cp, cp_cam, cp_adas, *_):
|
||||
ret = car.CarState.new_message()
|
||||
def update(self, cp, cp_cam, cp_adas, *_) -> structs.CarState:
|
||||
ret = structs.CarState()
|
||||
|
||||
prev_distance_button = self.distance_button
|
||||
self.distance_button = cp.vl["CRUISE_THROTTLE"]["FOLLOW_DISTANCE_BUTTON"]
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# ruff: noqa: E501
|
||||
from cereal import car
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.nissan.values import CAR
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
Ecu = CarParams.Ecu
|
||||
|
||||
FINGERPRINTS = {
|
||||
CAR.NISSAN_XTRAIL: [{
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
from cereal import car
|
||||
from panda import Panda
|
||||
from openpilot.selfdrive.car import get_safety_config
|
||||
from openpilot.selfdrive.car import get_safety_config, structs
|
||||
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
|
||||
from openpilot.selfdrive.car.nissan.values import CAR
|
||||
|
||||
|
@ -8,16 +7,16 @@ from openpilot.selfdrive.car.nissan.values import CAR
|
|||
class CarInterface(CarInterfaceBase):
|
||||
|
||||
@staticmethod
|
||||
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
|
||||
def _get_params(ret: structs.CarParams, candidate, fingerprint, car_fw, experimental_long, docs) -> structs.CarParams:
|
||||
ret.carName = "nissan"
|
||||
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.nissan)]
|
||||
ret.safetyConfigs = [get_safety_config(structs.CarParams.SafetyModel.nissan)]
|
||||
ret.autoResumeSng = False
|
||||
|
||||
ret.steerLimitTimer = 1.0
|
||||
|
||||
ret.steerActuatorDelay = 0.1
|
||||
|
||||
ret.steerControlType = car.CarParams.SteerControlType.angle
|
||||
ret.steerControlType = structs.CarParams.SteerControlType.angle
|
||||
ret.radarUnavailable = True
|
||||
|
||||
if candidate == CAR.NISSAN_ALTIMA:
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
from dataclasses import dataclass, field
|
||||
|
||||
from cereal import car
|
||||
from panda.python import uds
|
||||
from openpilot.selfdrive.car import AngleRateLimit, CarSpecs, DbcDict, PlatformConfig, Platforms, dbc_dict
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.docs_definitions import CarDocs, CarHarness, CarParts
|
||||
from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
Ecu = CarParams.Ecu
|
||||
|
||||
|
||||
class CarControllerParams:
|
||||
|
|
|
@ -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,3 +1,4 @@
|
|||
import copy
|
||||
from opendbc.can.packer import CANPacker
|
||||
from openpilot.selfdrive.car import apply_driver_steer_torque_limits, common_fault_avoidance, make_tester_present_msg
|
||||
from openpilot.selfdrive.car.common.numpy_fast import clip, interp
|
||||
|
@ -135,7 +136,7 @@ class CarController(CarControllerBase):
|
|||
if self.frame % 2 == 0:
|
||||
can_sends.append(subarucan.create_es_static_2(self.packer))
|
||||
|
||||
new_actuators = actuators.as_builder()
|
||||
new_actuators = copy.copy(actuators)
|
||||
new_actuators.steer = self.apply_steer_last / self.p.STEER_MAX
|
||||
new_actuators.steerOutputCan = self.apply_steer_last
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import copy
|
||||
from cereal import car
|
||||
from opendbc.can.can_define import CANDefine
|
||||
from opendbc.can.parser import CANParser
|
||||
from openpilot.selfdrive.car import structs
|
||||
from openpilot.selfdrive.car.conversions import Conversions as CV
|
||||
from openpilot.selfdrive.car.interfaces import CarStateBase
|
||||
from openpilot.selfdrive.car.subaru.values import DBC, CanBus, SubaruFlags
|
||||
|
@ -16,8 +16,8 @@ class CarState(CarStateBase):
|
|||
|
||||
self.angle_rate_calulator = CanSignalRateCalculator(50)
|
||||
|
||||
def update(self, cp, cp_cam, _, cp_body, __):
|
||||
ret = car.CarState.new_message()
|
||||
def update(self, cp, cp_cam, _, cp_body, __) -> structs.CarState:
|
||||
ret = structs.CarState()
|
||||
|
||||
throttle_msg = cp.vl["Throttle"] if not (self.CP.flags & SubaruFlags.HYBRID) else cp_body.vl["Throttle_Hybrid"]
|
||||
ret.gas = throttle_msg["Throttle_Pedal"] / 255.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from cereal import car
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.subaru.values import CAR
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
Ecu = CarParams.Ecu
|
||||
|
||||
FW_VERSIONS = {
|
||||
CAR.SUBARU_ASCENT: {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
from cereal import car
|
||||
from panda import Panda
|
||||
from openpilot.selfdrive.car import get_safety_config
|
||||
from openpilot.selfdrive.car import get_safety_config, structs
|
||||
from openpilot.selfdrive.car.disable_ecu import disable_ecu
|
||||
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
|
||||
from openpilot.selfdrive.car.subaru.values import CAR, GLOBAL_ES_ADDR, SubaruFlags
|
||||
|
@ -9,7 +8,7 @@ from openpilot.selfdrive.car.subaru.values import CAR, GLOBAL_ES_ADDR, SubaruFla
|
|||
class CarInterface(CarInterfaceBase):
|
||||
|
||||
@staticmethod
|
||||
def _get_params(ret, candidate: CAR, fingerprint, car_fw, experimental_long, docs):
|
||||
def _get_params(ret: structs.CarParams, candidate: CAR, fingerprint, car_fw, experimental_long, docs) -> structs.CarParams:
|
||||
ret.carName = "subaru"
|
||||
ret.radarUnavailable = True
|
||||
# for HYBRID CARS to be upstreamed, we need:
|
||||
|
@ -25,10 +24,10 @@ class CarInterface(CarInterfaceBase):
|
|||
|
||||
if ret.flags & SubaruFlags.PREGLOBAL:
|
||||
ret.enableBsm = 0x25c in fingerprint[0]
|
||||
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.subaruPreglobal)]
|
||||
ret.safetyConfigs = [get_safety_config(structs.CarParams.SafetyModel.subaruPreglobal)]
|
||||
else:
|
||||
ret.enableBsm = 0x228 in fingerprint[0]
|
||||
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.subaru)]
|
||||
ret.safetyConfigs = [get_safety_config(structs.CarParams.SafetyModel.subaru)]
|
||||
if ret.flags & SubaruFlags.GLOBAL_GEN2:
|
||||
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_SUBARU_GEN2
|
||||
|
||||
|
@ -36,7 +35,7 @@ class CarInterface(CarInterfaceBase):
|
|||
ret.steerActuatorDelay = 0.1
|
||||
|
||||
if ret.flags & SubaruFlags.LKAS_ANGLE:
|
||||
ret.steerControlType = car.CarParams.SteerControlType.angle
|
||||
ret.steerControlType = structs.CarParams.SteerControlType.angle
|
||||
else:
|
||||
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from cereal import car
|
||||
from openpilot.selfdrive.car import structs
|
||||
from openpilot.selfdrive.car.subaru.values import CanBus
|
||||
|
||||
VisualAlert = car.CarControl.HUDControl.VisualAlert
|
||||
VisualAlert = structs.CarControl.HUDControl.VisualAlert
|
||||
|
||||
|
||||
def create_steering_control(packer, apply_steer, steer_req):
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
from dataclasses import dataclass, field
|
||||
from enum import Enum, IntFlag
|
||||
|
||||
from cereal import car
|
||||
from panda.python import uds
|
||||
from openpilot.selfdrive.car import CarSpecs, DbcDict, PlatformConfig, Platforms, dbc_dict
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Tool, Column
|
||||
from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries, p16
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
Ecu = CarParams.Ecu
|
||||
|
||||
|
||||
class CarControllerParams:
|
||||
|
@ -93,7 +93,7 @@ class SubaruCarDocs(CarDocs):
|
|||
car_parts: CarParts = field(default_factory=CarParts.common([CarHarness.subaru_a]))
|
||||
footnotes: list[Enum] = field(default_factory=lambda: [Footnote.GLOBAL])
|
||||
|
||||
def init_make(self, CP: car.CarParams):
|
||||
def init_make(self, CP: CarParams):
|
||||
self.car_parts.parts.extend([Tool.socket_8mm_deep, Tool.pry_tool])
|
||||
|
||||
if CP.experimentalLongitudinalAvailable:
|
||||
|
|
|
@ -7,7 +7,9 @@ from parameterized import parameterized
|
|||
|
||||
from cereal import car, messaging
|
||||
from openpilot.selfdrive.car import DT_CTRL, gen_empty_fingerprint
|
||||
from openpilot.selfdrive.car.card import convert_carControl, convert_to_capnp
|
||||
from openpilot.selfdrive.car.car_helpers import interfaces
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.fingerprints import all_known_cars
|
||||
from openpilot.selfdrive.car.fw_versions import FW_VERSIONS, FW_QUERY_CONFIGS
|
||||
from openpilot.selfdrive.car.interfaces import get_interface_attr
|
||||
|
@ -43,8 +45,8 @@ def get_fuzzy_car_interface_args(draw: DrawType) -> dict:
|
|||
})
|
||||
|
||||
params: dict = draw(params_strategy)
|
||||
params['car_fw'] = [car.CarParams.CarFw(ecu=fw[0], address=fw[1], subAddress=fw[2] or 0,
|
||||
request=draw(st.sampled_from(sorted(ALL_REQUESTS))))
|
||||
params['car_fw'] = [CarParams.CarFw(ecu=fw[0], address=fw[1], subAddress=fw[2] or 0,
|
||||
request=draw(st.sampled_from(sorted(ALL_REQUESTS))))
|
||||
for fw in params['car_fw']]
|
||||
return params
|
||||
|
||||
|
@ -63,7 +65,6 @@ class TestCarInterfaces:
|
|||
|
||||
car_params = CarInterface.get_params(car_name, args['fingerprints'], args['car_fw'],
|
||||
experimental_long=args['experimental_long'], docs=False)
|
||||
car_params = car_params.as_reader()
|
||||
car_interface = CarInterface(car_params, CarController, CarState)
|
||||
assert car_params
|
||||
assert car_interface
|
||||
|
@ -79,7 +80,7 @@ class TestCarInterfaces:
|
|||
assert len(car_params.longitudinalTuning.kiV) == len(car_params.longitudinalTuning.kiBP)
|
||||
|
||||
# Lateral sanity checks
|
||||
if car_params.steerControlType != car.CarParams.SteerControlType.angle:
|
||||
if car_params.steerControlType != CarParams.SteerControlType.angle:
|
||||
tune = car_params.lateralTuning
|
||||
if tune.which() == 'pid':
|
||||
if car_name != MOCK.MOCK:
|
||||
|
@ -95,28 +96,31 @@ class TestCarInterfaces:
|
|||
# Run car interface
|
||||
now_nanos = 0
|
||||
CC = car.CarControl.new_message(**cc_msg)
|
||||
CC = convert_carControl(CC.as_reader())
|
||||
for _ in range(10):
|
||||
car_interface.update([])
|
||||
car_interface.apply(CC.as_reader(), now_nanos)
|
||||
car_interface.apply(CC, now_nanos)
|
||||
now_nanos += DT_CTRL * 1e9 # 10 ms
|
||||
|
||||
CC = car.CarControl.new_message(**cc_msg)
|
||||
CC.enabled = True
|
||||
CC = convert_carControl(CC.as_reader())
|
||||
for _ in range(10):
|
||||
car_interface.update([])
|
||||
car_interface.apply(CC.as_reader(), now_nanos)
|
||||
car_interface.apply(CC, now_nanos)
|
||||
now_nanos += DT_CTRL * 1e9 # 10ms
|
||||
|
||||
# Test controller initialization
|
||||
# TODO: wait until card refactor is merged to run controller a few times,
|
||||
# hypothesis also slows down significantly with just one more message draw
|
||||
LongControl(car_params)
|
||||
if car_params.steerControlType == car.CarParams.SteerControlType.angle:
|
||||
LatControlAngle(car_params, car_interface)
|
||||
car_params_capnp = convert_to_capnp(car_params).as_reader()
|
||||
LongControl(car_params_capnp)
|
||||
if car_params.steerControlType == CarParams.SteerControlType.angle:
|
||||
LatControlAngle(car_params_capnp, car_interface)
|
||||
elif car_params.lateralTuning.which() == 'pid':
|
||||
LatControlPID(car_params, car_interface)
|
||||
LatControlPID(car_params_capnp, car_interface)
|
||||
elif car_params.lateralTuning.which() == 'torque':
|
||||
LatControlTorque(car_params, car_interface)
|
||||
LatControlTorque(car_params_capnp, car_interface)
|
||||
|
||||
# Test radar interface
|
||||
RadarInterface = importlib.import_module(f'selfdrive.car.{car_params.carName}.radar_interface').RadarInterface
|
||||
|
|
|
@ -4,18 +4,16 @@ import time
|
|||
from collections import defaultdict
|
||||
from parameterized import parameterized
|
||||
|
||||
from cereal import car
|
||||
from openpilot.selfdrive.car.can_definitions import CanData
|
||||
from openpilot.selfdrive.car.car_helpers import interfaces
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.fingerprints import FW_VERSIONS
|
||||
from openpilot.selfdrive.car.fw_versions import ESSENTIAL_ECUS, FW_QUERY_CONFIGS, FUZZY_EXCLUDE_ECUS, VERSIONS, build_fw_dict, \
|
||||
match_fw_to_car, get_brand_ecu_matches, get_fw_versions, get_fw_versions_ordered, get_present_ecus
|
||||
from openpilot.selfdrive.car.vin import get_vin
|
||||
|
||||
CarFw = car.CarParams.CarFw
|
||||
Ecu = car.CarParams.Ecu
|
||||
|
||||
ECU_NAME = {v: k for k, v in Ecu.schema.enumerants.items()}
|
||||
CarFw = CarParams.CarFw
|
||||
Ecu = CarParams.Ecu
|
||||
|
||||
|
||||
class TestFwFingerprint:
|
||||
|
@ -27,7 +25,7 @@ class TestFwFingerprint:
|
|||
@parameterized.expand([(b, c, e[c], n) for b, e in VERSIONS.items() for c in e for n in (True, False)])
|
||||
def test_exact_match(self, brand, car_model, ecus, test_non_essential):
|
||||
config = FW_QUERY_CONFIGS[brand]
|
||||
CP = car.CarParams.new_message()
|
||||
CP = CarParams()
|
||||
for _ in range(100):
|
||||
fw = []
|
||||
for ecu, fw_versions in ecus.items():
|
||||
|
@ -37,8 +35,8 @@ class TestFwFingerprint:
|
|||
continue
|
||||
|
||||
ecu_name, addr, sub_addr = ecu
|
||||
fw.append({"ecu": ecu_name, "fwVersion": random.choice(fw_versions), 'brand': brand,
|
||||
"address": addr, "subAddress": 0 if sub_addr is None else sub_addr})
|
||||
fw.append(CarFw(ecu=ecu_name, fwVersion=random.choice(fw_versions), brand=brand,
|
||||
address=addr, subAddress=0 if sub_addr is None else sub_addr))
|
||||
CP.carFw = fw
|
||||
_, matches = match_fw_to_car(CP.carFw, CP.carVin, allow_fuzzy=False)
|
||||
if not test_non_essential:
|
||||
|
@ -55,13 +53,13 @@ class TestFwFingerprint:
|
|||
if config.match_fw_to_car_fuzzy is None:
|
||||
pytest.skip("Brand does not implement custom fuzzy fingerprinting function")
|
||||
|
||||
CP = car.CarParams.new_message()
|
||||
CP = CarParams()
|
||||
for _ in range(5):
|
||||
fw = []
|
||||
for ecu, fw_versions in ecus.items():
|
||||
ecu_name, addr, sub_addr = ecu
|
||||
fw.append({"ecu": ecu_name, "fwVersion": random.choice(fw_versions), 'brand': brand,
|
||||
"address": addr, "subAddress": 0 if sub_addr is None else sub_addr})
|
||||
fw.append(CarFw(ecu=ecu_name, fwVersion=random.choice(fw_versions), brand=brand,
|
||||
address=addr, subAddress=0 if sub_addr is None else sub_addr))
|
||||
CP.carFw = fw
|
||||
_, matches = match_fw_to_car(CP.carFw, CP.carVin, allow_exact=False, log=False)
|
||||
brand_matches = config.match_fw_to_car_fuzzy(build_fw_dict(CP.carFw), CP.carVin, VERSIONS[brand])
|
||||
|
@ -82,13 +80,13 @@ class TestFwFingerprint:
|
|||
ecu_name, addr, sub_addr = ecu
|
||||
for _ in range(5):
|
||||
# Add multiple FW versions to simulate ECU returning to multiple queries in a brand
|
||||
fw.append({"ecu": ecu_name, "fwVersion": random.choice(ecus[ecu]), 'brand': brand,
|
||||
"address": addr, "subAddress": 0 if sub_addr is None else sub_addr})
|
||||
CP = car.CarParams.new_message(carFw=fw)
|
||||
fw.append(CarFw(ecu=ecu_name, fwVersion=random.choice(ecus[ecu]), brand=brand,
|
||||
address=addr, subAddress=0 if sub_addr is None else sub_addr))
|
||||
CP = CarParams(carFw=fw)
|
||||
_, matches = match_fw_to_car(CP.carFw, CP.carVin, allow_exact=False, log=False)
|
||||
|
||||
# Assert no match if there are not enough unique ECUs
|
||||
unique_ecus = {(f['address'], f['subAddress']) for f in fw}
|
||||
unique_ecus = {(f.address, f.subAddress) for f in fw}
|
||||
if len(unique_ecus) < 2:
|
||||
assert len(matches) == 0, car_model
|
||||
# There won't always be a match due to shared FW, but if there is it should be correct
|
||||
|
@ -99,10 +97,10 @@ class TestFwFingerprint:
|
|||
for car_model, ecus in FW_VERSIONS.items():
|
||||
with subtests.test(car_model=car_model.value):
|
||||
for ecu, ecu_fw in ecus.items():
|
||||
with subtests.test(ecu):
|
||||
with subtests.test((ecu[0].value, ecu[1], ecu[2])):
|
||||
duplicates = {fw for fw in ecu_fw if ecu_fw.count(fw) > 1}
|
||||
assert not len(duplicates), f'{car_model}: Duplicate FW versions: Ecu.{ECU_NAME[ecu[0]]}, {duplicates}'
|
||||
assert len(ecu_fw) > 0, f'{car_model}: No FW versions: Ecu.{ECU_NAME[ecu[0]]}'
|
||||
assert not len(duplicates), f'{car_model}: Duplicate FW versions: Ecu.{ecu[0]}, {duplicates}'
|
||||
assert len(ecu_fw) > 0, f'{car_model}: No FW versions: Ecu.{ecu[0]}'
|
||||
|
||||
def test_all_addrs_map_to_one_ecu(self):
|
||||
for brand, cars in VERSIONS.items():
|
||||
|
@ -111,7 +109,7 @@ class TestFwFingerprint:
|
|||
for ecu_type, addr, sub_addr in ecus.keys():
|
||||
addr_to_ecu[(addr, sub_addr)].add(ecu_type)
|
||||
ecus_for_addr = addr_to_ecu[(addr, sub_addr)]
|
||||
ecu_strings = ", ".join([f'Ecu.{ECU_NAME[ecu]}' for ecu in ecus_for_addr])
|
||||
ecu_strings = ", ".join([f'Ecu.{ecu}' for ecu in ecus_for_addr])
|
||||
assert len(ecus_for_addr) <= 1, f"{brand} has multiple ECUs that map to one address: {ecu_strings} -> ({hex(addr)}, {sub_addr})"
|
||||
|
||||
def test_data_collection_ecus(self, subtests):
|
||||
|
@ -129,13 +127,13 @@ class TestFwFingerprint:
|
|||
CP = interfaces[car_model][0].get_non_essential_params(car_model)
|
||||
if CP.carName == 'subaru':
|
||||
for ecu in ecus.keys():
|
||||
assert ecu[1] not in blacklisted_addrs, f'{car_model}: Blacklisted ecu: (Ecu.{ECU_NAME[ecu[0]]}, {hex(ecu[1])})'
|
||||
assert ecu[1] not in blacklisted_addrs, f'{car_model}: Blacklisted ecu: (Ecu.{ecu[0]}, {hex(ecu[1])})'
|
||||
|
||||
elif CP.carName == "chrysler":
|
||||
# Some HD trucks have a combined TCM and ECM
|
||||
if CP.carFingerprint.startswith("RAM_HD"):
|
||||
for ecu in ecus.keys():
|
||||
assert ecu[0] != Ecu.transmission, f"{car_model}: Blacklisted ecu: (Ecu.{ECU_NAME[ecu[0]]}, {hex(ecu[1])})"
|
||||
assert ecu[0] != Ecu.transmission, f"{car_model}: Blacklisted ecu: (Ecu.{ecu[0]}, {hex(ecu[1])})"
|
||||
|
||||
def test_non_essential_ecus(self, subtests):
|
||||
for brand, config in FW_QUERY_CONFIGS.items():
|
||||
|
@ -143,7 +141,7 @@ class TestFwFingerprint:
|
|||
# These ECUs are already not in ESSENTIAL_ECUS which the fingerprint functions give a pass if missing
|
||||
unnecessary_non_essential_ecus = set(config.non_essential_ecus) - set(ESSENTIAL_ECUS)
|
||||
assert unnecessary_non_essential_ecus == set(), "Declaring non-essential ECUs non-essential is not required: " + \
|
||||
f"{', '.join([f'Ecu.{ECU_NAME[ecu]}' for ecu in unnecessary_non_essential_ecus])}"
|
||||
f"{', '.join([f'Ecu.{ecu}' for ecu in unnecessary_non_essential_ecus])}"
|
||||
|
||||
def test_missing_versions_and_configs(self, subtests):
|
||||
brand_versions = set(VERSIONS.keys())
|
||||
|
@ -172,7 +170,7 @@ class TestFwFingerprint:
|
|||
# each ecu in brand's fw versions + extra ecus needs to be whitelisted at least once
|
||||
ecus_not_whitelisted = brand_ecus - whitelisted_ecus
|
||||
|
||||
ecu_strings = ", ".join([f'Ecu.{ECU_NAME[ecu]}' for ecu in ecus_not_whitelisted])
|
||||
ecu_strings = ", ".join([f'Ecu.{ecu}' for ecu in ecus_not_whitelisted])
|
||||
assert not (len(whitelisted_ecus) and len(ecus_not_whitelisted)), \
|
||||
f'{brand.title()}: ECUs not in any FW query whitelists: {ecu_strings}'
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import capnp
|
||||
import copy
|
||||
import dataclasses
|
||||
import os
|
||||
import importlib
|
||||
import pytest
|
||||
|
@ -13,12 +15,13 @@ from cereal import messaging, log, car
|
|||
from openpilot.common.basedir import BASEDIR
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.selfdrive.car import DT_CTRL, gen_empty_fingerprint
|
||||
from openpilot.selfdrive.car import structs
|
||||
from openpilot.selfdrive.car.fingerprints import all_known_cars, MIGRATION
|
||||
from openpilot.selfdrive.car.car_helpers import FRAME_FINGERPRINT, interfaces
|
||||
from openpilot.selfdrive.car.honda.values import CAR as HONDA, HondaFlags
|
||||
from openpilot.selfdrive.car.tests.routes import non_tested_cars, routes, CarTestRoute
|
||||
from openpilot.selfdrive.car.values import Platform
|
||||
from openpilot.selfdrive.car.card import Car
|
||||
from openpilot.selfdrive.car.card import Car, convert_to_capnp
|
||||
from openpilot.selfdrive.pandad import can_capnp_to_list
|
||||
from openpilot.selfdrive.test.helpers import read_segment_list
|
||||
from openpilot.system.hardware.hw import DEFAULT_DOWNLOAD_CACHE_ROOT
|
||||
|
@ -181,7 +184,7 @@ class TestCarModelBase(unittest.TestCase):
|
|||
del cls.can_msgs
|
||||
|
||||
def setUp(self):
|
||||
self.CI = self.CarInterface(self.CP.copy(), self.CarController, self.CarState)
|
||||
self.CI = self.CarInterface(copy.deepcopy(self.CP), self.CarController, self.CarState)
|
||||
assert self.CI
|
||||
|
||||
Params().put_bool("OpenpilotEnabledToggle", self.openpilot_enabled)
|
||||
|
@ -189,7 +192,7 @@ class TestCarModelBase(unittest.TestCase):
|
|||
# TODO: check safetyModel is in release panda build
|
||||
self.safety = libpanda_py.libpanda
|
||||
|
||||
cfg = self.CP.safetyConfigs[-1]
|
||||
cfg = car.CarParams.SafetyConfig(**dataclasses.asdict(self.CP.safetyConfigs[-1]))
|
||||
set_status = self.safety.set_safety_hooks(cfg.safetyModel.raw, cfg.safetyParam)
|
||||
self.assertEqual(0, set_status, f"failed to set safetyModel {cfg}")
|
||||
self.safety.init_tests()
|
||||
|
@ -201,7 +204,7 @@ class TestCarModelBase(unittest.TestCase):
|
|||
# make sure car params are within a valid range
|
||||
self.assertGreater(self.CP.mass, 1)
|
||||
|
||||
if self.CP.steerControlType != car.CarParams.SteerControlType.angle:
|
||||
if self.CP.steerControlType != structs.CarParams.SteerControlType.angle:
|
||||
tuning = self.CP.lateralTuning.which()
|
||||
if tuning == 'pid':
|
||||
self.assertTrue(len(self.CP.lateralTuning.pid.kpV))
|
||||
|
@ -214,7 +217,7 @@ class TestCarModelBase(unittest.TestCase):
|
|||
# TODO: also check for checksum violations from can parser
|
||||
can_invalid_cnt = 0
|
||||
can_valid = False
|
||||
CC = car.CarControl.new_message().as_reader()
|
||||
CC = structs.CarControl()
|
||||
|
||||
for i, msg in enumerate(self.can_msgs):
|
||||
CS = self.CI.update(can_capnp_to_list((msg.as_builder().to_bytes(),)))
|
||||
|
@ -238,9 +241,9 @@ class TestCarModelBase(unittest.TestCase):
|
|||
# start parsing CAN messages after we've left ELM mode and can expect CAN traffic
|
||||
error_cnt = 0
|
||||
for i, msg in enumerate(self.can_msgs[self.elm_frame:]):
|
||||
rr = RI.update(can_capnp_to_list((msg.as_builder().to_bytes(),)))
|
||||
rr: structs.RadarData | None = RI.update(can_capnp_to_list((msg.as_builder().to_bytes(),)))
|
||||
if rr is not None and i > 50:
|
||||
error_cnt += car.RadarData.Error.canError in rr.errors
|
||||
error_cnt += structs.RadarData.Error.canError in rr.errors
|
||||
self.assertEqual(error_cnt, 0)
|
||||
|
||||
def test_panda_safety_rx_checks(self):
|
||||
|
@ -306,18 +309,18 @@ class TestCarModelBase(unittest.TestCase):
|
|||
self.assertGreater(msgs_sent, 50)
|
||||
|
||||
# Make sure we can send all messages while inactive
|
||||
CC = car.CarControl.new_message()
|
||||
test_car_controller(CC.as_reader())
|
||||
CC = structs.CarControl()
|
||||
test_car_controller(CC)
|
||||
|
||||
# Test cancel + general messages (controls_allowed=False & cruise_engaged=True)
|
||||
self.safety.set_cruise_engaged_prev(True)
|
||||
CC = car.CarControl.new_message(cruiseControl={'cancel': True})
|
||||
test_car_controller(CC.as_reader())
|
||||
CC = structs.CarControl(cruiseControl=structs.CarControl.CruiseControl(cancel=True))
|
||||
test_car_controller(CC)
|
||||
|
||||
# Test resume + general messages (controls_allowed=True & cruise_engaged=True)
|
||||
self.safety.set_controls_allowed(True)
|
||||
CC = car.CarControl.new_message(cruiseControl={'resume': True})
|
||||
test_car_controller(CC.as_reader())
|
||||
CC = structs.CarControl(cruiseControl=structs.CarControl.CruiseControl(resume=True))
|
||||
test_car_controller(CC)
|
||||
|
||||
# Skip stdout/stderr capture with pytest, causes elevated memory usage
|
||||
@pytest.mark.nocapture
|
||||
|
@ -403,7 +406,7 @@ class TestCarModelBase(unittest.TestCase):
|
|||
checks = defaultdict(int)
|
||||
card = Car(CI=self.CI)
|
||||
for idx, can in enumerate(self.can_msgs):
|
||||
CS = self.CI.update(can_capnp_to_list((can.as_builder().to_bytes(), )))
|
||||
CS = convert_to_capnp(self.CI.update(can_capnp_to_list((can.as_builder().to_bytes(), ))))
|
||||
for msg in filter(lambda m: m.src in range(64), can.can):
|
||||
to_send = libpanda_py.make_CANPacket(msg.address, msg.src % 4, msg.dat)
|
||||
ret = self.safety.safety_rx_hook(to_send)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from cereal import car
|
||||
from openpilot.selfdrive.car import apply_meas_steer_torque_limits, apply_std_steer_angle_limits, common_fault_avoidance, make_tester_present_msg
|
||||
import copy
|
||||
from openpilot.selfdrive.car import apply_meas_steer_torque_limits, apply_std_steer_angle_limits, common_fault_avoidance, make_tester_present_msg, structs
|
||||
from openpilot.selfdrive.car.can_definitions import CanData
|
||||
from openpilot.selfdrive.car.common.numpy_fast import clip
|
||||
from openpilot.selfdrive.car.interfaces import CarControllerBase
|
||||
|
@ -9,8 +9,8 @@ from openpilot.selfdrive.car.toyota.values import CAR, STATIC_DSU_MSGS, NO_STOP_
|
|||
UNSUPPORTED_DSU_CAR
|
||||
from opendbc.can.packer import CANPacker
|
||||
|
||||
SteerControlType = car.CarParams.SteerControlType
|
||||
VisualAlert = car.CarControl.HUDControl.VisualAlert
|
||||
SteerControlType = structs.CarParams.SteerControlType
|
||||
VisualAlert = structs.CarControl.HUDControl.VisualAlert
|
||||
|
||||
# LKA limits
|
||||
# EPS faults if you apply torque while the steering rate is above 100 deg/s for too long
|
||||
|
@ -168,7 +168,7 @@ class CarController(CarControllerBase):
|
|||
if self.frame % 20 == 0 and self.CP.flags & ToyotaFlags.DISABLE_RADAR.value:
|
||||
can_sends.append(make_tester_present_msg(0x750, 0, 0xF))
|
||||
|
||||
new_actuators = actuators.as_builder()
|
||||
new_actuators = copy.copy(actuators)
|
||||
new_actuators.steer = apply_steer / self.params.STEER_MAX
|
||||
new_actuators.steerOutputCan = apply_steer
|
||||
new_actuators.steeringAngleDeg = self.last_angle
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import copy
|
||||
|
||||
from cereal import car
|
||||
from opendbc.can.can_define import CANDefine
|
||||
from opendbc.can.parser import CANParser
|
||||
from openpilot.selfdrive.car import DT_CTRL, create_button_events
|
||||
from openpilot.selfdrive.car import DT_CTRL, create_button_events, structs
|
||||
from openpilot.selfdrive.car.conversions import Conversions as CV
|
||||
from openpilot.selfdrive.car.common.filter_simple import FirstOrderFilter
|
||||
from openpilot.selfdrive.car.common.numpy_fast import mean
|
||||
|
@ -11,8 +10,8 @@ from openpilot.selfdrive.car.interfaces import CarStateBase
|
|||
from openpilot.selfdrive.car.toyota.values import ToyotaFlags, CAR, DBC, STEER_THRESHOLD, NO_STOP_TIMER_CAR, \
|
||||
TSS2_CAR, RADAR_ACC_CAR, EPS_SCALE, UNSUPPORTED_DSU_CAR
|
||||
|
||||
ButtonType = car.CarState.ButtonEvent.Type
|
||||
SteerControlType = car.CarParams.SteerControlType
|
||||
ButtonType = structs.CarState.ButtonEvent.Type
|
||||
SteerControlType = structs.CarParams.SteerControlType
|
||||
|
||||
# These steering fault definitions seem to be common across LKA (torque) and LTA (angle):
|
||||
# - high steer rate fault: goes to 21 or 25 for 1 frame, then 9 for 2 seconds
|
||||
|
@ -49,8 +48,8 @@ class CarState(CarStateBase):
|
|||
self.acc_type = 1
|
||||
self.lkas_hud = {}
|
||||
|
||||
def update(self, cp, cp_cam, *_):
|
||||
ret = car.CarState.new_message()
|
||||
def update(self, cp, cp_cam, *_) -> structs.CarState:
|
||||
ret = structs.CarState()
|
||||
|
||||
ret.doorOpen = any([cp.vl["BODY_CONTROL_STATE"]["DOOR_OPEN_FL"], cp.vl["BODY_CONTROL_STATE"]["DOOR_OPEN_FR"],
|
||||
cp.vl["BODY_CONTROL_STATE"]["DOOR_OPEN_RL"], cp.vl["BODY_CONTROL_STATE"]["DOOR_OPEN_RR"]])
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from cereal import car
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.toyota.values import CAR
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
Ecu = CarParams.Ecu
|
||||
|
||||
FW_VERSIONS = {
|
||||
CAR.TOYOTA_AVALON: {
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
from cereal import car
|
||||
from panda import Panda
|
||||
from panda.python import uds
|
||||
from openpilot.selfdrive.car import structs, get_safety_config
|
||||
from openpilot.selfdrive.car.toyota.values import Ecu, CAR, DBC, ToyotaFlags, CarControllerParams, TSS2_CAR, RADAR_ACC_CAR, NO_DSU_CAR, \
|
||||
MIN_ACC_SPEED, EPS_SCALE, UNSUPPORTED_DSU_CAR, NO_STOP_TIMER_CAR, ANGLE_CONTROL_CAR
|
||||
from openpilot.selfdrive.car import get_safety_config
|
||||
from openpilot.selfdrive.car.disable_ecu import disable_ecu
|
||||
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
|
||||
|
||||
SteerControlType = car.CarParams.SteerControlType
|
||||
SteerControlType = structs.CarParams.SteerControlType
|
||||
|
||||
|
||||
class CarInterface(CarInterfaceBase):
|
||||
|
@ -16,9 +15,9 @@ class CarInterface(CarInterfaceBase):
|
|||
return CarControllerParams.ACCEL_MIN, CarControllerParams.ACCEL_MAX
|
||||
|
||||
@staticmethod
|
||||
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
|
||||
def _get_params(ret: structs.CarParams, candidate, fingerprint, car_fw, experimental_long, docs) -> structs.CarParams:
|
||||
ret.carName = "toyota"
|
||||
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.toyota)]
|
||||
ret.safetyConfigs = [get_safety_config(structs.CarParams.SafetyModel.toyota)]
|
||||
ret.safetyConfigs[0].safetyParam = EPS_SCALE[candidate]
|
||||
|
||||
# BRAKE_MODULE is on a different address for these cars
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
from opendbc.can.parser import CANParser
|
||||
from cereal import car
|
||||
from openpilot.selfdrive.car.structs import RadarData
|
||||
from openpilot.selfdrive.car.toyota.values import DBC, TSS2_CAR
|
||||
from openpilot.selfdrive.car.interfaces import RadarInterfaceBase
|
||||
|
||||
|
@ -54,7 +54,7 @@ class RadarInterface(RadarInterfaceBase):
|
|||
return rr
|
||||
|
||||
def _update(self, updated_messages):
|
||||
ret = car.RadarData.new_message()
|
||||
ret = RadarData()
|
||||
errors = []
|
||||
if not self.rcp.can_valid:
|
||||
errors.append("canError")
|
||||
|
@ -77,7 +77,7 @@ class RadarInterface(RadarInterfaceBase):
|
|||
# radar point only valid if it's a valid measurement and score is above 50
|
||||
if cpt['VALID'] or (score > 50 and cpt['LONG_DIST'] < 255 and self.valid_cnt[ii] > 0):
|
||||
if ii not in self.pts or cpt['NEW_TRACK']:
|
||||
self.pts[ii] = car.RadarData.RadarPoint.new_message()
|
||||
self.pts[ii] = RadarData.RadarPoint()
|
||||
self.pts[ii].trackId = self.track_id
|
||||
self.track_id += 1
|
||||
self.pts[ii].dRel = cpt['LONG_DIST'] # from front of car
|
||||
|
|
|
@ -1,19 +1,15 @@
|
|||
#!/usr/bin/env python3
|
||||
from collections import defaultdict
|
||||
from cereal import car
|
||||
from openpilot.selfdrive.car.toyota.values import PLATFORM_CODE_ECUS, get_platform_codes
|
||||
from openpilot.selfdrive.car.toyota.fingerprints import FW_VERSIONS
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
ECU_NAME = {v: k for k, v in Ecu.schema.enumerants.items()}
|
||||
|
||||
if __name__ == "__main__":
|
||||
parts_for_ecu: dict = defaultdict(set)
|
||||
cars_for_code: dict = defaultdict(lambda: defaultdict(set))
|
||||
for car_model, ecus in FW_VERSIONS.items():
|
||||
print()
|
||||
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:
|
||||
continue
|
||||
|
||||
|
@ -21,15 +17,15 @@ if __name__ == "__main__":
|
|||
parts_for_ecu[ecu] |= {code.split(b'-')[0] for code in platform_codes if code.count(b'-') > 1}
|
||||
for code in platform_codes:
|
||||
cars_for_code[ecu][b'-'.join(code.split(b'-')[:2])] |= {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: {platform_codes}')
|
||||
|
||||
print('\nECU parts:')
|
||||
for ecu, parts in parts_for_ecu.items():
|
||||
print(f' (Ecu.{ECU_NAME[ecu[0]]}, {hex(ecu[1])}, {ecu[2]}): {parts}')
|
||||
print(f' (Ecu.{ecu[0]}, {hex(ecu[1])}, {ecu[2]}): {parts}')
|
||||
|
||||
print('\nCar models vs. platform codes (no major versions):')
|
||||
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():
|
||||
print(f' {code!r}: {sorted(cars)}')
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
from hypothesis import given, settings, strategies as st
|
||||
|
||||
from cereal import car
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.fw_versions import build_fw_dict
|
||||
from openpilot.selfdrive.car.toyota.fingerprints import FW_VERSIONS
|
||||
from openpilot.selfdrive.car.toyota.values import CAR, DBC, TSS2_CAR, ANGLE_CONTROL_CAR, RADAR_ACC_CAR, \
|
||||
FW_QUERY_CONFIG, PLATFORM_CODE_ECUS, FUZZY_EXCLUDED_PLATFORMS, \
|
||||
get_platform_codes
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
ECU_NAME = {v: k for k, v in Ecu.schema.enumerants.items()}
|
||||
Ecu = CarParams.Ecu
|
||||
|
||||
|
||||
def check_fw_version(fw_version: bytes) -> bool:
|
||||
|
@ -153,10 +152,10 @@ class TestToyotaFingerprint:
|
|||
for ecu, fw_versions in fw_by_addr.items():
|
||||
ecu_name, addr, sub_addr = ecu
|
||||
for fw in fw_versions:
|
||||
car_fw.append({"ecu": ecu_name, "fwVersion": fw, "address": addr,
|
||||
"subAddress": 0 if sub_addr is None else sub_addr})
|
||||
car_fw.append(CarParams.CarFw(ecu=ecu_name, fwVersion=fw, address=addr,
|
||||
subAddress=0 if sub_addr is None else sub_addr))
|
||||
|
||||
CP = car.CarParams.new_message(carFw=car_fw)
|
||||
CP = CarParams(carFw=car_fw)
|
||||
matches = FW_QUERY_CONFIG.match_fw_to_car_fuzzy(build_fw_dict(CP.carFw), CP.carVin, FW_VERSIONS)
|
||||
if len(matches) == 1:
|
||||
assert list(matches)[0] == platform
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from cereal import car
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
|
||||
SteerControlType = car.CarParams.SteerControlType
|
||||
SteerControlType = CarParams.SteerControlType
|
||||
|
||||
|
||||
def create_steer_command(packer, steer, steer_req):
|
||||
|
|
|
@ -3,13 +3,13 @@ from collections import defaultdict
|
|||
from dataclasses import dataclass, field
|
||||
from enum import Enum, IntFlag
|
||||
|
||||
from cereal import car
|
||||
from openpilot.selfdrive.car import CarSpecs, PlatformConfig, Platforms, AngleRateLimit, dbc_dict
|
||||
from openpilot.selfdrive.car.conversions import Conversions as CV
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarDocs, Column, CarParts, CarHarness
|
||||
from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
Ecu = CarParams.Ecu
|
||||
MIN_ACC_SPEED = 19. * CV.MPH_TO_MS
|
||||
PEDAL_TRANSITION = 10. * CV.MPH_TO_MS
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
from cereal import car
|
||||
import copy
|
||||
from opendbc.can.packer import CANPacker
|
||||
from openpilot.selfdrive.car import DT_CTRL, apply_driver_steer_torque_limits
|
||||
from openpilot.selfdrive.car import DT_CTRL, apply_driver_steer_torque_limits, structs
|
||||
from openpilot.selfdrive.car.conversions import Conversions as CV
|
||||
from openpilot.selfdrive.car.common.numpy_fast import clip
|
||||
from openpilot.selfdrive.car.interfaces import CarControllerBase
|
||||
from openpilot.selfdrive.car.volkswagen import mqbcan, pqcan
|
||||
from openpilot.selfdrive.car.volkswagen.values import CANBUS, CarControllerParams, VolkswagenFlags
|
||||
|
||||
VisualAlert = car.CarControl.HUDControl.VisualAlert
|
||||
LongCtrlState = car.CarControl.Actuators.LongControlState
|
||||
VisualAlert = structs.CarControl.HUDControl.VisualAlert
|
||||
LongCtrlState = structs.CarControl.Actuators.LongControlState
|
||||
|
||||
|
||||
class CarController(CarControllerBase):
|
||||
|
@ -17,7 +17,7 @@ class CarController(CarControllerBase):
|
|||
self.CCP = CarControllerParams(CP)
|
||||
self.CCS = pqcan if CP.flags & VolkswagenFlags.PQ else mqbcan
|
||||
self.packer_pt = CANPacker(dbc_name)
|
||||
self.ext_bus = CANBUS.pt if CP.networkLocation == car.CarParams.NetworkLocation.fwdCamera else CANBUS.cam
|
||||
self.ext_bus = CANBUS.pt if CP.networkLocation == structs.CarParams.NetworkLocation.fwdCamera else CANBUS.cam
|
||||
|
||||
self.apply_steer_last = 0
|
||||
self.gra_acc_counter_last = None
|
||||
|
@ -110,7 +110,7 @@ class CarController(CarControllerBase):
|
|||
can_sends.append(self.CCS.create_acc_buttons_control(self.packer_pt, self.ext_bus, CS.gra_stock_values,
|
||||
cancel=CC.cruiseControl.cancel, resume=CC.cruiseControl.resume))
|
||||
|
||||
new_actuators = actuators.as_builder()
|
||||
new_actuators = copy.copy(actuators)
|
||||
new_actuators.steer = self.apply_steer_last / self.CCP.STEER_MAX
|
||||
new_actuators.steerOutputCan = self.apply_steer_last
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import numpy as np
|
||||
from cereal import car
|
||||
from opendbc.can.parser import CANParser
|
||||
from openpilot.selfdrive.car import structs
|
||||
from openpilot.selfdrive.car.interfaces import CarStateBase
|
||||
from openpilot.selfdrive.car.conversions import Conversions as CV
|
||||
from openpilot.selfdrive.car.volkswagen.values import DBC, CANBUS, NetworkLocation, TransmissionType, GearShifter, \
|
||||
|
@ -24,7 +24,7 @@ class CarState(CarStateBase):
|
|||
for button in buttons:
|
||||
state = pt_cp.vl[button.can_addr][button.can_msg] in button.values
|
||||
if self.button_states[button.event_type] != state:
|
||||
event = car.CarState.ButtonEvent.new_message()
|
||||
event = structs.CarState.ButtonEvent()
|
||||
event.type = button.event_type
|
||||
event.pressed = state
|
||||
button_events.append(event)
|
||||
|
@ -32,14 +32,14 @@ class CarState(CarStateBase):
|
|||
|
||||
return button_events
|
||||
|
||||
def update(self, pt_cp, cam_cp, *_):
|
||||
def update(self, pt_cp, cam_cp, *_) -> structs.CarState:
|
||||
|
||||
ext_cp = pt_cp if self.CP.networkLocation == NetworkLocation.fwdCamera else cam_cp
|
||||
|
||||
if self.CP.flags & VolkswagenFlags.PQ:
|
||||
return self.update_pq(pt_cp, cam_cp, ext_cp)
|
||||
|
||||
ret = car.CarState.new_message()
|
||||
ret = structs.CarState()
|
||||
# Update vehicle speed and acceleration from ABS wheel speeds.
|
||||
ret.wheelSpeeds = self.get_wheel_speeds(
|
||||
pt_cp.vl["ESP_19"]["ESP_VL_Radgeschw_02"],
|
||||
|
@ -158,8 +158,8 @@ class CarState(CarStateBase):
|
|||
self.frame += 1
|
||||
return ret
|
||||
|
||||
def update_pq(self, pt_cp, cam_cp, ext_cp):
|
||||
ret = car.CarState.new_message()
|
||||
def update_pq(self, pt_cp, cam_cp, ext_cp) -> structs.CarState:
|
||||
ret = structs.CarState()
|
||||
# Update vehicle speed and acceleration from ABS wheel speeds.
|
||||
ret.wheelSpeeds = self.get_wheel_speeds(
|
||||
pt_cp.vl["Bremse_3"]["Radgeschw__VL_4_1"],
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from cereal import car
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.volkswagen.values import CAR
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
Ecu = CarParams.Ecu
|
||||
|
||||
# TODO: Sharan Mk2 EPS and DQ250 auto trans both require KWP2000 support for fingerprinting
|
||||
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
from cereal import car
|
||||
from panda import Panda
|
||||
from openpilot.selfdrive.car import get_safety_config
|
||||
from openpilot.selfdrive.car import get_safety_config, structs
|
||||
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
|
||||
from openpilot.selfdrive.car.volkswagen.values import CAR, NetworkLocation, TransmissionType, VolkswagenFlags
|
||||
|
||||
|
||||
class CarInterface(CarInterfaceBase):
|
||||
@staticmethod
|
||||
def _get_params(ret, candidate: CAR, fingerprint, car_fw, experimental_long, docs):
|
||||
def _get_params(ret: structs.CarParams, candidate: CAR, fingerprint, car_fw, experimental_long, docs) -> structs.CarParams:
|
||||
ret.carName = "volkswagen"
|
||||
ret.radarUnavailable = True
|
||||
|
||||
if ret.flags & VolkswagenFlags.PQ:
|
||||
# Set global PQ35/PQ46/NMS parameters
|
||||
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.volkswagenPq)]
|
||||
ret.safetyConfigs = [get_safety_config(structs.CarParams.SafetyModel.volkswagenPq)]
|
||||
ret.enableBsm = 0x3BA in fingerprint[0] # SWA_1
|
||||
|
||||
if 0x440 in fingerprint[0] or docs: # Getriebe_1
|
||||
|
@ -36,7 +35,7 @@ class CarInterface(CarInterfaceBase):
|
|||
|
||||
else:
|
||||
# Set global MQB parameters
|
||||
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.volkswagen)]
|
||||
ret.safetyConfigs = [get_safety_config(structs.CarParams.SafetyModel.volkswagen)]
|
||||
ret.enableBsm = 0x30F in fingerprint[0] # SWA_01
|
||||
|
||||
if 0xAD in fingerprint[0] or docs: # Getriebe_11
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import random
|
||||
import re
|
||||
|
||||
from cereal import car
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
from openpilot.selfdrive.car.volkswagen.values import CAR, FW_QUERY_CONFIG, WMI
|
||||
from openpilot.selfdrive.car.volkswagen.fingerprints import FW_VERSIONS
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
Ecu = CarParams.Ecu
|
||||
|
||||
CHASSIS_CODE_PATTERN = re.compile('[A-Z0-9]{2}')
|
||||
# TODO: determine the unknown groups
|
||||
|
|
|
@ -2,19 +2,19 @@ from collections import defaultdict, namedtuple
|
|||
from dataclasses import dataclass, field
|
||||
from enum import Enum, IntFlag, StrEnum
|
||||
|
||||
from cereal import car
|
||||
from panda.python import uds
|
||||
from opendbc.can.can_define import CANDefine
|
||||
from openpilot.selfdrive.car import dbc_dict, CarSpecs, DbcDict, PlatformConfig, Platforms
|
||||
from openpilot.selfdrive.car.conversions import Conversions as CV
|
||||
from openpilot.selfdrive.car import structs
|
||||
from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column, \
|
||||
Device
|
||||
from openpilot.selfdrive.car.fw_query_definitions import EcuAddrSubAddr, FwQueryConfig, Request, p16
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
NetworkLocation = car.CarParams.NetworkLocation
|
||||
TransmissionType = car.CarParams.TransmissionType
|
||||
GearShifter = car.CarState.GearShifter
|
||||
Ecu = structs.CarParams.Ecu
|
||||
NetworkLocation = structs.CarParams.NetworkLocation
|
||||
TransmissionType = structs.CarParams.TransmissionType
|
||||
GearShifter = structs.CarState.GearShifter
|
||||
Button = namedtuple('Button', ['event_type', 'can_addr', 'can_msg', 'values'])
|
||||
|
||||
|
||||
|
@ -54,12 +54,12 @@ class CarControllerParams:
|
|||
self.hca_status_values = can_define.dv["Lenkhilfe_2"]["LH2_Sta_HCA"]
|
||||
|
||||
self.BUTTONS = [
|
||||
Button(car.CarState.ButtonEvent.Type.setCruise, "GRA_Neu", "GRA_Neu_Setzen", [1]),
|
||||
Button(car.CarState.ButtonEvent.Type.resumeCruise, "GRA_Neu", "GRA_Recall", [1]),
|
||||
Button(car.CarState.ButtonEvent.Type.accelCruise, "GRA_Neu", "GRA_Up_kurz", [1]),
|
||||
Button(car.CarState.ButtonEvent.Type.decelCruise, "GRA_Neu", "GRA_Down_kurz", [1]),
|
||||
Button(car.CarState.ButtonEvent.Type.cancel, "GRA_Neu", "GRA_Abbrechen", [1]),
|
||||
Button(car.CarState.ButtonEvent.Type.gapAdjustCruise, "GRA_Neu", "GRA_Zeitluecke", [1]),
|
||||
Button(structs.CarState.ButtonEvent.Type.setCruise, "GRA_Neu", "GRA_Neu_Setzen", [1]),
|
||||
Button(structs.CarState.ButtonEvent.Type.resumeCruise, "GRA_Neu", "GRA_Recall", [1]),
|
||||
Button(structs.CarState.ButtonEvent.Type.accelCruise, "GRA_Neu", "GRA_Up_kurz", [1]),
|
||||
Button(structs.CarState.ButtonEvent.Type.decelCruise, "GRA_Neu", "GRA_Down_kurz", [1]),
|
||||
Button(structs.CarState.ButtonEvent.Type.cancel, "GRA_Neu", "GRA_Abbrechen", [1]),
|
||||
Button(structs.CarState.ButtonEvent.Type.gapAdjustCruise, "GRA_Neu", "GRA_Zeitluecke", [1]),
|
||||
]
|
||||
|
||||
self.LDW_MESSAGES = {
|
||||
|
@ -85,12 +85,12 @@ class CarControllerParams:
|
|||
self.hca_status_values = can_define.dv["LH_EPS_03"]["EPS_HCA_Status"]
|
||||
|
||||
self.BUTTONS = [
|
||||
Button(car.CarState.ButtonEvent.Type.setCruise, "GRA_ACC_01", "GRA_Tip_Setzen", [1]),
|
||||
Button(car.CarState.ButtonEvent.Type.resumeCruise, "GRA_ACC_01", "GRA_Tip_Wiederaufnahme", [1]),
|
||||
Button(car.CarState.ButtonEvent.Type.accelCruise, "GRA_ACC_01", "GRA_Tip_Hoch", [1]),
|
||||
Button(car.CarState.ButtonEvent.Type.decelCruise, "GRA_ACC_01", "GRA_Tip_Runter", [1]),
|
||||
Button(car.CarState.ButtonEvent.Type.cancel, "GRA_ACC_01", "GRA_Abbrechen", [1]),
|
||||
Button(car.CarState.ButtonEvent.Type.gapAdjustCruise, "GRA_ACC_01", "GRA_Verstellung_Zeitluecke", [1]),
|
||||
Button(structs.CarState.ButtonEvent.Type.setCruise, "GRA_ACC_01", "GRA_Tip_Setzen", [1]),
|
||||
Button(structs.CarState.ButtonEvent.Type.resumeCruise, "GRA_ACC_01", "GRA_Tip_Wiederaufnahme", [1]),
|
||||
Button(structs.CarState.ButtonEvent.Type.accelCruise, "GRA_ACC_01", "GRA_Tip_Hoch", [1]),
|
||||
Button(structs.CarState.ButtonEvent.Type.decelCruise, "GRA_ACC_01", "GRA_Tip_Runter", [1]),
|
||||
Button(structs.CarState.ButtonEvent.Type.cancel, "GRA_ACC_01", "GRA_Abbrechen", [1]),
|
||||
Button(structs.CarState.ButtonEvent.Type.gapAdjustCruise, "GRA_ACC_01", "GRA_Verstellung_Zeitluecke", [1]),
|
||||
]
|
||||
|
||||
self.LDW_MESSAGES = {
|
||||
|
@ -190,7 +190,7 @@ class VWCarDocs(CarDocs):
|
|||
package: str = "Adaptive Cruise Control (ACC) & Lane Assist"
|
||||
car_parts: CarParts = field(default_factory=CarParts.common([CarHarness.vw_j533]))
|
||||
|
||||
def init_make(self, CP: car.CarParams):
|
||||
def init_make(self, CP: structs.CarParams):
|
||||
self.footnotes.append(Footnote.VW_EXP_LONG)
|
||||
if "SKODA" in CP.carFingerprint:
|
||||
self.footnotes.append(Footnote.SKODA_HEATED_WINDSHIELD)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from parameterized import parameterized
|
||||
|
||||
from cereal import car, log
|
||||
from openpilot.selfdrive.car.card import convert_to_capnp
|
||||
from openpilot.selfdrive.car.car_helpers import interfaces
|
||||
from openpilot.selfdrive.car.honda.values import CAR as HONDA
|
||||
from openpilot.selfdrive.car.toyota.values import CAR as TOYOTA
|
||||
|
@ -20,6 +21,7 @@ class TestLatControl:
|
|||
CarInterface, CarController, CarState = interfaces[car_name]
|
||||
CP = CarInterface.get_non_essential_params(car_name)
|
||||
CI = CarInterface(CP, CarController, CarState)
|
||||
CP = convert_to_capnp(CP)
|
||||
VM = VehicleModel(CP)
|
||||
|
||||
controller = controller(CP.as_reader(), CI)
|
||||
|
|
|
@ -3,6 +3,7 @@ import math
|
|||
|
||||
import numpy as np
|
||||
|
||||
from openpilot.selfdrive.car.card import convert_to_capnp
|
||||
from openpilot.selfdrive.car.honda.interface import CarInterface
|
||||
from openpilot.selfdrive.car.honda.values import CAR
|
||||
from openpilot.selfdrive.controls.lib.vehicle_model import VehicleModel, dyn_ss_sol, create_dyn_state_matrices
|
||||
|
@ -11,7 +12,7 @@ from openpilot.selfdrive.controls.lib.vehicle_model import VehicleModel, dyn_ss_
|
|||
class TestVehicleModel:
|
||||
def setup_method(self):
|
||||
CP = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC)
|
||||
self.VM = VehicleModel(CP)
|
||||
self.VM = VehicleModel(convert_to_capnp(CP))
|
||||
|
||||
def test_round_trip_yaw_rate(self):
|
||||
# TODO: fix VM to work at zero speed
|
||||
|
|
|
@ -11,6 +11,7 @@ from openpilot.common.params import Params
|
|||
from openpilot.common.realtime import DT_CTRL, Ratekeeper, Priority, config_realtime_process
|
||||
from openpilot.common.swaglog import cloudlog
|
||||
from openpilot.common.simple_kalman import KF1D
|
||||
from openpilot.selfdrive.car import structs
|
||||
from openpilot.selfdrive.pandad import can_capnp_to_list
|
||||
|
||||
|
||||
|
@ -208,7 +209,7 @@ class RadarD:
|
|||
|
||||
self.ready = False
|
||||
|
||||
def update(self, sm: messaging.SubMaster, rr: car.RadarData):
|
||||
def update(self, sm: messaging.SubMaster, rr: structs.RadarData):
|
||||
self.ready = sm.seen['modelV2']
|
||||
self.current_time = 1e-9*max(sm.logMonoTime.values())
|
||||
|
||||
|
@ -301,7 +302,7 @@ def main() -> None:
|
|||
|
||||
while 1:
|
||||
can_strings = messaging.drain_sock_raw(can_sock, wait_for_one=True)
|
||||
rr: car.RadarData | None = RI.update(can_capnp_to_list(can_strings))
|
||||
rr: structs.RadarData | None = RI.update(can_capnp_to_list(can_strings))
|
||||
sm.update(0)
|
||||
if rr is None:
|
||||
continue
|
||||
|
|
|
@ -2,28 +2,24 @@
|
|||
import jinja2
|
||||
import os
|
||||
|
||||
from cereal import car
|
||||
from openpilot.common.basedir import BASEDIR
|
||||
from openpilot.selfdrive.car.interfaces import get_interface_attr
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
|
||||
CARS = get_interface_attr('CAR')
|
||||
FW_VERSIONS = get_interface_attr('FW_VERSIONS')
|
||||
FINGERPRINTS = get_interface_attr('FINGERPRINTS')
|
||||
ECU_NAME = {v: k for k, v in Ecu.schema.enumerants.items()}
|
||||
|
||||
FINGERPRINTS_PY_TEMPLATE = jinja2.Template("""
|
||||
{%- if FINGERPRINTS[brand] %}
|
||||
# ruff: noqa: E501
|
||||
{% endif %}
|
||||
{% if FW_VERSIONS[brand] %}
|
||||
from cereal import car
|
||||
from openpilot.selfdrive.car.structs import CarParams
|
||||
{% endif %}
|
||||
from openpilot.selfdrive.car.{{brand}}.values import CAR
|
||||
{% if FW_VERSIONS[brand] %}
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
Ecu = CarParams.Ecu
|
||||
{% endif %}
|
||||
{% if comments +%}
|
||||
{{ comments | join() }}
|
||||
|
@ -49,7 +45,7 @@ FW_VERSIONS{% if not FW_VERSIONS[brand] %}: dict[str, dict[tuple, list[bytes]]]{
|
|||
{% for car, _ in FW_VERSIONS[brand].items() %}
|
||||
CAR.{{car.name}}: {
|
||||
{% for key, fw_versions in FW_VERSIONS[brand][car].items() %}
|
||||
(Ecu.{{ECU_NAME[key[0]]}}, 0x{{"%0x" | format(key[1] | int)}}, \
|
||||
(Ecu.{{key[0]}}, 0x{{"%0x" | format(key[1] | int)}}, \
|
||||
{% if key[2] %}0x{{"%0x" | format(key[2] | int)}}{% else %}{{key[2]}}{% endif %}): [
|
||||
{% for fw_version in (fw_versions + extra_fw_versions.get(car, {}).get(key, [])) | unique | sort %}
|
||||
{{fw_version}},
|
||||
|
@ -71,9 +67,8 @@ def format_brand_fw_versions(brand, extra_fw_versions: None | dict[str, dict[tup
|
|||
comments = [line for line in f.readlines() if line.startswith("#") and "noqa" not in line]
|
||||
|
||||
with open(fingerprints_file, "w") as f:
|
||||
f.write(FINGERPRINTS_PY_TEMPLATE.render(brand=brand, comments=comments, ECU_NAME=ECU_NAME,
|
||||
FINGERPRINTS=FINGERPRINTS, FW_VERSIONS=FW_VERSIONS,
|
||||
extra_fw_versions=extra_fw_versions))
|
||||
f.write(FINGERPRINTS_PY_TEMPLATE.render(brand=brand, comments=comments, FINGERPRINTS=FINGERPRINTS,
|
||||
FW_VERSIONS=FW_VERSIONS, extra_fw_versions=extra_fw_versions))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -16,6 +16,7 @@ from openpilot.common.realtime import config_realtime_process
|
|||
from openpilot.common.transformations.camera import DEVICE_CAMERAS
|
||||
from openpilot.common.transformations.model import get_warp_matrix
|
||||
from openpilot.system import sentry
|
||||
from openpilot.selfdrive.car.card import convert_to_capnp
|
||||
from openpilot.selfdrive.car.car_helpers import get_demo_car_params
|
||||
from openpilot.selfdrive.controls.lib.desire_helper import DesireHelper
|
||||
from openpilot.selfdrive.modeld.runners import ModelRunner, Runtime
|
||||
|
@ -170,7 +171,7 @@ def main(demo=False):
|
|||
|
||||
|
||||
if demo:
|
||||
CP = get_demo_car_params()
|
||||
CP = convert_to_capnp(get_demo_car_params())
|
||||
else:
|
||||
CP = messaging.log_from_bytes(params.get("CarParams", block=True), car.CarParams)
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ from msgq.visionipc import VisionIpcServer, VisionStreamType
|
|||
from openpilot.common.params import Params
|
||||
from openpilot.common.transformations.camera import DEVICE_CAMERAS
|
||||
from openpilot.common.realtime import DT_MDL
|
||||
from openpilot.selfdrive.car.card import convert_to_capnp
|
||||
from openpilot.selfdrive.car.car_helpers import get_demo_car_params
|
||||
from openpilot.system.manager.process_config import managed_processes
|
||||
from openpilot.selfdrive.test.process_replay.vision_meta import meta_from_camera_state
|
||||
|
@ -23,7 +24,7 @@ class TestModeld:
|
|||
self.vipc_server.create_buffers(VisionStreamType.VISION_STREAM_DRIVER, 40, False, CAM.width, CAM.height)
|
||||
self.vipc_server.create_buffers(VisionStreamType.VISION_STREAM_WIDE_ROAD, 40, False, CAM.width, CAM.height)
|
||||
self.vipc_server.start_listener()
|
||||
Params().put("CarParams", get_demo_car_params().to_bytes())
|
||||
Params().put("CarParams", convert_to_capnp(get_demo_car_params()).to_bytes())
|
||||
|
||||
self.sm = messaging.SubMaster(['modelV2', 'cameraOdometry'])
|
||||
self.pm = messaging.PubMaster(['roadCameraState', 'wideRoadCameraState', 'liveCalibration'])
|
||||
|
|
|
@ -22,8 +22,9 @@ from openpilot.common.prefix import OpenpilotPrefix
|
|||
from openpilot.common.timeout import Timeout
|
||||
from openpilot.common.realtime import DT_CTRL
|
||||
from panda.python import ALTERNATIVE_EXPERIENCE
|
||||
from openpilot.selfdrive.car.card import can_comm_callbacks
|
||||
from openpilot.selfdrive.car.card import can_comm_callbacks, convert_to_capnp
|
||||
from openpilot.selfdrive.car.car_helpers import get_car, interfaces
|
||||
from openpilot.selfdrive.car import structs
|
||||
from openpilot.system.manager.process_config import managed_processes
|
||||
from openpilot.selfdrive.test.process_replay.vision_meta import meta_from_camera_state, available_streams
|
||||
from openpilot.selfdrive.test.process_replay.migration import migrate_all
|
||||
|
@ -362,14 +363,14 @@ def get_car_params_callback(rc, pm, msgs, fingerprint):
|
|||
cached_params = None
|
||||
if has_cached_cp:
|
||||
with car.CarParams.from_bytes(cached_params_raw) as _cached_params:
|
||||
cached_params = _cached_params
|
||||
cached_params = structs.CarParams(carName=_cached_params.carName, carFw=_cached_params.carFw, carVin=_cached_params.carVin)
|
||||
|
||||
CP = get_car(*can_callbacks, lambda obd: None, Params().get_bool("ExperimentalLongitudinalEnabled"), cached_params=cached_params).CP
|
||||
|
||||
if not params.get_bool("DisengageOnAccelerator"):
|
||||
CP.alternativeExperience |= ALTERNATIVE_EXPERIENCE.DISABLE_DISENGAGE_ON_GAS
|
||||
|
||||
params.put("CarParams", CP.to_bytes())
|
||||
params.put("CarParams", convert_to_capnp(CP).to_bytes())
|
||||
|
||||
|
||||
def controlsd_rcv_callback(msg, cfg, frame):
|
||||
|
|
|
@ -1 +1 @@
|
|||
d768496a1a85bfe5b74c99a79203affdf9a0a065
|
||||
fa4965a27dee4449ad8b255f9f7674d69327b6f7
|
|
@ -36,7 +36,7 @@ MAX_TOTAL_CPU = 250. # total for all 8 cores
|
|||
PROCS = {
|
||||
# Baseline CPU usage by process
|
||||
"selfdrive.controls.controlsd": 32.0,
|
||||
"selfdrive.car.card": 22.0,
|
||||
"selfdrive.car.card": 26.0,
|
||||
"./loggerd": 14.0,
|
||||
"./encoderd": 17.0,
|
||||
"./camerad": 14.5,
|
||||
|
|
|
@ -9,6 +9,7 @@ import cereal.messaging as messaging
|
|||
from cereal.services import SERVICE_LIST
|
||||
from openpilot.common.mock import mock_messages
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.selfdrive.car.card import convert_to_capnp
|
||||
from openpilot.selfdrive.car.car_helpers import get_demo_car_params
|
||||
from openpilot.system.hardware.tici.power_monitor import get_power
|
||||
from openpilot.system.manager.process_config import managed_processes
|
||||
|
@ -42,7 +43,7 @@ PROCS = [
|
|||
class TestPowerDraw:
|
||||
|
||||
def setup_method(self):
|
||||
Params().put("CarParams", get_demo_car_params().to_bytes())
|
||||
Params().put("CarParams", convert_to_capnp(get_demo_car_params()).to_bytes())
|
||||
|
||||
# wait a bit for power save to disable
|
||||
time.sleep(5)
|
||||
|
|
Loading…
Reference in New Issue