diff --git a/src/Vehicle/BatteryFact.json b/src/Vehicle/BatteryFact.json index 3c3b861336c04dbbdc2a1f72a19207e012d8d9e2..6f6e1337626d524f50971d29cb17c6305b19019e 100644 --- a/src/Vehicle/BatteryFact.json +++ b/src/Vehicle/BatteryFact.json @@ -16,6 +16,16 @@ "decimalPlaces": 0, "units": "%" }, + { + "name": "percentRemainingAnnounce", + "shortDescription": "Percent", + "type": "int32", + "decimalPlaces": 0, + "units": "%", + "defaultValue": 30, + "min": 0, + "max": 100 + }, { "name": "mahConsumed", "shortDescription": "Consumed", diff --git a/src/Vehicle/Vehicle.cc b/src/Vehicle/Vehicle.cc index c6f3f82c6899dc9dcf8d2ab02220524f8d7a0e8c..14db6c283604c13914449064be5927c4d386f89f 100644 --- a/src/Vehicle/Vehicle.cc +++ b/src/Vehicle/Vehicle.cc @@ -60,36 +60,7 @@ const char* Vehicle::_batteryFactGroupName = "battery"; const char* Vehicle::_windFactGroupName = "wind"; const char* Vehicle::_vibrationFactGroupName = "vibration"; -const char* VehicleGPSFactGroup::_hdopFactName = "hdop"; -const char* VehicleGPSFactGroup::_vdopFactName = "vdop"; -const char* VehicleGPSFactGroup::_courseOverGroundFactName = "courseOverGround"; -const char* VehicleGPSFactGroup::_countFactName = "count"; -const char* VehicleGPSFactGroup::_lockFactName = "lock"; - -const char* VehicleBatteryFactGroup::_voltageFactName = "voltage"; -const char* VehicleBatteryFactGroup::_percentRemainingFactName = "percentRemaining"; -const char* VehicleBatteryFactGroup::_mahConsumedFactName = "mahConsumed"; -const char* VehicleBatteryFactGroup::_currentFactName = "current"; -const char* VehicleBatteryFactGroup::_temperatureFactName = "temperature"; -const char* VehicleBatteryFactGroup::_cellCountFactName = "cellCount"; - -const double VehicleBatteryFactGroup::_voltageUnavailable = -1.0; -const int VehicleBatteryFactGroup::_percentRemainingUnavailable = -1; -const int VehicleBatteryFactGroup::_mahConsumedUnavailable = -1; -const int VehicleBatteryFactGroup::_currentUnavailable = -1; -const double VehicleBatteryFactGroup::_temperatureUnavailable = -1.0; -const int VehicleBatteryFactGroup::_cellCountUnavailable = -1.0; - -const char* VehicleWindFactGroup::_directionFactName = "direction"; -const char* VehicleWindFactGroup::_speedFactName = "speed"; -const char* VehicleWindFactGroup::_verticalSpeedFactName = "verticalSpeed"; - -const char* VehicleVibrationFactGroup::_xAxisFactName = "xAxis"; -const char* VehicleVibrationFactGroup::_yAxisFactName = "yAxis"; -const char* VehicleVibrationFactGroup::_zAxisFactName = "zAxis"; -const char* VehicleVibrationFactGroup::_clipCount1FactName = "clipCount1"; -const char* VehicleVibrationFactGroup::_clipCount2FactName = "clipCount2"; -const char* VehicleVibrationFactGroup::_clipCount3FactName = "clipCount3"; +const int Vehicle::_lowBatteryAnnounceRepeatMSecs = 30 * 1000; Vehicle::Vehicle(LinkInterface* link, int vehicleId, @@ -101,6 +72,7 @@ Vehicle::Vehicle(LinkInterface* link, : FactGroup(_vehicleUIUpdateRateMSecs, ":/json/Vehicle/VehicleFact.json") , _id(vehicleId) , _active(false) + , _disconnectedVehicle(false) , _firmwareType(firmwareType) , _vehicleType(vehicleType) , _firmwarePlugin(NULL) @@ -165,8 +137,10 @@ Vehicle::Vehicle(LinkInterface* link, _mavlink = qgcApp()->toolbox()->mavlinkProtocol(); connect(_mavlink, &MAVLinkProtocol::messageReceived, this, &Vehicle::_mavlinkMessageReceived); - connect(this, &Vehicle::_sendMessageOnThread, this, &Vehicle::_sendMessage, Qt::QueuedConnection); + + connect(this, &Vehicle::_sendMessageOnThread, this, &Vehicle::_sendMessage, Qt::QueuedConnection); connect(this, &Vehicle::_sendMessageOnLinkOnThread, this, &Vehicle::_sendMessageOnLink, Qt::QueuedConnection); + connect(this, &Vehicle::flightModeChanged, this, &Vehicle::_announceflightModeChanged); _uas = new UAS(_mavlink, this, _firmwarePluginManager); @@ -227,6 +201,9 @@ Vehicle::Vehicle(LinkInterface* link, _mapTrajectoryTimer.setInterval(_mapTrajectoryMsecsBetweenPoints); connect(&_mapTrajectoryTimer, &QTimer::timeout, this, &Vehicle::_addNewMapTrajectoryPoint); + // Invalidate the timer to signal first announce + _lowBatteryAnnounceTimer.invalidate(); + // Build FactGroup object model _addFact(&_rollFact, _rollFactName); @@ -249,6 +226,93 @@ Vehicle::Vehicle(LinkInterface* link, _vibrationFactGroup.setVehicle(this); } +// Disconnected Vehicle +Vehicle::Vehicle(QObject* parent) + : FactGroup(_vehicleUIUpdateRateMSecs, ":/json/Vehicle/VehicleFact.json", parent) + , _id(0) + , _active(false) + , _disconnectedVehicle(false) + , _firmwareType(MAV_AUTOPILOT_PX4) + , _vehicleType(MAV_TYPE_QUADROTOR) + , _firmwarePlugin(NULL) + , _autopilotPlugin(NULL) + , _joystickMode(JoystickModeRC) + , _joystickEnabled(false) + , _uas(NULL) + , _coordinate(37.803784, -122.462276) + , _coordinateValid(false) + , _homePositionAvailable(false) + , _mav(NULL) + , _currentMessageCount(0) + , _messageCount(0) + , _currentErrorCount(0) + , _currentWarningCount(0) + , _currentNormalCount(0) + , _currentMessageType(MessageNone) + , _navigationAltitudeError(0.0f) + , _navigationSpeedError(0.0f) + , _navigationCrosstrackError(0.0f) + , _navigationTargetBearing(0.0f) + , _refreshTimer(new QTimer(this)) + , _updateCount(0) + , _rcRSSI(0) + , _rcRSSIstore(100.0) + , _autoDisconnect(false) + , _connectionLost(false) + , _connectionLostEnabled(true) + , _missionManager(NULL) + , _missionManagerInitialRequestComplete(false) + , _parameterLoader(NULL) + , _armed(false) + , _base_mode(0) + , _custom_mode(0) + , _nextSendMessageMultipleIndex(0) + , _firmwarePluginManager(NULL) + , _autopilotPluginManager(NULL) + , _joystickManager(NULL) + , _flowImageIndex(0) + , _allLinksInactiveSent(false) + , _messagesReceived(0) + , _messagesSent(0) + , _messagesLost(0) + , _messageSeq(0) + , _compID(0) + , _heardFrom(false) + , _rollFact (0, _rollFactName, FactMetaData::valueTypeDouble) + , _pitchFact (0, _pitchFactName, FactMetaData::valueTypeDouble) + , _headingFact (0, _headingFactName, FactMetaData::valueTypeDouble) + , _groundSpeedFact (0, _groundSpeedFactName, FactMetaData::valueTypeDouble) + , _airSpeedFact (0, _airSpeedFactName, FactMetaData::valueTypeDouble) + , _climbRateFact (0, _climbRateFactName, FactMetaData::valueTypeDouble) + , _altitudeRelativeFact (0, _altitudeRelativeFactName, FactMetaData::valueTypeDouble) + , _altitudeAMSLFact (0, _altitudeAMSLFactName, FactMetaData::valueTypeDouble) + , _gpsFactGroup(this) + , _batteryFactGroup(this) + , _windFactGroup(this) + , _vibrationFactGroup(this) +{ + // Build FactGroup object model + + _addFact(&_rollFact, _rollFactName); + _addFact(&_pitchFact, _pitchFactName); + _addFact(&_headingFact, _headingFactName); + _addFact(&_groundSpeedFact, _groundSpeedFactName); + _addFact(&_airSpeedFact, _airSpeedFactName); + _addFact(&_climbRateFact, _climbRateFactName); + _addFact(&_altitudeRelativeFact, _altitudeRelativeFactName); + _addFact(&_altitudeAMSLFact, _altitudeAMSLFactName); + + _addFactGroup(&_gpsFactGroup, _gpsFactGroupName); + _addFactGroup(&_batteryFactGroup, _batteryFactGroupName); + _addFactGroup(&_windFactGroup, _windFactGroupName); + _addFactGroup(&_vibrationFactGroup, _vibrationFactGroupName); + + _gpsFactGroup.setVehicle(NULL); + _batteryFactGroup.setVehicle(NULL); + _windFactGroup.setVehicle(NULL); + _vibrationFactGroup.setVehicle(NULL); +} + Vehicle::~Vehicle() { qCDebug(VehicleLog) << "~Vehicle" << this; @@ -399,6 +463,13 @@ void Vehicle::_handleSysStatus(mavlink_message_t& message) _batteryFactGroup.voltage()->setRawValue((double)sysStatus.voltage_battery / 1000.0); } _batteryFactGroup.percentRemaining()->setRawValue(sysStatus.battery_remaining); + + if (sysStatus.battery_remaining > 0 && sysStatus.battery_remaining < _batteryFactGroup.percentRemainingAnnounce()->rawValue().toInt()) { + if (!_lowBatteryAnnounceTimer.isValid() || _lowBatteryAnnounceTimer.elapsed() > _lowBatteryAnnounceRepeatMSecs) { + _lowBatteryAnnounceTimer.restart(); + _say(QString("Low battery on %1: %2 percent remaining").arg(_vehicleIdSpeech()).arg(sysStatus.battery_remaining)); + } + } } void Vehicle::_handleBatteryStatus(mavlink_message_t& message) @@ -1217,7 +1288,7 @@ void Vehicle::_connectionLostTimeout(void) _connectionLost = true; _heardFrom = false; emit connectionLostChanged(true); - _say(QString("connection lost to vehicle %1").arg(id()), GAudioOutput::AUDIO_SEVERITY_NOTICE); + _say(QString("communication lost to %1").arg(_vehicleIdSpeech())); if (_autoDisconnect) { disconnectInactiveVehicle(); } @@ -1230,14 +1301,13 @@ void Vehicle::_connectionActive(void) if (_connectionLost) { _connectionLost = false; emit connectionLostChanged(false); - _say(QString("connection regained to vehicle %1").arg(id()), GAudioOutput::AUDIO_SEVERITY_NOTICE); + _say(QString("communication regained to %1").arg(_vehicleIdSpeech())); } } -void Vehicle::_say(const QString& text, int severity) +void Vehicle::_say(const QString& text) { - if (!qgcApp()->runningUnitTests()) - qgcApp()->toolbox()->audioOutput()->say(text.toLower(), severity); + qgcApp()->toolbox()->audioOutput()->say(text.toLower()); } bool Vehicle::fixedWing(void) const @@ -1268,6 +1338,26 @@ void Vehicle::_setCoordinateValid(bool coordinateValid) } } +/// Returns the string to speak to identify the vehicle +QString Vehicle::_vehicleIdSpeech(void) +{ + if (qgcApp()->toolbox()->multiVehicleManager()->vehicles()->count() > 1) { + return QString("vehicle %1").arg(id()); + } else { + return QStringLiteral("vehicle"); + } +} + +void Vehicle::_announceflightModeChanged(const QString& flightMode) +{ + _say(QString("%1 is now in %2 flight mode").arg(_vehicleIdSpeech()).arg(flightMode)); +} + +const char* VehicleGPSFactGroup::_hdopFactName = "hdop"; +const char* VehicleGPSFactGroup::_vdopFactName = "vdop"; +const char* VehicleGPSFactGroup::_courseOverGroundFactName = "courseOverGround"; +const char* VehicleGPSFactGroup::_countFactName = "count"; +const char* VehicleGPSFactGroup::_lockFactName = "lock"; VehicleGPSFactGroup::VehicleGPSFactGroup(QObject* parent) : FactGroup(1000, ":/json/Vehicle/GPSFact.json", parent) @@ -1293,6 +1383,11 @@ void VehicleGPSFactGroup::setVehicle(Vehicle* vehicle) { _vehicle = vehicle; + if (!vehicle) { + // Disconnected Vehicle + return; + } + connect(_vehicle->uas(), &UASInterface::localizationChanged, this, &VehicleGPSFactGroup::_setSatLoc); UAS* pUas = dynamic_cast(_vehicle->uas()); @@ -1336,22 +1431,43 @@ void VehicleGPSFactGroup::_setSatLoc(UASInterface*, int fix) } } +const char* VehicleBatteryFactGroup::_voltageFactName = "voltage"; +const char* VehicleBatteryFactGroup::_percentRemainingFactName = "percentRemaining"; +const char* VehicleBatteryFactGroup::_percentRemainingAnnounceFactName = "percentRemainingAnnounce"; +const char* VehicleBatteryFactGroup::_mahConsumedFactName = "mahConsumed"; +const char* VehicleBatteryFactGroup::_currentFactName = "current"; +const char* VehicleBatteryFactGroup::_temperatureFactName = "temperature"; +const char* VehicleBatteryFactGroup::_cellCountFactName = "cellCount"; + +const char* VehicleBatteryFactGroup::_settingsGroup = "Vehicle.battery"; +const int VehicleBatteryFactGroup::_percentRemainingAnnounceDefault = 30; + +const double VehicleBatteryFactGroup::_voltageUnavailable = -1.0; +const int VehicleBatteryFactGroup::_percentRemainingUnavailable = -1; +const int VehicleBatteryFactGroup::_mahConsumedUnavailable = -1; +const int VehicleBatteryFactGroup::_currentUnavailable = -1; +const double VehicleBatteryFactGroup::_temperatureUnavailable = -1.0; +const int VehicleBatteryFactGroup::_cellCountUnavailable = -1.0; + +SettingsFact VehicleBatteryFactGroup::_percentRemainingAnnounceFact (_settingsGroup, _percentRemainingAnnounceFactName, FactMetaData::valueTypeInt32, _percentRemainingAnnounceDefault); + VehicleBatteryFactGroup::VehicleBatteryFactGroup(QObject* parent) : FactGroup(1000, ":/json/Vehicle/BatteryFact.json", parent) , _vehicle(NULL) - , _voltageFact (0, _voltageFactName, FactMetaData::valueTypeDouble) - , _percentRemainingFact (0, _percentRemainingFactName, FactMetaData::valueTypeInt32) - , _mahConsumedFact (0, _mahConsumedFactName, FactMetaData::valueTypeInt32) - , _currentFact (0, _currentFactName, FactMetaData::valueTypeInt32) - , _temperatureFact (0, _temperatureFactName, FactMetaData::valueTypeDouble) - , _cellCountFact (0, _cellCountFactName, FactMetaData::valueTypeInt32) -{ - _addFact(&_voltageFact, _voltageFactName); - _addFact(&_percentRemainingFact, _percentRemainingFactName); - _addFact(&_mahConsumedFact, _mahConsumedFactName); - _addFact(&_currentFact, _currentFactName); - _addFact(&_temperatureFact, _temperatureFactName); - _addFact(&_cellCountFact, _cellCountFactName); + , _voltageFact (0, _voltageFactName, FactMetaData::valueTypeDouble) + , _percentRemainingFact (0, _percentRemainingFactName, FactMetaData::valueTypeInt32) + , _mahConsumedFact (0, _mahConsumedFactName, FactMetaData::valueTypeInt32) + , _currentFact (0, _currentFactName, FactMetaData::valueTypeInt32) + , _temperatureFact (0, _temperatureFactName, FactMetaData::valueTypeDouble) + , _cellCountFact (0, _cellCountFactName, FactMetaData::valueTypeInt32) +{ + _addFact(&_voltageFact, _voltageFactName); + _addFact(&_percentRemainingFact, _percentRemainingFactName); + _addFact(&_percentRemainingAnnounceFact, _percentRemainingAnnounceFactName); + _addFact(&_mahConsumedFact, _mahConsumedFactName); + _addFact(&_currentFact, _currentFactName); + _addFact(&_temperatureFact, _temperatureFactName); + _addFact(&_cellCountFact, _cellCountFactName); // Start out as not available _voltageFact.setRawValue (_voltageUnavailable); @@ -1367,6 +1483,10 @@ void VehicleBatteryFactGroup::setVehicle(Vehicle* vehicle) _vehicle = vehicle; } +const char* VehicleWindFactGroup::_directionFactName = "direction"; +const char* VehicleWindFactGroup::_speedFactName = "speed"; +const char* VehicleWindFactGroup::_verticalSpeedFactName = "verticalSpeed"; + VehicleWindFactGroup::VehicleWindFactGroup(QObject* parent) : FactGroup(1000, ":/json/Vehicle/WindFact.json", parent) , _vehicle(NULL) @@ -1389,6 +1509,13 @@ void VehicleWindFactGroup::setVehicle(Vehicle* vehicle) _vehicle = vehicle; } +const char* VehicleVibrationFactGroup::_xAxisFactName = "xAxis"; +const char* VehicleVibrationFactGroup::_yAxisFactName = "yAxis"; +const char* VehicleVibrationFactGroup::_zAxisFactName = "zAxis"; +const char* VehicleVibrationFactGroup::_clipCount1FactName = "clipCount1"; +const char* VehicleVibrationFactGroup::_clipCount2FactName = "clipCount2"; +const char* VehicleVibrationFactGroup::_clipCount3FactName = "clipCount3"; + VehicleVibrationFactGroup::VehicleVibrationFactGroup(QObject* parent) : FactGroup(1000, ":/json/Vehicle/VibrationFact.json", parent) , _vehicle(NULL) diff --git a/src/Vehicle/Vehicle.h b/src/Vehicle/Vehicle.h index 84522cd6c4dfbf4d53f82c914713cd40ba550353..96d43c379f02d7323f05db413587ef1affc5d083 100644 --- a/src/Vehicle/Vehicle.h +++ b/src/Vehicle/Vehicle.h @@ -29,6 +29,7 @@ #include #include +#include #include "FactGroup.h" #include "LinkInterface.h" @@ -36,6 +37,7 @@ #include "QmlObjectListModel.h" #include "MAVLinkProtocol.h" #include "UASMessageHandler.h" +#include "SettingsFact.h" class UAS; class UASInterface; @@ -66,12 +68,12 @@ public: Q_PROPERTY(Fact* clipCount2 READ clipCount2 CONSTANT) Q_PROPERTY(Fact* clipCount3 READ clipCount3 CONSTANT) - Fact* xAxis(void) { return &_xAxisFact; } - Fact* yAxis(void) { return &_yAxisFact; } - Fact* zAxis(void) { return &_zAxisFact; } - Fact* clipCount1(void) { return &_clipCount1Fact; } - Fact* clipCount2(void) { return &_clipCount2Fact; } - Fact* clipCount3(void) { return &_clipCount3Fact; } + Fact* xAxis (void) { return &_xAxisFact; } + Fact* yAxis (void) { return &_yAxisFact; } + Fact* zAxis (void) { return &_zAxisFact; } + Fact* clipCount1 (void) { return &_clipCount1Fact; } + Fact* clipCount2 (void) { return &_clipCount2Fact; } + Fact* clipCount3 (void) { return &_clipCount3Fact; } void setVehicle(Vehicle* vehicle); @@ -103,9 +105,9 @@ public: Q_PROPERTY(Fact* speed READ speed CONSTANT) Q_PROPERTY(Fact* verticalSpeed READ verticalSpeed CONSTANT) - Fact* direction(void) { return &_directionFact; } - Fact* speed(void) { return &_speedFact; } - Fact* verticalSpeed(void) { return &_verticalSpeedFact; } + Fact* direction (void) { return &_directionFact; } + Fact* speed (void) { return &_speedFact; } + Fact* verticalSpeed (void) { return &_verticalSpeedFact; } void setVehicle(Vehicle* vehicle); @@ -133,11 +135,11 @@ public: Q_PROPERTY(Fact* count READ count CONSTANT) Q_PROPERTY(Fact* lock READ lock CONSTANT) - Fact* hdop(void) { return &_hdopFact; } - Fact* vdop(void) { return &_vdopFact; } - Fact* courseOverGround(void) { return &_courseOverGroundFact; } - Fact* count(void) { return &_countFact; } - Fact* lock(void) { return &_lockFact; } + Fact* hdop (void) { return &_hdopFact; } + Fact* vdop (void) { return &_vdopFact; } + Fact* courseOverGround (void) { return &_courseOverGroundFact; } + Fact* count (void) { return &_countFact; } + Fact* lock (void) { return &_lockFact; } void setVehicle(Vehicle* vehicle); @@ -175,24 +177,33 @@ public: Q_PROPERTY(Fact* mahConsumed READ mahConsumed CONSTANT) Q_PROPERTY(Fact* current READ current CONSTANT) Q_PROPERTY(Fact* temperature READ temperature CONSTANT) - Q_PROPERTY(Fact* cellCount READ cellCount CONSTANT) + Q_PROPERTY(Fact* cellCount READ cellCount CONSTANT) + + /// If percentRemaining falls below this value, warning will be output through speech + Q_PROPERTY(Fact* percentRemainingAnnounce READ percentRemainingAnnounce CONSTANT) + + Fact* voltage (void) { return &_voltageFact; } + Fact* percentRemaining (void) { return &_percentRemainingFact; } + Fact* percentRemainingAnnounce (void) { return &_percentRemainingAnnounceFact; } + Fact* mahConsumed (void) { return &_mahConsumedFact; } + Fact* current (void) { return &_currentFact; } + Fact* temperature (void) { return &_temperatureFact; } + Fact* cellCount (void) { return &_cellCountFact; } - Fact* voltage(void) { return &_voltageFact; } - Fact* percentRemaining(void) { return &_percentRemainingFact; } - Fact* mahConsumed(void) { return &_mahConsumedFact; } - Fact* current(void) { return &_currentFact; } - Fact* temperature(void) { return &_temperatureFact; } - Fact* cellCount(void) { return &_cellCountFact; } void setVehicle(Vehicle* vehicle); static const char* _voltageFactName; static const char* _percentRemainingFactName; + static const char* _percentRemainingAnnounceFactName; static const char* _mahConsumedFactName; static const char* _currentFactName; static const char* _temperatureFactName; static const char* _cellCountFactName; + static const char* _settingsGroup; + static const int _percentRemainingAnnounceDefault; + static const double _voltageUnavailable; static const int _percentRemainingUnavailable; static const int _mahConsumedUnavailable; @@ -201,13 +212,15 @@ public: static const int _cellCountUnavailable; private: - Vehicle* _vehicle; - Fact _voltageFact; - Fact _percentRemainingFact; - Fact _mahConsumedFact; - Fact _currentFact; - Fact _temperatureFact; - Fact _cellCountFact; + Vehicle* _vehicle; + Fact _voltageFact; + Fact _percentRemainingFact; + Fact _mahConsumedFact; + Fact _currentFact; + Fact _temperatureFact; + Fact _cellCountFact; + + static SettingsFact _percentRemainingAnnounceFact; }; class Vehicle : public FactGroup @@ -222,6 +235,11 @@ public: FirmwarePluginManager* firmwarePluginManager, AutoPilotPluginManager* autopilotPluginManager, JoystickManager* joystickManager); + + // The following is used to create a disconnected Vehicle. A disconnected vehicle is primarily used to access FactGroup information + // without needing a real connection. + Vehicle(QObject* parent = NULL); + ~Vehicle(); Q_PROPERTY(int id READ id CONSTANT) @@ -505,6 +523,7 @@ private slots: void _addNewMapTrajectoryPoint(void); void _parametersReady(bool parametersReady); void _remoteControlRSSIChanged(uint8_t rssi); + void _announceflightModeChanged(const QString& flightMode); void _handleTextMessage (int newCount); void _handletextMessageReceived (UASMessage* message); @@ -540,11 +559,13 @@ private: void _mapTrajectoryStart(void); void _mapTrajectoryStop(void); void _connectionActive(void); - void _say(const QString& text, int severity); + void _say(const QString& text); + QString _vehicleIdSpeech(void); private: int _id; ///< Mavlink system id bool _active; + bool _disconnectedVehicle; ///< This Vehicle is a "disconnected" vehicle for ui use when no active vehicle is available MAV_AUTOPILOT _firmwareType; MAV_TYPE _vehicleType; @@ -635,6 +656,9 @@ private: uint8_t _compID; bool _heardFrom; + static const int _lowBatteryAnnounceRepeatMSecs; // Amount of time in between each low battery announcement + QElapsedTimer _lowBatteryAnnounceTimer; + // FactGroup facts Fact _rollFact; diff --git a/src/ui/preferences/GeneralSettings.qml b/src/ui/preferences/GeneralSettings.qml index a4c8e27a9c7df78ab7aebb4a7e869e3bb85896b8..04b361b9ddfc5c56aab42ba93af6a7805d5f03da 100644 --- a/src/ui/preferences/GeneralSettings.qml +++ b/src/ui/preferences/GeneralSettings.qml @@ -40,6 +40,8 @@ Rectangle { anchors.fill: parent anchors.margins: ScreenTools.defaultFontPixelWidth + property Fact _percentRemainingAnnounce: QGroundControl.multiVehicleManager.disconnectedVehicle.battery.percentRemainingAnnounce + QGCPalette { id: qgcPal colorGroupEnabled: enabled @@ -127,6 +129,32 @@ Rectangle { } } } + //----------------------------------------------------------------- + //-- Battery talker + Row { + spacing: ScreenTools.defaultFontPixelWidth + + QGCCheckBox { + id: announcePercentCheckbox + anchors.baseline: announcePercent.baseline + text: "Announce battery percent lower than:" + checked: _percentRemainingAnnounce.value != 0 + + onClicked: { + if (checked) { + _percentRemainingAnnounce.value = _percentRemainingAnnounce.defaultValueString + } else { + _percentRemainingAnnounce.value = 0 + } + } + } + + FactTextField { + id: announcePercent + fact: _percentRemainingAnnounce + enabled: announcePercentCheckbox.checked + } + } Item { height: ScreenTools.defaultFontPixelHeight / 2