force stop edge case

This commit is contained in:
whoisdomi
2026-11-07 17:37:09 -06:00
committed by firestarsdog
parent 233a386ab4
commit f831010290
2 changed files with 19 additions and 2 deletions
@@ -141,7 +141,7 @@ class ForceStop:
permitted = (available and now >= self.override_until_ns and not frame.driving_in_curve and not turn and
not frame.tracking_lead and not lead)
model_path = frame.light and model_active and permitted and not curved
sign_path = frame.sign and permitted and speed < SIGN_MAX_SPEED_MPS and horizon < SIGN_MODEL_AGREE_M
sign_path = frame.sign and permitted and speed < SIGN_MAX_SPEED_MPS and (horizon < SIGN_MODEL_AGREE_M or self.forcing)
if sign_path:
self.sign_confirmed = True
active = model_path or sign_path
@@ -232,7 +232,7 @@ class ForceStop:
self.distance_cap = max(0.0, self.distance_cap - speed * dt)
self.distance = min(self.distance, self.distance_cap + 15 * min(self.distance_cap / 60, 1))
if frame.sign and available:
if horizon < SIGN_MODEL_AGREE_M:
if horizon < SIGN_MODEL_AGREE_M or self.sign_confirmed:
self.distance = min(self.distance, SIGN_SEED_M)
effective = self.distance + offset + tune.distance_bias_m
decel = SIGN_APPROACH_DECEL if frame.sign else MODEL_APPROACH_DECEL
@@ -244,6 +244,23 @@ class ForceStopTests(unittest.TestCase):
plan = self.owner.step(frame(50, speed_mps=8., horizon_m=20., sign=True), self.tune)
self.assertLessEqual(plan.tracked_distance_m, previous.tracked_distance_m)
def test_sign_latches_and_seeds_over_long_path_once_light_committed(self):
for tick in range(15):
plan = self.owner.step(frame(tick, horizon_m=60.), self.tune)
self.assertTrue(plan.forcing)
self.assertGreater(plan.tracked_distance_m, 50.)
plan = self.owner.step(frame(15, horizon_m=60., sign=True), self.tune)
self.assertTrue(self.owner.sign_confirmed)
self.assertLessEqual(plan.tracked_distance_m, 27.)
plan = self.owner.step(frame(16, horizon_m=60., light=False), self.tune)
self.assertLess(plan.tracked_distance_m, 27.)
def test_long_path_sign_alone_does_not_commit(self):
for tick in range(20):
plan = self.owner.step(frame(tick, horizon_m=60., light=False, sign=True), self.tune)
self.assertFalse(plan.forcing)
self.assertFalse(self.owner.sign_confirmed)
def test_positive_offset_keeps_stop_target_until_native_stop(self):
for tick in range(40):
plan = self.owner.step(frame(tick, horizon_m=12.), self.tune, 8)