From 912db794f0c764d1fca9a53ca9d902b50b0b00eb Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 11 Aug 2022 14:53:54 -0700 Subject: [PATCH 001/106] bump panda (#25407) --- panda | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda b/panda index 89989abca5def3..486af795034853 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 89989abca5def32c73b8c9e66da804acb12be357 +Subproject commit 486af7950348530309778240f235fd75a30f1842 From ab227027c339f6169b20e17454ca40afe8b375fd Mon Sep 17 00:00:00 2001 From: realfast Date: Thu, 11 Aug 2022 17:14:18 -0500 Subject: [PATCH 002/106] Ram 2500 + 3500 HD support (#25372) * Ram HD Init * Update selfdrive/car/torque_data/override.yaml * Revert FW for 1500 * little cleanup plus test route * bump panda * revert 1500 changes * bump panda * same error max * dashcam + cleanup Co-authored-by: Adeeb Shihadeh --- release/files_common | 1 + selfdrive/car/chrysler/interface.py | 24 ++++++++--- selfdrive/car/chrysler/values.py | 55 +++++++++++++++++++++++-- selfdrive/car/tests/routes.py | 1 + selfdrive/car/torque_data/override.yaml | 1 + 5 files changed, 72 insertions(+), 10 deletions(-) diff --git a/release/files_common b/release/files_common index 0980f7929dfda9..192c6ec45e0687 100644 --- a/release/files_common +++ b/release/files_common @@ -491,6 +491,7 @@ opendbc/can/parser_pyx.pyx opendbc/comma_body.dbc +opendbc/chrysler_ram_hd_generated.dbc opendbc/chrysler_ram_dt_generated.dbc opendbc/chrysler_pacifica_2017_hybrid_generated.dbc opendbc/chrysler_pacifica_2017_hybrid_private_fusion.dbc diff --git a/selfdrive/car/chrysler/interface.py b/selfdrive/car/chrysler/interface.py index 3c2bc3131a4b3c..9bb22b607ce87a 100755 --- a/selfdrive/car/chrysler/interface.py +++ b/selfdrive/car/chrysler/interface.py @@ -2,7 +2,7 @@ from cereal import car from panda import Panda from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config -from selfdrive.car.chrysler.values import CAR, DBC, RAM_CARS +from selfdrive.car.chrysler.values import CAR, DBC, RAM_HD, RAM_DT from selfdrive.car.interfaces import CarInterfaceBase @@ -12,14 +12,20 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None, disa ret = CarInterfaceBase.get_std_params(candidate, fingerprint) ret.carName = "chrysler" - ret.radarOffCan = DBC[candidate]['radar'] is None + ret.dashcamOnly = candidate in RAM_HD - param = Panda.FLAG_CHRYSLER_RAM_DT if candidate in RAM_CARS else None - ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.chrysler, param)] + ret.radarOffCan = DBC[candidate]['radar'] is None ret.steerActuatorDelay = 0.1 ret.steerLimitTimer = 0.4 + # safety config + ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.chrysler)] + if candidate in RAM_HD: + ret.safetyConfigs[0].safetyParam |= Panda.FLAG_CHRYSLER_RAM_HD + elif candidate in RAM_DT: + ret.safetyConfigs[0].safetyParam |= Panda.FLAG_CHRYSLER_RAM_DT + ret.minSteerSpeed = 3.8 # m/s if candidate in (CAR.PACIFICA_2019_HYBRID, CAR.PACIFICA_2020, CAR.JEEP_CHEROKEE_2019): # TODO: allow 2019 cars to steer down to 13 m/s if already engaged. @@ -47,18 +53,24 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None, disa # Ram elif candidate == CAR.RAM_1500: ret.steerActuatorDelay = 0.2 - ret.wheelbase = 3.88 ret.steerRatio = 16.3 ret.mass = 2493. + STD_CARGO_KG CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) - ret.minSteerSpeed = 14.5 if car_fw is not None: for fw in car_fw: if fw.ecu == 'eps' and fw.fwVersion in (b"68312176AE", b"68312176AG", b"68273275AG"): ret.minSteerSpeed = 0. + elif candidate == CAR.RAM_HD: + ret.steerActuatorDelay = 0.2 + ret.wheelbase = 3.785 + ret.steerRatio = 15.61 + ret.mass = 3405. + STD_CARGO_KG + ret.minSteerSpeed = 16 + CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning, 1.0, False) + else: raise ValueError(f"Unsupported car: {candidate}") diff --git a/selfdrive/car/chrysler/values.py b/selfdrive/car/chrysler/values.py index c45a81a0ace509..10478efa89ed49 100644 --- a/selfdrive/car/chrysler/values.py +++ b/selfdrive/car/chrysler/values.py @@ -22,23 +22,30 @@ class CAR: # Ram RAM_1500 = "RAM 1500 5TH GEN" + RAM_HD = "RAM HD 5TH GEN" class CarControllerParams: def __init__(self, CP): - self.STEER_MAX = 261 # higher than this faults the EPS on Chrysler/Jeep. Ram DT allows more self.STEER_ERROR_MAX = 80 - - if CP.carFingerprint in RAM_CARS: + if CP.carFingerprint in RAM_HD: + self.STEER_DELTA_UP = 14 + self.STEER_DELTA_DOWN = 14 + self.STEER_MAX = 361 # higher than this faults the EPS + elif CP.carFingerprint in RAM_DT: self.STEER_DELTA_UP = 6 self.STEER_DELTA_DOWN = 6 + self.STEER_MAX = 261 # EPS allows more, up to 350? else: self.STEER_DELTA_UP = 3 self.STEER_DELTA_DOWN = 3 + self.STEER_MAX = 261 # higher than this faults the EPS STEER_THRESHOLD = 120 -RAM_CARS = {CAR.RAM_1500, } +RAM_DT = {CAR.RAM_1500, } +RAM_HD = {CAR.RAM_HD, } +RAM_CARS = RAM_DT | RAM_HD @dataclass class ChryslerCarInfo(CarInfo): @@ -57,6 +64,10 @@ class ChryslerCarInfo(CarInfo): CAR.JEEP_CHEROKEE: ChryslerCarInfo("Jeep Grand Cherokee 2016-18", video_link="https://www.youtube.com/watch?v=eLR9o2JkuRk"), CAR.JEEP_CHEROKEE_2019: ChryslerCarInfo("Jeep Grand Cherokee 2019-21", video_link="https://www.youtube.com/watch?v=jBe4lWnRSu4"), CAR.RAM_1500: ChryslerCarInfo("Ram 1500 2019-22", harness=Harness.ram), + CAR.RAM_HD: [ + ChryslerCarInfo("Ram 2500 2020-22", harness=Harness.ram), + ChryslerCarInfo("Ram 3500 2020-22", harness=Harness.ram), + ], } # Unique CAN messages: @@ -177,6 +188,41 @@ class ChryslerCarInfo(CarInfo): b'68500483AB', ], }, + + CAR.RAM_HD: { + (Ecu.combinationMeter, 0x742, None): [ + b'68361606AH', + b'68492693AD', + ], + (Ecu.srs, 0x744, None): [ + b'68399794AC', + b'68428503AA', + b'68428505AA', + ], + (Ecu.esp, 0x747, None): [ + b'68334977AH', + b'68504022AB', + b'68530686AB', + ], + (Ecu.fwdRadar, 0x753, None): [ + b'04672895AB', + b'56029827AG', + b'68484694AE', + ], + (Ecu.eps, 0x761, None): [ + b'68421036AC', + b'68507906AB', + ], + (Ecu.engine, 0x7e0, None): [ + b'52421132AF', + b'M2370131MB', + b'M2421132MB', + ], + (Ecu.gateway, 0x18DACBF1, None): [ + b'68488419AB', + b'68535476AB', + ], + }, } DBC = { @@ -188,4 +234,5 @@ class ChryslerCarInfo(CarInfo): CAR.JEEP_CHEROKEE: dbc_dict('chrysler_pacifica_2017_hybrid_generated', 'chrysler_pacifica_2017_hybrid_private_fusion'), CAR.JEEP_CHEROKEE_2019: dbc_dict('chrysler_pacifica_2017_hybrid_generated', 'chrysler_pacifica_2017_hybrid_private_fusion'), CAR.RAM_1500: dbc_dict('chrysler_ram_dt_generated', None), + CAR.RAM_HD: dbc_dict('chrysler_ram_hd_generated', None), } diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py index 7b6355d73f7137..765be1ae310c05 100644 --- a/selfdrive/car/tests/routes.py +++ b/selfdrive/car/tests/routes.py @@ -39,6 +39,7 @@ TestRoute("8190c7275a24557b|2020-01-29--08-33-58", CHRYSLER.PACIFICA_2019_HYBRID), TestRoute("3d84727705fecd04|2021-05-25--08-38-56", CHRYSLER.PACIFICA_2020), TestRoute("221c253375af4ee9|2022-06-15--18-38-24", CHRYSLER.RAM_1500), + TestRoute("8fb5eabf914632ae|2022-08-04--17-28-53", CHRYSLER.RAM_HD, segment=6), #TestRoute("f1b4c567731f4a1b|2018-04-30--10-15-35", FORD.FUSION), diff --git a/selfdrive/car/torque_data/override.yaml b/selfdrive/car/torque_data/override.yaml index 27a8c26fd65b6b..635743c11a98bd 100644 --- a/selfdrive/car/torque_data/override.yaml +++ b/selfdrive/car/torque_data/override.yaml @@ -22,6 +22,7 @@ COMMA BODY: [.nan, 1000, .nan] # Totally new cars KIA EV6 2022: [3.5, 2.5, 0.0] RAM 1500 5TH GEN: [2.0, 2.0, 0.0] +RAM HD 5TH GEN: [1.4, 1.4, 0.0] SUBARU OUTBACK 6TH GEN: [2.3, 2.3, 0.11] # Dashcam or fallback configured as ideal car From 5d699a578cd72ebbfcfb1fc8565a567af4facbf6 Mon Sep 17 00:00:00 2001 From: Jason Young <46612682+jyoung8607@users.noreply.github.com> Date: Thu, 11 Aug 2022 18:24:23 -0400 Subject: [PATCH 003/106] Clean up timers on receipt of a non-0x78 UDS error (#25398) * clean up timers on receipt of a non-0x78 UDS error * Update selfdrive/car/isotp_parallel_query.py Co-authored-by: Shane Smiskol --- selfdrive/car/isotp_parallel_query.py | 1 + 1 file changed, 1 insertion(+) diff --git a/selfdrive/car/isotp_parallel_query.py b/selfdrive/car/isotp_parallel_query.py index bb96572c33e9a2..65122ab8971b9b 100644 --- a/selfdrive/car/isotp_parallel_query.py +++ b/selfdrive/car/isotp_parallel_query.py @@ -135,6 +135,7 @@ def get_data(self, timeout, total_timeout=60.): if self.debug: cloudlog.warning(f"iso-tp query response pending: {tx_addr}") else: + response_timeouts[tx_addr] = 0 request_done[tx_addr] = True cloudlog.warning(f"iso-tp query bad response: {tx_addr} - 0x{dat.hex()}") From 96e8d5c9fe1a8084dfa5d97c78d4ea2037272420 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 11 Aug 2022 17:23:51 -0700 Subject: [PATCH 004/106] Subaru: new harness is on the shop (#25406) * Subaru: new harness is on the shop * subaru a --- selfdrive/car/docs_definitions.py | 3 ++- selfdrive/car/subaru/values.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/selfdrive/car/docs_definitions.py b/selfdrive/car/docs_definitions.py index 46222d10040fc1..2567a5e19a5826 100644 --- a/selfdrive/car/docs_definitions.py +++ b/selfdrive/car/docs_definitions.py @@ -186,7 +186,8 @@ class Harness(Enum): bosch_a = "Honda Bosch A" bosch_b = "Honda Bosch B" toyota = "Toyota" - subaru = "Subaru" + subaru_a = "Subaru A" + subaru_b = "Subaru B" fca = "FCA" ram = "Ram" vw = "VW" diff --git a/selfdrive/car/subaru/values.py b/selfdrive/car/subaru/values.py index 9465f75edf807d..62ddaa54b5ca51 100644 --- a/selfdrive/car/subaru/values.py +++ b/selfdrive/car/subaru/values.py @@ -46,12 +46,12 @@ class CAR: @dataclass class SubaruCarInfo(CarInfo): package: str = "EyeSight Driver Assistance" - harness: Enum = Harness.subaru + harness: Enum = Harness.subaru_a CAR_INFO: Dict[str, Union[SubaruCarInfo, List[SubaruCarInfo]]] = { CAR.ASCENT: SubaruCarInfo("Subaru Ascent 2019-21", "All"), - CAR.OUTBACK: SubaruCarInfo("Subaru Outback 2020-22", "All", harness=Harness.none), + CAR.OUTBACK: SubaruCarInfo("Subaru Outback 2020-22", "All", harness=Harness.subaru_b), CAR.IMPREZA: [ SubaruCarInfo("Subaru Impreza 2017-19"), SubaruCarInfo("Subaru Crosstrek 2018-19", video_link="https://youtu.be/Agww7oE1k-s?t=26"), From 58fa5cab2cb1539d9364002c6b933e5f2f76477c Mon Sep 17 00:00:00 2001 From: John Belmonte Date: Fri, 12 Aug 2022 12:02:30 +0900 Subject: [PATCH 005/106] Car docs: J533 alternative isn't available on all cars (#25250) * Skoda unsupported connector footnote; note J533 alternative isn't available on all cars * limit footnote to Karoq * Update docs Co-authored-by: Shane Smiskol --- docs/CARS.md | 4 ++-- selfdrive/car/volkswagen/values.py | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/CARS.md b/docs/CARS.md index 7fe9441a822ac5..653e52ed94bab8 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -145,7 +145,7 @@ A supported vehicle is one that just works when you install a comma device. Ever |Subaru|XV 2018-19|EyeSight Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| |Subaru|XV 2020-21|EyeSight Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Škoda|Kamiq 2021[5](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Škoda|Karoq 2019-21|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| +|Škoda|Karoq 2019-21[7](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Škoda|Kodiaq 2018-19|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Škoda|Octavia 2015, 2018-19|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Škoda|Octavia RS 2016|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| @@ -230,7 +230,7 @@ A supported vehicle is one that just works when you install a comma device. Ever 4openpilot operates above 28mph for Camry 4CYL L, 4CYL LE and 4CYL SE which don't have Full-Speed Range Dynamic Radar Cruise Control.
5Not including the China market Kamiq, which is based on the (currently) unsupported PQ34 platform.
6Not including the USA/China market Passat, which is based on the (currently) unsupported PQ35/NMS platform.
-7Model-years 2021 and beyond may have a new camera harness design, which isn't yet available from the comma store. Before ordering, remove the Lane Assist camera cover and check to see if the connector is black (older design) or light brown (newer design). For the newer design, in the interim, choose "VW J533 Development" from the vehicle drop-down for a harness that integrates at the CAN gateway inside the dashboard.
+7Model-years 2021 and beyond may have a new camera harness design, which isn't yet available from the comma store. Before ordering, remove the Lane Assist camera cover and check to see if the connector is black (older design) or light brown (newer design). In the interim, if your car has a J533 connector CAN gateway inside the dashboard, choose "VW J533 Development" from the vehicle drop-down for a suitable harness. (Some newer models are also observed to not have a J533 connector.)
8Includes versions with extra rear cargo space (may be called Variant, Estate, SportWagen, Shooting Brake, etc.)
## Community Maintained Cars diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py index 9f58d68f81bb8b..8b2c7e93cc4d14 100755 --- a/selfdrive/car/volkswagen/values.py +++ b/selfdrive/car/volkswagen/values.py @@ -106,8 +106,9 @@ class Footnote(Enum): VW_HARNESS = CarFootnote( "Model-years 2021 and beyond may have a new camera harness design, which isn't yet available from the comma " + "store. Before ordering, remove the Lane Assist camera cover and check to see if the connector is black " + - "(older design) or light brown (newer design). For the newer design, in the interim, choose \"VW J533 Development\" " + - "from the vehicle drop-down for a harness that integrates at the CAN gateway inside the dashboard.", + "(older design) or light brown (newer design). In the interim, if your car has a J533 connector CAN gateway " + + "inside the dashboard, choose \"VW J533 Development\" from the vehicle drop-down for a suitable harness. " + + "(Some newer models are also observed to not have a J533 connector.)", Column.MODEL) VW_VARIANT = CarFootnote( "Includes versions with extra rear cargo space (may be called Variant, Estate, SportWagen, Shooting Brake, etc.)", @@ -177,7 +178,7 @@ class VWCarInfo(CarInfo): CAR.SEAT_ATECA_MK1: VWCarInfo("SEAT Ateca 2018"), CAR.SEAT_LEON_MK3: VWCarInfo("SEAT Leon 2014-20"), CAR.SKODA_KAMIQ_MK1: VWCarInfo("Škoda Kamiq 2021", footnotes=[Footnote.KAMIQ]), - CAR.SKODA_KAROQ_MK1: VWCarInfo("Škoda Karoq 2019-21"), + CAR.SKODA_KAROQ_MK1: VWCarInfo("Škoda Karoq 2019-21", footnotes=[Footnote.VW_HARNESS]), CAR.SKODA_KODIAQ_MK1: VWCarInfo("Škoda Kodiaq 2018-19"), CAR.SKODA_SCALA_MK1: VWCarInfo("Škoda Scala 2020"), CAR.SKODA_SUPERB_MK3: VWCarInfo("Škoda Superb 2015-18"), From 41daea118cd2f84556499a231091c6d03b6449ba Mon Sep 17 00:00:00 2001 From: Kento Tokuhiro Date: Fri, 12 Aug 2022 12:22:42 +0900 Subject: [PATCH 006/106] Lexus: add FW for 2020 Lexus RX Hybrid (#25346) add: fingerprint for lexus rxh h 2020 --- selfdrive/car/toyota/values.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index 9457eaf68b941d..171c0f255ad7fd 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -1823,15 +1823,18 @@ class ToyotaCarInfo(CarInfo): b'\x02348Y3000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00', b'\x0234D14000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00', b'\x0234D16000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00', + b'\x02348X4000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00', ], (Ecu.esp, 0x7b0, None): [ b'F152648831\x00\x00\x00\x00\x00\x00', b'F152648891\x00\x00\x00\x00\x00\x00', b'F152648D00\x00\x00\x00\x00\x00\x00', b'F152648D60\x00\x00\x00\x00\x00\x00', + b'F152648811\x00\x00\x00\x00\x00\x00', ], (Ecu.eps, 0x7a1, None): [ b'8965B48271\x00\x00\x00\x00\x00\x00', + b'8965B48261\x00\x00\x00\x00\x00\x00', ], (Ecu.fwdRadar, 0x750, 0xf): [ b'\x018821F3301400\x00\x00\x00\x00', From 5f35c669a686f12f5079abc6d69b17fe2e65de94 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 11 Aug 2022 22:49:49 -0700 Subject: [PATCH 007/106] Hyundai: rename HDA2 platform to CANFD (#25411) * Hyundai: rename HDA2 platform to CANFD * bump panda * bump panda * cleanup panda safety config --- cereal | 2 +- panda | 2 +- selfdrive/car/hyundai/carcontroller.py | 14 +++---- selfdrive/car/hyundai/carstate.py | 18 ++++---- .../hyundai/{hda2can.py => hyundaicanfd.py} | 0 selfdrive/car/hyundai/interface.py | 42 ++++++++++--------- selfdrive/car/hyundai/values.py | 4 +- 7 files changed, 43 insertions(+), 39 deletions(-) rename selfdrive/car/hyundai/{hda2can.py => hyundaicanfd.py} (100%) diff --git a/cereal b/cereal index fbd45de6e6bc71..5ab19700178f01 160000 --- a/cereal +++ b/cereal @@ -1 +1 @@ -Subproject commit fbd45de6e6bc71b4561eaef65dd86fce952c5d55 +Subproject commit 5ab19700178f01c14f362735532ee2662ab755fc diff --git a/panda b/panda index 486af795034853..06592b5c0e6f1a 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 486af7950348530309778240f235fd75a30f1842 +Subproject commit 06592b5c0e6f1aa83e4c8f95ecb1bf86b9277528 diff --git a/selfdrive/car/hyundai/carcontroller.py b/selfdrive/car/hyundai/carcontroller.py index 4d181e3821b012..60fb46340de664 100644 --- a/selfdrive/car/hyundai/carcontroller.py +++ b/selfdrive/car/hyundai/carcontroller.py @@ -4,8 +4,8 @@ from common.realtime import DT_CTRL from opendbc.can.packer import CANPacker from selfdrive.car import apply_std_steer_torque_limits -from selfdrive.car.hyundai import hda2can, hyundaican -from selfdrive.car.hyundai.values import Buttons, CarControllerParams, HDA2_CAR, CAR +from selfdrive.car.hyundai import hyundaicanfd, hyundaican +from selfdrive.car.hyundai.values import Buttons, CarControllerParams, CANFD_CAR, CAR VisualAlert = car.CarControl.HUDControl.VisualAlert LongCtrlState = car.CarControl.Actuators.LongControlState @@ -69,23 +69,23 @@ def update(self, CC, CS): can_sends = [] - if self.CP.carFingerprint in HDA2_CAR: + if self.CP.carFingerprint in CANFD_CAR: # steering control - can_sends.append(hda2can.create_lkas(self.packer, CC.enabled, CC.latActive, apply_steer)) + can_sends.append(hyundaicanfd.create_lkas(self.packer, CC.enabled, CC.latActive, apply_steer)) if self.frame % 5 == 0: - can_sends.append(hda2can.create_cam_0x2a4(self.packer, CS.cam_0x2a4)) + can_sends.append(hyundaicanfd.create_cam_0x2a4(self.packer, CS.cam_0x2a4)) # cruise cancel if (self.frame - self.last_button_frame) * DT_CTRL > 0.25: if CC.cruiseControl.cancel: for _ in range(20): - can_sends.append(hda2can.create_buttons(self.packer, CS.buttons_counter+1, Buttons.CANCEL)) + can_sends.append(hyundaicanfd.create_buttons(self.packer, CS.buttons_counter+1, Buttons.CANCEL)) self.last_button_frame = self.frame # cruise standstill resume elif CC.cruiseControl.resume: - can_sends.append(hda2can.create_buttons(self.packer, CS.buttons_counter+1, Buttons.RES_ACCEL)) + can_sends.append(hyundaicanfd.create_buttons(self.packer, CS.buttons_counter+1, Buttons.RES_ACCEL)) self.last_button_frame = self.frame else: diff --git a/selfdrive/car/hyundai/carstate.py b/selfdrive/car/hyundai/carstate.py index f1428555a88f52..9105f12789f067 100644 --- a/selfdrive/car/hyundai/carstate.py +++ b/selfdrive/car/hyundai/carstate.py @@ -5,7 +5,7 @@ from common.conversions import Conversions as CV from opendbc.can.parser import CANParser from opendbc.can.can_define import CANDefine -from selfdrive.car.hyundai.values import DBC, FEATURES, CAMERA_SCC_CAR, HDA2_CAR, EV_CAR, HYBRID_CAR, Buttons, CarControllerParams +from selfdrive.car.hyundai.values import DBC, FEATURES, CAMERA_SCC_CAR, CANFD_CAR, EV_CAR, HYBRID_CAR, Buttons, CarControllerParams from selfdrive.car.interfaces import CarStateBase PREV_BUTTON_SAMPLES = 8 @@ -19,7 +19,7 @@ def __init__(self, CP): self.cruise_buttons = deque([Buttons.NONE] * PREV_BUTTON_SAMPLES, maxlen=PREV_BUTTON_SAMPLES) self.main_buttons = deque([Buttons.NONE] * PREV_BUTTON_SAMPLES, maxlen=PREV_BUTTON_SAMPLES) - if CP.carFingerprint in HDA2_CAR: + if CP.carFingerprint in CANFD_CAR: self.shifter_values = can_define.dv["ACCELERATOR"]["GEAR"] elif self.CP.carFingerprint in FEATURES["use_cluster_gears"]: self.shifter_values = can_define.dv["CLU15"]["CF_Clu_Gear"] @@ -35,8 +35,8 @@ def __init__(self, CP): self.params = CarControllerParams(CP) def update(self, cp, cp_cam): - if self.CP.carFingerprint in HDA2_CAR: - return self.update_hda2(cp, cp_cam) + if self.CP.carFingerprint in CANFD_CAR: + return self.update_canfd(cp, cp_cam) ret = car.CarState.new_message() @@ -133,7 +133,7 @@ def update(self, cp, cp_cam): return ret - def update_hda2(self, cp, cp_cam): + def update_canfd(self, cp, cp_cam): ret = car.CarState.new_message() ret.gas = cp.vl["ACCELERATOR"]["ACCELERATOR_PEDAL"] / 255. @@ -183,8 +183,8 @@ def update_hda2(self, cp, cp_cam): @staticmethod def get_can_parser(CP): - if CP.carFingerprint in HDA2_CAR: - return CarState.get_can_parser_hda2(CP) + if CP.carFingerprint in CANFD_CAR: + return CarState.get_can_parser_canfd(CP) signals = [ # signal_name, signal_address @@ -318,7 +318,7 @@ def get_can_parser(CP): @staticmethod def get_cam_can_parser(CP): - if CP.carFingerprint in HDA2_CAR: + if CP.carFingerprint in CANFD_CAR: signals = [(f"BYTE{i}", "CAM_0x2a4") for i in range(3, 24)] checks = [("CAM_0x2a4", 20)] return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, 6) @@ -373,7 +373,7 @@ def get_cam_can_parser(CP): return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, 2) @staticmethod - def get_can_parser_hda2(CP): + def get_can_parser_canfd(CP): signals = [ ("WHEEL_SPEED_1", "WHEEL_SPEEDS"), ("WHEEL_SPEED_2", "WHEEL_SPEEDS"), diff --git a/selfdrive/car/hyundai/hda2can.py b/selfdrive/car/hyundai/hyundaicanfd.py similarity index 100% rename from selfdrive/car/hyundai/hda2can.py rename to selfdrive/car/hyundai/hyundaicanfd.py diff --git a/selfdrive/car/hyundai/interface.py b/selfdrive/car/hyundai/interface.py index 892f62c4279873..3fad98da15bb2b 100644 --- a/selfdrive/car/hyundai/interface.py +++ b/selfdrive/car/hyundai/interface.py @@ -2,7 +2,7 @@ from cereal import car from panda import Panda from common.conversions import Conversions as CV -from selfdrive.car.hyundai.values import CAR, DBC, CAMERA_SCC_CAR, EV_CAR, HYBRID_CAR, LEGACY_SAFETY_MODE_CAR, Buttons, CarControllerParams +from selfdrive.car.hyundai.values import CAR, DBC, CANFD_CAR, CAMERA_SCC_CAR, EV_CAR, HYBRID_CAR, LEGACY_SAFETY_MODE_CAR, Buttons, CarControllerParams from selfdrive.car.hyundai.radar_interface import RADAR_START_ADDR from selfdrive.car import STD_CARGO_KG, create_button_enable_events, create_button_event, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config from selfdrive.car.interfaces import CarInterfaceBase @@ -25,7 +25,6 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl ret = CarInterfaceBase.get_std_params(candidate, fingerprint) ret.carName = "hyundai" - ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.hyundai, 0)] ret.radarOffCan = RADAR_START_ADDR not in fingerprint[1] or DBC[ret.carFingerprint]["radar"] is None # WARNING: disabling radar also disables AEB (and we show the same warning on the instrument cluster as if you manually disabled AEB) @@ -238,8 +237,6 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl ret.mass = 2055 + STD_CARGO_KG ret.wheelbase = 2.9 ret.steerRatio = 16. - ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.noOutput), - get_safety_config(car.CarParams.SafetyModel.hyundaiHDA2)] tire_stiffness_factor = 0.65 CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) @@ -279,15 +276,28 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.16], [0.01]] - # these cars require a special panda safety mode due to missing counters and checksums in the messages - if candidate in LEGACY_SAFETY_MODE_CAR: - ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.hyundaiLegacy)] - - # set appropriate safety param for gas signal - if candidate in HYBRID_CAR: - ret.safetyConfigs[0].safetyParam = 2 - elif candidate in EV_CAR: - ret.safetyConfigs[0].safetyParam = 1 + # panda safety config + if candidate in CANFD_CAR: + ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.noOutput), + get_safety_config(car.CarParams.SafetyModel.hyundaiCanfd)] + 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)] + else: + ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.hyundai, 0)] + + # set appropriate safety param for gas signal + if candidate in HYBRID_CAR: + ret.safetyConfigs[0].safetyParam = 2 + elif candidate in EV_CAR: + ret.safetyConfigs[0].safetyParam = 1 + + if ret.openpilotLongitudinalControl: + ret.safetyConfigs[0].safetyParam |= Panda.FLAG_HYUNDAI_LONG + + if candidate in CAMERA_SCC_CAR: + ret.safetyConfigs[0].safetyParam |= Panda.FLAG_HYUNDAI_CAMERA_SCC ret.centerToFront = ret.wheelbase * 0.4 @@ -302,12 +312,6 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl ret.enableBsm = 0x58b in fingerprint[0] - if ret.openpilotLongitudinalControl: - ret.safetyConfigs[0].safetyParam |= Panda.FLAG_HYUNDAI_LONG - - if candidate in CAMERA_SCC_CAR: - ret.safetyConfigs[0].safetyParam |= Panda.FLAG_HYUNDAI_CAMERA_SCC - return ret @staticmethod diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index ec38123fa1a03b..75fc7737df2761 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -20,7 +20,7 @@ def __init__(self, CP): self.STEER_DRIVER_FACTOR = 1 self.STEER_THRESHOLD = 150 - if CP.carFingerprint in HDA2_CAR: + if CP.carFingerprint in CANFD_CAR: self.STEER_MAX = 270 self.STEER_DRIVER_ALLOWANCE = 250 self.STEER_DRIVER_MULTIPLIER = 2 @@ -1280,7 +1280,7 @@ class Buttons: "use_fca": {CAR.SONATA, CAR.SONATA_HYBRID, CAR.ELANTRA, CAR.ELANTRA_2021, CAR.ELANTRA_HEV_2021, CAR.ELANTRA_GT_I30, CAR.KIA_STINGER, CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.KONA_EV, CAR.KIA_FORTE, CAR.KIA_NIRO_EV, CAR.PALISADE, CAR.GENESIS_G70, CAR.GENESIS_G70_2020, CAR.KONA, CAR.SANTA_FE, CAR.KIA_SELTOS, CAR.KONA_HEV, CAR.SANTA_FE_2022, CAR.KIA_K5_2021, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022, CAR.TUCSON, CAR.KONA_EV_2022}, } -HDA2_CAR = {CAR.KIA_EV6, } +CANFD_CAR = {CAR.KIA_EV6, } # The camera does SCC on these cars, rather than the radar CAMERA_SCC_CAR = {CAR.KONA_EV_2022, } From 041458f632f197de3c954ed4a08650fbcb24690a Mon Sep 17 00:00:00 2001 From: HaraldSchafer Date: Fri, 12 Aug 2022 00:47:59 -0700 Subject: [PATCH 008/106] Falcon Punch Model: turn cutting improvements (#25413) * simplified change to mpc dynamics * add jerk pts * increase jerk cost * increase jerk pts multipler to master value * Add final commit * 1456d261-d232-4654-8885-4d9fde883894/440 ac1a6744-85b0-4ec6-8ba7-608d0717b8f1/750 * some copies are useful * update model replay ref * less frames in model replay onnx cpu * 1456d261-d232-4654-8885-4d9fde883894/440 264b67f5-3f52-4b58-b11f-58dd8aaf08bf/950 * 1456d261-d232-4654-8885-4d9fde883894/440 236fc556-fba3-4255-8ccf-684b22637160/950 * c9d10c64-bea4-41ec-8ca3-d8c886fda172/440 26d73dd2-862a-44ae-bbdd-32cc4f397ad7/900 * Fix couple tests * Update ref * Unused for now * Add lateral factor comment * Unused variable Co-authored-by: nuwandavek Co-authored-by: Bruce Wayne Co-authored-by: Yassine Yousfi Co-authored-by: Bruce Wayne --- .../controls/lib/lateral_mpc_lib/lat_mpc.py | 5 +++-- selfdrive/controls/lib/lateral_planner.py | 19 +++++++++++++------ selfdrive/controls/plannerd.py | 2 +- selfdrive/controls/tests/test_lateral_mpc.py | 3 ++- selfdrive/modeld/models/supercombo.dlc | 4 ++-- selfdrive/modeld/models/supercombo.onnx | 4 ++-- selfdrive/modeld/thneed/optimizer.cc | 8 ++++---- selfdrive/test/process_replay/model_replay.py | 2 +- .../process_replay/model_replay_ref_commit | 2 +- selfdrive/test/process_replay/ref_commit | 2 +- 10 files changed, 30 insertions(+), 21 deletions(-) diff --git a/selfdrive/controls/lib/lateral_mpc_lib/lat_mpc.py b/selfdrive/controls/lib/lateral_mpc_lib/lat_mpc.py index a1037f040bfaf3..c0e7358160fd0c 100755 --- a/selfdrive/controls/lib/lateral_mpc_lib/lat_mpc.py +++ b/selfdrive/controls/lib/lateral_mpc_lib/lat_mpc.py @@ -89,7 +89,7 @@ def gen_lat_ocp(): # TODO hacky weights to keep behavior the same ocp.model.cost_y_expr = vertcat(y_ego, ((v_ego +5.0) * psi_ego), - ((v_ego +5.0) * 4 * curv_rate)) + ((v_ego + 5.0) * 4.0 * curv_rate)) ocp.model.cost_y_expr_e = vertcat(y_ego, ((v_ego +5.0) * psi_ego)) @@ -147,7 +147,7 @@ def set_weights(self, path_weight, heading_weight, steer_rate_weight): #TODO hacky weights to keep behavior the same self.solver.cost_set(N, 'W', (3/20.)*W[:2,:2]) - def run(self, x0, p, y_pts, heading_pts): + def run(self, x0, p, y_pts, heading_pts, curv_rate_pts): x0_cp = np.copy(x0) p_cp = np.copy(p) self.solver.constraints_set(0, "lbx", x0_cp) @@ -156,6 +156,7 @@ def run(self, x0, p, y_pts, heading_pts): v_ego = p_cp[0] # rotation_radius = p_cp[1] self.yref[:,1] = heading_pts*(v_ego+5.0) + self.yref[:,2] = curv_rate_pts * (v_ego+5.0) * 4.0 for i in range(N): self.solver.cost_set(i, "yref", self.yref[i]) self.solver.set(i, "p", p_cp) diff --git a/selfdrive/controls/lib/lateral_planner.py b/selfdrive/controls/lib/lateral_planner.py index 019a19fb1dfe66..dda4f18a498458 100644 --- a/selfdrive/controls/lib/lateral_planner.py +++ b/selfdrive/controls/lib/lateral_planner.py @@ -3,7 +3,7 @@ from common.numpy_fast import interp from system.swaglog import cloudlog from selfdrive.controls.lib.lateral_mpc_lib.lat_mpc import LateralMpc -from selfdrive.controls.lib.drive_helpers import CONTROL_N, MPC_COST_LAT, LAT_MPC_N, CAR_ROTATION_RADIUS +from selfdrive.controls.lib.drive_helpers import CONTROL_N, MPC_COST_LAT, LAT_MPC_N from selfdrive.controls.lib.lane_planner import LanePlanner, TRAJECTORY_SIZE from selfdrive.controls.lib.desire_helper import DesireHelper import cereal.messaging as messaging @@ -11,17 +11,21 @@ class LateralPlanner: - def __init__(self, use_lanelines=True, wide_camera=False): + def __init__(self, CP, use_lanelines=True, wide_camera=False): self.use_lanelines = use_lanelines self.LP = LanePlanner(wide_camera) self.DH = DesireHelper() + # Vehicle model parameters used to calculate lateral movement of car + self.factor1 = CP.wheelbase - CP.centerToFront + self.factor2 = (CP.centerToFront * CP.mass) / (CP.wheelbase * CP.tireStiffnessRear) self.last_cloudlog_t = 0 self.solution_invalid_cnt = 0 self.path_xyz = np.zeros((TRAJECTORY_SIZE, 3)) self.path_xyz_stds = np.ones((TRAJECTORY_SIZE, 3)) self.plan_yaw = np.zeros((TRAJECTORY_SIZE,)) + self.plan_curv_rate = np.zeros((TRAJECTORY_SIZE,)) self.t_idxs = np.arange(TRAJECTORY_SIZE) self.y_pts = np.zeros(TRAJECTORY_SIZE) @@ -42,7 +46,7 @@ def update(self, sm): if len(md.position.x) == TRAJECTORY_SIZE and len(md.orientation.x) == TRAJECTORY_SIZE: self.path_xyz = np.column_stack([md.position.x, md.position.y, md.position.z]) self.t_idxs = np.array(md.position.t) - self.plan_yaw = list(md.orientation.z) + self.plan_yaw = np.array(md.orientation.z) if len(md.position.xStd) == TRAJECTORY_SIZE: self.path_xyz_stds = np.column_stack([md.position.xStd, md.position.yStd, md.position.zStd]) @@ -67,16 +71,19 @@ def update(self, sm): y_pts = np.interp(v_ego * self.t_idxs[:LAT_MPC_N + 1], np.linalg.norm(d_path_xyz, axis=1), d_path_xyz[:, 1]) heading_pts = np.interp(v_ego * self.t_idxs[:LAT_MPC_N + 1], np.linalg.norm(self.path_xyz, axis=1), self.plan_yaw) + curv_rate_pts = np.interp(v_ego * self.t_idxs[:LAT_MPC_N + 1], np.linalg.norm(self.path_xyz, axis=1), self.plan_curv_rate) self.y_pts = y_pts assert len(y_pts) == LAT_MPC_N + 1 assert len(heading_pts) == LAT_MPC_N + 1 - # self.x0[4] = v_ego - p = np.array([v_ego, CAR_ROTATION_RADIUS]) + assert len(curv_rate_pts) == LAT_MPC_N + 1 + lateral_factor = max(0, self.factor1 - (self.factor2 * v_ego**2)) + p = np.array([v_ego, lateral_factor]) self.lat_mpc.run(self.x0, p, y_pts, - heading_pts) + heading_pts, + curv_rate_pts) # init state for next # mpc.u_sol is the desired curvature rate given x0 curv state. # with x0[3] = measured_curvature, this would be the actual desired rate. diff --git a/selfdrive/controls/plannerd.py b/selfdrive/controls/plannerd.py index 9356a55d8433f8..06807b2a5cb84c 100755 --- a/selfdrive/controls/plannerd.py +++ b/selfdrive/controls/plannerd.py @@ -22,7 +22,7 @@ def plannerd_thread(sm=None, pm=None): cloudlog.event("e2e mode", on=use_lanelines) longitudinal_planner = Planner(CP) - lateral_planner = LateralPlanner(use_lanelines=use_lanelines, wide_camera=wide_camera) + lateral_planner = LateralPlanner(CP, use_lanelines=use_lanelines, wide_camera=wide_camera) if sm is None: sm = messaging.SubMaster(['carState', 'controlsState', 'radarState', 'modelV2'], diff --git a/selfdrive/controls/tests/test_lateral_mpc.py b/selfdrive/controls/tests/test_lateral_mpc.py index 4630e28a6154f5..4864dbdc068328 100644 --- a/selfdrive/controls/tests/test_lateral_mpc.py +++ b/selfdrive/controls/tests/test_lateral_mpc.py @@ -13,6 +13,7 @@ def run_mpc(lat_mpc=None, v_ref=30., x_init=0., y_init=0., psi_init=0., curvatur y_pts = poly_shift * np.ones(LAT_MPC_N + 1) heading_pts = np.zeros(LAT_MPC_N + 1) + curv_rate_pts = np.zeros(LAT_MPC_N + 1) x0 = np.array([x_init, y_init, psi_init, curvature_init]) p = np.array([v_ref, CAR_ROTATION_RADIUS]) @@ -20,7 +21,7 @@ def run_mpc(lat_mpc=None, v_ref=30., x_init=0., y_init=0., psi_init=0., curvatur # converge in no more than 10 iterations for _ in range(10): lat_mpc.run(x0, p, - y_pts, heading_pts) + y_pts, heading_pts, curv_rate_pts) return lat_mpc.x_sol diff --git a/selfdrive/modeld/models/supercombo.dlc b/selfdrive/modeld/models/supercombo.dlc index 23f6d904fb238b..fe3ad510211f29 100644 --- a/selfdrive/modeld/models/supercombo.dlc +++ b/selfdrive/modeld/models/supercombo.dlc @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:027cbb1fabae369878271cb0e3505071a8bdaa07473fad9a0b2e8d695c5dc1ff -size 76725611 +oid sha256:3c5c8d71a8a1434ef79073362e608b9fe02f22ce7478f11bc71c6806c1e00091 +size 94302331 diff --git a/selfdrive/modeld/models/supercombo.onnx b/selfdrive/modeld/models/supercombo.onnx index 9023c18dd7f970..39e8743642aef7 100644 --- a/selfdrive/modeld/models/supercombo.onnx +++ b/selfdrive/modeld/models/supercombo.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:484976ea5bd4ddcabc82e95faf30d7311a27802c1e337472558699fa2395a499 -size 77472267 +oid sha256:15d9eb01edd98998abceaa092d33fab149ff4a8942646b20a7c1403f999f4eca +size 95165081 diff --git a/selfdrive/modeld/thneed/optimizer.cc b/selfdrive/modeld/thneed/optimizer.cc index 03d20ff3861332..39737d3d7623ba 100644 --- a/selfdrive/modeld/thneed/optimizer.cc +++ b/selfdrive/modeld/thneed/optimizer.cc @@ -9,7 +9,7 @@ extern map g_program_source; -static int is_same_size_image(cl_mem a, cl_mem b) { +/*static int is_same_size_image(cl_mem a, cl_mem b) { size_t a_width, a_height, a_depth, a_array_size, a_row_pitch, a_slice_pitch; clGetImageInfo(a, CL_IMAGE_WIDTH, sizeof(a_width), &a_width, NULL); clGetImageInfo(a, CL_IMAGE_HEIGHT, sizeof(a_height), &a_height, NULL); @@ -29,7 +29,7 @@ static int is_same_size_image(cl_mem a, cl_mem b) { return (a_width == b_width) && (a_height == b_height) && (a_depth == b_depth) && (a_array_size == b_array_size) && (a_row_pitch == b_row_pitch) && (a_slice_pitch == b_slice_pitch); -} +}*/ static cl_mem make_image_like(cl_context context, cl_mem val) { cl_image_format format; @@ -138,7 +138,7 @@ int Thneed::optimize() { // delete useless copy layers // saves ~0.7 ms - if (kq[i]->name == "concatenation" || kq[i]->name == "flatten") { + /*if (kq[i]->name == "concatenation" || kq[i]->name == "flatten") { string in = kq[i]->args[kq[i]->get_arg_num("input")]; string out = kq[i]->args[kq[i]->get_arg_num("output")]; if (is_same_size_image(*(cl_mem*)in.data(), *(cl_mem*)out.data())) { @@ -148,7 +148,7 @@ int Thneed::optimize() { kq.erase(kq.begin()+i); --i; } - } + }*/ // NOTE: if activations/accumulation are done in the wrong order, this will be wrong diff --git a/selfdrive/test/process_replay/model_replay.py b/selfdrive/test/process_replay/model_replay.py index 8b41d6df1b66ba..12f3583ee44c00 100755 --- a/selfdrive/test/process_replay/model_replay.py +++ b/selfdrive/test/process_replay/model_replay.py @@ -22,7 +22,7 @@ TEST_ROUTE = "4cf7a6ad03080c90|2021-09-29--13-46-36" SEGMENT = 0 -MAX_FRAMES = 20 if PC else 1300 +MAX_FRAMES = 10 if PC else 1300 SEND_EXTRA_INPUTS = bool(os.getenv("SEND_EXTRA_INPUTS", "0")) diff --git a/selfdrive/test/process_replay/model_replay_ref_commit b/selfdrive/test/process_replay/model_replay_ref_commit index 8b9483419308ca..e5bbfa74c25098 100644 --- a/selfdrive/test/process_replay/model_replay_ref_commit +++ b/selfdrive/test/process_replay/model_replay_ref_commit @@ -1 +1 @@ -5c2cb8fb9787584a1eb553968cb87e7e6782dac5 +507241e0a41ee757cca4eb6ff12cff3f02c0b98a diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 27bea557408bef..8c8f5d10fecc71 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -c556add24a92c9d8593d9d3ebbeed9434b751d66 \ No newline at end of file +461333164e531e3ffdac05b63b529aa5dce1186f From 4dbad71171df6ffbe54de2d16409abb707b23d09 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 12 Aug 2022 01:58:49 -0700 Subject: [PATCH 009/106] Car docs: update Odyssey supported model years (#25410) * Revert Odyssey MY * update docs --- docs/CARS.md | 2 +- selfdrive/car/honda/values.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/CARS.md b/docs/CARS.md index 653e52ed94bab8..37ea5599b80bda 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -61,7 +61,7 @@ A supported vehicle is one that just works when you install a comma device. Ever |Honda|HR-V 2019-22|Honda Sensing|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| |Honda|Insight 2019-22|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| |Honda|Inspire 2018|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| -|Honda|Odyssey 2018-22|Honda Sensing|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| +|Honda|Odyssey 2018-20|Honda Sensing|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| |Honda|Passport 2019-21|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| |Honda|Pilot 2016-22|Honda Sensing|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| |Honda|Ridgeline 2017-22|Honda Sensing|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| diff --git a/selfdrive/car/honda/values.py b/selfdrive/car/honda/values.py index 88e118cc3d5a1d..ab1cc9a6cc0e51 100644 --- a/selfdrive/car/honda/values.py +++ b/selfdrive/car/honda/values.py @@ -131,7 +131,7 @@ class HondaCarInfo(CarInfo): CAR.FIT: HondaCarInfo("Honda Fit 2018-20", harness=Harness.nidec), CAR.FREED: HondaCarInfo("Honda Freed 2020", harness=Harness.nidec), CAR.HRV: HondaCarInfo("Honda HR-V 2019-22", harness=Harness.nidec), - CAR.ODYSSEY: HondaCarInfo("Honda Odyssey 2018-22", min_steer_speed=0., harness=Harness.nidec), + CAR.ODYSSEY: HondaCarInfo("Honda Odyssey 2018-20", min_steer_speed=0., harness=Harness.nidec), CAR.ODYSSEY_CHN: None, # Chinese version of Odyssey CAR.ACURA_RDX: HondaCarInfo("Acura RDX 2016-18", "AcuraWatch Plus", harness=Harness.nidec), CAR.ACURA_RDX_3G: HondaCarInfo("Acura RDX 2019-22", "All", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch_a), From 24645c92dadebaf69e1115d0ccd44edba4148b65 Mon Sep 17 00:00:00 2001 From: Robbe Derks Date: Fri, 12 Aug 2022 11:30:19 +0200 Subject: [PATCH 010/106] Use steeringAngleDeg for angle control saturation warnings (#25404) * use steeringAngleDeg for angle control cars * update refs --- selfdrive/controls/controlsd.py | 9 +++++++-- selfdrive/test/process_replay/ref_commit | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 2f7c85aa7d3324..3b2307f04ad6f6 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -626,8 +626,13 @@ def state_control(self, CS): if len(dpath_points): # Check if we deviated from the path # TODO use desired vs actual curvature - left_deviation = actuators.steer > 0 and dpath_points[0] < -0.20 - right_deviation = actuators.steer < 0 and dpath_points[0] > 0.20 + if self.CP.steerControlType == car.CarParams.SteerControlType.angle: + steering_value = actuators.steeringAngleDeg + else: + steering_value = actuators.steer + + left_deviation = steering_value > 0 and dpath_points[0] < -0.20 + right_deviation = steering_value < 0 and dpath_points[0] > 0.20 if left_deviation or right_deviation: self.events.add(EventName.steerSaturated) diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 8c8f5d10fecc71..260e917fb1f40a 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -461333164e531e3ffdac05b63b529aa5dce1186f +3c89454df9cf2f25a5759d523a8c595e69865505 \ No newline at end of file From e68631f472027839a04e0ca23b33ed87db17b5a0 Mon Sep 17 00:00:00 2001 From: Robbe Derks Date: Fri, 12 Aug 2022 13:51:04 +0200 Subject: [PATCH 011/106] Bump panda (#25416) bump panda --- panda | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda b/panda index 06592b5c0e6f1a..508ee90f8ecf1c 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 06592b5c0e6f1aa83e4c8f95ecb1bf86b9277528 +Subproject commit 508ee90f8ecf1ce70fc9d002bbc14b47a50a459a From 6e2584ef4b1016a4faf5b66b271acb1c29c2e753 Mon Sep 17 00:00:00 2001 From: Jason Wen <47793918+sunnyhaibin@users.noreply.github.com> Date: Fri, 12 Aug 2022 14:50:52 -0400 Subject: [PATCH 012/106] Hyundai: Car Port for Ioniq 5 (HDA2) 2022 (#25308) * Hyundai: Car Port for Ioniq 5 2022 * Add FW versions * HDA2 and modified harness for now Co-authored-by: Adeeb Shihadeh * Attempt to block LFA * BYTE7 blocks LFA * Merge and bump opendbc, panda * Update docs per request * HDA2 -> Highway Driving Assist II Co-authored-by: Shane Smiskol * Update RELEASES * remove that * generate docs * ev6 matches * fix panda bus Co-authored-by: Adeeb Shihadeh Co-authored-by: Shane Smiskol --- RELEASES.md | 1 + docs/CARS.md | 5 +++-- selfdrive/car/hyundai/interface.py | 6 ++++++ selfdrive/car/hyundai/values.py | 24 +++++++++++++++++++++-- selfdrive/car/tests/routes.py | 1 + selfdrive/car/tests/test_models.py | 2 ++ selfdrive/car/torque_data/substitute.yaml | 1 + 7 files changed, 36 insertions(+), 4 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index e69d7461b7bb14..dd18b4b775a68d 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,5 +1,6 @@ Version 0.8.16 (2022-XX-XX) ======================== +* Hyundai Ioniq 5 2022 support thanks to sunnyhaibin! * Hyundai Kona Electric 2022 support thanks to sunnyhaibin! * Subaru Outback 2020-22 support diff --git a/docs/CARS.md b/docs/CARS.md index 37ea5599b80bda..162d5e66f6b3e0 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -19,7 +19,7 @@ A supported vehicle is one that just works when you install a comma device. Ever - [![star](assets/icon-star-empty.svg)](##) - Limited ability to make tighter turns. -# 199 Supported Cars +# 200 Supported Cars |Make|Model|Supported Package|openpilot ACC|Stop and Go|Steer to 0|Steering Torque| |---|---|---|:---:|:---:|:---:|:---:| @@ -69,6 +69,7 @@ A supported vehicle is one that just works when you install a comma device. Ever |Hyundai|Elantra 2021-22|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Hyundai|Elantra Hybrid 2021-22|Smart Cruise Control (SCC)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Hyundai|Genesis 2015-16|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| +|Hyundai|Ioniq 5 2022|Highway Driving Assist II|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Hyundai|Ioniq Electric 2019|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Hyundai|Ioniq Electric 2020|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Hyundai|Ioniq Hybrid 2017-19|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| @@ -93,7 +94,7 @@ A supported vehicle is one that just works when you install a comma device. Ever |Jeep|Grand Cherokee 2016-18|Adaptive Cruise Control|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Jeep|Grand Cherokee 2019-21|Adaptive Cruise Control|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Kia|Ceed 2019|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Kia|EV6 2022|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| +|Kia|EV6 2022|Highway Driving Assist II|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Kia|Forte 2018|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Kia|Forte 2019-21|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Kia|K5 2021-22|Smart Cruise Control (SCC)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| diff --git a/selfdrive/car/hyundai/interface.py b/selfdrive/car/hyundai/interface.py index 3fad98da15bb2b..d3dc1a2c6e6d3c 100644 --- a/selfdrive/car/hyundai/interface.py +++ b/selfdrive/car/hyundai/interface.py @@ -239,6 +239,12 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl ret.steerRatio = 16. tire_stiffness_factor = 0.65 CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) + elif candidate == CAR.IONIQ_5: + ret.mass = 2012 + STD_CARGO_KG + ret.wheelbase = 3.0 + ret.steerRatio = 16. + tire_stiffness_factor = 0.65 + CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) # Genesis elif candidate == CAR.GENESIS_G70: diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index 75fc7737df2761..8879931b20070a 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -65,6 +65,7 @@ class CAR: PALISADE = "HYUNDAI PALISADE 2020" VELOSTER = "HYUNDAI VELOSTER 2019" SONATA_HYBRID = "HYUNDAI SONATA HYBRID 2021" + IONIQ_5 = "HYUNDAI IONIQ 5 2022" # Kia KIA_FORTE = "KIA FORTE E 2018 & GT 2021" @@ -126,6 +127,7 @@ class HyundaiCarInfo(CarInfo): ], CAR.VELOSTER: HyundaiCarInfo("Hyundai Veloster 2019-20", "Smart Cruise Control (SCC)", min_enable_speed=5. * CV.MPH_TO_MS, harness=Harness.hyundai_e), CAR.SONATA_HYBRID: HyundaiCarInfo("Hyundai Sonata Hybrid 2020-22", "All", harness=Harness.hyundai_a), + CAR.IONIQ_5: HyundaiCarInfo("Hyundai Ioniq 5 2022", "Highway Driving Assist II", harness=Harness.none), # Kia CAR.KIA_FORTE: [ @@ -156,7 +158,7 @@ class HyundaiCarInfo(CarInfo): ], CAR.KIA_STINGER: HyundaiCarInfo("Kia Stinger 2018-20", video_link="https://www.youtube.com/watch?v=MJ94qoofYw0", harness=Harness.hyundai_c), CAR.KIA_CEED: HyundaiCarInfo("Kia Ceed 2019", harness=Harness.hyundai_e), - CAR.KIA_EV6: HyundaiCarInfo("Kia EV6 2022", "All", harness=Harness.hyundai_p), + CAR.KIA_EV6: HyundaiCarInfo("Kia EV6 2022", "Highway Driving Assist II", harness=Harness.hyundai_p), # Genesis CAR.GENESIS_G70: HyundaiCarInfo("Genesis G70 2018-19", "All", harness=Harness.hyundai_f), @@ -1263,6 +1265,23 @@ class Buttons: b'\xf1\x00CV1 MFC AT USA LHD 1.00 1.05 99210-CV000 211027', ], }, + CAR.IONIQ_5: { + (Ecu.esp, 0x7d1, None): [ + b'\xf1\x00NE1 IEB \x07 106!\x11) 58520-GI010', + b'\xf1\x8758520GI010\xf1\x00NE1 IEB \x07 106!\x11) 58520-GI010', + ], + (Ecu.eps, 0x7d4, None): [ + b'\xf1\x00NE MDPS R 1.00 1.06 57700GI000 4NEDR106', + b'\xf1\x8757700GI000 \xf1\x00NE MDPS R 1.00 1.06 57700GI000 4NEDR106', + ], + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00NE1_ RDR ----- 1.00 1.00 99110-GI000 ', + b'\xf1\x8799110GI000\xf1\x00NE1_ RDR ----- 1.00 1.00 99110-GI000 ', + ], + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00NE1 MFC AT USA LHD 1.00 1.02 99211-GI010 211206', + ], + }, } CHECKSUM = { @@ -1280,7 +1299,7 @@ class Buttons: "use_fca": {CAR.SONATA, CAR.SONATA_HYBRID, CAR.ELANTRA, CAR.ELANTRA_2021, CAR.ELANTRA_HEV_2021, CAR.ELANTRA_GT_I30, CAR.KIA_STINGER, CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.KONA_EV, CAR.KIA_FORTE, CAR.KIA_NIRO_EV, CAR.PALISADE, CAR.GENESIS_G70, CAR.GENESIS_G70_2020, CAR.KONA, CAR.SANTA_FE, CAR.KIA_SELTOS, CAR.KONA_HEV, CAR.SANTA_FE_2022, CAR.KIA_K5_2021, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022, CAR.TUCSON, CAR.KONA_EV_2022}, } -CANFD_CAR = {CAR.KIA_EV6, } +CANFD_CAR = {CAR.KIA_EV6, CAR.IONIQ_5} # The camera does SCC on these cars, rather than the radar CAMERA_SCC_CAR = {CAR.KONA_EV_2022, } @@ -1335,4 +1354,5 @@ class Buttons: CAR.KIA_CEED: dbc_dict('hyundai_kia_generic', None), CAR.KIA_EV6: dbc_dict('kia_ev6', None), CAR.SONATA_HYBRID: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar'), + CAR.IONIQ_5: dbc_dict('kia_ev6', None), } diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py index 765be1ae310c05..2195befb221d73 100644 --- a/selfdrive/car/tests/routes.py +++ b/selfdrive/car/tests/routes.py @@ -90,6 +90,7 @@ TestRoute("fb3fd42f0baaa2f8|2022-03-30--15-25-05", HYUNDAI.TUCSON), TestRoute("5875672fc1d4bf57|2020-07-23--21-33-28", HYUNDAI.KIA_SORENTO), TestRoute("9c917ba0d42ffe78|2020-04-17--12-43-19", HYUNDAI.PALISADE), + TestRoute("22de8111a8c5463c|2022-07-29--13-34-49", HYUNDAI.IONIQ_5), TestRoute("3f29334d6134fcd4|2022-03-30--22-00-50", HYUNDAI.IONIQ_PHEV_2019), TestRoute("fa8db5869167f821|2021-06-10--22-50-10", HYUNDAI.IONIQ_PHEV), TestRoute("2c5cf2dd6102e5da|2020-12-17--16-06-44", HYUNDAI.IONIQ_EV_2020), diff --git a/selfdrive/car/tests/test_models.py b/selfdrive/car/tests/test_models.py index 929c539842bca1..8906942f26731b 100755 --- a/selfdrive/car/tests/test_models.py +++ b/selfdrive/car/tests/test_models.py @@ -219,6 +219,8 @@ def test_panda_safety_carstate(self): for can in self.can_msgs: CS = self.CI.update(CC, (can.as_builder().to_bytes(), )) for msg in can_capnp_to_can_list(can.can, src_filter=range(64)): + msg = list(msg) + msg[3] %= 4 to_send = package_can_msg(msg) ret = self.safety.safety_rx_hook(to_send) self.assertEqual(1, ret, f"safety rx failed ({ret=}): {to_send}") diff --git a/selfdrive/car/torque_data/substitute.yaml b/selfdrive/car/torque_data/substitute.yaml index f7288ec731cf46..279e28ff5d4d92 100644 --- a/selfdrive/car/torque_data/substitute.yaml +++ b/selfdrive/car/torque_data/substitute.yaml @@ -29,6 +29,7 @@ HYUNDAI I30 N LINE 2019 & GT 2018 DCT: HYUNDAI SONATA 2019 HYUNDAI KONA 2020: HYUNDAI KONA ELECTRIC 2019 HYUNDAI KONA HYBRID 2020: HYUNDAI KONA ELECTRIC 2019 HYUNDAI KONA ELECTRIC 2022: HYUNDAI KONA ELECTRIC 2019 +HYUNDAI IONIQ 5 2022: KIA EV6 2022 HYUNDAI IONIQ HYBRID 2017-2019: HYUNDAI IONIQ PLUG-IN HYBRID 2019 HYUNDAI IONIQ HYBRID 2020-2022: HYUNDAI IONIQ PLUG-IN HYBRID 2019 HYUNDAI IONIQ ELECTRIC 2020: HYUNDAI IONIQ PLUG-IN HYBRID 2019 From e4340e02606fccf66600119195ee704a78bc26cf Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 12 Aug 2022 12:31:55 -0700 Subject: [PATCH 013/106] Car docs: update RX supported model years (#25419) Update RX supported model years --- docs/CARS.md | 2 +- selfdrive/car/toyota/values.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/CARS.md b/docs/CARS.md index 162d5e66f6b3e0..00022bfb8bd670 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -122,7 +122,7 @@ A supported vehicle is one that just works when you install a comma device. Ever |Lexus|NX Hybrid 2018-19|All|[![star](assets/icon-star-half.svg)](##)[3](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Lexus|NX Hybrid 2020-21|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Lexus|RC 2017-20|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Lexus|RX 2016-18|All|[![star](assets/icon-star-half.svg)](##)[3](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| +|Lexus|RX 2016-19|All|[![star](assets/icon-star-half.svg)](##)[3](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Lexus|RX 2020-22|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Lexus|RX Hybrid 2016-19|All|[![star](assets/icon-star-half.svg)](##)[3](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Lexus|RX Hybrid 2020-21|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index 171c0f255ad7fd..b6181c1fd0b7a1 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -170,7 +170,7 @@ class ToyotaCarInfo(CarInfo): CAR.LEXUS_NX_TSS2: ToyotaCarInfo("Lexus NX 2020-21"), CAR.LEXUS_NXH_TSS2: ToyotaCarInfo("Lexus NX Hybrid 2020-21"), CAR.LEXUS_RC: ToyotaCarInfo("Lexus RC 2017-20"), - CAR.LEXUS_RX: ToyotaCarInfo("Lexus RX 2016-18", footnotes=[Footnote.DSU]), + CAR.LEXUS_RX: ToyotaCarInfo("Lexus RX 2016-19", footnotes=[Footnote.DSU]), CAR.LEXUS_RXH: ToyotaCarInfo("Lexus RX Hybrid 2016-19", footnotes=[Footnote.DSU]), CAR.LEXUS_RX_TSS2: ToyotaCarInfo("Lexus RX 2020-22"), CAR.LEXUS_RXH_TSS2: ToyotaCarInfo("Lexus RX Hybrid 2020-21"), From 4ffe9e68db8d752d9da45febccfe4c28a6e8a0f9 Mon Sep 17 00:00:00 2001 From: Jason Shuler Date: Fri, 12 Aug 2022 19:10:34 -0400 Subject: [PATCH 014/106] GM: Bolt EUV 2022-23 port (#24875) * Switch to ECMPRDNL2 for GM gear * Removing manumatic gear # * values.py almost complete * Silverado and Bolt EUV val and CP * GM controller updated * Cam hrns supp done (in theory) * cleanup for new cars * Remove extra constant * WS, etc cleanup * removing the unused * Fix kpBP typo * Updated docs * Skip's PIF tune * Dropped LKA CAN error patch * Add silverado sigmoid ff * CAN Err & LKA latch patch * Remove EPS fault fix (another PR) * Remove Silverado (another PR) * clean up some common params * Remove Escalade FP Remove Escalade FP * comment * Premier is just a trim Premier is just a trim Premier is just a trim * no footnote: new Bolt is like most other cars, older GM were outliers not at the camera * clean up clean up * bump panda * bump panda * bump panda * bump panda * bump panda * remove comments * try spamming buttons on bus 2 * bump panda * bumping opendbc w btn rc * not needed for this port This reverts commit 6af1f0ba799e075f877d7acc8ca0f117d97da361. * add button safety * Send next rc when spamming btns * forward other signals in message * missing DriveModeButton * fill cruiseState.speed * see if resume works without counter * try the whole message * send immediately and at 10Hz * no resume, back to just button signal * even holding random buttons it cancels * Use torque controller with base tune * stock long GM don't auto-resume yet * Testing GM zero min steer speed * Revert latcontrol * revert opendbc * latActive is basically lkas_enabled * Update Bolt torque params * comment * clean up * Add to releases * Add test route * Don't specify segment * bump panda * bump panda * no harness for Bolt just yet * Apply suggestions from code review Co-authored-by: Adeeb Shihadeh * We support all and 2023 * move safetyParam up to first cam check * Bump panda and update docs * Update RELEASES.md Co-authored-by: Adeeb Shihadeh Co-authored-by: Shane Smiskol Co-authored-by: Adeeb Shihadeh --- RELEASES.md | 1 + docs/CARS.md | 3 +- panda | 2 +- selfdrive/car/docs_definitions.py | 9 +++-- selfdrive/car/gm/carcontroller.py | 17 +++++++--- selfdrive/car/gm/carstate.py | 16 ++++++++- selfdrive/car/gm/gmcan.py | 4 +++ selfdrive/car/gm/interface.py | 45 +++++++++++++++++-------- selfdrive/car/gm/values.py | 19 ++++++++--- selfdrive/car/tests/routes.py | 1 + selfdrive/car/tests/test_models.py | 1 - selfdrive/car/torque_data/override.yaml | 1 + 12 files changed, 90 insertions(+), 29 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index dd18b4b775a68d..bcd6aa7aa1b5fb 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,5 +1,6 @@ Version 0.8.16 (2022-XX-XX) ======================== +* Chevrolet Bolt EUV 2022-23 support thanks to JasonJShuler! * Hyundai Ioniq 5 2022 support thanks to sunnyhaibin! * Hyundai Kona Electric 2022 support thanks to sunnyhaibin! * Subaru Outback 2020-22 support diff --git a/docs/CARS.md b/docs/CARS.md index 00022bfb8bd670..c3278d7066816f 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -19,7 +19,7 @@ A supported vehicle is one that just works when you install a comma device. Ever - [![star](assets/icon-star-empty.svg)](##) - Limited ability to make tighter turns. -# 200 Supported Cars +# 201 Supported Cars |Make|Model|Supported Package|openpilot ACC|Stop and Go|Steer to 0|Steering Torque| |---|---|---|:---:|:---:|:---:|:---:| @@ -33,6 +33,7 @@ A supported vehicle is one that just works when you install a comma device. Ever |Audi|RS3 2018|ACC + Lane Assist|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Audi|S3 2015-17|ACC + Lane Assist|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Cadillac|Escalade ESV 2016[1](#footnotes)|Adaptive Cruise Control (ACC) & LKAS|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| +|Chevrolet|Bolt EUV 2022-23|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Chevrolet|Volt 2017-18[1](#footnotes)|Adaptive Cruise Control|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Chrysler|Pacifica 2017-18|Adaptive Cruise Control|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Chrysler|Pacifica 2019-20|Adaptive Cruise Control|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| diff --git a/panda b/panda index 508ee90f8ecf1c..5e0dde7b480a93 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 508ee90f8ecf1ce70fc9d002bbc14b47a50a459a +Subproject commit 5e0dde7b480a930d3c3a164331c930541e905d71 diff --git a/selfdrive/car/docs_definitions.py b/selfdrive/car/docs_definitions.py index 2567a5e19a5826..0605ec1f2aff03 100644 --- a/selfdrive/car/docs_definitions.py +++ b/selfdrive/car/docs_definitions.py @@ -10,6 +10,10 @@ GOOD_TORQUE_THRESHOLD = 1.0 # m/s^2 MODEL_YEARS_RE = r"(?<= )((\d{4}-\d{2})|(\d{4}))(,|$)" +# Makes that lack auto-resume with stock long, and auto resume in any configuration +NO_AUTO_RESUME_STOCK_LONG = {"toyota", "gm"} +NO_AUTO_RESUME = NO_AUTO_RESUME_STOCK_LONG | {"nissan", "subaru"} + class Tier(Enum): GOLD = 0 @@ -147,11 +151,11 @@ def get_detail_sentence(self, CP): else: alc = "" - # Exception for Nissan, Subaru, and stock long Toyota which do not auto-resume yet + # Exception for cars which do not auto-resume yet acc = "" if self.min_enable_speed > 0: acc = f" while driving above {self.min_enable_speed * CV.MS_TO_MPH:.0f} mph" - elif CP.carName not in ("nissan", "subaru", "toyota") or (CP.carName == "toyota" and CP.openpilotLongitudinalControl): + elif CP.carName not in NO_AUTO_RESUME or (CP.carName in NO_AUTO_RESUME_STOCK_LONG and CP.openpilotLongitudinalControl): acc = " that automatically resumes from a stop" if self.row[Column.STEERING_TORQUE] != Star.FULL: @@ -210,6 +214,7 @@ class Harness(Enum): hyundai_p = "Hyundai P" custom = "Developer" obd_ii = "OBD-II" + gm = "GM" nissan_a = "Nissan A" nissan_b = "Nissan B" mazda = "Mazda" diff --git a/selfdrive/car/gm/carcontroller.py b/selfdrive/car/gm/carcontroller.py index 0e7406514315fe..10e6027973e60e 100644 --- a/selfdrive/car/gm/carcontroller.py +++ b/selfdrive/car/gm/carcontroller.py @@ -5,7 +5,7 @@ from opendbc.can.packer import CANPacker from selfdrive.car import apply_std_steer_torque_limits from selfdrive.car.gm import gmcan -from selfdrive.car.gm.values import DBC, CanBus, CarControllerParams, EV_CAR +from selfdrive.car.gm.values import DBC, CanBus, CarControllerParams, CruiseButtons, EV_CAR VisualAlert = car.CarControl.HUDControl.VisualAlert NetworkLocation = car.CarParams.NetworkLocation @@ -19,6 +19,7 @@ def __init__(self, dbc_name, CP, VM): self.apply_gas = 0 self.apply_brake = 0 self.frame = 0 + self.last_button_frame = 0 self.lka_steering_cmd_counter_last = -1 self.lka_icon_status_last = (False, False) @@ -46,8 +47,7 @@ def update(self, CC, CS): if CS.lka_steering_cmd_counter != self.lka_steering_cmd_counter_last: self.lka_steering_cmd_counter_last = CS.lka_steering_cmd_counter elif (self.frame % self.params.STEER_STEP) == 0: - lkas_enabled = CC.latActive and CS.out.vEgo > self.params.MIN_STEER_SPEED - if lkas_enabled: + if CC.latActive: new_steer = int(round(actuators.steer * self.params.STEER_MAX)) apply_steer = apply_std_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.params) else: @@ -58,7 +58,7 @@ def update(self, CC, CS): # moment of disengaging, increment the counter based on the last message known to pass Panda safety checks. idx = (CS.lka_steering_cmd_counter + 1) % 4 - can_sends.append(gmcan.create_steering_control(self.packer_pt, CanBus.POWERTRAIN, apply_steer, idx, lkas_enabled)) + can_sends.append(gmcan.create_steering_control(self.packer_pt, CanBus.POWERTRAIN, apply_steer, idx, CC.latActive)) if self.CP.openpilotLongitudinalControl: # Gas/regen, brakes, and UI commands - all at 25Hz @@ -107,6 +107,13 @@ def update(self, CC, CS): if self.CP.networkLocation == NetworkLocation.gateway and self.frame % self.params.ADAS_KEEPALIVE_STEP == 0: can_sends += gmcan.create_adas_keepalive(CanBus.POWERTRAIN) + else: + # Stock longitudinal, integrated at camera + if (self.frame - self.last_button_frame) * DT_CTRL > 0.1: + if CC.cruiseControl.cancel: + self.last_button_frame = self.frame + can_sends.append(gmcan.create_buttons(self.packer_pt, CanBus.CAMERA, CruiseButtons.CANCEL)) + # Show green icon when LKA torque is applied, and # alarming orange icon when approaching torque limit. # If not sent again, LKA icon disappears in about 5 seconds. @@ -114,6 +121,8 @@ def update(self, CC, CS): lka_active = CS.lkas_status == 1 lka_critical = lka_active and abs(actuators.steer) > 0.9 lka_icon_status = (lka_active, lka_critical) + + # SW_GMLAN not yet on cam harness, no HUD alerts if self.CP.networkLocation != NetworkLocation.fwdCamera and (self.frame % self.params.CAMERA_KEEPALIVE_STEP == 0 or lka_icon_status != self.lka_icon_status_last): steer_alert = hud_alert in (VisualAlert.steerRequired, VisualAlert.ldw) can_sends.append(gmcan.create_lka_icon_command(CanBus.SW_GMLAN, lka_active, lka_critical, steer_alert)) diff --git a/selfdrive/car/gm/carstate.py b/selfdrive/car/gm/carstate.py index b174d0327ed7c4..e89ece198e1d98 100644 --- a/selfdrive/car/gm/carstate.py +++ b/selfdrive/car/gm/carstate.py @@ -1,4 +1,5 @@ from cereal import car +from common.conversions import Conversions as CV from common.numpy_fast import mean from opendbc.can.can_define import CANDefine from opendbc.can.parser import CANParser @@ -6,6 +7,7 @@ from selfdrive.car.gm.values import DBC, AccState, CanBus, STEER_THRESHOLD TransmissionType = car.CarParams.TransmissionType +NetworkLocation = car.CarParams.NetworkLocation class CarState(CarStateBase): @@ -15,7 +17,7 @@ def __init__(self, CP): self.shifter_values = can_define.dv["ECMPRDNL2"]["PRNDL2"] self.lka_steering_cmd_counter = 0 - def update(self, pt_cp, loopback_cp): + def update(self, pt_cp, cam_cp, loopback_cp): ret = car.CarState.new_message() self.prev_cruise_buttons = self.cruise_buttons @@ -77,9 +79,21 @@ def update(self, pt_cp, loopback_cp): ret.cruiseState.enabled = pt_cp.vl["AcceleratorPedal2"]["CruiseState"] != AccState.OFF ret.cruiseState.standstill = pt_cp.vl["AcceleratorPedal2"]["CruiseState"] == AccState.STANDSTILL + if self.CP.networkLocation == NetworkLocation.fwdCamera: + ret.cruiseState.speed = (cam_cp.vl["ASCMActiveCruiseControlStatus"]["ACCSpeedSetpoint"] / 16) * CV.KPH_TO_MS return ret + @staticmethod + def get_cam_can_parser(CP): + signals = [] + checks = [] + if CP.networkLocation == NetworkLocation.fwdCamera: + signals.append(("ACCSpeedSetpoint", "ASCMActiveCruiseControlStatus")) + checks.append(("ASCMActiveCruiseControlStatus", 25)) + + return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, CanBus.CAMERA) + @staticmethod def get_can_parser(CP): signals = [ diff --git a/selfdrive/car/gm/gmcan.py b/selfdrive/car/gm/gmcan.py index 47e6090a03a32a..98265e8c6b68f0 100644 --- a/selfdrive/car/gm/gmcan.py +++ b/selfdrive/car/gm/gmcan.py @@ -1,5 +1,9 @@ from selfdrive.car import make_can_msg +def create_buttons(packer, bus, button): + values = {"ACCButtons": button} + return packer.make_can_msg("ASCMSteeringButton", bus, values) + def create_steering_control(packer, bus, apply_steer, idx, lkas_active): values = { diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py index 10ae670ac8e5b5..f3f1e587ca76ec 100755 --- a/selfdrive/car/gm/interface.py +++ b/selfdrive/car/gm/interface.py @@ -1,10 +1,11 @@ #!/usr/bin/env python3 from cereal import car from math import fabs +from panda import Panda from common.conversions import Conversions as CV from selfdrive.car import STD_CARGO_KG, create_button_enable_events, create_button_event, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config -from selfdrive.car.gm.values import CAR, CruiseButtons, CarControllerParams +from selfdrive.car.gm.values import CAR, CruiseButtons, CarControllerParams, EV_CAR, CAMERA_ACC_CAR from selfdrive.car.interfaces import CarInterfaceBase ButtonType = car.CarState.ButtonEvent.Type @@ -48,29 +49,36 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None, disa ret = CarInterfaceBase.get_std_params(candidate, fingerprint) ret.carName = "gm" ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.gm)] - ret.pcmCruise = False # For ASCM, stock non-adaptive cruise control is kept off - ret.radarOffCan = False # For ASCM, radar exists - ret.transmissionType = TransmissionType.automatic - # NetworkLocation.gateway: OBD-II harness (typically ASCM), NetworkLocation.fwdCamera: non-ASCM - ret.networkLocation = NetworkLocation.gateway + + if candidate in EV_CAR: + ret.transmissionType = TransmissionType.direct + else: + ret.transmissionType = TransmissionType.automatic + + if candidate in CAMERA_ACC_CAR: + ret.openpilotLongitudinalControl = False + ret.networkLocation = NetworkLocation.fwdCamera + ret.radarOffCan = True # no radar + ret.pcmCruise = True + ret.safetyConfigs[0].safetyParam |= Panda.FLAG_GM_HW_CAM + else: # ASCM, OBD-II harness + ret.openpilotLongitudinalControl = True + ret.networkLocation = NetworkLocation.gateway + ret.radarOffCan = False + ret.pcmCruise = False # stock non-adaptive cruise control is kept off # These cars have been put into dashcam only due to both a lack of users and test coverage. # These cars likely still work fine. Once a user confirms each car works and a test route is # added to selfdrive/car/tests/routes.py, we can remove it from this list. ret.dashcamOnly = candidate in {CAR.CADILLAC_ATS, CAR.HOLDEN_ASTRA, CAR.MALIBU, CAR.BUICK_REGAL} - # Presence of a camera on the object bus is ok. - # Have to go to read_only if ASCM is online (ACC-enabled cars), - # or camera is on powertrain bus (LKA cars without ACC). - ret.openpilotLongitudinalControl = True - tire_stiffness_factor = 0.444 # not optimized yet - # Start with a baseline tuning for all GM vehicles. Override tuning as needed in each model section below. ret.minSteerSpeed = 7 * CV.MPH_TO_MS ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2], [0.00]] ret.lateralTuning.pid.kf = 0.00004 # full torque for 20 deg at 80mph means 0.00007818594 ret.steerActuatorDelay = 0.1 # Default delay, not measured yet + tire_stiffness_factor = 0.444 # not optimized yet ret.longitudinalTuning.kpBP = [5., 35.] ret.longitudinalTuning.kpV = [2.4, 1.5] @@ -84,7 +92,6 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None, disa ret.minEnableSpeed = 18 * CV.MPH_TO_MS if candidate == CAR.VOLT: - ret.transmissionType = TransmissionType.direct ret.mass = 1607. + STD_CARGO_KG ret.wheelbase = 2.69 ret.steerRatio = 17.7 # Stock 15.7, LiveParameters @@ -143,6 +150,16 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None, disa ret.lateralTuning.pid.kf = 0.000045 tire_stiffness_factor = 1.0 + elif candidate == CAR.BOLT_EUV: + ret.minEnableSpeed = -1 + ret.mass = 1669. + STD_CARGO_KG + ret.wheelbase = 2.675 + ret.steerRatio = 16.8 + ret.centerToFront = ret.wheelbase * 0.4 + tire_stiffness_factor = 1.0 + ret.steerActuatorDelay = 0.2 + CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) + # TODO: get actual value, for now starting with reasonable value for # civic and scaling by mass and wheelbase ret.rotationalInertia = scale_rot_inertia(ret.mass, ret.wheelbase) @@ -156,7 +173,7 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None, disa # returns a car.CarState def _update(self, c): - ret = self.CS.update(self.cp, self.cp_loopback) + ret = self.CS.update(self.cp, self.cp_cam, self.cp_loopback) if self.CS.cruise_buttons != self.CS.prev_cruise_buttons and self.CS.prev_cruise_buttons != CruiseButtons.INIT: be = create_button_event(self.CS.cruise_buttons, self.CS.prev_cruise_buttons, BUTTONS_DICT, CruiseButtons.UNPRESS) diff --git a/selfdrive/car/gm/values.py b/selfdrive/car/gm/values.py index 016910a40fafde..6d34093102dc28 100644 --- a/selfdrive/car/gm/values.py +++ b/selfdrive/car/gm/values.py @@ -14,7 +14,6 @@ class CarControllerParams: STEER_STEP = 2 # Control frames per command (50hz) STEER_DELTA_UP = 7 # Delta rates require review due to observed EPS weakness STEER_DELTA_DOWN = 17 - MIN_STEER_SPEED = 3. # m/s STEER_DRIVER_ALLOWANCE = 50 STEER_DRIVER_MULTIPLIER = 4 STEER_DRIVER_FACTOR = 100 @@ -59,10 +58,7 @@ class CAR: ACADIA = "GMC ACADIA DENALI 2018" BUICK_REGAL = "BUICK REGAL ESSENCE 2018" ESCALADE_ESV = "CADILLAC ESCALADE ESV 2016" - - -EV_CAR = {CAR.VOLT} -STEER_THRESHOLD = 1.0 + BOLT_EUV = "CHEVROLET BOLT EUV 2022" class Footnote(Enum): @@ -87,6 +83,7 @@ class GMCarInfo(CarInfo): CAR.ACADIA: GMCarInfo("GMC Acadia 2018", video_link="https://www.youtube.com/watch?v=0ZN6DdsBUZo"), CAR.BUICK_REGAL: GMCarInfo("Buick Regal Essence 2018"), CAR.ESCALADE_ESV: GMCarInfo("Cadillac Escalade ESV 2016", "Adaptive Cruise Control (ACC) & LKAS"), + CAR.BOLT_EUV: GMCarInfo("Chevrolet Bolt EUV 2022-23", "All", footnotes=[], harness=Harness.gm), } @@ -107,6 +104,7 @@ class AccState: class CanBus: POWERTRAIN = 0 OBSTACLE = 1 + CAMERA = 2 CHASSIS = 2 SW_GMLAN = 3 LOOPBACK = 128 @@ -155,6 +153,17 @@ class CanBus: { 309: 1, 848: 8, 849: 8, 850: 8, 851: 8, 852: 8, 853: 8, 854: 3, 1056: 6, 1057: 8, 1058: 8, 1059: 8, 1060: 8, 1061: 8, 1062: 8, 1063: 8, 1064: 8, 1065: 8, 1066: 8, 1067: 8, 1068: 8, 1120: 8, 1121: 8, 1122: 8, 1123: 8, 1124: 8, 1125: 8, 1126: 8, 1127: 8, 1128: 8, 1129: 8, 1130: 8, 1131: 8, 1132: 8, 1133: 8, 1134: 8, 1135: 8, 1136: 8, 1137: 8, 1138: 8, 1139: 8, 1140: 8, 1141: 8, 1142: 8, 1143: 8, 1146: 8, 1147: 8, 1148: 8, 1149: 8, 1150: 8, 1151: 8, 1216: 8, 1217: 8, 1218: 8, 1219: 8, 1220: 8, 1221: 8, 1222: 8, 1223: 8, 1224: 8, 1225: 8, 1226: 8, 1232: 8, 1233: 8, 1234: 8, 1235: 8, 1236: 8, 1237: 8, 1238: 8, 1239: 8, 1240: 8, 1241: 8, 1242: 8, 1787: 8, 1788: 8 }], + CAR.BOLT_EUV: [ + { + 189: 7, 190: 7, 193: 8, 197: 8, 201: 8, 209: 7, 211: 3, 241: 6, 257: 8, 288: 5, 289: 8, 298: 8, 304: 3, 309: 8, 311: 8, 313: 8, 320: 4, 322: 7, 328: 1, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 451: 8, 452: 8, 453: 6, 458: 5, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 500: 6, 501: 8, 528: 5, 532: 6, 560: 8, 562: 8, 563: 5, 565: 5, 566: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 715: 8, 717: 5, 753: 5, 761: 7, 789: 5, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 848: 4, 869: 4, 880: 6, 977: 8, 1001: 8, 1017: 8, 1020: 8, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1265: 8, 1280: 4, 1296: 4, 1300: 8, 1930: 7 + }], } DBC: Dict[str, Dict[str, str]] = defaultdict(lambda: dbc_dict('gm_global_a_powertrain_generated', 'gm_global_a_object', chassis_dbc='gm_global_a_chassis')) + +EV_CAR = {CAR.VOLT, CAR.BOLT_EUV} + +# We're integrated at the camera with VOACC on these cars (instead of ASCM w/ OBD-II harness) +CAMERA_ACC_CAR = {CAR.BOLT_EUV} + +STEER_THRESHOLD = 1.0 diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py index 2195befb221d73..0b1726b0106e76 100644 --- a/selfdrive/car/tests/routes.py +++ b/selfdrive/car/tests/routes.py @@ -47,6 +47,7 @@ TestRoute("aa20e335f61ba898|2019-02-05--16-59-04", GM.BUICK_REGAL), TestRoute("46460f0da08e621e|2021-10-26--07-21-46", GM.ESCALADE_ESV), TestRoute("c950e28c26b5b168|2018-05-30--22-03-41", GM.VOLT), + TestRoute("f08912a233c1584f|2022-08-11--18-02-41", GM.BOLT_EUV), TestRoute("0e7a2ba168465df5|2020-10-18--14-14-22", HONDA.ACURA_RDX_3G), TestRoute("a74b011b32b51b56|2020-07-26--17-09-36", HONDA.CIVIC), diff --git a/selfdrive/car/tests/test_models.py b/selfdrive/car/tests/test_models.py index 8906942f26731b..4a1f1a61ee46fa 100755 --- a/selfdrive/car/tests/test_models.py +++ b/selfdrive/car/tests/test_models.py @@ -58,7 +58,6 @@ def setUpClass(cls): raise unittest.SkipTest if 'FILTER' in os.environ: - print(tuple(os.environ.get('FILTER').split(', '))) if not cls.car_model.startswith(tuple(os.environ.get('FILTER').split(','))): raise unittest.SkipTest diff --git a/selfdrive/car/torque_data/override.yaml b/selfdrive/car/torque_data/override.yaml index 635743c11a98bd..0a958a9d035028 100644 --- a/selfdrive/car/torque_data/override.yaml +++ b/selfdrive/car/torque_data/override.yaml @@ -24,6 +24,7 @@ KIA EV6 2022: [3.5, 2.5, 0.0] RAM 1500 5TH GEN: [2.0, 2.0, 0.0] RAM HD 5TH GEN: [1.4, 1.4, 0.0] SUBARU OUTBACK 6TH GEN: [2.3, 2.3, 0.11] +CHEVROLET BOLT EUV 2022: [2.0, 2.0, 0.05] # Dashcam or fallback configured as ideal car mock: [10.0, 10, 0.0] From f0214d5e83661cf6d7bada40a6ffef703609b4fe Mon Sep 17 00:00:00 2001 From: cydia2020 <12470297+cydia2020@users.noreply.github.com> Date: Sat, 13 Aug 2022 09:26:50 +1000 Subject: [PATCH 015/106] Multilang: fill missing Japanese translations (#25418) * japanese translations * ENTER literally means enter * This makes more sense * finished Co-authored-by: Shane Smiskol --- selfdrive/ui/translations/main_ja.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/selfdrive/ui/translations/main_ja.ts b/selfdrive/ui/translations/main_ja.ts index 20f96b8f4089be..111fe9184e445e 100644 --- a/selfdrive/ui/translations/main_ja.ts +++ b/selfdrive/ui/translations/main_ja.ts @@ -1025,23 +1025,23 @@ location set Switch Branch - + ブランチの切り替え ENTER - + 切替 The new branch will be pulled the next time the updater runs. - + updater を実行する時にブランチを切り替えます。 Enter branch name - + ブランチ名を入力 From 7e6f4e74bfccead6e347329d09cee2317605f343 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Fri, 12 Aug 2022 16:46:33 -0700 Subject: [PATCH 016/106] body: add fw repo as submodule (#25420) * body: add fw repo as submodule * bump body * file whitelist * revert that for now --- .gitignore | 1 - .gitmodules | 23 +++++++++++++---------- .pre-commit-config.yaml | 2 +- SConstruct | 10 +++++++--- body | 1 + release/files_common | 13 +++++++++++++ 6 files changed, 35 insertions(+), 15 deletions(-) create mode 160000 body diff --git a/.gitignore b/.gitignore index 07626f4e285ab2..6aee0ed8e0b077 100644 --- a/.gitignore +++ b/.gitignore @@ -55,7 +55,6 @@ selfdrive/modeld/_dmonitoringmodeld /src/ one -/body/ openpilot notebooks xx diff --git a/.gitmodules b/.gitmodules index 1e6110b7a6941e..bc439b451c4583 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,15 +1,18 @@ [submodule "panda"] - path = panda - url = ../../commaai/panda.git + path = panda + url = ../../commaai/panda.git [submodule "opendbc"] - path = opendbc - url = ../../commaai/opendbc.git + path = opendbc + url = ../../commaai/opendbc.git [submodule "laika_repo"] - path = laika_repo - url = ../../commaai/laika.git + path = laika_repo + url = ../../commaai/laika.git [submodule "cereal"] - path = cereal - url = ../../commaai/cereal.git + path = cereal + url = ../../commaai/cereal.git [submodule "rednose_repo"] - path = rednose_repo - url = ../../commaai/rednose.git + path = rednose_repo + url = ../../commaai/rednose.git +[submodule "body"] + path = body + url = ../../commaai/body.git diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8b8bc1f1b9ce67..e273cd9aeeab91 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -54,7 +54,7 @@ repos: entry: cppcheck language: system types: [c++] - exclude: '^(third_party/)|(pyextra/)|(cereal/)|(rednose/)|(rednose_repo/)|(opendbc/)|(panda/)|(tools/)|(selfdrive/modeld/thneed/debug/)|(selfdrive/modeld/test/)|(selfdrive/camerad/test/)/|(installer/)' + exclude: '^(third_party/)|(pyextra/)|(cereal/)|(body/)|(rednose/)|(rednose_repo/)|(opendbc/)|(panda/)|(tools/)|(selfdrive/modeld/thneed/debug/)|(selfdrive/modeld/test/)|(selfdrive/camerad/test/)|(installer/)' args: - --error-exitcode=1 - --language=c++ diff --git a/SConstruct b/SConstruct index 940b2367fa4b35..49685b19b20e29 100644 --- a/SConstruct +++ b/SConstruct @@ -393,9 +393,13 @@ if arch != "Darwin": # Build openpilot -SConscript(['cereal/SConscript']) -SConscript(['panda/board/SConscript']) -SConscript(['opendbc/can/SConscript']) +# build submodules +SConscript([ + 'cereal/SConscript', + 'body/board/SConscript', + 'panda/board/SConscript', + 'opendbc/can/SConscript', +]) SConscript(['third_party/SConscript']) diff --git a/body b/body new file mode 160000 index 00000000000000..04aeb30ce0bb14 --- /dev/null +++ b/body @@ -0,0 +1 @@ +Subproject commit 04aeb30ce0bb14759989cd374158233877e1e151 diff --git a/release/files_common b/release/files_common index 192c6ec45e0687..8bf99f02283847 100644 --- a/release/files_common +++ b/release/files_common @@ -434,6 +434,19 @@ rednose/.gitignore rednose/** laika/** +body/.gitignore +body/board/SConscript +body/board/*.h +body/board/*.c +body/board/*.s +body/board/*.ld +body/board/inc/** +body/board/obj/ +body/board/bldc/** +body/board/drivers/** +body/certs/** +body/crypto/** + cereal/.gitignore cereal/__init__.py cereal/car.capnp From 3e3f960342fb97f26d64648172970d65ade08fc4 Mon Sep 17 00:00:00 2001 From: Jason Young <46612682+jyoung8607@users.noreply.github.com> Date: Fri, 12 Aug 2022 22:43:36 -0400 Subject: [PATCH 017/106] VW PQ: Cleanup and prep for upstream (#25351) * VW MQB: Cleanup and abstractions * regen CARS.md * Update selfdrive/car/volkswagen/values.py Co-authored-by: Adeeb Shihadeh * regen CARS.md * now that's a refactor of a different sort * move shifter value init/storage Co-authored-by: Adeeb Shihadeh --- docs/CARS.md | 2 +- selfdrive/car/volkswagen/carcontroller.py | 46 ++++++------ selfdrive/car/volkswagen/carstate.py | 28 +++---- selfdrive/car/volkswagen/mqbcan.py | 38 ++++++++++ selfdrive/car/volkswagen/values.py | 92 ++++++++++++----------- selfdrive/car/volkswagen/volkswagencan.py | 42 ----------- 6 files changed, 121 insertions(+), 127 deletions(-) create mode 100644 selfdrive/car/volkswagen/mqbcan.py delete mode 100644 selfdrive/car/volkswagen/volkswagencan.py diff --git a/docs/CARS.md b/docs/CARS.md index c3278d7066816f..96d966ba98e474 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -231,7 +231,7 @@ A supported vehicle is one that just works when you install a comma device. Ever 3When the Driver Support Unit (DSU) is disconnected, openpilot Adaptive Cruise Control (ACC) will replace stock Adaptive Cruise Control (ACC). NOTE: disconnecting the DSU disables Automatic Emergency Braking (AEB).
4openpilot operates above 28mph for Camry 4CYL L, 4CYL LE and 4CYL SE which don't have Full-Speed Range Dynamic Radar Cruise Control.
5Not including the China market Kamiq, which is based on the (currently) unsupported PQ34 platform.
-6Not including the USA/China market Passat, which is based on the (currently) unsupported PQ35/NMS platform.
+6Refers only to the MQB-based European B8 Passat, not the NMS Passat in the USA/China/Mideast markets.
7Model-years 2021 and beyond may have a new camera harness design, which isn't yet available from the comma store. Before ordering, remove the Lane Assist camera cover and check to see if the connector is black (older design) or light brown (newer design). In the interim, if your car has a J533 connector CAN gateway inside the dashboard, choose "VW J533 Development" from the vehicle drop-down for a suitable harness. (Some newer models are also observed to not have a J533 connector.)
8Includes versions with extra rear cargo space (may be called Variant, Estate, SportWagen, Shooting Brake, etc.)
diff --git a/selfdrive/car/volkswagen/carcontroller.py b/selfdrive/car/volkswagen/carcontroller.py index 99a3ce55f4621b..0923ac0313b1ae 100644 --- a/selfdrive/car/volkswagen/carcontroller.py +++ b/selfdrive/car/volkswagen/carcontroller.py @@ -1,8 +1,8 @@ from cereal import car from opendbc.can.packer import CANPacker from selfdrive.car import apply_std_steer_torque_limits -from selfdrive.car.volkswagen import volkswagencan -from selfdrive.car.volkswagen.values import DBC_FILES, CANBUS, MQB_LDW_MESSAGES, CarControllerParams as P +from selfdrive.car.volkswagen import mqbcan +from selfdrive.car.volkswagen.values import CANBUS, CarControllerParams VisualAlert = car.CarControl.HUDControl.VisualAlert @@ -10,11 +10,12 @@ class CarController: def __init__(self, dbc_name, CP, VM): self.CP = CP + self.CCP = CarControllerParams(CP) + self.CCS = mqbcan + self.packer_pt = CANPacker(dbc_name) + self.apply_steer_last = 0 self.frame = 0 - - self.packer_pt = CANPacker(DBC_FILES.mqb) - self.hcaSameTorqueCount = 0 self.hcaEnabledFrameCount = 0 @@ -26,7 +27,7 @@ def update(self, CC, CS, ext_bus): # **** Steering Controls ************************************************ # - if self.frame % P.HCA_STEP == 0: + if self.frame % self.CCP.HCA_STEP == 0: # Logic to avoid HCA state 4 "refused": # * Don't steer unless HCA is in state 3 "ready" or 5 "active" # * Don't steer at standstill @@ -38,21 +39,21 @@ def update(self, CC, CS, ext_bus): # when exceeding ~1/3 the 360 second timer. if CC.latActive: - new_steer = int(round(actuators.steer * P.STEER_MAX)) - apply_steer = apply_std_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, P) + new_steer = int(round(actuators.steer * self.CCP.STEER_MAX)) + apply_steer = apply_std_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.CCP) if apply_steer == 0: hcaEnabled = False self.hcaEnabledFrameCount = 0 else: self.hcaEnabledFrameCount += 1 - if self.hcaEnabledFrameCount >= 118 * (100 / P.HCA_STEP): # 118s + if self.hcaEnabledFrameCount >= 118 * (100 / self.CCP.HCA_STEP): # 118s hcaEnabled = False self.hcaEnabledFrameCount = 0 else: hcaEnabled = True if self.apply_steer_last == apply_steer: self.hcaSameTorqueCount += 1 - if self.hcaSameTorqueCount > 1.9 * (100 / P.HCA_STEP): # 1.9s + if self.hcaSameTorqueCount > 1.9 * (100 / self.CCP.HCA_STEP): # 1.9s apply_steer -= (1, -1)[apply_steer < 0] self.hcaSameTorqueCount = 0 else: @@ -62,32 +63,29 @@ def update(self, CC, CS, ext_bus): apply_steer = 0 self.apply_steer_last = apply_steer - can_sends.append(volkswagencan.create_mqb_steering_control(self.packer_pt, CANBUS.pt, apply_steer, hcaEnabled)) + can_sends.append(self.CCS.create_steering_control(self.packer_pt, CANBUS.pt, apply_steer, hcaEnabled)) # **** HUD Controls ***************************************************** # - if self.frame % P.LDW_STEP == 0: + if self.frame % self.CCP.LDW_STEP == 0: + hud_alert = 0 if hud_control.visualAlert in (VisualAlert.steerRequired, VisualAlert.ldw): - hud_alert = MQB_LDW_MESSAGES["laneAssistTakeOverSilent"] - else: - hud_alert = MQB_LDW_MESSAGES["none"] + hud_alert = self.CCP.LDW_MESSAGES["laneAssistTakeOver"] - can_sends.append(volkswagencan.create_mqb_hud_control(self.packer_pt, CANBUS.pt, CC.enabled, - CS.out.steeringPressed, hud_alert, hud_control.leftLaneVisible, - hud_control.rightLaneVisible, CS.ldw_stock_values, - hud_control.leftLaneDepart, hud_control.rightLaneDepart)) + can_sends.append(self.CCS.create_lka_hud_control(self.packer_pt, CANBUS.pt, CS.ldw_stock_values, CC.enabled, + CS.out.steeringPressed, hud_alert, hud_control)) - # **** ACC Button Controls ********************************************** # + # **** Stock ACC Button Controls **************************************** # - if self.CP.pcmCruise and self.frame % P.GRA_ACC_STEP == 0: + if self.CP.pcmCruise and self.frame % self.CCP.GRA_ACC_STEP == 0: idx = (CS.gra_stock_values["COUNTER"] + 1) % 16 if CC.cruiseControl.cancel: - can_sends.append(volkswagencan.create_mqb_acc_buttons_control(self.packer_pt, ext_bus, CS.gra_stock_values, idx, cancel=True)) + can_sends.append(self.CCS.create_acc_buttons_control(self.packer_pt, ext_bus, CS.gra_stock_values, idx, cancel=True)) elif CC.cruiseControl.resume: - can_sends.append(volkswagencan.create_mqb_acc_buttons_control(self.packer_pt, ext_bus, CS.gra_stock_values, idx, resume=True)) + can_sends.append(self.CCS.create_acc_buttons_control(self.packer_pt, ext_bus, CS.gra_stock_values, idx, resume=True)) new_actuators = actuators.copy() - new_actuators.steer = self.apply_steer_last / P.STEER_MAX + new_actuators.steer = self.apply_steer_last / self.CCP.STEER_MAX self.frame += 1 return new_actuators, can_sends diff --git a/selfdrive/car/volkswagen/carstate.py b/selfdrive/car/volkswagen/carstate.py index 052a1262e43d7c..65e3de169c09f1 100644 --- a/selfdrive/car/volkswagen/carstate.py +++ b/selfdrive/car/volkswagen/carstate.py @@ -3,20 +3,14 @@ from common.conversions import Conversions as CV from selfdrive.car.interfaces import CarStateBase from opendbc.can.parser import CANParser -from opendbc.can.can_define import CANDefine -from selfdrive.car.volkswagen.values import DBC_FILES, CANBUS, NetworkLocation, TransmissionType, GearShifter, \ - CarControllerParams, MQB_BUTTONS +from selfdrive.car.volkswagen.values import DBC, CANBUS, NetworkLocation, TransmissionType, GearShifter, CarControllerParams + class CarState(CarStateBase): def __init__(self, CP): super().__init__(CP) - self.button_states = {button.event_type: False for button in MQB_BUTTONS} - can_define = CANDefine(DBC_FILES.mqb) - if CP.transmissionType == TransmissionType.automatic: - self.shifter_values = can_define.dv["Getriebe_11"]["GE_Fahrstufe"] - elif CP.transmissionType == TransmissionType.direct: - self.shifter_values = can_define.dv["EV_Gearshift"]["GearPosition"] - self.hca_status_values = can_define.dv["LH_EPS_03"]["EPS_HCA_Status"] + self.CCP = CarControllerParams(CP) + self.button_states = {button.event_type: False for button in self.CCP.BUTTONS} def update(self, pt_cp, cam_cp, ext_cp, trans_type): ret = car.CarState.new_message() @@ -37,11 +31,11 @@ def update(self, pt_cp, cam_cp, ext_cp, trans_type): ret.steeringAngleDeg = pt_cp.vl["LWI_01"]["LWI_Lenkradwinkel"] * (1, -1)[int(pt_cp.vl["LWI_01"]["LWI_VZ_Lenkradwinkel"])] ret.steeringRateDeg = pt_cp.vl["LWI_01"]["LWI_Lenkradw_Geschw"] * (1, -1)[int(pt_cp.vl["LWI_01"]["LWI_VZ_Lenkradw_Geschw"])] ret.steeringTorque = pt_cp.vl["LH_EPS_03"]["EPS_Lenkmoment"] * (1, -1)[int(pt_cp.vl["LH_EPS_03"]["EPS_VZ_Lenkmoment"])] - ret.steeringPressed = abs(ret.steeringTorque) > CarControllerParams.STEER_DRIVER_ALLOWANCE + ret.steeringPressed = abs(ret.steeringTorque) > self.CCP.STEER_DRIVER_ALLOWANCE ret.yawRate = pt_cp.vl["ESP_02"]["ESP_Gierrate"] * (1, -1)[int(pt_cp.vl["ESP_02"]["ESP_VZ_Gierrate"])] * CV.DEG_TO_RAD # Verify EPS readiness to accept steering commands - hca_status = self.hca_status_values.get(pt_cp.vl["LH_EPS_03"]["EPS_HCA_Status"]) + hca_status = self.CCP.hca_status_values.get(pt_cp.vl["LH_EPS_03"]["EPS_HCA_Status"]) ret.steerFaultPermanent = hca_status in ("DISABLED", "FAULT") ret.steerFaultTemporary = hca_status in ("INITIALIZING", "REJECTED") @@ -54,9 +48,9 @@ def update(self, pt_cp, cam_cp, ext_cp, trans_type): # Update gear and/or clutch position data. if trans_type == TransmissionType.automatic: - ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(pt_cp.vl["Getriebe_11"]["GE_Fahrstufe"], None)) + ret.gearShifter = self.parse_gear_shifter(self.CCP.shifter_values.get(pt_cp.vl["Getriebe_11"]["GE_Fahrstufe"], None)) elif trans_type == TransmissionType.direct: - ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(pt_cp.vl["EV_Gearshift"]["GearPosition"], None)) + ret.gearShifter = self.parse_gear_shifter(self.CCP.shifter_values.get(pt_cp.vl["EV_Gearshift"]["GearPosition"], None)) elif trans_type == TransmissionType.manual: ret.clutchPressed = not pt_cp.vl["Motor_14"]["MO_Kuppl_schalter"] if bool(pt_cp.vl["Gateway_72"]["BCM1_Rueckfahrlicht_Schalter"]): @@ -120,7 +114,7 @@ def update(self, pt_cp, cam_cp, ext_cp, trans_type): ret.rightBlinker = bool(pt_cp.vl["Blinkmodi_02"]["Comfort_Signal_Right"]) self.gra_stock_values = pt_cp.vl["GRA_ACC_01"] buttonEvents = [] - for button in MQB_BUTTONS: + for button in self.CCP.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() @@ -218,7 +212,7 @@ def get_can_parser(CP): signals += MqbExtraSignals.bsm_radar_signals checks += MqbExtraSignals.bsm_radar_checks - return CANParser(DBC_FILES.mqb, signals, checks, CANBUS.pt) + return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, CANBUS.pt) @staticmethod def get_cam_can_parser(CP): @@ -246,7 +240,7 @@ def get_cam_can_parser(CP): signals += MqbExtraSignals.bsm_radar_signals checks += MqbExtraSignals.bsm_radar_checks - return CANParser(DBC_FILES.mqb, signals, checks, CANBUS.cam) + return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, CANBUS.cam) class MqbExtraSignals: # Additional signal and message lists for optional or bus-portable controllers diff --git a/selfdrive/car/volkswagen/mqbcan.py b/selfdrive/car/volkswagen/mqbcan.py new file mode 100644 index 00000000000000..1a4ca339ab4f1e --- /dev/null +++ b/selfdrive/car/volkswagen/mqbcan.py @@ -0,0 +1,38 @@ +def create_steering_control(packer, bus, apply_steer, lkas_enabled): + values = { + "SET_ME_0X3": 0x3, + "Assist_Torque": abs(apply_steer), + "Assist_Requested": lkas_enabled, + "Assist_VZ": 1 if apply_steer < 0 else 0, + "HCA_Available": 1, + "HCA_Standby": not lkas_enabled, + "HCA_Active": lkas_enabled, + "SET_ME_0XFE": 0xFE, + "SET_ME_0X07": 0x07, + } + return packer.make_can_msg("HCA_01", bus, values) + + +def create_lka_hud_control(packer, bus, ldw_stock_values, enabled, steering_pressed, hud_alert, hud_control): + values = ldw_stock_values.copy() + + values.update({ + "LDW_Status_LED_gelb": 1 if enabled and steering_pressed else 0, + "LDW_Status_LED_gruen": 1 if enabled and not steering_pressed else 0, + "LDW_Lernmodus_links": 3 if hud_control.leftLaneDepart else 1 + hud_control.leftLaneVisible, + "LDW_Lernmodus_rechts": 3 if hud_control.rightLaneDepart else 1 + hud_control.rightLaneVisible, + "LDW_Texte": hud_alert, + }) + return packer.make_can_msg("LDW_02", bus, values) + + +def create_acc_buttons_control(packer, bus, gra_stock_values, idx, cancel=False, resume=False): + values = gra_stock_values.copy() + + values.update({ + "COUNTER": idx, + "GRA_Abbrechen": cancel, + "GRA_Tip_Wiederaufnahme": resume, + }) + + return packer.make_can_msg("GRA_ACC_01", bus, values) diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py index 8b2c7e93cc4d14..af0139e7bb1af2 100755 --- a/selfdrive/car/volkswagen/values.py +++ b/selfdrive/car/volkswagen/values.py @@ -4,6 +4,7 @@ from typing import Dict, List, Union from cereal import car +from opendbc.can.can_define import CANDefine from selfdrive.car import dbc_dict from selfdrive.car.docs_definitions import CarFootnote, CarInfo, Column, Harness @@ -15,54 +16,56 @@ class CarControllerParams: - HCA_STEP = 2 # HCA_01 message frequency 50Hz - LDW_STEP = 10 # LDW_02 message frequency 10Hz - GRA_ACC_STEP = 3 # GRA_ACC_01 message frequency 33Hz + HCA_STEP = 2 # HCA_01/HCA_1 message frequency 50Hz + GRA_ACC_STEP = 3 # GRA_ACC_01/GRA_Neu message frequency 33Hz - # Observed documented MQB limits: 3.00 Nm max, rate of change 5.00 Nm/sec. - # Limiting rate-of-change based on real-world testing and Comma's safety - # requirements for minimum time to lane departure. - STEER_MAX = 300 # Max heading control assist torque 3.00 Nm - STEER_DELTA_UP = 4 # Max HCA reached in 1.50s (STEER_MAX / (50Hz * 1.50)) - STEER_DELTA_DOWN = 10 # Min HCA reached in 0.60s (STEER_MAX / (50Hz * 0.60)) - STEER_DRIVER_ALLOWANCE = 80 - STEER_DRIVER_MULTIPLIER = 3 # weight driver torque heavily - STEER_DRIVER_FACTOR = 1 # from dbc + def __init__(self, CP): + # Documented lateral limits: 3.00 Nm max, rate of change 5.00 Nm/sec. + # MQB vs PQ maximums are shared, but rate-of-change limited differently + # based on safety requirements driven by lateral accel testing. + self.STEER_MAX = 300 # Max heading control assist torque 3.00 Nm + self.STEER_DRIVER_MULTIPLIER = 3 # weight driver torque heavily + self.STEER_DRIVER_FACTOR = 1 # from dbc + + can_define = CANDefine(DBC[CP.carFingerprint]["pt"]) + + if True: # pylint: disable=using-constant-test + self.LDW_STEP = 10 # LDW_02 message frequency 10Hz + self.STEER_DRIVER_ALLOWANCE = 80 # Driver intervention threshold 0.8 Nm + self.STEER_DELTA_UP = 4 # Max HCA reached in 1.50s (STEER_MAX / (50Hz * 1.50)) + self.STEER_DELTA_DOWN = 10 # Min HCA reached in 0.60s (STEER_MAX / (50Hz * 0.60)) + if CP.transmissionType == TransmissionType.automatic: + self.shifter_values = can_define.dv["Getriebe_11"]["GE_Fahrstufe"] + elif CP.transmissionType == TransmissionType.direct: + self.shifter_values = can_define.dv["EV_Gearshift"]["GearPosition"] + self.hca_status_values = can_define.dv["LH_EPS_03"]["EPS_HCA_Status"] -class CANBUS: - pt = 0 - cam = 2 - - -class DBC_FILES: - mqb = "vw_mqb_2010" # Used for all cars with MQB-style CAN messaging - - -DBC: Dict[str, Dict[str, str]] = defaultdict(lambda: dbc_dict(DBC_FILES.mqb, None)) + 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]), + ] + self.LDW_MESSAGES = { + "none": 0, # Nothing to display + "laneAssistUnavailChime": 1, # "Lane Assist currently not available." with chime + "laneAssistUnavailNoSensorChime": 3, # "Lane Assist not available. No sensor view." with chime + "laneAssistTakeOverUrgent": 4, # "Lane Assist: Please Take Over Steering" with urgent beep + "emergencyAssistUrgent": 6, # "Emergency Assist: Please Take Over Steering" with urgent beep + "laneAssistTakeOverChime": 7, # "Lane Assist: Please Take Over Steering" with chime + "laneAssistTakeOver": 8, # "Lane Assist: Please Take Over Steering" silent + "emergencyAssistChangingLanes": 9, # "Emergency Assist: Changing lanes..." with urgent beep + "laneAssistDeactivated": 10, # "Lane Assist deactivated." silent with persistent icon afterward + } -MQB_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]), -] - -MQB_LDW_MESSAGES = { - "none": 0, # Nothing to display - "laneAssistUnavailChime": 1, # "Lane Assist currently not available." with chime - "laneAssistUnavailNoSensorChime": 3, # "Lane Assist not available. No sensor view." with chime - "laneAssistTakeOverUrgent": 4, # "Lane Assist: Please Take Over Steering" with urgent beep - "emergencyAssistUrgent": 6, # "Emergency Assist: Please Take Over Steering" with urgent beep - "laneAssistTakeOverChime": 7, # "Lane Assist: Please Take Over Steering" with chime - "laneAssistTakeOverSilent": 8, # "Lane Assist: Please Take Over Steering" silent - "emergencyAssistChangingLanes": 9, # "Emergency Assist: Changing lanes..." with urgent beep - "laneAssistDeactivated": 10, # "Lane Assist deactivated." silent with persistent icon afterward -} +class CANBUS: + pt = 0 + cam = 2 # Check the 7th and 8th characters of the VIN before adding a new CAR. If the @@ -96,12 +99,15 @@ class CAR: SKODA_OCTAVIA_MK3 = "SKODA OCTAVIA 3RD GEN" # Chassis NE, Mk3 Skoda Octavia and variants +DBC: Dict[str, Dict[str, str]] = defaultdict(lambda: dbc_dict("vw_mqb_2010", None)) + + class Footnote(Enum): KAMIQ = CarFootnote( "Not including the China market Kamiq, which is based on the (currently) unsupported PQ34 platform.", Column.MODEL) PASSAT = CarFootnote( - "Not including the USA/China market Passat, which is based on the (currently) unsupported PQ35/NMS platform.", + "Refers only to the MQB-based European B8 Passat, not the NMS Passat in the USA/China/Mideast markets.", Column.MODEL) VW_HARNESS = CarFootnote( "Model-years 2021 and beyond may have a new camera harness design, which isn't yet available from the comma " + diff --git a/selfdrive/car/volkswagen/volkswagencan.py b/selfdrive/car/volkswagen/volkswagencan.py deleted file mode 100644 index f4c21eeed4410a..00000000000000 --- a/selfdrive/car/volkswagen/volkswagencan.py +++ /dev/null @@ -1,42 +0,0 @@ -# CAN controls for MQB platform Volkswagen, Audi, Skoda, and SEAT. -# PQ35/PQ46/NMS, and any future MLB, to come later. - -def create_mqb_steering_control(packer, bus, apply_steer, lkas_enabled): - values = { - "SET_ME_0X3": 0x3, - "Assist_Torque": abs(apply_steer), - "Assist_Requested": lkas_enabled, - "Assist_VZ": 1 if apply_steer < 0 else 0, - "HCA_Available": 1, - "HCA_Standby": not lkas_enabled, - "HCA_Active": lkas_enabled, - "SET_ME_0XFE": 0xFE, - "SET_ME_0X07": 0x07, - } - return packer.make_can_msg("HCA_01", bus, values) - -def create_mqb_hud_control(packer, bus, enabled, steering_pressed, hud_alert, left_lane_visible, right_lane_visible, - ldw_stock_values, left_lane_depart, right_lane_depart): - # Lane color reference: - # 0 (LKAS disabled) - off - # 1 (LKAS enabled, no lane detected) - dark gray - # 2 (LKAS enabled, lane detected) - light gray on VW, green or white on Audi depending on year or virtual cockpit. On a color MFD on a 2015 A3 TDI it is white, virtual cockpit on a 2018 A3 e-Tron its green. - # 3 (LKAS enabled, lane departure detected) - white on VW, red on Audi - values = ldw_stock_values.copy() - values.update({ - "LDW_Status_LED_gelb": 1 if enabled and steering_pressed else 0, - "LDW_Status_LED_gruen": 1 if enabled and not steering_pressed else 0, - "LDW_Lernmodus_links": 3 if left_lane_depart else 1 + left_lane_visible, - "LDW_Lernmodus_rechts": 3 if right_lane_depart else 1 + right_lane_visible, - "LDW_Texte": hud_alert, - }) - return packer.make_can_msg("LDW_02", bus, values) - -def create_mqb_acc_buttons_control(packer, bus, gra_stock_values, idx, cancel=False, resume=False): - values = gra_stock_values.copy() - - values["COUNTER"] = idx - values["GRA_Abbrechen"] = cancel - values["GRA_Tip_Wiederaufnahme"] = resume - - return packer.make_can_msg("GRA_ACC_01", bus, values) From 5f5d944368ea933f634953f63fabde52d773ae3b Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 12 Aug 2022 19:53:44 -0700 Subject: [PATCH 018/106] Subaru: add missing Impreza 2017 FW versions (#25424) * this is from hyundai query * These are also from Hyundai * Add missing FW versions from 5c3a4dc9bd0b2eaa|2022-08-12--18-01-46 * more FW --- selfdrive/car/subaru/values.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/selfdrive/car/subaru/values.py b/selfdrive/car/subaru/values.py index 62ddaa54b5ca51..691a4c9158f3a8 100644 --- a/selfdrive/car/subaru/values.py +++ b/selfdrive/car/subaru/values.py @@ -99,7 +99,6 @@ class SubaruCarInfo(CarInfo): b'\x00\xfe\xf7\x00\x00', b'\001\xfe\xf9\000\000', b'\x01\xfe\xf7\x00\x00', - b'\xf1\x00\xa4\x10@', ], }, CAR.IMPREZA: { @@ -116,6 +115,7 @@ class SubaruCarInfo(CarInfo): b'z\x94\x08\x90\x00', b'z\x84\x19\x90\x00', b'\xf1\x00\xb2\x06\x04', + b'z\x94\x0c\x90\x00', ], (Ecu.eps, 0x746, None): [ b'\x7a\xc0\x0c\x00', @@ -139,6 +139,7 @@ class SubaruCarInfo(CarInfo): b'\x00\x00c\xf4\x00\x00\x00\x00', b'\x00\x00d\xdc\x00\x00\x00\x00', b'\x00\x00dd\x00\x00\x00\x00', + b'\x00\x00c\xf4\x1f@ \x07', ], (Ecu.engine, 0x7e0, None): [ b'\xaa\x61\x66\x73\x07', @@ -148,7 +149,6 @@ class SubaruCarInfo(CarInfo): b'\xaa!`u\a', b'\xaa!dq\a', b'\xaa!dt\a', - b'\xf1\x00\xa2\x10\t', b'\xc5!ar\a', b'\xbe!as\a', b'\xc5!ds\a', @@ -158,6 +158,7 @@ class SubaruCarInfo(CarInfo): b'\xaa\x00Bu\x07', b'\xc5!dr\x07', b'\xaa!aw\x07', + b'\xaa!av\x07', ], (Ecu.transmission, 0x7e1, None): [ b'\xe3\xe5\x46\x31\x00', @@ -173,7 +174,6 @@ class SubaruCarInfo(CarInfo): b'\xe4\xf5\002\000\000', b'\xe3\xd0\x081\x00', b'\xe3\xf5\x06\x00\x00', - b'\xf1\x00\xa4\x10@', ], }, CAR.IMPREZA_2020: { @@ -202,7 +202,6 @@ class SubaruCarInfo(CarInfo): b'\xca!`0\a', b'\xcc\"f0\a', b'\xcc!fp\a', - b'\xf1\x00\xa2\x10\t', b'\xca!f@\x07', b'\xca!fp\x07', ], @@ -247,7 +246,6 @@ class SubaruCarInfo(CarInfo): b'\x1a\xf6F`\x00', b'\032\xf6b`\000', b'\x1a\xf6B`\x00', - b'\xf1\x00\xa4\x10@', b'\x1a\xf6b0\x00', ], }, @@ -475,4 +473,4 @@ class SubaruCarInfo(CarInfo): } GLOBAL_GEN2 = (CAR.OUTBACK, ) -PREGLOBAL_CARS = (CAR.FORESTER_PREGLOBAL, CAR.LEGACY_PREGLOBAL, CAR.OUTBACK_PREGLOBAL, CAR.OUTBACK_PREGLOBAL_2018) \ No newline at end of file +PREGLOBAL_CARS = (CAR.FORESTER_PREGLOBAL, CAR.LEGACY_PREGLOBAL, CAR.OUTBACK_PREGLOBAL, CAR.OUTBACK_PREGLOBAL_2018) From c2162420d24e8c4e43c63376cc5bc5576e467f58 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 12 Aug 2022 20:56:26 -0700 Subject: [PATCH 019/106] Car docs: fix required package for Bolt EUV 2022-23 (#25421) * Need Adaptive Cruise Control * no 2LT in configurator * or redline --- docs/CARS.md | 2 +- selfdrive/car/gm/values.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/CARS.md b/docs/CARS.md index 96d966ba98e474..ff539f052174ce 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -33,7 +33,7 @@ A supported vehicle is one that just works when you install a comma device. Ever |Audi|RS3 2018|ACC + Lane Assist|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Audi|S3 2015-17|ACC + Lane Assist|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Cadillac|Escalade ESV 2016[1](#footnotes)|Adaptive Cruise Control (ACC) & LKAS|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Chevrolet|Bolt EUV 2022-23|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| +|Chevrolet|Bolt EUV 2022-23|Premier/Premier Redline Trim|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Chevrolet|Volt 2017-18[1](#footnotes)|Adaptive Cruise Control|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Chrysler|Pacifica 2017-18|Adaptive Cruise Control|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Chrysler|Pacifica 2019-20|Adaptive Cruise Control|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| diff --git a/selfdrive/car/gm/values.py b/selfdrive/car/gm/values.py index 6d34093102dc28..75a5e96f92d916 100644 --- a/selfdrive/car/gm/values.py +++ b/selfdrive/car/gm/values.py @@ -83,7 +83,7 @@ class GMCarInfo(CarInfo): CAR.ACADIA: GMCarInfo("GMC Acadia 2018", video_link="https://www.youtube.com/watch?v=0ZN6DdsBUZo"), CAR.BUICK_REGAL: GMCarInfo("Buick Regal Essence 2018"), CAR.ESCALADE_ESV: GMCarInfo("Cadillac Escalade ESV 2016", "Adaptive Cruise Control (ACC) & LKAS"), - CAR.BOLT_EUV: GMCarInfo("Chevrolet Bolt EUV 2022-23", "All", footnotes=[], harness=Harness.gm), + CAR.BOLT_EUV: GMCarInfo("Chevrolet Bolt EUV 2022-23", "Premier/Premier Redline Trim", footnotes=[], harness=Harness.gm), } From 3bb1315136cb2c19622159130bd9f0de947f1c66 Mon Sep 17 00:00:00 2001 From: kravatch Date: Sat, 13 Aug 2022 01:31:57 -0400 Subject: [PATCH 020/106] Mazda: add missing CX5 FW versions (#25423) 2022 cx5 signature --- selfdrive/car/mazda/values.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/selfdrive/car/mazda/values.py b/selfdrive/car/mazda/values.py index 7db401e1617779..7e99cccec6f0b6 100644 --- a/selfdrive/car/mazda/values.py +++ b/selfdrive/car/mazda/values.py @@ -67,6 +67,7 @@ class Buttons: b'PX2G-188K2-H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'PX2H-188K2-H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'SH54-188K2-D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', + b'PXFG-188K2-C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], (Ecu.fwdRadar, 0x764, None): [ b'K131-67XK2-F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', @@ -80,6 +81,7 @@ class Buttons: (Ecu.transmission, 0x7e1, None): [ b'PYB2-21PS1-H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'SH51-21PS1-C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', + b'PXFG-21PS1-A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], }, CAR.CX5: { From 45cfcfa3bba6ae75c89114e58de445eaef4c5627 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 12 Aug 2022 23:36:50 -0700 Subject: [PATCH 021/106] Revert "FPv2: fingerprint on all FW combinations" (#25417) * Revert "FPv2: fingerprint on all FW combinations (#25204)" This reverts commit ee081f278b090b5bd4a06f12749fffeb780c6162. * Revert "Revert "FPv2: fingerprint on all FW combinations (#25204)"" This reverts commit bb68b7bc1c28ba8c67f3051b8f99fabc42e85771. * For breaking, match only with current brand's FW * Add comment for fuzzy matching * fingerprint (online) only using FW from that brand * test_fw_query_on_routes fingerprints like online * extend match_fw_to_car to work for test_fw_query_on_routes * Apply suggestions from code review --- selfdrive/car/fw_versions.py | 19 +++++++++++-------- selfdrive/debug/test_fw_query_on_routes.py | 7 +++---- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/selfdrive/car/fw_versions.py b/selfdrive/car/fw_versions.py index 0ed8cc5425d14d..9d2fd11b4550d6 100755 --- a/selfdrive/car/fw_versions.py +++ b/selfdrive/car/fw_versions.py @@ -337,17 +337,21 @@ def match_fw_to_car_exact(fw_versions_dict): return set(candidates.keys()) - set(invalid) -def match_fw_to_car(fw_versions, allow_fuzzy=True): +def match_fw_to_car(fw_versions, allow_exact=True, allow_fuzzy=True): # Try exact matching first - exact_matches = [(True, match_fw_to_car_exact)] + exact_matches = [] + if allow_exact: + exact_matches = [(True, match_fw_to_car_exact)] if allow_fuzzy: exact_matches.append((False, match_fw_to_car_fuzzy)) + brands = get_interface_attr('FW_VERSIONS', ignore_none=True).keys() for exact_match, match_func in exact_matches: - # TODO: For each brand, attempt to fingerprint using only FW returned from its queries + # For each brand, attempt to fingerprint using all FW returned from its queries matches = set() - fw_versions_dict = build_fw_dict(fw_versions, filter_brand=None) - matches |= match_func(fw_versions_dict) + for brand in brands: + fw_versions_dict = build_fw_dict(fw_versions, filter_brand=brand) + matches |= match_func(fw_versions_dict) if len(matches): return exact_match, matches @@ -416,9 +420,8 @@ def get_fw_versions_ordered(logcan, sendcan, ecu_rx_addrs, timeout=0.1, debug=Fa for brand in sorted(brand_matches, key=lambda b: len(brand_matches[b]), reverse=True): car_fw = get_fw_versions(logcan, sendcan, query_brand=brand, timeout=timeout, debug=debug, progress=progress) all_car_fw.extend(car_fw) - - # TODO: Until erroneous FW versions are removed, try to fingerprint on all possible combinations so far - _, matches = match_fw_to_car(all_car_fw, allow_fuzzy=False) + # Try to match using FW returned from this brand only + matches = match_fw_to_car_exact(build_fw_dict(car_fw)) if len(matches) == 1: break diff --git a/selfdrive/debug/test_fw_query_on_routes.py b/selfdrive/debug/test_fw_query_on_routes.py index 0cc674cfc8220f..868813b0feba29 100755 --- a/selfdrive/debug/test_fw_query_on_routes.py +++ b/selfdrive/debug/test_fw_query_on_routes.py @@ -10,7 +10,7 @@ from tools.lib.route import Route from selfdrive.car.interfaces import get_interface_attr from selfdrive.car.car_helpers import interface_names -from selfdrive.car.fw_versions import match_fw_to_car_exact, match_fw_to_car_fuzzy, build_fw_dict +from selfdrive.car.fw_versions import match_fw_to_car NO_API = "NO_API" in os.environ @@ -89,9 +89,8 @@ print("not in supported cars") break - fw_versions_dict = build_fw_dict(car_fw) - exact_matches = match_fw_to_car_exact(fw_versions_dict) - fuzzy_matches = match_fw_to_car_fuzzy(fw_versions_dict) + _, exact_matches = match_fw_to_car(car_fw, allow_exact=True, allow_fuzzy=False) + _, fuzzy_matches = match_fw_to_car(car_fw, allow_exact=False, allow_fuzzy=True) if (len(exact_matches) == 1) and (list(exact_matches)[0] == live_fingerprint): good_exact += 1 From 1f0a435763d6a3aa3fa6b7307450f73379de1185 Mon Sep 17 00:00:00 2001 From: Jason Young <46612682+jyoung8607@users.noreply.github.com> Date: Sat, 13 Aug 2022 14:45:23 -0400 Subject: [PATCH 022/106] VW: Additional PQ / long control prep (#25427) * VW: Longitudinal support prep * minimize diffs * make common button events function * update refs Co-authored-by: Adeeb Shihadeh --- selfdrive/car/volkswagen/carcontroller.py | 1 - selfdrive/car/volkswagen/carstate.py | 28 ++++++++++++++--------- selfdrive/car/volkswagen/interface.py | 23 ++++++++++++++++--- selfdrive/car/volkswagen/values.py | 4 ++-- selfdrive/test/process_replay/ref_commit | 2 +- 5 files changed, 40 insertions(+), 18 deletions(-) diff --git a/selfdrive/car/volkswagen/carcontroller.py b/selfdrive/car/volkswagen/carcontroller.py index 0923ac0313b1ae..2c5830f8682c53 100644 --- a/selfdrive/car/volkswagen/carcontroller.py +++ b/selfdrive/car/volkswagen/carcontroller.py @@ -71,7 +71,6 @@ def update(self, CC, CS, ext_bus): hud_alert = 0 if hud_control.visualAlert in (VisualAlert.steerRequired, VisualAlert.ldw): hud_alert = self.CCP.LDW_MESSAGES["laneAssistTakeOver"] - can_sends.append(self.CCS.create_lka_hud_control(self.packer_pt, CANBUS.pt, CS.ldw_stock_values, CC.enabled, CS.out.steeringPressed, hud_alert, hud_control)) diff --git a/selfdrive/car/volkswagen/carstate.py b/selfdrive/car/volkswagen/carstate.py index 65e3de169c09f1..50be6bf9ad2bd6 100644 --- a/selfdrive/car/volkswagen/carstate.py +++ b/selfdrive/car/volkswagen/carstate.py @@ -3,7 +3,8 @@ from common.conversions import Conversions as CV from selfdrive.car.interfaces import CarStateBase from opendbc.can.parser import CANParser -from selfdrive.car.volkswagen.values import DBC, CANBUS, NetworkLocation, TransmissionType, GearShifter, CarControllerParams +from selfdrive.car.volkswagen.values import DBC, CANBUS, NetworkLocation, TransmissionType, GearShifter, \ + CarControllerParams class CarState(CarStateBase): @@ -12,6 +13,20 @@ def __init__(self, CP): self.CCP = CarControllerParams(CP) self.button_states = {button.event_type: False for button in self.CCP.BUTTONS} + def create_button_events(self, pt_cp, buttons): + button_events = [] + + 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.type = button.event_type + event.pressed = state + button_events.append(event) + self.button_states[button.event_type] = state + + return button_events + def update(self, pt_cp, cam_cp, ext_cp, trans_type): ret = car.CarState.new_message() # Update vehicle speed and acceleration from ABS wheel speeds. @@ -112,17 +127,8 @@ def update(self, pt_cp, cam_cp, ext_cp, trans_type): # Update button states for turn signals and ACC controls, capture all ACC button state/config for passthrough ret.leftBlinker = bool(pt_cp.vl["Blinkmodi_02"]["Comfort_Signal_Left"]) ret.rightBlinker = bool(pt_cp.vl["Blinkmodi_02"]["Comfort_Signal_Right"]) + ret.buttonEvents = self.create_button_events(pt_cp, self.CCP.BUTTONS) self.gra_stock_values = pt_cp.vl["GRA_ACC_01"] - buttonEvents = [] - for button in self.CCP.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.type = button.event_type - event.pressed = state - buttonEvents.append(event) - self.button_states[button.event_type] = state - ret.buttonEvents = buttonEvents # Additional safety checks performed in CarInterface. ret.espDisabled = pt_cp.vl["ESP_21"]["ESP_Tastung_passiv"] != 0 diff --git a/selfdrive/car/volkswagen/interface.py b/selfdrive/car/volkswagen/interface.py index 8bab93d4a3dac5..dfa0a555e33654 100644 --- a/selfdrive/car/volkswagen/interface.py +++ b/selfdrive/car/volkswagen/interface.py @@ -1,7 +1,9 @@ from cereal import car -from selfdrive.car.volkswagen.values import CAR, CANBUS, NetworkLocation, TransmissionType, GearShifter -from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config +from selfdrive.car import STD_CARGO_KG, create_button_enable_events, scale_rot_inertia, scale_tire_stiffness, \ + gen_empty_fingerprint, get_safety_config from selfdrive.car.interfaces import CarInterfaceBase +from selfdrive.car.volkswagen.values import CAR, CANBUS, NetworkLocation, TransmissionType, GearShifter + EventName = car.CarEvent.EventName @@ -52,6 +54,13 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None, disa ret.lateralTuning.pid.kpV = [0.6] ret.lateralTuning.pid.kiV = [0.2] + # Global longitudinal tuning defaults, can be overridden per-vehicle + + ret.pcmCruise = not ret.openpilotLongitudinalControl + ret.longitudinalActuatorDelayUpperBound = 0.5 # s + ret.longitudinalTuning.kpV = [0.1] + ret.longitudinalTuning.kiV = [0.0] + # Per-chassis tuning values, override tuning defaults here if desired if candidate == CAR.ARTEON_MK1: @@ -160,7 +169,8 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None, disa def _update(self, c): ret = self.CS.update(self.cp, self.cp_cam, self.cp_ext, self.CP.transmissionType) - events = self.create_common_events(ret, extra_gears=[GearShifter.eco, GearShifter.sport, GearShifter.manumatic]) + events = self.create_common_events(ret, extra_gears=[GearShifter.eco, GearShifter.sport, GearShifter.manumatic], + pcm_enable=not self.CS.CP.openpilotLongitudinalControl) # Low speed steer alert hysteresis logic if self.CP.minSteerSpeed > 0. and ret.vEgo < (self.CP.minSteerSpeed + 1.): @@ -170,6 +180,13 @@ def _update(self, c): if self.low_speed_alert: events.add(EventName.belowSteerSpeed) + if self.CS.CP.openpilotLongitudinalControl: + if ret.vEgo < self.CP.minEnableSpeed + 2.: + events.add(EventName.belowEngageSpeed) + if c.enabled and ret.vEgo < self.CP.minEnableSpeed: + events.add(EventName.speedTooLow) + + events.events.extend(create_button_enable_events(ret.buttonEvents, pcm_cruise=self.CP.pcmCruise)) ret.events = events.to_msg() return ret diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py index af0139e7bb1af2..785a70d2dab3dc 100755 --- a/selfdrive/car/volkswagen/values.py +++ b/selfdrive/car/volkswagen/values.py @@ -26,9 +26,9 @@ def __init__(self, CP): self.STEER_MAX = 300 # Max heading control assist torque 3.00 Nm self.STEER_DRIVER_MULTIPLIER = 3 # weight driver torque heavily self.STEER_DRIVER_FACTOR = 1 # from dbc - + can_define = CANDefine(DBC[CP.carFingerprint]["pt"]) - + if True: # pylint: disable=using-constant-test self.LDW_STEP = 10 # LDW_02 message frequency 10Hz self.STEER_DRIVER_ALLOWANCE = 80 # Driver intervention threshold 0.8 Nm diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 260e917fb1f40a..67838d292163a4 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -3c89454df9cf2f25a5759d523a8c595e69865505 \ No newline at end of file +60aa8580527e513fe25100a348ee4c5971717960 \ No newline at end of file From 65f230e6f607469d187da0f3d84a2759c48d3711 Mon Sep 17 00:00:00 2001 From: Jason Shuler Date: Sat, 13 Aug 2022 21:53:45 -0400 Subject: [PATCH 023/106] ubuntu_setup.sh detect base ubuntu version for variant distros (#25433) ubuntu_setup detect base version --- tools/ubuntu_setup.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/ubuntu_setup.sh b/tools/ubuntu_setup.sh index 379df37adb6c84..863b853718fa56 100755 --- a/tools/ubuntu_setup.sh +++ b/tools/ubuntu_setup.sh @@ -108,7 +108,11 @@ if [ -f "/etc/os-release" ]; then if [[ ! $REPLY =~ ^[Yy]$ ]]; then exit 1 fi - install_ubuntu_focal_requirements + if [ "$UBUNTU_CODENAME" = "jammy" ]; then + install_ubuntu_jammy_requirements + else + install_ubuntu_focal_requirements + fi esac else echo "No /etc/os-release in the system" From ee3d72a1e3be3247fcc2a853a29fdf951242b04d Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sat, 13 Aug 2022 23:28:44 -0700 Subject: [PATCH 024/106] Create SECURITY.md --- SECURITY.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000000000..8b66082bf241e6 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,5 @@ +# Security Policy + +## Reporting a Vulnerability + +Suspected vulnerabilities can be reported to both `adeeb@comma.ai` and `security@comma.ai`. From f341df006a002a47034787673893f930caa81b53 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 15 Aug 2022 02:13:09 -0700 Subject: [PATCH 025/106] GM: move set speed scaling to DBC (#25422) * Move scaling into DBC for GM cruise setpoint * bump opendbc * no int * Update refs * Update ref_commit --- opendbc | 2 +- selfdrive/car/gm/carstate.py | 2 +- selfdrive/car/gm/gmcan.py | 3 +-- selfdrive/test/process_replay/ref_commit | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/opendbc b/opendbc index 48856851716219..c6665ed11b8d8c 160000 --- a/opendbc +++ b/opendbc @@ -1 +1 @@ -Subproject commit 488568517162194fbb2aa45d3dba4c6af663a883 +Subproject commit c6665ed11b8d8c998e46f8dbee30e70a7d451e5e diff --git a/selfdrive/car/gm/carstate.py b/selfdrive/car/gm/carstate.py index e89ece198e1d98..0bda7edad97ced 100644 --- a/selfdrive/car/gm/carstate.py +++ b/selfdrive/car/gm/carstate.py @@ -80,7 +80,7 @@ def update(self, pt_cp, cam_cp, loopback_cp): ret.cruiseState.enabled = pt_cp.vl["AcceleratorPedal2"]["CruiseState"] != AccState.OFF ret.cruiseState.standstill = pt_cp.vl["AcceleratorPedal2"]["CruiseState"] == AccState.STANDSTILL if self.CP.networkLocation == NetworkLocation.fwdCamera: - ret.cruiseState.speed = (cam_cp.vl["ASCMActiveCruiseControlStatus"]["ACCSpeedSetpoint"] / 16) * CV.KPH_TO_MS + ret.cruiseState.speed = cam_cp.vl["ASCMActiveCruiseControlStatus"]["ACCSpeedSetpoint"] * CV.KPH_TO_MS return ret diff --git a/selfdrive/car/gm/gmcan.py b/selfdrive/car/gm/gmcan.py index 98265e8c6b68f0..3a10c4d9dab4ac 100644 --- a/selfdrive/car/gm/gmcan.py +++ b/selfdrive/car/gm/gmcan.py @@ -63,8 +63,7 @@ def create_friction_brake_command(packer, bus, apply_brake, idx, near_stop, at_f return packer.make_can_msg("EBCMFrictionBrakeCmd", bus, values) def create_acc_dashboard_command(packer, bus, acc_engaged, target_speed_kph, lead_car_in_sight, fcw): - # Not a bit shift, dash can round up based on low 4 bits. - target_speed = int(target_speed_kph * 16) & 0xfff + target_speed = min(target_speed_kph, 255) values = { "ACCAlwaysOne" : 1, diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 67838d292163a4..8aa80d6b7946f1 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -60aa8580527e513fe25100a348ee4c5971717960 \ No newline at end of file +118d78e2040103c00b4bfcc875fcdcd6a15e2211 From 5b1ba4f1357ac7f385ee47c78b38cfb81bef42ab Mon Sep 17 00:00:00 2001 From: Chris Souers Date: Mon, 15 Aug 2022 14:37:24 -0400 Subject: [PATCH 026/106] Lateral planner: Don't prompt/initiate lane changes if lateral control is not active (#25436) * Don't set lane change events if we're not able to steer. * more specific variable name * update process replay socket config Co-authored-by: Adeeb Shihadeh --- selfdrive/controls/lib/desire_helper.py | 4 ++-- selfdrive/controls/lib/lateral_planner.py | 2 +- selfdrive/controls/plannerd.py | 2 +- selfdrive/test/process_replay/process_replay.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/selfdrive/controls/lib/desire_helper.py b/selfdrive/controls/lib/desire_helper.py index 978c386530aa24..19ab2da214caef 100644 --- a/selfdrive/controls/lib/desire_helper.py +++ b/selfdrive/controls/lib/desire_helper.py @@ -40,12 +40,12 @@ def __init__(self): self.prev_one_blinker = False self.desire = log.LateralPlan.Desire.none - def update(self, carstate, active, lane_change_prob): + def update(self, carstate, lateral_active, lane_change_prob): v_ego = carstate.vEgo one_blinker = carstate.leftBlinker != carstate.rightBlinker below_lane_change_speed = v_ego < LANE_CHANGE_SPEED_MIN - if not active or self.lane_change_timer > LANE_CHANGE_TIME_MAX: + if not lateral_active or self.lane_change_timer > LANE_CHANGE_TIME_MAX: self.lane_change_state = LaneChangeState.off self.lane_change_direction = LaneChangeDirection.none else: diff --git a/selfdrive/controls/lib/lateral_planner.py b/selfdrive/controls/lib/lateral_planner.py index dda4f18a498458..29dfc771111c92 100644 --- a/selfdrive/controls/lib/lateral_planner.py +++ b/selfdrive/controls/lib/lateral_planner.py @@ -52,7 +52,7 @@ def update(self, sm): # Lane change logic lane_change_prob = self.LP.l_lane_change_prob + self.LP.r_lane_change_prob - self.DH.update(sm['carState'], sm['controlsState'].active, lane_change_prob) + self.DH.update(sm['carState'], sm['carControl'].latActive, lane_change_prob) # Turn off lanes during lane change if self.DH.desire == log.LateralPlan.Desire.laneChangeRight or self.DH.desire == log.LateralPlan.Desire.laneChangeLeft: diff --git a/selfdrive/controls/plannerd.py b/selfdrive/controls/plannerd.py index 06807b2a5cb84c..ca7523f2eeffe3 100755 --- a/selfdrive/controls/plannerd.py +++ b/selfdrive/controls/plannerd.py @@ -25,7 +25,7 @@ def plannerd_thread(sm=None, pm=None): lateral_planner = LateralPlanner(CP, use_lanelines=use_lanelines, wide_camera=wide_camera) if sm is None: - sm = messaging.SubMaster(['carState', 'controlsState', 'radarState', 'modelV2'], + sm = messaging.SubMaster(['carControl', 'carState', 'controlsState', 'radarState', 'modelV2'], poll=['radarState', 'modelV2'], ignore_avg_freq=['radarState']) if pm is None: diff --git a/selfdrive/test/process_replay/process_replay.py b/selfdrive/test/process_replay/process_replay.py index 0c642cde178999..32a3c2f3bb0bf7 100755 --- a/selfdrive/test/process_replay/process_replay.py +++ b/selfdrive/test/process_replay/process_replay.py @@ -280,7 +280,7 @@ def laika_rcv_callback(msg, CP, cfg, fsm): proc_name="plannerd", pub_sub={ "modelV2": ["lateralPlan", "longitudinalPlan"], - "carState": [], "controlsState": [], "radarState": [], + "carControl": [], "carState": [], "controlsState": [], "radarState": [], }, ignore=["logMonoTime", "valid", "longitudinalPlan.processingDelay", "longitudinalPlan.solverExecutionTime", "lateralPlan.solverExecutionTime"], init_callback=get_car_params, From 42e4efe706ab41958dc1877701fc947149baf053 Mon Sep 17 00:00:00 2001 From: AlexandreSato <66435071+AlexandreSato@users.noreply.github.com> Date: Mon, 15 Aug 2022 16:14:29 -0300 Subject: [PATCH 027/106] Multilang: add Portuguese (Brazil) translation (#25287) * Add Portuguese-Brazil translations * Fixing some Japanese I used as a base. * Add pt_BR translation * Add QM file * multilang: Fix typo and missing pt_BR translation * fix typos in calibration translation * pt_BR new translations * fix translations * update qm * add Thai translation tkx tape#7233 * fix pt_BR translation * improve pt_BR translation * connect means connection not connected * update * plurals and typo * fix unitTest error * Add pt badge * Add test for missing plural translations * Make sure this doesn't test for translation completeness, we skip that test * fix missing plurals Co-authored-by: Shane Smiskol --- selfdrive/ui/tests/test_translations.py | 18 + selfdrive/ui/translations/README.md | 1 + selfdrive/ui/translations/languages.json | 1 + selfdrive/ui/translations/main_pt.ts | 1307 ++++++++++++++++++++++ 4 files changed, 1327 insertions(+) create mode 100644 selfdrive/ui/translations/main_pt.ts diff --git a/selfdrive/ui/tests/test_translations.py b/selfdrive/ui/tests/test_translations.py index 526dde93e85f75..7da4ec0d6e5a2e 100755 --- a/selfdrive/ui/tests/test_translations.py +++ b/selfdrive/ui/tests/test_translations.py @@ -3,6 +3,7 @@ import os import shutil import unittest +import xml.etree.ElementTree as ET from selfdrive.ui.update_translations import TRANSLATIONS_DIR, LANGUAGES_FILE, update_translations @@ -64,6 +65,23 @@ def test_vanished_translations(self): self.assertTrue(b"" not in cur_translations, f"{file} ({name}) translation file has obsolete translations. Run selfdrive/ui/update_translations.py --vanish to remove them") + def test_plural_translations(self): + for name, file in self.translation_files.items(): + with self.subTest(name=name, file=file): + tr_xml = ET.parse(os.path.join(TRANSLATIONS_DIR, f"{file}.ts")) + + for context in tr_xml.getroot(): + for message in context.iterfind("message"): + if message.get("numerus") == "yes": + translation = message.find("translation") + numerusform = translation.findall("numerusform") + + # Do not assert finished translations + if translation.get("type") == "unfinished": + continue + + self.assertNotIn(None, [x.text for x in numerusform], "Ensure all plural translation forms are completed.") + if __name__ == "__main__": unittest.main() diff --git a/selfdrive/ui/translations/README.md b/selfdrive/ui/translations/README.md index 07f1a4825c3c64..349b4847afc4f8 100644 --- a/selfdrive/ui/translations/README.md +++ b/selfdrive/ui/translations/README.md @@ -1,6 +1,7 @@ # Multilanguage [![language](https://raw.githubusercontent.com/commaai/openpilot/badges/translation_badge_main_en.svg)](https://github.com/commaai/openpilot/blob/master/selfdrive/ui/translations/main_en.ts) +[![language](https://raw.githubusercontent.com/commaai/openpilot/badges/translation_badge_main_pt.svg)](https://github.com/commaai/openpilot/blob/master/selfdrive/ui/translations/main_pt.ts) [![language](https://raw.githubusercontent.com/commaai/openpilot/badges/translation_badge_main_zh-CHT.svg)](https://github.com/commaai/openpilot/blob/master/selfdrive/ui/translations/main_zh-CHT.ts) [![language](https://raw.githubusercontent.com/commaai/openpilot/badges/translation_badge_main_zh-CHS.svg)](https://github.com/commaai/openpilot/blob/master/selfdrive/ui/translations/main_zh-CHS.ts) [![language](https://raw.githubusercontent.com/commaai/openpilot/badges/translation_badge_main_ko.svg)](https://github.com/commaai/openpilot/blob/master/selfdrive/ui/translations/main_ko.ts) diff --git a/selfdrive/ui/translations/languages.json b/selfdrive/ui/translations/languages.json index f52a28ef9a2294..2559b2d26d502b 100644 --- a/selfdrive/ui/translations/languages.json +++ b/selfdrive/ui/translations/languages.json @@ -1,5 +1,6 @@ { "English": "main_en", + "Português": "main_pt", "中文(繁體)": "main_zh-CHT", "中文(简体)": "main_zh-CHS", "한국어": "main_ko", diff --git a/selfdrive/ui/translations/main_pt.ts b/selfdrive/ui/translations/main_pt.ts new file mode 100644 index 00000000000000..4c05f973b2f8af --- /dev/null +++ b/selfdrive/ui/translations/main_pt.ts @@ -0,0 +1,1307 @@ + + + + + AbstractAlert + + + Close + Fechar + + + + Snooze Update + Adiar Atualização + + + + Reboot and Update + Reiniciar e Atualizar + + + + AdvancedNetworking + + + Back + Voltar + + + + Enable Tethering + Ativar Theter + + + + Tethering Password + Senha Thetering + + + + + EDIT + EDITAR + + + + Enter new tethering password + Insira nova senha thetering + + + + IP Address + IP Endereço + + + + Enable Roaming + Ativar Roaming + + + + APN Setting + APN Config + + + + Enter APN + Insira APN + + + + leave blank for automatic configuration + deixe em branco para configuração automática + + + + ConfirmationDialog + + + + Ok + OK + + + + Cancel + Cancelar + + + + DeclinePage + + + You must accept the Terms and Conditions in order to use openpilot. + Você precisa aceitar os Termos e Condições para utilizar openpilot. + + + + Back + Voltar + + + + Decline, uninstall %1 + Rejeitar, desintalar %1 + + + + DevicePanel + + + Dongle ID + Dongle ID + + + + N/A + N/A + + + + Serial + Serial + + + + Driver Camera + Câmera Motorista + + + + PREVIEW + PREVISUAL + + + + Preview the driver facing camera to ensure that driver monitoring has good visibility. (vehicle must be off) + Pré-visualizar a câmera voltada para o motorista para garantir que monitor tem uma boa visibilidade (veículo precisa estar desligado) + + + + Reset Calibration + Limpar Calibragem + + + + RESET + RESET + + + + Are you sure you want to reset calibration? + Tem certeza que quer limpar calibragem? + + + + Review Training Guide + Revisar o Treinamento + + + + REVIEW + REVISAR + + + + Review the rules, features, and limitations of openpilot + Revisar regras, features e limitações do openpilot + + + + Are you sure you want to review the training guide? + Tem certeza que quer rever o treinamento? + + + + Regulatory + Regulatório + + + + VIEW + VER + + + + Change Language + Mudar Língua + + + + CHANGE + MUDAR + + + + Select a language + Selecione uma linguagem + + + + Reboot + Reiniciar + + + + Power Off + Desligar + + + + openpilot requires the device to be mounted within 4° left or right and within 5° up or 8° down. openpilot is continuously calibrating, resetting is rarely required. + o openpilot requer que o dispositivo seja montado dentro de 4° esquerda ou direita e dentro de 5° para cima ou 8° para baixo. o openpilot está continuamente calibrando, a redefinição raramente é necessária. + + + + Your device is pointed %1° %2 and %3° %4. + Seu dispositivo está montado %1° %2 e %3° %4. + + + + down + baixo + + + + up + cima + + + + left + esquerda + + + + right + direita + + + + Are you sure you want to reboot? + Tem certeza que quer reiniciar? + + + + Disengage to Reboot + Desacione para Reiniciar + + + + Are you sure you want to power off? + Tem certeza que quer desligar? + + + + Disengage to Power Off + Desacione para Desligar + + + + DriveStats + + + Drives + Dirigidas + + + + Hours + Horas + + + + ALL TIME + TOTAL + + + + PAST WEEK + SEMANA PASSADA + + + + KM + KM + + + + Miles + Milhas + + + + DriverViewScene + + + camera starting + camera iniciando + + + + InputDialog + + + Cancel + Cancelar + + + + Need at least %n character(s)! + + Necessita no mínimo %n caractere! + Necessita no mínimo %n caracteres! + + + + + Installer + + + Installing... + Instalando... + + + + Receiving objects: + Recebendo objetos: + + + + Resolving deltas: + Resolvendo deltas: + + + + Updating files: + Atualizando arquivos: + + + + MapETA + + + eta + eta + + + + min + min + + + + hr + hr + + + + km + km + + + + mi + mi + + + + MapInstructions + + + km + km + + + + m + m + + + + mi + milha + + + + ft + pés + + + + MapPanel + + + Current Destination + Destino Atual + + + + CLEAR + LIMPAR + + + + Recent Destinations + Destinos Recentes + + + + Try the Navigation Beta + Experimente a Navegação Beta + + + + Get turn-by-turn directions displayed and more with a comma +prime subscription. Sign up now: https://connect.comma.ai + Obtenha instruções passo a passo exibidas e muito mais com +uma assinatura prime Increva-se agora:https://connect.comma.ai + + + + No home +location set + Sem local +residência definido + + + + No work +location set + Sem local +trabalho definido + + + + no recent destinations + sem destinos recentes + + + + MapWindow + + + Map Loading + Carregando Mapa + + + + Waiting for GPS + Esperando por GPS + + + + MultiOptionDialog + + + Select + Selecione + + + + Cancel + Cancelar + + + + Networking + + + Advanced + Avançado + + + + Enter password + Insira a senha + + + + + for "%1" + para "%1" + + + + Wrong password + Senha incorreta + + + + NvgWindow + + + km/h + km/h + + + + mph + mph + + + + + MAX + LIMITE + + + + + SPEED + MAX + + + + + LIMIT + VELO + + + + OffroadHome + + + UPDATE + ATUALIZAÇÃO + + + + ALERTS + ALERTAS + + + + ALERT + ALERTA + + + + PairingPopup + + + Pair your device to your comma account + Pareie seu dispositivo a sua conta comma + + + + Go to https://connect.comma.ai on your phone + navegue até https://connect.comma.ai no seu telefone + + + + Click "add new device" and scan the QR code on the right + Clique "add new device" e escaneie o QR code a seguir + + + + Bookmark connect.comma.ai to your home screen to use it like an app + Salve connect.comma.ai como sua página inicial para utilizar com um app + + + + PrimeAdWidget + + + Upgrade Now + Atualizar Agora + + + + Become a comma prime member at connect.comma.ai + Torne-se um membro comma prime em connect.comma.ai + + + + PRIME FEATURES: + PRIME FEATURES: + + + + Remote access + Acesso remoto + + + + 1 year of storage + 1 ano de armazenamento + + + + Developer perks + Benefícios para desenvolvedor + + + + PrimeUserWidget + + + ✓ SUBSCRIBED + ✓ INSCRITO + + + + comma prime + comma prime + + + + CONNECT.COMMA.AI + CONNECT.COMMA.AI + + + + COMMA POINTS + PONTOS COMMA + + + + QObject + + + Reboot + Reiniciar + + + + Exit + Sair + + + + dashcam + dashcam + + + + openpilot + openpilot + + + + %n minute(s) ago + + há %n minuto + há %n minutos + + + + + %n hour(s) ago + + há %n hora + há %n horas + + + + + %n day(s) ago + + há %n dia + há %n dias + + + + + Reset + + + Reset failed. Reboot to try again. + Reset falhou. Reinicie para tentar novamente. + + + + Are you sure you want to reset your device? + Tem certeza que quer resetar seu dispositivo? + + + + Resetting device... + Resetando dispositivo... + + + + System Reset + Resetar Sistema + + + + System reset triggered. Press confirm to erase all content and settings. Press cancel to resume boot. + Solicitado reset do sistema. Confirme para apagar todo conteúdo e configurações. Aperte cancelar para continuar boot. + + + + Cancel + Cancelar + + + + Reboot + Reiniciar + + + + Confirm + Confirmar + + + + Unable to mount data partition. Press confirm to reset your device. + Não foi possível montar a partição de dados. Pressione confirmar para resetar seu dispositivo. + + + + RichTextDialog + + + Ok + Ok + + + + SettingsWindow + + + × + × + + + + Device + Dispositivo + + + + + Network + Rede + + + + Toggles + Ajustes + + + + Software + Software + + + + Navigation + Navegação + + + + Setup + + + WARNING: Low Voltage + ALERTA: Baixa Voltagem + + + + Power your device in a car with a harness or proceed at your own risk. + Ligue seu dispositivo em um carro com um chicote ou prossiga por sua conta e risco. + + + + Power off + Desligar + + + + + + Continue + Continuar + + + + Getting Started + Começando + + + + Before we get on the road, let’s finish installation and cover some details. + Antes de pegarmos a estrada, vamos terminar a instalação e cobrir alguns detalhes. + + + + Connect to Wi-Fi + Conectar ao Wi-Fi + + + + + Back + Voltar + + + + Continue without Wi-Fi + Continuar sem Wi-Fi + + + + Waiting for internet + Esperando pela internet + + + + Choose Software to Install + Escolher Software para Instalar + + + + Dashcam + Dashcam + + + + Custom Software + Sofware Customizado + + + + Enter URL + Preencher URL + + + + for Custom Software + para o Software Customizado + + + + Downloading... + Baixando... + + + + Download Failed + Download Falhou + + + + Ensure the entered URL is valid, and the device’s internet connection is good. + Garanta que a URL inserida é valida, e uma boa conexão à internet. + + + + Reboot device + Reiniciar Dispositivo + + + + Start over + Inicializar + + + + SetupWidget + + + Finish Setup + Terminar Configuração + + + + Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer. + Pareie seu dispositivo com comma connect (connect.comma.ai) e reivindique sua oferta de comma prime. + + + + Pair device + Parear dispositivo + + + + Sidebar + + + + CONNECT + CONEXÃO + + + + OFFLINE + DESCONEC + + + + + ONLINE + CONECTADO + + + + ERROR + ERRO + + + + + + TEMP + TEMP + + + + HIGH + ALTA + + + + GOOD + BOA + + + + OK + OK + + + + VEHICLE + VEÍCULO + + + + NO + SEM + + + + PANDA + PANDA + + + + GPS + GPS + + + + SEARCH + PROCURA + + + + -- + -- + + + + Wi-Fi + Wi-Fi + + + + ETH + ETH + + + + 2G + 2G + + + + 3G + 3G + + + + LTE + LTE + + + + 5G + 5G + + + + SoftwarePanel + + + Git Branch + Ramo Git + + + + Git Commit + Commit Git + + + + OS Version + Versão do Sistema + + + + Version + Versão + + + + Last Update Check + Verificação da última atualização + + + + The last time openpilot successfully checked for an update. The updater only runs while the car is off. + A última vez que o openpilot verificou com sucesso uma atualização. O atualizador só funciona com o carro desligado. + + + + Check for Update + Verifique atualizações + + + + CHECKING + VERIFICANDO + + + + Switch Branch + Trocar Ramo + + + + ENTER + INSERIR + + + + + The new branch will be pulled the next time the updater runs. + O novo ramo será aplicado na próxima execução do atualizador. + + + + Enter branch name + Inserir o nome do ramo + + + + UNINSTALL + DESINSTALAR + + + + Uninstall %1 + Desintalando %1 + + + + Are you sure you want to uninstall? + Tem certeza que quer desinstalar? + + + + failed to fetch update + falha ao buscar atualização + + + + + CHECK + VERIFICAR + + + + SshControl + + + SSH Keys + Chave SSH + + + + Warning: This grants SSH access to all public keys in your GitHub settings. Never enter a GitHub username other than your own. A comma employee will NEVER ask you to add their GitHub username. + Aviso: isso concede acesso SSH a todas as chaves públicas nas configurações do GitHub. Nunca insira um nome de usuário do GitHub que não seja o seu. Um funcionário da comma NUNCA pedirá que você adicione seu nome de usuário do GitHub. + + + + + ADD + ADICIONAR + + + + Enter your GitHub username + Insira seu nome de usuário do GitHub + + + + LOADING + CARREGANDO + + + + REMOVE + REMOVER + + + + Username '%1' has no keys on GitHub + Usuário "%1” não possui chaves no GitHub + + + + Request timed out + A solicitação expirou + + + + Username '%1' doesn't exist on GitHub + Usuário '%1' não existe no GitHub + + + + SshToggle + + + Enable SSH + Habilitar SSH + + + + TermsPage + + + Terms & Conditions + Termos & Condições + + + + Decline + Declinar + + + + Scroll to accept + Role para aceitar + + + + Agree + Concordo + + + + TogglesPanel + + + Enable openpilot + Ativar openpilot + + + + Use the openpilot system for adaptive cruise control and lane keep driver assistance. Your attention is required at all times to use this feature. Changing this setting takes effect when the car is powered off. + Use o sistema openpilot para controle de cruzeiro adaptativo e assistência ao motorista de manutenção de faixa. Sua atenção é necessária o tempo todo para usar esse recurso. A alteração desta configuração tem efeito quando o carro é desligado. + + + + Enable Lane Departure Warnings + Ativar Avisos de Saída de Faixa + + + + Receive alerts to steer back into the lane when your vehicle drifts over a detected lane line without a turn signal activated while driving over 31 mph (50 km/h). + Receba alertas para voltar para a pista se o seu veículo sair da faixa e a seta não tiver sido acionada previamente quando em velocidades superiores a 50 km/h. + + + + Use Metric System + Usar Sistema Métrico + + + + Display speed in km/h instead of mph. + Exibir velocidade em km/h invés de mph. + + + + Record and Upload Driver Camera + Gravar e Upload Câmera Motorista + + + + Upload data from the driver facing camera and help improve the driver monitoring algorithm. + Upload dados da câmera voltada para o motorista e ajude a melhorar o algoritmo de monitoramentor. + + + + Disengage On Accelerator Pedal + Desacionar Com Pedal Do Acelerador + + + + When enabled, pressing the accelerator pedal will disengage openpilot. + Quando ativado, pressionar o pedal do acelerador desacionará o openpilot. + + + + Show ETA in 24h format + Mostrar ETA em formato 24h + + + + Use 24h format instead of am/pm + Use o formato 24h em vez de am/pm + + + + Show Map on Left Side of UI + Exibir Mapa no Lado Esquerdo + + + + Show map on left side when in split screen view. + Exibir mapa do lado esquerdo quando a tela for dividida. + + + + openpilot Longitudinal Control + openpilot Controle Longitudinal + + + + openpilot will disable the car's radar and will take over control of gas and brakes. Warning: this disables AEB! + openpilot desativará o radar do carro e assumirá o controle do acelerador e freios. Atenção: isso desativa AEB! + + + + Updater + + + Update Required + Atualização Necessária + + + + An operating system update is required. Connect your device to Wi-Fi for the fastest update experience. The download size is approximately 1GB. + Uma atualização do sistema operacional é necessária. Conecte seu dispositivo ao Wi-Fi para a experiência de atualização mais rápida. O tamanho do download é de aproximadamente 1GB. + + + + Connect to Wi-Fi + Conecte-se ao Wi-Fi + + + + Install + Instalar + + + + Back + Voltar + + + + Loading... + Carregando... + + + + Reboot + Reiniciar + + + + Update failed + Falha na atualização + + + + WifiUI + + + + Scanning for networks... + Procurando redes... + + + + CONNECTING... + CONECTANDO... + + + + FORGET + ESQUECER + + + + Forget Wi-Fi Network "%1"? + Esquecer Rede Wi-Fi "%1"? + + + From 370f58b7d677ee85249122b60362f4c323a30e95 Mon Sep 17 00:00:00 2001 From: Achilles308 <85138080+Achilles308@users.noreply.github.com> Date: Mon, 15 Aug 2022 16:49:43 -0400 Subject: [PATCH 028/106] UI: fix inconsistent capitalization in toggle title (#25441) --- selfdrive/ui/qt/offroad/settings.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index e6e21bd8d3a4a6..5e0e87e64d0deb 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -62,7 +62,7 @@ TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) { #ifdef ENABLE_MAPS { "NavSettingTime24h", - tr("Show ETA in 24h format"), + tr("Show ETA in 24h Format"), tr("Use 24h format instead of am/pm"), "../assets/offroad/icon_metric.png", }, From e24da95120aad859e8946c46ace7ee2e09b856e7 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 15 Aug 2022 15:12:46 -0700 Subject: [PATCH 029/106] Fix translations --- selfdrive/ui/translations/main_ja.ts | 2 +- selfdrive/ui/translations/main_ko.ts | 2 +- selfdrive/ui/translations/main_pt.ts | 2 +- selfdrive/ui/translations/main_zh-CHS.ts | 2 +- selfdrive/ui/translations/main_zh-CHT.ts | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/selfdrive/ui/translations/main_ja.ts b/selfdrive/ui/translations/main_ja.ts index 111fe9184e445e..b66bc4b80d6660 100644 --- a/selfdrive/ui/translations/main_ja.ts +++ b/selfdrive/ui/translations/main_ja.ts @@ -1204,7 +1204,7 @@ location set
- Show ETA in 24h format + Show ETA in 24h Format 24時間表示 diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts index cd9c73c34d5810..a67b957e832534 100644 --- a/selfdrive/ui/translations/main_ko.ts +++ b/selfdrive/ui/translations/main_ko.ts @@ -1204,7 +1204,7 @@ location set - Show ETA in 24h format + Show ETA in 24h Format 24시간 형식으로 도착예정시간 표시 diff --git a/selfdrive/ui/translations/main_pt.ts b/selfdrive/ui/translations/main_pt.ts index 4c05f973b2f8af..912afa38a43c10 100644 --- a/selfdrive/ui/translations/main_pt.ts +++ b/selfdrive/ui/translations/main_pt.ts @@ -1208,7 +1208,7 @@ trabalho definido - Show ETA in 24h format + Show ETA in 24h Format Mostrar ETA em formato 24h diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts index cb09e8c2effc93..1ed96422b060f7 100644 --- a/selfdrive/ui/translations/main_zh-CHS.ts +++ b/selfdrive/ui/translations/main_zh-CHS.ts @@ -1202,7 +1202,7 @@ location set - Show ETA in 24h format + Show ETA in 24h Format 以24小时格式显示预计到达时间 diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts index 58e921b313562f..4f5c37764f87e0 100644 --- a/selfdrive/ui/translations/main_zh-CHT.ts +++ b/selfdrive/ui/translations/main_zh-CHT.ts @@ -1204,7 +1204,7 @@ location set - Show ETA in 24h format + Show ETA in 24h Format 預計到達時間單位改用 24 小時制 From 07320fb8a83e9f7340b8db731be623fa6f8611b2 Mon Sep 17 00:00:00 2001 From: MadBrad <526878+MadBrad@users.noreply.github.com> Date: Mon, 15 Aug 2022 18:29:46 -0400 Subject: [PATCH 030/106] Car docs: add video link for 2022 Chevy Bolt EUV (#25443) * Car docs: Add video link for 2022 Chevy Bolt EUV * New video added --- selfdrive/car/gm/values.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/car/gm/values.py b/selfdrive/car/gm/values.py index 75a5e96f92d916..cb9aff172b4ef6 100644 --- a/selfdrive/car/gm/values.py +++ b/selfdrive/car/gm/values.py @@ -83,7 +83,7 @@ class GMCarInfo(CarInfo): CAR.ACADIA: GMCarInfo("GMC Acadia 2018", video_link="https://www.youtube.com/watch?v=0ZN6DdsBUZo"), CAR.BUICK_REGAL: GMCarInfo("Buick Regal Essence 2018"), CAR.ESCALADE_ESV: GMCarInfo("Cadillac Escalade ESV 2016", "Adaptive Cruise Control (ACC) & LKAS"), - CAR.BOLT_EUV: GMCarInfo("Chevrolet Bolt EUV 2022-23", "Premier/Premier Redline Trim", footnotes=[], harness=Harness.gm), + CAR.BOLT_EUV: GMCarInfo("Chevrolet Bolt EUV 2022-23", "Premier/Premier Redline Trim", video_link="https://youtu.be/xvwzGMUA210", footnotes=[], harness=Harness.gm), } From 574021a0acd7f632b902efe858a22cb7b66b67e6 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 15 Aug 2022 21:44:15 -0700 Subject: [PATCH 031/106] Car docs: test for missing harnesses (#25444) * All cars must have a harness * except body * skip test * Q for IoniQ --- selfdrive/car/docs_definitions.py | 3 +-- selfdrive/car/hyundai/values.py | 2 +- selfdrive/car/tests/test_docs.py | 10 +++++++++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/selfdrive/car/docs_definitions.py b/selfdrive/car/docs_definitions.py index 0605ec1f2aff03..65dbe4c626ac7c 100644 --- a/selfdrive/car/docs_definitions.py +++ b/selfdrive/car/docs_definitions.py @@ -92,8 +92,6 @@ def init(self, CP: car.CarParams, all_footnotes: Dict[Enum, int]): else: self.min_steer_speed = CP.minSteerSpeed - assert self.harness is not None, f"{CP.carFingerprint}: Need to specify car harness" - # TODO: set all the min enable speeds in carParams correctly and remove this if self.min_enable_speed is None: self.min_enable_speed = CP.minEnableSpeed @@ -212,6 +210,7 @@ class Harness(Enum): hyundai_n = "Hyundai N" hyundai_o = "Hyundai O" hyundai_p = "Hyundai P" + hyundai_q = "Hyundai Q" custom = "Developer" obd_ii = "OBD-II" gm = "GM" diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index 8879931b20070a..625b2630f3e3f8 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -127,7 +127,7 @@ class HyundaiCarInfo(CarInfo): ], CAR.VELOSTER: HyundaiCarInfo("Hyundai Veloster 2019-20", "Smart Cruise Control (SCC)", min_enable_speed=5. * CV.MPH_TO_MS, harness=Harness.hyundai_e), CAR.SONATA_HYBRID: HyundaiCarInfo("Hyundai Sonata Hybrid 2020-22", "All", harness=Harness.hyundai_a), - CAR.IONIQ_5: HyundaiCarInfo("Hyundai Ioniq 5 2022", "Highway Driving Assist II", harness=Harness.none), + CAR.IONIQ_5: HyundaiCarInfo("Hyundai Ioniq 5 2022", "Highway Driving Assist II", harness=Harness.hyundai_q), # Kia CAR.KIA_FORTE: [ diff --git a/selfdrive/car/tests/test_docs.py b/selfdrive/car/tests/test_docs.py index e31ad0d5c1325c..84c6b6e52062cc 100755 --- a/selfdrive/car/tests/test_docs.py +++ b/selfdrive/car/tests/test_docs.py @@ -4,7 +4,7 @@ from selfdrive.car.car_helpers import interfaces, get_interface_attr from selfdrive.car.docs import CARS_MD_OUT, CARS_MD_TEMPLATE, generate_cars_md, get_all_car_info -from selfdrive.car.docs_definitions import Column, Star +from selfdrive.car.docs_definitions import Column, Harness, Star from selfdrive.car.honda.values import CAR as HONDA @@ -56,6 +56,14 @@ def test_year_format(self): with self.subTest(car=car): self.assertIsNone(re.search(r"\d{4}-\d{4}", car.name), f"Format years correctly: {car.name}") + def test_harnesses(self): + for car in self.all_cars: + with self.subTest(car=car): + if car.name == "comma body": + raise unittest.SkipTest + + self.assertNotIn(car.harness, [None, Harness.none], f"Need to specify car harness: {car.name}") + if __name__ == "__main__": unittest.main() From df48ab9ee28a28173e3e84f6e7c5da585469de28 Mon Sep 17 00:00:00 2001 From: khoi <6994441+khoi@users.noreply.github.com> Date: Tue, 16 Aug 2022 11:46:56 +0700 Subject: [PATCH 032/106] Car docs: add video link for Hyundai Santa Fe 2022 (#25449) * Add video link for Santa Fe 2022 * Update selfdrive/car/hyundai/values.py Co-authored-by: Shane Smiskol --- selfdrive/car/hyundai/values.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index 625b2630f3e3f8..afd17b86ad4322 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -112,7 +112,7 @@ class HyundaiCarInfo(CarInfo): CAR.KONA_EV_2022: HyundaiCarInfo("Hyundai Kona Electric 2022", "Smart Cruise Control (SCC)", harness=Harness.hyundai_o), CAR.KONA_HEV: HyundaiCarInfo("Hyundai Kona Hybrid 2020", video_link="https://youtu.be/0dwpAHiZgFo", harness=Harness.hyundai_i), CAR.SANTA_FE: HyundaiCarInfo("Hyundai Santa Fe 2019-20", "All", harness=Harness.hyundai_d), - CAR.SANTA_FE_2022: HyundaiCarInfo("Hyundai Santa Fe 2021-22", "All", harness=Harness.hyundai_l), + CAR.SANTA_FE_2022: HyundaiCarInfo("Hyundai Santa Fe 2021-22", "All", video_link="https://youtu.be/VnHzSTygTS4", harness=Harness.hyundai_l), CAR.SANTA_FE_HEV_2022: HyundaiCarInfo("Hyundai Santa Fe Hybrid 2022", "All", harness=Harness.hyundai_l), CAR.SANTA_FE_PHEV_2022: HyundaiCarInfo("Hyundai Santa Fe Plug-in Hybrid 2022", "All", harness=Harness.hyundai_l), CAR.SONATA: HyundaiCarInfo("Hyundai Sonata 2020-22", "All", video_link="https://www.youtube.com/watch?v=ix63r9kE3Fw", harness=Harness.hyundai_a), From 4602e5a8f9e23f173635e9e00a60ab3b73deb254 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Tue, 16 Aug 2022 00:32:42 -0700 Subject: [PATCH 033/106] process replay: print correct ref path (#25448) * fix log paths ref printing in process replay * rm that * this is easier to read * fix model_replay --- selfdrive/test/process_replay/model_replay.py | 2 +- .../test/process_replay/test_processes.py | 19 +++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/selfdrive/test/process_replay/model_replay.py b/selfdrive/test/process_replay/model_replay.py index 12f3583ee44c00..d2090aa76aa625 100755 --- a/selfdrive/test/process_replay/model_replay.py +++ b/selfdrive/test/process_replay/model_replay.py @@ -176,7 +176,7 @@ def model_replay(lr, frs): # TODO this tolerence is absurdly large tolerance = 5e-1 if PC else None results: Any = {TEST_ROUTE: {}} - log_paths: Any = {TEST_ROUTE: {'ref': BASE_URL + log_fn, 'new': log_fn}} + log_paths: Any = {TEST_ROUTE: {"models": {'ref': BASE_URL + log_fn, 'new': log_fn}}} results[TEST_ROUTE]["models"] = compare_logs(cmp_log, log_msgs, tolerance=tolerance, ignore_fields=ignore) diff1, diff2, failed = format_diff(results, log_paths, ref_commit) diff --git a/selfdrive/test/process_replay/test_processes.py b/selfdrive/test/process_replay/test_processes.py index 9e6fee0de0c26f..68c1666b599e46 100755 --- a/selfdrive/test/process_replay/test_processes.py +++ b/selfdrive/test/process_replay/test_processes.py @@ -117,19 +117,19 @@ def format_diff(results, log_paths, ref_commit): for proc, diff in list(result.items()): # long diff diff2 += f"*** process: {proc} ***\n" - diff2 += f"\tref: {log_paths[segment]['ref']}\n\n" - diff2 += f"\tnew: {log_paths[segment]['new']}\n\n" + diff2 += f"\tref: {log_paths[segment][proc]['ref']}\n" + diff2 += f"\tnew: {log_paths[segment][proc]['new']}\n\n" # short diff diff1 += f" {proc}\n" if isinstance(diff, str): - diff1 += f" ref: {log_paths[segment]['ref']}\n" - diff1 += f" new: {log_paths[segment]['new']}\n\n" + diff1 += f" ref: {log_paths[segment][proc]['ref']}\n" + diff1 += f" new: {log_paths[segment][proc]['new']}\n\n" diff1 += f" {diff}\n" failed = True elif len(diff): - diff1 += f" ref: {log_paths[segment]['ref']}\n" - diff1 += f" new: {log_paths[segment]['new']}\n\n" + diff1 += f" ref: {log_paths[segment][proc]['ref']}\n" + diff1 += f" new: {log_paths[segment][proc]['new']}\n\n" cnt: Dict[str, int] = {} for d in diff: @@ -196,8 +196,7 @@ def format_diff(results, log_paths, ref_commit): untested = (set(interface_names) - set(excluded_interfaces)) - {c.lower() for c in tested_cars} assert len(untested) == 0, f"Cars missing routes: {str(untested)}" - - log_paths: DefaultDict[str, Dict[str, str]] = defaultdict(dict) + log_paths: DefaultDict[str, Dict[str, Dict[str, str]]] = defaultdict(lambda: defaultdict(dict)) with concurrent.futures.ProcessPoolExecutor(max_workers=args.jobs) as pool: if not args.upload_only: download_segments = [seg for car, seg in segments if car in tested_cars] @@ -225,8 +224,8 @@ def format_diff(results, log_paths, ref_commit): dat = None if args.upload_only else log_data[segment] pool_args.append((segment, cfg, args, cur_log_fn, ref_log_path, dat)) - log_paths[segment]['ref'] = ref_log_path - log_paths[segment]['new'] = cur_log_fn + log_paths[segment][cfg.proc_name + cfg.subtest_name]['ref'] = ref_log_path + log_paths[segment][cfg.proc_name + cfg.subtest_name]['new'] = cur_log_fn results: Any = defaultdict(dict) p2 = pool.map(run_test_process, pool_args) From 721fae7e8e0fdf239c2ef5bf138c8e7ca7f16771 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Tue, 16 Aug 2022 00:37:11 -0700 Subject: [PATCH 034/106] Multilang: language policy (#25414) * add draft translation merging policy * Update policy copy * copy * add link * Update selfdrive/ui/translations/README.md --- selfdrive/ui/translations/README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/selfdrive/ui/translations/README.md b/selfdrive/ui/translations/README.md index 349b4847afc4f8..5d469861482bb3 100644 --- a/selfdrive/ui/translations/README.md +++ b/selfdrive/ui/translations/README.md @@ -11,6 +11,14 @@ Before getting started, make sure you have set up the openpilot Ubuntu development environment by reading the [tools README.md](/tools/README.md). +### Policy + +Most of the languages supported by openpilot come from and are maintained by the community via pull requests. A pull request likely to be merged is one that [fixes a translation or adds missing translations.](https://github.com/commaai/openpilot/blob/lang-policy/selfdrive/ui/translations/README.md#improving-an-existing-language) + +We also generally merge pull requests adding support for a new language if there are community members willing to maintain it. Maintaining a language is ensuring quality and completion of translations before each openpilot release. + +comma may remove or hide language support from releases depending on translation quality and completeness. + ### Adding a New Language openpilot provides a few tools to help contributors manage their translations and to ensure quality. To get started: @@ -39,7 +47,7 @@ Any time you edit source code in the UI, you need to update the translations to ### Testing -openpilot has a few unit tests to make sure all translations are up to date and that all strings are wrapped in a translation marker. They are run in CI, but you can also run them locally. +openpilot has a few unit tests to make sure all translations are up-to-date and that all strings are wrapped in a translation marker. They are run in CI, but you can also run them locally. Tests translation files up to date: From 3fc001c945bb5e9092050bac1e55267dab63b9eb Mon Sep 17 00:00:00 2001 From: Chris Souers Date: Tue, 16 Aug 2022 03:40:47 -0400 Subject: [PATCH 035/106] Honda: cleanup minEnableSpeed (#25447) * Honda interface.py: cleanup `stop_and_go` variable * Update selfdrive/car/honda/interface.py Co-authored-by: Shane Smiskol --- selfdrive/car/honda/interface.py | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/selfdrive/car/honda/interface.py b/selfdrive/car/honda/interface.py index a78189b697448c..b1461827133a17 100755 --- a/selfdrive/car/honda/interface.py +++ b/selfdrive/car/honda/interface.py @@ -86,7 +86,6 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl eps_modified = True if candidate == CAR.CIVIC: - stop_and_go = True ret.mass = CivicParams.MASS ret.wheelbase = CivicParams.WHEELBASE ret.centerToFront = CivicParams.CENTER_TO_FRONT @@ -106,7 +105,6 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl tire_stiffness_factor = 1. elif candidate in (CAR.CIVIC_BOSCH, CAR.CIVIC_BOSCH_DIESEL, CAR.CIVIC_2022): - stop_and_go = True ret.mass = CivicParams.MASS ret.wheelbase = CivicParams.WHEELBASE ret.centerToFront = CivicParams.CENTER_TO_FRONT @@ -116,7 +114,6 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.8], [0.24]] elif candidate in (CAR.ACCORD, CAR.ACCORDH): - stop_and_go = True ret.mass = 3279. * CV.LB_TO_KG + STD_CARGO_KG ret.wheelbase = 2.83 ret.centerToFront = ret.wheelbase * 0.39 @@ -130,7 +127,6 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.6], [0.18]] elif candidate == CAR.ACURA_ILX: - stop_and_go = False ret.mass = 3095. * CV.LB_TO_KG + STD_CARGO_KG ret.wheelbase = 2.67 ret.centerToFront = ret.wheelbase * 0.37 @@ -140,7 +136,6 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.8], [0.24]] elif candidate in (CAR.CRV, CAR.CRV_EU): - stop_and_go = False ret.mass = 3572. * CV.LB_TO_KG + STD_CARGO_KG ret.wheelbase = 2.62 ret.centerToFront = ret.wheelbase * 0.41 @@ -151,7 +146,6 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl ret.wheelSpeedFactor = 1.025 elif candidate == CAR.CRV_5G: - stop_and_go = True ret.mass = 3410. * CV.LB_TO_KG + STD_CARGO_KG ret.wheelbase = 2.66 ret.centerToFront = ret.wheelbase * 0.41 @@ -169,7 +163,6 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl ret.wheelSpeedFactor = 1.025 elif candidate == CAR.CRV_HYBRID: - stop_and_go = True ret.mass = 1667. + STD_CARGO_KG # mean of 4 models in kg ret.wheelbase = 2.66 ret.centerToFront = ret.wheelbase * 0.41 @@ -180,7 +173,6 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl ret.wheelSpeedFactor = 1.025 elif candidate == CAR.FIT: - stop_and_go = False ret.mass = 2644. * CV.LB_TO_KG + STD_CARGO_KG ret.wheelbase = 2.53 ret.centerToFront = ret.wheelbase * 0.39 @@ -190,7 +182,6 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2], [0.05]] elif candidate == CAR.FREED: - stop_and_go = False ret.mass = 3086. * CV.LB_TO_KG + STD_CARGO_KG ret.wheelbase = 2.74 # the remaining parameters were copied from FIT @@ -201,7 +192,6 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2], [0.05]] elif candidate == CAR.HRV: - stop_and_go = False ret.mass = 3125 * CV.LB_TO_KG + STD_CARGO_KG ret.wheelbase = 2.61 ret.centerToFront = ret.wheelbase * 0.41 @@ -212,7 +202,6 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl ret.wheelSpeedFactor = 1.025 elif candidate == CAR.ACURA_RDX: - stop_and_go = False ret.mass = 3935. * CV.LB_TO_KG + STD_CARGO_KG ret.wheelbase = 2.68 ret.centerToFront = ret.wheelbase * 0.38 @@ -222,7 +211,6 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.8], [0.24]] elif candidate == CAR.ACURA_RDX_3G: - stop_and_go = True ret.mass = 4068. * CV.LB_TO_KG + STD_CARGO_KG ret.wheelbase = 2.75 ret.centerToFront = ret.wheelbase * 0.41 @@ -232,7 +220,6 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl tire_stiffness_factor = 0.677 elif candidate == CAR.ODYSSEY: - stop_and_go = False ret.mass = 4471. * CV.LB_TO_KG + STD_CARGO_KG ret.wheelbase = 3.00 ret.centerToFront = ret.wheelbase * 0.41 @@ -242,7 +229,6 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.28], [0.08]] elif candidate == CAR.ODYSSEY_CHN: - stop_and_go = False ret.mass = 1849.2 + STD_CARGO_KG # mean of 4 models in kg ret.wheelbase = 2.90 ret.centerToFront = ret.wheelbase * 0.41 # from CAR.ODYSSEY @@ -252,7 +238,6 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.28], [0.08]] elif candidate in (CAR.PILOT, CAR.PASSPORT): - stop_and_go = False ret.mass = 4204. * CV.LB_TO_KG + STD_CARGO_KG # average weight ret.wheelbase = 2.82 ret.centerToFront = ret.wheelbase * 0.428 @@ -262,7 +247,6 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.38], [0.11]] elif candidate == CAR.RIDGELINE: - stop_and_go = False ret.mass = 4515. * CV.LB_TO_KG + STD_CARGO_KG ret.wheelbase = 3.18 ret.centerToFront = ret.wheelbase * 0.41 @@ -272,7 +256,6 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.38], [0.11]] elif candidate == CAR.INSIGHT: - stop_and_go = True ret.mass = 2987. * CV.LB_TO_KG + STD_CARGO_KG ret.wheelbase = 2.7 ret.centerToFront = ret.wheelbase * 0.39 @@ -282,7 +265,6 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.6], [0.18]] elif candidate == CAR.HONDA_E: - stop_and_go = True ret.mass = 3338.8 * CV.LB_TO_KG + STD_CARGO_KG ret.wheelbase = 2.5 ret.centerToFront = ret.wheelbase * 0.5 @@ -311,7 +293,8 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl # min speed to enable ACC. if car can do stop and go, then set enabling speed # to a negative value, so it won't matter. Otherwise, add 0.5 mph margin to not # conflict with PCM acc - ret.minEnableSpeed = -1. if (stop_and_go or ret.enableGasInterceptor) else 25.5 * CV.MPH_TO_MS + stop_and_go = candidate in (HONDA_BOSCH | {CAR.CIVIC}) or ret.enableGasInterceptor + ret.minEnableSpeed = -1. if stop_and_go else 25.5 * CV.MPH_TO_MS # TODO: get actual value, for now starting with reasonable value for # civic and scaling by mass and wheelbase From 76a4daefffe0462162b984aae7baba25866903bb Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 16 Aug 2022 13:16:11 -0700 Subject: [PATCH 036/106] pj: update torque control layout --- .../plotjuggler/layouts/max-torque-debug.xml | 6 -- .../plotjuggler/layouts/torque-controller.xml | 60 ++++++++++--------- 2 files changed, 32 insertions(+), 34 deletions(-) diff --git a/tools/plotjuggler/layouts/max-torque-debug.xml b/tools/plotjuggler/layouts/max-torque-debug.xml index 05aa208e260808..6903ca8b1532b8 100644 --- a/tools/plotjuggler/layouts/max-torque-debug.xml +++ b/tools/plotjuggler/layouts/max-torque-debug.xml @@ -51,12 +51,6 @@ - - - - - - diff --git a/tools/plotjuggler/layouts/torque-controller.xml b/tools/plotjuggler/layouts/torque-controller.xml index 661bfe094de445..443255968ad31e 100644 --- a/tools/plotjuggler/layouts/torque-controller.xml +++ b/tools/plotjuggler/layouts/torque-controller.xml @@ -1,12 +1,12 @@ - + - + - + @@ -14,7 +14,7 @@ - + @@ -22,33 +22,26 @@ - + - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - @@ -64,19 +57,29 @@ - + + + return value * 3.6 + /carState/vEgo + + + + return value * 2.23694 + /carState/vEgo + + return (value * v1 ^ 2) - (v2 * 9.81) - /controlsState/curvature + /controlsState/desiredCurvature /carState/vEgo /liveParameters/roll - + return (value * v1 ^ 2) - (v2 * 9.81) - /controlsState/desiredCurvature + /controlsState/curvature /carState/vEgo /liveParameters/roll @@ -86,3 +89,4 @@ + From 0258ef74ff52b9f2d545537c05984de1b75252f8 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 16 Aug 2022 13:18:39 -0700 Subject: [PATCH 037/106] Hyundai: Kona torque tune (#25426) * Hyundai: Kona EV 2022 torque tune * Update selfdrive/car/hyundai/interface.py * update for all --- selfdrive/car/hyundai/interface.py | 1 + 1 file changed, 1 insertion(+) diff --git a/selfdrive/car/hyundai/interface.py b/selfdrive/car/hyundai/interface.py index d3dc1a2c6e6d3c..9080e5cdb91cd4 100644 --- a/selfdrive/car/hyundai/interface.py +++ b/selfdrive/car/hyundai/interface.py @@ -122,6 +122,7 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl tire_stiffness_factor = 0.385 ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.25], [0.05]] + CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) elif candidate in (CAR.IONIQ, CAR.IONIQ_EV_LTD, CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.IONIQ_HEV_2022): ret.lateralTuning.pid.kf = 0.00006 ret.mass = 1490. + STD_CARGO_KG # weight per hyundai site https://www.hyundaiusa.com/ioniq-electric/specifications.aspx From 0ed8a7f42def893bece557c0acd3d5fb1e11ecde Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 16 Aug 2022 13:41:58 -0700 Subject: [PATCH 038/106] Toyota: add new corolla fw --- selfdrive/car/toyota/values.py | 1 + 1 file changed, 1 insertion(+) diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index b6181c1fd0b7a1..b7b261adb0224c 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -687,6 +687,7 @@ class ToyotaCarInfo(CarInfo): b'\x01896630ZP2000\x00\x00\x00\x00', b'\x01896630ZQ5000\x00\x00\x00\x00', b'\x01896630ZU9000\x00\x00\x00\x00', + b'\x01896630ZX4000\x00\x00\x00\x00', b'\x018966312L8000\x00\x00\x00\x00', b'\x018966312M0000\x00\x00\x00\x00', b'\x018966312M9000\x00\x00\x00\x00', From c27d7913f2db43ec668dd068199bc568802dd809 Mon Sep 17 00:00:00 2001 From: Jason Young <46612682+jyoung8607@users.noreply.github.com> Date: Tue, 16 Aug 2022 17:32:59 -0400 Subject: [PATCH 039/106] VW PQ: Volkswagen Passat NMS (#24768) * VW PQ: Volkswagen Passat NMS * regen CARS.md * vEgo from Bremse_1 vehicle speed * sync opendbc to master * handle checksums and counters in opendbc * LDW HUD message handling * GRA_Neu_Zaehler -> COUNTER * bump opendbc * stub in till we find platform ACC standstill * bump opendbc * bump opendbc * placeholder lateral accel data * regen CARS.md * counters now directly supported in opendbc * additional door-open signals * add trunk lid state * add doors and trunk lid to signals list * LDW_Status updates and passthrough * bump opendbc for typo fix * update AWV comment * another comment update * regen CARS.md with PQ in dashcam only * don't show NMS footnotes while still in dashcam * polish * add stubbed-out dashcamOnly prep * VW MQB: Cleanup stock ACC button handling * bump opendbc and panda * use controls resume output as trigger * these can wait until taco bell * bump opendbc * pass through of previously fixed value * retry CI * checks already done in carcontroller * don't need these anymore * reduce diff for now * slightly better abstraction * more engine and trans FW * turn signal is instantaneous stalk position * weak sauce :( * better clarity * try torque tune * add test route references * bump opendbc and panda for OP long * don't show steering faults for 3 seconds after start * longitudinal control senders * a little more torque * test hax to torque control * test a little more delay * allow use of manufacturer ramp-up rate * soften wheel-touch threshold * Revert "test hax to torque control" This reverts commit d1af459c29e36264aae406f72b8fcbc9ef22b9e0. * punch it Chewie * better ACC state and mainswitch handling * a little more * tweak max accel gradient * oops * also oops * stuff * srsly * that's not how this works * regen CARS.md * footnotes now properly excluded for dashcam cars * this wasn't a problem * update network location detection * bump submodules for ACC main switch * clean up DBC references and long flag * bump one more time * one more time * follow CANPacker counter refactor * bump opendbc * sync opendbc to master * bump panda to fix Subaru tests * DBC handling cleanup * fix * model-year stretch * cleanup and rate bugfixes * better abstractions * simplify create_lka_hud_control * volkswagencan -> mqbcan * bump panda * fix doc data bug, regen CARS.md * style updates; diff reduction * use common button enable logic * not needed anymore * refactor TSK and HUD enum values * make common button events function * consistency * bump panda * bump panda * dashcam only * don't need process_replay yet * regen CARS.md with Passat NMS in dashcam * can't handle dashcam-orphaned footnotes yet * remove outdated standstill handling * editor tried to be too helpful at some point * don't need to import this anymore * Apply suggestions from code review Co-authored-by: Adeeb Shihadeh * follow parkingBrake refactor Co-authored-by: Adeeb Shihadeh --- panda | 2 +- release/files_common | 1 + selfdrive/car/tests/routes.py | 1 + selfdrive/car/torque_data/override.yaml | 1 + selfdrive/car/volkswagen/carcontroller.py | 21 +- selfdrive/car/volkswagen/carstate.py | 247 +++++++++++++++++- selfdrive/car/volkswagen/interface.py | 43 ++- selfdrive/car/volkswagen/pqcan.py | 84 ++++++ selfdrive/car/volkswagen/values.py | 62 ++++- .../test/process_replay/test_processes.py | 3 +- 10 files changed, 456 insertions(+), 9 deletions(-) create mode 100644 selfdrive/car/volkswagen/pqcan.py diff --git a/panda b/panda index 5e0dde7b480a93..199bc10db3a937 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 5e0dde7b480a930d3c3a164331c930541e905d71 +Subproject commit 199bc10db3a937fab0c50d9b708f6c76234f5c3a diff --git a/release/files_common b/release/files_common index 8bf99f02283847..01386b5858e405 100644 --- a/release/files_common +++ b/release/files_common @@ -552,6 +552,7 @@ opendbc/toyota_nodsu_pt_generated.dbc opendbc/toyota_adas.dbc opendbc/toyota_tss2_adas.dbc +opendbc/vw_golf_mk4.dbc opendbc/vw_mqb_2010.dbc opendbc/tesla_can.dbc diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py index 0b1726b0106e76..44672bf9dd24c8 100644 --- a/selfdrive/car/tests/routes.py +++ b/selfdrive/car/tests/routes.py @@ -168,6 +168,7 @@ TestRoute("cae14e88932eb364|2021-03-26--14-43-28", VOLKSWAGEN.GOLF_MK7), TestRoute("58a7d3b707987d65|2021-03-25--17-26-37", VOLKSWAGEN.JETTA_MK7), TestRoute("4d134e099430fba2|2021-03-26--00-26-06", VOLKSWAGEN.PASSAT_MK8), + TestRoute("3cfdec54aa035f3f|2022-07-19--23-45-10", VOLKSWAGEN.PASSAT_NMS), TestRoute("0cd0b7f7e31a3853|2021-11-03--19-30-22", VOLKSWAGEN.POLO_MK6), TestRoute("7d82b2f3a9115f1f|2021-10-21--15-39-42", VOLKSWAGEN.TAOS_MK1), TestRoute("2744c89a8dda9a51|2021-07-24--21-28-06", VOLKSWAGEN.TCROSS_MK1), diff --git a/selfdrive/car/torque_data/override.yaml b/selfdrive/car/torque_data/override.yaml index 0a958a9d035028..8dd8c43220d097 100644 --- a/selfdrive/car/torque_data/override.yaml +++ b/selfdrive/car/torque_data/override.yaml @@ -25,6 +25,7 @@ RAM 1500 5TH GEN: [2.0, 2.0, 0.0] RAM HD 5TH GEN: [1.4, 1.4, 0.0] SUBARU OUTBACK 6TH GEN: [2.3, 2.3, 0.11] CHEVROLET BOLT EUV 2022: [2.0, 2.0, 0.05] +VOLKSWAGEN PASSAT NMS: [2.5, 2.5, 0.1] # Dashcam or fallback configured as ideal car mock: [10.0, 10, 0.0] diff --git a/selfdrive/car/volkswagen/carcontroller.py b/selfdrive/car/volkswagen/carcontroller.py index 2c5830f8682c53..f14c119892c95a 100644 --- a/selfdrive/car/volkswagen/carcontroller.py +++ b/selfdrive/car/volkswagen/carcontroller.py @@ -1,8 +1,10 @@ from cereal import car from opendbc.can.packer import CANPacker +from common.numpy_fast import clip +from common.conversions import Conversions as CV from selfdrive.car import apply_std_steer_torque_limits -from selfdrive.car.volkswagen import mqbcan -from selfdrive.car.volkswagen.values import CANBUS, CarControllerParams +from selfdrive.car.volkswagen import mqbcan, pqcan +from selfdrive.car.volkswagen.values import CANBUS, PQ_CARS, CarControllerParams VisualAlert = car.CarControl.HUDControl.VisualAlert @@ -11,7 +13,7 @@ class CarController: def __init__(self, dbc_name, CP, VM): self.CP = CP self.CCP = CarControllerParams(CP) - self.CCS = mqbcan + self.CCS = pqcan if CP.carFingerprint in PQ_CARS else mqbcan self.packer_pt = CANPacker(dbc_name) self.apply_steer_last = 0 @@ -65,6 +67,13 @@ def update(self, CC, CS, ext_bus): self.apply_steer_last = apply_steer can_sends.append(self.CCS.create_steering_control(self.packer_pt, CANBUS.pt, apply_steer, hcaEnabled)) + # **** Acceleration Controls ******************************************** # + + if self.frame % self.CCP.ACC_CONTROL_STEP == 0 and self.CP.openpilotLongitudinalControl: + tsk_status = self.CCS.tsk_status_value(CS.out.cruiseState.available, CS.out.accFaulted, CC.longActive) + accel = clip(actuators.accel, self.CCP.ACCEL_MIN, self.CCP.ACCEL_MAX) if CC.longActive else 0 + can_sends.extend(self.CCS.create_acc_accel_control(self.packer_pt, CANBUS.pt, tsk_status, accel)) + # **** HUD Controls ***************************************************** # if self.frame % self.CCP.LDW_STEP == 0: @@ -74,6 +83,12 @@ def update(self, CC, CS, ext_bus): can_sends.append(self.CCS.create_lka_hud_control(self.packer_pt, CANBUS.pt, CS.ldw_stock_values, CC.enabled, CS.out.steeringPressed, hud_alert, hud_control)) + if self.frame % self.CCP.ACC_HUD_STEP == 0 and self.CP.openpilotLongitudinalControl: + acc_hud_status = self.CCS.acc_hud_status_value(CS.out.cruiseState.available, CS.out.accFaulted, CC.longActive) + set_speed = hud_control.setSpeed * CV.MS_TO_KPH # FIXME: follow the recent displayed-speed updates, also use mph_kmh toggle to fix display rounding problem? + can_sends.append(self.CCS.create_acc_hud_control(self.packer_pt, CANBUS.pt, acc_hud_status, set_speed, + hud_control.leadVisible)) + # **** Stock ACC Button Controls **************************************** # if self.CP.pcmCruise and self.frame % self.CCP.GRA_ACC_STEP == 0: diff --git a/selfdrive/car/volkswagen/carstate.py b/selfdrive/car/volkswagen/carstate.py index 50be6bf9ad2bd6..facc740a153a15 100644 --- a/selfdrive/car/volkswagen/carstate.py +++ b/selfdrive/car/volkswagen/carstate.py @@ -3,7 +3,7 @@ from common.conversions import Conversions as CV from selfdrive.car.interfaces import CarStateBase from opendbc.can.parser import CANParser -from selfdrive.car.volkswagen.values import DBC, CANBUS, NetworkLocation, TransmissionType, GearShifter, \ +from selfdrive.car.volkswagen.values import DBC, CANBUS, PQ_CARS, NetworkLocation, TransmissionType, GearShifter, \ CarControllerParams @@ -28,6 +28,9 @@ def create_button_events(self, pt_cp, buttons): return button_events def update(self, pt_cp, cam_cp, ext_cp, trans_type): + if self.CP.carFingerprint in PQ_CARS: + return self.update_pq(pt_cp, cam_cp, ext_cp, trans_type) + ret = car.CarState.new_message() # Update vehicle speed and acceleration from ABS wheel speeds. ret.wheelSpeeds = self.get_wheel_speeds( @@ -135,8 +138,111 @@ def update(self, pt_cp, cam_cp, ext_cp, trans_type): return ret + def update_pq(self, pt_cp, cam_cp, ext_cp, trans_type): + ret = car.CarState.new_message() + # Update vehicle speed and acceleration from ABS wheel speeds. + ret.wheelSpeeds = self.get_wheel_speeds( + pt_cp.vl["Bremse_3"]["Radgeschw__VL_4_1"], + pt_cp.vl["Bremse_3"]["Radgeschw__VR_4_1"], + pt_cp.vl["Bremse_3"]["Radgeschw__HL_4_1"], + pt_cp.vl["Bremse_3"]["Radgeschw__HR_4_1"], + ) + + # vEgo obtained from Bremse_1 vehicle speed rather than Bremse_3 wheel speeds because Bremse_3 isn't present on NSF + ret.vEgoRaw = pt_cp.vl["Bremse_1"]["Geschwindigkeit_neu__Bremse_1_"] * CV.KPH_TO_MS + ret.vEgo, ret.aEgo = self.update_speed_kf(ret.vEgoRaw) + ret.standstill = ret.vEgo < 0.1 + + # Update steering angle, rate, yaw rate, and driver input torque. VW send + # the sign/direction in a separate signal so they must be recombined. + ret.steeringAngleDeg = pt_cp.vl["Lenkhilfe_3"]["LH3_BLW"] * (1, -1)[int(pt_cp.vl["Lenkhilfe_3"]["LH3_BLWSign"])] + ret.steeringRateDeg = pt_cp.vl["Lenkwinkel_1"]["Lenkradwinkel_Geschwindigkeit"] * (1, -1)[int(pt_cp.vl["Lenkwinkel_1"]["Lenkradwinkel_Geschwindigkeit_S"])] + ret.steeringTorque = pt_cp.vl["Lenkhilfe_3"]["LH3_LM"] * (1, -1)[int(pt_cp.vl["Lenkhilfe_3"]["LH3_LMSign"])] + ret.steeringPressed = abs(ret.steeringTorque) > self.CCP.STEER_DRIVER_ALLOWANCE + ret.yawRate = pt_cp.vl["Bremse_5"]["Giergeschwindigkeit"] * (1, -1)[int(pt_cp.vl["Bremse_5"]["Vorzeichen_der_Giergeschwindigk"])] * CV.DEG_TO_RAD + + # Verify EPS readiness to accept steering commands + hca_status = self.CCP.hca_status_values.get(pt_cp.vl["Lenkhilfe_2"]["LH2_Sta_HCA"]) + ret.steerFaultPermanent = hca_status in ("DISABLED", "FAULT") + ret.steerFaultTemporary = hca_status in ("INITIALIZING", "REJECTED") + + # Update gas, brakes, and gearshift. + ret.gas = pt_cp.vl["Motor_3"]["Fahrpedal_Rohsignal"] / 100.0 + ret.gasPressed = ret.gas > 0 + ret.brake = pt_cp.vl["Bremse_5"]["Bremsdruck"] / 250.0 # FIXME: this is pressure in Bar, not sure what OP expects + ret.brakePressed = bool(pt_cp.vl["Motor_2"]["Bremstestschalter"]) + ret.parkingBrake = bool(pt_cp.vl["Kombi_1"]["Bremsinfo"]) + + # Update gear and/or clutch position data. + if trans_type == TransmissionType.automatic: + ret.gearShifter = self.parse_gear_shifter(self.CCP.shifter_values.get(pt_cp.vl["Getriebe_1"]["Waehlhebelposition__Getriebe_1_"], None)) + elif trans_type == TransmissionType.manual: + ret.clutchPressed = not pt_cp.vl["Motor_1"]["Kupplungsschalter"] + reverse_light = bool(pt_cp.vl["Gate_Komf_1"]["GK1_Rueckfahr"]) + if reverse_light: + ret.gearShifter = GearShifter.reverse + else: + ret.gearShifter = GearShifter.drive + + # Update door and trunk/hatch lid open status. + ret.doorOpen = any([pt_cp.vl["Gate_Komf_1"]["GK1_Fa_Tuerkont"], + pt_cp.vl["Gate_Komf_1"]["BSK_BT_geoeffnet"], + pt_cp.vl["Gate_Komf_1"]["BSK_HL_geoeffnet"], + pt_cp.vl["Gate_Komf_1"]["BSK_HR_geoeffnet"], + pt_cp.vl["Gate_Komf_1"]["BSK_HD_Hauptraste"]]) + + # Update seatbelt fastened status. + ret.seatbeltUnlatched = not bool(pt_cp.vl["Airbag_1"]["Gurtschalter_Fahrer"]) + + # Consume blind-spot monitoring info/warning LED states, if available. + # Infostufe: BSM LED on, Warnung: BSM LED flashing + if self.CP.enableBsm: + ret.leftBlindspot = bool(ext_cp.vl["SWA_1"]["SWA_Infostufe_SWA_li"]) or bool(ext_cp.vl["SWA_1"]["SWA_Warnung_SWA_li"]) + ret.rightBlindspot = bool(ext_cp.vl["SWA_1"]["SWA_Infostufe_SWA_re"]) or bool(ext_cp.vl["SWA_1"]["SWA_Warnung_SWA_re"]) + + # Consume factory LDW data relevant for factory SWA (Lane Change Assist) + # and capture it for forwarding to the blind spot radar controller + self.ldw_stock_values = cam_cp.vl["LDW_Status"] if self.CP.networkLocation == NetworkLocation.fwdCamera else {} + + # Stock FCW is considered active if the release bit for brake-jerk warning + # is set. Stock AEB considered active if the partial braking or target + # braking release bits are set. + # Refer to VW Self Study Program 890253: Volkswagen Driver Assistance + # Systems, chapters on Front Assist with Braking and City Emergency + # Braking for the 2016 Passat NMS + # TODO: deferred until we can collect data on pre-MY2016 behavior, AWV message may be shorter with fewer signals + ret.stockFcw = False + ret.stockAeb = False + + # Update ACC radar status. + ret.cruiseState.available = bool(pt_cp.vl["Motor_5"]["GRA_Hauptschalter"]) + ret.cruiseState.enabled = bool(pt_cp.vl["Motor_2"]["GRA_Status"]) + if self.CP.pcmCruise: + ret.accFaulted = ext_cp.vl["ACC_GRA_Anziege"]["ACA_StaACC"] in (6, 7) + # TODO: update opendbc with PQ TSK state for OP long accFaulted + + # Update ACC setpoint. When the setpoint reads as 255, the driver has not + # yet established an ACC setpoint, so treat it as zero. + ret.cruiseState.speed = ext_cp.vl["ACC_GRA_Anziege"]["ACA_V_Wunsch"] * CV.KPH_TO_MS + if ret.cruiseState.speed > 70: # 255 kph in m/s == no current setpoint + ret.cruiseState.speed = 0 + + # Update button states for turn signals and ACC controls, capture all ACC button state/config for passthrough + ret.leftBlinker, ret.rightBlinker = self.update_blinker_from_stalk(300, pt_cp.vl["Gate_Komf_1"]["GK1_Blinker_li"], + pt_cp.vl["Gate_Komf_1"]["GK1_Blinker_re"]) + ret.buttonEvents = self.create_button_events(pt_cp, self.CCP.BUTTONS) + self.gra_stock_values = pt_cp.vl["GRA_Neu"] + + # Additional safety checks performed in CarInterface. + ret.espDisabled = bool(pt_cp.vl["Bremse_1"]["ESP_Passiv_getastet"]) + + return ret + @staticmethod def get_can_parser(CP): + if CP.carFingerprint in PQ_CARS: + return CarState.get_can_parser_pq(CP) + signals = [ # sig_name, sig_address ("LWI_Lenkradwinkel", "LWI_01"), # Absolute steering angle @@ -222,6 +328,9 @@ def get_can_parser(CP): @staticmethod def get_cam_can_parser(CP): + if CP.carFingerprint in PQ_CARS: + return CarState.get_cam_can_parser_pq(CP) + signals = [] checks = [] @@ -248,6 +357,123 @@ def get_cam_can_parser(CP): return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, CANBUS.cam) + @staticmethod + def get_can_parser_pq(CP): + signals = [ + # sig_name, sig_address, default + ("LH3_BLW", "Lenkhilfe_3"), # Absolute steering angle + ("LH3_BLWSign", "Lenkhilfe_3"), # Steering angle sign + ("LH3_LM", "Lenkhilfe_3"), # Absolute driver torque input + ("LH3_LMSign", "Lenkhilfe_3"), # Driver torque input sign + ("LH2_Sta_HCA", "Lenkhilfe_2"), # Steering rack HCA status + ("Lenkradwinkel_Geschwindigkeit", "Lenkwinkel_1"), # Absolute steering rate + ("Lenkradwinkel_Geschwindigkeit_S", "Lenkwinkel_1"), # Steering rate sign + ("Geschwindigkeit_neu__Bremse_1_", "Bremse_1"), # Vehicle speed from ABS + ("Radgeschw__VL_4_1", "Bremse_3"), # ABS wheel speed, front left + ("Radgeschw__VR_4_1", "Bremse_3"), # ABS wheel speed, front right + ("Radgeschw__HL_4_1", "Bremse_3"), # ABS wheel speed, rear left + ("Radgeschw__HR_4_1", "Bremse_3"), # ABS wheel speed, rear right + ("Giergeschwindigkeit", "Bremse_5"), # Absolute yaw rate + ("Vorzeichen_der_Giergeschwindigk", "Bremse_5"), # Yaw rate sign + ("Gurtschalter_Fahrer", "Airbag_1"), # Seatbelt status, driver + ("Gurtschalter_Beifahrer", "Airbag_1"), # Seatbelt status, passenger + ("Bremstestschalter", "Motor_2"), # Brake pedal pressed (brake light test switch) + ("Bremslichtschalter", "Motor_2"), # Brakes applied (brake light switch) + ("Bremsdruck", "Bremse_5"), # Brake pressure applied + ("Vorzeichen_Bremsdruck", "Bremse_5"), # Brake pressure applied sign (???) + ("Fahrpedal_Rohsignal", "Motor_3"), # Accelerator pedal value + ("ESP_Passiv_getastet", "Bremse_1"), # Stability control disabled + ("GRA_Hauptschalter", "Motor_5"), # ACC main switch + ("GRA_Status", "Motor_2"), # ACC engagement status + ("GK1_Fa_Tuerkont", "Gate_Komf_1"), # Door open, driver + ("BSK_BT_geoeffnet", "Gate_Komf_1"), # Door open, passenger + ("BSK_HL_geoeffnet", "Gate_Komf_1"), # Door open, rear left + ("BSK_HR_geoeffnet", "Gate_Komf_1"), # Door open, rear right + ("BSK_HD_Hauptraste", "Gate_Komf_1"), # Trunk or hatch open + ("GK1_Blinker_li", "Gate_Komf_1"), # Left turn signal on + ("GK1_Blinker_re", "Gate_Komf_1"), # Right turn signal on + ("Bremsinfo", "Kombi_1"), # Manual handbrake applied + ("GRA_Hauptschalt", "GRA_Neu"), # ACC button, on/off + ("GRA_Typ_Hauptschalt", "GRA_Neu"), # ACC button, momentary vs latching + ("GRA_Kodierinfo", "GRA_Neu"), # ACC button, configuration + ("GRA_Abbrechen", "GRA_Neu"), # ACC button, cancel + ("GRA_Neu_Setzen", "GRA_Neu"), # ACC button, set + ("GRA_Up_lang", "GRA_Neu"), # ACC button, increase or accel, long press + ("GRA_Down_lang", "GRA_Neu"), # ACC button, decrease or decel, long press + ("GRA_Up_kurz", "GRA_Neu"), # ACC button, increase or accel, short press + ("GRA_Down_kurz", "GRA_Neu"), # ACC button, decrease or decel, short press + ("GRA_Recall", "GRA_Neu"), # ACC button, resume + ("GRA_Zeitluecke", "GRA_Neu"), # ACC button, time gap adj + ("COUNTER", "GRA_Neu"), # ACC button, message counter + ("GRA_Sender", "GRA_Neu"), # ACC button, CAN message originator + ] + + checks = [ + # sig_address, frequency + ("Bremse_1", 100), # From J104 ABS/ESP controller + ("Bremse_3", 100), # From J104 ABS/ESP controller + ("Lenkhilfe_3", 100), # From J500 Steering Assist with integrated sensors + ("Lenkwinkel_1", 100), # From J500 Steering Assist with integrated sensors + ("Motor_3", 100), # From J623 Engine control module + ("Airbag_1", 50), # From J234 Airbag control module + ("Bremse_5", 50), # From J104 ABS/ESP controller + ("GRA_Neu", 50), # From J??? steering wheel control buttons + ("Kombi_1", 50), # From J285 Instrument cluster + ("Motor_2", 50), # From J623 Engine control module + ("Motor_5", 50), # From J623 Engine control module + ("Lenkhilfe_2", 20), # From J500 Steering Assist with integrated sensors + ("Gate_Komf_1", 10), # From J533 CAN gateway + ] + + if CP.transmissionType == TransmissionType.automatic: + signals += [("Waehlhebelposition__Getriebe_1_", "Getriebe_1", 0)] # Auto trans gear selector position + checks += [("Getriebe_1", 100)] # From J743 Auto transmission control module + elif CP.transmissionType == TransmissionType.manual: + signals += [("Kupplungsschalter", "Motor_1", 0), # Clutch switch + ("GK1_Rueckfahr", "Gate_Komf_1", 0)] # Reverse light from BCM + checks += [("Motor_1", 100)] # From J623 Engine control module + + if CP.networkLocation == NetworkLocation.fwdCamera: + # Extended CAN devices other than the camera are here on CANBUS.pt + signals += PqExtraSignals.fwd_radar_signals + checks += PqExtraSignals.fwd_radar_checks + if CP.enableBsm: + signals += PqExtraSignals.bsm_radar_signals + checks += PqExtraSignals.bsm_radar_checks + + return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, CANBUS.pt) + + @staticmethod + def get_cam_can_parser_pq(CP): + + signals = [] + checks = [] + + if CP.networkLocation == NetworkLocation.fwdCamera: + signals += [ + # sig_name, sig_address + ("LDW_SW_Warnung_links", "LDW_Status"), # Blind spot in warning mode on left side due to lane departure + ("LDW_SW_Warnung_rechts", "LDW_Status"), # Blind spot in warning mode on right side due to lane departure + ("LDW_Seite_DLCTLC", "LDW_Status"), # Direction of most likely lane departure (left or right) + ("LDW_DLC", "LDW_Status"), # Lane departure, distance to line crossing + ("LDW_TLC", "LDW_Status"), # Lane departure, time to line crossing + ] + checks += [ + # sig_address, frequency + ("LDW_Status", 10) # From R242 Driver assistance camera + ] + + if CP.networkLocation == NetworkLocation.gateway: + # Radars are here on CANBUS.cam + signals += PqExtraSignals.fwd_radar_signals + checks += PqExtraSignals.fwd_radar_checks + if CP.enableBsm: + signals += PqExtraSignals.bsm_radar_signals + checks += PqExtraSignals.bsm_radar_checks + + return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, CANBUS.cam) + + class MqbExtraSignals: # Additional signal and message lists for optional or bus-portable controllers fwd_radar_signals = [ @@ -269,3 +495,22 @@ class MqbExtraSignals: bsm_radar_checks = [ ("SWA_01", 20), # From J1086 Lane Change Assist ] + +class PqExtraSignals: + # Additional signal and message lists for optional or bus-portable controllers + fwd_radar_signals = [ + ("ACA_StaACC", "ACC_GRA_Anziege", 0), # ACC drivetrain coordinator status + ("ACA_V_Wunsch", "ACC_GRA_Anziege", 0), # ACC set speed + ] + fwd_radar_checks = [ + ("ACC_GRA_Anziege", 25), # From J428 ACC radar control module + ] + bsm_radar_signals = [ + ("SWA_Infostufe_SWA_li", "SWA_1", 0), # Blind spot object info, left + ("SWA_Warnung_SWA_li", "SWA_1", 0), # Blind spot object warning, left + ("SWA_Infostufe_SWA_re", "SWA_1", 0), # Blind spot object info, right + ("SWA_Warnung_SWA_re", "SWA_1", 0), # Blind spot object warning, right + ] + bsm_radar_checks = [ + ("SWA_1", 20), # From J1086 Lane Change Assist + ] diff --git a/selfdrive/car/volkswagen/interface.py b/selfdrive/car/volkswagen/interface.py index dfa0a555e33654..22206635ace2ff 100644 --- a/selfdrive/car/volkswagen/interface.py +++ b/selfdrive/car/volkswagen/interface.py @@ -1,8 +1,10 @@ from cereal import car +from panda import Panda +from common.conversions import Conversions as CV from selfdrive.car import STD_CARGO_KG, create_button_enable_events, scale_rot_inertia, scale_tire_stiffness, \ gen_empty_fingerprint, get_safety_config from selfdrive.car.interfaces import CarInterfaceBase -from selfdrive.car.volkswagen.values import CAR, CANBUS, NetworkLocation, TransmissionType, GearShifter +from selfdrive.car.volkswagen.values import CAR, PQ_CARS, CANBUS, NetworkLocation, TransmissionType, GearShifter EventName = car.CarEvent.EventName @@ -25,7 +27,36 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None, disa ret.carName = "volkswagen" ret.radarOffCan = True - if True: # pylint: disable=using-constant-test + if candidate in PQ_CARS: + # Set global PQ35/PQ46/NMS parameters + ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.volkswagenPq)] + ret.enableBsm = 0x3BA in fingerprint[0] # SWA_1 + + if 0x440 in fingerprint[0]: # Getriebe_1 + ret.transmissionType = TransmissionType.automatic + else: + ret.transmissionType = TransmissionType.manual + + if any(msg in fingerprint[1] for msg in (0x1A0, 0xC2)): # Bremse_1, Lenkwinkel_1 + ret.networkLocation = NetworkLocation.gateway + else: + ret.networkLocation = NetworkLocation.fwdCamera + + # The PQ port is in dashcam-only mode due to a fixed six-minute maximum timer on HCA steering. An unsupported + # EPS flash update to work around this timer, and enable steering down to zero, is available from: + # https://github.com/pd0wm/pq-flasher + # It is documented in a four-part blog series: + # https://blog.willemmelching.nl/carhacking/2022/01/02/vw-part1/ + # Panda ALLOW_DEBUG firmware required. + ret.dashcamOnly = True + + if disable_radar and ret.networkLocation == NetworkLocation.gateway: + # Proof-of-concept, prep for E2E only. No radar points available. Follow-to-stop not yet supported, but should + # be simple to add when a suitable test car becomes available. Panda ALLOW_DEBUG firmware required. + ret.openpilotLongitudinalControl = True + ret.safetyConfigs[0].safetyParam |= Panda.FLAG_VOLKSWAGEN_LONG_CONTROL + + else: # Set global MQB parameters ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.volkswagen)] ret.enableBsm = 0x30F in fingerprint[0] # SWA_01 @@ -83,6 +114,14 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None, disa ret.mass = 1551 + STD_CARGO_KG ret.wheelbase = 2.79 + elif candidate == CAR.PASSAT_NMS: + ret.mass = 1503 + STD_CARGO_KG + 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 + STD_CARGO_KG ret.wheelbase = 2.55 diff --git a/selfdrive/car/volkswagen/pqcan.py b/selfdrive/car/volkswagen/pqcan.py new file mode 100644 index 00000000000000..1e7ed21342b54b --- /dev/null +++ b/selfdrive/car/volkswagen/pqcan.py @@ -0,0 +1,84 @@ +def create_steering_control(packer, bus, apply_steer, lkas_enabled): + values = { + "LM_Offset": abs(apply_steer), + "LM_OffSign": 1 if apply_steer < 0 else 0, + "HCA_Status": 5 if (lkas_enabled and apply_steer != 0) else 3, + "Vib_Freq": 16, + } + + return packer.make_can_msg("HCA_1", bus, values) + + +def create_lka_hud_control(packer, bus, ldw_stock_values, enabled, steering_pressed, hud_alert, hud_control): + values = ldw_stock_values.copy() + + values.update({ + "LDW_Lampe_gelb": 1 if enabled and steering_pressed else 0, + "LDW_Lampe_gruen": 1 if enabled and not steering_pressed else 0, + "LDW_Lernmodus_links": 3 if hud_control.leftLaneDepart else 1 + hud_control.leftLaneVisible, + "LDW_Lernmodus_rechts": 3 if hud_control.rightLaneDepart else 1 + hud_control.rightLaneVisible, + "LDW_Textbits": hud_alert, + }) + + return packer.make_can_msg("LDW_Status", bus, values) + + +def create_acc_buttons_control(packer, bus, gra_stock_values, idx, cancel=False, resume=False): + values = gra_stock_values.copy() + + values.update({ + "COUNTER": idx, + "GRA_Abbrechen": cancel, + "GRA_Recall": resume, + }) + + return packer.make_can_msg("GRA_Neu", bus, values) + + +def tsk_status_value(main_switch_on, acc_faulted, long_active): + if long_active: + tsk_status = 1 + elif main_switch_on: + tsk_status = 2 + else: + tsk_status = 0 + + return tsk_status + + +def acc_hud_status_value(main_switch_on, acc_faulted, long_active): + if acc_faulted: + hud_status = 6 + elif long_active: + hud_status = 3 + elif main_switch_on: + hud_status = 2 + else: + hud_status = 0 + + return hud_status + + +def create_acc_accel_control(packer, bus, adr_status, accel): + values = { + "ACS_Sta_ADR": adr_status, + "ACS_StSt_Info": adr_status != 1, + "ACS_Typ_ACC": 0, # TODO: this is ACC "basic", find a way to detect FtS support (1) + "ACS_Sollbeschl": accel if adr_status == 1 else 3.01, + "ACS_zul_Regelabw": 0.2 if adr_status == 1 else 1.27, + "ACS_max_AendGrad": 3.0 if adr_status == 1 else 5.08, + } + + return packer.make_can_msg("ACC_System", bus, values) + + +def create_acc_hud_control(packer, bus, acc_status, set_speed, lead_visible): + values = { + "ACA_StaACC": acc_status, + "ACA_Zeitluecke": 2, + "ACA_V_Wunsch": set_speed, + "ACA_gemZeitl": 8 if lead_visible else 0, + } + # TODO: ACA_ID_StaACC, ACA_AnzDisplay, ACA_kmh_mph, ACA_PrioDisp, ACA_Aend_Zeitluecke + + return packer.make_can_msg("ACC_GRA_Anziege", bus, values) diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py index 785a70d2dab3dc..58f071901b990e 100755 --- a/selfdrive/car/volkswagen/values.py +++ b/selfdrive/car/volkswagen/values.py @@ -18,6 +18,11 @@ class CarControllerParams: HCA_STEP = 2 # HCA_01/HCA_1 message frequency 50Hz GRA_ACC_STEP = 3 # GRA_ACC_01/GRA_Neu message frequency 33Hz + ACC_CONTROL_STEP = 2 # ACC_06/ACC_07/ACC_System frequency 50Hz + ACC_HUD_STEP = 4 # ACC_GRA_Anziege frequency 25Hz + + ACCEL_MAX = 2.0 # 2.0 m/s max acceleration + ACCEL_MIN = -3.5 # 3.5 m/s max deceleration def __init__(self, CP): # Documented lateral limits: 3.00 Nm max, rate of change 5.00 Nm/sec. @@ -29,7 +34,35 @@ def __init__(self, CP): can_define = CANDefine(DBC[CP.carFingerprint]["pt"]) - if True: # pylint: disable=using-constant-test + if CP.carFingerprint in PQ_CARS: + self.LDW_STEP = 5 # LDW_1 message frequency 20Hz + self.STEER_DRIVER_ALLOWANCE = 80 # Driver intervention threshold 0.8 Nm + self.STEER_DELTA_UP = 6 # Max HCA reached in 1.00s (STEER_MAX / (50Hz * 1.00)) + self.STEER_DELTA_DOWN = 10 # Min HCA reached in 0.60s (STEER_MAX / (50Hz * 0.60)) + + if CP.transmissionType == TransmissionType.automatic: + self.shifter_values = can_define.dv["Getriebe_1"]["Waehlhebelposition__Getriebe_1_"] + 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]), + ] + + self.LDW_MESSAGES = { + "none": 0, # Nothing to display + "laneAssistUnavail": 1, # "Lane Assist currently not available." + "laneAssistUnavailSysError": 2, # "Lane Assist system error" + "laneAssistUnavailNoSensorView": 3, # "Lane Assist not available. No sensor view." + "laneAssistTakeOver": 4, # "Lane Assist: Please Take Over Steering" + "laneAssistDeactivTrailer": 5, # "Lane Assist: no function with trailer" + } + + else: self.LDW_STEP = 10 # LDW_02 message frequency 10Hz self.STEER_DRIVER_ALLOWANCE = 80 # Driver intervention threshold 0.8 Nm self.STEER_DELTA_UP = 4 # Max HCA reached in 1.50s (STEER_MAX / (50Hz * 1.50)) @@ -79,6 +112,7 @@ class CAR: GOLF_MK7 = "VOLKSWAGEN GOLF 7TH GEN" # Chassis 5G/AU/BA/BE, Mk7 VW Golf and variants JETTA_MK7 = "VOLKSWAGEN JETTA 7TH GEN" # Chassis BU, Mk7 VW Jetta PASSAT_MK8 = "VOLKSWAGEN PASSAT 8TH GEN" # Chassis 3G, Mk8 VW Passat and variants + PASSAT_NMS = "VOLKSWAGEN PASSAT NMS" # Chassis A3, North America/China/Mideast NMS Passat, incl. facelift POLO_MK6 = "VOLKSWAGEN POLO 6TH GEN" # Chassis AW, Mk6 VW Polo TAOS_MK1 = "VOLKSWAGEN TAOS 1ST GEN" # Chassis B2, Mk1 VW Taos and Tharu TCROSS_MK1 = "VOLKSWAGEN T-CROSS 1ST GEN" # Chassis C1, Mk1 VW T-Cross SWB and LWB variants @@ -99,7 +133,12 @@ class CAR: SKODA_OCTAVIA_MK3 = "SKODA OCTAVIA 3RD GEN" # Chassis NE, Mk3 Skoda Octavia and variants +PQ_CARS = {CAR.PASSAT_NMS} + + DBC: Dict[str, Dict[str, str]] = defaultdict(lambda: dbc_dict("vw_mqb_2010", None)) +for car_type in PQ_CARS: + DBC[car_type] = dbc_dict("vw_golf_mk4", None) class Footnote(Enum): @@ -160,6 +199,7 @@ class VWCarInfo(CarInfo): VWCarInfo("Volkswagen Passat Alltrack 2015-22", footnotes=[Footnote.VW_HARNESS], harness=Harness.j533), VWCarInfo("Volkswagen Passat GTE 2015-22", footnotes=[Footnote.VW_HARNESS, Footnote.VW_VARIANT], harness=Harness.j533), ], + CAR.PASSAT_NMS: VWCarInfo("Volkswagen Passat NMS 2017-22", harness=Harness.j533), CAR.POLO_MK6: [ VWCarInfo("Volkswagen Polo 2020-22", footnotes=[Footnote.VW_HARNESS], harness=Harness.j533), VWCarInfo("Volkswagen Polo GTI 2020-22", footnotes=[Footnote.VW_HARNESS], harness=Harness.j533), @@ -514,6 +554,26 @@ class VWCarInfo(CarInfo): b'\xf1\x875Q0907572R \xf1\x890771', ], }, + CAR.PASSAT_NMS: { + (Ecu.engine, 0x7e0, None): [ + b'\xf1\x8706K906016C \xf1\x899609', + b'\xf1\x8706K906016G \xf1\x891124', + b'\xf1\x8706K906071BJ\xf1\x894891', + ], + (Ecu.transmission, 0x7e1, None): [ + b'\xf1\x8709G927158AB\xf1\x893318', + b'\xf1\x8709G927158BD\xf1\x893121', + b'\xf1\x8709G927158FQ\xf1\x893745', + ], + (Ecu.srs, 0x715, None): [ + b'\xf1\x87561959655 \xf1\x890210\xf1\x82\02212121111113000102011--121012--101312', + b'\xf1\x87561959655C \xf1\x890508\xf1\x82\02215141111121100314919--153015--304831', + ], + (Ecu.fwdRadar, 0x757, None): [ + b'\xf1\x87561907567A \xf1\x890132', + b'\xf1\x877N0907572C \xf1\x890211\xf1\x82\00152', + ], + }, CAR.POLO_MK6: { (Ecu.engine, 0x7e0, None): [ b'\xf1\x8704C906025H \xf1\x895177', diff --git a/selfdrive/test/process_replay/test_processes.py b/selfdrive/test/process_replay/test_processes.py index 68c1666b599e46..f5aaec362295f8 100755 --- a/selfdrive/test/process_replay/test_processes.py +++ b/selfdrive/test/process_replay/test_processes.py @@ -32,8 +32,9 @@ ("VOLKSWAGEN", "de9592456ad7d144|2021-06-29--11-00-15--6"), # VOLKSWAGEN.GOLF ("MAZDA", "bd6a637565e91581|2021-10-30--15-14-53--2"), # MAZDA.CX9_2021 - # Enable when port is tested and dascamOnly is no longer set + # Enable when port is tested and dashcamOnly is no longer set #("TESLA", "bb50caf5f0945ab1|2021-06-19--17-20-18--3"), # TESLA.AP2_MODELS + #("VOLKSWAGEN2", "3cfdec54aa035f3f|2022-07-19--23-45-10--2"), # VOLKSWAGEN.PASSAT_NMS ] segments = [ From f35468e88c228ae9d3138213525ffdd5beb3edcd Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 16 Aug 2022 14:48:26 -0700 Subject: [PATCH 040/106] Update RELEASES.md --- RELEASES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index bcd6aa7aa1b5fb..364d2a494b9141 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,5 +1,8 @@ Version 0.8.16 (2022-XX-XX) ======================== +* New driving model + * Reduced turn cutting +* Auto-detect right hand drive setting with driver monitoring model * Chevrolet Bolt EUV 2022-23 support thanks to JasonJShuler! * Hyundai Ioniq 5 2022 support thanks to sunnyhaibin! * Hyundai Kona Electric 2022 support thanks to sunnyhaibin! From aa32ea0f64e4035ac929e09ee85d268c3185221c Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 16 Aug 2022 16:37:58 -0700 Subject: [PATCH 041/106] loggerd: log all disk space usage in initData (#25455) * bootlog: log all disk space usage * not just agnos * move to initData * cleanup --- cereal | 2 +- selfdrive/loggerd/bootlog.cc | 22 +++++++++------------- selfdrive/loggerd/logger.cc | 27 +++++++++++++++++++++------ 3 files changed, 31 insertions(+), 20 deletions(-) diff --git a/cereal b/cereal index 5ab19700178f01..2d648b0dc4654f 160000 --- a/cereal +++ b/cereal @@ -1 +1 @@ -Subproject commit 5ab19700178f01c14f362735532ee2662ab755fc +Subproject commit 2d648b0dc4654fc7088ffb81fd301352707de749 diff --git a/selfdrive/loggerd/bootlog.cc b/selfdrive/loggerd/bootlog.cc index 882b749fe9d7b6..90ba487ff0984e 100644 --- a/selfdrive/loggerd/bootlog.cc +++ b/selfdrive/loggerd/bootlog.cc @@ -7,12 +7,6 @@ static kj::Array build_boot_log() { - std::vector bootlog_commands; - if (Hardware::AGNOS()) { - bootlog_commands.push_back("journalctl"); - bootlog_commands.push_back("sudo nvme smart-log --output-format=json /dev/nvme0"); - } - MessageBuilder msg; auto boot = msg.initEvent().initBoot(); @@ -31,17 +25,19 @@ static kj::Array build_boot_log() { } // Gather output of commands - i = 0; + std::vector bootlog_commands = { + "[ -e /dev/nvme0 ] && sudo nvme smart-log --output-format=json /dev/nvme0", + "[ -x \"$(command -v journalctl)\" ] && journalctl", + }; + auto commands = boot.initCommands().initEntries(bootlog_commands.size()); - for (auto &command : bootlog_commands) { - auto lentry = commands[i]; + for (int j = 0; j < bootlog_commands.size(); j++) { + auto lentry = commands[j]; - lentry.setKey(command); + lentry.setKey(bootlog_commands[j]); - const std::string result = util::check_output(command); + const std::string result = util::check_output(bootlog_commands[j]); lentry.setValue(capnp::Data::Reader((const kj::byte*)result.data(), result.size())); - - i++; } boot.setLaunchLog(util::read_file("/tmp/launch_log")); diff --git a/selfdrive/loggerd/logger.cc b/selfdrive/loggerd/logger.cc index 8038f1926c8d47..da3710cc72a69b 100644 --- a/selfdrive/loggerd/logger.cc +++ b/selfdrive/loggerd/logger.cc @@ -24,9 +24,11 @@ kj::Array logger_build_init_data() { MessageBuilder msg; auto init = msg.initEvent().initInitData(); - init.setDeviceType(Hardware::get_device_type()); init.setVersion(COMMA_VERSION); + init.setDirty(!getenv("CLEAN")); + init.setDeviceType(Hardware::get_device_type()); + // log kernel args std::ifstream cmdline_stream("/proc/cmdline"); std::vector kernel_args; std::string buf; @@ -42,8 +44,6 @@ kj::Array logger_build_init_data() { init.setKernelVersion(util::read_file("/proc/version")); init.setOsVersion(util::read_file("/VERSION")); - init.setDirty(!getenv("CLEAN")); - // log params auto params = Params(); std::map params_map = params.readAll(); @@ -55,16 +55,31 @@ kj::Array logger_build_init_data() { init.setDongleId(params_map["DongleId"]); auto lparams = init.initParams().initEntries(params_map.size()); - int i = 0; + int j = 0; for (auto& [key, value] : params_map) { - auto lentry = lparams[i]; + auto lentry = lparams[j]; lentry.setKey(key); if ( !(params.getKeyType(key) & DONT_LOG) ) { lentry.setValue(capnp::Data::Reader((const kj::byte*)value.data(), value.size())); } - i++; + j++; + } + + // log commands + std::vector log_commands = { + "df -h", // usage for all filesystems + }; + + auto commands = init.initCommands().initEntries(log_commands.size()); + for (int i = 0; i < log_commands.size(); i++) { + auto lentry = commands[i]; + lentry.setKey(log_commands[i]); + + const std::string result = util::check_output(log_commands[i]); + lentry.setValue(capnp::Data::Reader((const kj::byte*)result.data(), result.size())); } + return capnp::messageToFlatArray(msg); } From bacd2d5aee139865e1520c7d608883196edf2c42 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Tue, 16 Aug 2022 18:39:20 -0700 Subject: [PATCH 042/106] Kona: remove pid tuning --- selfdrive/car/hyundai/interface.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/selfdrive/car/hyundai/interface.py b/selfdrive/car/hyundai/interface.py index 9080e5cdb91cd4..6b62477a0caab2 100644 --- a/selfdrive/car/hyundai/interface.py +++ b/selfdrive/car/hyundai/interface.py @@ -115,13 +115,10 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl ret.lateralTuning.indi.actuatorEffectivenessV = [2.3] ret.minSteerSpeed = 60 * CV.KPH_TO_MS elif candidate in (CAR.KONA, CAR.KONA_EV, CAR.KONA_HEV, CAR.KONA_EV_2022): - ret.lateralTuning.pid.kf = 0.00005 ret.mass = {CAR.KONA_EV: 1685., CAR.KONA_HEV: 1425., CAR.KONA_EV_2022: 1743.}.get(candidate, 1275.) + STD_CARGO_KG ret.wheelbase = 2.6 ret.steerRatio = 13.42 # Spec tire_stiffness_factor = 0.385 - ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] - ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.25], [0.05]] CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) elif candidate in (CAR.IONIQ, CAR.IONIQ_EV_LTD, CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.IONIQ_HEV_2022): ret.lateralTuning.pid.kf = 0.00006 From b3dc7bb3cb75661993c068b993712a3a9f5238a2 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Tue, 16 Aug 2022 18:40:30 -0700 Subject: [PATCH 043/106] regen: initialize once (#25458) regen: init once --- selfdrive/test/process_replay/regen.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/selfdrive/test/process_replay/regen.py b/selfdrive/test/process_replay/regen.py index 39f75ce428aac6..16d7ea85198c7b 100755 --- a/selfdrive/test/process_replay/regen.py +++ b/selfdrive/test/process_replay/regen.py @@ -201,14 +201,14 @@ def regen_segment(lr, frs=None, outdir=FAKEDATA, disable_tqdm=False): params = Params() os.environ["LOG_ROOT"] = outdir - for msg in lr: - if msg.which() == 'carParams': - setup_env(CP=msg.carParams) - elif msg.which() == 'liveCalibration': - params.put("CalibrationParams", msg.as_builder().to_bytes()) + # Get and setup initial state + CP = [m for m in lr if m.which() == 'carParams'][0].carParams + liveCalibration = [m for m in lr if m.which() == 'liveCalibration'][0] - vs, cam_procs = replay_cameras(lr, frs, disable_tqdm=disable_tqdm) + setup_env(CP=CP) + params.put("CalibrationParams", liveCalibration.as_builder().to_bytes()) + vs, cam_procs = replay_cameras(lr, frs, disable_tqdm=disable_tqdm) fake_daemons = { 'sensord': [ multiprocessing.Process(target=replay_sensor_events, args=('sensorEvents', lr)), From 1388c80a8f6b2e502ec771afba80d37df4da70ba Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 16 Aug 2022 18:41:45 -0700 Subject: [PATCH 044/106] Toyota: remove Camry Hybrid footnote (#25457) * Toyota: remove TSS2 camry footnote * Apply suggestions from code review * update docs Co-authored-by: Shane Smiskol --- docs/CARS.md | 2 +- selfdrive/car/toyota/values.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/CARS.md b/docs/CARS.md index ff539f052174ce..fd82a5aa842cc6 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -165,7 +165,7 @@ A supported vehicle is one that just works when you install a comma device. Ever |Toyota|C-HR Hybrid 2017-19|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Toyota|Camry 2018-20|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)[4](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Toyota|Camry 2021-22|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)[4](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Camry Hybrid 2018-20|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)[4](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| +|Toyota|Camry Hybrid 2018-20|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Toyota|Camry Hybrid 2021-22|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Toyota|Corolla 2017-19|All|[![star](assets/icon-star-half.svg)](##)[3](#footnotes)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Toyota|Corolla 2020-22|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index b7b261adb0224c..b4e82ec3e361b5 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -114,7 +114,7 @@ class ToyotaCarInfo(CarInfo): CAR.AVALON_TSS2: ToyotaCarInfo("Toyota Avalon 2022"), CAR.AVALONH_TSS2: ToyotaCarInfo("Toyota Avalon Hybrid 2022"), CAR.CAMRY: ToyotaCarInfo("Toyota Camry 2018-20", video_link="https://www.youtube.com/watch?v=fkcjviZY9CM", footnotes=[Footnote.CAMRY]), - CAR.CAMRYH: ToyotaCarInfo("Toyota Camry Hybrid 2018-20", video_link="https://www.youtube.com/watch?v=Q2DYY0AWKgk", footnotes=[Footnote.CAMRY]), + CAR.CAMRYH: ToyotaCarInfo("Toyota Camry Hybrid 2018-20", video_link="https://www.youtube.com/watch?v=Q2DYY0AWKgk"), CAR.CAMRY_TSS2: ToyotaCarInfo("Toyota Camry 2021-22", footnotes=[Footnote.CAMRY]), CAR.CAMRYH_TSS2: ToyotaCarInfo("Toyota Camry Hybrid 2021-22"), CAR.CHR: ToyotaCarInfo("Toyota C-HR 2017-21"), From d7095d0d4368f0168433455f16236151a91ef83c Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Tue, 16 Aug 2022 19:39:11 -0700 Subject: [PATCH 045/106] process replay: show errors when updating refs (#25460) * Update test_processes.py * Apply suggestions from code review --- selfdrive/test/process_replay/test_processes.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/selfdrive/test/process_replay/test_processes.py b/selfdrive/test/process_replay/test_processes.py index f5aaec362295f8..608d0c4af3f4e4 100755 --- a/selfdrive/test/process_replay/test_processes.py +++ b/selfdrive/test/process_replay/test_processes.py @@ -248,8 +248,12 @@ def format_diff(results, log_paths, ref_commit): print("TEST SUCCEEDED") else: - with open(REF_COMMIT_FN, "w") as f: - f.write(cur_commit) - print(f"\n\nUpdated reference logs for commit: {cur_commit}") + if failed: + print(diff1) + print("FAILED TO UPDATE REFS") + else: + with open(REF_COMMIT_FN, "w") as f: + f.write(cur_commit) + print(f"\n\nUpdated reference logs for commit: {cur_commit}") sys.exit(int(failed)) From 63fb3e591e3d4c6a992ff3e9e7509a08b0f76659 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Tue, 16 Aug 2022 20:57:06 -0700 Subject: [PATCH 046/106] Kia: add missing Niro EV 2020 FW versions (#25446) Add missing FW versions from 9b052af2986bbe3c --- selfdrive/car/hyundai/values.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index afd17b86ad4322..c61efcdac42d5b 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -1010,6 +1010,7 @@ class Buttons: b'\xf1\x00DEev SCC F-CUP 1.00 1.02 96400-Q4000 ', b'\xf1\x00DEev SCC F-CUP 1.00 1.02 96400-Q4100 ', b'\xf1\x00DEev SCC F-CUP 1.00 1.03 96400-Q4100 ', + b'\xf1\x00DEev SCC FHCUP 1.00 1.03 96400-Q4000 ', b'\xf1\x8799110Q4000\xf1\x00DEev SCC F-CUP 1.00 1.00 99110-Q4000 ', b'\xf1\x8799110Q4100\xf1\x00DEev SCC F-CUP 1.00 1.00 99110-Q4100 ', b'\xf1\x8799110Q4500\xf1\x00DEev SCC F-CUP 1.00 1.00 99110-Q4500 ', @@ -1029,6 +1030,7 @@ class Buttons: b'\xf1\x00DEE MFC AT USA LHD 1.00 1.03 95740-Q4000 180821', b'\xf1\x00DEE MFC AT USA LHD 1.00 1.01 99211-Q4500 210428', b'\xf1\x00DEE MFC AT EUR LHD 1.00 1.03 95740-Q4000 180821', + b'\xf1\x00DEE MFC AT KOR LHD 1.00 1.03 95740-Q4000 180821', ], }, CAR.KIA_NIRO_HEV: { From 87ca42e993f1cc96cc313e33b3c538143e0a737c Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Tue, 16 Aug 2022 22:02:03 -0700 Subject: [PATCH 047/106] process replay: initialize controlsState with original route (#25461) * push * do process replay * commit * update refs * clean up * clean up controlsd * clean up controlsd * Add assert * debubuggier param name * can be peristent * Revert "can be peristent" This reverts commit 6e6d3f6423c26a202623cef728e038259e9e46cd. * Update selfdrive/test/process_replay/process_replay.py --- common/params.cc | 1 + selfdrive/controls/controlsd.py | 16 +++++++++---- .../test/process_replay/process_replay.py | 24 ++++++++++++++++--- selfdrive/test/process_replay/ref_commit | 2 +- selfdrive/test/process_replay/regen.py | 3 ++- .../test/process_replay/test_processes.py | 12 ++++------ 6 files changed, 41 insertions(+), 17 deletions(-) diff --git a/common/params.cc b/common/params.cc index 11b24fe9c120df..f89e7ff002b572 100644 --- a/common/params.cc +++ b/common/params.cc @@ -151,6 +151,7 @@ std::unordered_map keys = { {"RecordFront", PERSISTENT}, {"RecordFrontLock", PERSISTENT}, // for the internal fleet {"ReleaseNotes", PERSISTENT}, + {"ReplayControlsState", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON}, {"ShouldDoUpdate", CLEAR_ON_MANAGER_START}, {"SnoozeUpdate", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF}, {"SshEnabled", PERSISTENT}, diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 3b2307f04ad6f6..80d9bccb054328 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -203,6 +203,16 @@ def __init__(self, sm=None, pm=None, can_sock=None, CI=None): self.rk = Ratekeeper(100, print_delay_threshold=None) self.prof = Profiler(False) # off by default + def set_initial_state(self): + if REPLAY: + controls_state = Params().get("ReplayControlsState") + if controls_state is not None: + controls_state = log.ControlsState.from_bytes(controls_state) + self.v_cruise_kph = controls_state.vCruise + + if self.sm['pandaStates'][0].controlsAllowed: + self.state = State.enabled + def update_events(self, CS): """Compute carEvents from carState""" @@ -417,11 +427,9 @@ def data_sample(self): if all_valid or timed_out or SIMULATION: if not self.read_only: self.CI.init(self.CP, self.can_sock, self.pm.sock['sendcan']) - self.initialized = True - - if REPLAY and self.sm['pandaStates'][0].controlsAllowed: - self.state = State.enabled + self.initialized = True + self.set_initial_state() Params().put_bool("ControlsReady", True) # Check for CAN timeout diff --git a/selfdrive/test/process_replay/process_replay.py b/selfdrive/test/process_replay/process_replay.py index 32a3c2f3bb0bf7..8b9c77625f9ba1 100755 --- a/selfdrive/test/process_replay/process_replay.py +++ b/selfdrive/test/process_replay/process_replay.py @@ -385,7 +385,7 @@ def replay_process(cfg, lr, fingerprint=None): return cpp_replay_process(cfg, lr, fingerprint) -def setup_env(simulation=False, CP=None, cfg=None): +def setup_env(simulation=False, CP=None, cfg=None, controlsState=None): params = Params() params.clear_all() params.put_bool("OpenpilotEnabledToggle", True) @@ -414,6 +414,12 @@ def setup_env(simulation=False, CP=None, cfg=None): elif "SIMULATION" in os.environ: del os.environ["SIMULATION"] + # Initialize controlsd with a controlsState packet + if controlsState is not None: + params.put("ReplayControlsState", controlsState.as_builder().to_bytes()) + else: + params.delete("ReplayControlsState") + # Regen or python process if CP is not None: if CP.alternativeExperience == ALTERNATIVE_EXPERIENCE.DISABLE_DISENGAGE_ON_GAS: @@ -440,13 +446,25 @@ def python_replay_process(cfg, lr, fingerprint=None): all_msgs = sorted(lr, key=lambda msg: msg.logMonoTime) pub_msgs = [msg for msg in all_msgs if msg.which() in list(cfg.pub_sub.keys())] + controlsState = None + initialized = False + for msg in lr: + if msg.which() == 'controlsState': + controlsState = msg.controlsState + if initialized: + break + elif msg.which() == 'carEvents': + initialized = car.CarEvent.EventName.controlsInitializing not in [e.name for e in msg.carEvents] + + assert controlsState is not None and initialized, "controlsState never initialized" + if fingerprint is not None: os.environ['SKIP_FW_QUERY'] = "1" os.environ['FINGERPRINT'] = fingerprint - setup_env(cfg=cfg) + setup_env(cfg=cfg, controlsState=controlsState) else: CP = [m for m in lr if m.which() == 'carParams'][0].carParams - setup_env(CP=CP, cfg=cfg) + setup_env(CP=CP, cfg=cfg, controlsState=controlsState) assert(type(managed_processes[cfg.proc_name]) is PythonProcess) managed_processes[cfg.proc_name].prepare() diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 8aa80d6b7946f1..400d27f1a7de4c 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -118d78e2040103c00b4bfcc875fcdcd6a15e2211 +375f581030fe8efeb9dacd63875b3f046d3b420f \ No newline at end of file diff --git a/selfdrive/test/process_replay/regen.py b/selfdrive/test/process_replay/regen.py index 16d7ea85198c7b..4e1cbfd30d8684 100755 --- a/selfdrive/test/process_replay/regen.py +++ b/selfdrive/test/process_replay/regen.py @@ -203,9 +203,10 @@ def regen_segment(lr, frs=None, outdir=FAKEDATA, disable_tqdm=False): # Get and setup initial state CP = [m for m in lr if m.which() == 'carParams'][0].carParams + controlsState = [m for m in lr if m.which() == 'controlsState'][0].controlsState liveCalibration = [m for m in lr if m.which() == 'liveCalibration'][0] - setup_env(CP=CP) + setup_env(CP=CP, controlsState=controlsState) params.put("CalibrationParams", liveCalibration.as_builder().to_bytes()) vs, cam_procs = replay_cameras(lr, frs, disable_tqdm=disable_tqdm) diff --git a/selfdrive/test/process_replay/test_processes.py b/selfdrive/test/process_replay/test_processes.py index 608d0c4af3f4e4..2a005cf4cc67d8 100755 --- a/selfdrive/test/process_replay/test_processes.py +++ b/selfdrive/test/process_replay/test_processes.py @@ -49,7 +49,7 @@ ("CHRYSLER", "regen38346FB33D0|2022-07-14--18-05-26--0"), ("RAM", "2f4452b03ccb98f0|2022-07-07--08-01-56--3"), ("SUBARU", "regen54A1E2BE5AA|2022-07-14--18-07-50--0"), - ("GM", "regen01D09D915B5|2022-07-06--14-36-20--0"), + ("GM", "regen76027B408B7|2022-08-16--19-56-58--0"), ("NISSAN", "regenCA0B0DC946E|2022-07-14--18-10-17--0"), ("VOLKSWAGEN", "regen007098CA0EF|2022-07-06--15-01-26--0"), ("MAZDA", "regen61BA413D53B|2022-07-06--14-39-42--0"), @@ -248,12 +248,8 @@ def format_diff(results, log_paths, ref_commit): print("TEST SUCCEEDED") else: - if failed: - print(diff1) - print("FAILED TO UPDATE REFS") - else: - with open(REF_COMMIT_FN, "w") as f: - f.write(cur_commit) - print(f"\n\nUpdated reference logs for commit: {cur_commit}") + with open(REF_COMMIT_FN, "w") as f: + f.write(cur_commit) + print(f"\n\nUpdated reference logs for commit: {cur_commit}") sys.exit(int(failed)) From e0e0aad144f1e47486faa8c06d54d29c3dd94c79 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 17 Aug 2022 15:20:18 -0700 Subject: [PATCH 048/106] Chrysler: ensure control bit is high before torque cmd (#25465) * Chrysler: ensure control bit is high before torque cmd * move that & update refs * check control bit too --- selfdrive/car/chrysler/carcontroller.py | 39 ++++++++++++------------ selfdrive/test/process_replay/ref_commit | 2 +- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/selfdrive/car/chrysler/carcontroller.py b/selfdrive/car/chrysler/carcontroller.py index 22abf1b677d5fa..5a2d90c64c2410 100644 --- a/selfdrive/car/chrysler/carcontroller.py +++ b/selfdrive/car/chrysler/carcontroller.py @@ -22,23 +22,8 @@ def __init__(self, dbc_name, CP, VM): def update(self, CC, CS): can_sends = [] - # TODO: can we make this more sane? why is it different for all the cars? - lkas_control_bit = self.lkas_control_bit_prev - if CS.out.vEgo > self.CP.minSteerSpeed: - lkas_control_bit = True - elif self.CP.carFingerprint in (CAR.PACIFICA_2019_HYBRID, CAR.PACIFICA_2020, CAR.JEEP_CHEROKEE_2019): - if CS.out.vEgo < (self.CP.minSteerSpeed - 3.0): - lkas_control_bit = False - elif self.CP.carFingerprint in RAM_CARS: - if CS.out.vEgo < (self.CP.minSteerSpeed - 0.5): - lkas_control_bit = False - - # EPS faults if LKAS re-enables too quickly - lkas_control_bit = lkas_control_bit and (self.frame - self.last_lkas_falling_edge > 200) lkas_active = CC.latActive and self.lkas_control_bit_prev - # *** control msgs *** - # cruise buttons if (self.frame - self.last_button_frame)*DT_CTRL > 0.05: das_bus = 2 if self.CP.carFingerprint in RAM_CARS else 0 @@ -61,19 +46,35 @@ def update(self, CC, CS): # steering if self.frame % 2 == 0: + + # TODO: can we make this more sane? why is it different for all the cars? + lkas_control_bit = self.lkas_control_bit_prev + if CS.out.vEgo > self.CP.minSteerSpeed: + lkas_control_bit = True + elif self.CP.carFingerprint in (CAR.PACIFICA_2019_HYBRID, CAR.PACIFICA_2020, CAR.JEEP_CHEROKEE_2019): + if CS.out.vEgo < (self.CP.minSteerSpeed - 3.0): + lkas_control_bit = False + elif self.CP.carFingerprint in RAM_CARS: + if CS.out.vEgo < (self.CP.minSteerSpeed - 0.5): + lkas_control_bit = False + + # EPS faults if LKAS re-enables too quickly + lkas_control_bit = lkas_control_bit and (self.frame - self.last_lkas_falling_edge > 200) + + if not lkas_control_bit and self.lkas_control_bit_prev: + self.last_lkas_falling_edge = self.frame + self.lkas_control_bit_prev = lkas_control_bit + # steer torque new_steer = int(round(CC.actuators.steer * self.params.STEER_MAX)) apply_steer = apply_toyota_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorqueEps, self.params) - if not lkas_active: + if not lkas_active or not lkas_control_bit: apply_steer = 0 self.apply_steer_last = apply_steer can_sends.append(create_lkas_command(self.packer, self.CP, int(apply_steer), lkas_control_bit)) self.frame += 1 - if not lkas_control_bit and self.lkas_control_bit_prev: - self.last_lkas_falling_edge = self.frame - self.lkas_control_bit_prev = lkas_control_bit new_actuators = CC.actuators.copy() new_actuators.steer = self.apply_steer_last / self.params.STEER_MAX diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 400d27f1a7de4c..57d80369f149dc 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -375f581030fe8efeb9dacd63875b3f046d3b420f \ No newline at end of file +29e406826b1d7b0cc7e05153b623fbedcd8fd9e9 \ No newline at end of file From baef4c1fb2b9dd20bfa172eb49961c4171076b1f Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 17 Aug 2022 15:30:20 -0700 Subject: [PATCH 049/106] expand fingerprint dict size for multipanda setups --- selfdrive/car/__init__.py | 2 +- selfdrive/car/tests/test_car_interfaces.py | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/selfdrive/car/__init__.py b/selfdrive/car/__init__.py index c77e40daaf28bb..f2d198338d81f4 100644 --- a/selfdrive/car/__init__.py +++ b/selfdrive/car/__init__.py @@ -38,7 +38,7 @@ def create_button_enable_events(buttonEvents: capnp.lib.capnp._DynamicListBuilde def gen_empty_fingerprint(): - return {i: {} for i in range(0, 4)} + return {i: {} for i in range(0, 8)} # FIXME: hardcoding honda civic 2016 touring params so they can be used to diff --git a/selfdrive/car/tests/test_car_interfaces.py b/selfdrive/car/tests/test_car_interfaces.py index 412874c813e661..aabf652c8ccfce 100755 --- a/selfdrive/car/tests/test_car_interfaces.py +++ b/selfdrive/car/tests/test_car_interfaces.py @@ -5,6 +5,7 @@ from parameterized import parameterized from cereal import car +from selfdrive.car import gen_empty_fingerprint from selfdrive.car.fingerprints import all_known_cars from selfdrive.car.car_helpers import interfaces from selfdrive.car.fingerprints import _FINGERPRINTS as FINGERPRINTS @@ -19,11 +20,8 @@ def test_car_interfaces(self, car_name): fingerprint = {} CarInterface, CarController, CarState = interfaces[car_name] - fingerprints = { - 0: fingerprint, - 1: fingerprint, - 2: fingerprint, - } + fingerprints = gen_empty_fingerprint() + fingerprints.update({k: fingerprint for k in fingerprints.keys()}) car_fw = [] From 5ed587ebeff24bacf70c44879616c51756730bba Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Wed, 17 Aug 2022 18:03:33 -0700 Subject: [PATCH 050/106] controls: block resume if cruise not previously engaged (#25402) * see if this works at all * can revert this * think adding a no entry conditionally is nicer * then we can revert this * 0 makes more sense * Revert "0 makes more sense" This reverts commit efc89e8a2389ef58fbc0cec0a2872d24db524867. * gm CC uses > 70 * bump cereal * comment * test on Honda * whoops * works * add exception with todo * moved button enable events to controlsd * get rid of that get rid of that * different values for now * car interfaces add enable event, controlsd can block it * Regen and update refs * delete if not set * One place one place * regen routes are uninitialized first few frames * Trim start of segment so it's like original segment * stash * regen * not working * clean up * more cleanup * revert * bump ceral * actually check resume button * whoops * pcmCruise cars don't use setSpeed, so we're good * engage correctly in sim * Update ref_commit * Update refs --- cereal | 2 +- selfdrive/controls/controlsd.py | 32 ++++++++++++++--------- selfdrive/controls/lib/drive_helpers.py | 1 + selfdrive/controls/lib/events.py | 4 +++ selfdrive/test/process_replay/ref_commit | 2 +- tools/sim/tests/test_carla_integration.py | 2 +- 6 files changed, 27 insertions(+), 16 deletions(-) diff --git a/cereal b/cereal index 2d648b0dc4654f..f60f0ef200afa9 160000 --- a/cereal +++ b/cereal @@ -1 +1 @@ -Subproject commit 2d648b0dc4654fc7088ffb81fd301352707de749 +Subproject commit f60f0ef200afa9c7da932454b592ad5b0fb58493 diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 80d9bccb054328..1f394d487ada59 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -16,7 +16,7 @@ from selfdrive.boardd.boardd import can_list_to_can_capnp from selfdrive.car.car_helpers import get_car, get_startup_event, get_one_can from selfdrive.controls.lib.lane_planner import CAMERA_OFFSET -from selfdrive.controls.lib.drive_helpers import update_v_cruise, initialize_v_cruise +from selfdrive.controls.lib.drive_helpers import V_CRUISE_INITIAL, update_v_cruise, initialize_v_cruise from selfdrive.controls.lib.drive_helpers import get_lag_adjusted_curvature from selfdrive.controls.lib.latcontrol import LatControl from selfdrive.controls.lib.longcontrol import LongControl @@ -50,6 +50,7 @@ LaneChangeDirection = log.LateralPlan.LaneChangeDirection EventName = car.CarEvent.EventName ButtonEvent = car.CarState.ButtonEvent +ButtonType = car.CarState.ButtonEvent.Type SafetyModel = car.CarParams.SafetyModel IGNORED_SAFETY_MODES = (SafetyModel.silent, SafetyModel.noOutput) @@ -162,8 +163,8 @@ def __init__(self, sm=None, pm=None, can_sock=None, CI=None): self.active = False self.can_rcv_error = False self.soft_disable_timer = 0 - self.v_cruise_kph = 255 - self.v_cruise_cluster_kph = 255 + self.v_cruise_kph = V_CRUISE_INITIAL + self.v_cruise_cluster_kph = V_CRUISE_INITIAL self.v_cruise_kph_last = 0 self.mismatch_counter = 0 self.cruise_mismatch_counter = 0 @@ -228,6 +229,11 @@ def update_events(self, CS): self.events.add(EventName.controlsInitializing) return + # Block resume if cruise never previously enabled + resume_pressed = any(be.type in (ButtonType.accelCruise, ButtonType.resumeCruise) for be in CS.buttonEvents) + if not self.CP.pcmCruise and self.v_cruise_kph == V_CRUISE_INITIAL and resume_pressed: + self.events.add(EventName.resumeBlocked) + # Disable on rising edge of accelerator or brake. Also disable on brake when speed > 0 if (CS.gasPressed and not self.CS_prev.gasPressed and self.disengage_on_accelerator) or \ (CS.brakePressed and (not self.CS_prev.brakePressed or not CS.standstill)): @@ -460,18 +466,18 @@ def state_transition(self, CS): self.v_cruise_kph_last = self.v_cruise_kph - # if stock cruise is completely disabled, then we can use our own set speed logic - if not self.CP.pcmCruise: - self.v_cruise_kph = update_v_cruise(self.v_cruise_kph, CS.vEgo, CS.gasPressed, CS.buttonEvents, - self.button_timers, self.enabled, self.is_metric) - self.v_cruise_cluster_kph = self.v_cruise_kph - else: - if CS.cruiseState.available: + if CS.cruiseState.available: + # if stock cruise is completely disabled, then we can use our own set speed logic + if not self.CP.pcmCruise: + self.v_cruise_kph = update_v_cruise(self.v_cruise_kph, CS.vEgo, CS.gasPressed, CS.buttonEvents, + self.button_timers, self.enabled, self.is_metric) + self.v_cruise_cluster_kph = self.v_cruise_kph + else: self.v_cruise_kph = CS.cruiseState.speed * CV.MS_TO_KPH self.v_cruise_cluster_kph = CS.cruiseState.speedCluster * CV.MS_TO_KPH - else: - self.v_cruise_kph = 0 - self.v_cruise_cluster_kph = 0 + else: + self.v_cruise_kph = V_CRUISE_INITIAL + self.v_cruise_cluster_kph = V_CRUISE_INITIAL # decrement the soft disable timer at every step, as it's reset on # entrance in SOFT_DISABLING state diff --git a/selfdrive/controls/lib/drive_helpers.py b/selfdrive/controls/lib/drive_helpers.py index d79f94bbfdad82..ffa83738344825 100644 --- a/selfdrive/controls/lib/drive_helpers.py +++ b/selfdrive/controls/lib/drive_helpers.py @@ -11,6 +11,7 @@ V_CRUISE_MAX = 145 # kph V_CRUISE_MIN = 8 # kph V_CRUISE_ENABLE_MIN = 40 # kph +V_CRUISE_INITIAL = 255 # kph LAT_MPC_N = 16 LON_MPC_N = 32 diff --git a/selfdrive/controls/lib/events.py b/selfdrive/controls/lib/events.py index de666fd507c975..5139ead84bf195 100644 --- a/selfdrive/controls/lib/events.py +++ b/selfdrive/controls/lib/events.py @@ -635,6 +635,10 @@ def joystick_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, ET.NO_ENTRY: wrong_car_mode_alert, }, + EventName.resumeBlocked: { + ET.NO_ENTRY: NoEntryAlert("Press Set to Engage"), + }, + EventName.wrongCruiseMode: { ET.USER_DISABLE: EngagementAlert(AudibleAlert.disengage), ET.NO_ENTRY: NoEntryAlert("Adaptive Cruise Disabled"), diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 57d80369f149dc..da083eeee19604 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -29e406826b1d7b0cc7e05153b623fbedcd8fd9e9 \ No newline at end of file +35899d5137e298220e91063f3078109227cc8715 \ No newline at end of file diff --git a/tools/sim/tests/test_carla_integration.py b/tools/sim/tests/test_carla_integration.py index 43db783f4e38d4..f4673919674d29 100755 --- a/tools/sim/tests/test_carla_integration.py +++ b/tools/sim/tests/test_carla_integration.py @@ -77,7 +77,7 @@ def test_engage(self): while time.monotonic() < start_time + max_time_per_step: sm.update() - q.put("cruise_up") # Try engaging + q.put("cruise_down") # Try engaging if sm.all_alive() and sm['controlsState'].active: control_active += 1 From 96f8d3acd569a65b2989ce28299291e680d5222b Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 17 Aug 2022 20:00:15 -0700 Subject: [PATCH 051/106] rawgps in CI (#25473) --- release/files_tici | 2 ++ selfdrive/manager/process_config.py | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/release/files_tici b/release/files_tici index f8c0a279593806..8e3249cdfd55fb 100644 --- a/release/files_tici +++ b/release/files_tici @@ -11,5 +11,7 @@ system/camerad/cameras/camera_qcom2.cc system/camerad/cameras/camera_qcom2.h system/camerad/cameras/real_debayer.cl +selfdrive/sensord/rawgps/* + selfdrive/ui/qt/spinner_larch64 selfdrive/ui/qt/text_larch64 diff --git a/selfdrive/manager/process_config.py b/selfdrive/manager/process_config.py index dec51966a41dc8..927de563c5cb6f 100644 --- a/selfdrive/manager/process_config.py +++ b/selfdrive/manager/process_config.py @@ -2,7 +2,7 @@ from cereal import car from common.params import Params -from system.hardware import PC +from system.hardware import PC, TICI from selfdrive.manager.process import PythonProcess, NativeProcess, DaemonProcess WEBCAM = os.getenv("USE_WEBCAM") is not None @@ -57,7 +57,7 @@ def logging(started, params, CP: car.CarParams) -> bool: PythonProcess("webjoystick", "tools.joystick.web", onroad=False, callback=notcar), # Experimental - PythonProcess("rawgpsd", "selfdrive.sensord.rawgps.rawgpsd", enabled=os.path.isfile("/persist/comma/use-quectel-rawgps")), + PythonProcess("rawgpsd", "selfdrive.sensord.rawgps.rawgpsd", enabled=(TICI and os.path.isfile("/persist/comma/use-quectel-rawgps"))), ] managed_processes = {p.name: p for p in procs} From 1de8ad891bcf8c0b73b24f7e3eab17f3448e7473 Mon Sep 17 00:00:00 2001 From: eFini Date: Thu, 18 Aug 2022 11:21:38 +0800 Subject: [PATCH 052/106] Fix is_rhd param name in map.cc (#25464) --- selfdrive/ui/qt/maps/map.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/ui/qt/maps/map.cc b/selfdrive/ui/qt/maps/map.cc index f81c3dd8f07f20..046814d517d3e2 100644 --- a/selfdrive/ui/qt/maps/map.cc +++ b/selfdrive/ui/qt/maps/map.cc @@ -361,7 +361,7 @@ void MapWindow::offroadTransition(bool offroad) { } MapInstructions::MapInstructions(QWidget * parent) : QWidget(parent) { - is_rhd = Params().getBool("IsRHD"); + is_rhd = Params().getBool("IsRhdDetected"); QHBoxLayout *main_layout = new QHBoxLayout(this); main_layout->setContentsMargins(11, 50, 11, 11); { From 7087a154f57ced0919c2f27d6eb5ca4e89d853ac Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 17 Aug 2022 20:29:56 -0700 Subject: [PATCH 053/106] Ford: add Q3 and Q4 harnesses (#25474) --- selfdrive/car/docs_definitions.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/selfdrive/car/docs_definitions.py b/selfdrive/car/docs_definitions.py index 65dbe4c626ac7c..d882cd120dacd5 100644 --- a/selfdrive/car/docs_definitions.py +++ b/selfdrive/car/docs_definitions.py @@ -217,6 +217,8 @@ class Harness(Enum): nissan_a = "Nissan A" nissan_b = "Nissan B" mazda = "Mazda" + ford_q3 = "Ford Q3" + ford_q4 = "Ford Q4" none = "None" From c870d0cbdeacc3ab6c3e460fdc484c1961a5b2a0 Mon Sep 17 00:00:00 2001 From: Squiggle Squaggle Date: Wed, 17 Aug 2022 22:49:38 -0500 Subject: [PATCH 054/106] Hyundai: add missing FW for 2022 Elantra SEL (#25472) * added missing FW for 2022 Elantra SEL I connected the Comma 3 with Hyundai K Harness and the vehicle was unknown. I worked my way through fingerprint 2.0 and compared the FW I had with this file and added the missing firmware to the Elantra_2021 section. I then went for a drive and it worked as intended. A number of the fwVersion were already there and so I've only added the ones that were missing. * removed erroneous entries removed entries that were not labeled Hyundai that I had added. --- selfdrive/car/hyundai/values.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index c61efcdac42d5b..d22abc9e201811 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -1139,11 +1139,13 @@ class Buttons: b'\xf1\x00CN7 MFC AT USA LHD 1.00 1.00 99210-AB000 200819', b'\xf1\x00CN7 MFC AT USA LHD 1.00 1.03 99210-AA000 200819', b'\xf1\x00CN7 MFC AT USA LHD 1.00 1.01 99210-AB000 210205', + b'\xf1\x00CN7 MFC AT USA LHD 1.00 1.06 99210-AA000 220111', ], (Ecu.esp, 0x7d1, None): [ b'\xf1\x00CN ESC \t 101 \x10\x03 58910-AB800', b'\xf1\x8758910-AA800\xf1\x00CN ESC \t 104 \x08\x03 58910-AA800', b'\xf1\x8758910-AB800\xf1\x00CN ESC \t 101 \x10\x03 58910-AB800', + b'\xf1\x8758910-AA800\xf1\x00CN ESC \t 105 \x10\x03 58910-AA800', ], (Ecu.transmission, 0x7e1, None): [ b'\xf1\x00HT6WA280BLHT6VA640A1CCN0N20NS5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', @@ -1158,7 +1160,7 @@ class Buttons: b'\xf1\x82CNCWD0AMFCXCSFFA', b'\xf1\x82CNCWD0AMFCXCSFFB', b'\xf1\x82CNCVD0AMFCXCSFFB', - b'\xf1\x870\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x82CNDWD0AMFCXCSG8A', + b'\xf1\x870\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x81HM6M2_0a0_G80', ], }, CAR.ELANTRA_HEV_2021: { From 8ed87b12bc177c78ea3ca311d5a9e5675bea8436 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Wed, 17 Aug 2022 20:57:50 -0700 Subject: [PATCH 055/106] Hyundai: add missing Palisade transmission FW (#25476) Add missing transmission fp for Palisade --- selfdrive/car/hyundai/values.py | 1 + 1 file changed, 1 insertion(+) diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index d22abc9e201811..a27c6f68554086 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -810,6 +810,7 @@ class Buttons: b"\xf1\x87LBLUFN622950KF36\xa8\x88\x88\x88\x87w\x87xh\x99\x96\x89\x88\x99\x98\x89\x88\x99\x98\x89\x87o\xf6\xff\x98\x88o\xffx'\xf1\x81U891\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 U891\x00\x00\x00\x00\x00\x00SLX2G38NB3\xd1\xc3\xf8\xa8", b'\xf1\x87LDMVBN950669KF37\x97www\x96fffy\x99\xa7\x99\xa9\x99\xaa\x99g\x88\x96x\xb8\x8f\xf9\xffTD/\xff\xa7\xcb\xf1\x81U922\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 U922\x00\x00\x00\x00\x00\x00SLX4G38NB5\xb9\x94\xe8\x89', b'\xf1\x87LDLVAA4478824HH1\x87wwwvfvg\x89\x99\xa8\x99w\x88\x87x\x89\x99\xa8\x99\xa6o\xfa\xfffU/\xffu\x92\xf1\x81U903\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 U903\x00\x00\x00\x00\x00\x00TON4G38NB2[v\\\xb6', + b'\xf1\x87LDMVBN871852KF37\xb9\x99\x99\x99\xa8\x88\x88\x88y\x99\xa7\x99x\x99\xa7\x89\x88\x88\x98\x88\x89o\xf7\xff\xaa\x88o\xff\x0e\xed\xf1\x81U922\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 U922\x00\x00\x00\x00\x00\x00SLX4G38NB5\xb9\x94\xe8\x89', ], }, CAR.VELOSTER: { From 7679f4fa90d936850113cd345b23313bf25fde6e Mon Sep 17 00:00:00 2001 From: Robbe Derks Date: Wed, 17 Aug 2022 21:23:03 -0700 Subject: [PATCH 056/106] Panda fan controller (#25475) bump panda and add fan power to pandaState --- cereal | 2 +- panda | 2 +- selfdrive/boardd/boardd.cc | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cereal b/cereal index f60f0ef200afa9..ecff0a284a2aa9 160000 --- a/cereal +++ b/cereal @@ -1 +1 @@ -Subproject commit f60f0ef200afa9c7da932454b592ad5b0fb58493 +Subproject commit ecff0a284a2aa9879c4d04ea797356e4ef024dc4 diff --git a/panda b/panda index 199bc10db3a937..ba8772123f1312 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 199bc10db3a937fab0c50d9b708f6c76234f5c3a +Subproject commit ba8772123f13123c797234660c56adb70795cebb diff --git a/selfdrive/boardd/boardd.cc b/selfdrive/boardd/boardd.cc index 240935175bf4bd..afbc592b932237 100644 --- a/selfdrive/boardd/boardd.cc +++ b/selfdrive/boardd/boardd.cc @@ -372,6 +372,7 @@ std::optional send_panda_states(PubMaster *pm, const std::vector ps.setAlternativeExperience(health.alternative_experience_pkt); ps.setHarnessStatus(cereal::PandaState::HarnessStatus(health.car_harness_status_pkt)); ps.setInterruptLoad(health.interrupt_load); + ps.setFanPower(health.fan_power); // Convert faults bitset to capnp list std::bitset fault_bits(health.faults_pkt); From a21780dbeac42de6e4ab153ed29cd48b41d7f521 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 18 Aug 2022 09:02:33 -0700 Subject: [PATCH 057/106] Subaru: Legacy 2020-22 support (#25313) * Subaru: Legacy 2020 support * clean that up * force for now * update years * test route --- RELEASES.md | 1 + docs/CARS.md | 3 +- selfdrive/car/subaru/carstate.py | 6 ++-- selfdrive/car/subaru/interface.py | 2 +- selfdrive/car/subaru/values.py | 34 ++++++++++++++--------- selfdrive/car/tests/routes.py | 1 + selfdrive/car/torque_data/substitute.yaml | 2 ++ 7 files changed, 32 insertions(+), 17 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index 364d2a494b9141..ced165fb0d0200 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -6,6 +6,7 @@ Version 0.8.16 (2022-XX-XX) * Chevrolet Bolt EUV 2022-23 support thanks to JasonJShuler! * Hyundai Ioniq 5 2022 support thanks to sunnyhaibin! * Hyundai Kona Electric 2022 support thanks to sunnyhaibin! +* Subaru Legacy 2020-22 support thanks to martinl! * Subaru Outback 2020-22 support Version 0.8.15 (2022-07-20) diff --git a/docs/CARS.md b/docs/CARS.md index fd82a5aa842cc6..5757dd6d2613ee 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -19,7 +19,7 @@ A supported vehicle is one that just works when you install a comma device. Ever - [![star](assets/icon-star-empty.svg)](##) - Limited ability to make tighter turns. -# 201 Supported Cars +# 202 Supported Cars |Make|Model|Supported Package|openpilot ACC|Stop and Go|Steer to 0|Steering Torque| |---|---|---|:---:|:---:|:---:|:---:| @@ -143,6 +143,7 @@ A supported vehicle is one that just works when you install a comma device. Ever |Subaru|Forester 2019-21|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Subaru|Impreza 2017-19|EyeSight Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| |Subaru|Impreza 2020-22|EyeSight Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| +|Subaru|Legacy 2020-22|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Subaru|Outback 2020-22|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Subaru|XV 2018-19|EyeSight Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| |Subaru|XV 2020-21|EyeSight Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| diff --git a/selfdrive/car/subaru/carstate.py b/selfdrive/car/subaru/carstate.py index de5e62cb7e91ab..7fc5456d98f92f 100644 --- a/selfdrive/car/subaru/carstate.py +++ b/selfdrive/car/subaru/carstate.py @@ -4,7 +4,7 @@ from common.conversions import Conversions as CV from selfdrive.car.interfaces import CarStateBase from opendbc.can.parser import CANParser -from selfdrive.car.subaru.values import DBC, STEER_THRESHOLD, CAR, GLOBAL_GEN2, PREGLOBAL_CARS +from selfdrive.car.subaru.values import DBC, CAR, GLOBAL_GEN2, PREGLOBAL_CARS class CarState(CarStateBase): @@ -50,7 +50,9 @@ def update(self, cp, cp_cam, cp_body): ret.steeringAngleDeg = cp.vl["Steering_Torque"]["Steering_Angle"] ret.steeringTorque = cp.vl["Steering_Torque"]["Steer_Torque_Sensor"] ret.steeringTorqueEps = cp.vl["Steering_Torque"]["Steer_Torque_Output"] - ret.steeringPressed = abs(ret.steeringTorque) > STEER_THRESHOLD[self.car_fingerprint] + + steer_threshold = 75 if self.CP.carFingerprint in PREGLOBAL_CARS else 80 + ret.steeringPressed = abs(ret.steeringTorque) > steer_threshold cp_cruise = cp_body if self.car_fingerprint in GLOBAL_GEN2 else cp ret.cruiseState.enabled = cp_cruise.vl["CruiseControl"]["Cruise_Activated"] != 0 diff --git a/selfdrive/car/subaru/interface.py b/selfdrive/car/subaru/interface.py index 049da10a16b184..a464734a30b9bb 100644 --- a/selfdrive/car/subaru/interface.py +++ b/selfdrive/car/subaru/interface.py @@ -71,7 +71,7 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None, disa 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 == CAR.OUTBACK: + elif candidate in (CAR.OUTBACK, CAR.LEGACY): ret.mass = 1568. + STD_CARGO_KG ret.wheelbase = 2.67 ret.centerToFront = ret.wheelbase * 0.5 diff --git a/selfdrive/car/subaru/values.py b/selfdrive/car/subaru/values.py index 691a4c9158f3a8..7d8365a11f3435 100644 --- a/selfdrive/car/subaru/values.py +++ b/selfdrive/car/subaru/values.py @@ -35,6 +35,7 @@ class CAR: IMPREZA_2020 = "SUBARU IMPREZA SPORT 2020" FORESTER = "SUBARU FORESTER 2019" OUTBACK = "SUBARU OUTBACK 6TH GEN" + LEGACY = "SUBARU LEGACY 7TH GEN" # Pre-global FORESTER_PREGLOBAL = "SUBARU FORESTER 2017 - 2018" @@ -52,6 +53,7 @@ class SubaruCarInfo(CarInfo): CAR_INFO: Dict[str, Union[SubaruCarInfo, List[SubaruCarInfo]]] = { CAR.ASCENT: SubaruCarInfo("Subaru Ascent 2019-21", "All"), CAR.OUTBACK: SubaruCarInfo("Subaru Outback 2020-22", "All", harness=Harness.subaru_b), + CAR.LEGACY: SubaruCarInfo("Subaru Legacy 2020-22", "All", harness=Harness.subaru_b), CAR.IMPREZA: [ SubaruCarInfo("Subaru Impreza 2017-19"), SubaruCarInfo("Subaru Crosstrek 2018-19", video_link="https://youtu.be/Agww7oE1k-s?t=26"), @@ -101,6 +103,23 @@ class SubaruCarInfo(CarInfo): b'\x01\xfe\xf7\x00\x00', ], }, + CAR.LEGACY: { + (Ecu.esp, 0x7b0, None): [ + b'\xa1\\ x04\x01', + ], + (Ecu.eps, 0x746, None): [ + b'\x9b\xc0\x11\x00', + ], + (Ecu.fwdCamera, 0x787, None): [ + b'\x00\x00e\x80\x00\x1f@ \x19\x00', + ], + (Ecu.engine, 0x7e0, None): [ + b'\xde\"a0\x07', + ], + (Ecu.transmission, 0x7e1, None): [ + b'\xa5\xf6\x05@\x00', + ], + }, CAR.IMPREZA: { (Ecu.esp, 0x7b0, None): [ b'\x7a\x94\x3f\x90\x00', @@ -448,29 +467,18 @@ class SubaruCarInfo(CarInfo): }, } -STEER_THRESHOLD = { - CAR.ASCENT: 80, - CAR.IMPREZA: 80, - CAR.IMPREZA_2020: 80, - CAR.FORESTER: 80, - CAR.OUTBACK: 80, - CAR.FORESTER_PREGLOBAL: 75, - CAR.LEGACY_PREGLOBAL: 75, - CAR.OUTBACK_PREGLOBAL: 75, - CAR.OUTBACK_PREGLOBAL_2018: 75, -} - DBC = { CAR.ASCENT: 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.OUTBACK: 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), } -GLOBAL_GEN2 = (CAR.OUTBACK, ) +GLOBAL_GEN2 = (CAR.OUTBACK, CAR.LEGACY) PREGLOBAL_CARS = (CAR.FORESTER_PREGLOBAL, CAR.LEGACY_PREGLOBAL, CAR.OUTBACK_PREGLOBAL, CAR.OUTBACK_PREGLOBAL_2018) diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py index 44672bf9dd24c8..5c767ae1a85228 100644 --- a/selfdrive/car/tests/routes.py +++ b/selfdrive/car/tests/routes.py @@ -193,6 +193,7 @@ TestRoute("791340bc01ed993d|2019-03-10--16-28-08", SUBARU.IMPREZA), TestRoute("8bf7e79a3ce64055|2021-05-24--09-36-27", SUBARU.IMPREZA_2020), TestRoute("1bbe6bf2d62f58a8|2022-07-14--17-11-43", SUBARU.OUTBACK, segment=3), + TestRoute("c56e69bbc74b8fad|2022-08-18--09-43-51", SUBARU.LEGACY, segment=3), # Pre-global, dashcam TestRoute("95441c38ae8c130e|2020-06-08--12-10-17", SUBARU.FORESTER_PREGLOBAL), TestRoute("df5ca7660000fba8|2020-06-16--17-37-19", SUBARU.LEGACY_PREGLOBAL), diff --git a/selfdrive/car/torque_data/substitute.yaml b/selfdrive/car/torque_data/substitute.yaml index 279e28ff5d4d92..de64a5544c111f 100644 --- a/selfdrive/car/torque_data/substitute.yaml +++ b/selfdrive/car/torque_data/substitute.yaml @@ -69,6 +69,8 @@ VOLKSWAGEN POLO 6TH GEN: VOLKSWAGEN GOLF 7TH GEN SEAT LEON 3RD GEN: VOLKSWAGEN GOLF 7TH GEN SEAT ATECA 1ST GEN: VOLKSWAGEN GOLF 7TH GEN +SUBARU LEGACY 7TH GEN: SUBARU OUTBACK 6TH GEN + # Old subarus don't have much data guessing it's like low torque impreza SUBARU OUTBACK 2018 - 2019: SUBARU IMPREZA LIMITED 2019 SUBARU OUTBACK 2015 - 2017: SUBARU IMPREZA LIMITED 2019 From 5f8858266c4127ddd2df851c66678982667fc06b Mon Sep 17 00:00:00 2001 From: Alex Vazquez Date: Thu, 18 Aug 2022 14:35:07 -0400 Subject: [PATCH 058/106] Hyundai: add missing Santa Fe 2022 FW (#25479) * Update values.py Adding 2022 Santa Fe Limited drive train and sensors - 2.5T with Dual Clutch Transmission which is different than the SE/VRT/SEL models. * Update selfdrive/car/hyundai/values.py * Add back other FW Co-authored-by: Shane Smiskol --- selfdrive/car/hyundai/values.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index a27c6f68554086..17745a4d75a1c6 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -613,6 +613,7 @@ class Buttons: b'\xf1\x00TM__ SCC F-CUP 1.00 1.00 99110-S1500 ', b'\xf1\x8799110S1500\xf1\x00TM__ SCC F-CUP 1.00 1.00 99110-S1500 ', b'\xf1\x8799110S1500\xf1\x00TM__ SCC FHCUP 1.00 1.00 99110-S1500 ', + b'\xf1\x00TM__ SCC FHCUP 1.00 1.00 99110-S1500 ', ], (Ecu.esp, 0x7d1, None): [ b'\xf1\x00TM ESC \x02 101 \x08\x04 58910-S2GA0', @@ -621,6 +622,7 @@ class Buttons: b'\xf1\x8758910-S2GA0\xf1\x00TM ESC \x02 101 \x08\x04 58910-S2GA0', b'\xf1\x8758910-S1DA0\xf1\x00TM ESC \x1e 102 \x08\x08 58910-S1DA0', b'\xf1\x8758910-S2GA0\xf1\x00TM ESC \x04 102!\x04\x05 58910-S2GA0', + b'\xf1\x00TM ESC \x04 102!\x04\x05 58910-S2GA0', ], (Ecu.engine, 0x7e0, None): [ b'\xf1\x82TACVN5GMI3XXXH0A', @@ -629,6 +631,7 @@ class Buttons: b'\xf1\x82TMCFD5MMCXXXXG0A', b'\xf1\x870\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x82TMDWN5TMD3TXXJ1A', b'\xf1\x81HM6M2_0a0_G00', + b'\xf1\x870\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x81HM6M1_0a0_J10', ], (Ecu.eps, 0x7d4, None): [ b'\xf1\x00TM MDPS C 1.00 1.02 56370-S2AA0 0B19', @@ -648,6 +651,8 @@ class Buttons: b'\xf1\x87KMMYBU034207SB72x\x89\x88\x98h\x88\x98\x89\x87fhvvfWf33_\xff\x87\xff\x8f\xfa\x81\xe5\xf1\x89HT6TAF00A1\xf1\x82STM0M25GS1\x00\x00\x00\x00\x00\x00', b'\xf1\x87954A02N250\x00\x00\x00\x00\x00\xf1\x81T02730A1 \xf1\x00T02601BL T02730A1 VTMPT25XXX730NS2\xa6', b'\xf1\x00HT6TA290BLHT6TAF00A1STM0M25GS1\x00\x00\x00\x00\x00\x006\xd8\x97\x15', + b'\xf1\x00T02601BL T02900A1 VTMPT25XXX900NS8\xb7\xaa\xfe\xfc', + b'\xf1\x87954A02N250\x00\x00\x00\x00\x00\xf1\x81T02900A1 \xf1\x00T02601BL T02900A1 VTMPT25XXX900NS8\xb7\xaa\xfe\xfc', ], }, CAR.SANTA_FE_HEV_2022: { From 747bcb013dabdb1f220dc97a37270b42cb4eae03 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Thu, 18 Aug 2022 15:12:18 -0700 Subject: [PATCH 059/106] Car docs: show more information about cars (#25415) * back to actual information * remove some star code * round speeds * Try out showing lateral acceleration * remove that * Fix speed units * Add harness and try rounding to nearest half before scapping it fix ^2 ^2 * Add back steering torque star * Fix static analysis * auto-generate header * fix static analysis. set to Harness.none by default * rm --- docs/CARS.md | 423 ++++++++++++++---------------- selfdrive/car/CARS_template.md | 14 +- selfdrive/car/body/values.py | 4 +- selfdrive/car/docs.py | 28 +- selfdrive/car/docs_definitions.py | 148 ++++------- selfdrive/car/tests/test_docs.py | 2 +- selfdrive/car/toyota/values.py | 4 +- 7 files changed, 270 insertions(+), 353 deletions(-) diff --git a/docs/CARS.md b/docs/CARS.md index 5757dd6d2613ee..efd9b3c5201129 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -4,227 +4,212 @@ A supported vehicle is one that just works when you install a comma device. Every car performs differently with openpilot, but all supported cars should provide a better experience than any stock system. -## How We Rate The Cars - -### Stop and Go -- [![star](assets/icon-star-full.svg)](##) - openpilot operates down to 0 mph. -- [![star](assets/icon-star-empty.svg)](##) - openpilot operates only above a minimum speed. See your car's manual for the minimum speed. - -### Steer to 0 -- [![star](assets/icon-star-full.svg)](##) - openpilot can control the steering wheel down to 0 mph. -- [![star](assets/icon-star-empty.svg)](##) - No steering control below certain speeds. See your car's manual for the minimum speed. - -### Steering Torque -- [![star](assets/icon-star-full.svg)](##) - Car has enough steering torque to comfortably take most highway turns. -- [![star](assets/icon-star-empty.svg)](##) - Limited ability to make tighter turns. - - # 202 Supported Cars -|Make|Model|Supported Package|openpilot ACC|Stop and Go|Steer to 0|Steering Torque| -|---|---|---|:---:|:---:|:---:|:---:| -|Acura|ILX 2016-19|AcuraWatch Plus|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| -|Acura|RDX 2016-18|AcuraWatch Plus|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| -|Acura|RDX 2019-22|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| -|Audi|A3 2014-19|ACC + Lane Assist|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Audi|A3 Sportback e-tron 2017-18|ACC + Lane Assist|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Audi|Q2 2018|ACC + Lane Assist|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Audi|Q3 2020-21|ACC + Lane Assist|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Audi|RS3 2018|ACC + Lane Assist|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Audi|S3 2015-17|ACC + Lane Assist|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Cadillac|Escalade ESV 2016[1](#footnotes)|Adaptive Cruise Control (ACC) & LKAS|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Chevrolet|Bolt EUV 2022-23|Premier/Premier Redline Trim|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Chevrolet|Volt 2017-18[1](#footnotes)|Adaptive Cruise Control|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Chrysler|Pacifica 2017-18|Adaptive Cruise Control|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Chrysler|Pacifica 2019-20|Adaptive Cruise Control|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Chrysler|Pacifica 2021|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Chrysler|Pacifica Hybrid 2017-18|Adaptive Cruise Control|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Chrysler|Pacifica Hybrid 2019-22|Adaptive Cruise Control|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|comma|body|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Genesis|G70 2018-19|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Genesis|G70 2020|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Genesis|G80 2017-19|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Genesis|G90 2017-18|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|GMC|Acadia 2018[1](#footnotes)|Adaptive Cruise Control|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Honda|Accord 2018-22|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| -|Honda|Accord Hybrid 2018-22|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| -|Honda|Civic 2016-18|Honda Sensing|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| -|Honda|Civic 2019-21|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)[2](#footnotes)|[![star](assets/icon-star-empty.svg)](##)| -|Honda|Civic 2022|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Honda|Civic Hatchback 2017-21|Honda Sensing|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| -|Honda|Civic Hatchback 2022|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Honda|CR-V 2015-16|Touring Trim|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| -|Honda|CR-V 2017-22|Honda Sensing|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| -|Honda|CR-V Hybrid 2017-19|Honda Sensing|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| -|Honda|e 2020|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| -|Honda|Fit 2018-20|Honda Sensing|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| -|Honda|Freed 2020|Honda Sensing|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| -|Honda|HR-V 2019-22|Honda Sensing|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| -|Honda|Insight 2019-22|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| -|Honda|Inspire 2018|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| -|Honda|Odyssey 2018-20|Honda Sensing|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| -|Honda|Passport 2019-21|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| -|Honda|Pilot 2016-22|Honda Sensing|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| -|Honda|Ridgeline 2017-22|Honda Sensing|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| -|Hyundai|Elantra 2017-19|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Hyundai|Elantra 2021-22|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Hyundai|Elantra Hybrid 2021-22|Smart Cruise Control (SCC)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Hyundai|Genesis 2015-16|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Hyundai|Ioniq 5 2022|Highway Driving Assist II|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Hyundai|Ioniq Electric 2019|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Hyundai|Ioniq Electric 2020|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Hyundai|Ioniq Hybrid 2017-19|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Hyundai|Ioniq Hybrid 2020-22|Smart Cruise Control (SCC) & LFA|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Hyundai|Ioniq Plug-in Hybrid 2019|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Hyundai|Ioniq Plug-in Hybrid 2020-21|Smart Cruise Control (SCC)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Hyundai|Kona 2020|Smart Cruise Control (SCC)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Hyundai|Kona Electric 2018-21|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Hyundai|Kona Electric 2022|Smart Cruise Control (SCC)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Hyundai|Kona Hybrid 2020|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Hyundai|Palisade 2020-22|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Hyundai|Santa Fe 2019-20|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Hyundai|Santa Fe 2021-22|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Hyundai|Santa Fe Hybrid 2022|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Hyundai|Santa Fe Plug-in Hybrid 2022|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Hyundai|Sonata 2018-19|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Hyundai|Sonata 2020-22|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Hyundai|Sonata Hybrid 2020-22|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Hyundai|Tucson 2021|Smart Cruise Control (SCC)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Hyundai|Tucson Diesel 2019|Smart Cruise Control (SCC)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Hyundai|Veloster 2019-20|Smart Cruise Control (SCC)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Jeep|Grand Cherokee 2016-18|Adaptive Cruise Control|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Jeep|Grand Cherokee 2019-21|Adaptive Cruise Control|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Kia|Ceed 2019|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Kia|EV6 2022|Highway Driving Assist II|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Kia|Forte 2018|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Kia|Forte 2019-21|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Kia|K5 2021-22|Smart Cruise Control (SCC)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Kia|Niro Electric 2019|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Kia|Niro Electric 2020|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Kia|Niro Electric 2021|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Kia|Niro Electric 2022|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Kia|Niro Hybrid 2021|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Kia|Niro Hybrid 2022|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Kia|Niro Plug-in Hybrid 2018-19|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Kia|Optima 2017|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Kia|Optima 2019|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Kia|Seltos 2021|Smart Cruise Control (SCC)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Kia|Sorento 2018|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Kia|Sorento 2019|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Kia|Stinger 2018-20|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Kia|Telluride 2020|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Lexus|CT Hybrid 2017-18|Lexus Safety System+|[![star](assets/icon-star-half.svg)](##)[3](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Lexus|ES 2019-22|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Lexus|ES Hybrid 2017-18|Lexus Safety System+|[![star](assets/icon-star-half.svg)](##)[3](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Lexus|ES Hybrid 2019-22|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Lexus|IS 2017-19|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Lexus|NX 2018-19|All|[![star](assets/icon-star-half.svg)](##)[3](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Lexus|NX 2020-21|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Lexus|NX Hybrid 2018-19|All|[![star](assets/icon-star-half.svg)](##)[3](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Lexus|NX Hybrid 2020-21|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Lexus|RC 2017-20|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Lexus|RX 2016-19|All|[![star](assets/icon-star-half.svg)](##)[3](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Lexus|RX 2020-22|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Lexus|RX Hybrid 2016-19|All|[![star](assets/icon-star-half.svg)](##)[3](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Lexus|RX Hybrid 2020-21|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Lexus|UX Hybrid 2019-22|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Mazda|CX-5 2022|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Mazda|CX-9 2021-22|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Nissan|Altima 2019-20|ProPILOT Assist|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Nissan|Leaf 2018-22|ProPILOT Assist|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Nissan|Rogue 2018-20|ProPILOT Assist|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Nissan|X-Trail 2017|ProPILOT Assist|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Ram|1500 2019-22|Adaptive Cruise Control|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|SEAT|Ateca 2018|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|SEAT|Leon 2014-20|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Subaru|Ascent 2019-21|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Subaru|Crosstrek 2018-19|EyeSight Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| -|Subaru|Crosstrek 2020-21|EyeSight Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Subaru|Forester 2019-21|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Subaru|Impreza 2017-19|EyeSight Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| -|Subaru|Impreza 2020-22|EyeSight Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Subaru|Legacy 2020-22|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Subaru|Outback 2020-22|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Subaru|XV 2018-19|EyeSight Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| -|Subaru|XV 2020-21|EyeSight Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Škoda|Kamiq 2021[5](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Škoda|Karoq 2019-21[7](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Škoda|Kodiaq 2018-19|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Škoda|Octavia 2015, 2018-19|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Škoda|Octavia RS 2016|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Škoda|Scala 2020|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Škoda|Superb 2015-18|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Alphard 2019-20|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Alphard Hybrid 2021|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Avalon 2016|Toyota Safety Sense P|[![star](assets/icon-star-half.svg)](##)[3](#footnotes)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Avalon 2017-18|All|[![star](assets/icon-star-half.svg)](##)[3](#footnotes)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Avalon 2019-21|All|[![star](assets/icon-star-half.svg)](##)[3](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Avalon 2022|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Avalon Hybrid 2019-21|All|[![star](assets/icon-star-half.svg)](##)[3](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Avalon Hybrid 2022|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|C-HR 2017-21|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|C-HR Hybrid 2017-19|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Camry 2018-20|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)[4](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Camry 2021-22|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)[4](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Camry Hybrid 2018-20|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Camry Hybrid 2021-22|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Corolla 2017-19|All|[![star](assets/icon-star-half.svg)](##)[3](#footnotes)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Corolla 2020-22|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Corolla Cross (Non-US only) 2020-21|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Corolla Cross Hybrid (Non-US only) 2020-22|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Corolla Hatchback 2019-22|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Corolla Hybrid 2020-22|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Highlander 2017-19|All|[![star](assets/icon-star-half.svg)](##)[3](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Highlander 2020-22|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Highlander Hybrid 2017-19|All|[![star](assets/icon-star-half.svg)](##)[3](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Highlander Hybrid 2020-22|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Mirai 2021|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Prius 2016|Toyota Safety Sense P|[![star](assets/icon-star-half.svg)](##)[3](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Prius 2017-20|All|[![star](assets/icon-star-half.svg)](##)[3](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Prius 2021-22|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Prius Prime 2017-20|All|[![star](assets/icon-star-half.svg)](##)[3](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Prius Prime 2021-22|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Prius v 2017|Toyota Safety Sense P|[![star](assets/icon-star-half.svg)](##)[3](#footnotes)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|RAV4 2016|Toyota Safety Sense P|[![star](assets/icon-star-half.svg)](##)[3](#footnotes)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|RAV4 2017-18|All|[![star](assets/icon-star-half.svg)](##)[3](#footnotes)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|RAV4 2019-21|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|RAV4 2022|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|RAV4 Hybrid 2016|Toyota Safety Sense P|[![star](assets/icon-star-half.svg)](##)[3](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|RAV4 Hybrid 2017-18|All|[![star](assets/icon-star-half.svg)](##)[3](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|RAV4 Hybrid 2019-21|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|RAV4 Hybrid 2022|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Toyota|Sienna 2018-20|All|[![star](assets/icon-star-half.svg)](##)[3](#footnotes)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|Arteon 2018-22[7,8](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|Arteon eHybrid 2020-22[7,8](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|Arteon R 2020-22[7,8](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|Atlas 2018-22[7](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|Atlas Cross Sport 2021-22[7](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|California 2021[7](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|Caravelle 2020[7](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|CC 2018-22[7,8](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|e-Golf 2014-20|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|Golf 2015-20[8](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|Golf Alltrack 2015-19|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|Golf GTD 2015-20|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|Golf GTE 2015-20|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|Golf GTI 2015-21|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|Golf R 2015-19[8](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|Golf SportsVan 2015-20|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|Jetta 2018-22[7](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|Jetta GLI 2021-22[7](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|Passat 2015-22[6,7,8](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|Passat Alltrack 2015-22[7](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|Passat GTE 2015-22[7,8](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|Polo 2020-22[7](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|Polo GTI 2020-22[7](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|T-Cross 2021[7](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|T-Roc 2021[7](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|Taos 2022[7](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|Teramont 2018-22[7](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|Teramont Cross Sport 2021-22[7](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|Teramont X 2021-22[7](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|Tiguan 2019-22[7](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| -|Volkswagen|Touran 2017|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| +|Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Harness| +|---|---|---|:---:|:---:|:---:|:---:|:---:| +|Acura|ILX 2016-19|AcuraWatch Plus|openpilot|25 mph|25 mph|[![star](assets/icon-star-empty.svg)](##)|Honda Nidec| +|Acura|RDX 2016-18|AcuraWatch Plus|openpilot|25 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|Honda Nidec| +|Acura|RDX 2019-22|All|Stock|0 mph|3 mph|[![star](assets/icon-star-empty.svg)](##)|Honda Bosch A| +|Audi|A3 2014-19|ACC + Lane Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|VW| +|Audi|A3 Sportback e-tron 2017-18|ACC + Lane Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|VW| +|Audi|Q2 2018|ACC + Lane Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|VW| +|Audi|Q3 2020-21|ACC + Lane Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|VW| +|Audi|RS3 2018|ACC + Lane Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|VW| +|Audi|S3 2015-17|ACC + Lane Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|VW| +|Cadillac|Escalade ESV 2016[1](#footnotes)|Adaptive Cruise Control (ACC) & LKAS|openpilot|0 mph|7 mph|[![star](assets/icon-star-full.svg)](##)|OBD-II| +|Chevrolet|Bolt EUV 2022-23|Premier/Premier Redline Trim|Stock|0 mph|7 mph|[![star](assets/icon-star-full.svg)](##)|GM| +|Chevrolet|Volt 2017-18[1](#footnotes)|Adaptive Cruise Control|openpilot|0 mph|7 mph|[![star](assets/icon-star-full.svg)](##)|OBD-II| +|Chrysler|Pacifica 2017-18|Adaptive Cruise Control|Stock|0 mph|9 mph|[![star](assets/icon-star-full.svg)](##)|FCA| +|Chrysler|Pacifica 2019-20|Adaptive Cruise Control|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|FCA| +|Chrysler|Pacifica 2021|All|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|FCA| +|Chrysler|Pacifica Hybrid 2017-18|Adaptive Cruise Control|Stock|0 mph|9 mph|[![star](assets/icon-star-full.svg)](##)|FCA| +|Chrysler|Pacifica Hybrid 2019-22|Adaptive Cruise Control|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|FCA| +|comma|body|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|None| +|Genesis|G70 2018-19|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai F| +|Genesis|G70 2020|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai F| +|Genesis|G80 2017-19|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai H| +|Genesis|G90 2017-18|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai C| +|GMC|Acadia 2018[1](#footnotes)|Adaptive Cruise Control|openpilot|0 mph|7 mph|[![star](assets/icon-star-full.svg)](##)|OBD-II| +|Honda|Accord 2018-22|All|Stock|0 mph|3 mph|[![star](assets/icon-star-empty.svg)](##)|Honda Bosch A| +|Honda|Accord Hybrid 2018-22|All|Stock|0 mph|3 mph|[![star](assets/icon-star-empty.svg)](##)|Honda Bosch A| +|Honda|Civic 2016-18|Honda Sensing|openpilot|0 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|Honda Nidec| +|Honda|Civic 2019-21|All|Stock|0 mph|2 mph[2](#footnotes)|[![star](assets/icon-star-empty.svg)](##)|Honda Bosch A| +|Honda|Civic 2022|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Honda Bosch B| +|Honda|Civic Hatchback 2017-21|Honda Sensing|Stock|0 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|Honda Bosch A| +|Honda|Civic Hatchback 2022|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Honda Bosch B| +|Honda|CR-V 2015-16|Touring Trim|openpilot|25 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|Honda Nidec| +|Honda|CR-V 2017-22|Honda Sensing|Stock|0 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|Honda Bosch A| +|Honda|CR-V Hybrid 2017-19|Honda Sensing|Stock|0 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|Honda Bosch A| +|Honda|e 2020|All|Stock|0 mph|3 mph|[![star](assets/icon-star-empty.svg)](##)|Honda Bosch A| +|Honda|Fit 2018-20|Honda Sensing|openpilot|25 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|Honda Nidec| +|Honda|Freed 2020|Honda Sensing|openpilot|25 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|Honda Nidec| +|Honda|HR-V 2019-22|Honda Sensing|openpilot|25 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|Honda Nidec| +|Honda|Insight 2019-22|All|Stock|0 mph|3 mph|[![star](assets/icon-star-empty.svg)](##)|Honda Bosch A| +|Honda|Inspire 2018|All|Stock|0 mph|3 mph|[![star](assets/icon-star-empty.svg)](##)|Honda Bosch A| +|Honda|Odyssey 2018-20|Honda Sensing|openpilot|25 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|Honda Nidec| +|Honda|Passport 2019-21|All|openpilot|25 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|Honda Nidec| +|Honda|Pilot 2016-22|Honda Sensing|openpilot|25 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|Honda Nidec| +|Honda|Ridgeline 2017-22|Honda Sensing|openpilot|25 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|Honda Nidec| +|Hyundai|Elantra 2017-19|Smart Cruise Control (SCC) & LKAS|Stock|19 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai B| +|Hyundai|Elantra 2021-22|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai K| +|Hyundai|Elantra Hybrid 2021-22|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai K| +|Hyundai|Genesis 2015-16|Smart Cruise Control (SCC) & LKAS|Stock|19 mph|37 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai J| +|Hyundai|Ioniq 5 2022|Highway Driving Assist II|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai Q| +|Hyundai|Ioniq Electric 2019|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai C| +|Hyundai|Ioniq Electric 2020|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai H| +|Hyundai|Ioniq Hybrid 2017-19|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai C| +|Hyundai|Ioniq Hybrid 2020-22|Smart Cruise Control (SCC) & LFA|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai H| +|Hyundai|Ioniq Plug-in Hybrid 2019|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai C| +|Hyundai|Ioniq Plug-in Hybrid 2020-21|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai H| +|Hyundai|Kona 2020|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai B| +|Hyundai|Kona Electric 2018-21|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai G| +|Hyundai|Kona Electric 2022|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai O| +|Hyundai|Kona Hybrid 2020|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai I| +|Hyundai|Palisade 2020-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai H| +|Hyundai|Santa Fe 2019-20|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai D| +|Hyundai|Santa Fe 2021-22|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai L| +|Hyundai|Santa Fe Hybrid 2022|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai L| +|Hyundai|Santa Fe Plug-in Hybrid 2022|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai L| +|Hyundai|Sonata 2018-19|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai E| +|Hyundai|Sonata 2020-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai A| +|Hyundai|Sonata Hybrid 2020-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai A| +|Hyundai|Tucson 2021|Smart Cruise Control (SCC)|Stock|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai L| +|Hyundai|Tucson Diesel 2019|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai L| +|Hyundai|Veloster 2019-20|Smart Cruise Control (SCC)|Stock|5 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai E| +|Jeep|Grand Cherokee 2016-18|Adaptive Cruise Control|Stock|0 mph|9 mph|[![star](assets/icon-star-full.svg)](##)|FCA| +|Jeep|Grand Cherokee 2019-21|Adaptive Cruise Control|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|FCA| +|Kia|Ceed 2019|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai E| +|Kia|EV6 2022|Highway Driving Assist II|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai P| +|Kia|Forte 2018|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai B| +|Kia|Forte 2019-21|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai G| +|Kia|K5 2021-22|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai A| +|Kia|Niro Electric 2019|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai H| +|Kia|Niro Electric 2020|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai F| +|Kia|Niro Electric 2021|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai C| +|Kia|Niro Electric 2022|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai H| +|Kia|Niro Hybrid 2021|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai F| +|Kia|Niro Hybrid 2022|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai H| +|Kia|Niro Plug-in Hybrid 2018-19|Smart Cruise Control (SCC) & LKAS|openpilot|10 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai C| +|Kia|Optima 2017|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai B| +|Kia|Optima 2019|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai G| +|Kia|Seltos 2021|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai A| +|Kia|Sorento 2018|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai C| +|Kia|Sorento 2019|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai E| +|Kia|Stinger 2018-20|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai C| +|Kia|Telluride 2020|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai H| +|Lexus|CT Hybrid 2017-18|Lexus Safety System+|Stock[3](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Lexus|ES 2019-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Lexus|ES Hybrid 2017-18|Lexus Safety System+|Stock[3](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Lexus|ES Hybrid 2019-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Lexus|IS 2017-19|All|Stock|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Lexus|NX 2018-19|All|Stock[3](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Lexus|NX 2020-21|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Lexus|NX Hybrid 2018-19|All|Stock[3](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Lexus|NX Hybrid 2020-21|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Lexus|RC 2017-20|All|Stock|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Lexus|RX 2016-19|All|Stock[3](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Lexus|RX 2020-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Lexus|RX Hybrid 2016-19|All|Stock[3](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Lexus|RX Hybrid 2020-21|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Lexus|UX Hybrid 2019-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Mazda|CX-5 2022|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Mazda| +|Mazda|CX-9 2021-22|All|Stock|0 mph|28 mph|[![star](assets/icon-star-full.svg)](##)|Mazda| +|Nissan|Altima 2019-20|ProPILOT Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Nissan B| +|Nissan|Leaf 2018-22|ProPILOT Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Nissan A| +|Nissan|Rogue 2018-20|ProPILOT Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Nissan A| +|Nissan|X-Trail 2017|ProPILOT Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Nissan A| +|Ram|1500 2019-22|Adaptive Cruise Control|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|Ram| +|SEAT|Ateca 2018|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|VW| +|SEAT|Leon 2014-20|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|VW| +|Subaru|Ascent 2019-21|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Subaru A| +|Subaru|Crosstrek 2018-19|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|Subaru A| +|Subaru|Crosstrek 2020-21|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Subaru A| +|Subaru|Forester 2019-21|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Subaru A| +|Subaru|Impreza 2017-19|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|Subaru A| +|Subaru|Impreza 2020-22|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Subaru A| +|Subaru|Legacy 2020-22|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Subaru B| +|Subaru|Outback 2020-22|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Subaru B| +|Subaru|XV 2018-19|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|Subaru A| +|Subaru|XV 2020-21|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Subaru A| +|Škoda|Kamiq 2021[5](#footnotes)|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|VW| +|Škoda|Karoq 2019-21[7](#footnotes)|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|VW| +|Škoda|Kodiaq 2018-19|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|VW| +|Škoda|Octavia 2015, 2018-19|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|VW| +|Škoda|Octavia RS 2016|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|VW| +|Škoda|Scala 2020|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|VW| +|Škoda|Superb 2015-18|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|VW| +|Toyota|Alphard 2019-20|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Alphard Hybrid 2021|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Avalon 2016|Toyota Safety Sense P|Stock[3](#footnotes)|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Avalon 2017-18|All|Stock[3](#footnotes)|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Avalon 2019-21|All|Stock[3](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Avalon 2022|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Avalon Hybrid 2019-21|All|Stock[3](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Avalon Hybrid 2022|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|C-HR 2017-21|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|C-HR Hybrid 2017-19|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Camry 2018-20|All|Stock|0 mph[4](#footnotes)|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Camry 2021-22|All|openpilot|0 mph[4](#footnotes)|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Camry Hybrid 2018-20|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Camry Hybrid 2021-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Corolla 2017-19|All|Stock[3](#footnotes)|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Corolla 2020-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Corolla Cross (Non-US only) 2020-21|All|openpilot|17 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Corolla Cross Hybrid (Non-US only) 2020-22|All|openpilot|17 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Corolla Hatchback 2019-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Corolla Hybrid 2020-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Highlander 2017-19|All|Stock[3](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Highlander 2020-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Highlander Hybrid 2017-19|All|Stock[3](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Highlander Hybrid 2020-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Mirai 2021|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Prius 2016|Toyota Safety Sense P|Stock[3](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Prius 2017-20|All|Stock[3](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Prius 2021-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Prius Prime 2017-20|All|Stock[3](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Prius Prime 2021-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Prius v 2017|Toyota Safety Sense P|Stock[3](#footnotes)|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|RAV4 2016|Toyota Safety Sense P|Stock[3](#footnotes)|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|RAV4 2017-18|All|Stock[3](#footnotes)|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|RAV4 2019-21|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|RAV4 2022|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|RAV4 Hybrid 2016|Toyota Safety Sense P|Stock[3](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|RAV4 Hybrid 2017-18|All|Stock[3](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|RAV4 Hybrid 2019-21|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|RAV4 Hybrid 2022|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Toyota|Sienna 2018-20|All|Stock[3](#footnotes)|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Toyota| +|Volkswagen|Arteon 2018-22[7,8](#footnotes)|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Arteon eHybrid 2020-22[7,8](#footnotes)|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Arteon R 2020-22[7,8](#footnotes)|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Atlas 2018-22[7](#footnotes)|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Atlas Cross Sport 2021-22[7](#footnotes)|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|California 2021[7](#footnotes)|Driver Assistance|Stock|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Caravelle 2020[7](#footnotes)|Driver Assistance|Stock|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|CC 2018-22[7,8](#footnotes)|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|e-Golf 2014-20|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|VW| +|Volkswagen|Golf 2015-20[8](#footnotes)|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|VW| +|Volkswagen|Golf Alltrack 2015-19|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|VW| +|Volkswagen|Golf GTD 2015-20|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|VW| +|Volkswagen|Golf GTE 2015-20|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|VW| +|Volkswagen|Golf GTI 2015-21|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|VW| +|Volkswagen|Golf R 2015-19[8](#footnotes)|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|VW| +|Volkswagen|Golf SportsVan 2015-20|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|VW| +|Volkswagen|Jetta 2018-22[7](#footnotes)|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Jetta GLI 2021-22[7](#footnotes)|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Passat 2015-22[6,7,8](#footnotes)|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Passat Alltrack 2015-22[7](#footnotes)|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Passat GTE 2015-22[7,8](#footnotes)|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Polo 2020-22[7](#footnotes)|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Polo GTI 2020-22[7](#footnotes)|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|T-Cross 2021[7](#footnotes)|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|T-Roc 2021[7](#footnotes)|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Taos 2022[7](#footnotes)|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Teramont 2018-22[7](#footnotes)|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Teramont Cross Sport 2021-22[7](#footnotes)|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Teramont X 2021-22[7](#footnotes)|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Tiguan 2019-22[7](#footnotes)|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Touran 2017|Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|VW| 1Requires a community built ASCM harness. NOTE: disconnecting the ASCM disables Automatic Emergency Braking (AEB).
diff --git a/selfdrive/car/CARS_template.md b/selfdrive/car/CARS_template.md index e448c19d353f81..d306ca5d92bfe8 100644 --- a/selfdrive/car/CARS_template.md +++ b/selfdrive/car/CARS_template.md @@ -7,22 +7,10 @@ A supported vehicle is one that just works when you install a comma device. Every car performs differently with openpilot, but all supported cars should provide a better experience than any stock system. -## How We Rate The Cars - -{% for star_row in STAR_DESCRIPTIONS.values() %} -{% for name, stars in star_row.items() %} -### {{name}} -{% for star, description in stars %} -- {{star_icon.format(star)}} - {{description}} -{% endfor %} - -{% endfor %} -{% endfor %} - # {{all_car_info | length}} Supported Cars |{{Column | map(attribute='value') | join('|')}}| -|---|---|---|:---:|:---:|:---:|:---:| +|---|---|---|{% for _ in range((Column | length) - 3) %}{{':---:|'}}{% endfor +%} {% for car_info in all_car_info %} |{% for column in Column %}{{car_info.get_column(column, star_icon, footnote_tag)}}|{% endfor %} diff --git a/selfdrive/car/body/values.py b/selfdrive/car/body/values.py index 0caf93b619952a..61b72d5ade21b6 100644 --- a/selfdrive/car/body/values.py +++ b/selfdrive/car/body/values.py @@ -2,7 +2,7 @@ from cereal import car from selfdrive.car import dbc_dict -from selfdrive.car.docs_definitions import CarInfo, Harness +from selfdrive.car.docs_definitions import CarInfo Ecu = car.CarParams.Ecu SPEED_FROM_RPM = 0.008587 @@ -18,7 +18,7 @@ class CAR: BODY = "COMMA BODY" CAR_INFO: Dict[str, CarInfo] = { - CAR.BODY: CarInfo("comma body", package="All", harness=Harness.none), + CAR.BODY: CarInfo("comma body", package="All"), } FW_VERSIONS = { diff --git a/selfdrive/car/docs.py b/selfdrive/car/docs.py index 5793596a437009..795668381c3be6 100755 --- a/selfdrive/car/docs.py +++ b/selfdrive/car/docs.py @@ -8,16 +8,15 @@ from typing import Dict, List from common.basedir import BASEDIR -from selfdrive.car.docs_definitions import STAR_DESCRIPTIONS, StarColumns, TierColumns, CarInfo, Column, Star +from selfdrive.car.docs_definitions import CarInfo, Column from selfdrive.car.car_helpers import interfaces, get_interface_attr from selfdrive.car.hyundai.radar_interface import RADAR_START_ADDR as HKG_RADAR_START_ADDR -def get_all_footnotes(only_tier_cols: bool = False) -> Dict[Enum, int]: +def get_all_footnotes() -> Dict[Enum, int]: all_footnotes = [] - hide_cols = set(StarColumns) - set(TierColumns) if only_tier_cols else [] for footnotes in get_interface_attr("Footnote", ignore_none=True).values(): - all_footnotes.extend([fn for fn in footnotes if fn.value.column not in hide_cols]) + all_footnotes.extend(footnotes) return {fn: idx + 1 for idx, fn in enumerate(all_footnotes)} @@ -25,9 +24,9 @@ def get_all_footnotes(only_tier_cols: bool = False) -> Dict[Enum, int]: CARS_MD_TEMPLATE = os.path.join(BASEDIR, "selfdrive", "car", "CARS_template.md") -def get_all_car_info(only_tier_cols: bool = False) -> List[CarInfo]: +def get_all_car_info() -> List[CarInfo]: all_car_info: List[CarInfo] = [] - footnotes = get_all_footnotes(only_tier_cols) + footnotes = get_all_footnotes() for model, car_info in get_interface_attr("CAR_INFO", combine_brands=True).items(): # Hyundai exception: those with radar have openpilot longitudinal fingerprint = {0: {}, 1: {HKG_RADAR_START_ADDR: 8}, 2: {}, 3: {}} @@ -57,21 +56,13 @@ def group_by_make(all_car_info: List[CarInfo]) -> Dict[str, List[CarInfo]]: return dict(sorted_car_info) -def generate_cars_md(all_car_info: List[CarInfo], template_fn: str, only_tier_cols: bool) -> str: +def generate_cars_md(all_car_info: List[CarInfo], template_fn: str) -> str: with open(template_fn, "r") as f: template = jinja2.Template(f.read(), trim_blocks=True, lstrip_blocks=True) - cols = list(Column) - if only_tier_cols: - hide_cols = set(StarColumns) - set(TierColumns) - cols = [c for c in cols if c not in hide_cols] - for car in all_car_info: - for c in hide_cols: - del car.row[c] - - footnotes = [fn.value.text for fn in get_all_footnotes(only_tier_cols)] + footnotes = [fn.value.text for fn in get_all_footnotes()] cars_md: str = template.render(all_car_info=all_car_info, group_by_make=group_by_make, - footnotes=footnotes, Star=Star, Column=cols, STAR_DESCRIPTIONS=STAR_DESCRIPTIONS) + footnotes=footnotes, Column=Column) return cars_md @@ -79,11 +70,10 @@ def generate_cars_md(all_car_info: List[CarInfo], template_fn: str, only_tier_co parser = argparse.ArgumentParser(description="Auto generates supported cars documentation", formatter_class=argparse.ArgumentDefaultsHelpFormatter) - parser.add_argument("--tier-columns", action="store_true", help="Include only columns that count in the tier") parser.add_argument("--template", default=CARS_MD_TEMPLATE, help="Override default template filename") parser.add_argument("--out", default=CARS_MD_OUT, help="Override default generated filename") args = parser.parse_args() with open(args.out, 'w') as f: - f.write(generate_cars_md(get_all_car_info(args.tier_columns), args.template, args.tier_columns)) + f.write(generate_cars_md(get_all_car_info(), args.template)) print(f"Generated and written to {args.out}") diff --git a/selfdrive/car/docs_definitions.py b/selfdrive/car/docs_definitions.py index d882cd120dacd5..52d6388d7edf6b 100644 --- a/selfdrive/car/docs_definitions.py +++ b/selfdrive/car/docs_definitions.py @@ -2,7 +2,7 @@ from collections import namedtuple from dataclasses import dataclass, field from enum import Enum -from typing import Dict, List, Optional, Tuple, Union, no_type_check +from typing import Dict, List, Optional, Tuple, Union from cereal import car from common.conversions import Conversions as CV @@ -15,20 +15,15 @@ NO_AUTO_RESUME = NO_AUTO_RESUME_STOCK_LONG | {"nissan", "subaru"} -class Tier(Enum): - GOLD = 0 - SILVER = 1 - BRONZE = 2 - - class Column(Enum): MAKE = "Make" MODEL = "Model" PACKAGE = "Supported Package" - LONGITUDINAL = "openpilot ACC" - FSR_LONGITUDINAL = "Stop and Go" - FSR_STEERING = "Steer to 0" + LONGITUDINAL = "ACC" + FSR_LONGITUDINAL = "No ACC accel below" + FSR_STEERING = "No ALC below" STEERING_TORQUE = "Steering Torque" + HARNESS = "Harness" class Star(Enum): @@ -37,9 +32,46 @@ class Star(Enum): EMPTY = "empty" -StarColumns = list(Column)[3:] -TierColumns = (Column.FSR_LONGITUDINAL, Column.FSR_STEERING, Column.STEERING_TORQUE) -CarFootnote = namedtuple("CarFootnote", ["text", "column", "star"], defaults=[None]) +class Harness(Enum): + nidec = "Honda Nidec" + bosch_a = "Honda Bosch A" + bosch_b = "Honda Bosch B" + toyota = "Toyota" + subaru_a = "Subaru A" + subaru_b = "Subaru B" + fca = "FCA" + ram = "Ram" + vw = "VW" + j533 = "J533" + hyundai_a = "Hyundai A" + hyundai_b = "Hyundai B" + hyundai_c = "Hyundai C" + hyundai_d = "Hyundai D" + hyundai_e = "Hyundai E" + hyundai_f = "Hyundai F" + hyundai_g = "Hyundai G" + hyundai_h = "Hyundai H" + hyundai_i = "Hyundai I" + hyundai_j = "Hyundai J" + hyundai_k = "Hyundai K" + hyundai_l = "Hyundai L" + hyundai_m = "Hyundai M" + hyundai_n = "Hyundai N" + hyundai_o = "Hyundai O" + hyundai_p = "Hyundai P" + hyundai_q = "Hyundai Q" + custom = "Developer" + obd_ii = "OBD-II" + gm = "GM" + nissan_a = "Nissan A" + nissan_b = "Nissan B" + mazda = "Mazda" + ford_q3 = "Ford Q3" + ford_q4 = "Ford Q4" + none = "None" + + +CarFootnote = namedtuple("CarFootnote", ["text", "column"], defaults=[None]) def get_footnotes(footnotes: List[Enum], column: Column) -> List[Enum]: @@ -83,7 +115,7 @@ class CarInfo: footnotes: List[Enum] = field(default_factory=list) min_steer_speed: Optional[float] = None min_enable_speed: Optional[float] = None - harness: Optional[Enum] = None + harness: Enum = Harness.none def init(self, CP: car.CarParams, all_footnotes: Dict[Enum, int]): # TODO: set all the min steer speeds in carParams and remove this @@ -103,11 +135,11 @@ def init(self, CP: car.CarParams, all_footnotes: Dict[Enum, int]): Column.MAKE: self.make, Column.MODEL: self.model, Column.PACKAGE: self.package, - # StarColumns - Column.LONGITUDINAL: Star.FULL if CP.openpilotLongitudinalControl and not CP.radarOffCan else Star.EMPTY, - Column.FSR_LONGITUDINAL: Star.FULL if self.min_enable_speed <= 0. else Star.EMPTY, - Column.FSR_STEERING: Star.FULL if self.min_steer_speed <= 0. else Star.EMPTY, + Column.LONGITUDINAL: "openpilot" if CP.openpilotLongitudinalControl and not CP.radarOffCan else "Stock", + Column.FSR_LONGITUDINAL: f"{max(self.min_enable_speed * CV.MS_TO_MPH, 0):.0f} mph", + Column.FSR_STEERING: f"{max(self.min_steer_speed * CV.MS_TO_MPH, 0):.0f} mph", Column.STEERING_TORQUE: Star.EMPTY, + Column.HARNESS: self.harness.value, } # Set steering torque star from max lateral acceleration @@ -115,26 +147,7 @@ def init(self, CP: car.CarParams, all_footnotes: Dict[Enum, int]): if CP.maxLateralAccel >= GOOD_TORQUE_THRESHOLD: self.row[Column.STEERING_TORQUE] = Star.FULL - if CP.notCar: - for col in StarColumns: - self.row[col] = Star.FULL - self.all_footnotes = all_footnotes - for column in StarColumns: - # Demote if footnote specifies a star - for fn in get_footnotes(self.footnotes, column): - if fn.value.star is not None: - self.row[column] = fn.value.star - - # openpilot ACC star doesn't count for tiers - full_stars = [s for col, s in self.row.items() if col in TierColumns].count(Star.FULL) - if full_stars == len(TierColumns): - self.tier = Tier.GOLD - elif full_stars == len(TierColumns) - 1: - self.tier = Tier.SILVER - else: - self.tier = Tier.BRONZE - self.year_list = get_year_list(self.years) self.detail_sentence = self.get_detail_sentence(CP) @@ -167,10 +180,9 @@ def get_detail_sentence(self, CP): else: raise Exception(f"This notCar does not have a detail sentence: {CP.carFingerprint}") - @no_type_check def get_column(self, column: Column, star_icon: str, footnote_tag: str) -> str: item: Union[str, Star] = self.row[column] - if column in StarColumns: + if isinstance(item, Star): item = star_icon.format(item.value) elif column == Column.MODEL and len(self.years): item += f" {self.years}" @@ -182,61 +194,3 @@ def get_column(self, column: Column, star_icon: str, footnote_tag: str) -> str: return item - -class Harness(Enum): - nidec = "Honda Nidec" - bosch_a = "Honda Bosch A" - bosch_b = "Honda Bosch B" - toyota = "Toyota" - subaru_a = "Subaru A" - subaru_b = "Subaru B" - fca = "FCA" - ram = "Ram" - vw = "VW" - j533 = "J533" - hyundai_a = "Hyundai A" - hyundai_b = "Hyundai B" - hyundai_c = "Hyundai C" - hyundai_d = "Hyundai D" - hyundai_e = "Hyundai E" - hyundai_f = "Hyundai F" - hyundai_g = "Hyundai G" - hyundai_h = "Hyundai H" - hyundai_i = "Hyundai I" - hyundai_j = "Hyundai J" - hyundai_k = "Hyundai K" - hyundai_l = "Hyundai L" - hyundai_m = "Hyundai M" - hyundai_n = "Hyundai N" - hyundai_o = "Hyundai O" - hyundai_p = "Hyundai P" - hyundai_q = "Hyundai Q" - custom = "Developer" - obd_ii = "OBD-II" - gm = "GM" - nissan_a = "Nissan A" - nissan_b = "Nissan B" - mazda = "Mazda" - ford_q3 = "Ford Q3" - ford_q4 = "Ford Q4" - none = "None" - - -STAR_DESCRIPTIONS = { - "Gas & Brakes": { # icon and row name - Column.FSR_LONGITUDINAL.value: [ - [Star.FULL.value, "openpilot operates down to 0 mph."], - [Star.EMPTY.value, "openpilot operates only above a minimum speed. See your car's manual for the minimum speed."], - ], - }, - "Steering": { - Column.FSR_STEERING.value: [ - [Star.FULL.value, "openpilot can control the steering wheel down to 0 mph."], - [Star.EMPTY.value, "No steering control below certain speeds. See your car's manual for the minimum speed."], - ], - Column.STEERING_TORQUE.value: [ - [Star.FULL.value, "Car has enough steering torque to comfortably take most highway turns."], - [Star.EMPTY.value, "Limited ability to make tighter turns."], - ], - }, -} diff --git a/selfdrive/car/tests/test_docs.py b/selfdrive/car/tests/test_docs.py index 84c6b6e52062cc..af58bb5e5931fd 100755 --- a/selfdrive/car/tests/test_docs.py +++ b/selfdrive/car/tests/test_docs.py @@ -13,7 +13,7 @@ def setUp(self): self.all_cars = get_all_car_info() def test_generator(self): - generated_cars_md = generate_cars_md(self.all_cars, CARS_MD_TEMPLATE, False) + generated_cars_md = generate_cars_md(self.all_cars, CARS_MD_TEMPLATE) with open(CARS_MD_OUT, "r") as f: current_cars_md = f.read() diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index b4e82ec3e361b5..8915146063de3f 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -6,7 +6,7 @@ from cereal import car from common.conversions import Conversions as CV from selfdrive.car import dbc_dict -from selfdrive.car.docs_definitions import CarFootnote, CarInfo, Column, Harness, Star +from selfdrive.car.docs_definitions import CarFootnote, CarInfo, Column, Harness Ecu = car.CarParams.Ecu MIN_ACC_SPEED = 19. * CV.MPH_TO_MS @@ -89,7 +89,7 @@ class Footnote(Enum): DSU = CarFootnote( "When the Driver Support Unit (DSU) is disconnected, openpilot Adaptive Cruise Control (ACC) will replace " + "stock Adaptive Cruise Control (ACC). NOTE: disconnecting the DSU disables Automatic Emergency Braking (AEB).", - Column.LONGITUDINAL, star=Star.HALF) + Column.LONGITUDINAL) CAMRY = CarFootnote( "openpilot operates above 28mph for Camry 4CYL L, 4CYL LE and 4CYL SE which don't have Full-Speed Range Dynamic Radar Cruise Control.", Column.FSR_LONGITUDINAL) From 6a3a9944c25da54880460a579f3d4616ed4b7fa4 Mon Sep 17 00:00:00 2001 From: Erich Moraga <33645296+ErichMoraga@users.noreply.github.com> Date: Thu, 18 Aug 2022 17:18:50 -0500 Subject: [PATCH 060/106] ssh docs: corrections and readability improvements (#25482) * Corrections and readability improvements * Apply suggestions from code review Co-authored-by: Shane Smiskol --- tools/ssh/README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tools/ssh/README.md b/tools/ssh/README.md index 29d33493282076..67b5271a42ac48 100644 --- a/tools/ssh/README.md +++ b/tools/ssh/README.md @@ -7,11 +7,11 @@ In order to SSH into your device, you'll need a GitHub account with SSH keys. Se * Enable SSH in your device's settings * Enter your GitHub username in the device's settings * Connect to your device - * Username: `comma` (comma three) + * Username: `comma` * Port: `22` or `8022` -Here's an example command for connecting to your device using its tethered connection: -`ssh root@192.168.43.1` +Here's an example command for connecting to your device using its tethered connection:
+`ssh comma@192.168.43.1` For doing development work on device, it's recommended to use [SSH agent forwarding](https://docs.github.com/en/developers/overview/using-ssh-agent-forwarding). @@ -34,7 +34,8 @@ Requires [comma SIM with comma prime](https://comma.ai/shop) activated with comm ## Recommended .ssh/config -With the below ssh configuration, you can type `ssh comma-{dongleid}` to connect to your device through `ssh.comma.ai`. For example, `ssh comma-ffffffffffffffff`. +With the below SSH configuration, you can type `ssh comma-{dongleid}` to connect to your device through `ssh.comma.ai`.
+For example: `ssh comma-ffffffffffffffff` ``` Host comma-* From d907021d58b14f49480308f01935c975daa590a6 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 18 Aug 2022 15:36:50 -0700 Subject: [PATCH 061/106] disable panda deep sleep for now --- selfdrive/boardd/boardd.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/boardd/boardd.cc b/selfdrive/boardd/boardd.cc index afbc592b932237..23bf8f292989e8 100644 --- a/selfdrive/boardd/boardd.cc +++ b/selfdrive/boardd/boardd.cc @@ -197,7 +197,7 @@ Panda *usb_connect(std::string serial="", uint32_t index=0) { if (getenv("BOARDD_LOOPBACK")) { panda->set_loopback(true); } - panda->enable_deepsleep(); + //panda->enable_deepsleep(); // power on charging, only the first time. Panda can also change mode and it causes a brief disconneciton #ifndef __x86_64__ From 17992f29c82cbf2f5f7eacf6edf839f97c0e5816 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 18 Aug 2022 16:40:16 -0700 Subject: [PATCH 062/106] bump opendbc --- opendbc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opendbc b/opendbc index c6665ed11b8d8c..3f722780c3af70 160000 --- a/opendbc +++ b/opendbc @@ -1 +1 @@ -Subproject commit c6665ed11b8d8c998e46f8dbee30e70a7d451e5e +Subproject commit 3f722780c3af70a1c244ea762d61edd8c002ed9c From 858eea91634a866cef2e2943fa3654bf3e46d522 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 18 Aug 2022 17:52:09 -0700 Subject: [PATCH 063/106] Hyundai: add HDA1 signals (#25484) * Hyundai: add HDA1 signals * bump * bump to master --- opendbc | 2 +- release/files_common | 2 +- selfdrive/car/hyundai/values.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/opendbc b/opendbc index 3f722780c3af70..1619c9a40f46d1 160000 --- a/opendbc +++ b/opendbc @@ -1 +1 @@ -Subproject commit 3f722780c3af70a1c244ea762d61edd8c002ed9c +Subproject commit 1619c9a40f46d1976a1d4a55f7cf1e3367eea170 diff --git a/release/files_common b/release/files_common index 01386b5858e405..ac2a3ce6266dd2 100644 --- a/release/files_common +++ b/release/files_common @@ -532,7 +532,7 @@ opendbc/honda_insight_ex_2019_can_generated.dbc opendbc/acura_ilx_2016_nidec.dbc opendbc/honda_civic_ex_2022_can_generated.dbc -opendbc/kia_ev6.dbc +opendbc/hyundai_canfd.dbc opendbc/hyundai_kia_generic.dbc opendbc/hyundai_kia_mando_front_radar.dbc diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index 17745a4d75a1c6..9db6c3697c4f6f 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -1362,7 +1362,7 @@ class Buttons: CAR.PALISADE: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar'), CAR.VELOSTER: dbc_dict('hyundai_kia_generic', None), CAR.KIA_CEED: dbc_dict('hyundai_kia_generic', None), - CAR.KIA_EV6: dbc_dict('kia_ev6', None), + CAR.KIA_EV6: dbc_dict('hyundai_canfd', None), CAR.SONATA_HYBRID: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar'), - CAR.IONIQ_5: dbc_dict('kia_ev6', None), + CAR.IONIQ_5: dbc_dict('hyundai_canfd', None), } From e5bb55ccd69fa42777fcd4d836adc777feff9cb1 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Thu, 18 Aug 2022 22:23:39 -0700 Subject: [PATCH 064/106] Toyota: remove STEERING_LKA frequency check (#25490) * remove STEERING_LKA frequency check * bump to master * Update ref_commit --- opendbc | 2 +- selfdrive/car/toyota/carstate.py | 4 +--- selfdrive/test/process_replay/ref_commit | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/opendbc b/opendbc index 1619c9a40f46d1..7e095a90af3d36 160000 --- a/opendbc +++ b/opendbc @@ -1 +1 @@ -Subproject commit 1619c9a40f46d1976a1d4a55f7cf1e3367eea170 +Subproject commit 7e095a90af3d36e6db9128a80f6f3b0cca01efa2 diff --git a/selfdrive/car/toyota/carstate.py b/selfdrive/car/toyota/carstate.py index 281d01026f3a40..537915919c39eb 100644 --- a/selfdrive/car/toyota/carstate.py +++ b/selfdrive/car/toyota/carstate.py @@ -228,10 +228,8 @@ def get_cam_can_parser(CP): ("PRECOLLISION_ACTIVE", "PRE_COLLISION"), ] - # use steering message to check if panda is connected to frc checks = [ - ("STEERING_LKA", 42), - ("PRE_COLLISION", 0), # TODO: figure out why freq is inconsistent + ("PRE_COLLISION", 0), # TODO: figure out why freq is inconsistent ] if CP.carFingerprint in (TSS2_CAR - RADAR_ACC_CAR): diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index da083eeee19604..b9e99cd61754bb 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -35899d5137e298220e91063f3078109227cc8715 \ No newline at end of file +93a136f91739847afe1e1a4a1e98bc7c0adb5ec8 From 844d4d2eceee487aaaf27601522cb9b9bb351614 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Thu, 18 Aug 2022 23:32:11 -0700 Subject: [PATCH 065/106] Multilang: add plural translation test (#25491) Add test for correct format specifier for plural translations --- selfdrive/ui/tests/test_translations.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/selfdrive/ui/tests/test_translations.py b/selfdrive/ui/tests/test_translations.py index 7da4ec0d6e5a2e..fead288dfcad13 100755 --- a/selfdrive/ui/tests/test_translations.py +++ b/selfdrive/ui/tests/test_translations.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import json import os +import re import shutil import unittest import xml.etree.ElementTree as ET @@ -66,6 +67,11 @@ def test_vanished_translations(self): f"{file} ({name}) translation file has obsolete translations. Run selfdrive/ui/update_translations.py --vanish to remove them") def test_plural_translations(self): + """ + Tests: + - that any numerus (plural) translations marked "finished" have all plural forms non-empty + - that the correct format specifier is used (%n) + """ for name, file in self.translation_files.items(): with self.subTest(name=name, file=file): tr_xml = ET.parse(os.path.join(TRANSLATIONS_DIR, f"{file}.ts")) @@ -74,13 +80,15 @@ def test_plural_translations(self): for message in context.iterfind("message"): if message.get("numerus") == "yes": translation = message.find("translation") - numerusform = translation.findall("numerusform") + numerusform = [t.text for t in translation.findall("numerusform")] # Do not assert finished translations if translation.get("type") == "unfinished": continue - self.assertNotIn(None, [x.text for x in numerusform], "Ensure all plural translation forms are completed.") + self.assertNotIn(None, numerusform, "Ensure all plural translation forms are completed.") + self.assertTrue(all([re.search("%[0-9]+", t) is None for t in numerusform]), + "Plural translations must use %n, not %1, %2, etc.: {}".format(numerusform)) if __name__ == "__main__": From 16fe10e1281d68d8e560a9489b973bd34417d469 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Thu, 18 Aug 2022 23:34:48 -0700 Subject: [PATCH 066/106] joystick: revert max axes value (#25483) revert this to 255 --- tools/joystick/joystickd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/joystick/joystickd.py b/tools/joystick/joystickd.py index 6226038d516ed9..35ecca351d1250 100755 --- a/tools/joystick/joystickd.py +++ b/tools/joystick/joystickd.py @@ -41,7 +41,7 @@ class Joystick: def __init__(self): # TODO: find a way to get this from API, perhaps "inputs" doesn't support it self.min_axis_value = {'ABS_Y': 0., 'ABS_RZ': 0.} - self.max_axis_value = {'ABS_Y': 1023., 'ABS_RZ': 255.} + self.max_axis_value = {'ABS_Y': 255., 'ABS_RZ': 255.} self.cancel_button = 'BTN_TRIGGER' self.axes_values = {'ABS_Y': 0., 'ABS_RZ': 0.} # gb, steer self.axes_order = ['ABS_Y', 'ABS_RZ'] From e3d3fd02300ef7109f5fdf0717395eca3757195e Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Thu, 18 Aug 2022 23:40:24 -0700 Subject: [PATCH 067/106] Common button enable/cancel event creation (#25445) * handle button presses in create_common_events * remove from imports * Handle * Fix Honda (it hardcodes pcmCruise) * Update selfdrive/car/volkswagen/interface.py * Update selfdrive/car/volkswagen/interface.py --- selfdrive/car/gm/interface.py | 5 +---- selfdrive/car/honda/interface.py | 5 +---- selfdrive/car/hyundai/interface.py | 19 +++++++++---------- selfdrive/car/interfaces.py | 5 ++++- selfdrive/car/volkswagen/interface.py | 4 +--- 5 files changed, 16 insertions(+), 22 deletions(-) diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py index f3f1e587ca76ec..18709a2a8c816b 100755 --- a/selfdrive/car/gm/interface.py +++ b/selfdrive/car/gm/interface.py @@ -4,7 +4,7 @@ from panda import Panda from common.conversions import Conversions as CV -from selfdrive.car import STD_CARGO_KG, create_button_enable_events, create_button_event, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config +from selfdrive.car import STD_CARGO_KG, create_button_event, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config from selfdrive.car.gm.values import CAR, CruiseButtons, CarControllerParams, EV_CAR, CAMERA_ACC_CAR from selfdrive.car.interfaces import CarInterfaceBase @@ -195,9 +195,6 @@ def _update(self, c): if ret.vEgo < self.CP.minSteerSpeed: events.add(car.CarEvent.EventName.belowSteerSpeed) - # handle button presses - events.events.extend(create_button_enable_events(ret.buttonEvents, pcm_cruise=self.CP.pcmCruise)) - ret.events = events.to_msg() return ret diff --git a/selfdrive/car/honda/interface.py b/selfdrive/car/honda/interface.py index b1461827133a17..a235ba6cda7306 100755 --- a/selfdrive/car/honda/interface.py +++ b/selfdrive/car/honda/interface.py @@ -4,7 +4,7 @@ from common.conversions import Conversions as CV from common.numpy_fast import interp from selfdrive.car.honda.values import CarControllerParams, CruiseButtons, HondaFlags, CAR, HONDA_BOSCH, HONDA_NIDEC_ALT_SCM_MESSAGES, HONDA_BOSCH_ALT_BRAKE_SIGNAL, HONDA_BOSCH_RADARLESS -from selfdrive.car import STD_CARGO_KG, CivicParams, create_button_enable_events, create_button_event, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config +from selfdrive.car import STD_CARGO_KG, CivicParams, create_button_event, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config from selfdrive.car.interfaces import CarInterfaceBase from selfdrive.car.disable_ecu import disable_ecu @@ -352,9 +352,6 @@ def _update(self, c): if self.CS.CP.minEnableSpeed > 0 and ret.vEgo < 0.001: events.add(EventName.manualRestart) - # handle button presses - events.events.extend(create_button_enable_events(ret.buttonEvents, self.CP.pcmCruise)) - ret.events = events.to_msg() return ret diff --git a/selfdrive/car/hyundai/interface.py b/selfdrive/car/hyundai/interface.py index 6b62477a0caab2..6986b973ed97fa 100644 --- a/selfdrive/car/hyundai/interface.py +++ b/selfdrive/car/hyundai/interface.py @@ -4,7 +4,7 @@ from common.conversions import Conversions as CV from selfdrive.car.hyundai.values import CAR, DBC, CANFD_CAR, CAMERA_SCC_CAR, EV_CAR, HYBRID_CAR, LEGACY_SAFETY_MODE_CAR, Buttons, CarControllerParams from selfdrive.car.hyundai.radar_interface import RADAR_START_ADDR -from selfdrive.car import STD_CARGO_KG, create_button_enable_events, create_button_event, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config +from selfdrive.car import STD_CARGO_KG, create_button_event, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config from selfdrive.car.interfaces import CarInterfaceBase from selfdrive.car.disable_ecu import disable_ecu @@ -326,6 +326,14 @@ def init(CP, logcan, sendcan): def _update(self, c): ret = self.CS.update(self.cp, self.cp_cam) + if self.CS.CP.openpilotLongitudinalControl and self.CS.cruise_buttons[-1] != self.CS.prev_cruise_buttons: + buttonEvents = [create_button_event(self.CS.cruise_buttons[-1], self.CS.prev_cruise_buttons, BUTTONS_DICT)] + # Handle CF_Clu_CruiseSwState changing buttons mid-press + if self.CS.cruise_buttons[-1] != 0 and self.CS.prev_cruise_buttons != 0: + buttonEvents.append(create_button_event(0, self.CS.prev_cruise_buttons, BUTTONS_DICT)) + + ret.buttonEvents = buttonEvents + # 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 @@ -335,15 +343,6 @@ def _update(self, c): if self.CS.brake_error: events.add(EventName.brakeUnavailable) - if self.CS.CP.openpilotLongitudinalControl and self.CS.cruise_buttons[-1] != self.CS.prev_cruise_buttons: - buttonEvents = [create_button_event(self.CS.cruise_buttons[-1], self.CS.prev_cruise_buttons, BUTTONS_DICT)] - # Handle CF_Clu_CruiseSwState changing buttons mid-press - if self.CS.cruise_buttons[-1] != 0 and self.CS.prev_cruise_buttons != 0: - buttonEvents.append(create_button_event(0, self.CS.prev_cruise_buttons, BUTTONS_DICT)) - - ret.buttonEvents = buttonEvents - events.events.extend(create_button_enable_events(ret.buttonEvents)) - # low speed steer alert hysteresis logic (only for cars with steer cut off above 10 m/s) if ret.vEgo < (self.CP.minSteerSpeed + 2.) and self.CP.minSteerSpeed > 10.: self.low_speed_alert = True diff --git a/selfdrive/car/interfaces.py b/selfdrive/car/interfaces.py index 1e55e72ac4bec8..9da6aabd67b7cf 100644 --- a/selfdrive/car/interfaces.py +++ b/selfdrive/car/interfaces.py @@ -9,7 +9,7 @@ from common.conversions import Conversions as CV from common.kalman.simple_kalman import KF1D from common.realtime import DT_CTRL -from selfdrive.car import gen_empty_fingerprint +from selfdrive.car import create_button_enable_events, gen_empty_fingerprint from selfdrive.controls.lib.drive_helpers import V_CRUISE_MAX from selfdrive.controls.lib.events import Events from selfdrive.controls.lib.vehicle_model import VehicleModel @@ -213,6 +213,9 @@ def create_common_events(self, cs_out, extra_gears=None, pcm_enable=True, allow_ if cs_out.accFaulted: events.add(EventName.accFaulted) + # Handle button presses + events.events.extend(create_button_enable_events(cs_out.buttonEvents, pcm_cruise=self.CP.pcmCruise)) + # Handle permanent and temporary steering faults self.steering_unpressed = 0 if cs_out.steeringPressed else self.steering_unpressed + 1 if cs_out.steerFaultTemporary: diff --git a/selfdrive/car/volkswagen/interface.py b/selfdrive/car/volkswagen/interface.py index 22206635ace2ff..7e686b970712b3 100644 --- a/selfdrive/car/volkswagen/interface.py +++ b/selfdrive/car/volkswagen/interface.py @@ -1,12 +1,11 @@ from cereal import car from panda import Panda from common.conversions import Conversions as CV -from selfdrive.car import STD_CARGO_KG, create_button_enable_events, scale_rot_inertia, scale_tire_stiffness, \ +from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, \ gen_empty_fingerprint, get_safety_config from selfdrive.car.interfaces import CarInterfaceBase from selfdrive.car.volkswagen.values import CAR, PQ_CARS, CANBUS, NetworkLocation, TransmissionType, GearShifter - EventName = car.CarEvent.EventName @@ -225,7 +224,6 @@ def _update(self, c): if c.enabled and ret.vEgo < self.CP.minEnableSpeed: events.add(EventName.speedTooLow) - events.events.extend(create_button_enable_events(ret.buttonEvents, pcm_cruise=self.CP.pcmCruise)) ret.events = events.to_msg() return ret From 03b074426a7de22b9f5dbfb9bb30f8325ac43b4a Mon Sep 17 00:00:00 2001 From: Jason Wen <47793918+sunnyhaibin@users.noreply.github.com> Date: Fri, 19 Aug 2022 03:48:51 -0400 Subject: [PATCH 068/106] Rename KIA_NIRO_HEV to KIA_NIRO_PHEV (#24216) * Add car port: Kia Niro Plug-In Hybrid 2018 * Add additional FW version * Low speed lockout 32 MPH * Add test route * min_steer_speed in CarInfo * Remove min_steer_speed from CarInfo * Add to CARS.md * run generator * update min enable speed and regen * update ci routes * these are the same car * i think we only add a note if it's a new platform * fix HEV -> PHEV * Add test route * dup fw * haha we already support this car in #25187 Co-authored-by: Shane Smiskol --- selfdrive/car/hyundai/interface.py | 4 ++-- selfdrive/car/hyundai/values.py | 14 +++++++------- selfdrive/car/tests/routes.py | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/selfdrive/car/hyundai/interface.py b/selfdrive/car/hyundai/interface.py index 6986b973ed97fa..23a49a05e57713 100644 --- a/selfdrive/car/hyundai/interface.py +++ b/selfdrive/car/hyundai/interface.py @@ -169,7 +169,7 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl ret.steerRatio = 14.4 * 1.1 # 10% higher at the center seems reasonable ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.25], [0.05]] - elif candidate in (CAR.KIA_NIRO_EV, CAR.KIA_NIRO_HEV, CAR.KIA_NIRO_HEV_2021): + elif candidate in (CAR.KIA_NIRO_EV, CAR.KIA_NIRO_PHEV, CAR.KIA_NIRO_HEV_2021): ret.lateralTuning.pid.kf = 0.00006 ret.mass = 1737. + STD_CARGO_KG ret.wheelbase = 2.7 @@ -177,7 +177,7 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl tire_stiffness_factor = 0.385 ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.25], [0.05]] - if candidate == CAR.KIA_NIRO_HEV: + if candidate == CAR.KIA_NIRO_PHEV: ret.minSteerSpeed = 32 * CV.MPH_TO_MS elif candidate == CAR.KIA_SELTOS: ret.mass = 1337. + STD_CARGO_KG diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index 9db6c3697c4f6f..e36c9a6ac830b1 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -29,7 +29,7 @@ def __init__(self, CP): # To determine the limit for your car, find the maximum value that the stock LKAS will request. # If the max stock LKAS request is <384, add your car to this list. elif CP.carFingerprint in (CAR.GENESIS_G80, CAR.GENESIS_G90, CAR.ELANTRA, CAR.HYUNDAI_GENESIS, CAR.ELANTRA_GT_I30, CAR.IONIQ, - CAR.IONIQ_EV_LTD, CAR.SANTA_FE_PHEV_2022, CAR.SONATA_LF, CAR.KIA_FORTE, CAR.KIA_NIRO_HEV, + CAR.IONIQ_EV_LTD, CAR.SANTA_FE_PHEV_2022, CAR.SONATA_LF, CAR.KIA_FORTE, CAR.KIA_NIRO_PHEV, CAR.KIA_OPTIMA_H, CAR.KIA_SORENTO, CAR.KIA_STINGER): self.STEER_MAX = 255 @@ -71,7 +71,7 @@ class CAR: KIA_FORTE = "KIA FORTE E 2018 & GT 2021" KIA_K5_2021 = "KIA K5 2021" KIA_NIRO_EV = "KIA NIRO EV 2020" - KIA_NIRO_HEV = "KIA NIRO HYBRID 2019" + KIA_NIRO_PHEV = "KIA NIRO HYBRID 2019" KIA_NIRO_HEV_2021 = "KIA NIRO HYBRID 2021" KIA_OPTIMA = "KIA OPTIMA SX 2019 & 2016" KIA_OPTIMA_H = "KIA OPTIMA HYBRID 2017 & SPORTS 2019" @@ -141,7 +141,7 @@ class HyundaiCarInfo(CarInfo): HyundaiCarInfo("Kia Niro Electric 2021", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", harness=Harness.hyundai_c), HyundaiCarInfo("Kia Niro Electric 2022", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", harness=Harness.hyundai_h), ], - CAR.KIA_NIRO_HEV: HyundaiCarInfo("Kia Niro Plug-in Hybrid 2018-19", min_enable_speed=10. * CV.MPH_TO_MS, harness=Harness.hyundai_c), + CAR.KIA_NIRO_PHEV: HyundaiCarInfo("Kia Niro Plug-in Hybrid 2018-19", min_enable_speed=10. * CV.MPH_TO_MS, harness=Harness.hyundai_c), CAR.KIA_NIRO_HEV_2021: [ HyundaiCarInfo("Kia Niro Hybrid 2021", harness=Harness.hyundai_f), # TODO: could be hyundai_d, verify HyundaiCarInfo("Kia Niro Hybrid 2022", harness=Harness.hyundai_h), @@ -1039,7 +1039,7 @@ class Buttons: b'\xf1\x00DEE MFC AT KOR LHD 1.00 1.03 95740-Q4000 180821', ], }, - CAR.KIA_NIRO_HEV: { + CAR.KIA_NIRO_PHEV: { (Ecu.engine, 0x7e0, None): [ b'\xf1\x816H6F4051\x00\x00\x00\x00\x00\x00\x00\x00', b'\xf1\x816H6D1051\x00\x00\x00\x00\x00\x00\x00\x00', @@ -1303,7 +1303,7 @@ class Buttons: # which message has the gear "use_cluster_gears": {CAR.ELANTRA, CAR.ELANTRA_GT_I30, CAR.KONA}, "use_tcu_gears": {CAR.KIA_OPTIMA, CAR.SONATA_LF, CAR.VELOSTER, CAR.TUCSON}, - "use_elect_gears": {CAR.KIA_NIRO_EV, CAR.KIA_NIRO_HEV, CAR.KIA_NIRO_HEV_2021, CAR.KIA_OPTIMA_H, CAR.IONIQ_EV_LTD, CAR.KONA_EV, CAR.IONIQ, CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.ELANTRA_HEV_2021, CAR.SONATA_HYBRID, CAR.KONA_HEV, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022, CAR.IONIQ_PHEV_2019, CAR.KONA_EV_2022}, + "use_elect_gears": {CAR.KIA_NIRO_EV, CAR.KIA_NIRO_PHEV, CAR.KIA_NIRO_HEV_2021, CAR.KIA_OPTIMA_H, CAR.IONIQ_EV_LTD, CAR.KONA_EV, CAR.IONIQ, CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.ELANTRA_HEV_2021, CAR.SONATA_HYBRID, CAR.KONA_HEV, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022, CAR.IONIQ_PHEV_2019, CAR.KONA_EV_2022}, # these cars use the FCA11 message for the AEB and FCW signals, all others use SCC12 "use_fca": {CAR.SONATA, CAR.SONATA_HYBRID, CAR.ELANTRA, CAR.ELANTRA_2021, CAR.ELANTRA_HEV_2021, CAR.ELANTRA_GT_I30, CAR.KIA_STINGER, CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.KONA_EV, CAR.KIA_FORTE, CAR.KIA_NIRO_EV, CAR.PALISADE, CAR.GENESIS_G70, CAR.GENESIS_G70_2020, CAR.KONA, CAR.SANTA_FE, CAR.KIA_SELTOS, CAR.KONA_HEV, CAR.SANTA_FE_2022, CAR.KIA_K5_2021, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022, CAR.TUCSON, CAR.KONA_EV_2022}, @@ -1314,7 +1314,7 @@ class Buttons: # The camera does SCC on these cars, rather than the radar CAMERA_SCC_CAR = {CAR.KONA_EV_2022, } -HYBRID_CAR = {CAR.IONIQ_PHEV, CAR.ELANTRA_HEV_2021, CAR.KIA_NIRO_HEV, CAR.KIA_NIRO_HEV_2021, CAR.SONATA_HYBRID, CAR.KONA_HEV, CAR.IONIQ, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022, CAR.IONIQ_PHEV_2019} # these cars use a different gas signal +HYBRID_CAR = {CAR.IONIQ_PHEV, CAR.ELANTRA_HEV_2021, CAR.KIA_NIRO_PHEV, CAR.KIA_NIRO_HEV_2021, CAR.SONATA_HYBRID, CAR.KONA_HEV, CAR.IONIQ, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022, CAR.IONIQ_PHEV_2019} # these cars use a different gas signal EV_CAR = {CAR.IONIQ_EV_2020, CAR.IONIQ_EV_LTD, CAR.KONA_EV, CAR.KIA_NIRO_EV, CAR.KONA_EV_2022} # these cars require a special panda safety mode due to missing counters and checksums in the messages @@ -1341,7 +1341,7 @@ class Buttons: CAR.KIA_FORTE: dbc_dict('hyundai_kia_generic', None), CAR.KIA_K5_2021: dbc_dict('hyundai_kia_generic', None), CAR.KIA_NIRO_EV: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar'), - CAR.KIA_NIRO_HEV: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar'), + CAR.KIA_NIRO_PHEV: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar'), CAR.KIA_NIRO_HEV_2021: dbc_dict('hyundai_kia_generic', None), CAR.KIA_OPTIMA: dbc_dict('hyundai_kia_generic', None), CAR.KIA_OPTIMA_H: dbc_dict('hyundai_kia_generic', None), diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py index 5c767ae1a85228..7e27888208d86e 100644 --- a/selfdrive/car/tests/routes.py +++ b/selfdrive/car/tests/routes.py @@ -107,7 +107,7 @@ TestRoute("d824e27e8c60172c|2022-05-19--16-15-28", HYUNDAI.KIA_EV6), TestRoute("007d5e4ad9f86d13|2021-09-30--15-09-23", HYUNDAI.KIA_K5_2021), TestRoute("50c6c9b85fd1ff03|2020-10-26--17-56-06", HYUNDAI.KIA_NIRO_EV), - TestRoute("173219cf50acdd7b|2021-07-05--10-27-41", HYUNDAI.KIA_NIRO_HEV), + TestRoute("173219cf50acdd7b|2021-07-05--10-27-41", HYUNDAI.KIA_NIRO_PHEV), TestRoute("34a875f29f69841a|2021-07-29--13-02-09", HYUNDAI.KIA_NIRO_HEV_2021), TestRoute("50a2212c41f65c7b|2021-05-24--16-22-06", HYUNDAI.KIA_FORTE), TestRoute("c5ac319aa9583f83|2021-06-01--18-18-31", HYUNDAI.ELANTRA), From fe509e0354466a301dd403d29b5b2c82aea8aad1 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 19 Aug 2022 12:04:12 -0700 Subject: [PATCH 069/106] GM pcmCruise: cancel more reliably (#25454) * Cancel more reliably * Apply suggestions from code review * Try sending multiple * Apply suggestions from code review * Apply suggestions from code review * Update selfdrive/car/gm/carcontroller.py * lower rate a bit * try this * Update selfdrive/car/gm/carcontroller.py --- selfdrive/car/gm/carcontroller.py | 4 ++-- selfdrive/car/gm/carstate.py | 3 +++ selfdrive/car/gm/gmcan.py | 7 +++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/selfdrive/car/gm/carcontroller.py b/selfdrive/car/gm/carcontroller.py index 10e6027973e60e..977d20c5b3c2e1 100644 --- a/selfdrive/car/gm/carcontroller.py +++ b/selfdrive/car/gm/carcontroller.py @@ -109,10 +109,10 @@ def update(self, CC, CS): else: # Stock longitudinal, integrated at camera - if (self.frame - self.last_button_frame) * DT_CTRL > 0.1: + if (self.frame - self.last_button_frame) * DT_CTRL > 0.04: if CC.cruiseControl.cancel: self.last_button_frame = self.frame - can_sends.append(gmcan.create_buttons(self.packer_pt, CanBus.CAMERA, CruiseButtons.CANCEL)) + can_sends.append(gmcan.create_buttons(self.packer_pt, CanBus.CAMERA, CS.buttons_counter, CruiseButtons.CANCEL)) # Show green icon when LKA torque is applied, and # alarming orange icon when approaching torque limit. diff --git a/selfdrive/car/gm/carstate.py b/selfdrive/car/gm/carstate.py index 0bda7edad97ced..0bba1d29b8c01f 100644 --- a/selfdrive/car/gm/carstate.py +++ b/selfdrive/car/gm/carstate.py @@ -16,12 +16,14 @@ def __init__(self, CP): can_define = CANDefine(DBC[CP.carFingerprint]["pt"]) self.shifter_values = can_define.dv["ECMPRDNL2"]["PRNDL2"] self.lka_steering_cmd_counter = 0 + self.buttons_counter = 0 def update(self, pt_cp, cam_cp, loopback_cp): ret = car.CarState.new_message() self.prev_cruise_buttons = self.cruise_buttons self.cruise_buttons = pt_cp.vl["ASCMSteeringButton"]["ACCButtons"] + self.buttons_counter = pt_cp.vl["ASCMSteeringButton"]["RollingCounter"] ret.wheelSpeeds = self.get_wheel_speeds( pt_cp.vl["EBCMWheelSpdFront"]["FLWheelSpd"], @@ -109,6 +111,7 @@ def get_can_parser(CP): ("AcceleratorPedal2", "AcceleratorPedal2"), ("CruiseState", "AcceleratorPedal2"), ("ACCButtons", "ASCMSteeringButton"), + ("RollingCounter", "ASCMSteeringButton"), ("SteeringWheelAngle", "PSCMSteeringAngle"), ("SteeringWheelRate", "PSCMSteeringAngle"), ("FLWheelSpd", "EBCMWheelSpdFront"), diff --git a/selfdrive/car/gm/gmcan.py b/selfdrive/car/gm/gmcan.py index 3a10c4d9dab4ac..20e4c4ab6efb69 100644 --- a/selfdrive/car/gm/gmcan.py +++ b/selfdrive/car/gm/gmcan.py @@ -1,7 +1,10 @@ from selfdrive.car import make_can_msg -def create_buttons(packer, bus, button): - values = {"ACCButtons": button} +def create_buttons(packer, bus, idx, button): + values = { + "ACCButtons": button, + "RollingCounter": idx, + } return packer.make_can_msg("ASCMSteeringButton", bus, values) def create_steering_control(packer, bus, apply_steer, idx, lkas_active): From 93b01fd9eaa472ab93930bf8259574bdb7040c95 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Fri, 19 Aug 2022 12:54:08 -0700 Subject: [PATCH 070/106] bump panda --- panda | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda b/panda index ba8772123f1312..abaa9f8968df13 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit ba8772123f13123c797234660c56adb70795cebb +Subproject commit abaa9f8968df13c8a858413cc9936269702c2d60 From a0af3a998d3a36c9f65ca6d6443f043cbf5be068 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 19 Aug 2022 13:34:23 -0700 Subject: [PATCH 071/106] Car docs: add more videos (#25494) * Add Civic video * add mazda cx-9 2022 video link --- selfdrive/car/honda/values.py | 2 +- selfdrive/car/mazda/values.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/selfdrive/car/honda/values.py b/selfdrive/car/honda/values.py index ab1cc9a6cc0e51..ad4f73c011d4b2 100644 --- a/selfdrive/car/honda/values.py +++ b/selfdrive/car/honda/values.py @@ -113,7 +113,7 @@ class HondaCarInfo(CarInfo): HondaCarInfo("Honda Inspire 2018", "All", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch_a), ], CAR.ACCORDH: HondaCarInfo("Honda Accord Hybrid 2018-22", "All", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch_a), - CAR.CIVIC: HondaCarInfo("Honda Civic 2016-18", harness=Harness.nidec), + CAR.CIVIC: HondaCarInfo("Honda Civic 2016-18", harness=Harness.nidec, video_link="https://youtu.be/-IkImTe1NYE"), CAR.CIVIC_BOSCH: [ HondaCarInfo("Honda Civic 2019-21", "All", video_link="https://www.youtube.com/watch?v=4Iz1Mz5LGF8", footnotes=[Footnote.CIVIC_DIESEL], min_steer_speed=2. * CV.MPH_TO_MS, harness=Harness.bosch_a), HondaCarInfo("Honda Civic Hatchback 2017-21", harness=Harness.bosch_a), diff --git a/selfdrive/car/mazda/values.py b/selfdrive/car/mazda/values.py index 7e99cccec6f0b6..ed246f15da54db 100644 --- a/selfdrive/car/mazda/values.py +++ b/selfdrive/car/mazda/values.py @@ -40,7 +40,7 @@ class MazdaCarInfo(CarInfo): CAR.CX9: MazdaCarInfo("Mazda CX-9 2016-20"), CAR.MAZDA3: MazdaCarInfo("Mazda 3 2017-18"), CAR.MAZDA6: MazdaCarInfo("Mazda 6 2017-20"), - CAR.CX9_2021: MazdaCarInfo("Mazda CX-9 2021-22"), + CAR.CX9_2021: MazdaCarInfo("Mazda CX-9 2021-22", video_link="https://youtu.be/dA3duO4a0O4"), CAR.CX5_2022: MazdaCarInfo("Mazda CX-5 2022"), } From fb19e24d6019a23e8bfb5f767bfa976d373a6e3d Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 19 Aug 2022 15:48:46 -0700 Subject: [PATCH 072/106] GM Bolt EUV: update supported packages (#25496) * Update values.py * Update selfdrive/car/gm/values.py Co-authored-by: Adeeb Shihadeh * update docs Co-authored-by: Adeeb Shihadeh --- docs/CARS.md | 2 +- selfdrive/car/gm/values.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/CARS.md b/docs/CARS.md index efd9b3c5201129..fe2c423273c1b6 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -18,7 +18,7 @@ A supported vehicle is one that just works when you install a comma device. Ever |Audi|RS3 2018|ACC + Lane Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|VW| |Audi|S3 2015-17|ACC + Lane Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|VW| |Cadillac|Escalade ESV 2016[1](#footnotes)|Adaptive Cruise Control (ACC) & LKAS|openpilot|0 mph|7 mph|[![star](assets/icon-star-full.svg)](##)|OBD-II| -|Chevrolet|Bolt EUV 2022-23|Premier/Premier Redline Trim|Stock|0 mph|7 mph|[![star](assets/icon-star-full.svg)](##)|GM| +|Chevrolet|Bolt EUV 2022-23|Premier or Premier Redline Trim without Super Cruise Package|Stock|0 mph|7 mph|[![star](assets/icon-star-full.svg)](##)|GM| |Chevrolet|Volt 2017-18[1](#footnotes)|Adaptive Cruise Control|openpilot|0 mph|7 mph|[![star](assets/icon-star-full.svg)](##)|OBD-II| |Chrysler|Pacifica 2017-18|Adaptive Cruise Control|Stock|0 mph|9 mph|[![star](assets/icon-star-full.svg)](##)|FCA| |Chrysler|Pacifica 2019-20|Adaptive Cruise Control|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|FCA| diff --git a/selfdrive/car/gm/values.py b/selfdrive/car/gm/values.py index cb9aff172b4ef6..1f7b0a5db6a8ca 100644 --- a/selfdrive/car/gm/values.py +++ b/selfdrive/car/gm/values.py @@ -83,7 +83,7 @@ class GMCarInfo(CarInfo): CAR.ACADIA: GMCarInfo("GMC Acadia 2018", video_link="https://www.youtube.com/watch?v=0ZN6DdsBUZo"), CAR.BUICK_REGAL: GMCarInfo("Buick Regal Essence 2018"), CAR.ESCALADE_ESV: GMCarInfo("Cadillac Escalade ESV 2016", "Adaptive Cruise Control (ACC) & LKAS"), - CAR.BOLT_EUV: GMCarInfo("Chevrolet Bolt EUV 2022-23", "Premier/Premier Redline Trim", video_link="https://youtu.be/xvwzGMUA210", footnotes=[], harness=Harness.gm), + CAR.BOLT_EUV: GMCarInfo("Chevrolet Bolt EUV 2022-23", "Premier or Premier Redline Trim without Super Cruise Package", video_link="https://youtu.be/xvwzGMUA210", footnotes=[], harness=Harness.gm), } From 090e92bb699ac05340dbb325076402d09dd53a9c Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Fri, 19 Aug 2022 16:12:16 -0700 Subject: [PATCH 073/106] Hyundai: common CAN-FD gear signal (#25498) * Hyundai: common CAN-FD gear signal * bump opendbc --- opendbc | 2 +- selfdrive/car/hyundai/carstate.py | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/opendbc b/opendbc index 7e095a90af3d36..3270c931c07bd3 160000 --- a/opendbc +++ b/opendbc @@ -1 +1 @@ -Subproject commit 7e095a90af3d36e6db9128a80f6f3b0cca01efa2 +Subproject commit 3270c931c07bd3a47839a1a84c109eb2a7d295a6 diff --git a/selfdrive/car/hyundai/carstate.py b/selfdrive/car/hyundai/carstate.py index 9105f12789f067..08eccc3fe56421 100644 --- a/selfdrive/car/hyundai/carstate.py +++ b/selfdrive/car/hyundai/carstate.py @@ -20,7 +20,7 @@ def __init__(self, CP): self.main_buttons = deque([Buttons.NONE] * PREV_BUTTON_SAMPLES, maxlen=PREV_BUTTON_SAMPLES) if CP.carFingerprint in CANFD_CAR: - self.shifter_values = can_define.dv["ACCELERATOR"]["GEAR"] + self.shifter_values = can_define.dv["GEAR_SHIFTER"]["GEAR"] elif self.CP.carFingerprint in FEATURES["use_cluster_gears"]: self.shifter_values = can_define.dv["CLU15"]["CF_Clu_Gear"] elif self.CP.carFingerprint in FEATURES["use_tcu_gears"]: @@ -143,7 +143,7 @@ def update_canfd(self, cp, cp_cam): ret.doorOpen = cp.vl["DOORS_SEATBELTS"]["DRIVER_DOOR_OPEN"] == 1 ret.seatbeltUnlatched = cp.vl["DOORS_SEATBELTS"]["DRIVER_SEATBELT_LATCHED"] == 0 - gear = cp.vl["ACCELERATOR"]["GEAR"] + gear = cp.vl["GEAR_SHIFTER"]["GEAR"] ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(gear)) # TODO: figure out positions @@ -381,7 +381,7 @@ def get_can_parser_canfd(CP): ("WHEEL_SPEED_4", "WHEEL_SPEEDS"), ("ACCELERATOR_PEDAL", "ACCELERATOR"), - ("GEAR", "ACCELERATOR"), + ("GEAR", "GEAR_SHIFTER"), ("BRAKE_PRESSED", "BRAKE"), ("STEERING_RATE", "STEERING_SENSORS"), @@ -408,6 +408,7 @@ def get_can_parser_canfd(CP): checks = [ ("WHEEL_SPEEDS", 100), ("ACCELERATOR", 100), + ("GEAR_SHIFTER", 100), ("BRAKE", 100), ("STEERING_SENSORS", 100), ("MDPS", 100), From 1e9fdff6422c4f49702f5de56280241088b2abca Mon Sep 17 00:00:00 2001 From: Jason Shuler Date: Fri, 19 Aug 2022 19:58:06 -0400 Subject: [PATCH 074/106] GM: Chevy Silverado 2020-21 support (#25429) * Silverado support Co-authored-by: Jason Shuler * Update docs * Try 2 m/s/s * Should be good torque values * Add Silverado test route * Add to releases * Send counter * can't send multiple or it faults * Send at 33hz, no counter * try 25hz, don't line up exactly with car's buttons * never tried 10hz with same counter * Update selfdrive/car/gm/gmcan.py * Make same as pcmCruise branch * update year and package (different packages needed per-trim) * Update year in releases * Revert to 21 * We can use this package name again * wrong one! Co-authored-by: Shane Smiskol --- RELEASES.md | 1 + docs/CARS.md | 3 ++- selfdrive/car/gm/interface.py | 9 +++++++++ selfdrive/car/gm/values.py | 8 +++++++- selfdrive/car/tests/routes.py | 1 + selfdrive/car/torque_data/override.yaml | 1 + 6 files changed, 21 insertions(+), 2 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index ced165fb0d0200..cb6bf15525c0fb 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -4,6 +4,7 @@ Version 0.8.16 (2022-XX-XX) * Reduced turn cutting * Auto-detect right hand drive setting with driver monitoring model * Chevrolet Bolt EUV 2022-23 support thanks to JasonJShuler! +* Chevrolet Silverado 2020-21 support thanks to JasonJShuler! * Hyundai Ioniq 5 2022 support thanks to sunnyhaibin! * Hyundai Kona Electric 2022 support thanks to sunnyhaibin! * Subaru Legacy 2020-22 support thanks to martinl! diff --git a/docs/CARS.md b/docs/CARS.md index fe2c423273c1b6..b244b5c361d3e8 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -4,7 +4,7 @@ A supported vehicle is one that just works when you install a comma device. Every car performs differently with openpilot, but all supported cars should provide a better experience than any stock system. -# 202 Supported Cars +# 203 Supported Cars |Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Harness| |---|---|---|:---:|:---:|:---:|:---:|:---:| @@ -19,6 +19,7 @@ A supported vehicle is one that just works when you install a comma device. Ever |Audi|S3 2015-17|ACC + Lane Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|VW| |Cadillac|Escalade ESV 2016[1](#footnotes)|Adaptive Cruise Control (ACC) & LKAS|openpilot|0 mph|7 mph|[![star](assets/icon-star-full.svg)](##)|OBD-II| |Chevrolet|Bolt EUV 2022-23|Premier or Premier Redline Trim without Super Cruise Package|Stock|0 mph|7 mph|[![star](assets/icon-star-full.svg)](##)|GM| +|Chevrolet|Silverado 1500 2020-21|Safety Package II|Stock|0 mph|7 mph|[![star](assets/icon-star-full.svg)](##)|GM| |Chevrolet|Volt 2017-18[1](#footnotes)|Adaptive Cruise Control|openpilot|0 mph|7 mph|[![star](assets/icon-star-full.svg)](##)|OBD-II| |Chrysler|Pacifica 2017-18|Adaptive Cruise Control|Stock|0 mph|9 mph|[![star](assets/icon-star-full.svg)](##)|FCA| |Chrysler|Pacifica 2019-20|Adaptive Cruise Control|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|FCA| diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py index 18709a2a8c816b..09d950ea8d0072 100755 --- a/selfdrive/car/gm/interface.py +++ b/selfdrive/car/gm/interface.py @@ -160,6 +160,15 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None, disa ret.steerActuatorDelay = 0.2 CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) + elif candidate == CAR.SILVERADO: + ret.minEnableSpeed = -1 + ret.mass = 2200. + STD_CARGO_KG + ret.wheelbase = 3.75 + ret.steerRatio = 16.3 + ret.centerToFront = ret.wheelbase * 0.5 + tire_stiffness_factor = 1.0 + CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) + # TODO: get actual value, for now starting with reasonable value for # civic and scaling by mass and wheelbase ret.rotationalInertia = scale_rot_inertia(ret.mass, ret.wheelbase) diff --git a/selfdrive/car/gm/values.py b/selfdrive/car/gm/values.py index 1f7b0a5db6a8ca..df91938d8f0fbd 100644 --- a/selfdrive/car/gm/values.py +++ b/selfdrive/car/gm/values.py @@ -59,6 +59,7 @@ class CAR: BUICK_REGAL = "BUICK REGAL ESSENCE 2018" ESCALADE_ESV = "CADILLAC ESCALADE ESV 2016" BOLT_EUV = "CHEVROLET BOLT EUV 2022" + SILVERADO = "CHEVROLET SILVERADO 1500 2020" class Footnote(Enum): @@ -84,6 +85,7 @@ class GMCarInfo(CarInfo): CAR.BUICK_REGAL: GMCarInfo("Buick Regal Essence 2018"), CAR.ESCALADE_ESV: GMCarInfo("Cadillac Escalade ESV 2016", "Adaptive Cruise Control (ACC) & LKAS"), CAR.BOLT_EUV: GMCarInfo("Chevrolet Bolt EUV 2022-23", "Premier or Premier Redline Trim without Super Cruise Package", video_link="https://youtu.be/xvwzGMUA210", footnotes=[], harness=Harness.gm), + CAR.SILVERADO: GMCarInfo("Chevrolet Silverado 1500 2020-21", "Safety Package II", footnotes=[], harness=Harness.gm), } @@ -157,6 +159,10 @@ class CanBus: { 189: 7, 190: 7, 193: 8, 197: 8, 201: 8, 209: 7, 211: 3, 241: 6, 257: 8, 288: 5, 289: 8, 298: 8, 304: 3, 309: 8, 311: 8, 313: 8, 320: 4, 322: 7, 328: 1, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 451: 8, 452: 8, 453: 6, 458: 5, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 500: 6, 501: 8, 528: 5, 532: 6, 560: 8, 562: 8, 563: 5, 565: 5, 566: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 715: 8, 717: 5, 753: 5, 761: 7, 789: 5, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 848: 4, 869: 4, 880: 6, 977: 8, 1001: 8, 1017: 8, 1020: 8, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1265: 8, 1280: 4, 1296: 4, 1300: 8, 1930: 7 }], + CAR.SILVERADO: [ + { + 190: 6, 193: 8, 197: 8, 201: 8, 208: 8, 209: 7, 211: 2, 241: 6, 249: 8, 257: 8, 288: 5, 289: 8, 298: 8, 304: 3, 309: 8, 311: 8, 313: 8, 320: 4, 322: 7, 328: 1, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 413: 8, 451: 8, 452: 8, 453: 6, 455: 7, 460: 5, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 500: 6, 501: 8, 528: 5, 532: 6, 560: 8, 562: 8, 563: 5, 565: 5, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 715: 8, 717: 5, 761: 7, 789: 5, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 848: 4, 869: 4, 880: 6, 977: 8, 1001: 8, 1011: 6, 1017: 8, 1020: 8, 1033: 7, 1034: 7, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1271: 8, 1280: 4, 1296: 4, 1300: 8, 1930: 7 + }], } DBC: Dict[str, Dict[str, str]] = defaultdict(lambda: dbc_dict('gm_global_a_powertrain_generated', 'gm_global_a_object', chassis_dbc='gm_global_a_chassis')) @@ -164,6 +170,6 @@ class CanBus: EV_CAR = {CAR.VOLT, CAR.BOLT_EUV} # We're integrated at the camera with VOACC on these cars (instead of ASCM w/ OBD-II harness) -CAMERA_ACC_CAR = {CAR.BOLT_EUV} +CAMERA_ACC_CAR = {CAR.BOLT_EUV, CAR.SILVERADO} STEER_THRESHOLD = 1.0 diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py index 7e27888208d86e..6cae48cd98d7bc 100644 --- a/selfdrive/car/tests/routes.py +++ b/selfdrive/car/tests/routes.py @@ -48,6 +48,7 @@ TestRoute("46460f0da08e621e|2021-10-26--07-21-46", GM.ESCALADE_ESV), TestRoute("c950e28c26b5b168|2018-05-30--22-03-41", GM.VOLT), TestRoute("f08912a233c1584f|2022-08-11--18-02-41", GM.BOLT_EUV), + TestRoute("38aa7da107d5d252|2022-08-15--16-01-12", GM.SILVERADO), TestRoute("0e7a2ba168465df5|2020-10-18--14-14-22", HONDA.ACURA_RDX_3G), TestRoute("a74b011b32b51b56|2020-07-26--17-09-36", HONDA.CIVIC), diff --git a/selfdrive/car/torque_data/override.yaml b/selfdrive/car/torque_data/override.yaml index 8dd8c43220d097..5324108213852f 100644 --- a/selfdrive/car/torque_data/override.yaml +++ b/selfdrive/car/torque_data/override.yaml @@ -25,6 +25,7 @@ RAM 1500 5TH GEN: [2.0, 2.0, 0.0] RAM HD 5TH GEN: [1.4, 1.4, 0.0] SUBARU OUTBACK 6TH GEN: [2.3, 2.3, 0.11] CHEVROLET BOLT EUV 2022: [2.0, 2.0, 0.05] +CHEVROLET SILVERADO 1500 2020: [1.9, 1.9, 0.112] VOLKSWAGEN PASSAT NMS: [2.5, 2.5, 0.1] # Dashcam or fallback configured as ideal car From 3640922f85323250d852900c18ea532f4f89304b Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 19 Aug 2022 19:27:16 -0700 Subject: [PATCH 075/106] Show CAN error if message counters are invalid (#25497) * counter check affects can valid * Apply suggestions from code review * bump to master --- opendbc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opendbc b/opendbc index 3270c931c07bd3..b913296c912344 160000 --- a/opendbc +++ b/opendbc @@ -1 +1 @@ -Subproject commit 3270c931c07bd3a47839a1a84c109eb2a7d295a6 +Subproject commit b913296c9123441b2b271c00239929ed388169b5 From bd5e28909f4576699717f8a2f6751f0d9fdfecc0 Mon Sep 17 00:00:00 2001 From: Jason Wen <47793918+sunnyhaibin@users.noreply.github.com> Date: Fri, 19 Aug 2022 23:14:30 -0400 Subject: [PATCH 076/106] Hyundai: Car Port for Tucson Hybrid 2022 (#25276) * Hyundai: Car Port for Tucson Hybrid 2022 * Update RELEASES.md * Init gear_msg at the top * FW versions from script * Button send attempt * start with some cleanup * Send button fixed bits * Define all bytes and only send PAUSE/RESUME * Use CRUISE_INFO to cancel cruise and resume * 8-bit counter * Cleanup ish * 8 bit counter * Send at 20ms * Disengage bits * Revert bump submodules * Allow tx on 0x1a0 * Fix byte counts * Send LFA and HDA icons based on engageability * Send cruise buttons only on HDA2 cars for now * Add comments * Add FLAG_HYUNDAI_CANFD_HDA2 flag * Update interface.py * Update carstate.py * Update carstate.py * Update carstate.py * Bump submodules * Bump panda * Bump opendbc * Allow tx with CRUISE_INACTIVE * GEAR has 24 bytes only * Generate car docs * Fix CRUISE_INFO copy * Remove unused class * Add CAN-FD busses to unit test * Bump opendbc * Revert "Add CAN-FD busses to unit test" This reverts commit 2f751640408a7f73a9100947cbd95ea13fbb8a48. * Remove duplicate * New tune based on data * Panda safety cleanup * Include bus 0 in rx checks * Missed one * bus 6 check * Remove redundant check * Add comments * Bump opendbc * Sync with DBC * Hide LFA icon when disengaged * Little endian * fix comment * more conditions in carcontroller * update pedal signal * update tuning * cleanup carcontroller * bump panda * fix mismatch * alt buttons * little more cleanup * update refs for EV6 new safety param * bump panda Co-authored-by: Adeeb Shihadeh --- RELEASES.md | 1 + docs/CARS.md | 3 +- panda | 2 +- selfdrive/car/docs.py | 4 +- selfdrive/car/hyundai/carcontroller.py | 29 ++++-- selfdrive/car/hyundai/carstate.py | 96 ++++++++++++++----- selfdrive/car/hyundai/hyundaicanfd.py | 23 ++++- selfdrive/car/hyundai/interface.py | 21 +++- selfdrive/car/hyundai/values.py | 26 ++++- selfdrive/car/tests/routes.py | 1 + selfdrive/car/torque_data/override.yaml | 1 + selfdrive/test/process_replay/ref_commit | 2 +- .../test/process_replay/test_processes.py | 4 +- 13 files changed, 169 insertions(+), 44 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index cb6bf15525c0fb..235e90a3d71d4f 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -7,6 +7,7 @@ Version 0.8.16 (2022-XX-XX) * Chevrolet Silverado 2020-21 support thanks to JasonJShuler! * Hyundai Ioniq 5 2022 support thanks to sunnyhaibin! * Hyundai Kona Electric 2022 support thanks to sunnyhaibin! +* Hyundai Tucson Hybrid 2022 support thanks to sunnyhaibin! * Subaru Legacy 2020-22 support thanks to martinl! * Subaru Outback 2020-22 support diff --git a/docs/CARS.md b/docs/CARS.md index b244b5c361d3e8..2a1f770b7e9bac 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -4,7 +4,7 @@ A supported vehicle is one that just works when you install a comma device. Every car performs differently with openpilot, but all supported cars should provide a better experience than any stock system. -# 203 Supported Cars +# 204 Supported Cars |Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Harness| |---|---|---|:---:|:---:|:---:|:---:|:---:| @@ -77,6 +77,7 @@ A supported vehicle is one that just works when you install a comma device. Ever |Hyundai|Sonata Hybrid 2020-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai A| |Hyundai|Tucson 2021|Smart Cruise Control (SCC)|Stock|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai L| |Hyundai|Tucson Diesel 2019|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai L| +|Hyundai|Tucson Hybrid 2022|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai N| |Hyundai|Veloster 2019-20|Smart Cruise Control (SCC)|Stock|5 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai E| |Jeep|Grand Cherokee 2016-18|Adaptive Cruise Control|Stock|0 mph|9 mph|[![star](assets/icon-star-full.svg)](##)|FCA| |Jeep|Grand Cherokee 2019-21|Adaptive Cruise Control|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|FCA| diff --git a/panda b/panda index abaa9f8968df13..9d6496ece8465d 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit abaa9f8968df13c8a858413cc9936269702c2d60 +Subproject commit 9d6496ece8465dfe30997b31dfb352e1e51dde6c diff --git a/selfdrive/car/docs.py b/selfdrive/car/docs.py index 795668381c3be6..4d79cbfc765b42 100755 --- a/selfdrive/car/docs.py +++ b/selfdrive/car/docs.py @@ -8,6 +8,7 @@ from typing import Dict, List from common.basedir import BASEDIR +from selfdrive.car import gen_empty_fingerprint from selfdrive.car.docs_definitions import CarInfo, Column from selfdrive.car.car_helpers import interfaces, get_interface_attr from selfdrive.car.hyundai.radar_interface import RADAR_START_ADDR as HKG_RADAR_START_ADDR @@ -29,7 +30,8 @@ def get_all_car_info() -> List[CarInfo]: footnotes = get_all_footnotes() for model, car_info in get_interface_attr("CAR_INFO", combine_brands=True).items(): # Hyundai exception: those with radar have openpilot longitudinal - fingerprint = {0: {}, 1: {HKG_RADAR_START_ADDR: 8}, 2: {}, 3: {}} + fingerprint = gen_empty_fingerprint() + fingerprint[1] = {HKG_RADAR_START_ADDR: 8} CP = interfaces[model][0].get_params(model, fingerprint=fingerprint, disable_radar=True) if CP.dashcamOnly or car_info is None: diff --git a/selfdrive/car/hyundai/carcontroller.py b/selfdrive/car/hyundai/carcontroller.py index 60fb46340de664..971330a33516ce 100644 --- a/selfdrive/car/hyundai/carcontroller.py +++ b/selfdrive/car/hyundai/carcontroller.py @@ -5,7 +5,7 @@ from opendbc.can.packer import CANPacker from selfdrive.car import apply_std_steer_torque_limits from selfdrive.car.hyundai import hyundaicanfd, hyundaican -from selfdrive.car.hyundai.values import Buttons, CarControllerParams, CANFD_CAR, CAR +from selfdrive.car.hyundai.values import HyundaiFlags, Buttons, CarControllerParams, CANFD_CAR, CAR VisualAlert = car.CarControl.HUDControl.VisualAlert LongCtrlState = car.CarControl.Actuators.LongControlState @@ -71,22 +71,33 @@ def update(self, CC, CS): if self.CP.carFingerprint in CANFD_CAR: # steering control - can_sends.append(hyundaicanfd.create_lkas(self.packer, CC.enabled, CC.latActive, apply_steer)) + can_sends.append(hyundaicanfd.create_lkas(self.packer, self.CP, CC.enabled, CC.latActive, apply_steer)) - if self.frame % 5 == 0: + # block LFA on HDA2 + if self.frame % 5 == 0 and (self.CP.flags & HyundaiFlags.CANFD_HDA2): can_sends.append(hyundaicanfd.create_cam_0x2a4(self.packer, CS.cam_0x2a4)) - # cruise cancel + # LFA and HDA icons + if self.frame % 2 == 0 and not (self.CP.flags & HyundaiFlags.CANFD_HDA2): + can_sends.append(hyundaicanfd.create_lfahda_cluster(self.packer, CC.enabled)) + + # button presses if (self.frame - self.last_button_frame) * DT_CTRL > 0.25: + # cruise cancel if CC.cruiseControl.cancel: - for _ in range(20): - can_sends.append(hyundaicanfd.create_buttons(self.packer, CS.buttons_counter+1, Buttons.CANCEL)) - self.last_button_frame = self.frame + if self.CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS: + can_sends.append(hyundaicanfd.create_cruise_info(self.packer, CS.cruise_info_copy, True)) + self.last_button_frame = self.frame + else: + for _ in range(20): + can_sends.append(hyundaicanfd.create_buttons(self.packer, CS.buttons_counter+1, Buttons.CANCEL)) + self.last_button_frame = self.frame # cruise standstill resume elif CC.cruiseControl.resume: - can_sends.append(hyundaicanfd.create_buttons(self.packer, CS.buttons_counter+1, Buttons.RES_ACCEL)) - self.last_button_frame = self.frame + if not (self.CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS): + can_sends.append(hyundaicanfd.create_buttons(self.packer, CS.buttons_counter+1, Buttons.RES_ACCEL)) + self.last_button_frame = self.frame else: # tester present - w/ no response (keeps radar disabled) diff --git a/selfdrive/car/hyundai/carstate.py b/selfdrive/car/hyundai/carstate.py index 08eccc3fe56421..eab6e73f1f429b 100644 --- a/selfdrive/car/hyundai/carstate.py +++ b/selfdrive/car/hyundai/carstate.py @@ -5,7 +5,7 @@ from common.conversions import Conversions as CV from opendbc.can.parser import CANParser from opendbc.can.can_define import CANDefine -from selfdrive.car.hyundai.values import DBC, FEATURES, CAMERA_SCC_CAR, CANFD_CAR, EV_CAR, HYBRID_CAR, Buttons, CarControllerParams +from selfdrive.car.hyundai.values import HyundaiFlags, DBC, FEATURES, CAMERA_SCC_CAR, CANFD_CAR, EV_CAR, HYBRID_CAR, Buttons, CarControllerParams from selfdrive.car.interfaces import CarStateBase PREV_BUTTON_SAMPLES = 8 @@ -136,8 +136,11 @@ def update(self, cp, cp_cam): def update_canfd(self, cp, cp_cam): ret = car.CarState.new_message() - ret.gas = cp.vl["ACCELERATOR"]["ACCELERATOR_PEDAL"] / 255. - ret.gasPressed = ret.gas > 1e-3 + if self.CP.flags & HyundaiFlags.CANFD_HDA2: + ret.gas = cp.vl["ACCELERATOR"]["ACCELERATOR_PEDAL"] / 255. + else: + ret.gas = cp.vl["ACCELERATOR_ALT"]["ACCELERATOR_PEDAL"] / 1023. + ret.gasPressed = ret.gas > 1e-5 ret.brakePressed = cp.vl["BRAKE"]["BRAKE_PRESSED"] == 1 ret.doorOpen = cp.vl["DOORS_SEATBELTS"]["DRIVER_DOOR_OPEN"] == 1 @@ -168,16 +171,19 @@ def update_canfd(self, cp, cp_cam): ret.cruiseState.available = True ret.cruiseState.enabled = cp.vl["SCC1"]["CRUISE_ACTIVE"] == 1 - ret.cruiseState.standstill = cp.vl["CRUISE_INFO"]["CRUISE_STANDSTILL"] == 1 - + cp_cruise_info = cp if self.CP.flags & HyundaiFlags.CANFD_HDA2 else cp_cam speed_factor = CV.MPH_TO_MS if cp.vl["CLUSTER_INFO"]["DISTANCE_UNIT"] == 1 else CV.KPH_TO_MS - ret.cruiseState.speed = cp.vl["CRUISE_INFO"]["SET_SPEED"] * speed_factor + ret.cruiseState.speed = cp_cruise_info.vl["CRUISE_INFO"]["SET_SPEED"] * speed_factor + ret.cruiseState.standstill = cp_cruise_info.vl["CRUISE_INFO"]["CRUISE_STANDSTILL"] == 1 - self.cruise_buttons.extend(cp.vl_all["CRUISE_BUTTONS"]["CRUISE_BUTTONS"]) - self.main_buttons.extend(cp.vl_all["CRUISE_BUTTONS"]["ADAPTIVE_CRUISE_MAIN_BTN"]) - self.buttons_counter = cp.vl["CRUISE_BUTTONS"]["COUNTER"] + cruise_btn_msg = "CRUISE_BUTTONS_ALT" if self.CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS else "CRUISE_BUTTONS" + self.cruise_buttons.extend(cp.vl_all[cruise_btn_msg]["CRUISE_BUTTONS"]) + self.main_buttons.extend(cp.vl_all[cruise_btn_msg]["ADAPTIVE_CRUISE_MAIN_BTN"]) + self.buttons_counter = cp.vl[cruise_btn_msg]["COUNTER"] + self.cruise_info_copy = copy.copy(cp_cruise_info.vl["CRUISE_INFO"]) - self.cam_0x2a4 = copy.copy(cp_cam.vl["CAM_0x2a4"]) + if self.CP.flags & HyundaiFlags.CANFD_HDA2: + self.cam_0x2a4 = copy.copy(cp_cam.vl["CAM_0x2a4"]) return ret @@ -319,9 +325,7 @@ def get_can_parser(CP): @staticmethod def get_cam_can_parser(CP): if CP.carFingerprint in CANFD_CAR: - signals = [(f"BYTE{i}", "CAM_0x2a4") for i in range(3, 24)] - checks = [("CAM_0x2a4", 20)] - return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, 6) + return CarState.get_cam_can_parser_canfd(CP) signals = [ # signal_name, signal_address @@ -374,13 +378,14 @@ def get_cam_can_parser(CP): @staticmethod def get_can_parser_canfd(CP): + + cruise_btn_msg = "CRUISE_BUTTONS_ALT" if CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS else "CRUISE_BUTTONS" signals = [ ("WHEEL_SPEED_1", "WHEEL_SPEEDS"), ("WHEEL_SPEED_2", "WHEEL_SPEEDS"), ("WHEEL_SPEED_3", "WHEEL_SPEEDS"), ("WHEEL_SPEED_4", "WHEEL_SPEEDS"), - ("ACCELERATOR_PEDAL", "ACCELERATOR"), ("GEAR", "GEAR_SHIFTER"), ("BRAKE_PRESSED", "BRAKE"), @@ -390,11 +395,9 @@ def get_can_parser_canfd(CP): ("STEERING_OUT_TORQUE", "MDPS"), ("CRUISE_ACTIVE", "SCC1"), - ("SET_SPEED", "CRUISE_INFO"), - ("CRUISE_STANDSTILL", "CRUISE_INFO"), - ("COUNTER", "CRUISE_BUTTONS"), - ("CRUISE_BUTTONS", "CRUISE_BUTTONS"), - ("ADAPTIVE_CRUISE_MAIN_BTN", "CRUISE_BUTTONS"), + ("COUNTER", cruise_btn_msg), + ("CRUISE_BUTTONS", cruise_btn_msg), + ("ADAPTIVE_CRUISE_MAIN_BTN", cruise_btn_msg), ("DISTANCE_UNIT", "CLUSTER_INFO"), @@ -407,17 +410,64 @@ def get_can_parser_canfd(CP): checks = [ ("WHEEL_SPEEDS", 100), - ("ACCELERATOR", 100), ("GEAR_SHIFTER", 100), ("BRAKE", 100), ("STEERING_SENSORS", 100), ("MDPS", 100), ("SCC1", 50), - ("CRUISE_INFO", 50), - ("CRUISE_BUTTONS", 50), + (cruise_btn_msg, 50), ("CLUSTER_INFO", 4), ("BLINKERS", 4), ("DOORS_SEATBELTS", 4), ] - return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, 5) + if CP.flags & HyundaiFlags.CANFD_HDA2: + signals += [ + ("ACCELERATOR_PEDAL", "ACCELERATOR"), + ("GEAR", "ACCELERATOR"), + ("SET_SPEED", "CRUISE_INFO"), + ("CRUISE_STANDSTILL", "CRUISE_INFO"), + ] + checks += [ + ("CRUISE_INFO", 50), + ("ACCELERATOR", 100), + ] + else: + signals += [ + ("ACCELERATOR_PEDAL", "ACCELERATOR_ALT"), + ] + checks += [ + ("ACCELERATOR_ALT", 100), + ] + + bus = 5 if CP.flags & HyundaiFlags.CANFD_HDA2 else 4 + return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, bus) + + @staticmethod + def get_cam_can_parser_canfd(CP): + if CP.flags & HyundaiFlags.CANFD_HDA2: + signals = [(f"BYTE{i}", "CAM_0x2a4") for i in range(3, 24)] + checks = [("CAM_0x2a4", 20)] + else: + signals = [ + ("COUNTER", "CRUISE_INFO"), + ("NEW_SIGNAL_1", "CRUISE_INFO"), + ("CRUISE_MAIN", "CRUISE_INFO"), + ("CRUISE_STATUS", "CRUISE_INFO"), + ("CRUISE_INACTIVE", "CRUISE_INFO"), + ("NEW_SIGNAL_2", "CRUISE_INFO"), + ("CRUISE_STANDSTILL", "CRUISE_INFO"), + ("NEW_SIGNAL_3", "CRUISE_INFO"), + ("BYTE11", "CRUISE_INFO"), + ("SET_SPEED", "CRUISE_INFO"), + ("NEW_SIGNAL_4", "CRUISE_INFO"), + ] + + signals += [(f"BYTE{i}", "CRUISE_INFO") for i in range(3, 7)] + signals += [(f"BYTE{i}", "CRUISE_INFO") for i in range(13, 31)] + + checks = [ + ("CRUISE_INFO", 50), + ] + + return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, 6) diff --git a/selfdrive/car/hyundai/hyundaicanfd.py b/selfdrive/car/hyundai/hyundaicanfd.py index 36207aa113280d..a53be7627db2d8 100644 --- a/selfdrive/car/hyundai/hyundaicanfd.py +++ b/selfdrive/car/hyundai/hyundaicanfd.py @@ -1,4 +1,7 @@ -def create_lkas(packer, enabled, lat_active, apply_steer): +from selfdrive.car.hyundai.values import HyundaiFlags + + +def create_lkas(packer, CP, enabled, lat_active, apply_steer): values = { "LKA_MODE": 2, "LKA_ICON": 2 if enabled else 1, @@ -10,7 +13,9 @@ def create_lkas(packer, enabled, lat_active, apply_steer): "NEW_SIGNAL_1": 0, "NEW_SIGNAL_2": 0, } - return packer.make_can_msg("LKAS", 4, values) + + msg = "LKAS" if CP.flags & HyundaiFlags.CANFD_HDA2 else "LFA" + return packer.make_can_msg(msg, 4, values) def create_cam_0x2a4(packer, camera_values): camera_values.update({ @@ -25,3 +30,17 @@ def create_buttons(packer, cnt, btn): "CRUISE_BUTTONS": btn, } return packer.make_can_msg("CRUISE_BUTTONS", 5, values) + +def create_cruise_info(packer, cruise_info_copy, cancel): + values = cruise_info_copy + if cancel: + values["CRUISE_STATUS"] = 0 + values["CRUISE_INACTIVE"] = 1 + return packer.make_can_msg("CRUISE_INFO", 4, values) + +def create_lfahda_cluster(packer, enabled): + values = { + "HDA_ICON": 1 if enabled else 0, + "LFA_ICON": 2 if enabled else 0, + } + return packer.make_can_msg("LFAHDA_CLUSTER", 4, values) diff --git a/selfdrive/car/hyundai/interface.py b/selfdrive/car/hyundai/interface.py index 23a49a05e57713..fbf2334980ef44 100644 --- a/selfdrive/car/hyundai/interface.py +++ b/selfdrive/car/hyundai/interface.py @@ -2,7 +2,7 @@ from cereal import car from panda import Panda from common.conversions import Conversions as CV -from selfdrive.car.hyundai.values import CAR, DBC, CANFD_CAR, CAMERA_SCC_CAR, EV_CAR, HYBRID_CAR, LEGACY_SAFETY_MODE_CAR, Buttons, CarControllerParams +from selfdrive.car.hyundai.values import HyundaiFlags, CAR, DBC, CANFD_CAR, CAMERA_SCC_CAR, EV_CAR, HYBRID_CAR, LEGACY_SAFETY_MODE_CAR, Buttons, CarControllerParams from selfdrive.car.hyundai.radar_interface import RADAR_START_ADDR from selfdrive.car import STD_CARGO_KG, create_button_event, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config from selfdrive.car.interfaces import CarInterfaceBase @@ -160,6 +160,12 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl tire_stiffness_factor = 0.385 ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.25], [0.05]] + elif candidate == CAR.TUCSON_HYBRID_4TH_GEN: + ret.mass = 1680. + STD_CARGO_KG # average of all 3 trims + ret.wheelbase = 2.756 + ret.steerRatio = 16. + tire_stiffness_factor = 0.385 + CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) # Kia elif candidate == CAR.KIA_SORENTO: @@ -284,7 +290,18 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl if candidate in CANFD_CAR: ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.noOutput), get_safety_config(car.CarParams.SafetyModel.hyundaiCanfd)] + + # detect HDA2 with LKAS message + if 0x50 in fingerprint[6]: + ret.flags |= HyundaiFlags.CANFD_HDA2.value + ret.safetyConfigs[1].safetyParam |= Panda.FLAG_HYUNDAI_CANFD_HDA2 + else: + # non-HDA2 + if 0x1cf not in fingerprint[4]: + ret.flags |= HyundaiFlags.CANFD_ALT_BUTTONS.value else: + ret.enableBsm = 0x58b in fingerprint[0] + 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)] @@ -314,8 +331,6 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront, tire_stiffness_factor=tire_stiffness_factor) - ret.enableBsm = 0x58b in fingerprint[0] - return ret @staticmethod diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index e36c9a6ac830b1..2861e4dc828b6f 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -1,3 +1,4 @@ +from enum import IntFlag from dataclasses import dataclass from typing import Dict, List, Optional, Union @@ -38,6 +39,11 @@ def __init__(self, CP): self.STEER_MAX = 384 +class HyundaiFlags(IntFlag): + CANFD_HDA2 = 1 + CANFD_ALT_BUTTONS = 2 + + class CAR: # Hyundai ELANTRA = "HYUNDAI ELANTRA 2017" @@ -66,6 +72,7 @@ class CAR: VELOSTER = "HYUNDAI VELOSTER 2019" SONATA_HYBRID = "HYUNDAI SONATA HYBRID 2021" IONIQ_5 = "HYUNDAI IONIQ 5 2022" + TUCSON_HYBRID_4TH_GEN = "HYUNDAI TUCSON HYBRID 4TH GEN" # Kia KIA_FORTE = "KIA FORTE E 2018 & GT 2021" @@ -128,6 +135,7 @@ class HyundaiCarInfo(CarInfo): CAR.VELOSTER: HyundaiCarInfo("Hyundai Veloster 2019-20", "Smart Cruise Control (SCC)", min_enable_speed=5. * CV.MPH_TO_MS, harness=Harness.hyundai_e), CAR.SONATA_HYBRID: HyundaiCarInfo("Hyundai Sonata Hybrid 2020-22", "All", harness=Harness.hyundai_a), CAR.IONIQ_5: HyundaiCarInfo("Hyundai Ioniq 5 2022", "Highway Driving Assist II", harness=Harness.hyundai_q), + CAR.TUCSON_HYBRID_4TH_GEN: HyundaiCarInfo("Hyundai Tucson Hybrid 2022", "All", harness=Harness.hyundai_n), # Kia CAR.KIA_FORTE: [ @@ -1292,6 +1300,21 @@ class Buttons: b'\xf1\x00NE1 MFC AT USA LHD 1.00 1.02 99211-GI010 211206', ], }, + CAR.TUCSON_HYBRID_4TH_GEN: { + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00NX4 FR_CMR AT USA LHD 1.00 1.00 99211-N9240 14Q', + ], + (Ecu.eps, 0x7d4, None): [ + b'\xf1\x00NX4 MDPS C 1.00 1.01 56300-P0100 2228', + ], + (Ecu.engine, 0x7e0, None): [ + b'\xf1\x87391312MND0', + ], + (Ecu.transmission, 0x7e1, None): [ + b'\xf1\x00PSBG2441 G19_Rev\x00\x00\x00SNX4T16XXHS01NS2lS\xdfa', + b'\xf1\x8795441-3D220\x00\xf1\x81G19_Rev\x00\x00\x00\xf1\x00PSBG2441 G19_Rev\x00\x00\x00SNX4T16XXHS01NS2lS\xdfa', + ], + }, } CHECKSUM = { @@ -1309,7 +1332,7 @@ class Buttons: "use_fca": {CAR.SONATA, CAR.SONATA_HYBRID, CAR.ELANTRA, CAR.ELANTRA_2021, CAR.ELANTRA_HEV_2021, CAR.ELANTRA_GT_I30, CAR.KIA_STINGER, CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.KONA_EV, CAR.KIA_FORTE, CAR.KIA_NIRO_EV, CAR.PALISADE, CAR.GENESIS_G70, CAR.GENESIS_G70_2020, CAR.KONA, CAR.SANTA_FE, CAR.KIA_SELTOS, CAR.KONA_HEV, CAR.SANTA_FE_2022, CAR.KIA_K5_2021, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022, CAR.TUCSON, CAR.KONA_EV_2022}, } -CANFD_CAR = {CAR.KIA_EV6, CAR.IONIQ_5} +CANFD_CAR = {CAR.KIA_EV6, CAR.IONIQ_5, CAR.TUCSON_HYBRID_4TH_GEN} # The camera does SCC on these cars, rather than the radar CAMERA_SCC_CAR = {CAR.KONA_EV_2022, } @@ -1364,5 +1387,6 @@ class Buttons: CAR.KIA_CEED: dbc_dict('hyundai_kia_generic', None), CAR.KIA_EV6: dbc_dict('hyundai_canfd', None), CAR.SONATA_HYBRID: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar'), + CAR.TUCSON_HYBRID_4TH_GEN: dbc_dict('hyundai_canfd', None), CAR.IONIQ_5: dbc_dict('hyundai_canfd', None), } diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py index 6cae48cd98d7bc..33467ffcf035b4 100644 --- a/selfdrive/car/tests/routes.py +++ b/selfdrive/car/tests/routes.py @@ -90,6 +90,7 @@ TestRoute("5b7c365c50084530|2020-04-15--16-13-24", HYUNDAI.SONATA), TestRoute("b2a38c712dcf90bd|2020-05-18--18-12-48", HYUNDAI.SONATA_LF), TestRoute("fb3fd42f0baaa2f8|2022-03-30--15-25-05", HYUNDAI.TUCSON), + TestRoute("36e10531feea61a4|2022-07-25--13-37-42", HYUNDAI.TUCSON_HYBRID_4TH_GEN), TestRoute("5875672fc1d4bf57|2020-07-23--21-33-28", HYUNDAI.KIA_SORENTO), TestRoute("9c917ba0d42ffe78|2020-04-17--12-43-19", HYUNDAI.PALISADE), TestRoute("22de8111a8c5463c|2022-07-29--13-34-49", HYUNDAI.IONIQ_5), diff --git a/selfdrive/car/torque_data/override.yaml b/selfdrive/car/torque_data/override.yaml index 5324108213852f..14ee7e223962f8 100644 --- a/selfdrive/car/torque_data/override.yaml +++ b/selfdrive/car/torque_data/override.yaml @@ -27,6 +27,7 @@ SUBARU OUTBACK 6TH GEN: [2.3, 2.3, 0.11] CHEVROLET BOLT EUV 2022: [2.0, 2.0, 0.05] CHEVROLET SILVERADO 1500 2020: [1.9, 1.9, 0.112] VOLKSWAGEN PASSAT NMS: [2.5, 2.5, 0.1] +HYUNDAI TUCSON HYBRID 4TH GEN: [2.5, 2.5, 0.0] # Dashcam or fallback configured as ideal car mock: [10.0, 10, 0.0] diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index b9e99cd61754bb..f77f244594f725 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -93a136f91739847afe1e1a4a1e98bc7c0adb5ec8 +656daeb9de3680258527500ecae4ddff323b2e59 \ No newline at end of file diff --git a/selfdrive/test/process_replay/test_processes.py b/selfdrive/test/process_replay/test_processes.py index 2a005cf4cc67d8..e8c2e1dc9494e6 100755 --- a/selfdrive/test/process_replay/test_processes.py +++ b/selfdrive/test/process_replay/test_processes.py @@ -18,7 +18,7 @@ original_segments = [ ("BODY", "937ccb7243511b65|2022-05-24--16-03-09--1"), # COMMA.BODY ("HYUNDAI", "02c45f73a2e5c6e9|2021-01-01--19-08-22--1"), # HYUNDAI.SONATA - ("HYUNDAI", "d824e27e8c60172c|2022-07-08--21-21-15--0"), # HYUNDAI.KIA_EV6 + ("HYUNDAI", "d824e27e8c60172c|2022-08-19--17-58-07--2"), # HYUNDAI.KIA_EV6 ("TOYOTA", "0982d79ebb0de295|2021-01-04--17-13-21--13"), # TOYOTA.PRIUS (INDI) ("TOYOTA2", "0982d79ebb0de295|2021-01-03--20-03-36--6"), # TOYOTA.RAV4 (LQR) ("TOYOTA3", "f7d7e3538cda1a2a|2021-08-16--08-55-34--6"), # TOYOTA.COROLLA_TSS2 @@ -40,7 +40,7 @@ segments = [ ("BODY", "regen660D86654BA|2022-07-06--14-27-15--0"), ("HYUNDAI", "regen114E5FF24D8|2022-07-14--17-08-47--0"), - ("HYUNDAI", "d824e27e8c60172c|2022-07-08--21-21-15--0"), + ("HYUNDAI", "d824e27e8c60172c|2022-08-19--17-58-07--2"), ("TOYOTA", "regenBA97410FBEC|2022-07-06--14-26-49--0"), ("TOYOTA2", "regenDEDB1D9C991|2022-07-06--14-54-08--0"), ("TOYOTA3", "regenDDC1FE60734|2022-07-06--14-32-06--0"), From ddb7f91c9ba7d3aee7fe5da020db9598dc07cf5c Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Fri, 19 Aug 2022 23:09:21 -0700 Subject: [PATCH 077/106] remove old boardd stuff --- selfdrive/boardd/tests/boardd_old.py | 245 ---------------------- selfdrive/boardd/tests/replay_many.py | 83 -------- selfdrive/boardd/tests/test_boardd_api.py | 77 ------- 3 files changed, 405 deletions(-) delete mode 100755 selfdrive/boardd/tests/boardd_old.py delete mode 100755 selfdrive/boardd/tests/replay_many.py delete mode 100644 selfdrive/boardd/tests/test_boardd_api.py diff --git a/selfdrive/boardd/tests/boardd_old.py b/selfdrive/boardd/tests/boardd_old.py deleted file mode 100755 index fad29f6f34ae37..00000000000000 --- a/selfdrive/boardd/tests/boardd_old.py +++ /dev/null @@ -1,245 +0,0 @@ -#!/usr/bin/env python3 -# pylint: skip-file - -# This file is not used by openpilot. Only boardd.cc is used. -# The python version is slower, but has more options for development. - -# TODO: merge the extra functionalities of this file (like MOCK) in boardd.c and -# delete this python version of boardd - -import os -import struct -import time - -import cereal.messaging as messaging -from common.realtime import Ratekeeper -from system.swaglog import cloudlog -from selfdrive.boardd.boardd import can_capnp_to_can_list -from cereal import car - -SafetyModel = car.CarParams.SafetyModel - -# USB is optional -try: - import usb1 - from usb1 import USBErrorIO, USBErrorOverflow # pylint: disable=no-name-in-module -except Exception: - pass - -# *** serialization functions *** -def can_list_to_can_capnp(can_msgs, msgtype='can'): - dat = messaging.new_message(msgtype, len(can_msgs)) - for i, can_msg in enumerate(can_msgs): - if msgtype == 'sendcan': - cc = dat.sendcan[i] - else: - cc = dat.can[i] - cc.address = can_msg[0] - cc.busTime = can_msg[1] - cc.dat = bytes(can_msg[2]) - cc.src = can_msg[3] - return dat - - -# *** can driver *** -def can_health(): - while 1: - try: - dat = handle.controlRead(usb1.TYPE_VENDOR | usb1.RECIPIENT_DEVICE, 0xd2, 0, 0, 0x16) - break - except (USBErrorIO, USBErrorOverflow): - cloudlog.exception("CAN: BAD HEALTH, RETRYING") - v, i = struct.unpack("II", dat[0:8]) - ign_line, ign_can = struct.unpack("BB", dat[20:22]) - return {"voltage": v, "current": i, "ignition_line": bool(ign_line), "ignition_can": bool(ign_can)} - -def __parse_can_buffer(dat): - ret = [] - for j in range(0, len(dat), 0x10): - ddat = dat[j:j+0x10] - f1, f2 = struct.unpack("II", ddat[0:8]) - ret.append((f1 >> 21, f2 >> 16, ddat[8:8 + (f2 & 0xF)], (f2 >> 4) & 0xFF)) - return ret - -def can_send_many(arr): - snds = [] - for addr, _, dat, alt in arr: - if addr < 0x800: # only support 11 bit addr - snd = struct.pack("II", ((addr << 21) | 1), len(dat) | (alt << 4)) + dat - snd = snd.ljust(0x10, b'\x00') - snds.append(snd) - while 1: - try: - handle.bulkWrite(3, b''.join(snds)) - break - except (USBErrorIO, USBErrorOverflow): - cloudlog.exception("CAN: BAD SEND MANY, RETRYING") - -def can_recv(): - dat = b"" - while 1: - try: - dat = handle.bulkRead(1, 0x10*256) - break - except (USBErrorIO, USBErrorOverflow): - cloudlog.exception("CAN: BAD RECV, RETRYING") - return __parse_can_buffer(dat) - -def can_init(): - global handle, context - handle = None - cloudlog.info("attempting can init") - - context = usb1.USBContext() - #context.setDebug(9) - - for device in context.getDeviceList(skip_on_error=True): - if device.getVendorID() == 0xbbaa and device.getProductID() == 0xddcc: - handle = device.open() - handle.claimInterface(0) - handle.controlWrite(0x40, 0xdc, SafetyModel.allOutput, 0, b'') - - if handle is None: - cloudlog.warning("CAN NOT FOUND") - exit(-1) - - cloudlog.info("got handle") - cloudlog.info("can init done") - -def boardd_mock_loop(): - can_init() - handle.controlWrite(0x40, 0xdc, SafetyModel.allOutput, 0, b'') - - logcan = messaging.sub_sock('can') - sendcan = messaging.pub_sock('sendcan') - - while 1: - tsc = messaging.drain_sock(logcan, wait_for_one=True) - snds = map(lambda x: can_capnp_to_can_list(x.can), tsc) - snd = [] - for s in snds: - snd += s - snd = list(filter(lambda x: x[-1] <= 2, snd)) - snd_0 = len(list(filter(lambda x: x[-1] == 0, snd))) - snd_1 = len(list(filter(lambda x: x[-1] == 1, snd))) - snd_2 = len(list(filter(lambda x: x[-1] == 2, snd))) - can_send_many(snd) - - # recv @ 100hz - can_msgs = can_recv() - got_0 = len(list(filter(lambda x: x[-1] == 0+0x80, can_msgs))) - got_1 = len(list(filter(lambda x: x[-1] == 1+0x80, can_msgs))) - got_2 = len(list(filter(lambda x: x[-1] == 2+0x80, can_msgs))) - print("sent %3d (%3d/%3d/%3d) got %3d (%3d/%3d/%3d)" % - (len(snd), snd_0, snd_1, snd_2, len(can_msgs), got_0, got_1, got_2)) - m = can_list_to_can_capnp(can_msgs, msgtype='sendcan') - sendcan.send(m.to_bytes()) - -def boardd_test_loop(): - can_init() - cnt = 0 - while 1: - can_send_many([[0xbb, 0, "\xaa\xaa\xaa\xaa", 0], [0xaa, 0, "\xaa\xaa\xaa\xaa"+struct.pack("!I", cnt), 1]]) - #can_send_many([[0xaa,0,"\xaa\xaa\xaa\xaa",0]]) - #can_send_many([[0xaa,0,"\xaa\xaa\xaa\xaa",1]]) - # recv @ 100hz - can_msgs = can_recv() - print("got %d" % (len(can_msgs))) - time.sleep(0.01) - cnt += 1 - -# *** main loop *** -def boardd_loop(rate=100): - rk = Ratekeeper(rate) - - can_init() - - # *** publishes can and health - logcan = messaging.pub_sock('can') - health_sock = messaging.pub_sock('pandaStates') - - # *** subscribes to can send - sendcan = messaging.sub_sock('sendcan') - - # drain sendcan to delete any stale messages from previous runs - messaging.drain_sock(sendcan) - - while 1: - # health packet @ 2hz - if (rk.frame % (rate // 2)) == 0: - health = can_health() - msg = messaging.new_message('pandaStates', 1) - - # store the health to be logged - msg.pandaState[0].voltage = health['voltage'] - msg.pandaState[0].current = health['current'] - msg.pandaState[0].ignitionLine = health['ignition_line'] - msg.pandaState[0].ignitionCan = health['ignition_can'] - msg.pandaState[0].controlsAllowed = True - - health_sock.send(msg.to_bytes()) - - # recv @ 100hz - can_msgs = can_recv() - - # publish to logger - # TODO: refactor for speed - if len(can_msgs) > 0: - dat = can_list_to_can_capnp(can_msgs).to_bytes() - logcan.send(dat) - - # send can if we have a packet - tsc = messaging.recv_sock(sendcan) - if tsc is not None: - can_send_many(can_capnp_to_can_list(tsc.sendcan)) - - rk.keep_time() - -# *** main loop *** -def boardd_proxy_loop(rate=100, address="192.168.2.251"): - rk = Ratekeeper(rate) - - can_init() - - # *** subscribes can - logcan = messaging.sub_sock('can', addr=address) - # *** publishes to can send - sendcan = messaging.pub_sock('sendcan') - - # drain sendcan to delete any stale messages from previous runs - messaging.drain_sock(sendcan) - - while 1: - # recv @ 100hz - can_msgs = can_recv() - #for m in can_msgs: - # print("R: {0} {1}".format(hex(m[0]), str(m[2]).encode("hex"))) - - # publish to logger - # TODO: refactor for speed - if len(can_msgs) > 0: - dat = can_list_to_can_capnp(can_msgs, "sendcan") - sendcan.send(dat) - - # send can if we have a packet - tsc = messaging.recv_sock(logcan) - if tsc is not None: - cl = can_capnp_to_can_list(tsc.can) - #for m in cl: - # print("S: {0} {1}".format(hex(m[0]), str(m[2]).encode("hex"))) - can_send_many(cl) - - rk.keep_time() - -def main(): - if os.getenv("MOCK") is not None: - boardd_mock_loop() - elif os.getenv("PROXY") is not None: - boardd_proxy_loop() - elif os.getenv("BOARDTEST") is not None: - boardd_test_loop() - else: - boardd_loop() - -if __name__ == "__main__": - main() diff --git a/selfdrive/boardd/tests/replay_many.py b/selfdrive/boardd/tests/replay_many.py deleted file mode 100755 index 78aef07497ad14..00000000000000 --- a/selfdrive/boardd/tests/replay_many.py +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env python3 -import os -import sys -import time -import signal -import traceback -import usb1 -from panda import Panda, PandaDFU -from multiprocessing import Pool - -jungle = "JUNGLE" in os.environ -if jungle: - from panda_jungle import PandaJungle # pylint: disable=import-error - -import cereal.messaging as messaging -from selfdrive.boardd.boardd import can_capnp_to_can_list - -def initializer(): - """Ignore CTRL+C in the worker process. - source: https://stackoverflow.com/a/44869451 """ - signal.signal(signal.SIGINT, signal.SIG_IGN) - -def send_thread(sender_serial): - while True: - try: - if jungle: - sender = PandaJungle(sender_serial) - else: - sender = Panda(sender_serial) - sender.set_safety_mode(Panda.SAFETY_ALLOUTPUT) - - sender.set_can_loopback(False) - can_sock = messaging.sub_sock('can') - - while True: - tsc = messaging.recv_one(can_sock) - snd = can_capnp_to_can_list(tsc.can) - snd = list(filter(lambda x: x[-1] <= 2, snd)) - - try: - sender.can_send_many(snd) - except usb1.USBErrorTimeout: - pass - - # Drain panda message buffer - sender.can_recv() - except Exception: - traceback.print_exc() - time.sleep(1) - -if __name__ == "__main__": - if jungle: - serials = PandaJungle.list() - else: - serials = Panda.list() - num_senders = len(serials) - - if num_senders == 0: - print("No senders found. Exiting") - sys.exit(1) - else: - print("%d senders found. Starting broadcast" % num_senders) - - if "FLASH" in os.environ: - for s in PandaDFU.list(): - PandaDFU(s).recover() - - time.sleep(1) - for s in serials: - Panda(s).recover() - Panda(s).flash() - - pool = Pool(num_senders, initializer=initializer) - pool.map_async(send_thread, serials) - - while True: - try: - time.sleep(10) - except KeyboardInterrupt: - pool.terminate() - pool.join() - raise - diff --git a/selfdrive/boardd/tests/test_boardd_api.py b/selfdrive/boardd/tests/test_boardd_api.py deleted file mode 100644 index f2bcd57a6bf27d..00000000000000 --- a/selfdrive/boardd/tests/test_boardd_api.py +++ /dev/null @@ -1,77 +0,0 @@ -import random -import numpy as np - -import selfdrive.boardd.tests.boardd_old as boardd_old -import selfdrive.boardd.boardd as boardd - -from common.realtime import sec_since_boot -from cereal import log -import unittest - - -def generate_random_can_data_list(): - can_list = [] - cnt = random.randint(1, 64) - for _ in range(cnt): - can_data = np.random.bytes(random.randint(1, 8)) - can_list.append([random.randint(0, 128), random.randint(0, 128), can_data, random.randint(0, 128)]) - return can_list, cnt - - -class TestBoarddApiMethods(unittest.TestCase): - def test_correctness(self): - for i in range(1000): - can_list, _ = generate_random_can_data_list() - - # Sendcan - # Old API - m_old = boardd_old.can_list_to_can_capnp(can_list, 'sendcan').to_bytes() - # new API - m = boardd.can_list_to_can_capnp(can_list, 'sendcan') - - ev_old = log.Event.from_bytes(m_old) - ev = log.Event.from_bytes(m) - - self.assertEqual(ev_old.which(), ev.which()) - self.assertEqual(len(ev.sendcan), len(ev_old.sendcan)) - for i in range(len(ev.sendcan)): - attrs = ['address', 'busTime', 'dat', 'src'] - for attr in attrs: - self.assertEqual(getattr(ev.sendcan[i], attr, 'new'), getattr(ev_old.sendcan[i], attr, 'old')) - - # Can - m_old = boardd_old.can_list_to_can_capnp(can_list, 'can').to_bytes() - # new API - m = boardd.can_list_to_can_capnp(can_list, 'can') - - ev_old = log.Event.from_bytes(m_old) - ev = log.Event.from_bytes(m) - self.assertEqual(ev_old.which(), ev.which()) - self.assertEqual(len(ev.can), len(ev_old.can)) - for i in range(len(ev.can)): - attrs = ['address', 'busTime', 'dat', 'src'] - for attr in attrs: - self.assertEqual(getattr(ev.can[i], attr, 'new'), getattr(ev_old.can[i], attr, 'old')) - - def test_performance(self): - can_list, _ = generate_random_can_data_list() - recursions = 1000 - - n1 = sec_since_boot() - for _ in range(recursions): - boardd_old.can_list_to_can_capnp(can_list, 'sendcan').to_bytes() - n2 = sec_since_boot() - elapsed_old = n2 - n1 - - # print('Old API, elapsed time: {} secs'.format(elapsed_old)) - n1 = sec_since_boot() - for _ in range(recursions): - boardd.can_list_to_can_capnp(can_list) - n2 = sec_since_boot() - elapsed_new = n2 - n1 - # print('New API, elapsed time: {} secs'.format(elapsed_new)) - self.assertTrue(elapsed_new < elapsed_old / 2) - - -if __name__ == '__main__': - unittest.main() From ebea805aa8e45d8a56c1935b5181aa5a1151684f Mon Sep 17 00:00:00 2001 From: Cameron Clough Date: Sat, 20 Aug 2022 07:29:09 +0100 Subject: [PATCH 078/106] Ford: add CADS radar interface (#24296) * Ford: use FORD_CADS radar dbc * Ford: CADS radar interface impl Co-authored-by: ReFil <31960031+ReFil@users.noreply.github.com> * fixup radar interface for FORD_CADS dbc * CADS treat different scan indexes as separate points * Ford: support both Fusion and CADS radars * Ford: rename radars to DELPHI_ESR and DELPHI_MRR Co-authored-by: ReFil <31960031+ReFil@users.noreply.github.com> --- release/files_common | 2 + selfdrive/car/ford/radar_interface.py | 114 +++++++++++++++++++++----- selfdrive/car/ford/values.py | 9 +- 3 files changed, 101 insertions(+), 24 deletions(-) diff --git a/release/files_common b/release/files_common index ac2a3ce6266dd2..663d6d35529551 100644 --- a/release/files_common +++ b/release/files_common @@ -513,6 +513,8 @@ opendbc/gm_global_a_powertrain_generated.dbc opendbc/gm_global_a_object.dbc opendbc/gm_global_a_chassis.dbc +opendbc/FORD_CADS.dbc +opendbc/ford_fusion_2018_adas.dbc opendbc/ford_lincoln_base_pt.dbc opendbc/honda_accord_2018_can_generated.dbc diff --git a/selfdrive/car/ford/radar_interface.py b/selfdrive/car/ford/radar_interface.py index 866602cf09888b..c942703002ff29 100644 --- a/selfdrive/car/ford/radar_interface.py +++ b/selfdrive/car/ford/radar_interface.py @@ -1,33 +1,63 @@ #!/usr/bin/env python3 +from math import cos, sin from cereal import car -from common.conversions import Conversions as CV from opendbc.can.parser import CANParser -from selfdrive.car.ford.values import CANBUS, DBC +from common.conversions import Conversions as CV +from selfdrive.car.ford.values import CANBUS, DBC, RADAR from selfdrive.car.interfaces import RadarInterfaceBase -RADAR_MSGS = list(range(0x500, 0x540)) +DELPHI_ESR_RADAR_MSGS = list(range(0x500, 0x540)) +DELPHI_MRR_RADAR_START_ADDR = 0x120 +DELPHI_MRR_RADAR_MSG_COUNT = 64 -def _create_radar_can_parser(car_fingerprint): - if DBC[car_fingerprint]['radar'] is None: - return None - msg_n = len(RADAR_MSGS) +def _create_delphi_esr_radar_can_parser(): + msg_n = len(DELPHI_ESR_RADAR_MSGS) signals = list(zip(['X_Rel'] * msg_n + ['Angle'] * msg_n + ['V_Rel'] * msg_n, - RADAR_MSGS * 3)) - checks = list(zip(RADAR_MSGS, [20] * msg_n)) + DELPHI_ESR_RADAR_MSGS * 3)) + checks = list(zip(DELPHI_ESR_RADAR_MSGS, [20] * msg_n)) + + return CANParser(RADAR.DELPHI_ESR, signals, checks, CANBUS.radar) + + +def _create_delphi_mrr_radar_can_parser(): + signals = [] + checks = [] + + for i in range(1, DELPHI_MRR_RADAR_MSG_COUNT + 1): + msg = f"MRR_Detection_{i:03d}" + signals += [ + (f"CAN_DET_VALID_LEVEL_{i:02d}", msg), + (f"CAN_DET_AZIMUTH_{i:02d}", msg), + (f"CAN_DET_RANGE_{i:02d}", msg), + (f"CAN_DET_RANGE_RATE_{i:02d}", msg), + (f"CAN_DET_AMPLITUDE_{i:02d}", msg), + (f"CAN_SCAN_INDEX_2LSB_{i:02d}", msg), + ] + checks += [(msg, 20)] + + return CANParser(RADAR.DELPHI_MRR, signals, checks, CANBUS.radar) - return CANParser(DBC[car_fingerprint]['radar'], signals, checks, CANBUS.radar) class RadarInterface(RadarInterfaceBase): def __init__(self, CP): super().__init__(CP) - self.validCnt = {key: 0 for key in RADAR_MSGS} - self.track_id = 0 - self.rcp = _create_radar_can_parser(CP.carFingerprint) - self.trigger_msg = 0x53f self.updated_messages = set() + self.track_id = 0 + self.radar = DBC[CP.carFingerprint]['radar'] + if self.radar is None: + self.rcp = None + elif self.radar == RADAR.DELPHI_ESR: + self.rcp = _create_delphi_esr_radar_can_parser() + self.trigger_msg = DELPHI_ESR_RADAR_MSGS[-1] + self.valid_cnt = {key: 0 for key in DELPHI_ESR_RADAR_MSGS} + elif self.radar == RADAR.DELPHI_MRR: + self.rcp = _create_delphi_mrr_radar_can_parser() + self.trigger_msg = DELPHI_MRR_RADAR_START_ADDR + DELPHI_MRR_RADAR_MSG_COUNT - 1 + else: + raise ValueError(f"Unsupported radar: {self.radar}") def update(self, can_strings): if self.rcp is None: @@ -45,20 +75,30 @@ def update(self, can_strings): errors.append("canError") ret.errors = errors + if self.radar == RADAR.DELPHI_ESR: + self._update_delphi_esr() + elif self.radar == RADAR.DELPHI_MRR: + self._update_delphi_mrr() + + ret.points = list(self.pts.values()) + self.updated_messages.clear() + return ret + + def _update_delphi_esr(self): for ii in sorted(self.updated_messages): cpt = self.rcp.vl[ii] if cpt['X_Rel'] > 0.00001: - self.validCnt[ii] = 0 # reset counter + self.valid_cnt[ii] = 0 # reset counter if cpt['X_Rel'] > 0.00001: - self.validCnt[ii] += 1 + self.valid_cnt[ii] += 1 else: - self.validCnt[ii] = max(self.validCnt[ii] - 1, 0) - #print ii, self.validCnt[ii], cpt['VALID'], cpt['X_Rel'], cpt['Angle'] + self.valid_cnt[ii] = max(self.valid_cnt[ii] - 1, 0) + #print ii, self.valid_cnt[ii], cpt['VALID'], cpt['X_Rel'], cpt['Angle'] # radar point only valid if there have been enough valid measurements - if self.validCnt[ii] > 0: + if self.valid_cnt[ii] > 0: if ii not in self.pts: self.pts[ii] = car.RadarData.RadarPoint.new_message() self.pts[ii].trackId = self.track_id @@ -73,6 +113,36 @@ def update(self, can_strings): if ii in self.pts: del self.pts[ii] - ret.points = list(self.pts.values()) - self.updated_messages.clear() - return ret + def _update_delphi_mrr(self): + for ii in range(1, DELPHI_MRR_RADAR_MSG_COUNT + 1): + msg = self.rcp.vl[f"MRR_Detection_{ii:03d}"] + + # SCAN_INDEX rotates through 0..3 on each message + # treat these as separate points + scanIndex = msg[f"CAN_SCAN_INDEX_2LSB_{ii:02d}"] + i = (ii - 1) * 4 + scanIndex + + if i not in self.pts: + self.pts[i] = car.RadarData.RadarPoint.new_message() + self.pts[i].trackId = self.track_id + self.pts[i].aRel = float('nan') + self.pts[i].yvRel = float('nan') + self.track_id += 1 + + valid = bool(msg[f"CAN_DET_VALID_LEVEL_{ii:02d}"]) + amplitude = msg[f"CAN_DET_AMPLITUDE_{ii:02d}"] # dBsm [-64|63] + + if valid and 0 < amplitude <= 15: + azimuth = msg[f"CAN_DET_AZIMUTH_{ii:02d}"] # rad [-3.1416|3.13964] + dist = msg[f"CAN_DET_RANGE_{ii:02d}"] # m [0|255.984] + distRate = msg[f"CAN_DET_RANGE_RATE_{ii:02d}"] # m/s [-128|127.984] + + # *** openpilot radar point *** + self.pts[i].dRel = cos(azimuth) * dist # m from front of car + self.pts[i].yRel = -sin(azimuth) * dist # in car frame's y axis, left is positive + self.pts[i].vRel = distRate # m/s + + self.pts[i].measured = True + + else: + del self.pts[i] diff --git a/selfdrive/car/ford/values.py b/selfdrive/car/ford/values.py index 6b8396cf072ae6..825d515da9cbd6 100644 --- a/selfdrive/car/ford/values.py +++ b/selfdrive/car/ford/values.py @@ -24,6 +24,11 @@ class CarControllerParams: STEER_RATE_LIMIT_DOWN = AngleRateLimit(speed_points=[0., 5., 15.], max_angle_diff_points=[5., 3.5, 0.4]) +class RADAR: + DELPHI_ESR = 'ford_fusion_2018_adas' + DELPHI_MRR = 'FORD_CADS' + + class CANBUS: main = 0 radar = 1 @@ -80,6 +85,6 @@ class CAR: DBC = { - CAR.ESCAPE_MK4: dbc_dict('ford_lincoln_base_pt', None), - CAR.FOCUS_MK4: dbc_dict('ford_lincoln_base_pt', None), + CAR.ESCAPE_MK4: dbc_dict('ford_lincoln_base_pt', RADAR.DELPHI_MRR), + CAR.FOCUS_MK4: dbc_dict('ford_lincoln_base_pt', RADAR.DELPHI_MRR), } From 992ee329e96c80795bab2be98f979c0ae39ee5a2 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Fri, 19 Aug 2022 23:41:47 -0700 Subject: [PATCH 079/106] 0.8.16 release notes --- RELEASES.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index 235e90a3d71d4f..169a7af4dd0606 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,8 +1,12 @@ -Version 0.8.16 (2022-XX-XX) +Version 0.8.16 (2022-08-26) ======================== * New driving model * Reduced turn cutting * Auto-detect right hand drive setting with driver monitoring model +* Improved fan controller for comma three +* New translations + * Japanese thanks to cydia2020! + * Brazilian Portuguese thanks to AlexandreSato! * Chevrolet Bolt EUV 2022-23 support thanks to JasonJShuler! * Chevrolet Silverado 2020-21 support thanks to JasonJShuler! * Hyundai Ioniq 5 2022 support thanks to sunnyhaibin! From beae985f989068b6105df1a4698403a3f2329503 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Sat, 20 Aug 2022 14:47:18 -0700 Subject: [PATCH 080/106] test_models: no CAN invalid tolerance (#25501) * don't use end of route segment * no can invalid cnt tolerance * start checking can valid immediately once available * we check counter violations --- selfdrive/car/tests/routes.py | 2 +- selfdrive/car/tests/test_models.py | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py index 33467ffcf035b4..532ab7119173ce 100644 --- a/selfdrive/car/tests/routes.py +++ b/selfdrive/car/tests/routes.py @@ -83,7 +83,7 @@ TestRoute("4dbd55df87507948|2022-03-01--09-45-38", HYUNDAI.SANTA_FE), TestRoute("bf43d9df2b660eb0|2021-09-23--14-16-37", HYUNDAI.SANTA_FE_2022), TestRoute("37398f32561a23ad|2021-11-18--00-11-35", HYUNDAI.SANTA_FE_HEV_2022), - TestRoute("656ac0d830792fcc|2021-12-28--14-45-56", HYUNDAI.SANTA_FE_PHEV_2022), + TestRoute("656ac0d830792fcc|2021-12-28--14-45-56", HYUNDAI.SANTA_FE_PHEV_2022, segment=1), TestRoute("e0e98335f3ebc58f|2021-03-07--16-38-29", HYUNDAI.KIA_CEED), TestRoute("7653b2bce7bcfdaa|2020-03-04--15-34-32", HYUNDAI.KIA_OPTIMA), TestRoute("c75a59efa0ecd502|2021-03-11--20-52-55", HYUNDAI.KIA_SELTOS), diff --git a/selfdrive/car/tests/test_models.py b/selfdrive/car/tests/test_models.py index 4a1f1a61ee46fa..fdf7bca3d2e3f8 100755 --- a/selfdrive/car/tests/test_models.py +++ b/selfdrive/car/tests/test_models.py @@ -138,19 +138,23 @@ def test_car_params(self): raise Exception("unkown tuning") def test_car_interface(self): - # TODO: also check for checkusm and counter violations from can parser + # TODO: also check for checksum violations from can parser can_invalid_cnt = 0 + can_valid = False CC = car.CarControl.new_message() for i, msg in enumerate(self.can_msgs): CS = self.CI.update(CC, (msg.as_builder().to_bytes(),)) self.CI.apply(CC) - # wait 2s for low frequency msgs to be seen - if i > 200: + if CS.canValid: + can_valid = True + + # wait max of 2s for low frequency msgs to be seen + if i > 200 or can_valid: can_invalid_cnt += not CS.canValid - self.assertLess(can_invalid_cnt, 50) + self.assertEqual(can_invalid_cnt, 0) def test_radar_interface(self): os.environ['NO_RADAR_SLEEP'] = "1" From f528e9618b0f345039d19c0007539686c433c877 Mon Sep 17 00:00:00 2001 From: Joseph Wagner <68037585+wjoseph0@users.noreply.github.com> Date: Sat, 20 Aug 2022 16:51:50 -0500 Subject: [PATCH 081/106] README.md: update grammar (#25488) * first paragraph * second section * second section pt2 * third section * fifth section * fifth section pt2 * sixth section * Apply suggestions from code review Co-authored-by: Adeeb Shihadeh --- README.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 94837575b456e9..0b6fc20105ba26 100755 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Table of Contents What is openpilot? ------ -[openpilot](http://github.com/commaai/openpilot) is an open source driver assistance system. Currently, openpilot performs the functions of Adaptive Cruise Control (ACC), Automated Lane Centering (ALC), Forward Collision Warning (FCW) and Lane Departure Warning (LDW) for a growing variety of [supported car makes, models and model years](docs/CARS.md). In addition, while openpilot is engaged, a camera based Driver Monitoring (DM) feature alerts distracted and asleep drivers. See more about [the vehicle integration](docs/INTEGRATION.md) and [limitations](docs/LIMITATIONS.md). +[openpilot](http://github.com/commaai/openpilot) is an open source driver assistance system. Currently, openpilot performs the functions of Adaptive Cruise Control (ACC), Automated Lane Centering (ALC), Forward Collision Warning (FCW), and Lane Departure Warning (LDW) for a growing variety of [supported car makes, models, and model years](docs/CARS.md). In addition, while openpilot is engaged, a camera-based Driver Monitoring (DM) feature alerts distracted and asleep drivers. See more about [the vehicle integration](docs/INTEGRATION.md) and [limitations](docs/LIMITATIONS.md). @@ -40,9 +40,9 @@ Running on a dedicated device in a car To use openpilot in a car, you need four things * A supported device to run this software: a [comma three](https://comma.ai/shop/products/three). -* This software. The setup procedure of the comma three allows the user to enter a url for custom software. -The url, openpilot.comma.ai will install the release version of openpilot. To install openpilot master, you can use installer.comma.ai/commaai/master, and replacing commaai with another github username can install a fork. -* One of [the 150+ supported cars](docs/CARS.md). We support Honda, Toyota, Hyundai, Nissan, Kia, Chrysler, Lexus, Acura, Audi, VW, and more. If your car is not supported, but has adaptive cruise control and lane keeping assist, it's likely able to run openpilot. +* This software. The setup procedure of the comma three allows the user to enter a URL for custom software. +The URL, openpilot.comma.ai will install the release version of openpilot. To install openpilot master, you can use installer.comma.ai/commaai/master, and replacing commaai with another GitHub username can install a fork. +* One of [the 150+ supported cars](docs/CARS.md). We support Honda, Toyota, Hyundai, Nissan, Kia, Chrysler, Lexus, Acura, Audi, VW, and more. If your car is not supported but has adaptive cruise control and lane-keeping assist, it's likely able to run openpilot. * A [car harness](https://comma.ai/shop/products/car-harness) to connect to your car. We have detailed instructions for [how to mount the device in a car](https://comma.ai/setup). @@ -52,11 +52,11 @@ Running on PC All of openpilot's services can run as normal on a PC, even without special hardware or a car. To develop or experiment with openpilot you can run openpilot on recorded or simulated data. -With openpilot's tools you can plot logs, replay drives and watch the full-res camera streams. See [the tools README](tools/README.md) for more information. +With openpilot's tools, you can plot logs, replay drives, and watch the full-res camera streams. See [the tools README](tools/README.md) for more information. -You can also run openpilot in simulation [with the CARLA simulator](tools/sim/README.md). This allows openpilot to drive around a virtual car on your Ubuntu machine. The whole setup should only take a few minutes, but does require a decent GPU. +You can also run openpilot in simulation [with the CARLA simulator](tools/sim/README.md). This allows openpilot to drive around a virtual car on your Ubuntu machine. The whole setup should only take a few minutes but does require a decent GPU. -A PC running openpilot can also control your vehicle if it is connected to a [a webcam](https://github.com/commaai/openpilot/tree/master/tools/webcam), a [black panda](https://comma.ai/shop/products/panda), and [a harness](https://comma.ai/shop/products/car-harness). +A PC running openpilot can also control your vehicle if it is connected to a [webcam](https://github.com/commaai/openpilot/tree/master/tools/webcam), a [black panda](https://comma.ai/shop/products/panda), and a [harness](https://comma.ai/shop/products/car-harness). Community and Contributing ------ @@ -78,8 +78,8 @@ By default, openpilot uploads the driving data to our servers. You can also acce openpilot is open source software: the user is free to disable data collection if they wish to do so. -openpilot logs the road facing cameras, CAN, GPS, IMU, magnetometer, thermal sensors, crashes, and operating system logs. -The driver facing camera is only logged if you explicitly opt-in in settings. The microphone is not recorded. +openpilot logs the road-facing cameras, CAN, GPS, IMU, magnetometer, thermal sensors, crashes, and operating system logs. +The driver-facing camera is only logged if you explicitly opt-in in settings. The microphone is not recorded. By using openpilot, you agree to [our Privacy Policy](https://comma.ai/privacy). You understand that use of this software or its related services will generate certain types of user data, which may be logged and stored at the sole discretion of comma. By accepting this agreement, you grant an irrevocable, perpetual, worldwide right to comma for the use of this data. @@ -87,11 +87,11 @@ Safety and Testing ---- * openpilot observes ISO26262 guidelines, see [SAFETY.md](docs/SAFETY.md) for more details. -* openpilot has software in the loop [tests](.github/workflows/selfdrive_tests.yaml) that run on every commit. +* openpilot has software-in-the-loop [tests](.github/workflows/selfdrive_tests.yaml) that run on every commit. * The code enforcing the safety model lives in panda and is written in C, see [code rigor](https://github.com/commaai/panda#code-rigor) for more details. -* panda has software in the loop [safety tests](https://github.com/commaai/panda/tree/master/tests/safety). -* Internally, we have a hardware in the loop Jenkins test suite that builds and unit tests the various processes. -* panda has additional hardware in the loop [tests](https://github.com/commaai/panda/blob/master/Jenkinsfile). +* panda has software-in-the-loop [safety tests](https://github.com/commaai/panda/tree/master/tests/safety). +* Internally, we have a hardware-in-the-loop Jenkins test suite that builds and unit tests the various processes. +* panda has additional hardware-in-the-loop [tests](https://github.com/commaai/panda/blob/master/Jenkinsfile). * We run the latest openpilot in a testing closet containing 10 comma devices continuously replaying routes. Directory Structure From f2f8e7b930ec9c8ca2d264076700933bee7fa7d0 Mon Sep 17 00:00:00 2001 From: Greg Hogan Date: Sat, 20 Aug 2022 23:13:19 -0700 Subject: [PATCH 082/106] setup: perform all pyenv setup in a single place (#23408) * consolidate pyenv setup * cleanup openpilot_env.sh * undo openpilot_env.sh changes * needed on mac * add that back Co-authored-by: Adeeb Shihadeh --- update_requirements.sh | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/update_requirements.sh b/update_requirements.sh index 94b14496f151a9..719a28c3599ead 100755 --- a/update_requirements.sh +++ b/update_requirements.sh @@ -4,11 +4,26 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" cd $DIR +RC_FILE="${HOME}/.$(basename ${SHELL})rc" +if [ "$(uname)" == "Darwin" ] && [ $SHELL == "/bin/bash" ]; then + RC_FILE="$HOME/.bash_profile" +fi + if ! command -v "pyenv" > /dev/null 2>&1; then echo "pyenv install ..." curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash - export PATH=$HOME/.pyenv/bin:$HOME/.pyenv/shims:$PATH + + echo -e "\n. ~/.pyenvrc" >> $RC_FILE + cat < "${HOME}/.pyenvrc" +if [ -z "\$PYENV_ROOT" ]; then + export PATH=\$HOME/.pyenv/bin:\$HOME/.pyenv/shims:\$PATH + export PYENV_ROOT="\$HOME/.pyenv" + eval "\$(pyenv init -)" + eval "\$(pyenv virtualenv-init -)" +fi +EOF fi +source $RC_FILE export MAKEFLAGS="-j$(nproc)" From ed70a9ab1de142dfc3a8afe89a5b3c32b592dda1 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Mon, 22 Aug 2022 05:03:44 +0800 Subject: [PATCH 083/106] v4l_encoder: free buf_out in destructor (#25044) --- selfdrive/loggerd/encoder/v4l_encoder.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/selfdrive/loggerd/encoder/v4l_encoder.cc b/selfdrive/loggerd/encoder/v4l_encoder.cc index b3bd692b1639bd..016e6c57063f73 100644 --- a/selfdrive/loggerd/encoder/v4l_encoder.cc +++ b/selfdrive/loggerd/encoder/v4l_encoder.cc @@ -303,4 +303,10 @@ V4LEncoder::~V4LEncoder() { checked_ioctl(fd, VIDIOC_STREAMOFF, &buf_type); request_buffers(fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 0); close(fd); + + for (int i = 0; i < BUF_OUT_COUNT; i++) { + if (buf_out[i].free() != 0) { + LOGE("Failed to free buffer"); + } + } } From 62bb70ef2987647e9a9bb93af21f5424c617bafe Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 21 Aug 2022 14:29:52 -0700 Subject: [PATCH 084/106] test onroad: update dmonitoringd cpu usage --- selfdrive/test/test_onroad.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/test/test_onroad.py b/selfdrive/test/test_onroad.py index 31651706c698a5..93598a1b066c4f 100755 --- a/selfdrive/test/test_onroad.py +++ b/selfdrive/test/test_onroad.py @@ -37,7 +37,7 @@ "selfdrive.thermald.thermald": 3.87, "selfdrive.locationd.calibrationd": 2.0, "./_soundd": 1.0, - "selfdrive.monitoring.dmonitoringd": 1.90, + "selfdrive.monitoring.dmonitoringd": 4.0, "./proclogd": 1.54, "system.logmessaged": 0.2, "./clocksd": 0.02, From 71e76c3d0fa819b8aa9d3580c96b52480febf3d4 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 21 Aug 2022 19:14:36 -0700 Subject: [PATCH 085/106] CI: Actions cleanup + speedup (#25514) * actions cache cleanup * release build cleanup * fetch dpeth --- .github/workflows/badges.yaml | 25 +-- .github/workflows/selfdrive_tests.yaml | 230 +++++-------------------- .github/workflows/setup/action.yaml | 45 +++++ .github/workflows/tools_tests.yaml | 40 ----- 4 files changed, 88 insertions(+), 252 deletions(-) create mode 100644 .github/workflows/setup/action.yaml diff --git a/.github/workflows/badges.yaml b/.github/workflows/badges.yaml index 223c7348631f8f..644745920c4c4f 100644 --- a/.github/workflows/badges.yaml +++ b/.github/workflows/badges.yaml @@ -7,12 +7,7 @@ on: env: BASE_IMAGE: openpilot-base DOCKER_REGISTRY: ghcr.io/commaai - - BUILD: | - docker pull $(grep -iohP '(?<=^from)\s+\S+' Dockerfile.openpilot_base) || true - docker pull $DOCKER_REGISTRY/$BASE_IMAGE:latest || true - docker build --cache-from $DOCKER_REGISTRY/$BASE_IMAGE:latest -t $DOCKER_REGISTRY/$BASE_IMAGE:latest -t $BASE_IMAGE:latest -f Dockerfile.openpilot_base . - RUN: docker run --shm-size 1G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v /tmp/scons_cache:/tmp/scons_cache -v /tmp/comma_download_cache:/tmp/comma_download_cache -v /tmp/openpilot_cache:/tmp/openpilot_cache $BASE_IMAGE /bin/sh -c + RUN: docker run --shm-size 1G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v /tmp/scons_cache:/tmp/scons_cache -v /tmp/comma_download_cache:/tmp/comma_download_cache -v /tmp/openpilot_cache:/tmp/openpilot_cache $DOCKER_REGISTRY/$BASE_IMAGE:latest /bin/sh -c jobs: badges: @@ -23,23 +18,7 @@ jobs: - uses: actions/checkout@v3 with: submodules: true - - - name: Cache scons - id: scons-cache - # TODO: Change the version to the released version when https://github.com/actions/cache/pull/489 (or 571) is merged. - uses: actions/cache@03e00da99d75a2204924908e1cca7902cafce66b - env: - CACHE_SKIP_SAVE: true - with: - path: /tmp/scons_cache - key: scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- - restore-keys: | - scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- - scons- - - - name: Build Docker image - run: eval "$BUILD" - + - uses: ./.github/workflows/setup - name: Push badges run: | ${{ env.RUN }} "scons -j$(nproc) && python selfdrive/ui/translations/create_badges.py" diff --git a/.github/workflows/selfdrive_tests.yaml b/.github/workflows/selfdrive_tests.yaml index 7397e30f832971..8529da8e89fb1f 100644 --- a/.github/workflows/selfdrive_tests.yaml +++ b/.github/workflows/selfdrive_tests.yaml @@ -17,7 +17,7 @@ env: docker pull $DOCKER_REGISTRY/$BASE_IMAGE:latest || true docker build --cache-from $DOCKER_REGISTRY/$BASE_IMAGE:latest -t $DOCKER_REGISTRY/$BASE_IMAGE:latest -t $BASE_IMAGE:latest -f Dockerfile.openpilot_base . - RUN: docker run --shm-size 1G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v /tmp/scons_cache:/tmp/scons_cache -v /tmp/comma_download_cache:/tmp/comma_download_cache -v /tmp/openpilot_cache:/tmp/openpilot_cache $BASE_IMAGE /bin/sh -c + RUN: docker run --shm-size 1G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e FILEREADER_CACHE=1 -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v /tmp/scons_cache:/tmp/scons_cache -v /tmp/comma_download_cache:/tmp/comma_download_cache -v /tmp/openpilot_cache:/tmp/openpilot_cache $BASE_IMAGE /bin/sh -c BUILD_CL: | docker pull $DOCKER_REGISTRY/$CL_BASE_IMAGE:latest || true @@ -27,11 +27,10 @@ env: UNIT_TEST: coverage run --append -m unittest discover jobs: - # TODO: once actions/cache supports read only mode, use the cache for all jobs build_release: name: build release runs-on: ubuntu-20.04 - timeout-minutes: 50 + timeout-minutes: 30 env: STRIPPED_DIR: /tmp/releasepilot steps: @@ -39,44 +38,29 @@ jobs: with: fetch-depth: 0 submodules: true - - name: Pull LFS - run: git lfs pull + - name: Build devel + run: TARGET_DIR=$STRIPPED_DIR release/build_devel.sh + - uses: ./.github/workflows/setup - name: Check submodules if: github.ref == 'refs/heads/master' && github.repository == 'commaai/openpilot' run: release/check-submodules.sh - - name: Cache scons - id: scons-cache - # TODO: Change the version to the released version when https://github.com/actions/cache/pull/489 (or 571) is merged. - uses: actions/cache@03e00da99d75a2204924908e1cca7902cafce66b - env: - CACHE_SKIP_SAVE: true - with: - path: /tmp/scons_cache - key: scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- - restore-keys: | - scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- - scons- - - name: Build devel + - name: Build openpilot and run checks + run: | + cd $STRIPPED_DIR + ${{ env.RUN }} "CI=1 python selfdrive/manager/build.py" + - name: Run tests run: | - TARGET_DIR=$STRIPPED_DIR release/build_devel.sh - cp Dockerfile.openpilot_base $STRIPPED_DIR + cd $STRIPPED_DIR + ${{ env.RUN }} "release/check-dirty.sh && \ + python -m unittest discover selfdrive/car" + - name: pre-commit + run: | + cd $GITHUB_WORKSPACE cp .pre-commit-config.yaml $STRIPPED_DIR cp .pylintrc $STRIPPED_DIR cp mypy.ini $STRIPPED_DIR - - name: Build Docker image - run: | - eval "$BUILD" - rm $STRIPPED_DIR/Dockerfile.openpilot_base - - name: Build openpilot and run checks - run: | - cd $STRIPPED_DIR - ${{ env.RUN }} "CI=1 python selfdrive/manager/build.py && \ - pre-commit run --all && \ - rm .pre-commit-config.yaml && \ - rm .pylintrc && \ - rm mypy.ini && \ - release/check-dirty.sh && \ - python -m unittest discover selfdrive/car" + cd $STRIPPED_DIR + ${{ env.RUN }} "pre-commit run --all" build_all: name: build all @@ -86,26 +70,14 @@ jobs: - uses: actions/checkout@v3 with: submodules: true - - name: Cache scons - id: scons-cache - # TODO: Change the version to the released version when https://github.com/actions/cache/pull/489 (or 571) is merged. - uses: actions/cache@03e00da99d75a2204924908e1cca7902cafce66b - env: - CACHE_SKIP_SAVE: ${{ github.ref != 'refs/heads/master' || github.repository != 'commaai/openpilot' }} + - uses: ./.github/workflows/setup with: - path: /tmp/scons_cache - key: scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}-${{ steps.date.outputs.time }} - restore-keys: | - scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- - scons- - - name: Build Docker image - run: eval "$BUILD" + save-cache: true - name: Build openpilot with all flags run: ${{ env.RUN }} "scons -j$(nproc) --extras --test && release/check-dirty.sh" - name: Cleanup scons cache run: | - ${{ env.RUN }} "scons -j$(nproc) --extras --test && \ - rm -rf /tmp/scons_cache/* && \ + ${{ env.RUN }} "rm -rf /tmp/scons_cache/* && \ scons -j$(nproc) --extras --test --cache-populate" #build_mac: @@ -175,21 +147,9 @@ jobs: - uses: actions/checkout@v3 with: submodules: true - - name: Cache scons - id: scons-cache - # TODO: Change the version to the released version when https://github.com/actions/cache/pull/489 (or 571) is merged. - uses: actions/cache@03e00da99d75a2204924908e1cca7902cafce66b - env: - CACHE_SKIP_SAVE: true - with: - path: /tmp/scons_cache - key: scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- - restore-keys: | - scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- - scons- + - uses: ./.github/workflows/setup - name: Build Docker image run: | - eval "$BUILD" docker pull $DOCKER_REGISTRY/$IMAGE_NAME:latest || true docker build --cache-from $DOCKER_REGISTRY/$IMAGE_NAME:latest -t $DOCKER_REGISTRY/$IMAGE_NAME:latest -f tools/webcam/Dockerfile . - name: Build openpilot @@ -244,30 +204,11 @@ jobs: - uses: actions/checkout@v3 with: submodules: true - - name: Cache dependencies - id: dependency-cache - uses: actions/cache@v2 - with: - path: /tmp/comma_download_cache - key: ${{ hashFiles('.github/workflows/selfdrive_tests.yaml', 'selfdrive/test/test_valgrind_replay.py') }} - - name: Cache scons - id: scons-cache - # TODO: Change the version to the released version when https://github.com/actions/cache/pull/489 (or 571) is merged. - uses: actions/cache@03e00da99d75a2204924908e1cca7902cafce66b - env: - CACHE_SKIP_SAVE: true - with: - path: /tmp/scons_cache - key: scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- - restore-keys: | - scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- - scons- - - name: Build Docker image - run: eval "$BUILD" + - uses: ./.github/workflows/setup - name: Run valgrind run: | ${{ env.RUN }} "scons -j$(nproc) && \ - FILEREADER_CACHE=1 python selfdrive/test/test_valgrind_replay.py" + python selfdrive/test/test_valgrind_replay.py" - name: Print logs if: always() run: cat selfdrive/test/valgrind_logs.txt @@ -277,28 +218,10 @@ jobs: runs-on: ubuntu-20.04 timeout-minutes: 50 steps: - - name: Get current date - id: date - run: echo "::set-output name=time::$(date +'%s')" - - name: Output timestamp - run: echo $TIMESTAMP - env: - TIMESTAMP: ${{ steps.date.outputs.time }} - uses: actions/checkout@v3 with: submodules: true - - name: Cache scons - id: scons-cache - # TODO: Change the version to the released version when https://github.com/actions/cache/pull/489 (or 571) is merged. - uses: actions/cache@03e00da99d75a2204924908e1cca7902cafce66b - env: - CACHE_SKIP_SAVE: ${{ github.ref != 'refs/heads/master' || github.repository != 'commaai/openpilot' }} - with: - path: /tmp/scons_cache - key: scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}-${{ steps.date.outputs.time }} - restore-keys: scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- - - name: Build Docker image - run: eval "$BUILD" + - uses: ./.github/workflows/setup - name: Run unit tests run: | ${{ env.RUN }} "export SKIP_LONG_TESTS=1 && \ @@ -339,30 +262,17 @@ jobs: - uses: actions/checkout@v3 with: submodules: true - - name: Cache dependencies + - uses: ./.github/workflows/setup + - name: Cache test routes id: dependency-cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: /tmp/comma_download_cache - key: ${{ hashFiles('.github/workflows/selfdrive_tests.yaml', 'selfdrive/test/process_replay/test_processes.py') }} - - name: Cache scons - id: scons-cache - # TODO: Change the version to the released version when https://github.com/actions/cache/pull/489 (or 571) is merged. - uses: actions/cache@03e00da99d75a2204924908e1cca7902cafce66b - env: - CACHE_SKIP_SAVE: true - with: - path: /tmp/scons_cache - key: scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- - restore-keys: | - scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- - scons- - - name: Build Docker image - run: eval "$BUILD" + key: proc-replay-${{ hashFiles('.github/workflows/selfdrive_tests.yaml', 'selfdrive/test/process_replay/ref_commit') }} - name: Run replay run: | ${{ env.RUN }} "scons -j$(nproc) && \ - FILEREADER_CACHE=1 CI=1 coverage run selfdrive/test/process_replay/test_processes.py -j$(nproc) && \ + CI=1 coverage run selfdrive/test/process_replay/test_processes.py -j$(nproc) && \ coverage xml" - name: Print diff if: always() @@ -389,35 +299,16 @@ jobs: - uses: actions/checkout@v3 with: submodules: true - - name: Pull LFS - run: git lfs pull - - name: Cache dependencies - id: dependency-cache - uses: actions/cache@v2 - with: - path: /tmp/comma_download_cache - key: ${{ hashFiles('.github/workflows/selfdrive_tests.yaml', 'selfdrive/test/process_replay/model_replay.py') }} - - name: Cache scons - id: scons-cache - # TODO: Change the version to the released version when https://github.com/actions/cache/pull/489 (or 571) is merged. - uses: actions/cache@03e00da99d75a2204924908e1cca7902cafce66b - env: - CACHE_SKIP_SAVE: true - with: - path: /tmp/scons_cache - key: scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- - restore-keys: | - scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- - scons- + - uses: ./.github/workflows/setup - name: Build Docker image - # Sim docker is needed to get the intel OPENCL drivers + # Sim docker is needed to get the OpenCL drivers run: eval "$BUILD_CL" - name: Run replay run: | ${{ env.RUN_CL }} "scons -j$(nproc) && \ - ONNXCPU=1 FILEREADER_CACHE=1 CI=1 coverage run \ - selfdrive/test/process_replay/model_replay.py -j$(nproc) && \ - coverage xml" + ONNXCPU=1 CI=1 coverage run \ + selfdrive/test/process_replay/model_replay.py -j$(nproc) && \ + coverage xml" test_longitudinal: name: longitudinal @@ -427,20 +318,7 @@ jobs: - uses: actions/checkout@v3 with: submodules: true - - name: Cache scons - id: scons-cache - # TODO: Change the version to the released version when https://github.com/actions/cache/pull/489 (or 571) is merged. - uses: actions/cache@03e00da99d75a2204924908e1cca7902cafce66b - env: - CACHE_SKIP_SAVE: true - with: - path: /tmp/scons_cache - key: scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- - restore-keys: | - scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- - scons- - - name: Build Docker image - run: eval "$BUILD" + - uses: ./.github/workflows/setup - name: Test longitudinal run: | ${{ env.RUN }} "mkdir -p selfdrive/test/out && \ @@ -469,30 +347,17 @@ jobs: - uses: actions/checkout@v3 with: submodules: true - - name: Cache dependencies + - uses: ./.github/workflows/setup + - name: Cache test routes id: dependency-cache - uses: actions/cache@v2 + uses: actions/cache@03e00da99d75a2204924908e1cca7902cafce66b with: path: /tmp/comma_download_cache key: car_models-${{ hashFiles('selfdrive/car/tests/test_models.py', 'selfdrive/car/tests/routes.py') }}-${{ matrix.job }} - - name: Cache scons - id: scons-cache - # TODO: Change the version to the released version when https://github.com/actions/cache/pull/489 (or 571) is merged. - uses: actions/cache@03e00da99d75a2204924908e1cca7902cafce66b - env: - CACHE_SKIP_SAVE: true - with: - path: /tmp/scons_cache - key: scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- - restore-keys: | - scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- - scons- - - name: Build Docker image - run: eval "$BUILD" - name: Test car models run: | ${{ env.RUN }} "scons -j$(nproc) --test && \ - FILEREADER_CACHE=1 coverage run -m pytest selfdrive/car/tests/test_models.py && \ + coverage run -m pytest selfdrive/car/tests/test_models.py && \ coverage xml && \ chmod -R 777 /tmp/comma_download_cache" env: @@ -530,20 +395,7 @@ jobs: with: submodules: true ref: ${{ github.event.pull_request.base.ref }} - - name: Cache scons - id: scons-cache - # TODO: Change the version to the released version when https://github.com/actions/cache/pull/489 (or 571) is merged. - uses: actions/cache@03e00da99d75a2204924908e1cca7902cafce66b - env: - CACHE_SKIP_SAVE: true - with: - path: /tmp/scons_cache - key: scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- - restore-keys: | - scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- - scons- - - name: Build Docker image - run: eval "$BUILD" + - uses: ./.github/workflows/setup - name: Get base car info run: | ${{ env.RUN }} "scons -j$(nproc) && python selfdrive/debug/dump_car_info.py --path /tmp/openpilot_cache/base_car_info" diff --git a/.github/workflows/setup/action.yaml b/.github/workflows/setup/action.yaml new file mode 100644 index 00000000000000..79ec9212354c26 --- /dev/null +++ b/.github/workflows/setup/action.yaml @@ -0,0 +1,45 @@ +name: 'openpilot env setup' + +env: + BASE_IMAGE: openpilot-base + DOCKER_REGISTRY: ghcr.io/commaai + BUILD: | + docker pull $(grep -iohP '(?<=^from)\s+\S+' Dockerfile.openpilot_base) || true + docker pull $DOCKER_REGISTRY/$BASE_IMAGE:latest || true + docker build --cache-from $DOCKER_REGISTRY/$BASE_IMAGE:latest -t $DOCKER_REGISTRY/$BASE_IMAGE:latest -t $BASE_IMAGE:latest -f Dockerfile.openpilot_base . + +inputs: + save-cache: + default: false + required: false + +runs: + using: "composite" + steps: + # do this after checkout to ensure our custom LFS config is used to pull from GitLab + - shell: bash + run: git lfs pull + + # build cache + - id: date + shell: bash + run: echo "::set-output name=date::$(git log -1 --pretty='format:%cd' --date=format:'%Y-%m-%d')" + - shell: bash + run: echo "${{ steps.date.outputs.date }}" + - shell: bash + run: echo "CACHE_SKIP_SAVE=true" >> $GITHUB_ENV + if: github.ref != 'refs/heads/master' || inputs.save-cache == 'false' + - id: scons-cache + # TODO: change the version to the released version + # when https://github.com/actions/cache/pull/489 (or 571) is merged. + uses: actions/cache@03e00da99d75a2204924908e1cca7902cafce66b + with: + path: /tmp/scons_cache + key: scons-${{ steps.date.outputs.date }}-${{ github.sha }} + restore-keys: | + scons-${{ steps.date.outputs.date }}- + scons- + + # build our docker image + - shell: bash + run: eval "$BUILD" diff --git a/.github/workflows/tools_tests.yaml b/.github/workflows/tools_tests.yaml index e93ce2bb39a146..173e2083847264 100644 --- a/.github/workflows/tools_tests.yaml +++ b/.github/workflows/tools_tests.yaml @@ -21,46 +21,6 @@ env: GITHUB_REPOSITORY -e GITHUB_RUN_ID -v /tmp/comma_download_cache:/tmp/comma_download_cache $BASE_IMAGE /bin/sh -c jobs: - build_latest_ubuntu: - name: build latest ubuntu - runs-on: ubuntu-20.04 - timeout-minutes: 60 - steps: - - uses: actions/checkout@v3 - with: - submodules: true - - name: Cache pyenv - id: ubuntu-latest-pyenv - uses: actions/cache@v3 - with: - path: | - ~/.pyenv - ~/.local/share/virtualenvs/ - key: ubuntu-latest-python-${{ hashFiles('tools/ubuntu_setup.sh') }}- - - name: Cache scons - id: ubuntu-latest-scons - uses: actions/cache@v3 - with: - path: /tmp/scons_cache - key: ubuntu-latest-scons-${{ hashFiles('.github/workflows/tools_test.yaml') }}- - restore-keys: | - ubuntu-latest-scons-${{ hashFiles('.github/workflows/tools_test.yaml') }}- - ubuntu-latest-scons- - - - name: tools/ubuntu_setup.sh - run: | - source tools/openpilot_env.sh - tools/ubuntu_setup.sh - - name: Build openpilot - run: | - source tools/openpilot_env.sh - pipenv run scons -j$(nproc) --extras --test - - name: Cleanup scons cache - run: | - source tools/openpilot_env.sh - rm -rf /tmp/scons_cache/* - pipenv run scons -j$(nproc) --extras --test --cache-populate - plotjuggler: name: plotjuggler runs-on: ubuntu-20.04 From f65547fbe25501c1f6a1f7d0397a266dffa0e0ff Mon Sep 17 00:00:00 2001 From: Cameron Clough Date: Mon, 22 Aug 2022 16:23:36 -0700 Subject: [PATCH 086/106] sim: fix gps message (#25521) fix gps timestamp field renamed bug introduced in https://github.com/commaai/cereal/pull/341 --- tools/sim/bridge.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/sim/bridge.py b/tools/sim/bridge.py index fa4ce2b41d9742..f008b9e716cde9 100755 --- a/tools/sim/bridge.py +++ b/tools/sim/bridge.py @@ -179,7 +179,7 @@ def gps_callback(gps, vehicle_state): ] dat.gpsLocationExternal = { - "timestamp": int(time.time() * 1000), + "unixTimestampMillis": int(time.time() * 1000), "flags": 1, # valid fix "accuracy": 1.0, "verticalAccuracy": 1.0, From 68ba8df69329024e57efdbd00740acc0d298f214 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 22 Aug 2022 17:35:04 -0700 Subject: [PATCH 087/106] GMC: Sierra 2020-21 support (#25523) * Add Sierra * actually this package works * add to releases * credit --- RELEASES.md | 1 + docs/CARS.md | 3 ++- selfdrive/car/gm/values.py | 5 ++++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index 169a7af4dd0606..4b33ea8dc48b74 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -9,6 +9,7 @@ Version 0.8.16 (2022-08-26) * Brazilian Portuguese thanks to AlexandreSato! * Chevrolet Bolt EUV 2022-23 support thanks to JasonJShuler! * Chevrolet Silverado 2020-21 support thanks to JasonJShuler! +* GMC Sierra 1500 2020-21 support thanks to JasonJShuler! * Hyundai Ioniq 5 2022 support thanks to sunnyhaibin! * Hyundai Kona Electric 2022 support thanks to sunnyhaibin! * Hyundai Tucson Hybrid 2022 support thanks to sunnyhaibin! diff --git a/docs/CARS.md b/docs/CARS.md index 2a1f770b7e9bac..24be43e4f73664 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -4,7 +4,7 @@ A supported vehicle is one that just works when you install a comma device. Every car performs differently with openpilot, but all supported cars should provide a better experience than any stock system. -# 204 Supported Cars +# 205 Supported Cars |Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Harness| |---|---|---|:---:|:---:|:---:|:---:|:---:| @@ -32,6 +32,7 @@ A supported vehicle is one that just works when you install a comma device. Ever |Genesis|G80 2017-19|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai H| |Genesis|G90 2017-18|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|Hyundai C| |GMC|Acadia 2018[1](#footnotes)|Adaptive Cruise Control|openpilot|0 mph|7 mph|[![star](assets/icon-star-full.svg)](##)|OBD-II| +|GMC|Sierra 1500 2020-21|Driver Alert Package II|Stock|0 mph|7 mph|[![star](assets/icon-star-full.svg)](##)|GM| |Honda|Accord 2018-22|All|Stock|0 mph|3 mph|[![star](assets/icon-star-empty.svg)](##)|Honda Bosch A| |Honda|Accord Hybrid 2018-22|All|Stock|0 mph|3 mph|[![star](assets/icon-star-empty.svg)](##)|Honda Bosch A| |Honda|Civic 2016-18|Honda Sensing|openpilot|0 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|Honda Nidec| diff --git a/selfdrive/car/gm/values.py b/selfdrive/car/gm/values.py index df91938d8f0fbd..14022d23d53118 100644 --- a/selfdrive/car/gm/values.py +++ b/selfdrive/car/gm/values.py @@ -85,7 +85,10 @@ class GMCarInfo(CarInfo): CAR.BUICK_REGAL: GMCarInfo("Buick Regal Essence 2018"), CAR.ESCALADE_ESV: GMCarInfo("Cadillac Escalade ESV 2016", "Adaptive Cruise Control (ACC) & LKAS"), CAR.BOLT_EUV: GMCarInfo("Chevrolet Bolt EUV 2022-23", "Premier or Premier Redline Trim without Super Cruise Package", video_link="https://youtu.be/xvwzGMUA210", footnotes=[], harness=Harness.gm), - CAR.SILVERADO: GMCarInfo("Chevrolet Silverado 1500 2020-21", "Safety Package II", footnotes=[], harness=Harness.gm), + CAR.SILVERADO: [ + GMCarInfo("Chevrolet Silverado 1500 2020-21", "Safety Package II", footnotes=[], harness=Harness.gm), + GMCarInfo("GMC Sierra 1500 2020-21", "Driver Alert Package II", footnotes=[], harness=Harness.gm), + ], } From 0822f94bb4545bb9427d1525b157edbf46416fe7 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 22 Aug 2022 17:45:41 -0700 Subject: [PATCH 088/106] GM: add Silverado 2021 High Country FP (#25499) * Add FP from 61c6258cac78af08 * add to dict --- selfdrive/car/gm/values.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/car/gm/values.py b/selfdrive/car/gm/values.py index 14022d23d53118..21ede171e04202 100644 --- a/selfdrive/car/gm/values.py +++ b/selfdrive/car/gm/values.py @@ -164,7 +164,7 @@ class CanBus: }], CAR.SILVERADO: [ { - 190: 6, 193: 8, 197: 8, 201: 8, 208: 8, 209: 7, 211: 2, 241: 6, 249: 8, 257: 8, 288: 5, 289: 8, 298: 8, 304: 3, 309: 8, 311: 8, 313: 8, 320: 4, 322: 7, 328: 1, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 413: 8, 451: 8, 452: 8, 453: 6, 455: 7, 460: 5, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 500: 6, 501: 8, 528: 5, 532: 6, 560: 8, 562: 8, 563: 5, 565: 5, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 715: 8, 717: 5, 761: 7, 789: 5, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 848: 4, 869: 4, 880: 6, 977: 8, 1001: 8, 1011: 6, 1017: 8, 1020: 8, 1033: 7, 1034: 7, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1271: 8, 1280: 4, 1296: 4, 1300: 8, 1930: 7 + 190: 6, 193: 8, 197: 8, 201: 8, 208: 8, 209: 7, 211: 2, 241: 6, 249: 8, 257: 8, 288: 5, 289: 8, 298: 8, 304: 3, 309: 8, 311: 8, 313: 8, 320: 4, 322: 7, 328: 1, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 413: 8, 451: 8, 452: 8, 453: 6, 455: 7, 460: 5, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 500: 6, 501: 8, 528: 5, 532: 6, 534: 2, 560: 8, 562: 8, 563: 5, 565: 5, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 715: 8, 717: 5, 761: 7, 789: 5, 800: 6, 801: 8, 810: 8, 840: 5, 842: 5, 844: 8, 848: 4, 869: 4, 880: 6, 977: 8, 1001: 8, 1011: 6, 1017: 8, 1020: 8, 1033: 7, 1034: 7, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1271: 8, 1280: 4, 1296: 4, 1300: 8, 1930: 7 }], } From e84f397a72e7a7e76ea6c81ae9b627b41dd45e17 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 22 Aug 2022 19:15:32 -0700 Subject: [PATCH 089/106] Update Silverado release note (#25526) --- RELEASES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index 4b33ea8dc48b74..a6ba4558e7060f 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -8,7 +8,7 @@ Version 0.8.16 (2022-08-26) * Japanese thanks to cydia2020! * Brazilian Portuguese thanks to AlexandreSato! * Chevrolet Bolt EUV 2022-23 support thanks to JasonJShuler! -* Chevrolet Silverado 2020-21 support thanks to JasonJShuler! +* Chevrolet Silverado 1500 2020-21 support thanks to JasonJShuler! * GMC Sierra 1500 2020-21 support thanks to JasonJShuler! * Hyundai Ioniq 5 2022 support thanks to sunnyhaibin! * Hyundai Kona Electric 2022 support thanks to sunnyhaibin! From ad8d3de0d9abedc7c9db177b6c4a6b1a0fb03020 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 22 Aug 2022 20:39:54 -0700 Subject: [PATCH 090/106] Translations badges: concatenate into one badge (#25522) * add badge done correctly works Update translation_badge.svg Update translation_badge.svg Update translation_badge.svg Update README.md Update translation_badge.svg Update translation_badge.svg Update translation_badge.svg Update badge Update README.md test this try this finalize remove badges fixup readme add to test fix fix rm * clean up * no formats --- selfdrive/ui/translations/README.md | 7 +------ selfdrive/ui/translations/create_badges.py | 23 ++++++++++++++-------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/selfdrive/ui/translations/README.md b/selfdrive/ui/translations/README.md index 5d469861482bb3..ac3112c61af3fb 100644 --- a/selfdrive/ui/translations/README.md +++ b/selfdrive/ui/translations/README.md @@ -1,11 +1,6 @@ # Multilanguage -[![language](https://raw.githubusercontent.com/commaai/openpilot/badges/translation_badge_main_en.svg)](https://github.com/commaai/openpilot/blob/master/selfdrive/ui/translations/main_en.ts) -[![language](https://raw.githubusercontent.com/commaai/openpilot/badges/translation_badge_main_pt.svg)](https://github.com/commaai/openpilot/blob/master/selfdrive/ui/translations/main_pt.ts) -[![language](https://raw.githubusercontent.com/commaai/openpilot/badges/translation_badge_main_zh-CHT.svg)](https://github.com/commaai/openpilot/blob/master/selfdrive/ui/translations/main_zh-CHT.ts) -[![language](https://raw.githubusercontent.com/commaai/openpilot/badges/translation_badge_main_zh-CHS.svg)](https://github.com/commaai/openpilot/blob/master/selfdrive/ui/translations/main_zh-CHS.ts) -[![language](https://raw.githubusercontent.com/commaai/openpilot/badges/translation_badge_main_ko.svg)](https://github.com/commaai/openpilot/blob/master/selfdrive/ui/translations/main_ko.ts) -[![language](https://raw.githubusercontent.com/commaai/openpilot/badges/translation_badge_main_ja.svg)](https://github.com/commaai/openpilot/blob/master/selfdrive/ui/translations/main_ja.ts) +[![languages](https://raw.githubusercontent.com/commaai/openpilot/badges/translation_badge.svg)](#) ## Contributing diff --git a/selfdrive/ui/translations/create_badges.py b/selfdrive/ui/translations/create_badges.py index d9e2d443b969d4..451fbb23eb12b3 100755 --- a/selfdrive/ui/translations/create_badges.py +++ b/selfdrive/ui/translations/create_badges.py @@ -8,20 +8,17 @@ TRANSLATION_TAG = "'] + for idx, (name, file) in enumerate(translation_files.items()): with open(os.path.join(TRANSLATIONS_DIR, f"{file}.ts"), "r") as tr_f: tr_file = tr_f.read() - print(f"[![language](https://raw.githubusercontent.com/commaai/openpilot/badges/{TRANSLATION_BADGE.format(file)})]({TRANSLATION_LINK.format(file)}.ts)") - total_translations = 0 unfinished_translations = 0 for line in tr_file.splitlines(): @@ -35,6 +32,16 @@ r = requests.get(f"https://img.shields.io/badge/LANGUAGE {name}-{percent_finished}%25 complete-{color}") assert r.status_code == 200, "Error downloading badge" + content_svg = r.content.decode("utf-8") + + # make tag ids in each badge unique + for tag in ("r", "s"): + content_svg = content_svg.replace(f'id="{tag}"', f'id="{tag}{idx}"') + content_svg = content_svg.replace(f'"url(#{tag})"', f'"url(#{tag}{idx})"') + + badge_svg.extend([f'', content_svg, ""]) + + badge_svg.append("") - with open(os.path.join(BASEDIR, TRANSLATION_BADGE.format(file)), "wb") as badge_f: - badge_f.write(r.content) + with open(os.path.join(BASEDIR, "translation_badge.svg"), "w") as badge_f: + badge_f.write("\n".join(badge_svg)) From 10e414f9905d7d5ff9441b598d2a0285a618775b Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 22 Aug 2022 20:54:02 -0700 Subject: [PATCH 091/106] Fix badge workflow --- .github/workflows/badges.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/badges.yaml b/.github/workflows/badges.yaml index 644745920c4c4f..16edb45c21cf6b 100644 --- a/.github/workflows/badges.yaml +++ b/.github/workflows/badges.yaml @@ -28,6 +28,6 @@ jobs: git config user.email "badge-researcher@comma.ai" git config user.name "Badge Researcher" - git add translation_badge_*.svg + git add translation_badge.svg git commit -m "Add/Update badges" git push -f origin HEAD From b3cfe962cf346e70cce1389fe3c9bf23344a5512 Mon Sep 17 00:00:00 2001 From: Cameron Clough Date: Mon, 22 Aug 2022 21:47:09 -0700 Subject: [PATCH 092/106] user event flagging (#25517) * setup home_btn in sidebar * create UserFlag msg * replay: show and skip to user flags * update translations * bump to cereal master * remove comment Co-authored-by: Adeeb Shihadeh --- cereal | 2 +- selfdrive/ui/qt/sidebar.cc | 11 ++++++-- selfdrive/ui/qt/sidebar.h | 4 +++ selfdrive/ui/translations/main_ja.ts | 34 ++++++++++++------------ selfdrive/ui/translations/main_ko.ts | 34 ++++++++++++------------ selfdrive/ui/translations/main_pt.ts | 34 ++++++++++++------------ selfdrive/ui/translations/main_zh-CHS.ts | 34 ++++++++++++------------ selfdrive/ui/translations/main_zh-CHT.ts | 34 ++++++++++++------------ tools/replay/consoleui.cc | 8 ++++++ tools/replay/replay.cc | 9 ++++++- tools/replay/replay.h | 5 ++-- 11 files changed, 118 insertions(+), 91 deletions(-) diff --git a/cereal b/cereal index ecff0a284a2aa9..589ef049a7b0ba 160000 --- a/cereal +++ b/cereal @@ -1 +1 @@ -Subproject commit ecff0a284a2aa9879c4d04ea797356e4ef024dc4 +Subproject commit 589ef049a7b0bac31f4c8987c0fc539839fae489 diff --git a/selfdrive/ui/qt/sidebar.cc b/selfdrive/ui/qt/sidebar.cc index accab67bf071eb..a84542d29107b6 100644 --- a/selfdrive/ui/qt/sidebar.cc +++ b/selfdrive/ui/qt/sidebar.cc @@ -33,7 +33,7 @@ void Sidebar::drawMetric(QPainter &p, const QPair &label, QCol } Sidebar::Sidebar(QWidget *parent) : QFrame(parent) { - home_img = loadPixmap("../assets/images/button_home.png", {180, 180}); + home_img = loadPixmap("../assets/images/button_home.png", home_btn.size()); settings_img = loadPixmap("../assets/images/button_settings.png", settings_btn.size(), Qt::IgnoreAspectRatio); connect(this, &Sidebar::valueChanged, [=] { update(); }); @@ -43,9 +43,16 @@ Sidebar::Sidebar(QWidget *parent) : QFrame(parent) { setFixedWidth(300); QObject::connect(uiState(), &UIState::uiUpdate, this, &Sidebar::updateState); + + pm = std::make_unique>({"userFlag"}); } void Sidebar::mouseReleaseEvent(QMouseEvent *event) { + if (home_btn.contains(event->pos())) { + MessageBuilder msg; + msg.initEvent().initUserFlag(); + pm->send("userFlag", msg); + } if (settings_btn.contains(event->pos())) { emit openSettings(); } @@ -99,7 +106,7 @@ void Sidebar::paintEvent(QPaintEvent *event) { p.setOpacity(0.65); p.drawPixmap(settings_btn.x(), settings_btn.y(), settings_img); p.setOpacity(1.0); - p.drawPixmap(60, 1080 - 180 - 40, home_img); + p.drawPixmap(home_btn.x(), home_btn.y(), home_img); // network int x = 58; diff --git a/selfdrive/ui/qt/sidebar.h b/selfdrive/ui/qt/sidebar.h index 4c6d8f47e5bc35..0140673aac3fb1 100644 --- a/selfdrive/ui/qt/sidebar.h +++ b/selfdrive/ui/qt/sidebar.h @@ -43,6 +43,7 @@ public slots: {cereal::DeviceState::NetworkType::CELL5_G, tr("5G")} }; + const QRect home_btn = QRect(60, 860, 180, 180); const QRect settings_btn = QRect(50, 35, 200, 117); const QColor good_color = QColor(255, 255, 255); const QColor warning_color = QColor(218, 202, 37); @@ -52,4 +53,7 @@ public slots: ItemStatus connect_status, panda_status, temp_status; QString net_type; int net_strength = 0; + +private: + std::unique_ptr pm; }; diff --git a/selfdrive/ui/translations/main_ja.ts b/selfdrive/ui/translations/main_ja.ts index b66bc4b80d6660..79c982f81894e5 100644 --- a/selfdrive/ui/translations/main_ja.ts +++ b/selfdrive/ui/translations/main_ja.ts @@ -876,71 +876,71 @@ location set Sidebar - - + + CONNECT 接続 - + OFFLINE オフライン - - + + ONLINE オンライン - + ERROR エラー - - - + + + TEMP 温度 - + HIGH 高温 - + GOOD 最適 - + OK OK - + VEHICLE 車両 - + NO NO - + PANDA PANDA - + GPS GPS - + SEARCH 検索 diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts index a67b957e832534..ed5f1a96550ba6 100644 --- a/selfdrive/ui/translations/main_ko.ts +++ b/selfdrive/ui/translations/main_ko.ts @@ -876,71 +876,71 @@ location set Sidebar - - + + CONNECT 연결 - + OFFLINE 오프라인 - - + + ONLINE 온라인 - + ERROR 오류 - - - + + + TEMP 온도 - + HIGH 높음 - + GOOD 좋음 - + OK 경고 - + VEHICLE 차량 - + NO NO - + PANDA PANDA - + GPS GPS - + SEARCH 검색중 diff --git a/selfdrive/ui/translations/main_pt.ts b/selfdrive/ui/translations/main_pt.ts index 912afa38a43c10..980e7d4082a5f7 100644 --- a/selfdrive/ui/translations/main_pt.ts +++ b/selfdrive/ui/translations/main_pt.ts @@ -880,71 +880,71 @@ trabalho definido Sidebar - - + + CONNECT CONEXÃO - + OFFLINE DESCONEC - - + + ONLINE CONECTADO - + ERROR ERRO - - - + + + TEMP TEMP - + HIGH ALTA - + GOOD BOA - + OK OK - + VEHICLE VEÍCULO - + NO SEM - + PANDA PANDA - + GPS GPS - + SEARCH PROCURA diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts index 1ed96422b060f7..1fb65623e66c1d 100644 --- a/selfdrive/ui/translations/main_zh-CHS.ts +++ b/selfdrive/ui/translations/main_zh-CHS.ts @@ -874,71 +874,71 @@ location set Sidebar - - + + CONNECT CONNECT - + OFFLINE 离线 - - + + ONLINE 在线 - + ERROR 连接出错 - - - + + + TEMP 设备温度 - + HIGH 过热 - + GOOD 良好 - + OK 一般 - + VEHICLE 车辆连接 - + NO - + PANDA PANDA - + GPS GPS - + SEARCH 搜索中 diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts index 4f5c37764f87e0..0ba2f67a828b5c 100644 --- a/selfdrive/ui/translations/main_zh-CHT.ts +++ b/selfdrive/ui/translations/main_zh-CHT.ts @@ -876,71 +876,71 @@ location set Sidebar - - + + CONNECT 雲端服務 - + OFFLINE 已離線 - - + + ONLINE 已連線 - + ERROR 錯誤 - - - + + + TEMP 溫度 - + HIGH 偏高 - + GOOD 正常 - + OK 一般 - + VEHICLE 車輛通訊 - + NO 未連線 - + PANDA 車輛通訊 - + GPS GPS - + SEARCH 車輛通訊 diff --git a/tools/replay/consoleui.cc b/tools/replay/consoleui.cc index e4a3146a69c02c..6b419ca9d80908 100644 --- a/tools/replay/consoleui.cc +++ b/tools/replay/consoleui.cc @@ -18,6 +18,7 @@ const std::initializer_list> keyboard_shortc {"space", "Pause/Resume"}, {"e", "Next Engagement"}, {"d", "Next Disengagement"}, + {"t", "Next User Tag"} }, { {"enter", "Enter seek request"}, @@ -32,6 +33,7 @@ enum Color { Yellow, Green, Red, + Cyan, BrightWhite, Engaged, Disengaged, @@ -70,6 +72,7 @@ ConsoleUI::ConsoleUI(Replay *replay, QObject *parent) : replay(replay), sm({"car init_pair(Color::Debug, 246, COLOR_BLACK); // #949494 init_pair(Color::Yellow, 184, COLOR_BLACK); init_pair(Color::Red, COLOR_RED, COLOR_BLACK); + init_pair(Color::Cyan, COLOR_CYAN, COLOR_BLACK); init_pair(Color::BrightWhite, 15, COLOR_BLACK); init_pair(Color::Disengaged, COLOR_BLUE, COLOR_BLUE); init_pair(Color::Engaged, 28, 28); @@ -205,6 +208,7 @@ void ConsoleUI::displayTimelineDesc() { {Color::Green, " Info ", true}, {Color::Yellow, " Warning ", true}, {Color::Red, " Critical ", true}, + {Color::Cyan, " User Tag ", true}, }; for (auto [color, name, bold] : indicators) { add_str(w[Win::TimelineDesc], "__", color, bold); @@ -263,6 +267,8 @@ void ConsoleUI::updateTimeline() { if (type == TimelineType::Engaged) { mvwchgat(win, 1, start_pos, end_pos - start_pos + 1, A_COLOR, Color::Engaged, NULL); mvwchgat(win, 2, start_pos, end_pos - start_pos + 1, A_COLOR, Color::Engaged, NULL); + } else if (type == TimelineType::UserFlag) { + mvwchgat(win, 3, start_pos, end_pos - start_pos + 1, ACS_S3, Color::Cyan, NULL); } else { auto color_id = Color::Green; if (type != TimelineType::AlertInfo) { @@ -336,6 +342,8 @@ void ConsoleUI::handleKey(char c) { replay->seekToFlag(FindFlag::nextEngagement); } else if (c == 'd') { replay->seekToFlag(FindFlag::nextDisEngagement); + } else if (c == 't') { + replay->seekToFlag(FindFlag::nextUserFlag); } else if (c == 'm') { replay->seekTo(+60, true); } else if (c == 'M') { diff --git a/tools/replay/replay.cc b/tools/replay/replay.cc index c886a7e1862ae3..4b983fff85969d 100644 --- a/tools/replay/replay.cc +++ b/tools/replay/replay.cc @@ -149,6 +149,9 @@ void Replay::buildTimeline() { timeline.push_back({toSeconds(alert_begin), toSeconds(e->mono_time), alert_type}); alert_begin = 0; } + } else if (e->which == cereal::Event::Which::USER_FLAG) { + std::lock_guard lk(timeline_lock); + timeline.push_back({toSeconds(e->mono_time), toSeconds(e->mono_time), TimelineType::UserFlag}); } } } @@ -163,6 +166,10 @@ std::optional Replay::find(FindFlag flag) { } else if (flag == FindFlag::nextDisEngagement && end_ts > cur_ts) { return end_ts; } + } else if (type == TimelineType::UserFlag) { + if (flag == FindFlag::nextUserFlag && start_ts > cur_ts) { + return start_ts; + } } } return std::nullopt; @@ -360,7 +367,7 @@ void Replay::stream() { setCurrentSegment(toSeconds(cur_mono_time_) / 60); // migration for pandaState -> pandaStates to keep UI working for old segments - if (cur_which == cereal::Event::Which::PANDA_STATE_D_E_P_R_E_C_A_T_E_D && + if (cur_which == cereal::Event::Which::PANDA_STATE_D_E_P_R_E_C_A_T_E_D && sockets_[cereal::Event::Which::PANDA_STATES] != nullptr) { MessageBuilder msg; auto ps = msg.initEvent().initPandaStates(1); diff --git a/tools/replay/replay.h b/tools/replay/replay.h index 13269d3ec9a269..86d609683a5034 100644 --- a/tools/replay/replay.h +++ b/tools/replay/replay.h @@ -24,10 +24,11 @@ enum REPLAY_FLAGS { enum class FindFlag { nextEngagement, - nextDisEngagement + nextDisEngagement, + nextUserFlag, }; -enum class TimelineType { None, Engaged, AlertInfo, AlertWarning, AlertCritical }; +enum class TimelineType { None, Engaged, AlertInfo, AlertWarning, AlertCritical, UserFlag }; class Replay : public QObject { Q_OBJECT From 8b154fe27145f529d2459658e25cdd02f3fc9b5c Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Tue, 23 Aug 2022 11:18:23 -0700 Subject: [PATCH 093/106] Update translations --- selfdrive/ui/translations/main_ja.ts | 34 ++++++++++++------------ selfdrive/ui/translations/main_ko.ts | 34 ++++++++++++------------ selfdrive/ui/translations/main_pt.ts | 34 ++++++++++++------------ selfdrive/ui/translations/main_zh-CHS.ts | 34 ++++++++++++------------ selfdrive/ui/translations/main_zh-CHT.ts | 34 ++++++++++++------------ 5 files changed, 85 insertions(+), 85 deletions(-) diff --git a/selfdrive/ui/translations/main_ja.ts b/selfdrive/ui/translations/main_ja.ts index 79c982f81894e5..dd9f933dcf75ff 100644 --- a/selfdrive/ui/translations/main_ja.ts +++ b/selfdrive/ui/translations/main_ja.ts @@ -876,71 +876,71 @@ location set Sidebar - - + + CONNECT 接続 - + OFFLINE オフライン - - + + ONLINE オンライン - + ERROR エラー - - - + + + TEMP 温度 - + HIGH 高温 - + GOOD 最適 - + OK OK - + VEHICLE 車両 - + NO NO - + PANDA PANDA - + GPS GPS - + SEARCH 検索 diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts index ed5f1a96550ba6..d4abe861962c3a 100644 --- a/selfdrive/ui/translations/main_ko.ts +++ b/selfdrive/ui/translations/main_ko.ts @@ -876,71 +876,71 @@ location set Sidebar - - + + CONNECT 연결 - + OFFLINE 오프라인 - - + + ONLINE 온라인 - + ERROR 오류 - - - + + + TEMP 온도 - + HIGH 높음 - + GOOD 좋음 - + OK 경고 - + VEHICLE 차량 - + NO NO - + PANDA PANDA - + GPS GPS - + SEARCH 검색중 diff --git a/selfdrive/ui/translations/main_pt.ts b/selfdrive/ui/translations/main_pt.ts index 980e7d4082a5f7..3d5eda118ce042 100644 --- a/selfdrive/ui/translations/main_pt.ts +++ b/selfdrive/ui/translations/main_pt.ts @@ -880,71 +880,71 @@ trabalho definido Sidebar - - + + CONNECT CONEXÃO - + OFFLINE DESCONEC - - + + ONLINE CONECTADO - + ERROR ERRO - - - + + + TEMP TEMP - + HIGH ALTA - + GOOD BOA - + OK OK - + VEHICLE VEÍCULO - + NO SEM - + PANDA PANDA - + GPS GPS - + SEARCH PROCURA diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts index 1fb65623e66c1d..a26cddc0c34859 100644 --- a/selfdrive/ui/translations/main_zh-CHS.ts +++ b/selfdrive/ui/translations/main_zh-CHS.ts @@ -874,71 +874,71 @@ location set Sidebar - - + + CONNECT CONNECT - + OFFLINE 离线 - - + + ONLINE 在线 - + ERROR 连接出错 - - - + + + TEMP 设备温度 - + HIGH 过热 - + GOOD 良好 - + OK 一般 - + VEHICLE 车辆连接 - + NO - + PANDA PANDA - + GPS GPS - + SEARCH 搜索中 diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts index 0ba2f67a828b5c..f4681f85d940c2 100644 --- a/selfdrive/ui/translations/main_zh-CHT.ts +++ b/selfdrive/ui/translations/main_zh-CHT.ts @@ -876,71 +876,71 @@ location set Sidebar - - + + CONNECT 雲端服務 - + OFFLINE 已離線 - - + + ONLINE 已連線 - + ERROR 錯誤 - - - + + + TEMP 溫度 - + HIGH 偏高 - + GOOD 正常 - + OK 一般 - + VEHICLE 車輛通訊 - + NO 未連線 - + PANDA 車輛通訊 - + GPS GPS - + SEARCH 車輛通訊 From 506b719a40d4391a17a7bc081f761ec1215040ef Mon Sep 17 00:00:00 2001 From: AlexandreSato <66435071+AlexandreSato@users.noreply.github.com> Date: Tue, 23 Aug 2022 15:20:34 -0300 Subject: [PATCH 094/106] Toyota: add missing engine and esp FW for Corolla Cross Hybrid (#25532) add missing engine and esp FW for CorollaCross Hybrid DongleId 147613502316e718 --- selfdrive/car/toyota/values.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index 8915146063de3f..7b4031ca64ebcc 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -783,6 +783,7 @@ class ToyotaCarInfo(CarInfo): b'\x01896637626000\x00\x00\x00\x00', b'\x01896637648000\x00\x00\x00\x00', b'\x01896637643000\x00\x00\x00\x00', + b'\x02896630A21000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', b'\x02896630ZJ5000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', b'\x02896630ZN8000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', b'\x02896630ZQ3000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', @@ -827,6 +828,7 @@ class ToyotaCarInfo(CarInfo): b'F152612A10\x00\x00\x00\x00\x00\x00', b'F152612D00\x00\x00\x00\x00\x00\x00', b'F152616011\x00\x00\x00\x00\x00\x00', + b'F152616060\x00\x00\x00\x00\x00\x00', b'F152642540\x00\x00\x00\x00\x00\x00', b'F152676293\x00\x00\x00\x00\x00\x00', b'F152676303\x00\x00\x00\x00\x00\x00', From f41dc62a12cc0f3cb8c5453c0caa0ba21e1bd01e Mon Sep 17 00:00:00 2001 From: Jason Wen <47793918+sunnyhaibin@users.noreply.github.com> Date: Tue, 23 Aug 2022 14:21:07 -0400 Subject: [PATCH 095/106] HKG: Add FW for 2018 Kia Stinger (#25531) * HKG: Add FW for 2008 Kia Stinger * 2018 in disguise Co-authored-by: Shane Smiskol --- selfdrive/car/hyundai/values.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index 2861e4dc828b6f..aa18235223a6eb 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -703,6 +703,7 @@ class Buttons: (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00CK__ SCC F_CUP 1.00 1.01 96400-J5100 ', b'\xf1\x00CK__ SCC F_CUP 1.00 1.03 96400-J5100 ', + b'\xf1\x00CK__ SCC F_CUP 1.00 1.01 96400-J5000 ', ], (Ecu.engine, 0x7e0, None): [ b'\xf1\x81606DE051\x00\x00\x00\x00\x00\x00\x00\x00', @@ -720,6 +721,7 @@ class Buttons: (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00CK MFC AT USA LHD 1.00 1.03 95740-J5000 170822', b'\xf1\x00CK MFC AT USA LHD 1.00 1.04 95740-J5000 180504', + b'\xf1\x00CK MFC AT EUR LHD 1.00 1.03 95740-J5000 170822', ], (Ecu.transmission, 0x7e1, None): [ b'\xf1\x87VCJLE17622572DK0vd6D\x99\x98y\x97vwVffUfvfC%CuT&Dx\x87o\xff{\x1c\xf1\x81E21\x00\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 E21\x00\x00\x00\x00\x00\x00\x00SCK0T33NB0\x88\xa2\xe6\xf0', @@ -729,6 +731,7 @@ class Buttons: b'\xf1\x87VDHLG17118862DK2\x8awWwgu\x96wVfUVwv\x97xWvfvUTGTx\x87o\xff\xc9\xed\xf1\x81E21\x00\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 E21\x00\x00\x00\x00\x00\x00\x00SCK0T33NB0\x88\xa2\xe6\xf0', b'\xf1\x87VDKLJ18675252DK6\x89vhgwwwwveVU\x88w\x87w\x99vgf\x97vXfgw_\xff\xc2\xfb\xf1\x89E25\x00\x00\x00\x00\x00\x00\x00\xf1\x82TCK0T33NB2', b'\xf1\x87WAJTE17552812CH4vfFffvfVeT5DwvvVVdFeegeg\x88\x88o\xff\x1a]\xf1\x81E21\x00\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 E21\x00\x00\x00\x00\x00\x00\x00TCK2T20NB1\x19\xd2\x00\x94', + b'\xf1\x87VDHLG17274082DK2wfFf\x89x\x98wUT5T\x88v\x97xgeGefTGTVvO\xff\x1c\x14\xf1\x81E19\x00\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 E19\x00\x00\x00\x00\x00\x00\x00SCK0T33UB2\xee[\x97S', ], }, CAR.PALISADE: { From f8e44f2e9b186d5a3f99c9dfcf46dbf887b3861b Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Tue, 23 Aug 2022 13:42:14 -0700 Subject: [PATCH 096/106] test_models: pass carFw into car interface (#25535) pass carFw into get_params --- selfdrive/car/tests/test_models.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/selfdrive/car/tests/test_models.py b/selfdrive/car/tests/test_models.py index fdf7bca3d2e3f8..6e88e227cc3abc 100755 --- a/selfdrive/car/tests/test_models.py +++ b/selfdrive/car/tests/test_models.py @@ -81,6 +81,7 @@ def setUpClass(cls): except Exception: continue + car_fw = [] can_msgs = [] fingerprint = defaultdict(dict) for msg in lr: @@ -90,6 +91,7 @@ def setUpClass(cls): fingerprint[m.src][m.address] = len(m.dat) can_msgs.append(msg) elif msg.which() == "carParams": + car_fw = msg.carParams.carFw if msg.carParams.openpilotLongitudinalControl: disable_radar = True if cls.car_model is None and not cls.ci: @@ -103,7 +105,7 @@ def setUpClass(cls): cls.can_msgs = sorted(can_msgs, key=lambda msg: msg.logMonoTime) cls.CarInterface, cls.CarController, cls.CarState = interfaces[cls.car_model] - cls.CP = cls.CarInterface.get_params(cls.car_model, fingerprint, [], disable_radar) + cls.CP = cls.CarInterface.get_params(cls.car_model, fingerprint, car_fw, disable_radar) assert cls.CP assert cls.CP.carFingerprint == cls.car_model From a34acc316e8c4fc6d4ea101ef58919686cd0807c Mon Sep 17 00:00:00 2001 From: Rewat S <76684800+taperec@users.noreply.github.com> Date: Wed, 24 Aug 2022 06:29:47 +0700 Subject: [PATCH 097/106] Add Thai translations (#25189) * Add Thai translations * update to add plurals remove * Update translations * Update Thai translation to match English source. * Add to badges * use shorter km/h * Add test for correct format specifier for plural translations * pass new test * Update some sentences to make it clear. Change short form of some words. * Hide from the UI Co-authored-by: Shane Smiskol --- selfdrive/ui/translations/main_th.ts | 1303 ++++++++++++++++++++++++++ 1 file changed, 1303 insertions(+) create mode 100644 selfdrive/ui/translations/main_th.ts diff --git a/selfdrive/ui/translations/main_th.ts b/selfdrive/ui/translations/main_th.ts new file mode 100644 index 00000000000000..3277f537404ff0 --- /dev/null +++ b/selfdrive/ui/translations/main_th.ts @@ -0,0 +1,1303 @@ + + + + + AbstractAlert + + + Close + ปิด + + + + Snooze Update + เลื่อนการอัปเดต + + + + Reboot and Update + รีบูตและอัปเดต + + + + AdvancedNetworking + + + Back + ย้อนกลับ + + + + Enable Tethering + ปล่อยฮอตสปอต + + + + Tethering Password + รหัสผ่านฮอตสปอต + + + + + EDIT + แก้ไข + + + + Enter new tethering password + ป้อนรหัสผ่านฮอตสปอตใหม่ + + + + IP Address + หมายเลขไอพี + + + + Enable Roaming + เปิดใช้งานโรมมิ่ง + + + + APN Setting + ตั้งค่า APN + + + + Enter APN + ป้อนค่า APN + + + + leave blank for automatic configuration + เว้นว่างเพื่อตั้งค่าอัตโนมัติ + + + + ConfirmationDialog + + + + Ok + ตกลง + + + + Cancel + ยกเลิก + + + + DeclinePage + + + You must accept the Terms and Conditions in order to use openpilot. + คุณต้องยอมรับเงื่อนไขและข้อตกลง เพื่อใช้งาน openpilot + + + + Back + ย้อนกลับ + + + + Decline, uninstall %1 + ปฏิเสธ และถอนการติดตั้ง %1 + + + + DevicePanel + + + Dongle ID + Dongle ID + + + + N/A + ไม่มี + + + + Serial + ซีเรียล + + + + Driver Camera + กล้องฝั่งคนขับ + + + + PREVIEW + แสดงภาพ + + + + Preview the driver facing camera to ensure that driver monitoring has good visibility. (vehicle must be off) + ดูภาพตัวอย่างกล้องที่หันเข้าหาคนขับเพื่อให้แน่ใจว่าการตรวจสอบคนขับมีทัศนวิสัยที่ดี (รถต้องดับเครื่องยนต์) + + + + Reset Calibration + รีเซ็ตการคาลิเบรท + + + + RESET + รีเซ็ต + + + + Are you sure you want to reset calibration? + คุณแน่ใจหรือไม่ว่าต้องการรีเซ็ตการคาลิเบรท? + + + + Review Training Guide + ทบทวนคู่มือการใช้งาน + + + + REVIEW + ทบทวน + + + + Review the rules, features, and limitations of openpilot + ตรวจสอบกฎ คุณสมบัติ และข้อจำกัดของ openpilot + + + + Are you sure you want to review the training guide? + คุณแน่ใจหรือไม่ว่าต้องการทบทวนคู่มือการใช้งาน? + + + + Regulatory + ระเบียบข้อบังคับ + + + + VIEW + ดู + + + + Change Language + เปลี่ยนภาษา + + + + CHANGE + เปลี่ยน + + + + Select a language + เลือกภาษา + + + + Reboot + รีบูต + + + + Power Off + ปิดเครื่อง + + + + openpilot requires the device to be mounted within 4° left or right and within 5° up or 8° down. openpilot is continuously calibrating, resetting is rarely required. + openpilot กำหนดให้ติดตั้งอุปกรณ์ โดยสามารถเอียงด้านซ้ายหรือขวาไม่เกิน 4° และเอียงขึ้นด้านบนไม่เกิน 5° หรือเอียงลงด้านล่างไม่เกิน 8° openpilot ทำการคาลิเบรทอย่างต่อเนื่อง แทบจะไม่จำเป็นต้องทำการรีเซ็ตการคาลิเบรท + + + + Your device is pointed %1° %2 and %3° %4. + อุปกรณ์ของคุณเอียงไปทาง %2 %1° และ %4 %3° + + + + down + ด้านล่าง + + + + up + ด้านบน + + + + left + ด้านซ้าย + + + + right + ด้านขวา + + + + Are you sure you want to reboot? + คุณแน่ใจหรือไม่ว่าต้องการรีบูต? + + + + Disengage to Reboot + ยกเลิกระบบช่วยขับเพื่อรีบูต + + + + Are you sure you want to power off? + คุณแน่ใจหรือไม่ว่าต้องการปิดเครื่อง? + + + + Disengage to Power Off + ยกเลิกระบบช่วยขับเพื่อปิดเครื่อง + + + + DriveStats + + + Drives + การขับขี่ + + + + Hours + ชั่วโมง + + + + ALL TIME + ทั้งหมด + + + + PAST WEEK + สัปดาห์ที่ผ่านมา + + + + KM + กิโลเมตร + + + + Miles + ไมล์ + + + + DriverViewScene + + + camera starting + กำลังเปิดกล้อง + + + + InputDialog + + + Cancel + ยกเลิก + + + + Need at least %n character(s)! + + ต้องการอย่างน้อย %n ตัวอักษร! + + + + + Installer + + + Installing... + กำลังติดตั้ง... + + + + Receiving objects: + กำลังรับข้อมูล: + + + + Resolving deltas: + การแก้ไขเดลต้า: + + + + Updating files: + กำลังอัปเดตไฟล์: + + + + MapETA + + + eta + eta + + + + min + นาที + + + + hr + ชม. + + + + km + กม. + + + + mi + ไมล์ + + + + MapInstructions + + + km + กม. + + + + m + ม. + + + + mi + ไมล์ + + + + ft + ฟุต + + + + MapPanel + + + Current Destination + ปลายทางปัจจุบัน + + + + CLEAR + ล้างข้อมูล + + + + Recent Destinations + ปลายทางล่าสุด + + + + Try the Navigation Beta + ลองใช้ระบบนำทาง (เบต้า) + + + + Get turn-by-turn directions displayed and more with a comma +prime subscription. Sign up now: https://connect.comma.ai + รับการแสดงเส้นทางแบบเลี้ยวต่อเลี้ยว และอื่นๆ ด้วยการสมัครบริการ +comma prime สมัครเลย: https://connect.comma.ai + + + + No home +location set + ยังไม่ได้กำหนด +ตำแหน่งของบ้าน + + + + No work +location set + ยังไม่ได้กำหนด +ตำแหน่งของที่ทำงาน + + + + no recent destinations + ไม่พบปลายทางล่าสุด + + + + MapWindow + + + Map Loading + กำลังโหลดแผนที่ + + + + Waiting for GPS + กำลังรอสัญญาณ GPS + + + + MultiOptionDialog + + + Select + เลือก + + + + Cancel + ยกเลิก + + + + Networking + + + Advanced + ขั้นสูง + + + + Enter password + ใส่รหัสผ่าน + + + + + for "%1" + สำหรับ "%1" + + + + Wrong password + รหัสผ่านผิด + + + + NvgWindow + + + km/h + กม./ชม. + + + + mph + ไมล์/ชม. + + + + + MAX + สูงสุด + + + + + SPEED + ความเร็ว + + + + + LIMIT + จำกัด + + + + OffroadHome + + + UPDATE + อัปเดต + + + + ALERTS + การแจ้งเตือน + + + + ALERT + การแจ้งเตือน + + + + PairingPopup + + + Pair your device to your comma account + จับคู่อุปกรณ์ของคุณกับบัญชี comma ของคุณ + + + + Go to https://connect.comma.ai on your phone + ไปที่ https://connect.comma.ai ด้วยโทรศัพท์ของคุณ + + + + Click "add new device" and scan the QR code on the right + กดที่ "add new device" และสแกนคิวอาร์โค้ดทางด้านขวา + + + + Bookmark connect.comma.ai to your home screen to use it like an app + จดจำ connect.comma.ai โดยการเพิ่มไปยังหน้าจอโฮม เพื่อใช้งานเหมือนเป็นแอปพลิเคชัน + + + + PrimeAdWidget + + + Upgrade Now + อัพเกรดเดี๋ยวนี้ + + + + Become a comma prime member at connect.comma.ai + สมัครสมาชิก comma prime ได้ที่ connect.comma.ai + + + + PRIME FEATURES: + คุณสมบัติของ PRIME: + + + + Remote access + การเข้าถึงระยะไกล + + + + 1 year of storage + จัดเก็บข้อมูลนาน 1 ปี + + + + Developer perks + สิทธิพิเศษสำหรับนักพัฒนา + + + + PrimeUserWidget + + + ✓ SUBSCRIBED + ✓ สมัครสำเร็จ + + + + comma prime + comma prime + + + + CONNECT.COMMA.AI + CONNECT.COMMA.AI + + + + COMMA POINTS + คะแนน COMMA + + + + QObject + + + Reboot + รีบูต + + + + Exit + ปิด + + + + dashcam + กล้องติดรถยนต์ + + + + openpilot + openpilot + + + + %n minute(s) ago + + %n นาทีที่แล้ว + + + + + %n hour(s) ago + + %n ชั่วโมงที่แล้ว + + + + + %n day(s) ago + + %n วันที่แล้ว + + + + + Reset + + + Reset failed. Reboot to try again. + การรีเซ็ตล้มเหลว รีบูตเพื่อลองอีกครั้ง + + + + Are you sure you want to reset your device? + คุณแน่ใจหรือไม่ว่าต้องการรีเซ็ตอุปกรณ์? + + + + Resetting device... + กำลังรีเซ็ตอุปกรณ์... + + + + System Reset + รีเซ็ตระบบ + + + + System reset triggered. Press confirm to erase all content and settings. Press cancel to resume boot. + มีการสั่งรีเซ็ตระบบ กดยืนยันเพื่อลบข้อมูลและการตั้งค่าทั้งหมด กดยกเลิกเพื่อบูตเข้าระบบตามปกติ + + + + Cancel + ยกเลิก + + + + Reboot + รีบูต + + + + Confirm + ยืนยัน + + + + Unable to mount data partition. Press confirm to reset your device. + ไม่สามารถเมานต์พาร์ติชั่นข้อมูล กดยืนยันเพื่อรีเซ็ตอุปกรณ์ของคุณ + + + + RichTextDialog + + + Ok + ตกลง + + + + SettingsWindow + + + × + × + + + + Device + อุปกรณ์ + + + + + Network + เครือข่าย + + + + Toggles + ตัวเลือก + + + + Software + ซอฟต์แวร์ + + + + Navigation + การนำทาง + + + + Setup + + + WARNING: Low Voltage + คำเตือน: แรงดันไฟฟ้าต่ำ + + + + Power your device in a car with a harness or proceed at your own risk. + โปรดต่ออุปกรณ์ของคุณเข้ากับสายควบคุมในรถยนต์ หรือดำเนินการด้วยความเสี่ยงของคุณเอง + + + + Power off + ปิดเครื่อง + + + + + + Continue + ดำเนินการต่อ + + + + Getting Started + เริ่มกันเลย + + + + Before we get on the road, let’s finish installation and cover some details. + ก่อนออกเดินทาง เรามาทำการติดตั้งซอฟต์แวร์ และตรวจสอบการตั้งค่า + + + + Connect to Wi-Fi + เชื่อมต่อ Wi-Fi + + + + + Back + ย้อนกลับ + + + + Continue without Wi-Fi + ดำเนินการต่อโดยไม่ใช้ Wi-Fi + + + + Waiting for internet + กำลังรอสัญญาณอินเตอร์เน็ต + + + + Choose Software to Install + เลือกซอฟต์แวร์ที่จะติดตั้ง + + + + Dashcam + กล้องติดรถยนต์ + + + + Custom Software + ซอฟต์แวร์ที่กำหนดเอง + + + + Enter URL + ป้อน URL + + + + for Custom Software + สำหรับซอฟต์แวร์ที่กำหนดเอง + + + + Downloading... + กำลังดาวน์โหลด... + + + + Download Failed + ดาวน์โหลดล้มเหลว + + + + Ensure the entered URL is valid, and the device’s internet connection is good. + ตรวจสอบให้แน่ใจว่า URL ที่ป้อนนั้นถูกต้อง และอุปกรณ์เชื่อมต่ออินเทอร์เน็ตอยู่ + + + + Reboot device + รีบูตอุปกรณ์ + + + + Start over + เริ่มต้นใหม่ + + + + SetupWidget + + + Finish Setup + ตั้งค่าเสร็จสิ้น + + + + Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer. + จับคู่อุปกรณ์ของคุณกับ comma connect (connect.comma.ai) และรับข้อเสนอ comma prime ของคุณ + + + + Pair device + จับคู่อุปกรณ์ + + + + Sidebar + + + + CONNECT + เชื่อมต่อ + + + + OFFLINE + ออฟไลน์ + + + + + ONLINE + ออนไลน์ + + + + ERROR + เกิดข้อผิดพลาด + + + + + + TEMP + อุณหภูมิ + + + + HIGH + สูง + + + + GOOD + ดี + + + + OK + พอใช้ + + + + VEHICLE + รถยนต์ + + + + NO + ไม่พบ + + + + PANDA + PANDA + + + + GPS + จีพีเอส + + + + SEARCH + ค้นหา + + + + -- + -- + + + + Wi-Fi + Wi-Fi + + + + ETH + ETH + + + + 2G + 2G + + + + 3G + 3G + + + + LTE + LTE + + + + 5G + 5G + + + + SoftwarePanel + + + Git Branch + Git Branch + + + + Git Commit + Git Commit + + + + OS Version + เวอร์ชันระบบปฏิบัติการ + + + + Version + เวอร์ชั่น + + + + Last Update Check + ตรวจสอบการอัปเดตล่าสุด + + + + The last time openpilot successfully checked for an update. The updater only runs while the car is off. + ครั้งสุดท้ายที่ openpilot ตรวจสอบการอัปเดตสำเร็จ ตัวอัปเดตจะทำงานในขณะที่รถดับเครื่องอยู่เท่านั้น + + + + Check for Update + ตรวจสอบการอัปเดต + + + + CHECKING + กำลังตรวจสอบ + + + + Switch Branch + เปลี่ยน Branch + + + + ENTER + เปลี่ยน + + + + + The new branch will be pulled the next time the updater runs. + Branch ใหม่จะถูกติดตั้งในครั้งต่อไปที่ตัวอัปเดตทำงาน + + + + Enter branch name + ใส่ชื่อ Branch + + + + Uninstall %1 + ถอนการติดตั้ง %1 + + + + UNINSTALL + ถอนการติดตั้ง + + + + Are you sure you want to uninstall? + คุณแน่ใจหรือไม่ว่าต้องการถอนการติดตั้ง? + + + + failed to fetch update + โหลดข้อมูลอัปเดตไม่สำเร็จ + + + + + CHECK + ตรวจสอบ + + + + SshControl + + + SSH Keys + คีย์ SSH + + + + Warning: This grants SSH access to all public keys in your GitHub settings. Never enter a GitHub username other than your own. A comma employee will NEVER ask you to add their GitHub username. + คำเตือน: สิ่งนี้ให้สิทธิ์ SSH เข้าถึงคีย์สาธารณะทั้งหมดใน GitHub ของคุณ อย่าป้อนชื่อผู้ใช้ GitHub อื่นนอกเหนือจากของคุณเอง พนักงาน comma จะไม่ขอให้คุณเพิ่มชื่อผู้ใช้ GitHub ของพวกเขา + + + + + ADD + เพิ่ม + + + + Enter your GitHub username + ป้อนชื่อผู้ใช้ GitHub ของคุณ + + + + LOADING + กำลังโหลด + + + + REMOVE + ลบ + + + + Username '%1' has no keys on GitHub + ชื่อผู้ใช้ '%1' ไม่มีคีย์บน GitHub + + + + Request timed out + ตรวจสอบไม่สำเร็จ เนื่องจากใช้เวลามากเกินไป + + + + Username '%1' doesn't exist on GitHub + ไม่พบชื่อผู้ใช้ '%1' บน GitHub + + + + SshToggle + + + Enable SSH + เปิดใช้งาน SSH + + + + TermsPage + + + Terms & Conditions + ข้อตกลงและเงื่อนไข + + + + Decline + ปฏิเสธ + + + + Scroll to accept + เลื่อนเพื่อตอบรับข้อตกลง + + + + Agree + ยอมรับ + + + + TogglesPanel + + + Enable openpilot + เปิดใช้งาน openpilot + + + + Use the openpilot system for adaptive cruise control and lane keep driver assistance. Your attention is required at all times to use this feature. Changing this setting takes effect when the car is powered off. + ใช้ระบบ openpilot สำหรับระบบควบคุมความเร็วอัตโนมัติ และระบบช่วยควบคุมรถให้อยู่ในเลน คุณจำเป็นต้องให้ความสนใจตลอดเวลาที่ใช้คุณสมบัตินี้ การเปลี่ยนการตั้งค่านี้จะมีผลเมื่อคุณดับเครื่องยนต์ + + + + Enable Lane Departure Warnings + เปิดใช้งานการเตือนการออกนอกเลน + + + + Receive alerts to steer back into the lane when your vehicle drifts over a detected lane line without a turn signal activated while driving over 31 mph (50 km/h). + รับการแจ้งเตือนให้เลี้ยวกลับเข้าเลนเมื่อรถของคุณตรวจพบการข้ามช่องจราจรโดยไม่เปิดสัญญาณไฟเลี้ยวในขณะขับขี่ที่ความเร็วเกิน 31 ไมล์ต่อชั่วโมง (50 กม./ชม) + + + + Use Metric System + ใช้ระบบเมตริก + + + + Display speed in km/h instead of mph. + แสดงความเร็วเป็น กม./ชม. แทน ไมล์/ชั่วโมง + + + + Record and Upload Driver Camera + บันทึกและอัปโหลดภาพจากกล้องคนขับ + + + + Upload data from the driver facing camera and help improve the driver monitoring algorithm. + อัปโหลดข้อมูลจากกล้องที่หันหน้าไปทางคนขับ และช่วยปรับปรุงอัลกอริธึมการตรวจสอบผู้ขับขี่ + + + + Disengage On Accelerator Pedal + ยกเลิกระบบช่วยขับเมื่อเหยียบคันเร่ง + + + + When enabled, pressing the accelerator pedal will disengage openpilot. + เมื่อเปิดใช้งาน การกดแป้นคันเร่งจะเป็นการยกเลิกระบบช่วยขับโดย openpilot + + + + Show ETA in 24h Format + แสดงเวลา ETA ในรูปแบบ 24 ชั่วโมง + + + + Use 24h format instead of am/pm + ใช้รูปแบบเวลา 24 ชั่วโมง แทน am/pm + + + + Show Map on Left Side of UI + แสดงแผนที่ที่ด้านซ้ายของหน้าจอ + + + + Show map on left side when in split screen view. + แสดงแผนที่ด้านซ้ายของหน้าจอเมื่ออยู่ในโหมดแบ่งหน้าจอ + + + + openpilot Longitudinal Control + openpilot การควบคุมการเร่งและลดความเร็ว + + + + openpilot will disable the car's radar and will take over control of gas and brakes. Warning: this disables AEB! + openpilot จะปิดการใช้งานเรดาร์ของรถ และจะเข้าควบคุมการเร่งและเบรก คำเตือน: สิ่งนี้จะปิดระบบ AEB! + + + + Updater + + + Update Required + จำเป็นต้องอัปเดต + + + + An operating system update is required. Connect your device to Wi-Fi for the fastest update experience. The download size is approximately 1GB. + จำเป็นต้องมีการอัปเดตระบบปฏิบัติการ เชื่อมต่ออุปกรณ์ของคุณกับ Wi-Fi เพื่อประสบการณ์การอัปเดตที่เร็วที่สุด ขนาดดาวน์โหลดประมาณ 1GB + + + + Connect to Wi-Fi + เชื่อมต่อกับ Wi-Fi + + + + Install + ติดตั้ง + + + + Back + ย้อนกลับ + + + + Loading... + กำลังโหลด... + + + + Reboot + รีบูต + + + + Update failed + การอัปเดตล้มเหลว + + + + WifiUI + + + + Scanning for networks... + กำลังสแกนหาเครือข่าย... + + + + CONNECTING... + กำลังเชื่อมต่อ... + + + + FORGET + เลิกใช้ + + + + Forget Wi-Fi Network "%1"? + เลิกใช้เครือข่าย Wi-Fi "%1"? + + + From c8378b6ad58fc6ba68976ffaff49b03aa2224bbb Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 23 Aug 2022 16:54:45 -0700 Subject: [PATCH 098/106] update car candidate docs (#25536) * update car candidate docs * little more * that's a nice wikipedia * quotes --- docs/CARS.md | 15 ++++++++------- selfdrive/car/CARS_template.md | 14 ++++++++------ 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/docs/CARS.md b/docs/CARS.md index 24be43e4f73664..78b4d3b168305e 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -2,7 +2,7 @@ # Supported Cars -A supported vehicle is one that just works when you install a comma device. Every car performs differently with openpilot, but all supported cars should provide a better experience than any stock system. +A supported vehicle is one that just works when you install a comma three. All supported cars provide a better experience than any stock system. # 205 Supported Cars @@ -230,13 +230,13 @@ Although they're not upstream, the community has openpilot running on other make # Don't see your car here? **openpilot can support many more cars than it currently does.** There are a few reasons your car may not be supported. -If your car doesn't fit into any of the incompatibility criteria here, then there's a good chance it can be supported! We're adding support for new cars all the time. We don't have a roadmap for car support, and in fact, most car support comes from users like you! +If your car doesn't fit into any of the incompatibility criteria here, then there's a good chance it can be supported! We're adding support for new cars all the time. **We don't have a roadmap for car support**, and in fact, most car support comes from users like you! ### Which cars are able to be supported? -openpilot uses the existing steering, gas, and brake interfaces in your car. If your car lacks any one of these interfaces, openpilot will not be able to control the car. If your car has any form of [LKAS](https://en.wikipedia.org/wiki/Automated_Lane_Keeping_Systems)/[LCA](https://en.wikipedia.org/wiki/Lane_centering) and [ACC](https://en.wikipedia.org/wiki/Adaptive_cruise_control), then it almost certainly has these interfaces. These interfaces generally started shipping on cars around 2016. +openpilot uses the existing steering, gas, and brake interfaces in your car. If your car lacks any one of these interfaces, openpilot will not be able to control the car. If your car has [ACC](https://en.wikipedia.org/wiki/Adaptive_cruise_control) and any form of [LKAS](https://en.wikipedia.org/wiki/Automated_Lane_Keeping_Systems)/[LCA](https://en.wikipedia.org/wiki/Lane_centering), then it almost certainly has these interfaces. These features generally started shipping on cars around 2016. Note that manufacturers will often make their own [marketing terms](https://en.wikipedia.org/wiki/Adaptive_cruise_control#Vehicle_models_supporting_adaptive_cruise_control) for these features, such as Hyundai's "Smart Cruise Control" branding of Adaptive Cruise Control. -If your car has the following packages or features, then it's a good candidate for support. If it does not, then it's unlikely able to be supported. +If your car has the following packages or features, then it's a good candidate for support. | Make | Required Package/Features | | ---- | ------------------------- | @@ -254,8 +254,9 @@ All the cars that openpilot supports use a [CAN bus](https://en.wikipedia.org/wi ### Toyota Security -Specific new Toyota models are shipping with a new message authentication method that openpilot does not yet support. -So far, this list includes: +openpilot does not yet support these Toyota models due to a new message authentication method. +[Vote](https://comma.ai/shop/products/vote) if you'd like to see openpilot support on these models. + * Toyota RAV4 Prime 2021+ * Toyota Sienna 2021+ * Toyota Venza 2021+ @@ -264,4 +265,4 @@ So far, this list includes: * Toyota Corolla Cross 2022+ (only US model) * Lexus NX 2022+ * Toyota bZ4x 2023+ -* Subaru Solterra 2023+ \ No newline at end of file +* Subaru Solterra 2023+ diff --git a/selfdrive/car/CARS_template.md b/selfdrive/car/CARS_template.md index d306ca5d92bfe8..2fce0f9036176e 100644 --- a/selfdrive/car/CARS_template.md +++ b/selfdrive/car/CARS_template.md @@ -5,7 +5,7 @@ # Supported Cars -A supported vehicle is one that just works when you install a comma device. Every car performs differently with openpilot, but all supported cars should provide a better experience than any stock system. +A supported vehicle is one that just works when you install a comma three. All supported cars provide a better experience than any stock system. # {{all_car_info | length}} Supported Cars @@ -27,13 +27,13 @@ Although they're not upstream, the community has openpilot running on other make # Don't see your car here? **openpilot can support many more cars than it currently does.** There are a few reasons your car may not be supported. -If your car doesn't fit into any of the incompatibility criteria here, then there's a good chance it can be supported! We're adding support for new cars all the time. We don't have a roadmap for car support, and in fact, most car support comes from users like you! +If your car doesn't fit into any of the incompatibility criteria here, then there's a good chance it can be supported! We're adding support for new cars all the time. **We don't have a roadmap for car support**, and in fact, most car support comes from users like you! ### Which cars are able to be supported? -openpilot uses the existing steering, gas, and brake interfaces in your car. If your car lacks any one of these interfaces, openpilot will not be able to control the car. If your car has any form of [LKAS](https://en.wikipedia.org/wiki/Automated_Lane_Keeping_Systems)/[LCA](https://en.wikipedia.org/wiki/Lane_centering) and [ACC](https://en.wikipedia.org/wiki/Adaptive_cruise_control), then it almost certainly has these interfaces. These interfaces generally started shipping on cars around 2016. +openpilot uses the existing steering, gas, and brake interfaces in your car. If your car lacks any one of these interfaces, openpilot will not be able to control the car. If your car has [ACC](https://en.wikipedia.org/wiki/Adaptive_cruise_control) and any form of [LKAS](https://en.wikipedia.org/wiki/Automated_Lane_Keeping_Systems)/[LCA](https://en.wikipedia.org/wiki/Lane_centering), then it almost certainly has these interfaces. These features generally started shipping on cars around 2016. Note that manufacturers will often make their own [marketing terms](https://en.wikipedia.org/wiki/Adaptive_cruise_control#Vehicle_models_supporting_adaptive_cruise_control) for these features, such as Hyundai's "Smart Cruise Control" branding of Adaptive Cruise Control. -If your car has the following packages or features, then it's a good candidate for support. If it does not, then it's unlikely able to be supported. +If your car has the following packages or features, then it's a good candidate for support. | Make | Required Package/Features | | ---- | ------------------------- | @@ -51,8 +51,9 @@ All the cars that openpilot supports use a [CAN bus](https://en.wikipedia.org/wi ### Toyota Security -Specific new Toyota models are shipping with a new message authentication method that openpilot does not yet support. -So far, this list includes: +openpilot does not yet support these Toyota models due to a new message authentication method. +[Vote](https://comma.ai/shop/products/vote) if you'd like to see openpilot support on these models. + * Toyota RAV4 Prime 2021+ * Toyota Sienna 2021+ * Toyota Venza 2021+ @@ -62,3 +63,4 @@ So far, this list includes: * Lexus NX 2022+ * Toyota bZ4x 2023+ * Subaru Solterra 2023+ + From 19810f2dcc11f5fe307b71a19aff419e9459d3b3 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Tue, 23 Aug 2022 17:26:29 -0700 Subject: [PATCH 099/106] Silence a PytestCollectionWarning (#25537) Silence PytestCollectionWarning: cannot collect test class 'TestRoute' because it has a __new__ constructor (from: test_models.py) --- selfdrive/car/tests/routes.py | 376 ++++++++++++++--------------- selfdrive/car/tests/test_models.py | 4 +- selfdrive/debug/test_car_model.py | 6 +- 3 files changed, 193 insertions(+), 193 deletions(-) diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py index 532ab7119173ce..a47a3447e2c5f7 100644 --- a/selfdrive/car/tests/routes.py +++ b/selfdrive/car/tests/routes.py @@ -26,202 +26,202 @@ HYUNDAI.KIA_OPTIMA_H, ] -TestRoute = namedtuple('TestRoute', ['route', 'car_model', 'segment'], defaults=(None,)) +CarTestRoute = namedtuple('CarTestRoute', ['route', 'car_model', 'segment'], defaults=(None,)) routes = [ - TestRoute("efdf9af95e71cd84|2022-05-13--19-03-31", COMMA.BODY), - - TestRoute("0c94aa1e1296d7c6|2021-05-05--19-48-37", CHRYSLER.JEEP_CHEROKEE), - TestRoute("91dfedae61d7bd75|2021-05-22--20-07-52", CHRYSLER.JEEP_CHEROKEE_2019), - TestRoute("420a8e183f1aed48|2020-03-05--07-15-29", CHRYSLER.PACIFICA_2017_HYBRID), - TestRoute("43a685a66291579b|2021-05-27--19-47-29", CHRYSLER.PACIFICA_2018), - TestRoute("378472f830ee7395|2021-05-28--07-38-43", CHRYSLER.PACIFICA_2018_HYBRID), - TestRoute("8190c7275a24557b|2020-01-29--08-33-58", CHRYSLER.PACIFICA_2019_HYBRID), - TestRoute("3d84727705fecd04|2021-05-25--08-38-56", CHRYSLER.PACIFICA_2020), - TestRoute("221c253375af4ee9|2022-06-15--18-38-24", CHRYSLER.RAM_1500), - TestRoute("8fb5eabf914632ae|2022-08-04--17-28-53", CHRYSLER.RAM_HD, segment=6), + CarTestRoute("efdf9af95e71cd84|2022-05-13--19-03-31", COMMA.BODY), + + CarTestRoute("0c94aa1e1296d7c6|2021-05-05--19-48-37", CHRYSLER.JEEP_CHEROKEE), + CarTestRoute("91dfedae61d7bd75|2021-05-22--20-07-52", CHRYSLER.JEEP_CHEROKEE_2019), + CarTestRoute("420a8e183f1aed48|2020-03-05--07-15-29", CHRYSLER.PACIFICA_2017_HYBRID), + CarTestRoute("43a685a66291579b|2021-05-27--19-47-29", CHRYSLER.PACIFICA_2018), + CarTestRoute("378472f830ee7395|2021-05-28--07-38-43", CHRYSLER.PACIFICA_2018_HYBRID), + CarTestRoute("8190c7275a24557b|2020-01-29--08-33-58", CHRYSLER.PACIFICA_2019_HYBRID), + CarTestRoute("3d84727705fecd04|2021-05-25--08-38-56", CHRYSLER.PACIFICA_2020), + CarTestRoute("221c253375af4ee9|2022-06-15--18-38-24", CHRYSLER.RAM_1500), + CarTestRoute("8fb5eabf914632ae|2022-08-04--17-28-53", CHRYSLER.RAM_HD, segment=6), #TestRoute("f1b4c567731f4a1b|2018-04-30--10-15-35", FORD.FUSION), - TestRoute("7cc2a8365b4dd8a9|2018-12-02--12-10-44", GM.ACADIA), - TestRoute("aa20e335f61ba898|2019-02-05--16-59-04", GM.BUICK_REGAL), - TestRoute("46460f0da08e621e|2021-10-26--07-21-46", GM.ESCALADE_ESV), - TestRoute("c950e28c26b5b168|2018-05-30--22-03-41", GM.VOLT), - TestRoute("f08912a233c1584f|2022-08-11--18-02-41", GM.BOLT_EUV), - TestRoute("38aa7da107d5d252|2022-08-15--16-01-12", GM.SILVERADO), - - TestRoute("0e7a2ba168465df5|2020-10-18--14-14-22", HONDA.ACURA_RDX_3G), - TestRoute("a74b011b32b51b56|2020-07-26--17-09-36", HONDA.CIVIC), - TestRoute("a859a044a447c2b0|2020-03-03--18-42-45", HONDA.CRV_EU), - TestRoute("68aac44ad69f838e|2021-05-18--20-40-52", HONDA.CRV), - TestRoute("14fed2e5fa0aa1a5|2021-05-25--14-59-42", HONDA.CRV_HYBRID), - TestRoute("52f3e9ae60c0d886|2021-05-23--15-59-43", HONDA.FIT), - TestRoute("2c4292a5cd10536c|2021-08-19--21-32-15", HONDA.FREED), - TestRoute("03be5f2fd5c508d1|2020-04-19--18-44-15", HONDA.HRV), - TestRoute("917b074700869333|2021-05-24--20-40-20", HONDA.ACURA_ILX), - TestRoute("81722949a62ea724|2019-04-06--15-19-25", HONDA.ODYSSEY_CHN), - TestRoute("08a3deb07573f157|2020-03-06--16-11-19", HONDA.ACCORD), # 1.5T - TestRoute("1da5847ac2488106|2021-05-24--19-31-50", HONDA.ACCORD), # 2.0T - TestRoute("085ac1d942c35910|2021-03-25--20-11-15", HONDA.ACCORD), # 2021 with new style HUD msgs - TestRoute("07585b0da3c88459|2021-05-26--18-52-04", HONDA.ACCORDH), - TestRoute("f29e2b57a55e7ad5|2021-03-24--20-52-38", HONDA.ACCORDH), # 2021 with new style HUD msgs - TestRoute("1ad763dd22ef1a0e|2020-02-29--18-37-03", HONDA.CRV_5G), - TestRoute("0a96f86fcfe35964|2020-02-05--07-25-51", HONDA.ODYSSEY), - TestRoute("d83f36766f8012a5|2020-02-05--18-42-21", HONDA.CIVIC_BOSCH_DIESEL), - TestRoute("f0890d16a07a236b|2021-05-25--17-27-22", HONDA.INSIGHT), - TestRoute("07d37d27996096b6|2020-03-04--21-57-27", HONDA.PILOT), - TestRoute("684e8f96bd491a0e|2021-11-03--11-08-42", HONDA.PASSPORT), - TestRoute("0a78dfbacc8504ef|2020-03-04--13-29-55", HONDA.CIVIC_BOSCH), - TestRoute("f34a60d68d83b1e5|2020-10-06--14-35-55", HONDA.ACURA_RDX), - TestRoute("54fd8451b3974762|2021-04-01--14-50-10", HONDA.RIDGELINE), - TestRoute("2d5808fae0b38ac6|2021-09-01--17-14-11", HONDA.HONDA_E), - TestRoute("f44aa96ace22f34a|2021-12-22--06-22-31", HONDA.CIVIC_2022), - - TestRoute("6fe86b4e410e4c37|2020-07-22--16-27-13", HYUNDAI.HYUNDAI_GENESIS), - TestRoute("70c5bec28ec8e345|2020-08-08--12-22-23", HYUNDAI.GENESIS_G70), - TestRoute("6b301bf83f10aa90|2020-11-22--16-45-07", HYUNDAI.GENESIS_G80), - TestRoute("4dbd55df87507948|2022-03-01--09-45-38", HYUNDAI.SANTA_FE), - TestRoute("bf43d9df2b660eb0|2021-09-23--14-16-37", HYUNDAI.SANTA_FE_2022), - TestRoute("37398f32561a23ad|2021-11-18--00-11-35", HYUNDAI.SANTA_FE_HEV_2022), - TestRoute("656ac0d830792fcc|2021-12-28--14-45-56", HYUNDAI.SANTA_FE_PHEV_2022, segment=1), - TestRoute("e0e98335f3ebc58f|2021-03-07--16-38-29", HYUNDAI.KIA_CEED), - TestRoute("7653b2bce7bcfdaa|2020-03-04--15-34-32", HYUNDAI.KIA_OPTIMA), - TestRoute("c75a59efa0ecd502|2021-03-11--20-52-55", HYUNDAI.KIA_SELTOS), - TestRoute("5b7c365c50084530|2020-04-15--16-13-24", HYUNDAI.SONATA), - TestRoute("b2a38c712dcf90bd|2020-05-18--18-12-48", HYUNDAI.SONATA_LF), - TestRoute("fb3fd42f0baaa2f8|2022-03-30--15-25-05", HYUNDAI.TUCSON), - TestRoute("36e10531feea61a4|2022-07-25--13-37-42", HYUNDAI.TUCSON_HYBRID_4TH_GEN), - TestRoute("5875672fc1d4bf57|2020-07-23--21-33-28", HYUNDAI.KIA_SORENTO), - TestRoute("9c917ba0d42ffe78|2020-04-17--12-43-19", HYUNDAI.PALISADE), - TestRoute("22de8111a8c5463c|2022-07-29--13-34-49", HYUNDAI.IONIQ_5), - TestRoute("3f29334d6134fcd4|2022-03-30--22-00-50", HYUNDAI.IONIQ_PHEV_2019), - TestRoute("fa8db5869167f821|2021-06-10--22-50-10", HYUNDAI.IONIQ_PHEV), - TestRoute("2c5cf2dd6102e5da|2020-12-17--16-06-44", HYUNDAI.IONIQ_EV_2020), - TestRoute("610ebb9faaad6b43|2020-06-13--15-28-36", HYUNDAI.IONIQ_EV_LTD), - TestRoute("2c5cf2dd6102e5da|2020-06-26--16-00-08", HYUNDAI.IONIQ), - TestRoute("ab59fe909f626921|2021-10-18--18-34-28", HYUNDAI.IONIQ_HEV_2022), - TestRoute("22d955b2cd499c22|2020-08-10--19-58-21", HYUNDAI.KONA), - TestRoute("efc48acf44b1e64d|2021-05-28--21-05-04", HYUNDAI.KONA_EV), - TestRoute("ff973b941a69366f|2022-07-28--22-01-19", HYUNDAI.KONA_EV_2022, segment=11), - TestRoute("49f3c13141b6bc87|2021-07-28--08-05-13", HYUNDAI.KONA_HEV), - TestRoute("5dddcbca6eb66c62|2020-07-26--13-24-19", HYUNDAI.KIA_STINGER), - TestRoute("d624b3d19adce635|2020-08-01--14-59-12", HYUNDAI.VELOSTER), - TestRoute("d824e27e8c60172c|2022-05-19--16-15-28", HYUNDAI.KIA_EV6), - TestRoute("007d5e4ad9f86d13|2021-09-30--15-09-23", HYUNDAI.KIA_K5_2021), - TestRoute("50c6c9b85fd1ff03|2020-10-26--17-56-06", HYUNDAI.KIA_NIRO_EV), - TestRoute("173219cf50acdd7b|2021-07-05--10-27-41", HYUNDAI.KIA_NIRO_PHEV), - TestRoute("34a875f29f69841a|2021-07-29--13-02-09", HYUNDAI.KIA_NIRO_HEV_2021), - TestRoute("50a2212c41f65c7b|2021-05-24--16-22-06", HYUNDAI.KIA_FORTE), - TestRoute("c5ac319aa9583f83|2021-06-01--18-18-31", HYUNDAI.ELANTRA), - TestRoute("82e9cdd3f43bf83e|2021-05-15--02-42-51", HYUNDAI.ELANTRA_2021), - TestRoute("715ac05b594e9c59|2021-06-20--16-21-07", HYUNDAI.ELANTRA_HEV_2021), - TestRoute("7120aa90bbc3add7|2021-08-02--07-12-31", HYUNDAI.SONATA_HYBRID), - TestRoute("715ac05b594e9c59|2021-10-27--23-24-56", HYUNDAI.GENESIS_G70_2020), - - TestRoute("00c829b1b7613dea|2021-06-24--09-10-10", TOYOTA.ALPHARD_TSS2), - TestRoute("912119ebd02c7a42|2022-03-19--07-24-50", TOYOTA.ALPHARDH_TSS2), - TestRoute("000cf3730200c71c|2021-05-24--10-42-05", TOYOTA.AVALON), - TestRoute("0bb588106852abb7|2021-05-26--12-22-01", TOYOTA.AVALON_2019), - TestRoute("87bef2930af86592|2021-05-30--09-40-54", TOYOTA.AVALONH_2019), - TestRoute("e9966711cfb04ce3|2022-01-11--07-59-43", TOYOTA.AVALON_TSS2), - TestRoute("eca1080a91720a54|2022-03-17--13-32-29", TOYOTA.AVALONH_TSS2), - TestRoute("6cdecc4728d4af37|2020-02-23--15-44-18", TOYOTA.CAMRY), - TestRoute("3456ad0cd7281b24|2020-12-13--17-45-56", TOYOTA.CAMRY_TSS2), - TestRoute("ffccc77938ddbc44|2021-01-04--16-55-41", TOYOTA.CAMRYH_TSS2), - TestRoute("54034823d30962f5|2021-05-24--06-37-34", TOYOTA.CAMRYH), - TestRoute("4e45c89c38e8ec4d|2021-05-02--02-49-28", TOYOTA.COROLLA), - TestRoute("5f5afb36036506e4|2019-05-14--02-09-54", TOYOTA.COROLLA_TSS2), - TestRoute("5ceff72287a5c86c|2019-10-19--10-59-02", TOYOTA.COROLLAH_TSS2), - TestRoute("d2525c22173da58b|2021-04-25--16-47-04", TOYOTA.PRIUS), - TestRoute("b14c5b4742e6fc85|2020-07-28--19-50-11", TOYOTA.RAV4), - TestRoute("32a7df20486b0f70|2020-02-06--16-06-50", TOYOTA.RAV4H), - TestRoute("cdf2f7de565d40ae|2019-04-25--03-53-41", TOYOTA.RAV4_TSS2), - TestRoute("a5c341bb250ca2f0|2022-05-18--16-05-17", TOYOTA.RAV4_TSS2_2022), - TestRoute("7e34a988419b5307|2019-12-18--19-13-30", TOYOTA.RAV4H_TSS2), - TestRoute("2475fb3eb2ffcc2e|2022-04-29--12-46-23", TOYOTA.RAV4H_TSS2_2022), - TestRoute("e6a24be49a6cd46e|2019-10-29--10-52-42", TOYOTA.LEXUS_ES_TSS2), - TestRoute("25057fa6a5a63dfb|2020-03-04--08-44-23", TOYOTA.LEXUS_CTH), - TestRoute("f49e8041283f2939|2019-05-30--11-51-51", TOYOTA.LEXUS_ESH_TSS2), - TestRoute("37041c500fd30100|2020-12-30--12-17-24", TOYOTA.LEXUS_ESH), - TestRoute("32696cea52831b02|2021-11-19--18-13-30", TOYOTA.LEXUS_RC), - TestRoute("886fcd8408d570e9|2020-01-29--05-11-22", TOYOTA.LEXUS_RX), - TestRoute("886fcd8408d570e9|2020-01-29--02-18-55", TOYOTA.LEXUS_RX), - TestRoute("d27ad752e9b08d4f|2021-05-26--19-39-51", TOYOTA.LEXUS_RXH), - TestRoute("01b22eb2ed121565|2020-02-02--11-25-51", TOYOTA.LEXUS_RX_TSS2), - TestRoute("b74758c690a49668|2020-05-20--15-58-57", TOYOTA.LEXUS_RXH_TSS2), - TestRoute("ec429c0f37564e3c|2020-02-01--17-28-12", TOYOTA.LEXUS_NXH), - TestRoute("964c09eb11ca8089|2020-11-03--22-04-00", TOYOTA.LEXUS_NX), - TestRoute("3fd5305f8b6ca765|2021-04-28--19-26-49", TOYOTA.LEXUS_NX_TSS2), - TestRoute("09ae96064ed85a14|2022-06-09--12-22-31", TOYOTA.LEXUS_NXH_TSS2), - TestRoute("0a302ffddbb3e3d3|2020-02-08--16-19-08", TOYOTA.HIGHLANDER_TSS2), - TestRoute("437e4d2402abf524|2021-05-25--07-58-50", TOYOTA.HIGHLANDERH_TSS2), - TestRoute("3183cd9b021e89ce|2021-05-25--10-34-44", TOYOTA.HIGHLANDER), - TestRoute("80d16a262e33d57f|2021-05-23--20-01-43", TOYOTA.HIGHLANDERH), - TestRoute("eb6acd681135480d|2019-06-20--20-00-00", TOYOTA.SIENNA), - TestRoute("2e07163a1ba9a780|2019-08-25--13-15-13", TOYOTA.LEXUS_IS), - TestRoute("0a0de17a1e6a2d15|2020-09-21--21-24-41", TOYOTA.PRIUS_TSS2), - TestRoute("9b36accae406390e|2021-03-30--10-41-38", TOYOTA.MIRAI), - TestRoute("cd9cff4b0b26c435|2021-05-13--15-12-39", TOYOTA.CHR), - TestRoute("57858ede0369a261|2021-05-18--20-34-20", TOYOTA.CHRH), - TestRoute("14623aae37e549f3|2021-10-24--01-20-49", TOYOTA.PRIUS_V), - - TestRoute("202c40641158a6e5|2021-09-21--09-43-24", VOLKSWAGEN.ARTEON_MK1), - TestRoute("2c68dda277d887ac|2021-05-11--15-22-20", VOLKSWAGEN.ATLAS_MK1), - TestRoute("cae14e88932eb364|2021-03-26--14-43-28", VOLKSWAGEN.GOLF_MK7), - TestRoute("58a7d3b707987d65|2021-03-25--17-26-37", VOLKSWAGEN.JETTA_MK7), - TestRoute("4d134e099430fba2|2021-03-26--00-26-06", VOLKSWAGEN.PASSAT_MK8), - TestRoute("3cfdec54aa035f3f|2022-07-19--23-45-10", VOLKSWAGEN.PASSAT_NMS), - TestRoute("0cd0b7f7e31a3853|2021-11-03--19-30-22", VOLKSWAGEN.POLO_MK6), - TestRoute("7d82b2f3a9115f1f|2021-10-21--15-39-42", VOLKSWAGEN.TAOS_MK1), - TestRoute("2744c89a8dda9a51|2021-07-24--21-28-06", VOLKSWAGEN.TCROSS_MK1), - TestRoute("2cef8a0b898f331a|2021-03-25--20-13-57", VOLKSWAGEN.TIGUAN_MK2), - TestRoute("a589dcc642fdb10a|2021-06-14--20-54-26", VOLKSWAGEN.TOURAN_MK2), - TestRoute("a459f4556782eba1|2021-09-19--09-48-00", VOLKSWAGEN.TRANSPORTER_T61), - TestRoute("0cd0b7f7e31a3853|2021-11-18--00-38-32", VOLKSWAGEN.TROC_MK1), - TestRoute("07667b885add75fd|2021-01-23--19-48-42", VOLKSWAGEN.AUDI_A3_MK3), - TestRoute("6c6b466346192818|2021-06-06--14-17-47", VOLKSWAGEN.AUDI_Q2_MK1), - TestRoute("0cd0b7f7e31a3853|2021-12-03--03-12-05", VOLKSWAGEN.AUDI_Q3_MK2), - TestRoute("8f205bdd11bcbb65|2021-03-26--01-00-17", VOLKSWAGEN.SEAT_ATECA_MK1), - TestRoute("fc6b6c9a3471c846|2021-05-27--13-39-56", VOLKSWAGEN.SEAT_LEON_MK3), - TestRoute("12d6ae3057c04b0d|2021-09-15--00-04-07", VOLKSWAGEN.SKODA_KAMIQ_MK1), - TestRoute("12d6ae3057c04b0d|2021-09-04--21-21-21", VOLKSWAGEN.SKODA_KAROQ_MK1), - TestRoute("90434ff5d7c8d603|2021-03-15--12-07-31", VOLKSWAGEN.SKODA_KODIAQ_MK1), - TestRoute("66e5edc3a16459c5|2021-05-25--19-00-29", VOLKSWAGEN.SKODA_OCTAVIA_MK3), - TestRoute("026b6d18fba6417f|2021-03-26--09-17-04", VOLKSWAGEN.SKODA_SCALA_MK1), - TestRoute("b2e9858e29db492b|2021-03-26--16-58-42", VOLKSWAGEN.SKODA_SUPERB_MK3), - - TestRoute("3c8f0c502e119c1c|2020-06-30--12-58-02", SUBARU.ASCENT), - TestRoute("c321c6b697c5a5ff|2020-06-23--11-04-33", SUBARU.FORESTER), - TestRoute("791340bc01ed993d|2019-03-10--16-28-08", SUBARU.IMPREZA), - TestRoute("8bf7e79a3ce64055|2021-05-24--09-36-27", SUBARU.IMPREZA_2020), - TestRoute("1bbe6bf2d62f58a8|2022-07-14--17-11-43", SUBARU.OUTBACK, segment=3), - TestRoute("c56e69bbc74b8fad|2022-08-18--09-43-51", SUBARU.LEGACY, segment=3), + CarTestRoute("7cc2a8365b4dd8a9|2018-12-02--12-10-44", GM.ACADIA), + CarTestRoute("aa20e335f61ba898|2019-02-05--16-59-04", GM.BUICK_REGAL), + CarTestRoute("46460f0da08e621e|2021-10-26--07-21-46", GM.ESCALADE_ESV), + CarTestRoute("c950e28c26b5b168|2018-05-30--22-03-41", GM.VOLT), + CarTestRoute("f08912a233c1584f|2022-08-11--18-02-41", GM.BOLT_EUV), + CarTestRoute("38aa7da107d5d252|2022-08-15--16-01-12", GM.SILVERADO), + + CarTestRoute("0e7a2ba168465df5|2020-10-18--14-14-22", HONDA.ACURA_RDX_3G), + CarTestRoute("a74b011b32b51b56|2020-07-26--17-09-36", HONDA.CIVIC), + CarTestRoute("a859a044a447c2b0|2020-03-03--18-42-45", HONDA.CRV_EU), + CarTestRoute("68aac44ad69f838e|2021-05-18--20-40-52", HONDA.CRV), + CarTestRoute("14fed2e5fa0aa1a5|2021-05-25--14-59-42", HONDA.CRV_HYBRID), + CarTestRoute("52f3e9ae60c0d886|2021-05-23--15-59-43", HONDA.FIT), + CarTestRoute("2c4292a5cd10536c|2021-08-19--21-32-15", HONDA.FREED), + CarTestRoute("03be5f2fd5c508d1|2020-04-19--18-44-15", HONDA.HRV), + CarTestRoute("917b074700869333|2021-05-24--20-40-20", HONDA.ACURA_ILX), + CarTestRoute("81722949a62ea724|2019-04-06--15-19-25", HONDA.ODYSSEY_CHN), + CarTestRoute("08a3deb07573f157|2020-03-06--16-11-19", HONDA.ACCORD), # 1.5T + CarTestRoute("1da5847ac2488106|2021-05-24--19-31-50", HONDA.ACCORD), # 2.0T + CarTestRoute("085ac1d942c35910|2021-03-25--20-11-15", HONDA.ACCORD), # 2021 with new style HUD msgs + CarTestRoute("07585b0da3c88459|2021-05-26--18-52-04", HONDA.ACCORDH), + CarTestRoute("f29e2b57a55e7ad5|2021-03-24--20-52-38", HONDA.ACCORDH), # 2021 with new style HUD msgs + CarTestRoute("1ad763dd22ef1a0e|2020-02-29--18-37-03", HONDA.CRV_5G), + CarTestRoute("0a96f86fcfe35964|2020-02-05--07-25-51", HONDA.ODYSSEY), + CarTestRoute("d83f36766f8012a5|2020-02-05--18-42-21", HONDA.CIVIC_BOSCH_DIESEL), + CarTestRoute("f0890d16a07a236b|2021-05-25--17-27-22", HONDA.INSIGHT), + CarTestRoute("07d37d27996096b6|2020-03-04--21-57-27", HONDA.PILOT), + CarTestRoute("684e8f96bd491a0e|2021-11-03--11-08-42", HONDA.PASSPORT), + CarTestRoute("0a78dfbacc8504ef|2020-03-04--13-29-55", HONDA.CIVIC_BOSCH), + CarTestRoute("f34a60d68d83b1e5|2020-10-06--14-35-55", HONDA.ACURA_RDX), + CarTestRoute("54fd8451b3974762|2021-04-01--14-50-10", HONDA.RIDGELINE), + CarTestRoute("2d5808fae0b38ac6|2021-09-01--17-14-11", HONDA.HONDA_E), + CarTestRoute("f44aa96ace22f34a|2021-12-22--06-22-31", HONDA.CIVIC_2022), + + CarTestRoute("6fe86b4e410e4c37|2020-07-22--16-27-13", HYUNDAI.HYUNDAI_GENESIS), + CarTestRoute("70c5bec28ec8e345|2020-08-08--12-22-23", HYUNDAI.GENESIS_G70), + CarTestRoute("6b301bf83f10aa90|2020-11-22--16-45-07", HYUNDAI.GENESIS_G80), + CarTestRoute("4dbd55df87507948|2022-03-01--09-45-38", HYUNDAI.SANTA_FE), + CarTestRoute("bf43d9df2b660eb0|2021-09-23--14-16-37", HYUNDAI.SANTA_FE_2022), + CarTestRoute("37398f32561a23ad|2021-11-18--00-11-35", HYUNDAI.SANTA_FE_HEV_2022), + CarTestRoute("656ac0d830792fcc|2021-12-28--14-45-56", HYUNDAI.SANTA_FE_PHEV_2022, segment=1), + CarTestRoute("e0e98335f3ebc58f|2021-03-07--16-38-29", HYUNDAI.KIA_CEED), + CarTestRoute("7653b2bce7bcfdaa|2020-03-04--15-34-32", HYUNDAI.KIA_OPTIMA), + CarTestRoute("c75a59efa0ecd502|2021-03-11--20-52-55", HYUNDAI.KIA_SELTOS), + CarTestRoute("5b7c365c50084530|2020-04-15--16-13-24", HYUNDAI.SONATA), + CarTestRoute("b2a38c712dcf90bd|2020-05-18--18-12-48", HYUNDAI.SONATA_LF), + CarTestRoute("fb3fd42f0baaa2f8|2022-03-30--15-25-05", HYUNDAI.TUCSON), + CarTestRoute("36e10531feea61a4|2022-07-25--13-37-42", HYUNDAI.TUCSON_HYBRID_4TH_GEN), + CarTestRoute("5875672fc1d4bf57|2020-07-23--21-33-28", HYUNDAI.KIA_SORENTO), + CarTestRoute("9c917ba0d42ffe78|2020-04-17--12-43-19", HYUNDAI.PALISADE), + CarTestRoute("22de8111a8c5463c|2022-07-29--13-34-49", HYUNDAI.IONIQ_5), + CarTestRoute("3f29334d6134fcd4|2022-03-30--22-00-50", HYUNDAI.IONIQ_PHEV_2019), + CarTestRoute("fa8db5869167f821|2021-06-10--22-50-10", HYUNDAI.IONIQ_PHEV), + CarTestRoute("2c5cf2dd6102e5da|2020-12-17--16-06-44", HYUNDAI.IONIQ_EV_2020), + CarTestRoute("610ebb9faaad6b43|2020-06-13--15-28-36", HYUNDAI.IONIQ_EV_LTD), + CarTestRoute("2c5cf2dd6102e5da|2020-06-26--16-00-08", HYUNDAI.IONIQ), + CarTestRoute("ab59fe909f626921|2021-10-18--18-34-28", HYUNDAI.IONIQ_HEV_2022), + CarTestRoute("22d955b2cd499c22|2020-08-10--19-58-21", HYUNDAI.KONA), + CarTestRoute("efc48acf44b1e64d|2021-05-28--21-05-04", HYUNDAI.KONA_EV), + CarTestRoute("ff973b941a69366f|2022-07-28--22-01-19", HYUNDAI.KONA_EV_2022, segment=11), + CarTestRoute("49f3c13141b6bc87|2021-07-28--08-05-13", HYUNDAI.KONA_HEV), + CarTestRoute("5dddcbca6eb66c62|2020-07-26--13-24-19", HYUNDAI.KIA_STINGER), + CarTestRoute("d624b3d19adce635|2020-08-01--14-59-12", HYUNDAI.VELOSTER), + CarTestRoute("d824e27e8c60172c|2022-05-19--16-15-28", HYUNDAI.KIA_EV6), + CarTestRoute("007d5e4ad9f86d13|2021-09-30--15-09-23", HYUNDAI.KIA_K5_2021), + CarTestRoute("50c6c9b85fd1ff03|2020-10-26--17-56-06", HYUNDAI.KIA_NIRO_EV), + CarTestRoute("173219cf50acdd7b|2021-07-05--10-27-41", HYUNDAI.KIA_NIRO_PHEV), + CarTestRoute("34a875f29f69841a|2021-07-29--13-02-09", HYUNDAI.KIA_NIRO_HEV_2021), + CarTestRoute("50a2212c41f65c7b|2021-05-24--16-22-06", HYUNDAI.KIA_FORTE), + CarTestRoute("c5ac319aa9583f83|2021-06-01--18-18-31", HYUNDAI.ELANTRA), + CarTestRoute("82e9cdd3f43bf83e|2021-05-15--02-42-51", HYUNDAI.ELANTRA_2021), + CarTestRoute("715ac05b594e9c59|2021-06-20--16-21-07", HYUNDAI.ELANTRA_HEV_2021), + CarTestRoute("7120aa90bbc3add7|2021-08-02--07-12-31", HYUNDAI.SONATA_HYBRID), + CarTestRoute("715ac05b594e9c59|2021-10-27--23-24-56", HYUNDAI.GENESIS_G70_2020), + + CarTestRoute("00c829b1b7613dea|2021-06-24--09-10-10", TOYOTA.ALPHARD_TSS2), + CarTestRoute("912119ebd02c7a42|2022-03-19--07-24-50", TOYOTA.ALPHARDH_TSS2), + CarTestRoute("000cf3730200c71c|2021-05-24--10-42-05", TOYOTA.AVALON), + CarTestRoute("0bb588106852abb7|2021-05-26--12-22-01", TOYOTA.AVALON_2019), + CarTestRoute("87bef2930af86592|2021-05-30--09-40-54", TOYOTA.AVALONH_2019), + CarTestRoute("e9966711cfb04ce3|2022-01-11--07-59-43", TOYOTA.AVALON_TSS2), + CarTestRoute("eca1080a91720a54|2022-03-17--13-32-29", TOYOTA.AVALONH_TSS2), + CarTestRoute("6cdecc4728d4af37|2020-02-23--15-44-18", TOYOTA.CAMRY), + CarTestRoute("3456ad0cd7281b24|2020-12-13--17-45-56", TOYOTA.CAMRY_TSS2), + CarTestRoute("ffccc77938ddbc44|2021-01-04--16-55-41", TOYOTA.CAMRYH_TSS2), + CarTestRoute("54034823d30962f5|2021-05-24--06-37-34", TOYOTA.CAMRYH), + CarTestRoute("4e45c89c38e8ec4d|2021-05-02--02-49-28", TOYOTA.COROLLA), + CarTestRoute("5f5afb36036506e4|2019-05-14--02-09-54", TOYOTA.COROLLA_TSS2), + CarTestRoute("5ceff72287a5c86c|2019-10-19--10-59-02", TOYOTA.COROLLAH_TSS2), + CarTestRoute("d2525c22173da58b|2021-04-25--16-47-04", TOYOTA.PRIUS), + CarTestRoute("b14c5b4742e6fc85|2020-07-28--19-50-11", TOYOTA.RAV4), + CarTestRoute("32a7df20486b0f70|2020-02-06--16-06-50", TOYOTA.RAV4H), + CarTestRoute("cdf2f7de565d40ae|2019-04-25--03-53-41", TOYOTA.RAV4_TSS2), + CarTestRoute("a5c341bb250ca2f0|2022-05-18--16-05-17", TOYOTA.RAV4_TSS2_2022), + CarTestRoute("7e34a988419b5307|2019-12-18--19-13-30", TOYOTA.RAV4H_TSS2), + CarTestRoute("2475fb3eb2ffcc2e|2022-04-29--12-46-23", TOYOTA.RAV4H_TSS2_2022), + CarTestRoute("e6a24be49a6cd46e|2019-10-29--10-52-42", TOYOTA.LEXUS_ES_TSS2), + CarTestRoute("25057fa6a5a63dfb|2020-03-04--08-44-23", TOYOTA.LEXUS_CTH), + CarTestRoute("f49e8041283f2939|2019-05-30--11-51-51", TOYOTA.LEXUS_ESH_TSS2), + CarTestRoute("37041c500fd30100|2020-12-30--12-17-24", TOYOTA.LEXUS_ESH), + CarTestRoute("32696cea52831b02|2021-11-19--18-13-30", TOYOTA.LEXUS_RC), + CarTestRoute("886fcd8408d570e9|2020-01-29--05-11-22", TOYOTA.LEXUS_RX), + CarTestRoute("886fcd8408d570e9|2020-01-29--02-18-55", TOYOTA.LEXUS_RX), + CarTestRoute("d27ad752e9b08d4f|2021-05-26--19-39-51", TOYOTA.LEXUS_RXH), + CarTestRoute("01b22eb2ed121565|2020-02-02--11-25-51", TOYOTA.LEXUS_RX_TSS2), + CarTestRoute("b74758c690a49668|2020-05-20--15-58-57", TOYOTA.LEXUS_RXH_TSS2), + CarTestRoute("ec429c0f37564e3c|2020-02-01--17-28-12", TOYOTA.LEXUS_NXH), + CarTestRoute("964c09eb11ca8089|2020-11-03--22-04-00", TOYOTA.LEXUS_NX), + CarTestRoute("3fd5305f8b6ca765|2021-04-28--19-26-49", TOYOTA.LEXUS_NX_TSS2), + CarTestRoute("09ae96064ed85a14|2022-06-09--12-22-31", TOYOTA.LEXUS_NXH_TSS2), + CarTestRoute("0a302ffddbb3e3d3|2020-02-08--16-19-08", TOYOTA.HIGHLANDER_TSS2), + CarTestRoute("437e4d2402abf524|2021-05-25--07-58-50", TOYOTA.HIGHLANDERH_TSS2), + CarTestRoute("3183cd9b021e89ce|2021-05-25--10-34-44", TOYOTA.HIGHLANDER), + CarTestRoute("80d16a262e33d57f|2021-05-23--20-01-43", TOYOTA.HIGHLANDERH), + CarTestRoute("eb6acd681135480d|2019-06-20--20-00-00", TOYOTA.SIENNA), + CarTestRoute("2e07163a1ba9a780|2019-08-25--13-15-13", TOYOTA.LEXUS_IS), + CarTestRoute("0a0de17a1e6a2d15|2020-09-21--21-24-41", TOYOTA.PRIUS_TSS2), + CarTestRoute("9b36accae406390e|2021-03-30--10-41-38", TOYOTA.MIRAI), + CarTestRoute("cd9cff4b0b26c435|2021-05-13--15-12-39", TOYOTA.CHR), + CarTestRoute("57858ede0369a261|2021-05-18--20-34-20", TOYOTA.CHRH), + CarTestRoute("14623aae37e549f3|2021-10-24--01-20-49", TOYOTA.PRIUS_V), + + CarTestRoute("202c40641158a6e5|2021-09-21--09-43-24", VOLKSWAGEN.ARTEON_MK1), + CarTestRoute("2c68dda277d887ac|2021-05-11--15-22-20", VOLKSWAGEN.ATLAS_MK1), + CarTestRoute("cae14e88932eb364|2021-03-26--14-43-28", VOLKSWAGEN.GOLF_MK7), + CarTestRoute("58a7d3b707987d65|2021-03-25--17-26-37", VOLKSWAGEN.JETTA_MK7), + CarTestRoute("4d134e099430fba2|2021-03-26--00-26-06", VOLKSWAGEN.PASSAT_MK8), + CarTestRoute("3cfdec54aa035f3f|2022-07-19--23-45-10", VOLKSWAGEN.PASSAT_NMS), + CarTestRoute("0cd0b7f7e31a3853|2021-11-03--19-30-22", VOLKSWAGEN.POLO_MK6), + CarTestRoute("7d82b2f3a9115f1f|2021-10-21--15-39-42", VOLKSWAGEN.TAOS_MK1), + CarTestRoute("2744c89a8dda9a51|2021-07-24--21-28-06", VOLKSWAGEN.TCROSS_MK1), + CarTestRoute("2cef8a0b898f331a|2021-03-25--20-13-57", VOLKSWAGEN.TIGUAN_MK2), + CarTestRoute("a589dcc642fdb10a|2021-06-14--20-54-26", VOLKSWAGEN.TOURAN_MK2), + CarTestRoute("a459f4556782eba1|2021-09-19--09-48-00", VOLKSWAGEN.TRANSPORTER_T61), + CarTestRoute("0cd0b7f7e31a3853|2021-11-18--00-38-32", VOLKSWAGEN.TROC_MK1), + CarTestRoute("07667b885add75fd|2021-01-23--19-48-42", VOLKSWAGEN.AUDI_A3_MK3), + CarTestRoute("6c6b466346192818|2021-06-06--14-17-47", VOLKSWAGEN.AUDI_Q2_MK1), + CarTestRoute("0cd0b7f7e31a3853|2021-12-03--03-12-05", VOLKSWAGEN.AUDI_Q3_MK2), + CarTestRoute("8f205bdd11bcbb65|2021-03-26--01-00-17", VOLKSWAGEN.SEAT_ATECA_MK1), + CarTestRoute("fc6b6c9a3471c846|2021-05-27--13-39-56", VOLKSWAGEN.SEAT_LEON_MK3), + CarTestRoute("12d6ae3057c04b0d|2021-09-15--00-04-07", VOLKSWAGEN.SKODA_KAMIQ_MK1), + CarTestRoute("12d6ae3057c04b0d|2021-09-04--21-21-21", VOLKSWAGEN.SKODA_KAROQ_MK1), + CarTestRoute("90434ff5d7c8d603|2021-03-15--12-07-31", VOLKSWAGEN.SKODA_KODIAQ_MK1), + CarTestRoute("66e5edc3a16459c5|2021-05-25--19-00-29", VOLKSWAGEN.SKODA_OCTAVIA_MK3), + CarTestRoute("026b6d18fba6417f|2021-03-26--09-17-04", VOLKSWAGEN.SKODA_SCALA_MK1), + CarTestRoute("b2e9858e29db492b|2021-03-26--16-58-42", VOLKSWAGEN.SKODA_SUPERB_MK3), + + CarTestRoute("3c8f0c502e119c1c|2020-06-30--12-58-02", SUBARU.ASCENT), + CarTestRoute("c321c6b697c5a5ff|2020-06-23--11-04-33", SUBARU.FORESTER), + CarTestRoute("791340bc01ed993d|2019-03-10--16-28-08", SUBARU.IMPREZA), + CarTestRoute("8bf7e79a3ce64055|2021-05-24--09-36-27", SUBARU.IMPREZA_2020), + CarTestRoute("1bbe6bf2d62f58a8|2022-07-14--17-11-43", SUBARU.OUTBACK, segment=3), + CarTestRoute("c56e69bbc74b8fad|2022-08-18--09-43-51", SUBARU.LEGACY, segment=3), # Pre-global, dashcam - TestRoute("95441c38ae8c130e|2020-06-08--12-10-17", SUBARU.FORESTER_PREGLOBAL), - TestRoute("df5ca7660000fba8|2020-06-16--17-37-19", SUBARU.LEGACY_PREGLOBAL), - TestRoute("5ab784f361e19b78|2020-06-08--16-30-41", SUBARU.OUTBACK_PREGLOBAL), - TestRoute("e19eb5d5353b1ac1|2020-08-09--14-37-56", SUBARU.OUTBACK_PREGLOBAL_2018), - - TestRoute("fbbfa6af821552b9|2020-03-03--08-09-43", NISSAN.XTRAIL), - TestRoute("5b7c365c50084530|2020-03-25--22-10-13", NISSAN.LEAF), - TestRoute("22c3dcce2dd627eb|2020-12-30--16-38-48", NISSAN.LEAF_IC), - TestRoute("059ab9162e23198e|2020-05-30--09-41-01", NISSAN.ROGUE), - TestRoute("b72d3ec617c0a90f|2020-12-11--15-38-17", NISSAN.ALTIMA), - - TestRoute("32a319f057902bb3|2020-04-27--15-18-58", MAZDA.CX5), - TestRoute("10b5a4b380434151|2020-08-26--17-11-45", MAZDA.CX9), - TestRoute("74f1038827005090|2020-08-26--20-05-50", MAZDA.MAZDA3), - TestRoute("fb53c640f499b73d|2021-06-01--04-17-56", MAZDA.MAZDA6), - TestRoute("f6d5b1a9d7a1c92e|2021-07-08--06-56-59", MAZDA.CX9_2021), - TestRoute("a4af1602d8e668ac|2022-02-03--12-17-07", MAZDA.CX5_2022), - - TestRoute("6c14ee12b74823ce|2021-06-30--11-49-02", TESLA.AP1_MODELS), - TestRoute("bb50caf5f0945ab1|2021-06-19--17-20-18", TESLA.AP2_MODELS), + CarTestRoute("95441c38ae8c130e|2020-06-08--12-10-17", SUBARU.FORESTER_PREGLOBAL), + CarTestRoute("df5ca7660000fba8|2020-06-16--17-37-19", SUBARU.LEGACY_PREGLOBAL), + CarTestRoute("5ab784f361e19b78|2020-06-08--16-30-41", SUBARU.OUTBACK_PREGLOBAL), + CarTestRoute("e19eb5d5353b1ac1|2020-08-09--14-37-56", SUBARU.OUTBACK_PREGLOBAL_2018), + + CarTestRoute("fbbfa6af821552b9|2020-03-03--08-09-43", NISSAN.XTRAIL), + CarTestRoute("5b7c365c50084530|2020-03-25--22-10-13", NISSAN.LEAF), + CarTestRoute("22c3dcce2dd627eb|2020-12-30--16-38-48", NISSAN.LEAF_IC), + CarTestRoute("059ab9162e23198e|2020-05-30--09-41-01", NISSAN.ROGUE), + CarTestRoute("b72d3ec617c0a90f|2020-12-11--15-38-17", NISSAN.ALTIMA), + + CarTestRoute("32a319f057902bb3|2020-04-27--15-18-58", MAZDA.CX5), + CarTestRoute("10b5a4b380434151|2020-08-26--17-11-45", MAZDA.CX9), + CarTestRoute("74f1038827005090|2020-08-26--20-05-50", MAZDA.MAZDA3), + CarTestRoute("fb53c640f499b73d|2021-06-01--04-17-56", MAZDA.MAZDA6), + CarTestRoute("f6d5b1a9d7a1c92e|2021-07-08--06-56-59", MAZDA.CX9_2021), + CarTestRoute("a4af1602d8e668ac|2022-02-03--12-17-07", MAZDA.CX5_2022), + + CarTestRoute("6c14ee12b74823ce|2021-06-30--11-49-02", TESLA.AP1_MODELS), + CarTestRoute("bb50caf5f0945ab1|2021-06-19--17-20-18", TESLA.AP2_MODELS), # Segments that test specific issues # Controls mismatch due to interceptor threshold - TestRoute("cfb32f0fb91b173b|2022-04-06--14-54-45", HONDA.CIVIC, segment=21), - TestRoute("5a8762b91fc70467|2022-04-14--21-26-20", TOYOTA.RAV4, segment=2), + CarTestRoute("cfb32f0fb91b173b|2022-04-06--14-54-45", HONDA.CIVIC, segment=21), + CarTestRoute("5a8762b91fc70467|2022-04-14--21-26-20", TOYOTA.RAV4, segment=2), # Controls mismatch due to standstill threshold - TestRoute("bec2dcfde6a64235|2022-04-08--14-21-32", HONDA.CRV_HYBRID, segment=22), + CarTestRoute("bec2dcfde6a64235|2022-04-08--14-21-32", HONDA.CRV_HYBRID, segment=22), ] diff --git a/selfdrive/car/tests/test_models.py b/selfdrive/car/tests/test_models.py index 6e88e227cc3abc..502df3fe3f1524 100755 --- a/selfdrive/car/tests/test_models.py +++ b/selfdrive/car/tests/test_models.py @@ -15,7 +15,7 @@ from selfdrive.car.gm.values import CAR as GM from selfdrive.car.honda.values import CAR as HONDA, HONDA_BOSCH from selfdrive.car.hyundai.values import CAR as HYUNDAI -from selfdrive.car.tests.routes import non_tested_cars, routes, TestRoute +from selfdrive.car.tests.routes import non_tested_cars, routes, CarTestRoute from selfdrive.test.openpilotci import get_url from tools.lib.logreader import LogReader from tools.lib.route import Route @@ -38,7 +38,7 @@ for r in routes: routes_by_car[r.car_model].add(r) -test_cases: List[Tuple[str, Optional[TestRoute]]] = [] +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((c, r) for r in routes_by_car.get(c, (None, ))) diff --git a/selfdrive/debug/test_car_model.py b/selfdrive/debug/test_car_model.py index 9082dbe3d6b4e2..4de5b267628810 100755 --- a/selfdrive/debug/test_car_model.py +++ b/selfdrive/debug/test_car_model.py @@ -4,11 +4,11 @@ from typing import List, Tuple import unittest -from selfdrive.car.tests.routes import TestRoute +from selfdrive.car.tests.routes import CarTestRoute from selfdrive.car.tests.test_models import TestCarModel -def create_test_models_suite(routes: List[Tuple[str, TestRoute]], ci=False) -> unittest.TestSuite: +def create_test_models_suite(routes: List[Tuple[str, CarTestRoute]], ci=False) -> unittest.TestSuite: test_suite = unittest.TestSuite() for car_model, test_route in routes: # create new test case and discover tests @@ -30,7 +30,7 @@ def create_test_models_suite(routes: List[Tuple[str, TestRoute]], ci=False) -> u parser.print_help() sys.exit() - test_route = TestRoute(args.route, args.car, segment=args.segment) + test_route = CarTestRoute(args.route, args.car, segment=args.segment) test_suite = create_test_models_suite([(args.car, test_route)], ci=args.ci) unittest.TextTestRunner().run(test_suite) From 2f604d2f1a53ebecac02612a30d16566bb7e0a74 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 23 Aug 2022 17:29:03 -0700 Subject: [PATCH 100/106] bump version to 0.8.17 --- RELEASES.md | 3 +++ common/version.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index a6ba4558e7060f..3ac6c8e41dfe69 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,6 @@ +Version 0.8.17 (2022-XX-XX) +======================== + Version 0.8.16 (2022-08-26) ======================== * New driving model diff --git a/common/version.h b/common/version.h index bf1c58df1e2920..0a109c1faac060 100644 --- a/common/version.h +++ b/common/version.h @@ -1 +1 @@ -#define COMMA_VERSION "0.8.16" +#define COMMA_VERSION "0.8.17" From 70f7340c173f0a4b0d3bb98dda9032cd304f890e Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Tue, 23 Aug 2022 17:48:34 -0700 Subject: [PATCH 101/106] Toyota: log stockAeb on non-TSS2 cars (#25489) * check PRE_COLLISION * need to make sure this is right * revert * temp, stash * fixes * uncomment that * it's not really cruise/pcm, but acc remove improt * revert * Fix CI * revert exception * Revert "revert exception" This reverts commit 7e2f39097651f17cf3d2ac9f442fab5071e1b9d0. * this tested enableDsu, but we have other routes that do that * use segment from db * remove exception again --- selfdrive/car/tests/routes.py | 3 +-- selfdrive/car/toyota/carstate.py | 38 ++++++++++++++++++-------------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py index a47a3447e2c5f7..b769cbe5f7086a 100644 --- a/selfdrive/car/tests/routes.py +++ b/selfdrive/car/tests/routes.py @@ -140,11 +140,10 @@ CarTestRoute("7e34a988419b5307|2019-12-18--19-13-30", TOYOTA.RAV4H_TSS2), CarTestRoute("2475fb3eb2ffcc2e|2022-04-29--12-46-23", TOYOTA.RAV4H_TSS2_2022), CarTestRoute("e6a24be49a6cd46e|2019-10-29--10-52-42", TOYOTA.LEXUS_ES_TSS2), - CarTestRoute("25057fa6a5a63dfb|2020-03-04--08-44-23", TOYOTA.LEXUS_CTH), + CarTestRoute("da23c367491f53e2|2021-05-21--09-09-11", TOYOTA.LEXUS_CTH, segment=3), CarTestRoute("f49e8041283f2939|2019-05-30--11-51-51", TOYOTA.LEXUS_ESH_TSS2), CarTestRoute("37041c500fd30100|2020-12-30--12-17-24", TOYOTA.LEXUS_ESH), CarTestRoute("32696cea52831b02|2021-11-19--18-13-30", TOYOTA.LEXUS_RC), - CarTestRoute("886fcd8408d570e9|2020-01-29--05-11-22", TOYOTA.LEXUS_RX), CarTestRoute("886fcd8408d570e9|2020-01-29--02-18-55", TOYOTA.LEXUS_RX), CarTestRoute("d27ad752e9b08d4f|2021-05-26--19-39-51", TOYOTA.LEXUS_RXH), CarTestRoute("01b22eb2ed121565|2020-02-02--11-25-51", TOYOTA.LEXUS_RX_TSS2), diff --git a/selfdrive/car/toyota/carstate.py b/selfdrive/car/toyota/carstate.py index 537915919c39eb..843e7806dc9bba 100644 --- a/selfdrive/car/toyota/carstate.py +++ b/selfdrive/car/toyota/carstate.py @@ -94,12 +94,11 @@ def update(self, cp, cp_cam): ret.cruiseState.available = cp.vl["PCM_CRUISE_2"]["MAIN_ON"] != 0 ret.cruiseState.speed = cp.vl["PCM_CRUISE_2"]["SET_SPEED"] * CV.KPH_TO_MS - if self.CP.carFingerprint in RADAR_ACC_CAR: - self.acc_type = cp.vl["ACC_CONTROL"]["ACC_TYPE"] - ret.stockFcw = bool(cp.vl["ACC_HUD"]["FCW"]) - elif self.CP.carFingerprint in TSS2_CAR: - self.acc_type = cp_cam.vl["ACC_CONTROL"]["ACC_TYPE"] - ret.stockFcw = bool(cp_cam.vl["ACC_HUD"]["FCW"]) + cp_acc = cp_cam if self.CP.carFingerprint in (TSS2_CAR - RADAR_ACC_CAR) else cp + + if self.CP.carFingerprint in (TSS2_CAR | RADAR_ACC_CAR): + self.acc_type = cp_acc.vl["ACC_CONTROL"]["ACC_TYPE"] + ret.stockFcw = bool(cp_acc.vl["ACC_HUD"]["FCW"]) # some TSS2 cars have low speed lockout permanently set, so ignore on those cars # these cars are identified by an ACC_TYPE value of 2. @@ -120,10 +119,11 @@ def update(self, cp, cp_cam): ret.cruiseState.nonAdaptive = cp.vl["PCM_CRUISE"]["CRUISE_STATE"] in (1, 2, 3, 4, 5, 6) ret.genericToggle = bool(cp.vl["LIGHT_STALK"]["AUTO_HIGH_BEAM"]) - ret.stockAeb = bool(cp_cam.vl["PRE_COLLISION"]["PRECOLLISION_ACTIVE"] and cp_cam.vl["PRE_COLLISION"]["FORCE"] < -1e-5) - ret.espDisabled = cp.vl["ESP_CONTROL"]["TC_DISABLED"] != 0 + if not self.CP.enableDsu: + ret.stockAeb = bool(cp_acc.vl["PRE_COLLISION"]["PRECOLLISION_ACTIVE"] and cp_acc.vl["PRE_COLLISION"]["FORCE"] < -1e-5) + if self.CP.enableBsm: ret.leftBlindspot = (cp.vl["BSM"]["L_ADJACENT"] == 1) or (cp.vl["BSM"]["L_APPROACHING"] == 1) ret.rightBlindspot = (cp.vl["BSM"]["R_ADJACENT"] == 1) or (cp.vl["BSM"]["R_APPROACHING"] == 1) @@ -219,25 +219,31 @@ def get_can_parser(CP): ("ACC_HUD", 1), ] + if CP.carFingerprint not in (TSS2_CAR - RADAR_ACC_CAR) and not CP.enableDsu: + signals += [ + ("FORCE", "PRE_COLLISION"), + ("PRECOLLISION_ACTIVE", "PRE_COLLISION"), + ] + checks += [ + ("PRE_COLLISION", 33), + ] + return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, 0) @staticmethod def get_cam_can_parser(CP): - signals = [ - ("FORCE", "PRE_COLLISION"), - ("PRECOLLISION_ACTIVE", "PRE_COLLISION"), - ] - - checks = [ - ("PRE_COLLISION", 0), # TODO: figure out why freq is inconsistent - ] + signals = [] + checks = [] if CP.carFingerprint in (TSS2_CAR - RADAR_ACC_CAR): signals += [ + ("PRECOLLISION_ACTIVE", "PRE_COLLISION"), + ("FORCE", "PRE_COLLISION"), ("ACC_TYPE", "ACC_CONTROL"), ("FCW", "ACC_HUD"), ] checks += [ + ("PRE_COLLISION", 33), ("ACC_CONTROL", 33), ("ACC_HUD", 1), ] From 405e6c046d45d2f15cf9a111ae84f7e6dd2b2f85 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Thu, 25 Aug 2022 02:03:12 +0800 Subject: [PATCH 102/106] CameraBuf: remove unused cur_rgb_buf (#25544) rm cur_rgb_buf --- system/camerad/cameras/camera_common.h | 1 - 1 file changed, 1 deletion(-) diff --git a/system/camerad/cameras/camera_common.h b/system/camerad/cameras/camera_common.h index 2a56052559be95..198efca0bb3f8f 100644 --- a/system/camerad/cameras/camera_common.h +++ b/system/camerad/cameras/camera_common.h @@ -94,7 +94,6 @@ class CameraBuf { public: cl_command_queue q; FrameMetadata cur_frame_data; - VisionBuf *cur_rgb_buf; VisionBuf *cur_yuv_buf; VisionBuf *cur_camera_buf; std::unique_ptr camera_bufs; From f95519cb440ab25e24f14c12d37da535646d8419 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Thu, 25 Aug 2022 02:03:54 +0800 Subject: [PATCH 103/106] replay/CameraServer: yuv_buf should not be null (#25545) --- tools/replay/camera.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/replay/camera.cc b/tools/replay/camera.cc index 87afe63a2af64e..1a577b40cefa00 100644 --- a/tools/replay/camera.cc +++ b/tools/replay/camera.cc @@ -37,7 +37,8 @@ void CameraServer::startVipcServer() { void CameraServer::cameraThread(Camera &cam) { auto read_frame = [&](FrameReader *fr, int frame_id) { VisionBuf *yuv_buf = vipc_server_->get_buffer(cam.stream_type); - bool ret = fr->get(frame_id, yuv_buf ? (uint8_t *)yuv_buf->addr : nullptr); + assert(yuv_buf); + bool ret = fr->get(frame_id, (uint8_t *)yuv_buf->addr); return ret ? yuv_buf : nullptr; }; From c62447c7843141e426b24f71b7d7c5488aaf8c5d Mon Sep 17 00:00:00 2001 From: Jeroen Date: Wed, 24 Aug 2022 20:16:17 +0200 Subject: [PATCH 104/106] Fix broken url in translations README (#25546) Fix url in README.md --- selfdrive/ui/translations/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/ui/translations/README.md b/selfdrive/ui/translations/README.md index ac3112c61af3fb..91a6c3ca2f40c4 100644 --- a/selfdrive/ui/translations/README.md +++ b/selfdrive/ui/translations/README.md @@ -8,7 +8,7 @@ Before getting started, make sure you have set up the openpilot Ubuntu developme ### Policy -Most of the languages supported by openpilot come from and are maintained by the community via pull requests. A pull request likely to be merged is one that [fixes a translation or adds missing translations.](https://github.com/commaai/openpilot/blob/lang-policy/selfdrive/ui/translations/README.md#improving-an-existing-language) +Most of the languages supported by openpilot come from and are maintained by the community via pull requests. A pull request likely to be merged is one that [fixes a translation or adds missing translations.](https://github.com/commaai/openpilot/blob/master/selfdrive/ui/translations/README.md#improving-an-existing-language) We also generally merge pull requests adding support for a new language if there are community members willing to maintain it. Maintaining a language is ensuring quality and completion of translations before each openpilot release. From 70f2891928a3b7b89d19d57dfd7f1197806e2204 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Wed, 24 Aug 2022 16:06:11 -0700 Subject: [PATCH 105/106] Chrysler: whitelist FPv2 queries (#25549) * Add whitelist to Chrysler queries * gateway will respond to both (same 29-bit rx addr) * missing esp --- selfdrive/car/fw_versions.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/selfdrive/car/fw_versions.py b/selfdrive/car/fw_versions.py index 9d2fd11b4550d6..66a19a610d640d 100755 --- a/selfdrive/car/fw_versions.py +++ b/selfdrive/car/fw_versions.py @@ -208,12 +208,14 @@ class Request: "chrysler", [CHRYSLER_VERSION_REQUEST], [CHRYSLER_VERSION_RESPONSE], + whitelist_ecus=[Ecu.esp, Ecu.eps, Ecu.srs, Ecu.gateway, Ecu.fwdRadar, Ecu.fwdCamera, Ecu.combinationMeter], rx_offset=CHRYSLER_RX_OFFSET, ), Request( "chrysler", [CHRYSLER_VERSION_REQUEST], [CHRYSLER_VERSION_RESPONSE], + whitelist_ecus=[Ecu.engine, Ecu.transmission], ), # Ford Request( From 2f46fe5d856be0637cb55e460ea3f2d34be1703c Mon Sep 17 00:00:00 2001 From: HaraldSchafer Date: Thu, 25 Aug 2022 00:01:21 -0700 Subject: [PATCH 106/106] Nuclear Grade Model: less memory, more accuracy (#25524) * c9d10c64-bea4-41ec-8ca3-d8c886fda172/440 6d1c8a6b-4070-4780-80f1-6f08f234275e/900 * update ref --- selfdrive/modeld/models/supercombo.dlc | 2 +- selfdrive/modeld/models/supercombo.onnx | 4 ++-- selfdrive/test/process_replay/model_replay_ref_commit | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/selfdrive/modeld/models/supercombo.dlc b/selfdrive/modeld/models/supercombo.dlc index fe3ad510211f29..fe133523fc20b8 100644 --- a/selfdrive/modeld/models/supercombo.dlc +++ b/selfdrive/modeld/models/supercombo.dlc @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3c5c8d71a8a1434ef79073362e608b9fe02f22ce7478f11bc71c6806c1e00091 +oid sha256:93d265fc88f05746ce47257e15fc2afe43b250b44715313049f829e8aa30a9d6 size 94302331 diff --git a/selfdrive/modeld/models/supercombo.onnx b/selfdrive/modeld/models/supercombo.onnx index 39e8743642aef7..7b11edbe0800ad 100644 --- a/selfdrive/modeld/models/supercombo.onnx +++ b/selfdrive/modeld/models/supercombo.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:15d9eb01edd98998abceaa092d33fab149ff4a8942646b20a7c1403f999f4eca -size 95165081 +oid sha256:50c7fc8565ac69a4b9a0de122e961326820e78bf13659255a89d0ed04be030d5 +size 95167481 diff --git a/selfdrive/test/process_replay/model_replay_ref_commit b/selfdrive/test/process_replay/model_replay_ref_commit index e5bbfa74c25098..80be9b464f5ca5 100644 --- a/selfdrive/test/process_replay/model_replay_ref_commit +++ b/selfdrive/test/process_replay/model_replay_ref_commit @@ -1 +1 @@ -507241e0a41ee757cca4eb6ff12cff3f02c0b98a +ca90e11f8d59902af38d3785ddd91a27d0fbb411