当前位置: 首页 > news >正文

QGC 固件升级与硬件适配

QGC 固件升级与硬件适配

7.0 总体架构

QGC 4.0 将「固件烧录」与「运行时硬件/协议适配」分为两条相对独立的链路:

┌─────────────────────────────────────────────────────────────────┐ │ 离线烧录链路(USB 串口) │ │ FirmwareUpgrade.qml → FirmwareUpgradeController │ │ → PX4FirmwareUpgradeThread → Bootloader → QSerialPort │ └─────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────────┐ │ 在线运行链路(MAVLink 连接后) │ │ MultiVehicleManager → Vehicle │ │ → FirmwarePluginManager → FirmwarePlugin(PX4/APM/Generic)│ │ → AutoPilotPlugin → VehicleComponent[](传感器/机架/电台…) │ │ → ParameterManager + *ParameterMetaData │ └─────────────────────────────────────────────────────────────────┘

设计原则:

  • FirmwarePlugin:飞行栈(PX4 / ArduPilot)相关的全部差异逻辑应集中在此
  • AutoPilotPlugin+VehicleComponent:Setup 向导、传感器校准、机架选择等 UI/参数逻辑
  • VehicleMissionManager等保持MAVLink 通用,差异通过 Plugin 钩子注入

涉及的主要设计模式:

模式体现
Plugin 模式FirmwarePlugin/AutoPilotPlugin抽象飞行栈差异
Factory + 注册表FirmwarePluginFactory构造时自注册到FirmwarePluginFactoryRegister
Singleton(懒加载)各 Factory 内_pluginInstance单例复用
MVCFirmwareUpgradeController(C++)+FirmwareUpgrade.qml(View)
Worker ThreadPX4FirmwareUpgradeThreadController在独立线程执行串口 I/O
Strategy按 URI/板型/协议选择不同固件 URL、Bootloader 命令集
Template MethodVehicleComponent定义 setup 流程骨架,子类实现具体 QML/参数
AdapteradjustIncomingMavlinkMessage修正 APM 与标准 MAVLink 差异
Hash Map 配置_rgFMUV5Firmware等 boardId → URL 映射表

涉及语法与技术:

  • C++:QObjectQ_PROPERTYQ_INVOKABLEQ_ENUMsignals/slots
  • Qt Serial:QSerialPortQSerialPortInfo
  • JSON/XML:QJsonDocument.px4/.apj/manifest)、QXmlStreamReader(参数元数据)
  • Intel Hex:.ihx解析(SiK Radio)
  • MAVLink:mavlink_message_tMAV_AUTOPILOTMAV_TYPE
  • QML:SetupPageFirmwareUpgradeController注册为QGroundControl.Controllers

7.1 飞控固件烧录流程开发

7.1.1 模块与文件索引

文件职责
VehicleSetup/FirmwareUpgrade.qml固件升级 UI(Setup → Firmware)
VehicleSetup/FirmwareUpgradeController.h/.ccMVC 控制器:选固件、下载、调度烧录
VehicleSetup/PX4FirmwareUpgradeThread.h/.cc独立线程:找板、同步 Bootloader、擦除/编程/校验
VehicleSetup/Bootloader.h/.ccPX4 Bootloader 二进制协议实现
VehicleSetup/FirmwareImage.h/.cc固件镜像解析(.bin/.px4/.apj/.ihx)
comm/QGCSerialPortInfo.h/.ccUSB VID/PID 识别板型
comm/USBBoardInfo.json板型 VID/PID 配置表
Settings/FirmwareUpgradeSettings.*APM ChibiOS、机型偏好等

7.1.2 用户操作流程(状态机)

Plug USB → startBoardSearch() → 扫描串口 (canFlash) → 发现板 (foundBoard) → UI 显示板名 → 用户选 Stack(PX4/APM) + 版本(Stable/Beta/Dev) + 机型 → flash() → 等待 Bootloader (foundBootloader) → 解析 board_id / flash_size → 查 Hash 得固件 URL → QGCFileDownload 下载 → FirmwareImage::load() 校验 board_id、解压元数据 → ThreadController::flash() → erase → program → verify → reboot → flashComplete → 恢复 LinkManager 连接

入口startBoardSearch()关键行为:

void FirmwareUpgradeController::startBoardSearch(void) { LinkManager* linkMgr = qgcApp()->toolbox()->linkManager(); linkMgr->setConnectionsSuspended(tr("Connect not allowed during Firmware Upgrade.")); ... _threadController->startFindBoardLoop(); }

烧录期间禁止新建 MAVLink 连接,避免与 Bootloader 串口冲突。

7.1.3 USB 板型识别

QGCSerialPortInfo::getBoardInfo()读取:/json/USBBoardInfo.json

"boardInfo": [ { "vendorID": 9900, "productID": 16, "boardClass": "Pixhawk", "name": "PX4 FMU V1" }, { "vendorID": 9900, "productID": 17, "boardClass": "Pixhawk", "name": "PX4 FMU V2" }, ... { "vendorID": 9900, "productID": 50, "boardClass": "Pixhawk", "name": "PX4 FMU V5" },

匹配逻辑:先VID+PID,失败则description/manufacturer 正则 fallback

canFlash()仅对三类板返回 true:

bool QGCSerialPortInfo::canFlash(void) const { ... switch(boardType){ case QGCSerialPortInfo::BoardTypePixhawk: case QGCSerialPortInfo::BoardTypePX4Flow: case QGCSerialPortInfo::BoardTypeSiKRadio: return true;

新增可烧录硬件的第一步:在USBBoardInfo.json增加 VID/PID 条目,并在Bootloader.h增加boardID*常量(若为新 PX4 板型)。

7.1.4 Bootloader 通信协议

Bootloader类实现 PX4 官方 Bootloader 协议(也用于 3DR Radio 变体):

协议字节(节选):

符号含义
PROTO_INSYNC0x12同步前缀
PROTO_EOC0x20命令结束
PROTO_OK/PROTO_FAILED0x10 / 0x11响应
PROTO_GET_SYNC0x21建立同步
PROTO_CHIP_ERASE0x23全片擦除
PROTO_PROG_MULTI0x27多块写入(最大 64 字节,4 字节对齐)
PROTO_GET_CRC0x29CRC 校验(Bootloader ≥3)
PROTO_BOOT0x30重启进应用

烧录核心循环(.bin格式):

while (bytesSent < imageSize) { ... if (_write(port, PROTO_PROG_MULTI)) { if (_write(port, (uint8_t)bytesToSend)) { if (_write(port, imageBuf, bytesToSend)) { if (_write(port, PROTO_EOC)) { if (_getCommandResponse(port)) { failed = false; } } } } } ... _imageCRC = QGC::crc32((uint8_t *)imageBuf, bytesToSend, _imageCRC); emit updateProgress(bytesSent, imageSize); }

校验策略:

  • Bootloader ≤2 或.ihx:逐字节PROTO_READ_MULTI回读比对
  • Bootloader ≥3 且.binPROTO_GET_CRC与预计算 CRC 比较
  • 完成后reboot()发送PROTO_BOOT

Board ID 常量(与固件包内board_id对应):

static const int boardIDPX4FMUV2 = 9; static const int boardIDPX4FMUV4 = 11; static const int boardIDPX4FMUV5 = 50; static const int boardIDPX4FMUV3 = 255; // V2 大 Flash 模拟 ID static const int boardIDDurandalV1 = 139; ...

7.1.5 独立线程 Worker

PX4FirmwareUpgradeThreadController将耗时串口操作移出 UI 线程:

Controller (主线程) Worker (子线程) startFindBoardLoop ──signal──► _findBoardOnce() flash(image) ──signal──► _flash(): erase→program→verify cancel ──signal──► 关闭端口 ◄── foundBootloader / updateProgress / flashComplete

找 Bootloader 流程:

  1. 枚举QGCSerialPortInfo::availablePorts(),过滤canFlash()
  2. 首次发现 emitfoundBoard(UI 等待用户确认/选固件)
  3. 第二次循环(非 firstAttempt)打开串口 →Bootloader::sync()getPX4BoardInfo()INFO_BL_REV / INFO_BOARD_ID / INFO_FLASH_SIZE
  4. SiK Radio 特殊路径:先发+++/AT&UPDATE强制进 Bootloader

完整烧录_flash()

if (_erase()) { if (_bootloader->program(_bootloaderPort, _controller->image())) { ... } if (_bootloader->verify(_bootloaderPort, _controller->image())) { ... } } emit _reboot(); emit flashComplete();

7.1.6 固件镜像格式(FirmwareImage)

扩展名格式用途
.bin原始二进制直接编程
.px4JSON 包装(PX4 传统)含 base64 镜像 + 压缩 parameter/airframe XML
.apjJSON 包装(ArduPilot ChibiOS).px4结构,MAV_AUTOPILOT=APM
.ihxIntel Hex3DR SiK Radio

.px4/.apj加载流程:

QJsonDocument doc = QJsonDocument::fromJson(bytes); ... uint32_t firmwareBoardId = (uint32_t)px4Json.value(_jsonBoardIdKey).toInt(); if (!isCompatible(_boardId, firmwareBoardId)) { emit statusMessage(...); return false; }

兼容规则示例:FMUv3(board_id=255)可烧 FMUv2(id=9)固件;AUAV X2.1 同理。

解压后的parameter XML写入缓存并注册到ParameterManager::cacheMetaDataFile(),使烧录后 Setup 界面立即可用最新参数元数据,无需等飞控在线。

7.1.7 固件 URL 来源

(1)PX4 静态 Hash 表

_initFirmwareHash()为每块板维护QHash<FirmwareIdentifier, QString>

  • Key:AutoPilotStackType+FirmwareBuildType+FirmwareVehicleType
  • Value:S3 URL,如http://px4-travis.s3.amazonaws.com/Firmware/stable/px4fmu-v5_default.px4

FMUv2/V3/V4/V5、Durandal、KakuteF7 等各有独立 Hash。

(2)PX4 GitHub Releases 动态版本

_determinePX4StableVersion()拉取https://api.github.com/repos/PX4/Firmware/releases解析 stable/beta 标签。

(3)ArduPilot manifest.json

void FirmwareUpgradeController::_downloadArduPilotManifest(void) { ... downloader->download(QStringLiteral("http://firmware.ardupilot.org/manifest.json")); }

解析字段:board_idmav-typeurlmav-firmware-version-typeUSBIDbootloader_strbrand_name等,动态构建_rgManifestFirmwareInfo,供 ChibiOS 板按名称列表选择固件。

(4)SingleFirmwareMode

Custom 构建可通过QGCOptions::firmwareUpgradeSingleURL()指定单一 URL,跳过用户选择。

7.1.8 Controller 与 QML 绑定

FirmwareUpgradeController暴露给 QML 的属性示例:

  • boardPort/boardDescription/pixhawkBoard
  • selectedFirmwareBuildType(Stable/Beta/Dev/Custom)
  • apmFirmwareNames/apmFirmwareUrls(APM manifest 动态列表)
  • progressBar/statusLog(QQuickItem 指针,C++ 直接setProperty("value", ...)

QML 调用:

FirmwareUpgradeController { onFlashComplete: ... } // Q_INVOKABLE: controller.startBoardSearch() controller.flash(AutoPilotStackPX4, StableFirmware, DefaultVehicleFirmware)

7.1.9 扩展烧录流程的开发指南

若需支持新 Bootloader 协议新文件格式

  1. 扩展FirmwareImage::load()增加解析分支
  2. Bootloader中实现新命令集,或新建XxxBootloader
  3. 修改PX4FirmwareUpgradeThreadWorker::_findBootloader()的打开/同步逻辑
  4. FirmwareUpgradeController::_initFirmwareHash()或 manifest 解析处增加 URL
  5. 更新USBBoardInfo.jsonBootloader::boardID*常量

若仅需支持新 PX4 兼容板(沿用 PX4 Bootloader):通常只需 JSON + Hash URL,无需改协议代码。


7.2 新增机型、外设传感器适配

7.2.1 运行时对象模型

Vehicle 创建 └─ _firmwarePlugin = FirmwarePluginManager::firmwarePluginForAutopilot(type, mavType) └─ _firmwarePlugin->initializeVehicle(this) └─ ParameterManager 就绪后 └─ AutoPilotPlugin::vehicleComponents() └─ AirframeComponent / SensorsComponent / RadioComponent / ... └─ 各 Component 绑定 setup QML + Fact 参数名

Vehicle 中获取 Plugin:

void Vehicle::_commonInit() { _firmwarePlugin = _firmwarePluginManager->firmwarePluginForAutopilot(_firmwareType, _vehicleType);

7.2.2 FirmwarePluginFactory 注册机制

全局静态 Factory 对象在构造时自注册:

FirmwarePluginFactory::FirmwarePluginFactory(void) { FirmwarePluginFactoryRegister::instance()->registerPluginFactory(this); }

PX4 Factory:

QList<MAV_AUTOPILOT> PX4FirmwarePluginFactory::supportedFirmwareTypes(void) const { list.append(MAV_AUTOPILOT_PX4);

APM Factory(按 MAV_TYPE 分派):

switch (vehicleType) { case MAV_TYPE_QUADROTOR: case MAV_TYPE_HELICOPTER: return _arduCopterPluginInstance; case MAV_TYPE_FIXED_WING: case MAV_TYPE_VTOL_QUADROTOR: return _arduPlanePluginInstance; case MAV_TYPE_GROUND_ROVER: return _arduRoverPluginInstance; case MAV_TYPE_SUBMARINE: return _arduSubPluginInstance;

新增「机型」在 QGC 语义下通常指:

  • 新的MAV_TYPE组合 → 新建或扩展ArduXxxFirmwarePlugin
  • 新的机架/airframe→ PX4AirframeComponent+PX4AirframeLoaderXML
  • 新的Setup 步骤/外设→ 新建VehicleComponent子类

7.2.3 AutoPilotPlugin 与 VehicleComponent

VehicleComponent 抽象接口:

virtual QString name(void) const = 0; virtual bool requiresSetup(void) const = 0; virtual bool setupComplete(void) const = 0; virtual QUrl setupSource(void) const = 0; // 完整 Setup 面板 QML virtual QUrl summaryQmlSource(void) const = 0; // 摘要卡片 QML virtual QStringList setupCompleteChangedTriggerList(void) const = 0;

PX4 Setup 组件列表示例:

Component职责关键参数 Fact
AirframeComponent机架/机型选择SYS_AUTOSTART,SYS_AUTOCONFIG
SensorsComponentIMU/罗盘/气压计/空速计校准CAL_*,SENS_*
PX4RadioComponent遥控校准RC_*
FlightModesComponent飞行模式映射RC_MAP_*
PowerComponent电池/电源BAT_*
MotorComponent电机测试PWM_*
SafetyComponent返航/地理围栏RTL_*,GF_*
PX4TuningComponentPID 调参各控制器增益

APM 对应:APMSensorsComponentAPMAirframeComponentAPMMotorComponentAPMSubFrameComponent(ROV 框架)、APMLightsComponent等。

7.2.4 新增外设/传感器适配步骤(PX4 为例)

步骤 1:确认参数名与校准命令

PX4 传感器校准通过 MAVLinkMAV_CMD_PREFLIGHT_CALIBRATION或参数读写完成,QGCSensorsComponent的 QML 触发 C++ 发送命令。新传感器需确认固件暴露的参数名(如SENS_EN_XXX)和校准流程。

步骤 2:扩展 SensorsComponent

  • 修改setupCompleteChangedTriggerList()增加新参数
  • setupComplete()中检查校准状态参数(如CAL_ACC0_ID非零表示已校准)
  • SensorsSetup.qml(或对应 QML)增加 UI 入口

步骤 3:参数元数据(Parameter MetaData)

PX4 使用 XML 描述参数短名、单位、枚举、增量:

void loadParameterFactMetaDataFile (const QString& metaDataFile); FactMetaData* getMetaDataForFact (const QString& name, MAV_TYPE vehicleType); void addMetaDataToFact (Fact* fact, MAV_TYPE vehicleType);

元数据来源:

  • 飞控在线:ParameterManager向飞控请求
  • 离线/烧录后:.px4包内parameter_xml解压缓存
  • 内置:编译资源:/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml

新增参数 UI 显示:在固件 Parameter XML 中加入定义即可被 Fact 系统自动识别;若需特殊控件,扩展FactMetaDataenumStrings或自定义 QML FactControl。

步骤 4:机架/Airframe 元数据

PX4AutoPilotPlugin构造时:

_airframeFacts = new PX4AirframeLoader(this, _vehicle->uas(), this); PX4AirframeLoader::loadAirframeMetaData();

Airframe XML 定义SYS_AUTOSTARTID 与机型名称映射。新增 PX4 机架需在 PX4 固件侧airframes/添加,QGC 通过烧录包或在线同步 XML 自动更新列表。

步骤 5:FactGroup 扩展(遥测显示)

新传感器若通过 MAVLink 消息上报(非参数),在Vehicle或专用XxxFactGroup中解析消息并暴露Fact,供 Fly 视图仪表板使用。例如_distanceSensorFactGroup_battery1FactGroup

7.2.5 APM 传感器与机型差异

APM 的APMAutoPilotPlugin::vehicleComponents()vehicleType + 参数存在性动态组装:

  • 直升机:APMHeliComponent
  • 潜水器:APMSubFrameComponentAPMLightsComponent
  • 相机:APMCameraComponent(检测CAM1_TYPE等)
  • ESP8266 WiFi:ESP8266Component
if ( _vehicle->supportsRadio() ) { _radioComponent = new APMRadioComponent(_vehicle, this);

supportsRadio()来自FirmwarePlugin::supportsRadio()虚函数,可按机型关闭 RC Setup。

7.2.6 USB 外设自动连接

LinkManager扫描串口时调用QGCSerialPortInfo::getBoardInfo(),对 RTK GPS、SiK Radio 等可自动创建连接。新增 USB 外设类型:

  1. USBBoardInfo.json增加boardClass(如RTK GPS
  2. LinkManager自动连接逻辑中增加对应处理

7.2.7 Custom 定制示例

custom-example/展示最小定制路径:

QList<MAV_AUTOPILOT> CustomFirmwarePluginFactory::supportedFirmwareTypes() const { list.append(MAV_AUTOPILOT_PX4);

继承PX4FirmwarePlugin/PX4AutoPilotPlugin,Override 飞行模式、任务命令、Setup 组件列表,无需 fork 整个 QGC。

7.2.8 新增机型适配检查清单

层次修改位置说明
USB 识别USBBoardInfo.jsonVID/PID → 板名
烧录Bootloader.hboard ID + Firmware Hash固件 URL
协议XxxFirmwarePlugin飞行模式、GUIDED、任务
SetupVehicleComponent+ QML校准/配置 UI
参数PX4/APM Parameter XML名称/单位/枚举
机架Airframe XMLSYS_AUTOSTART
任务MavCmdInfo*.json航线命令 UI
连接LinkManager自动连接规则

7.3 不同飞控协议兼容改造

QGC 4.0 核心 MAVLink 处理保持栈无关;协议差异通过 FirmwarePlugin 钩子消化

7.3.1 插件选择与 Fallback

FirmwarePlugin* FirmwarePluginManager::firmwarePluginForAutopilot(MAV_AUTOPILOT firmwareType, MAV_TYPE vehicleType) { FirmwarePluginFactory* factory = _findPluginFactory(firmwareType); if (factory) { plugin = factory->firmwarePluginForAutopilot(firmwareType, vehicleType); } if (!plugin) { if (!_genericFirmwarePlugin) { _genericFirmwarePlugin = new FirmwarePlugin; } plugin = _genericFirmwarePlugin; } return plugin; }

未知 Autopilot 回退Generic FirmwarePlugin,提供基础 MAVLink 能力,无 PX4/APM 特有 Guided 等功能。

7.3.2 MAVLink 消息适配钩子

Vehicle 收消息前:

if (!_firmwarePlugin->adjustIncomingMavlinkMessage(this, &message)) {

返回false丢弃该消息(用于过滤重复 STATUSTEXT 等)。

Vehicle 发消息前:

_firmwarePlugin->adjustOutgoingMavlinkMessage(this, link, &message);

APM 入站适配(典型):

bool APMFirmwarePlugin::adjustIncomingMavlinkMessage(Vehicle* vehicle, mavlink_message_t* message) { if (message->msgid == MAVLINK_MSG_ID_HEARTBEAT) { _handleIncomingHeartbeat(vehicle, message); return true; } if (_ardupilotComponentMap[vehicle->id()][message->compid]) { switch (message->msgid) { case MAVLINK_MSG_ID_PARAM_VALUE: _handleIncomingParamValue(vehicle, message); break; case MAVLINK_MSG_ID_STATUSTEXT: return _handleIncomingStatusText(vehicle, message, false); ... } } return true; }

APM 兼容要点:

  1. 组件识别:通过 HEARTBEAT 的autopilot字段维护_ardupilotComponentMap,仅对 ArduPilot 组件做方言转换
  2. STATUSTEXT 严重级别:旧版 APM 使用非标准 severity 编码,_adjustSeverity()映射到 MAV_SEVERITY 标准值
  3. PARAM_VALUE:参数名可能带@后缀或索引差异,_handleIncomingParamValue规范化
  4. RC_CHANNELS vs RC_CHANNELS_RAW:合并处理不同版本消息
  5. 出站 PARAM_SET_handleOutgoingParamSet处理 APM 参数名/类型差异

PX4 入站适配:

bool PX4FirmwarePlugin::adjustIncomingMavlinkMessage(Vehicle* vehicle, mavlink_message_t* message) { if (message->compid == MAV_COMP_ID_UDP_BRIDGE) { return true; } switch (message->msgid) { case MAVLINK_MSG_ID_AUTOPILOT_VERSION: _handleAutopilotVersion(vehicle, message); break; } return true; }

主要处理版本过低警告、AUTOPILOT_VERSION解析;PX4 较贴近标准 MAVLink,适配量小于 APM。

7.3.3 飞行模式映射

各栈实现flightMode(base_mode, custom_mode)setFlightMode(name, &base, &custom)

APM Copter使用APMCopterMode枚举 +APMCustomMode映射表:

setEnumToStringMapping({ { STABILIZE, "Stabilize"}, { ACRO, "Acro"}, { GUIDED, "Guided"}, { LOITER, "Loiter"}, { RTL, "RTL"}, ... });

PX4使用union px4_custom_mode位域解析custom_mode,支持MAIN_MODE/SUB_MODE

Fly 视图下拉列表来自FirmwarePlugin::flightModes(vehicle),各子类按固件能力返回不同列表。

7.3.4 能力位(Capabilities)

typedef enum { SetFlightModeCapability = 1 << 0, PauseVehicleCapability = 1 << 1, GuidedModeCapability = 1 << 2, OrbitModeCapability = 1 << 3, TakeoffVehicleCapability = 1 << 4, ROIModeCapability = 1 << 5, } FirmwareCapabilities;

UI 与 Joystick 通过isCapable(vehicle, GuidedModeCapability)决定是否显示 Guided Takeoff、Orbit 等按钮,避免对不支持栈发送无效命令。

7.3.5 参数名版本 remap(APM 重点)

APM 跨版本常重命名参数。FirmwarePlugin定义三层 Map:

typedef QMap<QString, QString> remapParamNameMap_t; typedef QMap<int, remapParamNameMap_t> remapParamNameMinorVersionRemapMap_t; typedef QMap<int, remapParamNameMinorVersionRemapMap_t> remapParamNameMajorVersionMap_t;

ArduCopterFirmwarePlugin::paramNameRemapMajorVersionMap()在静态初始化中填充,如 3.5 版本"CHUKE_" → "CHUTE_"类映射。ParameterManager请求参数前查表转换,保证 QGC 内部统一使用新名称。

7.3.6 任务命令树(MissionCommandTree)

任务编辑器命令列表按MAV_AUTOPILOT × MAV_TYPE二维索引:

for (MAV_AUTOPILOT firmwareType: _toolbox->firmwarePluginManager()->supportedFirmwareTypes()) { FirmwarePlugin* plugin = ...->firmwarePluginForAutopilot(firmwareType, MAV_TYPE_QUADROTOR); for(MAV_TYPE vehicleType: vehicleTypes) { QString overrideFile = plugin->missionCommandOverrides(vehicleType); if (!overrideFile.isEmpty()) { _staticCommandTree[firmwareType][vehicleType] = new MissionCommandList(overrideFile, ...); } } }

各 Plugin 返回 JSON 路径如:/json/MavCmdInfoMultiRotor.json,定义命令显示名、参数 Fact 元数据、是否支持。
新增协议命令 UI:在对应MavCmdInfo*.json增加条目,或在 Custom Plugin 中 overridemissionCommandOverrides()

7.3.7 地理围栏 / Rally / Follow Me

  • GeoFenceManager/RallyPointManager:基类 MAVLink 通用,Plugin 提供supported()与格式差异
  • FollowMe:PX4 支持Follow Me模式字符串;APM 部分版本通过 Plugin 扩展

7.3.8 编译期协议裁剪

#if !defined(NO_ARDUPILOT_DIALECT) _downloadArduPilotManifest(); #endif

NO_ARDUPILOT_DIALECT宏可构建纯 PX4 版本,移除 APM manifest、APM 固件 URL 等,减小体积。

7.3.9 协议兼容改造实践指南

场景推荐改造点
新 MAVLink 消息字段与标准不符adjustIncomingMavlinkMessage解码后重写
发送命令被拒adjustOutgoingMavlinkMessage或 Plugin 专用 send 方法
新飞行模式子类flightModes+setFlightMode+ custom_mode 位定义
参数 renameparamNameRemapMajorVersionMap
新任务命令MavCmdInfo*.json+ MissionController 验证逻辑
完全新飞控栈新建XxxFirmwarePluginFactory+XxxAutoPilotPlugin+ 全局静态 Factory 实例
仅改品牌/隐藏 APMCustomQGCCorePlugin+CustomFirmwarePlugin继承 PX4

7.4 FirmwareUpgradeSettings 配置

Fact作用
apmChibiOS优先 ChibiOS vs NuttX 固件路径
apmVehicleType默认 APM 机型过滤(Copter/Plane/Rover/Sub)

变更时触发_buildAPMFirmwareNames()刷新 manifest 匹配列表。


7.5 关键类方法速查

方法作用
FirmwareUpgradeControllerstartBoardSearch()/flash()UI 入口
FirmwareUpgradeController_initFirmwareHash()PX4 URL 表
FirmwareUpgradeController_downloadArduPilotManifest()APM 动态固件
PX4FirmwareUpgradeThreadWorker_findBootloader()同步 Bootloader
PX4FirmwareUpgradeThreadWorker_flash()擦写校验
Bootloadersync/erase/program/verify协议实现
FirmwareImageload()/isCompatible()镜像解析
QGCSerialPortInfocanFlash()/getBoardInfo()USB 识别
FirmwarePluginManagerfirmwarePluginForAutopilot()运行时选栈
FirmwarePluginadjustIncomingMavlinkMessage()协议适配
AutoPilotPluginvehicleComponents()Setup 组件
VehicleComponentsetupComplete()校准完成判定
MissionCommandTreegetMissionCommands()任务命令 UI

7.6 本章小结

QGroundControl 4.0 的固件升级子系统采用Controller + Worker Thread + Bootloader 协议三层架构,通过 USB VID/PID(USBBoardInfo.json)识别 Pixhawk/PX4Flow/SiK 设备,经 PX4 Bootloader 二进制协议完成擦除、分块编程与 CRC/回读校验。固件来源包括 PX4 S3 静态表、GitHub Releases、ArduPilotmanifest.json动态清单;.px4/.apj包同时携带参数与机架元数据,烧录后即可更新 Setup 界面。

机型与外设适配依托FirmwarePluginFactory → FirmwarePlugin → AutoPilotPlugin → VehicleComponent插件链,参数/display 由 Fact 系统 + Parameter XML 驱动,传感器校准/机架选择通过 QML Setup 面板与 MAVLink 命令完成。新增硬件通常需同步修改 JSON 板型表、Parameter/Airframe 元数据及对应 Component。

协议兼容遵循「Vehicle 通用、Plugin 消化差异」原则,APM 侧通过 heartbeat 组件映射、STATUSTEXT 严重级别修正、参数 remap 等机制对齐 MAVLink 标准;PX4 侧适配较轻。任务命令、飞行模式、Guided 能力均通过 Plugin 虚函数与 JSON 配置扩展,Custom 示例提供了不修改主干的定制路径。

http://www.jsqmd.com/news/894551/

相关文章:

  • AI编程助手延迟优化:提升开发者心流与代码质量的智能交互设计
  • 【最新v2.7.5 版本安装包】零代码搭建智能助手,OpenClaw 零基础无需命令快速部署教程
  • 别再只读数据了!深入解析DHT11和MQ2的底层通信协议与51单片机精准驱动(附示波器波形分析)
  • 深入理解AURIX TC3xx中断路由(IR):对比ARM Cortex-M,聊聊SRN和ICU的设计哲学
  • 避坑指南:在VMware虚拟机Ubuntu22.04上搞定CH340串口驱动,连接ROS2机械臂
  • Java开发高手秘籍:性能优化与调试技巧全解析
  • 光电融合ViT加速:硅光子技术突破视觉Transformer瓶颈
  • 保姆级教程:用Docker Compose一键部署MinIO,并搞定初始密码设置
  • ClaudeOps:AI大模型如何革新运维工作流与自动化实践
  • Unity背包系统性能优化实战:告别ScriptableObject的暴力刷新,用事件驱动重构你的物品管理
  • ARMv8/v9调试寄存器OSDTRRX_EL1与OSDTRTX_EL1详解
  • 领域定制AI聊天机器人:基于RAG架构的构建实战与核心模块解析
  • 别再只用巴特沃斯了!用MATLAB的cheby1函数快速搞定带通滤波器设计(附完整代码)
  • 别再被AT指令搞懵了!手把手教你用串口助手搞定HC05蓝牙主从配对(附常见错误排查)
  • 基于阻抗谱与神经网络的无线充电系统参数实时估计方法
  • 2026年评价高的智能工厂生产/智能工厂执行用户好评推荐 - 品牌宣传支持者
  • OpenPCDet训练中断了怎么办?详解ckpt机制、eval配置与恢复训练的正确姿势
  • 保姆级教程:用Android Studio调试Camera HAL3接口,快速定位图像流配置问题
  • TDAL算法:基于信任度的动态主动学习如何将众包标注成本降低90%
  • 为内部工具集成 AI 能力时如何通过统一 API 网关简化运维
  • 手把手教你用Arduino UNO和NEO-7M GPS模块制作一个简易定位追踪器
  • 搞GIS开发必知:1985国家高程基准与常见DEM数据(ASTER、SRTM)的基准面转换避坑指南
  • 用Python复现FAST天眼反射面调节模型:从数学建模到代码实现(附完整源码)
  • 基于Groq与Streamlit构建语音控制AI智能体:从原理到实践
  • 优化工具箱之外:当Gurobi遇到NP-Hard难题时,试试SCA这个‘平替’方案
  • 2026年质量好的台州日化瓶盖模具/食用油瓶盖模具/五加仑瓶盖模具/矿泉水瓶盖模具用户口碑推荐厂家 - 品牌宣传支持者
  • SPSS语法(.sps)才是效率神器!告别重复点击,一键批量处理100份数据的自动化技巧
  • 频谱分析仪 UI 自定义绘制
  • 2026年比较好的厂区数字化孪生/厂区BIM三维规划/厂区仓储规划哪家好 - 行业平台推荐
  • OTAIP:用确定性智能体架构破解垂直领域AI应用难题