mavlink/qgroundcontrol — pull request #512 by DonLakeFlyer (2014-02-12 22:34:52+00:00)
Title: FactSystem looking for feedback only

Problem
Being a new user to the whole autopilot/mav space I’ve gotten pretty annoyed with how hard it is to get one of these vehicles off the ground correctly. Specifically all of the various parameters and tuning that is needed to get them to run well, or at all. So I decided to try to do something about it. Specifically to provide better information associated with values, as well as create a mechanism to express semantics between the various values which can cause things to ho haywire. This code is a start at what I think a solution could be. I’m pushing this up not to merge in but to see what people think as far as heading in this direction.

Concept
Simplest explanation is to provide access to the various values associated with the vehicle using a consistent mechanism. This system not only provides the values themselves but a standard set of meta data associated with each value as well. I call it the Fact System. This system gets data from Providers. There currently are four providers:
- Parameters - mavlink parameters
- Telemetry - the data coming through mavlink messages to the Ground Control Station (GCS)
- Settings - settings stored on the GCS for each registered has
- Rules - a Lua based rule system which allows you to write rules against the facts in the system and in turn expose new facts

Currently QGroundControl does some of this already but it uses different code for parameters and telemetry for example. The Fact System treats parameter and telemetry the same. To do this, I start with the basic concept of a Fact (Fact.cc/h). A Fact is simply a value. Facts come from Providers. The current set of Providers that are supported are: Parameter, Telemetry, Setting and Rule. The combination of a Provider and Fact Id will point you at a specific value. A fact also has meta data associated with it. This meta data tells you additional information about a Fact. When you put a Fact together with its Meta Data you can access additional properties of the Fact. Things like descriptions, units and so forth. All Facts can have meta data associated with them to make the UI easier to understand. The Fact is implement using the Qt MetaObject system such that all Fact information is also available to QML. The Fact System is agnostic to system or board type. It waits for the first heartbeat to determine the correct set of meta data to load which is appropriate for the uas it is talking to. Each uas has it’s own separate Fact System instance associated with it.

The Rule Fact is essentially also a value you can access. The difference is that the value is calculated using Lua Script. This script has access to all the facts in the system. See FactRuleHandler.cc/h. See files/MetaData/ArdupilotMega/commonrules.lua for some simple examples of Rule Facts which check for needed calibration.

You can use the rule language to build rules that understand the relationships between the values. These rules could then tell you things like:
- Various sensors need to be calibrated
- Internal systems need tuning of parameters before you use a specific feature. Simple example, don’t depend on plane TECS unless you have a calibrated airspeed sensor. Or be careful depending on good altitude hold if you haven’t done a vibration check on your quad. Rule could see you are using the feature on a flight mode and warn to tune specific settings first.
- Preflight checks that need to be met before use
- The rules could also allow you to abstract yourself from specific hard-coded connections to an autopilot type.

The whole “Rule” concept is the reason I started this whole thing and then it kind of spiraled out of control from there :)

There is also the ability to “Draw” user interfaces using these Facts. The current example is a QTableView. It uses the Qt MVC paradigm to back the table view model to the Fact information. So in reality you should be able to connect this to more things like Tree Views and so forth. It also creates item delegates to provide better editing which is driven from the meta data. Based on the meta data, you get SpinBox, ComboBox or ComboBox with check box controls. You draw the ui using a kind of spreadsheet format. For example if you put ‘=P.SYSID_MYGCS:Description’ into a cell, the cell will be filled with the Description meta data for the SYSID_MYGCS parameter (P.=Parameter provider). See FactTableModel.cc, FactItemDelegate.cc for the MVC stuff. See FactTableWidget.cc for the formula drawing stuff. See AdvancedParamterList.cc/ui for an example ui usage. All this stuff allows you to “draw” ui using QT Creator which basically just works in many case without any extra code. Facts which have not been sent are shown in red, Facts which differ from the default value are shown in yellow.

Also important to point out that since Facts are meta objects you can use QML to create ui directly with them as well. I don’t currently have any examples of that.

MetaData
I’ve cobbled together meta data for facts from as many places as I could find. I use the APM xml files, the mavlink xml files, I pull default values by flashing a board, and saving parameters for it right away. You can find the meta data under files/MetaData with subdirectories for each board, mav type and so forth fan out from under there.

The code:
At this point I’ve shimmed the Fact System into qgroundcontrol such that it doesn’t affect the main portion of the code. As a test case I have plumbed it into the APM Advanced Parameter List ui. I don’t think it would be that difficult to plumb it through the full code base. The Fact System code is all under src/factsystem:

Fact.cc/h - main Fact object
FactHandler.cc/h - handles all the facts in the system, also loads meta data
FactMavShim.cc/h - shim to connect to data coming from mavlink
FactTableWidget.cc/h - table widget class for building ui
FactTableModel.cc.h, FactItemDelegate.cc/h - MVC support for table view ui which shows facts
FactRuleHandlers.cc/h - handles the lua rules. Lua libs are currently just hacked into build.

Running
I’ve been mainly testing with and ArduPilot 2.6 board with ArduPlane loaded into it. The reason for this is that I have the best meta data for that board. I know it runs inn OSX and Linux. Crank up QGroundControl in APM mode connect to the board, wait for the parameters to come in and then go to the Software/Full Parameter List under software screen. You should see four tabs:

- Parameters shows you all parameters (double-click values to edit)
- Telemetry shows you all telemetry (this is live data)
- PIDs shows you an example of building ui for pids
- Rules shows you all the rules (rules are not currently static and will not update as the Facts they reference change)

Anyway, that’s a lot of words. Play around with it and see what you think. I think it could be pretty valuable as a starting point to make these things way more user friendly and consistent. Even without the rules part it provides lots of helpful information. I hope it makes sense to someone other than me! It still has a way to go code wise but I think there is enough there to gather some feedback. Some examples are the Fact currently don’t have timestamps for telemetry logging. But it would be easy to add timestamps and then Facts could driver the logging code. Rules don’t update live. Thinking about the possibility of an “Alias” provider which would allow you to write code which references an Aliased fact and then the rule engine connects you to the correct fact based on system and mav type. This would allow you to write generic code once for all the different board/mav combinations.