Skip to content

Commit 976ca82

Browse files
committed
Ford: set steeringRateLimited when exceeding angle limits
1 parent 3711bde commit 976ca82

File tree

2 files changed

+44
-25
lines changed

2 files changed

+44
-25
lines changed

selfdrive/car/ford/carcontroller.py

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,61 +6,78 @@
66
from selfdrive.car.ford.values import CarControllerParams
77
from opendbc.can.packer import CANPacker
88

9+
DEBUG_RAMP_TYPE = False
10+
911
VisualAlert = car.CarControl.HUDControl.VisualAlert
1012

13+
14+
def apply_steer_angle_limits(apply_steer, apply_steer_last, vEgo, LIMITS):
15+
steer_up = apply_steer * apply_steer_last > 0. and abs(apply_steer) > abs(apply_steer_last)
16+
rate_limit = LIMITS.STEER_RATE_LIMIT_UP if steer_up else LIMITS.STEER_RATE_LIMIT_DOWN
17+
max_angle_diff = interp(vEgo, rate_limit.speed_points, rate_limit.max_angle_diff_points)
18+
return clip(apply_steer, (apply_steer_last - max_angle_diff), (apply_steer_last + max_angle_diff))
19+
20+
1121
class CarController():
1222
def __init__(self, dbc_name, CP, VM):
1323
self.CP = CP
1424
self.vehicle_model = VM
1525
self.packer = CANPacker(dbc_name)
1626
self.params = CarControllerParams
1727

18-
self.enabled_last = False
28+
self.apply_steer_last = 0
29+
self.steer_rate_limited = False
1930
self.main_on_last = False
20-
self.generic_toggle_last = False
31+
self.enabled_last = False
2132
self.steer_alert_last = False
22-
self.angle_last = 0
33+
self.generic_toggle_last = False
34+
35+
self.ramp_type = 0
2336

2437
def update(self, enabled, CS, frame, actuators, cruise_cancel, visual_alert):
2538
can_sends = []
26-
2739
main_on = CS.out.cruiseState.available
2840
steer_alert = visual_alert in [VisualAlert.steerRequired, VisualAlert.ldw]
2941

30-
if cruise_cancel:
31-
can_sends.append(fordcan.spam_cancel_button(self.packer))
42+
apply_steer = 0
43+
self.steer_rate_limited = False
3244

33-
if (frame % self.params.LKAS_STEER_STEP) == 0:
34-
angle = actuators.steeringAngleDeg
45+
if enabled:
46+
# calculate steer angle, apply angle rate limits
47+
apply_steer = apply_steer_angle_limits(actuators.steeringAngleDeg, self.apply_steer_last, CS.out.vEgo, CarControllerParams)
48+
self.steer_rate_limited = actuators.steeringAngleDeg != apply_steer
3549

36-
# angle rate limit based on speed
37-
steer_up = angle * self.angle_last > 0. and abs(angle) > abs(self.angle_last)
38-
rate_limit = self.params.STEER_RATE_LIMIT_UP if steer_up else self.params.STEER_RATE_LIMIT_DOWN
39-
max_angle_diff = interp(CS.out.vEgo, rate_limit.speed_points, rate_limit.max_angle_diff_points)
40-
angle = clip(angle, (self.angle_last - max_angle_diff), (self.angle_last + max_angle_diff))
50+
if cruise_cancel:
51+
# cancel stock ACC
52+
can_sends.append(fordcan.spam_cancel_button(self.packer))
4153

42-
if enabled:
43-
lca_rq = 1
44-
else:
45-
lca_rq = 0
54+
if CS.out.genericToggle and not self.generic_toggle_last:
55+
# ramp type experiment
56+
if DEBUG_RAMP_TYPE:
57+
# TODO: stock varies this with distance from center
58+
self.ramp_type += 1
59+
if self.ramp_type > 3:
60+
self.ramp_type = 0
4661

47-
angle_rad = angle * CV.DEG_TO_RAD
62+
if (frame % self.params.LKAS_STEER_STEP) == 0:
63+
lca_rq = 1 if enabled else 0
64+
apply_steer_rad = apply_steer * CV.DEG_TO_RAD
4865
curvature = self.vehicle_model.calc_curvature(math.radians(actuators.steeringAngleDeg), CS.out.vEgo, 0.0)
49-
ramp_type = 3
5066

51-
can_sends.append(fordcan.create_steer_command(self.packer, angle, curvature))
52-
can_sends.append(fordcan.create_steer2_command(self.packer, lca_rq, ramp_type, angle_rad, curvature))
67+
self.apply_steer_last = apply_steer
5368

54-
self.angle_last = angle
55-
self.generic_toggle_last = CS.out.genericToggle
69+
# send steering commands
70+
can_sends.append(fordcan.create_steer_command(self.packer, apply_steer, curvature))
71+
can_sends.append(fordcan.create_steer2_command(self.packer, lca_rq, self.ramp_type, apply_steer_rad, curvature))
5672

57-
# TODO: do we also have to send if CS.ipma_data changed?
73+
# TODO: do we need to send when values change? is 1hz acceptable?
5874
if (frame % self.params.LKAS_UI_STEP) == 0 or (self.main_on_last != main_on) or (self.enabled_last != enabled) or \
5975
(self.steer_alert_last != steer_alert):
6076
can_sends.append(fordcan.create_lkas_ui_command(self.packer, main_on, enabled, steer_alert, CS.ipma_data))
6177

6278
self.main_on_last = main_on
6379
self.enabled_last = enabled
6480
self.steer_alert_last = steer_alert
81+
self.generic_toggle_last = CS.out.genericToggle
6582

6683
return actuators, can_sends

selfdrive/car/ford/interface.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,10 @@ def update(self, c, can_strings):
6565

6666
ret.canValid = self.cp.can_valid and self.cp_cam.can_valid
6767

68-
# TODO: fixup alerts for LCA
68+
# speeds
69+
ret.steeringRateLimited = self.CC.steer_rate_limited if self.CC is not None else False
6970

71+
# events
7072
events = self.create_common_events(ret)
7173
if self.CS.park_brake:
7274
events.add(EventName.parkBrake)

0 commit comments

Comments
 (0)