Files

170 lines
5.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Existing Lead-Targeting & Enemy Tracking Code
Scope: all garages in SirRoboGarage as of `research/lead-targeting` branch.
---
## Summary
No lead-targeting (bullet-travel-time prediction, fire-ahead calculation) exists anywhere in the repo.
What does exist is well-factored enemy tracking, lateral-speed measurement, and a bullet-speed constant —
all the primitives needed to implement lead targeting.
---
## 1. Enemy Tracker (`PPO_Bot_garage`)
**File:** `PPO_Bot_garage/src/PPO_Bot/enemy_tracker.nim`
The richest tracker in the repo. Provides:
| Feature | Detail |
|---|---|
| `EnemyState` | x, y, direction, speed, energy, ticksSinceLastScan, hasFired, lastFirePower |
| History ring | `array[5, (x, y, direction, speed)]` — sliding window of last 5 scan positions |
| `update()` | Called on `ScannedBotEvent`; detects enemy fire from energy delta in `[0.1, 3.0]` |
| `deadReckon()` | Projects position forward one tick using last known speed+direction |
| `getRadarTurnRate()` | Width-lock with overshoot `arctan(36/dist)` |
**No lead angle calculation.** History gives velocity vectors; `deadReckon` gives 1-tick projection;
but there is no `travelTime = dist / bulletSpeed` loop or `atan2(lateral, forward)` computation.
---
## 2. Bullet Speed Formula
**Files:** `PPO_Bot_garage/src/PPO_Bot/state_vector.nim` (line 109) and
`SAC_LSTM_Bot_garage/src/SAC_LSTM_Bot/state.nim` (line 105)
Both independently define:
```nim
let bSpeed = 20.0 - 3.0 * b.power # Tank Royale bullet speed formula
```
This is the authoritative formula. It appears in two garages but only for computing
`ticksToImpact` from the bullet's *current position* for the state vector (dodge context),
not for predicting where to aim before firing.
---
## 3. Lateral Speed Measurement (`QBot_garage`)
**File:** `QBot_garage/src/QBot.nim` (lines 100–105, 335–336)
```nim
# lateralSpeed: enemy velocity component perpendicular to our line of sight
let lateralSpeed = bot.enemySpeed * sin(degToRad(bot.enemyDir - bearingToEnemy))
```
QBot discretizes this into 4 bins (`N_LAT_SPD = 4`) as a state feature, then learns
Q-values for aim offsets `[-12, -6, -3, 0, 3, 6, 12]` degrees. This is the closest
thing to lead targeting in the repo: it captures *why* you'd lead, but the lead angle
itself is picked by the Q-table, not calculated analytically.
---
## 4. In-Flight Bullet Tracking (`PPO_Bot_garage`)
**File:** `PPO_Bot_garage/src/PPO_Bot.nim` (lines 70–74, 215–258)
PPO_Bot tracks enemy bullets in flight using a fixed `array[4, InFlightBullet]` (no heap).
Each bullet has `(x, y, vx, vy, power)` and is advanced each tick. Used to populate
the dodge-context slots in the state vector. No lead-targeting use.
---
## 5. State Vectors with Enemy History
### PPO_Bot (`PPO_Bot_garage/src/PPO_Bot/state_vector.nim`)
- 57-float tensor
- Indices 22–41: 5-tick history window (x, y, direction, speed per tick)
- Indices 44–55: up to 3 enemy bullets (relX, relY, speed, ticksToImpact)
### SAC_LSTM_Bot (`SAC_LSTM_Bot_garage/src/SAC_LSTM_Bot/state.nim`)
- 35-float tensor
- No explicit history window (LSTM handles temporal context)
- Indices 22–33: up to 3 enemy bullets
- Has `prevSpeed`, `prevDirection` on `EnemyData` for one-step acceleration/turn-rate
---
## 6. SNNBot (`SNNBot_garage/src/SNNBot.nim`)
Tracks only:
- `enemyBearing` (absolute, from last `ScannedBotEvent`)
- `enemyDist`
- `hasContact`
No velocity, no history, no position tracking. The SNN input is population-coded
relative bearing only. **No lead targeting.**
---
## 7. QBot (`QBot_garage/src/QBot.nim`)
Tracks `enemyX, enemyY, enemyDir, enemySpeed, hasContact, ticksSinceScan`.
Uses a 5-slot `array[BULLET_BUF_CAP, BulletRecord]` ring buffer for associating
Q-updates to bullet outcomes (hit/wall). This is a *reward attribution* ring buffer,
not a position history.
---
## 8. OscillatorBot (garage + adversary copy)
**Files:** `OscillatorBot_garage/src/OscillatorBot.nim`,
`common_libs/test_framework/adversaries/OscillatorBot/src/OscillatorBot.nim`
Head-on targeting only: aims gun directly at `directionTo(myX, myY, e.x, e.y)`.
No lead. Both files are identical.
---
## 9. Targeting Utilities
**File:** `PPO_Bot_garage/src/PPO_Bot/controllers.nim`
```nim
proc aimToTick*(targetX, targetY, botX, botY, gunDirection: float): float
```
Rotates gun toward a target *point* (clamped to ±`MAX_GUN_TURN_RATE`). Used by PPO_Bot
via an (x,y) target the network chooses. No lead calculation inside — caller must
provide the predicted impact point if desired.
**File:** `common_libs/radar_lock/radar_lock.nim`
```nim
proc doRadar*(currentRadarHeading, enemyBearing: float64): float64
```
Width-lock with configurable overshoot (`DefaultOvershootDeg = 5.0`). Used by QBot,
SNNBot, and the PPO_Bot tracker's `getRadarTurnRate`.
---
## 10. Adversaries in `common_libs/test_framework/adversaries/`
Only two adversaries exist:
| Bot | Behavior |
|---|---|
| `SittingDuck` | Does nothing (stationary target) |
| `OscillatorBot` | Zigzag (±4°/tick turn, speed 7, reverses every 25 ticks), head-on gun |
**No wall-bot, no spinner, no circler adversary.**
---
## Reuse Opportunities for SNNBot Lead Targeting
| Need | Reuse from |
|---|---|
| Enemy velocity (x, y, speed, dir) | `EnemyTracker` from `PPO_Bot_garage/src/PPO_Bot/enemy_tracker.nim` — drop-in, no bot API deps |
| Position history | Same: 5-slot array, pre-filled on cold-start |
| Bullet speed formula | `bSpeed = 20.0 - 3.0 * power` (inline constant, no import needed) |
| Radar lock | `common_libs/radar_lock/radar_lock.nim` — already used by SNNBot |
| Gun turn to point | `aimToTick` in `PPO_Bot_garage/src/PPO_Bot/controllers.nim` (or inline) |
The missing piece — the iterative lead-angle solver (`for t in 0..20: if dist(predicted_pos(t), bullet_pos(t)) < eps: break`) — does not exist anywhere in the repo and would need to be written.