3. GCS系统架构设计

地面控制站(GCS)不是“一个带界面的程序”,而是一套同时承担链路管理、遥测解析、指令下发、任务规划、载荷控制、告警与日志回放的实时系统。架构设计的核心目标,是让这些职责在代码结构、数据流向和部署位置上都有清晰边界,从而在链路抖动、模块升级、机型扩展时不会牵一发动全身。

一、分层架构:把“变化频率”不同的部分分开

推荐采用五层结构,自下而上依次为:设备与链路层、通信适配层、数据服务层、业务逻辑层、人机交互层。分层的依据不是“代码多少”,而是变化频率与依赖方向:越靠下越稳定、越贴近硬件;越靠上越易变、越贴近操作员。

  • 设备与链路层:数传电台、4G/5G 模块、Wi-Fi、串口、网口,负责物理收发与链路状态(RSSI、丢包率、延迟)。
  • 通信适配层:把 MAVLink、自定义二进制帧、JSON 等不同协议统一成内部消息,处理粘包、校验、重传与心跳超时。
  • 数据服务层:维护“当前真值”——姿态、位置、电池、飞行模式、任务航点、告警状态,并提供订阅/发布接口。
  • 业务逻辑层:航线规划、起飞/返航/降落流程、地理围栏判断、载荷控制、日志记录与回放。
  • 人机交互层:地图、仪表、告警面板、任务编辑器,只消费数据服务层的数据,不直接读串口。

关键约束是依赖单向向下:上层可调用下层,下层通过事件/回调向上通知,禁止下层反向依赖 UI。这样替换电台或更换协议时,只影响适配层。

二、模块划分:按职责而非按界面切分

模块划分建议与分层对应,但粒度更细,典型模块包括:链路管理模块、协议编解码模块、遥测缓存模块、指令队列模块、任务规划模块、告警引擎、日志与回放模块、配置管理模块。每个模块对外只暴露接口,内部状态不共享。

以指令队列模块为例,它必须解决“操作员连点三次返航”的问题:指令进入队列后按优先级排序,高优先级(如紧急悬停)可插队,低优先级(如拍照)可合并或丢弃;每条指令带唯一序号、发送时间、超时时间与重试次数。示例参数:指令超时 800 ms,最大重试 3 次,重试间隔 200 ms;若 3 次均无 ACK,则向告警引擎推送“指令未确认”。

三、数据流设计:区分遥测流、指令流与事件流

GCS 内部至少存在三条方向不同的数据流:

  • 遥测流(下行):飞控 → 链路 → 适配层解析 → 数据服务层更新 → UI 刷新。频率通常 1~10 Hz,需做节流与合并,避免 UI 每帧重绘。
  • 指令流(上行):UI → 业务逻辑 → 指令队列 → 适配层编码 → 链路 → 飞控。必须可追踪、可重试、可取消。
  • 事件流(内部):如“电池低于 20%”“GPS 星数小于 6”“链路丢失超过 2 s”,由数据服务层产生,告警引擎消费并驱动 UI 与日志。

数据流设计的关键是单一数据源:姿态、位置等状态只在数据服务层维护一份,UI 与日志都从它读取,避免“地图显示的位置”和“日志记录的位置”不一致。

GCS 分层架构与三类数据流 人机交互层 业务逻辑层 数据服务层 通信适配层 设备与链路层 地图视图 仪表面板 任务编辑器 告警面板 航线规划 飞行流程 告警引擎 日志与回放 状态真值(姿态/位置/电池) 指令队列 事件总线(发布/订阅) MAVLink 编解码 自定义帧解析 心跳与超时 数传电台 4G/5G Wi-Fi 串口/网口 遥测流(下行) 指令流(上行) 事件流 依赖单向向下:上层调用下层,下层通过事件/回调向上通知;UI 不直接访问链路

四、接口定义:让模块之间“可替换、可测试”

接口定义要明确三件事:数据格式、调用方向、失败语义。以遥测订阅接口为例,可采用如下约定:

// 数据服务层对外接口(伪代码)
subscribeTelemetry(fields: string[], rateHz: number, callback: (t: TelemetryFrame) => void): SubscriptionId
// TelemetryFrame: { ts: number, lat: number, lon: number, alt: number, battery: number, mode: string }
// 失败语义:若链路断开,callback 不再触发,同时事件总线发布 LinkLost 事件

指令接口则必须返回可追踪的结果,而不是“发出去就不管”:

sendCommand(cmd: Command, opts: { timeoutMs: number, retries: number }): Promise<CommandResult>
// CommandResult: { seq: number, status: "ACK" | "TIMEOUT" | "REJECTED", rttMs: number }

接口命名要避免“sendData”“handleMsg”这类模糊词,而应体现业务含义,如 uploadMission、setFlightMode、requestTelemetry。这样在替换底层协议时,业务层代码无需改动。

五、部署拓扑:单机、双机与分布式

部署拓扑取决于任务规模与可靠性要求。常见三种:

  • 单机部署:一台地面站电脑同时运行 UI、业务逻辑与链路服务,适合小型多旋翼、单操作员场景。优点是简单,缺点是 UI 卡顿会影响链路收发。
  • 双机热备:主备两台电脑通过心跳互检,主站故障时备站接管链路与任务。关键是状态同步——任务航点、飞行模式、告警状态需在备站保持镜像。
  • 分布式部署:链路服务、数据服务、UI 分离到不同进程或主机,通过内部消息总线通信,适合多操作员、多机协同或远程指挥场景。

无论哪种拓扑,都建议把链路服务与 UI 进程分离:链路服务作为独立进程运行,UI 崩溃或重启时链路不中断,遥测继续写入日志。这是工程上性价比最高的一条部署原则。

架构评审时可用三个问题快速检验:新增一种机型需要改几层?替换电台需要改几个模块?UI 崩溃后链路是否仍在记录?如果答案分别是“只改适配层”“只改链路管理”“是”,说明分层与接口边界基本合理。

综上,GCS 架构设计的主线是:用分层隔离变化,用模块划分明确职责,用三条数据流理清方向,用接口定义约束依赖,用部署拓扑匹配任务规模。这五者共同决定系统在扩展、排障和升级时的实际成本。