From c10a755516e07ebeddfa81b312084c23fd2b2c78 Mon Sep 17 00:00:00 2001 From: Vehicle Researcher Date: Sat, 17 Nov 2018 01:58:34 -0800 Subject: [PATCH 1/5] Squashed 'panda/' changes from 4dd3f5a..293fa33 293fa33 Honda: fixed message forwarding addresses from can2 to can0 799c338 Chrysler safety controls (#130) c05b15b Toyota frc on (#141) 8291971 Toyota: using a more generalized CRUISE_ACTIVE bit that works on all cars 6f157aa Toyota frc on (#140) 8d2470c bumped panda version 915ee4f Honda: forwarding CAN0 to camera, so camera can stay on (#139) git-subtree-dir: panda git-subtree-split: 293fa33f830f0c7cdfad31f621c4bdc016aa7d41 --- VERSION | 2 +- board/safety.h | 3 + board/safety/safety_chrysler.h | 136 ++++++++++++++++++++++++++++++ board/safety/safety_honda.h | 34 ++++++-- board/safety/safety_toyota.h | 20 +++-- python/__init__.py | 7 ++ tests/safety/libpandasafety_py.py | 6 ++ tests/safety/test.c | 8 ++ tests/safety/test_chrysler.py | 88 +++++++++++++++++++ tests/safety/test_toyota.py | 8 +- 10 files changed, 289 insertions(+), 23 deletions(-) create mode 100644 board/safety/safety_chrysler.h create mode 100755 tests/safety/test_chrysler.py diff --git a/VERSION b/VERSION index 46882bcf3..301779b03 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v1.1.6 \ No newline at end of file +v1.1.7 \ No newline at end of file diff --git a/board/safety.h b/board/safety.h index 51a2bb896..4d2b46899 100644 --- a/board/safety.h +++ b/board/safety.h @@ -62,6 +62,7 @@ int controls_allowed = 0; #include "safety/safety_ford.h" #include "safety/safety_cadillac.h" #include "safety/safety_hyundai.h" +#include "safety/safety_chrysler.h" #include "safety/safety_elm327.h" const safety_hooks *current_hooks = &nooutput_hooks; @@ -102,6 +103,7 @@ typedef struct { #define SAFETY_CADILLAC 6 #define SAFETY_HYUNDAI 7 #define SAFETY_TESLA 8 +#define SAFETY_CHRYSLER 9 #define SAFETY_TOYOTA_IPAS 0x1335 #define SAFETY_TOYOTA_NOLIMITS 0x1336 #define SAFETY_ALLOUTPUT 0x1337 @@ -116,6 +118,7 @@ const safety_hook_config safety_hook_registry[] = { {SAFETY_FORD, &ford_hooks}, {SAFETY_CADILLAC, &cadillac_hooks}, {SAFETY_HYUNDAI, &hyundai_hooks}, + {SAFETY_CHRYSLER, &chrysler_hooks}, {SAFETY_TOYOTA_NOLIMITS, &toyota_nolimits_hooks}, #ifdef PANDA {SAFETY_TOYOTA_IPAS, &toyota_ipas_hooks}, diff --git a/board/safety/safety_chrysler.h b/board/safety/safety_chrysler.h new file mode 100644 index 000000000..eadc8eaa7 --- /dev/null +++ b/board/safety/safety_chrysler.h @@ -0,0 +1,136 @@ +// board enforces +// in-state +// ACC is active (green) +// out-state +// brake pressed +// stock LKAS ECU is online +// ACC is not active (white or disabled) + +// chrysler_: namespacing +int chrysler_speed = 0; + +// silence everything if stock ECUs are still online +int chrysler_lkas_detected = 0; +int chrysler_desired_torque_last = 0; + +static void chrysler_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { + int bus_number = (to_push->RDTR >> 4) & 0xFF; + uint32_t addr; + if (to_push->RIR & 4) { + // Extended + // Not looked at, but have to be separated + // to avoid address collision + addr = to_push->RIR >> 3; + } else { + // Normal + addr = to_push->RIR >> 21; + } + + if (addr == 0x144 && bus_number == 0) { + chrysler_speed = ((to_push->RDLR & 0xFF000000) >> 16) | (to_push->RDHR & 0xFF); + } + + // check if stock LKAS ECU is still online + if (addr == 0x292 && bus_number == 0) { + chrysler_lkas_detected = 1; + controls_allowed = 0; + } + + // ["ACC_2"]['ACC_STATUS_2'] == 7 for active (green) Adaptive Cruise Control + if (addr == 0x1f4 && bus_number == 0) { + if (((to_push->RDLR & 0x380000) >> 19) == 7) { + controls_allowed = 1; + } else { + controls_allowed = 0; + } + } + + // exit controls on brake press by human + if (addr == 0x140) { + if (to_push->RDLR & 0x4) { + controls_allowed = 0; + } + } +} + +// if controls_allowed +// allow steering up to limit +// else +// block all commands that produce actuation +static int chrysler_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { + // There can be only one! (LKAS) + if (chrysler_lkas_detected) { + return 0; + } + + uint32_t addr; + if (to_send->RIR & 4) { + // Extended + addr = to_send->RIR >> 3; + } else { + // Normal + addr = to_send->RIR >> 21; + } + + // LKA STEER: Too large of values cause the steering actuator ECU to silently + // fault and no longer actuate the wheel until the car is rebooted. + if (addr == 0x292) { + int rdlr = to_send->RDLR; + int straight = 1024; + int steer = ((rdlr & 0x7) << 8) + ((rdlr & 0xFF00) >> 8) - straight; + int max_steer = 230; + int max_rate = 50; // ECU is fine with 100, but 3 is typical. + if (steer > max_steer) { + return false; + } + if (steer < -max_steer) { + return false; + } + if (!controls_allowed && steer != 0) { + // If controls not allowed, only allow steering to move closer to 0. + if (chrysler_desired_torque_last == 0) { + return false; + } + if ((chrysler_desired_torque_last > 0) && (steer >= chrysler_desired_torque_last)) { + return false; + } + if ((chrysler_desired_torque_last < 0) && (steer <= chrysler_desired_torque_last)) { + return false; + } + } + if (steer < (chrysler_desired_torque_last - max_rate)) { + return false; + } + if (steer > (chrysler_desired_torque_last + max_rate)) { + return false; + } + + chrysler_desired_torque_last = steer; + } + + // 1 allows the message through + return true; +} + +static int chrysler_tx_lin_hook(int lin_num, uint8_t *data, int len) { + // LIN is not used. + return false; +} + +static void chrysler_init(int16_t param) { + controls_allowed = 0; +} + +static int chrysler_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { + return -1; +} + +const safety_hooks chrysler_hooks = { + .init = chrysler_init, + .rx = chrysler_rx_hook, + .tx = chrysler_tx_hook, + .tx_lin = chrysler_tx_lin_hook, + .ignition = default_ign_hook, + .fwd = chrysler_fwd_hook, +}; + diff --git a/board/safety/safety_honda.h b/board/safety/safety_honda.h index 82e6eadda..fbee6cfe8 100644 --- a/board/safety/safety_honda.h +++ b/board/safety/safety_honda.h @@ -138,15 +138,6 @@ static void honda_init(int16_t param) { honda_alt_brake_msg = false; } -const safety_hooks honda_hooks = { - .init = honda_init, - .rx = honda_rx_hook, - .tx = honda_tx_hook, - .tx_lin = nooutput_tx_lin_hook, - .ignition = default_ign_hook, - .fwd = nooutput_fwd_hook, -}; - static void honda_bosch_init(int16_t param) { controls_allowed = 0; bosch_hardware = true; @@ -154,6 +145,22 @@ static void honda_bosch_init(int16_t param) { honda_alt_brake_msg = param == 1 ? true : false; } +static int honda_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { + // fwd from car to camera. also fwd certain msgs from camera to car + // 0xE4 is steering on all cars except CRV and RDX, 0x194 for CRV and RDX, + // 0x1FA is brake control, 0x30C is acc hud, 0x33D is lkas hud, + // 0x39f is radar hud + int addr = to_fwd->RIR>>21; + if (bus_num == 0) { + return 2; + } else if (bus_num == 2 && addr != 0xE4 && addr != 0x194 && addr != 0x1FA && + addr != 0x30C && addr != 0x33D && addr != 0x39F) { + return 0; + } + + return -1; +} + static int honda_bosch_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { if (bus_num == 1 || bus_num == 2) { int addr = to_fwd->RIR>>21; @@ -162,6 +169,15 @@ static int honda_bosch_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { return -1; } +const safety_hooks honda_hooks = { + .init = honda_init, + .rx = honda_rx_hook, + .tx = honda_tx_hook, + .tx_lin = nooutput_tx_lin_hook, + .ignition = default_ign_hook, + .fwd = honda_fwd_hook, +}; + const safety_hooks honda_bosch_hooks = { .init = honda_bosch_init, .rx = honda_rx_hook, diff --git a/board/safety/safety_toyota.h b/board/safety/safety_toyota.h index 6ddf2952d..9cab1512f 100644 --- a/board/safety/safety_toyota.h +++ b/board/safety/safety_toyota.h @@ -1,5 +1,5 @@ -int toyota_no_dsu_car = 0; // ch-r and camry don't have the DSU int toyota_giraffe_switch_1 = 0; // is giraffe switch 1 high? +int toyota_camera_forwarded = 0; // should we forward the camera bus? // global torque limit const int TOYOTA_MAX_TORQUE = 1500; // max torque cmd allowed ever @@ -49,8 +49,8 @@ static void toyota_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { // enter controls on rising edge of ACC, exit controls on ACC off if ((to_push->RIR>>21) == 0x1D2) { - // 4 bits: 55-52 - int cruise_engaged = to_push->RDHR & 0xF00000; + // 5th bit is CRUISE_ACTIVE + int cruise_engaged = to_push->RDLR & 0x20; if (cruise_engaged && !toyota_cruise_engaged_last) { controls_allowed = 1; } else if (!cruise_engaged) { @@ -60,16 +60,15 @@ static void toyota_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { } int bus = (to_push->RDTR >> 4) & 0xF; - // 0x680 is a radar msg only found in dsu-less cars - if ((to_push->RIR>>21) == 0x680 && (bus == 1)) { - toyota_no_dsu_car = 1; + // msgs are only on bus 2 if panda is connected to frc + if (bus == 2) { + toyota_camera_forwarded = 1; } // 0x2E4 is lkas cmd. If it is on bus 0, then giraffe switch 1 is high if ((to_push->RIR>>21) == 0x2E4 && (bus == 0)) { toyota_giraffe_switch_1 = 1; } - } static int toyota_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { @@ -150,13 +149,15 @@ static void toyota_init(int16_t param) { controls_allowed = 0; toyota_actuation_limits = 1; toyota_giraffe_switch_1 = 0; + toyota_camera_forwarded = 0; toyota_dbc_eps_torque_factor = param; } static int toyota_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { - // forward cam to radar and viceversa if car is dsu-less, except lkas cmd and hud - if ((bus_num == 0 || bus_num == 2) && toyota_no_dsu_car && !toyota_giraffe_switch_1) { + // forward cam to radar and viceversa if car, except lkas cmd and hud + // don't forward when switch 1 is high + if ((bus_num == 0 || bus_num == 2) && toyota_camera_forwarded && !toyota_giraffe_switch_1) { int addr = to_fwd->RIR>>21; bool is_lkas_msg = (addr == 0x2E4 || addr == 0x412) && bus_num == 2; return is_lkas_msg? -1 : (uint8_t)(~bus_num & 0x2); @@ -177,6 +178,7 @@ static void toyota_nolimits_init(int16_t param) { controls_allowed = 0; toyota_actuation_limits = 0; toyota_giraffe_switch_1 = 0; + toyota_camera_forwarded = 0; toyota_dbc_eps_torque_factor = param; } diff --git a/python/__init__.py b/python/__init__.py index 86b76285e..c49ee8362 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -105,7 +105,14 @@ class Panda(object): SAFETY_NOOUTPUT = 0 SAFETY_HONDA = 1 SAFETY_TOYOTA = 2 + SAFETY_GM = 3 SAFETY_HONDA_BOSCH = 4 + SAFETY_FORD = 5 + SAFETY_CADILLAC = 6 + SAFETY_HYUNDAI = 7 + SAFETY_TESLA = 8 + SAFETY_CHRYSLER = 9 + SAFETY_TOYOTA_IPAS = 0x1335 SAFETY_TOYOTA_NOLIMITS = 0x1336 SAFETY_ALLOUTPUT = 0x1337 SAFETY_ELM327 = 0xE327 diff --git a/tests/safety/libpandasafety_py.py b/tests/safety/libpandasafety_py.py index dfd396045..c6df9d334 100644 --- a/tests/safety/libpandasafety_py.py +++ b/tests/safety/libpandasafety_py.py @@ -81,6 +81,12 @@ void set_hyundai_rt_torque_last(int t); void toyota_ipas_rx_hook(CAN_FIFOMailBox_TypeDef *to_push); int toyota_ipas_tx_hook(CAN_FIFOMailBox_TypeDef *to_send); +void init_tests_chrysler(void); +void chrysler_rx_hook(CAN_FIFOMailBox_TypeDef *to_push); +int chrysler_tx_hook(CAN_FIFOMailBox_TypeDef *to_send); +void chrysler_init(int16_t param); +void set_chrysler_desired_torque_last(int t); + """) libpandasafety = ffi.dlopen(libpandasafety_fn) diff --git a/tests/safety/test.c b/tests/safety/test.c index c1555db5d..af0db3c92 100644 --- a/tests/safety/test.c +++ b/tests/safety/test.c @@ -121,6 +121,10 @@ void set_hyundai_desired_torque_last(int t){ hyundai_desired_torque_last = t; } +void set_chrysler_desired_torque_last(int t){ + chrysler_desired_torque_last = t; +} + int get_ego_speed(void){ return ego_speed; } @@ -184,6 +188,10 @@ void init_tests_honda(void){ gas_prev = 0; } +void init_tests_chrysler(void){ + chrysler_desired_torque_last = 0; + set_timer(0); +} void set_gmlan_digital_output(int to_set){ } diff --git a/tests/safety/test_chrysler.py b/tests/safety/test_chrysler.py new file mode 100755 index 000000000..9b8b17720 --- /dev/null +++ b/tests/safety/test_chrysler.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python2 +import unittest +import numpy as np +import libpandasafety_py + + +class TestChryslerSafety(unittest.TestCase): + @classmethod + def setUp(cls): + cls.safety = libpandasafety_py.libpandasafety + cls.safety.chrysler_init(0) + cls.safety.init_tests_chrysler() + + def _acc_msg(self, active): + to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') + to_send[0].RIR = 0x1f4 << 21 + to_send[0].RDLR = 0xfe3fff1f if active else 0xfe0fff1f + return to_send + + + def _brake_msg(self, brake): + to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') + to_send[0].RIR = 0x140 << 21 + to_send[0].RDLR = 0x485 if brake else 0x480 + return to_send + + def _steer_msg(self, angle): + to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') + to_send[0].RIR = 0x292 << 21 + c_angle = (1024 + angle) + to_send[0].RDLR = 0x10 | ((c_angle & 0xf00) >> 8) | ((c_angle & 0xff) << 8) + return to_send + + def test_default_controls_not_allowed(self): + self.assertFalse(self.safety.get_controls_allowed()) + + def test_acc_enables_controls(self): + self.safety.set_controls_allowed(0) + self.safety.chrysler_rx_hook(self._acc_msg(0)) + self.assertFalse(self.safety.get_controls_allowed()) + self.safety.chrysler_rx_hook(self._acc_msg(1)) + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.chrysler_rx_hook(self._acc_msg(0)) + self.assertFalse(self.safety.get_controls_allowed()) + + def test_disengage_on_brake(self): + self.safety.set_controls_allowed(1) + self.safety.chrysler_rx_hook(self._brake_msg(0)) + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.chrysler_rx_hook(self._brake_msg(1)) + self.assertFalse(self.safety.get_controls_allowed()) + + def test_steer_calculation(self): + self.assertEqual(0x14, self._steer_msg(0)[0].RDLR) # straight, no steering + + def test_steer_tx(self): + self.safety.set_controls_allowed(1) + self.assertTrue(self.safety.chrysler_tx_hook(self._steer_msg(0))) + self.safety.set_chrysler_desired_torque_last(227) + self.assertTrue(self.safety.chrysler_tx_hook(self._steer_msg(230))) + self.assertFalse(self.safety.chrysler_tx_hook(self._steer_msg(231))) + self.safety.set_chrysler_desired_torque_last(-227) + self.assertFalse(self.safety.chrysler_tx_hook(self._steer_msg(-231))) + self.assertTrue(self.safety.chrysler_tx_hook(self._steer_msg(-230))) + # verify max change + self.safety.set_chrysler_desired_torque_last(0) + self.assertFalse(self.safety.chrysler_tx_hook(self._steer_msg(230))) + + self.safety.set_controls_allowed(0) + self.safety.set_chrysler_desired_torque_last(0) + self.assertFalse(self.safety.chrysler_tx_hook(self._steer_msg(3))) + self.assertTrue(self.safety.chrysler_tx_hook(self._steer_msg(0))) + # verify when controls not allowed we can still go back towards 0 + self.safety.set_chrysler_desired_torque_last(10) + self.assertFalse(self.safety.chrysler_tx_hook(self._steer_msg(10))) + self.assertFalse(self.safety.chrysler_tx_hook(self._steer_msg(11))) + self.assertTrue(self.safety.chrysler_tx_hook(self._steer_msg(7))) + self.assertTrue(self.safety.chrysler_tx_hook(self._steer_msg(4))) + self.assertTrue(self.safety.chrysler_tx_hook(self._steer_msg(0))) + self.safety.set_chrysler_desired_torque_last(-10) + self.assertFalse(self.safety.chrysler_tx_hook(self._steer_msg(-10))) + self.assertFalse(self.safety.chrysler_tx_hook(self._steer_msg(-11))) + self.assertTrue(self.safety.chrysler_tx_hook(self._steer_msg(-7))) + self.assertTrue(self.safety.chrysler_tx_hook(self._steer_msg(-4))) + self.assertTrue(self.safety.chrysler_tx_hook(self._steer_msg(0))) + +if __name__ == "__main__": + unittest.main() diff --git a/tests/safety/test_toyota.py b/tests/safety/test_toyota.py index b4d23af65..40bc4bcf5 100644 --- a/tests/safety/test_toyota.py +++ b/tests/safety/test_toyota.py @@ -129,7 +129,7 @@ class TestToyotaSafety(unittest.TestCase): def test_enable_control_allowed_from_cruise(self): to_push = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') to_push[0].RIR = 0x1D2 << 21 - to_push[0].RDHR = 0xF00000 + to_push[0].RDLR = 0x20 self.safety.toyota_rx_hook(to_push) self.assertTrue(self.safety.get_controls_allowed()) @@ -137,7 +137,7 @@ class TestToyotaSafety(unittest.TestCase): def test_disable_control_allowed_from_cruise(self): to_push = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') to_push[0].RIR = 0x1D2 << 21 - to_push[0].RDHR = 0 + to_push[0].RDLR = 0 self.safety.set_controls_allowed(1) self.safety.toyota_rx_hook(to_push) @@ -373,7 +373,7 @@ class TestToyotaSafety(unittest.TestCase): self.assertTrue(self.safety.get_controls_allowed()) # now inject too high rates - self.assertEqual(False, self.safety.toyota_ipas_tx_hook(self._ipas_control_msg(a + sign(a) * + self.assertEqual(False, self.safety.toyota_ipas_tx_hook(self._ipas_control_msg(a + sign(a) * (max_delta_up + 1), 1))) self.assertFalse(self.safety.get_controls_allowed()) self.safety.set_controls_allowed(1) @@ -381,7 +381,7 @@ class TestToyotaSafety(unittest.TestCase): self.assertTrue(self.safety.get_controls_allowed()) self.assertEqual(True, self.safety.toyota_ipas_tx_hook(self._ipas_control_msg(a, 1))) self.assertTrue(self.safety.get_controls_allowed()) - self.assertEqual(False, self.safety.toyota_ipas_tx_hook(self._ipas_control_msg(a - sign(a) * + self.assertEqual(False, self.safety.toyota_ipas_tx_hook(self._ipas_control_msg(a - sign(a) * (max_delta_down + 1), 1))) self.assertFalse(self.safety.get_controls_allowed()) From 2f0b0fb15e042720c65471945d934f96cc0b122d Mon Sep 17 00:00:00 2001 From: Vehicle Researcher Date: Sat, 17 Nov 2018 01:58:36 -0800 Subject: [PATCH 2/5] Squashed 'opendbc/' changes from 62b7a01..3f6cd74 3f6cd74 Add 3rd RSA signal and cleanup (#120) a308ec1 add vals honda (#121) 1317514 Toyota: fixed typos 0339fc8 Toyota: added a better cruise active indicator b0c012d Lexus: add is 94ba43c Toyota: generated dnc files after latest change e16723e Add Distance Lines and RSA (#118) 9aec1ef Add GM signals for ESP/Mode/Highbeams/Intellibeam (#114) a67fff9 add toyota_prius_2010_pt.dbc (#50) c1ee10f Revert "Revert "GM: copy radar header from cadillac (#116)"" git-subtree-dir: opendbc git-subtree-split: 3f6cd74b6ea8e77da957501cfa3acf8ff0812509 --- acura_ilx_2016_can_generated.dbc | 2 +- acura_rdx_2018_can_generated.dbc | 1 + generator/honda/_bosch_2018.dbc | 2 + generator/honda/acura_ilx_2016_can.dbc | 2 +- generator/honda/acura_rdx_2018_can.dbc | 1 + .../honda/honda_civic_touring_2016_can.dbc | 2 +- .../honda/honda_crv_touring_2016_can.dbc | 2 +- generator/honda/honda_fit_ex_2018_can.dbc | 2 +- generator/honda/honda_odyssey_exl_2018.dbc | 4 +- .../honda/honda_pilot_touring_2017_can.dbc | 2 +- ...honda_ridgeline_black_edition_2017_can.dbc | 2 +- generator/toyota/_toyota_2017.dbc | 113 +++++-- generator/toyota/lexus_is_2018_pt.dbc | 39 +++ gm_global_a_object.dbc | 33 +- gm_global_a_powertrain.dbc | 15 + honda_accord_lx15t_2018_can_generated.dbc | 1 + honda_accord_s2t_2018_can_generated.dbc | 1 + ..._civic_hatchback_ex_2017_can_generated.dbc | 1 + honda_civic_touring_2016_can_generated.dbc | 2 +- honda_crv_ex_2017_can_generated.dbc | 1 + honda_crv_touring_2016_can_generated.dbc | 2 +- honda_fit_ex_2018_can_generated.dbc | 2 +- honda_odyssey_exl_2018_generated.dbc | 4 +- honda_pilot_touring_2017_can_generated.dbc | 2 +- ...eline_black_edition_2017_can_generated.dbc | 2 +- lexus_is_2018_pt_generated.dbc | 298 ++++++++++++++++++ lexus_rx_hybrid_2017_pt_generated.dbc | 113 +++++-- toyota_avalon_2017_pt_generated.dbc | 113 +++++-- toyota_camry_hybrid_2018_pt_generated.dbc | 113 +++++-- toyota_chr_2018_pt_generated.dbc | 113 +++++-- toyota_chr_hybrid_2018_pt_generated.dbc | 113 +++++-- toyota_corolla_2017_pt_generated.dbc | 113 +++++-- toyota_highlander_2017_pt_generated.dbc | 113 +++++-- ...ta_highlander_hybrid_2018_pt_generated.dbc | 113 +++++-- toyota_prius_2010_pt.dbc | 203 ++++++++++++ toyota_prius_2017_pt_generated.dbc | 113 +++++-- toyota_rav4_2017_pt_generated.dbc | 113 +++++-- toyota_rav4_hybrid_2017_pt_generated.dbc | 113 +++++-- 38 files changed, 1676 insertions(+), 308 deletions(-) create mode 100644 generator/toyota/lexus_is_2018_pt.dbc create mode 100644 lexus_is_2018_pt_generated.dbc create mode 100644 toyota_prius_2010_pt.dbc diff --git a/acura_ilx_2016_can_generated.dbc b/acura_ilx_2016_can_generated.dbc index b7214ff60..b0c16c814 100644 --- a/acura_ilx_2016_can_generated.dbc +++ b/acura_ilx_2016_can_generated.dbc @@ -293,7 +293,7 @@ CM_ SG_ 780 CRUISE_SPEED "255 = no speed"; CM_ SG_ 804 CRUISE_SPEED_PCM "255 = no speed"; CM_ SG_ 829 BEEP "beeps are pleasant, chimes are for warnngs etc..."; -VAL_ 399 STEER_STATUS 5 "fault" 4 "no_torque_alert_2" 2 "no_torque_alert_1" 0 "normal" ; +VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; VAL_ 419 GEAR_SHIFTER 10 "S" 4 "D" 3 "N" 2 "R" 1 "P" ; VAL_ 422 CRUISE_BUTTONS 7 "tbd" 6 "tbd" 5 "tbd" 4 "accel_res" 3 "decel_set" 2 "cancel" 1 "main" 0 "none" ; VAL_ 422 LIGHTS_SETTING 3 "high_beam" 2 "low_beam" 1 "position" 0 "no_lights" ; diff --git a/acura_rdx_2018_can_generated.dbc b/acura_rdx_2018_can_generated.dbc index bbfa1aeac..d60b90d75 100644 --- a/acura_rdx_2018_can_generated.dbc +++ b/acura_rdx_2018_can_generated.dbc @@ -288,6 +288,7 @@ BO_ 660 SCM_FEEDBACK: 8 SCM CM_ SG_ 422 PARKING_BRAKE_LIGHT "Believe this is just the dash light for the parking break"; VAL_ 392 GEAR_SHIFTER 0 "S" 1 "P" 2 "R" 4 "N" 8 "D" ; VAL_ 392 GEAR 26 "S" 4 "D" 3 "N" 2 "R" 1 "P" ; +VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; VAL_ 422 CRUISE_BUTTONS 7 "tbd" 6 "tbd" 5 "tbd" 4 "accel_res" 3 "decel_set" 2 "cancel" 1 "main" 0 "none" ; CM_ "CHFFR_METRIC 342 STEER_ANGLE STEER_ANGLE 0.36 180; CHFFR_METRIC 380 ENGINE_RPM ENGINE_RPM 1 0; CHFFR_METRIC 804 ENGINE_TEMPERATURE ENGINE_TEMPERATURE 1 0"; diff --git a/generator/honda/_bosch_2018.dbc b/generator/honda/_bosch_2018.dbc index 5d07e3bab..0b8d8a17f 100644 --- a/generator/honda/_bosch_2018.dbc +++ b/generator/honda/_bosch_2018.dbc @@ -259,3 +259,5 @@ BO_ 891 STALK_STATUS_2: 8 XXX SG_ PARK_LIGHTS : 36|1@0+ (1,0) [0|1] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + +VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; \ No newline at end of file diff --git a/generator/honda/acura_ilx_2016_can.dbc b/generator/honda/acura_ilx_2016_can.dbc index 5acfc3169..50677c4b0 100644 --- a/generator/honda/acura_ilx_2016_can.dbc +++ b/generator/honda/acura_ilx_2016_can.dbc @@ -64,7 +64,7 @@ CM_ SG_ 780 CRUISE_SPEED "255 = no speed"; CM_ SG_ 804 CRUISE_SPEED_PCM "255 = no speed"; CM_ SG_ 829 BEEP "beeps are pleasant, chimes are for warnngs etc..."; -VAL_ 399 STEER_STATUS 5 "fault" 4 "no_torque_alert_2" 2 "no_torque_alert_1" 0 "normal" ; +VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; VAL_ 419 GEAR_SHIFTER 10 "S" 4 "D" 3 "N" 2 "R" 1 "P" ; VAL_ 422 CRUISE_BUTTONS 7 "tbd" 6 "tbd" 5 "tbd" 4 "accel_res" 3 "decel_set" 2 "cancel" 1 "main" 0 "none" ; VAL_ 422 LIGHTS_SETTING 3 "high_beam" 2 "low_beam" 1 "position" 0 "no_lights" ; diff --git a/generator/honda/acura_rdx_2018_can.dbc b/generator/honda/acura_rdx_2018_can.dbc index f2d764c5c..30d09c7db 100644 --- a/generator/honda/acura_rdx_2018_can.dbc +++ b/generator/honda/acura_rdx_2018_can.dbc @@ -59,6 +59,7 @@ BO_ 660 SCM_FEEDBACK: 8 SCM CM_ SG_ 422 PARKING_BRAKE_LIGHT "Believe this is just the dash light for the parking break"; VAL_ 392 GEAR_SHIFTER 0 "S" 1 "P" 2 "R" 4 "N" 8 "D" ; VAL_ 392 GEAR 26 "S" 4 "D" 3 "N" 2 "R" 1 "P" ; +VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; VAL_ 422 CRUISE_BUTTONS 7 "tbd" 6 "tbd" 5 "tbd" 4 "accel_res" 3 "decel_set" 2 "cancel" 1 "main" 0 "none" ; CM_ "CHFFR_METRIC 342 STEER_ANGLE STEER_ANGLE 0.36 180; CHFFR_METRIC 380 ENGINE_RPM ENGINE_RPM 1 0; CHFFR_METRIC 804 ENGINE_TEMPERATURE ENGINE_TEMPERATURE 1 0"; diff --git a/generator/honda/honda_civic_touring_2016_can.dbc b/generator/honda/honda_civic_touring_2016_can.dbc index 9974d7068..21327ec39 100644 --- a/generator/honda/honda_civic_touring_2016_can.dbc +++ b/generator/honda/honda_civic_touring_2016_can.dbc @@ -129,7 +129,7 @@ CM_ SG_ 420 BRAKE_HOLD_RELATED "On when Brake Hold engaged"; CM_ SG_ 450 EPB_STATE "3 \"engaged\" 2 \"disengaging\" 1 \"engaging\" 0 \"disengaged\""; CM_ SG_ 806 REVERSE_LIGHT "Might be reverse gear selected and not the lights"; -VAL_ 399 STEER_STATUS 5 "fault" 4 "no_torque_alert_2" 2 "no_torque_alert_1" 0 "normal" ; +VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; VAL_ 401 GEAR_SHIFTER 32 "L" 16 "S" 8 "D" 4 "N" 2 "R" 1 "P" ; VAL_ 401 GEAR 7 "L" 10 "S" 4 "D" 3 "N" 2 "R" 1 "P" ; VAL_ 450 EPB_STATE 3 "engaged" 2 "disengaging" 1 "engaging" 0 "disengaged" ; diff --git a/generator/honda/honda_crv_touring_2016_can.dbc b/generator/honda/honda_crv_touring_2016_can.dbc index 54350c01b..f75586a4c 100644 --- a/generator/honda/honda_crv_touring_2016_can.dbc +++ b/generator/honda/honda_crv_touring_2016_can.dbc @@ -64,7 +64,7 @@ BO_ 891 WIPERS: 8 XXX CM_ SG_ 401 GEAR "10 = reverse, 11 = transition"; -VAL_ 399 STEER_STATUS 5 "fault" 4 "no_torque_alert_2" 2 "no_torque_alert_1" 0 "normal" ; +VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; VAL_ 401 GEAR_SHIFTER 32 "L" 16 "S" 8 "D" 4 "N" 2 "R" 1 "P" ; VAL_ 401 GEAR 7 "L" 10 "S" 4 "D" 3 "N" 2 "R" 1 "P" ; VAL_ 422 CRUISE_BUTTONS 7 "tbd" 6 "tbd" 5 "tbd" 4 "accel_res" 3 "decel_set" 2 "cancel" 1 "main" 0 "none" ; diff --git a/generator/honda/honda_fit_ex_2018_can.dbc b/generator/honda/honda_fit_ex_2018_can.dbc index 32b5718e6..bc911ffcb 100644 --- a/generator/honda/honda_fit_ex_2018_can.dbc +++ b/generator/honda/honda_fit_ex_2018_can.dbc @@ -87,7 +87,7 @@ BO_ 884 STALK_STATUS: 8 XXX CM_ SG_ 401 GEAR "10 = reverse, 11 = transition"; CM_ SG_ 420 BRAKE_HOLD_RELATED "On when Brake Hold engaged"; -VAL_ 399 STEER_STATUS 5 "fault" 4 "no_torque_alert_2" 2 "no_torque_alert_1" 0 "normal" ; +VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; VAL_ 401 GEAR_SHIFTER 32 "L" 16 "S" 8 "D" 4 "N" 2 "R" 1 "P" ; VAL_ 401 GEAR 7 "L" 10 "S" 4 "D" 3 "N" 2 "R" 1 "P" ; VAL_ 422 CRUISE_BUTTONS 7 "tbd" 6 "tbd" 5 "tbd" 4 "accel_res" 3 "decel_set" 2 "cancel" 1 "main" 0 "none" ; diff --git a/generator/honda/honda_odyssey_exl_2018.dbc b/generator/honda/honda_odyssey_exl_2018.dbc index 40638ac80..6c181d877 100644 --- a/generator/honda/honda_odyssey_exl_2018.dbc +++ b/generator/honda/honda_odyssey_exl_2018.dbc @@ -100,7 +100,7 @@ CM_ SG_ 804 CRUISE_SPEED_PCM "255 = no speed"; CM_ SG_ 806 REVERSE_LIGHT "Might be reverse gear selected and not the lights"; CM_ SG_ 829 BEEP "beeps are pleasant, chimes are for warnings etc..."; -VAL_ 399 STEER_STATUS 5 "fault" 4 "no_torque_alert_2" 2 "no_torque_alert_1" 0 "normal" ; +VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; VAL_ 419 GEAR_SHIFTER 10 "S" 4 "D" 3 "N" 2 "R" 1 "P" ; VAL_ 450 EPB_STATE 3 "engaged" 2 "disengaging" 1 "engaging" 0 "disengaged" ; VAL_ 662 CRUISE_BUTTONS 7 "tbd" 6 "tbd" 5 "tbd" 4 "accel_res" 3 "decel_set" 2 "cancel" 1 "main" 0 "none" ; @@ -110,7 +110,5 @@ VAL_ 829 BEEP 3 "single_beep" 2 "triple_beep" 1 "repeated_beep" 0 "no_beep" ; VAL_ 891 WIPERS 4 "High" 2 "Low" 0 "Off" ; VAL_ 927 ACC_ALERTS 29 "esp_active_acc_canceled" 10 "b_pedal_applied" 9 "speed_too_low" 8 "speed_too_high" 7 "p_brake_applied" 6 "gear_no_d" 5 "seatbelt" 4 "too_steep_downhill" 3 "too_steep_uphill" 2 "too_close" 1 "no_vehicle_ahead" ; VAL_ 806 CMBS_BUTTON 3 "pressed" 0 "released" ; -VAL_ 891 WIPERS 4 "High" 2 "Low" 0 "Off" ; -VAL_ 927 ACC_ALERTS 29 "esp_active_acc_canceled" 10 "b_pedal_applied" 9 "speed_too_low" 8 "speed_too_high" 7 "p_brake_applied" 6 "gear_no_d" 5 "seatbelt" 4 "too_steep_downhill" 3 "too_steep_uphill" 2 "too_close" 1 "no_vehicle_ahead" ; CM_ "CHFFR_METRIC 342 STEER_ANGLE STEER_ANGLE 0.36 180; CHFFR_METRIC 380 ENGINE_RPM ENGINE_RPM 1 0; CHFFR_METRIC 804 ENGINE_TEMPERATURE ENGINE_TEMPERATURE 1 0"; diff --git a/generator/honda/honda_pilot_touring_2017_can.dbc b/generator/honda/honda_pilot_touring_2017_can.dbc index c480fad10..a499b6bc9 100644 --- a/generator/honda/honda_pilot_touring_2017_can.dbc +++ b/generator/honda/honda_pilot_touring_2017_can.dbc @@ -58,7 +58,7 @@ BO_ 660 SCM_FEEDBACK: 8 SCM SG_ LEFT_BLINKER : 5|1@0+ (1,0) [0|1] "" EON SG_ WIPERS_SPEED : 4|2@0+ (1,0) [0|3] "" EON -VAL_ 399 STEER_STATUS 5 "fault" 4 "no_torque_alert_2" 2 "no_torque_alert_1" 0 "normal" ; +VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; VAL_ 419 GEAR_SHIFTER 32 "D" 8 "R" 4 "P" ; VAL_ 422 CRUISE_BUTTONS 7 "tbd" 6 "tbd" 5 "tbd" 4 "accel_res" 3 "decel_set" 2 "cancel" 1 "main" 0 "none" ; VAL_ 422 LIGHTS_SETTING 3 "high_beam" 2 "low_beam" 1 "position" 0 "no_lights" ; diff --git a/generator/honda/honda_ridgeline_black_edition_2017_can.dbc b/generator/honda/honda_ridgeline_black_edition_2017_can.dbc index bd4d0f136..7eee6a6c0 100644 --- a/generator/honda/honda_ridgeline_black_edition_2017_can.dbc +++ b/generator/honda/honda_ridgeline_black_edition_2017_can.dbc @@ -53,7 +53,7 @@ BO_ 660 SCM_FEEDBACK: 8 SCM SG_ LEFT_BLINKER : 5|1@0+ (1,0) [0|1] "" EON SG_ WIPERS_SPEED : 4|2@0+ (1,0) [0|3] "" EON -VAL_ 399 STEER_STATUS 5 "fault" 4 "no_torque_alert_2" 2 "no_torque_alert_1" 0 "normal" ; +VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; VAL_ 419 GEAR_SHIFTER 32 "D" 8 "R" 4 "P" ; VAL_ 422 CRUISE_BUTTONS 7 "tbd" 6 "tbd" 5 "tbd" 4 "accel_res" 3 "decel_set" 2 "cancel" 1 "main" 0 "none" ; VAL_ 422 LIGHTS_SETTING 3 "high_beam" 2 "low_beam" 1 "position" 0 "no_lights" ; diff --git a/generator/toyota/_toyota_2017.dbc b/generator/toyota/_toyota_2017.dbc index 5679ecf39..294b948dd 100644 --- a/generator/toyota/_toyota_2017.dbc +++ b/generator/toyota/_toyota_2017.dbc @@ -40,6 +40,11 @@ BO_ 36 KINEMATICS: 8 XXX SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX +BO_ 37 STEER_ANGLE_SENSOR: 8 XXX + SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX + SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX + SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX + BO_ 166 BRAKE: 8 XXX SG_ BRAKE_AMOUNT : 7|8@0+ (1,0) [0|255] "" XXX SG_ BRAKE_PEDAL : 23|8@0+ (1,0) [0|255] "" XXX @@ -57,11 +62,18 @@ BO_ 180 SPEED: 8 XXX BO_ 466 PCM_CRUISE: 8 XXX SG_ GAS_RELEASED : 4|1@0+ (1,0) [0|1] "" XXX + SG_ CRUISE_ACTIVE : 5|1@0+ (1,0) [0|1] "" XXX SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX +BO_ 467 PCM_CRUISE_2: 8 XXX + SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX + SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX + SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + BO_ 552 ACCELEROMETER: 8 XXX SG_ ACCEL_Z : 22|15@0- (1,0) [0|32767] "" XXX SG_ ACCEL_X : 6|15@0- (0.001,0) [-20|20] "m/s2" XXX @@ -102,23 +114,10 @@ BO_ 835 ACC_CONTROL: 8 DSU SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX -BO_ 1556 STEERING_LEVERS: 8 XXX - SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX - -BO_ 37 STEER_ANGLE_SENSOR: 8 XXX - SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX - SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX - SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX - -BO_ 467 PCM_CRUISE_2: 8 XXX - SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX - SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX - SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - 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_ UI_SET_SPEED : 31|8@0+ (1,0) [0|255] "" XXX BO_ 951 ESP_CONTROL: 8 ESP @@ -149,6 +148,9 @@ BO_ 1042 LKAS_HUD: 8 XXX BO_ 1553 UI_SEETING: 8 XXX SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX + +BO_ 1556 STEERING_LEVERS: 8 XXX + SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX BO_ 1568 SEATS_DOORS: 8 XXX SG_ SEATBELT_DRIVER_UNLATCHED : 62|1@0+ (1,0) [0|1] "" XXX @@ -160,32 +162,95 @@ BO_ 1568 SEATS_DOORS: 8 XXX BO_ 1570 LIGHT_STALK: 8 SCM SG_ AUTO_HIGH_BEAM : 37|1@0+ (1,0) [0|1] "" XXX +BO_ 1161 RSA1: 8 FCM + SG_ TSGN1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY1 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT1 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL1 : 23|8@0+ (1,0) [0|0] "kph" XXX + SG_ SPLSGN1 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN2 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN2 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY2 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT2 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL2 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_P : 63|2@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_A : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID1 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1162 RSA2: 8 FCM + SG_ TSGN3 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY3 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT3 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN3 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN4 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN4 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY4 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT4 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ DPSGNREQ : 54|1@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMP : 53|3@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMA : 50|3@0+ (1,0) [0|0] "" XXX + SG_ SPDUNT : 63|2@0+ (1,0) [0|0] "" XXX + SG_ TSRWMSG : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID2 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1163 RSA3: 8 FCM + SG_ TSREQPD : 7|1@0+ (1,0) [0|0] "" XXX + SG_ TSRMSW : 6|1@0+ (1,0) [0|0] "" XXX + SG_ OTSGNNTM : 5|2@0+ (1,0) [0|0] "" XXX + SG_ NTLVLSPD : 3|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPNTM : 1|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPVALL : 11|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALM : 19|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALH : 27|4@0+ (1,-5) [0|0] "" XXX + SG_ TSRSPU : 33|2@0+ (1,0) [0|0] "" XXX + CM_ SG_ 36 ACCEL_Y "unit is tbd"; CM_ SG_ 36 YAW_RATE "verify"; CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd"; +CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; +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_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt 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?"; -CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; -CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; -CM_ SG_ 37 STEER_RATE "factor is tbd"; -CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect"; -CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph"; CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; +CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; CM_ SG_ 1042 REPEATED_BEEPS "recommended for fcw and other important alerts"; -VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off" ; -VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok" ; +CM_ SG_ 1161 SPDVAL1 "Numbers 0-199 is displayed, 200-254 displays circle without number and 255 is for no limit."; +CM_ SG_ 1161 SYNCID1 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1161 SPDVAL2 "conditional speed value 70" +CM_ SG_ 1162 SGNNUMP "1 if SPDVAL1 is set, otherwise 0"; +CM_ SG_ 1162 SYNCID2 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1163 TSREQPD "always 1"; +CM_ SG_ 1163 TSRMSW "always 1"; +CM_ SG_ 1163 OTSGNNTM "always 3"; +CM_ SG_ 1163 NTLVLSPD "always 3"; +CM_ SG_ 1163 OVSPNTM "always 3"; +CM_ SG_ 1163 OVSPVALL "-5 at start then 2 after 2 seconds"; +CM_ SG_ 1163 OVSPVALM "-5 at start then 5 after 2 seconds"; +CM_ SG_ 1163 OVSPVALH "-5 at start then 10 after 2 seconds"; +CM_ SG_ 1163 TSRSPU "always 1"; + +VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; +VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; VAL_ 614 STATE 3 "enabled" 1 "disabled"; VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; -VAL_ 1553 UNITS 1 "km" 2 "miles"; -VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left" ; +VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; VAL_ 1042 RIGHT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; VAL_ 1042 LEFT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; -VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; +VAL_ 1553 UNITS 1 "km" 2 "miles"; +VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; +VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; +VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 65 "no overtake" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional" 0 "none"; + CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; diff --git a/generator/toyota/lexus_is_2018_pt.dbc b/generator/toyota/lexus_is_2018_pt.dbc new file mode 100644 index 000000000..6548822fd --- /dev/null +++ b/generator/toyota/lexus_is_2018_pt.dbc @@ -0,0 +1,39 @@ +CM_ "IMPORT _toyota_2017.dbc" +CM_ "IMPORT _comma.dbc" + +BO_ 550 BRAKE_MODULE: 8 XXX + SG_ BRAKE_PRESSURE : 0|9@0+ (1,0) [0|511] "" XXX + SG_ BRAKE_POSITION : 16|9@0+ (1,0) [0|511] "" XXX + SG_ BRAKE_PRESSED : 37|1@0+ (1,0) [0|1] "" XXX + +BO_ 705 GAS_PEDAL: 8 XXX + SG_ GAS_RELEASED : 3|1@0+ (1,0) [0|1] "" XXX + SG_ GAS_PEDAL : 55|8@0+ (0.005,0) [0|1] "" XXX + +BO_ 608 STEER_TORQUE_SENSOR: 8 XXX + SG_ STEER_TORQUE_EPS : 47|16@0- (0.73,0) [-20000|20000] "" XXX + SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX + SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 610 EPS_STATUS: 5 EPS + SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX + SG_ LKA_STATE : 31|7@0+ (1,0) [0|127] "" XXX + SG_ TYPE : 24|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 39|8@0+ (1,0) [0|255] "" XXX + +BO_ 956 GEAR_PACKET: 8 XXX + SG_ GEAR : 13|6@0+ (1,0) [0|63] "" XXX + +BO_ 1009 PCM_CRUISE_3: 8 XXX + SG_ MAIN_ON : 13|1@0+ (1,0) [0|3] "" XXX + SG_ CRUISE_STATE : 10|1@0+ (1,0) [0|1] "" XXX + SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "mph" XXX + +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"; +CM_ SG_ 1009 SET_SPEED "units seem to be whatever the car is set to"; +VAL_ 956 GEAR 0 "D" 1 "S" 8 "N" 16 "R" 32 "P"; +VAL_ 610 IPAS_STATE 5 "override" 3 "enabled" 1 "disabled"; +VAL_ 610 LKA_STATE 25 "temporary_fault" 9 "temporary_fault2" 5 "active" 1 "standby"; diff --git a/gm_global_a_object.dbc b/gm_global_a_object.dbc index b4aa31a3e..8847bab39 100644 --- a/gm_global_a_object.dbc +++ b/gm_global_a_object.dbc @@ -67,8 +67,37 @@ BO_ 776 ASCMAccSpeedStatus: 7 NEO SG_ VehicleSpeed : 15|12@0+ (1,0) [0|0] "" B233B_LRR SG_ AlwaysOne : 3|1@0+ (1,0) [0|0] "" B233B_LRR -BO_ 1120 LRRNumObjects: 8 B233B_LRR - SG_ LRRNumObjects : 20|5@0+ (1,0) [0|0] "" NEO +BO_ 1120 F_LRR_Obj_Header: 8 LRR_FO + SG_ FLRRRollingCount : 7|2@0+ (1,0) [0|3] "" EOCM_F_FO + SG_ FLRRModeCmdFdbk : 23|3@0+ (1,0) [0|7] "" EOCM_F_FO + SG_ FLRRNumValidTargets : 20|5@0+ (1,0) [0|31] "" EOCM_F_FO + SG_ FLRRTimeStampV : 31|1@0+ (1,0) [0|1] "" EOCM_F_FO + SG_ FLRRTimeStamp : 2|11@0+ (1,0) [0|2047] "ms" EOCM_F_FO + SG_ FLRRRoadTypeInfo : 5|3@0+ (1,0) [0|7] "" EOCM_F_FO + SG_ FLRRBurstChecksum : 55|16@0+ (1,0) [0|65535] "" EOCM_F_FO + SG_ FLRRDiagSpare : 30|1@0+ (1,0) [0|1] "" EOCM_F_FO + SG_ FLRRVltgOutRngLo : 44|1@0+ (1,0) [0|1] "" EOCM_F_FO + SG_ FLRRVltgOutRngHi : 43|1@0+ (1,0) [0|1] "" EOCM_F_FO + SG_ FLRRSvcAlgnInPrcs : 38|1@0+ (1,0) [0|1] "" EOCM_F_FO + SG_ FLRRSnsrBlckd : 45|1@0+ (1,0) [0|1] "" EOCM_F_FO + SG_ FLRRSnstvFltPrsntInt : 24|1@0+ (1,0) [0|1] "" EOCM_F_FO + SG_ FLRRPlntAlgnInProc : 37|1@0+ (1,0) [0|1] "" EOCM_F_FO + SG_ FLRRMsalgnYawRt : 47|1@0+ (1,0) [0|1] "" EOCM_F_FO + SG_ FLRRMsalgnYawLt : 46|1@0+ (1,0) [0|1] "" EOCM_F_FO + SG_ FLRRLonVelPlsblityFlt : 35|1@0+ (1,0) [0|1] "" EOCM_F_FO + SG_ FLRRYawRtPlsblityFlt : 34|1@0+ (1,0) [0|1] "" EOCM_F_FO + SG_ FLRRMsalgnPtchUp : 32|1@0+ (1,0) [0|1] "" EOCM_F_FO + SG_ FLRRMsalgnPtchDn : 33|1@0+ (1,0) [0|1] "" EOCM_F_FO + SG_ FLRRInitDiagCmplt : 40|1@0+ (1,0) [0|1] "" EOCM_F_FO + SG_ FLRRHWFltPrsntInt : 25|1@0+ (1,0) [0|1] "" EOCM_F_FO + SG_ FLRRExtIntrfrnc : 36|1@0+ (1,0) [0|1] "" EOCM_F_FO + SG_ FLRRCANSgnlSpvFld : 29|1@0+ (1,0) [0|1] "" EOCM_F_FO + SG_ FLRRCANRxErr : 28|1@0+ (1,0) [0|1] "" EOCM_F_FO + SG_ FLRRTunlDtctd : 27|1@0+ (1,0) [0|1] "" EOCM_F_FO + SG_ FLRRAmbTmpOutRngLw : 42|1@0+ (1,0) [0|1] "" EOCM_F_FO + SG_ FLRRAmbTmpOutRngHi : 41|1@0+ (1,0) [0|1] "" EOCM_F_FO + SG_ FLRRAntTngFltPrsnt : 26|1@0+ (1,0) [0|1] "" EOCM_F_FO + SG_ FLRRAlgnFltPrsnt : 39|1@0+ (1,0) [0|1] "" EOCM_F_FO BO_ 1134 LRRObject14: 8 B233B_LRR SG_ TrkRange : 5|11@0+ (0.125,0) [0|255.875] "m" NEO diff --git a/gm_global_a_powertrain.dbc b/gm_global_a_powertrain.dbc index 701054908..27f181dc0 100644 --- a/gm_global_a_powertrain.dbc +++ b/gm_global_a_powertrain.dbc @@ -35,13 +35,18 @@ BS_: BU_: K16_BECM K73_TCIC K9_BCM K43_PSCM K17_EBCM K20_ECM K114B_HPCM NEO K124_ASCM EPB VAL_TABLE_ TurnSignals 2 "Right Turn" 1 "Left Turn" 0 "None" ; +VAL_TABLE_ Intellibeam 1 "Active" 0 "Inactive" ; +VAL_TABLE_ HighBeamsActive 1 "Active" 0 "Inactive" ; +VAL_TABLE_ HighBeamsTemporary 1 "Active" 0 "Inactive" ; VAL_TABLE_ ACCLeadCar 1 "Present" 0 "Not Present" ; VAL_TABLE_ ACCCmdActive 1 "Active" 0 "Inactive" ; VAL_TABLE_ BrakePedalPressed 1 "Pressed" 0 "Depressed" ; VAL_TABLE_ DistanceButton 1 "Active" 0 "Inactive" ; VAL_TABLE_ LKAButton 1 "Active" 0 "Inactive" ; VAL_TABLE_ ACCButtons 6 "Cancel" 5 "Main" 3 "Set" 2 "Resume" 1 "None" ; +VAL_TABLE_ DriveModeButton 1 "Active" 0 "Inactive" ; VAL_TABLE_ PRNDL 3 "Reverse" 2 "Drive" 1 "Neutral" 0 "Park" ; +VAL_TABLE_ ESPButton 1 "Active" 0 "Inactive" ; VAL_TABLE_ DoorStatus 1 "Opened" 0 "Closed" ; VAL_TABLE_ SeatBeltStatus 1 "Latched" 0 "Unlatched" ; VAL_TABLE_ LKASteeringCmdActive 1 "Active" 0 "Inactive" ; @@ -81,9 +86,13 @@ BO_ 298 BCMDoorBeltStatus: 8 K9_BCM BO_ 309 ECMPRDNL: 8 K20_ECM SG_ PRNDL : 2|3@0+ (1,0) [0|0] "" NEO + SG_ ESPButton : 4|1@0+ (1,0) [0|1] "" XXX BO_ 320 BCMTurnSignals: 3 K9_BCM SG_ TurnSignals : 19|2@0+ (1,0) [0|0] "" NEO + SG_ Intellibeam : 13|1@0+ (1,0) [0|1] "" XXX + SG_ HighBeamsActive : 7|1@0+ (1,0) [0|1] "" XXX + SG_ HighBeamsTemporary : 5|1@0+ (1,0) [0|1] "" XXX BO_ 328 PSCM_148: 1 K43_PSCM @@ -118,6 +127,7 @@ 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_ ACCButtons : 46|3@0+ (1,0) [0|0] "" NEO + SG_ DriveModeButton : 39|1@0+ (1,0) [0|1] "" XXX BO_ 485 PSCMSteeringAngle: 8 K43_PSCM SG_ SteeringWheelAngle : 15|16@0- (0.0625,0) [-540|540] "deg" NEO @@ -224,8 +234,10 @@ BA_ "UseGMParameterIDs" 0; VAL_ 481 DistanceButton 1 "Active" 0 "Inactive" ; VAL_ 481 LKAButton 1 "Active" 0 "Inactive" ; VAL_ 481 ACCButtons 6 "Cancel" 5 "Main" 3 "Set" 2 "Resume" 1 "None" ; +VAL_ 481 DriveModeButton 1 "Active" 0 "Inactive" ; VAL_ 452 CruiseState 4 "Standstill" 3 "Faulted" 1 "Active" 0 "Off" ; VAL_ 309 PRNDL 3 "Reverse" 2 "Drive" 1 "Neutral" 0 "Park" ; +VAL_ 309 ESPButton 1 "Active" 0 "Inactive" ; VAL_ 384 LKASteeringCmdActive 1 "Active" 0 "Inactive" ; VAL_ 880 ACCLeadCar 1 "Present" 0 "Not Present" ; VAL_ 880 ACCGapLevel 3 "Far" 2 "Med" 1 "Near" 0 "Inactive" ; @@ -237,4 +249,7 @@ VAL_ 388 LKATorqueDeliveredStatus 3 "Failed" 2 "Temp. Limited" 1 "Active" 0 "Ina VAL_ 489 BrakePedalPressed 1 "Pressed" 0 "Depressed" ; VAL_ 715 GasRegenCmdActiveInv 1 "Inactive" 0 "Active" ; VAL_ 715 GasRegenCmdActive 1 "Active" 0 "Inactive" ; +VAL_ 320 Intellibeam 1 "Active" 0 "Inactive" ; +VAL_ 320 HighBeamsActive 1 "Active" 0 "Inactive" ; +VAL_ 320 HighBeamsTemporary 1 "Active" 0 "Inactive" ; diff --git a/honda_accord_lx15t_2018_can_generated.dbc b/honda_accord_lx15t_2018_can_generated.dbc index 8cc11ba6a..788963849 100644 --- a/honda_accord_lx15t_2018_can_generated.dbc +++ b/honda_accord_lx15t_2018_can_generated.dbc @@ -264,6 +264,7 @@ BO_ 891 STALK_STATUS_2: 8 XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON +VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; CM_ "honda_accord_lx15t_2018_can.dbc starts here" diff --git a/honda_accord_s2t_2018_can_generated.dbc b/honda_accord_s2t_2018_can_generated.dbc index 663c1acec..43a46aff8 100644 --- a/honda_accord_s2t_2018_can_generated.dbc +++ b/honda_accord_s2t_2018_can_generated.dbc @@ -264,6 +264,7 @@ BO_ 891 STALK_STATUS_2: 8 XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON +VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; CM_ "honda_accord_s2t_2018_can.dbc starts here" diff --git a/honda_civic_hatchback_ex_2017_can_generated.dbc b/honda_civic_hatchback_ex_2017_can_generated.dbc index 42d4e7c96..bbf810dd7 100644 --- a/honda_civic_hatchback_ex_2017_can_generated.dbc +++ b/honda_civic_hatchback_ex_2017_can_generated.dbc @@ -264,6 +264,7 @@ BO_ 891 STALK_STATUS_2: 8 XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON +VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; CM_ "honda_civic_hatchback_ex_2017_can.dbc starts here" diff --git a/honda_civic_touring_2016_can_generated.dbc b/honda_civic_touring_2016_can_generated.dbc index ff5f80caa..841631bf6 100644 --- a/honda_civic_touring_2016_can_generated.dbc +++ b/honda_civic_touring_2016_can_generated.dbc @@ -358,7 +358,7 @@ CM_ SG_ 420 BRAKE_HOLD_RELATED "On when Brake Hold engaged"; CM_ SG_ 450 EPB_STATE "3 \"engaged\" 2 \"disengaging\" 1 \"engaging\" 0 \"disengaged\""; CM_ SG_ 806 REVERSE_LIGHT "Might be reverse gear selected and not the lights"; -VAL_ 399 STEER_STATUS 5 "fault" 4 "no_torque_alert_2" 2 "no_torque_alert_1" 0 "normal" ; +VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; VAL_ 401 GEAR_SHIFTER 32 "L" 16 "S" 8 "D" 4 "N" 2 "R" 1 "P" ; VAL_ 401 GEAR 7 "L" 10 "S" 4 "D" 3 "N" 2 "R" 1 "P" ; VAL_ 450 EPB_STATE 3 "engaged" 2 "disengaging" 1 "engaging" 0 "disengaged" ; diff --git a/honda_crv_ex_2017_can_generated.dbc b/honda_crv_ex_2017_can_generated.dbc index f59b155d2..56a6b4e1b 100644 --- a/honda_crv_ex_2017_can_generated.dbc +++ b/honda_crv_ex_2017_can_generated.dbc @@ -264,6 +264,7 @@ BO_ 891 STALK_STATUS_2: 8 XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON +VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; CM_ "honda_crv_ex_2017_can.dbc starts here" diff --git a/honda_crv_touring_2016_can_generated.dbc b/honda_crv_touring_2016_can_generated.dbc index d41386efa..3fa85d899 100644 --- a/honda_crv_touring_2016_can_generated.dbc +++ b/honda_crv_touring_2016_can_generated.dbc @@ -293,7 +293,7 @@ BO_ 891 WIPERS: 8 XXX CM_ SG_ 401 GEAR "10 = reverse, 11 = transition"; -VAL_ 399 STEER_STATUS 5 "fault" 4 "no_torque_alert_2" 2 "no_torque_alert_1" 0 "normal" ; +VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; VAL_ 401 GEAR_SHIFTER 32 "L" 16 "S" 8 "D" 4 "N" 2 "R" 1 "P" ; VAL_ 401 GEAR 7 "L" 10 "S" 4 "D" 3 "N" 2 "R" 1 "P" ; VAL_ 422 CRUISE_BUTTONS 7 "tbd" 6 "tbd" 5 "tbd" 4 "accel_res" 3 "decel_set" 2 "cancel" 1 "main" 0 "none" ; diff --git a/honda_fit_ex_2018_can_generated.dbc b/honda_fit_ex_2018_can_generated.dbc index 9276d3195..2e7c7fb55 100644 --- a/honda_fit_ex_2018_can_generated.dbc +++ b/honda_fit_ex_2018_can_generated.dbc @@ -316,7 +316,7 @@ BO_ 884 STALK_STATUS: 8 XXX CM_ SG_ 401 GEAR "10 = reverse, 11 = transition"; CM_ SG_ 420 BRAKE_HOLD_RELATED "On when Brake Hold engaged"; -VAL_ 399 STEER_STATUS 5 "fault" 4 "no_torque_alert_2" 2 "no_torque_alert_1" 0 "normal" ; +VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; VAL_ 401 GEAR_SHIFTER 32 "L" 16 "S" 8 "D" 4 "N" 2 "R" 1 "P" ; VAL_ 401 GEAR 7 "L" 10 "S" 4 "D" 3 "N" 2 "R" 1 "P" ; VAL_ 422 CRUISE_BUTTONS 7 "tbd" 6 "tbd" 5 "tbd" 4 "accel_res" 3 "decel_set" 2 "cancel" 1 "main" 0 "none" ; diff --git a/honda_odyssey_exl_2018_generated.dbc b/honda_odyssey_exl_2018_generated.dbc index e6ff81cc3..05dd1a436 100644 --- a/honda_odyssey_exl_2018_generated.dbc +++ b/honda_odyssey_exl_2018_generated.dbc @@ -329,7 +329,7 @@ CM_ SG_ 804 CRUISE_SPEED_PCM "255 = no speed"; CM_ SG_ 806 REVERSE_LIGHT "Might be reverse gear selected and not the lights"; CM_ SG_ 829 BEEP "beeps are pleasant, chimes are for warnings etc..."; -VAL_ 399 STEER_STATUS 5 "fault" 4 "no_torque_alert_2" 2 "no_torque_alert_1" 0 "normal" ; +VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; VAL_ 419 GEAR_SHIFTER 10 "S" 4 "D" 3 "N" 2 "R" 1 "P" ; VAL_ 450 EPB_STATE 3 "engaged" 2 "disengaging" 1 "engaging" 0 "disengaged" ; VAL_ 662 CRUISE_BUTTONS 7 "tbd" 6 "tbd" 5 "tbd" 4 "accel_res" 3 "decel_set" 2 "cancel" 1 "main" 0 "none" ; @@ -339,7 +339,5 @@ VAL_ 829 BEEP 3 "single_beep" 2 "triple_beep" 1 "repeated_beep" 0 "no_beep" ; VAL_ 891 WIPERS 4 "High" 2 "Low" 0 "Off" ; VAL_ 927 ACC_ALERTS 29 "esp_active_acc_canceled" 10 "b_pedal_applied" 9 "speed_too_low" 8 "speed_too_high" 7 "p_brake_applied" 6 "gear_no_d" 5 "seatbelt" 4 "too_steep_downhill" 3 "too_steep_uphill" 2 "too_close" 1 "no_vehicle_ahead" ; VAL_ 806 CMBS_BUTTON 3 "pressed" 0 "released" ; -VAL_ 891 WIPERS 4 "High" 2 "Low" 0 "Off" ; -VAL_ 927 ACC_ALERTS 29 "esp_active_acc_canceled" 10 "b_pedal_applied" 9 "speed_too_low" 8 "speed_too_high" 7 "p_brake_applied" 6 "gear_no_d" 5 "seatbelt" 4 "too_steep_downhill" 3 "too_steep_uphill" 2 "too_close" 1 "no_vehicle_ahead" ; CM_ "CHFFR_METRIC 342 STEER_ANGLE STEER_ANGLE 0.36 180; CHFFR_METRIC 380 ENGINE_RPM ENGINE_RPM 1 0; CHFFR_METRIC 804 ENGINE_TEMPERATURE ENGINE_TEMPERATURE 1 0"; diff --git a/honda_pilot_touring_2017_can_generated.dbc b/honda_pilot_touring_2017_can_generated.dbc index d8accf081..0c43f98f3 100644 --- a/honda_pilot_touring_2017_can_generated.dbc +++ b/honda_pilot_touring_2017_can_generated.dbc @@ -287,7 +287,7 @@ BO_ 660 SCM_FEEDBACK: 8 SCM SG_ LEFT_BLINKER : 5|1@0+ (1,0) [0|1] "" EON SG_ WIPERS_SPEED : 4|2@0+ (1,0) [0|3] "" EON -VAL_ 399 STEER_STATUS 5 "fault" 4 "no_torque_alert_2" 2 "no_torque_alert_1" 0 "normal" ; +VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; VAL_ 419 GEAR_SHIFTER 32 "D" 8 "R" 4 "P" ; VAL_ 422 CRUISE_BUTTONS 7 "tbd" 6 "tbd" 5 "tbd" 4 "accel_res" 3 "decel_set" 2 "cancel" 1 "main" 0 "none" ; VAL_ 422 LIGHTS_SETTING 3 "high_beam" 2 "low_beam" 1 "position" 0 "no_lights" ; diff --git a/honda_ridgeline_black_edition_2017_can_generated.dbc b/honda_ridgeline_black_edition_2017_can_generated.dbc index 73be13bc8..a8a97d7f1 100644 --- a/honda_ridgeline_black_edition_2017_can_generated.dbc +++ b/honda_ridgeline_black_edition_2017_can_generated.dbc @@ -282,7 +282,7 @@ BO_ 660 SCM_FEEDBACK: 8 SCM SG_ LEFT_BLINKER : 5|1@0+ (1,0) [0|1] "" EON SG_ WIPERS_SPEED : 4|2@0+ (1,0) [0|3] "" EON -VAL_ 399 STEER_STATUS 5 "fault" 4 "no_torque_alert_2" 2 "no_torque_alert_1" 0 "normal" ; +VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; VAL_ 419 GEAR_SHIFTER 32 "D" 8 "R" 4 "P" ; VAL_ 422 CRUISE_BUTTONS 7 "tbd" 6 "tbd" 5 "tbd" 4 "accel_res" 3 "decel_set" 2 "cancel" 1 "main" 0 "none" ; VAL_ 422 LIGHTS_SETTING 3 "high_beam" 2 "low_beam" 1 "position" 0 "no_lights" ; diff --git a/lexus_is_2018_pt_generated.dbc b/lexus_is_2018_pt_generated.dbc new file mode 100644 index 000000000..c0522bec2 --- /dev/null +++ b/lexus_is_2018_pt_generated.dbc @@ -0,0 +1,298 @@ +CM_ "AUTOGENERATED FILE, DO NOT EDIT" + + +CM_ "Imported file _comma.dbc starts here" +BO_ 359 STEERING_IPAS_COMMA: 8 IPAS + SG_ STATE : 7|4@0+ (1,0) [0|15] "" XXX + SG_ ANGLE : 3|12@0- (1.5,0) [-510|510] "deg" XXX + SG_ SET_ME_X10 : 23|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX + SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +CM BO_ STEERING_IPAS_COMMA "Copy of msg 614 so we can do angle control while the Park Assist ECU is connected (Panda spoofs 614 with 359 on connector J70). Note that addresses 0x266 and 0x167 are checksum-invariant"; + + BO_ 512 GAS_COMMAND: 6 EON + SG_ GAS_COMMAND : 7|16@0+ (0.0244140625,0) [0|1] "" INTERCEPTOR + SG_ GAS_COMMAND2 : 23|16@0+ (0.0244140625,-11.962890625) [0|1] "" INTERCEPTOR + SG_ ENABLE : 39|1@0+ (1,0) [0|1] "" INTERCEPTOR + SG_ CHECKSUM : 47|8@0+ (1,0) [0|3] "" INTERCEPTOR + + BO_ 513 GAS_SENSOR: 6 INTERCEPTOR + SG_ INTERCEPTOR_GAS : 7|16@0+ (0.0244140625,0) [0|1] "" EON + SG_ INTERCEPTOR_GAS2 : 23|16@0+ (0.0244140625,-11.962890625) [0|1] "" EON + SG_ STATE : 39|8@0+ (1,0) [0|255] "" EON + SG_ CHECKSUM : 47|8@0+ (1,0) [0|3] "" EON + + VAL_ 513 STATE 5 "FAULT_TIMEOUT" 4 "FAULT_STARTUP" 3 "FAULT_SCE" 2 "FAULT_SEND" 1 "FAULT_BAD_CHECKSUM" 0 "NO_FAULT" ; + + +CM_ "Imported file _toyota_2017.dbc starts here" +VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + VAL_TABLE_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BS_: + +BU_: XXX DSU HCU EPS IPAS + +BO_ 36 KINEMATICS: 8 XXX + SG_ ACCEL_Y : 33|10@0+ (1,-512) [0|65535] "" XXX + SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX + SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX + +BO_ 166 BRAKE: 8 XXX + SG_ BRAKE_AMOUNT : 7|8@0+ (1,0) [0|255] "" XXX + SG_ BRAKE_PEDAL : 23|8@0+ (1,0) [0|255] "" XXX + +BO_ 170 WHEEL_SPEEDS: 8 XXX + SG_ WHEEL_SPEED_FR : 7|16@0+ (0.01,-67.67) [0|250] "kph" XXX + SG_ WHEEL_SPEED_FL : 23|16@0+ (0.01,-67.67) [0|250] "kph" XXX + SG_ WHEEL_SPEED_RR : 39|16@0+ (0.01,-67.67) [0|250] "kph" XXX + SG_ WHEEL_SPEED_RL : 55|16@0+ (0.01,-67.67) [0|250] "kph" XXX + +BO_ 180 SPEED: 8 XXX + SG_ ENCODER : 39|8@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + SG_ SPEED : 47|16@0+ (0.01,0) [0|250] "kph" XXX + +BO_ 466 PCM_CRUISE: 8 XXX + SG_ GAS_RELEASED : 4|1@0+ (1,0) [0|1] "" XXX + SG_ CRUISE_ACTIVE : 5|1@0+ (1,0) [0|1] "" XXX + SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX + SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX + SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 552 ACCELEROMETER: 8 XXX + SG_ ACCEL_Z : 22|15@0- (1,0) [0|32767] "" XXX + SG_ ACCEL_X : 6|15@0- (0.001,0) [-20|20] "m/s2" XXX + +BO_ 560 BRAKE_MODULE2: 7 XXX + SG_ BRAKE_PRESSED : 26|1@0+ (1,0) [0|1] "" XXX + +BO_ 614 STEERING_IPAS: 8 IPAS + SG_ STATE : 7|4@0+ (1,0) [0|15] "" XXX + SG_ ANGLE : 3|12@0- (1.5,0) [-510|510] "deg" XXX + SG_ SET_ME_X10 : 23|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX + SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 643 PRE_COLLISION: 8 XXX + +BO_ 740 STEERING_LKA: 5 XXX + SG_ LKA_STATE : 31|8@0+ (1,0) [0|255] "" XXX + SG_ STEER_REQUEST : 0|1@0+ (1,0) [0|1] "" XXX + SG_ COUNTER : 6|6@0+ (1,0) [0|63] "" XXX + SG_ SET_ME_1 : 7|1@0+ (1,0) [0|1] "" XXX + SG_ STEER_TORQUE_CMD : 15|16@0- (1,0) [0|65535] "" XXX + SG_ CHECKSUM : 39|8@0+ (1,0) [0|255] "" XXX + +BO_ 742 LEAD_INFO: 8 DSU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" HCU + SG_ LEAD_REL_SPEED : 23|12@0- (0.025,0) [-100|100] "m/s" HCU + SG_ LEAD_LONG_DIST : 7|13@0+ (0.05,0) [0|300] "m" HCU + +BO_ 835 ACC_CONTROL: 8 DSU + SG_ ACCEL_CMD : 7|16@0- (0.001,0) [-20|20] "m/s2" HCU + SG_ SET_ME_X63 : 23|8@0+ (1,0) [0|255] "" HCU + SG_ SET_ME_1 : 30|1@0+ (1,0) [0|1] "" HCU + SG_ RELEASE_STANDSTILL : 31|1@0+ (1,0) [0|1] "" HCU + SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 1556 STEERING_LEVERS: 8 XXX + SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX + +BO_ 37 STEER_ANGLE_SENSOR: 8 XXX + SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX + SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX + SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX + +BO_ 467 PCM_CRUISE_2: 8 XXX + SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX + SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX + SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +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_ UI_SET_SPEED : 31|8@0+ (1,0) [0|255] "" XXX + +BO_ 951 ESP_CONTROL: 8 ESP + SG_ TC_DISABLED : 13|1@0+ (1,0) [0|1] "" XXX + SG_ BRAKE_LIGHTS_ACC : 18|1@0+ (1,0) [0|1] "" XXX + +BO_ 1041 ACC_HUD: 8 DSU + SG_ FCW : 4|1@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X20 : 15|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X10 : 39|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X80 : 55|8@0+ (1,0) [0|1] "" XXX + +BO_ 1042 LKAS_HUD: 8 XXX + SG_ BARRIERS : 1|2@0+ (1,0) [0|3] "" XXX + SG_ RIGHT_LINE : 3|2@0+ (1,0) [0|3] "" XXX + SG_ LEFT_LINE : 5|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X01 : 7|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X01_2 : 11|2@0+ (1,0) [0|3] "" XXX + SG_ LDA_ALERT : 9|2@0+ (1,0) [0|3] "" XXX + SG_ TWO_BEEPS : 12|1@0+ (1,0) [0|1] "" XXX + SG_ ADJUSTING_CAMERA : 13|1@0+ (1,0) [0|1] "" XXX + SG_ LDA_MALFUNCTION : 15|1@0+ (1,0) [0|1] "" XXX + SG_ REPEATED_BEEPS : 32|1@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X0C : 23|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X2C : 47|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X38 : 55|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X02 : 63|8@0+ (1,0) [0|1] "" XXX + +BO_ 1553 UI_SEETING: 8 XXX + SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX + +BO_ 1568 SEATS_DOORS: 8 XXX + SG_ SEATBELT_DRIVER_UNLATCHED : 62|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_FL : 45|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_RL : 42|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_RR : 43|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_FR : 44|1@0+ (1,0) [0|1] "" XXX + +BO_ 1570 LIGHT_STALK: 8 SCM + SG_ AUTO_HIGH_BEAM : 37|1@0+ (1,0) [0|1] "" XXX + +BO_ 1161 RSA1: 8 FCM + SG_ TSGN1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY1 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT1 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL1 : 23|8@0+ (1,0) [0|0] "kph" XXX + SG_ SPLSGN1 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN2 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN2 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY2 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT2 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL2 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_P : 63|2@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_A : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID1 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1162 RSA2: 8 FCM + SG_ TSGN3 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY3 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT3 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN3 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN4 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN4 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY4 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT4 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ DPSGNREQ : 54|1@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMP : 53|3@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMA : 50|3@0+ (1,0) [0|0] "" XXX + SG_ SPDUNT : 63|2@0+ (1,0) [0|0] "" XXX + SG_ TSRWMSG : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID2 : 59|4@0+ (1,0) [0|0] "" XXX + +CM_ SG_ 36 ACCEL_Y "unit is tbd"; +CM_ SG_ 36 YAW_RATE "verify"; +CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd"; +CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors"; +CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?"; +CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; +CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; +CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; +CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; +CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; +CM_ SG_ 37 STEER_RATE "factor is tbd"; +CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect"; +CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph"; +CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; +CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; +CM_ SG_ 1042 REPEATED_BEEPS "recommended for fcw and other important alerts"; +CM_ SG_ 1161 SPDVAL1 "is the displayed speed 10,30,50,60,70,80,90,100,120 and 255 is for no limit. SPDVAL2 is the secondary speed usually written smaller"; +VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off" ; +VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok" ; +VAL_ 614 STATE 3 "enabled" 1 "disabled"; +VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; +VAL_ 1553 UNITS 1 "km" 2 "miles"; +VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left" ; +VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; +VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; +VAL_ 1042 RIGHT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; +VAL_ 1042 LEFT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; +VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; + +CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; + +CM_ "lexus_is_2018_pt.dbc starts here" + + + +BO_ 550 BRAKE_MODULE: 8 XXX + SG_ BRAKE_PRESSURE : 0|9@0+ (1,0) [0|511] "" XXX + SG_ BRAKE_POSITION : 16|9@0+ (1,0) [0|511] "" XXX + SG_ BRAKE_PRESSED : 37|1@0+ (1,0) [0|1] "" XXX + +BO_ 705 GAS_PEDAL: 8 XXX + SG_ GAS_RELEASED : 3|1@0+ (1,0) [0|1] "" XXX + SG_ GAS_PEDAL : 55|8@0+ (0.005,0) [0|1] "" XXX + +BO_ 608 STEER_TORQUE_SENSOR: 8 XXX + SG_ STEER_TORQUE_EPS : 47|16@0- (0.73,0) [-20000|20000] "" XXX + SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX + SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 610 EPS_STATUS: 5 EPS + SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX + SG_ LKA_STATE : 31|7@0+ (1,0) [0|127] "" XXX + SG_ TYPE : 24|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 39|8@0+ (1,0) [0|255] "" XXX + +BO_ 956 GEAR_PACKET: 8 XXX + SG_ GEAR : 13|6@0+ (1,0) [0|63] "" XXX + +BO_ 1009 PCM_CRUISE_3: 8 XXX + SG_ MAIN_ON : 13|1@0+ (1,0) [0|3] "" XXX + SG_ CRUISE_STATE : 10|1@0+ (1,0) [0|1] "" XXX + SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "mph" XXX + +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"; +CM_ SG_ 1009 SET_SPEED "units seem to be whatever the car is set to"; +VAL_ 956 GEAR 0 "D" 1 "S" 8 "N" 16 "R" 32 "P"; +VAL_ 610 IPAS_STATE 5 "override" 3 "enabled" 1 "disabled"; +VAL_ 610 LKA_STATE 25 "temporary_fault" 9 "temporary_fault2" 5 "active" 1 "standby"; diff --git a/lexus_rx_hybrid_2017_pt_generated.dbc b/lexus_rx_hybrid_2017_pt_generated.dbc index 38dc35ce3..94ca42f81 100644 --- a/lexus_rx_hybrid_2017_pt_generated.dbc +++ b/lexus_rx_hybrid_2017_pt_generated.dbc @@ -72,6 +72,11 @@ BO_ 36 KINEMATICS: 8 XXX SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX +BO_ 37 STEER_ANGLE_SENSOR: 8 XXX + SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX + SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX + SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX + BO_ 166 BRAKE: 8 XXX SG_ BRAKE_AMOUNT : 7|8@0+ (1,0) [0|255] "" XXX SG_ BRAKE_PEDAL : 23|8@0+ (1,0) [0|255] "" XXX @@ -89,11 +94,18 @@ BO_ 180 SPEED: 8 XXX BO_ 466 PCM_CRUISE: 8 XXX SG_ GAS_RELEASED : 4|1@0+ (1,0) [0|1] "" XXX + SG_ CRUISE_ACTIVE : 5|1@0+ (1,0) [0|1] "" XXX SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX +BO_ 467 PCM_CRUISE_2: 8 XXX + SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX + SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX + SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + BO_ 552 ACCELEROMETER: 8 XXX SG_ ACCEL_Z : 22|15@0- (1,0) [0|32767] "" XXX SG_ ACCEL_X : 6|15@0- (0.001,0) [-20|20] "m/s2" XXX @@ -134,23 +146,10 @@ BO_ 835 ACC_CONTROL: 8 DSU SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX -BO_ 1556 STEERING_LEVERS: 8 XXX - SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX - -BO_ 37 STEER_ANGLE_SENSOR: 8 XXX - SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX - SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX - SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX - -BO_ 467 PCM_CRUISE_2: 8 XXX - SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX - SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX - SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - 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_ UI_SET_SPEED : 31|8@0+ (1,0) [0|255] "" XXX BO_ 951 ESP_CONTROL: 8 ESP @@ -181,6 +180,9 @@ BO_ 1042 LKAS_HUD: 8 XXX BO_ 1553 UI_SEETING: 8 XXX SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX + +BO_ 1556 STEERING_LEVERS: 8 XXX + SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX BO_ 1568 SEATS_DOORS: 8 XXX SG_ SEATBELT_DRIVER_UNLATCHED : 62|1@0+ (1,0) [0|1] "" XXX @@ -192,33 +194,96 @@ BO_ 1568 SEATS_DOORS: 8 XXX BO_ 1570 LIGHT_STALK: 8 SCM SG_ AUTO_HIGH_BEAM : 37|1@0+ (1,0) [0|1] "" XXX +BO_ 1161 RSA1: 8 FCM + SG_ TSGN1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY1 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT1 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL1 : 23|8@0+ (1,0) [0|0] "kph" XXX + SG_ SPLSGN1 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN2 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN2 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY2 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT2 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL2 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_P : 63|2@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_A : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID1 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1162 RSA2: 8 FCM + SG_ TSGN3 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY3 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT3 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN3 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN4 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN4 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY4 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT4 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ DPSGNREQ : 54|1@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMP : 53|3@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMA : 50|3@0+ (1,0) [0|0] "" XXX + SG_ SPDUNT : 63|2@0+ (1,0) [0|0] "" XXX + SG_ TSRWMSG : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID2 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1163 RSA3: 8 FCM + SG_ TSREQPD : 7|1@0+ (1,0) [0|0] "" XXX + SG_ TSRMSW : 6|1@0+ (1,0) [0|0] "" XXX + SG_ OTSGNNTM : 5|2@0+ (1,0) [0|0] "" XXX + SG_ NTLVLSPD : 3|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPNTM : 1|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPVALL : 11|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALM : 19|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALH : 27|4@0+ (1,-5) [0|0] "" XXX + SG_ TSRSPU : 33|2@0+ (1,0) [0|0] "" XXX + CM_ SG_ 36 ACCEL_Y "unit is tbd"; CM_ SG_ 36 YAW_RATE "verify"; CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd"; +CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; +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_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt 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?"; -CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; -CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; -CM_ SG_ 37 STEER_RATE "factor is tbd"; -CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect"; -CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph"; CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; +CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; CM_ SG_ 1042 REPEATED_BEEPS "recommended for fcw and other important alerts"; -VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off" ; -VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok" ; +CM_ SG_ 1161 SPDVAL1 "Numbers 0-199 is displayed, 200-254 displays circle without number and 255 is for no limit."; +CM_ SG_ 1161 SYNCID1 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1161 SPDVAL2 "conditional speed value 70" +CM_ SG_ 1162 SGNNUMP "1 if SPDVAL1 is set, otherwise 0"; +CM_ SG_ 1162 SYNCID2 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1163 TSREQPD "always 1"; +CM_ SG_ 1163 TSRMSW "always 1"; +CM_ SG_ 1163 OTSGNNTM "always 3"; +CM_ SG_ 1163 NTLVLSPD "always 3"; +CM_ SG_ 1163 OVSPNTM "always 3"; +CM_ SG_ 1163 OVSPVALL "-5 at start then 2 after 2 seconds"; +CM_ SG_ 1163 OVSPVALM "-5 at start then 5 after 2 seconds"; +CM_ SG_ 1163 OVSPVALH "-5 at start then 10 after 2 seconds"; +CM_ SG_ 1163 TSRSPU "always 1"; + +VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; +VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; VAL_ 614 STATE 3 "enabled" 1 "disabled"; VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; -VAL_ 1553 UNITS 1 "km" 2 "miles"; -VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left" ; +VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; VAL_ 1042 RIGHT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; VAL_ 1042 LEFT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; -VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; +VAL_ 1553 UNITS 1 "km" 2 "miles"; +VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; +VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; +VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 65 "no overtake" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional" 0 "none"; + CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; diff --git a/toyota_avalon_2017_pt_generated.dbc b/toyota_avalon_2017_pt_generated.dbc index f1b0c5763..c44f2e4b1 100644 --- a/toyota_avalon_2017_pt_generated.dbc +++ b/toyota_avalon_2017_pt_generated.dbc @@ -72,6 +72,11 @@ BO_ 36 KINEMATICS: 8 XXX SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX +BO_ 37 STEER_ANGLE_SENSOR: 8 XXX + SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX + SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX + SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX + BO_ 166 BRAKE: 8 XXX SG_ BRAKE_AMOUNT : 7|8@0+ (1,0) [0|255] "" XXX SG_ BRAKE_PEDAL : 23|8@0+ (1,0) [0|255] "" XXX @@ -89,11 +94,18 @@ BO_ 180 SPEED: 8 XXX BO_ 466 PCM_CRUISE: 8 XXX SG_ GAS_RELEASED : 4|1@0+ (1,0) [0|1] "" XXX + SG_ CRUISE_ACTIVE : 5|1@0+ (1,0) [0|1] "" XXX SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX +BO_ 467 PCM_CRUISE_2: 8 XXX + SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX + SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX + SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + BO_ 552 ACCELEROMETER: 8 XXX SG_ ACCEL_Z : 22|15@0- (1,0) [0|32767] "" XXX SG_ ACCEL_X : 6|15@0- (0.001,0) [-20|20] "m/s2" XXX @@ -134,23 +146,10 @@ BO_ 835 ACC_CONTROL: 8 DSU SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX -BO_ 1556 STEERING_LEVERS: 8 XXX - SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX - -BO_ 37 STEER_ANGLE_SENSOR: 8 XXX - SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX - SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX - SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX - -BO_ 467 PCM_CRUISE_2: 8 XXX - SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX - SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX - SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - 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_ UI_SET_SPEED : 31|8@0+ (1,0) [0|255] "" XXX BO_ 951 ESP_CONTROL: 8 ESP @@ -181,6 +180,9 @@ BO_ 1042 LKAS_HUD: 8 XXX BO_ 1553 UI_SEETING: 8 XXX SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX + +BO_ 1556 STEERING_LEVERS: 8 XXX + SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX BO_ 1568 SEATS_DOORS: 8 XXX SG_ SEATBELT_DRIVER_UNLATCHED : 62|1@0+ (1,0) [0|1] "" XXX @@ -192,33 +194,96 @@ BO_ 1568 SEATS_DOORS: 8 XXX BO_ 1570 LIGHT_STALK: 8 SCM SG_ AUTO_HIGH_BEAM : 37|1@0+ (1,0) [0|1] "" XXX +BO_ 1161 RSA1: 8 FCM + SG_ TSGN1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY1 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT1 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL1 : 23|8@0+ (1,0) [0|0] "kph" XXX + SG_ SPLSGN1 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN2 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN2 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY2 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT2 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL2 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_P : 63|2@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_A : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID1 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1162 RSA2: 8 FCM + SG_ TSGN3 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY3 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT3 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN3 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN4 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN4 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY4 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT4 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ DPSGNREQ : 54|1@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMP : 53|3@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMA : 50|3@0+ (1,0) [0|0] "" XXX + SG_ SPDUNT : 63|2@0+ (1,0) [0|0] "" XXX + SG_ TSRWMSG : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID2 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1163 RSA3: 8 FCM + SG_ TSREQPD : 7|1@0+ (1,0) [0|0] "" XXX + SG_ TSRMSW : 6|1@0+ (1,0) [0|0] "" XXX + SG_ OTSGNNTM : 5|2@0+ (1,0) [0|0] "" XXX + SG_ NTLVLSPD : 3|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPNTM : 1|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPVALL : 11|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALM : 19|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALH : 27|4@0+ (1,-5) [0|0] "" XXX + SG_ TSRSPU : 33|2@0+ (1,0) [0|0] "" XXX + CM_ SG_ 36 ACCEL_Y "unit is tbd"; CM_ SG_ 36 YAW_RATE "verify"; CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd"; +CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; +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_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt 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?"; -CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; -CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; -CM_ SG_ 37 STEER_RATE "factor is tbd"; -CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect"; -CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph"; CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; +CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; CM_ SG_ 1042 REPEATED_BEEPS "recommended for fcw and other important alerts"; -VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off" ; -VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok" ; +CM_ SG_ 1161 SPDVAL1 "Numbers 0-199 is displayed, 200-254 displays circle without number and 255 is for no limit."; +CM_ SG_ 1161 SYNCID1 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1161 SPDVAL2 "conditional speed value 70" +CM_ SG_ 1162 SGNNUMP "1 if SPDVAL1 is set, otherwise 0"; +CM_ SG_ 1162 SYNCID2 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1163 TSREQPD "always 1"; +CM_ SG_ 1163 TSRMSW "always 1"; +CM_ SG_ 1163 OTSGNNTM "always 3"; +CM_ SG_ 1163 NTLVLSPD "always 3"; +CM_ SG_ 1163 OVSPNTM "always 3"; +CM_ SG_ 1163 OVSPVALL "-5 at start then 2 after 2 seconds"; +CM_ SG_ 1163 OVSPVALM "-5 at start then 5 after 2 seconds"; +CM_ SG_ 1163 OVSPVALH "-5 at start then 10 after 2 seconds"; +CM_ SG_ 1163 TSRSPU "always 1"; + +VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; +VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; VAL_ 614 STATE 3 "enabled" 1 "disabled"; VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; -VAL_ 1553 UNITS 1 "km" 2 "miles"; -VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left" ; +VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; VAL_ 1042 RIGHT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; VAL_ 1042 LEFT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; -VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; +VAL_ 1553 UNITS 1 "km" 2 "miles"; +VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; +VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; +VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 65 "no overtake" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional" 0 "none"; + CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; diff --git a/toyota_camry_hybrid_2018_pt_generated.dbc b/toyota_camry_hybrid_2018_pt_generated.dbc index aca1cc23b..4a3c48f96 100644 --- a/toyota_camry_hybrid_2018_pt_generated.dbc +++ b/toyota_camry_hybrid_2018_pt_generated.dbc @@ -72,6 +72,11 @@ BO_ 36 KINEMATICS: 8 XXX SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX +BO_ 37 STEER_ANGLE_SENSOR: 8 XXX + SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX + SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX + SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX + BO_ 166 BRAKE: 8 XXX SG_ BRAKE_AMOUNT : 7|8@0+ (1,0) [0|255] "" XXX SG_ BRAKE_PEDAL : 23|8@0+ (1,0) [0|255] "" XXX @@ -89,11 +94,18 @@ BO_ 180 SPEED: 8 XXX BO_ 466 PCM_CRUISE: 8 XXX SG_ GAS_RELEASED : 4|1@0+ (1,0) [0|1] "" XXX + SG_ CRUISE_ACTIVE : 5|1@0+ (1,0) [0|1] "" XXX SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX +BO_ 467 PCM_CRUISE_2: 8 XXX + SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX + SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX + SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + BO_ 552 ACCELEROMETER: 8 XXX SG_ ACCEL_Z : 22|15@0- (1,0) [0|32767] "" XXX SG_ ACCEL_X : 6|15@0- (0.001,0) [-20|20] "m/s2" XXX @@ -134,23 +146,10 @@ BO_ 835 ACC_CONTROL: 8 DSU SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX -BO_ 1556 STEERING_LEVERS: 8 XXX - SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX - -BO_ 37 STEER_ANGLE_SENSOR: 8 XXX - SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX - SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX - SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX - -BO_ 467 PCM_CRUISE_2: 8 XXX - SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX - SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX - SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - 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_ UI_SET_SPEED : 31|8@0+ (1,0) [0|255] "" XXX BO_ 951 ESP_CONTROL: 8 ESP @@ -181,6 +180,9 @@ BO_ 1042 LKAS_HUD: 8 XXX BO_ 1553 UI_SEETING: 8 XXX SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX + +BO_ 1556 STEERING_LEVERS: 8 XXX + SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX BO_ 1568 SEATS_DOORS: 8 XXX SG_ SEATBELT_DRIVER_UNLATCHED : 62|1@0+ (1,0) [0|1] "" XXX @@ -192,33 +194,96 @@ BO_ 1568 SEATS_DOORS: 8 XXX BO_ 1570 LIGHT_STALK: 8 SCM SG_ AUTO_HIGH_BEAM : 37|1@0+ (1,0) [0|1] "" XXX +BO_ 1161 RSA1: 8 FCM + SG_ TSGN1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY1 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT1 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL1 : 23|8@0+ (1,0) [0|0] "kph" XXX + SG_ SPLSGN1 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN2 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN2 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY2 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT2 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL2 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_P : 63|2@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_A : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID1 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1162 RSA2: 8 FCM + SG_ TSGN3 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY3 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT3 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN3 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN4 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN4 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY4 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT4 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ DPSGNREQ : 54|1@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMP : 53|3@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMA : 50|3@0+ (1,0) [0|0] "" XXX + SG_ SPDUNT : 63|2@0+ (1,0) [0|0] "" XXX + SG_ TSRWMSG : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID2 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1163 RSA3: 8 FCM + SG_ TSREQPD : 7|1@0+ (1,0) [0|0] "" XXX + SG_ TSRMSW : 6|1@0+ (1,0) [0|0] "" XXX + SG_ OTSGNNTM : 5|2@0+ (1,0) [0|0] "" XXX + SG_ NTLVLSPD : 3|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPNTM : 1|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPVALL : 11|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALM : 19|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALH : 27|4@0+ (1,-5) [0|0] "" XXX + SG_ TSRSPU : 33|2@0+ (1,0) [0|0] "" XXX + CM_ SG_ 36 ACCEL_Y "unit is tbd"; CM_ SG_ 36 YAW_RATE "verify"; CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd"; +CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; +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_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt 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?"; -CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; -CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; -CM_ SG_ 37 STEER_RATE "factor is tbd"; -CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect"; -CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph"; CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; +CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; CM_ SG_ 1042 REPEATED_BEEPS "recommended for fcw and other important alerts"; -VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off" ; -VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok" ; +CM_ SG_ 1161 SPDVAL1 "Numbers 0-199 is displayed, 200-254 displays circle without number and 255 is for no limit."; +CM_ SG_ 1161 SYNCID1 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1161 SPDVAL2 "conditional speed value 70" +CM_ SG_ 1162 SGNNUMP "1 if SPDVAL1 is set, otherwise 0"; +CM_ SG_ 1162 SYNCID2 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1163 TSREQPD "always 1"; +CM_ SG_ 1163 TSRMSW "always 1"; +CM_ SG_ 1163 OTSGNNTM "always 3"; +CM_ SG_ 1163 NTLVLSPD "always 3"; +CM_ SG_ 1163 OVSPNTM "always 3"; +CM_ SG_ 1163 OVSPVALL "-5 at start then 2 after 2 seconds"; +CM_ SG_ 1163 OVSPVALM "-5 at start then 5 after 2 seconds"; +CM_ SG_ 1163 OVSPVALH "-5 at start then 10 after 2 seconds"; +CM_ SG_ 1163 TSRSPU "always 1"; + +VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; +VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; VAL_ 614 STATE 3 "enabled" 1 "disabled"; VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; -VAL_ 1553 UNITS 1 "km" 2 "miles"; -VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left" ; +VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; VAL_ 1042 RIGHT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; VAL_ 1042 LEFT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; -VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; +VAL_ 1553 UNITS 1 "km" 2 "miles"; +VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; +VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; +VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 65 "no overtake" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional" 0 "none"; + CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; diff --git a/toyota_chr_2018_pt_generated.dbc b/toyota_chr_2018_pt_generated.dbc index 614ed6dc5..f9da41c3c 100644 --- a/toyota_chr_2018_pt_generated.dbc +++ b/toyota_chr_2018_pt_generated.dbc @@ -72,6 +72,11 @@ BO_ 36 KINEMATICS: 8 XXX SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX +BO_ 37 STEER_ANGLE_SENSOR: 8 XXX + SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX + SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX + SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX + BO_ 166 BRAKE: 8 XXX SG_ BRAKE_AMOUNT : 7|8@0+ (1,0) [0|255] "" XXX SG_ BRAKE_PEDAL : 23|8@0+ (1,0) [0|255] "" XXX @@ -89,11 +94,18 @@ BO_ 180 SPEED: 8 XXX BO_ 466 PCM_CRUISE: 8 XXX SG_ GAS_RELEASED : 4|1@0+ (1,0) [0|1] "" XXX + SG_ CRUISE_ACTIVE : 5|1@0+ (1,0) [0|1] "" XXX SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX +BO_ 467 PCM_CRUISE_2: 8 XXX + SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX + SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX + SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + BO_ 552 ACCELEROMETER: 8 XXX SG_ ACCEL_Z : 22|15@0- (1,0) [0|32767] "" XXX SG_ ACCEL_X : 6|15@0- (0.001,0) [-20|20] "m/s2" XXX @@ -134,23 +146,10 @@ BO_ 835 ACC_CONTROL: 8 DSU SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX -BO_ 1556 STEERING_LEVERS: 8 XXX - SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX - -BO_ 37 STEER_ANGLE_SENSOR: 8 XXX - SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX - SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX - SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX - -BO_ 467 PCM_CRUISE_2: 8 XXX - SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX - SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX - SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - 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_ UI_SET_SPEED : 31|8@0+ (1,0) [0|255] "" XXX BO_ 951 ESP_CONTROL: 8 ESP @@ -181,6 +180,9 @@ BO_ 1042 LKAS_HUD: 8 XXX BO_ 1553 UI_SEETING: 8 XXX SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX + +BO_ 1556 STEERING_LEVERS: 8 XXX + SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX BO_ 1568 SEATS_DOORS: 8 XXX SG_ SEATBELT_DRIVER_UNLATCHED : 62|1@0+ (1,0) [0|1] "" XXX @@ -192,33 +194,96 @@ BO_ 1568 SEATS_DOORS: 8 XXX BO_ 1570 LIGHT_STALK: 8 SCM SG_ AUTO_HIGH_BEAM : 37|1@0+ (1,0) [0|1] "" XXX +BO_ 1161 RSA1: 8 FCM + SG_ TSGN1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY1 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT1 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL1 : 23|8@0+ (1,0) [0|0] "kph" XXX + SG_ SPLSGN1 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN2 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN2 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY2 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT2 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL2 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_P : 63|2@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_A : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID1 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1162 RSA2: 8 FCM + SG_ TSGN3 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY3 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT3 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN3 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN4 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN4 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY4 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT4 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ DPSGNREQ : 54|1@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMP : 53|3@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMA : 50|3@0+ (1,0) [0|0] "" XXX + SG_ SPDUNT : 63|2@0+ (1,0) [0|0] "" XXX + SG_ TSRWMSG : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID2 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1163 RSA3: 8 FCM + SG_ TSREQPD : 7|1@0+ (1,0) [0|0] "" XXX + SG_ TSRMSW : 6|1@0+ (1,0) [0|0] "" XXX + SG_ OTSGNNTM : 5|2@0+ (1,0) [0|0] "" XXX + SG_ NTLVLSPD : 3|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPNTM : 1|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPVALL : 11|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALM : 19|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALH : 27|4@0+ (1,-5) [0|0] "" XXX + SG_ TSRSPU : 33|2@0+ (1,0) [0|0] "" XXX + CM_ SG_ 36 ACCEL_Y "unit is tbd"; CM_ SG_ 36 YAW_RATE "verify"; CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd"; +CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; +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_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt 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?"; -CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; -CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; -CM_ SG_ 37 STEER_RATE "factor is tbd"; -CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect"; -CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph"; CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; +CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; CM_ SG_ 1042 REPEATED_BEEPS "recommended for fcw and other important alerts"; -VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off" ; -VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok" ; +CM_ SG_ 1161 SPDVAL1 "Numbers 0-199 is displayed, 200-254 displays circle without number and 255 is for no limit."; +CM_ SG_ 1161 SYNCID1 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1161 SPDVAL2 "conditional speed value 70" +CM_ SG_ 1162 SGNNUMP "1 if SPDVAL1 is set, otherwise 0"; +CM_ SG_ 1162 SYNCID2 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1163 TSREQPD "always 1"; +CM_ SG_ 1163 TSRMSW "always 1"; +CM_ SG_ 1163 OTSGNNTM "always 3"; +CM_ SG_ 1163 NTLVLSPD "always 3"; +CM_ SG_ 1163 OVSPNTM "always 3"; +CM_ SG_ 1163 OVSPVALL "-5 at start then 2 after 2 seconds"; +CM_ SG_ 1163 OVSPVALM "-5 at start then 5 after 2 seconds"; +CM_ SG_ 1163 OVSPVALH "-5 at start then 10 after 2 seconds"; +CM_ SG_ 1163 TSRSPU "always 1"; + +VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; +VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; VAL_ 614 STATE 3 "enabled" 1 "disabled"; VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; -VAL_ 1553 UNITS 1 "km" 2 "miles"; -VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left" ; +VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; VAL_ 1042 RIGHT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; VAL_ 1042 LEFT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; -VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; +VAL_ 1553 UNITS 1 "km" 2 "miles"; +VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; +VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; +VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 65 "no overtake" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional" 0 "none"; + CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; diff --git a/toyota_chr_hybrid_2018_pt_generated.dbc b/toyota_chr_hybrid_2018_pt_generated.dbc index ceffc6088..5c9fdb457 100644 --- a/toyota_chr_hybrid_2018_pt_generated.dbc +++ b/toyota_chr_hybrid_2018_pt_generated.dbc @@ -72,6 +72,11 @@ BO_ 36 KINEMATICS: 8 XXX SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX +BO_ 37 STEER_ANGLE_SENSOR: 8 XXX + SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX + SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX + SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX + BO_ 166 BRAKE: 8 XXX SG_ BRAKE_AMOUNT : 7|8@0+ (1,0) [0|255] "" XXX SG_ BRAKE_PEDAL : 23|8@0+ (1,0) [0|255] "" XXX @@ -89,11 +94,18 @@ BO_ 180 SPEED: 8 XXX BO_ 466 PCM_CRUISE: 8 XXX SG_ GAS_RELEASED : 4|1@0+ (1,0) [0|1] "" XXX + SG_ CRUISE_ACTIVE : 5|1@0+ (1,0) [0|1] "" XXX SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX +BO_ 467 PCM_CRUISE_2: 8 XXX + SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX + SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX + SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + BO_ 552 ACCELEROMETER: 8 XXX SG_ ACCEL_Z : 22|15@0- (1,0) [0|32767] "" XXX SG_ ACCEL_X : 6|15@0- (0.001,0) [-20|20] "m/s2" XXX @@ -134,23 +146,10 @@ BO_ 835 ACC_CONTROL: 8 DSU SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX -BO_ 1556 STEERING_LEVERS: 8 XXX - SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX - -BO_ 37 STEER_ANGLE_SENSOR: 8 XXX - SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX - SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX - SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX - -BO_ 467 PCM_CRUISE_2: 8 XXX - SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX - SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX - SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - 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_ UI_SET_SPEED : 31|8@0+ (1,0) [0|255] "" XXX BO_ 951 ESP_CONTROL: 8 ESP @@ -181,6 +180,9 @@ BO_ 1042 LKAS_HUD: 8 XXX BO_ 1553 UI_SEETING: 8 XXX SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX + +BO_ 1556 STEERING_LEVERS: 8 XXX + SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX BO_ 1568 SEATS_DOORS: 8 XXX SG_ SEATBELT_DRIVER_UNLATCHED : 62|1@0+ (1,0) [0|1] "" XXX @@ -192,33 +194,96 @@ BO_ 1568 SEATS_DOORS: 8 XXX BO_ 1570 LIGHT_STALK: 8 SCM SG_ AUTO_HIGH_BEAM : 37|1@0+ (1,0) [0|1] "" XXX +BO_ 1161 RSA1: 8 FCM + SG_ TSGN1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY1 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT1 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL1 : 23|8@0+ (1,0) [0|0] "kph" XXX + SG_ SPLSGN1 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN2 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN2 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY2 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT2 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL2 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_P : 63|2@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_A : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID1 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1162 RSA2: 8 FCM + SG_ TSGN3 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY3 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT3 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN3 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN4 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN4 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY4 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT4 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ DPSGNREQ : 54|1@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMP : 53|3@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMA : 50|3@0+ (1,0) [0|0] "" XXX + SG_ SPDUNT : 63|2@0+ (1,0) [0|0] "" XXX + SG_ TSRWMSG : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID2 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1163 RSA3: 8 FCM + SG_ TSREQPD : 7|1@0+ (1,0) [0|0] "" XXX + SG_ TSRMSW : 6|1@0+ (1,0) [0|0] "" XXX + SG_ OTSGNNTM : 5|2@0+ (1,0) [0|0] "" XXX + SG_ NTLVLSPD : 3|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPNTM : 1|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPVALL : 11|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALM : 19|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALH : 27|4@0+ (1,-5) [0|0] "" XXX + SG_ TSRSPU : 33|2@0+ (1,0) [0|0] "" XXX + CM_ SG_ 36 ACCEL_Y "unit is tbd"; CM_ SG_ 36 YAW_RATE "verify"; CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd"; +CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; +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_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt 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?"; -CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; -CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; -CM_ SG_ 37 STEER_RATE "factor is tbd"; -CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect"; -CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph"; CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; +CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; CM_ SG_ 1042 REPEATED_BEEPS "recommended for fcw and other important alerts"; -VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off" ; -VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok" ; +CM_ SG_ 1161 SPDVAL1 "Numbers 0-199 is displayed, 200-254 displays circle without number and 255 is for no limit."; +CM_ SG_ 1161 SYNCID1 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1161 SPDVAL2 "conditional speed value 70" +CM_ SG_ 1162 SGNNUMP "1 if SPDVAL1 is set, otherwise 0"; +CM_ SG_ 1162 SYNCID2 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1163 TSREQPD "always 1"; +CM_ SG_ 1163 TSRMSW "always 1"; +CM_ SG_ 1163 OTSGNNTM "always 3"; +CM_ SG_ 1163 NTLVLSPD "always 3"; +CM_ SG_ 1163 OVSPNTM "always 3"; +CM_ SG_ 1163 OVSPVALL "-5 at start then 2 after 2 seconds"; +CM_ SG_ 1163 OVSPVALM "-5 at start then 5 after 2 seconds"; +CM_ SG_ 1163 OVSPVALH "-5 at start then 10 after 2 seconds"; +CM_ SG_ 1163 TSRSPU "always 1"; + +VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; +VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; VAL_ 614 STATE 3 "enabled" 1 "disabled"; VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; -VAL_ 1553 UNITS 1 "km" 2 "miles"; -VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left" ; +VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; VAL_ 1042 RIGHT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; VAL_ 1042 LEFT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; -VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; +VAL_ 1553 UNITS 1 "km" 2 "miles"; +VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; +VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; +VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 65 "no overtake" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional" 0 "none"; + CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; diff --git a/toyota_corolla_2017_pt_generated.dbc b/toyota_corolla_2017_pt_generated.dbc index 0c00352eb..0331f23c6 100644 --- a/toyota_corolla_2017_pt_generated.dbc +++ b/toyota_corolla_2017_pt_generated.dbc @@ -72,6 +72,11 @@ BO_ 36 KINEMATICS: 8 XXX SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX +BO_ 37 STEER_ANGLE_SENSOR: 8 XXX + SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX + SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX + SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX + BO_ 166 BRAKE: 8 XXX SG_ BRAKE_AMOUNT : 7|8@0+ (1,0) [0|255] "" XXX SG_ BRAKE_PEDAL : 23|8@0+ (1,0) [0|255] "" XXX @@ -89,11 +94,18 @@ BO_ 180 SPEED: 8 XXX BO_ 466 PCM_CRUISE: 8 XXX SG_ GAS_RELEASED : 4|1@0+ (1,0) [0|1] "" XXX + SG_ CRUISE_ACTIVE : 5|1@0+ (1,0) [0|1] "" XXX SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX +BO_ 467 PCM_CRUISE_2: 8 XXX + SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX + SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX + SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + BO_ 552 ACCELEROMETER: 8 XXX SG_ ACCEL_Z : 22|15@0- (1,0) [0|32767] "" XXX SG_ ACCEL_X : 6|15@0- (0.001,0) [-20|20] "m/s2" XXX @@ -134,23 +146,10 @@ BO_ 835 ACC_CONTROL: 8 DSU SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX -BO_ 1556 STEERING_LEVERS: 8 XXX - SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX - -BO_ 37 STEER_ANGLE_SENSOR: 8 XXX - SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX - SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX - SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX - -BO_ 467 PCM_CRUISE_2: 8 XXX - SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX - SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX - SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - 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_ UI_SET_SPEED : 31|8@0+ (1,0) [0|255] "" XXX BO_ 951 ESP_CONTROL: 8 ESP @@ -181,6 +180,9 @@ BO_ 1042 LKAS_HUD: 8 XXX BO_ 1553 UI_SEETING: 8 XXX SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX + +BO_ 1556 STEERING_LEVERS: 8 XXX + SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX BO_ 1568 SEATS_DOORS: 8 XXX SG_ SEATBELT_DRIVER_UNLATCHED : 62|1@0+ (1,0) [0|1] "" XXX @@ -192,33 +194,96 @@ BO_ 1568 SEATS_DOORS: 8 XXX BO_ 1570 LIGHT_STALK: 8 SCM SG_ AUTO_HIGH_BEAM : 37|1@0+ (1,0) [0|1] "" XXX +BO_ 1161 RSA1: 8 FCM + SG_ TSGN1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY1 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT1 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL1 : 23|8@0+ (1,0) [0|0] "kph" XXX + SG_ SPLSGN1 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN2 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN2 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY2 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT2 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL2 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_P : 63|2@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_A : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID1 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1162 RSA2: 8 FCM + SG_ TSGN3 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY3 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT3 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN3 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN4 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN4 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY4 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT4 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ DPSGNREQ : 54|1@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMP : 53|3@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMA : 50|3@0+ (1,0) [0|0] "" XXX + SG_ SPDUNT : 63|2@0+ (1,0) [0|0] "" XXX + SG_ TSRWMSG : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID2 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1163 RSA3: 8 FCM + SG_ TSREQPD : 7|1@0+ (1,0) [0|0] "" XXX + SG_ TSRMSW : 6|1@0+ (1,0) [0|0] "" XXX + SG_ OTSGNNTM : 5|2@0+ (1,0) [0|0] "" XXX + SG_ NTLVLSPD : 3|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPNTM : 1|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPVALL : 11|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALM : 19|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALH : 27|4@0+ (1,-5) [0|0] "" XXX + SG_ TSRSPU : 33|2@0+ (1,0) [0|0] "" XXX + CM_ SG_ 36 ACCEL_Y "unit is tbd"; CM_ SG_ 36 YAW_RATE "verify"; CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd"; +CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; +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_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt 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?"; -CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; -CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; -CM_ SG_ 37 STEER_RATE "factor is tbd"; -CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect"; -CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph"; CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; +CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; CM_ SG_ 1042 REPEATED_BEEPS "recommended for fcw and other important alerts"; -VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off" ; -VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok" ; +CM_ SG_ 1161 SPDVAL1 "Numbers 0-199 is displayed, 200-254 displays circle without number and 255 is for no limit."; +CM_ SG_ 1161 SYNCID1 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1161 SPDVAL2 "conditional speed value 70" +CM_ SG_ 1162 SGNNUMP "1 if SPDVAL1 is set, otherwise 0"; +CM_ SG_ 1162 SYNCID2 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1163 TSREQPD "always 1"; +CM_ SG_ 1163 TSRMSW "always 1"; +CM_ SG_ 1163 OTSGNNTM "always 3"; +CM_ SG_ 1163 NTLVLSPD "always 3"; +CM_ SG_ 1163 OVSPNTM "always 3"; +CM_ SG_ 1163 OVSPVALL "-5 at start then 2 after 2 seconds"; +CM_ SG_ 1163 OVSPVALM "-5 at start then 5 after 2 seconds"; +CM_ SG_ 1163 OVSPVALH "-5 at start then 10 after 2 seconds"; +CM_ SG_ 1163 TSRSPU "always 1"; + +VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; +VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; VAL_ 614 STATE 3 "enabled" 1 "disabled"; VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; -VAL_ 1553 UNITS 1 "km" 2 "miles"; -VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left" ; +VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; VAL_ 1042 RIGHT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; VAL_ 1042 LEFT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; -VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; +VAL_ 1553 UNITS 1 "km" 2 "miles"; +VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; +VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; +VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 65 "no overtake" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional" 0 "none"; + CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; diff --git a/toyota_highlander_2017_pt_generated.dbc b/toyota_highlander_2017_pt_generated.dbc index ef1cdf3c4..10220a752 100644 --- a/toyota_highlander_2017_pt_generated.dbc +++ b/toyota_highlander_2017_pt_generated.dbc @@ -72,6 +72,11 @@ BO_ 36 KINEMATICS: 8 XXX SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX +BO_ 37 STEER_ANGLE_SENSOR: 8 XXX + SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX + SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX + SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX + BO_ 166 BRAKE: 8 XXX SG_ BRAKE_AMOUNT : 7|8@0+ (1,0) [0|255] "" XXX SG_ BRAKE_PEDAL : 23|8@0+ (1,0) [0|255] "" XXX @@ -89,11 +94,18 @@ BO_ 180 SPEED: 8 XXX BO_ 466 PCM_CRUISE: 8 XXX SG_ GAS_RELEASED : 4|1@0+ (1,0) [0|1] "" XXX + SG_ CRUISE_ACTIVE : 5|1@0+ (1,0) [0|1] "" XXX SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX +BO_ 467 PCM_CRUISE_2: 8 XXX + SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX + SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX + SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + BO_ 552 ACCELEROMETER: 8 XXX SG_ ACCEL_Z : 22|15@0- (1,0) [0|32767] "" XXX SG_ ACCEL_X : 6|15@0- (0.001,0) [-20|20] "m/s2" XXX @@ -134,23 +146,10 @@ BO_ 835 ACC_CONTROL: 8 DSU SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX -BO_ 1556 STEERING_LEVERS: 8 XXX - SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX - -BO_ 37 STEER_ANGLE_SENSOR: 8 XXX - SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX - SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX - SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX - -BO_ 467 PCM_CRUISE_2: 8 XXX - SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX - SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX - SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - 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_ UI_SET_SPEED : 31|8@0+ (1,0) [0|255] "" XXX BO_ 951 ESP_CONTROL: 8 ESP @@ -181,6 +180,9 @@ BO_ 1042 LKAS_HUD: 8 XXX BO_ 1553 UI_SEETING: 8 XXX SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX + +BO_ 1556 STEERING_LEVERS: 8 XXX + SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX BO_ 1568 SEATS_DOORS: 8 XXX SG_ SEATBELT_DRIVER_UNLATCHED : 62|1@0+ (1,0) [0|1] "" XXX @@ -192,33 +194,96 @@ BO_ 1568 SEATS_DOORS: 8 XXX BO_ 1570 LIGHT_STALK: 8 SCM SG_ AUTO_HIGH_BEAM : 37|1@0+ (1,0) [0|1] "" XXX +BO_ 1161 RSA1: 8 FCM + SG_ TSGN1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY1 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT1 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL1 : 23|8@0+ (1,0) [0|0] "kph" XXX + SG_ SPLSGN1 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN2 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN2 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY2 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT2 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL2 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_P : 63|2@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_A : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID1 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1162 RSA2: 8 FCM + SG_ TSGN3 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY3 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT3 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN3 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN4 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN4 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY4 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT4 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ DPSGNREQ : 54|1@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMP : 53|3@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMA : 50|3@0+ (1,0) [0|0] "" XXX + SG_ SPDUNT : 63|2@0+ (1,0) [0|0] "" XXX + SG_ TSRWMSG : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID2 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1163 RSA3: 8 FCM + SG_ TSREQPD : 7|1@0+ (1,0) [0|0] "" XXX + SG_ TSRMSW : 6|1@0+ (1,0) [0|0] "" XXX + SG_ OTSGNNTM : 5|2@0+ (1,0) [0|0] "" XXX + SG_ NTLVLSPD : 3|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPNTM : 1|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPVALL : 11|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALM : 19|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALH : 27|4@0+ (1,-5) [0|0] "" XXX + SG_ TSRSPU : 33|2@0+ (1,0) [0|0] "" XXX + CM_ SG_ 36 ACCEL_Y "unit is tbd"; CM_ SG_ 36 YAW_RATE "verify"; CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd"; +CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; +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_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt 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?"; -CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; -CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; -CM_ SG_ 37 STEER_RATE "factor is tbd"; -CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect"; -CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph"; CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; +CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; CM_ SG_ 1042 REPEATED_BEEPS "recommended for fcw and other important alerts"; -VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off" ; -VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok" ; +CM_ SG_ 1161 SPDVAL1 "Numbers 0-199 is displayed, 200-254 displays circle without number and 255 is for no limit."; +CM_ SG_ 1161 SYNCID1 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1161 SPDVAL2 "conditional speed value 70" +CM_ SG_ 1162 SGNNUMP "1 if SPDVAL1 is set, otherwise 0"; +CM_ SG_ 1162 SYNCID2 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1163 TSREQPD "always 1"; +CM_ SG_ 1163 TSRMSW "always 1"; +CM_ SG_ 1163 OTSGNNTM "always 3"; +CM_ SG_ 1163 NTLVLSPD "always 3"; +CM_ SG_ 1163 OVSPNTM "always 3"; +CM_ SG_ 1163 OVSPVALL "-5 at start then 2 after 2 seconds"; +CM_ SG_ 1163 OVSPVALM "-5 at start then 5 after 2 seconds"; +CM_ SG_ 1163 OVSPVALH "-5 at start then 10 after 2 seconds"; +CM_ SG_ 1163 TSRSPU "always 1"; + +VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; +VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; VAL_ 614 STATE 3 "enabled" 1 "disabled"; VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; -VAL_ 1553 UNITS 1 "km" 2 "miles"; -VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left" ; +VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; VAL_ 1042 RIGHT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; VAL_ 1042 LEFT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; -VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; +VAL_ 1553 UNITS 1 "km" 2 "miles"; +VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; +VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; +VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 65 "no overtake" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional" 0 "none"; + CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; diff --git a/toyota_highlander_hybrid_2018_pt_generated.dbc b/toyota_highlander_hybrid_2018_pt_generated.dbc index d852eba64..f69d6629c 100644 --- a/toyota_highlander_hybrid_2018_pt_generated.dbc +++ b/toyota_highlander_hybrid_2018_pt_generated.dbc @@ -72,6 +72,11 @@ BO_ 36 KINEMATICS: 8 XXX SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX +BO_ 37 STEER_ANGLE_SENSOR: 8 XXX + SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX + SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX + SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX + BO_ 166 BRAKE: 8 XXX SG_ BRAKE_AMOUNT : 7|8@0+ (1,0) [0|255] "" XXX SG_ BRAKE_PEDAL : 23|8@0+ (1,0) [0|255] "" XXX @@ -89,11 +94,18 @@ BO_ 180 SPEED: 8 XXX BO_ 466 PCM_CRUISE: 8 XXX SG_ GAS_RELEASED : 4|1@0+ (1,0) [0|1] "" XXX + SG_ CRUISE_ACTIVE : 5|1@0+ (1,0) [0|1] "" XXX SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX +BO_ 467 PCM_CRUISE_2: 8 XXX + SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX + SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX + SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + BO_ 552 ACCELEROMETER: 8 XXX SG_ ACCEL_Z : 22|15@0- (1,0) [0|32767] "" XXX SG_ ACCEL_X : 6|15@0- (0.001,0) [-20|20] "m/s2" XXX @@ -134,23 +146,10 @@ BO_ 835 ACC_CONTROL: 8 DSU SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX -BO_ 1556 STEERING_LEVERS: 8 XXX - SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX - -BO_ 37 STEER_ANGLE_SENSOR: 8 XXX - SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX - SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX - SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX - -BO_ 467 PCM_CRUISE_2: 8 XXX - SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX - SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX - SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - 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_ UI_SET_SPEED : 31|8@0+ (1,0) [0|255] "" XXX BO_ 951 ESP_CONTROL: 8 ESP @@ -181,6 +180,9 @@ BO_ 1042 LKAS_HUD: 8 XXX BO_ 1553 UI_SEETING: 8 XXX SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX + +BO_ 1556 STEERING_LEVERS: 8 XXX + SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX BO_ 1568 SEATS_DOORS: 8 XXX SG_ SEATBELT_DRIVER_UNLATCHED : 62|1@0+ (1,0) [0|1] "" XXX @@ -192,33 +194,96 @@ BO_ 1568 SEATS_DOORS: 8 XXX BO_ 1570 LIGHT_STALK: 8 SCM SG_ AUTO_HIGH_BEAM : 37|1@0+ (1,0) [0|1] "" XXX +BO_ 1161 RSA1: 8 FCM + SG_ TSGN1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY1 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT1 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL1 : 23|8@0+ (1,0) [0|0] "kph" XXX + SG_ SPLSGN1 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN2 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN2 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY2 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT2 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL2 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_P : 63|2@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_A : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID1 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1162 RSA2: 8 FCM + SG_ TSGN3 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY3 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT3 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN3 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN4 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN4 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY4 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT4 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ DPSGNREQ : 54|1@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMP : 53|3@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMA : 50|3@0+ (1,0) [0|0] "" XXX + SG_ SPDUNT : 63|2@0+ (1,0) [0|0] "" XXX + SG_ TSRWMSG : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID2 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1163 RSA3: 8 FCM + SG_ TSREQPD : 7|1@0+ (1,0) [0|0] "" XXX + SG_ TSRMSW : 6|1@0+ (1,0) [0|0] "" XXX + SG_ OTSGNNTM : 5|2@0+ (1,0) [0|0] "" XXX + SG_ NTLVLSPD : 3|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPNTM : 1|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPVALL : 11|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALM : 19|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALH : 27|4@0+ (1,-5) [0|0] "" XXX + SG_ TSRSPU : 33|2@0+ (1,0) [0|0] "" XXX + CM_ SG_ 36 ACCEL_Y "unit is tbd"; CM_ SG_ 36 YAW_RATE "verify"; CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd"; +CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; +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_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt 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?"; -CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; -CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; -CM_ SG_ 37 STEER_RATE "factor is tbd"; -CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect"; -CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph"; CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; +CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; CM_ SG_ 1042 REPEATED_BEEPS "recommended for fcw and other important alerts"; -VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off" ; -VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok" ; +CM_ SG_ 1161 SPDVAL1 "Numbers 0-199 is displayed, 200-254 displays circle without number and 255 is for no limit."; +CM_ SG_ 1161 SYNCID1 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1161 SPDVAL2 "conditional speed value 70" +CM_ SG_ 1162 SGNNUMP "1 if SPDVAL1 is set, otherwise 0"; +CM_ SG_ 1162 SYNCID2 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1163 TSREQPD "always 1"; +CM_ SG_ 1163 TSRMSW "always 1"; +CM_ SG_ 1163 OTSGNNTM "always 3"; +CM_ SG_ 1163 NTLVLSPD "always 3"; +CM_ SG_ 1163 OVSPNTM "always 3"; +CM_ SG_ 1163 OVSPVALL "-5 at start then 2 after 2 seconds"; +CM_ SG_ 1163 OVSPVALM "-5 at start then 5 after 2 seconds"; +CM_ SG_ 1163 OVSPVALH "-5 at start then 10 after 2 seconds"; +CM_ SG_ 1163 TSRSPU "always 1"; + +VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; +VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; VAL_ 614 STATE 3 "enabled" 1 "disabled"; VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; -VAL_ 1553 UNITS 1 "km" 2 "miles"; -VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left" ; +VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; VAL_ 1042 RIGHT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; VAL_ 1042 LEFT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; -VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; +VAL_ 1553 UNITS 1 "km" 2 "miles"; +VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; +VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; +VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 65 "no overtake" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional" 0 "none"; + CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; diff --git a/toyota_prius_2010_pt.dbc b/toyota_prius_2010_pt.dbc new file mode 100644 index 000000000..5dba51958 --- /dev/null +++ b/toyota_prius_2010_pt.dbc @@ -0,0 +1,203 @@ +VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + VAL_TABLE_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BS_: + +BU_: XXX DSU HCU EPS IPAS + + +BO_ 36 KINEMATICS: 8 XXX + SG_ ACCEL_Y : 33|10@0+ (1,-512) [0|65535] "" XXX + SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX + SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX + +BO_ 166 BRAKE: 8 XXX + SG_ BRAKE_AMOUNT : 7|8@0+ (1,0) [0|255] "" XXX + SG_ BRAKE_PEDAL : 23|8@0+ (1,0) [0|255] "" XXX + +BO_ 170 WHEEL_SPEEDS: 8 XXX + SG_ WHEEL_SPEED_FR : 7|16@0+ (0.0062,-67.67) [0|250] "mph" XXX + SG_ WHEEL_SPEED_FL : 23|16@0+ (0.0062,-67.67) [0|250] "mph" XXX + SG_ WHEEL_SPEED_RR : 39|16@0+ (0.0062,-67.67) [0|250] "mph" XXX + SG_ WHEEL_SPEED_RL : 55|16@0+ (0.0062,-67.67) [0|250] "mph" XXX + +BO_ 180 SPEED: 8 XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + SG_ SPEED : 47|16@0+ (0.0062,0) [0|115] "mph" XXX + SG_ ENCODER : 39|8@0+ (1,0) [0|255] "" XXX + +BO_ 295 GEAR_PACKET: 8 XXX + SG_ CAR_MOVEMENT : 39|8@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 + +BO_ 466 PCM_CRUISE: 8 XXX + SG_ GAS_RELEASED : 4|1@0+ (1,0) [0|1] "" XXX + SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX + SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 550 BRAKE_MODULE: 8 XXX + SG_ BRAKE_PRESSURE : 0|9@0+ (1,0) [0|511] "" XXX + SG_ BRAKE_POSITION : 16|9@0+ (1,0) [0|511] "" XXX + SG_ BRAKE_PRESSED : 37|1@0+ (1,0) [0|1] "" XXX + +BO_ 552 ACCELEROMETER: 8 XXX + SG_ ACCEL_Z : 22|15@0- (1,0) [0|32767] "" XXX + SG_ ACCEL_X : 6|15@0- (0.001,0) [-20|20] "m/s2" XXX + +BO_ 560 BRAKE_MODULE2: 8 XXX + SG_ BRAKE_LIGHTS : 26|1@0+ (1,0) [0|1] "" XXX + +BO_ 581 GAS_PEDAL: 8 XXX + SG_ GAS_PEDAL : 23|8@0+ (0.005,0) [0|1] "" XXX + +BO_ 608 STEER_TORQUE_SENSOR: 8 XXX + SG_ STEER_TORQUE_EPS : 47|16@0- (0.66,0) [-20000|20000] "" XXX + SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX + SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 610 EPS_STATUS: 5 EPS + SG_ STATE : 3|4@0+ (1,0) [0|15] "" XXX + SG_ LKA_STATE : 31|8@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 39|8@0+ (1,0) [0|255] "" XXX + +BO_ 614 STEERING_IPAS: 8 IPAS + SG_ STATE : 7|4@0+ (1,0) [0|15] "" XXX + SG_ ANGLE : 3|12@0- (1,0) [0|16777215] "" XXX + SG_ SET_ME_X10 : 23|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 643 PRE_COLLISION: 8 XXX + +BO_ 740 STEERING_LKA: 8 XXX + SG_ LKA_STATE : 31|8@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 39|8@0+ (1,0) [0|255] "" XXX + SG_ STEER_REQUEST : 0|1@0+ (1,0) [0|1] "" XXX + SG_ COUNTER : 6|6@0+ (1,0) [0|63] "" XXX + SG_ SET_ME_1 : 7|1@0+ (1,0) [0|1] "" XXX + SG_ STEER_TORQUE_CMD : 15|16@0- (1,0) [0|65535] "" XXX + +BO_ 742 LEAD_INFO: 8 DSU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" HCU + SG_ LEAD_REL_SPEED : 23|12@0- (0.025,0) [-100|100] "m/s" HCU + SG_ LEAD_LONG_DIST : 7|13@0+ (0.05,0) [0|300] "m" HCU + +BO_ 835 ACC_CONTROL: 8 DSU + SG_ ACCEL_CMD : 7|16@0- (0.001,0) [-20|20] "m/s2" HCU + +BO_ 1556 STEERING_LEVERS: 8 XXX + SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX + +BO_ 37 STEER_ANGLE_SENSOR: 8 XXX + SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX + SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX + SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX + +BO_ 467 PCM_CRUISE_2: 8 XXX + SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX + SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX + SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +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_ UI_SET_SPEED : 31|8@0+ (1,0) [0|255] "" XXX + +BO_ 951 ESP_CONTROL: 8 ESP + SG_ TC_DISABLED : 13|1@0+ (1,0) [0|1] "" XXX + +BO_ 1042 LKAS_HUD: 8 XXX + SG_ BARRIERS : 1|2@0+ (1,0) [0|3] "" XXX + SG_ RIGHT_LINE : 3|2@0+ (1,0) [0|3] "" XXX + SG_ LEFT_LINE : 5|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_1 : 7|2@0+ (1,0) [0|3] "" XXX + SG_ LDA_ALERT : 9|2@0+ (1,0) [0|3] "" XXX + SG_ TWO_BEEPS : 12|1@0+ (1,0) [0|1] "" XXX + SG_ ADJUSTING_CAMERA : 13|1@0+ (1,0) [0|1] "" XXX + SG_ LDA_MALFUNCTION : 15|1@0+ (1,0) [0|1] "" XXX + +BO_ 1553 UI_SEETING: 8 XXX + SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX + +BO_ 1568 SEATS_DOORS: 8 XXX + SG_ SEATBELT_DRIVER_UNLATCHED : 62|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_FL : 45|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_RL : 42|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_RR : 43|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_FR : 44|1@0+ (1,0) [0|1] "" XXX + +BO_ 452 POWERTRAIN: 8 XXX + SG_ ENGINE_RPM : 7|16@0+ (1,0) [0|65535] "rpm" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + + + + +CM_ SG_ 36 ACCEL_Y "unit is tbd"; +CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd"; +CM_ SG_ 36 YAW_RATE "verify"; +CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors"; +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_ 560 BRAKE_LIGHTS "double check"; +CM_ SG_ 581 GAS_PEDAL "it seems slightly filtered"; +CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; +CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; +CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; +CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; +CM_ SG_ 37 STEER_RATE "factor is tbd"; +CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph"; +CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect"; +CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; +CM_ SG_ 1042 SET_ME_1 "unclear what this is, nut it's always 1 in drive traces"; +VAL_ 295 GEAR 0 "P" 1 "R" 2 "N" 3 "D" 4 "B" ; +VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off" ; +VAL_ 610 STATE 5 "override" 3 "enabled" 1 "disabled" ; +VAL_ 610 LKA_STATE 50 "temporary_fault" ; +VAL_ 614 STATE 3 "enabled" 1 "disabled" ; +VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left" ; +VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left" ; +VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok" ; +VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted" ; +VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none" ; +VAL_ 1042 RIGHT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none" ; +VAL_ 1042 LEFT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none" ; +VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none" ; +VAL_ 1553 UNITS 1 "km" 2 "miles" ; +CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; diff --git a/toyota_prius_2017_pt_generated.dbc b/toyota_prius_2017_pt_generated.dbc index a3f14954b..73de10d50 100644 --- a/toyota_prius_2017_pt_generated.dbc +++ b/toyota_prius_2017_pt_generated.dbc @@ -72,6 +72,11 @@ BO_ 36 KINEMATICS: 8 XXX SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX +BO_ 37 STEER_ANGLE_SENSOR: 8 XXX + SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX + SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX + SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX + BO_ 166 BRAKE: 8 XXX SG_ BRAKE_AMOUNT : 7|8@0+ (1,0) [0|255] "" XXX SG_ BRAKE_PEDAL : 23|8@0+ (1,0) [0|255] "" XXX @@ -89,11 +94,18 @@ BO_ 180 SPEED: 8 XXX BO_ 466 PCM_CRUISE: 8 XXX SG_ GAS_RELEASED : 4|1@0+ (1,0) [0|1] "" XXX + SG_ CRUISE_ACTIVE : 5|1@0+ (1,0) [0|1] "" XXX SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX +BO_ 467 PCM_CRUISE_2: 8 XXX + SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX + SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX + SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + BO_ 552 ACCELEROMETER: 8 XXX SG_ ACCEL_Z : 22|15@0- (1,0) [0|32767] "" XXX SG_ ACCEL_X : 6|15@0- (0.001,0) [-20|20] "m/s2" XXX @@ -134,23 +146,10 @@ BO_ 835 ACC_CONTROL: 8 DSU SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX -BO_ 1556 STEERING_LEVERS: 8 XXX - SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX - -BO_ 37 STEER_ANGLE_SENSOR: 8 XXX - SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX - SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX - SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX - -BO_ 467 PCM_CRUISE_2: 8 XXX - SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX - SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX - SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - 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_ UI_SET_SPEED : 31|8@0+ (1,0) [0|255] "" XXX BO_ 951 ESP_CONTROL: 8 ESP @@ -181,6 +180,9 @@ BO_ 1042 LKAS_HUD: 8 XXX BO_ 1553 UI_SEETING: 8 XXX SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX + +BO_ 1556 STEERING_LEVERS: 8 XXX + SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX BO_ 1568 SEATS_DOORS: 8 XXX SG_ SEATBELT_DRIVER_UNLATCHED : 62|1@0+ (1,0) [0|1] "" XXX @@ -192,33 +194,96 @@ BO_ 1568 SEATS_DOORS: 8 XXX BO_ 1570 LIGHT_STALK: 8 SCM SG_ AUTO_HIGH_BEAM : 37|1@0+ (1,0) [0|1] "" XXX +BO_ 1161 RSA1: 8 FCM + SG_ TSGN1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY1 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT1 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL1 : 23|8@0+ (1,0) [0|0] "kph" XXX + SG_ SPLSGN1 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN2 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN2 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY2 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT2 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL2 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_P : 63|2@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_A : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID1 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1162 RSA2: 8 FCM + SG_ TSGN3 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY3 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT3 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN3 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN4 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN4 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY4 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT4 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ DPSGNREQ : 54|1@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMP : 53|3@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMA : 50|3@0+ (1,0) [0|0] "" XXX + SG_ SPDUNT : 63|2@0+ (1,0) [0|0] "" XXX + SG_ TSRWMSG : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID2 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1163 RSA3: 8 FCM + SG_ TSREQPD : 7|1@0+ (1,0) [0|0] "" XXX + SG_ TSRMSW : 6|1@0+ (1,0) [0|0] "" XXX + SG_ OTSGNNTM : 5|2@0+ (1,0) [0|0] "" XXX + SG_ NTLVLSPD : 3|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPNTM : 1|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPVALL : 11|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALM : 19|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALH : 27|4@0+ (1,-5) [0|0] "" XXX + SG_ TSRSPU : 33|2@0+ (1,0) [0|0] "" XXX + CM_ SG_ 36 ACCEL_Y "unit is tbd"; CM_ SG_ 36 YAW_RATE "verify"; CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd"; +CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; +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_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt 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?"; -CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; -CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; -CM_ SG_ 37 STEER_RATE "factor is tbd"; -CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect"; -CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph"; CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; +CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; CM_ SG_ 1042 REPEATED_BEEPS "recommended for fcw and other important alerts"; -VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off" ; -VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok" ; +CM_ SG_ 1161 SPDVAL1 "Numbers 0-199 is displayed, 200-254 displays circle without number and 255 is for no limit."; +CM_ SG_ 1161 SYNCID1 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1161 SPDVAL2 "conditional speed value 70" +CM_ SG_ 1162 SGNNUMP "1 if SPDVAL1 is set, otherwise 0"; +CM_ SG_ 1162 SYNCID2 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1163 TSREQPD "always 1"; +CM_ SG_ 1163 TSRMSW "always 1"; +CM_ SG_ 1163 OTSGNNTM "always 3"; +CM_ SG_ 1163 NTLVLSPD "always 3"; +CM_ SG_ 1163 OVSPNTM "always 3"; +CM_ SG_ 1163 OVSPVALL "-5 at start then 2 after 2 seconds"; +CM_ SG_ 1163 OVSPVALM "-5 at start then 5 after 2 seconds"; +CM_ SG_ 1163 OVSPVALH "-5 at start then 10 after 2 seconds"; +CM_ SG_ 1163 TSRSPU "always 1"; + +VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; +VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; VAL_ 614 STATE 3 "enabled" 1 "disabled"; VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; -VAL_ 1553 UNITS 1 "km" 2 "miles"; -VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left" ; +VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; VAL_ 1042 RIGHT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; VAL_ 1042 LEFT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; -VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; +VAL_ 1553 UNITS 1 "km" 2 "miles"; +VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; +VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; +VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 65 "no overtake" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional" 0 "none"; + CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; diff --git a/toyota_rav4_2017_pt_generated.dbc b/toyota_rav4_2017_pt_generated.dbc index 9e086c792..a63c5351f 100644 --- a/toyota_rav4_2017_pt_generated.dbc +++ b/toyota_rav4_2017_pt_generated.dbc @@ -72,6 +72,11 @@ BO_ 36 KINEMATICS: 8 XXX SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX +BO_ 37 STEER_ANGLE_SENSOR: 8 XXX + SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX + SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX + SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX + BO_ 166 BRAKE: 8 XXX SG_ BRAKE_AMOUNT : 7|8@0+ (1,0) [0|255] "" XXX SG_ BRAKE_PEDAL : 23|8@0+ (1,0) [0|255] "" XXX @@ -89,11 +94,18 @@ BO_ 180 SPEED: 8 XXX BO_ 466 PCM_CRUISE: 8 XXX SG_ GAS_RELEASED : 4|1@0+ (1,0) [0|1] "" XXX + SG_ CRUISE_ACTIVE : 5|1@0+ (1,0) [0|1] "" XXX SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX +BO_ 467 PCM_CRUISE_2: 8 XXX + SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX + SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX + SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + BO_ 552 ACCELEROMETER: 8 XXX SG_ ACCEL_Z : 22|15@0- (1,0) [0|32767] "" XXX SG_ ACCEL_X : 6|15@0- (0.001,0) [-20|20] "m/s2" XXX @@ -134,23 +146,10 @@ BO_ 835 ACC_CONTROL: 8 DSU SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX -BO_ 1556 STEERING_LEVERS: 8 XXX - SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX - -BO_ 37 STEER_ANGLE_SENSOR: 8 XXX - SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX - SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX - SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX - -BO_ 467 PCM_CRUISE_2: 8 XXX - SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX - SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX - SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - 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_ UI_SET_SPEED : 31|8@0+ (1,0) [0|255] "" XXX BO_ 951 ESP_CONTROL: 8 ESP @@ -181,6 +180,9 @@ BO_ 1042 LKAS_HUD: 8 XXX BO_ 1553 UI_SEETING: 8 XXX SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX + +BO_ 1556 STEERING_LEVERS: 8 XXX + SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX BO_ 1568 SEATS_DOORS: 8 XXX SG_ SEATBELT_DRIVER_UNLATCHED : 62|1@0+ (1,0) [0|1] "" XXX @@ -192,33 +194,96 @@ BO_ 1568 SEATS_DOORS: 8 XXX BO_ 1570 LIGHT_STALK: 8 SCM SG_ AUTO_HIGH_BEAM : 37|1@0+ (1,0) [0|1] "" XXX +BO_ 1161 RSA1: 8 FCM + SG_ TSGN1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY1 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT1 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL1 : 23|8@0+ (1,0) [0|0] "kph" XXX + SG_ SPLSGN1 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN2 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN2 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY2 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT2 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL2 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_P : 63|2@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_A : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID1 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1162 RSA2: 8 FCM + SG_ TSGN3 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY3 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT3 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN3 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN4 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN4 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY4 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT4 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ DPSGNREQ : 54|1@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMP : 53|3@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMA : 50|3@0+ (1,0) [0|0] "" XXX + SG_ SPDUNT : 63|2@0+ (1,0) [0|0] "" XXX + SG_ TSRWMSG : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID2 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1163 RSA3: 8 FCM + SG_ TSREQPD : 7|1@0+ (1,0) [0|0] "" XXX + SG_ TSRMSW : 6|1@0+ (1,0) [0|0] "" XXX + SG_ OTSGNNTM : 5|2@0+ (1,0) [0|0] "" XXX + SG_ NTLVLSPD : 3|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPNTM : 1|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPVALL : 11|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALM : 19|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALH : 27|4@0+ (1,-5) [0|0] "" XXX + SG_ TSRSPU : 33|2@0+ (1,0) [0|0] "" XXX + CM_ SG_ 36 ACCEL_Y "unit is tbd"; CM_ SG_ 36 YAW_RATE "verify"; CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd"; +CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; +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_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt 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?"; -CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; -CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; -CM_ SG_ 37 STEER_RATE "factor is tbd"; -CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect"; -CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph"; CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; +CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; CM_ SG_ 1042 REPEATED_BEEPS "recommended for fcw and other important alerts"; -VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off" ; -VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok" ; +CM_ SG_ 1161 SPDVAL1 "Numbers 0-199 is displayed, 200-254 displays circle without number and 255 is for no limit."; +CM_ SG_ 1161 SYNCID1 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1161 SPDVAL2 "conditional speed value 70" +CM_ SG_ 1162 SGNNUMP "1 if SPDVAL1 is set, otherwise 0"; +CM_ SG_ 1162 SYNCID2 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1163 TSREQPD "always 1"; +CM_ SG_ 1163 TSRMSW "always 1"; +CM_ SG_ 1163 OTSGNNTM "always 3"; +CM_ SG_ 1163 NTLVLSPD "always 3"; +CM_ SG_ 1163 OVSPNTM "always 3"; +CM_ SG_ 1163 OVSPVALL "-5 at start then 2 after 2 seconds"; +CM_ SG_ 1163 OVSPVALM "-5 at start then 5 after 2 seconds"; +CM_ SG_ 1163 OVSPVALH "-5 at start then 10 after 2 seconds"; +CM_ SG_ 1163 TSRSPU "always 1"; + +VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; +VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; VAL_ 614 STATE 3 "enabled" 1 "disabled"; VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; -VAL_ 1553 UNITS 1 "km" 2 "miles"; -VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left" ; +VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; VAL_ 1042 RIGHT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; VAL_ 1042 LEFT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; -VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; +VAL_ 1553 UNITS 1 "km" 2 "miles"; +VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; +VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; +VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 65 "no overtake" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional" 0 "none"; + CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; diff --git a/toyota_rav4_hybrid_2017_pt_generated.dbc b/toyota_rav4_hybrid_2017_pt_generated.dbc index a5dbe4fa6..2d3825d03 100644 --- a/toyota_rav4_hybrid_2017_pt_generated.dbc +++ b/toyota_rav4_hybrid_2017_pt_generated.dbc @@ -72,6 +72,11 @@ BO_ 36 KINEMATICS: 8 XXX SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX +BO_ 37 STEER_ANGLE_SENSOR: 8 XXX + SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX + SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX + SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX + BO_ 166 BRAKE: 8 XXX SG_ BRAKE_AMOUNT : 7|8@0+ (1,0) [0|255] "" XXX SG_ BRAKE_PEDAL : 23|8@0+ (1,0) [0|255] "" XXX @@ -89,11 +94,18 @@ BO_ 180 SPEED: 8 XXX BO_ 466 PCM_CRUISE: 8 XXX SG_ GAS_RELEASED : 4|1@0+ (1,0) [0|1] "" XXX + SG_ CRUISE_ACTIVE : 5|1@0+ (1,0) [0|1] "" XXX SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX +BO_ 467 PCM_CRUISE_2: 8 XXX + SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX + SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX + SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + BO_ 552 ACCELEROMETER: 8 XXX SG_ ACCEL_Z : 22|15@0- (1,0) [0|32767] "" XXX SG_ ACCEL_X : 6|15@0- (0.001,0) [-20|20] "m/s2" XXX @@ -134,23 +146,10 @@ BO_ 835 ACC_CONTROL: 8 DSU SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX -BO_ 1556 STEERING_LEVERS: 8 XXX - SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX - -BO_ 37 STEER_ANGLE_SENSOR: 8 XXX - SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX - SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX - SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX - -BO_ 467 PCM_CRUISE_2: 8 XXX - SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX - SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX - SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - 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_ UI_SET_SPEED : 31|8@0+ (1,0) [0|255] "" XXX BO_ 951 ESP_CONTROL: 8 ESP @@ -181,6 +180,9 @@ BO_ 1042 LKAS_HUD: 8 XXX BO_ 1553 UI_SEETING: 8 XXX SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX + +BO_ 1556 STEERING_LEVERS: 8 XXX + SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX BO_ 1568 SEATS_DOORS: 8 XXX SG_ SEATBELT_DRIVER_UNLATCHED : 62|1@0+ (1,0) [0|1] "" XXX @@ -192,33 +194,96 @@ BO_ 1568 SEATS_DOORS: 8 XXX BO_ 1570 LIGHT_STALK: 8 SCM SG_ AUTO_HIGH_BEAM : 37|1@0+ (1,0) [0|1] "" XXX +BO_ 1161 RSA1: 8 FCM + SG_ TSGN1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY1 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT1 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL1 : 23|8@0+ (1,0) [0|0] "kph" XXX + SG_ SPLSGN1 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN2 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN2 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY2 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT2 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL2 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_P : 63|2@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_A : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID1 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1162 RSA2: 8 FCM + SG_ TSGN3 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY3 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT3 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN3 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN4 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN4 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY4 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT4 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ DPSGNREQ : 54|1@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMP : 53|3@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMA : 50|3@0+ (1,0) [0|0] "" XXX + SG_ SPDUNT : 63|2@0+ (1,0) [0|0] "" XXX + SG_ TSRWMSG : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID2 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1163 RSA3: 8 FCM + SG_ TSREQPD : 7|1@0+ (1,0) [0|0] "" XXX + SG_ TSRMSW : 6|1@0+ (1,0) [0|0] "" XXX + SG_ OTSGNNTM : 5|2@0+ (1,0) [0|0] "" XXX + SG_ NTLVLSPD : 3|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPNTM : 1|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPVALL : 11|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALM : 19|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALH : 27|4@0+ (1,-5) [0|0] "" XXX + SG_ TSRSPU : 33|2@0+ (1,0) [0|0] "" XXX + CM_ SG_ 36 ACCEL_Y "unit is tbd"; CM_ SG_ 36 YAW_RATE "verify"; CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd"; +CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; +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_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt 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?"; -CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; -CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; -CM_ SG_ 37 STEER_RATE "factor is tbd"; -CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect"; -CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph"; CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; +CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; CM_ SG_ 1042 REPEATED_BEEPS "recommended for fcw and other important alerts"; -VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off" ; -VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok" ; +CM_ SG_ 1161 SPDVAL1 "Numbers 0-199 is displayed, 200-254 displays circle without number and 255 is for no limit."; +CM_ SG_ 1161 SYNCID1 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1161 SPDVAL2 "conditional speed value 70" +CM_ SG_ 1162 SGNNUMP "1 if SPDVAL1 is set, otherwise 0"; +CM_ SG_ 1162 SYNCID2 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1163 TSREQPD "always 1"; +CM_ SG_ 1163 TSRMSW "always 1"; +CM_ SG_ 1163 OTSGNNTM "always 3"; +CM_ SG_ 1163 NTLVLSPD "always 3"; +CM_ SG_ 1163 OVSPNTM "always 3"; +CM_ SG_ 1163 OVSPVALL "-5 at start then 2 after 2 seconds"; +CM_ SG_ 1163 OVSPVALM "-5 at start then 5 after 2 seconds"; +CM_ SG_ 1163 OVSPVALH "-5 at start then 10 after 2 seconds"; +CM_ SG_ 1163 TSRSPU "always 1"; + +VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; +VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; VAL_ 614 STATE 3 "enabled" 1 "disabled"; VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; -VAL_ 1553 UNITS 1 "km" 2 "miles"; -VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left" ; +VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; VAL_ 1042 RIGHT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; VAL_ 1042 LEFT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; -VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; +VAL_ 1553 UNITS 1 "km" 2 "miles"; +VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; +VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; +VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 65 "no overtake" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional" 0 "none"; + CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; From efa97f23a53f5279b2239b8ee6f427d08c860e92 Mon Sep 17 00:00:00 2001 From: Vehicle Researcher Date: Sat, 17 Nov 2018 01:58:38 -0800 Subject: [PATCH 3/5] Squashed 'pyextra/' changes from eb09257..fb152de fb152de add overpy git-subtree-dir: pyextra git-subtree-split: fb152de1e9e54247d933400be1dbf580f4dd0f43 --- overpy-0.4-py2.7.egg-info/PKG-INFO | 123 ++ overpy-0.4-py2.7.egg-info/SOURCES.txt | 61 + .../dependency_links.txt | 1 + overpy-0.4-py2.7.egg-info/installed-files.txt | 56 + overpy-0.4-py2.7.egg-info/not-zip-safe | 1 + overpy-0.4-py2.7.egg-info/top_level.txt | 2 + overpy/__about__.py | 22 + overpy/__init__.py | 1536 +++++++++++++++++ overpy/exception.py | 108 ++ overpy/helper.py | 64 + 10 files changed, 1974 insertions(+) create mode 100644 overpy-0.4-py2.7.egg-info/PKG-INFO create mode 100644 overpy-0.4-py2.7.egg-info/SOURCES.txt create mode 100644 overpy-0.4-py2.7.egg-info/dependency_links.txt create mode 100644 overpy-0.4-py2.7.egg-info/installed-files.txt create mode 100644 overpy-0.4-py2.7.egg-info/not-zip-safe create mode 100644 overpy-0.4-py2.7.egg-info/top_level.txt create mode 100644 overpy/__about__.py create mode 100644 overpy/__init__.py create mode 100644 overpy/exception.py create mode 100644 overpy/helper.py diff --git a/overpy-0.4-py2.7.egg-info/PKG-INFO b/overpy-0.4-py2.7.egg-info/PKG-INFO new file mode 100644 index 000000000..96d494a14 --- /dev/null +++ b/overpy-0.4-py2.7.egg-info/PKG-INFO @@ -0,0 +1,123 @@ +Metadata-Version: 1.1 +Name: overpy +Version: 0.4 +Summary: Python Wrapper to access the OpenStreepMap Overpass API +Home-page: https://github.com/DinoTools/python-overpy +Author: PhiBo (DinoTools) +Author-email: UNKNOWN +License: MIT +Description: Python Overpass Wrapper + ======================= + + A Python Wrapper to access the Overpass API. + + Have a look at the `documentation`_ to find additional information. + + .. image:: https://pypip.in/version/overpy/badge.svg + :target: https://pypi.python.org/pypi/overpy/ + :alt: Latest Version + + .. image:: https://pypip.in/license/overpy/badge.svg + :target: https://pypi.python.org/pypi/overpy/ + :alt: License + + .. image:: https://travis-ci.org/DinoTools/python-overpy.svg?branch=master + :target: https://travis-ci.org/DinoTools/python-overpy + + .. image:: https://coveralls.io/repos/DinoTools/python-overpy/badge.png?branch=master + :target: https://coveralls.io/r/DinoTools/python-overpy?branch=master + + Features + -------- + + * Query Overpass API + * Parse JSON and XML response data + * Additional helper functions + + Install + ------- + + **Requirements:** + + Supported Python versions: + + * Python 2.7 + * Python >= 3.2 + * PyPy and PyPy3 + + **Install:** + + .. code-block:: console + + $ pip install overpy + + Examples + -------- + + Additional examples can be found in the `documentation`_ and in the *examples* directory. + + .. code-block:: python + + import overpy + + api = overpy.Overpass() + + # fetch all ways and nodes + result = api.query(""" + way(50.746,7.154,50.748,7.157) ["highway"]; + (._;>;); + out body; + """) + + for way in result.ways: + print("Name: %s" % way.tags.get("name", "n/a")) + print(" Highway: %s" % way.tags.get("highway", "n/a")) + print(" Nodes:") + for node in way.nodes: + print(" Lat: %f, Lon: %f" % (node.lat, node.lon)) + + + Helper + ~~~~~~ + + Helper methods are available to provide easy access to often used requests. + + .. code-block:: python + + import overpy.helper + + # 3600062594 is the OSM id of Chemnitz and is the bounding box for the request + street = overpy.helper.get_street( + "Straße der Nationen", + "3600062594" + ) + + # this finds an intersection between Straße der Nationen and Carolastraße in Chemnitz + intersection = overpy.helper.get_intersection( + "Straße der Nationen", + "Carolastraße", + "3600062594" + ) + + + License + ------- + + Published under the MIT (see LICENSE for more information) + + .. _`documentation`: http://python-overpy.readthedocs.org/ + +Keywords: OverPy Overpass OSM OpenStreetMap +Platform: UNKNOWN +Classifier: Development Status :: 4 - Beta +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.2 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy diff --git a/overpy-0.4-py2.7.egg-info/SOURCES.txt b/overpy-0.4-py2.7.egg-info/SOURCES.txt new file mode 100644 index 000000000..66bf17f7c --- /dev/null +++ b/overpy-0.4-py2.7.egg-info/SOURCES.txt @@ -0,0 +1,61 @@ +CHANGELOG.rst +LICENSE +MANIFEST.in +README.rst +setup.cfg +setup.py +docs/make.bat +docs/source/api.rst +docs/source/changelog.rst +docs/source/conf.py +docs/source/contributing.rst +docs/source/example.rst +docs/source/index.rst +docs/source/introduction.rst +examples/get_areas.py +examples/get_nodes.py +examples/get_ways.py +overpy/__about__.py +overpy/__init__.py +overpy/exception.py +overpy/helper.py +overpy.egg-info/PKG-INFO +overpy.egg-info/SOURCES.txt +overpy.egg-info/dependency_links.txt +overpy.egg-info/not-zip-safe +overpy.egg-info/top_level.txt +tests/__init__.py +tests/base_class.py +tests/test_exception.py +tests/test_json.py +tests/test_request.py +tests/test_result.py +tests/test_result_way.py +tests/test_xml.py +tests/json/area-01.json +tests/json/node-01.json +tests/json/relation-01.json +tests/json/relation-02.json +tests/json/relation-03.json +tests/json/relation-04.json +tests/json/result-expand-01.json +tests/json/result-expand-02.json +tests/json/result-way-01.json +tests/json/result-way-02.json +tests/json/result-way-03.json +tests/json/way-01.json +tests/json/way-02.json +tests/json/way-03.json +tests/json/way-04.json +tests/response/bad-request-encoding.html +tests/response/bad-request.html +tests/xml/area-01.xml +tests/xml/node-01.xml +tests/xml/relation-01.xml +tests/xml/relation-02.xml +tests/xml/relation-03.xml +tests/xml/relation-04.xml +tests/xml/way-01.xml +tests/xml/way-02.xml +tests/xml/way-03.xml +tests/xml/way-04.xml \ No newline at end of file diff --git a/overpy-0.4-py2.7.egg-info/dependency_links.txt b/overpy-0.4-py2.7.egg-info/dependency_links.txt new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/overpy-0.4-py2.7.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/overpy-0.4-py2.7.egg-info/installed-files.txt b/overpy-0.4-py2.7.egg-info/installed-files.txt new file mode 100644 index 000000000..0cd05ada1 --- /dev/null +++ b/overpy-0.4-py2.7.egg-info/installed-files.txt @@ -0,0 +1,56 @@ +../overpy/__about__.py +../overpy/__about__.pyc +../overpy/__init__.py +../overpy/__init__.pyc +../overpy/exception.py +../overpy/exception.pyc +../overpy/helper.py +../overpy/helper.pyc +../tests/__init__.py +../tests/__init__.pyc +../tests/base_class.py +../tests/base_class.pyc +../tests/json/area-01.json +../tests/json/node-01.json +../tests/json/relation-01.json +../tests/json/relation-02.json +../tests/json/relation-03.json +../tests/json/relation-04.json +../tests/json/result-expand-01.json +../tests/json/result-expand-02.json +../tests/json/result-way-01.json +../tests/json/result-way-02.json +../tests/json/result-way-03.json +../tests/json/way-01.json +../tests/json/way-02.json +../tests/json/way-03.json +../tests/json/way-04.json +../tests/response/bad-request-encoding.html +../tests/response/bad-request.html +../tests/test_exception.py +../tests/test_exception.pyc +../tests/test_json.py +../tests/test_json.pyc +../tests/test_request.py +../tests/test_request.pyc +../tests/test_result.py +../tests/test_result.pyc +../tests/test_result_way.py +../tests/test_result_way.pyc +../tests/test_xml.py +../tests/test_xml.pyc +../tests/xml/area-01.xml +../tests/xml/node-01.xml +../tests/xml/relation-01.xml +../tests/xml/relation-02.xml +../tests/xml/relation-03.xml +../tests/xml/relation-04.xml +../tests/xml/way-01.xml +../tests/xml/way-02.xml +../tests/xml/way-03.xml +../tests/xml/way-04.xml +PKG-INFO +SOURCES.txt +dependency_links.txt +not-zip-safe +top_level.txt diff --git a/overpy-0.4-py2.7.egg-info/not-zip-safe b/overpy-0.4-py2.7.egg-info/not-zip-safe new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/overpy-0.4-py2.7.egg-info/not-zip-safe @@ -0,0 +1 @@ + diff --git a/overpy-0.4-py2.7.egg-info/top_level.txt b/overpy-0.4-py2.7.egg-info/top_level.txt new file mode 100644 index 000000000..4611d9bb6 --- /dev/null +++ b/overpy-0.4-py2.7.egg-info/top_level.txt @@ -0,0 +1,2 @@ +overpy +tests diff --git a/overpy/__about__.py b/overpy/__about__.py new file mode 100644 index 000000000..33c6c493c --- /dev/null +++ b/overpy/__about__.py @@ -0,0 +1,22 @@ +__all__ = [ + "__author__", + "__copyright__", + "__email__", + "__license__", + "__summary__", + "__title__", + "__uri__", + "__version__", +] + +__title__ = "overpy" +__summary__ = "Python Wrapper to access the OpenStreepMap Overpass API" +__uri__ = "https://github.com/DinoTools/python-overpy" + +__version__ = "0.4" + +__author__ = "PhiBo (DinoTools)" +__email__ = "" + +__license__ = "MIT" +__copyright__ = "Copyright 2014-2016 %s" % __author__ diff --git a/overpy/__init__.py b/overpy/__init__.py new file mode 100644 index 000000000..8e038bda9 --- /dev/null +++ b/overpy/__init__.py @@ -0,0 +1,1536 @@ +from collections import OrderedDict +from datetime import datetime +from decimal import Decimal +from xml.sax import handler, make_parser +import json +import re +import sys + +from overpy import exception +from overpy.__about__ import ( + __author__, __copyright__, __email__, __license__, __summary__, __title__, + __uri__, __version__ +) + +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 + +XML_PARSER_DOM = 1 +XML_PARSER_SAX = 2 + +if PY2: + from urllib2 import urlopen + from urllib2 import HTTPError +elif PY3: + from urllib.request import urlopen + from urllib.error import HTTPError + + +def is_valid_type(element, cls): + """ + Test if an element is of a given type. + + :param Element() element: The element instance to test + :param Element cls: The element class to test + :return: False or True + :rtype: Boolean + """ + return isinstance(element, cls) and element.id is not None + + +class Overpass(object): + """ + Class to access the Overpass API + """ + default_read_chunk_size = 4096 + default_url = "http://overpass-api.de/api/interpreter" + + def __init__(self, read_chunk_size=None, url=None, xml_parser=XML_PARSER_SAX): + """ + :param read_chunk_size: Max size of each chunk read from the server response + :type read_chunk_size: Integer + :param url: Optional URL of the Overpass server. Defaults to http://overpass-api.de/api/interpreter + :type url: str + :param xml_parser: The xml parser to use + :type xml_parser: Integer + """ + self.url = self.default_url + if url is not None: + self.url = url + + self._regex_extract_error_msg = re.compile(b"\(?P\") + self._regex_remove_tag = re.compile(b"<[^>]*?>") + if read_chunk_size is None: + read_chunk_size = self.default_read_chunk_size + self.read_chunk_size = read_chunk_size + self.xml_parser = xml_parser + + def query(self, query): + """ + Query the Overpass API + + :param String|Bytes query: The query string in Overpass QL + :return: The parsed result + :rtype: overpy.Result + """ + if not isinstance(query, bytes): + query = query.encode("utf-8") + + try: + f = urlopen(self.url, query) + except HTTPError as e: + f = e + + response = f.read(self.read_chunk_size) + while True: + data = f.read(self.read_chunk_size) + if len(data) == 0: + break + response = response + data + f.close() + + if f.code == 200: + if PY2: + http_info = f.info() + content_type = http_info.getheader("content-type") + else: + content_type = f.getheader("Content-Type") + + if content_type == "application/json": + return self.parse_json(response) + + if content_type == "application/osm3s+xml": + return self.parse_xml(response) + + raise exception.OverpassUnknownContentType(content_type) + + if f.code == 400: + msgs = [] + for msg in self._regex_extract_error_msg.finditer(response): + tmp = self._regex_remove_tag.sub(b"", msg.group("msg")) + try: + tmp = tmp.decode("utf-8") + except UnicodeDecodeError: + tmp = repr(tmp) + msgs.append(tmp) + + raise exception.OverpassBadRequest( + query, + msgs=msgs + ) + + if f.code == 429: + raise exception.OverpassTooManyRequests + + if f.code == 504: + raise exception.OverpassGatewayTimeout + + raise exception.OverpassUnknownHTTPStatusCode(f.code) + + def parse_json(self, data, encoding="utf-8"): + """ + Parse raw response from Overpass service. + + :param data: Raw JSON Data + :type data: String or Bytes + :param encoding: Encoding to decode byte string + :type encoding: String + :return: Result object + :rtype: overpy.Result + """ + if isinstance(data, bytes): + data = data.decode(encoding) + data = json.loads(data, parse_float=Decimal) + return Result.from_json(data, api=self) + + def parse_xml(self, data, encoding="utf-8", parser=None): + """ + + :param data: Raw XML Data + :type data: String or Bytes + :param encoding: Encoding to decode byte string + :type encoding: String + :return: Result object + :rtype: overpy.Result + """ + if parser is None: + parser = self.xml_parser + + if isinstance(data, bytes): + data = data.decode(encoding) + if PY2 and not isinstance(data, str): + # Python 2.x: Convert unicode strings + data = data.encode(encoding) + + return Result.from_xml(data, api=self, parser=parser) + + +class Result(object): + """ + Class to handle the result. + """ + + def __init__(self, elements=None, api=None): + """ + + :param List elements: + :param api: + :type api: overpy.Overpass + """ + if elements is None: + elements = [] + self._areas = OrderedDict((element.id, element) for element in elements if is_valid_type(element, Area)) + self._nodes = OrderedDict((element.id, element) for element in elements if is_valid_type(element, Node)) + self._ways = OrderedDict((element.id, element) for element in elements if is_valid_type(element, Way)) + self._relations = OrderedDict((element.id, element) + for element in elements if is_valid_type(element, Relation)) + self._class_collection_map = {Node: self._nodes, Way: self._ways, Relation: self._relations, Area: self._areas} + self.api = api + + def expand(self, other): + """ + Add all elements from an other result to the list of elements of this result object. + + It is used by the auto resolve feature. + + :param other: Expand the result with the elements from this result. + :type other: overpy.Result + :raises ValueError: If provided parameter is not instance of :class:`overpy.Result` + """ + if not isinstance(other, Result): + raise ValueError("Provided argument has to be instance of overpy:Result()") + + other_collection_map = {Node: other.nodes, Way: other.ways, Relation: other.relations, Area: other.areas} + for element_type, own_collection in self._class_collection_map.items(): + for element in other_collection_map[element_type]: + if is_valid_type(element, element_type) and element.id not in own_collection: + own_collection[element.id] = element + + def append(self, element): + """ + Append a new element to the result. + + :param element: The element to append + :type element: overpy.Element + """ + if is_valid_type(element, Element): + self._class_collection_map[element.__class__].setdefault(element.id, element) + + def get_elements(self, filter_cls, elem_id=None): + """ + Get a list of elements from the result and filter the element type by a class. + + :param filter_cls: + :param elem_id: ID of the object + :type elem_id: Integer + :return: List of available elements + :rtype: List + """ + result = [] + if elem_id is not None: + try: + result = [self._class_collection_map[filter_cls][elem_id]] + except KeyError: + result = [] + else: + for e in self._class_collection_map[filter_cls].values(): + result.append(e) + return result + + def get_ids(self, filter_cls): + """ + + :param filter_cls: + :return: + """ + return list(self._class_collection_map[filter_cls].keys()) + + def get_node_ids(self): + return self.get_ids(filter_cls=Node) + + def get_way_ids(self): + return self.get_ids(filter_cls=Way) + + def get_relation_ids(self): + return self.get_ids(filter_cls=Relation) + + def get_area_ids(self): + return self.get_ids(filter_cls=Area) + + @classmethod + def from_json(cls, data, api=None): + """ + Create a new instance and load data from json object. + + :param data: JSON data returned by the Overpass API + :type data: Dict + :param api: + :type api: overpy.Overpass + :return: New instance of Result object + :rtype: overpy.Result + """ + result = cls(api=api) + for elem_cls in [Node, Way, Relation, Area]: + for element in data.get("elements", []): + e_type = element.get("type") + if hasattr(e_type, "lower") and e_type.lower() == elem_cls._type_value: + result.append(elem_cls.from_json(element, result=result)) + + return result + + @classmethod + def from_xml(cls, data, api=None, parser=XML_PARSER_SAX): + """ + Create a new instance and load data from xml object. + + :param data: Root element + :type data: xml.etree.ElementTree.Element + :param api: + :type api: Overpass + :param parser: Specify the parser to use(DOM or SAX) + :type parser: Integer + :return: New instance of Result object + :rtype: Result + """ + result = cls(api=api) + if parser == XML_PARSER_DOM: + import xml.etree.ElementTree as ET + root = ET.fromstring(data) + + for elem_cls in [Node, Way, Relation, Area]: + for child in root: + if child.tag.lower() == elem_cls._type_value: + result.append(elem_cls.from_xml(child, result=result)) + + elif parser == XML_PARSER_SAX: + if PY2: + from StringIO import StringIO + else: + from io import StringIO + source = StringIO(data) + sax_handler = OSMSAXHandler(result) + parser = make_parser() + parser.setContentHandler(sax_handler) + parser.parse(source) + else: + # ToDo: better exception + raise Exception("Unknown XML parser") + return result + + def get_area(self, area_id, resolve_missing=False): + """ + Get an area by its ID. + + :param area_id: The area ID + :type area_id: Integer + :param resolve_missing: Query the Overpass API if the area is missing in the result set. + :return: The area + :rtype: overpy.Area + :raises overpy.exception.DataIncomplete: The requested way is not available in the result cache. + :raises overpy.exception.DataIncomplete: If resolve_missing is True and the area can't be resolved. + """ + areas = self.get_areas(area_id=area_id) + if len(areas) == 0: + if resolve_missing is False: + raise exception.DataIncomplete("Resolve missing area is disabled") + + query = ("\n" + "[out:json];\n" + "area({area_id});\n" + "out body;\n" + ) + query = query.format( + area_id=area_id + ) + tmp_result = self.api.query(query) + self.expand(tmp_result) + + areas = self.get_areas(area_id=area_id) + + if len(areas) == 0: + raise exception.DataIncomplete("Unable to resolve requested areas") + + return areas[0] + + def get_areas(self, area_id=None, **kwargs): + """ + Alias for get_elements() but filter the result by Area + + :param area_id: The Id of the area + :type area_id: Integer + :return: List of elements + """ + return self.get_elements(Area, elem_id=area_id, **kwargs) + + def get_node(self, node_id, resolve_missing=False): + """ + Get a node by its ID. + + :param node_id: The node ID + :type node_id: Integer + :param resolve_missing: Query the Overpass API if the node is missing in the result set. + :return: The node + :rtype: overpy.Node + :raises overpy.exception.DataIncomplete: At least one referenced node is not available in the result cache. + :raises overpy.exception.DataIncomplete: If resolve_missing is True and at least one node can't be resolved. + """ + nodes = self.get_nodes(node_id=node_id) + if len(nodes) == 0: + if not resolve_missing: + raise exception.DataIncomplete("Resolve missing nodes is disabled") + + query = ("\n" + "[out:json];\n" + "node({node_id});\n" + "out body;\n" + ) + query = query.format( + node_id=node_id + ) + tmp_result = self.api.query(query) + self.expand(tmp_result) + + nodes = self.get_nodes(node_id=node_id) + + if len(nodes) == 0: + raise exception.DataIncomplete("Unable to resolve all nodes") + + return nodes[0] + + def get_nodes(self, node_id=None, **kwargs): + """ + Alias for get_elements() but filter the result by Node() + + :param node_id: The Id of the node + :type node_id: Integer + :return: List of elements + """ + return self.get_elements(Node, elem_id=node_id, **kwargs) + + def get_relation(self, rel_id, resolve_missing=False): + """ + Get a relation by its ID. + + :param rel_id: The relation ID + :type rel_id: Integer + :param resolve_missing: Query the Overpass API if the relation is missing in the result set. + :return: The relation + :rtype: overpy.Relation + :raises overpy.exception.DataIncomplete: The requested relation is not available in the result cache. + :raises overpy.exception.DataIncomplete: If resolve_missing is True and the relation can't be resolved. + """ + relations = self.get_relations(rel_id=rel_id) + if len(relations) == 0: + if resolve_missing is False: + raise exception.DataIncomplete("Resolve missing relations is disabled") + + query = ("\n" + "[out:json];\n" + "relation({relation_id});\n" + "out body;\n" + ) + query = query.format( + relation_id=rel_id + ) + tmp_result = self.api.query(query) + self.expand(tmp_result) + + relations = self.get_relations(rel_id=rel_id) + + if len(relations) == 0: + raise exception.DataIncomplete("Unable to resolve requested reference") + + return relations[0] + + def get_relations(self, rel_id=None, **kwargs): + """ + Alias for get_elements() but filter the result by Relation + + :param rel_id: Id of the relation + :type rel_id: Integer + :return: List of elements + """ + return self.get_elements(Relation, elem_id=rel_id, **kwargs) + + def get_way(self, way_id, resolve_missing=False): + """ + Get a way by its ID. + + :param way_id: The way ID + :type way_id: Integer + :param resolve_missing: Query the Overpass API if the way is missing in the result set. + :return: The way + :rtype: overpy.Way + :raises overpy.exception.DataIncomplete: The requested way is not available in the result cache. + :raises overpy.exception.DataIncomplete: If resolve_missing is True and the way can't be resolved. + """ + ways = self.get_ways(way_id=way_id) + if len(ways) == 0: + if resolve_missing is False: + raise exception.DataIncomplete("Resolve missing way is disabled") + + query = ("\n" + "[out:json];\n" + "way({way_id});\n" + "out body;\n" + ) + query = query.format( + way_id=way_id + ) + tmp_result = self.api.query(query) + self.expand(tmp_result) + + ways = self.get_ways(way_id=way_id) + + if len(ways) == 0: + raise exception.DataIncomplete("Unable to resolve requested way") + + return ways[0] + + def get_ways(self, way_id=None, **kwargs): + """ + Alias for get_elements() but filter the result by Way + + :param way_id: The Id of the way + :type way_id: Integer + :return: List of elements + """ + return self.get_elements(Way, elem_id=way_id, **kwargs) + + area_ids = property(get_area_ids) + areas = property(get_areas) + node_ids = property(get_node_ids) + nodes = property(get_nodes) + relation_ids = property(get_relation_ids) + relations = property(get_relations) + way_ids = property(get_way_ids) + ways = property(get_ways) + + +class Element(object): + """ + Base element + """ + + def __init__(self, attributes=None, result=None, tags=None): + """ + :param attributes: Additional attributes + :type attributes: Dict + :param result: The result object this element belongs to + :param tags: List of tags + :type tags: Dict + """ + + self._result = result + # Try to convert some common attributes + # http://wiki.openstreetmap.org/wiki/Elements#Common_attributes + self._attribute_modifiers = { + "changeset": int, + "timestamp": lambda ts: datetime.strptime(ts, "%Y-%m-%dT%H:%M:%SZ"), + "uid": int, + "version": int, + "visible": lambda v: v.lower() == "true" + } + self.attributes = attributes + for n, m in self._attribute_modifiers.items(): + if n in self.attributes: + self.attributes[n] = m(self.attributes[n]) + self.id = None + self.tags = tags + + @classmethod + def get_center_from_json(cls, data): + """ + Get center information from json data + + :param data: json data + :return: tuple with two elements: lat and lon + :rtype: tuple + """ + center_lat = None + center_lon = None + center = data.get("center") + if isinstance(center, dict): + center_lat = center.get("lat") + center_lon = center.get("lon") + if center_lat is None or center_lon is None: + raise ValueError("Unable to get lat or lon of way center.") + center_lat = Decimal(center_lat) + center_lon = Decimal(center_lon) + return (center_lat, center_lon) + + @classmethod + def get_center_from_xml_dom(cls, sub_child): + center_lat = sub_child.attrib.get("lat") + center_lon = sub_child.attrib.get("lon") + if center_lat is None or center_lon is None: + raise ValueError("Unable to get lat or lon of way center.") + center_lat = Decimal(center_lat) + center_lon = Decimal(center_lon) + return center_lat, center_lon + + +class Area(Element): + """ + Class to represent an element of type area + """ + + _type_value = "area" + + def __init__(self, area_id=None, **kwargs): + """ + :param area_id: Id of the area element + :type area_id: Integer + :param kwargs: Additional arguments are passed directly to the parent class + + """ + + Element.__init__(self, **kwargs) + #: The id of the way + self.id = area_id + + def __repr__(self): + return "".format(self.id) + + @classmethod + def from_json(cls, data, result=None): + """ + Create new Area element from JSON data + + :param data: Element data from JSON + :type data: Dict + :param result: The result this element belongs to + :type result: overpy.Result + :return: New instance of Way + :rtype: overpy.Area + :raises overpy.exception.ElementDataWrongType: If type value of the passed JSON data does not match. + """ + if data.get("type") != cls._type_value: + raise exception.ElementDataWrongType( + type_expected=cls._type_value, + type_provided=data.get("type") + ) + + tags = data.get("tags", {}) + + area_id = data.get("id") + + attributes = {} + ignore = ["id", "tags", "type"] + for n, v in data.items(): + if n in ignore: + continue + attributes[n] = v + + return cls(area_id=area_id, attributes=attributes, tags=tags, result=result) + + @classmethod + def from_xml(cls, child, result=None): + """ + Create new way element from XML data + + :param child: XML node to be parsed + :type child: xml.etree.ElementTree.Element + :param result: The result this node belongs to + :type result: overpy.Result + :return: New Way oject + :rtype: overpy.Way + :raises overpy.exception.ElementDataWrongType: If name of the xml child node doesn't match + :raises ValueError: If the ref attribute of the xml node is not provided + :raises ValueError: If a tag doesn't have a name + """ + if child.tag.lower() != cls._type_value: + raise exception.ElementDataWrongType( + type_expected=cls._type_value, + type_provided=child.tag.lower() + ) + + tags = {} + + for sub_child in child: + if sub_child.tag.lower() == "tag": + name = sub_child.attrib.get("k") + if name is None: + raise ValueError("Tag without name/key.") + value = sub_child.attrib.get("v") + tags[name] = value + + area_id = child.attrib.get("id") + if area_id is not None: + area_id = int(area_id) + + attributes = {} + ignore = ["id"] + for n, v in child.attrib.items(): + if n in ignore: + continue + attributes[n] = v + + return cls(area_id=area_id, attributes=attributes, tags=tags, result=result) + + +class Node(Element): + """ + Class to represent an element of type node + """ + + _type_value = "node" + + def __init__(self, node_id=None, lat=None, lon=None, **kwargs): + """ + :param lat: Latitude + :type lat: Decimal or Float + :param lon: Longitude + :type long: Decimal or Float + :param node_id: Id of the node element + :type node_id: Integer + :param kwargs: Additional arguments are passed directly to the parent class + """ + + Element.__init__(self, **kwargs) + self.id = node_id + self.lat = lat + self.lon = lon + + def __repr__(self): + return "".format(self.id, self.lat, self.lon) + + @classmethod + def from_json(cls, data, result=None): + """ + Create new Node element from JSON data + + :param data: Element data from JSON + :type data: Dict + :param result: The result this element belongs to + :type result: overpy.Result + :return: New instance of Node + :rtype: overpy.Node + :raises overpy.exception.ElementDataWrongType: If type value of the passed JSON data does not match. + """ + if data.get("type") != cls._type_value: + raise exception.ElementDataWrongType( + type_expected=cls._type_value, + type_provided=data.get("type") + ) + + tags = data.get("tags", {}) + + node_id = data.get("id") + lat = data.get("lat") + lon = data.get("lon") + + attributes = {} + ignore = ["type", "id", "lat", "lon", "tags"] + for n, v in data.items(): + if n in ignore: + continue + attributes[n] = v + + return cls(node_id=node_id, lat=lat, lon=lon, tags=tags, attributes=attributes, result=result) + + @classmethod + def from_xml(cls, child, result=None): + """ + Create new way element from XML data + + :param child: XML node to be parsed + :type child: xml.etree.ElementTree.Element + :param result: The result this node belongs to + :type result: overpy.Result + :return: New Way oject + :rtype: overpy.Node + :raises overpy.exception.ElementDataWrongType: If name of the xml child node doesn't match + :raises ValueError: If a tag doesn't have a name + """ + if child.tag.lower() != cls._type_value: + raise exception.ElementDataWrongType( + type_expected=cls._type_value, + type_provided=child.tag.lower() + ) + + tags = {} + + for sub_child in child: + if sub_child.tag.lower() == "tag": + name = sub_child.attrib.get("k") + if name is None: + raise ValueError("Tag without name/key.") + value = sub_child.attrib.get("v") + tags[name] = value + + node_id = child.attrib.get("id") + if node_id is not None: + node_id = int(node_id) + lat = child.attrib.get("lat") + if lat is not None: + lat = Decimal(lat) + lon = child.attrib.get("lon") + if lon is not None: + lon = Decimal(lon) + + attributes = {} + ignore = ["id", "lat", "lon"] + for n, v in child.attrib.items(): + if n in ignore: + continue + attributes[n] = v + + return cls(node_id=node_id, lat=lat, lon=lon, tags=tags, attributes=attributes, result=result) + + +class Way(Element): + """ + Class to represent an element of type way + """ + + _type_value = "way" + + def __init__(self, way_id=None, center_lat=None, center_lon=None, node_ids=None, **kwargs): + """ + :param node_ids: List of node IDs + :type node_ids: List or Tuple + :param way_id: Id of the way element + :type way_id: Integer + :param kwargs: Additional arguments are passed directly to the parent class + + """ + + Element.__init__(self, **kwargs) + #: The id of the way + self.id = way_id + + #: List of Ids of the associated nodes + self._node_ids = node_ids + + #: The lat/lon of the center of the way (optional depending on query) + self.center_lat = center_lat + self.center_lon = center_lon + + def __repr__(self): + return "".format(self.id, self._node_ids) + + @property + def nodes(self): + """ + List of nodes associated with the way. + """ + return self.get_nodes() + + def get_nodes(self, resolve_missing=False): + """ + Get the nodes defining the geometry of the way + + :param resolve_missing: Try to resolve missing nodes. + :type resolve_missing: Boolean + :return: List of nodes + :rtype: List of overpy.Node + :raises overpy.exception.DataIncomplete: At least one referenced node is not available in the result cache. + :raises overpy.exception.DataIncomplete: If resolve_missing is True and at least one node can't be resolved. + """ + result = [] + resolved = False + + for node_id in self._node_ids: + try: + node = self._result.get_node(node_id) + except exception.DataIncomplete: + node = None + + if node is not None: + result.append(node) + continue + + if not resolve_missing: + raise exception.DataIncomplete("Resolve missing nodes is disabled") + + # We tried to resolve the data but some nodes are still missing + if resolved: + raise exception.DataIncomplete("Unable to resolve all nodes") + + query = ("\n" + "[out:json];\n" + "way({way_id});\n" + "node(w);\n" + "out body;\n" + ) + query = query.format( + way_id=self.id + ) + tmp_result = self._result.api.query(query) + self._result.expand(tmp_result) + resolved = True + + try: + node = self._result.get_node(node_id) + except exception.DataIncomplete: + node = None + + if node is None: + raise exception.DataIncomplete("Unable to resolve all nodes") + + result.append(node) + + return result + + @classmethod + def from_json(cls, data, result=None): + """ + Create new Way element from JSON data + + :param data: Element data from JSON + :type data: Dict + :param result: The result this element belongs to + :type result: overpy.Result + :return: New instance of Way + :rtype: overpy.Way + :raises overpy.exception.ElementDataWrongType: If type value of the passed JSON data does not match. + """ + if data.get("type") != cls._type_value: + raise exception.ElementDataWrongType( + type_expected=cls._type_value, + type_provided=data.get("type") + ) + + tags = data.get("tags", {}) + + way_id = data.get("id") + node_ids = data.get("nodes") + (center_lat, center_lon) = cls.get_center_from_json(data=data) + + attributes = {} + ignore = ["center", "id", "nodes", "tags", "type"] + for n, v in data.items(): + if n in ignore: + continue + attributes[n] = v + + return cls( + attributes=attributes, + center_lat=center_lat, + center_lon=center_lon, + node_ids=node_ids, + tags=tags, + result=result, + way_id=way_id + ) + + @classmethod + def from_xml(cls, child, result=None): + """ + Create new way element from XML data + + :param child: XML node to be parsed + :type child: xml.etree.ElementTree.Element + :param result: The result this node belongs to + :type result: overpy.Result + :return: New Way oject + :rtype: overpy.Way + :raises overpy.exception.ElementDataWrongType: If name of the xml child node doesn't match + :raises ValueError: If the ref attribute of the xml node is not provided + :raises ValueError: If a tag doesn't have a name + """ + if child.tag.lower() != cls._type_value: + raise exception.ElementDataWrongType( + type_expected=cls._type_value, + type_provided=child.tag.lower() + ) + + tags = {} + node_ids = [] + center_lat = None + center_lon = None + + for sub_child in child: + if sub_child.tag.lower() == "tag": + name = sub_child.attrib.get("k") + if name is None: + raise ValueError("Tag without name/key.") + value = sub_child.attrib.get("v") + tags[name] = value + if sub_child.tag.lower() == "nd": + ref_id = sub_child.attrib.get("ref") + if ref_id is None: + raise ValueError("Unable to find required ref value.") + ref_id = int(ref_id) + node_ids.append(ref_id) + if sub_child.tag.lower() == "center": + (center_lat, center_lon) = cls.get_center_from_xml_dom(sub_child=sub_child) + + way_id = child.attrib.get("id") + if way_id is not None: + way_id = int(way_id) + + attributes = {} + ignore = ["id"] + for n, v in child.attrib.items(): + if n in ignore: + continue + attributes[n] = v + + return cls(way_id=way_id, center_lat=center_lat, center_lon=center_lon, + attributes=attributes, node_ids=node_ids, tags=tags, result=result) + + +class Relation(Element): + """ + Class to represent an element of type relation + """ + + _type_value = "relation" + + def __init__(self, rel_id=None, center_lat=None, center_lon=None, members=None, **kwargs): + """ + :param members: + :param rel_id: Id of the relation element + :type rel_id: Integer + :param kwargs: + :return: + """ + + Element.__init__(self, **kwargs) + self.id = rel_id + self.members = members + + #: The lat/lon of the center of the way (optional depending on query) + self.center_lat = center_lat + self.center_lon = center_lon + + def __repr__(self): + return "".format(self.id) + + @classmethod + def from_json(cls, data, result=None): + """ + Create new Relation element from JSON data + + :param data: Element data from JSON + :type data: Dict + :param result: The result this element belongs to + :type result: overpy.Result + :return: New instance of Relation + :rtype: overpy.Relation + :raises overpy.exception.ElementDataWrongType: If type value of the passed JSON data does not match. + """ + if data.get("type") != cls._type_value: + raise exception.ElementDataWrongType( + type_expected=cls._type_value, + type_provided=data.get("type") + ) + + tags = data.get("tags", {}) + + rel_id = data.get("id") + (center_lat, center_lon) = cls.get_center_from_json(data=data) + + members = [] + + supported_members = [RelationNode, RelationWay, RelationRelation] + for member in data.get("members", []): + type_value = member.get("type") + for member_cls in supported_members: + if member_cls._type_value == type_value: + members.append( + member_cls.from_json( + member, + result=result + ) + ) + + attributes = {} + ignore = ["id", "members", "tags", "type"] + for n, v in data.items(): + if n in ignore: + continue + attributes[n] = v + + return cls( + rel_id=rel_id, + attributes=attributes, + center_lat=center_lat, + center_lon=center_lon, + members=members, + tags=tags, + result=result + ) + + @classmethod + def from_xml(cls, child, result=None): + """ + Create new way element from XML data + + :param child: XML node to be parsed + :type child: xml.etree.ElementTree.Element + :param result: The result this node belongs to + :type result: overpy.Result + :return: New Way oject + :rtype: overpy.Relation + :raises overpy.exception.ElementDataWrongType: If name of the xml child node doesn't match + :raises ValueError: If a tag doesn't have a name + """ + if child.tag.lower() != cls._type_value: + raise exception.ElementDataWrongType( + type_expected=cls._type_value, + type_provided=child.tag.lower() + ) + + tags = {} + members = [] + center_lat = None + center_lon = None + + supported_members = [RelationNode, RelationWay, RelationRelation, RelationArea] + for sub_child in child: + if sub_child.tag.lower() == "tag": + name = sub_child.attrib.get("k") + if name is None: + raise ValueError("Tag without name/key.") + value = sub_child.attrib.get("v") + tags[name] = value + if sub_child.tag.lower() == "member": + type_value = sub_child.attrib.get("type") + for member_cls in supported_members: + if member_cls._type_value == type_value: + members.append( + member_cls.from_xml( + sub_child, + result=result + ) + ) + if sub_child.tag.lower() == "center": + (center_lat, center_lon) = cls.get_center_from_xml_dom(sub_child=sub_child) + + rel_id = child.attrib.get("id") + if rel_id is not None: + rel_id = int(rel_id) + + attributes = {} + ignore = ["id"] + for n, v in child.attrib.items(): + if n in ignore: + continue + attributes[n] = v + + return cls( + rel_id=rel_id, + attributes=attributes, + center_lat=center_lat, + center_lon=center_lon, + members=members, + tags=tags, + result=result + ) + + +class RelationMember(object): + """ + Base class to represent a member of a relation. + """ + + def __init__(self, attributes=None, geometry=None, ref=None, role=None, result=None): + """ + :param ref: Reference Id + :type ref: Integer + :param role: The role of the relation member + :type role: String + :param result: + """ + self.ref = ref + self._result = result + self.role = role + self.attributes = attributes + self.geometry = geometry + + @classmethod + def from_json(cls, data, result=None): + """ + Create new RelationMember element from JSON data + + :param child: Element data from JSON + :type child: Dict + :param result: The result this element belongs to + :type result: overpy.Result + :return: New instance of RelationMember + :rtype: overpy.RelationMember + :raises overpy.exception.ElementDataWrongType: If type value of the passed JSON data does not match. + """ + if data.get("type") != cls._type_value: + raise exception.ElementDataWrongType( + type_expected=cls._type_value, + type_provided=data.get("type") + ) + + ref = data.get("ref") + role = data.get("role") + + attributes = {} + ignore = ["geometry", "type", "ref", "role"] + for n, v in data.items(): + if n in ignore: + continue + attributes[n] = v + + geometry = data.get("geometry") + if isinstance(geometry, list): + geometry_orig = geometry + geometry = [] + for v in geometry_orig: + geometry.append( + RelationWayGeometryValue( + lat=v.get("lat"), + lon=v.get("lon") + ) + ) + else: + geometry = None + + return cls( + attributes=attributes, + geometry=geometry, + ref=ref, + role=role, + result=result + ) + + @classmethod + def from_xml(cls, child, result=None): + """ + Create new RelationMember from XML data + + :param child: XML node to be parsed + :type child: xml.etree.ElementTree.Element + :param result: The result this element belongs to + :type result: overpy.Result + :return: New relation member oject + :rtype: overpy.RelationMember + :raises overpy.exception.ElementDataWrongType: If name of the xml child node doesn't match + """ + if child.attrib.get("type") != cls._type_value: + raise exception.ElementDataWrongType( + type_expected=cls._type_value, + type_provided=child.tag.lower() + ) + + ref = child.attrib.get("ref") + if ref is not None: + ref = int(ref) + role = child.attrib.get("role") + + attributes = {} + ignore = ["geometry", "ref", "role", "type"] + for n, v in child.attrib.items(): + if n in ignore: + continue + attributes[n] = v + + geometry = None + for sub_child in child: + if sub_child.tag.lower() == "nd": + if geometry is None: + geometry = [] + geometry.append( + RelationWayGeometryValue( + lat=Decimal(sub_child.attrib["lat"]), + lon=Decimal(sub_child.attrib["lon"]) + ) + ) + + return cls( + attributes=attributes, + geometry=geometry, + ref=ref, + role=role, + result=result + ) + + +class RelationNode(RelationMember): + _type_value = "node" + + def resolve(self, resolve_missing=False): + return self._result.get_node(self.ref, resolve_missing=resolve_missing) + + def __repr__(self): + return "".format(self.ref, self.role) + + +class RelationWay(RelationMember): + _type_value = "way" + + def resolve(self, resolve_missing=False): + return self._result.get_way(self.ref, resolve_missing=resolve_missing) + + def __repr__(self): + return "".format(self.ref, self.role) + + +class RelationWayGeometryValue(object): + def __init__(self, lat, lon): + self.lat = lat + self.lon = lon + + def __repr__(self): + return "".format(self.lat, self.lon) + + +class RelationRelation(RelationMember): + _type_value = "relation" + + def resolve(self, resolve_missing=False): + return self._result.get_relation(self.ref, resolve_missing=resolve_missing) + + def __repr__(self): + return "".format(self.ref, self.role) + + +class RelationArea(RelationMember): + _type_value = "area" + + def resolve(self, resolve_missing=False): + return self._result.get_area(self.ref, resolve_missing=resolve_missing) + + def __repr__(self): + return "".format(self.ref, self.role) + + +class OSMSAXHandler(handler.ContentHandler): + """ + SAX parser for Overpass XML response. + """ + #: Tuple of opening elements to ignore + ignore_start = ('osm', 'meta', 'note', 'bounds', 'remark') + #: Tuple of closing elements to ignore + ignore_end = ('osm', 'meta', 'note', 'bounds', 'remark', 'tag', 'nd', 'center') + + def __init__(self, result): + """ + :param result: Append results to this result set. + :type result: overpy.Result + """ + handler.ContentHandler.__init__(self) + self._result = result + self._curr = {} + #: Current relation member object + self.cur_relation_member = None + + def startElement(self, name, attrs): + """ + Handle opening elements. + + :param name: Name of the element + :type name: String + :param attrs: Attributes of the element + :type attrs: Dict + """ + if name in self.ignore_start: + return + try: + handler = getattr(self, '_handle_start_%s' % name) + except AttributeError: + raise KeyError("Unknown element start '%s'" % name) + handler(attrs) + + def endElement(self, name): + """ + Handle closing elements + + :param name: Name of the element + :type name: String + """ + if name in self.ignore_end: + return + try: + handler = getattr(self, '_handle_end_%s' % name) + except AttributeError: + raise KeyError("Unknown element end '%s'" % name) + handler() + + def _handle_start_center(self, attrs): + """ + Handle opening center element + + :param attrs: Attributes of the element + :type attrs: Dict + """ + center_lat = attrs.get("lat") + center_lon = attrs.get("lon") + if center_lat is None or center_lon is None: + raise ValueError("Unable to get lat or lon of way center.") + self._curr["center_lat"] = Decimal(center_lat) + self._curr["center_lon"] = Decimal(center_lon) + + def _handle_start_tag(self, attrs): + """ + Handle opening tag element + + :param attrs: Attributes of the element + :type attrs: Dict + """ + try: + tag_key = attrs['k'] + except KeyError: + raise ValueError("Tag without name/key.") + self._curr['tags'][tag_key] = attrs.get('v') + + def _handle_start_node(self, attrs): + """ + Handle opening node element + + :param attrs: Attributes of the element + :type attrs: Dict + """ + self._curr = { + 'attributes': dict(attrs), + 'lat': None, + 'lon': None, + 'node_id': None, + 'tags': {} + } + if attrs.get('id', None) is not None: + self._curr['node_id'] = int(attrs['id']) + del self._curr['attributes']['id'] + if attrs.get('lat', None) is not None: + self._curr['lat'] = Decimal(attrs['lat']) + del self._curr['attributes']['lat'] + if attrs.get('lon', None) is not None: + self._curr['lon'] = Decimal(attrs['lon']) + del self._curr['attributes']['lon'] + + def _handle_end_node(self): + """ + Handle closing node element + """ + self._result.append(Node(result=self._result, **self._curr)) + self._curr = {} + + def _handle_start_way(self, attrs): + """ + Handle opening way element + + :param attrs: Attributes of the element + :type attrs: Dict + """ + self._curr = { + 'center_lat': None, + 'center_lon': None, + 'attributes': dict(attrs), + 'node_ids': [], + 'tags': {}, + 'way_id': None + } + if attrs.get('id', None) is not None: + self._curr['way_id'] = int(attrs['id']) + del self._curr['attributes']['id'] + + def _handle_end_way(self): + """ + Handle closing way element + """ + self._result.append(Way(result=self._result, **self._curr)) + self._curr = {} + + def _handle_start_area(self, attrs): + """ + Handle opening area element + + :param attrs: Attributes of the element + :type attrs: Dict + """ + self._curr = { + 'attributes': dict(attrs), + 'tags': {}, + 'area_id': None + } + if attrs.get('id', None) is not None: + self._curr['area_id'] = int(attrs['id']) + del self._curr['attributes']['id'] + + def _handle_end_area(self): + """ + Handle closing area element + """ + self._result.append(Area(result=self._result, **self._curr)) + self._curr = {} + + def _handle_start_nd(self, attrs): + """ + Handle opening nd element + + :param attrs: Attributes of the element + :type attrs: Dict + """ + if isinstance(self.cur_relation_member, RelationWay): + if self.cur_relation_member.geometry is None: + self.cur_relation_member.geometry = [] + self.cur_relation_member.geometry.append( + RelationWayGeometryValue( + lat=Decimal(attrs["lat"]), + lon=Decimal(attrs["lon"]) + ) + ) + else: + try: + node_ref = attrs['ref'] + except KeyError: + raise ValueError("Unable to find required ref value.") + self._curr['node_ids'].append(int(node_ref)) + + def _handle_start_relation(self, attrs): + """ + Handle opening relation element + + :param attrs: Attributes of the element + :type attrs: Dict + """ + self._curr = { + 'attributes': dict(attrs), + 'members': [], + 'rel_id': None, + 'tags': {} + } + if attrs.get('id', None) is not None: + self._curr['rel_id'] = int(attrs['id']) + del self._curr['attributes']['id'] + + def _handle_end_relation(self): + """ + Handle closing relation element + """ + self._result.append(Relation(result=self._result, **self._curr)) + self._curr = {} + + def _handle_start_member(self, attrs): + """ + Handle opening member element + + :param attrs: Attributes of the element + :type attrs: Dict + """ + + params = { + # ToDo: Parse attributes + 'attributes': {}, + 'ref': None, + 'result': self._result, + 'role': None + } + if attrs.get('ref', None): + params['ref'] = int(attrs['ref']) + if attrs.get('role', None): + params['role'] = attrs['role'] + + cls_map = { + "area": RelationArea, + "node": RelationNode, + "relation": RelationRelation, + "way": RelationWay + } + cls = cls_map.get(attrs["type"]) + if cls is None: + raise ValueError("Undefined type for member: '%s'" % attrs['type']) + + self.cur_relation_member = cls(**params) + self._curr['members'].append(self.cur_relation_member) + + def _handle_end_member(self): + self.cur_relation_member = None diff --git a/overpy/exception.py b/overpy/exception.py new file mode 100644 index 000000000..7179d246a --- /dev/null +++ b/overpy/exception.py @@ -0,0 +1,108 @@ +class OverPyException(BaseException): + """OverPy base exception""" + pass + + +class DataIncomplete(OverPyException): + """ + Raised if the requested data isn't available in the result. + Try to improve the query or to resolve the missing data. + """ + def __init__(self, *args, **kwargs): + OverPyException.__init__( + self, + "Data incomplete try to improve the query to resolve the missing data", + *args, + **kwargs + ) + + +class ElementDataWrongType(OverPyException): + """ + Raised if the provided element does not match the expected type. + + :param type_expected: The expected element type + :type type_expected: String + :param type_provided: The provided element type + :type type_provided: String|None + """ + def __init__(self, type_expected, type_provided=None): + self.type_expected = type_expected + self.type_provided = type_provided + + def __str__(self): + return "Type expected '%s' but '%s' provided" % ( + self.type_expected, + str(self.type_provided) + ) + + +class OverpassBadRequest(OverPyException): + """ + Raised if the Overpass API service returns a syntax error. + + :param query: The encoded query how it was send to the server + :type query: Bytes + :param msgs: List of error messages + :type msgs: List + """ + def __init__(self, query, msgs=None): + self.query = query + if msgs is None: + msgs = [] + self.msgs = msgs + + def __str__(self): + tmp_msgs = [] + for tmp_msg in self.msgs: + if not isinstance(tmp_msg, str): + tmp_msg = str(tmp_msg) + tmp_msgs.append(tmp_msg) + + return "\n".join(tmp_msgs) + + +class OverpassGatewayTimeout(OverPyException): + """ + Raised if load of the Overpass API service is too high and it can't handle the request. + """ + def __init__(self): + OverPyException.__init__(self, "Server load too high") + + +class OverpassTooManyRequests(OverPyException): + """ + Raised if the Overpass API service returns a 429 status code. + """ + def __init__(self): + OverPyException.__init__(self, "Too many requests") + + +class OverpassUnknownContentType(OverPyException): + """ + Raised if the reported content type isn't handled by OverPy. + + :param content_type: The reported content type + :type content_type: None or String + """ + def __init__(self, content_type): + self.content_type = content_type + + def __str__(self): + if self.content_type is None: + return "No content type returned" + return "Unknown content type: %s" % self.content_type + + +class OverpassUnknownHTTPStatusCode(OverPyException): + """ + Raised if the returned HTTP status code isn't handled by OverPy. + + :param code: The HTTP status code + :type code: Integer + """ + def __init__(self, code): + self.code = code + + def __str__(self): + return "Unknown/Unhandled status code: %d" % self.code \ No newline at end of file diff --git a/overpy/helper.py b/overpy/helper.py new file mode 100644 index 000000000..e3ac0170b --- /dev/null +++ b/overpy/helper.py @@ -0,0 +1,64 @@ +__author__ = 'mjob' + +import overpy + + +def get_street(street, areacode, api=None): + """ + Retrieve streets in a given bounding area + + :param overpy.Overpass api: First street of intersection + :param String street: Name of street + :param String areacode: The OSM id of the bounding area + :return: Parsed result + :raises overpy.exception.OverPyException: If something bad happens. + """ + if api is None: + api = overpy.Overpass() + + query = """ + area(%s)->.location; + ( + way[highway][name="%s"](area.location); + - ( + way[highway=service](area.location); + way[highway=track](area.location); + ); + ); + out body; + >; + out skel qt; + """ + + data = api.query(query % (areacode, street)) + + return data + + +def get_intersection(street1, street2, areacode, api=None): + """ + Retrieve intersection of two streets in a given bounding area + + :param overpy.Overpass api: First street of intersection + :param String street1: Name of first street of intersection + :param String street2: Name of second street of intersection + :param String areacode: The OSM id of the bounding area + :return: List of intersections + :raises overpy.exception.OverPyException: If something bad happens. + """ + if api is None: + api = overpy.Overpass() + + query = """ + area(%s)->.location; + ( + way[highway][name="%s"](area.location); node(w)->.n1; + way[highway][name="%s"](area.location); node(w)->.n2; + ); + node.n1.n2; + out meta; + """ + + data = api.query(query % (areacode, street1, street2)) + + return data.get_nodes() From 93020452323842a4c87e8cc9bc7780472fce8896 Mon Sep 17 00:00:00 2001 From: Vehicle Researcher Date: Sat, 17 Nov 2018 02:08:34 -0800 Subject: [PATCH 4/5] openpilot v0.5.6 release --- README.md | 131 +++-- RELEASES.md | 10 + cereal/car.capnp | 15 +- cereal/log.capnp | 7 + selfdrive/assets/sounds/disengaged.wav | Bin 0 -> 428188 bytes selfdrive/assets/sounds/engaged.wav | Bin 0 -> 159998 bytes selfdrive/assets/sounds/error.wav | Bin 0 -> 71030 bytes selfdrive/assets/sounds/hq_disengaged.mp3 | Bin 30966 -> 0 bytes selfdrive/assets/sounds/hq_engaged.mp3 | Bin 30963 -> 0 bytes selfdrive/assets/sounds/hq_warning_0.mp3 | Bin 30965 -> 0 bytes selfdrive/assets/sounds/hq_warning_1.mp3 | Bin 31592 -> 0 bytes selfdrive/assets/sounds/hq_warning_2.mp3 | Bin 30965 -> 0 bytes selfdrive/assets/sounds/warning_1.wav | Bin 0 -> 128798 bytes selfdrive/assets/sounds/warning_2.wav | Bin 0 -> 119446 bytes selfdrive/boardd/boardd.py | 6 +- selfdrive/car/gm/carcontroller.py | 6 +- selfdrive/car/gm/carstate.py | 7 +- selfdrive/car/gm/interface.py | 24 +- selfdrive/car/gm/radar_interface.py | 4 +- selfdrive/car/gm/values.py | 31 +- selfdrive/car/honda/carcontroller.py | 52 +- selfdrive/car/honda/carstate.py | 18 +- selfdrive/car/honda/hondacan.py | 43 +- selfdrive/car/honda/interface.py | 46 +- selfdrive/car/honda/values.py | 38 +- selfdrive/car/hyundai/values.py | 10 +- selfdrive/car/toyota/carcontroller.py | 29 +- selfdrive/car/toyota/carstate.py | 15 +- selfdrive/car/toyota/interface.py | 22 +- selfdrive/car/toyota/toyotacan.py | 2 +- selfdrive/common/touch.c | 20 +- selfdrive/common/version.h | 2 +- selfdrive/config.py | 22 - selfdrive/controls/controlsd.py | 162 +++--- selfdrive/controls/lib/alertmanager.py | 642 +--------------------- selfdrive/controls/lib/alerts.py | 627 +++++++++++++++++++++ selfdrive/controls/lib/drive_helpers.py | 16 +- selfdrive/controls/lib/latcontrol.py | 26 +- selfdrive/controls/lib/longcontrol.py | 61 +- selfdrive/controls/lib/vehicle_model.py | 159 ++++-- selfdrive/controls/radard.py | 12 +- selfdrive/loggerd/loggerd | Bin 1630952 -> 1630952 bytes selfdrive/manager.py | 5 +- selfdrive/sensord/gpsd | Bin 1171544 -> 1171544 bytes selfdrive/sensord/sensord | Bin 1159016 -> 1159016 bytes selfdrive/service_list.yaml | 1 + selfdrive/test/plant/plant.py | 10 +- selfdrive/ui/Makefile | 14 +- selfdrive/ui/slplay.c | 184 +++++++ selfdrive/ui/slplay.h | 21 + selfdrive/ui/start.sh | 6 + selfdrive/ui/ui.c | 240 +++++++- selfdrive/visiond/visiond | Bin 9069496 -> 9069496 bytes 53 files changed, 1660 insertions(+), 1086 deletions(-) create mode 100644 selfdrive/assets/sounds/disengaged.wav create mode 100644 selfdrive/assets/sounds/engaged.wav create mode 100644 selfdrive/assets/sounds/error.wav delete mode 100644 selfdrive/assets/sounds/hq_disengaged.mp3 delete mode 100644 selfdrive/assets/sounds/hq_engaged.mp3 delete mode 100644 selfdrive/assets/sounds/hq_warning_0.mp3 delete mode 100644 selfdrive/assets/sounds/hq_warning_1.mp3 delete mode 100644 selfdrive/assets/sounds/hq_warning_2.mp3 create mode 100644 selfdrive/assets/sounds/warning_1.wav create mode 100644 selfdrive/assets/sounds/warning_2.wav create mode 100644 selfdrive/controls/lib/alerts.py create mode 100644 selfdrive/ui/slplay.c create mode 100644 selfdrive/ui/slplay.h create mode 100755 selfdrive/ui/start.sh diff --git a/README.md b/README.md index 442fbd447..169417a05 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,26 @@ Welcome to openpilot ====== -[openpilot](http://github.com/commaai/openpilot) is an open source driving agent. Currently it performs the functions of Adaptive Cruise Control (ACC) and Lane Keeping Assist System (LKAS) for selected Honda, Toyota, Acura, Lexus, Chevrolet, Hyundai, Kia. It's about on par with Tesla Autopilot and GM Super Cruise, and better than [all other manufacturers](http://www.thedrive.com/tech/5707/the-war-for-autonomous-driving-part-iii-us-vs-germany-vs-japan). +[openpilot](http://github.com/commaai/openpilot) is an open source driving agent. Currently, it performs the functions of Adaptive Cruise Control (ACC) and Lane Keeping Assist System (LKAS) for selected Honda, Toyota, Acura, Lexus, Chevrolet, Hyundai, Kia. It's about on par with Tesla Autopilot and GM Super Cruise, and better than [all other manufacturers](http://www.thedrive.com/tech/5707/the-war-for-autonomous-driving-part-iii-us-vs-germany-vs-japan). -The openpilot codebase has been written to be concise and enable rapid prototyping. We look forward to your contributions - improving real vehicle automation has never been easier. +The openpilot codebase has been written to be concise and to enable rapid prototyping. We look forward to your contributions - improving real vehicle automation has never been easier. + +Table of Contents +======================= + +* [Community](#community) +* [Hardware](#hardware) +* [Supported Cars](#supported-cars) +* [Community Maintained Cars](#community-maintained-cars) +* [In Progress Cars](#in-progress-cars) +* [How can I add support for my car?](#how-can-i-add-support-for-my-car-) +* [Directory structure](#directory-structure) +* [User Data / chffr Account / Crash Reporting](#user-data-chffr-account-crash-reporting) +* [Testing on PC](#testing-on-pc) +* [Contributing](#contributing) +* [Licensing](#licensing) + +--- Community ------ @@ -41,73 +58,59 @@ Install openpilot on a neo device by entering ``https://openpilot.comma.ai`` dur Supported Cars ------ -| Make | Model | Supported Package | Lateral | Longitudinal | No Accel Below | No Steer Below | -| ---------------------| ----------------------| ---------------------| --------| ---------------| -----------------| ---------------| -| Acura | ILX 2016 | AcuraWatch Plus | Yes | Yes | 25mph1| 25mph | -| Acura | ILX 2017 | AcuraWatch Plus | Yes | Yes | 25mph1| 25mph | -| Acura | RDX 2018 | AcuraWatch Plus | Yes | Yes | 25mph1| 12mph | -| Chevrolet3| Volt 2017 | Adaptive Cruise | Yes | Yes | 0mph | 7mph | -| Chevrolet3| Volt 2018 | Adaptive Cruise | Yes | Yes | 0mph | 7mph | -| Honda | Accord 2018 | All | Yes | Stock | 0mph | 3mph | -| Honda | Civic 2016 | Honda Sensing | Yes | Yes | 0mph | 12mph | -| Honda | Civic 2017 | Honda Sensing | Yes | Yes | 0mph | 12mph | -| Honda | Civic 2017 *(Hatch)* | Honda Sensing | Yes | Stock | 0mph | 12mph | -| Honda | Civic 2018 | Honda Sensing | Yes | Yes | 0mph | 12mph | -| Honda | Civic 2018 *(Hatch)* | Honda Sensing | Yes | Stock | 0mph | 12mph | -| Honda | CR-V 2015 | Touring | Yes | Yes | 25mph1| 12mph | -| Honda | CR-V 2016 | Touring | Yes | Yes | 25mph1| 12mph | -| Honda | CR-V 2017 | Honda Sensing | Yes | Stock | 0mph | 12mph | -| Honda | CR-V 2018 | Honda Sensing | Yes | Stock | 0mph | 12mph | -| Honda | Odyssey 2017 | Honda Sensing | Yes | Yes | 25mph1| 0mph | -| Honda | Odyssey 2018 | Honda Sensing | Yes | Yes | 25mph1| 0mph | -| Honda | Odyssey 2019 | Honda Sensing | Yes | Yes | 25mph1| 0mph | -| Honda | Pilot 2017 | Honda Sensing | Yes | Yes | 25mph1| 12mph | -| Honda | Pilot 2018 | Honda Sensing | Yes | Yes | 25mph1| 12mph | -| Honda | Pilot 2019 | All | Yes | Yes | 25mph1| 12mph | -| Honda | Ridgeline 2017 | Honda Sensing | Yes | Yes | 25mph1| 12mph | -| Honda | Ridgeline 2018 | Honda Sensing | Yes | Yes | 25mph1| 12mph | -| Hyundai6 | Santa Fe 2019 | All | Yes | Stock | 0mph | 0mph | -| Hyundai6 | Elantra 2017 | SCC + LKAS | Yes | Stock | 19mph | 34mph | -| Hyundai6 | Genesis 2018 | All | Yes | Stock | 19mph | 34mph | -| Kia6 | Sorento 2018 | All | Yes | Stock | 0mph | 0mph | -| Kia6 | Stinger 2018 | SCC + LKAS | Yes | Stock | 0mph | 0mph | -| Lexus | RX Hybrid 2017 | All | Yes | Yes2| 0mph | 0mph | -| Lexus | RX Hybrid 2018 | All | Yes | Yes2| 0mph | 0mph | -| Toyota | Camry 20184| All | Yes | Stock | 0mph5 | 0mph | -| Toyota | C-HR 20184 | All | Yes | Stock | 0mph | 0mph | -| Toyota | Corolla 2017 | All | Yes | Yes2| 20mph | 0mph | -| Toyota | Corolla 2018 | All | Yes | Yes2| 20mph | 0mph | -| Toyota | Highlander 2017 | All | Yes | Yes2| 0mph | 0mph | -| Toyota | Highlander Hybrid 2018| All | Yes | Yes2| 0mph | 0mph | -| Toyota | Prius 2016 | TSS-P | Yes | Yes2| 0mph | 0mph | -| Toyota | Prius 2017 | All | Yes | Yes2| 0mph | 0mph | -| Toyota | Prius 2018 | All | Yes | Yes2| 0mph | 0mph | -| Toyota | Prius Prime 2017 | All | Yes | Yes2| 0mph | 0mph | -| Toyota | Prius Prime 2018 | All | Yes | Yes2| 0mph | 0mph | -| Toyota | Rav4 2016 | TSS-P | Yes | Yes2| 20mph | 0mph | -| Toyota | Rav4 2017 | All | Yes | Yes2| 20mph | 0mph | -| Toyota | Rav4 2018 | All | Yes | Yes2| 20mph | 0mph | -| Toyota | Rav4 Hybrid 2017 | All | Yes | Yes2| 0mph | 0mph | -| Toyota | Rav4 Hybrid 2018 | All | Yes | Yes2| 0mph | 0mph | +| Make | Model | Supported Package | Lateral | Longitudinal | No Accel Below | No Steer Below | Giraffe | +| ---------------------| ------------------------| ---------------------| --------| ---------------| -----------------| ---------------|-------------------| +| Acura | ILX 2016-17 | AcuraWatch Plus | Yes | Yes | 25mph1| 25mph | Nidec | +| Acura | RDX 2018 | AcuraWatch Plus | Yes | Yes | 25mph1| 12mph | Nidec | +| Chevrolet3| Malibu 2017 | Adaptive Cruise | Yes | Yes | 0mph | 7mph | Custom7| +| Chevrolet3| Volt 2017-18 | Adaptive Cruise | Yes | Yes | 0mph | 7mph | Custom7| +| Honda | Accord 2018 | All | Yes | Stock | 0mph | 3mph | Bosch | +| Honda | Civic 2016-18 | Honda Sensing | Yes | Yes | 0mph | 12mph | Nidec | +| Honda | Civic 2017-18 *(Hatch)* | Honda Sensing | Yes | Stock | 0mph | 12mph | Bosch | +| Honda | CR-V 2015-16 | Touring | Yes | Yes | 25mph1| 12mph | Nidec | +| Honda | CR-V 2017-18 | Honda Sensing | Yes | Stock | 0mph | 12mph | Bosch | +| Honda | Odyssey 2017-19 | Honda Sensing | Yes | Yes | 25mph1| 0mph | Inverted Nidec | +| Honda | Pilot 2017-18 | Honda Sensing | Yes | Yes | 25mph1| 12mph | Nidec | +| Honda | Pilot 2019 | All | Yes | Yes | 25mph1| 12mph | Inverted Nidec | +| Honda | Ridgeline 2017-18 | Honda Sensing | Yes | Yes | 25mph1| 12mph | Nidec | +| Hyundai | Santa Fe 2019 | All | Yes | Stock | 0mph | 0mph | Custom6| +| Hyundai | Elantra 2017 | SCC + LKAS | Yes | Stock | 19mph | 34mph | Custom6| +| Hyundai | Genesis 2018 | All | Yes | Stock | 19mph | 34mph | Custom6| +| Kia | Sorento 2018 | All | Yes | Stock | 0mph | 0mph | Custom6| +| Kia | Stinger 2018 | SCC + LKAS | Yes | Stock | 0mph | 0mph | Custom6| +| Lexus | RX Hybrid 2016-18 | All | Yes | Yes2| 0mph | 0mph | Toyota | +| Toyota | Camry 20184 | All | Yes | Stock | 0mph5 | 0mph | Toyota | +| Toyota | C-HR 2017-184| All | Yes | Stock | 0mph | 0mph | Toyota | +| Toyota | Corolla 2017-18 | All | Yes | Yes2| 20mph | 0mph | Toyota | +| Toyota | Highlander 2017-18 | All | Yes | Yes2| 0mph | 0mph | Toyota | +| Toyota | Highlander Hybrid 2018 | All | Yes | Yes2| 0mph | 0mph | Toyota | +| Toyota | Prius 2016 | TSS-P | Yes | Yes2| 0mph | 0mph | Toyota | +| Toyota | Prius 2017-18 | All | Yes | Yes2| 0mph | 0mph | Toyota | +| Toyota | Prius Prime 2017-18 | All | Yes | Yes2| 0mph | 0mph | Toyota | +| Toyota | Rav4 2016 | TSS-P | Yes | Yes2| 20mph | 0mph | Toyota | +| Toyota | Rav4 2017-18 | All | Yes | Yes2| 20mph | 0mph | Toyota | +| Toyota | Rav4 Hybrid 2017-18 | All | Yes | Yes2| 0mph | 0mph | Toyota | 1[Comma Pedal](https://community.comma.ai/wiki/index.php/Comma_Pedal) is used to provide stop-and-go capability to some of the openpilot-supported cars that don't currently support stop-and-go. Here is how to [build a Comma Pedal](https://medium.com/@jfrux/comma-pedal-building-with-macrofab-6328bea791e8). ***NOTE: The Comma Pedal is not officially supported by [comma.ai](https://comma.ai)*** 2When disconnecting the Driver Support Unit (DSU), otherwise longitudinal control is stock ACC. For DSU locations, see [Toyota Wiki page](https://community.comma.ai/wiki/index.php/Toyota) -3[GM installation guide](https://www.zoneos.com/volt.htm) +3[GM installation guide](https://zoneos.com/volt/). 4It needs an extra 120Ohm resistor ([pic1](https://i.imgur.com/CmdKtTP.jpg), [pic2](https://i.imgur.com/s2etUo6.jpg)) on bus 3 and giraffe switches set to 01X1 (11X1 for stock LKAS), where X depends on if you have the [comma power](https://comma.ai/shop/products/power/). 528mph for Camry 4CYL L, 4CYL LE and 4CYL SE which don't have Full-Speed Range Dynamic Radar Cruise Control. -6Giraffe is under development: architecture similar to Toyota giraffe, with an extra 120Ohm resistor on bus 3. +6Open sourced [Hyundai Giraffe](https://github.com/commaai/neo/tree/master/giraffe/hyundai) is designed ofor the 2019 Sante Fe; pinout may differ for other Hyundais.
+7Community built Giraffe, find more information here, [GM Giraffe](https://zoneos.com/shop/)
Community Maintained Cars ------ -| Make | Model | Supported Package | Lateral | Longitudinal | No Accel Below | No Steer Below | -| ------- | ---------------------- | -------------------- | ------- | ------------ | -------------- | -------------- | -| Honda | Fit 2018 | Honda Sensing | Yes | Yes | 25mph1| 12mph | -| Tesla | Model S 2012 | All | Yes | Not yet | Not applicable | 0mph | -| Tesla | Model S 2013 | All | Yes | Not yet | Not applicable | 0mph | +| Make | Model | Supported Package | Lateral | Longitudinal | No Accel Below | No Steer Below | Giraffe | +| ------- | ---------------------- | -------------------- | ------- | ------------ | -------------- | -------------- | ------------------| +| Honda | Fit 2018 | Honda Sensing | Yes | Yes | 25mph1| 12mph | Inverted Nidec | +| Tesla | Model S 2012 | All | Yes | Not yet | Not applicable | 0mph | Custom8| +| Tesla | Model S 2013 | All | Yes | Not yet | Not applicable | 0mph | Custom8| -[[Honda Fit Pull Request]](https://github.com/commaai/openpilot/pull/266). -[[Tesla Model S Pull Request]](https://github.com/commaai/openpilot/pull/246) +[[Honda Fit Pull Request]](https://github.com/commaai/openpilot/pull/266).
+[[Tesla Model S Pull Request]](https://github.com/commaai/openpilot/pull/246)
+8Community built Giraffe, find more information here [Community Tesla Giraffe](https://github.com/jeankalud/neo/tree/tesla_giraffe/giraffe/tesla)
Community Maintained Cars are not confirmed by comma.ai to meet our [safety model](https://github.com/commaai/openpilot/blob/devel/SAFETY.md). Be extra cautious using them. @@ -116,6 +119,7 @@ In Progress Cars - All TSS-P Toyota with Steering Assist. - 'Full Speed Range Dynamic Radar Cruise Control' is required to enable stop-and-go. Only the Prius, Camry and C-HR have this option. - Even though the Tundra, Sequoia and the Land Cruiser have TSS-P, they don't have Steering Assist and are not supported. + - Only remaining Toyota cars with no port yet are the Avalon and the Sienna. - All LSS-P Lexus with Steering Assist or Lane Keep Assist. - 'All-Speed Range Dynamic Radar Cruise Control' is required to enable stop-and-go. Only the GS, GSH, F, RX, RXH, LX, NX, NXH, LC, LCH, LS, LSH have this option. - Even though the LX have TSS-P, it does not have Steering Assist and is not supported. @@ -131,7 +135,7 @@ We've written guides for [Brand](https://medium.com/@comma_ai/how-to-write-a-car - BMW, Audi, Volvo, and Mercedes all use [FlexRay](https://en.wikipedia.org/wiki/FlexRay) and are unlikely to be supported any time soon. - We put time into a Ford port, but the steering has a 10 second cutout limitation that makes it unusable. -- The 2016-2017 Honda Accord use a custom signaling protocol for steering that's unlikely to ever be upstreamed. +- The 2016-2017 Honda Accord uses a custom signaling protocol for steering that's unlikely to ever be upstreamed. Directory structure ------ @@ -166,7 +170,7 @@ To understand how the services interact, see `selfdrive/service_list.yaml` User Data / chffr Account / Crash Reporting ------ -By default openpilot creates an account and includes a client for chffr, our dashcam app. We use your data to train better models and improve openpilot for everyone. +By default, openpilot creates an account and includes a client for chffr, our dashcam app. We use your data to train better models and improve openpilot for everyone. It's open source software, so you are free to disable it if you wish. @@ -190,6 +194,7 @@ The resulting plots are displayed in `selfdrive/test/tests/plant/out/longitudina More extensive testing infrastructure and simulation environments are coming soon. + Contributing ------ @@ -208,3 +213,7 @@ Any user of this software shall indemnify and hold harmless Comma.ai, Inc. and i **THIS IS ALPHA QUALITY SOFTWARE FOR RESEARCH PURPOSES ONLY. THIS IS NOT A PRODUCT. YOU ARE RESPONSIBLE FOR COMPLYING WITH LOCAL LAWS AND REGULATIONS. NO WARRANTY EXPRESSED OR IMPLIED.** + +--- + + diff --git a/RELEASES.md b/RELEASES.md index 82f012086..3720b5350 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,13 @@ +Version 0.5.6 (2018-11-16) +======================== + * Refresh settings layout and add feature descriptions + * In Honda, keep stock camera on for logging and extra stock features; new openpilot giraffe setting is 0111! + * In Toyota, option to keep stock camera on for logging and extra stock features (e.g. AHB); 120Ohm resistor required on giraffe. + * Improve camera calibration stability + * More tuning to Honda positive accelerations + * Reduce brake pump use on Hondas + * Chevrolet Malibu support thanks to tylergets! + Version 0.5.5 (2018-10-20) ======================== * Increase allowed Honda positive accelerations diff --git a/cereal/car.capnp b/cereal/car.capnp index 6b2e95f6c..2f25aa0d1 100644 --- a/cereal/car.capnp +++ b/cereal/car.capnp @@ -71,6 +71,7 @@ struct CarEvent @0x9b1657f34caf3ad3 { belowSteerSpeed @46; calibrationProgress @47; lowBattery @48; + invalidGiraffeHonda @49; } } @@ -260,13 +261,13 @@ struct CarControl { # these are the choices from the Honda # map as good as you can for your car none @0; - beepSingle @1; - beepTriple @2; - beepRepeated @3; - chimeSingle @4; - chimeDouble @5; - chimeRepeated @6; - chimeContinuous @7; + chimeEngage @1; + chimeDisengage @2; + chimeError @3; + chimeWarning1 @4; + chimeWarning2 @5; + chimeWarningRepeat @6; + chimePrompt @7; } } } diff --git a/cereal/log.capnp b/cereal/log.capnp index f1b4b50b6..389b550ad 100644 --- a/cereal/log.capnp +++ b/cereal/log.capnp @@ -411,6 +411,7 @@ struct Live100Data { alertSize @39 :AlertSize; alertBlinkingRate @42 :Float32; alertType @44 :Text; + alertSound @45 :Text; awarenessStatus @26 :Float32; angleOffset @27 :Float32; gpsPlannerActive @40 :Bool; @@ -1565,6 +1566,11 @@ struct LiveParametersData { angleOffset @2 :Float32; } +struct LiveMapData { + valid @0 :Bool; + speedLimit @1 :Float32; +} + struct Event { # in nanoseconds? @@ -1632,5 +1638,6 @@ struct Event { driverMonitoring @59 :DriverMonitoring; boot @60 :Boot; liveParameters @61 :LiveParametersData; + liveMapData @62 :LiveMapData; } } diff --git a/selfdrive/assets/sounds/disengaged.wav b/selfdrive/assets/sounds/disengaged.wav new file mode 100644 index 0000000000000000000000000000000000000000..958e08fd85b3e6e8e47316e06ccb5e317528c38a GIT binary patch literal 428188 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 nVA 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 z0#3jQH~}Z%1e|~qZ~{)i2{-{K-~^n26L11fzzH}3C*TB}fD>>6PQVE`0Vm)DoPZN> z0#3jQH~}Z%1e|~qZ~{)i2{-{K-~^n26L11fzzH}3C*TB}fD>>6PQVE`0Vm)DoPZN> z0#3jQH~}Z%1e|~qZ~{)i2{-{K-~^n26L11fzzH}3C*TB}fD>>6PQVE`0Vm)DoPZN> z0#3jQH~}Z%1e|~qZ~{)i2{-{K-~^n26L11fzzH}3C*TB}fD>>6PQVE`0Vm)DoPZN> z0#3jQH~}Z%1e|~qZ~{)i2{-{K-~^n26L11fzzH}3C*TB}fD>>6PQVE`0Vm)DoPZN> z0#3jQH~}Z%1e|~qZ~{)i2{-{K-~^n26L11fzzH}3C*TB}fD>>6PQVE`0Vm)DoPZN> z0#3jQH~}Z%1e|~qZ~{)i2{-{K-~^n26L11fzzH}3C*TB}fD>>6PQVE`0Vm)DoPZN> z0#3jQH~}Z%1e|~qZ~{)i2{-{K-~^n26L11fzzH}3C*TB}fD>>6PQVE`0Vm)DoPZN> z0#3jQH~}Z%1e|~qZ~{)i2{-{K-~^n26L11fzzH}3C*TB}fD>>6PQVE`0Vm)DoPZN> z0#3jQH~}Z%1e|~qZ~{)i2{-{K-~^n26L11fzzH}3C*TB}fD>>6PQVE`0Vm)DoPZN> z0#3jQH~}Z%1e|~qZ~{)i2{-{K-~^n26L11fzzH}3C*TB}fD>>6PQVE`0Vm)DoPZN> z0#3jQH~}Z%1e|~qZ~{)i2{-{K-~^n26L11fzzH}3C*TB}fD>>6PQVE`0Vm)DoPZN> z0#3jQH~}Z%1e|~qZ~{)i2{-{K-~^n26L11fzzH}3C*TB}fD>>6PQVE`0Vm)DoPZN> z0#3jQH~}Z%1e|~qZ~{)i2{-{K-~^n26L11fzzH}3C*TB}fD>>6PQVE`0Vm)DoPZN> z0#3jQH~}Z%1e|~qZ~{)i2{-{K-~^n26L11fzzH}3C*TB}fD>>6PQVE`0Vm)DoPZN> z0#3jQH~}Z%1e|~qZ~{)i2{-{K-~^n26L11fzzH}3C*TB}fD>>6PQVE`0Vm)DoPZN> z0#3jQH~}Z%1e|~qZ~{)i2{-{K-~^n26L11fzzH}3C*TB}fD>>6PQVE`0Vm)DoPZN> z0#3jQH~}Z%1e|~qZ~{)i2{-{K-~^n26L11fzzH}3C*TB}fD>>6PQVE`0Vm)DoPZN> z0#3jQH~}Z%1e|~qZ~{)i2{-{K-~^n26L11fzzH}3C*TB}fD>>6PQVE`0Vm)DoPZN> z0#3jQH~}Z%1e|~qZ~{)i2{-{K-~^n26L11fzzH}3C*TB}fD>>6PQVE`0Vm)DoPZN> z0#3jQH~}Z%1e|~qZ~{)i2{-{K-~^n26L11fzzH}3C*TB}fD>>6PQVE`0Vm)DoPZN> z0#3jQH~}Z%1e|~qZ~{)i2{-{K-~^n26L11fzzH}3C*TB}fD>>6PQVE`0Vm)DoPZN> z0#3jQH~}Z%1e|~qZ~{)i2{-{K-~^n26L11fzzH}3C*TB}fD>>6PQVE`0Vm)DoPZN> z0#3jQH~}Z%1e|~qZ~{)i2{-{K-~^n26L11fzzH}3C*TB}fD>>6PQVE`0Vm)DoPZN> z0#3jQH~}Z%1e|~qZ~{)i2{-{K-~^n26L11fzzH}3C*TB}fD>>6PQVE`0Vm)DoPZN> z0#3jQH~}Z%1e|~qZ~{)i2{-{K-~^n26L11fzzO`nLg3;NBQHFOCmZ|63HRjxmp@%R z_q@;hU75RvWXIfJ|MAKP2N!AYAO9~s^PEdYTsZRdkt5FBYRBDy8<#8{`1ZWc`yT$x Yd;6{_`f1W-7o2nE#{c-}|L*wz3vM8@N&o-= literal 0 HcmV?d00001 diff --git a/selfdrive/assets/sounds/engaged.wav b/selfdrive/assets/sounds/engaged.wav new file mode 100644 index 0000000000000000000000000000000000000000..c6c088e01c8b73287864957509940ddef3d2e934 GIT binary patch literal 159998 zcmd>mWt1Dql5UBaS!!<6n3P5M(PW#^7 z{kcE(Jbgz}sVX5dGcqzVB2t}NHE$jsOGUaj>ej4v*LH3CApg6sfrF<`>_z?Gt>gbf z=^e(8$?7s@%*YA<1F=1a)ohd7YV_cyoyHCrFrdYV|4df7Vx^kpDpe|1sY<14wJTPv zU9Bc^>38mbruzT!cmAk}S*4)i6oiV*y$Tm@DnduZ|6^B-8a6tgcv`X2g{>=Qyrra= zbMVMfmEQl4x&E&|$Qv+m0Mawn)?Zsgfu6%~9H+od;*I0KK26;t?oxkAS#+Ps57{9< z@lE8#a4Mw5;F>6z$VWUUb7PQ>pn|wVJV6ljU*AMd;zc}3r6KR6K2tRjzl*L@R|M_E zizt_D2l0ex8BsGyS?U>?j;sgA37W{<1hq6si~g$xsk~(FpT$GURH;N=|6NU~7Lea$ zU1YlnI>_3J`h}#8>?7j(*E)&P$&_T>sq0ib{_{6+pLo+CIoYp8G>~Pd=q;k1D7onF zzn4g~6ood@Aw}{hWh5QMXHiO$N@C22+K6Yw9pV#%))Kv+s)3}NOi#9xNJr)(`GZJF z{3c5y+mO0LeiJ!}R7JnY(IayabfqXE>LE({@5YNvN0gCzPSQ-2O|*mH03u(ij8sV^ zt*QEn)MN?d{S+ld?Ik&x=qs|WR3DM$68Td#5Z^`fkVr@5B3{HSAzMZEXQ~XcH^~xy z9StHUF#`#jh%_Ysr&1H?iE?OgpQtZYLs4IoWfhHHQQ1U!Vcxth*U&P#GTYNQAUcJ$R}hzk~WeqvMzFlk!?;Lh8YLSwN?1LhT$r{NN z#NB`AcCuH0?Ls2qLNarB%l6g-xu*Y@jS(^`XH1GG z$Q~e`kuM@0*#`2Pn7cH1N|r{p?brSwYfN#wG+>X)I}pnrcR9*Su4>7 zl0s4%5IsS>ik=ds5!9nlP--p_zl%yH(i63$Mz`oG*=pi>ik5%>Chn7^lf6bhOP5DuC_Y#97ObPYJLzU6^%v_Ka!*SYwaY>M2k~(6M2btkn|Vv zFTvAf>&W~h4XJsY%1!1hDlPRpRU(;}r2Ic61X1&^J(Q{;HM5A{#5>i`MckUYNA>|J z3sZB09L-Ll)^R!OowM2mT;A$f~z z)vp?95!FR%M?MNm)n#!mwO z%SWn2a)eTkQ`G*No4i*vqGan+Bbv%dey8#i-(-78sY&!Y+0s-${rk8QX$gwRz9mP5 zD1*F5w2RPV(4Re?(i?tO0Uu<#)UW^kcdEz9)}~tU?{|wzAg;(#|1%|-gBbZD4TtC} zvRon`*{}c30VJo8JyF!NDY}W4ldU8Bgd9<_}TE!DmT4hKKPe?#I1& zA#TNg;NS7LfJcC9fU|%DfIawbd<(t}--NHn*T8!%z8c=^@QwHed@H^kp6-HFhw#(* zN>?1;2;i$6o-x;Gb|Kl-i?qZNYkI!P2sA^zwR|c8vJ}#4^r2M)OC^Ckh{jePz9+1Q_;BnRHbkW3^Ckcp%r>G0MenxAhK(5D0_5GgklT?!Y~`0ebBn{vLmfKY^BChCVnA{jmr7WfQ&_UxClXXW--UN%#=J0K6aG z4eyS(!#m(@@K$&;KqI^f-WYFy*Z+Cd2(FvrE%6q3d%P{)5$}rsf%nD-1IFPK@LBjw zC~-NA#CH4$favQN_;VPw?=X&GoS-ceP!-S`FbFUeunuqla0|JOd_dkIPQ;DSDRhdC zqNS9hRG>7cG^KQ-bf=7;N1FoCn+jJO;b~d;oj`e4%^=e1>12DQ_sR z;OP^}6~Ix-5z0o&rk~~fLFq@SN2v?7=qMp1h&%=SjqF3FAybgHNP8HK;z$A{&nNr? zehxnmJhmC1hEK=y0G*)q&G6=UT|j-j9=sbskF|sz>5h-Uhe5y2#dqR=;#Z*$zTjVB zL@+!T$wit0h5=Rp4gu~0J|mwHD`E!<0!RelL;Q#dF(UsU&yf?zF=QSxA87{=AVTB; z@a_Z{F)6OVPh%&s23URU5&93>25pHxOg>81P1Z}EN}Nn&0anFV$CEKMHaa#k_C5L| z+5_-5@;1^Z(l=rYTf>V1<-%pd#*jI57_cBTFEk`H4Bq*niGb~)9ig|OH=*2cZg>TN z9brYbNB)eoh&GL~W9-=1*tgg}@qgma63-H*q#?=2L|AL!jSa|V#6xjXy3o4Q?$Phi z>oDsu&$7<3%5uta4s!Q#6?_$ckzkR)E_4Vxirb5iOHN4WGMcQ7yq$cJV!q;l@}Tmx z>Wpf)dY5{fW`ZVLo25MoNY`cP2I&Uq7U`DgX6t6@+5#flsCEXxsL^YRYf5R_s@teL ztGcM_C~GTmIYn_uwqI6NT0?qFd{nF!DMh0NV+9X+4|xi%f}79IXP;-DWil8XMqgS_ z+F9TwVm?jBregM_Jvk&XG!c%4W1FL!qwON?BAT!|91F&S(Lgl70o3qU_fPlD^nLMu z_IC7k@D_OVo~52;p4Oh0o*YlEM+DFSDgg$0272~;4tNrP0p9-Jw}2kLo<0*`wtu!i zE07s@72S)|Z1y{D~* z=AnCDxnH_ZxlgH?`q#_Ul)HDf0aO$ zK*?aKVC_(?Q2%hh@Se!tNGuwU=Ew8m-xA*wd1xLQzyjDZWEoO|TAX@^c8}JJ(Uak4 z`k9N^3)wOlx4(FQ@^S^m1-pfR31wobc&cQY*T9sF|;^3 z936`8M)#mk0fndub)!CbJJAp5d-MW&5uK0DLmQ%vQGe2t+>qRq{4H53c{Xu2Q87_D zaVWkoE{@CM(_&L&AEFjRvt0JbbAzTNr4J1e;7zy?d{t^5q@FLJ6&?NBK|Bt_~ zzqcQ%@g4V_@J;ZI^R@J~@>TX#@>TFv^fd;I@{RBv@*O6`pnn9w=lA$m1Xcwa1{(%N z&_}+IKjaKM!|_NgqKl=+I>kH0wa3oCpBN(0J0>RoDEdRzKu#z#gT zYbeXdcCyECCvx398}ARn0KseFOJOx}4e=JqW{FK|m6n&6m-kl;R4h==Q!Y_0Rn1UO zSGUu&*D$nn?O)p6T9rbts+owCEyRN&UI|i7oo2x6YE2F!jy{at*n5>zk*{9yG zzO1^WI;A|NT%}m0=qc|Z=g4@nQy}M>h?@ZqJr{NmbP~Mcz2LRww&Ol!KVi3IwPHPG zJZ7||cc6cwzM~GJ45py4_H4tpV$IOzD4Iwl?!@oKcf_{GmPMCE7e*FDc8329KL|Yt zaYLNYpkQ9`ec)Z-4*&&l#ec=W%)it>7C`jjERZq#{CoXh{9pa00wn|U0}BHFfG;pI zI5HRltO%_Lm4nsb4PbF(QKUw+X4D?FMYqRx#9GB$#XW#ciH(W!$qLEa$y>>mXe;zK zdJCV<>EgT;Eu56SPcwzA{$qw<&{uBf7_ zqUxmXsP3WZscE8Zq~+@Px(m80=5rPqde|XP$CAr18 z^Vtj7KbSw5br`i7JAhs)DAa_W@dGnp{m@>hCE-Xcfpw!&tZFPA2}PcV{|R3ST?^e0 z-Vd4s#z0meJ22Tl*>8sRXgthHnNR9_?|tt*2H5TW3wrmU_o??EFU5!WIs#7nPWeju zOZiXwPxzY!ngu)ocVKsLZ!kYJC{#9FAxsBF=1b&T0jx$`mDar(3UseH{OBX!CtYK?|trh={XGR+b+Nn&r#1u&wG!? ztMktB&hjPz+kD%7#F|(pP&$wq%nVizRSEqO?i1b}*#qlXG&&+aBJO~`UW_h8OX8*R zAIMkaPwGx;fBGPL8Rl8sLfXVlENlW{vED>FBGQTI_lfnJ)1r{Vc%K6)#0Gf^^LDt;ikFIqiP zD`E)!2>l)07n~QE7ntFn?qBU&<-6s*>y>zg-Wi^m9tP+JN8Lx=Bi*Cjzq?zxo4T91 zd$@bLm$(mPz9bR>8rxGA(Dv@pCR zJTo#qGBG+anh#n_-*}IB{X`Scd1T42$?wVa=o+*tRvmi`XbJlG8PL5KdUJF8O2H_*msz&?eB)A8xpH0&Gt1ucV?L&qk^CjU!#v|}-b#HYy z0AMc6^%3v_U~(BQS4!Cd}2a^kdcJS@EUo8oT8qjuA{G~Ph^f~c4PNs*XGvXYWeB>m>?{8E_xyQ zOY)awkZh1ltI#NJDQ_z~synEkXr5@wz}hqfWXtmOCF%1r7G!kI?3T&MqGm0~T9oxA z>vI+>o0(0?re%M~dY3gdYZ|Db{>+A%4KfF2}7lkb-vl-?KL5x)ceE#MdMEnExN#u^&Hc0i$!OOu8fldLIpW*)mGWs9SW6x*zH#gVKcK34ic0F)DboOv|apDe| z^SR@x)qhe>lH7`@06fvX8lrxevQXdPaHbdh2@Aed#`q zpW~+l5KtwNAS=WO3B#hWCZdXDM~g*E#)`*^#f!z231uP)c$s{eT!F4cD`4fYi-1!2 zZ}hLzZb85s{59+Vx4;_L1mw?WtOwQ&yMx|CRj3^8o9vfdlUSX&5Wf(A z9(xhf!+y&Wu}17+N7xf`h8#gx&3og6O}w*Vt~_%;cUJUyy*N6DDKL2t#GY&Dcy4S4Zt$ba?cc4@0R+O_^$e|`h`JZ zaB*l!NCT7oe)N8HWqd`ve{x{54b~c~2NsJu)H>9L^oI1-%vQiZ-Pw8EJnmTjX#N!8 zG~qPyH1QPaBl zv}H79HC_kK6BNxf$+;u7ZYTmsgnowyL}F+-4iuqNzB9wLvxs`2*cUVjI&1J<(MVB^BTO0^ni;4FMNHVnIr zUPi;oNU~(IM6y|;MWSE4Z+u8>SZoaF@)IHxBBR2i!{bBaLZd+cA0HSWSmh44C1X30$+vbqgSI%iN3I3*1WBlRoo2_3ZWT z^X~NR@Llj<@CV@4A=EMS4D^CQ(Lqs3TpIt7c%L|o9zj>a>O7M&lQMxeo;I2>jxm8X zjx~idl{1q!lQ&N=U$9WLKr~x2M>0`1QPxY*OHo}_9k!jQ`h@m`wpm)UwA<--($g|^ znH{n^W(~^D%Wjp^B8Q&K%3YVcHrEai6cZMs7NZnYzStrnddo)az%T7$!3e0hGZ|1oGcM_}bY z=sw_n=z8K}x)`ou&Y@0=!|GV(Sng=)XyN$HQN~fykqf-k)G^I5(ecpn#8Jgr73SzU zXGd2jV*3F+blbhov(7WwJJCDHm+u?k@8=&J$PbJUjt|Zc%@1u3Zw?=f9Ex0yUW(p~ z-HhFe-;SS4oJ(v?ZcUCtN1|o1@}Sv#z(#@<$&6cY!m2nARh9Sej zGL?(m#~_i{?sT`wWpO=nJ#;+)m;qVt zZ1*fc%pGxWg4MgTx4pNLubQv2zoNfuple`LaC0yoiif5}rbQ$%N$hs~PJCfgO17G<<7&8R{0x4kFhiIwP8Z9i3MpMqmzxwu#Rb(x6|v@| z>9o52X@}C}8S;z)nf)@CWG&5Fl)WgsM^3MtXihjMFE=mu&)nU)Cv%VGuFPGP+c>vr z?u(p%a?0eC&&kUkm_0UYLRL>$^VAu-j06UAjYwoM=tBeY>!XdNCzJu=m zKy+WUPjFDMkT;*#o70C=omHJBW5^f*YLNN^`HsB8USsc)?~>NIH7o^>+9ny>HW>C@+dty?i_a~;D?>gKb<@$*SXEH&C$%!+#zv@9jG0%(;O5> zDd44Hj(o>$$2~`NXBFpl=PhSHSKps=^ppFe`?%+XXQOwccZqMYZ@zz_e_3GZ&;H#X z+8??Qz7T#Gc^G*ceINZ8dl!2b{}8{ExSQCY+?O1OjsqSli@gMT3488au>Dp8d+S7G zGV&L)>!;0eBXAKRn{;4TChX|MdUgT3jHxjtHV7RI`?6ihCt%Yv$BpqoEEJ1J!9o*B z!hS3gPQduagJ_T&k2in75zcHMIg*08DG&Y*?2^|$j64-5 z5bu}lpDcxy!U&&30mVRhMte%T&bZ0A0CtyCoRgd*yraDRFm}5{e~Q*h)<~wvrpmf0 zdMHY&im3|JM)h*-GOapIleRQ{Y5JFpFB$ACb`~$2pREVX&smTY&xz$U1kM?hJ0Q1n zZr9wj+>G2CIahNk3Et~%Cv2x|R-4UM+g{VY-+s_u5+u|ez$oWvXGK>97w$q}Mw{HPJg+>@ zz0bXGeeZk*zrh~`ol_i=!CtLQxOt>`q))VObTn9sC&nkm$AMk359l+s(3&U(qhe>V zGgwEEG#|l}&=fT5?SMD1qJ@zVk_4C#GjavFjEn+(TLL!fE#O_?;Jlxh7oAODmC4DkDELKXZ20tgQao z1G2R_+MEM92XmOY^xQhR^>bU~HqR}QTQc`s&exnFIm2=uWk1TM0wh_ItYik7aWnl^ zdcU;(X+N}IwKX+$HPcm7RofIh6nkNhzd^E5GD$Q^)Jo7=pynxgMs^|l81o2o5`7xI z1+_6%3*M;&nn3LdTf!Q%#gY*;QYu_BJOb>t&-_pQEx;yX^cX$c-P_#bT;pB&&cV)U zjv0;<_LFv+9kEZeO|h{6*Q{5p%dIP|(*a8XXRN2KA#2py!`9XI-1frO*WS<0aL^ss z0n44sokLv1T%Fw=-R(RbK=yZr^=*)kuq$l~YzzWYDzApI7La3Q(TA#ISQ*? z2c#qN124dPLHcXh4NQhfur6pfl(2DMNL);O1i2Rk`@AqFh?R_%iZ+cjjpT*%!)rsU zLwADrg3KTz*csNPOa4p#vi>sui@wXg?!Ind*^v75UZeMw_XSuuK6)`P>aFLi=lj$5 zmoLq)18wM{e{x__pk1(iuyv?SXmB_W_-JRu6Lm$q#Jj}bB|aubfZddji*Uk!GoL!2 z+8*q7#hJyJIE%v8bM&11U>`arI4W2rS|b`O87pZnYavrBl#2Jt&&n0*rRp4QaqUsv z5uGSql-@m~N5+KAiJAFXd0EA?OJ(29zMWkjq|fA>NjYml*Pfd*C#QK%s~mlHL3Wqy z&e=P%c4ghjyq88Yvhl zsLiX(V{+)6N6e?p4fJ*Np448{Qs8r>VhC0U`ofpkmzX(H7-57N;rhY)!S((PeyWe= zTkBclsqL=grno3ByTk5q+dX!uI}ey=<)y_+t5N*=pHlnP{1083R}bxNW&( zQCXGNCBR`4o7i^VcFs1;KFVIhQPm-E3Y`&W%;|QyT|v;gC>Dx@Twza`5v50~#Hz%m#b?Gp zCq5*8N86zfFlw=CvZx#y=N0!gcRznWf0A&Lu%)=ASR$24 zKg!ZBXB;?GstSeb{vm0b@&EAsz zAp2qV%j_4~N3xG*_XF6nY+0?d+GH)vT#&gTV`IkL^ttKHL07kEZQ3E4e9Z&ZLr~Kg z%F^;O^2*Z6(&FM0Vz!Va{LK5pJIp!E8Os{Ws>-OwK&dG8E^-IijBUZjCdVav$9u)Q zN4rOdhKGgM2G<1N`QQ5q+diSsG<7$2hn-R96USr6CHqDDZQEU&&1$ul2CT5Gu&}|1 zaHQ~X;ZQ*9!ZwA!!+T`mn8H(q#|n8Ck!1-W!_-gVwfFxRdALccDU5$qW15Ly~u8onO69&tw9QF&Yrw#bT!ddY^# zx@c{*7*-stEJ^GNehKdnKIs7BMe->_DGvZ#Dvw%&T8-M0+J@SM+6X*SC8@+@*iG33 z9)|jq`>?koJp6m`zwsoL(G0K*U54IH-b=<4kwlq9`NW|3!1%V;rjAj7FM#e^- zg`b7%0WOEG0(EUeKCr=`51t7w3N8sw0?Y>N27Cw93DpUm4xJ6P4z~=WfTxk?k?YZ` z(Yvv`F+Dz6=SBh7K-P54>YDW! zAjy_yR|Av-U|D$9en5$=;#t!(XJ#JDIG%Af{dD@4w5@4fbzOCCjZZT|Jyd;1c~_Z~ zqw;iFx{O!=#Uh!=%XjhbaPMjG;7-+bS|X42Su*L}xL*nQMawbNyH+CSJn+6t_CE8R-9HnlXj94I_kSgNo@ z;S=*y^BTZJ^Ca^uz<%>Sv)k-7cP;E(__6Ry;WW!+O9g9XE5(Lc3v5Q)XZt7n7qBq7 zolYmm&2yLcl=t-T_VBLot?=FP-|-`$pEL?J3M~pR4Bv}90R5B_s~N8yACwr7n3bFZ zHl*d~LTnK>4E+B!AXdZ+>)0B~T8fgYq|Spi;v@9~RYa4}s?w^^>d@-a$^uw`$J8g( zsQ@8hGi3{f4H%7#M(%a!$`K@=I+SXrnPA^PmO%$%ceD4hTX36#56#E>Q?OIe zM$|?W5{JcqNq0%>%InGBC|)aisd}rPtDmbYYRhXU=qBrSq-{&vn!YW4T*kPJ+{|K` zXEIM`sX}w zTB~+}j`ULYN(P%LiCttDy%)R}oaUY4&EqWK{LX5_5;H`M*VMPvt;iN+AT|iAmaLLg z#?^6Flo{oR1>rK_SMBfb??2-`?bUkHJ%77)x#~NcIK%dU{hsZ<%aEf_~IckcV_L_E^@=ZfbT}|CggG>WW>rER?g(j1!tGS!mWHy`E7p^VrYUyFA zYOQ3=wUw}ywU@RNHm8Bk{?3(Pfw}L#=SDrKr-845kFec54Ll2^hqR#)VAmmRO1u~^ z)&nP2r&8Xi1{b>DYcfl_%rAz3I=uPPT z=zq}r09pYwbRGQ*?IUeIZ4pgFQ_*%(cT;6l5p^PE3gs2@>Sz27;hQ^#9mAZc3#|yA zxbew}$ykw-n`v~%iu)7zJmW(=qzaB*%M{WXMMP5cC;CpQx zZ4})D>tt3eCw3)vIW`9J)=M-<~zDSSUcN>XGqR`mXfr zX}8j@=`QP5Yu9RK6r@U8GF{|bK-cMEq2JC9wS zS%K-N1!6*98_!kGWlw2$8TU!&DQ7!J z8wYNq+Fw|oThCd}S}qh`D*S5xY*w3f=DDVsCW?t}I&M5>oMxPA9A+G8oMW6}Ja4>Y z6q$skWq=%Ww)wsJqxm4nuyvL-mQ~g@);+e}wmbIQcE2OwDCa8c8tWeGz6$#wmXGP{ z0XCfDfujLxh!W}t@f4RMS0n0}A~rNWEPg(5DG`LdR~D9w)q^;t=12>qCZz^NPL;z9 zc}JZ`n@bbWh4cl00{Rbn8Y7+2oY9QYk&{FK}6N`WxCSS|?g( z+8yd0YB6dqbtYvNOrlq`UFjwXqwiOccJ@p|#P z@t3hzvFWjCv6`{kF@B5_3xiz&h1d^mEG^b0);V?vpoY2nH-M0Fj3hnzG5INZ2fd5l z$L?YuVF!vM6iO{vk>}AC&_2^Y((5woGf%LNvx;+yaSm_~bIbBe^Dhc63L1zSik^xe zi`z=uOP|S}%IYf`LR`^4*vG|HwKTOf{k4B+^T0pWEUkGOvDWQQ-CDSFVM61E4wpuWWH;LDk(}h!#Rgx8?hv-+SSEvh-g-Bbh9hQ+yPbR_FZ3h2< zIb;ka0`WjD_`XJZhk5V2AG&M1YPfEKWvH*ck6mJu*uGi5S?(9!D|`&=nbTx9RRnA? zZZ&2CUKpMm_5ijTwi(U?LWZEBo3Xp`3t+ZsmZ`qEfmvIqEfibCmNd|vYTIhtM%qW% z4>}GzLe7A*8TjRPdH(Vwy>V|Ze;@yiz|}xTC^NJ;yeRC7cp^Pw-D20`SL1SsU&)8q zoWHSs*em=cZbKZ1kK(3$q<*2Eq#dUXr4OaEA&zPVV>tu1fQ)9$X3VL8P0WqV4e&XK zIg8l=z-J1W7a12A?Er7+Z|UtIKI0$$c$Me}NW>HI)A5t>$?<9N?yxWWJ>D+f2e2%@B>pJ=IR0DW zx5OSm8Z1Ij9j zs*1m4J7H~eNz%nSab;l@VKsggelhUxv)F95fuU!drJbS8qs*tYhbYY~@T-AgF8(e0 zJ^DKQBK!&VCsBXIU)ER7H_bEI^U3wu)z;b8`Of~E4$>Misaeg^sS)$|Qy z5n^g?Y+*cQIBBR2aO>UryMWsOqh7BsZYX8gU|45>;5y?2<74A`(`wTM^JMd+!U=^d zEz2!utmmx(o7Yy`QQNW3xz6czd0pK-T|GCwx4h;3<$l@)co3a3F+3@3iI{a zAI2*}49RkI1^N|yXhbAyeM&=0H)g=7j2@@w(FfA6(XP|vfPU2e)Dy4|Bz%!X zbS@DWY{3d4a-aov96gSfKue-WlSh(`lZ}%0gfnqCaVRk}F(WZJkq^;-LlX-V3&7HF z5o8e~IRao$+LE)-IY0NG4$O(&!|&q9i6~8oEWJX#MkUr>4ui*N%51`1&RW6x#{R;t z%B{}b$Xm|~^CSG;!d}Abq8p+NNxEdRbh7l3?17A<;42y^>ni_H^;3;d4^wy1bkmdo z`@lTPOmZfWjN z*r{;5Wt`=Jb-&dKw#~+lhK{|?znucNz&+P9%MHU~31twHhY)eqI>2IV2}Z{#*m86=Si4G~?_l-XncM+UnG=$O zlS7kZk|UFAlk1aDl8=)xgdoutqI8UbZO67j>_SVN3GvZCkZ;I6%00>r>MiO&w8yj` zbOW8wawP?r?Rheu5wsBF0UuQ8~>o-kN}Kd!sZZDwpy}E@{jbHlo_B>y+!1`HFmnR<4mBl^&I5Niro9L=!}(1SbV=dGB}@j+tX;*;xgQ0>%@d^El-= zh42%OL`R_Qz}H^~R{6@{bE+4r8|oS85m@e9?t2BXHKp7o-Rqp|oqPw^vDLQKR?}J& zWRj=wrumlnnCXb=tnr+&!0_Gho1wH}yMDXAyuO^?USKbH1b78N3z7xx^zHQb0DTR8 z3<{$XOr36{8FcZmIc!d|=q$aheXYlAhin`N&oS9K$>{{&!w}C9kHc&8j_{9yEmANr zJv1#ujZhaI4{07u`VG)#prTu1xCcGcLDqG4(bl-OWF&Xo$jFffDb-0KQa%o z4zYT%d$Ij&AA2}w1m`j55r+$}3f%JC+T1$avfR>K8kf$!&$-7L%NfVva@d?T>@{pc zevf61VZCI&04re$<|M`h#!dQdI+xC(cc68oZKH0dS}7KYMz2F5^ku@=F&ZC*gK-j@ z2XS-7v0~U4^fP)8Jq*@`r9a~`*P-jtOJH9QqfxXq))G69UBGJK)$phIGkhw=*?=j>oIjb(a4tpeLBxf&oFZT!U2QOWaCg>&XDcmU9B6

`T8e6l-;`yPbQM)~M|Dp%P~A^$P@B|EHH|cLfv^73?9^=0Y}1U< zjMQXkvNR{u$J7e7Qr#Q&fwPn|l+zT`6g$}z=wi& z1s4l07d$AqR}e0U6tvd2)ZYhrm1h`W$TVidb_+9tTi+xu6cyI9)UzzGF0g*Ey|dK^ zxpW#LGRnCtxX*wstG2JM?~(tZzk9H2&>FIYrbMPjxG`32YkX_GB*e&`K~JDn@f!Fk z z-twM`o^`G@E~b;=Tw-5h&#}~F0Zewa^>TT?0Ty0os_@@7%@22mf z_ZIjH&J>(3*akQN_yVY=ucAK%=xFF{P#R@M2*x&sOhMo!X<>6qQ_E`WDy!XQw{>@P zcf5AKbar-kb`xg?Ci=$um;qK`57_%^gRS{v_xKASO5O-{w!{PvdLh490%meqJVEId>V?4D!4>ry6HAdk*_1>l!NwIzkO*b>;-d zc*Ys}8M>bqpf#j5psk~>r8>d>*&Xl<_I_OeF5r?)5Es=0P7jp^$N&;RNxTG{lIaL% zvev@stwOvb(h2;AuaG>-5Q+$F-46h3Y3pbs=_BZ!Vb9r;*__!LY&ad+9oU07gE=#~ zQ@I;>n|UXpB~JuT1O*Ul>lHagQE^=Cm-r=m=@01**>%}M`678uMRmms#Vf_{%9hH* z$|FiMfT?1F#KM)|lm*JI%1z30%JRy+irtE!JSfkW=g2F_%FEKE8mU=aC|)O8FDfR? z7H;EjD|26hKW`q43EldrU4*nJ# z|^e0?qF(f8e+^hZZd2Jx20R3 z2cYR0`iCHoP64hL+$abZ_+gD}uYaz8rXOt>WvF7TW>lGECZ$7c8hn5mr0gLdP{pt z!JH&}Ci_P=Kt52emw%Jj1G~XI#T@Xc?N#gpEC#dynB@lf0C}GLs_c?149;e*ln<&W zBKa)(B-$X{AgnB?B)G!6!Yj)y$6d-^#D2ki$z(E^jEb}hv=)?>l>TsXZaC;l(-Tu6 zE^+SJ~}e%^7>QPWk`b;o_z-Oby@>+|`2>%s0`GgKY)?jPY5 z(dE%P@tR;KwkI}&J-RX85H}(QWCnExl?{5#T*jQAzH~yjn8KO-Qy%@v+r?YLU&!wS z=N*y)RIpmOTo@N7g>6KwM6&?vMQcS%0D}R=MY*Eqa5kbJ;H%)1pqZeBU^jmkAJjNr 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 literal 0 HcmV?d00001 diff --git a/selfdrive/assets/sounds/error.wav b/selfdrive/assets/sounds/error.wav new file mode 100644 index 0000000000000000000000000000000000000000..1ff0c540d26ab0d4abcf7eb073566a214e8b0f82 GIT binary patch literal 71030 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