RadioComponent.qml 18.9 KB
Newer Older
1 2
/****************************************************************************
 *
Gus Grubba's avatar
Gus Grubba committed
3
 * (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
4 5 6 7 8
 *
 * 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
import QtQuick          2.3
11
import QtQuick.Controls 2.4
Don Gagne's avatar
Don Gagne committed
12
import QtQuick.Dialogs  1.2
Don Gagne's avatar
Don Gagne committed
13
import QtQuick.Layouts  1.11
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
            readonly property string  dialogTitle: qsTr("Radio")
35

36
            function setupPageCompleted() {
37 38
                controller.start()
                updateChannelCount()
39
            }
40 41 42

            function updateChannelCount()
            {
43
            }
44

45 46
            QGCPalette { id: qgcPal; colorGroupEnabled: radioPage.enabled }

47 48 49 50 51 52 53
            RadioComponentController {
                id:             controller
                statusText:     statusText
                cancelButton:   cancelButton
                nextButton:     nextButton
                skipButton:     skipButton
                onChannelCountChanged:              updateChannelCount()
54 55
                onFunctionMappingChangedAPMReboot:  mainWindow.showMessageDialog(qsTr("Reboot required"), qsTr("Your stick mappings have changed, you must reboot the vehicle for correct operation."))
                onThrottleReversedCalFailure:       mainWindow.showMessageDialog(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."))
Don Gagne's avatar
Don Gagne committed
56 57
            }

58 59 60 61 62 63 64 65
            Component {
                id: copyTrimsDialogComponent
                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.")
                    function accept() {
                        hideDialog()
                        controller.copyTrims()
                    }
Don Gagne's avatar
Don Gagne committed
66 67 68
                }
            }

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

81 82 83 84
            Component {
                id: channelCountDialogComponent
                QGCViewMessage {
                    message: controller.channelCount == 0 ? qsTr("Please turn on transmitter.") : qsTr("%1 channels or more are needed to fly.").arg(controller.minChannelCount)
85
                }
86
            }
Don Gagne's avatar
Don Gagne committed
87

88 89 90
            Component {
                id: spektrumBindDialogComponent
                QGCViewDialog {
Don Gagne's avatar
Don Gagne committed
91

92
                    function accept() {
93
                        controller.spektrumBindMode(radioGroup.checkedButton.bindMode)
94
                        hideDialog()
95
                    }
Don Gagne's avatar
Don Gagne committed
96

97 98
                    function reject() {
                        hideDialog()
99
                    }
Don Gagne's avatar
Don Gagne committed
100

101 102
                    ButtonGroup { id: radioGroup }

103 104 105
                    Column {
                        anchors.fill:   parent
                        spacing:        5
Don Gagne's avatar
Don Gagne committed
106

107 108 109 110 111
                        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
112

113
                        QGCRadioButton {
114 115
                            text:               qsTr("DSM2 Mode")
                            ButtonGroup.group:  radioGroup
116 117
                            property int bindMode: RadioComponentController.DSM2
                        }
Don Gagne's avatar
Don Gagne committed
118

119
                        QGCRadioButton {
120 121
                            text:               qsTr("DSMX (7 channels or less)")
                            ButtonGroup.group:  radioGroup
122 123
                            property int bindMode: RadioComponentController.DSMX7
                        }
Don Gagne's avatar
Don Gagne committed
124

125
                        QGCRadioButton {
126 127 128
                            checked:            true
                            text:               qsTr("DSMX (8 channels or more)")
                            ButtonGroup.group:  radioGroup
129 130 131
                            property int bindMode: RadioComponentController.DSMX8
                        }
                    }
132
                }
133
            } // Component - spektrumBindDialogComponent
Don Gagne's avatar
Don Gagne committed
134

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

139 140
                Item {
                    property int    rcValue:    1500
Don Gagne's avatar
Don Gagne committed
141 142


143 144 145 146 147 148 149
                    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
150

151 152 153 154 155 156 157
                    // Bar
                    Rectangle {
                        id:                     bar
                        anchors.verticalCenter: parent.verticalCenter
                        width:                  parent.width
                        height:                 parent.height / 2
                        color:                  __barColor
Don Gagne's avatar
Don Gagne committed
158 159
                    }

160 161 162 163 164 165 166
                    // Center point
                    Rectangle {
                        anchors.horizontalCenter:   parent.horizontalCenter
                        width:                      defaultTextWidth / 2
                        height:                     parent.height
                        color:                      qgcPal.window
                    }
167

168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
                    // 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
                    }
186

187 188 189 190 191 192 193 194 195 196
                    ColorAnimation {
                        id:         barAnimation
                        target:     bar
                        property:   "color"
                        from:       "yellow"
                        to:         __barColor
                        duration:   1500
                    }
                }
            } // Component - channelMonitorDisplayComponent
Don Gagne's avatar
Don Gagne committed
197 198

            // Left side column
199
            Column {
Don Gagne's avatar
Don Gagne committed
200 201 202 203
                id:             leftColumn
                anchors.left:   parent.left
                anchors.right:  columnSpacer.left
                spacing:        10
Don Gagne's avatar
Don Gagne committed
204

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

Don Gagne's avatar
Don Gagne committed
211 212 213 214 215 216
                    Item {
                        width:  parent.width
                        height: defaultTextHeight * 2
                        QGCLabel {
                            id:     rollLabel
                            width:  defaultTextWidth * 10
217
                            text:   qsTr("Roll")
Don Gagne's avatar
Don Gagne committed
218
                        }
Don Gagne's avatar
Don Gagne committed
219

Don Gagne's avatar
Don Gagne committed
220 221 222 223
                        Loader {
                            id:                 rollLoader
                            anchors.left:       rollLabel.right
                            anchors.right:      parent.right
224
                            height:             defaultTextHeight
Don Gagne's avatar
Don Gagne committed
225 226 227
                            width:              100
                            sourceComponent:    channelMonitorDisplayComponent

228
                            property real defaultTextWidth: defaultTextWidth
Don Gagne's avatar
Don Gagne committed
229 230 231 232 233 234
                            property bool mapped:           controller.rollChannelMapped
                            property bool reversed:         controller.rollChannelReversed
                        }

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

Don Gagne's avatar
Don Gagne committed
236 237
                            onRollChannelRCValueChanged: rollLoader.item.rcValue = rcValue
                        }
Don Gagne's avatar
Don Gagne committed
238 239
                    }

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

Don Gagne's avatar
Don Gagne committed
244 245 246
                        QGCLabel {
                            id:     pitchLabel
                            width:  defaultTextWidth * 10
247
                            text:   qsTr("Pitch")
Don Gagne's avatar
Don Gagne committed
248
                        }
Don Gagne's avatar
Don Gagne committed
249

Don Gagne's avatar
Don Gagne committed
250 251 252 253
                        Loader {
                            id:                 pitchLoader
                            anchors.left:       pitchLabel.right
                            anchors.right:      parent.right
254
                            height:             defaultTextHeight
Don Gagne's avatar
Don Gagne committed
255 256 257
                            width:              100
                            sourceComponent:    channelMonitorDisplayComponent

258
                            property real defaultTextWidth: defaultTextWidth
Don Gagne's avatar
Don Gagne committed
259 260 261
                            property bool mapped:           controller.pitchChannelMapped
                            property bool reversed:         controller.pitchChannelReversed
                        }
Don Gagne's avatar
Don Gagne committed
262

Don Gagne's avatar
Don Gagne committed
263 264
                        Connections {
                            target: controller
Don Gagne's avatar
Don Gagne committed
265

Don Gagne's avatar
Don Gagne committed
266 267
                            onPitchChannelRCValueChanged: pitchLoader.item.rcValue = rcValue
                        }
Don Gagne's avatar
Don Gagne committed
268 269
                    }

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

Don Gagne's avatar
Don Gagne committed
274 275 276
                        QGCLabel {
                            id:     yawLabel
                            width:  defaultTextWidth * 10
277
                            text:   qsTr("Yaw")
Don Gagne's avatar
Don Gagne committed
278
                        }
Don Gagne's avatar
Don Gagne committed
279

Don Gagne's avatar
Don Gagne committed
280 281 282 283
                        Loader {
                            id:                 yawLoader
                            anchors.left:       yawLabel.right
                            anchors.right:      parent.right
284
                            height:             defaultTextHeight
Don Gagne's avatar
Don Gagne committed
285 286 287
                            width:              100
                            sourceComponent:    channelMonitorDisplayComponent

288
                            property real defaultTextWidth: defaultTextWidth
Don Gagne's avatar
Don Gagne committed
289 290 291
                            property bool mapped:           controller.yawChannelMapped
                            property bool reversed:         controller.yawChannelReversed
                        }
Don Gagne's avatar
Don Gagne committed
292

Don Gagne's avatar
Don Gagne committed
293 294
                        Connections {
                            target: controller
Don Gagne's avatar
Don Gagne committed
295

Don Gagne's avatar
Don Gagne committed
296 297
                            onYawChannelRCValueChanged: yawLoader.item.rcValue = rcValue
                        }
298
                    }
Don Gagne's avatar
Don Gagne committed
299

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

Don Gagne's avatar
Don Gagne committed
304 305 306
                        QGCLabel {
                            id:     throttleLabel
                            width:  defaultTextWidth * 10
307
                            text:   qsTr("Throttle")
Don Gagne's avatar
Don Gagne committed
308
                        }
Don Gagne's avatar
Don Gagne committed
309

Don Gagne's avatar
Don Gagne committed
310 311 312 313
                        Loader {
                            id:                 throttleLoader
                            anchors.left:       throttleLabel.right
                            anchors.right:      parent.right
314
                            height:             defaultTextHeight
Don Gagne's avatar
Don Gagne committed
315 316 317
                            width:              100
                            sourceComponent:    channelMonitorDisplayComponent

318
                            property real defaultTextWidth: defaultTextWidth
Don Gagne's avatar
Don Gagne committed
319 320 321
                            property bool mapped:           controller.throttleChannelMapped
                            property bool reversed:         controller.throttleChannelReversed
                        }
Don Gagne's avatar
Don Gagne committed
322

Don Gagne's avatar
Don Gagne committed
323
                        Connections {
Don Gagne's avatar
Don Gagne committed
324 325
                            target:                             controller
                            onThrottleChannelRCValueChanged:    throttleLoader.item.rcValue = rcValue
Don Gagne's avatar
Don Gagne committed
326
                        }
327
                    }
Don Gagne's avatar
Don Gagne committed
328
                } // Column - Attitude Control labels
Don Gagne's avatar
Don Gagne committed
329

Don Gagne's avatar
Don Gagne committed
330 331 332
                // Command Buttons
                Row {
                    spacing: 10
Don Gagne's avatar
Don Gagne committed
333

Don Gagne's avatar
Don Gagne committed
334 335
                    QGCButton {
                        id:         skipButton
336
                        text:       qsTr("Skip")
Don Gagne's avatar
Don Gagne committed
337
                        onClicked:  controller.skipButtonClicked()
Don Gagne's avatar
Don Gagne committed
338
                    }
Don Gagne's avatar
Don Gagne committed
339

Don Gagne's avatar
Don Gagne committed
340 341
                    QGCButton {
                        id:         cancelButton
342
                        text:       qsTr("Cancel")
Don Gagne's avatar
Don Gagne committed
343
                        onClicked:  controller.cancelButtonClicked()
Don Gagne's avatar
Don Gagne committed
344
                    }
Don Gagne's avatar
Don Gagne committed
345

Don Gagne's avatar
Don Gagne committed
346 347 348
                    QGCButton {
                        id:         nextButton
                        primary:    true
349
                        text:       qsTr("Calibrate")
Don Gagne's avatar
Don Gagne committed
350 351

                        onClicked: {
352
                            if (text === qsTr("Calibrate")) {
353
                                mainWindow.showComponentDialog(zeroTrimsDialogComponent, dialogTitle, mainWindow.showDialogDefaultWidth, StandardButton.Ok | StandardButton.Cancel)
Don Gagne's avatar
Don Gagne committed
354 355 356
                            } else {
                                controller.nextButtonClicked()
                            }
Don Gagne's avatar
Don Gagne committed
357 358
                        }
                    }
Don Gagne's avatar
Don Gagne committed
359
                } // Row - Buttons
Don Gagne's avatar
Don Gagne committed
360

Don Gagne's avatar
Don Gagne committed
361
                // Status Text
Don Gagne's avatar
Don Gagne committed
362
                QGCLabel {
Don Gagne's avatar
Don Gagne committed
363 364 365
                    id:         statusText
                    width:      parent.width
                    wrapMode:   Text.WordWrap
Don Gagne's avatar
Don Gagne committed
366 367
                }

Don Gagne's avatar
Don Gagne committed
368 369 370 371 372 373
                Rectangle {
                    width:          parent.width
                    height:         1
                    border.color:   qgcPal.text
                    border.width:   1
                }
Don Gagne's avatar
Don Gagne committed
374

375
                QGCLabel { text: qsTr("Additional Radio setup:") }
376

Don Gagne's avatar
Don Gagne committed
377 378 379 380 381 382
                GridLayout {
                    id:                 switchSettingsGrid
                    anchors.left:       parent.left
                    anchors.right:      parent.right
                    columns:            2
                    columnSpacing:      ScreenTools.defaultFontPixelWidth
383

Don Gagne's avatar
Don Gagne committed
384 385 386 387 388 389
                    Repeater {
                        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
390

Don Gagne's avatar
Don Gagne committed
391 392
                        RowLayout {
                            Layout.fillWidth: true
393

Don Gagne's avatar
Don Gagne committed
394
                            property Fact fact: controller.getParameterFact(-1, modelData)
Don Gagne's avatar
Don Gagne committed
395

Don Gagne's avatar
Don Gagne committed
396 397 398 399 400 401 402 403 404
                            QGCLabel {
                                Layout.fillWidth:   true
                                text:               fact.shortDescription
                            }
                            FactComboBox {
                                width:      ScreenTools.defaultFontPixelWidth * 15
                                fact:       parent.fact
                                indexModel: false
                            }
Don Gagne's avatar
Don Gagne committed
405
                        }
Don Gagne's avatar
Don Gagne committed
406 407
                    }
                }
Don Gagne's avatar
Don Gagne committed
408

Don Gagne's avatar
Don Gagne committed
409 410 411 412
                RowLayout {
                    QGCButton {
                        id:         bindButton
                        text:       qsTr("Spektrum Bind")
413
                        onClicked:  mainWindow.showComponentDialog(spektrumBindDialogComponent, dialogTitle, mainWindow.showDialogDefaultWidth, StandardButton.Ok | StandardButton.Cancel)
Don Gagne's avatar
Don Gagne committed
414
                    }
Don Gagne's avatar
Don Gagne committed
415 416 417

                    QGCButton {
                        text:       qsTr("Copy Trims")
418
                        onClicked:  mainWindow.showComponentDialog(copyTrimsDialogComponent, dialogTitle, mainWindow.showDialogDefaultWidth, StandardButton.Ok | StandardButton.Cancel)
Don Gagne's avatar
Don Gagne committed
419 420
                    }
                }
Don Gagne's avatar
Don Gagne committed
421
            } // Column - Left Column
Don Gagne's avatar
Don Gagne committed
422

Don Gagne's avatar
Don Gagne committed
423 424 425 426
            Item {
                id:             columnSpacer
                anchors.right:  rightColumn.left
                width:          20
Don Gagne's avatar
Don Gagne committed
427 428
            }

Don Gagne's avatar
Don Gagne committed
429
            // Right side column
Don Gagne's avatar
Don Gagne committed
430
            Column {
Don Gagne's avatar
Don Gagne committed
431 432 433
                id:             rightColumn
                anchors.top:    parent.top
                anchors.right:  parent.right
Don Gagne's avatar
Don Gagne committed
434
                width:          ScreenTools.defaultFontPixelWidth * 40
Don Gagne's avatar
Don Gagne committed
435
                spacing:        ScreenTools.defaultFontPixelHeight / 2
Don Gagne's avatar
Don Gagne committed
436

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

Don Gagne's avatar
Don Gagne committed
440
                    QGCRadioButton {
441 442 443
                        text:       qsTr("Mode 1")
                        checked:    controller.transmitterMode == 1
                        onClicked:  controller.transmitterMode = 1
Don Gagne's avatar
Don Gagne committed
444 445 446
                    }

                    QGCRadioButton {
447 448 449
                        text:       qsTr("Mode 2")
                        checked:    controller.transmitterMode == 2
                        onClicked:  controller.transmitterMode = 2
Don Gagne's avatar
Don Gagne committed
450 451 452
                    }
                }

Don Gagne's avatar
Don Gagne committed
453 454 455 456 457 458
                Image {
                    width:      parent.width
                    fillMode:   Image.PreserveAspectFit
                    smooth:     true
                    source:     controller.imageHelp
                }
Don Gagne's avatar
Don Gagne committed
459

Don Gagne's avatar
Don Gagne committed
460
                RCChannelMonitor {
Don Gagne's avatar
Don Gagne committed
461 462
                    width:      parent.width
                    twoColumn:  true
Don Gagne's avatar
Don Gagne committed
463
                }
Don Gagne's avatar
Don Gagne committed
464
            } // Column - Right Column
465
        } // Item
466 467
    } // Component - pageComponent
} // SetupPage