Car Simulator API

REST API & WebSocket 接口文档 | 多用户隔离架构

架构说明 REST API WebSocket Data Types 坐标 & 比例
多用户隔离架构

每个模拟器页面生成唯一的 clientId(格式 car-xxxxxxxxx), 通过 WebSocket 的 Socket.IO Room 机制实现隔离。指令和状态只在同一个 Room 内广播,不同 clientId 的小车互不干扰。

┌─────────────────────────────────┐
│ 浏览器 A                        │
│ clientId: car-abc123            │
│ Room "car-abc123" ─── 小车 A    │
└─────────────────────────────────┘

┌─────────────────────────────────┐
│ 浏览器 B                        │
│ clientId: car-xyz789            │
│ Room "car-xyz789" ─── 小车 B    │
└─────────────────────────────────┘

REST API / WebSocket 通过 clientId 指定目标:
  ?clientId=car-abc123  →  只操控小车 A
  ?clientId=car-xyz789  →  只操控小车 B
  不填 clientId         →  指令不会到达任何小车
REST API
GET /api/control
发送控制指令(推荐用于外部调用,匹配真实小车接口格式)
Query Parameters
NameTypeRequiredDescription
clientIdstringrequired 目标小车 ID(从模拟器页面复制),不填则指令不会到达任何小车
actionstringrequired 动作类型:up / down / left / right / stop / grab / release
speednumberoptional 速度 (0.01 ~ 0.5)
distancenumberoptional 移动距离(厘米),适用于 up/down。参考:小车长 20cm,distance=20 约一个车身位
anglenumberoptional 转动角度(度),适用于 left/right
timenumberoptional 持续时间(毫秒)
Examples
# 控制 car-abc123 前进 20cm(约一个车身位)
GET /api/control?clientId=car-abc123&action=up&speed=0.1&distance=20

# 控制 car-abc123 左转 90 度
GET /api/control?clientId=car-abc123&action=left&speed=0.05&angle=90

# 停止
GET /api/control?clientId=car-abc123&action=stop

# 抓起物品
GET /api/control?clientId=car-abc123&action=grab
Response
{
  "success": true,
  "target": "car-abc123",
  "command": {
    "action": "up",
    "speed": 0.1,
    "distance": 20
  }
}
GET /api/car/state?clientId=car-xxxxx
获取指定小车的当前状态
Query Parameters
NameTypeRequiredDescription
clientIdstringoptional目标小车 ID,默认 "default"
Response
{
  "x": 0.5,
  "z": -1.2,
  "rotation": 3.14,
  "velocity": 0.1,
  "angularVelocity": 0,
  "armState": "idle",
  "hasBall": false,
  "isColliding": false,
  "grabAvailable": true,
  "ballPosition": { "x": 0, "z": -5 }
}
POST /api/car/control
发送控制指令(JSON Body),通过 clientId 指定目标小车
Request Body
{
  "clientId": "car-abc123",
  "action": "up",
  "speed": 0.1,
  "distance": 20,
  "angle": 90
}
POST /api/car/reset?clientId=car-xxxxx
重置指定小车的仿真状态(位置、速度、机械臂、球和桶的位置)
Query Parameters
NameTypeRequiredDescription
clientIdstringoptional目标小车 ID,默认 "default"
GET /api/car/speed
获取当前速度设置
Response
{
  "speed": 0.1,
  "turnSpeed": 0.05
}
POST /api/car/speed
更新速度设置
Request Body
{
  "speed": 0.15,
  "turnSpeed": 0.08
}
WebSocket

Namespace: /car  |  Transport: WebSocket / Polling

注意:所有消息基于 Room 隔离。必须先发送 join(带 clientId)加入 Room,否则 command/state 不会到达目标。

CLIENT emit: join
客户端加入房间。模拟器页面自动生成 clientId,外部控制器需提供目标 clientId。
// 模拟器(自动)
socket.emit('join', { role: 'simulator', clientId: 'car-abc123' })

// 外部控制器(指定要控制的小车)
socket.emit('join', { role: 'controller', clientId: 'car-abc123' })
CLIENT emit: command
发送控制指令(仅在当前 Room 内广播,只影响同一 clientId 的小车)
socket.emit('command', {
  action: 'up',
  speed: 0.1,
  distance: 20,
  angle: 90
})
SERVER broadcast: command
服务端将指令广播到同一 Room 内的所有客户端(包括控制器自身)
socket.on('command', (data) => {
  // data: { action, value?, speed?, distance?, angle?, time? }
  // 只有同一 clientId 的客户端能收到
})
CLIENT emit: state
模拟器上报机器人状态(10Hz),广播给同一 Room 内的其他客户端
socket.emit('state', {
  x: 0.5,
  z: -1.2,
  rotation: 3.14,
  velocity: 0.1,
  angularVelocity: 0,
  armState: 'idle',
  hasBall: false,
  isColliding: false,
  grabAvailable: true,
  ballPosition: { x: 0, z: -5 }
})
SERVER broadcast: state
服务端将状态广播给同一 Room 内的其他客户端(排除发送者自身)
socket.on('state', (state) => {
  // state: RobotState object
  // 只收到同一 clientId 的小车状态
})
Data Types
ControlCommand
{
  action: 'up' | 'down' | 'left' | 'right' | 'stop' | 'grab' | 'release' | 'setSpeed' | 'setTurnSpeed' | 'turnAngle',
  value?: number,
  distance?: number,  // 厘米
  angle?: number,     // 度
  speed?: number,
  time?: number       // 毫秒
}
RobotState
{
  x: number,
  z: number,
  rotation: number,
  velocity: number,
  angularVelocity: number,
  armState: 'idle' | 'picking_down' | 'picking_up' | 'holding' | 'dropping_down' | 'dropping_up',
  hasBall: boolean,
  isColliding: boolean,
  grabAvailable: boolean,
  ballPosition: { x: number, z: number } | null
}
SpeedSettings
{
  speed: number,
  turnSpeed: number
}
坐标 & 比例换算
实物仿真单位换算
小车长度 20cm1.8 单位1cm = 0.09 单位
1 米9 单位1 单位 ≈ 11.1cm
地面尺寸160×160 单位≈ 17.8m × 17.8m
网格间距9 单位= 1m(16×16 格)

distance 参数单位为厘米。例如 distance=20 表示前进 20cm,即 20 × 0.09 = 1.8 单位 ≈ 一个车身位。