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 与日志都从它读取,避免“地图显示的位置”和“日志记录的位置”不一致。
四、接口定义:让模块之间“可替换、可测试”
接口定义要明确三件事:数据格式、调用方向、失败语义。以遥测订阅接口为例,可采用如下约定:
// 数据服务层对外接口(伪代码)
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 崩溃或重启时链路不中断,遥测继续写入日志。这是工程上性价比最高的一条部署原则。
综上,GCS 架构设计的主线是:用分层隔离变化,用模块划分明确职责,用三条数据流理清方向,用接口定义约束依赖,用部署拓扑匹配任务规模。这五者共同决定系统在扩展、排障和升级时的实际成本。