LP-311 Remove basic/advanced stabilization tab auto-switch (autotune/txpid lock issues)
[librepilot.git] / ground / gcs / src / plugins / config / configcamerastabilizationwidget.cpp
blobc6ace5728f995a255f9b8a24ee107f6a22b0636b
1 /**
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
8 * @{
9 * @addtogroup ConfigPlugin Config Plugin
10 * @{
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
22 * for more details.
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
34 * on this.
37 #include "configcamerastabilizationwidget.h"
39 #include "ui_camerastabilization.h"
41 #include <extensionsystem/pluginmanager.h>
42 #include <coreplugin/generalsettings.h>
44 #include "camerastabsettings.h"
45 #include "hwsettings.h"
46 #include "mixersettings.h"
47 #include "actuatorcommand.h"
49 ConfigCameraStabilizationWidget::ConfigCameraStabilizationWidget(QWidget *parent) : ConfigTaskWidget(parent)
51 ui = new Ui_CameraStabilizationWidget();
52 ui->setupUi(this);
54 addApplySaveButtons(ui->camerastabilizationSaveRAM, ui->camerastabilizationSaveSD);
56 ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
57 Core::Internal::GeneralSettings *settings = pm->getObject<Core::Internal::GeneralSettings>();
58 if (!settings->useExpertMode()) {
59 ui->camerastabilizationSaveRAM->setVisible(false);
63 // These widgets don't have direct relation to UAVObjects
64 // and need special processing
65 QComboBox *outputs[] = {
66 ui->rollChannel,
67 ui->pitchChannel,
68 ui->yawChannel,
70 const int NUM_OUTPUTS = sizeof(outputs) / sizeof(outputs[0]);
72 // Populate widgets with channel numbers
73 for (int i = 0; i < NUM_OUTPUTS; i++) {
74 outputs[i]->clear();
75 outputs[i]->addItem("None");
76 for (quint32 j = 0; j < ActuatorCommand::CHANNEL_NUMELEM; j++) {
77 outputs[i]->addItem(QString("Channel %1").arg(j + 1));
81 setWikiURL("Camera+Stabilisation+Configuration");
82 // Load UAVObjects to widget relations from UI file
83 // using objrelation dynamic property
84 autoLoadWidgets();
86 // Add some widgets to track their UI dirty state and handle smartsave
87 addWidget(ui->enableCameraStabilization);
88 addWidget(ui->rollChannel);
89 addWidget(ui->pitchChannel);
90 addWidget(ui->yawChannel);
92 // Add some UAVObjects to monitor their changes in addition to autoloaded ones.
93 // Note also that we want to reload some UAVObjects by "Reload" button and have
94 // to pass corresponding reload group numbers (defined also in objrelation property)
95 // to the montitor. We don't reload HwSettings (module enable state) but reload
96 // output channels.
97 QList<int> reloadGroups;
98 reloadGroups << 1;
99 addUAVObject("HwSettings");
100 addUAVObject("MixerSettings", &reloadGroups);
102 // To set special widgets to defaults when requested
103 connect(this, SIGNAL(defaultRequested(int)), this, SLOT(defaultRequestedSlot(int)));
105 disableMouseWheelEvents();
106 updateEnableControls();
109 ConfigCameraStabilizationWidget::~ConfigCameraStabilizationWidget()
111 // Do nothing
115 * This overridden function refreshes widgets which have no direct relation
116 * to any of UAVObjects. It saves their dirty state first because update comes
117 * from UAVObjects, and then restores it. Aftewards it calls base class
118 * function to take care of other widgets which were dynamically added.
120 void ConfigCameraStabilizationWidget::refreshWidgetsValues(UAVObject *obj)
122 bool dirty = isDirty();
124 // Set module enable checkbox from OptionalModules UAVObject item.
125 // It needs special processing because ConfigTaskWidget uses TRUE/FALSE
126 // for QCheckBox, but OptionalModules uses Enabled/Disabled enum values.
127 HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
128 HwSettings::DataFields hwSettingsData = hwSettings->getData();
130 ui->enableCameraStabilization->setChecked(
131 hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_CAMERASTAB] == HwSettings::OPTIONALMODULES_ENABLED);
133 // Load mixer outputs which are mapped to camera controls
134 MixerSettings *mixerSettings = MixerSettings::GetInstance(getObjectManager());
135 MixerSettings::DataFields mixerSettingsData = mixerSettings->getData();
137 // TODO: Need to reformat object so types are an
138 // array themselves. This gets really awkward
139 quint8 *mixerTypes[] = {
140 &mixerSettingsData.Mixer1Type,
141 &mixerSettingsData.Mixer2Type,
142 &mixerSettingsData.Mixer3Type,
143 &mixerSettingsData.Mixer4Type,
144 &mixerSettingsData.Mixer5Type,
145 &mixerSettingsData.Mixer6Type,
146 &mixerSettingsData.Mixer7Type,
147 &mixerSettingsData.Mixer8Type,
148 &mixerSettingsData.Mixer9Type,
149 &mixerSettingsData.Mixer10Type,
151 const int NUM_MIXERS = sizeof(mixerTypes) / sizeof(mixerTypes[0]);
153 QComboBox *outputs[] = {
154 ui->rollChannel,
155 ui->pitchChannel,
156 ui->yawChannel
158 const int NUM_OUTPUTS = sizeof(outputs) / sizeof(outputs[0]);
160 for (int i = 0; i < NUM_OUTPUTS; i++) {
161 // Default to none if not found.
162 // Then search for any mixer channels set to this
163 outputs[i]->setCurrentIndex(0);
164 for (int j = 0; j < NUM_MIXERS; j++) {
165 if (*mixerTypes[j] == (MixerSettings::MIXER1TYPE_CAMERAROLLORSERVO1 + i) &&
166 outputs[i]->currentIndex() != (j + 1)) {
167 outputs[i]->setCurrentIndex(j + 1);
172 setDirty(dirty);
174 ConfigTaskWidget::refreshWidgetsValues(obj);
178 * This overridden function updates UAVObjects which have no direct relation
179 * to any of widgets. Aftewards it calls base class function to take care of
180 * other object to widget relations which were dynamically added.
182 void ConfigCameraStabilizationWidget::updateObjectsFromWidgets()
184 // Save state of the module enable checkbox first.
185 // Do not use setData() member on whole object, if possible, since it triggers
186 // unnessesary UAVObect update.
187 quint8 enableModule = ui->enableCameraStabilization->isChecked() ?
188 HwSettings::OPTIONALMODULES_ENABLED : HwSettings::OPTIONALMODULES_DISABLED;
189 HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
191 hwSettings->setOptionalModules(HwSettings::OPTIONALMODULES_CAMERASTAB, enableModule);
193 // Update mixer channels which were mapped to camera outputs in case they are
194 // not used for other function yet
195 MixerSettings *mixerSettings = MixerSettings::GetInstance(getObjectManager());
196 MixerSettings::DataFields mixerSettingsData = mixerSettings->getData();
198 // TODO: Need to reformat object so types are an
199 // array themselves. This gets really awkward
200 quint8 *mixerTypes[] = {
201 &mixerSettingsData.Mixer1Type,
202 &mixerSettingsData.Mixer2Type,
203 &mixerSettingsData.Mixer3Type,
204 &mixerSettingsData.Mixer4Type,
205 &mixerSettingsData.Mixer5Type,
206 &mixerSettingsData.Mixer6Type,
207 &mixerSettingsData.Mixer7Type,
208 &mixerSettingsData.Mixer8Type,
209 &mixerSettingsData.Mixer9Type,
210 &mixerSettingsData.Mixer10Type,
212 const int NUM_MIXERS = sizeof(mixerTypes) / sizeof(mixerTypes[0]);
214 QComboBox *outputs[] = {
215 ui->rollChannel,
216 ui->pitchChannel,
217 ui->yawChannel
219 const int NUM_OUTPUTS = sizeof(outputs) / sizeof(outputs[0]);
221 ui->message->setText("");
222 bool widgetUpdated;
223 do {
224 widgetUpdated = false;
226 for (int i = 0; i < NUM_OUTPUTS; i++) {
227 // Channel 1 is second entry, so becomes zero
228 int mixerNum = outputs[i]->currentIndex() - 1;
230 if ((mixerNum >= 0) && // Short circuit in case of none
231 (*mixerTypes[mixerNum] != MixerSettings::MIXER1TYPE_DISABLED) &&
232 (*mixerTypes[mixerNum] != MixerSettings::MIXER1TYPE_CAMERAROLLORSERVO1 + i)) {
233 // If the mixer channel already mapped to something, it should not be
234 // used for camera output, we reset it to none
235 outputs[i]->setCurrentIndex(0);
236 ui->message->setText("One of the channels is already assigned, reverted to none");
238 // Loop again or we may have inconsistent widget and UAVObject
239 widgetUpdated = true;
240 } else {
241 // Make sure no other channels have this output set
242 for (int j = 0; j < NUM_MIXERS; j++) {
243 if (*mixerTypes[j] == (MixerSettings::MIXER1TYPE_CAMERAROLLORSERVO1 + i)) {
244 *mixerTypes[j] = MixerSettings::MIXER1TYPE_DISABLED;
248 // If this channel is assigned to one of the outputs that is not disabled
249 // set it
250 if ((mixerNum >= 0) && (mixerNum < NUM_MIXERS)) {
251 *mixerTypes[mixerNum] = MixerSettings::MIXER1TYPE_CAMERAROLLORSERVO1 + i;
255 } while (widgetUpdated);
257 // FIXME: Should not use setData() to prevent double updates.
258 // It should be refactored after the reformatting of MixerSettings UAVObject.
259 mixerSettings->setData(mixerSettingsData);
261 ConfigTaskWidget::updateObjectsFromWidgets();
265 * This slot function is called when "Default" button is clicked.
266 * All special widgets which belong to the group passed should be set here.
268 void ConfigCameraStabilizationWidget::defaultRequestedSlot(int group)
270 Q_UNUSED(group);
272 // Here is the example of how to reset the state of QCheckBox. It is
273 // commented out because we normally don't want to reset the module
274 // enable state to default "disabled" (or we don't care about values at all).
275 // But if you want, you could use the dirtyClone() function to get default
276 // values of an object and then use them to set a widget state.
278 // HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
279 // HwSettings *hwSettingsDefault=(HwSettings*)hwSettings->dirtyClone();
280 // HwSettings::DataFields hwSettingsData = hwSettingsDefault->getData();
281 // m_camerastabilization->enableCameraStabilization->setChecked(
282 // hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_CAMERASTAB] == HwSettings::OPTIONALMODULES_ENABLED);
284 // For outputs we set them all to none, so don't use any UAVObject to get defaults
285 QComboBox *outputs[] = {
286 ui->rollChannel,
287 ui->pitchChannel,
288 ui->yawChannel,
290 const int NUM_OUTPUTS = sizeof(outputs) / sizeof(outputs[0]);
292 for (int i = 0; i < NUM_OUTPUTS; i++) {
293 outputs[i]->setCurrentIndex(0);