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

Configuration

Every rig has one TOML file: its source, markers, detector settings, outputs and recording. The GUI saves edits back into it automatically, keeping its comments. Configs are validated when loaded; an invalid value is reported with the key’s name, and nothing is changed.

Relative paths in a config are relative to the config file. Edits that change the source, the outputs or the label take effect after Settings → Restart acquisition. Everything else applies to the next frame.

tests/docs.rs checks that every key of the default config appears on this page.

Top level

KeyDefaultMeaning
instance"rig-a"Label for the window title, logs and recordings (1–128 characters)
autosavetrueSave GUI edits automatically, 300 ms after the last change and on close
preview_fps40GUI refresh rate, 1–120. Tracking always uses every frame

[source]

KeyDefaultMeaning
source.kind"camera""camera", "video", "network" (through FFmpeg) or "demo" (simulated fly)
source.device"auto"Camera: "auto", a number from --list-cameras, a device path, or part of the name (choosing a camera)
source.pathVideo file (kind = "video")
source.repeatfalseVideo: loop at the end
source.realtimetrueVideo: play at the recorded frame rate; false processes as fast as possible
source.urlStream URL (kind = "network"), for example rtsp://…
source.beat_hz0.8Simulated fly: how fast its stroke changes, below fps / 2
source.width, source.height640, 480Processing size, 32–8192 each, at most 32 megapixels. Other sizes are scaled to fit without distortion
source.fps30Requested camera rate, 1–10000

Only the keys of the chosen kind are allowed. A config with kind = "camera" and a path is an error, so a typo cannot be silently ignored.

Body axis: [head], [tail]

KeyDefaultMeaning
head.x, head.y320, 175The head end of the body axis (pixels)
tail.x, tail.y320, 330The tail end of the body axis (pixels)

The head and tail must be distinct, and the body axis must not be parallel to the line between the wing hinges.

[tracking]

KeyDefaultMeaning
tracking.asymmetricfalseEdit the wings independently instead of mirroring
tracking.dark_on_lighttrueA dark insect on a light background. false for a bright insect on dark
tracking.subtract_backgroundfalseTrack the difference from the saved background
tracking.background_path"rig-a.background.png"The background image, saved by Save BG
tracking.angle_bins240Angular samples per sector, 16–2048
tracking.radial_samples72Radial samples per sector, 4–1024 (bins × samples at most 524,288)

Parts: [tracking.left], [tracking.right], [tracking.head], [tracking.abdomen]

Each part has the same keys. Here <part> stands for left, right, head or abdomen.

KeyDefault (wings)Meaning
tracking.<part>.enabledtrue (false for head and abdomen)Track this part
tracking.<part>.hinge.x, tracking.<part>.hinge.yleft (296, 240), right (344, 240)The hinge (pixels): where the wing turns, at its base. For the head and abdomen, the pivot
tracking.<part>.start_degleft 135, right -85Where the sector starts: image degrees, clockwise from image-right
tracking.<part>.span_deg130The sector’s angular size, 5–355
tracking.<part>.inner_radius55Inner radius (pixels): just past the body
tracking.<part>.outer_radius185Outer radius (pixels): inside the wing blur
tracking.<part>.method"wing_blur" (wings), "centroid" (head, abdomen)"wing_blur" robust, "edge" classic, "centroid". "robust" is accepted for "wing_blur"
tracking.<part>.primary_edge"strongest"Which edge is the angle: "strongest", "toward_head" (leading edge) or "toward_tail" (trailing edge)
tracking.<part>.threshold0.0Minimum edge strength, 0–1. 0 reports the strongest edge
tracking.<part>.max_edges2Edges reported in angles_rad, 1–8
tracking.<part>.spike_width_deg5.0Robust detector: features narrower than this are ignored, 0–45
tracking.<part>.contrast_cap0.12Robust detector: contrast limit above the background, as a fraction of full brightness

What these mean, and when to change them: The detectors and Tuning a rig.

[output]

KeyDefaultMeaning
output.zmq_enabledtruePublish Kinefly-compatible ZMQ
output.zmq_bind"tcp://*:9871"ZMQ publisher address. tcp://127.0.0.1:9871 keeps it on this computer
output.enabledtrueSend full measurements over UDP
output.bind"127.0.0.1:5501"This rig’s own UDP sending address; every rig needs a different port
output.target"127.0.0.1:5601"Where your UDP receiver listens
output.jsonl_path""Also write every measurement to this JSONL file. Empty = off. Never overwritten

See Receiving measurements.

[recording]

KeyDefaultMeaning
recording.enabledfalseRecord from the start of every run
recording.directory"recordings"Where recording sessions go
recording.format"mjpeg""mjpeg", "png" or "raw"
recording.quality90MJPEG quality, 1–100
recording.queue_frames32Frames that may wait for the disk, 1–256 (at most 256 MiB)
recording.segment_mb1024Start a new AVI file at this size, 16–1900

See Recording video.

A complete config

The config for the first camera, as shipped, with its comments:

# Rig A: the first camera. UDP 5501 → 5601, ZMQ 9871.
# The GUI saves marker and detector edits back into this file automatically;
# these comments are kept. Run it with:  rekkefly --config <this file>
# Every setting is explained in the README ("Configuration reference").

# Name shown in the window title, logs and recording folder names.
instance = "rig-a"
# How often the GUI preview refreshes. Tracking always uses every frame.
preview_fps = 40
# Save GUI edits 300 ms after you stop dragging (and on close).
autosave = true

[source]
# kind: "camera", "video", "network" or "demo" (simulated fly).
kind = "camera"
# device: "auto" = first camera that opens; a number = its position in
# `rekkefly --list-cameras` (0 = first); or a device path such as
# /dev/v4l/by-id/... (Linux, stable across reboots), or part of the camera name.
device = "auto"
# Processing size and requested frame rate. Other camera modes are scaled to fit.
width = 640
height = 480
fps = 30

# Body axis: drag the magenta head dot and cyan tail dot onto the insect.
[head]
x = 320.0
y = 175.0

[tail]
x = 320.0
y = 330.0

[tracking]
# false: the wings mirror each other across the head–tail axis while you edit.
asymmetric = false
# Angular and radial sampling of each sector (more = finer, slower).
angle_bins = 240
radial_samples = 72
# true: dark insect on a light (backlit) background; false: bright insect on dark.
dark_on_light = true
# Track the difference from a saved empty-scene image ("Save BG" in the toolbar).
subtract_background = false
background_path = "rig-a.background.png"

# Wing sectors. Angles are image degrees, clockwise from image-right.
# method: "wing_blur" = robust, ignores legs and antennae (default)
#         "edge"      = classic strongest edge of the averaged profile
#         "centroid"  = intensity centroid (used for head/abdomen)
# threshold: 0 reports the strongest edge however faint; raise it to reject noise.
# spike_width_deg: robust mode ignores dark features narrower than this (legs, antennae).
# contrast_cap: robust mode limits contrast so opaque legs cannot outweigh a translucent wing.

[tracking.left]
enabled = true
start_deg = 135.0
span_deg = 130.0
inner_radius = 55.0
outer_radius = 185.0
method = "wing_blur"
threshold = 0.0
max_edges = 2
primary_edge = "strongest"
contrast_cap = 0.12
spike_width_deg = 5.0

[tracking.left.hinge]
x = 296.0
y = 240.0

[tracking.right]
enabled = true
start_deg = -85.0
span_deg = 130.0
inner_radius = 55.0
outer_radius = 185.0
method = "wing_blur"
threshold = 0.0
max_edges = 2
primary_edge = "strongest"
contrast_cap = 0.12
spike_width_deg = 5.0

[tracking.right.hinge]
x = 344.0
y = 240.0

[tracking.head]
enabled = false
start_deg = -125.0
span_deg = 70.0
inner_radius = 12.0
outer_radius = 62.0
method = "centroid"
threshold = 0.0
max_edges = 2
primary_edge = "strongest"
contrast_cap = 0.12
spike_width_deg = 5.0

[tracking.head.hinge]
x = 320.0
y = 205.0

[tracking.abdomen]
enabled = false
start_deg = 55.0
span_deg = 70.0
inner_radius = 15.0
outer_radius = 88.0
method = "centroid"
threshold = 0.0
max_edges = 2
primary_edge = "strongest"
contrast_cap = 0.12
spike_width_deg = 5.0

[tracking.abdomen.hinge]
x = 320.0
y = 265.0

[output]
# Full measurements as JSON over UDP, one datagram per frame.
enabled = true
# This rig's own sending port: every rig needs a different one.
bind = "127.0.0.1:5501"
# Where your receiver listens (python3 examples/receive_udp.py --port 5601).
target = "127.0.0.1:5601"
# Also write every measurement to this JSONL file (relative to this config). Empty = off.
jsonl_path = ""
# Kinefly-compatible ZMQ publisher. Subscribers connect to tcp://<this computer>:9871.
zmq_enabled = true
zmq_bind = "tcp://*:9871"

[recording]
# Start recording as soon as this rig starts (the Record button works any time).
enabled = false
# Folder for recordings, relative to this config.
directory = "recordings"
# "mjpeg" = small (about 10–20× smaller than raw), "png" = lossless, "raw" = lossless and largest.
format = "mjpeg"
# MJPEG quality 1–100; 90 is visually lossless for wing tracking.
quality = 90
# Frames buffered for the disk writer, and the size of each AVI file.
queue_frames = 32
segment_mb = 1024

The other shipped configs are in configs/: camera-b.toml (second camera and ports), bogong-moth.toml (the example video), demo.toml (the simulated fly), network.toml (an RTSP stream) and rigs.toml (a rig manifest).

Rig manifests

rigs.toml lists rigs to start together; its keys are in Several rigs at once.