mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-07-19 00:02:08 +08:00
openpilot v0.9.2 release
date: 2023-05-18T22:02:42 master commit: c7d3b28b93faa6c955fb24bc64031512ee985ee9
This commit is contained in:
@@ -46,9 +46,6 @@ selfdrive/mapd/default_speeds_by_region.json
|
||||
system/proclogd/proclogd
|
||||
selfdrive/ui/_ui
|
||||
selfdrive/test/longitudinal_maneuvers/out
|
||||
selfdrive/visiond/visiond
|
||||
selfdrive/sensord/_gpsd
|
||||
selfdrive/sensord/_sensord
|
||||
system/camerad/camerad
|
||||
system/camerad/test/ae_gray_test
|
||||
selfdrive/modeld/_modeld
|
||||
|
||||
Vendored
+26
-13
@@ -19,6 +19,9 @@ source ~/.bash_profile
|
||||
if [ -f /TICI ]; then
|
||||
source /etc/profile
|
||||
fi
|
||||
if [ -f /data/openpilot/launch_env.sh ]; then
|
||||
source /data/openpilot/launch_env.sh
|
||||
fi
|
||||
|
||||
ln -snf ${env.TEST_DIR} /data/pythonpath
|
||||
|
||||
@@ -125,6 +128,21 @@ pipeline {
|
||||
}
|
||||
*/
|
||||
|
||||
stage('tizi-tests') {
|
||||
agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root' } }
|
||||
steps {
|
||||
phone_steps("tizi", [
|
||||
["build openpilot", "cd selfdrive/manager && ./build.py"],
|
||||
["test boardd loopback", "SINGLE_PANDA=1 python selfdrive/boardd/tests/test_boardd_loopback.py"],
|
||||
["test pandad", "python selfdrive/boardd/tests/test_pandad.py"],
|
||||
["test sensord", "cd system/sensord/tests && python -m unittest test_sensord.py"],
|
||||
["test camerad", "python system/camerad/test/test_camerad.py"],
|
||||
["test exposure", "python system/camerad/test/test_exposure.py"],
|
||||
["test amp", "python system/hardware/tici/tests/test_amplifier.py"],
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
stage('build') {
|
||||
agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root' } }
|
||||
environment {
|
||||
@@ -156,16 +174,17 @@ pipeline {
|
||||
steps {
|
||||
phone_steps("tici-common", [
|
||||
["build", "cd selfdrive/manager && ./build.py"],
|
||||
["test power draw", "python system/hardware/tici/test_power_draw.py"],
|
||||
["test loggerd", "python selfdrive/loggerd/tests/test_loggerd.py"],
|
||||
["test encoder", "LD_LIBRARY_PATH=/usr/local/lib python selfdrive/loggerd/tests/test_encoder.py"],
|
||||
["test pigeond", "python selfdrive/sensord/tests/test_pigeond.py"],
|
||||
["test power draw", "python system/hardware/tici/tests/test_power_draw.py"],
|
||||
["test loggerd", "python system/loggerd/tests/test_loggerd.py"],
|
||||
["test encoder", "LD_LIBRARY_PATH=/usr/local/lib python system/loggerd/tests/test_encoder.py"],
|
||||
["test pigeond", "python system/sensord/tests/test_pigeond.py"],
|
||||
["test manager", "python selfdrive/manager/test/test_manager.py"],
|
||||
["test pandad", "python selfdrive/boardd/tests/test_pandad.py"],
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
stage('camerad-ar') {
|
||||
stage('camerad') {
|
||||
agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root' } }
|
||||
steps {
|
||||
phone_steps("tici-ar0231", [
|
||||
@@ -173,12 +192,6 @@ pipeline {
|
||||
["test camerad", "python system/camerad/test/test_camerad.py"],
|
||||
["test exposure", "python system/camerad/test/test_exposure.py"],
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
stage('camerad-ox') {
|
||||
agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root' } }
|
||||
steps {
|
||||
phone_steps("tici-ox03c10", [
|
||||
["build", "cd selfdrive/manager && ./build.py"],
|
||||
["test camerad", "python system/camerad/test/test_camerad.py"],
|
||||
@@ -192,11 +205,11 @@ pipeline {
|
||||
steps {
|
||||
phone_steps("tici-lsmc", [
|
||||
["build", "cd selfdrive/manager && ./build.py"],
|
||||
["test sensord", "cd selfdrive/sensord/tests && python -m unittest test_sensord.py"],
|
||||
["test sensord", "cd system/sensord/tests && python -m unittest test_sensord.py"],
|
||||
])
|
||||
phone_steps("tici-bmx-lsm", [
|
||||
["build", "cd selfdrive/manager && ./build.py"],
|
||||
["test sensord", "cd selfdrive/sensord/tests && python -m unittest test_sensord.py"],
|
||||
["test sensord", "cd system/sensord/tests && python -m unittest test_sensord.py"],
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ To use openpilot in a car, you need four things
|
||||
* A supported device to run this software: a [comma three](https://comma.ai/shop/products/three).
|
||||
* This software. The setup procedure of the comma three allows the user to enter a URL for custom software.
|
||||
The URL, openpilot.comma.ai will install the release version of openpilot. To install openpilot master, you can use installer.comma.ai/commaai/master, and replacing commaai with another GitHub username can install a fork.
|
||||
* One of [the 200+ supported cars](docs/CARS.md). We support Honda, Toyota, Hyundai, Nissan, Kia, Chrysler, Lexus, Acura, Audi, VW, and more. If your car is not supported but has adaptive cruise control and lane-keeping assist, it's likely able to run openpilot.
|
||||
* One of [the 250+ supported cars](docs/CARS.md). We support Honda, Toyota, Hyundai, Nissan, Kia, Chrysler, Lexus, Acura, Audi, VW, Ford and more. If your car is not supported but has adaptive cruise control and lane-keeping assist, it's likely able to run openpilot.
|
||||
* A [car harness](https://comma.ai/shop/products/car-harness) to connect to your car.
|
||||
|
||||
We have detailed instructions for [how to mount the device in a car](https://comma.ai/setup).
|
||||
@@ -67,7 +67,7 @@ Documentation related to openpilot development can be found on [docs.comma.ai](h
|
||||
|
||||
You can add support for your car by following guides we have written for [Brand](https://blog.comma.ai/how-to-write-a-car-port-for-openpilot/) and [Model](https://blog.comma.ai/openpilot-port-guide-for-toyota-models/) ports. Generally, a car with adaptive cruise control and lane keep assist is a good candidate. [Join our Discord](https://discord.comma.ai) to discuss car ports: most car makes have a dedicated channel.
|
||||
|
||||
Want to get paid to work on openpilot? [comma is hiring](https://comma.ai/jobs/).
|
||||
Want to get paid to work on openpilot? [comma is hiring](https://comma.ai/jobs#open-positions).
|
||||
|
||||
And [follow us on Twitter](https://twitter.com/comma_ai).
|
||||
|
||||
@@ -108,7 +108,10 @@ Directory Structure
|
||||
├── clocksd # Broadcasts current time
|
||||
├── hardware # Hardware abstraction classes
|
||||
├── logcatd # systemd journal as a service
|
||||
└── proclogd # Logs information from /proc
|
||||
├── loggerd # Logger and uploader of car data
|
||||
├── proclogd # Logs information from /proc
|
||||
├── sensord # IMU interface code
|
||||
└── ubloxd # u-blox GNSS module interface code
|
||||
└── selfdrive # Code needed to drive the car
|
||||
├── assets # Fonts, images, and sounds for UI
|
||||
├── athena # Allows communication with the app
|
||||
@@ -117,12 +120,10 @@ Directory Structure
|
||||
├── controls # Planning and controls
|
||||
├── debug # Tools to help you debug and do car ports
|
||||
├── locationd # Precise localization and vehicle parameter estimation
|
||||
├── loggerd # Logger and uploader of car data
|
||||
├── manager # Daemon that starts/stops all other daemons as needed
|
||||
├── modeld # Driving and monitoring model runners
|
||||
├── monitoring # Daemon to determine driver attention
|
||||
├── navd # Turn-by-turn navigation
|
||||
├── sensord # IMU interface code
|
||||
├── test # Unit tests, system tests, and a car simulator
|
||||
└── ui # The UI
|
||||
|
||||
|
||||
+27
@@ -1,3 +1,30 @@
|
||||
Version 0.9.2 (2023-05-22)
|
||||
========================
|
||||
* New driving model
|
||||
* Reduced turn diving
|
||||
* Trained on a new dataset
|
||||
* UI updates
|
||||
* New experimental mode visualization
|
||||
* Draw MPC path instead of model-predicted path
|
||||
* AGNOS 7
|
||||
* Faster boot time
|
||||
* Fixes rare no sounds bug
|
||||
* Fixes bootsplash bug at extreme temperatures
|
||||
* Buick LaCrosse 2017-19 support thanks to koch-cf!
|
||||
* Chevrolet Trailblazer 2021-22 support thanks to TurboCE!
|
||||
* Ford Bronco Sport 2021-22 support
|
||||
* Ford Escape 2020-22 support
|
||||
* Ford Explorer 2020-22 support
|
||||
* Ford Kuga 2020-22 support
|
||||
* Ford Maverick 2022-23 support
|
||||
* Genesis GV80 2023 support thanks to JWingate80!
|
||||
* Honda HR-V 2023 support thanks to AlexandreSato and galegozi!
|
||||
* Kia Niro EV 2023 support thanks to JosselinLecocq!
|
||||
* Lexus ES 2017-18 support
|
||||
* Lincoln Aviator 2021 support
|
||||
* Škoda Fabia 2022-23 support thanks to jyoung8607!
|
||||
|
||||
|
||||
Version 0.9.1 (2023-02-28)
|
||||
========================
|
||||
* New driving model
|
||||
|
||||
+24
-18
@@ -5,6 +5,10 @@ import sysconfig
|
||||
import platform
|
||||
import numpy as np
|
||||
|
||||
import SCons.Errors
|
||||
|
||||
SCons.Warnings.warningAsException(True)
|
||||
|
||||
TICI = os.path.isfile('/TICI')
|
||||
AGNOS = TICI
|
||||
|
||||
@@ -118,7 +122,7 @@ else:
|
||||
f"#third_party/libyuv/{yuv_dir}/lib",
|
||||
f"{brew_prefix}/lib",
|
||||
f"{brew_prefix}/Library",
|
||||
f"{brew_prefix}/opt/openssl/lib",
|
||||
f"{brew_prefix}/opt/openssl@3.0/lib",
|
||||
f"{brew_prefix}/Cellar",
|
||||
"/System/Library/Frameworks/OpenGL.framework/Libraries",
|
||||
]
|
||||
@@ -131,7 +135,7 @@ else:
|
||||
cxxflags += ["-DGL_SILENCE_DEPRECATION"]
|
||||
cpppath += [
|
||||
f"{brew_prefix}/include",
|
||||
f"{brew_prefix}/opt/openssl/include",
|
||||
f"{brew_prefix}/opt/openssl@3.0/include",
|
||||
]
|
||||
# Linux 86_64
|
||||
else:
|
||||
@@ -310,8 +314,14 @@ else:
|
||||
qt_env.PrependENVPath('PATH', Dir("#third_party/qt5/larch64/bin/").abspath)
|
||||
elif arch != "Darwin":
|
||||
qt_libs += ["GL"]
|
||||
qt_env['QT3DIR'] = qt_env['QTDIR']
|
||||
|
||||
# compatibility for older SCons versions
|
||||
try:
|
||||
qt_env.Tool('qt3')
|
||||
except SCons.Errors.UserError:
|
||||
qt_env.Tool('qt')
|
||||
|
||||
qt_env.Tool('qt')
|
||||
qt_env['CPPPATH'] += qt_dirs + ["#selfdrive/ui/qt/"]
|
||||
qt_flags = [
|
||||
"-D_REENTRANT",
|
||||
@@ -395,12 +405,17 @@ SConscript(['rednose/SConscript'])
|
||||
|
||||
# Build system services
|
||||
SConscript([
|
||||
'system/camerad/SConscript',
|
||||
'system/clocksd/SConscript',
|
||||
'system/proclogd/SConscript',
|
||||
'system/ubloxd/SConscript',
|
||||
'system/loggerd/SConscript',
|
||||
])
|
||||
if arch != "Darwin":
|
||||
SConscript(['system/logcatd/SConscript'])
|
||||
SConscript([
|
||||
'system/camerad/SConscript',
|
||||
'system/sensord/SConscript',
|
||||
'system/logcatd/SConscript',
|
||||
])
|
||||
|
||||
# Build openpilot
|
||||
|
||||
@@ -417,25 +432,16 @@ SConscript(['third_party/SConscript'])
|
||||
SConscript(['common/kalman/SConscript'])
|
||||
SConscript(['common/transformations/SConscript'])
|
||||
|
||||
SConscript(['selfdrive/modeld/SConscript'])
|
||||
|
||||
SConscript(['selfdrive/boardd/SConscript'])
|
||||
SConscript(['selfdrive/controls/lib/lateral_mpc_lib/SConscript'])
|
||||
SConscript(['selfdrive/controls/lib/longitudinal_mpc_lib/SConscript'])
|
||||
|
||||
SConscript(['selfdrive/boardd/SConscript'])
|
||||
|
||||
SConscript(['selfdrive/loggerd/SConscript'])
|
||||
|
||||
SConscript(['selfdrive/locationd/SConscript'])
|
||||
SConscript(['selfdrive/sensord/SConscript'])
|
||||
SConscript(['selfdrive/ui/SConscript'])
|
||||
SConscript(['selfdrive/navd/SConscript'])
|
||||
SConscript(['selfdrive/modeld/SConscript'])
|
||||
SConscript(['selfdrive/ui/SConscript'])
|
||||
|
||||
if arch in ['x86_64', 'Darwin'] or GetOption('extras'):
|
||||
if (arch in ['x86_64', 'Darwin'] and Dir('#tools/cabana/').exists()) or GetOption('extras'):
|
||||
SConscript(['tools/replay/SConscript'])
|
||||
|
||||
opendbc = abspath([File('opendbc/can/libdbc.so')])
|
||||
Export('opendbc')
|
||||
SConscript(['tools/cabana/SConscript'])
|
||||
|
||||
external_sconscript = GetOption('external_sconscript')
|
||||
|
||||
+8
-6
@@ -43,6 +43,7 @@ struct CarEvent @0x9b1657f34caf3ad3 {
|
||||
overheat @19;
|
||||
calibrationIncomplete @20;
|
||||
calibrationInvalid @21;
|
||||
calibrationRecalibrating @117;
|
||||
controlsMismatch @22;
|
||||
pcmEnable @23;
|
||||
pcmDisable @24;
|
||||
@@ -65,7 +66,6 @@ struct CarEvent @0x9b1657f34caf3ad3 {
|
||||
lowBattery @48;
|
||||
vehicleModelInvalid @50;
|
||||
accFaulted @51;
|
||||
accFaultedTemp @115;
|
||||
sensorDataInvalid @52;
|
||||
commIssue @53;
|
||||
commIssueAvgFreq @109;
|
||||
@@ -114,6 +114,8 @@ struct CarEvent @0x9b1657f34caf3ad3 {
|
||||
canBusMissing @111;
|
||||
controlsdLagging @112;
|
||||
resumeBlocked @113;
|
||||
steerTimeLimit @115;
|
||||
vehicleSensorsInvalid @116;
|
||||
|
||||
radarCanErrorDEPRECATED @15;
|
||||
communityFeatureDisallowedDEPRECATED @62;
|
||||
@@ -579,7 +581,7 @@ struct CarParams {
|
||||
noOutput @19; # like silent but without silent CAN TXs
|
||||
hondaBosch @20;
|
||||
volkswagenPq @21;
|
||||
subaruLegacy @22; # pre-Global platform
|
||||
subaruPreglobal @22; # pre-Global platform
|
||||
hyundaiLegacy @23;
|
||||
hyundaiCommunity @24;
|
||||
volkswagenMlb @25;
|
||||
@@ -612,6 +614,7 @@ struct CarParams {
|
||||
brand @6 :Text;
|
||||
bus @7 :UInt8;
|
||||
logging @8 :Bool;
|
||||
obdMultiplexing @9 :Bool;
|
||||
}
|
||||
|
||||
enum Ecu {
|
||||
@@ -630,10 +633,11 @@ struct CarParams {
|
||||
shiftByWire @16;
|
||||
adas @19;
|
||||
cornerRadar @21;
|
||||
hvac @20;
|
||||
parkingAdas @7; # parking assist system ECU, e.g. Toyota's IPAS, Hyundai's RSPA, etc.
|
||||
|
||||
# Toyota only
|
||||
dsu @6;
|
||||
apgs @7;
|
||||
|
||||
# Honda only
|
||||
vsa @13; # Vehicle Stability Assist
|
||||
@@ -642,10 +646,8 @@ struct CarParams {
|
||||
# Chrysler only
|
||||
hcp @18; # Hybrid Control Processor
|
||||
|
||||
# Hyundai only
|
||||
vcu @20; # Vehicle (Motor) Control Unit
|
||||
|
||||
debug @17;
|
||||
unused @22;
|
||||
}
|
||||
|
||||
enum FingerprintSource {
|
||||
|
||||
+100
-39
@@ -46,6 +46,7 @@ struct InitData {
|
||||
chffrIos @3;
|
||||
tici @4;
|
||||
pc @5;
|
||||
tizi @6;
|
||||
}
|
||||
|
||||
struct PandaInfo {
|
||||
@@ -139,16 +140,6 @@ struct FrameData {
|
||||
targetGreyFraction @22 :Float32;
|
||||
exposureValPercent @27 :Float32;
|
||||
|
||||
# Focus
|
||||
lensPos @11 :Int32;
|
||||
lensSag @12 :Float32;
|
||||
lensErr @13 :Float32;
|
||||
lensTruePos @14 :Float32;
|
||||
focusVal @16 :List(Int16);
|
||||
focusConf @17 :List(UInt8);
|
||||
sharpnessScore @18 :List(UInt16);
|
||||
recoverState @19 :Int32;
|
||||
|
||||
transform @10 :List(Float32);
|
||||
|
||||
image @6 :Data;
|
||||
@@ -171,6 +162,14 @@ struct FrameData {
|
||||
|
||||
globalGainDEPRECATED @5 :Int32;
|
||||
androidCaptureResultDEPRECATED @9 :AndroidCaptureResult;
|
||||
lensPosDEPRECATED @11 :Int32;
|
||||
lensSagDEPRECATED @12 :Float32;
|
||||
lensErrDEPRECATED @13 :Float32;
|
||||
lensTruePosDEPRECATED @14 :Float32;
|
||||
focusValDEPRECATED @16 :List(Int16);
|
||||
focusConfDEPRECATED @17 :List(UInt8);
|
||||
sharpnessScoreDEPRECATED @18 :List(UInt16);
|
||||
recoverStateDEPRECATED @19 :Int32;
|
||||
struct AndroidCaptureResult {
|
||||
sensitivity @0 :Int32;
|
||||
frameDuration @1 :Int64;
|
||||
@@ -409,10 +408,16 @@ struct PandaState @0xa7649e2575e4591e {
|
||||
powerSaveEnabled @16 :Bool;
|
||||
uptime @17 :UInt32;
|
||||
faults @18 :List(FaultType);
|
||||
harnessStatus @21 :HarnessStatus;
|
||||
heartbeatLost @22 :Bool;
|
||||
interruptLoad @25 :Float32;
|
||||
fanPower @28 :UInt8;
|
||||
fanStallCount @34 :UInt8;
|
||||
|
||||
spiChecksumErrorCount @33 :UInt16;
|
||||
|
||||
harnessStatus @21 :HarnessStatus;
|
||||
sbu1Voltage @35 :Float32;
|
||||
sbu2Voltage @36 :Float32;
|
||||
|
||||
# can health
|
||||
canState0 @29 :PandaCanState;
|
||||
@@ -428,6 +433,9 @@ struct PandaState @0xa7649e2575e4591e {
|
||||
alternativeExperience @23 :Int16;
|
||||
safetyRxChecksInvalid @32 :Bool;
|
||||
|
||||
voltage @0 :UInt32;
|
||||
current @1 :UInt32;
|
||||
|
||||
enum FaultStatus {
|
||||
none @0;
|
||||
faultTemp @1;
|
||||
@@ -460,6 +468,8 @@ struct PandaState @0xa7649e2575e4591e {
|
||||
interruptRateExti @22;
|
||||
interruptRateSpi @23;
|
||||
interruptRateUart7 @24;
|
||||
sirenMalfunction @25;
|
||||
heartbeatLoopWatchdog @26;
|
||||
# Update max fault type in boardd when adding faults
|
||||
}
|
||||
|
||||
@@ -482,15 +492,6 @@ struct PandaState @0xa7649e2575e4591e {
|
||||
flipped @2;
|
||||
}
|
||||
|
||||
startedSignalDetectedDEPRECATED @5 :Bool;
|
||||
voltageDEPRECATED @0 :UInt32;
|
||||
currentDEPRECATED @1 :UInt32;
|
||||
hasGpsDEPRECATED @6 :Bool;
|
||||
fanSpeedRpmDEPRECATED @11 :UInt16;
|
||||
usbPowerModeDEPRECATED @12 :PeripheralState.UsbPowerModeDEPRECATED;
|
||||
safetyParamDEPRECATED @20 :Int16;
|
||||
safetyParam2DEPRECATED @26 :UInt32;
|
||||
|
||||
struct PandaCanState {
|
||||
busOff @0 :Bool;
|
||||
busOffCnt @1 :UInt32;
|
||||
@@ -525,6 +526,13 @@ struct PandaState @0xa7649e2575e4591e {
|
||||
noChange @7;
|
||||
}
|
||||
}
|
||||
|
||||
startedSignalDetectedDEPRECATED @5 :Bool;
|
||||
hasGpsDEPRECATED @6 :Bool;
|
||||
fanSpeedRpmDEPRECATED @11 :UInt16;
|
||||
usbPowerModeDEPRECATED @12 :PeripheralState.UsbPowerModeDEPRECATED;
|
||||
safetyParamDEPRECATED @20 :Int16;
|
||||
safetyParam2DEPRECATED @26 :UInt32;
|
||||
}
|
||||
|
||||
struct PeripheralState {
|
||||
@@ -581,7 +589,7 @@ struct RadarState @0x9a185389d6fdd05f {
|
||||
}
|
||||
|
||||
struct LiveCalibrationData {
|
||||
calStatus @1 :Int8;
|
||||
calStatus @11 :Status;
|
||||
calCycle @2 :Int32;
|
||||
calPerc @3 :Int8;
|
||||
validBlocks @9 :Int32;
|
||||
@@ -595,8 +603,16 @@ struct LiveCalibrationData {
|
||||
wideFromDeviceEuler @10 :List(Float32);
|
||||
|
||||
warpMatrixDEPRECATED @0 :List(Float32);
|
||||
calStatusDEPRECATED @1 :Int8;
|
||||
warpMatrix2DEPRECATED @5 :List(Float32);
|
||||
warpMatrixBigDEPRECATED @6 :List(Float32);
|
||||
|
||||
enum Status {
|
||||
uncalibrated @0;
|
||||
calibrated @1;
|
||||
invalid @2;
|
||||
recalibrating @3;
|
||||
}
|
||||
}
|
||||
|
||||
struct LiveTracks {
|
||||
@@ -794,6 +810,17 @@ struct ControlsState @0x97ff69c53601abf1 {
|
||||
canMonoTimesDEPRECATED @21 :List(UInt64);
|
||||
}
|
||||
|
||||
# All SI units and in device frame
|
||||
struct XYZTData @0xc3cbae1fd505ae80 {
|
||||
x @0 :List(Float32);
|
||||
y @1 :List(Float32);
|
||||
z @2 :List(Float32);
|
||||
t @3 :List(Float32);
|
||||
xStd @4 :List(Float32);
|
||||
yStd @5 :List(Float32);
|
||||
zStd @6 :List(Float32);
|
||||
}
|
||||
|
||||
struct ModelDataV2 {
|
||||
frameId @0 :UInt32;
|
||||
frameIdExtra @20 :UInt32;
|
||||
@@ -827,16 +854,6 @@ struct ModelDataV2 {
|
||||
# Model perceived motion
|
||||
temporalPose @21 :Pose;
|
||||
|
||||
# All SI units and in device frame
|
||||
struct XYZTData {
|
||||
x @0 :List(Float32);
|
||||
y @1 :List(Float32);
|
||||
z @2 :List(Float32);
|
||||
t @3 :List(Float32);
|
||||
xStd @4 :List(Float32);
|
||||
yStd @5 :List(Float32);
|
||||
zStd @6 :List(Float32);
|
||||
}
|
||||
|
||||
struct LeadDataV2 {
|
||||
prob @0 :Float32; # probability that car is your lead at time t
|
||||
@@ -995,6 +1012,11 @@ struct LongitudinalPlan @0xe00b5b3eba12876c {
|
||||
y @1 :List(Float32);
|
||||
}
|
||||
}
|
||||
struct UiPlan {
|
||||
frameId @2 :UInt32;
|
||||
position @0 :XYZTData;
|
||||
accel @1 :List(Float32);
|
||||
}
|
||||
|
||||
struct LateralPlan @0xe1e9318e2ae8b51e {
|
||||
modelMonoTime @31 :UInt64;
|
||||
@@ -1100,6 +1122,7 @@ struct LiveLocationKalman {
|
||||
deviceStable @22 :Bool = true;
|
||||
timeSinceReset @23 :Float64;
|
||||
excessiveResets @24 :Bool;
|
||||
timeToFirstFix @25 :Float32;
|
||||
|
||||
enum Status {
|
||||
uninitialized @0;
|
||||
@@ -1172,13 +1195,22 @@ struct GnssMeasurements {
|
||||
gpsTimeOfWeek @2 :Float64;
|
||||
|
||||
correctedMeasurements @3 :List(CorrectedMeasurement);
|
||||
ephemerisStatuses @9 :List(EphemerisStatus);
|
||||
|
||||
kalmanPositionECEF @4 :LiveLocationKalman.Measurement;
|
||||
kalmanVelocityECEF @5 :LiveLocationKalman.Measurement;
|
||||
positionECEF @6 :LiveLocationKalman.Measurement;
|
||||
velocityECEF @7 :LiveLocationKalman.Measurement;
|
||||
timeToFirstFix @8 :Float32;
|
||||
# Todo sync this with timing pulse of ublox
|
||||
|
||||
struct EphemerisStatus {
|
||||
constellationId @0 :ConstellationId;
|
||||
svId @1 :UInt8;
|
||||
type @2 :EphemerisType;
|
||||
source @3 :EphemerisSource;
|
||||
}
|
||||
|
||||
struct CorrectedMeasurement {
|
||||
constellationId @0 :ConstellationId;
|
||||
svId @1 :UInt8;
|
||||
@@ -1191,11 +1223,11 @@ struct GnssMeasurements {
|
||||
# Satellite position and velocity [x,y,z]
|
||||
satPos @7 :List(Float64);
|
||||
satVel @8 :List(Float64);
|
||||
ephemerisSource @9 :EphemerisSource;
|
||||
ephemerisSourceDEPRECATED @9 :EphemerisSourceDEPRECATED;
|
||||
}
|
||||
|
||||
struct EphemerisSource {
|
||||
type @0 :EphemerisSourceType;
|
||||
struct EphemerisSourceDEPRECATED {
|
||||
type @0 :EphemerisType;
|
||||
# first epoch in file:
|
||||
gpsWeek @1 :Int16; # -1 if Nav
|
||||
gpsTimeOfWeek @2 :Int32; # -1 if Nav. Integer for seconds is good enough for logs.
|
||||
@@ -1212,13 +1244,20 @@ struct GnssMeasurements {
|
||||
glonass @6;
|
||||
}
|
||||
|
||||
enum EphemerisSourceType {
|
||||
enum EphemerisType {
|
||||
nav @0;
|
||||
# Different ultra-rapid files:
|
||||
nasaUltraRapid @1;
|
||||
glonassIacUltraRapid @2;
|
||||
qcom @3;
|
||||
}
|
||||
|
||||
enum EphemerisSource {
|
||||
gnssChip @0;
|
||||
internet @1;
|
||||
cache @2;
|
||||
unknown @3;
|
||||
}
|
||||
}
|
||||
|
||||
struct UbloxGnss {
|
||||
@@ -1229,6 +1268,19 @@ struct UbloxGnss {
|
||||
hwStatus @3 :HwStatus;
|
||||
hwStatus2 @4 :HwStatus2;
|
||||
glonassEphemeris @5 :GlonassEphemeris;
|
||||
satReport @6 :SatReport;
|
||||
}
|
||||
|
||||
struct SatReport {
|
||||
#received time of week in gps time in seconds and gps week
|
||||
iTow @0 :UInt32;
|
||||
svs @1 :List(SatInfo);
|
||||
|
||||
struct SatInfo {
|
||||
svId @0 :UInt8;
|
||||
gnssId @1 :UInt8;
|
||||
flagsBitfield @2 :UInt32;
|
||||
}
|
||||
}
|
||||
|
||||
struct MeasurementReport {
|
||||
@@ -1322,7 +1374,7 @@ struct UbloxGnss {
|
||||
|
||||
iDot @26 :Float64;
|
||||
codesL2 @27 :Float64;
|
||||
gpsWeek @28 :Float64;
|
||||
gpsWeekDEPRECATED @28 :Float64;
|
||||
l2 @29 :Float64;
|
||||
|
||||
svAcc @30 :Float64;
|
||||
@@ -1340,6 +1392,8 @@ struct UbloxGnss {
|
||||
ionoBeta @39 :List(Float64);
|
||||
|
||||
towCount @40 :UInt32;
|
||||
toeWeek @41 :UInt16;
|
||||
tocWeek @42 :UInt16;
|
||||
}
|
||||
|
||||
struct IonoData {
|
||||
@@ -1418,7 +1472,7 @@ struct UbloxGnss {
|
||||
age @17 :UInt8;
|
||||
|
||||
svHealth @18 :UInt8;
|
||||
tk @19 :UInt16;
|
||||
tkDEPRECATED @19 :UInt16;
|
||||
tb @20 :UInt16;
|
||||
|
||||
tauN @21 :Float64;
|
||||
@@ -1430,7 +1484,12 @@ struct UbloxGnss {
|
||||
p3 @26 :UInt8;
|
||||
p4 @27 :UInt8;
|
||||
|
||||
freqNum @28 :UInt32;
|
||||
freqNumDEPRECATED @28 :UInt32;
|
||||
|
||||
n4 @29 :UInt8;
|
||||
nt @30 :UInt16;
|
||||
freqNum @31 :Int16;
|
||||
tkSeconds @32 :UInt32;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1864,7 +1923,6 @@ struct LiveParametersData {
|
||||
stiffnessFactor @4 :Float32;
|
||||
steerRatio @5 :Float32;
|
||||
sensorValid @6 :Bool;
|
||||
yawRate @7 :Float32;
|
||||
posenetSpeed @8 :Float32;
|
||||
posenetValid @9 :Bool;
|
||||
angleOffsetFastStd @10 :Float32;
|
||||
@@ -1872,6 +1930,8 @@ struct LiveParametersData {
|
||||
stiffnessFactorStd @12 :Float32;
|
||||
steerRatioStd @13 :Float32;
|
||||
roll @14 :Float32;
|
||||
|
||||
yawRateDEPRECATED @7 :Float32;
|
||||
}
|
||||
|
||||
struct LiveTorqueParametersData {
|
||||
@@ -2081,6 +2141,7 @@ struct Event {
|
||||
carControl @23 :Car.CarControl;
|
||||
longitudinalPlan @24 :LongitudinalPlan;
|
||||
lateralPlan @64 :LateralPlan;
|
||||
uiPlan @106 :UiPlan;
|
||||
ubloxGnss @34 :UbloxGnss;
|
||||
ubloxRaw @39 :Data;
|
||||
qcomGnss @31 :QcomGnss;
|
||||
|
||||
@@ -94,20 +94,3 @@ Poller * Poller::create(std::vector<SubSocket*> sockets){
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
extern "C" Context * messaging_context_create() {
|
||||
return Context::create();
|
||||
}
|
||||
|
||||
extern "C" SubSocket * messaging_subsocket_create(Context* context, const char* endpoint) {
|
||||
return SubSocket::create(context, std::string(endpoint));
|
||||
}
|
||||
|
||||
extern "C" PubSocket * messaging_pubsocket_create(Context* context, const char* endpoint) {
|
||||
return PubSocket::create(context, std::string(endpoint));
|
||||
}
|
||||
|
||||
extern "C" Poller * messaging_poller_create(SubSocket** sockets, int size) {
|
||||
std::vector<SubSocket*> socketsVec(sockets, sockets + size);
|
||||
return Poller::create(socketsVec);
|
||||
}
|
||||
|
||||
@@ -76,6 +76,7 @@ services = {
|
||||
"navThumbnail": (True, 0.),
|
||||
"navModel": (True, 2., 4.),
|
||||
"mapRenderState": (True, 2., 1.),
|
||||
"uiPlan": (True, 20., 40.),
|
||||
"qRoadEncodeIdx": (False, 20.),
|
||||
"userFlag": (True, 0., 1),
|
||||
"microphone": (True, 10., 10),
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
from libcpp.string cimport string
|
||||
from libcpp.vector cimport vector
|
||||
from libcpp.set cimport set
|
||||
from libc.stdint cimport uint32_t, uint64_t
|
||||
from libcpp cimport bool
|
||||
|
||||
@@ -40,3 +41,5 @@ cdef extern from "cereal/visionipc/visionipc_client.h":
|
||||
VisionBuf * recv(VisionIpcBufExtra *, int)
|
||||
bool connect(bool)
|
||||
bool is_connected()
|
||||
@staticmethod
|
||||
set[VisionStreamType] getAvailableStreams(string, bool)
|
||||
|
||||
@@ -97,3 +97,7 @@ cdef class VisionIpcClient:
|
||||
|
||||
def is_connected(self):
|
||||
return self.client.is_connected()
|
||||
|
||||
@staticmethod
|
||||
def available_streams(string name, bool block):
|
||||
return cppVisionIpcClient.getAvailableStreams(name, block)
|
||||
|
||||
+12
-1
@@ -1,4 +1,5 @@
|
||||
from typing import Optional
|
||||
import glob
|
||||
from typing import Optional, List
|
||||
|
||||
def gpio_init(pin: int, output: bool) -> None:
|
||||
try:
|
||||
@@ -23,3 +24,13 @@ def gpio_read(pin: int) -> Optional[bool]:
|
||||
print(f"Failed to set gpio {pin} value: {e}")
|
||||
|
||||
return val
|
||||
|
||||
def get_irq_for_action(action: str) -> List[int]:
|
||||
ret = []
|
||||
for fn in glob.glob('/sys/kernel/irq/*/actions'):
|
||||
with open(fn) as f:
|
||||
actions = f.read().strip().split(',')
|
||||
if action in actions:
|
||||
irq = int(fn.split('/')[-2])
|
||||
ret.append(irq)
|
||||
return ret
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
#define UNUSED(x) (void)(x)
|
||||
|
||||
#ifdef QCOM2
|
||||
// TODO: decide if we want to isntall libi2c-dev everywhere
|
||||
// TODO: decide if we want to install libi2c-dev everywhere
|
||||
extern "C" {
|
||||
#include <linux/i2c-dev.h>
|
||||
#include <i2c/smbus.h>
|
||||
|
||||
+31
-24
@@ -92,15 +92,15 @@ std::unordered_map<std::string, uint32_t> keys = {
|
||||
{"CameraDebugExpGain", CLEAR_ON_MANAGER_START},
|
||||
{"CameraDebugExpTime", CLEAR_ON_MANAGER_START},
|
||||
{"CarBatteryCapacity", PERSISTENT},
|
||||
{"CarParams", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
|
||||
{"CarParams", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
|
||||
{"CarParamsCache", CLEAR_ON_MANAGER_START},
|
||||
{"CarParamsPersistent", PERSISTENT},
|
||||
{"CarVin", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
|
||||
{"CarVin", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
|
||||
{"CompletedTrainingVersion", PERSISTENT},
|
||||
{"ControlsReady", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
|
||||
{"CurrentRoute", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
|
||||
{"DashcamOverride", PERSISTENT},
|
||||
{"DisableLogging", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
|
||||
{"ControlsReady", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
|
||||
{"CurrentBootlog", PERSISTENT},
|
||||
{"CurrentRoute", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
|
||||
{"DisableLogging", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
|
||||
{"DisablePowerDown", PERSISTENT},
|
||||
{"ExperimentalMode", PERSISTENT},
|
||||
{"ExperimentalModeConfirmed", PERSISTENT},
|
||||
@@ -111,7 +111,7 @@ std::unordered_map<std::string, uint32_t> keys = {
|
||||
{"DoReboot", CLEAR_ON_MANAGER_START},
|
||||
{"DoShutdown", CLEAR_ON_MANAGER_START},
|
||||
{"DoUninstall", CLEAR_ON_MANAGER_START},
|
||||
{"FirmwareObdQueryDone", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
|
||||
{"FirmwareQueryDone", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
|
||||
{"ForcePowerDown", CLEAR_ON_MANAGER_START},
|
||||
{"GitBranch", PERSISTENT},
|
||||
{"GitCommit", PERSISTENT},
|
||||
@@ -137,8 +137,8 @@ std::unordered_map<std::string, uint32_t> keys = {
|
||||
{"IsTestedBranch", CLEAR_ON_MANAGER_START},
|
||||
{"IsReleaseBranch", CLEAR_ON_MANAGER_START},
|
||||
{"IsUpdateAvailable", CLEAR_ON_MANAGER_START},
|
||||
{"JoystickDebugMode", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF},
|
||||
{"LaikadEphemerisV2", PERSISTENT | DONT_LOG},
|
||||
{"JoystickDebugMode", CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION},
|
||||
{"LaikadEphemerisV3", PERSISTENT | DONT_LOG},
|
||||
{"LanguageSetting", PERSISTENT},
|
||||
{"LastAthenaPingTime", CLEAR_ON_MANAGER_START},
|
||||
{"LastGPSPosition", PERSISTENT},
|
||||
@@ -150,29 +150,30 @@ std::unordered_map<std::string, uint32_t> keys = {
|
||||
{"LiveParameters", PERSISTENT},
|
||||
{"LiveTorqueCarParams", PERSISTENT},
|
||||
{"LiveTorqueParameters", PERSISTENT | DONT_LOG},
|
||||
{"NavDestination", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF},
|
||||
{"NavDestinationWaypoints", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF},
|
||||
{"NavDestination", CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION},
|
||||
{"NavDestinationWaypoints", CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION},
|
||||
{"NavSettingTime24h", PERSISTENT},
|
||||
{"NavSettingLeftSide", PERSISTENT},
|
||||
{"NavdRender", PERSISTENT},
|
||||
{"ObdMultiplexingDisabled", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
|
||||
{"ObdMultiplexingChanged", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
|
||||
{"ObdMultiplexingEnabled", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
|
||||
{"OpenpilotEnabledToggle", PERSISTENT},
|
||||
{"PandaHeartbeatLost", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF},
|
||||
{"PandaHeartbeatLost", CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION},
|
||||
{"PandaSignatures", CLEAR_ON_MANAGER_START},
|
||||
{"Passive", PERSISTENT},
|
||||
{"PrimeType", PERSISTENT},
|
||||
{"RecordFront", PERSISTENT},
|
||||
{"RecordFrontLock", PERSISTENT}, // for the internal fleet
|
||||
{"ReplayControlsState", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
|
||||
{"ReplayControlsState", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
|
||||
{"ShouldDoUpdate", CLEAR_ON_MANAGER_START},
|
||||
{"SnoozeUpdate", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF},
|
||||
{"SnoozeUpdate", CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION},
|
||||
{"SshEnabled", PERSISTENT},
|
||||
{"SubscriberInfo", PERSISTENT},
|
||||
{"TermsVersion", PERSISTENT},
|
||||
{"Timezone", PERSISTENT},
|
||||
{"TrainingVersion", PERSISTENT},
|
||||
{"UbloxAvailable", PERSISTENT},
|
||||
{"UpdateAvailable", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
|
||||
{"UpdateAvailable", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
|
||||
{"UpdateFailedCount", CLEAR_ON_MANAGER_START},
|
||||
{"UpdaterState", CLEAR_ON_MANAGER_START},
|
||||
{"UpdaterFetchAvailable", CLEAR_ON_MANAGER_START},
|
||||
@@ -190,17 +191,18 @@ std::unordered_map<std::string, uint32_t> keys = {
|
||||
{"ApiCache_NavDestinations", PERSISTENT},
|
||||
{"ApiCache_Owner", PERSISTENT},
|
||||
{"Offroad_BadNvme", CLEAR_ON_MANAGER_START},
|
||||
{"Offroad_CarUnrecognized", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
|
||||
{"Offroad_CarUnrecognized", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
|
||||
{"Offroad_ConnectivityNeeded", CLEAR_ON_MANAGER_START},
|
||||
{"Offroad_ConnectivityNeededPrompt", CLEAR_ON_MANAGER_START},
|
||||
{"Offroad_InvalidTime", CLEAR_ON_MANAGER_START},
|
||||
{"Offroad_IsTakingSnapshot", CLEAR_ON_MANAGER_START},
|
||||
{"Offroad_NeosUpdate", CLEAR_ON_MANAGER_START},
|
||||
{"Offroad_NoFirmware", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
|
||||
{"Offroad_NoFirmware", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
|
||||
{"Offroad_StorageMissing", CLEAR_ON_MANAGER_START},
|
||||
{"Offroad_TemperatureTooHigh", CLEAR_ON_MANAGER_START},
|
||||
{"Offroad_UnofficialHardware", CLEAR_ON_MANAGER_START},
|
||||
{"Offroad_UpdateFailed", CLEAR_ON_MANAGER_START},
|
||||
{"Offroad_Recalibration", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@@ -304,14 +306,19 @@ std::map<std::string, std::string> Params::readAll() {
|
||||
void Params::clearAll(ParamKeyType key_type) {
|
||||
FileLock file_lock(params_path + "/.lock");
|
||||
|
||||
if (key_type == ALL) {
|
||||
util::remove_files_in_dir(getParamPath());
|
||||
} else {
|
||||
for (auto &[key, type] : keys) {
|
||||
if (type & key_type) {
|
||||
unlink(getParamPath(key).c_str());
|
||||
// 1) delete params of key_type
|
||||
// 2) delete files that are not defined in the keys.
|
||||
if (DIR *d = opendir(getParamPath().c_str())) {
|
||||
struct dirent *de = NULL;
|
||||
while ((de = readdir(d))) {
|
||||
if (de->d_type != DT_DIR) {
|
||||
auto it = keys.find(de->d_name);
|
||||
if (it == keys.end() || (it->second & key_type)) {
|
||||
unlink(getParamPath(de->d_name).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(d);
|
||||
}
|
||||
|
||||
fsync_dir(getParamPath());
|
||||
|
||||
+2
-2
@@ -7,8 +7,8 @@
|
||||
enum ParamKeyType {
|
||||
PERSISTENT = 0x02,
|
||||
CLEAR_ON_MANAGER_START = 0x04,
|
||||
CLEAR_ON_IGNITION_ON = 0x08,
|
||||
CLEAR_ON_IGNITION_OFF = 0x10,
|
||||
CLEAR_ON_ONROAD_TRANSITION = 0x08,
|
||||
CLEAR_ON_OFFROAD_TRANSITION = 0x10,
|
||||
DONT_LOG = 0x20,
|
||||
ALL = 0xFFFFFFFF
|
||||
};
|
||||
|
||||
@@ -9,8 +9,8 @@ cdef extern from "common/params.h":
|
||||
cpdef enum ParamKeyType:
|
||||
PERSISTENT
|
||||
CLEAR_ON_MANAGER_START
|
||||
CLEAR_ON_IGNITION_ON
|
||||
CLEAR_ON_IGNITION_OFF
|
||||
CLEAR_ON_ONROAD_TRANSITION
|
||||
CLEAR_ON_OFFROAD_TRANSITION
|
||||
ALL
|
||||
|
||||
cdef cppclass c_Params "Params":
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "common/statlog.h"
|
||||
#include "common/util.h"
|
||||
|
||||
#include <cstdarg>
|
||||
#include <stdio.h>
|
||||
#include <mutex>
|
||||
#include <zmq.h>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "common/swaglog.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdarg>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <mutex>
|
||||
|
||||
@@ -99,22 +99,6 @@ std::map<std::string, std::string> read_files_in_dir(const std::string &path) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void remove_files_in_dir(const std::string &path) {
|
||||
DIR *d = opendir(path.c_str());
|
||||
if (!d) return;
|
||||
|
||||
std::string fn;
|
||||
struct dirent *de = NULL;
|
||||
while ((de = readdir(d))) {
|
||||
if (de->d_type != DT_DIR) {
|
||||
fn = path + "/" + de->d_name;
|
||||
unlink(fn.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
closedir(d);
|
||||
}
|
||||
|
||||
int write_file(const char* path, const void* data, size_t size, int flags, mode_t mode) {
|
||||
int fd = HANDLE_EINTR(open(path, flags, mode));
|
||||
if (fd == -1) {
|
||||
|
||||
@@ -81,7 +81,6 @@ std::string dir_name(std::string const& path);
|
||||
// **** file fhelpers *****
|
||||
std::string read_file(const std::string& fn);
|
||||
std::map<std::string, std::string> read_files_in_dir(const std::string& path);
|
||||
void remove_files_in_dir(const std::string& path);
|
||||
int write_file(const char* path, const void* data, size_t size, int flags = O_WRONLY, mode_t mode = 0664);
|
||||
|
||||
FILE* safe_fopen(const char* filename, const char* mode);
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
#define COMMA_VERSION "0.9.1"
|
||||
#define COMMA_VERSION "0.9.2"
|
||||
|
||||
+255
-239
@@ -2,249 +2,264 @@
|
||||
|
||||
# Supported Cars
|
||||
|
||||
A supported vehicle is one that just works when you install a comma three. All supported cars provide a better experience than any stock system.
|
||||
A supported vehicle is one that just works when you install a comma three. All supported cars provide a better experience than any stock system. Supported vehicles reference the US market unless otherwise specified.
|
||||
|
||||
# 237 Supported Cars
|
||||
# 252 Supported Cars
|
||||
|
||||
|Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Resume from stop|Harness|Video|
|
||||
|Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Resume from stop|<a href="##"><img width=2000></a>Harness Kit<br> |Video|
|
||||
|---|---|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
||||
|Acura|ILX 2016-19|AcuraWatch Plus|openpilot|25 mph|25 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Acura&model=ILX 2016-19">Honda Nidec</a>||
|
||||
|Acura|RDX 2016-18|AcuraWatch Plus|openpilot|25 mph|12 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Acura&model=RDX 2016-18">Honda Nidec</a>||
|
||||
|Acura|RDX 2019-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Acura&model=RDX 2019-22">Honda Bosch A</a>||
|
||||
|Audi|A3 2014-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Audi&model=A3 2014-19">J533</a>||
|
||||
|Audi|A3 Sportback e-tron 2017-18|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Audi&model=A3 Sportback e-tron 2017-18">J533</a>||
|
||||
|Audi|Q2 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Audi&model=Q2 2018">J533</a>||
|
||||
|Audi|Q3 2019-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Audi&model=Q3 2019-23">J533</a>||
|
||||
|Audi|RS3 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Audi&model=RS3 2018">J533</a>||
|
||||
|Audi|S3 2015-17|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Audi&model=S3 2015-17">J533</a>||
|
||||
|Cadillac|Escalade 2017[<sup>3</sup>](#footnotes)|Driver Assist Package|openpilot|0 mph|7 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Cadillac&model=Escalade 2017">OBD-II</a>||
|
||||
|Cadillac|Escalade ESV 2016[<sup>3</sup>](#footnotes)|Adaptive Cruise Control (ACC) & LKAS|openpilot|0 mph|7 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Cadillac&model=Escalade ESV 2016">OBD-II</a>||
|
||||
|Chevrolet|Bolt EUV 2022-23|Premier or Premier Redline Trim without Super Cruise Package|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Chevrolet&model=Bolt EUV 2022-23">GM</a>|<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|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Chevrolet&model=Bolt EV 2022-23">GM</a>||
|
||||
|Chevrolet|Silverado 1500 2020-21|Safety Package II|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Chevrolet&model=Silverado 1500 2020-21">GM</a>||
|
||||
|Chevrolet|Volt 2017-18[<sup>3</sup>](#footnotes)|Adaptive Cruise Control (ACC)|openpilot|0 mph|7 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Chevrolet&model=Volt 2017-18">OBD-II</a>|<a href="https://youtu.be/QeMCN_4TFfQ" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Chrysler|Pacifica 2017-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Chrysler&model=Pacifica 2017-18">FCA</a>||
|
||||
|Chrysler|Pacifica 2019-20|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Chrysler&model=Pacifica 2019-20">FCA</a>||
|
||||
|Chrysler|Pacifica 2021|All|Stock|0 mph|39 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Chrysler&model=Pacifica 2021">FCA</a>||
|
||||
|Chrysler|Pacifica Hybrid 2017-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Chrysler&model=Pacifica Hybrid 2017-18">FCA</a>||
|
||||
|Chrysler|Pacifica Hybrid 2019-22|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Chrysler&model=Pacifica Hybrid 2019-22">FCA</a>||
|
||||
|Acura|ILX 2016-19|AcuraWatch Plus|openpilot|25 mph|25 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Acura&model=ILX 2016-19">Honda Nidec connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Acura|RDX 2016-18|AcuraWatch Plus|openpilot|25 mph|12 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Acura&model=RDX 2016-18">Honda Nidec connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Acura|RDX 2019-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Acura&model=RDX 2019-22">Honda Bosch A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Audi|A3 2014-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Audi&model=A3 2014-19">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Audi|A3 Sportback e-tron 2017-18|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Audi&model=A3 Sportback e-tron 2017-18">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Audi|Q2 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Audi&model=Q2 2018">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Audi|Q3 2019-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Audi&model=Q3 2019-23">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Audi|RS3 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Audi&model=RS3 2018">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Audi|S3 2015-17|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Audi&model=S3 2015-17">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Buick|LaCrosse 2017-19[<sup>3</sup>](#footnotes)|Driver Confidence Package 2|openpilot|18 mph|7 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Buick&model=LaCrosse 2017-19">OBD-II connector</a><br>- 1 USB-C coupler<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Cadillac|Escalade 2017[<sup>3</sup>](#footnotes)|Driver Assist Package|openpilot|0 mph|7 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Cadillac&model=Escalade 2017">OBD-II connector</a><br>- 1 USB-C coupler<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Cadillac|Escalade ESV 2016[<sup>3</sup>](#footnotes)|Adaptive Cruise Control (ACC) & LKAS|openpilot|0 mph|7 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Cadillac&model=Escalade ESV 2016">OBD-II connector</a><br>- 1 USB-C coupler<br>- 1 long OBD-C cable</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|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Chevrolet&model=Bolt EUV 2022-23">GM connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</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|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Chevrolet&model=Bolt EV 2022-23">GM connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Chevrolet|Silverado 1500 2020-21|Safety Package II|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Chevrolet&model=Silverado 1500 2020-21">GM connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Chevrolet|Trailblazer 2021-22|Adaptive Cruise Control (ACC)|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Chevrolet&model=Trailblazer 2021-22">GM connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Chevrolet|Volt 2017-18[<sup>3</sup>](#footnotes)|Adaptive Cruise Control (ACC)|openpilot|0 mph|7 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Chevrolet&model=Volt 2017-18">OBD-II connector</a><br>- 1 USB-C coupler<br>- 1 long OBD-C cable</sub></details>|<a href="https://youtu.be/QeMCN_4TFfQ" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Chrysler|Pacifica 2017-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Chrysler&model=Pacifica 2017-18">FCA connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Chrysler|Pacifica 2019-20|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Chrysler&model=Pacifica 2019-20">FCA connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Chrysler|Pacifica 2021|All|Stock|0 mph|39 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Chrysler&model=Pacifica 2021">FCA connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Chrysler|Pacifica Hybrid 2017-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Chrysler&model=Pacifica Hybrid 2017-18">FCA connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Chrysler|Pacifica Hybrid 2019-23|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Chrysler&model=Pacifica Hybrid 2019-23">FCA connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|comma|body|All|openpilot|0 mph|0 mph|[](##)|[](##)|None||
|
||||
|Genesis|G70 2018-19|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Genesis&model=G70 2018-19">Hyundai F</a>||
|
||||
|Genesis|G70 2020|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Genesis&model=G70 2020">Hyundai F</a>||
|
||||
|Genesis|G80 2017|All|Stock|19 mph|37 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Genesis&model=G80 2017">Hyundai J</a>||
|
||||
|Genesis|G80 2018-19|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Genesis&model=G80 2018-19">Hyundai H</a>||
|
||||
|Genesis|G90 2017-18|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Genesis&model=G90 2017-18">Hyundai C</a>||
|
||||
|Genesis|GV60 (Advanced Trim) 2023[<sup>5</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Genesis&model=GV60 (Advanced Trim) 2023">Hyundai A</a>||
|
||||
|Genesis|GV60 (Performance Trim) 2023[<sup>5</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Genesis&model=GV60 (Performance Trim) 2023">Hyundai K</a>||
|
||||
|Genesis|GV70 2022-23[<sup>5</sup>](#footnotes)|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Genesis&model=GV70 2022-23">Hyundai L</a>||
|
||||
|GMC|Acadia 2018[<sup>3</sup>](#footnotes)|Adaptive Cruise Control (ACC)|openpilot|0 mph|7 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=GMC&model=Acadia 2018">OBD-II</a>|<a href="https://www.youtube.com/watch?v=0ZN6DdsBUZo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|GMC|Sierra 1500 2020-21|Driver Alert Package II|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=GMC&model=Sierra 1500 2020-21">GM</a>|<a href="https://youtu.be/5HbNoBLzRwE" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Honda|Accord 2018-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Accord 2018-22">Honda Bosch A</a>|<a href="https://www.youtube.com/watch?v=mrUwlj3Mi58" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Honda|Accord Hybrid 2018-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Accord Hybrid 2018-22">Honda Bosch A</a>||
|
||||
|Honda|Civic 2016-18|Honda Sensing|openpilot|0 mph|12 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Civic 2016-18">Honda Nidec</a>|<a href="https://youtu.be/-IkImTe1NYE" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Honda|Civic 2019-21|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|2 mph[<sup>4</sup>](#footnotes)|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Civic 2019-21">Honda Bosch A</a>|<a href="https://www.youtube.com/watch?v=4Iz1Mz5LGF8" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Honda|Civic 2022|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Civic 2022">Honda Bosch B</a>||
|
||||
|Honda|Civic Hatchback 2017-21|Honda Sensing|openpilot available[<sup>1</sup>](#footnotes)|0 mph|12 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Civic Hatchback 2017-21">Honda Bosch A</a>||
|
||||
|Honda|Civic Hatchback 2022|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Civic Hatchback 2022">Honda Bosch B</a>||
|
||||
|Honda|CR-V 2015-16|Touring Trim|openpilot|25 mph|12 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Honda&model=CR-V 2015-16">Honda Nidec</a>||
|
||||
|Honda|CR-V 2017-22|Honda Sensing|openpilot available[<sup>1</sup>](#footnotes)|0 mph|12 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Honda&model=CR-V 2017-22">Honda Bosch A</a>||
|
||||
|Honda|CR-V Hybrid 2017-19|Honda Sensing|openpilot available[<sup>1</sup>](#footnotes)|0 mph|12 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Honda&model=CR-V Hybrid 2017-19">Honda Bosch A</a>||
|
||||
|Honda|e 2020|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Honda&model=e 2020">Honda Bosch A</a>||
|
||||
|Honda|Fit 2018-20|Honda Sensing|openpilot|25 mph|12 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Fit 2018-20">Honda Nidec</a>||
|
||||
|Honda|Freed 2020|Honda Sensing|openpilot|25 mph|12 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Freed 2020">Honda Nidec</a>||
|
||||
|Honda|HR-V 2019-22|Honda Sensing|openpilot|25 mph|12 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Honda&model=HR-V 2019-22">Honda Nidec</a>||
|
||||
|Honda|Insight 2019-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Insight 2019-22">Honda Bosch A</a>||
|
||||
|Honda|Inspire 2018|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Inspire 2018">Honda Bosch A</a>||
|
||||
|Honda|Odyssey 2018-20|Honda Sensing|openpilot|25 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Odyssey 2018-20">Honda Nidec</a>||
|
||||
|Honda|Passport 2019-21|All|openpilot|25 mph|12 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Passport 2019-21">Honda Nidec</a>||
|
||||
|Honda|Pilot 2016-22|Honda Sensing|openpilot|25 mph|12 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Pilot 2016-22">Honda Nidec</a>||
|
||||
|Honda|Ridgeline 2017-22|Honda Sensing|openpilot|25 mph|12 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Ridgeline 2017-22">Honda Nidec</a>||
|
||||
|Hyundai|Elantra 2017-19|Smart Cruise Control (SCC)|Stock|19 mph|32 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Elantra 2017-19">Hyundai B</a>||
|
||||
|Hyundai|Elantra 2021-23|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Elantra 2021-23">Hyundai K</a>|<a href="https://youtu.be/_EdYQtV52-c" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Hyundai|Elantra GT 2017-19|Smart Cruise Control (SCC)|Stock|0 mph|32 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Elantra GT 2017-19">Hyundai E</a>||
|
||||
|Hyundai|Elantra Hybrid 2021-23|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Elantra Hybrid 2021-23">Hyundai K</a>|<a href="https://youtu.be/_EdYQtV52-c" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Hyundai|Genesis 2015-16|Smart Cruise Control (SCC)|Stock|19 mph|37 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Genesis 2015-16">Hyundai J</a>||
|
||||
|Hyundai|i30 2017-19|Smart Cruise Control (SCC)|Stock|0 mph|32 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=i30 2017-19">Hyundai E</a>||
|
||||
|Hyundai|Ioniq 5 (Southeast Asia only) 2022-23[<sup>5</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Ioniq 5 (Southeast Asia only) 2022-23">Hyundai Q</a>||
|
||||
|Hyundai|Ioniq 5 (with HDA II) 2022-23[<sup>5</sup>](#footnotes)|Highway Driving Assist II|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Ioniq 5 (with HDA II) 2022-23">Hyundai Q</a>||
|
||||
|Hyundai|Ioniq 5 (without HDA II) 2022-23[<sup>5</sup>](#footnotes)|Highway Driving Assist|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Ioniq 5 (without HDA II) 2022-23">Hyundai K</a>||
|
||||
|Hyundai|Ioniq Electric 2019|Smart Cruise Control (SCC)|Stock|0 mph|32 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Ioniq Electric 2019">Hyundai C</a>||
|
||||
|Hyundai|Ioniq Electric 2020|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Ioniq Electric 2020">Hyundai H</a>||
|
||||
|Hyundai|Ioniq Hybrid 2017-19|Smart Cruise Control (SCC)|Stock|0 mph|32 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Ioniq Hybrid 2017-19">Hyundai C</a>||
|
||||
|Hyundai|Ioniq Hybrid 2020-22|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Ioniq Hybrid 2020-22">Hyundai H</a>||
|
||||
|Hyundai|Ioniq Plug-in Hybrid 2019|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|32 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Ioniq Plug-in Hybrid 2019">Hyundai C</a>||
|
||||
|Hyundai|Ioniq Plug-in Hybrid 2020-21|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Ioniq Plug-in Hybrid 2020-21">Hyundai H</a>||
|
||||
|Hyundai|Kona 2020|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Kona 2020">Hyundai B</a>||
|
||||
|Hyundai|Kona Electric 2018-21|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Kona Electric 2018-21">Hyundai G</a>||
|
||||
|Hyundai|Kona Electric 2022|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Kona Electric 2022">Hyundai O</a>||
|
||||
|Hyundai|Kona Hybrid 2020|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Kona Hybrid 2020">Hyundai I</a>|<a href="https://youtu.be/0dwpAHiZgFo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Hyundai|Palisade 2020-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Palisade 2020-22">Hyundai H</a>|<a href="https://youtu.be/TAnDqjF4fDY?t=456" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Hyundai|Santa Cruz 2021-22[<sup>5</sup>](#footnotes)|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Santa Cruz 2021-22">Hyundai N</a>||
|
||||
|Hyundai|Santa Fe 2019-20|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Santa Fe 2019-20">Hyundai D</a>||
|
||||
|Hyundai|Santa Fe 2021-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Santa Fe 2021-22">Hyundai L</a>|<a href="https://youtu.be/VnHzSTygTS4" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Hyundai|Santa Fe Hybrid 2022|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Santa Fe Hybrid 2022">Hyundai L</a>||
|
||||
|Hyundai|Santa Fe Plug-in Hybrid 2022|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Santa Fe Plug-in Hybrid 2022">Hyundai L</a>||
|
||||
|Hyundai|Sonata 2018-19|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Sonata 2018-19">Hyundai E</a>||
|
||||
|Hyundai|Sonata 2020-23|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Sonata 2020-23">Hyundai A</a>|<a href="https://www.youtube.com/watch?v=ix63r9kE3Fw" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Hyundai|Sonata Hybrid 2020-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Sonata Hybrid 2020-22">Hyundai A</a>||
|
||||
|Hyundai|Tucson 2021|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|19 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Tucson 2021">Hyundai L</a>||
|
||||
|Hyundai|Tucson 2022[<sup>5</sup>](#footnotes)|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Tucson 2022">Hyundai N</a>||
|
||||
|Hyundai|Tucson 2023[<sup>5</sup>](#footnotes)|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Tucson 2023">Hyundai N</a>||
|
||||
|Hyundai|Tucson Diesel 2019|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Tucson Diesel 2019">Hyundai L</a>||
|
||||
|Hyundai|Tucson Hybrid 2022[<sup>5</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Tucson Hybrid 2022">Hyundai N</a>||
|
||||
|Hyundai|Veloster 2019-20|Smart Cruise Control (SCC)|Stock|5 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Veloster 2019-20">Hyundai E</a>||
|
||||
|Jeep|Grand Cherokee 2016-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Jeep&model=Grand Cherokee 2016-18">FCA</a>|<a href="https://www.youtube.com/watch?v=eLR9o2JkuRk" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Jeep|Grand Cherokee 2019-21|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Jeep&model=Grand Cherokee 2019-21">FCA</a>|<a href="https://www.youtube.com/watch?v=jBe4lWnRSu4" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Kia|Ceed 2019|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Ceed 2019">Hyundai E</a>||
|
||||
|Kia|EV6 (Southeast Asia only) 2022-23[<sup>5</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=EV6 (Southeast Asia only) 2022-23">Hyundai P</a>||
|
||||
|Kia|EV6 (with HDA II) 2022[<sup>5</sup>](#footnotes)|Highway Driving Assist II|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=EV6 (with HDA II) 2022">Hyundai P</a>||
|
||||
|Kia|EV6 (without HDA II) 2022[<sup>5</sup>](#footnotes)|Highway Driving Assist|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=EV6 (without HDA II) 2022">Hyundai L</a>||
|
||||
|Kia|Forte 2019-21|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Forte 2019-21">Hyundai G</a>||
|
||||
|Kia|K5 2021-22|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=K5 2021-22">Hyundai A</a>||
|
||||
|Kia|K5 Hybrid 2020|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=K5 Hybrid 2020">Hyundai A</a>||
|
||||
|Kia|Niro EV 2019|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Niro EV 2019">Hyundai H</a>|<a href="https://www.youtube.com/watch?v=lT7zcG6ZpGo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Kia|Niro EV 2020|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Niro EV 2020">Hyundai F</a>|<a href="https://www.youtube.com/watch?v=lT7zcG6ZpGo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Kia|Niro EV 2021|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Niro EV 2021">Hyundai C</a>|<a href="https://www.youtube.com/watch?v=lT7zcG6ZpGo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Kia|Niro EV 2022|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Niro EV 2022">Hyundai H</a>|<a href="https://www.youtube.com/watch?v=lT7zcG6ZpGo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Kia|Niro Hybrid 2021|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Niro Hybrid 2021">Hyundai F</a>||
|
||||
|Kia|Niro Hybrid 2022|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Niro Hybrid 2022">Hyundai H</a>||
|
||||
|Kia|Niro Hybrid 2023[<sup>5</sup>](#footnotes)|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Niro Hybrid 2023">Hyundai A</a>||
|
||||
|Kia|Niro Plug-in Hybrid 2018-19|All|openpilot available[<sup>1</sup>](#footnotes)|10 mph|32 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Niro Plug-in Hybrid 2018-19">Hyundai C</a>||
|
||||
|Kia|Niro Plug-in Hybrid 2020|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|32 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Niro Plug-in Hybrid 2020">Hyundai D</a>||
|
||||
|Kia|Optima 2017|Advanced Smart Cruise Control|Stock|0 mph|32 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Optima 2017">Hyundai B</a>||
|
||||
|Kia|Optima 2019-20|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Optima 2019-20">Hyundai G</a>||
|
||||
|Kia|Seltos 2021|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Seltos 2021">Hyundai A</a>||
|
||||
|Kia|Sorento 2018|Advanced Smart Cruise Control|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Sorento 2018">Hyundai C</a>|<a href="https://www.youtube.com/watch?v=Fkh3s6WHJz8" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Kia|Sorento 2019|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Sorento 2019">Hyundai E</a>|<a href="https://www.youtube.com/watch?v=Fkh3s6WHJz8" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Kia|Sorento 2022-23[<sup>5</sup>](#footnotes)|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Sorento 2022-23">Hyundai K</a>||
|
||||
|Kia|Sorento Plug-in Hybrid 2022-23[<sup>5</sup>](#footnotes)|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Sorento Plug-in Hybrid 2022-23">Hyundai A</a>||
|
||||
|Kia|Sportage 2023[<sup>5</sup>](#footnotes)|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Sportage 2023">Hyundai N</a>||
|
||||
|Kia|Sportage Hybrid 2023[<sup>5</sup>](#footnotes)|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Sportage Hybrid 2023">Hyundai N</a>||
|
||||
|Kia|Stinger 2018-20|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Stinger 2018-20">Hyundai C</a>|<a href="https://www.youtube.com/watch?v=MJ94qoofYw0" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Kia|Stinger 2022|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Stinger 2022">Hyundai K</a>||
|
||||
|Kia|Telluride 2020-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Telluride 2020-22">Hyundai H</a>||
|
||||
|Lexus|CT Hybrid 2017-18|Lexus Safety System+|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=CT Hybrid 2017-18">Toyota</a>||
|
||||
|Lexus|ES 2019-22|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=ES 2019-22">Toyota</a>||
|
||||
|Lexus|ES Hybrid 2017-18|Lexus Safety System+|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=ES Hybrid 2017-18">Toyota</a>||
|
||||
|Lexus|ES Hybrid 2019-23|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=ES Hybrid 2019-23">Toyota</a>|<a href="https://youtu.be/BZ29osRVJeg?t=12" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Lexus|IS 2017-19|All|Stock|19 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=IS 2017-19">Toyota</a>||
|
||||
|Lexus|NX 2018-19|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=NX 2018-19">Toyota</a>||
|
||||
|Lexus|NX 2020-21|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=NX 2020-21">Toyota</a>||
|
||||
|Lexus|NX Hybrid 2018-19|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=NX Hybrid 2018-19">Toyota</a>||
|
||||
|Lexus|NX Hybrid 2020-21|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=NX Hybrid 2020-21">Toyota</a>||
|
||||
|Lexus|RC 2017-20|All|Stock|19 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=RC 2017-20">Toyota</a>||
|
||||
|Lexus|RX 2016|Lexus Safety System+|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=RX 2016">Toyota</a>||
|
||||
|Lexus|RX 2017-19|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=RX 2017-19">Toyota</a>||
|
||||
|Lexus|RX 2020-22|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=RX 2020-22">Toyota</a>||
|
||||
|Lexus|RX Hybrid 2016|Lexus Safety System+|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=RX Hybrid 2016">Toyota</a>||
|
||||
|Lexus|RX Hybrid 2017-19|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=RX Hybrid 2017-19">Toyota</a>||
|
||||
|Lexus|RX Hybrid 2020-21|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=RX Hybrid 2020-21">Toyota</a>||
|
||||
|Lexus|UX Hybrid 2019-22|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=UX Hybrid 2019-22">Toyota</a>||
|
||||
|MAN|eTGE 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=MAN&model=eTGE 2020-23">J533</a>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|MAN|TGE 2017-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=MAN&model=TGE 2017-23">J533</a>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Mazda|CX-5 2022-23|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Mazda&model=CX-5 2022-23">Mazda</a>||
|
||||
|Mazda|CX-9 2021-23|All|Stock|0 mph|28 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Mazda&model=CX-9 2021-23">Mazda</a>|<a href="https://youtu.be/dA3duO4a0O4" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Nissan|Altima 2019-20|ProPILOT Assist|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Nissan&model=Altima 2019-20">Nissan B</a>||
|
||||
|Nissan|Leaf 2018-22|ProPILOT Assist|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Nissan&model=Leaf 2018-22">Nissan A</a>|<a href="https://youtu.be/vaMbtAh_0cY" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Nissan|Rogue 2018-20|ProPILOT Assist|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Nissan&model=Rogue 2018-20">Nissan A</a>||
|
||||
|Nissan|X-Trail 2017|ProPILOT Assist|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Nissan&model=X-Trail 2017">Nissan A</a>||
|
||||
|Ram|1500 2019-22|Adaptive Cruise Control (ACC)|Stock|0 mph|32 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Ram&model=1500 2019-22">Ram</a>||
|
||||
|SEAT|Ateca 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=SEAT&model=Ateca 2018">J533</a>||
|
||||
|SEAT|Leon 2014-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=SEAT&model=Leon 2014-20">J533</a>||
|
||||
|Subaru|Ascent 2019-21|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Subaru&model=Ascent 2019-21">Subaru A</a>||
|
||||
|Subaru|Crosstrek 2018-19|EyeSight Driver Assistance|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Subaru&model=Crosstrek 2018-19">Subaru A</a>|<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|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Subaru&model=Crosstrek 2020-23">Subaru A</a>||
|
||||
|Subaru|Forester 2019-21|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Subaru&model=Forester 2019-21">Subaru A</a>||
|
||||
|Subaru|Impreza 2017-19|EyeSight Driver Assistance|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Subaru&model=Impreza 2017-19">Subaru A</a>||
|
||||
|Subaru|Impreza 2020-22|EyeSight Driver Assistance|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Subaru&model=Impreza 2020-22">Subaru A</a>||
|
||||
|Subaru|Legacy 2020-22|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Subaru&model=Legacy 2020-22">Subaru B</a>||
|
||||
|Subaru|Outback 2020-22|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Subaru&model=Outback 2020-22">Subaru B</a>||
|
||||
|Subaru|XV 2018-19|EyeSight Driver Assistance|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Subaru&model=XV 2018-19">Subaru A</a>|<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|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Subaru&model=XV 2020-21">Subaru A</a>||
|
||||
|Škoda|Kamiq 2021[<sup>7</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Škoda&model=Kamiq 2021">J533</a>[<sup>10</sup>](#footnotes)||
|
||||
|Škoda|Karoq 2019-21|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Škoda&model=Karoq 2019-21">J533</a>||
|
||||
|Škoda|Kodiaq 2018-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Škoda&model=Kodiaq 2018-19">J533</a>||
|
||||
|Škoda|Octavia 2015, 2018-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Škoda&model=Octavia 2015, 2018-19">J533</a>||
|
||||
|Škoda|Octavia RS 2016|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Škoda&model=Octavia RS 2016">J533</a>||
|
||||
|Škoda|Scala 2020|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Škoda&model=Scala 2020">J533</a>[<sup>10</sup>](#footnotes)||
|
||||
|Škoda|Superb 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Škoda&model=Superb 2015-22">J533</a>||
|
||||
|Toyota|Alphard 2019-20|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Alphard 2019-20">Toyota</a>||
|
||||
|Toyota|Alphard Hybrid 2021|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Alphard Hybrid 2021">Toyota</a>||
|
||||
|Toyota|Avalon 2016|Toyota Safety Sense P|openpilot available[<sup>2</sup>](#footnotes)|19 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Avalon 2016">Toyota</a>||
|
||||
|Toyota|Avalon 2017-18|All|openpilot available[<sup>2</sup>](#footnotes)|19 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Avalon 2017-18">Toyota</a>||
|
||||
|Toyota|Avalon 2019-21|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Avalon 2019-21">Toyota</a>||
|
||||
|Toyota|Avalon 2022|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Avalon 2022">Toyota</a>||
|
||||
|Toyota|Avalon Hybrid 2019-21|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Avalon Hybrid 2019-21">Toyota</a>||
|
||||
|Toyota|Avalon Hybrid 2022|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Avalon Hybrid 2022">Toyota</a>||
|
||||
|Toyota|C-HR 2017-20|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=C-HR 2017-20">Toyota</a>||
|
||||
|Toyota|C-HR 2021|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=C-HR 2021">Toyota</a>||
|
||||
|Toyota|C-HR Hybrid 2017-19|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=C-HR Hybrid 2017-19">Toyota</a>||
|
||||
|Toyota|C-HR Hybrid 2022|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=C-HR Hybrid 2022">Toyota</a>||
|
||||
|Toyota|Camry 2018-20|All|Stock|0 mph[<sup>6</sup>](#footnotes)|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Camry 2018-20">Toyota</a>|<a href="https://www.youtube.com/watch?v=fkcjviZY9CM" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|Camry 2021-22|All|openpilot|0 mph[<sup>6</sup>](#footnotes)|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Camry 2021-22">Toyota</a>||
|
||||
|Toyota|Camry Hybrid 2018-20|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Camry Hybrid 2018-20">Toyota</a>|<a href="https://www.youtube.com/watch?v=Q2DYY0AWKgk" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|Camry Hybrid 2021-23|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Camry Hybrid 2021-23">Toyota</a>||
|
||||
|Toyota|Corolla 2017-19|All|openpilot available[<sup>2</sup>](#footnotes)|19 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Corolla 2017-19">Toyota</a>||
|
||||
|Toyota|Corolla 2020-22|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Corolla 2020-22">Toyota</a>|<a href="https://www.youtube.com/watch?v=_66pXk0CBYA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|Corolla Cross (Non-US only) 2020-23|All|openpilot|17 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Corolla Cross (Non-US only) 2020-23">Toyota</a>||
|
||||
|Toyota|Corolla Cross Hybrid (Non-US only) 2020-22|All|openpilot|17 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Corolla Cross Hybrid (Non-US only) 2020-22">Toyota</a>||
|
||||
|Toyota|Corolla Hatchback 2019-22|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Corolla Hatchback 2019-22">Toyota</a>|<a href="https://www.youtube.com/watch?v=_66pXk0CBYA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|Corolla Hybrid 2020-22|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Corolla Hybrid 2020-22">Toyota</a>||
|
||||
|Toyota|Corolla Hybrid (Non-US only) 2020-23|All|openpilot|17 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Corolla Hybrid (Non-US only) 2020-23">Toyota</a>||
|
||||
|Toyota|Highlander 2017-19|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Highlander 2017-19">Toyota</a>|<a href="https://www.youtube.com/watch?v=0wS0wXSLzoo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|Highlander 2020-23|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Highlander 2020-23">Toyota</a>||
|
||||
|Toyota|Highlander Hybrid 2017-19|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Highlander Hybrid 2017-19">Toyota</a>||
|
||||
|Toyota|Highlander Hybrid 2020-23|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Highlander Hybrid 2020-23">Toyota</a>||
|
||||
|Toyota|Mirai 2021|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Mirai 2021">Toyota</a>||
|
||||
|Toyota|Prius 2016|Toyota Safety Sense P|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Prius 2016">Toyota</a>|<a href="https://www.youtube.com/watch?v=8zopPJI8XQ0" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|Prius 2017-20|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Prius 2017-20">Toyota</a>|<a href="https://www.youtube.com/watch?v=8zopPJI8XQ0" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|Prius 2021-22|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Prius 2021-22">Toyota</a>|<a href="https://www.youtube.com/watch?v=J58TvCpUd4U" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|Prius Prime 2017-20|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Prius Prime 2017-20">Toyota</a>|<a href="https://www.youtube.com/watch?v=8zopPJI8XQ0" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|Prius Prime 2021-22|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Prius Prime 2021-22">Toyota</a>|<a href="https://www.youtube.com/watch?v=J58TvCpUd4U" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|Prius v 2017|Toyota Safety Sense P|openpilot available[<sup>2</sup>](#footnotes)|19 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Prius v 2017">Toyota</a>||
|
||||
|Toyota|RAV4 2016|Toyota Safety Sense P|openpilot available[<sup>2</sup>](#footnotes)|19 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=RAV4 2016">Toyota</a>||
|
||||
|Toyota|RAV4 2017-18|All|openpilot available[<sup>2</sup>](#footnotes)|19 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=RAV4 2017-18">Toyota</a>||
|
||||
|Toyota|RAV4 2019-21|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=RAV4 2019-21">Toyota</a>|<a href="https://www.youtube.com/watch?v=wJxjDd42gGA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|RAV4 2022|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=RAV4 2022">Toyota</a>||
|
||||
|Toyota|RAV4 Hybrid 2016|Toyota Safety Sense P|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=RAV4 Hybrid 2016">Toyota</a>|<a href="https://youtu.be/LhT5VzJVfNI?t=26" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|RAV4 Hybrid 2017-18|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=RAV4 Hybrid 2017-18">Toyota</a>|<a href="https://youtu.be/LhT5VzJVfNI?t=26" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|RAV4 Hybrid 2019-21|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=RAV4 Hybrid 2019-21">Toyota</a>||
|
||||
|Toyota|RAV4 Hybrid 2022|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=RAV4 Hybrid 2022">Toyota</a>|<a href="https://youtu.be/U0nH9cnrFB0" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|Sienna 2018-20|All|openpilot available[<sup>2</sup>](#footnotes)|19 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Sienna 2018-20">Toyota</a>|<a href="https://www.youtube.com/watch?v=q1UPOo4Sh68" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Volkswagen|Arteon 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Arteon 2018-22">J533</a>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Volkswagen|Arteon eHybrid 2020-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Arteon eHybrid 2020-22">J533</a>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Volkswagen|Arteon R 2020-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Arteon R 2020-22">J533</a>|<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,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Atlas 2018-23">J533</a>||
|
||||
|Volkswagen|Atlas Cross Sport 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Atlas Cross Sport 2021-22">J533</a>||
|
||||
|Volkswagen|California 2021|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=California 2021">J533</a>||
|
||||
|Volkswagen|Caravelle 2020|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Caravelle 2020">J533</a>||
|
||||
|Volkswagen|CC 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=CC 2018-22">J533</a>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Volkswagen|Crafter 2017-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Crafter 2017-23">J533</a>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Volkswagen|e-Crafter 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=e-Crafter 2018-23">J533</a>|<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,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=e-Golf 2014-20">J533</a>||
|
||||
|Volkswagen|Golf 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Golf 2015-20">J533</a>||
|
||||
|Volkswagen|Golf Alltrack 2015-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Golf Alltrack 2015-19">J533</a>||
|
||||
|Volkswagen|Golf GTD 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Golf GTD 2015-20">J533</a>||
|
||||
|Volkswagen|Golf GTE 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Golf GTE 2015-20">J533</a>||
|
||||
|Volkswagen|Golf GTI 2015-21|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Golf GTI 2015-21">J533</a>||
|
||||
|Volkswagen|Golf R 2015-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Golf R 2015-19">J533</a>||
|
||||
|Volkswagen|Golf SportsVan 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Golf SportsVan 2015-20">J533</a>||
|
||||
|Volkswagen|Grand California 2019-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Grand California 2019-23">J533</a>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Volkswagen|Jetta 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Jetta 2018-22">J533</a>||
|
||||
|Volkswagen|Jetta GLI 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Jetta GLI 2021-22">J533</a>||
|
||||
|Volkswagen|Passat 2015-22[<sup>8</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Passat 2015-22">J533</a>||
|
||||
|Volkswagen|Passat Alltrack 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Passat Alltrack 2015-22">J533</a>||
|
||||
|Volkswagen|Passat GTE 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Passat GTE 2015-22">J533</a>||
|
||||
|Volkswagen|Polo 2020-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Polo 2020-22">J533</a>[<sup>10</sup>](#footnotes)||
|
||||
|Volkswagen|Polo GTI 2020-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Polo GTI 2020-22">J533</a>[<sup>10</sup>](#footnotes)||
|
||||
|Volkswagen|T-Cross 2021|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=T-Cross 2021">J533</a>[<sup>10</sup>](#footnotes)||
|
||||
|Volkswagen|T-Roc 2021|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=T-Roc 2021">J533</a>[<sup>10</sup>](#footnotes)||
|
||||
|Volkswagen|Taos 2022|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Taos 2022">J533</a>||
|
||||
|Volkswagen|Teramont 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Teramont 2018-22">J533</a>||
|
||||
|Volkswagen|Teramont Cross Sport 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Teramont Cross Sport 2021-22">J533</a>||
|
||||
|Volkswagen|Teramont X 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Teramont X 2021-22">J533</a>||
|
||||
|Volkswagen|Tiguan 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Tiguan 2018-23">J533</a>||
|
||||
|Volkswagen|Touran 2017|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Touran 2017">J533</a>||
|
||||
|Ford|Bronco Sport 2021-22|Co-Pilot360 Assist+|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Ford&model=Bronco Sport 2021-22">Ford Q3 connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Ford|Escape 2020-22|Co-Pilot360 Assist+|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Ford&model=Escape 2020-22">Ford Q3 connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Ford|Explorer 2020-22|Co-Pilot360 Assist+|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Ford&model=Explorer 2020-22">Ford Q3 connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Ford|Kuga 2020-22|Adaptive Cruise Control with Lane Centering|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Ford&model=Kuga 2020-22">Ford Q3 connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Ford|Maverick 2022-23|Co-Pilot360 Assist|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Ford&model=Maverick 2022-23">Ford Q3 connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Genesis|G70 2018-19|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Genesis&model=G70 2018-19">Hyundai F connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Genesis|G70 2020|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Genesis&model=G70 2020">Hyundai F connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Genesis|G80 2017|All|Stock|19 mph|37 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Genesis&model=G80 2017">Hyundai J connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Genesis|G80 2018-19|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Genesis&model=G80 2018-19">Hyundai H connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Genesis|G90 2017-18|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Genesis&model=G90 2017-18">Hyundai C connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Genesis|GV60 (Advanced Trim) 2023[<sup>5</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Genesis&model=GV60 (Advanced Trim) 2023">Hyundai A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Genesis|GV60 (Performance Trim) 2023[<sup>5</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Genesis&model=GV60 (Performance Trim) 2023">Hyundai K connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Genesis|GV70 (2.5T Trim) 2022-23[<sup>5</sup>](#footnotes)|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Genesis&model=GV70 (2.5T Trim) 2022-23">Hyundai L connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Genesis|GV70 (3.5T Trim) 2022-23[<sup>5</sup>](#footnotes)|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Genesis&model=GV70 (3.5T Trim) 2022-23">Hyundai M connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Genesis|GV80 2023[<sup>5</sup>](#footnotes)|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Genesis&model=GV80 2023">Hyundai M connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|GMC|Acadia 2018[<sup>3</sup>](#footnotes)|Adaptive Cruise Control (ACC)|openpilot|0 mph|7 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=GMC&model=Acadia 2018">OBD-II connector</a><br>- 1 USB-C coupler<br>- 1 long OBD-C cable</sub></details>|<a href="https://www.youtube.com/watch?v=0ZN6DdsBUZo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|GMC|Sierra 1500 2020-21|Driver Alert Package II|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=GMC&model=Sierra 1500 2020-21">GM connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://youtu.be/5HbNoBLzRwE" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Honda|Accord 2018-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Accord 2018-22">Honda Bosch A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://www.youtube.com/watch?v=mrUwlj3Mi58" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Honda|Accord Hybrid 2018-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Accord Hybrid 2018-22">Honda Bosch A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Honda|Civic 2016-18|Honda Sensing|openpilot|0 mph|12 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Civic 2016-18">Honda Nidec connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://youtu.be/-IkImTe1NYE" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Honda|Civic 2019-21|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|2 mph[<sup>4</sup>](#footnotes)|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Civic 2019-21">Honda Bosch A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://www.youtube.com/watch?v=4Iz1Mz5LGF8" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Honda|Civic 2022|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Civic 2022">Honda Bosch B connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://youtu.be/ytiOT5lcp6Q" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Honda|Civic Hatchback 2017-21|Honda Sensing|openpilot available[<sup>1</sup>](#footnotes)|0 mph|12 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Civic Hatchback 2017-21">Honda Bosch A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Honda|Civic Hatchback 2022|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Civic Hatchback 2022">Honda Bosch B connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://youtu.be/ytiOT5lcp6Q" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Honda|CR-V 2015-16|Touring Trim|openpilot|25 mph|12 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Honda&model=CR-V 2015-16">Honda Nidec connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Honda|CR-V 2017-22|Honda Sensing|openpilot available[<sup>1</sup>](#footnotes)|0 mph|12 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Honda&model=CR-V 2017-22">Honda Bosch A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Honda|CR-V Hybrid 2017-19|Honda Sensing|openpilot available[<sup>1</sup>](#footnotes)|0 mph|12 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Honda&model=CR-V Hybrid 2017-19">Honda Bosch A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Honda|e 2020|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Honda&model=e 2020">Honda Bosch A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Honda|Fit 2018-20|Honda Sensing|openpilot|25 mph|12 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Fit 2018-20">Honda Nidec connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Honda|Freed 2020|Honda Sensing|openpilot|25 mph|12 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Freed 2020">Honda Nidec connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Honda|HR-V 2019-22|Honda Sensing|openpilot|25 mph|12 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Honda&model=HR-V 2019-22">Honda Nidec connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Honda|HR-V 2023|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Honda&model=HR-V 2023">Honda Bosch B connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Honda|Insight 2019-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Insight 2019-22">Honda Bosch A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Honda|Inspire 2018|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Inspire 2018">Honda Bosch A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Honda|Odyssey 2018-20|Honda Sensing|openpilot|25 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Odyssey 2018-20">Honda Nidec connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Honda|Passport 2019-22|All|openpilot|25 mph|12 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Passport 2019-22">Honda Nidec connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Honda|Pilot 2016-22|Honda Sensing|openpilot|25 mph|12 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Pilot 2016-22">Honda Nidec connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Honda|Ridgeline 2017-23|Honda Sensing|openpilot|25 mph|12 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Honda&model=Ridgeline 2017-23">Honda Nidec connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|Elantra 2017-19|Smart Cruise Control (SCC)|Stock|19 mph|32 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Elantra 2017-19">Hyundai B connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|Elantra 2021-23|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Elantra 2021-23">Hyundai K connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</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-19|Smart Cruise Control (SCC)|Stock|0 mph|32 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Elantra GT 2017-19">Hyundai E connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|Elantra Hybrid 2021-23|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Elantra Hybrid 2021-23">Hyundai K connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://youtu.be/_EdYQtV52-c" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Hyundai|Genesis 2015-16|Smart Cruise Control (SCC)|Stock|19 mph|37 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Genesis 2015-16">Hyundai J connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|i30 2017-19|Smart Cruise Control (SCC)|Stock|0 mph|32 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=i30 2017-19">Hyundai E connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|Ioniq 5 (Southeast Asia only) 2022-23[<sup>5</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Ioniq 5 (Southeast Asia only) 2022-23">Hyundai Q connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|Ioniq 5 (with HDA II) 2022-23[<sup>5</sup>](#footnotes)|Highway Driving Assist II|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Ioniq 5 (with HDA II) 2022-23">Hyundai Q connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|Ioniq 5 (without HDA II) 2022-23[<sup>5</sup>](#footnotes)|Highway Driving Assist|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Ioniq 5 (without HDA II) 2022-23">Hyundai K connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|Ioniq Electric 2019|Smart Cruise Control (SCC)|Stock|0 mph|32 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Ioniq Electric 2019">Hyundai C connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|Ioniq Electric 2020|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Ioniq Electric 2020">Hyundai H connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|Ioniq Hybrid 2017-19|Smart Cruise Control (SCC)|Stock|0 mph|32 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Ioniq Hybrid 2017-19">Hyundai C connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|Ioniq Hybrid 2020-22|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Ioniq Hybrid 2020-22">Hyundai H connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|Ioniq Plug-in Hybrid 2019|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|32 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Ioniq Plug-in Hybrid 2019">Hyundai C connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|Ioniq Plug-in Hybrid 2020-22|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Ioniq Plug-in Hybrid 2020-22">Hyundai H connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|Kona 2020|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Kona 2020">Hyundai B connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|Kona Electric 2018-21|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Kona Electric 2018-21">Hyundai G connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|Kona Electric 2022|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Kona Electric 2022">Hyundai O connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|Kona Hybrid 2020|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Kona Hybrid 2020">Hyundai I connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://youtu.be/0dwpAHiZgFo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Hyundai|Palisade 2020-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Palisade 2020-22">Hyundai H connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</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-23[<sup>5</sup>](#footnotes)|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Santa Cruz 2022-23">Hyundai N connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|Santa Fe 2019-20|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Santa Fe 2019-20">Hyundai D connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|Santa Fe 2021-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Santa Fe 2021-22">Hyundai L connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://youtu.be/VnHzSTygTS4" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Hyundai|Santa Fe Hybrid 2022|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Santa Fe Hybrid 2022">Hyundai L connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|Santa Fe Plug-in Hybrid 2022|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Santa Fe Plug-in Hybrid 2022">Hyundai L connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|Sonata 2018-19|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Sonata 2018-19">Hyundai E connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|Sonata 2020-23|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Sonata 2020-23">Hyundai A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://www.youtube.com/watch?v=ix63r9kE3Fw" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Hyundai|Sonata Hybrid 2020-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Sonata Hybrid 2020-22">Hyundai A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|Tucson 2021|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|19 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Tucson 2021">Hyundai L connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|Tucson 2022[<sup>5</sup>](#footnotes)|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Tucson 2022">Hyundai N connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|Tucson 2023[<sup>5</sup>](#footnotes)|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Tucson 2023">Hyundai N connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|Tucson Diesel 2019|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Tucson Diesel 2019">Hyundai L connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|Tucson Hybrid 2022-23[<sup>5</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Tucson Hybrid 2022-23">Hyundai N connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Hyundai|Veloster 2019-20|Smart Cruise Control (SCC)|Stock|5 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Hyundai&model=Veloster 2019-20">Hyundai E connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Jeep|Grand Cherokee 2016-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Jeep&model=Grand Cherokee 2016-18">FCA connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://www.youtube.com/watch?v=eLR9o2JkuRk" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Jeep|Grand Cherokee 2019-21|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Jeep&model=Grand Cherokee 2019-21">FCA connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://www.youtube.com/watch?v=jBe4lWnRSu4" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Kia|Ceed 2019|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Ceed 2019">Hyundai E connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Kia|EV6 (Southeast Asia only) 2022-23[<sup>5</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=EV6 (Southeast Asia only) 2022-23">Hyundai P connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Kia|EV6 (with HDA II) 2022-23[<sup>5</sup>](#footnotes)|Highway Driving Assist II|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=EV6 (with HDA II) 2022-23">Hyundai P connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Kia|EV6 (without HDA II) 2022-23[<sup>5</sup>](#footnotes)|Highway Driving Assist|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=EV6 (without HDA II) 2022-23">Hyundai L connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Kia|Forte 2019-21|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Forte 2019-21">Hyundai G connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Kia|Forte 2023|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Forte 2023">Hyundai E connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Kia|K5 2021-22|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=K5 2021-22">Hyundai A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Kia|K5 Hybrid 2020|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=K5 Hybrid 2020">Hyundai A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Kia|Niro EV 2019|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Niro EV 2019">Hyundai H connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://www.youtube.com/watch?v=lT7zcG6ZpGo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Kia|Niro EV 2020|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Niro EV 2020">Hyundai F connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://www.youtube.com/watch?v=lT7zcG6ZpGo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Kia|Niro EV 2021|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Niro EV 2021">Hyundai C connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://www.youtube.com/watch?v=lT7zcG6ZpGo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Kia|Niro EV 2022|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Niro EV 2022">Hyundai H connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://www.youtube.com/watch?v=lT7zcG6ZpGo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Kia|Niro EV 2023[<sup>5</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Niro EV 2023">Hyundai A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Kia|Niro Hybrid 2021-22|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Niro Hybrid 2021-22">Hyundai F connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Kia|Niro Hybrid 2023[<sup>5</sup>](#footnotes)|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Niro Hybrid 2023">Hyundai A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Kia|Niro Plug-in Hybrid 2018-19|All|openpilot available[<sup>1</sup>](#footnotes)|10 mph|32 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Niro Plug-in Hybrid 2018-19">Hyundai C connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Kia|Niro Plug-in Hybrid 2020|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|32 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Niro Plug-in Hybrid 2020">Hyundai D connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Kia|Optima 2017|Advanced Smart Cruise Control|Stock|0 mph|32 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Optima 2017">Hyundai B connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Kia|Optima 2019-20|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Optima 2019-20">Hyundai G connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Kia|Seltos 2021|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Seltos 2021">Hyundai A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Kia|Sorento 2018|Advanced Smart Cruise Control|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Sorento 2018">Hyundai C connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://www.youtube.com/watch?v=Fkh3s6WHJz8" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Kia|Sorento 2019|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Sorento 2019">Hyundai E connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://www.youtube.com/watch?v=Fkh3s6WHJz8" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Kia|Sorento 2021-23[<sup>5</sup>](#footnotes)|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Sorento 2021-23">Hyundai K connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Kia|Sorento Plug-in Hybrid 2022-23[<sup>5</sup>](#footnotes)|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Sorento Plug-in Hybrid 2022-23">Hyundai A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Kia|Sportage 2023[<sup>5</sup>](#footnotes)|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Sportage 2023">Hyundai N connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Kia|Sportage Hybrid 2023[<sup>5</sup>](#footnotes)|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Sportage Hybrid 2023">Hyundai N connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Kia|Stinger 2018-20|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Stinger 2018-20">Hyundai C connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://www.youtube.com/watch?v=MJ94qoofYw0" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Kia|Stinger 2022|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Stinger 2022">Hyundai K connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Kia|Telluride 2020-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Telluride 2020-22">Hyundai H connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Lexus|CT Hybrid 2017-18|Lexus Safety System+|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=CT Hybrid 2017-18">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Lexus|ES 2017-18|All|openpilot available[<sup>2</sup>](#footnotes)|19 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=ES 2017-18">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Lexus|ES 2019-22|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=ES 2019-22">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Lexus|ES Hybrid 2017-18|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=ES Hybrid 2017-18">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Lexus|ES Hybrid 2019-23|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=ES Hybrid 2019-23">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://youtu.be/BZ29osRVJeg?t=12" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Lexus|IS 2017-19|All|Stock|19 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=IS 2017-19">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Lexus|NX 2018-19|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=NX 2018-19">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Lexus|NX 2020-21|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=NX 2020-21">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Lexus|NX Hybrid 2018-19|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=NX Hybrid 2018-19">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Lexus|NX Hybrid 2020-21|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=NX Hybrid 2020-21">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Lexus|RC 2018-20|All|Stock|19 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=RC 2018-20">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Lexus|RX 2016|Lexus Safety System+|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=RX 2016">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Lexus|RX 2017-19|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=RX 2017-19">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Lexus|RX 2020-22|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=RX 2020-22">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Lexus|RX Hybrid 2016|Lexus Safety System+|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=RX Hybrid 2016">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Lexus|RX Hybrid 2017-19|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=RX Hybrid 2017-19">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Lexus|RX Hybrid 2020-21|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=RX Hybrid 2020-21">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Lexus|UX Hybrid 2019-22|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=UX Hybrid 2019-22">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Lincoln|Aviator 2021|Co-Pilot360 Plus|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Lincoln&model=Aviator 2021">Ford Q3 connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|MAN|eTGE 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=MAN&model=eTGE 2020-23">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|MAN|TGE 2017-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=MAN&model=TGE 2017-23">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Mazda|CX-5 2022-23|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Mazda&model=CX-5 2022-23">Mazda connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Mazda|CX-9 2021-23|All|Stock|0 mph|28 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Mazda&model=CX-9 2021-23">Mazda connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://youtu.be/dA3duO4a0O4" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Nissan|Altima 2019-20|ProPILOT Assist|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Nissan&model=Altima 2019-20">Nissan B connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Nissan|Leaf 2018-23|ProPILOT Assist|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Nissan&model=Leaf 2018-23">Nissan A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>|<a href="https://youtu.be/vaMbtAh_0cY" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Nissan|Rogue 2018-20|ProPILOT Assist|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Nissan&model=Rogue 2018-20">Nissan A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Nissan|X-Trail 2017|ProPILOT Assist|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Nissan&model=X-Trail 2017">Nissan A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Ram|1500 2019-23|Adaptive Cruise Control (ACC)|Stock|0 mph|32 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Ram&model=1500 2019-23">Ram connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|SEAT|Ateca 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=SEAT&model=Ateca 2018">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|SEAT|Leon 2014-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=SEAT&model=Leon 2014-20">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Subaru|Ascent 2019-21|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Subaru&model=Ascent 2019-21">Subaru A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Subaru|Crosstrek 2018-19|EyeSight Driver Assistance|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Subaru&model=Crosstrek 2018-19">Subaru A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</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|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Subaru&model=Crosstrek 2020-23">Subaru A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Subaru|Forester 2019-21|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Subaru&model=Forester 2019-21">Subaru A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Subaru|Impreza 2017-19|EyeSight Driver Assistance|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Subaru&model=Impreza 2017-19">Subaru A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Subaru|Impreza 2020-22|EyeSight Driver Assistance|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Subaru&model=Impreza 2020-22">Subaru A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Subaru|Legacy 2020-22|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Subaru&model=Legacy 2020-22">Subaru B connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Subaru|Outback 2020-22|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Subaru&model=Outback 2020-22">Subaru B connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Subaru|XV 2018-19|EyeSight Driver Assistance|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Subaru&model=XV 2018-19">Subaru A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</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|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Subaru&model=XV 2020-21">Subaru A connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Škoda|Fabia 2022-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Škoda&model=Fabia 2022-23">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>[<sup>10</sup>](#footnotes)||
|
||||
|Škoda|Kamiq 2021[<sup>7</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Škoda&model=Kamiq 2021">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>[<sup>10</sup>](#footnotes)||
|
||||
|Škoda|Karoq 2019-21|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Škoda&model=Karoq 2019-21">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Škoda|Kodiaq 2017-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Škoda&model=Kodiaq 2017-23">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Škoda|Octavia 2015, 2018-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Škoda&model=Octavia 2015, 2018-19">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Škoda|Octavia RS 2016|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Škoda&model=Octavia RS 2016">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Škoda|Scala 2020|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Škoda&model=Scala 2020">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>[<sup>10</sup>](#footnotes)||
|
||||
|Škoda|Superb 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Škoda&model=Superb 2015-22">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Toyota|Alphard 2019-20|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Alphard 2019-20">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|Alphard Hybrid 2021|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Alphard Hybrid 2021">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|Avalon 2016|Toyota Safety Sense P|openpilot available[<sup>2</sup>](#footnotes)|19 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Avalon 2016">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|Avalon 2017-18|All|openpilot available[<sup>2</sup>](#footnotes)|19 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Avalon 2017-18">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|Avalon 2019-21|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Avalon 2019-21">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|Avalon 2022|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Avalon 2022">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|Avalon Hybrid 2019-21|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Avalon Hybrid 2019-21">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|Avalon Hybrid 2022|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Avalon Hybrid 2022">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|C-HR 2017-20|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=C-HR 2017-20">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|C-HR 2021|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=C-HR 2021">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|C-HR Hybrid 2017-20|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=C-HR Hybrid 2017-20">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|C-HR Hybrid 2021-22|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=C-HR Hybrid 2021-22">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|Camry 2018-20|All|Stock|0 mph[<sup>6</sup>](#footnotes)|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Camry 2018-20">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://www.youtube.com/watch?v=fkcjviZY9CM" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|Camry 2021-23|All|openpilot|0 mph[<sup>6</sup>](#footnotes)|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Camry 2021-23">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|Camry Hybrid 2018-20|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Camry Hybrid 2018-20">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://www.youtube.com/watch?v=Q2DYY0AWKgk" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|Camry Hybrid 2021-23|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Camry Hybrid 2021-23">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|Corolla 2017-19|All|openpilot available[<sup>2</sup>](#footnotes)|19 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Corolla 2017-19">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|Corolla 2020-22|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Corolla 2020-22">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://www.youtube.com/watch?v=_66pXk0CBYA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|Corolla Cross (Non-US only) 2020-23|All|openpilot|17 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Corolla Cross (Non-US only) 2020-23">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|Corolla Cross Hybrid (Non-US only) 2020-22|All|openpilot|17 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Corolla Cross Hybrid (Non-US only) 2020-22">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|Corolla Hatchback 2019-22|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Corolla Hatchback 2019-22">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://www.youtube.com/watch?v=_66pXk0CBYA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|Corolla Hybrid 2020-22|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Corolla Hybrid 2020-22">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|Corolla Hybrid (Non-US only) 2020-23|All|openpilot|17 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Corolla Hybrid (Non-US only) 2020-23">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|Highlander 2017-19|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Highlander 2017-19">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://www.youtube.com/watch?v=0wS0wXSLzoo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|Highlander 2020-23|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Highlander 2020-23">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|Highlander Hybrid 2017-19|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Highlander Hybrid 2017-19">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|Highlander Hybrid 2020-23|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Highlander Hybrid 2020-23">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|Mirai 2021|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Mirai 2021">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|Prius 2016|Toyota Safety Sense P|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Prius 2016">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://www.youtube.com/watch?v=8zopPJI8XQ0" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|Prius 2017-20|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Prius 2017-20">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://www.youtube.com/watch?v=8zopPJI8XQ0" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|Prius 2021-22|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Prius 2021-22">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://www.youtube.com/watch?v=J58TvCpUd4U" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|Prius Prime 2017-20|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Prius Prime 2017-20">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://www.youtube.com/watch?v=8zopPJI8XQ0" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|Prius Prime 2021-22|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Prius Prime 2021-22">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://www.youtube.com/watch?v=J58TvCpUd4U" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|Prius v 2017|Toyota Safety Sense P|openpilot available[<sup>2</sup>](#footnotes)|19 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Prius v 2017">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|RAV4 2016|Toyota Safety Sense P|openpilot available[<sup>2</sup>](#footnotes)|19 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=RAV4 2016">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|RAV4 2017-18|All|openpilot available[<sup>2</sup>](#footnotes)|19 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=RAV4 2017-18">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|RAV4 2019-21|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=RAV4 2019-21">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://www.youtube.com/watch?v=wJxjDd42gGA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|RAV4 2022|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=RAV4 2022">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|RAV4 Hybrid 2016|Toyota Safety Sense P|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=RAV4 Hybrid 2016">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://youtu.be/LhT5VzJVfNI?t=26" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|RAV4 Hybrid 2017-18|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=RAV4 Hybrid 2017-18">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://youtu.be/LhT5VzJVfNI?t=26" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|RAV4 Hybrid 2019-21|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=RAV4 Hybrid 2019-21">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>||
|
||||
|Toyota|RAV4 Hybrid 2022|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=RAV4 Hybrid 2022">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</sub></details>|<a href="https://youtu.be/U0nH9cnrFB0" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|Sienna 2018-20|All|openpilot available[<sup>2</sup>](#footnotes)|19 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Sienna 2018-20">Toyota connector</a><br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 harness box</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-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Arteon 2018-22">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Volkswagen|Arteon eHybrid 2020-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Arteon eHybrid 2020-22">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Volkswagen|Arteon R 2020-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Arteon R 2020-22">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</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,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Atlas 2018-23">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Volkswagen|Atlas Cross Sport 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Atlas Cross Sport 2021-22">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Volkswagen|California 2021|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=California 2021">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Volkswagen|Caravelle 2020|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Caravelle 2020">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Volkswagen|CC 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=CC 2018-22">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Volkswagen|Crafter 2017-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Crafter 2017-23">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Volkswagen|e-Crafter 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=e-Crafter 2018-23">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</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,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=e-Golf 2014-20">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Volkswagen|Golf 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Golf 2015-20">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Volkswagen|Golf Alltrack 2015-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Golf Alltrack 2015-19">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Volkswagen|Golf GTD 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Golf GTD 2015-20">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Volkswagen|Golf GTE 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Golf GTE 2015-20">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Volkswagen|Golf GTI 2015-21|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Golf GTI 2015-21">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Volkswagen|Golf R 2015-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Golf R 2015-19">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Volkswagen|Golf SportsVan 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Golf SportsVan 2015-20">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Volkswagen|Grand California 2019-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Grand California 2019-23">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Volkswagen|Jetta 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Jetta 2018-22">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Volkswagen|Jetta GLI 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Jetta GLI 2021-22">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Volkswagen|Passat 2015-22[<sup>8</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Passat 2015-22">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Volkswagen|Passat Alltrack 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Passat Alltrack 2015-22">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Volkswagen|Passat GTE 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Passat GTE 2015-22">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Volkswagen|Polo 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Polo 2018-23">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>[<sup>10</sup>](#footnotes)||
|
||||
|Volkswagen|Polo GTI 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Polo GTI 2018-23">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>[<sup>10</sup>](#footnotes)||
|
||||
|Volkswagen|T-Cross 2021|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=T-Cross 2021">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>[<sup>10</sup>](#footnotes)||
|
||||
|Volkswagen|T-Roc 2021|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=T-Roc 2021">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>[<sup>10</sup>](#footnotes)||
|
||||
|Volkswagen|Taos 2022|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Taos 2022">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Volkswagen|Teramont 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Teramont 2018-22">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Volkswagen|Teramont Cross Sport 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Teramont Cross Sport 2021-22">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Volkswagen|Teramont X 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Teramont X 2021-22">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Volkswagen|Tiguan 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Tiguan 2018-23">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Volkswagen|Tiguan eHybrid 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Tiguan eHybrid 2021-23">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|Volkswagen|Touran 2017|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>View</summary><sub>- 1 <a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Touran 2017">J533 connector</a><br>- 1 USB-C coupler<br>- 1 harness box<br>- 1 long OBD-C cable</sub></details>||
|
||||
|
||||
<a id="footnotes"></a>
|
||||
<sup>1</sup>Experimental openpilot longitudinal control is available behind a toggle; the toggle is only available in non-release branches such as `devel` or `master-ci`. <br />
|
||||
@@ -275,6 +290,7 @@ If your car has the following packages or features, then it's a good candidate f
|
||||
| Make | Required Package/Features |
|
||||
| ---- | ------------------------- |
|
||||
| Acura | Any car with AcuraWatch Plus will work. AcuraWatch Plus comes standard on many newer models. |
|
||||
| Ford | Any car with Lane Centering will likely work. |
|
||||
| Honda | Any car with Honda Sensing will work. Honda Sensing comes standard on many newer models. |
|
||||
| Subaru | Any car with EyeSight will work. EyeSight comes standard on many newer models. |
|
||||
| Nissan | Any car with ProPILOT will likely work. |
|
||||
|
||||
@@ -1,2 +1,9 @@
|
||||
import logging
|
||||
import os
|
||||
|
||||
from .astro_dog import AstroDog
|
||||
assert AstroDog
|
||||
|
||||
# setup logging
|
||||
LOGLEVEL = os.environ.get('LOGLEVEL', 'INFO').upper()
|
||||
logging.basicConfig(level=LOGLEVEL, format='%(message)s')
|
||||
|
||||
+46
-16
@@ -9,7 +9,7 @@ from .ephemeris import Ephemeris, EphemerisType, GLONASSEphemeris, GPSEphemeris,
|
||||
from .downloader import download_orbits_gps, download_orbits_russia_src, download_nav, download_ionex, download_dcb, download_prediction_orbits_russia_src
|
||||
from .downloader import download_cors_station
|
||||
from .trop import saast
|
||||
from .iono import IonexMap, parse_ionex
|
||||
from .iono import IonexMap, parse_ionex, get_slant_delay
|
||||
from .dcb import DCB, parse_dcbs
|
||||
from .gps_time import GPSTime
|
||||
from .dgps import get_closest_station_names, parse_dgps
|
||||
@@ -33,9 +33,14 @@ class AstroDog:
|
||||
def __init__(self, auto_update=True,
|
||||
cache_dir='/tmp/gnss/',
|
||||
dgps=False,
|
||||
valid_const=('GPS', 'GLONASS'),
|
||||
valid_const=(ConstellationId.GPS, ConstellationId.GLONASS),
|
||||
valid_ephem_types=EphemerisType.all_orbits(),
|
||||
clear_old_ephemeris=False):
|
||||
|
||||
for const in valid_const:
|
||||
if not isinstance(const, ConstellationId):
|
||||
raise TypeError(f"valid_const must be a list of ConstellationId, got {const}")
|
||||
|
||||
self.auto_update = auto_update
|
||||
self.cache_dir = cache_dir
|
||||
self.clear_old_ephemeris = clear_old_ephemeris
|
||||
@@ -44,6 +49,7 @@ class AstroDog:
|
||||
valid_ephem_types = [valid_ephem_types]
|
||||
self.pull_orbit = len(set(EphemerisType.all_orbits()) & set(valid_ephem_types)) > 0
|
||||
self.pull_nav = EphemerisType.NAV in valid_ephem_types
|
||||
self.use_qcom_poly = EphemerisType.QCOM_POLY in valid_ephem_types
|
||||
self.valid_const = valid_const
|
||||
self.valid_ephem_types = valid_ephem_types
|
||||
|
||||
@@ -54,12 +60,14 @@ class AstroDog:
|
||||
self.dgps_delays = []
|
||||
self.ionex_maps: List[IonexMap] = []
|
||||
self.orbits: DefaultDict[str, List[PolyEphemeris]] = defaultdict(list)
|
||||
self.qcom_polys: DefaultDict[str, List[PolyEphemeris]] = defaultdict(list)
|
||||
self.navs: DefaultDict[str, List[Union[GPSEphemeris, GLONASSEphemeris]]] = defaultdict(list)
|
||||
self.dcbs: DefaultDict[str, List[DCB]] = defaultdict(list)
|
||||
|
||||
self.cached_ionex: Optional[IonexMap] = None
|
||||
self.cached_dgps = None
|
||||
self.cached_orbit: DefaultDict[str, Optional[PolyEphemeris]] = defaultdict(lambda: None)
|
||||
self.cached_qcom_polys: DefaultDict[str, Optional[PolyEphemeris]] = defaultdict(lambda: None)
|
||||
self.cached_nav: DefaultDict[str, Union[GPSEphemeris, GLONASSEphemeris, None]] = defaultdict(lambda: None)
|
||||
self.cached_dcb: DefaultDict[str, Optional[DCB]] = defaultdict(lambda: None)
|
||||
|
||||
@@ -96,6 +104,9 @@ class AstroDog:
|
||||
result[prn] = obj
|
||||
return result
|
||||
|
||||
def get_all_ephem_prns(self):
|
||||
return set(self.orbits.keys()).union(set(self.navs.keys())).union(set(self.qcom_polys.keys()))
|
||||
|
||||
def get_navs(self, time):
|
||||
if time not in self.navs_fetched_times:
|
||||
self.get_nav_data(time)
|
||||
@@ -108,6 +119,12 @@ class AstroDog:
|
||||
self.cached_orbit[prn] = orbit
|
||||
return orbit
|
||||
|
||||
def get_qcom_poly(self, prn: str, time: GPSTime):
|
||||
poly = self._get_latest_valid_data(self.qcom_polys[prn], self.cached_qcom_polys[prn], None, time, True)
|
||||
if poly is not None:
|
||||
self.cached_qcom_polys[prn] = poly
|
||||
return poly
|
||||
|
||||
def get_orbits(self, time):
|
||||
if time not in self.orbit_fetched_times:
|
||||
self.get_orbit_data(time)
|
||||
@@ -129,13 +146,16 @@ class AstroDog:
|
||||
self.cached_dgps = latest_data
|
||||
return latest_data
|
||||
|
||||
def add_qcom_polys(self, new_ephems: Dict[str, List[Ephemeris]]):
|
||||
self._add_ephems(new_ephems, self.qcom_polys)
|
||||
|
||||
def add_orbits(self, new_ephems: Dict[str, List[Ephemeris]]):
|
||||
self._add_ephems(new_ephems, self.orbits, self.orbit_fetched_times)
|
||||
self._add_ephems(new_ephems, self.orbits)
|
||||
|
||||
def add_navs(self, new_ephems: Dict[str, List[Ephemeris]]):
|
||||
self._add_ephems(new_ephems, self.navs, self.navs_fetched_times)
|
||||
self._add_ephems(new_ephems, self.navs)
|
||||
|
||||
def _add_ephems(self, new_ephems: Dict[str, List[Ephemeris]], ephems_dict, fetched_times):
|
||||
def _add_ephems(self, new_ephems: Dict[str, List[Ephemeris]], ephems_dict):
|
||||
for k, v in new_ephems.items():
|
||||
if len(v) > 0:
|
||||
if self.clear_old_ephemeris:
|
||||
@@ -143,9 +163,10 @@ class AstroDog:
|
||||
else:
|
||||
ephems_dict[k].extend(v)
|
||||
|
||||
def add_ephem_fetched_time(self, ephems, fetched_times):
|
||||
min_epochs = []
|
||||
max_epochs = []
|
||||
for v in new_ephems.values():
|
||||
for v in ephems.values():
|
||||
if len(v) > 0:
|
||||
min_ephem, max_ephem = self.get_epoch_range(v)
|
||||
min_epochs.append(min_ephem)
|
||||
@@ -162,9 +183,9 @@ class AstroDog:
|
||||
|
||||
fetched_ephems = {}
|
||||
|
||||
if 'GPS' in self.valid_const:
|
||||
if ConstellationId.GPS in self.valid_const:
|
||||
fetched_ephems = download_and_parse(ConstellationId.GPS, parse_rinex_nav_msg_gps)
|
||||
if 'GLONASS' in self.valid_const:
|
||||
if ConstellationId.GLONASS in self.valid_const:
|
||||
for k, v in download_and_parse(ConstellationId.GLONASS, parse_rinex_nav_msg_glonass).items():
|
||||
fetched_ephems.setdefault(k, []).extend(v)
|
||||
self.add_navs(fetched_ephems)
|
||||
@@ -180,7 +201,7 @@ class AstroDog:
|
||||
with ThreadPoolExecutor() as executor:
|
||||
futures_other = [executor.submit(download_orbits_russia_src, t, self.cache_dir, self.valid_ephem_types) for t in time_steps]
|
||||
futures_gps = None
|
||||
if "GPS" in self.valid_const:
|
||||
if ConstellationId.GPS in self.valid_const:
|
||||
futures_gps = [executor.submit(download_orbits_gps, t, self.cache_dir, self.valid_ephem_types) for t in time_steps]
|
||||
|
||||
ephems_other = parse_sp3_orbits([f.result() for f in futures_other if f.result()], self.valid_const, skip_before_epoch)
|
||||
@@ -195,7 +216,7 @@ class AstroDog:
|
||||
result = download_prediction_orbits_russia_src(gps_time, self.cache_dir)
|
||||
if result is not None:
|
||||
result = [result]
|
||||
elif "GPS" in self.valid_const:
|
||||
elif ConstellationId.GPS in self.valid_const:
|
||||
# Slower fallback. Russia src prediction orbits are published from 2022
|
||||
result = [download_orbits_gps(t, self.cache_dir, self.valid_ephem_types) for t in [gps_time - SECS_IN_DAY, gps_time]]
|
||||
if result is None:
|
||||
@@ -209,7 +230,7 @@ class AstroDog:
|
||||
ephems_sp3 = self.download_parse_orbit(time)
|
||||
if sum([len(v) for v in ephems_sp3.values()]) < 5:
|
||||
raise RuntimeError(f'No orbit data found. For Time {time.as_datetime()} constellations {self.valid_const} valid ephem types {self.valid_ephem_types}')
|
||||
|
||||
self.add_ephem_fetched_time(ephems_sp3, self.orbit_fetched_times)
|
||||
self.add_orbits(ephems_sp3)
|
||||
|
||||
def get_dcb_data(self, time):
|
||||
@@ -257,7 +278,7 @@ class AstroDog:
|
||||
return eph.get_tgd()
|
||||
return None
|
||||
|
||||
def get_sat_info(self, prn, time):
|
||||
def get_eph(self, prn, time):
|
||||
if get_constellation(prn) not in self.valid_const:
|
||||
return None
|
||||
eph = None
|
||||
@@ -265,6 +286,12 @@ class AstroDog:
|
||||
eph = self.get_orbit(prn, time)
|
||||
if not eph and self.pull_nav:
|
||||
eph = self.get_nav(prn, time)
|
||||
if not eph and self.use_qcom_poly:
|
||||
eph = self.get_qcom_poly(prn, time)
|
||||
return eph
|
||||
|
||||
def get_sat_info(self, prn, time):
|
||||
eph = self.get_eph(prn, time)
|
||||
if eph:
|
||||
return eph.get_sat_info(time)
|
||||
return None
|
||||
@@ -285,7 +312,7 @@ class AstroDog:
|
||||
return None
|
||||
|
||||
def get_frequency(self, prn, time, signal='C1C'):
|
||||
if get_constellation(prn) == 'GPS':
|
||||
if get_constellation(prn) == ConstellationId.GPS:
|
||||
switch = {'1': constants.GPS_L1,
|
||||
'2': constants.GPS_L2,
|
||||
'5': constants.GPS_L5,
|
||||
@@ -296,7 +323,7 @@ class AstroDog:
|
||||
if freq:
|
||||
return freq
|
||||
raise NotImplementedError("Dont know this GPS frequency: ", signal, prn)
|
||||
elif get_constellation(prn) == 'GLONASS':
|
||||
elif get_constellation(prn) == ConstellationId.GLONASS:
|
||||
n = self.get_glonass_channel(prn, time)
|
||||
if n is None:
|
||||
return None
|
||||
@@ -319,7 +346,6 @@ class AstroDog:
|
||||
el, az = get_el_az(rcv_pos, sat_pos)
|
||||
if el < 0.2:
|
||||
return None
|
||||
|
||||
if self.dgps and not no_dgps:
|
||||
return self._get_delay_dgps(prn, rcv_pos, time)
|
||||
|
||||
@@ -330,7 +356,11 @@ class AstroDog:
|
||||
# When using internet we expect all data or return None
|
||||
if self.auto_update and (ionex is None or dcb is None or freq is None):
|
||||
return None
|
||||
iono_delay = ionex.get_delay(rcv_pos, az, el, sat_pos, time, freq) if ionex is not None else 0.
|
||||
if ionex is not None:
|
||||
iono_delay = ionex.get_delay(rcv_pos, az, el, sat_pos, time, freq)
|
||||
else:
|
||||
# 5m vertical delay is a good default
|
||||
iono_delay = get_slant_delay(rcv_pos, az, el, sat_pos, time, freq, vertical_delay=5.0)
|
||||
trop_delay = saast(rcv_pos, el)
|
||||
code_bias = dcb.get_delay(signal) if dcb is not None else 0.
|
||||
return iono_delay + trop_delay + code_bias
|
||||
|
||||
+3
-4
@@ -8,8 +8,7 @@ from . import raw_gnss as raw
|
||||
from . import opt
|
||||
from .rinex_file import RINEXFile
|
||||
from .downloader import download_cors_coords
|
||||
from .helpers import get_constellation
|
||||
|
||||
from .helpers import get_constellation, ConstellationId
|
||||
|
||||
def mean_filter(delay):
|
||||
d2 = delay.copy()
|
||||
@@ -79,7 +78,7 @@ def get_station_position(station_id, cache_dir='/tmp/gnss/', time=GPSTime.from_d
|
||||
return ((time - epoch)/SECS_IN_YEAR)*np.array(vel) + np.array(pos)
|
||||
|
||||
|
||||
def parse_dgps(station_id, station_obs_file_path, dog, max_distance=100000, required_constellations=['GPS']):
|
||||
def parse_dgps(station_id, station_obs_file_path, dog, max_distance=100000, required_constellations=[ConstellationId.GPS]):
|
||||
station_pos = get_station_position(station_id, cache_dir=dog.cache_dir)
|
||||
obsdata = RINEXFile(station_obs_file_path)
|
||||
measurements = raw.read_rinex_obs(obsdata)
|
||||
@@ -122,7 +121,7 @@ def parse_dgps(station_id, station_obs_file_path, dog, max_distance=100000, requ
|
||||
# could this be biased? Only use GPS for convenience.
|
||||
model_delays = {}
|
||||
for prn in station_delays['C1C']:
|
||||
if get_constellation(prn) == 'GPS':
|
||||
if get_constellation(prn) == ConstellationId.GPS:
|
||||
model_delays[prn] = np.nan*np.zeros(n)
|
||||
for i in range(n):
|
||||
model_delays[prn][i] = dog.get_delay(prn, times[i], station_pos, no_dgps=True)
|
||||
|
||||
+7
-6
@@ -8,6 +8,7 @@ import pycurl
|
||||
import re
|
||||
import time
|
||||
import socket
|
||||
import logging
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from urllib.parse import urlparse
|
||||
@@ -42,7 +43,7 @@ def retryable(f):
|
||||
try:
|
||||
return f(url_base, *args, **kwargs)
|
||||
except DownloadFailed as e:
|
||||
print(e)
|
||||
logging.warning(e)
|
||||
# none of them succeeded
|
||||
raise DownloadFailed("Multiple URL failures attempting to pull file(s)")
|
||||
return wrapped
|
||||
@@ -98,7 +99,7 @@ def ftp_download_files(url_base, folder_path, cacheDir, filenames):
|
||||
if "/" in filename:
|
||||
continue
|
||||
filepath = os.path.join(folder_path_abs, filename)
|
||||
print("pulling from", url_base, "to", filepath)
|
||||
logging.debug("pulling from", url_base, "to", filepath)
|
||||
|
||||
if not os.path.isfile(filepath):
|
||||
os.makedirs(folder_path_abs, exist_ok=True)
|
||||
@@ -141,7 +142,7 @@ def http_download_files(url_base, folder_path, cacheDir, filenames):
|
||||
continue
|
||||
filepath = os.path.join(folder_path_abs, filename)
|
||||
if not os.path.isfile(filepath):
|
||||
print("pulling from", url_base, "to", filepath)
|
||||
logging.debug("pulling from", url_base, "to", filepath)
|
||||
os.makedirs(folder_path_abs, exist_ok=True)
|
||||
url_path = url_base + folder_path + filename
|
||||
handle = pycurl.Curl()
|
||||
@@ -170,7 +171,7 @@ def http_download_files(url_base, folder_path, cacheDir, filenames):
|
||||
# if there are downloads left to be done, repeat, and don't overwrite
|
||||
_, requests_processing = fetcher.perform()
|
||||
if requests_processing > 0:
|
||||
print("some requests stalled, retrying them")
|
||||
logging.warning("some requests stalled, retrying them")
|
||||
return http_download_files(url_base, folder_path, cacheDir, filenames)
|
||||
|
||||
return filepaths
|
||||
@@ -229,7 +230,7 @@ def download_files(url_base, folder_path, cacheDir, filenames):
|
||||
@retryable
|
||||
def download_file(url_base, folder_path, filename_zipped):
|
||||
url = url_base + folder_path + filename_zipped
|
||||
print('Downloading ' + url)
|
||||
logging.debug('Downloading ' + url)
|
||||
if url.startswith('https://'):
|
||||
return https_download_file(url)
|
||||
elif url.startswith('ftp://'):
|
||||
@@ -478,5 +479,5 @@ def download_cors_station(time, station_name, cache_dir):
|
||||
filepath = download_and_cache_file(url_bases, folder_path, cache_dir+'cors_obs/', filename, compression='.gz')
|
||||
return filepath
|
||||
except DownloadFailed:
|
||||
print("File not downloaded, check availability on server.")
|
||||
logging.warning("File not downloaded, check availability on server.")
|
||||
return None
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
@0xb3ca6d2462778bb1;
|
||||
|
||||
struct Ephemeris {
|
||||
# This is according to the rinex (2?) format
|
||||
svId @0 :UInt16;
|
||||
year @1 :UInt16;
|
||||
month @2 :UInt16;
|
||||
day @3 :UInt16;
|
||||
hour @4 :UInt16;
|
||||
minute @5 :UInt16;
|
||||
second @6 :Float32;
|
||||
af0 @7 :Float64;
|
||||
af1 @8 :Float64;
|
||||
af2 @9 :Float64;
|
||||
|
||||
iode @10 :Float64;
|
||||
crs @11 :Float64;
|
||||
deltaN @12 :Float64;
|
||||
m0 @13 :Float64;
|
||||
|
||||
cuc @14 :Float64;
|
||||
ecc @15 :Float64;
|
||||
cus @16 :Float64;
|
||||
a @17 :Float64; # note that this is not the root!!
|
||||
|
||||
toe @18 :Float64;
|
||||
cic @19 :Float64;
|
||||
omega0 @20 :Float64;
|
||||
cis @21 :Float64;
|
||||
|
||||
i0 @22 :Float64;
|
||||
crc @23 :Float64;
|
||||
omega @24 :Float64;
|
||||
omegaDot @25 :Float64;
|
||||
|
||||
iDot @26 :Float64;
|
||||
codesL2 @27 :Float64;
|
||||
gpsWeekDEPRECATED @28 :Float64;
|
||||
l2 @29 :Float64;
|
||||
|
||||
svAcc @30 :Float64;
|
||||
svHealth @31 :Float64;
|
||||
tgd @32 :Float64;
|
||||
iodc @33 :Float64;
|
||||
|
||||
transmissionTime @34 :Float64;
|
||||
fitInterval @35 :Float64;
|
||||
|
||||
toc @36 :Float64;
|
||||
|
||||
ionoCoeffsValid @37 :Bool;
|
||||
ionoAlpha @38 :List(Float64);
|
||||
ionoBeta @39 :List(Float64);
|
||||
|
||||
towCount @40 :UInt32;
|
||||
toeWeek @41 :UInt16;
|
||||
tocWeek @42 :UInt16;
|
||||
}
|
||||
|
||||
struct GlonassEphemeris {
|
||||
svId @0 :UInt16;
|
||||
year @1 :UInt16;
|
||||
dayInYear @2 :UInt16;
|
||||
hour @3 :UInt16;
|
||||
minute @4 :UInt16;
|
||||
second @5 :Float32;
|
||||
|
||||
x @6 :Float64;
|
||||
xVel @7 :Float64;
|
||||
xAccel @8 :Float64;
|
||||
y @9 :Float64;
|
||||
yVel @10 :Float64;
|
||||
yAccel @11 :Float64;
|
||||
z @12 :Float64;
|
||||
zVel @13 :Float64;
|
||||
zAccel @14 :Float64;
|
||||
|
||||
svType @15 :UInt8;
|
||||
svURA @16 :Float32;
|
||||
age @17 :UInt8;
|
||||
|
||||
svHealth @18 :UInt8;
|
||||
tkDEPRECATED @19 :UInt16;
|
||||
tb @20 :UInt16;
|
||||
|
||||
tauN @21 :Float64;
|
||||
deltaTauN @22 :Float64;
|
||||
gammaN @23 :Float64;
|
||||
|
||||
p1 @24 :UInt8;
|
||||
p2 @25 :UInt8;
|
||||
p3 @26 :UInt8;
|
||||
p4 @27 :UInt8;
|
||||
|
||||
freqNumDEPRECATED @28 :UInt32;
|
||||
|
||||
n4 @29 :UInt8;
|
||||
nt @30 :UInt16;
|
||||
freqNum @31 :Int16;
|
||||
tkSeconds @32 :UInt32;
|
||||
}
|
||||
|
||||
struct EphemerisCache {
|
||||
gpsEphemerides @0 :List(Ephemeris);
|
||||
glonassEphemerides @1 :List(GlonassEphemeris);
|
||||
}
|
||||
+106
-201
@@ -1,4 +1,3 @@
|
||||
import json
|
||||
import warnings
|
||||
from abc import ABC, abstractmethod
|
||||
from collections import defaultdict
|
||||
@@ -7,7 +6,7 @@ from typing import Dict, List, Optional
|
||||
|
||||
import numpy as np
|
||||
import numpy.polynomial.polynomial as poly
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime
|
||||
from math import sin, cos, sqrt, fabs, atan2
|
||||
|
||||
from .gps_time import GPSTime, utc_to_gpst
|
||||
@@ -15,6 +14,12 @@ from .constants import SPEED_OF_LIGHT, SECS_IN_MIN, SECS_IN_HR, SECS_IN_DAY, \
|
||||
SECS_IN_WEEK, EARTH_ROTATION_RATE, EARTH_GM
|
||||
from .helpers import get_constellation, get_prn_from_nmea_id
|
||||
|
||||
import capnp
|
||||
import os
|
||||
capnp.remove_import_hook()
|
||||
capnp_path = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "ephemeris.capnp"))
|
||||
ephemeris_structs = capnp.load(capnp_path)
|
||||
|
||||
|
||||
def read4(f, rinex_ver):
|
||||
line = f.readline()[:-1]
|
||||
@@ -24,95 +29,6 @@ def read4(f, rinex_ver):
|
||||
return float(line[4:23]), float(line[23:42]), float(line[42:61]), float(line[61:80])
|
||||
|
||||
|
||||
def convert_ublox_gps_ephem(ublox_ephem, current_time: Optional[datetime] = None):
|
||||
# Week time of ephemeris gps msg has a roll-over period of 10 bits (19.6 years)
|
||||
# The latest roll-over was on 2019-04-07
|
||||
week = ublox_ephem.gpsWeek
|
||||
if current_time is None:
|
||||
# Each message is incremented to be greater or equal than week 1877 (2015-12-27).
|
||||
# To skip this use the current_time argument
|
||||
week += 1024
|
||||
if week < 1877:
|
||||
week += 1024
|
||||
else:
|
||||
roll_overs = GPSTime.from_datetime(current_time).week // 1024
|
||||
week += (roll_overs - (week // 1024)) * 1024
|
||||
|
||||
# GPS week refers to current week, the ephemeris can be valid for the next
|
||||
# if toe equals 0, this can be verified by the TOW count if it is within the
|
||||
# last 2 hours of the week (gps ephemeris valid for 4hours)
|
||||
if ublox_ephem.toe == 0 and ublox_ephem.towCount*6 >= (SECS_IN_WEEK - 2*SECS_IN_HR):
|
||||
week += 1
|
||||
|
||||
ephem = {}
|
||||
ephem['sv_id'] = ublox_ephem.svId
|
||||
ephem['toe'] = GPSTime(week, ublox_ephem.toe)
|
||||
ephem['toc'] = GPSTime(week, ublox_ephem.toc)
|
||||
ephem['af0'] = ublox_ephem.af0
|
||||
ephem['af1'] = ublox_ephem.af1
|
||||
ephem['af2'] = ublox_ephem.af2
|
||||
ephem['tgd'] = ublox_ephem.tgd
|
||||
|
||||
ephem['sqrta'] = np.sqrt(ublox_ephem.a)
|
||||
ephem['dn'] = ublox_ephem.deltaN
|
||||
ephem['m0'] = ublox_ephem.m0
|
||||
|
||||
ephem['ecc'] = ublox_ephem.ecc
|
||||
ephem['w'] = ublox_ephem.omega
|
||||
ephem['cus'] = ublox_ephem.cus
|
||||
ephem['cuc'] = ublox_ephem.cuc
|
||||
ephem['crc'] = ublox_ephem.crc
|
||||
ephem['crs'] = ublox_ephem.crs
|
||||
ephem['cic'] = ublox_ephem.cic
|
||||
ephem['cis'] = ublox_ephem.cis
|
||||
|
||||
ephem['inc'] = ublox_ephem.i0
|
||||
ephem['inc_dot'] = ublox_ephem.iDot
|
||||
ephem['omegadot'] = ublox_ephem.omegaDot
|
||||
ephem['omega0'] = ublox_ephem.omega0
|
||||
|
||||
ephem['healthy'] = ublox_ephem.svHealth == 0.0
|
||||
|
||||
epoch = ephem['toe']
|
||||
return GPSEphemeris(ephem, epoch)
|
||||
|
||||
|
||||
def convert_ublox_glonass_ephem(ublox_ephem, current_time: Optional[datetime] = None):
|
||||
ephem = {}
|
||||
ephem['prn'] = 'R%02i' % ublox_ephem.svId
|
||||
|
||||
etime = datetime.strptime(f"{ublox_ephem.year}-{ublox_ephem.dayInYear}", "%Y-%j")
|
||||
# glonass time: UTC + 3h
|
||||
time_in_day = timedelta(hours=ublox_ephem.hour, minutes=ublox_ephem.minute, seconds=ublox_ephem.second)
|
||||
ephem['toc'] = GPSTime.from_datetime(etime + time_in_day - timedelta(hours=3))
|
||||
ephem['toe'] = GPSTime.from_datetime(etime + timedelta(minutes=(ublox_ephem.tb*15 - 180)))
|
||||
|
||||
ephem['x'] = ublox_ephem.x # km
|
||||
ephem['x_vel'] = ublox_ephem.xVel # km/s
|
||||
ephem['x_acc'] = ublox_ephem.xAccel # km/s*s
|
||||
|
||||
ephem['y'] = ublox_ephem.y # km
|
||||
ephem['y_vel'] = ublox_ephem.yVel # km/s
|
||||
ephem['y_acc'] = ublox_ephem.yAccel # km/s*s
|
||||
|
||||
ephem['z'] = ublox_ephem.z # km
|
||||
ephem['z_vel'] = ublox_ephem.zVel # km/s
|
||||
ephem['z_acc'] = ublox_ephem.zAccel # km/s*s
|
||||
|
||||
ephem['healthy'] = ublox_ephem.svHealth == 0.0
|
||||
ephem['age'] = ublox_ephem.age # age of information [days]
|
||||
|
||||
# tauN compared to ephemeris from gdc.cddis.eosdis.nasa.gov is times -1
|
||||
ephem['min_tauN'] = ublox_ephem.tauN * (-1) # time correction relative to GLONASS tc
|
||||
ephem['GammaN'] = ublox_ephem.gammaN
|
||||
|
||||
# TODO: channel is in string 7, which is not parsed
|
||||
ephem['freq_num'] = "1"
|
||||
|
||||
# NOTE: ublox_ephem.tk is in a different format than rinex tk
|
||||
return GLONASSEphemeris(ephem, ephem['toe'])
|
||||
|
||||
|
||||
class EphemerisType(IntEnum):
|
||||
# Matches the enum in log.capnp
|
||||
NAV = 0
|
||||
@@ -138,17 +54,16 @@ class EphemerisType(IntEnum):
|
||||
|
||||
class Ephemeris(ABC):
|
||||
|
||||
def __init__(self, prn: str, data, epoch: GPSTime, eph_type: EphemerisType, healthy: bool, max_time_diff: float,
|
||||
def __init__(self, prn: str, epoch: GPSTime, eph_type: EphemerisType, healthy: bool, max_time_diff: float,
|
||||
file_epoch: Optional[GPSTime] = None, file_name=None):
|
||||
self.prn = prn
|
||||
self.data = data
|
||||
self.epoch = epoch
|
||||
self.eph_type = eph_type
|
||||
self.healthy = healthy
|
||||
self.max_time_diff = max_time_diff
|
||||
self.file_epoch = file_epoch
|
||||
self.file_name = file_name
|
||||
self.file_source = '' if file_name is None else file_name.split('/')[-1][:3] # File source for the ephemeris (e.g. igu, igr, Sta)
|
||||
self.__json = None
|
||||
|
||||
def valid(self, time):
|
||||
return abs(time - self.epoch) <= self.max_time_diff
|
||||
@@ -169,54 +84,24 @@ class Ephemeris(ABC):
|
||||
def _get_sat_info(self, time):
|
||||
pass
|
||||
|
||||
def to_json(self):
|
||||
if self.__json is None:
|
||||
dict = self.__dict__
|
||||
dict['ephemeris_class'] = self.__class__.__name__
|
||||
self.__json = {'ephemeris': json.dumps(dict, cls=EphemerisSerializer)}
|
||||
return self.__json
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_dct):
|
||||
dct = json.loads(json_dct['ephemeris'], object_hook=ephemeris_deserialize_hook)
|
||||
obj = cls.__new__(globals()[dct['ephemeris_class']])
|
||||
obj.__dict__.update(dct)
|
||||
obj.__json = json_dct
|
||||
return obj
|
||||
|
||||
|
||||
def ephemeris_deserialize_hook(dct):
|
||||
if 'week' in dct:
|
||||
return GPSTime(dct['week'], dct['tow'])
|
||||
return dct
|
||||
|
||||
|
||||
class EphemerisSerializer(json.JSONEncoder):
|
||||
|
||||
def default(self, o):
|
||||
if isinstance(o, GPSTime):
|
||||
return o.__dict__
|
||||
if isinstance(o, np.ndarray):
|
||||
return o.tolist()
|
||||
return json.JSONEncoder.default(self, o)
|
||||
|
||||
|
||||
class GLONASSEphemeris(Ephemeris):
|
||||
def __init__(self, data, epoch, file_name=None):
|
||||
super().__init__(data['prn'], data, epoch, EphemerisType.NAV, data['healthy'], max_time_diff=25*SECS_IN_MIN, file_name=file_name)
|
||||
self.channel = data['freq_num']
|
||||
self.to_json()
|
||||
def __init__(self, data, file_name=None):
|
||||
self.epoch = GPSTime.from_glonass(data.n4, data.nt, data.tb*15*SECS_IN_MIN)
|
||||
super().__init__('R%02i' % data.svId, self.epoch, EphemerisType.NAV, data.svHealth==0, max_time_diff=25*SECS_IN_MIN, file_name=file_name)
|
||||
self.data = data
|
||||
self.epoch = GPSTime.from_glonass(data.n4, data.nt, data.tb*15 * SECS_IN_MIN)
|
||||
self.channel = data.freqNum
|
||||
|
||||
def _get_sat_info(self, time: GPSTime):
|
||||
# see the russian doc for this:
|
||||
# http://gauss.gge.unb.ca/GLONASS.ICD.pdf
|
||||
|
||||
eph = self.data
|
||||
tdiff = time - utc_to_gpst(eph['toe'])
|
||||
|
||||
tdiff = time - self.epoch
|
||||
# Clock correction (except for general relativity which is applied later)
|
||||
clock_err = eph['min_tauN'] + tdiff * (eph['GammaN'])
|
||||
clock_rate_err = eph['GammaN']
|
||||
clock_err = -eph.tauN + tdiff * eph.gammaN
|
||||
clock_rate_err = eph.gammaN
|
||||
|
||||
def glonass_diff_eq(state, acc):
|
||||
J2 = 1.0826257e-3
|
||||
@@ -238,14 +123,14 @@ class GLONASSEphemeris(Ephemeris):
|
||||
return ders
|
||||
|
||||
init_state = np.empty(6)
|
||||
init_state[0] = eph['x']
|
||||
init_state[1] = eph['y']
|
||||
init_state[2] = eph['z']
|
||||
init_state[3] = eph['x_vel']
|
||||
init_state[4] = eph['y_vel']
|
||||
init_state[5] = eph['z_vel']
|
||||
init_state[0] = eph.x
|
||||
init_state[1] = eph.y
|
||||
init_state[2] = eph.z
|
||||
init_state[3] = eph.xVel
|
||||
init_state[4] = eph.yVel
|
||||
init_state[5] = eph.zVel
|
||||
init_state = 1000*init_state
|
||||
acc = 1000*np.array([eph['x_acc'], eph['y_acc'], eph['z_acc']])
|
||||
acc = 1000*np.array([eph.xAccel, eph.yAccel, eph.zAccel])
|
||||
state = init_state
|
||||
tstep = 90
|
||||
if tdiff < 0:
|
||||
@@ -271,9 +156,9 @@ class PolyEphemeris(Ephemeris):
|
||||
def __init__(self, prn: str, data, epoch: GPSTime, ephem_type: EphemerisType,
|
||||
file_epoch: GPSTime=None, file_name: str=None, healthy=True, tgd=0,
|
||||
max_time_diff: int=SECS_IN_HR):
|
||||
super().__init__(prn, data, epoch, ephem_type, healthy, max_time_diff=max_time_diff, file_epoch=file_epoch, file_name=file_name)
|
||||
super().__init__(prn, epoch, ephem_type, healthy, max_time_diff=max_time_diff, file_epoch=file_epoch, file_name=file_name)
|
||||
self.data = data
|
||||
self.tgd = tgd
|
||||
self.to_json()
|
||||
|
||||
def _get_sat_info(self, time: GPSTime):
|
||||
dt = time - self.data['t0']
|
||||
@@ -290,27 +175,32 @@ class PolyEphemeris(Ephemeris):
|
||||
|
||||
|
||||
class GPSEphemeris(Ephemeris):
|
||||
def __init__(self, data, epoch, file_name=None):
|
||||
super().__init__('G%02i' % data['sv_id'], data, epoch, EphemerisType.NAV, data['healthy'], max_time_diff=2*SECS_IN_HR, file_name=file_name)
|
||||
def __init__(self, data, file_name=None):
|
||||
self.toe = GPSTime(data.toeWeek, data.toe)
|
||||
self.toc = GPSTime(data.tocWeek, data.toc)
|
||||
self.epoch = self.toc
|
||||
|
||||
super().__init__('G%02i' % data.svId, self.epoch, EphemerisType.NAV, data.svHealth==0, max_time_diff=2*SECS_IN_HR, file_name=file_name)
|
||||
self.max_time_diff_tgd = SECS_IN_DAY
|
||||
self.to_json()
|
||||
self.data = data
|
||||
self.sqrta = np.sqrt(data.a)
|
||||
|
||||
def get_tgd(self):
|
||||
return self.data['tgd']
|
||||
return self.datatgd
|
||||
|
||||
def _get_sat_info(self, time: GPSTime):
|
||||
eph = self.data
|
||||
tdiff = time - eph['toc'] # Time of clock
|
||||
clock_err = eph['af0'] + tdiff * (eph['af1'] + tdiff * eph['af2'])
|
||||
clock_rate_err = eph['af1'] + 2 * tdiff * eph['af2']
|
||||
tdiff = time - self.toc # Time of clock
|
||||
clock_err = eph.af0 + tdiff * (eph.af1 + tdiff * eph.af2)
|
||||
clock_rate_err = eph.af1 + 2 * tdiff * eph.af2\
|
||||
|
||||
# Orbit propagation
|
||||
tdiff = time - eph['toe'] # Time of ephemeris (might be different from time of clock)
|
||||
tdiff = time - self.toe # Time of ephemeris (might be different from time of clock)
|
||||
|
||||
# Calculate position per IS-GPS-200D p 97 Table 20-IV
|
||||
a = eph['sqrta'] * eph['sqrta'] # [m] Semi-major axis
|
||||
ma_dot = sqrt(EARTH_GM / (a * a * a)) + eph['dn'] # [rad/sec] Corrected mean motion
|
||||
ma = eph['m0'] + ma_dot * tdiff # [rad] Corrected mean anomaly
|
||||
a = self.sqrta * self.sqrta # [m] Semi-major axis
|
||||
ma_dot = sqrt(EARTH_GM / (a * a * a)) + eph.deltaN # [rad/sec] Corrected mean motion
|
||||
ma = eph.m0 + ma_dot * tdiff # [rad] Corrected mean anomaly
|
||||
|
||||
# Iteratively solve for the Eccentric Anomaly (from Keith Alter and David Johnston)
|
||||
ea = ma # Starting value for E
|
||||
@@ -318,37 +208,37 @@ class GPSEphemeris(Ephemeris):
|
||||
ea_old = 2222
|
||||
while fabs(ea - ea_old) > 1.0E-14:
|
||||
ea_old = ea
|
||||
tempd1 = 1.0 - eph['ecc'] * cos(ea_old)
|
||||
ea = ea + (ma - ea_old + eph['ecc'] * sin(ea_old)) / tempd1
|
||||
tempd1 = 1.0 - eph.ecc * cos(ea_old)
|
||||
ea = ea + (ma - ea_old + eph.ecc * sin(ea_old)) / tempd1
|
||||
ea_dot = ma_dot / tempd1
|
||||
|
||||
# Relativistic correction term
|
||||
einstein = -4.442807633E-10 * eph['ecc'] * eph['sqrta'] * sin(ea)
|
||||
einstein = -4.442807633E-10 * eph.ecc * self.sqrta * sin(ea)
|
||||
|
||||
# Begin calc for True Anomaly and Argument of Latitude
|
||||
tempd2 = sqrt(1.0 - eph['ecc'] * eph['ecc'])
|
||||
tempd2 = sqrt(1.0 - eph.ecc * eph.ecc)
|
||||
# [rad] Argument of Latitude = True Anomaly + Argument of Perigee
|
||||
al = atan2(tempd2 * sin(ea), cos(ea) - eph['ecc']) + eph['w']
|
||||
al = atan2(tempd2 * sin(ea), cos(ea) - eph.ecc) + eph.omega
|
||||
al_dot = tempd2 * ea_dot / tempd1
|
||||
|
||||
# Calculate corrected argument of latitude based on position
|
||||
cal = al + eph['cus'] * sin(2.0 * al) + eph['cuc'] * cos(2.0 * al)
|
||||
cal_dot = al_dot * (1.0 + 2.0 * (eph['cus'] * cos(2.0 * al) -
|
||||
eph['cuc'] * sin(2.0 * al)))
|
||||
cal = al + eph.cus * sin(2.0 * al) + eph.cuc * cos(2.0 * al)
|
||||
cal_dot = al_dot * (1.0 + 2.0 * (eph.cus * cos(2.0 * al) -
|
||||
eph.cuc * sin(2.0 * al)))
|
||||
|
||||
# Calculate corrected radius based on argument of latitude
|
||||
r = a * tempd1 + eph['crc'] * cos(2.0 * al) + eph['crs'] * sin(2.0 * al)
|
||||
r_dot = (a * eph['ecc'] * sin(ea) * ea_dot +
|
||||
2.0 * al_dot * (eph['crs'] * cos(2.0 * al) -
|
||||
eph['crc'] * sin(2.0 * al)))
|
||||
r = a * tempd1 + eph.crc * cos(2.0 * al) + eph.crs * sin(2.0 * al)
|
||||
r_dot = (a * eph.ecc * sin(ea) * ea_dot +
|
||||
2.0 * al_dot * (eph.crs * cos(2.0 * al) -
|
||||
eph.crc * sin(2.0 * al)))
|
||||
|
||||
# Calculate inclination based on argument of latitude
|
||||
inc = (eph['inc'] + eph['inc_dot'] * tdiff +
|
||||
eph['cic'] * cos(2.0 * al) +
|
||||
eph['cis'] * sin(2.0 * al))
|
||||
inc_dot = (eph['inc_dot'] +
|
||||
2.0 * al_dot * (eph['cis'] * cos(2.0 * al) -
|
||||
eph['cic'] * sin(2.0 * al)))
|
||||
inc = (eph.i0 + eph.iDot * tdiff +
|
||||
eph.cic * cos(2.0 * al) +
|
||||
eph.cis * sin(2.0 * al))
|
||||
inc_dot = (eph.iDot +
|
||||
2.0 * al_dot * (eph.cis * cos(2.0 * al) -
|
||||
eph.cic * sin(2.0 * al)))
|
||||
|
||||
# Calculate position and velocity in orbital plane
|
||||
x = r * cos(cal)
|
||||
@@ -357,8 +247,8 @@ class GPSEphemeris(Ephemeris):
|
||||
y_dot = r_dot * sin(cal) + x * cal_dot
|
||||
|
||||
# Corrected longitude of ascending node
|
||||
om_dot = eph['omegadot'] - EARTH_ROTATION_RATE
|
||||
om = eph['omega0'] + tdiff * om_dot - EARTH_ROTATION_RATE * eph['toe'].tow
|
||||
om_dot = eph.omegaDot - EARTH_ROTATION_RATE
|
||||
om = eph.omega0 + tdiff * om_dot - EARTH_ROTATION_RATE * self.toe.tow
|
||||
|
||||
# Compute the satellite's position in Earth-Centered Earth-Fixed coordinates
|
||||
pos = np.empty(3)
|
||||
@@ -507,24 +397,26 @@ def parse_rinex_nav_msg_gps(file_name):
|
||||
line = ' ' + line # Shift 1 char to the right
|
||||
|
||||
line = line.replace('D', 'E') # Handle bizarro float format
|
||||
e = {'epoch': epoch, 'sv_id': sv_id}
|
||||
e['toc'] = epoch
|
||||
e = {'svId': sv_id}
|
||||
# TODO are TOC and TOE the same?
|
||||
e['toc'] = epoch.tow
|
||||
e['tocWeek'] = epoch.week
|
||||
e['af0'] = float(line[23:42])
|
||||
e['af1'] = float(line[42:61])
|
||||
e['af2'] = float(line[61:80])
|
||||
|
||||
e['iode'], e['crs'], e['dn'], e['m0'] = read4(f, rinex_ver)
|
||||
e['cuc'], e['ecc'], e['cus'], e['sqrta'] = read4(f, rinex_ver)
|
||||
toe_tow, e['cic'], e['omega0'], e['cis'] = read4(f, rinex_ver)
|
||||
e['inc'], e['crc'], e['w'], e['omegadot'] = read4(f, rinex_ver)
|
||||
e['inc_dot'], e['l2_codes'], toe_week, e['l2_pflag'] = read4(f, rinex_ver)
|
||||
e['sv_accuracy'], e['health'], e['tgd'], e['iodc'] = read4(f, rinex_ver)
|
||||
e['iode'], e['crs'], e['deltaN'], e['m0'] = read4(f, rinex_ver)
|
||||
e['cuc'], e['ecc'], e['cus'], sqrta = read4(f, rinex_ver)
|
||||
e['a'] = sqrta ** 2
|
||||
e['toe'], e['cic'], e['omega0'], e['cis'] = read4(f, rinex_ver)
|
||||
e['i0'], e['crc'], e['omega'], e['omegaDot'] = read4(f, rinex_ver)
|
||||
e['iDot'], e['codesL2'], e['toeWeek'], l2_pflag = read4(f, rinex_ver)
|
||||
e['svAcc'], e['svHealth'], e['tgd'], e['iodc'] = read4(f, rinex_ver)
|
||||
f.readline() # Discard last row
|
||||
|
||||
e['toe'] = GPSTime(toe_week, toe_tow)
|
||||
e['healthy'] = (e['health'] == 0.0)
|
||||
data_struct = ephemeris_structs.Ephemeris.new_message(**e)
|
||||
|
||||
ephem = GPSEphemeris(e, epoch, file_name=file_name)
|
||||
ephem = GPSEphemeris(data_struct, file_name=file_name)
|
||||
ephems[ephem.prn].append(ephem)
|
||||
f.close()
|
||||
return ephems
|
||||
@@ -550,26 +442,39 @@ def parse_rinex_nav_msg_glonass(file_name):
|
||||
got_header = True
|
||||
continue
|
||||
if rinex_ver == 3:
|
||||
prn = line[:3]
|
||||
epoch = GPSTime.from_datetime(datetime.strptime(line[4:23], "%y %m %d %H %M %S"))
|
||||
sv_id = int(line[1:3])
|
||||
|
||||
epoch = utc_to_gpst(GPSTime.from_datetime(datetime.strptime(line[4:23], "%y %m %d %H %M %S")))
|
||||
elif rinex_ver == 2:
|
||||
prn = 'R%02i' % int(line[0:2])
|
||||
epoch = GPSTime.from_datetime(datetime.strptime(line[3:20], "%y %m %d %H %M %S"))
|
||||
sv_id = int(line[0:2])
|
||||
epoch = utc_to_gpst(GPSTime.from_datetime(datetime.strptime(line[3:20], "%y %m %d %H %M %S")))
|
||||
line = ' ' + line # Shift 1 char to the right
|
||||
|
||||
line = line.replace('D', 'E') # Handle bizarro float format
|
||||
e = {'epoch': epoch, 'prn': prn}
|
||||
e['toe'] = epoch
|
||||
e['min_tauN'] = float(line[23:42])
|
||||
e['GammaN'] = float(line[42:61])
|
||||
e['tk'] = float(line[61:80])
|
||||
e = {'svId': sv_id}
|
||||
e['n4'], e['nt'], toe_seconds = epoch.as_glonass()
|
||||
tb = toe_seconds / (15 * SECS_IN_MIN)
|
||||
|
||||
e['x'], e['x_vel'], e['x_acc'], e['health'] = read4(f, rinex_ver)
|
||||
e['y'], e['y_vel'], e['y_acc'], e['freq_num'] = read4(f, rinex_ver)
|
||||
e['z'], e['z_vel'], e['z_acc'], e['age'] = read4(f, rinex_ver)
|
||||
|
||||
e['tb'] = tb
|
||||
|
||||
e['healthy'] = (e['health'] == 0.0)
|
||||
ephems[prn].append(GLONASSEphemeris(e, epoch, file_name=file_name))
|
||||
e['tauN'] = -float(line[23:42])
|
||||
e['gammaN'] = float(line[42:61])
|
||||
e['tkSeconds'] = float(line[61:80])
|
||||
|
||||
e['x'], e['xVel'], e['xAccel'], e['svHealth'] = read4(f, rinex_ver)
|
||||
e['y'], e['yVel'], e['yAccel'], e['freqNum'] = read4(f, rinex_ver)
|
||||
e['z'], e['zVel'], e['zAccel'], e['age'] = read4(f, rinex_ver)
|
||||
|
||||
# TODO unclear why glonass sometimes has nav messages 3s after correct one
|
||||
if abs(tb - int(tb)) > 1e-3:
|
||||
continue
|
||||
|
||||
|
||||
data_struct = ephemeris_structs.GlonassEphemeris.new_message(**e)
|
||||
ephem = GLONASSEphemeris(data_struct, file_name=file_name)
|
||||
|
||||
ephems[ephem.prn].append(ephem)
|
||||
f.close()
|
||||
return ephems
|
||||
|
||||
@@ -580,9 +485,9 @@ def parse_qcom_ephem(qcom_poly, current_week):
|
||||
t0 = data.t0
|
||||
# fix glonass time
|
||||
prn = get_prn_from_nmea_id(svId)
|
||||
if prn == 'GLONASS':
|
||||
if prn[0] == 'R':
|
||||
# TODO should handle leap seconds better
|
||||
epoch = GPSTime(current_week, (t0 + 3*SECS_IN_WEEK) % (SECS_IN_WEEK) + 18)
|
||||
epoch = GPSTime(current_week, (t0 - 3*SECS_IN_HR + SECS_IN_DAY) % (SECS_IN_WEEK) + 18)
|
||||
else:
|
||||
epoch = GPSTime(current_week, t0)
|
||||
poly_data = {}
|
||||
@@ -595,4 +500,4 @@ def parse_qcom_ephem(qcom_poly, current_week):
|
||||
poly_data['clock'] = [1e-3*data.other[3], 1e-3*data.other[2], 1e-3*data.other[1], 1e-3*data.other[0]]
|
||||
poly_data['deg'] = 3
|
||||
poly_data['deg_t'] = 3
|
||||
return PolyEphemeris(prn, poly_data, epoch, ephem_type=EphemerisType.QCOM_POLY, max_time_diff=180)
|
||||
return PolyEphemeris(prn, poly_data, epoch, ephem_type=EphemerisType.QCOM_POLY, max_time_diff=300, file_name='qcom')
|
||||
|
||||
@@ -152,6 +152,17 @@ class GPSTime:
|
||||
def as_datetime(self):
|
||||
return tow_to_datetime(self.tow, self.week)
|
||||
|
||||
def as_glonass(self):
|
||||
time_utc = gpst_to_utc(self)
|
||||
datetime_utc = time_utc.as_datetime()
|
||||
datetime_glonass = datetime_utc + datetime.timedelta(hours=3)
|
||||
|
||||
year = datetime_glonass.year
|
||||
cycle = (year - 1992) // 4
|
||||
days = (datetime_glonass - datetime.datetime(1992 + cycle*4, 1, 1)).days + 1
|
||||
tod = (datetime_glonass - datetime_glonass.replace(hour=0, minute=0, second=0, microsecond=0)).total_seconds()
|
||||
return cycle, days, tod
|
||||
|
||||
def as_unix_timestamp(self):
|
||||
return (gpst_to_utc(self).as_datetime() - datetime.datetime(1970, 1, 1)).total_seconds()
|
||||
|
||||
|
||||
+5
-10
@@ -26,7 +26,7 @@ class ConstellationId(IntEnum):
|
||||
if c in RINEX_ID_TO_CONSTELLATION:
|
||||
return RINEX_ID_TO_CONSTELLATION[c]
|
||||
else:
|
||||
return None
|
||||
raise ValueError("Unknown rinex constellation id: ", c)
|
||||
|
||||
@classmethod
|
||||
def from_qcom_source(cls, report_source: int):
|
||||
@@ -97,14 +97,12 @@ def get_closest(time, candidates, recv_pos=None):
|
||||
default=None,
|
||||
)
|
||||
|
||||
|
||||
def get_constellation(prn: str):
|
||||
identifier = prn[0]
|
||||
constellation = ConstellationId.from_rinex_char(identifier)
|
||||
if constellation is not None:
|
||||
return constellation.name
|
||||
return None
|
||||
return ConstellationId.from_rinex_char(identifier)
|
||||
|
||||
def get_sv_id(prn: str):
|
||||
return int(prn[1:])
|
||||
|
||||
def get_constellation_and_sv_id(nmea_id):
|
||||
for c, ranges in CONSTELLATION_TO_NMEA_RANGES.items():
|
||||
@@ -123,11 +121,8 @@ def get_prn_from_nmea_id(nmea_id: int):
|
||||
|
||||
def get_nmea_id_from_prn(prn: str):
|
||||
constellation = get_constellation(prn)
|
||||
if constellation is None:
|
||||
raise ValueError(f"Constellation not found for prn {prn}")
|
||||
|
||||
sv_id = int(prn[1:]) # satellite id
|
||||
return get_nmea_id_from_constellation_and_svid(ConstellationId[constellation], sv_id)
|
||||
return get_nmea_id_from_constellation_and_svid(constellation, sv_id)
|
||||
|
||||
|
||||
def get_nmea_id_from_constellation_and_svid(constellation: ConstellationId, sv_id: int):
|
||||
|
||||
+14
-5
@@ -9,6 +9,17 @@ from .gps_time import GPSTime
|
||||
# Altitude of Ionospheric-pierce-point
|
||||
IPP_ALT = 6821000
|
||||
|
||||
def get_alpha_beta(rcv_pos, el):
|
||||
geocentric_alt = np.linalg.norm(rcv_pos)
|
||||
alpha = np.pi/2 + el
|
||||
beta = np.arcsin(geocentric_alt*np.sin(alpha)/IPP_ALT)
|
||||
return alpha, beta
|
||||
|
||||
def get_slant_delay(rcv_pos, az, el, sat_pos, time, freq, vertical_delay):
|
||||
alpha, beta = get_alpha_beta(rcv_pos, el)
|
||||
slant_delay = vertical_delay * ((1 - ((EARTH_RADIUS * np.sin(beta)) /
|
||||
(EARTH_RADIUS + 3.5e5))**2)**(-0.5))
|
||||
return slant_delay
|
||||
|
||||
def closest_in_list(lst, val, num=2):
|
||||
"""
|
||||
@@ -134,18 +145,16 @@ class IonexMap:
|
||||
# To get a delay from a TEC map, we need to calculate
|
||||
# the ionospheric pierce point, geometry described here
|
||||
# https://en.wikipedia.org/wiki/Ionospheric_pierce_point
|
||||
alpha, beta = get_alpha_beta(rcv_pos, el)
|
||||
conv = LocalCoord.from_ecef(rcv_pos)
|
||||
geocentric_alt = np.linalg.norm(rcv_pos)
|
||||
alpha = np.pi/2 + el
|
||||
beta = np.arcsin(geocentric_alt*np.sin(alpha)/IPP_ALT)
|
||||
gamma = np.pi - alpha - beta
|
||||
geocentric_alt = np.linalg.norm(rcv_pos)
|
||||
ipp_dist = geocentric_alt*np.sin(gamma)/np.sin(beta)
|
||||
ipp_ned = conv.ecef2ned(sat_pos)*(ipp_dist)/np.linalg.norm(sat_pos)
|
||||
ipp_geo = conv.ned2geodetic(ipp_ned)
|
||||
factor = 40.30E16 / (freq**2) * 10**(self.exp)
|
||||
vertical_delay = self.get_TEC(ipp_geo, time) * factor
|
||||
slant_delay = vertical_delay * ((1 - ((EARTH_RADIUS * np.sin(beta)) /
|
||||
(EARTH_RADIUS + 3.5e5))**2)**(-0.5))
|
||||
slant_delay = get_slant_delay(rcv_pos, az, el, sat_pos, time, freq, vertical_delay)
|
||||
return slant_delay
|
||||
|
||||
@staticmethod
|
||||
|
||||
+35
-34
@@ -7,22 +7,28 @@ from .helpers import ConstellationId
|
||||
from .raw_gnss import GNSSMeasurement
|
||||
|
||||
|
||||
def gauss_newton(fun, b, xtol=1e-8, max_n=25):
|
||||
def gauss_newton(fun, b, M, xtol=1e-8, max_n=25):
|
||||
|
||||
W = np.linalg.inv(M)
|
||||
for _ in range(max_n):
|
||||
# Compute function and jacobian on current estimate
|
||||
r, J = fun(b)
|
||||
|
||||
# Update estimate
|
||||
delta = np.linalg.pinv(J) @ r
|
||||
# Update estimate, WLS https://en.wikipedia.org/wiki/Weighted_least_squares
|
||||
delta = np.linalg.pinv(J.T.dot(W).dot(J)).dot(J.T).dot(W) @ r
|
||||
b -= delta
|
||||
|
||||
# Check step size for stopping condition
|
||||
if np.linalg.norm(delta) < xtol:
|
||||
break
|
||||
return b
|
||||
|
||||
r, J = fun(b)
|
||||
Mb = np.linalg.pinv(J.T.dot(W).dot(J))
|
||||
x_std = np.sqrt(np.diagonal(Mb))
|
||||
return b, r, x_std
|
||||
|
||||
|
||||
def calc_pos_fix(measurements, posfix_functions=None, x0=None, no_weight=False, signal='C1C', min_measurements=6):
|
||||
def calc_pos_fix(measurements, posfix_functions=None, x0=None, signal='C1C', min_measurements=5):
|
||||
'''
|
||||
Calculates gps fix using gauss newton method
|
||||
To solve the problem a minimal of 4 measurements are required.
|
||||
@@ -35,15 +41,16 @@ def calc_pos_fix(measurements, posfix_functions=None, x0=None, no_weight=False,
|
||||
x0 = [0, 0, 0, 0, 0]
|
||||
|
||||
if len(measurements) < min_measurements:
|
||||
return [],[]
|
||||
return [],[],[]
|
||||
|
||||
Fx_pos = pr_residual(measurements, posfix_functions, signal=signal, no_weight=no_weight, no_nans=True)
|
||||
x = gauss_newton(Fx_pos, x0)
|
||||
residual, _ = Fx_pos(x, no_weight=True)
|
||||
return x.tolist(), residual.tolist()
|
||||
Fx_pos = pr_residual(measurements, posfix_functions, signal=signal, no_nans=True)
|
||||
meas_cov = np.diag([meas.observables_std[signal]**2 for meas in measurements])
|
||||
|
||||
x, residual, x_std = gauss_newton(Fx_pos, x0, meas_cov)
|
||||
return x.tolist(), residual.tolist(), x_std
|
||||
|
||||
|
||||
def calc_vel_fix(measurements, est_pos, velfix_function=None, v0=None, no_weight=False, signal='D1C', min_measurements=6):
|
||||
def calc_vel_fix(measurements, est_pos, velfix_function=None, v0=None, signal='D1C', min_measurements=5):
|
||||
'''
|
||||
Calculates gps velocity fix using gauss newton method
|
||||
returns:
|
||||
@@ -54,12 +61,13 @@ def calc_vel_fix(measurements, est_pos, velfix_function=None, v0=None, no_weight
|
||||
v0 = [0, 0, 0, 0]
|
||||
|
||||
if len(measurements) < min_measurements:
|
||||
return [], []
|
||||
return [], [], []
|
||||
|
||||
Fx_vel = prr_residual(measurements, est_pos, velfix_function, signal=signal, no_weight=no_weight, no_nans=True)
|
||||
v = gauss_newton(Fx_vel, v0)
|
||||
residual, _ = Fx_vel(v, no_weight=True)
|
||||
return v.tolist(), residual.tolist()
|
||||
Fx_vel = prr_residual(measurements, est_pos, velfix_function, signal=signal, no_nans=True)
|
||||
meas_cov = np.diag([meas.observables_std[signal]**2 for meas in measurements])
|
||||
|
||||
v, residual, x_std = gauss_newton(Fx_vel, v0, meas_cov)
|
||||
return v.tolist(), residual.tolist(), x_std
|
||||
|
||||
|
||||
def get_posfix_sympy_fun(constellation):
|
||||
@@ -73,7 +81,6 @@ def get_posfix_sympy_fun(constellation):
|
||||
# Knowns
|
||||
pr = sympy.Symbol('pr')
|
||||
sat_x, sat_y, sat_z = sympy.Symbol('sat_x'), sympy.Symbol('sat_y'), sympy.Symbol('sat_z')
|
||||
weight = sympy.Symbol('weight')
|
||||
|
||||
theta = (EARTH_ROTATION_RATE * (pr - bc) / SPEED_OF_LIGHT)*zero_theta
|
||||
val = sympy.sqrt(
|
||||
@@ -83,15 +90,15 @@ def get_posfix_sympy_fun(constellation):
|
||||
)
|
||||
|
||||
if constellation == ConstellationId.GLONASS:
|
||||
res = weight * (val - (pr - bc - bg))
|
||||
res = val - (pr - bc - bg)
|
||||
elif constellation == ConstellationId.GPS:
|
||||
res = weight * (val - (pr - bc))
|
||||
res = val - (pr - bc)
|
||||
else:
|
||||
raise NotImplementedError(f"Constellation {constellation} not supported")
|
||||
|
||||
res = [res] + [sympy.diff(res, v) for v in var]
|
||||
|
||||
return sympy.lambdify([x, y, z, bc, bg, pr, zero_theta, sat_x, sat_y, sat_z, weight], res, modules=["numpy"])
|
||||
return sympy.lambdify([x, y, z, bc, bg, pr, zero_theta, sat_x, sat_y, sat_z], res, modules=["numpy"])
|
||||
|
||||
|
||||
def get_velfix_sympy_func():
|
||||
@@ -105,7 +112,6 @@ def get_velfix_sympy_func():
|
||||
sv_x, sv_y, sv_z = sympy.Symbol('sv_x'), sympy.Symbol('sv_y'), sympy.Symbol('sv_z')
|
||||
sat_vel = np.array([sv_x, sv_y, sv_z])
|
||||
observables = sympy.Symbol('observables')
|
||||
weight = sympy.Symbol('weight')
|
||||
|
||||
# unknown, receiver velocity
|
||||
v_x, v_y, v_z = sympy.Symbol('v_x'), sympy.Symbol('v_y'), sympy.Symbol('v_z')
|
||||
@@ -114,27 +120,24 @@ def get_velfix_sympy_func():
|
||||
|
||||
loss = sat_pos - est_pos
|
||||
loss /= sympy.sqrt(loss.dot(loss))
|
||||
|
||||
nv = loss.dot(sat_vel - vel)
|
||||
ov = (observables - vel_o)
|
||||
res = (nv - ov)*weight
|
||||
res = loss.dot(sat_vel - vel) - (observables - vel_o)
|
||||
|
||||
res = [res] + [sympy.diff(res, v) for v in [v_x, v_y, v_z, vel_o]]
|
||||
|
||||
return sympy.lambdify([
|
||||
ep_x, ep_y, ep_z, sp_x, sp_y, sp_z,
|
||||
sv_x, sv_y, sv_z, observables, weight,
|
||||
sv_x, sv_y, sv_z, observables,
|
||||
v_x, v_y, v_z, vel_o
|
||||
],
|
||||
res, modules=["numpy"])
|
||||
|
||||
|
||||
def pr_residual(measurements: List[GNSSMeasurement], posfix_functions=None, signal='C1C', no_weight=False, no_nans=False):
|
||||
def pr_residual(measurements: List[GNSSMeasurement], posfix_functions=None, signal='C1C', no_nans=False):
|
||||
|
||||
if posfix_functions is None:
|
||||
posfix_functions = {constellation: get_posfix_sympy_fun(constellation) for constellation in (ConstellationId.GPS, ConstellationId.GLONASS)}
|
||||
|
||||
def Fx_pos(inp, no_weight=no_weight):
|
||||
def Fx_pos(inp):
|
||||
vals, gradients = [], []
|
||||
|
||||
for meas in measurements:
|
||||
@@ -153,20 +156,19 @@ def pr_residual(measurements: List[GNSSMeasurement], posfix_functions=None, sign
|
||||
gradients.append(np.nan)
|
||||
continue
|
||||
|
||||
w = 1.0 if no_weight or meas.observables_std[signal] == 0 else (1 / meas.observables_std[signal])
|
||||
val, *gradient = posfix_functions[meas.constellation_id](*inp, pr, zero_theta, *sat_pos, w)
|
||||
val, *gradient = posfix_functions[meas.constellation_id](*inp, pr, zero_theta, *sat_pos)
|
||||
vals.append(val)
|
||||
gradients.append(gradient)
|
||||
return np.asarray(vals), np.asarray(gradients)
|
||||
return Fx_pos
|
||||
|
||||
|
||||
def prr_residual(measurements: List[GNSSMeasurement], est_pos, velfix_function=None, signal='D1C', no_weight=False, no_nans=False):
|
||||
def prr_residual(measurements: List[GNSSMeasurement], est_pos, velfix_function=None, signal='D1C', no_nans=False):
|
||||
|
||||
if velfix_function is None:
|
||||
velfix_function = get_velfix_sympy_func()
|
||||
|
||||
def Fx_vel(vel, no_weight=no_weight):
|
||||
def Fx_vel(vel):
|
||||
vals, gradients = [], []
|
||||
|
||||
for meas in measurements:
|
||||
@@ -177,12 +179,11 @@ def prr_residual(measurements: List[GNSSMeasurement], est_pos, velfix_function=N
|
||||
continue
|
||||
|
||||
sat_pos = meas.sat_pos_final if meas.corrected else meas.sat_pos
|
||||
weight = 1.0 if no_weight or meas.observables_std[signal] == 0 else (1 / meas.observables_std[signal])
|
||||
|
||||
val, *gradient = velfix_function(est_pos[0], est_pos[1], est_pos[2],
|
||||
sat_pos[0], sat_pos[1], sat_pos[2],
|
||||
meas.sat_vel[0], meas.sat_vel[1], meas.sat_vel[2],
|
||||
meas.observables[signal], weight,
|
||||
meas.observables[signal],
|
||||
vel[0], vel[1], vel[2], vel[3])
|
||||
vals.append(val)
|
||||
gradients.append(gradient)
|
||||
|
||||
+12
-9
@@ -92,10 +92,13 @@ class GNSSMeasurement:
|
||||
self.processed = True
|
||||
return True
|
||||
|
||||
def correct(self, est_pos, dog):
|
||||
def correct(self, est_pos, dog, correct_delay=True):
|
||||
for obs in self.observables:
|
||||
if obs[0] == 'C': # or obs[0] == 'L':
|
||||
delay = dog.get_delay(self.prn, self.recv_time, est_pos, signal=obs)
|
||||
if correct_delay:
|
||||
delay = dog.get_delay(self.prn, self.recv_time, est_pos, signal=obs)
|
||||
else:
|
||||
delay = 0.0
|
||||
if delay is not None:
|
||||
self.observables_final[obs] = (self.observables[obs] +
|
||||
self.sat_clock_err*constants.SPEED_OF_LIGHT -
|
||||
@@ -147,10 +150,10 @@ def process_measurements(measurements: List[GNSSMeasurement], dog) -> List[GNSSM
|
||||
return proc_measurements
|
||||
|
||||
|
||||
def correct_measurements(measurements: List[GNSSMeasurement], est_pos, dog) -> List[GNSSMeasurement]:
|
||||
def correct_measurements(measurements: List[GNSSMeasurement], est_pos, dog, correct_delay=True) -> List[GNSSMeasurement]:
|
||||
corrected_measurements = []
|
||||
for meas in measurements:
|
||||
if meas.correct(est_pos, dog):
|
||||
if meas.correct(est_pos, dog, correct_delay=correct_delay):
|
||||
corrected_measurements.append(meas)
|
||||
return corrected_measurements
|
||||
|
||||
@@ -195,12 +198,12 @@ def read_raw_qcom(report):
|
||||
time_bias_ms = report.timeBias
|
||||
else:
|
||||
raise NotImplementedError('Only GPS (0), SBAS (1) and GLONASS (6) are supported from qcom, not:', {report.source})
|
||||
#print(recv_time, report.source, time_bias_ms, dr)
|
||||
# logging.debug(recv_time, report.source, time_bias_ms, dr)
|
||||
measurements = []
|
||||
for i in report.sv:
|
||||
nmea_id = i.svId # todo change svId to nmea_id in cereal message. Or better: change the publisher to publish correct svId's, since constellation id is also given
|
||||
if nmea_id == 255:
|
||||
# todo nmea_id is not valid. Fix publisher
|
||||
# TODO nmea_id is not valid. Fix publisher
|
||||
continue
|
||||
_, sv_id = get_constellation_and_sv_id(nmea_id)
|
||||
if not i.measurementStatus.measurementNotUsable and i.measurementStatus.satelliteTimeIsKnown:
|
||||
@@ -217,9 +220,9 @@ def read_raw_qcom(report):
|
||||
observables_std['D1C'] = i.unfilteredSpeedUncertainty
|
||||
observables['S1C'] = (i.carrierNoise/100.) if i.carrierNoise != 0 else np.nan
|
||||
observables['L1C'] = np.nan
|
||||
#print(" %.5f %3d %10.2f %7.2f %7.2f %.2f %d" % (recv_time.tow, nmea_id,
|
||||
# observables['C1C'], observables_std['C1C'],
|
||||
# observables_std['D1C'], observables['S1C'], i.latency), i.observationState, i.measurementStatus.fineOrCoarseVelocity)
|
||||
# logging.debug(" %.5f %3d %10.2f %7.2f %7.2f %.2f %d" % (recv_time.tow, nmea_id,
|
||||
# observables['C1C'], observables_std['C1C'],
|
||||
# observables_std['D1C'], observables['S1C'], i.latency), i.observationState, i.measurementStatus.fineOrCoarseVelocity)
|
||||
glonass_freq = (i.glonassFrequencyIndex - 7) if constellation_id == ConstellationId.GLONASS else np.nan
|
||||
measurements.append(GNSSMeasurement(constellation_id, sv_id,
|
||||
recv_time.week,
|
||||
|
||||
+3
-3
@@ -11,7 +11,7 @@
|
||||
|
||||
import datetime
|
||||
import numpy as np
|
||||
|
||||
import logging
|
||||
|
||||
def floatornan(x):
|
||||
if x == '' or x[-1] == ' ':
|
||||
@@ -49,10 +49,10 @@ class RINEXFile:
|
||||
self._read_header(f)
|
||||
self._read_data(f)
|
||||
except TypeError:
|
||||
print("TypeError, file likely not downloaded.")
|
||||
logging.exception("TypeError, file likely not downloaded.")
|
||||
raise DownloadError("file download failure")
|
||||
except FileNotFoundError:
|
||||
print("File not found in directory.")
|
||||
logging.exception("File not found in directory.")
|
||||
raise DownloadError("file missing in download cache")
|
||||
def _read_header(self, f):
|
||||
version_line = padline(f.readline(), 80)
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ export OPENBLAS_NUM_THREADS=1
|
||||
export VECLIB_MAXIMUM_THREADS=1
|
||||
|
||||
if [ -z "$AGNOS_VERSION" ]; then
|
||||
export AGNOS_VERSION="6.2"
|
||||
export AGNOS_VERSION="7.1"
|
||||
fi
|
||||
|
||||
if [ -z "$PASSIVE" ]; then
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
.sconsign.dblite
|
||||
|
||||
can/*.so
|
||||
can/*.a
|
||||
can/build/
|
||||
can/obj/
|
||||
can/packer_pyx.cpp
|
||||
|
||||
@@ -255,7 +255,7 @@ BO_ 829 LKAS_HUD: 5 ADAS
|
||||
SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ BOH_2 : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_ON : 28|1@0+ (1,0) [0|1] "" BDY
|
||||
|
||||
@@ -255,7 +255,7 @@ BO_ 829 LKAS_HUD: 5 ADAS
|
||||
SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ BOH_2 : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_ON : 28|1@0+ (1,0) [0|1] "" BDY
|
||||
|
||||
@@ -357,7 +357,7 @@ BO_ 13274 LKAS_HUD_A: 5 ADAS
|
||||
SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ BOH_2 : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY
|
||||
SG_ SET_ME_X01 : 20|1@0+ (1,0) [0|1] "" BDY
|
||||
@@ -378,7 +378,7 @@ BO_ 13275 LKAS_HUD_B: 8 ADAS
|
||||
SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ BOH_2 : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY
|
||||
SG_ SET_ME_X01 : 20|1@0+ (1,0) [0|1] "" BDY
|
||||
@@ -436,7 +436,7 @@ BO_ 829 LKAS_HUD: 5 ADAS
|
||||
SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ BOH_2 : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_ON : 28|1@0+ (1,0) [0|1] "" BDY
|
||||
|
||||
@@ -5,7 +5,14 @@ import os
|
||||
envDBC = env.Clone()
|
||||
dbc_file_path = '-DDBC_FILE_PATH=\'"%s"\'' % (envDBC.Dir("..").abspath)
|
||||
envDBC['CXXFLAGS'] += [dbc_file_path]
|
||||
libdbc = envDBC.SharedLibrary('libdbc', ["dbc.cc", "parser.cc", "packer.cc", "common.cc"], LIBS=[common, "capnp", "kj", "zmq"])
|
||||
src = ["dbc.cc", "parser.cc", "packer.cc", "common.cc"]
|
||||
libs = [common, "capnp", "kj", "zmq"]
|
||||
|
||||
# shared library for openpilot
|
||||
libdbc = envDBC.SharedLibrary('libdbc', src, LIBS=libs)
|
||||
|
||||
# static library for tools like cabana
|
||||
envDBC.Library('libdbc_static', src, LIBS=libs)
|
||||
|
||||
# Build packer and parser
|
||||
lenv = envCython.Clone()
|
||||
|
||||
@@ -37,6 +37,7 @@ unsigned int pedal_checksum(uint32_t address, const Signal &sig, const std::vect
|
||||
|
||||
class MessageState {
|
||||
public:
|
||||
std::string name;
|
||||
uint32_t address;
|
||||
unsigned int size;
|
||||
|
||||
@@ -80,11 +81,12 @@ public:
|
||||
CANParser(int abus, const std::string& dbc_name, bool ignore_checksum, bool ignore_counter);
|
||||
#ifndef DYNAMIC_CAPNP
|
||||
void update_string(const std::string &data, bool sendcan);
|
||||
void update_strings(const std::vector<std::string> &data, std::vector<SignalValue> &vals, bool sendcan);
|
||||
void UpdateCans(uint64_t sec, const capnp::List<cereal::CanData>::Reader& cans);
|
||||
#endif
|
||||
void UpdateCans(uint64_t sec, const capnp::DynamicStruct::Reader& cans);
|
||||
void UpdateValid(uint64_t sec);
|
||||
std::vector<SignalValue> query_latest();
|
||||
void query_latest(std::vector<SignalValue> &vals, uint64_t last_ts = 0);
|
||||
};
|
||||
|
||||
class CANPacker {
|
||||
|
||||
@@ -78,9 +78,8 @@ cdef extern from "common.h":
|
||||
bool can_valid
|
||||
bool bus_timeout
|
||||
CANParser(int, string, vector[MessageParseOptions], vector[SignalParseOptions])
|
||||
void update_string(string, bool)
|
||||
vector[SignalValue] query_latest()
|
||||
void update_strings(vector[string]&, vector[SignalValue]&, bool)
|
||||
|
||||
cdef cppclass CANPacker:
|
||||
CANPacker(string)
|
||||
vector[uint8_t] pack(uint32_t, vector[SignalPackValue])
|
||||
vector[uint8_t] pack(uint32_t, vector[SignalPackValue]&)
|
||||
|
||||
@@ -84,6 +84,6 @@ typedef struct ChecksumState {
|
||||
} ChecksumState;
|
||||
|
||||
DBC* dbc_parse(const std::string& dbc_path);
|
||||
DBC* dbc_parse_from_stream(const std::string &dbc_name, std::istream &stream, ChecksumState *checksum = nullptr);
|
||||
DBC* dbc_parse_from_stream(const std::string &dbc_name, std::istream &stream, ChecksumState *checksum = nullptr, bool allow_duplicate_msg_name=false);
|
||||
const DBC* dbc_lookup(const std::string& dbc_name);
|
||||
std::vector<std::string> get_dbc_names();
|
||||
|
||||
+11
-3
@@ -98,10 +98,11 @@ void set_signal_type(Signal& s, ChecksumState* chk, const std::string& dbc_name,
|
||||
}
|
||||
}
|
||||
|
||||
DBC* dbc_parse_from_stream(const std::string &dbc_name, std::istream &stream, ChecksumState *checksum) {
|
||||
DBC* dbc_parse_from_stream(const std::string &dbc_name, std::istream &stream, ChecksumState *checksum, bool allow_duplicate_msg_name) {
|
||||
uint32_t address = 0;
|
||||
std::set<uint32_t> address_set;
|
||||
std::set<std::string> msg_name_set;
|
||||
std::map<uint32_t, std::set<std::string>> signal_name_sets;
|
||||
std::map<uint32_t, std::vector<Signal>> signals;
|
||||
DBC* dbc = new DBC;
|
||||
dbc->name = dbc_name;
|
||||
@@ -134,8 +135,11 @@ DBC* dbc_parse_from_stream(const std::string &dbc_name, std::istream &stream, Ch
|
||||
// check for duplicates
|
||||
DBC_ASSERT(address_set.find(address) == address_set.end(), "Duplicate message address: " << address << " (" << msg.name << ")");
|
||||
address_set.insert(address);
|
||||
DBC_ASSERT(msg_name_set.find(msg.name) == msg_name_set.end(), "Duplicate message name: " << msg.name);
|
||||
msg_name_set.insert(msg.name);
|
||||
|
||||
if (!allow_duplicate_msg_name) {
|
||||
DBC_ASSERT(msg_name_set.find(msg.name) == msg_name_set.end(), "Duplicate message name: " << msg.name);
|
||||
msg_name_set.insert(msg.name);
|
||||
}
|
||||
} else if (startswith(line, "SG_ ")) {
|
||||
// new signal
|
||||
int offset = 0;
|
||||
@@ -162,6 +166,10 @@ DBC* dbc_parse_from_stream(const std::string &dbc_name, std::istream &stream, Ch
|
||||
sig.msb = sig.start_bit;
|
||||
}
|
||||
DBC_ASSERT(sig.lsb < (64 * 8) && sig.msb < (64 * 8), "Signal out of bounds: " << line);
|
||||
|
||||
// Check for duplicate signal names
|
||||
DBC_ASSERT(signal_name_sets[address].find(sig.name) == signal_name_sets[address].end(), "Duplicate signal name: " << sig.name);
|
||||
signal_name_sets[address].insert(sig.name);
|
||||
} else if (startswith(line, "VAL_ ")) {
|
||||
// new signal value/definition
|
||||
bool ret = std::regex_search(line, match, val_regexp);
|
||||
|
||||
+30
-18
@@ -33,7 +33,7 @@ int64_t get_raw_value(const std::vector<uint8_t> &msg, const Signal &sig) {
|
||||
|
||||
bool MessageState::parse(uint64_t sec, const std::vector<uint8_t> &dat) {
|
||||
for (int i = 0; i < parse_sigs.size(); i++) {
|
||||
auto &sig = parse_sigs[i];
|
||||
const auto &sig = parse_sigs[i];
|
||||
|
||||
int64_t tmp = get_raw_value(dat, sig);
|
||||
if (sig.is_signed) {
|
||||
@@ -124,6 +124,7 @@ CANParser::CANParser(int abus, const std::string& dbc_name,
|
||||
assert(false);
|
||||
}
|
||||
|
||||
state.name = msg->name;
|
||||
state.size = msg->size;
|
||||
assert(state.size <= 64); // max signal size is 64 bytes
|
||||
|
||||
@@ -162,6 +163,7 @@ CANParser::CANParser(int abus, const std::string& dbc_name, bool ignore_checksum
|
||||
|
||||
for (const auto& msg : dbc->msgs) {
|
||||
MessageState state = {
|
||||
.name = msg.name,
|
||||
.address = msg.address,
|
||||
.size = msg.size,
|
||||
.ignore_checksum = ignore_checksum,
|
||||
@@ -202,14 +204,24 @@ void CANParser::update_string(const std::string &data, bool sendcan) {
|
||||
UpdateValid(last_sec);
|
||||
}
|
||||
|
||||
void CANParser::update_strings(const std::vector<std::string> &data, std::vector<SignalValue> &vals, bool sendcan) {
|
||||
uint64_t current_sec = 0;
|
||||
for (const auto &d : data) {
|
||||
update_string(d, sendcan);
|
||||
if (current_sec == 0) {
|
||||
current_sec = last_sec;
|
||||
}
|
||||
}
|
||||
query_latest(vals, current_sec);
|
||||
}
|
||||
|
||||
void CANParser::UpdateCans(uint64_t sec, const capnp::List<cereal::CanData>::Reader& cans) {
|
||||
//DEBUG("got %d messages\n", cans.size());
|
||||
|
||||
bool bus_empty = true;
|
||||
|
||||
// parse the messages
|
||||
for (int i = 0; i < cans.size(); i++) {
|
||||
auto cmsg = cans[i];
|
||||
for (const auto cmsg : cans) {
|
||||
if (cmsg.getSrc() != bus) {
|
||||
// DEBUG("skip %d: wrong bus\n", cmsg.getAddress());
|
||||
continue;
|
||||
@@ -287,9 +299,9 @@ void CANParser::UpdateValid(uint64_t sec) {
|
||||
if (state.check_threshold > 0 && (missing || timed_out)) {
|
||||
if (show_missing && !bus_timeout) {
|
||||
if (missing) {
|
||||
LOGE("0x%X NOT SEEN", state.address);
|
||||
LOGE("0x%X '%s' NOT SEEN", state.address, state.name.c_str());
|
||||
} else if (timed_out) {
|
||||
LOGE("0x%X TIMED OUT", state.address);
|
||||
LOGE("0x%X '%s' TIMED OUT", state.address, state.name.c_str());
|
||||
}
|
||||
}
|
||||
_valid = false;
|
||||
@@ -299,25 +311,25 @@ void CANParser::UpdateValid(uint64_t sec) {
|
||||
can_valid = (can_invalid_cnt < CAN_INVALID_CNT) && _counters_valid;
|
||||
}
|
||||
|
||||
std::vector<SignalValue> CANParser::query_latest() {
|
||||
std::vector<SignalValue> ret;
|
||||
|
||||
void CANParser::query_latest(std::vector<SignalValue> &vals, uint64_t last_ts) {
|
||||
if (last_ts == 0) {
|
||||
last_ts = last_sec;
|
||||
}
|
||||
for (auto& kv : message_states) {
|
||||
auto& state = kv.second;
|
||||
if (last_sec != 0 && state.last_seen_nanos != last_sec) continue;
|
||||
if (last_ts != 0 && state.last_seen_nanos < last_ts) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < state.parse_sigs.size(); i++) {
|
||||
const Signal &sig = state.parse_sigs[i];
|
||||
ret.push_back((SignalValue){
|
||||
.address = state.address,
|
||||
.ts_nanos = state.last_seen_nanos,
|
||||
.name = sig.name,
|
||||
.value = state.vals[i],
|
||||
.all_values = state.all_vals[i],
|
||||
});
|
||||
SignalValue &v = vals.emplace_back();
|
||||
v.address = state.address;
|
||||
v.ts_nanos = state.last_seen_nanos;
|
||||
v.name = sig.name;
|
||||
v.value = state.vals[i];
|
||||
v.all_values = state.all_vals[i];
|
||||
state.all_vals[i].clear();
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
+21
-28
@@ -1,6 +1,7 @@
|
||||
# distutils: language = c++
|
||||
# cython: c_string_encoding=ascii, language_level=3
|
||||
|
||||
from cython.operator cimport dereference as deref, preincrement as preinc
|
||||
from libcpp.string cimport string
|
||||
from libcpp.vector cimport vector
|
||||
from libcpp.unordered_set cimport unordered_set
|
||||
@@ -51,7 +52,7 @@ cdef class CANParser:
|
||||
self.address_to_msg_name[msg.address] = name
|
||||
self.vl[msg.address] = {}
|
||||
self.vl[name] = self.vl[msg.address]
|
||||
self.vl_all[msg.address] = defaultdict(list)
|
||||
self.vl_all[msg.address] = {}
|
||||
self.vl_all[name] = self.vl_all[msg.address]
|
||||
self.ts_nanos[msg.address] = {}
|
||||
self.ts_nanos[name] = self.ts_nanos[msg.address]
|
||||
@@ -101,37 +102,29 @@ cdef class CANParser:
|
||||
message_options_v.push_back(mpo)
|
||||
|
||||
self.can = new cpp_CANParser(bus, dbc_name, message_options_v, signal_options_v)
|
||||
self.update_vl()
|
||||
|
||||
cdef unordered_set[uint32_t] update_vl(self):
|
||||
cdef unordered_set[uint32_t] updated_addrs
|
||||
|
||||
new_vals = self.can.query_latest()
|
||||
for cv in new_vals:
|
||||
# Cast char * directly to unicode
|
||||
cv_name = <unicode>cv.name
|
||||
self.vl[cv.address][cv_name] = cv.value
|
||||
self.vl_all[cv.address][cv_name].extend(cv.all_values)
|
||||
self.ts_nanos[cv.address][cv_name] = cv.ts_nanos
|
||||
updated_addrs.insert(cv.address)
|
||||
|
||||
return updated_addrs
|
||||
|
||||
def update_string(self, dat, sendcan=False):
|
||||
for v in self.vl_all.values():
|
||||
v.clear()
|
||||
|
||||
self.can.update_string(dat, sendcan)
|
||||
return self.update_vl()
|
||||
self.update_strings([])
|
||||
|
||||
def update_strings(self, strings, sendcan=False):
|
||||
for v in self.vl_all.values():
|
||||
v.clear()
|
||||
for l in v.values():
|
||||
l.clear()
|
||||
|
||||
cdef vector[SignalValue] new_vals
|
||||
cdef unordered_set[uint32_t] updated_addrs
|
||||
|
||||
self.can.update_strings(strings, new_vals, sendcan)
|
||||
cdef vector[SignalValue].iterator it = new_vals.begin()
|
||||
cdef SignalValue* cv
|
||||
while it != new_vals.end():
|
||||
cv = &deref(it)
|
||||
# Cast char * directly to unicode
|
||||
cv_name = <unicode>cv.name
|
||||
self.vl[cv.address][cv_name] = cv.value
|
||||
self.vl_all[cv.address][cv_name] = cv.all_values
|
||||
self.ts_nanos[cv.address][cv_name] = cv.ts_nanos
|
||||
updated_addrs.insert(cv.address)
|
||||
preinc(it)
|
||||
|
||||
updated_addrs = set()
|
||||
for s in strings:
|
||||
self.can.update_string(s, sendcan)
|
||||
updated_addrs.update(self.update_vl())
|
||||
return updated_addrs
|
||||
|
||||
@property
|
||||
|
||||
@@ -263,6 +263,11 @@ BO_ 880 ASCMActiveCruiseControlStatus: 6 K124_ASCM
|
||||
SG_ ACCCmdActive : 23|1@0+ (1,0) [0|0] "" NEO
|
||||
SG_ FCWAlert : 41|2@0+ (1,0) [0|3] "" XXX
|
||||
|
||||
BO_ 967 EVDriveMode: 4 XXX
|
||||
SG_ SinglePedalModeActive : 7|1@0+ (1,0) [0|1] "" XXX
|
||||
SG_ SinglePedalModeRisingEdge : 21|1@0+ (1,0) [0|1] "" XXX
|
||||
SG_ SinglePedalModeFallingEdge : 22|1@0+ (1,0) [0|1] "" XXX
|
||||
|
||||
BO_ 977 ECMCruiseControl: 8 K20_ECM
|
||||
SG_ CruiseActive : 39|1@0+ (1,0) [0|3] "" NEO
|
||||
SG_ CruiseSetSpeed : 19|12@0+ (0.0625,0) [0|0] "km/h" NEO
|
||||
|
||||
@@ -357,7 +357,7 @@ BO_ 13274 LKAS_HUD_A: 5 ADAS
|
||||
SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ BOH_2 : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY
|
||||
SG_ SET_ME_X01 : 20|1@0+ (1,0) [0|1] "" BDY
|
||||
@@ -378,7 +378,7 @@ BO_ 13275 LKAS_HUD_B: 8 ADAS
|
||||
SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ BOH_2 : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY
|
||||
SG_ SET_ME_X01 : 20|1@0+ (1,0) [0|1] "" BDY
|
||||
@@ -436,7 +436,7 @@ BO_ 829 LKAS_HUD: 5 ADAS
|
||||
SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ BOH_2 : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_ON : 28|1@0+ (1,0) [0|1] "" BDY
|
||||
|
||||
@@ -375,7 +375,7 @@ BO_ 13274 LKAS_HUD_A: 5 ADAS
|
||||
SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ BOH_2 : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY
|
||||
SG_ SET_ME_X01 : 20|1@0+ (1,0) [0|1] "" BDY
|
||||
@@ -396,7 +396,7 @@ BO_ 13275 LKAS_HUD_B: 8 ADAS
|
||||
SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ BOH_2 : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY
|
||||
SG_ SET_ME_X01 : 20|1@0+ (1,0) [0|1] "" BDY
|
||||
@@ -445,6 +445,12 @@ BO_ 432 STANDSTILL: 7 VSA
|
||||
SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON
|
||||
SG_ CHECKSUM : 51|4@0+ (1,0) [0|15] "" EON
|
||||
|
||||
BO_ 446 BRAKE_MODULE: 3 VSA
|
||||
SG_ BRAKE_PRESSED : 4|1@0+ (1,0) [0|1] "" XXX
|
||||
SG_ CRUISE_FAULT : 22|1@0+ (1,0) [0|1] "" XXX
|
||||
SG_ COUNTER : 21|2@0+ (1,0) [0|3] "" XXX
|
||||
SG_ CHECKSUM : 19|4@0+ (1,0) [0|15] "" XXX
|
||||
|
||||
BO_ 456 ACC_CONTROL: 8 XXX
|
||||
SG_ ACCEL_COMMAND : 7|12@0- (0.01,0) [0|0] "m/s^2" XXX
|
||||
SG_ IDLESTOP_ALLOW : 8|1@0+ (1,0) [0|1] "" XXX
|
||||
@@ -459,6 +465,11 @@ BO_ 456 ACC_CONTROL: 8 XXX
|
||||
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX
|
||||
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX
|
||||
|
||||
BO_ 467 CRUISE_FAULT_STATUS: 8 XXX
|
||||
SG_ CRUISE_FAULT : 3|1@0+ (1,0) [0|1] "" XXX
|
||||
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX
|
||||
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX
|
||||
|
||||
BO_ 829 LKAS_HUD: 8 ADAS
|
||||
SG_ CAM_TEMP_HIGH : 7|1@0+ (1,0) [0|255] "" BDY
|
||||
SG_ SET_ME_X41 : 6|7@0+ (1,0) [0|127] "" BDY
|
||||
@@ -470,7 +481,7 @@ BO_ 829 LKAS_HUD: 8 ADAS
|
||||
SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ BOH_2 : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_ON : 28|1@0+ (1,0) [0|1] "" BDY
|
||||
@@ -496,6 +507,7 @@ BO_ 254913108 LKAS_HUD_2: 8 ADAS
|
||||
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX
|
||||
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX
|
||||
|
||||
CM_ 446 "If exists, describes cruise faults and what the PCM uses for brake press detection.";
|
||||
CM_ SG_ 456 IDLESTOP_ALLOW "allows car to turn off engine at a standstill";
|
||||
CM_ SG_ 456 STANDSTILL "set to 1 when camera requests -4.0 m/s^2";
|
||||
|
||||
|
||||
@@ -357,7 +357,7 @@ BO_ 13274 LKAS_HUD_A: 5 ADAS
|
||||
SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ BOH_2 : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY
|
||||
SG_ SET_ME_X01 : 20|1@0+ (1,0) [0|1] "" BDY
|
||||
@@ -378,7 +378,7 @@ BO_ 13275 LKAS_HUD_B: 8 ADAS
|
||||
SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ BOH_2 : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY
|
||||
SG_ SET_ME_X01 : 20|1@0+ (1,0) [0|1] "" BDY
|
||||
@@ -436,7 +436,7 @@ BO_ 829 LKAS_HUD: 5 ADAS
|
||||
SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ BOH_2 : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_ON : 28|1@0+ (1,0) [0|1] "" BDY
|
||||
|
||||
@@ -255,7 +255,7 @@ BO_ 829 LKAS_HUD: 5 ADAS
|
||||
SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ BOH_2 : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_ON : 28|1@0+ (1,0) [0|1] "" BDY
|
||||
|
||||
@@ -357,7 +357,7 @@ BO_ 13274 LKAS_HUD_A: 5 ADAS
|
||||
SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ BOH_2 : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY
|
||||
SG_ SET_ME_X01 : 20|1@0+ (1,0) [0|1] "" BDY
|
||||
@@ -378,7 +378,7 @@ BO_ 13275 LKAS_HUD_B: 8 ADAS
|
||||
SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ BOH_2 : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY
|
||||
SG_ SET_ME_X01 : 20|1@0+ (1,0) [0|1] "" BDY
|
||||
@@ -436,7 +436,7 @@ BO_ 829 LKAS_HUD: 5 ADAS
|
||||
SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ BOH_2 : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_ON : 28|1@0+ (1,0) [0|1] "" BDY
|
||||
|
||||
@@ -255,7 +255,7 @@ BO_ 829 LKAS_HUD: 5 ADAS
|
||||
SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ BOH_2 : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_ON : 28|1@0+ (1,0) [0|1] "" BDY
|
||||
@@ -306,7 +306,7 @@ BO_ 404 STEERING_CONTROL: 4 EON
|
||||
SG_ STEER_TORQUE : 7|12@0- (1,0) [-768|768] "" EPS
|
||||
SG_ SET_ME_X00 : 11|4@0+ (1,0) [0|15] "" EPS
|
||||
SG_ STEER_TORQUE_REQUEST : 23|1@0+ (1,0) [0|1] "" EPS
|
||||
SG_ SET_ME_X00 : 22|7@0+ (1,0) [0|127] "" EPS
|
||||
SG_ SET_ME_X00_2 : 22|7@0+ (1,0) [0|127] "" EPS
|
||||
SG_ COUNTER : 29|2@0+ (1,0) [0|15] "" EPS
|
||||
SG_ CHECKSUM : 27|4@0+ (1,0) [0|3] "" EPS
|
||||
|
||||
|
||||
@@ -255,7 +255,7 @@ BO_ 829 LKAS_HUD: 5 ADAS
|
||||
SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ BOH_2 : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_ON : 28|1@0+ (1,0) [0|1] "" BDY
|
||||
@@ -308,7 +308,7 @@ BO_ 404 STEERING_CONTROL: 4 EON
|
||||
SG_ STEER_TORQUE : 7|12@0- (1,0) [-768|768] "" EPS
|
||||
SG_ SET_ME_X00 : 11|4@0+ (1,0) [0|15] "" EPS
|
||||
SG_ STEER_TORQUE_REQUEST : 23|1@0+ (1,0) [0|1] "" EPS
|
||||
SG_ SET_ME_X00 : 22|7@0+ (1,0) [0|127] "" EPS
|
||||
SG_ SET_ME_X00_2 : 22|7@0+ (1,0) [0|127] "" EPS
|
||||
SG_ COUNTER : 29|2@0+ (1,0) [0|15] "" EPS
|
||||
SG_ CHECKSUM : 27|4@0+ (1,0) [0|3] "" EPS
|
||||
|
||||
|
||||
@@ -255,7 +255,7 @@ BO_ 829 LKAS_HUD: 5 ADAS
|
||||
SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ BOH_2 : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_ON : 28|1@0+ (1,0) [0|1] "" BDY
|
||||
|
||||
@@ -357,7 +357,7 @@ BO_ 13274 LKAS_HUD_A: 5 ADAS
|
||||
SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ BOH_2 : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY
|
||||
SG_ SET_ME_X01 : 20|1@0+ (1,0) [0|1] "" BDY
|
||||
@@ -378,7 +378,7 @@ BO_ 13275 LKAS_HUD_B: 8 ADAS
|
||||
SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ BOH_2 : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY
|
||||
SG_ SET_ME_X01 : 20|1@0+ (1,0) [0|1] "" BDY
|
||||
@@ -436,7 +436,7 @@ BO_ 829 LKAS_HUD: 5 ADAS
|
||||
SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ BOH_2 : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_ON : 28|1@0+ (1,0) [0|1] "" BDY
|
||||
|
||||
@@ -255,7 +255,7 @@ BO_ 829 LKAS_HUD: 5 ADAS
|
||||
SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ BOH_2 : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_ON : 28|1@0+ (1,0) [0|1] "" BDY
|
||||
|
||||
@@ -255,7 +255,7 @@ BO_ 829 LKAS_HUD: 5 ADAS
|
||||
SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ BOH_2 : 23|2@0+ (1,0) [0|4] "" BDY
|
||||
SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY
|
||||
SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY
|
||||
SG_ LDW_ON : 28|1@0+ (1,0) [0|1] "" BDY
|
||||
|
||||
@@ -316,10 +316,22 @@ BO_ 576 CruiseControl: 8 XXX
|
||||
SG_ Cruise_Activated : 41|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ Signal2 : 42|22@1+ (1,0) [0|4194303] "" XXX
|
||||
|
||||
BO_ 803 INFOTAINMENT_STATUS: 8 XXX
|
||||
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" XXX
|
||||
SG_ LKAS_Blue_Lines : 15|4@0+ (1,0) [0|15] "" XXX
|
||||
SG_ Signal1 : 19|4@0+ (1,0) [0|15] "" XXX
|
||||
SG_ LKAS_State_Infotainment : 22|3@0+ (1,0) [0|7] "" XXX
|
||||
SG_ Signal2 : 24|1@0+ (1,0) [0|1] "" XXX
|
||||
|
||||
CM_ SG_ 545 Cruise_Throttle "RPM-like output signal";
|
||||
CM_ SG_ 545 Cruise_EPB "1 = Electric Parking Brake set";
|
||||
CM_ SG_ 545 Distance_Swap "Switch from Close to Far distance";
|
||||
CM_ SG_ 545 Cruise_Soft_Disable "Eyesight Temporary disable, sets CruiseControl Activated = 0";
|
||||
CM_ SG_ 546 Cruise_RPM "ES RPM output for ECM and TCM";
|
||||
CM_ SG_ 546 Signal3 "0 when cruise_activated = 1";
|
||||
CM_ SG_ 803 Signal1 "Seems to be static, set only on some cars";
|
||||
CM_ SG_ 803 Signal2 "Seems to be static, set only on some cars";
|
||||
VAL_ 803 LKAS_Blue_Lines 0 "no modifier" 2 "changes lines to blue";
|
||||
VAL_ 803 LKAS_State_Infotainment 0 "none" 2 "Obstacle Detected" 3 "Keep Hands On Wheel" 4 "Keep Hands On Wheel Off";
|
||||
VAL_ 72 Gear 2 "N" 3 "R" 4 "P" 121 "D" 137 "1" 145 "2" 153 "3" 161 "4" 169 "5" 177 "6";
|
||||
|
||||
@@ -127,6 +127,7 @@ BO_ 466 PCM_CRUISE: 8 XXX
|
||||
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
|
||||
|
||||
BO_ 467 PCM_CRUISE_2: 8 XXX
|
||||
SG_ BRAKE_PRESSED : 3|1@0+ (1,0) [0|1] "" XXX
|
||||
SG_ PCM_FOLLOW_DISTANCE : 12|2@0+ (1,0) [0|3] "" XXX
|
||||
SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "" XXX
|
||||
SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX
|
||||
@@ -547,6 +548,9 @@ BO_ 610 EPS_STATUS: 5 EPS
|
||||
SG_ TYPE : 24|1@0+ (1,0) [0|1] "" XXX
|
||||
SG_ CHECKSUM : 39|8@0+ (1,0) [0|255] "" XXX
|
||||
|
||||
BO_ 1178 BRAKE_RELATED: 8 XXX
|
||||
SG_ BRAKE_PRESSED : 48|1@0+ (1,0) [0|1] "" XXX
|
||||
|
||||
CM_ SG_ 548 BRAKE_PRESSURE "seems prop to pedal force";
|
||||
CM_ SG_ 548 BRAKE_POSITION "seems proportional to pedal displacement, unclear the max value of 0x1c8";
|
||||
CM_ SG_ 610 TYPE "seems 1 on Corolla, 0 on all others";
|
||||
|
||||
@@ -127,6 +127,7 @@ BO_ 466 PCM_CRUISE: 8 XXX
|
||||
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
|
||||
|
||||
BO_ 467 PCM_CRUISE_2: 8 XXX
|
||||
SG_ BRAKE_PRESSED : 3|1@0+ (1,0) [0|1] "" XXX
|
||||
SG_ PCM_FOLLOW_DISTANCE : 12|2@0+ (1,0) [0|3] "" XXX
|
||||
SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "" XXX
|
||||
SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX
|
||||
|
||||
@@ -127,6 +127,7 @@ BO_ 466 PCM_CRUISE: 8 XXX
|
||||
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
|
||||
|
||||
BO_ 467 PCM_CRUISE_2: 8 XXX
|
||||
SG_ BRAKE_PRESSED : 3|1@0+ (1,0) [0|1] "" XXX
|
||||
SG_ PCM_FOLLOW_DISTANCE : 12|2@0+ (1,0) [0|3] "" XXX
|
||||
SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "" XXX
|
||||
SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX
|
||||
|
||||
+67
-23
@@ -770,23 +770,36 @@ BO_ 1340 Fahrwerk_1: 1 XXX
|
||||
SG_ Ansteuererung_Fahrzeugniveau : 0|4@1+ (1,0) [0|15] "" XXX
|
||||
|
||||
BO_ 1472 EPB_1: 8 XXX
|
||||
SG_ Textmeldungen_EPB : 52|4@1+ (1,0) [0|0] "" XXX
|
||||
SG_ Aufmerksamkeits_Gtong_EPB : 51|1@1+ (1,0) [0|0] "" XXX
|
||||
SG_ Fehler_Gong_EBP : 50|1@1+ (1,0) [0|0] "" XXX
|
||||
SG_ Warnton_EPB : 49|1@1+ (1,0) [0|0] "" XXX
|
||||
SG_ Funktionslampe_EPB : 48|1@1+ (1,0) [0|0] "" XXX
|
||||
SG_ Frei_EPB_1_1 : 33|15@1+ (1,0) [0|0] "" XXX
|
||||
SG_ Fehlerspeichereintrag_EPB : 32|1@1+ (1,0) [0|0] "" XXX
|
||||
SG_ Neigungswinkel : 24|8@1+ (1,-128) [-128|127] "g" XXX
|
||||
SG_ Verzoegerungsanforderung__EPB_ : 24|8@1+ (0.5,0) [0|255] "g" XXX
|
||||
SG_ Status_Neigungswinkelgeber : 15|1@1+ (1,0) [0|0] "" XXX
|
||||
SG_ Schalterinfo_Parkbremse : 13|2@1+ (1,0) [0|0] "" XXX
|
||||
SG_ Erreichte_Spannkraft : 8|5@1+ (1,0) [0|30] "kN" XXX
|
||||
SG_ Checksumme_Parkbremse : 8|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ Schalterstatus_Parkbremse : 7|1@1+ (1,0) [0|0] "" XXX
|
||||
SG_ Status_Parkbremse : 6|1@1+ (1,0) [0|0] "" XXX
|
||||
SG_ Fehlerstatus_Parkbremse : 4|2@1+ (1,0) [0|0] "" XXX
|
||||
SG_ Zaehler_Parkbremse : 0|4@1+ (1,0) [0|0] "" XXX
|
||||
SG_ CHECKSUM : 56|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ COUNTER : 0|4@1+ (1,0) [0|15] "" XXX
|
||||
SG_ EP1__Text : 52|4@1+ (1,0) [0|8] "" Vector__XXX
|
||||
SG_ EP1_Failure_gelb : 51|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ EP1_Failure_BKL : 50|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ EP1_Warnton : 49|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ EP1_Fkt_Lampe : 48|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ EP1_Freigabe_Ver : 33|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ EP1_Failureeintr : 32|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ EP1_Neig_winkel : 16|8@1+ (1,-128) [-128|127] "g" XXX
|
||||
SG_ EP1_Verzoegerung : 24|8@1+ (0.048,-7.968) [-7.968|4.224] "g" XXX
|
||||
SG_ EP1_Sta_NWS : 15|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ EP1_Schalterinfo : 13|2@1+ (1,0) [0|3] "" XXX
|
||||
SG_ EP1_Spannkraft : 8|5@1+ (1,0) [0|30] "kN" XXX
|
||||
SG_ EP1_Sta_Schalter : 7|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ EP1_Sta_EPB : 6|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ EP1_Failure_Sta : 4|2@1+ (1,0) [0|3] "" XXX
|
||||
SG_ EP1_AutoHold_zul : 34|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ EP1_AutoHold_active : 35|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ EP1_SleepInd : 36|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ EP1_Status_Kl_15 : 37|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ EP1_Lampe_AutoP : 38|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ EP1_Bremslicht : 39|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ EP1_Warnton1 : 40|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ EP1_Warnton2 : 41|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ EP1_AnfShLock : 42|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ EPB_Autoholdlampe : 43|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ EP1_KuppModBer : 45|2@1+ (1,0) [0|3] "" XXX
|
||||
SG_ EP1_HydrHalten : 47|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ EP1_QualNeigWi : 44|1@1+ (1,0) [0|1] "" XXX
|
||||
|
||||
BO_ 1326 Diag_Lenkhilfe: 3 XXX
|
||||
SG_ Werkstattcode__Diag_ : 16|8@1+ (1,0) [0|0] "" XXX
|
||||
@@ -1086,10 +1099,10 @@ BO_ 872 ACC_System: 8 XXX
|
||||
SG_ ACS_Sollbeschl : 24|11@1+ (0.005,-7.22) [-7.22|3.005] "Unit_MeterPerSeconSquar" XXX
|
||||
SG_ ACS_Anhaltewunsch : 38|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ ACS_Fehler : 39|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ ACS_zul_Regelabw : 40|8@1+ (1,0.005) [0|1.265] "Unit_MeterPerSeconSquar" XXX
|
||||
SG_ ACS_max_AendGrad : 48|8@1+ (1,0.02) [0.02|5.06] "Unit_MeterPerSeconSquar" XXX
|
||||
SG_ ACS_zul_Regelabw : 40|8@1+ (0.005,0) [0|1.265] "Unit_MeterPerSeconSquar" XXX
|
||||
SG_ ACS_max_AendGrad : 48|8@1+ (0.02,0) [0.02|5.06] "Unit_MeterPerSeconSquar" XXX
|
||||
|
||||
BO_ 1386 ACC_GRA_Anziege: 8 XXX
|
||||
BO_ 1386 ACC_GRA_Anzeige: 8 XXX
|
||||
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ ACA_StaACC : 8|3@1+ (1,0) [0|7] "" XXX
|
||||
SG_ ACA_ID_StaACC : 11|5@1+ (1,0) [0|31] "" XXX
|
||||
@@ -1100,7 +1113,7 @@ BO_ 1386 ACC_GRA_Anziege: 8 XXX
|
||||
SG_ ACA_kmh_mph : 32|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ ACA_Akustik1 : 33|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ ACA_Akustik2 : 34|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ ACA_PrioDisp : 35|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ ACA_PrioDisp : 35|2@1+ (1,0) [0|3] "" XXX
|
||||
SG_ ACA_gemZeitl : 40|4@1+ (1,0) [0|15] "" XXX
|
||||
SG_ ACA_ACC_Verz : 44|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ ACA_StaGRA : 48|3@1+ (1,0) [0|7] "" XXX
|
||||
@@ -1153,8 +1166,8 @@ BO_ 644 Motor_Bremse: 6 XXX
|
||||
SG_ MOB_COUNTER : 8|4@1+ (1,0) [0|15] "" Bremse_MK25AESP
|
||||
SG_ TSK_v_Begrenzung_aktiv : 15|1@0+ (1,0) [0|1] "" XXX
|
||||
SG_ TSK_ax_Getriebe_01 : 40|8@1+ (0.048,0) [0|255] "m/s2" XXX
|
||||
SG_ MOB_Bremsstgr : 16|11@1+ (0.76,0) [0|100] "Unit_PerCent" Vector__XXX
|
||||
SG_ MOB_Bremsmom : 27|13@1+ (1,0) [0|8190] "Unit_NewtoMeter" Bremse_MK25AESP
|
||||
SG_ MOB_Bremsstgr : 16|11@1+ (0.048852,0) [0|100] "Unit_PerCent" Vector__XXX
|
||||
SG_ MOB_Bremsmom : 27|13@1+ (4,0) [0|32760] "Unit_NewtoMeter" Bremse_MK25AESP
|
||||
|
||||
BO_ 870 AWV: 5 XXX
|
||||
SG_ AWV_2_Gurtstraffer : 39|1@1+ (1,0) [0|1] "" Bremsbooster
|
||||
@@ -1531,5 +1544,36 @@ CM_ SG_ 1470 XX_DLCORTLC2 "Might be DLC or TLC, might have wrong size";
|
||||
CM_ SG_ 1550 MFA_v_Signal_02 "0=km/h, 1=mph";
|
||||
|
||||
|
||||
VAL_ 872 ACS_Sta_ADR 2 "ADR_passiv" 0 "ADR_nicht_aktiv" 1 "ADR_aktiv" 3 "irrev_Fehler" ;
|
||||
VAL_ 872 ACS_ADR_Schub 1 "Verz_begr_auf_Schub" 0 "Verz_nicht_begr_auf_Schub" ;
|
||||
VAL_ 872 ACS_Schubabsch 1 "SA_nicht_zulaessig" 0 "SA_zulaessig" ;
|
||||
VAL_ 872 ACS_StSt_Info 3 "Systemfehler" 0 "Motorlauf_nn" 1 "Stoppverbot_Motoranlauf_nn" 2 "Motoranlauf_notwendig" ;
|
||||
VAL_ 872 ACS_MomEingriff 1 "MomEingr_verhindern" 0 "keine_Beeinfl_MomEingr_Mot" ;
|
||||
VAL_ 872 ACS_Typ_ACC 0 "Basis_ACC" 1 "ACC_mit_FollowToStop" 3 "frei" 2 "frei" ;
|
||||
VAL_ 872 ACS_FreigSollB 0 "Sollbeschl_nicht_freigeg" 1 "Sollbeschl_freigeg" ;
|
||||
VAL_ 872 ACS_Sollbeschl 2046 "ADR_nicht_aktiv" 2047 "Fehler" ;
|
||||
VAL_ 872 ACS_Anhaltewunsch 0 "kein_Haltewunsch" 1 "Fzg_haelt_an" ;
|
||||
VAL_ 872 ACS_Fehler 1 "Fehlerspeichereintrag" 0 "kein_Fehlerspeichereintrag" ;
|
||||
VAL_ 872 ACS_zul_Regelabw 254 "ADR_nicht_aktiv" 255 "Fehler" ;
|
||||
VAL_ 872 ACS_max_AendGrad 254 "Neutralwert" 0 "Neutralwert" 255 "Fehler" ;
|
||||
|
||||
VAL_ 978 LH2_Sta_HCA 0 "disabled" 1 "initializing" 2 "fault" 3 "ready" 4 "rejected" 5 "active";
|
||||
VAL_ 1088 Waehlhebelposition__Getriebe_1_ 8 "P" 7 "R" 6 "N" 5 "D" 9 "U" 12 "S" 14 "T" 10 "T" 11 "T";
|
||||
|
||||
VAL_ 1386 ACA_StaACC 6 "ACC_rev_aus" 0 "Hauptschalter_aus" 4 "ACC_im_Hintergrund" 3 "ACC_aktiv" 1 "Reserve" 2 "ACC_passiv" 7 "ACC_irrev_aus" 5 "frei" ;
|
||||
VAL_ 1386 ACA_ID_StaACC 0 "keine_Anzeige" ;
|
||||
VAL_ 1386 ACA_Fahrerhinw 1 "Ein" 0 "Aus" ;
|
||||
VAL_ 1386 ACA_AnzDisplay 1 "Anzeige_erw" 0 "Anzeige_nicht_erw" ;
|
||||
VAL_ 1386 ACA_Zeitluecke 3 "Zeitluecke3" 10 "Zeitluecke10" 4 "Zeitluecke4" 14 "Zeitluecke14" 11 "Zeitluecke11" 2 "Zeitluecke2" 13 "Zeitluecke13" 9 "Zeitluecke9" 1 "Zeitluecke1" 8 "Zeitluecke8" 5 "Zeitluecke5" 15 "Zeitluecke15" 0 "nicht_definiert" 12 "Zeitluecke12" 6 "Zeitluecke6" 7 "Zeitluecke7" ;
|
||||
VAL_ 1386 ACA_V_Wunsch 255 "kein_Wert_im_Speicher" ;
|
||||
VAL_ 1386 ACA_kmh_mph 0 "km_h" 1 "mph" ;
|
||||
VAL_ 1386 ACA_Akustik1 0 "kein_Gong" 1 "Gong" ;
|
||||
VAL_ 1386 ACA_Akustik2 0 "kein_Summer" 1 "Summer" ;
|
||||
VAL_ 1386 ACA_PrioDisp 1 "mittlere_Prio" 3 "keine_Anzeige_Anf" 0 "hohe_Prio" 2 "niedrige_Prio" ;
|
||||
VAL_ 1386 ACA_gemZeitl 6 "Zeitluecke6" 2 "Zeitluecke2" 7 "Zeitluecke7" 13 "Zeitluecke13" 11 "Zeitluecke11" 4 "Zeitluecke4" 8 "Zeitluecke8" 12 "Zeitluecke12" 10 "Zeitluecke10" 0 "Kein_Objekt_erfasst" 1 "Zeitluecke1" 3 "Zeitluecke3" 9 "Zeitluecke9" 15 "Zeitluecke15" 14 "Zeitluecke14" 5 "Zeitluecke5" ;
|
||||
VAL_ 1386 ACA_ACC_Verz 0 "ACC_verzoegert_nicht" 1 "ACC_verzoegert" ;
|
||||
VAL_ 1386 ACA_StaGRA 3 "GRA_aktiv" 4 "GRA_uebertreten" 2 "GRA_passiv" 0 "Hauptschalter_aus" 6 "frei" 7 "GRA_Fehler" 1 "Reserve" 5 "frei" ;
|
||||
VAL_ 1386 ACA_ID_StaGRA 0 "keine_Anzeige" ;
|
||||
VAL_ 1386 ACA_Codierung 0 "ACC" 1 "GRA" ;
|
||||
VAL_ 1386 ACA_Tachokranz 0 "nicht_beleuchtet" 1 "beleuchtet" ;
|
||||
VAL_ 1386 ACA_Aend_Zeitluecke 1 "Anzeige_angef" 0 "keine_Anzeige" ;
|
||||
|
||||
+30
-18
@@ -1211,18 +1211,19 @@ BO_ 1602 WIV_01: 8 Motor_Diesel_MQB
|
||||
SG_ WIV_W_min : 48|7@1+ (1000,0) [0|127000] "Unit_KiloMeter" Gateway_MQB
|
||||
SG_ WIV_W_max : 56|7@1+ (1000,0) [0|127000] "Unit_KiloMeter" Gateway_MQB
|
||||
|
||||
BO_ 294 HCA_01: 8 XXX
|
||||
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ COUNTER : 8|4@1+ (1,0) [0|255] "" XXX
|
||||
SG_ SET_ME_0X3 : 12|4@1+ (1,0) [0|15] "" XXX
|
||||
SG_ Assist_Torque : 16|14@1+ (1,0) [0|300] "Nm" XXX
|
||||
SG_ Assist_Requested : 30|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ Assist_VZ : 31|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ HCA_Available : 32|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ HCA_Standby : 33|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ HCA_Active : 34|1@1+ (1,0) [0|1] "" XXX
|
||||
SG_ SET_ME_0XFE : 40|8@1+ (1,0) [0|255] "" XXX
|
||||
SG_ SET_ME_0X07 : 48|8@1+ (1,0) [0|255] "" XXX
|
||||
BO_ 294 HCA_01: 8 Frontsensorik
|
||||
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" Vector__XXX
|
||||
SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" Vector__XXX
|
||||
SG_ HCA_01_Vib_Freq : 12|4@1+ (1,15) [15|30] "Unit_Hertz" Vector__XXX
|
||||
SG_ HCA_01_LM_Offset : 16|9@1+ (1,0) [0|511] "Unit_centiNewtoMeter" Vector__XXX
|
||||
SG_ EA_ACC_Sollstatus : 25|2@1+ (1,0) [0|3] "" Frontradar
|
||||
SG_ EA_Ruckprofil : 27|3@1+ (1,0) [0|7] "" Vector__XXX
|
||||
SG_ HCA_01_Sendestatus : 30|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ HCA_01_LM_OffSign : 31|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ HCA_01_Status_HCA : 32|4@1+ (1,0) [0|15] "" Vector__XXX
|
||||
SG_ HCA_01_Vib_Amp : 36|4@1+ (0.2,0) [0|3] "Unit_NewtoMeter" Vector__XXX
|
||||
SG_ EA_Ruckfreigabe : 40|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ EA_ACC_Wunschgeschwindigkeit : 41|10@1+ (0.32,0) [0|327.04] "Unit_KiloMeterPerHour" Frontradar
|
||||
|
||||
BO_ 159 LH_EPS_03: 8 XXX
|
||||
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
|
||||
@@ -1420,12 +1421,16 @@ CM_ SG_ 159 EPS_VZ_Lenkmoment "Steering input by driver, direction";
|
||||
CM_ SG_ 159 EPS_Berechneter_LW "Raw steering angle, degrees";
|
||||
CM_ SG_ 159 EPS_VZ_BLW "Raw steering angle, direction";
|
||||
CM_ SG_ 173 COUNTERXX "Message not renamed to COUNTER because J533 rate-limiting makes it look like messages are being lost";
|
||||
CM_ SG_ 294 SET_ME_0X3 "May be zero when sent by older cameras";
|
||||
CM_ SG_ 294 SET_ME_0X07 "May be zero when sent by older cameras";
|
||||
CM_ SG_ 294 SET_ME_0XFE "May be zero when sent by older cameras";
|
||||
CM_ SG_ 294 Assist_Torque "Heading control input, torque";
|
||||
CM_ SG_ 294 Assist_VZ "Heading control input, direction (sign)";
|
||||
CM_ SG_ 294 HCA_Available "Must be 1 for steering rack to accept HCA commands";
|
||||
CM_ SG_ 294 HCA_01_Vib_Freq "Frequenz der Lenkradvibration";
|
||||
CM_ SG_ 294 HCA_01_LM_Offset "Von HCA angefordertes Lenkmoment (Betrag)";
|
||||
CM_ SG_ 294 EA_ACC_Sollstatus "Status-Anforderung ACC von Emergency Alert. Statuswechsel bei Flanke. Solange Wert=1, wird EA_ACC_Wunschgeschwindigkeit übernommen. Wert=2 führt zu Zustand ¿ACC_GRA_passiv¿";
|
||||
CM_ SG_ 294 EA_Ruckprofil "Emergency Alert Anforderung an ESP, welcher Ruck verwendet werden soll. Eine Umsetzung der Ruckanforderung im ESP erfolgt nur mit gesetztem Bit 'EA_Ruckfreigabe'.";
|
||||
CM_ SG_ 294 HCA_01_Sendestatus "Gibt den Sendestatus der HCA_01 an (notwendig für IL-Unterstützung)";
|
||||
CM_ SG_ 294 HCA_01_LM_OffSign "Vorzeichen des HCA-Lenkmoments";
|
||||
CM_ SG_ 294 HCA_01_Status_HCA "Statusinformation vom HCA und Manoevrierassistent für Handshakemechanismus mit der Lenkung";
|
||||
CM_ SG_ 294 HCA_01_Vib_Amp "Momentenamplitude der Lenkradvibration";
|
||||
CM_ SG_ 294 EA_Ruckfreigabe "Emergency Alert Freigabit für die Warnruck-Anforderung an das ESP";
|
||||
CM_ SG_ 294 EA_ACC_Wunschgeschwindigkeit "Emergency Alert Anforderung neue Wunschgeschwindigkeit";
|
||||
CM_ SG_ 302 ACC_Hold_Request "Active request for ABS brake hold in ACC_Hold_Type";
|
||||
CM_ SG_ 302 ACC_Boost_Request "Hybrid engine start related";
|
||||
CM_ SG_ 302 ACC_Freewheel_Request "Active request for DSG sailing/coasting in ACC_Freewheel_Type";
|
||||
@@ -1475,6 +1480,13 @@ CM_ SG_ 1720 KBI_Variante_USA "In diesem Signal wird die HW-Variante des Kombis
|
||||
VAL_ 159 EPS_HCA_Status 0 "disabled" 1 "initializing" 2 "fault" 3 "ready" 4 "rejected" 5 "active" ;
|
||||
VAL_ 173 GE_Fahrstufe 5 "P" 6 "R" 7 "N" 8 "D" 9 "S" 10 "E" 13 "T" 14 "T" ;
|
||||
VAL_ 288 TSK_Status 0 "init" 1 "disabled" 2 "enabled" 3 "regulating" 4 "accel_pedal_override" 5 "brake_only" 6 "temp_fault" 7 "perm_fault" ;
|
||||
VAL_ 294 EA_ACC_Sollstatus 0 "Init" 1 "ACC_aktivieren" 2 "ACC_deaktivieren" ;
|
||||
VAL_ 294 EA_Ruckprofil 0 "Init" 1 "Profil_1" 2 "Profil_2" 3 "Profil_3" 4 "Profil_4" 5 "Profil_5" 6 "Profil_6" 7 "Profil_7" ;
|
||||
VAL_ 294 HCA_01_Sendestatus 0 "HCA_sendet_mit_1000ms" 1 "HCA_sendet_mit_20ms" ;
|
||||
VAL_ 294 HCA_01_LM_OffSign 0 "positives_Vorzeichen" 1 "negatives_Vorzeichen" ;
|
||||
VAL_ 294 HCA_01_Status_HCA 0 "deaktiviert" 1 "reserviert" 2 "reserviert" 3 "funktionsbereit" 4 "reserviert" 5 "HCA_Momenteneingriff_1" 6 "MA_Aktiv" 7 "HCA_Momenteneingriff_2" 8 "reserviert" 9 "reserviert" 10 "reserviert" 11 "reserviert" 12 "reserviert" 13 "reserviert" 14 "reserviert" 15 "reserviert" ;
|
||||
VAL_ 294 EA_Ruckfreigabe 0 "keine_Freigabe" 1 "Freigabe" ;
|
||||
VAL_ 294 EA_ACC_Wunschgeschwindigkeit 1023 "Init" ;
|
||||
VAL_ 780 ACC_Wunschgeschw_02 1023 "keine_Anzeige" ;
|
||||
VAL_ 780 ACC_Status_Prim_Anz 0 "Symbol nicht beleuchtet" 1 "Farbe 1 (typisch 'gruen')" 2 "Farbe 2 (typisch 'rot')" 3 "Farbe 3 (typisch 'gelb')" ;
|
||||
VAL_ 780 ACC_Abstandsindex 0 "Sonderanzeige_graue_Fahrbahn" 1022 "Sonderanzeige_graue_Fahrbahn" 1023 "Sonderanzeige_Fahrbahn_mit_gruenem_roten_Bereich" ;
|
||||
|
||||
@@ -4,18 +4,15 @@ Programming
|
||||
**Panda**
|
||||
|
||||
```
|
||||
./recover.sh # flash bootstub
|
||||
```
|
||||
|
||||
```
|
||||
./flash.sh # flash application
|
||||
./recover.py # flash bootstub
|
||||
./flash.py # flash application
|
||||
```
|
||||
|
||||
Troubleshooting
|
||||
----
|
||||
|
||||
If your panda will not flash and green LED is on, use `recover.sh`.
|
||||
If panda is blinking fast with green LED, use `flash.sh`.
|
||||
If your panda will not flash and green LED is on, use `recover.py`.
|
||||
If panda is blinking fast with green LED, use `flash.py`.
|
||||
Otherwise if LED is off and panda can't be seen with `lsusb` command, use [panda paw](https://comma.ai/shop/products/panda-paw) to go into DFU mode.
|
||||
|
||||
|
||||
|
||||
@@ -102,7 +102,8 @@ def get_key_header(name):
|
||||
from Crypto.PublicKey import RSA
|
||||
|
||||
public_fn = File(f'../certs/{name}.pub').srcnode().abspath
|
||||
rsa = RSA.importKey(open(public_fn).read())
|
||||
with open(public_fn) as f:
|
||||
rsa = RSA.importKey(f.read())
|
||||
assert(rsa.size_in_bits() == 1024)
|
||||
|
||||
rr = pow(2**1024, 2, rsa.n)
|
||||
|
||||
@@ -25,7 +25,7 @@ void black_enable_can_transceiver(uint8_t transceiver, bool enabled) {
|
||||
void black_enable_can_transceivers(bool enabled) {
|
||||
for(uint8_t i=1U; i<=4U; i++){
|
||||
// Leave main CAN always on for CAN-based ignition detection
|
||||
if((car_harness_status == HARNESS_STATUS_FLIPPED) ? (i == 3U) : (i == 1U)){
|
||||
if((harness.status == HARNESS_STATUS_FLIPPED) ? (i == 3U) : (i == 1U)){
|
||||
black_enable_can_transceiver(i, true);
|
||||
} else {
|
||||
black_enable_can_transceiver(i, enabled);
|
||||
@@ -83,7 +83,7 @@ void black_set_can_mode(uint8_t mode){
|
||||
switch (mode) {
|
||||
case CAN_MODE_NORMAL:
|
||||
case CAN_MODE_OBD_CAN2:
|
||||
if ((bool)(mode == CAN_MODE_NORMAL) != (bool)(car_harness_status == HARNESS_STATUS_FLIPPED)) {
|
||||
if ((bool)(mode == CAN_MODE_NORMAL) != (bool)(harness.status == HARNESS_STATUS_FLIPPED)) {
|
||||
// B12,B13: disable OBD mode
|
||||
set_gpio_mode(GPIOB, 12, MODE_INPUT);
|
||||
set_gpio_mode(GPIOB, 13, MODE_INPUT);
|
||||
@@ -160,7 +160,7 @@ void black_init(void) {
|
||||
black_set_can_mode(CAN_MODE_NORMAL);
|
||||
|
||||
// flip CAN0 and CAN2 if we are flipped
|
||||
if (car_harness_status == HARNESS_STATUS_FLIPPED) {
|
||||
if (harness.status == HARNESS_STATUS_FLIPPED) {
|
||||
can_flip_buses(0, 2);
|
||||
}
|
||||
}
|
||||
@@ -191,6 +191,9 @@ const board board_black = {
|
||||
.has_canfd = false,
|
||||
.has_rtc_battery = false,
|
||||
.fan_max_rpm = 0U,
|
||||
.avdd_mV = 3300U,
|
||||
.fan_stall_recovery = false,
|
||||
.fan_enable_cooldown_time = 0U,
|
||||
.init = black_init,
|
||||
.enable_can_transceiver = black_enable_can_transceiver,
|
||||
.enable_can_transceivers = black_enable_can_transceivers,
|
||||
@@ -204,4 +207,4 @@ const board board_black = {
|
||||
.set_phone_power = unused_set_phone_power,
|
||||
.set_siren = unused_set_siren,
|
||||
.read_som_gpio = unused_read_som_gpio
|
||||
};
|
||||
};
|
||||
|
||||
@@ -11,7 +11,7 @@ typedef void (*board_set_ir_power)(uint8_t percentage);
|
||||
typedef void (*board_set_fan_enabled)(bool enabled);
|
||||
typedef void (*board_set_phone_power)(bool enabled);
|
||||
typedef void (*board_set_siren)(bool enabled);
|
||||
typedef void (*board_board_tick)(bool ignition, bool usb_enum, bool heartbeat_seen);
|
||||
typedef void (*board_board_tick)(bool ignition, bool usb_enum, bool heartbeat_seen, bool harness_inserted);
|
||||
typedef bool (*board_read_som_gpio)(void);
|
||||
|
||||
struct board {
|
||||
@@ -25,6 +25,9 @@ struct board {
|
||||
const bool has_canfd;
|
||||
const bool has_rtc_battery;
|
||||
const uint16_t fan_max_rpm;
|
||||
const uint16_t avdd_mV;
|
||||
const bool fan_stall_recovery;
|
||||
const uint8_t fan_enable_cooldown_time;
|
||||
board_init init;
|
||||
board_enable_can_transceiver enable_can_transceiver;
|
||||
board_enable_can_transceivers enable_can_transceivers;
|
||||
|
||||
+11
-12
@@ -25,7 +25,7 @@ void dos_enable_can_transceiver(uint8_t transceiver, bool enabled) {
|
||||
void dos_enable_can_transceivers(bool enabled) {
|
||||
for(uint8_t i=1U; i<=4U; i++){
|
||||
// Leave main CAN always on for CAN-based ignition detection
|
||||
if((car_harness_status == HARNESS_STATUS_FLIPPED) ? (i == 3U) : (i == 1U)){
|
||||
if((harness.status == HARNESS_STATUS_FLIPPED) ? (i == 3U) : (i == 1U)){
|
||||
dos_enable_can_transceiver(i, true);
|
||||
} else {
|
||||
dos_enable_can_transceiver(i, enabled);
|
||||
@@ -53,9 +53,9 @@ void dos_set_bootkick(bool enabled){
|
||||
set_gpio_output(GPIOC, 4, !enabled);
|
||||
}
|
||||
|
||||
void dos_board_tick(bool ignition, bool usb_enum, bool heartbeat_seen) {
|
||||
if (ignition && !usb_enum) {
|
||||
// enable bootkick if ignition seen
|
||||
void dos_board_tick(bool ignition, bool usb_enum, bool heartbeat_seen, bool harness_inserted) {
|
||||
if ((ignition && !usb_enum) || harness_inserted) {
|
||||
// enable bootkick if ignition seen or if plugged into a harness
|
||||
dos_set_bootkick(true);
|
||||
} else if (heartbeat_seen) {
|
||||
// disable once openpilot is up
|
||||
@@ -69,7 +69,7 @@ void dos_set_can_mode(uint8_t mode){
|
||||
switch (mode) {
|
||||
case CAN_MODE_NORMAL:
|
||||
case CAN_MODE_OBD_CAN2:
|
||||
if ((bool)(mode == CAN_MODE_NORMAL) != (bool)(car_harness_status == HARNESS_STATUS_FLIPPED)) {
|
||||
if ((bool)(mode == CAN_MODE_NORMAL) != (bool)(harness.status == HARNESS_STATUS_FLIPPED)) {
|
||||
// B12,B13: disable OBD mode
|
||||
set_gpio_mode(GPIOB, 12, MODE_INPUT);
|
||||
set_gpio_mode(GPIOB, 13, MODE_INPUT);
|
||||
@@ -140,12 +140,8 @@ void dos_init(void) {
|
||||
set_gpio_output(GPIOC, 11, 1);
|
||||
|
||||
#ifdef ENABLE_SPI
|
||||
// A4-A7: SPI
|
||||
set_gpio_alternate(GPIOA, 4, GPIO_AF5_SPI1);
|
||||
set_gpio_alternate(GPIOA, 5, GPIO_AF5_SPI1);
|
||||
set_gpio_alternate(GPIOA, 6, GPIO_AF5_SPI1);
|
||||
set_gpio_alternate(GPIOA, 7, GPIO_AF5_SPI1);
|
||||
register_set_bits(&(GPIOA->OSPEEDR), GPIO_OSPEEDER_OSPEEDR4 | GPIO_OSPEEDER_OSPEEDR5 | GPIO_OSPEEDER_OSPEEDR6 | GPIO_OSPEEDER_OSPEEDR7);
|
||||
// SPI init
|
||||
gpio_spi_init();
|
||||
#endif
|
||||
|
||||
// C8: FAN PWM aka TIM3_CH3
|
||||
@@ -181,7 +177,7 @@ void dos_init(void) {
|
||||
dos_set_can_mode(CAN_MODE_NORMAL);
|
||||
|
||||
// flip CAN0 and CAN2 if we are flipped
|
||||
if (car_harness_status == HARNESS_STATUS_FLIPPED) {
|
||||
if (harness.status == HARNESS_STATUS_FLIPPED) {
|
||||
can_flip_buses(0, 2);
|
||||
}
|
||||
|
||||
@@ -219,6 +215,9 @@ const board board_dos = {
|
||||
.has_canfd = false,
|
||||
.has_rtc_battery = true,
|
||||
.fan_max_rpm = 6500U,
|
||||
.avdd_mV = 3300U,
|
||||
.fan_stall_recovery = true,
|
||||
.fan_enable_cooldown_time = 3U,
|
||||
.init = dos_init,
|
||||
.enable_can_transceiver = dos_enable_can_transceiver,
|
||||
.enable_can_transceivers = dos_enable_can_transceivers,
|
||||
|
||||
@@ -45,6 +45,9 @@ const board board_grey = {
|
||||
.has_canfd = false,
|
||||
.has_rtc_battery = false,
|
||||
.fan_max_rpm = 0U,
|
||||
.avdd_mV = 3300U,
|
||||
.fan_stall_recovery = false,
|
||||
.fan_enable_cooldown_time = 0U,
|
||||
.init = grey_init,
|
||||
.enable_can_transceiver = white_enable_can_transceiver,
|
||||
.enable_can_transceivers = white_enable_can_transceivers,
|
||||
|
||||
@@ -83,6 +83,9 @@ const board board_pedal = {
|
||||
.has_canfd = false,
|
||||
.has_rtc_battery = false,
|
||||
.fan_max_rpm = 0U,
|
||||
.avdd_mV = 3300U,
|
||||
.fan_stall_recovery = false,
|
||||
.fan_enable_cooldown_time = 0U,
|
||||
.init = pedal_init,
|
||||
.enable_can_transceiver = pedal_enable_can_transceiver,
|
||||
.enable_can_transceivers = pedal_enable_can_transceivers,
|
||||
|
||||
@@ -22,7 +22,7 @@ void red_enable_can_transceiver(uint8_t transceiver, bool enabled) {
|
||||
}
|
||||
|
||||
void red_enable_can_transceivers(bool enabled) {
|
||||
uint8_t main_bus = (car_harness_status == HARNESS_STATUS_FLIPPED) ? 3U : 1U;
|
||||
uint8_t main_bus = (harness.status == HARNESS_STATUS_FLIPPED) ? 3U : 1U;
|
||||
for (uint8_t i=1U; i<=4U; i++) {
|
||||
// Leave main CAN always on for CAN-based ignition detection
|
||||
if (i == main_bus) {
|
||||
@@ -53,7 +53,7 @@ void red_set_can_mode(uint8_t mode) {
|
||||
switch (mode) {
|
||||
case CAN_MODE_NORMAL:
|
||||
case CAN_MODE_OBD_CAN2:
|
||||
if ((bool)(mode == CAN_MODE_NORMAL) != (bool)(car_harness_status == HARNESS_STATUS_FLIPPED)) {
|
||||
if ((bool)(mode == CAN_MODE_NORMAL) != (bool)(harness.status == HARNESS_STATUS_FLIPPED)) {
|
||||
// B12,B13: disable normal mode
|
||||
set_gpio_pullup(GPIOB, 12, PULL_NONE);
|
||||
set_gpio_mode(GPIOB, 12, MODE_ANALOG);
|
||||
@@ -147,7 +147,7 @@ void red_init(void) {
|
||||
red_set_can_mode(CAN_MODE_NORMAL);
|
||||
|
||||
// flip CAN0 and CAN2 if we are flipped
|
||||
if (car_harness_status == HARNESS_STATUS_FLIPPED) {
|
||||
if (harness.status == HARNESS_STATUS_FLIPPED) {
|
||||
can_flip_buses(0, 2);
|
||||
}
|
||||
}
|
||||
@@ -178,6 +178,9 @@ const board board_red = {
|
||||
.has_canfd = true,
|
||||
.has_rtc_battery = false,
|
||||
.fan_max_rpm = 0U,
|
||||
.avdd_mV = 3300U,
|
||||
.fan_stall_recovery = false,
|
||||
.fan_enable_cooldown_time = 0U,
|
||||
.init = red_init,
|
||||
.enable_can_transceiver = red_enable_can_transceiver,
|
||||
.enable_can_transceivers = red_enable_can_transceivers,
|
||||
|
||||
@@ -24,7 +24,7 @@ void red_chiplet_enable_can_transceiver(uint8_t transceiver, bool enabled) {
|
||||
}
|
||||
|
||||
void red_chiplet_enable_can_transceivers(bool enabled) {
|
||||
uint8_t main_bus = (car_harness_status == HARNESS_STATUS_FLIPPED) ? 3U : 1U;
|
||||
uint8_t main_bus = (harness.status == HARNESS_STATUS_FLIPPED) ? 3U : 1U;
|
||||
for (uint8_t i=1U; i<=4U; i++) {
|
||||
// Leave main CAN always on for CAN-based ignition detection
|
||||
if (i == main_bus) {
|
||||
@@ -45,13 +45,13 @@ void red_chiplet_init(void) {
|
||||
// A8, A3: OBD_SBU1_RELAY, OBD_SBU2_RELAY
|
||||
set_gpio_output_type(GPIOA, 8, OUTPUT_TYPE_OPEN_DRAIN);
|
||||
set_gpio_pullup(GPIOA, 8, PULL_NONE);
|
||||
set_gpio_mode(GPIOA, 8, MODE_OUTPUT);
|
||||
set_gpio_output(GPIOA, 8, 1);
|
||||
set_gpio_mode(GPIOA, 8, MODE_OUTPUT);
|
||||
|
||||
set_gpio_output_type(GPIOA, 3, OUTPUT_TYPE_OPEN_DRAIN);
|
||||
set_gpio_pullup(GPIOA, 3, PULL_NONE);
|
||||
set_gpio_mode(GPIOA, 3, MODE_OUTPUT);
|
||||
set_gpio_output(GPIOA, 3, 1);
|
||||
set_gpio_mode(GPIOA, 3, MODE_OUTPUT);
|
||||
|
||||
// G11,B10,D7,B11: transceiver enable
|
||||
set_gpio_pullup(GPIOG, 11, PULL_NONE);
|
||||
@@ -70,13 +70,10 @@ void red_chiplet_init(void) {
|
||||
set_gpio_pullup(GPIOD, 3, PULL_NONE);
|
||||
set_gpio_mode(GPIOD, 3, MODE_OUTPUT);
|
||||
|
||||
//B0: 5VOUT_S
|
||||
// B0: 5VOUT_S
|
||||
set_gpio_pullup(GPIOB, 0, PULL_NONE);
|
||||
set_gpio_mode(GPIOB, 0, MODE_ANALOG);
|
||||
|
||||
// Turn on USB load switch.
|
||||
red_chiplet_set_fan_or_usb_load_switch(true);
|
||||
|
||||
// Initialize harness
|
||||
harness_init();
|
||||
|
||||
@@ -95,7 +92,7 @@ void red_chiplet_init(void) {
|
||||
red_set_can_mode(CAN_MODE_NORMAL);
|
||||
|
||||
// flip CAN0 and CAN2 if we are flipped
|
||||
if (car_harness_status == HARNESS_STATUS_FLIPPED) {
|
||||
if (harness.status == HARNESS_STATUS_FLIPPED) {
|
||||
can_flip_buses(0, 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,14 @@
|
||||
// Red Panda V2 with chiplet + Harness //
|
||||
// ///////////////////// //
|
||||
|
||||
void red_panda_v2_init(void) {
|
||||
// common chiplet init
|
||||
red_chiplet_init();
|
||||
|
||||
// Turn on USB load switch
|
||||
red_chiplet_set_fan_or_usb_load_switch(true);
|
||||
}
|
||||
|
||||
const board board_red_v2 = {
|
||||
.board_type = "Red_v2",
|
||||
.board_tick = unused_board_tick,
|
||||
@@ -14,7 +22,10 @@ const board board_red_v2 = {
|
||||
.has_canfd = true,
|
||||
.has_rtc_battery = true,
|
||||
.fan_max_rpm = 0U,
|
||||
.init = red_chiplet_init,
|
||||
.avdd_mV = 3300U,
|
||||
.fan_stall_recovery = false,
|
||||
.fan_enable_cooldown_time = 0U,
|
||||
.init = red_panda_v2_init,
|
||||
.enable_can_transceiver = red_chiplet_enable_can_transceiver,
|
||||
.enable_can_transceivers = red_chiplet_enable_can_transceivers,
|
||||
.set_led = red_set_led,
|
||||
|
||||
@@ -19,9 +19,9 @@ void tres_set_bootkick(bool enabled){
|
||||
}
|
||||
|
||||
bool tres_ignition_prev = false;
|
||||
void tres_board_tick(bool ignition, bool usb_enum, bool heartbeat_seen) {
|
||||
void tres_board_tick(bool ignition, bool usb_enum, bool heartbeat_seen, bool harness_inserted) {
|
||||
UNUSED(usb_enum);
|
||||
if (ignition && !tres_ignition_prev) {
|
||||
if ((ignition && !tres_ignition_prev) || harness_inserted) {
|
||||
// enable bootkick on rising edge of ignition
|
||||
tres_set_bootkick(true);
|
||||
} else if (heartbeat_seen) {
|
||||
@@ -62,11 +62,7 @@ void tres_init(void) {
|
||||
uart_init(&uart_ring_som_debug, 115200);
|
||||
|
||||
// SPI init
|
||||
set_gpio_alternate(GPIOE, 11, GPIO_AF5_SPI4);
|
||||
set_gpio_alternate(GPIOE, 12, GPIO_AF5_SPI4);
|
||||
set_gpio_alternate(GPIOE, 13, GPIO_AF5_SPI4);
|
||||
set_gpio_alternate(GPIOE, 14, GPIO_AF5_SPI4);
|
||||
register_set_bits(&(GPIOE->OSPEEDR), GPIO_OSPEEDR_OSPEED11 | GPIO_OSPEEDR_OSPEED12 | GPIO_OSPEEDR_OSPEED13 | GPIO_OSPEEDR_OSPEED14);
|
||||
gpio_spi_init();
|
||||
|
||||
// fan setup
|
||||
set_gpio_alternate(GPIOC, 8, GPIO_AF2_TIM3);
|
||||
@@ -97,7 +93,10 @@ const board board_tres = {
|
||||
.has_spi = true,
|
||||
.has_canfd = true,
|
||||
.has_rtc_battery = true,
|
||||
.fan_max_rpm = 6500U, // TODO: verify this, copied from dos
|
||||
.fan_max_rpm = 6600U,
|
||||
.avdd_mV = 1800U,
|
||||
.fan_stall_recovery = false,
|
||||
.fan_enable_cooldown_time = 3U,
|
||||
.init = tres_init,
|
||||
.enable_can_transceiver = red_chiplet_enable_can_transceiver,
|
||||
.enable_can_transceivers = red_chiplet_enable_can_transceivers,
|
||||
|
||||
@@ -27,7 +27,7 @@ void uno_enable_can_transceiver(uint8_t transceiver, bool enabled) {
|
||||
void uno_enable_can_transceivers(bool enabled) {
|
||||
for(uint8_t i=1U; i<=4U; i++){
|
||||
// Leave main CAN always on for CAN-based ignition detection
|
||||
if((car_harness_status == HARNESS_STATUS_FLIPPED) ? (i == 3U) : (i == 1U)){
|
||||
if((harness.status == HARNESS_STATUS_FLIPPED) ? (i == 3U) : (i == 1U)){
|
||||
uno_enable_can_transceiver(i, true);
|
||||
} else {
|
||||
uno_enable_can_transceiver(i, enabled);
|
||||
@@ -102,7 +102,7 @@ void uno_set_can_mode(uint8_t mode){
|
||||
switch (mode) {
|
||||
case CAN_MODE_NORMAL:
|
||||
case CAN_MODE_OBD_CAN2:
|
||||
if ((bool)(mode == CAN_MODE_NORMAL) != (bool)(car_harness_status == HARNESS_STATUS_FLIPPED)) {
|
||||
if ((bool)(mode == CAN_MODE_NORMAL) != (bool)(harness.status == HARNESS_STATUS_FLIPPED)) {
|
||||
// B12,B13: disable OBD mode
|
||||
set_gpio_mode(GPIOB, 12, MODE_INPUT);
|
||||
set_gpio_mode(GPIOB, 13, MODE_INPUT);
|
||||
@@ -126,10 +126,11 @@ void uno_set_can_mode(uint8_t mode){
|
||||
}
|
||||
}
|
||||
|
||||
void uno_board_tick(bool ignition, bool usb_enum, bool heartbeat_seen) {
|
||||
void uno_board_tick(bool ignition, bool usb_enum, bool heartbeat_seen, bool harness_inserted) {
|
||||
UNUSED(ignition);
|
||||
UNUSED(usb_enum);
|
||||
UNUSED(heartbeat_seen);
|
||||
UNUSED(harness_inserted);
|
||||
if (bootkick_timer != 0U) {
|
||||
bootkick_timer--;
|
||||
} else {
|
||||
@@ -210,12 +211,12 @@ void uno_init(void) {
|
||||
uno_set_can_mode(CAN_MODE_NORMAL);
|
||||
|
||||
// flip CAN0 and CAN2 if we are flipped
|
||||
if (car_harness_status == HARNESS_STATUS_FLIPPED) {
|
||||
if (harness.status == HARNESS_STATUS_FLIPPED) {
|
||||
can_flip_buses(0, 2);
|
||||
}
|
||||
|
||||
// Switch to phone usb mode if harness connection is powered by less than 7V
|
||||
if(adc_get_voltage() < 7000U){
|
||||
if((adc_get_mV(ADCCHAN_VIN) * VIN_READOUT_DIVIDER) < 7000U){
|
||||
uno_set_usb_switch(true);
|
||||
} else {
|
||||
uno_set_usb_switch(false);
|
||||
@@ -251,6 +252,9 @@ const board board_uno = {
|
||||
.has_canfd = false,
|
||||
.has_rtc_battery = true,
|
||||
.fan_max_rpm = 5100U,
|
||||
.avdd_mV = 3300U,
|
||||
.fan_stall_recovery = false,
|
||||
.fan_enable_cooldown_time = 0U,
|
||||
.init = uno_init,
|
||||
.enable_can_transceiver = uno_enable_can_transceiver,
|
||||
.enable_can_transceivers = uno_enable_can_transceivers,
|
||||
|
||||
@@ -22,10 +22,11 @@ uint32_t unused_read_current(void) {
|
||||
return 0U;
|
||||
}
|
||||
|
||||
void unused_board_tick(bool ignition, bool usb_enum, bool heartbeat_seen) {
|
||||
void unused_board_tick(bool ignition, bool usb_enum, bool heartbeat_seen, bool harness_inserted) {
|
||||
UNUSED(ignition);
|
||||
UNUSED(usb_enum);
|
||||
UNUSED(heartbeat_seen);
|
||||
UNUSED(harness_inserted);
|
||||
}
|
||||
|
||||
bool unused_read_som_gpio(void) {
|
||||
|
||||
@@ -142,7 +142,7 @@ void white_set_can_mode(uint8_t mode){
|
||||
}
|
||||
|
||||
uint32_t white_read_current(void){
|
||||
return adc_get(ADCCHAN_CURRENT);
|
||||
return adc_get_raw(ADCCHAN_CURRENT);
|
||||
}
|
||||
|
||||
bool white_check_ignition(void){
|
||||
@@ -214,7 +214,7 @@ void white_grey_common_init(void) {
|
||||
white_set_can_mode(CAN_MODE_NORMAL);
|
||||
|
||||
// Init usb power mode
|
||||
uint32_t voltage = adc_get_voltage();
|
||||
uint32_t voltage = adc_get_mV(ADCCHAN_VIN) * VIN_READOUT_DIVIDER;
|
||||
// Init in CDP mode only if panda is powered by 12V.
|
||||
// Otherwise a PC would not be able to flash a standalone panda
|
||||
if (voltage > 8000U) { // 8V threshold
|
||||
@@ -247,6 +247,9 @@ const board board_white = {
|
||||
.has_canfd = false,
|
||||
.has_rtc_battery = false,
|
||||
.fan_max_rpm = 0U,
|
||||
.avdd_mV = 3300U,
|
||||
.fan_stall_recovery = false,
|
||||
.fan_enable_cooldown_time = 0U,
|
||||
.init = white_init,
|
||||
.enable_can_transceiver = white_enable_can_transceiver,
|
||||
.enable_can_transceivers = white_enable_can_transceivers,
|
||||
|
||||
@@ -8,12 +8,15 @@
|
||||
//#define DEBUG_SPI
|
||||
//#define DEBUG_FAULTS
|
||||
//#define DEBUG_COMMS
|
||||
//#define DEBUG_FAN
|
||||
|
||||
#define CAN_INIT_TIMEOUT_MS 500U
|
||||
#define DEEPSLEEP_WAKEUP_DELAY 3U
|
||||
#define USBPACKET_MAX_SIZE 0x40U
|
||||
#define MAX_CAN_MSGS_PER_BULK_TRANSFER 51U
|
||||
|
||||
#define VIN_READOUT_DIVIDER 11U
|
||||
|
||||
// USB definitions
|
||||
#define USB_VID 0xBBAAU
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ void process_can(uint8_t can_number) {
|
||||
// check for empty mailbox
|
||||
CANPacket_t to_send;
|
||||
if ((CAN->TSR & (CAN_TSR_TERR0 | CAN_TSR_ALST0)) != 0) { // last TX failed due to error arbitration lost
|
||||
can_health[can_number].total_rx_lost_cnt += 1U;
|
||||
can_health[can_number].total_tx_lost_cnt += 1U;
|
||||
CAN->TSR |= (CAN_TSR_TERR0 | CAN_TSR_ALST0);
|
||||
}
|
||||
if ((CAN->TSR & CAN_TSR_TME0) == CAN_TSR_TME0) {
|
||||
@@ -167,7 +167,7 @@ void can_rx(uint8_t can_number) {
|
||||
uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number);
|
||||
|
||||
if ((CAN->RF0R & (CAN_RF0R_FOVR0)) != 0) { // RX message lost due to FIFO overrun
|
||||
can_health[can_number].total_tx_lost_cnt += 1U;
|
||||
can_health[can_number].total_rx_lost_cnt += 1U;
|
||||
CAN->RF0R &= ~(CAN_RF0R_FOVR0);
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ void can_rx(uint8_t can_number) {
|
||||
can_set_checksum(&to_push);
|
||||
|
||||
// forwarding (panda only)
|
||||
int bus_fwd_num = safety_fwd_hook(bus_number, &to_push);
|
||||
int bus_fwd_num = safety_fwd_hook(bus_number, to_push.addr);
|
||||
if (bus_fwd_num != -1) {
|
||||
CANPacket_t to_send;
|
||||
|
||||
|
||||
@@ -199,7 +199,7 @@ void ignition_can_hook(CANPacket_t *to_push) {
|
||||
// GM exception
|
||||
if ((addr == 0x160) && (len == 5)) {
|
||||
// this message isn't all zeros when ignition is on
|
||||
ignition_can = GET_BYTES_04(to_push) != 0U;
|
||||
ignition_can = GET_BYTES(to_push, 0, 4) != 0U;
|
||||
ignition_can_cnt = 0U;
|
||||
}
|
||||
|
||||
@@ -257,6 +257,7 @@ void can_send(CANPacket_t *to_push, uint8_t bus_number, bool skip_tx_hook) {
|
||||
}
|
||||
} else {
|
||||
safety_tx_blocked += 1U;
|
||||
to_push->returned = 0U;
|
||||
to_push->rejected = 1U;
|
||||
|
||||
// data changed
|
||||
|
||||
@@ -1,27 +1,29 @@
|
||||
#include "stm32h7/lli2c.h"
|
||||
|
||||
#define CODEC_I2C_ADDR 0x10
|
||||
|
||||
// 1Vpp sine wave with 1V offset
|
||||
const uint8_t fake_siren_lut[360] = { 134U, 135U, 137U, 138U, 139U, 140U, 141U, 143U, 144U, 145U, 146U, 148U, 149U, 150U, 151U, 152U, 154U, 155U, 156U, 157U, 158U, 159U, 160U, 162U, 163U, 164U, 165U, 166U, 167U, 168U, 169U, 170U, 171U, 172U, 174U, 175U, 176U, 177U, 177U, 178U, 179U, 180U, 181U, 182U, 183U, 184U, 185U, 186U, 186U, 187U, 188U, 189U, 190U, 190U, 191U, 192U, 193U, 193U, 194U, 195U, 195U, 196U, 196U, 197U, 197U, 198U, 199U, 199U, 199U, 200U, 200U, 201U, 201U, 202U, 202U, 202U, 203U, 203U, 203U, 203U, 204U, 204U, 204U, 204U, 204U, 204U, 204U, 205U, 205U, 205U, 205U, 205U, 205U, 205U, 204U, 204U, 204U, 204U, 204U, 204U, 204U, 203U, 203U, 203U, 203U, 202U, 202U, 202U, 201U, 201U, 200U, 200U, 199U, 199U, 199U, 198U, 197U, 197U, 196U, 196U, 195U, 195U, 194U, 193U, 193U, 192U, 191U, 190U, 190U, 189U, 188U, 187U, 186U, 186U, 185U, 184U, 183U, 182U, 181U, 180U, 179U, 178U, 177U, 177U, 176U, 175U, 174U, 172U, 171U, 170U, 169U, 168U, 167U, 166U, 165U, 164U, 163U, 162U, 160U, 159U, 158U, 157U, 156U, 155U, 154U, 152U, 151U, 150U, 149U, 148U, 146U, 145U, 144U, 143U, 141U, 140U, 139U, 138U, 137U, 135U, 134U, 133U, 132U, 130U, 129U, 128U, 127U, 125U, 124U, 123U, 122U, 121U, 119U, 118U, 117U, 116U, 115U, 113U, 112U, 111U, 110U, 109U, 108U, 106U, 105U, 104U, 103U, 102U, 101U, 100U, 99U, 98U, 97U, 96U, 95U, 94U, 93U, 92U, 91U, 90U, 89U, 88U, 87U, 86U, 85U, 84U, 83U, 82U, 82U, 81U, 80U, 79U, 78U, 78U, 77U, 76U, 76U, 75U, 74U, 74U, 73U, 72U, 72U, 71U, 71U, 70U, 70U, 69U, 69U, 68U, 68U, 67U, 67U, 67U, 66U, 66U, 66U, 65U, 65U, 65U, 65U, 64U, 64U, 64U, 64U, 64U, 64U, 64U, 64U, 64U, 63U, 64U, 64U, 64U, 64U, 64U, 64U, 64U, 64U, 64U, 65U, 65U, 65U, 65U, 66U, 66U, 66U, 67U, 67U, 67U, 68U, 68U, 69U, 69U, 70U, 70U, 71U, 71U, 72U, 72U, 73U, 74U, 74U, 75U, 76U, 76U, 77U, 78U, 78U, 79U, 80U, 81U, 82U, 82U, 83U, 84U, 85U, 86U, 87U, 88U, 89U, 90U, 91U, 92U, 93U, 94U, 95U, 96U, 97U, 98U, 99U, 100U, 101U, 102U, 103U, 104U, 105U, 106U, 108U, 109U, 110U, 111U, 112U, 113U, 115U, 116U, 117U, 118U, 119U, 121U, 122U, 123U, 124U, 125U, 127U, 128U, 129U, 130U, 132U, 133U };
|
||||
|
||||
bool fake_siren_enabled = false;
|
||||
|
||||
void fake_siren_codec_enable(bool enabled) {
|
||||
if(enabled) {
|
||||
bool success = false;
|
||||
if (enabled) {
|
||||
bool success = true;
|
||||
success &= i2c_set_reg_bits(I2C5, CODEC_I2C_ADDR, 0x2B, (1U << 1)); // Left speaker mix from INA1
|
||||
success &= i2c_set_reg_bits(I2C5, CODEC_I2C_ADDR, 0x2C, (1U << 1)); // Right speaker mix from INA1
|
||||
success &= i2c_set_reg_mask(I2C5, CODEC_I2C_ADDR, 0x3D, 0x1F, 0b11111); // Left speaker volume
|
||||
success &= i2c_set_reg_mask(I2C5, CODEC_I2C_ADDR, 0x3E, 0x1F, 0b11111); // Right speaker volume
|
||||
success &= i2c_set_reg_mask(I2C5, CODEC_I2C_ADDR, 0x3D, 0x17, 0b11111); // Left speaker volume
|
||||
success &= i2c_set_reg_mask(I2C5, CODEC_I2C_ADDR, 0x3E, 0x17, 0b11111); // Right speaker volume
|
||||
success &= i2c_set_reg_mask(I2C5, CODEC_I2C_ADDR, 0x37, 0b101, 0b111); // INA gain
|
||||
success &= i2c_set_reg_bits(I2C5, CODEC_I2C_ADDR, 0x4C, (1U << 7)); // Enable INA
|
||||
success &= i2c_set_reg_bits(I2C5, CODEC_I2C_ADDR, 0x51, (1U << 7)); // Disable global shutdown
|
||||
if (!success) {
|
||||
print("Failed to setup the codec for fake siren\n");
|
||||
print("Siren codec enable failed\n");
|
||||
fault_occurred(FAULT_SIREN_MALFUNCTION);
|
||||
}
|
||||
} else {
|
||||
// Disable INA input. Make sure to retry a few times if the I2C bus is busy.
|
||||
for(uint8_t i=0U; i<10U; i++) {
|
||||
for (uint8_t i=0U; i<10U; i++) {
|
||||
if (i2c_clear_reg_bits(I2C5, CODEC_I2C_ADDR, 0x4C, (1U << 7))) {
|
||||
break;
|
||||
}
|
||||
@@ -56,7 +58,7 @@ void fake_siren_init(void) {
|
||||
register_set(&DMA1_Stream1->M0AR, (uint32_t) fake_siren_lut, 0xFFFFFFFFU);
|
||||
register_set(&DMA1_Stream1->PAR, (uint32_t) &(DAC1->DHR8R1), 0xFFFFFFFFU);
|
||||
DMA1_Stream1->NDTR = sizeof(fake_siren_lut);
|
||||
register_set(&DMA1_Stream1->FCR, 0U, 0xFFFFFFFFU);
|
||||
register_set(&DMA1_Stream1->FCR, 0U, 0x00000083U);
|
||||
DMA1_Stream1->CR = (0b11 << DMA_SxCR_PL_Pos);
|
||||
DMA1_Stream1->CR |= DMA_SxCR_MINC | DMA_SxCR_CIRC | (1 << DMA_SxCR_DIR_Pos);
|
||||
|
||||
@@ -71,4 +73,4 @@ void fake_siren_init(void) {
|
||||
// Enable the I2C to the codec
|
||||
i2c_init(I2C5);
|
||||
fake_siren_codec_enable(false);
|
||||
}
|
||||
}
|
||||
|
||||
+64
-28
@@ -5,55 +5,91 @@ struct fan_state_t {
|
||||
uint8_t power;
|
||||
float error_integral;
|
||||
uint8_t stall_counter;
|
||||
uint8_t stall_threshold;
|
||||
uint8_t total_stall_count;
|
||||
uint8_t cooldown_counter;
|
||||
} fan_state_t;
|
||||
struct fan_state_t fan_state;
|
||||
|
||||
#define FAN_I 0.001f
|
||||
#define FAN_STALL_THRESHOLD 25U
|
||||
const float FAN_I = 0.001f;
|
||||
|
||||
void fan_set_power(uint8_t percentage){
|
||||
fan_state.target_rpm = ((current_board->fan_max_rpm * MIN(100U, MAX(0U, percentage))) / 100U);
|
||||
const uint8_t FAN_TICK_FREQ = 8U;
|
||||
const uint8_t FAN_STALL_THRESHOLD_MIN = 3U;
|
||||
const uint8_t FAN_STALL_THRESHOLD_MAX = 8U;
|
||||
|
||||
|
||||
void fan_set_power(uint8_t percentage) {
|
||||
fan_state.target_rpm = ((current_board->fan_max_rpm * CLAMP(percentage, 0U, 100U)) / 100U);
|
||||
}
|
||||
|
||||
// Call this at 8Hz
|
||||
void fan_tick(void){
|
||||
void llfan_init(void);
|
||||
void fan_init(void) {
|
||||
fan_state.stall_threshold = FAN_STALL_THRESHOLD_MIN;
|
||||
fan_state.cooldown_counter = current_board->fan_enable_cooldown_time * FAN_TICK_FREQ;
|
||||
llfan_init();
|
||||
}
|
||||
|
||||
// Call this at FAN_TICK_FREQ
|
||||
void fan_tick(void) {
|
||||
if (current_board->fan_max_rpm > 0U) {
|
||||
// 4 interrupts per rotation
|
||||
uint16_t fan_rpm_fast = fan_state.tach_counter * (60U * 8U / 4U);
|
||||
// Measure fan RPM
|
||||
uint16_t fan_rpm_fast = fan_state.tach_counter * (60U * FAN_TICK_FREQ / 4U); // 4 interrupts per rotation
|
||||
fan_state.tach_counter = 0U;
|
||||
fan_state.rpm = (fan_rpm_fast + (3U * fan_state.rpm)) / 4U;
|
||||
|
||||
// Enable fan if we want it to spin
|
||||
current_board->set_fan_enabled(fan_state.target_rpm > 0U);
|
||||
|
||||
// Stall detection
|
||||
if (fan_state.power > 0U) {
|
||||
if (fan_rpm_fast == 0U) {
|
||||
fan_state.stall_counter = MIN(fan_state.stall_counter + 1U, 255U);
|
||||
bool fan_stalled = false;
|
||||
if (current_board->fan_stall_recovery) {
|
||||
if (fan_state.target_rpm > 0U) {
|
||||
if (fan_rpm_fast == 0U) {
|
||||
fan_state.stall_counter = MIN(fan_state.stall_counter + 1U, 255U);
|
||||
} else {
|
||||
fan_state.stall_counter = 0U;
|
||||
}
|
||||
|
||||
if (fan_state.stall_counter > (fan_state.stall_threshold*FAN_TICK_FREQ)) {
|
||||
fan_stalled = true;
|
||||
fan_state.stall_counter = 0U;
|
||||
fan_state.stall_threshold = CLAMP(fan_state.stall_threshold + 2U, FAN_STALL_THRESHOLD_MIN, FAN_STALL_THRESHOLD_MAX);
|
||||
fan_state.total_stall_count += 1U;
|
||||
|
||||
// datasheet gives this range as the minimum startup duty
|
||||
fan_state.error_integral = CLAMP(fan_state.error_integral, 20.0f, 45.0f);
|
||||
}
|
||||
} else {
|
||||
fan_state.stall_counter = 0U;
|
||||
fan_state.stall_threshold = FAN_STALL_THRESHOLD_MIN;
|
||||
}
|
||||
}
|
||||
|
||||
if (fan_state.stall_counter > FAN_STALL_THRESHOLD) {
|
||||
// Stall detected, power cycling fan controller
|
||||
current_board->set_fan_enabled(false);
|
||||
#ifdef DEBUG_FAN
|
||||
puth(fan_state.target_rpm);
|
||||
print(" "); puth(fan_rpm_fast);
|
||||
print(" "); puth(fan_state.power);
|
||||
print(" "); puth(fan_state.stall_counter);
|
||||
print("\n");
|
||||
#endif
|
||||
|
||||
// clip integral, can't fully reset otherwise we may always be stuck in stall detection
|
||||
fan_state.error_integral = MIN(50.0f, MAX(0.0f, fan_state.error_integral));
|
||||
}
|
||||
// Cooldown counter
|
||||
if (fan_state.target_rpm > 0U) {
|
||||
fan_state.cooldown_counter = current_board->fan_enable_cooldown_time * FAN_TICK_FREQ;
|
||||
} else {
|
||||
fan_state.stall_counter = 0U;
|
||||
fan_state.error_integral = 0.0f;
|
||||
if (fan_state.cooldown_counter > 0U) {
|
||||
fan_state.cooldown_counter--;
|
||||
}
|
||||
}
|
||||
|
||||
// Update controller
|
||||
float feedforward = (fan_state.target_rpm * 100.0f) / current_board->fan_max_rpm;
|
||||
float error = fan_state.target_rpm - fan_rpm_fast;
|
||||
if (fan_state.target_rpm == 0U) {
|
||||
fan_state.error_integral = 0.0f;
|
||||
} else {
|
||||
float error = fan_state.target_rpm - fan_rpm_fast;
|
||||
fan_state.error_integral += FAN_I * error;
|
||||
}
|
||||
fan_state.power = CLAMP(fan_state.error_integral, 0U, 100U);
|
||||
|
||||
fan_state.error_integral += FAN_I * error;
|
||||
fan_state.error_integral = MIN(70.0f, MAX(-70.0f, fan_state.error_integral));
|
||||
|
||||
fan_state.power = MIN(100U, MAX(0U, feedforward + fan_state.error_integral));
|
||||
// Set PWM and enable line
|
||||
pwm_set(TIM3, 3, fan_state.power);
|
||||
current_board->set_fan_enabled(!fan_stalled && ((fan_state.target_rpm > 0U) || (fan_state.cooldown_counter > 0U)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,9 +61,6 @@ void update_can_health_pkt(uint8_t can_number, bool error_irq) {
|
||||
|
||||
if (error_irq) {
|
||||
can_health[can_number].total_error_cnt += 1U;
|
||||
if ((CANx->IR & (FDCAN_IR_RF0L)) != 0) {
|
||||
can_health[can_number].total_rx_lost_cnt += 1U;
|
||||
}
|
||||
if ((CANx->IR & (FDCAN_IR_TEFL)) != 0) {
|
||||
can_health[can_number].total_tx_lost_cnt += 1U;
|
||||
}
|
||||
@@ -88,6 +85,7 @@ void process_can(uint8_t can_number) {
|
||||
can_health[can_number].total_tx_cnt += 1U;
|
||||
|
||||
uint32_t TxFIFOSA = FDCAN_START_ADDRESS + (can_number * FDCAN_OFFSET) + (FDCAN_RX_FIFO_0_EL_CNT * FDCAN_RX_FIFO_0_EL_SIZE);
|
||||
// get the index of the next TX FIFO element (0 to FDCAN_TX_FIFO_EL_CNT - 1)
|
||||
uint8_t tx_index = (CANx->TXFQS >> FDCAN_TXFQS_TFQPI_Pos) & 0x1F;
|
||||
// only send if we have received a packet
|
||||
canfd_fifo *fifo;
|
||||
@@ -145,9 +143,15 @@ void can_rx(uint8_t can_number) {
|
||||
// can is live
|
||||
pending_can_live = 1;
|
||||
|
||||
// getting new message index (0 to 63)
|
||||
// get the index of the next RX FIFO element (0 to FDCAN_RX_FIFO_0_EL_CNT - 1)
|
||||
uint8_t rx_fifo_idx = (uint8_t)((CANx->RXF0S >> FDCAN_RXF0S_F0GI_Pos) & 0x3F);
|
||||
|
||||
// Recommended to offset get index by at least +1 if RX FIFO is in overwrite mode and full (datasheet)
|
||||
if((CANx->RXF0S & FDCAN_RXF0S_F0F) == FDCAN_RXF0S_F0F) {
|
||||
rx_fifo_idx = ((rx_fifo_idx + 1U) >= FDCAN_RX_FIFO_0_EL_CNT) ? 0U : (rx_fifo_idx + 1U);
|
||||
can_health[can_number].total_rx_lost_cnt += 1U; // At least one message was lost
|
||||
}
|
||||
|
||||
uint32_t RxFIFO0SA = FDCAN_START_ADDRESS + (can_number * FDCAN_OFFSET);
|
||||
CANPacket_t to_push;
|
||||
canfd_fifo *fifo;
|
||||
@@ -173,7 +177,7 @@ void can_rx(uint8_t can_number) {
|
||||
can_set_checksum(&to_push);
|
||||
|
||||
// forwarding (panda only)
|
||||
int bus_fwd_num = safety_fwd_hook(bus_number, &to_push);
|
||||
int bus_fwd_num = safety_fwd_hook(bus_number, to_push.addr);
|
||||
if (bus_fwd_num != -1) {
|
||||
CANPacket_t to_send;
|
||||
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
uint8_t car_harness_status = 0U;
|
||||
#define HARNESS_STATUS_NC 0U
|
||||
#define HARNESS_STATUS_NORMAL 1U
|
||||
#define HARNESS_STATUS_FLIPPED 2U
|
||||
|
||||
struct harness_t {
|
||||
uint8_t status;
|
||||
uint16_t sbu1_voltage_mV;
|
||||
uint16_t sbu2_voltage_mV;
|
||||
bool relay_driven;
|
||||
bool sbu_adc_lock;
|
||||
};
|
||||
struct harness_t harness;
|
||||
|
||||
struct harness_configuration {
|
||||
const bool has_harness;
|
||||
GPIO_TypeDef *GPIO_SBU1;
|
||||
@@ -17,26 +25,42 @@ struct harness_configuration {
|
||||
uint8_t adc_channel_SBU2;
|
||||
};
|
||||
|
||||
// this function will be the API for tici
|
||||
void set_intercept_relay(bool intercept) {
|
||||
if (car_harness_status != HARNESS_STATUS_NC) {
|
||||
if (intercept) {
|
||||
print("switching harness to intercept (relay on)\n");
|
||||
} else {
|
||||
print("switching harness to passthrough (relay off)\n");
|
||||
if (current_board->harness_config->has_harness) {
|
||||
bool drive_relay = intercept;
|
||||
if (harness.status == HARNESS_STATUS_NC) {
|
||||
// no harness, no relay to drive
|
||||
drive_relay = false;
|
||||
}
|
||||
|
||||
if(car_harness_status == HARNESS_STATUS_NORMAL){
|
||||
set_gpio_output(current_board->harness_config->GPIO_relay_SBU2, current_board->harness_config->pin_relay_SBU2, !intercept);
|
||||
if (drive_relay) {
|
||||
harness.relay_driven = true;
|
||||
}
|
||||
|
||||
// wait until we're not reading the analog voltages anymore
|
||||
while (harness.sbu_adc_lock == true) {}
|
||||
|
||||
if (harness.status == HARNESS_STATUS_NORMAL) {
|
||||
set_gpio_output(current_board->harness_config->GPIO_relay_SBU1, current_board->harness_config->pin_relay_SBU1, true);
|
||||
set_gpio_output(current_board->harness_config->GPIO_relay_SBU2, current_board->harness_config->pin_relay_SBU2, !drive_relay);
|
||||
} else {
|
||||
set_gpio_output(current_board->harness_config->GPIO_relay_SBU1, current_board->harness_config->pin_relay_SBU1, !intercept);
|
||||
set_gpio_output(current_board->harness_config->GPIO_relay_SBU1, current_board->harness_config->pin_relay_SBU1, !drive_relay);
|
||||
set_gpio_output(current_board->harness_config->GPIO_relay_SBU2, current_board->harness_config->pin_relay_SBU2, true);
|
||||
}
|
||||
|
||||
if (!drive_relay) {
|
||||
harness.relay_driven = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool harness_check_ignition(void) {
|
||||
bool ret = false;
|
||||
switch(car_harness_status){
|
||||
|
||||
// wait until we're not reading the analog voltages anymore
|
||||
while (harness.sbu_adc_lock == true) {}
|
||||
|
||||
switch(harness.status){
|
||||
case HARNESS_STATUS_NORMAL:
|
||||
ret = !get_gpio_input(current_board->harness_config->GPIO_SBU1, current_board->harness_config->pin_SBU1);
|
||||
break;
|
||||
@@ -50,27 +74,46 @@ bool harness_check_ignition(void) {
|
||||
}
|
||||
|
||||
uint8_t harness_detect_orientation(void) {
|
||||
uint8_t ret = HARNESS_STATUS_NC;
|
||||
uint8_t ret = harness.status;
|
||||
|
||||
#ifndef BOOTSTUB
|
||||
uint32_t sbu1_voltage = adc_get(current_board->harness_config->adc_channel_SBU1);
|
||||
uint32_t sbu2_voltage = adc_get(current_board->harness_config->adc_channel_SBU2);
|
||||
// We can't detect orientation if the relay is being driven
|
||||
if (!harness.relay_driven && current_board->harness_config->has_harness) {
|
||||
harness.sbu_adc_lock = true;
|
||||
set_gpio_mode(current_board->harness_config->GPIO_SBU1, current_board->harness_config->pin_SBU1, MODE_ANALOG);
|
||||
set_gpio_mode(current_board->harness_config->GPIO_SBU2, current_board->harness_config->pin_SBU2, MODE_ANALOG);
|
||||
|
||||
// Detect connection and orientation
|
||||
if((sbu1_voltage < HARNESS_CONNECTED_THRESHOLD) || (sbu2_voltage < HARNESS_CONNECTED_THRESHOLD)){
|
||||
if (sbu1_voltage < sbu2_voltage) {
|
||||
// orientation flipped (PANDA_SBU1->HARNESS_SBU1(relay), PANDA_SBU2->HARNESS_SBU2(ign))
|
||||
ret = HARNESS_STATUS_FLIPPED;
|
||||
harness.sbu1_voltage_mV = adc_get_mV(current_board->harness_config->adc_channel_SBU1);
|
||||
harness.sbu2_voltage_mV = adc_get_mV(current_board->harness_config->adc_channel_SBU2);
|
||||
uint16_t detection_threshold = current_board->avdd_mV / 2U;
|
||||
|
||||
// Detect connection and orientation
|
||||
if((harness.sbu1_voltage_mV < detection_threshold) || (harness.sbu2_voltage_mV < detection_threshold)){
|
||||
if (harness.sbu1_voltage_mV < harness.sbu2_voltage_mV) {
|
||||
// orientation flipped (PANDA_SBU1->HARNESS_SBU1(relay), PANDA_SBU2->HARNESS_SBU2(ign))
|
||||
ret = HARNESS_STATUS_FLIPPED;
|
||||
} else {
|
||||
// orientation normal (PANDA_SBU2->HARNESS_SBU1(relay), PANDA_SBU1->HARNESS_SBU2(ign))
|
||||
ret = HARNESS_STATUS_NORMAL;
|
||||
}
|
||||
} else {
|
||||
// orientation normal (PANDA_SBU2->HARNESS_SBU1(relay), PANDA_SBU1->HARNESS_SBU2(ign))
|
||||
ret = HARNESS_STATUS_NORMAL;
|
||||
ret = HARNESS_STATUS_NC;
|
||||
}
|
||||
|
||||
// Pins are not 5V tolerant in ADC mode
|
||||
set_gpio_mode(current_board->harness_config->GPIO_SBU1, current_board->harness_config->pin_SBU1, MODE_INPUT);
|
||||
set_gpio_mode(current_board->harness_config->GPIO_SBU2, current_board->harness_config->pin_SBU2, MODE_INPUT);
|
||||
harness.sbu_adc_lock = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void harness_tick(void) {
|
||||
harness.status = harness_detect_orientation();
|
||||
}
|
||||
|
||||
void harness_init(void) {
|
||||
// delay such that the connection is fully made before trying orientation detection
|
||||
current_board->set_led(LED_BLUE, true);
|
||||
@@ -78,18 +121,13 @@ void harness_init(void) {
|
||||
current_board->set_led(LED_BLUE, false);
|
||||
|
||||
// try to detect orientation
|
||||
uint8_t ret = harness_detect_orientation();
|
||||
if (ret != HARNESS_STATUS_NC) {
|
||||
print("detected car harness with orientation "); puth2(ret); print("\n");
|
||||
car_harness_status = ret;
|
||||
|
||||
// set the SBU lines to be inputs before using the relay. The lines are not 5V tolerant in ADC mode!
|
||||
set_gpio_mode(current_board->harness_config->GPIO_SBU1, current_board->harness_config->pin_SBU1, MODE_INPUT);
|
||||
set_gpio_mode(current_board->harness_config->GPIO_SBU2, current_board->harness_config->pin_SBU2, MODE_INPUT);
|
||||
|
||||
// keep busses connected by default
|
||||
set_intercept_relay(false);
|
||||
harness.status = harness_detect_orientation();
|
||||
if (harness.status != HARNESS_STATUS_NC) {
|
||||
print("detected car harness with orientation "); puth2(harness.status); print("\n");
|
||||
} else {
|
||||
print("failed to detect car harness!\n");
|
||||
}
|
||||
|
||||
// keep buses connected by default
|
||||
set_intercept_relay(false);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
#define RCC_BDCR_OPTIONS_LSE (RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL_0 | RCC_BDCR_LSEON)
|
||||
#define RCC_BDCR_OPTIONS_LSI (RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL_1)
|
||||
|
||||
#define YEAR_OFFSET 2000U
|
||||
|
||||
typedef struct __attribute__((packed)) timestamp_t {
|
||||
@@ -21,39 +18,6 @@ uint16_t from_bcd(uint8_t value){
|
||||
return (((value & 0xF0U) >> 4U) * 10U) + (value & 0x0FU);
|
||||
}
|
||||
|
||||
void rtc_init(void){
|
||||
uint32_t bdcr_opts = 0U;
|
||||
uint32_t bdcr_mask = 0U;
|
||||
if (current_board->has_rtc_battery) {
|
||||
bdcr_opts = RCC_BDCR_OPTIONS_LSE;
|
||||
bdcr_mask = RCC_BDCR_MASK_LSE;
|
||||
} else {
|
||||
bdcr_opts = RCC_BDCR_OPTIONS_LSI;
|
||||
bdcr_mask = RCC_BDCR_MASK_LSI;
|
||||
RCC->CSR |= RCC_CSR_LSION;
|
||||
while((RCC->CSR & RCC_CSR_LSIRDY) == 0){}
|
||||
}
|
||||
|
||||
// Initialize RTC module and clock if not done already.
|
||||
if((RCC->BDCR & bdcr_mask) != bdcr_opts){
|
||||
print("Initializing RTC\n");
|
||||
// Reset backup domain
|
||||
register_set_bits(&(RCC->BDCR), RCC_BDCR_BDRST);
|
||||
|
||||
// Disable write protection
|
||||
disable_bdomain_protection();
|
||||
|
||||
// Clear backup domain reset
|
||||
register_clear_bits(&(RCC->BDCR), RCC_BDCR_BDRST);
|
||||
|
||||
// Set RTC options
|
||||
register_set(&(RCC->BDCR), bdcr_opts, bdcr_mask);
|
||||
|
||||
// Enable write protection
|
||||
enable_bdomain_protection();
|
||||
}
|
||||
}
|
||||
|
||||
void rtc_set_time(timestamp_t time){
|
||||
print("Setting RTC time\n");
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
typedef struct simple_watchdog_state_t {
|
||||
uint32_t fault;
|
||||
uint32_t last_ts;
|
||||
uint32_t threshold;
|
||||
} simple_watchdog_state_t;
|
||||
|
||||
simple_watchdog_state_t wd_state;
|
||||
|
||||
|
||||
void simple_watchdog_kick(void) {
|
||||
uint32_t ts = microsecond_timer_get();
|
||||
|
||||
uint32_t et = get_ts_elapsed(ts, wd_state.last_ts);
|
||||
if (et > wd_state.threshold) {
|
||||
print("WD timeout 0x"); puth(et); print("\n");
|
||||
fault_occurred(wd_state.fault);
|
||||
}
|
||||
|
||||
wd_state.last_ts = ts;
|
||||
}
|
||||
|
||||
void simple_watchdog_init(uint32_t fault, uint32_t threshold) {
|
||||
wd_state.fault = fault;
|
||||
wd_state.threshold = threshold;
|
||||
wd_state.last_ts = microsecond_timer_get();
|
||||
}
|
||||
+61
-33
@@ -3,6 +3,10 @@
|
||||
#define SPI_BUF_SIZE 1024U
|
||||
#define SPI_TIMEOUT_US 10000U
|
||||
|
||||
// we expect less than 50 transactions (including control messages and
|
||||
// CAN buffers) at the 100Hz boardd interval, plus some buffer
|
||||
#define SPI_IRQ_RATE 6500U
|
||||
|
||||
#ifdef STM32H7
|
||||
__attribute__((section(".ram_d1"))) uint8_t spi_buf_rx[SPI_BUF_SIZE];
|
||||
__attribute__((section(".ram_d1"))) uint8_t spi_buf_tx[SPI_BUF_SIZE];
|
||||
@@ -27,10 +31,13 @@ enum {
|
||||
SPI_STATE_DATA_TX
|
||||
};
|
||||
|
||||
bool spi_tx_dma_done = false;
|
||||
uint8_t spi_state = SPI_STATE_HEADER;
|
||||
uint8_t spi_endpoint;
|
||||
uint16_t spi_data_len_mosi;
|
||||
uint16_t spi_data_len_miso;
|
||||
uint16_t spi_checksum_error_count = 0;
|
||||
|
||||
|
||||
#define SPI_HEADER_SIZE 7U
|
||||
|
||||
@@ -40,10 +47,6 @@ void llspi_mosi_dma(uint8_t *addr, int len);
|
||||
void llspi_miso_dma(uint8_t *addr, int len);
|
||||
|
||||
void spi_init(void) {
|
||||
// clear buffers (for debugging)
|
||||
(void)memset(spi_buf_rx, 0, SPI_BUF_SIZE);
|
||||
(void)memset(spi_buf_tx, 0, SPI_BUF_SIZE);
|
||||
|
||||
// platform init
|
||||
llspi_init();
|
||||
|
||||
@@ -61,8 +64,10 @@ bool check_checksum(uint8_t *data, uint16_t len) {
|
||||
return checksum == 0U;
|
||||
}
|
||||
|
||||
void spi_handle_rx(void) {
|
||||
uint8_t next_rx_state = SPI_STATE_HEADER;
|
||||
void spi_rx_done(void) {
|
||||
uint16_t response_len = 0U;
|
||||
uint8_t next_rx_state = SPI_STATE_HEADER_NACK;
|
||||
bool checksum_valid = false;
|
||||
|
||||
// parse header
|
||||
spi_endpoint = spi_buf_rx[1];
|
||||
@@ -70,45 +75,47 @@ void spi_handle_rx(void) {
|
||||
spi_data_len_miso = (spi_buf_rx[5] << 8) | spi_buf_rx[4];
|
||||
|
||||
if (spi_state == SPI_STATE_HEADER) {
|
||||
if ((spi_buf_rx[0] == SPI_SYNC_BYTE) && check_checksum(spi_buf_rx, SPI_HEADER_SIZE)) {
|
||||
checksum_valid = check_checksum(spi_buf_rx, SPI_HEADER_SIZE);
|
||||
if ((spi_buf_rx[0] == SPI_SYNC_BYTE) && checksum_valid) {
|
||||
// response: ACK and start receiving data portion
|
||||
spi_buf_tx[0] = SPI_HACK;
|
||||
next_rx_state = SPI_STATE_HEADER_ACK;
|
||||
response_len = 1U;
|
||||
} else {
|
||||
// response: NACK and reset state machine
|
||||
print("- incorrect header sync or checksum "); hexdump(spi_buf_rx, SPI_HEADER_SIZE);
|
||||
spi_buf_tx[0] = SPI_NACK;
|
||||
next_rx_state = SPI_STATE_HEADER_NACK;
|
||||
response_len = 1U;
|
||||
}
|
||||
llspi_miso_dma(spi_buf_tx, 1);
|
||||
} else if (spi_state == SPI_STATE_DATA_RX) {
|
||||
// We got everything! Based on the endpoint specified, call the appropriate handler
|
||||
uint16_t response_len = 0U;
|
||||
bool reponse_ack = false;
|
||||
if (check_checksum(&(spi_buf_rx[SPI_HEADER_SIZE]), spi_data_len_mosi + 1U)) {
|
||||
bool response_ack = false;
|
||||
checksum_valid = check_checksum(&(spi_buf_rx[SPI_HEADER_SIZE]), spi_data_len_mosi + 1U);
|
||||
if (checksum_valid) {
|
||||
if (spi_endpoint == 0U) {
|
||||
if (spi_data_len_mosi >= sizeof(ControlPacket_t)) {
|
||||
ControlPacket_t ctrl;
|
||||
(void)memcpy(&ctrl, &spi_buf_rx[SPI_HEADER_SIZE], sizeof(ControlPacket_t));
|
||||
response_len = comms_control_handler(&ctrl, &spi_buf_tx[3]);
|
||||
reponse_ack = true;
|
||||
response_ack = true;
|
||||
} else {
|
||||
print("SPI: insufficient data for control handler\n");
|
||||
}
|
||||
} else if ((spi_endpoint == 1U) || (spi_endpoint == 0x81U)) {
|
||||
if (spi_data_len_mosi == 0U) {
|
||||
response_len = comms_can_read(&(spi_buf_tx[3]), spi_data_len_miso);
|
||||
reponse_ack = true;
|
||||
response_ack = true;
|
||||
} else {
|
||||
print("SPI: did not expect data for can_read\n");
|
||||
}
|
||||
} else if (spi_endpoint == 2U) {
|
||||
comms_endpoint2_write(&spi_buf_rx[SPI_HEADER_SIZE], spi_data_len_mosi);
|
||||
reponse_ack = true;
|
||||
response_ack = true;
|
||||
} else if (spi_endpoint == 3U) {
|
||||
if (spi_data_len_mosi > 0U) {
|
||||
comms_can_write(&spi_buf_rx[SPI_HEADER_SIZE], spi_data_len_mosi);
|
||||
reponse_ack = true;
|
||||
response_ack = true;
|
||||
} else {
|
||||
print("SPI: did expect data for can_write\n");
|
||||
}
|
||||
@@ -117,35 +124,56 @@ void spi_handle_rx(void) {
|
||||
}
|
||||
} else {
|
||||
// Checksum was incorrect
|
||||
reponse_ack = false;
|
||||
print("- incorrect data checksum\n");
|
||||
response_ack = false;
|
||||
print("- incorrect data checksum ");
|
||||
puth2(spi_data_len_mosi);
|
||||
print("\n");
|
||||
hexdump(spi_buf_rx, SPI_HEADER_SIZE);
|
||||
hexdump(&(spi_buf_rx[SPI_HEADER_SIZE]), MIN(spi_data_len_mosi, 64));
|
||||
print("\n");
|
||||
}
|
||||
|
||||
// Setup response header
|
||||
spi_buf_tx[0] = reponse_ack ? SPI_DACK : SPI_NACK;
|
||||
spi_buf_tx[1] = response_len & 0xFFU;
|
||||
spi_buf_tx[2] = (response_len >> 8) & 0xFFU;
|
||||
if (!response_ack) {
|
||||
spi_buf_tx[0] = SPI_NACK;
|
||||
next_rx_state = SPI_STATE_HEADER_NACK;
|
||||
response_len = 1U;
|
||||
} else {
|
||||
// Setup response header
|
||||
spi_buf_tx[0] = SPI_DACK;
|
||||
spi_buf_tx[1] = response_len & 0xFFU;
|
||||
spi_buf_tx[2] = (response_len >> 8) & 0xFFU;
|
||||
|
||||
// Add checksum
|
||||
uint8_t checksum = SPI_CHECKSUM_START;
|
||||
for(uint16_t i = 0U; i < (response_len + 3U); i++) {
|
||||
checksum ^= spi_buf_tx[i];
|
||||
// Add checksum
|
||||
uint8_t checksum = SPI_CHECKSUM_START;
|
||||
for(uint16_t i = 0U; i < (response_len + 3U); i++) {
|
||||
checksum ^= spi_buf_tx[i];
|
||||
}
|
||||
spi_buf_tx[response_len + 3U] = checksum;
|
||||
response_len += 4U;
|
||||
|
||||
next_rx_state = SPI_STATE_DATA_TX;
|
||||
}
|
||||
spi_buf_tx[response_len + 3U] = checksum;
|
||||
|
||||
// Write response
|
||||
llspi_miso_dma(spi_buf_tx, response_len + 4U);
|
||||
|
||||
next_rx_state = SPI_STATE_DATA_TX;
|
||||
} else {
|
||||
print("SPI: RX unexpected state: "); puth(spi_state); print("\n");
|
||||
}
|
||||
|
||||
// send out response
|
||||
if (response_len == 0U) {
|
||||
print("SPI: no response\n");
|
||||
spi_buf_tx[0] = SPI_NACK;
|
||||
spi_state = SPI_STATE_HEADER_NACK;
|
||||
response_len = 1U;
|
||||
}
|
||||
llspi_miso_dma(spi_buf_tx, response_len);
|
||||
|
||||
spi_state = next_rx_state;
|
||||
if (!checksum_valid && (spi_checksum_error_count < __UINT16_MAX__)) {
|
||||
spi_checksum_error_count += 1U;
|
||||
}
|
||||
}
|
||||
|
||||
void spi_handle_tx(bool timed_out) {
|
||||
if ((spi_state == SPI_STATE_HEADER_NACK) || timed_out) {
|
||||
void spi_tx_done(bool reset) {
|
||||
if ((spi_state == SPI_STATE_HEADER_NACK) || reset) {
|
||||
// Reset state
|
||||
spi_state = SPI_STATE_HEADER;
|
||||
llspi_mosi_dma(spi_buf_rx, SPI_HEADER_SIZE);
|
||||
|
||||
@@ -24,6 +24,7 @@ typedef union _USB_Setup {
|
||||
USB_Setup_TypeDef;
|
||||
|
||||
bool usb_enumerated = false;
|
||||
uint16_t usb_last_frame_num = 0U;
|
||||
|
||||
void usb_init(void);
|
||||
void usb_cb_ep3_out_complete(void);
|
||||
@@ -471,6 +472,12 @@ char to_hex_char(int a) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void usb_tick(void) {
|
||||
uint16_t current_frame_num = (USBx_DEVICE->DSTS & USB_OTG_DSTS_FNSOF_Msk) >> USB_OTG_DSTS_FNSOF_Pos;
|
||||
usb_enumerated = (current_frame_num != usb_last_frame_num);
|
||||
usb_last_frame_num = current_frame_num;
|
||||
}
|
||||
|
||||
void usb_setup(void) {
|
||||
int resp_len;
|
||||
ControlPacket_t control_req;
|
||||
@@ -673,24 +680,11 @@ void usb_irqhandler(void) {
|
||||
print("connector ID status change\n");
|
||||
}
|
||||
|
||||
if ((gintsts & USB_OTG_GINTSTS_ESUSP) != 0) {
|
||||
print("ESUSP detected\n");
|
||||
}
|
||||
|
||||
if ((gintsts & USB_OTG_GINTSTS_EOPF) != 0) {
|
||||
usb_enumerated = true;
|
||||
}
|
||||
|
||||
if ((gintsts & USB_OTG_GINTSTS_USBRST) != 0) {
|
||||
print("USB reset\n");
|
||||
usb_enumerated = false;
|
||||
usb_reset();
|
||||
}
|
||||
|
||||
if ((gintsts & USB_OTG_GINTSTS_USBSUSP) != 0) {
|
||||
usb_enumerated = false;
|
||||
}
|
||||
|
||||
if ((gintsts & USB_OTG_GINTSTS_ENUMDNE) != 0) {
|
||||
print("enumeration done");
|
||||
// Full speed, ENUMSPD
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
// TODO: why doesn't it define these?
|
||||
#ifdef STM32F2
|
||||
#define IWDG_PR_PR_Msk 0x7U
|
||||
#define IWDG_RLR_RL_Msk 0xFFFU
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
WATCHDOG_50_MS = (400U - 1U),
|
||||
WATCHDOG_500_MS = 4000U,
|
||||
} WatchdogTimeout;
|
||||
|
||||
void watchdog_feed(void) {
|
||||
IND_WDG->KR = 0xAAAAU;
|
||||
}
|
||||
|
||||
void watchdog_init(WatchdogTimeout timeout) {
|
||||
// enable watchdog
|
||||
IND_WDG->KR = 0xCCCCU;
|
||||
IND_WDG->KR = 0x5555U;
|
||||
|
||||
// 32KHz / 4 prescaler = 8000Hz
|
||||
register_set(&(IND_WDG->PR), 0x0U, IWDG_PR_PR_Msk);
|
||||
register_set(&(IND_WDG->RLR), timeout, IWDG_RLR_RL_Msk);
|
||||
|
||||
// wait for watchdog to be updated
|
||||
while (IND_WDG->SR != 0U);
|
||||
|
||||
// start the countdown
|
||||
watchdog_feed();
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
#define FAULT_STATUS_TEMPORARY 1U
|
||||
#define FAULT_STATUS_PERMANENT 2U
|
||||
|
||||
// Fault types
|
||||
// Fault types, matches cereal.log.PandaState.FaultType
|
||||
#define FAULT_RELAY_MALFUNCTION (1U << 0)
|
||||
#define FAULT_UNUSED_INTERRUPT_HANDLED (1U << 1)
|
||||
#define FAULT_INTERRUPT_RATE_CAN_1 (1U << 2)
|
||||
@@ -28,6 +28,8 @@
|
||||
#define FAULT_INTERRUPT_RATE_EXTI (1U << 22)
|
||||
#define FAULT_INTERRUPT_RATE_SPI (1U << 23)
|
||||
#define FAULT_INTERRUPT_RATE_UART_7 (1U << 24)
|
||||
#define FAULT_SIREN_MALFUNCTION (1U << 25)
|
||||
#define FAULT_HEARTBEAT_LOOP_WATCHDOG (1U << 26)
|
||||
|
||||
// Permanent faults
|
||||
#define PERMANENT_FAULTS 0U
|
||||
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from panda import Panda
|
||||
|
||||
board_path = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
if __name__ == "__main__":
|
||||
subprocess.check_call(f"scons -C {board_path}/.. -j$(nproc) {board_path}", shell=True)
|
||||
|
||||
serials = Panda.list()
|
||||
print(f"found {len(serials)} panda(s) - {serials}")
|
||||
for s in serials:
|
||||
print("flashing", s)
|
||||
with Panda(serial=s) as p:
|
||||
p.flash()
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
set -e
|
||||
|
||||
scons -u -j$(nproc)
|
||||
printf %b 'from python import Panda\nfor serial in Panda.list(): Panda(serial).flash()' | PYTHONPATH=.. python3
|
||||
@@ -2,6 +2,8 @@
|
||||
uint32_t *prog_ptr = NULL;
|
||||
bool unlocked = false;
|
||||
|
||||
void spi_init(void);
|
||||
|
||||
#ifdef uart_ring
|
||||
void debug_ring_callback(uart_ring *ring) {}
|
||||
#endif
|
||||
@@ -41,6 +43,11 @@ int comms_control_handler(ControlPacket_t *req, uint8_t *resp) {
|
||||
resp[1] = 0xff;
|
||||
}
|
||||
break;
|
||||
// **** 0xc1: get hardware type
|
||||
case 0xc1:
|
||||
resp[0] = hw_type;
|
||||
resp_len = 1;
|
||||
break;
|
||||
// **** 0xc3: fetch MCU UID
|
||||
case 0xc3:
|
||||
#ifdef UID_BASE
|
||||
@@ -289,6 +296,12 @@ void soft_flasher_start(void) {
|
||||
// enable USB
|
||||
usb_init();
|
||||
|
||||
// enable SPI
|
||||
if (current_board->has_spi) {
|
||||
gpio_spi_init();
|
||||
spi_init();
|
||||
}
|
||||
|
||||
// green LED on for flashing
|
||||
current_board->set_led(LED_GREEN, 1);
|
||||
|
||||
|
||||
+10
-7
@@ -1,7 +1,6 @@
|
||||
// When changing these structs, python/__init__.py needs to be kept up to date!
|
||||
|
||||
#define HEALTH_PACKET_VERSION 11
|
||||
|
||||
#define HEALTH_PACKET_VERSION 14
|
||||
struct __attribute__((packed)) health_t {
|
||||
uint32_t uptime_pkt;
|
||||
uint32_t voltage_pkt;
|
||||
@@ -26,6 +25,10 @@ struct __attribute__((packed)) health_t {
|
||||
float interrupt_load;
|
||||
uint8_t fan_power;
|
||||
uint8_t safety_rx_checks_invalid;
|
||||
uint16_t spi_checksum_error_count;
|
||||
uint8_t fan_stall_count;
|
||||
uint16_t sbu1_voltage_mV;
|
||||
uint16_t sbu2_voltage_mV;
|
||||
};
|
||||
|
||||
#define CAN_HEALTH_PACKET_VERSION 4
|
||||
@@ -38,11 +41,11 @@ typedef struct __attribute__((packed)) {
|
||||
uint8_t last_stored_error; // last LEC positive error code stored
|
||||
uint8_t last_data_error; // DLEC (for CANFD only)
|
||||
uint8_t last_data_stored_error; // last DLEC positive error code stored (for CANFD only)
|
||||
uint8_t receive_error_cnt; // REC
|
||||
uint8_t transmit_error_cnt; // TEC
|
||||
uint32_t total_error_cnt; // How many times any error interrupt were invoked
|
||||
uint32_t total_tx_lost_cnt; // Tx event FIFO element Lost
|
||||
uint32_t total_rx_lost_cnt; // Rx FIFO 0 message Lost
|
||||
uint8_t receive_error_cnt; // Actual state of the receive error counter, values between 0 and 127. FDCAN_ECR.REC
|
||||
uint8_t transmit_error_cnt; // Actual state of the transmit error counter, values between 0 and 255. FDCAN_ECR.TEC
|
||||
uint32_t total_error_cnt; // How many times any error interrupt was invoked
|
||||
uint32_t total_tx_lost_cnt; // Tx event FIFO element lost
|
||||
uint32_t total_rx_lost_cnt; // Rx FIFO 0 message lost due to FIFO full condition
|
||||
uint32_t total_tx_cnt;
|
||||
uint32_t total_rx_cnt;
|
||||
uint32_t total_fwd_cnt; // Messages forwarded from one bus to another
|
||||
|
||||
+16
-3
@@ -5,6 +5,7 @@
|
||||
#include "drivers/usb.h"
|
||||
#include "drivers/gmlan_alt.h"
|
||||
#include "drivers/kline_init.h"
|
||||
#include "drivers/simple_watchdog.h"
|
||||
|
||||
#include "early_init.h"
|
||||
#include "provision.h"
|
||||
@@ -143,6 +144,7 @@ void __attribute__ ((noinline)) enable_fpu(void) {
|
||||
|
||||
// called at 8Hz
|
||||
uint8_t loop_counter = 0U;
|
||||
uint8_t previous_harness_status = HARNESS_STATUS_NC;
|
||||
void tick_handler(void) {
|
||||
if (TICK_TIMER->SR != 0) {
|
||||
// siren
|
||||
@@ -150,6 +152,8 @@ void tick_handler(void) {
|
||||
|
||||
// tick drivers at 8Hz
|
||||
fan_tick();
|
||||
usb_tick();
|
||||
simple_watchdog_kick();
|
||||
|
||||
// decimated to 1Hz
|
||||
if (loop_counter == 0U) {
|
||||
@@ -177,8 +181,11 @@ void tick_handler(void) {
|
||||
current_board->set_led(LED_BLUE, (uptime_cnt & 1U) && (power_save_status == POWER_SAVE_STATUS_ENABLED));
|
||||
|
||||
// tick drivers at 1Hz
|
||||
harness_tick();
|
||||
|
||||
const bool recent_heartbeat = heartbeat_counter == 0U;
|
||||
current_board->board_tick(check_started(), usb_enumerated, recent_heartbeat);
|
||||
current_board->board_tick(check_started(), usb_enumerated, recent_heartbeat, ((harness.status != previous_harness_status) && (harness.status != HARNESS_STATUS_NC)));
|
||||
previous_harness_status = harness.status;
|
||||
|
||||
// increase heartbeat counter and cap it at the uint32 limit
|
||||
if (heartbeat_counter < __UINT32_MAX__) {
|
||||
@@ -194,7 +201,7 @@ void tick_handler(void) {
|
||||
siren_countdown -= 1U;
|
||||
}
|
||||
|
||||
if (controls_allowed) {
|
||||
if (controls_allowed || heartbeat_engaged) {
|
||||
controls_allowed_countdown = 30U;
|
||||
} else if (controls_allowed_countdown > 0U) {
|
||||
controls_allowed_countdown -= 1U;
|
||||
@@ -229,6 +236,9 @@ void tick_handler(void) {
|
||||
heartbeat_lost = true;
|
||||
}
|
||||
|
||||
// clear heartbeat engaged state
|
||||
heartbeat_engaged = false;
|
||||
|
||||
if (current_safety_mode != SAFETY_SILENT) {
|
||||
set_safety_mode(SAFETY_SILENT, 0U);
|
||||
}
|
||||
@@ -353,7 +363,7 @@ int main(void) {
|
||||
}
|
||||
|
||||
if (current_board->fan_max_rpm > 0U) {
|
||||
llfan_init();
|
||||
fan_init();
|
||||
}
|
||||
|
||||
microsecond_timer_init();
|
||||
@@ -364,6 +374,9 @@ int main(void) {
|
||||
// enable CAN TXs
|
||||
current_board->enable_can_transceivers(true);
|
||||
|
||||
// init watchdog for heartbeat loop, fed at 8Hz
|
||||
simple_watchdog_init(FAULT_HEARTBEAT_LOOP_WATCHDOG, (3U * 1000000U / 8U));
|
||||
|
||||
// 8Hz timer
|
||||
REGISTER_INTERRUPT(TICK_TIMER_IRQ, tick_handler, 10U, FAULT_INTERRUPT_RATE_TICK)
|
||||
tick_timer_init();
|
||||
|
||||
@@ -9,10 +9,10 @@ int get_health_pkt(void *dat) {
|
||||
struct health_t * health = (struct health_t*)dat;
|
||||
|
||||
health->uptime_pkt = uptime_cnt;
|
||||
health->voltage_pkt = adc_get_voltage();
|
||||
health->voltage_pkt = adc_get_mV(ADCCHAN_VIN) * VIN_READOUT_DIVIDER;
|
||||
health->current_pkt = current_board->read_current();
|
||||
|
||||
//Use the GPIO pin to determine ignition or use a CAN based logic
|
||||
// Use the GPIO pin to determine ignition or use a CAN based logic
|
||||
health->ignition_line_pkt = (uint8_t)(current_board->check_ignition());
|
||||
health->ignition_can_pkt = (uint8_t)(ignition_can);
|
||||
|
||||
@@ -23,7 +23,7 @@ int get_health_pkt(void *dat) {
|
||||
health->tx_buffer_overflow_pkt = tx_buffer_overflow;
|
||||
health->rx_buffer_overflow_pkt = rx_buffer_overflow;
|
||||
health->gmlan_send_errs_pkt = gmlan_send_errs;
|
||||
health->car_harness_status_pkt = car_harness_status;
|
||||
health->car_harness_status_pkt = harness.status;
|
||||
health->safety_mode_pkt = (uint8_t)(current_safety_mode);
|
||||
health->safety_param_pkt = current_safety_param;
|
||||
health->alternative_experience_pkt = alternative_experience;
|
||||
@@ -31,12 +31,18 @@ int get_health_pkt(void *dat) {
|
||||
health->heartbeat_lost_pkt = (uint8_t)(heartbeat_lost);
|
||||
health->safety_rx_checks_invalid = safety_rx_checks_invalid;
|
||||
|
||||
health->spi_checksum_error_count = spi_checksum_error_count;
|
||||
|
||||
health->fault_status_pkt = fault_status;
|
||||
health->faults_pkt = faults;
|
||||
|
||||
health->interrupt_load = interrupt_load;
|
||||
|
||||
health->fan_power = fan_state.power;
|
||||
health->fan_stall_count = fan_state.total_stall_count;
|
||||
|
||||
health->sbu1_voltage_mV = harness.sbu1_voltage_mV;
|
||||
health->sbu2_voltage_mV = harness.sbu2_voltage_mV;
|
||||
|
||||
return sizeof(*health);
|
||||
}
|
||||
|
||||
@@ -244,8 +244,8 @@ void TIM3_IRQ_Handler(void) {
|
||||
|
||||
void pedal(void) {
|
||||
// read/write
|
||||
pdl0 = adc_get(ADCCHAN_ACCEL0);
|
||||
pdl1 = adc_get(ADCCHAN_ACCEL1);
|
||||
pdl0 = adc_get_raw(ADCCHAN_ACCEL0);
|
||||
pdl1 = adc_get_raw(ADCCHAN_ACCEL1);
|
||||
|
||||
// write the pedal to the DAC
|
||||
if (state == NO_FAULT) {
|
||||
@@ -302,7 +302,7 @@ int main(void) {
|
||||
timer_init(TIM3, 15);
|
||||
NVIC_EnableIRQ(TIM3_IRQn);
|
||||
|
||||
watchdog_init();
|
||||
watchdog_init(WATCHDOG_50_MS);
|
||||
|
||||
print("**** INTERRUPTS ON ****\n");
|
||||
enable_interrupts();
|
||||
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import time
|
||||
import subprocess
|
||||
|
||||
from panda import Panda, PandaDFU
|
||||
|
||||
board_path = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
if __name__ == "__main__":
|
||||
subprocess.check_call(f"scons -C {board_path}/.. -j$(nproc) {board_path}", shell=True)
|
||||
|
||||
for s in Panda.list():
|
||||
print("putting", s, "in DFU mode")
|
||||
with Panda(serial=s) as p:
|
||||
p.reset(enter_bootstub=True)
|
||||
p.reset(enter_bootloader=True)
|
||||
|
||||
# wait for reset pandas to come back up
|
||||
time.sleep(1)
|
||||
|
||||
dfu_serials = PandaDFU.list()
|
||||
print(f"found {len(dfu_serials)} panda(s) in DFU - {dfu_serials}")
|
||||
for s in dfu_serials:
|
||||
print("flashing", s)
|
||||
PandaDFU(s).recover()
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
set -e
|
||||
|
||||
scons -u -j$(nproc)
|
||||
# Recovers panda from DFU mode only, use flash.sh after power cycling panda
|
||||
printf %b 'from python import Panda\nfor serial in Panda.list(): Panda(serial).reset(enter_bootstub=True); Panda(serial).reset(enter_bootloader=True)' | PYTHONPATH=.. python3
|
||||
sleep 1
|
||||
printf %b 'from python import PandaDFU\nfor serial in PandaDFU.list(): PandaDFU(serial).recover()' | PYTHONPATH=.. python3
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user