Commit 600008e2 authored by Gus Grubba's avatar Gus Grubba

Dealing with brief features and telemetry.

parent 4283729f
......@@ -254,7 +254,7 @@ AirMapFlightPlanManager::updateFlightPlan()
}
_flightPermitStatus = AirspaceFlightPlanProvider::PermitPending;
emit flightPermitStatusChanged();
_updateFlightPlan();
_updateFlightPlan(true);
}
//-----------------------------------------------------------------------------
......@@ -373,9 +373,6 @@ AirMapFlightPlanManager::_createFlightPlan()
qCDebug(AirMapManagerLog) << "Flight Start:" << flightStartTime().toString();
qCDebug(AirMapManagerLog) << "Flight End: " << flightEndTime().toString();
//-- Not Yet
//return;
if (_pilotID == "") {
//-- Need to get the pilot id before uploading the flight plan
qCDebug(AirMapManagerLog) << "Getting pilot ID";
......@@ -413,7 +410,7 @@ AirMapFlightPlanManager::_createFlightPlan()
//-----------------------------------------------------------------------------
void
AirMapFlightPlanManager::_updateRulesAndFeatures(std::vector<RuleSet::Id>& rulesets, std::unordered_map<std::string, RuleSet::Feature::Value>& features)
AirMapFlightPlanManager::_updateRulesAndFeatures(std::vector<RuleSet::Id>& rulesets, std::unordered_map<std::string, RuleSet::Feature::Value>& features, bool updateFeatures)
{
AirMapRulesetsManager* pRulesMgr = dynamic_cast<AirMapRulesetsManager*>(qgcApp()->toolbox()->airspaceManager()->ruleSets());
if(pRulesMgr) {
......@@ -422,34 +419,42 @@ AirMapFlightPlanManager::_updateRulesAndFeatures(std::vector<RuleSet::Id>& rules
//-- If this ruleset is selected
if(ruleSet && ruleSet->selected()) {
rulesets.push_back(ruleSet->id().toStdString());
//-- Features within each rule
for(int r = 0; r < ruleSet->rules()->count(); r++) {
AirMapRule* rule = qobject_cast<AirMapRule*>(ruleSet->rules()->get(r));
if(rule) {
for(int f = 0; f < rule->features()->count(); f++) {
AirMapRuleFeature* feature = qobject_cast<AirMapRuleFeature*>(rule->features()->get(f));
if(feature && feature->value().isValid()) {
switch(feature->type()) {
case AirspaceRuleFeature::Boolean:
//-- Skip not set responses (feature->value is initialized to "2")
if(feature->value().toInt() == 0 || feature->value().toInt() == 1) {
features[feature->name().toStdString()] = RuleSet::Feature::Value(feature->value().toBool());
}
break;
case AirspaceRuleFeature::Float:
//-- Sanity check for floats
if(std::isfinite(feature->value().toFloat())) {
features[feature->name().toStdString()] = RuleSet::Feature::Value(feature->value().toFloat());
}
break;
case AirspaceRuleFeature::String:
//-- Skip empty responses
if(!feature->value().toString().isEmpty()) {
features[feature->name().toStdString()] = RuleSet::Feature::Value(feature->value().toString().toStdString());
//-- Features within each rule (only when updating)
if(updateFeatures) {
for(int r = 0; r < ruleSet->rules()->count(); r++) {
AirMapRule* rule = qobject_cast<AirMapRule*>(ruleSet->rules()->get(r));
if(rule) {
for(int f = 0; f < rule->features()->count(); f++) {
AirMapRuleFeature* feature = qobject_cast<AirMapRuleFeature*>(rule->features()->get(f));
if(features.find(feature->name().toStdString()) != features.end()) {
qCDebug(AirMapManagerLog) << "Removing duplicate:" << feature->name();
continue;
}
if(feature && feature->value().isValid()) {
switch(feature->type()) {
case AirspaceRuleFeature::Boolean:
if(feature->value().toInt() == 0 || feature->value().toInt() == 1) {
features[feature->name().toStdString()] = RuleSet::Feature::Value(feature->value().toBool());
} else {
//-- If not set, default to false
features[feature->name().toStdString()] = RuleSet::Feature::Value(false);
}
break;
case AirspaceRuleFeature::Float:
//-- Sanity check for floats
if(std::isfinite(feature->value().toFloat())) {
features[feature->name().toStdString()] = RuleSet::Feature::Value(feature->value().toFloat());
}
break;
case AirspaceRuleFeature::String:
//-- Skip empty responses
if(!feature->value().toString().isEmpty()) {
features[feature->name().toStdString()] = RuleSet::Feature::Value(feature->value().toString().toStdString());
}
break;
default:
qCWarning(AirMapManagerLog) << "Unknown type for feature" << feature->name();
}
break;
default:
qCWarning(AirMapManagerLog) << "Unknown type for feature" << feature->name();
}
}
}
......@@ -516,15 +521,19 @@ AirMapFlightPlanManager::_uploadFlightPlan()
//-----------------------------------------------------------------------------
void
AirMapFlightPlanManager::_updateFlightPlan()
AirMapFlightPlanManager::_updateFlightPlanOnTimer()
{
//-- TODO: This is broken as the parameters for updating the plan have
// little to do with those used when creating it.
_updateFlightPlan(false);
}
//-----------------------------------------------------------------------------
void
AirMapFlightPlanManager::_updateFlightPlan(bool interactive)
{
qCDebug(AirMapManagerLog) << "Updating flight plan. State:" << (int)_state;
if(_state != State::Idle) {
QTimer::singleShot(100, this, &AirMapFlightPlanManager::_updateFlightPlan);
QTimer::singleShot(100, this, &AirMapFlightPlanManager::_updateFlightPlanOnTimer);
return;
}
//-- Get flight data
......@@ -546,7 +555,8 @@ AirMapFlightPlanManager::_updateFlightPlan()
//-- Rules & Features
_flightPlan.rulesets.clear();
_flightPlan.features.clear();
_updateRulesAndFeatures(_flightPlan.rulesets, _flightPlan.features);
//-- If interactive, we collect features otherwise we don't
_updateRulesAndFeatures(_flightPlan.rulesets, _flightPlan.features, interactive);
//-- Geometry: polygon
Geometry::Polygon polygon;
for (const auto& qcoord : _flight.coords) {
......@@ -600,6 +610,19 @@ rules_sort(QObject* a, QObject* b)
return (int)aa->status() > (int)bb->status();
}
//-----------------------------------------------------------------------------
bool
AirMapFlightPlanManager::_findBriefFeature(const QString& name)
{
for(int i = 0; i < _briefFeatures.count(); i++ ) {
AirMapRuleFeature* feature = qobject_cast<AirMapRuleFeature*>(_briefFeatures.get(i));
if (feature && feature->name() == name) {
return true;
}
}
return false;
}
//-----------------------------------------------------------------------------
void
AirMapFlightPlanManager::_pollBriefing()
......@@ -657,8 +680,12 @@ AirMapFlightPlanManager::_pollBriefing()
AirMapRuleFeature* pFeature = new AirMapRuleFeature(feature, this);
pRule->_features.append(pFeature);
if(rule.status == RuleSet::Rule::Status::missing_info) {
_briefFeatures.append(pFeature);
qCDebug(AirMapManagerLog) << "Adding briefing feature" << pFeature->name() << pFeature->description() << pFeature->type();
if(!_findBriefFeature(pFeature->name())) {
_briefFeatures.append(pFeature);
qCDebug(AirMapManagerLog) << "Adding briefing feature" << pFeature->name() << pFeature->description() << pFeature->type();
} else {
qCDebug(AirMapManagerLog) << "Skipping briefing feature duplicate" << pFeature->name() << pFeature->description() << pFeature->type();
}
}
}
pRuleSet->_rules.append(pRule);
......
......@@ -90,6 +90,7 @@ public:
AirspaceFlightModel*flightList () override { return &_flightList; }
bool loadingFlightList () override { return _loadingFlightList; }
QString flightPlanID () {return QString::fromStdString(_flightPlan.id); }
QString flightID () {return _flightId; }
void updateFlightPlan () override;
void submitFlightPlan () override;
......@@ -107,13 +108,15 @@ private slots:
void _missionChanged ();
void _endFlight ();
void _uploadFlightPlan ();
void _updateFlightPlan ();
void _updateFlightPlanOnTimer ();
void _loadFlightList ();
private:
void _createFlightPlan ();
bool _collectFlightDtata ();
void _updateRulesAndFeatures (std::vector<airmap::RuleSet::Id>& rulesets, std::unordered_map<std::string, airmap::RuleSet::Feature::Value>& features);
void _updateFlightPlan (bool interactive = false);
bool _findBriefFeature (const QString& name);
void _updateRulesAndFeatures (std::vector<airmap::RuleSet::Id>& rulesets, std::unordered_map<std::string, airmap::RuleSet::Feature::Value>& features, bool updateFeatures = false);
private:
enum class State {
......
......@@ -42,8 +42,8 @@ AirMapManager::AirMapManager(QGCApplication* app, QGCToolbox* toolbox)
{
_logger = std::make_shared<qt::Logger>();
qt::register_types(); // TODO: still needed?
_logger->logging_category().setEnabled(QtDebugMsg, true);
_logger->logging_category().setEnabled(QtInfoMsg, true);
_logger->logging_category().setEnabled(QtDebugMsg, false);
_logger->logging_category().setEnabled(QtInfoMsg, false);
_logger->logging_category().setEnabled(QtWarningMsg, false);
_dispatchingLogger = std::make_shared<qt::DispatchingLogger>(_logger);
connect(&_shared, &AirMapSharedState::error, this, &AirMapManager::_error);
......
......@@ -31,6 +31,7 @@ AirMapRuleFeature::AirMapRuleFeature(airmap::RuleSet::Feature feature, QObject*
settings.beginGroup(kAirMapFeatureGroup);
switch(_feature.type) {
case RuleSet::Feature::Type::boolean:
//-- For boolean, we have 3 states: 0 - false, 1 - true and 2 - not set
_value = settings.value(name(), 2);
break;;
case RuleSet::Feature::Type::floating_point:
......@@ -45,6 +46,14 @@ AirMapRuleFeature::AirMapRuleFeature(airmap::RuleSet::Feature feature, QObject*
settings.endGroup();
}
//-----------------------------------------------------------------------------
QVariant
AirMapRuleFeature::value()
{
//qCDebug(AirMapManagerLog) << "Value of" << name() << "==>" << _value << type();
return _value;
}
//-----------------------------------------------------------------------------
AirspaceRuleFeature::Type
AirMapRuleFeature::type()
......@@ -100,6 +109,25 @@ AirMapRuleFeature::measurement()
void
AirMapRuleFeature::setValue(const QVariant val)
{
switch(_feature.type) {
case RuleSet::Feature::Type::boolean:
if(val.toInt() != 0 && val.toInt() != 1) {
return;
}
break;
case RuleSet::Feature::Type::floating_point:
if(!std::isfinite(val.toDouble())) {
return;
}
break;;
case RuleSet::Feature::Type::string:
if(val.toString().isEmpty()) {
return;
}
break;;
default:
return;
}
_value = val;
//-- Make value persistent
QSettings settings;
......
......@@ -39,7 +39,7 @@ public:
Measurement measurement () override;
QString name () override { return QString::fromStdString(_feature.name); }
QString description () override { return QString::fromStdString(_feature.description); }
QVariant value () override { return _value; }
QVariant value () override;
void setValue (const QVariant val) override;
private:
airmap::RuleSet::Feature _feature;
......
......@@ -84,6 +84,7 @@ AirMapTelemetry::_handleGlobalPositionInt(const mavlink_message_t& message)
globalPosition.vz / 100.f
};
//qCDebug(AirMapManagerLog) << "Telemetry:" << globalPosition.lat / 1e7 << globalPosition.lon / 1e7;
Flight flight;
flight.id = _flightID.toStdString();
_shared.client()->telemetry().submit_updates(flight, _key,
......
......@@ -7,9 +7,12 @@
*
****************************************************************************/
#include "AirspaceFlightPlanProvider.h"
#include "AirMapFlightPlanManager.h"
#include "AirMapVehicleManager.h"
#include "AirMapManager.h"
#include "QGCApplication.h"
#include "Vehicle.h"
//-----------------------------------------------------------------------------
......@@ -30,9 +33,13 @@ AirMapVehicleManager::AirMapVehicleManager(AirMapSharedState& shared, const Vehi
void
AirMapVehicleManager::startTelemetryStream()
{
if (!_flightManager.flightID().isEmpty()) {
//-- TODO: This will start telemetry using the current flight ID in memory
_telemetry.startTelemetryStream(_flightManager.flightID());
AirMapFlightPlanManager* planMgr = (AirMapFlightPlanManager*)qgcApp()->toolbox()->airspaceManager()->flightPlan();
if (!planMgr->flightID().isEmpty()) {
//-- TODO: This will start telemetry using the current flight ID in memory (current flight in AirMapFlightPlanManager)
qCDebug(AirMapManagerLog) << "AirMap telemetry stream enabled";
_telemetry.startTelemetryStream(planMgr->flightID());
} else {
qCDebug(AirMapManagerLog) << "AirMap telemetry stream not possible (No Flight ID)";
}
}
......@@ -54,8 +61,9 @@ AirMapVehicleManager::isTelemetryStreaming()
void
AirMapVehicleManager::endFlight()
{
if (!_flightManager.flightID().isEmpty()) {
_flightManager.endFlight(_flightManager.flightID());
AirMapFlightPlanManager* planMgr = (AirMapFlightPlanManager*)qgcApp()->toolbox()->airspaceManager()->flightPlan();
if (!planMgr->flightID().isEmpty()) {
_flightManager.endFlight(planMgr->flightID());
}
_trafficMonitor.stop();
}
......
......@@ -312,11 +312,11 @@ QGCView {
anchors.fill: parent
TableView {
id: tableView
anchors.top: parent.top
anchors.bottom: parent.bottom
model: _flightList
selectionMode: SelectionMode.SingleSelection
Layout.alignment: Qt.AlignVCenter
Layout.fillWidth: true
Layout.fillHeight: true
onCurrentRowChanged: {
var o = _flightList.get(tableView.currentRow)
if(o) {
......
......@@ -56,10 +56,12 @@ Rectangle {
QGCCheckBox {
id: checkBox
text: ""
checked: feature.value && feature.value < 2 ? feature.value : false
onClicked: feature.value = checked
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
Component.onCompleted: {
checked = feature.value && feature.value < 2 ? feature.value : false
}
}
QGCLabel {
id: label
......
......@@ -16,6 +16,7 @@
AirspaceVehicleManager::AirspaceVehicleManager(const Vehicle& vehicle)
: _vehicle(vehicle)
{
qCDebug(AirspaceManagementLog) << "Instatiating AirspaceVehicleManager";
connect(&_vehicle, &Vehicle::armedChanged, this, &AirspaceVehicleManager::_vehicleArmedChanged);
connect(&_vehicle, &Vehicle::mavlinkMessageReceived, this, &AirspaceVehicleManager::vehicleMavlinkMessageReceived);
}
......@@ -23,9 +24,11 @@ AirspaceVehicleManager::AirspaceVehicleManager(const Vehicle& vehicle)
void AirspaceVehicleManager::_vehicleArmedChanged(bool armed)
{
if (armed) {
qCDebug(AirspaceManagementLog) << "Starting telemetry";
startTelemetryStream();
_vehicleWasInMissionMode = _vehicle.flightMode() == _vehicle.missionFlightMode();
} else {
qCDebug(AirspaceManagementLog) << "Stopping telemetry";
stopTelemetryStream();
// end the flight if we were in mission mode during arming or disarming
// TODO: needs to be improved. for instance if we do RTL and then want to continue the mission...
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment