Compare commits

..

2 Commits

Author SHA1 Message Date
github-actions[bot] 9f226a4f5e sunnypilot v2026.01.14-3989
version: sunnypilot v2025.003.000 (feature-branch)
date: 2026-01-14T04:01:43
master commit: 89a3a953b2
2026-01-14 04:01:43 +00:00
github-actions[bot] d5a9c45fc8 sunnypilot v2026.01.14-3989 release 2026-01-14 04:01:33 +00:00
1673 changed files with 283234 additions and 321112 deletions
-5
View File
@@ -99,11 +99,6 @@ Pipfile
.history
.ionide
.claude/
.context/
PLAN.md
TASK.md
### JetBrains ###
!.idea/customTargets.xml
!.idea/tools/*
+1 -100
View File
@@ -1,104 +1,5 @@
sunnypilot Version 2026.001.000 (2026-03-xx)
sunnypilot Version 2025.003.000 (20xx-xx-xx)
========================
* What's Changed (sunnypilot/sunnypilot)
* Complete rewrite of the user interface from Qt C++ to Raylib Python
* comma four support
* ui: sunnypilot toggle style by @nayan8teen
* ui: fix scroll panel mouse wheel behavior by @nayan8teen
* ui: sunnypilot panels by @nayan8teen
* sunnylink: centralize key pair handling in sunnylink registration by @devtekve
* ui: reimplement sunnypilot branding with Raylib by @sunnyhaibin
* ui: Platform Selector by @Discountchubbs
* ui: vehicle brand settings by @Discountchubbs
* ui: sunnylink client-side implementation by @nayan8teen
* ui: `NetworkUISP` by @Discountchubbs
* ui: add sunnypilot font by @nayan8teen
* ui: sunnypilot sponsor tier color mapping by @sunnyhaibin
* ui: sunnylink panel by @nayan8teen
* ui: Models panel by @Discountchubbs
* ui: software panel by @Discountchubbs
* modeld_v2: support planplus outputs by @Discountchubbs
* ui: OSM panel by @Discountchubbs
* ui: Developer panel extension by @Discountchubbs
* sunnylink: Vehicle Selector support by @sunnyhaibin
* [TIZI/TICI] ui: Developer Metrics by @rav4kumar
* [comma 4] ui: sunnylink panel by @nayan8teen
* ui: lateral-only and longitudinal-only UI statuses support by @royjr
* sunnylink: elliptic curve keys support and improve key path handling by @nayan8teen
* sunnylink: block remote modification of SSH key parameters by @zikeji
* [TIZI/TICI] ui: rainbow path by @rav4kumar
* [TIZI/TICI] ui: chevron metrics by @rav4kumar
* ui: include MADS enabled state to `engaged` check by @sunnyhaibin
* Toyota: Enforce Factory Longitudinal Control by @sunnyhaibin
* ui: fix malformed dongle ID display on the PC if dongleID is not set by @dzid26
* SL: Re enable and validate ingestion of swaglogs by @devtekve
* modeld_v2: planplus model tuning by @Discountchubbs
* ui: fix Always Offroad button visibility by @nayan8teen
* Reimplement sunnypilot Terms of Service & sunnylink Consent Screens by @sunnyhaibin
* [TIZI/TICI] ui: update dmoji position and Developer UI adjustments by @rav4kumar
* modeld: configurable camera offset by @Discountchubbs
* [TIZI/TICI] ui: sunnylink status on sidebar by @Copilot
* ui: Global Brightness Override by @nayan8teen
* ui: Customizable Interactive Timeout by @sunnyhaibin
* sunnylink: add units to param metadata by @nayan8teen
* ui: Customizable Onroad Brightness by @sunnyhaibin
* [TIZI/TICI] ui: Steering panel by @nayan8teen
* [TIZI/TICI] ui: Rocket Fuel by @rav4kumar
* [TIZI/TICI] ui: MICI style turn signals by @rav4kumar
* [TIZI/TICI] ui: MICI style blindspot indicators by @sunnyhaibin
* [MICI] ui: display blindspot indicators when available by @rav4kumar
* [TIZI/TICI] ui: Road Name by @rav4kumar
* [TIZI/TICI] ui: Blue "Exit Always Offroad" button by @dzid26
* [TIZI/TICI] ui: Speed Limit by @rav4kumar
* Reapply "latcontrol_torque: lower kp and lower friction threshold (commaai/openpilot#36619)" by @sunnyhaibin
* [TIZI/TICI] ui: steering arc by @royjr
* [TIZI/TICI] ui: Smart Cruise Control elements by @sunnyhaibin
* [TIZI/TICI] ui: Green Light and Lead Departure elements by @sunnyhaibin
* [TIZI/TICI] ui: standstill timer by @sunnyhaibin
* [MICI] ui: driving models selector by @Discountchubbs
* [TIZI/TICI] ui: Hide vEgo and True vEgo by @sunnyhaibin
* [TIZI/TICI] ui: Visuals panel by @nayan8teen
* Device: Retain QuickBoot state after op switch by @nayan8teen
* [TIZI/TICI] ui: Trips panel by @sunnyhaibin
* [TIZI/TICI] ui: dynamic ICBM status by @sunnyhaibin
* [TIZI/TICI] ui: Cruise panel by @sunnyhaibin
* ui: better wake mode support by @nayan8teen
* Pause Lateral Control with Blinker: Post-Blinker Delay by @CHaucke89
* SCC-V: Use p97 for predicted lateral accel by @yasu-oh
* Controls: Support for Torque Lateral Control v0 Tune by @sunnyhaibin
* What's Changed (sunnypilot/opendbc)
* Honda: DBC for Accord 9th Generation by @mvl-boston
* FCA: update tire stiffness values for `RAM_HD` by @dparring
* Honda: Nidec hybrid baseline brake support by @mvl-boston
* Subaru Global Gen2: bump steering limits and update tuning by @sunnyhaibin
* Toyota: Enforce Stock Longitudinal Control by @rav4kumar
* Nissan: use MADS enabled status for LKAS HUD logic by @downquark7
* Reapply "Lateral: lower friction threshold (#2915)" (#378) by @sunnyhaibin
* HKG: add KIA_FORTE_2019_NON_SCC fingerprint by @royjr
* Nissan: Parse cruise control buttons by @downquark7
* Rivian: Add stalk down ACC behavior to match stock Rivian by @lukasloetkolben
* Tesla: remove `TESLA_MODEL_X` from `dashcamOnly` by @ssysm
* Hyundai Longitudinal: refactor tuning by @Discountchubbs
* Tesla: add fingerprint for Model 3 Performance HW4 by @sunnyhaibin
* Toyota: do not disable radar when smartDSU or CAN Filter detected by @sunnyhaibin
* Honda: add missing `GasInterceptor` messages to Taiwan Odyssey DBC by @mvl-boston
* GM: remove `CHEVROLET_EQUINOX_NON_ACC_3RD_GEN` from `dashcamOnly` by @sunnyhaibin
* GM: remove `CHEVROLET_BOLT_NON_ACC_2ND_GEN` from `dashcamOnly` by @sunnyhaibin
* New Contributors (sunnypilot/sunnypilot)
* @TheSecurityDev made their first contribution in "ui: fix sidebar scroll in UI screenshots"
* @zikeji made their first contribution in "sunnylink: block remote modification of SSH key parameters"
* @Candy0707 made their first contribution in "[TIZI/TICI] ui: Fix misaligned turn signals and blindspot indicators with sidebar"
* @CHaucke89 made their first contribution in "Pause Lateral Control with Blinker: Post-Blinker Delay"
* @yasu-oh made their first contribution in "SCC-V: Use p97 for predicted lateral accel"
* New Contributors (sunnypilot/opendbc)
* @AmyJeanes made their first contribution in "Tesla: Fix stock LKAS being blocked when MADS is enabled"
* @mvl-boston made their first contribution in "Honda: Update Clarity brake to renamed DBC message name"
* @dzid26 made their first contribution in "Tesla: Parse speed limit from CAN"
* @firestar5683 made their first contribution in "GM: Non-ACC platforms with steering only support"
* @downquark7 made their first contribution in "Nissan: use MADS enabled status for LKAS HUD logic"
* @royjr made their first contribution in "HKG: add KIA_FORTE_2019_NON_SCC fingerprint"
* @ssysm made their first contribution in "Tesla: remove `TESLA_MODEL_X` from `dashcamOnly`"
* Full Changelog: https://github.com/sunnypilot/sunnypilot/compare/v2025.002.000...v2026.001.000
sunnypilot Version 2025.002.000 (2025-11-06)
========================
+1 -3
View File
@@ -9,6 +9,4 @@ WORKDIR ${OPENPILOT_PATH}
COPY . ${OPENPILOT_PATH}/
ENV UV_BIN="/home/batman/.local/bin/"
ENV PATH="$UV_BIN:$PATH"
RUN UV_PROJECT_ENVIRONMENT=$VIRTUAL_ENV uv run scons --cache-readonly -j$(nproc)
RUN scons --cache-readonly -j$(nproc)
-4
View File
@@ -1,7 +1,3 @@
Version 0.10.4 (2026-02-17)
========================
* Lexus LS 2018 support thanks to Hacheoy!
Version 0.10.3 (2025-12-17)
========================
* New driving model #36249
+118 -4
View File
@@ -153,7 +153,6 @@ struct ModelManagerSP @0xaedffd8f31e7b55d {
navigation @1;
vision @2;
policy @3;
offPolicy @4;
}
}
@@ -289,6 +288,7 @@ struct LongitudinalPlanSP @0xf35cc4560bbf6ec2 {
sccVision @1;
sccMap @2;
speedLimitAssist @3;
mapd @4;
}
struct E2eAlerts {
@@ -476,11 +476,125 @@ struct CustomReserved15 @0xbd443b539493bc68 {
struct CustomReserved16 @0xfc6241ed8877b611 {
}
struct CustomReserved17 @0xa30662f84033036c {
struct MapdDownloadLocationDetails @0xff889853e7b0987f {
location @0 :Text;
totalFiles @1 :UInt32;
downloadedFiles @2 :UInt32;
}
struct CustomReserved18 @0xc86a3d38d13eb3ef {
struct MapdDownloadProgress @0xfaa35dcac85073a2 {
active @0 :Bool;
cancelled @1 :Bool;
totalFiles @2 :UInt32;
downloadedFiles @3 :UInt32;
locations @4 :List(Text);
locationDetails @5 :List(MapdDownloadLocationDetails);
}
struct CustomReserved19 @0xa4f1eb3323f5f582 {
struct MapdPathPoint @0xd6f78acca1bc3939 {
latitude @0 :Float64;
longitude @1 :Float64;
curvature @2 :Float32;
targetVelocity @3 :Float32;
}
struct MapdExtendedOut @0xa30662f84033036c {
downloadProgress @0 :MapdDownloadProgress;
settings @1 :Text;
path @2 :List(MapdPathPoint);
}
enum MapdInputType {
download @0;
setTargetLateralAccel @1;
setSpeedLimitOffset @2;
setSpeedLimitControl @3;
setMapCurveSpeedControl @4;
setVisionCurveSpeedControl @5;
setLogLevel @6;
setVisionCurveTargetLatA @7;
setVisionCurveMinTargetV @8;
reloadSettings @9;
saveSettings @10;
setEnableSpeed @11;
setVisionCurveUseEnableSpeed @12;
setMapCurveUseEnableSpeed @13;
setSpeedLimitUseEnableSpeed @14;
setHoldLastSeenSpeedLimit @15;
setTargetSpeedJerk @16;
setTargetSpeedAccel @17;
setTargetSpeedTimeOffset @18;
setDefaultLaneWidth @19;
setMapCurveTargetLatA @20;
loadDefaultSettings @21;
loadRecommendedSettings @22;
setSlowDownForNextSpeedLimit @23;
setSpeedUpForNextSpeedLimit @24;
setHoldSpeedLimitWhileChangingSetSpeed @25;
loadPersistentSettings @26;
cancelDownload @27;
setLogJson @28;
setLogSource @29;
setExternalSpeedLimitControl @30;
setExternalSpeedLimit @31;
setSpeedLimitPriority @32;
setSpeedLimitChangeRequiresAccept @33;
acceptSpeedLimit @34;
setPressGasToAcceptSpeedLimit @35;
setAdjustSetSpeedToAcceptSpeedLimit @36;
setAcceptSpeedLimitTimeout @37;
setPressGasToOverrideSpeedLimit @38;
}
enum WaySelectionType {
current @0;
predicted @1;
possible @2;
extended @3;
fail @4;
}
enum SpeedLimitOffsetType {
static @0;
percent @1;
}
struct MapdIn @0xc86a3d38d13eb3ef {
type @0 :MapdInputType;
float @1 :Float32;
str @2 :Text;
bool @3 :Bool;
}
enum RoadContext {
freeway @0;
city @1;
unknown @2;
}
struct MapdOut @0xa4f1eb3323f5f582 {
wayName @0 :Text;
wayRef @1 :Text;
roadName @2 :Text;
speedLimit @3 :Float32;
nextSpeedLimit @4 :Float32;
nextSpeedLimitDistance @5 :Float32;
hazard @6 :Text;
nextHazard @7 :Text;
nextHazardDistance @8 :Float32;
advisorySpeed @9 :Float32;
nextAdvisorySpeed @10 :Float32;
nextAdvisorySpeedDistance @11 :Float32;
oneWay @12 :Bool;
lanes @13 :UInt8;
tileLoaded @14 :Bool;
speedLimitSuggestedSpeed @15 :Float32;
suggestedSpeed @16 :Float32;
estimatedRoadWidth @17 :Float32;
roadContext @18 :RoadContext;
distanceFromWayCenter @19 :Float32;
visionCurveSpeed @20 :Float32;
mapCurveSpeed @21 :Float32;
waySelectionType @22 :WaySelectionType;
speedLimitAccepted @23 :Bool;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+321 -378
View File
@@ -369,7 +369,7 @@ const ::capnp::_::RawSchema s_c4fa6047f024e718 = {
1, 11, i_c4fa6047f024e718, nullptr, nullptr, { &s_c4fa6047f024e718, nullptr, nullptr, 0, 0, nullptr }, false
};
#endif // !CAPNP_LITE
static const ::capnp::_::AlignedData<553> b_91f1992a1f77fb03 = {
static const ::capnp::_::AlignedData<548> b_91f1992a1f77fb03 = {
{ 0, 0, 0, 0, 5, 0, 6, 0,
3, 251, 119, 31, 42, 153, 241, 145,
22, 0, 0, 0, 2, 0, 0, 0,
@@ -379,7 +379,7 @@ static const ::capnp::_::AlignedData<553> b_91f1992a1f77fb03 = {
21, 0, 0, 0, 2, 1, 0, 0,
33, 0, 0, 0, 7, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
29, 0, 0, 0, 79, 9, 0, 0,
29, 0, 0, 0, 55, 9, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
108, 111, 103, 46, 99, 97, 112, 110,
@@ -387,303 +387,300 @@ static const ::capnp::_::AlignedData<553> b_91f1992a1f77fb03 = {
69, 118, 101, 110, 116, 46, 69, 118,
101, 110, 116, 78, 97, 109, 101, 0,
0, 0, 0, 0, 1, 0, 1, 0,
140, 1, 0, 0, 1, 0, 2, 0,
136, 1, 0, 0, 1, 0, 2, 0,
0, 0, 0, 0, 0, 0, 0, 0,
157, 4, 0, 0, 74, 0, 0, 0,
145, 4, 0, 0, 74, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0,
153, 4, 0, 0, 138, 0, 0, 0,
141, 4, 0, 0, 138, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
2, 0, 0, 0, 0, 0, 0, 0,
153, 4, 0, 0, 82, 0, 0, 0,
141, 4, 0, 0, 82, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
3, 0, 0, 0, 0, 0, 0, 0,
149, 4, 0, 0, 74, 0, 0, 0,
137, 4, 0, 0, 74, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
4, 0, 0, 0, 0, 0, 0, 0,
145, 4, 0, 0, 154, 0, 0, 0,
133, 4, 0, 0, 154, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
5, 0, 0, 0, 0, 0, 0, 0,
145, 4, 0, 0, 98, 0, 0, 0,
133, 4, 0, 0, 98, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
6, 0, 0, 0, 0, 0, 0, 0,
141, 4, 0, 0, 106, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
7, 0, 0, 0, 0, 0, 0, 0,
137, 4, 0, 0, 170, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
8, 0, 0, 0, 0, 0, 0, 0,
137, 4, 0, 0, 98, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
9, 0, 0, 0, 0, 0, 0, 0,
133, 4, 0, 0, 106, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
10, 0, 0, 0, 0, 0, 0, 0,
129, 4, 0, 0, 106, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
7, 0, 0, 0, 0, 0, 0, 0,
125, 4, 0, 0, 170, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
8, 0, 0, 0, 0, 0, 0, 0,
125, 4, 0, 0, 98, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
9, 0, 0, 0, 0, 0, 0, 0,
121, 4, 0, 0, 106, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
10, 0, 0, 0, 0, 0, 0, 0,
117, 4, 0, 0, 106, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
11, 0, 0, 0, 0, 0, 0, 0,
125, 4, 0, 0, 106, 0, 0, 0,
113, 4, 0, 0, 106, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
12, 0, 0, 0, 0, 0, 0, 0,
121, 4, 0, 0, 162, 0, 0, 0,
109, 4, 0, 0, 162, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
13, 0, 0, 0, 0, 0, 0, 0,
121, 4, 0, 0, 154, 0, 0, 0,
109, 4, 0, 0, 154, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
14, 0, 0, 0, 0, 0, 0, 0,
121, 4, 0, 0, 114, 0, 0, 0,
109, 4, 0, 0, 114, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
16, 0, 0, 0, 0, 0, 0, 0,
117, 4, 0, 0, 122, 0, 0, 0,
105, 4, 0, 0, 122, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
17, 0, 0, 0, 0, 0, 0, 0,
113, 4, 0, 0, 98, 0, 0, 0,
101, 4, 0, 0, 98, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
18, 0, 0, 0, 0, 0, 0, 0,
109, 4, 0, 0, 90, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
19, 0, 0, 0, 0, 0, 0, 0,
105, 4, 0, 0, 74, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
20, 0, 0, 0, 0, 0, 0, 0,
101, 4, 0, 0, 178, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
21, 0, 0, 0, 0, 0, 0, 0,
101, 4, 0, 0, 154, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
22, 0, 0, 0, 0, 0, 0, 0,
101, 4, 0, 0, 202, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
23, 0, 0, 0, 0, 0, 0, 0,
105, 4, 0, 0, 138, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
24, 0, 0, 0, 0, 0, 0, 0,
105, 4, 0, 0, 82, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
25, 0, 0, 0, 0, 0, 0, 0,
101, 4, 0, 0, 90, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
26, 0, 0, 0, 0, 0, 0, 0,
97, 4, 0, 0, 90, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
28, 0, 0, 0, 0, 0, 0, 0,
19, 0, 0, 0, 0, 0, 0, 0,
93, 4, 0, 0, 74, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
20, 0, 0, 0, 0, 0, 0, 0,
89, 4, 0, 0, 178, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
21, 0, 0, 0, 0, 0, 0, 0,
89, 4, 0, 0, 154, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
22, 0, 0, 0, 0, 0, 0, 0,
89, 4, 0, 0, 202, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
23, 0, 0, 0, 0, 0, 0, 0,
93, 4, 0, 0, 138, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
24, 0, 0, 0, 0, 0, 0, 0,
93, 4, 0, 0, 82, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
25, 0, 0, 0, 0, 0, 0, 0,
89, 4, 0, 0, 90, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
26, 0, 0, 0, 0, 0, 0, 0,
85, 4, 0, 0, 90, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
28, 0, 0, 0, 0, 0, 0, 0,
81, 4, 0, 0, 82, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
29, 0, 0, 0, 0, 0, 0, 0,
89, 4, 0, 0, 82, 0, 0, 0,
77, 4, 0, 0, 82, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
30, 0, 0, 0, 0, 0, 0, 0,
85, 4, 0, 0, 114, 0, 0, 0,
73, 4, 0, 0, 114, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
31, 0, 0, 0, 0, 0, 0, 0,
81, 4, 0, 0, 114, 0, 0, 0,
69, 4, 0, 0, 114, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
32, 0, 0, 0, 0, 0, 0, 0,
77, 4, 0, 0, 170, 0, 0, 0,
65, 4, 0, 0, 170, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
33, 0, 0, 0, 0, 0, 0, 0,
77, 4, 0, 0, 218, 0, 0, 0,
65, 4, 0, 0, 218, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
34, 0, 0, 0, 0, 0, 0, 0,
81, 4, 0, 0, 122, 0, 0, 0,
69, 4, 0, 0, 122, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
35, 0, 0, 0, 0, 0, 0, 0,
77, 4, 0, 0, 162, 0, 0, 0,
65, 4, 0, 0, 162, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
36, 0, 0, 0, 0, 0, 0, 0,
77, 4, 0, 0, 186, 0, 0, 0,
65, 4, 0, 0, 186, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
37, 0, 0, 0, 0, 0, 0, 0,
77, 4, 0, 0, 138, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
38, 0, 0, 0, 0, 0, 0, 0,
77, 4, 0, 0, 178, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
39, 0, 0, 0, 0, 0, 0, 0,
77, 4, 0, 0, 202, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
40, 0, 0, 0, 0, 0, 0, 0,
81, 4, 0, 0, 154, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
41, 0, 0, 0, 0, 0, 0, 0,
81, 4, 0, 0, 130, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
42, 0, 0, 0, 0, 0, 0, 0,
77, 4, 0, 0, 90, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
43, 0, 0, 0, 0, 0, 0, 0,
73, 4, 0, 0, 90, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
44, 0, 0, 0, 0, 0, 0, 0,
69, 4, 0, 0, 146, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
45, 0, 0, 0, 0, 0, 0, 0,
69, 4, 0, 0, 82, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
46, 0, 0, 0, 0, 0, 0, 0,
65, 4, 0, 0, 138, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
47, 0, 0, 0, 0, 0, 0, 0,
65, 4, 0, 0, 114, 0, 0, 0,
38, 0, 0, 0, 0, 0, 0, 0,
65, 4, 0, 0, 178, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
48, 0, 0, 0, 0, 0, 0, 0,
61, 4, 0, 0, 122, 0, 0, 0,
39, 0, 0, 0, 0, 0, 0, 0,
65, 4, 0, 0, 202, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
98, 0, 0, 0, 0, 0, 0, 0,
57, 4, 0, 0, 226, 0, 0, 0,
40, 0, 0, 0, 0, 0, 0, 0,
69, 4, 0, 0, 154, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
49, 0, 0, 0, 0, 0, 0, 0,
61, 4, 0, 0, 146, 0, 0, 0,
41, 0, 0, 0, 0, 0, 0, 0,
69, 4, 0, 0, 130, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
50, 0, 0, 0, 0, 0, 0, 0,
61, 4, 0, 0, 154, 0, 0, 0,
42, 0, 0, 0, 0, 0, 0, 0,
65, 4, 0, 0, 90, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
51, 0, 0, 0, 0, 0, 0, 0,
43, 0, 0, 0, 0, 0, 0, 0,
61, 4, 0, 0, 90, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
52, 0, 0, 0, 0, 0, 0, 0,
44, 0, 0, 0, 0, 0, 0, 0,
57, 4, 0, 0, 146, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
45, 0, 0, 0, 0, 0, 0, 0,
57, 4, 0, 0, 82, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
53, 0, 0, 0, 0, 0, 0, 0,
53, 4, 0, 0, 74, 0, 0, 0,
46, 0, 0, 0, 0, 0, 0, 0,
53, 4, 0, 0, 138, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
55, 0, 0, 0, 0, 0, 0, 0,
49, 4, 0, 0, 34, 0, 0, 0,
47, 0, 0, 0, 0, 0, 0, 0,
53, 4, 0, 0, 114, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
56, 0, 0, 0, 0, 0, 0, 0,
41, 4, 0, 0, 130, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
57, 0, 0, 0, 0, 0, 0, 0,
37, 4, 0, 0, 154, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
58, 0, 0, 0, 0, 0, 0, 0,
37, 4, 0, 0, 106, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
59, 0, 0, 0, 0, 0, 0, 0,
33, 4, 0, 0, 146, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
60, 0, 0, 0, 0, 0, 0, 0,
33, 4, 0, 0, 138, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
61, 0, 0, 0, 0, 0, 0, 0,
33, 4, 0, 0, 74, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
62, 0, 0, 0, 0, 0, 0, 0,
29, 4, 0, 0, 66, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
63, 0, 0, 0, 0, 0, 0, 0,
21, 4, 0, 0, 106, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
64, 0, 0, 0, 0, 0, 0, 0,
17, 4, 0, 0, 138, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
65, 0, 0, 0, 0, 0, 0, 0,
17, 4, 0, 0, 146, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
66, 0, 0, 0, 0, 0, 0, 0,
17, 4, 0, 0, 114, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
67, 0, 0, 0, 0, 0, 0, 0,
13, 4, 0, 0, 34, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
68, 0, 0, 0, 0, 0, 0, 0,
5, 4, 0, 0, 122, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
69, 0, 0, 0, 0, 0, 0, 0,
1, 4, 0, 0, 138, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
70, 0, 0, 0, 0, 0, 0, 0,
1, 4, 0, 0, 50, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
71, 0, 0, 0, 0, 0, 0, 0,
249, 3, 0, 0, 130, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
72, 0, 0, 0, 0, 0, 0, 0,
245, 3, 0, 0, 114, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
73, 0, 0, 0, 0, 0, 0, 0,
241, 3, 0, 0, 114, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
74, 0, 0, 0, 0, 0, 0, 0,
237, 3, 0, 0, 122, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
75, 0, 0, 0, 0, 0, 0, 0,
233, 3, 0, 0, 146, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
76, 0, 0, 0, 0, 0, 0, 0,
233, 3, 0, 0, 130, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
77, 0, 0, 0, 0, 0, 0, 0,
229, 3, 0, 0, 146, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
78, 0, 0, 0, 0, 0, 0, 0,
229, 3, 0, 0, 98, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
79, 0, 0, 0, 0, 0, 0, 0,
225, 3, 0, 0, 178, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
80, 0, 0, 0, 0, 0, 0, 0,
225, 3, 0, 0, 74, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
81, 0, 0, 0, 0, 0, 0, 0,
221, 3, 0, 0, 122, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
82, 0, 0, 0, 0, 0, 0, 0,
217, 3, 0, 0, 114, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
83, 0, 0, 0, 0, 0, 0, 0,
213, 3, 0, 0, 146, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
84, 0, 0, 0, 0, 0, 0, 0,
213, 3, 0, 0, 114, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
85, 0, 0, 0, 0, 0, 0, 0,
209, 3, 0, 0, 122, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
86, 0, 0, 0, 0, 0, 0, 0,
205, 3, 0, 0, 178, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
87, 0, 0, 0, 0, 0, 0, 0,
205, 3, 0, 0, 194, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
88, 0, 0, 0, 0, 0, 0, 0,
205, 3, 0, 0, 194, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
89, 0, 0, 0, 0, 0, 0, 0,
205, 3, 0, 0, 178, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
90, 0, 0, 0, 0, 0, 0, 0,
205, 3, 0, 0, 178, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
91, 0, 0, 0, 0, 0, 0, 0,
205, 3, 0, 0, 194, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
92, 0, 0, 0, 0, 0, 0, 0,
205, 3, 0, 0, 82, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
93, 0, 0, 0, 0, 0, 0, 0,
201, 3, 0, 0, 154, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
94, 0, 0, 0, 0, 0, 0, 0,
201, 3, 0, 0, 34, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
27, 0, 0, 0, 0, 0, 0, 0,
193, 3, 0, 0, 170, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
15, 0, 0, 0, 0, 0, 0, 0,
193, 3, 0, 0, 122, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
95, 0, 0, 0, 0, 0, 0, 0,
189, 3, 0, 0, 106, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
96, 0, 0, 0, 0, 0, 0, 0,
185, 3, 0, 0, 154, 0, 0, 0,
48, 0, 0, 0, 0, 0, 0, 0,
49, 4, 0, 0, 122, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
97, 0, 0, 0, 0, 0, 0, 0,
185, 3, 0, 0, 114, 0, 0, 0,
45, 4, 0, 0, 226, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
49, 0, 0, 0, 0, 0, 0, 0,
49, 4, 0, 0, 146, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
50, 0, 0, 0, 0, 0, 0, 0,
49, 4, 0, 0, 154, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
51, 0, 0, 0, 0, 0, 0, 0,
49, 4, 0, 0, 90, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
52, 0, 0, 0, 0, 0, 0, 0,
45, 4, 0, 0, 82, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
53, 0, 0, 0, 0, 0, 0, 0,
41, 4, 0, 0, 74, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
54, 0, 0, 0, 0, 0, 0, 0,
181, 3, 0, 0, 82, 0, 0, 0,
37, 4, 0, 0, 34, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
55, 0, 0, 0, 0, 0, 0, 0,
29, 4, 0, 0, 130, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
56, 0, 0, 0, 0, 0, 0, 0,
25, 4, 0, 0, 154, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
57, 0, 0, 0, 0, 0, 0, 0,
25, 4, 0, 0, 106, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
58, 0, 0, 0, 0, 0, 0, 0,
21, 4, 0, 0, 146, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
59, 0, 0, 0, 0, 0, 0, 0,
21, 4, 0, 0, 138, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
60, 0, 0, 0, 0, 0, 0, 0,
21, 4, 0, 0, 74, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
61, 0, 0, 0, 0, 0, 0, 0,
17, 4, 0, 0, 66, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
62, 0, 0, 0, 0, 0, 0, 0,
9, 4, 0, 0, 106, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
63, 0, 0, 0, 0, 0, 0, 0,
5, 4, 0, 0, 138, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
64, 0, 0, 0, 0, 0, 0, 0,
5, 4, 0, 0, 146, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
65, 0, 0, 0, 0, 0, 0, 0,
5, 4, 0, 0, 114, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
66, 0, 0, 0, 0, 0, 0, 0,
1, 4, 0, 0, 34, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
67, 0, 0, 0, 0, 0, 0, 0,
249, 3, 0, 0, 122, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
68, 0, 0, 0, 0, 0, 0, 0,
245, 3, 0, 0, 138, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
69, 0, 0, 0, 0, 0, 0, 0,
245, 3, 0, 0, 50, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
70, 0, 0, 0, 0, 0, 0, 0,
237, 3, 0, 0, 130, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
71, 0, 0, 0, 0, 0, 0, 0,
233, 3, 0, 0, 114, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
72, 0, 0, 0, 0, 0, 0, 0,
229, 3, 0, 0, 114, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
73, 0, 0, 0, 0, 0, 0, 0,
225, 3, 0, 0, 122, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
74, 0, 0, 0, 0, 0, 0, 0,
221, 3, 0, 0, 146, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
75, 0, 0, 0, 0, 0, 0, 0,
221, 3, 0, 0, 130, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
76, 0, 0, 0, 0, 0, 0, 0,
217, 3, 0, 0, 146, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
77, 0, 0, 0, 0, 0, 0, 0,
217, 3, 0, 0, 98, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
78, 0, 0, 0, 0, 0, 0, 0,
213, 3, 0, 0, 178, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
79, 0, 0, 0, 0, 0, 0, 0,
213, 3, 0, 0, 74, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
80, 0, 0, 0, 0, 0, 0, 0,
209, 3, 0, 0, 122, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
81, 0, 0, 0, 0, 0, 0, 0,
205, 3, 0, 0, 114, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
82, 0, 0, 0, 0, 0, 0, 0,
201, 3, 0, 0, 146, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
83, 0, 0, 0, 0, 0, 0, 0,
201, 3, 0, 0, 114, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
84, 0, 0, 0, 0, 0, 0, 0,
197, 3, 0, 0, 122, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
85, 0, 0, 0, 0, 0, 0, 0,
193, 3, 0, 0, 178, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
86, 0, 0, 0, 0, 0, 0, 0,
193, 3, 0, 0, 194, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
87, 0, 0, 0, 0, 0, 0, 0,
193, 3, 0, 0, 194, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
88, 0, 0, 0, 0, 0, 0, 0,
193, 3, 0, 0, 178, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
89, 0, 0, 0, 0, 0, 0, 0,
193, 3, 0, 0, 178, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
90, 0, 0, 0, 0, 0, 0, 0,
193, 3, 0, 0, 194, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
91, 0, 0, 0, 0, 0, 0, 0,
193, 3, 0, 0, 82, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
92, 0, 0, 0, 0, 0, 0, 0,
189, 3, 0, 0, 154, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
93, 0, 0, 0, 0, 0, 0, 0,
189, 3, 0, 0, 34, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
27, 0, 0, 0, 0, 0, 0, 0,
181, 3, 0, 0, 170, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
15, 0, 0, 0, 0, 0, 0, 0,
181, 3, 0, 0, 122, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
94, 0, 0, 0, 0, 0, 0, 0,
177, 3, 0, 0, 106, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
95, 0, 0, 0, 0, 0, 0, 0,
173, 3, 0, 0, 154, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
96, 0, 0, 0, 0, 0, 0, 0,
173, 3, 0, 0, 114, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
99, 97, 110, 69, 114, 114, 111, 114,
0, 0, 0, 0, 0, 0, 0, 0,
@@ -920,16 +917,14 @@ static const ::capnp::_::AlignedData<553> b_91f1992a1f77fb03 = {
101, 65, 99, 116, 117, 97, 116, 105,
111, 110, 0, 0, 0, 0, 0, 0,
97, 117, 100, 105, 111, 70, 101, 101,
100, 98, 97, 99, 107, 0, 0, 0,
115, 116, 111, 99, 107, 76, 107, 97,
115, 0, 0, 0, 0, 0, 0, 0, }
100, 98, 97, 99, 107, 0, 0, 0, }
};
::capnp::word const* const bp_91f1992a1f77fb03 = b_91f1992a1f77fb03.words;
#if !CAPNP_LITE
static const uint16_t m_91f1992a1f77fb03[] = {41, 89, 92, 97, 67, 39, 26, 9, 10, 19, 20, 21, 74, 73, 80, 0, 54, 43, 44, 22, 15, 79, 76, 71, 3, 35, 38, 90, 5, 96, 72, 65, 13, 55, 29, 50, 57, 53, 86, 85, 30, 40, 51, 28, 70, 68, 17, 18, 88, 87, 27, 24, 23, 11, 91, 46, 33, 36, 12, 48, 49, 75, 34, 37, 25, 93, 58, 82, 32, 8, 4, 77, 81, 42, 47, 56, 16, 60, 64, 61, 62, 63, 94, 14, 66, 7, 31, 83, 1, 52, 59, 98, 45, 78, 95, 84, 6, 69, 2};
static const uint16_t m_91f1992a1f77fb03[] = {41, 89, 92, 97, 67, 39, 26, 9, 10, 19, 20, 21, 74, 73, 80, 0, 54, 43, 44, 22, 15, 79, 76, 71, 3, 35, 38, 90, 5, 96, 72, 65, 13, 55, 29, 50, 57, 53, 86, 85, 30, 40, 51, 28, 70, 68, 17, 18, 88, 87, 27, 24, 23, 11, 91, 46, 33, 36, 12, 48, 49, 75, 34, 37, 25, 93, 58, 82, 32, 8, 4, 77, 81, 42, 47, 56, 16, 60, 64, 61, 62, 63, 94, 14, 66, 7, 31, 83, 1, 52, 59, 45, 78, 95, 84, 6, 69, 2};
const ::capnp::_::RawSchema s_91f1992a1f77fb03 = {
0x91f1992a1f77fb03, b_91f1992a1f77fb03.words, 553, nullptr, m_91f1992a1f77fb03,
0, 99, nullptr, nullptr, nullptr, { &s_91f1992a1f77fb03, nullptr, nullptr, 0, 0, nullptr }, false
0x91f1992a1f77fb03, b_91f1992a1f77fb03.words, 548, nullptr, m_91f1992a1f77fb03,
0, 98, nullptr, nullptr, nullptr, { &s_91f1992a1f77fb03, nullptr, nullptr, 0, 0, nullptr }, false
};
#endif // !CAPNP_LITE
CAPNP_DEFINE_ENUM(EventName_91f1992a1f77fb03, 91f1992a1f77fb03);
@@ -17015,17 +17010,17 @@ const ::capnp::_::RawSchema s_af85387b3f681406 = {
3, 3, i_af85387b3f681406, nullptr, nullptr, { &s_af85387b3f681406, nullptr, nullptr, 0, 0, nullptr }, false
};
#endif // !CAPNP_LITE
static const ::capnp::_::AlignedData<332> b_b0b85613f19e6d28 = {
static const ::capnp::_::AlignedData<285> b_b0b85613f19e6d28 = {
{ 0, 0, 0, 0, 5, 0, 6, 0,
40, 109, 158, 241, 19, 86, 184, 176,
18, 0, 0, 0, 1, 0, 12, 0,
18, 0, 0, 0, 1, 0, 9, 0,
6, 20, 104, 63, 123, 56, 133, 175,
3, 0, 7, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
21, 0, 0, 0, 210, 0, 0, 0,
33, 0, 0, 0, 7, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
29, 0, 0, 0, 103, 4, 0, 0,
29, 0, 0, 0, 191, 3, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
108, 111, 103, 46, 99, 97, 112, 110,
@@ -17033,147 +17028,126 @@ static const ::capnp::_::AlignedData<332> b_b0b85613f19e6d28 = {
103, 46, 80, 114, 111, 99, 101, 115,
115, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 1, 0,
80, 0, 0, 0, 3, 0, 4, 0,
68, 0, 0, 0, 3, 0, 4, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
33, 2, 0, 0, 34, 0, 0, 0,
205, 1, 0, 0, 34, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
28, 2, 0, 0, 3, 0, 1, 0,
40, 2, 0, 0, 2, 0, 1, 0,
200, 1, 0, 0, 3, 0, 1, 0,
212, 1, 0, 0, 2, 0, 1, 0,
1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
37, 2, 0, 0, 42, 0, 0, 0,
209, 1, 0, 0, 42, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
32, 2, 0, 0, 3, 0, 1, 0,
44, 2, 0, 0, 2, 0, 1, 0,
204, 1, 0, 0, 3, 0, 1, 0,
216, 1, 0, 0, 2, 0, 1, 0,
2, 0, 0, 0, 4, 0, 0, 0,
0, 0, 1, 0, 2, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
41, 2, 0, 0, 50, 0, 0, 0,
213, 1, 0, 0, 50, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
36, 2, 0, 0, 3, 0, 1, 0,
48, 2, 0, 0, 2, 0, 1, 0,
208, 1, 0, 0, 3, 0, 1, 0,
220, 1, 0, 0, 2, 0, 1, 0,
3, 0, 0, 0, 2, 0, 0, 0,
0, 0, 1, 0, 3, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
45, 2, 0, 0, 42, 0, 0, 0,
217, 1, 0, 0, 42, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
40, 2, 0, 0, 3, 0, 1, 0,
52, 2, 0, 0, 2, 0, 1, 0,
212, 1, 0, 0, 3, 0, 1, 0,
224, 1, 0, 0, 2, 0, 1, 0,
4, 0, 0, 0, 3, 0, 0, 0,
0, 0, 1, 0, 4, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
49, 2, 0, 0, 66, 0, 0, 0,
221, 1, 0, 0, 66, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
44, 2, 0, 0, 3, 0, 1, 0,
56, 2, 0, 0, 2, 0, 1, 0,
216, 1, 0, 0, 3, 0, 1, 0,
228, 1, 0, 0, 2, 0, 1, 0,
5, 0, 0, 0, 4, 0, 0, 0,
0, 0, 1, 0, 5, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
53, 2, 0, 0, 82, 0, 0, 0,
225, 1, 0, 0, 82, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
52, 2, 0, 0, 3, 0, 1, 0,
64, 2, 0, 0, 2, 0, 1, 0,
224, 1, 0, 0, 3, 0, 1, 0,
236, 1, 0, 0, 2, 0, 1, 0,
6, 0, 0, 0, 5, 0, 0, 0,
0, 0, 1, 0, 6, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
61, 2, 0, 0, 130, 0, 0, 0,
233, 1, 0, 0, 130, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
60, 2, 0, 0, 3, 0, 1, 0,
72, 2, 0, 0, 2, 0, 1, 0,
232, 1, 0, 0, 3, 0, 1, 0,
244, 1, 0, 0, 2, 0, 1, 0,
7, 0, 0, 0, 6, 0, 0, 0,
0, 0, 1, 0, 7, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
69, 2, 0, 0, 146, 0, 0, 0,
241, 1, 0, 0, 146, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
72, 2, 0, 0, 3, 0, 1, 0,
84, 2, 0, 0, 2, 0, 1, 0,
244, 1, 0, 0, 3, 0, 1, 0,
0, 2, 0, 0, 2, 0, 1, 0,
8, 0, 0, 0, 4, 0, 0, 0,
0, 0, 1, 0, 8, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
81, 2, 0, 0, 74, 0, 0, 0,
253, 1, 0, 0, 74, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
80, 2, 0, 0, 3, 0, 1, 0,
92, 2, 0, 0, 2, 0, 1, 0,
252, 1, 0, 0, 3, 0, 1, 0,
8, 2, 0, 0, 2, 0, 1, 0,
9, 0, 0, 0, 7, 0, 0, 0,
0, 0, 1, 0, 9, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
89, 2, 0, 0, 42, 0, 0, 0,
5, 2, 0, 0, 42, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
84, 2, 0, 0, 3, 0, 1, 0,
96, 2, 0, 0, 2, 0, 1, 0,
0, 2, 0, 0, 3, 0, 1, 0,
12, 2, 0, 0, 2, 0, 1, 0,
10, 0, 0, 0, 10, 0, 0, 0,
0, 0, 1, 0, 10, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
93, 2, 0, 0, 90, 0, 0, 0,
9, 2, 0, 0, 90, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
92, 2, 0, 0, 3, 0, 1, 0,
104, 2, 0, 0, 2, 0, 1, 0,
8, 2, 0, 0, 3, 0, 1, 0,
20, 2, 0, 0, 2, 0, 1, 0,
11, 0, 0, 0, 6, 0, 0, 0,
0, 0, 1, 0, 11, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
101, 2, 0, 0, 82, 0, 0, 0,
17, 2, 0, 0, 82, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
100, 2, 0, 0, 3, 0, 1, 0,
112, 2, 0, 0, 2, 0, 1, 0,
16, 2, 0, 0, 3, 0, 1, 0,
28, 2, 0, 0, 2, 0, 1, 0,
12, 0, 0, 0, 7, 0, 0, 0,
0, 0, 1, 0, 12, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
109, 2, 0, 0, 58, 0, 0, 0,
25, 2, 0, 0, 58, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
104, 2, 0, 0, 3, 0, 1, 0,
116, 2, 0, 0, 2, 0, 1, 0,
20, 2, 0, 0, 3, 0, 1, 0,
32, 2, 0, 0, 2, 0, 1, 0,
13, 0, 0, 0, 8, 0, 0, 0,
0, 0, 1, 0, 13, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
113, 2, 0, 0, 58, 0, 0, 0,
29, 2, 0, 0, 58, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
108, 2, 0, 0, 3, 0, 1, 0,
120, 2, 0, 0, 2, 0, 1, 0,
24, 2, 0, 0, 3, 0, 1, 0,
36, 2, 0, 0, 2, 0, 1, 0,
14, 0, 0, 0, 11, 0, 0, 0,
0, 0, 1, 0, 14, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
117, 2, 0, 0, 82, 0, 0, 0,
33, 2, 0, 0, 82, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
116, 2, 0, 0, 3, 0, 1, 0,
128, 2, 0, 0, 2, 0, 1, 0,
32, 2, 0, 0, 3, 0, 1, 0,
44, 2, 0, 0, 2, 0, 1, 0,
15, 0, 0, 0, 1, 0, 0, 0,
0, 0, 1, 0, 15, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
125, 2, 0, 0, 66, 0, 0, 0,
41, 2, 0, 0, 66, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
120, 2, 0, 0, 3, 0, 1, 0,
148, 2, 0, 0, 2, 0, 1, 0,
36, 2, 0, 0, 3, 0, 1, 0,
64, 2, 0, 0, 2, 0, 1, 0,
16, 0, 0, 0, 2, 0, 0, 0,
0, 0, 1, 0, 16, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
145, 2, 0, 0, 34, 0, 0, 0,
61, 2, 0, 0, 34, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
140, 2, 0, 0, 3, 0, 1, 0,
152, 2, 0, 0, 2, 0, 1, 0,
17, 0, 0, 0, 9, 0, 0, 0,
0, 0, 1, 0, 17, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
149, 2, 0, 0, 58, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
144, 2, 0, 0, 3, 0, 1, 0,
156, 2, 0, 0, 2, 0, 1, 0,
18, 0, 0, 0, 10, 0, 0, 0,
0, 0, 1, 0, 18, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
153, 2, 0, 0, 90, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
152, 2, 0, 0, 3, 0, 1, 0,
164, 2, 0, 0, 2, 0, 1, 0,
19, 0, 0, 0, 11, 0, 0, 0,
0, 0, 1, 0, 19, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
161, 2, 0, 0, 98, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
160, 2, 0, 0, 3, 0, 1, 0,
172, 2, 0, 0, 2, 0, 1, 0,
56, 2, 0, 0, 3, 0, 1, 0,
68, 2, 0, 0, 2, 0, 1, 0,
112, 105, 100, 0, 0, 0, 0, 0,
4, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
@@ -17320,42 +17294,16 @@ static const ::capnp::_::AlignedData<332> b_b0b85613f19e6d28 = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
12, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
109, 101, 109, 80, 115, 115, 0, 0,
9, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
9, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
109, 101, 109, 80, 115, 115, 65, 110,
111, 110, 0, 0, 0, 0, 0, 0,
9, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
9, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
109, 101, 109, 80, 115, 115, 83, 104,
109, 101, 109, 0, 0, 0, 0, 0,
9, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
9, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, }
};
::capnp::word const* const bp_b0b85613f19e6d28 = b_b0b85613f19e6d28.words;
#if !CAPNP_LITE
static const uint16_t m_b0b85613f19e6d28[] = {15, 7, 6, 5, 4, 16, 17, 18, 19, 13, 12, 1, 9, 10, 0, 3, 8, 14, 11, 2};
static const uint16_t i_b0b85613f19e6d28[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
static const uint16_t m_b0b85613f19e6d28[] = {15, 7, 6, 5, 4, 16, 13, 12, 1, 9, 10, 0, 3, 8, 14, 11, 2};
static const uint16_t i_b0b85613f19e6d28[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
const ::capnp::_::RawSchema s_b0b85613f19e6d28 = {
0xb0b85613f19e6d28, b_b0b85613f19e6d28.words, 332, nullptr, m_b0b85613f19e6d28,
0, 20, i_b0b85613f19e6d28, nullptr, nullptr, { &s_b0b85613f19e6d28, nullptr, nullptr, 0, 0, nullptr }, false
0xb0b85613f19e6d28, b_b0b85613f19e6d28.words, 285, nullptr, m_b0b85613f19e6d28,
0, 17, i_b0b85613f19e6d28, nullptr, nullptr, { &s_b0b85613f19e6d28, nullptr, nullptr, 0, 0, nullptr }, false
};
#endif // !CAPNP_LITE
static const ::capnp::_::AlignedData<138> b_f189c8c5bf2ce087 = {
@@ -30606,7 +30554,7 @@ const ::capnp::_::RawSchema s_8795cd2944faeab6 = {
0, 5, i_8795cd2944faeab6, nullptr, nullptr, { &s_8795cd2944faeab6, nullptr, nullptr, 0, 0, nullptr }, false
};
#endif // !CAPNP_LITE
static const ::capnp::_::AlignedData<2560> b_d314cfd957229c11 = {
static const ::capnp::_::AlignedData<2555> b_d314cfd957229c11 = {
{ 0, 0, 0, 0, 5, 0, 6, 0,
17, 156, 34, 87, 217, 207, 20, 211,
10, 0, 0, 0, 1, 0, 2, 0,
@@ -31627,52 +31575,52 @@ static const ::capnp::_::AlignedData<2560> b_d314cfd957229c11 = {
101, 0, 114, 255, 0, 0, 0, 0,
0, 0, 1, 0, 143, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
5, 23, 0, 0, 138, 0, 0, 0,
5, 23, 0, 0, 130, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
8, 23, 0, 0, 3, 0, 1, 0,
20, 23, 0, 0, 2, 0, 1, 0,
4, 23, 0, 0, 3, 0, 1, 0,
16, 23, 0, 0, 2, 0, 1, 0,
102, 0, 113, 255, 0, 0, 0, 0,
0, 0, 1, 0, 144, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
17, 23, 0, 0, 138, 0, 0, 0,
13, 23, 0, 0, 58, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
20, 23, 0, 0, 3, 0, 1, 0,
32, 23, 0, 0, 2, 0, 1, 0,
8, 23, 0, 0, 3, 0, 1, 0,
20, 23, 0, 0, 2, 0, 1, 0,
103, 0, 112, 255, 0, 0, 0, 0,
0, 0, 1, 0, 145, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
29, 23, 0, 0, 138, 0, 0, 0,
17, 23, 0, 0, 66, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
32, 23, 0, 0, 3, 0, 1, 0,
44, 23, 0, 0, 2, 0, 1, 0,
12, 23, 0, 0, 3, 0, 1, 0,
24, 23, 0, 0, 2, 0, 1, 0,
33, 0, 111, 255, 0, 0, 0, 0,
0, 0, 1, 0, 146, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
41, 23, 0, 0, 82, 0, 0, 0,
21, 23, 0, 0, 82, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
40, 23, 0, 0, 3, 0, 1, 0,
52, 23, 0, 0, 2, 0, 1, 0,
20, 23, 0, 0, 3, 0, 1, 0,
32, 23, 0, 0, 2, 0, 1, 0,
54, 0, 110, 255, 0, 0, 0, 0,
0, 0, 1, 0, 147, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
49, 23, 0, 0, 106, 0, 0, 0,
29, 23, 0, 0, 106, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
48, 23, 0, 0, 3, 0, 1, 0,
60, 23, 0, 0, 2, 0, 1, 0,
28, 23, 0, 0, 3, 0, 1, 0,
40, 23, 0, 0, 2, 0, 1, 0,
70, 0, 109, 255, 0, 0, 0, 0,
0, 0, 1, 0, 148, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
57, 23, 0, 0, 122, 0, 0, 0,
37, 23, 0, 0, 122, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
56, 23, 0, 0, 3, 0, 1, 0,
68, 23, 0, 0, 2, 0, 1, 0,
36, 23, 0, 0, 3, 0, 1, 0,
48, 23, 0, 0, 2, 0, 1, 0,
71, 0, 108, 255, 0, 0, 0, 0,
0, 0, 1, 0, 149, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
65, 23, 0, 0, 114, 0, 0, 0,
45, 23, 0, 0, 114, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
64, 23, 0, 0, 3, 0, 1, 0,
76, 23, 0, 0, 2, 0, 1, 0,
44, 23, 0, 0, 3, 0, 1, 0,
56, 23, 0, 0, 2, 0, 1, 0,
108, 111, 103, 77, 111, 110, 111, 84,
105, 109, 101, 0, 0, 0, 0, 0,
9, 0, 0, 0, 0, 0, 0, 0,
@@ -33101,9 +33049,8 @@ static const ::capnp::_::AlignedData<2560> b_d314cfd957229c11 = {
16, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
99, 117, 115, 116, 111, 109, 82, 101,
115, 101, 114, 118, 101, 100, 49, 55,
0, 0, 0, 0, 0, 0, 0, 0,
109, 97, 112, 100, 69, 120, 116, 101,
110, 100, 101, 100, 79, 117, 116, 0,
16, 0, 0, 0, 0, 0, 0, 0,
108, 3, 51, 64, 248, 98, 6, 163,
0, 0, 0, 0, 0, 0, 0, 0,
@@ -33111,9 +33058,7 @@ static const ::capnp::_::AlignedData<2560> b_d314cfd957229c11 = {
16, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
99, 117, 115, 116, 111, 109, 82, 101,
115, 101, 114, 118, 101, 100, 49, 56,
0, 0, 0, 0, 0, 0, 0, 0,
109, 97, 112, 100, 73, 110, 0, 0,
16, 0, 0, 0, 0, 0, 0, 0,
239, 179, 62, 209, 56, 61, 106, 200,
0, 0, 0, 0, 0, 0, 0, 0,
@@ -33121,9 +33066,7 @@ static const ::capnp::_::AlignedData<2560> b_d314cfd957229c11 = {
16, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
99, 117, 115, 116, 111, 109, 82, 101,
115, 101, 114, 118, 101, 100, 49, 57,
0, 0, 0, 0, 0, 0, 0, 0,
109, 97, 112, 100, 79, 117, 116, 0,
16, 0, 0, 0, 0, 0, 0, 0,
130, 245, 245, 35, 51, 235, 241, 164,
0, 0, 0, 0, 0, 0, 0, 0,
@@ -33280,10 +33223,10 @@ static const ::capnp::_::RawSchema* const d_d314cfd957229c11[] = {
&s_fe346a9de48d9b50,
&s_fe35ad896ffaeacf,
};
static const uint16_t m_d314cfd957229c11[] = {98, 101, 133, 30, 20, 55, 42, 149, 113, 148, 60, 63, 5, 23, 112, 127, 69, 111, 22, 114, 28, 35, 7, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 124, 125, 126, 6, 132, 70, 87, 76, 71, 59, 92, 128, 85, 26, 10, 91, 21, 48, 3, 41, 40, 99, 100, 1, 65, 64, 32, 96, 19, 146, 8, 46, 25, 72, 51, 44, 37, 62, 115, 36, 61, 129, 94, 131, 16, 14, 122, 119, 120, 117, 121, 118, 49, 18, 0, 24, 109, 95, 78, 105, 9, 116, 108, 75, 82, 104, 83, 38, 84, 27, 134, 68, 110, 54, 58, 56, 47, 53, 45, 12, 81, 80, 33, 89, 90, 31, 13, 147, 2, 86, 15, 130, 107, 17, 4, 11, 73, 103, 97, 123, 52, 66, 135, 43, 34, 39, 102, 57, 50, 106, 79, 93, 67, 74, 88, 77, 29};
static const uint16_t m_d314cfd957229c11[] = {98, 101, 133, 30, 20, 55, 42, 149, 113, 148, 60, 63, 5, 23, 112, 127, 69, 111, 22, 114, 28, 35, 7, 136, 137, 138, 139, 140, 141, 142, 124, 125, 126, 6, 132, 70, 87, 76, 71, 59, 92, 128, 85, 26, 10, 91, 21, 48, 3, 41, 40, 99, 100, 1, 65, 64, 32, 96, 19, 146, 8, 46, 25, 72, 51, 44, 37, 62, 115, 36, 61, 129, 94, 131, 16, 14, 122, 119, 120, 117, 121, 118, 49, 18, 0, 24, 109, 95, 78, 105, 143, 144, 145, 9, 116, 108, 75, 82, 104, 83, 38, 84, 27, 134, 68, 110, 54, 58, 56, 47, 53, 45, 12, 81, 80, 33, 89, 90, 31, 13, 147, 2, 86, 15, 130, 107, 17, 4, 11, 73, 103, 97, 123, 52, 66, 135, 43, 34, 39, 102, 57, 50, 106, 79, 93, 67, 74, 88, 77, 29};
static const uint16_t i_d314cfd957229c11[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 0, 67};
const ::capnp::_::RawSchema s_d314cfd957229c11 = {
0xd314cfd957229c11, b_d314cfd957229c11.words, 2560, d_d314cfd957229c11, m_d314cfd957229c11,
0xd314cfd957229c11, b_d314cfd957229c11.words, 2555, d_d314cfd957229c11, m_d314cfd957229c11,
108, 150, i_d314cfd957229c11, nullptr, nullptr, { &s_d314cfd957229c11, nullptr, nullptr, 0, 0, nullptr }, true
};
#endif // !CAPNP_LITE
+115 -173
View File
@@ -125,7 +125,6 @@ enum class EventName_91f1992a1f77fb03: uint16_t {
USER_BOOKMARK,
EXCESSIVE_ACTUATION,
AUDIO_FEEDBACK,
STOCK_LKAS,
};
CAPNP_DECLARE_ENUM(EventName, 91f1992a1f77fb03);
CAPNP_DECLARE_SCHEMA(d692e23d1a247d99);
@@ -1766,7 +1765,7 @@ struct ProcLog::Process {
class Pipeline;
struct _capnpPrivate {
CAPNP_DECLARE_STRUCT_HEADER(b0b85613f19e6d28, 12, 3)
CAPNP_DECLARE_STRUCT_HEADER(b0b85613f19e6d28, 9, 3)
#if !CAPNP_LITE
static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
#endif // !CAPNP_LITE
@@ -2904,9 +2903,9 @@ struct Event {
CUSTOM_RESERVED14,
CUSTOM_RESERVED15,
CUSTOM_RESERVED16,
CUSTOM_RESERVED17,
CUSTOM_RESERVED18,
CUSTOM_RESERVED19,
MAPD_EXTENDED_OUT,
MAPD_IN,
MAPD_OUT,
LIVE_DELAY,
RAW_AUDIO_DATA,
BOOKMARK_BUTTON,
@@ -12817,12 +12816,6 @@ public:
inline bool hasExe() const;
inline ::capnp::Text::Reader getExe() const;
inline ::uint64_t getMemPss() const;
inline ::uint64_t getMemPssAnon() const;
inline ::uint64_t getMemPssShmem() const;
private:
::capnp::_::StructReader _reader;
template <typename, ::capnp::Kind>
@@ -12915,15 +12908,6 @@ public:
inline void adoptExe(::capnp::Orphan< ::capnp::Text>&& value);
inline ::capnp::Orphan< ::capnp::Text> disownExe();
inline ::uint64_t getMemPss();
inline void setMemPss( ::uint64_t value);
inline ::uint64_t getMemPssAnon();
inline void setMemPssAnon( ::uint64_t value);
inline ::uint64_t getMemPssShmem();
inline void setMemPssShmem( ::uint64_t value);
private:
::capnp::_::StructBuilder _builder;
template <typename, ::capnp::Kind>
@@ -21752,17 +21736,17 @@ public:
inline bool hasCustomReserved16() const;
inline ::cereal::CustomReserved16::Reader getCustomReserved16() const;
inline bool isCustomReserved17() const;
inline bool hasCustomReserved17() const;
inline ::cereal::CustomReserved17::Reader getCustomReserved17() const;
inline bool isMapdExtendedOut() const;
inline bool hasMapdExtendedOut() const;
inline ::cereal::MapdExtendedOut::Reader getMapdExtendedOut() const;
inline bool isCustomReserved18() const;
inline bool hasCustomReserved18() const;
inline ::cereal::CustomReserved18::Reader getCustomReserved18() const;
inline bool isMapdIn() const;
inline bool hasMapdIn() const;
inline ::cereal::MapdIn::Reader getMapdIn() const;
inline bool isCustomReserved19() const;
inline bool hasCustomReserved19() const;
inline ::cereal::CustomReserved19::Reader getCustomReserved19() const;
inline bool isMapdOut() const;
inline bool hasMapdOut() const;
inline ::cereal::MapdOut::Reader getMapdOut() const;
inline bool isLiveDelay() const;
inline bool hasLiveDelay() const;
@@ -22943,29 +22927,29 @@ public:
inline void adoptCustomReserved16(::capnp::Orphan< ::cereal::CustomReserved16>&& value);
inline ::capnp::Orphan< ::cereal::CustomReserved16> disownCustomReserved16();
inline bool isCustomReserved17();
inline bool hasCustomReserved17();
inline ::cereal::CustomReserved17::Builder getCustomReserved17();
inline void setCustomReserved17( ::cereal::CustomReserved17::Reader value);
inline ::cereal::CustomReserved17::Builder initCustomReserved17();
inline void adoptCustomReserved17(::capnp::Orphan< ::cereal::CustomReserved17>&& value);
inline ::capnp::Orphan< ::cereal::CustomReserved17> disownCustomReserved17();
inline bool isMapdExtendedOut();
inline bool hasMapdExtendedOut();
inline ::cereal::MapdExtendedOut::Builder getMapdExtendedOut();
inline void setMapdExtendedOut( ::cereal::MapdExtendedOut::Reader value);
inline ::cereal::MapdExtendedOut::Builder initMapdExtendedOut();
inline void adoptMapdExtendedOut(::capnp::Orphan< ::cereal::MapdExtendedOut>&& value);
inline ::capnp::Orphan< ::cereal::MapdExtendedOut> disownMapdExtendedOut();
inline bool isCustomReserved18();
inline bool hasCustomReserved18();
inline ::cereal::CustomReserved18::Builder getCustomReserved18();
inline void setCustomReserved18( ::cereal::CustomReserved18::Reader value);
inline ::cereal::CustomReserved18::Builder initCustomReserved18();
inline void adoptCustomReserved18(::capnp::Orphan< ::cereal::CustomReserved18>&& value);
inline ::capnp::Orphan< ::cereal::CustomReserved18> disownCustomReserved18();
inline bool isMapdIn();
inline bool hasMapdIn();
inline ::cereal::MapdIn::Builder getMapdIn();
inline void setMapdIn( ::cereal::MapdIn::Reader value);
inline ::cereal::MapdIn::Builder initMapdIn();
inline void adoptMapdIn(::capnp::Orphan< ::cereal::MapdIn>&& value);
inline ::capnp::Orphan< ::cereal::MapdIn> disownMapdIn();
inline bool isCustomReserved19();
inline bool hasCustomReserved19();
inline ::cereal::CustomReserved19::Builder getCustomReserved19();
inline void setCustomReserved19( ::cereal::CustomReserved19::Reader value);
inline ::cereal::CustomReserved19::Builder initCustomReserved19();
inline void adoptCustomReserved19(::capnp::Orphan< ::cereal::CustomReserved19>&& value);
inline ::capnp::Orphan< ::cereal::CustomReserved19> disownCustomReserved19();
inline bool isMapdOut();
inline bool hasMapdOut();
inline ::cereal::MapdOut::Builder getMapdOut();
inline void setMapdOut( ::cereal::MapdOut::Reader value);
inline ::cereal::MapdOut::Builder initMapdOut();
inline void adoptMapdOut(::capnp::Orphan< ::cereal::MapdOut>&& value);
inline ::capnp::Orphan< ::cereal::MapdOut> disownMapdOut();
inline bool isLiveDelay();
inline bool hasLiveDelay();
@@ -39718,48 +39702,6 @@ inline ::capnp::Orphan< ::capnp::Text> ProcLog::Process::Builder::disownExe() {
::capnp::bounded<2>() * ::capnp::POINTERS));
}
inline ::uint64_t ProcLog::Process::Reader::getMemPss() const {
return _reader.getDataField< ::uint64_t>(
::capnp::bounded<9>() * ::capnp::ELEMENTS);
}
inline ::uint64_t ProcLog::Process::Builder::getMemPss() {
return _builder.getDataField< ::uint64_t>(
::capnp::bounded<9>() * ::capnp::ELEMENTS);
}
inline void ProcLog::Process::Builder::setMemPss( ::uint64_t value) {
_builder.setDataField< ::uint64_t>(
::capnp::bounded<9>() * ::capnp::ELEMENTS, value);
}
inline ::uint64_t ProcLog::Process::Reader::getMemPssAnon() const {
return _reader.getDataField< ::uint64_t>(
::capnp::bounded<10>() * ::capnp::ELEMENTS);
}
inline ::uint64_t ProcLog::Process::Builder::getMemPssAnon() {
return _builder.getDataField< ::uint64_t>(
::capnp::bounded<10>() * ::capnp::ELEMENTS);
}
inline void ProcLog::Process::Builder::setMemPssAnon( ::uint64_t value) {
_builder.setDataField< ::uint64_t>(
::capnp::bounded<10>() * ::capnp::ELEMENTS, value);
}
inline ::uint64_t ProcLog::Process::Reader::getMemPssShmem() const {
return _reader.getDataField< ::uint64_t>(
::capnp::bounded<11>() * ::capnp::ELEMENTS);
}
inline ::uint64_t ProcLog::Process::Builder::getMemPssShmem() {
return _builder.getDataField< ::uint64_t>(
::capnp::bounded<11>() * ::capnp::ELEMENTS);
}
inline void ProcLog::Process::Builder::setMemPssShmem( ::uint64_t value) {
_builder.setDataField< ::uint64_t>(
::capnp::bounded<11>() * ::capnp::ELEMENTS, value);
}
inline ::int64_t ProcLog::CPUTimes::Reader::getCpuNum() const {
return _reader.getDataField< ::int64_t>(
::capnp::bounded<0>() * ::capnp::ELEMENTS);
@@ -59294,165 +59236,165 @@ inline ::capnp::Orphan< ::cereal::CustomReserved16> Event::Builder::disownCustom
::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline bool Event::Reader::isCustomReserved17() const {
return which() == Event::CUSTOM_RESERVED17;
inline bool Event::Reader::isMapdExtendedOut() const {
return which() == Event::MAPD_EXTENDED_OUT;
}
inline bool Event::Builder::isCustomReserved17() {
return which() == Event::CUSTOM_RESERVED17;
inline bool Event::Builder::isMapdExtendedOut() {
return which() == Event::MAPD_EXTENDED_OUT;
}
inline bool Event::Reader::hasCustomReserved17() const {
if (which() != Event::CUSTOM_RESERVED17) return false;
inline bool Event::Reader::hasMapdExtendedOut() const {
if (which() != Event::MAPD_EXTENDED_OUT) return false;
return !_reader.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Event::Builder::hasCustomReserved17() {
if (which() != Event::CUSTOM_RESERVED17) return false;
inline bool Event::Builder::hasMapdExtendedOut() {
if (which() != Event::MAPD_EXTENDED_OUT) return false;
return !_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline ::cereal::CustomReserved17::Reader Event::Reader::getCustomReserved17() const {
KJ_IREQUIRE((which() == Event::CUSTOM_RESERVED17),
inline ::cereal::MapdExtendedOut::Reader Event::Reader::getMapdExtendedOut() const {
KJ_IREQUIRE((which() == Event::MAPD_EXTENDED_OUT),
"Must check which() before get()ing a union member.");
return ::capnp::_::PointerHelpers< ::cereal::CustomReserved17>::get(_reader.getPointerField(
return ::capnp::_::PointerHelpers< ::cereal::MapdExtendedOut>::get(_reader.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline ::cereal::CustomReserved17::Builder Event::Builder::getCustomReserved17() {
KJ_IREQUIRE((which() == Event::CUSTOM_RESERVED17),
inline ::cereal::MapdExtendedOut::Builder Event::Builder::getMapdExtendedOut() {
KJ_IREQUIRE((which() == Event::MAPD_EXTENDED_OUT),
"Must check which() before get()ing a union member.");
return ::capnp::_::PointerHelpers< ::cereal::CustomReserved17>::get(_builder.getPointerField(
return ::capnp::_::PointerHelpers< ::cereal::MapdExtendedOut>::get(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Event::Builder::setCustomReserved17( ::cereal::CustomReserved17::Reader value) {
inline void Event::Builder::setMapdExtendedOut( ::cereal::MapdExtendedOut::Reader value) {
_builder.setDataField<Event::Which>(
::capnp::bounded<4>() * ::capnp::ELEMENTS, Event::CUSTOM_RESERVED17);
::capnp::_::PointerHelpers< ::cereal::CustomReserved17>::set(_builder.getPointerField(
::capnp::bounded<4>() * ::capnp::ELEMENTS, Event::MAPD_EXTENDED_OUT);
::capnp::_::PointerHelpers< ::cereal::MapdExtendedOut>::set(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline ::cereal::CustomReserved17::Builder Event::Builder::initCustomReserved17() {
inline ::cereal::MapdExtendedOut::Builder Event::Builder::initMapdExtendedOut() {
_builder.setDataField<Event::Which>(
::capnp::bounded<4>() * ::capnp::ELEMENTS, Event::CUSTOM_RESERVED17);
return ::capnp::_::PointerHelpers< ::cereal::CustomReserved17>::init(_builder.getPointerField(
::capnp::bounded<4>() * ::capnp::ELEMENTS, Event::MAPD_EXTENDED_OUT);
return ::capnp::_::PointerHelpers< ::cereal::MapdExtendedOut>::init(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Event::Builder::adoptCustomReserved17(
::capnp::Orphan< ::cereal::CustomReserved17>&& value) {
inline void Event::Builder::adoptMapdExtendedOut(
::capnp::Orphan< ::cereal::MapdExtendedOut>&& value) {
_builder.setDataField<Event::Which>(
::capnp::bounded<4>() * ::capnp::ELEMENTS, Event::CUSTOM_RESERVED17);
::capnp::_::PointerHelpers< ::cereal::CustomReserved17>::adopt(_builder.getPointerField(
::capnp::bounded<4>() * ::capnp::ELEMENTS, Event::MAPD_EXTENDED_OUT);
::capnp::_::PointerHelpers< ::cereal::MapdExtendedOut>::adopt(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::cereal::CustomReserved17> Event::Builder::disownCustomReserved17() {
KJ_IREQUIRE((which() == Event::CUSTOM_RESERVED17),
inline ::capnp::Orphan< ::cereal::MapdExtendedOut> Event::Builder::disownMapdExtendedOut() {
KJ_IREQUIRE((which() == Event::MAPD_EXTENDED_OUT),
"Must check which() before get()ing a union member.");
return ::capnp::_::PointerHelpers< ::cereal::CustomReserved17>::disown(_builder.getPointerField(
return ::capnp::_::PointerHelpers< ::cereal::MapdExtendedOut>::disown(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline bool Event::Reader::isCustomReserved18() const {
return which() == Event::CUSTOM_RESERVED18;
inline bool Event::Reader::isMapdIn() const {
return which() == Event::MAPD_IN;
}
inline bool Event::Builder::isCustomReserved18() {
return which() == Event::CUSTOM_RESERVED18;
inline bool Event::Builder::isMapdIn() {
return which() == Event::MAPD_IN;
}
inline bool Event::Reader::hasCustomReserved18() const {
if (which() != Event::CUSTOM_RESERVED18) return false;
inline bool Event::Reader::hasMapdIn() const {
if (which() != Event::MAPD_IN) return false;
return !_reader.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Event::Builder::hasCustomReserved18() {
if (which() != Event::CUSTOM_RESERVED18) return false;
inline bool Event::Builder::hasMapdIn() {
if (which() != Event::MAPD_IN) return false;
return !_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline ::cereal::CustomReserved18::Reader Event::Reader::getCustomReserved18() const {
KJ_IREQUIRE((which() == Event::CUSTOM_RESERVED18),
inline ::cereal::MapdIn::Reader Event::Reader::getMapdIn() const {
KJ_IREQUIRE((which() == Event::MAPD_IN),
"Must check which() before get()ing a union member.");
return ::capnp::_::PointerHelpers< ::cereal::CustomReserved18>::get(_reader.getPointerField(
return ::capnp::_::PointerHelpers< ::cereal::MapdIn>::get(_reader.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline ::cereal::CustomReserved18::Builder Event::Builder::getCustomReserved18() {
KJ_IREQUIRE((which() == Event::CUSTOM_RESERVED18),
inline ::cereal::MapdIn::Builder Event::Builder::getMapdIn() {
KJ_IREQUIRE((which() == Event::MAPD_IN),
"Must check which() before get()ing a union member.");
return ::capnp::_::PointerHelpers< ::cereal::CustomReserved18>::get(_builder.getPointerField(
return ::capnp::_::PointerHelpers< ::cereal::MapdIn>::get(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Event::Builder::setCustomReserved18( ::cereal::CustomReserved18::Reader value) {
inline void Event::Builder::setMapdIn( ::cereal::MapdIn::Reader value) {
_builder.setDataField<Event::Which>(
::capnp::bounded<4>() * ::capnp::ELEMENTS, Event::CUSTOM_RESERVED18);
::capnp::_::PointerHelpers< ::cereal::CustomReserved18>::set(_builder.getPointerField(
::capnp::bounded<4>() * ::capnp::ELEMENTS, Event::MAPD_IN);
::capnp::_::PointerHelpers< ::cereal::MapdIn>::set(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline ::cereal::CustomReserved18::Builder Event::Builder::initCustomReserved18() {
inline ::cereal::MapdIn::Builder Event::Builder::initMapdIn() {
_builder.setDataField<Event::Which>(
::capnp::bounded<4>() * ::capnp::ELEMENTS, Event::CUSTOM_RESERVED18);
return ::capnp::_::PointerHelpers< ::cereal::CustomReserved18>::init(_builder.getPointerField(
::capnp::bounded<4>() * ::capnp::ELEMENTS, Event::MAPD_IN);
return ::capnp::_::PointerHelpers< ::cereal::MapdIn>::init(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Event::Builder::adoptCustomReserved18(
::capnp::Orphan< ::cereal::CustomReserved18>&& value) {
inline void Event::Builder::adoptMapdIn(
::capnp::Orphan< ::cereal::MapdIn>&& value) {
_builder.setDataField<Event::Which>(
::capnp::bounded<4>() * ::capnp::ELEMENTS, Event::CUSTOM_RESERVED18);
::capnp::_::PointerHelpers< ::cereal::CustomReserved18>::adopt(_builder.getPointerField(
::capnp::bounded<4>() * ::capnp::ELEMENTS, Event::MAPD_IN);
::capnp::_::PointerHelpers< ::cereal::MapdIn>::adopt(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::cereal::CustomReserved18> Event::Builder::disownCustomReserved18() {
KJ_IREQUIRE((which() == Event::CUSTOM_RESERVED18),
inline ::capnp::Orphan< ::cereal::MapdIn> Event::Builder::disownMapdIn() {
KJ_IREQUIRE((which() == Event::MAPD_IN),
"Must check which() before get()ing a union member.");
return ::capnp::_::PointerHelpers< ::cereal::CustomReserved18>::disown(_builder.getPointerField(
return ::capnp::_::PointerHelpers< ::cereal::MapdIn>::disown(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline bool Event::Reader::isCustomReserved19() const {
return which() == Event::CUSTOM_RESERVED19;
inline bool Event::Reader::isMapdOut() const {
return which() == Event::MAPD_OUT;
}
inline bool Event::Builder::isCustomReserved19() {
return which() == Event::CUSTOM_RESERVED19;
inline bool Event::Builder::isMapdOut() {
return which() == Event::MAPD_OUT;
}
inline bool Event::Reader::hasCustomReserved19() const {
if (which() != Event::CUSTOM_RESERVED19) return false;
inline bool Event::Reader::hasMapdOut() const {
if (which() != Event::MAPD_OUT) return false;
return !_reader.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Event::Builder::hasCustomReserved19() {
if (which() != Event::CUSTOM_RESERVED19) return false;
inline bool Event::Builder::hasMapdOut() {
if (which() != Event::MAPD_OUT) return false;
return !_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline ::cereal::CustomReserved19::Reader Event::Reader::getCustomReserved19() const {
KJ_IREQUIRE((which() == Event::CUSTOM_RESERVED19),
inline ::cereal::MapdOut::Reader Event::Reader::getMapdOut() const {
KJ_IREQUIRE((which() == Event::MAPD_OUT),
"Must check which() before get()ing a union member.");
return ::capnp::_::PointerHelpers< ::cereal::CustomReserved19>::get(_reader.getPointerField(
return ::capnp::_::PointerHelpers< ::cereal::MapdOut>::get(_reader.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline ::cereal::CustomReserved19::Builder Event::Builder::getCustomReserved19() {
KJ_IREQUIRE((which() == Event::CUSTOM_RESERVED19),
inline ::cereal::MapdOut::Builder Event::Builder::getMapdOut() {
KJ_IREQUIRE((which() == Event::MAPD_OUT),
"Must check which() before get()ing a union member.");
return ::capnp::_::PointerHelpers< ::cereal::CustomReserved19>::get(_builder.getPointerField(
return ::capnp::_::PointerHelpers< ::cereal::MapdOut>::get(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Event::Builder::setCustomReserved19( ::cereal::CustomReserved19::Reader value) {
inline void Event::Builder::setMapdOut( ::cereal::MapdOut::Reader value) {
_builder.setDataField<Event::Which>(
::capnp::bounded<4>() * ::capnp::ELEMENTS, Event::CUSTOM_RESERVED19);
::capnp::_::PointerHelpers< ::cereal::CustomReserved19>::set(_builder.getPointerField(
::capnp::bounded<4>() * ::capnp::ELEMENTS, Event::MAPD_OUT);
::capnp::_::PointerHelpers< ::cereal::MapdOut>::set(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline ::cereal::CustomReserved19::Builder Event::Builder::initCustomReserved19() {
inline ::cereal::MapdOut::Builder Event::Builder::initMapdOut() {
_builder.setDataField<Event::Which>(
::capnp::bounded<4>() * ::capnp::ELEMENTS, Event::CUSTOM_RESERVED19);
return ::capnp::_::PointerHelpers< ::cereal::CustomReserved19>::init(_builder.getPointerField(
::capnp::bounded<4>() * ::capnp::ELEMENTS, Event::MAPD_OUT);
return ::capnp::_::PointerHelpers< ::cereal::MapdOut>::init(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Event::Builder::adoptCustomReserved19(
::capnp::Orphan< ::cereal::CustomReserved19>&& value) {
inline void Event::Builder::adoptMapdOut(
::capnp::Orphan< ::cereal::MapdOut>&& value) {
_builder.setDataField<Event::Which>(
::capnp::bounded<4>() * ::capnp::ELEMENTS, Event::CUSTOM_RESERVED19);
::capnp::_::PointerHelpers< ::cereal::CustomReserved19>::adopt(_builder.getPointerField(
::capnp::bounded<4>() * ::capnp::ELEMENTS, Event::MAPD_OUT);
::capnp::_::PointerHelpers< ::cereal::MapdOut>::adopt(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::cereal::CustomReserved19> Event::Builder::disownCustomReserved19() {
KJ_IREQUIRE((which() == Event::CUSTOM_RESERVED19),
inline ::capnp::Orphan< ::cereal::MapdOut> Event::Builder::disownMapdOut() {
KJ_IREQUIRE((which() == Event::MAPD_OUT),
"Must check which() before get()ing a union member.");
return ::capnp::_::PointerHelpers< ::cereal::CustomReserved19>::disown(_builder.getPointerField(
return ::capnp::_::PointerHelpers< ::cereal::MapdOut>::disown(_builder.getPointerField(
::capnp::bounded<0>() * ::capnp::POINTERS));
}
+3 -9
View File
@@ -87,7 +87,6 @@ struct OnroadEvent @0xc4fa6047f024e718 {
laneChange @50;
lowMemory @51;
stockAeb @52;
stockLkas @98;
ldw @53;
carUnrecognized @54;
invalidLkasSetting @55;
@@ -1478,11 +1477,6 @@ struct ProcLog {
cmdline @15 :List(Text);
exe @16 :Text;
# from /proc/<pid>/smaps_rollup (proportional/private memory)
memPss @17 :UInt64; # Pss — shared pages split by mapper count
memPssAnon @18 :UInt64; # Pss_Anon — private anonymous (heap, stack)
memPssShmem @19 :UInt64; # Pss_Shmem — proportional MSGQ/tmpfs share
}
struct CPUTimes {
@@ -2648,9 +2642,9 @@ struct Event {
customReserved14 @140 :Custom.CustomReserved14;
customReserved15 @141 :Custom.CustomReserved15;
customReserved16 @142 :Custom.CustomReserved16;
customReserved17 @143 :Custom.CustomReserved17;
customReserved18 @144 :Custom.CustomReserved18;
customReserved19 @145 :Custom.CustomReserved19;
mapdExtendedOut @143 :Custom.MapdExtendedOut;
mapdIn @144 :Custom.MapdIn;
mapdOut @145 :Custom.MapdOut;
# *********** legacy + deprecated ***********
model @9 :Legacy.ModelData; # TODO: rename modelV2 and mark this as deprecated
+6 -4
View File
@@ -1,8 +1,10 @@
# must be built with scons
from msgq import fake_event_handle, drain_sock_raw, MultiplePublishersError, IpcError, \
Context, Poller, SubSocket, PubSocket, SocketEventHandle, toggle_fake_events, \
set_fake_prefix, get_fake_prefix, delete_fake_prefix, wait_for_one_event
from msgq.ipc_pyx import Context, Poller, SubSocket, PubSocket, SocketEventHandle, toggle_fake_events, \
set_fake_prefix, get_fake_prefix, delete_fake_prefix, wait_for_one_event
from msgq.ipc_pyx import MultiplePublishersError, IpcError
from msgq import fake_event_handle, drain_sock_raw
import msgq
import os
import capnp
import time
@@ -11,7 +13,7 @@ from typing import Optional, List, Union, Dict
from cereal import log
from cereal.services import SERVICE_LIST
from openpilot.common.utils import MovingAverage
from openpilot.common.util import MovingAverage
NO_TRAVERSAL_LIMIT = 2**64-1
Binary file not shown.
+7 -8
View File
@@ -25,16 +25,15 @@ void msgq_to_zmq(const std::vector<std::string> &endpoints, const std::string &i
}
void zmq_to_msgq(const std::vector<std::string> &endpoints, const std::string &ip) {
auto poller = std::make_unique<BridgeZmqPoller>();
auto pub_context = std::make_unique<Context>();
auto sub_context = std::make_unique<BridgeZmqContext>();
std::map<BridgeZmqSubSocket *, PubSocket *> sub2pub;
auto poller = std::make_unique<ZMQPoller>();
auto pub_context = std::make_unique<MSGQContext>();
auto sub_context = std::make_unique<ZMQContext>();
std::map<SubSocket *, PubSocket *> sub2pub;
for (auto endpoint : endpoints) {
auto pub_sock = new PubSocket();
auto sub_sock = new BridgeZmqSubSocket();
size_t queue_size = services.at(endpoint).queue_size;
pub_sock->connect(pub_context.get(), endpoint, true, queue_size);
auto pub_sock = new MSGQPubSocket();
auto sub_sock = new ZMQSubSocket();
pub_sock->connect(pub_context.get(), endpoint);
sub_sock->connect(sub_context.get(), endpoint, ip, false);
poller->registerSocket(sub_sock);
-170
View File
@@ -1,170 +0,0 @@
#include "cereal/messaging/bridge_zmq.h"
#include <cassert>
#include <cstring>
#include <unistd.h>
static size_t fnv1a_hash(const std::string &str) {
const size_t fnv_prime = 0x100000001b3;
size_t hash_value = 0xcbf29ce484222325;
for (char c : str) {
hash_value ^= (unsigned char)c;
hash_value *= fnv_prime;
}
return hash_value;
}
// FIXME: This is a hack to get the port number from the socket name, might have collisions.
static int get_port(std::string endpoint) {
size_t hash_value = fnv1a_hash(endpoint);
int start_port = 8023;
int max_port = 65535;
return start_port + (hash_value % (max_port - start_port));
}
BridgeZmqContext::BridgeZmqContext() {
context = zmq_ctx_new();
}
BridgeZmqContext::~BridgeZmqContext() {
if (context != nullptr) {
zmq_ctx_term(context);
}
}
void BridgeZmqMessage::init(size_t sz) {
size = sz;
data = new char[size];
}
void BridgeZmqMessage::init(char *d, size_t sz) {
size = sz;
data = new char[size];
memcpy(data, d, size);
}
void BridgeZmqMessage::close() {
if (size > 0) {
delete[] data;
}
data = nullptr;
size = 0;
}
BridgeZmqMessage::~BridgeZmqMessage() {
close();
}
int BridgeZmqSubSocket::connect(BridgeZmqContext *context, std::string endpoint, std::string address, bool conflate, bool check_endpoint) {
sock = zmq_socket(context->getRawContext(), ZMQ_SUB);
if (sock == nullptr) {
return -1;
}
zmq_setsockopt(sock, ZMQ_SUBSCRIBE, "", 0);
if (conflate) {
int arg = 1;
zmq_setsockopt(sock, ZMQ_CONFLATE, &arg, sizeof(int));
}
int reconnect_ivl = 500;
zmq_setsockopt(sock, ZMQ_RECONNECT_IVL_MAX, &reconnect_ivl, sizeof(reconnect_ivl));
full_endpoint = "tcp://" + address + ":";
if (check_endpoint) {
full_endpoint += std::to_string(get_port(endpoint));
} else {
full_endpoint += endpoint;
}
return zmq_connect(sock, full_endpoint.c_str());
}
void BridgeZmqSubSocket::setTimeout(int timeout) {
zmq_setsockopt(sock, ZMQ_RCVTIMEO, &timeout, sizeof(int));
}
Message *BridgeZmqSubSocket::receive(bool non_blocking) {
zmq_msg_t msg;
assert(zmq_msg_init(&msg) == 0);
int flags = non_blocking ? ZMQ_DONTWAIT : 0;
int rc = zmq_msg_recv(&msg, sock, flags);
Message *ret = nullptr;
if (rc >= 0) {
ret = new BridgeZmqMessage;
ret->init((char *)zmq_msg_data(&msg), zmq_msg_size(&msg));
}
zmq_msg_close(&msg);
return ret;
}
BridgeZmqSubSocket::~BridgeZmqSubSocket() {
if (sock != nullptr) {
zmq_close(sock);
}
}
int BridgeZmqPubSocket::connect(BridgeZmqContext *context, std::string endpoint, bool check_endpoint) {
sock = zmq_socket(context->getRawContext(), ZMQ_PUB);
if (sock == nullptr) {
return -1;
}
full_endpoint = "tcp://*:";
if (check_endpoint) {
full_endpoint += std::to_string(get_port(endpoint));
} else {
full_endpoint += endpoint;
}
// ZMQ pub sockets cannot be shared between processes, so we need to ensure pid stays the same.
pid = getpid();
return zmq_bind(sock, full_endpoint.c_str());
}
int BridgeZmqPubSocket::sendMessage(Message *message) {
assert(pid == getpid());
return zmq_send(sock, message->getData(), message->getSize(), ZMQ_DONTWAIT);
}
int BridgeZmqPubSocket::send(char *data, size_t size) {
assert(pid == getpid());
return zmq_send(sock, data, size, ZMQ_DONTWAIT);
}
BridgeZmqPubSocket::~BridgeZmqPubSocket() {
if (sock != nullptr) {
zmq_close(sock);
}
}
void BridgeZmqPoller::registerSocket(BridgeZmqSubSocket *socket) {
assert(num_polls + 1 < (sizeof(polls) / sizeof(polls[0])));
polls[num_polls].socket = socket->getRawSocket();
polls[num_polls].events = ZMQ_POLLIN;
sockets.push_back(socket);
num_polls++;
}
std::vector<BridgeZmqSubSocket *> BridgeZmqPoller::poll(int timeout) {
std::vector<BridgeZmqSubSocket *> ret;
int rc = zmq_poll(polls, num_polls, timeout);
if (rc < 0) {
return ret;
}
for (size_t i = 0; i < num_polls; i++) {
if (polls[i].revents) {
ret.push_back(sockets[i]);
}
}
return ret;
}
-72
View File
@@ -1,72 +0,0 @@
#pragma once
#include <cstddef>
#include <string>
#include <vector>
#include <zmq.h>
#include "msgq/ipc.h"
class BridgeZmqContext {
public:
BridgeZmqContext();
void *getRawContext() { return context; }
~BridgeZmqContext();
private:
void *context = nullptr;
};
class BridgeZmqMessage : public Message {
public:
void init(size_t size);
void init(char *data, size_t size);
void close();
size_t getSize() { return size; }
char *getData() { return data; }
~BridgeZmqMessage();
private:
char *data = nullptr;
size_t size = 0;
};
class BridgeZmqSubSocket {
public:
int connect(BridgeZmqContext *context, std::string endpoint, std::string address, bool conflate = false, bool check_endpoint = true);
void setTimeout(int timeout);
Message *receive(bool non_blocking = false);
void *getRawSocket() { return sock; }
~BridgeZmqSubSocket();
private:
void *sock = nullptr;
std::string full_endpoint;
};
class BridgeZmqPubSocket {
public:
int connect(BridgeZmqContext *context, std::string endpoint, bool check_endpoint = true);
int sendMessage(Message *message);
int send(char *data, size_t size);
void *getRawSocket() { return sock; }
~BridgeZmqPubSocket();
private:
void *sock = nullptr;
std::string full_endpoint;
int pid = -1;
};
class BridgeZmqPoller {
public:
void registerSocket(BridgeZmqSubSocket *socket);
std::vector<BridgeZmqSubSocket *> poll(int timeout);
private:
static constexpr size_t MAX_BRIDGE_ZMQ_POLLERS = 128;
std::vector<BridgeZmqSubSocket *> sockets;
zmq_pollitem_t polls[MAX_BRIDGE_ZMQ_POLLERS] = {};
size_t num_polls = 0;
};
+7 -9
View File
@@ -2,7 +2,6 @@
#include <cassert>
#include "cereal/services.h"
#include "common/util.h"
extern ExitHandler do_exit;
@@ -22,14 +21,14 @@ static std::string recv_zmq_msg(void *sock) {
}
void MsgqToZmq::run(const std::vector<std::string> &endpoints, const std::string &ip) {
zmq_context = std::make_unique<BridgeZmqContext>();
msgq_context = std::make_unique<Context>();
zmq_context = std::make_unique<ZMQContext>();
msgq_context = std::make_unique<MSGQContext>();
// Create ZMQPubSockets for each endpoint
for (const auto &endpoint : endpoints) {
auto &socket_pair = socket_pairs.emplace_back();
socket_pair.endpoint = endpoint;
socket_pair.pub_sock = std::make_unique<BridgeZmqPubSocket>();
socket_pair.pub_sock = std::make_unique<ZMQPubSocket>();
int ret = socket_pair.pub_sock->connect(zmq_context.get(), endpoint);
if (ret != 0) {
printf("Failed to create ZMQ publisher for [%s]: %s\n", endpoint.c_str(), zmq_strerror(zmq_errno()));
@@ -49,7 +48,7 @@ void MsgqToZmq::run(const std::vector<std::string> &endpoints, const std::string
for (auto sub_sock : msgq_poller->poll(100)) {
// Process messages for each socket
BridgeZmqPubSocket *pub_sock = sub2pub.at(sub_sock);
ZMQPubSocket *pub_sock = sub2pub.at(sub_sock);
for (int i = 0; i < MAX_MESSAGES_PER_SOCKET; ++i) {
auto msg = std::unique_ptr<Message>(sub_sock->receive(true));
if (!msg) break;
@@ -72,7 +71,7 @@ void MsgqToZmq::zmqMonitorThread() {
// Set up ZMQ monitor for each pub socket
for (int i = 0; i < socket_pairs.size(); ++i) {
std::string addr = "inproc://op-bridge-monitor-" + std::to_string(i);
zmq_socket_monitor(socket_pairs[i].pub_sock->getRawSocket(), addr.c_str(), ZMQ_EVENT_ACCEPTED | ZMQ_EVENT_DISCONNECTED);
zmq_socket_monitor(socket_pairs[i].pub_sock->sock, addr.c_str(), ZMQ_EVENT_ACCEPTED | ZMQ_EVENT_DISCONNECTED);
void *monitor_socket = zmq_socket(zmq_context->getRawContext(), ZMQ_PAIR);
zmq_connect(monitor_socket, addr.c_str());
@@ -109,8 +108,7 @@ void MsgqToZmq::zmqMonitorThread() {
if (++pair.connected_clients == 1) {
// Create new MSGQ subscriber socket and map to ZMQ publisher
pair.sub_sock = std::make_unique<MSGQSubSocket>();
size_t queue_size = services.at(pair.endpoint).queue_size;
pair.sub_sock->connect(msgq_context.get(), pair.endpoint, "127.0.0.1", false, true, queue_size);
pair.sub_sock->connect(msgq_context.get(), pair.endpoint, "127.0.0.1");
sub2pub[pair.sub_sock.get()] = pair.pub_sock.get();
registerSockets();
}
@@ -130,7 +128,7 @@ void MsgqToZmq::zmqMonitorThread() {
// Clean up monitor sockets
for (int i = 0; i < pollitems.size(); ++i) {
zmq_socket_monitor(socket_pairs[i].pub_sock->getRawSocket(), nullptr, 0);
zmq_socket_monitor(socket_pairs[i].pub_sock->sock, nullptr, 0);
zmq_close(pollitems[i].socket);
}
cv.notify_one();
+6 -5
View File
@@ -7,8 +7,9 @@
#include <string>
#include <vector>
#define private public
#include "msgq/impl_msgq.h"
#include "cereal/messaging/bridge_zmq.h"
#include "msgq/impl_zmq.h"
class MsgqToZmq {
public:
@@ -21,16 +22,16 @@ protected:
struct SocketPair {
std::string endpoint;
std::unique_ptr<BridgeZmqPubSocket> pub_sock;
std::unique_ptr<ZMQPubSocket> pub_sock;
std::unique_ptr<MSGQSubSocket> sub_sock;
int connected_clients = 0;
};
std::unique_ptr<Context> msgq_context;
std::unique_ptr<BridgeZmqContext> zmq_context;
std::unique_ptr<MSGQContext> msgq_context;
std::unique_ptr<ZMQContext> zmq_context;
std::mutex mutex;
std::condition_variable cv;
std::unique_ptr<MSGQPoller> msgq_poller;
std::map<SubSocket *, BridgeZmqPubSocket *> sub2pub;
std::map<SubSocket *, ZMQPubSocket *> sub2pub;
std::vector<SocketPair> socket_pairs;
};
+1 -1
View File
@@ -79,9 +79,9 @@ static std::map<std::string, service> services = {
{ "carParamsSP", {"carParamsSP", true, 0.020000, 1, 256000}},
{ "carControlSP", {"carControlSP", true, 100.000000, 10, 256000}},
{ "carStateSP", {"carStateSP", true, 100.000000, 10, 256000}},
{ "liveMapDataSP", {"liveMapDataSP", true, 1.000000, 1, 256000}},
{ "modelDataV2SP", {"modelDataV2SP", true, 20.000000, -1, 10485760}},
{ "liveLocationKalman", {"liveLocationKalman", true, 20.000000, -1, 256000}},
{ "mapdOut", {"mapdOut", true, 20.000000, 20, 2097152}},
{ "uiDebug", {"uiDebug", true, 0.000000, 1, 256000}},
{ "testJoystick", {"testJoystick", true, 0.000000, -1, 256000}},
{ "alertDebug", {"alertDebug", true, 20.000000, 5, 256000}},
+1 -1
View File
@@ -98,9 +98,9 @@ _services: dict[str, tuple] = {
"carParamsSP": (True, 0.02, 1),
"carControlSP": (True, 100., 10),
"carStateSP": (True, 100., 10),
"liveMapDataSP": (True, 1., 1),
"modelDataV2SP": (True, 20., None, QueueSize.BIG),
"liveLocationKalman": (True, 20.),
"mapdOut": (True, 20., 20, QueueSize.MEDIUM),
# debug
"uiDebug": (True, 0., 1),
+2 -2
View File
@@ -18,8 +18,8 @@ class Api:
return self.service.get_token(payload_extra, expiry_hours)
def api_get(endpoint, method='GET', timeout=None, access_token=None, session=None, **params):
return CommaConnectApi(None).api_get(endpoint, method, timeout, access_token, session, **params)
def api_get(endpoint, method='GET', timeout=None, access_token=None, **params):
return CommaConnectApi(None).api_get(endpoint, method, timeout, access_token, **params)
def get_key_pair() -> tuple[str, str, str] | tuple[None, None, None]:
+2 -4
View File
@@ -51,7 +51,7 @@ class BaseApi:
ascii_encoded_text = normalized_text.encode('ascii', 'ignore')
return ascii_encoded_text.decode()
def api_get(self, endpoint, method='GET', timeout=None, access_token=None, session=None, json=None, **params):
def api_get(self, endpoint, method='GET', timeout=None, access_token=None, json=None, **params):
headers = {}
if access_token is not None:
headers['Authorization'] = "JWT " + access_token
@@ -59,9 +59,7 @@ class BaseApi:
version = self.remove_non_ascii_chars(get_version())
headers['User-Agent'] = self.user_agent + version
# TODO: add session to Api
req = requests if session is None else session
return req.request(method, f"{self.api_host}/{endpoint}", timeout=timeout, headers=headers, json=json, params=params)
return requests.request(method, f"{self.api_host}/{endpoint}", timeout=timeout, headers=headers, json=json, params=params)
@staticmethod
def get_key_pair() -> tuple[str, str, str] | tuple[None, None, None]:
+6 -6
View File
@@ -4,27 +4,27 @@ from openpilot.common.utils import run_cmd, run_cmd_default
@cache
def get_commit(cwd: str | None = None, branch: str = "HEAD") -> str:
def get_commit(cwd: str = None, branch: str = "HEAD") -> str:
return run_cmd_default(["git", "rev-parse", branch], cwd=cwd)
@cache
def get_commit_date(cwd: str | None = None, commit: str = "HEAD") -> str:
def get_commit_date(cwd: str = None, commit: str = "HEAD") -> str:
return run_cmd_default(["git", "show", "--no-patch", "--format='%ct %ci'", commit], cwd=cwd)
@cache
def get_short_branch(cwd: str | None = None) -> str:
def get_short_branch(cwd: str = None) -> str:
return run_cmd_default(["git", "rev-parse", "--abbrev-ref", "HEAD"], cwd=cwd)
@cache
def get_branch(cwd: str | None = None) -> str:
def get_branch(cwd: str = None) -> str:
return run_cmd_default(["git", "rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}"], cwd=cwd)
@cache
def get_origin(cwd: str | None = None) -> str:
def get_origin(cwd: str = None) -> str:
try:
local_branch = run_cmd(["git", "name-rev", "--name-only", "HEAD"], cwd=cwd)
tracking_remote = run_cmd(["git", "config", "branch." + local_branch + ".remote"], cwd=cwd)
@@ -34,7 +34,7 @@ def get_origin(cwd: str | None = None) -> str:
@cache
def get_normalized_origin(cwd: str | None = None) -> str:
def get_normalized_origin(cwd: str = None) -> str:
return get_origin(cwd) \
.replace("git@", "", 1) \
.replace(".git", "", 1) \
-81
View File
@@ -1,81 +0,0 @@
import os
import fcntl
import ctypes
# I2C constants from /usr/include/linux/i2c-dev.h
I2C_SLAVE = 0x0703
I2C_SLAVE_FORCE = 0x0706
I2C_SMBUS = 0x0720
# SMBus transfer types
I2C_SMBUS_READ = 1
I2C_SMBUS_WRITE = 0
I2C_SMBUS_BYTE_DATA = 2
I2C_SMBUS_I2C_BLOCK_DATA = 8
I2C_SMBUS_BLOCK_MAX = 32
class _I2cSmbusData(ctypes.Union):
_fields_ = [
("byte", ctypes.c_uint8),
("word", ctypes.c_uint16),
("block", ctypes.c_uint8 * (I2C_SMBUS_BLOCK_MAX + 2)),
]
class _I2cSmbusIoctlData(ctypes.Structure):
_fields_ = [
("read_write", ctypes.c_uint8),
("command", ctypes.c_uint8),
("size", ctypes.c_uint32),
("data", ctypes.POINTER(_I2cSmbusData)),
]
class SMBus:
def __init__(self, bus: int):
self._fd = os.open(f'/dev/i2c-{bus}', os.O_RDWR)
def __enter__(self) -> 'SMBus':
return self
def __exit__(self, *args) -> None:
self.close()
def close(self) -> None:
if hasattr(self, '_fd') and self._fd >= 0:
os.close(self._fd)
self._fd = -1
def _set_address(self, addr: int, force: bool = False) -> None:
ioctl_arg = I2C_SLAVE_FORCE if force else I2C_SLAVE
fcntl.ioctl(self._fd, ioctl_arg, addr)
def _smbus_access(self, read_write: int, command: int, size: int, data: _I2cSmbusData) -> None:
ioctl_data = _I2cSmbusIoctlData(read_write, command, size, ctypes.pointer(data))
fcntl.ioctl(self._fd, I2C_SMBUS, ioctl_data)
def read_byte_data(self, addr: int, register: int, force: bool = False) -> int:
self._set_address(addr, force)
data = _I2cSmbusData()
self._smbus_access(I2C_SMBUS_READ, register, I2C_SMBUS_BYTE_DATA, data)
return int(data.byte)
def write_byte_data(self, addr: int, register: int, value: int, force: bool = False) -> None:
self._set_address(addr, force)
data = _I2cSmbusData()
data.byte = value & 0xFF
self._smbus_access(I2C_SMBUS_WRITE, register, I2C_SMBUS_BYTE_DATA, data)
def read_i2c_block_data(self, addr: int, register: int, length: int, force: bool = False) -> list[int]:
self._set_address(addr, force)
if not (0 <= length <= I2C_SMBUS_BLOCK_MAX):
raise ValueError(f"length must be 0..{I2C_SMBUS_BLOCK_MAX}")
data = _I2cSmbusData()
data.block[0] = length
self._smbus_access(I2C_SMBUS_READ, register, I2C_SMBUS_I2C_BLOCK_DATA, data)
read_len = int(data.block[0]) or length
read_len = min(read_len, length)
return [int(b) for b in data.block[1 : read_len + 1]]
+1 -1
View File
@@ -1 +1 @@
#define DEFAULT_MODEL "CD210 (Default)"
#define DEFAULT_MODEL "Dark Souls 2 (Default)"
+4 -36
View File
@@ -115,7 +115,6 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"SnoozeUpdate", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, BOOL}},
{"SshEnabled", {PERSISTENT | BACKUP, BOOL}},
{"TermsVersion", {PERSISTENT, STRING}},
{"TorqueBar", {PERSISTENT | BACKUP, BOOL, "0"}},
{"TrainingVersion", {PERSISTENT, STRING}},
{"UbloxAvailable", {PERSISTENT, BOOL}},
{"UpdateAvailable", {CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION, BOOL}},
@@ -137,7 +136,6 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"ApiCache_DriveStats", {PERSISTENT, JSON}},
{"AutoLaneChangeBsmDelay", {PERSISTENT | BACKUP, BOOL, "0"}},
{"AutoLaneChangeTimer", {PERSISTENT | BACKUP, INT, "0"}},
{"BlinkerLateralReengageDelay", {PERSISTENT | BACKUP, INT, "0"}}, // seconds
{"BlinkerMinLateralControlSpeed", {PERSISTENT | BACKUP, INT, "20"}}, // MPH or km/h
{"BlinkerPauseLateralControl", {PERSISTENT | BACKUP, INT, "0"}},
{"Brightness", {PERSISTENT | BACKUP, INT, "0"}},
@@ -170,12 +168,12 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"OffroadMode", {CLEAR_ON_MANAGER_START, BOOL}},
{"Offroad_TiciSupport", {CLEAR_ON_MANAGER_START, JSON}},
{"OnroadScreenOffBrightness", {PERSISTENT | BACKUP, INT, "0"}},
{"OnroadScreenOffControl", {PERSISTENT | BACKUP, BOOL}},
{"OnroadScreenOffTimer", {PERSISTENT | BACKUP, INT, "15"}},
{"OnroadUploads", {PERSISTENT | BACKUP, BOOL, "1"}},
{"QuickBootToggle", {PERSISTENT | BACKUP, BOOL, "0"}},
{"QuietMode", {PERSISTENT | BACKUP, BOOL, "0"}},
{"RainbowMode", {PERSISTENT | BACKUP, BOOL, "0"}},
{"RocketFuel", {PERSISTENT | BACKUP, BOOL, "0"}},
{"ShowAdvancedControls", {PERSISTENT | BACKUP, BOOL, "0"}},
{"ShowTurnSignals", {PERSISTENT | BACKUP, BOOL, "0"}},
{"StandstillTimer", {PERSISTENT | BACKUP, BOOL, "0"}},
@@ -195,6 +193,9 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"ModelManager_LastSyncTime", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, INT, "0"}},
{"ModelManager_ModelsCache", {PERSISTENT | BACKUP, JSON}},
{"MapdSettings", {PERSISTENT, JSON}},
{"Offroad_OSMUpdateRequired", {CLEAR_ON_MANAGER_START, JSON}},
// Neural Network Lateral Control
{"NeuralNetworkLateralControl", {PERSISTENT | BACKUP, BOOL, "0"}},
@@ -231,44 +232,11 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"LaneTurnValue", {PERSISTENT | BACKUP, FLOAT, "19.0"}},
{"PlanplusControl", {PERSISTENT | BACKUP, FLOAT, "1.0"}},
// mapd
{"MapAdvisorySpeedLimit", {CLEAR_ON_ONROAD_TRANSITION, FLOAT}},
{"MapdVersion", {PERSISTENT, STRING}},
{"MapSpeedLimit", {CLEAR_ON_ONROAD_TRANSITION, FLOAT, "0.0"}},
{"NextMapSpeedLimit", {CLEAR_ON_ONROAD_TRANSITION, JSON}},
{"Offroad_OSMUpdateRequired", {CLEAR_ON_MANAGER_START, JSON}},
{"OsmDbUpdatesCheck", {CLEAR_ON_MANAGER_START, BOOL}}, // mapd database update happens with device ON, reset on boot
{"OSMDownloadBounds", {PERSISTENT, STRING}},
{"OsmDownloadedDate", {PERSISTENT, STRING, "0.0"}},
{"OSMDownloadLocations", {PERSISTENT, JSON}},
{"OSMDownloadProgress", {CLEAR_ON_MANAGER_START, JSON}},
{"OsmLocal", {PERSISTENT, BOOL}},
{"OsmLocationName", {PERSISTENT, STRING}},
{"OsmLocationTitle", {PERSISTENT, STRING}},
{"OsmLocationUrl", {PERSISTENT, STRING}},
{"OsmStateName", {PERSISTENT, STRING, "All"}},
{"OsmStateTitle", {PERSISTENT, STRING}},
{"OsmWayTest", {PERSISTENT, STRING}},
{"RoadName", {CLEAR_ON_ONROAD_TRANSITION, STRING}},
{"RoadNameToggle", {PERSISTENT | BACKUP, BOOL, "0"}},
// Speed Limit
{"SpeedLimitMode", {PERSISTENT | BACKUP, INT, "1"}},
{"SpeedLimitOffsetType", {PERSISTENT | BACKUP, INT, "0"}},
{"SpeedLimitPolicy", {PERSISTENT | BACKUP, INT, "3"}},
{"SpeedLimitValueOffset", {PERSISTENT | BACKUP, INT, "0"}},
// Smart Cruise Control
{"MapTargetVelocities", {CLEAR_ON_ONROAD_TRANSITION, STRING}},
{"SmartCruiseControlMap", {PERSISTENT | BACKUP, BOOL, "0"}},
{"SmartCruiseControlVision", {PERSISTENT | BACKUP, BOOL, "0"}},
// Torque lateral control custom params
{"CustomTorqueParams", {PERSISTENT | BACKUP , BOOL}},
{"EnforceTorqueControl", {PERSISTENT | BACKUP, BOOL}},
{"LiveTorqueParamsToggle", {PERSISTENT | BACKUP , BOOL}},
{"LiveTorqueParamsRelaxedToggle", {PERSISTENT | BACKUP , BOOL}},
{"TorqueControlTune", {PERSISTENT | BACKUP, FLOAT}},
{"TorqueParamsOverrideEnabled", {PERSISTENT | BACKUP, BOOL, "0"}},
{"TorqueParamsOverrideFriction", {PERSISTENT | BACKUP, FLOAT, "0.1"}},
{"TorqueParamsOverrideLatAccelFactor", {PERSISTENT | BACKUP, FLOAT, "2.5"}},
Binary file not shown.
+9 -3
View File
@@ -3,9 +3,15 @@ from numbers import Number
class PIDController:
def __init__(self, k_p, k_i, k_d=0., pos_limit=1e308, neg_limit=-1e308, rate=100):
self._k_p: list[list[float]] = [[0], [k_p]] if isinstance(k_p, Number) else k_p
self._k_i: list[list[float]] = [[0], [k_i]] if isinstance(k_i, Number) else k_i
self._k_d: list[list[float]] = [[0], [k_d]] if isinstance(k_d, Number) else k_d
self._k_p = k_p
self._k_i = k_i
self._k_d = k_d
if isinstance(self._k_p, Number):
self._k_p = [[0], [self._k_p]]
if isinstance(self._k_i, Number):
self._k_i = [[0], [self._k_i]]
if isinstance(self._k_d, Number):
self._k_d = [[0], [self._k_d]]
self.set_limits(pos_limit, neg_limit)
+1 -5
View File
@@ -13,11 +13,7 @@ public:
if (prefix.empty()) {
prefix = util::random_string(15);
}
#ifdef __APPLE__
msgq_path = "/tmp/msgq_" + prefix;
#else
msgq_path = "/dev/shm/msgq_" + prefix;
#endif
msgq_path = Path::shm_path() + "/" + prefix;
bool ret = util::create_directories(msgq_path, 0777);
assert(ret);
setenv("OPENPILOT_PREFIX", prefix.c_str(), 1);
+2 -4
View File
@@ -1,5 +1,4 @@
import os
import platform
import shutil
import uuid
@@ -10,10 +9,9 @@ from openpilot.system.hardware.hw import Paths
from openpilot.system.hardware.hw import DEFAULT_DOWNLOAD_CACHE_ROOT
class OpenpilotPrefix:
def __init__(self, prefix: str | None = None, create_dirs_on_enter: bool = True, clean_dirs_on_exit: bool = True, shared_download_cache: bool = False):
def __init__(self, prefix: str = None, create_dirs_on_enter: bool = True, clean_dirs_on_exit: bool = True, shared_download_cache: bool = False):
self.prefix = prefix if prefix else str(uuid.uuid4().hex[0:15])
shm_path = "/tmp" if platform.system() == "Darwin" else "/dev/shm"
self.msgq_path = os.path.join(shm_path, "msgq_" + self.prefix)
self.msgq_path = os.path.join(Paths.shm_path(), "msgq_" + self.prefix)
self.create_dirs_on_enter = create_dirs_on_enter
self.clean_dirs_on_exit = clean_dirs_on_exit
self.shared_download_cache = shared_download_cache
+1 -1
View File
@@ -6,7 +6,7 @@ import time
from setproctitle import getproctitle
from openpilot.common.utils import MovingAverage
from openpilot.common.util import MovingAverage
from openpilot.system.hardware import PC
@@ -1,6 +1,6 @@
#define _USE_MATH_DEFINES
#include "sunnypilot/common/transformations/coordinates.hpp"
#include "common/transformations/coordinates.hpp"
#include <iostream>
#include <cmath>
@@ -4,8 +4,8 @@
#include <cmath>
#include <eigen3/Eigen/Dense>
#include "sunnypilot/common/transformations/orientation.hpp"
#include "sunnypilot/common/transformations/coordinates.hpp"
#include "common/transformations/orientation.hpp"
#include "common/transformations/coordinates.hpp"
Eigen::Quaterniond ensure_unique(const Eigen::Quaterniond &quat) {
if (quat.w() > 0){
@@ -141,3 +141,4 @@ Eigen::Vector3d ned_euler_from_ecef(const ECEF &ecef_init, const Eigen::Vector3d
return {phi, theta, psi};
}
@@ -1,6 +1,6 @@
#pragma once
#include <eigen3/Eigen/Dense>
#include "sunnypilot/common/transformations/coordinates.hpp"
#include "common/transformations/coordinates.hpp"
Eigen::Quaterniond ensure_unique(const Eigen::Quaterniond &quat);
@@ -102,36 +102,3 @@ class TestNED:
np.testing.assert_allclose(converter.ned2ecef(ned_offsets_batch),
ecef_positions_offset_batch,
rtol=1e-9, atol=1e-7)
def test_errors(self):
# Test wrong shape/type for geodetic2ecef
# numpy_wrap raises IndexError for scalar input
with np.testing.assert_raises(IndexError):
coord.geodetic2ecef(1.0)
with np.testing.assert_raises_regex(ValueError, "Geodetic must be size 3"):
coord.geodetic2ecef([0, 0])
with np.testing.assert_raises_regex(ValueError, "Geodetic must be size 3"):
coord.geodetic2ecef([0, 0, 0, 0])
with np.testing.assert_raises(TypeError):
coord.geodetic2ecef(['a', 'b', 'c'])
# Test LocalCoord constructor errors
with np.testing.assert_raises(ValueError):
coord.LocalCoord.from_geodetic([0, 0])
with np.testing.assert_raises(ValueError):
coord.LocalCoord.from_geodetic(1)
with np.testing.assert_raises(TypeError):
coord.LocalCoord.from_geodetic(['a', 'b', 'c'])
# Test wrong shape/type for ecef2geodetic
with np.testing.assert_raises(ValueError):
coord.ecef2geodetic([1, 2])
with np.testing.assert_raises(ValueError):
coord.ecef2geodetic([1, 2, 3, 4])
with np.testing.assert_raises(IndexError):
coord.ecef2geodetic(1.0)
@@ -1,5 +1,4 @@
import numpy as np
import pytest
from openpilot.common.transformations.orientation import euler2quat, quat2euler, euler2rot, rot2euler, \
rot2quat, quat2rot, \
@@ -60,32 +59,3 @@ class TestOrientation:
np.testing.assert_allclose(ned_eulers[i], ned_euler_from_ecef(ecef_positions[i], eulers[i]), rtol=1e-7)
#np.testing.assert_allclose(eulers[i], ecef_euler_from_ned(ecef_positions[i], ned_eulers[i]), rtol=1e-7)
# np.testing.assert_allclose(ned_eulers, ned_euler_from_ecef(ecef_positions, eulers), rtol=1e-7)
def test_inputs(self):
with pytest.raises(ValueError):
euler2quat([1, 2])
with pytest.raises(ValueError):
quat2rot([1, 2, 3])
with pytest.raises(IndexError):
rot2quat(np.zeros((2, 2)))
def test_euler_rot_consistency(self):
rpy = [0.1, 0.2, 0.3]
R = euler2rot(rpy)
# R -> q -> R
q = rot2quat(R)
R_new = quat2rot(q)
np.testing.assert_allclose(R, R_new, atol=1e-15)
# q -> R -> Euler (quat2euler) -> R
rpy_new = quat2euler(q)
R_new2 = euler2rot(rpy_new)
np.testing.assert_allclose(R, R_new2, atol=1e-15)
# R -> Euler (rot2euler) -> R
rpy_from_rot = rot2euler(R)
R_new3 = euler2rot(rpy_from_rot)
np.testing.assert_allclose(R, R_new3, atol=1e-15)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,72 @@
# cython: language_level=3
from libcpp cimport bool
cdef extern from "orientation.cc":
pass
cdef extern from "orientation.hpp":
cdef cppclass Quaternion "Eigen::Quaterniond":
Quaternion()
Quaternion(double, double, double, double)
double w()
double x()
double y()
double z()
cdef cppclass Vector3 "Eigen::Vector3d":
Vector3()
Vector3(double, double, double)
double operator()(int)
cdef cppclass Matrix3 "Eigen::Matrix3d":
Matrix3()
Matrix3(double*)
double operator()(int, int)
Quaternion euler2quat(const Vector3 &)
Vector3 quat2euler(const Quaternion &)
Matrix3 quat2rot(const Quaternion &)
Quaternion rot2quat(const Matrix3 &)
Vector3 rot2euler(const Matrix3 &)
Matrix3 euler2rot(const Vector3 &)
Matrix3 rot_matrix(double, double, double)
Vector3 ecef_euler_from_ned(const ECEF &, const Vector3 &)
Vector3 ned_euler_from_ecef(const ECEF &, const Vector3 &)
cdef extern from "coordinates.cc":
cdef struct ECEF:
double x
double y
double z
cdef struct NED:
double n
double e
double d
cdef struct Geodetic:
double lat
double lon
double alt
bool radians
ECEF geodetic2ecef(const Geodetic &)
Geodetic ecef2geodetic(const ECEF &)
cdef cppclass LocalCoord_c "LocalCoord":
Matrix3 ned2ecef_matrix
Matrix3 ecef2ned_matrix
LocalCoord_c(const Geodetic &, const ECEF &)
LocalCoord_c(const Geodetic &)
LocalCoord_c(const ECEF &)
NED ecef2ned(const ECEF &)
ECEF ned2ecef(const NED &)
NED geodetic2ned(const Geodetic &)
Geodetic ned2geodetic(const NED &)
cdef extern from "coordinates.hpp":
pass
-342
View File
@@ -1,342 +0,0 @@
import numpy as np
# Constants
a = 6378137.0
b = 6356752.3142
esq = 6.69437999014e-3
e1sq = 6.73949674228e-3
def geodetic2ecef_single(g):
"""
Convert geodetic coordinates (latitude, longitude, altitude) to ECEF.
"""
try:
if len(g) != 3:
raise ValueError("Geodetic must be size 3")
except TypeError:
raise ValueError("Geodetic must be a sequence of length 3") from None
lat, lon, alt = g
lat = np.radians(lat)
lon = np.radians(lon)
xi = np.sqrt(1.0 - esq * np.sin(lat)**2)
x = (a / xi + alt) * np.cos(lat) * np.cos(lon)
y = (a / xi + alt) * np.cos(lat) * np.sin(lon)
z = (a / xi * (1.0 - esq) + alt) * np.sin(lat)
return np.array([x, y, z])
def ecef2geodetic_single(e):
"""
Convert ECEF to geodetic coordinates using Ferrari's solution.
"""
x, y, z = e
r = np.sqrt(x**2 + y**2)
Esq = a**2 - b**2
F = 54 * b**2 * z**2
G = r**2 + (1 - esq) * z**2 - esq * Esq
C = (esq**2 * F * r**2) / (G**3)
S = np.cbrt(1 + C + np.sqrt(C**2 + 2 * C))
P = F / (3 * (S + 1 / S + 1)**2 * G**2)
Q = np.sqrt(1 + 2 * esq**2 * P)
r_0 = -(P * esq * r) / (1 + Q) + np.sqrt(0.5 * a**2 * (1 + 1.0 / Q) - P * (1 - esq) * z**2 / (Q * (1 + Q)) - 0.5 * P * r**2)
U = np.sqrt((r - esq * r_0)**2 + z**2)
V = np.sqrt((r - esq * r_0)**2 + (1 - esq) * z**2)
Z_0 = b**2 * z / (a * V)
h = U * (1 - b**2 / (a * V))
lat = np.arctan((z + e1sq * Z_0) / r)
lon = np.arctan2(y, x)
return np.array([np.degrees(lat), np.degrees(lon), h])
def euler2quat_single(euler):
"""
Convert Euler angles (roll, pitch, yaw) to a quaternion.
Rotation order: Z-Y-X (yaw, pitch, roll).
"""
phi, theta, psi = euler
c_phi, s_phi = np.cos(phi / 2), np.sin(phi / 2)
c_theta, s_theta = np.cos(theta / 2), np.sin(theta / 2)
c_psi, s_psi = np.cos(psi / 2), np.sin(psi / 2)
w = c_phi * c_theta * c_psi + s_phi * s_theta * s_psi
x = s_phi * c_theta * c_psi - c_phi * s_theta * s_psi
y = c_phi * s_theta * c_psi + s_phi * c_theta * s_psi
z = c_phi * c_theta * s_psi - s_phi * s_theta * c_psi
if w < 0:
return np.array([-w, -x, -y, -z])
return np.array([w, x, y, z])
def quat2euler_single(q):
"""
Convert a quaternion to Euler angles (roll, pitch, yaw).
"""
w, x, y, z = q
gamma = np.arctan2(2 * (w * x + y * z), 1 - 2 * (x**2 + y**2))
sin_arg = 2 * (w * y - z * x)
sin_arg = np.clip(sin_arg, -1.0, 1.0)
theta = np.arcsin(sin_arg)
psi = np.arctan2(2 * (w * z + x * y), 1 - 2 * (y**2 + z**2))
return np.array([gamma, theta, psi])
def quat2rot_single(q):
"""
Convert a quaternion to a 3x3 rotation matrix.
"""
w, x, y, z = q
xx, yy, zz = x * x, y * y, z * z
xy, xz, yz = x * y, x * z, y * z
wx, wy, wz = w * x, w * y, w * z
mat = np.array([
[1 - 2 * (yy + zz), 2 * (xy - wz), 2 * (xz + wy)],
[2 * (xy + wz), 1 - 2 * (xx + zz), 2 * (yz - wx)],
[2 * (xz - wy), 2 * (yz + wx), 1 - 2 * (xx + yy)]
])
return mat
def rot2quat_single(rot):
"""
Convert a 3x3 rotation matrix to a quaternion.
"""
trace = np.trace(rot)
if trace > 0:
s = 0.5 / np.sqrt(trace + 1.0)
w = 0.25 / s
x = (rot[2, 1] - rot[1, 2]) * s
y = (rot[0, 2] - rot[2, 0]) * s
z = (rot[1, 0] - rot[0, 1]) * s
else:
if rot[0, 0] > rot[1, 1] and rot[0, 0] > rot[2, 2]:
s = 2.0 * np.sqrt(1.0 + rot[0, 0] - rot[1, 1] - rot[2, 2])
w = (rot[2, 1] - rot[1, 2]) / s
x = 0.25 * s
y = (rot[0, 1] + rot[1, 0]) / s
z = (rot[0, 2] + rot[2, 0]) / s
elif rot[1, 1] > rot[2, 2]:
s = 2.0 * np.sqrt(1.0 + rot[1, 1] - rot[0, 0] - rot[2, 2])
w = (rot[0, 2] - rot[2, 0]) / s
x = (rot[0, 1] + rot[1, 0]) / s
y = 0.25 * s
z = (rot[1, 2] + rot[2, 1]) / s
else:
s = 2.0 * np.sqrt(1.0 + rot[2, 2] - rot[0, 0] - rot[1, 1])
w = (rot[1, 0] - rot[0, 1]) / s
x = (rot[0, 2] + rot[2, 0]) / s
y = (rot[1, 2] + rot[2, 1]) / s
z = 0.25 * s
if w < 0:
return np.array([-w, -x, -y, -z])
return np.array([w, x, y, z])
def euler2rot_single(euler):
"""
Convert Euler angles (roll, pitch, yaw) to a 3x3 rotation matrix.
Rotation order: Z-Y-X (yaw, pitch, roll).
"""
phi, theta, psi = euler
cx, sx = np.cos(phi), np.sin(phi)
cy, sy = np.cos(theta), np.sin(theta)
cz, sz = np.cos(psi), np.sin(psi)
Rx = np.array([[1, 0, 0], [0, cx, -sx], [0, sx, cx]])
Ry = np.array([[cy, 0, sy], [0, 1, 0], [-sy, 0, cy]])
Rz = np.array([[cz, -sz, 0], [sz, cz, 0], [0, 0, 1]])
return Rz @ Ry @ Rx
def rot2euler_single(rot):
"""
Convert a 3x3 rotation matrix to Euler angles (roll, pitch, yaw).
"""
return quat2euler_single(rot2quat_single(rot))
def rot_matrix(roll, pitch, yaw):
"""
Create a 3x3 rotation matrix from roll, pitch, and yaw angles.
"""
return euler2rot_single([roll, pitch, yaw])
def axis_angle_to_rot(axis, angle):
"""
Convert an axis-angle representation to a 3x3 rotation matrix.
"""
c = np.cos(angle / 2)
s = np.sin(angle / 2)
q = np.array([c, s*axis[0], s*axis[1], s*axis[2]])
return quat2rot_single(q)
class LocalCoord:
"""
A class to handle conversions between ECEF and local NED coordinates.
"""
def __init__(self, geodetic=None, ecef=None):
"""
Initialize LocalCoord with either geodetic or ECEF coordinates.
"""
if geodetic is not None:
self.init_ecef = geodetic2ecef_single(geodetic)
lat, lon, _ = geodetic
elif ecef is not None:
self.init_ecef = np.array(ecef)
lat, lon, _ = ecef2geodetic_single(ecef)
else:
raise ValueError("Must provide geodetic or ecef")
lat = np.radians(lat)
lon = np.radians(lon)
self.ned2ecef_matrix = np.array([
[-np.sin(lat) * np.cos(lon), -np.sin(lon), -np.cos(lat) * np.cos(lon)],
[-np.sin(lat) * np.sin(lon), np.cos(lon), -np.cos(lat) * np.sin(lon)],
[np.cos(lat), 0, -np.sin(lat)]
])
self.ecef2ned_matrix = self.ned2ecef_matrix.T
@classmethod
def from_geodetic(cls, geodetic):
"""
Create a LocalCoord instance from geodetic coordinates.
"""
return cls(geodetic=geodetic)
@classmethod
def from_ecef(cls, ecef):
"""
Create a LocalCoord instance from ECEF coordinates.
"""
return cls(ecef=ecef)
def ecef2ned_single(self, ecef):
"""
Convert a single ECEF point to NED coordinates relative to the origin.
"""
return self.ecef2ned_matrix @ (ecef - self.init_ecef)
def ned2ecef_single(self, ned):
"""
Convert a single NED point to ECEF coordinates.
"""
return self.ned2ecef_matrix @ ned + self.init_ecef
def geodetic2ned_single(self, geodetic):
"""
Convert a single geodetic point to NED coordinates.
"""
ecef = geodetic2ecef_single(geodetic)
return self.ecef2ned_single(ecef)
def ned2geodetic_single(self, ned):
"""
Convert a single NED point to geodetic coordinates.
"""
ecef = self.ned2ecef_single(ned)
return ecef2geodetic_single(ecef)
@property
def ned_from_ecef_matrix(self):
"""
Returns the rotation matrix from ECEF to NED coordinates.
"""
return self.ecef2ned_matrix
@property
def ecef_from_ned_matrix(self):
"""
Returns the rotation matrix from NED to ECEF coordinates.
"""
return self.ned2ecef_matrix
def ecef_euler_from_ned_single(ecef_init, ned_pose):
"""
Convert NED Euler angles (roll, pitch, yaw) at a given ECEF origin
to equivalent ECEF Euler angles.
"""
converter = LocalCoord(ecef=ecef_init)
zero = np.array(ecef_init)
x0 = converter.ned2ecef_single([1, 0, 0]) - zero
y0 = converter.ned2ecef_single([0, 1, 0]) - zero
z0 = converter.ned2ecef_single([0, 0, 1]) - zero
phi, theta, psi = ned_pose
x1 = axis_angle_to_rot(z0, psi) @ x0
y1 = axis_angle_to_rot(z0, psi) @ y0
z1 = axis_angle_to_rot(z0, psi) @ z0
x2 = axis_angle_to_rot(y1, theta) @ x1
y2 = axis_angle_to_rot(y1, theta) @ y1
z2 = axis_angle_to_rot(y1, theta) @ z1
x3 = axis_angle_to_rot(x2, phi) @ x2
y3 = axis_angle_to_rot(x2, phi) @ y2
x0 = np.array([1.0, 0, 0])
y0 = np.array([0, 1.0, 0])
z0 = np.array([0, 0, 1.0])
psi_out = np.arctan2(np.dot(x3, y0), np.dot(x3, x0))
theta_out = np.arctan2(-np.dot(x3, z0), np.sqrt(np.dot(x3, x0)**2 + np.dot(x3, y0)**2))
y2 = axis_angle_to_rot(z0, psi_out) @ y0
z2 = axis_angle_to_rot(y2, theta_out) @ z0
phi_out = np.arctan2(np.dot(y3, z2), np.dot(y3, y2))
return np.array([phi_out, theta_out, psi_out])
def ned_euler_from_ecef_single(ecef_init, ecef_pose):
"""
Convert ECEF Euler angles (roll, pitch, yaw) at a given ECEF origin
to equivalent NED Euler angles.
"""
converter = LocalCoord(ecef=ecef_init)
x0 = np.array([1.0, 0, 0])
y0 = np.array([0, 1.0, 0])
z0 = np.array([0, 0, 1.0])
phi, theta, psi = ecef_pose
x1 = axis_angle_to_rot(z0, psi) @ x0
y1 = axis_angle_to_rot(z0, psi) @ y0
z1 = axis_angle_to_rot(z0, psi) @ z0
x2 = axis_angle_to_rot(y1, theta) @ x1
y2 = axis_angle_to_rot(y1, theta) @ y1
z2 = axis_angle_to_rot(y1, theta) @ z1
x3 = axis_angle_to_rot(x2, phi) @ x2
y3 = axis_angle_to_rot(x2, phi) @ y2
zero = np.array(ecef_init)
x0 = converter.ned2ecef_single([1, 0, 0]) - zero
y0 = converter.ned2ecef_single([0, 1, 0]) - zero
z0 = converter.ned2ecef_single([0, 0, 1]) - zero
psi_out = np.arctan2(np.dot(x3, y0), np.dot(x3, x0))
theta_out = np.arctan2(-np.dot(x3, z0), np.sqrt(np.dot(x3, x0)**2 + np.dot(x3, y0)**2))
y2 = axis_angle_to_rot(z0, psi_out) @ y0
z2 = axis_angle_to_rot(y2, theta_out) @ z0
phi_out = np.arctan2(np.dot(y3, z2), np.dot(y3, y2))
return np.array([phi_out, theta_out, psi_out])
+173
View File
@@ -0,0 +1,173 @@
# distutils: language = c++
# cython: language_level = 3
from openpilot.common.transformations.transformations cimport Matrix3, Vector3, Quaternion
from openpilot.common.transformations.transformations cimport ECEF, NED, Geodetic
from openpilot.common.transformations.transformations cimport euler2quat as euler2quat_c
from openpilot.common.transformations.transformations cimport quat2euler as quat2euler_c
from openpilot.common.transformations.transformations cimport quat2rot as quat2rot_c
from openpilot.common.transformations.transformations cimport rot2quat as rot2quat_c
from openpilot.common.transformations.transformations cimport euler2rot as euler2rot_c
from openpilot.common.transformations.transformations cimport rot2euler as rot2euler_c
from openpilot.common.transformations.transformations cimport rot_matrix as rot_matrix_c
from openpilot.common.transformations.transformations cimport ecef_euler_from_ned as ecef_euler_from_ned_c
from openpilot.common.transformations.transformations cimport ned_euler_from_ecef as ned_euler_from_ecef_c
from openpilot.common.transformations.transformations cimport geodetic2ecef as geodetic2ecef_c
from openpilot.common.transformations.transformations cimport ecef2geodetic as ecef2geodetic_c
from openpilot.common.transformations.transformations cimport LocalCoord_c
import numpy as np
cimport numpy as np
cdef np.ndarray[double, ndim=2] matrix2numpy(Matrix3 m):
return np.array([
[m(0, 0), m(0, 1), m(0, 2)],
[m(1, 0), m(1, 1), m(1, 2)],
[m(2, 0), m(2, 1), m(2, 2)],
])
cdef Matrix3 numpy2matrix(np.ndarray[double, ndim=2, mode="fortran"] m):
assert m.shape[0] == 3
assert m.shape[1] == 3
return Matrix3(<double*>m.data)
cdef ECEF list2ecef(ecef):
cdef ECEF e
e.x = ecef[0]
e.y = ecef[1]
e.z = ecef[2]
return e
cdef NED list2ned(ned):
cdef NED n
n.n = ned[0]
n.e = ned[1]
n.d = ned[2]
return n
cdef Geodetic list2geodetic(geodetic):
cdef Geodetic g
g.lat = geodetic[0]
g.lon = geodetic[1]
g.alt = geodetic[2]
return g
def euler2quat_single(euler):
cdef Vector3 e = Vector3(euler[0], euler[1], euler[2])
cdef Quaternion q = euler2quat_c(e)
return [q.w(), q.x(), q.y(), q.z()]
def quat2euler_single(quat):
cdef Quaternion q = Quaternion(quat[0], quat[1], quat[2], quat[3])
cdef Vector3 e = quat2euler_c(q)
return [e(0), e(1), e(2)]
def quat2rot_single(quat):
cdef Quaternion q = Quaternion(quat[0], quat[1], quat[2], quat[3])
cdef Matrix3 r = quat2rot_c(q)
return matrix2numpy(r)
def rot2quat_single(rot):
cdef Matrix3 r = numpy2matrix(np.asfortranarray(rot, dtype=np.double))
cdef Quaternion q = rot2quat_c(r)
return [q.w(), q.x(), q.y(), q.z()]
def euler2rot_single(euler):
cdef Vector3 e = Vector3(euler[0], euler[1], euler[2])
cdef Matrix3 r = euler2rot_c(e)
return matrix2numpy(r)
def rot2euler_single(rot):
cdef Matrix3 r = numpy2matrix(np.asfortranarray(rot, dtype=np.double))
cdef Vector3 e = rot2euler_c(r)
return [e(0), e(1), e(2)]
def rot_matrix(roll, pitch, yaw):
return matrix2numpy(rot_matrix_c(roll, pitch, yaw))
def ecef_euler_from_ned_single(ecef_init, ned_pose):
cdef ECEF init = list2ecef(ecef_init)
cdef Vector3 pose = Vector3(ned_pose[0], ned_pose[1], ned_pose[2])
cdef Vector3 e = ecef_euler_from_ned_c(init, pose)
return [e(0), e(1), e(2)]
def ned_euler_from_ecef_single(ecef_init, ecef_pose):
cdef ECEF init = list2ecef(ecef_init)
cdef Vector3 pose = Vector3(ecef_pose[0], ecef_pose[1], ecef_pose[2])
cdef Vector3 e = ned_euler_from_ecef_c(init, pose)
return [e(0), e(1), e(2)]
def geodetic2ecef_single(geodetic):
cdef Geodetic g = list2geodetic(geodetic)
cdef ECEF e = geodetic2ecef_c(g)
return [e.x, e.y, e.z]
def ecef2geodetic_single(ecef):
cdef ECEF e = list2ecef(ecef)
cdef Geodetic g = ecef2geodetic_c(e)
return [g.lat, g.lon, g.alt]
cdef class LocalCoord:
cdef LocalCoord_c * lc
def __init__(self, geodetic=None, ecef=None):
assert (geodetic is not None) or (ecef is not None)
if geodetic is not None:
self.lc = new LocalCoord_c(list2geodetic(geodetic))
elif ecef is not None:
self.lc = new LocalCoord_c(list2ecef(ecef))
@property
def ned2ecef_matrix(self):
return matrix2numpy(self.lc.ned2ecef_matrix)
@property
def ecef2ned_matrix(self):
return matrix2numpy(self.lc.ecef2ned_matrix)
@property
def ned_from_ecef_matrix(self):
return self.ecef2ned_matrix
@property
def ecef_from_ned_matrix(self):
return self.ned2ecef_matrix
@classmethod
def from_geodetic(cls, geodetic):
return cls(geodetic=geodetic)
@classmethod
def from_ecef(cls, ecef):
return cls(ecef=ecef)
def ecef2ned_single(self, ecef):
assert self.lc
cdef ECEF e = list2ecef(ecef)
cdef NED n = self.lc.ecef2ned(e)
return [n.n, n.e, n.d]
def ned2ecef_single(self, ned):
assert self.lc
cdef NED n = list2ned(ned)
cdef ECEF e = self.lc.ned2ecef(n)
return [e.x, e.y, e.z]
def geodetic2ned_single(self, geodetic):
assert self.lc
cdef Geodetic g = list2geodetic(geodetic)
cdef NED n = self.lc.geodetic2ned(g)
return [n.n, n.e, n.d]
def ned2geodetic_single(self, ned):
assert self.lc
cdef NED n = list2ned(ned)
cdef Geodetic g = self.lc.ned2geodetic(n)
return [g.lat, g.lon, g.alt]
def __dealloc__(self):
del self.lc
Binary file not shown.
+46
View File
@@ -0,0 +1,46 @@
import os
import subprocess
def sudo_write(val: str, path: str) -> None:
try:
with open(path, 'w') as f:
f.write(str(val))
except PermissionError:
os.system(f"sudo chmod a+w {path}")
try:
with open(path, 'w') as f:
f.write(str(val))
except PermissionError:
# fallback for debugfs files
os.system(f"sudo su -c 'echo {val} > {path}'")
def sudo_read(path: str) -> str:
try:
return subprocess.check_output(f"sudo cat {path}", shell=True, encoding='utf8').strip()
except Exception:
return ""
class MovingAverage:
def __init__(self, window_size: int):
self.window_size: int = window_size
self.buffer: list[float] = [0.0] * window_size
self.index: int = 0
self.count: int = 0
self.sum: float = 0.0
def add_value(self, new_value: float):
# Update the sum: subtract the value being replaced and add the new value
self.sum -= self.buffer[self.index]
self.buffer[self.index] = new_value
self.sum += new_value
# Update the index in a circular manner
self.index = (self.index + 1) % self.window_size
# Track the number of added values (for partial windows)
self.count = min(self.count + 1, self.window_size)
def get_average(self) -> float:
if self.count == 0:
return float('nan')
return self.sum / self.count
+3 -157
View File
@@ -7,82 +7,14 @@ import time
import functools
from subprocess import Popen, PIPE, TimeoutExpired
import zstandard as zstd
from openpilot.common.swaglog import cloudlog
LOG_COMPRESSION_LEVEL = 10 # little benefit up to level 15. level ~17 is a small step change
class Timer:
"""Simple lap timer for profiling sequential operations."""
def __init__(self):
self._start = self._lap = time.monotonic()
self._sections = {}
def lap(self, name):
now = time.monotonic()
self._sections[name] = now - self._lap
self._lap = now
@property
def total(self):
return time.monotonic() - self._start
def fmt(self, duration):
parts = ", ".join(f"{k}={v:.2f}s" + (f" ({duration/v:.0f}x)" if k == 'render' and v > 0 else "") for k, v in self._sections.items())
total = self.total
realtime = f"{duration/total:.1f}x realtime" if total > 0 else "N/A"
return f"{duration}s in {total:.1f}s ({realtime}) | {parts}"
def sudo_write(val: str, path: str) -> None:
try:
with open(path, 'w') as f:
f.write(str(val))
except PermissionError:
os.system(f"sudo chmod a+w {path}")
try:
with open(path, 'w') as f:
f.write(str(val))
except PermissionError:
# fallback for debugfs files
os.system(f"sudo su -c 'echo {val} > {path}'")
def sudo_read(path: str) -> str:
try:
return subprocess.check_output(f"sudo cat {path}", shell=True, encoding='utf8').strip()
except Exception:
return ""
class MovingAverage:
def __init__(self, window_size: int):
self.window_size: int = window_size
self.buffer: list[float] = [0.0] * window_size
self.index: int = 0
self.count: int = 0
self.sum: float = 0.0
def add_value(self, new_value: float):
# Update the sum: subtract the value being replaced and add the new value
self.sum -= self.buffer[self.index]
self.buffer[self.index] = new_value
self.sum += new_value
# Update the index in a circular manner
self.index = (self.index + 1) % self.window_size
# Track the number of added values (for partial windows)
self.count = min(self.count + 1, self.window_size)
def get_average(self) -> float:
if self.count == 0:
return float('nan')
return self.sum / self.count
class CallbackReader:
"""Wraps a file, but overrides the read method to also
call a callback function with the number of bytes read so far."""
def __init__(self, f, callback, *args):
self.f = f
self.callback = callback
@@ -167,92 +99,6 @@ def managed_proc(cmd: list[str], env: dict[str, str]):
proc.kill()
def tabulate(tabular_data, headers=(), tablefmt="simple", floatfmt="g", stralign="left", numalign=None):
rows = [list(row) for row in tabular_data]
def fmt(val):
if isinstance(val, str):
return val
if isinstance(val, (bool, int)):
return str(val)
try:
return format(val, floatfmt)
except (TypeError, ValueError):
return str(val)
formatted = [[fmt(c) for c in row] for row in rows]
hdrs = [str(h) for h in headers] if headers else None
ncols = max((len(r) for r in formatted), default=0)
if hdrs:
ncols = max(ncols, len(hdrs))
if ncols == 0:
return ""
for r in formatted:
r.extend([""] * (ncols - len(r)))
if hdrs:
hdrs.extend([""] * (ncols - len(hdrs)))
widths = [0] * ncols
if hdrs:
for i in range(ncols):
widths[i] = len(hdrs[i])
for row in formatted:
for i in range(ncols):
widths[i] = max(widths[i], max(len(ln) for ln in row[i].split('\n')))
def _align(s, w):
if stralign == "center":
return s.center(w)
return s.ljust(w)
if tablefmt == "html":
parts = ["<table>"]
if hdrs:
parts.append("<thead>")
parts.append("<tr>" + "".join(f"<th>{h}</th>" for h in hdrs) + "</tr>")
parts.append("</thead>")
parts.append("<tbody>")
for row in formatted:
parts.append("<tr>" + "".join(f"<td>{c}</td>" for c in row) + "</tr>")
parts.append("</tbody>")
parts.append("</table>")
return "\n".join(parts)
if tablefmt == "simple_grid":
def _sep(left, mid, right):
return left + mid.join("\u2500" * (w + 2) for w in widths) + right
top, mid_sep, bot = _sep("\u250c", "\u252c", "\u2510"), _sep("\u251c", "\u253c", "\u2524"), _sep("\u2514", "\u2534", "\u2518")
def _fmt_row(cells):
split = [c.split('\n') for c in cells]
nlines = max(len(s) for s in split)
for s in split:
s.extend([""] * (nlines - len(s)))
return ["\u2502" + "\u2502".join(f" {_align(split[i][li], widths[i])} " for i in range(ncols)) + "\u2502" for li in range(nlines)]
lines = [top]
if hdrs:
lines.extend(_fmt_row(hdrs))
lines.append(mid_sep)
for ri, row in enumerate(formatted):
lines.extend(_fmt_row(row))
lines.append(mid_sep if ri < len(formatted) - 1 else bot)
return "\n".join(lines)
# simple
gap = " "
lines = []
if hdrs:
lines.append(gap.join(h.ljust(w) for h, w in zip(hdrs, widths, strict=True)))
lines.append(gap.join("-" * w for w in widths))
for row in formatted:
lines.append(gap.join(_align(row[i], widths[i]) for i in range(ncols)))
return "\n".join(lines)
def retry(attempts=3, delay=1.0, ignore_failure=False):
def decorator(func):
@functools.wraps(func)
@@ -261,11 +107,11 @@ def retry(attempts=3, delay=1.0, ignore_failure=False):
try:
return func(*args, **kwargs)
except Exception:
print(f"{func.__name__} failed, trying again")
cloudlog.exception(f"{func.__name__} failed, trying again")
time.sleep(delay)
if ignore_failure:
print(f"{func.__name__} failed after retry")
cloudlog.error(f"{func.__name__} failed after retry")
else:
raise Exception(f"{func.__name__} failed after retry")
return wrapper
+1 -1
View File
@@ -1 +1 @@
#define COMMA_VERSION "0.10.4"
#define COMMA_VERSION "0.10.3"
+36 -18
View File
@@ -35,6 +35,24 @@
"file": "/data/openpilot/common/params_pyx.cpp",
"output": "/data/openpilot/common/params_pyx.o"
},
{
"command": "clang++ -o common/transformations/orientation.o -c -std=c++1z -D__TICI__ -mcpu=cortex-a57 -DQCOM2 -g -fPIC -O2 -Wunused -Werror -Wshadow -Wno-unknown-warning-option -Wno-inconsistent-missing-override -Wno-c99-designator -Wno-reorder-init-list -Wno-vla-cxx-extension -D__TICI__ -mcpu=cortex-a57 -DQCOM2 -I. -Imsgq -Ithird_party -Ithird_party/json11 -Ithird_party/linux/include -Ithird_party/acados/include -Ithird_party/acados/include/blasfeo/include -Ithird_party/acados/include/hpipm/include -Ithird_party/catch2/include -Ithird_party/libyuv/include -Ithird_party/opencl/include common/transformations/orientation.cc",
"directory": "/data/openpilot",
"file": "/data/openpilot/common/transformations/orientation.cc",
"output": "/data/openpilot/common/transformations/orientation.o"
},
{
"command": "clang++ -o common/transformations/coordinates.o -c -std=c++1z -D__TICI__ -mcpu=cortex-a57 -DQCOM2 -g -fPIC -O2 -Wunused -Werror -Wshadow -Wno-unknown-warning-option -Wno-inconsistent-missing-override -Wno-c99-designator -Wno-reorder-init-list -Wno-vla-cxx-extension -D__TICI__ -mcpu=cortex-a57 -DQCOM2 -I. -Imsgq -Ithird_party -Ithird_party/json11 -Ithird_party/linux/include -Ithird_party/acados/include -Ithird_party/acados/include/blasfeo/include -Ithird_party/acados/include/hpipm/include -Ithird_party/catch2/include -Ithird_party/libyuv/include -Ithird_party/opencl/include common/transformations/coordinates.cc",
"directory": "/data/openpilot",
"file": "/data/openpilot/common/transformations/coordinates.cc",
"output": "/data/openpilot/common/transformations/coordinates.o"
},
{
"command": "clang++ -o common/transformations/transformations.o -c -std=c++1z -D__TICI__ -mcpu=cortex-a57 -DQCOM2 -g -fPIC -O2 -Wunused -Wshadow -Wno-unknown-warning-option -Wno-inconsistent-missing-override -Wno-c99-designator -Wno-reorder-init-list -Wno-vla-cxx-extension -D__TICI__ -mcpu=cortex-a57 -DQCOM2 -Wno-#warnings -Wno-shadow -Wno-deprecated-declarations -I. -Imsgq -Ithird_party -Ithird_party/json11 -Ithird_party/linux/include -Ithird_party/acados/include -Ithird_party/acados/include/blasfeo/include -Ithird_party/acados/include/hpipm/include -Ithird_party/catch2/include -Ithird_party/libyuv/include -Ithird_party/opencl/include -I/usr/include/python3.12 -I/usr/local/venv/lib/python3.12/site-packages/numpy/_core/include common/transformations/transformations.cpp",
"directory": "/data/openpilot",
"file": "/data/openpilot/common/transformations/transformations.cpp",
"output": "/data/openpilot/common/transformations/transformations.o"
},
{
"command": "clang++ -o msgq_repo/msgq/ipc.os -c -std=c++1z -D__TICI__ -mcpu=cortex-a57 -DQCOM2 -DSWAGLOG=\"\\\"common/swaglog.h\\\"\" -g -fPIC -O2 -Wunused -Werror -Wshadow -Wno-unknown-warning-option -Wno-inconsistent-missing-override -Wno-c99-designator -Wno-reorder-init-list -Wno-vla-cxx-extension -D__TICI__ -mcpu=cortex-a57 -DQCOM2 -fPIC -I. -Imsgq -Ithird_party -Ithird_party/json11 -Ithird_party/linux/include -Ithird_party/acados/include -Ithird_party/acados/include/blasfeo/include -Ithird_party/acados/include/hpipm/include -Ithird_party/catch2/include -Ithird_party/libyuv/include -Ithird_party/opencl/include msgq_repo/msgq/ipc.cc",
"directory": "/data/openpilot",
@@ -47,6 +65,12 @@
"file": "/data/openpilot/msgq_repo/msgq/event.cc",
"output": "/data/openpilot/msgq_repo/msgq/event.os"
},
{
"command": "clang++ -o msgq_repo/msgq/impl_zmq.os -c -std=c++1z -D__TICI__ -mcpu=cortex-a57 -DQCOM2 -DSWAGLOG=\"\\\"common/swaglog.h\\\"\" -g -fPIC -O2 -Wunused -Werror -Wshadow -Wno-unknown-warning-option -Wno-inconsistent-missing-override -Wno-c99-designator -Wno-reorder-init-list -Wno-vla-cxx-extension -D__TICI__ -mcpu=cortex-a57 -DQCOM2 -fPIC -I. -Imsgq -Ithird_party -Ithird_party/json11 -Ithird_party/linux/include -Ithird_party/acados/include -Ithird_party/acados/include/blasfeo/include -Ithird_party/acados/include/hpipm/include -Ithird_party/catch2/include -Ithird_party/libyuv/include -Ithird_party/opencl/include msgq_repo/msgq/impl_zmq.cc",
"directory": "/data/openpilot",
"file": "/data/openpilot/msgq_repo/msgq/impl_zmq.cc",
"output": "/data/openpilot/msgq_repo/msgq/impl_zmq.os"
},
{
"command": "clang++ -o msgq_repo/msgq/impl_msgq.os -c -std=c++1z -D__TICI__ -mcpu=cortex-a57 -DQCOM2 -DSWAGLOG=\"\\\"common/swaglog.h\\\"\" -g -fPIC -O2 -Wunused -Werror -Wshadow -Wno-unknown-warning-option -Wno-inconsistent-missing-override -Wno-c99-designator -Wno-reorder-init-list -Wno-vla-cxx-extension -D__TICI__ -mcpu=cortex-a57 -DQCOM2 -fPIC -I. -Imsgq -Ithird_party -Ithird_party/json11 -Ithird_party/linux/include -Ithird_party/acados/include -Ithird_party/acados/include/blasfeo/include -Ithird_party/acados/include/hpipm/include -Ithird_party/catch2/include -Ithird_party/libyuv/include -Ithird_party/opencl/include msgq_repo/msgq/impl_msgq.cc",
"directory": "/data/openpilot",
@@ -143,12 +167,6 @@
"file": "/data/openpilot/cereal/messaging/msgq_to_zmq.cc",
"output": "/data/openpilot/cereal/messaging/msgq_to_zmq.o"
},
{
"command": "clang++ -o cereal/messaging/bridge_zmq.o -c -std=c++1z -D__TICI__ -mcpu=cortex-a57 -DQCOM2 -g -fPIC -O2 -Wunused -Werror -Wshadow -Wno-unknown-warning-option -Wno-inconsistent-missing-override -Wno-c99-designator -Wno-reorder-init-list -Wno-vla-cxx-extension -D__TICI__ -mcpu=cortex-a57 -DQCOM2 -I. -Imsgq -Ithird_party -Ithird_party/json11 -Ithird_party/linux/include -Ithird_party/acados/include -Ithird_party/acados/include/blasfeo/include -Ithird_party/acados/include/hpipm/include -Ithird_party/catch2/include -Ithird_party/libyuv/include -Ithird_party/opencl/include cereal/messaging/bridge_zmq.cc",
"directory": "/data/openpilot",
"file": "/data/openpilot/cereal/messaging/bridge_zmq.cc",
"output": "/data/openpilot/cereal/messaging/bridge_zmq.o"
},
{
"command": "clang++ -o cereal/messaging/socketmaster.o -c -std=c++1z -D__TICI__ -mcpu=cortex-a57 -DQCOM2 -g -fPIC -O2 -Wunused -Werror -Wshadow -Wno-unknown-warning-option -Wno-inconsistent-missing-override -Wno-c99-designator -Wno-reorder-init-list -Wno-vla-cxx-extension -D__TICI__ -mcpu=cortex-a57 -DQCOM2 -I. -Imsgq -Ithird_party -Ithird_party/json11 -Ithird_party/linux/include -Ithird_party/acados/include -Ithird_party/acados/include/blasfeo/include -Ithird_party/acados/include/hpipm/include -Ithird_party/catch2/include -Ithird_party/libyuv/include -Ithird_party/opencl/include cereal/messaging/socketmaster.cc",
"directory": "/data/openpilot",
@@ -401,6 +419,18 @@
"file": "/data/openpilot/selfdrive/pandad/panda_safety.cc",
"output": "/data/openpilot/selfdrive/pandad/panda_safety.o"
},
{
"command": "clang++ -o selfdrive/pandad/can_list_to_can_capnp.o -c -std=c++1z -D__TICI__ -mcpu=cortex-a57 -DQCOM2 -g -fPIC -O2 -Wunused -Werror -Wshadow -Wno-unknown-warning-option -Wno-inconsistent-missing-override -Wno-c99-designator -Wno-reorder-init-list -Wno-vla-cxx-extension -D__TICI__ -mcpu=cortex-a57 -DQCOM2 -I. -Imsgq -Ithird_party -Ithird_party/json11 -Ithird_party/linux/include -Ithird_party/acados/include -Ithird_party/acados/include/blasfeo/include -Ithird_party/acados/include/hpipm/include -Ithird_party/catch2/include -Ithird_party/libyuv/include -Ithird_party/opencl/include selfdrive/pandad/can_list_to_can_capnp.cc",
"directory": "/data/openpilot",
"file": "/data/openpilot/selfdrive/pandad/can_list_to_can_capnp.cc",
"output": "/data/openpilot/selfdrive/pandad/can_list_to_can_capnp.o"
},
{
"command": "clang++ -o selfdrive/pandad/pandad_api_impl.o -c -std=c++1z -D__TICI__ -mcpu=cortex-a57 -DQCOM2 -g -fPIC -O2 -Wunused -Wshadow -Wno-unknown-warning-option -Wno-inconsistent-missing-override -Wno-c99-designator -Wno-reorder-init-list -Wno-vla-cxx-extension -D__TICI__ -mcpu=cortex-a57 -DQCOM2 -Wno-#warnings -Wno-shadow -Wno-deprecated-declarations -I. -Imsgq -Ithird_party -Ithird_party/json11 -Ithird_party/linux/include -Ithird_party/acados/include -Ithird_party/acados/include/blasfeo/include -Ithird_party/acados/include/hpipm/include -Ithird_party/catch2/include -Ithird_party/libyuv/include -Ithird_party/opencl/include -I/usr/include/python3.12 -I/usr/local/venv/lib/python3.12/site-packages/numpy/_core/include selfdrive/pandad/pandad_api_impl.cpp",
"directory": "/data/openpilot",
"file": "/data/openpilot/selfdrive/pandad/pandad_api_impl.cpp",
"output": "/data/openpilot/selfdrive/pandad/pandad_api_impl.o"
},
{
"command": "clang -o selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/acados_solver_lat.os -c -std=gnu11 -DACADOS_WITH_QPOASES -g -fPIC -O2 -Wunused -Werror -Wshadow -Wno-unknown-warning-option -Wno-inconsistent-missing-override -Wno-c99-designator -Wno-reorder-init-list -Wno-vla-cxx-extension -D__TICI__ -mcpu=cortex-a57 -DQCOM2 -Wno-unused -fPIC -I. -Imsgq -Ithird_party -Ithird_party/json11 -Ithird_party/linux/include -Ithird_party/acados/include -Ithird_party/acados/include/blasfeo/include -Ithird_party/acados/include/hpipm/include -Ithird_party/catch2/include -Ithird_party/libyuv/include -Ithird_party/opencl/include selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/acados_solver_lat.c",
"directory": "/data/openpilot",
@@ -605,18 +635,6 @@
"file": "/data/openpilot/selfdrive/modeld/models/commonmodel_pyx.cpp",
"output": "/data/openpilot/selfdrive/modeld/models/commonmodel_pyx.o"
},
{
"command": "clang++ -o sunnypilot/common/transformations/orientation.o -c -std=c++1z -D__TICI__ -mcpu=cortex-a57 -DQCOM2 -g -fPIC -O2 -Wunused -Werror -Wshadow -Wno-unknown-warning-option -Wno-inconsistent-missing-override -Wno-c99-designator -Wno-reorder-init-list -Wno-vla-cxx-extension -D__TICI__ -mcpu=cortex-a57 -DQCOM2 -I. -Imsgq -Ithird_party -Ithird_party/json11 -Ithird_party/linux/include -Ithird_party/acados/include -Ithird_party/acados/include/blasfeo/include -Ithird_party/acados/include/hpipm/include -Ithird_party/catch2/include -Ithird_party/libyuv/include -Ithird_party/opencl/include sunnypilot/common/transformations/orientation.cc",
"directory": "/data/openpilot",
"file": "/data/openpilot/sunnypilot/common/transformations/orientation.cc",
"output": "/data/openpilot/sunnypilot/common/transformations/orientation.o"
},
{
"command": "clang++ -o sunnypilot/common/transformations/coordinates.o -c -std=c++1z -D__TICI__ -mcpu=cortex-a57 -DQCOM2 -g -fPIC -O2 -Wunused -Werror -Wshadow -Wno-unknown-warning-option -Wno-inconsistent-missing-override -Wno-c99-designator -Wno-reorder-init-list -Wno-vla-cxx-extension -D__TICI__ -mcpu=cortex-a57 -DQCOM2 -I. -Imsgq -Ithird_party -Ithird_party/json11 -Ithird_party/linux/include -Ithird_party/acados/include -Ithird_party/acados/include/blasfeo/include -Ithird_party/acados/include/hpipm/include -Ithird_party/catch2/include -Ithird_party/libyuv/include -Ithird_party/opencl/include sunnypilot/common/transformations/coordinates.cc",
"directory": "/data/openpilot",
"file": "/data/openpilot/sunnypilot/common/transformations/coordinates.cc",
"output": "/data/openpilot/sunnypilot/common/transformations/coordinates.o"
},
{
"command": "clang++ -o sunnypilot/modeld/models/commonmodel.o -c -std=c++1z -D__TICI__ -mcpu=cortex-a57 -DQCOM2 -DTRANSFORM_PATH=\\\"/data/openpilot/sunnypilot/modeld/transforms/transform.cl\\\" -DLOADYUV_PATH=\\\"/data/openpilot/sunnypilot/modeld/transforms/loadyuv.cl\\\" -g -fPIC -O2 -Wunused -Werror -Wshadow -Wno-unknown-warning-option -Wno-inconsistent-missing-override -Wno-c99-designator -Wno-reorder-init-list -Wno-vla-cxx-extension -D__TICI__ -mcpu=cortex-a57 -DQCOM2 -I. -Imsgq -Ithird_party -Ithird_party/json11 -Ithird_party/linux/include -Ithird_party/acados/include -Ithird_party/acados/include/blasfeo/include -Ithird_party/acados/include/hpipm/include -Ithird_party/catch2/include -Ithird_party/libyuv/include -Ithird_party/opencl/include sunnypilot/modeld/models/commonmodel.cc",
"directory": "/data/openpilot",
+88 -82
View File
@@ -4,26 +4,28 @@
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.
# 335 Supported Cars
# 341 Supported Cars
|Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Resume from stop|<a href="##"><img width=2000></a>Hardware Needed<br>&nbsp;|Video|Setup Video|
|---|---|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|Acura|ILX 2016-18|Technology Plus Package or AcuraWatch Plus|openpilot|26 mph|25 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura ILX 2016-18">Buy Here</a></sub></details>|||
|Acura|ILX 2019|All|openpilot|26 mph|25 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura ILX 2019">Buy Here</a></sub></details>|||
|Acura|MDX 2025-26|All except Type S|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura MDX 2025-26">Buy Here</a></sub></details>|||
|Acura|MDX 2025|All except Type S|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura MDX 2025">Buy Here</a></sub></details>|||
|Acura|RDX 2016-18|AcuraWatch Plus or Advance Package|openpilot|26 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura RDX 2016-18">Buy Here</a></sub></details>|||
|Acura|RDX 2019-21|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura RDX 2019-21">Buy Here</a></sub></details>|||
|Acura|TLX 2021|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura TLX 2021">Buy Here</a></sub></details>|||
|Acura|TLX 2025|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura TLX 2025">Buy Here</a></sub></details>|||
|Audi|A3 2014-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Audi A3 2014-19">Buy Here</a></sub></details>|||
|Audi|A3 Sportback e-tron 2017-18|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Audi A3 Sportback e-tron 2017-18">Buy Here</a></sub></details>|||
|Audi|Q2 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Audi Q2 2018">Buy Here</a></sub></details>|||
|Audi|Q3 2019-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Audi Q3 2019-24">Buy Here</a></sub></details>|||
|Audi|RS3 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Audi RS3 2018">Buy Here</a></sub></details>|||
|Audi|S3 2015-17|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Audi S3 2015-17">Buy Here</a></sub></details>|||
|Audi|A3 2014-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Audi A3 2014-19">Buy Here</a></sub></details>|||
|Audi|A3 Sportback e-tron 2017-18|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Audi A3 Sportback e-tron 2017-18">Buy Here</a></sub></details>|||
|Audi|Q2 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Audi Q2 2018">Buy Here</a></sub></details>|||
|Audi|Q3 2019-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Audi Q3 2019-24">Buy Here</a></sub></details>|||
|Audi|RS3 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Audi RS3 2018">Buy Here</a></sub></details>|||
|Audi|S3 2015-17|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Audi S3 2015-17">Buy Here</a></sub></details>|||
|Chevrolet|Bolt EUV 2022-23|Premier or Premier Redline Trim, without Super Cruise Package|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Bolt EUV 2022-23">Buy Here</a></sub></details>|<a href="https://youtu.be/xvwzGMUA210" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Chevrolet|Bolt EV 2022-23|2LT Trim with Adaptive Cruise Control Package|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Bolt EV 2022-23">Buy Here</a></sub></details>|||
|Chevrolet|Bolt EV Non-ACC 2017|Adaptive Cruise Control (ACC)|Stock|24 mph|7 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Bolt EV Non-ACC 2017">Buy Here</a></sub></details>|||
|Chevrolet|Bolt EV Non-ACC 2018-21|Adaptive Cruise Control (ACC)|Stock|24 mph|7 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Bolt EV Non-ACC 2018-21">Buy Here</a></sub></details>|||
|Chevrolet|Equinox 2019-22|Adaptive Cruise Control (ACC)|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Equinox 2019-22">Buy Here</a></sub></details>|||
|Chevrolet|Malibu Non-ACC 2016-23|Adaptive Cruise Control (ACC)|Stock|24 mph|7 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Malibu Non-ACC 2016-23">Buy Here</a></sub></details>|||
|Chevrolet|Silverado 1500 2020-21|Safety Package II|openpilot available[<sup>1</sup>](#footnotes)|0 mph|6 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Silverado 1500 2020-21">Buy Here</a></sub></details>|||
|Chevrolet|Trailblazer 2021-22|Adaptive Cruise Control (ACC)|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Trailblazer 2021-22">Buy Here</a></sub></details>|||
|Chrysler|Pacifica 2017-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chrysler Pacifica 2017-18">Buy Here</a></sub></details>|||
@@ -32,33 +34,33 @@ A supported vehicle is one that just works when you install a comma device. All
|Chrysler|Pacifica Hybrid 2017-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chrysler Pacifica Hybrid 2017-18">Buy Here</a></sub></details>|||
|Chrysler|Pacifica Hybrid 2019-25|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chrysler Pacifica Hybrid 2019-25">Buy Here</a></sub></details>|||
|comma|body|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|None|<a href="https://youtu.be/VT-i3yRsX2s?t=2736" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|CUPRA|Ateca 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=CUPRA Ateca 2018-23">Buy Here</a></sub></details>|||
|CUPRA|Ateca 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=CUPRA Ateca 2018-23">Buy Here</a></sub></details>|||
|Dodge|Durango 2020-21|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Dodge Durango 2020-21">Buy Here</a></sub></details>|||
|Ford|Bronco Sport 2021-24|Co-Pilot360 Assist+|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Bronco Sport 2021-24">Buy Here</a></sub></details>|||
|Ford|Escape 2020-22|Co-Pilot360 Assist+|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Escape 2020-22">Buy Here</a></sub></details>|||
|Ford|Escape 2023-24|Co-Pilot360 Assist+|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Escape 2023-24">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Ford|Escape 2023-24|Co-Pilot360 Assist+|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Escape 2023-24">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Ford|Escape Hybrid 2020-22|Co-Pilot360 Assist+|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Escape Hybrid 2020-22">Buy Here</a></sub></details>|||
|Ford|Escape Hybrid 2023-24|Co-Pilot360 Assist+|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Escape Hybrid 2023-24">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Ford|Escape Hybrid 2023-24|Co-Pilot360 Assist+|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Escape Hybrid 2023-24">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Ford|Escape Plug-in Hybrid 2020-22|Co-Pilot360 Assist+|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Escape Plug-in Hybrid 2020-22">Buy Here</a></sub></details>|||
|Ford|Escape Plug-in Hybrid 2023-24|Co-Pilot360 Assist+|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Escape Plug-in Hybrid 2023-24">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Ford|Expedition 2022-24|Co-Pilot360 Assist 2.0|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Expedition 2022-24">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=MewJc9LYp9M" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Ford|Escape Plug-in Hybrid 2023-24|Co-Pilot360 Assist+|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Escape Plug-in Hybrid 2023-24">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Ford|Expedition 2022-24|Co-Pilot360 Assist 2.0|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Expedition 2022-24">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=MewJc9LYp9M" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Ford|Explorer 2020-24|Co-Pilot360 Assist+|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Explorer 2020-24">Buy Here</a></sub></details>|||
|Ford|Explorer Hybrid 2020-24|Co-Pilot360 Assist+|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Explorer Hybrid 2020-24">Buy Here</a></sub></details>|||
|Ford|F-150 2021-23|Co-Pilot360 Assist 2.0|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford F-150 2021-23">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=MewJc9LYp9M" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Ford|F-150 Hybrid 2021-23|Co-Pilot360 Assist 2.0|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford F-150 Hybrid 2021-23">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=MewJc9LYp9M" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Ford|F-150 2021-23|Co-Pilot360 Assist 2.0|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford F-150 2021-23">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=MewJc9LYp9M" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Ford|F-150 Hybrid 2021-23|Co-Pilot360 Assist 2.0|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford F-150 Hybrid 2021-23">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=MewJc9LYp9M" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Ford|Focus 2018[<sup>2</sup>](#footnotes)|Adaptive Cruise Control with Lane Centering|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Focus 2018">Buy Here</a></sub></details>|||
|Ford|Focus Hybrid 2018[<sup>2</sup>](#footnotes)|Adaptive Cruise Control with Lane Centering|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Focus Hybrid 2018">Buy Here</a></sub></details>|||
|Ford|Kuga 2020-23|Adaptive Cruise Control with Lane Centering|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Kuga 2020-23">Buy Here</a></sub></details>|||
|Ford|Kuga Hybrid 2020-23|Adaptive Cruise Control with Lane Centering|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Kuga Hybrid 2020-23">Buy Here</a></sub></details>|||
|Ford|Kuga Hybrid 2024|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Kuga Hybrid 2024">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Ford|Kuga Hybrid 2024|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Kuga Hybrid 2024">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Ford|Kuga Plug-in Hybrid 2020-23|Adaptive Cruise Control with Lane Centering|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Kuga Plug-in Hybrid 2020-23">Buy Here</a></sub></details>|||
|Ford|Kuga Plug-in Hybrid 2024|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Kuga Plug-in Hybrid 2024">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Ford|Kuga Plug-in Hybrid 2024|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Kuga Plug-in Hybrid 2024">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Ford|Maverick 2022|LARIAT Luxury|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Maverick 2022">Buy Here</a></sub></details>|||
|Ford|Maverick 2023-24|Co-Pilot360 Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Maverick 2023-24">Buy Here</a></sub></details>|||
|Ford|Maverick Hybrid 2022|LARIAT Luxury|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Maverick Hybrid 2022">Buy Here</a></sub></details>|||
|Ford|Maverick Hybrid 2023-24|Co-Pilot360 Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Maverick Hybrid 2023-24">Buy Here</a></sub></details>|||
|Ford|Mustang Mach-E 2021-24|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Mustang Mach-E 2021-24">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Ford|Ranger 2024|Adaptive Cruise Control with Lane Centering|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Ranger 2024">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Ford|Mustang Mach-E 2021-24|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Mustang Mach-E 2021-24">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Ford|Ranger 2024|Adaptive Cruise Control with Lane Centering|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Ranger 2024">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Genesis|G70 2018|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai F connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis G70 2018">Buy Here</a></sub></details>|||
|Genesis|G70 2019-21|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai F connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis G70 2019-21">Buy Here</a></sub></details>|||
|Genesis|G70 2022-23|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai L connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis G70 2022-23">Buy Here</a></sub></details>|||
@@ -88,11 +90,12 @@ A supported vehicle is one that just works when you install a comma device. All
|Honda|Civic Hatchback Hybrid 2025-26|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Civic Hatchback Hybrid 2025-26">Buy Here</a></sub></details>|||
|Honda|Civic Hatchback Hybrid (Europe only) 2023|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Civic Hatchback Hybrid (Europe only) 2023">Buy Here</a></sub></details>|||
|Honda|Civic Hybrid 2025-26|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Civic Hybrid 2025-26">Buy Here</a></sub></details>|||
|Honda|Clarity 2018-21|Honda Sensing|openpilot|0 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector + Honda Clarity Proxy Board<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://shop.retropilot.org/product/honda-clarity-proxy-board-kit">Buy Here</a></sub></details>|||
|Honda|CR-V 2015-16|Touring Trim|openpilot|26 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda CR-V 2015-16">Buy Here</a></sub></details>|||
|Honda|CR-V 2017-22|Honda Sensing|openpilot available[<sup>1</sup>](#footnotes)|0 mph|15 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda CR-V 2017-22">Buy Here</a></sub></details>|||
|Honda|CR-V 2023-26|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda CR-V 2023-26">Buy Here</a></sub></details>|||
|Honda|CR-V Hybrid 2017-22|Honda Sensing|openpilot available[<sup>1</sup>](#footnotes)|0 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda CR-V Hybrid 2017-22">Buy Here</a></sub></details>|||
|Honda|CR-V Hybrid 2023-26|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda CR-V Hybrid 2023-26">Buy Here</a></sub></details>|||
|Honda|CR-V Hybrid 2023-25|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda CR-V Hybrid 2023-25">Buy Here</a></sub></details>|||
|Honda|e 2020|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda e 2020">Buy Here</a></sub></details>|||
|Honda|Fit 2018-20|Honda Sensing|openpilot|26 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Fit 2018-20">Buy Here</a></sub></details>|||
|Honda|Freed 2020|Honda Sensing|openpilot|26 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Freed 2020">Buy Here</a></sub></details>|||
@@ -103,7 +106,6 @@ A supported vehicle is one that just works when you install a comma device. All
|Honda|N-Box 2018|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|11 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda N-Box 2018">Buy Here</a></sub></details>|||
|Honda|Odyssey 2018-20|Honda Sensing|openpilot|26 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Odyssey 2018-20">Buy Here</a></sub></details>|||
|Honda|Odyssey 2021-26|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|43 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Odyssey 2021-26">Buy Here</a></sub></details>|||
|Honda|Odyssey (Taiwan) 2018-19|Honda Sensing|openpilot|19 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Odyssey (Taiwan) 2018-19">Buy Here</a></sub></details>|||
|Honda|Passport 2019-25|All|openpilot|26 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Passport 2019-25">Buy Here</a></sub></details>|||
|Honda|Passport 2026|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Passport 2026">Buy Here</a></sub></details>|||
|Honda|Pilot 2016-22|Honda Sensing|openpilot|26 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Pilot 2016-22">Buy Here</a></sub></details>|||
@@ -118,6 +120,7 @@ A supported vehicle is one that just works when you install a comma device. All
|Hyundai|Elantra 2021-23|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Elantra 2021-23">Buy Here</a></sub></details>|<a href="https://youtu.be/_EdYQtV52-c" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Hyundai|Elantra GT 2017-20|Smart Cruise Control (SCC)|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai E connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Elantra GT 2017-20">Buy Here</a></sub></details>|||
|Hyundai|Elantra Hybrid 2021-23|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Elantra Hybrid 2021-23">Buy Here</a></sub></details>|<a href="https://youtu.be/_EdYQtV52-c" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Hyundai|Elantra Non-SCC 2022|No Smart Cruise Control (Non-SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Elantra Non-SCC 2022">Buy Here</a></sub></details>|||
|Hyundai|Genesis 2015-16|Smart Cruise Control (SCC)|Stock|19 mph|37 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai J connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Genesis 2015-16">Buy Here</a></sub></details>|||
|Hyundai|i30 2017-19|Smart Cruise Control (SCC)|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai E connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai i30 2017-19">Buy Here</a></sub></details>|||
|Hyundai|Ioniq 5 (Southeast Asia and Europe only) 2022-24|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai Q connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Ioniq 5 (Southeast Asia and Europe only) 2022-24">Buy Here</a></sub></details>|||
@@ -135,7 +138,9 @@ A supported vehicle is one that just works when you install a comma device. All
|Hyundai|Kona Electric 2018-21|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai G connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Kona Electric 2018-21">Buy Here</a></sub></details>|||
|Hyundai|Kona Electric 2022-23|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai O connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Kona Electric 2022-23">Buy Here</a></sub></details>|||
|Hyundai|Kona Electric (with HDA II, Korea only) 2023|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai R connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Kona Electric (with HDA II, Korea only) 2023">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=U2fOCmcQ8hw" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Hyundai|Kona Electric Non-SCC 2019|No Smart Cruise Control (Non-SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai G connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Kona Electric Non-SCC 2019">Buy Here</a></sub></details>|||
|Hyundai|Kona Hybrid 2020|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai I connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Kona Hybrid 2020">Buy Here</a></sub></details>|||
|Hyundai|Kona Non-SCC 2019|No Smart Cruise Control (Non-SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Kona Non-SCC 2019">Buy Here</a></sub></details>|||
|Hyundai|Nexo 2021|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai H connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Nexo 2021">Buy Here</a></sub></details>|||
|Hyundai|Palisade 2020-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai H connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Palisade 2020-22">Buy Here</a></sub></details>|<a href="https://youtu.be/TAnDqjF4fDY?t=456" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Hyundai|Santa Cruz 2022-24|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai N connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Santa Cruz 2022-24">Buy Here</a></sub></details>|||
@@ -159,11 +164,13 @@ A supported vehicle is one that just works when you install a comma device. All
|Kia|Carnival 2022-24|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Carnival 2022-24">Buy Here</a></sub></details>|||
|Kia|Carnival (China only) 2023|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Carnival (China only) 2023">Buy Here</a></sub></details>|||
|Kia|Ceed 2019-21|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai E connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Ceed 2019-21">Buy Here</a></sub></details>|||
|Kia|Ceed Plug-in Hybrid Non-SCC 2022|No Smart Cruise Control (Non-SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai I connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Ceed Plug-in Hybrid Non-SCC 2022">Buy Here</a></sub></details>|||
|Kia|EV6 (Southeast Asia only) 2022-24|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai P connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia EV6 (Southeast Asia only) 2022-24">Buy Here</a></sub></details>|||
|Kia|EV6 (with HDA II) 2022-24|Highway Driving Assist II|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai P connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia EV6 (with HDA II) 2022-24">Buy Here</a></sub></details>|||
|Kia|EV6 (without HDA II) 2022-24|Highway Driving Assist|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai L connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia EV6 (without HDA II) 2022-24">Buy Here</a></sub></details>|||
|Kia|Forte 2019-21|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|6 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai G connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Forte 2019-21">Buy Here</a></sub></details>|||
|Kia|Forte 2022-23|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai E connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Forte 2022-23">Buy Here</a></sub></details>|||
|Kia|Forte Non-SCC 2019|No Smart Cruise Control (Non-SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai G connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Forte Non-SCC 2019">Buy Here</a></sub></details>|||
|Kia|K5 2021-24|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia K5 2021-24">Buy Here</a></sub></details>|||
|Kia|K5 Hybrid 2020-22|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia K5 Hybrid 2020-22">Buy Here</a></sub></details>|||
|Kia|K8 Hybrid (with HDA II) 2023|Highway Driving Assist II|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai Q connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia K8 Hybrid (with HDA II) 2023">Buy Here</a></sub></details>|||
@@ -204,7 +211,6 @@ A supported vehicle is one that just works when you install a comma device. All
|Lexus|IS 2017-19|All|Stock|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Lexus IS 2017-19">Buy Here</a></sub></details>|||
|Lexus|IS 2022-24|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Lexus IS 2022-24">Buy Here</a></sub></details>|||
|Lexus|LC 2024-25|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Lexus LC 2024-25">Buy Here</a></sub></details>|||
|Lexus|LS 2018|All except Lexus Safety System+ A|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Lexus LS 2018">Buy Here</a></sub></details>|||
|Lexus|NX 2018-19|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Lexus NX 2018-19">Buy Here</a></sub></details>|||
|Lexus|NX 2020-21|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Lexus NX 2020-21">Buy Here</a></sub></details>|||
|Lexus|NX Hybrid 2018-19|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Lexus NX Hybrid 2018-19">Buy Here</a></sub></details>|||
@@ -220,21 +226,21 @@ A supported vehicle is one that just works when you install a comma device. All
|Lexus|UX Hybrid 2019-24|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Lexus UX Hybrid 2019-24">Buy Here</a></sub></details>|||
|Lincoln|Aviator 2020-24|Co-Pilot360 Plus|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Lincoln Aviator 2020-24">Buy Here</a></sub></details>|||
|Lincoln|Aviator Plug-in Hybrid 2020-24|Co-Pilot360 Plus|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Lincoln Aviator Plug-in Hybrid 2020-24">Buy Here</a></sub></details>|||
|MAN|eTGE 2020-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=MAN eTGE 2020-24">Buy Here</a></sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|MAN|TGE 2017-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=MAN TGE 2017-24">Buy Here</a></sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|MAN|eTGE 2020-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=MAN eTGE 2020-24">Buy Here</a></sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|MAN|TGE 2017-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=MAN TGE 2017-24">Buy Here</a></sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Mazda|CX-5 2022-25|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Mazda connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Mazda CX-5 2022-25">Buy Here</a></sub></details>|||
|Mazda|CX-9 2021-23|All|Stock|0 mph|28 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Mazda connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Mazda CX-9 2021-23">Buy Here</a></sub></details>|<a href="https://youtu.be/dA3duO4a0O4" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Nissan[<sup>5</sup>](#footnotes)|Altima 2019-20, 2024|ProPILOT Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 Nissan B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Nissan Altima 2019-20, 2024">Buy Here</a></sub></details>|||
|Nissan[<sup>5</sup>](#footnotes)|Leaf 2018-23|ProPILOT Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 Nissan A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Nissan Leaf 2018-23">Buy Here</a></sub></details>|<a href="https://youtu.be/vaMbtAh_0cY" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Nissan[<sup>5</sup>](#footnotes)|Rogue 2018-20|ProPILOT Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 Nissan A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Nissan Rogue 2018-20">Buy Here</a></sub></details>|||
|Nissan[<sup>5</sup>](#footnotes)|X-Trail 2017|ProPILOT Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 Nissan A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Nissan X-Trail 2017">Buy Here</a></sub></details>|||
|Nissan[<sup>5</sup>](#footnotes)|Altima 2019-20, 2024|ProPILOT Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 Nissan B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Nissan Altima 2019-20, 2024">Buy Here</a></sub></details>|||
|Nissan[<sup>5</sup>](#footnotes)|Leaf 2018-23|ProPILOT Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 Nissan A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Nissan Leaf 2018-23">Buy Here</a></sub></details>|<a href="https://youtu.be/vaMbtAh_0cY" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Nissan[<sup>5</sup>](#footnotes)|Rogue 2018-20|ProPILOT Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 Nissan A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Nissan Rogue 2018-20">Buy Here</a></sub></details>|||
|Nissan[<sup>5</sup>](#footnotes)|X-Trail 2017|ProPILOT Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 Nissan A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Nissan X-Trail 2017">Buy Here</a></sub></details>|||
|Ram|1500 2019-24|Adaptive Cruise Control (ACC)|Stock|32 mph|1 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Ram connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ram 1500 2019-24">Buy Here</a></sub></details>|||
|Ram|2500 2020-24|Adaptive Cruise Control (ACC)|Stock|0 mph|36 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Ram connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ram 2500 2020-24">Buy Here</a></sub></details>|||
|Ram|3500 2019-22|Adaptive Cruise Control (ACC)|Stock|0 mph|36 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Ram connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ram 3500 2019-22">Buy Here</a></sub></details>|||
|Rivian|R1S 2022-24|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Rivian A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Rivian R1S 2022-24">Buy Here</a></sub></details>||<a href="https://youtu.be/uaISd1j7Z4U" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Rivian|R1T 2022-24|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Rivian A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Rivian R1T 2022-24">Buy Here</a></sub></details>||<a href="https://youtu.be/uaISd1j7Z4U" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|SEAT|Ateca 2016-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=SEAT Ateca 2016-23">Buy Here</a></sub></details>|||
|SEAT|Leon 2014-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=SEAT Leon 2014-20">Buy Here</a></sub></details>|||
|Rivian|R1S 2022-24|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Rivian A connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Rivian R1S 2022-24">Buy Here</a></sub></details>||<a href="https://youtu.be/uaISd1j7Z4U" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Rivian|R1T 2022-24|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Rivian A connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Rivian R1T 2022-24">Buy Here</a></sub></details>||<a href="https://youtu.be/uaISd1j7Z4U" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|SEAT|Ateca 2016-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=SEAT Ateca 2016-23">Buy Here</a></sub></details>|||
|SEAT|Leon 2014-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=SEAT Leon 2014-20">Buy Here</a></sub></details>|||
|Subaru|Ascent 2019-21|All[<sup>6</sup>](#footnotes)|openpilot available[<sup>1,7</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru Ascent 2019-21">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|||
|Subaru|Crosstrek 2018-19|EyeSight Driver Assistance[<sup>6</sup>](#footnotes)|openpilot available[<sup>1,7</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru Crosstrek 2018-19">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|<a href="https://youtu.be/Agww7oE1k-s?t=26" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Subaru|Crosstrek 2020-23|EyeSight Driver Assistance[<sup>6</sup>](#footnotes)|openpilot available[<sup>1,7</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru Crosstrek 2020-23">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|||
@@ -249,19 +255,19 @@ A supported vehicle is one that just works when you install a comma device. All
|Subaru|Outback 2020-22|All[<sup>6</sup>](#footnotes)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru B connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru Outback 2020-22">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|||
|Subaru|XV 2018-19|EyeSight Driver Assistance[<sup>6</sup>](#footnotes)|openpilot available[<sup>1,7</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru XV 2018-19">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|<a href="https://youtu.be/Agww7oE1k-s?t=26" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Subaru|XV 2020-21|EyeSight Driver Assistance[<sup>6</sup>](#footnotes)|openpilot available[<sup>1,7</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru XV 2020-21">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|||
|Škoda|Fabia 2022-23[<sup>13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Fabia 2022-23">Buy Here</a></sub></details>[<sup>15</sup>](#footnotes)|||
|Škoda|Kamiq 2021-23[<sup>11,13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Kamiq 2021-23">Buy Here</a></sub></details>[<sup>15</sup>](#footnotes)|||
|Škoda|Karoq 2019-23[<sup>13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Karoq 2019-23">Buy Here</a></sub></details>|||
|Škoda|Kodiaq 2017-23[<sup>13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Kodiaq 2017-23">Buy Here</a></sub></details>|||
|Škoda|Octavia 2015-19[<sup>13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Octavia 2015-19">Buy Here</a></sub></details>|||
|Škoda|Octavia RS 2016[<sup>13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Octavia RS 2016">Buy Here</a></sub></details>|||
|Škoda|Octavia Scout 2017-19[<sup>13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Octavia Scout 2017-19">Buy Here</a></sub></details>|||
|Škoda|Scala 2020-23[<sup>13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Scala 2020-23">Buy Here</a></sub></details>[<sup>15</sup>](#footnotes)|||
|Škoda|Superb 2015-22[<sup>13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Superb 2015-22">Buy Here</a></sub></details>|||
|Tesla[<sup>9</sup>](#footnotes)|Model 3 (with HW3) 2019-23[<sup>8</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Tesla A connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Tesla Model 3 (with HW3) 2019-23">Buy Here</a></sub></details>|||
|Tesla[<sup>9</sup>](#footnotes)|Model 3 (with HW4) 2024-25[<sup>8</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Tesla B connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Tesla Model 3 (with HW4) 2024-25">Buy Here</a></sub></details>|||
|Tesla[<sup>9</sup>](#footnotes)|Model Y (with HW3) 2020-23[<sup>8</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Tesla A connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Tesla Model Y (with HW3) 2020-23">Buy Here</a></sub></details>|||
|Tesla[<sup>9</sup>](#footnotes)|Model Y (with HW4) 2024-25[<sup>8</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Tesla B connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Tesla Model Y (with HW4) 2024-25">Buy Here</a></sub></details>|||
|Škoda|Fabia 2022-23[<sup>13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Fabia 2022-23">Buy Here</a></sub></details>[<sup>15</sup>](#footnotes)|||
|Škoda|Kamiq 2021-23[<sup>11,13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Kamiq 2021-23">Buy Here</a></sub></details>[<sup>15</sup>](#footnotes)|||
|Škoda|Karoq 2019-23[<sup>13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Karoq 2019-23">Buy Here</a></sub></details>|||
|Škoda|Kodiaq 2017-23[<sup>13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Kodiaq 2017-23">Buy Here</a></sub></details>|||
|Škoda|Octavia 2015-19[<sup>13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Octavia 2015-19">Buy Here</a></sub></details>|||
|Škoda|Octavia RS 2016[<sup>13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Octavia RS 2016">Buy Here</a></sub></details>|||
|Škoda|Octavia Scout 2017-19[<sup>13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Octavia Scout 2017-19">Buy Here</a></sub></details>|||
|Škoda|Scala 2020-23[<sup>13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Scala 2020-23">Buy Here</a></sub></details>[<sup>15</sup>](#footnotes)|||
|Škoda|Superb 2015-22[<sup>13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Superb 2015-22">Buy Here</a></sub></details>|||
|Tesla[<sup>9</sup>](#footnotes)|Model 3 (with HW3) 2019-23[<sup>8</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Tesla A connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Tesla Model 3 (with HW3) 2019-23">Buy Here</a></sub></details>|||
|Tesla[<sup>9</sup>](#footnotes)|Model 3 (with HW4) 2024-25[<sup>8</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Tesla B connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Tesla Model 3 (with HW4) 2024-25">Buy Here</a></sub></details>|||
|Tesla[<sup>9</sup>](#footnotes)|Model Y (with HW3) 2020-23[<sup>8</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Tesla A connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Tesla Model Y (with HW3) 2020-23">Buy Here</a></sub></details>|||
|Tesla[<sup>9</sup>](#footnotes)|Model Y (with HW4) 2024-25[<sup>8</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Tesla B connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Tesla Model Y (with HW4) 2024-25">Buy Here</a></sub></details>|||
|Toyota|Alphard 2019-20|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota Alphard 2019-20">Buy Here</a></sub></details>|||
|Toyota|Alphard Hybrid 2021|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota Alphard Hybrid 2021">Buy Here</a></sub></details>|||
|Toyota|Avalon 2016|Toyota Safety Sense P|Stock|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota Avalon 2016">Buy Here</a></sub></details>|||
@@ -307,42 +313,42 @@ A supported vehicle is one that just works when you install a comma device. All
|Toyota|RAV4 Hybrid 2022|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota RAV4 Hybrid 2022">Buy Here</a></sub></details>|<a href="https://youtu.be/U0nH9cnrFB0" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Toyota|RAV4 Hybrid 2023-25|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota RAV4 Hybrid 2023-25">Buy Here</a></sub></details>|<a href="https://youtu.be/4eIsEq4L4Ng" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Toyota|Sienna 2018-20|All|Stock|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota Sienna 2018-20">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=q1UPOo4Sh68" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Volkswagen|Arteon 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Arteon 2018-23">Buy Here</a></sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Volkswagen|Arteon eHybrid 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Arteon eHybrid 2020-23">Buy Here</a></sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Volkswagen|Arteon R 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Arteon R 2020-23">Buy Here</a></sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Volkswagen|Arteon Shooting Brake 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Arteon Shooting Brake 2020-23">Buy Here</a></sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Volkswagen|Atlas 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Atlas 2018-23">Buy Here</a></sub></details>|||
|Volkswagen|Atlas Cross Sport 2020-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Atlas Cross Sport 2020-22">Buy Here</a></sub></details>|||
|Volkswagen|California 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen California 2021-23">Buy Here</a></sub></details>|||
|Volkswagen|Caravelle 2020|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Caravelle 2020">Buy Here</a></sub></details>|||
|Volkswagen|CC 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen CC 2018-22">Buy Here</a></sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Volkswagen|Crafter 2017-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Crafter 2017-24">Buy Here</a></sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Volkswagen|e-Crafter 2018-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen e-Crafter 2018-24">Buy Here</a></sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Volkswagen|e-Golf 2014-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen e-Golf 2014-20">Buy Here</a></sub></details>|||
|Volkswagen|Golf 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf 2015-20">Buy Here</a></sub></details>|||
|Volkswagen|Golf Alltrack 2015-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf Alltrack 2015-19">Buy Here</a></sub></details>|||
|Volkswagen|Golf GTD 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf GTD 2015-20">Buy Here</a></sub></details>|||
|Volkswagen|Golf GTE 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf GTE 2015-20">Buy Here</a></sub></details>|||
|Volkswagen|Golf GTI 2015-21|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf GTI 2015-21">Buy Here</a></sub></details>|||
|Volkswagen|Golf R 2015-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf R 2015-19">Buy Here</a></sub></details>|||
|Volkswagen|Golf SportsVan 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf SportsVan 2015-20">Buy Here</a></sub></details>|||
|Volkswagen|Grand California 2019-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Grand California 2019-24">Buy Here</a></sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Volkswagen|Jetta 2019-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Jetta 2019-23">Buy Here</a></sub></details>|||
|Volkswagen|Jetta GLI 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Jetta GLI 2021-23">Buy Here</a></sub></details>|||
|Volkswagen|Passat 2015-22[<sup>12</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Passat 2015-22">Buy Here</a></sub></details>|||
|Volkswagen|Passat Alltrack 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Passat Alltrack 2015-22">Buy Here</a></sub></details>|||
|Volkswagen|Passat GTE 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Passat GTE 2015-22">Buy Here</a></sub></details>|||
|Volkswagen|Polo 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Polo 2018-23">Buy Here</a></sub></details>[<sup>15</sup>](#footnotes)|||
|Volkswagen|Polo GTI 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Polo GTI 2018-23">Buy Here</a></sub></details>[<sup>15</sup>](#footnotes)|||
|Volkswagen|T-Cross 2021|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen T-Cross 2021">Buy Here</a></sub></details>[<sup>15</sup>](#footnotes)|||
|Volkswagen|T-Roc 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen T-Roc 2018-23">Buy Here</a></sub></details>|||
|Volkswagen|Taos 2022-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Taos 2022-24">Buy Here</a></sub></details>|||
|Volkswagen|Teramont 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Teramont 2018-22">Buy Here</a></sub></details>|||
|Volkswagen|Teramont Cross Sport 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Teramont Cross Sport 2021-22">Buy Here</a></sub></details>|||
|Volkswagen|Teramont X 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Teramont X 2021-22">Buy Here</a></sub></details>|||
|Volkswagen|Tiguan 2018-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Tiguan 2018-24">Buy Here</a></sub></details>|||
|Volkswagen|Tiguan eHybrid 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Tiguan eHybrid 2021-23">Buy Here</a></sub></details>|||
|Volkswagen|Touran 2016-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Touran 2016-23">Buy Here</a></sub></details>|||
|Volkswagen|Arteon 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Arteon 2018-23">Buy Here</a></sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Volkswagen|Arteon eHybrid 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Arteon eHybrid 2020-23">Buy Here</a></sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Volkswagen|Arteon R 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Arteon R 2020-23">Buy Here</a></sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Volkswagen|Arteon Shooting Brake 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Arteon Shooting Brake 2020-23">Buy Here</a></sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Volkswagen|Atlas 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Atlas 2018-23">Buy Here</a></sub></details>|||
|Volkswagen|Atlas Cross Sport 2020-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Atlas Cross Sport 2020-22">Buy Here</a></sub></details>|||
|Volkswagen|California 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen California 2021-23">Buy Here</a></sub></details>|||
|Volkswagen|Caravelle 2020|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Caravelle 2020">Buy Here</a></sub></details>|||
|Volkswagen|CC 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen CC 2018-22">Buy Here</a></sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Volkswagen|Crafter 2017-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Crafter 2017-24">Buy Here</a></sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Volkswagen|e-Crafter 2018-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen e-Crafter 2018-24">Buy Here</a></sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Volkswagen|e-Golf 2014-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen e-Golf 2014-20">Buy Here</a></sub></details>|||
|Volkswagen|Golf 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf 2015-20">Buy Here</a></sub></details>|||
|Volkswagen|Golf Alltrack 2015-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf Alltrack 2015-19">Buy Here</a></sub></details>|||
|Volkswagen|Golf GTD 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf GTD 2015-20">Buy Here</a></sub></details>|||
|Volkswagen|Golf GTE 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf GTE 2015-20">Buy Here</a></sub></details>|||
|Volkswagen|Golf GTI 2015-21|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf GTI 2015-21">Buy Here</a></sub></details>|||
|Volkswagen|Golf R 2015-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf R 2015-19">Buy Here</a></sub></details>|||
|Volkswagen|Golf SportsVan 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf SportsVan 2015-20">Buy Here</a></sub></details>|||
|Volkswagen|Grand California 2019-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Grand California 2019-24">Buy Here</a></sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|Volkswagen|Jetta 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Jetta 2018-23">Buy Here</a></sub></details>|||
|Volkswagen|Jetta GLI 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Jetta GLI 2021-23">Buy Here</a></sub></details>|||
|Volkswagen|Passat 2015-22[<sup>12</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Passat 2015-22">Buy Here</a></sub></details>|||
|Volkswagen|Passat Alltrack 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Passat Alltrack 2015-22">Buy Here</a></sub></details>|||
|Volkswagen|Passat GTE 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Passat GTE 2015-22">Buy Here</a></sub></details>|||
|Volkswagen|Polo 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Polo 2018-23">Buy Here</a></sub></details>[<sup>15</sup>](#footnotes)|||
|Volkswagen|Polo GTI 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Polo GTI 2018-23">Buy Here</a></sub></details>[<sup>15</sup>](#footnotes)|||
|Volkswagen|T-Cross 2021|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen T-Cross 2021">Buy Here</a></sub></details>[<sup>15</sup>](#footnotes)|||
|Volkswagen|T-Roc 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen T-Roc 2018-23">Buy Here</a></sub></details>|||
|Volkswagen|Taos 2022-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Taos 2022-24">Buy Here</a></sub></details>|||
|Volkswagen|Teramont 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Teramont 2018-22">Buy Here</a></sub></details>|||
|Volkswagen|Teramont Cross Sport 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Teramont Cross Sport 2021-22">Buy Here</a></sub></details>|||
|Volkswagen|Teramont X 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Teramont X 2021-22">Buy Here</a></sub></details>|||
|Volkswagen|Tiguan 2018-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Tiguan 2018-24">Buy Here</a></sub></details>|||
|Volkswagen|Tiguan eHybrid 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Tiguan eHybrid 2021-23">Buy Here</a></sub></details>|||
|Volkswagen|Touran 2016-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Touran 2016-23">Buy Here</a></sub></details>|||
### Footnotes
<sup>1</sup>openpilot Longitudinal Control (Alpha) is available behind a toggle; the toggle is only available in non-release branches such as `devel` or `nightly-dev`. <br />
+1 -1
View File
@@ -16,7 +16,7 @@ export VECLIB_MAXIMUM_THREADS=1
export QCOM_PRIORITY=12
if [ -z "$AGNOS_VERSION" ]; then
export AGNOS_VERSION="16"
export AGNOS_VERSION="15.1"
fi
export STAGING_ROOT="/data/safe_staging"
+49
View File
@@ -0,0 +1,49 @@
files: ^msgq/
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: check-ast
- id: check-yaml
- id: check-executables-have-shebangs
- id: check-shebang-scripts-are-executable
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.17.1
hooks:
- id: mypy
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.12.12
hooks:
- id: ruff
- repo: local
hooks:
- id: cppcheck
name: cppcheck
entry: cppcheck
language: system
types: [c++]
exclude: '^(msgq/msgq_tests.cc|msgq/test_runner.cc)'
args:
- --error-exitcode=1
- --inline-suppr
- --language=c++
- --force
- --quiet
- -j4
- --check-level=exhaustive
- repo: https://github.com/cpplint/cpplint
rev: 2.0.2
hooks:
- id: cpplint
args:
- --quiet
- --counting=detailed
- --linelength=240
- --filter=-build,-legal,-readability,-runtime,-whitespace,+build/include_subdir,+build/forward_decl,+build/include_what_you_use,+build/deprecated,+whitespace/comma,+whitespace/line_length,+whitespace/empty_if_body,+whitespace/empty_loop_body,+whitespace/empty_conditional_body,+whitespace/forcolon,+whitespace/parens,+whitespace/semicolon,+whitespace/tab,+readability/braces
- repo: https://github.com/codespell-project/codespell
rev: v2.4.1
hooks:
- id: codespell
args:
- -L ned
- --builtins clear,rare,informal,usage,code,names,en-GB_to_en-US
+1 -1
View File
@@ -1,7 +1,7 @@
# MSGQ: A lock free single producer multi consumer message queue
## What is this library?
MSGQ is a generic high performance IPC pub sub system with a single publisher and multiple subscribers. It uses a ring buffer in shared memory to efficiently read and write data. Each read requires a copy. Writing can be done without a copy, as long as the size of the data is known in advance. This library also provides a spoofed implementation that can be used for deterministic testing, and visionipc, an IPC system specifically for large contiguous buffers (like images/video).
MSGQ is a generic high performance IPC pub sub system with a single publisher and multiple subscribers. MSGQ is designed to be a high performance replacement for ZMQ-like SUB/PUB patterns. It uses a ring buffer in shared memory to efficiently read and write data. Each read requires a copy. Writing can be done without a copy, as long as the size of the data is known in advance. While MSGQ is the core of this library, this library also allows replacing the MSGQ backend with ZMQ or a spoofed implementation that can be used for deterministic testing. This library also contains visionipc, an IPC system specifically for large contiguous buffers (like images/video).
## Storage
The storage for the queue consists of an area of metadata, and the actual buffer. The metadata contains:
-32
View File
@@ -1,32 +0,0 @@
output:
- meta # Print lefthook version
- summary # Print summary block (successful and failed steps)
- empty_summary # Print summary heading when there are no steps to run
- success # Print successful steps
- failure # Print failed steps printing
- execution # Print any execution logs
#- execution_out # Print execution output
#- execution_info # Print `EXECUTE > ...` logging
- skips # Print "skip" (i.e. no files matched)
test:
parallel: true
commands:
# *** static analysis ***
ruff:
run: ruff check .
ty:
run: ty check .
codespell:
run: codespell {files} -L ned,stdio,master --builtin clear,rare,informal,usage,code,names,en-GB_to_en-US -S uv.lock,*_pyx.cpp,catch2*
files: git ls-tree -r HEAD --name-only
cppcheck:
run: cppcheck --error-exitcode=1 --inline-suppr --language=c++ --force --quiet -j4 --check-level=exhaustive $(git ls-files '*.cc' | grep -v -E '(msgq_tests|test_runner)\.cc')
cpplint:
run: cpplint --exclude=msgq/catch2/ --exclude=msgq/ipc_pyx.cpp --exclude=msgq/visionipc/visionipc_pyx.cpp --recursive --quiet --counting=detailed --linelength=240 --filter=-build,-legal,-readability,-runtime,-whitespace,+build/include_subdir,+build/forward_decl,+build/include_what_you_use,+build/deprecated,+whitespace/comma,+whitespace/line_length,+whitespace/empty_if_body,+whitespace/empty_loop_body,+whitespace/empty_conditional_body,+whitespace/forcolon,+whitespace/parens,+whitespace/semicolon,+whitespace/tab,+readability/braces msgq/
# *** tests ***
test_runner:
run: msgq/test_runner
pytest:
run: pytest
+4 -4
View File
@@ -3,7 +3,7 @@ from msgq.ipc_pyx import Context, Poller, SubSocket, PubSocket, SocketEventHandl
set_fake_prefix, get_fake_prefix, delete_fake_prefix, wait_for_one_event
from msgq.ipc_pyx import MultiplePublishersError, IpcError
from typing import Optional, List, Union
from typing import Optional, List
assert MultiplePublishersError
assert IpcError
@@ -18,9 +18,9 @@ NO_TRAVERSAL_LIMIT = 2**64-1
context = Context()
def fake_event_handle(endpoint: str, identifier: Optional[Union[str, bytes]] = None, override: bool = True, enable: bool = False) -> SocketEventHandle:
ident = identifier if identifier is not None else get_fake_prefix()
handle = SocketEventHandle(endpoint, ident, override)
def fake_event_handle(endpoint: str, identifier: Optional[str] = None, override: bool = True, enable: bool = False) -> SocketEventHandle:
identifier = identifier or get_fake_prefix()
handle = SocketEventHandle(endpoint, identifier, override)
if override:
handle.enabled = enable
-6
View File
@@ -1,6 +0,0 @@
import pytest
import msgq
@pytest.fixture(autouse=True)
def msgq_context():
msgq.context = msgq.Context()
+25 -14
View File
@@ -8,30 +8,36 @@
#include "msgq/impl_msgq.h"
void Message::init(size_t sz) {
MSGQContext::MSGQContext() {
}
MSGQContext::~MSGQContext() {
}
void MSGQMessage::init(size_t sz) {
size = sz;
data = new char[size];
}
void Message::init(char * d, size_t sz) {
void MSGQMessage::init(char * d, size_t sz) {
size = sz;
data = new char[size];
memcpy(data, d, size);
}
void Message::takeOwnership(char * d, size_t sz) {
void MSGQMessage::takeOwnership(char * d, size_t sz) {
size = sz;
data = d;
}
void Message::close() {
void MSGQMessage::close() {
if (size > 0){
delete[] data;
}
size = 0;
}
Message::~Message() {
MSGQMessage::~MSGQMessage() {
this->close();
}
@@ -61,7 +67,7 @@ int MSGQSubSocket::connect(Context *context, std::string endpoint, std::string a
Message * MSGQSubSocket::receive(bool non_blocking){
msgq_msg_t msg;
Message *r = NULL;
MSGQMessage *r = NULL;
int rc = msgq_msg_recv(&msg, q);
@@ -86,11 +92,11 @@ Message * MSGQSubSocket::receive(bool non_blocking){
}
if (rc > 0){
r = new Message;
r = new MSGQMessage;
r->takeOwnership(msg.data, msg.size);
}
return r;
return (Message*)r;
}
void MSGQSubSocket::setTimeout(int t){
@@ -104,9 +110,14 @@ MSGQSubSocket::~MSGQSubSocket(){
}
}
int PubSocket::connect(Context *context, std::string endpoint, bool check_endpoint, size_t segment_size){
int MSGQPubSocket::connect(Context *context, std::string endpoint, bool check_endpoint, size_t segment_size){
assert(context);
// TODO
//if (check_endpoint && !service_exists(std::string(endpoint))){
// std::cout << "Warning, " << std::string(endpoint) << " is not in service list." << std::endl;
//}
q = new msgq_queue_t;
size_t size = segment_size > 0 ? segment_size : DEFAULT_SEGMENT_SIZE;
int r = msgq_new_queue(q, endpoint.c_str(), size);
@@ -119,7 +130,7 @@ int PubSocket::connect(Context *context, std::string endpoint, bool check_endpoi
return 0;
}
int PubSocket::sendMessage(Message *message){
int MSGQPubSocket::sendMessage(Message *message){
msgq_msg_t msg;
msg.data = message->getData();
msg.size = message->getSize();
@@ -127,7 +138,7 @@ int PubSocket::sendMessage(Message *message){
return msgq_msg_send(&msg, q);
}
int PubSocket::send(char *data, size_t size){
int MSGQPubSocket::send(char *data, size_t size){
msgq_msg_t msg;
msg.data = data;
msg.size = size;
@@ -135,11 +146,11 @@ int PubSocket::send(char *data, size_t size){
return msgq_msg_send(&msg, q);
}
bool PubSocket::all_readers_updated() {
bool MSGQPubSocket::all_readers_updated() {
return msgq_all_readers_updated(q);
}
PubSocket::~PubSocket(){
MSGQPubSocket::~MSGQPubSocket(){
if (q != NULL){
msgq_close_queue(q);
delete q;
@@ -149,7 +160,7 @@ PubSocket::~PubSocket(){
void MSGQPoller::registerSocket(SubSocket * socket){
assert(num_polls + 1 < MAX_POLLERS);
polls[num_polls].q = static_cast<MSGQSubSocket*>(socket)->getQueue();
polls[num_polls].q = (msgq_queue_t*)socket->getRawSocket();
sockets.push_back(socket);
num_polls++;
+35 -1
View File
@@ -8,6 +8,29 @@
#define MAX_POLLERS 128
class MSGQContext : public Context {
private:
void * context = NULL;
public:
MSGQContext();
void * getRawContext() {return context;}
~MSGQContext();
};
class MSGQMessage : public Message {
private:
char * data;
size_t size;
public:
void init(size_t size);
void init(char *data, size_t size);
void takeOwnership(char *data, size_t size);
size_t getSize(){return size;}
char * getData(){return data;}
void close();
~MSGQMessage();
};
class MSGQSubSocket : public SubSocket {
private:
msgq_queue_t * q = NULL;
@@ -15,11 +38,22 @@ private:
public:
int connect(Context *context, std::string endpoint, std::string address, bool conflate=false, bool check_endpoint=true, size_t segment_size=0);
void setTimeout(int timeout);
msgq_queue_t * getQueue() {return q;}
void * getRawSocket() {return (void*)q;}
Message *receive(bool non_blocking=false);
~MSGQSubSocket();
};
class MSGQPubSocket : public PubSocket {
private:
msgq_queue_t * q = NULL;
public:
int connect(Context *context, std::string endpoint, bool check_endpoint=true, size_t segment_size=0);
int sendMessage(Message *message);
int send(char *data, size_t size);
bool all_readers_updated();
~MSGQPubSocket();
};
class MSGQPoller : public Poller {
private:
std::vector<SubSocket*> sockets;
+179
View File
@@ -0,0 +1,179 @@
#include <cassert>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <cerrno>
#include <unistd.h>
#include <string>
#include <vector>
#include "msgq/impl_zmq.h"
static size_t fnv1a_hash(const std::string &str) {
const size_t fnv_prime = 0x100000001b3;
size_t hash_value = 0xcbf29ce484222325;
for (char c : str) {
hash_value ^= (unsigned char)c;
hash_value *= fnv_prime;
}
return hash_value;
}
//FIXME: This is a hack to get the port number from the socket name, might have collisions
static int get_port(std::string endpoint) {
size_t hash_value = fnv1a_hash(endpoint);
int start_port = 8023;
int max_port = 65535;
int port = start_port + (hash_value % (max_port - start_port));
return port;
}
ZMQContext::ZMQContext() {
context = zmq_ctx_new();
}
ZMQContext::~ZMQContext() {
zmq_ctx_term(context);
}
void ZMQMessage::init(size_t sz) {
size = sz;
data = new char[size];
}
void ZMQMessage::init(char * d, size_t sz) {
size = sz;
data = new char[size];
memcpy(data, d, size);
}
void ZMQMessage::close() {
if (size > 0){
delete[] data;
}
size = 0;
}
ZMQMessage::~ZMQMessage() {
this->close();
}
int ZMQSubSocket::connect(Context *context, std::string endpoint, std::string address, bool conflate, bool check_endpoint, size_t segment_size){
sock = zmq_socket(context->getRawContext(), ZMQ_SUB);
if (sock == NULL){
return -1;
}
zmq_setsockopt(sock, ZMQ_SUBSCRIBE, "", 0);
if (conflate){
int arg = 1;
zmq_setsockopt(sock, ZMQ_CONFLATE, &arg, sizeof(int));
}
int reconnect_ivl = 500;
zmq_setsockopt(sock, ZMQ_RECONNECT_IVL_MAX, &reconnect_ivl, sizeof(reconnect_ivl));
full_endpoint = "tcp://" + address + ":";
if (check_endpoint){
full_endpoint += std::to_string(get_port(endpoint));
} else {
full_endpoint += endpoint;
}
return zmq_connect(sock, full_endpoint.c_str());
}
Message * ZMQSubSocket::receive(bool non_blocking){
zmq_msg_t msg;
assert(zmq_msg_init(&msg) == 0);
int flags = non_blocking ? ZMQ_DONTWAIT : 0;
int rc = zmq_msg_recv(&msg, sock, flags);
Message *r = NULL;
if (rc >= 0){
// Make a copy to ensure the data is aligned
r = new ZMQMessage;
r->init((char*)zmq_msg_data(&msg), zmq_msg_size(&msg));
}
zmq_msg_close(&msg);
return r;
}
void ZMQSubSocket::setTimeout(int timeout){
zmq_setsockopt(sock, ZMQ_RCVTIMEO, &timeout, sizeof(int));
}
ZMQSubSocket::~ZMQSubSocket(){
zmq_close(sock);
}
int ZMQPubSocket::connect(Context *context, std::string endpoint, bool check_endpoint, size_t segment_size){
sock = zmq_socket(context->getRawContext(), ZMQ_PUB);
if (sock == NULL){
return -1;
}
full_endpoint = "tcp://*:";
if (check_endpoint){
full_endpoint += std::to_string(get_port(endpoint));
} else {
full_endpoint += endpoint;
}
// ZMQ pub sockets cannot be shared between processes, so we need to ensure pid stays the same
pid = getpid();
return zmq_bind(sock, full_endpoint.c_str());
}
int ZMQPubSocket::sendMessage(Message *message) {
assert(pid == getpid());
return zmq_send(sock, message->getData(), message->getSize(), ZMQ_DONTWAIT);
}
int ZMQPubSocket::send(char *data, size_t size) {
assert(pid == getpid());
return zmq_send(sock, data, size, ZMQ_DONTWAIT);
}
bool ZMQPubSocket::all_readers_updated() {
assert(false); // TODO not implemented
return false;
}
ZMQPubSocket::~ZMQPubSocket(){
zmq_close(sock);
}
void ZMQPoller::registerSocket(SubSocket * socket){
assert(num_polls + 1 < MAX_POLLERS);
polls[num_polls].socket = socket->getRawSocket();
polls[num_polls].events = ZMQ_POLLIN;
sockets.push_back(socket);
num_polls++;
}
std::vector<SubSocket*> ZMQPoller::poll(int timeout){
std::vector<SubSocket*> r;
int rc = zmq_poll(polls, num_polls, timeout);
if (rc < 0){
return r;
}
for (size_t i = 0; i < num_polls; i++){
if (polls[i].revents){
r.push_back(sockets[i]);
}
}
return r;
}
+68
View File
@@ -0,0 +1,68 @@
#pragma once
#include <zmq.h>
#include <string>
#include <vector>
#include "msgq/ipc.h"
#define MAX_POLLERS 128
class ZMQContext : public Context {
private:
void * context = NULL;
public:
ZMQContext();
void * getRawContext() {return context;}
~ZMQContext();
};
class ZMQMessage : public Message {
private:
char * data;
size_t size;
public:
void init(size_t size);
void init(char *data, size_t size);
size_t getSize(){return size;}
char * getData(){return data;}
void close();
~ZMQMessage();
};
class ZMQSubSocket : public SubSocket {
private:
void * sock;
std::string full_endpoint;
public:
int connect(Context *context, std::string endpoint, std::string address, bool conflate=false, bool check_endpoint=true, size_t segment_size=0);
void setTimeout(int timeout);
void * getRawSocket() {return sock;}
Message *receive(bool non_blocking=false);
~ZMQSubSocket();
};
class ZMQPubSocket : public PubSocket {
private:
void * sock;
std::string full_endpoint;
int pid = -1;
public:
int connect(Context *context, std::string endpoint, bool check_endpoint=true, size_t segment_size=0);
int sendMessage(Message *message);
int send(char *data, size_t size);
bool all_readers_updated();
~ZMQPubSocket();
};
class ZMQPoller : public Poller {
private:
std::vector<SubSocket*> sockets;
zmq_pollitem_t polls[MAX_POLLERS];
size_t num_polls = 0;
public:
void registerSocket(SubSocket *socket);
std::vector<SubSocket*> poll(int timeout);
~ZMQPoller(){}
};
+56 -6
View File
@@ -3,23 +3,59 @@
#include <string>
#include "msgq/ipc.h"
#include "msgq/impl_zmq.h"
#include "msgq/impl_msgq.h"
#include "msgq/impl_fake.h"
#ifdef __APPLE__
const bool MUST_USE_ZMQ = true;
#else
const bool MUST_USE_ZMQ = false;
#endif
bool messaging_use_zmq(){
if (std::getenv("ZMQ") || MUST_USE_ZMQ) {
if (std::getenv("OPENPILOT_PREFIX")) {
std::cerr << "OPENPILOT_PREFIX not supported with ZMQ backend\n";
assert(false);
}
return true;
}
return false;
}
bool messaging_use_fake(){
char* fake_enabled = std::getenv("CEREAL_FAKE");
return fake_enabled != NULL;
}
Context * Context::create(){
return new Context();
Context * c;
if (messaging_use_zmq()){
c = new ZMQContext();
} else {
c = new MSGQContext();
}
return c;
}
SubSocket * SubSocket::create(){
SubSocket * s;
if (messaging_use_fake()) {
return new FakeSubSocket<MSGQSubSocket>();
if (messaging_use_zmq()) {
s = new FakeSubSocket<ZMQSubSocket>();
} else {
s = new FakeSubSocket<MSGQSubSocket>();
}
} else {
if (messaging_use_zmq()){
s = new ZMQSubSocket();
} else {
s = new MSGQSubSocket();
}
}
return new MSGQSubSocket();
return s;
}
SubSocket * SubSocket::create(Context * context, std::string endpoint, std::string address, bool conflate, bool check_endpoint, size_t segment_size){
@@ -37,7 +73,14 @@ SubSocket * SubSocket::create(Context * context, std::string endpoint, std::stri
}
PubSocket * PubSocket::create(){
return new PubSocket();
PubSocket * s;
if (messaging_use_zmq()){
s = new ZMQPubSocket();
} else {
s = new MSGQPubSocket();
}
return s;
}
PubSocket * PubSocket::create(Context * context, std::string endpoint, bool check_endpoint, size_t segment_size){
@@ -55,10 +98,17 @@ PubSocket * PubSocket::create(Context * context, std::string endpoint, bool chec
}
Poller * Poller::create(){
Poller * p;
if (messaging_use_fake()) {
return new FakePoller();
p = new FakePoller();
} else {
if (messaging_use_zmq()){
p = new ZMQPoller();
} else {
p = new MSGQPoller();
}
}
return new MSGQPoller();
return p;
}
Poller * Poller::create(std::vector<SubSocket*> sockets){
+17 -19
View File
@@ -15,24 +15,23 @@
#define MSG_MULTIPLE_PUBLISHERS 100
bool messaging_use_zmq();
class Context {
public:
virtual void * getRawContext() = 0;
static Context * create();
~Context(){}
virtual ~Context(){}
};
class Message {
private:
char * data = nullptr;
size_t size = 0;
public:
void init(size_t size);
void init(char * data, size_t size);
void takeOwnership(char * data, size_t size);
void close();
size_t getSize(){return size;}
char * getData(){return data;}
~Message();
virtual void init(size_t size) = 0;
virtual void init(char * data, size_t size) = 0;
virtual void close() = 0;
virtual size_t getSize() = 0;
virtual char * getData() = 0;
virtual ~Message(){}
};
@@ -41,22 +40,21 @@ public:
virtual int connect(Context *context, std::string endpoint, std::string address, bool conflate=false, bool check_endpoint=true, size_t segment_size=0) = 0;
virtual void setTimeout(int timeout) = 0;
virtual Message *receive(bool non_blocking=false) = 0;
virtual void * getRawSocket() = 0;
static SubSocket * create();
static SubSocket * create(Context * context, std::string endpoint, std::string address="127.0.0.1", bool conflate=false, bool check_endpoint=true, size_t segment_size=0);
virtual ~SubSocket(){}
};
class PubSocket {
private:
struct msgq_queue_t * q = nullptr;
public:
int connect(Context *context, std::string endpoint, bool check_endpoint=true, size_t segment_size=0);
int sendMessage(Message *message);
int send(char *data, size_t size);
bool all_readers_updated();
virtual int connect(Context *context, std::string endpoint, bool check_endpoint=true, size_t segment_size=0) = 0;
virtual int sendMessage(Message *message) = 0;
virtual int send(char *data, size_t size) = 0;
virtual bool all_readers_updated() = 0;
static PubSocket * create();
static PubSocket * create(Context * context, std::string endpoint, bool check_endpoint=true, size_t segment_size=0);
~PubSocket();
virtual ~PubSocket(){}
};
class Poller {
@@ -66,4 +64,4 @@ public:
static Poller * create();
static Poller * create(std::vector<SubSocket*> sockets);
virtual ~Poller(){}
};
};
Binary file not shown.
+7 -36
View File
@@ -87,16 +87,12 @@ int msgq_new_queue(msgq_queue_t * q, const char * path, size_t size){
assert(size < 0xFFFFFFFF); // Buffer must be smaller than 2^32 bytes
std::signal(SIGUSR2, sigusr2_handler);
#ifdef __APPLE__
std::string base_path = "/tmp/msgq_";
#else
std::string base_path = "/dev/shm/msgq_";
#endif
std::string full_path = "/dev/shm/msgq_";
const char* prefix = std::getenv("OPENPILOT_PREFIX");
if (prefix) {
base_path += std::string(prefix) + "/";
full_path += std::string(prefix) + "/";
}
std::string full_path = base_path + path;
full_path += path;
auto fd = open(full_path.c_str(), O_RDWR | O_CREAT, 0664);
if (fd < 0) {
@@ -172,11 +168,8 @@ void msgq_init_publisher(msgq_queue_t * q) {
}
static void thread_signal(uint32_t tid) {
#ifdef __APPLE__
// macOS doesn't have tkill, rely on polling instead
(void)tid;
#elif !defined(SYS_tkill)
// fallback for systems without tkill
#ifndef SYS_tkill
// TODO: this won't work for multithreaded programs
kill(tid, SIGUSR2);
#else
syscall(SYS_tkill, tid, SIGUSR2);
@@ -446,18 +439,9 @@ int msgq_poll(msgq_pollitem_t * items, size_t nitems, int timeout){
}
int ms = (timeout == -1) ? 100 : timeout;
#ifdef __APPLE__
// On macOS, signals can't interrupt nanosleep, so poll more frequently
int poll_ms = std::min(ms, 10);
int remaining_ms = ms;
#else
int poll_ms = ms;
#endif
struct timespec ts;
ts.tv_sec = poll_ms / 1000;
ts.tv_nsec = (poll_ms % 1000) * 1000 * 1000;
ts.tv_sec = ms / 1000;
ts.tv_nsec = (ms % 1000) * 1000 * 1000;
while (num == 0) {
@@ -473,23 +457,10 @@ int msgq_poll(msgq_pollitem_t * items, size_t nitems, int timeout){
}
}
#ifdef __APPLE__
// exit if we had a timeout and we've exhausted it
if (timeout != -1 && ret == 0){
remaining_ms -= poll_ms;
if (remaining_ms <= 0){
break;
}
poll_ms = std::min(remaining_ms, 10);
ts.tv_sec = poll_ms / 1000;
ts.tv_nsec = (poll_ms % 1000) * 1000 * 1000;
}
#else
// exit if we had a timeout and the sleep finished
if (timeout != -1 && ret == 0){
break;
}
#endif
}
return num;
+11 -19
View File
@@ -1,14 +1,6 @@
#include "catch2/catch.hpp"
#include "msgq/msgq.h"
static void cleanup_test_queue() {
#ifdef __APPLE__
remove("/tmp/msgq_test_queue");
#else
remove("/dev/shm/msgq_test_queue");
#endif
}
TEST_CASE("ALIGN")
{
REQUIRE(ALIGN(0) == 0);
@@ -51,7 +43,7 @@ TEST_CASE("msgq_msg_init_data")
TEST_CASE("msgq_init_subscriber")
{
cleanup_test_queue();
remove("/dev/shm/msgq_test_queue");
msgq_queue_t q;
msgq_new_queue(&q, "test_queue", 1024);
REQUIRE(*q.num_readers == 0);
@@ -71,7 +63,7 @@ TEST_CASE("msgq_init_subscriber")
TEST_CASE("msgq_msg_send first message")
{
cleanup_test_queue();
remove("/dev/shm/msgq_test_queue");
msgq_queue_t q;
msgq_new_queue(&q, "test_queue", 1024);
msgq_init_publisher(&q);
@@ -108,7 +100,7 @@ TEST_CASE("msgq_msg_send first message")
TEST_CASE("msgq_msg_send test wraparound")
{
cleanup_test_queue();
remove("/dev/shm/msgq_test_queue");
msgq_queue_t q;
msgq_new_queue(&q, "test_queue", 1024);
msgq_init_publisher(&q);
@@ -140,7 +132,7 @@ TEST_CASE("msgq_msg_send test wraparound")
TEST_CASE("msgq_msg_recv test wraparound")
{
cleanup_test_queue();
remove("/dev/shm/msgq_test_queue");
msgq_queue_t q_pub, q_sub;
msgq_new_queue(&q_pub, "test_queue", 1024);
msgq_new_queue(&q_sub, "test_queue", 1024);
@@ -186,7 +178,7 @@ TEST_CASE("msgq_msg_recv test wraparound")
TEST_CASE("msgq_msg_send test invalidation")
{
cleanup_test_queue();
remove("/dev/shm/msgq_test_queue");
msgq_queue_t q_pub, q_sub;
msgq_new_queue(&q_pub, "test_queue", 1024);
msgq_new_queue(&q_sub, "test_queue", 1024);
@@ -222,7 +214,7 @@ TEST_CASE("msgq_msg_send test invalidation")
TEST_CASE("msgq_init_subscriber init 2 subscribers")
{
cleanup_test_queue();
remove("/dev/shm/msgq_test_queue");
msgq_queue_t q1, q2;
msgq_new_queue(&q1, "test_queue", 1024);
msgq_new_queue(&q2, "test_queue", 1024);
@@ -245,7 +237,7 @@ TEST_CASE("msgq_init_subscriber init 2 subscribers")
TEST_CASE("Write 1 msg, read 1 msg", "[integration]")
{
cleanup_test_queue();
remove("/dev/shm/msgq_test_queue");
const size_t msg_size = 128;
msgq_queue_t writer, reader;
@@ -281,7 +273,7 @@ TEST_CASE("Write 1 msg, read 1 msg", "[integration]")
TEST_CASE("Write 2 msg, read 2 msg - conflate = false", "[integration]")
{
cleanup_test_queue();
remove("/dev/shm/msgq_test_queue");
const size_t msg_size = 128;
msgq_queue_t writer, reader;
@@ -318,7 +310,7 @@ TEST_CASE("Write 2 msg, read 2 msg - conflate = false", "[integration]")
TEST_CASE("Write 2 msg, read 2 msg - conflate = true", "[integration]")
{
cleanup_test_queue();
remove("/dev/shm/msgq_test_queue");
const size_t msg_size = 128;
msgq_queue_t writer, reader;
@@ -356,7 +348,7 @@ TEST_CASE("Write 2 msg, read 2 msg - conflate = true", "[integration]")
TEST_CASE("1 publisher, 1 slow subscriber", "[integration]")
{
cleanup_test_queue();
remove("/dev/shm/msgq_test_queue");
msgq_queue_t writer, reader;
msgq_new_queue(&writer, "test_queue", 1024);
@@ -399,7 +391,7 @@ TEST_CASE("1 publisher, 1 slow subscriber", "[integration]")
TEST_CASE("1 publisher, 2 subscribers", "[integration]")
{
cleanup_test_queue();
remove("/dev/shm/msgq_test_queue");
msgq_queue_t writer, reader1, reader2;
msgq_new_queue(&writer, "test_queue", 1024);
+2
View File
@@ -1,4 +1,5 @@
import pytest
import os
import multiprocessing
import platform
import msgq
@@ -63,6 +64,7 @@ class TestEvents:
@pytest.mark.skipif(condition=platform.system() == "Darwin", reason="FakeSockets not supported on macOS")
@pytest.mark.skipif(condition="ZMQ" in os.environ, reason="FakeSockets not supported on ZMQ")
@parameterized_class([{"prefix": None}, {"prefix": "test"}])
class TestFakeSockets:
prefix: Optional[str] = None
+37 -22
View File
@@ -1,3 +1,4 @@
import os
import random
import time
import string
@@ -10,12 +11,22 @@ def random_sock():
def random_bytes(length=1000):
return bytes([random.randrange(0xFF) for _ in range(length)])
def zmq_sleep(t=1):
if "ZMQ" in os.environ:
time.sleep(t)
class TestPubSubSockets:
def setup_method(self):
# ZMQ pub socket takes too long to die
# sleep to prevent multiple publishers error between tests
zmq_sleep()
def test_pub_sub(self):
sock = random_sock()
pub_sock = msgq.pub_sock(sock)
sub_sock = msgq.sub_sock(sock, conflate=False, timeout=None)
zmq_sleep(3)
for _ in range(1000):
msg = random_bytes()
@@ -27,31 +38,35 @@ class TestPubSubSockets:
sock = random_sock()
pub_sock = msgq.pub_sock(sock)
for conflate in [True, False]:
num_msgs = random.randint(3, 10)
sub_sock = msgq.sub_sock(sock, conflate=conflate, timeout=None)
for _ in range(10):
num_msgs = random.randint(3, 10)
sub_sock = msgq.sub_sock(sock, conflate=conflate, timeout=None)
zmq_sleep()
sent_msgs = []
for __ in range(num_msgs):
msg = random_bytes()
pub_sock.send(msg)
sent_msgs.append(msg)
time.sleep(0.1)
recvd_msgs = msgq.drain_sock_raw(sub_sock)
if conflate:
assert len(recvd_msgs) == 1
assert recvd_msgs[0] == sent_msgs[-1]
else:
assert len(recvd_msgs) == len(sent_msgs)
for rec_msg, sent_msg in zip(recvd_msgs, sent_msgs):
assert rec_msg == sent_msg
sent_msgs = []
for __ in range(num_msgs):
msg = random_bytes()
pub_sock.send(msg)
sent_msgs.append(msg)
time.sleep(0.1)
recvd_msgs = msgq.drain_sock_raw(sub_sock)
if conflate:
assert len(recvd_msgs) == 1
assert recvd_msgs[0] == sent_msgs[-1]
else:
assert len(recvd_msgs) == len(sent_msgs)
for rec_msg, sent_msg in zip(recvd_msgs, sent_msgs):
assert rec_msg == sent_msg
@pytest.mark.flaky(retries=3, delay=1)
def test_receive_timeout(self):
sock = random_sock()
timeout = random.randrange(200)
sub_sock = msgq.sub_sock(sock, timeout=timeout)
for _ in range(10):
timeout = random.randrange(200)
sub_sock = msgq.sub_sock(sock, timeout=timeout)
zmq_sleep()
start_time = time.monotonic()
recvd = sub_sock.receive()
assert (time.monotonic() - start_time) < (timeout + 0.1)
assert recvd is None
start_time = time.monotonic()
recvd = sub_sock.receive()
assert (time.monotonic() - start_time) < 0.2
assert recvd is None
+1 -1
View File
@@ -111,7 +111,7 @@ class TestPoller:
msg_seen = True
i += 1
if r is None and msg_seen:
if r is None and msg_seen: # ZMQ sometimes receives nothing on the first receive
break
del pub
@@ -1,12 +1,15 @@
import os
import time
import random
from typing import Optional
import numpy as np
from msgq.visionipc import VisionIpcServer, VisionIpcClient, VisionStreamType
def zmq_sleep(t=1):
if "ZMQ" in os.environ:
time.sleep(t)
class TestVisionIpc:
server: VisionIpcServer
client: Optional[VisionIpcClient]
def setup_vipc(self, name, *stream_types, num_buffers=1, width=100, height=100, conflate=False):
self.server = VisionIpcServer(name)
@@ -20,11 +23,11 @@ class TestVisionIpc:
else:
self.client = None
zmq_sleep()
return self.server, self.client
def test_connect(self):
self.setup_vipc("camerad", VisionStreamType.VISION_STREAM_ROAD)
assert self.client is not None
assert self.client.is_connected
del self.client
del self.server
@@ -41,18 +44,16 @@ class TestVisionIpc:
def test_buffers(self):
width, height, num_buffers = 100, 200, 5
self.setup_vipc("camerad", VisionStreamType.VISION_STREAM_ROAD, num_buffers=num_buffers, width=width, height=height)
assert self.client is not None
assert self.client.width == width
assert self.client.height == height
assert self.client.buffer_len is not None and self.client.buffer_len > 0
assert self.client.buffer_len > 0
assert self.client.num_buffers == num_buffers
del self.client
del self.server
def test_send_single_buffer(self):
self.setup_vipc("camerad", VisionStreamType.VISION_STREAM_ROAD)
assert self.client is not None
assert self.client.buffer_len is not None
buf = np.zeros(self.client.buffer_len, dtype=np.uint8)
buf.view('<i4')[0] = 1234
self.server.send(VisionStreamType.VISION_STREAM_ROAD, buf, frame_id=1337)
@@ -66,8 +67,7 @@ class TestVisionIpc:
def test_no_conflate(self):
self.setup_vipc("camerad", VisionStreamType.VISION_STREAM_ROAD)
assert self.client is not None
assert self.client.buffer_len is not None
buf = np.zeros(self.client.buffer_len, dtype=np.uint8)
self.server.send(VisionStreamType.VISION_STREAM_ROAD, buf, frame_id=1)
self.server.send(VisionStreamType.VISION_STREAM_ROAD, buf, frame_id=2)
@@ -84,8 +84,7 @@ class TestVisionIpc:
def test_conflate(self):
self.setup_vipc("camerad", VisionStreamType.VISION_STREAM_ROAD, conflate=True)
assert self.client is not None
assert self.client.buffer_len is not None
buf = np.zeros(self.client.buffer_len, dtype=np.uint8)
self.server.send(VisionStreamType.VISION_STREAM_ROAD, buf, frame_id=1)
self.server.send(VisionStreamType.VISION_STREAM_ROAD, buf, frame_id=2)
+2 -2
View File
@@ -52,8 +52,8 @@ bool VisionIpcClient::connect(bool blocking) {
assert(r == sizeof(type));
// Get FDs
int fds[VISIONIPC_MAX_FDS] = {};
VisionBuf bufs[VISIONIPC_MAX_FDS] = {};
int fds[VISIONIPC_MAX_FDS];
VisionBuf bufs[VISIONIPC_MAX_FDS];
r = ipc_sendrecv_with_fds(false, socket_fd, &bufs, sizeof(bufs), fds, VISIONIPC_MAX_FDS, &num_buffers);
if (r < 0) {
// only expected error is server shutting down
Binary file not shown.
+12 -5
View File
@@ -10,12 +10,18 @@
#include <sys/socket.h>
#include <unistd.h>
#include "msgq/ipc.h"
#include "msgq/visionipc/visionipc.h"
#include "msgq/visionipc/visionipc_server.h"
#include "msgq/logger/logger.h"
std::string get_endpoint_name(std::string name, VisionStreamType type){
return "visionipc_" + name + "_" + std::to_string(type);
if (messaging_use_zmq()){
assert(name == "camerad" || name == "navd");
return std::to_string(9000 + static_cast<int>(type));
} else {
return "visionipc_" + name + "_" + std::to_string(type);
}
}
std::string get_ipc_path(const std::string& name) {
@@ -67,6 +73,7 @@ void VisionIpcServer::create_buffers_with_sizes(VisionStreamType type, size_t nu
cur_idx[type] = 0;
// Create msgq publisher for each of the `name` + type combos
// TODO: compute port number directly if using zmq
sockets[type] = PubSocket::create(msg_ctx, get_endpoint_name(name, type), false);
}
@@ -77,7 +84,7 @@ void VisionIpcServer::start_listener(){
void VisionIpcServer::listener(){
LOGD("Starting listener for: %s", name.c_str());
std::cout << "Starting listener for: " << name << std::endl;
const std::string ipc_path = get_ipc_path(name);
int sock = ipc_bind(ipc_path.c_str());
@@ -127,9 +134,9 @@ void VisionIpcServer::listener(){
continue;
}
int fds[VISIONIPC_MAX_FDS] = {};
int fds[VISIONIPC_MAX_FDS];
int num_fds = buffers[type].size();
VisionBuf bufs[VISIONIPC_MAX_FDS] = {};
VisionBuf bufs[VISIONIPC_MAX_FDS];
for (int i = 0; i < num_fds; i++){
fds[i] = buffers[type][i]->fd;
@@ -148,7 +155,7 @@ void VisionIpcServer::listener(){
close(fd);
}
LOGD("Stopping listener for: %s", name.c_str());
std::cout << "Stopping listener for: " << name << std::endl;
close(sock);
unlink(ipc_path.c_str());
}
@@ -1,9 +1,18 @@
#include <thread>
#include <chrono>
#include "catch2/catch.hpp"
#include "msgq/visionipc/visionipc_server.h"
#include "msgq/visionipc/visionipc_client.h"
static void zmq_sleep(int milliseconds=1000){
if (messaging_use_zmq()){
std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds));
}
}
TEST_CASE("Connecting"){
VisionIpcServer server("camerad");
server.create_buffers(VISION_STREAM_ROAD, 1, 100, 100);
@@ -48,6 +57,8 @@ TEST_CASE("Send single buffer"){
VisionIpcClient client = VisionIpcClient("camerad", VISION_STREAM_ROAD, false);
REQUIRE(client.connect());
zmq_sleep();
VisionBuf * buf = server.get_buffer(VISION_STREAM_ROAD);
REQUIRE(buf != nullptr);
@@ -75,6 +86,8 @@ TEST_CASE("Test no conflate"){
VisionIpcClient client = VisionIpcClient("camerad", VISION_STREAM_ROAD, false);
REQUIRE(client.connect());
zmq_sleep();
VisionBuf * buf = server.get_buffer(VISION_STREAM_ROAD);
REQUIRE(buf != nullptr);
@@ -101,6 +114,8 @@ TEST_CASE("Test conflate"){
VisionIpcClient client = VisionIpcClient("camerad", VISION_STREAM_ROAD, true);
REQUIRE(client.connect());
zmq_sleep();
VisionBuf * buf = server.get_buffer(VISION_STREAM_ROAD);
REQUIRE(buf != nullptr);
+12 -9
View File
@@ -15,6 +15,7 @@ dependencies = [
"setuptools", # for distutils
"Cython",
"scons",
"pre-commit",
"ruff",
"parameterized",
"coverage",
@@ -22,10 +23,6 @@ dependencies = [
"pytest",
"pytest-retry",
"cppcheck",
"cpplint",
"codespell",
"ty",
"lefthook",
]
# https://beta.ruff.rs/docs/configuration/#using-pyprojecttoml
@@ -41,12 +38,18 @@ target-version="py311"
"pytest.main".msg = "pytest.main requires special handling that is easy to mess up!"
"unittest".msg = "Use pytest"
[tool.ty.src]
exclude = ["site_scons/"]
[tool.mypy]
# third-party packages
ignore_missing_imports=true
[tool.ty.rules]
# Cython modules are compiled at build time, not available for static analysis
unresolved-import = "ignore"
# helpful warnings
warn_redundant_casts=true
warn_unreachable=true
warn_unused_ignores=true
# restrict dynamic typing
warn_return_any=true
check_untyped_defs=true
[tool.pytest.ini_options]
addopts = "--durations=10"
+5 -4
View File
@@ -8,10 +8,10 @@ PLATFORM=$(uname -s)
echo "installing dependencies"
if [[ $PLATFORM == "Darwin" ]]; then
if ! command -v python3 &>/dev/null; then
export HOMEBREW_NO_AUTO_UPDATE=1
brew install python3
fi
export ZMQ=1
export HOMEBREW_NO_AUTO_UPDATE=1
brew install python3 zeromq
elif [[ $PLATFORM == "Linux" ]]; then
# for AGNOS since we clear the apt lists
if [[ ! -d /"var/lib/apt/" ]]; then
@@ -20,6 +20,7 @@ elif [[ $PLATFORM == "Linux" ]]; then
sudo apt-get install -y --no-install-recommends \
curl ca-certificates \
libzmq3-dev \
ocl-icd-opencl-dev opencl-headers \
python3-dev python3-pip python3-venv
else
+8 -7
View File
@@ -1,18 +1,19 @@
#!/bin/bash
#!/usr/bin/env bash
set -e
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
cd $DIR
# *** env setup ***
source ./setup.sh
# *** build ***
scons -j8
# *** lint + test ***
lefthook run test
# *** lint ***
#ruff check .
#mypy python/
pre-commit run --all-files
# *** all done ***
GREEN='\033[0;32m'
NC='\033[0m'
printf "\n${GREEN}All good!${NC} Finished build, lint, and test in ${SECONDS}s\n"
# *** test ***
pytest
+2 -1
View File
@@ -1,5 +1,6 @@
.cache/
/build/
.mypy_cache/
*.pyc
*.os
*.o
@@ -17,6 +18,7 @@
*.gcno
*.dump
*.gcov
uv.lock
/dist/
.vscode/
__pycache__/
@@ -31,4 +33,3 @@ cppcheck-addon-ctu-file-list
opendbc/safety/tests/coverage-out
compile_commands.json
.mull/
+1 -1
View File
@@ -138,7 +138,7 @@ The above tests are themselves tested by:
* a [mutation test](opendbc/safety/tests/misra/test_mutation.py) on the MISRA coverage
* 100% line coverage enforced on the safety unit tests
In addition, we run the [ruff linter](https://github.com/astral-sh/ruff) and [ty](https://github.com/astral-sh/ty) on the car interface library.
In addition, we run the [ruff linter](https://github.com/astral-sh/ruff) and [mypy](https://mypy-lang.org/) on the car interface library.
### Bounties
+29 -62
View File
@@ -1,18 +1,16 @@
<!--- AUTOGENERATED FROM selfdrive/car/CARS_template.md, DO NOT EDIT. --->
# Support Information for 410 Known Cars
# Support Information for 384 Known Cars
|Make|Model|Package|Support Level|
|---|---|---|:---:|
|Acura|ADX 2025-26|All|[Community](#community)|
|Acura|ILX 2016-18|Technology Plus Package or AcuraWatch Plus|[Upstream](#upstream)|
|Acura|ILX 2019|All|[Upstream](#upstream)|
|Acura|Integra 2023-25|All|[Community](#community)|
|Acura|MDX 2015-16|Advance Package|[Community](#community)|
|Acura|MDX 2017-20|All|[Community](#community)|
|Acura|MDX 2022-24|All|[Community](#community)|
|Acura|MDX 2025-26|All except Type S|[Upstream](#upstream)|
|Acura|MDX Hybrid 2017-20|All|[Community](#community)|
|Acura|MDX 2025|All except Type S|[Upstream](#upstream)|
|Acura|RDX 2016-18|AcuraWatch Plus or Advance Package|[Upstream](#upstream)|
|Acura|RDX 2019-21|All|[Upstream](#upstream)|
|Acura|RDX 2022-25|All|[Community](#community)|
@@ -21,7 +19,6 @@
|Acura|TLX 2018-20|All|[Community](#community)|
|Acura|TLX 2021|All|[Upstream](#upstream)|
|Acura|TLX 2022-23|All|[Community](#community)|
|Acura|TLX 2025|All|[Upstream](#upstream)|
|Acura|ZDX 2024|All|[Not compatible](#can-bus-security)|
|Audi|A3 2014-19|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|Audi|A3 Sportback e-tron 2017-18|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
@@ -32,21 +29,11 @@
|Audi|Q5 2017-24|All|[Not compatible](#flexray)|
|Audi|RS3 2018|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|Audi|S3 2015-17|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|Cadillac|CT6 Non-ACC 2017-18|No Adaptive Cruise Control (Non-ACC)|[Dashcam mode](#dashcam)|
|Cadillac|XT5 Non-ACC 2018|No Adaptive Cruise Control (Non-ACC)|[Dashcam mode](#dashcam)|
|Chevrolet|Bolt EUV 2022-23|Premier or Premier Redline Trim, without Super Cruise Package|[Upstream](#upstream)|
|Chevrolet|Bolt EUV LT Non-ACC 2022-23|No Adaptive Cruise Control (Non-ACC)|[Community](community)|
|Chevrolet|Bolt EV 2022-23|2LT Trim with Adaptive Cruise Control Package|[Upstream](#upstream)|
|Chevrolet|Bolt EV LT Non-ACC 2022-23|No Adaptive Cruise Control (Non-ACC)|[Community](community)|
|Chevrolet|Bolt EV Non-ACC 2017|No Adaptive Cruise Control (Non-ACC)|[Community](community)|
|Chevrolet|Bolt EV Non-ACC 2018-21|No Adaptive Cruise Control (Non-ACC)|[Community](community)|
|Chevrolet|Equinox 2019-22|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|Chevrolet|Equinox Non-ACC 2019-22|No Adaptive Cruise Control (Non-ACC)|[Community](community)|
|Chevrolet|Malibu Non-ACC 2016-23|No Adaptive Cruise Control (Non-ACC)|[Community](community)|
|Chevrolet|Silverado 1500 2020-21|Safety Package II|[Upstream](#upstream)|
|Chevrolet|Suburban Non-ACC 2016-20|No Adaptive Cruise Control (Non-ACC)|[Dashcam mode](#dashcam)|
|Chevrolet|Trailblazer 2021-22|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|Chevrolet|Trailblazer Non-ACC 2021-22|No Adaptive Cruise Control (Non-ACC)|[Dashcam mode](#dashcam)|
|Chrysler|Pacifica 2017-18|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|Chrysler|Pacifica 2019-20|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|Chrysler|Pacifica 2021-23|All|[Upstream](#upstream)|
@@ -83,7 +70,6 @@
|Genesis|G70 2018|All|[Upstream](#upstream)|
|Genesis|G70 2019-21|All|[Upstream](#upstream)|
|Genesis|G70 2022-23|All|[Upstream](#upstream)|
|Genesis|G70 Non-SCC 2021|No Smart Cruise Control (Non-SCC)|[Dashcam mode](#dashcam)|
|Genesis|G80 2017|All|[Upstream](#upstream)|
|Genesis|G80 2018-19|All|[Upstream](#upstream)|
|Genesis|G80 (2.5T Advanced Trim, with HDA II) 2024|Highway Driving Assist II|[Upstream](#upstream)|
@@ -100,7 +86,6 @@
|Honda|Accord 2016-17|Honda Sensing|[Community](#community)|
|Honda|Accord 2018-22|All|[Upstream](#upstream)|
|Honda|Accord 2023-25|All|[Upstream](#upstream)|
|Honda|Accord Hybrid 2017|All|[Community](#community)|
|Honda|Accord Hybrid 2018-22|All|[Upstream](#upstream)|
|Honda|Accord Hybrid 2023-25|All|[Upstream](#upstream)|
|Honda|City (Brazil only) 2023|All|[Upstream](#upstream)|
@@ -113,13 +98,12 @@
|Honda|Civic Hatchback Hybrid 2025-26|All|[Upstream](#upstream)|
|Honda|Civic Hatchback Hybrid (Europe only) 2023|All|[Upstream](#upstream)|
|Honda|Civic Hybrid 2025-26|All|[Upstream](#upstream)|
|Honda|Clarity 2018-21|Honda Sensing|[Community](community)|
|Honda|Clarity 2018-21|All|[Community](#community)|
|Honda|CR-V 2015-16|Touring Trim|[Upstream](#upstream)|
|Honda|CR-V 2017-22|Honda Sensing|[Upstream](#upstream)|
|Honda|CR-V 2023-26|All|[Upstream](#upstream)|
|Honda|CR-V Hybrid 2017-22|Honda Sensing|[Upstream](#upstream)|
|Honda|CR-V Hybrid 2023-26|All|[Upstream](#upstream)|
|Honda|CR-V Hybrid 2023-25|All|[Upstream](#upstream)|
|Honda|e 2020|All|[Upstream](#upstream)|
|Honda|Fit 2018-20|Honda Sensing|[Upstream](#upstream)|
|Honda|Freed 2020|Honda Sensing|[Upstream](#upstream)|
@@ -130,7 +114,6 @@
|Honda|N-Box 2018|All|[Upstream](#upstream)|
|Honda|Odyssey 2018-20|Honda Sensing|[Upstream](#upstream)|
|Honda|Odyssey 2021-26|All|[Upstream](#upstream)|
|Honda|Odyssey (Taiwan) 2018-19|Honda Sensing|[Upstream](#upstream)|
|Honda|Passport 2019-25|All|[Upstream](#upstream)|
|Honda|Passport 2026|All|[Upstream](#upstream)|
|Honda|Pilot 2016-22|Honda Sensing|[Upstream](#upstream)|
@@ -140,14 +123,12 @@
|Hyundai|Azera 2022|All|[Upstream](#upstream)|
|Hyundai|Azera Hybrid 2019|All|[Upstream](#upstream)|
|Hyundai|Azera Hybrid 2020|All|[Upstream](#upstream)|
|Hyundai|Bayon Non-SCC 2021|No Smart Cruise Control (Non-SCC)|[Dashcam mode](#dashcam)|
|Hyundai|Custin 2023|All|[Upstream](#upstream)|
|Hyundai|Elantra 2017-18|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|Hyundai|Elantra 2019|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|Hyundai|Elantra 2021-23|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|Hyundai|Elantra GT 2017-20|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|Hyundai|Elantra Hybrid 2021-23|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|Hyundai|Elantra Non-SCC 2022|No Smart Cruise Control (Non-SCC)|[Community](community)|
|Hyundai|Genesis 2015-16|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|Hyundai|i30 2017-19|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|Hyundai|Ioniq 5 (Southeast Asia and Europe only) 2022-24|All|[Upstream](#upstream)|
@@ -161,16 +142,14 @@
|Hyundai|Ioniq Plug-in Hybrid 2019|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|Hyundai|Ioniq Plug-in Hybrid 2020-22|All|[Upstream](#upstream)|
|Hyundai|Kona 2020|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|Hyundai|Kona 2022-23|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|Hyundai|Kona 2022-23|Smart Cruise Control (SCC)|[Dashcam mode](#dashcam)|
|Hyundai|Kona Electric 2018-21|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|Hyundai|Kona Electric 2022-23|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|Hyundai|Kona Electric (with HDA II, Korea only) 2023|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|Hyundai|Kona Electric Non-SCC 2019|No Smart Cruise Control (Non-SCC)|[Community](community)|
|Hyundai|Kona Hybrid 2020|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|Hyundai|Kona Non-SCC 2019|No Smart Cruise Control (Non-SCC)|[Community](community)|
|Hyundai|Nexo 2021|All|[Upstream](#upstream)|
|Hyundai|Palisade 2020-22|All|[Upstream](#upstream)|
|Hyundai|Palisade 2023-24|Highway Driving Assist II|[Community](#community)|
|Hyundai|Palisade 2023-24|HDA2|[Community](#community)|
|Hyundai|Santa Cruz 2022-24|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|Hyundai|Santa Fe 2019-20|All|[Upstream](#upstream)|
|Hyundai|Santa Fe 2021-23|All|[Upstream](#upstream)|
@@ -192,14 +171,11 @@
|Kia|Carnival 2022-24|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|Kia|Carnival (China only) 2023|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|Kia|Ceed 2019-21|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|Kia|Ceed Plug-in Hybrid Non-SCC 2022|No Smart Cruise Control (Non-SCC)|[Community](community)|
|Kia|EV6 (Southeast Asia only) 2022-24|All|[Upstream](#upstream)|
|Kia|EV6 (with HDA II) 2022-24|Highway Driving Assist II|[Upstream](#upstream)|
|Kia|EV6 (without HDA II) 2022-24|Highway Driving Assist|[Upstream](#upstream)|
|Kia|Forte 2019-21|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|Kia|Forte 2022-23|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|Kia|Forte Non-SCC 2019|No Smart Cruise Control (Non-SCC)|[Community](community)|
|Kia|Forte Non-SCC 2021|No Smart Cruise Control (Non-SCC)|[Dashcam mode](#dashcam)|
|Kia|K5 2021-24|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|Kia|K5 Hybrid 2020-22|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|Kia|K8 Hybrid (with HDA II) 2023|Highway Driving Assist II|[Upstream](#upstream)|
@@ -222,7 +198,6 @@
|Kia|Optima Hybrid 2017|Advanced Smart Cruise Control|[Dashcam mode](#dashcam)|
|Kia|Optima Hybrid 2019|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|Kia|Seltos 2021|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|Kia|Seltos Non-SCC 2023-24|No Smart Cruise Control (Non-SCC)|[Dashcam mode](#dashcam)|
|Kia|Sorento 2018|Advanced Smart Cruise Control & LKAS|[Upstream](#upstream)|
|Kia|Sorento 2019|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|Kia|Sorento 2021-23|Smart Cruise Control (SCC)|[Upstream](#upstream)|
@@ -233,7 +208,7 @@
|Kia|Stinger 2018-20|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|Kia|Stinger 2022-23|All|[Upstream](#upstream)|
|Kia|Telluride 2020-22|All|[Upstream](#upstream)|
|Kia|Telluride 2023-24|Highway Driving Assist II|[Community](#community)|
|Kia|Telluride 2023-24|HDA2|[Community](#community)|
|Lexus|CT Hybrid 2017-18|Lexus Safety System+|[Upstream](#upstream)|
|Lexus|ES 2017-18|All|[Upstream](#upstream)|
|Lexus|ES 2019-25|All|[Upstream](#upstream)|
@@ -243,8 +218,7 @@
|Lexus|IS 2017-19|All|[Upstream](#upstream)|
|Lexus|IS 2022-24|All|[Upstream](#upstream)|
|Lexus|LC 2024-25|All|[Upstream](#upstream)|
|Lexus|LS 2018|All except Lexus Safety System+ A|[Upstream](#upstream)|
|Lexus|NS 2022-25|All|[Not compatible](#can-bus-security)|
|Lexus|NS 2022-25|Any|[Not compatible](#can-bus-security)|
|Lexus|NX 2018-19|All|[Upstream](#upstream)|
|Lexus|NX 2020-21|All|[Upstream](#upstream)|
|Lexus|NX Hybrid 2018-19|All|[Upstream](#upstream)|
@@ -275,8 +249,8 @@
|Peugeot|208 2019-25|Adaptive Cruise Control (ACC) & Lane Assist|[Dashcam mode](#dashcam)|
|Porsche|Macan 2017-24|Adaptive Cruise Control (ACC) & Lane Assist|[Dashcam mode](#dashcam)|
|Ram|1500 2019-24|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|Ram|2500 2020-24|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|Ram|3500 2019-22|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|Ram|2500 2020-24|Adaptive Cruise Control (ACC)|[Dashcam mode](#dashcam)|
|Ram|3500 2019-22|Adaptive Cruise Control (ACC)|[Dashcam mode](#dashcam)|
|Rivian|R1S 2022-24|All|[Upstream](#upstream)|
|Rivian|R1T 2022-24|All|[Upstream](#upstream)|
|SEAT|Alhambra 2018-20|Adaptive Cruise Control (ACC) & Lane Assist|[Dashcam mode](#dashcam)|
@@ -287,19 +261,19 @@
|Subaru|Crosstrek 2018-19|EyeSight Driver Assistance|[Upstream](#upstream)|
|Subaru|Crosstrek 2020-23|EyeSight Driver Assistance|[Upstream](#upstream)|
|Subaru|Crosstrek Hybrid 2020|EyeSight Driver Assistance|[Dashcam mode](#dashcam)|
|Subaru|Forester 2017-18|EyeSight Driver Assistance|[Upstream](#upstream)|
|Subaru|Forester 2017-18|EyeSight Driver Assistance|[Dashcam mode](#dashcam)|
|Subaru|Forester 2019-21|All|[Upstream](#upstream)|
|Subaru|Forester 2022-24|All|[Dashcam mode](#dashcam)|
|Subaru|Forester Hybrid 2020|EyeSight Driver Assistance|[Dashcam mode](#dashcam)|
|Subaru|Impreza 2017-19|EyeSight Driver Assistance|[Upstream](#upstream)|
|Subaru|Impreza 2020-22|EyeSight Driver Assistance|[Upstream](#upstream)|
|Subaru|Legacy 2015-18|EyeSight Driver Assistance|[Upstream](#upstream)|
|Subaru|Legacy 2015-18|EyeSight Driver Assistance|[Dashcam mode](#dashcam)|
|Subaru|Legacy 2020-22|All|[Upstream](#upstream)|
|Subaru|Outback 2015-17|EyeSight Driver Assistance|[Upstream](#upstream)|
|Subaru|Outback 2018-19|EyeSight Driver Assistance|[Upstream](#upstream)|
|Subaru|Outback 2015-17|EyeSight Driver Assistance|[Dashcam mode](#dashcam)|
|Subaru|Outback 2018-19|EyeSight Driver Assistance|[Dashcam mode](#dashcam)|
|Subaru|Outback 2020-22|All|[Upstream](#upstream)|
|Subaru|Outback 2023|All|[Dashcam mode](#dashcam)|
|Subaru|Solterra 2023-25|All|[Not compatible](#can-bus-security)|
|Subaru|Solterra 2023-25|Any|[Not compatible](#can-bus-security)|
|Subaru|XV 2018-19|EyeSight Driver Assistance|[Upstream](#upstream)|
|Subaru|XV 2020-21|EyeSight Driver Assistance|[Upstream](#upstream)|
|Škoda|Fabia 2022-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
@@ -313,7 +287,7 @@
|Škoda|Superb 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|Tesla|Model 3 (with HW3) 2019-23|All|[Upstream](#upstream)|
|Tesla|Model 3 (with HW4) 2024-25|All|[Upstream](#upstream)|
|Tesla|Model X (with HW4) 2024|All|[Community](community)|
|Tesla|Model X (with HW4) 2024|All|[Dashcam mode](#dashcam)|
|Tesla|Model Y (with HW3) 2020-23|All|[Upstream](#upstream)|
|Tesla|Model Y (with HW4) 2024-25|All|[Upstream](#upstream)|
|Toyota|Alphard 2019-20|All|[Upstream](#upstream)|
@@ -324,19 +298,19 @@
|Toyota|Avalon 2022|All|[Upstream](#upstream)|
|Toyota|Avalon Hybrid 2019-21|All|[Upstream](#upstream)|
|Toyota|Avalon Hybrid 2022|All|[Upstream](#upstream)|
|Toyota|bZ4x 2023-25|All|[Not compatible](#can-bus-security)|
|Toyota|bZ4x 2023-25|Any|[Not compatible](#can-bus-security)|
|Toyota|C-HR 2017-20|All|[Upstream](#upstream)|
|Toyota|C-HR 2021|All|[Upstream](#upstream)|
|Toyota|C-HR Hybrid 2017-20|All|[Upstream](#upstream)|
|Toyota|C-HR Hybrid 2021-22|All|[Upstream](#upstream)|
|Toyota|Camry 2018-20|All|[Upstream](#upstream)|
|Toyota|Camry 2021-24|All|[Upstream](#upstream)|
|Toyota|Camry 2025|All|[Not compatible](#can-bus-security)|
|Toyota|Camry 2025|Any|[Not compatible](#can-bus-security)|
|Toyota|Camry Hybrid 2018-20|All|[Upstream](#upstream)|
|Toyota|Camry Hybrid 2021-24|All|[Upstream](#upstream)|
|Toyota|Corolla 2017-19|All|[Upstream](#upstream)|
|Toyota|Corolla 2020-22|All|[Upstream](#upstream)|
|Toyota|Corolla Cross 2022-25|All|[Not compatible](#can-bus-security)|
|Toyota|Corolla Cross 2022-25|Any|[Not compatible](#can-bus-security)|
|Toyota|Corolla Cross (Non-US only) 2020-23|All|[Upstream](#upstream)|
|Toyota|Corolla Cross Hybrid (Non-US only) 2020-22|All|[Upstream](#upstream)|
|Toyota|Corolla Hatchback 2019-22|All|[Upstream](#upstream)|
@@ -344,7 +318,7 @@
|Toyota|Corolla Hybrid (South America only) 2020-23|All|[Upstream](#upstream)|
|Toyota|Highlander 2017-19|All|[Upstream](#upstream)|
|Toyota|Highlander 2020-23|All|[Upstream](#upstream)|
|Toyota|Highlander 2025|All|[Not compatible](#can-bus-security)|
|Toyota|Highlander 2025|Any|[Not compatible](#can-bus-security)|
|Toyota|Highlander Hybrid 2017-19|All|[Upstream](#upstream)|
|Toyota|Highlander Hybrid 2020-23|All|[Upstream](#upstream)|
|Toyota|Mirai 2021|All|[Upstream](#upstream)|
@@ -364,15 +338,15 @@
|Toyota|RAV4 Hybrid 2019-21|All|[Upstream](#upstream)|
|Toyota|RAV4 Hybrid 2022|All|[Upstream](#upstream)|
|Toyota|RAV4 Hybrid 2023-25|All|[Upstream](#upstream)|
|Toyota|RAV4 Prime 2021-23|All|[Custom](#secoc-cars-with-recoverable-keys)|
|Toyota|RAV4 Prime 2024-25|All|[Not compatible](#can-bus-security)|
|Toyota|Sequoia 2023-25|All|[Not compatible](#can-bus-security)|
|Toyota|RAV4 Prime 2021-23|All|[Community](#community)|
|Toyota|RAV4 Prime 2024-25|Any|[Not compatible](#can-bus-security)|
|Toyota|Sequoia 2023-25|Any|[Not compatible](#can-bus-security)|
|Toyota|Sienna 2018-20|All|[Upstream](#upstream)|
|Toyota|Sienna 2021-23|All|[Custom](#secoc-cars-with-recoverable-keys)|
|Toyota|Sienna 2024-25|All|[Not compatible](#can-bus-security)|
|Toyota|Tundra 2022-25|All|[Not compatible](#can-bus-security)|
|Toyota|Venza 2021-25|All|[Not compatible](#can-bus-security)|
|Toyota|Yaris (Non-US only) 2020, 2023|All|[Custom](#secoc-cars-with-recoverable-keys)|
|Toyota|Sienna 2021-23|All|[Community](#community)|
|Toyota|Sienna 2024-25|Any|[Not compatible](#can-bus-security)|
|Toyota|Tundra 2022-25|Any|[Not compatible](#can-bus-security)|
|Toyota|Venza 2021-25|Any|[Not compatible](#can-bus-security)|
|Toyota|Yaris (Non-US only) 2020, 2023|All|[Community](#community)|
|Volkswagen|Arteon 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|Volkswagen|Arteon eHybrid 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|Volkswagen|Arteon R 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
@@ -396,7 +370,7 @@
|Volkswagen|Golf SportsVan 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|Volkswagen|Grand California 2019-24|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|Volkswagen|Jetta 2015-18|Adaptive Cruise Control (ACC) & Lane Assist|[Dashcam mode](#dashcam)|
|Volkswagen|Jetta 2019-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|Volkswagen|Jetta 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|Volkswagen|Jetta GLI 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|Volkswagen|Passat 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|Volkswagen|Passat Alltrack 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
@@ -438,14 +412,7 @@ openpilot is installed, but custom forks may allow their use.
Vehicles in this category are not considered plug-and-play. Software support is included in upstream openpilot, but
these vehicles might not have a harness in the comma store, or the physical install might be at an unusual or cumbersome
location, or they might need unusual configuration after install. These vehicles will not work with release builds of
openpilot, but depending on the situation, development builds or custom forks may allow their use.
### SecOC cars with recoverable keys
For a small subset of SecOC-protected vehicles, tools may be available in the community to recover the SecOC keys. These
tools, and the recovery process, are not part of openpilot. If supplied with a valid SecOC key, development builds or
custom forks may work with these vehicles. Release builds of openpilot don't support SecOC.
location, or they might need unusual configuration after install.
## Dashcam
-2
View File
@@ -15,8 +15,6 @@ test:
# *** static analysis
ruff:
run: ruff check .
ty:
run: ty check
codespell:
run: codespell {files} -L tge,stdio -S *.dbc --ignore-words=.codespellignore
files: git ls-tree -r HEAD --name-only
+2 -2
View File
@@ -91,7 +91,7 @@ class MessageState:
if self.frequency < 1e-5 and len(self.timestamps) >= 3:
dt = (self.timestamps[-1] - self.timestamps[0]) * 1e-9
if (dt > 1.0 or (self.timestamps.maxlen is not None and len(self.timestamps) >= self.timestamps.maxlen)) and dt != 0:
if (dt > 1.0 or len(self.timestamps) >= self.timestamps.maxlen) and dt != 0:
self.frequency = min(len(self.timestamps) / dt, 100.0)
self.timeout_threshold = (1_000_000_000 / self.frequency) * 10
return True
@@ -153,7 +153,7 @@ class CANParser:
self.last_nonempty_nanos: int = 0
self._last_update_nanos: int = 0
def _add_message(self, name_or_addr: str | int, freq: int | None = None) -> None:
def _add_message(self, name_or_addr: str | int, freq: int = None) -> None:
if isinstance(name_or_addr, numbers.Number):
msg = self.dbc.addr_to_msg.get(int(name_or_addr))
else:
+1 -8
View File
@@ -32,14 +32,7 @@ openpilot is installed, but custom forks may allow their use.
Vehicles in this category are not considered plug-and-play. Software support is included in upstream openpilot, but
these vehicles might not have a harness in the comma store, or the physical install might be at an unusual or cumbersome
location, or they might need unusual configuration after install. These vehicles will not work with release builds of
openpilot, but depending on the situation, development builds or custom forks may allow their use.
### SecOC cars with recoverable keys
For a small subset of SecOC-protected vehicles, tools may be available in the community to recover the SecOC keys. These
tools, and the recovery process, are not part of openpilot. If supplied with a valid SecOC key, development builds or
custom forks may work with these vehicles. Release builds of openpilot don't support SecOC.
location, or they might need unusual configuration after install.
## Dashcam
+6 -4
View File
@@ -106,7 +106,7 @@ def make_tester_present_msg(addr, bus, subaddr=None, suppress_response=False):
return CanData(addr, bytes(dat), bus)
def get_safety_config(safety_model: structs.CarParams.SafetyModel, safety_param: int | None = None) -> structs.CarParams.SafetyConfig:
def get_safety_config(safety_model: structs.CarParams.SafetyModel, safety_param: int = None) -> structs.CarParams.SafetyConfig:
ret = structs.CarParams.SafetyConfig()
ret.safetyModel = safety_model
if safety_param is not None:
@@ -131,15 +131,17 @@ class CanSignalRateCalculator:
Calculates the instantaneous rate of a CAN signal by using the counter
variable and the known frequency of the CAN message that contains it.
"""
def __init__(self, frequency: int):
def __init__(self, frequency):
self.frequency = frequency
self.previous_counter = 0
self.previous_value = 0
self.rate = 0
def update(self, current_value: float, updated: bool):
if updated:
def update(self, current_value, current_counter):
if current_counter != self.previous_counter:
self.rate = (current_value - self.previous_value) * self.frequency
self.previous_counter = current_counter
self.previous_value = current_value
return self.rate
+7 -4
View File
@@ -1,6 +1,3 @@
from opendbc.car.crc import CRC8BODY
def create_control(packer, torque_l, torque_r):
values = {
"TORQUE_L": torque_l,
@@ -12,6 +9,12 @@ def create_control(packer, torque_l, torque_r):
def body_checksum(address: int, sig, d: bytearray) -> int:
crc = 0xFF
poly = 0xD5
for i in range(len(d) - 2, -1, -1):
crc = CRC8BODY[crc ^ d[i]]
crc ^= d[i]
for _ in range(8):
if crc & 0x80:
crc = ((crc << 1) ^ poly) & 0xFF
else:
crc = (crc << 1) & 0xFF
return crc
+1 -1
View File
@@ -153,7 +153,7 @@ def fingerprint(can_recv: CanRecvCallable, can_send: CanSendCallable, set_obd_mu
def get_car(can_recv: CanRecvCallable, can_send: CanSendCallable, set_obd_multiplexing: ObdCallback, alpha_long_allowed: bool,
is_release: bool, num_pandas: int = 1, cached_params: CarParamsT | None = None,
fixed_fingerprint: str | None = None, init_params_list_sp: list[dict[str, str]] | None = None, is_release_sp: bool = False):
fixed_fingerprint: str | None = None, init_params_list_sp: list[dict[str, str]] = None, is_release_sp: bool = False):
candidate, fingerprints, vin, car_fw, source, exact_match = fingerprint(can_recv, can_send, set_obd_multiplexing, num_pandas, cached_params,
fixed_fingerprint)
+4 -4
View File
@@ -217,7 +217,7 @@ class CcpClient:
resp = self._recv_dto(0.025)
# mta_addr_ext = resp[0]
mta_addr = struct.unpack(f"{self.byte_order.value}I", resp[1:5])[0]
return mta_addr
return mta_addr # type: ignore
def download_6_bytes(self, data: bytes) -> int:
if len(data) != 6:
@@ -226,7 +226,7 @@ class CcpClient:
resp = self._recv_dto(0.025)
# mta_addr_ext = resp[0]
mta_addr = struct.unpack(f"{self.byte_order.value}I", resp[1:5])[0]
return mta_addr
return mta_addr # type: ignore
def upload(self, size: int) -> bytes:
if size > 5:
@@ -325,7 +325,7 @@ class CcpClient:
resp = self._recv_dto(0.1)
# mta_addr_ext = resp[0]
mta_addr = struct.unpack(f"{self.byte_order.value}I", resp[1:5])[0]
return mta_addr
return mta_addr # type: ignore
def program_6_bytes(self, data: bytes) -> int:
if len(data) != 6:
@@ -334,7 +334,7 @@ class CcpClient:
resp = self._recv_dto(0.1)
# mta_addr_ext = resp[0]
mta_addr = struct.unpack(f"{self.byte_order.value}I", resp[1:5])[0]
return mta_addr
return mta_addr # type: ignore
def move_memory_block(self, size: int) -> None:
self._send_cro(COMMAND_CODE.MOVE, struct.pack(f"{self.byte_order.value}I", size))
@@ -13,8 +13,6 @@ class CarInterface(CarInterfaceBase):
CarController = CarController
RadarInterface = RadarInterface
DRIVABLE_GEARS = (structs.CarState.GearShifter.low,)
@staticmethod
def _get_params(ret: structs.CarParams, candidate, fingerprint, car_fw, alpha_long, is_release, docs) -> structs.CarParams:
ret.brand = "chrysler"
@@ -73,8 +73,8 @@ class RadarInterface(RadarInterfaceBase):
if 'LONG_DIST' in cpt: # c_* message
self.pts[trackId].dRel = cpt['LONG_DIST'] # from front of car
# our lat_dist is positive to the right in car's frame.
# LAT_DIST is right-positive, yRel is left-positive
self.pts[trackId].yRel = -cpt['LAT_DIST'] # in car frame's y axis, left is positive
# TODO what does yRel want?
self.pts[trackId].yRel = cpt['LAT_DIST'] # in car frame's y axis, left is positive
else: # d_* message
self.pts[trackId].vRel = cpt['REL_SPEED']
-1
View File
@@ -27,5 +27,4 @@ def _gen_crc16_table(poly: int) -> list[int]:
CRC8H2F = _gen_crc8_table(0x2F)
CRC8J1850 = _gen_crc8_table(0x1D)
CRC8BODY = _gen_crc8_table(0xD5)
CRC16_XMODEM = _gen_crc16_table(0x1021)
+7 -14
View File
@@ -1,13 +1,12 @@
#!/usr/bin/env python3
import re
import os
import jinja2
import argparse
import unicodedata
import os
from typing import get_args
from enum import Enum
from collections import defaultdict
import jinja2
from enum import Enum
from natsort import natsorted
from opendbc.car.common.basedir import BASEDIR
from opendbc.car import gen_empty_fingerprint
@@ -33,11 +32,11 @@ def get_params_for_docs(platform) -> tuple[CarParams, CarParamsSP]:
cp_platform = platform if platform in interfaces else MOCK.MOCK
CP: CarParams = interfaces[cp_platform].get_params(cp_platform, fingerprint=gen_empty_fingerprint(),
car_fw=[CarParams.CarFw(ecu=CarParams.Ecu.unknown)],
alpha_long=True, is_release=True, docs=True)
alpha_long=True, is_release=False, docs=True)
CP_SP: CarParamsSP = interfaces[cp_platform].get_params_sp(CP, cp_platform, fingerprint=gen_empty_fingerprint(),
car_fw=[CarParams.CarFw(ecu=CarParams.Ecu.unknown)],
alpha_long=True, is_release_sp=True, docs=True)
alpha_long=True, is_release_sp=False, docs=True)
return CP, CP_SP
@@ -48,12 +47,6 @@ def get_all_footnotes() -> dict[Enum, int]:
return {fn: idx + 1 for idx, fn in enumerate(all_footnotes)}
def _natural_sort_key(s):
# NFKD normalization ensures accented characters sort with their base letter (e.g., Š sorts with S)
normalized = unicodedata.normalize('NFKD', s)
return [int(t) if t.isdigit() else t.lower() for t in re.split(r'(\d+)', normalized) if t]
def build_sorted_car_docs_list(platforms, footnotes=None):
collected_car_docs: list[CarDocs | ExtraCarDocs] = []
for platform in platforms.values():
@@ -71,7 +64,7 @@ def build_sorted_car_docs_list(platforms, footnotes=None):
collected_car_docs.append(_car_docs)
# Sort cars by make and model + year
sorted_cars = sorted(collected_car_docs, key=lambda car: _natural_sort_key(car.name))
sorted_cars = natsorted(collected_car_docs, key=lambda car: car.name.lower())
return sorted_cars
+16 -13
View File
@@ -78,6 +78,7 @@ class Cable(EnumBase):
long_obdc_cable = BasePart("long OBD-C cable (9.5 ft)")
usb_a_2_a_cable = BasePart("USB A-A cable")
usbc_otg_cable = BasePart("USB C OTG cable")
usbc_coupler = BasePart("USB-C coupler")
obd_c_cable_2ft = BasePart("OBD-C cable (2 ft)")
@@ -111,7 +112,7 @@ class CarHarness(EnumBase):
fca = BaseCarHarness("FCA connector")
ram = BaseCarHarness("Ram connector")
vw_a = BaseCarHarness("VW A connector")
vw_j533 = BaseCarHarness("VW J533 connector", parts=[Accessory.harness_box, Cable.long_obdc_cable])
vw_j533 = BaseCarHarness("VW J533 connector", parts=[Accessory.harness_box, Cable.long_obdc_cable, Cable.usbc_coupler])
hyundai_a = BaseCarHarness("Hyundai A connector")
hyundai_b = BaseCarHarness("Hyundai B connector")
hyundai_c = BaseCarHarness("Hyundai C connector")
@@ -131,18 +132,18 @@ class CarHarness(EnumBase):
hyundai_q = BaseCarHarness("Hyundai Q connector")
hyundai_r = BaseCarHarness("Hyundai R connector")
custom = BaseCarHarness("Developer connector")
obd_ii = BaseCarHarness("OBD-II connector", parts=[Cable.long_obdc_cable], has_connector=False)
obd_ii = BaseCarHarness("OBD-II connector", parts=[Cable.long_obdc_cable, Cable.usbc_coupler], has_connector=False)
gm = BaseCarHarness("GM connector", parts=[Accessory.harness_box])
gmsdgm = BaseCarHarness("GM SDGM connector", parts=[Accessory.harness_box, Accessory.comma_power, Cable.long_obdc_cable])
nissan_a = BaseCarHarness("Nissan A connector", parts=[Accessory.harness_box, Accessory.comma_power, Cable.long_obdc_cable])
nissan_b = BaseCarHarness("Nissan B connector", parts=[Accessory.harness_box, Accessory.comma_power, Cable.long_obdc_cable])
gmsdgm = BaseCarHarness("GM SDGM connector", parts=[Accessory.harness_box, Accessory.comma_power, Cable.long_obdc_cable, Cable.usbc_coupler])
nissan_a = BaseCarHarness("Nissan A connector", parts=[Accessory.harness_box, Accessory.comma_power, Cable.long_obdc_cable, Cable.usbc_coupler])
nissan_b = BaseCarHarness("Nissan B connector", parts=[Accessory.harness_box, Accessory.comma_power, Cable.long_obdc_cable, Cable.usbc_coupler])
mazda = BaseCarHarness("Mazda connector")
ford_q3 = BaseCarHarness("Ford Q3 connector")
ford_q4 = BaseCarHarness("Ford Q4 connector", parts=[Accessory.harness_box, Accessory.comma_power, Cable.long_obdc_cable])
rivian = BaseCarHarness("Rivian A connector", parts=[Accessory.harness_box, Accessory.comma_power, Cable.long_obdc_cable])
tesla_a = BaseCarHarness("Tesla A connector", parts=[Accessory.harness_box, Cable.long_obdc_cable])
tesla_b = BaseCarHarness("Tesla B connector", parts=[Accessory.harness_box, Cable.long_obdc_cable])
psa_a = BaseCarHarness("PSA A connector", parts=[Accessory.harness_box, Cable.long_obdc_cable])
ford_q4 = BaseCarHarness("Ford Q4 connector", parts=[Accessory.harness_box, Accessory.comma_power, Cable.long_obdc_cable, Cable.usbc_coupler])
rivian = BaseCarHarness("Rivian A connector", parts=[Accessory.harness_box, Accessory.comma_power, Cable.long_obdc_cable, Cable.usbc_coupler])
tesla_a = BaseCarHarness("Tesla A connector", parts=[Accessory.harness_box, Cable.long_obdc_cable, Cable.usbc_coupler])
tesla_b = BaseCarHarness("Tesla B connector", parts=[Accessory.harness_box, Cable.long_obdc_cable, Cable.usbc_coupler])
psa_a = BaseCarHarness("PSA A connector", parts=[Accessory.harness_box, Cable.long_obdc_cable, Cable.usbc_coupler])
# custom harness
honda_clarity = BaseCarHarness("Honda Nidec connector + Honda Clarity Proxy Board")
@@ -173,7 +174,7 @@ class CarParts:
return copy.deepcopy(self)
@classmethod
def common(cls, add: list[EnumBase] | None = None, remove: list[EnumBase] | None = None):
def common(cls, add: list[EnumBase] = None, remove: list[EnumBase] = None):
p = [part for part in (add or []) + DEFAULT_CAR_PARTS if part not in (remove or [])]
return cls(p)
@@ -259,9 +260,11 @@ class CarDocs:
self.longitudinal_control = CP.openpilotLongitudinalControl and not CP.alphaLongitudinalAvailable
if self.merged and CP.dashcamOnly:
if self.support_type not in (SupportType.CUSTOM, SupportType.REVIEW):
if self.support_type != SupportType.REVIEW:
self.support_type = SupportType.DASHCAM
self.support_link = "#dashcam"
else:
self.support_link = "#under-review"
# longitudinal column
op_long = "Stock"
@@ -400,7 +403,7 @@ class CarDocs:
@dataclass
class ExtraCarDocs(CarDocs):
package: str = "All"
package: str = "Any"
merged: bool = False
support_type: SupportType = SupportType.INCOMPATIBLE
support_link: str | None = "#incompatible"
+1 -1
View File
@@ -6,7 +6,7 @@ from opendbc.car.carlog import carlog
from opendbc.car.fw_query_definitions import EcuAddrBusType
def _is_tester_present_response(msg: CanData, subaddr: int | None = None) -> bool:
def _is_tester_present_response(msg: CanData, subaddr: int = None) -> bool:
# ISO-TP messages may use CAN frame optimization (not always 8 bytes)
# tester present response is always a single frame
dat_offset = 1 if subaddr is not None else 0
+14 -17
View File
@@ -37,29 +37,26 @@ class CAR(Platforms):
EXTRA_HONDA = ExtraPlatformConfig(
[
CommunityCarDocs("Acura ADX 2025-26"),
CommunityCarDocs("Acura Integra 2023-25"),
CommunityCarDocs("Acura Integra 2023-25", "All"),
CommunityCarDocs("Acura MDX 2015-16", "Advance Package"),
CommunityCarDocs("Acura MDX 2017-20"),
CommunityCarDocs("Acura MDX Hybrid 2017-20"),
CommunityCarDocs("Acura MDX 2022-24"),
CommunityCarDocs("Acura RDX 2022-25"),
CommunityCarDocs("Acura MDX 2017-20", "All"),
CommunityCarDocs("Acura MDX 2022-24", "All"),
CommunityCarDocs("Acura RDX 2022-25", "All"),
CommunityCarDocs("Acura RLX 2017", "Advance Package or Technology Package"),
CommunityCarDocs("Acura TLX 2015-17", "Advance Package"),
CommunityCarDocs("Acura TLX 2018-20"),
CommunityCarDocs("Acura TLX 2022-23"),
GMSecurityCarDocs("Acura ZDX 2024"),
CommunityCarDocs("Acura TLX 2018-20", "All"),
CommunityCarDocs("Acura TLX 2022-23", "All"),
GMSecurityCarDocs("Acura ZDX 2024", "All"),
CommunityCarDocs("Honda Accord 2016-17", "Honda Sensing"),
CommunityCarDocs("Honda Accord Hybrid 2017"),
CommunityCarDocs("Honda Clarity 2018-21"),
GMSecurityCarDocs("Honda Prologue 2024-25"),
CommunityCarDocs("Honda Clarity 2018-21", "All"),
GMSecurityCarDocs("Honda Prologue 2024-25", "All"),
],
)
EXTRA_HYUNDAI = ExtraPlatformConfig(
[
CommunityCarDocs("Hyundai Palisade 2023-24", "Highway Driving Assist II"),
CommunityCarDocs("Kia Telluride 2023-24", "Highway Driving Assist II"),
CommunityCarDocs("Hyundai Palisade 2023-24", package="HDA2"),
CommunityCarDocs("Kia Telluride 2023-24", package="HDA2"),
],
)
@@ -81,8 +78,8 @@ class CAR(Platforms):
EXTRA_VOLKSWAGEN = ExtraPlatformConfig(
[
FlexRayCarDocs("Audi A4 2016-24"),
FlexRayCarDocs("Audi A5 2016-24"),
FlexRayCarDocs("Audi Q5 2017-24"),
FlexRayCarDocs("Audi A4 2016-24", package="All"),
FlexRayCarDocs("Audi A5 2016-24", package="All"),
FlexRayCarDocs("Audi Q5 2017-24", package="All"),
],
)
@@ -17,8 +17,6 @@ class CarInterface(CarInterfaceBase):
CarController = CarController
RadarInterface = RadarInterface
DRIVABLE_GEARS = (structs.CarState.GearShifter.low, structs.CarState.GearShifter.manumatic)
@staticmethod
def get_pid_accel_limits(CP, CP_SP, current_speed, cruise_speed):
# PCM doesn't allow acceleration near cruise_speed,
+6 -7
View File
@@ -37,7 +37,7 @@ def is_brand(brand: str, filter_brand: str | None) -> bool:
return filter_brand is None or brand == filter_brand
def build_fw_dict(fw_versions: list[CarParams.CarFw], filter_brand: str | None = None) -> dict[AddrType, set[bytes]]:
def build_fw_dict(fw_versions: list[CarParams.CarFw], filter_brand: str = None) -> dict[AddrType, set[bytes]]:
fw_versions_dict: defaultdict[AddrType, set[bytes]] = defaultdict(set)
for fw in fw_versions:
if is_brand(fw.brand, filter_brand) and not fw.logging:
@@ -47,11 +47,11 @@ def build_fw_dict(fw_versions: list[CarParams.CarFw], filter_brand: str | None =
class MatchFwToCar(Protocol):
def __call__(self, live_fw_versions: LiveFwVersions, match_brand: str | None = None, log: bool = True) -> set[str]:
def __call__(self, live_fw_versions: LiveFwVersions, match_brand: str = None, log: bool = True) -> set[str]:
...
def match_fw_to_car_fuzzy(live_fw_versions: LiveFwVersions, match_brand: str | None = None, log: bool = True, exclude: str | None = None) -> set[str]:
def match_fw_to_car_fuzzy(live_fw_versions: LiveFwVersions, match_brand: str = None, log: bool = True, exclude: str = None) -> set[str]:
"""Do a fuzzy FW match. This function will return a match, and the number of firmware version
that were matched uniquely to that specific car. If multiple ECUs uniquely match to different cars
the match is rejected."""
@@ -101,8 +101,7 @@ def match_fw_to_car_fuzzy(live_fw_versions: LiveFwVersions, match_brand: str | N
return set()
def match_fw_to_car_exact(live_fw_versions: LiveFwVersions, match_brand: str | None = None,
log: bool = True, extra_fw_versions: dict | None = None) -> set[str]:
def match_fw_to_car_exact(live_fw_versions: LiveFwVersions, match_brand: str = None, log: bool = True, extra_fw_versions: dict = None) -> set[str]:
"""Do an exact FW match. Returns all cars that match the given
FW versions for a list of "essential" ECUs. If an ECU is not considered
essential the FW version can be missing to get a fingerprint, but if it's present it
@@ -253,8 +252,8 @@ def get_fw_versions_ordered(can_recv: CanRecvCallable, can_send: CanSendCallable
return all_car_fw
def get_fw_versions(can_recv: CanRecvCallable, can_send: CanSendCallable, set_obd_multiplexing: ObdCallback, query_brand: str | None = None,
extra: OfflineFwVersions | None = None, timeout: float = 0.1, num_pandas: int = 1, progress: bool = False) -> list[CarParams.CarFw]:
def get_fw_versions(can_recv: CanRecvCallable, can_send: CanSendCallable, set_obd_multiplexing: ObdCallback, query_brand: str = None,
extra: OfflineFwVersions = None, timeout: float = 0.1, num_pandas: int = 1, progress: bool = False) -> list[CarParams.CarFw]:
versions = VERSIONS.copy()
if query_brand is not None:
@@ -54,9 +54,6 @@ FINGERPRINTS = {
}],
CAR.CHEVROLET_SILVERADO: [{
190: 6, 193: 8, 197: 8, 201: 8, 208: 8, 209: 7, 211: 2, 241: 6, 249: 8, 257: 8, 288: 5, 289: 8, 298: 8, 304: 3, 309: 8, 311: 8, 313: 8, 320: 4, 322: 7, 328: 1, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 413: 8, 451: 8, 452: 8, 453: 6, 455: 7, 460: 5, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 500: 6, 501: 8, 528: 5, 532: 6, 534: 2, 560: 8, 562: 8, 563: 5, 565: 5, 587: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 715: 8, 717: 5, 761: 7, 789: 5, 800: 6, 801: 8, 810: 8, 840: 5, 842: 5, 844: 8, 848: 4, 869: 4, 880: 6, 977: 8, 1001: 8, 1011: 6, 1017: 8, 1020: 8, 1033: 7, 1034: 7, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1271: 8, 1280: 4, 1296: 4, 1300: 8, 1611: 8, 1930: 7
},
{
190: 6, 193: 8, 197: 8, 201: 8, 208: 8, 209: 7, 211: 2, 241: 6, 249: 8, 257: 3, 288: 5, 289: 8, 298: 8, 304: 3, 309: 8, 311: 8, 313: 8, 320: 4, 322: 7, 328: 1, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 413: 8, 451: 8, 452: 8, 453: 6, 455: 7, 460: 5, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 500: 6, 501: 8, 528: 5, 532: 6, 534: 2, 560: 8, 562: 8, 563: 5, 565: 5, 587: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 715: 8, 717: 5, 761: 7, 789: 5, 800: 6, 801: 8, 810: 8, 840: 5, 842: 5, 844: 8, 848: 4, 869: 4, 880: 6, 977: 8, 1001: 8, 1011: 6, 1017: 8, 1020: 8, 1033: 7, 1034: 7, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1271: 8, 1280: 4, 1296: 4, 1300: 8, 1611: 8, 1930: 7
}],
CAR.CHEVROLET_EQUINOX: [{
190: 6, 193: 8, 197: 8, 201: 8, 209: 7, 211: 2, 241: 6, 249: 8, 257: 8, 288: 5, 289: 8, 298: 8, 304: 1, 309: 8, 311: 8, 313: 8, 320: 3, 328: 1, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 413: 8, 451: 8, 452: 8, 453: 6, 455: 7, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 500: 6, 501: 8, 510: 8, 528: 5, 532: 6, 560: 8, 562: 8, 563: 5, 565: 5, 587: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 715: 8, 717: 5, 753: 5, 761: 7, 789: 5, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 869: 4, 880: 6, 977: 8, 1001: 8, 1011: 6, 1017: 8, 1020: 8, 1033: 7, 1034: 7, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1271: 8, 1280: 4, 1296: 4, 1300: 8, 1611: 8, 1930: 7
+5 -6
View File
@@ -35,9 +35,6 @@ class CarInterface(CarInterfaceBase, CarInterfaceExt):
CarController = CarController
RadarInterface = RadarInterface
DRIVABLE_GEARS = (structs.CarState.GearShifter.sport, structs.CarState.GearShifter.low,
structs.CarState.GearShifter.eco, structs.CarState.GearShifter.manumatic)
def __init__(self, CP, CP_SP):
CarInterfaceBase.__init__(self, CP, CP_SP)
CarInterfaceExt.__init__(self, CP, CarInterfaceBase)
@@ -59,7 +56,7 @@ class CarInterface(CarInterfaceBase, CarInterfaceExt):
else:
return CarInterfaceBase.get_steer_feedforward_default
def get_lataccel_torque_siglin(self) -> tuple[list[float], np.ndarray]:
def get_lataccel_torque_siglin(self) -> float:
def torque_from_lateral_accel_siglin_func(lateral_acceleration: float) -> float:
# The "lat_accel vs torque" relationship is assumed to be the sum of "sigmoid + linear" curves
@@ -68,6 +65,7 @@ class CarInterface(CarInterfaceBase, CarInterfaceExt):
non_linear_torque_params = NON_LINEAR_TORQUE_PARAMS.get(self.CP.carFingerprint)
assert non_linear_torque_params, "The params are not defined"
a, b, c, d = non_linear_torque_params
d = d if NON_LINEAR_TORQUE_PARAMS_SP.get(self.CP.carFingerprint) else 0.0
sig_input = a * lateral_acceleration
sig = np.sign(sig_input) * (1 / (1 + exp(-fabs(sig_input))) - 0.5)
steer_torque = (sig * b) + (lateral_acceleration * c) + d
@@ -260,8 +258,9 @@ class CarInterface(CarInterfaceBase, CarInterfaceExt):
stock_cp.minSteerSpeed = 3.0 # ~6 mph
# dashcamOnly platforms: untested platforms, need user validations
if candidate in (CAR.CHEVROLET_SUBURBAN_NON_ACC_11TH_GEN, CAR.CADILLAC_CT6_NON_ACC_1ST_GEN,
CAR.CHEVROLET_TRAILBLAZER_NON_ACC_2ND_GEN, CAR.CADILLAC_XT5_NON_ACC_1ST_GEN):
if candidate in (CAR.CHEVROLET_BOLT_NON_ACC_2ND_GEN, CAR.CHEVROLET_EQUINOX_NON_ACC_3RD_GEN,
CAR.CHEVROLET_SUBURBAN_NON_ACC_11TH_GEN, CAR.CADILLAC_CT6_NON_ACC_1ST_GEN, CAR.CHEVROLET_TRAILBLAZER_NON_ACC_2ND_GEN,
CAR.CADILLAC_XT5_NON_ACC_1ST_GEN):
stock_cp.dashcamOnly = True
return ret
+32 -35
View File
@@ -3,7 +3,7 @@ from enum import Enum, IntFlag
from opendbc.car import Bus, PlatformConfig, DbcDict, Platforms, CarSpecs
from opendbc.car.structs import CarParams
from opendbc.car.docs_definitions import CarDocs, CarFootnote, CarHarness, CarParts, Column, SupportType
from opendbc.car.docs_definitions import CarDocs, CarFootnote, CarHarness, CarParts, Column
from opendbc.car.fw_query_definitions import FwQueryConfig, Request, StdQueries
from opendbc.sunnypilot.car.gm.values_ext import GMFlagsSP
@@ -88,13 +88,6 @@ class GMCarDocs(CarDocs):
self.car_parts = CarParts.common([CarHarness.obd_ii])
@dataclass
class GMNonAccCarDocs(GMCarDocs):
package: str = "No Adaptive Cruise Control (Non-ACC)"
support_type: SupportType = SupportType.COMMUNITY
support_link: str = "community"
@dataclass(frozen=True, kw_only=True)
class GMCarSpecs(CarSpecs):
tireStiffnessFactor: float = 0.444 # not optimized yet
@@ -123,12 +116,6 @@ class GMSDGMPlatformConfig(GMPlatformConfig):
self.car_docs = []
@dataclass
class GMNonSccPlatformConfig(GMPlatformConfig):
def init(self):
self.sp_flags |= GMFlagsSP.NON_ACC
class CAR(Platforms):
HOLDEN_ASTRA = GMASCMPlatformConfig(
[GMCarDocs("Holden Astra 2017")],
@@ -212,48 +199,58 @@ class CAR(Platforms):
# port extensions
# Separate car def is required when there is no ASCM
# (for now) unless there is a way to detect it when it has been unplugged...
# CHEVROLET_VOLT_CC = GMNonSccPlatformConfig(
# [GMNonAccCarDocs("Chevrolet Volt LT 2017-18")],
# CHEVROLET_VOLT_CC = GMPlatformConfig(
# [GMCarDocs("Chevrolet Volt LT 2017-18")],
# CHEVROLET_VOLT.specs,
# sp_flags=GMFlagsSP.NON_ACC,
# )
CHEVROLET_BOLT_NON_ACC = GMNonSccPlatformConfig(
[GMNonAccCarDocs("Chevrolet Bolt EV Non-ACC 2017")],
CHEVROLET_BOLT_NON_ACC = GMPlatformConfig(
[GMCarDocs("Chevrolet Bolt EV Non-ACC 2017")],
CHEVROLET_BOLT_EUV.specs,
sp_flags=GMFlagsSP.NON_ACC,
)
CHEVROLET_BOLT_NON_ACC_1ST_GEN = GMNonSccPlatformConfig(
[GMNonAccCarDocs("Chevrolet Bolt EV Non-ACC 2018-21")],
CHEVROLET_BOLT_NON_ACC_1ST_GEN = GMPlatformConfig(
[GMCarDocs("Chevrolet Bolt EV Non-ACC 2018-21")],
CHEVROLET_BOLT_EUV.specs,
sp_flags=GMFlagsSP.NON_ACC,
)
CHEVROLET_BOLT_NON_ACC_2ND_GEN = GMNonSccPlatformConfig(
CHEVROLET_BOLT_NON_ACC_2ND_GEN = GMPlatformConfig(
[
GMNonAccCarDocs("Chevrolet Bolt EUV LT Non-ACC 2022-23"),
GMNonAccCarDocs("Chevrolet Bolt EV LT Non-ACC 2022-23"),
GMCarDocs("Chevrolet Bolt EUV LT Non-ACC 2022-23"),
GMCarDocs("Chevrolet Bolt EV LT Non-ACC 2022-23"),
],
CHEVROLET_BOLT_EUV.specs,
sp_flags=GMFlagsSP.NON_ACC,
)
CHEVROLET_EQUINOX_NON_ACC_3RD_GEN = GMNonSccPlatformConfig(
[GMNonAccCarDocs("Chevrolet Equinox Non-ACC 2019-22")],
CHEVROLET_EQUINOX_NON_ACC_3RD_GEN = GMPlatformConfig(
[GMCarDocs("Chevrolet Equinox Non-ACC 2019-22")],
CHEVROLET_EQUINOX.specs,
sp_flags=GMFlagsSP.NON_ACC,
)
CHEVROLET_SUBURBAN_NON_ACC_11TH_GEN = GMNonSccPlatformConfig(
[GMNonAccCarDocs("Chevrolet Suburban Non-ACC 2016-20")],
CHEVROLET_SUBURBAN_NON_ACC_11TH_GEN = GMPlatformConfig(
[GMCarDocs("Chevrolet Suburban Non-ACC 2016-20")],
CarSpecs(mass=2731, wheelbase=3.302, steerRatio=17.3, centerToFrontRatio=0.49),
sp_flags=GMFlagsSP.NON_ACC,
)
CADILLAC_CT6_NON_ACC_1ST_GEN = GMNonSccPlatformConfig(
[GMNonAccCarDocs("Cadillac CT6 Non-ACC 2017-18")],
CADILLAC_CT6_NON_ACC_1ST_GEN = GMPlatformConfig(
[GMCarDocs("Cadillac CT6 Non-ACC 2017-18")],
CarSpecs(mass=2358, wheelbase=3.11, steerRatio=17.7, centerToFrontRatio=0.4),
sp_flags=GMFlagsSP.NON_ACC,
)
CHEVROLET_TRAILBLAZER_NON_ACC_2ND_GEN = GMNonSccPlatformConfig(
[GMNonAccCarDocs("Chevrolet Trailblazer Non-ACC 2021-22")],
CHEVROLET_TRAILBLAZER_NON_ACC_2ND_GEN = GMPlatformConfig(
[GMCarDocs("Chevrolet Trailblazer Non-ACC 2021-22")],
CHEVROLET_TRAILBLAZER.specs,
sp_flags=GMFlagsSP.NON_ACC,
)
CHEVROLET_MALIBU_NON_ACC_9TH_GEN = GMNonSccPlatformConfig(
[GMNonAccCarDocs("Chevrolet Malibu Non-ACC 2016-23")],
CHEVROLET_MALIBU_NON_ACC_9TH_GEN = GMPlatformConfig(
[GMCarDocs("Chevrolet Malibu Non-ACC 2016-23")],
CarSpecs(mass=1450, wheelbase=2.8, steerRatio=15.8, centerToFrontRatio=0.4),
sp_flags=GMFlagsSP.NON_ACC,
)
CADILLAC_XT5_NON_ACC_1ST_GEN = GMNonSccPlatformConfig(
[GMNonAccCarDocs("Cadillac XT5 Non-ACC 2018")],
CADILLAC_XT5_NON_ACC_1ST_GEN = GMPlatformConfig(
[GMCarDocs("Cadillac XT5 Non-ACC 2018")],
CarSpecs(mass=1810, wheelbase=2.86, steerRatio=16.34, centerToFrontRatio=0.5),
sp_flags=GMFlagsSP.NON_ACC,
)
+5 -9
View File
@@ -51,8 +51,6 @@ class CarState(CarStateBase, CarStateExt):
# When available we use cp.vl["CAR_SPEED"]["ROUGH_CAR_SPEED_2"] to populate vEgoCluster
# However, on cars without a digital speedometer this is not always present (HRV, FIT, CRV 2016, ILX and RDX)
self.dash_speed_seen = False
self.is_metric = False
self.v_cruise_factor = 1.
def update(self, can_parsers) -> tuple[structs.CarState, structs.CarStateSP]:
cp = can_parsers[Bus.pt]
@@ -74,8 +72,7 @@ class CarState(CarStateBase, CarStateExt):
self.cruise_buttons = cp.vl["SCM_BUTTONS"]["CRUISE_BUTTONS"]
# used for car hud message
# TODO: find CAR_SPEED for HONDA_ODYSSEY_TWN or use ACC_HUD w/ detection
self.is_metric = self.CP.carFingerprint in (CAR.HONDA_ODYSSEY_TWN,) or not cp.vl["CAR_SPEED"]["IMPERIAL_UNIT"]
self.is_metric = not cp.vl["CAR_SPEED"]["IMPERIAL_UNIT"]
self.v_cruise_factor = CV.MPH_TO_MS if self.dynamic_v_cruise_units and not self.is_metric else CV.KPH_TO_MS
# ******************* parse out can *******************
@@ -134,11 +131,10 @@ class CarState(CarStateBase, CarStateExt):
ret.espDisabled = cp.vl["VSA_STATUS"]["ESP_DISABLED"] != 0
if self.CP.carFingerprint not in (CAR.HONDA_ODYSSEY_TWN,):
self.dash_speed_seen = self.dash_speed_seen or cp.vl["CAR_SPEED"]["ROUGH_CAR_SPEED_2"] > 1e-3
if self.dash_speed_seen:
conversion = CV.KPH_TO_MS if self.is_metric else CV.MPH_TO_MS
ret.vEgoCluster = cp.vl["CAR_SPEED"]["ROUGH_CAR_SPEED_2"] * conversion
self.dash_speed_seen = self.dash_speed_seen or cp.vl["CAR_SPEED"]["ROUGH_CAR_SPEED_2"] > 1e-3
if self.dash_speed_seen:
conversion = CV.KPH_TO_MS if self.is_metric else CV.MPH_TO_MS
ret.vEgoCluster = cp.vl["CAR_SPEED"]["ROUGH_CAR_SPEED_2"] * conversion
ret.steeringAngleDeg = cp.vl["STEERING_SENSORS"]["STEER_ANGLE"]
ret.steeringRateDeg = cp.vl["STEERING_SENSORS"]["STEER_ANGLE_RATE"]
@@ -223,12 +223,10 @@ FW_VERSIONS = {
b'57114-TBG-A340\x00\x00',
b'57114-TBG-A350\x00\x00',
b'57114-TGG-A340\x00\x00',
b'57114-TGG-C120\x00\x00',
b'57114-TGG-C320\x00\x00',
b'57114-TGG-G320\x00\x00',
b'57114-TGG-L320\x00\x00',
b'57114-TGG-L330\x00\x00',
b'57114-TGH-A130\x00\x00',
b'57114-TGH-L130\x00\x00',
b'57114-TGJ-Q330\x00\x00',
b'57114-TGK-T320\x00\x00',
@@ -243,7 +241,6 @@ FW_VERSIONS = {
b'39990-TGG-A020\x00\x00',
b'39990-TGG-A120\x00\x00',
b'39990-TGG-J510\x00\x00',
b'39990-TGH-J020\x00\x00',
b'39990-TGH-J530\x00\x00',
b'39990-TGL-E130\x00\x00',
b'39990-TGN-E120\x00\x00',
@@ -260,7 +257,6 @@ FW_VERSIONS = {
b'77959-TGG-J320\x00\x00',
b'77959-TGG-Q810\x00\x00',
b'77959-TGG-Z820\x00\x00',
b'77959-TGH-E220\x00\x00',
b'77959-TGH-J110\x00\x00',
],
(Ecu.fwdRadar, 0x18dab0f1, None): [
@@ -273,7 +269,6 @@ FW_VERSIONS = {
b'36802-TGG-A130\x00\x00',
b'36802-TGG-G040\x00\x00',
b'36802-TGG-G130\x00\x00',
b'36802-TGH-A030\x00\x00',
b'36802-TGH-A140\x00\x00',
b'36802-TGK-Q030\x00\x00',
b'36802-TGK-Q120\x00\x00',
@@ -290,7 +285,6 @@ FW_VERSIONS = {
b'36161-TGG-G070\x00\x00',
b'36161-TGG-G130\x00\x00',
b'36161-TGG-G140\x00\x00',
b'36161-TGH-A020\x00\x00',
b'36161-TGH-A140\x00\x00',
b'36161-TGK-Q040\x00\x00',
b'36161-TGK-Q120\x00\x00',
@@ -586,17 +580,6 @@ FW_VERSIONS = {
b'54008-THR-A020\x00\x00',
],
},
CAR.HONDA_ODYSSEY_TWN: {
(Ecu.eps, 0x18da30f1, None): [
b'39990-T6A-J210\x00\x00',
],
(Ecu.srs, 0x18da53f1, None): [
b'77959-T6A-P110\x00\x00',
],
(Ecu.fwdRadar, 0x18dab0f1, None): [
b'36161-T6A-P040\x00\x00',
],
},
CAR.HONDA_ODYSSEY_5G_MMR: {
(Ecu.vsa, 0x18da28f1, None): [
b'57114-THR-A240\x00\x00',
@@ -875,7 +858,6 @@ FW_VERSIONS = {
b'77959-3V0-A910\x00\x00',
],
(Ecu.fwdRadar, 0x18dab0f1, None): [
b'8S102-3M1-T050\x00\x00',
b'8S102-3M3-T050\x00\x00',
b'8S102-3M6-P030\x00\x00',
b'8S102-3M6-PA20\x00\x00',
@@ -1030,7 +1012,6 @@ FW_VERSIONS = {
(Ecu.fwdCamera, 0x18dab5f1, None): [
b'8S102-30A-A050\x00\x00',
b'8S102-30A-A060\x00\x00',
b'8S102-30A-A070\x00\x00',
],
},
CAR.HONDA_CRV_6G: {
@@ -1088,14 +1069,6 @@ FW_VERSIONS = {
b'36161-TGV-A030\x00\x00',
],
},
CAR.ACURA_TLX_2G_MMR: {
(Ecu.fwdRadar, 0x18dab0f1, None): [
b'8S302-TGV-A030\x00\x00',
],
(Ecu.fwdCamera, 0x18dab5f1, None): [
b'8S102-TGV-A030\x00\x00',
],
},
}
FW_VERSIONS = merge_fw_versions(FW_VERSIONS, FW_VERSIONS_EXT)
+2 -18
View File
@@ -21,8 +21,6 @@ class CarInterface(CarInterfaceBase):
CarController = CarController
RadarInterface = RadarInterface
DRIVABLE_GEARS = (structs.CarState.GearShifter.sport,)
@staticmethod
def get_pid_accel_limits(CP, CP_SP, current_speed, cruise_speed):
if CP.carFingerprint in HONDA_BOSCH:
@@ -167,10 +165,6 @@ class CarInterface(CarInterfaceBase):
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.28], [0.08]]
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end
elif candidate == CAR.HONDA_ODYSSEY_TWN:
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.28], [0.08]]
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 32767], [0, 32767]] # TODO: determine if there is a dead zone at the top end
elif candidate == CAR.HONDA_PILOT:
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.38], [0.11]]
@@ -199,11 +193,6 @@ class CarInterface(CarInterfaceBase):
# When using stock ACC, the radar intercepts and filters steering commands the EPS would otherwise accept
ret.minSteerSpeed = 70. * CV.KPH_TO_MS
elif candidate == CAR.ACURA_TLX_2G_MMR:
ret.steerActuatorDelay = 0.15
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 3840], [0, 3840]]
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
# TODO-SP: remove when https://github.com/commaai/opendbc/pull/2687 is merged
elif candidate == CAR.HONDA_CLARITY:
pass
@@ -214,7 +203,7 @@ class CarInterface(CarInterfaceBase):
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
# These cars use alternate user brake msg (0x1BE)
if 0x1BE in fingerprint[CAN.pt] and candidate in (CAR.HONDA_ACCORD, CAR.HONDA_HRV_3G, CAR.ACURA_RDX_3G, *HONDA_BOSCH_CANFD):
if 0x1BE in fingerprint[CAN.pt] and candidate in (CAR.HONDA_ACCORD, CAR.HONDA_HRV_3G, *HONDA_BOSCH_CANFD):
ret.flags |= HondaFlags.BOSCH_ALT_BRAKE.value
if ret.flags & HondaFlags.BOSCH_ALT_BRAKE:
@@ -232,12 +221,7 @@ class CarInterface(CarInterfaceBase):
# to a negative value, so it won't matter. Otherwise, add 0.5 mph margin to not
# conflict with PCM acc
ret.autoResumeSng = candidate in (HONDA_BOSCH | {CAR.HONDA_CIVIC})
if ret.autoResumeSng:
ret.minEnableSpeed = -1.
elif candidate == CAR.HONDA_ODYSSEY_TWN:
ret.minEnableSpeed = 19. * CV.MPH_TO_MS
else:
ret.minEnableSpeed = 25.51 * CV.MPH_TO_MS
ret.minEnableSpeed = -1. if ret.autoResumeSng else 25.51 * CV.MPH_TO_MS
ret.steerLimitTimer = 0.8
ret.radarDelay = 0.1
+3 -17
View File
@@ -3,7 +3,7 @@ from enum import Enum, IntFlag
from opendbc.car import Bus, CarSpecs, DbcDict, PlatformConfig, Platforms, structs, uds
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column, SupportType
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
@@ -114,8 +114,6 @@ class HondaCarDocs(CarDocs):
if CP.carFingerprint in (CAR.HONDA_CLARITY,):
self.car_parts = CarParts.common([CarHarness.honda_clarity])
self.car_parts.custom_parts_url = "https://shop.retropilot.org/product/honda-clarity-proxy-board-kit"
self.support_type: SupportType = SupportType.COMMUNITY
self.support_link: str = "community"
class Footnote(Enum):
@@ -191,7 +189,6 @@ class CAR(Platforms):
],
CarSpecs(mass=1326, wheelbase=2.7, steerRatio=15.38, centerToFrontRatio=0.4), # steerRatio: 10.93 is end-to-end spec
{Bus.pt: 'honda_civic_hatchback_ex_2017_can_generated'},
flags=HondaFlags.ALLOW_MANUAL_TRANS,
)
HONDA_CIVIC_BOSCH_DIESEL = HondaBoschPlatformConfig(
[], # don't show in docs
@@ -221,7 +218,7 @@ class CAR(Platforms):
HONDA_CRV_6G = HondaBoschCANFDPlatformConfig(
[
HondaCarDocs("Honda CR-V 2023-26", "All"),
HondaCarDocs("Honda CR-V Hybrid 2023-26", "All"),
HondaCarDocs("Honda CR-V Hybrid 2023-25", "All"),
],
CarSpecs(mass=1703, wheelbase=2.7, steerRatio=16.2, centerToFrontRatio=0.42),
)
@@ -269,7 +266,7 @@ class CAR(Platforms):
)
# mid-model refresh
ACURA_MDX_4G_MMR = HondaBoschCANFDPlatformConfig(
[HondaCarDocs("Acura MDX 2025-26", "All except Type S")],
[HondaCarDocs("Acura MDX 2025", "All except Type S")],
CarSpecs(mass=4544 * CV.LB_TO_KG, wheelbase=2.89, centerToFrontRatio=0.428, steerRatio=16.2),
)
HONDA_ODYSSEY_5G_MMR = HondaBoschPlatformConfig(
@@ -284,11 +281,6 @@ class CAR(Platforms):
{Bus.pt: 'honda_civic_hatchback_ex_2017_can_generated'},
flags=HondaFlags.BOSCH_ALT_RADAR,
)
# mid-model refresh
ACURA_TLX_2G_MMR = HondaBoschCANFDPlatformConfig(
[HondaCarDocs("Acura TLX 2025", "All")],
CarSpecs(mass=3990 * CV.LB_TO_KG, wheelbase=2.87, centerToFrontRatio=0.43, steerRatio=13.7),
)
# Nidec Cars
ACURA_ILX = HondaNidecPlatformConfig(
@@ -336,12 +328,6 @@ class CAR(Platforms):
radar_dbc_dict('honda_odyssey_exl_2018_generated'),
flags=HondaFlags.NIDEC_ALT_PCM_ACCEL | HondaFlags.HAS_ALL_DOOR_STATES,
)
HONDA_ODYSSEY_TWN = HondaNidecPlatformConfig(
[HondaCarDocs("Honda Odyssey (Taiwan) 2018-19")],
CarSpecs(mass=1865, wheelbase=2.9, steerRatio=14.35, centerToFrontRatio=0.44, tireStiffnessFactor=0.82),
radar_dbc_dict('honda_odyssey_twn_2018_generated'),
flags=HondaFlags.NIDEC_ALT_SCM_MESSAGES,
)
ACURA_RDX = HondaNidecPlatformConfig(
[HondaCarDocs("Acura RDX 2016-18", "AcuraWatch Plus or Advance Package", min_steer_speed=12. * CV.MPH_TO_MS)],
CarSpecs(mass=3925 * CV.LB_TO_KG, wheelbase=2.68, steerRatio=15.0, centerToFrontRatio=0.38, tireStiffnessFactor=0.444), # as spec
@@ -71,7 +71,7 @@ class CarController(CarControllerBase, EsccCarController, LeadDataCarController,
EsccCarController.update(self, CS)
LeadDataCarController.update(self, CC_SP)
MadsCarController.update(self, self.CP, CC, CC_SP, self.frame)
if self.frame % 5 == 0:
if self.frame % 2 == 0:
LongitudinalController.update(self, CC, CS)
actuators = CC.actuators
@@ -701,7 +701,6 @@ FW_VERSIONS = {
b'\xf1\x00OSP MDPS C 1.00 1.02 56310-K4271 4OEPC102',
b'\xf1\x00OSP MDPS C 1.00 1.02 56310/K4271 4OEPC102',
b'\xf1\x00OSP MDPS C 1.00 1.02 56310/K4970 4OEPC102',
b'\xf1\x00OSP MDPS C 1.00 1.02 56310/K4971 4OEPC102',
b'\xf1\x00OSP MDPS C 1.00 1.02 56310K4260\x00 4OEPC102',
b'\xf1\x00OSP MDPS C 1.00 1.02 56310K4261\x00 4OEPC102',
b'\xf1\x00OSP MDPS C 1.00 1.02 56310K4971\x00 4OEPC102',
@@ -864,11 +863,9 @@ FW_VERSIONS = {
CAR.KIA_OPTIMA_H_G4_FL: {
(Ecu.fwdRadar, 0x7d0, None): [
b'\xf1\x00JFhe SCC FHCUP 1.00 1.01 99110-A8500 ',
b'\xf1\x00JFhe SCC FHCUP 1.00 1.03 99110-A8500 ',
],
(Ecu.fwdCamera, 0x7c4, None): [
b'\xf1\x00JFH MFC AT KOR LHD 1.00 1.01 95895-A8200 180323',
b'\xf1\x00JFH MFC AT KOR LHD 1.00 1.04 95895-A8200 181217',
],
},
CAR.HYUNDAI_ELANTRA: {
@@ -1088,14 +1085,12 @@ FW_VERSIONS = {
b'\xf1\x00NX4 FR_CMR AT USA LHD 1.00 1.00 99211-N9260 14Y',
b'\xf1\x00NX4 FR_CMR AT USA LHD 1.00 1.01 99211-N9100 14A',
b'\xf1\x00NX4 FR_CMR AT USA LHD 1.00 1.01 99211-N9240 14T',
b'\xf1\x00NX4 FR_CMR AT EUR LHD 1.00 1.00 99211-N9240 14Q',
],
(Ecu.fwdRadar, 0x7d0, None): [
b'\xf1\x00NX4__ 1.00 1.00 99110-N9100 ',
b'\xf1\x00NX4__ 1.00 1.01 99110-N9000 ',
b'\xf1\x00NX4__ 1.00 1.02 99110-N9000 ',
b'\xf1\x00NX4__ 1.01 1.00 99110-N9100 ',
b'\xf1\x00NX4__ 1.01 1.02 99110-N9000 ',
],
},
CAR.HYUNDAI_SANTA_CRUZ_1ST_GEN: {
@@ -1119,7 +1114,6 @@ FW_VERSIONS = {
b'\xf1\x00NQ5 FR_CMR AT USA LHD 1.00 1.00 99211-P1040 663',
b'\xf1\x00NQ5 FR_CMR AT USA LHD 1.00 1.00 99211-P1060 665',
b'\xf1\x00NQ5 FR_CMR AT USA LHD 1.00 1.00 99211-P1070 690',
b'\xf1\x00NQ5 FR_CMR AT USA LHD 1.00 1.01 99211-P1060 680',
],
(Ecu.fwdRadar, 0x7d0, None): [
b'\xf1\x00NQ5__ 1.00 1.02 99110-P1000 ',

Some files were not shown because too many files have changed in this diff Show More