Skip to content

Commit fe8617e

Browse files
committed
Ford: calculate wheel angle
1 parent f01266c commit fe8617e

File tree

4 files changed

+35
-31
lines changed

4 files changed

+35
-31
lines changed

selfdrive/car/ford/carcontroller.py

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import math
12
from cereal import car
23
from common.numpy_fast import clip, interp
34
from opendbc.can.packer import CANPacker
@@ -7,14 +8,22 @@
78
VisualAlert = car.CarControl.HUDControl.VisualAlert
89

910

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+
1115
# 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
1418
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
1625

17-
return apply_steer
26+
return apply_angle * VM.sR
1827

1928

2029
class CarController:
@@ -42,32 +51,31 @@ def update(self, CC, CS):
4251
# cancel stock ACC
4352
can_sends.append(fordcan.spam_cancel_button(self.packer))
4453

45-
# apply rate limits
54+
55+
### lateral control ###
4656
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)
4858

4959
# send steering commands at 20Hz
5060
if (self.frame % CarControllerParams.LKAS_STEER_STEP) == 0:
5161
lca_rq = 1 if CC.latActive else 0
5262

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
5566

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
6571

6672
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))
6874
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+
7077

78+
### ui ###
7179
send_ui = (self.main_on_last != main_on) or (self.lkas_enabled_last != CC.latActive) or (self.steer_alert_last != steer_alert)
7280

7381
# send lkas ui command at 1Hz or if ui state changes

selfdrive/car/ford/fordcan.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
from common.numpy_fast import clip
2-
3-
41
def create_lkas_command(packer, angle_deg: float, curvature: float):
52
"""
63
Creates a CAN message for the Ford LKAS Command.
@@ -43,10 +40,10 @@ def create_tja_command(packer, lca_rq: int, ramp_type: int, precision: int, path
4340
"LatCtl_D_Rq": lca_rq, # Mode: 0=None, 1=ContinuousPathFollowing, 2=InterventionLeft, 3=InterventionRight, 4-7=NotUsed [0|7]
4441
"LatCtlRampType_D_Rq": ramp_type, # Ramp speed: 0=Slow, 1=Medium, 2=Fast, 3=Immediate [0|3]
4542
"LatCtlPrecision_D_Rq": precision, # Precision: 0=Comfortable, 1=Precise, 2/3=NotUsed [0|3]
46-
"LatCtlPathOffst_L_Actl": clip(path_offset, -5.12, 5.11), # Path offset [-5.12|5.11] meter
47-
"LatCtlPath_An_Actl": clip(path_angle, -0.5, 0.5235), # Path angle [-0.5|0.5235] radians
48-
"LatCtlCurv_NoRate_Actl": clip(curvature_rate, -0.001024, 0.00102375), # Curvature rate [-0.001024|0.00102375] 1/meter^2
49-
"LatCtlCurv_No_Actl": clip(curvature, -0.02, 0.02094), # Curvature [-0.02|0.02094] 1/meter
43+
"LatCtlPathOffst_L_Actl": path_offset, # Path offset [-5.12|5.11] meter
44+
"LatCtlPath_An_Actl": path_angle, # Path angle [-0.5|0.5235] radians
45+
"LatCtlCurv_NoRate_Actl": curvature_rate, # Curvature rate [-0.001024|0.00102375] 1/meter^2
46+
"LatCtlCurv_No_Actl": curvature, # Curvature [-0.02|0.02094] 1/meter
5047
}
5148
return packer.make_can_msg("LateralMotionControl", 0, values)
5249

selfdrive/car/ford/interface.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,8 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None, disa
1919
ret.dashcamOnly = True
2020

2121
# Angle-based steering
22-
# TODO: use curvature control when ready
2322
ret.steerControlType = car.CarParams.SteerControlType.angle
24-
ret.steerActuatorDelay = 0.1
23+
ret.steerActuatorDelay = 0.15
2524
ret.steerLimitTimer = 1.0
2625

2726
# TODO: detect stop-and-go vehicles

selfdrive/car/ford/values.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ class CarControllerParams:
2020
# Message: ACCDATA_3
2121
ACC_UI_STEP = 5
2222

23-
STEER_RATE_LIMIT_UP = AngleRateLimit(speed_points=[0., 5., 15.], max_angle_diff_points=[5., .8, .15])
24-
STEER_RATE_LIMIT_DOWN = AngleRateLimit(speed_points=[0., 5., 15.], max_angle_diff_points=[5., 3.5, 0.4])
23+
ANGLE_RATE_LIMIT_UP = AngleRateLimit(speed_points=[0., 5., 15.], max_angle_diff_points=[1.66, 0.26, 0.05])
24+
ANGLE_RATE_LIMIT_DOWN = AngleRateLimit(speed_points=[0., 5., 15.], max_angle_diff_points=[1.66, 1.16, 0.133])
2525

2626

2727
class CANBUS:

0 commit comments

Comments
 (0)