openpilot is an open source driver assistance system. openpilot performs the functions of Automated Lane Centering and Adaptive Cruise Control for over 200 supported car makes and models.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

112 lines
3.5 KiB

3 years ago
#!/usr/bin/env python3
from enum import Enum
import os
3 years ago
from common.basedir import BASEDIR
from selfdrive.car.car_helpers import interfaces, get_interface_attr
from selfdrive.test.test_routes import non_tested_cars
from collections import defaultdict, namedtuple
3 years ago
class Tier(Enum):
GOLD = "Gold"
SILVER = "Silver"
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
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]
3 years ago
@property
def tier(self):
return {5: Tier.GOLD, 4: Tier.SILVER}.get(sum(self.stars), Tier.BRONZE)
3 years ago
def make_row(columns):
return "|{}|".format("|".join(columns))
3 years ago
# TODO: unify with column names below?
Stars = namedtuple("Stars", ["op_long", "fsr_long", "fsr_lat", "steering_torque", "well_supported"])
STAR_ICON_FULL = '<img src="assets/icon-star-full.png" width="18" />'
STAR_ICON_HALF = '<img src="assets/icon-star-half.png" width="18" />'
STAR_ICON_EMPTY = '<img src="assets/icon-star-empty.png" width="18" />'
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"]
3 years ago
def generate_cars_md():
tiered_cars = defaultdict(list)
for _, models in get_interface_attr("CAR_INFO").items():
for model, car_info in models.items():
CP = interfaces[model][0].get_params(model)
3 years ago
# Skip community supported
if CP.dashcamOnly:
continue
# Some candidates have multiple variants
if not isinstance(car_info, list):
car_info = [car_info]
for _car_info in car_info:
car = Car(_car_info, CP)
tiered_cars[car.tier].append(car)
# Build CARS.md
cars_md_doc = []
for tier in Tier:
# Sort by make, model name, and year
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(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.append("") # newline
return '\n'.join(cars_md_doc)
if __name__ == "__main__":
# TODO: add argparse for generating json or html (undecided)
3 years ago
with open(CARS_MD_OUT, 'w') as f:
f.write(generate_cars_md())
print('Generated and written to {}'.format(CARS_MD_OUT))