Files
OmniSocketGo_streaming/robot/v4l2/OmniSocketGo_robot/scripts/dev
2026-08-09 15:56:20 +08:00
..

Dev Startup Scripts

This directory lives inside the OmniSocketGo repo and acts as the main launch entry for the whole local setup.

Default layout:

~/Documents/
  OmniSocketGo/
    scripts/dev/
  robot-command-center/

The scripts assume:

  • OmniSocketGo is the current repo
  • robot-command-center is a sibling directory next to it

If your robot-command-center is elsewhere, set ROBOT_COMMAND_CENTER_ROOT in robot-remote.env.local. start-backend.sh and start-frontend.sh need that repo; start-ros-receiver.sh and start-b-side-omnid.sh do not.

Files

  • robot-remote.env: shared defaults for backend, frontend, ROS, and b_side_omnid
  • robot-remote.env.local: optional local override file loaded after robot-remote.env
  • load-env.sh: loads the shared environment into the current shell
  • prepare-camera-device.sh: reports V4L2 owners and optionally stops one explicitly configured camera service
  • resolve-camera-device.sh: resolves an RGB capture node by USB serial plus MJPEG resolution support
  • apply-camera-controls.sh: applies the camera preset before b_side_omnid starts
  • start-backend.sh: starts Django ASGI with uvicorn
  • log-network-summary.py: polls the backend network/latest API and appends compact JSONL snapshots
  • start-frontend.sh: starts the Vite dev server
  • start-ros-receiver.sh: starts the ROS2 udp_teleop_bridge receiver
  • start-b-side-omnid.sh: applies camera controls, then starts ./bin/b_side_omnid and uses sudo -E by default
  • start-dev-tmux.sh: optional one-command tmux launcher for all four processes

Usage

Run these from the OmniSocketGo repo root:

bash scripts/dev/start-backend.sh
bash scripts/dev/start-frontend.sh
bash scripts/dev/start-ros-receiver.sh
bash scripts/dev/start-b-side-omnid.sh

If you prefer one command and use tmux:

bash scripts/dev/start-dev-tmux.sh

If you only want the shared environment for manual commands:

source scripts/dev/load-env.sh

When you launch via start-*.sh, you do not need to manually export the variables from robot-remote.env or robot-remote.env.local. load-env.sh loads those files with set -a, so the variables are exported automatically for the child process. Manual export is only needed if you bypass these scripts and start binaries directly from a clean shell.

Customizing

Edit scripts/dev/robot-remote.env for shared changes such as:

  • ROBOT_COMMAND_CENTER_ROOT
  • CONTROL_SIDE_OMNISOCKET_SERVER_ADDR
  • CONTROL_SIDE_OMNISOCKET_RELAY_VIA
  • ROBOT_SIDE_OMNISOCKET_SERVER_ADDR
  • ROBOT_SIDE_OMNISOCKET_RELAY_VIA
  • VITE_API_BASE_URL
  • OMNI_CAMERA_DEVICE
  • OMNI_CAMERA_AUTO_DISCOVER=1 resolves both camera nodes on every start instead of trusting unstable /dev/video* numbers
  • OMNI_CAMERA_HEAD_SERIAL and OMNI_CAMERA_WAIST_SERIAL permanently map the physical cameras to the head/waist roles
  • OMNI_CAMERA_HEAD_DEVICE and OMNI_CAMERA_WAIST_DEVICE are fallback nodes when automatic discovery is disabled
  • OMNI_CAMERA_DISCOVERY_WIDTH, OMNI_CAMERA_DISCOVERY_HEIGHT, and OMNI_CAMERA_DISCOVERY_TIMEOUT_SEC tune capability matching and retry time
  • OMNI_CAMERA_ACTIVE=head|waist selects the camera sent at startup

b_side_omnid keeps both configured cameras streaming and only decodes/encodes/sends the selected input. Send a text control message with body camera:head or camera:waist to peer-b-ctrl to switch without reopening either camera. After applying the selection, the robot replies to the sender with {"type":"camera.selected","camera":"head|waist"} so callers can confirm the actual state. The normal fixed-size binary robot control packets are unchanged.

  • OMNI_CAMERA_OCCUPANCY_POLICY
  • OMNI_CAMERA_RELEASE_SERVICE
  • OMNI_CAMERA_PROFILE
  • OMNI_CAMERA_BRIGHTNESS
  • OMNI_CAMERA_CUSTOM_CTRL
  • OMNI_CAMERA_VERIFY
  • OMNI_VIDEO_PEER_ID
  • OMNI_CONTROL_PEER_ID
  • OMNI_VIDEO_SOFT_BACKPRESSURE_SEGMENTS
  • OMNI_VIDEO_HARD_BACKPRESSURE_SEGMENTS
  • OMNI_VIDEO_HARD_BACKPRESSURE_HOLD_MS
  • OMNI_CONTROL_SERVER_IDLE_RECONNECT_MS
  • OMNI_VIDEO_MAX_FRAME_AGE_MS
  • OMNISOCKET_TELEMETRY_PEER_ID
  • OMNISOCKET_TELEMETRY_INTERVAL_MS
  • OMNISOCKET_TELEMETRY_STALE_AFTER_MS
  • OMNI_NETWORK_SUMMARY_LOG_ENABLED
  • OMNI_NETWORK_SUMMARY_LOG_PATH
  • OMNI_NETWORK_SUMMARY_LOG_INTERVAL_MS

Camera discovery uses udevadm and v4l2-ctl on the robot side. A candidate must have the configured serial number and advertise MJPEG at the configured capture resolution; depth, IR, Bayer, and metadata nodes are rejected. With OMNI_CAMERA_OCCUPANCY_POLICY=release-known, the start script stops the configured head/waist Orbbec services before discovery so libusb-owned interfaces can reattach to uvcvideo.

Role mapping:

  • start-backend.sh uses the CONTROL_SIDE_* address pair
  • start-b-side-omnid.sh uses the ROBOT_SIDE_* address pair
  • start-b-side-omnid.sh also applies the OMNI_CAMERA_* preset before the daemon opens the camera
  • start-b-side-omnid.sh runs the camera occupancy preflight before applying camera controls
  • start-ros-receiver.sh defaults to the robot-side address pair, but with transport=unix_dgram it usually does not need the server address

New repair knobs:

  • OMNI_VIDEO_SOFT_BACKPRESSURE_SEGMENTS, OMNI_VIDEO_HARD_BACKPRESSURE_SEGMENTS, and OMNI_VIDEO_HARD_BACKPRESSURE_HOLD_MS are used by b_side_omnid
  • OMNI_CONTROL_SERVER_IDLE_RECONNECT_MS is used by b_side_omnid
  • OMNI_VIDEO_MAX_FRAME_AGE_MS is used by start-backend.sh on the A-side backend, not by b_side_omnid
  • OMNISOCKET_TELEMETRY_INTERVAL_MS and OMNISOCKET_TELEMETRY_STALE_AFTER_MS tune the backend's D-side telemetry freshness window
  • OMNI_NETWORK_SUMMARY_LOG_* controls the A-side JSONL summary logger that polls GET /api/network/latest/

Default long-run network logging:

  • A-side starts a compact JSONL logger by default at ${OMNISOCKETGO_ROOT}/logs/a-network-summary.jsonl
  • The default A-side polling interval is 2000 ms
  • For D-side long runs, prefer:
./bin/kcpserver -listen 0.0.0.0:10909 \
  -telemetry-peer peer-a-telemetry \
  -telemetry-interval 1000ms \
  -kcp-session-stats-log logs/d-kcp-stats.jsonl \
  -kcp-session-stats-interval 1000ms
  • Keep -latency-log and -kcp-ts-debug-log off by default for multi-hour runs
  • Do not continuously redirect relay C stderr to a file unless you are reproducing a short issue window

Put machine-specific overrides into scripts/dev/robot-remote.env.local. Example:

ROBOT_COMMAND_CENTER_ROOT="$HOME/Documents/robot-command-center"
OMNI_CAMERA_DEVICE="/dev/video30"
B_SIDE_OMNID_USE_SUDO="0"
OMNI_NETWORK_SUMMARY_LOG_INTERVAL_MS="5000"

Camera occupancy handling is deliberately narrow. check only reports owners and fails if the device is busy. release-known stops exactly OMNI_CAMERA_RELEASE_SERVICE, then checks the device again. It never kills an arbitrary PID and refuses to stop proc_manager.service automatically:

OMNI_CAMERA_DEVICE="/dev/video18"
OMNI_CAMERA_OCCUPANCY_POLICY="release-known"
OMNI_CAMERA_RELEASE_SERVICE="orbbec_waist.service"

Run the preflight without starting the daemon:

bash scripts/dev/prepare-camera-device.sh

If a remaining owner belongs to proc_manager.service, inspect it with ros2 component list and unload only the camera component. Stopping the complete process manager can interrupt unrelated robot functions.

Default camera behavior is the night preset:

OMNI_CAMERA_PROFILE="night"
# Optional per-machine tweak:
OMNI_CAMERA_BRIGHTNESS="8"

To switch to a daytime preset with brightness only:

OMNI_CAMERA_PROFILE="day"
OMNI_CAMERA_BRIGHTNESS="8"

To send the raw v4l2-ctl --set-ctrl=... payload yourself:

OMNI_CAMERA_PROFILE="custom"
OMNI_CAMERA_CUSTOM_CTRL="brightness=8,auto_exposure=1,exposure_time_absolute=800,gain=64"
OMNI_CAMERA_VERIFY="1"