PixiJS port of the Raspberry Pi laser combat tank ยท 10 hits to win
A robot is a computer with hands. This tank's "brain" is a set of behaviours that switch: drive, aim, reload, play a melody. At every heartbeat (10 ms) the code checks a few conditions โ "did the player move the stick?", "did we get hit?", "is the magazine empty?" โ and reacts. That pattern, a finite-state machine, is the whole secret of the project: complex behaviour from simple, well-defined states and crisp transition rules.
A finite-state machine is a flowchart the program actually lives inside: exactly one state is active at a time, and every arrow between states has a condition. Formally,
\[ \delta : S \times I \rightarrow S \]
โ a transition function mapping (current state, input event) to the next state. The C code runs four parallel FSMs on a shared 10 ms clock:
The web edition ports these states and timings 1:1 โ the game you play is the C program's behaviour, rendered in the browser.
A digital pin can only be fully on or fully off. PWM (pulse width modulation) fakes "in between" by switching very fast:
\[ \text{duty} = \frac{t_{\text{on}}}{T} \times 100\% \]
The duty cycle โ fraction of time the pin is high โ sets the effective voltage, i.e. the motor speed. The wheels use hardware PWM (pins 18/19: precise, no CPU involvement); the turret servos use software PWM (pins 17/27), where the pulse width itself encodes the angle (e.g. 1 ms โ 0ยฐ, 1.5 ms โ 90ยฐ, 2 ms โ 180ยฐ).
Mechanical buttons "bounce": the contacts chatter for a few milliseconds before settling. Without care, one press looks like many. The fix is a debounce window โ ignore readings until the signal has been stable for a few ms โ so exactly one event fires per press.
The laser is infrared light; the receiver raises a hardware interrupt (pin 11, rising edge) the moment a hit arrives. The controller counts magazine rounds (10 shots, reload with X) and applies damage to the opponent's HP.
Raspberry Pi + tricycle-drive chassis, wiringPi control (PWM 18/19, servos 17/27, buzzer 23, laser 9, hit interrupt 11), Xbox 360 controller via the xbox360controller Python bridge. Full FSM architecture: docs/fsm_arch.svg.