-
Notifications
You must be signed in to change notification settings - Fork 1
Record and Replay
Record and Replay ("Clips") captures everything your droid does over a bounded window — Maestro servo moves, HCR / MP3 / WLED / WCB commands, aux‑serial, and continuous knob/gimbal streams — saves it as a named clip, and plays it back on demand. Clips live in a renamable library on the board, and can be triggered from a transmitter control, the config tool, or the serial CLI.
The feature is implemented in firmware in the navirec namespace (navicore_record.h) and surfaced in the config tool as a 🎬 Clips panel with a 📈 timeline editor.
A clip is a timestamped event list. Recording taps three sources as they happen:
- Discrete actions — every dispatched WCB (unicast/broadcast), Maestro, aux‑serial, HCR, MP3, and WLED action.
- Maestro knob keyframes — continuous passthrough knob → servo moves, captured as dense keyframes (one per knob change past the deadband).
- HCR‑volume keyframes — the post‑gate volume a knob emits.
The lifecycle is record → save → library → replay. You start a capture, perform the moves, stop (which always saves the take), then play the clip back at any time. Replay re‑dispatches the discrete actions through the same code path they took live, and drives Maestro motion with a continuous interpolating curve‑follower — so playback is at least as smooth as the original move.
🚀 Because Maestro motion is re‑interpolated on replay rather than fired keyframe‑by‑keyframe, a clip recorded from jittery knob input plays back smoothly.
Persisted clips need the 16 MB custom‑partition firmware. Clips are stored on a dedicated 12 MB clips LittleFS partition (offset 0x400000, size 0xc00000), mounted as a second LittleFS with its own label and base path so its format never touches the config filesystem or /config.json.
| Board build | Clip behavior |
|---|---|
| 16 MB custom‑partition build | Clips are saved to the clips partition and survive reboots. |
Old 4 MB (min_spiffs) table |
Record/replay still works, but clips are in‑RAM only and lost on reboot. |
On a board without the clips partition the firmware logs:
[CLIPS] no `clips` partition — clips are in-RAM only (flash the 16 MB partition build)
Enabling persistence requires a full flash of the 16 MB build (the 16 MB custom bootloader + PartitionScheme=custom + FlashSize=16M). An app‑only OTA update does not change the partition table. See Flashing the Firmware.
Clip file format (/<name>.ncr): a small header followed by the raw event array.
| Field | Value |
|---|---|
magic |
"NCR1" |
version |
1 |
mode |
function‑switch state at record time (clip context) |
count |
number of events that follow |
durationMs |
clip length (derived from the last event's timestamp) |
Limits and names:
-
Recording window: 60 s backstop (
REC_MAX_MS). A take that runs past 60 s is auto‑stopped and saved so a long take is never lost. -
Event buffer: 24000 events (
RecEventis 136 B ≈ 3.1 MB of PSRAM). A very dense capture can hit the event cap before 60 s; drop‑if‑full at either the capture queue or the buffer just thins a frame (counted indrops). -
Clip names: sanitized to
[A-Za-z0-9_-]and truncated to 32 characters on save. Non‑matching characters are silently stripped.
- Connect the board over USB or Via‑WCB (see Connecting).
- Click the 🎬 Clips toolbar button.
- In the Record row, optionally type a clip name. Leave it blank to auto‑save as
rec_1,rec_2, … (lowest unused number). - Click ● Record. The button becomes ■ Stop & Save.
- Perform the droid moves.
- Click ■ Stop & Save.
The take is always saved — a named clip overwrites that name, a blank name auto‑names rec_N. The library refreshes automatically after a save.
The Library section of the Clips panel lists every saved clip. Press ⟳ Refresh to query the board; it shows a storage‑usage bar (from the partition's total/used bytes) and one row per clip with its duration and byte size.
Each clip row has:
| Button | Action |
|---|---|
| ▶ Play | Load the clip from flash and replay it |
| 📈 | Open the timeline editor |
| ✎ | Rename the clip |
| 🗑 | Delete the clip |
Renaming or deleting a clip also re‑points any transmitter trigger actions that reference it by name (button tap‑tiers and switch positions, plus an open timeline's actions). Those changes are local until you Save the config to the board.
The Clips panel works over Direct USB or Via‑WCB — over the bridge, commands are relayed to the target board. See Remote Management over WCB.
In the Action Editor and Command Library you can map three record/replay action types onto a button or switch:
| Type | Behavior |
|---|---|
| Record (toggle) | Fire → start capturing. Fire again → stop and save. Optional clip name (blank → rec_N). |
| Play clip | Fire → load the named clip from flash, then replay. Fire again while playing → stop. Optional Loop checkbox for idle‑animation replay. |
| Stop | Explicit halt — saves an in‑progress recording, aborts an in‑progress replay. |
Both Record and Play are toggles: one control starts and stops. Assign the action, then Save the config to the board. The record/play/stop action types are never captured into a clip.
⚠️ Record is toggle‑only in firmware. A matrix button delivers only a debounced tap‑count (no release or hold duration), so toggle is the only matrix‑button‑safe mode — there is no separate hold/level record handler.
All record/replay CLI commands are ?REC sub‑commands (see CLI Commands and Serial JSON Protocol).
| Command | Effect |
|---|---|
?REC,START |
Start recording |
?REC,STOP |
Abort recording or an in‑progress replay |
?REC,PLAY[,name] |
Load name (if given) and replay |
?REC,SAVE[,name] |
Save the current take; blank name auto‑names rec_N
|
?REC,LOAD,name |
Load a clip into the buffer |
?REC,LS |
List clips (emits a [CLIPFS] storage line, then [CLIPLIST] / [CLIPITEM] lines) |
?REC,RM,name |
Delete a clip |
?REC,RENAME,from,to |
Rename a clip (emits `[CLIPUL:RENAME,OK |
?REC,CLEAR |
Clear the in‑RAM buffer |
?REC or ?REC,INFO
|
Print state, event count, duration, and drops |
The timeline editor uses additional transport verbs: EDITLOAD, EDITBEGIN, EDITEV, EDITEND, and EDITCANCEL.
Typical CLI record/replay session:
?REC,START
… perform moves …
?REC,STOP
?REC,SAVE,wave
?REC,PLAY,wave
Replay is deliberately faithful, and it owns the outputs while it runs.
- Discrete actions are re‑dispatched through the same path as live input, so emotion/verb rewrites and routing re‑apply exactly.
-
Maestro motion is not fired keyframe‑by‑keyframe. A curve‑follower emits a linearly‑interpolated ¼µs position for every active
(slot, ch)on every tick. Before the first frame it forces speed = 0 / accel = 0 on every touched channel (so the Maestro's own smoothing can't double‑smooth the interpolated stream), then eases in from the servo's last‑commanded position. The interplay with Maestro speed/accel limits is covered in Maestro Setup. - HCR volume replays through a raw SetVolume path that bypasses the live volume‑dedupe cache, so recorded volume ramps aren't decimated. See WLED and HCR Audio.
- Live dispatch is suppressed during replay — button, switch, knob, and remote input are gated off, except the record/play/stop controls, so a mapped button can still stop a running clip.
-
Loop mode (
fn = 1on a Play action) rewinds cheaply at the end of each lap and eases the loop seam. - A 1‑second safety net past the clip's length completes replay even if a bad timestamp would otherwise wedge it, so live control is never locked out indefinitely.
⚠️ A looping Play clip keeps replay active — and therefore keeps live control locked out — until you fire the control again to stop it.
Anti‑snap servo shadow. The firmware keeps a last‑commanded position per slot + ch, written on every real Maestro move. goHome / stopScript and single‑channel auto‑release mark a channel's pose as unknown, so replay re‑anchors and snaps to the next keyframe instead of sweeping the servo up from a stale pose.
Click 📈 on a clip row to open the SVG timeline editor. It:
-
Downloads the clip from the board (
?REC,EDITLOAD, streamed as tagged JSON lines). - Shows one draggable‑keyframe polyline per Maestro
(slot, ch), HCR‑volume curves, and an Actions row. - Lets you add / select / delete / drag keyframes, add and edit actions, apply easing (which inserts denser synthesized keyframes — the firmware only ever linearly interpolates), Smooth, Undo (Ctrl+Z), and zoom / Fit.
-
Uploads the edited clip back (
?REC,EDITBEGIN→ indexed, idempotent?REC,EDITEVper event →?REC,EDITEND, which re‑sorts events by time and saves).
⚠️ Editing is best over Direct USB. Download and upload run in the main loop and block SBUS/heartbeat servicing for their duration, so over the WCB bridge the firmware refuses clips larger than 3000 events — connect over USB to edit those.
- Persistence requires the 16 MB build. On the old 4 MB table clips live only in RAM and are lost on reboot; the enabling change arrives only via a full flash, not an app‑only OTA.
-
Clips are not self‑describing. The stored header is only
{magic, version, mode, count, durationMs}. Replay depends on the board's current live routing, volume, and servo state — the servo home used for ease‑in is read live at replay start, and volume/destination shadows are not restored. Replaying a clip on a differently‑configured board (or after routing changes) may mis‑route or mis‑anchor. - MP3 NEXT / PREV are not deterministic on replay — they advance relative to the module's live track pointer, which NaviCore doesn't shadow. Use absolute "Play track N" in recorded routines.
- Playing a missing clip does nothing. A named Play that isn't on the board won't fall back to a stale in‑RAM clip.
-
Name sanitization can change targets. Because names are stripped to
[A-Za-z0-9_-]and truncated to 32 chars in both the save path and the action editor, a name with other characters can end up pointing a trigger at a different clip than you expect. -
Event and time caps. 60 s window and 24000 events; a dense capture can hit the event cap first. Dropped frames are counted and reported by
?REC.
See also: Action Editor and Command Library · Maestro Setup · WLED and HCR Audio · CLI Commands · Config Tool Guide
NaviCore — Astromech Animation Controller · Home · WCB v3.2 / ESP32‑S3
Setup
- Setup Guide — start here
- PCB Assembly and BOM
- Hardware and Wiring
- Flashing the Firmware
- Transmitter Setup
- Connecting
- Config Tool Guide
- Maestro Setup
Reference
- Action Editor and Command Library
- Actions Reference
- WLED and HCR Audio
- Record and Replay
- Cheat Sheet
- Configuration Schema
- WCB Network
- Remote Management over WCB
- Serial JSON Protocol
- CLI Commands
- Failsafe and Signal Loss
- Glossary
Help