Skip to content

feat(teleop): multi-episode recording without restarting the simulator - #182

Open
2047767028-lang wants to merge 1 commit into
AgibotTech:mainfrom
2047767028-lang:feat/multi-episode-recording
Open

feat(teleop): multi-episode recording without restarting the simulator#182
2047767028-lang wants to merge 1 commit into
AgibotTech:mainfrom
2047767028-lang:feat/multi-episode-recording

Conversation

@2047767028-lang

Copy link
Copy Markdown
Contributor

Motivation

autoteleop.sh currently supports exactly one episode per launch:
pressing y/N kills every teleop process (simulator included) and the
script exits. Collecting N episodes means restarting all four terminals
N times, paying the full Isaac Sim startup cost per episode.

This implements the multi-episode half of #181.

How it works

A new /sim/stop_episode topic carries an end-of-episode signal:

  • autoteleop.sh: y/n now end only the current episode
    (keep / mark-discarded), print a completeness check of the produced
    files (.mcap, metadata.yaml, recording_info.json), and keep
    waiting — the next record-button press starts the next episode.
    A new q key stops everything (the previous y/N behaviour).
  • api_core.py (_on_recording): on the stop signal, the current ros2
    bag is finalized gracefully via SIGINT (so metadata.yaml is
    written), recording_info.json is written if the episode ended
    before frame 100, and the one-shot wait_recording latch is re-armed
    for the next record-button press.
  • server_node.py / ros_nodes.py / teleop.py: subscribe to the
    stop signal and reset the cached recording state on both the
    simulator and teleop sides, so the next episode always requires a
    fresh record-button press and never auto-starts from stale signals.

Testing status

Being transparent here: the logic was developed and validated
end-to-end on the pre-3.2.0 layout (a v3.0-era container) — we used it
to collect multi-episode teleop datasets in one sitting, which later
trained successfully. This PR ports it 1:1 to the current package
layout (insertion points verified against current main; bash -n and
py_compile pass), but our local environment cannot run the 3.2.0
stack, so it has NOT been run end-to-end on 3.2.0 itself. Happy to
adjust anything that doesn't match the new runtime.

🤖 Generated with Claude Code

Previously autoteleop.sh supported exactly one episode per launch: a single
y/N press killed every teleop process (simulator included) and the script
exited, so collecting N episodes meant restarting all four terminals N
times (~2 min of Isaac Sim startup per episode).

This adds an end-of-episode signal on a new /sim/stop_episode topic:

- autoteleop.sh: y/n now only ends the *current* episode (keep/discard),
  shows a completeness check of the produced files (.mcap /
  metadata.yaml / recording_info.json), and waits for the next episode;
  a new q key stops everything as before.
- api_core.py (_on_recording): on the stop signal, finalize the current
  ros2 bag gracefully via SIGINT (metadata.yaml intact), write
  recording_info.json if the episode ended before frame 100, and re-arm
  the one-shot wait_recording latch for the next record-button press.
- server_node.py / ros_nodes.py / teleop.py: subscribe to the stop
  signal and reset the cached recording state on both the simulator and
  teleop sides, so the next episode requires a fresh button press and
  never auto-starts from stale signals.

Ported from a validated implementation on the pre-3.2.0 layout (used to
collect multi-episode datasets that trained successfully); adapted to the
3.2.0 package layout but not yet run end-to-end on 3.2.0 itself.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant