Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: finish CarDocs migration to opendbc #1333

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion opendbc/car/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from panda import uds
from opendbc.car import structs
from opendbc.car.can_definitions import CanData
from opendbc.car.docs_definitions import CarDocs
from opendbc.car.docs.definitions import CarDocs
from opendbc.car.common.numpy_fast import clip, interp

# set up logging
Expand Down
2 changes: 1 addition & 1 deletion opendbc/car/body/values.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from opendbc.car import CarSpecs, PlatformConfig, Platforms, dbc_dict
from opendbc.car.structs import CarParams
from opendbc.car.docs_definitions import CarDocs
from opendbc.car.docs.definitions import CarDocs
from opendbc.car.fw_query_definitions import FwQueryConfig, Request, StdQueries

Ecu = CarParams.Ecu
Expand Down
2 changes: 1 addition & 1 deletion opendbc/car/chrysler/values.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from panda import uds
from opendbc.car import CarSpecs, DbcDict, PlatformConfig, Platforms, dbc_dict
from opendbc.car.structs import CarParams
from opendbc.car.docs_definitions import CarHarness, CarDocs, CarParts
from opendbc.car.docs.definitions import CarHarness, CarDocs, CarParts
from opendbc.car.fw_query_definitions import FwQueryConfig, Request, p16

Ecu = CarParams.Ecu
Expand Down
74 changes: 74 additions & 0 deletions opendbc/car/docs/CARS_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
{% set footnote_tag = '[<sup>{}</sup>](#footnotes)' %}
{% set star_icon = '[![star](assets/icon-star-{}.svg)](##)' %}
{% set video_icon = '<a href="{}" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>' %}
{# Force hardware column wider by using a blank image with max width. #}
{% set width_tag = '<a href="##"><img width=2000></a>%s<br>&nbsp;' %}
{% set hardware_col_name = 'Hardware Needed' %}
{% set wide_hardware_col_name = width_tag|format(hardware_col_name) -%}

<!--- AUTOGENERATED FROM selfdrive/car/CARS_template.md, DO NOT EDIT. --->

# Supported Cars

A supported vehicle is one that just works when you install a comma device. All supported cars provide a better experience than any stock system. Supported vehicles reference the US market unless otherwise specified.

# {{all_car_docs | length}} Supported Cars

|{{Column | map(attribute='value') | join('|') | replace(hardware_col_name, wide_hardware_col_name)}}|
|---|---|---|{% for _ in range((Column | length) - 3) %}{{':---:|'}}{% endfor +%}
{% for car_docs in all_car_docs %}
|{% for column in Column %}{{car_docs.get_column(column, star_icon, video_icon, footnote_tag)}}|{% endfor %}

{% endfor %}

### Footnotes
{% for footnote in footnotes %}
<sup>{{loop.index}}</sup>{{footnote}} <br />
{% 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/).

# Don't see your car here?

**openpilot can support many more cars than it currently does.** There are a few reasons your car may not be supported.
If your car doesn't fit into any of the incompatibility criteria here, then there's a good chance it can be supported! We're adding support for new cars all the time. **We don't have a roadmap for car support**, and in fact, most car support comes from users like you!

### Which cars are able to be supported?

openpilot uses the existing steering, gas, and brake interfaces in your car. If your car lacks any one of these interfaces, openpilot will not be able to control the car. If your car has [ACC](https://en.wikipedia.org/wiki/Adaptive_cruise_control) and any form of [LKAS](https://en.wikipedia.org/wiki/Automated_Lane_Keeping_Systems)/[LCA](https://en.wikipedia.org/wiki/Lane_centering), then it almost certainly has these interfaces. These features generally started shipping on cars around 2016. Note that manufacturers will often make their own [marketing terms](https://en.wikipedia.org/wiki/Adaptive_cruise_control#Vehicle_models_supporting_adaptive_cruise_control) for these features, such as Hyundai's "Smart Cruise Control" branding of Adaptive Cruise Control.

If your car has the following packages or features, then it's a good candidate for support.

| Make | Required Package/Features |
| ---- | ------------------------- |
| Acura | Any car with AcuraWatch Plus will work. AcuraWatch Plus comes standard on many newer models. |
| Ford | Any car with Lane Centering will likely work. |
| Honda | Any car with Honda Sensing will work. Honda Sensing comes standard on many newer models. |
| Subaru | Any car with EyeSight will work. EyeSight comes standard on many newer models. |
| Nissan | Any car with ProPILOT will likely work. |
| Toyota & Lexus | Any car that has Toyota/Lexus Safety Sense with "Lane Departure Alert with Steering Assist (LDA w/SA)" and/or "Lane Tracing Assist (LTA)" will work. Note that LDA without Steering Assist will not work. These features come standard on most newer models. |
| Hyundai, Kia, & Genesis | Any car with Smart Cruise Control (SCC) and Lane Following Assist (LFA) or Lane Keeping Assist (LKAS) will work. LKAS/LFA comes standard on most newer models. Any form of SCC will work, such as NSCC. |
| Chrysler, Jeep, & Ram | Any car with LaneSense and Adaptive Cruise Control will likely work. These come standard on many newer models. |

### FlexRay

All the cars that openpilot supports use a [CAN bus](https://en.wikipedia.org/wiki/CAN_bus) for communication between all the car's computers, however a CAN bus isn't the only way that the computers in your car can communicate. Most, if not all, vehicles from the following manufacturers use [FlexRay](https://en.wikipedia.org/wiki/FlexRay) instead of a CAN bus: **BMW, Mercedes, Audi, Land Rover, and some Volvo**. These cars may one day be supported, but we have no immediate plans to support FlexRay.

### Toyota Security

openpilot does not yet support these Toyota models due to a new message authentication method.
[Vote](https://comma.ai/shop#toyota-security) if you'd like to see openpilot support on these models.

* Toyota RAV4 Prime 2021+
* Toyota Sienna 2021+
* Toyota Venza 2021+
* Toyota Sequoia 2023+
* Toyota Tundra 2022+
* Toyota Highlander 2024+
* Toyota Corolla Cross 2022+ (only US model)
* Toyota Camry 2025+
* Lexus NX 2022+
* Toyota bZ4x 2023+
* Subaru Solterra 2023+

File renamed without changes.
18 changes: 18 additions & 0 deletions opendbc/car/docs/dump_car_docs.py
jyoung8607 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env python3
import argparse
import pickle

from opendbc.car.docs.generate_docs import get_all_car_docs


def dump_car_docs(path):
with open(path, 'wb') as f:
pickle.dump(get_all_car_docs(), f)
print(f'Dumping car info to {path}')


if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--path", required=True)
args = parser.parse_args()
dump_car_docs(args.path)
28 changes: 27 additions & 1 deletion opendbc/car/docs.py → opendbc/car/docs/generate_docs.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
#!/usr/bin/env python3
import argparse
from collections import defaultdict
import jinja2
import os
from enum import Enum
from natsort import natsorted

from opendbc.car import gen_empty_fingerprint
from opendbc.car.structs import CarParams
from opendbc.car.docs_definitions import CarDocs, Column, CommonFootnote, PartType
from opendbc.car.docs.definitions import CarDocs, Column, CommonFootnote, PartType
from opendbc.car.car_helpers import interfaces, get_interface_attr
from opendbc.car.values import PLATFORMS

try:
from openpilot.common.basedir import BASEDIR
except ModuleNotFoundError:
# TODO: make sure we run in a sensible way if not checked out as a submodule
BASEDIR = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../../../"))
jyoung8607 marked this conversation as resolved.
Show resolved Hide resolved


CARS_MD_OUT = os.path.join(BASEDIR, "docs", "CARS.md")
CARS_MD_TEMPLATE = os.path.join(BASEDIR, "opendbc", "car", "docs", "CARS_template.md")


def get_all_footnotes() -> dict[Enum, int]:
all_footnotes = list(CommonFootnote)
Expand Down Expand Up @@ -57,3 +70,16 @@ def generate_cars_md(all_car_docs: list[CarDocs], template_fn: str) -> str:
group_by_make=group_by_make, footnotes=footnotes,
Column=Column)
return cars_md


if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Auto generates supported cars documentation",
formatter_class=argparse.ArgumentDefaultsHelpFormatter)

parser.add_argument("--template", default=CARS_MD_TEMPLATE, help="Override default template filename")
parser.add_argument("--out", default=CARS_MD_OUT, help="Override default generated filename")
args = parser.parse_args()

with open(args.out, 'w') as f:
f.write(generate_cars_md(get_all_car_docs(), args.template))
print(f"Generated and written to {args.out}")
120 changes: 120 additions & 0 deletions opendbc/car/docs/print_docs_diff.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#!/usr/bin/env python3
import argparse
from collections import defaultdict
import difflib
import pickle

from opendbc.car.docs.generate_docs import get_all_car_docs
from opendbc.car.docs.definitions import Column

FOOTNOTE_TAG = "<sup>{}</sup>"
STAR_ICON = '<a href="##"><img valign="top" ' + \
'src="https://media.githubusercontent.com/media/commaai/openpilot/master/docs/assets/icon-star-{}.svg" width="22" /></a>'
VIDEO_ICON = '<a href="{}" target="_blank">' + \
'<img height="18px" src="https://media.githubusercontent.com/media/commaai/openpilot/master/docs/assets/icon-youtube.svg"></img></a>'
COLUMNS = "|" + "|".join([column.value for column in Column]) + "|"
COLUMN_HEADER = "|---|---|---|{}|".format("|".join([":---:"] * (len(Column) - 3)))
ARROW_SYMBOL = "➡️"


def load_base_car_docs(path):
with open(path, "rb") as f:
return pickle.load(f)


def match_cars(base_cars, new_cars):
changes = []
additions = []
for new in new_cars:
# Addition if no close matches or close match already used
# Change if close match and not already used
matches = difflib.get_close_matches(new.name, [b.name for b in base_cars], cutoff=0.)
if not len(matches) or matches[0] in [c[1].name for c in changes]:
additions.append(new)
else:
changes.append((new, next(car for car in base_cars if car.name == matches[0])))

# Removal if base car not in changes
removals = [b for b in base_cars if b.name not in [c[1].name for c in changes]]
return changes, additions, removals


def build_column_diff(base_car, new_car):
row_builder = []
for column in Column:
base_column = base_car.get_column(column, STAR_ICON, VIDEO_ICON, FOOTNOTE_TAG)
new_column = new_car.get_column(column, STAR_ICON, VIDEO_ICON, FOOTNOTE_TAG)

if base_column != new_column:
row_builder.append(f"{base_column} {ARROW_SYMBOL} {new_column}")
else:
row_builder.append(new_column)

return format_row(row_builder)


def format_row(builder):
return "|" + "|".join(builder) + "|"


def print_car_docs_diff(path):
base_car_docs = defaultdict(list)
new_car_docs = defaultdict(list)

for car in load_base_car_docs(path):
base_car_docs[car.car_fingerprint].append(car)
for car in get_all_car_docs():
new_car_docs[car.car_fingerprint].append(car)

# Add new platforms to base cars so we can detect additions and removals in one pass
base_car_docs.update({car: [] for car in new_car_docs if car not in base_car_docs})

changes = defaultdict(list)
for base_car_model, base_cars in base_car_docs.items():
# Match car info changes, and get additions and removals
new_cars = new_car_docs[base_car_model]
car_changes, car_additions, car_removals = match_cars(base_cars, new_cars)

# Removals
for car_docs in car_removals:
changes["removals"].append(format_row([car_docs.get_column(column, STAR_ICON, VIDEO_ICON, FOOTNOTE_TAG) for column in Column]))

# Additions
for car_docs in car_additions:
changes["additions"].append(format_row([car_docs.get_column(column, STAR_ICON, VIDEO_ICON, FOOTNOTE_TAG) for column in Column]))

for new_car, base_car in car_changes:
# Column changes
row_diff = build_column_diff(base_car, new_car)
if ARROW_SYMBOL in row_diff:
changes["column"].append(row_diff)

# Detail sentence changes
if base_car.detail_sentence != new_car.detail_sentence:
changes["detail"].append(f"- Sentence for {base_car.name} changed!\n" +
" ```diff\n" +
f" - {base_car.detail_sentence}\n" +
f" + {new_car.detail_sentence}\n" +
" ```")

# Print diff
if any(len(c) for c in changes.values()):
markdown_builder = ["### ⚠️ This PR makes changes to [CARS.md](../blob/master/docs/CARS.md) ⚠️"]

for title, category in (("## 🔀 Column Changes", "column"), ("## ❌ Removed", "removals"),
("## ➕ Added", "additions"), ("## 📖 Detail Sentence Changes", "detail")):
if len(changes[category]):
markdown_builder.append(title)
if category not in ("detail",):
markdown_builder.append(COLUMNS)
markdown_builder.append(COLUMN_HEADER)
markdown_builder.extend(changes[category])

print("\n".join(markdown_builder))


if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--path", required=True)
args = parser.parse_args()
print_car_docs_diff(args.path)
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import re

from opendbc.car.car_helpers import interfaces
from opendbc.car.docs import get_all_car_docs
from opendbc.car.docs_definitions import Cable, Column, PartType, Star
from opendbc.car.docs.generate_docs import get_all_car_docs
from opendbc.car.docs.definitions import Cable, Column, PartType, Star
from opendbc.car.honda.values import CAR as HONDA
from opendbc.car.values import PLATFORMS

Expand Down
2 changes: 1 addition & 1 deletion opendbc/car/ford/values.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from panda import uds
from opendbc.car import AngleRateLimit, CarSpecs, dbc_dict, DbcDict, PlatformConfig, Platforms
from opendbc.car.structs import CarParams
from opendbc.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column, \
from opendbc.car.docs.definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column, \
Device
from opendbc.car.fw_query_definitions import FwQueryConfig, LiveFwVersions, OfflineFwVersions, Request, StdQueries, p16

Expand Down
2 changes: 1 addition & 1 deletion opendbc/car/gm/values.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from opendbc.car import dbc_dict, PlatformConfig, DbcDict, Platforms, CarSpecs
from opendbc.car.structs import CarParams
from opendbc.car.docs_definitions import CarHarness, CarDocs, CarParts
from opendbc.car.docs.definitions import CarHarness, CarDocs, CarParts
from opendbc.car.fw_query_definitions import FwQueryConfig, Request, StdQueries

Ecu = CarParams.Ecu
Expand Down
2 changes: 1 addition & 1 deletion opendbc/car/honda/values.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from panda import uds
from opendbc.car import CarSpecs, PlatformConfig, Platforms, dbc_dict, structs
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column
from opendbc.car.docs.definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column
from opendbc.car.fw_query_definitions import FwQueryConfig, Request, StdQueries, p16

Ecu = structs.CarParams.Ecu
Expand Down
2 changes: 1 addition & 1 deletion opendbc/car/hyundai/values.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from opendbc.car import CarSpecs, DbcDict, PlatformConfig, Platforms, dbc_dict
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.structs import CarParams
from opendbc.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column
from opendbc.car.docs.definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column
from opendbc.car.fw_query_definitions import FwQueryConfig, Request, p16

Ecu = CarParams.Ecu
Expand Down
2 changes: 1 addition & 1 deletion opendbc/car/mazda/values.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from opendbc.car import CarSpecs, DbcDict, PlatformConfig, Platforms, dbc_dict
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.structs import CarParams
from opendbc.car.docs_definitions import CarHarness, CarDocs, CarParts
from opendbc.car.docs.definitions import CarHarness, CarDocs, CarParts
from opendbc.car.fw_query_definitions import FwQueryConfig, Request, StdQueries

Ecu = CarParams.Ecu
Expand Down
2 changes: 1 addition & 1 deletion opendbc/car/nissan/values.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from panda import uds
from opendbc.car import AngleRateLimit, CarSpecs, DbcDict, PlatformConfig, Platforms, dbc_dict
from opendbc.car.structs import CarParams
from opendbc.car.docs_definitions import CarDocs, CarHarness, CarParts
from opendbc.car.docs.definitions import CarDocs, CarHarness, CarParts
from opendbc.car.fw_query_definitions import FwQueryConfig, Request, StdQueries

Ecu = CarParams.Ecu
Expand Down
2 changes: 1 addition & 1 deletion opendbc/car/subaru/values.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from panda import uds
from opendbc.car import CarSpecs, DbcDict, PlatformConfig, Platforms, dbc_dict
from opendbc.car.structs import CarParams
from opendbc.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Tool, Column
from opendbc.car.docs.definitions import CarFootnote, CarHarness, CarDocs, CarParts, Tool, Column
from opendbc.car.fw_query_definitions import FwQueryConfig, Request, StdQueries, p16

Ecu = CarParams.Ecu
Expand Down
2 changes: 1 addition & 1 deletion opendbc/car/tesla/values.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from opendbc.car.structs import CarParams
from opendbc.car import structs
from opendbc.car import AngleRateLimit, CarSpecs, PlatformConfig, Platforms, dbc_dict
from opendbc.car.docs_definitions import CarDocs
from opendbc.car.docs.definitions import CarDocs
from opendbc.car.fw_query_definitions import FwQueryConfig, Request, StdQueries

Ecu = CarParams.Ecu
Expand Down
2 changes: 1 addition & 1 deletion opendbc/car/toyota/values.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from opendbc.car import CarSpecs, PlatformConfig, Platforms, AngleRateLimit, dbc_dict
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.structs import CarParams
from opendbc.car.docs_definitions import CarFootnote, CarDocs, Column, CarParts, CarHarness
from opendbc.car.docs.definitions import CarFootnote, CarDocs, Column, CarParts, CarHarness
from opendbc.car.fw_query_definitions import FwQueryConfig, Request, StdQueries

Ecu = CarParams.Ecu
Expand Down
2 changes: 1 addition & 1 deletion opendbc/car/volkswagen/values.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from opendbc.car import dbc_dict, CarSpecs, DbcDict, PlatformConfig, Platforms
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car import structs
from opendbc.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column, \
from opendbc.car.docs.definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column, \
Device
from opendbc.car.fw_query_definitions import EcuAddrSubAddr, FwQueryConfig, Request, p16

Expand Down
Loading