From 31a6b141d6c37d7241146a9dc7b3a10313abdc40 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Wed, 16 Mar 2022 21:27:05 -0700 Subject: [PATCH] Docs: auto-generate supported cars documentation (#23762) * make CAR class enum, and values.py formatting * Revert "make CAR class enum, and values.py formatting" This reverts commit 04d9817e9d5d6ab5c027754018fc445f2cd3067a. * stash * add supported packages and model years * don't change model years in fps * move Lexus to info dict and make int enum * remove sometimes wrong model years from name string * use enum names * convert Honda's values * nice names * use name * GM * Mazda, Ford * Hyundai: WIP * finish Hyundai * fix * Nissan * Subaru * Tesla * formatting is for another PR * Chrysler: todo: unify the Pacificas? * do volkswagen * this isn't a zoo * skip enums for now * Update selfdrive/car/volkswagen/values.py Co-authored-by: Jason Young <46612682+jyoung8607@users.noreply.github.com> * set All * temp cars * auto-generate CARS.md * update type hinting * add generated file * add longitudinal star to cars that support disabling radar * add TODO * add notes * add min_steer_speed exception for hatchback * add minimum steering speeds * Add exceptions and run generator * Missing Telluride * fix Prius v * missing Prius Prime generate * start to convert years to strings * Fixup Hyundai * convert year sets to strings * handle this * missing S3 * Fix and add all missing cars (verified with script * Supported Package fixes * add get_tiered_cars * Check radarOffCan for removing most Honda from op long * Update for Avalon stop and go update on master * Fix missing car params * add my temporary script i'm using to verify new generated DBC add my temporary script i'm using to verify new generated DBC * generate with jinja template * add header and footer * clean up * rename rename * add exceptions. jinja is nice, but why are its loop indexes starting at 1? * add list of known car videos * See how these look * Add nice table formatting for column description Add nice table formatting for column description * generate * consisten br tag * small clean up * temp * Move car videos into CarInfo * add new copy and rename to footnotes * Revert "temp" This reverts commit 93c3fce1d3ab406f80cbfb9c00c2237d109c7846. clean up * generate * replace with svg * simplify a bit * add footnotes to CarInfo * move some variables to docs.py * Add video link for Acadia * Make Footnote an enum so we don't use random ints * static analysis fixes * move to CARS.md * fix last missing footnote * add to release files * rm test file * use svg generate * fix sorting * not needed * not sure how this got here * remove Sedan/Couple and add Diesel footnote * finish todos * move make specific footnotes to selfdrive/car/*/values.py rename * change to zeros * align bottom to center * Apply some suggestions * Update selfdrive/car/mock/values.py Co-authored-by: Adeeb Shihadeh * Update copy * Try headers + bullet points * somehow better somehow better * finish updating copy * move template and add links to sups * stars shouldn't be clickable that didn't work try this try this this is better * add type hints to CarInfo add more type hinting * optional needs a type and any covers all (?) * move good steering torque to */values.py * dataclasses are much nicer than attr * use tuple * Update docs/cars.py Co-authored-by: Adeeb Shihadeh * suggestions * suggestions * suggestions remove * clean up a bit * add more type hints * center stars and remove hardcoding from template * update copy * Add test * Fix types Fix types * add supported cars documentation test * clean up * replace with docs_definitions * Add back Footnote enums * Ah so these are like fstrings! * Update selfdrive/car/CARS_template.md Co-authored-by: Adeeb Shihadeh * Update selfdrive/car/docs.py Co-authored-by: Adeeb Shihadeh * Update year from master merge * Fix longitudinal star from merge * sort properly stars by Column enum * clean up * HKG: Sorry guys * Prius V gets FSR star, like others * Update selfdrive/car/docs.py Co-authored-by: Adeeb Shihadeh * update comment * No Prius docs change for now Co-authored-by: Jason Young <46612682+jyoung8607@users.noreply.github.com> Co-authored-by: Adeeb Shihadeh --- docs/CARS.md | 387 ++++++++++++++++------------- docs/assets/icon-star-empty.svg | 3 + docs/assets/icon-star-full.svg | 3 + docs/assets/icon-star-half.svg | 5 + release/files_common | 1 + selfdrive/car/CARS_template.md | 53 ++++ selfdrive/car/car_helpers.py | 22 +- selfdrive/car/chrysler/values.py | 13 + selfdrive/car/docs.py | 66 +++++ selfdrive/car/docs_definitions.py | 101 ++++++++ selfdrive/car/ford/values.py | 11 +- selfdrive/car/gm/values.py | 27 +- selfdrive/car/honda/values.py | 46 +++- selfdrive/car/hyundai/values.py | 60 +++++ selfdrive/car/mazda/values.py | 15 ++ selfdrive/car/mock/values.py | 8 + selfdrive/car/nissan/values.py | 11 + selfdrive/car/subaru/values.py | 19 ++ selfdrive/car/tesla/values.py | 10 + selfdrive/car/tests/test_docs.py | 18 ++ selfdrive/car/toyota/values.py | 83 ++++++- selfdrive/car/volkswagen/values.py | 75 +++++- 22 files changed, 846 insertions(+), 191 deletions(-) create mode 100644 docs/assets/icon-star-empty.svg create mode 100644 docs/assets/icon-star-full.svg create mode 100644 docs/assets/icon-star-half.svg create mode 100644 selfdrive/car/CARS_template.md create mode 100755 selfdrive/car/docs.py create mode 100644 selfdrive/car/docs_definitions.py create mode 100755 selfdrive/car/tests/test_docs.py diff --git a/docs/CARS.md b/docs/CARS.md index ccf3d04ac..1f9b91c13 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -1,186 +1,219 @@ # Supported Cars -## comma.ai supported cars +A supported vehicle is one that just works when you install openpilot on a compatible device. Every car performs differently with openpilot, but we aim for all supported cars to provide a solid highway experience in the US market. -| Make | Model (US Market Reference) | Supported Package | ACC | No ACC accel below | No ALC below | -| ----------| ------------------------------| ------------------| -----------------| -------------------| ------------------| -| Acura | ILX 2016-19 | AcuraWatch Plus | openpilot | 25mph1 | 25mph | -| Acura | RDX 2016-18 | AcuraWatch Plus | openpilot | 25mph1 | 12mph | -| Acura | RDX 2019-21 | All | Stock | 0mph | 3mph | -| Honda | Accord 2018-21 | All | Stock | 0mph | 3mph | -| Honda | Accord Hybrid 2018-21 | All | Stock | 0mph | 3mph | -| Honda | Civic Hatchback 2017-21 | Honda Sensing | Stock | 0mph | 12mph | -| Honda | Civic Coupe 2016-18 | Honda Sensing | openpilot | 0mph | 12mph | -| Honda | Civic Coupe 2019-20 | All | Stock | 0mph | 2mph2 | -| Honda | Civic Sedan 2016-18 | Honda Sensing | openpilot | 0mph | 12mph | -| Honda | Civic Sedan 2019-20 | All | Stock | 0mph | 2mph2 | -| Honda | CR-V 2015-16 | Touring | openpilot | 25mph1 | 12mph | -| Honda | CR-V 2017-21 | Honda Sensing | Stock | 0mph | 12mph | -| Honda | CR-V Hybrid 2017-2019 | Honda Sensing | Stock | 0mph | 12mph | -| Honda | e 2020 | All | Stock | 0mph | 3mph | -| Honda | Fit 2018-19 | Honda Sensing | openpilot | 25mph1 | 12mph | -| Honda | Freed 2020 | Honda Sensing | openpilot | 25mph1 | 12mph | -| Honda | HR-V 2019-20 | Honda Sensing | openpilot | 25mph1 | 12mph | -| Honda | Insight 2019-21 | All | Stock | 0mph | 3mph | -| Honda | Inspire 2018 | All | Stock | 0mph | 3mph | -| Honda | Odyssey 2018-20 | Honda Sensing | openpilot | 25mph1 | 0mph | -| Honda | Passport 2019-21 | All | openpilot | 25mph1 | 12mph | -| Honda | Pilot 2016-21 | Honda Sensing | openpilot | 25mph1 | 12mph | -| Honda | Ridgeline 2017-21 | Honda Sensing | openpilot | 25mph1 | 12mph | -| Hyundai | Palisade 2020-21 | All | Stock | 0mph | 0mph | -| Hyundai | Sonata 2020-22 | All | Stock | 0mph | 0mph | -| Lexus | CT Hybrid 2017-18 | LSS | Stock3| 0mph | 0mph | -| Lexus | ES 2019-21 | All | openpilot | 0mph | 0mph | -| Lexus | ES Hybrid 2017-18 | LSS | Stock3| 0mph | 0mph | -| Lexus | ES Hybrid 2019-21 | All | openpilot | 0mph | 0mph | -| Lexus | IS 2017-2019 | All | Stock | 22mph | 0mph | -| Lexus | NX 2018-2019 | All | Stock3| 0mph | 0mph | -| Lexus | NX 2020 | All | openpilot | 0mph | 0mph | -| Lexus | NX Hybrid 2018-19 | All | Stock3| 0mph | 0mph | -| Lexus | RC 2020 | All | Stock | 22mph | 0mph | -| Lexus | RX 2016-18 | All | Stock3| 0mph | 0mph | -| Lexus | RX 2020-21 | All | openpilot | 0mph | 0mph | -| Lexus | RX Hybrid 2016-19 | All | Stock3| 0mph | 0mph | -| Lexus | RX Hybrid 2020-21 | All | openpilot | 0mph | 0mph | -| Lexus | UX Hybrid 2019-21 | All | openpilot | 0mph | 0mph | -| Toyota | Alphard 2019-20 | All | openpilot | 0mph | 0mph | -| Toyota | Avalon 2016-18 | TSS-P | Stock3| 20mph1 | 0mph | -| Toyota | Avalon 2019-21 | TSS-P | Stock3| 0mph | 0mph | -| Toyota | Avalon 2022 | All | openpilot | 0mph | 0mph | -| Toyota | Avalon Hybrid 2019-21 | TSS-P | Stock3| 0mph | 0mph | -| Toyota | Camry 2018-20 | All | Stock | 0mph4 | 0mph | -| Toyota | Camry 2021-22 | All | openpilot | 0mph4 | 0mph | -| Toyota | Camry Hybrid 2018-20 | All | Stock | 0mph4 | 0mph | -| Toyota | Camry Hybrid 2021-22 | All | openpilot | 0mph | 0mph | -| Toyota | C-HR 2017-21 | All | Stock | 0mph | 0mph | -| Toyota | C-HR Hybrid 2017-19 | All | Stock | 0mph | 0mph | -| Toyota | Corolla 2017-19 | All | Stock3| 20mph1 | 0mph | -| Toyota | Corolla 2020-22 | All | openpilot | 0mph | 0mph | -| Toyota | Corolla Hatchback 2019-22 | All | openpilot | 0mph | 0mph | -| Toyota | Corolla Hybrid 2020-22 | All | openpilot | 0mph | 0mph | -| Toyota | Highlander 2017-19 | All | Stock3| 0mph | 0mph | -| Toyota | Highlander 2020-22 | All | openpilot | 0mph | 0mph | -| Toyota | Highlander Hybrid 2017-19 | All | Stock3| 0mph | 0mph | -| Toyota | Highlander Hybrid 2020-22 | All | openpilot | 0mph | 0mph | -| Toyota | Mirai 2021 | All | openpilot | 0mph | 0mph | -| Toyota | Prius 2016-20 | TSS-P | Stock3| 0mph | 0mph | -| Toyota | Prius 2021-22 | All | openpilot | 0mph | 0mph | -| Toyota | Prius v 2017 | TSS-P | Stock3| 20mph1 | 0mph | -| Toyota | Prius Prime 2017-20 | All | Stock3| 0mph | 0mph | -| Toyota | Prius Prime 2021-22 | All | openpilot | 0mph | 0mph | -| Toyota | Rav4 2016-18 | TSS-P | Stock3| 20mph1 | 0mph | -| Toyota | Rav4 2019-21 | All | openpilot | 0mph | 0mph | -| Toyota | Rav4 Hybrid 2016-18 | TSS-P | Stock3| 0mph | 0mph | -| Toyota | Rav4 Hybrid 2019-21 | All | openpilot | 0mph | 0mph | -| Toyota | Sienna 2018-20 | All | Stock3| 0mph | 0mph | +Cars are organized into three tiers: -1[Comma Pedal](https://github.com/commaai/openpilot/wiki/comma-pedal) is used to provide stop-and-go capability to some of the openpilot-supported cars that don't currently support stop-and-go. ***NOTE: The Comma Pedal is not officially supported by [comma](https://comma.ai).***
-22019 Honda Civic 1.6L Diesel Sedan does not have ALC below 12mph.
-3When disconnecting the Driver Support Unit (DSU), openpilot ACC will replace stock ACC. ***NOTE: disconnecting the DSU disables Automatic Emergency Braking (AEB).***
-428mph for Camry 4CYL L, 4CYL LE and 4CYL SE which don't have Full-Speed Range Dynamic Radar Cruise Control.
+- Gold - The best openpilot experience. Great highway driving with continual updates. +- Silver - A solid highway experience, but is limited by stock longitudinal. +- Bronze - A solid highway experience, but will have limited performance in stop-and-go. May have ACC and ALC speed limitations. -## Community Maintained Cars and Features +How We Rate The Cars +--- -| Make | Model (US Market Reference) | Supported Package | ACC | No ACC accel below | No ALC below | -| ----------| --------------------------------| ------------------| -----------------| -------------------| -------------| -| Audi | A3 2014-19 | ACC + Lane Assist | Stock | 0mph | 0mph | -| Audi | A3 Sportback e-tron 2017-18 | ACC + Lane Assist | Stock | 0mph | 0mph | -| Audi | Q2 2018 | ACC + Lane Assist | Stock | 0mph | 0mph | -| Audi | Q3 2020-21 | ACC + Lane Assist | Stock | 0mph | 0mph | -| Audi | S3 2015-17 | ACC + Lane Assist | Stock | 0mph | 0mph | -| Cadillac | Escalade ESV 20161 | ACC + LKAS | openpilot | 0mph | 7mph | -| Chevrolet | Volt 2017-181 | Adaptive Cruise | openpilot | 0mph | 7mph | -| Chrysler | Pacifica 2017-18 | Adaptive Cruise | Stock | 0mph | 9mph | -| Chrysler | Pacifica 2020 | Adaptive Cruise | Stock | 0mph | 39mph | -| Chrysler | Pacifica Hybrid 2017-18 | Adaptive Cruise | Stock | 0mph | 9mph | -| Chrysler | Pacifica Hybrid 2019-21 | Adaptive Cruise | Stock | 0mph | 39mph | -| Genesis | G70 2018 | All | Stock | 0mph | 0mph | -| Genesis | G70 2020 | All | Stock | 0mph | 0mph | -| Genesis | G80 2018 | All | Stock | 0mph | 0mph | -| Genesis | G90 2018 | All | Stock | 0mph | 0mph | -| GMC | Acadia 20181 | Adaptive Cruise | openpilot | 0mph | 7mph | -| Hyundai | Elantra 2017-19 | SCC + LKAS | Stock | 19mph | 34mph | -| Hyundai | Elantra 2021-22 | SCC + LKAS | Stock | 0mph | 0mph | -| Hyundai | Elantra Hybrid 2021 | SCC + LKAS | Stock | 0mph | 0mph | -| Hyundai | Genesis 2015-16 | SCC + LKAS | Stock | 19mph | 37mph | -| Hyundai | Ioniq Electric 2019 | SCC + LKAS | Stock | 0mph | 32mph | -| Hyundai | Ioniq Electric 2020 | SCC + LKAS | Stock | 0mph | 0mph | -| Hyundai | Ioniq Hybrid 2017-19 | SCC + LKAS | Stock | 0mph | 32mph | -| Hyundai | Ioniq Hybrid 2020-22 | SCC + LFA | Stock | 0mph | 0mph | -| Hyundai | Ioniq PHEV 2020-21 | SCC + LKAS | Stock | 0mph | 0mph | -| Hyundai | Kona 2020 | SCC + LKAS | Stock | 0mph | 0mph | -| Hyundai | Kona EV 2018-19 | SCC + LKAS | Stock | 0mph | 0mph | -| Hyundai | Kona Hybrid 2020 | SCC + LKAS | Stock | 0mph | 0mph | -| Hyundai | Santa Fe 2019-20 | All | Stock | 0mph | 0mph | -| Hyundai | Santa Fe 2021-22 | All | Stock | 0mph | 0mph | -| Hyundai | Santa Fe Hybrid 2022 | All | Stock | 0mph | 0mph | -| Hyundai | Santa Fe Plug-in Hybrid 2022 | All | Stock | 0mph | 0mph | -| Hyundai | Sonata 2018-2019 | SCC + LKAS | Stock | 0mph | 0mph | -| Hyundai | Sonata Hybrid 2021-22 | All | Stock | 0mph | 0mph | -| Hyundai | Veloster 2019-20 | SCC + LKAS | Stock | 5mph | 0mph | -| Jeep | Grand Cherokee 2016-18 | Adaptive Cruise | Stock | 0mph | 9mph | -| Jeep | Grand Cherokee 2019-20 | Adaptive Cruise | Stock | 0mph | 39mph | -| Kia | Ceed 2019 | SCC + LKAS | Stock | 0mph | 0mph | -| Kia | Forte 2018-21 | SCC + LKAS | Stock | 0mph | 0mph | -| Kia | K5 2021-22 | SCC + LFA | Stock | 0mph | 0mph | -| Kia | Niro EV 2019-22 | All | Stock | 0mph | 0mph | -| Kia | Niro Hybrid 2021-22 | SCC + LKAS | Stock | 0mph | 0mph | -| Kia | Niro PHEV 2019 | SCC + LKAS | Stock | 10mph | 32mph | -| Kia | Optima 2017 | SCC + LKAS | Stock | 0mph | 32mph | -| Kia | Optima 2019 | SCC + LKAS | Stock | 0mph | 0mph | -| Kia | Seltos 2021 | SCC + LKAS | Stock | 0mph | 0mph | -| Kia | Sorento 2018-19 | SCC + LKAS | Stock | 0mph | 0mph | -| Kia | Stinger 2018 | SCC + LKAS | Stock | 0mph | 0mph | -| Kia | Telluride 2020 | SCC + LKAS | Stock | 0mph | 0mph | -| Mazda | CX-5 2022 | All | Stock | 0mph | 0mph | -| Mazda | CX-9 2021 | All | Stock | 0mph | 28mph | -| Nissan | Altima 2019-20 | ProPILOT | Stock | 0mph | 0mph | -| Nissan | Leaf 2018-22 | ProPILOT | Stock | 0mph | 0mph | -| Nissan | Rogue 2018-20 | ProPILOT | Stock | 0mph | 0mph | -| Nissan | X-Trail 2017 | ProPILOT | Stock | 0mph | 0mph | -| SEAT | Ateca 2018 | Driver Assistance | Stock | 0mph | 0mph | -| SEAT | Leon 2014-2020 | Driver Assistance | Stock | 0mph | 0mph | -| Subaru | Ascent 2019 | EyeSight | Stock | 0mph | 0mph | -| Subaru | Crosstrek 2018-20 | EyeSight | Stock | 0mph | 0mph | -| Subaru | Forester 2019-21 | EyeSight | Stock | 0mph | 0mph | -| Subaru | Impreza 2017-19 | EyeSight | Stock | 0mph | 0mph | -| Škoda | Kamiq 20212 | Driver Assistance | Stock | 0mph | 0mph | -| Škoda | Karoq 2019 | Driver Assistance | Stock | 0mph | 0mph | -| Škoda | Kodiaq 2018-19 | Driver Assistance | Stock | 0mph | 0mph | -| Škoda | Octavia 2015, 2018-19 | Driver Assistance | Stock | 0mph | 0mph | -| Škoda | Octavia RS 2016 | Driver Assistance | Stock | 0mph | 0mph | -| Škoda | Scala 2020 | Driver Assistance | Stock | 0mph | 0mph | -| Škoda | Superb 2015-18 | Driver Assistance | Stock | 0mph | 0mph | -| Volkswagen| Arteon 2018, 20214 | Driver Assistance | Stock | 0mph | 0mph | -| Volkswagen| Atlas 2018-19, 20224 | Driver Assistance | Stock | 0mph | 0mph | -| Volkswagen| Caravelle 20204 | Driver Assistance | Stock | 0mph | 32mph | -| Volkswagen| California 20214 | Driver Assistance | Stock | 0mph | 32mph | -| Volkswagen| e-Golf 2014, 2019-20 | Driver Assistance | Stock | 0mph | 0mph | -| Volkswagen| Golf 2015-20 | Driver Assistance | Stock | 0mph | 0mph | -| Volkswagen| Golf Alltrack 2017-18 | Driver Assistance | Stock | 0mph | 0mph | -| Volkswagen| Golf GTE 2016 | Driver Assistance | Stock | 0mph | 0mph | -| Volkswagen| Golf GTI 2018-20 | Driver Assistance | Stock | 0mph | 0mph | -| Volkswagen| Golf R 2016-19 | Driver Assistance | Stock | 0mph | 0mph | -| Volkswagen| Golf SportsVan 2016 | Driver Assistance | Stock | 0mph | 0mph | -| Volkswagen| Golf SportWagen 2015 | Driver Assistance | Stock | 0mph | 0mph | -| Volkswagen| Jetta 2018-21 | Driver Assistance | Stock | 0mph | 0mph | -| Volkswagen| Jetta GLI 2021 | Driver Assistance | Stock | 0mph | 0mph | -| Volkswagen| Passat 2016-183 | Driver Assistance | Stock | 0mph | 0mph | -| Volkswagen| Polo 2020 | Driver Assistance | Stock | 0mph | 0mph | -| Volkswagen| T-Cross 20214 | Driver Assistance | Stock | 0mph | 0mph | -| Volkswagen| T-Roc 20214 | Driver Assistance | Stock | 0mph | 0mph | -| Volkswagen| Taos 20224 | Driver Assistance | Stock | 0mph | 0mph | -| Volkswagen| Tiguan 2020-224 | Driver Assistance | Stock | 0mph | 0mph | -| Volkswagen| Touran 2017 | Driver Assistance | Stock | 0mph | 0mph | +### openpilot Adaptive Cruise Control (ACC) +- - openpilot is able to control the gas and brakes. +- - openpilot is able to control the gas and brakes with some restrictions. +- - The gas and brakes are controlled by the car's stock Adaptive Cruise Control (ACC) system. -1Requires an [OBD-II car harness](https://comma.ai/shop/products/comma-car-harness) and [community built ASCM harness](https://github.com/commaai/openpilot/wiki/GM#hardware). ***NOTE: disconnecting the ASCM disables Automatic Emergency Braking (AEB).***
-2Not including the China market Kamiq, which is based on the (currently) unsupported PQ34 platform.
-3Not including the USA/China market Passat, which is based on the (currently) unsupported PQ35/NMS platform.
-4Model-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.
-Community Maintained Cars and Features are not verified by comma to meet our [safety model](SAFETY.md). Be extra cautious using them. +### Stop and Go +- - Adaptive Cruise Control (ACC) operates down to 0 mph. +- - Adaptive Cruise Control (ACC) available only above certain speeds. See your car's manual for the minimum speed. -To promote a car from community maintained, it must meet a few requirements. We must own one from the brand, we must sell the harness for it, has full ISO26262 in both panda and openpilot, there must be a path forward for longitudinal control, it must have AEB still enabled, and it must support fingerprinting 2.0 +### Steer to 0 +- - openpilot can control the steering wheel down to 0 mph. +- - No steering control below certain speeds. -Although they're not upstream, the community has openpilot running on other makes and models. See the 'Community Supported Models' section of each make [on our wiki](https://wiki.comma.ai/). +### Steering Torque +- - Car has enough steering torque for comfortable highway driving. +- - Limited ability to make turns. + +### Actively Maintained +- - Mainline software support, harness hardware sold by comma, lots of users, primary development target. +- - Low user count, community maintained, harness hardware not sold by comma. + +**All supported cars can move between the tiers as support changes.** + +## Gold Cars + +|Make|Model|Supported Package|openpilot ACC|Stop and Go|Steer to 0|Steering Torque|Actively Maintained| +|---|---|---|:---:|:---:|:---:|:---:|:---:| +|Genesis|G70 2020|All|||||| +|Hyundai|Palisade 2020-21|All|||||| +|Hyundai|Santa Fe 2019-20|All|||||| +|Hyundai|Sonata 2020-22|All|||||| +|Hyundai|Sonata Hybrid 2021-22|All|||||| +|Kia|Niro Electric 2019-22|All|||||| +|Kia|Telluride 2020|SCC + LKAS|||||| +|Lexus|ES 2019-21|All|||||| +|Lexus|ES Hybrid 2019-21|All|||||| +|Lexus|NX 2020|All|||||| +|Lexus|RX 2020-21|All|||||| +|Lexus|RX Hybrid 2020-21|All|||||| +|Lexus|UX Hybrid 2019-21|All|||||| +|Toyota|Alphard 2019-20|All|||||| +|Toyota|Avalon 2022|All|||||| +|Toyota|Camry 2021-22|All||[7](#Footnotes)|||| +|Toyota|Camry Hybrid 2021-22|All|||||| +|Toyota|Corolla 2020-22|All|||||| +|Toyota|Corolla Hatchback 2019-22|All|||||| +|Toyota|Corolla Hybrid 2020-22|All|||||| +|Toyota|Highlander 2020-22|All|||||| +|Toyota|Highlander Hybrid 2020-22|All|||||| +|Toyota|Mirai 2021|All|||||| +|Toyota|Prius 2021-22|All|||||| +|Toyota|Prius Prime 2021-22|All|||||| +|Toyota|RAV4 2019-21|All|||||| +|Toyota|RAV4 Hybrid 2019-21|All|||||| + +## Silver Cars + +|Make|Model|Supported Package|openpilot ACC|Stop and Go|Steer to 0|Steering Torque|Actively Maintained| +|---|---|---|:---:|:---:|:---:|:---:|:---:| +|Audi|A3 2014-19|ACC + Lane Assist|||||| +|Audi|A3 Sportback e-tron 2017-18|ACC + Lane Assist|||||| +|Audi|Q2 2018|ACC + Lane Assist|||||| +|Audi|Q3 2020-21|ACC + Lane Assist|||||| +|Audi|S3 2015-17|ACC + Lane Assist|||||| +|Genesis|G70 2018|All|||||| +|Genesis|G80 2018|All|||||| +|Hyundai|Elantra 2021-22|SCC + LKAS|||||| +|Hyundai|Elantra Hybrid 2021|SCC + LKAS|||||| +|Hyundai|Ioniq Electric 2020|SCC + LKAS|||||| +|Hyundai|Ioniq Hybrid 2020-22|SCC + LFA|||||| +|Hyundai|Ioniq Plug-In Hybrid 2020-21|SCC + LKAS|||||| +|Hyundai|Kona 2020|SCC + LKAS|||||| +|Hyundai|Kona Electric 2018-19|SCC + LKAS|||||| +|Hyundai|Kona Hybrid 2020|SCC + LKAS|||||| +|Hyundai|Santa Fe 2021-22|All|||||| +|Hyundai|Santa Fe Hybrid 2022|All|||||| +|Hyundai|Santa Fe Plug-In Hybrid 2022|All|||||| +|Hyundai|Sonata 2018-19|SCC + LKAS|||||| +|Kia|Ceed 2019|SCC + LKAS|||||| +|Kia|Forte 2018-21|SCC + LKAS|||||| +|Kia|K5 2021-22|SCC + LFA|||||| +|Kia|Niro Hybrid 2021-22|SCC + LKAS|||||| +|Kia|Optima 2019|SCC + LKAS|||||| +|Kia|Seltos 2021|SCC + LKAS|||||| +|Kia|Sorento 2018-19|SCC + LKAS|||||| +|Kia|Stinger 2018|SCC + LKAS|||||| +|Lexus|CT Hybrid 2017-18|LSS|[6](#Footnotes)||||| +|Lexus|ES Hybrid 2017-18|LSS|[6](#Footnotes)||||| +|Lexus|NX 2018-19|All|[6](#Footnotes)||||| +|Lexus|NX Hybrid 2018-19|All|[6](#Footnotes)||||| +|Lexus|RX 2016-18|All|[6](#Footnotes)||||| +|Lexus|RX Hybrid 2016-19|All|[6](#Footnotes)||||| +|SEAT|Ateca 2018|Driver Assistance|||||| +|SEAT|Leon 2014-20|Driver Assistance|||||| +|Toyota|Avalon 2019-21|TSS-P|[6](#Footnotes)||||| +|Toyota|Avalon Hybrid 2019-21|TSS-P|[6](#Footnotes)||||| +|Toyota|C-HR 2017-21|All|||||| +|Toyota|C-HR Hybrid 2017-19|All|||||| +|Toyota|Camry 2018-20|All||[7](#Footnotes)|||| +|Toyota|Camry Hybrid 2018-20|All||[7](#Footnotes)|||| +|Toyota|Highlander 2017-19|All|[6](#Footnotes)||||| +|Toyota|Highlander Hybrid 2017-19|All|[6](#Footnotes)||||| +|Toyota|RAV4 Hybrid 2016-18|TSS-P|[6](#Footnotes)||||| +|Toyota|Sienna 2018-20|All|[6](#Footnotes)||||| +|Volkswagen|Arteon 2018, 2021[5](#Footnotes)|Driver Assistance|||||| +|Volkswagen|Atlas 2018-19, 2022[5](#Footnotes)|Driver Assistance|||||| +|Volkswagen|Golf 2015-20|Driver Assistance|||||| +|Volkswagen|Golf Alltrack 2017-18|Driver Assistance|||||| +|Volkswagen|Golf GTE 2016|Driver Assistance|||||| +|Volkswagen|Golf GTI 2018-20|Driver Assistance|||||| +|Volkswagen|Golf R 2016-19|Driver Assistance|||||| +|Volkswagen|Golf SportWagen 2015|Driver Assistance|||||| +|Volkswagen|Golf SportsVan 2016|Driver Assistance|||||| +|Volkswagen|Jetta 2018-21|Driver Assistance|||||| +|Volkswagen|Jetta GLI 2021|Driver Assistance|||||| +|Volkswagen|Passat 2016-18[4](#Footnotes)|Driver Assistance|||||| +|Volkswagen|Polo 2020|Driver Assistance|||||| +|Volkswagen|T-Cross 2021[5](#Footnotes)|Driver Assistance|||||| +|Volkswagen|T-Roc 2021[5](#Footnotes)|Driver Assistance|||||| +|Volkswagen|Taos 2022[5](#Footnotes)|Driver Assistance|||||| +|Volkswagen|Tiguan 2020-22[5](#Footnotes)|Driver Assistance|||||| +|Volkswagen|Touran 2017|Driver Assistance|||||| +|Volkswagen|e-Golf 2014, 2019-20|Driver Assistance|||||| +|Škoda|Kamiq 2021[3](#Footnotes)|Driver Assistance|||||| +|Škoda|Karoq 2019|Driver Assistance|||||| +|Škoda|Kodiaq 2018-19|Driver Assistance|||||| +|Škoda|Octavia 2015, 2018-19|Driver Assistance|||||| +|Škoda|Octavia RS 2016|Driver Assistance|||||| +|Škoda|Scala 2020|Driver Assistance|||||| +|Škoda|Superb 2015-18|Driver Assistance|||||| + +## Bronze Cars + +|Make|Model|Supported Package|openpilot ACC|Stop and Go|Steer to 0|Steering Torque|Actively Maintained| +|---|---|---|:---:|:---:|:---:|:---:|:---:| +|Acura|ILX 2016-19|AcuraWatch Plus|||||| +|Acura|RDX 2016-18|AcuraWatch Plus|||||| +|Acura|RDX 2019-21|All|||||| +|Cadillac|Escalade ESV 2016[2](#Footnotes)|ACC + LKAS|||||| +|Chevrolet|Volt 2017-18[2](#Footnotes)|Adaptive Cruise|||||| +|Chrysler|Pacifica 2017-18|Adaptive Cruise|||||| +|Chrysler|Pacifica 2020|Adaptive Cruise|||||| +|Chrysler|Pacifica Hybrid 2017-18|Adaptive Cruise|||||| +|Chrysler|Pacifica Hybrid 2019-21|Adaptive Cruise|||||| +|GMC|Acadia 2018[2](#Footnotes)|Adaptive Cruise|||||| +|Genesis|G90 2018|All|||||| +|Honda|Accord 2018-21|All|||||| +|Honda|Accord Hybrid 2018-21|All|||||| +|Honda|CR-V 2015-16|Touring|||||| +|Honda|CR-V 2017-21|Honda Sensing|||||| +|Honda|CR-V Hybrid 2017-19|Honda Sensing|||||| +|Honda|Civic 2016-18|Honda Sensing|||||| +|Honda|Civic 2019-20|All|||[1](#Footnotes)||| +|Honda|Civic Hatchback 2017-21|Honda Sensing|||||| +|Honda|Fit 2018-19|Honda Sensing|||||| +|Honda|Freed 2020|Honda Sensing|||||| +|Honda|HR-V 2019-20|Honda Sensing|||||| +|Honda|Insight 2019-21|All|||||| +|Honda|Inspire 2018|All|||||| +|Honda|Odyssey 2018-20|Honda Sensing|||||| +|Honda|Passport 2019-21|All|||||| +|Honda|Pilot 2016-21|Honda Sensing|||||| +|Honda|Ridgeline 2017-21|Honda Sensing|||||| +|Honda|e 2020|All|||||| +|Hyundai|Elantra 2017-19|SCC + LKAS|||||| +|Hyundai|Genesis 2015-16|SCC + LKAS|||||| +|Hyundai|Ioniq Electric 2019|SCC + LKAS|||||| +|Hyundai|Ioniq Hybrid 2017-19|SCC + LKAS|||||| +|Hyundai|Veloster 2019-20|SCC + LKAS|||||| +|Jeep|Grand Cherokee 2016-18|Adaptive Cruise|||||| +|Jeep|Grand Cherokee 2019-20|Adaptive Cruise|||||| +|Kia|Niro Plug-In Hybrid 2019|SCC + LKAS|||||| +|Kia|Optima 2017|SCC + LKAS|||||| +|Lexus|IS 2017-19|All|||||| +|Lexus|RC 2020|All|||||| +|Mazda|CX-5 2022|All|||||| +|Mazda|CX-9 2021|All|||||| +|Nissan|Altima 2019-20|ProPILOT|||||| +|Nissan|Leaf 2018-22|ProPILOT|||||| +|Nissan|Rogue 2018-20|ProPILOT|||||| +|Nissan|X-Trail 2017|ProPILOT|||||| +|Subaru|Ascent 2019|EyeSight|||||| +|Subaru|Crosstrek 2018-20|EyeSight|||||| +|Subaru|Forester 2019-21|EyeSight|||||| +|Subaru|Impreza 2017-19|EyeSight|||||| +|Toyota|Avalon 2016-18|TSS-P|[6](#Footnotes)||||| +|Toyota|Corolla 2017-19|All|[6](#Footnotes)||||| +|Toyota|Prius 2016-20|TSS-P|[6](#Footnotes)|||[8](#Footnotes)|| +|Toyota|Prius Prime 2017-20|All|[6](#Footnotes)|||[8](#Footnotes)|| +|Toyota|Prius v 2017|TSS-P|[6](#Footnotes)|||[8](#Footnotes)|| +|Toyota|RAV4 2016-18|TSS-P|[6](#Footnotes)||||| +|Volkswagen|California 2021[5](#Footnotes)|Driver Assistance|||||| +|Volkswagen|Caravelle 2020[5](#Footnotes)|Driver Assistance|||||| + + +12019 Honda Civic 1.6L Diesel Sedan does not have ALC below 12mph.
+2Requires an [OBD-II](https://comma.ai/shop/products/comma-car-harness) car harness and [community built ASCM harness](https://github.com/commaai/openpilot/wiki/GM#hardware). NOTE: disconnecting the ASCM disables Automatic Emergency Braking (AEB).
+3Not including the China market Kamiq, which is based on the (currently) unsupported PQ34 platform.
+4Not including the USA/China market Passat, which is based on the (currently) unsupported PQ35/NMS platform.
+5Model-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.
+6When disconnecting the Driver Support Unit (DSU), openpilot Adaptive Cruise Control (ACC) will replace stock Adaptive Cruise Control (ACC). NOTE: disconnecting the DSU disables Automatic Emergency Braking (AEB).
+728mph for Camry 4CYL L, 4CYL LE and 4CYL SE which don't have Full-Speed Range Dynamic Radar Cruise Control.
+8An inaccurate steering wheel angle sensor makes precise control difficult.
+ +## Community Maintained Cars +Although they're not upstream, the community has openpilot running on other makes and models. See the 'Community Supported Models' section of each make [on our wiki](https://wiki.comma.ai/). \ No newline at end of file diff --git a/docs/assets/icon-star-empty.svg b/docs/assets/icon-star-empty.svg new file mode 100644 index 000000000..b12b42662 --- /dev/null +++ b/docs/assets/icon-star-empty.svg @@ -0,0 +1,3 @@ + + + diff --git a/docs/assets/icon-star-full.svg b/docs/assets/icon-star-full.svg new file mode 100644 index 000000000..8211fdcc2 --- /dev/null +++ b/docs/assets/icon-star-full.svg @@ -0,0 +1,3 @@ + + + diff --git a/docs/assets/icon-star-half.svg b/docs/assets/icon-star-half.svg new file mode 100644 index 000000000..7f64bc87e --- /dev/null +++ b/docs/assets/icon-star-half.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/release/files_common b/release/files_common index d2d5f14ae..a68f8d1f5 100644 --- a/release/files_common +++ b/release/files_common @@ -100,6 +100,7 @@ selfdrive/boardd/set_time.py selfdrive/boardd/pandad.py selfdrive/car/__init__.py +selfdrive/car/docs_definitions.py selfdrive/car/car_helpers.py selfdrive/car/fingerprints.py selfdrive/car/interfaces.py diff --git a/selfdrive/car/CARS_template.md b/selfdrive/car/CARS_template.md new file mode 100644 index 000000000..7cdb7bc02 --- /dev/null +++ b/selfdrive/car/CARS_template.md @@ -0,0 +1,53 @@ +# Supported Cars + +A supported vehicle is one that just works when you install openpilot on a compatible device. Every car performs differently with openpilot, but we aim for all supported cars to provide a solid highway experience in the US market. + +Cars are organized into three tiers: + +- Gold - The best openpilot experience. Great highway driving with continual updates. +- Silver - A solid highway experience, but is limited by stock longitudinal. +- Bronze - A solid highway experience, but will have limited performance in stop-and-go. May have ACC and ALC speed limitations. + +How We Rate The Cars +--- + +### openpilot Adaptive Cruise Control (ACC) +- {{Star.FULL.icon}} - openpilot is able to control the gas and brakes. +- {{Star.HALF.icon}} - openpilot is able to control the gas and brakes with some restrictions. +- {{Star.EMPTY.icon}} - The gas and brakes are controlled by the car's stock Adaptive Cruise Control (ACC) system. + +### Stop and Go +- {{Star.FULL.icon}} - Adaptive Cruise Control (ACC) operates down to 0 mph. +- {{Star.EMPTY.icon}} - Adaptive Cruise Control (ACC) available only above certain speeds. See your car's manual for the minimum speed. + +### Steer to 0 +- {{Star.FULL.icon}} - openpilot can control the steering wheel down to 0 mph. +- {{Star.EMPTY.icon}} - No steering control below certain speeds. + +### Steering Torque +- {{Star.FULL.icon}} - Car has enough steering torque for comfortable highway driving. +- {{Star.EMPTY.icon}} - Limited ability to make turns. + +### Actively Maintained +- {{Star.FULL.icon}} - Mainline software support, harness hardware sold by comma, lots of users, primary development target. +- {{Star.EMPTY.icon}} - Low user count, community maintained, harness hardware not sold by comma. + +**All supported cars can move between the tiers as support changes.** + +{% for tier, car_rows in tiers %} +## {{tier}} Cars + +|{{columns | join('|')}}| +|---|---|---|:---:|:---:|:---:|:---:|:---:| +{% for row in car_rows %} +|{{row | join('|')}}| +{% endfor %} + +{% endfor %} + +{% for footnote in footnotes %} +{{loop.index}}{{footnote}}
+{% endfor %} + +## Community Maintained Cars +Although they're not upstream, the community has openpilot running on other makes and models. See the 'Community Supported Models' section of each make [on our wiki](https://wiki.comma.ai/). diff --git a/selfdrive/car/car_helpers.py b/selfdrive/car/car_helpers.py index e88fc9952..6e9c842df 100644 --- a/selfdrive/car/car_helpers.py +++ b/selfdrive/car/car_helpers.py @@ -1,4 +1,6 @@ import os +from typing import Any, Dict, List + from common.params import Params from common.basedir import BASEDIR from selfdrive.version import is_comma_remote, is_tested_branch @@ -57,19 +59,25 @@ def load_interfaces(brand_names): return ret -def _get_interface_names(): - # read all the folders in selfdrive/car and return a dict where: - # - keys are all the car names that which we have an interface for - # - values are lists of spefic car models for a given car +def get_interface_attr(attr: str) -> Dict[str, Any]: + # returns given attribute from each interface brand_names = {} for car_folder in [x[0] for x in os.walk(BASEDIR + '/selfdrive/car')]: try: brand_name = car_folder.split('/')[-1] - model_names = __import__(f'selfdrive.car.{brand_name}.values', fromlist=['CAR']).CAR - model_names = [getattr(model_names, c) for c in model_names.__dict__.keys() if not c.startswith("__")] - brand_names[brand_name] = model_names + attr_data = getattr(__import__(f'selfdrive.car.{brand_name}.values', fromlist=[attr]), attr, None) + brand_names[brand_name] = attr_data except (ImportError, OSError): pass + return brand_names + + +def _get_interface_names() -> Dict[str, List[str]]: + # returns a dict of brand name and its respective models + brand_names = {} + for brand_name, model_names in get_interface_attr("CAR").items(): + model_names = [getattr(model_names, c) for c in model_names.__dict__.keys() if not c.startswith("__")] + brand_names[brand_name] = model_names return brand_names diff --git a/selfdrive/car/chrysler/values.py b/selfdrive/car/chrysler/values.py index 3fd32e9bc..cda15dbbd 100644 --- a/selfdrive/car/chrysler/values.py +++ b/selfdrive/car/chrysler/values.py @@ -1,4 +1,7 @@ +from typing import Dict, List, Union + from selfdrive.car import dbc_dict +from selfdrive.car.docs_definitions import CarInfo from cereal import car Ecu = car.CarParams.Ecu @@ -18,6 +21,16 @@ class CAR: JEEP_CHEROKEE = "JEEP GRAND CHEROKEE V6 2018" # includes 2017 Trailhawk JEEP_CHEROKEE_2019 = "JEEP GRAND CHEROKEE 2019" # includes 2020 Trailhawk + +CAR_INFO: Dict[str, Union[CarInfo, List[CarInfo]]] = { + CAR.PACIFICA_2017_HYBRID: CarInfo("Chrysler Pacifica Hybrid 2017-18", "Adaptive Cruise"), + CAR.PACIFICA_2019_HYBRID: CarInfo("Chrysler Pacifica Hybrid 2019-21", "Adaptive Cruise"), + CAR.PACIFICA_2018: CarInfo("Chrysler Pacifica 2017-18", "Adaptive Cruise"), + CAR.PACIFICA_2020: CarInfo("Chrysler Pacifica 2020", "Adaptive Cruise"), + CAR.JEEP_CHEROKEE: CarInfo("Jeep Grand Cherokee 2016-18", "Adaptive Cruise", "https://www.youtube.com/watch?v=eLR9o2JkuRk"), + CAR.JEEP_CHEROKEE_2019: CarInfo("Jeep Grand Cherokee 2019-20", "Adaptive Cruise", "https://www.youtube.com/watch?v=jBe4lWnRSu4"), +} + # Unique CAN messages: # Only the hybrids have 270: 8 # Only the gas have 55: 8, 416: 7 diff --git a/selfdrive/car/docs.py b/selfdrive/car/docs.py new file mode 100755 index 000000000..362b14235 --- /dev/null +++ b/selfdrive/car/docs.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 +import jinja2 +import os +from enum import Enum +from typing import Dict, Iterator, List, Tuple + +from common.basedir import BASEDIR +from selfdrive.car.docs_definitions import Column, Star, Tier +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 +from selfdrive.car.tests.routes import non_tested_cars + + +def get_all_footnotes(): + all_footnotes = [] + for _, footnotes in get_interface_attr("Footnote").items(): + if footnotes is not None: + all_footnotes += footnotes + return {fn: idx + 1 for idx, fn in enumerate(all_footnotes)} + + +ALL_FOOTNOTES: Dict[Enum, int] = get_all_footnotes() +CARS_MD_OUT = os.path.join(BASEDIR, "docs", "CARS.md") +CARS_MD_TEMPLATE = os.path.join(BASEDIR, "selfdrive", "car", "CARS_template.md") + + +def get_tier_car_rows() -> Iterator[Tuple[str, List[str]]]: + tier_car_rows: Dict[Tier, list] = {tier: [] for tier in Tier} + + for models in get_interface_attr("CAR_INFO").values(): + for model, car_info in models.items(): + # Hyundai exception: those with radar have openpilot longitudinal + fingerprint = {0: {}, 1: {HKG_RADAR_START_ADDR: 8}, 2: {}, 3: {}} + CP = interfaces[model][0].get_params(model, fingerprint=fingerprint, disable_radar=True) + + if CP.dashcamOnly: + continue + + # A platform can include multiple car models + if not isinstance(car_info, list): + car_info = (car_info,) + + for _car_info in car_info: + stars = _car_info.get_stars(CP, non_tested_cars) + tier = {5: Tier.GOLD, 4: Tier.SILVER}.get(stars.count(Star.FULL), Tier.BRONZE) + tier_car_rows[tier].append(_car_info.get_row(ALL_FOOTNOTES, stars)) + + # Return tier title and car rows for each tier + for tier, car_rows in tier_car_rows.items(): + yield tier.name.title(), sorted(car_rows) + + +def generate_cars_md(tier_car_rows: Iterator[Tuple[str, List[str]]], template_fn: str) -> str: + with open(template_fn, "r") as f: + template = jinja2.Template(f.read(), trim_blocks=True) + + footnotes = [fn.value.text for fn in ALL_FOOTNOTES] + return template.render(tiers=tier_car_rows, columns=[column.value for column in Column], + footnotes=footnotes, Star=Star) + + +if __name__ == "__main__": + # Auto generates supported cars documentation + with open(CARS_MD_OUT, 'w') as f: + f.write(generate_cars_md(get_tier_car_rows(), CARS_MD_TEMPLATE)) + print(f"Generated and written to {CARS_MD_OUT}") diff --git a/selfdrive/car/docs_definitions.py b/selfdrive/car/docs_definitions.py new file mode 100644 index 000000000..95591652e --- /dev/null +++ b/selfdrive/car/docs_definitions.py @@ -0,0 +1,101 @@ +from collections import namedtuple +from dataclasses import dataclass +from enum import Enum +from typing import List, Optional + + +@dataclass +class CarInfo: + name: str + package: str + video_link: Optional[str] = None + footnotes: Optional[List[Enum]] = None + min_steer_speed: Optional[float] = None + min_enable_speed: Optional[float] = None + good_torque: bool = False + + def get_stars(self, CP, non_tested_cars): + # TODO: set all the min steer speeds in carParams and remove this + min_steer_speed = CP.minSteerSpeed + if self.min_steer_speed is not None: + min_steer_speed = self.min_steer_speed + assert CP.minSteerSpeed == 0, f"Minimum steer speed set in both CarInfo and CarParams for {CP.carFingerprint}" + + # TODO: set all the min enable speeds in carParams correctly and remove this + min_enable_speed = CP.minEnableSpeed + if self.min_enable_speed is not None: + min_enable_speed = self.min_enable_speed + + stars = { + Column.LONGITUDINAL: CP.openpilotLongitudinalControl and not CP.radarOffCan, + Column.FSR_LONGITUDINAL: min_enable_speed <= 0., + Column.FSR_STEERING: min_steer_speed <= 0., + Column.STEERING_TORQUE: self.good_torque, + Column.MAINTAINED: CP.carFingerprint not in non_tested_cars, + } + + for column in StarColumns: + stars[column] = Star.FULL if stars[column] else Star.EMPTY + + # Demote if footnote specifies a star + footnote = get_footnote(self.footnotes, column) + if footnote is not None and footnote.value.star is not None: + stars[column] = footnote.value.star + + return [stars[column] for column in StarColumns] + + def get_row(self, all_footnotes, stars): + # TODO: add YouTube vidos + make, model = self.name.split(' ', 1) + row = [make, model, self.package, *stars] + + # Check for car footnotes and get star icons + for row_idx, column in enumerate(Column): + if column in StarColumns: + row[row_idx] = row[row_idx].icon + + footnote = get_footnote(self.footnotes, column) + if footnote is not None: + row[row_idx] += f"[{all_footnotes[footnote]}](#Footnotes)" + + return row + + +class Tier(Enum): + GOLD = "Gold" + SILVER = "Silver" + BRONZE = "Bronze" + + +class Column(Enum): + MAKE = "Make" + MODEL = "Model" + PACKAGE = "Supported Package" + LONGITUDINAL = "openpilot ACC" + FSR_LONGITUDINAL = "Stop and Go" + FSR_STEERING = "Steer to 0" + STEERING_TORQUE = "Steering Torque" + MAINTAINED = "Actively Maintained" + + +class Star(Enum): + FULL = "full" + HALF = "half" + EMPTY = "empty" + + @property + def icon(self): + return f'' + + +StarColumns = list(Column)[3:] +CarFootnote = namedtuple("CarFootnote", ["text", "column", "star"], defaults=[None]) + + +def get_footnote(footnotes: Optional[List[Enum]], column: Column) -> Optional[Enum]: + # Returns applicable footnote given current column + if footnotes is not None: + for fn in footnotes: + if fn.value.column == column: + return fn + return None diff --git a/selfdrive/car/ford/values.py b/selfdrive/car/ford/values.py index e1e220647..dd76f48b3 100644 --- a/selfdrive/car/ford/values.py +++ b/selfdrive/car/ford/values.py @@ -1,12 +1,21 @@ -from selfdrive.car import dbc_dict +from typing import Dict, List, Union + from cereal import car +from selfdrive.car import dbc_dict +from selfdrive.car.docs_definitions import CarInfo Ecu = car.CarParams.Ecu MAX_ANGLE = 87. # make sure we never command the extremes (0xfff) which cause latching fault + class CAR: FUSION = "FORD FUSION 2018" + +CAR_INFO: Dict[str, Union[CarInfo, List[CarInfo]]] = { + CAR.FUSION: CarInfo("Ford Fusion 2018", "All") +} + DBC = { CAR.FUSION: dbc_dict('ford_fusion_2018_pt', 'ford_fusion_2018_adas'), } diff --git a/selfdrive/car/gm/values.py b/selfdrive/car/gm/values.py index 8e0907671..8f5e6d584 100644 --- a/selfdrive/car/gm/values.py +++ b/selfdrive/car/gm/values.py @@ -1,8 +1,13 @@ +from enum import Enum +from typing import Dict, List, Union + from cereal import car from selfdrive.car import dbc_dict +from selfdrive.car.docs_definitions import CarFootnote, CarInfo, Column Ecu = car.CarParams.Ecu -class CarControllerParams(): + +class CarControllerParams: STEER_MAX = 300 # Safety limit, not LKA max. Trucks use 600. STEER_STEP = 2 # control frames per command STEER_DELTA_UP = 7 @@ -38,6 +43,7 @@ class CarControllerParams(): STEER_THRESHOLD = 1.0 + class CAR: HOLDEN_ASTRA = "HOLDEN ASTRA RS-V BK 2017" VOLT = "CHEVROLET VOLT PREMIER 2017" @@ -47,6 +53,25 @@ class CAR: BUICK_REGAL = "BUICK REGAL ESSENCE 2018" ESCALADE_ESV = "CADILLAC ESCALADE ESV 2016" + +class Footnote(Enum): + OBD_II = CarFootnote( + "Requires an [OBD-II](https://comma.ai/shop/products/comma-car-harness) car harness and [community built ASCM harness]" + + "(https://github.com/commaai/openpilot/wiki/GM#hardware). NOTE: disconnecting the ASCM disables Automatic Emergency Braking (AEB).", + Column.MODEL) + + +CAR_INFO: Dict[str, Union[CarInfo, List[CarInfo]]] = { + CAR.HOLDEN_ASTRA: CarInfo("Holden Astra 2017", "Adaptive Cruise"), + CAR.VOLT: CarInfo("Chevrolet Volt 2017-18", "Adaptive Cruise", footnotes=[Footnote.OBD_II], min_enable_speed=0), + CAR.CADILLAC_ATS: CarInfo("Cadillac ATS Premium Performance 2018", "Adaptive Cruise"), + CAR.MALIBU: CarInfo("Chevrolet Malibu Premier 2017", "Adaptive Cruise"), + CAR.ACADIA: CarInfo("GMC Acadia 2018", "Adaptive Cruise", video_link="https://www.youtube.com/watch?v=0ZN6DdsBUZo", footnotes=[Footnote.OBD_II]), + CAR.BUICK_REGAL: CarInfo("Buick Regal Essence 2018", "Adaptive Cruise"), + CAR.ESCALADE_ESV: CarInfo("Cadillac Escalade ESV 2016", "ACC + LKAS", footnotes=[Footnote.OBD_II]), +} + + class CruiseButtons: INIT = 0 UNPRESS = 1 diff --git a/selfdrive/car/honda/values.py b/selfdrive/car/honda/values.py index 50ea52faa..4b8300eea 100644 --- a/selfdrive/car/honda/values.py +++ b/selfdrive/car/honda/values.py @@ -1,13 +1,15 @@ -from enum import IntFlag +from enum import Enum, IntFlag +from typing import Dict, List, Union from cereal import car from selfdrive.car import dbc_dict +from selfdrive.car.docs_definitions import CarFootnote, CarInfo, Column +from common.conversions import Conversions as CV Ecu = car.CarParams.Ecu VisualAlert = car.CarControl.HUDControl.VisualAlert - -class CarControllerParams(): +class CarControllerParams: # Allow small margin below -3.5 m/s^2 from ISO 15622:2018 since we # perform the closed loop control, and might need some # to apply some more braking if we're on a downhill slope. @@ -63,6 +65,7 @@ VISUAL_HUD = { VisualAlert.speedTooHigh: 8 } + class CAR: ACCORD = "HONDA ACCORD 2018" ACCORDH = "HONDA ACCORD HYBRID 2018" @@ -87,6 +90,43 @@ class CAR: INSIGHT = "HONDA INSIGHT 2019" HONDA_E = "HONDA E 2020" + +class Footnote(Enum): + CIVIC_DIESEL = CarFootnote( + "2019 Honda Civic 1.6L Diesel Sedan does not have ALC below 12mph.", + Column.FSR_STEERING) + + +CAR_INFO: Dict[str, Union[CarInfo, List[CarInfo]]] = { + CAR.ACCORD: [ + CarInfo("Honda Accord 2018-21", "All", video_link="https://www.youtube.com/watch?v=mrUwlj3Mi58", min_steer_speed=3. * CV.MPH_TO_MS), + CarInfo("Honda Inspire 2018", "All", min_steer_speed=3. * CV.MPH_TO_MS), + ], + CAR.ACCORDH: CarInfo("Honda Accord Hybrid 2018-21", "All", min_steer_speed=3. * CV.MPH_TO_MS), + CAR.CIVIC: CarInfo("Honda Civic 2016-18", "Honda Sensing", min_steer_speed=12. * CV.MPH_TO_MS), + CAR.CIVIC_BOSCH: [ + CarInfo("Honda Civic 2019-20", "All", video_link="https://www.youtube.com/watch?v=4Iz1Mz5LGF8", footnotes=[Footnote.CIVIC_DIESEL], min_steer_speed=2. * CV.MPH_TO_MS), + CarInfo("Honda Civic Hatchback 2017-21", "Honda Sensing", min_steer_speed=12. * CV.MPH_TO_MS), + ], + CAR.ACURA_ILX: CarInfo("Acura ILX 2016-19", "AcuraWatch Plus", min_steer_speed=25. * CV.MPH_TO_MS), + CAR.CRV: CarInfo("Honda CR-V 2015-16", "Touring", min_steer_speed=12. * CV.MPH_TO_MS), + CAR.CRV_5G: CarInfo("Honda CR-V 2017-21", "Honda Sensing", min_steer_speed=12. * CV.MPH_TO_MS), + # CAR.CRV_EU: CarInfo("Honda CR-V EU", "Touring"), # Euro version of CRV Touring + CAR.CRV_HYBRID: CarInfo("Honda CR-V Hybrid 2017-19", "Honda Sensing", min_steer_speed=12. * CV.MPH_TO_MS), + CAR.FIT: CarInfo("Honda Fit 2018-19", "Honda Sensing", min_steer_speed=12. * CV.MPH_TO_MS), + CAR.FREED: CarInfo("Honda Freed 2020", "Honda Sensing", min_steer_speed=12. * CV.MPH_TO_MS), + CAR.HRV: CarInfo("Honda HR-V 2019-20", "Honda Sensing", min_steer_speed=12. * CV.MPH_TO_MS), + CAR.ODYSSEY: CarInfo("Honda Odyssey 2018-20", "Honda Sensing"), + CAR.ACURA_RDX: CarInfo("Acura RDX 2016-18", "AcuraWatch Plus", min_steer_speed=12. * CV.MPH_TO_MS), + CAR.ACURA_RDX_3G: CarInfo("Acura RDX 2019-21", "All", min_steer_speed=3. * CV.MPH_TO_MS), + CAR.PILOT: CarInfo("Honda Pilot 2016-21", "Honda Sensing", min_steer_speed=12. * CV.MPH_TO_MS), + CAR.PASSPORT: CarInfo("Honda Passport 2019-21", "All", min_steer_speed=12. * CV.MPH_TO_MS), + CAR.RIDGELINE: CarInfo("Honda Ridgeline 2017-21", "Honda Sensing", min_steer_speed=12. * CV.MPH_TO_MS), + CAR.INSIGHT: CarInfo("Honda Insight 2019-21", "All", min_steer_speed=3. * CV.MPH_TO_MS), + CAR.HONDA_E: CarInfo("Honda e 2020", "All", min_steer_speed=3. * CV.MPH_TO_MS), +} + + FW_VERSIONS = { CAR.ACCORD: { (Ecu.programmedFuelInjection, 0x18da10f1, None): [ diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index 78a0ead90..21a2a4128 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -1,5 +1,10 @@ +from dataclasses import dataclass +from typing import Dict, List, Union + from cereal import car +from common.conversions import Conversions as CV from selfdrive.car import dbc_dict +from selfdrive.car.docs_definitions import CarInfo Ecu = car.CarParams.Ecu # Steer torque limits @@ -22,6 +27,7 @@ class CarControllerParams: self.STEER_DRIVER_MULTIPLIER = 2 self.STEER_DRIVER_FACTOR = 1 + class CAR: # Hyundai ELANTRA = "HYUNDAI ELANTRA 2017" @@ -67,6 +73,60 @@ class CAR: GENESIS_G90 = "GENESIS G90 2017" +@dataclass +class HyundaiCarInfo(CarInfo): + package: str = "SCC + LKAS" + good_torque: bool = True + + +CAR_INFO: Dict[str, Union[HyundaiCarInfo, List[HyundaiCarInfo]]] = { + CAR.ELANTRA: HyundaiCarInfo("Hyundai Elantra 2017-19", min_enable_speed=19 * CV.MPH_TO_MS), + CAR.ELANTRA_2021: HyundaiCarInfo("Hyundai Elantra 2021-22", video_link="https://youtu.be/_EdYQtV52-c"), + CAR.ELANTRA_HEV_2021: HyundaiCarInfo("Hyundai Elantra Hybrid 2021", video_link="https://youtu.be/_EdYQtV52-c"), + CAR.HYUNDAI_GENESIS: HyundaiCarInfo("Hyundai Genesis 2015-16", min_enable_speed=19 * CV.MPH_TO_MS), + CAR.IONIQ: HyundaiCarInfo("Hyundai Ioniq Hybrid 2017-19"), + CAR.IONIQ_HEV_2022: HyundaiCarInfo("Hyundai Ioniq Hybrid 2020-22", "SCC + LFA"), + CAR.IONIQ_EV_LTD: HyundaiCarInfo("Hyundai Ioniq Electric 2019"), + CAR.IONIQ_EV_2020: HyundaiCarInfo("Hyundai Ioniq Electric 2020"), + CAR.IONIQ_PHEV: HyundaiCarInfo("Hyundai Ioniq Plug-In Hybrid 2020-21"), + CAR.KONA: HyundaiCarInfo("Hyundai Kona 2020"), + CAR.KONA_EV: HyundaiCarInfo("Hyundai Kona Electric 2018-19"), + CAR.KONA_HEV: HyundaiCarInfo("Hyundai Kona Hybrid 2020", video_link="https://youtu.be/_EdYQtV52-c"), + CAR.SANTA_FE: HyundaiCarInfo("Hyundai Santa Fe 2019-20", "All"), + CAR.SANTA_FE_2022: HyundaiCarInfo("Hyundai Santa Fe 2021-22", "All"), + CAR.SANTA_FE_HEV_2022: HyundaiCarInfo("Hyundai Santa Fe Hybrid 2022", "All"), + CAR.SANTA_FE_PHEV_2022: HyundaiCarInfo("Hyundai Santa Fe Plug-In Hybrid 2022", "All"), + CAR.SONATA: HyundaiCarInfo("Hyundai Sonata 2020-22", "All", video_link="https://www.youtube.com/watch?v=ix63r9kE3Fw"), + CAR.SONATA_LF: HyundaiCarInfo("Hyundai Sonata 2018-19"), + CAR.PALISADE: [ + HyundaiCarInfo("Hyundai Palisade 2020-21", "All", video_link="https://youtu.be/TAnDqjF4fDY?t=456"), + HyundaiCarInfo("Kia Telluride 2020"), + ], + CAR.VELOSTER: HyundaiCarInfo("Hyundai Veloster 2019-20", min_enable_speed=5. * CV.MPH_TO_MS), + CAR.SONATA_HYBRID: HyundaiCarInfo("Hyundai Sonata Hybrid 2021-22", "All"), + + # Kia + CAR.KIA_FORTE: HyundaiCarInfo("Kia Forte 2018-21"), + CAR.KIA_K5_2021: HyundaiCarInfo("Kia K5 2021-22", "SCC + LFA"), + CAR.KIA_NIRO_EV: HyundaiCarInfo("Kia Niro Electric 2019-22", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo"), + CAR.KIA_NIRO_HEV: HyundaiCarInfo("Kia Niro Plug-In Hybrid 2019", min_enable_speed=10. * CV.MPH_TO_MS), + CAR.KIA_NIRO_HEV_2021: HyundaiCarInfo("Kia Niro Hybrid 2021-22"), + CAR.KIA_OPTIMA: [ + HyundaiCarInfo("Kia Optima 2017", min_steer_speed=32. * CV.MPH_TO_MS), + HyundaiCarInfo("Kia Optima 2019"), + ], + CAR.KIA_SELTOS: HyundaiCarInfo("Kia Seltos 2021"), + CAR.KIA_SORENTO: HyundaiCarInfo("Kia Sorento 2018-19", video_link="https://www.youtube.com/watch?v=Fkh3s6WHJz8"), + CAR.KIA_STINGER: HyundaiCarInfo("Kia Stinger 2018", video_link="https://www.youtube.com/watch?v=MJ94qoofYw0"), + CAR.KIA_CEED: HyundaiCarInfo("Kia Ceed 2019"), + + # Genesis + CAR.GENESIS_G70: HyundaiCarInfo("Genesis G70 2018", "All"), + CAR.GENESIS_G70_2020: HyundaiCarInfo("Genesis G70 2020", "All"), + CAR.GENESIS_G80: HyundaiCarInfo("Genesis G80 2018", "All"), + CAR.GENESIS_G90: HyundaiCarInfo("Genesis G90 2018", "All"), +} + class Buttons: NONE = 0 RES_ACCEL = 1 diff --git a/selfdrive/car/mazda/values.py b/selfdrive/car/mazda/values.py index 1fcf18428..969b43aeb 100644 --- a/selfdrive/car/mazda/values.py +++ b/selfdrive/car/mazda/values.py @@ -1,4 +1,7 @@ +from typing import Dict, List, Union + from selfdrive.car import dbc_dict +from selfdrive.car.docs_definitions import CarInfo from cereal import car Ecu = car.CarParams.Ecu @@ -14,6 +17,7 @@ class CarControllerParams: STEER_DRIVER_FACTOR = 1 # from dbc STEER_ERROR_MAX = 350 # max delta between torque cmd and torque motor + class CAR: CX5 = "MAZDA CX-5" CX9 = "MAZDA CX-9" @@ -22,6 +26,17 @@ class CAR: CX9_2021 = "MAZDA CX-9 2021" CX5_2022 = "MAZDA CX-5 2022" + +CAR_INFO: Dict[str, Union[CarInfo, List[CarInfo]]] = { + CAR.CX5: CarInfo("Mazda CX-5 2017, 2019", "All"), # TODO: verify years for first 4 + CAR.CX9: CarInfo("Mazda CX-9 2016-17", "All"), + CAR.MAZDA3: CarInfo("Mazda 3 2017", "All"), + CAR.MAZDA6: CarInfo("Mazda 6 2017", "All"), + CAR.CX9_2021: CarInfo("Mazda CX-9 2021", "All"), + CAR.CX5_2022: CarInfo("Mazda CX-5 2022", "All"), +} + + class LKAS_LIMITS: STEER_THRESHOLD = 15 DISABLE_SPEED = 45 # kph diff --git a/selfdrive/car/mock/values.py b/selfdrive/car/mock/values.py index 0dd91565b..77d8171b0 100644 --- a/selfdrive/car/mock/values.py +++ b/selfdrive/car/mock/values.py @@ -1,2 +1,10 @@ +from typing import Dict, List, Union + +from selfdrive.car.docs_definitions import CarInfo + + class CAR: MOCK = 'mock' + + +CAR_INFO: Dict[str, Union[CarInfo, List[CarInfo]]] = {} diff --git a/selfdrive/car/nissan/values.py b/selfdrive/car/nissan/values.py index f7001d141..a201c9113 100644 --- a/selfdrive/car/nissan/values.py +++ b/selfdrive/car/nissan/values.py @@ -1,4 +1,7 @@ +from typing import Dict, List, Union + from selfdrive.car import dbc_dict +from selfdrive.car.docs_definitions import CarInfo from cereal import car Ecu = car.CarParams.Ecu @@ -10,6 +13,7 @@ class CarControllerParams: LKAS_MAX_TORQUE = 1 # A value of 1 is easy to overpower STEER_THRESHOLD = 1.0 + class CAR: XTRAIL = "NISSAN X-TRAIL 2017" LEAF = "NISSAN LEAF 2018" @@ -20,6 +24,13 @@ class CAR: ALTIMA = "NISSAN ALTIMA 2020" +CAR_INFO: Dict[str, Union[CarInfo, List[CarInfo]]] = { + CAR.XTRAIL: CarInfo("Nissan X-Trail 2017", "ProPILOT"), + CAR.LEAF: CarInfo("Nissan Leaf 2018-22", "ProPILOT"), + CAR.ROGUE: CarInfo("Nissan Rogue 2018-20", "ProPILOT"), + CAR.ALTIMA: CarInfo("Nissan Altima 2019-20", "ProPILOT"), +} + FINGERPRINTS = { CAR.XTRAIL: [ { diff --git a/selfdrive/car/subaru/values.py b/selfdrive/car/subaru/values.py index ee1148529..27210d8f5 100644 --- a/selfdrive/car/subaru/values.py +++ b/selfdrive/car/subaru/values.py @@ -1,4 +1,7 @@ +from typing import Dict, List, Union + from selfdrive.car import dbc_dict +from selfdrive.car.docs_definitions import CarInfo from cereal import car Ecu = car.CarParams.Ecu @@ -15,6 +18,7 @@ class CarControllerParams: self.STEER_DRIVER_MULTIPLIER = 10 # weight driver torque heavily self.STEER_DRIVER_FACTOR = 1 # from dbc + class CAR: ASCENT = "SUBARU ASCENT LIMITED 2019" IMPREZA = "SUBARU IMPREZA LIMITED 2019" @@ -25,6 +29,21 @@ class CAR: OUTBACK_PREGLOBAL = "SUBARU OUTBACK 2015 - 2017" OUTBACK_PREGLOBAL_2018 = "SUBARU OUTBACK 2018 - 2019" + +CAR_INFO: Dict[str, Union[CarInfo, List[CarInfo]]] = { + CAR.ASCENT: CarInfo("Subaru Ascent 2019", "EyeSight"), + CAR.IMPREZA: [ + CarInfo("Subaru Impreza 2017-19", "EyeSight"), + CarInfo("Subaru Crosstrek 2018-20", "EyeSight"), + ], + CAR.FORESTER: CarInfo("Subaru Forester 2019-21", "EyeSight"), + CAR.FORESTER_PREGLOBAL: CarInfo("Subaru Forester 2017-18", "EyeSight"), + CAR.LEGACY_PREGLOBAL: CarInfo("Subaru Legacy 2015-18", "EyeSight"), + CAR.OUTBACK_PREGLOBAL: CarInfo("Subaru Outback 2015-17", "EyeSight"), + CAR.OUTBACK_PREGLOBAL_2018: CarInfo("Subaru Outback 2018-19", "EyeSight"), +} + + FINGERPRINTS = { CAR.IMPREZA_2020: [{ 2: 8, 64: 8, 65: 8, 72: 8, 73: 8, 280: 8, 281: 8, 282: 8, 290: 8, 312: 8, 313: 8, 314: 8, 315: 8, 316: 8, 326: 8, 372: 8, 544: 8, 545: 8, 546: 8, 552: 8, 554: 8, 557: 8, 576: 8, 577: 8, 722: 8, 801: 8, 802: 8, 803: 8, 805: 8, 808: 8, 816: 8, 826: 8, 837: 8, 838: 8, 839: 8, 842: 8, 912: 8, 915: 8, 940: 8, 1617: 8, 1632: 8, 1650: 8, 1677: 8, 1697: 8, 1722: 8, 1743: 8, 1759: 8, 1786: 5, 1787: 5, 1788: 8, 1809: 8, 1813: 8, 1817: 8, 1821: 8, 1840: 8, 1848: 8, 1924: 8, 1932: 8, 1952: 8, 1960: 8, 1968: 8, 1976: 8, 2015: 8, 2016: 8, 2024: 8 diff --git a/selfdrive/car/tesla/values.py b/selfdrive/car/tesla/values.py index 616933789..4f07b6fea 100644 --- a/selfdrive/car/tesla/values.py +++ b/selfdrive/car/tesla/values.py @@ -1,14 +1,24 @@ from collections import namedtuple +from typing import Dict, List, Union + from selfdrive.car import dbc_dict +from selfdrive.car.docs_definitions import CarInfo from cereal import car Button = namedtuple('Button', ['event_type', 'can_addr', 'can_msg', 'values']) AngleRateLimit = namedtuple('AngleRateLimit', ['speed_points', 'max_angle_diff_points']) + class CAR: AP1_MODELS = 'TESLA AP1 MODEL S' AP2_MODELS = 'TESLA AP2 MODEL S' + +CAR_INFO: Dict[str, Union[CarInfo, List[CarInfo]]] = { + CAR.AP1_MODELS: CarInfo("Tesla AP1 Model S", "All"), + CAR.AP2_MODELS: CarInfo("Tesla AP2 Model S", "All"), +} + FINGERPRINTS = { CAR.AP2_MODELS: [ { diff --git a/selfdrive/car/tests/test_docs.py b/selfdrive/car/tests/test_docs.py new file mode 100755 index 000000000..33ca9a192 --- /dev/null +++ b/selfdrive/car/tests/test_docs.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +import unittest + +from selfdrive.car.docs import CARS_MD_OUT, CARS_MD_TEMPLATE, generate_cars_md, get_tier_car_rows + + +class TestCarDocs(unittest.TestCase): + def test_car_docs(self): + generated_cars_md = generate_cars_md(get_tier_car_rows(), CARS_MD_TEMPLATE) + with open(CARS_MD_OUT, "r") as f: + current_cars_md = f.read() + + self.assertEqual(generated_cars_md, current_cars_md, + "Run selfdrive/car/docs.py to generate new supported cars documentation") + + +if __name__ == "__main__": + unittest.main() diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index acf3f42c3..a11ad7959 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -1,9 +1,12 @@ from collections import defaultdict -from enum import IntFlag +from dataclasses import dataclass +from enum import Enum, IntFlag +from typing import Dict, List, Union 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, Star Ecu = car.CarParams.Ecu MIN_ACC_SPEED = 19. * CV.MPH_TO_MS @@ -70,6 +73,84 @@ class CAR: LEXUS_RX_TSS2 = "LEXUS RX 2020" LEXUS_RXH_TSS2 = "LEXUS RX HYBRID 2020" + +class Footnote(Enum): + DSU = CarFootnote( + "When disconnecting the Driver Support Unit (DSU), 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) + CAMRY = CarFootnote( + "28mph for Camry 4CYL L, 4CYL LE and 4CYL SE which don't have Full-Speed Range Dynamic Radar Cruise Control.", + Column.FSR_LONGITUDINAL) + ANGLE_SENSOR = CarFootnote( + "An inaccurate steering wheel angle sensor makes precise control difficult.", + Column.STEERING_TORQUE, star=Star.HALF) + + +@dataclass +class ToyotaCarInfo(CarInfo): + package: str = "All" + good_torque: bool = True + + +CAR_INFO: Dict[str, Union[ToyotaCarInfo, List[ToyotaCarInfo]]] = { + # Toyota + CAR.ALPHARD_TSS2: ToyotaCarInfo("Toyota Alphard 2019-20"), + CAR.AVALON: ToyotaCarInfo("Toyota Avalon 2016-18", "TSS-P", footnotes=[Footnote.DSU]), + CAR.AVALON_2019: ToyotaCarInfo("Toyota Avalon 2019-21", "TSS-P", footnotes=[Footnote.DSU]), + CAR.AVALONH_2019: ToyotaCarInfo("Toyota Avalon Hybrid 2019-21", "TSS-P", footnotes=[Footnote.DSU]), + CAR.AVALON_TSS2: ToyotaCarInfo("Toyota Avalon 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.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"), + CAR.CHRH: ToyotaCarInfo("Toyota C-HR Hybrid 2017-19"), + CAR.COROLLA: ToyotaCarInfo("Toyota Corolla 2017-19", footnotes=[Footnote.DSU]), + CAR.COROLLA_TSS2: [ + ToyotaCarInfo("Toyota Corolla 2020-22", video_link="https://www.youtube.com/watch?v=_66pXk0CBYA"), + ToyotaCarInfo("Toyota Corolla Hatchback 2019-22", video_link="https://www.youtube.com/watch?v=_66pXk0CBYA"), + ], + CAR.COROLLAH_TSS2: [ + ToyotaCarInfo("Toyota Corolla Hybrid 2020-22"), + ToyotaCarInfo("Lexus UX Hybrid 2019-21"), + ], + CAR.HIGHLANDER: ToyotaCarInfo("Toyota Highlander 2017-19", video_link="https://www.youtube.com/watch?v=0wS0wXSLzoo", footnotes=[Footnote.DSU]), + CAR.HIGHLANDER_TSS2: ToyotaCarInfo("Toyota Highlander 2020-22"), + CAR.HIGHLANDERH: ToyotaCarInfo("Toyota Highlander Hybrid 2017-19", footnotes=[Footnote.DSU]), + CAR.HIGHLANDERH_TSS2: ToyotaCarInfo("Toyota Highlander Hybrid 2020-22"), + CAR.PRIUS: [ + ToyotaCarInfo("Toyota Prius 2016-20", "TSS-P", video_link="https://www.youtube.com/watch?v=8zopPJI8XQ0", footnotes=[Footnote.DSU, Footnote.ANGLE_SENSOR]), + ToyotaCarInfo("Toyota Prius Prime 2017-20", video_link="https://www.youtube.com/watch?v=8zopPJI8XQ0", footnotes=[Footnote.DSU, Footnote.ANGLE_SENSOR]), + ], + CAR.PRIUS_V: ToyotaCarInfo("Toyota Prius v 2017", "TSS-P", min_enable_speed=MIN_ACC_SPEED, footnotes=[Footnote.DSU, Footnote.ANGLE_SENSOR]), + CAR.PRIUS_TSS2: [ + ToyotaCarInfo("Toyota Prius 2021-22", video_link="https://www.youtube.com/watch?v=J58TvCpUd4U"), + ToyotaCarInfo("Toyota Prius Prime 2021-22", video_link="https://www.youtube.com/watch?v=J58TvCpUd4U"), + ], + CAR.RAV4: ToyotaCarInfo("Toyota RAV4 2016-18", "TSS-P", footnotes=[Footnote.DSU]), + CAR.RAV4H: ToyotaCarInfo("Toyota RAV4 Hybrid 2016-18", "TSS-P", footnotes=[Footnote.DSU]), + CAR.RAV4_TSS2: ToyotaCarInfo("Toyota RAV4 2019-21", video_link="https://www.youtube.com/watch?v=wJxjDd42gGA"), + CAR.RAV4H_TSS2: ToyotaCarInfo("Toyota RAV4 Hybrid 2019-21"), + CAR.MIRAI: ToyotaCarInfo("Toyota Mirai 2021"), + CAR.SIENNA: ToyotaCarInfo("Toyota Sienna 2018-20", video_link="https://www.youtube.com/watch?v=q1UPOo4Sh68", footnotes=[Footnote.DSU]), + + # Lexus + CAR.LEXUS_CTH: ToyotaCarInfo("Lexus CT Hybrid 2017-18", "LSS", footnotes=[Footnote.DSU]), + CAR.LEXUS_ESH: ToyotaCarInfo("Lexus ES Hybrid 2017-18", "LSS", footnotes=[Footnote.DSU]), + CAR.LEXUS_ES_TSS2: ToyotaCarInfo("Lexus ES 2019-21"), + CAR.LEXUS_ESH_TSS2: ToyotaCarInfo("Lexus ES Hybrid 2019-21"), + CAR.LEXUS_IS: ToyotaCarInfo("Lexus IS 2017-19"), + CAR.LEXUS_NX: ToyotaCarInfo("Lexus NX 2018-19", footnotes=[Footnote.DSU]), + CAR.LEXUS_NXH: ToyotaCarInfo("Lexus NX Hybrid 2018-19", footnotes=[Footnote.DSU]), + CAR.LEXUS_NX_TSS2: ToyotaCarInfo("Lexus NX 2020"), + CAR.LEXUS_RC: ToyotaCarInfo("Lexus RC 2020"), + CAR.LEXUS_RX: ToyotaCarInfo("Lexus RX 2016-18", footnotes=[Footnote.DSU]), + CAR.LEXUS_RXH: ToyotaCarInfo("Lexus RX Hybrid 2016-19", footnotes=[Footnote.DSU]), + CAR.LEXUS_RX_TSS2: ToyotaCarInfo("Lexus RX 2020-21"), + CAR.LEXUS_RXH_TSS2: ToyotaCarInfo("Lexus RX Hybrid 2020-21"), +} + # (addr, cars, bus, 1/freq*100, vl) STATIC_DSU_MSGS = [ (0x128, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.LEXUS_NXH, CAR.LEXUS_NX, CAR.RAV4, CAR.COROLLA, CAR.AVALON), 1, 3, b'\xf4\x01\x90\x83\x00\x37'), diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py index f7e1612a9..7d7c0c978 100755 --- a/selfdrive/car/volkswagen/values.py +++ b/selfdrive/car/volkswagen/values.py @@ -1,8 +1,11 @@ from collections import defaultdict -from typing import Dict +from dataclasses import dataclass +from enum import Enum +from typing import Dict, List, Union from cereal import car from selfdrive.car import dbc_dict +from selfdrive.car.docs_definitions import CarFootnote, CarInfo, Column Ecu = car.CarParams.Ecu NetworkLocation = car.CarParams.NetworkLocation @@ -87,6 +90,76 @@ class CAR: SKODA_SUPERB_MK3 = "SKODA SUPERB 3RD GEN" # Chassis 3V/NP, Mk3 Skoda Superb and variants SKODA_OCTAVIA_MK3 = "SKODA OCTAVIA 3RD GEN" # Chassis NE, Mk3 Skoda Octavia and variants + +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.", + 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 " + + "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.", + Column.MODEL) + + +@dataclass +class VWCarInfo(CarInfo): + package: str = "Driver Assistance" + good_torque: bool = True + + +CAR_INFO: Dict[str, Union[VWCarInfo, List[VWCarInfo]]] = { + CAR.ARTEON_MK1: VWCarInfo("Volkswagen Arteon 2018, 2021", footnotes=[Footnote.VW_HARNESS]), + CAR.ATLAS_MK1: VWCarInfo("Volkswagen Atlas 2018-19, 2022", footnotes=[Footnote.VW_HARNESS]), + CAR.GOLF_MK7: [ + VWCarInfo("Volkswagen e-Golf 2014, 2019-20"), + VWCarInfo("Volkswagen Golf 2015-20"), + VWCarInfo("Volkswagen Golf Alltrack 2017-18"), + VWCarInfo("Volkswagen Golf GTE 2016"), + VWCarInfo("Volkswagen Golf GTI 2018-20"), + VWCarInfo("Volkswagen Golf R 2016-19"), + VWCarInfo("Volkswagen Golf SportsVan 2016"), + VWCarInfo("Volkswagen Golf SportWagen 2015"), + ], + CAR.JETTA_MK7: [ + VWCarInfo("Volkswagen Jetta 2018-21"), + VWCarInfo("Volkswagen Jetta GLI 2021"), + ], + CAR.PASSAT_MK8: VWCarInfo("Volkswagen Passat 2016-18", footnotes=[Footnote.PASSAT]), + CAR.POLO_MK6: VWCarInfo("Volkswagen Polo 2020"), + CAR.TAOS_MK1: VWCarInfo("Volkswagen Taos 2022", footnotes=[Footnote.VW_HARNESS]), + CAR.TCROSS_MK1: VWCarInfo("Volkswagen T-Cross 2021", footnotes=[Footnote.VW_HARNESS]), + CAR.TIGUAN_MK2: VWCarInfo("Volkswagen Tiguan 2020-22", footnotes=[Footnote.VW_HARNESS]), + CAR.TOURAN_MK2: VWCarInfo("Volkswagen Touran 2017"), + CAR.TRANSPORTER_T61: [ + VWCarInfo("Volkswagen Caravelle 2020", footnotes=[Footnote.VW_HARNESS]), + VWCarInfo("Volkswagen California 2021", footnotes=[Footnote.VW_HARNESS]), + ], + CAR.TROC_MK1: VWCarInfo("Volkswagen T-Roc 2021", footnotes=[Footnote.VW_HARNESS]), + CAR.AUDI_A3_MK3: [ + VWCarInfo("Audi A3 2014-19", "ACC + Lane Assist"), + VWCarInfo("Audi A3 Sportback e-tron 2017-18", "ACC + Lane Assist"), + VWCarInfo("Audi S3 2015-17", "ACC + Lane Assist"), + ], + CAR.AUDI_Q2_MK1: VWCarInfo("Audi Q2 2018", "ACC + Lane Assist"), + CAR.AUDI_Q3_MK2: VWCarInfo("Audi Q3 2020-21", "ACC + Lane Assist"), + 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"), + 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"), + CAR.SKODA_OCTAVIA_MK3: [ + VWCarInfo("Škoda Octavia 2015, 2018-19"), + VWCarInfo("Škoda Octavia RS 2016"), + ], +} + # All supported cars should return FW from the engine, srs, eps, and fwdRadar. Cars # with a manual trans won't return transmission firmware, but all other cars will. #