The new Kinefly · v0.6

Wing tracking for tethered insects, done right.

Rekkefly follows each wing's stroke envelope from a camera or a video and streams L − R, the steering signal, to your closed-loop experiment in real time. One small native app. No ROS, Python, OpenCV or Docker.

Free and open source · macOS · Windows · Linux

A real tethered Bogong moth at 30 fps, exactly as filmed. On top: each wing's sector and the leading edge Rekkefly reports, and its measurement of every frame. The wingbeat is faster than the camera, so L and R jump between frames while L − R stays steady.
340 µsto track a 640×480 frame
3 of 900moth frames where painted antennae moved L − R (classic: 489)
6%of one CPU core for a 30 fps rig
15MCP tools for AI agents

How it works

Legs are sharp. Wings are broad.

A beating wing leaves a translucent stroke envelope tens of degrees wide; its leading edge is the stroke amplitude. A leg or an antenna is narrow, and because it is in focus, its edges are sharper than the wing's. A detector that reports the sharpest edge jumps onto it. Rekkefly ranks each edge by the broad blur shoulder behind it.

Frames where the antennae moved L − R by more than 5°0 of 0
Frames where the antennae moved L − R by more than 5°0 of 0
The same real footage with two thin bright lines painted on, sweeping from the head through both wing sectors like antennae. Each detector is compared with its own result on the clean frame. Over the whole clip: classic 489 of 900 frames, Rekkefly 3. More evidence.
  1. SampleEach sector is sampled on a polar grid around its hinge, from positions computed once.
  2. Remove narrowFeatures narrower than 5° are opened away in every radial band, however dark.
  3. VoteThe median across bands out-votes anything present at only some radii.
  4. Rank by shoulderEdges score by steepness times the blur behind them; the steepest point gives the angle.

Evidence

Measured, not claimed.

Thin lines painted through the wings of the real moth, compared frame by frame with the same frames without them. And synthetic flies with exactly known angles, legs kicking through the wings.

Over 30 seconds of the real moth with painted antennae, the classic detector's L minus R moves by more than 5 degrees in 489 of 900 frames, often by over 100 degrees; Rekkefly's moves in 3 of 900.
TestClassicRekkefly
Real moth, painted antennae: frames where L − R moved > 5°489 / 9003 / 900
Real moth, painted legs 5 px wide632 / 9008 / 900
Synthetic: legs kicking through the wings, worst L − R error107°0.6°
Synthetic: front legs reaching forward, wing angles off by > 4°720 / 7200 / 720
Median angle error, synthetic flies with known angles—≈ 0.25°

Reproduce with cargo test --release --test moth -- --ignored and --test intrusions. All the tables, and what is not yet verified.

Total frames per second with every rig decoding and tracking its own moth video: about 970 for one rig, 2,040 for two, 3,960 for four and 3,770 for eight, far above the 240 frames per second that eight 30 fps cameras need.

Performance

Tracking is never the bottleneck.

  • Tracking runs on each rig's capture thread, as each frame arrives.
  • No frame copies: sectors are sampled from precomputed positions.
  • Recording encodes on its own threads, never on the capture path.
  • Eight rigs on four cores still leave 15× headroom at 30 fps.
Benchmarks

Lineage

Standing on Kinefly's shoulders.

Rekkefly keeps Kinefly's method and conventions (annular sectors around the hinges, the leading edge of the stroke envelope, angles positive toward the head) and drops the stack around it.

  1. Kinefly

    Made it practical

    Real-time wing, head and abdomen tracking for tethered flight, on ROS 1 and Python 2. Both are now end-of-life.

    ssafarik/Kinefly
  2. Kinefly Docker

    Kept it alive

    The original stack in a container, plus a bridge that publishes wing angles as simple JSON over ZMQ.

    pvnkmrksk/Kinefly_Docker
  3. Rekkefly

    The next step

    A native app, written from scratch in Rust, that sends the bridge's message byte for byte, to any ZeroMQ library, Unity's NetMQ included. Point your subscriber at it and it keeps working.

    Coming from Kinefly
ZMQ, tcp://*:9871: one message per frame
{"timestamp_unix": 1700000000.125, "pitch": 0.0, "y": -0.5, "x": 0.25,
 "yaw": 0.75, "z": 0.0, "roll": 0.0, "frame_number": 77}

Automation

Built for scripts and AI agents.

A Model Context Protocol server is built in. An agent can list cameras, edit configs with validation, start and stop rigs, read live angles, measure a trial, and see a snapshot with the tracking drawn on it, to check the markers before it measures.

Every command also has --json output, configs are commented TOML, and live data streams over ZMQ and UDP.

All 15 tools
# Add Rekkefly to Claude Code (or any MCP client)
claude mcp add rekkefly -- rekkefly mcp

# Then ask: "Start arena 1 on camera 1, check the markers,
#  and give me the mean L − R over a 10-second trial."
start_rig  {config: "camera-a", device: "1", label: "arena-1"}
snapshot   {rig: "arena-1"}          → image with the sectors
measure    {rig: "arena-1", seconds: 10, csv: "trial-01.csv"}
stop_rig   {rig: "arena-1"}

Read the docs.

From the first five minutes to every setting: installing, placing the markers, tuning, rigs, outputs, agents and the full reference.