Skip to content

Commit 4368748

Browse files
authored
WIP: Toyota brake check. (#459)
* Toyota brake check with safety tests
1 parent 2ef996f commit 4368748

File tree

5 files changed

+79
-17
lines changed

5 files changed

+79
-17
lines changed

board/drivers/llcan.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ bool llcan_set_speed(CAN_TypeDef *CAN_obj, uint32_t speed, bool loopback, bool s
5252
void llcan_init(CAN_TypeDef *CAN_obj) {
5353
// Enter init mode
5454
register_set_bits(&(CAN_obj->FMR), CAN_FMR_FINIT);
55-
55+
5656
// Wait for INAK bit to be set
5757
while(((CAN_obj->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)) {}
5858

board/safety/safety_toyota.h

+39-12
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,19 @@ const uint32_t TOYOTA_RT_INTERVAL = 250000; // 250ms between real time checks
1616
const int TOYOTA_MAX_ACCEL = 1500; // 1.5 m/s2
1717
const int TOYOTA_MIN_ACCEL = -3000; // 3.0 m/s2
1818

19-
const int TOYOTA_GAS_INTERCEPTOR_THRESHOLD = 475; // ratio between offset and gain from dbc file
19+
const int TOYOTA_STANDSTILL_THRSLD = 100; // 1kph
20+
const int TOYOTA_GAS_INTERCEPTOR_THRSLD = 475; // ratio between offset and gain from dbc file
2021

2122
const AddrBus TOYOTA_TX_MSGS[] = {{0x283, 0}, {0x2E6, 0}, {0x2E7, 0}, {0x33E, 0}, {0x344, 0}, {0x365, 0}, {0x366, 0}, {0x4CB, 0}, // DSU bus 0
2223
{0x128, 1}, {0x141, 1}, {0x160, 1}, {0x161, 1}, {0x470, 1}, // DSU bus 1
2324
{0x2E4, 0}, {0x411, 0}, {0x412, 0}, {0x343, 0}, {0x1D2, 0}, // LKAS + ACC
2425
{0x200, 0}, {0x750, 0}}; // interceptor + Blindspot monitor
2526

2627
AddrCheckStruct toyota_rx_checks[] = {
27-
{.addr = {0x260}, .bus = 0, .check_checksum = true, .max_counter = 0U, .expected_timestep = 20000U},
28-
{.addr = {0x1D2}, .bus = 0, .check_checksum = true, .max_counter = 0U, .expected_timestep = 30000U},
28+
{.addr = { 0xaa}, .bus = 0, .check_checksum = false, .expected_timestep = 12000U},
29+
{.addr = {0x260}, .bus = 0, .check_checksum = true, .expected_timestep = 20000U},
30+
{.addr = {0x1D2}, .bus = 0, .check_checksum = true, .expected_timestep = 30000U},
31+
{.addr = {0x224, 0x226}, .bus = 0, .check_checksum = false, .expected_timestep = 25000U},
2932
};
3033
const int TOYOTA_RX_CHECKS_LEN = sizeof(toyota_rx_checks) / sizeof(toyota_rx_checks[0]);
3134

@@ -37,7 +40,9 @@ int toyota_desired_torque_last = 0; // last desired steer torque
3740
int toyota_rt_torque_last = 0; // last desired torque for real time check
3841
uint32_t toyota_ts_last = 0;
3942
int toyota_cruise_engaged_last = 0; // cruise state
40-
int toyota_gas_prev = 0;
43+
bool toyota_gas_prev = false;
44+
bool toyota_brake_prev = false;
45+
bool toyota_moving = false;
4146
struct sample_t toyota_torque_meas; // last 3 motor torques produced by the eps
4247

4348

@@ -65,7 +70,7 @@ static int toyota_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
6570
int addr = GET_ADDR(to_push);
6671

6772
// get eps motor torque (0.66 factor in dbc)
68-
if (addr == 0x260) {
73+
if ((addr == 0x260) && (bus == 0)) {
6974
int torque_meas_new = (GET_BYTE(to_push, 5) << 8) | GET_BYTE(to_push, 6);
7075
torque_meas_new = to_signed(torque_meas_new, 16);
7176

@@ -81,7 +86,7 @@ static int toyota_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
8186
}
8287

8388
// enter controls on rising edge of ACC, exit controls on ACC off
84-
if (addr == 0x1D2) {
89+
if ((addr == 0x1D2) && (bus == 0)) {
8590
// 5th bit is CRUISE_ACTIVE
8691
int cruise_engaged = GET_BYTE(to_push, 0) & 0x20;
8792
if (!cruise_engaged) {
@@ -93,21 +98,43 @@ static int toyota_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
9398
toyota_cruise_engaged_last = cruise_engaged;
9499
}
95100

101+
// sample speed
102+
if ((addr == 0xaa) && (bus == 0)) {
103+
int speed = 0;
104+
// sum 4 wheel speeds
105+
for (int i=0; i<8; i+=2) {
106+
int next_byte = i + 1; // hack to deal with misra 10.8
107+
speed += (GET_BYTE(to_push, i) << 8) + GET_BYTE(to_push, next_byte);
108+
}
109+
toyota_moving = (speed / 4) > TOYOTA_STANDSTILL_THRSLD;
110+
}
111+
112+
// exit controls on rising edge of brake pedal
113+
// most cars have brake_pressed on 0x226, corolla and rav4 on 0x224
114+
if (((addr == 0x224) || (addr == 0x226)) && (bus == 0)) {
115+
int byte = (addr == 0x224) ? 0 : 4;
116+
bool brake = ((GET_BYTE(to_push, byte) >> 5) & 1) != 0;
117+
if (brake && (!toyota_brake_prev || toyota_moving)) {
118+
controls_allowed = 0;
119+
}
120+
toyota_brake_prev = brake;
121+
}
122+
96123
// exit controls on rising edge of interceptor gas press
97-
if (addr == 0x201) {
124+
if ((addr == 0x201) && (bus == 0)) {
98125
gas_interceptor_detected = 1;
99126
int gas_interceptor = GET_INTERCEPTOR(to_push);
100-
if ((gas_interceptor > TOYOTA_GAS_INTERCEPTOR_THRESHOLD) &&
101-
(gas_interceptor_prev <= TOYOTA_GAS_INTERCEPTOR_THRESHOLD)) {
127+
if ((gas_interceptor > TOYOTA_GAS_INTERCEPTOR_THRSLD) &&
128+
(gas_interceptor_prev <= TOYOTA_GAS_INTERCEPTOR_THRSLD)) {
102129
controls_allowed = 0;
103130
}
104131
gas_interceptor_prev = gas_interceptor;
105132
}
106133

107134
// exit controls on rising edge of gas press
108-
if (addr == 0x2C1) {
109-
int gas = GET_BYTE(to_push, 6);
110-
if ((gas > 0) && (toyota_gas_prev == 0) && !gas_interceptor_detected) {
135+
if ((addr == 0x2C1) && (bus == 0)) {
136+
bool gas = GET_BYTE(to_push, 6) != 0;
137+
if (gas && !toyota_gas_prev && !gas_interceptor_detected) {
111138
controls_allowed = 0;
112139
}
113140
toyota_gas_prev = gas;

tests/safety/libpandasafety_py.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
void init_tests_toyota(void);
4949
int get_toyota_torque_meas_min(void);
5050
int get_toyota_torque_meas_max(void);
51-
int get_toyota_gas_prev(void);
51+
bool get_toyota_gas_prev(void);
5252
void set_toyota_torque_meas(int min, int max);
5353
void set_toyota_desired_torque_last(int t);
5454
void set_toyota_rt_torque_last(int t);

tests/safety/test.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ int get_chrysler_torque_meas_max(void){
159159
return chrysler_torque_meas.max;
160160
}
161161

162-
int get_toyota_gas_prev(void){
162+
bool get_toyota_gas_prev(void){
163163
return toyota_gas_prev;
164164
}
165165

tests/safety/test_toyota.py

+37-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
MAX_RT_DELTA = 375
1616
RT_INTERVAL = 250000
1717

18+
STANDSTILL_THRESHOLD = 100 # 1kph
19+
1820
MAX_TORQUE_ERROR = 350
1921
INTERCEPTOR_THRESHOLD = 475
2022

@@ -62,7 +64,7 @@ def _torque_meas_msg(self, torque):
6264
t = twos_comp(torque, 16)
6365
to_send = make_msg(0, 0x260)
6466
to_send[0].RDHR = (t & 0xff00) | ((t & 0xFF) << 16)
65-
to_send[0].RDHR = to_send[0].RDHR | (toyota_checksum(to_send[0], 0x260, 8) << 24)
67+
to_send[0].RDHR |= toyota_checksum(to_send[0], 0x260, 8) << 24
6668
return to_send
6769

6870
def _torque_msg(self, torque):
@@ -77,6 +79,20 @@ def _accel_msg(self, accel):
7779
to_send[0].RDLR = (a & 0xFF) << 8 | (a >> 8)
7880
return to_send
7981

82+
def _speed_msg(self, s):
83+
to_send = make_msg(0, 0xaa)
84+
to_send[0].RDLR = (s & 0xFF) << 8 | (s >> 8)
85+
to_send[0].RDLR += (s & 0xFF) << 24 | ((s >> 8) << 16)
86+
to_send[0].RDHR = (s & 0xFF) << 8 | (s >> 8)
87+
to_send[0].RDHR += (s & 0xFF) << 24 | ((s >> 8) << 16)
88+
return to_send
89+
90+
def _brake_msg(self, brake):
91+
to_send = make_msg(0, 0x226)
92+
to_send[0].RDHR = brake << 5
93+
to_send[0].RDHR |= toyota_checksum(to_send[0], 0x226, 8) << 24
94+
return to_send
95+
8096
def _send_gas_msg(self, gas):
8197
to_send = make_msg(0, 0x2C1)
8298
to_send[0].RDHR = (gas & 0xFF) << 16
@@ -121,7 +137,7 @@ def test_disable_control_allowed_from_cruise(self):
121137
def test_prev_gas(self):
122138
for g in range(0, 256):
123139
self.safety.safety_rx_hook(self._send_gas_msg(g))
124-
self.assertEqual(g, self.safety.get_toyota_gas_prev())
140+
self.assertEqual(True if g > 0 else False, self.safety.get_toyota_gas_prev())
125141

126142
def test_prev_gas_interceptor(self):
127143
self.safety.safety_rx_hook(self._send_interceptor_msg(0x0, 0x201))
@@ -155,6 +171,25 @@ def test_disengage_on_gas_interceptor(self):
155171
self.safety.safety_rx_hook(self._send_interceptor_msg(0, 0x201))
156172
self.safety.set_gas_interceptor_detected(False)
157173

174+
def test_allow_brake_at_zero_speed(self):
175+
# Brake was already pressed
176+
self.safety.safety_rx_hook(self._speed_msg(0))
177+
self.safety.safety_rx_hook(self._brake_msg(True))
178+
self.safety.set_controls_allowed(1)
179+
180+
self.safety.safety_rx_hook(self._brake_msg(True))
181+
self.assertTrue(self.safety.get_controls_allowed())
182+
self.safety.safety_rx_hook(self._brake_msg(False)) # reset no brakes
183+
184+
def test_not_allow_brake_when_moving(self):
185+
# Brake was already pressed
186+
self.safety.safety_rx_hook(self._brake_msg(True))
187+
self.safety.safety_rx_hook(self._speed_msg(STANDSTILL_THRESHOLD + 1))
188+
self.safety.set_controls_allowed(1)
189+
190+
self.safety.safety_rx_hook(self._brake_msg(True))
191+
self.assertFalse(self.safety.get_controls_allowed())
192+
158193
def test_allow_engage_with_gas_interceptor_pressed(self):
159194
self.safety.safety_rx_hook(self._send_interceptor_msg(0x1000, 0x201))
160195
self.safety.set_controls_allowed(1)

0 commit comments

Comments
 (0)