openpilot v0.9.1 release

date: 2023-02-17T21:02:50
master commit: 89f68bf0cbf53a81b0553d3816fdbe522f941fa1
This commit is contained in:
Vehicle Researcher
2023-02-17 21:02:51 +00:00
committed by Adeeb Shihadeh
parent 75c97aaf3f
commit bcd4bb4821
509 changed files with 11784 additions and 4912 deletions
+1
View File
@@ -52,6 +52,7 @@ selfdrive/sensord/_sensord
system/camerad/camerad
system/camerad/test/ae_gray_test
selfdrive/modeld/_modeld
selfdrive/modeld/_navmodeld
selfdrive/modeld/_dmonitoringmodeld
/src/
Vendored
+27 -7
View File
@@ -11,6 +11,9 @@ export SOURCE_DIR=${env.SOURCE_DIR}
export GIT_BRANCH=${env.GIT_BRANCH}
export GIT_COMMIT=${env.GIT_COMMIT}
export AZURE_TOKEN='${env.AZURE_TOKEN}'
export MAPBOX_TOKEN='${env.MAPBOX_TOKEN}'
export GIT_SSH_COMMAND="ssh -i /data/gitkey"
source ~/.bash_profile
if [ -f /TICI ]; then
@@ -47,20 +50,34 @@ pipeline {
TEST_DIR = "/data/openpilot"
SOURCE_DIR = "/data/openpilot_source/"
AZURE_TOKEN = credentials('azure_token')
MAPBOX_TOKEN = credentials('mapbox_token')
}
options {
timeout(time: 4, unit: 'HOURS')
timeout(time: 3, unit: 'HOURS')
disableConcurrentBuilds(abortPrevious: env.BRANCH_NAME != 'master')
}
stages {
stage('build release3') {
stage('build release3-staging') {
agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root' } }
when {
branch 'devel-staging'
}
steps {
phone_steps("tici-needs-can", [
["build release3-staging & dashcam3-staging", "PUSH=1 $SOURCE_DIR/release/build_release.sh"],
["build release3-staging & dashcam3-staging", "RELEASE_BRANCH=release3-staging DASHCAM_BRANCH=dashcam3-staging $SOURCE_DIR/release/build_release.sh"],
])
}
}
stage('build nightly') {
agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root' } }
when {
branch 'master-ci'
}
steps {
phone_steps("tici-needs-can", [
["build nightly", "RELEASE_BRANCH=nightly $SOURCE_DIR/release/build_release.sh"],
])
}
}
@@ -78,6 +95,7 @@ pipeline {
parallel {
/*
stage('simulator') {
agent {
dockerfile {
@@ -87,7 +105,8 @@ pipeline {
}
}
steps {
sh "git config --global --add safe.directory ${WORKSPACE}"
sh "git config --global --add safe.directory '*'"
sh "git submodule update --init --recursive"
sh "git lfs pull"
lock(resource: "", label: "simulator", inversePrecedence: true, quantity: 1) {
sh "${WORKSPACE}/tools/sim/build_container.sh"
@@ -104,6 +123,7 @@ pipeline {
}
}
}
*/
stage('build') {
agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root' } }
@@ -115,7 +135,6 @@ pipeline {
["build master-ci", "cd $SOURCE_DIR/release && TARGET_DIR=$TEST_DIR EXTRA_FILES='tools/' ./build_devel.sh"],
["build openpilot", "cd selfdrive/manager && ./build.py"],
["check dirty", "release/check-dirty.sh"],
["test manager", "python selfdrive/manager/test/test_manager.py"],
["onroad tests", "cd selfdrive/test/ && ./test_onroad.py"],
["test car interfaces", "cd selfdrive/car/tests/ && ./test_car_interfaces.py"],
])
@@ -141,6 +160,7 @@ pipeline {
["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 manager", "python selfdrive/manager/test/test_manager.py"],
])
}
}
@@ -148,7 +168,7 @@ pipeline {
stage('camerad-ar') {
agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root' } }
steps {
phone_steps("tici-ar0321", [
phone_steps("tici-ar0231", [
["build", "cd selfdrive/manager && ./build.py"],
["test camerad", "python system/camerad/test/test_camerad.py"],
["test exposure", "python system/camerad/test/test_exposure.py"],
@@ -186,7 +206,7 @@ pipeline {
steps {
phone_steps("tici-common", [
["build", "cd selfdrive/manager && ./build.py"],
["model replay", "cd selfdrive/test/process_replay && ./model_replay.py"],
["model replay", "cd selfdrive/test/process_replay && NO_NAV=1 ./model_replay.py"],
])
}
}
-4
View File
@@ -103,7 +103,6 @@ Directory Structure
├── opendbc # Files showing how to interpret data from cars
├── panda # Code used to communicate on CAN
├── third_party # External libraries
├── pyextra # Extra python packages
└── system # Generic services
├── camerad # Driver to capture images from the camera sensors
├── clocksd # Broadcasts current time
@@ -143,7 +142,4 @@ NO WARRANTY EXPRESSED OR IMPLIED.**
<img src="https://d1qb2nb5cznatu.cloudfront.net/startups/i/1061157-bc7e9bf3b246ece7322e6ffe653f6af8-medium_jpg.jpg?buster=1458363130" width="75"></img> <img src="https://cdn-images-1.medium.com/max/1600/1*C87EjxGeMPrkTuVRVWVg4w.png" width="225"></img>
[![openpilot tests](https://github.com/commaai/openpilot/workflows/openpilot%20tests/badge.svg?event=push)](https://github.com/commaai/openpilot/actions)
[![Total alerts](https://img.shields.io/lgtm/alerts/g/commaai/openpilot.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/commaai/openpilot/alerts/)
[![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/commaai/openpilot.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/commaai/openpilot/context:python)
[![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/commaai/openpilot.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/commaai/openpilot/context:cpp)
[![codecov](https://codecov.io/gh/commaai/openpilot/branch/master/graph/badge.svg)](https://codecov.io/gh/commaai/openpilot)
+21
View File
@@ -1,3 +1,24 @@
Version 0.9.1 (2023-02-28)
========================
* New driving model
* 30% improved height estimation resulting in better driving performance for tall cars
* Driver monitoring: removed timer resetting on user interaction if distracted
* UI updates
* Adjust alert volume using ambient noise level
* Driver monitoring icon shows driver's head pose
* German translation thanks to Vrabetz and CzokNorris!
* Cadillac Escalade 2017 support thanks to rickygilleland!
* Chevrolet Bolt EV 2022-23 support thanks to JasonJShuler!
* Genesis GV60 2023 support thanks to sunnyhaibin!
* Hyundai Tucson 2022-23 support
* Kia K5 Hybrid 2020 support thanks to sunnyhaibin!
* Kia Niro Hybrid 2023 support thanks to sunnyhaibin!
* Kia Sorento 2022-23 support thanks to sunnyhaibin!
* Kia Sorento Plug-in Hybrid 2022 support thanks to sunnyhaibin!
* Toyota C-HR 2021 support thanks to eFiniLan!
* Toyota C-HR Hybrid 2022 support thanks to Korben00!
* Volkswagen Crafter and MAN TGE 2017-23 support thanks to jyoung8607!
Version 0.9.0 (2022-11-21)
========================
* New driving model
+14 -18
View File
@@ -71,10 +71,10 @@ if arch == "aarch64" and AGNOS:
lenv = {
"PATH": os.environ['PATH'],
"LD_LIBRARY_PATH": [Dir(f"#third_party/acados/{arch}/lib").abspath],
"PYTHONPATH": Dir("#").abspath + ":" + Dir("#pyextra/").abspath,
"PYTHONPATH": Dir("#").abspath,
"ACADOS_SOURCE_DIR": Dir("#third_party/acados/include/acados").abspath,
"ACADOS_PYTHON_INTERFACE_PATH": Dir("#pyextra/acados_template").abspath,
"ACADOS_PYTHON_INTERFACE_PATH": Dir("#third_party/acados/acados_template").abspath,
"TERA_PATH": Dir("#").abspath + f"/third_party/acados/{arch}/t_renderer"
}
@@ -197,10 +197,6 @@ env = Environment(
"#third_party/libyuv/include",
"#third_party/json11",
"#third_party/curl/include",
"#third_party/libgralloc/include",
"#third_party/android_frameworks_native/include",
"#third_party/android_hardware_libhardware/include",
"#third_party/android_system_core/include",
"#third_party/linux/include",
"#third_party/snpe/include",
"#third_party/mapbox-gl-native-qt/include",
@@ -282,7 +278,7 @@ Export('envCython')
# Qt build environment
qt_env = env.Clone()
qt_modules = ["Widgets", "Gui", "Core", "Network", "Concurrent", "Multimedia", "Quick", "Qml", "QuickWidgets", "Location", "Positioning", "DBus"]
qt_modules = ["Widgets", "Gui", "Core", "Network", "Concurrent", "Multimedia", "Quick", "Qml", "QuickWidgets", "Location", "Positioning", "DBus", "Xml"]
qt_libs = []
if arch == "Darwin":
@@ -298,16 +294,20 @@ if arch == "Darwin":
qt_env["FRAMEWORKS"] += [f"Qt{m}" for m in qt_modules] + ["OpenGL"]
qt_env.AppendENVPath('PATH', os.path.join(qt_env['QTDIR'], "bin"))
else:
qt_env['QTDIR'] = "/usr"
qt_install_prefix = subprocess.check_output(['qmake', '-query', 'QT_INSTALL_PREFIX'], encoding='utf8').strip()
qt_install_headers = subprocess.check_output(['qmake', '-query', 'QT_INSTALL_HEADERS'], encoding='utf8').strip()
qt_env['QTDIR'] = qt_install_prefix
qt_dirs = [
f"/usr/include/{real_arch}-linux-gnu/qt5",
f"/usr/include/{real_arch}-linux-gnu/qt5/QtGui/5.12.8/QtGui",
f"{qt_install_headers}",
f"{qt_install_headers}/QtGui/5.12.8/QtGui",
]
qt_dirs += [f"/usr/include/{real_arch}-linux-gnu/qt5/Qt{m}" for m in qt_modules]
qt_dirs += [f"{qt_install_headers}/Qt{m}" for m in qt_modules]
qt_libs = [f"Qt5{m}" for m in qt_modules]
if arch == "larch64":
qt_libs += ["GLESv2", "wayland-client"]
qt_env.PrependENVPath('PATH', Dir("#third_party/qt5/larch64/bin/").abspath)
elif arch != "Darwin":
qt_libs += ["GL"]
@@ -384,10 +384,10 @@ rednose_config = {
if arch != "larch64":
rednose_config['to_build'].update({
'loc_4': ('#selfdrive/locationd/models/loc_kf.py', True, [], rednose_deps),
'lane': ('#selfdrive/locationd/models/lane_kf.py', True, [], rednose_deps),
'pos_computer_4': ('#rednose/helpers/lst_sq_computer.py', False, [], []),
'pos_computer_5': ('#rednose/helpers/lst_sq_computer.py', False, [], []),
'feature_handler_5': ('#rednose/helpers/feature_handler.py', False, [], []),
'lane': ('#xx/pipeline/lib/ekf/lane_kf.py', True, [], rednose_deps),
})
Export('rednose_config')
@@ -406,10 +406,10 @@ if arch != "Darwin":
# build submodules
SConscript([
'cereal/SConscript',
'body/board/SConscript',
'panda/board/SConscript',
'cereal/SConscript',
'opendbc/can/SConscript',
'panda/SConscript',
])
SConscript(['third_party/SConscript'])
@@ -419,7 +419,6 @@ SConscript(['common/transformations/SConscript'])
SConscript(['selfdrive/modeld/SConscript'])
SConscript(['selfdrive/controls/lib/cluster/SConscript'])
SConscript(['selfdrive/controls/lib/lateral_mpc_lib/SConscript'])
SConscript(['selfdrive/controls/lib/longitudinal_mpc_lib/SConscript'])
@@ -439,9 +438,6 @@ if arch in ['x86_64', 'Darwin'] or GetOption('extras'):
Export('opendbc')
SConscript(['tools/cabana/SConscript'])
if GetOption('test'):
SConscript('panda/tests/safety/SConscript')
external_sconscript = GetOption('external_sconscript')
if external_sconscript:
SConscript([external_sconscript])
+2
View File
@@ -40,6 +40,7 @@ void board_detect(void) {
board.led_portB = GPIOC;
board.can_addr_offset = 0x0U;
board.uds_offset = 0x0U;
} else if (hw_type == HW_TYPE_KNEE) {
board.hall_left.hall_portA = GPIOC;
@@ -77,6 +78,7 @@ void board_detect(void) {
board.led_portB = GPIOB;
board.can_addr_offset = KNEE_ADDR_OFFSET;
board.uds_offset = 0x10U;
#ifndef BOOTSTUB
MX_I2C_Init();
+18 -9
View File
@@ -6,10 +6,10 @@
#define BROADCAST_ADDR 0x7DFU
#define FALLBACK_ADDR 0x7E0U
#define FALLBACK_R_ADDR (FALLBACK_ADDR + OFFSET)
#define ECU_ADDR 0x720U
#define ECU_R_ADDR (ECU_ADDR + OFFSET)
#define DEBUG_ADDR 0x721U
#define DEBUG_R_ADDR (DEBUG_ADDR + OFFSET)
#define ENGINE_ADDR 0x720U
#define ENGINE_R_ADDR (ENGINE_ADDR + OFFSET)
#define DEBUG_ADDR 0x721U
#define DEBUG_R_ADDR (DEBUG_ADDR + OFFSET)
#include "drivers/llbxcan.h"
#include "uds.h"
@@ -24,6 +24,8 @@ extern board_t board;
extern uint32_t enter_bootloader_mode;
extern volatile uint32_t torque_cmd_timeout;
extern volatile uint32_t ignition_off_counter;
const uint8_t crc_poly = 0xD5U; // standard crc8
uint32_t current_idx = 0;
@@ -84,8 +86,9 @@ void can_send_msg(uint32_t addr, uint32_t dhr, uint32_t dlr, uint8_t len) {
}
void process_can(void) {
__disable_irq();
CAN_FIFOMailBox_TypeDef to_send;
if (board.CAN->TSR & CAN_TSR_TME0) {
if ((board.CAN->TSR & CAN_TSR_TME0) == CAN_TSR_TME0) {
if (can_pop(&can_tx_q, &to_send)) {
board.CAN->sTxMailBox[0].TDLR = to_send.RDLR;
board.CAN->sTxMailBox[0].TDHR = to_send.RDHR;
@@ -93,12 +96,13 @@ void process_can(void) {
board.CAN->sTxMailBox[0].TIR = to_send.RIR;
}
}
__enable_irq();
}
void can_rx(void) {
while ((board.CAN->RF0R & CAN_RF0R_FMP0) != 0) {
int address = board.CAN->sFIFOMailBox[0].RIR >> 21;
if (address == (int32_t)(0x250U + board.can_addr_offset)) {
uint32_t address = board.CAN->sFIFOMailBox[0].RIR >> 21;
if (address == (0x250U + board.can_addr_offset)) {
if ((GET_MAILBOX_BYTES_04(&board.CAN->sFIFOMailBox[0]) == 0xdeadface) && (GET_MAILBOX_BYTES_48(&board.CAN->sFIFOMailBox[0]) == 0x0ab00b1e)) {
enter_bootloader_mode = ENTER_SOFTLOADER_MAGIC;
NVIC_SystemReset();
@@ -121,7 +125,7 @@ void can_rx(void) {
current_idx = idx;
}
out_enable(LED_BLUE, true);
} else if (address == (int32_t)(0x251U + board.can_addr_offset)) {
} else if (address == (0x251U + board.can_addr_offset)) {
#define MSG_SPD_LEN 5
uint8_t dat[MSG_TRQ_LEN];
for (int i=0; i<MSG_TRQ_LEN; i++) {
@@ -139,11 +143,16 @@ void can_rx(void) {
}
}
out_enable(LED_BLUE, true);
} else if ((hw_type == HW_TYPE_BASE) && ((address == BROADCAST_ADDR) || (address == FALLBACK_ADDR) || (address == ECU_ADDR) || (address == DEBUG_ADDR))) { // Process UBS and OBD2 requests, ignore for knee
} else if ((address == BROADCAST_ADDR) || // Process UBS and OBD2 requests
(address == FALLBACK_ADDR) ||
(address == (ENGINE_ADDR + board.uds_offset)) ||
(address == (DEBUG_ADDR + board.uds_offset))) {
process_uds(address, GET_MAILBOX_BYTES_04(&board.CAN->sFIFOMailBox[0]));
out_enable(LED_BLUE, true);
} else if ((hw_type == HW_TYPE_BASE) && (address == 0x203U + KNEE_ADDR_OFFSET)) { // detect knee by body and set flag for use with UDS message
knee_detected = 1;
} else if ((hw_type == HW_TYPE_KNEE) && (address == 0x202U)) { // CAN based ignition for knee
ignition_off_counter = 0;
}
// next
board.CAN->RF0R |= CAN_RF0R_RFOM0;
+8 -6
View File
@@ -5,23 +5,25 @@
#include "stm32f4xx_hal.h"
#define CORE_FREQ 96000000U // MCU frequency in hertz
#define PWM_FREQ 16000 // PWM frequency in Hz / is also used for buzzer
#define DEAD_TIME 48 // PWM deadtime
#define DELAY_IN_MAIN_LOOP 5 // in ms. default 5. it is independent of all the timing critical stuff. do not touch if you do not know what you are doing.
#define A2BIT_CONV 50 // A to bit for current conversion on ADC. Example: 1 A = 50, 2 A = 100, etc
#define I2C_CLOCKSPEED 100 // I2C clock in kHz
#define PWM_FREQ 16000 // PWM frequency in Hz / is also used for buzzer
#define DEAD_TIME 48 // PWM deadtime
#define DELAY_IN_MAIN_LOOP 5 // in ms. default 5. it is independent of all the timing critical stuff. do not touch if you do not know what you are doing.
#define A2BIT_CONV 50 // A to bit for current conversion on ADC. Example: 1 A = 50, 2 A = 100, etc
#define IGNITION_OFF_DELAY 5 // Stop sending CAN messages after 5 seconds
#define ADC_CONV_CLOCK_CYCLES (ADC_SAMPLETIME_15CYCLES)
#define ADC_CLOCK_DIV (4)
#define ADC_TOTAL_CONV_TIME (ADC_CLOCK_DIV * ADC_CONV_CLOCK_CYCLES) // = ((SystemCoreClock / ADC_CLOCK_HZ) * ADC_CONV_CLOCK_CYCLES), where ADC_CLOCK_HZ = SystemCoreClock/ADC_CLOCK_DIV
#define KNEE_ADDR_OFFSET 0x100U
#define ANGLE_TO_DEGREES 0.021972656 // Convert 14 bit angle sensor output to degrees
#define GEARBOX_RATIO_LEFT 19
#define GEARBOX_RATIO_RIGHT 19
#define TRQ_LIMIT_LEFT 400 // Torque limit for knee gearbox(left)
#define TRQ_LIMIT_RIGHT 200 // Torque limit for hip gearbox(right)
#define KNEE_ADDR_OFFSET 0x100
#define BAT_FILT_COEF 655 // battery voltage filter coefficient in fixed-point. coef_fixedPoint = coef_floatingPoint * 2^16. In this case 655 = 0.01 * 2^16
#define BAT_CALIB_REAL_VOLTAGE 3192 // input voltage measured by multimeter (multiplied by 100). In this case 43.00 V * 100 = 4300
#define BAT_CALIB_ADC 1275 // adc-value measured by mainboard (value nr 5 on UART debug output)
+9 -1
View File
@@ -166,7 +166,8 @@ typedef struct {
GPIO_TypeDef* ignition_port;
uint16_t ignition_pin;
uint32_t can_addr_offset;
uint16_t can_addr_offset;
uint8_t uds_offset;
GPIO_TypeDef* led_portR;
uint16_t led_pinR;
@@ -177,4 +178,11 @@ typedef struct {
} board_t;
typedef struct {
uint8_t left_i2c : 1;
uint8_t left_angle : 1;
uint8_t right_i2c : 1;
uint8_t right_angle : 1;
} fault_status_t;
#endif // DEFINES_H
+15
View File
@@ -19,14 +19,29 @@ extern I2C_HandleTypeDef hi2c1;
const uint8_t init_imu_regaddr[] = {0x76, 0x4c, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53};
const uint8_t init_imu_data[] = {0x00, 0x12, 0x2f, 0x26, 0x67, 0x04, 0x00, 0x00};
fault_status_t fault_status = {0};
void angle_sensor_read(uint16_t *sensor_angle) {
if (fault_status.left_i2c && fault_status.right_i2c) { // Try to reinitialize halted I2C
if (HAL_I2C_Init(&hi2c1) == HAL_OK) {
fault_status.left_i2c = 0;
fault_status.right_i2c = 0;
}
}
uint8_t buf[2];
if (HAL_I2C_Mem_Read(&hi2c1, (AS5048_ADDRESS_LEFT<<1), AS5048B_ANGLMSB_REG, I2C_MEMADD_SIZE_8BIT, buf, 2, 10) == HAL_OK) {
sensor_angle[0] = (buf[0] << 6) | (buf[1] & 0x3F);
fault_status.left_i2c = 0;
} else {
fault_status.left_i2c = 1;
}
if (HAL_I2C_Mem_Read(&hi2c1, (AS5048_ADDRESS_RIGHT<<1), AS5048B_ANGLMSB_REG, I2C_MEMADD_SIZE_8BIT, buf, 2, 10) == HAL_OK) {
sensor_angle[1] = (buf[0] << 6) | (buf[1] & 0x3F);
fault_status.right_i2c = 0;
} else {
fault_status.right_i2c = 1;
}
}
+18 -18
View File
@@ -1,4 +1,4 @@
#define SW_I2C_WAIT_TIME 22
#define SW_I2C_WAIT_TIME 22
#define I2C_READ 0x01
#define READ_CMD 1
@@ -7,14 +7,14 @@
void SW_I2C_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure = { 0 };
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Pin = SW_I2C1_SCL_PIN;
HAL_GPIO_Init(SW_I2C1_SCL_GPIO, &GPIO_InitStructure);
GPIO_InitStructure.Pin = SW_I2C1_SDA_PIN;
GPIO_InitStructure.Pin = SW_I2C1_SDA_PIN;
HAL_GPIO_Init(SW_I2C1_SDA_GPIO, &GPIO_InitStructure);
}
@@ -24,7 +24,7 @@ uint8_t SW_I2C_ReadVal_SDA(void)
ret = (uint16_t)HAL_GPIO_ReadPin(SW_I2C1_SDA_GPIO, SW_I2C1_SDA_PIN);
return ret;
}
void sda_high(void)
{
HAL_GPIO_WritePin(SW_I2C1_SDA_GPIO, SW_I2C1_SDA_PIN, GPIO_PIN_SET);
@@ -59,23 +59,23 @@ void sda_out(uint8_t out)
void sda_in_mode(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure = { 0 };
GPIO_InitStructure.Speed=GPIO_SPEED_FREQ_HIGH;
GPIO_InitStructure.Mode=GPIO_MODE_INPUT;
GPIO_InitStructure.Pin = SW_I2C1_SDA_PIN;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
GPIO_InitStructure.Pin = SW_I2C1_SDA_PIN;
HAL_GPIO_Init(SW_I2C1_SDA_GPIO, &GPIO_InitStructure);
}
void sda_out_mode(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure = { 0 };
GPIO_InitStructure.Speed=GPIO_SPEED_FREQ_HIGH;
GPIO_InitStructure.Mode=GPIO_MODE_OUTPUT_OD;
GPIO_InitStructure.Pin = SW_I2C1_SDA_PIN;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStructure.Pin = SW_I2C1_SDA_PIN;
HAL_GPIO_Init(SW_I2C1_SDA_GPIO, &GPIO_InitStructure);
}
@@ -129,15 +129,15 @@ uint8_t i2c_check_ack(void)
delay(SW_I2C_WAIT_TIME);
for (i = 10; i > 0; i--) {
temp = !(SW_I2C_ReadVal_SDA());
if (temp)
temp = !(SW_I2C_ReadVal_SDA());
if (temp)
{
ack = 1;
break;
}
}
scl_low();
sda_out_mode();
sda_out_mode();
delay(SW_I2C_WAIT_TIME);
return ack;
+8 -7
View File
@@ -1,13 +1,11 @@
// maximum 500kbps! (or needs clock change)
// SAE 2284-3 : minimum 16 tq, SJW 3, sample point at 81.3%
#define CAN_QUANTA 16U
#define CAN_SEQ1 13U // roundf(quanta * 0.875f) - 1;
#define CAN_SEQ2 2U // roundf(quanta * 0.125f);
#define CAN_SEQ1 12U
#define CAN_SEQ2 3U
#define CAN_SJW 3U
#define CAN_PCLK (CORE_FREQ / 2U / 1000U)
// 333 = 33.3 kbps
// 5000 = 500 kbps
#define can_speed_to_prescaler(x) (CAN_PCLK / CAN_QUANTA * 10U / (x))
#define CAN_INIT_TIMEOUT_MS 500
bool llcan_set_speed(CAN_TypeDef *CAN_obj, uint32_t speed, bool loopback, bool silent) {
@@ -30,7 +28,10 @@ bool llcan_set_speed(CAN_TypeDef *CAN_obj, uint32_t speed, bool loopback, bool s
if(ret){
// set time quanta from defines
CAN_obj->BTR = ((CAN_BTR_TS1_0 * (CAN_SEQ1-1)) | (CAN_BTR_TS2_0 * (CAN_SEQ2-1)) | (can_speed_to_prescaler(speed) - 1U));
CAN_obj->BTR = ((CAN_BTR_TS1_0 * (CAN_SEQ1-1)) |
(CAN_BTR_TS2_0 * (CAN_SEQ2-1)) |
(CAN_BTR_SJW_0 * (CAN_SJW-1)) |
(can_speed_to_prescaler(speed) - 1U));
// silent loopback mode for debugging
if (loopback) {
+29 -13
View File
@@ -58,6 +58,9 @@ extern board_t board;
extern volatile uint32_t buzzerTimer;
volatile uint32_t torque_cmd_timeout = 0U;
volatile uint32_t ignition_off_counter = 0U;
uint16_t cnt_press = 0;
int16_t batVoltageCalib; // global variable for calibrated battery voltage
int16_t board_temp_deg_c; // global variable for calibrated temperature in degrees Celsius
volatile int16_t cmdL; // global variable for Left Command
@@ -66,9 +69,7 @@ volatile int16_t cmdR; // global variable for Right Command
uint8_t hw_type; // type of the board detected(0 - base, 3 - knee)
uint8_t ignition = 0; // global variable for ignition on SBU2 line
uint8_t charger_connected = 0; // status of the charger port
uint8_t fault_status = 0; // fault status of the whole system
uint8_t pkt_idx = 0; // For CAN msg counter
//------------------------------------------------------------------------
// Local variables
//------------------------------------------------------------------------
@@ -120,6 +121,7 @@ int main(void) {
} else {
out_enable(POWERSWITCH, false);
ignition = 1;
knee_detected = 1;
}
// Reset LEDs on startup
out_enable(LED_RED, false);
@@ -175,8 +177,10 @@ int main(void) {
if (hw_type == HW_TYPE_KNEE) {
// Safety to stop operation if angle sensor reading failed TODO: adjust sensivity and add lowpass to angle sensor?
if ((ABS((hall_angle_offset[0] + ((motPosL / 15 / GEARBOX_RATIO_LEFT) % 360)) - (sensor_angle[0] * ANGLE_TO_DEGREES)) > 5) ||
(ABS((hall_angle_offset[1] + ((motPosR / 15 / GEARBOX_RATIO_RIGHT) % 360)) - (sensor_angle[1] * ANGLE_TO_DEGREES)) > 5)) {
fault_status.left_angle = (ABS((hall_angle_offset[0] + ((motPosL / 15 / GEARBOX_RATIO_LEFT) % 360)) - (sensor_angle[0] * ANGLE_TO_DEGREES)) > 5);
fault_status.right_angle = (ABS((hall_angle_offset[1] + ((motPosR / 15 / GEARBOX_RATIO_RIGHT) % 360)) - (sensor_angle[1] * ANGLE_TO_DEGREES)) > 5);
if (fault_status.left_angle || fault_status.right_angle) {
cmdL = cmdR = 0;
}
// Safety to stop movement when reaching dead angles, around 20 and 340 degrees
@@ -211,7 +215,7 @@ int main(void) {
}
}
if (ignition_off_counter <= 10) {
if (ignition_off_counter <= IGNITION_OFF_DELAY) {
// MOTORS_DATA: speed_L(2), speed_R(2), counter(1), checksum(1)
uint8_t dat[8];
uint16_t speedL = rtY_Left.n_mot;
@@ -287,19 +291,15 @@ int main(void) {
// runs at 10Hz
if ((HAL_GetTick() - (main_loop_10Hz - main_loop_10Hz_runtime)) >= 100) {
main_loop_10Hz_runtime = HAL_GetTick();
if (ignition_off_counter <= 10) {
// VAR_VALUES: fault_status(0:6), enable_motors(0:1), ignition(0:1), left motor error(1), right motor error(1), global fault status(1)
if (ignition_off_counter <= IGNITION_OFF_DELAY) {
// VAR_VALUES: fault_status(0:4), enable_motors(0:1), ignition(0:1), left motor error(1), right motor error(1)
uint8_t dat[2];
dat[0] = (((fault_status & 0x3F) << 2U) | (enable_motors << 1U) | ignition);
dat[0] = ((fault_status.right_angle << 5U) | (fault_status.right_i2c << 4U) | (fault_status.left_angle << 3U) | (fault_status.left_i2c << 2U) | (enable_motors << 1U) | ignition);
dat[1] = rtY_Left.z_errCode;
dat[2] = rtY_Right.z_errCode;
can_send_msg((0x202U + board.can_addr_offset), 0x0U, ((dat[2] << 16U) | (dat[1] << 8U) | dat[0]), 3U);
}
out_enable(LED_GREEN, ignition);
if (hw_type == HW_TYPE_BASE) {
poweroffPressCheck();
}
main_loop_10Hz_runtime = HAL_GetTick() - main_loop_10Hz_runtime;
main_loop_10Hz = HAL_GetTick();
@@ -330,7 +330,7 @@ int main(void) {
out_enable(LED_BLUE, false); // Reset LED after CAN RX
out_enable(LED_GREEN, true); // Always use LED to show that body is on
if (ignition) {
if ((hw_type == HW_TYPE_BASE) && ignition) {
ignition_off_counter = 0;
} else {
ignition_off_counter = (ignition_off_counter < MAX_uint32_T) ? (ignition_off_counter+1) : 0;
@@ -341,6 +341,8 @@ int main(void) {
} else if (rtY_Left.z_errCode || rtY_Right.z_errCode) { // 1 beep (low pitch): Motor error, disable motors
enable_motors = 0;
beepCount(1, 24, 1);
} else if (fault_status.left_angle || fault_status.left_i2c || fault_status.right_angle || fault_status.right_i2c) { // 2 beeps (low pitch): Motor error, disable motors
beepCount(2, 24, 1);
} else if (TEMP_WARNING_ENABLE && board_temp_deg_c >= TEMP_WARNING) { // 5 beeps (low pitch): Mainboard temperature warning
beepCount(5, 24, 1);
} else if (batVoltage < BAT_LVL1) { // 1 beep fast (medium pitch): Low bat 1
@@ -357,6 +359,20 @@ int main(void) {
main_loop_1Hz = HAL_GetTick();
}
if (hw_type == HW_TYPE_BASE) {
if (HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN)) {
cnt_press += 1;
if (cnt_press == (2 * 1008)) {
poweroff();
}
} else if (cnt_press >= 10) {
ignition = !ignition;
out_enable(IGNITION, ignition);
beepShort(5);
cnt_press = 0;
}
}
process_can();
tick_prev = HAL_GetTick();
}
+3 -4
View File
@@ -8,7 +8,6 @@ TIM_HandleTypeDef htim_right;
TIM_HandleTypeDef htim_left;
ADC_HandleTypeDef hadc;
I2C_HandleTypeDef hi2c1;
// SPI_HandleTypeDef hspi3;
volatile adc_buf_t adc_buffer;
extern board_t board;
@@ -26,7 +25,7 @@ void MX_GPIO_Clocks_Init(void) {
}
void MX_GPIO_Common_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitTypeDef GPIO_InitStruct = { 0 };
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
@@ -167,7 +166,7 @@ void MX_GPIO_Common_Init(void) {
void MX_I2C_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitTypeDef GPIO_InitStruct = { 0 };
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
@@ -179,7 +178,7 @@ void MX_I2C_Init(void) {
__HAL_RCC_I2C1_CLK_ENABLE();
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 400000;
hi2c1.Init.ClockSpeed = (I2C_CLOCKSPEED * 1000);
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
+64 -57
View File
@@ -1,118 +1,125 @@
extern uint8_t hw_type;
void can_send_msg(uint32_t addr, uint32_t dhr, uint32_t dlr, uint8_t len);
uint8_t uid[10];
uint32_t uds_request = 0;
uint32_t uds_engine_request = 0;
uint32_t uds_debug_request = 0;
uint8_t knee_detected = 0;
uint8_t sep_time = 0;
void process_uds(uint32_t addr, uint32_t dlr) {
memcpy(uid, (void *)0x1FFF7A10U, 0xAU);
if ((addr == BROADCAST_ADDR) || (addr == FALLBACK_ADDR)) { // OBD2 broadcast request, redirect to UDS?
if ((hw_type == HW_TYPE_BASE) &&
((addr == BROADCAST_ADDR) ||
(addr == FALLBACK_ADDR))) { // OBD2 broadcast request, redirect to UDS?
switch(dlr) {
// VIN 09 OBD2
case 0x020902U:
can_send_msg(FALLBACK_R_ADDR, 0x4D4F4301U, 0x02491410U, 8U);
uds_request = 0xF190U;
uds_engine_request = 0xF190U;
break;
// VIN : F190 on broadcast
case 0x90F12203U:
can_send_msg(FALLBACK_R_ADDR, 0x4D4F4390U, 0xF1621410U, 8U);
break;
// VIN continue
case 0x30U:
can_send_msg(FALLBACK_R_ADDR, 0x5659444FU, 0x42414D21U, 8U);
can_send_msg(FALLBACK_R_ADDR, 0x314E4F49U, 0x53524522U, 8U);
default:
if ((dlr & 0xFF) == 0x30U) {
sep_time = (dlr >> 16U) & 0xFF;
delay(sep_time);
can_send_msg(FALLBACK_R_ADDR, 0x5659444FU, 0x42414D21U, 8U);
can_send_msg(FALLBACK_R_ADDR, 0x314E4F49U, 0x53524522U, 8U);
}
break;
}
} else if (addr == ECU_ADDR) { // UDS request to "main" ECU
} else if (addr == (ENGINE_ADDR + board.uds_offset)) { // UDS request to "main" ECU
switch(dlr) {
// TESTER PRESENT
case 0x3E02U:
can_send_msg(ECU_R_ADDR, 0x0U, 0x7E02U, 8U);
can_send_msg(ENGINE_R_ADDR + board.uds_offset, 0x0U, 0x7E02U, 8U);
break;
// DIAGNOSTIC SESSION CONTROL: DEFAULT
case 0x011002U:
can_send_msg(ECU_R_ADDR, 0x0U, 0x015002U, 8U);
can_send_msg(ENGINE_R_ADDR + board.uds_offset, 0x0U, 0x015002U, 8U);
break;
// DIAGNOSTIC SESSION CONTROL: EXTENDED
case 0x031002U:
can_send_msg(ECU_R_ADDR, 0x0U, 0x035002U, 8U);
can_send_msg(ENGINE_R_ADDR + board.uds_offset, 0x0U, 0x035002U, 8U);
break;
// APPLICATION SOFTWARE IDENTIFICATION : F181 (used for fingerprinting, firmware version)
case 0x81F12203U:
COMPILE_TIME_ASSERT(sizeof(version) == 6U);
can_send_msg(ECU_R_ADDR, ((version[2] << 24U) | (version[1] << 16U) | (version[0] << 8U) | 0x81U), 0xF1620910U, 8U);
uds_request = 0xF181U;
can_send_msg(ENGINE_R_ADDR + board.uds_offset, ((version[2] << 24U) | (version[1] << 16U) | (version[0] << 8U) | 0x81U), 0xF1620A10U, 8U);
uds_engine_request = 0xF181U;
break;
// ECU SERIAL NUMBER : F18C
case 0x8CF12203U:
can_send_msg(ECU_R_ADDR, ((uid[2] << 24U) | (uid[1] << 16U) | (uid[0] << 8U) | 0x8CU), 0xF1620D10U, 8U);
uds_request = 0xF18CU;
can_send_msg(ENGINE_R_ADDR + board.uds_offset, ((uid[2] << 24U) | (uid[1] << 16U) | (uid[0] << 8U) | 0x8CU), 0xF1620D10U, 8U);
uds_engine_request = 0xF18CU;
break;
// VIN : F190
case 0x90F12203U:
can_send_msg(ECU_R_ADDR, 0x4D4F4390U, 0xF1621410U, 8U);
uds_request = 0xF190U;
break;
// SYSTEM NAME OR ENGINE TYPE : F197
case 0x97F12203U:
can_send_msg(ECU_R_ADDR, 0x454C4597U, 0xF1620C10U, 8U);
uds_request = 0xF197U;
can_send_msg(ENGINE_R_ADDR + board.uds_offset, 0x4D4F4390U, 0xF1621410U, 8U);
uds_engine_request = 0xF190U;
break;
// FLOW CONTROL MESSAGE
case 0x30U:
switch(uds_request) {
// APPLICATION SOFTWARE IDENTIFICATION : F181
case 0xF181U:
can_send_msg(ECU_R_ADDR, 0x0U, ((version[5] << 24U) | (version[4] << 16U) | (version[3] << 8U) | 0x21U), 8U);
uds_request = 0;
break;
// ECU SERIAL NUMBER : F18C
case 0xF18CU:
can_send_msg(ECU_R_ADDR, ((uid[9] << 24U) | (uid[8] << 16U) | (uid[7]<< 8U) | uid[6]), ((uid[5] << 24U) | (uid[4] << 16U) | (uid[3] << 8U) | 0x21U), 8U);
uds_request = 0;
break;
// VIN : F190
case 0xF190U:
can_send_msg(ECU_R_ADDR, 0x5659444FU, 0x42414D21U, 8U);
can_send_msg(ECU_R_ADDR, 0x314E4F49U, 0x53524522U, 8U);
uds_request = 0;
break;
// SYSTEM NAME OR ENGINE TYPE : F197
case 0xF197U:
can_send_msg(ECU_R_ADDR, (((knee_detected + 0x30) << 16U) | 0x4349U), 0x52544321U, 8U);
uds_request = 0;
break;
default:
if ((dlr & 0xFF) == 0x30U) {
sep_time = (dlr >> 16U) & 0xFF;
delay(sep_time);
switch(uds_engine_request) {
// APPLICATION SOFTWARE IDENTIFICATION : F181
case 0xF181U:
can_send_msg(ENGINE_R_ADDR + board.uds_offset, (knee_detected + 0x61), ((version[5] << 24U) | (version[4] << 16U) | (version[3] << 8U) | 0x21U), 8U);
uds_engine_request = 0;
break;
// ECU SERIAL NUMBER : F18C
case 0xF18CU:
can_send_msg(ENGINE_R_ADDR + board.uds_offset, ((uid[9] << 24U) | (uid[8] << 16U) | (uid[7]<< 8U) | uid[6]), ((uid[5] << 24U) | (uid[4] << 16U) | (uid[3] << 8U) | 0x21U), 8U);
uds_engine_request = 0;
break;
// VIN : F190
case 0xF190U:
can_send_msg(ENGINE_R_ADDR + board.uds_offset, 0x5659444FU, 0x42414D21U, 8U);
can_send_msg(ENGINE_R_ADDR + board.uds_offset, 0x314E4F49U, 0x53524522U, 8U);
uds_engine_request = 0;
break;
}
}
break;
}
} else if (addr == DEBUG_ADDR) { // UDS request to "DEBUG" ECU
} else if (addr == (DEBUG_ADDR + board.uds_offset)) { // UDS request to "DEBUG" ECU
switch(dlr) {
// TESTER PRESENT
case 0x3E02U:
can_send_msg(DEBUG_R_ADDR, 0x0U, 0x7E02U, 8U);
can_send_msg(DEBUG_R_ADDR + board.uds_offset, 0x0U, 0x7E02U, 8U);
break;
// DIAGNOSTIC SESSION CONTROL: DEFAULT
case 0x011002U:
can_send_msg(DEBUG_R_ADDR, 0x0U, 0x015002U, 8U);
can_send_msg(DEBUG_R_ADDR + board.uds_offset, 0x0U, 0x015002U, 8U);
break;
// DIAGNOSTIC SESSION CONTROL: EXTENDED
case 0x031002U:
can_send_msg(DEBUG_R_ADDR, 0x0U, 0x035002U, 8U);
can_send_msg(DEBUG_R_ADDR + board.uds_offset, 0x0U, 0x035002U, 8U);
break;
// APPLICATION SOFTWARE IDENTIFICATION : F181 (used for git hash logging)
case 0x81F12203U:
COMPILE_TIME_ASSERT(sizeof(gitversion) == 8U);
can_send_msg(DEBUG_R_ADDR, ((gitversion[2] << 24U) | (gitversion[1] << 16U) | (gitversion[0] << 8U) | 0x81U), 0xF1620B10U, 8U);
uds_request = 0xF181U;
can_send_msg((DEBUG_R_ADDR + board.uds_offset), ((gitversion[2] << 24U) | (gitversion[1] << 16U) | (gitversion[0] << 8U) | 0x81U), 0xF1620B10U, 8U);
uds_debug_request = 0xF181U;
break;
case 0x30U:
switch(uds_request) {
// APPLICATION SOFTWARE IDENTIFICATION : F181
case 0xF181U:
can_send_msg(DEBUG_R_ADDR, ((gitversion[7]<< 8U) | gitversion[6]), ((gitversion[5] << 24U) | (gitversion[4] << 16U) | (gitversion[3] << 8U) | 0x21U), 8U);
uds_request = 0;
break;
default:
if ((dlr & 0xFF) == 0x30U) {
sep_time = (dlr >> 16U) & 0xFF;
delay(sep_time);
switch(uds_debug_request) {
// APPLICATION SOFTWARE IDENTIFICATION : F181
case 0xF181U:
can_send_msg((DEBUG_R_ADDR + board.uds_offset), ((gitversion[7]<< 8U) | gitversion[6]), ((gitversion[5] << 24U) | (gitversion[4] << 16U) | (gitversion[3] << 8U) | 0x21U), 8U);
uds_debug_request = 0;
break;
}
}
break;
}
-16
View File
@@ -175,22 +175,6 @@ void poweroff(void) {
}
}
void poweroffPressCheck(void) {
if(HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN)) {
uint16_t cnt_press = 0;
while(HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN)) {
HAL_Delay(10);
cnt_press++;
if (cnt_press == (2 * 100)) { poweroff(); }
}
if (cnt_press > 8) {
ignition = !ignition;
out_enable(IGNITION, ignition);
beepShort(5);
}
}
}
#define PULL_EFFECTIVE_DELAY 4096
uint8_t detect_with_pull(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, uint32_t mode) {
GPIO_InitTypeDef GPIO_InitStruct;
-1
View File
@@ -19,7 +19,6 @@ void calcAvgSpeed(void);
// Poweroff Functions
void poweroff(void);
void poweroffPressCheck(void);
// GPIO functions
uint8_t detect_with_pull(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, uint32_t mode);
+1 -1
View File
@@ -1 +1 @@
const uint8_t version[6] = "0.0.02";
const uint8_t version[6] = "0.3.00";
+1 -4
View File
@@ -1,6 +1,4 @@
gen
node_modules
package-lock.json
/gen/
*.tmp
*.pyc
__pycache__
@@ -18,4 +16,3 @@ services.h
.sconsign.dblite
libcereal_shared.*
.mypy_cache/
catch2/
+18 -11
View File
@@ -34,7 +34,7 @@ struct CarEvent @0x9b1657f34caf3ad3 {
buttonCancel @11;
buttonEnable @12;
pedalPressed @13; # exits active state
pedalPressedPreEnable @73; # added during pre-enable state for either pedal
preEnableStandstill @73; # added during pre-enable state with brake
gasPressedOverride @108; # added when user is pressing gas with no disengage on gas
steerOverride @114;
cruiseDisabled @14;
@@ -46,7 +46,6 @@ struct CarEvent @0x9b1657f34caf3ad3 {
controlsMismatch @22;
pcmEnable @23;
pcmDisable @24;
noTarget @25;
radarFault @26;
brakeHold @28;
parkBrake @29;
@@ -138,6 +137,7 @@ struct CarEvent @0x9b1657f34caf3ad3 {
modelLagWarningDEPRECATED @93;
startupOneplusDEPRECATED @82;
startupFuzzyFingerprintDEPRECATED @97;
noTargetDEPRECATED @25;
}
}
@@ -205,9 +205,6 @@ struct CarState {
# clutch (manual transmission only)
clutchPressed @28 :Bool;
# which packets this state came from
canMonoTimes @12: List(UInt64);
# blindspot sensors
leftBlindspot @33 :Bool; # Is there something blocking the left lane change
rightBlindspot @34 :Bool; # Is there something blocking the right lane change
@@ -267,9 +264,11 @@ struct CarState {
}
}
# deprecated
errorsDEPRECATED @0 :List(CarEvent.EventName);
brakeLightsDEPRECATED @19 :Bool;
steeringRateLimitedDEPRECATED @29 :Bool;
canMonoTimesDEPRECATED @12: List(UInt64);
}
# ******* radar state @ 20hz *******
@@ -278,9 +277,6 @@ struct RadarData @0x888ad6581cf0aacb {
errors @0 :List(Error);
points @1 :List(RadarPoint);
# which packets this state came from
canMonoTimes @2 :List(UInt64);
enum Error {
canError @0;
fault @1;
@@ -304,6 +300,9 @@ struct RadarData @0x888ad6581cf0aacb {
# some radars flag measurements VS estimates
measured @6 :Bool;
}
# deprecated
canMonoTimesDEPRECATED @2 :List(UInt64);
}
# ******* car controls @ 100hz *******
@@ -317,6 +316,9 @@ struct CarControl {
# Actuator commands as computed by controlsd
actuators @6 :Actuators;
leftBlinker @15: Bool;
rightBlinker @16: Bool;
# Any car specific rate limits or quirks applied by
# the CarController are reflected in actuatorsOutput
# and matches what is sent to the car
@@ -334,8 +336,12 @@ struct CarControl {
brake @1: Float32;
# range from -1.0 - 1.0
steer @2: Float32;
# value sent over can to the car
steerOutputCan @8: Float32;
steeringAngleDeg @3: Float32;
curvature @7: Float32;
speed @6: Float32; # m/s
accel @4: Float32; # m/s^2
longControlState @5: LongControlState;
@@ -346,7 +352,6 @@ struct CarControl {
stopping @2;
starting @3;
}
}
struct CruiseControl {
@@ -459,7 +464,7 @@ struct CarParams {
vEgoStarting @59 :Float32; # Speed at which the car goes into starting state
stoppingControl @31 :Bool; # Does the car allow full control even at lows speeds when stopping
steerControlType @34 :SteerControlType;
radarOffCan @35 :Bool; # True when radar objects aren't visible on CAN
radarUnavailable @35 :Bool; # True when radar objects aren't visible on CAN or aren't parsed out
stopAccel @60 :Float32; # Required acceleration to keep vehicle stationary
stoppingDecelRate @52 :Float32; # m/s^2/s while trying to stop
startAccel @32 :Float32; # Required acceleration to get car moving
@@ -577,7 +582,7 @@ struct CarParams {
subaruLegacy @22; # pre-Global platform
hyundaiLegacy @23;
hyundaiCommunity @24;
stellantisDEPRECATED @25; # Consolidated with Chrysler; may be recycled for the next new model
volkswagenMlb @25;
hongqi @26;
body @27;
hyundaiCanfd @28;
@@ -586,6 +591,7 @@ struct CarParams {
enum SteerControlType {
torque @0;
angle @1;
curvature @2;
}
enum TransmissionType {
@@ -605,6 +611,7 @@ struct CarParams {
request @5 :List(Data);
brand @6 :Text;
bus @7 :UInt8;
logging @8 :Bool;
}
enum Ecu {
+109 -17
View File
@@ -165,7 +165,7 @@ struct FrameData {
sensor @26 :ImageSensor;
enum ImageSensor {
unknown @0;
ar0321 @1;
ar0231 @1;
ox03c10 @2;
}
@@ -543,7 +543,6 @@ struct PeripheralState {
}
struct RadarState @0x9a185389d6fdd05f {
canMonoTimes @10 :List(UInt64);
mdMonoTime @6 :UInt64;
carStateMonoTime @11 :UInt64;
radarErrors @12 :List(Car.RadarData.Error);
@@ -578,6 +577,7 @@ struct RadarState @0x9a185389d6fdd05f {
calStatusDEPRECATED @2 :Int8;
calCycleDEPRECATED @8 :Int32;
calPercDEPRECATED @9 :Int8;
canMonoTimesDEPRECATED @10 :List(UInt64);
}
struct LiveCalibrationData {
@@ -614,7 +614,6 @@ struct LiveTracks {
struct ControlsState @0x97ff69c53601abf1 {
startMonoTime @48 :UInt64;
canMonoTimes @21 :List(UInt64);
longitudinalPlanMonoTime @28 :UInt64;
lateralPlanMonoTime @50 :UInt64;
@@ -654,10 +653,12 @@ struct ControlsState @0x97ff69c53601abf1 {
lateralControlState :union {
indiState @52 :LateralINDIState;
pidState @53 :LateralPIDState;
lqrState @55 :LateralLQRState;
angleState @58 :LateralAngleState;
debugState @59 :LateralDebugState;
torqueState @60 :LateralTorqueState;
curvatureState @65 :LateralCurvatureState;
lqrStateDEPRECATED @55 :LateralLQRState;
}
enum OpenpilotState @0xdbe58b96d2d1ac61 {
@@ -742,6 +743,18 @@ struct ControlsState @0x97ff69c53601abf1 {
steeringAngleDesiredDeg @4 :Float32;
}
struct LateralCurvatureState {
active @0 :Bool;
actualCurvature @1 :Float32;
desiredCurvature @2 :Float32;
error @3 :Float32;
p @4 :Float32;
i @5 :Float32;
f @6 :Float32;
output @7 :Float32;
saturated @8 :Bool;
}
struct LateralDebugState {
active @0 :Bool;
steeringAngleDeg @1 :Float32;
@@ -778,6 +791,7 @@ struct ControlsState @0x97ff69c53601abf1 {
jerkFactorDEPRECATED @12 :Float32;
steerOverrideDEPRECATED @20 :Bool;
steeringAngleDesiredDegDEPRECATED @29 :Float32;
canMonoTimesDEPRECATED @21 :List(UInt64);
}
struct ModelDataV2 {
@@ -1153,16 +1167,16 @@ struct ProcLog {
}
struct GnssMeasurements {
ubloxMonoTime @0 :UInt64;
measTime @0 :UInt64;
gpsWeek @1 :Int16;
gpsTimeOfWeek @2 :Float64;
correctedMeasurements @3 :List(CorrectedMeasurement);
positionECEF @4 :LiveLocationKalman.Measurement;
velocityECEF @5 :LiveLocationKalman.Measurement;
# Used for debugging:
positionFixECEF @6 :LiveLocationKalman.Measurement;
kalmanPositionECEF @4 :LiveLocationKalman.Measurement;
kalmanVelocityECEF @5 :LiveLocationKalman.Measurement;
positionECEF @6 :LiveLocationKalman.Measurement;
velocityECEF @7 :LiveLocationKalman.Measurement;
# Todo sync this with timing pulse of ublox
struct CorrectedMeasurement {
@@ -1188,14 +1202,14 @@ struct GnssMeasurements {
}
enum ConstellationId {
# Satellite Constellation using the Ublox gnssid as index
gps @0;
sbas @1;
galileo @2;
beidou @3;
imes @4;
qznss @5;
glonass @6;
# Satellite Constellation using the Ublox gnssid as index
gps @0;
sbas @1;
galileo @2;
beidou @3;
imes @4;
qznss @5;
glonass @6;
}
enum EphemerisSourceType {
@@ -1214,6 +1228,7 @@ struct UbloxGnss {
ionoData @2 :IonoData;
hwStatus @3 :HwStatus;
hwStatus2 @4 :HwStatus2;
glonassEphemeris @5 :GlonassEphemeris;
}
struct MeasurementReport {
@@ -1324,6 +1339,7 @@ struct UbloxGnss {
ionoAlpha @38 :List(Float64);
ionoBeta @39 :List(Float64);
towCount @40 :UInt32;
}
struct IonoData {
@@ -1378,6 +1394,44 @@ struct UbloxGnss {
flash @4;
}
}
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;
tk @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;
freqNum @28 :UInt32;
}
}
struct QcomGnss @0xde94674b07ae51c1 {
@@ -1951,6 +2005,30 @@ struct NavRoute {
}
}
struct MapRenderState {
locationMonoTime @0 :UInt64;
renderTime @1 :Float32;
frameId @2: UInt32;
}
struct NavModelData {
frameId @0 :UInt32;
modelExecutionTime @1 :Float32;
dspExecutionTime @2 :Float32;
features @3 :List(Float32);
# predicted future position
position @4 :XYData;
desirePrediction @5 :List(Float32);
# All SI units and in device frame
struct XYData {
x @0 :List(Float32);
y @1 :List(Float32);
xStd @2 :List(Float32);
yStd @3 :List(Float32);
}
}
struct EncodeData {
idx @0 :EncodeIndex;
data @1 :Data;
@@ -1961,6 +2039,15 @@ struct EncodeData {
struct UserFlag {
}
struct Microphone {
soundPressure @0 :Float32;
# uncalibrated, A-weighted
soundPressureWeighted @3 :Float32;
soundPressureWeightedDb @1 :Float32;
filteredSoundPressureWeightedDb @2 :Float32;
}
struct Event {
logMonoTime @0 :UInt64; # nanoseconds
valid @67 :Bool = true;
@@ -2010,6 +2097,7 @@ struct Event {
liveLocationKalman @72 :LiveLocationKalman;
modelV2 @75 :ModelDataV2;
driverStateV2 @92 :DriverStateV2;
navModel @104 :NavModelData;
# camera stuff, each camera state has a matching encode idx
roadCameraState @2 :FrameData;
@@ -2020,6 +2108,9 @@ struct Event {
wideRoadEncodeIdx @77 :EncodeIndex;
qRoadEncodeIdx @90 :EncodeIndex;
# microphone data
microphone @103 :Microphone;
# systems stuff
androidLog @20 :AndroidLogEntry;
managerState @78 :ManagerState;
@@ -2034,6 +2125,7 @@ struct Event {
navInstruction @82 :NavInstruction;
navRoute @83 :NavRoute;
navThumbnail @84: Thumbnail;
mapRenderState @105: MapRenderState;
# UI services
userFlag @93 :UserFlag;
+4 -4
View File
@@ -7,9 +7,9 @@
typedef void (*sighandler_t)(int sig);
#include "impl_msgq.h"
#include "impl_zmq.h"
#include "services.h"
#include "cereal/services.h"
#include "cereal/messaging/impl_msgq.h"
#include "cereal/messaging/impl_zmq.h"
std::atomic<bool> do_exit = false;
static void set_do_exit(int sig) {
@@ -57,7 +57,7 @@ int main(int argc, char** argv) {
}
std::map<SubSocket*, PubSocket*> sub2pub;
for (auto endpoint: get_services(whitelist_str, zmq_to_msgq)) {
for (auto endpoint : get_services(whitelist_str, zmq_to_msgq)) {
PubSocket * pub_sock;
SubSocket * sub_sock;
if (zmq_to_msgq) {
+2 -2
View File
@@ -5,8 +5,8 @@
#include <csignal>
#include <cerrno>
#include "services.h"
#include "impl_msgq.h"
#include "cereal/services.h"
#include "cereal/messaging/impl_msgq.h"
volatile sig_atomic_t msgq_do_exit = 0;
+5 -3
View File
@@ -1,8 +1,10 @@
#pragma once
#include "messaging.h"
#include "msgq.h"
#include <zmq.h>
#include <string>
#include <vector>
#include "cereal/messaging/messaging.h"
#include "cereal/messaging/msgq.h"
#define MAX_POLLERS 128
+2 -4
View File
@@ -4,10 +4,8 @@
#include <cstdlib>
#include <cerrno>
#include <zmq.h>
#include "services.h"
#include "impl_zmq.h"
#include "cereal/services.h"
#include "cereal/messaging/impl_zmq.h"
static int get_port(std::string endpoint) {
int port = -1;
+4 -1
View File
@@ -1,7 +1,10 @@
#pragma once
#include "messaging.h"
#include <zmq.h>
#include <string>
#include <vector>
#include "cereal/messaging/messaging.h"
#define MAX_POLLERS 128
+3 -3
View File
@@ -1,9 +1,9 @@
#include <cassert>
#include <iostream>
#include "messaging.h"
#include "impl_zmq.h"
#include "impl_msgq.h"
#include "cereal/messaging/messaging.h"
#include "cereal/messaging/impl_zmq.h"
#include "cereal/messaging/impl_msgq.h"
#ifdef __APPLE__
const bool MUST_USE_ZMQ = true;
+7 -2
View File
@@ -1,10 +1,15 @@
#pragma once
#include <cstddef>
#include <map>
#include <string>
#include <vector>
#include <utility>
#include <time.h>
#include <capnp/serialize.h>
#include "../gen/cpp/log.capnp.h"
#include "cereal/gen/cpp/log.capnp.h"
#ifdef __APPLE__
#define CLOCK_BOOTTIME CLOCK_MONOTONIC
@@ -18,7 +23,7 @@ class Context {
public:
virtual void * getRawContext() = 0;
static Context * create();
virtual ~Context(){};
virtual ~Context(){}
};
class Message {
+1 -1
View File
@@ -6,7 +6,7 @@ from libcpp.vector cimport vector
from libcpp cimport bool
cdef extern from "messaging.h":
cdef extern from "cereal/messaging/messaging.h":
cdef cppclass Context:
@staticmethod
Context * create()
+7 -3
View File
@@ -10,6 +10,7 @@
#include <csignal>
#include <random>
#include <string>
#include <limits>
#include <poll.h>
#include <sys/ioctl.h>
@@ -22,7 +23,7 @@
#include <stdio.h>
#include "msgq.h"
#include "cereal/messaging/msgq.h"
void sigusr2_handler(int signal) {
assert(signal == SIGUSR2);
@@ -30,7 +31,7 @@ void sigusr2_handler(int signal) {
uint64_t msgq_get_uid(void){
std::random_device rd("/dev/urandom");
std::uniform_int_distribution<uint64_t> distribution(0,std::numeric_limits<uint32_t>::max());
std::uniform_int_distribution<uint64_t> distribution(0, std::numeric_limits<uint32_t>::max());
#ifdef __APPLE__
// TODO: this doesn't work
@@ -76,7 +77,7 @@ void msgq_reset_reader(msgq_queue_t * q){
void msgq_wait_for_subscriber(msgq_queue_t *q){
while (*q->num_readers == 0){
;
// wait for subscriber
}
return;
@@ -320,9 +321,11 @@ int msgq_msg_ready(msgq_queue_t * q){
uint32_t read_cycles, read_pointer;
UNPACK64(read_cycles, read_pointer, *q->read_pointers[id]);
UNUSED(read_cycles);
uint32_t write_cycles, write_pointer;
UNPACK64(write_cycles, write_pointer, *q->write_pointer);
UNUSED(write_cycles);
// Check if new message is available
return (read_pointer != write_pointer);
@@ -350,6 +353,7 @@ int msgq_msg_recv(msgq_msg_t * msg, msgq_queue_t * q){
uint32_t write_cycles, write_pointer;
UNPACK64(write_cycles, write_pointer, *q->write_pointer);
UNUSED(write_cycles);
char * p = q->data + read_pointer;
+3 -1
View File
@@ -1,4 +1,5 @@
#pragma once
#include <cstdint>
#include <cstring>
#include <string>
@@ -8,8 +9,9 @@
#define NUM_READERS 12
#define ALIGN(n) ((n + (8 - 1)) & -8)
#define UNUSED(x) (void)x
#define UNPACK64(higher, lower, input) do {uint64_t tmp = input; higher = tmp >> 32; lower = tmp & 0xFFFFFFFF;} while (0)
#define PACK64(output, higher, lower) output = ((uint64_t)higher << 32 ) | ((uint64_t)lower & 0xFFFFFFFF)
#define PACK64(output, higher, lower) output = ((uint64_t)higher << 32) | ((uint64_t)lower & 0xFFFFFFFF)
struct msgq_header_t {
uint64_t num_readers;
+3 -3
View File
@@ -4,8 +4,8 @@
#include <string>
#include <mutex>
#include "services.h"
#include "messaging.h"
#include "cereal/services.h"
#include "cereal/messaging/messaging.h"
const bool SIMULATION = (getenv("SIMULATION") != nullptr) && (std::string(getenv("SIMULATION")) == "1");
@@ -116,7 +116,7 @@ void SubMaster::update(int timeout) {
void SubMaster::update_msgs(uint64_t current_time, const std::vector<std::pair<std::string, cereal::Event::Reader>> &messages){
if (++frame == UINT64_MAX) frame = 1;
for(auto &kv : messages) {
for (auto &kv : messages) {
auto m_find = services_.find(kv.first);
if (m_find == services_.end()){
continue;
+4 -1
View File
@@ -30,7 +30,7 @@ services = {
"temperatureSensor": (True, 100., 100),
"gpsNMEA": (True, 9.),
"deviceState": (True, 2., 1),
"can": (True, 100.),
"can": (True, 100., 1223), # decimation gives ~5 msgs in a full segment
"controlsState": (True, 100., 10),
"pandaStates": (True, 2., 1),
"peripheralState": (True, 2., 1),
@@ -74,8 +74,11 @@ services = {
"navInstruction": (True, 1., 10),
"navRoute": (True, 0.),
"navThumbnail": (True, 0.),
"navModel": (True, 2., 4.),
"mapRenderState": (True, 2., 1.),
"qRoadEncodeIdx": (False, 20.),
"userFlag": (True, 0., 1),
"microphone": (True, 10., 10),
# debug
"uiDebug": (True, 0., 1),
+1 -1
View File
@@ -15,7 +15,7 @@
#define getsocket() socket(AF_UNIX, SOCK_SEQPACKET, 0)
#endif
#include "ipc.h"
#include "cereal/visionipc/ipc.h"
int ipc_connect(const char* socket_path) {
int err;
+1 -1
View File
@@ -1,4 +1,4 @@
#include "visionbuf.h"
#include "cereal/visionipc/visionbuf.h"
#define ALIGN(x, align) (((x) + (align)-1) & ~((align)-1))
+2 -1
View File
@@ -1,5 +1,6 @@
#pragma once
#include "visionipc.h"
#include "cereal/visionipc/visionipc.h"
#define CL_USE_DEPRECATED_OPENCL_1_2_APIS
#ifdef __APPLE__
+1 -1
View File
@@ -1,4 +1,4 @@
#include "visionbuf.h"
#include "cereal/visionipc/visionbuf.h"
#include <atomic>
#include <stdio.h>
+1 -1
View File
@@ -14,7 +14,7 @@
#include <msm_ion.h>
#include "visionbuf.h"
#include "cereal/visionipc/visionbuf.h"
// keep trying if x gets interrupted by a signal
#define HANDLE_EINTR(x) \
+4 -4
View File
@@ -6,7 +6,7 @@ from libcpp.vector cimport vector
from libc.stdint cimport uint32_t, uint64_t
from libcpp cimport bool
cdef extern from "visionbuf.h":
cdef extern from "cereal/visionipc/visionbuf.h":
cdef enum VisionStreamType:
pass
@@ -19,13 +19,13 @@ cdef extern from "visionbuf.h":
size_t uv_offset
void set_frame_id(uint64_t id)
cdef extern from "visionipc.h":
cdef extern from "cereal/visionipc/visionipc.h":
struct VisionIpcBufExtra:
uint32_t frame_id
uint64_t timestamp_sof
uint64_t timestamp_eof
cdef extern from "visionipc_server.h":
cdef extern from "cereal/visionipc/visionipc_server.h":
cdef cppclass VisionIpcServer:
VisionIpcServer(string, void*, void*)
void create_buffers(VisionStreamType, size_t, bool, size_t, size_t)
@@ -34,7 +34,7 @@ cdef extern from "visionipc_server.h":
void send(VisionBuf *, VisionIpcBufExtra *, bool)
void start_listener()
cdef extern from "visionipc_client.h":
cdef extern from "cereal/visionipc/visionipc_client.h":
cdef cppclass VisionIpcClient:
VisionIpcClient(string, VisionStreamType, bool, void*, void*)
VisionBuf * recv(VisionIpcBufExtra *, int)
+33 -20
View File
@@ -3,10 +3,21 @@
#include <iostream>
#include <thread>
#include "visionipc/ipc.h"
#include "visionipc/visionipc_client.h"
#include "visionipc/visionipc_server.h"
#include "logger/logger.h"
#include "cereal/visionipc/ipc.h"
#include "cereal/visionipc/visionipc_client.h"
#include "cereal/visionipc/visionipc_server.h"
#include "cereal/logger/logger.h"
static int connect_to_vipc_server(const std::string &name, bool blocking) {
std::string path = "/tmp/visionipc_" + name;
int socket_fd = ipc_connect(path.c_str());
while (socket_fd < 0 && blocking) {
std::cout << "VisionIpcClient connecting" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
socket_fd = ipc_connect(path.c_str());
}
return socket_fd;
}
VisionIpcClient::VisionIpcClient(std::string name, VisionStreamType type, bool conflate, cl_device_id device_id, cl_context ctx) : name(name), type(type), device_id(device_id), ctx(ctx) {
msg_ctx = Context::create();
@@ -29,23 +40,10 @@ bool VisionIpcClient::connect(bool blocking){
num_buffers = 0;
// Connect to server socket and ask for all FDs of type
std::string path = "/tmp/visionipc_" + name;
int socket_fd = -1;
while (socket_fd < 0) {
socket_fd = ipc_connect(path.c_str());
if (socket_fd < 0) {
if (blocking){
std::cout << "VisionIpcClient connecting" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
} else {
return false;
}
}
int socket_fd = connect_to_vipc_server(name, blocking);
if (socket_fd < 0) {
return false;
}
// Send stream type to server to request FDs
int r = ipc_sendrecv_with_fds(true, socket_fd, &type, sizeof(type), nullptr, 0, nullptr);
assert(r == sizeof(type));
@@ -114,7 +112,22 @@ VisionBuf * VisionIpcClient::recv(VisionIpcBufExtra * extra, const int timeout_m
return buf;
}
std::set<VisionStreamType> VisionIpcClient::getAvailableStreams(const std::string &name, bool blocking) {
int socket_fd = connect_to_vipc_server(name, blocking);
if (socket_fd < 0) {
return {};
}
// Send VISION_STREAM_MAX to server to request available streams
int request = VISION_STREAM_MAX;
int r = ipc_sendrecv_with_fds(true, socket_fd, &request, sizeof(request), nullptr, 0, nullptr);
assert(r == sizeof(request));
VisionStreamType available_streams[VISION_STREAM_MAX] = {};
r = ipc_sendrecv_with_fds(false, socket_fd, &available_streams, sizeof(available_streams), nullptr, 0, nullptr);
assert(r >= sizeof(VisionStreamType) && r % sizeof(VisionStreamType) == 0);
close(socket_fd);
return std::set<VisionStreamType>(available_streams, available_streams + r / sizeof(VisionStreamType));
}
VisionIpcClient::~VisionIpcClient(){
for (size_t i = 0; i < num_buffers; i++){
+8 -6
View File
@@ -1,11 +1,13 @@
#pragma once
#include <vector>
#include <set>
#include <string>
#include <vector>
#include <unistd.h>
#include "messaging/messaging.h"
#include "visionipc/visionipc.h"
#include "visionipc/visionbuf.h"
#include "cereal/messaging/messaging.h"
#include "cereal/visionipc/visionipc.h"
#include "cereal/visionipc/visionbuf.h"
class VisionIpcClient {
private:
@@ -14,8 +16,6 @@ private:
SubSocket * sock;
Poller * poller;
VisionStreamType type;
cl_device_id device_id = nullptr;
cl_context ctx = nullptr;
@@ -23,6 +23,7 @@ private:
public:
bool connected = false;
VisionStreamType type;
int num_buffers = 0;
VisionBuf buffers[VISIONIPC_MAX_FDS];
VisionIpcClient(std::string name, VisionStreamType type, bool conflate, cl_device_id device_id=nullptr, cl_context ctx=nullptr);
@@ -30,4 +31,5 @@ public:
VisionBuf * recv(VisionIpcBufExtra * extra=nullptr, const int timeout_ms=100);
bool connect(bool blocking=true);
bool is_connected() { return connected; }
static std::set<VisionStreamType> getAvailableStreams(const std::string &name, bool blocking = true);
};
+21 -7
View File
@@ -2,15 +2,16 @@
#include <chrono>
#include <cassert>
#include <random>
#include <limits>
#include <poll.h>
#include <sys/socket.h>
#include <unistd.h>
#include "messaging/messaging.h"
#include "visionipc/ipc.h"
#include "visionipc/visionipc_server.h"
#include "logger/logger.h"
#include "cereal/messaging/messaging.h"
#include "cereal/visionipc/ipc.h"
#include "cereal/visionipc/visionipc_server.h"
#include "cereal/logger/logger.h"
std::string get_endpoint_name(std::string name, VisionStreamType type){
if (messaging_use_zmq()){
@@ -25,7 +26,7 @@ VisionIpcServer::VisionIpcServer(std::string name, cl_device_id device_id, cl_co
msg_ctx = Context::create();
std::random_device rd("/dev/urandom");
std::uniform_int_distribution<uint64_t> distribution(0,std::numeric_limits<uint64_t>::max());
std::uniform_int_distribution<uint64_t> distribution(0, std::numeric_limits<uint64_t>::max());
server_id = distribution(rd);
}
@@ -111,6 +112,19 @@ void VisionIpcServer::listener(){
VisionStreamType type = VisionStreamType::VISION_STREAM_MAX;
int r = ipc_sendrecv_with_fds(false, fd, &type, sizeof(type), nullptr, 0, nullptr);
assert(r == sizeof(type));
// send available stream types
if (type == VisionStreamType::VISION_STREAM_MAX) {
std::vector<VisionStreamType> available_stream_types;
for (auto& [stream_type, _] : buffers) {
available_stream_types.push_back(stream_type);
}
r = ipc_sendrecv_with_fds(true, fd, available_stream_types.data(), available_stream_types.size() * sizeof(VisionStreamType), nullptr, 0, nullptr);
assert(r == available_stream_types.size() * sizeof(VisionStreamType));
close(fd);
continue;
}
if (buffers.count(type) <= 0) {
std::cout << "got request for invalid buffer type: " << type << std::endl;
close(fd);
@@ -174,7 +188,7 @@ VisionIpcServer::~VisionIpcServer(){
listener_thread.join();
// VisionBuf cleanup
for( auto const& [type, buf] : buffers ) {
for (auto const& [type, buf] : buffers) {
for (VisionBuf* b : buf){
if (b->free() != 0) {
LOGE("Failed to free buffer");
@@ -184,7 +198,7 @@ VisionIpcServer::~VisionIpcServer(){
}
// Messaging cleanup
for( auto const& [type, sock] : sockets ) {
for (auto const& [type, sock] : sockets) {
delete sock;
}
delete msg_ctx;
+3 -3
View File
@@ -5,9 +5,9 @@
#include <atomic>
#include <map>
#include "messaging/messaging.h"
#include "visionipc/visionipc.h"
#include "visionipc/visionbuf.h"
#include "cereal/messaging/messaging.h"
#include "cereal/visionipc/visionipc.h"
#include "cereal/visionipc/visionbuf.h"
std::string get_endpoint_name(std::string name, VisionStreamType type);
+13 -2
View File
@@ -2,8 +2,8 @@
#include <chrono>
#include "catch2/catch.hpp"
#include "visionipc_server.h"
#include "visionipc_client.h"
#include "cereal/visionipc/visionipc_server.h"
#include "cereal/visionipc/visionipc_client.h"
static void zmq_sleep(int milliseconds=1000){
if (messaging_use_zmq()){
@@ -22,6 +22,17 @@ TEST_CASE("Connecting"){
REQUIRE(client.connected);
}
TEST_CASE("getAvailableStreams"){
VisionIpcServer server("camerad");
server.create_buffers(VISION_STREAM_ROAD, 1, false, 100, 100);
server.create_buffers(VISION_STREAM_WIDE_ROAD, 1, false, 100, 100);
server.start_listener();
auto available_streams = VisionIpcClient::getAvailableStreams("camerad");
REQUIRE(available_streams.size() == 2);
REQUIRE(available_streams.count(VISION_STREAM_ROAD) == 1);
REQUIRE(available_streams.count(VISION_STREAM_WIDE_ROAD) == 1);
}
TEST_CASE("Check buffers"){
size_t width = 100, height = 200, num_buffers = 5;
VisionIpcServer server("camerad");
+3 -1
View File
@@ -10,11 +10,13 @@ common_libs = [
'statlog.cc',
'swaglog.cc',
'util.cc',
'gpio.cc',
'i2c.cc',
'watchdog.cc',
]
if arch != "Darwin":
common_libs.append('gpio.cc')
_common = fxn('common', common_libs, LIBS="json11")
files = [
+13 -11
View File
@@ -5,6 +5,7 @@
#include <memory>
#include "common/util.h"
#include "common/swaglog.h"
namespace { // helper functions
@@ -31,14 +32,14 @@ void cl_print_info(cl_platform_id platform, cl_device_id device) {
case CL_DEVICE_TYPE_ACCELERATOR: type_str = "CL_DEVICE_TYPE_ACCELERATOR"; break;
}
std::cout << "vendor: " << get_platform_info(platform, CL_PLATFORM_VENDOR) << std::endl
<< "platform version: " << get_platform_info(platform, CL_PLATFORM_VERSION) << std::endl
<< "profile: " << get_platform_info(platform, CL_PLATFORM_PROFILE) << std::endl
<< "extensions: " << get_platform_info(platform, CL_PLATFORM_EXTENSIONS) << std::endl
<< "name :" << get_device_info(device, CL_DEVICE_NAME) << std::endl
<< "device version :" << get_device_info(device, CL_DEVICE_VERSION) << std::endl
<< "max work group size :" << work_group_size << std::endl
<< "type = " << device_type << " = " << type_str << std::endl;
LOGD("vendor: %s", get_platform_info(platform, CL_PLATFORM_VENDOR).c_str());
LOGD("platform version: %s", get_platform_info(platform, CL_PLATFORM_VERSION).c_str());
LOGD("profile: %s", get_platform_info(platform, CL_PLATFORM_PROFILE).c_str());
LOGD("extensions: %s", get_platform_info(platform, CL_PLATFORM_EXTENSIONS).c_str());
LOGD("name: %s", get_device_info(device, CL_DEVICE_NAME).c_str());
LOGD("device version: %s", get_device_info(device, CL_DEVICE_VERSION).c_str());
LOGD("max work group size: %d", work_group_size);
LOGD("type = %d = ", device_type, type_str);
}
void cl_print_build_errors(cl_program program, cl_device_id device) {
@@ -49,7 +50,7 @@ void cl_print_build_errors(cl_program program, cl_device_id device) {
std::string log(log_size, '\0');
clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, log_size, &log[0], NULL);
std::cout << "build failed; status=" << status << ", log:" << std::endl << log << std::endl;
LOGE("build failed; status=%d, log: %s", status, log.c_str());
}
} // namespace
@@ -61,14 +62,15 @@ cl_device_id cl_get_device_id(cl_device_type device_type) {
CL_CHECK(clGetPlatformIDs(num_platforms, &platform_ids[0], NULL));
for (size_t i = 0; i < num_platforms; ++i) {
std::cout << "platform[" << i << "] CL_PLATFORM_NAME: " << get_platform_info(platform_ids[i], CL_PLATFORM_NAME) << std::endl;
LOGD("platform[%d] CL_PLATFORM_NAME: %s", i, get_platform_info(platform_ids[i], CL_PLATFORM_NAME).c_str());
// Get first device
if (cl_device_id device_id = NULL; clGetDeviceIDs(platform_ids[i], device_type, 1, &device_id, NULL) == 0 && device_id) {
cl_print_info(platform_ids[i], device_id);
return device_id;
}
}
std::cout << "No valid openCL platform found" << std::endl;
LOGE("No valid openCL platform found");
assert(0);
return nullptr;
}
+17
View File
@@ -1,5 +1,20 @@
#include "common/gpio.h"
#ifdef __APPLE__
int gpio_init(int pin_nr, bool output) {
return 0;
}
int gpio_set(int pin_nr, bool high) {
return 0;
}
int gpiochip_get_ro_value_fd(const char* consumer_label, int gpiochiop_id, int pin_nr) {
return 0;
}
#else
#include <fcntl.h>
#include <unistd.h>
@@ -63,3 +78,5 @@ int gpiochip_get_ro_value_fd(const char* consumer_label, int gpiochiop_id, int p
close(fd);
return rq.fd;
}
#endif
+7 -3
View File
@@ -104,13 +104,14 @@ std::unordered_map<std::string, uint32_t> keys = {
{"DisablePowerDown", PERSISTENT},
{"ExperimentalMode", PERSISTENT},
{"ExperimentalModeConfirmed", PERSISTENT},
{"ExperimentalLongitudinalEnabled", PERSISTENT}, // WARNING: THIS MAY DISABLE AEB
{"ExperimentalLongitudinalEnabled", PERSISTENT},
{"DisableUpdates", PERSISTENT},
{"DisengageOnAccelerator", PERSISTENT},
{"DongleId", PERSISTENT},
{"DoReboot", CLEAR_ON_MANAGER_START},
{"DoShutdown", CLEAR_ON_MANAGER_START},
{"DoUninstall", CLEAR_ON_MANAGER_START},
{"FirmwareObdQueryDone", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
{"ForcePowerDown", CLEAR_ON_MANAGER_START},
{"GitBranch", PERSISTENT},
{"GitCommit", PERSISTENT},
@@ -134,9 +135,10 @@ std::unordered_map<std::string, uint32_t> keys = {
{"IsRhdDetected", PERSISTENT},
{"IsTakingSnapshot", CLEAR_ON_MANAGER_START},
{"IsTestedBranch", CLEAR_ON_MANAGER_START},
{"IsReleaseBranch", CLEAR_ON_MANAGER_START},
{"IsUpdateAvailable", CLEAR_ON_MANAGER_START},
{"JoystickDebugMode", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF},
{"LaikadEphemeris", PERSISTENT | DONT_LOG},
{"LaikadEphemerisV2", PERSISTENT | DONT_LOG},
{"LanguageSetting", PERSISTENT},
{"LastAthenaPingTime", CLEAR_ON_MANAGER_START},
{"LastGPSPosition", PERSISTENT},
@@ -149,9 +151,11 @@ std::unordered_map<std::string, uint32_t> keys = {
{"LiveTorqueCarParams", PERSISTENT},
{"LiveTorqueParameters", PERSISTENT | DONT_LOG},
{"NavDestination", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF},
{"NavDestinationWaypoints", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF},
{"NavSettingTime24h", PERSISTENT},
{"NavSettingLeftSide", PERSISTENT},
{"NavdRender", PERSISTENT},
{"ObdMultiplexingDisabled", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
{"OpenpilotEnabledToggle", PERSISTENT},
{"PandaHeartbeatLost", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF},
{"PandaSignatures", CLEAR_ON_MANAGER_START},
@@ -168,7 +172,7 @@ std::unordered_map<std::string, uint32_t> keys = {
{"Timezone", PERSISTENT},
{"TrainingVersion", PERSISTENT},
{"UbloxAvailable", PERSISTENT},
{"UpdateAvailable", CLEAR_ON_MANAGER_START},
{"UpdateAvailable", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
{"UpdateFailedCount", CLEAR_ON_MANAGER_START},
{"UpdaterState", CLEAR_ON_MANAGER_START},
{"UpdaterFetchAvailable", CLEAR_ON_MANAGER_START},
+34
View File
@@ -0,0 +1,34 @@
#pragma once
#include <cassert>
#include <string>
#include "common/params.h"
#include "common/util.h"
class OpenpilotPrefix {
public:
OpenpilotPrefix(std::string prefix = {}) {
if (prefix.empty()) {
prefix = util::random_string(15);
}
msgq_path = "/dev/shm/" + prefix;
bool ret = util::create_directories(msgq_path, 0777);
assert(ret);
setenv("OPENPILOT_PREFIX", prefix.c_str(), 1);
}
~OpenpilotPrefix() {
auto param_path = Params().getParamPath();
if (util::file_exists(param_path)) {
std::string real_path = util::readlink(param_path);
system(util::string_format("rm %s -rf", real_path.c_str()).c_str());
unlink(param_path.c_str());
}
system(util::string_format("rm %s -rf", msgq_path.c_str()).c_str());
unsetenv("OPENPILOT_PREFIX");
}
private:
std::string msgq_path;
};
+13
View File
@@ -10,6 +10,7 @@
#include <dirent.h>
#include <fstream>
#include <iomanip>
#include <random>
#include <sstream>
#ifdef __linux__
@@ -228,6 +229,18 @@ std::string hexdump(const uint8_t* in, const size_t size) {
return ss.str();
}
std::string random_string(std::string::size_type length) {
const char* chrs = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
std::mt19937 rg{std::random_device{}()};
std::uniform_int_distribution<std::string::size_type> pick(0, sizeof(chrs) - 2);
std::string s;
s.reserve(length);
while (length--) {
s += chrs[pick(rg)];
}
return s;
}
std::string dir_name(std::string const &path) {
size_t pos = path.find_last_of("/");
if (pos == std::string::npos) return "";
+1
View File
@@ -75,6 +75,7 @@ int getenv(const char* key, int default_val);
float getenv(const char* key, float default_val);
std::string hexdump(const uint8_t* in, const size_t size);
std::string random_string(std::string::size_type length);
std::string dir_name(std::string const& path);
// **** file fhelpers *****
+1 -1
View File
@@ -1 +1 @@
#define COMMA_VERSION "0.9.0"
#define COMMA_VERSION "0.9.1"
+249 -226
View File
@@ -4,236 +4,259 @@
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.
# 215 Supported Cars
# 237 Supported Cars
|Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Resume from stop|Harness|
|---|---|---|:---:|:---:|:---:|:---:|:---:|:---:|
|Acura|ILX 2016-19|AcuraWatch Plus|openpilot|25 mph|25 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Nidec|
|Acura|RDX 2016-18|AcuraWatch Plus|openpilot|25 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Nidec|
|Acura|RDX 2019-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Bosch A|
|Audi|A3 2014-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Audi|A3 Sportback e-tron 2017-18|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Audi|Q2 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Audi|Q3 2019-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Audi|RS3 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Audi|S3 2015-17|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Cadillac|Escalade ESV 2016[<sup>3</sup>](#footnotes)|Adaptive Cruise Control (ACC) & LKAS|openpilot|0 mph|6 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|OBD-II|
|Chevrolet|Bolt EUV 2022-23|Premier or Premier Redline Trim without Super Cruise Package|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|GM|
|Chevrolet|Silverado 1500 2020-21|Safety Package II|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|GM|
|Chevrolet|Volt 2017-18[<sup>3</sup>](#footnotes)|Adaptive Cruise Control (ACC)|openpilot|0 mph|6 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|OBD-II|
|Chrysler|Pacifica 2017-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|FCA|
|Chrysler|Pacifica 2019-20|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|FCA|
|Chrysler|Pacifica 2021|All|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|FCA|
|Chrysler|Pacifica Hybrid 2017-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|FCA|
|Chrysler|Pacifica Hybrid 2019-22|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|FCA|
|comma|body|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|None|
|Genesis|G70 2018-19|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai F|
|Genesis|G70 2020|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai F|
|Genesis|G80 2017-19|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai H|
|Genesis|G90 2017-18|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai C|
|Genesis|GV70 2022-23|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai L|
|GMC|Acadia 2018[<sup>3</sup>](#footnotes)|Adaptive Cruise Control (ACC)|openpilot|0 mph|6 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|OBD-II|
|GMC|Sierra 1500 2020-21|Driver Alert Package II|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|GM|
|Honda|Accord 2018-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Bosch A|
|Honda|Accord Hybrid 2018-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Bosch A|
|Honda|Civic 2016-18|Honda Sensing|openpilot|0 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Nidec|
|Honda|Civic 2019-21|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|2 mph[<sup>4</sup>](#footnotes)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Bosch A|
|Honda|Civic 2022|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Bosch B|
|Honda|Civic Hatchback 2017-21|Honda Sensing|openpilot available[<sup>1</sup>](#footnotes)|0 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Bosch A|
|Honda|Civic Hatchback 2022|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Bosch B|
|Honda|CR-V 2015-16|Touring Trim|openpilot|25 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Nidec|
|Honda|CR-V 2017-22|Honda Sensing|openpilot available[<sup>1</sup>](#footnotes)|0 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Bosch A|
|Honda|CR-V Hybrid 2017-19|Honda Sensing|openpilot available[<sup>1</sup>](#footnotes)|0 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Bosch A|
|Honda|e 2020|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Bosch A|
|Honda|Fit 2018-20|Honda Sensing|openpilot|25 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Nidec|
|Honda|Freed 2020|Honda Sensing|openpilot|25 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Nidec|
|Honda|HR-V 2019-22|Honda Sensing|openpilot|25 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Nidec|
|Honda|Insight 2019-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Bosch A|
|Honda|Inspire 2018|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Bosch A|
|Honda|Odyssey 2018-20|Honda Sensing|openpilot|25 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Nidec|
|Honda|Passport 2019-21|All|openpilot|25 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Nidec|
|Honda|Pilot 2016-22|Honda Sensing|openpilot|25 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Nidec|
|Honda|Ridgeline 2017-22|Honda Sensing|openpilot|25 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Nidec|
|Hyundai|Elantra 2017-19|Smart Cruise Control (SCC)|Stock|19 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai B|
|Hyundai|Elantra 2021-22|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai K|
|Hyundai|Elantra GT 2017-19|Smart Cruise Control (SCC)|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai E|
|Hyundai|Elantra Hybrid 2021-23|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai K|
|Hyundai|Genesis 2015-16|Smart Cruise Control (SCC)|Stock|19 mph|37 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai J|
|Hyundai|i30 2019|Smart Cruise Control (SCC)|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai E|
|Hyundai|Ioniq 5 (with HDA II) 2022-23|Highway Driving Assist II|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai Q|
|Hyundai|Ioniq 5 (without HDA II) 2022-23|Highway Driving Assist|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai K|
|Hyundai|Ioniq Electric 2019|Smart Cruise Control (SCC)|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai C|
|Hyundai|Ioniq Electric 2020|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai H|
|Hyundai|Ioniq Hybrid 2017-19|Smart Cruise Control (SCC)|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai C|
|Hyundai|Ioniq Hybrid 2020-22|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai H|
|Hyundai|Ioniq Plug-in Hybrid 2019|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai C|
|Hyundai|Ioniq Plug-in Hybrid 2020-21|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai H|
|Hyundai|Kona 2020|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai B|
|Hyundai|Kona Electric 2018-21|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai G|
|Hyundai|Kona Electric 2022|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai O|
|Hyundai|Kona Hybrid 2020|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai I|
|Hyundai|Palisade 2020-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai H|
|Hyundai|Santa Cruz 2021-22|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai N|
|Hyundai|Santa Fe 2019-20|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai D|
|Hyundai|Santa Fe 2021-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai L|
|Hyundai|Santa Fe Hybrid 2022|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai L|
|Hyundai|Santa Fe Plug-in Hybrid 2022|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai L|
|Hyundai|Sonata 2018-19|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai E|
|Hyundai|Sonata 2020-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai A|
|Hyundai|Sonata Hybrid 2020-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai A|
|Hyundai|Tucson 2021|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai L|
|Hyundai|Tucson Diesel 2019|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai L|
|Hyundai|Tucson Hybrid 2022|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai N|
|Hyundai|Veloster 2019-20|Smart Cruise Control (SCC)|Stock|5 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai E|
|Jeep|Grand Cherokee 2016-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|FCA|
|Jeep|Grand Cherokee 2019-21|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|FCA|
|Kia|Ceed 2019|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai E|
|Kia|EV6 (with HDA II) 2022|Highway Driving Assist II|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai P|
|Kia|EV6 (without HDA II) 2022|Highway Driving Assist|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai L|
|Kia|Forte 2019-21|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai G|
|Kia|K5 2021-22|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai A|
|Kia|Niro EV 2019|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai H|
|Kia|Niro EV 2020|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai F|
|Kia|Niro EV 2021|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai C|
|Kia|Niro EV 2022|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai H|
|Kia|Niro Hybrid 2021|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai F|
|Kia|Niro Hybrid 2022|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai H|
|Kia|Niro Plug-in Hybrid 2018-19|All|openpilot available[<sup>1</sup>](#footnotes)|10 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai C|
|Kia|Optima 2017|Advanced Smart Cruise Control|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai B|
|Kia|Optima 2019-20|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai G|
|Kia|Seltos 2021|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai A|
|Kia|Sorento 2018|Advanced Smart Cruise Control|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai C|
|Kia|Sorento 2019|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai E|
|Kia|Sportage 2023|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai N|
|Kia|Sportage Hybrid 2023|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai N|
|Kia|Stinger 2018-20|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai C|
|Kia|Stinger 2022|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai K|
|Kia|Telluride 2020-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai H|
|Lexus|CT Hybrid 2017-18|Lexus Safety System+|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|
|Lexus|ES 2019-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Lexus|ES Hybrid 2017-18|Lexus Safety System+|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Lexus|ES Hybrid 2019-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Lexus|IS 2017-19|All|Stock|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|
|Lexus|NX 2018-19|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|
|Lexus|NX 2020-21|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Lexus|NX Hybrid 2018-19|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|
|Lexus|NX Hybrid 2020-21|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Lexus|RC 2017-20|All|Stock|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|
|Lexus|RX 2016|Lexus Safety System+|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|
|Lexus|RX 2017-19|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|
|Lexus|RX 2020-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Lexus|RX Hybrid 2016|Lexus Safety System+|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|
|Lexus|RX Hybrid 2017-19|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|
|Lexus|RX Hybrid 2020-21|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Lexus|UX Hybrid 2019-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Mazda|CX-5 2022-23|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Mazda|
|Mazda|CX-9 2021-22|All|Stock|0 mph|28 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Mazda|
|Nissan|Altima 2019-20|ProPILOT Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Nissan B|
|Nissan|Leaf 2018-22|ProPILOT Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Nissan A|
|Nissan|Rogue 2018-20|ProPILOT Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Nissan A|
|Nissan|X-Trail 2017|ProPILOT Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Nissan A|
|Ram|1500 2019-22|Adaptive Cruise Control (ACC)|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Ram|
|SEAT|Ateca 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|SEAT|Leon 2014-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Subaru|Ascent 2019-21|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|
|Subaru|Crosstrek 2018-19|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|
|Subaru|Crosstrek 2020-21|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|
|Subaru|Forester 2019-21|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|
|Subaru|Impreza 2017-19|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|
|Subaru|Impreza 2020-22|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|
|Subaru|Legacy 2020-22|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru B|
|Subaru|Outback 2020-22|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru B|
|Subaru|XV 2018-19|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|
|Subaru|XV 2020-21|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|
|Škoda|Kamiq 2021[<sup>6</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533[<sup>9</sup>](#footnotes)|
|Škoda|Karoq 2019-21|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Škoda|Kodiaq 2018-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Škoda|Octavia 2015, 2018-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Škoda|Octavia RS 2016|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Škoda|Scala 2020|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533[<sup>9</sup>](#footnotes)|
|Škoda|Superb 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Toyota|Alphard 2019-20|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Toyota|Alphard Hybrid 2021|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Toyota|Avalon 2016|Toyota Safety Sense P|openpilot available[<sup>2</sup>](#footnotes)|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|
|Toyota|Avalon 2017-18|All|openpilot available[<sup>2</sup>](#footnotes)|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|
|Toyota|Avalon 2019-21|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|
|Toyota|Avalon 2022|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Toyota|Avalon Hybrid 2019-21|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|
|Toyota|Avalon Hybrid 2022|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Toyota|C-HR 2017-21|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|
|Toyota|C-HR Hybrid 2017-19|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|
|Toyota|Camry 2018-20|All|Stock|0 mph[<sup>5</sup>](#footnotes)|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|
|Toyota|Camry 2021-22|All|openpilot|0 mph[<sup>5</sup>](#footnotes)|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Toyota|Camry Hybrid 2018-20|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|
|Toyota|Camry Hybrid 2021-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Toyota|Corolla 2017-19|All|openpilot available[<sup>2</sup>](#footnotes)|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|
|Toyota|Corolla 2020-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Toyota|Corolla Cross (Non-US only) 2020-23|All|openpilot|17 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Toyota|Corolla Cross Hybrid (Non-US only) 2020-22|All|openpilot|17 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Toyota|Corolla Hatchback 2019-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Toyota|Corolla Hybrid 2020-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Toyota|Highlander 2017-19|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Toyota|Highlander 2020-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Toyota|Highlander Hybrid 2017-19|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Toyota|Highlander Hybrid 2020-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Toyota|Mirai 2021|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Toyota|Prius 2016|Toyota Safety Sense P|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|
|Toyota|Prius 2017-20|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|
|Toyota|Prius 2021-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Toyota|Prius Prime 2017-20|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|
|Toyota|Prius Prime 2021-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Toyota|Prius v 2017|Toyota Safety Sense P|openpilot available[<sup>2</sup>](#footnotes)|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Toyota|RAV4 2016|Toyota Safety Sense P|openpilot available[<sup>2</sup>](#footnotes)|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|
|Toyota|RAV4 2017-18|All|openpilot available[<sup>2</sup>](#footnotes)|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|
|Toyota|RAV4 2019-21|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Toyota|RAV4 2022|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|
|Toyota|RAV4 Hybrid 2016|Toyota Safety Sense P|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Toyota|RAV4 Hybrid 2017-18|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Toyota|RAV4 Hybrid 2019-21|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Toyota|RAV4 Hybrid 2022|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|
|Toyota|Sienna 2018-20|All|openpilot available[<sup>2</sup>](#footnotes)|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|
|Volkswagen|Arteon 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Volkswagen|Arteon eHybrid 2020-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Volkswagen|Arteon R 2020-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Volkswagen|Atlas 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Volkswagen|Atlas Cross Sport 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Volkswagen|California 2021|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Volkswagen|Caravelle 2020|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Volkswagen|CC 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Volkswagen|e-Golf 2014-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Volkswagen|Golf 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Volkswagen|Golf Alltrack 2015-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Volkswagen|Golf GTD 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Volkswagen|Golf GTE 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Volkswagen|Golf GTI 2015-21|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Volkswagen|Golf R 2015-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Volkswagen|Golf SportsVan 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Volkswagen|Jetta 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Volkswagen|Jetta GLI 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Volkswagen|Passat 2015-22[<sup>7</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Volkswagen|Passat Alltrack 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Volkswagen|Passat GTE 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Volkswagen|Polo 2020-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533[<sup>9</sup>](#footnotes)|
|Volkswagen|Polo GTI 2020-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533[<sup>9</sup>](#footnotes)|
|Volkswagen|T-Cross 2021|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533[<sup>9</sup>](#footnotes)|
|Volkswagen|T-Roc 2021|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533[<sup>9</sup>](#footnotes)|
|Volkswagen|Taos 2022|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Volkswagen|Teramont 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Volkswagen|Teramont Cross Sport 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Volkswagen|Teramont X 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Volkswagen|Tiguan 2019-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Volkswagen|Touran 2017|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|
|Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Resume from stop|Harness|Video|
|---|---|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|Acura|ILX 2016-19|AcuraWatch Plus|openpilot|25 mph|25 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<a href="https://comma.ai/shop/comma-three.html?make=Chrysler&model=Pacifica Hybrid 2019-22">FCA</a>||
|comma|body|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|None||
|Genesis|G70 2018-19|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<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|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<a href="https://comma.ai/shop/comma-three.html?make=Volkswagen&model=Touran 2017">J533</a>||
<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 `master-ci`. Using openpilot longitudinal may disable Automatic Emergency Braking (AEB). <br />
<sup>2</sup>When the Driver Support Unit (DSU) is disconnected, openpilot Adaptive Cruise Control (ACC) will replace stock Adaptive Cruise Control (ACC). <b><i>NOTE: disconnecting the DSU disables Automatic Emergency Braking (AEB).</i></b> <br />
<sup>3</sup>Requires a <a href="https://github.com/commaai/openpilot/wiki/GM#hardware">community built ASCM harness</a>. <b><i>NOTE: disconnecting the ASCM disables Automatic Emergency Braking (AEB).</i></b> <br />
<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 />
<sup>2</sup>By default, this car will use the stock Adaptive Cruise Control (ACC) for longitudinal control. If the Driver Support Unit (DSU) is disconnected, openpilot ACC will replace stock ACC. <b><i>NOTE: disconnecting the DSU disables Automatic Emergency Braking (AEB).</i></b> <br />
<sup>3</sup>Requires a <a href="https://github.com/commaai/openpilot/wiki/GM#hardware" target="_blank">community built ASCM harness</a>. <b><i>NOTE: disconnecting the ASCM disables Automatic Emergency Braking (AEB).</i></b> <br />
<sup>4</sup>2019 Honda Civic 1.6L Diesel Sedan does not have ALC below 12mph. <br />
<sup>5</sup>openpilot operates above 28mph for Camry 4CYL L, 4CYL LE and 4CYL SE which don't have Full-Speed Range Dynamic Radar Cruise Control. <br />
<sup>6</sup>Not including the China market Kamiq, which is based on the (currently) unsupported PQ34 platform. <br />
<sup>7</sup>Refers only to the MQB-based European B8 Passat, not the NMS Passat in the USA/China/Mideast markets. <br />
<sup>8</sup>Only available for vehicles using a gateway (J533) harness. At this time, vehicles using a camera harness are limited to using stock ACC. <br />
<sup>9</sup>Model-years 2022 and beyond may have a combined CAN gateway and BCM, which is supported by openpilot in software, but doesn't yet have a harness available from the comma store. <br />
<sup>5</sup>Requires a <a href="https://comma.ai/shop/panda" target="_blank">red panda</a> for this <a href="https://en.wikipedia.org/wiki/CAN_FD" target="_blank">CAN FD car</a>. All the hardware needed is sold in the <a href="https://comma.ai/shop/can-fd-panda-kit" target="_blank">CAN FD kit</a>. <br />
<sup>6</sup>openpilot operates above 28mph for Camry 4CYL L, 4CYL LE and 4CYL SE which don't have Full-Speed Range Dynamic Radar Cruise Control. <br />
<sup>7</sup>Not including the China market Kamiq, which is based on the (currently) unsupported PQ34 platform. <br />
<sup>8</sup>Refers only to the MQB-based European B8 Passat, not the NMS Passat in the USA/China/Mideast markets. <br />
<sup>9</sup>Only available for vehicles using a gateway (J533) harness. At this time, vehicles using a camera harness are limited to using stock ACC. <br />
<sup>10</sup>Model-years 2022 and beyond may have a combined CAN gateway and BCM, which is supported by openpilot in software, but doesn't yet have a harness available from the comma store. <br />
## Community Maintained Cars
Although they're not upstream, the community has openpilot running on other makes and models. See the 'Community Supported Models' section of each make [on our wiki](https://wiki.comma.ai/).
+1 -1
View File
@@ -8,4 +8,4 @@ Additionally, on specific supported cars (see ACC column in [supported cars](CAR
* Stock ACC is replaced by openpilot ACC.
* openpilot FCW operates in addition to stock FCW.
openpilot should preserve all other vehicle's stock features, including, but are not limited to: FCW, Automatic Emergency Braking (AEB), auto high-beam, blind spot warning, and side collision warning.
openpilot should preserve all other vehicle's stock features, including, but not limited to: FCW, Automatic Emergency Braking (AEB), auto high-beam, blind spot warning, and side collision warning.
+8 -9
View File
@@ -48,13 +48,13 @@ class AstroDog:
self.valid_ephem_types = valid_ephem_types
self.orbit_fetched_times = TimeRangeHolder()
self.nav_fetched_times = TimeRangeHolder()
self.navs_fetched_times = TimeRangeHolder()
self.dcbs_fetched_times = TimeRangeHolder()
self.dgps_delays = []
self.ionex_maps: List[IonexMap] = []
self.orbits: DefaultDict[str, List[PolyEphemeris]] = defaultdict(list)
self.nav: DefaultDict[str, List[Union[GPSEphemeris, GLONASSEphemeris]]] = 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
@@ -73,8 +73,8 @@ class AstroDog:
return ionex
def get_nav(self, prn, time):
skip_download = time in self.nav_fetched_times
nav = self._get_latest_valid_data(self.nav[prn], self.cached_nav[prn], self.get_nav_data, time, skip_download)
skip_download = time in self.navs_fetched_times
nav = self._get_latest_valid_data(self.navs[prn], self.cached_nav[prn], self.get_nav_data, time, skip_download)
if nav is not None:
self.cached_nav[prn] = nav
return nav
@@ -97,9 +97,9 @@ class AstroDog:
return result
def get_navs(self, time):
if time not in self.nav_fetched_times and self.auto_update:
if time not in self.navs_fetched_times:
self.get_nav_data(time)
return AstroDog._select_valid_temporal_items(self.nav, time, self.cached_nav)
return AstroDog._select_valid_temporal_items(self.navs, time, self.cached_nav)
def get_orbit(self, prn: str, time: GPSTime):
skip_download = time in self.orbit_fetched_times
@@ -133,7 +133,7 @@ class AstroDog:
self._add_ephems(new_ephems, self.orbits, self.orbit_fetched_times)
def add_navs(self, new_ephems: Dict[str, List[Ephemeris]]):
self._add_ephems(new_ephems, self.nav, self.nav_fetched_times)
self._add_ephems(new_ephems, self.navs, self.navs_fetched_times)
def _add_ephems(self, new_ephems: Dict[str, List[Ephemeris]], ephems_dict, fetched_times):
for k, v in new_ephems.items():
@@ -172,7 +172,7 @@ class AstroDog:
if sum([len(v) for v in fetched_ephems.values()]) == 0:
begin_day = GPSTime(time.week, SECS_IN_DAY * (time.tow // SECS_IN_DAY))
end_day = GPSTime(time.week, SECS_IN_DAY * (1 + (time.tow // SECS_IN_DAY)))
self.nav_fetched_times.add(begin_day, end_day)
self.navs_fetched_times.add(begin_day, end_day)
def download_parse_orbit(self, gps_time: GPSTime, skip_before_epoch=None) -> Dict[str, List[PolyEphemeris]]:
# Download multiple days to be able to polyfit at the start-end of the day
@@ -265,7 +265,6 @@ class AstroDog:
eph = self.get_orbit(prn, time)
if not eph and self.pull_nav:
eph = self.get_nav(prn, time)
if eph:
return eph.get_sat_info(time)
return None
+4 -2
View File
@@ -5,6 +5,7 @@ from datetime import datetime
from .gps_time import GPSTime
from .constants import SECS_IN_YEAR
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
@@ -107,8 +108,9 @@ def parse_dgps(station_id, station_obs_file_path, dog, max_distance=100000, requ
station_delays[signal] = {}
for i, proc_measurement in enumerate(proc_measurements):
times.append(proc_measurement[0].recv_time)
Fx_pos = raw.pr_residual(proc_measurement, signal=signal)
residual = -np.array(Fx_pos(list(station_pos) + [0, 0]))
Fx_pos = opt.pr_residual(proc_measurement, signal=signal)
residual, _ = Fx_pos(list(station_pos) + [0,0])
residual = -np.array(residual)
for j, m in enumerate(proc_measurement):
prn = m.prn
if prn not in station_delays[signal]:
+60 -40
View File
@@ -7,18 +7,18 @@ import urllib.error
import pycurl
import re
import time
import tempfile
import socket
from datetime import datetime, timedelta
from urllib.parse import urlparse
from io import BytesIO
from ftplib import FTP_TLS
from atomicwrites import atomic_write
from laika.ephemeris import EphemerisType
from .constants import SECS_IN_HR, SECS_IN_DAY, SECS_IN_WEEK
from .gps_time import GPSTime
from .gps_time import GPSTime, tow_to_datetime
from .helpers import ConstellationId
dir_path = os.path.dirname(os.path.realpath(__file__))
@@ -177,24 +177,6 @@ def http_download_files(url_base, folder_path, cacheDir, filenames):
def https_download_file(url):
if 'nasa.gov/' not in url:
netrc_path = None
f = None
elif os.path.isfile(dir_path + '/.netrc'):
netrc_path = dir_path + '/.netrc'
f = None
else:
try:
username = os.environ['NASA_USERNAME']
password = os.environ['NASA_PASSWORD']
f = tempfile.NamedTemporaryFile()
netrc = f"machine urs.earthdata.nasa.gov login {username} password {password}"
f.write(netrc.encode())
f.flush()
netrc_path = f.name
except KeyError:
raise DownloadFailed('Could not find .netrc file and no NASA_USERNAME and NASA_PASSWORD in environment for urs.earthdata.nasa.gov authentication')
crl = pycurl.Curl()
crl.setopt(crl.CAINFO, certifi.where())
crl.setopt(crl.URL, url)
@@ -202,17 +184,12 @@ def https_download_file(url):
crl.setopt(crl.SSL_CIPHER_LIST, 'DEFAULT@SECLEVEL=1')
crl.setopt(crl.COOKIEJAR, '/tmp/cddis_cookies')
crl.setopt(pycurl.CONNECTTIMEOUT, 10)
if netrc_path is not None:
crl.setopt(crl.NETRC_FILE, netrc_path)
crl.setopt(crl.NETRC, 2)
buf = BytesIO()
crl.setopt(crl.WRITEDATA, buf)
crl.perform()
response = crl.getinfo(pycurl.RESPONSE_CODE)
crl.close()
if f is not None:
f.close()
if response != 200:
raise DownloadFailed('HTTPS error ' + str(response))
@@ -228,6 +205,17 @@ def ftp_download_file(url):
except urllib.error.URLError as e:
raise DownloadFailed(e)
def ftps_download_file(url):
parsed = urlparse(url)
try:
buf = BytesIO()
with FTP_TLS(parsed.hostname) as ftps:
ftps.login(user='anonymous')
ftps.prot_p()
ftps.retrbinary('RETR ' + parsed.path, buf.write)
return buf.getvalue()
except ftplib.all_errors as e:
raise DownloadFailed(e)
@retryable
def download_files(url_base, folder_path, cacheDir, filenames):
@@ -242,11 +230,13 @@ def download_files(url_base, folder_path, cacheDir, filenames):
def download_file(url_base, folder_path, filename_zipped):
url = url_base + folder_path + filename_zipped
print('Downloading ' + url)
if url.startswith('https'):
if url.startswith('https://'):
return https_download_file(url)
if url.startswith('ftp'):
elif url.startswith('ftp://'):
return ftp_download_file(url)
raise NotImplementedError('Did find ftp or https preamble')
elif url.startswith('sftp://'):
return ftps_download_file(url)
raise NotImplementedError('Did not find supported url scheme')
def download_and_cache_file_return_first_success(url_bases, folder_and_file_names, cache_dir, compression='', overwrite=False, raise_error=False):
@@ -308,26 +298,51 @@ def download_nav(time: GPSTime, cache_dir, constellation: ConstellationId):
if GPSTime.from_datetime(datetime.utcnow()) - time > SECS_IN_DAY:
url_bases = (
'https://github.com/commaai/gnss-data/raw/master/gnss/data/daily/',
'https://cddis.nasa.gov/archive/gnss/data/daily/',
'sftp://gdc.cddis.eosdis.nasa.gov/gnss/data/daily/',
)
filename = t.strftime(f"brdc%j0.%y{c}")
folder_path = t.strftime(f'%Y/%j/%y{c}/')
compression = '.gz' if folder_path >= '2020/335/' else '.Z'
return download_and_cache_file(url_bases, folder_path, cache_dir+'daily_nav/', filename, compression)
elif constellation == ConstellationId.GPS:
url_base = 'https://cddis.nasa.gov/archive/gnss/data/hourly/'
filename = t.strftime(f"hour%j0.%y{c}")
folder_path = t.strftime('%Y/%j/')
compression = '.gz' if folder_path >= '2020/336/' else '.Z'
return download_and_cache_file(url_base, folder_path, cache_dir+'hourly_nav/', filename, compression)
else:
url_bases = (
'https://github.com/commaai/gnss-data-hourly/raw/master/',
'sftp://gdc.cddis.eosdis.nasa.gov/gnss/data/hourly/',
)
times = [t, (t - timedelta(hours=1))]
folder_and_filenames = [(t.strftime('%Y/%j/'), t.strftime(f"hour%j0.%y{c}")) for t in times]
compression = '.gz' if folder_and_filenames[0][0] >= '2020/336/' else '.Z'
# always overwrite as this file is appended
return download_and_cache_file_return_first_success(url_bases,
folder_and_filenames, cache_dir+'hourly_nav/', compression, overwrite=True)
except DownloadFailed:
pass
def download_orbits_gps_cod0(time, cache_dir, ephem_types):
url_bases = (
'https://github.com/commaai/gnss-data/raw/master/gnss/products/',
'sftp://gdc.cddis.eosdis.nasa.gov/gnss/products/',
)
if EphemerisType.ULTRA_RAPID_ORBIT not in ephem_types:
# TODO: raise error here
return None
tm = tow_to_datetime(time.tow, time.week).timetuple()
doy = str(tm.tm_yday).zfill(3)
filename = f"COD0OPSULT_{tm.tm_year}{doy}0000_02D_05M_ORB.SP3"
# TODO: add hour management
folder_path = "%i/" % time.week
folder_file_names = [(folder_path, filename)]
return download_and_cache_file_return_first_success(url_bases, folder_file_names, cache_dir+'cddis_products/', compression='.gz')
def download_orbits_gps(time, cache_dir, ephem_types):
url_bases = (
'https://github.com/commaai/gnss-data/raw/master/gnss/products/',
'https://cddis.nasa.gov/archive/gnss/products/',
'sftp://gdc.cddis.eosdis.nasa.gov/gnss/products/',
'ftp://igs.ign.fr/pub/igs/products/',
)
folder_path = "%i/" % time.week
@@ -344,7 +359,12 @@ def download_orbits_gps(time, cache_dir, ephem_types):
f"igu{time_str}_06.sp3",
f"igu{time_str}_00.sp3"])
folder_file_names = [(folder_path, filename) for filename in filenames]
return download_and_cache_file_return_first_success(url_bases, folder_file_names, cache_dir+'cddis_products/', compression='.Z')
ret = download_and_cache_file_return_first_success(url_bases, folder_file_names, cache_dir+'cddis_products/', compression='.Z')
if ret is not None:
return ret
# fallback to COD0 Ultra Rapid Orbits
return download_orbits_gps_cod0(time, cache_dir, ephem_types)
def download_prediction_orbits_russia_src(gps_time, cache_dir):
@@ -406,7 +426,7 @@ def download_ionex(time, cache_dir):
t = time.as_datetime()
url_bases = (
'https://github.com/commaai/gnss-data/raw/master/gnss/products/ionex/',
'https://cddis.nasa.gov/archive/gnss/products/ionex/',
'sftp://gdc.cddis.eosdis.nasa.gov/gnss/products/ionex/',
'ftp://igs.ensg.ign.fr/pub/igs/products/ionosphere/',
'ftp://gssc.esa.int/gnss/products/ionex/',
)
@@ -422,7 +442,7 @@ def download_dcb(time, cache_dir):
folder_paths = []
url_bases = (
'https://github.com/commaai/gnss-data/raw/master/gnss/products/bias/',
'https://cddis.nasa.gov/archive/gnss/products/bias/',
'sftp://gdc.cddis.eosdis.nasa.gov/gnss/products/bias/',
'ftp://igs.ign.fr/pub/igs/products/mgex/dcb/',
)
# seem to be a lot of data missing, so try many days
+58 -16
View File
@@ -7,7 +7,7 @@ from typing import Dict, List, Optional
import numpy as np
import numpy.polynomial.polynomial as poly
from datetime import datetime
from datetime import datetime, timedelta
from math import sin, cos, sqrt, fabs, atan2
from .gps_time import GPSTime, utc_to_gpst
@@ -24,7 +24,7 @@ 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_ephem(ublox_ephem, current_time: Optional[datetime] = None):
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
@@ -38,6 +38,12 @@ def convert_ublox_ephem(ublox_ephem, current_time: Optional[datetime] = None):
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)
@@ -65,10 +71,48 @@ def convert_ublox_ephem(ublox_ephem, current_time: Optional[datetime] = None):
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
@@ -87,7 +131,7 @@ class EphemerisType(IntEnum):
return EphemerisType.FINAL_ORBIT
if "/rapid" in file_name or "/igr" in file_name:
return EphemerisType.RAPID_ORBIT
if "/ultra" in file_name or "/igu" in file_name:
if "/ultra" in file_name or "/igu" in file_name or "COD0OPSULT" in file_name:
return EphemerisType.ULTRA_RAPID_ORBIT
raise RuntimeError(f"Ephemeris type not found in filename: {file_name}")
@@ -158,8 +202,8 @@ class EphemerisSerializer(json.JSONEncoder):
class GLONASSEphemeris(Ephemeris):
def __init__(self, data, epoch, healthy=True, file_name=None):
super().__init__(data['prn'], data, epoch, EphemerisType.NAV, healthy, max_time_diff=25*SECS_IN_MIN, file_name=file_name)
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()
@@ -168,9 +212,7 @@ class GLONASSEphemeris(Ephemeris):
# http://gauss.gge.unb.ca/GLONASS.ICD.pdf
eph = self.data
# TODO should handle leap seconds better
toc_gps_time = utc_to_gpst(eph['toc'])
tdiff = time - toc_gps_time
tdiff = time - utc_to_gpst(eph['toe'])
# Clock correction (except for general relativity which is applied later)
clock_err = eph['min_tauN'] + tdiff * (eph['GammaN'])
@@ -227,8 +269,9 @@ class GLONASSEphemeris(Ephemeris):
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):
super().__init__(prn, data, epoch, ephem_type, healthy, max_time_diff=SECS_IN_HR, file_epoch=file_epoch, file_name=file_name)
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)
self.tgd = tgd
self.to_json()
@@ -247,8 +290,8 @@ class PolyEphemeris(Ephemeris):
class GPSEphemeris(Ephemeris):
def __init__(self, data, epoch, healthy=True, file_name=None):
super().__init__('G%02i' % data['sv_id'], data, epoch, EphemerisType.NAV, healthy, max_time_diff=2*SECS_IN_HR, file_name=file_name)
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)
self.max_time_diff_tgd = SECS_IN_DAY
self.to_json()
@@ -403,7 +446,7 @@ def read_prn_data(data, prn, deg=16, deg_t=1):
measurements = np_data_prn[i:i + deg + 1, 1:5]
times = (measurements[:, 0] - epoch).astype(float)
if (np.diff(times) != 900).any():
if not (np.diff(times) != 900).any() and not (np.diff(times) != 300).any():
continue
poly_data = {}
@@ -516,7 +559,7 @@ def parse_rinex_nav_msg_glonass(file_name):
line = line.replace('D', 'E') # Handle bizarro float format
e = {'epoch': epoch, 'prn': prn}
e['toc'] = epoch
e['toe'] = epoch
e['min_tauN'] = float(line[23:42])
e['GammaN'] = float(line[42:61])
e['tk'] = float(line[61:80])
@@ -526,7 +569,6 @@ def parse_rinex_nav_msg_glonass(file_name):
e['z'], e['z_vel'], e['z_acc'], e['age'] = read4(f, rinex_ver)
e['healthy'] = (e['health'] == 0.0)
ephems[prn].append(GLONASSEphemeris(e, epoch, file_name=file_name))
f.close()
return ephems
@@ -553,4 +595,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)
return PolyEphemeris(prn, poly_data, epoch, ephem_type=EphemerisType.QCOM_POLY, max_time_diff=180)
+1 -2
View File
@@ -62,8 +62,7 @@ def get_leap_seconds(time):
return 15
elif time <= GPSTime.from_datetime(datetime.datetime(2015, 7, 1)):
return 16
# TODO is this correct?
elif time <= GPSTime.from_datetime(datetime.datetime(2017, 7, 1)):
elif time <= GPSTime.from_datetime(datetime.datetime(2017, 1, 1)):
return 17
else:
return 18
+191
View File
@@ -0,0 +1,191 @@
import sympy
import numpy as np
from typing import List
from .constants import EARTH_ROTATION_RATE, SPEED_OF_LIGHT
from .helpers import ConstellationId
from .raw_gnss import GNSSMeasurement
def gauss_newton(fun, b, xtol=1e-8, max_n=25):
for _ in range(max_n):
# Compute function and jacobian on current estimate
r, J = fun(b)
# Update estimate
delta = np.linalg.pinv(J) @ r
b -= delta
# Check step size for stopping condition
if np.linalg.norm(delta) < xtol:
break
return b
def calc_pos_fix(measurements, posfix_functions=None, x0=None, no_weight=False, signal='C1C', min_measurements=6):
'''
Calculates gps fix using gauss newton method
To solve the problem a minimal of 4 measurements are required.
If Glonass is included 5 are required to solve for the additional free variable.
returns:
0 -> list with positions
1 -> pseudorange errs
'''
if x0 is None:
x0 = [0, 0, 0, 0, 0]
if len(measurements) < min_measurements:
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()
def calc_vel_fix(measurements, est_pos, velfix_function=None, v0=None, no_weight=False, signal='D1C', min_measurements=6):
'''
Calculates gps velocity fix using gauss newton method
returns:
0 -> list with velocities
1 -> pseudorange_rate errs
'''
if v0 is None:
v0 = [0, 0, 0, 0]
if len(measurements) < min_measurements:
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()
def get_posfix_sympy_fun(constellation):
# Unknowns
x, y, z = sympy.Symbol('x'), sympy.Symbol('y'), sympy.Symbol('z')
bc = sympy.Symbol('bc')
bg = sympy.Symbol('bg')
zero_theta = sympy.Symbol('zero_theta')
var = [x, y, z, bc, bg]
# 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(
(sat_x * sympy.cos(theta) + sat_y * sympy.sin(theta) - x) ** 2 +
(sat_y * sympy.cos(theta) - sat_x * sympy.sin(theta) - y) ** 2 +
(sat_z - z) ** 2
)
if constellation == ConstellationId.GLONASS:
res = weight * (val - (pr - bc - bg))
elif constellation == ConstellationId.GPS:
res = weight * (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"])
def get_velfix_sympy_func():
# implementing this without sympy.Matrix gives a 2x speedup at generation
# knowns, receiver position, satellite position, satellite velocity
ep_x, ep_y, ep_z = sympy.Symbol('ep_x'), sympy.Symbol('ep_y'), sympy.Symbol('ep_z')
est_pos = np.array([ep_x, ep_y, ep_z])
sp_x, sp_y, sp_z = sympy.Symbol('sp_x'), sympy.Symbol('sp_y'), sympy.Symbol('sp_z')
sat_pos = np.array([sp_x, sp_y, sp_z])
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')
vel = np.array([v_x, v_y, v_z])
vel_o = sympy.Symbol('vel_o')
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 = [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,
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):
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):
vals, gradients = [], []
for meas in measurements:
if signal in meas.observables_final and np.isfinite(meas.observables_final[signal]):
pr = meas.observables_final[signal]
sat_pos = meas.sat_pos_final
zero_theta = 0
elif signal in meas.observables and np.isfinite(meas.observables[signal]) and meas.processed:
pr = meas.observables[signal]
pr += meas.sat_clock_err * SPEED_OF_LIGHT
sat_pos = meas.sat_pos
zero_theta = 1
else:
if not no_nans:
vals.append(np.nan)
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)
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):
if velfix_function is None:
velfix_function = get_velfix_sympy_func()
def Fx_vel(vel, no_weight=no_weight):
vals, gradients = [], []
for meas in measurements:
if signal not in meas.observables or not np.isfinite(meas.observables[signal]):
if not no_nans:
vals.append(np.nan)
gradients.append(np.nan)
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,
vel[0], vel[1], vel[2], vel[3])
vals.append(val)
gradients.append(gradient)
return np.asarray(vals), np.asarray(gradients)
return Fx_vel
+4 -106
View File
@@ -92,11 +92,11 @@ class GNSSMeasurement:
self.processed = True
return True
def correct(self, est_pos, dog, allow_incomplete_delay=False):
def correct(self, est_pos, dog):
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 delay is not None and (allow_incomplete_delay or delay != 0):
if delay is not None:
self.observables_final[obs] = (self.observables[obs] +
self.sat_clock_err*constants.SPEED_OF_LIGHT -
delay)
@@ -147,10 +147,10 @@ def process_measurements(measurements: List[GNSSMeasurement], dog) -> List[GNSSM
return proc_measurements
def correct_measurements(measurements: List[GNSSMeasurement], est_pos, dog, allow_incomplete_delay=False) -> List[GNSSMeasurement]:
def correct_measurements(measurements: List[GNSSMeasurement], est_pos, dog) -> List[GNSSMeasurement]:
corrected_measurements = []
for meas in measurements:
if meas.correct(est_pos, dog, allow_incomplete_delay):
if meas.correct(est_pos, dog):
corrected_measurements.append(meas)
return corrected_measurements
@@ -292,108 +292,6 @@ def read_rinex_obs(obsdata) -> List[List[GNSSMeasurement]]:
return measurements
def calc_pos_fix(measurements, x0=[0, 0, 0, 0, 0], no_weight=False, signal='C1C', min_measurements=6):
'''
Calculates gps fix with WLS optimizer
returns:
0 -> list with positions
1 -> pseudorange errs
'''
import scipy.optimize as opt # Only use scipy here
n = len(measurements)
if n < min_measurements:
return []
Fx_pos = pr_residual(measurements, signal=signal, no_weight=no_weight, no_nans=True)
opt_pos = opt.least_squares(Fx_pos, x0).x
return opt_pos, Fx_pos(opt_pos, no_weight=True)
def calc_vel_fix(measurements, est_pos, v0=[0, 0, 0, 0], no_weight=False, signal='D1C'):
'''
Calculates gps velocity fix with WLS optimizer
returns:
0 -> list with velocities
1 -> pseudorange_rate errs
'''
import scipy.optimize as opt # Only use scipy here
n = len(measurements)
if n < 6:
return []
Fx_vel = prr_residual(measurements, est_pos, signal=signal, no_weight=no_weight, no_nans=True)
opt_vel = opt.least_squares(Fx_vel, v0).x
return opt_vel, Fx_vel(opt_vel, no_weight=True)
def pr_residual(measurements: List[GNSSMeasurement], signal='C1C', no_weight=False, no_nans=False):
# solve for pos
def Fx_pos(xxx_todo_changeme, no_weight=no_weight):
(x, y, z, bc, bg) = xxx_todo_changeme
rows = []
for meas in measurements:
if signal in meas.observables_final and np.isfinite(meas.observables_final[signal]):
pr = meas.observables_final[signal]
sat_pos = meas.sat_pos_final
theta = 0
elif signal in meas.observables and np.isfinite(meas.observables[signal]) and meas.processed:
pr = meas.observables[signal]
pr += meas.sat_clock_err * constants.SPEED_OF_LIGHT
sat_pos = meas.sat_pos
theta = constants.EARTH_ROTATION_RATE * (pr - bc) / constants.SPEED_OF_LIGHT
else:
if not no_nans:
rows.append(np.nan)
continue
if no_weight:
weight = 1
else:
weight = (1 / meas.observables_std[signal])
val = np.sqrt(
(sat_pos[0] * np.cos(theta) + sat_pos[1] * np.sin(theta) - x) ** 2 +
(sat_pos[1] * np.cos(theta) - sat_pos[0] * np.sin(theta) - y) ** 2 +
(sat_pos[2] - z) ** 2
)
if meas.constellation_id == ConstellationId.GLONASS:
rows.append(weight * (val - (pr - bc - bg)))
elif meas.constellation_id == ConstellationId.GPS:
rows.append(weight * (val - (pr - bc)))
return rows
return Fx_pos
def prr_residual(measurements, est_pos, signal='D1C', no_weight=False, no_nans=False):
# solve for vel
def Fx_vel(vel, no_weight=no_weight):
rows = []
for meas in measurements:
if signal not in meas.observables or not np.isfinite(meas.observables[signal]):
if not no_nans:
rows.append(np.nan)
continue
if meas.corrected:
sat_pos = meas.sat_pos_final
else:
sat_pos = meas.sat_pos
if no_weight:
weight = 1
else:
weight = (1 / meas.observables[signal])
los_vector = (sat_pos - est_pos[0:3]
) / np.linalg.norm(sat_pos - est_pos[0:3])
rows.append(
weight * ((meas.sat_vel - vel[0:3]).dot(los_vector) -
(meas.observables[signal] - vel[3])))
return rows
return Fx_vel
def get_Q(recv_pos, sat_positions):
local = LocalCoord.from_ecef(recv_pos)
sat_positions_rel = local.ecef2ned(sat_positions)
+1 -1
View File
@@ -16,7 +16,7 @@ def saast(pos, el, humi=0.75, temp0=15.0):
:return: tropospheric delay (m)
"""
pos_rad = ecef2geodetic(pos, radians=True)
if pos_rad[2] < -100.0 or 1E4 < pos_rad[2] or el <= 0:
if pos_rad[2] < -1E3 or 1E4 < pos_rad[2] or el <= 0:
return 0.0
# /* standard atmosphere */
+1 -1
View File
@@ -74,7 +74,7 @@ function launch {
# handle pythonpath
ln -sfn $(pwd) /data/pythonpath
export PYTHONPATH="$PWD:$PWD/pyextra"
export PYTHONPATH="$PWD"
# hardware specific init
agnos_init
+23 -23
View File
@@ -1,4 +1,5 @@
#include "common.h"
#include "opendbc/can/common.h"
unsigned int honda_checksum(uint32_t address, const Signal &sig, const std::vector<uint8_t> &d) {
int s = 0;
@@ -34,7 +35,7 @@ unsigned int subaru_checksum(uint32_t address, const Signal &sig, const std::vec
}
unsigned int chrysler_checksum(uint32_t address, const Signal &sig, const std::vector<uint8_t> &d) {
/* jeep chrysler canbus checksum from http://illmatics.com/Remote%20Car%20Hacking.pdf */
// jeep chrysler canbus checksum from http://illmatics.com/Remote%20Car%20Hacking.pdf
uint8_t checksum = 0xFF;
for (int j = 0; j < (d.size() - 1); j++) {
uint8_t shift = 0x80;
@@ -123,64 +124,64 @@ unsigned int volkswagen_mqb_checksum(uint32_t address, const Signal &sig, const
// Look up and apply the magic final CRC padding byte, which permutes by CAN
// address, and additionally (for SOME addresses) by the message counter.
uint8_t counter = d[1] & 0x0F;
switch(address) {
switch (address) {
case 0x86: // LWI_01 Steering Angle
crc ^= (uint8_t[]){0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86}[counter];
crc ^= (uint8_t[]){0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86}[counter];
break;
case 0x9F: // LH_EPS_03 Electric Power Steering
crc ^= (uint8_t[]){0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5}[counter];
crc ^= (uint8_t[]){0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5}[counter];
break;
case 0xAD: // Getriebe_11 Automatic Gearbox
crc ^= (uint8_t[]){0x3F,0x69,0x39,0xDC,0x94,0xF9,0x14,0x64,0xD8,0x6A,0x34,0xCE,0xA2,0x55,0xB5,0x2C}[counter];
crc ^= (uint8_t[]){0x3F, 0x69, 0x39, 0xDC, 0x94, 0xF9, 0x14, 0x64, 0xD8, 0x6A, 0x34, 0xCE, 0xA2, 0x55, 0xB5, 0x2C}[counter];
break;
case 0xFD: // ESP_21 Electronic Stability Program
crc ^= (uint8_t[]){0xB4,0xEF,0xF8,0x49,0x1E,0xE5,0xC2,0xC0,0x97,0x19,0x3C,0xC9,0xF1,0x98,0xD6,0x61}[counter];
crc ^= (uint8_t[]){0xB4, 0xEF, 0xF8, 0x49, 0x1E, 0xE5, 0xC2, 0xC0, 0x97, 0x19, 0x3C, 0xC9, 0xF1, 0x98, 0xD6, 0x61}[counter];
break;
case 0x106: // ESP_05 Electronic Stability Program
crc ^= (uint8_t[]){0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07}[counter];
crc ^= (uint8_t[]){0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07}[counter];
break;
case 0x117: // ACC_10 Automatic Cruise Control
crc ^= (uint8_t[]){0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16}[counter];
crc ^= (uint8_t[]){0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16}[counter];
break;
case 0x120: // TSK_06 Drivetrain Coordinator
crc ^= (uint8_t[]){0xC4,0xE2,0x4F,0xE4,0xF8,0x2F,0x56,0x81,0x9F,0xE5,0x83,0x44,0x05,0x3F,0x97,0xDF}[counter];
crc ^= (uint8_t[]){0xC4, 0xE2, 0x4F, 0xE4, 0xF8, 0x2F, 0x56, 0x81, 0x9F, 0xE5, 0x83, 0x44, 0x05, 0x3F, 0x97, 0xDF}[counter];
break;
case 0x121: // Motor_20 Driver Throttle Inputs
crc ^= (uint8_t[]){0xE9,0x65,0xAE,0x6B,0x7B,0x35,0xE5,0x5F,0x4E,0xC7,0x86,0xA2,0xBB,0xDD,0xEB,0xB4}[counter];
crc ^= (uint8_t[]){0xE9, 0x65, 0xAE, 0x6B, 0x7B, 0x35, 0xE5, 0x5F, 0x4E, 0xC7, 0x86, 0xA2, 0xBB, 0xDD, 0xEB, 0xB4}[counter];
break;
case 0x122: // ACC_06 Automatic Cruise Control
crc ^= (uint8_t[]){0x37,0x7D,0xF3,0xA9,0x18,0x46,0x6D,0x4D,0x3D,0x71,0x92,0x9C,0xE5,0x32,0x10,0xB9}[counter];
crc ^= (uint8_t[]){0x37, 0x7D, 0xF3, 0xA9, 0x18, 0x46, 0x6D, 0x4D, 0x3D, 0x71, 0x92, 0x9C, 0xE5, 0x32, 0x10, 0xB9}[counter];
break;
case 0x126: // HCA_01 Heading Control Assist
crc ^= (uint8_t[]){0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA}[counter];
crc ^= (uint8_t[]){0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA}[counter];
break;
case 0x12B: // GRA_ACC_01 Steering wheel controls for ACC
crc ^= (uint8_t[]){0x6A,0x38,0xB4,0x27,0x22,0xEF,0xE1,0xBB,0xF8,0x80,0x84,0x49,0xC7,0x9E,0x1E,0x2B}[counter];
crc ^= (uint8_t[]){0x6A, 0x38, 0xB4, 0x27, 0x22, 0xEF, 0xE1, 0xBB, 0xF8, 0x80, 0x84, 0x49, 0xC7, 0x9E, 0x1E, 0x2B}[counter];
break;
case 0x12E: // ACC_07 Automatic Cruise Control
crc ^= (uint8_t[]){0xF8,0xE5,0x97,0xC9,0xD6,0x07,0x47,0x21,0x66,0xDD,0xCF,0x6F,0xA1,0x94,0x74,0x63}[counter];
crc ^= (uint8_t[]){0xF8, 0xE5, 0x97, 0xC9, 0xD6, 0x07, 0x47, 0x21, 0x66, 0xDD, 0xCF, 0x6F, 0xA1, 0x94, 0x74, 0x63}[counter];
break;
case 0x187: // EV_Gearshift "Gear" selection data for EVs with no gearbox
crc ^= (uint8_t[]){0x7F,0xED,0x17,0xC2,0x7C,0xEB,0x44,0x21,0x01,0xFA,0xDB,0x15,0x4A,0x6B,0x23,0x05}[counter];
crc ^= (uint8_t[]){0x7F, 0xED, 0x17, 0xC2, 0x7C, 0xEB, 0x44, 0x21, 0x01, 0xFA, 0xDB, 0x15, 0x4A, 0x6B, 0x23, 0x05}[counter];
break;
case 0x30C: // ACC_02 Automatic Cruise Control
crc ^= (uint8_t[]){0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F}[counter];
crc ^= (uint8_t[]){0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F}[counter];
break;
case 0x30F: // SWA_01 Lane Change Assist (SpurWechselAssistent)
crc ^= (uint8_t[]){0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C}[counter];
crc ^= (uint8_t[]){0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C}[counter];
break;
case 0x324: // ACC_04 Automatic Cruise Control
crc ^= (uint8_t[]){0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27}[counter];
crc ^= (uint8_t[]){0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27}[counter];
break;
case 0x3C0: // Klemmen_Status_01 ignition and starting status
crc ^= (uint8_t[]){0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3}[counter];
crc ^= (uint8_t[]){0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3}[counter];
break;
case 0x65D: // ESP_20 Electronic Stability Program
crc ^= (uint8_t[]){0xAC,0xB3,0xAB,0xEB,0x7A,0xE1,0x3B,0xF7,0x73,0xBA,0x7C,0x9E,0x06,0x5F,0x02,0xD9}[counter];
crc ^= (uint8_t[]){0xAC, 0xB3, 0xAB, 0xEB, 0x7A, 0xE1, 0x3B, 0xF7, 0x73, 0xBA, 0x7C, 0x9E, 0x06, 0x5F, 0x02, 0xD9}[counter];
break;
default: // As-yet undefined CAN message, CRC check expected to fail
printf("Attempt to CRC check undefined Volkswagen message 0x%02X\n", address);
crc ^= (uint8_t[]){0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}[counter];
crc ^= (uint8_t[]){0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}[counter];
break;
}
crc = crc8_lut_8h2f[crc];
@@ -221,7 +222,6 @@ unsigned int pedal_checksum(uint32_t address, const Signal &sig, const std::vect
}
unsigned int hkg_can_fd_checksum(uint32_t address, const Signal &sig, const std::vector<uint8_t> &d) {
uint16_t crc = 0;
for (int i = 2; i < d.size(); i++) {
+5 -2
View File
@@ -1,10 +1,11 @@
#pragma once
#include <vector>
#include <map>
#include <string>
#include <utility>
#include <unordered_map>
#include <vector>
#include "common_dbc.h"
#include <capnp/dynamic.h>
#include <capnp/serialize.h>
@@ -12,6 +13,8 @@
#include "cereal/gen/cpp/log.capnp.h"
#endif
#include "opendbc/can/common_dbc.h"
#define INFO printf
#define WARN printf
#define DEBUG(...)
+1
View File
@@ -61,6 +61,7 @@ cdef extern from "common_dbc.h":
cdef struct SignalValue:
uint32_t address
uint64_t ts_nanos
string name
double value
vector[double] all_values
+1
View File
@@ -24,6 +24,7 @@ struct MessageParseOptions {
struct SignalValue {
uint32_t address;
uint64_t ts_nanos;
std::string name;
double value; // latest value
std::vector<double> all_values; // all values from this cycle
+3 -2
View File
@@ -8,9 +8,10 @@
#include <vector>
#include <mutex>
#include <cstring>
#include <iterator>
#include "common.h"
#include "common_dbc.h"
#include "opendbc/can/common.h"
#include "opendbc/can/common_dbc.h"
std::regex bo_regexp(R"(^BO_ (\w+) (\w+) *: (\w+) (\w+))");
std::regex sg_regexp(R"(^SG_ (\w+) : (\d+)\|(\d+)@(\d+)([\+|\-]) \(([0-9.+\-eE]+),([0-9.+\-eE]+)\) \[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] \"(.*)\" (.*))");
+1 -1
View File
@@ -4,7 +4,7 @@
#include <map>
#include <cmath>
#include "common.h"
#include "opendbc/can/common.h"
void set_value(std::vector<uint8_t> &msg, const Signal &sig, int64_t ival) {
+1 -2
View File
@@ -1,3 +1,2 @@
# pylint: skip-file
from opendbc.can.packer_pyx import CANPacker
from opendbc.can.packer_pyx import CANPacker # pylint: disable=no-name-in-module, import-error
assert CANPacker
+1 -2
View File
@@ -32,7 +32,6 @@ 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];
@@ -94,7 +93,6 @@ CANParser::CANParser(int abus, const std::string& dbc_name,
const std::vector<MessageParseOptions> &options,
const std::vector<SignalParseOptions> &sigoptions)
: bus(abus), aligned_buf(kj::heapArray<capnp::word>(1024)) {
dbc = dbc_lookup(dbc_name);
assert(dbc);
init_crc_lookup_tables();
@@ -312,6 +310,7 @@ std::vector<SignalValue> CANParser::query_latest() {
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],
+5
View File
@@ -26,6 +26,7 @@ cdef class CANParser:
cdef readonly:
dict vl
dict vl_all
dict ts_nanos
string dbc_name
def __init__(self, dbc_name, signals, checks=None, bus=0, enforce_checks=True):
@@ -39,6 +40,7 @@ cdef class CANParser:
self.vl = {}
self.vl_all = {}
self.ts_nanos = {}
msg_name_to_address = {}
for i in range(self.dbc[0].msgs.size()):
@@ -51,6 +53,8 @@ cdef class CANParser:
self.vl[name] = self.vl[msg.address]
self.vl_all[msg.address] = defaultdict(list)
self.vl_all[name] = self.vl_all[msg.address]
self.ts_nanos[msg.address] = {}
self.ts_nanos[name] = self.ts_nanos[msg.address]
# Convert message names into addresses
for i in range(len(signals)):
@@ -108,6 +112,7 @@ cdef class CANParser:
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
@@ -81,6 +81,7 @@ BO_ 544 EPS_2: 8 XXX
SG_ TORQUE_OVERLAY_STATUS : 6|4@0+ (1,0) [0|15] "" XXX
SG_ EPS_TORQUE_MOTOR_RAW : 19|12@0+ (1,-2048) [-2048|2047] "" XXX
SG_ EPS_TORQUE_MOTOR : 34|11@0+ (1,-1024) [-1024|1023] "" XXX
SG_ LKAS_TEMPORARY_FAULT : 38|1@0+ (1,0) [0|1] "" XXX
SG_ AUTO_PARK_HAS_CONTROL_2 : 51|1@0+ (1,0) [0|1] "" XXX
SG_ COUNTER : 55|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
+1
View File
@@ -83,6 +83,7 @@ BO_ 49 EPS_2: 8 XXX
SG_ TORQUE_OVERLAY_STATUS : 6|4@0+ (1,0) [0|15] "" XXX
SG_ EPS_TORQUE_MOTOR_RAW : 19|12@0+ (1,-2048) [-2048|2047] "" XXX
SG_ EPS_TORQUE_MOTOR : 34|11@0+ (1,-1024) [-1024|1023] "" XXX
SG_ LKAS_TEMPORARY_FAULT : 38|1@0+ (1,0) [0|1] "" XXX
SG_ AUTO_PARK_HAS_CONTROL_2 : 51|1@0+ (1,0) [0|1] "" XXX
SG_ COUNTER : 55|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
+1
View File
@@ -83,6 +83,7 @@ BO_ 544 EPS_2: 8 XXX
SG_ TORQUE_OVERLAY_STATUS : 6|4@0+ (1,0) [0|15] "" XXX
SG_ EPS_TORQUE_MOTOR_RAW : 19|12@0+ (1,-2048) [-2048|2047] "" XXX
SG_ EPS_TORQUE_MOTOR : 34|11@0+ (1,-1024) [-1024|1023] "" XXX
SG_ LKAS_TEMPORARY_FAULT : 38|1@0+ (1,0) [0|1] "" XXX
SG_ AUTO_PARK_HAS_CONTROL_2 : 51|1@0+ (1,0) [0|1] "" XXX
SG_ COUNTER : 55|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
+1 -1
View File
@@ -153,7 +153,7 @@ VAL_TABLE_ ChrgCordLck_D_Stat 7 "Faulty" 6 "LockFail" 5 "UnlockFail" 4 "LockInPr
VAL_TABLE_ LkaActvStats_D2_Req 7 "NotUsed" 6 "LkaIncrIntervRight" 5 "LkaSupprRight" 4 "LkaStandIntervRight" 3 "LkaSupprLeft" 2 "LkaStandIntervLeft" 1 "LkaIncrIntervLeft" 0 "LkaNoInterv";
VAL_TABLE_ OffOnNoDataFaulty 3 "Faulty" 2 "No_Data_Exists" 1 "On" 0 "Off";
VAL_TABLE_ NoMessage_Msg1_3 3 "Message3" 2 "Message2" 1 "Message1" 0 "NoMessage";
VAL_TABLE_ TrnRng_D_RqGsm 15 "Fault" 14 "UnknownPosition" 13 "Undefined_2" 12 "Undefined_1" 11 "_6" 10 "_5" 9 "_4" 8 "_3" 7 "_2" 6 "_1" 5 "Low" 4 "Sport_DriveSport" 3 "Drive" 2 "Neutral" 1 "Reverse" 0 "Park";
VAL_TABLE_ TrnRng_D_RqGsm 15 "Fault" 14 "UnknownPosition" 13 "Undefined_2" 12 "Undefined_1" 11 "_6" 10 "_5" 9 "_4" 8 "_3" 7 "_2" 6 "_1" 5 "Low" 4 "Sport" 3 "Drive" 2 "Neutral" 1 "Reverse" 0 "Park";
VAL_TABLE_ PrkBrkActv_D_RqGsmGear 3 "NotUsed" 2 "RequestParkBrakeEngage" 1 "NoRequest" 0 "Null";
VAL_TABLE_ TrnPrkSys_D_Actl 15 "Faulty" 14 "NotUsed_5" 13 "NotUsed_4" 12 "NotUsed_3" 11 "NotUsed_2" 10 "NotUsed_1" 9 "FrequencyError" 8 "OutOfRangeHigh" 7 "OutOfRangeLow" 6 "Override" 5 "OutOfPark" 4 "TransitionCloseToOutOfPark" 3 "AtNoSpring" 2 "TransitionCloseToPark" 1 "Park" 0 "NotKnown";
VAL_TABLE_ OKLowUnknownInvalid 3 "Invalid" 2 "Unknown" 1 "Low" 0 "OK";
@@ -160,6 +160,7 @@ BO_ 452 AcceleratorPedal2: 8 XXX
BO_ 481 ASCMSteeringButton: 7 K124_ASCM
SG_ DistanceButton : 22|1@0+ (1,0) [0|0] "" NEO
SG_ LKAButton : 23|1@0+ (1,0) [0|0] "" NEO
SG_ ACCAlwaysOne : 24|1@0+ (1,0) [0|1] "" XXX
SG_ ACCButtons : 46|3@0+ (1,0) [0|0] "" NEO
SG_ DriveModeButton : 39|1@0+ (1,0) [0|1] "" XXX
SG_ RollingCounter : 33|2@0+ (1,0) [0|3] "" NEO
@@ -193,6 +194,13 @@ BO_ 532 BRAKE_RELATED: 6 XXX
BO_ 560 EPBStatus: 8 EPB
SG_ EPBClosed : 12|1@0+ (1,0) [0|1] "" NEO
BO_ 562 EBCMFrictionBrakeStatus: 8 XXX
SG_ FrictionBrakeUnavailable : 46|1@0+ (1,0) [0|1] "" XXX
BO_ 608 SPEED_RELATED: 8 XXX
SG_ RollingCounter : 5|2@0+ (1,0) [0|0] "" XXX
SG_ ClusterSpeed : 31|8@0+ (1,0) [0|0] "" XXX
BO_ 711 BECMBatteryVoltageCurrent: 6 K17_EBCM
SG_ HVBatteryVoltage : 31|12@0+ (0.125,0) [0|511.875] "V" NEO
SG_ HVBatteryCurrent : 12|13@0- (0.15,0) [-614.4|614.25] "A" NEO
@@ -245,6 +253,7 @@ BO_ 842 EBCMWheelSpdRear: 5 K17_EBCM
BO_ 869 ASCM_365: 4 K124_ASCM
BO_ 880 ASCMActiveCruiseControlStatus: 6 K124_ASCM
SG_ ACCCruiseState : 8|3@1+ (1,0) [0|7] "" XXX
SG_ ACCLeadCar : 44|1@0+ (1,0) [0|0] "" Vector__XXX
SG_ ACCAlwaysOne2 : 32|1@0+ (1,0) [0|0] "" Vector__XXX
SG_ ACCAlwaysOne : 0|1@0+ (1,0) [0|0] "" Vector__XXX
@@ -304,9 +313,12 @@ CM_ BO_ 190 "Length varies from 6 to 8 bytes by car";
CM_ SG_ 190 GasPedalAndAcc "ACC baseline is 62";
CM_ SG_ 352 Ignition "Non-zero when ignition is on";
CM_ SG_ 451 GasPedalAndAcc2 "ACC baseline is 62";
CM_ SG_ 481 ACCAlwaysOne "Usually 1 if the car is equipped with ACC";
CM_ SG_ 562 FrictionBrakeUnavailable "1 when ACC brake control is unavailable. Stays high if brake command messages are blocked for a period of time";
CM_ SG_ 497 Ignition "Describes ignition + preconditioning mode, noisy";
CM_ SG_ 501 PRNDL2 "When ManualMode is Active, Value is 13=L1 12=L2 11=L3 ... 4=L10";
CM_ SG_ 532 UserBrakePressure "can be lower than other brake position signals when the brakes are pre-filled from ACC braking and the user presses on the brakes. user-only pressure?";
CM_ SG_ 608 ClusterSpeed "Cluster speed signal seems to match dash on newer cars, but is a lower rate and can be noisier.";
CM_ SG_ 761 UserBrakePressure2 "Similar to BRAKE_RELATED->UserBrakePressure";
CM_ SG_ 1001 VehicleSpeed "Spinouts show here on 2wd. Speed derived from right front wheel (drive tire)";
BA_DEF_ "UseGMParameterIDs" INT 0 0;
@@ -326,6 +338,7 @@ VAL_ 452 CruiseState 4 "Standstill" 3 "Faulted" 1 "Active" 0 "Off" ;
VAL_ 309 PRNDL 3 "R" 2 "D" 1 "N" 0 "P" ;
VAL_ 309 ESPButton 1 "Active" 0 "Inactive" ;
VAL_ 384 LKASteeringCmdActive 1 "Active" 0 "Inactive" ;
VAL_ 880 ACCCruiseState 2 "Adaptive" 3 "Adaptive" 4 "Non-adaptive" 5 "Non-adaptive" ;
VAL_ 880 ACCLeadCar 1 "Present" 0 "Not Present" ;
VAL_ 880 ACCGapLevel 3 "Far" 2 "Med" 1 "Near" 0 "Inactive" ;
VAL_ 880 ACCResumeButton 1 "Pressed" 0 "Depressed" ;
@@ -447,7 +447,7 @@ BO_ 432 STANDSTILL: 7 VSA
BO_ 456 ACC_CONTROL: 8 XXX
SG_ ACCEL_COMMAND : 7|12@0- (0.01,0) [0|0] "m/s^2" XXX
SG_ CONTROL_OFF : 8|1@0+ (1,0) [0|1] "" XXX
SG_ IDLESTOP_ALLOW : 8|1@0+ (1,0) [0|1] "" XXX
SG_ STANDSTILL : 9|1@0+ (1,0) [0|1] "" XXX
SG_ CONTROL_ON : 10|1@0+ (1,0) [0|1] "" XXX
SG_ BOH : 23|1@0+ (1,0) [0|1] "" XXX
@@ -496,7 +496,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_ BO_ 456 "not sure which bit enables cruise";
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";
VAL_ 401 GEAR_SHIFTER 32 "L" 16 "S" 8 "D" 4 "N" 2 "R" 1 "P";
+26 -5
View File
@@ -33,7 +33,7 @@ NS_ :
BS_:
BU_: XXX CAMERA FRONT_RADAR ADRV
BU_: XXX CAMERA FRONT_RADAR ADRV APRK
BO_ 53 ACCELERATOR: 32 XXX
@@ -86,6 +86,11 @@ BO_ 101 BRAKE: 32 XXX
SG_ BRAKE_POSITION : 40|16@1- (1,0) [0|65535] "" XXX
SG_ BRAKE_PRESSED : 57|1@1+ (1,0) [0|3] "" XXX
BO_ 112 GEAR_ALT_2: 32 XXX
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ GEAR : 60|3@1+ (1,0) [0|7] "" XXX
BO_ 160 WHEEL_SPEEDS: 24 XXX
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
@@ -144,6 +149,17 @@ BO_ 304 GEAR_SHIFTER: 16 XXX
SG_ GEAR : 64|3@1+ (1,0) [0|7] "" XXX
SG_ KNOB_POSITION : 40|3@1+ (1,0) [0|3] "" XXX
BO_ 357 SPAS1: 24 APRK
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|0] "" XXX
SG_ NEW_SIGNAL_1 : 96|16@1- (0.1,0) [0|0] "" XXX
SG_ NEW_SIGNAL_2 : 90|3@1+ (1,0) [0|0] "" XXX
BO_ 362 SPAS2: 32 APRK
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|0] "" XXX
SG_ BLINKER_CONTROL : 133|3@1+ (1,0) [0|0] "" XXX
BO_ 373 TCS: 24 XXX
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
@@ -162,6 +178,7 @@ BO_ 373 TCS: 24 XXX
SG_ DriverBrakingLowSens : 84|1@1+ (1,0) [0|1] "" XXX
SG_ ACC_REQ : 68|1@0+ (1,0) [0|1] "" XXX
SG_ ACCEL_REF_ACC : 48|11@1- (1,0) [0|1023] "" XXX
SG_ ACCEnable : 67|2@0+ (1,0) [0|3] "" XXX
BO_ 352 ADRV_0x160: 16 ADRV
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
@@ -200,7 +217,6 @@ BO_ 416 SCC_CONTROL: 32 ADRV
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ NEW_SIGNAL_1 : 64|2@1+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_8 : 170|4@1+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 156|5@0+ (1,0) [0|3] "" XXX
SG_ ZEROS : 215|48@0+ (1,0) [0|281474976710655] "" XXX
SG_ ZEROS_3 : 191|7@0+ (1,0) [0|127] "" XXX
SG_ ZEROS_4 : 183|4@0+ (1,0) [0|63] "" XXX
@@ -225,7 +241,6 @@ BO_ 416 SCC_CONTROL: 32 ADRV
SG_ aReqRaw : 140|11@1+ (0.01,-10.23) [-10.23|10.24] "m/s^2" XXX
SG_ aReqValue : 128|11@1+ (0.01,-10.23) [-10.23|10.24] "m/s^2" XXX
SG_ ZEROS_7 : 63|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_4 : 158|2@0+ (1,0) [0|3] "" XXX
SG_ ACCMode : 68|3@1+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_12 : 35|9@1+ (0.1,0) [0|255] "" XXX
SG_ JerkLowerLimit : 166|7@0+ (0.1,0) [0|12.7] "m/s^3" XXX
@@ -233,12 +248,14 @@ BO_ 416 SCC_CONTROL: 32 ADRV
SG_ NEW_SIGNAL_15 : 192|11@1+ (0.1,0) [0|204.7] "m" XXX
SG_ VSetDis : 103|8@0+ (1,0) [0|255] "km/h or mph" XXX
SG_ MainMode_ACC : 66|1@1+ (1,0) [0|1] "" XXX
SG_ JerkUpperLimit : 158|7@0+ (0.1,0) [0|0] "" XXX
BO_ 426 CRUISE_BUTTONS_ALT: 16 XXX
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 24|4@1+ (1,0) [0|15] "" XXX
SG_ SET_ME_1 : 28|3@1+ (1,0) [0|7] "" XXX
SG_ SET_ME_1 : 28|2@1+ (1,0) [0|3] "" XXX
SG_ DISTANCE_UNIT : 30|1@1+ (1,0) [0|1] "" XXX
SG_ NEW_SIGNAL_2 : 31|3@1+ (1,0) [0|7] "" XXX
SG_ ADAPTIVE_CRUISE_MAIN_BTN : 34|1@1+ (1,0) [0|1] "" XXX
SG_ NEW_SIGNAL_3 : 35|1@1+ (1,0) [0|1] "" XXX
@@ -516,7 +533,7 @@ BO_ 485 BLINDSPOTS_FRONT_CORNER_1: 16 XXX
SG_ NEW_SIGNAL_3 : 88|1@0+ (1,0) [0|1] "" XXX
SG_ NEW_SIGNAL_4 : 80|1@0+ (1,0) [0|1] "" XXX
SG_ NEW_SIGNAL_5 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_6 : 24|1@0+ (1,0) [0|1] "" XXX
SG_ REVERSING : 24|1@0+ (1,0) [0|1] "" XXX
SG_ NEW_SIGNAL_7 : 32|2@1+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_8 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_9 : 55|8@0+ (1,0) [0|255] "" XXX
@@ -539,6 +556,7 @@ BO_ 506 CLUSTER_SPEED_LIMIT: 32 XXX
CM_ SG_ 96 BRAKE_PRESSURE "User applied brake pedal pressure. Ramps from computer applied pressure on falling edge of cruise. Cruise cancels if !=0";
CM_ SG_ 101 BRAKE_POSITION "User applied brake pedal position, max is ~700. Signed on some vehicles";
CM_ SG_ 373 PROBABLY_EQUIP "aeb equip?";
CM_ SG_ 373 ACCEnable "Likely a copy of CAN's TCS13->ACCEnable";
CM_ SG_ 373 DriverBraking "Likely derived from BRAKE->BRAKE_POSITION";
CM_ SG_ 373 DriverBrakingLowSens "Higher threshold version of DriverBraking";
CM_ SG_ 352 SET_ME_9 "has something to do with AEB settings";
@@ -549,6 +567,7 @@ CM_ SG_ 1043 COUNTER_ALT "only increments on change";
VAL_ 53 GEAR 0 "P" 5 "D" 6 "N" 7 "R" ;
VAL_ 64 GEAR 0 "P" 5 "D" 6 "N" 7 "R" ;
VAL_ 69 GEAR 0 "P" 5 "D" 6 "N" 7 "R" ;
VAL_ 112 GEAR 0 "P" 5 "D" 6 "N" 7 "R" ;
VAL_ 80 LKA_ICON 0 "hidden" 1 "grey" 2 "green" 3 "flashing green" ;
VAL_ 80 LKA_MODE 1 "warning only" 2 "assist" 6 "off" ;
VAL_ 234 LKA_FAULT 0 "ok" 1 "lka fault" ;
@@ -556,6 +575,8 @@ VAL_ 298 LKA_ICON 0 "hidden" 1 "grey" 2 "green" 3 "flashing green" ;
VAL_ 298 LKA_MODE 1 "warning only" 2 "assist" 6 "off" ;
VAL_ 304 GEAR 1 "P" 2 "R" 3 "N" 4 "D" ;
VAL_ 352 AEB_SETTING 1 "off" 2 "warning only" 3 "active assist" ;
VAL_ 362 BLINKER_CONTROL 1 "hazards" 2 "hazards button backlight" 3 "left blinkers" 4 "right blinkers";
VAL_ 373 ACCEnable 0 "SCC ready" 1 "SCC temp fault" 2 "SCC permanent fault" 3 "SCC permanent fault, communication issue";
VAL_ 416 ACCMode 0 "off" 1 "enabled" 2 "driver_override" 3 "off_maybe_fault" 4 "cancelled" ;
VAL_ 426 CRUISE_BUTTONS 0 "none" 1 "res_accel" 2 "set_decel" 3 "gap_distance" 4 "pause_resume" ;
VAL_ 463 CRUISE_BUTTONS 0 "none" 1 "res_accel" 2 "set_decel" 3 "gap_distance" 4 "pause_resume" ;
+8 -8
View File
@@ -352,12 +352,10 @@ BO_ 130 STEER: 8 XXX
SG_ CHKSUM_MAYBE : 39|8@0+ (1,0) [0|255] "" XXX
BO_ 120 BRAKE: 8 XXX
SG_ NEW_SIGNAL_1 : 7|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_2 : 15|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_3 : 23|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_4 : 31|8@0+ (1,0) [0|255] "" XXX
SG_ CTR : 55|8@0+ (1,0) [0|255] "" XXX
SG_ BRAKE_PRESSURE : 39|8@0+ (1,0) [0|255] "" XXX
SG_ VEHICLE_ACC_X : 5|13@0+ (0.01,-40) [-40|40] "m/s^2" XXX
SG_ VEHICLE_ACC_Y : 8|13@0+ (0.001,-4.096) [-4.096|4.096] "m/s^2" XXX
BO_ 304 GEAR_RELATED: 8 XXX
SG_ NEW_SIGNAL_1 : 55|8@0+ (1,0) [0|255] "" XXX
@@ -556,8 +554,6 @@ BO_ 535 CURVE_CTRS: 8 XXX
BO_ 540 CRZ_CTRL: 8 XXX
SG_ NEW_SIGNAL_6 : 10|1@0+ (1,0) [0|1] "" XXX
SG_ NEW_SIGNAL_9 : 31|1@0+ (1,0) [0|255] "" XXX
SG_ ACC_GAS_MAYBE2 : 29|1@0+ (1,0) [0|1] "" XXX
SG_ HANDS_OFF_STEERING : 48|1@0+ (1,0) [0|1] "" XXX
SG_ HANDS_ON_STEER_WARN : 59|4@0+ (1,0) [0|255] "" XXX
SG_ CRZ_ACTIVE : 3|1@0+ (1,0) [0|1] "" XXX
@@ -565,13 +561,13 @@ BO_ 540 CRZ_CTRL: 8 XXX
SG_ DISTANCE_SETTING : 20|3@0+ (1,0) [0|7] "" XXX
SG_ MSG_1_INV : 1|1@0+ (1,0) [0|1] "" XXX
SG_ MSG_1_COPY : 9|1@0+ (1,0) [0|1] "" XXX
SG_ ACC_GAS_MAYBE : 23|1@0+ (1,0) [0|31] "" XXX
SG_ ACC_ACTIVE_2 : 52|1@0+ (1,0) [0|1] "" XXX
SG_ NEW_SIGNAL_10 : 30|1@0+ (1,0) [0|1] "" XXX
SG_ MSG_1 : 0|1@0+ (1,0) [0|3] "" XXX
SG_ 5_SEC_DISABLE_TIMER : 45|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_3 : 13|1@0+ (1,0) [0|3] "" XXX
SG_ MSG_1_INV_COPY : 8|1@0+ (1,0) [0|7] "" XXX
SG_ RADAR_HAS_LEAD : 23|1@0+ (1,0) [0|1] "" XXX
SG_ RADAR_LEAD_RELATIVE_DISTANCE : 31|3@0+ (1,0) [0|5] "" XXX
BO_ 539 CRZ_INFO: 8 XXX
SG_ CTR1 : 55|8@0+ (1,0) [0|255] "" XXX
@@ -765,6 +761,8 @@ CM_ SG_ 1157 LANEE_DEPARTURE_ALERT "1 off, 2 on";
CM_ SG_ 1157 WARNING "1 Rare, 0 often";
CM_ SG_ 1088 LANE_LINES "0 LKAS disabled, 1 no lines, 2 two lines, 3 left line, 4 right line";
CM_ SG_ 1045 ABS_MALFUNCTION "off: 0, solid: 1, slow blink: 2, fast blink: 3";
CM_ SG_ 120 VEHICLE_ACC_X "Vehicle acceleration of X-axis wrt. NED frame.";
CM_ SG_ 120 VEHICLE_ACC_Y "Vehicle acceleration of Y-axis wrt. NED frame.";
CM_ SG_ 157 CAN_OFF "Disengage Cruise if enabled, if already disabled TURN it OFF ";
CM_ SG_ 552 MORE_GEAR "";
CM_ SG_ 552 GEAR "0 Shifting, 1 P, 2 R, 3 N, 4 D";
@@ -773,3 +771,5 @@ CM_ SG_ 540 HANDS_ON_STEER_WARN "0 no warning, b warning";
CM_ SG_ 540 DISTANCE_SETTING "Radar distance 0: disabled, 1: 4 bars, 2: 3 bars, 3: 2 bars, 4: 1 bar";
CM_ SG_ 1143 REAR_CT_ALERT "Rear Cross Traffic Alert";
VAL_ 552 GEAR 1 "P" 2 "R" 3 "N" 4 "D" ;
VAL_ 540 RADAR_HAS_LEAD 0 "NO LEAD" 1 "HAS LEAD" ;
VAL_ 540 RADAR_LEAD_RELATIVE_DISTANCE 0 "NO LEAD" 1 "FARTHEST" 2 "4" 3 "3" 4 "2" 5 "NEAREST" ;
+10 -5
View File
@@ -106,7 +106,7 @@ BO_ 180 SPEED: 8 XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 295 GEAR_PACKET_HYBRID: 8 XXX
SG_ CAR_MOVEMENT : 39|8@0- (1,0) [0|255] "" XXX
SG_ CAR_MOVEMENT : 25|10@0- (1,0) [0|255] "" XXX
SG_ COUNTER : 55|8@0+ (1,0) [0|255] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
SG_ GEAR : 47|4@0+ (1,0) [0|15] "" XXX
@@ -128,9 +128,10 @@ BO_ 466 PCM_CRUISE: 8 XXX
BO_ 467 PCM_CRUISE_2: 8 XXX
SG_ PCM_FOLLOW_DISTANCE : 12|2@0+ (1,0) [0|3] "" XXX
SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX
SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "" XXX
SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX
SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "km/h" XXX
SG_ ACC_FAULTED : 47|1@0+ (1,0) [0|1] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 552 ACCELEROMETER: 8 XXX
@@ -209,8 +210,9 @@ BO_ 836 PRE_COLLISION_2: 8 DSU
SG_ CHECKSUM : 63|8@0+ (1,0) [0|0] "" XXX
BO_ 865 CLUTCH: 8 XXX
SG_ CLUTCH_RELEASED : 38|1@0+ (1,0) [0|1] "" XXX
SG_ ACC_FAULTED : 32|1@0+ (1,0) [0|1] "" XXX
SG_ GAS_PEDAL_ALT : 23|8@0+ (0.005,0) [0|1] "" XXX
SG_ CLUTCH_RELEASED : 38|1@0+ (1,0) [0|1] "" XXX
BO_ 869 DSU_CRUISE : 7 DSU
SG_ RES_BTN : 3|1@0+ (1,0) [0|0] "" XXX
@@ -225,6 +227,7 @@ BO_ 921 PCM_CRUISE_SM: 8 XXX
SG_ MAIN_ON : 4|1@0+ (1,0) [0|1] "" XXX
SG_ CRUISE_CONTROL_STATE : 11|4@0+ (1,0) [0|15] "" XXX
SG_ DISTANCE_LINES : 14|2@0+ (1,0) [0|3] "" XXX
SG_ TEMP_ACC_FAULTED : 15|1@0+ (1,0) [0|1] "" XXX
SG_ UI_SET_SPEED : 31|8@0+ (1,0) [0|255] "" XXX
BO_ 951 ESP_CONTROL: 8 ESP
@@ -377,8 +380,7 @@ BO_ 1552 BODY_CONTROL_STATE_2: 8 XXX
BO_ 1553 UI_SETTING: 8 XXX
SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX
SG_ ODOMETER : 43|20@0+ (1,0) [0|1048575] "" XXX
SG_ ODOMETER : 39|32@0+ (1,0) [0|1048575] "" XXX
BO_ 1556 BLINKERS_STATE: 8 XXX
SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX
SG_ HAZARD_LIGHT : 27|1@0+ (1,0) [0|1] "" XXX
@@ -416,6 +418,7 @@ CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; n
CM_ SG_ 37 STEER_RATE "factor is tbd";
CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors";
CM_ SG_ 466 CRUISE_STATE "Active state is 8, if standstill is requested will switch to state 11(3 sec timer), after timer is elapsed will switch into state 7(standstill). If plus button was pressed - status 9, minus button pressed - status 10";
CM_ SG_ 467 ACC_FAULTED "1 when ACC is faulted and the PCM disallows engagement";
CM_ SG_ 467 SET_SPEED "43 km/h are shown as 28 mph, so conversion isn't perfect";
CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
@@ -437,7 +440,9 @@ CM_ SG_ 835 PERMIT_BRAKING "Original ACC has this going high when a car in front
CM_ SG_ 835 ACCEL_CMD_ALT "Copy of main ACCEL_CMD, but across 8 bits instead of 16 bits like ACCEL_CMD. Unsure if only informational or has an effect. Likely informational as existing openpilot sets this to 0 and no loss of functionality observed. Originally 'AT_RAW' in leaked toyota_2017_ref_pt.dbc file.";
CM_ SG_ 865 GAS_PEDAL_ALT "copy of main GAS_PEDAL. Both use 8 bits. Might indicate that this message is for pedals.";
CM_ SG_ 865 CLUTCH_RELEASED "boolean of clutch for 6MT.";
CM_ SG_ 865 ACC_FAULTED "1 when ACC is faulted and the PCM disallows engagement";
CM_ SG_ 921 UI_SET_SPEED "set speed shown in the vehicle's UI with the vehicle's unit";
CM_ SG_ 921 TEMP_ACC_FAULTED "1 when the UI is displaying or playing fault-related alerts or sounds. Also 1 when pressing main on.";
CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel";
CM_ SG_ 956 GEAR "on 6MT, only R shows.";
CM_ SG_ 1009 UI_SET_SPEED "units seem to be whatever the car is set to";
+17 -10
View File
@@ -106,7 +106,7 @@ BO_ 180 SPEED: 8 XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 295 GEAR_PACKET_HYBRID: 8 XXX
SG_ CAR_MOVEMENT : 39|8@0- (1,0) [0|255] "" XXX
SG_ CAR_MOVEMENT : 25|10@0- (1,0) [0|255] "" XXX
SG_ COUNTER : 55|8@0+ (1,0) [0|255] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
SG_ GEAR : 47|4@0+ (1,0) [0|15] "" XXX
@@ -128,9 +128,10 @@ BO_ 466 PCM_CRUISE: 8 XXX
BO_ 467 PCM_CRUISE_2: 8 XXX
SG_ PCM_FOLLOW_DISTANCE : 12|2@0+ (1,0) [0|3] "" XXX
SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX
SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "" XXX
SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX
SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "km/h" XXX
SG_ ACC_FAULTED : 47|1@0+ (1,0) [0|1] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 552 ACCELEROMETER: 8 XXX
@@ -209,8 +210,9 @@ BO_ 836 PRE_COLLISION_2: 8 DSU
SG_ CHECKSUM : 63|8@0+ (1,0) [0|0] "" XXX
BO_ 865 CLUTCH: 8 XXX
SG_ CLUTCH_RELEASED : 38|1@0+ (1,0) [0|1] "" XXX
SG_ ACC_FAULTED : 32|1@0+ (1,0) [0|1] "" XXX
SG_ GAS_PEDAL_ALT : 23|8@0+ (0.005,0) [0|1] "" XXX
SG_ CLUTCH_RELEASED : 38|1@0+ (1,0) [0|1] "" XXX
BO_ 869 DSU_CRUISE : 7 DSU
SG_ RES_BTN : 3|1@0+ (1,0) [0|0] "" XXX
@@ -225,6 +227,7 @@ BO_ 921 PCM_CRUISE_SM: 8 XXX
SG_ MAIN_ON : 4|1@0+ (1,0) [0|1] "" XXX
SG_ CRUISE_CONTROL_STATE : 11|4@0+ (1,0) [0|15] "" XXX
SG_ DISTANCE_LINES : 14|2@0+ (1,0) [0|3] "" XXX
SG_ TEMP_ACC_FAULTED : 15|1@0+ (1,0) [0|1] "" XXX
SG_ UI_SET_SPEED : 31|8@0+ (1,0) [0|255] "" XXX
BO_ 951 ESP_CONTROL: 8 ESP
@@ -377,8 +380,7 @@ BO_ 1552 BODY_CONTROL_STATE_2: 8 XXX
BO_ 1553 UI_SETTING: 8 XXX
SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX
SG_ ODOMETER : 43|20@0+ (1,0) [0|1048575] "" XXX
SG_ ODOMETER : 39|32@0+ (1,0) [0|1048575] "" XXX
BO_ 1556 BLINKERS_STATE: 8 XXX
SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX
SG_ HAZARD_LIGHT : 27|1@0+ (1,0) [0|1] "" XXX
@@ -416,6 +418,7 @@ CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; n
CM_ SG_ 37 STEER_RATE "factor is tbd";
CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors";
CM_ SG_ 466 CRUISE_STATE "Active state is 8, if standstill is requested will switch to state 11(3 sec timer), after timer is elapsed will switch into state 7(standstill). If plus button was pressed - status 9, minus button pressed - status 10";
CM_ SG_ 467 ACC_FAULTED "1 when ACC is faulted and the PCM disallows engagement";
CM_ SG_ 467 SET_SPEED "43 km/h are shown as 28 mph, so conversion isn't perfect";
CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
@@ -437,7 +440,9 @@ CM_ SG_ 835 PERMIT_BRAKING "Original ACC has this going high when a car in front
CM_ SG_ 835 ACCEL_CMD_ALT "Copy of main ACCEL_CMD, but across 8 bits instead of 16 bits like ACCEL_CMD. Unsure if only informational or has an effect. Likely informational as existing openpilot sets this to 0 and no loss of functionality observed. Originally 'AT_RAW' in leaked toyota_2017_ref_pt.dbc file.";
CM_ SG_ 865 GAS_PEDAL_ALT "copy of main GAS_PEDAL. Both use 8 bits. Might indicate that this message is for pedals.";
CM_ SG_ 865 CLUTCH_RELEASED "boolean of clutch for 6MT.";
CM_ SG_ 865 ACC_FAULTED "1 when ACC is faulted and the PCM disallows engagement";
CM_ SG_ 921 UI_SET_SPEED "set speed shown in the vehicle's UI with the vehicle's unit";
CM_ SG_ 921 TEMP_ACC_FAULTED "1 when the UI is displaying or playing fault-related alerts or sounds. Also 1 when pressing main on.";
CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel";
CM_ SG_ 956 GEAR "on 6MT, only R shows.";
CM_ SG_ 1009 UI_SET_SPEED "units seem to be whatever the car is set to";
@@ -539,10 +544,11 @@ BO_ 401 STEERING_LTA: 8 XXX
SG_ SETME_X64 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ ANGLE : 55|8@0- (0.5,0) [0|255] "" XXX
SG_ STEER_ANGLE_CMD : 15|16@0- (0.0573,0) [-540|540] "" XXX
SG_ STEER_REQUEST : 25|1@0+ (1,0) [0|1] "" XXX
SG_ STEER_REQUEST_2 : 25|1@0+ (1,0) [0|1] "" XXX
SG_ LKA_ACTIVE : 26|1@0+ (1,0) [0|1] "" XXX
SG_ BIT : 30|1@0+ (1,0) [0|1] "" XXX
SG_ COUNTER : 6|6@0+ (1,0) [0|255] "" XXX
SG_ STEER_REQUEST_2 : 0|1@0+ (1,0) [0|1] "" XXX
SG_ STEER_REQUEST : 0|1@0+ (1,0) [0|1] "" XXX
SG_ SETME_X1 : 7|1@0+ (1,0) [0|1] "" XXX
BO_ 550 BRAKE_MODULE: 8 XXX
@@ -569,9 +575,10 @@ CM_ SG_ 401 PERCENTAGE "driver override percentage (0-100), very close to steeri
CM_ SG_ 401 SETME_X64 "ramps to 0 smoothly then back on falling edge of STEER_REQUEST if BIT isn't 1";
CM_ SG_ 401 ANGLE "angle of car relative to lane center on LTA camera";
CM_ SG_ 401 STEER_ANGLE_CMD "desired angle, OEM steers up to 95 degrees, no angle limit but torque will bottom out";
CM_ SG_ 401 STEER_REQUEST "enable bit for steering, 1 to steer, 0 to not";
CM_ SG_ 401 BIT "has correlation to STEER_REQUEST";
CM_ SG_ 401 STEER_REQUEST "enable bit for steering, 1 to steer, 0 to not";
CM_ SG_ 401 STEER_REQUEST_2 "enable bit for steering, 1 to steer, 0 to not";
CM_ SG_ 401 LKA_ACTIVE "1 when using LTA for LKA";
CM_ SG_ 550 BRAKE_PRESSURE "seems prop to pedal force";
CM_ SG_ 550 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";
@@ -583,5 +590,5 @@ CM_ SG_ 1014 ADJACENT_ENABLED "when BSM is enabled in settings, this is on along
CM_ SG_ 1014 APPROACHING_ENABLED "when BSM is enabled in settings, this is on along with ADJACENT_ENABLED. this controls bsm alert visibility";
VAL_ 610 IPAS_STATE 5 "override" 3 "enabled" 1 "disabled";
VAL_ 610 LKA_STATE 25 "temporary_fault" 17 "permanent_fault" 9 "temporary_fault2" 5 "active" 1 "standby";
VAL_ 610 LTA_STATE 25 "temporary_fault" 9 "temporary_fault2" 5 "active" 1 "standby";
VAL_ 610 LKA_STATE 25 "temporary_fault" 17 "permanent_fault" 11 "lka_missing_unavailable2" 9 "temporary_fault2" 5 "active" 3 "lka_missing_unavailable" 1 "standby";
VAL_ 610 LTA_STATE 25 "temporary_fault" 9 "temporary_fault2" 5 "active" 3 "lta_missing_unavailable" 1 "standby";
+10 -5
View File
@@ -106,7 +106,7 @@ BO_ 180 SPEED: 8 XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 295 GEAR_PACKET_HYBRID: 8 XXX
SG_ CAR_MOVEMENT : 39|8@0- (1,0) [0|255] "" XXX
SG_ CAR_MOVEMENT : 25|10@0- (1,0) [0|255] "" XXX
SG_ COUNTER : 55|8@0+ (1,0) [0|255] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
SG_ GEAR : 47|4@0+ (1,0) [0|15] "" XXX
@@ -128,9 +128,10 @@ BO_ 466 PCM_CRUISE: 8 XXX
BO_ 467 PCM_CRUISE_2: 8 XXX
SG_ PCM_FOLLOW_DISTANCE : 12|2@0+ (1,0) [0|3] "" XXX
SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX
SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "" XXX
SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX
SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "km/h" XXX
SG_ ACC_FAULTED : 47|1@0+ (1,0) [0|1] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 552 ACCELEROMETER: 8 XXX
@@ -209,8 +210,9 @@ BO_ 836 PRE_COLLISION_2: 8 DSU
SG_ CHECKSUM : 63|8@0+ (1,0) [0|0] "" XXX
BO_ 865 CLUTCH: 8 XXX
SG_ CLUTCH_RELEASED : 38|1@0+ (1,0) [0|1] "" XXX
SG_ ACC_FAULTED : 32|1@0+ (1,0) [0|1] "" XXX
SG_ GAS_PEDAL_ALT : 23|8@0+ (0.005,0) [0|1] "" XXX
SG_ CLUTCH_RELEASED : 38|1@0+ (1,0) [0|1] "" XXX
BO_ 869 DSU_CRUISE : 7 DSU
SG_ RES_BTN : 3|1@0+ (1,0) [0|0] "" XXX
@@ -225,6 +227,7 @@ BO_ 921 PCM_CRUISE_SM: 8 XXX
SG_ MAIN_ON : 4|1@0+ (1,0) [0|1] "" XXX
SG_ CRUISE_CONTROL_STATE : 11|4@0+ (1,0) [0|15] "" XXX
SG_ DISTANCE_LINES : 14|2@0+ (1,0) [0|3] "" XXX
SG_ TEMP_ACC_FAULTED : 15|1@0+ (1,0) [0|1] "" XXX
SG_ UI_SET_SPEED : 31|8@0+ (1,0) [0|255] "" XXX
BO_ 951 ESP_CONTROL: 8 ESP
@@ -377,8 +380,7 @@ BO_ 1552 BODY_CONTROL_STATE_2: 8 XXX
BO_ 1553 UI_SETTING: 8 XXX
SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX
SG_ ODOMETER : 43|20@0+ (1,0) [0|1048575] "" XXX
SG_ ODOMETER : 39|32@0+ (1,0) [0|1048575] "" XXX
BO_ 1556 BLINKERS_STATE: 8 XXX
SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX
SG_ HAZARD_LIGHT : 27|1@0+ (1,0) [0|1] "" XXX
@@ -416,6 +418,7 @@ CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; n
CM_ SG_ 37 STEER_RATE "factor is tbd";
CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors";
CM_ SG_ 466 CRUISE_STATE "Active state is 8, if standstill is requested will switch to state 11(3 sec timer), after timer is elapsed will switch into state 7(standstill). If plus button was pressed - status 9, minus button pressed - status 10";
CM_ SG_ 467 ACC_FAULTED "1 when ACC is faulted and the PCM disallows engagement";
CM_ SG_ 467 SET_SPEED "43 km/h are shown as 28 mph, so conversion isn't perfect";
CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph";
CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?";
@@ -437,7 +440,9 @@ CM_ SG_ 835 PERMIT_BRAKING "Original ACC has this going high when a car in front
CM_ SG_ 835 ACCEL_CMD_ALT "Copy of main ACCEL_CMD, but across 8 bits instead of 16 bits like ACCEL_CMD. Unsure if only informational or has an effect. Likely informational as existing openpilot sets this to 0 and no loss of functionality observed. Originally 'AT_RAW' in leaked toyota_2017_ref_pt.dbc file.";
CM_ SG_ 865 GAS_PEDAL_ALT "copy of main GAS_PEDAL. Both use 8 bits. Might indicate that this message is for pedals.";
CM_ SG_ 865 CLUTCH_RELEASED "boolean of clutch for 6MT.";
CM_ SG_ 865 ACC_FAULTED "1 when ACC is faulted and the PCM disallows engagement";
CM_ SG_ 921 UI_SET_SPEED "set speed shown in the vehicle's UI with the vehicle's unit";
CM_ SG_ 921 TEMP_ACC_FAULTED "1 when the UI is displaying or playing fault-related alerts or sounds. Also 1 when pressing main on.";
CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel";
CM_ SG_ 956 GEAR "on 6MT, only R shows.";
CM_ SG_ 1009 UI_SET_SPEED "units seem to be whatever the car is set to";
+3
View File
@@ -18,3 +18,6 @@ examples/output.csv
nosetests.xml
.mypy_cache/
.sconsign.dblite
# CTU info files generated by Cppcheck
*.*.ctu-info
+6
View File
@@ -0,0 +1,6 @@
# panda fw
SConscript('board/SConscript')
# test files
if GetOption('test'):
SConscript('tests/libpanda/SConscript')
+5 -10
View File
@@ -1,10 +1,5 @@
# flake8: noqa
# pylint: skip-file
from .python import Panda, PandaDFU, flash_release, \
BASEDIR, ensure_st_up_to_date, PandaSerial, pack_can_buffer, unpack_can_buffer, \
DEFAULT_FW_FN, DEFAULT_H7_FW_FN, MCU_TYPE_H7, MCU_TYPE_F4, DLC_TO_LEN, LEN_TO_DLC, \
ALTERNATIVE_EXPERIENCE
from .python.config import BOOTSTUB_ADDRESS, BLOCK_SIZE_FX, APP_ADDRESS_FX, \
BLOCK_SIZE_H7, APP_ADDRESS_H7, DEVICE_SERIAL_NUMBER_ADDR_H7, \
DEVICE_SERIAL_NUMBER_ADDR_FX
from .python.constants import McuType, BASEDIR # noqa: F401
from .python.serial import PandaSerial # noqa: F401
from .python import (Panda, PandaDFU, # noqa: F401
pack_can_buffer, unpack_can_buffer, calculate_checksum,
DLC_TO_LEN, LEN_TO_DLC, ALTERNATIVE_EXPERIENCE, USBPACKET_MAX_SIZE, CANPACKET_HEAD_SIZE)
-17
View File
@@ -1,20 +1,3 @@
Dependencies
--------
**Mac**
```
xcode-select --install
./get_sdk_mac.sh
```
**Debian / Ubuntu**
```
./get_sdk.sh
```
Programming
----
+6 -6
View File
@@ -17,7 +17,7 @@ void black_enable_can_transceiver(uint8_t transceiver, bool enabled) {
set_gpio_output(GPIOB, 10, !enabled);
break;
default:
puts("Invalid CAN transceiver ("); puth(transceiver); puts("): enabling failed\n");
print("Invalid CAN transceiver ("); puth(transceiver); print("): enabling failed\n");
break;
}
}
@@ -74,7 +74,7 @@ void black_set_gps_mode(uint8_t mode) {
set_gpio_output(GPIOC, 5, 0);
break;
default:
puts("Invalid GPS mode\n");
print("Invalid GPS mode\n");
break;
}
}
@@ -102,7 +102,7 @@ void black_set_can_mode(uint8_t mode){
}
break;
default:
puts("Tried to set unsupported CAN mode: "); puth(mode); puts("\n");
print("Tried to set unsupported CAN mode: "); puth(mode); print("\n");
break;
}
}
@@ -202,6 +202,6 @@ const board board_black = {
.set_fan_enabled = unused_set_fan_enabled,
.set_ir_power = unused_set_ir_power,
.set_phone_power = unused_set_phone_power,
.set_clock_source_mode = unused_set_clock_source_mode,
.set_siren = unused_set_siren
};
.set_siren = unused_set_siren,
.read_som_gpio = unused_read_som_gpio
};
+2 -2
View File
@@ -10,9 +10,9 @@ typedef uint32_t (*board_read_current)(void);
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_clock_source_mode)(uint8_t mode);
typedef void (*board_set_siren)(bool enabled);
typedef void (*board_board_tick)(bool ignition, bool usb_enum, bool heartbeat_seen);
typedef bool (*board_read_som_gpio)(void);
struct board {
const char *board_type;
@@ -36,9 +36,9 @@ struct board {
board_set_ir_power set_ir_power;
board_set_fan_enabled set_fan_enabled;
board_set_phone_power set_phone_power;
board_set_clock_source_mode set_clock_source_mode;
board_set_siren set_siren;
board_board_tick board_tick;
board_read_som_gpio read_som_gpio;
};
// ******************* Definitions ********************
+13 -13
View File
@@ -17,7 +17,7 @@ void dos_enable_can_transceiver(uint8_t transceiver, bool enabled) {
set_gpio_output(GPIOB, 10, !enabled);
break;
default:
puts("Invalid CAN transceiver ("); puth(transceiver); puts("): enabling failed\n");
print("Invalid CAN transceiver ("); puth(transceiver); print("): enabling failed\n");
break;
}
}
@@ -88,7 +88,7 @@ void dos_set_can_mode(uint8_t mode){
}
break;
default:
puts("Tried to set unsupported CAN mode: "); puth(mode); puts("\n");
print("Tried to set unsupported CAN mode: "); puth(mode); print("\n");
break;
}
}
@@ -110,14 +110,14 @@ void dos_set_fan_enabled(bool enabled){
set_gpio_output(GPIOA, 1, enabled);
}
void dos_set_clock_source_mode(uint8_t mode){
clock_source_init(mode);
}
void dos_set_siren(bool enabled){
set_gpio_output(GPIOC, 12, enabled);
}
bool dos_read_som_gpio (void){
return (get_gpio_input(GPIOC, 2) != 0);
}
void dos_init(void) {
common_init_gpio();
@@ -151,15 +151,15 @@ void dos_init(void) {
// C8: FAN PWM aka TIM3_CH3
set_gpio_alternate(GPIOC, 8, GPIO_AF2_TIM3);
// C2: SOM GPIO used as input (fan control at boot)
set_gpio_mode(GPIOC, 2, MODE_INPUT);
set_gpio_pullup(GPIOC, 2, PULL_DOWN);
// Initialize IR PWM and set to 0%
set_gpio_alternate(GPIOB, 7, GPIO_AF2_TIM4);
pwm_init(TIM4, 2);
dos_set_ir_power(0U);
// Initialize fan and set to 0%
fan_init();
dos_set_fan_enabled(false);
// Initialize harness
harness_init();
@@ -186,7 +186,7 @@ void dos_init(void) {
}
// Init clock source (camera strobe) using PWM
dos_set_clock_source_mode(CLOCK_SOURCE_MODE_PWM);
clock_source_init();
}
const harness_configuration dos_harness_config = {
@@ -230,6 +230,6 @@ const board board_dos = {
.set_fan_enabled = dos_set_fan_enabled,
.set_ir_power = dos_set_ir_power,
.set_phone_power = unused_set_phone_power,
.set_clock_source_mode = dos_set_clock_source_mode,
.set_siren = dos_set_siren
.set_siren = dos_set_siren,
.read_som_gpio = dos_read_som_gpio
};
+3 -3
View File
@@ -28,7 +28,7 @@ void grey_set_gps_mode(uint8_t mode) {
set_gpio_output(GPIOC, 5, 0);
break;
default:
puts("Invalid ESP/GPS mode\n");
print("Invalid ESP/GPS mode\n");
break;
}
}
@@ -56,6 +56,6 @@ const board board_grey = {
.set_fan_enabled = unused_set_fan_enabled,
.set_ir_power = unused_set_ir_power,
.set_phone_power = unused_set_phone_power,
.set_clock_source_mode = unused_set_clock_source_mode,
.set_siren = unused_set_siren
.set_siren = unused_set_siren,
.read_som_gpio = unused_read_som_gpio
};
+5 -5
View File
@@ -8,7 +8,7 @@ void pedal_enable_can_transceiver(uint8_t transceiver, bool enabled) {
set_gpio_output(GPIOB, 3, !enabled);
break;
default:
puts("Invalid CAN transceiver ("); puth(transceiver); puts("): enabling failed\n");
print("Invalid CAN transceiver ("); puth(transceiver); print("): enabling failed\n");
break;
}
}
@@ -32,7 +32,7 @@ void pedal_set_led(uint8_t color, bool enabled) {
void pedal_set_gps_mode(uint8_t mode) {
UNUSED(mode);
puts("Trying to set ESP/GPS mode on pedal. This is not supported.\n");
print("Trying to set ESP/GPS mode on pedal. This is not supported.\n");
}
void pedal_set_can_mode(uint8_t mode){
@@ -40,7 +40,7 @@ void pedal_set_can_mode(uint8_t mode){
case CAN_MODE_NORMAL:
break;
default:
puts("Tried to set unsupported CAN mode: "); puth(mode); puts("\n");
print("Tried to set unsupported CAN mode: "); puth(mode); print("\n");
break;
}
}
@@ -94,6 +94,6 @@ const board board_pedal = {
.set_fan_enabled = unused_set_fan_enabled,
.set_ir_power = unused_set_ir_power,
.set_phone_power = unused_set_phone_power,
.set_clock_source_mode = unused_set_clock_source_mode,
.set_siren = unused_set_siren
.set_siren = unused_set_siren,
.read_som_gpio = unused_read_som_gpio
};
+7 -12
View File
@@ -49,10 +49,6 @@ void red_set_led(uint8_t color, bool enabled) {
}
}
void red_set_usb_load_switch(bool enabled) {
set_gpio_output(GPIOB, 14, !enabled);
}
void red_set_can_mode(uint8_t mode) {
switch (mode) {
case CAN_MODE_NORMAL:
@@ -123,16 +119,15 @@ void red_init(void) {
set_gpio_pullup(GPIOB, 4, PULL_NONE);
set_gpio_mode(GPIOB, 4, MODE_OUTPUT);
// B14: usb load switch
set_gpio_pullup(GPIOB, 14, PULL_NONE);
set_gpio_mode(GPIOB, 14, MODE_OUTPUT);
//B1: 5VOUT_S
set_gpio_pullup(GPIOB, 1, PULL_NONE);
set_gpio_mode(GPIOB, 1, MODE_ANALOG);
// Turn on USB load switch.
red_set_usb_load_switch(true);
// B14: usb load switch, enabled by pull resistor on board, obsolete for red panda
set_gpio_output_type(GPIOB, 14, OUTPUT_TYPE_OPEN_DRAIN);
set_gpio_pullup(GPIOB, 14, PULL_UP);
set_gpio_mode(GPIOB, 14, MODE_OUTPUT);
set_gpio_output(GPIOB, 14, 1);
// Initialize harness
harness_init();
@@ -194,6 +189,6 @@ const board board_red = {
.set_fan_enabled = unused_set_fan_enabled,
.set_ir_power = unused_set_ir_power,
.set_phone_power = unused_set_phone_power,
.set_clock_source_mode = unused_set_clock_source_mode,
.set_siren = unused_set_siren
.set_siren = unused_set_siren,
.read_som_gpio = unused_read_som_gpio
};
+8 -8
View File
@@ -35,23 +35,23 @@ void red_chiplet_enable_can_transceivers(bool enabled) {
}
}
void red_chiplet_set_usb_load_switch(bool enabled) {
void red_chiplet_set_fan_or_usb_load_switch(bool enabled) {
set_gpio_output(GPIOD, 3, enabled);
}
void red_chiplet_init(void) {
common_init_gpio();
//A8, A9 : OBD_SBU1_RELAY, OBD_SBU2_RELAY
// 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_output_type(GPIOA, 9, OUTPUT_TYPE_OPEN_DRAIN);
set_gpio_pullup(GPIOA, 9, PULL_NONE);
set_gpio_mode(GPIOA, 9, MODE_OUTPUT);
set_gpio_output(GPIOA, 9, 1);
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);
// G11,B10,D7,B11: transceiver enable
set_gpio_pullup(GPIOG, 11, PULL_NONE);
@@ -75,7 +75,7 @@ void red_chiplet_init(void) {
set_gpio_mode(GPIOB, 0, MODE_ANALOG);
// Turn on USB load switch.
red_chiplet_set_usb_load_switch(true);
red_chiplet_set_fan_or_usb_load_switch(true);
// Initialize harness
harness_init();
@@ -109,7 +109,7 @@ const harness_configuration red_chiplet_harness_config = {
.pin_SBU1 = 4,
.pin_SBU2 = 1,
.pin_relay_SBU1 = 8,
.pin_relay_SBU2 = 9,
.pin_relay_SBU2 = 3,
.adc_channel_SBU1 = 4, // ADC12_INP4
.adc_channel_SBU2 = 17 // ADC1_INP17
};
-1
View File
@@ -25,6 +25,5 @@ const board board_red_v2 = {
.set_fan_enabled = unused_set_fan_enabled,
.set_ir_power = unused_set_ir_power,
.set_phone_power = unused_set_phone_power,
.set_clock_source_mode = unused_set_clock_source_mode,
.set_siren = unused_set_siren
};
+74 -6
View File
@@ -2,6 +2,47 @@
// Tres + Harness //
// /////////////////
bool tres_ir_enabled;
bool tres_fan_enabled;
void tres_update_fan_ir_power(void) {
red_chiplet_set_fan_or_usb_load_switch(tres_ir_enabled || tres_fan_enabled);
}
void tres_set_ir_power(uint8_t percentage){
tres_ir_enabled = (percentage > 0U);
tres_update_fan_ir_power();
pwm_set(TIM3, 4, percentage);
}
void tres_set_bootkick(bool enabled){
set_gpio_output(GPIOA, 0, !enabled);
}
bool tres_ignition_prev = false;
void tres_board_tick(bool ignition, bool usb_enum, bool heartbeat_seen) {
UNUSED(usb_enum);
if (ignition && !tres_ignition_prev) {
// enable bootkick on rising edge of ignition
tres_set_bootkick(true);
} else if (heartbeat_seen) {
// disable once openpilot is up
tres_set_bootkick(false);
} else {
}
tres_ignition_prev = ignition;
}
void tres_set_fan_enabled(bool enabled) {
// NOTE: fan controller reset doesn't work on a tres if IR is enabled
tres_fan_enabled = enabled;
tres_update_fan_ir_power();
}
bool tres_read_som_gpio (void){
return (get_gpio_input(GPIOC, 2) != 0);
}
void tres_init(void) {
// Enable USB 3.3V LDO for USB block
register_set_bits(&(PWR->CR3), PWR_CR3_USBREGEN);
@@ -10,17 +51,44 @@ void tres_init(void) {
red_chiplet_init();
// C2: SOM GPIO used as input (fan control at boot)
set_gpio_mode(GPIOC, 2, MODE_INPUT);
set_gpio_pullup(GPIOC, 2, PULL_DOWN);
tres_set_bootkick(true);
// SOM debugging UART
gpio_uart7_init();
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);
// fan setup
set_gpio_alternate(GPIOC, 8, GPIO_AF2_TIM3);
// Initialize IR PWM and set to 0%
set_gpio_alternate(GPIOC, 9, GPIO_AF2_TIM3);
pwm_init(TIM3, 4);
tres_set_ir_power(0U);
// Fake siren
set_gpio_alternate(GPIOC, 10, GPIO_AF4_I2C5);
set_gpio_alternate(GPIOC, 11, GPIO_AF4_I2C5);
register_set_bits(&(GPIOC->OTYPER), GPIO_OTYPER_OT10 | GPIO_OTYPER_OT11); // open drain
fake_siren_init();
// Clock source
clock_source_init();
}
const board board_tres = {
.board_type = "Tres",
.board_tick = unused_board_tick,
.board_tick = tres_board_tick,
.harness_config = &red_chiplet_harness_config,
.has_gps = false,
.has_hw_gmlan = false,
@@ -29,7 +97,7 @@ const board board_tres = {
.has_spi = true,
.has_canfd = true,
.has_rtc_battery = true,
.fan_max_rpm = 0U,
.fan_max_rpm = 6500U, // TODO: verify this, copied from dos
.init = tres_init,
.enable_can_transceiver = red_chiplet_enable_can_transceiver,
.enable_can_transceivers = red_chiplet_enable_can_transceivers,
@@ -38,9 +106,9 @@ const board board_tres = {
.set_can_mode = red_set_can_mode,
.check_ignition = red_check_ignition,
.read_current = unused_read_current,
.set_fan_enabled = unused_set_fan_enabled,
.set_ir_power = unused_set_ir_power,
.set_fan_enabled = tres_set_fan_enabled,
.set_ir_power = tres_set_ir_power,
.set_phone_power = unused_set_phone_power,
.set_clock_source_mode = unused_set_clock_source_mode,
.set_siren = unused_set_siren
.set_siren = fake_siren_set,
.read_som_gpio = tres_read_som_gpio
};
+5 -9
View File
@@ -19,7 +19,7 @@ void uno_enable_can_transceiver(uint8_t transceiver, bool enabled) {
set_gpio_output(GPIOB, 10, !enabled);
break;
default:
puts("Invalid CAN transceiver ("); puth(transceiver); puts("): enabling failed\n");
print("Invalid CAN transceiver ("); puth(transceiver); print("): enabling failed\n");
break;
}
}
@@ -93,7 +93,7 @@ void uno_set_gps_mode(uint8_t mode) {
uno_set_gps_load_switch(true);
break;
default:
puts("Invalid ESP/GPS mode\n");
print("Invalid ESP/GPS mode\n");
break;
}
}
@@ -121,7 +121,7 @@ void uno_set_can_mode(uint8_t mode){
}
break;
default:
puts("Tried to set unsupported CAN mode: "); puth(mode); puts("\n");
print("Tried to set unsupported CAN mode: "); puth(mode); print("\n");
break;
}
}
@@ -192,10 +192,6 @@ void uno_init(void) {
pwm_init(TIM4, 2);
uno_set_ir_power(0U);
// Initialize fan and set to 0%
fan_init();
uno_set_fan_enabled(false);
// Initialize harness
harness_init();
@@ -266,6 +262,6 @@ const board board_uno = {
.set_fan_enabled = uno_set_fan_enabled,
.set_ir_power = uno_set_ir_power,
.set_phone_power = uno_set_phone_power,
.set_clock_source_mode = unused_set_clock_source_mode,
.set_siren = unused_set_siren
.set_siren = unused_set_siren,
.read_som_gpio = unused_read_som_gpio
};
+4 -4
View File
@@ -14,10 +14,6 @@ void unused_set_phone_power(bool enabled) {
UNUSED(enabled);
}
void unused_set_clock_source_mode(uint8_t mode) {
UNUSED(mode);
}
void unused_set_siren(bool enabled) {
UNUSED(enabled);
}
@@ -30,4 +26,8 @@ void unused_board_tick(bool ignition, bool usb_enum, bool heartbeat_seen) {
UNUSED(ignition);
UNUSED(usb_enum);
UNUSED(heartbeat_seen);
}
bool unused_read_som_gpio(void) {
return false;
}
+6 -6
View File
@@ -14,7 +14,7 @@ void white_enable_can_transceiver(uint8_t transceiver, bool enabled) {
set_gpio_output(GPIOA, 0, !enabled);
break;
default:
puts("Invalid CAN transceiver ("); puth(transceiver); puts("): enabling failed\n");
print("Invalid CAN transceiver ("); puth(transceiver); print("): enabling failed\n");
break;
}
}
@@ -60,7 +60,7 @@ void white_set_usb_power_mode(uint8_t mode){
set_gpio_output(GPIOA, 13, 0);
break;
default:
puts("Invalid usb power mode\n");
print("Invalid usb power mode\n");
break;
}
}
@@ -77,7 +77,7 @@ void white_set_gps_mode(uint8_t mode) {
set_gpio_output(GPIOC, 5, 0);
break;
default:
puts("Invalid ESP/GPS mode\n");
print("Invalid ESP/GPS mode\n");
break;
}
}
@@ -136,7 +136,7 @@ void white_set_can_mode(uint8_t mode){
set_gpio_alternate(GPIOB, 6, GPIO_AF9_CAN2);
break;
default:
puts("Tried to set unsupported CAN mode: "); puth(mode); puts("\n");
print("Tried to set unsupported CAN mode: "); puth(mode); print("\n");
break;
}
}
@@ -258,6 +258,6 @@ const board board_white = {
.set_fan_enabled = unused_set_fan_enabled,
.set_ir_power = unused_set_ir_power,
.set_phone_power = unused_set_phone_power,
.set_clock_source_mode = unused_set_clock_source_mode,
.set_siren = unused_set_siren
.set_siren = unused_set_siren,
.read_som_gpio = unused_read_som_gpio
};
+5 -1
View File
@@ -1,5 +1,5 @@
// ******************** Prototypes ********************
void puts(const char *a){ UNUSED(a); }
void print(const char *a){ UNUSED(a); }
void puth(uint8_t i){ UNUSED(i); }
void puth2(uint8_t i){ UNUSED(i); }
void puth4(uint8_t i){ UNUSED(i); }
@@ -10,6 +10,10 @@ typedef struct harness_configuration harness_configuration;
void can_flip_buses(uint8_t bus1, uint8_t bus2){UNUSED(bus1); UNUSED(bus2);}
void pwm_init(TIM_TypeDef *TIM, uint8_t channel);
void pwm_set(TIM_TypeDef *TIM, uint8_t channel, uint8_t percentage);
// No UART support in bootloader
typedef struct uart_ring {} uart_ring;
uart_ring uart_ring_som_debug;
void uart_init(uart_ring *q, int baud) { UNUSED(q); UNUSED(baud); }
// ********************* Globals **********************
uint8_t hw_type = 0;

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