← Work

Full-stack engineer

LunarComm — Delay-Tolerant Lunar Mesh

Role
Full-stack engineer
Built with
Python · FastAPI · NetworkX · NumPy · React · TypeScript · Three.js · Zustand
Mission control in the nominal state: the tactical view of Shackleton crater with lander, two rovers and two beacons linked, beside a node status matrix and a bundle inspector listing delivered bundles

A mission-control simulation for ISRO–JAXA LUPEX operations around Shackleton’s south pole. Rovers lose line-of-sight inside Permanently Shadowed Regions, so the system does not assume a continuous radio link. It builds a breadcrumb relay mesh, stores RFC-style bundles until a hop reopens, and renders the crater from a NASA LOLA heightfield. The interesting part is not the 3D viewport but the connectivity problem underneath it: when a hop dies, who holds the data, how the mesh is extended, and what the rover is allowed to do in the seconds after blackout.

Problem

Crater geometry breaks RF. An exact, always-on mesh is not the operating regime: links appear and vanish with terrain, range, and solar-flare attenuation. The practical question is how to keep science data moving under intermittent connectivity, and how to let an operator keep driving for a bounded window after signal loss without stranding the rover beyond recovery.

Approach

The backend runs a 10 Hz physics tick: bilinear LOLA sampling for line-of-sight, RSSI from free-space path loss plus terrain attenuation, NetworkX for the RF graph, and DTN FIFOs aligned with RFC 9171 (QUEUED → IN_TRANSIT → DELIVERED / FAILED, TTL, burst flush on reconnect). Auto-beacons drop when RSSI crosses a threshold, subject to cooldown, spacing, and inventory. Live Demo pauses that feed and becomes client-authoritative: BFS over lander, relays, and both rovers as transceivers; exact-perimeter drops only on the 0.95R–R rim (R = 300 m); a 29 s speculative probe on blackout with a 35 s pose FIFO, then autonomous reverse if no hop is found. Solution quality was judged in demo rehearsal (mesh re-acquire, probe timeout, chaos flare) rather than against a published DTN benchmark, so no delivery-ratio figure is claimed.

Screens

Launch film · 21 seconds, with sound.
Mission control in the nominal state: the tactical view of Shackleton crater with lander, two rovers and two beacons linked, beside a node status matrix and a bundle inspector listing delivered bundles
Nominal. Every node holds a link, and the inspector shows bundles arriving one hop from a rover to the lander.
The rover chase camera following a rover across the crater floor, with mesh range rings drawn around it and the mission control panel showing Live Demo mode
Live Demo hands kinematics to the client and pauses the backend feed, so the mesh you see is being solved in the browser as the rover drives.
A beacon deployed on the rim of the lander's range ring, with the event log reading “relay deployed at maximum perimeter”
A breadcrumb dropped at the edge of range, not inside it. Placing a relay anywhere closer wastes the reach it was carried out to buy.
The blackout state: a signal-lost banner counting down the probe window, the rover marked SPECULATIVE PROBE · HOLD, and the bundle inspector filling with queued bundles
Line of sight breaks. The rover keeps driving on a 29-second speculative probe while science data queues locally instead of being lost.
The LOS critical state, the viewport washed red, the rover marked BACKTRACKING, and the event log reading “probe failed — reversing 35 s breadcrumb”
The probe expires with no hop found, so the rover reverses along its own 35-second pose history — the bounded part of “keep driving after blackout”.
The first-person view at the moment the mesh returns, with the event log reading “mesh re-acquired — control restored” and the queued bundles flushed
Reacquire. Control returns and the buffered bundles burst-flush in one pass, which is the whole point of holding them rather than dropping them.
The tactical view back in the nominal state, mesh rings intact around the lander and both rovers, with an empty bundle queue
Back to nominal, queue empty. The round trip — blackout, probe, backtrack, reacquire — is the behaviour the simulation exists to exercise.

Watch the walkthrough on YouTube Walkthrough: nominal mesh, blackout, speculative probe, and reacquire.

End-to-end architecture

End-to-end architecture
The mode switch in the middle is the load-bearing part: one toggle decides whether the backend or the browser is authoritative for the mesh.
Describe the diagram

The full LunarComm system. On the left, the actors and peripherals: the operator's dashboard, a gamepad, a phone trigger, a keyboard failsafe, and a one-off offline bake of NASA PDS elevation data. That bake produces a single terrain file consumed byte-identically by both halves of the system. The backend container runs a FastAPI process on a 10 Hz tick — a simulation engine for kinematics and auto-breadcrumbs, an RF model computing RSSI from free-space path loss minus terrain attenuation, a terrain context that raycasts line of sight against the elevation model, and a DTN layer holding RFC-style bundles in per-node FIFOs with TTL and a burst flush on reconnect. The frontend container runs React and react-three-fiber: an app shell, a scene graph of visual, entity and UI layers, and two stores. A mode switch decides which store is authoritative — the telemetry store ingesting backend snapshots, or the Live Demo store which pauses that feed and solves the mesh client-side. A shared terrain contract keeps the frontend's sampling identical to the backend's, so both agree on where the ground is.