RadioComponent.qml 19 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 183 184 185 186
                // Bar
                Rectangle {
                    id:                     bar
                    anchors.verticalCenter: parent.verticalCenter
                    width:                  parent.width
                    height:                 parent.height / 2
                    color:                  __barColor
                }
Don Gagne's avatar
Don Gagne committed
187

188 189 190 191 192 193 194
                // Center point
                Rectangle {
                    anchors.horizontalCenter:   parent.horizontalCenter
                    width:                      defaultTextWidth / 2
                    height:                     parent.height
                    color:                      qgcPal.window
                }
Don Gagne's avatar
Don Gagne committed
195

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

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

215 216 217 218 219 220 221 222
                ColorAnimation {
                    id:         barAnimation
                    target:     bar
                    property:   "color"
                    from:       "yellow"
                    to:         __barColor
                    duration:   1500
                }
Don Gagne's avatar
Don Gagne committed
223

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

233 234 235 236 237 238 239 240 241 242 243
                // rcValue debugger
                QGCLabel {
                    anchors.fill: parent
                    text: rcValue
                }
                */
            }
        } // Component - channelMonitorDisplayComponent

        // Main view Qml starts here

Don Gagne's avatar
Don Gagne committed
244 245 246 247 248 249
        QGCFlickable {
            anchors.fill:   parent
            contentHeight:  Math.max(leftColumn.height, rightColumn.height)
            clip:           true

            // Left side column
250
            Column {
Don Gagne's avatar
Don Gagne committed
251 252 253 254
                id:             leftColumn
                anchors.left:   parent.left
                anchors.right:  columnSpacer.left
                spacing:        10
Don Gagne's avatar
Don Gagne committed
255

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

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

Don Gagne's avatar
Don Gagne committed
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285
                        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
286

Don Gagne's avatar
Don Gagne committed
287 288
                            onRollChannelRCValueChanged: rollLoader.item.rcValue = rcValue
                        }
Don Gagne's avatar
Don Gagne committed
289 290
                    }

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

Don Gagne's avatar
Don Gagne committed
295 296 297
                        QGCLabel {
                            id:     pitchLabel
                            width:  defaultTextWidth * 10
298
                            text:   qsTr("Pitch")
Don Gagne's avatar
Don Gagne committed
299
                        }
Don Gagne's avatar
Don Gagne committed
300

Don Gagne's avatar
Don Gagne committed
301 302 303 304 305 306 307 308 309 310 311 312
                        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
313

Don Gagne's avatar
Don Gagne committed
314 315
                        Connections {
                            target: controller
Don Gagne's avatar
Don Gagne committed
316

Don Gagne's avatar
Don Gagne committed
317 318
                            onPitchChannelRCValueChanged: pitchLoader.item.rcValue = rcValue
                        }
Don Gagne's avatar
Don Gagne committed
319 320
                    }

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

Don Gagne's avatar
Don Gagne committed
325 326 327
                        QGCLabel {
                            id:     yawLabel
                            width:  defaultTextWidth * 10
328
                            text:   qsTr("Yaw")
Don Gagne's avatar
Don Gagne committed
329
                        }
Don Gagne's avatar
Don Gagne committed
330

Don Gagne's avatar
Don Gagne committed
331 332 333 334 335 336 337 338 339 340 341 342
                        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
343

Don Gagne's avatar
Don Gagne committed
344 345
                        Connections {
                            target: controller
Don Gagne's avatar
Don Gagne committed
346

Don Gagne's avatar
Don Gagne committed
347 348
                            onYawChannelRCValueChanged: yawLoader.item.rcValue = rcValue
                        }
349
                    }
Don Gagne's avatar
Don Gagne committed
350

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

Don Gagne's avatar
Don Gagne committed
355 356 357
                        QGCLabel {
                            id:     throttleLabel
                            width:  defaultTextWidth * 10
358
                            text:   qsTr("Throttle")
Don Gagne's avatar
Don Gagne committed
359
                        }
Don Gagne's avatar
Don Gagne committed
360

Don Gagne's avatar
Don Gagne committed
361 362 363 364 365 366 367 368 369 370 371 372
                        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
373

Don Gagne's avatar
Don Gagne committed
374 375
                        Connections {
                            target: controller
Don Gagne's avatar
Don Gagne committed
376

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

Don Gagne's avatar
Don Gagne committed
382 383 384
                // Command Buttons
                Row {
                    spacing: 10
Don Gagne's avatar
Don Gagne committed
385

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

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

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

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

Don Gagne's avatar
Don Gagne committed
400 401 402
                    QGCButton {
                        id:         nextButton
                        primary:    true
403
                        text:       qsTr("Calibrate")
Don Gagne's avatar
Don Gagne committed
404 405

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

Don Gagne's avatar
Don Gagne committed
415
                // Status Text
Don Gagne's avatar
Don Gagne committed
416
                QGCLabel {
Don Gagne's avatar
Don Gagne committed
417 418 419
                    id:         statusText
                    width:      parent.width
                    wrapMode:   Text.WordWrap
Don Gagne's avatar
Don Gagne committed
420 421
                }

Don Gagne's avatar
Don Gagne committed
422 423 424
                Item {
                    width: 10
                    height: defaultTextHeight * 4
Don Gagne's avatar
Don Gagne committed
425 426
                }

Don Gagne's avatar
Don Gagne committed
427 428 429 430 431 432
                Rectangle {
                    width:          parent.width
                    height:         1
                    border.color:   qgcPal.text
                    border.width:   1
                }
Don Gagne's avatar
Don Gagne committed
433

434
                QGCLabel { text: qsTr("Additional Radio setup:") }
435

Don Gagne's avatar
Don Gagne committed
436 437 438
                QGCButton {
                    id:         bindButton
                    text:       qsTr("Spektrum Bind")
Don Gagne's avatar
Don Gagne committed
439

Don Gagne's avatar
Don Gagne committed
440
                    onClicked: showDialog(spektrumBindDialogComponent, dialogTitle, qgcView.showDialogDefaultWidth, StandardButton.Ok | StandardButton.Cancel)
441
                }
442

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

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

Don Gagne's avatar
Don Gagne committed
452 453 454
                    Row {
                        spacing: ScreenTools.defaultFontPixelWidth
                        property Fact fact: controller.getParameterFact(-1, modelData)
Don Gagne's avatar
Don Gagne committed
455

Don Gagne's avatar
Don Gagne committed
456 457 458 459
                        QGCLabel {
                            anchors.baseline:   optCombo.baseline
                            text:               fact.shortDescription + ":"
                        }
Don Gagne's avatar
Don Gagne committed
460

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

Don Gagne's avatar
Don Gagne committed
471 472 473 474
            Item {
                id:             columnSpacer
                anchors.right:  rightColumn.left
                width:          20
Don Gagne's avatar
Don Gagne committed
475 476
            }

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

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

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

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

Don Gagne's avatar
Don Gagne committed
495 496 497 498 499
                        onClicked: controller.transmitterMode = 1
                    }

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

                        onClicked: controller.transmitterMode = 2
Don Gagne's avatar
Don Gagne committed
504 505 506
                    }
                }

Don Gagne's avatar
Don Gagne committed
507 508 509 510 511 512
                Image {
                    width:      parent.width
                    fillMode:   Image.PreserveAspectFit
                    smooth:     true
                    source:     controller.imageHelp
                }
Don Gagne's avatar
Don Gagne committed
513

Don Gagne's avatar
Don Gagne committed
514
                RCChannelMonitor {
Don Gagne's avatar
Don Gagne committed
515
                    width: parent.width
Don Gagne's avatar
Don Gagne committed
516
                }
Don Gagne's avatar
Don Gagne committed
517 518
            } // Column - Right Column
        } // QGCFlickable
519
    } // QGCViewPanel
Don Gagne's avatar
Don Gagne committed
520
}