Both bots run a real finite-state controller like a mini-sumo competition robot (RoboCup / FIRST-style club builds):
SEARCH → rotate in place, scanning
CHARGE → opponent inside FOV cone and range → drive straight at it
EDGE → own distance to ring center > R_ring − r_bot − margin
→ highest priority: turn back toward center
Detection is a field-of-view test done with the dot product between the bot's forward heading ĥ and the unit vector û toward the opponent:
cos(θ) = ĥ · û
opponent visible ⇔ distance ≤ sensor_range AND θ ≤ FOV / 2
The polar panel below plots exactly that test: the shaded wedge is Blue's cone, the dot is the opponent's true bearing, and the readout compares cos θ against the cos(FOV/2) threshold live.
Motion is simple differential-drive kinematics integrated every frame with a clamped step Δt:
x += v·sin(ψ)·Δt
z += v·cos(ψ)·Δt
ψ += ω·Δt
On contact the overlap between the two circular hulls is resolved by pushing both bots apart along the line joining their centers, weighted by relative closing speed — the live push force readout is that closing-speed impulse. A round ends the instant a bot's center crosses the ring boundary (distance from center ≥ ring radius) — the boundary is exactly what an edge/line sensor detects on a real sumo bot's underside.
- FOV — a narrow cone (real IR rangefinders) makes Blue miss opponents to its side; a wide one (real ultrasonic array) spots them earlier.
- Sensor range — how far the proximity sensor reaches before an opponent registers as "seen".
- Charge speed — top speed once locked onto a target; faster hits harder but overshoots the edge more easily.
- Circle & flank — instead of driving straight in, Blue aims roughly 40° off the opponent's heading until close, trying to hit its side rather than its front, then straightens out to push.
- Drag / scroll — drag the arena to pan, scroll or pinch to zoom; the sensor cone and telemetry keep tracking live underneath.