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

7.8 KiB
Raw Blame History

与前端对接文档

整体架构

┌──────────────────────────────────────────────────────────┐
│  浏览器 (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 直接托管:

# 本地构建
cd aimbot-web
pnpm build

# 上传到服务器
scp -r dist/* user@server:/var/www/aimbot/

1.2 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 反代。

# 安装
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 推流)

# 安装
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:

// 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,避免跨域问题。

摄像头话题发布示例

# 确保摄像头话题有数据
ros2 run image_transport republish raw in:=/camera_auto/image_raw out:=/camera_auto/compressed

web_video_server 自动识别话题类型并推送 MJPEG。


四、启动顺序

# 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 中的地址以匹配实际服务器环境:

// 后端 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 完整部署命令

# 构建
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