PowerComponent.qml 24.5 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.
 *
 ****************************************************************************/
dogmaphobic's avatar
dogmaphobic committed
9 10 11 12 13 14


/// @file
///     @brief Battery, propeller and magnetometer settings
///     @author Gus Grubba <mavlink@grubba.com>

15
import QtQuick          2.2
dogmaphobic's avatar
dogmaphobic committed
16
import QtQuick.Controls 1.2
17 18
import QtQuick.Dialogs  1.2
import QtQuick.Layouts  1.2
dogmaphobic's avatar
dogmaphobic committed
19

20 21 22 23 24 25
import QGroundControl.FactSystem    1.0
import QGroundControl.FactControls  1.0
import QGroundControl.Palette       1.0
import QGroundControl.Controls      1.0
import QGroundControl.ScreenTools   1.0
import QGroundControl.Controllers   1.0
dogmaphobic's avatar
dogmaphobic committed
26

27
QGCView {
28 29 30
    id:         rootQGCView
    viewPanel:  panel

31
    property int textEditWidth:    ScreenTools.defaultFontPixelWidth * 8
32

33 34 35 36 37 38 39
    property Fact battNumCells:         controller.getParameterFact(-1, "BAT_N_CELLS")
    property Fact battHighVolt:         controller.getParameterFact(-1, "BAT_V_CHARGED")
    property Fact battLowVolt:          controller.getParameterFact(-1, "BAT_V_EMPTY")
    property Fact battVoltLoadDrop:     controller.getParameterFact(-1, "BAT_V_LOAD_DROP")
    property Fact battVoltageDivider:   controller.getParameterFact(-1, "BAT_V_DIV")
    property Fact battAmpsPerVolt:      controller.getParameterFact(-1, "BAT_A_PER_V")
    property Fact uavcanEnable:         controller.getParameterFact(-1, "UAVCAN_ENABLE", false)
40

dogmaphobic's avatar
dogmaphobic committed
41 42 43 44
    readonly property string highlightPrefix:   "<font color=\"" + qgcPal.warningText + "\">"
    readonly property string highlightSuffix:   "</font>"


45 46 47
    function getBatteryImage()
    {
        switch(battNumCells.value) {
48 49 50 51 52 53 54
        case 1:  return "/qmlimages/PowerComponentBattery_01cell.svg";
        case 2:  return "/qmlimages/PowerComponentBattery_02cell.svg"
        case 3:  return "/qmlimages/PowerComponentBattery_03cell.svg"
        case 4:  return "/qmlimages/PowerComponentBattery_04cell.svg"
        case 5:  return "/qmlimages/PowerComponentBattery_05cell.svg"
        case 6:  return "/qmlimages/PowerComponentBattery_06cell.svg"
        default: return "/qmlimages/PowerComponentBattery_01cell.svg";
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
        }
    }

    function drawArrowhead(ctx, x, y, radians)
    {
        ctx.save();
        ctx.beginPath();
        ctx.translate(x,y);
        ctx.rotate(radians);
        ctx.moveTo(0,0);
        ctx.lineTo(5,10);
        ctx.lineTo(-5,10);
        ctx.closePath();
        ctx.restore();
        ctx.fill();
    }

    function drawLineWithArrow(ctx, x1, y1, x2, y2)
    {
        ctx.beginPath();
        ctx.moveTo(x1, y1);
        ctx.lineTo(x2, y2);
        ctx.stroke();
        var rd = Math.atan((y2 - y1) / (x2 - x1));
        rd += ((x2 > x1) ? 90 : -90) * Math.PI/180;
        drawArrowhead(ctx, x2, y2, rd);
    }

    PowerComponentController {
        id:         controller
        factPanel:  panel

87 88 89 90 91 92 93
        onOldFirmware:          showMessage(qsTr("ESC Calibration"), qsTr("QGroundControl cannot perform ESC Calibration with this version of firmware. You will need to upgrade to a newer firmware."), StandardButton.Ok)
        onNewerFirmware:        showMessage(qsTr("ESC Calibration"), qsTr("QGroundControl cannot perform ESC Calibration with this version of firmware. You will need to upgrade QGroundControl."), StandardButton.Ok)
        onBatteryConnected:     showMessage(qsTr("ESC Calibration"), qsTr("Performing calibration. This will take a few seconds.."), 0)
        onCalibrationFailed:    showMessage(qsTr("ESC Calibration failed"), errorMessage, StandardButton.Ok)
        onCalibrationSuccess:   showMessage(qsTr("ESC Calibration"), qsTr("Calibration complete. You can disconnect your battery now if you like."), StandardButton.Ok)
        onConnectBattery:       showMessage(qsTr("ESC Calibration"), highlightPrefix + qsTr("WARNING: Props must be removed from vehicle prior to performing ESC calibration.") + highlightSuffix + qsTr(" Connect the battery now and calibration will begin."), 0)
        onDisconnectBattery:    showMessage(qsTr("ESC Calibration failed"), qsTr("You must disconnect the battery prior to performing ESC Calibration. Disconnect your battery and try again."), StandardButton.Ok)
94 95 96 97
    }

    QGCPalette { id: palette; colorGroupEnabled: panel.enabled }

98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
    Component {
        id: calcVoltageDividerDlgComponent

        QGCViewDialog {
            id: calcVoltageDividerDlg

            QGCFlickable {
                anchors.fill:   parent
                contentHeight:  column.height
                contentWidth:   column.width

                Column {
                    id:         column
                    width:      calcVoltageDividerDlg.width
                    spacing:    ScreenTools.defaultFontPixelHeight

                    QGCLabel {
                        width:      parent.width
                        wrapMode:   Text.WordWrap
                        text:       "Measure battery voltage using an external voltmeter and enter the value below. Click Calculate to set the new voltage multiplier."
                    }

                    Grid {
                        columns: 2
                        spacing: ScreenTools.defaultFontPixelHeight / 2
                        verticalItemAlignment: Grid.AlignVCenter

                        QGCLabel {
                            text: "Measured voltage:"
                        }
                        QGCTextField { id: measuredVoltage }

                        QGCLabel { text: "Vehicle voltage:" }
                        QGCLabel { text: controller.vehicle.battery.voltage.valueString }

                        QGCLabel { text: "Voltage divider:" }
                        FactLabel { fact: battVoltageDivider }
                    }

                    QGCButton {
                        text: "Calculate"

                        onClicked:  {
                            var measuredVoltageValue = parseFloat(measuredVoltage.text)
                            if (measuredVoltageValue == 0) {
                                return
                            }
                            var newVoltageDivider = (measuredVoltageValue * battVoltageDivider.value) / controller.vehicle.battery.voltage.value
                            if (newVoltageDivider != 0) {
                                battVoltageDivider.value = newVoltageDivider
                            }
                        }
                    }
                } // Column
            } // QGCFlickable
        } // QGCViewDialog
    } // Component - calcVoltageDividerDlgComponent

    Component {
        id: calcAmpsPerVoltDlgComponent

        QGCViewDialog {
            id: calcAmpsPerVoltDlg

            QGCFlickable {
                anchors.fill:   parent
                contentHeight:  column.height
                contentWidth:   column.width

                Column {
                    id:         column
                    width:      calcAmpsPerVoltDlg.width
                    spacing:    ScreenTools.defaultFontPixelHeight

                    QGCLabel {
                        width:      parent.width
                        wrapMode:   Text.WordWrap
                        text:       "Measure current draw using an external current meter and enter the value below. Click Calculate to set the new amps per volt value."
                    }

                    Grid {
                        columns: 2
                        spacing: ScreenTools.defaultFontPixelHeight / 2
                        verticalItemAlignment: Grid.AlignVCenter

                        QGCLabel {
                            text: "Measured current:"
                        }
                        QGCTextField { id: measuredCurrent }

                        QGCLabel { text: "Vehicle current:" }
                        QGCLabel { text: controller.vehicle.battery.current.valueString }

                        QGCLabel { text: "Amps per volt:" }
                        FactLabel { fact: battAmpsPerVolt }
                    }

                    QGCButton {
                        text: "Calculate"

                        onClicked:  {
                            var measuredCurrentValue = parseFloat(measuredCurrent.text)
                            if (measuredCurrentValue == 0) {
                                return
                            }
                            var newAmpsPerVolt = (measuredCurrentValue * battAmpsPerVolt.value) / controller.vehicle.battery.current.value
                            if (newAmpsPerVolt != 0) {
                                battAmpsPerVolt.value = newAmpsPerVolt
                            }
                        }
                    }
                } // Column
            } // QGCFlickable
        } // QGCViewDialog
    } // Component - calcAmpsPerVoltDlgComponent

214 215 216 217
    QGCViewPanel {
        id:             panel
        anchors.fill:   parent

Don Gagne's avatar
Don Gagne committed
218
        QGCFlickable {
219
            anchors.fill:       parent
dogmaphobic's avatar
dogmaphobic committed
220
            clip:               true
221
            contentHeight:      innerColumn.height
222
            contentWidth:       panel.width
dogmaphobic's avatar
dogmaphobic committed
223
            flickableDirection: Flickable.VerticalFlick
224 225 226

            Column {
                id:             innerColumn
Don Gagne's avatar
Don Gagne committed
227
                width:          parent.width
dogmaphobic's avatar
dogmaphobic committed
228
                spacing:        ScreenTools.defaultFontPixelHeight * 0.5
229 230

                QGCLabel {
231
                    text: qsTr("Battery")
232
                    font.family: ScreenTools.demiboldFontFamily
233
                }
234

235 236
                Rectangle {
                    width:  parent.width
237
                    height: batteryGrid.height + ScreenTools.defaultFontPixelHeight
238
                    color:  palette.windowShade
239

240 241
                    GridLayout {
                        id:                 batteryGrid
242 243 244
                        anchors.margins:    ScreenTools.defaultFontPixelHeight / 2
                        anchors.left:       parent.left
                        anchors.top:        parent.top
245 246
                        columns:            5
                        columnSpacing:      ScreenTools.defaultFontPixelWidth
247

248 249 250
                        QGCLabel {
                            text:               qsTr("Number of Cells (in Series)")
                        }
251

252 253 254 255 256 257
                        FactTextField {
                            id:         cellsField
                            width:      textEditWidth
                            fact:       battNumCells
                            showUnits:  true
                        }
258

259 260 261 262 263 264 265 266 267 268 269 270
                        QGCColoredImage {
                            id:                     batteryImage
                            Layout.rowSpan:         3
                            width:                  height * 0.75
                            height:                 100
                            sourceSize.height:      height
                            fillMode:               Image.PreserveAspectFit
                            smooth:                 true
                            color:                  palette.text
                            cache:                  false
                            source:                 getBatteryImage();
                        }
271

272 273 274 275 276
                        Item { width: 1; height: 1; Layout.columnSpan: 2 }

                        QGCLabel {
                            id:                 battHighLabel
                            text:               qsTr("Full Voltage (per cell)")
277
                        }
278

279 280 281 282 283 284
                        FactTextField {
                            id:         battHighField
                            width:      textEditWidth
                            fact:       battHighVolt
                            showUnits:  true
                        }
285

286 287 288
                        QGCLabel {
                            text:   qsTr("Battery Max:")
                        }
289

290 291
                        QGCLabel {
                            text:   (battNumCells.value * battHighVolt.value).toFixed(1) + ' V'
292 293
                        }

294 295 296 297
                        QGCLabel {
                            id:                 battLowLabel
                            text:               qsTr("Empty Voltage (per cell)")
                        }
298

299 300 301 302 303 304
                        FactTextField {
                            id:         battLowField
                            width:      textEditWidth
                            fact:       battLowVolt
                            showUnits:  true
                        }
305

306 307
                        QGCLabel {
                            text:   qsTr("Battery Min:")
308
                        }
309

310 311 312
                        QGCLabel {
                            text:   (battNumCells.value * battLowVolt.value).toFixed(1) + ' V'
                        }
Don Gagne's avatar
Don Gagne committed
313

314 315 316
                        QGCLabel {
                            text:               qsTr("Voltage divider")
                        }
Don Gagne's avatar
Don Gagne committed
317

318 319 320 321
                        FactTextField {
                            id:                 voltMultField
                            fact:               battVoltageDivider
                        }
Don Gagne's avatar
Don Gagne committed
322

323 324 325 326 327
                        QGCButton {
                            id:                 voltMultCalculateButton
                            text:               "Calculate"
                            onClicked:          showDialog(calcVoltageDividerDlgComponent, qsTr("Calculate Voltage Divider"), qgcView.showDialogDefaultWidth, StandardButton.Close)
                        }
Don Gagne's avatar
Don Gagne committed
328

329 330 331 332 333 334 335 336 337 338
                        Item { width: 1; height: 1; Layout.columnSpan: 2 }

                        QGCLabel {
                            id:                 voltMultHelp
                            Layout.columnSpan:  batteryGrid.columns
                            Layout.fillWidth:   true
                            font.pointSize:     ScreenTools.smallFontPointSize
                            wrapMode:           Text.WordWrap
                            text:               "If the battery voltage reported by the vehicle is largely different than the voltage read externally using a voltmeter you can adjust the voltage multiplier value to correct this. " +
                                                "Click the Calculate button for help with calculating a new value."
339
                        }
Don Gagne's avatar
Don Gagne committed
340

341 342 343 344
                        QGCLabel {
                            id:                 ampPerVoltLabel
                            text:               qsTr("Amps per volt")
                        }
Don Gagne's avatar
Don Gagne committed
345

346 347 348
                        FactTextField {
                            id:                 ampPerVoltField
                            fact:               battAmpsPerVolt
349
                        }
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368

                        QGCButton {
                            id:                 ampPerVoltCalculateButton
                            text:               "Calculate"
                            onClicked:          showDialog(calcAmpsPerVoltDlgComponent, qsTr("Calculate Amps per Volt"), qgcView.showDialogDefaultWidth, StandardButton.Close)
                        }

                        Item { width: 1; height: 1; Layout.columnSpan: 2 }

                        QGCLabel {
                            id:                 ampPerVoltHelp
                            Layout.columnSpan:  batteryGrid.columns
                            Layout.fillWidth:   true
                            font.pointSize:     ScreenTools.smallFontPointSize
                            wrapMode:           Text.WordWrap
                            text:               "If the current draw reported by the vehicle is largely different than the current read externally using a current meter you can adjust the amps per volt value to correct this. " +
                                                "Click the Calculate button for help with calculating a new value."
                        }
                    } // Grid
369 370 371
                } // Rectangle - Battery settings

                QGCLabel {
372
                    text:           qsTr("ESC PWM Minimum and Maximum Calibration")
373
                    font.family:    ScreenTools.demiboldFontFamily
374
                }
375

376 377 378 379
                Rectangle {
                    width:  parent.width
                    height: escCalColumn.height + ScreenTools.defaultFontPixelHeight
                    color:  palette.windowShade
380

381 382 383 384
                    Column {
                        id :                escCalColumn
                        anchors.margins:    ScreenTools.defaultFontPixelHeight / 2
                        anchors.left:       parent.left
Don Gagne's avatar
Don Gagne committed
385
                        anchors.right:      parent.right
386 387
                        anchors.top:        parent.top
                        spacing:            ScreenTools.defaultFontPixelWidth
388

389
                        QGCLabel {
Don Gagne's avatar
Don Gagne committed
390 391 392 393
                            width:      parent.width
                            color:      palette.warningText
                            wrapMode:   Text.WordWrap
                            text:       qsTr("WARNING: Propellers must be removed from vehicle prior to performing ESC calibration.")
394
                        }
Don Gagne's avatar
Don Gagne committed
395

396
                        QGCLabel {
397
                            text: qsTr("You must use USB connection for this operation.")
398
                        }
399

400
                        QGCButton {
401
                            text:       qsTr("Calibrate")
dogmaphobic's avatar
dogmaphobic committed
402
                            width:      ScreenTools.defaultFontPixelWidth * 20
403 404
                            onClicked:  controller.calibrateEsc()
                        }
dogmaphobic's avatar
dogmaphobic committed
405
                    }
406
                }
407

dogmaphobic's avatar
dogmaphobic committed
408
                QGCCheckBox {
dogmaphobic's avatar
dogmaphobic committed
409 410
                    id:         showUAVCAN
                    text:       qsTr("Show UAVCAN Settings")
Lorenz Meier's avatar
Lorenz Meier committed
411
                    visible:    uavcanEnable !== -1
dogmaphobic's avatar
dogmaphobic committed
412 413
                }

414
                QGCLabel {
415
                    text:           qsTr("UAVCAN Bus Configuration")
416
                    font.family:    ScreenTools.demiboldFontFamily
dogmaphobic's avatar
dogmaphobic committed
417
                    visible:        showUAVCAN.checked
418
                }
419

420
                Rectangle {
dogmaphobic's avatar
dogmaphobic committed
421 422 423 424
                    width:      parent.width
                    height:     uavCanConfigColumn.height + ScreenTools.defaultFontPixelHeight
                    color:      palette.windowShade
                    visible:    showUAVCAN.checked
425

426
                    Column {
427
                        id:                 uavCanConfigColumn
428 429 430 431
                        anchors.margins:    ScreenTools.defaultFontPixelHeight / 2
                        anchors.left:       parent.left
                        anchors.top:        parent.top
                        spacing:            ScreenTools.defaultFontPixelWidth
432

433 434 435
                        FactCheckBox {
                            id:                 uavcanEnabledCheckBox
                            width:              ScreenTools.defaultFontPixelWidth * 20
dogmaphobic's avatar
dogmaphobic committed
436
                            fact:               uavcanEnable
437 438
                            checkedValue:       3
                            uncheckedValue:     0
439
                            text:               qsTr("Enable UAVCAN as the default MAIN output bus (requires autopilot restart)")
440
                        }
441 442 443 444
                    }
                }

                QGCLabel {
445
                    text:           qsTr("UAVCAN Motor Index and Direction Assignment")
446
                    font.family:    ScreenTools.demiboldFontFamily
dogmaphobic's avatar
dogmaphobic committed
447
                    visible:        showUAVCAN.checked
448 449 450
                }

                Rectangle {
dogmaphobic's avatar
dogmaphobic committed
451 452 453 454 455
                    width:      parent.width
                    height:     uavCanEscCalColumn.height + ScreenTools.defaultFontPixelHeight
                    color:      palette.windowShade
                    visible:    showUAVCAN.checked
                    enabled:    uavcanEnabledCheckBox.checked
456 457 458 459 460

                    Column {
                        id:                 uavCanEscCalColumn
                        anchors.margins:    ScreenTools.defaultFontPixelHeight / 2
                        anchors.left:       parent.left
Don Gagne's avatar
Don Gagne committed
461
                        anchors.right:      parent.right
462 463
                        anchors.top:        parent.top
                        spacing:            ScreenTools.defaultFontPixelWidth
464

465
                        QGCLabel {
Don Gagne's avatar
Don Gagne committed
466 467 468 469
                            width:      parent.width
                            wrapMode:   Text.WordWrap
                            color:      palette.warningText
                            text:       qsTr("WARNING: Propellers must be removed from vehicle prior to performing UAVCAN ESC configuration.")
470 471
                        }

472
                        QGCLabel {
Don Gagne's avatar
Don Gagne committed
473 474 475
                            width:      parent.width
                            wrapMode:   Text.WordWrap
                            text:       qsTr("ESC parameters will only be accessible in the editor after assignment.")
476 477 478
                        }

                        QGCLabel {
Don Gagne's avatar
Don Gagne committed
479 480 481
                            width:      parent.width
                            wrapMode:   Text.WordWrap
                            text:       qsTr("Start the process, then turn each motor into its turn direction, in the order of their motor indices.")
482
                        }
483

484
                        QGCButton {
485
                            text:       qsTr("Start Assignment")
dogmaphobic's avatar
dogmaphobic committed
486
                            width:      ScreenTools.defaultFontPixelWidth * 20
487 488 489 490
                            onClicked:  controller.busConfigureActuators()
                        }

                        QGCButton {
491
                            text:       qsTr("Stop Assignment")
dogmaphobic's avatar
dogmaphobic committed
492
                            width:      ScreenTools.defaultFontPixelWidth * 20
dogmaphobic's avatar
dogmaphobic committed
493
                            onClicked:  controller.stopBusConfigureActuators()
494
                        }
495
                    }
496
                }
497

498 499
                QGCCheckBox {
                    id:     showAdvanced
500
                    text:   qsTr("Show Advanced Settings")
501
                }
502

503
                QGCLabel {
504
                    text:           qsTr("Advanced Power Settings")
505
                    font.family:    ScreenTools.demiboldFontFamily
506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527
                    visible:        showAdvanced.checked
                }

                Rectangle {
                    id:         batteryRectangle
                    width:      parent.width
                    height:     advBatteryColumn.height + ScreenTools.defaultFontPixelHeight
                    color:      palette.windowShade
                    visible:    showAdvanced.checked

                    Column {
                        id: advBatteryColumn
                        anchors.margins:    ScreenTools.defaultFontPixelHeight / 2
                        anchors.left:       parent.left
                        anchors.right:      parent.right
                        anchors.top:        parent.top
                        spacing:            ScreenTools.defaultFontPixelWidth

                        Row {
                            spacing: ScreenTools.defaultFontPixelWidth

                            QGCLabel {
528
                                text:               qsTr("Voltage Drop on Full Load (per cell)")
529 530 531 532 533 534 535 536 537
                                anchors.baseline:   battDropField.baseline
                            }

                            FactTextField {
                                id:         battDropField
                                width:      textEditWidth
                                fact:       battVoltLoadDrop
                                showUnits:  true
                            }
538
                        }
539

540
                        QGCLabel {
541 542
                            width:      parent.width
                            wrapMode:   Text.WordWrap
543 544
                            text:       qsTr("Batteries show less voltage at high throttle. Enter the difference in Volts between idle throttle and full ") +
                                        qsTr("throttle, divided by the number of battery cells. Leave at the default if unsure. ") +
545
                                        highlightPrefix + qsTr("If this value is set too high, the battery might be deep discharged and damaged.") + highlightSuffix
546 547 548 549 550 551
                        }

                        Row {
                            spacing: ScreenTools.defaultFontPixelWidth

                            QGCLabel {
552
                                text: qsTr("Compensated Minimum Voltage:")
553 554 555
                            }

                            QGCLabel {
556
                                text: ((battNumCells.value * battLowVolt.value) - (battNumCells.value * battVoltLoadDrop.value)).toFixed(1) + qsTr(" V")
557
                            }
558 559
                        }
                    }
560 561
                } // Rectangle - Advanced power settings
            } // Column
Don Gagne's avatar
Don Gagne committed
562
        } // QGCFlickable
563
    } // QGCViewPanel
564
} // QGCView