RadioComponent.qml 18.6 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
            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 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
                        QGCRadioButton {
112
                            text:       qsTr("DSM2 Mode")
113 114
                            property int bindMode: RadioComponentController.DSM2
                        }
Don Gagne's avatar
Don Gagne committed
115

116
                        QGCRadioButton {
117
                            text:       qsTr("DSMX (7 channels or less)")
118 119
                            property int bindMode: RadioComponentController.DSMX7
                        }
Don Gagne's avatar
Don Gagne committed
120

121
                        QGCRadioButton {
122 123
                            checked:    true
                            text:       qsTr("DSMX (8 channels or more)")
124 125 126
                            property int bindMode: RadioComponentController.DSMX8
                        }
                    }
127
                }
128
            } // Component - spektrumBindDialogComponent
Don Gagne's avatar
Don Gagne committed
129

130 131 132
            // Live channel monitor control component
            Component {
                id: channelMonitorDisplayComponent
Don Gagne's avatar
Don Gagne committed
133

134 135
                Item {
                    property int    rcValue:    1500
Don Gagne's avatar
Don Gagne committed
136 137


138 139 140 141 142 143 144
                    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
145

146 147 148 149 150 151 152
                    // Bar
                    Rectangle {
                        id:                     bar
                        anchors.verticalCenter: parent.verticalCenter
                        width:                  parent.width
                        height:                 parent.height / 2
                        color:                  __barColor
Don Gagne's avatar
Don Gagne committed
153 154
                    }

155 156 157 158 159 160 161
                    // Center point
                    Rectangle {
                        anchors.horizontalCenter:   parent.horizontalCenter
                        width:                      defaultTextWidth / 2
                        height:                     parent.height
                        color:                      qgcPal.window
                    }
162

163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
                    // 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
                    }
181

182 183 184 185 186 187 188 189 190 191
                    ColorAnimation {
                        id:         barAnimation
                        target:     bar
                        property:   "color"
                        from:       "yellow"
                        to:         __barColor
                        duration:   1500
                    }
                }
            } // Component - channelMonitorDisplayComponent
Don Gagne's avatar
Don Gagne committed
192 193

            // Left side column
194
            Column {
Don Gagne's avatar
Don Gagne committed
195 196 197 198
                id:             leftColumn
                anchors.left:   parent.left
                anchors.right:  columnSpacer.left
                spacing:        10
Don Gagne's avatar
Don Gagne committed
199

Don Gagne's avatar
Don Gagne committed
200 201 202 203
                // Attitude Controls
                Column {
                    width:      parent.width
                    spacing:    5
204
                    QGCLabel { text: qsTr("Attitude Controls") }
Don Gagne's avatar
Don Gagne committed
205

Don Gagne's avatar
Don Gagne committed
206 207 208 209 210 211
                    Item {
                        width:  parent.width
                        height: defaultTextHeight * 2
                        QGCLabel {
                            id:     rollLabel
                            width:  defaultTextWidth * 10
212
                            text:   qsTr("Roll")
Don Gagne's avatar
Don Gagne committed
213
                        }
Don Gagne's avatar
Don Gagne committed
214

Don Gagne's avatar
Don Gagne committed
215 216 217 218
                        Loader {
                            id:                 rollLoader
                            anchors.left:       rollLabel.right
                            anchors.right:      parent.right
219
                            height:             defaultTextHeight
Don Gagne's avatar
Don Gagne committed
220 221 222
                            width:              100
                            sourceComponent:    channelMonitorDisplayComponent

223
                            property real defaultTextWidth: defaultTextWidth
Don Gagne's avatar
Don Gagne committed
224 225 226 227 228 229
                            property bool mapped:           controller.rollChannelMapped
                            property bool reversed:         controller.rollChannelReversed
                        }

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

Don Gagne's avatar
Don Gagne committed
231 232
                            onRollChannelRCValueChanged: rollLoader.item.rcValue = rcValue
                        }
Don Gagne's avatar
Don Gagne committed
233 234
                    }

Don Gagne's avatar
Don Gagne committed
235 236 237
                    Item {
                        width:  parent.width
                        height: defaultTextHeight * 2
Don Gagne's avatar
Don Gagne committed
238

Don Gagne's avatar
Don Gagne committed
239 240 241
                        QGCLabel {
                            id:     pitchLabel
                            width:  defaultTextWidth * 10
242
                            text:   qsTr("Pitch")
Don Gagne's avatar
Don Gagne committed
243
                        }
Don Gagne's avatar
Don Gagne committed
244

Don Gagne's avatar
Don Gagne committed
245 246 247 248
                        Loader {
                            id:                 pitchLoader
                            anchors.left:       pitchLabel.right
                            anchors.right:      parent.right
249
                            height:             defaultTextHeight
Don Gagne's avatar
Don Gagne committed
250 251 252
                            width:              100
                            sourceComponent:    channelMonitorDisplayComponent

253
                            property real defaultTextWidth: defaultTextWidth
Don Gagne's avatar
Don Gagne committed
254 255 256
                            property bool mapped:           controller.pitchChannelMapped
                            property bool reversed:         controller.pitchChannelReversed
                        }
Don Gagne's avatar
Don Gagne committed
257

Don Gagne's avatar
Don Gagne committed
258 259
                        Connections {
                            target: controller
Don Gagne's avatar
Don Gagne committed
260

Don Gagne's avatar
Don Gagne committed
261 262
                            onPitchChannelRCValueChanged: pitchLoader.item.rcValue = rcValue
                        }
Don Gagne's avatar
Don Gagne committed
263 264
                    }

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

Don Gagne's avatar
Don Gagne committed
269 270 271
                        QGCLabel {
                            id:     yawLabel
                            width:  defaultTextWidth * 10
272
                            text:   qsTr("Yaw")
Don Gagne's avatar
Don Gagne committed
273
                        }
Don Gagne's avatar
Don Gagne committed
274

Don Gagne's avatar
Don Gagne committed
275 276 277 278
                        Loader {
                            id:                 yawLoader
                            anchors.left:       yawLabel.right
                            anchors.right:      parent.right
279
                            height:             defaultTextHeight
Don Gagne's avatar
Don Gagne committed
280 281 282
                            width:              100
                            sourceComponent:    channelMonitorDisplayComponent

283
                            property real defaultTextWidth: defaultTextWidth
Don Gagne's avatar
Don Gagne committed
284 285 286
                            property bool mapped:           controller.yawChannelMapped
                            property bool reversed:         controller.yawChannelReversed
                        }
Don Gagne's avatar
Don Gagne committed
287

Don Gagne's avatar
Don Gagne committed
288 289
                        Connections {
                            target: controller
Don Gagne's avatar
Don Gagne committed
290

Don Gagne's avatar
Don Gagne committed
291 292
                            onYawChannelRCValueChanged: yawLoader.item.rcValue = rcValue
                        }
293
                    }
Don Gagne's avatar
Don Gagne committed
294

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

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

Don Gagne's avatar
Don Gagne committed
305 306 307 308
                        Loader {
                            id:                 throttleLoader
                            anchors.left:       throttleLabel.right
                            anchors.right:      parent.right
309
                            height:             defaultTextHeight
Don Gagne's avatar
Don Gagne committed
310 311 312
                            width:              100
                            sourceComponent:    channelMonitorDisplayComponent

313
                            property real defaultTextWidth: defaultTextWidth
Don Gagne's avatar
Don Gagne committed
314 315 316
                            property bool mapped:           controller.throttleChannelMapped
                            property bool reversed:         controller.throttleChannelReversed
                        }
Don Gagne's avatar
Don Gagne committed
317

Don Gagne's avatar
Don Gagne committed
318
                        Connections {
Don Gagne's avatar
Don Gagne committed
319 320
                            target:                             controller
                            onThrottleChannelRCValueChanged:    throttleLoader.item.rcValue = rcValue
Don Gagne's avatar
Don Gagne committed
321
                        }
322
                    }
Don Gagne's avatar
Don Gagne committed
323
                } // Column - Attitude Control labels
Don Gagne's avatar
Don Gagne committed
324

Don Gagne's avatar
Don Gagne committed
325 326 327
                // Command Buttons
                Row {
                    spacing: 10
Don Gagne's avatar
Don Gagne committed
328

Don Gagne's avatar
Don Gagne committed
329 330
                    QGCButton {
                        id:         skipButton
331
                        text:       qsTr("Skip")
Don Gagne's avatar
Don Gagne committed
332
                        onClicked:  controller.skipButtonClicked()
Don Gagne's avatar
Don Gagne committed
333
                    }
Don Gagne's avatar
Don Gagne committed
334

Don Gagne's avatar
Don Gagne committed
335 336
                    QGCButton {
                        id:         cancelButton
337
                        text:       qsTr("Cancel")
Don Gagne's avatar
Don Gagne committed
338
                        onClicked:  controller.cancelButtonClicked()
Don Gagne's avatar
Don Gagne committed
339
                    }
Don Gagne's avatar
Don Gagne committed
340

Don Gagne's avatar
Don Gagne committed
341 342 343
                    QGCButton {
                        id:         nextButton
                        primary:    true
344
                        text:       qsTr("Calibrate")
Don Gagne's avatar
Don Gagne committed
345 346

                        onClicked: {
347
                            if (text === qsTr("Calibrate")) {
348
                                mainWindow.showDialog(zeroTrimsDialogComponent, dialogTitle, mainWindow.showDialogDefaultWidth, StandardButton.Ok | StandardButton.Cancel)
Don Gagne's avatar
Don Gagne committed
349 350 351
                            } else {
                                controller.nextButtonClicked()
                            }
Don Gagne's avatar
Don Gagne committed
352 353
                        }
                    }
Don Gagne's avatar
Don Gagne committed
354
                } // Row - Buttons
Don Gagne's avatar
Don Gagne committed
355

Don Gagne's avatar
Don Gagne committed
356
                // Status Text
Don Gagne's avatar
Don Gagne committed
357
                QGCLabel {
Don Gagne's avatar
Don Gagne committed
358 359 360
                    id:         statusText
                    width:      parent.width
                    wrapMode:   Text.WordWrap
Don Gagne's avatar
Don Gagne committed
361 362
                }

Don Gagne's avatar
Don Gagne committed
363 364 365 366 367 368
                Rectangle {
                    width:          parent.width
                    height:         1
                    border.color:   qgcPal.text
                    border.width:   1
                }
Don Gagne's avatar
Don Gagne committed
369

370
                QGCLabel { text: qsTr("Additional Radio setup:") }
371

Don Gagne's avatar
Don Gagne committed
372 373 374 375 376 377
                GridLayout {
                    id:                 switchSettingsGrid
                    anchors.left:       parent.left
                    anchors.right:      parent.right
                    columns:            2
                    columnSpacing:      ScreenTools.defaultFontPixelWidth
378

Don Gagne's avatar
Don Gagne committed
379 380 381 382 383 384
                    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
385

Don Gagne's avatar
Don Gagne committed
386 387
                        RowLayout {
                            Layout.fillWidth: true
388

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

Don Gagne's avatar
Don Gagne committed
391 392 393 394 395 396 397 398 399
                            QGCLabel {
                                Layout.fillWidth:   true
                                text:               fact.shortDescription
                            }
                            FactComboBox {
                                width:      ScreenTools.defaultFontPixelWidth * 15
                                fact:       parent.fact
                                indexModel: false
                            }
Don Gagne's avatar
Don Gagne committed
400
                        }
Don Gagne's avatar
Don Gagne committed
401 402
                    }
                }
Don Gagne's avatar
Don Gagne committed
403

Don Gagne's avatar
Don Gagne committed
404 405 406 407
                RowLayout {
                    QGCButton {
                        id:         bindButton
                        text:       qsTr("Spektrum Bind")
408
                        onClicked:  mainWindow.showDialog(spektrumBindDialogComponent, dialogTitle, mainWindow.showDialogDefaultWidth, StandardButton.Ok | StandardButton.Cancel)
Don Gagne's avatar
Don Gagne committed
409
                    }
Don Gagne's avatar
Don Gagne committed
410 411 412

                    QGCButton {
                        text:       qsTr("Copy Trims")
413
                        onClicked:  mainWindow.showDialog(copyTrimsDialogComponent, dialogTitle, mainWindow.showDialogDefaultWidth, StandardButton.Ok | StandardButton.Cancel)
Don Gagne's avatar
Don Gagne committed
414 415
                    }
                }
Don Gagne's avatar
Don Gagne committed
416
            } // Column - Left Column
Don Gagne's avatar
Don Gagne committed
417

Don Gagne's avatar
Don Gagne committed
418 419 420 421
            Item {
                id:             columnSpacer
                anchors.right:  rightColumn.left
                width:          20
Don Gagne's avatar
Don Gagne committed
422 423
            }

Don Gagne's avatar
Don Gagne committed
424
            // Right side column
Don Gagne's avatar
Don Gagne committed
425
            Column {
Don Gagne's avatar
Don Gagne committed
426 427 428
                id:             rightColumn
                anchors.top:    parent.top
                anchors.right:  parent.right
Don Gagne's avatar
Don Gagne committed
429
                width:          ScreenTools.defaultFontPixelWidth * 40
Don Gagne's avatar
Don Gagne committed
430
                spacing:        ScreenTools.defaultFontPixelHeight / 2
Don Gagne's avatar
Don Gagne committed
431

Don Gagne's avatar
Don Gagne committed
432
                Row {
Don Gagne's avatar
Don Gagne committed
433 434
                    spacing: ScreenTools.defaultFontPixelWidth

Don Gagne's avatar
Don Gagne committed
435
                    QGCRadioButton {
436 437 438
                        text:       qsTr("Mode 1")
                        checked:    controller.transmitterMode == 1
                        onClicked:  controller.transmitterMode = 1
Don Gagne's avatar
Don Gagne committed
439 440 441
                    }

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

Don Gagne's avatar
Don Gagne committed
448 449 450 451 452 453
                Image {
                    width:      parent.width
                    fillMode:   Image.PreserveAspectFit
                    smooth:     true
                    source:     controller.imageHelp
                }
Don Gagne's avatar
Don Gagne committed
454

Don Gagne's avatar
Don Gagne committed
455
                RCChannelMonitor {
Don Gagne's avatar
Don Gagne committed
456 457
                    width:      parent.width
                    twoColumn:  true
Don Gagne's avatar
Don Gagne committed
458
                }
Don Gagne's avatar
Don Gagne committed
459
            } // Column - Right Column
460
        } // Item
461 462
    } // Component - pageComponent
} // SetupPage