diff --git a/Dockerfile b/Dockerfile index b2c20732..99bedcf0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -52,7 +52,7 @@ ENV PATH="/root/.pyenv/bin:/root/.pyenv/shims:${PATH}" ENV PANDA_PATH=/tmp/openpilot/panda ENV OPENPILOT_REF="5690386d8d731c9bebda536a5c71c890f6dfe98c" -ENV OPENDBC_REF="40d9c723d48496229fecc436046538a53af19c11" +ENV OPENDBC_REF="1745ab51825055cd18748013c4a5e3377319e390" COPY requirements.txt /tmp/ RUN pyenv install 3.11.4 && \ diff --git a/board/safety/safety_tesla.h b/board/safety/safety_tesla.h index 4fa0df84..652161ff 100644 --- a/board/safety/safety_tesla.h +++ b/board/safety/safety_tesla.h @@ -19,6 +19,7 @@ const LongitudinalLimits TESLA_LONG_LIMITS = { const int TESLA_FLAG_POWERTRAIN = 1; const int TESLA_FLAG_LONGITUDINAL_CONTROL = 2; +const int TESLA_FLAG_RAVEN = 4; const CanMsg TESLA_TX_MSGS[] = { {0x488, 0, 4}, // DAS_steeringControl @@ -41,6 +42,16 @@ RxCheck tesla_rx_checks[] = { {.msg = {{0x318, 0, 8, .frequency = 10U}, { 0 }, { 0 }}}, // GTW_carState }; +RxCheck tesla_raven_rx_checks[] = { + {.msg = {{0x2b9, 2, 8, .frequency = 25U}, { 0 }, { 0 }}}, // DAS_control + {.msg = {{0x131, 2, 8, .frequency = 100U}, { 0 }, { 0 }}}, // EPAS3P_sysStatus + {.msg = {{0x108, 0, 8, .frequency = 100U}, { 0 }, { 0 }}}, // DI_torque1 + {.msg = {{0x118, 0, 6, .frequency = 100U}, { 0 }, { 0 }}}, // DI_torque2 + {.msg = {{0x20a, 0, 8, .frequency = 50U}, { 0 }, { 0 }}}, // BrakeMessage + {.msg = {{0x368, 0, 8, .frequency = 10U}, { 0 }, { 0 }}}, // DI_state + {.msg = {{0x318, 0, 8, .frequency = 10U}, { 0 }, { 0 }}}, // GTW_carState +}; + RxCheck tesla_pt_rx_checks[] = { {.msg = {{0x106, 0, 8, .frequency = 100U}, { 0 }, { 0 }}}, // DI_torque1 {.msg = {{0x116, 0, 6, .frequency = 100U}, { 0 }, { 0 }}}, // DI_torque2 @@ -51,6 +62,7 @@ RxCheck tesla_pt_rx_checks[] = { bool tesla_longitudinal = false; bool tesla_powertrain = false; // Are we the second panda intercepting the powertrain bus? +bool tesla_raven = false; bool tesla_stock_aeb = false; @@ -58,16 +70,16 @@ static void tesla_rx_hook(const CANPacket_t *to_push) { int bus = GET_BUS(to_push); int addr = GET_ADDR(to_push); - if(bus == 0) { - if (!tesla_powertrain) { - if(addr == 0x370) { - // Steering angle: (0.1 * val) - 819.2 in deg. - // Store it 1/10 deg to match steering request - int angle_meas_new = (((GET_BYTE(to_push, 4) & 0x3FU) << 8) | GET_BYTE(to_push, 5)) - 8192U; - update_sample(&angle_meas, angle_meas_new); - } + if (!tesla_powertrain) { + if((!tesla_raven && (addr == 0x370) && (bus == 0)) || (tesla_raven && (addr == 0x131) && (bus == 2))) { + // Steering angle: (0.1 * val) - 819.2 in deg. + // Store it 1/10 deg to match steering request + int angle_meas_new = (((GET_BYTE(to_push, 4) & 0x3FU) << 8) | GET_BYTE(to_push, 5)) - 8192U; + update_sample(&angle_meas, angle_meas_new); } + } + if(bus == 0) { if(addr == (tesla_powertrain ? 0x116 : 0x118)) { // Vehicle speed: ((0.05 * val) - 25) * MPH_TO_MPS float speed = (((((GET_BYTE(to_push, 3) & 0x0FU) << 8) | (GET_BYTE(to_push, 2))) * 0.05) - 25) * 0.447; @@ -206,12 +218,15 @@ static int tesla_fwd_hook(int bus_num, int addr) { static safety_config tesla_init(uint16_t param) { tesla_powertrain = GET_FLAG(param, TESLA_FLAG_POWERTRAIN); tesla_longitudinal = GET_FLAG(param, TESLA_FLAG_LONGITUDINAL_CONTROL); + tesla_raven = GET_FLAG(param, TESLA_FLAG_RAVEN); tesla_stock_aeb = false; safety_config ret; if (tesla_powertrain) { ret = BUILD_SAFETY_CFG(tesla_pt_rx_checks, TESLA_PT_TX_MSGS); + } else if (tesla_raven) { + ret = BUILD_SAFETY_CFG(tesla_raven_rx_checks, TESLA_TX_MSGS); } else { ret = BUILD_SAFETY_CFG(tesla_rx_checks, TESLA_TX_MSGS); } diff --git a/python/__init__.py b/python/__init__.py index 6e614775..304aa135 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -214,6 +214,7 @@ class Panda: FLAG_TESLA_POWERTRAIN = 1 FLAG_TESLA_LONG_CONTROL = 2 + FLAG_TESLA_RAVEN = 4 FLAG_VOLKSWAGEN_LONG_CONTROL = 1 diff --git a/tests/safety/test_tesla.py b/tests/safety/test_tesla.py index 0b425ae1..9461ff68 100755 --- a/tests/safety/test_tesla.py +++ b/tests/safety/test_tesla.py @@ -108,6 +108,17 @@ class TestTeslaSteeringSafety(TestTeslaSafety, common.AngleSteeringSafetyTest): self.assertEqual(tx, should_tx) +class TestTeslaRavenSteeringSafety(TestTeslaSteeringSafety): + def setUp(self): + self.packer = CANPackerPanda("tesla_can") + self.safety = libpanda_py.libpanda + self.safety.set_safety_hooks(Panda.SAFETY_TESLA, Panda.FLAG_TESLA_RAVEN) + self.safety.init_tests() + + def _angle_meas_msg(self, angle: float): + values = {"EPAS_internalSAS": angle} + return self.packer.make_can_msg_panda("EPAS3P_sysStatus", 2, values) + class TestTeslaLongitudinalSafety(TestTeslaSafety): def setUp(self): raise unittest.SkipTest