The fly’s movement comes from a repeated calculation: environment geometry produces input, the circuit updates, motor readouts produce forces, and the new pose changes the next input.
The software loop
- SenseCalculate size, expansion, and bearing.
- PropagateUpdate the signed rate network.
- ActTurn motor rates into body commands.
- IntegrateUpdate velocity and position.
The body advances in 20 ms model steps. During each step, the sensory vector is held fixed while the neural network performs ten synchronous 2 ms updates. The motor adapter then reads the new activity and updates the body. Everything starts from zero activity and a resting pose.
This is a closed loop because the next input depends on what the body just did. The target has a prescribed trajectory, but there is no prescribed fly trajectory or goal-seeking controller steering it around the target.
Vision from geometry
The default target is a sphere of radius 1.25 arena units. Its x-coordinate follows 12 − 2.4t, its height is 1.1, and its lateral offset selects frontal, left, or right approach. A stationary control keeps it at x=6.
For distance d, radius R, and relative approach velocity vradial, the implementation calculates:
expansion = max(0, −2R vradial / (d² + R²))
The expansion signal is scaled, clipped, and weighted by the target’s bearing. It is zero outside the forward field. Side-specific drive enters LC4; LPLC2 drive also receives an angular-size factor. The exact clipping and scaling rules are in the equation notes.
These rules are a feature-level approximation. They skip photoreceptors, individual ommatidia, within-type spatial structure, and image processing. The visual-field canvas is an explanation of the geometry, not the input image to a retina model.
A small, explicit motor adapter
The updated network state contains activity for every included population. Three readouts connect it to the body:
| Readout | Transformation | Body effect |
|---|---|---|
| Mean bilateral TTMn | Crosses 0.008 while grounded, with more than 1 s since the previous launch. | Sets upward velocity to 4.2 au/s. |
| Mean DLMn/DVMn | p = tanh(mean activity / 0.018). | Scales lift and forward thrust. |
| b2 right minus left | q = tanh(activity difference / 0.008). | Scales yaw torque, together with power p. |
The anatomy motivates separate launch and wing readouts: TTMn is associated with a jump muscle, DLM/DVM with wing power, and b2 with wing steering. hDVM denotes haltere power and is excluded from the lift readout. The particular thresholds, gains, timing, and yaw sign above are assumptions. Cheong et al., motor-circuit anatomy.
Each of the ten selected wing-power populations contributes equally to the mean. A population containing several neurons is still one contribution. No motor adapter reads the target’s position directly; environment influence passes through the sensory input and network first.
Move the body with simple dynamics
The adapter combines motor commands with gravity and drag. For power p, yaw command q, lift multiplier L, and heading ψ, the acceleration rules are:
yaw acceleration = 6 q p − 3 yaw_rate
forward thrust = 7 p, once off the floor or launching
x acceleration = thrust cos(ψ) − 1.7 vx
y acceleration = thrust sin(ψ) − 1.7 vy
z acceleration = 20 L p − 9.8 − 1.1 vz
Velocities are updated before position. A floor, side walls, and ceiling constrain the state. The visual sphere has no collision force. The model omits muscle mechanics, aerodynamic wing forces, body collisions, airflow, and leg articulation.
Distances are reported in arbitrary arena units. Although the display mesh is scaled to one nominal body length, the acceleration and time parameters are not calibrated to that physical scale. A reported model speed cannot be read as a measured fly speed.
The rules also explain a potentially surprising outcome: wing lift can raise the body without a TTMn jump. Silencing DNp01 can therefore remove an early launch while leaving later body movement. That follows from the declared network and adapter; it is not proof of a biological alternative-takeoff mechanism.
Draw the fly without confusing appearance with physics
Flybody supplies an anatomical model designed for MuJoCo and locomotion research. The app reuses its geometry, pinned to a source commit and decimated to 81 pieces with 28,700 triangles. The original XML transforms are baked into a compact display asset.
Three.js renders that asset at the computed pose. Wings have a deliberately slowed display oscillation whose amplitude follows the connected power command. This is not asynchronous muscle simulation. Flybody’s MuJoCo dynamics, aerodynamic model, and trained control policies are not executed by this site.
The same computed state drives the body view, neural graph, numeric readouts, event list, and traces. The renderer can change cameras without changing the simulation. When 3D rendering is unavailable, a labeled 2D position view can still display the numerical result.
How the implementation is organized
| Source file in the download | Responsibility |
|---|---|
python/prepare_graph.py | Download source tables, aggregate populations and counts, select the original subnetwork. |
python/prepare_arena_graph.py | Add actual wing motor units and their input context. |
dist/sim.mjs | Batch and stateful versions of the signed rate equation. |
dist/sim.worker.mjs | Run the circuit experiment away from its interface thread. |
dist/world-sim.mjs | Pure sensory, neural, motor, and body integration. |
dist/world.mjs | Arena controls, recorded states, playback, readouts, and exports. It steps the compact model on the browser’s main thread. |
dist/world-render.mjs | 3D anatomy, cameras, trajectory, force indicators, and fallback view. |
python/simulate_full.py | Sparse full typed-CNS propagation. |
The prepared experiment runs locally in the browser after the assets load. It makes no model-server calls during a run and does not require a GPU service or an LLM. The Python scripts support data preparation and larger-scale experiments.
Reproduce the arena without its interface
Download and unzip the project. With Node.js available, run this from the package root:
node examples/run-arena.mjs
node examples/run-arena.mjs power
The example imports the same graph and pure simulation used by the site. It prints maximum height above the floor and final horizontal displacement, so the comparison can be reproduced without depending on the rendering.
To use the interactive site locally, serve its static directory with Python and open the local address printed by the server:
python -m http.server 8000 --directory dist
The README covers full-data preparation and sparse Python runs. The detailed model notes list every geometric coefficient, boundary rule, and asset provenance record.