Skip to content
RadioComponent.qml 19.5 KiB
Newer Older
/****************************************************************************
 *
 *   (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/
import QtQuick          2.3
import QtQuick.Controls 1.2
Don Gagne's avatar
Don Gagne committed
import QtQuick.Dialogs  1.2
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
import QGroundControl               1.0
import QGroundControl.FactSystem    1.0
import QGroundControl.FactControls  1.0
import QGroundControl.Controls      1.0
import QGroundControl.ScreenTools   1.0
import QGroundControl.Controllers   1.0
import QGroundControl.Palette       1.0
Don Gagne's avatar
Don Gagne committed

SetupPage {
    id:             radioPage
    pageComponent:  pageComponent
    Component {
        id: pageComponent
        Item {
            width:  availableWidth
            height: Math.max(leftColumn.height, rightColumn.height)
            readonly property string    dialogTitle:            qsTr("Radio")
            readonly property real      labelToMonitorMargin:   defaultTextWidth * 3
            property bool controllerCompleted:      false
            property bool controllerAndViewReady:   false

            Component.onCompleted: {
                if (controllerCompleted) {
                    controllerAndViewReady = true
                    controller.start()
                    updateChannelCount()
                }

            function updateChannelCount()
            {
            QGCPalette { id: qgcPal; colorGroupEnabled: radioPage.enabled }

            RadioComponentController {
                id:             controller
                factPanel:      radioPage.viewPanel
                statusText:     statusText
                cancelButton:   cancelButton
                nextButton:     nextButton
                skipButton:     skipButton

                Component.onCompleted: {
                    controllerCompleted = true
                    if (qgcView.completedSignalled) {
                        controllerAndViewReady = true
                        controller.start()
                        updateChannelCount()
                    }
Don Gagne's avatar
Don Gagne committed
                }

                onChannelCountChanged:              updateChannelCount()
                onFunctionMappingChangedAPMReboot:  showMessage(qsTr("Reboot required"), qsTr("Your stick mappings have changed, you must reboot the vehicle for correct operation."), StandardButton.Ok)
                onThrottleReversedCalFailure:       showMessage(qsTr("Throttle channel reversed"), qsTr("Calibration failed. The throttle channel on your transmitter is reversed. You must correct this on your transmitter in order to complete calibration."), StandardButton.Ok)
            Component {
                id: copyTrimsDialogComponent
Don Gagne's avatar
Don Gagne committed

                QGCViewMessage {
                    message: qsTr("Center your sticks and move throttle all the way down, then press Ok to copy trims. After pressing Ok, reset the trims on your radio back to zero.")
Don Gagne's avatar
Don Gagne committed

                    function accept() {
                        hideDialog()
                        controller.copyTrims()
                    }
            Component {
                id: zeroTrimsDialogComponent
                QGCViewMessage {
                    message: qsTr("Before calibrating you should zero all your trims and subtrims. Click Ok to start Calibration.\n\n%1").arg(
                                 (QGroundControl.multiVehicleManager.activeVehicle.px4Firmware ? "" : qsTr("Please ensure all motor power is disconnected AND all props are removed from the vehicle.")))
Don Gagne's avatar
Don Gagne committed

                    function accept() {
                        hideDialog()
                        controller.nextButtonClicked()
                    }
                }
            }
Don Gagne's avatar
Don Gagne committed

            Component {
                id: channelCountDialogComponent
Don Gagne's avatar
Don Gagne committed

                QGCViewMessage {
                    message: controller.channelCount == 0 ? qsTr("Please turn on transmitter.") : qsTr("%1 channels or more are needed to fly.").arg(controller.minChannelCount)
Don Gagne's avatar
Don Gagne committed

            Component {
                id: spektrumBindDialogComponent
Don Gagne's avatar
Don Gagne committed

                QGCViewDialog {
Don Gagne's avatar
Don Gagne committed

                    function accept() {
                        controller.spektrumBindMode(radioGroup.current.bindMode)
                        hideDialog()
Don Gagne's avatar
Don Gagne committed

                    function reject() {
                        hideDialog()
Don Gagne's avatar
Don Gagne committed

                    Column {
                        anchors.fill:   parent
                        spacing:        5
Don Gagne's avatar
Don Gagne committed

                        QGCLabel {
                            width:      parent.width
                            wrapMode:   Text.WordWrap
                            text:       qsTr("Click Ok to place your Spektrum receiver in the bind mode. Select the specific receiver type below:")
                        }
Don Gagne's avatar
Don Gagne committed

                        ExclusiveGroup { id: radioGroup }
Don Gagne's avatar
Don Gagne committed

                        QGCRadioButton {
                            exclusiveGroup: radioGroup
                            text:           qsTr("DSM2 Mode")
Don Gagne's avatar
Don Gagne committed

                            property int bindMode: RadioComponentController.DSM2
                        }
Don Gagne's avatar
Don Gagne committed

                        QGCRadioButton {
                            exclusiveGroup: radioGroup
                            text:           qsTr("DSMX (7 channels or less)")
Don Gagne's avatar
Don Gagne committed

                            property int bindMode: RadioComponentController.DSMX7
                        }
Don Gagne's avatar
Don Gagne committed

                        QGCRadioButton {
                            exclusiveGroup: radioGroup
                            checked:        true
                            text:           qsTr("DSMX (8 channels or more)")
                            property int bindMode: RadioComponentController.DSMX8
                        }
                    }
            } // Component - spektrumBindDialogComponent
Don Gagne's avatar
Don Gagne committed

            // Live channel monitor control component
            Component {
                id: channelMonitorDisplayComponent
Don Gagne's avatar
Don Gagne committed

                Item {
                    property int    rcValue:    1500
                    property int            __lastRcValue:      1500
                    readonly property int   __rcValueMaxJitter: 2
                    property color          __barColor:         qgcPal.windowShade

                    readonly property int _pwmMin:      800
                    readonly property int _pwmMax:      2200
                    readonly property int _pwmRange:    _pwmMax - _pwmMin
Don Gagne's avatar
Don Gagne committed

                    // Bar
                    Rectangle {
                        id:                     bar
                        anchors.verticalCenter: parent.verticalCenter
                        width:                  parent.width
                        height:                 parent.height / 2
                        color:                  __barColor
                    // Center point
                    Rectangle {
                        anchors.horizontalCenter:   parent.horizontalCenter
                        width:                      defaultTextWidth / 2
                        height:                     parent.height
                        color:                      qgcPal.window
                    }
                    // Indicator
                    Rectangle {
                        anchors.verticalCenter: parent.verticalCenter
                        width:                  parent.height * 0.75
                        height:                 width
                        radius:                 width / 2
                        color:                  qgcPal.text
                        visible:                mapped
                        x:                      (((reversed ? _pwmMax - rcValue : rcValue - _pwmMin) / _pwmRange) * parent.width) - (width / 2)
                    }

                    QGCLabel {
                        anchors.fill:           parent
                        horizontalAlignment:    Text.AlignHCenter
                        verticalAlignment:      Text.AlignVCenter
                        text:                   qsTr("Not Mapped")
                        visible:                !mapped
                    }
                    ColorAnimation {
                        id:         barAnimation
                        target:     bar
                        property:   "color"
                        from:       "yellow"
                        to:         __barColor
                        duration:   1500
                    }
                }
            } // Component - channelMonitorDisplayComponent
Don Gagne's avatar
Don Gagne committed

            // Left side column
Don Gagne's avatar
Don Gagne committed
                id:             leftColumn
                anchors.left:   parent.left
                anchors.right:  columnSpacer.left
                spacing:        10
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                // Attitude Controls
                Column {
                    width:      parent.width
                    spacing:    5
                    QGCLabel { text: qsTr("Attitude Controls") }
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                    Item {
                        width:  parent.width
                        height: defaultTextHeight * 2
                        QGCLabel {
                            id:     rollLabel
                            width:  defaultTextWidth * 10
                            text:   qsTr("Roll")
Don Gagne's avatar
Don Gagne committed
                        }
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                        Loader {
                            id:                 rollLoader
                            anchors.left:       rollLabel.right
                            anchors.right:      parent.right
                            height:             radioPage.defaultTextHeight
Don Gagne's avatar
Don Gagne committed
                            width:              100
                            sourceComponent:    channelMonitorDisplayComponent

                            property real defaultTextWidth: radioPage.defaultTextWidth
Don Gagne's avatar
Don Gagne committed
                            property bool mapped:           controller.rollChannelMapped
                            property bool reversed:         controller.rollChannelReversed
                        }

                        Connections {
                            target: controller
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                            onRollChannelRCValueChanged: rollLoader.item.rcValue = rcValue
                        }
Don Gagne's avatar
Don Gagne committed
                    Item {
                        width:  parent.width
                        height: defaultTextHeight * 2
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                        QGCLabel {
                            id:     pitchLabel
                            width:  defaultTextWidth * 10
                            text:   qsTr("Pitch")
Don Gagne's avatar
Don Gagne committed
                        }
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                        Loader {
                            id:                 pitchLoader
                            anchors.left:       pitchLabel.right
                            anchors.right:      parent.right
                            height:             radioPage.defaultTextHeight
Don Gagne's avatar
Don Gagne committed
                            width:              100
                            sourceComponent:    channelMonitorDisplayComponent

                            property real defaultTextWidth: radioPage.defaultTextWidth
Don Gagne's avatar
Don Gagne committed
                            property bool mapped:           controller.pitchChannelMapped
                            property bool reversed:         controller.pitchChannelReversed
                        }
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                        Connections {
                            target: controller
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                            onPitchChannelRCValueChanged: pitchLoader.item.rcValue = rcValue
                        }
Don Gagne's avatar
Don Gagne committed
                    Item {
                        width:  parent.width
                        height: defaultTextHeight * 2
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                        QGCLabel {
                            id:     yawLabel
                            width:  defaultTextWidth * 10
                            text:   qsTr("Yaw")
Don Gagne's avatar
Don Gagne committed
                        }
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                        Loader {
                            id:                 yawLoader
                            anchors.left:       yawLabel.right
                            anchors.right:      parent.right
                            height:             radioPage.defaultTextHeight
Don Gagne's avatar
Don Gagne committed
                            width:              100
                            sourceComponent:    channelMonitorDisplayComponent

                            property real defaultTextWidth: radioPage.defaultTextWidth
Don Gagne's avatar
Don Gagne committed
                            property bool mapped:           controller.yawChannelMapped
                            property bool reversed:         controller.yawChannelReversed
                        }
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                        Connections {
                            target: controller
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                            onYawChannelRCValueChanged: yawLoader.item.rcValue = rcValue
                        }
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                    Item {
                        width:  parent.width
                        height: defaultTextHeight * 2
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                        QGCLabel {
                            id:     throttleLabel
                            width:  defaultTextWidth * 10
                            text:   qsTr("Throttle")
Don Gagne's avatar
Don Gagne committed
                        }
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                        Loader {
                            id:                 throttleLoader
                            anchors.left:       throttleLabel.right
                            anchors.right:      parent.right
                            height:             radioPage.defaultTextHeight
Don Gagne's avatar
Don Gagne committed
                            width:              100
                            sourceComponent:    channelMonitorDisplayComponent

                            property real defaultTextWidth: radioPage.defaultTextWidth
Don Gagne's avatar
Don Gagne committed
                            property bool mapped:           controller.throttleChannelMapped
                            property bool reversed:         controller.throttleChannelReversed
                        }
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                        Connections {
                            target: controller
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                            onThrottleChannelRCValueChanged: throttleLoader.item.rcValue = rcValue
                        }
Don Gagne's avatar
Don Gagne committed
                } // Column - Attitude Control labels
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                // Command Buttons
                Row {
                    spacing: 10
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                    QGCButton {
                        id:         skipButton
                        text:       qsTr("Skip")
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                        onClicked: controller.skipButtonClicked()
                    }
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                    QGCButton {
                        id:         cancelButton
                        text:       qsTr("Cancel")
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                        onClicked: controller.cancelButtonClicked()
                    }
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                    QGCButton {
                        id:         nextButton
                        primary:    true
                        text:       qsTr("Calibrate")
Don Gagne's avatar
Don Gagne committed

                        onClicked: {
                            if (text == qsTr("Calibrate")) {
                                showDialog(zeroTrimsDialogComponent, dialogTitle, radioPage.showDialogDefaultWidth, StandardButton.Ok | StandardButton.Cancel)
Don Gagne's avatar
Don Gagne committed
                            } else {
                                controller.nextButtonClicked()
                            }
Don Gagne's avatar
Don Gagne committed
                        }
                    }
Don Gagne's avatar
Don Gagne committed
                } // Row - Buttons
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                // Status Text
Don Gagne's avatar
Don Gagne committed
                QGCLabel {
Don Gagne's avatar
Don Gagne committed
                    id:         statusText
                    width:      parent.width
                    wrapMode:   Text.WordWrap
Don Gagne's avatar
Don Gagne committed
                Item {
                    width: 10
                    height: defaultTextHeight * 4
Don Gagne's avatar
Don Gagne committed
                Rectangle {
                    width:          parent.width
                    height:         1
                    border.color:   qgcPal.text
                    border.width:   1
                }
Don Gagne's avatar
Don Gagne committed

                QGCLabel { text: qsTr("Additional Radio setup:") }
Don Gagne's avatar
Don Gagne committed
                QGCButton {
                    id:         bindButton
                    text:       qsTr("Spektrum Bind")
Don Gagne's avatar
Don Gagne committed

                    onClicked: showDialog(spektrumBindDialogComponent, dialogTitle, radioPage.showDialogDefaultWidth, StandardButton.Ok | StandardButton.Cancel)
Don Gagne's avatar
Don Gagne committed
                QGCButton {
                    text:       qsTr("Copy Trims")
Don Gagne's avatar
Don Gagne committed
                    visible:    QGroundControl.multiVehicleManager.activeVehicle.px4Firmware
                    onClicked:  showDialog(copyTrimsDialogComponent, dialogTitle, radioPage.showDialogDefaultWidth, StandardButton.Ok | StandardButton.Cancel)
Don Gagne's avatar
Don Gagne committed
                }
Don Gagne's avatar
Don Gagne committed
                Repeater {
Don Gagne's avatar
Don Gagne committed
                    model: QGroundControl.multiVehicleManager.activeVehicle.px4Firmware ?
                               (QGroundControl.multiVehicleManager.activeVehicle.multiRotor ?
                                   [ "RC_MAP_AUX1", "RC_MAP_AUX2", "RC_MAP_PARAM1", "RC_MAP_PARAM2", "RC_MAP_PARAM3"] :
                                   [ "RC_MAP_FLAPS", "RC_MAP_AUX1", "RC_MAP_AUX2", "RC_MAP_PARAM1", "RC_MAP_PARAM2", "RC_MAP_PARAM3"]) :
                               0
Don Gagne's avatar
Don Gagne committed
                    Row {
                        spacing: ScreenTools.defaultFontPixelWidth
                        property Fact fact: controller.getParameterFact(-1, modelData)
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                        QGCLabel {
                            anchors.baseline:   optCombo.baseline
                            text:               fact.shortDescription + ":"
                        }
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                        FactComboBox {
                            id:         optCombo
                            width:      ScreenTools.defaultFontPixelWidth * 15
                            fact:       parent.fact
                            indexModel: false
                        }
                    }
                } // Repeater
            } // Column - Left Column
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
            Item {
                id:             columnSpacer
                anchors.right:  rightColumn.left
                width:          20
Don Gagne's avatar
Don Gagne committed
            // Right side column
Don Gagne's avatar
Don Gagne committed
            Column {
Don Gagne's avatar
Don Gagne committed
                id:             rightColumn
                anchors.top:    parent.top
                anchors.right:  parent.right
                width:          Math.min(radioPage.defaultTextWidth * 35, availableWidth * 0.4)
Don Gagne's avatar
Don Gagne committed
                spacing:        ScreenTools.defaultFontPixelHeight / 2
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                Row {
Don Gagne's avatar
Don Gagne committed
                    spacing: ScreenTools.defaultFontPixelWidth

Don Gagne's avatar
Don Gagne committed
                    ExclusiveGroup { id: modeGroup }
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                    QGCRadioButton {
                        exclusiveGroup: modeGroup
                        text:           qsTr("Mode 1")
Don Gagne's avatar
Don Gagne committed
                        checked:        controller.transmitterMode == 1
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                        onClicked: controller.transmitterMode = 1
                    }

                    QGCRadioButton {
                        exclusiveGroup: modeGroup
                        text:           qsTr("Mode 2")
Don Gagne's avatar
Don Gagne committed
                        checked:        controller.transmitterMode == 2

                        onClicked: controller.transmitterMode = 2
Don Gagne's avatar
Don Gagne committed
                Image {
                    width:      parent.width
                    fillMode:   Image.PreserveAspectFit
                    smooth:     true
                    source:     controller.imageHelp
                }
Don Gagne's avatar
Don Gagne committed

Don Gagne's avatar
Don Gagne committed
                RCChannelMonitor {
Don Gagne's avatar
Don Gagne committed
                    width: parent.width
Don Gagne's avatar
Don Gagne committed
            } // Column - Right Column
        } // Item    
    } // Component - pageComponent
} // SetupPage