QGroundControl 设置视图(Setup View)架构解析:固定面板与 VehicleComponent 动态配置体系

原创2026-10-02 16:18:32464 阅读
文章标签:无人机智能硬件

QGroundControl 设置视图(Setup View)架构解析:固定面板与 VehicleComponent 动态配置体系

导读

设置视图(Setup View)是 QGroundControl 地面站中用于对无人机进行飞前配置的核心界面,涵盖机架选择、传感器校准、遥控器设置、飞行模式、动力与安全配置、固件升级等全部装机环节。本篇以开发指南文档《Setup View》为骨架,结合当前仓库源码(VehicleConfigView.qml、AutoPilotPlugin.h、VehicleComponent.h 等),深入解析该视图"固定按钮 + 插件动态组件列表"的架构设计、页面组织方式与底层实现原理,帮助读者理解如何在 QGC 中扩展新的配置页面,并掌握其入口加载、参数就绪、前置依赖与安全禁用等关键机制。


一、从 SetupView.qml 到 VehicleConfigView.qml:视图的入口与演进

开发指南中明确指出,设置视图的顶级 QML 代码在 SetupView.qml 中实现。在当前的仓库代码中,该顶级视图已重构为 VehicleConfigView.qml(位于 src/Vehicle/VehicleSetup/ 目录),并在 MainWindow.qml 中通过如下代码被加载进主窗口的工具抽屉(Tool Drawer):

function showVehicleConfig() {
    showTool(qsTr("Vehicle Configuration"), "qrc:/qml/QGroundControl/VehicleSetup/VehicleConfigView.qml", "/qmlimages/Gears.svg")
}

这一调用揭示出设置视图的完整加载链路:

  1. 用户在主窗口点击"齿轮"图标或通过工具栏触发 showVehicleConfig();
  2. showTool() 将 VehicleConfigView.qml 的资源路径注入 toolDrawer 并显示工具面板;
  3. VehicleConfigView.qml 作为根矩形(Rectangle)挂载在 toolDrawerLoader 中,并设置 objectName: "vehicleConfig_root"、z: QGroundControl.zOrderTopMost,确保其覆盖在底图之上。

视图内部还通过 DeadMouseArea 屏蔽底层地图的点击事件穿透,防止配置页面操作误触地图。

从源码结构看,SetupView.qml 是早期版本的命名,现仓库已将其整合进 VehicleSetup 目录体系,与 SetupPage.qml(所有子配置页面的通用基类)、VehicleSummary.qml、FirmwareUpgrade.qml、SetupParameterEditor.qml 等文件共同组成设置视图模块。


二、固定按钮集:Summary 与 Firmware 面板

2.1 Summary(摘要页)

侧边栏的第一个固定按钮是 Summary(VehicleConfigView.qml),点击后调用 showSummaryPanel()。摘要页的内容加载具有严格的状态分支逻辑(_showSummaryPanel()),根据车辆连接与参数状态决定显示何种摘要组件:

车辆状态 加载组件 提示内容
参数就绪且组件列表为空 noComponentsVehicleSummaryComponent "当前固件尚不支持配置该机型,已配置好可直接飞行"
参数就绪但有缺失参数 missingParametersVehicleSummaryComponent "车辆未返回完整参数列表,配置页面不可用"
无活动车辆或参数下载中 disconnectedVehicleAndParamsSummaryComponent "连接车辆并完成参数下载后,配置页面才会显示"(并提供"Download Parameters"按钮触发 refreshAllParameters())
参数就绪且存在组件 加载 VehicleSummary.qml(qrc:/qml/QGroundControl/VehicleSetup/VehicleSummary.qml) 按组件网格展示配置完成状态

其中 VehicleSummary.qml 的顶部标题会根据 autopilotPlugin.setupComplete 属性动态切换文案:配置未完成时以警告色显示 "Configuration tasks remain before this vehicle is ready to fly",并提示打开左侧红色标记的组件完成配置;配置完成后则显示正常引导文案。下方 Repeater 遍历所有 VehicleComponent,结合各组件提供的 summaryQmlSource 与 setupComplete 状态生成摘要卡片。

2.2 Firmware(固件升级)

第二个固定按钮是 Firmware(VehicleConfigView.qml),点击后加载 FirmwareUpgrade.qml(资源路径 qrc:/qml/QGroundControl/VehicleSetup/FirmwareUpgrade.qml)。该按钮有两个显式的显示条件:

  • !ScreenTools.isMobile:仅在桌面端显示,移动端(Android/iOS)不提供固件刷写入口;
  • _corePlugin.options.showFirmwareUpgrade:由核心插件选项控制,可通过自定义插件关闭固件升级功能。

2.3 其他"特殊"固定面板

除了开发指南提到的 Summary 与 Firmware,当前源码还实现了两类按条件出现的固定面板:

  • Parameters(参数编辑器)(VehicleConfigView.qml):显示条件为参数就绪、非高延迟链路、且 _corePlugin.showAdvancedUI(仅高级 UI 模式可见),点击后加载 SetupParameterEditor.qml,用于直接浏览与编辑全部飞控参数(如 PX4 的 SYS_*、COM_* 等);
  • Optical Flow(光流传感器)(VehicleConfigView.qml):当 _activeVehicle.flowImageIndex > 0(车辆报告携带光流传感器)时显示,加载 OpticalFlowSensor.qml。

这两类按钮与 Summary、Firmware 一样,都是在 VehicleComponent 动态列表之外硬编码在视图里的,共同构成"固定按钮集"。


三、动态部分:AutoPilotPlugin 的 VehicleComponent 列表

3.1 动态列表的渲染方式

开发指南指出:"按钮/页面的剩余部分来自 AutoPilotPlugin VehicleComponent 列表"。这一设计在 VehicleConfigView.qml 中体现为 componentRepeater:

Repeater {
    id:     componentRepeater
    model:  _fullParameterVehicleAvailable ? _activeVehicle.autopilotPlugin.vehicleComponents : 0
    ...
}

也就是说,左侧侧边栏在 Summary 与 Firmware 之下渲染的所有配置入口,全部来源于当前活动车辆的 autopilotPlugin.vehicleComponents 属性。每个组件条目由 VehicleComponent.h 中定义的以下核心属性驱动:

Q_PROPERTY 说明
name 组件显示名称(如 Airframe、Sensors、Radio)
description 组件描述,显示在配置页标题区
iconResource 侧边栏按钮图标资源路径
setupSource 该组件配置面板的 QML 资源地址,点击后由 panelLoader 加载
setupComplete 配置是否完成,驱动侧边栏绿色/橙色圆点标记
sectionIds 组件内部的可展开小节 ID 列表(如 Sensors 下的 Accelerometer、Gyroscope 等),用于树形二级导航
sectionKeywords 各小节的搜索关键词(可翻译),驱动视图内搜索框过滤
allowSetupWhileArmed / allowSetupWhileFlying 是否允许在解锁/飞行状态下进行该组件配置

panelLoader(VehicleConfigView.qml)负责按需加载每个组件提供的 setupSource,并在组件拥有多个 sectionIds 时通过 sectionIdFilter 属性将小节过滤条件传递给加载出的配置面板。

3.2 组件列表是如何构建的:以 PX4 为例

vehicleComponents 是 AutoPilotPlugin.h 中声明的抽象属性(virtual const QVariantList &vehicleComponents() = 0),由各固件插件具体实现。以 PX4AutoPilotPlugin.cc 为例,组件列表的构建遵循以下逻辑:

  1. 参数就绪前置检查:只有 _vehicle->parameterManager()->parametersReady() 为真时才开始构建组件,否则输出 "Call to vehicleCompenents prior to parametersReady" 警告并返回空列表——这正是开发指南所述"动态部分"存在的前提:必须等参数下载完成后才有组件页面;
  2. 按机型与硬件条件逐项创建:
    • 固定创建:AirframeComponent(机架)、PX4RadioComponent(遥控器)、FlightModesComponent(飞行模式)、PowerComponent(电源)、SafetyComponent(安全)、PX4TuningComponent(调参)、JoystickComponent(手柄);
    • 条件创建:非 HIL 仿真模式才创建 SensorsComponent;根据执行机构元数据决定显示新版 ActuatorComponent 还是旧版 MotorComponent;检测到 SYS_VEHICLE_RESP 参数才创建 PX4FlightBehavior;检测到 UDP 桥接参数 SW_VER 才创建 ESP8266Component;检测到 SLNK_RADIO_CHAN 参数才创建 SyslinkComponent;
  3. 排序:全部组件创建完成后,按 name() 字母序排序(std::sort)。

可见"剩余按钮/页面来自 VehicleComponent 列表"的实质是:每个飞控固件插件在参数就绪后,根据机型、仿真模式、硬件探测结果动态组装一份配置组件清单,设置视图只负责渲染这份清单,从而做到"同一个视图、不同固件呈现不同配置入口"。

3.3 组件的"配置完成"联动

AutoPilotPlugin.cc 中的 _recalcSetupComplete() 会遍历所有组件汇总 setupComplete 状态:只要任一组件未完成配置,插件的 setupComplete 即为 false,并通过 parametersReadyPreChecks() 弹出应用级提示"Configuration tasks remain before this vehicle is ready to fly"。同时它把每个组件的 setupCompleteChanged 信号连接到 _recalcSetupComplete,保证用户完成某项配置后摘要页与侧边栏状态实时刷新。这也是 VehicleSummary.qml 顶部警告文案的数据来源。


四、树形导航、搜索与前置依赖机制

4.1 可展开的组件树与搜索过滤

当前实现的侧边栏是支持二级展开的树形结构(开发指南文档成文时称为"按钮/页面"集,现源码已扩展为树):

  • 组件拥有多个 sectionIds 时,根按钮可展开(expandable/expanded 属性),点击展开后显示各小节子项;
  • 每个小节子项带有一个状态圆点:sectionSetupComplete 为 true 时绿色(qgcPal.colorGreen),否则橙色(qgcPal.colorOrange),与根按钮的 setupComplete 标记逻辑一致(VehicleConfigView.qml);
  • 顶部搜索框(searchField)支持按组件名、小节 ID、显示名及 sectionKeywords 关键词进行实时过滤(_componentMatchesSearch / _sectionMatchesSearch,VehicleConfigView.qml);
  • 小节 ID 保持跨语言稳定(用于过滤与路由),显示名通过 _sectionDisplayName() 结合 JSON 文件名翻译上下文或组件的 sectionDisplayName() 函数本地化。

4.2 前置依赖(prerequisiteSetup)

部分组件依赖其他组件先完成配置,这一约束由插件层的 prerequisiteSetup(component) 虚函数实现(声明于 AutoPilotPlugin.h)。PX4 实现(PX4AutoPilotPlugin.cc)的核心逻辑如下:

  • FlightModesComponent:若 COM_RC_IN_MODE 非"无遥控输入"模式,则依次要求 Airframe 与 Radio 组件完成配置;
  • PX4TuningComponent / PowerComponent / SafetyComponent / SensorsComponent:均要求 Airframe 组件先完成(requiresAirframeCheck 统一处理);
  • 当检测到前置未满足时,VehicleConfigView.qml 的 _navigateToComponent() 会加载 messagePanelComponent 并显示提示:"%1 setup must be completed prior to %2 setup."(例如"必须先完成 Airframe 设置才能进行 Sensors 设置")。

4.3 参数未就绪时的兜底界面

若 _fullParameterVehicleAvailable 为 false(未连接、参数下载被跳过、参数缺失),动态组件列表渲染为空,同时搜索框隐藏,仅保留 Summary 与 Firmware 固定按钮。此时摘要页会给出对应引导(见 2.1 表格),其中"参数下载被跳过"场景还提供一键 refreshAllParameters() 按钮,待参数就绪后视图自动切换到正常摘要(通过 onParameterReadyVehicleAvailableChanged 连接触发)。


五、子页面基类 SetupPage 的安全与高级选项机制

所有由 VehicleComponent 加载的配置面板都基于通用基类 SetupPage.qml。该基类承担了两项关键职责:

  1. 安全禁用机制:当 _vehicleArmed(已解锁)或 _vehicleFlying(飞行中)为真时,若组件未声明 allowSetupWhileArmed / allowSetupWhileFlying,整个页面会被禁用(enabled: false),标题区显示警告文案 "Disabled while the vehicle is armed/flying",页面之上叠加半透明黑色遮罩(SetupPage.qml),防止飞行中误改配置;
  2. 高级选项开关:showAdvanced 属性控制页面头部是否显示"Advanced"复选框(advancedCheckBox),用于把进阶参数折叠在高级模式内,与设置视图入口的 showAdvancedUI 全局开关配合使用;
  3. 小节过滤透传:基类转发 sectionIdFilter 与 sectionVisible() 调用给实际加载的页面,使侧边栏小节导航与面板内容联动。

从源码结构看,SetupPage.qml 处于 src/QmlControls/ 目录,属于跨模块复用的公共控件,任何新配置页面(无论是手写 QML 还是 JSON 驱动的 vehicleConfigJson 页面)都可直接以它为根组件获得上述能力。


六、扩展指引:如何为设置视图新增配置页面

综合开发指南的架构说明与上述源码实现,开发者向 QGC 添加一个新配置页面的标准路径如下(仓库只读,此处仅介绍扩展机制本身):

  1. 实现一个 VehicleComponent 子类:继承 VehicleComponent(VehicleComponent.h),实现 name()、iconResource()、setupComplete()、setupSource()、summaryQmlSource() 等纯虚函数,并根据需要覆盖 sectionIds()、sectionKeywords()、allowSetupWhileArmed() 等;
  2. 在固件插件中注册:在对应固件的 vehicleComponents() 实现(如 PX4AutoPilotPlugin.cc)中实例化组件并 _components.append(...),可配合参数探测(parameterExists)实现条件显隐;
  3. 编写配置面板 QML:以 SetupPage.qml 为根组件编写页面,或提供 JSON 驱动的页面定义(vehicleConfigJson())以自动生成小节导航;
  4. 如需强制依赖顺序:在插件的 prerequisiteSetup() 中返回前置组件名,视图会自动拦截并提示。

设置视图会自动完成其余工作:侧边栏按钮生成、图标与完成标记、摘要卡片、搜索过滤、参数就绪等待与解锁/飞行安全禁用。


七、总结

QGroundControl 设置视图的本质是一个**"固定外壳 + 动态插件列表"**的组合架构:SetupView.qml(现为 VehicleConfigView.qml)提供侧边栏、搜索框、面板加载器与状态兜底;Summary、Firmware(及高级模式下的 Parameters、条件出现的 Optical Flow)构成固定面板集;其余所有配置入口则由 AutoPilotPlugin 在参数就绪后动态生成的 VehicleComponent 列表驱动。这种设计将"界面框架"与"固件特性"解耦,使 PX4、ArduPilot(APM)与 Generic 固件能够共享同一套设置视图框架,同时呈现各自差异化的配置流程,并通过 prerequisiteSetup、setupComplete、armed/flying 禁用等机制保障配置过程的安全与有序。

登录后查看全文
qgroundcontrol