QGC地面站手把手教你改——如何添加跟随面板显示关键参数


所有的热爱都要不遗余力,真正喜欢它便给它更高的优先级,和更多的时间吧!

关于QGC地面站其它文章请点击这里:     QGC地面站


QGroundControl(QGC)是一款开源的跨平台地面站软件,用于控制和监控各种类型的无人机、无人船、无人车等载具。它提供了丰富的功能,包括飞行计划、实时地图、传感器数据显示、飞行状态监测、遥控器控制、实时视频显示等,可以支持多种硬件设备和自定义设置。

一. 要实现的目标

当无人机在地图上飞行时,实现飞机图标实时跟随一个参数小面板,让用户对关键信息一目了然。 此参数小面板设置为半透明,可实时跟随飞机图标移动,显示内容包括电池剩余百分比、电池电压、飞行模式、地速、空速、爬升速度、相对高度、飞行距离等关键参数。如下gif:

在这里插入图片描述

二. 代码分析与修改

1. 飞行地图文件的分析与修改

代码如下:(FlightDisplayViewMap.qml):

// Add the vehicles to the map  244行
MapItemView {  											//标记1
    model: QGroundControl.multiVehicleManager.vehicles  //标记2
    delegate: VehicleMapItem { 							//标记3
        vehicle:        		object
        coordinate:     		object.coordinate 		//标记4
        map:            		flightMap
		size:           		mainIsMap ? ScreenTools.defaultFontPixelHeight * 3 : ScreenTools.defaultFontPixelHeight
        //z:              QGroundControl.zOrderVehicles  //总修改1-1
    }
    z:              QGroundControl.zOrderTopMost         //总修改1-2
}

参考:QT Creator 帮助中搜 “MapItemView”,MapQuickItem

● 标记1:MapItemView是用来构成Map的一部分的。它数据主要是源自model(ListModel、RouteModel等)。和ListView 相似 ,也是mode-delegate模型。 仅仅不同于MapItemView的代理Delegate需要为地图控件,即位置设置为经纬度坐标。ListView的Delegate控件为桌面控件,位置设置为屏幕位置。 MapItemView类型只有在包含在Map中时才有意义,它不能独立存在。

● 标记2:model:提供数据给委托定义的mapItem(VehicleMapItem),由它提供的信息(飞行模式、地速、空速、爬升速度、相对高度、飞行距离)作为Map ItemView的输入,下面再具体讲解。记住model 仅支持 “QAbstractItemModel” 的基础模型。

显然 “QGroundControl.multiVehicleManager.vehicles” 是 QAbstractItemModel 类型的,如下:

// src\Vehicle\MultiVehicleManager.h:100
QmlObjectListModel* vehicles(void) { return &_vehicles; }

● 标记3:delegate:定义了模型中的每个项改如何显示。 要求 delegate 必须为组件,且包含一个map Item, “MapQuickItem”类型的居多。

● 标记4:coordinate:定位坐标。为什么能动态跟随,此为最关键的属性,它在C++ vehiclel 类中会实时更新。(NOTIFY修饰的属性,下文会讲到)

coordinate是“MapQuickItem”的一个属性。 此属性保存MapQuickItem的锚点坐标。在地图显示时,由anchorPoint指定的sourceItem上的点与此坐标保持会一致。

在此MapItemView中。object 对应的就是 vehicles ,委托了VehicleMapItem来实现,VehicleMapItem为MapQuickItem类型的。MapQuickItem的sourceItem指定了一个Item来如何显示。该Item就是9行3列的关键参数的显示信息。

● 修改1: 此文件中仅修改一处“z” 属性,是为了让面板在顶层显示。记得放在“MapItemView”的属性下,不然不会生效,这很关键

接下来让我再看看代理中的文件吧!

2. 代理文件中数据源

上文提到 model,由它提供的飞行模式、地速、空速、爬升速度、相对高度、飞行距离的。

flightMode、roll、groundSpeed都是在“VehicleMapItem”中定义的变量。 object.flightMode、object.roll.rawValue、 object.groundSpeed.rawValue来自于“vehicles”。那么再看下 C++中的Vehicle吧

● 修改2: 在文件头增加如下属性:

//总修改2: (object = vehicle = QGroundControl.multiVehicleManager.vehicles)
property string flightMode:           vehicle.flightMode;
property real   roll:                 vehicle.roll.rawValue;
property real   groundSpeed:          vehicle.groundSpeed.rawValue;
property real   airSpeed:             vehicle.airSpeed.rawValue;
property real   climbRate:            vehicle.climbRate.rawValue;
property real   altitudeRelative:     vehicle.altitudeRelative.rawValue;
property real   flightDistance:       vehicle.flightDistance.rawValue;
property real   distanceToHome:       object.distanceToHome.rawValue;
property real   batteryPercentRemain: object.battery.percentRemaining.value
property real   batteryVoltage:       object.battery.voltage.value;

object = vehicle = QGroundControl.multiVehicleManager.vehicles ,让我们在看看vehicle类…

● C++中的Vehicle类的分析。
要在QML实时显示,那么必须是“NOTIFY”修饰的信号,它给属性关联一个信号,当属性的值发生变化时就会触发该信号。比下flightMode属性,

  Q_PROPERTY(QString              flightMode              READ flightMode             WRITE setFlightMode             NOTIFY flightModeChanged)

C++和QML之间不懂如何交互的可以点击这里:Qt Quick Qml 之QML与C++ 混合编程学习

当我们在 C++中改变该参数值时,发射 flightModeChanged 信号, 来通知 qml 相关的属性有更改,进而实现相关的状态更改。没有“NOTIFY”修饰的,不会实时触发,也不会动态更新了。

但是是不是发现在Vehicle类中,一些关键的属性并没有使用NOTIFY ?

如下:

Fact* roll                              () { return &_rollFact; }
Fact* rollRate                          () { return &_rollRateFact; }
Fact* pitchRate                         () { return &_pitchRateFact; }
Fact* yawRate                           () { return &_yawRateFact; }
Fact* airSpeed                          () { return &_airSpeedFact; }
Fact* groundSpeed                       () { return &_groundSpeedFact; }
Fact* climbRate                         () { return &_climbRateFact; }

仔细分析Fact类:

class Fact : public QObject
{
    Q_OBJECT
...
    Q_PROPERTY(QString      shortDescription        READ shortDescription                                   CONSTANT)
    Q_PROPERTY(QString      units                   READ cookedUnits                                        CONSTANT)
    Q_PROPERTY(QVariant     value                   READ cookedValue            WRITE setCookedValue        NOTIFY valueChanged)
    Q_PROPERTY(QVariant     rawValue                READ rawValue               WRITE setRawValue           NOTIFY rawValueChanged)
}

发现“rawValue ”也用“NOTIFY”修饰了。所以问题就很简单了,直接去到 “rawValue” 就好

...
property string flightMode:           vehicle.flightMode;
property real   roll:                 vehicle.roll.rawValue;
property real   groundSpeed:          vehicle.groundSpeed.rawValue;
property real   airSpeed:             vehicle.airSpeed.rawValue;
property real   climbRate:            vehicle.climbRate.rawValue;
...

3. 代理文件中显示形式

● 修改3: 在MapQuickItem中的“ sourceItem: Item "中最后增加矩形框:

Rectangle {
    id:                         cchVehicleStatusView;
    anchors.bottom:             vehicleIcon.top;
    anchors.bottomMargin:  4
    anchors.horizontalCenter:   vehicleIcon.horizontalCenter;
    color:                      "#DDDDFF"
    radius:                     10
    width:                      buttonColumn.implicitWidth * 1.1
    height:                     buttonColumn.implicitHeight * 1.1
    opacity :                   0.8;
    border.color:               "black"
    border.width:               2

    Column {
        id:                 buttonColumn
        width:              statusNameRepeater.implicitWidth
        height:             statusNameRepeater.implicitHeight
        anchors.top:        parent.top
        anchors.topMargin:  6
        anchors.left:       parent.left
        anchors.leftMargin: 6
        spacing:            ScreenTools.defaultFontPixelHeight / 2

        Repeater {
            id:     statusNameRepeater
            model:  9
            property var statusNames:  [ "电池剩余百分比: ", "电池电压: ", qsTr("飞行模式:"), qsTr("地速: "), qsTr("空速: "), qsTr("爬升速度: "), qsTr("相对高度: "), qsTr("飞行距离: "),"到home点距离: "]
            property var statusValues: [batteryPercentRemain, batteryVoltage, flightMode, groundSpeed.toFixed(2), airSpeed.toFixed(2), climbRate.toFixed(2), altitudeRelative.toFixed(2), flightDistance.toFixed(2), distanceToHome.toFixed(2)]
            property var statusUnits: ["%", "v", "", "(m/s)", "(m/s)", "(m/s)", "(m)", "(m)", "(m)"]

            Row{
                id: _row
                QGCLabel {
                    color:                            "#424200"
                    horizontalAlignment:              Text.AlignHCenter
                    font.pointSize:                   ScreenTools.mediumFontPointSize * 1.0
                    text:                             statusNameRepeater.statusNames[index]
                    font.bold:                        true
                }
                QGCLabel {
                    color:                            "#336666"
                    horizontalAlignment:              Text.AlignHCenter
                    font.pointSize:                   ScreenTools.mediumFontPointSize *1.0
                    text:                             statusNameRepeater.statusValues[index] + statusNameRepeater.statusUnits[index]
                    font.bold:                        true
                }
            }
        }
    }
}

这个Column和Row的嵌套布局的详细解释,可以看我的 QT Quick QML 布局——定位置布局(Row、Column、Grid、Flow和Repeater) 总结。 这里不再介绍。

如下绿色框中:
在这里插入图片描述

有其他想法的,可以在飞行视图中,增加一个控件,来配置矩形框是否显示;还可以增加一个定时器让变化的数据高亮显示;有UI美工支持的还可以弄个炫酷的皮肤。


关于QGC地面站其它文章请点击这里:     QGC地面站

  • 50
    点赞
  • 115
    收藏
    觉得还不错? 一键收藏
  • 32
    评论
QGC地面站QGroundControl)是用于控制和监控无人机系统的开源地面站软件。它提供了用户界面,用户可以使用该界面与无人机进行通信,发送指令和接收数据。对于想要学习和了解QGC地面站的人来说,以下是一些学习资料建议。 首先,可以通过访问QGC官方网站(https://docs.qgroundcontrol.com/)来获取官方的学习资料。该网站提供了QGC地面站的全部文档,包括用户手册、操作指南、程和开发者文档等。这些文档详细介绍了QGC地面站的各种功能和使用方法,对于初学者来说是很好的学习资料。 其次,QGC地面站的开源性质使得有很多社区和论坛可以参考和学习。比如,可以加入QGC地面站的官方论坛(https://discuss.px4.io/c/qgc)或者无人机开发社区,与其他开发者和用户交流经验和问题。在这些社区中,你可以找到很多有关QGC地面站的讨论和指导,还可以提出自己的问题和疑问。 此外,还可以寻找一些在线程和视频资源,例如在YouTube上搜索“QGC地面站程”等关键词,会有很多开发者分享的学习视频。在这些视频中,你可以看到具体的操作步骤和实例演示,更好地理解和掌握QGC地面站的使用方法。 最后,建议尝试实际操作QGC地面站无人机连接和控制。实践是学习的最佳方式,只有亲自操作才能更好地理解和掌握软件的功能。可以尝试模拟连接无人机、发送指令、查看数据等操作,进一步加深对QGC地面站的理解。 综上所述,通过官方文档、社区交流、在线程和实践操作等多种途径,可以全面了解和学习QGC地面站的使用方法和功能。有了这些学习资料的支持,相信你能够更好地掌握和应用QGC地面站

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 32
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值