Local rosbag recording¶
Record a rosbag on the appliance, inspect its topics, then play it back with
pause and resume. Use robot.archive.recordBag and robot.archive.playBag.
import time
from concurrent.futures import ThreadPoolExecutor
from olo import Client
# @olo-playground: autofill-sim-topics
with Client() as client:
robot = client.robot()
bag_session = None
playback = None
try:
# Record selected ROS topics for 10 seconds.
bag_session = robot.archive.record_bag(topics=["cmd_vel"])
print(f"Recording bag {bag_session.filename} for 10s")
time.sleep(10)
bag_result = bag_session.stop()
bag_session = None
print(f"Saved {bag_result.filename} ({bag_result.total_bytes} bytes)")
# Inspect the saved bag and list its topics.
info = robot.archive.inspect_bag(bag_result.filename)
summary = info.summary
print(
f"Bag: {summary.message_count} messages, "
f"{summary.duration_seconds:.1f}s, {summary.storage_format or 'unknown'} format"
)
for topic in info.topics:
print(f" {topic.name}: {topic.message_count} messages")
# Play the bag, exercise playback controls, and wait for completion.
# system_time avoids a second /clock publisher when the sim already publishes one.
with ThreadPoolExecutor(max_workers=1) as pool:
playback = robot.archive.play_bag(bag_result.filename, clock_type="system_time")
# Subscribe before control/demo sleeps so fast bags cannot finish unseen.
playback_done = pool.submit(playback.watch)
print(f"Playing back {bag_result.filename}")
time.sleep(5)
playback.pause()
print("Paused")
time.sleep(2)
playback.resume()
print("Resumed — waiting for bag to finish")
finished = playback_done.result()
print(f"Playback {finished.type} (exit {finished.exit_code})")
playback = None
finally:
if bag_session is not None:
bag_session.stop()
if playback is not None:
playback.stop()
import { connect } from "olo/node";
// @olo-playground: autofill-sim-topics
await using client = connect();
const robot = await client.robot();
let bagSession: Awaited<ReturnType<typeof robot.archive.recordBag>> | null = null;
let playback: Awaited<ReturnType<typeof robot.archive.playBag>> | null = null;
try {
// Record selected ROS topics for 10 seconds.
bagSession = await robot.archive.recordBag({ topics: ["cmd_vel"] });
console.log(`Recording bag ${bagSession.filename} for 10s`);
await new Promise((r) => setTimeout(r, 10_000));
const bagResult = await bagSession.stop();
bagSession = null;
console.log(`Saved ${bagResult.filename} (${bagResult.totalBytes} bytes)`);
// Inspect the saved bag and list its topics.
const info = await robot.archive.inspectBag(bagResult.filename);
const { summary } = info;
console.log(
`Bag: ${summary.messageCount} messages, ${summary.durationSeconds.toFixed(1)}s, ${summary.storageFormat || "unknown"} format`,
);
for (const topic of info.topics) {
console.log(` ${topic.name}: ${topic.messageCount} messages`);
}
// Play the bag, exercise playback controls, and wait for completion.
// system_time avoids a second /clock publisher when the sim already publishes one.
playback = await robot.archive.playBag(bagResult.filename, { clockType: "system_time" });
// Subscribe before control/demo sleeps so fast bags cannot finish unseen.
const playbackDone = playback.watch();
console.log(`Playing back ${bagResult.filename}`);
await new Promise((r) => setTimeout(r, 5_000));
await playback.pause();
console.log("Paused");
await new Promise((r) => setTimeout(r, 2_000));
await playback.resume();
console.log("Resumed — waiting for bag to finish");
const finished = await playbackDone;
console.log(`Playback ${finished.type} (exit ${finished.exitCode})`);
playback = null;
} finally {
if (bagSession) await bagSession.stop();
if (playback) await playback.stop();
}