From c16f69e6ca14778e5b2a9e2f9ea82e009fb1c4d5 Mon Sep 17 00:00:00 2001
From: Don Gagne <don@thegagnes.com>
Date: Sun, 13 Dec 2015 20:19:28 -0800
Subject: [PATCH] APM Safety Config

---
 qgroundcontrol.pro                            |   2 +
 qgroundcontrol.qrc                            |   7 +
 .../APM/APMAutoPilotPlugin.cc                 |  10 +
 src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h |   3 +
 src/AutoPilotPlugins/APM/APMNotSupported.qml  |  33 +++
 .../APM/APMSafetyComponent.cc                 | 149 ++++++++++++++
 src/AutoPilotPlugins/APM/APMSafetyComponent.h |  56 +++++
 .../APM/APMSafetyComponentCopter.qml          | 193 ++++++++++++++++++
 .../APM/APMSafetyComponentPlane.qml           |  33 +++
 .../APM/APMSafetyComponentRover.qml           |  33 +++
 .../APM/APMSafetyComponentSummaryCopter.qml   |  46 +++++
 .../APM/APMSafetyComponentSummaryPlane.qml    |  33 +++
 .../APM/APMSafetyComponentSummaryRover.qml    |  33 +++
 13 files changed, 631 insertions(+)
 create mode 100644 src/AutoPilotPlugins/APM/APMNotSupported.qml
 create mode 100644 src/AutoPilotPlugins/APM/APMSafetyComponent.cc
 create mode 100644 src/AutoPilotPlugins/APM/APMSafetyComponent.h
 create mode 100644 src/AutoPilotPlugins/APM/APMSafetyComponentCopter.qml
 create mode 100644 src/AutoPilotPlugins/APM/APMSafetyComponentPlane.qml
 create mode 100644 src/AutoPilotPlugins/APM/APMSafetyComponentRover.qml
 create mode 100644 src/AutoPilotPlugins/APM/APMSafetyComponentSummaryCopter.qml
 create mode 100644 src/AutoPilotPlugins/APM/APMSafetyComponentSummaryPlane.qml
 create mode 100644 src/AutoPilotPlugins/APM/APMSafetyComponentSummaryRover.qml

diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro
index 9d95909a76..0e69320ad9 100644
--- a/qgroundcontrol.pro
+++ b/qgroundcontrol.pro
@@ -554,6 +554,7 @@ HEADERS+= \
     src/AutoPilotPlugins/APM/APMRadioComponent.h \
     src/AutoPilotPlugins/APM/APMFlightModesComponent.h \
     src/AutoPilotPlugins/APM/APMFlightModesComponentController.h \
+    src/AutoPilotPlugins/APM/APMSafetyComponent.h \
     src/AutoPilotPlugins/APM/APMSensorsComponent.h \
     src/AutoPilotPlugins/APM/APMSensorsComponentController.h \
     src/AutoPilotPlugins/Common/RadioComponentController.h \
@@ -603,6 +604,7 @@ SOURCES += \
     src/AutoPilotPlugins/APM/APMRadioComponent.cc \
     src/AutoPilotPlugins/APM/APMFlightModesComponent.cc \
     src/AutoPilotPlugins/APM/APMFlightModesComponentController.cc \
+    src/AutoPilotPlugins/APM/APMSafetyComponent.cc \
     src/AutoPilotPlugins/APM/APMSensorsComponent.cc \
     src/AutoPilotPlugins/APM/APMSensorsComponentController.cc \
     src/AutoPilotPlugins/Common/RadioComponentController.cc \
diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc
index d48a6f478b..adfbf599b2 100644
--- a/qgroundcontrol.qrc
+++ b/qgroundcontrol.qrc
@@ -105,7 +105,14 @@
         <file alias="QmlTest.qml">src/QmlControls/QmlTest.qml</file>
         <file alias="RadioComponent.qml">src/AutoPilotPlugins/Common/RadioComponent.qml</file>
         <file alias="PX4RadioComponentSummary.qml">src/AutoPilotPlugins/PX4/PX4RadioComponentSummary.qml</file>
+        <file alias="APMNotSupported.qml">src/AutoPilotPlugins/APM/APMNotSupported.qml</file>
         <file alias="APMRadioComponentSummary.qml">src/AutoPilotPlugins/APM/APMRadioComponentSummary.qml</file>
+        <file alias="APMSafetyComponentCopter.qml">src/AutoPilotPlugins/APM/APMSafetyComponentCopter.qml</file>
+        <file alias="APMSafetyComponentPlane.qml">src/AutoPilotPlugins/APM/APMSafetyComponentPlane.qml</file>
+        <file alias="APMSafetyComponentRover.qml">src/AutoPilotPlugins/APM/APMSafetyComponentRover.qml</file>
+        <file alias="APMSafetyComponentSummaryCopter.qml">src/AutoPilotPlugins/APM/APMSafetyComponentSummaryCopter.qml</file>
+        <file alias="APMSafetyComponentSummaryPlane.qml">src/AutoPilotPlugins/APM/APMSafetyComponentSummaryPlane.qml</file>
+        <file alias="APMSafetyComponentSummaryRover.qml">src/AutoPilotPlugins/APM/APMSafetyComponentSummaryRover.qml</file>
         <file alias="SafetyComponent.qml">src/AutoPilotPlugins/PX4/SafetyComponent.qml</file>
         <file alias="SafetyComponentSummary.qml">src/AutoPilotPlugins/PX4/SafetyComponentSummary.qml</file>
         <file alias="SensorsComponent.qml">src/AutoPilotPlugins/PX4/SensorsComponent.qml</file>
diff --git a/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc b/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc
index 93d9fe19ee..13bbce599d 100644
--- a/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc
+++ b/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc
@@ -34,6 +34,8 @@ APMAutoPilotPlugin::APMAutoPilotPlugin(Vehicle* vehicle, QObject* parent)
     , _airframeComponent(NULL)
     , _flightModesComponent(NULL)
     , _radioComponent(NULL)
+    , _safetyComponent(NULL)
+    , _sensorsComponent(NULL)
 {
     Q_ASSERT(vehicle);
 }
@@ -80,6 +82,14 @@ const QVariantList& APMAutoPilotPlugin::vehicleComponents(void)
             } else {
                 qWarning() << "new APMSensorsComponent failed";
             }
+
+            _safetyComponent = new APMSafetyComponent(_vehicle, this);
+            if (_safetyComponent) {
+                _safetyComponent->setupTriggerSignals();
+                _components.append(QVariant::fromValue((VehicleComponent*)_safetyComponent));
+            } else {
+                qWarning() << "new APMSafetyComponent failed";
+            }
         } else {
             qWarning() << "Call to vehicleCompenents prior to parametersReady";
         }
diff --git a/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h b/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h
index 93b564812d..41f081c56a 100644
--- a/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h
+++ b/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h
@@ -29,6 +29,7 @@
 #include "APMAirframeComponent.h"
 #include "APMFlightModesComponent.h"
 #include "APMRadioComponent.h"
+#include "APMSafetyComponent.h"
 #include "APMSensorsComponent.h"
 
 /// This is the APM specific implementation of the AutoPilot class.
@@ -46,6 +47,7 @@ public:
     APMAirframeComponent*       airframeComponent   (void) { return _airframeComponent; }
     APMFlightModesComponent*    flightModesComponent(void) { return _flightModesComponent; }
     APMRadioComponent*          radioComponent      (void) { return _radioComponent; }
+    APMSafetyComponent*         safetyComponent     (void) { return _safetyComponent; }
     APMSensorsComponent*        sensorsComponent    (void) { return _sensorsComponent; }
 
 public slots:
@@ -59,6 +61,7 @@ private:
     APMAirframeComponent*       _airframeComponent;
     APMFlightModesComponent*    _flightModesComponent;
     APMRadioComponent*          _radioComponent;
+    APMSafetyComponent*         _safetyComponent;
     APMSensorsComponent*        _sensorsComponent;
 };
 
diff --git a/src/AutoPilotPlugins/APM/APMNotSupported.qml b/src/AutoPilotPlugins/APM/APMNotSupported.qml
new file mode 100644
index 0000000000..ace3b3a1d4
--- /dev/null
+++ b/src/AutoPilotPlugins/APM/APMNotSupported.qml
@@ -0,0 +1,33 @@
+/*=====================================================================
+
+ QGroundControl Open Source Ground Control Station
+
+ (c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
+
+ This file is part of the QGROUNDCONTROL project
+
+ QGROUNDCONTROL is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ QGROUNDCONTROL is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
+
+ ======================================================================*/
+
+import QtQuick 2.5
+
+import QGroundControl.Controls 1.0
+
+QGCLabel {
+    anchors.fill:           parent
+    text:                   "Not supported"
+    horizontalAlignment:    Text.AlignHCenter
+    verticalAlignment:      Text.AlignVCenter
+}
diff --git a/src/AutoPilotPlugins/APM/APMSafetyComponent.cc b/src/AutoPilotPlugins/APM/APMSafetyComponent.cc
new file mode 100644
index 0000000000..4d18ab7610
--- /dev/null
+++ b/src/AutoPilotPlugins/APM/APMSafetyComponent.cc
@@ -0,0 +1,149 @@
+/*=====================================================================
+
+ QGroundControl Open Source Ground Control Station
+
+ (c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
+
+ This file is part of the QGROUNDCONTROL project
+
+ QGROUNDCONTROL is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ QGROUNDCONTROL is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
+
+ ======================================================================*/
+
+/// @file
+///     @author Don Gagne <don@thegagnes.com>
+
+#include "APMSafetyComponent.h"
+#include "QGCQmlWidgetHolder.h"
+#include "APMAutoPilotPlugin.h"
+
+APMSafetyComponent::APMSafetyComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent)
+    : APMComponent(vehicle, autopilot, parent)
+    , _name(tr("Safety"))
+{
+}
+
+QString APMSafetyComponent::name(void) const
+{
+    return _name;
+}
+
+QString APMSafetyComponent::description(void) const
+{
+    return tr("The Safety Component is used to setup triggers for Return to Land as well as the settings for Return to Land itself.");
+}
+
+QString APMSafetyComponent::iconResource(void) const
+{
+    return "/qmlimages/SafetyComponentIcon.png";
+}
+
+bool APMSafetyComponent::requiresSetup(void) const
+{
+    return false;
+}
+
+bool APMSafetyComponent::setupComplete(void) const
+{
+    // FIXME: What aboout invalid settings?
+    return true;
+}
+
+QString APMSafetyComponent::setupStateDescription(void) const
+{
+    const char* stateDescription;
+
+    if (requiresSetup()) {
+        stateDescription = "Requires setup";
+    } else {
+        stateDescription = "Setup complete";
+    }
+    return QString(stateDescription);
+}
+
+QStringList APMSafetyComponent::setupCompleteChangedTriggerList(void) const
+{
+    return QStringList();
+}
+
+QStringList APMSafetyComponent::paramFilterList(void) const
+{
+    return QStringList();
+}
+
+QUrl APMSafetyComponent::setupSource(void) const
+{
+    QString qmlFile;
+
+    switch (_vehicle->vehicleType()) {
+        case MAV_TYPE_FIXED_WING:
+            qmlFile = "qrc:/qml/APMSafetyComponentPlane.qml";
+            break;
+        case MAV_TYPE_QUADROTOR:
+        case MAV_TYPE_COAXIAL:
+        case MAV_TYPE_HELICOPTER:
+        case MAV_TYPE_HEXAROTOR:
+        case MAV_TYPE_OCTOROTOR:
+        case MAV_TYPE_TRICOPTER:
+            qmlFile = "qrc:/qml/APMSafetyComponentCopter.qml";
+            break;
+        case MAV_TYPE_GROUND_ROVER:
+            qmlFile = "qrc:/qml/APMSafetyComponentRover.qml";
+            break;
+        default:
+            qmlFile = "qrc:/qml/APMNotSupported.qml";
+            break;
+    }
+
+    return QUrl::fromUserInput(qmlFile);
+}
+
+QUrl APMSafetyComponent::summaryQmlSource(void) const
+{
+    QString qmlFile;
+
+    switch (_vehicle->vehicleType()) {
+        case MAV_TYPE_FIXED_WING:
+            qmlFile = "qrc:/qml/APMSafetyComponentSummaryPlane.qml";
+            break;
+        case MAV_TYPE_QUADROTOR:
+        case MAV_TYPE_COAXIAL:
+        case MAV_TYPE_HELICOPTER:
+        case MAV_TYPE_HEXAROTOR:
+        case MAV_TYPE_OCTOROTOR:
+        case MAV_TYPE_TRICOPTER:
+            qmlFile = "qrc:/qml/APMSafetyComponentSummaryCopter.qml";
+            break;
+        case MAV_TYPE_GROUND_ROVER:
+            qmlFile = "qrc:/qml/APMSafetyComponentSummaryRover.qml";
+            break;
+        default:
+            qmlFile = "qrc:/qml/APMNotSupported.qml";
+            break;
+    }
+
+    return QUrl::fromUserInput(qmlFile);
+}
+
+QString APMSafetyComponent::prerequisiteSetup(void) const
+{
+    APMAutoPilotPlugin* plugin = dynamic_cast<APMAutoPilotPlugin*>(_autopilot);
+    Q_ASSERT(plugin);
+
+    if (!plugin->airframeComponent()->setupComplete()) {
+        return plugin->airframeComponent()->name();
+    }
+
+    return QString();
+}
diff --git a/src/AutoPilotPlugins/APM/APMSafetyComponent.h b/src/AutoPilotPlugins/APM/APMSafetyComponent.h
new file mode 100644
index 0000000000..bb8ed68d8b
--- /dev/null
+++ b/src/AutoPilotPlugins/APM/APMSafetyComponent.h
@@ -0,0 +1,56 @@
+/*=====================================================================
+ 
+ QGroundControl Open Source Ground Control Station
+ 
+ (c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
+ 
+ This file is part of the QGROUNDCONTROL project
+ 
+ QGROUNDCONTROL is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+ 
+ QGROUNDCONTROL is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
+ 
+ ======================================================================*/
+
+#ifndef APMSafetyComponent_H
+#define APMSafetyComponent_H
+
+#include "APMComponent.h"
+
+class APMSafetyComponent : public APMComponent
+{
+    Q_OBJECT
+    
+public:
+    APMSafetyComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent = NULL);
+    
+    // Virtuals from PX4Component
+    virtual QStringList setupCompleteChangedTriggerList(void) const;
+    
+    // Virtuals from VehicleComponent
+    virtual QString name(void) const;
+    virtual QString description(void) const;
+    virtual QString iconResource(void) const;
+    virtual bool requiresSetup(void) const;
+    virtual bool setupComplete(void) const;
+    virtual QString setupStateDescription(void) const;
+    virtual QUrl setupSource(void) const;
+    virtual QStringList paramFilterList(void) const;
+    virtual QUrl summaryQmlSource(void) const;
+    virtual QString prerequisiteSetup(void) const;
+    
+private:
+    const QString   _name;
+    QVariantList    _summaryItems;
+};
+
+#endif
diff --git a/src/AutoPilotPlugins/APM/APMSafetyComponentCopter.qml b/src/AutoPilotPlugins/APM/APMSafetyComponentCopter.qml
new file mode 100644
index 0000000000..a7267ba06a
--- /dev/null
+++ b/src/AutoPilotPlugins/APM/APMSafetyComponentCopter.qml
@@ -0,0 +1,193 @@
+/*=====================================================================
+
+ QGroundControl Open Source Ground Control Station
+
+ (c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
+
+ This file is part of the QGROUNDCONTROL project
+
+ QGROUNDCONTROL is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ QGROUNDCONTROL is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
+
+ ======================================================================*/
+
+import QtQuick              2.5
+import QtQuick.Controls     1.2
+import QtGraphicalEffects   1.0
+
+import QGroundControl.FactSystem    1.0
+import QGroundControl.FactControls  1.0
+import QGroundControl.Palette       1.0
+import QGroundControl.Controls      1.0
+import QGroundControl.ScreenTools   1.0
+
+QGCView {
+    id:                 _safetyView
+    viewPanel:          panel
+    anchors.fill:       parent
+
+    FactPanelController { id: controller; factPanel: panel }
+
+    QGCPalette { id: palette; colorGroupEnabled: enabled }
+
+    property Fact _landSpeedFact:   controller.getParameterFact(-1, "LAND_SPEED")
+    property Fact _rtlAltFact:      controller.getParameterFact(-1, "RTL_ALT")
+    property Fact _rtlLoitTimeFact: controller.getParameterFact(-1, "RTL_LOIT_TIME")
+    property Fact _rtlAltFinalFact: controller.getParameterFact(-1, "RTL_ALT_FINAL")
+
+    property real _margins: ScreenTools.defaultFontPixelHeight
+
+    ExclusiveGroup { id: landLoiterRadioGroup }
+    ExclusiveGroup { id: returnAltRadioGroup }
+
+    QGCViewPanel {
+        id:             panel
+        anchors.fill:   parent
+
+        Flickable {
+            clip:               true
+            anchors.fill:       parent
+            boundsBehavior:     Flickable.StopAtBounds
+            flickableDirection: Flickable.VerticalFlick
+
+            QGCLabel {
+                id:         rtlLabel
+                text:       "Return Home Settings"
+                font.weight: Font.DemiBold
+            }
+
+            Rectangle {
+                anchors.topMargin:  _margins / 2
+                anchors.left:       parent.left
+                anchors.right:      parent.right
+                anchors.top:        rtlLabel.bottom
+                height:             rltAltFinalField.y + rltAltFinalField.height + _margins
+                color:              palette.windowShade
+
+                Image {
+                    id:                 icon
+                    anchors.margins:    _margins
+                    anchors.left:       parent.left
+                    anchors.top:        parent.top
+                    height:             ScreenTools.defaultFontPixelWidth * 20
+                    width:              ScreenTools.defaultFontPixelWidth * 20
+                    mipmap:             true
+                    fillMode:           Image.PreserveAspectFit
+                    visible:            false
+                    source:             "/qmlimages/ReturnToHomeAltitude.svg"
+                }
+
+                ColorOverlay {
+                    anchors.fill:   icon
+                    source:         icon
+                    color:          palette.text
+                }
+
+                QGCRadioButton {
+                    id:                 returnAtCurrentRadio
+                    anchors.leftMargin: _margins
+                    anchors.left:       icon.right
+                    anchors.top:        icon.top
+                    text:               "Return at current altitude"
+                    checked:            _rtlAltFact.value == 0
+                    exclusiveGroup:     returnAltRadioGroup
+
+                    onClicked: _rtlAltFact.value = 0
+                }
+
+                QGCRadioButton {
+                    id:                 returnAltRadio
+                    anchors.topMargin:  _margins
+                    anchors.left:       returnAtCurrentRadio.left
+                    anchors.top:        returnAtCurrentRadio.bottom
+                    text:               "Return at specified altitude:"
+                    exclusiveGroup:     returnAltRadioGroup
+                    checked:            _rtlAltFact.value != 0
+
+                    onClicked: _rtlAltFact.value = 1500
+                }
+
+                FactTextField {
+                    id:                 rltAltField
+                    anchors.leftMargin: _margins
+                    anchors.left:       returnAltRadio.right
+                    anchors.baseline:   returnAltRadio.baseline
+                    fact:               _rtlAltFact
+                    showUnits:          true
+                    enabled:            returnAltRadio.checked
+                }
+
+                QGCCheckBox {
+                    id:                 homeLoiterCheckbox
+                    anchors.left:       returnAtCurrentRadio.left
+                    anchors.baseline:   landDelayField.baseline
+                    checked:            _rtlLoitTimeFact.value > 0
+                    text:               "Loiter above Home for:"
+
+                    onClicked: _rtlLoitTimeFact.value = checked ? 60 : 0
+                }
+
+                FactTextField {
+                    id:                 landDelayField
+                    anchors.topMargin:  _margins * 1.5
+                    anchors.left:       rltAltField.left
+                    anchors.top:        rltAltField.bottom
+                    fact:               _rtlLoitTimeFact
+                    showUnits:          true
+                    enabled:            homeLoiterCheckbox.checked === true
+                }
+
+                QGCRadioButton {
+                    id:                 landRadio
+                    anchors.left:       returnAtCurrentRadio.left
+                    anchors.baseline:   landSpeedField.baseline
+                    text:               "Land with descent speed:"
+                    checked:            _rtlAltFinalFact.value == 0
+                    exclusiveGroup:     landLoiterRadioGroup
+
+                    onClicked: _rtlAltFinalFact.value = 0
+                }
+
+                FactTextField {
+                    id:                 landSpeedField
+                    anchors.topMargin:  _margins * 1.5
+                    anchors.top:        landDelayField.bottom
+                    anchors.left:       rltAltField.left
+                    fact:               _landSpeedFact
+                    showUnits:          true
+                    enabled:            landRadio.checked
+                }
+
+                QGCRadioButton {
+                    id:                 finalLoiterRadio
+                    anchors.left:       returnAtCurrentRadio.left
+                    anchors.baseline:   rltAltFinalField.baseline
+                    text:               "Final loiter altitude:"
+                    exclusiveGroup:     landLoiterRadioGroup
+
+                    onClicked: _rtlAltFinalFact.value = _rtlAltFact.value
+                }
+
+                FactTextField {
+                    id:                 rltAltFinalField
+                    anchors.topMargin:  _margins / 2
+                    anchors.left:       rltAltField.left
+                    anchors.top:        landSpeedField.bottom
+                    fact:               _rtlAltFinalFact
+                    enabled:            finalLoiterRadio.checked
+                    showUnits:          true
+                }
+            } // Rectangle - RTL Settings
+        } // Flickable
+    } // QGCViewPanel
+} // QGCView
diff --git a/src/AutoPilotPlugins/APM/APMSafetyComponentPlane.qml b/src/AutoPilotPlugins/APM/APMSafetyComponentPlane.qml
new file mode 100644
index 0000000000..ace3b3a1d4
--- /dev/null
+++ b/src/AutoPilotPlugins/APM/APMSafetyComponentPlane.qml
@@ -0,0 +1,33 @@
+/*=====================================================================
+
+ QGroundControl Open Source Ground Control Station
+
+ (c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
+
+ This file is part of the QGROUNDCONTROL project
+
+ QGROUNDCONTROL is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ QGROUNDCONTROL is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
+
+ ======================================================================*/
+
+import QtQuick 2.5
+
+import QGroundControl.Controls 1.0
+
+QGCLabel {
+    anchors.fill:           parent
+    text:                   "Not supported"
+    horizontalAlignment:    Text.AlignHCenter
+    verticalAlignment:      Text.AlignVCenter
+}
diff --git a/src/AutoPilotPlugins/APM/APMSafetyComponentRover.qml b/src/AutoPilotPlugins/APM/APMSafetyComponentRover.qml
new file mode 100644
index 0000000000..ace3b3a1d4
--- /dev/null
+++ b/src/AutoPilotPlugins/APM/APMSafetyComponentRover.qml
@@ -0,0 +1,33 @@
+/*=====================================================================
+
+ QGroundControl Open Source Ground Control Station
+
+ (c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
+
+ This file is part of the QGROUNDCONTROL project
+
+ QGROUNDCONTROL is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ QGROUNDCONTROL is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
+
+ ======================================================================*/
+
+import QtQuick 2.5
+
+import QGroundControl.Controls 1.0
+
+QGCLabel {
+    anchors.fill:           parent
+    text:                   "Not supported"
+    horizontalAlignment:    Text.AlignHCenter
+    verticalAlignment:      Text.AlignVCenter
+}
diff --git a/src/AutoPilotPlugins/APM/APMSafetyComponentSummaryCopter.qml b/src/AutoPilotPlugins/APM/APMSafetyComponentSummaryCopter.qml
new file mode 100644
index 0000000000..c99126de25
--- /dev/null
+++ b/src/AutoPilotPlugins/APM/APMSafetyComponentSummaryCopter.qml
@@ -0,0 +1,46 @@
+import QtQuick 2.2
+import QtQuick.Controls 1.2
+
+import QGroundControl.FactSystem 1.0
+import QGroundControl.FactControls 1.0
+import QGroundControl.Controls 1.0
+import QGroundControl.Palette 1.0
+
+FactPanel {
+    id:             panel
+    anchors.fill:   parent
+    color:          qgcPal.windowShadeDark
+
+    QGCPalette { id: qgcPal; colorGroupEnabled: enabled }
+    FactPanelController { id: controller; factPanel: panel }
+
+    property Fact _rtlAltFact:      controller.getParameterFact(-1, "RTL_ALT")
+    property Fact _rtlLoitTimeFact: controller.getParameterFact(-1, "RTL_LOIT_TIME")
+    property Fact _rtlAltFinalFact: controller.getParameterFact(-1, "RTL_ALT_FINAL")
+    property Fact _landSpeedFact:   controller.getParameterFact(-1, "LAND_SPEED")
+
+    Column {
+        anchors.fill:       parent
+        anchors.margins:    8
+
+        VehicleSummaryRow {
+            labelText: "RTL min alt:"
+            valueText: _rtlAltFact.value == 0 ? "current" : _rtlAltFact.valueString
+        }
+
+        VehicleSummaryRow {
+            labelText: "RTL loiter time:"
+            valueText: _rtlLoitTimeFact.valueString
+        }
+
+        VehicleSummaryRow {
+            labelText: "RTL final alt:"
+            valueText: _rtlAltFinalFact.value == 0 ? "Land" : _rtlAltFinalFact.valueString
+        }
+
+        VehicleSummaryRow {
+            labelText: "Descent speed:"
+            valueText: _landSpeedFact.valueString
+        }
+    }
+}
diff --git a/src/AutoPilotPlugins/APM/APMSafetyComponentSummaryPlane.qml b/src/AutoPilotPlugins/APM/APMSafetyComponentSummaryPlane.qml
new file mode 100644
index 0000000000..ace3b3a1d4
--- /dev/null
+++ b/src/AutoPilotPlugins/APM/APMSafetyComponentSummaryPlane.qml
@@ -0,0 +1,33 @@
+/*=====================================================================
+
+ QGroundControl Open Source Ground Control Station
+
+ (c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
+
+ This file is part of the QGROUNDCONTROL project
+
+ QGROUNDCONTROL is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ QGROUNDCONTROL is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
+
+ ======================================================================*/
+
+import QtQuick 2.5
+
+import QGroundControl.Controls 1.0
+
+QGCLabel {
+    anchors.fill:           parent
+    text:                   "Not supported"
+    horizontalAlignment:    Text.AlignHCenter
+    verticalAlignment:      Text.AlignVCenter
+}
diff --git a/src/AutoPilotPlugins/APM/APMSafetyComponentSummaryRover.qml b/src/AutoPilotPlugins/APM/APMSafetyComponentSummaryRover.qml
new file mode 100644
index 0000000000..ace3b3a1d4
--- /dev/null
+++ b/src/AutoPilotPlugins/APM/APMSafetyComponentSummaryRover.qml
@@ -0,0 +1,33 @@
+/*=====================================================================
+
+ QGroundControl Open Source Ground Control Station
+
+ (c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
+
+ This file is part of the QGROUNDCONTROL project
+
+ QGROUNDCONTROL is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ QGROUNDCONTROL is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
+
+ ======================================================================*/
+
+import QtQuick 2.5
+
+import QGroundControl.Controls 1.0
+
+QGCLabel {
+    anchors.fill:           parent
+    text:                   "Not supported"
+    horizontalAlignment:    Text.AlignHCenter
+    verticalAlignment:      Text.AlignVCenter
+}
-- 
GitLab