1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-05 21:52:10 +01:00

Merge remote-tracking branch 'origin/ccfly/outputchannelform' into next

This commit is contained in:
James Cotton 2011-11-25 10:48:41 -06:00
commit 60664f6a26
7 changed files with 785 additions and 1347 deletions

View File

@ -1,7 +1,6 @@
TEMPLATE = lib TEMPLATE = lib
TARGET = Config TARGET = Config
QT += svg QT += svg
include(../../openpilotgcsplugin.pri) include(../../openpilotgcsplugin.pri)
include(../../libs/utils/utils.pri) include(../../libs/utils/utils.pri)
include(../../plugins/uavtalk/uavtalk.pri) include(../../plugins/uavtalk/uavtalk.pri)
@ -10,9 +9,7 @@ include(../../plugins/uavobjects/uavobjects.pri)
include(../../plugins/uavobjectutil/uavobjectutil.pri) include(../../plugins/uavobjectutil/uavobjectutil.pri)
include(../../plugins/uavsettingsimportexport/uavsettingsimportexport.pri) include(../../plugins/uavsettingsimportexport/uavsettingsimportexport.pri)
INCLUDEPATH += ../../libs/eigen INCLUDEPATH += ../../libs/eigen
OTHER_FILES += Config.pluginspec OTHER_FILES += Config.pluginspec
HEADERS += configplugin.h \ HEADERS += configplugin.h \
configgadgetconfiguration.h \ configgadgetconfiguration.h \
configgadgetwidget.h \ configgadgetwidget.h \
@ -39,8 +36,8 @@ HEADERS += configplugin.h \
smartsavebutton.h \ smartsavebutton.h \
defaulthwsettingswidget.h \ defaulthwsettingswidget.h \
inputchannelform.h \ inputchannelform.h \
configcamerastabilizationwidget.h configcamerastabilizationwidget.h \
outputchannelform.h
SOURCES += configplugin.cpp \ SOURCES += configplugin.cpp \
configgadgetconfiguration.cpp \ configgadgetconfiguration.cpp \
configgadgetwidget.cpp \ configgadgetwidget.cpp \
@ -69,10 +66,9 @@ SOURCES += configplugin.cpp \
smartsavebutton.cpp \ smartsavebutton.cpp \
defaulthwsettingswidget.cpp \ defaulthwsettingswidget.cpp \
inputchannelform.cpp \ inputchannelform.cpp \
configcamerastabilizationwidget.cpp configcamerastabilizationwidget.cpp \
outputchannelform.cpp
FORMS += \ FORMS += airframe.ui \
airframe.ui \
cc_hw_settings.ui \ cc_hw_settings.ui \
pro_hw_settings.ui \ pro_hw_settings.ui \
ahrs.ui \ ahrs.ui \
@ -84,10 +80,6 @@ FORMS += \
defaultattitude.ui \ defaultattitude.ui \
defaulthwsettings.ui \ defaulthwsettings.ui \
inputchannelform.ui \ inputchannelform.ui \
camerastabilization.ui camerastabilization.ui \
outputchannelform.ui
RESOURCES += configgadget.qrc RESOURCES += configgadget.qrc

View File

@ -1,13 +1,13 @@
/** /**
****************************************************************************** ******************************************************************************
* *
* @file configservowidget.cpp * @file configoutputwidget.cpp
* @author E. Lafargue & The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @author E. Lafargue & The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins * @addtogroup GCSPlugins GCS Plugins
* @{ * @{
* @addtogroup ConfigPlugin Config Plugin * @addtogroup ConfigPlugin Config Plugin
* @{ * @{
* @brief Servo input/output configuration panel for the config gadget * @brief Servo output configuration panel for the config gadget
*****************************************************************************/ *****************************************************************************/
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -26,6 +26,7 @@
*/ */
#include "configoutputwidget.h" #include "configoutputwidget.h"
#include "outputchannelform.h"
#include "uavtalk/telemetrymanager.h" #include "uavtalk/telemetrymanager.h"
@ -39,6 +40,7 @@
#include <QDesktopServices> #include <QDesktopServices>
#include <QUrl> #include <QUrl>
#include "actuatorcommand.h" #include "actuatorcommand.h"
#include "actuatorsettings.h"
#include "systemalarms.h" #include "systemalarms.h"
#include "uavsettingsimportexport/uavsettingsimportexportfactory.h" #include "uavsettingsimportexport/uavsettingsimportexportfactory.h"
@ -57,99 +59,20 @@ ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(paren
setupButtons(m_config->saveRCOutputToRAM,m_config->saveRCOutputToSD); setupButtons(m_config->saveRCOutputToRAM,m_config->saveRCOutputToSD);
addUAVObject("ActuatorSettings"); addUAVObject("ActuatorSettings");
// First of all, put all the channel widgets into lists, so that we can // NOTE: we have channel indices from 0 to 9, but the convention for OP is Channel 1 to Channel 10.
// manipulate those:
// NOTE: for historical reasons, we have objects below called ch0 to ch7, but the convention for OP is Channel 1 to Channel 8.
outLabels << m_config->ch0OutValue
<< m_config->ch1OutValue
<< m_config->ch2OutValue
<< m_config->ch3OutValue
<< m_config->ch4OutValue
<< m_config->ch5OutValue
<< m_config->ch6OutValue
<< m_config->ch7OutValue
<< m_config->ch8OutValue
<< m_config->ch9OutValue;
outSliders << m_config->ch0OutSlider
<< m_config->ch1OutSlider
<< m_config->ch2OutSlider
<< m_config->ch3OutSlider
<< m_config->ch4OutSlider
<< m_config->ch5OutSlider
<< m_config->ch6OutSlider
<< m_config->ch7OutSlider
<< m_config->ch8OutSlider
<< m_config->ch9OutSlider;
outMin << m_config->ch0OutMin
<< m_config->ch1OutMin
<< m_config->ch2OutMin
<< m_config->ch3OutMin
<< m_config->ch4OutMin
<< m_config->ch5OutMin
<< m_config->ch6OutMin
<< m_config->ch7OutMin
<< m_config->ch8OutMin
<< m_config->ch9OutMin;
outMax << m_config->ch0OutMax
<< m_config->ch1OutMax
<< m_config->ch2OutMax
<< m_config->ch3OutMax
<< m_config->ch4OutMax
<< m_config->ch5OutMax
<< m_config->ch6OutMax
<< m_config->ch7OutMax
<< m_config->ch8OutMax
<< m_config->ch9OutMax;
reversals << m_config->ch0Rev
<< m_config->ch1Rev
<< m_config->ch2Rev
<< m_config->ch3Rev
<< m_config->ch4Rev
<< m_config->ch5Rev
<< m_config->ch6Rev
<< m_config->ch7Rev
<< m_config->ch8Rev
<< m_config->ch9Rev;
links << m_config->ch0Link
<< m_config->ch1Link
<< m_config->ch2Link
<< m_config->ch3Link
<< m_config->ch4Link
<< m_config->ch5Link
<< m_config->ch6Link
<< m_config->ch7Link
<< m_config->ch8Link
<< m_config->ch9Link;
// Register for ActuatorSettings changes: // Register for ActuatorSettings changes:
for (int i = 0; i < ActuatorCommand::CHANNEL_NUMELEM; i++) { for (unsigned int i = 0; i < ActuatorCommand::CHANNEL_NUMELEM; i++)
connect(outMin[i], SIGNAL(editingFinished()), this, SLOT(setChOutRange())); {
connect(outMax[i], SIGNAL(editingFinished()), this, SLOT(setChOutRange())); OutputChannelForm *form = new OutputChannelForm(i, this, i==0);
connect(reversals[i], SIGNAL(toggled(bool)), this, SLOT(reverseChannel(bool))); connect(m_config->channelOutTest, SIGNAL(toggled(bool)),
// Now connect the channel out sliders to our signal to send updates in test mode form, SLOT(enableChannelTest(bool)));
connect(outSliders[i], SIGNAL(valueChanged(int)), this, SLOT(sendChannelTest(int))); connect(form, SIGNAL(channelChanged(int,int)),
this, SLOT(sendChannelTest(int,int)));
addWidget(outMin[i]); m_config->channelLayout->addWidget(form);
addWidget(outMax[i]);
addWidget(reversals[i]);
addWidget(outSliders[i]);
addWidget(links[i]);
} }
connect(m_config->channelOutTest, SIGNAL(toggled(bool)), this, SLOT(runChannelTests(bool))); connect(m_config->channelOutTest, SIGNAL(toggled(bool)), this, SLOT(runChannelTests(bool)));
for (int i = 0; i < links.count(); i++)
links[i]->setChecked(false);
for (int i = 0; i < links.count(); i++)
connect(links[i], SIGNAL(toggled(bool)), this, SLOT(linkToggled(bool)));
refreshWidgetsValues(); refreshWidgetsValues();
firstUpdate = true; firstUpdate = true;
@ -179,37 +102,6 @@ ConfigOutputWidget::~ConfigOutputWidget()
// ************************************ // ************************************
/**
Toggles the channel linked state for use in testing mode
*/
void ConfigOutputWidget::linkToggled(bool state)
{
Q_UNUSED(state)
// find the minimum slider value for the linked ones
int min = 10000;
int linked_count = 0;
for (int i = 0; i < outSliders.count(); i++)
{
if (!links[i]->checkState()) continue;
int value = outSliders[i]->value();
if (min > value) min = value;
linked_count++;
}
if (linked_count <= 0)
return; // no linked channels
if (!m_config->channelOutTest->checkState())
return; // we are not in Test Output mode
// set the linked channels to the same value
for (int i = 0; i < outSliders.count(); i++)
{
if (!links[i]->checkState()) continue;
outSliders[i]->setValue(min);
}
}
/** /**
Toggles the channel testing mode by making the GCS take over Toggles the channel testing mode by making the GCS take over
the ActuatorCommand objects the ActuatorCommand objects
@ -257,79 +149,43 @@ void ConfigOutputWidget::runChannelTests(bool state)
mdata.gcsTelemetryAcked = false; mdata.gcsTelemetryAcked = false;
mdata.gcsTelemetryUpdateMode = UAVObject::UPDATEMODE_ONCHANGE; mdata.gcsTelemetryUpdateMode = UAVObject::UPDATEMODE_ONCHANGE;
mdata.gcsTelemetryUpdatePeriod = 100; mdata.gcsTelemetryUpdatePeriod = 100;
// Prevent stupid users from touching the minimum & maximum ranges while
// moving the sliders. Thanks Ivan for the tip :)
foreach (QSpinBox* box, outMin) {
box->setEnabled(false);
}
foreach (QSpinBox* box, outMax) {
box->setEnabled(false);
}
foreach (QCheckBox* box, reversals) {
box->setEnabled(false);
}
} }
else else
{ {
wasItMe=false; wasItMe=false;
mdata = accInitialData; // Restore metadata mdata = accInitialData; // Restore metadata
foreach (QSpinBox* box, outMin) {
box->setEnabled(true);
}
foreach (QSpinBox* box, outMax) {
box->setEnabled(true);
}
foreach (QCheckBox* box, reversals) {
box->setEnabled(true);
}
} }
obj->setMetadata(mdata); obj->setMetadata(mdata);
obj->updated(); obj->updated();
} }
OutputChannelForm* ConfigOutputWidget::getOutputChannelForm(const int index) const
{
QList<OutputChannelForm*> outputChannelForms = findChildren<OutputChannelForm*>();
foreach(OutputChannelForm *outputChannelForm, outputChannelForms)
{
if( outputChannelForm->index() == index)
return outputChannelForm;
}
// no OutputChannelForm found with given index
return NULL;
}
/** /**
* Set the label for a channel output assignement * Set the label for a channel output assignement
*/ */
void ConfigOutputWidget::assignOutputChannel(UAVDataObject *obj, QString str) void ConfigOutputWidget::assignOutputChannel(UAVDataObject *obj, QString str)
{ {
//FIXME: use signal/ slot approach
UAVObjectField* field = obj->getField(str); UAVObjectField* field = obj->getField(str);
QStringList options = field->getOptions(); QStringList options = field->getOptions();
switch (options.indexOf(field->getValue().toString())) { int index = options.indexOf(field->getValue().toString());
case 0:
m_config->ch0Output->setText(str); OutputChannelForm *outputChannelForm = getOutputChannelForm(index);
break; if(outputChannelForm)
case 1: outputChannelForm->setAssignment(str);
m_config->ch1Output->setText(str);
break;
case 2:
m_config->ch2Output->setText(str);
break;
case 3:
m_config->ch3Output->setText(str);
break;
case 4:
m_config->ch4Output->setText(str);
break;
case 5:
m_config->ch5Output->setText(str);
break;
case 6:
m_config->ch6Output->setText(str);
break;
case 7:
m_config->ch7Output->setText(str);
break;
case 8:
m_config->ch8Output->setText(str);
break;
case 9:
m_config->ch9Output->setText(str);
break;
}
} }
/** /**
@ -337,63 +193,36 @@ void ConfigOutputWidget::assignOutputChannel(UAVDataObject *obj, QString str)
*/ */
void ConfigOutputWidget::setSpinningArmed(bool val) void ConfigOutputWidget::setSpinningArmed(bool val)
{ {
UAVDataObject *obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorSettings"))); ActuatorSettings *actuatorSettings = ActuatorSettings::GetInstance(getObjectManager());
if (!obj) return; Q_ASSERT(actuatorSettings);
UAVObjectField *field = obj->getField("MotorsSpinWhileArmed"); ActuatorSettings::DataFields actuatorSettingsData = actuatorSettings->getData();
if (!field) return;
if(val) if(val)
field->setValue("TRUE"); actuatorSettingsData.MotorsSpinWhileArmed = ActuatorSettings::MOTORSSPINWHILEARMED_TRUE;
else else
field->setValue("FALSE"); actuatorSettingsData.MotorsSpinWhileArmed = ActuatorSettings::MOTORSSPINWHILEARMED_FALSE;
// Apply settings
actuatorSettings->setData(actuatorSettingsData);
} }
/** /**
Sends the channel value to the UAV to move the servo. Sends the channel value to the UAV to move the servo.
Returns immediately if we are not in testing mode Returns immediately if we are not in testing mode
*/ */
void ConfigOutputWidget::sendChannelTest(int value) void ConfigOutputWidget::sendChannelTest(int index, int value)
{ {
int in_value = value;
QSlider *ob = (QSlider *)QObject::sender();
if (!ob) return;
int index = outSliders.indexOf(ob);
if (index < 0) return;
if (reversals[index]->isChecked())
value = outMin[index]->value() - value + outMax[index]->value(); // the chsnnel is reversed
// update the label
outLabels[index]->setText(QString::number(value));
if (links[index]->checkState())
{ // the channel is linked to other channels
// set the linked channels to the same value
for (int i = 0; i < outSliders.count(); i++)
{
if (i == index) continue;
if (!links[i]->checkState()) continue;
int val = in_value;
if (val < outSliders[i]->minimum()) val = outSliders[i]->minimum();
if (val > outSliders[i]->maximum()) val = outSliders[i]->maximum();
if (outSliders[i]->value() == val) continue;
outSliders[i]->setValue(val);
outLabels[i]->setText(QString::number(val));
}
}
if (!m_config->channelOutTest->isChecked()) if (!m_config->channelOutTest->isChecked())
return; return;
UAVDataObject *obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorCommand"))); if(index < 0 || (unsigned)index >= ActuatorCommand::CHANNEL_NUMELEM)
if (!obj) return; return;
UAVObjectField *channel = obj->getField("Channel");
if (!channel) return; ActuatorCommand *actuatorCommand = ActuatorCommand::GetInstance(getObjectManager());
channel->setValue(value, index); Q_ASSERT(actuatorCommand);
obj->updated(); ActuatorCommand::DataFields actuatorCommandFields = actuatorCommand->getData();
actuatorCommandFields.Channel[index] = value;
actuatorCommand->setData(actuatorCommandFields);
} }
@ -408,12 +237,19 @@ void ConfigOutputWidget::sendChannelTest(int value)
void ConfigOutputWidget::refreshWidgetsValues() void ConfigOutputWidget::refreshWidgetsValues()
{ {
bool dirty=isDirty(); bool dirty=isDirty();
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
// Reset all channel assignements: // Reset all channel assignements:
for (int i = 0; i < ActuatorCommand::CHANNEL_NUMELEM; i++) QList<OutputChannelForm*> outputChannelForms = findChildren<OutputChannelForm*>();
outLabels[i]->setText("-"); foreach(OutputChannelForm *outputChannelForm, outputChannelForms)
{
outputChannelForm->setAssignment("-");
}
// FIXME: Use static accessor method for retrieving channel assignments
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
Q_ASSERT(pm);
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
Q_ASSERT(objManager);
// Get the channel assignements: // Get the channel assignements:
UAVDataObject * obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ActuatorSettings"))); UAVDataObject * obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ActuatorSettings")));
@ -425,15 +261,17 @@ void ConfigOutputWidget::refreshWidgetsValues()
} }
} }
ActuatorSettings *actuatorSettings = ActuatorSettings::GetInstance(getObjectManager());
Q_ASSERT(actuatorSettings);
ActuatorSettings::DataFields actuatorSettingsData = actuatorSettings->getData();
// Get the SpinWhileArmed setting // Get the SpinWhileArmed setting
UAVObjectField *field = obj->getField(QString("MotorsSpinWhileArmed")); m_config->spinningArmed->setChecked(actuatorSettingsData.MotorsSpinWhileArmed == ActuatorSettings::MOTORSSPINWHILEARMED_TRUE);
m_config->spinningArmed->setChecked(field->getValue().toString().contains("TRUE"));
// Get Output rates for both banks // Get Output rates for both banks
field = obj->getField(QString("ChannelUpdateFreq")); m_config->outputRate1->setValue(actuatorSettingsData.ChannelUpdateFreq[0]);
m_config->outputRate2->setValue(actuatorSettingsData.ChannelUpdateFreq[1]);
UAVObjectUtilManager* utilMngr = pm->getObject<UAVObjectUtilManager>(); UAVObjectUtilManager* utilMngr = pm->getObject<UAVObjectUtilManager>();
m_config->outputRate1->setValue(field->getValue(0).toInt());
m_config->outputRate2->setValue(field->getValue(1).toInt());
if (utilMngr) { if (utilMngr) {
int board = utilMngr->getBoardModel(); int board = utilMngr->getBoardModel();
if ((board & 0xff00) == 1024) { if ((board & 0xff00) == 1024) {
@ -446,8 +284,8 @@ void ConfigOutputWidget::refreshWidgetsValues()
m_config->outputRate2->setEnabled(true); m_config->outputRate2->setEnabled(true);
m_config->outputRate3->setEnabled(true); m_config->outputRate3->setEnabled(true);
m_config->outputRate4->setEnabled(true); m_config->outputRate4->setEnabled(true);
m_config->outputRate3->setValue(field->getValue(2).toInt()); m_config->outputRate3->setValue(actuatorSettingsData.ChannelUpdateFreq[2]);
m_config->outputRate4->setValue(field->getValue(3).toInt()); m_config->outputRate4->setValue(actuatorSettingsData.ChannelUpdateFreq[3]);
} else if ((board & 0xff00) == 256 ) { } else if ((board & 0xff00) == 256 ) {
// Mainboard family // Mainboard family
m_config->outputRate1->setEnabled(true); m_config->outputRate1->setEnabled(true);
@ -463,34 +301,18 @@ void ConfigOutputWidget::refreshWidgetsValues()
} }
} }
// Get Channel ranges: // Get Channel ranges:
for (int i=0;i<ActuatorCommand::CHANNEL_NUMELEM;i++) { foreach(OutputChannelForm *outputChannelForm, outputChannelForms)
field = obj->getField(QString("ChannelMin")); {
int minValue = field->getValue(i).toInt(); int minValue = actuatorSettingsData.ChannelMin[outputChannelForm->index()];
outMin[i]->setValue(minValue); int maxValue = actuatorSettingsData.ChannelMax[outputChannelForm->index()];
field = obj->getField(QString("ChannelMax")); outputChannelForm->minmax(minValue, maxValue);
int maxValue = field->getValue(i).toInt();
outMax[i]->setValue(maxValue); int neutral = actuatorSettingsData.ChannelNeutral[outputChannelForm->index()];
if (maxValue>minValue) { outputChannelForm->neutral(neutral);
outSliders[i]->setMinimum(minValue);
outSliders[i]->setMaximum(maxValue);
reversals[i]->setChecked(false);
} else {
outSliders[i]->setMinimum(maxValue);
outSliders[i]->setMaximum(minValue);
reversals[i]->setChecked(true);
}
} }
field = obj->getField(QString("ChannelNeutral"));
for (int i=0; i<ActuatorCommand::CHANNEL_NUMELEM; i++) {
int value = field->getValue(i).toInt();
outSliders[i]->setValue(value);
outLabels[i]->setText(QString::number(value));
}
setDirty(dirty); setDirty(dirty);
} }
/** /**
@ -498,105 +320,27 @@ void ConfigOutputWidget::refreshWidgetsValues()
*/ */
void ConfigOutputWidget::updateObjectsFromWidgets() void ConfigOutputWidget::updateObjectsFromWidgets()
{ {
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); ActuatorSettings *actuatorSettings = ActuatorSettings::GetInstance(getObjectManager());
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>(); Q_ASSERT(actuatorSettings);
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ActuatorSettings"))); ActuatorSettings::DataFields actuatorSettingsData = actuatorSettings->getData();
Q_ASSERT(obj);
// Now send channel ranges: // Set channel ranges
UAVObjectField * field = obj->getField(QString("ChannelMax")); QList<OutputChannelForm*> outputChannelForms = findChildren<OutputChannelForm*>();
for (int i = 0; i < ActuatorCommand::CHANNEL_NUMELEM; i++) { foreach(OutputChannelForm *outputChannelForm, outputChannelForms)
field->setValue(outMax[i]->value(),i);
}
field = obj->getField(QString("ChannelMin"));
for (int i = 0; i < ActuatorCommand::CHANNEL_NUMELEM; i++) {
field->setValue(outMin[i]->value(),i);
}
field = obj->getField(QString("ChannelNeutral"));
for (int i = 0; i < ActuatorCommand::CHANNEL_NUMELEM; i++) {
field->setValue(outSliders[i]->value(),i);
}
field = obj->getField(QString("ChannelUpdateFreq"));
field->setValue(m_config->outputRate1->value(),0);
field->setValue(m_config->outputRate2->value(),1);
field->setValue(m_config->outputRate3->value(),2);
field->setValue(m_config->outputRate4->value(),3);
}
/**
Sets the minimum/maximum value of the channel 0 to seven output sliders.
Have to do it here because setMinimum is not a slot.
One added trick: if the slider is at its min when the value
is changed, then keep it on the min.
*/
void ConfigOutputWidget::setChOutRange()
{ {
QSpinBox *spinbox = (QSpinBox*)QObject::sender(); actuatorSettingsData.ChannelMax[outputChannelForm->index()] = outputChannelForm->max();
actuatorSettingsData.ChannelMin[outputChannelForm->index()] = outputChannelForm->min();
int index = outMin.indexOf(spinbox); // This is the channel number actuatorSettingsData.ChannelNeutral[outputChannelForm->index()] = outputChannelForm->neutral();
if (index < 0)
index = outMax.indexOf(spinbox); // We can't know if the signal came from min or max
QSlider *slider = outSliders[index];
int oldMini = slider->minimum();
// int oldMaxi = slider->maximum();
if (outMin[index]->value()<outMax[index]->value())
{
slider->setRange(outMin[index]->value(), outMax[index]->value());
reversals[index]->setChecked(false);
}
else
{
slider->setRange(outMax[index]->value(), outMin[index]->value());
reversals[index]->setChecked(true);
} }
if (slider->value() == oldMini) // Set update rates
slider->setValue(slider->minimum()); actuatorSettingsData.ChannelUpdateFreq[0] = m_config->outputRate1->value();
actuatorSettingsData.ChannelUpdateFreq[1] = m_config->outputRate2->value();
// if (slider->value() == oldMaxi) actuatorSettingsData.ChannelUpdateFreq[2] = m_config->outputRate3->value();
// slider->setValue(slider->maximum()); // this can be dangerous if it happens to be controlling a motor at the time! actuatorSettingsData.ChannelUpdateFreq[3] = m_config->outputRate4->value();
}
/**
Reverses the channel when the checkbox is clicked
*/
void ConfigOutputWidget::reverseChannel(bool state)
{
QCheckBox *checkbox = (QCheckBox*)QObject::sender();
int index = reversals.indexOf(checkbox); // This is the channel number
// Sanity check: if state became true, make sure the Maxvalue was higher than Minvalue
// the situations below can happen!
if (state && (outMax[index]->value()<outMin[index]->value()))
return;
if (!state && (outMax[index]->value()>outMin[index]->value()))
return;
// Now, swap the min & max values (only on the spinboxes, the slider
// does not change!
int temp = outMax[index]->value();
outMax[index]->setValue(outMin[index]->value());
outMin[index]->setValue(temp);
// Also update the channel value
// This is a trick to force the slider to update its value and
// emit the right signal itself, because our sendChannelTest(int) method
// relies on the object sender's identity.
if (outSliders[index]->value()<outSliders[index]->maximum()) {
outSliders[index]->setValue(outSliders[index]->value()+1);
outSliders[index]->setValue(outSliders[index]->value()-1);
} else {
outSliders[index]->setValue(outSliders[index]->value()-1);
outSliders[index]->setValue(outSliders[index]->value()+1);
}
// Apply settings
actuatorSettings->setData(actuatorSettingsData);
} }
void ConfigOutputWidget::openHelp() void ConfigOutputWidget::openHelp()

View File

@ -1,13 +1,13 @@
/** /**
****************************************************************************** ******************************************************************************
* *
* @file configservowidget.h * @file configoutputwidget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins * @addtogroup GCSPlugins GCS Plugins
* @{ * @{
* @addtogroup ConfigPlugin Config Plugin * @addtogroup ConfigPlugin Config Plugin
* @{ * @{
* @brief Servo input/output configuration panel for the config gadget * @brief Servo output configuration panel for the config gadget
*****************************************************************************/ *****************************************************************************/
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -37,6 +37,7 @@
#include <QList> #include <QList>
class Ui_OutputWidget; class Ui_OutputWidget;
class OutputChannelForm;
class ConfigOutputWidget: public ConfigTaskWidget class ConfigOutputWidget: public ConfigTaskWidget
{ {
@ -55,18 +56,12 @@ private:
void assignChannel(UAVDataObject *obj, QString str); void assignChannel(UAVDataObject *obj, QString str);
void assignOutputChannel(UAVDataObject *obj, QString str); void assignOutputChannel(UAVDataObject *obj, QString str);
OutputChannelForm* getOutputChannelForm(const int index) const;
int mccDataRate; int mccDataRate;
UAVObject::Metadata accInitialData; UAVObject::Metadata accInitialData;
QList<QSlider*> outSliders;
QList<QSpinBox*> outMin;
QList<QSpinBox*> outMax;
QList<QCheckBox*> reversals;
QList<QCheckBox*> links;
QList<QLabel*> outLabels;
bool firstUpdate; bool firstUpdate;
bool wasItMe; bool wasItMe;
@ -76,10 +71,7 @@ private slots:
virtual void refreshWidgetsValues(); virtual void refreshWidgetsValues();
void updateObjectsFromWidgets(); void updateObjectsFromWidgets();
void runChannelTests(bool state); void runChannelTests(bool state);
void sendChannelTest(int value); void sendChannelTest(int index, int value);
void setChOutRange();
void reverseChannel(bool state);
void linkToggled(bool state);
void setSpinningArmed(bool val); void setSpinningArmed(bool val);
void openHelp(); void openHelp();
}; };

View File

@ -210,933 +210,7 @@ Leave at 50Hz for fixed wing.</string>
</widget> </widget>
</item> </item>
<item> <item>
<layout class="QGridLayout" name="gridLayout_2"> <layout class="QVBoxLayout" name="channelLayout"/>
<item row="1" column="0">
<widget class="QLabel" name="actuator0Label">
<property name="text">
<string>Channel 1:</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="ch0OutMin">
<property name="enabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Minimum PWM value, beware of not overdriving your servo.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QSlider" name="ch0OutSlider">
<property name="enabled">
<bool>true</bool>
</property>
<property name="maximum">
<number>9999</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QSpinBox" name="ch0OutMax">
<property name="enabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Maximum PWM value, beware of not overdriving your servo.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="1" column="5">
<widget class="QLabel" name="ch0OutValue">
<property name="toolTip">
<string>Current value of slider.</string>
</property>
<property name="text">
<string>0000</string>
</property>
</widget>
</item>
<item row="1" column="6">
<widget class="QCheckBox" name="ch0Rev">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'FreeSans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Check to invert the channel.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="7">
<widget class="QCheckBox" name="ch0Link">
<property name="toolTip">
<string>Only used with Test Output mode</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="7">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Link</string>
</property>
</widget>
</item>
<item row="0" column="6">
<widget class="QLabel" name="label">
<property name="text">
<string>Rev.</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="actuator1Label">
<property name="text">
<string>Channel 2:</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QSpinBox" name="ch1OutMin">
<property name="enabled">
<bool>true</bool>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QSlider" name="ch1OutSlider">
<property name="enabled">
<bool>true</bool>
</property>
<property name="maximum">
<number>9999</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="QSpinBox" name="ch1OutMax">
<property name="enabled">
<bool>true</bool>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="2" column="5">
<widget class="QLabel" name="ch1OutValue">
<property name="text">
<string>0000</string>
</property>
</widget>
</item>
<item row="2" column="6">
<widget class="QCheckBox" name="ch1Rev">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'FreeSans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Check to invert the channel.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="7">
<widget class="QCheckBox" name="ch1Link">
<property name="toolTip">
<string>Only used with Test Output mode</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="actuator2Label">
<property name="text">
<string>Channel 3:</string>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QSpinBox" name="ch2OutMin">
<property name="enabled">
<bool>true</bool>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QSlider" name="ch2OutSlider">
<property name="enabled">
<bool>true</bool>
</property>
<property name="maximum">
<number>9999</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="3" column="4">
<widget class="QSpinBox" name="ch2OutMax">
<property name="enabled">
<bool>true</bool>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="3" column="5">
<widget class="QLabel" name="ch2OutValue">
<property name="text">
<string>0000</string>
</property>
</widget>
</item>
<item row="3" column="6">
<widget class="QCheckBox" name="ch2Rev">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'FreeSans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Check to invert the channel.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="7">
<widget class="QCheckBox" name="ch2Link">
<property name="toolTip">
<string>Only used with Test Output mode</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="actuator3Label">
<property name="text">
<string>Channel 4:</string>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QSpinBox" name="ch3OutMin">
<property name="enabled">
<bool>true</bool>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="4" column="3">
<widget class="QSlider" name="ch3OutSlider">
<property name="enabled">
<bool>true</bool>
</property>
<property name="maximum">
<number>9999</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="4" column="4">
<widget class="QSpinBox" name="ch3OutMax">
<property name="enabled">
<bool>true</bool>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="4" column="5">
<widget class="QLabel" name="ch3OutValue">
<property name="text">
<string>0000</string>
</property>
</widget>
</item>
<item row="4" column="6">
<widget class="QCheckBox" name="ch3Rev">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'FreeSans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Check to invert the channel.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="4" column="7">
<widget class="QCheckBox" name="ch3Link">
<property name="toolTip">
<string>Only used with Test Output mode</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="actuator4Label">
<property name="text">
<string>Channel 5:</string>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QSpinBox" name="ch4OutMin">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="5" column="3">
<widget class="QSlider" name="ch4OutSlider">
<property name="maximum">
<number>9999</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="5" column="4">
<widget class="QSpinBox" name="ch4OutMax">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="5" column="5">
<widget class="QLabel" name="ch4OutValue">
<property name="text">
<string>0000</string>
</property>
</widget>
</item>
<item row="5" column="6">
<widget class="QCheckBox" name="ch4Rev">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'FreeSans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Check to invert the channel.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="5" column="7">
<widget class="QCheckBox" name="ch4Link">
<property name="toolTip">
<string>Only used with Test Output mode</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="actuator5Label">
<property name="text">
<string>Channel 6:</string>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QSpinBox" name="ch5OutMin">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="6" column="3">
<widget class="QSlider" name="ch5OutSlider">
<property name="maximum">
<number>9999</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="6" column="4">
<widget class="QSpinBox" name="ch5OutMax">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="6" column="5">
<widget class="QLabel" name="ch5OutValue">
<property name="text">
<string>0000</string>
</property>
</widget>
</item>
<item row="6" column="6">
<widget class="QCheckBox" name="ch5Rev">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'FreeSans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Check to invert the channel.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="6" column="7">
<widget class="QCheckBox" name="ch5Link">
<property name="toolTip">
<string>Only used with Test Output mode</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="actuator6Label">
<property name="text">
<string>Channel 7:</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="actuator7Label">
<property name="text">
<string>Channel 8:</string>
</property>
</widget>
</item>
<item row="7" column="2">
<widget class="QSpinBox" name="ch6OutMin">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="7" column="3">
<widget class="QSlider" name="ch6OutSlider">
<property name="maximum">
<number>9999</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="7" column="4">
<widget class="QSpinBox" name="ch6OutMax">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="7" column="5">
<widget class="QLabel" name="ch6OutValue">
<property name="text">
<string>0000</string>
</property>
</widget>
</item>
<item row="7" column="6">
<widget class="QCheckBox" name="ch6Rev">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'FreeSans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Check to invert the channel.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="7" column="7">
<widget class="QCheckBox" name="ch6Link">
<property name="toolTip">
<string>Only used with Test Output mode</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="8" column="2">
<widget class="QSpinBox" name="ch7OutMin">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="8" column="3">
<widget class="QSlider" name="ch7OutSlider">
<property name="maximum">
<number>9999</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="8" column="4">
<widget class="QSpinBox" name="ch7OutMax">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="8" column="5">
<widget class="QLabel" name="ch7OutValue">
<property name="text">
<string>0000</string>
</property>
</widget>
</item>
<item row="8" column="6">
<widget class="QCheckBox" name="ch7Rev">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'FreeSans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Check to invert the channel.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="8" column="7">
<widget class="QCheckBox" name="ch7Link">
<property name="toolTip">
<string>Only used with Test Output mode</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="ch0Output">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>-</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="ch1Output">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>-</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="ch2Output">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>-</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="ch3Output">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>-</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="ch4Output">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>-</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLabel" name="ch5Output">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>-</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QLabel" name="ch6Output">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>-</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QLabel" name="ch7Output">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>-</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Assignment</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Min</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Neutral (slowest for motor)</string>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Max</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="actuator8Label">
<property name="text">
<string>Channel 9:</string>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QLabel" name="actuator9Label">
<property name="text">
<string>Channel 10:</string>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QLabel" name="ch8Output">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>-</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QLabel" name="ch9Output">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>-</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="9" column="2">
<widget class="QSpinBox" name="ch8OutMin">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="10" column="2">
<widget class="QSpinBox" name="ch9OutMin">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="9" column="3">
<widget class="QSlider" name="ch8OutSlider">
<property name="maximum">
<number>9999</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="10" column="3">
<widget class="QSlider" name="ch9OutSlider">
<property name="maximum">
<number>9999</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="9" column="4">
<widget class="QSpinBox" name="ch8OutMax">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="10" column="4">
<widget class="QSpinBox" name="ch9OutMax">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="9" column="5">
<widget class="QLabel" name="ch8OutValue">
<property name="text">
<string>0000</string>
</property>
</widget>
</item>
<item row="10" column="5">
<widget class="QLabel" name="ch9OutValue">
<property name="text">
<string>0000</string>
</property>
</widget>
</item>
<item row="9" column="6">
<widget class="QCheckBox" name="ch8Rev">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'FreeSans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Check to invert the channel.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="10" column="6">
<widget class="QCheckBox" name="ch9Rev">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'FreeSans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Check to invert the channel.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="9" column="7">
<widget class="QCheckBox" name="ch8Link">
<property name="toolTip">
<string>Only used with Test Output mode</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="10" column="7">
<widget class="QCheckBox" name="ch9Link">
<property name="toolTip">
<string>Only used with Test Output mode</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item> </item>
<item> <item>
<spacer name="verticalSpacer_2"> <spacer name="verticalSpacer_2">
@ -1281,46 +355,6 @@ Applies and Saves all settings to SD</string>
<tabstop>outputRate2</tabstop> <tabstop>outputRate2</tabstop>
<tabstop>outputRate3</tabstop> <tabstop>outputRate3</tabstop>
<tabstop>outputRate4</tabstop> <tabstop>outputRate4</tabstop>
<tabstop>ch0OutMin</tabstop>
<tabstop>ch0OutMax</tabstop>
<tabstop>ch1OutMin</tabstop>
<tabstop>ch1OutMax</tabstop>
<tabstop>ch2OutMin</tabstop>
<tabstop>ch2OutMax</tabstop>
<tabstop>ch3OutMin</tabstop>
<tabstop>ch3OutMax</tabstop>
<tabstop>ch4OutMin</tabstop>
<tabstop>ch4OutMax</tabstop>
<tabstop>ch5OutMin</tabstop>
<tabstop>ch5OutMax</tabstop>
<tabstop>ch6OutMin</tabstop>
<tabstop>ch6OutMax</tabstop>
<tabstop>ch7OutMin</tabstop>
<tabstop>ch7OutMax</tabstop>
<tabstop>ch0OutSlider</tabstop>
<tabstop>ch0Rev</tabstop>
<tabstop>ch0Link</tabstop>
<tabstop>ch1OutSlider</tabstop>
<tabstop>ch1Rev</tabstop>
<tabstop>ch1Link</tabstop>
<tabstop>ch2OutSlider</tabstop>
<tabstop>ch2Rev</tabstop>
<tabstop>ch2Link</tabstop>
<tabstop>ch3OutSlider</tabstop>
<tabstop>ch3Rev</tabstop>
<tabstop>ch3Link</tabstop>
<tabstop>ch4OutSlider</tabstop>
<tabstop>ch4Rev</tabstop>
<tabstop>ch4Link</tabstop>
<tabstop>ch5OutSlider</tabstop>
<tabstop>ch5Rev</tabstop>
<tabstop>ch5Link</tabstop>
<tabstop>ch6OutSlider</tabstop>
<tabstop>ch6Rev</tabstop>
<tabstop>ch6Link</tabstop>
<tabstop>ch7OutSlider</tabstop>
<tabstop>ch7Rev</tabstop>
<tabstop>ch7Link</tabstop>
<tabstop>channelOutTest</tabstop> <tabstop>channelOutTest</tabstop>
<tabstop>saveRCOutputToRAM</tabstop> <tabstop>saveRCOutputToRAM</tabstop>
<tabstop>saveRCOutputToSD</tabstop> <tabstop>saveRCOutputToSD</tabstop>

View File

@ -0,0 +1,297 @@
/**
******************************************************************************
*
* @file outputchannelform.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
* @{
* @brief Servo output configuration form for the config output gadget
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "outputchannelform.h"
#include "configoutputwidget.h"
OutputChannelForm::OutputChannelForm(const int index, QWidget *parent, const bool showLegend) :
QWidget(parent),
ui(),
m_index(index),
m_inChannelTest(false)
{
ui.setupUi(this);
if(!showLegend)
{
// Remove legend
QGridLayout *grid_layout = dynamic_cast<QGridLayout*>(layout());
Q_ASSERT(grid_layout);
for (int col = 0; col < grid_layout->columnCount(); col++)
{ // remove every item in first row
QLayoutItem *item = grid_layout->itemAtPosition(0, col);
if (!item) continue;
// get widget from layout item
QWidget *legend_widget = item->widget();
if (!legend_widget) continue;
// delete widget
grid_layout->removeWidget(legend_widget);
delete legend_widget;
}
}
// The convention for OP is Channel 1 to Channel 10.
ui.actuatorNumber->setText(QString("%1:").arg(m_index+1));
// Register for ActuatorSettings changes:
connect(ui.actuatorMin, SIGNAL(editingFinished()),
this, SLOT(setChannelRange()));
connect(ui.actuatorMax, SIGNAL(editingFinished()),
this, SLOT(setChannelRange()));
connect(ui.actuatorRev, SIGNAL(toggled(bool)),
this, SLOT(reverseChannel(bool)));
// Now connect the channel out sliders to our signal to send updates in test mode
connect(ui.actuatorNeutral, SIGNAL(valueChanged(int)),
this, SLOT(sendChannelTest(int)));
ui.actuatorLink->setChecked(false);
connect(ui.actuatorLink, SIGNAL(toggled(bool)),
this, SLOT(linkToggled(bool)));
}
OutputChannelForm::~OutputChannelForm()
{
// Do nothing
}
/**
* Restrict UI to protect users from accidental misuse.
*/
void OutputChannelForm::enableChannelTest(bool state)
{
if (m_inChannelTest == state) return;
m_inChannelTest = state;
if(m_inChannelTest)
{
// Prevent stupid users from touching the minimum & maximum ranges while
// moving the sliders. Thanks Ivan for the tip :)
ui.actuatorMin->setEnabled(false);
ui.actuatorMax->setEnabled(false);
ui.actuatorRev->setEnabled(false);
}
else
{
ui.actuatorMin->setEnabled(true);
ui.actuatorMax->setEnabled(true);
ui.actuatorRev->setEnabled(true);
}
}
/**
* Toggles the channel linked state for use in testing mode
*/
void OutputChannelForm::linkToggled(bool state)
{
Q_UNUSED(state)
if (!m_inChannelTest)
return; // we are not in Test Output mode
// find the minimum slider value for the linked ones
if (!parent()) return;
int min = 10000;
int linked_count = 0;
QList<OutputChannelForm*> outputChannelForms = parent()->findChildren<OutputChannelForm*>();
// set the linked channels of the parent widget to the same value
foreach(OutputChannelForm *outputChannelForm, outputChannelForms)
{
if (!outputChannelForm->ui.actuatorLink->checkState())
continue;
if (this == outputChannelForm)
continue;
int value = outputChannelForm->ui.actuatorNeutral->value();
if(min > value) min = value;
linked_count++;
}
if (linked_count <= 0)
return; // no linked channels
// set the linked channels to the same value
foreach(OutputChannelForm *outputChannelForm, outputChannelForms)
{
if (!outputChannelForm->ui.actuatorLink->checkState())
continue;
outputChannelForm->ui.actuatorNeutral->setValue(min);
}
}
/**
* Set maximal channel value.
*/
void OutputChannelForm::max(int maximum)
{
minmax(ui.actuatorMin->value(), maximum);
}
/**
* Set minimal channel value.
*/
void OutputChannelForm::min(int minimum)
{
minmax(minimum, ui.actuatorMax->value());
}
/**
* Set minimal and maximal channel value.
*/
void OutputChannelForm::minmax(int minimum, int maximum)
{
ui.actuatorMin->setValue(minimum);
ui.actuatorMax->setValue(maximum);
setChannelRange();
if(ui.actuatorMin->value() > ui.actuatorMax->value())
ui.actuatorRev->setChecked(true);
else
ui.actuatorRev->setChecked(false);
}
/**
* Set neutral of channel.
*/
void OutputChannelForm::neutral(int value)
{
ui.actuatorNeutral->setValue(value);
}
/**
* Set the channel assignment label.
*/
void OutputChannelForm::setAssignment(const QString &assignment)
{
ui.actuatorName->setText(assignment);
}
/**
* Sets the minimum/maximum value of the channel output sliders.
* Have to do it here because setMinimum is not a slot.
*
* One added trick: if the slider is at its min when the value
* is changed, then keep it on the min.
*/
void OutputChannelForm::setChannelRange()
{
int oldMini = ui.actuatorNeutral->minimum();
// int oldMaxi = ui.actuatorNeutral->maximum();
if (ui.actuatorMin->value() < ui.actuatorMax->value())
{
ui.actuatorNeutral->setRange(ui.actuatorMin->value(), ui.actuatorMax->value());
ui.actuatorRev->setChecked(false);
}
else
{
ui.actuatorNeutral->setRange(ui.actuatorMax->value(), ui.actuatorMin->value());
ui.actuatorRev->setChecked(true);
}
if (ui.actuatorNeutral->value() == oldMini)
ui.actuatorNeutral->setValue(ui.actuatorNeutral->minimum());
// if (ui.actuatorNeutral->value() == oldMaxi)
// ui.actuatorNeutral->setValue(ui.actuatorNeutral->maximum()); // this can be dangerous if it happens to be controlling a motor at the time!
}
/**
* Reverses the channel when the checkbox is clicked
*/
void OutputChannelForm::reverseChannel(bool state)
{
// Sanity check: if state became true, make sure the Maxvalue was higher than Minvalue
// the situations below can happen!
if (state && (ui.actuatorMax->value() < ui.actuatorMin->value()))
return;
if (!state && (ui.actuatorMax->value() > ui.actuatorMin->value()))
return;
// Now, swap the min & max values (only on the spinboxes, the slider
// does not change!
int temp = ui.actuatorMax->value();
ui.actuatorMax->setValue(ui.actuatorMin->value());
ui.actuatorMin->setValue(temp);
// Also update the channel value
// This is a trick to force the slider to update its value and
// emit the right signal itself, because our sendChannelTest(int) method
// relies on the object sender's identity.
if (ui.actuatorNeutral->value() < ui.actuatorNeutral->maximum())
{
ui.actuatorNeutral->setValue(ui.actuatorNeutral->value()+1);
ui.actuatorNeutral->setValue(ui.actuatorNeutral->value()-1);
}
else
{
ui.actuatorNeutral->setValue(ui.actuatorNeutral->value()-1);
ui.actuatorNeutral->setValue(ui.actuatorNeutral->value()+1);
}
}
/**
* Emits the channel value which will be send to the UAV to move the servo.
* Returns immediately if we are not in testing mode.
*/
void OutputChannelForm::sendChannelTest(int value)
{
int in_value = value;
QSlider *ob = (QSlider *)QObject::sender();
if (!ob) return;
if (ui.actuatorRev->isChecked())
value = ui.actuatorMin->value() - value + ui.actuatorMax->value(); // the channel is reversed
// update the label
ui.actuatorValue->setText(QString::number(value));
if (ui.actuatorLink->checkState() && parent())
{ // the channel is linked to other channels
QList<OutputChannelForm*> outputChannelForms = parent()->findChildren<OutputChannelForm*>();
// set the linked channels of the parent widget to the same value
foreach(OutputChannelForm *outputChannelForm, outputChannelForms)
{
if (this == outputChannelForm) continue;
if (!outputChannelForm->ui.actuatorLink->checkState()) continue;
int val = in_value;
if (val < outputChannelForm->ui.actuatorNeutral->minimum())
val = outputChannelForm->ui.actuatorNeutral->minimum();
if (val > outputChannelForm->ui.actuatorNeutral->maximum())
val = outputChannelForm->ui.actuatorNeutral->maximum();
if (outputChannelForm->ui.actuatorNeutral->value() == val) continue;
outputChannelForm->ui.actuatorNeutral->setValue(val);
outputChannelForm->ui.actuatorValue->setText(QString::number(val));
}
}
if (!m_inChannelTest)
return; // we are not in Test Output mode
emit channelChanged(index(), value);
}

View File

@ -0,0 +1,92 @@
/**
******************************************************************************
*
* @file outputchannelform.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
* @{
* @brief Servo output configuration form for the config output gadget
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef OUTPUTCHANNELFORM_H
#define OUTPUTCHANNELFORM_H
#include <QWidget>
#include "ui_outputchannelform.h"
class ConfigInputWidget;
class OutputChannelForm : public QWidget
{
Q_OBJECT
public:
explicit OutputChannelForm(const int index, QWidget *parent = NULL, const bool showLegend = false);
~OutputChannelForm();
friend class ConfigInputWidget;
void setAssignment(const QString &assignment);
int index() const;
public slots:
void max(int maximum);
int max() const;
void min(int minimum);
int min() const;
void minmax(int minimum, int maximum);
void neutral(int value);
int neutral() const;
void enableChannelTest(bool state);
signals:
void channelChanged(int index, int value);
private:
Ui::outputChannelForm ui;
/// Channel index
int m_index;
bool m_inChannelTest;
private slots:
void linkToggled(bool state);
void reverseChannel(bool state);
void sendChannelTest(int value);
void setChannelRange();
};
inline int OutputChannelForm::index() const
{
return m_index;
}
inline int OutputChannelForm::max() const
{
return ui.actuatorMax->value();
}
inline int OutputChannelForm::min() const
{
return ui.actuatorMin->value();
}
inline int OutputChannelForm::neutral() const
{
return ui.actuatorNeutral->value();
}
#endif // OUTPUTCHANNELFORM_H

View File

@ -0,0 +1,287 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>outputChannelForm</class>
<widget class="QWidget" name="outputChannelForm">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>562</width>
<height>49</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="topMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<number>1</number>
</property>
<item row="1" column="0">
<widget class="QLabel" name="actuatorNumber">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Channel Number</string>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="actuatorName">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>90</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="actuatorMin">
<property name="toolTip">
<string>Minimum PWM value, beware of not overdriving your servo.</string>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="1" column="3">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="4">
<widget class="QSlider" name="actuatorNeutral">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximum">
<number>9999</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="6">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="9">
<widget class="QCheckBox" name="actuatorRev">
<property name="toolTip">
<string>Check to invert the channel.</string>
</property>
</widget>
</item>
<item row="1" column="10">
<widget class="QCheckBox" name="actuatorLink">
<property name="toolTip">
<string>Output mode</string>
</property>
</widget>
</item>
<item row="1" column="8">
<widget class="QSpinBox" name="actuatorMax">
<property name="toolTip">
<string>Maximum PWM value, beware of not overdriving your servo.</string>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="legend0">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Assignment</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="legend1">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Min</string>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QLabel" name="legend2">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Neutral (slowest for motor)</string>
</property>
</widget>
</item>
<item row="0" column="8">
<widget class="QLabel" name="legend3">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Max</string>
</property>
</widget>
</item>
<item row="0" column="9">
<widget class="QLabel" name="legend4">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Rev.</string>
</property>
</widget>
</item>
<item row="0" column="10">
<widget class="QLabel" name="legend5">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Link</string>
</property>
</widget>
</item>
<item row="1" column="5">
<widget class="QLabel" name="actuatorValue">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Current value of slider.</string>
</property>
<property name="text">
<string>0000</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="legend6">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
<string>#</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="margin">
<number>0</number>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>