2 ******************************************************************************
4 * @file configgadgetwidget.cpp
5 * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2017.
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
29 #include "configgadgetwidget.h"
31 #include "configvehicletypewidget.h"
32 #include "configccattitudewidget.h"
33 #include "configinputwidget.h"
34 #include "configoutputwidget.h"
35 #include "configstabilizationwidget.h"
36 #include "configcamerastabilizationwidget.h"
37 #include "configtxpidwidget.h"
38 #include "configrevohwwidget.h"
39 #include "config_cc_hw_widget.h"
40 #include "configautotunewidget.h"
41 #include "configoplinkwidget.h"
42 #include "configrevowidget.h"
43 #include "configrevonanohwwidget.h"
44 #include "configsparky2hwwidget.h"
45 #include "configspracingf3evohwwidget.h"
46 #include "configtinyfishhwwidget.h"
47 #include "configpikoblxhwwidget.h"
48 #include "defaultconfigwidget.h"
50 #include <extensionsystem/pluginmanager.h>
51 #include <uavobjectutilmanager.h>
52 #include <uavtalk/telemetrymanager.h>
53 #include <uavtalk/oplinkmanager.h>
55 #include "utils/mytabbedstackwidget.h"
58 #include <QVBoxLayout>
59 #include <QMessageBox>
63 #define OPLINK_TIMEOUT 2000
65 ConfigGadgetWidget::ConfigGadgetWidget(QWidget
*parent
) : QWidget(parent
)
67 setSizePolicy(QSizePolicy::MinimumExpanding
, QSizePolicy::MinimumExpanding
);
69 stackWidget
= new MyTabbedStackWidget(this, true, true);
70 stackWidget
->setIconSize(64);
72 QVBoxLayout
*layout
= new QVBoxLayout
;
73 layout
->setContentsMargins(0, 0, 0, 0);
74 layout
->addWidget(stackWidget
);
77 ExtensionSystem::PluginManager
*pm
= ExtensionSystem::PluginManager::instance();
81 QWidget
*outputWidget
;
85 icon
->addFile(":/configgadget/images/hardware_normal.png", QSize(), QIcon::Normal
, QIcon::Off
);
86 icon
->addFile(":/configgadget/images/hardware_selected.png", QSize(), QIcon::Selected
, QIcon::Off
);
87 widget
= new DefaultConfigWidget(this, tr("Hardware"));
88 stackWidget
->insertTab(ConfigGadgetWidget::Hardware
, widget
, *icon
, QString("Hardware"));
91 icon
->addFile(":/configgadget/images/vehicle_normal.png", QSize(), QIcon::Normal
, QIcon::Off
);
92 icon
->addFile(":/configgadget/images/vehicle_selected.png", QSize(), QIcon::Selected
, QIcon::Off
);
93 widget
= new ConfigVehicleTypeWidget(this);
94 static_cast<ConfigTaskWidget
*>(widget
)->bind();
95 stackWidget
->insertTab(ConfigGadgetWidget::Aircraft
, widget
, *icon
, QString("Vehicle"));
98 icon
->addFile(":/configgadget/images/input_normal.png", QSize(), QIcon::Normal
, QIcon::Off
);
99 icon
->addFile(":/configgadget/images/input_selected.png", QSize(), QIcon::Selected
, QIcon::Off
);
100 widget
= new ConfigInputWidget(this);
101 static_cast<ConfigTaskWidget
*>(widget
)->bind();
102 stackWidget
->insertTab(ConfigGadgetWidget::Input
, widget
, *icon
, QString("Input"));
103 inputWidget
= widget
;
106 icon
->addFile(":/configgadget/images/output_normal.png", QSize(), QIcon::Normal
, QIcon::Off
);
107 icon
->addFile(":/configgadget/images/output_selected.png", QSize(), QIcon::Selected
, QIcon::Off
);
108 widget
= new ConfigOutputWidget(this);
109 static_cast<ConfigTaskWidget
*>(widget
)->bind();
110 stackWidget
->insertTab(ConfigGadgetWidget::Output
, widget
, *icon
, QString("Output"));
111 outputWidget
= widget
;
114 icon
->addFile(":/configgadget/images/ins_normal.png", QSize(), QIcon::Normal
, QIcon::Off
);
115 icon
->addFile(":/configgadget/images/ins_selected.png", QSize(), QIcon::Selected
, QIcon::Off
);
116 widget
= new DefaultConfigWidget(this, tr("Attitude"));
117 stackWidget
->insertTab(ConfigGadgetWidget::Sensors
, widget
, *icon
, QString("Attitude"));
120 icon
->addFile(":/configgadget/images/stabilization_normal.png", QSize(), QIcon::Normal
, QIcon::Off
);
121 icon
->addFile(":/configgadget/images/stabilization_selected.png", QSize(), QIcon::Selected
, QIcon::Off
);
122 widget
= new ConfigStabilizationWidget(this);
123 static_cast<ConfigTaskWidget
*>(widget
)->bind();
124 stackWidget
->insertTab(ConfigGadgetWidget::Stabilization
, widget
, *icon
, QString("Stabilization"));
127 icon
->addFile(":/configgadget/images/camstab_normal.png", QSize(), QIcon::Normal
, QIcon::Off
);
128 icon
->addFile(":/configgadget/images/camstab_selected.png", QSize(), QIcon::Selected
, QIcon::Off
);
129 widget
= new ConfigCameraStabilizationWidget(this);
130 static_cast<ConfigTaskWidget
*>(widget
)->bind();
131 stackWidget
->insertTab(ConfigGadgetWidget::CameraStabilization
, widget
, *icon
, QString("Gimbal"));
134 icon
->addFile(":/configgadget/images/txpid_normal.png", QSize(), QIcon::Normal
, QIcon::Off
);
135 icon
->addFile(":/configgadget/images/txpid_selected.png", QSize(), QIcon::Selected
, QIcon::Off
);
136 widget
= new ConfigTxPIDWidget(this);
137 static_cast<ConfigTaskWidget
*>(widget
)->bind();
138 stackWidget
->insertTab(ConfigGadgetWidget::TxPid
, widget
, *icon
, QString("TxPID"));
141 icon
->addFile(":/configgadget/images/autotune_normal.png", QSize(), QIcon::Normal
, QIcon::Off
);
142 icon
->addFile(":/configgadget/images/autotune_selected.png", QSize(), QIcon::Selected
, QIcon::Off
);
143 widget
= new DefaultConfigWidget(this, tr("AutoTune Configuration"));
144 stackWidget
->insertTab(ConfigGadgetWidget::AutoTune
, widget
, *icon
, QString("AutoTune"));
147 icon
->addFile(":/configgadget/images/pipx-normal.png", QSize(), QIcon::Normal
, QIcon::Off
);
148 icon
->addFile(":/configgadget/images/pipx-selected.png", QSize(), QIcon::Selected
, QIcon::Off
);
149 widget
= new DefaultConfigWidget(this, tr("OPLink Configuration"));
150 stackWidget
->insertTab(ConfigGadgetWidget::OPLink
, widget
, *icon
, QString("OPLink"));
152 stackWidget
->setCurrentIndex(ConfigGadgetWidget::Hardware
);
154 // connect to autopilot connection events
155 TelemetryManager
*tm
= pm
->getObject
<TelemetryManager
>();
156 connect(tm
, SIGNAL(connected()), this, SLOT(onAutopilotConnect()));
157 connect(tm
, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect()));
158 // check if we are already connected
159 if (tm
->isConnected()) {
160 onAutopilotConnect();
163 // connect to oplink manager
164 OPLinkManager
*om
= pm
->getObject
<OPLinkManager
>();
165 connect(om
, SIGNAL(connected()), this, SLOT(onOPLinkConnect()));
166 connect(om
, SIGNAL(disconnected()), this, SLOT(onOPLinkDisconnect()));
167 // check if we are already connected
168 if (om
->isConnected()) {
172 // Connect output tab and input tab for safe
173 // output config and input calibration
174 connect(outputWidget
, SIGNAL(outputConfigSafe(bool)), inputWidget
, SLOT(outputConfigSafe(bool)));
175 connect(inputWidget
, SIGNAL(inputCalibrationStatus(bool)), outputWidget
, SLOT(inputCalibrationStatus(bool)));
178 connect(stackWidget
, SIGNAL(currentAboutToShow(int, bool *)), this, SLOT(tabAboutToChange(int, bool *)));
181 ConfigGadgetWidget::~ConfigGadgetWidget()
186 void ConfigGadgetWidget::startInputWizard()
188 stackWidget
->setCurrentIndex(ConfigGadgetWidget::Input
);
189 ConfigInputWidget
*inputWidget
= dynamic_cast<ConfigInputWidget
*>(stackWidget
->getWidget(ConfigGadgetWidget::Input
));
190 Q_ASSERT(inputWidget
);
191 inputWidget
->startInputWizard();
194 void ConfigGadgetWidget::saveState(QSettings
&settings
) const
196 settings
.setValue("currentIndex", stackWidget
->currentIndex());
199 void ConfigGadgetWidget::restoreState(QSettings
&settings
)
201 int index
= settings
.value("currentIndex", 0).toInt();
203 stackWidget
->setCurrentIndex(index
);
206 void ConfigGadgetWidget::resizeEvent(QResizeEvent
*event
)
208 QWidget::resizeEvent(event
);
211 void ConfigGadgetWidget::onAutopilotConnect()
213 // qDebug() << "ConfigGadgetWidget::onAutopilotConnect";
215 // Check what Board type we are talking to, and if necessary, remove/add tabs in the config gadget
216 ExtensionSystem::PluginManager
*pm
= ExtensionSystem::PluginManager::instance();
217 UAVObjectUtilManager
*utilMngr
= pm
->getObject
<UAVObjectUtilManager
>();
220 int board
= utilMngr
->getBoardModel();
221 if ((board
& 0xff00) == 0x0400) {
222 // CopterControl family
224 ConfigTaskWidget
*widget
;
226 if ((board
& 0x00ff) == 0x03) {
227 widget
= new ConfigRevoWidget(this);
229 widget
= new ConfigCCAttitudeWidget(this);
233 stackWidget
->replaceTab(ConfigGadgetWidget::Sensors
, widget
);
235 widget
= new ConfigCCHWWidget(this);
237 stackWidget
->replaceTab(ConfigGadgetWidget::Hardware
, widget
);
238 } else if ((board
& 0xff00) == 0x0900) {
240 ConfigTaskWidget
*widget
;
241 widget
= new ConfigRevoWidget(this);
243 stackWidget
->replaceTab(ConfigGadgetWidget::Sensors
, widget
);
244 widget
= new ConfigAutoTuneWidget(this);
246 stackWidget
->replaceTab(ConfigGadgetWidget::AutoTune
, widget
);
247 if (board
== 0x0903 || board
== 0x0904) {
248 widget
= new ConfigRevoHWWidget(this);
249 } else if (board
== 0x0905) {
250 widget
= new ConfigRevoNanoHWWidget(this);
253 stackWidget
->replaceTab(ConfigGadgetWidget::Hardware
, widget
);
254 } else if ((board
& 0xff00) == 0x9200) {
256 ConfigTaskWidget
*widget
;
257 widget
= new ConfigRevoWidget(this);
259 stackWidget
->replaceTab(ConfigGadgetWidget::Sensors
, widget
);
260 widget
= new ConfigAutoTuneWidget(this);
262 stackWidget
->replaceTab(ConfigGadgetWidget::AutoTune
, widget
);
263 widget
= new ConfigSparky2HWWidget(this);
265 stackWidget
->replaceTab(ConfigGadgetWidget::Hardware
, widget
);
266 } else if ((board
& 0xff00) == 0x1000) { // F3 boards
267 ConfigTaskWidget
*widget
;
268 widget
= new ConfigRevoWidget(this);
270 stackWidget
->replaceTab(ConfigGadgetWidget::Sensors
, widget
);
276 // widget = new ConfigSPRacingF3HWWidget(this);
280 widget
= new ConfigSPRacingF3EVOHWWidget(this);
283 widget
= new ConfigPikoBLXHWWidget(this);
286 widget
= new ConfigTinyFISHHWWidget(this);
292 stackWidget
->replaceTab(ConfigGadgetWidget::Hardware
, widget
);
296 qWarning() << "Unknown board " << board
;
301 void ConfigGadgetWidget::onAutopilotDisconnect()
303 // qDebug() << "ConfigGadgetWidget::onAutopilotDiconnect";
306 widget
= new DefaultConfigWidget(this, tr("Attitude"));
307 stackWidget
->replaceTab(ConfigGadgetWidget::Sensors
, widget
);
309 widget
= new DefaultConfigWidget(this, tr("Hardware"));
310 stackWidget
->replaceTab(ConfigGadgetWidget::Hardware
, widget
);
312 widget
= new DefaultConfigWidget(this, tr("AutoTune"));
313 stackWidget
->replaceTab(ConfigGadgetWidget::AutoTune
, widget
);
316 void ConfigGadgetWidget::onOPLinkConnect()
318 // qDebug() << "ConfigGadgetWidget::onOPLinkConnect";
320 ConfigTaskWidget
*widget
= new ConfigOPLinkWidget(this);
323 stackWidget
->replaceTab(ConfigGadgetWidget::OPLink
, widget
);
326 void ConfigGadgetWidget::onOPLinkDisconnect()
328 // qDebug() << "ConfigGadgetWidget::onOPLinkDisconnect";
330 QWidget
*widget
= new DefaultConfigWidget(this, tr("OPLink Configuration"));
332 stackWidget
->replaceTab(ConfigGadgetWidget::OPLink
, widget
);
335 void ConfigGadgetWidget::tabAboutToChange(int index
, bool *proceed
)
339 ConfigTaskWidget
*wid
= qobject_cast
<ConfigTaskWidget
*>(stackWidget
->currentWidget());
343 if (wid
->isDirty()) {
344 int ans
= QMessageBox::warning(this, tr("Unsaved changes"), tr("The tab you are leaving has unsaved changes, "
345 "if you proceed they will be lost.\n"
346 "Do you still want to proceed?"), QMessageBox::Yes
, QMessageBox::No
);
347 if (ans
== QMessageBox::No
) {