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

car docs: list all needed hardware #28212

Merged
merged 20 commits into from
May 22, 2023
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
504 changes: 252 additions & 252 deletions docs/CARS.md

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions selfdrive/car/CARS_template.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{% 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 harness column wider by using a blank image with max width. #}
{# 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 harness_col_name = 'Harness Kit' %}
{% set wide_harness_col_name = width_tag|format(harness_col_name) -%}
{% 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. --->

Expand All @@ -14,7 +14,7 @@ A supported vehicle is one that just works when you install a comma three. All s

# {{all_car_info | length}} Supported Cars

|{{Column | map(attribute='value') | join('|') | replace(harness_col_name, wide_harness_col_name)}}|
|{{Column | map(attribute='value') | join('|') | replace(hardware_col_name, wide_hardware_col_name)}}|
|---|---|---|{% for _ in range((Column | length) - 3) %}{{':---:|'}}{% endfor +%}
{% for car_info in all_car_info %}
|{% for column in Column %}{{car_info.get_column(column, star_icon, video_icon, footnote_tag)}}|{% endfor %}
Expand Down
10 changes: 5 additions & 5 deletions selfdrive/car/chrysler/values.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from cereal import car
from panda.python import uds
from selfdrive.car import dbc_dict
from selfdrive.car.docs_definitions import CarInfo, Harness, HarnessKit
from selfdrive.car.docs_definitions import CarInfo, CarParts, HarnessConnector
from selfdrive.car.fw_query_definitions import FwQueryConfig, Request, p16

Ecu = car.CarParams.Ecu
Expand Down Expand Up @@ -60,7 +60,7 @@ def __init__(self, CP):
@dataclass
class ChryslerCarInfo(CarInfo):
package: str = "Adaptive Cruise Control (ACC)"
harness_kit: HarnessKit = HarnessKit(Harness.fca)
car_parts: CarParts = CarParts.default([HarnessConnector.fca])


CAR_INFO: Dict[str, Optional[Union[ChryslerCarInfo, List[ChryslerCarInfo]]]] = {
Expand All @@ -74,10 +74,10 @@ class ChryslerCarInfo(CarInfo):
],
CAR.JEEP_CHEROKEE: ChryslerCarInfo("Jeep Grand Cherokee 2016-18", video_link="https://www.youtube.com/watch?v=eLR9o2JkuRk"),
CAR.JEEP_CHEROKEE_2019: ChryslerCarInfo("Jeep Grand Cherokee 2019-21", video_link="https://www.youtube.com/watch?v=jBe4lWnRSu4"),
CAR.RAM_1500: ChryslerCarInfo("Ram 1500 2019-23", harness_kit=HarnessKit(Harness.ram)),
CAR.RAM_1500: ChryslerCarInfo("Ram 1500 2019-23", car_parts=CarParts.default([HarnessConnector.ram])),
CAR.RAM_HD: [
ChryslerCarInfo("Ram 2500 2020-22", harness_kit=HarnessKit(Harness.ram)),
ChryslerCarInfo("Ram 3500 2019-22", harness_kit=HarnessKit(Harness.ram)),
ChryslerCarInfo("Ram 2500 2020-22", car_parts=CarParts.default([HarnessConnector.ram])),
ChryslerCarInfo("Ram 3500 2019-22", car_parts=CarParts.default([HarnessConnector.ram])),
],
}

Expand Down
134 changes: 78 additions & 56 deletions selfdrive/car/docs_definitions.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import re
from collections import namedtuple
import copy
from dataclasses import dataclass, field
from enum import Enum
from typing import Dict, List, Optional, Tuple, Union
Expand All @@ -21,7 +20,7 @@ class Column(Enum):
FSR_STEERING = "No ALC below"
STEERING_TORQUE = "Steering Torque"
AUTO_RESUME = "Resume from stop"
HARNESS = "Harness Kit"
HARDWARE = "Hardware Needed"
VIDEO = "Video"


Expand All @@ -31,60 +30,83 @@ class Star(Enum):
EMPTY = "empty"


class Harness(Enum):
maxime-desroches marked this conversation as resolved.
Show resolved Hide resolved
maxime-desroches marked this conversation as resolved.
Show resolved Hide resolved
nidec = "Honda Nidec"
bosch_a = "Honda Bosch A"
bosch_b = "Honda Bosch B"
toyota = "Toyota"
subaru_a = "Subaru A"
subaru_b = "Subaru B"
fca = "FCA"
ram = "Ram"
vw = "VW"
j533 = "J533"
hyundai_a = "Hyundai A"
hyundai_b = "Hyundai B"
hyundai_c = "Hyundai C"
hyundai_d = "Hyundai D"
hyundai_e = "Hyundai E"
hyundai_f = "Hyundai F"
hyundai_g = "Hyundai G"
hyundai_h = "Hyundai H"
hyundai_i = "Hyundai I"
hyundai_j = "Hyundai J"
hyundai_k = "Hyundai K"
hyundai_l = "Hyundai L"
hyundai_m = "Hyundai M"
hyundai_n = "Hyundai N"
hyundai_o = "Hyundai O"
hyundai_p = "Hyundai P"
hyundai_q = "Hyundai Q"
custom = "Developer"
obd_ii = "OBD-II"
gm = "GM"
nissan_a = "Nissan A"
nissan_b = "Nissan B"
mazda = "Mazda"
ford_q3 = "Ford Q3"
ford_q4 = "Ford Q4"
none = "None"


class HarnessPart(Enum):
class CarPart(Enum):
maxime-desroches marked this conversation as resolved.
Show resolved Hide resolved
maxime-desroches marked this conversation as resolved.
Show resolved Hide resolved
pass


class HarnessConnector(CarPart):
maxime-desroches marked this conversation as resolved.
Show resolved Hide resolved
nidec = "Honda Nidec connector"
bosch_a = "Honda Bosch A connector"
bosch_b = "Honda Bosch B connector"
toyota = "Toyota connector"
subaru_a = "Subaru A connector"
subaru_b = "Subaru B connector"
fca = "FCA connector"
ram = "Ram connector"
vw = "VW connector"
j533 = "J533 connector"
hyundai_a = "Hyundai A connector"
hyundai_b = "Hyundai B connector"
hyundai_c = "Hyundai C connector"
hyundai_d = "Hyundai D connector"
hyundai_e = "Hyundai E connector"
hyundai_f = "Hyundai F connector"
hyundai_g = "Hyundai G connector"
hyundai_h = "Hyundai H connector"
hyundai_i = "Hyundai I connector"
hyundai_j = "Hyundai J connector"
hyundai_k = "Hyundai K connector"
hyundai_l = "Hyundai L connector"
hyundai_m = "Hyundai M connector"
hyundai_n = "Hyundai N connector"
hyundai_o = "Hyundai O connector"
hyundai_p = "Hyundai P connector"
hyundai_q = "Hyundai Q connector"
custom = "Developer connector"
obd_ii = "OBD-II connector"
gm = "GM connector"
nissan_a = "Nissan A connector"
nissan_b = "Nissan B connector"
mazda = "Mazda connector"
ford_q3 = "Ford Q3 connector"
ford_q4 = "Ford Q4 connector"


class HarnessAccessory(CarPart):
harness_box = "harness box"
comma_power_v2 = "comma power v2"
rj45_cable = "RJ45 cable (7 ft)"


class Mount(CarPart):
mount = "mount"
angled_mount = "angled mount"


class Cable(CarPart):
rj45_cable_7ft = "RJ45 cable (7 ft)"
long_obdc_cable = "long OBD-C cable"
usb_a_2_a_cable = "USB A-A cable"
usbc_otg_cable = "USB C OTG cable"
usbc_coupler = "USB-C coupler"
obd_c_cable_1_5ft = "OBD-C cable (1.5 ft)"


DEFAULT_HARNESS_PARTS: List[HarnessPart] = [HarnessPart.harness_box, HarnessPart.comma_power_v2, HarnessPart.rj45_cable]
class Device(CarPart):
comma_3 = "comma 3"
red_panda = "red panda"


DEFAULT_CAR_PARTS: List[CarPart] = [HarnessAccessory.harness_box, HarnessAccessory.comma_power_v2, Cable.rj45_cable_7ft, Mount.mount]
maxime-desroches marked this conversation as resolved.
Show resolved Hide resolved


@dataclass
class HarnessKit:
connector: Harness = Harness.none
parts: List[HarnessPart] = field(default_factory=lambda: copy.copy(DEFAULT_HARNESS_PARTS))
class CarParts:
parts: List[CarPart] = field(default_factory=list)

@classmethod
def default(cls, add: List[CarPart] = None, remove: List[CarPart] = None):
p = [part for part in (add or []) + DEFAULT_CAR_PARTS if part not in (remove or [])]
return cls(p)
maxime-desroches marked this conversation as resolved.
Show resolved Hide resolved


CarFootnote = namedtuple("CarFootnote", ["text", "column", "docs_only", "shop_footnote"], defaults=(False, False))
Expand Down Expand Up @@ -154,8 +176,8 @@ class CarInfo:
min_steer_speed: Optional[float] = None
min_enable_speed: Optional[float] = None

# harness connectors + all the parts needed
harness_kit: HarnessKit = HarnessKit()
# all the parts needed for the supported car
car_parts: CarParts = CarParts()

def init(self, CP: car.CarParams, all_footnotes: Dict[Enum, int]):
self.car_name = CP.carName
Expand Down Expand Up @@ -184,13 +206,13 @@ def init(self, CP: car.CarParams, all_footnotes: Dict[Enum, int]):
if self.min_enable_speed is None:
self.min_enable_speed = CP.minEnableSpeed

# harness column
harness_col = self.harness_kit.connector.value
if self.harness_kit.connector is not Harness.none:
# hardware column
hardware_col = "None"
if self.car_parts.parts:
model_years = self.model + (' ' + self.years if self.years else '')
harness_connector = f'- 1 <a href="https://comma.ai/shop/comma-three.html?make={self.make}&model={model_years}">{harness_col} connector</a>'
harness_parts = '<br>'.join([f"- {self.harness_kit.parts.count(part)} {part.value}" for part in sorted(set(self.harness_kit.parts), key=lambda part: part.value)])
harness_col = f'<details><summary>View</summary><sub>{harness_connector}<br>{harness_parts}</sub></details>'
buy_link = f'<a href="https://comma.ai/shop/comma-three.html?make={self.make}&model={model_years}">Buy Here</a>'
parts = '<br>'.join([f"- {self.car_parts.parts.count(part)} {part.value}" for part in sorted(set(self.car_parts.parts), key=lambda part: part.name)])
hardware_col = f'<details><summary>View</summary><sub>{parts}<br>{buy_link}</sub></details>'

self.row: Dict[Enum, Union[str, Star]] = {
Column.MAKE: self.make,
Expand All @@ -201,7 +223,7 @@ def init(self, CP: car.CarParams, all_footnotes: Dict[Enum, int]):
Column.FSR_STEERING: f"{max(self.min_steer_speed * CV.MS_TO_MPH, 0):.0f} mph",
Column.STEERING_TORQUE: Star.EMPTY,
Column.AUTO_RESUME: Star.FULL if CP.autoResumeSng else Star.EMPTY,
Column.HARNESS: harness_col,
Column.HARDWARE: hardware_col,
Column.VIDEO: self.video_link if self.video_link is not None else "", # replaced with an image and link from template in get_column
}

Expand Down
7 changes: 3 additions & 4 deletions selfdrive/car/ford/values.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from cereal import car
from selfdrive.car import AngleRateLimit, dbc_dict
from selfdrive.car.docs_definitions import CarInfo, Harness, HarnessKit
from selfdrive.car.docs_definitions import CarInfo, CarParts, HarnessConnector, Mount
from selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries

Ecu = car.CarParams.Ecu
Expand Down Expand Up @@ -62,15 +62,14 @@ class RADAR:

DBC: Dict[str, Dict[str, str]] = defaultdict(lambda: dbc_dict("ford_lincoln_base_pt", RADAR.DELPHI_MRR))

maxime-desroches marked this conversation as resolved.
Show resolved Hide resolved

@dataclass
class FordCarInfo(CarInfo):
package: str = "Co-Pilot360 Assist+"
harness_kit: HarnessKit = HarnessKit(Harness.ford_q3)
car_parts: CarParts = CarParts.default([HarnessConnector.ford_q3])


CAR_INFO: Dict[str, Union[CarInfo, List[CarInfo]]] = {
CAR.BRONCO_SPORT_MK1: FordCarInfo("Ford Bronco Sport 2021-22"),
CAR.BRONCO_SPORT_MK1: FordCarInfo("Ford Bronco Sport 2021-22", car_parts=CarParts.default([HarnessConnector.ford_q3, Mount.angled_mount], remove=[Mount.mount])),
CAR.ESCAPE_MK4: [
FordCarInfo("Ford Escape 2020-22"),
FordCarInfo("Ford Kuga 2020-22", "Adaptive Cruise Control with Lane Centering"),
Expand Down
6 changes: 3 additions & 3 deletions selfdrive/car/gm/values.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from cereal import car
from selfdrive.car import dbc_dict
from selfdrive.car.docs_definitions import CarFootnote, CarInfo, Column, Harness, HarnessKit, HarnessPart
from selfdrive.car.docs_definitions import Cable, CarFootnote, CarInfo, CarParts, Column, HarnessConnector, Mount
Ecu = car.CarParams.Ecu


Expand Down Expand Up @@ -89,9 +89,9 @@ class GMCarInfo(CarInfo):

def init_make(self, CP: car.CarParams):
if CP.networkLocation == car.CarParams.NetworkLocation.fwdCamera:
self.harness_kit = HarnessKit(Harness.gm)
self.car_parts = CarParts.default([HarnessConnector.gm])
else:
self.harness_kit = HarnessKit(Harness.obd_ii, parts=[HarnessPart.long_obdc_cable, HarnessPart.usbc_coupler])
self.car_parts = CarParts([HarnessConnector.obd_ii, Cable.long_obdc_cable, Cable.usbc_coupler, Mount.mount])
self.footnotes.append(Footnote.OBD_II)


Expand Down
6 changes: 3 additions & 3 deletions selfdrive/car/honda/values.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from common.conversions import Conversions as CV
from panda.python import uds
from selfdrive.car import dbc_dict
from selfdrive.car.docs_definitions import CarFootnote, CarInfo, Column, Harness, HarnessKit
from selfdrive.car.docs_definitions import CarFootnote, CarInfo, CarParts, Column, HarnessConnector
from selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries, p16

Ecu = car.CarParams.Ecu
Expand Down Expand Up @@ -110,9 +110,9 @@ class HondaCarInfo(CarInfo):

def init_make(self, CP: car.CarParams):
if CP.carFingerprint in HONDA_BOSCH:
self.harness_kit = HarnessKit(Harness.bosch_b) if CP.carFingerprint in HONDA_BOSCH_RADARLESS else HarnessKit(Harness.bosch_a)
self.car_parts = CarParts.default([HarnessConnector.bosch_b]) if CP.carFingerprint in HONDA_BOSCH_RADARLESS else CarParts.default([HarnessConnector.bosch_a])
else:
self.harness_kit = HarnessKit(Harness.nidec)
self.car_parts = CarParts.default([HarnessConnector.nidec])


CAR_INFO: Dict[str, Optional[Union[HondaCarInfo, List[HondaCarInfo]]]] = {
Expand Down