|
| 1 | +import math |
1 | 2 | from cereal import car
|
2 | 3 | from common.numpy_fast import clip, interp
|
3 | 4 | from opendbc.can.packer import CANPacker
|
|
7 | 8 | VisualAlert = car.CarControl.HUDControl.VisualAlert
|
8 | 9 |
|
9 | 10 |
|
10 |
| -def apply_ford_steer_angle_limits(apply_steer, apply_steer_last, vEgo): |
| 11 | +def apply_ford_steer_angle_limits(apply_steer, apply_steer_last, vEgo, VM): |
| 12 | + apply_angle = apply_steer / VM.sR |
| 13 | + apply_angle_last = apply_steer_last / VM.sR |
| 14 | + |
11 | 15 | # rate limit
|
12 |
| - steer_up = apply_steer * apply_steer_last > 0. and abs(apply_steer) > abs(apply_steer_last) |
13 |
| - rate_limit = CarControllerParams.STEER_RATE_LIMIT_UP if steer_up else CarControllerParams.STEER_RATE_LIMIT_DOWN |
| 16 | + steer_up = apply_angle * apply_angle_last > 0. and abs(apply_angle) > abs(apply_angle_last) |
| 17 | + rate_limit = CarControllerParams.ANGLE_RATE_LIMIT_UP if steer_up else CarControllerParams.ANGLE_RATE_LIMIT_DOWN |
14 | 18 | max_angle_diff = interp(vEgo, rate_limit.speed_points, rate_limit.max_angle_diff_points)
|
15 |
| - apply_steer = clip(apply_steer, (apply_steer_last - max_angle_diff), (apply_steer_last + max_angle_diff)) |
| 19 | + apply_angle = clip(apply_angle, (apply_angle_last - max_angle_diff), (apply_angle_last + max_angle_diff)) |
| 20 | + |
| 21 | + # absolute limit (0.5 rad after steer ratio) |
| 22 | + apply_angle = math.radians(apply_angle) * 4.1 |
| 23 | + apply_angle = clip(apply_angle, -0.5, 0.5235) |
| 24 | + apply_angle = math.degrees(apply_angle) / 4.1 |
16 | 25 |
|
17 |
| - return apply_steer |
| 26 | + return apply_angle * VM.sR |
18 | 27 |
|
19 | 28 |
|
20 | 29 | class CarController:
|
@@ -42,32 +51,31 @@ def update(self, CC, CS):
|
42 | 51 | # cancel stock ACC
|
43 | 52 | can_sends.append(fordcan.spam_cancel_button(self.packer))
|
44 | 53 |
|
45 |
| - # apply rate limits |
| 54 | + |
| 55 | + ### lateral control ### |
46 | 56 | new_steer = actuators.steeringAngleDeg
|
47 |
| - apply_steer = apply_ford_steer_angle_limits(new_steer, self.apply_steer_last, CS.out.vEgo) |
| 57 | + apply_steer = apply_ford_steer_angle_limits(new_steer, self.apply_steer_last, CS.out.vEgo, self.VM) |
48 | 58 |
|
49 | 59 | # send steering commands at 20Hz
|
50 | 60 | if (self.frame % CarControllerParams.LKAS_STEER_STEP) == 0:
|
51 | 61 | lca_rq = 1 if CC.latActive else 0
|
52 | 62 |
|
53 |
| - # use LatCtlPath_An_Actl to actuate steering for now until curvature control is implemented |
54 |
| - path_angle = apply_steer |
| 63 | + # use LatCtlPath_An_Actl to actuate steering |
| 64 | + # path angle is the car wheel angle, not the steering wheel angle |
| 65 | + path_angle = math.radians(apply_steer) * 4.1 / self.VM.sR |
55 | 66 |
|
56 |
| - # convert steer angle to curvature |
57 |
| - curvature = self.VM.calc_curvature(apply_steer, CS.out.vEgo, 0.0) |
58 |
| - |
59 |
| - # TODO: get other actuators |
60 |
| - curvature_rate = 0 |
61 |
| - path_offset = 0 |
62 |
| - |
63 |
| - ramp_type = 3 # 0=Slow, 1=Medium, 2=Fast, 3=Immediately |
64 |
| - precision = 0 # 0=Comfortable, 1=Precise |
| 67 | + # ramp rate: 0=Slow, 1=Medium, 2=Fast, 3=Immediately |
| 68 | + # TODO: slower ramp speed when driver torque detected |
| 69 | + ramp_type = 2 |
| 70 | + precision = 1 # 0=Comfortable, 1=Precise |
65 | 71 |
|
66 | 72 | self.apply_steer_last = apply_steer
|
67 |
| - can_sends.append(fordcan.create_lkas_command(self.packer, apply_steer, curvature)) |
| 73 | + can_sends.append(fordcan.create_lkas_command(self.packer, apply_steer, 0)) |
68 | 74 | can_sends.append(fordcan.create_tja_command(self.packer, lca_rq, ramp_type, precision,
|
69 |
| - path_offset, path_angle, curvature_rate, curvature)) |
| 75 | + 0, path_angle, 0, 0)) |
| 76 | + |
70 | 77 |
|
| 78 | + ### ui ### |
71 | 79 | send_ui = (self.main_on_last != main_on) or (self.lkas_enabled_last != CC.latActive) or (self.steer_alert_last != steer_alert)
|
72 | 80 |
|
73 | 81 | # send lkas ui command at 1Hz or if ui state changes
|
|
0 commit comments