2 ******************************************************************************
4 * @file setupwizard.cpp
5 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
6 * @addtogroup GCSPlugins GCS Plugins
8 * @addtogroup Setup Wizard Plugin
10 * @brief A Wizard to make the initial setup easy for everyone.
11 *****************************************************************************/
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "setupwizard.h"
29 #include "pages/opstartpage.h"
30 #include "pages/opendpage.h"
31 #include "pages/controllerpage.h"
32 #include "pages/vehiclepage.h"
33 #include "pages/multipage.h"
34 #include "pages/fixedwingpage.h"
35 #include "pages/airspeedpage.h"
36 #include "pages/gpspage.h"
37 #include "pages/helipage.h"
38 #include "pages/surfacepage.h"
39 #include "pages/inputpage.h"
40 #include "pages/escpage.h"
41 #include "pages/servopage.h"
42 #include "pages/biascalibrationpage.h"
43 #include "pages/esccalibrationpage.h"
44 #include "pages/summarypage.h"
45 #include "pages/savepage.h"
46 #include "pages/notyetimplementedpage.h"
47 #include "pages/outputcalibrationpage.h"
48 #include "pages/revocalibrationpage.h"
49 #include "pages/airframeinitialtuningpage.h"
50 #include "extensionsystem/pluginmanager.h"
51 #include "vehicleconfigurationhelper.h"
52 #include "actuatorsettings.h"
53 #include "pages/autoupdatepage.h"
54 #include "uploader/uploadergadgetfactory.h"
56 SetupWizard::SetupWizard(QWidget
*parent
) : QWizard(parent
), VehicleConfigurationSource(),
57 m_controllerType(CONTROLLER_UNKNOWN
),
58 m_vehicleType(VEHICLE_UNKNOWN
), m_inputType(INPUT_UNKNOWN
),
59 m_escType(ESC_UNKNOWN
), m_servoType(SERVO_UNKNOWN
),
60 m_airspeedType(AIRSPEED_DISABLED
), m_gpsType(GPS_DISABLED
),
61 m_vehicleTemplate(NULL
), m_calibrationPerformed(false),
62 m_restartNeeded(false), m_connectionManager(NULL
)
64 setWindowTitle(tr("Setup Wizard"));
65 setOption(QWizard::IndependentPages
, false);
66 for (quint16 i
= 0; i
< ActuatorSettings::CHANNELMAX_NUMELEM
; i
++) {
67 m_actuatorSettings
<< actuatorChannelSettings();
69 setWizardStyle(QWizard::ModernStyle
);
70 setMinimumSize(780, 600);
75 SetupWizard::~SetupWizard()
77 if (m_vehicleTemplate
!= NULL
) {
78 delete m_vehicleTemplate
;
79 m_vehicleTemplate
= NULL
;
83 int SetupWizard::nextId() const
85 switch (currentId()) {
87 if (canAutoUpdate()) {
90 return PAGE_CONTROLLER
;
93 return PAGE_CONTROLLER
;
97 switch (getControllerType()) {
100 case CONTROLLER_REVO
:
101 case CONTROLLER_DISCOVERYF4
:
104 case CONTROLLER_NANO
:
105 if (isRestartNeeded()) {
110 case CONTROLLER_OPLINK
:
112 return PAGE_NOTYETIMPLEMENTED
;
117 switch (getVehicleType()) {
121 case VEHICLE_FIXEDWING
:
122 return PAGE_FIXEDWING
;
127 case VEHICLE_SURFACE
:
131 return PAGE_NOTYETIMPLEMENTED
;
139 if (getVehicleSubType() == GROUNDVEHICLE_DIFFERENTIAL
) {
146 if (isRestartNeeded()) {
147 saveHardwareSettings();
150 return PAGE_VEHICLES
;
153 if (getVehicleSubType() == MULTI_ROTOR_TRI_Y
) {
156 switch (getControllerType()) {
157 case CONTROLLER_REVO
:
158 case CONTROLLER_NANO
:
168 switch (getControllerType()) {
169 case CONTROLLER_REVO
:
170 case CONTROLLER_NANO
:
178 case PAGE_BIAS_CALIBRATION
:
179 if (getVehicleType() == VEHICLE_MULTI
) {
180 return PAGE_ESC_CALIBRATION
;
182 return PAGE_OUTPUT_CALIBRATION
;
185 case PAGE_ESC_CALIBRATION
:
186 return PAGE_OUTPUT_CALIBRATION
;
188 case PAGE_OUTPUT_CALIBRATION
:
189 return PAGE_AIRFRAME_INITIAL_TUNING
;
191 case PAGE_AIRFRAME_INITIAL_TUNING
:
195 switch (getVehicleType()) {
196 case VEHICLE_FIXEDWING
:
197 if (getGpsType() != GPS_DISABLED
) {
198 return PAGE_AIRSPEED
;
211 switch (getControllerType()) {
213 case CONTROLLER_CC3D
:
214 case CONTROLLER_REVO
:
215 case CONTROLLER_NANO
:
216 case CONTROLLER_DISCOVERYF4
:
217 switch (getVehicleType()) {
218 case VEHICLE_FIXEDWING
:
219 return PAGE_OUTPUT_CALIBRATION
;
222 return PAGE_BIAS_CALIBRATION
;
225 return PAGE_NOTYETIMPLEMENTED
;
231 case PAGE_NOTYETIMPLEMENTED
:
239 QString
SetupWizard::getSummaryText()
241 QString summary
= "";
243 summary
.append("<b>").append(tr("Controller type: ")).append("</b>");
244 switch (getControllerType()) {
246 summary
.append(tr("OpenPilot CopterControl"));
248 case CONTROLLER_CC3D
:
249 summary
.append(tr("OpenPilot CopterControl 3D"));
251 case CONTROLLER_REVO
:
252 summary
.append(tr("OpenPilot Revolution"));
254 case CONTROLLER_NANO
:
255 summary
.append(tr("OpenPilot Nano"));
257 case CONTROLLER_OPLINK
:
258 summary
.append(tr("OpenPilot OPLink Radio Modem"));
260 case CONTROLLER_DISCOVERYF4
:
261 summary
.append(tr("OpenPilot DiscoveryF4 Development Board"));
264 summary
.append(tr("Unknown"));
268 summary
.append("<br>");
269 summary
.append("<b>").append(tr("Vehicle type: ")).append("</b>");
270 switch (getVehicleType()) {
272 summary
.append(tr("Multirotor"));
274 summary
.append("<br>");
275 summary
.append("<b>").append(tr("Vehicle sub type: ")).append("</b>");
276 switch (getVehicleSubType()) {
277 case SetupWizard::MULTI_ROTOR_TRI_Y
:
278 summary
.append(tr("Tricopter"));
280 case SetupWizard::MULTI_ROTOR_QUAD_X
:
281 summary
.append(tr("Quadcopter X"));
283 case SetupWizard::MULTI_ROTOR_QUAD_PLUS
:
284 summary
.append(tr("Quadcopter +"));
286 case SetupWizard::MULTI_ROTOR_HEXA
:
287 summary
.append(tr("Hexacopter"));
289 case SetupWizard::MULTI_ROTOR_HEXA_COAX_Y
:
290 summary
.append(tr("Hexacopter Coax (Y6)"));
292 case SetupWizard::MULTI_ROTOR_HEXA_H
:
293 summary
.append(tr("Hexacopter H"));
295 case SetupWizard::MULTI_ROTOR_HEXA_X
:
296 summary
.append(tr("Hexacopter X"));
298 case SetupWizard::MULTI_ROTOR_OCTO
:
299 summary
.append(tr("Octocopter"));
301 case SetupWizard::MULTI_ROTOR_OCTO_COAX_X
:
302 summary
.append(tr("Octocopter Coax X"));
304 case SetupWizard::MULTI_ROTOR_OCTO_COAX_PLUS
:
305 summary
.append(tr("Octocopter Coax +"));
307 case SetupWizard::MULTI_ROTOR_OCTO_V
:
308 summary
.append(tr("Octocopter V"));
311 summary
.append(tr("Unknown"));
316 case VEHICLE_FIXEDWING
:
317 summary
.append(tr("Fixed wing"));
319 summary
.append("<br>");
320 summary
.append("<b>").append(tr("Vehicle sub type: ")).append("</b>");
321 switch (getVehicleSubType()) {
322 case SetupWizard::FIXED_WING_DUAL_AILERON
:
323 summary
.append(tr("Dual Aileron"));
325 case SetupWizard::FIXED_WING_AILERON
:
326 summary
.append(tr("Aileron"));
328 case SetupWizard::FIXED_WING_ELEVON
:
329 summary
.append(tr("Elevon"));
332 summary
.append(tr("Unknown"));
338 summary
.append(tr("Helicopter"));
340 case VEHICLE_SURFACE
:
341 summary
.append(tr("Surface vehicle"));
343 summary
.append("<br>");
344 summary
.append("<b>").append(tr("Vehicle sub type: ")).append("</b>");
345 switch (getVehicleSubType()) {
346 case SetupWizard::GROUNDVEHICLE_CAR
:
347 summary
.append(tr("Car"));
349 case SetupWizard::GROUNDVEHICLE_DIFFERENTIAL
:
350 summary
.append(tr("Tank"));
352 case SetupWizard::GROUNDVEHICLE_MOTORCYCLE
:
353 summary
.append(tr("Motorcycle"));
356 summary
.append(tr("Unknown"));
362 summary
.append(tr("Unknown"));
365 summary
.append("<br>");
366 summary
.append("<b>").append(tr("Input type: ")).append("</b>");
367 switch (getInputType()) {
369 summary
.append(tr("PWM (One cable per channel)"));
372 summary
.append(tr("PPM (One cable for all channels)"));
375 summary
.append(tr("Futaba S.Bus"));
378 summary
.append(tr("Spektrum Satellite"));
381 summary
.append(tr("Unknown"));
384 summary
.append("<br>");
385 summary
.append("<b>").append(tr("Speed Controller (ESC) type: ")).append("</b>");
386 switch (getEscType()) {
388 summary
.append(tr("Standard ESC (%1 Hz)").arg(VehicleConfigurationHelper::LEGACY_ESC_FREQUENCY
));
391 summary
.append(tr("Rapid ESC (%1 Hz)").arg(VehicleConfigurationHelper::RAPID_ESC_FREQUENCY
));
394 summary
.append(tr("Synched ESC"));
397 summary
.append(tr("Oneshot ESC"));
400 summary
.append(tr("Unknown"));
403 // If Tricopter show tail servo speed
404 if (getVehicleSubType() == MULTI_ROTOR_TRI_Y
|| getVehicleType() == VEHICLE_FIXEDWING
405 || getVehicleSubType() == GROUNDVEHICLE_MOTORCYCLE
|| getVehicleSubType() == GROUNDVEHICLE_CAR
) {
406 summary
.append("<br>");
407 summary
.append("<b>").append(tr("Servo type: ")).append("</b>");
408 switch (getServoType()) {
410 summary
.append(tr("Analog Servos (50 Hz)"));
413 summary
.append(tr("Digital Servos (333 Hz)"));
416 summary
.append(tr("Unknown"));
421 if (getControllerType() == CONTROLLER_REVO
|| getControllerType() == CONTROLLER_NANO
) {
422 summary
.append("<br>");
423 summary
.append("<b>").append(tr("GPS type: ")).append("</b>");
424 switch (getGpsType()) {
426 summary
.append(tr("OpenPilot Platinum"));
429 summary
.append(tr("OpenPilot v8 or Generic UBLOX GPS"));
432 summary
.append(tr("Generic NMEA GPS"));
435 summary
.append(tr("None"));
439 // Show Airspeed sensor type
440 if ((getControllerType() == CONTROLLER_REVO
|| getControllerType() == CONTROLLER_NANO
) && getVehicleType() == VEHICLE_FIXEDWING
) {
441 summary
.append("<br>");
442 summary
.append("<b>").append(tr("Airspeed Sensor: ")).append("</b>");
443 switch (getAirspeedType()) {
444 case AIRSPEED_ESTIMATE
:
445 summary
.append(tr("Software Estimated"));
447 case AIRSPEED_EAGLETREE
:
448 summary
.append(tr("EagleTree on Flexi-Port"));
450 case AIRSPEED_MS4525
:
451 summary
.append(tr("MS4525 based on Flexi-Port"));
454 summary
.append(tr("Unknown"));
460 void SetupWizard::createPages()
462 setPage(PAGE_START
, new OPStartPage(this));
463 setPage(PAGE_UPDATE
, new AutoUpdatePage(this));
464 setPage(PAGE_CONTROLLER
, new ControllerPage(this));
465 setPage(PAGE_VEHICLES
, new VehiclePage(this));
466 setPage(PAGE_MULTI
, new MultiPage(this));
467 setPage(PAGE_FIXEDWING
, new FixedWingPage(this));
468 setPage(PAGE_AIRSPEED
, new AirSpeedPage(this));
469 setPage(PAGE_GPS
, new GpsPage(this));
470 setPage(PAGE_HELI
, new HeliPage(this));
471 setPage(PAGE_SURFACE
, new SurfacePage(this));
472 setPage(PAGE_INPUT
, new InputPage(this));
473 setPage(PAGE_ESC
, new EscPage(this));
474 setPage(PAGE_SERVO
, new ServoPage(this));
475 setPage(PAGE_BIAS_CALIBRATION
, new BiasCalibrationPage(this));
476 setPage(PAGE_ESC_CALIBRATION
, new EscCalibrationPage(this));
477 setPage(PAGE_OUTPUT_CALIBRATION
, new OutputCalibrationPage(this));
478 setPage(PAGE_SUMMARY
, new SummaryPage(this));
479 setPage(PAGE_SAVE
, new SavePage(this));
480 setPage(PAGE_NOTYETIMPLEMENTED
, new NotYetImplementedPage(this));
481 setPage(PAGE_AIRFRAME_INITIAL_TUNING
, new AirframeInitialTuningPage(this));
482 setPage(PAGE_END
, new OPEndPage(this));
484 setStartId(PAGE_START
);
486 connect(button(QWizard::CustomButton1
), SIGNAL(clicked()), this, SLOT(customBackClicked()));
487 setButtonText(QWizard::CustomButton1
, buttonText(QWizard::BackButton
));
488 QList
<QWizard::WizardButton
> button_layout
;
489 button_layout
<< QWizard::Stretch
<< QWizard::CustomButton1
<< QWizard::NextButton
<< QWizard::CancelButton
<< QWizard::FinishButton
;
490 setButtonLayout(button_layout
);
491 connect(this, SIGNAL(currentIdChanged(int)), this, SLOT(pageChanged(int)));
494 void SetupWizard::customBackClicked()
496 if (currentId() == PAGE_OUTPUT_CALIBRATION
) {
497 static_cast<OutputCalibrationPage
*>(currentPage())->customBackClicked();
500 if (currentId() == PAGE_OUTPUT_CALIBRATION
) {
501 static_cast<OutputCalibrationPage
*>(currentPage())->customBackClicked();
506 void SetupWizard::pageChanged(int currId
)
508 button(QWizard::CustomButton1
)->setVisible(currId
!= PAGE_START
);
509 button(QWizard::CancelButton
)->setVisible(currId
!= PAGE_END
);
512 void SetupWizard::reboot() const
514 SetupWizard
*wiz
= const_cast<SetupWizard
*>(this);
516 wiz
->setWindowFlags(wiz
->windowFlags() & ~Qt::WindowStaysOnTopHint
);
518 ExtensionSystem::PluginManager
*pm
= ExtensionSystem::PluginManager::instance();
520 UploaderGadgetFactory
*uploader
= pm
->getObject
<UploaderGadgetFactory
>();
524 wiz
->setRestartNeeded(false);
525 wiz
->setWindowFlags(wiz
->windowFlags() | Qt::WindowStaysOnTopHint
);
529 bool SetupWizard::saveHardwareSettings() const
531 VehicleConfigurationHelper
helper(const_cast<SetupWizard
*>(this));
533 return helper
.setupHardwareSettings();
536 bool SetupWizard::canAutoUpdate() const
538 ExtensionSystem::PluginManager
*pm
= ExtensionSystem::PluginManager::instance();
541 UploaderGadgetFactory
*uploader
= pm
->getObject
<UploaderGadgetFactory
>();
543 return uploader
->isAutoUpdateCapable();