Consensus tracker + active scan close Webots 140° LiDAR gap
Two deploy-time fixes that take v1 360°-trained BC/RL from 0/n to n/n penned on the canonical 140° LiDAR proto for diff/field: * SheepTracker now supports a consensus stage: new detections start as candidate tracks invisible to get_positions(). A candidate must accumulate consensus_k matches within consensus_radius_m of itself inside a consensus_max_age window to be promoted; otherwise it expires. Real sheep self-confirm within 3 frames (≪0.05 m/step); wall-return cluster centroids jitter beyond 0.3 m as the dog moves and never promote. consensus_k=1 (default) is a no-op so unconfigured callers and HERDING_DEFAULT keep prior behaviour. * HERDING_WEBOTS preset gets consensus_k=3, radius=0.3, max_age=20, plus longer forget_steps=300 and predict_steps=180 so confirmed sheep persist through long FOV-occlusion gaps a narrow 140° cone produces. max_new_tracks_per_step=1 still rate-caps spawn bursts. * shepherd_dog.py BC/RL empty-obs fallback now rotates the desired heading with step_count so the cone actively sweeps the field instead of driving due north into the wall. Verified in headless Webots (HERDING_USE_GT=0, LiDAR only): BC diff/field: 5/5 @ 11698, 10/10 @ 15079 RL diff/field: 5/5 @ 10039, 9/10 @ 18200 (timeout) Strömbom diff/field: 5/5 @ 7528 All previously 0/n. 120 unit tests pass; 9 new consensus tests cover the candidate stage, promotion radius, and one-shot phantom rejection. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+22
-1
@@ -61,10 +61,23 @@ class TestTrackerConfig:
|
||||
|
||||
def test_webots_preset_tighter(self):
|
||||
cfg = HERDING_WEBOTS.tracker
|
||||
assert cfg.forget_steps == 120
|
||||
# forget_steps was extended so confirmed sheep tracks survive
|
||||
# sparse 140° FOV re-sightings; consensus blocks phantoms from
|
||||
# reaching this lifetime.
|
||||
assert cfg.forget_steps >= 200
|
||||
assert cfg.max_new_tracks_per_step == 1
|
||||
assert cfg.pen_latch_depth == 2.0
|
||||
|
||||
def test_default_consensus_disabled(self):
|
||||
cfg = TrackerConfig()
|
||||
assert cfg.consensus_k == 1
|
||||
|
||||
def test_webots_preset_enables_consensus(self):
|
||||
cfg = HERDING_WEBOTS.tracker
|
||||
assert cfg.consensus_k > 1
|
||||
assert cfg.consensus_radius_m > 0.0
|
||||
assert cfg.consensus_max_age >= cfg.consensus_k
|
||||
|
||||
def test_invalid_forget_steps(self):
|
||||
with pytest.raises(ValueError):
|
||||
TrackerConfig(forget_steps=0)
|
||||
@@ -73,6 +86,14 @@ class TestTrackerConfig:
|
||||
with pytest.raises(ValueError):
|
||||
TrackerConfig(max_new_tracks_per_step=0)
|
||||
|
||||
def test_invalid_consensus_params(self):
|
||||
with pytest.raises(ValueError):
|
||||
TrackerConfig(consensus_k=0)
|
||||
with pytest.raises(ValueError):
|
||||
TrackerConfig(consensus_radius_m=0.0)
|
||||
with pytest.raises(ValueError):
|
||||
TrackerConfig(consensus_max_age=0)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# DetectionConfig
|
||||
|
||||
Reference in New Issue
Block a user