当前位置:   article > 正文

关于QGroundControl的软件架构的理解

qgroundcontrol

首先QGC是基于QT平台开发,个人理解软件架构即为项目前后端结构,以及前后端数据交互的逻辑。下面是对QGroundControl源码的一些个人理解,写这个博客只是为了记录下来,防止时间久了忘记,过程中看了一些大佬的博客来帮助理解,感谢一下大佬:

火山上的企鹅

阿木实验室

望天边星宿

前言

  • 前端qml结构

QGC的前端主要为五个主要页面和一个顶栏:

MainToolBar(顶栏)

AppSetting.qml

SetupView.qml

PlanView.qml

FlightDispalyView.qml

AnalyzeView.qml

  • 后端类结构

 前端显示与后端逻辑进行数据交互,即实现了QGC地面站功能。

架构理解

架构理解可以从QGC的运行main函数开始逐步理解。

  • main.cc

在main.cc中有几个关键程序

创建QGCApplication实例,QGCApplication是QGroundControl中的核心类,提供了应用程序的生命周期管理、连接管理、飞行日志管理、地图和任务管理、设置和配置管理,以及警报和通知管理等功能。它扮演着关键角色。这个类只提供了唯一的实例,另外提供了一个访问它的全局函数QGCApplication* qgcApp(void){}

QGCApplication* app = new QGCApplication(argc, argv, runUnitTests);

在_initCommon()中将C++类注册,在前端qml中可以调用,实现前后端数据交互。在

qgroundcontrolQmlGlobalSingletonFactory中将QGroundControlQmlGlobal类实例化为单例工厂QGroundControl。
  1. app->_initCommon()
  2. {
  3. static const char* kRefOnly = "Reference only";
  4. static const char* kQGroundControl = "QGroundControl";
  5. static const char* kQGCControllers = "QGroundControl.Controllers";
  6. static const char* kQGCVehicle = "QGroundControl.Vehicle";
  7. QSettings settings;
  8. // Register our Qml objects
  9. qmlRegisterType<QGCPalette> ("QGroundControl.Palette", 1, 0, "QGCPalette");
  10. qmlRegisterType<QGCMapPalette> ("QGroundControl.Palette", 1, 0, "QGCMapPalette");
  11. qmlRegisterUncreatableType<Vehicle> (kQGCVehicle, 1, 0, "Vehicle", kRefOnly);
  12. qmlRegisterUncreatableType<MissionManager> (kQGCVehicle, 1, 0, "MissionManager", kRefOnly);
  13. qmlRegisterUncreatableType<ParameterManager> (kQGCVehicle, 1, 0, "ParameterManager", kRefOnly);
  14. qmlRegisterUncreatableType<VehicleObjectAvoidance> (kQGCVehicle, 1, 0, "VehicleObjectAvoidance", kRefOnly);
  15. qmlRegisterUncreatableType<QGCCameraManager> (kQGCVehicle, 1, 0, "QGCCameraManager", kRefOnly);
  16. qmlRegisterUncreatableType<QGCCameraControl> (kQGCVehicle, 1, 0, "QGCCameraControl", kRefOnly);
  17. qmlRegisterUncreatableType<QGCVideoStreamInfo> (kQGCVehicle, 1, 0, "QGCVideoStreamInfo", kRefOnly);
  18. qmlRegisterUncreatableType<LinkInterface> (kQGCVehicle, 1, 0, "LinkInterface", kRefOnly);
  19. qmlRegisterUncreatableType<MissionController> (kQGCControllers, 1, 0, "MissionController", kRefOnly);
  20. qmlRegisterUncreatableType<GeoFenceController> (kQGCControllers, 1, 0, "GeoFenceController", kRefOnly);
  21. qmlRegisterUncreatableType<RallyPointController> (kQGCControllers, 1, 0, "RallyPointController", kRefOnly);
  22. qmlRegisterUncreatableType<MissionItem> (kQGroundControl, 1, 0, "MissionItem", kRefOnly);
  23. qmlRegisterUncreatableType<VisualMissionItem> (kQGroundControl, 1, 0, "VisualMissionItem", kRefOnly);
  24. qmlRegisterUncreatableType<CoordinateVector> (kQGroundControl, 1, 0, "CoordinateVector", kRefOnly);
  25. qmlRegisterUncreatableType<QmlObjectListModel> (kQGroundControl, 1, 0, "QmlObjectListModel", kRefOnly);
  26. qmlRegisterUncreatableType<MissionCommandTree> (kQGroundControl, 1, 0, "MissionCommandTree", kRefOnly);
  27. qmlRegisterUncreatableType<CameraCalc> (kQGroundControl, 1, 0, "CameraCalc", kRefOnly);
  28. qmlRegisterUncreatableType<LogReplayLink> (kQGroundControl, 1, 0, "LogReplayLink", kRefOnly);
  29. qmlRegisterType<LogReplayLinkController> (kQGroundControl, 1, 0, "LogReplayLinkController");
  30. #if defined(QGC_ENABLE_MAVLINK_INSPECTOR)
  31. qmlRegisterUncreatableType<MAVLinkChartController> (kQGroundControl, 1, 0, "MAVLinkChart", kRefOnly);
  32. #endif
  33. #if defined(QGC_ENABLE_PAIRING)
  34. qmlRegisterUncreatableType<PairingManager> (kQGroundControl, 1, 0, "PairingManager", kRefOnly);
  35. #endif
  36. qmlRegisterUncreatableType<AutoPilotPlugin> ("QGroundControl.AutoPilotPlugin", 1, 0, "AutoPilotPlugin", kRefOnly);
  37. qmlRegisterUncreatableType<VehicleComponent> ("QGroundControl.AutoPilotPlugin", 1, 0, "VehicleComponent", kRefOnly);
  38. qmlRegisterUncreatableType<JoystickManager> ("QGroundControl.JoystickManager", 1, 0, "JoystickManager", kRefOnly);
  39. qmlRegisterUncreatableType<Joystick> ("QGroundControl.JoystickManager", 1, 0, "Joystick", kRefOnly);
  40. qmlRegisterUncreatableType<QGCPositionManager> ("QGroundControl.QGCPositionManager", 1, 0, "QGCPositionManager", kRefOnly);
  41. qmlRegisterUncreatableType<FactValueSliderListModel>("QGroundControl.FactControls", 1, 0, "FactValueSliderListModel", kRefOnly);
  42. qmlRegisterUncreatableType<QGCMapPolygon> ("QGroundControl.FlightMap", 1, 0, "QGCMapPolygon", kRefOnly);
  43. qmlRegisterUncreatableType<QGCGeoBoundingCube> ("QGroundControl.FlightMap", 1, 0, "QGCGeoBoundingCube", kRefOnly);
  44. qmlRegisterUncreatableType<TrajectoryPoints> ("QGroundControl.FlightMap", 1, 0, "TrajectoryPoints", kRefOnly);
  45. qmlRegisterType<QGCMapCircle> ("QGroundControl.FlightMap", 1, 0, "QGCMapCircle");
  46. qmlRegisterType<ParameterEditorController> (kQGCControllers, 1, 0, "ParameterEditorController");
  47. qmlRegisterType<ESP8266ComponentController> (kQGCControllers, 1, 0, "ESP8266ComponentController");
  48. qmlRegisterType<ScreenToolsController> (kQGCControllers, 1, 0, "ScreenToolsController");
  49. qmlRegisterType<PlanMasterController> (kQGCControllers, 1, 0, "PlanMasterController");
  50. qmlRegisterType<ValuesWidgetController> (kQGCControllers, 1, 0, "ValuesWidgetController");
  51. qmlRegisterType<QGCFileDialogController> (kQGCControllers, 1, 0, "QGCFileDialogController");
  52. qmlRegisterType<RCChannelMonitorController> (kQGCControllers, 1, 0, "RCChannelMonitorController");
  53. qmlRegisterType<JoystickConfigController> (kQGCControllers, 1, 0, "JoystickConfigController");
  54. qmlRegisterType<LogDownloadController> (kQGCControllers, 1, 0, "LogDownloadController");
  55. qmlRegisterType<SyslinkComponentController> (kQGCControllers, 1, 0, "SyslinkComponentController");
  56. qmlRegisterType<EditPositionDialogController> (kQGCControllers, 1, 0, "EditPositionDialogController");
  57. #ifndef __mobile__
  58. #ifndef NO_SERIAL_LINK
  59. qmlRegisterType<FirmwareUpgradeController> (kQGCControllers, 1, 0, "FirmwareUpgradeController");
  60. #endif
  61. #endif
  62. qmlRegisterType<GeoTagController> (kQGCControllers, 1, 0, "GeoTagController");
  63. qmlRegisterType<MavlinkConsoleController> (kQGCControllers, 1, 0, "MavlinkConsoleController");
  64. #if defined(QGC_ENABLE_MAVLINK_INSPECTOR)
  65. qmlRegisterType<MAVLinkInspectorController> (kQGCControllers, 1, 0, "MAVLinkInspectorController");
  66. #endif
  67. // Register Qml Singletons
  68. qmlRegisterSingletonType<QGroundControlQmlGlobal> ("QGroundControl", 1, 0, "QGroundControl", qgroundcontrolQmlGlobalSingletonFactory);
  69. qmlRegisterSingletonType<ScreenToolsController> ("QGroundControl.ScreenToolsController", 1, 0, "ScreenToolsController", screenToolsControllerSingletonFactory);
  70. qmlRegisterSingletonType<ShapeFileHelper> ("QGroundControl.ShapeFileHelper", 1, 0, "ShapeFileHelper", shapeFileHelperSingletonFactory);
  71. }

在_initForNormalAppBoot()中进行启动初始化,加载qml文件。

  1. app->_initForNormalAppBoot()
  2. QQmlApplicationEngine* QGCCorePlugin::createRootWindow(QObject *parent)
  3. {
  4. QQmlApplicationEngine* pEngine = new QQmlApplicationEngine(parent);
  5. pEngine->addImportPath("qrc:/qml");
  6. // 注册为对象在qml中直接使用,不需要import
  7. pEngine->rootContext()->setContextProperty("joystickManager", qgcApp()->toolbox()->joystickManager());
  8. pEngine->rootContext()->setContextProperty("debugMessageModel", AppMessages::getModel());
  9. pEngine->load(QUrl(QStringLiteral("qrc:/qml/MainRootWindow.qml")));
  10. return pEngine;
  11. }
  • 整体架构

想要搞明白整体架构就需要理解QGCApplication类、QGCToolBox类、QGroundControlQmlGlobal类和QGCtool类。

QGCApplication类中新建了QGCToolbox类,在QGCToolbox类初始化时需要传入QGCApplication类,这样通过qgcAPP()->toolBox()就可以获取到功能类的所有属性。

QGCToolBox类是一个大的工具类,QGC的所有功能类都在这个toolBox中进行实例化,使用toolBox提供的接口即可调用类的属性和方法。

在QGroundControlQmlGlobal中通过Q_PROPERTY将功能类的属性和方法共前端可以调用,setToolbox()方法将所有功能类使用指针地址连接到QGCToolBox定义的功能类,所以QGroundControlQmlGlobal是前端获取后端数据的总接口。上边的单例工厂实例化将QGroundControlQmlGlobal实例化为QGroundControl,则前端qml通过import 即可实现调用C++类。

还有一个QGCTool类,所有的功能类都继承了QGCTool。在QGCTool类型定义了QGCApplication* _app;和QGCToolbox* _toolbox;和(QGCApplication* app, QGCToolbox* toolbox)方法,即每个功能类都都有QGCApplication和QGCToolbox,并且都指向同一个QGCApplication和QGCToolbox,即QGCApplication中的_app和_toolBox.这样实现了各个功能类的互通。

  1. QGCToolbox::QGCToolbox(QGCApplication* app)
  2. {
  3. // SettingsManager must be first so settings are available to any subsequent tools
  4. _settingsManager = new SettingsManager (app, this);
  5. //-- Scan and load plugins
  6. _scanAndLoadPlugins(app);
  7. _audioOutput = new AudioOutput (app, this);
  8. _factSystem = new FactSystem (app, this);
  9. _firmwarePluginManager = new FirmwarePluginManager (app, this);
  10. #ifndef __mobile__
  11. _gpsManager = new GPSManager (app, this);
  12. #endif
  13. _imageProvider = new QGCImageProvider (app, this);
  14. _joystickManager = new JoystickManager (app, this);
  15. _linkManager = new LinkManager (app, this);
  16. _mavlinkProtocol = new MAVLinkProtocol (app, this);
  17. _missionCommandTree = new MissionCommandTree (app, this);
  18. _multiVehicleManager = new MultiVehicleManager (app, this);
  19. _mapEngineManager = new QGCMapEngineManager (app, this);
  20. _uasMessageHandler = new UASMessageHandler (app, this);
  21. _qgcPositionManager = new QGCPositionManager (app, this);
  22. _followMe = new FollowMe (app, this);
  23. _videoManager = new VideoManager (app, this);
  24. _mavlinkLogManager = new MAVLinkLogManager (app, this);
  25. _adsbVehicleManager = new ADSBVehicleManager (app, this);
  26. #if defined(QGC_ENABLE_PAIRING)
  27. _pairingManager = new PairingManager (app, this);
  28. #endif
  29. //-- Airmap Manager
  30. //-- This should be "pluggable" so an arbitrary AirSpace manager can be used
  31. //-- For now, we instantiate the one and only AirMap provider
  32. #if defined(QGC_AIRMAP_ENABLED)
  33. _airspaceManager = new AirMapManager (app, this);
  34. #else
  35. _airspaceManager = new AirspaceManager (app, this);
  36. #endif
  37. #if defined(QGC_GST_TAISYNC_ENABLED)
  38. _taisyncManager = new TaisyncManager (app, this);
  39. #endif
  40. #if defined(QGC_GST_MICROHARD_ENABLED)
  41. _microhardManager = new MicrohardManager (app, this);
  42. #endif
  43. }
  44. void QGCToolbox::setChildToolboxes(void)
  45. {
  46. // SettingsManager must be first so settings are available to any subsequent tools
  47. _settingsManager->setToolbox(this);
  48. _corePlugin->setToolbox(this);
  49. _audioOutput->setToolbox(this);
  50. _factSystem->setToolbox(this);
  51. _firmwarePluginManager->setToolbox(this);
  52. #ifndef __mobile__
  53. _gpsManager->setToolbox(this);
  54. #endif
  55. _imageProvider->setToolbox(this);
  56. _joystickManager->setToolbox(this);
  57. _linkManager->setToolbox(this);
  58. _mavlinkProtocol->setToolbox(this);
  59. _missionCommandTree->setToolbox(this);
  60. _multiVehicleManager->setToolbox(this);
  61. _mapEngineManager->setToolbox(this);
  62. _uasMessageHandler->setToolbox(this);
  63. _followMe->setToolbox(this);
  64. _qgcPositionManager->setToolbox(this);
  65. _videoManager->setToolbox(this);
  66. _mavlinkLogManager->setToolbox(this);
  67. _airspaceManager->setToolbox(this);
  68. _adsbVehicleManager->setToolbox(this);
  69. #if defined(QGC_GST_TAISYNC_ENABLED)
  70. _taisyncManager->setToolbox(this);
  71. #endif
  72. #if defined(QGC_GST_MICROHARD_ENABLED)
  73. _microhardManager->setToolbox(this);
  74. #endif
  75. #if defined(QGC_ENABLE_PAIRING)
  76. _pairingManager->setToolbox(this);
  77. #endif
  78. }
  79. void QGCToolbox::_scanAndLoadPlugins(QGCApplication* app)
  80. {
  81. #if defined (QGC_CUSTOM_BUILD)
  82. //-- Create custom plugin (Static)
  83. _corePlugin = (QGCCorePlugin*) new CUSTOMCLASS(app, app->toolbox());
  84. if(_corePlugin) {
  85. return;
  86. }
  87. #endif
  88. //-- No plugins found, use default instance
  89. _corePlugin = new QGCCorePlugin(app, app->toolbox());
  90. }

在前端获取后端类的属性的总借口即为QGroundControl,例如

property var   _vehicle:          QGroundControl.multiVehicleManager.getVehicleById(1)

在功能类中向获取其他功能类的属性即使用qgcApp()->toolbox(),如果功能类继承了QGCTool则直接可以使用_toolbox->...即可。

  1. _mavlink = qgcApp()->toolbox()->mavlinkProtocol();
  2. _mavlinkProtocol = _toolbox->mavlinkProtocol();

其实只要理解这几个总文件之间的关系后,就理解了QGC的整体结构。_app和_toolbox是QGC整个软件的总接口,_app和_toolbox都在QGCApplication类中,然后所有功能类都在QGCToolBox类中新建,想要获取功能类的属性就需要通过_toolbox。然后QGroundControlQmlGlobal中通过指针地址获取到了所有功能类,然后又通过Q_PROPERTY将类以属性的形式开放给前端,再加上单例模式直接在前端import QGroundControl即可获取到后端属性。这样即完成了前后端数据连通,也解决了各个功能类之间的属性获取。

以上是个人理解,很多地理解的不是太透彻,等有新的理解再更新。有错误的地方也望大佬指正,共同进步。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/428949
推荐阅读
相关标签
  

闽ICP备14008679号