move template specific variable into templates, should be a bit simpler

pull/24020/head
Shane Smiskol 3 years ago
parent 9ac98d0950
commit a61a1bd0d6
  1. 36
      selfdrive/car/CARS_template.md
  2. 22
      selfdrive/car/docs.py
  3. 58
      selfdrive/car/docs_definitions.py

@ -1,10 +1,13 @@
{% set footnote_tag = '[<sup>{}</sup>](#Footnotes)' -%}
{% set star_icon = '<a href="#"><img valign="top" src="assets/icon-star-{}.svg" width="22" /></a>' -%}
# 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.
Cars are organized into three tiers:
{% for tier, car_rows in tiers %}
{% for tier, cars in tiers %}
- {{tier.name.title()}} - {{tier.value}}
{% endfor %}
@ -12,36 +15,35 @@ How We Rate The Cars
---
### openpilot Adaptive Cruise Control (ACC)
- {{Star.FULL.md_icon}} - openpilot is able to control the gas and brakes.
- {{Star.HALF.md_icon}} - openpilot is able to control the gas and brakes with some restrictions.
- {{Star.EMPTY.md_icon}} - The gas and brakes are controlled by the car's stock Adaptive Cruise Control (ACC) system.
- {{star_icon.format(Star.FULL.value)}} - openpilot is able to control the gas and brakes.
- {{star_icon.format(Star.HALF.value)}} - openpilot is able to control the gas and brakes with some restrictions.
- {{star_icon.format(Star.EMPTY.value)}} - The gas and brakes are controlled by the car's stock Adaptive Cruise Control (ACC) system.
### Stop and Go
- {{Star.FULL.md_icon}} - Adaptive Cruise Control (ACC) operates down to 0 mph.
- {{Star.EMPTY.md_icon}} - Adaptive Cruise Control (ACC) available only above certain speeds. See your car's manual for the minimum speed.
- {{star_icon.format(Star.FULL.value)}} - Adaptive Cruise Control (ACC) operates down to 0 mph.
- {{star_icon.format(Star.EMPTY.value)}} - Adaptive Cruise Control (ACC) available only above certain speeds. See your car's manual for the minimum speed.
### Steer to 0
- {{Star.FULL.md_icon}} - openpilot can control the steering wheel down to 0 mph.
- {{Star.EMPTY.md_icon}} - No steering control below certain speeds.
- {{star_icon.format(Star.FULL.value)}} - openpilot can control the steering wheel down to 0 mph.
- {{star_icon.format(Star.EMPTY.value)}} - No steering control below certain speeds.
### Steering Torque
- {{Star.FULL.md_icon}} - Car has enough steering torque for comfortable highway driving.
- {{Star.EMPTY.md_icon}} - Limited ability to make turns.
- {{star_icon.format(Star.FULL.value)}} - Car has enough steering torque for comfortable highway driving.
- {{star_icon.format(Star.EMPTY.value)}} - Limited ability to make turns.
### Actively Maintained
- {{Star.FULL.md_icon}} - Mainline software support, harness hardware sold by comma, lots of users, primary development target.
- {{Star.EMPTY.md_icon}} - Low user count, community maintained, harness hardware not sold by comma.
- {{star_icon.format(Star.FULL.value)}} - Mainline software support, harness hardware sold by comma, lots of users, primary development target.
- {{star_icon.format(Star.EMPTY.value)}} - Low user count, community maintained, harness hardware not sold by comma.
**All supported cars can move between the tiers as support changes.**
{% set footnote_tag = '[<sup>{}</sup>](#Footnotes)' %}
{% for tier, car_rows in tiers %}
{% for tier, cars in tiers %}
## {{tier.name.title()}} Cars
|{{columns | join('|')}}|
|{{Column | map(attribute='value') | join('|')}}|
|---|---|---|:---:|:---:|:---:|:---:|:---:|
{% for row in car_rows %}
|{% for row_item in row %}{{row_item.text if row_item.text else row_item.star.md_icon}}{{footnote_tag.format(row_item.footnote) if row_item.footnote else ''}}|{% endfor %}
{% for car_info in cars %}
|{% for column in Column %}{{car_info.get_column(column, star_icon, footnote_tag)}}|{% endfor %}
{% endfor %}

@ -6,7 +6,7 @@ from enum import Enum
from typing import Dict, Iterator, List, Tuple
from common.basedir import BASEDIR
from selfdrive.car.docs_definitions import Column, RowItem, Star, Tier
from selfdrive.car.docs_definitions import Column, CarInfo, 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
@ -25,8 +25,8 @@ 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() -> List[Tuple[Tier, List[RowItem]]]:
tier_car_rows: Dict[Tier, list] = {tier: [] for tier in Tier}
def get_tier_car_info() -> List[Tuple[Tier, List[CarInfo]]]: # TODO: update typing for all this
tier_car_info: Dict[Tier, list] = {tier: [] for tier in Tier}
for models in get_interface_attr("CAR_INFO").values():
for model, car_info in models.items():
@ -42,24 +42,22 @@ def get_tier_car_rows() -> List[Tuple[Tier, List[RowItem]]]:
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))
_car_info.init(CP, non_tested_cars, ALL_FOOTNOTES)
tier_car_info[_car_info.tier].append(_car_info)
# Return tier enum and car rows for each tier
tiers = []
for tier, car_rows in tier_car_rows.items():
tiers.append((tier, sorted(car_rows, key=lambda x: x[0].text + x[1].text)))
for tier, car_rows in tier_car_info.items():
tiers.append((tier, sorted(car_rows, key=lambda x: x.make + x.model)))
return tiers
def generate_cars_md(tier_car_rows: List[Tuple[Tier, List[RowItem]]], template_fn: str) -> str:
def generate_cars_md(tier_car_info: List[Tuple[Tier, List[CarInfo]]], template_fn: str) -> str:
with open(template_fn, "r") as f:
template = jinja2.Template(f.read(), trim_blocks=True, lstrip_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)
return template.render(tiers=tier_car_info, Star=Star, Column=Column, footnotes=footnotes)
if __name__ == "__main__":
@ -71,5 +69,5 @@ if __name__ == "__main__":
args = parser.parse_args()
with open(args.out, 'w') as f:
f.write(generate_cars_md(get_tier_car_rows(), args.template))
f.write(generate_cars_md(get_tier_car_info(), args.template))
print(f"Generated and written to {args.out}")

@ -14,7 +14,7 @@ class CarInfo:
min_enable_speed: Optional[float] = None
good_torque: bool = False
def get_stars(self, CP, non_tested_cars):
def init(self, CP, non_tested_cars, all_footnotes):
# 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:
@ -26,7 +26,12 @@ class CarInfo:
if self.min_enable_speed is not None:
min_enable_speed = self.min_enable_speed
stars = {
self.make, self.model = self.name.split(' ', 1)
self.row = {
Column.MAKE: self.make,
Column.MODEL: self.model,
Column.PACKAGE: self.package,
# StarColumns
Column.LONGITUDINAL: CP.openpilotLongitudinalControl and not CP.radarOffCan,
Column.FSR_LONGITUDINAL: min_enable_speed <= 0.,
Column.FSR_STEERING: min_steer_speed <= 0.,
@ -34,44 +39,27 @@ class CarInfo:
Column.MAINTAINED: CP.carFingerprint not in non_tested_cars,
}
self.all_footnotes = all_footnotes
for column in StarColumns:
stars[column] = Star.FULL if stars[column] else Star.EMPTY
self.row[column] = Star.FULL if self.row[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
self.row[column] = footnote.value.star
return [stars[column] for column in StarColumns]
self.tier = {5: Tier.GOLD, 4: Tier.SILVER}.get(list(self.row.values()).count(Star.FULL), Tier.BRONZE)
def get_row(self, all_footnotes, stars):
# TODO: add YouTube videos
make, model = self.name.split(' ', 1)
row = [make, model, self.package, *stars]
def get_column(self, column, star_icon, footnote_tag):
item = self.row[column]
if column in StarColumns:
item = star_icon.format(item.value)
# Check for car footnotes and get star icons
for row_idx, column in enumerate(Column):
row_item = RowItem()
if column in StarColumns:
row_item.star = row[row_idx]
else:
row_item.text = row[row_idx]
footnote = get_footnote(self.footnotes, column)
if footnote is not None:
item += footnote_tag.format(self.all_footnotes[footnote])
footnote = get_footnote(self.footnotes, column)
if footnote is not None:
row_item.footnote = all_footnotes[footnote]
# TODO: we can also specify footnote in RowItem and get rid of the template footnote variables
# row[row_idx] += f"[<sup>{all_footnotes[footnote]}</sup>](#Footnotes)"
row[row_idx] = row_item
return row
@dataclass
class RowItem:
text: Optional[str] = None
footnote: Optional[int] = None # TODO: if we change to '' then we can get rid of if statements in templates
star: Optional[str] = None
return item
class Tier(Enum):
@ -96,14 +84,6 @@ class Star(Enum):
HALF = "half"
EMPTY = "empty"
@property
def md_icon(self):
return f'<a href="#"><img valign="top" src="assets/icon-star-{self.value}.svg" width="22" /></a>'
@property
def html_icon(self):
return f'<img src="/supported-cars/icon-star-{self.value}.svg" alt="">'
StarColumns = list(Column)[3:]
CarFootnote = namedtuple("CarFootnote", ["text", "column", "star"], defaults=[None])

Loading…
Cancel
Save