diff --git a/docs/CARS_generated.md b/docs/CARS_generated.md
index 63b0306258..784cd4206f 100644
--- a/docs/CARS_generated.md
+++ b/docs/CARS_generated.md
@@ -1,6 +1,6 @@
## Gold Cars
-|Make|Model (US Market Reference)|Supported Package|openpilot Longitudinal|FSR Longitudinal|FSR Steering|Steering Torque|Actively Maintained|
+|Make|Model|Supported Package|openpilot Longitudinal|FSR Longitudinal|FSR Steering|Steering Torque|Actively Maintained|
|---|---|---|:---:|:---:|:---:|:---:|:---:|
|Genesis|G70 2020|All|
|
|
|
|
|
|Hyundai|Elantra 2021|SCC + LKAS|
|
|
|
|
|
@@ -25,7 +25,7 @@
|Lexus|RX 2021|All|
|
|
|
|
|
|Lexus|RX Hybrid 2021|All|
|
|
|
|
|
|Toyota|Alphard 2020|All|
|
|
|
|
|
-|Toyota|Camry 2022|All|
|
|
|
|
|
+|Toyota|Camry 2022|All|
|
2|
|
|
|
|Toyota|Camry Hybrid 2022|All|
|
|
|
|
|
|Toyota|Corolla Hybrid TSS2 2022|All|
|
|
|
|
|
|Toyota|Corolla TSS2 2022|All|
|
|
|
|
|
@@ -38,9 +38,8 @@
## Silver Cars
-|Make|Model (US Market Reference)|Supported Package|openpilot Longitudinal|FSR Longitudinal|FSR Steering|Steering Torque|Actively Maintained|
+|Make|Model|Supported Package|openpilot Longitudinal|FSR Longitudinal|FSR Steering|Steering Torque|Actively Maintained|
|---|---|---|:---:|:---:|:---:|:---:|:---:|
-|Acura|RDX 2021|All|
|
|
|
|
|
|Audi|A3 2019|ACC + Lane Assist|
|
|
|
|
|
|Audi|A3 Sportback e-tron 2018|ACC + Lane Assist|
|
|
|
|
|
|Audi|Q2 2018|ACC + Lane Assist|
|
|
|
|
|
@@ -48,15 +47,6 @@
|Genesis|G70 2018|All|
|
|
|
|
|
|Genesis|G80 2018|All|
|
|
|
|
|
|Genesis|G90 2018|All|
|
|
|
|
|
-|Honda|Accord 2021|All|
|
|
|
|
|
-|Honda|Accord Hybrid 2021|All|
|
|
|
|
|
-|Honda|CR-V 2021|Honda Sensing|
|
|
|
|
|
-|Honda|CR-V Hybrid 2019|Honda Sensing|
|
|
|
|
|
-|Honda|Civic (Bosch) 2020|All|
|
|
|
|
|
-|Honda|Civic 2018|Honda Sensing|
|
|
|
|
|
-|Honda|Civic Sedan 1.6 DIESEL 2020|All|
|
|
|
|
|
-|Honda|E 2020|All|
|
|
|
|
|
-|Honda|Insight 2021|All|
|
|
|
|
|
|Hyundai|Ioniq Electric 2020|SCC + LKAS|
|
|
|
|
|
|Hyundai|Ioniq Hybrid 2022|SCC + LFA|
|
|
|
|
|
|Hyundai|Ioniq Plug-In Hybrid 2021|SCC + LKAS|
|
|
|
|
|
@@ -68,27 +58,25 @@
|Kia|Optima SX 2019 & 2016 2019|SCC + LKAS|
|
|
|
|
|
|Kia|Sorento GT-Line 2019|SCC + LKAS|
|
|
|
|
|
|Kia|Stinger GT2 2018|SCC + LKAS|
|
|
|
|
|
-|Lexus|CT Hybrid 2018|LSS|
|
|
|
|
|
-|Lexus|ES Hybrid 2018|LSS|
|
|
|
|
|
-|Lexus|NX 2019|All|
|
|
|
|
|
-|Lexus|NX Hybrid 2019|All|
|
|
|
|
|
-|Lexus|RX 2018|All|
|
|
|
|
|
-|Lexus|RX Hybrid 2019|All|
|
|
|
|
|
+|Lexus|CT Hybrid 2018|LSS|
1|
|
|
|
|
+|Lexus|ES Hybrid 2018|LSS|
1|
|
|
|
|
+|Lexus|NX 2019|All|
1|
|
|
|
|
+|Lexus|NX Hybrid 2019|All|
1|
|
|
|
|
+|Lexus|RX 2018|All|
1|
|
|
|
|
+|Lexus|RX Hybrid 2019|All|
1|
|
|
|
|
|SEAT|Ateca 2018|Driver Assistance|
|
|
|
|
|
|SEAT|Leon 2020|Driver Assistance|
|
|
|
|
|
|Toyota|Avalon 2022|All|
|
|
|
|
|
|Toyota|C-HR 2021|All|
|
|
|
|
|
|Toyota|C-HR Hybrid 2019|All|
|
|
|
|
|
-|Toyota|Camry 2020|All|
|
|
|
|
|
-|Toyota|Camry Hybrid 2020|All|
|
|
|
|
|
-|Toyota|Highlander 2019|All|
|
|
|
|
|
-|Toyota|Highlander Hybrid 2019|All|
|
|
|
|
|
-|Toyota|Prius 2020|TSS-P|
|
|
|
|
|
-|Toyota|Prius v 2017|TSS-P|
|
|
|
|
|
-|Toyota|RAV4 Hybrid 2018|TSS-P|
|
|
|
|
|
-|Toyota|Sienna 2020|All|
|
|
|
|
|
-|Volkswagen|Arteon 2021|Driver Assistance|
|
|
|
|
|
-|Volkswagen|Atlas 2022|Driver Assistance|
|
|
|
|
|
+|Toyota|Camry 2020|All|
|
2|
|
|
|
+|Toyota|Camry Hybrid 2020|All|
|
2|
|
|
|
+|Toyota|Highlander 2019|All|
1|
|
|
|
|
+|Toyota|Highlander Hybrid 2019|All|
1|
|
|
|
|
+|Toyota|RAV4 Hybrid 2018|TSS-P|
1|
|
|
|
|
+|Toyota|Sienna 2020|All|
1|
|
|
|
|
+|Volkswagen|Arteon 20216|Driver Assistance|
|
|
|
|
|
+|Volkswagen|Atlas 20226|Driver Assistance|
|
|
|
|
|
|Volkswagen|Golf 2020|Driver Assistance|
|
|
|
|
|
|Volkswagen|Golf Alltrack 2018|Driver Assistance|
|
|
|
|
|
|Volkswagen|Golf GTE 2016|Driver Assistance|
|
|
|
|
|
@@ -98,15 +86,15 @@
|Volkswagen|Golf SportsVan 2016|Driver Assistance|
|
|
|
|
|
|Volkswagen|Jetta 2020|Driver Assistance|
|
|
|
|
|
|Volkswagen|Jetta GLI 2021|Driver Assistance|
|
|
|
|
|
-|Volkswagen|Passat 2018|Driver Assistance|
|
|
|
|
|
+|Volkswagen|Passat 20185|Driver Assistance|
|
|
|
|
|
|Volkswagen|Polo 2020|Driver Assistance|
|
|
|
|
|
-|Volkswagen|T-Cross 2021|Driver Assistance|
|
|
|
|
|
-|Volkswagen|T-Roc 2021|Driver Assistance|
|
|
|
|
|
-|Volkswagen|Taos 2022|Driver Assistance|
|
|
|
|
|
-|Volkswagen|Tiguan 2020|Driver Assistance|
|
|
|
|
|
+|Volkswagen|T-Cross 20216|Driver Assistance|
|
|
|
|
|
+|Volkswagen|T-Roc 20216|Driver Assistance|
|
|
|
|
|
+|Volkswagen|Taos 20226|Driver Assistance|
|
|
|
|
|
+|Volkswagen|Tiguan 20206|Driver Assistance|
|
|
|
|
|
|Volkswagen|Touran 2017|Driver Assistance|
|
|
|
|
|
|Volkswagen|e-Golf 2020|Driver Assistance|
|
|
|
|
|
-|Škoda|Kamiq 2021|Driver Assistance|
|
|
|
|
|
+|Škoda|Kamiq 20214|Driver Assistance|
|
|
|
|
|
|Škoda|Karoq 2019|Driver Assistance|
|
|
|
|
|
|Škoda|Kodiaq 2019|Driver Assistance|
|
|
|
|
|
|Škoda|Octavia 2019|Driver Assistance|
|
|
|
|
|
@@ -116,28 +104,36 @@
## Bronze Cars
-|Make|Model (US Market Reference)|Supported Package|openpilot Longitudinal|FSR Longitudinal|FSR Steering|Steering Torque|Actively Maintained|
+|Make|Model|Supported Package|openpilot Longitudinal|FSR Longitudinal|FSR Steering|Steering Torque|Actively Maintained|
|---|---|---|:---:|:---:|:---:|:---:|:---:|
-|Acura|ILX 2019|AcuraWatch Plus|
|
|
|
|
|
-|Acura|RDX 2018|AcuraWatch Plus|
|
|
|
|
|
-|Cadillac|Escalade ESV 2016|ACC + LKAS|
|
|
|
|
|
-|Chevrolet|Volt Premier 2018|Adaptive Cruise|
|
|
|
|
|
+|Acura|ILX 2019|AcuraWatch Plus|
|
|
|
|
|
+|Acura|RDX 2018|AcuraWatch Plus|
|
|
|
|
|
+|Acura|RDX 2021|All|
|
|
|
|
|
+|Cadillac|Escalade ESV 20163|ACC + LKAS|
|
|
|
|
|
+|Chevrolet|Volt Premier 20183|Adaptive Cruise|
|
|
|
|
|
|Chrysler|Pacifica 2018|Adaptive Cruise|
|
|
|
|
|
|Chrysler|Pacifica 2020|Adaptive Cruise|
|
|
|
|
|
|Chrysler|Pacifica Hybrid 2017|Adaptive Cruise|
|
|
|
|
|
|Chrysler|Pacifica Hybrid 2018|Adaptive Cruise|
|
|
|
|
|
|Chrysler|Pacifica Hybrid 2019|Adaptive Cruise|
|
|
|
|
|
-|GMC|Acadia Denali 2018|Adaptive Cruise|
|
|
|
|
|
-|Honda|CR-V 2016|Touring|
|
|
|
|
|
-|Honda|CR-V EU 2016|Touring|
|
|
|
|
|
-|Honda|Fit 2019|Honda Sensing|
|
|
|
|
|
-|Honda|Freed 2020|Honda Sensing|
|
|
|
|
|
-|Honda|HR-V 2020|Honda Sensing|
|
|
|
|
|
+|GMC|Acadia Denali 20183|Adaptive Cruise|
|
|
|
|
|
+|Honda|Accord 2021|All|
|
|
|
|
|
+|Honda|Accord Hybrid 2021|All|
|
|
|
|
|
+|Honda|CR-V 2016|Touring|
|
|
|
|
|
+|Honda|CR-V 2021|Honda Sensing|
|
|
|
|
|
+|Honda|CR-V Hybrid 2019|Honda Sensing|
|
|
|
|
|
+|Honda|Civic Hatchback 2021|All|
|
|
|
|
|
+|Honda|Civic Sedan/Coupe 2018|Honda Sensing|
|
|
|
|
|
+|Honda|Civic Sedan/Coupe 2020|All|
|
|
|
|
|
+|Honda|E 2020|All|
|
|
|
|
|
+|Honda|Fit 2019|Honda Sensing|
|
|
|
|
|
+|Honda|Freed 2020|Honda Sensing|
|
|
|
|
|
+|Honda|HR-V 2020|Honda Sensing|
|
|
|
|
|
+|Honda|Insight 2021|All|
|
|
|
|
|
|Honda|Odyssey 2020|Honda Sensing|
|
|
|
|
|
-|Honda|Odyssey CHN 2020|Honda Sensing|
|
|
|
|
|
-|Honda|Passport 2021|All|
|
|
|
|
|
-|Honda|Pilot 2021|Honda Sensing|
|
|
|
|
|
-|Honda|Ridgeline 2021|Honda Sensing|
|
|
|
|
|
+|Honda|Passport 2021|All|
|
|
|
|
|
+|Honda|Pilot 2021|Honda Sensing|
|
|
|
|
|
+|Honda|Ridgeline 2021|Honda Sensing|
|
|
|
|
|
|Hyundai|Elantra 2019|SCC + LKAS|
|
|
|
|
|
|Hyundai|Genesis 2016|SCC + LKAS|
|
|
|
|
|
|Hyundai|Ioniq Electric Limited 2019|SCC + LKAS|
|
|
|
|
|
@@ -156,10 +152,12 @@
|Subaru|Forester 2021|EyeSight|
|
|
|
|
|
|Subaru|Impreza Limited 2019|EyeSight|
|
|
|
|
|
|Subaru|Impreza Sport 2021|EyeSight|
|
|
|
|
|
-|Toyota|Avalon 2021|TSS-P|
|
|
|
|
|
+|Toyota|Avalon 2021|TSS-P|
1|
|
|
|
|
|Toyota|Avalon 2022|TSS-P|
|
|
|
|
|
-|Toyota|Avalon Hybrid 2021|TSS-P|
|
|
|
|
|
-|Toyota|Corolla 2019|All|
|
|
|
|
|
-|Toyota|RAV4 2018|TSS-P|
|
|
|
|
|
-|Volkswagen|California 2021|Driver Assistance|
|
|
|
|
|
-|Volkswagen|Caravelle 2020|Driver Assistance|
|
|
|
|
|
+|Toyota|Avalon Hybrid 2021|TSS-P|
1|
|
|
|
|
+|Toyota|Corolla 2019|All|
1|
|
|
|
|
+|Toyota|Prius 2020|TSS-P|
1|
|
|
7|
|
+|Toyota|Prius v 2017|TSS-P|
1|
|
|
7|
|
+|Toyota|RAV4 2018|TSS-P|
1|
|
|
|
|
+|Volkswagen|California 20216|Driver Assistance|
|
|
|
|
|
+|Volkswagen|Caravelle 20206|Driver Assistance|
|
|
|
|
|
diff --git a/docs/cars.py b/docs/cars.py
index 8062477479..a81296f71d 100755
--- a/docs/cars.py
+++ b/docs/cars.py
@@ -2,10 +2,14 @@
from collections import defaultdict, namedtuple
from enum import Enum
import os
+from typing import Dict
from common.basedir import BASEDIR
from common.params import Params
from selfdrive.car.car_helpers import interfaces, get_interface_attr
+from selfdrive.car.toyota.values import CAR as TOYOTA
+from selfdrive.car.volkswagen.values import CAR as VOLKSWAGEN
+from selfdrive.car.gm.values import CAR as GM
from selfdrive.test.test_routes import non_tested_cars
@@ -15,54 +19,127 @@ class Tier(Enum):
BRONZE = "Bronze"
-class Car:
- def __init__(self, car_info, CP):
- self.make, self.model = car_info.name.split(' ', 1)
-
- assert len(car_info.years), 'Model {} has no years listed'.format(CP.carFingerprint)
-
- # TODO: properly format model years
- years = ' ' + str(max(car_info.years))
- self.model_string = "{}{}".format(self.model, years)
- self.package = car_info.package
+class Column(Enum):
+ MAKE = "Make"
+ MODEL = "Model"
+ PACKAGE = "Supported Package"
+ LONGITUDINAL = "openpilot Longitudinal"
+ FSR_LONGITUDINAL = "FSR Longitudinal"
+ FSR_STEERING = "FSR Steering"
+ STEERING_TORQUE = "Steering Torque"
+ SUPPORTED = "Actively Maintained"
- self.stars = Stars(
- CP.openpilotLongitudinalControl,
- CP.minEnableSpeed <= 1e-3, # TODO: 0 is probably okay
- CP.minSteerSpeed <= 1e-3,
- CP.carName in MAKES_GOOD_STEERING_TORQUE,
- # TODO: make sure this check is complete
- CP.carFingerprint not in non_tested_cars,
- )
- def format_stars(self):
- # TODO: exceptions and half stars
- return [STAR_ICON_FULL if cat else STAR_ICON_EMPTY for cat in self.stars]
-
- @property
- def tier(self):
- return {5: Tier.GOLD, 4: Tier.SILVER}.get(sum(self.stars), Tier.BRONZE)
+StarColumns = list(Column)[3:]
+CarException = namedtuple("CarException", ["cars", "text", "column", "star"], defaults=[None])
def make_row(columns):
return "|{}|".format("|".join(columns))
-# TODO: unify with column names below?
-Stars = namedtuple("Stars", ["op_long", "fsr_long", "fsr_lat", "steering_torque", "well_supported"])
+def get_star_icon(variant):
+ return '
'.format(variant)
+
+
+def get_exceptions(CP) -> Dict[Column, CarException]:
+ exceptions = {}
+ for car_exception in CAR_EXCEPTIONS:
+ if CP.carFingerprint in car_exception.cars:
+ exceptions[car_exception.column] = car_exception
+ return exceptions
-STAR_ICON_FULL = '
'
-STAR_ICON_HALF = '
'
-STAR_ICON_EMPTY = '
'
CARS_MD_OUT = os.path.join(BASEDIR, "docs", "CARS_generated.md")
-CAR_TABLE_COLUMNS = make_row(['Make', 'Model (US Market Reference)', 'Supported Package', 'openpilot Longitudinal',
- 'FSR Longitudinal', 'FSR Steering', 'Steering Torque', 'Actively Maintained'])
CAR_TABLE_HEADER = make_row(["---"] * 3 + [":---:"] * 5) # first three aren't centered
-CAR_ROW_TEMPLATE = make_row(["{}"] * 8)
# TODO: which other makes?
MAKES_GOOD_STEERING_TORQUE = ["toyota", "hyundai", "volkswagen"]
+CAR_EXCEPTIONS = [
+ CarException([TOYOTA.LEXUS_CTH, TOYOTA.LEXUS_ESH, TOYOTA.LEXUS_NX, TOYOTA.LEXUS_NXH, TOYOTA.LEXUS_RX,
+ TOYOTA.LEXUS_RXH, TOYOTA.AVALON, TOYOTA.AVALONH_2019, TOYOTA.COROLLA, TOYOTA.HIGHLANDER,
+ TOYOTA.HIGHLANDERH, TOYOTA.PRIUS, TOYOTA.PRIUS_V, TOYOTA.RAV4, TOYOTA.RAV4H, TOYOTA.SIENNA],
+ "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="half"),
+ CarException([TOYOTA.CAMRY, TOYOTA.CAMRY_TSS2, TOYOTA.CAMRYH],
+ "28mph for Camry 4CYL L, 4CYL LE and 4CYL SE which don't have Full-Speed Range Dynamic Radar Cruise Control.",
+ Column.FSR_LONGITUDINAL),
+ CarException([GM.ESCALADE_ESV, GM.VOLT, GM.ACADIA],
+ "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),
+ CarException([VOLKSWAGEN.SKODA_KAMIQ_MK1],
+ "Not including the China market Kamiq, which is based on the (currently) unsupported PQ34 platform.",
+ Column.MODEL),
+ CarException([VOLKSWAGEN.PASSAT_MK8],
+ "Not including the USA/China market Passat, which is based on the (currently) unsupported PQ35/NMS platform.",
+ Column.MODEL),
+ CarException([VOLKSWAGEN.ARTEON_MK1, VOLKSWAGEN.ATLAS_MK1, VOLKSWAGEN.TRANSPORTER_T61, VOLKSWAGEN.TCROSS_MK1,
+ VOLKSWAGEN.TROC_MK1, VOLKSWAGEN.TAOS_MK1, VOLKSWAGEN.TIGUAN_MK2],
+ '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),
+ CarException([TOYOTA.PRIUS, TOYOTA.PRIUS_V],
+ "An inaccurate steering wheel angle sensor makes precise control difficult.",
+ Column.STEERING_TORQUE, star="half"),
+]
+
+
+class Car:
+ def __init__(self, car_info, CP):
+ self.make, self.model = car_info.name.split(' ', 1)
+ self.car_fingerprint = CP.carFingerprint
+ assert len(car_info.years), 'Model {} has no years listed'.format(CP.carFingerprint)
+
+ # TODO: properly format model years
+ years = ' ' + str(max(car_info.years))
+ self.model_string = "{}{}".format(self.model, years)
+ self.package = car_info.package
+
+ self.exceptions = get_exceptions(CP)
+ self.stars = self._calculate_stars(CP, car_info)
+
+ @property
+ def row(self):
+ # TODO: add YouTube videos
+ row = [self.make, self.model_string, self.package, *map(get_star_icon, self.stars)]
+
+ # Check for car exceptions
+ for row_idx, column in enumerate(Column):
+ exception = self.exceptions.get(column, None)
+ if exception is not None:
+ superscript_number = CAR_EXCEPTIONS.index(exception) + 1
+ row[row_idx] += "{}".format(superscript_number)
+
+ return make_row(row)
+
+ @property
+ def tier(self):
+ return {5: Tier.GOLD, 4: Tier.SILVER}.get(self.stars.count("full"), Tier.BRONZE)
+
+ def _calculate_stars(self, CP, car_info):
+ # Some minimum steering speeds are not yet in CarParams
+ min_steer_speed = CP.minSteerSpeed
+ if car_info.min_steer_speed is not None:
+ min_steer_speed = car_info.min_steer_speed
+ assert CP.minSteerSpeed == 0, "Minimum steer speed set in both CarInfo and CarParams for {}".format(
+ CP.carFingerprint)
+
+ # TODO: make sure well supported check is complete
+ stars = [CP.openpilotLongitudinalControl, CP.minEnableSpeed <= 1e-3, min_steer_speed <= 1e-3,
+ CP.carName in MAKES_GOOD_STEERING_TORQUE, CP.carFingerprint not in non_tested_cars]
+
+ # Check for star demotions from exceptions
+ for idx, (star, column) in enumerate(zip(stars, StarColumns)):
+ star = "full" if star else "empty"
+ exception = self.exceptions.get(column, None)
+ if exception is not None and exception.star is not None:
+ star = exception.star.lower()
+ stars[idx] = star
+ return stars
def generate_cars_md():
@@ -90,14 +167,10 @@ def generate_cars_md():
cars = sorted(tiered_cars[tier], key=lambda car: car.make + car.model_string)
cars_md_doc.append("## {} Cars\n".format(tier.name.title()))
- cars_md_doc.append(CAR_TABLE_COLUMNS)
+
+ cars_md_doc.append(make_row([column.value for column in Column]))
cars_md_doc.append(CAR_TABLE_HEADER)
- for car in cars:
- line = CAR_ROW_TEMPLATE.format(car.make,
- car.model_string,
- car.package,
- *car.format_stars())
- cars_md_doc.append(line)
+ cars_md_doc.extend(map(lambda car: car.row, cars))
cars_md_doc.append("") # newline
return '\n'.join(cars_md_doc)
diff --git a/selfdrive/car/__init__.py b/selfdrive/car/__init__.py
index 24fe0f062f..924dcbf1f7 100644
--- a/selfdrive/car/__init__.py
+++ b/selfdrive/car/__init__.py
@@ -7,7 +7,7 @@ from common.numpy_fast import clip
# kg of standard extra cargo to count for drive, gas, etc...
STD_CARGO_KG = 136.
-CarInfo = namedtuple('CarInfo', ['name', 'years', 'package', 'min_steer_speed'], defaults=[0])
+CarInfo = namedtuple('CarInfo', ['name', 'years', 'package', 'min_steer_speed'], defaults=[None])
def gen_empty_fingerprint():