QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
APMTuningComponentCopter.qml
Go to the documentation of this file.
1import QtQuick
2import QtQuick.Controls
3import QtQuick.Layouts
4
5import QGroundControl
6import QGroundControl.FactControls
7import QGroundControl.Controls
8
9SetupPage {
10 id: tuningPage
11 pageComponent: tuningPageComponent
12
13 Component {
14 id: tuningPageComponent
15
16 ColumnLayout {
17 width: availableWidth
18
19 FactPanelController { id: controller; }
20
21 property bool _atcInputTCAvailable: controller.parameterExists(-1, "ATC_INPUT_TC")
22 property Fact _atcInputTC: controller.getParameterFact(-1, "ATC_INPUT_TC", false)
23 property Fact _rateRollP: controller.getParameterFact(-1, "ATC_RAT_RLL_P")
24 property Fact _rateRollI: controller.getParameterFact(-1, "ATC_RAT_RLL_I")
25 property Fact _ratePitchP: controller.getParameterFact(-1, "ATC_RAT_PIT_P")
26 property Fact _ratePitchI: controller.getParameterFact(-1, "ATC_RAT_PIT_I")
27 property Fact _rateClimbP: controller.getParameterFact(-1, "PSC_ACCZ_P")
28 property Fact _rateClimbI: controller.getParameterFact(-1, "PSC_ACCZ_I")
29 property Fact _motSpinArm: controller.getParameterFact(-1, "MOT_SPIN_ARM")
30 property Fact _motSpinMin: controller.getParameterFact(-1, "MOT_SPIN_MIN")
31
32 property Fact _ch7Opt: controller.getParameterFact(-1, "r.RC7_OPTION")
33 property Fact _ch8Opt: controller.getParameterFact(-1, "r.RC8_OPTION")
34 property Fact _ch9Opt: controller.getParameterFact(-1, "r.RC9_OPTION")
35 property Fact _ch10Opt: controller.getParameterFact(-1, "r.RC10_OPTION")
36 property Fact _ch11Opt: controller.getParameterFact(-1, "r.RC11_OPTION")
37 property Fact _ch12Opt: controller.getParameterFact(-1, "r.RC12_OPTION")
38
39 readonly property int _firstOptionChannel: 7
40 readonly property int _lastOptionChannel: 12
41
42 property Fact _autoTuneAxes: controller.getParameterFact(-1, "AUTOTUNE_AXES")
43 property int _autoTuneSwitchChannelIndex: 0
44 readonly property int _autoTuneOption: 17
45
46 property real _margins: ScreenTools.defaultFontPixelHeight
47
48 property bool _loadComplete: false
49
50 Component.onCompleted: {
51 // We use QtCharts only on Desktop platforms
52 showAdvanced = !ScreenTools.isMobile
53 _loadComplete = true
54 calcAutoTuneChannel()
55 }
56
57 /// The AutoTune switch is stored in one of the RC#_OPTION parameters. We need to loop through those
58 /// to find them and setup the ui accordindly.
59 function calcAutoTuneChannel() {
60 _autoTuneSwitchChannelIndex = 0
61 for (var channel=_firstOptionChannel; channel<=_lastOptionChannel; channel++) {
62 var optionFact = controller.getParameterFact(-1, "r.RC" + channel + "_OPTION")
63 if (optionFact.value == _autoTuneOption) {
64 _autoTuneSwitchChannelIndex = channel - _firstOptionChannel + 1
65 break
66 }
67 }
68 }
69
70 /// We need to clear AutoTune from any previous channel before setting it to a new one
71 function setChannelAutoTuneOption(channel) {
72 // First clear any previous settings for AutTune
73 for (var optionChannel=_firstOptionChannel; optionChannel<=_lastOptionChannel; optionChannel++) {
74 var optionFact = controller.getParameterFact(-1, "r.RC" + optionChannel + "_OPTION")
75 if (optionFact.value == _autoTuneOption) {
76 optionFact.value = 0
77 }
78 }
79
80 // Now set the function into the new channel
81 if (channel != 0) {
82 var optionFact = controller.getParameterFact(-1, "r.RC" + channel + "_OPTION")
83 optionFact.value = _autoTuneOption
84 }
85 }
86
87 Connections { target: _ch7Opt; function onValueChanged(value) { calcAutoTuneChannel() } }
88 Connections { target: _ch8Opt; function onValueChanged(value) { calcAutoTuneChannel() } }
89 Connections { target: _ch9Opt; function onValueChanged(value) { calcAutoTuneChannel() } }
90 Connections { target: _ch10Opt; function onValueChanged(value) { calcAutoTuneChannel() } }
91 Connections { target: _ch11Opt; function onValueChanged(value) { calcAutoTuneChannel() } }
92 Connections { target: _ch12Opt; function onValueChanged(value) { calcAutoTuneChannel() } }
93
94 ColumnLayout {
95 Layout.fillWidth: true
96 spacing: _margins
97 visible: !advanced
98
99 SettingsGroupLayout {
100 Layout.fillWidth: true
101 heading: qsTr("Roll/Pitch Sensitivity")
102 headingDescription: qsTr("Slide to the right if the copter is sluggish or slide to the left if the copter is twitchy")
103
104 FactSlider {
105 id: rollPitch
106 Layout.fillWidth: true
107 from: 0.08
108 to: 0.4
109 majorTickStepSize: 0.02
110 decimalPlaces: 3
111 fact: _rateRollP
112
113 onValueChanged: {
114 _rateRollI.rawValue = value
115 _ratePitchP.rawValue = value
116 _ratePitchI.rawValue = value
117 }
118 }
119 }
120
121 SettingsGroupLayout {
122 Layout.fillWidth: true
123 heading: qsTr("Climb Sensitivity")
124 headingDescription: qsTr("Slide to the right to climb more aggressively or slide to the left to climb more gently")
125
126 FactSlider {
127 id: climb
128 Layout.fillWidth: true
129 from: 0.03
130 to: 1.0
131 majorTickStepSize: 0.05
132 decimalPlaces: 3
133 fact: _rateClimbP
134 onValueChanged: _rateClimbI.rawValue = value * 2
135 }
136 }
137
138 SettingsGroupLayout {
139 Layout.fillWidth: true
140 heading: qsTr("RC Roll/Pitch Feel")
141 headingDescription: qsTr("Slide to the left for soft control, slide to the right for crisp control")
142
143 FactSlider {
144 id: atcInputTC
145 Layout.fillWidth: true
146 from: _atcInputTC.min
147 to: _atcInputTC.max
148 majorTickStepSize: _atcInputTC.increment
149 decimalPlaces: 2
150 unitsString: ""
151 fact: _atcInputTC
152 }
153 }
154
155 SettingsGroupLayout {
156 Layout.fillWidth: true
157 heading: qsTr("Spin While Armed")
158 headingDescription: qsTr("Adjust the amount the motors spin to indicate armed. Should be lower than 'Minimum Thrust'")
159
160 FactSlider {
161 Layout.fillWidth: true
162 from: 0
163 to: 0.3
164 majorTickStepSize: 0.1
165 decimalPlaces: 1
166 fact: _motSpinArm
167 }
168 }
169
170 SettingsGroupLayout {
171 Layout.fillWidth: true
172 heading: qsTr("Minimum Thrust")
173 headingDescription: qsTr("Adjust the minimum amount of thrust require for the vehicle to move. Should be higher than 'Spin While Armed")
174
175 FactSlider {
176 Layout.fillWidth: true
177 from: 0
178 to: 0.3
179 majorTickStepSize: 0.1
180 decimalPlaces: 1
181 fact: _motSpinArm
182 }
183 }
184
185 Flow {
186 id: flowLayout
187 Layout.fillWidth: true
188 spacing: _margins
189
190 SettingsGroupLayout {
191 heading: qsTr("AutoTune")
192
193 ColumnLayout {
194 RowLayout {
195 spacing: _margins
196
197 QGCLabel { text: qsTr("Axes to AutoTune:") }
198 FactBitmask { fact: _autoTuneAxes }
199 }
200
201 LabelledComboBox {
202 id: autoTuneChannelCombo
203 width: ScreenTools.defaultFontPixelWidth * 14
204 label: qsTr("Channel for AutoTune switch:")
205 model: [qsTr("None"), qsTr("Channel 7"), qsTr("Channel 8"), qsTr("Channel 9"), qsTr("Channel 10"), qsTr("Channel 11"), qsTr("Channel 12") ]
206 currentIndex: _autoTuneSwitchChannelIndex
207
208 onActivated: (index) => {
209 var channel = index
210
211 if (channel > 0) {
212 channel += 6
213 }
214 setChannelAutoTuneOption(channel)
215 }
216 }
217 }
218 }
219
220 SettingsGroupLayout {
221 heading: qsTr("In Flight Tuning")
222
223 ColumnLayout {
224 id: channel6TuningOptColumn
225 spacing: ScreenTools.defaultFontPixelHeight
226
227 LabelledFactComboBox {
228 id: optCombo
229 width: ScreenTools.defaultFontPixelWidth * 15
230 label: qsTr("RC Channel 6 Option (Tuning):")
231 fact: controller.getParameterFact(-1, "TUNE")
232 indexModel: false
233 }
234
235 RowLayout {
236 spacing: ScreenTools.defaultFontPixelWidth
237
238 LabelledFactTextField {
239 id: tuneMinField
240 textField.validator: DoubleValidator {bottom: 0; top: 32767;}
241 label: qsTr("Min:")
242 fact: controller.getParameterFact(-1, "r.TUNE_MIN")
243 }
244
245 LabelledFactTextField {
246 id: tuneMaxField
247 textField.validator: DoubleValidator {bottom: 0; top: 32767;}
248 label: qsTr("Max:")
249 fact: controller.getParameterFact(-1, "r.TUNE_MAX")
250 }
251 }
252 }
253 }
254 }
255 }
256
257 Loader {
258 Layout.fillWidth: true
259 sourceComponent: advanced ? advancePageComponent : undefined
260 }
261
262 Component {
263 id: advancePageComponent
264
265 PIDTuning {
266 property bool useAutoTuning: false
267
268 property var roll: QtObject {
269 property string name: qsTr("Roll")
270 property var plot: [
271 { name: "Response", value: globals.activeVehicle.rollRate.value },
272 { name: "Setpoint", value: globals.activeVehicle.setpoint.rollRate.value }
273 ]
274 property var params: ListModel {
275 ListElement {
276 title: qsTr("Roll axis angle controller P gain")
277 param: "ATC_ANG_RLL_P"
278 description: ""
279 min: 3
280 max: 12
281 step: 1
282 }
283 ListElement {
284 title: qsTr("Roll axis rate controller P gain")
285 param: "ATC_RAT_RLL_P"
286 description: ""
287 min: 0.001
288 max: 0.5
289 step: 0.025
290 }
291 ListElement {
292 title: qsTr("Roll axis rate controller I gain")
293 param: "ATC_RAT_RLL_I"
294 description: ""
295 min: 0.01
296 max: 2
297 step: 0.05
298 }
299 ListElement {
300 title: qsTr("Roll axis rate controller D gain")
301 param: "ATC_RAT_RLL_D"
302 description: ""
303 min: 0.0
304 max: 0.05
305 step: 0.001
306 }
307 }
308 }
309 property var pitch: QtObject {
310 property string name: qsTr("Pitch")
311 property var plot: [
312 { name: "Response", value: globals.activeVehicle.pitchRate.value },
313 { name: "Setpoint", value: globals.activeVehicle.setpoint.pitchRate.value }
314 ]
315 property var params: ListModel {
316 ListElement {
317 title: qsTr("Pitch axis angle controller P gain")
318 param: "ATC_ANG_PIT_P"
319 description: ""
320 min: 3
321 max: 12
322 step: 1
323 }
324 ListElement {
325 title: qsTr("Pitch axis rate controller P gain")
326 param: "ATC_RAT_PIT_P"
327 description: ""
328 min: 0.001
329 max: 0.5
330 step: 0.025
331 }
332 ListElement {
333 title: qsTr("Pitch axis rate controller I gain")
334 param: "ATC_RAT_PIT_I"
335 description: ""
336 min: 0.01
337 max: 2
338 step: 0.05
339 }
340 ListElement {
341 title: qsTr("Pitch axis rate controller D gain")
342 param: "ATC_RAT_PIT_D"
343 description: ""
344 min: 0.0
345 max: 0.05
346 step: 0.001
347 }
348 }
349 }
350 property var yaw: QtObject {
351 property string name: qsTr("Yaw")
352 property var plot: [
353 { name: "Response", value: globals.activeVehicle.yawRate.value },
354 { name: "Setpoint", value: globals.activeVehicle.setpoint.yawRate.value }
355 ]
356 property var params: ListModel {
357 ListElement {
358 title: qsTr("Yaw axis angle controller P gain")
359 param: "ATC_ANG_YAW_P"
360 description: ""
361 min: 3
362 max: 12
363 step: 1
364 }
365 ListElement {
366 title: qsTr("Yaw axis rate controller P gain")
367 param: "ATC_RAT_YAW_P"
368 description: ""
369 min: 0.1
370 max: 2.5
371 step: 0.05
372 }
373 ListElement {
374 title: qsTr("Yaw axis rate controller I gain")
375 param: "ATC_RAT_YAW_I"
376 description: ""
377 min: 0.01
378 max: 1
379 step: 0.05
380 }
381 }
382 }
383 title: "Rate"
384 tuningMode: Vehicle.ModeDisabled
385 unit: "deg/s"
386 axis: [ roll, pitch, yaw ]
387 chartDisplaySec: 3
388 }
389 } // Component - Advanced Page
390 } // Column
391 } // Component
392} // SetupView