202 lines
6.6 KiB
Markdown
202 lines
6.6 KiB
Markdown
# 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) |
|
|
|
|
```bash
|
|
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 |
|
|
|
|
```bash
|
|
pip install websockets
|
|
```
|
|
|
|
---
|
|
|
|
## Monitor Server — `main_monitor.py`
|
|
|
|
### Start
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
# 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`) from `MotorStatusMsg1` are merged into the corresponding motor entry by `name` ID.
|
|
- 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
|
|
|
|
```json
|
|
{
|
|
"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)
|
|
|
|
1. **On the monitor server** (PC on the same LAN):
|
|
```bash
|
|
pip install fastapi uvicorn
|
|
python main_monitor.py
|
|
```
|
|
|
|
2. **On the robot controller** (source your ROS 2 workspace first):
|
|
```bash
|
|
source /home/ubuntu/ros2ws/install/setup.bash
|
|
python3 monitor_sender.py --ip <your-server-ip>
|
|
```
|
|
|
|
3. **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 |
|
|
|