RadioComponent.qml 19.4 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 67
        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)
68 69 70 71 72 73 74 75 76 77 78 79 80 81
    }

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

    QGCViewPanel {
        id:             panel
        anchors.fill:   parent

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

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

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

        Component {
            id: zeroTrimsDialogComponent

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

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

109 110 111 112
        Component {
            id: channelCountDialogComponent

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

        // Main view Qml starts here

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

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

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

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

Don Gagne's avatar
Don Gagne committed
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
                        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
291

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

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

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

Don Gagne's avatar
Don Gagne committed
306 307 308 309 310 311 312 313 314 315 316 317
                        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
318

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

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

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

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

Don Gagne's avatar
Don Gagne committed
336 337 338 339 340 341 342 343 344 345 346 347
                        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
348

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

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

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

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

Don Gagne's avatar
Don Gagne committed
366 367 368 369 370 371 372 373 374 375 376 377
                        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
378

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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