LP-56 - Better txpid option namings, fix tabs-spaces, tooltips. headers, variable...
[librepilot.git] / ground / openpilotgcs / src / plugins / config / configstabilizationwidget.cpp
blobca02fcea87aac4f62bdb447f2e03c90c9606ee55
1 /**
2 ******************************************************************************
4 * @file configstabilizationwidget.cpp
5 * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
6 * @author 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 <QDebug>
31 #include <QStringList>
32 #include <QWidget>
33 #include <QTextEdit>
34 #include <QVBoxLayout>
35 #include <QPushButton>
36 #include <QDesktopServices>
37 #include <QUrl>
38 #include <QList>
39 #include <QTabBar>
40 #include <QMessageBox>
41 #include <QToolButton>
42 #include <QMenu>
43 #include <QAction>
45 #include <extensionsystem/pluginmanager.h>
46 #include <coreplugin/generalsettings.h>
47 #include "altitudeholdsettings.h"
48 #include "stabilizationsettings.h"
50 #include "qwt/src/qwt.h"
51 #include "qwt/src/qwt_plot.h"
52 #include "qwt/src/qwt_plot_canvas.h"
53 #include "qwt/src/qwt_scale_widget.h"
55 ConfigStabilizationWidget::ConfigStabilizationWidget(QWidget *parent) : ConfigTaskWidget(parent),
56 boardModel(0), m_stabSettingsBankCount(0), m_currentStabSettingsBank(0)
58 ui = new Ui_StabilizationWidget();
59 ui->setupUi(this);
61 setupExpoPlot();
63 setupStabBanksGUI();
65 ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
66 Core::Internal::GeneralSettings *settings = pm->getObject<Core::Internal::GeneralSettings>();
68 if (!settings->useExpertMode()) {
69 ui->saveStabilizationToRAM_6->setVisible(false);
72 autoLoadWidgets();
74 realtimeUpdates = new QTimer(this);
75 connect(realtimeUpdates, SIGNAL(timeout()), this, SLOT(apply()));
77 connect(ui->realTimeUpdates_6, SIGNAL(toggled(bool)), this, SLOT(realtimeUpdatesSlot(bool)));
78 addWidget(ui->realTimeUpdates_6);
79 connect(ui->realTimeUpdates_8, SIGNAL(toggled(bool)), this, SLOT(realtimeUpdatesSlot(bool)));
80 addWidget(ui->realTimeUpdates_8);
81 connect(ui->realTimeUpdates_12, SIGNAL(toggled(bool)), this, SLOT(realtimeUpdatesSlot(bool)));
82 addWidget(ui->realTimeUpdates_12);
83 connect(ui->realTimeUpdates_7, SIGNAL(toggled(bool)), this, SLOT(realtimeUpdatesSlot(bool)));
84 addWidget(ui->realTimeUpdates_7);
86 connect(ui->checkBox_7, SIGNAL(toggled(bool)), this, SLOT(linkCheckBoxes(bool)));
87 addWidget(ui->checkBox_7);
88 connect(ui->checkBox_2, SIGNAL(toggled(bool)), this, SLOT(linkCheckBoxes(bool)));
89 addWidget(ui->checkBox_2);
90 connect(ui->checkBox_8, SIGNAL(toggled(bool)), this, SLOT(linkCheckBoxes(bool)));
91 addWidget(ui->checkBox_8);
92 connect(ui->checkBox_3, SIGNAL(toggled(bool)), this, SLOT(linkCheckBoxes(bool)));
93 addWidget(ui->checkBox_3);
95 connect(ui->checkBoxLinkAcroFactors, SIGNAL(toggled(bool)), this, SLOT(linkCheckBoxes(bool)));
96 addWidget(ui->checkBoxLinkAcroFactors);
98 addWidget(ui->pushButton_2);
99 addWidget(ui->pushButton_3);
100 addWidget(ui->pushButton_4);
101 addWidget(ui->pushButton_5);
102 addWidget(ui->pushButton_6);
103 addWidget(ui->pushButton_7);
104 addWidget(ui->pushButton_8);
105 addWidget(ui->pushButton_9);
106 addWidget(ui->pushButton_10);
107 addWidget(ui->pushButton_11);
108 addWidget(ui->pushButton_20);
109 addWidget(ui->pushButton_22);
110 addWidget(ui->pushButton_23);
112 addWidget(ui->basicResponsivenessGroupBox);
113 addWidget(ui->basicResponsivenessCheckBox);
114 connect(ui->basicResponsivenessCheckBox, SIGNAL(toggled(bool)), this, SLOT(linkCheckBoxes(bool)));
115 addWidget(ui->advancedResponsivenessGroupBox);
116 addWidget(ui->advancedResponsivenessCheckBox);
117 connect(ui->advancedResponsivenessCheckBox, SIGNAL(toggled(bool)), this, SLOT(linkCheckBoxes(bool)));
119 connect(ui->defaultThrottleCurveButton, SIGNAL(clicked()), this, SLOT(resetThrottleCurveToDefault()));
120 connect(ui->enableThrustPIDScalingCheckBox, SIGNAL(toggled(bool)), ui->ThrustPIDSource, SLOT(setEnabled(bool)));
121 connect(ui->enableThrustPIDScalingCheckBox, SIGNAL(toggled(bool)), ui->ThrustPIDTarget, SLOT(setEnabled(bool)));
122 connect(ui->enableThrustPIDScalingCheckBox, SIGNAL(toggled(bool)), ui->ThrustPIDAxis, SLOT(setEnabled(bool)));
123 connect(ui->enableThrustPIDScalingCheckBox, SIGNAL(toggled(bool)), ui->thrustPIDScalingCurve, SLOT(setEnabled(bool)));
124 ui->thrustPIDScalingCurve->setXAxisLabel(tr("Thrust"));
125 ui->thrustPIDScalingCurve->setYAxisLabel(tr("Scaling factor"));
126 ui->thrustPIDScalingCurve->setMin(-0.5);
127 ui->thrustPIDScalingCurve->setMax(0.5);
128 ui->thrustPIDScalingCurve->initLinearCurve(5, -0.25, 0.25);
129 connect(ui->thrustPIDScalingCurve, SIGNAL(curveUpdated()), this, SLOT(throttleCurveUpdated()));
131 addWidget(ui->defaultThrottleCurveButton);
132 addWidget(ui->enableThrustPIDScalingCheckBox);
133 addWidget(ui->thrustPIDScalingCurve);
134 addWidget(ui->thrustPIDScalingCurve);
135 connect(this, SIGNAL(widgetContentsChanged(QWidget *)), this, SLOT(processLinkedWidgets(QWidget *)));
137 connect(this, SIGNAL(autoPilotConnected()), this, SLOT(onBoardConnected()));
139 addWidget(ui->expoPlot);
140 connect(ui->expoSpinnerRoll, SIGNAL(valueChanged(int)), this, SLOT(replotExpoRoll(int)));
141 connect(ui->expoSpinnerPitch, SIGNAL(valueChanged(int)), this, SLOT(replotExpoPitch(int)));
142 connect(ui->expoSpinnerYaw, SIGNAL(valueChanged(int)), this, SLOT(replotExpoYaw(int)));
144 disableMouseWheelEvents();
145 updateEnableControls();
148 void ConfigStabilizationWidget::setupStabBanksGUI()
150 StabilizationSettings *stabSettings = qobject_cast<StabilizationSettings *>(getObject("StabilizationSettings"));
152 Q_ASSERT(stabSettings);
154 m_stabSettingsBankCount = stabSettings->getField("FlightModeMap")->getOptions().count();
156 // Set up fake tab widget stuff for pid banks support
157 m_stabTabBars.append(ui->basicPIDBankTabBar);
158 m_stabTabBars.append(ui->advancedPIDBankTabBar);
160 QAction *defaultStabMenuAction = new QAction(QIcon(":configgadget/images/gear.png"), QString(), this);
161 QAction *restoreAllAction = new QAction(tr("all to saved"), this);
162 connect(restoreAllAction, SIGNAL(triggered()), this, SLOT(restoreAllStabBanks()));
163 QAction *resetAllAction = new QAction(tr("all to default"), this);
164 connect(resetAllAction, SIGNAL(triggered()), this, SLOT(resetAllStabBanks()));
165 QAction *restoreCurrentAction = new QAction(tr("to saved"), this);
166 connect(restoreCurrentAction, SIGNAL(triggered()), this, SLOT(restoreCurrentAction()));
167 QAction *resetCurrentAction = new QAction(tr("to default"), this);
168 connect(resetCurrentAction, SIGNAL(triggered()), this, SLOT(resetCurrentStabBank()));
169 QAction *copyCurrentAction = new QAction(tr("to others"), this);
170 connect(copyCurrentAction, SIGNAL(triggered()), this, SLOT(copyCurrentStabBank()));
171 connect(&m_stabSettingsCopyFromSignalMapper, SIGNAL(mapped(int)), this, SLOT(copyFromBankToCurrent(int)));
172 connect(&m_stabSettingsCopyToSignalMapper, SIGNAL(mapped(int)), this, SLOT(copyToBankFromCurrent(int)));
173 connect(&m_stabSettingsSwapSignalMapper, SIGNAL(mapped(int)), this, SLOT(swapBankAndCurrent(int)));
175 foreach(QTabBar * tabBar, m_stabTabBars) {
176 for (int i = 0; i < m_stabSettingsBankCount; i++) {
177 tabBar->addTab(tr("Settings Bank %1").arg(i + 1));
178 tabBar->setTabData(i, QString("StabilizationSettingsBank%1").arg(i + 1));
179 QToolButton *tabButton = new QToolButton();
180 connect(this, SIGNAL(enableControlsChanged(bool)), tabButton, SLOT(setEnabled(bool)));
181 tabButton->setDefaultAction(defaultStabMenuAction);
182 tabButton->setAutoRaise(true);
183 tabButton->setPopupMode(QToolButton::InstantPopup);
184 tabButton->setToolTip(tr("The functions in this menu effect all fields in the settings banks,\n"
185 "not only the ones visible on screen."));
186 QMenu *tabMenu = new QMenu();
187 QMenu *restoreMenu = new QMenu(tr("Restore"));
188 QMenu *resetMenu = new QMenu(tr("Reset"));
189 QMenu *copyMenu = new QMenu(tr("Copy"));
190 QMenu *swapMenu = new QMenu(tr("Swap"));
191 QAction *menuAction;
192 for (int j = 0; j < m_stabSettingsBankCount; j++) {
193 if (j == i) {
194 restoreMenu->addAction(restoreCurrentAction);
195 resetMenu->addAction(resetCurrentAction);
196 copyMenu->addAction(copyCurrentAction);
197 } else {
198 menuAction = new QAction(tr("from %1").arg(j + 1), this);
199 connect(menuAction, SIGNAL(triggered()), &m_stabSettingsCopyFromSignalMapper, SLOT(map()));
200 m_stabSettingsCopyFromSignalMapper.setMapping(menuAction, j);
201 copyMenu->addAction(menuAction);
203 menuAction = new QAction(tr("to %1").arg(j + 1), this);
204 connect(menuAction, SIGNAL(triggered()), &m_stabSettingsCopyToSignalMapper, SLOT(map()));
205 m_stabSettingsCopyToSignalMapper.setMapping(menuAction, j);
206 copyMenu->addAction(menuAction);
208 menuAction = new QAction(tr("with %1").arg(j + 1), this);
209 connect(menuAction, SIGNAL(triggered()), &m_stabSettingsSwapSignalMapper, SLOT(map()));
210 m_stabSettingsSwapSignalMapper.setMapping(menuAction, j);
211 swapMenu->addAction(menuAction);
214 restoreMenu->addAction(restoreAllAction);
215 resetMenu->addAction(resetAllAction);
216 tabMenu->addMenu(copyMenu);
217 tabMenu->addMenu(swapMenu);
218 tabMenu->addMenu(resetMenu);
219 tabMenu->addMenu(restoreMenu);
220 tabButton->setMenu(tabMenu);
221 tabBar->setTabButton(i, QTabBar::RightSide, tabButton);
223 tabBar->setExpanding(false);
224 connect(tabBar, SIGNAL(currentChanged(int)), this, SLOT(stabBankChanged(int)));
227 for (int i = 0; i < m_stabSettingsBankCount; i++) {
228 if (i > 0) {
229 m_stabilizationObjectsString.append(",");
231 m_stabilizationObjectsString.append(m_stabTabBars.at(0)->tabData(i).toString());
235 ConfigStabilizationWidget::~ConfigStabilizationWidget()
237 // Do nothing
240 void ConfigStabilizationWidget::refreshWidgetsValues(UAVObject *o)
242 ConfigTaskWidget::refreshWidgetsValues(o);
244 updateThrottleCurveFromObject();
246 ui->basicResponsivenessCheckBox->setChecked(ui->rateRollKp_3->value() == ui->ratePitchKp_4->value() &&
247 ui->rateRollKi_3->value() == ui->ratePitchKi_4->value());
250 void ConfigStabilizationWidget::updateObjectsFromWidgets()
252 updateObjectFromThrottleCurve();
253 ConfigTaskWidget::updateObjectsFromWidgets();
256 void ConfigStabilizationWidget::updateThrottleCurveFromObject()
258 bool dirty = isDirty();
259 UAVObject *stabBank = getObjectManager()->getObject(QString(m_stabTabBars.at(0)->tabData(m_currentStabSettingsBank).toString()));
261 Q_ASSERT(stabBank);
263 UAVObjectField *field = stabBank->getField("ThrustPIDScaleCurve");
264 Q_ASSERT(field);
266 QList<double> curve;
267 for (quint32 i = 0; i < field->getNumElements(); i++) {
268 curve.append(field->getValue(i).toDouble());
271 ui->thrustPIDScalingCurve->setCurve(&curve);
273 field = stabBank->getField("EnableThrustPIDScaling");
274 Q_ASSERT(field);
276 bool enabled = field->getValue() == "TRUE";
277 ui->enableThrustPIDScalingCheckBox->setChecked(enabled);
278 ui->thrustPIDScalingCurve->setEnabled(enabled);
279 setDirty(dirty);
282 void ConfigStabilizationWidget::updateObjectFromThrottleCurve()
284 UAVObject *stabBank = getObjectManager()->getObject(QString(m_stabTabBars.at(0)->tabData(m_currentStabSettingsBank).toString()));
286 Q_ASSERT(stabBank);
288 UAVObjectField *field = stabBank->getField("ThrustPIDScaleCurve");
289 Q_ASSERT(field);
291 QList<double> curve = ui->thrustPIDScalingCurve->getCurve();
292 for (quint32 i = 0; i < field->getNumElements(); i++) {
293 field->setValue(curve.at(i), i);
296 field = stabBank->getField("EnableThrustPIDScaling");
297 Q_ASSERT(field);
298 field->setValue(ui->enableThrustPIDScalingCheckBox->isChecked() ? "TRUE" : "FALSE");
301 void ConfigStabilizationWidget::setupExpoPlot()
303 ui->expoPlot->setMouseTracking(false);
304 ui->expoPlot->setAxisScale(QwtPlot::xBottom, 0, 100, 25);
306 QwtText title;
307 title.setText(tr("Input %"));
308 title.setFont(ui->expoPlot->axisFont(QwtPlot::xBottom));
309 ui->expoPlot->setAxisTitle(QwtPlot::xBottom, title);
310 ui->expoPlot->setAxisScale(QwtPlot::yLeft, 0, 100, 25);
312 title.setText(tr("Output %"));
313 title.setFont(ui->expoPlot->axisFont(QwtPlot::yLeft));
314 ui->expoPlot->setAxisTitle(QwtPlot::yLeft, title);
315 QwtPlotCanvas *plotCanvas = dynamic_cast<QwtPlotCanvas *>(ui->expoPlot->canvas());
316 if (plotCanvas) {
317 plotCanvas->setFrameStyle(QFrame::NoFrame);
319 ui->expoPlot->canvas()->setCursor(QCursor());
321 m_plotGrid.setMajorPen(QColor(Qt::gray));
322 m_plotGrid.setMinorPen(QColor(Qt::lightGray));
323 m_plotGrid.enableXMin(false);
324 m_plotGrid.enableYMin(false);
325 m_plotGrid.attach(ui->expoPlot);
327 m_expoPlotCurveRoll.setRenderHint(QwtPlotCurve::RenderAntialiased);
328 QColor rollColor(Qt::red);
329 rollColor.setAlpha(180);
330 m_expoPlotCurveRoll.setPen(QPen(rollColor, 2));
331 m_expoPlotCurveRoll.attach(ui->expoPlot);
332 replotExpoRoll(ui->expoSpinnerRoll->value());
333 m_expoPlotCurveRoll.show();
335 QColor pitchColor(Qt::green);
336 pitchColor.setAlpha(180);
337 m_expoPlotCurvePitch.setRenderHint(QwtPlotCurve::RenderAntialiased);
338 m_expoPlotCurvePitch.setPen(QPen(pitchColor, 2));
339 m_expoPlotCurvePitch.attach(ui->expoPlot);
340 replotExpoPitch(ui->expoSpinnerPitch->value());
341 m_expoPlotCurvePitch.show();
343 QColor yawColor(Qt::blue);
344 yawColor.setAlpha(180);
345 m_expoPlotCurveYaw.setRenderHint(QwtPlotCurve::RenderAntialiased);
346 m_expoPlotCurveYaw.setPen(QPen(yawColor, 2));
347 m_expoPlotCurveYaw.attach(ui->expoPlot);
348 replotExpoYaw(ui->expoSpinnerYaw->value());
349 m_expoPlotCurveYaw.show();
352 void ConfigStabilizationWidget::resetThrottleCurveToDefault()
354 UAVDataObject *defaultStabBank = (UAVDataObject *)getObjectManager()->getObject(QString(m_stabTabBars.at(0)->tabData(m_currentStabSettingsBank).toString()));
356 Q_ASSERT(defaultStabBank);
357 defaultStabBank = defaultStabBank->dirtyClone();
359 UAVObjectField *field = defaultStabBank->getField("ThrustPIDScaleCurve");
360 Q_ASSERT(field);
362 QList<double> curve;
363 for (quint32 i = 0; i < field->getNumElements(); i++) {
364 curve.append(field->getValue(i).toDouble());
367 ui->thrustPIDScalingCurve->setCurve(&curve);
369 field = defaultStabBank->getField("EnableThrustPIDScaling");
370 Q_ASSERT(field);
372 bool enabled = field->getValue() == "TRUE";
373 ui->enableThrustPIDScalingCheckBox->setChecked(enabled);
374 ui->thrustPIDScalingCurve->setEnabled(enabled);
376 delete defaultStabBank;
379 void ConfigStabilizationWidget::throttleCurveUpdated()
381 setDirty(true);
384 void ConfigStabilizationWidget::replotExpo(int value, QwtPlotCurve &curve)
386 double x[EXPO_CURVE_POINTS_COUNT] = { 0 };
387 double y[EXPO_CURVE_POINTS_COUNT] = { 0 };
388 double factor = pow(EXPO_CURVE_CONSTANT, value);
389 double step = 1.0 / (EXPO_CURVE_POINTS_COUNT - 1);
391 for (int i = 0; i < EXPO_CURVE_POINTS_COUNT; i++) {
392 double val = i * step;
393 x[i] = val * 100.0;
394 y[i] = pow(val, factor) * 100.0;
396 curve.setSamples(x, y, EXPO_CURVE_POINTS_COUNT);
397 ui->expoPlot->replot();
400 void ConfigStabilizationWidget::replotExpoRoll(int value)
402 replotExpo(value, m_expoPlotCurveRoll);
405 void ConfigStabilizationWidget::replotExpoPitch(int value)
407 replotExpo(value, m_expoPlotCurvePitch);
410 void ConfigStabilizationWidget::replotExpoYaw(int value)
412 replotExpo(value, m_expoPlotCurveYaw);
415 void ConfigStabilizationWidget::restoreAllStabBanks()
417 for (int i = 0; i < m_stabSettingsBankCount; i++) {
418 restoreStabBank(i);
422 void ConfigStabilizationWidget::resetAllStabBanks()
424 for (int i = 0; i < m_stabSettingsBankCount; i++) {
425 resetStabBank(i);
429 void ConfigStabilizationWidget::restoreCurrentAction()
431 restoreStabBank(m_currentStabSettingsBank);
434 UAVObject *ConfigStabilizationWidget::getStabBankObject(int bank)
436 return getObject(QString("StabilizationSettingsBank%1").arg(bank + 1));
439 void ConfigStabilizationWidget::resetStabBank(int bank)
441 UAVDataObject *stabBankObject =
442 dynamic_cast<UAVDataObject *>(getStabBankObject(bank));
444 if (stabBankObject) {
445 UAVDataObject *defaultStabBankObject = stabBankObject->dirtyClone();
446 quint8 data[stabBankObject->getNumBytes()];
447 defaultStabBankObject->pack(data);
448 stabBankObject->unpack(data);
452 void ConfigStabilizationWidget::restoreStabBank(int bank)
454 UAVObject *stabBankObject = getStabBankObject(bank);
456 if (stabBankObject) {
457 ObjectPersistence *objectPersistenceObject = ObjectPersistence::GetInstance(getObjectManager());
458 QTimer updateTimer(this);
459 QEventLoop eventLoop(this);
460 connect(&updateTimer, SIGNAL(timeout()), &eventLoop, SLOT(quit()));
461 connect(objectPersistenceObject, SIGNAL(objectUpdated(UAVObject *)), &eventLoop, SLOT(quit()));
463 ObjectPersistence::DataFields data;
464 data.Operation = ObjectPersistence::OPERATION_LOAD;
465 data.Selection = ObjectPersistence::SELECTION_SINGLEOBJECT;
466 data.ObjectID = stabBankObject->getObjID();
467 data.InstanceID = stabBankObject->getInstID();
468 objectPersistenceObject->setData(data);
469 objectPersistenceObject->updated();
470 updateTimer.start(500);
471 eventLoop.exec();
472 if (updateTimer.isActive()) {
473 stabBankObject->requestUpdate();
475 updateTimer.stop();
479 void ConfigStabilizationWidget::resetCurrentStabBank()
481 resetStabBank(m_currentStabSettingsBank);
484 void ConfigStabilizationWidget::copyCurrentStabBank()
486 UAVObject *fromStabBankObject = getStabBankObject(m_currentStabSettingsBank);
488 if (fromStabBankObject) {
489 quint8 fromStabBankObjectData[fromStabBankObject->getNumBytes()];
490 fromStabBankObject->pack(fromStabBankObjectData);
491 for (int i = 0; i < m_stabSettingsBankCount; i++) {
492 if (i != m_currentStabSettingsBank) {
493 UAVObject *toStabBankObject = getStabBankObject(i);
494 if (toStabBankObject) {
495 toStabBankObject->unpack(fromStabBankObjectData);
502 void ConfigStabilizationWidget::copyFromBankToBank(int fromBank, int toBank)
504 UAVObject *fromStabBankObject = getStabBankObject(fromBank);
505 UAVObject *toStabBankObject = getStabBankObject(toBank);
507 if (fromStabBankObject && toStabBankObject) {
508 quint8 data[fromStabBankObject->getNumBytes()];
509 fromStabBankObject->pack(data);
510 toStabBankObject->unpack(data);
514 void ConfigStabilizationWidget::copyFromBankToCurrent(int bank)
516 copyFromBankToBank(bank, m_currentStabSettingsBank);
519 void ConfigStabilizationWidget::copyToBankFromCurrent(int bank)
521 copyFromBankToBank(m_currentStabSettingsBank, bank);
524 void ConfigStabilizationWidget::swapBankAndCurrent(int bank)
526 UAVObject *fromStabBankObject = getStabBankObject(m_currentStabSettingsBank);
527 UAVObject *toStabBankObject = getStabBankObject(bank);
529 if (fromStabBankObject && toStabBankObject) {
530 quint8 fromStabBankObjectData[fromStabBankObject->getNumBytes()];
531 quint8 toStabBankObjectData[toStabBankObject->getNumBytes()];
532 fromStabBankObject->pack(fromStabBankObjectData);
533 toStabBankObject->pack(toStabBankObjectData);
534 toStabBankObject->unpack(fromStabBankObjectData);
535 fromStabBankObject->unpack(toStabBankObjectData);
539 void ConfigStabilizationWidget::realtimeUpdatesSlot(bool value)
541 ui->realTimeUpdates_6->setChecked(value);
542 ui->realTimeUpdates_8->setChecked(value);
543 ui->realTimeUpdates_12->setChecked(value);
544 ui->realTimeUpdates_7->setChecked(value);
546 if (value && !realtimeUpdates->isActive()) {
547 realtimeUpdates->start(AUTOMATIC_UPDATE_RATE);
548 } else if (!value && realtimeUpdates->isActive()) {
549 realtimeUpdates->stop();
553 void ConfigStabilizationWidget::linkCheckBoxes(bool value)
555 if (sender() == ui->checkBox_7) {
556 ui->checkBox_3->setChecked(value);
557 } else if (sender() == ui->checkBox_3) {
558 ui->checkBox_7->setChecked(value);
559 } else if (sender() == ui->checkBox_8) {
560 ui->checkBox_2->setChecked(value);
561 } else if (sender() == ui->checkBox_2) {
562 ui->checkBox_8->setChecked(value);
563 } else if (sender() == ui->basicResponsivenessCheckBox) {
564 ui->advancedResponsivenessCheckBox->setChecked(!value);
565 ui->basicResponsivenessControls->setEnabled(value);
566 ui->advancedResponsivenessControls->setEnabled(!value);
567 if (value) {
568 processLinkedWidgets(ui->AttitudeResponsivenessSlider);
569 processLinkedWidgets(ui->RateResponsivenessSlider);
571 } else if (sender() == ui->advancedResponsivenessCheckBox) {
572 ui->basicResponsivenessCheckBox->setChecked(!value);
573 ui->basicResponsivenessControls->setEnabled(!value);
574 ui->advancedResponsivenessControls->setEnabled(value);
575 } else if(sender() == ui->checkBoxLinkAcroFactors) {
576 processLinkedWidgets(ui->AcroFactorRollSlider);
580 void ConfigStabilizationWidget::processLinkedWidgets(QWidget *widget)
582 if (ui->checkBox_7->isChecked()) {
583 if (widget == ui->RateRollKp_2) {
584 ui->RatePitchKp->setValue(ui->RateRollKp_2->value());
585 } else if (widget == ui->RateRollKi_2) {
586 ui->RatePitchKi->setValue(ui->RateRollKi_2->value());
587 } else if (widget == ui->RatePitchKp) {
588 ui->RateRollKp_2->setValue(ui->RatePitchKp->value());
589 } else if (widget == ui->RatePitchKi) {
590 ui->RateRollKi_2->setValue(ui->RatePitchKi->value());
591 } else if (widget == ui->RollRateKd) {
592 ui->PitchRateKd->setValue(ui->RollRateKd->value());
593 } else if (widget == ui->PitchRateKd) {
594 ui->RollRateKd->setValue(ui->PitchRateKd->value());
598 if (ui->checkBox_8->isChecked()) {
599 if (widget == ui->AttitudeRollKp) {
600 ui->AttitudePitchKp_2->setValue(ui->AttitudeRollKp->value());
601 } else if (widget == ui->AttitudeRollKi) {
602 ui->AttitudePitchKi_2->setValue(ui->AttitudeRollKi->value());
603 } else if (widget == ui->AttitudePitchKp_2) {
604 ui->AttitudeRollKp->setValue(ui->AttitudePitchKp_2->value());
605 } else if (widget == ui->AttitudePitchKi_2) {
606 ui->AttitudeRollKi->setValue(ui->AttitudePitchKi_2->value());
610 if (ui->basicResponsivenessCheckBox->isChecked()) {
611 if (widget == ui->AttitudeResponsivenessSlider) {
612 ui->ratePitchKp_4->setValue(ui->AttitudeResponsivenessSlider->value());
613 } else if (widget == ui->RateResponsivenessSlider) {
614 ui->ratePitchKi_4->setValue(ui->RateResponsivenessSlider->value());
617 if (ui->checkBoxLinkAcroFactors->isChecked()) {
618 if (widget == ui->AcroFactorRollSlider) {
619 ui->AcroFactorPitchSlider->setValue(ui->AcroFactorRollSlider->value());
620 } else if (widget == ui->AcroFactorPitchSlider) {
621 ui->AcroFactorRollSlider->setValue(ui->AcroFactorPitchSlider->value());
626 void ConfigStabilizationWidget::onBoardConnected()
628 ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
629 UAVObjectUtilManager *utilMngr = pm->getObject<UAVObjectUtilManager>();
631 Q_ASSERT(utilMngr);
632 boardModel = utilMngr->getBoardModel();
633 // If Revolution board enable Althold tab, otherwise disable it
634 ui->AltitudeHold->setEnabled((boardModel & 0xff00) == 0x0900);
637 void ConfigStabilizationWidget::stabBankChanged(int index)
639 bool dirty = isDirty();
641 updateObjectFromThrottleCurve();
642 foreach(QTabBar * tabBar, m_stabTabBars) {
643 disconnect(tabBar, SIGNAL(currentChanged(int)), this, SLOT(stabBankChanged(int)));
644 tabBar->setCurrentIndex(index);
645 connect(tabBar, SIGNAL(currentChanged(int)), this, SLOT(stabBankChanged(int)));
648 for (int i = 0; i < m_stabTabBars.at(0)->count(); i++) {
649 setWidgetBindingObjectEnabled(m_stabTabBars.at(0)->tabData(i).toString(), false);
652 setWidgetBindingObjectEnabled(m_stabTabBars.at(0)->tabData(index).toString(), true);
654 m_currentStabSettingsBank = index;
655 updateThrottleCurveFromObject();
656 setDirty(dirty);
659 bool ConfigStabilizationWidget::shouldObjectBeSaved(UAVObject *object)
661 // AltitudeHoldSettings should only be saved for Revolution board to avoid error.
662 if ((boardModel & 0xff00) != 0x0900) {
663 return dynamic_cast<AltitudeHoldSettings *>(object) == 0;
664 } else {
665 return true;
669 QString ConfigStabilizationWidget::mapObjectName(const QString objectName)
671 if (objectName == "StabilizationSettingsBankX") {
672 return m_stabilizationObjectsString;
674 return ConfigTaskWidget::mapObjectName(objectName);