mirror of
https://github.com/infiniteCable2/opendbc.git
synced 2026-06-08 10:54:51 +08:00
128 lines
5.0 KiB
C
128 lines
5.0 KiB
C
#pragma once
|
|
|
|
#include "opendbc/safety/declarations.h"
|
|
#include "opendbc/safety/modes/volkswagen_common.h"
|
|
|
|
|
|
static safety_config volkswagen_mlb_init(uint16_t param) {
|
|
// Transmit of LS_01 is allowed on bus 0 and 2 to keep compatibility with gateway and camera integration
|
|
static const CanMsg VOLKSWAGEN_MLB_STOCK_TX_MSGS[] = {{MSG_HCA_01, 0, 8, .check_relay = true}, {MSG_LDW_02, 0, 8, .check_relay = true},
|
|
{MSG_LS_01, 0, 4, .check_relay = false}, {MSG_LS_01, 2, 4, .check_relay = false}};
|
|
|
|
static RxCheck volkswagen_mlb_rx_checks[] = {
|
|
// TODO: implement checksum validation
|
|
{.msg = {{MSG_ESP_03, 0, 8, 50U, .ignore_checksum = true, .max_counter = 15U, .ignore_quality_flag = true}, { 0 }, { 0 }}},
|
|
{.msg = {{MSG_LH_EPS_03, 0, 8, 100U, .ignore_checksum = true, .max_counter = 15U, .ignore_quality_flag = true}, { 0 }, { 0 }}},
|
|
{.msg = {{MSG_ESP_05, 0, 8, 50U, .ignore_checksum = true, .max_counter = 15U, .ignore_quality_flag = true}, { 0 }, { 0 }}},
|
|
{.msg = {{MSG_TSK_04, 1, 8, 50U, .ignore_checksum = true, .max_counter = 15U, .ignore_quality_flag = true}, { 0 }, { 0 }}},
|
|
{.msg = {{MSG_MOTOR_03, 0, 8, 100U, .ignore_checksum = true, .max_counter = 15U, .ignore_quality_flag = true}, { 0 }, { 0 }}},
|
|
{.msg = {{MSG_LS_01, 0, 4, 10U, .ignore_checksum = true, .max_counter = 15U, .ignore_quality_flag = true}, { 0 }, { 0 }}},
|
|
};
|
|
|
|
SAFETY_UNUSED(param);
|
|
volkswagen_common_init();
|
|
|
|
return BUILD_SAFETY_CFG(volkswagen_mlb_rx_checks, VOLKSWAGEN_MLB_STOCK_TX_MSGS);
|
|
}
|
|
|
|
static void volkswagen_mlb_rx_hook(const CANPacket_t *msg) {
|
|
if (msg->bus == 0U) {
|
|
// Check all wheel speeds for any movement
|
|
// Signals: ESP_03.ESP_[VL|VR|HL|HR]_Radgeschw
|
|
if (msg->addr == MSG_ESP_03) {
|
|
uint32_t speed = 0;
|
|
speed += ((msg->data[3] & 0xFU) << 8) | msg->data[2]; // FL
|
|
speed += (msg->data[4] << 4) | (msg->data[3] >> 4); // FR
|
|
speed += ((msg->data[6] & 0xFU) << 8) | msg->data[5]; // RL
|
|
speed += (msg->data[7] << 4) | (msg->data[6] >> 4); // RR
|
|
vehicle_moving = speed > 0U;
|
|
}
|
|
|
|
// Update driver input torque
|
|
if (msg->addr == MSG_LH_EPS_03) {
|
|
update_sample(&torque_driver, volkswagen_mlb_mqb_driver_input_torque(msg));
|
|
}
|
|
|
|
if (msg->addr == MSG_LS_01) {
|
|
// Always exit controls on rising edge of Cancel
|
|
// Signal: LS_01.LS_Abbrechen
|
|
if (GET_BIT(msg, 13U)) {
|
|
controls_allowed = false;
|
|
}
|
|
}
|
|
|
|
// Signal: Motor_03.MO_Fahrpedalrohwert_01
|
|
// Signal: Motor_03.MO_Fahrer_bremst
|
|
if (msg->addr == MSG_MOTOR_03) {
|
|
gas_pressed = msg->data[6] != 0U;
|
|
volkswagen_brake_pedal_switch = GET_BIT(msg, 35U);
|
|
}
|
|
|
|
if (msg->addr == MSG_ESP_05) {
|
|
volkswagen_brake_pressure_detected = GET_BIT(msg, 26U);
|
|
}
|
|
|
|
brake_pressed = volkswagen_brake_pedal_switch || volkswagen_brake_pressure_detected;
|
|
|
|
}
|
|
|
|
if (msg->bus == 1U) {
|
|
if (msg->addr == MSG_TSK_04) {
|
|
// When using stock ACC, enter controls on rising edge of stock ACC engage, exit on disengage
|
|
// Signal: TSK_04.TSK_Status_GRA_ACC_02
|
|
int acc_status = (msg->data[7] & 0xC0U) >> 6;
|
|
bool cruise_engaged = (acc_status == 1) || (acc_status == 2);
|
|
|
|
pcm_cruise_check(cruise_engaged);
|
|
}
|
|
}
|
|
}
|
|
|
|
static bool volkswagen_mlb_tx_hook(const CANPacket_t *msg) {
|
|
// lateral limits
|
|
const TorqueSteeringLimits VOLKSWAGEN_MLB_STEERING_LIMITS = {
|
|
.max_torque = 300, // 3.0 Nm (EPS side max of 3.0Nm with fault if violated)
|
|
.max_rt_delta = 169, // 10 max rate up * 50Hz send rate * 250000 RT interval / 1000000 = 112.5 ; 112.5 * 1.5 for safety pad = 168.75
|
|
.max_rate_up = 9, // 5.0 Nm/s RoC limit (EPS rack has own soft-limit of 5.0 Nm/s)
|
|
.max_rate_down = 10, // 5.0 Nm/s RoC limit (EPS rack has own soft-limit of 5.0 Nm/s)
|
|
.driver_torque_allowance = 60,
|
|
.driver_torque_multiplier = 3,
|
|
.type = TorqueDriverLimited,
|
|
};
|
|
|
|
bool tx = true;
|
|
|
|
// Safety check for HCA_01 Heading Control Assist torque
|
|
if (msg->addr == MSG_HCA_01) {
|
|
int desired_torque = volkswagen_mlb_mqb_steering_control_torque(msg);
|
|
|
|
int steer_status = msg->data[4] & 0xFU;
|
|
bool steer_req = (steer_status == 5) || (steer_status == 7);
|
|
|
|
if (steer_torque_cmd_checks(desired_torque, steer_req, VOLKSWAGEN_MLB_STEERING_LIMITS)) {
|
|
tx = false;
|
|
}
|
|
}
|
|
|
|
// FORCE CANCEL: ensuring that only the cancel button press is sent when controls are off.
|
|
// This avoids unintended engagements while still allowing resume spam
|
|
if ((msg->addr == MSG_LS_01) && !controls_allowed) {
|
|
// disallow resume and set: bits 16 and 19
|
|
if (GET_BIT(msg, 16U) || GET_BIT(msg, 19U)) {
|
|
tx = false;
|
|
}
|
|
}
|
|
|
|
return tx;
|
|
}
|
|
|
|
// TODO: rename these functions to MXB or something
|
|
const safety_hooks volkswagen_mlb_hooks = {
|
|
.init = volkswagen_mlb_init,
|
|
.rx = volkswagen_mlb_rx_hook,
|
|
.tx = volkswagen_mlb_tx_hook,
|
|
.get_counter = volkswagen_mqb_meb_get_counter,
|
|
.get_checksum = volkswagen_mqb_meb_get_checksum,
|
|
.compute_checksum = volkswagen_mqb_meb_compute_crc,
|
|
};
|