Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

restore hyundai safety & create community_safety #156

Merged
merged 5 commits into from
Sep 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions panda/board/safety.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "safety/safety_nissan.h"
#include "safety/safety_volkswagen.h"
#include "safety/safety_elm327.h"
#include "safety/safety_hyundai_community.h"

// from cereal.car.CarParams.SafetyModel
#define SAFETY_SILENT 0U
Expand Down Expand Up @@ -249,6 +250,7 @@ const safety_hook_config safety_hook_registry[] = {
{SAFETY_NISSAN, &nissan_hooks},
{SAFETY_NOOUTPUT, &nooutput_hooks},
{SAFETY_HYUNDAI_LEGACY, &hyundai_legacy_hooks},
{SAFETY_HYUNDAI_COMMUNITY, &hyundai_community_hooks},
#ifdef ALLOW_DEBUG
{SAFETY_MAZDA, &mazda_hooks},
{SAFETY_SUBARU_LEGACY, &subaru_legacy_hooks},
Expand Down
202 changes: 28 additions & 174 deletions panda/board/safety/safety_hyundai.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,15 @@ const int HYUNDAI_MAX_RATE_DOWN = 7;
const int HYUNDAI_DRIVER_TORQUE_ALLOWANCE = 50;
const int HYUNDAI_DRIVER_TORQUE_FACTOR = 2;
const int HYUNDAI_STANDSTILL_THRSLD = 30; // ~1kph
bool hyundai_has_scc = false;
int OP_LKAS_live = 0;
int OP_MDPS_live = 0;
int OP_CLU_live = 0;
int OP_SCC_live = 0;
int car_SCC_live = 0;
int OP_EMS_live = 0;
int hyundai_mdps_bus = -1;
bool hyundai_LCAN_on_bus1 = false;
bool hyundai_forward_bus1 = false;
const CanMsg HYUNDAI_TX_MSGS[] = {
{832, 0, 8}, {832, 1, 8}, // LKAS11 Bus 0, 1
{1265, 0, 4}, {1265, 1, 4}, {1265, 2, 4}, // CLU11 Bus 0, 1, 2
{832, 0, 8}, // LKAS11 Bus 0
{1265, 0, 4}, // CLU11 Bus 0
{1157, 0, 4}, // LFAHDA_MFC Bus 0
{593, 2, 8}, // MDPS12, Bus 2
{1056, 0, 8}, // SCC11, Bus 0
{1057, 0, 8}, // SCC12, Bus 0
{1290, 0, 8}, // SCC13, Bus 0
{905, 0, 8}, // SCC14, Bus 0
{1186, 0, 8}, // 4a2SCC, Bus 0
{790, 1, 8}, // EMS11, Bus 1
{912, 0, 7}, {912,1, 7}, // SPAS11, Bus 0, 1
{1268, 0, 8}, {1268,1, 8}, // SPAS12, Bus 0, 1
// {1056, 0, 8}, // SCC11, Bus 0
// {1057, 0, 8}, // SCC12, Bus 0
// {1290, 0, 8}, // SCC13, Bus 0
// {905, 0, 8}, // SCC14, Bus 0
// {1186, 0, 8} // 4a2SCC, Bus 0
};

// TODO: missing checksum for wheel speeds message,worst failure case is
Expand All @@ -45,8 +31,8 @@ const int HYUNDAI_RX_CHECK_LEN = sizeof(hyundai_rx_checks) / sizeof(hyundai_rx_c
AddrCheckStruct hyundai_legacy_rx_checks[] = {
{.msg = {{608, 0, 8, .check_checksum = true, .max_counter = 3U, .expected_timestep = 10000U},
{881, 0, 8, .expected_timestep = 10000U}}},
{.msg = {{902, 0, 8, .expected_timestep = 20000U}}},
{.msg = {{916, 0, 8, .expected_timestep = 20000U}}},
{.msg = {{902, 0, 8, .expected_timestep = 10000U}}},
{.msg = {{916, 0, 8, .expected_timestep = 10000U}}},
{.msg = {{1057, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U}}},
};
const int HYUNDAI_LEGACY_RX_CHECK_LEN = sizeof(hyundai_legacy_rx_checks) / sizeof(hyundai_legacy_rx_checks[0]);
Expand Down Expand Up @@ -105,8 +91,6 @@ static uint8_t hyundai_compute_checksum(CAN_FIFOMailBox_TypeDef *to_push) {
static int hyundai_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {

bool valid;
int addr = GET_ADDR(to_push);
int bus = GET_BUS(to_push);
if (hyundai_legacy) {
valid = addr_safety_check(to_push, hyundai_legacy_rx_checks, HYUNDAI_LEGACY_RX_CHECK_LEN,
hyundai_get_checksum, hyundai_compute_checksum,
Expand All @@ -118,45 +102,17 @@ static int hyundai_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
hyundai_get_counter);
}

// check if we have a LCAN on Bus1
if (bus == 1 && (addr == 1296 || addr == 524)) {
if (hyundai_forward_bus1 || !hyundai_LCAN_on_bus1) {
hyundai_LCAN_on_bus1 = true;
hyundai_forward_bus1 = false;
}
}
if (bus == 1 && hyundai_LCAN_on_bus1) {valid = false;}

// check MDPS on Bus
if ((addr == 593 || addr == 897) && hyundai_mdps_bus != bus) {
if (bus == 0){
hyundai_mdps_bus = bus;
if (!hyundai_forward_bus1 && board_has_obd()) {
current_board->set_can_mode(CAN_MODE_NORMAL);
}
} else if (bus == 1 && !hyundai_LCAN_on_bus1) {
hyundai_mdps_bus = bus;
hyundai_forward_bus1 = true;
}
}
// check if we have a SCC on Bus1 and LCAN not on the bus
if (bus == 1 && addr == 1057 && !hyundai_LCAN_on_bus1) {
if (!hyundai_forward_bus1) {
hyundai_forward_bus1 = true;
}
}
if (valid && (GET_BUS(to_push) == 0)) {
int addr = GET_ADDR(to_push);

if (valid) {
if (addr == 593 && bus == hyundai_mdps_bus) {
if (addr == 593) {
int torque_driver_new = ((GET_BYTES_04(to_push) & 0x7ff) * 0.79) - 808; // scale down new driver torque signal to match previous one
// update array of samples
update_sample(&torque_driver, torque_driver_new);
}

// enter controls on rising edge of ACC, exit controls on ACC off
if (addr == 1057 && OP_SCC_live) { // for cars with long control
hyundai_has_scc = true;
car_SCC_live = 50;
if (addr == 1057) {
// 2 bits: 13-14
int cruise_engaged = (GET_BYTES_04(to_push) >> 13) & 0x3;
if (cruise_engaged && !cruise_engaged_prev) {
Expand All @@ -167,64 +123,28 @@ static int hyundai_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
}
cruise_engaged_prev = cruise_engaged;
}
if (addr == 1056 && !OP_SCC_live) { // for cars without long control
hyundai_has_scc = true;
// 2 bits: 13-14
int cruise_engaged = GET_BYTES_04(to_push) & 0x1; // ACC main_on signal
if (cruise_engaged && !cruise_engaged_prev) {
controls_allowed = 1;
}
if (!cruise_engaged) {
controls_allowed = 0;
}
cruise_engaged_prev = cruise_engaged;
}
// cruise control for car without SCC
if (addr == 608 && bus == 0 && !hyundai_has_scc && !OP_SCC_live) {
// bit 25
int cruise_engaged = (GET_BYTES_04(to_push) >> 25 & 0x1); // ACC main_on signal
if (cruise_engaged && !cruise_engaged_prev) {
controls_allowed = 1;
}
if (!cruise_engaged) {
controls_allowed = 0;
}
cruise_engaged_prev = cruise_engaged;
}
// engage for Cruise control disabled car
if (addr == 1265 && bus == 0 && OP_SCC_live && !car_SCC_live) {
// first byte
int cruise_button = (GET_BYTES_04(to_push) & 0x7);
// enable on both accel and decel buttons falling edge
if (!cruise_button && (cruise_engaged_prev == 1 || cruise_engaged_prev == 2)) {
controls_allowed = 1;
}
// disable on cancel rising edge
if (cruise_button == 4) {
controls_allowed = 0;

if ((addr == 608) || (hyundai_legacy && (addr == 881))) {
if (addr == 608) {
gas_pressed = (GET_BYTE(to_push, 7) >> 6) != 0;
} else {
gas_pressed = (((GET_BYTE(to_push, 4) & 0x7F) << 1) | GET_BYTE(to_push, 3) >> 7) != 0;
}
cruise_engaged_prev = cruise_button;
}
// exit controls on rising edge of gas press for cars with long control
if (addr == 608 && OP_SCC_live && bus == 0) {
gas_pressed = (GET_BYTE(to_push, 7) >> 6) != 0;
}
if (addr == 881 && hyundai_legacy && OP_SCC_live && bus == 0) {
gas_pressed = (((GET_BYTE(to_push, 4) & 0x7F) << 1) | GET_BYTE(to_push, 3) >> 7) != 0;
}

// sample wheel speed, averaging opposite corners
if (addr == 902 && bus == 0) {
if (addr == 902) {
int hyundai_speed = GET_BYTES_04(to_push) & 0x3FFF; // FL
hyundai_speed += (GET_BYTES_48(to_push) >> 16) & 0x3FFF; // RL
hyundai_speed /= 2;
vehicle_moving = hyundai_speed > HYUNDAI_STANDSTILL_THRSLD;
}
// exit controls on rising edge of brake press for cars with long control
if (addr == 916 && OP_SCC_live && bus == 0) {

if (addr == 916) {
brake_pressed = (GET_BYTE(to_push, 6) >> 7) != 0;
}

generic_rx_checks((addr == 832 && bus == 0));
generic_rx_checks((addr == 832));
}
return valid;
}
Expand All @@ -233,7 +153,6 @@ static int hyundai_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {

int tx = 1;
int addr = GET_ADDR(to_send);
int bus = GET_BUS(to_send);

if (!msg_allowed(to_send, HYUNDAI_TX_MSGS, sizeof(HYUNDAI_TX_MSGS)/sizeof(HYUNDAI_TX_MSGS[0]))) {
tx = 0;
Expand All @@ -245,7 +164,6 @@ static int hyundai_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {

// LKA STEER: safety check
if (addr == 832) {
OP_LKAS_live = 20;
int desired_torque = ((GET_BYTES_04(to_send) >> 16) & 0x7ff) - 1024;
uint32_t ts = TIM2->CNT;
bool violation = 0;
Expand Down Expand Up @@ -280,7 +198,7 @@ static int hyundai_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
}

// reset to 0 if either controls is not allowed or there's a violation
if (!controls_allowed) { // a reset worsen the issue of Panda blocking some valid LKAS messages
if (violation || !controls_allowed) {
desired_torque_last = 0;
rt_torque_last = 0;
ts_last = ts;
Expand All @@ -294,18 +212,12 @@ static int hyundai_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
// FORCE CANCEL: safety check only relevant when spamming the cancel button.
// ensuring that only the cancel button press is sent (VAL 4) when controls are off.
// This avoids unintended engagements while still allowing resume spam
//allow clu11 to be sent to MDPS if MDPS is not on bus0
if (addr == 1265 && !controls_allowed && (bus != hyundai_mdps_bus && hyundai_mdps_bus == 1)) {
if ((addr == 1265) && !controls_allowed) {
if ((GET_BYTES_04(to_send) & 0x7) != 4) {
tx = 0;
}
}

if (addr == 593) {OP_MDPS_live = 20;}
if (addr == 1265 && bus == 1) {OP_CLU_live = 20;} // only count mesage created for MDPS
if (addr == 1057) {OP_SCC_live = 20; if (car_SCC_live > 0) {car_SCC_live -= 1;}}
if (addr == 790) {OP_EMS_live = 20;}

// 1 allows the message through
return tx;
}
Expand All @@ -314,62 +226,12 @@ static int hyundai_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {

int bus_fwd = -1;
int addr = GET_ADDR(to_fwd);
int fwd_to_bus1 = -1;
if (hyundai_forward_bus1){fwd_to_bus1 = 1;}

// forward cam to ccan and viceversa, except lkas cmd
if (!relay_malfunction) {
if (bus_num == 0) {
if (!OP_CLU_live || addr != 1265 || hyundai_mdps_bus == 0) {
if (!OP_MDPS_live || addr != 593) {
if (!OP_EMS_live || addr != 790) {
bus_fwd = hyundai_forward_bus1 ? 12 : 2;
} else {
bus_fwd = 2; // EON create EMS11 for MDPS
OP_EMS_live -= 1;
}
} else {
bus_fwd = fwd_to_bus1; // EON create MDPS for LKAS
OP_MDPS_live -= 1;
}
} else {
bus_fwd = 2; // EON create CLU12 for MDPS
OP_CLU_live -= 1;
}
bus_fwd = 2;
}
if (bus_num == 1 && hyundai_forward_bus1) {
if (!OP_MDPS_live || addr != 593) {
if (!OP_SCC_live || (addr != 1056 && addr != 1057 && addr != 1290 && addr != 905)) {
bus_fwd = 20;
} else {
bus_fwd = 2; // EON create SCC11 SCC12 SCC13 SCC14 for Car
OP_SCC_live -= 1;
}
} else {
bus_fwd = 0; // EON create MDPS for LKAS
OP_MDPS_live -= 1;
}
}
if (bus_num == 2) {
if (!OP_LKAS_live || (addr != 832 && addr != 1157)) {
if (!OP_SCC_live || (addr != 1056 && addr != 1057 && addr != 1290 && addr != 905)) {
bus_fwd = hyundai_forward_bus1 ? 10 : 0;
} else {
bus_fwd = fwd_to_bus1; // EON create SCC12 for Car
OP_SCC_live -= 1;
}
} else if (hyundai_mdps_bus == 0) {
bus_fwd = fwd_to_bus1; // EON create LKAS and LFA for Car
OP_LKAS_live -= 1;
} else {
OP_LKAS_live -= 1; // EON create LKAS and LFA for Car and MDPS
}
}
} else {
if (bus_num == 0) {
bus_fwd = fwd_to_bus1;
}
if (bus_num == 1 && hyundai_forward_bus1) {
if ((bus_num == 2) && (addr != 832) && (addr != 1157)) {
bus_fwd = 0;
}
}
Expand All @@ -382,10 +244,6 @@ static void hyundai_init(int16_t param) {
relay_malfunction_reset();

hyundai_legacy = false;

if (board_has_obd()) {
current_board->set_can_mode(CAN_MODE_OBD_CAN2);
}
}

static void hyundai_legacy_init(int16_t param) {
Expand All @@ -394,10 +252,6 @@ static void hyundai_legacy_init(int16_t param) {
relay_malfunction_reset();

hyundai_legacy = true;

if (board_has_obd()) {
current_board->set_can_mode(CAN_MODE_OBD_CAN2);
}
}

const safety_hooks hyundai_hooks = {
Expand Down
Loading