OP-1734 Change mixer values : Vtail and FixedWing rudder
[librepilot.git] / ground / openpilotgcs / src / plugins / setupwizard / vehicleconfigurationhelper.cpp
blob083a8185b9e1d7bca34e68d299fd750a77d6ee56
1 /**
2 ******************************************************************************
4 * @file vehicleconfigurationhelper.cpp
5 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
6 * @addtogroup
7 * @{
8 * @addtogroup VehicleConfigurationHelper
9 * @{
10 * @brief
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 "vehicleconfigurationhelper.h"
29 #include "extensionsystem/pluginmanager.h"
30 #include "hwsettings.h"
31 #include "actuatorsettings.h"
32 #include "attitudesettings.h"
33 #include "mixersettings.h"
34 #include "systemsettings.h"
35 #include "manualcontrolsettings.h"
36 #include "flightmodesettings.h"
37 #include "stabilizationsettings.h"
38 #include "stabilizationbank.h"
39 #include "stabilizationsettingsbank1.h"
40 #include "revocalibration.h"
41 #include "accelgyrosettings.h"
42 #include "gpssettings.h"
43 #include "airspeedsettings.h"
44 #include <QtCore/qmath.h>
45 #include <QJsonObject>
46 #include "auxmagsettings.h"
48 VehicleConfigurationHelper::VehicleConfigurationHelper(VehicleConfigurationSource *configSource)
49 : m_configSource(configSource), m_uavoManager(0),
50 m_transactionOK(false), m_transactionTimeout(false), m_currentTransactionObjectID(-1),
51 m_progress(0)
53 Q_ASSERT(m_configSource);
54 ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
55 m_uavoManager = pm->getObject<UAVObjectManager>();
56 Q_ASSERT(m_uavoManager);
59 bool VehicleConfigurationHelper::setupVehicle(bool save)
61 m_progress = 0;
62 clearModifiedObjects();
63 resetVehicleConfig();
64 resetGUIData();
65 if (!saveChangesToController(save)) {
66 return false;
69 m_progress = 0;
70 applyHardwareConfiguration();
71 applyVehicleConfiguration();
72 applyActuatorConfiguration();
73 applyFlightModeConfiguration();
75 if (save) {
76 applySensorBiasConfiguration();
79 applyStabilizationConfiguration();
80 applyManualControlDefaults();
82 applyTemplateSettings();
84 bool result = saveChangesToController(save);
85 emit saveProgress(m_modifiedObjects.count() + 1, ++m_progress, result ? tr("Done!") : tr("Failed!"));
86 return result;
89 bool VehicleConfigurationHelper::setupHardwareSettings(bool save)
91 m_progress = 0;
92 clearModifiedObjects();
93 applyHardwareConfiguration();
94 applyManualControlDefaults();
96 bool result = saveChangesToController(save);
97 emit saveProgress(m_modifiedObjects.count() + 1, ++m_progress, result ? tr("Done!") : tr("Failed!"));
98 return result;
101 bool VehicleConfigurationHelper::isApplicable(UAVObject *dataObj)
103 switch (m_configSource->getControllerType()) {
104 case VehicleConfigurationSource::CONTROLLER_CC:
105 case VehicleConfigurationSource::CONTROLLER_CC3D:
106 if (dataObj->getName() == "EKFConfiguration") {
107 return false;
109 default:
110 return true;
114 void VehicleConfigurationHelper::addModifiedObject(UAVDataObject *object, QString description)
116 m_modifiedObjects << new QPair<UAVDataObject *, QString>(object, description);
119 void VehicleConfigurationHelper::clearModifiedObjects()
121 for (int i = 0; i < m_modifiedObjects.count(); i++) {
122 QPair<UAVDataObject *, QString> *pair = m_modifiedObjects.at(i);
123 delete pair;
125 m_modifiedObjects.clear();
128 void VehicleConfigurationHelper::applyHardwareConfiguration()
130 HwSettings *hwSettings = HwSettings::GetInstance(m_uavoManager);
132 Q_ASSERT(hwSettings);
133 HwSettings::DataFields data = hwSettings->getData();
135 data.OptionalModules[HwSettings::OPTIONALMODULES_GPS] = 0;
136 data.OptionalModules[HwSettings::OPTIONALMODULES_AIRSPEED] = 0;
138 switch (m_configSource->getControllerType()) {
139 case VehicleConfigurationSource::CONTROLLER_CC:
140 case VehicleConfigurationSource::CONTROLLER_CC3D:
141 // Reset all ports
142 data.CC_RcvrPort = HwSettings::CC_RCVRPORT_DISABLEDONESHOT;
144 // Default mainport to be active telemetry link
145 data.CC_MainPort = HwSettings::CC_MAINPORT_TELEMETRY;
147 data.CC_FlexiPort = HwSettings::CC_FLEXIPORT_DISABLED;
148 switch (m_configSource->getInputType()) {
149 case VehicleConfigurationSource::INPUT_PWM:
150 data.CC_RcvrPort = HwSettings::CC_RCVRPORT_PWMNOONESHOT;
151 break;
152 case VehicleConfigurationSource::INPUT_PPM:
153 data.CC_RcvrPort = HwSettings::CC_RCVRPORT_PPMNOONESHOT;
154 break;
155 case VehicleConfigurationSource::INPUT_SBUS:
156 // We have to set teletry on flexport since s.bus needs the mainport.
157 data.CC_MainPort = HwSettings::CC_MAINPORT_SBUS;
158 data.CC_FlexiPort = HwSettings::CC_FLEXIPORT_TELEMETRY;
159 break;
160 case VehicleConfigurationSource::INPUT_DSM:
161 data.CC_FlexiPort = HwSettings::CC_FLEXIPORT_DSM;
162 break;
163 default:
164 break;
166 break;
167 case VehicleConfigurationSource::CONTROLLER_REVO:
168 case VehicleConfigurationSource::CONTROLLER_NANO:
169 case VehicleConfigurationSource::CONTROLLER_DISCOVERYF4:
170 // Reset all ports to their defaults
171 data.RM_RcvrPort = HwSettings::RM_RCVRPORT_DISABLED;
172 data.RM_FlexiPort = HwSettings::RM_FLEXIPORT_DISABLED;
174 // Revo uses inbuilt Modem do not set mainport to be active telemetry link for the Revo
175 if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_REVO) {
176 data.RM_MainPort = HwSettings::RM_MAINPORT_DISABLED;
177 } else {
178 data.RM_MainPort = HwSettings::RM_MAINPORT_TELEMETRY;
181 switch (m_configSource->getInputType()) {
182 case VehicleConfigurationSource::INPUT_PWM:
183 data.RM_RcvrPort = HwSettings::RM_RCVRPORT_PWM;
184 break;
185 case VehicleConfigurationSource::INPUT_PPM:
186 data.RM_RcvrPort = HwSettings::RM_RCVRPORT_PPM;
187 break;
188 case VehicleConfigurationSource::INPUT_SBUS:
189 data.RM_MainPort = HwSettings::RM_MAINPORT_SBUS;
190 // We have to set telemetry on flexport since s.bus needs the mainport on all but Revo.
191 if (m_configSource->getControllerType() != VehicleConfigurationSource::CONTROLLER_REVO) {
192 data.RM_FlexiPort = HwSettings::RM_FLEXIPORT_TELEMETRY;
194 break;
195 case VehicleConfigurationSource::INPUT_DSM:
196 data.RM_FlexiPort = HwSettings::RM_FLEXIPORT_DSM;
197 break;
198 default:
199 break;
202 if (m_configSource->getGpsType() != VehicleConfigurationSource::GPS_DISABLED) {
203 data.OptionalModules[HwSettings::OPTIONALMODULES_GPS] = 1;
204 data.GPSSpeed = HwSettings::GPSSPEED_57600;
206 if (m_configSource->getInputType() == VehicleConfigurationSource::INPUT_SBUS) {
207 data.RM_FlexiPort = HwSettings::RM_FLEXIPORT_GPS;
208 } else {
209 data.RM_MainPort = HwSettings::RM_MAINPORT_GPS;
212 GPSSettings *gpsSettings = GPSSettings::GetInstance(m_uavoManager);
213 Q_ASSERT(gpsSettings);
214 GPSSettings::DataFields gpsData = gpsSettings->getData();
215 gpsData.UbxAutoConfig = GPSSettings::UBXAUTOCONFIG_DISABLED;
217 switch (m_configSource->getGpsType()) {
218 case VehicleConfigurationSource::GPS_NMEA:
219 gpsData.DataProtocol = GPSSettings::DATAPROTOCOL_NMEA;
220 break;
221 case VehicleConfigurationSource::GPS_UBX:
222 gpsData.DataProtocol = GPSSettings::DATAPROTOCOL_UBX;
223 break;
224 case VehicleConfigurationSource::GPS_PLATINUM:
226 gpsData.DataProtocol = GPSSettings::DATAPROTOCOL_UBX;
227 gpsData.UbxAutoConfig = GPSSettings::UBXAUTOCONFIG_CONFIGURE;
228 AuxMagSettings *magSettings = AuxMagSettings::GetInstance(m_uavoManager);
229 Q_ASSERT(magSettings);
230 AuxMagSettings::DataFields magsData = magSettings->getData();
231 magsData.Usage = AuxMagSettings::USAGE_AUXONLY;
232 magSettings->setData(magsData);
233 addModifiedObject(magSettings, tr("Writing External Mag sensor settings"));
234 break;
236 case VehicleConfigurationSource::GPS_DISABLED:
237 // Should not be able to reach here
238 break;
241 gpsSettings->setData(gpsData);
242 addModifiedObject(gpsSettings, tr("Writing GPS sensor settings"));
243 } else {
244 data.OptionalModules[HwSettings::OPTIONALMODULES_GPS] = 0;
247 if (m_configSource->getVehicleType() == VehicleConfigurationSource::VEHICLE_FIXEDWING &&
248 m_configSource->getAirspeedType() != VehicleConfigurationSource::AIRSPEED_DISABLED) {
249 AirspeedSettings *airspeedSettings = AirspeedSettings::GetInstance(m_uavoManager);
250 Q_ASSERT(airspeedSettings);
251 AirspeedSettings::DataFields airspeedData = airspeedSettings->getData();
253 switch (m_configSource->getAirspeedType()) {
254 case VehicleConfigurationSource::AIRSPEED_ESTIMATE:
255 data.OptionalModules[HwSettings::OPTIONALMODULES_AIRSPEED] = 1;
256 airspeedData.AirspeedSensorType = AirspeedSettings::AIRSPEEDSENSORTYPE_GROUNDSPEEDBASEDWINDESTIMATION;
257 break;
258 case VehicleConfigurationSource::AIRSPEED_EAGLETREE:
259 data.OptionalModules[HwSettings::OPTIONALMODULES_AIRSPEED] = 1;
260 data.RM_FlexiPort = HwSettings::RM_FLEXIPORT_I2C;
261 airspeedData.AirspeedSensorType = AirspeedSettings::AIRSPEEDSENSORTYPE_EAGLETREEAIRSPEEDV3;
262 break;
263 case VehicleConfigurationSource::AIRSPEED_MS4525:
264 data.OptionalModules[HwSettings::OPTIONALMODULES_AIRSPEED] = 1;
265 data.RM_FlexiPort = HwSettings::RM_FLEXIPORT_I2C;
266 airspeedData.AirspeedSensorType = AirspeedSettings::AIRSPEEDSENSORTYPE_PIXHAWKAIRSPEEDMS4525DO;
267 break;
268 default:
269 data.OptionalModules[HwSettings::OPTIONALMODULES_AIRSPEED] = 0;
270 break;
273 airspeedSettings->setData(airspeedData);
274 addModifiedObject(airspeedSettings, tr("Writing Airspeed sensor settings"));
276 break;
277 default:
278 break;
280 hwSettings->setData(data);
281 addModifiedObject(hwSettings, tr("Writing hardware settings"));
284 void VehicleConfigurationHelper::applyVehicleConfiguration()
286 switch (m_configSource->getVehicleType()) {
287 case VehicleConfigurationSource::VEHICLE_MULTI:
289 switch (m_configSource->getVehicleSubType()) {
290 case VehicleConfigurationSource::MULTI_ROTOR_TRI_Y:
291 setupTriCopter();
292 break;
293 case VehicleConfigurationSource::MULTI_ROTOR_QUAD_X:
294 case VehicleConfigurationSource::MULTI_ROTOR_QUAD_PLUS:
295 setupQuadCopter();
296 break;
297 case VehicleConfigurationSource::MULTI_ROTOR_HEXA:
298 case VehicleConfigurationSource::MULTI_ROTOR_HEXA_COAX_Y:
299 case VehicleConfigurationSource::MULTI_ROTOR_HEXA_H:
300 case VehicleConfigurationSource::MULTI_ROTOR_HEXA_X:
301 setupHexaCopter();
302 break;
303 case VehicleConfigurationSource::MULTI_ROTOR_OCTO:
304 case VehicleConfigurationSource::MULTI_ROTOR_OCTO_X:
305 case VehicleConfigurationSource::MULTI_ROTOR_OCTO_COAX_X:
306 case VehicleConfigurationSource::MULTI_ROTOR_OCTO_COAX_PLUS:
307 case VehicleConfigurationSource::MULTI_ROTOR_OCTO_V:
308 setupOctoCopter();
309 break;
310 default:
311 break;
313 break;
315 case VehicleConfigurationSource::VEHICLE_FIXEDWING:
317 switch (m_configSource->getVehicleSubType()) {
318 case VehicleConfigurationSource::FIXED_WING_DUAL_AILERON:
319 setupDualAileron();
320 break;
321 case VehicleConfigurationSource::FIXED_WING_AILERON:
322 setupAileron();
323 break;
324 case VehicleConfigurationSource::FIXED_WING_ELEVON:
325 setupElevon();
326 break;
327 case VehicleConfigurationSource::FIXED_WING_VTAIL:
328 setupVtail();
329 break;
330 default:
331 break;
333 break;
335 case VehicleConfigurationSource::VEHICLE_HELI:
336 // TODO: Implement settings for Helis
337 break;
339 case VehicleConfigurationSource::VEHICLE_SURFACE:
341 switch (m_configSource->getVehicleSubType()) {
342 case VehicleConfigurationSource::GROUNDVEHICLE_CAR:
343 setupCar();
344 break;
345 case VehicleConfigurationSource::GROUNDVEHICLE_DIFFERENTIAL:
346 setupTank();
347 break;
348 case VehicleConfigurationSource::GROUNDVEHICLE_MOTORCYCLE:
349 setupMotorcycle();
350 break;
351 default:
352 break;
354 break;
357 default:
358 break;
362 void VehicleConfigurationHelper::applyActuatorConfiguration()
364 ActuatorSettings *actSettings = ActuatorSettings::GetInstance(m_uavoManager);
366 qint16 escFrequence = LEGACY_ESC_FREQUENCY;
368 switch (m_configSource->getEscType()) {
369 case VehicleConfigurationSource::ESC_STANDARD:
370 escFrequence = LEGACY_ESC_FREQUENCY;
371 break;
372 case VehicleConfigurationSource::ESC_RAPID:
373 escFrequence = RAPID_ESC_FREQUENCY;
374 break;
375 default:
376 break;
379 qint16 servoFrequence = ANALOG_SERVO_FREQUENCY;
380 switch (m_configSource->getServoType()) {
381 case VehicleConfigurationSource::SERVO_ANALOG:
382 servoFrequence = ANALOG_SERVO_FREQUENCY;
383 break;
384 case VehicleConfigurationSource::SERVO_DIGITAL:
385 servoFrequence = DIGITAL_SERVO_FREQUENCY;
386 break;
387 default:
388 break;
391 switch (m_configSource->getVehicleType()) {
392 case VehicleConfigurationSource::VEHICLE_MULTI:
394 ActuatorSettings::DataFields data = actSettings->getData();
396 QList<actuatorChannelSettings> actuatorSettings = m_configSource->getActuatorSettings();
397 for (quint16 i = 0; i < ActuatorSettings::CHANNELMAX_NUMELEM; i++) {
398 data.ChannelType[i] = ActuatorSettings::CHANNELTYPE_PWM;
399 data.ChannelAddr[i] = i;
400 data.ChannelMin[i] = actuatorSettings[i].channelMin;
401 data.ChannelNeutral[i] = actuatorSettings[i].channelNeutral;
402 data.ChannelMax[i] = actuatorSettings[i].channelMax;
405 data.MotorsSpinWhileArmed = ActuatorSettings::MOTORSSPINWHILEARMED_FALSE;
407 for (quint16 i = 0; i < ActuatorSettings::BANKUPDATEFREQ_NUMELEM; i++) {
408 data.BankUpdateFreq[i] = LEGACY_ESC_FREQUENCY;
411 switch (m_configSource->getVehicleSubType()) {
412 case VehicleConfigurationSource::MULTI_ROTOR_TRI_Y:
413 // Servo always on channel 4
414 data.BankUpdateFreq[0] = escFrequence;
415 if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_CC ||
416 m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_CC3D) {
417 data.BankUpdateFreq[1] = servoFrequence;
418 } else if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_REVO) {
419 data.BankUpdateFreq[1] = escFrequence;
420 data.BankUpdateFreq[2] = servoFrequence;
421 } else if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_NANO) {
422 data.BankUpdateFreq[1] = escFrequence;
423 data.BankUpdateFreq[2] = escFrequence;
424 data.BankUpdateFreq[3] = servoFrequence;
426 break;
427 case VehicleConfigurationSource::MULTI_ROTOR_QUAD_X:
428 case VehicleConfigurationSource::MULTI_ROTOR_QUAD_PLUS:
429 data.BankUpdateFreq[0] = escFrequence;
430 data.BankUpdateFreq[1] = escFrequence;
431 if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_REVO) {
432 data.BankUpdateFreq[2] = escFrequence;
434 break;
435 case VehicleConfigurationSource::MULTI_ROTOR_HEXA:
436 case VehicleConfigurationSource::MULTI_ROTOR_HEXA_COAX_Y:
437 case VehicleConfigurationSource::MULTI_ROTOR_HEXA_H:
438 case VehicleConfigurationSource::MULTI_ROTOR_HEXA_X:
439 case VehicleConfigurationSource::MULTI_ROTOR_OCTO:
440 case VehicleConfigurationSource::MULTI_ROTOR_OCTO_X:
441 case VehicleConfigurationSource::MULTI_ROTOR_OCTO_COAX_X:
442 case VehicleConfigurationSource::MULTI_ROTOR_OCTO_COAX_PLUS:
443 case VehicleConfigurationSource::MULTI_ROTOR_OCTO_V:
444 data.BankUpdateFreq[0] = escFrequence;
445 data.BankUpdateFreq[1] = escFrequence;
446 data.BankUpdateFreq[2] = escFrequence;
447 data.BankUpdateFreq[3] = escFrequence;
448 break;
449 default:
450 break;
452 actSettings->setData(data);
453 addModifiedObject(actSettings, tr("Writing actuator settings"));
454 break;
457 case VehicleConfigurationSource::VEHICLE_FIXEDWING:
459 ActuatorSettings::DataFields data = actSettings->getData();
461 QList<actuatorChannelSettings> actuatorSettings = m_configSource->getActuatorSettings();
462 for (quint16 i = 0; i < ActuatorSettings::CHANNELMAX_NUMELEM; i++) {
463 data.ChannelType[i] = ActuatorSettings::CHANNELTYPE_PWM;
464 data.ChannelAddr[i] = i;
465 data.ChannelMin[i] = actuatorSettings[i].channelMin;
466 data.ChannelNeutral[i] = actuatorSettings[i].channelNeutral;
467 data.ChannelMax[i] = actuatorSettings[i].channelMax;
470 for (quint16 i = 0; i < ActuatorSettings::BANKUPDATEFREQ_NUMELEM; i++) {
471 data.BankUpdateFreq[i] = servoFrequence;
472 if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_REVO) {
473 if (i == 1) {
474 data.BankUpdateFreq[i] = escFrequence;
476 } else if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_NANO) {
477 if (i == 2) {
478 data.BankUpdateFreq[i] = escFrequence;
483 actSettings->setData(data);
484 addModifiedObject(actSettings, tr("Writing actuator settings"));
486 break;
489 case VehicleConfigurationSource::VEHICLE_HELI:
490 // TODO: Implement settings for Heli vehicle types
491 break;
493 case VehicleConfigurationSource::VEHICLE_SURFACE:
495 ActuatorSettings::DataFields data = actSettings->getData();
497 QList<actuatorChannelSettings> actuatorSettings = m_configSource->getActuatorSettings();
498 for (quint16 i = 0; i < ActuatorSettings::CHANNELMAX_NUMELEM; i++) {
499 data.ChannelType[i] = ActuatorSettings::CHANNELTYPE_PWM;
500 data.ChannelAddr[i] = i;
501 data.ChannelMin[i] = actuatorSettings[i].channelMin;
502 data.ChannelNeutral[i] = actuatorSettings[i].channelNeutral;
503 data.ChannelMax[i] = actuatorSettings[i].channelMax;
506 for (quint16 i = 0; i < ActuatorSettings::BANKUPDATEFREQ_NUMELEM; i++) {
507 data.BankUpdateFreq[i] = servoFrequence;
508 if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_REVO) {
509 if (i == 1) {
510 data.BankUpdateFreq[i] = escFrequence;
512 } else if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_NANO) {
513 if (i == 2) {
514 data.BankUpdateFreq[i] = escFrequence;
519 actSettings->setData(data);
520 addModifiedObject(actSettings, tr("Writing actuator settings"));
522 break;
525 default:
526 break;
530 void VehicleConfigurationHelper::applyFlightModeConfiguration()
532 FlightModeSettings *modeSettings = FlightModeSettings::GetInstance(m_uavoManager);
533 ManualControlSettings *controlSettings = ManualControlSettings::GetInstance(m_uavoManager);
535 Q_ASSERT(modeSettings);
536 Q_ASSERT(controlSettings);
538 FlightModeSettings::DataFields data = modeSettings->getData();
539 ManualControlSettings::DataFields data2 = controlSettings->getData();
540 data.Stabilization1Settings[0] = FlightModeSettings::STABILIZATION1SETTINGS_ATTITUDE;
541 data.Stabilization1Settings[1] = FlightModeSettings::STABILIZATION1SETTINGS_ATTITUDE;
542 data.Stabilization1Settings[2] = FlightModeSettings::STABILIZATION1SETTINGS_AXISLOCK;
543 data.Stabilization1Settings[3] = FlightModeSettings::STABILIZATION1SETTINGS_MANUAL;
544 data.Stabilization2Settings[0] = FlightModeSettings::STABILIZATION2SETTINGS_ATTITUDE;
545 data.Stabilization2Settings[1] = FlightModeSettings::STABILIZATION2SETTINGS_ATTITUDE;
546 data.Stabilization2Settings[2] = FlightModeSettings::STABILIZATION2SETTINGS_RATE;
547 data.Stabilization2Settings[3] = FlightModeSettings::STABILIZATION2SETTINGS_MANUAL;
548 data.Stabilization3Settings[0] = FlightModeSettings::STABILIZATION3SETTINGS_RATE;
549 data.Stabilization3Settings[1] = FlightModeSettings::STABILIZATION3SETTINGS_RATE;
550 data.Stabilization3Settings[2] = FlightModeSettings::STABILIZATION3SETTINGS_RATE;
551 data.Stabilization3Settings[3] = FlightModeSettings::STABILIZATION3SETTINGS_MANUAL;
552 data.Stabilization4Settings[0] = FlightModeSettings::STABILIZATION4SETTINGS_ATTITUDE;
553 data.Stabilization4Settings[1] = FlightModeSettings::STABILIZATION4SETTINGS_ATTITUDE;
554 data.Stabilization4Settings[2] = FlightModeSettings::STABILIZATION4SETTINGS_AXISLOCK;
555 data.Stabilization4Settings[3] = FlightModeSettings::STABILIZATION4SETTINGS_CRUISECONTROL;
556 data.Stabilization5Settings[0] = FlightModeSettings::STABILIZATION5SETTINGS_ATTITUDE;
557 data.Stabilization5Settings[1] = FlightModeSettings::STABILIZATION5SETTINGS_ATTITUDE;
558 data.Stabilization5Settings[2] = FlightModeSettings::STABILIZATION5SETTINGS_RATE;
559 data.Stabilization5Settings[3] = FlightModeSettings::STABILIZATION5SETTINGS_CRUISECONTROL;
560 data.Stabilization6Settings[0] = FlightModeSettings::STABILIZATION6SETTINGS_RATE;
561 data.Stabilization6Settings[1] = FlightModeSettings::STABILIZATION6SETTINGS_RATE;
562 data.Stabilization6Settings[2] = FlightModeSettings::STABILIZATION6SETTINGS_RATE;
563 data.Stabilization6Settings[3] = FlightModeSettings::STABILIZATION6SETTINGS_CRUISECONTROL;
564 data2.FlightModeNumber = 3;
565 data.FlightModePosition[0] = FlightModeSettings::FLIGHTMODEPOSITION_STABILIZED1;
566 data.FlightModePosition[1] = FlightModeSettings::FLIGHTMODEPOSITION_STABILIZED2;
567 data.FlightModePosition[2] = FlightModeSettings::FLIGHTMODEPOSITION_STABILIZED3;
568 data.FlightModePosition[3] = FlightModeSettings::FLIGHTMODEPOSITION_STABILIZED4;
569 data.FlightModePosition[4] = FlightModeSettings::FLIGHTMODEPOSITION_STABILIZED5;
570 data.FlightModePosition[5] = FlightModeSettings::FLIGHTMODEPOSITION_STABILIZED6;
571 modeSettings->setData(data);
572 addModifiedObject(modeSettings, tr("Writing flight mode settings 1/2"));
573 controlSettings->setData(data2);
574 addModifiedObject(controlSettings, tr("Writing flight mode settings 2/2"));
577 void VehicleConfigurationHelper::applySensorBiasConfiguration()
579 if (m_configSource->isCalibrationPerformed()) {
580 accelGyroBias bias = m_configSource->getCalibrationBias();
581 float G = 9.81f;
583 AccelGyroSettings *accelGyroSettings = AccelGyroSettings::GetInstance(m_uavoManager);
584 Q_ASSERT(accelGyroSettings);
585 AccelGyroSettings::DataFields accelGyroSettingsData = accelGyroSettings->getData();
587 accelGyroSettingsData.accel_bias[AccelGyroSettings::ACCEL_BIAS_X] += bias.m_accelerometerXBias;
588 accelGyroSettingsData.accel_bias[AccelGyroSettings::ACCEL_BIAS_Y] += bias.m_accelerometerYBias;
589 accelGyroSettingsData.accel_bias[AccelGyroSettings::ACCEL_BIAS_Z] += bias.m_accelerometerZBias + G;
590 accelGyroSettingsData.gyro_bias[AccelGyroSettings::GYRO_BIAS_X] = bias.m_gyroXBias;
591 accelGyroSettingsData.gyro_bias[AccelGyroSettings::GYRO_BIAS_Y] = bias.m_gyroYBias;
592 accelGyroSettingsData.gyro_bias[AccelGyroSettings::GYRO_BIAS_Z] = bias.m_gyroZBias;
594 accelGyroSettings->setData(accelGyroSettingsData);
595 addModifiedObject(accelGyroSettings, tr("Writing gyro and accelerometer bias settings"));
597 switch (m_configSource->getControllerType()) {
598 case VehicleConfigurationSource::CONTROLLER_CC:
599 case VehicleConfigurationSource::CONTROLLER_CC3D:
601 AttitudeSettings *copterControlCalibration = AttitudeSettings::GetInstance(m_uavoManager);
602 Q_ASSERT(copterControlCalibration);
603 AttitudeSettings::DataFields data = copterControlCalibration->getData();
605 data.AccelTau = DEFAULT_ENABLED_ACCEL_TAU;
606 data.BiasCorrectGyro = AttitudeSettings::BIASCORRECTGYRO_TRUE;
608 copterControlCalibration->setData(data);
609 addModifiedObject(copterControlCalibration, tr("Writing board settings"));
610 break;
612 case VehicleConfigurationSource::CONTROLLER_REVO:
614 RevoCalibration *revolutionCalibration = RevoCalibration::GetInstance(m_uavoManager);
615 Q_ASSERT(revolutionCalibration);
616 RevoCalibration::DataFields data = revolutionCalibration->getData();
618 data.BiasCorrectedRaw = RevoCalibration::BIASCORRECTEDRAW_TRUE;
620 revolutionCalibration->setData(data);
621 addModifiedObject(revolutionCalibration, tr("Writing board settings"));
622 break;
624 default:
625 // Something went terribly wrong.
626 break;
631 void VehicleConfigurationHelper::applyStabilizationConfiguration()
633 StabilizationSettings *stabSettings = StabilizationSettings::GetInstance(m_uavoManager);
635 Q_ASSERT(stabSettings);
637 StabilizationSettings defaultSettings;
638 stabSettings->setData(defaultSettings.getData());
639 addModifiedObject(stabSettings, tr("Writing stabilization settings"));
642 void VehicleConfigurationHelper::applyMixerConfiguration(mixerChannelSettings channels[])
644 // Set all mixer data
645 MixerSettings *mSettings = MixerSettings::GetInstance(m_uavoManager);
647 Q_ASSERT(mSettings);
649 // Set Mixer types and values
650 QString mixerTypePattern = "Mixer%1Type";
651 QString mixerVectorPattern = "Mixer%1Vector";
652 for (quint32 i = 0; i < ActuatorSettings::CHANNELADDR_NUMELEM; i++) {
653 UAVObjectField *field = mSettings->getField(mixerTypePattern.arg(i + 1));
654 Q_ASSERT(field);
655 field->setValue(field->getOptions().at(channels[i].type));
657 field = mSettings->getField(mixerVectorPattern.arg(i + 1));
658 Q_ASSERT(field);
659 field->setValue((channels[i].throttle1 * 127) / 100, 0);
660 field->setValue((channels[i].throttle2 * 127) / 100, 1);
662 // Normalize mixer values, allow a well balanced mixer saved
663 if (channels[i].roll < 0) {
664 field->setValue(qFloor((double)(channels[i].roll * 127) / 100), 2);
665 } else {
666 field->setValue(qCeil((double)(channels[i].roll * 127) / 100), 2);
669 if (channels[i].pitch < 0) {
670 field->setValue(qFloor((double)(channels[i].pitch * 127) / 100), 3);
671 } else {
672 field->setValue(qCeil((double)(channels[i].pitch * 127) / 100), 3);
675 if (channels[i].yaw < 0) {
676 field->setValue(qFloor((double)(channels[i].yaw * 127) / 100), 4);
677 } else {
678 field->setValue(qCeil((double)(channels[i].yaw * 127) / 100), 4);
682 // Default maxThrottle and minThrottle
683 float maxThrottle = 0.9;
684 float minThrottle = 0;
687 // Save mixer values for sliders
688 switch (m_configSource->getVehicleType()) {
689 case VehicleConfigurationSource::VEHICLE_MULTI:
691 switch (m_configSource->getVehicleSubType()) {
692 case VehicleConfigurationSource::MULTI_ROTOR_TRI_Y:
693 case VehicleConfigurationSource::MULTI_ROTOR_HEXA:
694 case VehicleConfigurationSource::MULTI_ROTOR_HEXA_H:
695 case VehicleConfigurationSource::MULTI_ROTOR_HEXA_X:
696 mSettings->setMixerValueRoll(100);
697 mSettings->setMixerValuePitch(100);
698 mSettings->setMixerValueYaw(100);
699 break;
700 case VehicleConfigurationSource::MULTI_ROTOR_QUAD_X:
701 mSettings->setMixerValueRoll(50);
702 mSettings->setMixerValuePitch(50);
703 mSettings->setMixerValueYaw(50);
704 break;
705 case VehicleConfigurationSource::MULTI_ROTOR_QUAD_PLUS:
706 mSettings->setMixerValueRoll(100);
707 mSettings->setMixerValuePitch(100);
708 mSettings->setMixerValueYaw(50);
709 break;
710 case VehicleConfigurationSource::MULTI_ROTOR_HEXA_COAX_Y:
711 mSettings->setMixerValueRoll(100);
712 mSettings->setMixerValuePitch(50);
713 mSettings->setMixerValueYaw(66);
714 break;
715 case VehicleConfigurationSource::MULTI_ROTOR_OCTO:
716 case VehicleConfigurationSource::MULTI_ROTOR_OCTO_X:
717 mSettings->setMixerValueRoll(100);
718 mSettings->setMixerValuePitch(100);
719 mSettings->setMixerValueYaw(100);
720 break;
721 case VehicleConfigurationSource::MULTI_ROTOR_OCTO_COAX_X:
722 case VehicleConfigurationSource::MULTI_ROTOR_OCTO_COAX_PLUS:
723 case VehicleConfigurationSource::MULTI_ROTOR_OCTO_V:
724 break;
725 default:
726 break;
728 break;
730 case VehicleConfigurationSource::VEHICLE_FIXEDWING:
731 mSettings->setMixerValueRoll(100);
732 mSettings->setMixerValuePitch(100);
733 mSettings->setMixerValueYaw(100);
734 maxThrottle = 1;
735 break;
736 case VehicleConfigurationSource::VEHICLE_HELI:
737 break;
738 case VehicleConfigurationSource::VEHICLE_SURFACE:
740 switch (m_configSource->getVehicleSubType()) {
741 case VehicleConfigurationSource::GROUNDVEHICLE_MOTORCYCLE:
742 mSettings->setMixerValueRoll(100);
743 mSettings->setMixerValuePitch(100);
744 mSettings->setMixerValueYaw(100);
745 maxThrottle = 1;
746 break;
747 case VehicleConfigurationSource::GROUNDVEHICLE_CAR:
748 mSettings->setMixerValueRoll(100);
749 mSettings->setMixerValuePitch(100);
750 mSettings->setMixerValueYaw(100);
751 // Set curve2 range from -0.926 to 1 : take in account 4% offset in Throttle input
752 // 0.5 / 0.54 = 0.926
753 maxThrottle = 1;
754 minThrottle = -0.926;
755 break;
756 case VehicleConfigurationSource::GROUNDVEHICLE_DIFFERENTIAL:
757 mSettings->setMixerValueRoll(100);
758 mSettings->setMixerValuePitch(100);
759 mSettings->setMixerValueYaw(100);
760 maxThrottle = 0.8;
761 minThrottle = -0.8;
762 break;
763 default:
764 break;
768 break;
769 default:
770 break;
773 // Apply Throttle curve max 90% for Multis, 100% for FixedWing/car/Motorbike, 80% for Tank
774 QString throttlePattern = "ThrottleCurve%1";
775 for (int i = 1; i <= 2; i++) {
776 UAVObjectField *field = mSettings->getField(throttlePattern.arg(i));
777 Q_ASSERT(field);
778 for (quint32 i = 0; i < field->getNumElements(); i++) {
779 field->setValue(minThrottle + (i * ((maxThrottle - minThrottle) / (field->getNumElements() - 1))), i);
783 // Apply updates
784 mSettings->setData(mSettings->getData());
785 addModifiedObject(mSettings, tr("Writing mixer settings"));
788 void VehicleConfigurationHelper::applyMultiGUISettings(SystemSettings::AirframeTypeOptions airframe, GUIConfigDataUnion guiConfig)
790 SystemSettings *sSettings = SystemSettings::GetInstance(m_uavoManager);
792 Q_ASSERT(sSettings);
793 SystemSettings::DataFields data = sSettings->getData();
794 data.AirframeType = airframe;
796 for (int i = 0; i < (int)(SystemSettings::GUICONFIGDATA_NUMELEM); i++) {
797 data.GUIConfigData[i] = guiConfig.UAVObject[i];
800 sSettings->setData(data);
801 addModifiedObject(sSettings, tr("Writing vehicle settings"));
804 void VehicleConfigurationHelper::applyManualControlDefaults()
806 ManualControlSettings *mcSettings = ManualControlSettings::GetInstance(m_uavoManager);
808 Q_ASSERT(mcSettings);
809 ManualControlSettings::DataFields cData = mcSettings->getData();
811 ManualControlSettings::ChannelGroupsOptions channelType = ManualControlSettings::CHANNELGROUPS_PWM;
812 switch (m_configSource->getInputType()) {
813 case VehicleConfigurationSource::INPUT_PWM:
814 channelType = ManualControlSettings::CHANNELGROUPS_PWM;
815 break;
816 case VehicleConfigurationSource::INPUT_PPM:
817 channelType = ManualControlSettings::CHANNELGROUPS_PPM;
818 break;
819 case VehicleConfigurationSource::INPUT_SBUS:
820 channelType = ManualControlSettings::CHANNELGROUPS_SBUS;
821 break;
822 case VehicleConfigurationSource::INPUT_DSM:
823 channelType = ManualControlSettings::CHANNELGROUPS_DSMFLEXIPORT;
824 break;
825 default:
826 break;
829 cData.ChannelGroups[ManualControlSettings::CHANNELGROUPS_THROTTLE] = channelType;
830 cData.ChannelGroups[ManualControlSettings::CHANNELGROUPS_ROLL] = channelType;
831 cData.ChannelGroups[ManualControlSettings::CHANNELGROUPS_YAW] = channelType;
832 cData.ChannelGroups[ManualControlSettings::CHANNELGROUPS_PITCH] = channelType;
833 cData.ChannelGroups[ManualControlSettings::CHANNELGROUPS_FLIGHTMODE] = channelType;
835 mcSettings->setData(cData);
836 addModifiedObject(mcSettings, tr("Writing manual control defaults"));
839 void VehicleConfigurationHelper::applyTemplateSettings()
841 if (m_configSource->getVehicleTemplate() != NULL) {
842 QJsonObject *json = m_configSource->getVehicleTemplate();
843 QList<UAVObject *> updatedObjects;
844 m_uavoManager->fromJson(*json, &updatedObjects);
845 foreach(UAVObject * object, updatedObjects) {
846 UAVDataObject *dataObj = dynamic_cast<UAVDataObject *>(object);
848 if (dataObj != NULL && isApplicable(dataObj)) {
849 addModifiedObject(dataObj, tr("Writing template settings for %1").arg(object->getName()));
855 bool VehicleConfigurationHelper::saveChangesToController(bool save)
857 qDebug() << "Saving modified objects to controller. " << m_modifiedObjects.count() << " objects in found.";
858 const int OUTER_TIMEOUT = 3000 * 20; // 10 seconds timeout for saving all objects
859 const int INNER_TIMEOUT = 2000; // 1 second timeout on every save attempt
861 ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
862 Q_ASSERT(pm);
863 UAVObjectUtilManager *utilMngr = pm->getObject<UAVObjectUtilManager>();
864 Q_ASSERT(utilMngr);
866 QTimer outerTimeoutTimer;
867 outerTimeoutTimer.setSingleShot(true);
869 QTimer innerTimeoutTimer;
870 innerTimeoutTimer.setSingleShot(true);
872 connect(utilMngr, SIGNAL(saveCompleted(int, bool)), this, SLOT(uAVOTransactionCompleted(int, bool)));
873 connect(&innerTimeoutTimer, SIGNAL(timeout()), &m_eventLoop, SLOT(quit()));
874 connect(&outerTimeoutTimer, SIGNAL(timeout()), this, SLOT(saveChangesTimeout()));
876 outerTimeoutTimer.start(OUTER_TIMEOUT);
877 for (int i = 0; i < m_modifiedObjects.count(); i++) {
878 QPair<UAVDataObject *, QString> *objPair = m_modifiedObjects.at(i);
879 m_transactionOK = false;
880 UAVDataObject *obj = objPair->first;
881 QString objDescription = objPair->second;
882 if (UAVObject::GetGcsAccess(obj->getMetadata()) != UAVObject::ACCESS_READONLY && obj->isSettingsObject()) {
883 emit saveProgress(m_modifiedObjects.count() + 1, ++m_progress, objDescription);
885 m_currentTransactionObjectID = obj->getObjID();
887 connect(obj, SIGNAL(transactionCompleted(UAVObject *, bool)), this, SLOT(uAVOTransactionCompleted(UAVObject *, bool)));
888 while (!m_transactionOK && !m_transactionTimeout) {
889 // Allow the transaction to take some time
890 innerTimeoutTimer.start(INNER_TIMEOUT);
892 // Set object updated
893 obj->updated();
894 if (!m_transactionOK) {
895 m_eventLoop.exec();
897 innerTimeoutTimer.stop();
899 disconnect(obj, SIGNAL(transactionCompleted(UAVObject *, bool)), this, SLOT(uAVOTransactionCompleted(UAVObject *, bool)));
900 if (m_transactionOK) {
901 qDebug() << "Object " << obj->getName() << " was successfully updated.";
902 if (save) {
903 m_transactionOK = false;
904 m_currentTransactionObjectID = obj->getObjID();
905 // Try to save until success or timeout
906 while (!m_transactionOK && !m_transactionTimeout) {
907 // Allow the transaction to take some time
908 innerTimeoutTimer.start(INNER_TIMEOUT);
910 // Persist object in controller
911 utilMngr->saveObjectToSD(obj);
912 if (!m_transactionOK) {
913 m_eventLoop.exec();
915 innerTimeoutTimer.stop();
917 m_currentTransactionObjectID = -1;
921 if (!m_transactionOK) {
922 qDebug() << "Transaction timed out when trying to save: " << obj->getName();
923 } else {
924 qDebug() << "Object " << obj->getName() << " was successfully saved.";
926 } else {
927 qDebug() << "Trying to save a UAVDataObject that is read only or is not a settings object.";
929 if (m_transactionTimeout) {
930 qDebug() << "Transaction timed out when trying to save " << m_modifiedObjects.count() << " objects.";
931 break;
935 outerTimeoutTimer.stop();
936 disconnect(&outerTimeoutTimer, SIGNAL(timeout()), this, SLOT(saveChangesTimeout()));
937 disconnect(&innerTimeoutTimer, SIGNAL(timeout()), &m_eventLoop, SLOT(quit()));
938 disconnect(utilMngr, SIGNAL(saveCompleted(int, bool)), this, SLOT(uAVOTransactionCompleted(int, bool)));
940 qDebug() << "Finished saving modified objects to controller. Success = " << m_transactionOK;
942 return m_transactionOK;
945 void VehicleConfigurationHelper::uAVOTransactionCompleted(int oid, bool success)
947 if (oid == m_currentTransactionObjectID) {
948 m_transactionOK = success;
949 m_eventLoop.quit();
953 void VehicleConfigurationHelper::uAVOTransactionCompleted(UAVObject *object, bool success)
955 if (object) {
956 uAVOTransactionCompleted(object->getObjID(), success);
960 void VehicleConfigurationHelper::saveChangesTimeout()
962 m_transactionOK = false;
963 m_transactionTimeout = true;
964 m_eventLoop.quit();
967 void VehicleConfigurationHelper::resetVehicleConfig()
969 // Reset all vehicle data
970 MixerSettings *mSettings = MixerSettings::GetInstance(m_uavoManager);
972 // Reset feed forward, accel times etc
973 mSettings->setFeedForward(0.0f);
974 mSettings->setMaxAccel(1000.0f);
975 mSettings->setAccelTime(0.0f);
976 mSettings->setDecelTime(0.0f);
978 // Reset throttle curves
979 QString throttlePattern = "ThrottleCurve%1";
980 for (int i = 1; i <= 2; i++) {
981 UAVObjectField *field = mSettings->getField(throttlePattern.arg(i));
982 Q_ASSERT(field);
983 // Set default curve at 90% max for Multirotors
984 for (quint32 i = 0; i < field->getNumElements(); i++) {
985 field->setValue(i * (0.9f / (field->getNumElements() - 1)), i);
989 // Reset Mixer types and values
990 QString mixerTypePattern = "Mixer%1Type";
991 QString mixerVectorPattern = "Mixer%1Vector";
992 for (int i = 1; i <= 10; i++) {
993 UAVObjectField *field = mSettings->getField(mixerTypePattern.arg(i));
994 Q_ASSERT(field);
995 field->setValue(field->getOptions().at(0));
997 field = mSettings->getField(mixerVectorPattern.arg(i));
998 Q_ASSERT(field);
999 for (quint32 i = 0; i < field->getNumElements(); i++) {
1000 field->setValue(0, i);
1004 // Apply updates
1005 // mSettings->setData(mSettings->getData());
1006 addModifiedObject(mSettings, tr("Preparing mixer settings"));
1009 void VehicleConfigurationHelper::resetGUIData()
1011 SystemSettings *sSettings = SystemSettings::GetInstance(m_uavoManager);
1013 Q_ASSERT(sSettings);
1014 SystemSettings::DataFields data = sSettings->getData();
1015 data.AirframeType = SystemSettings::AIRFRAMETYPE_CUSTOM;
1016 for (quint32 i = 0; i < SystemSettings::GUICONFIGDATA_NUMELEM; i++) {
1017 data.GUIConfigData[i] = 0;
1019 sSettings->setData(data);
1020 addModifiedObject(sSettings, tr("Preparing vehicle settings"));
1024 void VehicleConfigurationHelper::setupTriCopter()
1026 // Typical vehicle setup
1027 // 1. Setup mixer data
1028 // 2. Setup GUI data
1029 // 3. Apply changes
1031 mixerChannelSettings channels[ActuatorSettings::CHANNELADDR_NUMELEM];
1032 GUIConfigDataUnion guiSettings = getGUIConfigData();
1034 channels[0].type = MIXER_TYPE_MOTOR;
1035 channels[0].throttle1 = 100;
1036 channels[0].throttle2 = 0;
1037 channels[0].roll = 100;
1038 channels[0].pitch = 50;
1039 channels[0].yaw = 0;
1041 channels[1].type = MIXER_TYPE_MOTOR;
1042 channels[1].throttle1 = 100;
1043 channels[1].throttle2 = 0;
1044 channels[1].roll = -100;
1045 channels[1].pitch = 50;
1046 channels[1].yaw = 0;
1048 channels[2].type = MIXER_TYPE_MOTOR;
1049 channels[2].throttle1 = 100;
1050 channels[2].throttle2 = 0;
1051 channels[2].roll = 0;
1052 channels[2].pitch = -100;
1053 channels[2].yaw = 0;
1055 channels[3].type = MIXER_TYPE_SERVO;
1056 channels[3].throttle1 = 0;
1057 channels[3].throttle2 = 0;
1058 channels[3].roll = 0;
1059 channels[3].pitch = 0;
1060 channels[3].yaw = 100;
1062 guiSettings.multi.VTOLMotorNW = 1;
1063 guiSettings.multi.VTOLMotorNE = 2;
1064 guiSettings.multi.VTOLMotorS = 3;
1065 guiSettings.multi.TRIYaw = 4;
1067 applyMixerConfiguration(channels);
1068 applyMultiGUISettings(SystemSettings::AIRFRAMETYPE_TRI, guiSettings);
1071 GUIConfigDataUnion VehicleConfigurationHelper::getGUIConfigData()
1073 GUIConfigDataUnion configData;
1075 for (int i = 0; i < (int)(SystemSettings::GUICONFIGDATA_NUMELEM); i++) {
1076 configData.UAVObject[i] = 0; // systemSettingsData.GUIConfigData[i];
1079 return configData;
1082 void VehicleConfigurationHelper::setupQuadCopter()
1084 mixerChannelSettings channels[ActuatorSettings::CHANNELADDR_NUMELEM];
1085 GUIConfigDataUnion guiSettings = getGUIConfigData();
1086 SystemSettings::AirframeTypeOptions frame = SystemSettings::AIRFRAMETYPE_QUADX;
1088 switch (m_configSource->getVehicleSubType()) {
1089 case VehicleConfigurationSource::MULTI_ROTOR_QUAD_PLUS:
1091 frame = SystemSettings::AIRFRAMETYPE_QUADP;
1092 channels[0].type = MIXER_TYPE_MOTOR;
1093 channels[0].throttle1 = 100;
1094 channels[0].throttle2 = 0;
1095 channels[0].roll = 0;
1096 channels[0].pitch = 100;
1097 channels[0].yaw = -50;
1099 channels[1].type = MIXER_TYPE_MOTOR;
1100 channels[1].throttle1 = 100;
1101 channels[1].throttle2 = 0;
1102 channels[1].roll = -100;
1103 channels[1].pitch = 0;
1104 channels[1].yaw = 50;
1106 channels[2].type = MIXER_TYPE_MOTOR;
1107 channels[2].throttle1 = 100;
1108 channels[2].throttle2 = 0;
1109 channels[2].roll = 0;
1110 channels[2].pitch = -100;
1111 channels[2].yaw = -50;
1113 channels[3].type = MIXER_TYPE_MOTOR;
1114 channels[3].throttle1 = 100;
1115 channels[3].throttle2 = 0;
1116 channels[3].roll = 100;
1117 channels[3].pitch = 0;
1118 channels[3].yaw = 50;
1120 guiSettings.multi.VTOLMotorN = 1;
1121 guiSettings.multi.VTOLMotorE = 2;
1122 guiSettings.multi.VTOLMotorS = 3;
1123 guiSettings.multi.VTOLMotorW = 4;
1125 break;
1127 case VehicleConfigurationSource::MULTI_ROTOR_QUAD_X:
1129 frame = SystemSettings::AIRFRAMETYPE_QUADX;
1130 channels[0].type = MIXER_TYPE_MOTOR;
1131 channels[0].throttle1 = 100;
1132 channels[0].throttle2 = 0;
1133 channels[0].roll = 50;
1134 channels[0].pitch = 50;
1135 channels[0].yaw = -50;
1137 channels[1].type = MIXER_TYPE_MOTOR;
1138 channels[1].throttle1 = 100;
1139 channels[1].throttle2 = 0;
1140 channels[1].roll = -50;
1141 channels[1].pitch = 50;
1142 channels[1].yaw = 50;
1144 channels[2].type = MIXER_TYPE_MOTOR;
1145 channels[2].throttle1 = 100;
1146 channels[2].throttle2 = 0;
1147 channels[2].roll = -50;
1148 channels[2].pitch = -50;
1149 channels[2].yaw = -50;
1151 channels[3].type = MIXER_TYPE_MOTOR;
1152 channels[3].throttle1 = 100;
1153 channels[3].throttle2 = 0;
1154 channels[3].roll = 50;
1155 channels[3].pitch = -50;
1156 channels[3].yaw = 50;
1158 guiSettings.multi.VTOLMotorNW = 1;
1159 guiSettings.multi.VTOLMotorNE = 2;
1160 guiSettings.multi.VTOLMotorSE = 3;
1161 guiSettings.multi.VTOLMotorSW = 4;
1163 break;
1165 default:
1166 break;
1168 applyMixerConfiguration(channels);
1169 applyMultiGUISettings(frame, guiSettings);
1172 void VehicleConfigurationHelper::setupHexaCopter()
1174 mixerChannelSettings channels[ActuatorSettings::CHANNELADDR_NUMELEM];
1175 GUIConfigDataUnion guiSettings = getGUIConfigData();
1176 SystemSettings::AirframeTypeOptions frame = SystemSettings::AIRFRAMETYPE_HEXA;
1178 switch (m_configSource->getVehicleSubType()) {
1179 case VehicleConfigurationSource::MULTI_ROTOR_HEXA:
1181 frame = SystemSettings::AIRFRAMETYPE_HEXA;
1182 // HexaPlus according to new mixer table and pitch-roll-yaw mixing at 100%
1183 // Pitch Roll Yaw
1184 // M1 { 1 , 0 , -1 },
1185 // M2 { 0.5, -1, 1 },
1186 // M3 { -0.5, -1, -1 },
1187 // M4 { -1 , 0 , 1 },
1188 // M5 { -0.5, 1 , -1 },
1189 // M6 { 0.5, 1 , 1 },
1190 channels[0].type = MIXER_TYPE_MOTOR;
1191 channels[0].throttle1 = 100;
1192 channels[0].throttle2 = 0;
1193 channels[0].roll = 0;
1194 channels[0].pitch = 100;
1195 channels[0].yaw = -100;
1197 channels[1].type = MIXER_TYPE_MOTOR;
1198 channels[1].throttle1 = 100;
1199 channels[1].throttle2 = 0;
1200 channels[1].roll = -100;
1201 channels[1].pitch = 50;
1202 channels[1].yaw = 100;
1204 channels[2].type = MIXER_TYPE_MOTOR;
1205 channels[2].throttle1 = 100;
1206 channels[2].throttle2 = 0;
1207 channels[2].roll = -100;
1208 channels[2].pitch = -50;
1209 channels[2].yaw = -100;
1211 channels[3].type = MIXER_TYPE_MOTOR;
1212 channels[3].throttle1 = 100;
1213 channels[3].throttle2 = 0;
1214 channels[3].roll = 0;
1215 channels[3].pitch = -100;
1216 channels[3].yaw = 100;
1218 channels[4].type = MIXER_TYPE_MOTOR;
1219 channels[4].throttle1 = 100;
1220 channels[4].throttle2 = 0;
1221 channels[4].roll = 100;
1222 channels[4].pitch = -50;
1223 channels[4].yaw = -100;
1225 channels[5].type = MIXER_TYPE_MOTOR;
1226 channels[5].throttle1 = 100;
1227 channels[5].throttle2 = 0;
1228 channels[5].roll = 100;
1229 channels[5].pitch = 50;
1230 channels[5].yaw = 100;
1232 guiSettings.multi.VTOLMotorN = 1;
1233 guiSettings.multi.VTOLMotorNE = 2;
1234 guiSettings.multi.VTOLMotorSE = 3;
1235 guiSettings.multi.VTOLMotorS = 4;
1236 guiSettings.multi.VTOLMotorSW = 5;
1237 guiSettings.multi.VTOLMotorNW = 6;
1239 break;
1241 case VehicleConfigurationSource::MULTI_ROTOR_HEXA_COAX_Y:
1243 frame = SystemSettings::AIRFRAMETYPE_HEXACOAX;
1245 channels[0].type = MIXER_TYPE_MOTOR;
1246 channels[0].throttle1 = 100;
1247 channels[0].throttle2 = 0;
1248 channels[0].roll = 100;
1249 channels[0].pitch = 25;
1250 channels[0].yaw = -66;
1252 channels[1].type = MIXER_TYPE_MOTOR;
1253 channels[1].throttle1 = 100;
1254 channels[1].throttle2 = 0;
1255 channels[1].roll = 100;
1256 channels[1].pitch = 25;
1257 channels[1].yaw = 66;
1259 channels[2].type = MIXER_TYPE_MOTOR;
1260 channels[2].throttle1 = 100;
1261 channels[2].throttle2 = 0;
1262 channels[2].roll = -100;
1263 channels[2].pitch = 25;
1264 channels[2].yaw = -66;
1266 channels[3].type = MIXER_TYPE_MOTOR;
1267 channels[3].throttle1 = 100;
1268 channels[3].throttle2 = 0;
1269 channels[3].roll = -100;
1270 channels[3].pitch = 25;
1271 channels[3].yaw = 66;
1273 channels[4].type = MIXER_TYPE_MOTOR;
1274 channels[4].throttle1 = 100;
1275 channels[4].throttle2 = 0;
1276 channels[4].roll = 0;
1277 channels[4].pitch = -50;
1278 channels[4].yaw = -66;
1280 channels[5].type = MIXER_TYPE_MOTOR;
1281 channels[5].throttle1 = 100;
1282 channels[5].throttle2 = 0;
1283 channels[5].roll = 0;
1284 channels[5].pitch = -50;
1285 channels[5].yaw = 66;
1287 guiSettings.multi.VTOLMotorNW = 1;
1288 guiSettings.multi.VTOLMotorW = 2;
1289 guiSettings.multi.VTOLMotorNE = 3;
1290 guiSettings.multi.VTOLMotorE = 4;
1291 guiSettings.multi.VTOLMotorS = 5;
1292 guiSettings.multi.VTOLMotorSE = 6;
1294 break;
1296 case VehicleConfigurationSource::MULTI_ROTOR_HEXA_H:
1298 frame = SystemSettings::AIRFRAMETYPE_HEXAH;
1299 // HexaH according to new mixer table and pitch-roll-yaw mixing at 100%
1300 // Pitch Roll Yaw
1301 // M1 { 1 , -0.5, -0.5 },
1302 // M2 { 0 , -1 , 1 },
1303 // M3 { -1 , -0.5, -0.5 },
1304 // M4 { -1 , 0.5, 0.5 },
1305 // M5 { 0 , 1 , -1 },
1306 // M6 { 1 , 0.5, 0.5 },
1307 channels[0].type = MIXER_TYPE_MOTOR;
1308 channels[0].throttle1 = 100;
1309 channels[0].throttle2 = 0;
1310 channels[0].roll = -50;
1311 channels[0].pitch = 100;
1312 channels[0].yaw = -50;
1314 channels[1].type = MIXER_TYPE_MOTOR;
1315 channels[1].throttle1 = 100;
1316 channels[1].throttle2 = 0;
1317 channels[1].roll = -100;
1318 channels[1].pitch = 0;
1319 channels[1].yaw = 100;
1321 channels[2].type = MIXER_TYPE_MOTOR;
1322 channels[2].throttle1 = 100;
1323 channels[2].throttle2 = 0;
1324 channels[2].roll = -50;
1325 channels[2].pitch = -100;
1326 channels[2].yaw = -50;
1328 channels[3].type = MIXER_TYPE_MOTOR;
1329 channels[3].throttle1 = 100;
1330 channels[3].throttle2 = 0;
1331 channels[3].roll = 50;
1332 channels[3].pitch = -100;
1333 channels[3].yaw = 50;
1335 channels[4].type = MIXER_TYPE_MOTOR;
1336 channels[4].throttle1 = 100;
1337 channels[4].throttle2 = 0;
1338 channels[4].roll = 100;
1339 channels[4].pitch = 0;
1340 channels[4].yaw = -100;
1342 channels[5].type = MIXER_TYPE_MOTOR;
1343 channels[5].throttle1 = 100;
1344 channels[5].throttle2 = 0;
1345 channels[5].roll = 50;
1346 channels[5].pitch = 100;
1347 channels[5].yaw = 50;
1349 guiSettings.multi.VTOLMotorNE = 1;
1350 guiSettings.multi.VTOLMotorE = 2;
1351 guiSettings.multi.VTOLMotorSE = 3;
1352 guiSettings.multi.VTOLMotorSW = 4;
1353 guiSettings.multi.VTOLMotorW = 5;
1354 guiSettings.multi.VTOLMotorNW = 6;
1356 break;
1358 case VehicleConfigurationSource::MULTI_ROTOR_HEXA_X:
1360 frame = SystemSettings::AIRFRAMETYPE_HEXAX;
1361 // HexaX according to new mixer table and pitch-roll-yaw mixing at 100%
1362 // Pitch Roll Yaw
1363 // M1 { 1, -0.5, -1 },
1364 // M2 { 0, -1 , 1 },
1365 // M3 { -1, -0.5, -1 },
1366 // M4 { -1, 0.5, 1 },
1367 // M5 { 0, 1 , -1 },
1368 // M6 { 1, 0.5, 1 },
1369 channels[0].type = MIXER_TYPE_MOTOR;
1370 channels[0].throttle1 = 100;
1371 channels[0].throttle2 = 0;
1372 channels[0].roll = -50;
1373 channels[0].pitch = 100;
1374 channels[0].yaw = -100;
1376 channels[1].type = MIXER_TYPE_MOTOR;
1377 channels[1].throttle1 = 100;
1378 channels[1].throttle2 = 0;
1379 channels[1].roll = -100;
1380 channels[1].pitch = 0;
1381 channels[1].yaw = 100;
1383 channels[2].type = MIXER_TYPE_MOTOR;
1384 channels[2].throttle1 = 100;
1385 channels[2].throttle2 = 0;
1386 channels[2].roll = -50;
1387 channels[2].pitch = -100;
1388 channels[2].yaw = -100;
1390 channels[3].type = MIXER_TYPE_MOTOR;
1391 channels[3].throttle1 = 100;
1392 channels[3].throttle2 = 0;
1393 channels[3].roll = 50;
1394 channels[3].pitch = -100;
1395 channels[3].yaw = 100;
1397 channels[4].type = MIXER_TYPE_MOTOR;
1398 channels[4].throttle1 = 100;
1399 channels[4].throttle2 = 0;
1400 channels[4].roll = 100;
1401 channels[4].pitch = 0;
1402 channels[4].yaw = -100;
1404 channels[5].type = MIXER_TYPE_MOTOR;
1405 channels[5].throttle1 = 100;
1406 channels[5].throttle2 = 0;
1407 channels[5].roll = 50;
1408 channels[5].pitch = 100;
1409 channels[5].yaw = 100;
1411 guiSettings.multi.VTOLMotorNE = 1;
1412 guiSettings.multi.VTOLMotorE = 2;
1413 guiSettings.multi.VTOLMotorSE = 3;
1414 guiSettings.multi.VTOLMotorSW = 4;
1415 guiSettings.multi.VTOLMotorW = 5;
1416 guiSettings.multi.VTOLMotorNW = 6;
1418 break;
1420 default:
1421 break;
1423 applyMixerConfiguration(channels);
1424 applyMultiGUISettings(frame, guiSettings);
1427 void VehicleConfigurationHelper::setupOctoCopter()
1429 mixerChannelSettings channels[ActuatorSettings::CHANNELADDR_NUMELEM];
1430 GUIConfigDataUnion guiSettings = getGUIConfigData();
1431 SystemSettings::AirframeTypeOptions frame = SystemSettings::AIRFRAMETYPE_OCTO;
1433 switch (m_configSource->getVehicleSubType()) {
1434 case VehicleConfigurationSource::MULTI_ROTOR_OCTO:
1436 frame = SystemSettings::AIRFRAMETYPE_OCTO;
1437 // OctoP according to new mixer table and pitch-roll-yaw mixing at 100%
1438 // Pitch Roll Yaw
1439 // M1{ 1 , 0 , -1 },
1440 // M2{ 0.71,-0.71, 1 },
1441 // M3{ 0 ,-1 , -1 },
1442 // M4{ -0.71,-0.71, 1 },
1443 // M5{ -1 , 0 , -1 },
1444 // M6{ -0.71, 0.71, 1 },
1445 // M7{ 0 , 1 , -1 },
1446 // M8{ 0.71, 0.71, 1 }
1447 channels[0].type = MIXER_TYPE_MOTOR;
1448 channels[0].throttle1 = 100;
1449 channels[0].throttle2 = 0;
1450 channels[0].roll = 0;
1451 channels[0].pitch = 100;
1452 channels[0].yaw = -100;
1454 channels[1].type = MIXER_TYPE_MOTOR;
1455 channels[1].throttle1 = 100;
1456 channels[1].throttle2 = 0;
1457 channels[1].roll = -71;
1458 channels[1].pitch = 71;
1459 channels[1].yaw = 100;
1461 channels[2].type = MIXER_TYPE_MOTOR;
1462 channels[2].throttle1 = 100;
1463 channels[2].throttle2 = 0;
1464 channels[2].roll = -71;
1465 channels[2].pitch = 0;
1466 channels[2].yaw = -100;
1468 channels[3].type = MIXER_TYPE_MOTOR;
1469 channels[3].throttle1 = 100;
1470 channels[3].throttle2 = 0;
1471 channels[3].roll = -71;
1472 channels[3].pitch = -71;
1473 channels[3].yaw = 100;
1475 channels[4].type = MIXER_TYPE_MOTOR;
1476 channels[4].throttle1 = 100;
1477 channels[4].throttle2 = 0;
1478 channels[4].roll = 0;
1479 channels[4].pitch = -100;
1480 channels[4].yaw = -100;
1482 channels[5].type = MIXER_TYPE_MOTOR;
1483 channels[5].throttle1 = 100;
1484 channels[5].throttle2 = 0;
1485 channels[5].roll = 71;
1486 channels[5].pitch = -71;
1487 channels[5].yaw = 100;
1489 channels[6].type = MIXER_TYPE_MOTOR;
1490 channels[6].throttle1 = 100;
1491 channels[6].throttle2 = 0;
1492 channels[6].roll = 100;
1493 channels[6].pitch = 0;
1494 channels[6].yaw = -100;
1496 channels[7].type = MIXER_TYPE_MOTOR;
1497 channels[7].throttle1 = 100;
1498 channels[7].throttle2 = 0;
1499 channels[7].roll = 71;
1500 channels[7].pitch = 71;
1501 channels[7].yaw = 100;
1503 guiSettings.multi.VTOLMotorN = 1;
1504 guiSettings.multi.VTOLMotorNE = 2;
1505 guiSettings.multi.VTOLMotorE = 3;
1506 guiSettings.multi.VTOLMotorSE = 4;
1507 guiSettings.multi.VTOLMotorS = 5;
1508 guiSettings.multi.VTOLMotorSW = 6;
1509 guiSettings.multi.VTOLMotorW = 7;
1510 guiSettings.multi.VTOLMotorNW = 8;
1512 break;
1514 case VehicleConfigurationSource::MULTI_ROTOR_OCTO_X:
1516 frame = SystemSettings::AIRFRAMETYPE_OCTOX;
1517 // OctoX according to new mixer table and pitch-roll-yaw mixing at 100%
1518 // Pitch Roll Yaw
1519 // M1{ 1 ,-0.41, -1 },
1520 // M2{ 0.41, -1 , 1 },
1521 // M3{ -0.41, -1 , -1 },
1522 // M4{ -1 ,-0.41, 1 },
1523 // M5{ -1 , 0.41, -1 },
1524 // M6{ -0.41, 1 , 1 },
1525 // M7{ 0.41, 1 , -1 },
1526 // M8{ 1 , 0.41, 1 }
1527 channels[0].type = MIXER_TYPE_MOTOR;
1528 channels[0].throttle1 = 100;
1529 channels[0].throttle2 = 0;
1530 channels[0].roll = -41;
1531 channels[0].pitch = 100;
1532 channels[0].yaw = -100;
1534 channels[1].type = MIXER_TYPE_MOTOR;
1535 channels[1].throttle1 = 100;
1536 channels[1].throttle2 = 0;
1537 channels[1].roll = -100;
1538 channels[1].pitch = 41;
1539 channels[1].yaw = 100;
1541 channels[2].type = MIXER_TYPE_MOTOR;
1542 channels[2].throttle1 = 100;
1543 channels[2].throttle2 = 0;
1544 channels[2].roll = -100;
1545 channels[2].pitch = -41;
1546 channels[2].yaw = -100;
1548 channels[3].type = MIXER_TYPE_MOTOR;
1549 channels[3].throttle1 = 100;
1550 channels[3].throttle2 = 0;
1551 channels[3].roll = -41;
1552 channels[3].pitch = -100;
1553 channels[3].yaw = 100;
1555 channels[4].type = MIXER_TYPE_MOTOR;
1556 channels[4].throttle1 = 100;
1557 channels[4].throttle2 = 0;
1558 channels[4].roll = 41;
1559 channels[4].pitch = -100;
1560 channels[4].yaw = -100;
1562 channels[5].type = MIXER_TYPE_MOTOR;
1563 channels[5].throttle1 = 100;
1564 channels[5].throttle2 = 0;
1565 channels[5].roll = 100;
1566 channels[5].pitch = -41;
1567 channels[5].yaw = 100;
1569 channels[6].type = MIXER_TYPE_MOTOR;
1570 channels[6].throttle1 = 100;
1571 channels[6].throttle2 = 0;
1572 channels[6].roll = 100;
1573 channels[6].pitch = 41;
1574 channels[6].yaw = -100;
1576 channels[7].type = MIXER_TYPE_MOTOR;
1577 channels[7].throttle1 = 100;
1578 channels[7].throttle2 = 0;
1579 channels[7].roll = 41;
1580 channels[7].pitch = 100;
1581 channels[7].yaw = 100;
1583 guiSettings.multi.VTOLMotorNNE = 1;
1584 guiSettings.multi.VTOLMotorENE = 2;
1585 guiSettings.multi.VTOLMotorESE = 3;
1586 guiSettings.multi.VTOLMotorSSE = 4;
1587 guiSettings.multi.VTOLMotorSSW = 5;
1588 guiSettings.multi.VTOLMotorWSW = 6;
1589 guiSettings.multi.VTOLMotorWNW = 7;
1590 guiSettings.multi.VTOLMotorNNW = 8;
1592 break;
1594 case VehicleConfigurationSource::MULTI_ROTOR_OCTO_COAX_X:
1596 frame = SystemSettings::AIRFRAMETYPE_OCTOCOAXX;
1598 channels[0].type = MIXER_TYPE_MOTOR;
1599 channels[0].throttle1 = 100;
1600 channels[0].throttle2 = 0;
1601 channels[0].roll = 50;
1602 channels[0].pitch = 50;
1603 channels[0].yaw = -50;
1605 channels[1].type = MIXER_TYPE_MOTOR;
1606 channels[1].throttle1 = 100;
1607 channels[1].throttle2 = 0;
1608 channels[1].roll = 50;
1609 channels[1].pitch = 50;
1610 channels[1].yaw = 50;
1612 channels[2].type = MIXER_TYPE_MOTOR;
1613 channels[2].throttle1 = 100;
1614 channels[2].throttle2 = 0;
1615 channels[2].roll = -50;
1616 channels[2].pitch = 50;
1617 channels[2].yaw = -50;
1619 channels[3].type = MIXER_TYPE_MOTOR;
1620 channels[3].throttle1 = 100;
1621 channels[3].throttle2 = 0;
1622 channels[3].roll = -50;
1623 channels[3].pitch = 50;
1624 channels[3].yaw = 50;
1626 channels[4].type = MIXER_TYPE_MOTOR;
1627 channels[4].throttle1 = 100;
1628 channels[4].throttle2 = 0;
1629 channels[4].roll = -50;
1630 channels[4].pitch = -50;
1631 channels[4].yaw = -50;
1633 channels[5].type = MIXER_TYPE_MOTOR;
1634 channels[5].throttle1 = 100;
1635 channels[5].throttle2 = 0;
1636 channels[5].roll = -50;
1637 channels[5].pitch = -50;
1638 channels[5].yaw = 50;
1640 channels[6].type = MIXER_TYPE_MOTOR;
1641 channels[6].throttle1 = 100;
1642 channels[6].throttle2 = 0;
1643 channels[6].roll = 50;
1644 channels[6].pitch = -50;
1645 channels[6].yaw = -50;
1647 channels[7].type = MIXER_TYPE_MOTOR;
1648 channels[7].throttle1 = 100;
1649 channels[7].throttle2 = 0;
1650 channels[7].roll = 50;
1651 channels[7].pitch = -50;
1652 channels[7].yaw = 50;
1654 guiSettings.multi.VTOLMotorNW = 1;
1655 guiSettings.multi.VTOLMotorN = 2;
1656 guiSettings.multi.VTOLMotorNE = 3;
1657 guiSettings.multi.VTOLMotorE = 4;
1658 guiSettings.multi.VTOLMotorSE = 5;
1659 guiSettings.multi.VTOLMotorS = 6;
1660 guiSettings.multi.VTOLMotorSW = 7;
1661 guiSettings.multi.VTOLMotorW = 8;
1663 break;
1665 case VehicleConfigurationSource::MULTI_ROTOR_OCTO_COAX_PLUS:
1667 frame = SystemSettings::AIRFRAMETYPE_OCTOCOAXP;
1669 channels[0].type = MIXER_TYPE_MOTOR;
1670 channels[0].throttle1 = 100;
1671 channels[0].throttle2 = 0;
1672 channels[0].roll = 0;
1673 channels[0].pitch = 100;
1674 channels[0].yaw = -50;
1676 channels[1].type = MIXER_TYPE_MOTOR;
1677 channels[1].throttle1 = 100;
1678 channels[1].throttle2 = 0;
1679 channels[1].roll = 0;
1680 channels[1].pitch = 100;
1681 channels[1].yaw = 50;
1683 channels[2].type = MIXER_TYPE_MOTOR;
1684 channels[2].throttle1 = 100;
1685 channels[2].throttle2 = 0;
1686 channels[2].roll = -100;
1687 channels[2].pitch = 0;
1688 channels[2].yaw = -50;
1690 channels[3].type = MIXER_TYPE_MOTOR;
1691 channels[3].throttle1 = 100;
1692 channels[3].throttle2 = 0;
1693 channels[3].roll = -100;
1694 channels[3].pitch = 0;
1695 channels[3].yaw = 50;
1697 channels[4].type = MIXER_TYPE_MOTOR;
1698 channels[4].throttle1 = 100;
1699 channels[4].throttle2 = 0;
1700 channels[4].roll = 0;
1701 channels[4].pitch = -100;
1702 channels[4].yaw = -50;
1704 channels[5].type = MIXER_TYPE_MOTOR;
1705 channels[5].throttle1 = 100;
1706 channels[5].throttle2 = 0;
1707 channels[5].roll = 0;
1708 channels[5].pitch = -100;
1709 channels[5].yaw = 50;
1711 channels[6].type = MIXER_TYPE_MOTOR;
1712 channels[6].throttle1 = 100;
1713 channels[6].throttle2 = 0;
1714 channels[6].roll = 100;
1715 channels[6].pitch = 0;
1716 channels[6].yaw = -50;
1718 channels[7].type = MIXER_TYPE_MOTOR;
1719 channels[7].throttle1 = 100;
1720 channels[7].throttle2 = 0;
1721 channels[7].roll = 100;
1722 channels[7].pitch = 0;
1723 channels[7].yaw = 50;
1725 guiSettings.multi.VTOLMotorN = 1;
1726 guiSettings.multi.VTOLMotorNE = 2;
1727 guiSettings.multi.VTOLMotorE = 3;
1728 guiSettings.multi.VTOLMotorSE = 4;
1729 guiSettings.multi.VTOLMotorS = 5;
1730 guiSettings.multi.VTOLMotorSW = 6;
1731 guiSettings.multi.VTOLMotorW = 7;
1732 guiSettings.multi.VTOLMotorNW = 8;
1734 break;
1736 case VehicleConfigurationSource::MULTI_ROTOR_OCTO_V:
1738 frame = SystemSettings::AIRFRAMETYPE_OCTOV;
1739 channels[0].type = MIXER_TYPE_MOTOR;
1740 channels[0].throttle1 = 100;
1741 channels[0].throttle2 = 0;
1742 channels[0].roll = -25;
1743 channels[0].pitch = 8;
1744 channels[0].yaw = -25;
1746 channels[1].type = MIXER_TYPE_MOTOR;
1747 channels[1].throttle1 = 100;
1748 channels[1].throttle2 = 0;
1749 channels[1].roll = -25;
1750 channels[1].pitch = 25;
1751 channels[1].yaw = 25;
1753 channels[2].type = MIXER_TYPE_MOTOR;
1754 channels[2].throttle1 = 100;
1755 channels[2].throttle2 = 0;
1756 channels[2].roll = -25;
1757 channels[2].pitch = -25;
1758 channels[2].yaw = -25;
1760 channels[3].type = MIXER_TYPE_MOTOR;
1761 channels[3].throttle1 = 100;
1762 channels[3].throttle2 = 0;
1763 channels[3].roll = -25;
1764 channels[3].pitch = -8;
1765 channels[3].yaw = 25;
1767 channels[4].type = MIXER_TYPE_MOTOR;
1768 channels[4].throttle1 = 100;
1769 channels[4].throttle2 = 0;
1770 channels[4].roll = 25;
1771 channels[4].pitch = -8;
1772 channels[4].yaw = -25;
1774 channels[5].type = MIXER_TYPE_MOTOR;
1775 channels[5].throttle1 = 100;
1776 channels[5].throttle2 = 0;
1777 channels[5].roll = 25;
1778 channels[5].pitch = -25;
1779 channels[5].yaw = 25;
1781 channels[6].type = MIXER_TYPE_MOTOR;
1782 channels[6].throttle1 = 100;
1783 channels[6].throttle2 = 0;
1784 channels[6].roll = 25;
1785 channels[6].pitch = 25;
1786 channels[6].yaw = -25;
1788 channels[7].type = MIXER_TYPE_MOTOR;
1789 channels[7].throttle1 = 100;
1790 channels[7].throttle2 = 0;
1791 channels[7].roll = 25;
1792 channels[7].pitch = 8;
1793 channels[7].yaw = 25;
1795 guiSettings.multi.VTOLMotorN = 1;
1796 guiSettings.multi.VTOLMotorNE = 2;
1797 guiSettings.multi.VTOLMotorE = 3;
1798 guiSettings.multi.VTOLMotorSE = 4;
1799 guiSettings.multi.VTOLMotorS = 5;
1800 guiSettings.multi.VTOLMotorSW = 6;
1801 guiSettings.multi.VTOLMotorW = 7;
1802 guiSettings.multi.VTOLMotorNW = 8;
1804 break;
1806 default:
1807 break;
1810 applyMixerConfiguration(channels);
1811 applyMultiGUISettings(frame, guiSettings);
1814 void VehicleConfigurationHelper::setupElevon()
1816 mixerChannelSettings channels[ActuatorSettings::CHANNELADDR_NUMELEM];
1817 GUIConfigDataUnion guiSettings = getGUIConfigData();
1819 // Motor (Chan 3)
1820 channels[2].type = MIXER_TYPE_MOTOR;
1821 channels[2].throttle1 = 100;
1822 channels[2].throttle2 = 0;
1823 channels[2].roll = 0;
1824 channels[2].pitch = 0;
1825 channels[2].yaw = 0;
1827 // Elevon Servo 1 (Chan 1)
1828 channels[0].type = MIXER_TYPE_SERVO;
1829 channels[0].throttle1 = 0;
1830 channels[0].throttle2 = 0;
1831 channels[0].roll = 100;
1832 channels[0].pitch = -100;
1833 channels[0].yaw = 0;
1835 // Elevon Servo 2 (Chan 2)
1836 channels[1].type = MIXER_TYPE_SERVO;
1837 channels[1].throttle1 = 0;
1838 channels[1].throttle2 = 0;
1839 channels[1].roll = 100;
1840 channels[1].pitch = 100;
1841 channels[1].yaw = 0;
1843 guiSettings.fixedwing.FixedWingThrottle = 3;
1844 guiSettings.fixedwing.FixedWingRoll1 = 1;
1845 guiSettings.fixedwing.FixedWingRoll2 = 2;
1847 applyMixerConfiguration(channels);
1848 applyMultiGUISettings(SystemSettings::AIRFRAMETYPE_FIXEDWINGELEVON, guiSettings);
1851 void VehicleConfigurationHelper::setupDualAileron()
1853 // Typical vehicle setup
1854 // 1. Setup mixer data
1855 // 2. Setup GUI data
1856 // 3. Apply changes
1858 mixerChannelSettings channels[ActuatorSettings::CHANNELADDR_NUMELEM];
1859 GUIConfigDataUnion guiSettings = getGUIConfigData();
1861 // Motor (Chan 3)
1862 channels[2].type = MIXER_TYPE_MOTOR;
1863 channels[2].throttle1 = 100;
1864 channels[2].throttle2 = 0;
1865 channels[2].roll = 0;
1866 channels[2].pitch = 0;
1867 channels[2].yaw = 0;
1869 // Aileron Servo 1 (Chan 1)
1870 channels[0].type = MIXER_TYPE_SERVO;
1871 channels[0].throttle1 = 0;
1872 channels[0].throttle2 = 0;
1873 channels[0].roll = 100;
1874 channels[0].pitch = 0;
1875 channels[0].yaw = 0;
1877 // Aileron Servo 2 (Chan 6)
1878 channels[5].type = MIXER_TYPE_SERVO;
1879 channels[5].throttle1 = 0;
1880 channels[5].throttle2 = 0;
1881 channels[5].roll = 100;
1882 channels[5].pitch = 0;
1883 channels[5].yaw = 0;
1885 // Elevator Servo (Chan 2)
1886 channels[1].type = MIXER_TYPE_SERVO;
1887 channels[1].throttle1 = 0;
1888 channels[1].throttle2 = 0;
1889 channels[1].roll = 0;
1890 channels[1].pitch = 100;
1891 channels[1].yaw = 0;
1893 // Rudder Servo (Chan 4)
1894 channels[3].type = MIXER_TYPE_SERVO;
1895 channels[3].throttle1 = 0;
1896 channels[3].throttle2 = 0;
1897 channels[3].roll = 0;
1898 channels[3].pitch = 0;
1899 channels[3].yaw = -100;
1901 guiSettings.fixedwing.FixedWingThrottle = 3;
1902 guiSettings.fixedwing.FixedWingRoll1 = 1;
1903 guiSettings.fixedwing.FixedWingRoll2 = 6;
1904 guiSettings.fixedwing.FixedWingPitch1 = 2;
1905 guiSettings.fixedwing.FixedWingYaw1 = 4;
1907 applyMixerConfiguration(channels);
1908 applyMultiGUISettings(SystemSettings::AIRFRAMETYPE_FIXEDWING, guiSettings);
1911 void VehicleConfigurationHelper::setupAileron()
1913 // Typical vehicle setup
1914 // 1. Setup mixer data
1915 // 2. Setup GUI data
1916 // 3. Apply changes
1918 mixerChannelSettings channels[ActuatorSettings::CHANNELADDR_NUMELEM];
1919 GUIConfigDataUnion guiSettings = getGUIConfigData();
1921 // Motor (Chan 3)
1922 channels[2].type = MIXER_TYPE_MOTOR;
1923 channels[2].throttle1 = 100;
1924 channels[2].throttle2 = 0;
1925 channels[2].roll = 0;
1926 channels[2].pitch = 0;
1927 channels[2].yaw = 0;
1929 // Aileron Servo (Chan 1)
1930 channels[0].type = MIXER_TYPE_SERVO;
1931 channels[0].throttle1 = 0;
1932 channels[0].throttle2 = 0;
1933 channels[0].roll = 100;
1934 channels[0].pitch = 0;
1935 channels[0].yaw = 0;
1937 // Elevator Servo (Chan 2)
1938 channels[1].type = MIXER_TYPE_SERVO;
1939 channels[1].throttle1 = 0;
1940 channels[1].throttle2 = 0;
1941 channels[1].roll = 0;
1942 channels[1].pitch = 100;
1943 channels[1].yaw = 0;
1945 // Rudder Servo (Chan 4)
1946 channels[3].type = MIXER_TYPE_SERVO;
1947 channels[3].throttle1 = 0;
1948 channels[3].throttle2 = 0;
1949 channels[3].roll = 0;
1950 channels[3].pitch = 0;
1951 channels[3].yaw = -100;
1953 guiSettings.fixedwing.FixedWingThrottle = 3;
1954 guiSettings.fixedwing.FixedWingRoll1 = 1;
1955 guiSettings.fixedwing.FixedWingPitch1 = 2;
1956 guiSettings.fixedwing.FixedWingYaw1 = 4;
1958 applyMixerConfiguration(channels);
1959 applyMultiGUISettings(SystemSettings::AIRFRAMETYPE_FIXEDWING, guiSettings);
1962 void VehicleConfigurationHelper::setupVtail()
1964 // Typical vehicle setup
1965 // 1. Setup mixer data
1966 // 2. Setup GUI data
1967 // 3. Apply changes
1969 mixerChannelSettings channels[ActuatorSettings::CHANNELADDR_NUMELEM];
1970 GUIConfigDataUnion guiSettings = getGUIConfigData();
1972 // Motor (Chan 3)
1973 channels[2].type = MIXER_TYPE_MOTOR;
1974 channels[2].throttle1 = 100;
1975 channels[2].throttle2 = 0;
1976 channels[2].roll = 0;
1977 channels[2].pitch = 0;
1978 channels[2].yaw = 0;
1980 // Aileron Servo (Chan 1)
1981 channels[0].type = MIXER_TYPE_SERVO;
1982 channels[0].throttle1 = 0;
1983 channels[0].throttle2 = 0;
1984 channels[0].roll = 100;
1985 channels[0].pitch = 0;
1986 channels[0].yaw = 0;
1988 // Aileron Servo 2 (Chan 6)
1989 channels[5].type = MIXER_TYPE_SERVO;
1990 channels[5].throttle1 = 0;
1991 channels[5].throttle2 = 0;
1992 channels[5].roll = 100;
1993 channels[5].pitch = 0;
1994 channels[5].yaw = 0;
1996 // Right Vtail Servo (Chan 2)
1997 channels[1].type = MIXER_TYPE_SERVO;
1998 channels[1].throttle1 = 0;
1999 channels[1].throttle2 = 0;
2000 channels[1].roll = 0;
2001 channels[1].pitch = 100;
2002 channels[1].yaw = -100;
2004 // Left Vtail Servo (Chan 4)
2005 channels[3].type = MIXER_TYPE_SERVO;
2006 channels[3].throttle1 = 0;
2007 channels[3].throttle2 = 0;
2008 channels[3].roll = 0;
2009 channels[3].pitch = -100;
2010 channels[3].yaw = -100;
2012 guiSettings.fixedwing.FixedWingThrottle = 3;
2013 guiSettings.fixedwing.FixedWingRoll1 = 1;
2014 guiSettings.fixedwing.FixedWingRoll2 = 6;
2015 guiSettings.fixedwing.FixedWingPitch1 = 4; // Vtail left (top view, nose up)
2016 guiSettings.fixedwing.FixedWingPitch2 = 2; // Vtail right
2018 applyMixerConfiguration(channels);
2019 applyMultiGUISettings(SystemSettings::AIRFRAMETYPE_FIXEDWINGVTAIL, guiSettings);
2024 * Ground vehicles
2028 void VehicleConfigurationHelper::setupCar()
2030 // Typical vehicle setup
2031 // 1. Setup mixer data
2032 // 2. Setup GUI data
2033 // 3. Apply changes
2035 mixerChannelSettings channels[ActuatorSettings::CHANNELADDR_NUMELEM];
2036 GUIConfigDataUnion guiSettings = getGUIConfigData();
2038 // Steering Servo (Chan 1)
2039 channels[0].type = MIXER_TYPE_SERVO;
2040 channels[0].throttle1 = 0;
2041 channels[0].throttle2 = 0;
2042 channels[0].roll = 0;
2043 channels[0].pitch = 0;
2044 channels[0].yaw = 100;
2046 // Motor (Chan 2)
2047 channels[1].type = MIXER_TYPE_REVERSABLEMOTOR;
2048 channels[1].throttle1 = 0;
2049 channels[1].throttle2 = 100;
2050 channels[1].roll = 0;
2051 channels[1].pitch = 0;
2052 channels[1].yaw = 0;
2054 guiSettings.ground.GroundVehicleSteering1 = 1;
2055 guiSettings.ground.GroundVehicleThrottle2 = 2;
2057 applyMixerConfiguration(channels);
2058 applyMultiGUISettings(SystemSettings::AIRFRAMETYPE_GROUNDVEHICLECAR, guiSettings);
2061 void VehicleConfigurationHelper::setupTank()
2063 // Typical vehicle setup
2064 // 1. Setup mixer data
2065 // 2. Setup GUI data
2066 // 3. Apply changes
2068 mixerChannelSettings channels[ActuatorSettings::CHANNELADDR_NUMELEM];
2069 GUIConfigDataUnion guiSettings = getGUIConfigData();
2071 // Left Motor (Chan 1)
2072 channels[0].type = MIXER_TYPE_REVERSABLEMOTOR;
2073 channels[0].throttle1 = 0;
2074 channels[0].throttle2 = 100;
2075 channels[0].roll = 0;
2076 channels[0].pitch = 0;
2077 channels[0].yaw = 100;
2079 // Right Motor (Chan 2)
2080 channels[1].type = MIXER_TYPE_REVERSABLEMOTOR;
2081 channels[1].throttle1 = 0;
2082 channels[1].throttle2 = 100;
2083 channels[1].roll = 0;
2084 channels[1].pitch = 0;
2085 channels[1].yaw = -100;
2087 guiSettings.ground.GroundVehicleThrottle1 = 1;
2088 guiSettings.ground.GroundVehicleThrottle2 = 2;
2090 applyMixerConfiguration(channels);
2091 applyMultiGUISettings(SystemSettings::AIRFRAMETYPE_GROUNDVEHICLEDIFFERENTIAL, guiSettings);
2094 void VehicleConfigurationHelper::setupMotorcycle()
2096 // Typical vehicle setup
2097 // 1. Setup mixer data
2098 // 2. Setup GUI data
2099 // 3. Apply changes
2101 mixerChannelSettings channels[ActuatorSettings::CHANNELADDR_NUMELEM];
2102 GUIConfigDataUnion guiSettings = getGUIConfigData();
2104 // Steering Servo (Chan 1)
2105 channels[0].type = MIXER_TYPE_SERVO;
2106 channels[0].throttle1 = 0;
2107 channels[0].throttle2 = 0;
2108 channels[0].roll = 0;
2109 channels[0].pitch = 0;
2110 channels[0].yaw = 100;
2112 // Motor (Chan 2) : Curve1, no reverse
2113 channels[1].type = MIXER_TYPE_MOTOR;
2114 channels[1].throttle1 = 100;
2115 channels[1].throttle2 = 0;
2116 channels[1].roll = 0;
2117 channels[1].pitch = 0;
2118 channels[1].yaw = 0;
2120 guiSettings.ground.GroundVehicleSteering1 = 1;
2121 guiSettings.ground.GroundVehicleThrottle2 = 2;
2123 applyMixerConfiguration(channels);
2124 applyMultiGUISettings(SystemSettings::AIRFRAMETYPE_GROUNDVEHICLEMOTORCYCLE, guiSettings);