panda/board/safety/safety_hyundai.h

158 lines
4.7 KiB
C
Raw Normal View History

const int HYUNDAI_MAX_STEER = 255; // like stock
2018-08-29 20:30:14 -06:00
const int HYUNDAI_MAX_RT_DELTA = 112; // max delta torque allowed for real time checks
2019-06-14 11:57:14 -06:00
const uint32_t HYUNDAI_RT_INTERVAL = 250000; // 250ms between real time checks
2018-08-28 21:05:58 -06:00
const int HYUNDAI_MAX_RATE_UP = 3;
const int HYUNDAI_MAX_RATE_DOWN = 7;
const int HYUNDAI_DRIVER_TORQUE_ALLOWANCE = 50;
2018-08-28 21:05:58 -06:00
const int HYUNDAI_DRIVER_TORQUE_FACTOR = 2;
2019-06-12 21:12:48 -06:00
bool hyundai_camera_detected = 0;
bool hyundai_giraffe_switch_2 = 0; // is giraffe switch 2 high?
int hyundai_camera_bus = 0;
int hyundai_rt_torque_last = 0;
int hyundai_desired_torque_last = 0;
int hyundai_cruise_engaged_last = 0;
uint32_t hyundai_ts_last = 0;
struct sample_t hyundai_torque_driver; // last few driver torques measured
static void hyundai_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
int bus = GET_BUS(to_push);
int addr = GET_ADDR(to_push);
if (addr == 897) {
2018-08-29 20:23:49 -06:00
int torque_driver_new = ((to_push->RDLR >> 11) & 0xfff) - 2048;
// update array of samples
update_sample(&hyundai_torque_driver, torque_driver_new);
}
// check if stock camera ECU is still online
if ((bus == 0) && (addr == 832)) {
hyundai_camera_detected = 1;
controls_allowed = 0;
}
// Find out which bus the camera is on
if (addr == 832) {
2018-09-05 17:08:42 -06:00
hyundai_camera_bus = bus;
}
// enter controls on rising edge of ACC, exit controls on ACC off
if (addr == 1057) {
// 2 bits: 13-14
int cruise_engaged = (to_push->RDLR >> 13) & 0x3;
if (cruise_engaged && !hyundai_cruise_engaged_last) {
controls_allowed = 1;
} else if (!cruise_engaged) {
controls_allowed = 0;
}
hyundai_cruise_engaged_last = cruise_engaged;
}
2018-08-30 12:53:52 -06:00
// 832 is lkas cmd. If it is on camera bus, then giraffe switch 2 is high
if ((addr == 832) && (bus == hyundai_camera_bus) && (hyundai_camera_bus != 0)) {
2018-08-30 12:53:52 -06:00
hyundai_giraffe_switch_2 = 1;
}
}
static int hyundai_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
int tx = 1;
int addr = GET_ADDR(to_send);
// There can be only one! (camera)
if (hyundai_camera_detected) {
tx = 0;
}
// LKA STEER: safety check
if (addr == 832) {
2018-08-29 20:23:49 -06:00
int desired_torque = ((to_send->RDLR >> 16) & 0x7ff) - 1024;
uint32_t ts = TIM2->CNT;
2019-06-12 21:12:48 -06:00
bool violation = 0;
if (controls_allowed) {
// *** global torque limit check ***
violation |= max_limit_check(desired_torque, HYUNDAI_MAX_STEER, -HYUNDAI_MAX_STEER);
// *** torque rate limit check ***
violation |= driver_limit_check(desired_torque, hyundai_desired_torque_last, &hyundai_torque_driver,
HYUNDAI_MAX_STEER, HYUNDAI_MAX_RATE_UP, HYUNDAI_MAX_RATE_DOWN,
HYUNDAI_DRIVER_TORQUE_ALLOWANCE, HYUNDAI_DRIVER_TORQUE_FACTOR);
// used next time
hyundai_desired_torque_last = desired_torque;
// *** torque real time rate limit check ***
violation |= rt_rate_limit_check(desired_torque, hyundai_rt_torque_last, HYUNDAI_MAX_RT_DELTA);
// every RT_INTERVAL set the new limits
uint32_t ts_elapsed = get_ts_elapsed(ts, hyundai_ts_last);
if (ts_elapsed > HYUNDAI_RT_INTERVAL) {
hyundai_rt_torque_last = desired_torque;
hyundai_ts_last = ts;
}
}
// no torque if controls is not allowed
if (!controls_allowed && (desired_torque != 0)) {
violation = 1;
}
// reset to 0 if either controls is not allowed or there's a violation
if (violation || !controls_allowed) {
hyundai_desired_torque_last = 0;
hyundai_rt_torque_last = 0;
hyundai_ts_last = ts;
}
if (violation) {
tx = 0;
}
}
// 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
// TODO: fix bug preventing the button msg to be fwd'd on bus 2
//if ((addr == 1265) && !controls_allowed && (bus == 0) {
// if ((to_send->RDLR & 0x7) != 4) {
// tx = 0;
// }
//}
// 1 allows the message through
return tx;
}
2018-08-30 12:53:52 -06:00
static int hyundai_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
int bus_fwd = -1;
2018-08-30 12:53:52 -06:00
// forward cam to ccan and viceversa, except lkas cmd
if (hyundai_giraffe_switch_2) {
if (bus_num == 0) {
bus_fwd = hyundai_camera_bus;
} else if (bus_num == hyundai_camera_bus) {
int addr = GET_ADDR(to_fwd);
if (addr != 832) {
bus_fwd = 0;
}
}
2018-08-30 12:53:52 -06:00
}
return bus_fwd;
2018-08-30 12:53:52 -06:00
}
static void hyundai_init(int16_t param) {
controls_allowed = 0;
hyundai_giraffe_switch_2 = 0;
}
const safety_hooks hyundai_hooks = {
2018-08-30 12:53:52 -06:00
.init = hyundai_init,
.rx = hyundai_rx_hook,
.tx = hyundai_tx_hook,
.tx_lin = nooutput_tx_lin_hook,
.ignition = default_ign_hook,
2018-08-30 12:53:52 -06:00
.fwd = hyundai_fwd_hook,
};