Skip to content

feat(studio): remote-control mode, run requests over ROS 2 or WebSocket - #295

Open
mbreiser wants to merge 3 commits into
mainfrom
feat/studio-remote-control
Open

mbreiser wants to merge 3 commits into
mainfrom
feat/studio-remote-control

Conversation

@mbreiser

Copy link
Copy Markdown
Contributor

Summary

Remote-control mode for Arena Studio (LAB-357). Studio stays the one executor. In remote-control mode the page is display-only, and a program asks the gateway to run a protocol. The only human action is STOP, behind an in-page confirmation.

  • Studio: "Remote control" button in the Run view and ?remote=1. A banner sits outside the frozen page. Entry needs the controller and a remote-capable bridge connected, no run active, and no unsaved edits.
  • Experiment rules: the Run button's rule moved into one function, runExperimentGate(). A remote run marked experiment must pass it after the request's metadata is applied. test runs are unrestricted.
  • Gateway (rig/nodes/bridge_node.py, remote_relay.py): relays requests to the attached Studio. One run at a time, stop is owner-only, a 60 s watchdog fails an unanswered request, and the terminal status is sent only after the run's bag is closed (it carries the bag path).
  • ROS 2: requests on /arena/run_request, statuses on /arena/run_status, both recorded in the bag. Any ROS 2 node can drive a run with a plain publish and subscribe.
  • Client (rig/nodes/studio_remote.py): StudioRemote, ROS 2 by default, WebSocket with --ws. pixi tasks remote and test-remote.
  • Flow example (rig/examples/flow_control/sbd_place_learning_flow.py): runs the SBD pre-probe, reads the bag, picks the least-occupied seam, and runs training with the safe zone there.
  • Doc: docs/development/studio-remote-control.md (message reference, bench steps, plain-rclpy example).

Known limit: nothing identifies the asker, so any ROS node can stop a ROS-started run. Acceptable on a loopback-only graph; revisit before the robot station shares the graph.

Tier

next candidate

Release notes

Studio

  • Studio can now be driven by a program. Turn on Remote control in the Run view (or open with ?remote=1) and a Python script or ROS 2 node can start and stop protocols. The page shows the run and offers one action, STOP, which asks for confirmation.
  • Remote experiment runs follow the Run experiment rules. A remote run marked as an experiment is refused unless the arena and bridge are connected, the protocol is saved, Experimenter and Fly genotype are filled, and every pattern is on the SD card.

Test plan

  • pixi run test (74 of 74 files)
  • pixi run test-remote in the default (Jazzy) and lyrical environments (0 failures)
  • pixi run test-gateway (5 of 5), pixi run studio-smoke
  • Two-stage flow end to end over ROS 2 against the simulated rig with a stand-in executor
  • Real arena on ww18: remote run over serial, real STOP, experiment-rule refusals (bench steps in the doc)
  • Windows, and MATLAB calling the client

Draft until the ww18 bench test passes.

🤖 Generated with Claude Code

mbreiser and others added 3 commits November 10, 2026 07:13
…et (LAB-357)

Arena Studio stays the one executor. In remote-control mode the page is
display-only: a program (Python, MATLAB through Python, or any ROS 2 node)
asks the gateway to run a protocol, and the only human action is STOP,
behind an in-page confirmation.

- Studio: remote banner and STOP modal, `?remote=1`, entry preconditions,
  run state machine (js/studio-remote-control.js). The Run button's rule
  moves into runExperimentGate(); a remote `experiment` run must pass it.
- Gateway (rig/nodes/bridge_node.py + remote_relay.py): relays run requests
  to the attached Studio, one owner at a time, 60 s watchdog, terminal
  status only after the bag is closed. ROS topics /arena/run_request and
  /arena/run_status, both recorded in the bag.
- Client (rig/nodes/studio_remote.py): StudioRemote, ROS 2 by default,
  WebSocket with --ws. pixi tasks `remote` and `test-remote`.
- Docs: docs/development/studio-remote-control.md.

Not tested on a real arena yet; see the bench steps in the doc.

Co-Authored-By: Claude <noreply@anthropic.com>
… (LAB-357)

Runs the pre-probe as stage 1, reads the run's bag, picks the seam the fly
occupied least, and runs training with the safe zone at that seam as
stage 2. Uses the ROS 2 remote-control client by default (--ws for
WebSocket).

Co-Authored-By: Claude <noreply@anthropic.com>
…splay stays usable (LAB-357)

From the ww18 bench test (2026-11-10):
- The lock is now selective. Everything that can change a run, the arena
  or the protocol stays inert; the bottom dock works as a display (resize,
  Log / Scope / collapse, the scope's settings and sound, the log text with
  Copy and Save), and the wheel scrolls the Run column, the sequence list
  and the Run-details panel. Default is locked: a control is live only
  when the glue's LIVE list names it. The dock's own STOP, All on / All
  off, Clear and Push log stay locked.
- The key handler leaves the browser's own keys alone (zoom, reload,
  function keys). It never cancelled a default action; whether this fixes
  Ctrl+minus on ww18 is to be retested there.
- Doc: the bag holds `accepted` and `running` statuses but not the
  terminal status (the bag is closed first); a `test` run has no run
  metadata, so runlog-check reports that.

Co-Authored-By: Claude <noreply@anthropic.com>
@mbreiser
mbreiser marked this pull request as ready for review November 12, 2026 21:05

This branch has not been deployed

No deployments
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