LP-106 Setup Wizard refresh : Add dual servo setup (dual aileron or
[librepilot.git] / ground / gcs / src / plugins / setupwizard / setupwizard.cpp
blob2f512fa82932ef03f59ae68bcd12ee6c75fe89af
1 /**
2 ******************************************************************************
4 * @file setupwizard.cpp
5 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
6 * @addtogroup GCSPlugins GCS Plugins
7 * @{
8 * @addtogroup Setup Wizard Plugin
9 * @{
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
21 * for more details.
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);
71 resize(780, 600);
72 createPages();
75 SetupWizard::~SetupWizard()
77 if (m_vehicleTemplate != NULL) {
78 delete m_vehicleTemplate;
79 m_vehicleTemplate = NULL;
83 int SetupWizard::nextId() const
85 switch (currentId()) {
86 case PAGE_START:
87 if (canAutoUpdate()) {
88 return PAGE_UPDATE;
89 } else {
90 return PAGE_CONTROLLER;
92 case PAGE_UPDATE:
93 return PAGE_CONTROLLER;
95 case PAGE_CONTROLLER:
97 switch (getControllerType()) {
98 case CONTROLLER_CC:
99 case CONTROLLER_CC3D:
100 case CONTROLLER_REVO:
101 case CONTROLLER_DISCOVERYF4:
102 return PAGE_INPUT;
104 case CONTROLLER_NANO:
105 if (isRestartNeeded()) {
106 reboot();
108 return PAGE_INPUT;
110 case CONTROLLER_OPLINK:
111 default:
112 return PAGE_NOTYETIMPLEMENTED;
115 case PAGE_VEHICLES:
117 switch (getVehicleType()) {
118 case VEHICLE_MULTI:
119 return PAGE_MULTI;
121 case VEHICLE_FIXEDWING:
122 return PAGE_FIXEDWING;
124 case VEHICLE_HELI:
125 return PAGE_HELI;
127 case VEHICLE_SURFACE:
128 return PAGE_SURFACE;
130 default:
131 return PAGE_NOTYETIMPLEMENTED;
134 case PAGE_MULTI:
135 return PAGE_ESC;
137 case PAGE_FIXEDWING:
138 case PAGE_SURFACE:
139 if (getVehicleSubType() == GROUNDVEHICLE_DIFFERENTIAL) {
140 return PAGE_ESC;
141 } else {
142 return PAGE_SERVO;
145 case PAGE_INPUT:
146 if (isRestartNeeded()) {
147 saveHardwareSettings();
148 reboot();
150 return PAGE_VEHICLES;
152 case PAGE_ESC:
153 if (getVehicleSubType() == MULTI_ROTOR_TRI_Y) {
154 return PAGE_SERVO;
155 } else {
156 switch (getControllerType()) {
157 case CONTROLLER_REVO:
158 case CONTROLLER_NANO:
159 return PAGE_GPS;
161 default:
162 return PAGE_SUMMARY;
166 case PAGE_SERVO:
168 switch (getControllerType()) {
169 case CONTROLLER_REVO:
170 case CONTROLLER_NANO:
171 return PAGE_GPS;
173 default:
174 return PAGE_SUMMARY;
178 case PAGE_BIAS_CALIBRATION:
179 if (getVehicleType() == VEHICLE_MULTI) {
180 return PAGE_ESC_CALIBRATION;
181 } else {
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:
192 return PAGE_SAVE;
194 case PAGE_GPS:
195 switch (getVehicleType()) {
196 case VEHICLE_FIXEDWING:
197 if (getGpsType() != GPS_DISABLED) {
198 return PAGE_AIRSPEED;
199 } else {
200 return PAGE_SUMMARY;
202 default:
203 return PAGE_SUMMARY;
206 case PAGE_AIRSPEED:
207 return PAGE_SUMMARY;
209 case PAGE_SUMMARY:
211 switch (getControllerType()) {
212 case CONTROLLER_CC:
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;
221 default:
222 return PAGE_BIAS_CALIBRATION;
224 default:
225 return PAGE_NOTYETIMPLEMENTED;
228 case PAGE_SAVE:
229 return PAGE_END;
231 case PAGE_NOTYETIMPLEMENTED:
232 return PAGE_END;
234 default:
235 return -1;
239 QString SetupWizard::getSummaryText()
241 QString summary = "";
243 summary.append("<b>").append(tr("Controller type: ")).append("</b>");
244 switch (getControllerType()) {
245 case CONTROLLER_CC:
246 summary.append(tr("OpenPilot CopterControl"));
247 break;
248 case CONTROLLER_CC3D:
249 summary.append(tr("OpenPilot CopterControl 3D"));
250 break;
251 case CONTROLLER_REVO:
252 summary.append(tr("OpenPilot Revolution"));
253 break;
254 case CONTROLLER_NANO:
255 summary.append(tr("OpenPilot Nano"));
256 break;
257 case CONTROLLER_OPLINK:
258 summary.append(tr("OpenPilot OPLink Radio Modem"));
259 break;
260 case CONTROLLER_DISCOVERYF4:
261 summary.append(tr("OpenPilot DiscoveryF4 Development Board"));
262 break;
263 default:
264 summary.append(tr("Unknown"));
265 break;
268 summary.append("<br>");
269 summary.append("<b>").append(tr("Vehicle type: ")).append("</b>");
270 switch (getVehicleType()) {
271 case VEHICLE_MULTI:
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"));
279 break;
280 case SetupWizard::MULTI_ROTOR_QUAD_X:
281 summary.append(tr("Quadcopter X"));
282 break;
283 case SetupWizard::MULTI_ROTOR_QUAD_PLUS:
284 summary.append(tr("Quadcopter +"));
285 break;
286 case SetupWizard::MULTI_ROTOR_HEXA:
287 summary.append(tr("Hexacopter"));
288 break;
289 case SetupWizard::MULTI_ROTOR_HEXA_COAX_Y:
290 summary.append(tr("Hexacopter Coax (Y6)"));
291 break;
292 case SetupWizard::MULTI_ROTOR_HEXA_H:
293 summary.append(tr("Hexacopter H"));
294 break;
295 case SetupWizard::MULTI_ROTOR_HEXA_X:
296 summary.append(tr("Hexacopter X"));
297 break;
298 case SetupWizard::MULTI_ROTOR_OCTO:
299 summary.append(tr("Octocopter"));
300 break;
301 case SetupWizard::MULTI_ROTOR_OCTO_COAX_X:
302 summary.append(tr("Octocopter Coax X"));
303 break;
304 case SetupWizard::MULTI_ROTOR_OCTO_COAX_PLUS:
305 summary.append(tr("Octocopter Coax +"));
306 break;
307 case SetupWizard::MULTI_ROTOR_OCTO_V:
308 summary.append(tr("Octocopter V"));
309 break;
310 default:
311 summary.append(tr("Unknown"));
312 break;
315 break;
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"));
324 break;
325 case SetupWizard::FIXED_WING_AILERON:
326 summary.append(tr("Aileron"));
327 break;
328 case SetupWizard::FIXED_WING_ELEVON:
329 summary.append(tr("Elevon"));
330 break;
331 default:
332 summary.append(tr("Unknown"));
333 break;
336 break;
337 case VEHICLE_HELI:
338 summary.append(tr("Helicopter"));
339 break;
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"));
348 break;
349 case SetupWizard::GROUNDVEHICLE_DIFFERENTIAL:
350 summary.append(tr("Tank"));
351 break;
352 case SetupWizard::GROUNDVEHICLE_MOTORCYCLE:
353 summary.append(tr("Motorcycle"));
354 break;
355 default:
356 summary.append(tr("Unknown"));
357 break;
360 break;
361 default:
362 summary.append(tr("Unknown"));
365 summary.append("<br>");
366 summary.append("<b>").append(tr("Input type: ")).append("</b>");
367 switch (getInputType()) {
368 case INPUT_PWM:
369 summary.append(tr("PWM (One cable per channel)"));
370 break;
371 case INPUT_PPM:
372 summary.append(tr("PPM (One cable for all channels)"));
373 break;
374 case INPUT_SBUS:
375 summary.append(tr("Futaba S.Bus"));
376 break;
377 case INPUT_DSM:
378 summary.append(tr("Spektrum Satellite"));
379 break;
380 default:
381 summary.append(tr("Unknown"));
384 summary.append("<br>");
385 summary.append("<b>").append(tr("Speed Controller (ESC) type: ")).append("</b>");
386 switch (getEscType()) {
387 case ESC_STANDARD:
388 summary.append(tr("Standard ESC (%1 Hz)").arg(VehicleConfigurationHelper::LEGACY_ESC_FREQUENCY));
389 break;
390 case ESC_RAPID:
391 summary.append(tr("Rapid ESC (%1 Hz)").arg(VehicleConfigurationHelper::RAPID_ESC_FREQUENCY));
392 break;
393 case ESC_SYNCHED:
394 summary.append(tr("Synched ESC"));
395 break;
396 case ESC_ONESHOT:
397 summary.append(tr("Oneshot ESC"));
398 break;
399 default:
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()) {
409 case SERVO_ANALOG:
410 summary.append(tr("Analog Servos (50 Hz)"));
411 break;
412 case SERVO_DIGITAL:
413 summary.append(tr("Digital Servos (333 Hz)"));
414 break;
415 default:
416 summary.append(tr("Unknown"));
420 // Show GPS Type
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()) {
425 case GPS_PLATINUM:
426 summary.append(tr("OpenPilot Platinum"));
427 break;
428 case GPS_UBX:
429 summary.append(tr("OpenPilot v8 or Generic UBLOX GPS"));
430 break;
431 case GPS_NMEA:
432 summary.append(tr("Generic NMEA GPS"));
433 break;
434 default:
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"));
446 break;
447 case AIRSPEED_EAGLETREE:
448 summary.append(tr("EagleTree on Flexi-Port"));
449 break;
450 case AIRSPEED_MS4525:
451 summary.append(tr("MS4525 based on Flexi-Port"));
452 break;
453 default:
454 summary.append(tr("Unknown"));
457 return summary;
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();
498 } else {
499 back();
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();
519 Q_ASSERT(pm);
520 UploaderGadgetFactory *uploader = pm->getObject<UploaderGadgetFactory>();
521 Q_ASSERT(uploader);
522 uploader->reboot();
524 wiz->setRestartNeeded(false);
525 wiz->setWindowFlags(wiz->windowFlags() | Qt::WindowStaysOnTopHint);
526 wiz->show();
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();
540 Q_ASSERT(pm);
541 UploaderGadgetFactory *uploader = pm->getObject<UploaderGadgetFactory>();
542 Q_ASSERT(uploader);
543 return uploader->isAutoUpdateCapable();