2 ******************************************************************************
4 * @file configstabilizationwidget.cpp
5 * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
6 * E. Lafargue & The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
7 * @addtogroup GCSPlugins GCS Plugins
9 * @addtogroup ConfigPlugin Config Plugin
11 * @brief The Configuration Gadget used to update settings in the firmware
12 *****************************************************************************/
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 3 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "configstabilizationwidget.h"
30 #include "ui_stabilization.h"
32 #include <extensionsystem/pluginmanager.h>
33 #include <coreplugin/generalsettings.h>
34 #include "uavobjectutilmanager.h"
36 #include "objectpersistence.h"
37 #include "altitudeholdsettings.h"
38 #include "stabilizationsettings.h"
40 #include "qwt/src/qwt.h"
41 #include "qwt/src/qwt_plot.h"
42 #include "qwt/src/qwt_plot_canvas.h"
43 #include "qwt/src/qwt_scale_widget.h"
46 #include <QStringList>
49 #include <QVBoxLayout>
50 #include <QPushButton>
51 #include <QDesktopServices>
55 #include <QMessageBox>
56 #include <QToolButton>
60 ConfigStabilizationWidget::ConfigStabilizationWidget(QWidget
*parent
) : ConfigTaskWidget(parent
),
61 boardModel(0), m_stabSettingsBankCount(0), m_currentStabSettingsBank(0)
63 ui
= new Ui_StabilizationWidget();
66 setWikiURL("Stabilization+Configuration");
72 ExtensionSystem::PluginManager
*pm
= ExtensionSystem::PluginManager::instance();
73 Core::Internal::GeneralSettings
*settings
= pm
->getObject
<Core::Internal::GeneralSettings
>();
75 if (!settings
->useExpertMode()) {
76 ui
->saveStabilizationToRAM_6
->setVisible(false);
81 realtimeUpdates
= new QTimer(this);
82 connect(realtimeUpdates
, SIGNAL(timeout()), this, SLOT(apply()));
84 connect(ui
->realTimeUpdates_6
, SIGNAL(toggled(bool)), this, SLOT(realtimeUpdatesSlot(bool)));
85 addWidget(ui
->realTimeUpdates_6
);
86 connect(ui
->realTimeUpdates_8
, SIGNAL(toggled(bool)), this, SLOT(realtimeUpdatesSlot(bool)));
87 addWidget(ui
->realTimeUpdates_8
);
88 connect(ui
->realTimeUpdates_12
, SIGNAL(toggled(bool)), this, SLOT(realtimeUpdatesSlot(bool)));
89 addWidget(ui
->realTimeUpdates_12
);
90 connect(ui
->realTimeUpdates_7
, SIGNAL(toggled(bool)), this, SLOT(realtimeUpdatesSlot(bool)));
91 addWidget(ui
->realTimeUpdates_7
);
93 connect(ui
->checkBox_7
, SIGNAL(toggled(bool)), this, SLOT(linkCheckBoxes(bool)));
94 addWidget(ui
->checkBox_7
);
95 connect(ui
->checkBox_2
, SIGNAL(toggled(bool)), this, SLOT(linkCheckBoxes(bool)));
96 addWidget(ui
->checkBox_2
);
97 connect(ui
->checkBox_8
, SIGNAL(toggled(bool)), this, SLOT(linkCheckBoxes(bool)));
98 addWidget(ui
->checkBox_8
);
99 connect(ui
->checkBox_3
, SIGNAL(toggled(bool)), this, SLOT(linkCheckBoxes(bool)));
100 addWidget(ui
->checkBox_3
);
102 connect(ui
->checkBoxLinkAcroFactors
, SIGNAL(toggled(bool)), this, SLOT(linkCheckBoxes(bool)));
103 addWidget(ui
->checkBoxLinkAcroFactors
);
105 addWidget(ui
->pushButton_2
);
106 addWidget(ui
->pushButton_3
);
107 addWidget(ui
->pushButton_4
);
108 addWidget(ui
->pushButton_5
);
109 addWidget(ui
->pushButton_6
);
110 addWidget(ui
->pushButton_7
);
111 addWidget(ui
->pushButton_8
);
112 addWidget(ui
->pushButton_9
);
113 addWidget(ui
->pushButton_10
);
114 addWidget(ui
->pushButton_11
);
115 addWidget(ui
->pushButton_12
);
116 addWidget(ui
->pushButton_13
);
117 addWidget(ui
->pushButton_14
);
118 addWidget(ui
->pushButton_20
);
119 addWidget(ui
->pushButton_22
);
120 addWidget(ui
->pushButton_23
);
122 addWidget(ui
->basicResponsivenessGroupBox
);
123 addWidget(ui
->basicResponsivenessCheckBox
);
124 connect(ui
->basicResponsivenessCheckBox
, SIGNAL(toggled(bool)), this, SLOT(linkCheckBoxes(bool)));
125 addWidget(ui
->advancedResponsivenessGroupBox
);
126 addWidget(ui
->advancedResponsivenessCheckBox
);
127 connect(ui
->advancedResponsivenessCheckBox
, SIGNAL(toggled(bool)), this, SLOT(linkCheckBoxes(bool)));
129 connect(ui
->defaultThrottleCurveButton
, SIGNAL(clicked()), this, SLOT(resetThrottleCurveToDefault()));
130 connect(ui
->enableThrustPIDScalingCheckBox
, SIGNAL(toggled(bool)), ui
->ThrustPIDSource
, SLOT(setEnabled(bool)));
131 connect(ui
->enableThrustPIDScalingCheckBox
, SIGNAL(toggled(bool)), ui
->ThrustPIDTarget
, SLOT(setEnabled(bool)));
132 connect(ui
->enableThrustPIDScalingCheckBox
, SIGNAL(toggled(bool)), ui
->ThrustPIDAxis
, SLOT(setEnabled(bool)));
133 connect(ui
->enableThrustPIDScalingCheckBox
, SIGNAL(toggled(bool)), ui
->thrustPIDScalingCurve
, SLOT(setEnabled(bool)));
134 ui
->thrustPIDScalingCurve
->setXAxisLabel(tr("Thrust"));
135 ui
->thrustPIDScalingCurve
->setYAxisLabel(tr("Scaling factor"));
136 ui
->thrustPIDScalingCurve
->setMin(-0.5);
137 ui
->thrustPIDScalingCurve
->setMax(0.5);
138 ui
->thrustPIDScalingCurve
->initLinearCurve(5, -0.25, 0.25);
139 connect(ui
->thrustPIDScalingCurve
, SIGNAL(curveUpdated()), this, SLOT(throttleCurveUpdated()));
141 addWidget(ui
->defaultThrottleCurveButton
);
142 addWidget(ui
->enableThrustPIDScalingCheckBox
);
143 addWidget(ui
->thrustPIDScalingCurve
);
144 addWidget(ui
->thrustPIDScalingCurve
);
145 connect(this, SIGNAL(widgetContentsChanged(QWidget
*)), this, SLOT(processLinkedWidgets(QWidget
*)));
147 connect(this, SIGNAL(autoPilotConnected()), this, SLOT(onBoardConnected()));
149 addWidget(ui
->expoPlot
);
150 connect(ui
->expoSpinnerRoll
, SIGNAL(valueChanged(int)), this, SLOT(replotExpoRoll(int)));
151 connect(ui
->expoSpinnerPitch
, SIGNAL(valueChanged(int)), this, SLOT(replotExpoPitch(int)));
152 connect(ui
->expoSpinnerYaw
, SIGNAL(valueChanged(int)), this, SLOT(replotExpoYaw(int)));
154 disableMouseWheelEvents();
155 updateEnableControls();
158 void ConfigStabilizationWidget::setupStabBanksGUI()
160 StabilizationSettings
*stabSettings
= qobject_cast
<StabilizationSettings
*>(getObject("StabilizationSettings"));
162 Q_ASSERT(stabSettings
);
164 m_stabSettingsBankCount
= stabSettings
->getField("FlightModeMap")->getOptions().count();
166 // Set up fake tab widget stuff for pid banks support
167 m_stabTabBars
.append(ui
->basicPIDBankTabBar
);
168 m_stabTabBars
.append(ui
->advancedPIDBankTabBar
);
170 QAction
*defaultStabMenuAction
= new QAction(QIcon(":configgadget/images/gear.png"), QString(), this);
171 QAction
*restoreAllAction
= new QAction(tr("all to saved"), this);
172 connect(restoreAllAction
, SIGNAL(triggered()), this, SLOT(restoreAllStabBanks()));
173 QAction
*resetAllAction
= new QAction(tr("all to default"), this);
174 connect(resetAllAction
, SIGNAL(triggered()), this, SLOT(resetAllStabBanks()));
175 QAction
*restoreCurrentAction
= new QAction(tr("to saved"), this);
176 connect(restoreCurrentAction
, SIGNAL(triggered()), this, SLOT(restoreCurrentAction()));
177 QAction
*resetCurrentAction
= new QAction(tr("to default"), this);
178 connect(resetCurrentAction
, SIGNAL(triggered()), this, SLOT(resetCurrentStabBank()));
179 QAction
*copyCurrentAction
= new QAction(tr("to others"), this);
180 connect(copyCurrentAction
, SIGNAL(triggered()), this, SLOT(copyCurrentStabBank()));
181 connect(&m_stabSettingsCopyFromSignalMapper
, SIGNAL(mapped(int)), this, SLOT(copyFromBankToCurrent(int)));
182 connect(&m_stabSettingsCopyToSignalMapper
, SIGNAL(mapped(int)), this, SLOT(copyToBankFromCurrent(int)));
183 connect(&m_stabSettingsSwapSignalMapper
, SIGNAL(mapped(int)), this, SLOT(swapBankAndCurrent(int)));
185 foreach(QTabBar
* tabBar
, m_stabTabBars
) {
186 for (int i
= 0; i
< m_stabSettingsBankCount
; i
++) {
187 tabBar
->addTab(tr("Settings Bank %1").arg(i
+ 1));
188 tabBar
->setTabData(i
, QString("StabilizationSettingsBank%1").arg(i
+ 1));
189 QToolButton
*tabButton
= new QToolButton();
190 connect(this, SIGNAL(enableControlsChanged(bool)), tabButton
, SLOT(setEnabled(bool)));
191 tabButton
->setDefaultAction(defaultStabMenuAction
);
192 tabButton
->setAutoRaise(true);
193 tabButton
->setPopupMode(QToolButton::InstantPopup
);
194 tabButton
->setToolTip(tr("The functions in this menu effect all fields in the settings banks,\n"
195 "not only the ones visible on screen."));
196 QMenu
*tabMenu
= new QMenu();
197 QMenu
*restoreMenu
= new QMenu(tr("Restore"));
198 QMenu
*resetMenu
= new QMenu(tr("Reset"));
199 QMenu
*copyMenu
= new QMenu(tr("Copy"));
200 QMenu
*swapMenu
= new QMenu(tr("Swap"));
202 for (int j
= 0; j
< m_stabSettingsBankCount
; j
++) {
204 restoreMenu
->addAction(restoreCurrentAction
);
205 resetMenu
->addAction(resetCurrentAction
);
206 copyMenu
->addAction(copyCurrentAction
);
208 menuAction
= new QAction(tr("from %1").arg(j
+ 1), this);
209 connect(menuAction
, SIGNAL(triggered()), &m_stabSettingsCopyFromSignalMapper
, SLOT(map()));
210 m_stabSettingsCopyFromSignalMapper
.setMapping(menuAction
, j
);
211 copyMenu
->addAction(menuAction
);
213 menuAction
= new QAction(tr("to %1").arg(j
+ 1), this);
214 connect(menuAction
, SIGNAL(triggered()), &m_stabSettingsCopyToSignalMapper
, SLOT(map()));
215 m_stabSettingsCopyToSignalMapper
.setMapping(menuAction
, j
);
216 copyMenu
->addAction(menuAction
);
218 menuAction
= new QAction(tr("with %1").arg(j
+ 1), this);
219 connect(menuAction
, SIGNAL(triggered()), &m_stabSettingsSwapSignalMapper
, SLOT(map()));
220 m_stabSettingsSwapSignalMapper
.setMapping(menuAction
, j
);
221 swapMenu
->addAction(menuAction
);
224 restoreMenu
->addAction(restoreAllAction
);
225 resetMenu
->addAction(resetAllAction
);
226 tabMenu
->addMenu(copyMenu
);
227 tabMenu
->addMenu(swapMenu
);
228 tabMenu
->addMenu(resetMenu
);
229 tabMenu
->addMenu(restoreMenu
);
230 tabButton
->setMenu(tabMenu
);
231 tabBar
->setTabButton(i
, QTabBar::RightSide
, tabButton
);
233 tabBar
->setExpanding(false);
234 connect(tabBar
, SIGNAL(currentChanged(int)), this, SLOT(stabBankChanged(int)));
237 for (int i
= 0; i
< m_stabSettingsBankCount
; i
++) {
239 m_stabilizationObjectsString
.append(",");
241 m_stabilizationObjectsString
.append(m_stabTabBars
.at(0)->tabData(i
).toString());
245 ConfigStabilizationWidget::~ConfigStabilizationWidget()
250 void ConfigStabilizationWidget::refreshWidgetsValues(UAVObject
*o
)
252 ConfigTaskWidget::refreshWidgetsValues(o
);
254 updateThrottleCurveFromObject();
257 void ConfigStabilizationWidget::updateObjectsFromWidgets()
259 updateObjectFromThrottleCurve();
260 ConfigTaskWidget::updateObjectsFromWidgets();
263 void ConfigStabilizationWidget::updateThrottleCurveFromObject()
265 bool dirty
= isDirty();
266 UAVObject
*stabBank
= getObjectManager()->getObject(QString(m_stabTabBars
.at(0)->tabData(m_currentStabSettingsBank
).toString()));
270 UAVObjectField
*field
= stabBank
->getField("ThrustPIDScaleCurve");
274 for (quint32 i
= 0; i
< field
->getNumElements(); i
++) {
275 curve
.append(field
->getValue(i
).toDouble() / 100);
278 ui
->thrustPIDScalingCurve
->setCurve(&curve
);
280 field
= stabBank
->getField("EnableThrustPIDScaling");
283 bool enabled
= field
->getValue() == "True";
284 ui
->enableThrustPIDScalingCheckBox
->setChecked(enabled
);
285 ui
->thrustPIDScalingCurve
->setEnabled(enabled
);
289 void ConfigStabilizationWidget::updateObjectFromThrottleCurve()
291 UAVObject
*stabBank
= getObjectManager()->getObject(QString(m_stabTabBars
.at(0)->tabData(m_currentStabSettingsBank
).toString()));
295 UAVObjectField
*field
= stabBank
->getField("ThrustPIDScaleCurve");
298 QList
<double> curve
= ui
->thrustPIDScalingCurve
->getCurve();
299 for (quint32 i
= 0; i
< field
->getNumElements(); i
++) {
300 field
->setValue(curve
.at(i
) * 100, i
);
303 field
= stabBank
->getField("EnableThrustPIDScaling");
305 field
->setValue(ui
->enableThrustPIDScalingCheckBox
->isChecked() ? "True" : "False");
308 void ConfigStabilizationWidget::setupExpoPlot()
310 ui
->expoPlot
->setMouseTracking(false);
311 ui
->expoPlot
->setAxisScale(QwtPlot::xBottom
, 0, 100, 25);
314 title
.setText(tr("Input %"));
315 title
.setFont(ui
->expoPlot
->axisFont(QwtPlot::xBottom
));
316 ui
->expoPlot
->setAxisTitle(QwtPlot::xBottom
, title
);
317 ui
->expoPlot
->setAxisScale(QwtPlot::yLeft
, 0, 100, 25);
319 title
.setText(tr("Output %"));
320 title
.setFont(ui
->expoPlot
->axisFont(QwtPlot::yLeft
));
321 ui
->expoPlot
->setAxisTitle(QwtPlot::yLeft
, title
);
322 QwtPlotCanvas
*plotCanvas
= dynamic_cast<QwtPlotCanvas
*>(ui
->expoPlot
->canvas());
324 plotCanvas
->setFrameStyle(QFrame::NoFrame
);
326 ui
->expoPlot
->canvas()->setCursor(QCursor());
328 m_plotGrid
.setMajorPen(QColor(Qt::gray
));
329 m_plotGrid
.setMinorPen(QColor(Qt::lightGray
));
330 m_plotGrid
.enableXMin(false);
331 m_plotGrid
.enableYMin(false);
332 m_plotGrid
.attach(ui
->expoPlot
);
334 m_expoPlotCurveRoll
.setRenderHint(QwtPlotCurve::RenderAntialiased
);
335 QColor
rollColor(Qt::red
);
336 rollColor
.setAlpha(180);
337 m_expoPlotCurveRoll
.setPen(QPen(rollColor
, 2));
338 m_expoPlotCurveRoll
.attach(ui
->expoPlot
);
339 replotExpoRoll(ui
->expoSpinnerRoll
->value());
340 m_expoPlotCurveRoll
.show();
342 QColor
pitchColor(Qt::green
);
343 pitchColor
.setAlpha(180);
344 m_expoPlotCurvePitch
.setRenderHint(QwtPlotCurve::RenderAntialiased
);
345 m_expoPlotCurvePitch
.setPen(QPen(pitchColor
, 2));
346 m_expoPlotCurvePitch
.attach(ui
->expoPlot
);
347 replotExpoPitch(ui
->expoSpinnerPitch
->value());
348 m_expoPlotCurvePitch
.show();
350 QColor
yawColor(Qt::blue
);
351 yawColor
.setAlpha(180);
352 m_expoPlotCurveYaw
.setRenderHint(QwtPlotCurve::RenderAntialiased
);
353 m_expoPlotCurveYaw
.setPen(QPen(yawColor
, 2));
354 m_expoPlotCurveYaw
.attach(ui
->expoPlot
);
355 replotExpoYaw(ui
->expoSpinnerYaw
->value());
356 m_expoPlotCurveYaw
.show();
359 void ConfigStabilizationWidget::resetThrottleCurveToDefault()
361 UAVDataObject
*defaultStabBank
= (UAVDataObject
*)getObjectManager()->getObject(QString(m_stabTabBars
.at(0)->tabData(m_currentStabSettingsBank
).toString()));
363 Q_ASSERT(defaultStabBank
);
364 defaultStabBank
= defaultStabBank
->dirtyClone();
366 UAVObjectField
*field
= defaultStabBank
->getField("ThrustPIDScaleCurve");
370 for (quint32 i
= 0; i
< field
->getNumElements(); i
++) {
371 curve
.append(field
->getValue(i
).toDouble() / 100);
374 ui
->thrustPIDScalingCurve
->setCurve(&curve
);
376 field
= defaultStabBank
->getField("EnableThrustPIDScaling");
379 bool enabled
= field
->getValue() == "True";
380 ui
->enableThrustPIDScalingCheckBox
->setChecked(enabled
);
381 ui
->thrustPIDScalingCurve
->setEnabled(enabled
);
383 delete defaultStabBank
;
386 void ConfigStabilizationWidget::throttleCurveUpdated()
391 void ConfigStabilizationWidget::replotExpo(int value
, QwtPlotCurve
&curve
)
393 double x
[EXPO_CURVE_POINTS_COUNT
] = { 0 };
394 double y
[EXPO_CURVE_POINTS_COUNT
] = { 0 };
395 double factor
= pow(EXPO_CURVE_CONSTANT
, value
);
396 double step
= 1.0 / (EXPO_CURVE_POINTS_COUNT
- 1);
398 for (int i
= 0; i
< EXPO_CURVE_POINTS_COUNT
; i
++) {
399 double val
= i
* step
;
401 y
[i
] = pow(val
, factor
) * 100.0;
403 curve
.setSamples(x
, y
, EXPO_CURVE_POINTS_COUNT
);
404 ui
->expoPlot
->replot();
407 void ConfigStabilizationWidget::replotExpoRoll(int value
)
409 replotExpo(value
, m_expoPlotCurveRoll
);
412 void ConfigStabilizationWidget::replotExpoPitch(int value
)
414 replotExpo(value
, m_expoPlotCurvePitch
);
417 void ConfigStabilizationWidget::replotExpoYaw(int value
)
419 replotExpo(value
, m_expoPlotCurveYaw
);
422 void ConfigStabilizationWidget::restoreAllStabBanks()
424 for (int i
= 0; i
< m_stabSettingsBankCount
; i
++) {
429 void ConfigStabilizationWidget::resetAllStabBanks()
431 for (int i
= 0; i
< m_stabSettingsBankCount
; i
++) {
436 void ConfigStabilizationWidget::restoreCurrentAction()
438 restoreStabBank(m_currentStabSettingsBank
);
441 UAVObject
*ConfigStabilizationWidget::getStabBankObject(int bank
)
443 return getObject(QString("StabilizationSettingsBank%1").arg(bank
+ 1));
446 void ConfigStabilizationWidget::resetStabBank(int bank
)
448 UAVDataObject
*stabBankObject
=
449 dynamic_cast<UAVDataObject
*>(getStabBankObject(bank
));
451 if (stabBankObject
) {
452 UAVDataObject
*defaultStabBankObject
= stabBankObject
->dirtyClone();
453 quint8 data
[stabBankObject
->getNumBytes()];
454 defaultStabBankObject
->pack(data
);
455 stabBankObject
->unpack(data
);
459 void ConfigStabilizationWidget::restoreStabBank(int bank
)
461 UAVObject
*stabBankObject
= getStabBankObject(bank
);
463 if (stabBankObject
) {
464 ObjectPersistence
*objectPersistenceObject
= ObjectPersistence::GetInstance(getObjectManager());
465 QTimer
updateTimer(this);
466 QEventLoop
eventLoop(this);
467 connect(&updateTimer
, SIGNAL(timeout()), &eventLoop
, SLOT(quit()));
468 connect(objectPersistenceObject
, SIGNAL(objectUpdated(UAVObject
*)), &eventLoop
, SLOT(quit()));
470 ObjectPersistence::DataFields data
;
471 data
.Operation
= ObjectPersistence::OPERATION_LOAD
;
472 data
.Selection
= ObjectPersistence::SELECTION_SINGLEOBJECT
;
473 data
.ObjectID
= stabBankObject
->getObjID();
474 data
.InstanceID
= stabBankObject
->getInstID();
475 objectPersistenceObject
->setData(data
);
476 objectPersistenceObject
->updated();
477 updateTimer
.start(500);
479 if (updateTimer
.isActive()) {
480 stabBankObject
->requestUpdate();
486 void ConfigStabilizationWidget::resetCurrentStabBank()
488 resetStabBank(m_currentStabSettingsBank
);
491 void ConfigStabilizationWidget::copyCurrentStabBank()
493 UAVObject
*fromStabBankObject
= getStabBankObject(m_currentStabSettingsBank
);
495 if (fromStabBankObject
) {
496 quint8 fromStabBankObjectData
[fromStabBankObject
->getNumBytes()];
497 fromStabBankObject
->pack(fromStabBankObjectData
);
498 for (int i
= 0; i
< m_stabSettingsBankCount
; i
++) {
499 if (i
!= m_currentStabSettingsBank
) {
500 UAVObject
*toStabBankObject
= getStabBankObject(i
);
501 if (toStabBankObject
) {
502 toStabBankObject
->unpack(fromStabBankObjectData
);
509 void ConfigStabilizationWidget::copyFromBankToBank(int fromBank
, int toBank
)
511 UAVObject
*fromStabBankObject
= getStabBankObject(fromBank
);
512 UAVObject
*toStabBankObject
= getStabBankObject(toBank
);
514 if (fromStabBankObject
&& toStabBankObject
) {
515 quint8 data
[fromStabBankObject
->getNumBytes()];
516 fromStabBankObject
->pack(data
);
517 toStabBankObject
->unpack(data
);
521 void ConfigStabilizationWidget::copyFromBankToCurrent(int bank
)
523 copyFromBankToBank(bank
, m_currentStabSettingsBank
);
526 void ConfigStabilizationWidget::copyToBankFromCurrent(int bank
)
528 copyFromBankToBank(m_currentStabSettingsBank
, bank
);
531 void ConfigStabilizationWidget::swapBankAndCurrent(int bank
)
533 UAVObject
*fromStabBankObject
= getStabBankObject(m_currentStabSettingsBank
);
534 UAVObject
*toStabBankObject
= getStabBankObject(bank
);
536 if (fromStabBankObject
&& toStabBankObject
) {
537 quint8 fromStabBankObjectData
[fromStabBankObject
->getNumBytes()];
538 quint8 toStabBankObjectData
[toStabBankObject
->getNumBytes()];
539 fromStabBankObject
->pack(fromStabBankObjectData
);
540 toStabBankObject
->pack(toStabBankObjectData
);
541 toStabBankObject
->unpack(fromStabBankObjectData
);
542 fromStabBankObject
->unpack(toStabBankObjectData
);
546 void ConfigStabilizationWidget::realtimeUpdatesSlot(bool value
)
548 ui
->realTimeUpdates_6
->setChecked(value
);
549 ui
->realTimeUpdates_8
->setChecked(value
);
550 ui
->realTimeUpdates_12
->setChecked(value
);
551 ui
->realTimeUpdates_7
->setChecked(value
);
553 if (value
&& !realtimeUpdates
->isActive()) {
554 realtimeUpdates
->start(AUTOMATIC_UPDATE_RATE
);
555 } else if (!value
&& realtimeUpdates
->isActive()) {
556 realtimeUpdates
->stop();
560 void ConfigStabilizationWidget::linkCheckBoxes(bool value
)
562 if (sender() == ui
->checkBox_7
) {
563 ui
->checkBox_3
->setChecked(value
);
564 } else if (sender() == ui
->checkBox_3
) {
565 ui
->checkBox_7
->setChecked(value
);
566 } else if (sender() == ui
->checkBox_8
) {
567 ui
->checkBox_2
->setChecked(value
);
568 } else if (sender() == ui
->checkBox_2
) {
569 ui
->checkBox_8
->setChecked(value
);
570 } else if (sender() == ui
->basicResponsivenessCheckBox
) {
571 ui
->advancedResponsivenessCheckBox
->setChecked(!value
);
572 ui
->basicResponsivenessControls
->setEnabled(value
);
573 ui
->advancedResponsivenessControls
->setEnabled(!value
);
575 processLinkedWidgets(ui
->AttitudeResponsivenessSlider
);
576 processLinkedWidgets(ui
->RateResponsivenessSlider
);
578 } else if (sender() == ui
->advancedResponsivenessCheckBox
) {
579 ui
->basicResponsivenessCheckBox
->setChecked(!value
);
580 ui
->basicResponsivenessControls
->setEnabled(!value
);
581 ui
->advancedResponsivenessControls
->setEnabled(value
);
582 } else if (sender() == ui
->checkBoxLinkAcroFactors
) {
583 processLinkedWidgets(ui
->AcroFactorRollSlider
);
587 void ConfigStabilizationWidget::processLinkedWidgets(QWidget
*widget
)
589 if (ui
->checkBox_7
->isChecked()) {
590 if (widget
== ui
->RateRollKp_2
) {
591 ui
->RatePitchKp
->setValue(ui
->RateRollKp_2
->value());
592 } else if (widget
== ui
->RateRollKi_2
) {
593 ui
->RatePitchKi
->setValue(ui
->RateRollKi_2
->value());
594 } else if (widget
== ui
->RatePitchKp
) {
595 ui
->RateRollKp_2
->setValue(ui
->RatePitchKp
->value());
596 } else if (widget
== ui
->RatePitchKi
) {
597 ui
->RateRollKi_2
->setValue(ui
->RatePitchKi
->value());
598 } else if (widget
== ui
->RollRateKd
) {
599 ui
->PitchRateKd
->setValue(ui
->RollRateKd
->value());
600 } else if (widget
== ui
->PitchRateKd
) {
601 ui
->RollRateKd
->setValue(ui
->PitchRateKd
->value());
605 if (ui
->checkBox_8
->isChecked()) {
606 if (widget
== ui
->AttitudeRollKp
) {
607 ui
->AttitudePitchKp_2
->setValue(ui
->AttitudeRollKp
->value());
608 } else if (widget
== ui
->AttitudeRollKi
) {
609 ui
->AttitudePitchKi_2
->setValue(ui
->AttitudeRollKi
->value());
610 } else if (widget
== ui
->AttitudePitchKp_2
) {
611 ui
->AttitudeRollKp
->setValue(ui
->AttitudePitchKp_2
->value());
612 } else if (widget
== ui
->AttitudePitchKi_2
) {
613 ui
->AttitudeRollKi
->setValue(ui
->AttitudePitchKi_2
->value());
617 if (ui
->basicResponsivenessCheckBox
->isChecked()) {
618 if (widget
== ui
->AttitudeResponsivenessSlider
) {
619 ui
->attitudePitchResponse
->setValue(ui
->AttitudeResponsivenessSlider
->value());
620 ui
->attitudeRollResponse
->setValue(ui
->AttitudeResponsivenessSlider
->value());
621 } else if (widget
== ui
->RateResponsivenessSlider
) {
622 ui
->ratePitchResponse
->setValue(ui
->RateResponsivenessSlider
->value());
623 ui
->rateRollResponse
->setValue(ui
->RateResponsivenessSlider
->value());
626 if (ui
->checkBoxLinkAcroFactors
->isChecked()) {
627 if (widget
== ui
->AcroFactorRollSlider
) {
628 ui
->AcroFactorPitchSlider
->setValue(ui
->AcroFactorRollSlider
->value());
629 } else if (widget
== ui
->AcroFactorPitchSlider
) {
630 ui
->AcroFactorRollSlider
->setValue(ui
->AcroFactorPitchSlider
->value());
635 void ConfigStabilizationWidget::onBoardConnected()
637 ExtensionSystem::PluginManager
*pm
= ExtensionSystem::PluginManager::instance();
638 UAVObjectUtilManager
*utilMngr
= pm
->getObject
<UAVObjectUtilManager
>();
641 boardModel
= utilMngr
->getBoardModel();
642 // If Revolution board enable Althold tab, otherwise disable it
643 ui
->AltitudeHold
->setEnabled((boardModel
& 0xff00) == 0x0900);
646 void ConfigStabilizationWidget::stabBankChanged(int index
)
648 bool dirty
= isDirty();
650 disconnect(this, SIGNAL(widgetContentsChanged(QWidget
*)), this, SLOT(processLinkedWidgets(QWidget
*)));
652 updateObjectFromThrottleCurve();
653 foreach(QTabBar
* tabBar
, m_stabTabBars
) {
654 disconnect(tabBar
, SIGNAL(currentChanged(int)), this, SLOT(stabBankChanged(int)));
655 tabBar
->setCurrentIndex(index
);
656 connect(tabBar
, SIGNAL(currentChanged(int)), this, SLOT(stabBankChanged(int)));
659 for (int i
= 0; i
< m_stabTabBars
.at(0)->count(); i
++) {
660 setWidgetBindingObjectEnabled(m_stabTabBars
.at(0)->tabData(i
).toString(), false);
663 setWidgetBindingObjectEnabled(m_stabTabBars
.at(0)->tabData(index
).toString(), true);
665 m_currentStabSettingsBank
= index
;
666 updateThrottleCurveFromObject();
668 connect(this, SIGNAL(widgetContentsChanged(QWidget
*)), this, SLOT(processLinkedWidgets(QWidget
*)));
672 bool ConfigStabilizationWidget::shouldObjectBeSaved(UAVObject
*object
)
674 // AltitudeHoldSettings should only be saved for Revolution board to avoid error.
675 if ((boardModel
& 0xff00) != 0x0900) {
676 return dynamic_cast<AltitudeHoldSettings
*>(object
) == 0;
682 QString
ConfigStabilizationWidget::mapObjectName(const QString objectName
)
684 if (objectName
== "StabilizationSettingsBankX") {
685 return m_stabilizationObjectsString
;
687 return ConfigTaskWidget::mapObjectName(objectName
);