Skip to content

Instantly share code, notes, and snippets.

@kingsimba
Created February 25, 2026 10:01
Show Gist options
  • Select an option

  • Save kingsimba/61221913f8e4c8fe440b84afc1e77382 to your computer and use it in GitHub Desktop.

Select an option

Save kingsimba/61221913f8e4c8fe440b84afc1e77382 to your computer and use it in GitHub Desktop.
robot_simulation

这是一个完整的高性能分布式多机器人仿真平台技术方案。该方案结合了C++ 高保真物理/传感器仿真WebSocket 实时通信以及Docker 容器化分布式控制,专为单服务器运行数十至上百个机器人的场景设计。


🤖 高性能分布式多机器人仿真平台技术方案

1. 方案概述

本方案旨在构建一个轻量级、高并发、高保真的机器人仿真系统。

  • 核心目标:在单台服务器上支持 50+ 个机器人同时运行,每个机器人拥有独立的控制栈(ROS/ROS2),进行真实的运动控制算法验证。
  • 架构特点
    • 仿真端:C++ 原生开发,无重型物理引擎开销,专注于运动学与射线检测。
    • 通信层:WebSocket + Protobuf (Binary),低延迟、低带宽。
    • 控制端:Docker 容器化部署,实现环境隔离与大规模并行。

2. 系统架构拓扑

graph TD
    subgraph "Host Server (仿真服务器)"
        SimCore["🚀 C++ 仿真核心 (Single Process)"]
        Embree["📐 Intel Embree (3D Ray Casting)"]
        WS_Server["🌐 WebSocket Server (uWebSockets)"]
        
        SimCore -->|加载地图 | GLB_Map["🗺️ 3D Map (.glb)"]
        SimCore -->|构建 BVH | Embree
        SimCore -->|管理连接 | WS_Server
    end

    subgraph "Network (LAN / Docker Bridge)"
        TCP_Stream["🔌 TCP Streams (Binary Frames)"]
    end

    subgraph "Control Cluster (Docker Containers)"
        direction TB
        Container1["🐳 Docker: Robot_1"]
        Container2["🐳 Docker: Robot_2"]
        ContainerN["🐳 Docker: Robot_N (Scale to 50+)"]
        
        subgraph "Inside Container"
            ROS_Master["⚡ ROS Master (Local)"]
            Ctrl_Node["🧠 Control Node (SLAM/Nav)"]
            WS_Client["📡 WebSocket Client"]
            
            Ctrl_Node <-->|Topics| ROS_Master
            WS_Client <-->|Twist/Sensor| Ctrl_Node
        end
        
        Container1 --> WS_Client
        Container2 --> WS_Client
        ContainerN --> WS_Client
    end

    WS_Server <==>|Binary Protobuf| TCP_Stream
    TCP_Stream <==>|Binary Protobuf| WS_Client
Loading

3. 核心模块详细设计

3.1 仿真服务端 (C++)

技术栈: C++17, CMake, uWebSockets, Intel Embree, tinygltf, Protobuf.

A. 场景加载与加速结构

  • 地图格式: .glb (glTF Binary)。利用 tinygltf 解析顶点和索引。
  • 加速结构: 使用 Intel Embree 构建 BVH (Bounding Volume Hierarchy)。
    • 零拷贝: 直接引用 tinygltf 解析后的内存指针,无需数据复制。
    • 性能: 支持百万级三角形场景的实时射线检测。

B. 机器人状态管理

  • 数据结构: std::unordered_map<int, RobotState>
  • 运动学模型: 差分驱动 (Diff Drive) 或 全向轮。
    • 公式: $x_{new} = x + v \cdot \cos(\theta) \cdot dt$, $\theta_{new} = \theta + \omega \cdot dt$
  • 碰撞检测:
    • 简单模式:检查新位置是否在栅格地图占用区。
    • 精确模式:利用 Embree 检测机器人包围盒与场景 Mesh 的干涉。

C. 传感器仿真 (核心性能点)

  • 激光雷达 (LiDAR):
    • 频率: 10Hz - 20Hz。
    • 算法: 从机器人 Pose 发射射线束 (Ray Packet),调用 rtcIntersectV (SIMD 加速) 计算交点距离。
    • 输出: ranges (float array) 或 pointcloud (xyz array)。
  • IMU:
    • 频率: 100Hz。
    • 算法: 基于当前速度 + 高斯噪声 (std::normal_distribution) 生成加速度和角速度。
  • Odometry:
    • 频率: 20Hz - 50Hz。
    • 内容: 当前 Pose (x, y, theta) 和 Twist。

D. 网络通信层

  • 协议: WebSocket (Binary Mode)。
  • 序列化: Google Protobuf。
  • 消息类型:
    • SensorPacket: 包含 Lidar, IMU, Odom, CollisionFlag。
    • TwistCommand: 线性速度 $v$, 角速度 $\omega$
  • 背压处理 (Backpressure):
    • 发送前检查 ws->getBufferedAmount()
    • 若缓冲区满,丢弃当前生成的非关键帧(如 IMU/Lidar),保证实时性,避免阻塞仿真循环。

3.2 控制客户端 (Docker)

技术栈: Ubuntu + ROS (Noetic/Humble) + Python/C++ Node + WebSocket Client.

A. 容器化设计

  • 镜像: 单一镜像 my-robot-control:v1,包含所有依赖和算法代码。
  • 隔离性:
    • 每个容器运行独立的 roscore (ROS 1) 或 ROS 2 Daemon。
    • 环境变量 ROS_MASTER_URI=http://localhost:11311 确保内部通信隔离。
    • 环境变量 ROS_DOMAIN_ID (ROS 2) 动态设置,防止 DDS 串台。

B. 节点逻辑

  1. WS Client Node:
    • 启动时连接仿真器 ws://host.docker.internal:9001
    • 订阅本地 ROS Topic /cmd_vel,序列化为 Protobuf 发送给仿真器。
    • 接收仿真器二进制包,反序列化后发布到 /scan, /imu/data, /odom
  2. 算法 Node:
    • 标准的 SLAM (Gmapping/Cartographer)、导航 (MoveBase/Nav2) 或自定义集群算法。
    • 完全无需修改,如同在真实机器人上运行。

3.3 通信协议定义 (Protobuf)

syntax = "proto3";

package sim_proto;

message ImuData {
  double timestamp = 1;
  float linear_x = 2; float linear_y = 3; float linear_z = 4;
  float angular_x = 5; float angular_y = 6; float angular_z = 7;
}

message OdometryData {
  double timestamp = 1;
  double x = 2; double y = 3; double theta = 4;
  float v_linear = 5; float v_angular = 6;
}

message LidarData {
  double timestamp = 1;
  repeated float ranges = 2; // 2D: distances; 3D: flattened xyz or distances
}

message SensorPacket {
  int32 robot_id = 1;
  double sim_timestamp = 2;
  OdometryData odom = 3;
  ImuData imu = 4;
  LidarData lidar = 5;
  bool collision = 6;
}

message TwistCommand {
  int32 robot_id = 1;
  float linear = 2;
  float angular = 3;
}

4. 部署与运维流程

4.1 环境准备

  1. 安装依赖:
    sudo apt install libembree-dev libprotobuf-dev protobuf-compiler cmake build-essential
  2. 构建仿真器:
    mkdir build && cd build
    cmake .. && make -j$(nproc)

4.2 构建控制端镜像

# Dockerfile
FROM ros:humble
WORKDIR /app
COPY . .
RUN apt-get update && apt-get install -y libprotobuf-dev protobuf-compiler
RUN pip3 install protobuf websocket-client
# 编译 ROS 节点...
CMD ["ros2", "launch", "my_robot", "control.launch.py"]
docker build -t my-robot-control:v1 .

4.3 一键启动集群 (docker-compose)

创建 docker-compose.yml:

version: '3.8'
services:
  robot:
    image: my-robot-control:v1
    deploy:
      replicas: 50  # 启动 50 个机器人
    environment:
      - ROS_DOMAIN_ID=${SERVICE_NUMBER} # 自动分配 1-50
      - SIM_HOST=host.docker.internal
    network_mode: "bridge"
    extra_hosts:
      - "host.docker.internal:host-gateway" # 让容器能访问宿主机仿真器
    cpus: 0.5       # 限制 CPU
    memory: 512M    # 限制内存

启动命令:

# 启动仿真器 (后台)
./sim_server --map world.glb --port 9001 &

# 启动 50 个机器人控制容器
docker-compose up -d --scale robot=50

5. 性能优化与关键技术点

关键点 解决方案 预期效果
射线检测性能 使用 Intel Embree + Packet Tracing (SIMD) 单核可支撑 100+ 机器人 @ 10Hz 360 线雷达
网络吞吐量 Protobuf Binary + WebSocket Binary Frame (无 Base64/JSON) 带宽占用降低 60%,延迟 < 1ms (LAN)
实时性保障 应用层背压控制 (Buffer Full 时丢包) + 客户端时间戳过滤 消除 TCP 队头阻塞影响,模拟 UDP 实时性
资源隔离 Docker CPU/Memory Limits 防止单节点异常拖垮整机
扩展性 Stateless Simulation (仿真器无状态,仅依赖内存) 增加机器人只需增加 Docker 副本,无需改代码

6. 开发路线图

  1. Phase 1: 原型验证 (1 周)

    • 实现 C++ 最小仿真循环 (方块移动)。
    • 集成 tinygltf 加载简单地图。
    • 实现 WebSocket 二进制收发 Protobuf。
    • 手动启动 2 个 Python 脚本模拟客户端。
  2. Phase 2: 传感器与加速 (1-2 周)

    • 集成 Intel Embree,实现 3D 激光雷达射线检测。
    • 添加 IMU 噪声模型和运动学解算。
    • 压力测试:单进程跑 20 个虚拟客户端。
  3. Phase 3: 容器化与自动化 (1 周)

    • 编写 Dockerfile 和 docker-compose 配置。
    • 实现 ROS 节点与 WebSocket 的桥接。
    • 测试 50+ 容器并发启动与通信稳定性。
  4. Phase 4: 高级功能 (可选)

    • 支持动态障碍物。
    • 可视化调试界面 (Web 前端连接仿真器查看全局态势)。
    • 录制回放功能 (Bag 包记录)。

7. 总结

本方案摒弃了沉重的通用物理引擎和复杂的 WebRTC 协议,选择了**“专款专用”**的技术路线:

  • Embree 解决射线检测性能瓶颈。
  • WebSocket + Protobuf 解决通信效率与开发成本的平衡。
  • Docker 解决大规模并发控制的环境隔离问题。

这是一套低成本、高性能、易维护无限接近真实部署的现代化机器人仿真平台架构。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment