Newer
Older
/****************************************************************************
*
* (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.
*
****************************************************************************/
/// @file
/// @brief Battery, propeller and magnetometer settings
/// @author Gus Grubba <mavlink@grubba.com>
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.2
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
SetupPage {
id: powerPage
pageComponent: pageComponent
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
id: pageComponent
Column {
id: innerColumn
width: availableWidth
spacing: ScreenTools.defaultFontPixelHeight * 0.5
property int textEditWidth: ScreenTools.defaultFontPixelWidth * 8
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)
readonly property string highlightPrefix: "<font color=\"" + qgcPal.warningText + "\">"
readonly property string highlightSuffix: "</font>"
function getBatteryImage()
{
switch(battNumCells.value) {
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";
}
}
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: powerPage.viewPanel
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)
}
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 }
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
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
QGCLabel {
text: qsTr("Battery")
font.family: ScreenTools.demiboldFontFamily
}
Rectangle {
width: parent.width
height: batteryGrid.height + ScreenTools.defaultFontPixelHeight
color: qgcPal.windowShade
GridLayout {
id: batteryGrid
anchors.margins: ScreenTools.defaultFontPixelHeight / 2
anchors.left: parent.left
anchors.top: parent.top
columns: 5
columnSpacing: ScreenTools.defaultFontPixelWidth
text: qsTr("Number of Cells (in Series)")
FactTextField {
id: cellsField
width: textEditWidth
fact: battNumCells
showUnits: true
QGCColoredImage {
id: batteryImage
Layout.rowSpan: 3
width: height * 0.75
height: 100
sourceSize.height: height
fillMode: Image.PreserveAspectFit
smooth: true
color: qgcPal.text
cache: false
source: getBatteryImage();
Item { width: 1; height: 1; Layout.columnSpan: 2 }
QGCLabel {
id: battHighLabel
text: qsTr("Full Voltage (per cell)")
}
FactTextField {
id: battHighField
width: textEditWidth
fact: battHighVolt
showUnits: true
}
QGCLabel {
text: qsTr("Battery Max:")
}
QGCLabel {
text: (battNumCells.value * battHighVolt.value).toFixed(1) + ' V'
}
QGCLabel {
id: battLowLabel
text: qsTr("Empty Voltage (per cell)")
}
FactTextField {
id: battLowField
width: textEditWidth
fact: battLowVolt
showUnits: true
}
QGCLabel {
text: qsTr("Battery Min:")
}
QGCLabel {
text: (battNumCells.value * battLowVolt.value).toFixed(1) + ' V'
}
QGCLabel {
text: qsTr("Voltage divider")
}
FactTextField {
id: voltMultField
fact: battVoltageDivider
}
QGCButton {
id: voltMultCalculateButton
text: "Calculate"
onClicked: showDialog(calcVoltageDividerDlgComponent, qsTr("Calculate Voltage Divider"), powerPage.showDialogDefaultWidth, StandardButton.Close)
}
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."
}
QGCLabel {
id: ampPerVoltLabel
text: qsTr("Amps per volt")
}
FactTextField {
id: ampPerVoltField
fact: battAmpsPerVolt
}
QGCButton {
id: ampPerVoltCalculateButton
text: "Calculate"
onClicked: showDialog(calcAmpsPerVoltDlgComponent, qsTr("Calculate Amps per Volt"), powerPage.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
} // Rectangle - Battery settings
QGCLabel {
text: qsTr("ESC PWM Minimum and Maximum Calibration")
font.family: ScreenTools.demiboldFontFamily
}
Rectangle {
width: parent.width
height: escCalColumn.height + ScreenTools.defaultFontPixelHeight
color: qgcPal.windowShade
Column {
id : escCalColumn
anchors.margins: ScreenTools.defaultFontPixelHeight / 2
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
spacing: ScreenTools.defaultFontPixelWidth
QGCLabel {
width: parent.width
color: qgcPal.warningText
wrapMode: Text.WordWrap
text: qsTr("WARNING: Propellers must be removed from vehicle prior to performing ESC calibration.")
}
QGCLabel {
text: qsTr("You must use USB connection for this operation.")
}
QGCButton {
text: qsTr("Calibrate")
width: ScreenTools.defaultFontPixelWidth * 20
onClicked: controller.calibrateEsc()
}
}
QGCCheckBox {
id: showUAVCAN
text: qsTr("Show UAVCAN Settings")
visible: uavcanEnable !== -1
}
QGCLabel {
text: qsTr("UAVCAN Bus Configuration")
font.family: ScreenTools.demiboldFontFamily
visible: showUAVCAN.checked
}
Rectangle {
width: parent.width
height: uavCanConfigColumn.height + ScreenTools.defaultFontPixelHeight
color: qgcPal.windowShade
visible: showUAVCAN.checked
Column {
id: uavCanConfigColumn
anchors.margins: ScreenTools.defaultFontPixelHeight / 2
anchors.left: parent.left
anchors.top: parent.top
spacing: ScreenTools.defaultFontPixelWidth
FactCheckBox {
id: uavcanEnabledCheckBox
width: ScreenTools.defaultFontPixelWidth * 20
fact: uavcanEnable
checkedValue: 3
uncheckedValue: 0
text: qsTr("Enable UAVCAN as the default MAIN output bus (requires autopilot restart)")
}
}
}
QGCLabel {
text: qsTr("UAVCAN Motor Index and Direction Assignment")
font.family: ScreenTools.demiboldFontFamily
visible: showUAVCAN.checked
}
Rectangle {
width: parent.width
height: uavCanEscCalColumn.height + ScreenTools.defaultFontPixelHeight
color: qgcPal.windowShade
visible: showUAVCAN.checked
enabled: uavcanEnabledCheckBox.checked
Column {
id: uavCanEscCalColumn
anchors.margins: ScreenTools.defaultFontPixelHeight / 2
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
spacing: ScreenTools.defaultFontPixelWidth
QGCLabel {
width: parent.width
wrapMode: Text.WordWrap
color: qgcPal.warningText
text: qsTr("WARNING: Propellers must be removed from vehicle prior to performing UAVCAN ESC configuration.")
QGCLabel {
width: parent.width
wrapMode: Text.WordWrap
text: qsTr("ESC parameters will only be accessible in the editor after assignment.")
}
QGCLabel {
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.")
}
QGCButton {
text: qsTr("Start Assignment")
width: ScreenTools.defaultFontPixelWidth * 20
onClicked: controller.busConfigureActuators()
QGCButton {
text: qsTr("Stop Assignment")
width: ScreenTools.defaultFontPixelWidth * 20
onClicked: controller.stopBusConfigureActuators()
}
}
QGCCheckBox {
id: showAdvanced
text: qsTr("Show Advanced Settings")
}
QGCLabel {
text: qsTr("Advanced Power Settings")
font.family: ScreenTools.demiboldFontFamily
visible: showAdvanced.checked
}
Rectangle {
id: batteryRectangle
width: parent.width
height: advBatteryColumn.height + ScreenTools.defaultFontPixelHeight
color: qgcPal.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
text: qsTr("Voltage Drop on Full Load (per cell)")
anchors.baseline: battDropField.baseline
FactTextField {
id: battDropField
width: textEditWidth
fact: battVoltLoadDrop
showUnits: true
QGCLabel {
width: parent.width
wrapMode: Text.WordWrap
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. ") +
highlightPrefix + qsTr("If this value is set too high, the battery might be deep discharged and damaged.") + highlightSuffix
}
Row {
spacing: ScreenTools.defaultFontPixelWidth
text: qsTr("Compensated Minimum Voltage:")
QGCLabel {
text: ((battNumCells.value * battLowVolt.value) - (battNumCells.value * battVoltLoadDrop.value)).toFixed(1) + qsTr(" V")