dRonin  adbada4
dRonin GCS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
configcamerastabilizationwidget.cpp
Go to the documentation of this file.
1 
12 /*
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.
17  *
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.
22  *
23  * You should have received a copy of the GNU General Public License along
24  * with this program; if not, see <http://www.gnu.org/licenses/>
25  */
26 
27 /*
28  * IMPORTANT: This module is meant to be a reference implementation which
29  * demostrates the use of ConfigTaskWidget API for widgets which are not directly
30  * related to UAVObjects. It contains a lot of comments including some commented
31  * out code samples. Please DO NOT COPY/PASTE them into any other module based
32  * on this.
33  */
34 
36 #include "camerastabsettings.h"
37 #include "modulesettings.h"
38 #include "mixersettings.h"
39 #include "actuatorcommand.h"
40 
42  : ConfigTaskWidget(parent)
43 {
44  m_camerastabilization = new Ui_CameraStabilizationWidget();
45  m_camerastabilization->setupUi(this);
46 
47  // These widgets don't have direct relation to UAVObjects
48  // and need special processing
49  QComboBox *outputs[] = {
50  m_camerastabilization->rollChannel,
51  m_camerastabilization->pitchChannel,
52  m_camerastabilization->yawChannel,
53 
54  };
55  const int NUM_OUTPUTS = sizeof(outputs) / sizeof(outputs[0]);
56 
57  // Populate widgets with channel numbers
58  for (int i = 0; i < NUM_OUTPUTS; i++) {
59  outputs[i]->clear();
60  outputs[i]->addItem("None");
61  for (quint32 j = 0; j < ActuatorCommand::CHANNEL_NUMELEM; j++)
62  outputs[i]->addItem(QString("Channel %1").arg(j + 1));
63  }
64 
65  // Load UAVObjects to widget relations from UI file
66  // using objrelation dynamic property
68 
69  // Add some widgets to track their UI dirty state and handle smartsave
70  addWidget(m_camerastabilization->enableCameraStabilization);
71  addWidget(m_camerastabilization->rollChannel);
72  addWidget(m_camerastabilization->pitchChannel);
73  addWidget(m_camerastabilization->yawChannel);
74 
75  // Add some UAVObjects to monitor their changes in addition to autoloaded ones.
76  // Note also that we want to reload some UAVObjects by "Reload" button and have
77  // to pass corresponding reload group numbers (defined also in objrelation property)
78  // to the montitor. We don't reload ModuleSettings (module enable state) but reload
79  // output channels.
80  QList<int> reloadGroups;
81  reloadGroups << 1;
82  addUAVObject("ModuleSettings");
83  addUAVObject("MixerSettings", &reloadGroups);
84 
85  // To set special widgets to defaults when requested
86  connect(this, &ConfigTaskWidget::defaultRequested, this,
87  &ConfigCameraStabilizationWidget::defaultRequestedSlot);
88 
90 }
91 
93 {
94  // Do nothing
95 }
96 
97 /*
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. Aftewards it calls base class
101  * function to take care of other widgets which were dynamically added.
102  */
103 void ConfigCameraStabilizationWidget::refreshWidgetsValues(UAVObject *obj)
104 {
105  bool dirty = isDirty();
106 
107  // Set module enable checkbox from OptionalModules UAVObject item.
108  // It needs special processing because ConfigTaskWidget uses TRUE/FALSE
109  // for QCheckBox, but OptionalModules uses Enabled/Disabled enum values.
110  ModuleSettings *moduleSettings = ModuleSettings::GetInstance(getObjectManager());
111  ModuleSettings::DataFields moduleSettingsData = moduleSettings->getData();
112 
113  m_camerastabilization->enableCameraStabilization->setChecked(
114  moduleSettingsData.AdminState[ModuleSettings::ADMINSTATE_CAMERASTAB]
115  == ModuleSettings::ADMINSTATE_ENABLED);
116 
117  // Load mixer outputs which are mapped to camera controls
118  MixerSettings *mixerSettings = MixerSettings::GetInstance(getObjectManager());
119  MixerSettings::DataFields mixerSettingsData = mixerSettings->getData();
120 
121  // TODO: Need to reformat object so types are an
122  // array themselves. This gets really awkward
123  quint8 *mixerTypes[] = {
124  &mixerSettingsData.Mixer1Type, &mixerSettingsData.Mixer2Type,
125  &mixerSettingsData.Mixer3Type, &mixerSettingsData.Mixer4Type,
126  &mixerSettingsData.Mixer5Type, &mixerSettingsData.Mixer6Type,
127  &mixerSettingsData.Mixer7Type, &mixerSettingsData.Mixer8Type,
128  &mixerSettingsData.Mixer9Type, &mixerSettingsData.Mixer10Type,
129  };
130  const int NUM_MIXERS = sizeof(mixerTypes) / sizeof(mixerTypes[0]);
131 
132  QComboBox *outputs[] = { m_camerastabilization->rollChannel,
133  m_camerastabilization->pitchChannel,
134  m_camerastabilization->yawChannel };
135  const int NUM_OUTPUTS = sizeof(outputs) / sizeof(outputs[0]);
136 
137  for (int i = 0; i < NUM_OUTPUTS; i++) {
138  // Default to none if not found.
139  // Then search for any mixer channels set to this
140  outputs[i]->setCurrentIndex(0);
141  for (int j = 0; j < NUM_MIXERS; j++)
142  if (*mixerTypes[j] == (MixerSettings::MIXER1TYPE_CAMERAROLL + i)
143  && outputs[i]->currentIndex() != (j + 1))
144  outputs[i]->setCurrentIndex(j + 1);
145  }
146 
147  setDirty(dirty);
148 
150 }
151 
152 /*
153  * This overridden function updates UAVObjects which have no direct relation
154  * to any of widgets. Aftewards it calls base class function to take care of
155  * other object to widget relations which were dynamically added.
156  */
157 void ConfigCameraStabilizationWidget::updateObjectsFromWidgets()
158 {
159  // Save state of the module enable checkbox first.
160  // Do not use setData() member on whole object, if possible, since it triggers
161  // unnessesary UAVObect update.
162  quint8 enableModule = m_camerastabilization->enableCameraStabilization->isChecked()
163  ? (ModuleSettings::ADMINSTATE_ENABLED)
164  : (ModuleSettings::ADMINSTATE_DISABLED);
165  ModuleSettings *moduleSettings = ModuleSettings::GetInstance(getObjectManager());
166  moduleSettings->setAdminState(ModuleSettings::ADMINSTATE_CAMERASTAB, enableModule);
167 
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();
172 
173  // TODO: Need to reformat object so types are an
174  // array themselves. This gets really awkward
175  quint8 *mixerTypes[] = {
176  &mixerSettingsData.Mixer1Type, &mixerSettingsData.Mixer2Type,
177  &mixerSettingsData.Mixer3Type, &mixerSettingsData.Mixer4Type,
178  &mixerSettingsData.Mixer5Type, &mixerSettingsData.Mixer6Type,
179  &mixerSettingsData.Mixer7Type, &mixerSettingsData.Mixer8Type,
180  &mixerSettingsData.Mixer9Type, &mixerSettingsData.Mixer10Type,
181  };
182  const int NUM_MIXERS = sizeof(mixerTypes) / sizeof(mixerTypes[0]);
183 
184  QComboBox *outputs[] = { m_camerastabilization->rollChannel,
185  m_camerastabilization->pitchChannel,
186  m_camerastabilization->yawChannel };
187  const int NUM_OUTPUTS = sizeof(outputs) / sizeof(outputs[0]);
188 
189  m_camerastabilization->message->setText("");
190  bool widgetUpdated;
191  do {
192  widgetUpdated = false;
193 
194  for (int i = 0; i < NUM_OUTPUTS; i++) {
195  // Channel 1 is second entry, so becomes zero
196  int mixerNum = outputs[i]->currentIndex() - 1;
197 
198  if ((mixerNum >= 0) && // Short circuit in case of none
199  (*mixerTypes[mixerNum] != MixerSettings::MIXER1TYPE_DISABLED)
200  && (*mixerTypes[mixerNum] != MixerSettings::MIXER1TYPE_CAMERAROLL + i)) {
201  // If the mixer channel already mapped to something, it should not be
202  // used for camera output, we reset it to none
203  outputs[i]->setCurrentIndex(0);
204  m_camerastabilization->message->setText(
205  "One of the channels is already assigned, reverted to none");
206 
207  // Loop again or we may have inconsistent widget and UAVObject
208  widgetUpdated = true;
209  } else {
210  // Make sure no other channels have this output set
211  for (int j = 0; j < NUM_MIXERS; j++)
212  if (*mixerTypes[j] == (MixerSettings::MIXER1TYPE_CAMERAROLL + i))
213  *mixerTypes[j] = MixerSettings::MIXER1TYPE_DISABLED;
214 
215  // If this channel is assigned to one of the outputs that is not disabled
216  // set it
217  if ((mixerNum >= 0) && (mixerNum < NUM_MIXERS))
218  *mixerTypes[mixerNum] = MixerSettings::MIXER1TYPE_CAMERAROLL + i;
219  }
220  }
221  } while (widgetUpdated);
222 
223  // FIXME: Should not use setData() to prevent double updates.
224  // It should be refactored after the reformatting of MixerSettings UAVObject.
225  mixerSettings->setData(mixerSettingsData);
226 
228 }
229 
230 /*
231  * This slot function is called when "Default" button is clicked.
232  * All special widgets which belong to the group passed should be set here.
233  */
234 void ConfigCameraStabilizationWidget::defaultRequestedSlot(int group)
235 {
236  Q_UNUSED(group);
237 
238  // Here is the example of how to reset the state of QCheckBox. It is
239  // commented out because we normally don't want to reset the module
240  // enable state to default "disabled" (or we don't care about values at all).
241  // But if you want, you could use the dirtyClone() function to get default
242  // values of an object and then use them to set a widget state.
243  //
244  // HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
245  // HwSettings *hwSettingsDefault=dynamic_cast <HwSettings*> (hwSettings)->dirtyClone();
246  // HwSettings::DataFields hwSettingsData = hwSettingsDefault->getData();
247  // m_camerastabilization->enableCameraStabilization->setChecked(
248  // hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_CAMERASTAB] ==
249  // HwSettings::OPTIONALMODULES_ENABLED);
250 
251  // For outputs we set them all to none, so don't use any UAVObject to get defaults
252  QComboBox *outputs[] = {
253  m_camerastabilization->rollChannel,
254  m_camerastabilization->pitchChannel,
255  m_camerastabilization->yawChannel,
256  };
257  const int NUM_OUTPUTS = sizeof(outputs) / sizeof(outputs[0]);
258 
259  for (int i = 0; i < NUM_OUTPUTS; i++) {
260  outputs[i]->setCurrentIndex(0);
261  }
262 }
263 
void setDirty(bool value)
ConfigCameraStabilizationWidget(QWidget *parent=nullptr)
void addWidget(QWidget *widget)
for i
Definition: OPPlots.m:140
void addUAVObject(QString objectName, QList< int > *reloadGroups=NULL)
virtual void updateObjectsFromWidgets()
virtual void refreshWidgetsValues(UAVObject *obj=NULL)
UAVObjectManager * getObjectManager()
ConfigTaskWidget::getObjectManager Utility function to get a pointer to the object manager...
void defaultRequested(int group)