7import QGroundControl.FactControls
8import QGroundControl.Controls
12 pageComponent: powerPageComponent
19 id: powerPageComponent
26 property Fact _batt1Monitor: controller.getParameterFact(-1, "BATT_MONITOR")
27 property Fact _batt2Monitor: controller.getParameterFact(-1, "BATT2_MONITOR", false /* reportMissing */)
28 property bool _batt2MonitorAvailable: controller.parameterExists(-1, "BATT2_MONITOR")
29 property bool _batt1MonitorEnabled: _batt1Monitor.rawValue !== 0
30 property bool _batt2MonitorEnabled: _batt2MonitorAvailable && _batt2Monitor.rawValue !== 0
31 property bool _batt1ParamsAvailable: controller.parameterExists(-1, "BATT_CAPACITY")
32 property bool _batt2ParamsAvailable: controller.parameterExists(-1, "BATT2_CAPACITY")
33 property bool _showBatt1Reboot: _batt1MonitorEnabled && !_batt1ParamsAvailable
34 property bool _showBatt2Reboot: _batt2MonitorEnabled && !_batt2ParamsAvailable
35 property bool _escCalibrationAvailable: controller.parameterExists(-1, "ESC_CALIBRATION")
36 property Fact _escCalibration: controller.getParameterFact(-1, "ESC_CALIBRATION", false /* reportMissing */)
38 property string _restartRequired: qsTr("Requires vehicle reboot")
40 QGCPalette { id: ggcPal; colorGroupEnabled: true }
42 // Battery1 Monitor settings only - used when only monitor param is available
45 visible: !_batt1MonitorEnabled || !_batt1ParamsAvailable
48 text: qsTr("Battery 1")
53 width: batt1Column.x + batt1Column.width + _margins
54 height: batt1Column.y + batt1Column.height + _margins
55 color: ggcPal.windowShade
59 anchors.margins: _margins
60 anchors.top: parent.top
61 anchors.left: parent.left
62 spacing: ScreenTools.defaultFontPixelWidth
66 spacing: ScreenTools.defaultFontPixelWidth
68 QGCLabel { text: qsTr("Battery1 monitor:") }
78 text: _restartRequired
79 visible: _showBatt1Reboot
83 text: qsTr("Reboot vehicle")
84 visible: _showBatt1Reboot
85 onClicked: controller.vehicle.rebootVehicle()
93 id: _batt1FullSettings
95 visible: _batt1MonitorEnabled && _batt1ParamsAvailable
98 text: qsTr("Battery 1")
103 width: battery1Loader.x + battery1Loader.width + _margins
104 height: battery1Loader.y + battery1Loader.height + _margins
105 color: ggcPal.windowShade
109 anchors.margins: _margins
110 anchors.top: parent.top
111 anchors.left: parent.left
112 sourceComponent: _batt1FullSettings.visible ? powerSetupComponent : undefined
114 property Fact armVoltMin: controller.getParameterFact(-1, "r.BATT_ARM_VOLT", false /* reportMissing */)
115 property Fact battAmpPerVolt: controller.getParameterFact(-1, "r.BATT_AMP_PERVLT", false /* reportMissing */)
116 property Fact battAmpOffset: controller.getParameterFact(-1, "BATT_AMP_OFFSET", false /* reportMissing */)
117 property Fact battCapacity: controller.getParameterFact(-1, "BATT_CAPACITY", false /* reportMissing */)
118 property Fact battCurrPin: controller.getParameterFact(-1, "BATT_CURR_PIN", false /* reportMissing */)
119 property Fact battMonitor: controller.getParameterFact(-1, "BATT_MONITOR", false /* reportMissing */)
120 property Fact battVoltMult: controller.getParameterFact(-1, "BATT_VOLT_MULT", false /* reportMissing */)
121 property Fact battVoltPin: controller.getParameterFact(-1, "BATT_VOLT_PIN", false /* reportMissing */)
122 property FactGroup _batteryFactGroup: _batt1FullSettings.visible ? controller.vehicle.getFactGroup("battery0") : null
123 property Fact vehicleVoltage: _batteryFactGroup ? _batteryFactGroup.voltage : null
124 property Fact vehicleCurrent: _batteryFactGroup ? _batteryFactGroup.current : null
129 // Battery2 Monitor settings only - used when only monitor param is available
131 spacing: _margins / 2
132 visible: !_batt2MonitorEnabled || !_batt2ParamsAvailable
135 text: qsTr("Battery 2")
140 width: batt2Column.x + batt2Column.width + _margins
141 height: batt2Column.y + batt2Column.height + _margins
142 color: ggcPal.windowShade
146 anchors.margins: _margins
147 anchors.top: parent.top
148 anchors.left: parent.left
149 spacing: ScreenTools.defaultFontPixelWidth
153 spacing: ScreenTools.defaultFontPixelWidth
155 QGCLabel { text: qsTr("Battery2 monitor:") }
165 text: _restartRequired
166 visible: _showBatt2Reboot
170 text: qsTr("Reboot vehicle")
171 visible: _showBatt2Reboot
172 onClicked: controller.vehicle.rebootVehicle()
178 // Battery 2 settings - Used when full params are available
180 id: batt2FullSettings
181 spacing: _margins / 2
182 visible: _batt2MonitorEnabled && _batt2ParamsAvailable
185 text: qsTr("Battery 2")
190 width: battery2Loader.x + battery2Loader.width + _margins
191 height: battery2Loader.y + battery2Loader.height + _margins
192 color: ggcPal.windowShade
196 anchors.margins: _margins
197 anchors.top: parent.top
198 anchors.left: parent.left
199 sourceComponent: batt2FullSettings.visible ? powerSetupComponent : undefined
201 property Fact armVoltMin: controller.getParameterFact(-1, "r.BATT2_ARM_VOLT", false /* reportMissing */)
202 property Fact battAmpPerVolt: controller.getParameterFact(-1, "r.BATT2_AMP_PERVLT", false /* reportMissing */)
203 property Fact battAmpOffset: controller.getParameterFact(-1, "BATT2_AMP_OFFSET", false /* reportMissing */)
204 property Fact battCapacity: controller.getParameterFact(-1, "BATT2_CAPACITY", false /* reportMissing */)
205 property Fact battCurrPin: controller.getParameterFact(-1, "BATT2_CURR_PIN", false /* reportMissing */)
206 property Fact battMonitor: controller.getParameterFact(-1, "BATT2_MONITOR", false /* reportMissing */)
207 property Fact battVoltMult: controller.getParameterFact(-1, "BATT2_VOLT_MULT", false /* reportMissing */)
208 property Fact battVoltPin: controller.getParameterFact(-1, "BATT2_VOLT_PIN", false /* reportMissing */)
209 property FactGroup _batteryFactGroup: batt2FullSettings.visible ? controller.vehicle.getFactGroup("battery1") : null
210 property Fact vehicleVoltage: _batteryFactGroup ? _batteryFactGroup.voltage : null
211 property Fact vehicleCurrent: _batteryFactGroup ? _batteryFactGroup.current : null
217 spacing: _margins / 2
218 visible: _escCalibrationAvailable
221 text: qsTr("ESC Calibration")
226 width: escCalibrationHolder.x + escCalibrationHolder.width + _margins
227 height: escCalibrationHolder.y + escCalibrationHolder.height + _margins
228 color: ggcPal.windowShade
231 id: escCalibrationHolder
240 text: qsTr("WARNING: Remove props prior to calibration!")
241 color: qgcPal.warningText
248 text: qsTr("Calibrate")
249 enabled: _escCalibration && _escCalibration.rawValue === 0
250 onClicked: if(_escCalibration) _escCalibration.rawValue = 3
254 enabled: _escCalibration && _escCalibration.rawValue === 3
255 QGCLabel { text: _escCalibration ? (_escCalibration.rawValue === 3 ? qsTr("Now perform these steps:") : qsTr("Click Calibrate to start, then:")) : "" }
256 QGCLabel { text: qsTr("- Disconnect USB and battery so flight controller powers down") }
257 QGCLabel { text: qsTr("- Connect the battery") }
258 QGCLabel { text: qsTr("- The arming tone will be played (if the vehicle has a buzzer attached)") }
259 QGCLabel { text: qsTr("- If using a flight controller with a safety button press it until it displays solid red") }
260 QGCLabel { text: qsTr("- You will hear a musical tone then two beeps") }
261 QGCLabel { text: qsTr("- A few seconds later you should hear a number of beeps (one for each battery cell you're using)") }
262 QGCLabel { text: qsTr("- And finally a single long beep indicating the end points have been set and the ESC is calibrated") }
263 QGCLabel { text: qsTr("- Disconnect the battery and power up again normally") }
271 } // Component - powerPageComponent
274 id: powerSetupComponent
279 property real _margins: ScreenTools.defaultFontPixelHeight / 2
280 property bool _showAdvanced: sensorCombo.currentIndex === sensorModel.count - 1
281 property real _fieldWidth: ScreenTools.defaultFontPixelWidth * 25
283 Component.onCompleted: calcSensor()
285 function calcSensor() {
286 for (var i=0; i<sensorModel.count - 1; i++) {
287 if (sensorModel.get(i).voltPin === battVoltPin.value &&
288 sensorModel.get(i).currPin === battCurrPin.value &&
289 Math.abs(sensorModel.get(i).voltMult - battVoltMult.value) < 0.001 &&
290 Math.abs(sensorModel.get(i).ampPerVolt - battAmpPerVolt.value) < 0.0001 &&
291 Math.abs(sensorModel.get(i).ampOffset - battAmpOffset.value) < 0.0001) {
292 sensorCombo.currentIndex = i
296 sensorCombo.currentIndex = sensorModel.count - 1
299 QGCPalette { id: qgcPal; colorGroupEnabled: true }
305 text: qsTr("Power Module 90A")
314 text: qsTr("Power Module HV")
323 text: qsTr("3DR Iris")
332 text: qsTr("Blue Robotics Power Sense Module")
341 text: qsTr("Navigator w/ Blue Robotics Power Sense Module")
358 columnSpacing: _margins
360 QGCLabel { text: qsTr("Battery monitor:") }
372 text: qsTr("Battery capacity:")
384 text: qsTr("Minimum arming voltage:")
396 text: qsTr("Power sensor:")
401 Layout.minimumWidth: _fieldWidth
405 onActivated: (index) => {
406 if (index < sensorModel.count - 1) {
407 battVoltPin.value = sensorModel.get(index).voltPin
408 battCurrPin.value = sensorModel.get(index).currPin
409 battVoltMult.value = sensorModel.get(index).voltMult
410 battAmpPerVolt.value = sensorModel.get(index).ampPerVolt
411 battAmpOffset.value = sensorModel.get(index).ampOffset
421 text: qsTr("Current pin:")
422 visible: _showAdvanced
426 Layout.minimumWidth: _fieldWidth
429 visible: _showAdvanced
436 text: qsTr("Voltage pin:")
437 visible: _showAdvanced
441 Layout.minimumWidth: _fieldWidth
444 visible: _showAdvanced
451 text: qsTr("Voltage multiplier:")
452 visible: _showAdvanced
458 visible: _showAdvanced
462 text: qsTr("Calculate")
463 visible: _showAdvanced
464 onClicked: calcVoltageMultiplierDlgFactory.open({ vehicleVoltageFact: vehicleVoltage, battVoltMultFact: battVoltMult })
469 Layout.fillWidth: true
470 font.pointSize: ScreenTools.smallFontPointSize
471 wrapMode: Text.WordWrap
472 text: qsTr("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.")
473 visible: _showAdvanced
477 text: qsTr("Amps per volt:")
478 visible: _showAdvanced
484 visible: _showAdvanced
488 text: qsTr("Calculate")
489 visible: _showAdvanced
490 onClicked: calcAmpsPerVoltDlgFactory.open({ vehicleCurrentFact: vehicleCurrent, battAmpPerVoltFact: battAmpPerVolt })
495 Layout.fillWidth: true
496 font.pointSize: ScreenTools.smallFontPointSize
497 wrapMode: Text.WordWrap
498 text: qsTr("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.")
499 visible: _showAdvanced
503 text: qsTr("Amps Offset:")
504 visible: _showAdvanced
510 visible: _showAdvanced
515 Layout.fillWidth: true
516 font.pointSize: ScreenTools.smallFontPointSize
517 wrapMode: Text.WordWrap
518 text: qsTr("If the vehicle reports a high current read when there is little or no current going through it, adjust the Amps Offset. It should be equal to the voltage reported by the sensor when the current is zero.")
519 visible: _showAdvanced
524 } // Component - powerSetupComponent
526 QGCPopupDialogFactory {
527 id: calcVoltageMultiplierDlgFactory
529 dialogComponent: calcVoltageMultiplierDlgComponent
533 id: calcVoltageMultiplierDlgComponent
536 title: qsTr("Calculate Voltage Multiplier")
537 buttons: Dialog.Close
539 property Fact vehicleVoltageFact
540 property Fact battVoltMultFact
543 spacing: ScreenTools.defaultFontPixelHeight
546 Layout.preferredWidth: gridLayout.width
547 wrapMode: Text.WordWrap
548 text: qsTr("Measure battery voltage using an external voltmeter and enter the value below. Click Calculate to set the new adjusted voltage multiplier.")
556 text: qsTr("Measured voltage:")
558 QGCTextField { id: measuredVoltage }
560 QGCLabel { text: qsTr("Vehicle voltage:") }
561 FactLabel { fact: vehicleVoltageFact }
563 QGCLabel { text: qsTr("Voltage multiplier:") }
564 FactLabel { fact: battVoltMultFact }
568 text: qsTr("Calculate And Set")
571 var measuredVoltageValue = parseFloat(measuredVoltage.text)
572 if (measuredVoltageValue === 0 || isNaN(measuredVoltageValue) || !vehicleVoltageFact || !battVoltMultFact) {
575 var newVoltageMultiplier = (vehicleVoltageFact.value !== 0) ? (measuredVoltageValue * battVoltMultFact.value) / vehicleVoltageFact.value : 0
576 if (newVoltageMultiplier > 0) {
577 battVoltMultFact.value = newVoltageMultiplier
585 QGCPopupDialogFactory {
586 id: calcAmpsPerVoltDlgFactory
588 dialogComponent: calcAmpsPerVoltDlgComponent
592 id: calcAmpsPerVoltDlgComponent
595 title: qsTr("Calculate Amps per Volt")
596 buttons: Dialog.Close
598 property Fact vehicleCurrentFact
599 property Fact battAmpPerVoltFact
602 spacing: ScreenTools.defaultFontPixelHeight
605 Layout.preferredWidth: gridLayout.width
606 wrapMode: Text.WordWrap
607 text: qsTr("Measure current draw using an external current meter and enter the value below. Click Calculate to set the new amps per volt value.")
615 text: qsTr("Measured current:")
617 QGCTextField { id: measuredCurrent }
619 QGCLabel { text: qsTr("Vehicle current:") }
620 FactLabel { fact: vehicleCurrentFact }
622 QGCLabel { text: qsTr("Amps per volt:") }
623 FactLabel { fact: battAmpPerVoltFact }
627 text: qsTr("Calculate And Set")
630 var measuredCurrentValue = parseFloat(measuredCurrent.text)
631 if (measuredCurrentValue === 0 || isNaN(measuredCurrentValue) || !vehicleCurrentFact || !battAmpPerVoltFact) {
634 var newAmpsPerVolt = (vehicleCurrentFact.value !== 0) ? (measuredCurrentValue * battAmpPerVoltFact.value) / vehicleCurrentFact.value : 0
635 if (newAmpsPerVolt !== 0) {
636 battAmpPerVoltFact.value = newAmpsPerVolt