基于QGC3.3.0(翻译的很烂)
本指南解释了QGroundControl(QGC)如何在内部工作,并提供了为项目贡献代码的指导原则。它旨在供开发人员使用!
支持
本开发人员指南最终将成为有关QGroundControl开发信息的主要提供者。如果您发现它缺少有用信息或者有错误的信息,请提出问题。
开发问题可以在QGroundControl Developer里讨论或者通过QGroundControlGitter Gitter的方式。
设计理念
QGC提供了一套单一的代码库,可以在多个系统平台以及不同尺寸和样式的设备上运行。
QGC用户界面使用Qt QML实现。QML提供硬件加速功能,这是平板电脑或手机等低功耗设备的主要特征。QML还提供了一些功能,使我们能够更轻松地创建单一用户界面,从而适应不同的屏幕尺寸和分辨率。
+
QGC用户界面的目标更多的是平板电脑+触摸式UI,而不是基于桌面鼠标的用户界面。这使得单一的用户界面更容易创建,因为平板电脑风格的用户界面也可以在桌面/笔记本电脑上正常工作。
通信流
设备自动连接期间发生的高层通信流的描述。
HEARTBEAT,则通知
MultiVehicleManagerHEARTBEAT通知到MultiVehicleManager 后,
会根据HEARTBEAT
消息中的信息创建一个新的Vehicle
固件插件
尽管MAVLink规范定义了与Vehicle进行通信的标准通信协议。该规范有很多方面可供固件开发人员解释。因此,有很多情况下,与运行一个固件的Vehicle的通信必须与运行不同固件的Vehicle的通信略有不同,以完成相同的任务。每个固件也可以实现MAVLink命令集的子集。
另一个主要问题是MAVLink规范不包括Vehicle配置或通用参数集。由于这个与Vehicle配置有关的所有代码最终都是固件特定的。另外,任何必须引用特定参数的代码也是固件特定的。
鉴于固件实现之间的所有这些差异,创建一个单一的地面站应用程序可能非常困难,该应用程序可以支持每个应用程序,而无需将代码库降级为基于Vehicle固件使用的固件随处可见的大量if / then / else语句。
QGC使用插件架构将固件特定代码与所有固件通用的代码隔离开来。
类层次结构
QGC中的“链接”是与vehicle 的特定类型的通信管道,例如串口或WiFi上的UDP。所有链接的基类是LinkInterface。每个链接运行在它自己的线程上并发送字节到MAVLinkProtocol。
该LinkManager
对象跟踪系统中所有打开的链接。LinkManager
还通过串口和UDP链接管理自动连接。
系统中只有一个MAVLinkProtocol
对象。它的任务是从一个链接获取传入的字节并将它们转换为MAVLink消息。MAVLink HEARTBEAT消息被发送到MultiVehicleManager
。所有MAVLink消息都被发送到与链路关联的vehicle。
系统中有一个MultiVehicleManager
对象。当它在以前没有看到的链接上收到HEARTBEAT时,它会创建一个Vehicle对象。`MultiVehicleManager
还可以跟踪系统中的所有vehicle,并处理从一辆活动的vehicle到另一个的切换,并正确处理正在移除的vehicle。
Vehicle
Vehicle对象是QGC代码通过其与物理设备通信的主接口。
注意:还有一个与每个Vehicle相关的UAS对象,这是一个弃用的类,正在慢慢地逐步淘汰,所有的功能都转移到Vehicle类。这里不应该添加新的代码。
FirmwarePlugin类被用作固件插件的基类。固件插件包含特定于固件的代码,这样Vehicle对象就是干净的,支持UI的单个标准接口。
FirmwarePluginManager是一个工厂类,它根据vehicle的MAV_AUTOPILOT / MAV_TYPE组合创建一个FirmwarePlugin实例。
QGC中UI设计的主要模式是用QML编写的UI页面,多次与用C ++编写的定制“控制器”进行通信。类似MVC的设计模式。
QML代码通过以下机制绑定到与系统相关的信息:
QGroundControl
提供访问活动Vehicle对象的全局对象注意:由于QGC中使用的QML的复杂性以及它依赖与C ++对象的通信来驱动ui,所以不可能使用Qt提供的QML Designer来编辑QML。
多设备设计模式
QGroundControl被设计用于使用鼠标和触摸在多种设备类型上运行,从台式机到笔记本电脑到平板电脑,再到小型手机大小的屏幕。以下是QGC如何做的说明及其背后的原理。
QGC开发用于解决此问题的设计模式基于快速开发新功能开发,并允许代码库由一个非常小的团队(假设1位开发人员为默认开发团队规模)进行测试和维护。实现这一目标的模式非常严格,因为不遵循它会导致更慢的开发时间和更低的质量。
支持这个1人开发团队的概念会导致一些艰难的决定,而不是每个人都会为此感到高兴。但它确实导致QGC在许多操作系统和外形因素上使用单个代码库进行发布。这是他们其他大多数其他地面站无法实现的。
你问的贡献者呢?QGC有相当数量的贡献者。他们难道不能帮助我们将事情从这个1人开发团队的概念中移除 是的,QGC有不少贡献者。但不幸的是,他们随着时间的推移而来。当他们离开时,他们提供的代码仍然必须保留。因此,您可以回到1人开发团队的概念,这个概念大部分是过去三年发展过程中的平均值。
QGC UI设计的优先目标是平板电脑,无论是从触摸角度还是屏幕尺寸角度考虑(例如10英寸Samsung Galaxy标签)。其他设备类型和尺寸可能会因此决定而牺牲一些视觉效果和/或可用性。基于优先级决定的当前订单是平板电脑,笔记本电脑,台式机,手机(任何小屏幕)。
在上面指定的情况下,此时较小的手机大小的屏幕是QGC的最低优先级。更多的重点放在使飞行视图更加实用的主动飞行级别显示上。设置和航迹规划等视图不太关注。这些具体的视图经过测试可以在小屏幕上实用,但使用起来可能很痛苦。
Qt Layout controls
QGC没有针对不同屏幕尺寸和/或形状因素的不同编码的UI。一般来说,它使用QML Layout功能来重排一组QML UI代码以适应不同的外观因素。在某些情况下,它在小屏幕尺寸上提供较少的细节以使其适合。但这是一个简单的可见性模式。
QGC内部是一个系统,用于管理系统内的所有单个数据。这个数据模型是他们连接到控件。
QGC UI是从一组可重用控件和UI元素开发而来的。这样,添加到可重用控件的任何新功能现在都可以在整个UI中使用。这些可重复使用的控件还连接到FactSystem Facts,然后自动提供适当的用户界面。
QGC有一套标准的字体和调色板,应该被所有用户界面使用。
import QGroundControl.Palette 1.0
import QGroundControl.ScreenTools 1.0
此项目公开QGC调色板。这个调色板有两个变种:明亮和黑暗。调色板适用于户外使用,黑色调色板适用于室内。通常,您不应该直接为UI指定颜色,您应该始终使用调色板中的颜色。如果您不遵循此规则,则您创建的用户界面将无法从明暗风格中更改。
地图调色板用于绘制地图的颜色。由于地图样式不同,特别是卫星和街道,您需要使用不同的颜色来清晰地绘制它们。卫星地图需要看到较浅的颜色,而街道地图需要较暗的颜色才能看到。该QGCMapPalette
项目为此提供了一组颜色,以及通过地图在浅色和深色之间切换的功能。
ScreenTools项目提供了可用于指定字体大小的值。它还提供屏幕大小和QGC是否在移动设备上运行的信息。
QGC为构建用户界面提供了一套基础控件。一般而言,它们倾向于Qt支持的基础QML控件之上的薄层,这与QGC调色板相关。
import QGroundControl.Controls 1.0
以下控件是标准Qt QML控件的QGC变体。它们提供与相应的Qt控件相同的功能,除了它们是使用QGC调色板绘制的。
这些自定义控件是QGC独有的,用于创建标准的UI元素。
Fact System
Fact System 提供了一组标准化和简化QGC用户界面创建的功能
Fact
fact表示系统内的单个值
FactMetaData
这FactMetaData
与每个fact都有关联。它提供了Fact的详细信息,以推动自动用户界面的生成和验证
Fact Controls
Fact Control是一个QML用户界面控件,它连接到一个Fact,并且FactMetaData
提供一个控件给用户修改/显示与Fact相关的值。
本节包含有关顶级视图代码的主题:配置,设置,计划和飞行。
MissionController
(C ++)进行通信以用于任务显示FlightDisplayViewMap
FlightDisplayViewVideo
本节包含有关QGroundControl使用/支持的文件格式的主题
# Onboard parameters for Vehicle 1
#
# # Vehicle-Id Component-Id Name Value Type
1 1 ACRO_LOCKING 0 2
1 1 ACRO_PITCH_RATE 180 4
1 1 ACRO_ROLL_RATE 180 4
1 1 ADSB_ENABLE 0 2
以上是带有四个参数的参数文件的示例。该文件可以包含所需的参数。
注释以#开头。
这个标题:# MAV ID COMPONENT ID PARAM NAME VALUE
描述了每一行的格式:
Vehicle-Id
vehicle IDComponent-Id
参数的组件IDName
参数名称Value
参数值Type
使用MAVLink MAV_PARAM_TYPE_*
枚举值的参数类型参数文件包含单个vehicle的参数。它可以包含该vehicle内多个组件的参数。
除非另有说明,否则单位为m.
{
"fileType": "Plan",
"version": 1
"groundStation": "QGroundControl",
"mission": {
"version": 2
"firmwareType": 12,
"vehicleType": 2,
"cruiseSpeed": 15,
"hoverSpeed": 5,
"plannedHomePosition": [
47.632939716176864,
-122.08905141,
40
],
"items": [
...
],
},
"geoFence": {
...
},
"rallyPoints": {
...
},
}
在上面,您可以看到计划文件的顶级格式。计划文件以JSON文件格式存储,并包含与飞行计划相关的任务,地理围栏和集会点。
键 | 描述 |
---|---|
文件类型 | 必须是“计划”。 |
版 | 该文件的版本。当前版本是1。 |
地面站 | 创建此文件的地面站的名称。 |
任务 | 与此飞行计划相关的任务。 |
栅栏 | (可选的) |
rallyPoints(集会) | (可选的) |
以下值是必需的:
键 | 描述 |
---|---|
版 | 任务对象的版本。当前版本是2。 |
firmwareType | 此任务创建的固件类型使用MAVLink MAV_AUTOPILOT枚举值。 |
飞机类型 | 此任务创建的车型使用MAVLink MAV_TYPE枚举值。 |
cruiseSpeed | |
hoverSpeed | |
项目 | 与任务相关的任务项目对象列表。 |
plannedHomePosition | 当您编辑任务时,您计划在地图上显示的主要位置。数组的值是纬度,经度和高度。 |
SimpleItem
一个简单的项目代表单个MAVLink MISSION_ITEM命令。
{
"autoContinue": true,
"command": 22,
"frame": 2,
"params": [
0,
0,
0,
0,
47.633127690000002,
-122.08867133,
50
],
"type": "SimpleItem"
},
在这些值SimpleItem
直接映射到在值MISSION_ITEM:
在这些值SimpleItem
直接映射到在值MISSION_ITEM:
键 | 描述 |
---|---|
AUTOCONTINUE | MISSION_ITEM.autoContinue |
命令 | MISSION_ITEM.command |
帧 | MISSION_ITEM.frame |
PARAMS | MISSION_ITEM.param1,2,3,4,X,Y,Z |
ComplexItem
一个复杂的项目是将多个MISSION_ITEMS作为单个实体处理的更高级别的封装。
{
"complexItemType": "survey",
"type": "ComplexItem",
"version": 3,
...
},
复杂的项目有两个与它们相关的附加值:
键 | 描述 |
---|---|
complexItemType | 指定复杂项目的类型。QGroundControl目前支持以下类型:survey,fwLandingPattern |
版 | 指定此复杂项目的版本。 |
由于DO_JUMP命令要求您指定要跳转到的序列号,并且任务文件格式不指定序列号,所以需要进行特殊处理。
首先,您必须为要跳转到的任务项目分配一个唯一标识符:
{
...
"doJumpId": 100
}
的doJumpId
可以是大于0的任何值,且必须唯一地识别目标DO_JUMP。
然后在实际的DO_JUMP任务项目中,您可以在MISSION_ITEM.param1值中引用此唯一ID:
{
...
"command": 177,
"params": [
100,
...
],
...
},
加载任务时,将确定并填写实际的DO_JUMP序列号。
调查在任务中的多边形区域上创建了一条飞行路线。
{
"camera": {
"focalLength": 16,
"groundResolution": 3,
"imageFrontalOverlap": 10,
"imageSideOverlap": 10,
"name": "Sony ILCE-QX1",
"orientationLandscape": true,
"resolutionHeight": 3632,
"resolutionWidth": 5456,
"sensorHeight": 15.4,
"sensorWidth": 23.199999999999999
},
"cameraTrigger": true,
"cameraTriggerDistance": 25,
"complexItemType": "survey",
"fixedValueIsAltitude": false,
"grid": {
"altitude": 50,
"angle": 0,
"relativeAltitude": true,
"spacing": 30,
"turnAroundDistance": 0
},
"manualGrid": true,
"polygon": [
[
47.633933816132817,
-122.08937942845
],
[
47.634139864633021,
-122.08781838280333
],
[
47.633395194285789,
-122.08872496945037
]
],
"type": "ComplexItem",
"version": 3
}
Survey被表示为存储在items
数组中的JSON对象。它存储与调查相关的所有元数据。它不存储调查中的各个航点。这些是在QGroundControl加载任务时生成的。
键 | 描述 |
---|---|
相机 | 指定与用于调查的相机关联的值的对象。仅在必要时manualGrid 为false 。 |
cameraTrigger | 指定是否应以指定的cameraTriggerDistance 时间间隔触发相机。 |
complexItemType | 将这个复杂的任务项目标识为一个survey 。 |
fixedValueIsAltitude | 指定在修改Survey用户界面的其他值时是否保持Altitude不变。仅供QGroundControl UI使用。 |
格 | 指定与测量网格关联的值的对象。 |
manualGrid | true :网格值由用户手动指定false :网格值基于camera 对象指定的相机设置。 |
多边形 | 表示多边形调查区域的多边形数组。每个点都是多边形顶点的纬度和经度对。 |
类型 | 指定这个项目是一个ComplexItem 。 |
版 | 调查复杂任务项目格式的版本号。当前版本是3。 |
该grid
对象指定与调查网格关联的值。
"grid": {
"altitude": 50,
"angle": 0,
"relativeAltitude": true,
"spacing": 30,
"turnAroundDistance": 0
},
键 | 描述 |
---|---|
高度 | 网格内所有横断面航点的高度。 |
角度 | 横断面路径的角度(度)。 |
relativeAltitude | true :altitude 是相对于家庭的,false :altitude 是AMSL |
间距 | 每个样线之间的间距。 |
turnAroundDistance | 在转向下一个横断面之前飞过多边形边的距离。 |
该camera
对象指定与用于调查的相机相关的值。该对象仅在manualGrid
is时是必需的false
。
"camera": {
"focalLength": 16,
"groundResolution": 3,
"imageFrontalOverlap": 10,
"imageSideOverlap": 10,
"name": "Sony ILCE-QX1",
"orientationLandscape": true,
"resolutionHeight": 3632,
"resolutionWidth": 5456,
"sensorHeight": 15.4,
"sensorWidth": 23.199999999999999
},
键 | 描述 |
---|---|
长焦点 | 相机镜头的焦距,单位为毫米。 |
groundResolution | 目标地面分辨率,单位为cm / px。 |
imageFrontalOverlap | 正面图像重叠的百分比。 |
imageSideOverlap | 侧面图像重叠的百分比。 |
名称 | 正在使用的照相机的名称。应该对应于QGroundControl已知的摄像头之一。使用"Custom Camera Grid" 自定义摄像头规格, |
orientationLandscape | true :照相机横向安装在车辆上,false :照相机以纵向方向安装在车辆上 |
resolutionHeight,resolutionWidth | 图像像素分辨率。 |
sensorHeight,sensorWidth | 传感器尺寸以毫米为单位。 |
{
"fileType": "RallyPoints",
"groundStation": "QGroundControl",
"points": [
[
47.634309760000001,
-122.08936869999999,
50
],
[
47.634244700000004,
-122.08700836,
50
],
[
47.632784270000002,
-122.08712101,
50
],
[
47.632769809999999,
-122.08939552,
50
]
],
"version": 1
}
{
"fileType": "GeoFence",
"groundStation": "QGroundControl",
"parameters": [
{
"compId": 1,
"name": "FENCE_ENABLE",
"value": 1
},
{
"compId": 1,
"name": "FENCE_TYPE",
"value": 4
},
{
"compId": 1,
"name": "FENCE_ACTION",
"value": 0
},
{
"compId": 1,
"name": "FENCE_ALT_MAX",
"value": 0
},
{
"compId": 1,
"name": "FENCE_RADIUS",
"value": 0
},
{
"compId": 1,
"name": "FENCE_MARGIN",
"value": 0
}
],
"polygon": [
[
47.634457973002796,
-122.08958864075316
],
[
47.634371216366716,
-122.08675086361541
],
[
47.632610748511105,
-122.08689033848418
],
[
47.632610748511105,
-122.08967983585967
]
],
"version": 1
}
QGroundControl允许您生成可重播的简单MAVLink数据包日志(使用QGroundControl)以再次观看任务以进行分析。
格式是二进制的:
要检查您的数据,请在十六进制编辑器中打开您的书面文件。你应该在8字节后看到0x55。前8个字节也应该转换为有效的时间戳,所以要么接近于零,要么围绕数字1294571828792000(这是当前Unix纪元时间戳,以微秒为单位)。
下面的代码片段显示了如何使用C ++标准库中的C ++流实现日志记录。
//write into mavlink logfile
const int len = MAVLINK_MAX_PACKET_LEN+sizeof(uint64_t);
uint8_t buf[len];
uint64_t time = getSystemTimeUsecs();
memcpy(buf, (void*)&time, sizeof(uint64_t));
mavlink_msg_to_send_buffer(buf+sizeof(uint64_t), msg);
mavlinkFile << buf << flush;
QGroundControl在调试版本中提供了许多工具。这些简化了常见的开发人员任务,包括设置用于测试的模拟连接以及通过MAVLink访问System Shell。
工具包括:
模拟链接允许您在QGroundControl调试版本中创建和停止多个模拟(模拟)vehicle的链接。
该模拟不支持飞行,但确实可以轻松测试:
它对于任务上传/下载的单元测试错误情况特别有用。
要使用模拟链接:
通过选择顶部工具栏中的应用程序设置图标访问模拟链接,然后选择边栏中的模拟链接:
使用模拟链接与使用任何其他vehicle差不多,除了模拟不允许飞行。
自定义命令的widget功能允许开发加载QML的UI在运行时(而不必重新生成QGroundControl或了解其内部结构)。一次可以加载一个小部件,在QGroundControl重新启动之间将被“记住” 。
开发人员可以使用QML语言的任何功能以及任何暴露于QML的vehiccle功能(包括许多有用的“标准vehicle信息”,但不是任意的MAVLink流量或自定义类型)。
该功能主要用于创建简单的UI以发送自定义命令和更改参数。
此功能仅在桌面版本(Windows,Linux,Mac OS)上受支持。虽然它出现在最终用户的构建中,但仅供开发人员使用。
加载一个小部件:
从任何屏幕打开菜单窗口小部件>自定义命令。
该自定义命令将显示选择对话框。
选择加载自定义Qml文件...,然后使用文件选择器找到用于小部件加载的QML文件(下图显示了示例小部件)
重新启动QGroundControl以激活小部件。
您可以按重置以删除当前的小部件或加载自定义Qml文件...以选择一个新的小部件。如果QML文件无效,您将收到警告,如下所示。
开发人员可以使用QML语言的任何特性。以下部分显示了解决主要(预期)用例的情况:
COMMAND_LONG
消息)即使按下重置(这些缓存),您也必须重新启动QGroundControl才能获取QML文件中的任何更改。
该QGCButton
控件由...提供QGroundControl.Controls
。它是标准QML Button
元素的包装,它使用默认的QGC字体和调色板。
该按钮连接到controller.sendCommand()
发送MAVLink COMMAND_LONG
消息的方法(在这种情况下,设置原始位置)。
QGCButton {
text: "Set Home to current position"
// Arguments to CustomCommandWidgetController::sendCommand (MAVLink COMMAND_LONG)
// command id
// component id
// confirmation
// param 1-7
onClicked: controller.sendCommand(179, 50, 0, 1, 0, 0, 0, 0, 0, 0)
}
该FactTextField
控件由Fact System(GroundControl.FactControls
)提供。它是QML TextField
元素的一个包装,它允许你直接绑定到任何参数。当您单击输入或单击字段时,参数会自动更改。
- 目前没有值验证。因此,您可能会通过将参数设置为不正确的值来使您的车辆坠毁。验证将在未来进行。
- 引用参数时要非常小心。如果您指定了一个不存在的参数,QGroundControl将发出警告并关闭。
FactTextField {
// The -1 signals default component id.
// You can replace it with a specific component id if you like
fact: controller.getParameterFact(-1, "MAV_SYS_ID")
}
下面的示例自定义命令窗口小部件QML文件结合了上一节中介绍的控件。
import QtQuick 2.2
import QGroundControl.Controls 1.0
import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.Palette 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Controllers 1.0
Rectangle {
anchors.fill: parent
color: qgcPal.window
CustomCommandWidgetController {
id: controller
factPanel: panel
}
QGCPalette { id: qgcPal; colorGroupEnabled: enabled }
Column {
spacing: ScreenTools.defaultFontPixelHeight
QGCButton {
text: "Set Home to current position"
// Arguments to CustomCommandWidgetController::sendCommand (MAVLink COMMAND_LONG)
// command id
// component id
// confirmation
// param 1-7
onClicked: controller.sendCommand(179, 50, 0, 1, 0, 0, 0, 0, 0, 0)
}
// The FactTextField control is bound to the specified parameter. Note that there is no validation.
FactTextField {
// The -1 signals default component id.
// You can replace it with a specific component id if you like
fact: controller.getParameterFact(-1, "MAV_SYS_ID")
}
}
}
您可以使用命令行选项启动QGroundControl。这些用于启用日志记录,运行单元测试以及模拟不同的主机环境进行测试。
您需要打开命令提示符或终端,将目录更改为qgroundcontrol.exe的存储位置,然后运行它。下面显示了每个平台(使用该--logging:full
选项):
Windows命令提示符:
cd "\Program Files (x86)\qgroundcontrol"
qgroundcontrol --logging:full
OSX终端应用程序(应用程序/实用程序):
cd /Applications/qgroundcontrol.app/Contents/MacOS/
./qgroundcontrol --logging:full
Linux终端:
./qgroundcontrol-start.sh --logging:full
下表列出了选项/命令行参数。
选项 | 描述 |
---|---|
--clear-settings |
清除应用程序设置(将QGroundControl恢复为默认设置)。 |
--logging:full |
打开完整日志记录。请参阅控制台记录。 |
--logging:full,LinkManagerVerboseLog,ParameterLoaderLog |
打开完整日志记录并关闭以下列出的以逗号分隔的日志记录选项。 |
--logging:LinkManagerLog,ParameterLoaderLog |
打开指定的逗号分隔记录选项 |
--unittest:name |
(仅限Debug版本)运行指定的单元测试。离开:name 去运行所有测试。 |
--unittest-stress:name |
(仅限Debug版本)连续运行指定的单元测试20次。离开:姓名以运行所有测试。 |
--fake-mobile |
模拟在移动设备上运行。 |
--test-high-dpi |
模拟在高DPI设备上运行QGroundControl。 |
笔记:
+
本节包含有关贡献代码的主题,包括编码风格,测试和请求格式。
QGroundControl(QGC)作为Apache 2.0和GPLv3双重许可。所有捐款都必须在两个许可下进行。
高级风格信息:
样式本身是以下示例文件中的文档:
QGC包含一组必须通过的单元测试,才能通过拉取请求考虑更改。为QGC增加新的复杂子系统应该包括一个相应的新单元测试来测试它。
您可以使用--unittest
命令行选项从命令行运行单元测试,该选项将运行所有测试。您可以通过指定它来运行特定的单元测试:--unittest:RadioConfigTest
。
单元测试的完整列表可以在UnitTestList.cc中找到。
所有的请求都通过QGC CI构建系统,构建发布和调试版本。如果有编译器警告,构建将失败。单元测试也针对支持的操作系统调试版本运行。
QGroundControl(QGC)作为Apache 2.0和GPLv3双重许可。所有捐款都必须在两个许可下进行。代码库的用户可以根据任何许可证免费使用它。
QGroundControl许可排除了任何copyleft(例如GPL)许可代码的重复使用。所有贡献必须是原始的或来自兼容许可证(BSD 2/3条款,MIT,Apache 2.0)。
为了能够通过iOS和Android应用商店提供QGroundControl并提供开源社区选择,双重方法是必要的。
的Apache 2.0的许可证是一个许可证,它允许QGC待建并在任何环境中使用,包括专用应用程序。它允许QGC为移动应用程序商店构建。使用Apache 2.0构建商业Qt许可证是必需的。
在GPL v3的许可是一种强的copyleft许可证。在根据此许可证构建QGC时,可以使用Qt的开源版本。我们的许可授予许可使用许可的更高版本,但是,贡献必须在3.0以下。
QGroundControl文档,艺术作品和图像在CC BY 4.0下获得许可。