Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Architecture

Rekkefly is one Rust crate: a library (src/lib.rs) with everything that tracks, records and publishes, and a binary (src/main.rs) for the command line. The GUI and the MCP server are clients of the same library.

A frame’s journey

 camera / video / stream / simulated fly
        │  source.rs, camera.rs, avi.rs
        ▼
 capture thread (one per rig) ── engine.rs
        │  8-bit gray frame, sequence number, arrival time
        ├──► tracker.rs: sample each sector, find edges ──► Measurement
        │        │
        │        ├──► ZMQ publisher (zmq_output.rs, a thread per subscriber)
        │        ├──► UDP sender (output.rs)
        │        ├──► JSONL file (measurement_log.rs)
        │        └──► subscribers: GUI plots, MCP `measure`
        │
        ├──► recorder (recording.rs): encoder threads, AVI segments, frames.jsonl
        └──► latest frame for the preview (GUI, MCP `snapshot`)

Tracking runs on the capture thread, so there is no queue between a frame arriving and its measurement being published. Everything slower than tracking, such as encoding, drawing and disk writes, runs on other threads and receives frames by reference, never by copy. Outputs never block tracking: a full subscriber queue drops messages for that subscriber, and the recorder stops loudly rather than silently dropping frames.

Modules

FileRole
src/camera.rsCamera listing and selection, mode negotiation, fast grayscale paths
src/source.rsImage sources: camera, native AVI, FFmpeg, simulated fly, the bundled example
src/avi.rsAVI reader and writer (MJPEG / PNG / Y800), including OpenDML and interrupted files
src/frame.rsGrayscale frames and scaling without distortion
src/tracker.rsPolar sampling and the classic, robust and centroid detectors; the measurement schema
src/synth.rsThe synthetic tethered fly with ground truth
src/engine.rsThe acquisition thread, commands, fallback to the example, measurement subscriptions
src/analyze.rs, src/overlay.rsOffline tracking and summaries; drawing the tracking onto frames
src/mcp.rsThe Model Context Protocol server
src/recording.rs, src/clip.rsVideo recording; cutting and converting videos
src/output.rs, src/zmq_output.rs, src/measurement_log.rsUDP, ZMQ and JSONL outputs
src/rigs.rs, src/lock.rs, src/installation.rsRig manifests, one-window-per-config locks, per-user configs
src/config.rs, src/geometry.rs, src/persistence.rsSettings and validation, marker editing, atomic autosave
src/gui.rsThe desktop window

Design rules

  • Never regress tracking. Detector changes are judged by the synthetic and real-footage tables (Tests).
  • No work on the capture thread that can wait. No allocations or frame copies in the tracking path; sampling positions are precomputed.
  • Never lose user data. Config writes are atomic and keep comments. Recordings never drop frames silently. Run-only overrides are never saved.
  • Fail loudly in experiments, gently in the GUI. A missing camera or busy port is an error headless and in rigs; in a double-clicked window it falls back with a visible banner.
  • Every operation is scriptable. Each GUI action has a command-line or MCP equivalent with machine-readable output.

Native window lifecycle

The eframe/egui 0.36 integration polls worker results and shutdown in App::logic, including while the window is hidden. App::ui builds the panels and camera view from the root UI. Tracking stays on the capture worker, while preview textures are refreshed when the UI is drawn.

Dependencies

PurposeCrates
Windoweframe / egui
Camerasnokhwa (AVFoundation, Media Foundation), v4l (Linux)
OutputsNone: the ZMQ publisher (zmq_output.rs) speaks ZMTP 3.0, 2.0 and 1.0 itself, as libzmq does
Images and videozune-jpeg (decoding), jpeg-encoder (encoding), image (PNG)
Configsserde, toml, toml_edit (comment-preserving writes)
Command lineclap

There is no C++ computer-vision library, no Python and no ROS: everything specific to wing tracking is in src/tracker.rs.