From 015eed5d61c583328d419a7990ffac0eee97edd4 Mon Sep 17 00:00:00 2001 From: Justin Newberry Date: Thu, 22 Feb 2024 20:17:00 -0500 Subject: [PATCH 01/10] Subaru: move to PlatformConfig (#31547) * subaru platform config * forester wrong dbc * spacing --- selfdrive/car/subaru/values.py | 156 +++++++++++++++++++-------------- 1 file changed, 90 insertions(+), 66 deletions(-) diff --git a/selfdrive/car/subaru/values.py b/selfdrive/car/subaru/values.py index 2f7350b966..580408df0c 100644 --- a/selfdrive/car/subaru/values.py +++ b/selfdrive/car/subaru/values.py @@ -1,10 +1,10 @@ from dataclasses import dataclass, field -from enum import Enum, IntFlag, StrEnum -from typing import Dict, List, Union +from enum import Enum, IntFlag +from typing import List from cereal import car from panda.python import uds -from openpilot.selfdrive.car import dbc_dict +from openpilot.selfdrive.car import DbcDict, PlatformConfig, Platforms, dbc_dict from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarInfo, CarParts, Tool, Column from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries, p16 @@ -68,27 +68,6 @@ class CanBus: camera = 2 -class CAR(StrEnum): - # Global platform - ASCENT = "SUBARU ASCENT LIMITED 2019" - ASCENT_2023 = "SUBARU ASCENT 2023" - IMPREZA = "SUBARU IMPREZA LIMITED 2019" - IMPREZA_2020 = "SUBARU IMPREZA SPORT 2020" - FORESTER = "SUBARU FORESTER 2019" - OUTBACK = "SUBARU OUTBACK 6TH GEN" - CROSSTREK_HYBRID = "SUBARU CROSSTREK HYBRID 2020" - FORESTER_HYBRID = "SUBARU FORESTER HYBRID 2020" - LEGACY = "SUBARU LEGACY 7TH GEN" - FORESTER_2022 = "SUBARU FORESTER 2022" - OUTBACK_2023 = "SUBARU OUTBACK 7TH GEN" - - # Pre-global - FORESTER_PREGLOBAL = "SUBARU FORESTER 2017 - 2018" - LEGACY_PREGLOBAL = "SUBARU LEGACY 2015 - 2018" - OUTBACK_PREGLOBAL = "SUBARU OUTBACK 2015 - 2017" - OUTBACK_PREGLOBAL_2018 = "SUBARU OUTBACK 2018 - 2019" - - class Footnote(Enum): GLOBAL = CarFootnote( "In the non-US market, openpilot requires the car to come equipped with EyeSight with Lane Keep Assistance.", @@ -110,32 +89,92 @@ class SubaruCarInfo(CarInfo): if CP.experimentalLongitudinalAvailable: self.footnotes.append(Footnote.EXP_LONG) -CAR_INFO: Dict[str, Union[SubaruCarInfo, List[SubaruCarInfo]]] = { - CAR.ASCENT: SubaruCarInfo("Subaru Ascent 2019-21", "All"), - CAR.OUTBACK: SubaruCarInfo("Subaru Outback 2020-22", "All", car_parts=CarParts.common([CarHarness.subaru_b])), - CAR.LEGACY: SubaruCarInfo("Subaru Legacy 2020-22", "All", car_parts=CarParts.common([CarHarness.subaru_b])), - CAR.IMPREZA: [ - SubaruCarInfo("Subaru Impreza 2017-19"), - SubaruCarInfo("Subaru Crosstrek 2018-19", video_link="https://youtu.be/Agww7oE1k-s?t=26"), - SubaruCarInfo("Subaru XV 2018-19", video_link="https://youtu.be/Agww7oE1k-s?t=26"), - ], - CAR.IMPREZA_2020: [ - SubaruCarInfo("Subaru Impreza 2020-22"), - SubaruCarInfo("Subaru Crosstrek 2020-23"), - SubaruCarInfo("Subaru XV 2020-21"), - ], + +@dataclass +class SubaruPlatformConfig(PlatformConfig): + dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('subaru_global_2017_generated', None)) + + +class CAR(Platforms): + # Global platform + ASCENT = SubaruPlatformConfig( + "SUBARU ASCENT LIMITED 2019", + SubaruCarInfo("Subaru Ascent 2019-21", "All"), + ) + OUTBACK = SubaruPlatformConfig( + "SUBARU OUTBACK 6TH GEN", + SubaruCarInfo("Subaru Outback 2020-22", "All", car_parts=CarParts.common([CarHarness.subaru_b])), + ) + LEGACY = SubaruPlatformConfig( + "SUBARU LEGACY 7TH GEN", + SubaruCarInfo("Subaru Legacy 2020-22", "All", car_parts=CarParts.common([CarHarness.subaru_b])), + ) + IMPREZA= SubaruPlatformConfig( + "SUBARU IMPREZA LIMITED 2019", + [ + SubaruCarInfo("Subaru Impreza 2017-19"), + SubaruCarInfo("Subaru Crosstrek 2018-19", video_link="https://youtu.be/Agww7oE1k-s?t=26"), + SubaruCarInfo("Subaru XV 2018-19", video_link="https://youtu.be/Agww7oE1k-s?t=26"), + ], + ) + IMPREZA_2020 = SubaruPlatformConfig( + "SUBARU IMPREZA SPORT 2020", + [ + SubaruCarInfo("Subaru Impreza 2020-22"), + SubaruCarInfo("Subaru Crosstrek 2020-23"), + SubaruCarInfo("Subaru XV 2020-21"), + ], + ) # TODO: is there an XV and Impreza too? - CAR.CROSSTREK_HYBRID: SubaruCarInfo("Subaru Crosstrek Hybrid 2020", car_parts=CarParts.common([CarHarness.subaru_b])), - CAR.FORESTER_HYBRID: SubaruCarInfo("Subaru Forester Hybrid 2020"), - CAR.FORESTER: SubaruCarInfo("Subaru Forester 2019-21", "All"), - CAR.FORESTER_PREGLOBAL: SubaruCarInfo("Subaru Forester 2017-18"), - CAR.LEGACY_PREGLOBAL: SubaruCarInfo("Subaru Legacy 2015-18"), - CAR.OUTBACK_PREGLOBAL: SubaruCarInfo("Subaru Outback 2015-17"), - CAR.OUTBACK_PREGLOBAL_2018: SubaruCarInfo("Subaru Outback 2018-19"), - CAR.FORESTER_2022: SubaruCarInfo("Subaru Forester 2022-24", "All", car_parts=CarParts.common([CarHarness.subaru_c])), - CAR.OUTBACK_2023: SubaruCarInfo("Subaru Outback 2023", "All", car_parts=CarParts.common([CarHarness.subaru_d])), - CAR.ASCENT_2023: SubaruCarInfo("Subaru Ascent 2023", "All", car_parts=CarParts.common([CarHarness.subaru_d])), -} + CROSSTREK_HYBRID = SubaruPlatformConfig( + "SUBARU CROSSTREK HYBRID 2020", + SubaruCarInfo("Subaru Crosstrek Hybrid 2020", car_parts=CarParts.common([CarHarness.subaru_b])), + dbc_dict('subaru_global_2020_hybrid_generated', None), + ) + FORESTER_HYBRID = SubaruPlatformConfig( + "SUBARU FORESTER HYBRID 2020", + SubaruCarInfo("Subaru Forester Hybrid 2020"), + dbc_dict('subaru_global_2020_hybrid_generated', None), + ) + FORESTER = SubaruPlatformConfig( + "SUBARU FORESTER 2019", + SubaruCarInfo("Subaru Forester 2019-21", "All"), + ) + # Pre-global + FORESTER_PREGLOBAL = SubaruPlatformConfig( + "SUBARU FORESTER 2017 - 2018", + SubaruCarInfo("Subaru Forester 2017-18"), + dbc_dict('subaru_forester_2017_generated', None), + ) + LEGACY_PREGLOBAL = SubaruPlatformConfig( + "SUBARU LEGACY 2015 - 2018", + SubaruCarInfo("Subaru Legacy 2015-18"), + dbc_dict('subaru_outback_2015_generated', None), + ) + OUTBACK_PREGLOBAL = SubaruPlatformConfig( + "SUBARU OUTBACK 2015 - 2017", + SubaruCarInfo("Subaru Outback 2015-17"), + dbc_dict('subaru_outback_2015_generated', None), + ) + OUTBACK_PREGLOBAL_2018 = SubaruPlatformConfig( + "SUBARU OUTBACK 2018 - 2019", + SubaruCarInfo("Subaru Outback 2018-19"), + dbc_dict('subaru_outback_2019_generated', None), + ) + # Angle LKAS + FORESTER_2022= SubaruPlatformConfig( + "SUBARU FORESTER 2022", + SubaruCarInfo("Subaru Forester 2022-24", "All", car_parts=CarParts.common([CarHarness.subaru_c])), + ) + OUTBACK_2023 = SubaruPlatformConfig( + "SUBARU OUTBACK 7TH GEN", + SubaruCarInfo("Subaru Outback 2023", "All", car_parts=CarParts.common([CarHarness.subaru_d])), + ) + ASCENT_2023 = SubaruPlatformConfig( + "SUBARU ASCENT 2023", + SubaruCarInfo("Subaru Ascent 2023", "All", car_parts=CarParts.common([CarHarness.subaru_d])) + ) + LKAS_ANGLE = {CAR.FORESTER_2022, CAR.OUTBACK_2023, CAR.ASCENT_2023} GLOBAL_GEN2 = {CAR.OUTBACK, CAR.LEGACY, CAR.OUTBACK_2023, CAR.ASCENT_2023} @@ -186,20 +225,5 @@ FW_QUERY_CONFIG = FwQueryConfig( } ) -DBC = { - CAR.ASCENT: dbc_dict('subaru_global_2017_generated', None), - CAR.ASCENT_2023: dbc_dict('subaru_global_2017_generated', None), - CAR.IMPREZA: dbc_dict('subaru_global_2017_generated', None), - CAR.IMPREZA_2020: dbc_dict('subaru_global_2017_generated', None), - CAR.FORESTER: dbc_dict('subaru_global_2017_generated', None), - CAR.FORESTER_2022: dbc_dict('subaru_global_2017_generated', None), - CAR.OUTBACK: dbc_dict('subaru_global_2017_generated', None), - CAR.FORESTER_HYBRID: dbc_dict('subaru_global_2020_hybrid_generated', None), - CAR.CROSSTREK_HYBRID: dbc_dict('subaru_global_2020_hybrid_generated', None), - CAR.OUTBACK_2023: dbc_dict('subaru_global_2017_generated', None), - CAR.LEGACY: dbc_dict('subaru_global_2017_generated', None), - CAR.FORESTER_PREGLOBAL: dbc_dict('subaru_forester_2017_generated', None), - CAR.LEGACY_PREGLOBAL: dbc_dict('subaru_outback_2015_generated', None), - CAR.OUTBACK_PREGLOBAL: dbc_dict('subaru_outback_2015_generated', None), - CAR.OUTBACK_PREGLOBAL_2018: dbc_dict('subaru_outback_2019_generated', None), -} +CAR_INFO = CAR.create_carinfo_map() +DBC = CAR.create_dbc_map() From 73a497ded8b4ae7f1e2d3b5a7c4a2f57c748ff1c Mon Sep 17 00:00:00 2001 From: Justin Newberry Date: Thu, 22 Feb 2024 20:49:27 -0500 Subject: [PATCH 02/10] cleanup PlatformConfig (#31551) cleanup --- selfdrive/car/__init__.py | 2 ++ selfdrive/car/subaru/values.py | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/selfdrive/car/__init__.py b/selfdrive/car/__init__.py index ab0a26ca0c..ad21c694cc 100644 --- a/selfdrive/car/__init__.py +++ b/selfdrive/car/__init__.py @@ -78,6 +78,7 @@ def scale_tire_stiffness(mass, wheelbase, center_to_front, tire_stiffness_factor DbcDict = Dict[str, str] + def dbc_dict(pt_dbc, radar_dbc, chassis_dbc=None, body_dbc=None) -> DbcDict: return {'pt': pt_dbc, 'radar': radar_dbc, 'chassis': chassis_dbc, 'body': body_dbc} @@ -245,6 +246,7 @@ class CanSignalRateCalculator: CarInfos = Union[CarInfo, List[CarInfo]] + @dataclass(order=True) class PlatformConfig: platform_str: str diff --git a/selfdrive/car/subaru/values.py b/selfdrive/car/subaru/values.py index 580408df0c..7de083f4a2 100644 --- a/selfdrive/car/subaru/values.py +++ b/selfdrive/car/subaru/values.py @@ -109,7 +109,7 @@ class CAR(Platforms): "SUBARU LEGACY 7TH GEN", SubaruCarInfo("Subaru Legacy 2020-22", "All", car_parts=CarParts.common([CarHarness.subaru_b])), ) - IMPREZA= SubaruPlatformConfig( + IMPREZA = SubaruPlatformConfig( "SUBARU IMPREZA LIMITED 2019", [ SubaruCarInfo("Subaru Impreza 2017-19"), @@ -162,7 +162,7 @@ class CAR(Platforms): dbc_dict('subaru_outback_2019_generated', None), ) # Angle LKAS - FORESTER_2022= SubaruPlatformConfig( + FORESTER_2022 = SubaruPlatformConfig( "SUBARU FORESTER 2022", SubaruCarInfo("Subaru Forester 2022-24", "All", car_parts=CarParts.common([CarHarness.subaru_c])), ) From c9c2ab9cc858bc2bc1ce16a3f4b04545582fcb1d Mon Sep 17 00:00:00 2001 From: Justin Newberry Date: Thu, 22 Feb 2024 21:34:42 -0500 Subject: [PATCH 03/10] pre-commit: run ruff first (#31548) move ruff up --- .pre-commit-config.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f98bca6060..335ccae456 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -32,6 +32,11 @@ repos: # if you've got a short variable name that's getting flagged, add it here - -L bu,ro,te,ue,alo,hda,ois,nam,nams,ned,som,parm,setts,inout,warmup,bumb,nd,sie,preints - --builtins clear,rare,informal,usage,code,names,en-GB_to_en-US +- repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.2.2 + hooks: + - id: ruff + exclude: '^(third_party/)|(cereal/)|(panda/)|(rednose/)|(rednose_repo/)|(tinygrad/)|(tinygrad_repo/)|(teleoprtc/)|(teleoprtc_repo/)' - repo: local hooks: - id: mypy @@ -43,11 +48,6 @@ repos: - --local-partial-types - --explicit-package-bases exclude: '^(third_party/)|(cereal/)|(opendbc/)|(panda/)|(rednose/)|(rednose_repo/)|(tinygrad/)|(tinygrad_repo/)|(teleoprtc/)|(teleoprtc_repo/)|(xx/)' -- repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.2.2 - hooks: - - id: ruff - exclude: '^(third_party/)|(cereal/)|(panda/)|(rednose/)|(rednose_repo/)|(tinygrad/)|(tinygrad_repo/)|(teleoprtc/)|(teleoprtc_repo/)' - repo: local hooks: - id: cppcheck From 72a7f008ab3c4d0f86605860579926911815a103 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 23 Feb 2024 06:00:28 -0600 Subject: [PATCH 04/10] Volkswagen: log FW on non-OBD buses (#31556) * log lots * update refs * cmt --- selfdrive/car/tests/test_fw_fingerprint.py | 4 ++-- selfdrive/car/volkswagen/values.py | 15 +++++++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/selfdrive/car/tests/test_fw_fingerprint.py b/selfdrive/car/tests/test_fw_fingerprint.py index e1ebd5cf18..1a745b4447 100755 --- a/selfdrive/car/tests/test_fw_fingerprint.py +++ b/selfdrive/car/tests/test_fw_fingerprint.py @@ -263,7 +263,7 @@ class TestFwFingerprintTiming(unittest.TestCase): print(f'get_vin {name} case, query time={self.total_time / self.N} seconds') def test_fw_query_timing(self): - total_ref_time = {1: 6.05, 2: 6.95} + total_ref_time = {1: 6.5, 2: 7.4} brand_ref_times = { 1: { 'gm': 0.5, @@ -277,7 +277,7 @@ class TestFwFingerprintTiming(unittest.TestCase): 'subaru': 0.45, 'tesla': 0.2, 'toyota': 1.6, - 'volkswagen': 0.2, + 'volkswagen': 0.65, }, 2: { 'ford': 0.3, diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py index 35cb3607ec..b09cbc5d8a 100644 --- a/selfdrive/car/volkswagen/values.py +++ b/selfdrive/car/volkswagen/values.py @@ -293,17 +293,24 @@ VOLKSWAGEN_VERSION_RESPONSE = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER + VOLKSWAGEN_RX_OFFSET = 0x6a FW_QUERY_CONFIG = FwQueryConfig( - requests=[ + # TODO: add back whitelists after we gather enough data + requests=[request for bus, obd_multiplexing in [(1, True), (1, False), (0, False)] for request in [ Request( [VOLKSWAGEN_VERSION_REQUEST_MULTI], [VOLKSWAGEN_VERSION_RESPONSE], - whitelist_ecus=[Ecu.srs, Ecu.eps, Ecu.fwdRadar], + # whitelist_ecus=[Ecu.srs, Ecu.eps, Ecu.fwdRadar], rx_offset=VOLKSWAGEN_RX_OFFSET, + bus=bus, + logging=(bus != 1 or not obd_multiplexing), + obd_multiplexing=obd_multiplexing, ), Request( [VOLKSWAGEN_VERSION_REQUEST_MULTI], [VOLKSWAGEN_VERSION_RESPONSE], - whitelist_ecus=[Ecu.engine, Ecu.transmission], + # whitelist_ecus=[Ecu.engine, Ecu.transmission], + bus=bus, + logging=(bus != 1 or not obd_multiplexing), + obd_multiplexing=obd_multiplexing, ), - ], + ]], ) From 556f9738960526d6eeaab9fe639d0340a6d5d6c9 Mon Sep 17 00:00:00 2001 From: Justin Newberry Date: Fri, 23 Feb 2024 14:50:33 -0500 Subject: [PATCH 05/10] segment range docs update (#31560) * the format * cleaner --- tools/lib/README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/lib/README.md b/tools/lib/README.md index a0c4a0863b..af1ad0de22 100644 --- a/tools/lib/README.md +++ b/tools/lib/README.md @@ -34,10 +34,16 @@ for msg in lr: ### Segment Ranges -We also support a new format called a "segment range", where you can specify which segments from a route to load. +We also support a new format called a "segment range": + +``` +344c5c15b34f2d8a / 2024-01-03--09-37-12 / 2:6 / q +[ dongle id ] [ timestamp ] [ selector ] [ query type] +``` + +you can specify which segments from a route to load ```python - lr = LogReader("a2a0ccea32023010|2023-07-27--13-01-19/4") # 4th segment lr = LogReader("a2a0ccea32023010|2023-07-27--13-01-19/4:6") # 4th and 5th segment lr = LogReader("a2a0ccea32023010|2023-07-27--13-01-19/-1") # last segment From 1161d33c1892b32980a222b7c5b2ad9d6b05621e Mon Sep 17 00:00:00 2001 From: Justin Newberry Date: Fri, 23 Feb 2024 16:23:40 -0500 Subject: [PATCH 06/10] Subaru: move carspecs to PlatformConfig (#31550) * subaru platform config * forester wrong dbc * spacing * subaru car specs * someday! * more red diff * all brands can be done like this * but this should be done first and thats subaru specific * that seems very low but we shouldn't change it here * as long as it subclasses str its fine * fix --- selfdrive/car/__init__.py | 13 ++++++++-- selfdrive/car/interfaces.py | 12 +++++++-- selfdrive/car/subaru/interface.py | 40 +++--------------------------- selfdrive/car/subaru/values.py | 27 +++++++++++++++----- selfdrive/car/tests/test_models.py | 2 +- 5 files changed, 47 insertions(+), 47 deletions(-) diff --git a/selfdrive/car/__init__.py b/selfdrive/car/__init__.py index ad21c694cc..8f2c8bd451 100644 --- a/selfdrive/car/__init__.py +++ b/selfdrive/car/__init__.py @@ -247,12 +247,21 @@ class CanSignalRateCalculator: CarInfos = Union[CarInfo, List[CarInfo]] +@dataclass +class CarSpecs: + mass: float + wheelbase: float + steerRatio: float + + @dataclass(order=True) class PlatformConfig: platform_str: str car_info: CarInfos dbc_dict: DbcDict + specs: Optional[CarSpecs] = None + def __hash__(self) -> int: return hash(self.platform_str) @@ -268,8 +277,8 @@ class Platforms(str, ReprEnum): @classmethod def create_dbc_map(cls) -> Dict[str, DbcDict]: - return {p.config.platform_str: p.config.dbc_dict for p in cls} + return {p: p.config.dbc_dict for p in cls} @classmethod def create_carinfo_map(cls) -> Dict[str, CarInfos]: - return {p.config.platform_str: p.config.car_info for p in cls} + return {p: p.config.car_info for p in cls} diff --git a/selfdrive/car/interfaces.py b/selfdrive/car/interfaces.py index 9767752edb..2b0b148ccf 100644 --- a/selfdrive/car/interfaces.py +++ b/selfdrive/car/interfaces.py @@ -4,7 +4,7 @@ import numpy as np import tomllib from abc import abstractmethod, ABC from enum import StrEnum -from typing import Any, Dict, Optional, Tuple, List, Callable, NamedTuple +from typing import Any, Dict, Optional, Tuple, List, Callable, NamedTuple, cast from cereal import car from openpilot.common.basedir import BASEDIR @@ -12,7 +12,7 @@ from openpilot.common.conversions import Conversions as CV from openpilot.common.simple_kalman import KF1D, get_kalman_gain from openpilot.common.numpy_fast import clip from openpilot.common.realtime import DT_CTRL -from openpilot.selfdrive.car import apply_hysteresis, gen_empty_fingerprint, scale_rot_inertia, scale_tire_stiffness, STD_CARGO_KG +from openpilot.selfdrive.car import PlatformConfig, apply_hysteresis, gen_empty_fingerprint, scale_rot_inertia, scale_tire_stiffness, STD_CARGO_KG from openpilot.selfdrive.controls.lib.drive_helpers import V_CRUISE_MAX, get_friction from openpilot.selfdrive.controls.lib.events import Events from openpilot.selfdrive.controls.lib.vehicle_model import VehicleModel @@ -109,6 +109,14 @@ class CarInterfaceBase(ABC): @classmethod def get_params(cls, candidate: str, fingerprint: Dict[int, Dict[int, int]], car_fw: List[car.CarParams.CarFw], experimental_long: bool, docs: bool): ret = CarInterfaceBase.get_std_params(candidate) + + if hasattr(candidate, "config"): + platform_config = cast(PlatformConfig, candidate.config) + if platform_config.specs is not None: + ret.mass = platform_config.specs.mass + ret.wheelbase = platform_config.specs.wheelbase + ret.steerRatio = platform_config.specs.steerRatio + ret = cls._get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs) # Vehicle mass is published curb weight plus assumed payload such as a human driver; notCars have no assumed payload diff --git a/selfdrive/car/subaru/interface.py b/selfdrive/car/subaru/interface.py index 1296aead5e..edf07ac2ef 100644 --- a/selfdrive/car/subaru/interface.py +++ b/selfdrive/car/subaru/interface.py @@ -40,11 +40,10 @@ class CarInterface(CarInterfaceBase): else: CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) + + ret.centerToFront = ret.wheelbase * 0.5 + if candidate in (CAR.ASCENT, CAR.ASCENT_2023): - ret.mass = 2031. - ret.wheelbase = 2.89 - ret.centerToFront = ret.wheelbase * 0.5 - ret.steerRatio = 13.5 ret.steerActuatorDelay = 0.3 # end-to-end angle controller ret.lateralTuning.init('pid') ret.lateralTuning.pid.kf = 0.00003 @@ -52,10 +51,6 @@ class CarInterface(CarInterfaceBase): ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.0025, 0.1], [0.00025, 0.01]] elif candidate == CAR.IMPREZA: - ret.mass = 1568. - ret.wheelbase = 2.67 - ret.centerToFront = ret.wheelbase * 0.5 - ret.steerRatio = 15 ret.steerActuatorDelay = 0.4 # end-to-end angle controller ret.lateralTuning.init('pid') ret.lateralTuning.pid.kf = 0.00005 @@ -63,58 +58,31 @@ class CarInterface(CarInterfaceBase): ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2, 0.3], [0.02, 0.03]] elif candidate == CAR.IMPREZA_2020: - ret.mass = 1480. - ret.wheelbase = 2.67 - ret.centerToFront = ret.wheelbase * 0.5 - ret.steerRatio = 17 # learned, 14 stock ret.lateralTuning.init('pid') ret.lateralTuning.pid.kf = 0.00005 ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0., 14., 23.], [0., 14., 23.]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.045, 0.042, 0.20], [0.04, 0.035, 0.045]] elif candidate == CAR.CROSSTREK_HYBRID: - ret.mass = 1668. - ret.wheelbase = 2.67 - ret.centerToFront = ret.wheelbase * 0.5 - ret.steerRatio = 17 ret.steerActuatorDelay = 0.1 elif candidate in (CAR.FORESTER, CAR.FORESTER_2022, CAR.FORESTER_HYBRID): - ret.mass = 1568. - ret.wheelbase = 2.67 - ret.centerToFront = ret.wheelbase * 0.5 - ret.steerRatio = 17 # learned, 14 stock ret.lateralTuning.init('pid') ret.lateralTuning.pid.kf = 0.000038 ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0., 14., 23.], [0., 14., 23.]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.01, 0.065, 0.2], [0.001, 0.015, 0.025]] elif candidate in (CAR.OUTBACK, CAR.LEGACY, CAR.OUTBACK_2023): - ret.mass = 1568. - ret.wheelbase = 2.67 - ret.centerToFront = ret.wheelbase * 0.5 - ret.steerRatio = 17 ret.steerActuatorDelay = 0.1 elif candidate in (CAR.FORESTER_PREGLOBAL, CAR.OUTBACK_PREGLOBAL_2018): ret.safetyConfigs[0].safetyParam = Panda.FLAG_SUBARU_PREGLOBAL_REVERSED_DRIVER_TORQUE # Outback 2018-2019 and Forester have reversed driver torque signal - ret.mass = 1568 - ret.wheelbase = 2.67 - ret.centerToFront = ret.wheelbase * 0.5 - ret.steerRatio = 20 # learned, 14 stock elif candidate == CAR.LEGACY_PREGLOBAL: - ret.mass = 1568 - ret.wheelbase = 2.67 - ret.centerToFront = ret.wheelbase * 0.5 - ret.steerRatio = 12.5 # 14.5 stock ret.steerActuatorDelay = 0.15 elif candidate == CAR.OUTBACK_PREGLOBAL: - ret.mass = 1568 - ret.wheelbase = 2.67 - ret.centerToFront = ret.wheelbase * 0.5 - ret.steerRatio = 20 # learned, 14 stock + pass else: raise ValueError(f"unknown car: {candidate}") diff --git a/selfdrive/car/subaru/values.py b/selfdrive/car/subaru/values.py index 7de083f4a2..b871a919e3 100644 --- a/selfdrive/car/subaru/values.py +++ b/selfdrive/car/subaru/values.py @@ -4,7 +4,7 @@ from typing import List from cereal import car from panda.python import uds -from openpilot.selfdrive.car import DbcDict, PlatformConfig, Platforms, dbc_dict +from openpilot.selfdrive.car import CarSpecs, DbcDict, PlatformConfig, Platforms, dbc_dict from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarInfo, CarParts, Tool, Column from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries, p16 @@ -100,14 +100,17 @@ class CAR(Platforms): ASCENT = SubaruPlatformConfig( "SUBARU ASCENT LIMITED 2019", SubaruCarInfo("Subaru Ascent 2019-21", "All"), + specs=CarSpecs(mass=2031, wheelbase=2.89, steerRatio=13.5), ) OUTBACK = SubaruPlatformConfig( "SUBARU OUTBACK 6TH GEN", SubaruCarInfo("Subaru Outback 2020-22", "All", car_parts=CarParts.common([CarHarness.subaru_b])), + specs=CarSpecs(mass=1568, wheelbase=2.67, steerRatio=17), ) LEGACY = SubaruPlatformConfig( "SUBARU LEGACY 7TH GEN", SubaruCarInfo("Subaru Legacy 2020-22", "All", car_parts=CarParts.common([CarHarness.subaru_b])), + specs=OUTBACK.specs, ) IMPREZA = SubaruPlatformConfig( "SUBARU IMPREZA LIMITED 2019", @@ -116,6 +119,7 @@ class CAR(Platforms): SubaruCarInfo("Subaru Crosstrek 2018-19", video_link="https://youtu.be/Agww7oE1k-s?t=26"), SubaruCarInfo("Subaru XV 2018-19", video_link="https://youtu.be/Agww7oE1k-s?t=26"), ], + specs=CarSpecs(mass=1568, wheelbase=2.67, steerRatio=15), ) IMPREZA_2020 = SubaruPlatformConfig( "SUBARU IMPREZA SPORT 2020", @@ -124,55 +128,66 @@ class CAR(Platforms): SubaruCarInfo("Subaru Crosstrek 2020-23"), SubaruCarInfo("Subaru XV 2020-21"), ], + specs=CarSpecs(mass=1480, wheelbase=2.67, steerRatio=17), ) # TODO: is there an XV and Impreza too? CROSSTREK_HYBRID = SubaruPlatformConfig( "SUBARU CROSSTREK HYBRID 2020", SubaruCarInfo("Subaru Crosstrek Hybrid 2020", car_parts=CarParts.common([CarHarness.subaru_b])), dbc_dict('subaru_global_2020_hybrid_generated', None), + specs=CarSpecs(mass=1668, wheelbase=2.67, steerRatio=17), + ) + FORESTER = SubaruPlatformConfig( + "SUBARU FORESTER 2019", + SubaruCarInfo("Subaru Forester 2019-21", "All"), + specs=CarSpecs(mass=1668, wheelbase=2.67, steerRatio=17), ) FORESTER_HYBRID = SubaruPlatformConfig( "SUBARU FORESTER HYBRID 2020", SubaruCarInfo("Subaru Forester Hybrid 2020"), dbc_dict('subaru_global_2020_hybrid_generated', None), - ) - FORESTER = SubaruPlatformConfig( - "SUBARU FORESTER 2019", - SubaruCarInfo("Subaru Forester 2019-21", "All"), + specs=FORESTER.specs, ) # Pre-global FORESTER_PREGLOBAL = SubaruPlatformConfig( "SUBARU FORESTER 2017 - 2018", SubaruCarInfo("Subaru Forester 2017-18"), dbc_dict('subaru_forester_2017_generated', None), + specs=CarSpecs(mass=1568, wheelbase=2.67, steerRatio=20), ) LEGACY_PREGLOBAL = SubaruPlatformConfig( "SUBARU LEGACY 2015 - 2018", SubaruCarInfo("Subaru Legacy 2015-18"), dbc_dict('subaru_outback_2015_generated', None), + specs=CarSpecs(mass=1568, wheelbase=2.67, steerRatio=12.5), ) OUTBACK_PREGLOBAL = SubaruPlatformConfig( "SUBARU OUTBACK 2015 - 2017", SubaruCarInfo("Subaru Outback 2015-17"), dbc_dict('subaru_outback_2015_generated', None), + specs=FORESTER_PREGLOBAL.specs, ) OUTBACK_PREGLOBAL_2018 = SubaruPlatformConfig( "SUBARU OUTBACK 2018 - 2019", SubaruCarInfo("Subaru Outback 2018-19"), dbc_dict('subaru_outback_2019_generated', None), + specs=FORESTER_PREGLOBAL.specs, ) # Angle LKAS FORESTER_2022 = SubaruPlatformConfig( "SUBARU FORESTER 2022", SubaruCarInfo("Subaru Forester 2022-24", "All", car_parts=CarParts.common([CarHarness.subaru_c])), + specs=FORESTER.specs, ) OUTBACK_2023 = SubaruPlatformConfig( "SUBARU OUTBACK 7TH GEN", SubaruCarInfo("Subaru Outback 2023", "All", car_parts=CarParts.common([CarHarness.subaru_d])), + specs=OUTBACK.specs, ) ASCENT_2023 = SubaruPlatformConfig( "SUBARU ASCENT 2023", - SubaruCarInfo("Subaru Ascent 2023", "All", car_parts=CarParts.common([CarHarness.subaru_d])) + SubaruCarInfo("Subaru Ascent 2023", "All", car_parts=CarParts.common([CarHarness.subaru_d])), + specs=ASCENT.specs, ) diff --git a/selfdrive/car/tests/test_models.py b/selfdrive/car/tests/test_models.py index 3592fd0baa..ec7527713d 100755 --- a/selfdrive/car/tests/test_models.py +++ b/selfdrive/car/tests/test_models.py @@ -50,7 +50,7 @@ def get_test_cases() -> List[Tuple[str, Optional[CarTestRoute]]]: for i, c in enumerate(sorted(all_known_cars())): if i % NUM_JOBS == JOB_ID: - test_cases.extend(sorted((c.value, r) for r in routes_by_car.get(c, (None,)))) + test_cases.extend(sorted((c, r) for r in routes_by_car.get(c, (None,)))) else: segment_list = read_segment_list(os.path.join(BASEDIR, INTERNAL_SEG_LIST)) From b75a6cea34864d097ebd22a713db445180c72732 Mon Sep 17 00:00:00 2001 From: Jason Young <46612682+jyoung8607@users.noreply.github.com> Date: Fri, 23 Feb 2024 19:35:21 -0600 Subject: [PATCH 07/10] VW PQ: Consolidate and cleanup tuning (#31566) consolidate and cleanup PQ configs --- selfdrive/car/volkswagen/interface.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/selfdrive/car/volkswagen/interface.py b/selfdrive/car/volkswagen/interface.py index 710e779d0a..544d104d33 100644 --- a/selfdrive/car/volkswagen/interface.py +++ b/selfdrive/car/volkswagen/interface.py @@ -72,14 +72,18 @@ class CarInterface(CarInterfaceBase): # Global lateral tuning defaults, can be overridden per-vehicle - ret.steerActuatorDelay = 0.1 - ret.steerLimitTimer = 0.4 ret.steerRatio = 15.6 # Let the params learner figure this out - ret.lateralTuning.pid.kpBP = [0.] - ret.lateralTuning.pid.kiBP = [0.] - ret.lateralTuning.pid.kf = 0.00006 - ret.lateralTuning.pid.kpV = [0.6] - ret.lateralTuning.pid.kiV = [0.2] + ret.steerLimitTimer = 0.4 + if candidate in PQ_CARS: + ret.steerActuatorDelay = 0.2 + CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) + else: + ret.steerActuatorDelay = 0.1 + ret.lateralTuning.pid.kpBP = [0.] + ret.lateralTuning.pid.kiBP = [0.] + ret.lateralTuning.pid.kf = 0.00006 + ret.lateralTuning.pid.kpV = [0.6] + ret.lateralTuning.pid.kiV = [0.2] # Global longitudinal tuning defaults, can be overridden per-vehicle @@ -131,8 +135,6 @@ class CarInterface(CarInterfaceBase): ret.wheelbase = 2.80 ret.minEnableSpeed = 20 * CV.KPH_TO_MS # ACC "basic", no FtS ret.minSteerSpeed = 50 * CV.KPH_TO_MS - ret.steerActuatorDelay = 0.2 - CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) elif candidate == CAR.POLO_MK6: ret.mass = 1230 @@ -142,7 +144,6 @@ class CarInterface(CarInterfaceBase): ret.mass = 1639 ret.wheelbase = 2.92 ret.minSteerSpeed = 50 * CV.KPH_TO_MS - ret.steerActuatorDelay = 0.2 elif candidate == CAR.TAOS_MK1: ret.mass = 1498 From 92475d653bcb94a907d20701a697118fbe8815ef Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Fri, 23 Feb 2024 17:41:03 -0800 Subject: [PATCH 08/10] agnos 9.7 (#31564) * agnos 9.7 * update --- launch_env.sh | 2 +- system/hardware/tici/agnos.json | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/launch_env.sh b/launch_env.sh index 0c72c54581..6859afb0d4 100755 --- a/launch_env.sh +++ b/launch_env.sh @@ -7,7 +7,7 @@ export OPENBLAS_NUM_THREADS=1 export VECLIB_MAXIMUM_THREADS=1 if [ -z "$AGNOS_VERSION" ]; then - export AGNOS_VERSION="9.6" + export AGNOS_VERSION="9.7" fi export STAGING_ROOT="/data/safe_staging" diff --git a/system/hardware/tici/agnos.json b/system/hardware/tici/agnos.json index b4408d2140..e69842cfec 100644 --- a/system/hardware/tici/agnos.json +++ b/system/hardware/tici/agnos.json @@ -61,17 +61,17 @@ }, { "name": "system", - "url": "https://commadist.azureedge.net/agnosupdate/system-3bfb0f3a6bf677bdc8a6227f49ce3258025e1886dc81533e3fbacb356b5601db.img.xz", - "hash": "10ac02f18c5f1cde5a888a3411d3701b929c3488753467e77aad6085db058eb9", - "hash_raw": "3bfb0f3a6bf677bdc8a6227f49ce3258025e1886dc81533e3fbacb356b5601db", + "url": "https://commadist.azureedge.net/agnosupdate/system-0f69173d5f3058f7197c139442a6556be59e52f15402a263215a329ba5ec41e2.img.xz", + "hash": "4858385ba6284bcaa179ab77ac4263486e4d8670df921e4ac400464dc1dde59c", + "hash_raw": "0f69173d5f3058f7197c139442a6556be59e52f15402a263215a329ba5ec41e2", "size": 10737418240, "sparse": true, "full_check": false, "has_ab": true, "alt": { - "hash": "a7db41b93b587f8f9c3f83a3313f186445c4bdf07283cd6a5421dfbc0286c9db", - "url": "https://commadist.azureedge.net/agnosupdate/system-skip-chunks-3bfb0f3a6bf677bdc8a6227f49ce3258025e1886dc81533e3fbacb356b5601db.img.xz", - "size": 4548131508 + "hash": "42658a6fff660d9b6abb9cb9fbb3481071259c9a9598718af6b1edff2b556009", + "url": "https://commadist.azureedge.net/agnosupdate/system-skip-chunks-0f69173d5f3058f7197c139442a6556be59e52f15402a263215a329ba5ec41e2.img.xz", + "size": 4548292756 } } ] \ No newline at end of file From adb7e2e2297ecfc00e333155d4c8d0666c2c9205 Mon Sep 17 00:00:00 2001 From: Justin Newberry Date: Fri, 23 Feb 2024 23:54:48 -0500 Subject: [PATCH 09/10] CI: Retry multiarch build (#31570) hardware --- .github/workflows/selfdrive_tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/selfdrive_tests.yaml b/.github/workflows/selfdrive_tests.yaml index 8b1f256bfb..d1dff147f2 100644 --- a/.github/workflows/selfdrive_tests.yaml +++ b/.github/workflows/selfdrive_tests.yaml @@ -117,7 +117,7 @@ jobs: - name: Merge x64 and arm64 tags run: | export PUSH_IMAGE=true - selfdrive/test/docker_tag_multiarch.sh base x86_64 aarch64 + scripts/retry.sh selfdrive/test/docker_tag_multiarch.sh base x86_64 aarch64 static_analysis: name: static analysis From 378ba114f9d4852374d76c7ebc0318a80cd29c43 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 23 Feb 2024 23:22:34 -0600 Subject: [PATCH 10/10] Ford: support hybrid Q3 platforms (#31568) * bump * ford: remove dynamic dashcam lockout for hybrids * releases? * Revert "releases?" This reverts commit 88d950043d79b8c00535f48ed84b854bc2ab2557. * bump * Reapply "releases?" This reverts commit db5079dc3f1a6bce70bd04430be45704d8604e76. * 097 --- RELEASES.md | 1 + panda | 2 +- selfdrive/car/ford/carstate.py | 7 ------- selfdrive/car/ford/interface.py | 2 -- 4 files changed, 2 insertions(+), 10 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index 096fa691ac..d0fd530db1 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,6 +1,7 @@ Version 0.9.7 (2024-XX-XX) ======================== * New driving model +* Support for many hybrid Ford models Version 0.9.6 (2024-02-27) ======================== diff --git a/panda b/panda index b4442a7c93..6aa4b55033 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit b4442a7c930aac112cdd82cddfc3dd12254a56e1 +Subproject commit 6aa4b550336136bc20a6abb307cf310e876eba28 diff --git a/selfdrive/car/ford/carstate.py b/selfdrive/car/ford/carstate.py index ef56d23d79..34006e8da4 100644 --- a/selfdrive/car/ford/carstate.py +++ b/selfdrive/car/ford/carstate.py @@ -18,17 +18,10 @@ class CarState(CarStateBase): self.shifter_values = can_define.dv["Gear_Shift_by_Wire_FD1"]["TrnRng_D_RqGsm"] self.vehicle_sensors_valid = False - self.unsupported_platform = False def update(self, cp, cp_cam): ret = car.CarState.new_message() - # Ford Q3 hybrid variants experience a bug where a message from the PCM sends invalid checksums, - # this must be root-caused before enabling support. Ford Q4 hybrids do not have this problem. - # TrnAin_Tq_Actl and its quality flag are only set on ICE platform variants - self.unsupported_platform = (cp.vl["VehicleOperatingModes"]["TrnAinTq_D_Qf"] == 0 and - self.CP.carFingerprint not in CANFD_CAR) - # 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 self.vehicle_sensors_valid = cp.vl["SteeringPinion_Data"]["StePinCompAnEst_D_Qf"] == 3 diff --git a/selfdrive/car/ford/interface.py b/selfdrive/car/ford/interface.py index cc013fb54b..685a2a27ad 100644 --- a/selfdrive/car/ford/interface.py +++ b/selfdrive/car/ford/interface.py @@ -109,8 +109,6 @@ class CarInterface(CarInterfaceBase): events = self.create_common_events(ret, extra_gears=[GearShifter.manumatic]) if not self.CS.vehicle_sensors_valid: events.add(car.CarEvent.EventName.vehicleSensorsInvalid) - if self.CS.unsupported_platform: - events.add(car.CarEvent.EventName.startupNoControl) ret.events = events.to_msg()