diff --git a/SNNBot_garage/src/SNNBot.nim b/SNNBot_garage/src/SNNBot.nim index e72fbd6..c4f1092 100644 --- a/SNNBot_garage/src/SNNBot.nim +++ b/SNNBot_garage/src/SNNBot.nim @@ -215,6 +215,7 @@ type velSpeed: float64 # speed (units/tick) from last scan delta lastDecideGunDir: float # gun heading captured at DECIDE time for EVALUATE lastBinInput: BitVec80 # DECIDE-time binary input, reused in EVALUATE + lastError: float # last aiming error (for jump detection) # ── aimTo helper ────────────────────────────────────────────────────────────── @@ -273,6 +274,7 @@ method onRoundStarted*(bot: SNNBot, e: RoundStartedEvent) = bot.velSpeed = 0.0 bot.phase = DECIDE bot.tick = 0 + bot.lastError = -1.0 # sentinel: no error yet setTargetSpeed(0.0) setTurnRate(0.0) @@ -382,9 +384,21 @@ method run*(bot: SNNBot) = of WAITING: aimTo(bot.targetAngle, gunDir) let err = abs(normalizeRelativeAngle(bot.targetAngle - gunDir)) + + # Bidirectional fire gate: fire only when error within tolerance if err < AIM_TOL: discard setFire(FIRE_POWER) bot.phase = EVALUATE + else: + discard setFire(0.0) + + # Fast recovery: detect error jump (regime change) and reset ring buffer + # ponytail: >5° jump triggers reset; tune threshold if target moves frequently + if bot.lastError >= 0.0 and err - bot.lastError > 5.0: + bot.res.count = 0 + bot.res.nextSlot = 0 + + bot.lastError = err of EVALUATE: # Predictive error signal: extrapolate enemy position at bullet impact time.