RadioComponent.qml 19.2 KB
Newer Older
1 2 3 4 5 6 7 8
/****************************************************************************
 *
 *   (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.
 *
 ****************************************************************************/
Don Gagne's avatar
Don Gagne committed
9 10


Don Gagne's avatar
Don Gagne committed
11
import QtQuick          2.5
Don Gagne's avatar
Don Gagne committed
12
import QtQuick.Controls 1.2
Don Gagne's avatar
Don Gagne committed
13
import QtQuick.Dialogs  1.2
Don Gagne's avatar
Don Gagne committed
14

Don Gagne's avatar
Don Gagne committed
15 16 17 18 19 20 21
import QGroundControl               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
import QGroundControl.Controllers   1.0
Don Gagne's avatar
Don Gagne committed
22 23

QGCView {
24
    id:         qgcView
25 26 27 28
    viewPanel:  panel

    QGCPalette { id: qgcPal; colorGroupEnabled: panel.enabled }

29
    readonly property string    dialogTitle:            qsTr("Radio")
Don Gagne's avatar
Don Gagne committed
30
    readonly property real      labelToMonitorMargin:   defaultTextWidth * 3
31

Don Gagne's avatar
Don Gagne committed
32 33
    property bool controllerCompleted:      false
    property bool controllerAndViewReady:   false
34

35 36
    function updateChannelCount()
    {
Don Gagne's avatar
Don Gagne committed
37 38 39
/*
            FIXME: Turned off for now, since it prevents binding. Need to restructure to
            allow binding and still check channel count
40
            if (controller.channelCount < controller.minChannelCount) {
41
                showDialog(channelCountDialogComponent, dialogTitle, qgcView.showDialogDefaultWidth, 0)
42 43 44
            } else {
                hideDialog()
            }
Don Gagne's avatar
Don Gagne committed
45
*/
46 47 48 49 50 51 52 53 54 55 56 57
    }

    RadioComponentController {
        id:             controller
        factPanel:      panel
        statusText:     statusText
        cancelButton:   cancelButton
        nextButton:     nextButton
        skipButton:     skipButton

        Component.onCompleted: {
            controllerCompleted = true
58
            if (qgcView.completedSignalled) {
59 60 61 62 63
                controllerAndViewReady = true
                controller.start()
                updateChannelCount()
            }
        }
Don Gagne's avatar
Don Gagne committed
64 65

        onChannelCountChanged:              updateChannelCount()
66
        onFunctionMappingChangedAPMReboot:    showMessage(qsTr("Reboot required"), qsTr("Your stick mappings have changed, you must reboot the vehicle for correct operation."), StandardButton.Ok)
67 68 69 70 71 72 73 74 75 76 77 78 79 80
    }

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

    QGCViewPanel {
        id:             panel
        anchors.fill:   parent

Don Gagne's avatar
Don Gagne committed
81 82 83 84
        Component {
            id: copyTrimsDialogComponent

            QGCViewMessage {
85
                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
86 87 88 89 90 91 92 93 94 95 96 97

                function accept() {
                    hideDialog()
                    controller.copyTrims()
                }
            }
        }

        Component {
            id: zeroTrimsDialogComponent

            QGCViewMessage {
98 99
                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
100 101 102 103 104 105 106 107

                function accept() {
                    hideDialog()
                    controller.nextButtonClicked()
                }
            }
        }

108 109 110 111
        Component {
            id: channelCountDialogComponent

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

116 117
        Component {
            id: spektrumBindDialogComponent
Don Gagne's avatar
Don Gagne committed
118

119
            QGCViewDialog {
Don Gagne's avatar
Don Gagne committed
120

121 122 123 124
                function accept() {
                    controller.spektrumBindMode(radioGroup.current.bindMode)
                    hideDialog()
                }
Don Gagne's avatar
Don Gagne committed
125

126
                function reject() {
Don Gagne's avatar
Don Gagne committed
127 128 129
                    hideDialog()
                }

130 131 132
                Column {
                    anchors.fill:   parent
                    spacing:        5
Don Gagne's avatar
Don Gagne committed
133

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

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

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

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

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

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

156 157 158
                    QGCRadioButton {
                        exclusiveGroup: radioGroup
                        checked:        true
159
                        text:           qsTr("DSMX (8 channels or more)")
Don Gagne's avatar
Don Gagne committed
160

161
                        property int bindMode: RadioComponentController.DSMX8
Don Gagne's avatar
Don Gagne committed
162
                    }
163 164 165
                }
            }
        } // Component - spektrumBindDialogComponent
Don Gagne's avatar
Don Gagne committed
166

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

171 172
            Item {
                property int    rcValue:    1500
Don Gagne's avatar
Don Gagne committed
173 174


175 176 177
                property int            __lastRcValue:      1500
                readonly property int   __rcValueMaxJitter: 2
                property color          __barColor:         qgcPal.windowShade
Don Gagne's avatar
Don Gagne committed
178

179 180 181 182
                readonly property int _pwmMin:      800
                readonly property int _pwmMax:      2200
                readonly property int _pwmRange:    _pwmMax - _pwmMin

183 184 185 186 187 188 189 190
                // Bar
                Rectangle {
                    id:                     bar
                    anchors.verticalCenter: parent.verticalCenter
                    width:                  parent.width
                    height:                 parent.height / 2
                    color:                  __barColor
                }
Don Gagne's avatar
Don Gagne committed
191

192 193 194 195 196 197 198
                // Center point
                Rectangle {
                    anchors.horizontalCenter:   parent.horizontalCenter
                    width:                      defaultTextWidth / 2
                    height:                     parent.height
                    color:                      qgcPal.window
                }
Don Gagne's avatar
Don Gagne committed
199

200 201 202 203 204
                // Indicator
                Rectangle {
                    anchors.verticalCenter: parent.verticalCenter
                    width:                  parent.height * 0.75
                    height:                 width
205
                    x:                      ((Math.abs((rcValue - _pwmMin) - (reversed ? _pwmMin : 0)) / _pwmRange) * parent.width) - (width / 2)
206 207 208 209
                    radius:                 width / 2
                    color:                  qgcPal.text
                    visible:                mapped
                }
Don Gagne's avatar
Don Gagne committed
210

211 212 213 214
                QGCLabel {
                    anchors.fill:           parent
                    horizontalAlignment:    Text.AlignHCenter
                    verticalAlignment:      Text.AlignVCenter
215
                    text:                   qsTr("Not Mapped")
216 217
                    visible:                !mapped
                }
Don Gagne's avatar
Don Gagne committed
218

219 220 221 222 223 224 225 226
                ColorAnimation {
                    id:         barAnimation
                    target:     bar
                    property:   "color"
                    from:       "yellow"
                    to:         __barColor
                    duration:   1500
                }
Don Gagne's avatar
Don Gagne committed
227

Don Gagne's avatar
Don Gagne committed
228 229
                /*
                // FIXME: Bar animation is turned off for now to figure out better usbaility
230 231 232 233
                onRcValueChanged: {
                    if (Math.abs(rcValue - __lastRcValue) > __rcValueMaxJitter) {
                        __lastRcValue = rcValue
                        barAnimation.restart()
Don Gagne's avatar
Don Gagne committed
234 235 236
                    }
                }

237 238 239 240 241 242 243 244 245 246 247
                // rcValue debugger
                QGCLabel {
                    anchors.fill: parent
                    text: rcValue
                }
                */
            }
        } // Component - channelMonitorDisplayComponent

        // Main view Qml starts here

Don Gagne's avatar
Don Gagne committed
248 249 250 251 252 253
        QGCFlickable {
            anchors.fill:   parent
            contentHeight:  Math.max(leftColumn.height, rightColumn.height)
            clip:           true

            // Left side column
254
            Column {
Don Gagne's avatar
Don Gagne committed
255 256 257 258
                id:             leftColumn
                anchors.left:   parent.left
                anchors.right:  columnSpacer.left
                spacing:        10
Don Gagne's avatar
Don Gagne committed
259

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

Don Gagne's avatar
Don Gagne committed
266 267 268 269 270 271
                    Item {
                        width:  parent.width
                        height: defaultTextHeight * 2
                        QGCLabel {
                            id:     rollLabel
                            width:  defaultTextWidth * 10
272
                            text:   qsTr("Roll")
Don Gagne's avatar
Don Gagne committed
273
                        }
Don Gagne's avatar
Don Gagne committed
274

Don Gagne's avatar
Don Gagne committed
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
                        Loader {
                            id:                 rollLoader
                            anchors.left:       rollLabel.right
                            anchors.right:      parent.right
                            height:             qgcView.defaultTextHeight
                            width:              100
                            sourceComponent:    channelMonitorDisplayComponent

                            property real defaultTextWidth: qgcView.defaultTextWidth
                            property bool mapped:           controller.rollChannelMapped
                            property bool reversed:         controller.rollChannelReversed
                        }

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

Don Gagne's avatar
Don Gagne committed
291 292
                            onRollChannelRCValueChanged: rollLoader.item.rcValue = rcValue
                        }
Don Gagne's avatar
Don Gagne committed
293 294
                    }

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

Don Gagne's avatar
Don Gagne committed
299 300 301
                        QGCLabel {
                            id:     pitchLabel
                            width:  defaultTextWidth * 10
302
                            text:   qsTr("Pitch")
Don Gagne's avatar
Don Gagne committed
303
                        }
Don Gagne's avatar
Don Gagne committed
304

Don Gagne's avatar
Don Gagne committed
305 306 307 308 309 310 311 312 313 314 315 316
                        Loader {
                            id:                 pitchLoader
                            anchors.left:       pitchLabel.right
                            anchors.right:      parent.right
                            height:             qgcView.defaultTextHeight
                            width:              100
                            sourceComponent:    channelMonitorDisplayComponent

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

Don Gagne's avatar
Don Gagne committed
318 319
                        Connections {
                            target: controller
Don Gagne's avatar
Don Gagne committed
320

Don Gagne's avatar
Don Gagne committed
321 322
                            onPitchChannelRCValueChanged: pitchLoader.item.rcValue = rcValue
                        }
Don Gagne's avatar
Don Gagne committed
323 324
                    }

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

Don Gagne's avatar
Don Gagne committed
329 330 331
                        QGCLabel {
                            id:     yawLabel
                            width:  defaultTextWidth * 10
332
                            text:   qsTr("Yaw")
Don Gagne's avatar
Don Gagne committed
333
                        }
Don Gagne's avatar
Don Gagne committed
334

Don Gagne's avatar
Don Gagne committed
335 336 337 338 339 340 341 342 343 344 345 346
                        Loader {
                            id:                 yawLoader
                            anchors.left:       yawLabel.right
                            anchors.right:      parent.right
                            height:             qgcView.defaultTextHeight
                            width:              100
                            sourceComponent:    channelMonitorDisplayComponent

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

Don Gagne's avatar
Don Gagne committed
348 349
                        Connections {
                            target: controller
Don Gagne's avatar
Don Gagne committed
350

Don Gagne's avatar
Don Gagne committed
351 352
                            onYawChannelRCValueChanged: yawLoader.item.rcValue = rcValue
                        }
353
                    }
Don Gagne's avatar
Don Gagne committed
354

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

Don Gagne's avatar
Don Gagne committed
359 360 361
                        QGCLabel {
                            id:     throttleLabel
                            width:  defaultTextWidth * 10
362
                            text:   qsTr("Throttle")
Don Gagne's avatar
Don Gagne committed
363
                        }
Don Gagne's avatar
Don Gagne committed
364

Don Gagne's avatar
Don Gagne committed
365 366 367 368 369 370 371 372 373 374 375 376
                        Loader {
                            id:                 throttleLoader
                            anchors.left:       throttleLabel.right
                            anchors.right:      parent.right
                            height:             qgcView.defaultTextHeight
                            width:              100
                            sourceComponent:    channelMonitorDisplayComponent

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

Don Gagne's avatar
Don Gagne committed
378 379
                        Connections {
                            target: controller
Don Gagne's avatar
Don Gagne committed
380

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

Don Gagne's avatar
Don Gagne committed
386 387 388
                // Command Buttons
                Row {
                    spacing: 10
Don Gagne's avatar
Don Gagne committed
389

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

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

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

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

Don Gagne's avatar
Don Gagne committed
404 405 406
                    QGCButton {
                        id:         nextButton
                        primary:    true
407
                        text:       qsTr("Calibrate")
Don Gagne's avatar
Don Gagne committed
408 409

                        onClicked: {
410
                            if (text == qsTr("Calibrate")) {
Don Gagne's avatar
Don Gagne committed
411 412 413 414
                                showDialog(zeroTrimsDialogComponent, dialogTitle, qgcView.showDialogDefaultWidth, StandardButton.Ok | StandardButton.Cancel)
                            } else {
                                controller.nextButtonClicked()
                            }
Don Gagne's avatar
Don Gagne committed
415 416
                        }
                    }
Don Gagne's avatar
Don Gagne committed
417
                } // Row - Buttons
Don Gagne's avatar
Don Gagne committed
418

Don Gagne's avatar
Don Gagne committed
419
                // Status Text
Don Gagne's avatar
Don Gagne committed
420
                QGCLabel {
Don Gagne's avatar
Don Gagne committed
421 422 423
                    id:         statusText
                    width:      parent.width
                    wrapMode:   Text.WordWrap
Don Gagne's avatar
Don Gagne committed
424 425
                }

Don Gagne's avatar
Don Gagne committed
426 427 428
                Item {
                    width: 10
                    height: defaultTextHeight * 4
Don Gagne's avatar
Don Gagne committed
429 430
                }

Don Gagne's avatar
Don Gagne committed
431 432 433 434 435 436
                Rectangle {
                    width:          parent.width
                    height:         1
                    border.color:   qgcPal.text
                    border.width:   1
                }
Don Gagne's avatar
Don Gagne committed
437

438
                QGCLabel { text: qsTr("Additional Radio setup:") }
439

Don Gagne's avatar
Don Gagne committed
440 441 442
                QGCButton {
                    id:         bindButton
                    text:       qsTr("Spektrum Bind")
Don Gagne's avatar
Don Gagne committed
443

Don Gagne's avatar
Don Gagne committed
444
                    onClicked: showDialog(spektrumBindDialogComponent, dialogTitle, qgcView.showDialogDefaultWidth, StandardButton.Ok | StandardButton.Cancel)
445
                }
446

Don Gagne's avatar
Don Gagne committed
447
                QGCButton {
448
                    text:       qsTr("Copy Trims")
Don Gagne's avatar
Don Gagne committed
449 450 451
                    visible:    QGroundControl.multiVehicleManager.activeVehicle.px4Firmware
                    onClicked:  showDialog(copyTrimsDialogComponent, dialogTitle, qgcView.showDialogDefaultWidth, StandardButton.Ok | StandardButton.Cancel)
                }
452

Don Gagne's avatar
Don Gagne committed
453
                Repeater {
Lorenz Meier's avatar
Lorenz Meier committed
454
                    model: QGroundControl.multiVehicleManager.activeVehicle.px4Firmware ? [ "RC_MAP_FLAPS", "RC_MAP_AUX1", "RC_MAP_AUX2", "RC_MAP_PARAM1", "RC_MAP_PARAM2", "RC_MAP_PARAM3"] : 0
455

Don Gagne's avatar
Don Gagne committed
456 457 458
                    Row {
                        spacing: ScreenTools.defaultFontPixelWidth
                        property Fact fact: controller.getParameterFact(-1, modelData)
Don Gagne's avatar
Don Gagne committed
459

Don Gagne's avatar
Don Gagne committed
460 461 462 463
                        QGCLabel {
                            anchors.baseline:   optCombo.baseline
                            text:               fact.shortDescription + ":"
                        }
Don Gagne's avatar
Don Gagne committed
464

Don Gagne's avatar
Don Gagne committed
465 466 467 468 469 470 471 472 473
                        FactComboBox {
                            id:         optCombo
                            width:      ScreenTools.defaultFontPixelWidth * 15
                            fact:       parent.fact
                            indexModel: false
                        }
                    }
                } // Repeater
            } // Column - Left Column
Don Gagne's avatar
Don Gagne committed
474

Don Gagne's avatar
Don Gagne committed
475 476 477 478
            Item {
                id:             columnSpacer
                anchors.right:  rightColumn.left
                width:          20
Don Gagne's avatar
Don Gagne committed
479 480
            }

Don Gagne's avatar
Don Gagne committed
481
            // Right side column
Don Gagne's avatar
Don Gagne committed
482
            Column {
Don Gagne's avatar
Don Gagne committed
483 484 485
                id:             rightColumn
                anchors.top:    parent.top
                anchors.right:  parent.right
Don Gagne's avatar
Don Gagne committed
486 487
                width:          Math.min(defaultTextWidth * 35, qgcView.width * 0.4)
                spacing:        ScreenTools.defaultFontPixelHeight / 2
Don Gagne's avatar
Don Gagne committed
488

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

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

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

Don Gagne's avatar
Don Gagne committed
499 500 501 502 503
                        onClicked: controller.transmitterMode = 1
                    }

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

                        onClicked: controller.transmitterMode = 2
Don Gagne's avatar
Don Gagne committed
508 509 510
                    }
                }

Don Gagne's avatar
Don Gagne committed
511 512 513 514 515 516
                Image {
                    width:      parent.width
                    fillMode:   Image.PreserveAspectFit
                    smooth:     true
                    source:     controller.imageHelp
                }
Don Gagne's avatar
Don Gagne committed
517

Don Gagne's avatar
Don Gagne committed
518
                RCChannelMonitor {
Don Gagne's avatar
Don Gagne committed
519
                    width: parent.width
Don Gagne's avatar
Don Gagne committed
520
                }
Don Gagne's avatar
Don Gagne committed
521 522
            } // Column - Right Column
        } // QGCFlickable
523
    } // QGCViewPanel
Don Gagne's avatar
Don Gagne committed
524
}