LP-311 Remove basic/advanced stabilization tab auto-switch (autotune/txpid lock issues)
[librepilot.git] / ground / gcs / src / plugins / config / configstabilizationwidget.cpp
blobc5f1f99e1cbde835f06e313db67876a4b660b7b7
1 /**
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
8 * @{
9 * @addtogroup ConfigPlugin Config Plugin
10 * @{
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
22 * for more details.
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"
45 #include <QDebug>
46 #include <QStringList>
47 #include <QWidget>
48 #include <QTextEdit>
49 #include <QVBoxLayout>
50 #include <QPushButton>
51 #include <QDesktopServices>
52 #include <QUrl>
53 #include <QList>
54 #include <QTabBar>
55 #include <QMessageBox>
56 #include <QToolButton>
57 #include <QMenu>
58 #include <QAction>
60 ConfigStabilizationWidget::ConfigStabilizationWidget(QWidget *parent) : ConfigTaskWidget(parent),
61 boardModel(0), m_stabSettingsBankCount(0), m_currentStabSettingsBank(0)
63 ui = new Ui_StabilizationWidget();
64 ui->setupUi(this);
66 setWikiURL("Stabilization+Configuration");
68 setupExpoPlot();
70 setupStabBanksGUI();
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);
79 autoLoadWidgets();
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"));
201 QAction *menuAction;
202 for (int j = 0; j < m_stabSettingsBankCount; j++) {
203 if (j == i) {
204 restoreMenu->addAction(restoreCurrentAction);
205 resetMenu->addAction(resetCurrentAction);
206 copyMenu->addAction(copyCurrentAction);
207 } else {
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++) {
238 if (i > 0) {
239 m_stabilizationObjectsString.append(",");
241 m_stabilizationObjectsString.append(m_stabTabBars.at(0)->tabData(i).toString());
245 ConfigStabilizationWidget::~ConfigStabilizationWidget()
247 // Do nothing
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()));
268 Q_ASSERT(stabBank);
270 UAVObjectField *field = stabBank->getField("ThrustPIDScaleCurve");
271 Q_ASSERT(field);
273 QList<double> curve;
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");
281 Q_ASSERT(field);
283 bool enabled = field->getValue() == "True";
284 ui->enableThrustPIDScalingCheckBox->setChecked(enabled);
285 ui->thrustPIDScalingCurve->setEnabled(enabled);
286 setDirty(dirty);
289 void ConfigStabilizationWidget::updateObjectFromThrottleCurve()
291 UAVObject *stabBank = getObjectManager()->getObject(QString(m_stabTabBars.at(0)->tabData(m_currentStabSettingsBank).toString()));
293 Q_ASSERT(stabBank);
295 UAVObjectField *field = stabBank->getField("ThrustPIDScaleCurve");
296 Q_ASSERT(field);
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");
304 Q_ASSERT(field);
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);
313 QwtText title;
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());
323 if (plotCanvas) {
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");
367 Q_ASSERT(field);
369 QList<double> curve;
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");
377 Q_ASSERT(field);
379 bool enabled = field->getValue() == "True";
380 ui->enableThrustPIDScalingCheckBox->setChecked(enabled);
381 ui->thrustPIDScalingCurve->setEnabled(enabled);
383 delete defaultStabBank;
386 void ConfigStabilizationWidget::throttleCurveUpdated()
388 setDirty(true);
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;
400 x[i] = val * 100.0;
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++) {
425 restoreStabBank(i);
429 void ConfigStabilizationWidget::resetAllStabBanks()
431 for (int i = 0; i < m_stabSettingsBankCount; i++) {
432 resetStabBank(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);
478 eventLoop.exec();
479 if (updateTimer.isActive()) {
480 stabBankObject->requestUpdate();
482 updateTimer.stop();
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);
574 if (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>();
640 Q_ASSERT(utilMngr);
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 *)));
669 setDirty(dirty);
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;
677 } else {
678 return true;
682 QString ConfigStabilizationWidget::mapObjectName(const QString objectName)
684 if (objectName == "StabilizationSettingsBankX") {
685 return m_stabilizationObjectsString;
687 return ConfigTaskWidget::mapObjectName(objectName);