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 11
import QtQuick          2.3
import QtQuick.Controls 1.2
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 37 38
            onSetupPageCompleted: {
                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 93 94
                    function accept() {
                        controller.spektrumBindMode(radioGroup.current.bindMode)
                        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 103
                    Column {
                        anchors.fill:   parent
                        spacing:        5
Don Gagne's avatar
Don Gagne committed
104

105 106 107 108 109
                        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
110

111
                        ExclusiveGroup { id: radioGroup }
Don Gagne's avatar
Don Gagne committed
112

113 114 115
                        QGCRadioButton {
                            exclusiveGroup: radioGroup
                            text:           qsTr("DSM2 Mode")
Don Gagne's avatar
Don Gagne committed
116

117 118
                            property int bindMode: RadioComponentController.DSM2
                        }
Don Gagne's avatar
Don Gagne committed
119

120 121 122
                        QGCRadioButton {
                            exclusiveGroup: radioGroup
                            text:           qsTr("DSMX (7 channels or less)")
Don Gagne's avatar
Don Gagne committed
123

124 125
                            property int bindMode: RadioComponentController.DSMX7
                        }
Don Gagne's avatar
Don Gagne committed
126

127 128 129 130
                        QGCRadioButton {
                            exclusiveGroup: radioGroup
                            checked:        true
                            text:           qsTr("DSMX (8 channels or more)")
131

132 133 134
                            property int bindMode: RadioComponentController.DSMX8
                        }
                    }
135
                }
136
            } // Component - spektrumBindDialogComponent
Don Gagne's avatar
Don Gagne committed
137

138 139 140
            // Live channel monitor control component
            Component {
                id: channelMonitorDisplayComponent
Don Gagne's avatar
Don Gagne committed
141

142 143
                Item {
                    property int    rcValue:    1500
Don Gagne's avatar
Don Gagne committed
144 145


146 147 148 149 150 151 152
                    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
153

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

163 164 165 166 167 168 169
                    // Center point
                    Rectangle {
                        anchors.horizontalCenter:   parent.horizontalCenter
                        width:                      defaultTextWidth / 2
                        height:                     parent.height
                        color:                      qgcPal.window
                    }
170

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

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

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

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

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

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

231
                            property real defaultTextWidth: defaultTextWidth
Don Gagne's avatar
Don Gagne committed
232 233 234 235 236 237
                            property bool mapped:           controller.rollChannelMapped
                            property bool reversed:         controller.rollChannelReversed
                        }

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

Don Gagne's avatar
Don Gagne committed
239 240
                            onRollChannelRCValueChanged: rollLoader.item.rcValue = rcValue
                        }
Don Gagne's avatar
Don Gagne committed
241 242
                    }

Don Gagne's avatar
Don Gagne committed
243 244 245
                    Item {
                        width:  parent.width
                        height: defaultTextHeight * 2
Don Gagne's avatar
Don Gagne committed
246

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

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

261
                            property real defaultTextWidth: defaultTextWidth
Don Gagne's avatar
Don Gagne committed
262 263 264
                            property bool mapped:           controller.pitchChannelMapped
                            property bool reversed:         controller.pitchChannelReversed
                        }
Don Gagne's avatar
Don Gagne committed
265

Don Gagne's avatar
Don Gagne committed
266 267
                        Connections {
                            target: controller
Don Gagne's avatar
Don Gagne committed
268

Don Gagne's avatar
Don Gagne committed
269 270
                            onPitchChannelRCValueChanged: pitchLoader.item.rcValue = rcValue
                        }
Don Gagne's avatar
Don Gagne committed
271 272
                    }

Don Gagne's avatar
Don Gagne committed
273 274 275
                    Item {
                        width:  parent.width
                        height: defaultTextHeight * 2
Don Gagne's avatar
Don Gagne committed
276

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

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

291
                            property real defaultTextWidth: defaultTextWidth
Don Gagne's avatar
Don Gagne committed
292 293 294
                            property bool mapped:           controller.yawChannelMapped
                            property bool reversed:         controller.yawChannelReversed
                        }
Don Gagne's avatar
Don Gagne committed
295

Don Gagne's avatar
Don Gagne committed
296 297
                        Connections {
                            target: controller
Don Gagne's avatar
Don Gagne committed
298

Don Gagne's avatar
Don Gagne committed
299 300
                            onYawChannelRCValueChanged: yawLoader.item.rcValue = rcValue
                        }
301
                    }
Don Gagne's avatar
Don Gagne committed
302

Don Gagne's avatar
Don Gagne committed
303 304 305
                    Item {
                        width:  parent.width
                        height: defaultTextHeight * 2
Don Gagne's avatar
Don Gagne committed
306

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

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

321
                            property real defaultTextWidth: defaultTextWidth
Don Gagne's avatar
Don Gagne committed
322 323 324
                            property bool mapped:           controller.throttleChannelMapped
                            property bool reversed:         controller.throttleChannelReversed
                        }
Don Gagne's avatar
Don Gagne committed
325

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

Don Gagne's avatar
Don Gagne committed
333 334 335
                // Command Buttons
                Row {
                    spacing: 10
Don Gagne's avatar
Don Gagne committed
336

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

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

Don Gagne's avatar
Don Gagne committed
349 350 351
                    QGCButton {
                        id:         nextButton
                        primary:    true
352
                        text:       qsTr("Calibrate")
Don Gagne's avatar
Don Gagne committed
353 354

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

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

Don Gagne's avatar
Don Gagne committed
371 372 373 374 375 376
                Rectangle {
                    width:          parent.width
                    height:         1
                    border.color:   qgcPal.text
                    border.width:   1
                }
Don Gagne's avatar
Don Gagne committed
377

378
                QGCLabel { text: qsTr("Additional Radio setup:") }
379

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

Don Gagne's avatar
Don Gagne committed
387 388 389 390 391 392
                    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
393

Don Gagne's avatar
Don Gagne committed
394 395
                        RowLayout {
                            Layout.fillWidth: true
396

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

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

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

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

Don Gagne's avatar
Don Gagne committed
426 427 428 429
            Item {
                id:             columnSpacer
                anchors.right:  rightColumn.left
                width:          20
Don Gagne's avatar
Don Gagne committed
430 431
            }

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

Don Gagne's avatar
Don Gagne committed
440
                Row {
Don Gagne's avatar
Don Gagne committed
441 442
                    spacing: ScreenTools.defaultFontPixelWidth

Don Gagne's avatar
Don Gagne committed
443
                    ExclusiveGroup { id: modeGroup }
Don Gagne's avatar
Don Gagne committed
444

Don Gagne's avatar
Don Gagne committed
445 446
                    QGCRadioButton {
                        exclusiveGroup: modeGroup
447
                        text:           qsTr("Mode 1")
Don Gagne's avatar
Don Gagne committed
448
                        checked:        controller.transmitterMode == 1
Don Gagne's avatar
Don Gagne committed
449

Don Gagne's avatar
Don Gagne committed
450 451 452 453 454
                        onClicked: controller.transmitterMode = 1
                    }

                    QGCRadioButton {
                        exclusiveGroup: modeGroup
455
                        text:           qsTr("Mode 2")
Don Gagne's avatar
Don Gagne committed
456 457 458
                        checked:        controller.transmitterMode == 2

                        onClicked: controller.transmitterMode = 2
Don Gagne's avatar
Don Gagne committed
459 460 461
                    }
                }

Don Gagne's avatar
Don Gagne committed
462 463 464 465 466 467
                Image {
                    width:      parent.width
                    fillMode:   Image.PreserveAspectFit
                    smooth:     true
                    source:     controller.imageHelp
                }
Don Gagne's avatar
Don Gagne committed
468

Don Gagne's avatar
Don Gagne committed
469
                RCChannelMonitor {
Don Gagne's avatar
Don Gagne committed
470 471
                    width:      parent.width
                    twoColumn:  true
Don Gagne's avatar
Don Gagne committed
472
                }
Don Gagne's avatar
Don Gagne committed
473
            } // Column - Right Column
474
        } // Item
475 476
    } // Component - pageComponent
} // SetupPage