APM飞控电压显示异常?手把手教你修改QGC源码,从SYS_STATUS帧里挖出电压值

张开发
2026/4/6 13:29:38 15 分钟阅读

分享文章

APM飞控电压显示异常?手把手教你修改QGC源码,从SYS_STATUS帧里挖出电压值
APM飞控电压显示异常从SYS_STATUS帧提取电压值的实战指南当你盯着QGroundControl地面站界面却发现APM飞控的电压读数始终显示为0——这种场景对无人机开发者来说再熟悉不过。不同于PX4飞控直接提供电池组数据APM的电压信息隐藏在系统状态帧中需要开发者主动挖掘。本文将带你深入MAVLink协议层通过修改QGC源码实现电压数据的可视化。1. 理解APM与PX4的电压数据差异在MAVLink协议中电池状态通常通过两种消息帧传递BATTERY_STATUS帧PX4飞控的标准数据源包含电压、电流、剩余电量等完整电池信息SYS_STATUS帧APM飞控存放核心系统状态其中voltage_battery字段携带实际电压值关键区别在于数据封装方式特性PX4APM数据源BATTERY_STATUSSYS_STATUS电压字段voltages[0]voltage_battery单位毫伏毫伏是否需要转换否需要除以1000// APM电压值转换示例 double voltage static_castdouble(sysStatus.voltage_battery)/1000;2. 修改Vehicle类添加自定义Fact参数QGroundControl通过Fact系统管理飞控参数我们需要在Vehicle类中新增电压参数2.1 Vehicle.h头文件修改在声明部分添加以下内容// 声明自定义Fact参数 Q_PROPERTY(Fact* myVoltage READ myVoltage CONSTANT) // 类成员函数 Fact* myVoltage() { return _myVoltageFact; } // 私有成员变量 Fact _myVoltageFact; static const char* _myVoltageFactName;2.2 Vehicle.cpp实现修改关键修改点包括静态成员初始化const char* Vehicle::_myVoltageFactName myVoltage;构造函数初始化_myVoltageFact(0, _myVoltageFactName, FactMetaData::valueTypeDouble)注册Fact参数_addFact(_myVoltageFact, _myVoltageFactName);在_handleSysStatus消息处理函数中更新值double voltage static_castdouble(sysStatus.voltage_battery)/1000; _myVoltageFact.setRawValue(voltage);提示所有数值操作建议放在try-catch块中避免异常数据导致程序崩溃3. 创建参数元数据描述文件在QGC的资源文件中添加JSON描述定义参数的显示特性{ name: myVoltage, shortDesc: Current voltage, type: double, decimalPlaces: 2, units: v }这个配置文件决定了参数在UI中的显示格式保留2位小数单位显示为V参数描述为Current voltage4. 实现前端可视化组件创建VoltageTest.qml自定义组件显示电压值Rectangle { id: valuesRoot width: rowRoot.width 10 height: rowRoot.height 10 color: black property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle ? QGroundControl.multiVehicleManager.activeVehicle : QGroundControl.multiVehicleManager.offlineEditingVehicle property var voltageVal: _activeVehicle ? _activeVehicle.voltage0 : 0 property var voltageMax: 4.2 * 6 //6s电池 property var voltageMin: 3.7 * 6 //6s电池 Row { id: rowRoot anchors.centerIn: parent spacing: 5 property Fact fact: _activeVehicle.getFact(myVoltage); Column { spacing: 0 anchors.verticalCenter: parent.verticalCenter QGCLabel { id: sgLabel color: getModelColor(rowRoot.fact.enumOrValueString) text: qsTr(电压) font.pointSize: 12 font.bold: true } QGCLabel { text: rowRoot.fact.valueEqualsDefault ? : rowRoot.fact.value.toFixed(1) rowRoot.fact.units font.pointSize: 12 font.bold: true } } } }关键功能实现动态颜色变化绿/黄/红反映电压状态定时器每1秒刷新显示支持离线编辑模式预览5. 工程配置与集成测试最后需要将新组件集成到QGC工程中在qgroundcontrol.qrc资源文件中注册QML组件file aliasQGroundControl/FlightDisplay/VoltageTest.qml src/FlightDisplay/VoltageTest.qml /file在qmldir中声明组件版本VoltageTest 1.0 VoltageTest.qml在主界面FlyViewWidgetLayer.qml中调用组件VoltageTest { anchors.top: parent.top anchors.topMargin: 50 anchors.horizontalCenter: parent.horizontalCenter }测试时注意检查数据刷新频率是否正常单位换算是否正确极端值情况下的显示处理多飞控切换时的参数同步6. 进阶PX4飞控的适配方案虽然PX4默认提供电池组数据但有时也需要直接从系统状态获取电压。实现方式略有不同// Vehicle类中添加定时器 connect(_upVoltageTimer, QTimer::timeout, this, Vehicle::getVoltage0); _upVoltageTimer.start(1000); bool Vehicle::getVoltage0(void) { if(_batteryFactGroupListModel.count() 1) { return false; } auto batteriesList batteries(); auto groop batteriesList-valueVehicleBatteryFactGroup*(0); _voltage0 groop-voltage()-enumOrValueString(); emit voltage0Changed(_voltage0); return true; }前端调用方式与APM方案保持一致保证了代码的统一性。在实际项目中建议封装一个兼容两种飞控的电压获取接口根据飞控类型自动选择数据源。

更多文章