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


11 12
import QtQuick          2.3
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
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
21
import QGroundControl.Palette       1.0
Don Gagne's avatar
Don Gagne committed
22

23 24 25
SetupPage {
    id:             radioPage
    pageComponent:  pageComponent
26

27 28
    Component {
        id: pageComponent
29

30 31 32
        Item {
            width:  availableWidth
            height: Math.max(leftColumn.height, rightColumn.height)
33

34 35
            readonly property string    dialogTitle:            qsTr("Radio")
            readonly property real      labelToMonitorMargin:   defaultTextWidth * 3
36

37 38 39 40 41 42 43 44 45
            property bool controllerCompleted:      false
            property bool controllerAndViewReady:   false

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

            function updateChannelCount()
            {
50
            }
51

52 53
            QGCPalette { id: qgcPal; colorGroupEnabled: radioPage.enabled }

54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
            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
69
                }
70 71 72 73

                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)
Don Gagne's avatar
Don Gagne committed
74 75
            }

76 77
            Component {
                id: copyTrimsDialogComponent
Don Gagne's avatar
Don Gagne committed
78

79 80
                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
81

82 83 84 85
                    function accept() {
                        hideDialog()
                        controller.copyTrims()
                    }
Don Gagne's avatar
Don Gagne committed
86 87 88
                }
            }

89 90
            Component {
                id: zeroTrimsDialogComponent
91

92 93 94
                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
95

96 97 98 99 100 101
                    function accept() {
                        hideDialog()
                        controller.nextButtonClicked()
                    }
                }
            }
Don Gagne's avatar
Don Gagne committed
102

103 104
            Component {
                id: channelCountDialogComponent
Don Gagne's avatar
Don Gagne committed
105

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

111 112
            Component {
                id: spektrumBindDialogComponent
Don Gagne's avatar
Don Gagne committed
113

114
                QGCViewDialog {
Don Gagne's avatar
Don Gagne committed
115

116 117 118
                    function accept() {
                        controller.spektrumBindMode(radioGroup.current.bindMode)
                        hideDialog()
119
                    }
Don Gagne's avatar
Don Gagne committed
120

121 122
                    function reject() {
                        hideDialog()
123
                    }
Don Gagne's avatar
Don Gagne committed
124

125 126 127
                    Column {
                        anchors.fill:   parent
                        spacing:        5
Don Gagne's avatar
Don Gagne committed
128

129 130 131 132 133
                        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
134

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

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

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

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

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

151 152 153 154
                        QGCRadioButton {
                            exclusiveGroup: radioGroup
                            checked:        true
                            text:           qsTr("DSMX (8 channels or more)")
155

156 157 158
                            property int bindMode: RadioComponentController.DSMX8
                        }
                    }
159
                }
160
            } // Component - spektrumBindDialogComponent
Don Gagne's avatar
Don Gagne committed
161

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

166 167
                Item {
                    property int    rcValue:    1500
Don Gagne's avatar
Don Gagne committed
168 169


170 171 172 173 174 175 176
                    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
177

178 179 180 181 182 183 184
                    // Bar
                    Rectangle {
                        id:                     bar
                        anchors.verticalCenter: parent.verticalCenter
                        width:                  parent.width
                        height:                 parent.height / 2
                        color:                  __barColor
Don Gagne's avatar
Don Gagne committed
185 186
                    }

187 188 189 190 191 192 193
                    // Center point
                    Rectangle {
                        anchors.horizontalCenter:   parent.horizontalCenter
                        width:                      defaultTextWidth / 2
                        height:                     parent.height
                        color:                      qgcPal.window
                    }
194

195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
                    // 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
                    }
213

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

            // Left side column
226
            Column {
Don Gagne's avatar
Don Gagne committed
227 228 229 230
                id:             leftColumn
                anchors.left:   parent.left
                anchors.right:  columnSpacer.left
                spacing:        10
Don Gagne's avatar
Don Gagne committed
231

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

Don Gagne's avatar
Don Gagne committed
238 239 240 241 242 243
                    Item {
                        width:  parent.width
                        height: defaultTextHeight * 2
                        QGCLabel {
                            id:     rollLabel
                            width:  defaultTextWidth * 10
244
                            text:   qsTr("Roll")
Don Gagne's avatar
Don Gagne committed
245
                        }
Don Gagne's avatar
Don Gagne committed
246

Don Gagne's avatar
Don Gagne committed
247 248 249 250
                        Loader {
                            id:                 rollLoader
                            anchors.left:       rollLabel.right
                            anchors.right:      parent.right
251
                            height:             radioPage.defaultTextHeight
Don Gagne's avatar
Don Gagne committed
252 253 254
                            width:              100
                            sourceComponent:    channelMonitorDisplayComponent

255
                            property real defaultTextWidth: radioPage.defaultTextWidth
Don Gagne's avatar
Don Gagne committed
256 257 258 259 260 261
                            property bool mapped:           controller.rollChannelMapped
                            property bool reversed:         controller.rollChannelReversed
                        }

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

Don Gagne's avatar
Don Gagne committed
263 264
                            onRollChannelRCValueChanged: rollLoader.item.rcValue = rcValue
                        }
Don Gagne's avatar
Don Gagne committed
265 266
                    }

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

Don Gagne's avatar
Don Gagne committed
271 272 273
                        QGCLabel {
                            id:     pitchLabel
                            width:  defaultTextWidth * 10
274
                            text:   qsTr("Pitch")
Don Gagne's avatar
Don Gagne committed
275
                        }
Don Gagne's avatar
Don Gagne committed
276

Don Gagne's avatar
Don Gagne committed
277 278 279 280
                        Loader {
                            id:                 pitchLoader
                            anchors.left:       pitchLabel.right
                            anchors.right:      parent.right
281
                            height:             radioPage.defaultTextHeight
Don Gagne's avatar
Don Gagne committed
282 283 284
                            width:              100
                            sourceComponent:    channelMonitorDisplayComponent

285
                            property real defaultTextWidth: radioPage.defaultTextWidth
Don Gagne's avatar
Don Gagne committed
286 287 288
                            property bool mapped:           controller.pitchChannelMapped
                            property bool reversed:         controller.pitchChannelReversed
                        }
Don Gagne's avatar
Don Gagne committed
289

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

Don Gagne's avatar
Don Gagne committed
293 294
                            onPitchChannelRCValueChanged: pitchLoader.item.rcValue = rcValue
                        }
Don Gagne's avatar
Don Gagne committed
295 296
                    }

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

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

Don Gagne's avatar
Don Gagne committed
307 308 309 310
                        Loader {
                            id:                 yawLoader
                            anchors.left:       yawLabel.right
                            anchors.right:      parent.right
311
                            height:             radioPage.defaultTextHeight
Don Gagne's avatar
Don Gagne committed
312 313 314
                            width:              100
                            sourceComponent:    channelMonitorDisplayComponent

315
                            property real defaultTextWidth: radioPage.defaultTextWidth
Don Gagne's avatar
Don Gagne committed
316 317 318
                            property bool mapped:           controller.yawChannelMapped
                            property bool reversed:         controller.yawChannelReversed
                        }
Don Gagne's avatar
Don Gagne committed
319

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

Don Gagne's avatar
Don Gagne committed
323 324
                            onYawChannelRCValueChanged: yawLoader.item.rcValue = rcValue
                        }
325
                    }
Don Gagne's avatar
Don Gagne committed
326

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

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

Don Gagne's avatar
Don Gagne committed
337 338 339 340
                        Loader {
                            id:                 throttleLoader
                            anchors.left:       throttleLabel.right
                            anchors.right:      parent.right
341
                            height:             radioPage.defaultTextHeight
Don Gagne's avatar
Don Gagne committed
342 343 344
                            width:              100
                            sourceComponent:    channelMonitorDisplayComponent

345
                            property real defaultTextWidth: radioPage.defaultTextWidth
Don Gagne's avatar
Don Gagne committed
346 347 348
                            property bool mapped:           controller.throttleChannelMapped
                            property bool reversed:         controller.throttleChannelReversed
                        }
Don Gagne's avatar
Don Gagne committed
349

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

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

Don Gagne's avatar
Don Gagne committed
358 359 360
                // Command Buttons
                Row {
                    spacing: 10
Don Gagne's avatar
Don Gagne committed
361

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

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

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

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

Don Gagne's avatar
Don Gagne committed
376 377 378
                    QGCButton {
                        id:         nextButton
                        primary:    true
379
                        text:       qsTr("Calibrate")
Don Gagne's avatar
Don Gagne committed
380 381

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

Don Gagne's avatar
Don Gagne committed
391
                // Status Text
Don Gagne's avatar
Don Gagne committed
392
                QGCLabel {
Don Gagne's avatar
Don Gagne committed
393 394 395
                    id:         statusText
                    width:      parent.width
                    wrapMode:   Text.WordWrap
Don Gagne's avatar
Don Gagne committed
396 397
                }

Don Gagne's avatar
Don Gagne committed
398 399 400
                Item {
                    width: 10
                    height: defaultTextHeight * 4
Don Gagne's avatar
Don Gagne committed
401 402
                }

Don Gagne's avatar
Don Gagne committed
403 404 405 406 407 408
                Rectangle {
                    width:          parent.width
                    height:         1
                    border.color:   qgcPal.text
                    border.width:   1
                }
Don Gagne's avatar
Don Gagne committed
409

410
                QGCLabel { text: qsTr("Additional Radio setup:") }
411

Don Gagne's avatar
Don Gagne committed
412 413 414
                QGCButton {
                    id:         bindButton
                    text:       qsTr("Spektrum Bind")
Don Gagne's avatar
Don Gagne committed
415

416
                    onClicked: showDialog(spektrumBindDialogComponent, dialogTitle, radioPage.showDialogDefaultWidth, StandardButton.Ok | StandardButton.Cancel)
417
                }
418

Don Gagne's avatar
Don Gagne committed
419
                QGCButton {
420
                    text:       qsTr("Copy Trims")
421
                    onClicked:  showDialog(copyTrimsDialogComponent, dialogTitle, radioPage.showDialogDefaultWidth, StandardButton.Ok | StandardButton.Cancel)
Don Gagne's avatar
Don Gagne committed
422
                }
423

Don Gagne's avatar
Don Gagne committed
424
                Repeater {
Don Gagne's avatar
Don Gagne committed
425 426 427 428 429
                    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
430

Don Gagne's avatar
Don Gagne committed
431 432 433
                    Row {
                        spacing: ScreenTools.defaultFontPixelWidth
                        property Fact fact: controller.getParameterFact(-1, modelData)
Don Gagne's avatar
Don Gagne committed
434

Don Gagne's avatar
Don Gagne committed
435 436 437 438
                        QGCLabel {
                            anchors.baseline:   optCombo.baseline
                            text:               fact.shortDescription + ":"
                        }
Don Gagne's avatar
Don Gagne committed
439

Don Gagne's avatar
Don Gagne committed
440 441 442 443 444 445 446 447 448
                        FactComboBox {
                            id:         optCombo
                            width:      ScreenTools.defaultFontPixelWidth * 15
                            fact:       parent.fact
                            indexModel: false
                        }
                    }
                } // Repeater
            } // Column - Left Column
Don Gagne's avatar
Don Gagne committed
449

Don Gagne's avatar
Don Gagne committed
450 451 452 453
            Item {
                id:             columnSpacer
                anchors.right:  rightColumn.left
                width:          20
Don Gagne's avatar
Don Gagne committed
454 455
            }

Don Gagne's avatar
Don Gagne committed
456
            // Right side column
Don Gagne's avatar
Don Gagne committed
457
            Column {
Don Gagne's avatar
Don Gagne committed
458 459 460
                id:             rightColumn
                anchors.top:    parent.top
                anchors.right:  parent.right
461
                width:          Math.min(radioPage.defaultTextWidth * 35, availableWidth * 0.4)
Don Gagne's avatar
Don Gagne committed
462
                spacing:        ScreenTools.defaultFontPixelHeight / 2
Don Gagne's avatar
Don Gagne committed
463

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

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

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

Don Gagne's avatar
Don Gagne committed
474 475 476 477 478
                        onClicked: controller.transmitterMode = 1
                    }

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

                        onClicked: controller.transmitterMode = 2
Don Gagne's avatar
Don Gagne committed
483 484 485
                    }
                }

Don Gagne's avatar
Don Gagne committed
486 487 488 489 490 491
                Image {
                    width:      parent.width
                    fillMode:   Image.PreserveAspectFit
                    smooth:     true
                    source:     controller.imageHelp
                }
Don Gagne's avatar
Don Gagne committed
492

Don Gagne's avatar
Don Gagne committed
493
                RCChannelMonitor {
Don Gagne's avatar
Don Gagne committed
494
                    width: parent.width
Don Gagne's avatar
Don Gagne committed
495
                }
Don Gagne's avatar
Don Gagne committed
496
            } // Column - Right Column
497 498 499
        } // Item    
    } // Component - pageComponent
} // SetupPage