2 ******************************************************************************
4 * @file configcamerastabilizationwidget.cpp
5 * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
6 * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011-2012.
7 * @addtogroup GCSPlugins GCS Plugins
9 * @addtogroup ConfigPlugin Config Plugin
11 * @brief The Configuration Gadget used to update settings in the firmware
12 *****************************************************************************/
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 3 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 * IMPORTANT: This module is meant to be a reference implementation which
31 * demostrates the use of ConfigTaskWidget API for widgets which are not directly
32 * related to UAVObjects. It contains a lot of comments including some commented
33 * out code samples. Please DO NOT COPY/PASTE them into any other module based
37 #include "configcamerastabilizationwidget.h"
39 #include "ui_camerastabilization.h"
41 #include "camerastabsettings.h"
42 #include "hwsettings.h"
43 #include "mixersettings.h"
44 #include "actuatorcommand.h"
46 ConfigCameraStabilizationWidget::ConfigCameraStabilizationWidget(QWidget
*parent
) : ConfigTaskWidget(parent
)
48 ui
= new Ui_CameraStabilizationWidget();
51 // must be done before auto binding !
52 setWikiURL("Camera+Stabilisation+Configuration");
56 disableMouseWheelEvents();
58 // These widgets don't have direct relation to UAVObjects
59 // and need special processing
60 QComboBox
*outputs
[] = { ui
->rollChannel
, ui
->pitchChannel
, ui
->yawChannel
, };
61 const int NUM_OUTPUTS
= sizeof(outputs
) / sizeof(outputs
[0]);
63 // Populate widgets with channel numbers
64 for (int i
= 0; i
< NUM_OUTPUTS
; i
++) {
66 outputs
[i
]->addItem("None");
67 for (quint32 j
= 0; j
< ActuatorCommand::CHANNEL_NUMELEM
; j
++) {
68 outputs
[i
]->addItem(QString("Channel %1").arg(j
+ 1));
72 // Add some widgets to track their UI dirty state and handle smartsave
73 addWidget(ui
->enableCameraStabilization
);
74 addWidget(ui
->rollChannel
);
75 addWidget(ui
->pitchChannel
);
76 addWidget(ui
->yawChannel
);
78 // Add some UAVObjects to monitor their changes in addition to autoloaded ones.
79 // Note also that we want to reload some UAVObjects by "Reload" button and have
80 // to pass corresponding reload group numbers (defined also in objrelation property)
81 // to the montitor. We don't reload HwSettings (module enable state) but reload
83 QList
<int> reloadGroups
;
85 addUAVObject("HwSettings");
86 addUAVObject("MixerSettings", &reloadGroups
);
88 // To set special widgets to defaults when requested
89 connect(this, SIGNAL(defaultRequested(int)), this, SLOT(defaultRequestedSlot(int)));
92 ConfigCameraStabilizationWidget::~ConfigCameraStabilizationWidget()
98 * This overridden function refreshes widgets which have no direct relation
99 * to any of UAVObjects. It saves their dirty state first because update comes
100 * from UAVObjects, and then restores it.
102 void ConfigCameraStabilizationWidget::refreshWidgetsValuesImpl(UAVObject
*obj
)
106 // Set module enable checkbox from OptionalModules UAVObject item.
107 // It needs special processing because ConfigTaskWidget uses TRUE/FALSE
108 // for QCheckBox, but OptionalModules uses Enabled/Disabled enum values.
109 HwSettings
*hwSettings
= HwSettings::GetInstance(getObjectManager());
111 ui
->enableCameraStabilization
->setChecked(
112 hwSettings
->getOptionalModules(HwSettings::OPTIONALMODULES_CAMERASTAB
) == HwSettings::OPTIONALMODULES_ENABLED
);
114 // Load mixer outputs which are mapped to camera controls
115 MixerSettings
*mixerSettings
= MixerSettings::GetInstance(getObjectManager());
116 MixerSettings::DataFields mixerSettingsData
= mixerSettings
->getData();
118 // TODO: Need to reformat object so types are an
119 // array themselves. This gets really awkward
120 quint8
*mixerTypes
[] = {
121 &mixerSettingsData
.Mixer1Type
,
122 &mixerSettingsData
.Mixer2Type
,
123 &mixerSettingsData
.Mixer3Type
,
124 &mixerSettingsData
.Mixer4Type
,
125 &mixerSettingsData
.Mixer5Type
,
126 &mixerSettingsData
.Mixer6Type
,
127 &mixerSettingsData
.Mixer7Type
,
128 &mixerSettingsData
.Mixer8Type
,
129 &mixerSettingsData
.Mixer9Type
,
130 &mixerSettingsData
.Mixer10Type
,
132 const int NUM_MIXERS
= sizeof(mixerTypes
) / sizeof(mixerTypes
[0]);
134 QComboBox
*outputs
[] = {
139 const int NUM_OUTPUTS
= sizeof(outputs
) / sizeof(outputs
[0]);
141 for (int i
= 0; i
< NUM_OUTPUTS
; i
++) {
142 // Default to none if not found.
143 // Then search for any mixer channels set to this
144 outputs
[i
]->setCurrentIndex(0);
145 for (int j
= 0; j
< NUM_MIXERS
; j
++) {
146 if (*mixerTypes
[j
] == (MixerSettings::MIXER1TYPE_CAMERAROLLORSERVO1
+ i
) &&
147 outputs
[i
]->currentIndex() != (j
+ 1)) {
148 outputs
[i
]->setCurrentIndex(j
+ 1);
155 * This overridden function updates UAVObjects which have no direct relation
158 void ConfigCameraStabilizationWidget::updateObjectsFromWidgetsImpl()
160 // Save state of the module enable checkbox first.
161 // Do not use setData() member on whole object, if possible, since it triggers unnecessary UAVObect update.
162 quint8 enableModule
= ui
->enableCameraStabilization
->isChecked() ?
163 HwSettings::OPTIONALMODULES_ENABLED
: HwSettings::OPTIONALMODULES_DISABLED
;
164 HwSettings
*hwSettings
= HwSettings::GetInstance(getObjectManager());
166 hwSettings
->setOptionalModules(HwSettings::OPTIONALMODULES_CAMERASTAB
, enableModule
);
168 // Update mixer channels which were mapped to camera outputs in case they are
169 // not used for other function yet
170 MixerSettings
*mixerSettings
= MixerSettings::GetInstance(getObjectManager());
171 MixerSettings::DataFields mixerSettingsData
= mixerSettings
->getData();
173 // TODO: Need to reformat object so types are an
174 // array themselves. This gets really awkward
175 quint8
*mixerTypes
[] = {
176 &mixerSettingsData
.Mixer1Type
,
177 &mixerSettingsData
.Mixer2Type
,
178 &mixerSettingsData
.Mixer3Type
,
179 &mixerSettingsData
.Mixer4Type
,
180 &mixerSettingsData
.Mixer5Type
,
181 &mixerSettingsData
.Mixer6Type
,
182 &mixerSettingsData
.Mixer7Type
,
183 &mixerSettingsData
.Mixer8Type
,
184 &mixerSettingsData
.Mixer9Type
,
185 &mixerSettingsData
.Mixer10Type
,
187 const int NUM_MIXERS
= sizeof(mixerTypes
) / sizeof(mixerTypes
[0]);
189 QComboBox
*outputs
[] = {
194 const int NUM_OUTPUTS
= sizeof(outputs
) / sizeof(outputs
[0]);
196 ui
->message
->setText("");
199 widgetUpdated
= false;
201 for (int i
= 0; i
< NUM_OUTPUTS
; i
++) {
202 // Channel 1 is second entry, so becomes zero
203 int mixerNum
= outputs
[i
]->currentIndex() - 1;
205 if ((mixerNum
>= 0) && // Short circuit in case of none
206 (*mixerTypes
[mixerNum
] != MixerSettings::MIXER1TYPE_DISABLED
) &&
207 (*mixerTypes
[mixerNum
] != MixerSettings::MIXER1TYPE_CAMERAROLLORSERVO1
+ i
)) {
208 // If the mixer channel already mapped to something, it should not be
209 // used for camera output, we reset it to none
210 outputs
[i
]->setCurrentIndex(0);
211 ui
->message
->setText("One of the channels is already assigned, reverted to none");
213 // Loop again or we may have inconsistent widget and UAVObject
214 widgetUpdated
= true;
216 // Make sure no other channels have this output set
217 for (int j
= 0; j
< NUM_MIXERS
; j
++) {
218 if (*mixerTypes
[j
] == (MixerSettings::MIXER1TYPE_CAMERAROLLORSERVO1
+ i
)) {
219 *mixerTypes
[j
] = MixerSettings::MIXER1TYPE_DISABLED
;
223 // If this channel is assigned to one of the outputs that is not disabled
225 if ((mixerNum
>= 0) && (mixerNum
< NUM_MIXERS
)) {
226 *mixerTypes
[mixerNum
] = MixerSettings::MIXER1TYPE_CAMERAROLLORSERVO1
+ i
;
230 } while (widgetUpdated
);
232 // FIXME: Should not use setData() to prevent double updates.
233 // It should be refactored after the reformatting of MixerSettings UAVObject.
234 mixerSettings
->setData(mixerSettingsData
);
238 * This slot function is called when "Default" button is clicked.
239 * All special widgets which belong to the group passed should be set here.
241 void ConfigCameraStabilizationWidget::defaultRequestedSlot(int group
)
245 // For outputs we set them all to none, so don't use any UAVObject to get defaults
246 QComboBox
*outputs
[] = {
251 const int NUM_OUTPUTS
= sizeof(outputs
) / sizeof(outputs
[0]);
253 for (int i
= 0; i
< NUM_OUTPUTS
; i
++) {
254 outputs
[i
]->setCurrentIndex(0);