371 lines
15 KiB
Markdown
371 lines
15 KiB
Markdown
# 云端高层飞控意图 JSON 规范 v1(完整版)
|
||
|
||
> **定位**:定义 WebSocket `dialog_result.flight_intent` 中的**语义对象**与**伴飞侧执行约定**,不是 MAVLink 二进制帧。
|
||
> **目标**:
|
||
>
|
||
> 1. **协议**:客户端与云端可 **100% 按字段表 strict 解析**;**禁止**用自然语言或 `summary` 驱动机控。
|
||
> 2. **桥(companion)**:按本文执行 **有序 `actions`**、校验、排队与安全门,再译为 PX4 可接受的模式 / 指令 / Offboard setpoint。
|
||
> 3. **ROS**:为 MAVROS(或等价 ROS 2 封装)提供**参考映射表**;具体 topic/service 名称以装机软件栈为准。
|
||
|
||
**协议(bundle)**:`proto_version: "1.0"`,`transport_profile: "text_uplink"`(与现有会话协议一致)。
|
||
|
||
---
|
||
|
||
## 1. 顶层对象 `flight_intent`
|
||
|
||
当 `routing === "flight_intent"` 时,`flight_intent` **必须非 null**,且为下表 JSON 对象(键顺序任意)。
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| `is_flight_intent` | `boolean` | 是 | **必须为 `true`** |
|
||
| `version` | `integer` | 是 | **Schema 版本,本文档固定为 `1`** |
|
||
| `actions` | `array` | 是 | **有序**动作列表,按**时间先后**执行(见 §5、§10) |
|
||
| `summary` | `string` | 是 | 一句人类可读中文摘要(播报/日志);**不参与机控解析** |
|
||
| `trace_id` | `string` | 否 | **端到端追踪 ID**(建议 UUID 或雪花 ID);用于桥、ROS 节点与日志关联;长度建议 ≤ 128 |
|
||
|
||
**禁止字段**:除上表外,顶层不得出现其它键(便于 `strict` 解析)。扩展须 **递增 `version`**(见 §8)。
|
||
|
||
**字符编码**:UTF-8。
|
||
|
||
---
|
||
|
||
## 2. `actions[]` 通用形式
|
||
|
||
每个元素:
|
||
|
||
```json
|
||
{ "type": "<ActionType>", "args": { ... } }
|
||
```
|
||
|
||
| 字段 | 类型 | 必填 |
|
||
|------|------|------|
|
||
| `type` | `string` | 是,取值限于 §3 枚举 |
|
||
| `args` | `object` | 是,允许为空对象 `{}`;**仅允许**各小节表中列出的键 |
|
||
|
||
---
|
||
|
||
## 3. `ActionType` 与白名单 `args`
|
||
|
||
以下 **`type` 仅允许小写**。未列出的值在 v1 **非法**。
|
||
|
||
### 3.1 `takeoff`
|
||
|
||
| args 键 | 类型 | 必填 | 说明 |
|
||
|---------|------|------|------|
|
||
| `relative_altitude_m` | `number` | 否 | 相对起飞点(或飞控定义的 TAKEOFF 参考)的**目标高度**,单位 **米**,须 **> 0**。省略则 **完全由机端/飞控缺省参数** 决定(与旧版「空 args」语义一致) |
|
||
|
||
```json
|
||
{ "type": "takeoff", "args": {} }
|
||
```
|
||
|
||
```json
|
||
{ "type": "takeoff", "args": { "relative_altitude_m": 5 } }
|
||
```
|
||
|
||
**桥 / ROS 映射提示**:PX4 `TAKEOFF` 模式、`MAV_CMD_NAV_TAKEOFF`;相对高度常与 `MIS_TAKEOFF_ALT` 或命令参数结合,**以装机参数为准**。
|
||
|
||
---
|
||
|
||
### 3.2 `land`
|
||
|
||
| args 键 | 类型 | 必填 | 说明 |
|
||
|---------|------|------|------|
|
||
| — | — | — | v1 无参;降落行为由飞控 `AUTO.LAND` 等策略决定 |
|
||
|
||
```json
|
||
{ "type": "land", "args": {} }
|
||
```
|
||
|
||
**桥 / ROS 映射提示**:`AUTO.LAND`、`MAV_CMD_NAV_LAND`;固定翼 / 多旋翼路径不同,由机端处理。
|
||
|
||
---
|
||
|
||
### 3.3 `return_home`
|
||
|
||
```json
|
||
{ "type": "return_home", "args": {} }
|
||
```
|
||
|
||
语义:**返航至 Home 并按飞控策略降落或盘旋**(与 PX4 **RTL** 概义一致)。
|
||
|
||
---
|
||
|
||
### 3.4 `hover` 与 `hold`
|
||
|
||
二者在 v1 **语义等价**:**在当前位置附近保持**(多旋翼常见为位置保持;固定翼可能映射为 Loiter,由机端按机型解释)。
|
||
|
||
| args 键 | 类型 | 必填 | 说明 |
|
||
|---------|------|------|------|
|
||
| — | — | — | 仅 `{}` 合法;表示进入保持,**不隐含**持续时间(时长用 §3.6 `wait`) |
|
||
|
||
```json
|
||
{ "type": "hover", "args": {} }
|
||
```
|
||
|
||
```json
|
||
{ "type": "hold", "args": {} }
|
||
```
|
||
|
||
**约定**:同一 `actions` 序列建议只选 `hover` 或 `hold` 一种命名;解析端可映射到同一 PX4 行为。
|
||
|
||
**典型组合**(「悬停 3 秒后降落」):
|
||
|
||
```json
|
||
[
|
||
{ "type": "takeoff", "args": {} },
|
||
{ "type": "hover", "args": {} },
|
||
{ "type": "wait", "args": { "seconds": 3 } },
|
||
{ "type": "land", "args": {} }
|
||
]
|
||
```
|
||
|
||
---
|
||
|
||
### 3.5 `goto` — 相对/局部位移
|
||
|
||
| args 键 | 类型 | 必填 | 说明 |
|
||
|---------|------|------|------|
|
||
| `frame` | `string` | 是 | 坐标系,取值见 §4 |
|
||
| `x` | `number` \| `null` | 否 | **米**;`null` 或 **省略** 表示该轴**无位移意图**(机端保持) |
|
||
| `y` | `number` \| `null` | 否 | 同上 |
|
||
| `z` | `number` \| `null` | 否 | 同上 |
|
||
|
||
```json
|
||
{
|
||
"type": "goto",
|
||
"args": {
|
||
"frame": "local_ned",
|
||
"x": 100,
|
||
"y": 0,
|
||
"z": 0
|
||
}
|
||
}
|
||
```
|
||
|
||
**语义**:在 `frame` 下相对当前位置的**增量**。v1 **不**定义绝对经纬度航点;若未来需要,应 **v2** 增加 `goto_global` / `waypoint`。
|
||
|
||
**口语映射示例**:「向前飞 10 米」可建模为 `frame: "body_ned"`, `x: 10`(前为 x+,与 §4 一致)。
|
||
|
||
---
|
||
|
||
### 3.6 `wait` — 纯时间等待
|
||
|
||
**不包含**模式切换;桥在**本地计时**后继续下一步。用于「悬停多久」「停顿再执行」等。
|
||
|
||
| args 键 | 类型 | 必填 | 说明 |
|
||
|---------|------|------|------|
|
||
| `seconds` | `number` | 是 | 等待秒数,须满足 **0 < seconds ≤ 3600**(上限可防止 LLM 写极大值;产品可改小) |
|
||
|
||
```json
|
||
{ "type": "wait", "args": { "seconds": 3 } }
|
||
```
|
||
|
||
**安全**:等待期间桥须持续监测遥测(失联、低电量、姿态异常等),**可中断**序列并转入 `RTL` / `LAND` / `HOLD`(策略见 §10.4)。
|
||
|
||
---
|
||
|
||
### 3.7 v1 动作类型一览
|
||
|
||
| `type` | 必填 `args` 键 | 备注 |
|
||
|--------|----------------|------|
|
||
| `takeoff` | 无 | 可选 `relative_altitude_m` |
|
||
| `land` | 无 | |
|
||
| `return_home` | 无 | |
|
||
| `hover` | 无 | |
|
||
| `hold` | 无 | 与 `hover` 等价 |
|
||
| `goto` | `frame` | 可选 x/y/z |
|
||
| `wait` | `seconds` | |
|
||
|
||
---
|
||
|
||
## 4. `frame`(仅 `goto`)
|
||
|
||
| 取值 | 含义 |
|
||
|------|------|
|
||
| `local_ned` | **局部 NED**:北(x)-东(y)-地(z),单位 m;**向下为 z 正**(与 PX4 `LOCAL_NED` 常见用法一致) |
|
||
| `body_ned` | **机体系**:**前(x)-右(y)-下(z)**,单位 m;桥或 ROS 侧需转换到 NED / setpoint |
|
||
|
||
**v1 仅此两值**;其它字符串 **L2 非法**。
|
||
|
||
---
|
||
|
||
## 5. 序列语义与组合规则
|
||
|
||
- **`actions` 有序**:严格对应口语**时间顺序**(先执行索引 0,再 1,…)。
|
||
- **空列表**:**不允许**(至少 1 个元素)。
|
||
- **`wait`**:不改变飞控模式;若需「边悬停边等」,应先 `hover`/`hold` 再 `wait`(或在上一步已进入位置模式的假定下仅 `wait`,由机端策略定义;**推荐**显式 `hover` 再 `wait`)。
|
||
- **首步**:首元素为 `wait` **不推荐**(飞机未起飞则等待无控飞意义);服务端可做 **L4 警告或拒绝**。
|
||
- **`takeoff` 后出现 `goto`**:桥应确保已有位置估计/GPS 等前置条件,否则拒绝并回报原因。
|
||
- **重复动作**:不禁止连续多个 `goto` / `wait`;机端可合并或排队。
|
||
|
||
---
|
||
|
||
## 6. 校验分级(服务端 + 桥建议共用)
|
||
|
||
| 级别 | 内容 |
|
||
|------|------|
|
||
| **L1 结构** | JSON 可解析;`is_flight_intent===true`;`version===1`;`actions` 为非空数组;`summary` 为非空字符串;`trace_id` 若存在则为 string。 |
|
||
| **L2 枚举** | 每个 `action.type` ∈ §3.7;`goto` 含合法 `frame`;各 `args` **仅含**该 `type` 允许的键(无多余键)。 |
|
||
| **L3 数值** | `relative_altitude_m` 若存在则 **> 0** 且建议 capped(如 ≤ 500);`wait.seconds` 在 **(0, 3600]**;`goto` 的 x/y/z 为有限 number 或 null;位移模长可设上限(如 10e3 m)。 |
|
||
| **L4 语义** | 结合 `session.start.client.px4`(机型、是否支持 Offboard、地理围栏等);禁止不合法序列(如无定位时 `goto`);不通过则 `error` 或带工程约定 `warnings`(v2 可标准化 `warnings` 数组)。 |
|
||
|
||
---
|
||
|
||
## 7. 完整示例
|
||
|
||
### 7.1 起飞 → 北飞 100m → 悬停
|
||
|
||
```json
|
||
{
|
||
"is_flight_intent": true,
|
||
"version": 1,
|
||
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
|
||
"actions": [
|
||
{ "type": "takeoff", "args": {} },
|
||
{
|
||
"type": "goto",
|
||
"args": { "frame": "local_ned", "x": 100, "y": 0, "z": 0 }
|
||
},
|
||
{ "type": "hover", "args": {} }
|
||
],
|
||
"summary": "起飞后向北飞约100米并悬停"
|
||
}
|
||
```
|
||
|
||
### 7.2 起飞 → 悬停 3 秒 → 降落
|
||
|
||
```json
|
||
{
|
||
"is_flight_intent": true,
|
||
"version": 1,
|
||
"actions": [
|
||
{ "type": "takeoff", "args": { "relative_altitude_m": 3 } },
|
||
{ "type": "hover", "args": {} },
|
||
{ "type": "wait", "args": { "seconds": 3 } },
|
||
{ "type": "land", "args": {} }
|
||
],
|
||
"summary": "起飞至约3米高,悬停3秒后降落"
|
||
}
|
||
```
|
||
|
||
### 7.3 返航
|
||
|
||
```json
|
||
{
|
||
"is_flight_intent": true,
|
||
"version": 1,
|
||
"actions": [
|
||
{ "type": "return_home", "args": {} }
|
||
],
|
||
"summary": "返航至 Home"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 8. 演进与扩展
|
||
|
||
- **新增 `type`、新 `frame`、顶层字段**:须 **递增 `version`**(如 `2`)并附迁移说明。
|
||
- **严禁**:在 `flight_intent` 内增加自由文本字段用于机动解释(仅 `summary` 可读)。
|
||
- **调试**:可在外层 bundle(非 `flight_intent` 体内)附加 `schema: "cloud_voice.flight_intent@1"`,由工程约定。
|
||
|
||
---
|
||
|
||
## 9. JSON → PX4 责任边界(摘要)
|
||
|
||
| JSON `type` | 机端典型职责(PX4 侧,非规范强制) |
|
||
|-------------|--------------------------------------|
|
||
| `return_home` | RTL / `MAV_CMD_NAV_RETURN_TO_LAUNCH` 等 |
|
||
| `takeoff` | TAKEOFF / `MAV_CMD_NAV_TAKEOFF`,高度来自 args 或参数 |
|
||
| `land` | LAND 模式 / `MAV_CMD_NAV_LAND` |
|
||
| `goto` | Offboard 轨迹、外部跟踪或 Mission 航点(**桥根据策略选一**) |
|
||
| `hover` / `hold` | LOITER / HOLD / 位置保持 setpoint |
|
||
| `wait` | 仅伴飞计时;**不发**模式切换 MAV 命令(除非实现为「保持当前模式下的阻塞」) |
|
||
|
||
**不重样规定**:MAVLink messageId、发送频率、Offboard 心跳、EKF 就绪条件由 **companion + PX4 装机** 保证。
|
||
|
||
---
|
||
|
||
## 10. 伴飞桥(Bridge)设计要点
|
||
|
||
本节约定:**桥** = 运行在伴飞计算机上的进程(可与语音同源或独立),负责消费 `flight_intent`(或等价 JSON),**绝不**把原始 LLM 文本直接发给 PX4。
|
||
|
||
### 10.1 逻辑分层
|
||
|
||
1. **接入**:WebSocket 回调 → 解析 `flight_intent`;或订阅 ROS Topic `flight_intent/json`;或 TCP 接收与本文相同的 JSON。
|
||
2. **校验**:至少 L1–L3;有 px4 上下文时做 L4。
|
||
3. **执行器**:对 `actions` **单线程顺序**执行;内部每步调用 **翻译器**(见 §10.3)。
|
||
4. **遥测与安全**:每步前置检查(模式、解锁、定位、电量、围栏);执行中 watchdog;可打断队列。
|
||
5. **回执(建议)**:ROS 发布 `flight_intent/result` 或写日志/Socket:success / rejected / aborted + `trace_id` + 步号 + 原因码。
|
||
|
||
### 10.2 与语音客户端的关系(本仓库)
|
||
|
||
- 语音侧可将 **`flight_intent` 映射** 为现有 `Command`(`command` + `params` + `sequence_id` + `timestamp`)经 **Socket** 发到桥;或由桥 **直接订阅云端结果**(二选一,避免双源)。
|
||
- **`wait`**:若 Socket 协议暂无对应 `Command`,桥在本地对「已解析的 `actions` 列表」执行 `wait`,**不必**经 Socket 转发计时。
|
||
- **扩展 `Command`**:若希望所有步骤可经 Socket 观测,可增加 `command: "noop"` + `params.duration` 仅作日志,但 **推荐** 桥本地处理 `wait`。
|
||
|
||
### 10.3 翻译器(`type` → 行为)
|
||
|
||
实现为代码表 + 机型分支,示例:
|
||
|
||
| `type` | 桥内典型步骤(抽象) |
|
||
|--------|----------------------|
|
||
| `takeoff` | 检查 arming 策略 → 发送起飞命令/切 TAKEOFF → 等待「达到 hover 可接受高度」或超时 |
|
||
| `land` | 切 LAND 或发 NAV_LAND → 监测直到 disarm 或超时 |
|
||
| `return_home` | 切 RTL |
|
||
| `hover`/`hold` | 切 AUTO.LOITER 或发位置保持 setpoint(Offboard 路径则发零速/当前位 setpoint) |
|
||
| `goto` | 按 `frame` 解算目标 → Offboard 轨迹或上传迷你 mission → 等待到达容差或超时 |
|
||
| `wait` | `sleep(seconds)` + 可中断环形检查遥测 |
|
||
|
||
每步应定义 **超时** 与 **失败策略**(中止整段序列 / 仅跳过一步)。
|
||
|
||
### 10.4 安全与中断
|
||
|
||
- **急停 / 人机优先级**:本地硬件或 ROS `/emergency_hold` 等应能 **清空队列** 并进入安全模式。
|
||
- **云断连**:不要求中断已在执行的序列(产品可配置「断连即 RTL」)。
|
||
- **`wait` 期间**:持续判据;触发阈值则 **中止等待** 并执行安全动作。
|
||
|
||
---
|
||
|
||
## 11. ROS / MAVROS 实施参考
|
||
|
||
以下为方便对接 **ROS 2 + MAVROS**(或 `px4_ros_com`)的**参考映射**;实际包名、话题名、QoS 以你方 `mavros` 版本与 launch 为准。
|
||
|
||
### 11.1 常用接口类型
|
||
|
||
| 目的 | 常见 ROS 2 形态 | 说明 |
|
||
|------|------------------|------|
|
||
| 模式切换 | `mavros_msgs/srv/VehicleCmd` 或 SetMode 等价服务 | 切 `AUTO.TAKEOFF`, `AUTO.LAND`, `AUTO.LOITER`, `AUTO.RTL` 等 |
|
||
| 解锁/上锁 | `cmd/arming` 服务或 VehicleCommand | 桥策略决定是否自动 arm |
|
||
| Offboard 轨迹 | `trajectory_setpoint`、`offboard_control_mode`(PX4 官方 ROS 2 示例) | 用于 `goto` / `hover` 的 setpoint 路径 |
|
||
| 状态反馈 | `vehicle_status`、`local_position`、电池 topic | L4 与每步完成判定 |
|
||
| 长航指令 | `Mission`、`CMD` 接口 | 复杂航迹可选用 mission 上传 |
|
||
|
||
### 11.2 JSON → ROS 责任划分建议
|
||
|
||
- **桥节点**订阅或接收 `flight_intent`,执行 §10.3,并调用 **MAVROS / px4_ros_com** 客户端。
|
||
- **飞控仿真**:同一套 `flight_intent` 可在 SITL 上回放,便于 CI。
|
||
- **单飞控单 writer**:同一时刻建议只有一个节点向 Offboard 端口写 setpoint,避免竞争。
|
||
|
||
### 11.3 与 PX4 模式的关系(概念)
|
||
|
||
- **AUTO 模式族**(TAKEOFF / LAND / LOITER / RTL):适合 `takeoff`、`land`、`return_home`、部分 `hover`。
|
||
- **Offboard**:适合连续 `goto`、精细悬停;桥需负责 **先切 Offboard 再发 setpoint**,并满足 PX4 Offboard 丢包监测。
|
||
- 具体选 AUTO 还是 Offboard 由 **桥配置**(YAML)决定,**不写入** `flight_intent` JSON(保持云侧与机型解耦)。
|
||
|
||
---
|
||
|
||
## 12. 与当前仓库实现的对齐清单
|
||
|
||
| 项 | 建议 |
|
||
|----|------|
|
||
| Pydantic | `FlightIntentPayload` / `FlightIntentAction`:收紧 `type` Literal;`args` 按 §3 分类型或 discriminated union |
|
||
| 云端校验 | `_validate_flight_intent`:L2 白名单 + `goto.frame` + `wait.seconds` + `takeoff.relative_altitude_m` |
|
||
| LLM 提示词 | 仅允许 §3.7 中 `type` 与各 `args` 键;**必须**用 `wait` 表达明确停顿时长 |
|
||
| `main_app` | `land`/`hover`/`return_home` 已映射为 Socket `Command`;`goto`/`takeoff`(关键词外)/`wait` 等仍依赖桥或扩展 |
|
||
| `Command` | 可扩展 `Literal` 与 `CommandParams`,或与桥约定「语音只发 Socket,复杂序列由桥执行」 |
|
||
|
||
---
|
||
|
||
**文档版本**:2026-04-07(修订:增加 `wait`、`takeoff` 可选高度、`trace_id`、桥与 ROS 章节)。与 **`flight_intent.version === 1`** 对应。
|