Information Hub WebSocket Interface

The information hub consumes only the shared MocapState contract. It never opens IMU UDP sockets or parses ESP32 packets. This keeps the motion-capture solver, Web UI, ROS 2, and Unity on the same body_rh, synchronization, and claw semantics.

Start

python3 -m pip install -r SOFTWARE/信息中枢/requirements.txt
python3 SOFTWARE/信息中枢/mocap_ws_hub.py

The default WebSocket address is ws://127.0.0.1:8765; the local status page is http://127.0.0.1:8766. Use ?ws=ws://host:port to point the page at a different hub.

Publish the JSONL demo:

python3 SOFTWARE/信息中枢/mocap_hub_bridge.py \
  --replay examples/demo_replay.jsonl

In another terminal, run the minimal subscriber:

python3 SOFTWARE/信息中枢/examples/ws_subscriber.py

Inbound Messages

Publishers first send:

{"type":"hello","role":"publisher"}

They then submit a state produced by MocapState.to_dict():

{"type":"mocap_state","state":{"schema_version":1,"frame_id":42,"frame":"body_rh","wear_side":"right","target":{}}}

Events can be sent directly:

{"type":"event","event":"calibration_completed","details":{}}

Outbound Channels

  • control: approximately 50 Hz. Contains the control target, frame_id, frame_time_ns, synchronization quality, and body frame. A slow client keeps only its newest unsent control frame, so stale teleoperation commands do not queue.

  • status: approximately 5 Hz. Carries the complete latest MocapState for node, calibration, and skeleton diagnostics.

  • event: sent immediately for calibration, recording, disconnection, and other discrete events.

Subscribers send:

{"type":"hello","role":"subscriber"}
{"type":"subscribe","channels":["control","status","event"]}

On connection and on every subscription, the hub first sends the latest control and status frames, so a client does not wait for a future frame. All outbound packets contain schema_version and hub_time_ns; mocap frames also contain frame_id, frame_time_ns, frame, and wear_side. The formal JSON Schema is at schemas/mocap_hub_frame.schema.json.

MocapState.nodes provides each node’s role, online state, packet rate, cumulative sequence gaps, out-of-order count, sample time, and synchronization quality. The cumulative loss count is a link diagnostic for the current service session; it is not an end-to-end hardware packet-loss measurement.

Runtime Boundary

In live mode, mocap_hub_bridge.py owns the MultiImuService input and publishes its states. Do not run another live receiver that binds the same UDP port at the same time. Replay mode requires no hardware.