Files
Vision/docs/与前端对接文档.md
T
dev01 d506e01188 feat: initial ROS2 vision pipeline with gimbal control and nginx config
- camera_node (driver_pkg): Hikrobot MvCamera SDK image capture
- vision_node (algorithm_pkg): Otsu threshold + contour detection + target tracking
- web_node (application_pkg): HTTP server with MJPEG preview and mode switch API
- gimbal_node (gimbal_control_pkg): UART serial communication per gimbal protocol
- bringup_pkg: launch file for full pipeline
- config: nginx reverse-proxy for MJPEG streaming and API routing
2026-05-31 22:10:12 +08:00

251 lines
7.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 与前端对接文档
## 整体架构
```
┌──────────────────────────────────────────────────────────┐
│ 浏览器 (Vue3 前端) │
│ - 自动模式:观看 MJPEG 视频流 │
│ - 手动模式:键盘遥控 + MJPEG 视频流 │
│ - 调试模式:PID 调参 │
└──────┬──────────────┬──────────────┬─────────────────────┘
│ HTTP │ WebSocket │ HTTP (MJPEG)
▼ ▼ ▼
┌──────────────┐ ┌──────────┐ ┌───────────────────┐
│ Nginx │ │rosbridge │ │ web_video_server │
│ 静态文件 │ │ :9090 │ │ :8081 │
│ 反向代理 │ └────┬─────┘ └────────┬──────────┘
└──────┬───────┘ │ │
│ ▼ ▼
│ ┌────────────────────────────────┐
└─────►│ ROS2 节点 │
│ - /cmd_wheel (轮速控制) │
│ - /cmd_gimbal (云台控制) │
│ - /pid_config (PID参数) │
│ - /api/mode/switch (模式切换) │
└────────────────────────────────┘
```
## 一、Nginx 配置
Nginx 负责三件事:托管 Vue 前端静态文件、反代 MJPEG 视频流、反代 HTTP API。
### 1.1 前端部署
构建产物在 `dist/` 目录,部署到服务器后由 Nginx 直接托管:
```bash
# 本地构建
cd aimbot-web
pnpm build
# 上传到服务器
scp -r dist/* user@server:/var/www/aimbot/
```
### 1.2 Nginx 配置示例
```nginx
server {
listen 80;
server_name your-domain.com;
# 前端静态文件
root /var/www/aimbot;
index index.html;
# SPA 路由回退 — 所有非文件请求回 index.html
location / {
try_files $uri $uri/ /index.html;
}
# MJPEG 视频流反代 (web_video_server)
location /stream {
proxy_pass http://127.0.0.1:8081/stream;
proxy_http_version 1.1;
proxy_buffering off;
# MJPEG multipart 边界必须保持完整
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# 长连接支持
proxy_set_header Connection "";
chunked_transfer_encoding off;
# 超时配置 — 视频流需要长连接
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
# 模式切换 API (HTTP → ROS2 节点)
location /api/ {
proxy_pass http://127.0.0.1:8080/api/;
proxy_set_header Host $host;
proxy_set_header Content-Type application/json;
}
}
```
### 1.3 关键说明
| 配置项 | 说明 |
|--------|------|
| `proxy_buffering off` | MJPEG 流必须关闭缓冲,否则画面延迟严重 |
| `chunked_transfer_encoding off` | multipart 边界依赖原始编码 |
| `proxy_read_timeout 86400s` | 视频流是长连接,超时必须足够大 |
| `try_files $uri /index.html` | Vue Hash 路由支持,直接访问 /#/manual 等路径 |
---
## 二、ROS2 环境配置
### 2.1 rosbridge (WebSocket 服务)
前端通过 roslibjs 直连 rosbridge WebSocket,不走 Nginx 反代。
```bash
# 安装
sudo apt install ros-${ROS_DISTRO}-rosbridge-server
# 启动 (默认 ws://0.0.0.0:9090)
ros2 run rosbridge_server rosbridge_websocket
```
### 2.2 web_video_server (MJPEG 推流)
```bash
# 安装
sudo apt install ros-${ROS_DISTRO}-web-video-server
# 启动 (默认 http://0.0.0.0:8081)
# 发布摄像头话题后自动生成 /stream?topic=<topic_name>
ros2 run web_video_server web_video_server
```
### 2.3 话题一览
rosbridge 发布/订阅的话题需要与前端 `config.js` 一致:
| 话题 | 消息类型 | 方向 | 用途 |
|------|----------|------|------|
| `/cmd_wheel` | `std_msgs/Float32MultiArray` | 前端→ROS2 | 左右轮速 `[left, right]` |
| `/cmd_gimbal` | `geometry_msgs/Twist` | 前端→ROS2 | 云台角速度 `angular.y`(pitch) `angular.z`(yaw) |
| `/pid_config` | `std_msgs/String` | 前端→ROS2 | PID 参数 JSON |
### 2.4 模式切换 API
前端 HTTP POST → Nginx 反代 → ROS2 节点(用户自行实现 HTTP 端):
```
POST /api/mode/switch
Content-Type: application/json
{ "mode": "auto" | "manual" | "debug" }
```
此接口需由 ROS2 侧 HTTP 服务(如 FastAPI / Flask / ros2-web-bridge)接收并处理模式切换逻辑。
---
## 三、MJPEG 视频流地址
`web_video_server` 的 URL 规则:`http://<host>:8081/stream?topic=<话题名>`
前端 `config.js` 中配置对应 URL:
```js
// src/config.js
export const MJPEG_AUTO_URL = '/stream?topic=/camera_auto'
export const MJPEG_MANUAL_URL = '/stream?topic=/camera_manual'
```
使用 `/stream` 相对路径时由 Nginx 反代到 `web_video_server`,避免跨域问题。
### 摄像头话题发布示例
```bash
# 确保摄像头话题有数据
ros2 run image_transport republish raw in:=/camera_auto/image_raw out:=/camera_auto/compressed
```
`web_video_server` 自动识别话题类型并推送 MJPEG。
---
## 四、启动顺序
```bash
# 1. 启动 ROS2 核心节点
ros2 launch your_robot bringup.launch.py
# 2. 启动 rosbridge
ros2 run rosbridge_server rosbridge_websocket &
# 3. 启动视频推流
ros2 run web_video_server web_video_server &
# 4. 启动模式切换 HTTP 服务(自行实现)
python3 mode_api_server.py &
# 5. 启动/重载 Nginx
sudo systemctl reload nginx
```
---
## 五、前端 config.js 配置
部署前修改 `src/config.js` 中的地址以匹配实际服务器环境:
```js
// 后端 HTTP API(模式切换)
export const HTTP_API_BASE = '' // 同域代理可留空或填 '/api'
// rosbridge WebSocket
export const ROSBRIDGE_URL = 'ws://192.168.1.100:9090' // 改成 ROS2 主机 IP
// MJPEG 视频流 — 经 Nginx 代理
export const MJPEG_AUTO_URL = '/stream?topic=/camera_auto'
export const MJPEG_MANUAL_URL = '/stream?topic=/camera_manual'
// ROS 话题 — 必须与 ROS2 侧一致
export const CMD_WHEEL_TOPIC = '/cmd_wheel'
export const CMD_GIMBAL_TOPIC = '/cmd_gimbal'
export const PID_CONFIG_TOPIC = '/pid_config'
// 键盘控制参数 — 按实际机器人调整
export const MAX_LINEAR = 0.5 // 最大线速度 m/s
export const MAX_ANGULAR = 1.0 // 最大角速度 rad/s
export const WHEEL_SEPARATION = 0.2 // 轮距 m
export const GIMBAL_PITCH_SPEED = 0.5 // 云台 pitch 角速度 rad/s
export const GIMBAL_YAW_SPEED = 0.5 // 云台 yaw 角速度 rad/s
```
---
## 六、前端 nginx 完整部署命令
```bash
# 构建
cd aimbot-web && pnpm build
# 部署
sudo cp -r dist/* /var/www/aimbot/
sudo cp nginx-aimbot.conf /etc/nginx/sites-available/aimbot
sudo ln -s /etc/nginx/sites-available/aimbot /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
```
---
## 七、故障排查
| 现象 | 检查项 |
|------|--------|
| MJPEG 不出画面 | `web_video_server` 是否运行,话题是否有数据,Nginx `proxy_buffering` 是否设为 `off` |
| rosbridge 连不上 | 防火墙是否开放 9090,`ROSBRIDGE_URL` 是否用 `ws://` 协议 |
| 按键无反应 | rosbridge 连接状态是否为"已连接",话题名是否与 ROS2 侧一致 |
| 模式切换报错 | `/api/mode/switch` 的 HTTP 服务是否实现并运行 |
| 页面空白 | Nginx `try_files` 是否配了 `$uri /index.html` |