replay-session.sh: a recorded session's frames through the decoder, live to displays
/ crosscheck (push) Successful in 1s

Frames go onto vcan_replay (the recorder never sees them); the decoder service
stands aside for the replay and comes back however it ends.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DDwfd6Ki8UfG4hK6W5YpJz
This commit is contained in:
2026-10-14 08:59:51 +09:00
parent c29f5819c5
commit ba6100fd17
2 changed files with 43 additions and 0 deletions
+2
View File
@@ -30,6 +30,8 @@ scripts/deploy-native.sh BIN # build BIN on the development Orin,
# Redeploy after any contracts signals.json change
yukart-decoder --list # the signals it decodes, and where
zstdcat can-*.log.zst | yukart-decoder --replay # what it would publish for a recording
scripts/replay-session.sh SESSION_DIR [SKIP_S] # on the Orin: replay a session's frames through a
# decoder on vcan_replay, live to displays; never recorded
yukart-obd-poller --elm ADDR --once # on the Orin, service stopped: adapter, protocol,
# supported PIDs and one value each
yukart-gnss --once # the next fix as JSON, no broker
+41
View File
@@ -0,0 +1,41 @@
#!/usr/bin/env bash
# Replay a recorded session's CAN frames through the decoder, so displays react as
# if the car were live. Runs on the car Orin (sudo: vcan and the decoder service).
#
# usage: scripts/replay-session.sh SESSION_DIR [SKIP_S]
# SESSION_DIR e.g. /var/lib/yukart/recordings/000001-20261013T170050
# SKIP_S seconds of the recording to skip first (default 0)
#
# Frames go onto a virtual interface, vcan_replay, never can_pcan: the recorder only
# watches can_pcan, so a replay is never recorded as a drive. The decoder service is
# stopped for the replay (one MQTT client id) and a decoder runs on vcan_replay instead;
# however the replay ends (finished, Ctrl-C, killed), the service comes back and the
# interface goes. Values carry the replay's own timing; nothing marks them as replayed.
set -euo pipefail
SESSION="${1:?usage: replay-session.sh SESSION_DIR [SKIP_S]}"
SKIP="${2:-0}"
IF=vcan_replay
ls "$SESSION"/can-*.log* >/dev/null
cleanup() {
[ -n "${DEC:-}" ] && kill "$DEC" 2>/dev/null || true
sudo ip link del "$IF" 2>/dev/null || true
sudo systemctl start yukart-decoder
echo "replay: done; yukart-decoder back on can_pcan"
}
trap cleanup EXIT INT TERM
sudo modprobe vcan
sudo ip link add "$IF" type vcan 2>/dev/null || true
sudo ip link set "$IF" up
sudo systemctl stop yukart-decoder
/usr/local/bin/yukart-decoder --can "$IF" &
DEC=$!
sleep 1
echo "replay: $SESSION from +${SKIP} s onto $IF"
# candump -L lines: "(1791878450.945008) can_pcan 139#...". Skip by the first frame's time.
zstdcat -f "$SESSION"/can-*.log* 2>/dev/null \
| awk -v skip="$SKIP" '{ t = substr($1, 2, length($1) - 2) + 0; if (NR == 1) t0 = t; if (t - t0 >= skip) print }' \
| canplayer "$IF=can_pcan"