1313const SteeringLimits SUBARU_STEERING_LIMITS = SUBARU_STEERING_LIMITS_GENERATOR (2047 , 50 , 70 );
1414const SteeringLimits SUBARU_GEN2_STEERING_LIMITS = SUBARU_STEERING_LIMITS_GENERATOR (1000 , 40 , 40 );
1515
16+ const SteeringLimits SUBARU_ANGLE_STEERING_LIMITS = {
17+ .angle_deg_to_can = 100 ,
18+ .angle_rate_up_lookup = {
19+ {0. , 5. , 15. },
20+ {5. , .8 , .15 }
21+ },
22+ .angle_rate_down_lookup = {
23+ {0. , 5. , 15. },
24+ {5. , 3.5 , .4 }
25+ },
26+ };
1627
1728const LongitudinalLimits SUBARU_LONG_LIMITS = {
1829 .min_gas = 808 , // appears to be engine braking
@@ -44,7 +55,7 @@ const LongitudinalLimits SUBARU_LONG_LIMITS = {
4455#define SUBARU_CAM_BUS 2
4556
4657#define SUBARU_COMMON_TX_MSGS (alt_bus , lkas_msg ) \
47- {MSG_SUBARU_ES_LKAS, SUBARU_MAIN_BUS, 8}, \
58+ {lkas_msg, SUBARU_MAIN_BUS, 8}, \
4859 {MSG_SUBARU_ES_Distance, alt_bus, 8}, \
4960 {MSG_SUBARU_ES_DashStatus, SUBARU_MAIN_BUS, 8}, \
5061 {MSG_SUBARU_ES_LKAS_State, SUBARU_MAIN_BUS, 8}, \
@@ -77,6 +88,11 @@ const CanMsg SUBARU_GEN2_TX_MSGS[] = {
7788};
7889#define SUBARU_GEN2_TX_MSGS_LEN (sizeof(SUBARU_GEN2_TX_MSGS) / sizeof(SUBARU_GEN2_TX_MSGS[0]))
7990
91+ const CanMsg SUBARU_LKAS_ANGLE_TX_MSGS [] = {
92+ SUBARU_COMMON_TX_MSGS (SUBARU_MAIN_BUS , MSG_SUBARU_ES_LKAS_ANGLE )
93+ };
94+ #define SUBARU_LKAS_ANGLE_TX_MSGS_LEN (sizeof(SUBARU_LKAS_ANGLE_TX_MSGS) / sizeof(SUBARU_LKAS_ANGLE_TX_MSGS[0]))
95+
8096AddrCheckStruct subaru_addr_checks [] = {
8197 SUBARU_COMMON_ADDR_CHECKS (SUBARU_MAIN_BUS )
8298};
@@ -92,9 +108,11 @@ addr_checks subaru_gen2_rx_checks = {subaru_gen2_addr_checks, SUBARU_GEN2_ADDR_C
92108
93109const uint16_t SUBARU_PARAM_GEN2 = 1 ;
94110const uint16_t SUBARU_PARAM_LONGITUDINAL = 2 ;
111+ const uint16_t SUBARU_PARAM_LKAS_ANGLE = 4 ;
95112
96113bool subaru_gen2 = false;
97114bool subaru_longitudinal = false;
115+ bool lkas_angle = false;
98116
99117
100118static uint32_t subaru_get_checksum (CANPacket_t * to_push ) {
@@ -123,6 +141,7 @@ static int subaru_rx_hook(CANPacket_t *to_push) {
123141 if (valid ) {
124142 const int bus = GET_BUS (to_push );
125143 const int alt_main_bus = subaru_gen2 ? SUBARU_ALT_BUS : SUBARU_MAIN_BUS ;
144+ const int stock_ecu = lkas_angle ? MSG_SUBARU_ES_LKAS_ANGLE : MSG_SUBARU_ES_LKAS ;
126145
127146 int addr = GET_ADDR (to_push );
128147 if ((addr == MSG_SUBARU_Steering_Torque ) && (bus == SUBARU_MAIN_BUS )) {
@@ -164,7 +183,7 @@ static int subaru_rx_hook(CANPacket_t *to_push) {
164183 gas_pressed = GET_BYTE (to_push , 4 ) != 0U ;
165184 }
166185
167- generic_rx_checks ((addr == MSG_SUBARU_ES_LKAS ) && (bus == SUBARU_MAIN_BUS ));
186+ generic_rx_checks ((addr == stock_ecu ) && (bus == SUBARU_MAIN_BUS ));
168187 }
169188 return valid ;
170189}
@@ -179,6 +198,8 @@ static int subaru_tx_hook(CANPacket_t *to_send) {
179198 tx = msg_allowed (to_send , SUBARU_GEN2_TX_MSGS , SUBARU_GEN2_TX_MSGS_LEN );
180199 } else if (subaru_longitudinal ) {
181200 tx = msg_allowed (to_send , SUBARU_LONG_TX_MSGS , SUBARU_LONG_TX_MSGS_LEN );
201+ } else if (lkas_angle ) {
202+ tx = msg_allowed (to_send , SUBARU_LKAS_ANGLE_TX_MSGS , SUBARU_LKAS_ANGLE_TX_MSGS_LEN );
182203 } else {
183204 tx = msg_allowed (to_send , SUBARU_TX_MSGS , SUBARU_TX_MSGS_LEN );
184205 }
@@ -194,6 +215,15 @@ static int subaru_tx_hook(CANPacket_t *to_send) {
194215 violation |= steer_torque_cmd_checks (desired_torque , steer_req , limits );
195216 }
196217
218+ if (addr == MSG_SUBARU_ES_LKAS_ANGLE ) {
219+ int desired_angle = (GET_BYTES (to_send , 5 , 3 ) & 0x1FFFFU );
220+ desired_angle = to_signed (desired_angle , 17 );
221+ bool lkas_request = GET_BIT (to_send , 12U );
222+
223+ const SteeringLimits limits = SUBARU_ANGLE_STEERING_LIMITS ;
224+ violation |= steer_angle_cmd_checks (desired_angle , lkas_request , limits );
225+ }
226+
197227 // check es_brake brake_pressure limits
198228 if (addr == MSG_SUBARU_ES_Brake ) {
199229 int es_brake_pressure = GET_BYTES (to_send , 2 , 2 );
@@ -236,10 +266,12 @@ static int subaru_fwd_hook(int bus_num, int addr) {
236266
237267 if (bus_num == SUBARU_CAM_BUS ) {
238268 // Global platform
239- bool block_lkas = ((addr == MSG_SUBARU_ES_LKAS ) ||
240- (addr == MSG_SUBARU_ES_DashStatus ) ||
241- (addr == MSG_SUBARU_ES_LKAS_State ) ||
242- (addr == MSG_SUBARU_ES_Infotainment ));
269+
270+ bool block_lkas = (((addr == MSG_SUBARU_ES_LKAS ) && !lkas_angle ) ||
271+ ((addr == MSG_SUBARU_ES_LKAS_ANGLE ) && lkas_angle ) ||
272+ (addr == MSG_SUBARU_ES_DashStatus ) ||
273+ (addr == MSG_SUBARU_ES_LKAS_State ) ||
274+ (addr == MSG_SUBARU_ES_Infotainment ));
243275
244276 bool block_long = ((addr == MSG_SUBARU_ES_Brake ) ||
245277 (addr == MSG_SUBARU_ES_Distance ) ||
@@ -259,6 +291,7 @@ static const addr_checks* subaru_init(uint16_t param) {
259291
260292#ifdef ALLOW_DEBUG
261293 subaru_longitudinal = GET_FLAG (param , SUBARU_PARAM_LONGITUDINAL ) && !subaru_gen2 ;
294+ lkas_angle = GET_FLAG (param , SUBARU_PARAM_LKAS_ANGLE ) && !subaru_gen2 ;
262295#endif
263296
264297 if (subaru_gen2 ) {
0 commit comments