6.6 KiB
6.6 KiB
xMonitor — Robot Status Monitor
A real-time web dashboard for monitoring a ROS 2 robot's motor, arm, waist, and power status.
Data is streamed from the robot controller over WebSocket and displayed in a browser.
Architecture
Robot Controller (ROS 2) Monitor Server (PC / Server)
┌──────────────────────────┐ ┌──────────────────────────┐
│ monitor_sender.py │ WebSocket │ main_monitor.py │
│ ─────────────────────── │─────────────▶│ (FastAPI + uvicorn) │
│ Subscribes: │ /ws/robot │ │
│ • /leg/status │ │ Broadcasts to browsers │
│ • /arm/status │ │ via /ws │
│ • /waist/status │ └────────────┬─────────────┘
│ • /power/battery/status │ │ WebSocket /ws
│ • /leg/motor_status │ ▼
│ • /arm/motor_status │ ┌──────────────────────────┐
│ • /waist/motor_status │ │ Browser (any device) │
│ │ │ http://<server-ip>:8000 │
│ Sends JSON every 1 s │ └──────────────────────────┘
└──────────────────────────┘
Requirements
Monitor Server (PC / any host)
| Package | Purpose |
|---|---|
| Python ≥ 3.9 | Runtime |
fastapi |
Web framework |
uvicorn |
ASGI server |
websockets |
(used by sender; not needed on server) |
pip install fastapi uvicorn
Robot Controller (ROS 2 node)
| Package | Purpose |
|---|---|
| Python ≥ 3.9 | Runtime |
| ROS 2 (Humble / Iron / …) | Middleware |
bodyctrl_msgs |
Custom message package |
websockets |
WebSocket client |
rclpy |
ROS 2 Python client |
pip install websockets
Monitor Server — main_monitor.py
Start
# Default: listens on all interfaces, port 8000
python main_monitor.py
# Or with uvicorn directly (supports --reload for development)
uvicorn main_monitor:app --host 0.0.0.0 --port 8000
WebSocket endpoints
| Endpoint | Direction | Description |
|---|---|---|
GET / |
HTTP | Returns the web dashboard HTML |
WS /ws |
Server → Browser | Pushes robot status to every connected browser |
WS /ws/robot |
Robot → Server | Receives JSON from monitor_sender.py |
Web GUI
Open http://<server-ip>:8000 in any browser.
The dashboard shows:
- Connection status indicator (green / red dot)
- Last update timestamp
- Power panel (two rows):
- 主电池 (Master battery): voltage (V), current (A), SOC (%)
- 副电池 (Secondary battery): voltage (V), current (A), SOC (%)
- Cards turn orange (warn) or red (alert) when voltage / SOC drops low
- Motor status table with columns:
ID | Pos (rad) | Speed | Current (A) | Temp (°C) | Motor Temp | MOS Temp | Error- Groups: 左臂 11-14, 右臂 21-24, 腰部 31-33, 左腿 51-56, 右腿 61-66
- Temperature cells turn yellow when > 100 °C, red when > 120 °C
- Rows with errors are highlighted red; error column shows
✓when OK - Browser auto-reconnects every 3 s if the WebSocket drops
Robot Sender — monitor_sender.py
Run this on the robot controller where ROS 2 is running.
Usage
python3 monitor_sender.py --ip <server-ip> [--port <port>]
| Argument | Default | Description |
|---|---|---|
--ip |
10.11.24.86 |
IP address of the monitor server |
--port |
8000 |
TCP port of the monitor server |
Examples
# Connect to server at 192.168.1.100 on default port 8000
python3 monitor_sender.py --ip 192.168.1.100
# Connect to server at 10.0.0.5 on port 9000
python3 monitor_sender.py --ip 10.0.0.5 --port 9000
Subscribed ROS 2 topics
| Topic | Message Type | Description |
|---|---|---|
/leg/status |
bodyctrl_msgs/MotorStatusMsg |
Leg motor status (pos / speed / current / temp / error) |
/arm/status |
bodyctrl_msgs/MotorStatusMsg |
Arm motor status |
/waist/status |
bodyctrl_msgs/MotorStatusMsg |
Waist motor status |
/leg/motor_status |
bodyctrl_msgs/MotorStatusMsg1 |
Leg motor & MOS temperatures |
/arm/motor_status |
bodyctrl_msgs/MotorStatusMsg1 |
Arm motor & MOS temperatures |
/waist/motor_status |
bodyctrl_msgs/MotorStatusMsg1 |
Waist motor & MOS temperatures |
/power/battery/status |
bodyctrl_msgs/PowerBatteryStatus |
Battery voltages, currents, SOC |
Behaviour
- All topics are sampled once per second (1 Hz) via a ROS 2 timer, reducing network overhead.
- Data from all topics is merged into a single JSON payload and sent over WebSocket.
- Motor temperature (
motortemperature) and MOS temperature (mostemperature) fromMotorStatusMsg1are merged into the corresponding motor entry bynameID. - If the WebSocket connection to the server drops, the sender automatically retries every 3 s and clears the internal queue to avoid stale data.
JSON payload format
{
"timestamp": "2026-04-05T10:00:00+00:00",
"statuses": [
{
"name": 51,
"pos": -0.2508,
"speed": -0.0051,
"current": -0.0488,
"temperature": 30.0,
"motor_temp": 28.5,
"mos_temp": 31.2,
"error": 0
}
],
"power": {
"voltage": 52.30,
"current": -2.60,
"power": 100.0,
"little_voltage": 53.10,
"little_current": -0.10,
"little_power": 94.0
}
}
Quick-start (end-to-end)
-
On the monitor server (PC on the same LAN):
pip install fastapi uvicorn python main_monitor.py -
On the robot controller (source your ROS 2 workspace first):
source /home/ubuntu/ros2ws/install/setup.bash python3 monitor_sender.py --ip <your-server-ip> -
Open browser: navigate to
http://<your-server-ip>:8000
File Overview
| File | Description |
|---|---|
main_monitor.py |
FastAPI server — hosts the web GUI and relays data to browsers |
monitor_sender.py |
ROS 2 node — collects robot data and streams it to the server |
README.md |
This file |