1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-18 03:52:11 +01:00

Merge remote-tracking branch 'origin/os/CameraStab-use-ConfigTaskWidget' into next

This commit is contained in:
James Cotton 2012-08-22 08:06:34 -05:00
commit a99b5454eb
6 changed files with 470 additions and 269 deletions

View File

@ -27,8 +27,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>696</width>
<height>635</height>
<width>702</width>
<height>660</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
@ -107,6 +107,16 @@ have to define channel output range using Output configuration tab.</string>
<property name="value">
<number>20</number>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:OutputRange</string>
<string>element:Yaw</string>
<string>haslimits:no</string>
<string>scale:1</string>
<string>buttongroup:1</string>
</stringlist>
</property>
</widget>
</item>
<item row="2" column="2">
@ -126,6 +136,16 @@ have to define channel output range using Output configuration tab.</string>
<property name="value">
<number>20</number>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:OutputRange</string>
<string>element:Pitch</string>
<string>haslimits:no</string>
<string>scale:1</string>
<string>buttongroup:1</string>
</stringlist>
</property>
</widget>
</item>
<item row="2" column="1">
@ -145,6 +165,16 @@ have to define channel output range using Output configuration tab.</string>
<property name="value">
<number>20</number>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:OutputRange</string>
<string>element:Roll</string>
<string>haslimits:no</string>
<string>scale:1</string>
<string>buttongroup:1</string>
</stringlist>
</property>
</widget>
</item>
<item row="1" column="3">
@ -339,6 +369,14 @@ margin:1px;</string>
Don't forget to map this channel using Input configuration tab.</string>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:Input</string>
<string>element:Yaw</string>
<string>buttongroup:1</string>
</stringlist>
</property>
<item>
<property name="text">
<string>None</string>
@ -356,6 +394,14 @@ Don't forget to map this channel using Input configuration tab.</string>
Don't forget to map this channel using Input configuration tab.</string>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:Input</string>
<string>element:Pitch</string>
<string>buttongroup:1</string>
</stringlist>
</property>
<item>
<property name="text">
<string>None</string>
@ -373,6 +419,14 @@ Don't forget to map this channel using Input configuration tab.</string>
Don't forget to map this channel using Input configuration tab.</string>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:Input</string>
<string>element:Roll</string>
<string>buttongroup:1</string>
</stringlist>
</property>
<item>
<property name="text">
<string>None</string>
@ -398,6 +452,14 @@ Don't forget to map this channel using Input configuration tab.</string>
Attitude: camera tracks level for the axis. Input controls the deflection.
AxisLock: camera remembers tracking attitude. Input controls the rate of deflection.</string>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:StabilizationMode</string>
<string>element:Yaw</string>
<string>buttongroup:1</string>
</stringlist>
</property>
<item>
<property name="text">
<string>Attitude</string>
@ -419,6 +481,16 @@ AxisLock: camera remembers tracking attitude. Input controls the rate of deflect
<property name="value">
<number>20</number>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:InputRange</string>
<string>element:Yaw</string>
<string>haslimits:no</string>
<string>scale:1</string>
<string>buttongroup:1</string>
</stringlist>
</property>
</widget>
</item>
<item row="4" column="3">
@ -435,6 +507,16 @@ AxisLock: camera remembers tracking attitude. Input controls the rate of deflect
<property name="value">
<number>50</number>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:InputRate</string>
<string>element:Yaw</string>
<string>haslimits:no</string>
<string>scale:1</string>
<string>buttongroup:1</string>
</stringlist>
</property>
</widget>
</item>
<item row="5" column="3">
@ -453,6 +535,16 @@ This option smoothes the stick input. Zero value disables LPF.</string>
<property name="value">
<number>150</number>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:ResponseTime</string>
<string>element:Yaw</string>
<string>haslimits:no</string>
<string>scale:1</string>
<string>buttongroup:1</string>
</stringlist>
</property>
</widget>
</item>
<item row="2" column="2">
@ -466,6 +558,14 @@ This option smoothes the stick input. Zero value disables LPF.</string>
Attitude: camera tracks level for the axis. Input controls the deflection.
AxisLock: camera remembers tracking attitude. Input controls the rate of deflection.</string>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:StabilizationMode</string>
<string>element:Pitch</string>
<string>buttongroup:1</string>
</stringlist>
</property>
<item>
<property name="text">
<string>Attitude</string>
@ -487,6 +587,16 @@ AxisLock: camera remembers tracking attitude. Input controls the rate of deflect
<property name="value">
<number>20</number>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:InputRange</string>
<string>element:Pitch</string>
<string>haslimits:no</string>
<string>scale:1</string>
<string>buttongroup:1</string>
</stringlist>
</property>
</widget>
</item>
<item row="4" column="2">
@ -503,6 +613,16 @@ AxisLock: camera remembers tracking attitude. Input controls the rate of deflect
<property name="value">
<number>50</number>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:InputRate</string>
<string>element:Pitch</string>
<string>haslimits:no</string>
<string>scale:1</string>
<string>buttongroup:1</string>
</stringlist>
</property>
</widget>
</item>
<item row="5" column="2">
@ -521,6 +641,16 @@ This option smoothes the stick input. Zero value disables LPF.</string>
<property name="value">
<number>150</number>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:ResponseTime</string>
<string>element:Pitch</string>
<string>haslimits:no</string>
<string>scale:1</string>
<string>buttongroup:1</string>
</stringlist>
</property>
</widget>
</item>
<item row="2" column="1">
@ -534,6 +664,14 @@ This option smoothes the stick input. Zero value disables LPF.</string>
Attitude: camera tracks level for the axis. Input controls the deflection.
AxisLock: camera remembers tracking attitude. Input controls the rate of deflection.</string>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:StabilizationMode</string>
<string>element:Roll</string>
<string>buttongroup:1</string>
</stringlist>
</property>
<item>
<property name="text">
<string>Attitude</string>
@ -555,6 +693,16 @@ AxisLock: camera remembers tracking attitude. Input controls the rate of deflect
<property name="value">
<number>20</number>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:InputRange</string>
<string>element:Roll</string>
<string>haslimits:no</string>
<string>scale:1</string>
<string>buttongroup:1</string>
</stringlist>
</property>
</widget>
</item>
<item row="4" column="1">
@ -571,6 +719,16 @@ AxisLock: camera remembers tracking attitude. Input controls the rate of deflect
<property name="value">
<number>50</number>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:InputRate</string>
<string>element:Roll</string>
<string>haslimits:no</string>
<string>scale:1</string>
<string>buttongroup:1</string>
</stringlist>
</property>
</widget>
</item>
<item row="5" column="1">
@ -589,6 +747,16 @@ This option smoothes the stick input. Zero value disables LPF.</string>
<property name="value">
<number>150</number>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:ResponseTime</string>
<string>element:Roll</string>
<string>haslimits:no</string>
<string>scale:1</string>
<string>buttongroup:1</string>
</stringlist>
</property>
</widget>
</item>
<item row="6" column="0">
@ -657,6 +825,15 @@ value.</string>
<property name="value">
<double>1.000000000000000</double>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:MaxAxisLockRate</string>
<string>haslimits:no</string>
<string>scale:1</string>
<string>buttongroup:1</string>
</stringlist>
</property>
</widget>
</item>
</layout>
@ -754,12 +931,18 @@ value.</string>
<property name="flat">
<bool>true</bool>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>button:help</string>
<string>url:http://wiki.openpilot.org/display/Doc/Camera+Stabilization+Configuration</string>
</stringlist>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="camerastabilizationResetToDefaults">
<property name="toolTip">
<string>Load default CameraStabilization settings except output channels
<string>Load default CameraStabilization settings except output channels into GCS.
Loaded settings are not applied automatically. You have to click the
Apply or Save button afterwards.</string>
@ -767,6 +950,33 @@ Apply or Save button afterwards.</string>
<property name="text">
<string>Reset To Defaults</string>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>button:default</string>
<string>buttongroup:1</string>
</stringlist>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="toolTip">
<string>Reloads saved CameraStabilization settings except output channels
from board into GCS. Useful if you have accidentally changed some
settings.
Loaded settings are not applied automatically. You have to click the
Apply or Save button afterwards.</string>
</property>
<property name="text">
<string>Reload Board Data</string>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>button:reload</string>
<string>buttongroup:1</string>
</stringlist>
</property>
</widget>
</item>
<item>
@ -777,6 +987,11 @@ Apply or Save button afterwards.</string>
<property name="text">
<string>Apply</string>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>button:apply</string>
</stringlist>
</property>
</widget>
</item>
<item>
@ -790,6 +1005,11 @@ Apply or Save button afterwards.</string>
<property name="checked">
<bool>false</bool>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>button:save</string>
</stringlist>
</property>
</widget>
</item>
</layout>
@ -823,7 +1043,6 @@ Apply or Save button afterwards.</string>
<tabstop>yawResponseTime</tabstop>
<tabstop>MaxAxisLockRate</tabstop>
<tabstop>camerastabilizationHelp</tabstop>
<tabstop>camerastabilizationResetToDefaults</tabstop>
<tabstop>camerastabilizationSaveRAM</tabstop>
<tabstop>camerastabilizationSaveSD</tabstop>
<tabstop>scrollArea</tabstop>

View File

@ -2,7 +2,7 @@
******************************************************************************
*
* @file configcamerastabilizationwidget.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011.
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011-2012.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
@ -30,65 +30,50 @@
#include "mixersettings.h"
#include "actuatorcommand.h"
#include <QDebug>
#include <QDesktopServices>
#include <QUrl>
ConfigCameraStabilizationWidget::ConfigCameraStabilizationWidget(QWidget *parent) : ConfigTaskWidget(parent)
{
// TODO: this widget should use the addUAVObjectToWidgetRelation()
m_camerastabilization = new Ui_CameraStabilizationWidget();
m_camerastabilization->setupUi(this);
QComboBox *outputs[3] = {
// These widgets don't have direct relation to UAVObjects
// and need special processing
QComboBox *outputs[] = {
m_camerastabilization->rollChannel,
m_camerastabilization->pitchChannel,
m_camerastabilization->yawChannel,
};
const int NUM_OUTPUTS = sizeof(outputs) / sizeof(outputs[0]);
QComboBox *inputs[3] = {
m_camerastabilization->rollInputChannel,
m_camerastabilization->pitchInputChannel,
m_camerastabilization->yawInputChannel,
};
QComboBox *stabilizationMode[3] = {
m_camerastabilization->rollStabilizationMode,
m_camerastabilization->pitchStabilizationMode,
m_camerastabilization->yawStabilizationMode,
};
CameraStabSettings *cameraStab = CameraStabSettings::GetInstance(getObjectManager());
CameraStabSettings::DataFields cameraStabData = cameraStab->getData();
for (int i = 0; i < 3; i++) {
// Populate widgets with channel numbers
for (int i = 0; i < NUM_OUTPUTS; i++) {
outputs[i]->clear();
outputs[i]->addItem("None");
for (quint32 j = 0; j < ActuatorCommand::CHANNEL_NUMELEM; j++)
outputs[i]->addItem(QString("Channel %1").arg(j+1));
UAVObjectField *field;
field = cameraStab->getField("Input");
Q_ASSERT(field);
inputs[i]->clear();
inputs[i]->addItems(field->getOptions());
inputs[i]->setCurrentIndex(cameraStabData.Input[i]);
field = cameraStab->getField("StabilizationMode");
Q_ASSERT(field);
stabilizationMode[i]->clear();
stabilizationMode[i]->addItems(field->getOptions());
stabilizationMode[i]->setCurrentIndex(cameraStabData.StabilizationMode[i]);
}
connectUpdates();
// Load UAVObjects to widget relations from UI file
// using objrelation dynamic property
autoLoadWidgets();
// Connect buttons
connect(m_camerastabilization->camerastabilizationResetToDefaults, SIGNAL(clicked()), this, SLOT(resetToDefaults()));
connect(m_camerastabilization->camerastabilizationSaveRAM, SIGNAL(clicked()), this, SLOT(applySettings()));
connect(m_camerastabilization->camerastabilizationSaveSD, SIGNAL(clicked()), this, SLOT(saveSettings()));
connect(m_camerastabilization->camerastabilizationHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
// Add some widgets to track their UI dirty state and handle smartsave
addWidget(m_camerastabilization->enableCameraStabilization);
addWidget(m_camerastabilization->rollChannel);
addWidget(m_camerastabilization->pitchChannel);
addWidget(m_camerastabilization->yawChannel);
// Add some UAVObjects to monitor their changes in addition to autoloaded ones.
// Note also that we want to reload some UAVObjects by "Reload" button and have
// to pass corresponding reload group numbers (defined also in objrelation property)
// to the montitor. We don't reload HwSettings (module enable state) but reload
// output channels.
QList<int> reloadGroups;
reloadGroups << 1;
addUAVObject("HwSettings");
addUAVObject("MixerSettings", &reloadGroups);
// To set special widgets to defaults when requested
connect(this, SIGNAL(defaultRequested(int)), this, SLOT(defaultRequestedSlot(int)));
disableMouseWheelEvents();
}
@ -98,52 +83,32 @@ ConfigCameraStabilizationWidget::~ConfigCameraStabilizationWidget()
// Do nothing
}
void ConfigCameraStabilizationWidget::connectUpdates()
/*
* This overridden function refreshes widgets which have no direct relation
* to any of UAVObjects. It saves their dirty state first because update comes
* from UAVObjects, and then restores it. Aftewards it calls base class
* function to take care of other widgets which were dynamically added.
*/
void ConfigCameraStabilizationWidget::refreshWidgetsValues(UAVObject *obj)
{
// Now connect the widget to the StabilizationSettings object
connect(MixerSettings::GetInstance(getObjectManager()), SIGNAL(objectUpdated(UAVObject *)), this, SLOT(refreshValues()));
connect(CameraStabSettings::GetInstance(getObjectManager()), SIGNAL(objectUpdated(UAVObject *)), this, SLOT(refreshValues()));
// TODO: This will need to support both CC and OP later
connect(HwSettings::GetInstance(getObjectManager()), SIGNAL(objectUpdated(UAVObject *)), this, SLOT(refreshValues()));
}
bool dirty = isDirty();
void ConfigCameraStabilizationWidget::disconnectUpdates()
{
// Now connect the widget to the StabilizationSettings object
disconnect(MixerSettings::GetInstance(getObjectManager()), SIGNAL(objectUpdated(UAVObject *)), this, SLOT(refreshValues()));
disconnect(CameraStabSettings::GetInstance(getObjectManager()), SIGNAL(objectUpdated(UAVObject *)), this, SLOT(refreshValues()));
// TODO: This will need to support both CC and OP later
disconnect(HwSettings::GetInstance(getObjectManager()), SIGNAL(objectUpdated(UAVObject *)), this, SLOT(refreshValues()));
}
/**
* @brief Populate the gui settings into the appropriate
* UAV structures
*/
void ConfigCameraStabilizationWidget::applySettings()
{
// Enable or disable the settings
// Set module enable checkbox from OptionalModules UAVObject item.
// It needs special processing because ConfigTaskWidget uses TRUE/FALSE
// for QCheckBox, but OptionalModules uses Enabled/Disabled enum values.
HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
HwSettings::DataFields hwSettingsData = hwSettings->getData();
hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_CAMERASTAB] =
m_camerastabilization->enableCameraStabilization->isChecked() ?
HwSettings::OPTIONALMODULES_ENABLED :
HwSettings::OPTIONALMODULES_DISABLED;
// Update the mixer settings
m_camerastabilization->enableCameraStabilization->setChecked(
hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_CAMERASTAB] == HwSettings::OPTIONALMODULES_ENABLED);
// Load mixer outputs which are mapped to camera controls
MixerSettings *mixerSettings = MixerSettings::GetInstance(getObjectManager());
MixerSettings::DataFields mixerSettingsData = mixerSettings->getData();
const int NUM_MIXERS = 10;
QComboBox *outputs[3] = {
m_camerastabilization->rollChannel,
m_camerastabilization->pitchChannel,
m_camerastabilization->yawChannel,
};
// TODO: Need to reformat object so types are an
// array themselves. This gets really awkward
quint8 * mixerTypes[NUM_MIXERS] = {
quint8 *mixerTypes[] = {
&mixerSettingsData.Mixer1Type,
&mixerSettingsData.Mixer2Type,
&mixerSettingsData.Mixer3Type,
@ -155,187 +120,144 @@ void ConfigCameraStabilizationWidget::applySettings()
&mixerSettingsData.Mixer9Type,
&mixerSettingsData.Mixer10Type,
};
const int NUM_MIXERS = sizeof(mixerTypes) / sizeof(mixerTypes[0]);
m_camerastabilization->message->setText("");
for (int i = 0; i < 3; i++)
{
// Channel 1 is second entry, so becomes zero
int mixerNum = outputs[i]->currentIndex() - 1;
if ( mixerNum >= 0 && // Short circuit in case of none
*mixerTypes[mixerNum] != MixerSettings::MIXER1TYPE_DISABLED &&
(*mixerTypes[mixerNum] != MixerSettings::MIXER1TYPE_CAMERAROLL + i) ) {
// If the mixer channel already to something that isn't what we are
// about to set it to reset to none
outputs[i]->setCurrentIndex(0);
m_camerastabilization->message->setText("One of the channels is already assigned, reverted to none");
} else {
// Make sure no other channels have this output set
for (int j = 0; j < NUM_MIXERS; j++)
if (*mixerTypes[j] == (MixerSettings::MIXER1TYPE_CAMERAROLL + i))
*mixerTypes[j] = MixerSettings::MIXER1TYPE_DISABLED;
// If this channel is assigned to one of the outputs that is not disabled
// set it
if(mixerNum >= 0 && mixerNum < NUM_MIXERS)
*mixerTypes[mixerNum] = MixerSettings::MIXER1TYPE_CAMERAROLL + i;
}
}
// Update the settings
CameraStabSettings *cameraStab = CameraStabSettings::GetInstance(getObjectManager());
CameraStabSettings::DataFields cameraStabData = cameraStab->getData();
cameraStabData.OutputRange[CameraStabSettings::OUTPUTRANGE_ROLL] = m_camerastabilization->rollOutputRange->value();
cameraStabData.OutputRange[CameraStabSettings::OUTPUTRANGE_PITCH] = m_camerastabilization->pitchOutputRange->value();
cameraStabData.OutputRange[CameraStabSettings::OUTPUTRANGE_YAW] = m_camerastabilization->yawOutputRange->value();
cameraStabData.Input[CameraStabSettings::INPUT_ROLL] = m_camerastabilization->rollInputChannel->currentIndex();
cameraStabData.Input[CameraStabSettings::INPUT_PITCH] = m_camerastabilization->pitchInputChannel->currentIndex();
cameraStabData.Input[CameraStabSettings::INPUT_YAW] = m_camerastabilization->yawInputChannel->currentIndex();
cameraStabData.StabilizationMode[CameraStabSettings::STABILIZATIONMODE_ROLL] = m_camerastabilization->rollStabilizationMode->currentIndex();
cameraStabData.StabilizationMode[CameraStabSettings::STABILIZATIONMODE_PITCH] = m_camerastabilization->pitchStabilizationMode->currentIndex();
cameraStabData.StabilizationMode[CameraStabSettings::STABILIZATIONMODE_YAW] = m_camerastabilization->yawStabilizationMode->currentIndex();
cameraStabData.InputRange[CameraStabSettings::INPUTRANGE_ROLL] = m_camerastabilization->rollInputRange->value();
cameraStabData.InputRange[CameraStabSettings::INPUTRANGE_PITCH] = m_camerastabilization->pitchInputRange->value();
cameraStabData.InputRange[CameraStabSettings::INPUTRANGE_YAW] = m_camerastabilization->yawInputRange->value();
cameraStabData.InputRate[CameraStabSettings::INPUTRATE_ROLL] = m_camerastabilization->rollInputRate->value();
cameraStabData.InputRate[CameraStabSettings::INPUTRATE_PITCH] = m_camerastabilization->pitchInputRate->value();
cameraStabData.InputRate[CameraStabSettings::INPUTRATE_YAW] = m_camerastabilization->yawInputRate->value();
cameraStabData.ResponseTime[CameraStabSettings::RESPONSETIME_ROLL] = m_camerastabilization->rollResponseTime->value();
cameraStabData.ResponseTime[CameraStabSettings::RESPONSETIME_PITCH] = m_camerastabilization->pitchResponseTime->value();
cameraStabData.ResponseTime[CameraStabSettings::RESPONSETIME_YAW] = m_camerastabilization->yawResponseTime->value();
cameraStabData.MaxAxisLockRate = m_camerastabilization->MaxAxisLockRate->value();
// Because multiple objects are updated, and all of them trigger the callback
// they must be done together (if update one then load settings from second
// the first update would wipe the UI controls). However to be extra cautious
// I'm also disabling updates during the setting to the UAVObjects
disconnectUpdates();
hwSettings->setData(hwSettingsData);
mixerSettings->setData(mixerSettingsData);
cameraStab->setData(cameraStabData);
connectUpdates();
}
/**
* Push settings into UAV objects then save them
*/
void ConfigCameraStabilizationWidget::saveSettings()
{
applySettings();
UAVObject *obj = HwSettings::GetInstance(getObjectManager());
saveObjectToSD(obj);
obj = MixerSettings::GetInstance(getObjectManager());
saveObjectToSD(obj);
obj = CameraStabSettings::GetInstance(getObjectManager());
saveObjectToSD(obj);
}
/**
* Refresh UI with new settings of CameraStabSettings object
* (either from active configuration or just loaded defaults
* to be applied or saved)
*/
void ConfigCameraStabilizationWidget::refreshUIValues(CameraStabSettings::DataFields &cameraStabData)
{
m_camerastabilization->rollOutputRange->setValue(cameraStabData.OutputRange[CameraStabSettings::OUTPUTRANGE_ROLL]);
m_camerastabilization->pitchOutputRange->setValue(cameraStabData.OutputRange[CameraStabSettings::OUTPUTRANGE_PITCH]);
m_camerastabilization->yawOutputRange->setValue(cameraStabData.OutputRange[CameraStabSettings::OUTPUTRANGE_YAW]);
m_camerastabilization->rollInputChannel->setCurrentIndex(cameraStabData.Input[CameraStabSettings::INPUT_ROLL]);
m_camerastabilization->pitchInputChannel->setCurrentIndex(cameraStabData.Input[CameraStabSettings::INPUT_PITCH]);
m_camerastabilization->yawInputChannel->setCurrentIndex(cameraStabData.Input[CameraStabSettings::INPUT_YAW]);
m_camerastabilization->rollStabilizationMode->setCurrentIndex(cameraStabData.StabilizationMode[CameraStabSettings::STABILIZATIONMODE_ROLL]);
m_camerastabilization->pitchStabilizationMode->setCurrentIndex(cameraStabData.StabilizationMode[CameraStabSettings::STABILIZATIONMODE_PITCH]);
m_camerastabilization->yawStabilizationMode->setCurrentIndex(cameraStabData.StabilizationMode[CameraStabSettings::STABILIZATIONMODE_YAW]);
m_camerastabilization->rollInputRange->setValue(cameraStabData.InputRange[CameraStabSettings::INPUTRANGE_ROLL]);
m_camerastabilization->pitchInputRange->setValue(cameraStabData.InputRange[CameraStabSettings::INPUTRANGE_PITCH]);
m_camerastabilization->yawInputRange->setValue(cameraStabData.InputRange[CameraStabSettings::INPUTRANGE_YAW]);
m_camerastabilization->rollInputRate->setValue(cameraStabData.InputRate[CameraStabSettings::INPUTRATE_ROLL]);
m_camerastabilization->pitchInputRate->setValue(cameraStabData.InputRate[CameraStabSettings::INPUTRATE_PITCH]);
m_camerastabilization->yawInputRate->setValue(cameraStabData.InputRate[CameraStabSettings::INPUTRATE_YAW]);
m_camerastabilization->rollResponseTime->setValue(cameraStabData.ResponseTime[CameraStabSettings::RESPONSETIME_ROLL]);
m_camerastabilization->pitchResponseTime->setValue(cameraStabData.ResponseTime[CameraStabSettings::RESPONSETIME_PITCH]);
m_camerastabilization->yawResponseTime->setValue(cameraStabData.ResponseTime[CameraStabSettings::RESPONSETIME_YAW]);
m_camerastabilization->MaxAxisLockRate->setValue(cameraStabData.MaxAxisLockRate);
}
void ConfigCameraStabilizationWidget::refreshValues()
{
HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
HwSettings::DataFields hwSettingsData = hwSettings->getData();
m_camerastabilization->enableCameraStabilization->setChecked(
hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_CAMERASTAB] ==
HwSettings::OPTIONALMODULES_ENABLED);
CameraStabSettings *cameraStabSettings = CameraStabSettings::GetInstance(getObjectManager());
CameraStabSettings::DataFields cameraStabData = cameraStabSettings->getData();
refreshUIValues(cameraStabData);
MixerSettings *mixerSettings = MixerSettings::GetInstance(getObjectManager());
MixerSettings::DataFields mixerSettingsData = mixerSettings->getData();
const int NUM_MIXERS = 10;
QComboBox *outputs[3] = {
QComboBox *outputs[] = {
m_camerastabilization->rollChannel,
m_camerastabilization->pitchChannel,
m_camerastabilization->yawChannel
};
const int NUM_OUTPUTS = sizeof(outputs) / sizeof(outputs[0]);
// TODO: Need to reformat object so types are an
// array themselves. This gets really awkward
quint8 * mixerTypes[NUM_MIXERS] = {
&mixerSettingsData.Mixer1Type,
&mixerSettingsData.Mixer2Type,
&mixerSettingsData.Mixer3Type,
&mixerSettingsData.Mixer4Type,
&mixerSettingsData.Mixer5Type,
&mixerSettingsData.Mixer6Type,
&mixerSettingsData.Mixer7Type,
&mixerSettingsData.Mixer8Type,
&mixerSettingsData.Mixer9Type,
&mixerSettingsData.Mixer10Type,
};
for (int i = 0; i < 3; i++)
{
// Default to none if not found. Then search for any mixer channels set to
// this
for (int i = 0; i < NUM_OUTPUTS; i++) {
// Default to none if not found.
// Then search for any mixer channels set to this
outputs[i]->setCurrentIndex(0);
for (int j = 0; j < NUM_MIXERS; j++)
if (*mixerTypes[j] == (MixerSettings::MIXER1TYPE_CAMERAROLL + i) &&
outputs[i]->currentIndex() != (j + 1))
outputs[i]->setCurrentIndex(j + 1);
}
setDirty(dirty);
ConfigTaskWidget::refreshWidgetsValues(obj);
}
void ConfigCameraStabilizationWidget::resetToDefaults()
/*
* This overridden function updates UAVObjects which have no direct relation
* to any of widgets. Aftewards it calls base class function to take care of
* other object to widget relations which were dynamically added.
*/
void ConfigCameraStabilizationWidget::updateObjectsFromWidgets()
{
CameraStabSettings cameraStabDefaults;
CameraStabSettings::DataFields defaults = cameraStabDefaults.getData();
refreshUIValues(defaults);
// Save state of the module enable checkbox first.
// Do not use setData() member on whole object, if possible, since it triggers
// unnessesary UAVObect update.
quint8 enableModule = m_camerastabilization->enableCameraStabilization->isChecked() ?
HwSettings::OPTIONALMODULES_ENABLED : HwSettings::OPTIONALMODULES_DISABLED;
HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
hwSettings->setOptionalModules(HwSettings::OPTIONALMODULES_CAMERASTAB, enableModule);
// Update mixer channels which were mapped to camera outputs in case they are
// not used for other function yet
MixerSettings *mixerSettings = MixerSettings::GetInstance(getObjectManager());
MixerSettings::DataFields mixerSettingsData = mixerSettings->getData();
// TODO: Need to reformat object so types are an
// array themselves. This gets really awkward
quint8 *mixerTypes[] = {
&mixerSettingsData.Mixer1Type,
&mixerSettingsData.Mixer2Type,
&mixerSettingsData.Mixer3Type,
&mixerSettingsData.Mixer4Type,
&mixerSettingsData.Mixer5Type,
&mixerSettingsData.Mixer6Type,
&mixerSettingsData.Mixer7Type,
&mixerSettingsData.Mixer8Type,
&mixerSettingsData.Mixer9Type,
&mixerSettingsData.Mixer10Type,
};
const int NUM_MIXERS = sizeof(mixerTypes) / sizeof(mixerTypes[0]);
QComboBox *outputs[] = {
m_camerastabilization->rollChannel,
m_camerastabilization->pitchChannel,
m_camerastabilization->yawChannel
};
const int NUM_OUTPUTS = sizeof(outputs) / sizeof(outputs[0]);
m_camerastabilization->message->setText("");
bool widgetUpdated;
do {
widgetUpdated = false;
for (int i = 0; i < NUM_OUTPUTS; i++) {
// Channel 1 is second entry, so becomes zero
int mixerNum = outputs[i]->currentIndex() - 1;
if ((mixerNum >= 0) && // Short circuit in case of none
(*mixerTypes[mixerNum] != MixerSettings::MIXER1TYPE_DISABLED) &&
(*mixerTypes[mixerNum] != MixerSettings::MIXER1TYPE_CAMERAROLL + i) ) {
// If the mixer channel already mapped to something, it should not be
// used for camera output, we reset it to none
outputs[i]->setCurrentIndex(0);
m_camerastabilization->message->setText("One of the channels is already assigned, reverted to none");
// Loop again or we may have inconsistent widget and UAVObject
widgetUpdated = true;
} else {
// Make sure no other channels have this output set
for (int j = 0; j < NUM_MIXERS; j++)
if (*mixerTypes[j] == (MixerSettings::MIXER1TYPE_CAMERAROLL + i))
*mixerTypes[j] = MixerSettings::MIXER1TYPE_DISABLED;
// If this channel is assigned to one of the outputs that is not disabled
// set it
if ((mixerNum >= 0) && (mixerNum < NUM_MIXERS))
*mixerTypes[mixerNum] = MixerSettings::MIXER1TYPE_CAMERAROLL + i;
}
}
} while(widgetUpdated);
// FIXME: Should not use setData() to prevent double updates.
// It should be refactored after the reformatting of MixerSettings UAVObject.
mixerSettings->setData(mixerSettingsData);
ConfigTaskWidget::updateObjectsFromWidgets();
}
void ConfigCameraStabilizationWidget::openHelp()
/*
* This slot function is called when "Default" button is clicked.
* All special widgets which belong to the group passed should be set here.
*/
void ConfigCameraStabilizationWidget::defaultRequestedSlot(int group)
{
QDesktopServices::openUrl( QUrl("http://wiki.openpilot.org/display/Doc/Camera+Stabilization+Configuration", QUrl::StrictMode) );
}
Q_UNUSED(group);
void ConfigCameraStabilizationWidget::enableControls(bool enable)
{
m_camerastabilization->camerastabilizationResetToDefaults->setEnabled(enable);
m_camerastabilization->camerastabilizationSaveSD->setEnabled(enable);
m_camerastabilization->camerastabilizationSaveRAM->setEnabled(enable);
// Here is the example of how to reset the state of QCheckBox. It is
// commented out because we normally don't want to reset the module
// enable state to default "disabled" (or we don't care about values at all).
// But if you want, you could use the dirtyClone() function to get default
// values of an object and then use them to set a widget state.
//
//HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
//HwSettings *hwSettingsDefault=(HwSettings*)hwSettings->dirtyClone();
//HwSettings::DataFields hwSettingsData = hwSettingsDefault->getData();
//m_camerastabilization->enableCameraStabilization->setChecked(
// hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_CAMERASTAB] == HwSettings::OPTIONALMODULES_ENABLED);
// For outputs we set them all to none, so don't use any UAVObject to get defaults
QComboBox *outputs[] = {
m_camerastabilization->rollChannel,
m_camerastabilization->pitchChannel,
m_camerastabilization->yawChannel,
};
const int NUM_OUTPUTS = sizeof(outputs) / sizeof(outputs[0]);
for (int i = 0; i < NUM_OUTPUTS; i++) {
outputs[i]->setCurrentIndex(0);
}
}
/**

View File

@ -41,21 +41,14 @@ class ConfigCameraStabilizationWidget: public ConfigTaskWidget
public:
ConfigCameraStabilizationWidget(QWidget *parent = 0);
~ConfigCameraStabilizationWidget();
private:
Ui_CameraStabilizationWidget *m_camerastabilization;
virtual void enableControls(bool enable);
void refreshUIValues(CameraStabSettings::DataFields &cameraStabData);
void refreshWidgetsValues(UAVObject *obj);
void updateObjectsFromWidgets();
private slots:
void openHelp();
void resetToDefaults();
void applySettings();
void saveSettings();
void refreshValues();
protected:
void connectUpdates();
void disconnectUpdates();
void defaultRequestedSlot(int group);
};
#endif // CONFIGCAMERASTABILIZATIONWIDGET_H

View File

@ -58,9 +58,18 @@ void ConfigTaskWidget::addWidget(QWidget * widget)
* Add an object to the management system
* @param objectName name of the object to add to the management system
*/
void ConfigTaskWidget::addUAVObject(QString objectName)
void ConfigTaskWidget::addUAVObject(QString objectName,QList<int> * reloadGroups)
{
addUAVObjectToWidgetRelation(objectName,"",NULL);
addUAVObjectToWidgetRelation(objectName,"",NULL,0,1,false,reloadGroups);
}
void ConfigTaskWidget::addUAVObject(UAVObject *objectName, QList<int> *reloadGroups)
{
QString objstr;
if(objectName)
objstr=objectName->getName();
addUAVObject(objstr, reloadGroups);
}
/**
* Add an UAVObject field to widget relation to the management system
@ -79,6 +88,17 @@ void ConfigTaskWidget::addUAVObjectToWidgetRelation(QString object, QString fiel
Q_ASSERT(_field);
addUAVObjectToWidgetRelation(object,field,widget,_field->getElementNames().indexOf(index));
}
void ConfigTaskWidget::addUAVObjectToWidgetRelation(UAVObject *obj, UAVObjectField * field, QWidget *widget, QString index)
{
QString objstr;
QString fieldstr;
if(obj)
objstr=obj->getName();
if(field)
fieldstr=field->getName();
addUAVObjectToWidgetRelation(objstr, fieldstr, widget, index);
}
/**
* Add a UAVObject field to widget relation to the management system
* @param object name of the object to add
@ -104,6 +124,28 @@ void ConfigTaskWidget::addUAVObjectToWidgetRelation(QString object, QString fiel
}
addUAVObjectToWidgetRelation(object, field, widget,index,scale,isLimited,defaultReloadGroups,instID);
}
void ConfigTaskWidget::addUAVObjectToWidgetRelation(UAVObject *obj, UAVObjectField *field, QWidget *widget, QString element, double scale, bool isLimited, QList<int> *defaultReloadGroups, quint32 instID)
{
QString objstr;
QString fieldstr;
if(obj)
objstr=obj->getName();
if(field)
fieldstr=field->getName();
addUAVObjectToWidgetRelation(objstr, fieldstr, widget, element, scale, isLimited, defaultReloadGroups, instID);
}
void ConfigTaskWidget::addUAVObjectToWidgetRelation(UAVObject * obj,UAVObjectField * field, QWidget * widget, int index,double scale,bool isLimited,QList<int>* defaultReloadGroups, quint32 instID)
{
QString objstr;
QString fieldstr;
if(obj)
objstr=obj->getName();
if(field)
fieldstr=field->getName();
addUAVObjectToWidgetRelation(objstr,fieldstr,widget,index,scale,isLimited,defaultReloadGroups,instID);
}
/**
* Add an UAVObject field to widget relation to the management system
* @param object name of the object to add
@ -149,7 +191,21 @@ void ConfigTaskWidget::addUAVObjectToWidgetRelation(QString object, QString fiel
}
if(widget==NULL)
{
// do nothing
if(defaultReloadGroups && obj)
{
foreach(int i,*defaultReloadGroups)
{
if(this->defaultReloadGroups.contains(i))
{
this->defaultReloadGroups.value(i)->append(ow);
}
else
{
this->defaultReloadGroups.insert(i,new QList<objectToWidget*>());
this->defaultReloadGroups.value(i)->append(ow);
}
}
}
}
else
{
@ -177,10 +233,6 @@ ConfigTaskWidget::~ConfigTaskWidget()
if(oTw)
delete oTw;
}
if(timeOut)
{
delete timeOut;
}
}
void ConfigTaskWidget::saveObjectToSD(UAVObject *obj)
@ -548,7 +600,7 @@ bool ConfigTaskWidget::addShadowWidget(QString object, QString field, QWidget *w
{
foreach(objectToWidget * oTw,objOfInterest)
{
if(!oTw->object || !oTw->widget)
if(!oTw->object || !oTw->widget || !oTw->field)
continue;
if(oTw->object->getName()==object && oTw->field->getName()==field && oTw->index==index && oTw->object->getInstID()==instID)
{
@ -705,10 +757,12 @@ void ConfigTaskWidget::autoLoadWidgets()
forceShadowUpdates();
foreach(objectToWidget * ow,objOfInterest)
{
qDebug()<<"Master:"<<ow->widget->objectName();
if(ow->widget)
qDebug()<<"Master:"<<ow->widget->objectName();
foreach(shadow * sh,ow->shadowsList)
{
qDebug()<<"Child"<<sh->widget->objectName();
if(sh->widget)
qDebug()<<"Child"<<sh->widget->objectName();
}
}
}
@ -777,10 +831,11 @@ void ConfigTaskWidget::addReloadButton(QPushButton *button, int buttonGroup)
void ConfigTaskWidget::defaultButtonClicked()
{
int group=sender()->property("group").toInt();
emit defaultRequested(group);
QList<objectToWidget*> * list=defaultReloadGroups.value(group);
foreach(objectToWidget * oTw,*list)
{
if(!oTw->object)
if(!oTw->object || !oTw->field)
continue;
UAVDataObject * temp=((UAVDataObject*)oTw->object)->dirtyClone();
setWidgetFromField(oTw->widget,temp->getField(oTw->field->getName()),oTw->index,oTw->scale,oTw->isLimited);
@ -791,6 +846,8 @@ void ConfigTaskWidget::defaultButtonClicked()
*/
void ConfigTaskWidget::reloadButtonClicked()
{
if(timeOut)
return;
int group=sender()->property("group").toInt();
QList<objectToWidget*> * list=defaultReloadGroups.value(group,NULL);
if(!list)
@ -816,7 +873,8 @@ void ConfigTaskWidget::reloadButtonClicked()
if(timeOut->isActive())
{
oTw->object->requestUpdate();
setWidgetFromField(oTw->widget,oTw->field,oTw->index,oTw->scale,oTw->isLimited);
if(oTw->widget)
setWidgetFromField(oTw->widget,oTw->field,oTw->index,oTw->scale,oTw->isLimited);
}
timeOut->stop();
}

View File

@ -93,12 +93,19 @@ public:
UAVObjectManager* getObjectManager();
static double listMean(QList<double> list);
void addUAVObject(QString objectName);
void addUAVObject(QString objectName, QList<int> *reloadGroups=NULL);
void addUAVObject(UAVObject * objectName, QList<int> *reloadGroups=NULL);
void addWidget(QWidget * widget);
void addUAVObjectToWidgetRelation(QString object,QString field,QWidget * widget,int index=0,double scale=1,bool isLimited=false,QList<int>* defaultReloadGroups=0,quint32 instID=0);
void addUAVObjectToWidgetRelation(UAVObject *obj, UAVObjectField * field, QWidget *widget, int index=0, double scale=1, bool isLimited=false, QList<int> *defaultReloadGroups=0, quint32 instID=0);
void addUAVObjectToWidgetRelation(QString object,QString field,QWidget * widget,QString element,double scale,bool isLimited=false,QList<int>* defaultReloadGroups=0,quint32 instID=0);
void addUAVObjectToWidgetRelation(UAVObject *obj, UAVObjectField * field,QWidget * widget,QString element,double scale,bool isLimited=false,QList<int>* defaultReloadGroups=0,quint32 instID=0);
void addUAVObjectToWidgetRelation(QString object, QString field, QWidget *widget, QString index);
void addUAVObjectToWidgetRelation(UAVObject *obj, UAVObjectField * field, QWidget *widget, QString index);
//BUTTONS//
void addApplySaveButtons(QPushButton * update,QPushButton * save);
@ -139,6 +146,7 @@ signals:
void autoPilotConnected();
//fired when the autopilot disconnects
void autoPilotDisconnected();
void defaultRequested(int group);
private slots:
void objectUpdated(UAVObject*);
void defaultButtonClicked();

View File

@ -151,6 +151,7 @@ void smartSaveButton::setObjects(QList<UAVDataObject *> list)
void smartSaveButton::addObject(UAVDataObject * obj)
{
Q_ASSERT(obj);
if(!objects.contains(obj))
objects.append(obj);
}