Files
svc-core/scripts/replay-session.sh
mikkeli ba6100fd17
/ crosscheck (push) Successful in 1s
replay-session.sh: a recorded session's frames through the decoder, live to displays
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
2026-10-14 08:59:51 +09:00

42 lines
1.7 KiB
Bash
Executable File

#!/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"