Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Steer Rate consideration for Lateral Control #435

Closed
wants to merge 28 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
ea86f34
Fixed feed-forward to consider steer_offset
Gernby Nov 6, 2018
0bbc4fc
fixed a small oops on types
Gernby Nov 7, 2018
f6e5830
Testing strategies for zero-crossing
Gernby Nov 8, 2018
f720034
Moved angle stat collection to latcontrol.py
Gernby Nov 8, 2018
ebbfd0b
First version that runs
Gernby Nov 8, 2018
f543fe9
added outbound interface for feed-forward table
Gernby Nov 8, 2018
f475160
First working
Gernby Nov 8, 2018
b6a5180
Added more metrics
Gernby Nov 8, 2018
8f0effd
Adjusted parameter timing
Gernby Nov 8, 2018
d9c8dff
performance tweaks
Gernby Nov 9, 2018
8087e81
Cleanup
Gernby Nov 9, 2018
78095f4
untested tweaks
Gernby Nov 10, 2018
855684c
minor tweaks
Gernby Nov 10, 2018
a8fabe2
many untested changes
Gernby Nov 11, 2018
347d1d1
going the other way with some things...
Gernby Nov 11, 2018
4b4767c
Best yet
Gernby Nov 11, 2018
b12aaf3
cleaned up personalized "stuff"
Gernby Nov 12, 2018
1251809
more cleanup for general use
Gernby Nov 12, 2018
66ec2bc
untested: minor adjustment to further reduce noise
Gernby Nov 12, 2018
f26785e
Fixed defect in desired angle interpolation
Gernby Nov 13, 2018
856f2b1
some cleanup
Gernby Nov 13, 2018
a0c9b2d
reverted change to Ki
Gernby Nov 13, 2018
900b9cd
Reverted changes to manager.py
Gernby Nov 13, 2018
34e239f
Added steering rate consideration to latcontrol
Gernby Nov 13, 2018
52094ba
cleaned up for PR
Gernby Nov 13, 2018
3134bce
Merge remote-tracking branch 'origin' into Feed-Forward_Steer_Offset
Gernby Nov 17, 2018
07bbadc
Fixed merge
Gernby Nov 17, 2018
64a5a72
Merged fix for straight line torque calculation
Gernby Nov 20, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion selfdrive/controls/controlsd.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ def state_control(plan, CS, CP, state, events, v_cruise_kph, v_cruise_kph_last,
v_cruise_kph, plan.vTarget, plan.vTargetFuture, plan.aTarget,
CP, PL.lead_1)
# Steering PID loop and lateral MPC
actuators.steer, actuators.steerAngle = LaC.update(active, CS.vEgo, CS.steeringAngle,
actuators.steer, actuators.steerAngle = LaC.update(active, CS.vEgo, CS.steeringAngle, CS.steeringRate,
CS.steeringPressed, plan.dPoly, angle_offset, CP, VM, PL)

# Send a "steering required alert" if saturation count has reached the limit
Expand Down
47 changes: 32 additions & 15 deletions selfdrive/controls/lib/latcontrol.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ def calc_states_after_delay(states, v_ego, steer_angle, curvature_factor, steer_
def get_steer_max(CP, v_ego):
return interp(v_ego, CP.steerMaxBP, CP.steerMaxV)

def apply_deadzone(angle, deadzone):
if angle > deadzone:
angle -= deadzone
elif angle < -deadzone:
angle += deadzone
else:
angle = 0.
return angle

class LatControl(object):
def __init__(self, CP):
Expand All @@ -46,19 +54,21 @@ def setup_mpc(self, steer_rate_cost):
self.last_mpc_ts = 0.0
self.angle_steers_des = 0.0
self.angle_steers_des_mpc = 0.0
self.angle_steers_des_prev = 0.0
self.angle_steers_des_time = 0.0
self.starting_angle_steers = 0.0
self.avg_angle_rate = 0.0
self.angle_rate_count = 0.0

def reset(self):
self.pid.reset()

def update(self, active, v_ego, angle_steers, steer_override, d_poly, angle_offset, CP, VM, PL):
cur_time = sec_since_boot()
def update(self, active, v_ego, angle_steers, angle_rate, steer_override, d_poly, angle_offset, CP, VM, PL):
self.mpc_updated = False
# TODO: this creates issues in replay when rewinding time: mpc won't run
if self.last_mpc_ts < PL.last_md_ts:
self.last_mpc_ts = PL.last_md_ts
self.angle_steers_des_prev = self.angle_steers_des_mpc
self.starting_angle_steers = angle_steers
self.avg_angle_rate = 0.0
self.angle_rate_count = 0.0

curvature_factor = VM.curvature_factor(v_ego)

Expand All @@ -83,7 +93,6 @@ def update(self, active, v_ego, angle_steers, steer_override, d_poly, angle_offs
self.cur_state[0].delta = delta_desired

self.angle_steers_des_mpc = float(math.degrees(delta_desired * CP.steerRatio) + angle_offset)
self.angle_steers_des_time = cur_time
self.mpc_updated = True

# Check for infeasable MPC solution
Expand All @@ -101,20 +110,28 @@ def update(self, active, v_ego, angle_steers, steer_override, d_poly, angle_offs
output_steer = 0.0
self.pid.reset()
else:
# TODO: ideally we should interp, but for tuning reasons we keep the mpc solution
# constant for 0.05s.
#dt = min(cur_time - self.angle_steers_des_time, _DT_MPC + _DT) + _DT # no greater than dt mpc + dt, to prevent too high extraps
#self.angle_steers_des = self.angle_steers_des_prev + (dt / _DT_MPC) * (self.angle_steers_des_mpc - self.angle_steers_des_prev)
self.angle_steers_des = self.angle_steers_des_mpc
# Calculate average steering rate since last MPC update
self.avg_angle_rate = (self.avg_angle_rate * self.angle_rate_count + angle_rate) / (self.angle_rate_count + 1.)
self.angle_rate_count += 1.0

if abs(angle_rate) <= 1. or abs(angle_steers - self.angle_steers_des_mpc) <= 0.2:
# For small steering error, use instantaneous angle for torque calculation
future_angle_steers = angle_steers
else:
# Otherwise, use average steering rate since last MPC update to project future steering error
future_angle_steers = (self.avg_angle_rate * _DT_MPC) + self.starting_angle_steers

steers_max = get_steer_max(CP, v_ego)
self.pid.pos_limit = steers_max
self.pid.neg_limit = -steers_max
steer_feedforward = self.angle_steers_des # feedforward desired angle
if CP.steerControlType == car.CarParams.SteerControlType.torque:
steer_feedforward = apply_deadzone(self.angle_steers_des_mpc - float(angle_offset), 0.5)
steer_feedforward *= v_ego**2 # proportional to realigning tire momentum (~ lateral accel)
else:
steer_feedforward = self.angle_steers_des_mpc # feedforward desired angle
deadzone = 0.0
output_steer = self.pid.update(self.angle_steers_des, angle_steers, check_saturation=(v_ego > 10), override=steer_override,
feedforward=steer_feedforward, speed=v_ego, deadzone=deadzone)

output_steer = self.pid.update(self.angle_steers_des_mpc, future_angle_steers, check_saturation=(v_ego > 10), override=steer_override,
feedforward=steer_feedforward, speed=v_ego, deadzone=deadzone)
self.sat_flag = self.pid.saturated
return output_steer, float(self.angle_steers_des)
return output_steer, float(self.angle_steers_des_mpc)