@ -1,32 +1,34 @@
struct sample_t torque_meas ; // last 3 motor torques produced by the eps
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?
// global torque limit
// global torque limit
const int MAX_TORQUE = 1500 ; // max torque cmd allowed ever
const int TOYOTA_ MAX_TORQUE = 1500 ; // max torque cmd allowed ever
// rate based torque limit + stay within actually applied
// rate based torque limit + stay within actually applied
// packet is sent at 100hz, so this limit is 1000/sec
// packet is sent at 100hz, so this limit is 1000/sec
const int MAX_RATE_UP = 10 ; // ramp up slow
const int TOYOTA_ MAX_RATE_UP = 10 ; // ramp up slow
const int MAX_RATE_DOWN = 25 ; // ramp down fast
const int TOYOTA_ MAX_RATE_DOWN = 25 ; // ramp down fast
const int MAX_TORQUE_ERROR = 350 ; // max torque cmd in excess of torque motor
const int TOYOTA_ MAX_TORQUE_ERROR = 350 ; // max torque cmd in excess of torque motor
// real time torque limit to prevent controls spamming
// real time torque limit to prevent controls spamming
// the real time limit is 1500/sec
// the real time limit is 1500/sec
const int MAX_RT_DELTA = 375 ; // max delta torque allowed for real time checks
const int TOYOTA_ MAX_RT_DELTA = 375 ; // max delta torque allowed for real time checks
const int RT_INTERVAL = 250000 ; // 250ms between real time checks
const int TOYOTA_ RT_INTERVAL = 250000 ; // 250ms between real time checks
// longitudinal limits
// longitudinal limits
const int MAX_ACCEL = 1500 ; // 1.5 m/s2
const int TOYOTA_ MAX_ACCEL = 1500 ; // 1.5 m/s2
const int MIN_ACCEL = - 3000 ; // 3.0 m/s2
const int TOYOTA_ MIN_ACCEL = - 3000 ; // 3.0 m/s2
// global actuation limit state
// global actuation limit state
int actuation_limits = 1 ; // by default steer limits are imposed
int toyota_ actuation_limits = 1 ; // by default steer limits are imposed
int dbc_eps_torque_factor = 100 ; // conversion factor for STEER_TORQUE_EPS in %: see dbc file
int toyota_ dbc_eps_torque_factor = 100 ; // conversion factor for STEER_TORQUE_EPS in %: see dbc file
// state of torque limits
// state of torque limits
int desired_torque_last = 0 ; // last desired steer torque
int toyota_desired_torque_last = 0 ; // last desired steer torque
int rt_torque_last = 0 ; // last desired torque for real time check
int toyota_rt_torque_last = 0 ; // last desired torque for real time check
uint32_t ts_last = 0 ;
uint32_t toyota_ts_last = 0 ;
int cruise_engaged_last = 0 ; // cruise state
int toyota_cruise_engaged_last = 0 ; // cruise state
struct sample_t toyota_torque_meas ; // last 3 motor torques produced by the eps
static void toyota_rx_hook ( CAN_FIFOMailBox_TypeDef * to_push ) {
static void toyota_rx_hook ( CAN_FIFOMailBox_TypeDef * to_push ) {
@ -36,26 +38,38 @@ static void toyota_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
torque_meas_new = to_signed ( torque_meas_new , 16 ) ;
torque_meas_new = to_signed ( torque_meas_new , 16 ) ;
// scale by dbc_factor
// scale by dbc_factor
torque_meas_new = ( torque_meas_new * dbc_eps_torque_factor ) / 100 ;
torque_meas_new = ( torque_meas_new * toyota_ dbc_eps_torque_factor) / 100 ;
// increase torque_meas by 1 to be conservative on rounding
// increase torque_meas by 1 to be conservative on rounding
torque_meas_new + = ( torque_meas_new > 0 ? 1 : - 1 ) ;
torque_meas_new + = ( torque_meas_new > 0 ? 1 : - 1 ) ;
// update array of sample
// update array of sample
update_sample ( & torque_meas , torque_meas_new ) ;
update_sample ( & toyota_to rque_meas , torque_meas_new ) ;
}
}
// enter controls on rising edge of ACC, exit controls on ACC off
// enter controls on rising edge of ACC, exit controls on ACC off
if ( ( to_push - > RIR > > 21 ) = = 0x1D2 ) {
if ( ( to_push - > RIR > > 21 ) = = 0x1D2 ) {
// 4 bits: 55-52
// 4 bits: 55-52
int cruise_engaged = to_push - > RDHR & 0xF00000 ;
int cruise_engaged = to_push - > RDHR & 0xF00000 ;
if ( cruise_engaged & & ! cruise_engaged_last ) {
if ( cruise_engaged & & ! toyota_ cruise_engaged_last) {
controls_allowed = 1 ;
controls_allowed = 1 ;
} else if ( ! cruise_engaged ) {
} else if ( ! cruise_engaged ) {
controls_allowed = 0 ;
controls_allowed = 0 ;
}
}
cruise_engaged_last = cruise_engaged ;
toyota_ cruise_engaged_last = cruise_engaged ;
}
}
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 ;
}
// 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 ) {
static int toyota_tx_hook ( CAN_FIFOMailBox_TypeDef * to_send ) {
@ -70,8 +84,8 @@ static int toyota_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
if ( ( to_send - > RIR > > 21 ) = = 0x343 ) {
if ( ( to_send - > RIR > > 21 ) = = 0x343 ) {
int desired_accel = ( ( to_send - > RDLR & 0xFF ) < < 8 ) | ( ( to_send - > RDLR > > 8 ) & 0xFF ) ;
int desired_accel = ( ( to_send - > RDLR & 0xFF ) < < 8 ) | ( ( to_send - > RDLR > > 8 ) & 0xFF ) ;
desired_accel = to_signed ( desired_accel , 16 ) ;
desired_accel = to_signed ( desired_accel , 16 ) ;
if ( controls_allowed & & actuation_limits ) {
if ( controls_allowed & & toyota_ actuation_limits) {
int violation = max_limit_check ( desired_accel , MAX_ACCEL , MIN_ACCEL ) ;
int violation = max_limit_check ( desired_accel , TOYOTA_ MAX_ACCEL, TOYOTA_ MIN_ACCEL) ;
if ( violation ) return 0 ;
if ( violation ) return 0 ;
} else if ( ! controls_allowed & & ( desired_accel ! = 0 ) ) {
} else if ( ! controls_allowed & & ( desired_accel ! = 0 ) ) {
return 0 ;
return 0 ;
@ -87,25 +101,26 @@ static int toyota_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
uint32_t ts = TIM2 - > CNT ;
uint32_t ts = TIM2 - > CNT ;
// only check if controls are allowed and actuation_limits are imposed
// only check if controls are allowed and actuation_limits are imposed
if ( controls_allowed & & actuation_limits ) {
if ( controls_allowed & & toyota_ actuation_limits) {
// *** global torque limit check ***
// *** global torque limit check ***
violation | = max_limit_check ( desired_torque , MAX_TORQUE , - MAX_TORQUE ) ;
violation | = max_limit_check ( desired_torque , TOYOTA_ MAX_TORQUE, - TOYOTA_ MAX_TORQUE) ;
// *** torque rate limit check ***
// *** torque rate limit check ***
violation | = dist_to_meas_check ( desired_torque , desired_torque_last , & torque_meas , MAX_RATE_UP , MAX_RATE_DOWN , MAX_TORQUE_ERROR ) ;
violation | = dist_to_meas_check ( desired_torque , toyota_desired_torque_last ,
& toyota_torque_meas , TOYOTA_MAX_RATE_UP , TOYOTA_MAX_RATE_DOWN , TOYOTA_MAX_TORQUE_ERROR ) ;
// used next time
// used next time
desired_torque_last = desired_torque ;
toyota_ desired_torque_last = desired_torque ;
// *** torque real time rate limit check ***
// *** torque real time rate limit check ***
violation | = rt_rate_limit_check ( desired_torque , rt_torque_last , MAX_RT_DELTA ) ;
violation | = rt_rate_limit_check ( desired_torque , toyota_ rt_torque_last, TOYOTA_ MAX_RT_DELTA) ;
// every RT_INTERVAL set the new limits
// every RT_INTERVAL set the new limits
uint32_t ts_elapsed = get_ts_elapsed ( ts , ts_last ) ;
uint32_t ts_elapsed = get_ts_elapsed ( ts , toyota_t s_last ) ;
if ( ts_elapsed > RT_INTERVAL ) {
if ( ts_elapsed > TOYOTA_ RT_INTERVAL) {
rt_torque_last = desired_torque ;
toyota_ rt_torque_last = desired_torque ;
ts_last = ts ;
toyota_t s_last = ts ;
}
}
}
}
@ -116,9 +131,9 @@ static int toyota_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
// reset to 0 if either controls is not allowed or there's a violation
// reset to 0 if either controls is not allowed or there's a violation
if ( violation | | ! controls_allowed ) {
if ( violation | | ! controls_allowed ) {
desired_torque_last = 0 ;
toyota_ desired_torque_last = 0 ;
rt_torque_last = 0 ;
toyota_ rt_torque_last = 0 ;
ts_last = ts ;
toyota_t s_last = ts ;
}
}
if ( violation ) {
if ( violation ) {
@ -138,11 +153,19 @@ static int toyota_tx_lin_hook(int lin_num, uint8_t *data, int len) {
static void toyota_init ( int16_t param ) {
static void toyota_init ( int16_t param ) {
controls_allowed = 0 ;
controls_allowed = 0 ;
actuation_limits = 1 ;
toyota_actuation_limits = 1 ;
dbc_eps_torque_factor = param ;
toyota_giraffe_switch_1 = 0 ;
toyota_dbc_eps_torque_factor = param ;
}
}
static int toyota_fwd_hook ( int bus_num , CAN_FIFOMailBox_TypeDef * to_fwd ) {
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 ) {
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 ) ;
}
return - 1 ;
return - 1 ;
}
}
@ -157,8 +180,9 @@ const safety_hooks toyota_hooks = {
static void toyota_nolimits_init ( int16_t param ) {
static void toyota_nolimits_init ( int16_t param ) {
controls_allowed = 0 ;
controls_allowed = 0 ;
actuation_limits = 0 ;
toyota_actuation_limits = 0 ;
dbc_eps_torque_factor = param ;
toyota_giraffe_switch_1 = 0 ;
toyota_dbc_eps_torque_factor = param ;
}
}
const safety_hooks toyota_nolimits_hooks = {
const safety_hooks toyota_nolimits_hooks = {