1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-20 10:54:14 +01:00

Merge branch 'next' into revo

Conflicts:
	flight/PiOS/Boards/STM32F4xx_Revolution.h
	flight/Revolution/System/inc/pios_config.h
	package/Makefile
This commit is contained in:
James Cotton 2012-06-07 12:44:52 -05:00
commit f5b2575c88
33 changed files with 5673 additions and 5256 deletions

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>RemoteSystemsTempFiles</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
</buildSpec>
<natures>
<nature>org.eclipse.rse.ui.remoteSystemsTempNature</nature>
</natures>
</projectDescription>

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>796</width> <width>730</width>
<height>605</height> <height>602</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -1359,7 +1359,7 @@ margin:1px;</string>
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
<widget class="ConfigccpmWidget" name="widget_3" native="true"/> <widget class="ConfigCcpmWidget" name="widget_3" native="true"/>
</item> </item>
</layout> </layout>
</item> </item>
@ -2893,7 +2893,7 @@ p, li { white-space: pre-wrap; }
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>ConfigccpmWidget</class> <class>ConfigCcpmWidget</class>
<extends>QWidget</extends> <extends>QWidget</extends>
<header>cfg_vehicletypes/configccpmwidget.h</header> <header>cfg_vehicletypes/configccpmwidget.h</header>
<container>1</container> <container>1</container>
@ -2999,22 +2999,6 @@ p, li { white-space: pre-wrap; }
</hint> </hint>
</hints> </hints>
</connection> </connection>
<connection>
<sender>mrPitchMixLevel</sender>
<signal>valueChanged(int)</signal>
<receiver>mrPitchMixValue</receiver>
<slot>setNum(int)</slot>
<hints>
<hint type="sourcelabel">
<x>83</x>
<y>228</y>
</hint>
<hint type="destinationlabel">
<x>82</x>
<y>168</y>
</hint>
</hints>
</connection>
<connection> <connection>
<sender>mrRollMixLevel</sender> <sender>mrRollMixLevel</sender>
<signal>valueChanged(int)</signal> <signal>valueChanged(int)</signal>
@ -3047,5 +3031,21 @@ p, li { white-space: pre-wrap; }
</hint> </hint>
</hints> </hints>
</connection> </connection>
<connection>
<sender>mrPitchMixLevel</sender>
<signal>valueChanged(int)</signal>
<receiver>mrPitchMixValue</receiver>
<slot>setNum(int)</slot>
<hints>
<hint type="sourcelabel">
<x>92</x>
<y>222</y>
</hint>
<hint type="destinationlabel">
<x>92</x>
<y>151</y>
</hint>
</hints>
</connection>
</connections> </connections>
</ui> </ui>

View File

@ -3959,7 +3959,7 @@ margin:1px;</string>
<connections> <connections>
<connection> <connection>
<sender>ccpmCollectiveSlider</sender> <sender>ccpmCollectiveSlider</sender>
<signal>sliderMoved(int)</signal> <signal>valueChanged(int)</signal>
<receiver>ccpmCollectivespinBox</receiver> <receiver>ccpmCollectivespinBox</receiver>
<slot>setValue(int)</slot> <slot>setValue(int)</slot>
<hints> <hints>
@ -4007,7 +4007,7 @@ margin:1px;</string>
</connection> </connection>
<connection> <connection>
<sender>ccpmRevoSlider</sender> <sender>ccpmRevoSlider</sender>
<signal>sliderMoved(int)</signal> <signal>valueChanged(int)</signal>
<receiver>ccpmREVOspinBox</receiver> <receiver>ccpmREVOspinBox</receiver>
<slot>setValue(int)</slot> <slot>setValue(int)</slot>
<hints> <hints>
@ -4023,7 +4023,7 @@ margin:1px;</string>
</connection> </connection>
<connection> <connection>
<sender>SwashLvlPositionSlider</sender> <sender>SwashLvlPositionSlider</sender>
<signal>sliderMoved(int)</signal> <signal>valueChanged(int)</signal>
<receiver>SwashLvlPositionSpinBox</receiver> <receiver>SwashLvlPositionSpinBox</receiver>
<slot>setValue(int)</slot> <slot>setValue(int)</slot>
<hints> <hints>
@ -4071,7 +4071,7 @@ margin:1px;</string>
</connection> </connection>
<connection> <connection>
<sender>ccpmCollectiveScale</sender> <sender>ccpmCollectiveScale</sender>
<signal>sliderMoved(int)</signal> <signal>valueChanged(int)</signal>
<receiver>ccpmCollectiveScaleBox</receiver> <receiver>ccpmCollectiveScaleBox</receiver>
<slot>setValue(int)</slot> <slot>setValue(int)</slot>
<hints> <hints>
@ -4087,7 +4087,7 @@ margin:1px;</string>
</connection> </connection>
<connection> <connection>
<sender>ccpmCyclicScale</sender> <sender>ccpmCyclicScale</sender>
<signal>sliderMoved(int)</signal> <signal>valueChanged(int)</signal>
<receiver>ccpmCyclicScaleBox</receiver> <receiver>ccpmCyclicScaleBox</receiver>
<slot>setValue(int)</slot> <slot>setValue(int)</slot>
<hints> <hints>
@ -4119,7 +4119,7 @@ margin:1px;</string>
</connection> </connection>
<connection> <connection>
<sender>ccpmPitchScale</sender> <sender>ccpmPitchScale</sender>
<signal>sliderMoved(int)</signal> <signal>valueChanged(int)</signal>
<receiver>ccpmPitchScaleBox</receiver> <receiver>ccpmPitchScaleBox</receiver>
<slot>setValue(int)</slot> <slot>setValue(int)</slot>
<hints> <hints>
@ -4167,7 +4167,7 @@ margin:1px;</string>
</connection> </connection>
<connection> <connection>
<sender>ccpmRollScale</sender> <sender>ccpmRollScale</sender>
<signal>sliderMoved(int)</signal> <signal>valueChanged(int)</signal>
<receiver>ccpmRollScaleBox</receiver> <receiver>ccpmRollScaleBox</receiver>
<slot>setValue(int)</slot> <slot>setValue(int)</slot>
<hints> <hints>

View File

@ -25,7 +25,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "configccpmwidget.h" #include "configccpmwidget.h"
#include "mixersettings.h" //#include "mixersettings.h"
#include <QDebug> #include <QDebug>
#include <QStringList> #include <QStringList>
@ -44,21 +44,17 @@
#define Pi 3.14159265358979323846 #define Pi 3.14159265358979323846
ConfigccpmWidget::ConfigccpmWidget(QWidget *parent) : ConfigTaskWidget(parent) ConfigCcpmWidget::ConfigCcpmWidget(QWidget *parent) : VehicleConfig(parent)
{ {
int i; int i;
m_ccpm = new Ui_ccpmWidget();
m_ccpm->setupUi(this);
SwashLvlConfigurationInProgress=0; SwashLvlConfigurationInProgress=0;
SwashLvlState=0; SwashLvlState=0;
SwashLvlServoInterlock=0; SwashLvlServoInterlock=0;
updatingFromHardware=FALSE; updatingFromHardware=FALSE;
updatingToHardware=FALSE; updatingToHardware=FALSE;
// Now connect the widget to the ManualControlCommand / Channel UAVObject m_ccpm = new Ui_ccpmWidget();
//ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); m_ccpm->setupUi(this);
//UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
// Initialization of the swashplaye widget // Initialization of the swashplaye widget
m_ccpm->SwashplateImage->setScene(new QGraphicsScene(this)); m_ccpm->SwashplateImage->setScene(new QGraphicsScene(this));
@ -147,21 +143,18 @@ ConfigccpmWidget::ConfigccpmWidget(QWidget *parent) : ConfigTaskWidget(parent)
UAVObjectField * curve2source = mixerSettings->getField("Curve2Source"); UAVObjectField * curve2source = mixerSettings->getField("Curve2Source");
Q_ASSERT(curve2source); Q_ASSERT(curve2source);
QStringList channels; m_ccpm->ccpmEngineChannel->addItems(channelNames);
channels << "Channel1" << "Channel2" << "Channel3" << "Channel4" << m_ccpm->ccpmEngineChannel->setCurrentIndex(0);
"Channel5" << "Channel6" << "Channel7" << "Channel8" << "None"; m_ccpm->ccpmTailChannel->addItems(channelNames);
m_ccpm->ccpmEngineChannel->addItems(channels); m_ccpm->ccpmTailChannel->setCurrentIndex(0);
m_ccpm->ccpmEngineChannel->setCurrentIndex(8); m_ccpm->ccpmServoWChannel->addItems(channelNames);
m_ccpm->ccpmTailChannel->addItems(channels); m_ccpm->ccpmServoWChannel->setCurrentIndex(0);
m_ccpm->ccpmTailChannel->setCurrentIndex(8); m_ccpm->ccpmServoXChannel->addItems(channelNames);
m_ccpm->ccpmServoWChannel->addItems(channels); m_ccpm->ccpmServoXChannel->setCurrentIndex(0);
m_ccpm->ccpmServoWChannel->setCurrentIndex(8); m_ccpm->ccpmServoYChannel->addItems(channelNames);
m_ccpm->ccpmServoXChannel->addItems(channels); m_ccpm->ccpmServoYChannel->setCurrentIndex(0);
m_ccpm->ccpmServoXChannel->setCurrentIndex(8); m_ccpm->ccpmServoZChannel->addItems(channelNames);
m_ccpm->ccpmServoYChannel->addItems(channels); m_ccpm->ccpmServoZChannel->setCurrentIndex(0);
m_ccpm->ccpmServoYChannel->setCurrentIndex(8);
m_ccpm->ccpmServoZChannel->addItems(channels);
m_ccpm->ccpmServoZChannel->setCurrentIndex(8);
QStringList Types; QStringList Types;
Types << QString::fromUtf8("CCPM 2 Servo 90º") << QString::fromUtf8("CCPM 3 Servo 90º") << Types << QString::fromUtf8("CCPM 2 Servo 90º") << QString::fromUtf8("CCPM 3 Servo 90º") <<
@ -170,12 +163,14 @@ ConfigccpmWidget::ConfigccpmWidget(QWidget *parent) : ConfigTaskWidget(parent)
QString::fromUtf8("Custom - User Angles") << QString::fromUtf8("Custom - Advanced Settings"); QString::fromUtf8("Custom - User Angles") << QString::fromUtf8("Custom - Advanced Settings");
m_ccpm->ccpmType->addItems(Types); m_ccpm->ccpmType->addItems(Types);
m_ccpm->ccpmType->setCurrentIndex(m_ccpm->ccpmType->count() - 1); m_ccpm->ccpmType->setCurrentIndex(m_ccpm->ccpmType->count() - 1);
requestccpmUpdate();
UpdateCurveSettings(); UpdateCurveSettings();
//disable changing number of points in curves until UAVObjects have more than 5 //disable changing number of points in curves until UAVObjects have more than 5
m_ccpm->NumCurvePoints->setEnabled(0); m_ccpm->NumCurvePoints->setEnabled(0);
refreshWidgetsValues(QString("HeliCP"));
UpdateType(); UpdateType();
//connect(m_ccpm->saveccpmToSD, SIGNAL(clicked()), this, SLOT(saveccpmUpdate())); //connect(m_ccpm->saveccpmToSD, SIGNAL(clicked()), this, SLOT(saveccpmUpdate()));
@ -205,9 +200,6 @@ ConfigccpmWidget::ConfigccpmWidget(QWidget *parent) : ConfigTaskWidget(parent)
connect(m_ccpm->CurveSettings, SIGNAL(cellChanged (int, int)), this, SLOT(UpdateCurveWidgets())); connect(m_ccpm->CurveSettings, SIGNAL(cellChanged (int, int)), this, SLOT(UpdateCurveWidgets()));
connect(m_ccpm->TabObject, SIGNAL(currentChanged ( QWidget * )), this, SLOT(UpdateType())); connect(m_ccpm->TabObject, SIGNAL(currentChanged ( QWidget * )), this, SLOT(UpdateType()));
// connect(m_ccpm->SwashLvlSwashplateImage, SIGNAL(valueChanged(double)), this, SLOT(ccpmSwashplateRedraw()));
connect(m_ccpm->PitchCurve, SIGNAL(curveUpdated(QList<double>,double)), this, SLOT(updatePitchCurveValue(QList<double>,double))); connect(m_ccpm->PitchCurve, SIGNAL(curveUpdated(QList<double>,double)), this, SLOT(updatePitchCurveValue(QList<double>,double)));
connect(m_ccpm->ThrottleCurve, SIGNAL(curveUpdated(QList<double>,double)), this, SLOT(updateThrottleCurveValue(QList<double>,double))); connect(m_ccpm->ThrottleCurve, SIGNAL(curveUpdated(QList<double>,double)), this, SLOT(updateThrottleCurveValue(QList<double>,double)));
@ -216,6 +208,7 @@ ConfigccpmWidget::ConfigccpmWidget(QWidget *parent) : ConfigTaskWidget(parent)
connect(m_ccpm->SwashLvlCancelButton, SIGNAL(clicked()), this, SLOT(SwashLvlCancelButtonPressed())); connect(m_ccpm->SwashLvlCancelButton, SIGNAL(clicked()), this, SLOT(SwashLvlCancelButtonPressed()));
connect(m_ccpm->SwashLvlFinishButton, SIGNAL(clicked()), this, SLOT(SwashLvlFinishButtonPressed())); connect(m_ccpm->SwashLvlFinishButton, SIGNAL(clicked()), this, SLOT(SwashLvlFinishButtonPressed()));
connect(m_ccpm->ccpmCollectivePassthrough, SIGNAL(clicked()),this, SLOT(SetUIComponentVisibilities()));
connect(m_ccpm->ccpmLinkCyclic, SIGNAL(clicked()), this, SLOT(SetUIComponentVisibilities())); connect(m_ccpm->ccpmLinkCyclic, SIGNAL(clicked()), this, SLOT(SetUIComponentVisibilities()));
connect(m_ccpm->ccpmLinkRoll, SIGNAL(clicked()), this, SLOT(SetUIComponentVisibilities())); connect(m_ccpm->ccpmLinkRoll, SIGNAL(clicked()), this, SLOT(SetUIComponentVisibilities()));
@ -224,18 +217,96 @@ ConfigccpmWidget::ConfigccpmWidget(QWidget *parent) : ConfigTaskWidget(parent)
ccpmSwashplateRedraw(); ccpmSwashplateRedraw();
} }
ConfigccpmWidget::~ConfigccpmWidget() ConfigCcpmWidget::~ConfigCcpmWidget()
{ {
// Do nothing // Do nothing
} }
void ConfigccpmWidget::UpdateType() void ConfigCcpmWidget::setupUI(QString frameType)
{
}
void ConfigCcpmWidget::ResetActuators(GUIConfigDataUnion* configData)
{
configData->heli.Throttle = 0;
configData->heli.Tail = 0;
configData->heli.ServoIndexW = 0;
configData->heli.ServoIndexX = 0;
configData->heli.ServoIndexY = 0;
configData->heli.ServoIndexZ = 0;
}
QStringList ConfigCcpmWidget::getChannelDescriptions()
{
int i;
QStringList channelDesc;
// init a channel_numelem list of channel desc defaults
for (i=0; i < (int)(ConfigCcpmWidget::CHANNEL_NUMELEM); i++)
{
channelDesc.append(QString("-"));
}
// get the gui config data
GUIConfigDataUnion configData = GetConfigData();
heliGUISettingsStruct heli = configData.heli;
if (heli.Throttle > 0)
channelDesc[heli.Throttle - 1] = QString("Throttle");
if (heli.Tail > 0)
channelDesc[heli.Tail - 1] = QString("Tail");
switch(heli.FirstServoIndex)
{
case 0: //front
if (heli.ServoIndexW > 0)
channelDesc[heli.ServoIndexW - 1] = QString("Elevator");
if (heli.ServoIndexX > 0)
channelDesc[heli.ServoIndexX - 1] = QString("Roll1");
if (heli.ServoIndexY > 0)
channelDesc[heli.ServoIndexY - 1] = QString("Roll2");
break;
case 1: //right
if (heli.ServoIndexW > 0)
channelDesc[heli.ServoIndexW - 1] = QString("ServoW");
if (heli.ServoIndexX > 0)
channelDesc[heli.ServoIndexX - 1] = QString("ServoX");
if (heli.ServoIndexY > 0)
channelDesc[heli.ServoIndexY - 1] = QString("ServoY");
break;
case 2: //rear
if (heli.ServoIndexW > 0)
channelDesc[heli.ServoIndexW - 1] = QString("Elevator");
if (heli.ServoIndexX > 0)
channelDesc[heli.ServoIndexX - 1] = QString("Roll1");
if (heli.ServoIndexY > 0)
channelDesc[heli.ServoIndexY - 1] = QString("Roll2");
break;
case 3: //left
if (heli.ServoIndexW > 0)
channelDesc[heli.ServoIndexW - 1] = QString("ServoW");
if (heli.ServoIndexX > 0)
channelDesc[heli.ServoIndexX - 1] = QString("ServoX");
if (heli.ServoIndexY > 0)
channelDesc[heli.ServoIndexY - 1] = QString("ServoY");
break;
}
if (heli.ServoIndexZ > 0)
channelDesc[heli.ServoIndexZ - 1] = QString("ServoZ");
return channelDesc;
}
void ConfigCcpmWidget::UpdateType()
{ {
int TypeInt,SingleServoIndex,NumServosDefined; int TypeInt,SingleServoIndex,NumServosDefined;
QString TypeText; QString TypeText;
double AdjustmentAngle=0; double AdjustmentAngle=0;
UpdateCCPMOptionsFromUI();
SetUIComponentVisibilities(); SetUIComponentVisibilities();
TypeInt = m_ccpm->ccpmType->count() - m_ccpm->ccpmType->currentIndex()-1; TypeInt = m_ccpm->ccpmType->count() - m_ccpm->ccpmType->currentIndex()-1;
@ -283,8 +354,8 @@ void ConfigccpmWidget::UpdateType()
m_ccpm->ccpmAngleZ->setValue(0); m_ccpm->ccpmAngleZ->setValue(0);
m_ccpm->ccpmAngleY->setEnabled(0); m_ccpm->ccpmAngleY->setEnabled(0);
m_ccpm->ccpmAngleZ->setEnabled(0); m_ccpm->ccpmAngleZ->setEnabled(0);
m_ccpm->ccpmServoYChannel->setCurrentIndex(8); m_ccpm->ccpmServoYChannel->setCurrentIndex(0);
m_ccpm->ccpmServoZChannel->setCurrentIndex(8); m_ccpm->ccpmServoZChannel->setCurrentIndex(0);
m_ccpm->ccpmServoYChannel->setEnabled(0); m_ccpm->ccpmServoYChannel->setEnabled(0);
m_ccpm->ccpmServoZChannel->setEnabled(0); m_ccpm->ccpmServoZChannel->setEnabled(0);
//m_ccpm->ccpmCorrectionAngle->setValue(0); //m_ccpm->ccpmCorrectionAngle->setValue(0);
@ -298,7 +369,7 @@ void ConfigccpmWidget::UpdateType()
m_ccpm->ccpmAngleY->setValue(fmod(AdjustmentAngle + 180,360)); m_ccpm->ccpmAngleY->setValue(fmod(AdjustmentAngle + 180,360));
m_ccpm->ccpmAngleZ->setValue(0); m_ccpm->ccpmAngleZ->setValue(0);
m_ccpm->ccpmAngleZ->setEnabled(0); m_ccpm->ccpmAngleZ->setEnabled(0);
m_ccpm->ccpmServoZChannel->setCurrentIndex(8); m_ccpm->ccpmServoZChannel->setCurrentIndex(0);
m_ccpm->ccpmServoZChannel->setEnabled(0); m_ccpm->ccpmServoZChannel->setEnabled(0);
//m_ccpm->ccpmCorrectionAngle->setValue(0); //m_ccpm->ccpmCorrectionAngle->setValue(0);
NumServosDefined=3; NumServosDefined=3;
@ -323,7 +394,7 @@ void ConfigccpmWidget::UpdateType()
m_ccpm->ccpmAngleY->setValue(fmod(AdjustmentAngle + 240,360)); m_ccpm->ccpmAngleY->setValue(fmod(AdjustmentAngle + 240,360));
m_ccpm->ccpmAngleZ->setValue(0); m_ccpm->ccpmAngleZ->setValue(0);
m_ccpm->ccpmAngleZ->setEnabled(0); m_ccpm->ccpmAngleZ->setEnabled(0);
m_ccpm->ccpmServoZChannel->setCurrentIndex(8); m_ccpm->ccpmServoZChannel->setCurrentIndex(0);
m_ccpm->ccpmServoZChannel->setEnabled(0); m_ccpm->ccpmServoZChannel->setEnabled(0);
//m_ccpm->ccpmCorrectionAngle->setValue(0); //m_ccpm->ccpmCorrectionAngle->setValue(0);
NumServosDefined=3; NumServosDefined=3;
@ -336,7 +407,7 @@ void ConfigccpmWidget::UpdateType()
m_ccpm->ccpmAngleY->setValue(fmod(AdjustmentAngle + 220,360)); m_ccpm->ccpmAngleY->setValue(fmod(AdjustmentAngle + 220,360));
m_ccpm->ccpmAngleZ->setValue(0); m_ccpm->ccpmAngleZ->setValue(0);
m_ccpm->ccpmAngleZ->setEnabled(0); m_ccpm->ccpmAngleZ->setEnabled(0);
m_ccpm->ccpmServoZChannel->setCurrentIndex(8); m_ccpm->ccpmServoZChannel->setCurrentIndex(0);
m_ccpm->ccpmServoZChannel->setEnabled(0); m_ccpm->ccpmServoZChannel->setEnabled(0);
//m_ccpm->ccpmCorrectionAngle->setValue(0); //m_ccpm->ccpmCorrectionAngle->setValue(0);
NumServosDefined=3; NumServosDefined=3;
@ -350,8 +421,8 @@ void ConfigccpmWidget::UpdateType()
m_ccpm->ccpmAngleZ->setValue(0); m_ccpm->ccpmAngleZ->setValue(0);
m_ccpm->ccpmAngleY->setEnabled(0); m_ccpm->ccpmAngleY->setEnabled(0);
m_ccpm->ccpmAngleZ->setEnabled(0); m_ccpm->ccpmAngleZ->setEnabled(0);
m_ccpm->ccpmServoYChannel->setCurrentIndex(8); m_ccpm->ccpmServoYChannel->setCurrentIndex(0);
m_ccpm->ccpmServoZChannel->setCurrentIndex(8); m_ccpm->ccpmServoZChannel->setCurrentIndex(0);
m_ccpm->ccpmServoYChannel->setEnabled(0); m_ccpm->ccpmServoYChannel->setEnabled(0);
m_ccpm->ccpmServoZChannel->setEnabled(0); m_ccpm->ccpmServoZChannel->setEnabled(0);
//m_ccpm->ccpmCorrectionAngle->setValue(0); //m_ccpm->ccpmCorrectionAngle->setValue(0);
@ -407,12 +478,12 @@ void ConfigccpmWidget::UpdateType()
/** /**
Resets a mixer curve Resets a mixer curve
*/ */
void ConfigccpmWidget::resetMixer(MixerCurveWidget *mixer, int numElements) void ConfigCcpmWidget::resetMixer(MixerCurveWidget *mixer, int numElements)
{ {
mixer->initLinearCurve(numElements,(double)1); mixer->initLinearCurve(numElements,(double)1);
} }
void ConfigccpmWidget::UpdateCurveWidgets() void ConfigCcpmWidget::UpdateCurveWidgets()
{ {
int NumCurvePoints,i,Changed; int NumCurvePoints,i,Changed;
QList<double> curveValues; QList<double> curveValues;
@ -446,7 +517,7 @@ void ConfigccpmWidget::UpdateCurveWidgets()
if (Changed==1)m_ccpm->PitchCurve->setCurve(curveValues); if (Changed==1)m_ccpm->PitchCurve->setCurve(curveValues);
} }
void ConfigccpmWidget::updatePitchCurveValue(QList<double> curveValues0,double Value0) void ConfigCcpmWidget::updatePitchCurveValue(QList<double> curveValues0,double Value0)
{ {
Q_UNUSED(curveValues0); Q_UNUSED(curveValues0);
Q_UNUSED(Value0); Q_UNUSED(Value0);
@ -470,7 +541,7 @@ void ConfigccpmWidget::updatePitchCurveValue(QList<double> curveValues0,double V
} }
void ConfigccpmWidget::updateThrottleCurveValue(QList<double> curveValues0,double Value0) void ConfigCcpmWidget::updateThrottleCurveValue(QList<double> curveValues0,double Value0)
{ {
Q_UNUSED(curveValues0); Q_UNUSED(curveValues0);
Q_UNUSED(Value0); Q_UNUSED(Value0);
@ -495,7 +566,7 @@ void ConfigccpmWidget::updateThrottleCurveValue(QList<double> curveValues0,doubl
} }
void ConfigccpmWidget::UpdateCurveSettings() void ConfigCcpmWidget::UpdateCurveSettings()
{ {
int NumCurvePoints,i; int NumCurvePoints,i;
double scale; double scale;
@ -625,7 +696,7 @@ void ConfigccpmWidget::UpdateCurveSettings()
UpdateCurveWidgets(); UpdateCurveWidgets();
} }
void ConfigccpmWidget::GenerateCurve() void ConfigCcpmWidget::GenerateCurve()
{ {
int NumCurvePoints,CurveToGenerate,i; int NumCurvePoints,CurveToGenerate,i;
double value1, value2, value3, scale; double value1, value2, value3, scale;
@ -695,7 +766,7 @@ void ConfigccpmWidget::GenerateCurve()
} }
void ConfigccpmWidget::ccpmSwashplateRedraw() void ConfigCcpmWidget::ccpmSwashplateRedraw()
{ {
double angle[CCPM_MAX_SWASH_SERVOS],CorrectionAngle,x,y,w,h,radius,CenterX,CenterY; double angle[CCPM_MAX_SWASH_SERVOS],CorrectionAngle,x,y,w,h,radius,CenterX,CenterY;
int used[CCPM_MAX_SWASH_SERVOS],defined[CCPM_MAX_SWASH_SERVOS],i; int used[CCPM_MAX_SWASH_SERVOS],defined[CCPM_MAX_SWASH_SERVOS],i;
@ -735,10 +806,10 @@ void ConfigccpmWidget::ccpmSwashplateRedraw()
defined[1]=(m_ccpm->ccpmServoXChannel->isEnabled()); defined[1]=(m_ccpm->ccpmServoXChannel->isEnabled());
defined[2]=(m_ccpm->ccpmServoYChannel->isEnabled()); defined[2]=(m_ccpm->ccpmServoYChannel->isEnabled());
defined[3]=(m_ccpm->ccpmServoZChannel->isEnabled()); defined[3]=(m_ccpm->ccpmServoZChannel->isEnabled());
used[0]=((m_ccpm->ccpmServoWChannel->currentIndex()<8)&&(m_ccpm->ccpmServoWChannel->isEnabled())); used[0]=((m_ccpm->ccpmServoWChannel->currentIndex()>0)&&(m_ccpm->ccpmServoWChannel->isEnabled()));
used[1]=((m_ccpm->ccpmServoXChannel->currentIndex()<8)&&(m_ccpm->ccpmServoXChannel->isEnabled())); used[1]=((m_ccpm->ccpmServoXChannel->currentIndex()>0)&&(m_ccpm->ccpmServoXChannel->isEnabled()));
used[2]=((m_ccpm->ccpmServoYChannel->currentIndex()<8)&&(m_ccpm->ccpmServoYChannel->isEnabled())); used[2]=((m_ccpm->ccpmServoYChannel->currentIndex()>0)&&(m_ccpm->ccpmServoYChannel->isEnabled()));
used[3]=((m_ccpm->ccpmServoZChannel->currentIndex()<8)&&(m_ccpm->ccpmServoZChannel->isEnabled())); used[3]=((m_ccpm->ccpmServoZChannel->currentIndex()>0)&&(m_ccpm->ccpmServoZChannel->isEnabled()));
angle[0]=(CorrectionAngle+180+m_ccpm->ccpmAngleW->value())*Pi/180.00; angle[0]=(CorrectionAngle+180+m_ccpm->ccpmAngleW->value())*Pi/180.00;
angle[1]=(CorrectionAngle+180+m_ccpm->ccpmAngleX->value())*Pi/180.00; angle[1]=(CorrectionAngle+180+m_ccpm->ccpmAngleX->value())*Pi/180.00;
angle[2]=(CorrectionAngle+180+m_ccpm->ccpmAngleY->value())*Pi/180.00; angle[2]=(CorrectionAngle+180+m_ccpm->ccpmAngleY->value())*Pi/180.00;
@ -796,69 +867,14 @@ void ConfigccpmWidget::ccpmSwashplateRedraw()
//m_ccpm->SwashplateImage->fitInView(SwashplateImg, Qt::KeepAspectRatio); //m_ccpm->SwashplateImage->fitInView(SwashplateImg, Qt::KeepAspectRatio);
} }
void ConfigccpmWidget::ccpmSwashplateUpdate() void ConfigCcpmWidget::ccpmSwashplateUpdate()
{ {
ccpmSwashplateRedraw(); ccpmSwashplateRedraw();
SetUIComponentVisibilities(); SetUIComponentVisibilities();
UpdateMixer(); UpdateMixer();
} }
void ConfigccpmWidget::ccpmChannelCheck() void ConfigCcpmWidget::UpdateMixer()
{
if((m_ccpm->ccpmServoWChannel->currentIndex()==8)&&(m_ccpm->ccpmServoWChannel->isEnabled()))
{
m_ccpm->ccpmServoWLabel->setText("<font color=red>Servo W</font>");
}
else
{
m_ccpm->ccpmServoWLabel->setText("<font color=black>Servo W</font>");
}
if((m_ccpm->ccpmServoXChannel->currentIndex()==8)&&(m_ccpm->ccpmServoXChannel->isEnabled()))
{
m_ccpm->ccpmServoXLabel->setText("<font color=red>Servo X</font>");
}
else
{
m_ccpm->ccpmServoXLabel->setText("<font color=black>Servo X</font>");
}
if((m_ccpm->ccpmServoYChannel->currentIndex()==8)&&(m_ccpm->ccpmServoYChannel->isEnabled()))
{
m_ccpm->ccpmServoYLabel->setText("<font color=red>Servo Y</font>");
}
else
{
m_ccpm->ccpmServoYLabel->setText("<font color=black>Servo Y</font>");
}
if((m_ccpm->ccpmServoZChannel->currentIndex()==8)&&(m_ccpm->ccpmServoZChannel->isEnabled()))
{
m_ccpm->ccpmServoZLabel->setText("<font color=red>Servo Z</font>");
}
else
{
m_ccpm->ccpmServoZLabel->setText("<font color=black>Servo Z</font>");
}
if((m_ccpm->ccpmEngineChannel->currentIndex()==8)&&(m_ccpm->ccpmEngineChannel->isEnabled()))
{
m_ccpm->ccpmEngineLabel->setText("<font color=red>Engine</font>");
}
else
{
m_ccpm->ccpmEngineLabel->setText("<font color=black>Engine</font>");
}
if((m_ccpm->ccpmTailChannel->currentIndex()==8)&&(m_ccpm->ccpmTailChannel->isEnabled()))
{
m_ccpm->ccpmTailLabel->setText("<font color=red>Tail Rotor</font>");
}
else
{
m_ccpm->ccpmTailLabel->setText("<font color=black>Tail Rotor</font>");
}
}
void ConfigccpmWidget::UpdateMixer()
{ {
bool useCCPM; bool useCCPM;
bool useCyclic; bool useCyclic;
@ -866,13 +882,14 @@ void ConfigccpmWidget::UpdateMixer()
float CollectiveConstant,PitchConstant,RollConstant,ThisAngle[6]; float CollectiveConstant,PitchConstant,RollConstant,ThisAngle[6];
QString Channel; QString Channel;
ccpmChannelCheck(); throwConfigError(QString("HeliCP"));
UpdateCCPMOptionsFromUI();
useCCPM = !(GUIConfigData.heli.ccpmCollectivePassthroughState || !GUIConfigData.heli.ccpmLinkCyclicState); GUIConfigDataUnion config = GetConfigData();
useCyclic = GUIConfigData.heli.ccpmLinkRollState;
CollectiveConstant = (float)GUIConfigData.heli.SliderValue0 / 100.00; useCCPM = !(config.heli.ccpmCollectivePassthroughState || !config.heli.ccpmLinkCyclicState);
useCyclic = config.heli.ccpmLinkRollState;
CollectiveConstant = (float)config.heli.SliderValue0 / 100.00;
if (useCCPM) if (useCCPM)
{//cyclic = 1 - collective {//cyclic = 1 - collective
@ -881,18 +898,18 @@ void ConfigccpmWidget::UpdateMixer()
} }
else else
{ {
PitchConstant = (float)GUIConfigData.heli.SliderValue1 / 100.00;; PitchConstant = (float)config.heli.SliderValue1 / 100.00;;
if (useCyclic) if (useCyclic)
{ {
RollConstant = PitchConstant; RollConstant = PitchConstant;
} }
else else
{ {
RollConstant = (float)GUIConfigData.heli.SliderValue2 / 100.00;; RollConstant = (float)config.heli.SliderValue2 / 100.00;;
} }
} }
if (GUIConfigData.heli.SwasplateType>0) if (config.heli.SwashplateType>0)
{//not advanced settings {//not advanced settings
//get the channel data from the ui //get the channel data from the ui
MixerChannelData[0] = m_ccpm->ccpmEngineChannel->currentIndex(); MixerChannelData[0] = m_ccpm->ccpmEngineChannel->currentIndex();
@ -914,18 +931,18 @@ void ConfigccpmWidget::UpdateMixer()
ThisEnable[4] = m_ccpm->ccpmServoYChannel->isEnabled(); ThisEnable[4] = m_ccpm->ccpmServoYChannel->isEnabled();
ThisEnable[5] = m_ccpm->ccpmServoZChannel->isEnabled(); ThisEnable[5] = m_ccpm->ccpmServoZChannel->isEnabled();
ServosText[0]->setPlainText(QString("%1").arg( MixerChannelData[2]+1 )); ServosText[0]->setPlainText(QString("%1").arg( MixerChannelData[2] ));
ServosText[1]->setPlainText(QString("%1").arg( MixerChannelData[3]+1 )); ServosText[1]->setPlainText(QString("%1").arg( MixerChannelData[3] ));
ServosText[2]->setPlainText(QString("%1").arg( MixerChannelData[4]+1 )); ServosText[2]->setPlainText(QString("%1").arg( MixerChannelData[4] ));
ServosText[3]->setPlainText(QString("%1").arg( MixerChannelData[5]+1 )); ServosText[3]->setPlainText(QString("%1").arg( MixerChannelData[5] ));
//go through the user data and update the mixer matrix //go through the user data and update the mixer matrix
for (i=0;i<6;i++) for (i=0;i<6;i++)
{ {
if ((MixerChannelData[i]<8)&&((ThisEnable[i])||(i<2))) if ((MixerChannelData[i]>0)&&((ThisEnable[i])||(i<2)))
{ {
m_ccpm->ccpmAdvancedSettingsTable->item(i,0)->setText(QString("%1").arg( MixerChannelData[i]+1 )); m_ccpm->ccpmAdvancedSettingsTable->item(i,0)->setText(QString("%1").arg( MixerChannelData[i] ));
//config the vector //config the vector
if (i==0) if (i==0)
{//motor-engine {//motor-engine
@ -947,8 +964,8 @@ void ConfigccpmWidget::UpdateMixer()
{//Swashplate {//Swashplate
m_ccpm->ccpmAdvancedSettingsTable->item(i,1)->setText(QString("%1").arg(0));//ThrottleCurve1 m_ccpm->ccpmAdvancedSettingsTable->item(i,1)->setText(QString("%1").arg(0));//ThrottleCurve1
m_ccpm->ccpmAdvancedSettingsTable->item(i,2)->setText(QString("%1").arg((int)(127.0*CollectiveConstant)));//ThrottleCurve2 m_ccpm->ccpmAdvancedSettingsTable->item(i,2)->setText(QString("%1").arg((int)(127.0*CollectiveConstant)));//ThrottleCurve2
m_ccpm->ccpmAdvancedSettingsTable->item(i,3)->setText(QString("%1").arg((int)(127.0*(RollConstant)*sin((180+GUIConfigData.heli.CorrectionAngle + ThisAngle[i])*Pi/180.00))));//Roll m_ccpm->ccpmAdvancedSettingsTable->item(i,3)->setText(QString("%1").arg((int)(127.0*(RollConstant)*sin((180+config.heli.CorrectionAngle + ThisAngle[i])*Pi/180.00))));//Roll
m_ccpm->ccpmAdvancedSettingsTable->item(i,4)->setText(QString("%1").arg((int)(127.0*(PitchConstant)*cos((GUIConfigData.heli.CorrectionAngle + ThisAngle[i])*Pi/180.00))));//Pitch m_ccpm->ccpmAdvancedSettingsTable->item(i,4)->setText(QString("%1").arg((int)(127.0*(PitchConstant)*cos((config.heli.CorrectionAngle + ThisAngle[i])*Pi/180.00))));//Pitch
m_ccpm->ccpmAdvancedSettingsTable->item(i,5)->setText(QString("%1").arg(0));//Yaw m_ccpm->ccpmAdvancedSettingsTable->item(i,5)->setText(QString("%1").arg(0));//Yaw
} }
@ -970,122 +987,140 @@ void ConfigccpmWidget::UpdateMixer()
} }
} }
} }
QString ConfigCcpmWidget::updateConfigObjects()
/**************************
* ccpm settings
**************************/
/*
Get the state of the UI check boxes and change the visibility of sliders
typedef struct {
uint SwasplateType:3;
uint FirstServoIndex:2;
uint CorrectionAngle:9;
uint ccpmCollectivePassthroughState:1;
uint ccpmLinkCyclicState:1;
uint ccpmLinkRollState:1;
uint CollectiveChannel:3;
uint padding:12;
} __attribute__((packed)) heliGUISettingsStruct;
*/
void ConfigccpmWidget::UpdateCCPMOptionsFromUI()
{ {
QString airframeType = "HeliCP";
bool useCCPM; bool useCCPM;
bool useCyclic; bool useCyclic;
if (updatingFromHardware) return; if (updatingFromHardware == TRUE) return airframeType;
updatingFromHardware = TRUE;
//get the user options //get the user options
GUIConfigDataUnion config = GetConfigData();
//swashplate config //swashplate config
GUIConfigData.heli.SwasplateType = m_ccpm->ccpmType->count() - m_ccpm->ccpmType->currentIndex()-1; config.heli.SwashplateType = m_ccpm->ccpmType->count() - m_ccpm->ccpmType->currentIndex()-1;
GUIConfigData.heli.FirstServoIndex = m_ccpm->ccpmSingleServo->currentIndex(); config.heli.FirstServoIndex = m_ccpm->ccpmSingleServo->currentIndex();
//ccpm mixing options //ccpm mixing options
GUIConfigData.heli.ccpmCollectivePassthroughState = m_ccpm->ccpmCollectivePassthrough->isChecked(); config.heli.ccpmCollectivePassthroughState = m_ccpm->ccpmCollectivePassthrough->isChecked();
GUIConfigData.heli.ccpmLinkCyclicState = m_ccpm->ccpmLinkCyclic->isChecked(); config.heli.ccpmLinkCyclicState = m_ccpm->ccpmLinkCyclic->isChecked();
GUIConfigData.heli.ccpmLinkRollState = m_ccpm->ccpmLinkRoll->isChecked(); config.heli.ccpmLinkRollState = m_ccpm->ccpmLinkRoll->isChecked();
useCCPM = !(GUIConfigData.heli.ccpmCollectivePassthroughState || !GUIConfigData.heli.ccpmLinkCyclicState); useCCPM = !(config.heli.ccpmCollectivePassthroughState || !config.heli.ccpmLinkCyclicState);
useCyclic = GUIConfigData.heli.ccpmLinkRollState; useCyclic = config.heli.ccpmLinkRollState;
//correction angle //correction angle
GUIConfigData.heli.CorrectionAngle = m_ccpm->ccpmCorrectionAngle->value(); config.heli.CorrectionAngle = m_ccpm->ccpmCorrectionAngle->value();
//update sliders //update sliders
if (useCCPM) if (useCCPM)
{ {
GUIConfigData.heli.SliderValue0 = m_ccpm->ccpmCollectiveSlider->value(); config.heli.SliderValue0 = m_ccpm->ccpmCollectiveSlider->value();
} }
else else
{ {
GUIConfigData.heli.SliderValue0 = m_ccpm->ccpmCollectiveScale->value(); config.heli.SliderValue0 = m_ccpm->ccpmCollectiveScale->value();
} }
if (useCyclic) if (useCyclic)
{ {
GUIConfigData.heli.SliderValue1 = m_ccpm->ccpmCyclicScale->value(); config.heli.SliderValue1 = m_ccpm->ccpmCyclicScale->value();
} }
else else
{ {
GUIConfigData.heli.SliderValue1 = m_ccpm->ccpmPitchScale->value(); config.heli.SliderValue1 = m_ccpm->ccpmPitchScale->value();
} }
GUIConfigData.heli.SliderValue2 = m_ccpm->ccpmRollScale->value(); config.heli.SliderValue2 = m_ccpm->ccpmRollScale->value();
//servo assignments //servo assignments
GUIConfigData.heli.ServoIndexW = m_ccpm->ccpmServoWChannel->currentIndex(); config.heli.ServoIndexW = m_ccpm->ccpmServoWChannel->currentIndex();
GUIConfigData.heli.ServoIndexX = m_ccpm->ccpmServoXChannel->currentIndex(); config.heli.ServoIndexX = m_ccpm->ccpmServoXChannel->currentIndex();
GUIConfigData.heli.ServoIndexY = m_ccpm->ccpmServoYChannel->currentIndex(); config.heli.ServoIndexY = m_ccpm->ccpmServoYChannel->currentIndex();
GUIConfigData.heli.ServoIndexZ = m_ccpm->ccpmServoZChannel->currentIndex(); config.heli.ServoIndexZ = m_ccpm->ccpmServoZChannel->currentIndex();
//throttle
config.heli.Throttle = m_ccpm->ccpmEngineChannel->currentIndex();
//tail
config.heli.Tail = m_ccpm->ccpmTailChannel->currentIndex();
SetConfigData(config);
updatingFromHardware = FALSE;
return airframeType;
} }
void ConfigccpmWidget::UpdateCCPMUIFromOptions()
QString ConfigCcpmWidget::updateConfigObjectsFromWidgets() //UpdateCCPMOptionsFromUI()
{ {
QString airframeType = updateConfigObjects();
setMixer();
return airframeType;
}
void ConfigCcpmWidget::refreshWidgetsValues(QString frameType) //UpdateCCPMUIFromOptions()
{
Q_UNUSED(frameType);
GUIConfigDataUnion config = GetConfigData();
//swashplate config //swashplate config
m_ccpm->ccpmType->setCurrentIndex(m_ccpm->ccpmType->count() - (GUIConfigData.heli.SwasplateType +1)); setComboCurrentIndex( m_ccpm->ccpmType, m_ccpm->ccpmType->count() - (config.heli.SwashplateType +1));
m_ccpm->ccpmSingleServo->setCurrentIndex(GUIConfigData.heli.FirstServoIndex); setComboCurrentIndex(m_ccpm->ccpmSingleServo, config.heli.FirstServoIndex);
//ccpm mixing options //ccpm mixing options
m_ccpm->ccpmCollectivePassthrough->setChecked(GUIConfigData.heli.ccpmCollectivePassthroughState); m_ccpm->ccpmCollectivePassthrough->setChecked(config.heli.ccpmCollectivePassthroughState);
m_ccpm->ccpmLinkCyclic->setChecked(GUIConfigData.heli.ccpmLinkCyclicState); m_ccpm->ccpmLinkCyclic->setChecked(config.heli.ccpmLinkCyclicState);
m_ccpm->ccpmLinkRoll->setChecked(GUIConfigData.heli.ccpmLinkRollState); m_ccpm->ccpmLinkRoll->setChecked(config.heli.ccpmLinkRollState);
//correction angle //correction angle
m_ccpm->ccpmCorrectionAngle->setValue(GUIConfigData.heli.CorrectionAngle); m_ccpm->ccpmCorrectionAngle->setValue(config.heli.CorrectionAngle);
//update sliders //update sliders
m_ccpm->ccpmCollectiveScale->setValue(GUIConfigData.heli.SliderValue0); m_ccpm->ccpmCollectiveScale->setValue(config.heli.SliderValue0);
m_ccpm->ccpmCollectiveScaleBox->setValue(GUIConfigData.heli.SliderValue0); m_ccpm->ccpmCollectiveScaleBox->setValue(config.heli.SliderValue0);
m_ccpm->ccpmCyclicScale->setValue(GUIConfigData.heli.SliderValue1); m_ccpm->ccpmCyclicScale->setValue(config.heli.SliderValue1);
m_ccpm->ccpmCyclicScaleBox->setValue(GUIConfigData.heli.SliderValue1); m_ccpm->ccpmCyclicScaleBox->setValue(config.heli.SliderValue1);
m_ccpm->ccpmPitchScale->setValue(GUIConfigData.heli.SliderValue1); m_ccpm->ccpmPitchScale->setValue(config.heli.SliderValue1);
m_ccpm->ccpmPitchScaleBox->setValue(GUIConfigData.heli.SliderValue1); m_ccpm->ccpmPitchScaleBox->setValue(config.heli.SliderValue1);
m_ccpm->ccpmRollScale->setValue(GUIConfigData.heli.SliderValue2); m_ccpm->ccpmRollScale->setValue(config.heli.SliderValue2);
m_ccpm->ccpmRollScaleBox->setValue(GUIConfigData.heli.SliderValue2); m_ccpm->ccpmRollScaleBox->setValue(config.heli.SliderValue2);
m_ccpm->ccpmCollectiveSlider->setValue(GUIConfigData.heli.SliderValue0); m_ccpm->ccpmCollectiveSlider->setValue(config.heli.SliderValue0);
m_ccpm->ccpmCollectivespinBox->setValue(GUIConfigData.heli.SliderValue0); m_ccpm->ccpmCollectivespinBox->setValue(config.heli.SliderValue0);
//servo assignments //servo assignments
m_ccpm->ccpmServoWChannel->setCurrentIndex(GUIConfigData.heli.ServoIndexW); setComboCurrentIndex(m_ccpm->ccpmServoWChannel, config.heli.ServoIndexW);
m_ccpm->ccpmServoXChannel->setCurrentIndex(GUIConfigData.heli.ServoIndexX); setComboCurrentIndex( m_ccpm->ccpmServoXChannel,config.heli.ServoIndexX);
m_ccpm->ccpmServoYChannel->setCurrentIndex(GUIConfigData.heli.ServoIndexY); setComboCurrentIndex( m_ccpm->ccpmServoYChannel,config.heli.ServoIndexY);
m_ccpm->ccpmServoZChannel->setCurrentIndex(GUIConfigData.heli.ServoIndexZ); setComboCurrentIndex( m_ccpm->ccpmServoZChannel,config.heli.ServoIndexZ);
//throttle
setComboCurrentIndex( m_ccpm->ccpmEngineChannel, config.heli.Throttle);
//tail
setComboCurrentIndex( m_ccpm->ccpmTailChannel, config.heli.Tail);
getMixer();
} }
void ConfigccpmWidget::SetUIComponentVisibilities() void ConfigCcpmWidget::SetUIComponentVisibilities()
{ {
UpdateCCPMOptionsFromUI();
//set which sliders are user...
m_ccpm->ccpmRevoMixingBox->setVisible(0); m_ccpm->ccpmRevoMixingBox->setVisible(0);
m_ccpm->ccpmPitchMixingBox->setVisible(!GUIConfigData.heli.ccpmCollectivePassthroughState && GUIConfigData.heli.ccpmLinkCyclicState); m_ccpm->ccpmPitchMixingBox->setVisible(!m_ccpm->ccpmCollectivePassthrough->isChecked() &&
m_ccpm->ccpmCollectiveScalingBox->setVisible(GUIConfigData.heli.ccpmCollectivePassthroughState || !GUIConfigData.heli.ccpmLinkCyclicState); m_ccpm->ccpmLinkCyclic->isChecked());
m_ccpm->ccpmLinkCyclic->setVisible(!GUIConfigData.heli.ccpmCollectivePassthroughState); m_ccpm->ccpmCollectiveScalingBox->setVisible(m_ccpm->ccpmCollectivePassthrough->isChecked() || !m_ccpm->ccpmLinkCyclic->isChecked());
m_ccpm->ccpmCyclicScalingBox->setVisible((GUIConfigData.heli.ccpmCollectivePassthroughState || !GUIConfigData.heli.ccpmLinkCyclicState) && GUIConfigData.heli.ccpmLinkRollState); m_ccpm->ccpmLinkCyclic->setVisible(!m_ccpm->ccpmCollectivePassthrough->isChecked());
if (!GUIConfigData.heli.ccpmCollectivePassthroughState && GUIConfigData.heli.ccpmLinkCyclicState)
m_ccpm->ccpmCyclicScalingBox->setVisible((m_ccpm->ccpmCollectivePassthrough->isChecked() || !m_ccpm->ccpmLinkCyclic->isChecked()) &&
m_ccpm->ccpmLinkRoll->isChecked());
if (!m_ccpm->ccpmCollectivePassthrough->checkState() && m_ccpm->ccpmLinkCyclic->isChecked())
{ {
m_ccpm->ccpmPitchScalingBox->setVisible(0); m_ccpm->ccpmPitchScalingBox->setVisible(0);
m_ccpm->ccpmRollScalingBox->setVisible(0); m_ccpm->ccpmRollScalingBox->setVisible(0);
@ -1094,123 +1129,26 @@ void ConfigccpmWidget::SetUIComponentVisibilities()
} }
else else
{ {
m_ccpm->ccpmPitchScalingBox->setVisible(!GUIConfigData.heli.ccpmLinkRollState); m_ccpm->ccpmPitchScalingBox->setVisible(!m_ccpm->ccpmLinkRoll->isChecked());
m_ccpm->ccpmRollScalingBox->setVisible(!GUIConfigData.heli.ccpmLinkRollState); m_ccpm->ccpmRollScalingBox->setVisible(!m_ccpm->ccpmLinkRoll->isChecked());
m_ccpm->ccpmLinkRoll->setVisible(1); m_ccpm->ccpmLinkRoll->setVisible(1);
} }
} }
/** /**
Request the current value of the SystemSettings which holds the ccpm type Request the current value of the SystemSettings which holds the ccpm type
*/ */
void ConfigccpmWidget::requestccpmUpdate() void ConfigCcpmWidget::getMixer()
{ {
#define MaxAngleError 2
int MixerDataFromHeli[8][5];
quint8 MixerOutputType[8];
int EngineChannel,TailRotorChannel,ServoChannels[4],ServoAngles[4],SortAngles[4],ServoCurve2[4];
int NumServos=0;
if (SwashLvlConfigurationInProgress)return; if (SwashLvlConfigurationInProgress)return;
if (updatingToHardware)return; if (updatingToHardware)return;
updatingFromHardware=TRUE; updatingFromHardware=TRUE;
unsigned int i,j; int i;
SystemSettings * systemSettings = SystemSettings::GetInstance(getObjectManager());
Q_ASSERT(systemSettings);
SystemSettings::DataFields systemSettingsData = systemSettings->getData();
Q_ASSERT(SystemSettings::GUICONFIGDATA_NUMELEM ==
(sizeof(GUIConfigData.UAVObject) / sizeof(GUIConfigData.UAVObject[0])));
for(i = 0; i < SystemSettings::GUICONFIGDATA_NUMELEM; i++)
GUIConfigData.UAVObject[i]=systemSettingsData.GUIConfigData[i];
UpdateCCPMUIFromOptions();
// Get existing mixer settings // Get existing mixer settings
MixerSettings * mixerSettings = MixerSettings::GetInstance(getObjectManager()); MixerSettings * mixerSettings = MixerSettings::GetInstance(getObjectManager());
MixerSettings::DataFields mixerSettingsData = mixerSettings->getData(); MixerSettings::DataFields mixerSettingsData = mixerSettings->getData();
//go through the user data and update the mixer matrix
for (j=0;j<5;j++)
{
MixerDataFromHeli[0][j] = mixerSettingsData.Mixer1Vector[j];
MixerDataFromHeli[1][j] = mixerSettingsData.Mixer2Vector[j];
MixerDataFromHeli[2][j] = mixerSettingsData.Mixer3Vector[j];
MixerDataFromHeli[3][j] = mixerSettingsData.Mixer4Vector[j];
MixerDataFromHeli[4][j] = mixerSettingsData.Mixer5Vector[j];
MixerDataFromHeli[5][j] = mixerSettingsData.Mixer6Vector[j];
MixerDataFromHeli[6][j] = mixerSettingsData.Mixer7Vector[j];
MixerDataFromHeli[7][j] = mixerSettingsData.Mixer8Vector[j];
}
MixerOutputType[0] = mixerSettingsData.Mixer1Type;
MixerOutputType[1] = mixerSettingsData.Mixer2Type;
MixerOutputType[2] = mixerSettingsData.Mixer3Type;
MixerOutputType[3] = mixerSettingsData.Mixer4Type;
MixerOutputType[4] = mixerSettingsData.Mixer5Type;
MixerOutputType[5] = mixerSettingsData.Mixer6Type;
MixerOutputType[6] = mixerSettingsData.Mixer7Type;
MixerOutputType[7] = mixerSettingsData.Mixer8Type;
EngineChannel =-1;
TailRotorChannel =-1;
for (j=0;j<5;j++)
{
ServoChannels[j]=8;
ServoCurve2[j]=0;
ServoAngles[j]=0;
SortAngles[j]=j;
}
NumServos=0;
//process the data from Heli and try to figure out the settings...
for (i=0;i<8;i++)
{
//check if this is the engine... Throttle only
if ((MixerOutputType[i] == MixerSettings::MIXER1TYPE_MOTOR)&&
(MixerDataFromHeli[i][0]>0)&&//ThrottleCurve1
(MixerDataFromHeli[i][1]==0)&&//ThrottleCurve2
(MixerDataFromHeli[i][2]==0)&&//Roll
(MixerDataFromHeli[i][3]==0)&&//Pitch
(MixerDataFromHeli[i][4]==0))//Yaw
{
EngineChannel = i;
m_ccpm->ccpmEngineChannel->setCurrentIndex(i);
}
//check if this is the tail rotor... REVO and YAW
if ((MixerOutputType[i] == MixerSettings::MIXER1TYPE_SERVO)&&
//(MixerDataFromHeli[i][0]!=0)&&//ThrottleCurve1
(MixerDataFromHeli[i][1]==0)&&//ThrottleCurve2
(MixerDataFromHeli[i][2]==0)&&//Roll
(MixerDataFromHeli[i][3]==0)&&//Pitch
(MixerDataFromHeli[i][4]!=0))//Yaw
{
TailRotorChannel = i;
m_ccpm->ccpmTailChannel->setCurrentIndex(i);
m_ccpm->ccpmRevoSlider->setValue((MixerDataFromHeli[i][0]*100)/127);
m_ccpm->ccpmREVOspinBox->setValue((MixerDataFromHeli[i][0]*100)/127);
}
//check if this is a swashplate servo... Throttle is zero
if ((MixerOutputType[i] == MixerSettings::MIXER1TYPE_SERVO)&&
(MixerDataFromHeli[i][0]==0)&&//ThrottleCurve1
//(MixerDataFromHeli[i][1]==0)&&//ThrottleCurve2
//(MixerDataFromHeli[i][2]==0)&&//Roll
//(MixerDataFromHeli[i][3]==0)&&//Pitch
(MixerDataFromHeli[i][4]==0))//Yaw
{
ServoChannels[NumServos] = i;//record the channel for this servo
ServoCurve2[NumServos]=MixerDataFromHeli[i][1];//record the ThrottleCurve2 contribution to this servo
ServoAngles[NumServos]=NumServos*45;//make this 0 for the final version
NumServos++;
}
}
//get the settings for the curve from the mixer settings //get the settings for the curve from the mixer settings
for (i=0;i<5;i++) for (i=0;i<5;i++)
{ {
@ -1221,7 +1159,7 @@ void ConfigccpmWidget::requestccpmUpdate()
} }
updatingFromHardware=FALSE; updatingFromHardware=FALSE;
UpdateCCPMUIFromOptions();
ccpmSwashplateUpdate(); ccpmSwashplateUpdate();
} }
@ -1229,24 +1167,14 @@ void ConfigccpmWidget::requestccpmUpdate()
/** /**
Sends the config to the board (ccpm type) Sends the config to the board (ccpm type)
*/ */
void ConfigccpmWidget::sendccpmUpdate() void ConfigCcpmWidget::setMixer()
{ {
int i,j; int i,j;
if (SwashLvlConfigurationInProgress)return; if (SwashLvlConfigurationInProgress)return;
if (updatingToHardware == TRUE) return;
updatingToHardware=TRUE; updatingToHardware=TRUE;
//ShowDisclaimer(1);
UpdateCCPMOptionsFromUI();
// Store the data required to reconstruct
SystemSettings * systemSettings = SystemSettings::GetInstance(getObjectManager());
Q_ASSERT(systemSettings);
SystemSettings::DataFields systemSettingsData = systemSettings->getData();
systemSettingsData.GUIConfigData[0] = GUIConfigData.UAVObject[0];
systemSettingsData.GUIConfigData[1] = GUIConfigData.UAVObject[1];
systemSettings->setData(systemSettingsData);
systemSettings->updated();
MixerSettings * mixerSettings = MixerSettings::GetInstance(getObjectManager()); MixerSettings * mixerSettings = MixerSettings::GetInstance(getObjectManager());
Q_ASSERT(mixerSettings); Q_ASSERT(mixerSettings);
@ -1276,19 +1204,23 @@ void ConfigccpmWidget::sendccpmUpdate()
&mixerSettingsData.Mixer8Type &mixerSettingsData.Mixer8Type
}; };
//reset all to Disabled
for (i=0; i<8; i++)
*mixerTypes[i] = 0;
//go through the user data and update the mixer matrix //go through the user data and update the mixer matrix
for (i=0;i<6;i++) for (i=0;i<6;i++)
{ {
if (MixerChannelData[i]<8) if (MixerChannelData[i]>0)
{ {
//set the mixer type //set the mixer type
*(mixerTypes[MixerChannelData[i]]) = i==0 ? *(mixerTypes[MixerChannelData[i] - 1]) = i==0 ?
MixerSettings::MIXER1TYPE_MOTOR : MixerSettings::MIXER1TYPE_MOTOR :
MixerSettings::MIXER1TYPE_SERVO; MixerSettings::MIXER1TYPE_SERVO;
//config the vector //config the vector
for (j=0;j<5;j++) for (j=0;j<5;j++)
mixers[MixerChannelData[i]][j] = m_ccpm->ccpmAdvancedSettingsTable->item(i,j+1)->text().toInt(); mixers[MixerChannelData[i] - 1][j] = m_ccpm->ccpmAdvancedSettingsTable->item(i,j+1)->text().toInt();
} }
} }
@ -1302,7 +1234,7 @@ void ConfigccpmWidget::sendccpmUpdate()
//mapping of collective input to curve 2... //mapping of collective input to curve 2...
//MixerSettings.Curve2Source = Throttle,Roll,Pitch,Yaw,Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5 //MixerSettings.Curve2Source = Throttle,Roll,Pitch,Yaw,Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5
//check if we are using throttle or directly from a channel... //check if we are using throttle or directly from a channel...
if (GUIConfigData.heli.ccpmCollectivePassthroughState) if (m_ccpm->ccpmCollectivePassthrough->isChecked())
mixerSettingsData.Curve2Source = MixerSettings::CURVE2SOURCE_COLLECTIVE; mixerSettingsData.Curve2Source = MixerSettings::CURVE2SOURCE_COLLECTIVE;
else else
mixerSettingsData.Curve2Source = MixerSettings::CURVE2SOURCE_THROTTLE; mixerSettingsData.Curve2Source = MixerSettings::CURVE2SOURCE_THROTTLE;
@ -1316,18 +1248,19 @@ void ConfigccpmWidget::sendccpmUpdate()
/** /**
Send ccpm type to the board and request saving to SD card Send ccpm type to the board and request saving to SD card
*/ */
void ConfigccpmWidget::saveccpmUpdate() void ConfigCcpmWidget::saveccpmUpdate()
{ {
if (SwashLvlConfigurationInProgress)return; if (SwashLvlConfigurationInProgress)return;
ShowDisclaimer(0); ShowDisclaimer(0);
// Send update so that the latest value is saved // Send update so that the latest value is saved
sendccpmUpdate(); //sendccpmUpdate();
setMixer();
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings"))); UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
Q_ASSERT(obj); Q_ASSERT(obj);
saveObjectToSD(obj); saveObjectToSD(obj);
} }
void ConfigccpmWidget::resizeEvent(QResizeEvent* event) void ConfigCcpmWidget::resizeEvent(QResizeEvent* event)
{ {
Q_UNUSED(event); Q_UNUSED(event);
// Make the custom table columns autostretch: // Make the custom table columns autostretch:
@ -1339,7 +1272,7 @@ void ConfigccpmWidget::resizeEvent(QResizeEvent* event)
ccpmSwashplateRedraw(); ccpmSwashplateRedraw();
} }
void ConfigccpmWidget::showEvent(QShowEvent *event) void ConfigCcpmWidget::showEvent(QShowEvent *event)
{ {
Q_UNUSED(event) Q_UNUSED(event)
m_ccpm->ccpmAdvancedSettingsTable->resizeColumnsToContents(); m_ccpm->ccpmAdvancedSettingsTable->resizeColumnsToContents();
@ -1351,7 +1284,7 @@ void ConfigccpmWidget::showEvent(QShowEvent *event)
} }
void ConfigccpmWidget::SwashLvlStartButtonPressed() void ConfigCcpmWidget::SwashLvlStartButtonPressed()
{ {
QMessageBox msgBox; QMessageBox msgBox;
int i; int i;
@ -1388,7 +1321,8 @@ void ConfigccpmWidget::SwashLvlStartButtonPressed()
//download the current settings to the OP hw //download the current settings to the OP hw
sendccpmUpdate(); //sendccpmUpdate();
setMixer();
//change control mode to gcs control / disarmed //change control mode to gcs control / disarmed
//set throttle to 0 //set throttle to 0
@ -1413,10 +1347,10 @@ void ConfigccpmWidget::SwashLvlStartButtonPressed()
oldSwashLvlConfiguration.ServoChannels[2]=m_ccpm->ccpmServoYChannel->currentIndex(); oldSwashLvlConfiguration.ServoChannels[2]=m_ccpm->ccpmServoYChannel->currentIndex();
oldSwashLvlConfiguration.ServoChannels[3]=m_ccpm->ccpmServoZChannel->currentIndex(); oldSwashLvlConfiguration.ServoChannels[3]=m_ccpm->ccpmServoZChannel->currentIndex();
//if servos are used //if servos are used
oldSwashLvlConfiguration.Used[0]=((m_ccpm->ccpmServoWChannel->currentIndex()<8)&&(m_ccpm->ccpmServoWChannel->isEnabled())); oldSwashLvlConfiguration.Used[0]=((m_ccpm->ccpmServoWChannel->currentIndex()>0)&&(m_ccpm->ccpmServoWChannel->isEnabled()));
oldSwashLvlConfiguration.Used[1]=((m_ccpm->ccpmServoXChannel->currentIndex()<8)&&(m_ccpm->ccpmServoXChannel->isEnabled())); oldSwashLvlConfiguration.Used[1]=((m_ccpm->ccpmServoXChannel->currentIndex()>0)&&(m_ccpm->ccpmServoXChannel->isEnabled()));
oldSwashLvlConfiguration.Used[2]=((m_ccpm->ccpmServoYChannel->currentIndex()<8)&&(m_ccpm->ccpmServoYChannel->isEnabled())); oldSwashLvlConfiguration.Used[2]=((m_ccpm->ccpmServoYChannel->currentIndex()>0)&&(m_ccpm->ccpmServoYChannel->isEnabled()));
oldSwashLvlConfiguration.Used[3]=((m_ccpm->ccpmServoZChannel->currentIndex()<8)&&(m_ccpm->ccpmServoZChannel->isEnabled())); oldSwashLvlConfiguration.Used[3]=((m_ccpm->ccpmServoZChannel->currentIndex()>0)&&(m_ccpm->ccpmServoZChannel->isEnabled()));
//min,neutral,max values for the servos //min,neutral,max values for the servos
for (i=0;i<CCPM_MAX_SWASH_SERVOS;i++) for (i=0;i<CCPM_MAX_SWASH_SERVOS;i++)
{ {
@ -1449,7 +1383,7 @@ void ConfigccpmWidget::SwashLvlStartButtonPressed()
} }
void ConfigccpmWidget::SwashLvlNextButtonPressed() void ConfigCcpmWidget::SwashLvlNextButtonPressed()
{ {
//ShowDisclaimer(2); //ShowDisclaimer(2);
SwashLvlState++; SwashLvlState++;
@ -1552,7 +1486,7 @@ void ConfigccpmWidget::SwashLvlNextButtonPressed()
break; break;
} }
} }
void ConfigccpmWidget::SwashLvlCancelButtonPressed() void ConfigCcpmWidget::SwashLvlCancelButtonPressed()
{ {
int i; int i;
SwashLvlState=0; SwashLvlState=0;
@ -1600,7 +1534,7 @@ void ConfigccpmWidget::SwashLvlCancelButtonPressed()
} }
void ConfigccpmWidget::SwashLvlFinishButtonPressed() void ConfigCcpmWidget::SwashLvlFinishButtonPressed()
{ {
int i; int i;
@ -1644,7 +1578,7 @@ void ConfigccpmWidget::SwashLvlFinishButtonPressed()
} }
int ConfigccpmWidget::ShowDisclaimer(int messageID) int ConfigCcpmWidget::ShowDisclaimer(int messageID)
{ {
QMessageBox msgBox; QMessageBox msgBox;
msgBox.setText("<font color=red><h1>Warning!!!</h2></font>"); msgBox.setText("<font color=red><h1>Warning!!!</h2></font>");
@ -1693,7 +1627,7 @@ int ConfigccpmWidget::ShowDisclaimer(int messageID)
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
*/ */
void ConfigccpmWidget::enableSwashplateLevellingControl(bool state) void ConfigCcpmWidget::enableSwashplateLevellingControl(bool state)
{ {
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>(); UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
@ -1733,7 +1667,7 @@ void ConfigccpmWidget::enableSwashplateLevellingControl(bool state)
Sets the swashplate level to a given value based on current settings for Max, Neutral and Min values. Sets the swashplate level to a given value based on current settings for Max, Neutral and Min values.
level ranges -1 to +1 level ranges -1 to +1
*/ */
void ConfigccpmWidget::setSwashplateLevel(int percent) void ConfigCcpmWidget::setSwashplateLevel(int percent)
{ {
if (percent<0)return;// -1; if (percent<0)return;// -1;
if (percent>100)return;// -1; if (percent>100)return;// -1;
@ -1768,7 +1702,7 @@ return;
} }
void ConfigccpmWidget::SwashLvlSpinBoxChanged(int value) void ConfigCcpmWidget::SwashLvlSpinBoxChanged(int value)
{ {
Q_UNUSED(value); Q_UNUSED(value);
int i; int i;
@ -1808,3 +1742,63 @@ void ConfigccpmWidget::SwashLvlSpinBoxChanged(int value)
return; return;
} }
/**
This function displays text and color formatting in order to help the user understand what channels have not yet been configured.
*/
void ConfigCcpmWidget::throwConfigError(QString airframeType)
{
Q_UNUSED(airframeType);
if((m_ccpm->ccpmServoWChannel->currentIndex()==0)&&(m_ccpm->ccpmServoWChannel->isEnabled()))
{
m_ccpm->ccpmServoWLabel->setText("<font color=red>Servo W</font>");
}
else
{
m_ccpm->ccpmServoWLabel->setText("<font color=black>Servo W</font>");
}
if((m_ccpm->ccpmServoXChannel->currentIndex()==0)&&(m_ccpm->ccpmServoXChannel->isEnabled()))
{
m_ccpm->ccpmServoXLabel->setText("<font color=red>Servo X</font>");
}
else
{
m_ccpm->ccpmServoXLabel->setText("<font color=black>Servo X</font>");
}
if((m_ccpm->ccpmServoYChannel->currentIndex()==0)&&(m_ccpm->ccpmServoYChannel->isEnabled()))
{
m_ccpm->ccpmServoYLabel->setText("<font color=red>Servo Y</font>");
}
else
{
m_ccpm->ccpmServoYLabel->setText("<font color=black>Servo Y</font>");
}
if((m_ccpm->ccpmServoZChannel->currentIndex()==0)&&(m_ccpm->ccpmServoZChannel->isEnabled()))
{
m_ccpm->ccpmServoZLabel->setText("<font color=red>Servo Z</font>");
}
else
{
m_ccpm->ccpmServoZLabel->setText("<font color=black>Servo Z</font>");
}
if((m_ccpm->ccpmEngineChannel->currentIndex()==0)&&(m_ccpm->ccpmEngineChannel->isEnabled()))
{
m_ccpm->ccpmEngineLabel->setText("<font color=red>Engine</font>");
}
else
{
m_ccpm->ccpmEngineLabel->setText("<font color=black>Engine</font>");
}
if((m_ccpm->ccpmTailChannel->currentIndex()==0)&&(m_ccpm->ccpmTailChannel->isEnabled()))
{
m_ccpm->ccpmTailLabel->setText("<font color=red>Tail Rotor</font>");
}
else
{
m_ccpm->ccpmTailLabel->setText("<font color=black>Tail Rotor</font>");
}
}

View File

@ -29,6 +29,7 @@
#include "ui_ccpm.h" #include "ui_ccpm.h"
#include "../uavobjectwidgetutils/configtaskwidget.h" #include "../uavobjectwidgetutils/configtaskwidget.h"
#include "cfg_vehicletypes/vehicleconfig.h"
#include "extensionsystem/pluginmanager.h" #include "extensionsystem/pluginmanager.h"
#include "uavobjectmanager.h" #include "uavobjectmanager.h"
#include "uavobject.h" #include "uavobject.h"
@ -50,36 +51,14 @@ typedef struct {
int Min[CCPM_MAX_SWASH_SERVOS]; int Min[CCPM_MAX_SWASH_SERVOS];
} SwashplateServoSettingsStruct; } SwashplateServoSettingsStruct;
typedef struct {
uint SwasplateType:3;
uint FirstServoIndex:2;
uint CorrectionAngle:9;
uint ccpmCollectivePassthroughState:1;
uint ccpmLinkCyclicState:1;
uint ccpmLinkRollState:1;
uint SliderValue0:7;
uint SliderValue1:7;
uint SliderValue2:7;//41bits
uint ServoIndexW:4;
uint ServoIndexX:4;
uint ServoIndexY:4;
uint ServoIndexZ:4;//57bits
uint padding:7;
} __attribute__((packed)) heliGUISettingsStruct;
typedef union class ConfigCcpmWidget: public VehicleConfig
{
uint UAVObject[2];//32bits * 2
heliGUISettingsStruct heli;//64bits
} GUIConfigDataUnion;
class ConfigccpmWidget: public ConfigTaskWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
ConfigccpmWidget(QWidget *parent = 0); ConfigCcpmWidget(QWidget *parent = 0);
~ConfigccpmWidget(); ~ConfigCcpmWidget();
friend class ConfigVehicleTypeWidget; friend class ConfigVehicleTypeWidget;
@ -87,14 +66,6 @@ private:
Ui_ccpmWidget *m_ccpm; Ui_ccpmWidget *m_ccpm;
QGraphicsSvgItem *SwashplateImg; QGraphicsSvgItem *SwashplateImg;
QGraphicsSvgItem *CurveImg; QGraphicsSvgItem *CurveImg;
//QGraphicsSvgItem *ServoW;
//QGraphicsSvgItem *ServoX;
//QGraphicsSvgItem *ServoY;
//QGraphicsSvgItem *ServoZ;
//QGraphicsTextItem *ServoWText;
//QGraphicsTextItem *ServoXText;
//QGraphicsTextItem *ServoYText;
//QGraphicsTextItem *ServoZText;
QGraphicsSvgItem *Servos[CCPM_MAX_SWASH_SERVOS]; QGraphicsSvgItem *Servos[CCPM_MAX_SWASH_SERVOS];
QGraphicsTextItem *ServosText[CCPM_MAX_SWASH_SERVOS]; QGraphicsTextItem *ServosText[CCPM_MAX_SWASH_SERVOS];
QGraphicsLineItem *ServoLines[CCPM_MAX_SWASH_SERVOS]; QGraphicsLineItem *ServoLines[CCPM_MAX_SWASH_SERVOS];
@ -109,8 +80,6 @@ private:
SwashplateServoSettingsStruct oldSwashLvlConfiguration; SwashplateServoSettingsStruct oldSwashLvlConfiguration;
SwashplateServoSettingsStruct newSwashLvlConfiguration; SwashplateServoSettingsStruct newSwashLvlConfiguration;
GUIConfigDataUnion GUIConfigData;
int MixerChannelData[6]; int MixerChannelData[6];
int ShowDisclaimer(int messageID); int ShowDisclaimer(int messageID);
virtual void enableControls(bool enable) { Q_UNUSED(enable)}; // Not used by this widget virtual void enableControls(bool enable) { Q_UNUSED(enable)}; // Not used by this widget
@ -118,7 +87,16 @@ private:
bool updatingFromHardware; bool updatingFromHardware;
bool updatingToHardware; bool updatingToHardware;
virtual void ResetActuators(GUIConfigDataUnion* configData);
virtual QStringList getChannelDescriptions();
QString updateConfigObjects();
private slots: private slots:
virtual void setupUI(QString airframeType);
virtual void refreshWidgetsValues(QString frameType);
virtual QString updateConfigObjectsFromWidgets();
virtual void throwConfigError(QString airframeType);
void ccpmSwashplateUpdate(); void ccpmSwashplateUpdate();
void ccpmSwashplateRedraw(); void ccpmSwashplateRedraw();
void UpdateCurveSettings(); void UpdateCurveSettings();
@ -135,11 +113,10 @@ private:
void SwashLvlCancelButtonPressed(); void SwashLvlCancelButtonPressed();
void SwashLvlFinishButtonPressed(); void SwashLvlFinishButtonPressed();
void UpdateCCPMOptionsFromUI(); //void UpdateCCPMOptionsFromUI();
void UpdateCCPMUIFromOptions(); //void UpdateCCPMUIFromOptions();
void SetUIComponentVisibilities(); void SetUIComponentVisibilities();
void ccpmChannelCheck();
void enableSwashplateLevellingControl(bool state); void enableSwashplateLevellingControl(bool state);
void setSwashplateLevel(int percent); void setSwashplateLevel(int percent);
@ -147,8 +124,8 @@ private:
virtual void refreshValues() {}; // Not used virtual void refreshValues() {}; // Not used
public slots: public slots:
void requestccpmUpdate(); void getMixer();
void sendccpmUpdate(); void setMixer();
void saveccpmUpdate(); void saveccpmUpdate();
protected: protected:

View File

@ -24,7 +24,7 @@
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
//#include "configfixedwingwidget.h" #include "configfixedwingwidget.h"
#include "configvehicletypewidget.h" #include "configvehicletypewidget.h"
#include "mixersettings.h" #include "mixersettings.h"
@ -40,18 +40,38 @@
#include "mixersettings.h" #include "mixersettings.h"
#include "systemsettings.h" #include "systemsettings.h"
#include "actuatorsettings.h"
#include "actuatorcommand.h" #include "actuatorcommand.h"
/** /**
Helper function to setup the UI Constructor
*/ */
void ConfigVehicleTypeWidget::setupFixedWingUI(QString frameType) ConfigFixedWingWidget::ConfigFixedWingWidget(Ui_AircraftWidget *aircraft, QWidget *parent) : VehicleConfig(parent)
{ {
m_aircraft = aircraft;
}
/**
Destructor
*/
ConfigFixedWingWidget::~ConfigFixedWingWidget()
{
// Do nothing
}
/**
Virtual function to setup the UI
*/
void ConfigFixedWingWidget::setupUI(QString frameType)
{
Q_ASSERT(m_aircraft);
if (frameType == "FixedWing" || frameType == "Elevator aileron rudder") { if (frameType == "FixedWing" || frameType == "Elevator aileron rudder") {
// Setup the UI // Setup the UI
m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Fixed Wing")); setComboCurrentIndex(m_aircraft->aircraftType, m_aircraft->aircraftType->findText("Fixed Wing"));
m_aircraft->fixedWingType->setCurrentIndex(m_aircraft->fixedWingType->findText("Elevator aileron rudder")); setComboCurrentIndex(m_aircraft->fixedWingType, m_aircraft->fixedWingType->findText("Elevator aileron rudder"));
m_aircraft->fwRudder1ChannelBox->setEnabled(true); m_aircraft->fwRudder1ChannelBox->setEnabled(true);
m_aircraft->fwRudder1Label->setEnabled(true); m_aircraft->fwRudder1Label->setEnabled(true);
m_aircraft->fwRudder2ChannelBox->setEnabled(true); m_aircraft->fwRudder2ChannelBox->setEnabled(true);
@ -72,8 +92,8 @@ void ConfigVehicleTypeWidget::setupFixedWingUI(QString frameType)
m_aircraft->elevonMixBox->setHidden(true); m_aircraft->elevonMixBox->setHidden(true);
} else if (frameType == "FixedWingElevon" || frameType == "Elevon") { } else if (frameType == "FixedWingElevon" || frameType == "Elevon") {
m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Fixed Wing")); setComboCurrentIndex(m_aircraft->aircraftType, m_aircraft->aircraftType->findText("Fixed Wing"));
m_aircraft->fixedWingType->setCurrentIndex(m_aircraft->fixedWingType->findText("Elevon")); setComboCurrentIndex(m_aircraft->fixedWingType, m_aircraft->fixedWingType->findText("Elevon"));
m_aircraft->fwAileron1Label->setText("Elevon 1"); m_aircraft->fwAileron1Label->setText("Elevon 1");
m_aircraft->fwAileron2Label->setText("Elevon 2"); m_aircraft->fwAileron2Label->setText("Elevon 2");
m_aircraft->fwElevator1ChannelBox->setEnabled(false); m_aircraft->fwElevator1ChannelBox->setEnabled(false);
@ -91,8 +111,8 @@ void ConfigVehicleTypeWidget::setupFixedWingUI(QString frameType)
m_aircraft->elevonLabel2->setText("Pitch"); m_aircraft->elevonLabel2->setText("Pitch");
} else if (frameType == "FixedWingVtail" || frameType == "Vtail") { } else if (frameType == "FixedWingVtail" || frameType == "Vtail") {
m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Fixed Wing")); setComboCurrentIndex(m_aircraft->aircraftType, m_aircraft->aircraftType->findText("Fixed Wing"));
m_aircraft->fixedWingType->setCurrentIndex(m_aircraft->fixedWingType->findText("Vtail")); setComboCurrentIndex(m_aircraft->fixedWingType, m_aircraft->fixedWingType->findText("Vtail"));
m_aircraft->fwRudder1ChannelBox->setEnabled(false); m_aircraft->fwRudder1ChannelBox->setEnabled(false);
m_aircraft->fwRudder1Label->setEnabled(false); m_aircraft->fwRudder1Label->setEnabled(false);
m_aircraft->fwRudder2ChannelBox->setEnabled(false); m_aircraft->fwRudder2ChannelBox->setEnabled(false);
@ -111,12 +131,53 @@ void ConfigVehicleTypeWidget::setupFixedWingUI(QString frameType)
} }
} }
void ConfigFixedWingWidget::ResetActuators(GUIConfigDataUnion* configData)
{
configData->fixedwing.FixedWingPitch1 = 0;
configData->fixedwing.FixedWingPitch2 = 0;
configData->fixedwing.FixedWingRoll1 = 0;
configData->fixedwing.FixedWingRoll2 = 0;
configData->fixedwing.FixedWingYaw1 = 0;
configData->fixedwing.FixedWingYaw2 = 0;
configData->fixedwing.FixedWingThrottle = 0;
}
QStringList ConfigFixedWingWidget::getChannelDescriptions()
{
int i;
QStringList channelDesc;
// init a channel_numelem list of channel desc defaults
for (i=0; i < (int)(ConfigFixedWingWidget::CHANNEL_NUMELEM); i++)
{
channelDesc.append(QString("-"));
}
// get the gui config data
GUIConfigDataUnion configData = GetConfigData();
if (configData.fixedwing.FixedWingPitch1 > 0)
channelDesc[configData.fixedwing.FixedWingPitch1-1] = QString("FixedWingPitch1");
if (configData.fixedwing.FixedWingPitch2 > 0)
channelDesc[configData.fixedwing.FixedWingPitch2-1] = QString("FixedWingPitch2");
if (configData.fixedwing.FixedWingRoll1 > 0)
channelDesc[configData.fixedwing.FixedWingRoll1-1] = QString("FixedWingRoll1");
if (configData.fixedwing.FixedWingRoll2 > 0)
channelDesc[configData.fixedwing.FixedWingRoll2-1] = QString("FixedWingRoll2");
if (configData.fixedwing.FixedWingYaw1 > 0)
channelDesc[configData.fixedwing.FixedWingYaw1-1] = QString("FixedWingYaw1");
if (configData.fixedwing.FixedWingYaw2 > 0)
channelDesc[configData.fixedwing.FixedWingYaw2-1] = QString("FixedWingYaw2");
if (configData.fixedwing.FixedWingThrottle > 0)
channelDesc[configData.fixedwing.FixedWingThrottle-1] = QString("FixedWingThrottle");
return channelDesc;
}
/** /**
Helper function to update the UI widget objects Virtual function to update the UI widget objects
*/ */
QString ConfigVehicleTypeWidget::updateFixedWingObjectsFromWidgets() QString ConfigFixedWingWidget::updateConfigObjectsFromWidgets()
{ {
QString airframeType = "FixedWing"; QString airframeType = "FixedWing";
@ -145,53 +206,32 @@ QString ConfigVehicleTypeWidget::updateFixedWingObjectsFromWidgets()
setupFrameVtail( airframeType ); setupFrameVtail( airframeType );
} }
// Now reflect those settings in the "Custom" panel as well
updateCustomAirframeUI();
return airframeType; return airframeType;
} }
/** /**
Helper function to refresh the UI widget values Virtual function to refresh the UI widget values
*/ */
void ConfigVehicleTypeWidget::refreshFixedWingWidgetsValues(QString frameType) void ConfigFixedWingWidget::refreshWidgetsValues(QString frameType)
{ {
Q_ASSERT(m_aircraft);
GUIConfigDataUnion config = GetConfigData();
fixedGUISettingsStruct fixed = config.fixedwing;
// Then retrieve how channels are setup
setComboCurrentIndex(m_aircraft->fwEngineChannelBox, fixed.FixedWingThrottle);
setComboCurrentIndex(m_aircraft->fwAileron1ChannelBox, fixed.FixedWingRoll1);
setComboCurrentIndex(m_aircraft->fwAileron2ChannelBox, fixed.FixedWingRoll2);
setComboCurrentIndex(m_aircraft->fwElevator1ChannelBox, fixed.FixedWingPitch1);
setComboCurrentIndex(m_aircraft->fwElevator2ChannelBox, fixed.FixedWingPitch2);
setComboCurrentIndex(m_aircraft->fwRudder1ChannelBox, fixed.FixedWingYaw1);
setComboCurrentIndex(m_aircraft->fwRudder2ChannelBox, fixed.FixedWingYaw2);
UAVDataObject* obj; UAVDataObject* obj;
UAVObjectField *field; UAVObjectField *field;
// Then retrieve how channels are setup
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorSettings")));
Q_ASSERT(obj);
field = obj->getField(QString("FixedWingThrottle"));
Q_ASSERT(field);
m_aircraft->fwEngineChannelBox->setCurrentIndex(m_aircraft->fwEngineChannelBox->findText(field->getValue().toString()));
field = obj->getField(QString("FixedWingRoll1"));
Q_ASSERT(field);
m_aircraft->fwAileron1ChannelBox->setCurrentIndex(m_aircraft->fwAileron1ChannelBox->findText(field->getValue().toString()));
field = obj->getField(QString("FixedWingRoll2"));
Q_ASSERT(field);
m_aircraft->fwAileron2ChannelBox->setCurrentIndex(m_aircraft->fwAileron2ChannelBox->findText(field->getValue().toString()));
field = obj->getField(QString("FixedWingPitch1"));
Q_ASSERT(field);
m_aircraft->fwElevator1ChannelBox->setCurrentIndex(m_aircraft->fwElevator1ChannelBox->findText(field->getValue().toString()));
field = obj->getField(QString("FixedWingPitch2"));
Q_ASSERT(field);
m_aircraft->fwElevator2ChannelBox->setCurrentIndex(m_aircraft->fwElevator2ChannelBox->findText(field->getValue().toString()));
field = obj->getField(QString("FixedWingYaw1"));
Q_ASSERT(field);
m_aircraft->fwRudder1ChannelBox->setCurrentIndex(m_aircraft->fwRudder1ChannelBox->findText(field->getValue().toString()));
field = obj->getField(QString("FixedWingYaw2"));
Q_ASSERT(field);
m_aircraft->fwRudder2ChannelBox->setCurrentIndex(m_aircraft->fwRudder2ChannelBox->findText(field->getValue().toString()));
if (frameType == "FixedWingElevon") { if (frameType == "FixedWingElevon") {
// If the airframe is elevon, restore the slider setting // If the airframe is elevon, restore the slider setting
// Find the channel number for Elevon1 (FixedWingRoll1) // Find the channel number for Elevon1 (FixedWingRoll1)
@ -230,11 +270,11 @@ void ConfigVehicleTypeWidget::refreshFixedWingWidgetsValues(QString frameType)
Returns False if impossible to create the mixer. Returns False if impossible to create the mixer.
*/ */
bool ConfigVehicleTypeWidget::setupFrameFixedWing(QString airframeType) bool ConfigFixedWingWidget::setupFrameFixedWing(QString airframeType)
{ {
// Check coherence: // Check coherence:
//Show any config errors in GUI //Show any config errors in GUI
throwFixedWingChannelConfigError(airframeType); throwConfigError(airframeType);
// - At least Pitch and either Roll or Yaw // - At least Pitch and either Roll or Yaw
if (m_aircraft->fwEngineChannelBox->currentText() == "None" || if (m_aircraft->fwEngineChannelBox->currentText() == "None" ||
@ -245,118 +285,67 @@ bool ConfigVehicleTypeWidget::setupFrameFixedWing(QString airframeType)
// m_aircraft->fwStatusLabel->setText("ERROR: check channel assignment"); // m_aircraft->fwStatusLabel->setText("ERROR: check channel assignment");
return false; return false;
} }
// Now setup the channels: // Now setup the channels:
resetActuators();
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorSettings"))); GUIConfigDataUnion config = GetConfigData();
Q_ASSERT(obj); ResetActuators(&config);
// Elevator config.fixedwing.FixedWingPitch1 = m_aircraft->fwElevator1ChannelBox->currentIndex();
UAVObjectField *field = obj->getField("FixedWingPitch1"); config.fixedwing.FixedWingPitch2 = m_aircraft->fwElevator2ChannelBox->currentIndex();
Q_ASSERT(field); config.fixedwing.FixedWingRoll1 = m_aircraft->fwAileron1ChannelBox->currentIndex();
field->setValue(m_aircraft->fwElevator1ChannelBox->currentText()); config.fixedwing.FixedWingRoll2 = m_aircraft->fwAileron2ChannelBox->currentIndex();
field = obj->getField("FixedWingPitch2"); config.fixedwing.FixedWingYaw1 = m_aircraft->fwRudder1ChannelBox->currentIndex();
Q_ASSERT(field); config.fixedwing.FixedWingThrottle = m_aircraft->fwEngineChannelBox->currentIndex();
field->setValue(m_aircraft->fwElevator2ChannelBox->currentText());
// Aileron SetConfigData(config);
field = obj->getField("FixedWingRoll1");
Q_ASSERT(field);
field->setValue(m_aircraft->fwAileron1ChannelBox->currentText());
field = obj->getField("FixedWingRoll2");
Q_ASSERT(field);
field->setValue(m_aircraft->fwAileron2ChannelBox->currentText());
// Rudder UAVDataObject* mixer = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
field = obj->getField("FixedWingYaw1"); Q_ASSERT(mixer);
Q_ASSERT(field);
field->setValue(m_aircraft->fwRudder1ChannelBox->currentText());
// Throttle
field = obj->getField("FixedWingThrottle");
Q_ASSERT(field);
field->setValue(m_aircraft->fwEngineChannelBox->currentText());
obj->updated();
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
Q_ASSERT(obj);
// ... and compute the matrix: // ... and compute the matrix:
// In order to make code a bit nicer, we assume: // In order to make code a bit nicer, we assume:
// - Channel dropdowns start with 'None', then 0 to 7 // - Channel dropdowns start with 'None', then 0 to 7
// 1. Assign the servo/motor/none for each channel // 1. Assign the servo/motor/none for each channel
// Disable all
foreach(QString mixer, mixerTypes) {
field = obj->getField(mixer);
Q_ASSERT(field);
field->setValue("Disabled");
}
// and set only the relevant channels:
// Engine
int tmpVal = m_aircraft->fwEngineChannelBox->currentIndex()-1;
field = obj->getField(mixerTypes.at(tmpVal));
field->setValue("Motor");
field = obj->getField(mixerVectors.at(tmpVal));
// First of all reset the vector
resetField(field);
int ti = field->getElementNames().indexOf("ThrottleCurve1");
field->setValue(127, ti);
// Rudder int channel;
tmpVal = m_aircraft->fwRudder1ChannelBox->currentIndex()-1; //disable all
// tmpVal will be -1 if rudder is set to "None" for (channel=0; channel<VehicleConfig::CHANNEL_NUMELEM; channel++)
if (tmpVal > -1) { setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_DISABLED);
field = obj->getField(mixerTypes.at(tmpVal));
field->setValue("Servo");
field = obj->getField(mixerVectors.at(tmpVal));
resetField(field);
ti = field->getElementNames().indexOf("Yaw");
field->setValue(127, ti);
} // Else: we have no rudder, only ailerons, we're fine with it.
// Ailerons //motor
tmpVal = m_aircraft->fwAileron1ChannelBox->currentIndex()-1; channel = m_aircraft->fwEngineChannelBox->currentIndex()-1;
if (tmpVal > -1) { setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_MOTOR);
field = obj->getField(mixerTypes.at(tmpVal)); setMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127);
field->setValue("Servo");
field = obj->getField(mixerVectors.at(tmpVal));
resetField(field);
ti = field->getElementNames().indexOf("Roll");
field->setValue(127, ti);
// Only set Aileron 2 if Aileron 1 is defined
tmpVal = m_aircraft->fwAileron2ChannelBox->currentIndex()-1;
if (tmpVal > -1) {
field = obj->getField(mixerTypes.at(tmpVal));
field->setValue("Servo");
field = obj->getField(mixerVectors.at(tmpVal));
resetField(field);
ti = field->getElementNames().indexOf("Roll");
field->setValue(127, ti);
}
} // Else we have no ailerons. Our consistency check guarantees we have
// rudder in this case, so we're fine with it too.
// Elevator //rudder
tmpVal = m_aircraft->fwElevator1ChannelBox->currentIndex()-1; channel = m_aircraft->fwRudder1ChannelBox->currentIndex()-1;
field = obj->getField(mixerTypes.at(tmpVal)); setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO);
field->setValue("Servo"); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, 127);
field = obj->getField(mixerVectors.at(tmpVal));
resetField(field); //ailerons
ti = field->getElementNames().indexOf("Pitch"); channel = m_aircraft->fwAileron1ChannelBox->currentIndex()-1;
field->setValue(127, ti); if (channel > -1) {
// Only set Elevator 2 if it is defined setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO);
tmpVal = m_aircraft->fwElevator2ChannelBox->currentIndex()-1; setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, 127);
if (tmpVal > -1) {
field = obj->getField(mixerTypes.at(tmpVal)); channel = m_aircraft->fwAileron2ChannelBox->currentIndex()-1;
field->setValue("Servo"); setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO);
field = obj->getField(mixerVectors.at(tmpVal)); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, 127);
resetField(field); }
ti = field->getElementNames().indexOf("Pitch");
field->setValue(127, ti); //elevators
channel = m_aircraft->fwElevator1ChannelBox->currentIndex()-1;
if (channel > -1) {
setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO);
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH, 127);
channel = m_aircraft->fwElevator2ChannelBox->currentIndex()-1;
setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO);
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH, 127);
} }
obj->updated();
m_aircraft->fwStatusLabel->setText("Mixer generated"); m_aircraft->fwStatusLabel->setText("Mixer generated");
return true; return true;
@ -367,11 +356,11 @@ bool ConfigVehicleTypeWidget::setupFrameFixedWing(QString airframeType)
/** /**
Setup Elevon Setup Elevon
*/ */
bool ConfigVehicleTypeWidget::setupFrameElevon(QString airframeType) bool ConfigFixedWingWidget::setupFrameElevon(QString airframeType)
{ {
// Check coherence: // Check coherence:
//Show any config errors in GUI //Show any config errors in GUI
throwFixedWingChannelConfigError(airframeType); throwConfigError(airframeType);
// - At least Aileron1 and Aileron 2, and engine // - At least Aileron1 and Aileron 2, and engine
if (m_aircraft->fwEngineChannelBox->currentText() == "None" || if (m_aircraft->fwEngineChannelBox->currentText() == "None" ||
@ -382,106 +371,64 @@ bool ConfigVehicleTypeWidget::setupFrameElevon(QString airframeType)
return false; return false;
} }
resetActuators(); GUIConfigDataUnion config = GetConfigData();
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorSettings"))); ResetActuators(&config);
Q_ASSERT(obj);
// Elevons config.fixedwing.FixedWingRoll1 = m_aircraft->fwAileron1ChannelBox->currentIndex();
UAVObjectField *field = obj->getField("FixedWingRoll1"); config.fixedwing.FixedWingRoll2 = m_aircraft->fwAileron2ChannelBox->currentIndex();
Q_ASSERT(field); config.fixedwing.FixedWingYaw1 = m_aircraft->fwRudder1ChannelBox->currentIndex();
field->setValue(m_aircraft->fwAileron1ChannelBox->currentText()); config.fixedwing.FixedWingYaw2 = m_aircraft->fwRudder2ChannelBox->currentIndex();
field = obj->getField("FixedWingRoll2"); config.fixedwing.FixedWingThrottle = m_aircraft->fwEngineChannelBox->currentIndex();
Q_ASSERT(field);
field->setValue(m_aircraft->fwAileron2ChannelBox->currentText());
// Rudder 1 (can be None)
field = obj->getField("FixedWingYaw1");
Q_ASSERT(field);
field->setValue(m_aircraft->fwRudder1ChannelBox->currentText());
// Rudder 2 (can be None)
field = obj->getField("FixedWingYaw2");
Q_ASSERT(field);
field->setValue(m_aircraft->fwRudder2ChannelBox->currentText());
// Throttle
field = obj->getField("FixedWingThrottle");
Q_ASSERT(field);
field->setValue(m_aircraft->fwEngineChannelBox->currentText());
obj->updated(); SetConfigData(config);
UAVDataObject* mixer = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
Q_ASSERT(mixer);
// Save the curve: // Save the curve:
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
Q_ASSERT(obj);
// ... and compute the matrix: // ... and compute the matrix:
// In order to make code a bit nicer, we assume: // In order to make code a bit nicer, we assume:
// - Channel dropdowns start with 'None', then 0 to 7 // - Channel dropdowns start with 'None', then 0 to 7
// 1. Assign the servo/motor/none for each channel // 1. Assign the servo/motor/none for each channel
// Disable all
foreach(QString mixer, mixerTypes) {
field = obj->getField(mixer);
Q_ASSERT(field);
field->setValue("Disabled");
}
// and set only the relevant channels:
// Engine
int tmpVal = m_aircraft->fwEngineChannelBox->currentIndex()-1;
field = obj->getField(mixerTypes.at(tmpVal));
field->setValue("Motor");
field = obj->getField(mixerVectors.at(tmpVal));
// First of all reset the vector
resetField(field);
int ti = field->getElementNames().indexOf("ThrottleCurve1");
field->setValue(127, ti);
// Rudder 1 int channel;
tmpVal = m_aircraft->fwRudder1ChannelBox->currentIndex()-1; double value;
// tmpVal will be -1 if rudder 1 is set to "None" //disable all
if (tmpVal > -1) { for (channel=0; channel<VehicleConfig::CHANNEL_NUMELEM; channel++)
field = obj->getField(mixerTypes.at(tmpVal)); setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_DISABLED);
field->setValue("Servo");
field = obj->getField(mixerVectors.at(tmpVal));
resetField(field);
ti = field->getElementNames().indexOf("Yaw");
field->setValue(127, ti);
} // Else: we have no rudder, only elevons, we're fine with it.
// Rudder 2 //motor
tmpVal = m_aircraft->fwRudder2ChannelBox->currentIndex()-1; channel = m_aircraft->fwEngineChannelBox->currentIndex()-1;
// tmpVal will be -1 if rudder 2 is set to "None" setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_MOTOR);
if (tmpVal > -1) { setMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127);
field = obj->getField(mixerTypes.at(tmpVal));
field->setValue("Servo");
field = obj->getField(mixerVectors.at(tmpVal));
resetField(field);
ti = field->getElementNames().indexOf("Yaw");
field->setValue(-127, ti);
} // Else: we have no rudder, only elevons, we're fine with it.
tmpVal = m_aircraft->fwAileron1ChannelBox->currentIndex()-1; //rudders
if (tmpVal > -1) { channel = m_aircraft->fwRudder1ChannelBox->currentIndex()-1;
field = obj->getField(mixerTypes.at(tmpVal)); setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO);
field->setValue("Servo"); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, 127);
field = obj->getField(mixerVectors.at(tmpVal));
resetField(field); channel = m_aircraft->fwRudder2ChannelBox->currentIndex()-1;
ti = field->getElementNames().indexOf("Pitch"); setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO);
field->setValue((double)m_aircraft->elevonSlider2->value()*1.27, ti); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, -127);
ti = field->getElementNames().indexOf("Roll");
field->setValue((double)m_aircraft->elevonSlider1->value()*1.27,ti); //ailerons
channel = m_aircraft->fwAileron1ChannelBox->currentIndex()-1;
if (channel > -1) {
setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO);
value = (double)(m_aircraft->elevonSlider2->value()*1.27);
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH, value);
value = (double)(m_aircraft->elevonSlider1->value()*1.27);
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, value);
channel = m_aircraft->fwAileron2ChannelBox->currentIndex()-1;
setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO);
value = (double)(m_aircraft->elevonSlider2->value()*1.27);
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH, value);
value = (double)(m_aircraft->elevonSlider1->value()*1.27);
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, -value);
} }
tmpVal = m_aircraft->fwAileron2ChannelBox->currentIndex()-1;
if (tmpVal > -1) {
field = obj->getField(mixerTypes.at(tmpVal));
field->setValue("Servo");
field = obj->getField(mixerVectors.at(tmpVal));
resetField(field);
ti = field->getElementNames().indexOf("Pitch");
field->setValue((double)m_aircraft->elevonSlider2->value()*1.27, ti);
ti = field->getElementNames().indexOf("Roll");
field->setValue(-(double)m_aircraft->elevonSlider1->value()*1.27,ti);
}
obj->updated();
m_aircraft->fwStatusLabel->setText("Mixer generated"); m_aircraft->fwStatusLabel->setText("Mixer generated");
return true; return true;
} }
@ -491,11 +438,11 @@ bool ConfigVehicleTypeWidget::setupFrameElevon(QString airframeType)
/** /**
Setup VTail Setup VTail
*/ */
bool ConfigVehicleTypeWidget::setupFrameVtail(QString airframeType) bool ConfigFixedWingWidget::setupFrameVtail(QString airframeType)
{ {
// Check coherence: // Check coherence:
//Show any config errors in GUI //Show any config errors in GUI
throwFixedWingChannelConfigError(airframeType); throwConfigError(airframeType);
// - At least Pitch1 and Pitch2, and engine // - At least Pitch1 and Pitch2, and engine
if (m_aircraft->fwEngineChannelBox->currentText() == "None" || if (m_aircraft->fwEngineChannelBox->currentText() == "None" ||
@ -506,97 +453,75 @@ bool ConfigVehicleTypeWidget::setupFrameVtail(QString airframeType)
return false; return false;
} }
resetActuators(); GUIConfigDataUnion config = GetConfigData();
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorSettings"))); ResetActuators(&config);
Q_ASSERT(obj);
// Elevons config.fixedwing.FixedWingPitch1 = m_aircraft->fwElevator1ChannelBox->currentIndex();
UAVObjectField *field = obj->getField("FixedWingPitch1"); config.fixedwing.FixedWingPitch2 = m_aircraft->fwElevator2ChannelBox->currentIndex();
Q_ASSERT(field); config.fixedwing.FixedWingRoll1 = m_aircraft->fwAileron1ChannelBox->currentIndex();
field->setValue(m_aircraft->fwElevator1ChannelBox->currentText()); config.fixedwing.FixedWingRoll2 = m_aircraft->fwAileron2ChannelBox->currentIndex();
field = obj->getField("FixedWingPitch2"); config.fixedwing.FixedWingThrottle = m_aircraft->fwEngineChannelBox->currentIndex();
Q_ASSERT(field);
field->setValue(m_aircraft->fwElevator2ChannelBox->currentText());
field = obj->getField("FixedWingRoll1");
Q_ASSERT(field);
field->setValue(m_aircraft->fwAileron1ChannelBox->currentText());
field = obj->getField("FixedWingRoll2");
Q_ASSERT(field);
field->setValue(m_aircraft->fwAileron2ChannelBox->currentText());
// Throttle SetConfigData(config);
field = obj->getField("FixedWingThrottle");
Q_ASSERT(field);
field->setValue(m_aircraft->fwEngineChannelBox->currentText());
obj->updated(); UAVDataObject* mixer = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
Q_ASSERT(mixer);
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings"))); // Save the curve:
Q_ASSERT(obj);
// ... and compute the matrix: // ... and compute the matrix:
// In order to make code a bit nicer, we assume: // In order to make code a bit nicer, we assume:
// - Channel dropdowns start with 'None', then 0 to 7 // - Channel dropdowns start with 'None', then 0 to 7
// 1. Assign the servo/motor/none for each channel // 1. Assign the servo/motor/none for each channel
// Disable all
foreach(QString mixer, mixerTypes) {
field = obj->getField(mixer);
Q_ASSERT(field);
field->setValue("Disabled");
}
// and set only the relevant channels:
// Engine
int tmpVal = m_aircraft->fwEngineChannelBox->currentIndex()-1;
field = obj->getField(mixerTypes.at(tmpVal));
field->setValue("Motor");
field = obj->getField(mixerVectors.at(tmpVal));
// First of all reset the vector
resetField(field);
int ti = field->getElementNames().indexOf("ThrottleCurve1");
field->setValue(127, ti);
tmpVal = m_aircraft->fwAileron1ChannelBox->currentIndex()-1; int channel;
if (tmpVal > -1) { double value;
field = obj->getField(mixerTypes.at(tmpVal)); //disable all
field->setValue("Servo"); for (channel=0; channel<VehicleConfig::CHANNEL_NUMELEM; channel++)
field = obj->getField(mixerVectors.at(tmpVal)); setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_DISABLED);
resetField(field);
ti = field->getElementNames().indexOf("Roll"); //motor
field->setValue(127,ti); channel = m_aircraft->fwEngineChannelBox->currentIndex()-1;
setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_MOTOR);
setMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127);
//rudders
channel = m_aircraft->fwRudder1ChannelBox->currentIndex()-1;
setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO);
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, 127);
channel = m_aircraft->fwRudder2ChannelBox->currentIndex()-1;
setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO);
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, -127);
//ailerons
channel = m_aircraft->fwAileron1ChannelBox->currentIndex()-1;
if (channel > -1) {
setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO);
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, 127);
channel = m_aircraft->fwAileron2ChannelBox->currentIndex()-1;
setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO);
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, -127);
} }
tmpVal = m_aircraft->fwAileron2ChannelBox->currentIndex()-1; //vtail
if (tmpVal > -1) { channel = m_aircraft->fwElevator1ChannelBox->currentIndex()-1;
field = obj->getField(mixerTypes.at(tmpVal)); if (channel > -1) {
field->setValue("Servo"); setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO);
field = obj->getField(mixerVectors.at(tmpVal)); value = (double)(m_aircraft->elevonSlider2->value()*1.27);
resetField(field); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH, value);
ti = field->getElementNames().indexOf("Roll"); value = (double)(m_aircraft->elevonSlider1->value()*1.27);
field->setValue(-127,ti); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, value);
channel = m_aircraft->fwElevator2ChannelBox->currentIndex()-1;
setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO);
value = (double)(m_aircraft->elevonSlider2->value()*1.27);
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH, value);
value = (double)(m_aircraft->elevonSlider1->value()*1.27);
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, -value);
} }
// Now compute the VTail
tmpVal = m_aircraft->fwElevator1ChannelBox->currentIndex()-1;
field = obj->getField(mixerTypes.at(tmpVal));
field->setValue("Servo");
field = obj->getField(mixerVectors.at(tmpVal));
resetField(field);
ti = field->getElementNames().indexOf("Pitch");
field->setValue((double)m_aircraft->elevonSlider2->value()*1.27, ti);
ti = field->getElementNames().indexOf("Yaw");
field->setValue((double)m_aircraft->elevonSlider1->value()*1.27,ti);
tmpVal = m_aircraft->fwElevator2ChannelBox->currentIndex()-1;
field = obj->getField(mixerTypes.at(tmpVal));
field->setValue("Servo");
field = obj->getField(mixerVectors.at(tmpVal));
resetField(field);
ti = field->getElementNames().indexOf("Pitch");
field->setValue((double)m_aircraft->elevonSlider2->value()*1.27, ti);
ti = field->getElementNames().indexOf("Yaw");
field->setValue(-(double)m_aircraft->elevonSlider1->value()*1.27,ti);
obj->updated();
m_aircraft->fwStatusLabel->setText("Mixer generated"); m_aircraft->fwStatusLabel->setText("Mixer generated");
return true; return true;
} }
@ -604,7 +529,7 @@ bool ConfigVehicleTypeWidget::setupFrameVtail(QString airframeType)
/** /**
This function displays text and color formatting in order to help the user understand what channels have not yet been configured. This function displays text and color formatting in order to help the user understand what channels have not yet been configured.
*/ */
void ConfigVehicleTypeWidget::throwFixedWingChannelConfigError(QString airframeType) void ConfigFixedWingWidget::throwConfigError(QString airframeType)
{ {
//Initialize configuration error flag //Initialize configuration error flag
bool error=false; bool error=false;

View File

@ -0,0 +1,74 @@
/**
******************************************************************************
*
* @file configairframetwidget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
* @{
* @brief Airframe configuration panel
*****************************************************************************/
/*
* 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 CONFIGFIXEDWINGWIDGET_H
#define CONFIGFIXEDWINGWIDGET_H
#include "ui_airframe.h"
#include "../uavobjectwidgetutils/configtaskwidget.h"
#include "extensionsystem/pluginmanager.h"
#include "uavobjectmanager.h"
#include "uavobject.h"
#include "uavtalk/telemetrymanager.h"
#include <QtGui/QWidget>
#include <QList>
#include <QItemDelegate>
class Ui_Widget;
class ConfigFixedWingWidget: public VehicleConfig
{
Q_OBJECT
public:
ConfigFixedWingWidget(Ui_AircraftWidget *aircraft = 0, QWidget *parent = 0);
~ConfigFixedWingWidget();
friend class ConfigVehicleTypeWidget;
private:
Ui_AircraftWidget *m_aircraft;
bool setupFrameFixedWing(QString airframeType);
bool setupFrameElevon(QString airframeType);
bool setupFrameVtail(QString airframeType);
virtual void ResetActuators(GUIConfigDataUnion* configData);
virtual QStringList getChannelDescriptions();
private slots:
virtual void setupUI(QString airframeType);
virtual void refreshWidgetsValues(QString frameType);
virtual QString updateConfigObjectsFromWidgets();
virtual void throwConfigError(QString airframeType);
protected:
};
#endif // CONFIGFIXEDWINGWIDGET_H

View File

@ -24,7 +24,7 @@
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
//#include "configgroundvehiclewidget.h" #include "configgroundvehiclewidget.h"
#include "configvehicletypewidget.h" #include "configvehicletypewidget.h"
#include "mixersettings.h" #include "mixersettings.h"
@ -40,18 +40,35 @@
#include "mixersettings.h" #include "mixersettings.h"
#include "systemsettings.h" #include "systemsettings.h"
#include "actuatorsettings.h"
#include "actuatorcommand.h" #include "actuatorcommand.h"
/** /**
Helper function to setup the UI Constructor
*/ */
void ConfigVehicleTypeWidget::setupGroundVehicleUI(QString frameType) ConfigGroundVehicleWidget::ConfigGroundVehicleWidget(Ui_AircraftWidget *aircraft, QWidget *parent) : VehicleConfig(parent)
{
m_aircraft = aircraft;
}
/**
Destructor
*/
ConfigGroundVehicleWidget::~ConfigGroundVehicleWidget()
{
// Do nothing
}
/**
Virtual function to setup the UI
*/
void ConfigGroundVehicleWidget::setupUI(QString frameType)
{ {
m_aircraft->differentialSteeringMixBox->setHidden(true); m_aircraft->differentialSteeringMixBox->setHidden(true);
//STILL NEEDS WORK //STILL NEEDS WORK
// Setup the UI // Setup the UI
m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Ground")); setComboCurrentIndex(m_aircraft->aircraftType, m_aircraft->aircraftType->findText("Ground"));
m_aircraft->gvEngineChannelBox->setEnabled(false); m_aircraft->gvEngineChannelBox->setEnabled(false);
m_aircraft->gvEngineLabel->setEnabled(false); m_aircraft->gvEngineLabel->setEnabled(false);
@ -64,7 +81,7 @@ void ConfigVehicleTypeWidget::setupGroundVehicleUI(QString frameType)
m_aircraft->gvAileron2Label->setEnabled(false); m_aircraft->gvAileron2Label->setEnabled(false);
if (frameType == "GroundVehicleDifferential" || frameType == "Differential (tank)"){ //Tank if (frameType == "GroundVehicleDifferential" || frameType == "Differential (tank)"){ //Tank
m_aircraft->groundVehicleType->setCurrentIndex(m_aircraft->groundVehicleType->findText("Differential (tank)")); setComboCurrentIndex(m_aircraft->groundVehicleType, m_aircraft->groundVehicleType->findText("Differential (tank)"));
m_aircraft->gvMotor1ChannelBox->setEnabled(true); m_aircraft->gvMotor1ChannelBox->setEnabled(true);
m_aircraft->gvMotor1Label->setEnabled(true); m_aircraft->gvMotor1Label->setEnabled(true);
@ -89,7 +106,7 @@ void ConfigVehicleTypeWidget::setupGroundVehicleUI(QString frameType)
} }
else if (frameType == "GroundVehicleMotorcycle" || frameType == "Motorcycle"){ //Motorcycle else if (frameType == "GroundVehicleMotorcycle" || frameType == "Motorcycle"){ //Motorcycle
m_aircraft->groundVehicleType->setCurrentIndex(m_aircraft->groundVehicleType->findText("Motorcycle")); setComboCurrentIndex(m_aircraft->groundVehicleType, m_aircraft->groundVehicleType->findText("Motorcycle"));
m_aircraft->gvMotor1ChannelBox->setEnabled(false); m_aircraft->gvMotor1ChannelBox->setEnabled(false);
m_aircraft->gvMotor1Label->setEnabled(false); m_aircraft->gvMotor1Label->setEnabled(false);
@ -113,7 +130,7 @@ void ConfigVehicleTypeWidget::setupGroundVehicleUI(QString frameType)
m_aircraft->gvThrottleCurve2GroupBox->setTitle("Rear throttle curve"); m_aircraft->gvThrottleCurve2GroupBox->setTitle("Rear throttle curve");
} }
else {//Car else {//Car
m_aircraft->groundVehicleType->setCurrentIndex(m_aircraft->groundVehicleType->findText("Turnable (car)")); setComboCurrentIndex(m_aircraft->groundVehicleType, m_aircraft->groundVehicleType->findText("Turnable (car)"));
m_aircraft->gvMotor1ChannelBox->setEnabled(true); m_aircraft->gvMotor1ChannelBox->setEnabled(true);
m_aircraft->gvMotor1Label->setEnabled(true); m_aircraft->gvMotor1Label->setEnabled(true);
@ -137,12 +154,46 @@ void ConfigVehicleTypeWidget::setupGroundVehicleUI(QString frameType)
} }
} }
void ConfigGroundVehicleWidget::ResetActuators(GUIConfigDataUnion* configData)
{
configData->ground.GroundVehicleSteering1 = 0;
configData->ground.GroundVehicleSteering2 = 0;
configData->ground.GroundVehicleThrottle1 = 0;
configData->ground.GroundVehicleThrottle2 = 0;
}
QStringList ConfigGroundVehicleWidget::getChannelDescriptions()
{
int i;
QStringList channelDesc;
// init a channel_numelem list of channel desc defaults
for (i=0; i < (int)(ConfigGroundVehicleWidget::CHANNEL_NUMELEM); i++)
{
channelDesc.append(QString("-"));
}
// get the gui config data
GUIConfigDataUnion configData = GetConfigData();
if (configData.ground.GroundVehicleSteering1 > 0)
channelDesc[configData.ground.GroundVehicleSteering1-1] = QString("GroundSteering1");
if (configData.ground.GroundVehicleSteering2 > 0)
channelDesc[configData.ground.GroundVehicleSteering2-1] = QString("GroundSteering2");
if (configData.ground.GroundVehicleThrottle1 > 0)
channelDesc[configData.ground.GroundVehicleThrottle1-1] = QString("GroundThrottle1");
if (configData.ground.GroundVehicleThrottle2 > 0)
channelDesc[configData.ground.GroundVehicleThrottle2-1] = QString("GroundThrottle2");
return channelDesc;
}
/** /**
Helper function to update the UI widget objects Virtual function to update the UI widget objects
*/ */
QString ConfigVehicleTypeWidget::updateGroundVehicleObjectsFromWidgets() QString ConfigGroundVehicleWidget::updateConfigObjectsFromWidgets()
{ {
QString airframeType = "GroundVehicleCar"; QString airframeType = "GroundVehicleCar";
@ -177,54 +228,27 @@ QString ConfigVehicleTypeWidget::updateGroundVehicleObjectsFromWidgets()
setupGroundVehicleMotorcycle(airframeType); setupGroundVehicleMotorcycle(airframeType);
} }
// Now reflect those settings in the "Custom" panel as well
updateCustomAirframeUI();
return airframeType; return airframeType;
} }
/** /**
Helper function to refresh the UI widget values Virtual function to refresh the UI widget values
*/ */
void ConfigVehicleTypeWidget::refreshGroundVehicleWidgetsValues(QString frameType) void ConfigGroundVehicleWidget::refreshWidgetsValues(QString frameType)
{ {
UAVDataObject* obj; UAVDataObject* obj;
UAVObjectField *field; UAVObjectField *field;
GUIConfigDataUnion config = GetConfigData();
//THIS SECTION STILL NEEDS WORK. FOR THE MOMENT, USE THE FIXED-WING ONBOARD SETTING IN ORDER TO MINIMIZE CHANCES OF BOLLOXING REAL CODE //THIS SECTION STILL NEEDS WORK. FOR THE MOMENT, USE THE FIXED-WING ONBOARD SETTING IN ORDER TO MINIMIZE CHANCES OF BOLLOXING REAL CODE
// Retrieve channel setup values // Retrieve channel setup values
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorSettings"))); setComboCurrentIndex(m_aircraft->gvMotor1ChannelBox, config.ground.GroundVehicleThrottle1);
Q_ASSERT(obj); setComboCurrentIndex(m_aircraft->gvMotor2ChannelBox, config.ground.GroundVehicleThrottle2);
field = obj->getField(QString("FixedWingThrottle")); setComboCurrentIndex(m_aircraft->gvSteering1ChannelBox, config.ground.GroundVehicleSteering1);
Q_ASSERT(field); setComboCurrentIndex(m_aircraft->gvSteering2ChannelBox, config.ground.GroundVehicleSteering2);
m_aircraft->gvEngineChannelBox->setCurrentIndex(m_aircraft->gvEngineChannelBox->findText(field->getValue().toString()));
field = obj->getField(QString("FixedWingRoll1"));
Q_ASSERT(field);
m_aircraft->gvAileron1ChannelBox->setCurrentIndex(m_aircraft->gvAileron1ChannelBox->findText(field->getValue().toString()));
field = obj->getField(QString("FixedWingRoll2"));
Q_ASSERT(field);
m_aircraft->gvAileron2ChannelBox->setCurrentIndex(m_aircraft->gvAileron2ChannelBox->findText(field->getValue().toString()));
field = obj->getField(QString("GroundVehicleThrottle1"));
Q_ASSERT(field);
m_aircraft->gvMotor1ChannelBox->setCurrentIndex(m_aircraft->gvMotor1ChannelBox->findText(field->getValue().toString()));
field = obj->getField(QString("GroundVehicleThrottle2"));
Q_ASSERT(field);
m_aircraft->gvMotor2ChannelBox->setCurrentIndex(m_aircraft->gvMotor2ChannelBox->findText(field->getValue().toString()));
field = obj->getField(QString("GroundVehicleSteering1"));
Q_ASSERT(field);
m_aircraft->gvSteering1ChannelBox->setCurrentIndex(m_aircraft->gvSteering1ChannelBox->findText(field->getValue().toString()));
field = obj->getField(QString("GroundVehicleSteering2"));
Q_ASSERT(field);
m_aircraft->gvSteering2ChannelBox->setCurrentIndex(m_aircraft->gvSteering2ChannelBox->findText(field->getValue().toString()));
if (frameType == "GroundVehicleDifferential") { if (frameType == "GroundVehicleDifferential") {
//CURRENTLY BROKEN UNTIL WE DECIDE HOW DIFFERENTIAL SHOULD BEHAVE //CURRENTLY BROKEN UNTIL WE DECIDE HOW DIFFERENTIAL SHOULD BEHAVE
@ -233,14 +257,11 @@ void ConfigVehicleTypeWidget::refreshGroundVehicleWidgetsValues(QString frameTyp
// Find the channel number for Motor1 // Find the channel number for Motor1
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings"))); obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
Q_ASSERT(obj); Q_ASSERT(obj);
int chMixerNumber = m_aircraft->gvMotor1ChannelBox->currentIndex()-1; int channel = m_aircraft->gvMotor1ChannelBox->currentIndex()-1;
if (chMixerNumber >= 0) { // If for some reason the actuators were incoherent, we might fail here, hence the check. if (channel > -1) { // If for some reason the actuators were incoherent, we might fail here, hence the check.
field = obj->getField(mixerVectors.at(chMixerNumber));
int ti = field->getElementNames().indexOf("Roll");
m_aircraft->differentialSteeringSlider1->setValue(field->getDouble(ti)*100);
ti = field->getElementNames().indexOf("Pitch"); m_aircraft->differentialSteeringSlider1->setValue(getMixerVectorValue(obj,channel,VehicleConfig::MIXERVECTOR_ROLL)*100);
m_aircraft->differentialSteeringSlider2->setValue(field->getDouble(ti)*100); m_aircraft->differentialSteeringSlider2->setValue(getMixerVectorValue(obj,channel,VehicleConfig::MIXERVECTOR_PITCH)*100);
} }
} }
if (frameType == "GroundVehicleMotorcycle") { if (frameType == "GroundVehicleMotorcycle") {
@ -260,20 +281,18 @@ void ConfigVehicleTypeWidget::refreshGroundVehicleWidgetsValues(QString frameTyp
} }
/** /**
Setup balancing ground vehicle. Setup balancing ground vehicle.
Returns False if impossible to create the mixer. Returns False if impossible to create the mixer.
*/ */
bool ConfigVehicleTypeWidget::setupGroundVehicleMotorcycle(QString airframeType){ bool ConfigGroundVehicleWidget::setupGroundVehicleMotorcycle(QString airframeType){
// Check coherence: // Check coherence:
//Show any config errors in GUI //Show any config errors in GUI
throwGroundVehicleChannelConfigError(airframeType); throwConfigError(airframeType);
// - Motor, steering, and balance // - Motor, steering, and balance
if (m_aircraft->gvMotor1ChannelBox->currentText() == "None" || if (m_aircraft->gvMotor2ChannelBox->currentText() == "None" ||
(m_aircraft->gvSteering1ChannelBox->currentText() == "None" || (m_aircraft->gvSteering1ChannelBox->currentText() == "None" ||
m_aircraft->gvSteering2ChannelBox->currentText() == "None") ) m_aircraft->gvSteering2ChannelBox->currentText() == "None") )
{ {
@ -282,97 +301,42 @@ bool ConfigVehicleTypeWidget::setupGroundVehicleMotorcycle(QString airframeType)
// Now setup the channels: // Now setup the channels:
resetActuators(); GUIConfigDataUnion config = GetConfigData();
ResetActuators(&config);
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorSettings"))); config.ground.GroundVehicleThrottle1 = m_aircraft->gvMotor1ChannelBox->currentIndex();
Q_ASSERT(obj); config.ground.GroundVehicleThrottle2 = m_aircraft->gvMotor2ChannelBox->currentIndex();
// Left motor SetConfigData(config);
UAVObjectField *field = obj->getField("GroundVehicleThrottle1");
Q_ASSERT(field);
field->setValue(m_aircraft->gvMotor1ChannelBox->currentText());
// Right motor UAVDataObject* mixer = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
field = obj->getField("GroundVehicleThrottle2"); Q_ASSERT(mixer);
Q_ASSERT(field);
field->setValue(m_aircraft->gvMotor2ChannelBox->currentText());
obj->updated();
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
Q_ASSERT(obj);
// ... and compute the matrix:
// In order to make code a bit nicer, we assume:
// - Channel dropdowns start with 'None', then 0 to 7
// 1. Assign the servo/motor/none for each channel
int tmpVal, ti;
// Disable all output channels
foreach(QString mixer, mixerTypes) {
field = obj->getField(mixer);
Q_ASSERT(field);
//Disable output channel
field->setValue("Disabled");
int channel;
//disable all
for (channel=0; channel<VehicleConfig::CHANNEL_NUMELEM; channel++) {
setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_DISABLED);
resetMixerVector(mixer, channel);
} }
// Set all mixer values to zero //motor
foreach(QString mixer, mixerVectors) { channel = m_aircraft->gvMotor2ChannelBox->currentIndex()-1;
field = obj->getField(mixer); setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO);
resetField(field); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127);
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, 127);
ti = field->getElementNames().indexOf("ThrottleCurve1"); //steering
field->setValue(0, ti); channel = m_aircraft->gvSteering1ChannelBox->currentIndex()-1;
ti = field->getElementNames().indexOf("ThrottleCurve2"); setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO);
field->setValue(0, ti); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, -127);
ti = field->getElementNames().indexOf("Yaw"); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, -127);
field->setValue(0, ti);
ti = field->getElementNames().indexOf("Pitch");
field->setValue(0, ti);
ti = field->getElementNames().indexOf("Roll");
field->setValue(0, ti);
}
// Motor //balance
// Setup motor channel = m_aircraft->gvSteering2ChannelBox->currentIndex()-1;
tmpVal = m_aircraft->gvMotor2ChannelBox->currentIndex()-1; setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO);
field = obj->getField(mixerTypes.at(tmpVal)); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, 127);
field->setValue("Servo"); //Set motor mixer type to Servo setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, 127);
field = obj->getField(mixerVectors.at(tmpVal));
resetField(field);
ti = field->getElementNames().indexOf("ThrottleCurve1"); //Set motor to full forward
field->setValue(127, ti);
//Steering
// Setup steering
tmpVal = m_aircraft->gvSteering1ChannelBox->currentIndex()-1;
field = obj->getField(mixerTypes.at(tmpVal));
field->setValue("Servo"); //Set motor mixer type to Servo
field = obj->getField(mixerVectors.at(tmpVal));
resetField(field);
ti = field->getElementNames().indexOf("Yaw"); //Set steering response to roll
field->setValue(-127, ti);
ti = field->getElementNames().indexOf("Roll"); //Set steering response to roll
field->setValue(-127, ti);
//Balancing
// Setup balancing servo
tmpVal = m_aircraft->gvSteering2ChannelBox->currentIndex()-1;
field = obj->getField(mixerTypes.at(tmpVal));
field->setValue("Servo"); //Set motor mixer type to Servo
field = obj->getField(mixerVectors.at(tmpVal));
resetField(field);
ti = field->getElementNames().indexOf("Yaw"); //Set balance response to yaw
field->setValue(127, ti);
ti = field->getElementNames().indexOf("Roll"); //Set balance response to roll
field->setValue(127, ti);
obj->updated();
//Output success message
m_aircraft->gvStatusLabel->setText("Mixer generated"); m_aircraft->gvStatusLabel->setText("Mixer generated");
return true; return true;
@ -385,10 +349,10 @@ bool ConfigVehicleTypeWidget::setupGroundVehicleMotorcycle(QString airframeType)
Returns False if impossible to create the mixer. Returns False if impossible to create the mixer.
*/ */
bool ConfigVehicleTypeWidget::setupGroundVehicleDifferential(QString airframeType){ bool ConfigGroundVehicleWidget::setupGroundVehicleDifferential(QString airframeType){
// Check coherence: // Check coherence:
//Show any config errors in GUI //Show any config errors in GUI
throwGroundVehicleChannelConfigError(airframeType); throwConfigError(airframeType);
// - Left and right steering // - Left and right steering
if ( m_aircraft->gvMotor2ChannelBox->currentText() == "None" || if ( m_aircraft->gvMotor2ChannelBox->currentText() == "None" ||
@ -399,84 +363,35 @@ bool ConfigVehicleTypeWidget::setupGroundVehicleDifferential(QString airframeTyp
// Now setup the channels: // Now setup the channels:
resetActuators(); GUIConfigDataUnion config = GetConfigData();
ResetActuators(&config);
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorSettings"))); config.ground.GroundVehicleThrottle1 = m_aircraft->gvMotor1ChannelBox->currentIndex();
Q_ASSERT(obj); config.ground.GroundVehicleThrottle2 = m_aircraft->gvMotor2ChannelBox->currentIndex();
// Left motor SetConfigData((config));
UAVObjectField *field = obj->getField("GroundVehicleThrottle1");
Q_ASSERT(field);
field->setValue(m_aircraft->gvMotor1ChannelBox->currentText());
// Right motor UAVDataObject* mixer = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
field = obj->getField("GroundVehicleThrottle2"); Q_ASSERT(mixer);
Q_ASSERT(field);
field->setValue(m_aircraft->gvMotor2ChannelBox->currentText());
obj->updated();
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
Q_ASSERT(obj);
// ... and compute the matrix:
// In order to make code a bit nicer, we assume:
// - Channel dropdowns start with 'None', then 0 to 7
// 1. Assign the servo/motor/none for each channel
int tmpVal, ti;
// Disable all output channels
foreach(QString mixer, mixerTypes) {
field = obj->getField(mixer);
Q_ASSERT(field);
//Disable output channel
field->setValue("Disabled");
int channel;
//disable all
for (channel=0; channel<VehicleConfig::CHANNEL_NUMELEM; channel++) {
setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_DISABLED);
resetMixerVector(mixer, channel);
} }
// Set all mixer values to zero //left motor
foreach(QString mixer, mixerVectors) { channel = m_aircraft->gvMotor1ChannelBox->currentIndex()-1;
field = obj->getField(mixer); setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO);
resetField(field); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127);
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, 127);
ti = field->getElementNames().indexOf("ThrottleCurve1"); //right motor
field->setValue(0, ti); channel = m_aircraft->gvMotor2ChannelBox->currentIndex()-1;
ti = field->getElementNames().indexOf("ThrottleCurve2"); setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO);
field->setValue(0, ti); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE2, 127);
ti = field->getElementNames().indexOf("Yaw"); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, -127);
field->setValue(0, ti);
ti = field->getElementNames().indexOf("Pitch");
field->setValue(0, ti);
ti = field->getElementNames().indexOf("Roll");
field->setValue(0, ti);
}
// Motor
// Setup left motor
tmpVal = m_aircraft->gvMotor1ChannelBox->currentIndex()-1;
field = obj->getField(mixerTypes.at(tmpVal));
field->setValue("Servo"); //Set motor mixer type to Servo
field = obj->getField(mixerVectors.at(tmpVal));
resetField(field);
ti = field->getElementNames().indexOf("ThrottleCurve1"); //Set motor to full forward
field->setValue(127, ti);
ti = field->getElementNames().indexOf("Yaw"); //Set motor to turn right with increasing throttle
field->setValue(127, ti);
// Setup right motor
tmpVal = m_aircraft->gvMotor2ChannelBox->currentIndex()-1;
field = obj->getField(mixerTypes.at(tmpVal));
field->setValue("Servo"); //Set motor mixer type to Servo
field = obj->getField(mixerVectors.at(tmpVal));
resetField(field);
ti = field->getElementNames().indexOf("ThrottleCurve2"); //Set motor to full forward
field->setValue(127, ti);
ti = field->getElementNames().indexOf("Yaw"); //Set motor to turn left with increasing throttle
field->setValue(-127, ti);
obj->updated();
//Output success message //Output success message
m_aircraft->gvStatusLabel->setText("Mixer generated"); m_aircraft->gvStatusLabel->setText("Mixer generated");
@ -492,11 +407,11 @@ bool ConfigVehicleTypeWidget::setupGroundVehicleDifferential(QString airframeTyp
Returns False if impossible to create the mixer. Returns False if impossible to create the mixer.
*/ */
bool ConfigVehicleTypeWidget::setupGroundVehicleCar(QString airframeType) bool ConfigGroundVehicleWidget::setupGroundVehicleCar(QString airframeType)
{ {
// Check coherence: // Check coherence:
//Show any config errors in GUI //Show any config errors in GUI
throwGroundVehicleChannelConfigError(airframeType); throwConfigError(airframeType);
// - At least one motor and one steering servo // - At least one motor and one steering servo
if ((m_aircraft->gvMotor1ChannelBox->currentText() == "None" && if ((m_aircraft->gvMotor1ChannelBox->currentText() == "None" &&
@ -506,147 +421,43 @@ bool ConfigVehicleTypeWidget::setupGroundVehicleCar(QString airframeType)
{ {
return false; return false;
} }
// else{
// // m_aircraft->gvStatusLabel->setText("Mixer generated");
// QTextEdit* htmlText=new QTextEdit(m_aircraft->gvSteering1Label->text()); // HtmlText is any QString with html tags.
// m_aircraft->gvSteering1Label->setText(htmlText->toPlainText());
// delete htmlText;
//
// htmlText=new QTextEdit(m_aircraft->gvSteering2Label->text()); // HtmlText is any QString with html tags.
// m_aircraft->gvSteering2Label->setText(htmlText->toPlainText());
// delete htmlText;
//
// htmlText=new QTextEdit(m_aircraft->gvMotor1Label->text()); // HtmlText is any QString with html tags.
// m_aircraft->gvMotor1Label->setText(htmlText->toPlainText());
// delete htmlText;
//
// htmlText=new QTextEdit(m_aircraft->gvMotor2Label->text()); // HtmlText is any QString with html tags.
// m_aircraft->gvMotor2Label->setText(htmlText->toPlainText());
// }
// Now setup the channels: // Now setup the channels:
resetActuators(); GUIConfigDataUnion config = GetConfigData();
ResetActuators(&config);
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorSettings"))); config.ground.GroundVehicleThrottle1 = m_aircraft->gvMotor1ChannelBox->currentIndex();
Q_ASSERT(obj); config.ground.GroundVehicleThrottle2 = m_aircraft->gvMotor2ChannelBox->currentIndex();
config.ground.GroundVehicleSteering1 = m_aircraft->gvSteering1ChannelBox->currentIndex();
config.ground.GroundVehicleSteering2 = m_aircraft->gvSteering2ChannelBox->currentIndex();
// Front motor SetConfigData(config);
UAVObjectField *field = obj->getField("GroundVehicleThrottle1");
Q_ASSERT(field);
field->setValue(m_aircraft->gvMotor1ChannelBox->currentText());
// Rear motor UAVDataObject* mixer = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
field = obj->getField("GroundVehicleThrottle2"); Q_ASSERT(mixer);
Q_ASSERT(field);
field->setValue(m_aircraft->gvMotor2ChannelBox->currentText());
// // Aileron
// field = obj->getField("FixedWingRoll1");
// Q_ASSERT(field);
// field->setValue(m_aircraft->fwAileron1ChannelBox->currentText());
//
// field = obj->getField("FixedWingRoll2");
// Q_ASSERT(field);
// field->setValue(m_aircraft->fwAileron2ChannelBox->currentText());
// Front steering
field = obj->getField("GroundVehicleSteering1");
Q_ASSERT(field);
field->setValue(m_aircraft->gvSteering1ChannelBox->currentText());
// Rear steering
field = obj->getField("GroundVehicleSteering2");
Q_ASSERT(field);
field->setValue(m_aircraft->gvSteering2ChannelBox->currentText());
obj->updated();
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
Q_ASSERT(obj);
// ... and compute the matrix:
// In order to make code a bit nicer, we assume:
// - Channel dropdowns start with 'None', then 0 to 7
// 1. Assign the servo/motor/none for each channel
int tmpVal, ti;
// Disable all output channels
foreach(QString mixer, mixerTypes) {
field = obj->getField(mixer);
Q_ASSERT(field);
//Disable output channel
field->setValue("Disabled");
int channel;
//disable all
for (channel=0; channel<VehicleConfig::CHANNEL_NUMELEM; channel++) {
setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_DISABLED);
resetMixerVector(mixer, channel);
} }
// Set all mixer values to zero channel = m_aircraft->gvSteering1ChannelBox->currentIndex()-1;
foreach(QString mixer, mixerVectors) { setMixerType(mixer,channel, VehicleConfig::MIXERTYPE_SERVO);
field = obj->getField(mixer); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, 127);
resetField(field);
ti = field->getElementNames().indexOf("ThrottleCurve1"); channel = m_aircraft->gvSteering2ChannelBox->currentIndex()-1;
field->setValue(0, ti); setMixerType(mixer,channel, VehicleConfig::MIXERTYPE_SERVO);
ti = field->getElementNames().indexOf("ThrottleCurve2"); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, -127);
field->setValue(0, ti);
ti = field->getElementNames().indexOf("Yaw");
field->setValue(0, ti);
ti = field->getElementNames().indexOf("Pitch");
field->setValue(0, ti);
ti = field->getElementNames().indexOf("Roll");
field->setValue(0, ti);
}
// Steering channel = m_aircraft->gvMotor1ChannelBox->currentIndex()-1;
// Only set front steering if it is defined setMixerType(mixer,channel, VehicleConfig::MIXERTYPE_SERVO);
tmpVal = m_aircraft->gvSteering1ChannelBox->currentIndex()-1; setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127);
// tmpVal will be -1 if steering is set to "None"
if (tmpVal > -1) {
field = obj->getField(mixerTypes.at(tmpVal));
field->setValue("Servo");
field = obj->getField(mixerVectors.at(tmpVal));
resetField(field);
ti = field->getElementNames().indexOf("Yaw");
field->setValue(127, ti);
} // Else: we have no front steering. We're fine with it as long as we have rear steering
// Only set rear steering if it is defined channel = m_aircraft->gvMotor2ChannelBox->currentIndex()-1;
tmpVal = m_aircraft->gvSteering2ChannelBox->currentIndex()-1; setMixerType(mixer,channel, VehicleConfig::MIXERTYPE_SERVO);
// tmpVal will be -1 if steering is set to "None" setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE2, 127);
if (tmpVal > -1) {
field = obj->getField(mixerTypes.at(tmpVal));
field->setValue("Servo");
field = obj->getField(mixerVectors.at(tmpVal));
resetField(field);
ti = field->getElementNames().indexOf("Yaw");
field->setValue(-127, ti);
} // Else: we have no rear steering. We're fine with it as long as we have front steering
// Motor
// Only set front motor if it is defined
tmpVal = m_aircraft->gvMotor1ChannelBox->currentIndex()-1;
if (tmpVal > -1) {
field = obj->getField(mixerTypes.at(tmpVal));
field->setValue("Servo");
field = obj->getField(mixerVectors.at(tmpVal));
resetField(field);
ti = field->getElementNames().indexOf("ThrottleCurve1");
field->setValue(127, ti);
}
// Only set rear motor if it is defined
tmpVal = m_aircraft->gvMotor2ChannelBox->currentIndex()-1;
if (tmpVal > -1) {
field = obj->getField(mixerTypes.at(tmpVal));
field->setValue("Servo");
field = obj->getField(mixerVectors.at(tmpVal));
resetField(field);
ti = field->getElementNames().indexOf("ThrottleCurve2");
field->setValue(127, ti);
}
obj->updated();
//Output success message //Output success message
m_aircraft->gvStatusLabel->setText("Mixer generated"); m_aircraft->gvStatusLabel->setText("Mixer generated");
@ -657,7 +468,7 @@ bool ConfigVehicleTypeWidget::setupGroundVehicleCar(QString airframeType)
/** /**
This function displays text and color formatting in order to help the user understand what channels have not yet been configured. This function displays text and color formatting in order to help the user understand what channels have not yet been configured.
*/ */
void ConfigVehicleTypeWidget::throwGroundVehicleChannelConfigError(QString airframeType) void ConfigGroundVehicleWidget::throwConfigError(QString airframeType)
{ {
//Initialize configuration error flag //Initialize configuration error flag
bool error=false; bool error=false;

View File

@ -0,0 +1,74 @@
/**
******************************************************************************
*
* @file configairframetwidget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
* @{
* @brief Airframe configuration panel
*****************************************************************************/
/*
* 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 CONFIGGROUNDVEHICLEWIDGET_H
#define CONFIGGROUNDVEHICLEWIDGET_H
#include "ui_airframe.h"
#include "../uavobjectwidgetutils/configtaskwidget.h"
#include "extensionsystem/pluginmanager.h"
#include "uavobjectmanager.h"
#include "uavobject.h"
#include "uavtalk/telemetrymanager.h"
#include <QtGui/QWidget>
#include <QList>
#include <QItemDelegate>
class Ui_Widget;
class ConfigGroundVehicleWidget: public VehicleConfig
{
Q_OBJECT
public:
ConfigGroundVehicleWidget(Ui_AircraftWidget *aircraft = 0, QWidget *parent = 0);
~ConfigGroundVehicleWidget();
friend class ConfigVehicleTypeWidget;
private:
Ui_AircraftWidget *m_aircraft;
bool setupGroundVehicleCar(QString airframeType);
bool setupGroundVehicleDifferential(QString airframeType);
bool setupGroundVehicleMotorcycle(QString airframeType);
virtual void ResetActuators(GUIConfigDataUnion* configData);
virtual QStringList getChannelDescriptions();
private slots:
virtual void setupUI(QString airframeType);
virtual void refreshWidgetsValues(QString frameType);
virtual QString updateConfigObjectsFromWidgets();
virtual void throwConfigError(QString airframeType);
protected:
};
#endif // CONFIGGROUNDVEHICLEWIDGET_H

View File

@ -24,8 +24,7 @@
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
//#include "configmultirotorwidget.h" #include "configmultirotorwidget.h"
#include "configvehicletypewidget.h"
#include "mixersettings.h" #include "mixersettings.h"
#include <QDebug> #include <QDebug>
@ -34,200 +33,192 @@
#include <QtGui/QTextEdit> #include <QtGui/QTextEdit>
#include <QtGui/QVBoxLayout> #include <QtGui/QVBoxLayout>
#include <QtGui/QPushButton> #include <QtGui/QPushButton>
#include <QtGui/QComboBox>
#include <QBrush> #include <QBrush>
#include <math.h> #include <math.h>
#include <QMessageBox> #include <QMessageBox>
#include "mixersettings.h" #include "mixersettings.h"
#include "systemsettings.h" #include "systemsettings.h"
#include "actuatorsettings.h"
#include "actuatorcommand.h" #include "actuatorcommand.h"
//#define Pi 3.14159265358979323846 //#define Pi 3.14159265358979323846
/** /**
Helper function to setup the UI Constructor
*/ */
void ConfigVehicleTypeWidget::setupMultiRotorUI(QString frameType) ConfigMultiRotorWidget::ConfigMultiRotorWidget(Ui_AircraftWidget *aircraft, QWidget *parent) : VehicleConfig(parent)
{ {
m_aircraft = aircraft;
}
/**
Destructor
*/
ConfigMultiRotorWidget::~ConfigMultiRotorWidget()
{
// Do nothing
}
void ConfigMultiRotorWidget::setupUI(QString frameType)
{
Q_ASSERT(m_aircraft);
Q_ASSERT(uiowner);
Q_ASSERT(quad);
int i;
// set aircraftType to Multirotor, disable triyaw channel
setComboCurrentIndex(m_aircraft->aircraftType, m_aircraft->aircraftType->findText("Multirotor"));
m_aircraft->triYawChannelBox->setEnabled(false);
// disable all motor channel boxes
for (i=1; i <=8; i++) {
// do it manually so we can turn off any error decorations
QComboBox *combobox = qFindChild<QComboBox*>(uiowner, "multiMotorChannelBox" + QString::number(i));
if (combobox) {
combobox->setEnabled(false);
combobox->setItemData(0, 0, Qt::DecorationRole);
}
}
if (frameType == "Tri" || frameType == "Tricopter Y") { if (frameType == "Tri" || frameType == "Tricopter Y") {
m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Multirotor")); setComboCurrentIndex( m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Tricopter Y"));
m_aircraft->multirotorFrameType->setCurrentIndex(m_aircraft->multirotorFrameType->findText("Tricopter Y"));
quad->setElementId("tri"); quad->setElementId("tri");
//Enable all necessary motor channel boxes... //Enable all necessary motor channel boxes...
for (int i=1; i <=3; i++) { for (i=1; i <=3; i++) {
QComboBox *combobox = qFindChild<QComboBox*>(this, "multiMotorChannelBox" + QString::number(i)); enableComboBox(uiowner, QString("multiMotorChannelBox%0").arg(i), true);
combobox->setEnabled(true);
}
//and grey out all unused motor channel boxes
for (int i=4; i <=8; i++) {
QComboBox *combobox = qFindChild<QComboBox*>(this, "multiMotorChannelBox" + QString::number(i));
combobox->setEnabled(false);
} }
m_aircraft->triYawChannelBox->setEnabled(true); m_aircraft->triYawChannelBox->setEnabled(true);
} else if (frameType == "QuadX" || frameType == "Quad X") { }
m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Multirotor")); else if (frameType == "QuadX" || frameType == "Quad X") {
m_aircraft->multirotorFrameType->setCurrentIndex(m_aircraft->multirotorFrameType->findText("Quad X")); setComboCurrentIndex( m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Quad X"));
quad->setElementId("quad-X"); quad->setElementId("quad-X");
//Enable all necessary motor channel boxes... //Enable all necessary motor channel boxes...
for (int i=1; i <=4; i++) { for (i=1; i <=4; i++) {
QComboBox *combobox = qFindChild<QComboBox*>(this, "multiMotorChannelBox" + QString::number(i)); enableComboBox(uiowner, QString("multiMotorChannelBox%0").arg(i), true);
combobox->setEnabled(true);
}
//and grey out all unused motor channel boxes
for (int i=5; i <=8; i++) {
QComboBox *combobox = qFindChild<QComboBox*>(this, "multiMotorChannelBox" + QString::number(i));
combobox->setEnabled(false);
} }
m_aircraft->triYawChannelBox->setEnabled(false);
m_aircraft->mrRollMixLevel->setValue(50); m_aircraft->mrRollMixLevel->setValue(50);
m_aircraft->mrPitchMixLevel->setValue(50); m_aircraft->mrPitchMixLevel->setValue(50);
m_aircraft->mrYawMixLevel->setValue(50); m_aircraft->mrYawMixLevel->setValue(50);
} else if (frameType == "QuadP" || frameType == "Quad +") { }
m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Multirotor")); else if (frameType == "QuadP" || frameType == "Quad +") {
m_aircraft->multirotorFrameType->setCurrentIndex(m_aircraft->multirotorFrameType->findText("Quad +")); setComboCurrentIndex( m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Quad +"));
quad->setElementId("quad-plus"); quad->setElementId("quad-plus");
//Enable all necessary motor channel boxes... //Enable all necessary motor channel boxes...
for (int i=1; i <=4; i++) { for (i=1; i <=4; i++) {
QComboBox *combobox = qFindChild<QComboBox*>(this, "multiMotorChannelBox" + QString::number(i)); enableComboBox(uiowner, QString("multiMotorChannelBox%0").arg(i), true);
combobox->setEnabled(true);
}
//and grey out all unused motor channel boxes
for (int i=5; i <=8; i++) {
QComboBox *combobox = qFindChild<QComboBox*>(this, "multiMotorChannelBox" + QString::number(i));
combobox->setEnabled(false);
} }
m_aircraft->triYawChannelBox->setEnabled(false);
m_aircraft->mrRollMixLevel->setValue(100); m_aircraft->mrRollMixLevel->setValue(100);
m_aircraft->mrPitchMixLevel->setValue(100); m_aircraft->mrPitchMixLevel->setValue(100);
m_aircraft->mrYawMixLevel->setValue(50); m_aircraft->mrYawMixLevel->setValue(50);
} else if (frameType == "Hexa" || frameType == "Hexacopter") { }
m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Multirotor")); else if (frameType == "Hexa" || frameType == "Hexacopter")
m_aircraft->multirotorFrameType->setCurrentIndex(m_aircraft->multirotorFrameType->findText("Hexacopter")); {
setComboCurrentIndex( m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Hexacopter"));
quad->setElementId("quad-hexa"); quad->setElementId("quad-hexa");
//Enable all necessary motor channel boxes... //Enable all necessary motor channel boxes...
for (int i=1; i <=6; i++) { for (i=1; i <=6; i++) {
QComboBox *combobox = qFindChild<QComboBox*>(this, "multiMotorChannelBox" + QString::number(i)); enableComboBox(uiowner, QString("multiMotorChannelBox%0").arg(i), true);
combobox->setEnabled(true);
}
//and grey out all unused motor channel boxes
for (int i=7; i <=8; i++) {
QComboBox *combobox = qFindChild<QComboBox*>(this, "multiMotorChannelBox" + QString::number(i));
combobox->setEnabled(false);
} }
m_aircraft->triYawChannelBox->setEnabled(false);
m_aircraft->mrRollMixLevel->setValue(50); m_aircraft->mrRollMixLevel->setValue(50);
m_aircraft->mrPitchMixLevel->setValue(33); m_aircraft->mrPitchMixLevel->setValue(33);
m_aircraft->mrYawMixLevel->setValue(33); m_aircraft->mrYawMixLevel->setValue(33);
} else if (frameType == "HexaX" || frameType == "Hexacopter X" ) { }
m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Multirotor")); else if (frameType == "HexaX" || frameType == "Hexacopter X" ) {
m_aircraft->multirotorFrameType->setCurrentIndex(m_aircraft->multirotorFrameType->findText("Hexacopter X")); setComboCurrentIndex( m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Hexacopter X"));
quad->setElementId("quad-hexa-H"); quad->setElementId("quad-hexa-H");
//Enable all necessary motor channel boxes... //Enable all necessary motor channel boxes...
for (int i=1; i <=6; i++) { for (i=1; i <=6; i++) {
QComboBox *combobox = qFindChild<QComboBox*>(this, "multiMotorChannelBox" + QString::number(i)); enableComboBox(uiowner, QString("multiMotorChannelBox%0").arg(i), true);
combobox->setEnabled(true);
}
//and grey out all unused motor channel boxes
for (int i=7; i <=8; i++) {
QComboBox *combobox = qFindChild<QComboBox*>(this, "multiMotorChannelBox" + QString::number(i));
combobox->setEnabled(false);
} }
m_aircraft->triYawChannelBox->setEnabled(false);
m_aircraft->mrRollMixLevel->setValue(33); m_aircraft->mrRollMixLevel->setValue(33);
m_aircraft->mrPitchMixLevel->setValue(50); m_aircraft->mrPitchMixLevel->setValue(50);
m_aircraft->mrYawMixLevel->setValue(33); m_aircraft->mrYawMixLevel->setValue(33);
} else if (frameType == "HexaCoax" || frameType == "Hexacopter Y6") { }
m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Multirotor")); else if (frameType == "HexaCoax" || frameType == "Hexacopter Y6")
m_aircraft->multirotorFrameType->setCurrentIndex(m_aircraft->multirotorFrameType->findText("Hexacopter Y6")); {
setComboCurrentIndex( m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Hexacopter Y6"));
quad->setElementId("hexa-coax"); quad->setElementId("hexa-coax");
//Enable all necessary motor channel boxes... //Enable all necessary motor channel boxes...
for (int i=1; i <=6; i++) { for (i=1; i <=6; i++) {
QComboBox *combobox = qFindChild<QComboBox*>(this, "multiMotorChannelBox" + QString::number(i)); enableComboBox(uiowner, QString("multiMotorChannelBox%0").arg(i), true);
combobox->setEnabled(true);
}
//and grey out all unused motor channel boxes
for (int i=7; i <=8; i++) {
QComboBox *combobox = qFindChild<QComboBox*>(this, "multiMotorChannelBox" + QString::number(i));
combobox->setEnabled(false);
} }
m_aircraft->triYawChannelBox->setEnabled(false);
m_aircraft->mrRollMixLevel->setValue(100); m_aircraft->mrRollMixLevel->setValue(100);
m_aircraft->mrPitchMixLevel->setValue(50); m_aircraft->mrPitchMixLevel->setValue(50);
m_aircraft->mrYawMixLevel->setValue(66); m_aircraft->mrYawMixLevel->setValue(66);
} else if (frameType == "Octo" || frameType == "Octocopter") { }
m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Multirotor")); else if (frameType == "Octo" || frameType == "Octocopter")
m_aircraft->multirotorFrameType->setCurrentIndex(m_aircraft->multirotorFrameType->findText("Octocopter")); {
setComboCurrentIndex( m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Octocopter"));
quad->setElementId("quad-octo"); quad->setElementId("quad-octo");
//Enable all necessary motor channel boxes //Enable all necessary motor channel boxes
for (int i=1; i <=8; i++) { for (i=1; i <=8; i++) {
QComboBox *combobox = qFindChild<QComboBox*>(this, "multiMotorChannelBox" + QString::number(i)); enableComboBox(uiowner, QString("multiMotorChannelBox%0").arg(i), true);
combobox->setEnabled(true);
} }
m_aircraft->triYawChannelBox->setEnabled(false);
m_aircraft->mrRollMixLevel->setValue(33); m_aircraft->mrRollMixLevel->setValue(33);
m_aircraft->mrPitchMixLevel->setValue(33); m_aircraft->mrPitchMixLevel->setValue(33);
m_aircraft->mrYawMixLevel->setValue(25); m_aircraft->mrYawMixLevel->setValue(25);
} else if (frameType == "OctoV" || frameType == "Octocopter V") { }
m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Multirotor")); else if (frameType == "OctoV" || frameType == "Octocopter V")
m_aircraft->multirotorFrameType->setCurrentIndex(m_aircraft->multirotorFrameType->findText("Octocopter V")); {
setComboCurrentIndex( m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Octocopter V"));
quad->setElementId("quad-octo-v"); quad->setElementId("quad-octo-v");
//Enable all necessary motor channel boxes //Enable all necessary motor channel boxes
for (int i=1; i <=8; i++) { for (i=1; i <=8; i++) {
QComboBox *combobox = qFindChild<QComboBox*>(this, "multiMotorChannelBox" + QString::number(i)); enableComboBox(uiowner, QString("multiMotorChannelBox%0").arg(i), true);
combobox->setEnabled(true);
} }
m_aircraft->triYawChannelBox->setEnabled(false);
m_aircraft->mrRollMixLevel->setValue(25); m_aircraft->mrRollMixLevel->setValue(25);
m_aircraft->mrPitchMixLevel->setValue(25); m_aircraft->mrPitchMixLevel->setValue(25);
m_aircraft->mrYawMixLevel->setValue(25); m_aircraft->mrYawMixLevel->setValue(25);
} else if (frameType == "OctoCoaxP" || frameType == "Octo Coax +") { }
m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Multirotor")); else if (frameType == "OctoCoaxP" || frameType == "Octo Coax +")
m_aircraft->multirotorFrameType->setCurrentIndex(m_aircraft->multirotorFrameType->findText("Octo Coax +")); {
setComboCurrentIndex( m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Octo Coax +"));
quad->setElementId("octo-coax-P"); quad->setElementId("octo-coax-P");
//Enable all necessary motor channel boxes //Enable all necessary motor channel boxes
for (int i=1; i <=8; i++) { for (int i=1; i <=8; i++) {
QComboBox *combobox = qFindChild<QComboBox*>(this, "multiMotorChannelBox" + QString::number(i)); enableComboBox(uiowner, QString("multiMotorChannelBox%0").arg(i), true);
combobox->setEnabled(true);
} }
m_aircraft->triYawChannelBox->setEnabled(false);
m_aircraft->mrRollMixLevel->setValue(100); m_aircraft->mrRollMixLevel->setValue(100);
m_aircraft->mrPitchMixLevel->setValue(100); m_aircraft->mrPitchMixLevel->setValue(100);
m_aircraft->mrYawMixLevel->setValue(50); m_aircraft->mrYawMixLevel->setValue(50);
} else if (frameType == "OctoCoaxX" || frameType == "Octo Coax X") { }
m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Multirotor")); else if (frameType == "OctoCoaxX" || frameType == "Octo Coax X")
m_aircraft->multirotorFrameType->setCurrentIndex(m_aircraft->multirotorFrameType->findText("Octo Coax X")); {
setComboCurrentIndex( m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Octo Coax X"));
quad->setElementId("octo-coax-X"); quad->setElementId("octo-coax-X");
//Enable all necessary motor channel boxes //Enable all necessary motor channel boxes
for (int i=1; i <=8; i++) { for (int i=1; i <=8; i++) {
QComboBox *combobox = qFindChild<QComboBox*>(this, "multiMotorChannelBox" + QString::number(i)); enableComboBox(uiowner, QString("multiMotorChannelBox%0").arg(i), true);
combobox->setEnabled(true);
} }
m_aircraft->triYawChannelBox->setEnabled(false);
m_aircraft->mrRollMixLevel->setValue(50); m_aircraft->mrRollMixLevel->setValue(50);
m_aircraft->mrPitchMixLevel->setValue(50); m_aircraft->mrPitchMixLevel->setValue(50);
m_aircraft->mrYawMixLevel->setValue(50); m_aircraft->mrYawMixLevel->setValue(50);
@ -235,12 +226,61 @@ void ConfigVehicleTypeWidget::setupMultiRotorUI(QString frameType)
} }
} }
void ConfigMultiRotorWidget::ResetActuators(GUIConfigDataUnion* configData)
{
configData->multi.VTOLMotorN = 0;
configData->multi.VTOLMotorNE = 0;
configData->multi.VTOLMotorE = 0;
configData->multi.VTOLMotorSE = 0;
configData->multi.VTOLMotorS = 0;
configData->multi.VTOLMotorSW = 0;
configData->multi.VTOLMotorW = 0;
configData->multi.VTOLMotorNW = 0;
configData->multi.TRIYaw = 0;
}
QStringList ConfigMultiRotorWidget::getChannelDescriptions()
{
int i;
QStringList channelDesc;
// init a channel_numelem list of channel desc defaults
for (i=0; i < (int)(ConfigMultiRotorWidget::CHANNEL_NUMELEM); i++)
{
channelDesc.append(QString("-"));
}
// get the gui config data
GUIConfigDataUnion configData = GetConfigData();
multiGUISettingsStruct multi = configData.multi;
if (multi.VTOLMotorN > 0 && multi.VTOLMotorN < ConfigMultiRotorWidget::CHANNEL_NUMELEM)
channelDesc[multi.VTOLMotorN-1] = QString("VTOLMotorN");
if (multi.VTOLMotorNE > 0 && multi.VTOLMotorNE < ConfigMultiRotorWidget::CHANNEL_NUMELEM)
channelDesc[multi.VTOLMotorNE-1] = QString("VTOLMotorNE");
if (multi.VTOLMotorNW > 0 && multi.VTOLMotorNW < ConfigMultiRotorWidget::CHANNEL_NUMELEM)
channelDesc[multi.VTOLMotorNW-1] = QString("VTOLMotorNW");
if (multi.VTOLMotorS > 0 && multi.VTOLMotorS < ConfigMultiRotorWidget::CHANNEL_NUMELEM)
channelDesc[multi.VTOLMotorS-1] = QString("VTOLMotorS");
if (multi.VTOLMotorSE > 0 && multi.VTOLMotorSE < ConfigMultiRotorWidget::CHANNEL_NUMELEM)
channelDesc[multi.VTOLMotorSE-1] = QString("VTOLMotorSE");
if (multi.VTOLMotorSW > 0 && multi.VTOLMotorSW < ConfigMultiRotorWidget::CHANNEL_NUMELEM)
channelDesc[multi.VTOLMotorSW-1] = QString("VTOLMotorSW");
if (multi.VTOLMotorW > 0 && multi.VTOLMotorW < ConfigMultiRotorWidget::CHANNEL_NUMELEM)
channelDesc[multi.VTOLMotorW-1] = QString("VTOLMotorW");
if (multi.VTOLMotorE > 0 && multi.VTOLMotorE < ConfigMultiRotorWidget::CHANNEL_NUMELEM)
channelDesc[multi.VTOLMotorE-1] = QString("VTOLMotorE");
return channelDesc;
}
/** /**
Helper function to update the UI widget objects Helper function to update the UI widget objects
*/ */
QString ConfigVehicleTypeWidget::updateMultiRotorObjectsFromWidgets() QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets()
{ {
QString airframeType; QString airframeType;
QList<QString> motorList; QList<QString> motorList;
@ -279,7 +319,7 @@ QString ConfigVehicleTypeWidget::updateMultiRotorObjectsFromWidgets()
airframeType = "HexaCoax"; airframeType = "HexaCoax";
//Show any config errors in GUI //Show any config errors in GUI
throwMultiRotorChannelConfigError(6); throwConfigError(6);
if (m_aircraft->multiMotorChannelBox1->currentText() == "None" || if (m_aircraft->multiMotorChannelBox1->currentText() == "None" ||
m_aircraft->multiMotorChannelBox2->currentText() == "None" || m_aircraft->multiMotorChannelBox2->currentText() == "None" ||
@ -313,7 +353,7 @@ QString ConfigVehicleTypeWidget::updateMultiRotorObjectsFromWidgets()
airframeType = "Octo"; airframeType = "Octo";
//Show any config errors in GUI //Show any config errors in GUI
throwMultiRotorChannelConfigError(8); throwConfigError(8);
if (m_aircraft->multiMotorChannelBox1->currentText() == "None" || if (m_aircraft->multiMotorChannelBox1->currentText() == "None" ||
m_aircraft->multiMotorChannelBox2->currentText() == "None" || m_aircraft->multiMotorChannelBox2->currentText() == "None" ||
@ -348,7 +388,7 @@ QString ConfigVehicleTypeWidget::updateMultiRotorObjectsFromWidgets()
airframeType = "OctoV"; airframeType = "OctoV";
//Show any config errors in GUI //Show any config errors in GUI
throwMultiRotorChannelConfigError(8); throwConfigError(8);
if (m_aircraft->multiMotorChannelBox1->currentText() == "None" || if (m_aircraft->multiMotorChannelBox1->currentText() == "None" ||
m_aircraft->multiMotorChannelBox2->currentText() == "None" || m_aircraft->multiMotorChannelBox2->currentText() == "None" ||
@ -384,7 +424,7 @@ QString ConfigVehicleTypeWidget::updateMultiRotorObjectsFromWidgets()
airframeType = "OctoCoaxP"; airframeType = "OctoCoaxP";
//Show any config errors in GUI //Show any config errors in GUI
throwMultiRotorChannelConfigError(8); throwConfigError(8);
if (m_aircraft->multiMotorChannelBox1->currentText() == "None" || if (m_aircraft->multiMotorChannelBox1->currentText() == "None" ||
m_aircraft->multiMotorChannelBox2->currentText() == "None" || m_aircraft->multiMotorChannelBox2->currentText() == "None" ||
@ -419,7 +459,7 @@ QString ConfigVehicleTypeWidget::updateMultiRotorObjectsFromWidgets()
airframeType = "OctoCoaxX"; airframeType = "OctoCoaxX";
//Show any config errors in GUI //Show any config errors in GUI
throwMultiRotorChannelConfigError(8); throwConfigError(8);
if (m_aircraft->multiMotorChannelBox1->currentText() == "None" || if (m_aircraft->multiMotorChannelBox1->currentText() == "None" ||
m_aircraft->multiMotorChannelBox2->currentText() == "None" || m_aircraft->multiMotorChannelBox2->currentText() == "None" ||
@ -454,7 +494,7 @@ QString ConfigVehicleTypeWidget::updateMultiRotorObjectsFromWidgets()
airframeType = "Tri"; airframeType = "Tri";
//Show any config errors in GUI //Show any config errors in GUI
throwMultiRotorChannelConfigError(3); throwConfigError(3);
if (m_aircraft->multiMotorChannelBox1->currentText() == "None" || if (m_aircraft->multiMotorChannelBox1->currentText() == "None" ||
m_aircraft->multiMotorChannelBox2->currentText() == "None" || m_aircraft->multiMotorChannelBox2->currentText() == "None" ||
m_aircraft->multiMotorChannelBox3->currentText() == "None" ) { m_aircraft->multiMotorChannelBox3->currentText() == "None" ) {
@ -467,10 +507,11 @@ QString ConfigVehicleTypeWidget::updateMultiRotorObjectsFromWidgets()
} }
motorList << "VTOLMotorNW" << "VTOLMotorNE" << "VTOLMotorS"; motorList << "VTOLMotorNW" << "VTOLMotorNE" << "VTOLMotorS";
setupMotors(motorList); setupMotors(motorList);
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorSettings")));
Q_ASSERT(obj); GUIConfigDataUnion config = GetConfigData();
field = obj->getField("FixedWingYaw1"); config.multi.TRIYaw = m_aircraft->triYawChannelBox->currentIndex();
field->setValue(m_aircraft->triYawChannelBox->currentText()); SetConfigData(config);
// Motor 1 to 6, Y6 Layout: // Motor 1 to 6, Y6 Layout:
// pitch roll yaw // pitch roll yaw
@ -486,20 +527,19 @@ QString ConfigVehicleTypeWidget::updateMultiRotorObjectsFromWidgets()
}; };
setupMultiRotorMixer(mixer); setupMultiRotorMixer(mixer);
int tmpVal = m_aircraft->triYawChannelBox->currentIndex()-1; //tell the mixer about tricopter yaw channel
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings"))); UAVDataObject* mixerObj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
field = obj->getField(mixerTypes.at(tmpVal)); Q_ASSERT(mixerObj);
field->setValue("Servo");
field = obj->getField(mixerVectors.at(tmpVal)); int channel = m_aircraft->triYawChannelBox->currentIndex()-1;
resetField(field); if (channel > -1){
int ti = field->getElementNames().indexOf("Yaw"); setMixerType(mixerObj, channel, VehicleConfig::MIXERTYPE_SERVO);
field->setValue(127,ti); setMixerVectorValue(mixerObj, channel, VehicleConfig::MIXERVECTOR_YAW, 127);
}
m_aircraft->mrStatusLabel->setText("SUCCESS: Mixer Saved OK"); m_aircraft->mrStatusLabel->setText("SUCCESS: Mixer Saved OK");
} }
// Now reflect those settings in the "Custom" panel as well
updateCustomAirframeUI();
return airframeType; return airframeType;
} }
@ -509,341 +549,252 @@ QString ConfigVehicleTypeWidget::updateMultiRotorObjectsFromWidgets()
/** /**
Helper function to refresh the UI widget values Helper function to refresh the UI widget values
*/ */
void ConfigVehicleTypeWidget::refreshMultiRotorWidgetsValues(QString frameType) void ConfigMultiRotorWidget::refreshWidgetsValues(QString frameType)
{ {
////////////////////////////////////////////////////////////////// int channel;
// Retrieve settings double value;
//////////////////////////////////////////////////////////////////
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorSettings"))); GUIConfigDataUnion config = GetConfigData();
Q_ASSERT(obj); multiGUISettingsStruct multi = config.multi;
UAVObjectField *field;
UAVDataObject* mixer = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
Q_ASSERT(mixer);
if (frameType == "QuadP") { if (frameType == "QuadP") {
// Motors 1/2/3/4 are: N / E / S / W // Motors 1/2/3/4 are: N / E / S / W
field = obj->getField(QString("VTOLMotorN")); setComboCurrentIndex(m_aircraft->multiMotorChannelBox1,multi.VTOLMotorN);
Q_ASSERT(field); setComboCurrentIndex(m_aircraft->multiMotorChannelBox2,multi.VTOLMotorE);
m_aircraft->multiMotorChannelBox1->setCurrentIndex(m_aircraft->multiMotorChannelBox1->findText(field->getValue().toString())); setComboCurrentIndex(m_aircraft->multiMotorChannelBox3,multi.VTOLMotorS);
field = obj->getField(QString("VTOLMotorE")); setComboCurrentIndex(m_aircraft->multiMotorChannelBox4,multi.VTOLMotorW);
Q_ASSERT(field);
m_aircraft->multiMotorChannelBox2->setCurrentIndex(m_aircraft->multiMotorChannelBox2->findText(field->getValue().toString()));
field = obj->getField(QString("VTOLMotorS"));
Q_ASSERT(field);
m_aircraft->multiMotorChannelBox3->setCurrentIndex(m_aircraft->multiMotorChannelBox3->findText(field->getValue().toString()));
field = obj->getField(QString("VTOLMotorW"));
Q_ASSERT(field);
m_aircraft->multiMotorChannelBox4->setCurrentIndex(m_aircraft->multiMotorChannelBox4->findText(field->getValue().toString()));
// Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders.
// This assumes that all vectors are identical - if not, the user should use the // This assumes that all vectors are identical - if not, the user should use the
// "custom" setting. // "custom" setting.
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
Q_ASSERT(obj); channel = m_aircraft->multiMotorChannelBox1->currentIndex() - 1;
int tmpVal= m_aircraft->multiMotorChannelBox1->currentIndex()-1; if (channel > -1)
// tmpVal will be -1 if value is set to "None" {
if (tmpVal > -1) { value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH);
field = obj->getField(mixerVectors.at(tmpVal)); m_aircraft->mrPitchMixLevel->setValue( value/1.27 );
int i = field->getElementNames().indexOf("Pitch");
double val = field->getDouble(i)/1.27; value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW);
m_aircraft->mrPitchMixLevel->setValue(val); m_aircraft->mrYawMixLevel->setValue( 1-value/1.27 );
i = field->getElementNames().indexOf("Yaw");
val = (1-field->getDouble(i)/1.27); channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1;
m_aircraft->mrYawMixLevel->setValue(val); value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL);
tmpVal = m_aircraft->multiMotorChannelBox2->currentIndex()-1; m_aircraft->mrRollMixLevel->setValue( -value/1.27);
field = obj->getField(mixerVectors.at(tmpVal));
i = field->getElementNames().indexOf("Roll");
val = -field->getDouble(i)/1.27;
m_aircraft->mrRollMixLevel->setValue(val);
} }
} else if (frameType == "QuadX") { } else if (frameType == "QuadX") {
// Motors 1/2/3/4 are: NW / NE / SE / SW // Motors 1/2/3/4 are: NW / NE / SE / SW
field = obj->getField(QString("VTOLMotorNW")); setComboCurrentIndex(m_aircraft->multiMotorChannelBox1,multi.VTOLMotorNW);
Q_ASSERT(field); setComboCurrentIndex(m_aircraft->multiMotorChannelBox2,multi.VTOLMotorNE);
m_aircraft->multiMotorChannelBox1->setCurrentIndex(m_aircraft->multiMotorChannelBox1->findText(field->getValue().toString())); setComboCurrentIndex(m_aircraft->multiMotorChannelBox3,multi.VTOLMotorSE);
field = obj->getField(QString("VTOLMotorNE")); setComboCurrentIndex(m_aircraft->multiMotorChannelBox4,multi.VTOLMotorSW);
Q_ASSERT(field);
m_aircraft->multiMotorChannelBox2->setCurrentIndex(m_aircraft->multiMotorChannelBox2->findText(field->getValue().toString()));
field = obj->getField(QString("VTOLMotorSE"));
Q_ASSERT(field);
m_aircraft->multiMotorChannelBox3->setCurrentIndex(m_aircraft->multiMotorChannelBox3->findText(field->getValue().toString()));
field = obj->getField(QString("VTOLMotorSW"));
Q_ASSERT(field);
m_aircraft->multiMotorChannelBox4->setCurrentIndex(m_aircraft->multiMotorChannelBox4->findText(field->getValue().toString()));
// Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders.
// This assumes that all vectors are identical - if not, the user should use the // This assumes that all vectors are identical - if not, the user should use the
// "custom" setting. // "custom" setting.
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings"))); channel = m_aircraft->multiMotorChannelBox1->currentIndex() - 1;
Q_ASSERT(obj); if (channel > -1)
int tmpVal= m_aircraft->multiMotorChannelBox1->currentIndex()-1; {
// tmpVal will be -1 if value is set to "None" value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH);
if (tmpVal > -1) { m_aircraft->mrPitchMixLevel->setValue( value/1.27 );
field = obj->getField(mixerVectors.at(tmpVal));
int i = field->getElementNames().indexOf("Pitch"); value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW);
double val = field->getDouble(i)/1.27; m_aircraft->mrYawMixLevel->setValue( 1-value/1.27 );
m_aircraft->mrPitchMixLevel->setValue(val);
i = field->getElementNames().indexOf("Yaw"); value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL);
val = 1-field->getDouble(i)/1.27; m_aircraft->mrRollMixLevel->setValue( value/1.27);
m_aircraft->mrYawMixLevel->setValue(val);
i = field->getElementNames().indexOf("Roll");
val = field->getDouble(i)/1.27;
m_aircraft->mrRollMixLevel->setValue(val);
} }
} else if (frameType == "Hexa") { } else if (frameType == "Hexa") {
// Motors 1/2/3 4/5/6 are: N / NE / SE / S / SW / NW // Motors 1/2/3 4/5/6 are: N / NE / SE / S / SW / NW
field = obj->getField(QString("VTOLMotorN"));
m_aircraft->multiMotorChannelBox1->setCurrentIndex(m_aircraft->multiMotorChannelBox1->findText(field->getValue().toString())); setComboCurrentIndex(m_aircraft->multiMotorChannelBox1,multi.VTOLMotorN);
field = obj->getField(QString("VTOLMotorNE")); setComboCurrentIndex(m_aircraft->multiMotorChannelBox2,multi.VTOLMotorNE);
m_aircraft->multiMotorChannelBox2->setCurrentIndex(m_aircraft->multiMotorChannelBox2->findText(field->getValue().toString())); setComboCurrentIndex(m_aircraft->multiMotorChannelBox3,multi.VTOLMotorSE);
field = obj->getField(QString("VTOLMotorSE")); setComboCurrentIndex(m_aircraft->multiMotorChannelBox4,multi.VTOLMotorS);
m_aircraft->multiMotorChannelBox3->setCurrentIndex(m_aircraft->multiMotorChannelBox3->findText(field->getValue().toString())); setComboCurrentIndex(m_aircraft->multiMotorChannelBox5,multi.VTOLMotorSW);
field = obj->getField(QString("VTOLMotorS")); setComboCurrentIndex(m_aircraft->multiMotorChannelBox6,multi.VTOLMotorNW);
m_aircraft->multiMotorChannelBox4->setCurrentIndex(m_aircraft->multiMotorChannelBox4->findText(field->getValue().toString()));
field = obj->getField(QString("VTOLMotorSW"));
m_aircraft->multiMotorChannelBox5->setCurrentIndex(m_aircraft->multiMotorChannelBox4->findText(field->getValue().toString()));
field = obj->getField(QString("VTOLMotorNW"));
m_aircraft->multiMotorChannelBox6->setCurrentIndex(m_aircraft->multiMotorChannelBox4->findText(field->getValue().toString()));
// Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders.
// This assumes that all vectors are identical - if not, the user should use the // This assumes that all vectors are identical - if not, the user should use the
// "custom" setting. // "custom" setting.
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
int tmpVal= m_aircraft->multiMotorChannelBox1->currentIndex()-1; channel = m_aircraft->multiMotorChannelBox1->currentIndex() - 1;
// tmpVal will be -1 if value is set to "None" if (channel > -1)
if (tmpVal > -1) {
field = obj->getField(mixerVectors.at(tmpVal));
int i = field->getElementNames().indexOf("Pitch");
double val = floor(field->getDouble(i)/1.27);
m_aircraft->mrPitchMixLevel->setValue(val);
i = field->getElementNames().indexOf("Yaw");
val = floor(-field->getDouble(i)/1.27);
m_aircraft->mrYawMixLevel->setValue(val);
tmpVal = m_aircraft->multiMotorChannelBox2->currentIndex()-1;
if(tmpVal>-1)
{ {
field = obj->getField(mixerVectors.at(tmpVal)); value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH);
i = field->getElementNames().indexOf("Roll"); m_aircraft->mrPitchMixLevel->setValue( floor(value/1.27) );
val = floor(1-field->getDouble(i)/1.27);
m_aircraft->mrRollMixLevel->setValue(val); value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW);
} m_aircraft->mrYawMixLevel->setValue( floor(-value/1.27) );
//change channels
channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1;
value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL);
m_aircraft->mrRollMixLevel->setValue( floor(1-value/1.27) );
} }
} else if (frameType == "HexaX") { } else if (frameType == "HexaX") {
// Motors 1/2/3 4/5/6 are: NE / E / SE / SW / W / NW // Motors 1/2/3 4/5/6 are: NE / E / SE / SW / W / NW
field = obj->getField(QString("VTOLMotorNE"));
m_aircraft->multiMotorChannelBox1->setCurrentIndex(m_aircraft->multiMotorChannelBox1->findText(field->getValue().toString())); setComboCurrentIndex(m_aircraft->multiMotorChannelBox1,multi.VTOLMotorNE);
field = obj->getField(QString("VTOLMotorE")); setComboCurrentIndex(m_aircraft->multiMotorChannelBox2,multi.VTOLMotorE);
m_aircraft->multiMotorChannelBox2->setCurrentIndex(m_aircraft->multiMotorChannelBox2->findText(field->getValue().toString())); setComboCurrentIndex(m_aircraft->multiMotorChannelBox3,multi.VTOLMotorSE);
field = obj->getField(QString("VTOLMotorSE")); setComboCurrentIndex(m_aircraft->multiMotorChannelBox4,multi.VTOLMotorSW);
m_aircraft->multiMotorChannelBox3->setCurrentIndex(m_aircraft->multiMotorChannelBox3->findText(field->getValue().toString())); setComboCurrentIndex(m_aircraft->multiMotorChannelBox5,multi.VTOLMotorW);
field = obj->getField(QString("VTOLMotorSW")); setComboCurrentIndex(m_aircraft->multiMotorChannelBox6,multi.VTOLMotorNW);
m_aircraft->multiMotorChannelBox4->setCurrentIndex(m_aircraft->multiMotorChannelBox4->findText(field->getValue().toString()));
field = obj->getField(QString("VTOLMotorW"));
m_aircraft->multiMotorChannelBox5->setCurrentIndex(m_aircraft->multiMotorChannelBox4->findText(field->getValue().toString()));
field = obj->getField(QString("VTOLMotorNW"));
m_aircraft->multiMotorChannelBox6->setCurrentIndex(m_aircraft->multiMotorChannelBox4->findText(field->getValue().toString()));
// Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders.
// This assumes that all vectors are identical - if not, the user should use the // This assumes that all vectors are identical - if not, the user should use the
// "custom" setting. // "custom" setting.
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
int tmpVal= m_aircraft->multiMotorChannelBox1->currentIndex()-1; channel = m_aircraft->multiMotorChannelBox1->currentIndex() - 1;
// tmpVal will be -1 if value is set to "None" if (channel > -1)
if (tmpVal > -1) { {
field = obj->getField(mixerVectors.at(tmpVal)); value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH);
int i = field->getElementNames().indexOf("Pitch"); m_aircraft->mrPitchMixLevel->setValue( floor(value/1.27) );
double val = floor(field->getDouble(i)/1.27);
m_aircraft->mrPitchMixLevel->setValue(val); value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW);
i = field->getElementNames().indexOf("Yaw"); m_aircraft->mrYawMixLevel->setValue( floor(-value/1.27) );
val = floor(-field->getDouble(i)/1.27);
m_aircraft->mrYawMixLevel->setValue(val); channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1;
tmpVal = m_aircraft->multiMotorChannelBox2->currentIndex()-1; value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL);
field = obj->getField(mixerVectors.at(tmpVal)); m_aircraft->mrRollMixLevel->setValue( floor(1-value/1.27) );
i = field->getElementNames().indexOf("Roll");
val = floor(1-field->getDouble(i)/1.27);
m_aircraft->mrRollMixLevel->setValue(val);
} }
} else if (frameType == "HexaCoax") { } else if (frameType == "HexaCoax") {
// Motors 1/2/3 4/5/6 are: NW/W NE/E S/SE // Motors 1/2/3 4/5/6 are: NW/W NE/E S/SE
field = obj->getField(QString("VTOLMotorNW"));
m_aircraft->multiMotorChannelBox1->setCurrentIndex(m_aircraft->multiMotorChannelBox1->findText(field->getValue().toString())); setComboCurrentIndex(m_aircraft->multiMotorChannelBox1,multi.VTOLMotorNW);
field = obj->getField(QString("VTOLMotorW")); setComboCurrentIndex(m_aircraft->multiMotorChannelBox2,multi.VTOLMotorW);
m_aircraft->multiMotorChannelBox2->setCurrentIndex(m_aircraft->multiMotorChannelBox2->findText(field->getValue().toString())); setComboCurrentIndex(m_aircraft->multiMotorChannelBox3,multi.VTOLMotorNE);
field = obj->getField(QString("VTOLMotorNE")); setComboCurrentIndex(m_aircraft->multiMotorChannelBox4,multi.VTOLMotorE);
m_aircraft->multiMotorChannelBox3->setCurrentIndex(m_aircraft->multiMotorChannelBox3->findText(field->getValue().toString())); setComboCurrentIndex(m_aircraft->multiMotorChannelBox5,multi.VTOLMotorS);
field = obj->getField(QString("VTOLMotorE")); setComboCurrentIndex(m_aircraft->multiMotorChannelBox6,multi.VTOLMotorSE);
m_aircraft->multiMotorChannelBox4->setCurrentIndex(m_aircraft->multiMotorChannelBox4->findText(field->getValue().toString()));
field = obj->getField(QString("VTOLMotorS"));
m_aircraft->multiMotorChannelBox5->setCurrentIndex(m_aircraft->multiMotorChannelBox4->findText(field->getValue().toString()));
field = obj->getField(QString("VTOLMotorSE"));
m_aircraft->multiMotorChannelBox6->setCurrentIndex(m_aircraft->multiMotorChannelBox4->findText(field->getValue().toString()));
// Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders.
// This assumes that all vectors are identical - if not, the user should use the // This assumes that all vectors are identical - if not, the user should use the
// "custom" setting. // "custom" setting.
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings"))); channel = m_aircraft->multiMotorChannelBox1->currentIndex() - 1;
int tmpVal= m_aircraft->multiMotorChannelBox1->currentIndex()-1; if (channel > -1)
// tmpVal will be -1 if value is set to "None" {
if (tmpVal > -1) { value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH);
field = obj->getField(mixerVectors.at(tmpVal)); m_aircraft->mrPitchMixLevel->setValue( value/1.27 );
int i = field->getElementNames().indexOf("Pitch");
double val = floor(2*field->getDouble(i)/1.27); value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW);
m_aircraft->mrPitchMixLevel->setValue(val); m_aircraft->mrYawMixLevel->setValue( value/1.27 );
i = field->getElementNames().indexOf("Yaw");
val = floor(-field->getDouble(i)/1.27); channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1;
m_aircraft->mrYawMixLevel->setValue(val); value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL);
i = field->getElementNames().indexOf("Roll"); m_aircraft->mrRollMixLevel->setValue( value/1.27);
val = floor(field->getDouble(i)/1.27);
m_aircraft->mrRollMixLevel->setValue(val);
} }
} else if (frameType == "Octo" || frameType == "OctoV" || } else if (frameType == "Octo" || frameType == "OctoV" ||
frameType == "OctoCoaxP") { frameType == "OctoCoaxP") {
// Motors 1 to 8 are N / NE / E / etc // Motors 1 to 8 are N / NE / E / etc
field = obj->getField(QString("VTOLMotorN"));
Q_ASSERT(field); setComboCurrentIndex(m_aircraft->multiMotorChannelBox1,multi.VTOLMotorN);
m_aircraft->multiMotorChannelBox1->setCurrentIndex(m_aircraft->multiMotorChannelBox1->findText(field->getValue().toString())); setComboCurrentIndex(m_aircraft->multiMotorChannelBox2,multi.VTOLMotorNE);
field = obj->getField(QString("VTOLMotorNE")); setComboCurrentIndex(m_aircraft->multiMotorChannelBox3,multi.VTOLMotorE);
Q_ASSERT(field); setComboCurrentIndex(m_aircraft->multiMotorChannelBox4,multi.VTOLMotorSE);
m_aircraft->multiMotorChannelBox2->setCurrentIndex(m_aircraft->multiMotorChannelBox2->findText(field->getValue().toString())); setComboCurrentIndex(m_aircraft->multiMotorChannelBox5,multi.VTOLMotorS);
field = obj->getField(QString("VTOLMotorE")); setComboCurrentIndex(m_aircraft->multiMotorChannelBox6,multi.VTOLMotorSW);
Q_ASSERT(field); setComboCurrentIndex(m_aircraft->multiMotorChannelBox7,multi.VTOLMotorW);
m_aircraft->multiMotorChannelBox3->setCurrentIndex(m_aircraft->multiMotorChannelBox3->findText(field->getValue().toString())); setComboCurrentIndex(m_aircraft->multiMotorChannelBox8,multi.VTOLMotorNW);
field = obj->getField(QString("VTOLMotorSE"));
Q_ASSERT(field);
m_aircraft->multiMotorChannelBox4->setCurrentIndex(m_aircraft->multiMotorChannelBox4->findText(field->getValue().toString()));
field = obj->getField(QString("VTOLMotorS"));
Q_ASSERT(field);
m_aircraft->multiMotorChannelBox5->setCurrentIndex(m_aircraft->multiMotorChannelBox4->findText(field->getValue().toString()));
field = obj->getField(QString("VTOLMotorSW"));
Q_ASSERT(field);
m_aircraft->multiMotorChannelBox6->setCurrentIndex(m_aircraft->multiMotorChannelBox4->findText(field->getValue().toString()));
field = obj->getField(QString("VTOLMotorW"));
Q_ASSERT(field);
m_aircraft->multiMotorChannelBox7->setCurrentIndex(m_aircraft->multiMotorChannelBox4->findText(field->getValue().toString()));
field = obj->getField(QString("VTOLMotorNW"));
Q_ASSERT(field);
m_aircraft->multiMotorChannelBox8->setCurrentIndex(m_aircraft->multiMotorChannelBox4->findText(field->getValue().toString()));
// Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders.
// This assumes that all vectors are identical - if not, the user should use the // This assumes that all vectors are identical - if not, the user should use the
// "custom" setting. // "custom" setting.
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings"))); channel = m_aircraft->multiMotorChannelBox1->currentIndex() - 1;
int tmpVal= m_aircraft->multiMotorChannelBox1->currentIndex()-1; if (channel > -1)
// tmpVal will be -1 if value is set to "None" {
if (tmpVal > -1) {
if (frameType == "Octo") { if (frameType == "Octo") {
field = obj->getField(mixerVectors.at(tmpVal)); value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH);
int i = field->getElementNames().indexOf("Pitch"); m_aircraft->mrPitchMixLevel->setValue( floor(value/1.27) );
double val = floor(field->getDouble(i)/1.27);
m_aircraft->mrPitchMixLevel->setValue(val);
i = field->getElementNames().indexOf("Yaw");
val = floor(-field->getDouble(i)/1.27);
m_aircraft->mrYawMixLevel->setValue(val);
tmpVal = m_aircraft->multiMotorChannelBox2->currentIndex()-1;
field = obj->getField(mixerVectors.at(tmpVal));
i = field->getElementNames().indexOf("Roll");
val = floor(-field->getDouble(i)/1.27);
m_aircraft->mrRollMixLevel->setValue(val);
} else if (frameType == "OctoV") {
field = obj->getField(mixerVectors.at(tmpVal));
int i = field->getElementNames().indexOf("Yaw");
double val = floor(-field->getDouble(i)/1.27);
m_aircraft->mrYawMixLevel->setValue(val);
i = field->getElementNames().indexOf("Roll");
val = floor(-field->getDouble(i)/1.27);
m_aircraft->mrRollMixLevel->setValue(val);
tmpVal = m_aircraft->multiMotorChannelBox2->currentIndex()-1;
field = obj->getField(mixerVectors.at(tmpVal));
i = field->getElementNames().indexOf("Pitch");
val = floor(field->getDouble(i)/1.27);
m_aircraft->mrPitchMixLevel->setValue(val);
} else if (frameType == "OctoCoaxP") { value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW);
field = obj->getField(mixerVectors.at(tmpVal)); m_aircraft->mrYawMixLevel->setValue( floor(-value/1.27) );
int i = field->getElementNames().indexOf("Pitch");
double val = floor(field->getDouble(i)/1.27);
m_aircraft->mrPitchMixLevel->setValue(val);
i = field->getElementNames().indexOf("Yaw");
val = floor(-field->getDouble(i)/1.27);
m_aircraft->mrYawMixLevel->setValue(val);
tmpVal = m_aircraft->multiMotorChannelBox3->currentIndex()-1;
field = obj->getField(mixerVectors.at(tmpVal));
i = field->getElementNames().indexOf("Roll");
val = floor(-field->getDouble(i)/1.27);
m_aircraft->mrRollMixLevel->setValue(val);
//change channels
channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1;
value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL);
m_aircraft->mrRollMixLevel->setValue( floor(-value/1.27) );
} }
else if (frameType == "OctoV") {
value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH);
m_aircraft->mrPitchMixLevel->setValue( floor(value/1.27) );
value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW);
m_aircraft->mrYawMixLevel->setValue( floor(-value/1.27) );
//change channels
channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1;
value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL);
m_aircraft->mrRollMixLevel->setValue( floor(-value/1.27) );
}
else if (frameType == "OctoCoaxP") {
value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH);
m_aircraft->mrPitchMixLevel->setValue( floor(value/1.27) );
value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW);
m_aircraft->mrYawMixLevel->setValue( floor(-value/1.27) );
//change channels
channel = m_aircraft->multiMotorChannelBox3->currentIndex() - 1;
value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL);
m_aircraft->mrRollMixLevel->setValue( floor(-value/1.27) );
}
} }
} else if (frameType == "OctoCoaxX") { } else if (frameType == "OctoCoaxX") {
// Motors 1 to 8 are N / NE / E / etc // Motors 1 to 8 are N / NE / E / etc
field = obj->getField(QString("VTOLMotorNW"));
Q_ASSERT(field); setComboCurrentIndex(m_aircraft->multiMotorChannelBox1,multi.VTOLMotorNW);
m_aircraft->multiMotorChannelBox1->setCurrentIndex(m_aircraft->multiMotorChannelBox1->findText(field->getValue().toString())); setComboCurrentIndex(m_aircraft->multiMotorChannelBox2,multi.VTOLMotorN);
field = obj->getField(QString("VTOLMotorN")); setComboCurrentIndex(m_aircraft->multiMotorChannelBox3,multi.VTOLMotorNE);
Q_ASSERT(field); setComboCurrentIndex(m_aircraft->multiMotorChannelBox4,multi.VTOLMotorE);
m_aircraft->multiMotorChannelBox2->setCurrentIndex(m_aircraft->multiMotorChannelBox2->findText(field->getValue().toString())); setComboCurrentIndex(m_aircraft->multiMotorChannelBox5,multi.VTOLMotorSE);
field = obj->getField(QString("VTOLMotorNE")); setComboCurrentIndex(m_aircraft->multiMotorChannelBox6,multi.VTOLMotorS);
Q_ASSERT(field); setComboCurrentIndex(m_aircraft->multiMotorChannelBox7,multi.VTOLMotorSW);
m_aircraft->multiMotorChannelBox3->setCurrentIndex(m_aircraft->multiMotorChannelBox3->findText(field->getValue().toString())); setComboCurrentIndex(m_aircraft->multiMotorChannelBox8,multi.VTOLMotorW);
field = obj->getField(QString("VTOLMotorE"));
Q_ASSERT(field);
m_aircraft->multiMotorChannelBox4->setCurrentIndex(m_aircraft->multiMotorChannelBox4->findText(field->getValue().toString()));
field = obj->getField(QString("VTOLMotorSE"));
Q_ASSERT(field);
m_aircraft->multiMotorChannelBox5->setCurrentIndex(m_aircraft->multiMotorChannelBox4->findText(field->getValue().toString()));
field = obj->getField(QString("VTOLMotorS"));
Q_ASSERT(field);
m_aircraft->multiMotorChannelBox6->setCurrentIndex(m_aircraft->multiMotorChannelBox4->findText(field->getValue().toString()));
field = obj->getField(QString("VTOLMotorSW"));
Q_ASSERT(field);
m_aircraft->multiMotorChannelBox7->setCurrentIndex(m_aircraft->multiMotorChannelBox4->findText(field->getValue().toString()));
field = obj->getField(QString("VTOLMotorW"));
Q_ASSERT(field);
m_aircraft->multiMotorChannelBox8->setCurrentIndex(m_aircraft->multiMotorChannelBox4->findText(field->getValue().toString()));
// Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders.
// This assumes that all vectors are identical - if not, the user should use the // This assumes that all vectors are identical - if not, the user should use the
// "custom" setting. // "custom" setting.
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings"))); channel = m_aircraft->multiMotorChannelBox1->currentIndex() - 1;
int tmpVal= m_aircraft->multiMotorChannelBox1->currentIndex()-1; if (channel > -1)
// tmpVal will be -1 if value is set to "None" {
if (tmpVal > -1) { value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH);
field = obj->getField(mixerVectors.at(tmpVal)); m_aircraft->mrPitchMixLevel->setValue( floor(value/1.27) );
int i = field->getElementNames().indexOf("Pitch");
double val = floor(field->getDouble(i)/1.27); value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW);
m_aircraft->mrPitchMixLevel->setValue(val); m_aircraft->mrYawMixLevel->setValue( floor(-value/1.27) );
i = field->getElementNames().indexOf("Yaw");
val = floor(-field->getDouble(i)/1.27); value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL);
m_aircraft->mrYawMixLevel->setValue(val); m_aircraft->mrRollMixLevel->setValue( floor(value/1.27) );
i = field->getElementNames().indexOf("Roll");
val = floor(field->getDouble(i)/1.27);
m_aircraft->mrRollMixLevel->setValue(val);
} }
} else if (frameType == "Tri") { } else if (frameType == "Tri") {
// Motors 1 to 8 are N / NE / E / etc // Motors 1 to 8 are N / NE / E / etc
field = obj->getField(QString("VTOLMotorNW"));
Q_ASSERT(field);
m_aircraft->multiMotorChannelBox1->setCurrentIndex(m_aircraft->multiMotorChannelBox1->findText(field->getValue().toString()));
field = obj->getField(QString("VTOLMotorNE"));
Q_ASSERT(field);
m_aircraft->multiMotorChannelBox2->setCurrentIndex(m_aircraft->multiMotorChannelBox2->findText(field->getValue().toString()));
field = obj->getField(QString("VTOLMotorS"));
Q_ASSERT(field);
m_aircraft->multiMotorChannelBox3->setCurrentIndex(m_aircraft->multiMotorChannelBox3->findText(field->getValue().toString()));
field = obj->getField(QString("FixedWingYaw1"));
Q_ASSERT(field);
m_aircraft->triYawChannelBox->setCurrentIndex(m_aircraft->multiMotorChannelBox3->findText(field->getValue().toString()));
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings"))); setComboCurrentIndex(m_aircraft->multiMotorChannelBox1,multi.VTOLMotorNW);
int tmpVal= m_aircraft->multiMotorChannelBox1->currentIndex()-1; setComboCurrentIndex(m_aircraft->multiMotorChannelBox2,multi.VTOLMotorNE);
// tmpVal will be -1 if value is set to "None" setComboCurrentIndex(m_aircraft->multiMotorChannelBox3,multi.VTOLMotorS);
if (tmpVal > -1) { setComboCurrentIndex(m_aircraft->multiMotorChannelBox4,multi.VTOLMotorS);
field = obj->getField(mixerVectors.at(tmpVal)); setComboCurrentIndex(m_aircraft->triYawChannelBox,multi.TRIYaw);
int i = field->getElementNames().indexOf("Pitch");
double val = floor(2*field->getDouble(i)/1.27); channel = m_aircraft->multiMotorChannelBox1->currentIndex() - 1;
m_aircraft->mrPitchMixLevel->setValue(val); if (channel > -1)
i = field->getElementNames().indexOf("Roll"); {
val = floor(field->getDouble(i)/1.27); value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH);
m_aircraft->mrRollMixLevel->setValue(val); m_aircraft->mrPitchMixLevel->setValue( floor(2*value/1.27) );
value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL);
m_aircraft->mrRollMixLevel->setValue( floor(value/1.27) );
} }
} }
} }
@ -853,27 +804,20 @@ void ConfigVehicleTypeWidget::refreshMultiRotorWidgetsValues(QString frameType)
/** /**
Helper function: setupQuadMotor Helper function: setupQuadMotor
*/ */
void ConfigVehicleTypeWidget::setupQuadMotor(int channel, double pitch, double roll, double yaw) void ConfigMultiRotorWidget::setupQuadMotor(int channel, double pitch, double roll, double yaw)
{ {
qDebug()<<QString("Setup quad motor channel=%0 pitch=%1 roll=%2 yaw=%3").arg(channel).arg(pitch).arg(roll).arg(yaw); qDebug()<<QString("Setup quad motor channel=%0 pitch=%1 roll=%2 yaw=%3").arg(channel).arg(pitch).arg(roll).arg(yaw);
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
Q_ASSERT(obj); UAVDataObject* mixer = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
UAVObjectField *field = obj->getField(mixerTypes.at(channel)); Q_ASSERT(mixer);
field->setValue("Motor");
field = obj->getField(mixerVectors.at(channel)); setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_MOTOR);
// First of all reset the vector
resetField(field); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127);
int ti = field->getElementNames().indexOf("ThrottleCurve1"); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE2, 0);
field->setValue(127, ti); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, roll*127);
ti = field->getElementNames().indexOf("Roll"); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH, pitch*127);
field->setValue(roll*127,ti); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, yaw*127);
qDebug()<<"Set roll="<<roll*127;
ti = field->getElementNames().indexOf("Pitch");
field->setValue(pitch*127,ti);
qDebug()<<"Set pitch="<<pitch*127;
ti = field->getElementNames().indexOf("Yaw");
field->setValue(yaw*127,ti);
qDebug()<<"Set yaw="<<yaw*127;
} }
@ -881,21 +825,42 @@ void ConfigVehicleTypeWidget::setupQuadMotor(int channel, double pitch, double r
/** /**
Helper function: setup motors. Takes a list of channel names in input. Helper function: setup motors. Takes a list of channel names in input.
*/ */
void ConfigVehicleTypeWidget::setupMotors(QList<QString> motorList) void ConfigMultiRotorWidget::setupMotors(QList<QString> motorList)
{ {
resetActuators();
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorSettings")));
Q_ASSERT(obj);
UAVObjectField *field;
QList<QComboBox*> mmList; QList<QComboBox*> mmList;
mmList << m_aircraft->multiMotorChannelBox1 << m_aircraft->multiMotorChannelBox2 << m_aircraft->multiMotorChannelBox3 mmList << m_aircraft->multiMotorChannelBox1 << m_aircraft->multiMotorChannelBox2 << m_aircraft->multiMotorChannelBox3
<< m_aircraft->multiMotorChannelBox4 << m_aircraft->multiMotorChannelBox5 << m_aircraft->multiMotorChannelBox6 << m_aircraft->multiMotorChannelBox4 << m_aircraft->multiMotorChannelBox5 << m_aircraft->multiMotorChannelBox6
<< m_aircraft->multiMotorChannelBox7 << m_aircraft->multiMotorChannelBox8; << m_aircraft->multiMotorChannelBox7 << m_aircraft->multiMotorChannelBox8;
GUIConfigDataUnion configData = GetConfigData();
ResetActuators(&configData);
int index;
foreach (QString motor, motorList) { foreach (QString motor, motorList) {
field = obj->getField(motor);
field->setValue(mmList.takeFirst()->currentText()); index = mmList.takeFirst()->currentIndex();
//qDebug()<<QString("Setup motor: %0 = %1").arg(motor).arg(index);
if (motor == QString("VTOLMotorN"))
configData.multi.VTOLMotorN = index;
else if (motor == QString("VTOLMotorNE"))
configData.multi.VTOLMotorNE = index;
else if (motor == QString("VTOLMotorE"))
configData.multi.VTOLMotorE = index;
else if (motor == QString("VTOLMotorSE"))
configData.multi.VTOLMotorSE = index;
else if (motor == QString( "VTOLMotorS"))
configData.multi.VTOLMotorS = index;
else if (motor == QString( "VTOLMotorSW"))
configData.multi.VTOLMotorSW = index;
else if (motor == QString( "VTOLMotorW"))
configData.multi.VTOLMotorW = index;
else if (motor == QString( "VTOLMotorNW"))
configData.multi.VTOLMotorNW = index;
} }
//obj->updated(); // Save... SetConfigData(configData);
} }
@ -903,12 +868,12 @@ void ConfigVehicleTypeWidget::setupMotors(QList<QString> motorList)
/** /**
Set up a Quad-X or Quad-P mixer Set up a Quad-X or Quad-P mixer
*/ */
bool ConfigVehicleTypeWidget::setupQuad(bool pLayout) bool ConfigMultiRotorWidget::setupQuad(bool pLayout)
{ {
// Check coherence: // Check coherence:
//Show any config errors in GUI //Show any config errors in GUI
throwMultiRotorChannelConfigError(4); throwConfigError(4);
// - Four engines have to be defined // - Four engines have to be defined
if (m_aircraft->multiMotorChannelBox1->currentText() == "None" || if (m_aircraft->multiMotorChannelBox1->currentText() == "None" ||
@ -979,11 +944,11 @@ bool ConfigVehicleTypeWidget::setupQuad(bool pLayout)
/** /**
Set up a Hexa-X or Hexa-P mixer Set up a Hexa-X or Hexa-P mixer
*/ */
bool ConfigVehicleTypeWidget::setupHexa(bool pLayout) bool ConfigMultiRotorWidget::setupHexa(bool pLayout)
{ {
// Check coherence: // Check coherence:
//Show any config errors in GUI //Show any config errors in GUI
throwMultiRotorChannelConfigError(6); throwConfigError(6);
// - Four engines have to be defined // - Four engines have to be defined
if (m_aircraft->multiMotorChannelBox1->currentText() == "None" || if (m_aircraft->multiMotorChannelBox1->currentText() == "None" ||
@ -1060,7 +1025,7 @@ bool ConfigVehicleTypeWidget::setupHexa(bool pLayout)
/** /**
This function sets up the multirotor mixer values. This function sets up the multirotor mixer values.
*/ */
bool ConfigVehicleTypeWidget::setupMultiRotorMixer(double mixerFactors[8][3]) bool ConfigMultiRotorWidget::setupMultiRotorMixer(double mixerFactors[8][3])
{ {
qDebug()<<"Mixer factors"; qDebug()<<"Mixer factors";
qDebug()<<mixerFactors[0][0]<<" "<<mixerFactors[0][1]<<" "<<mixerFactors[0][2]; qDebug()<<mixerFactors[0][0]<<" "<<mixerFactors[0][1]<<" "<<mixerFactors[0][2];
@ -1107,7 +1072,7 @@ bool ConfigVehicleTypeWidget::setupMultiRotorMixer(double mixerFactors[8][3])
/** /**
This function displays text and color formatting in order to help the user understand what channels have not yet been configured. This function displays text and color formatting in order to help the user understand what channels have not yet been configured.
*/ */
void ConfigVehicleTypeWidget::throwMultiRotorChannelConfigError(int numMotors) void ConfigMultiRotorWidget::throwConfigError(int numMotors)
{ {
//Initialize configuration error flag //Initialize configuration error flag
bool error=false; bool error=false;
@ -1115,26 +1080,17 @@ void ConfigVehicleTypeWidget::throwMultiRotorChannelConfigError(int numMotors)
//Iterate through all instances of multiMotorChannelBox //Iterate through all instances of multiMotorChannelBox
for (int i=0; i<numMotors; i++) { for (int i=0; i<numMotors; i++) {
//Fine widgets with text "multiMotorChannelBox.x", where x is an integer //Fine widgets with text "multiMotorChannelBox.x", where x is an integer
QComboBox *combobox = qFindChild<QComboBox*>(this, "multiMotorChannelBox" + QString::number(i+1)); QComboBox *combobox = qFindChild<QComboBox*>(uiowner, "multiMotorChannelBox" + QString::number(i+1));
if (combobox){ //if QLabel exists if (combobox){
QLabel *label = qFindChild<QLabel*>(this, "MotorOutputLabel" + QString::number(i+1));
if (combobox->currentText() == "None") { if (combobox->currentText() == "None") {
// label->setText("<font color='red'>" + label->text() + "</font>");
int size = combobox->style()->pixelMetric(QStyle::PM_SmallIconSize); int size = combobox->style()->pixelMetric(QStyle::PM_SmallIconSize);
QPixmap pixmap(size,size); QPixmap pixmap(size,size);
pixmap.fill(QColor("red")); pixmap.fill(QColor("red"));
combobox->setItemData(0, pixmap, Qt::DecorationRole);//Set color palettes combobox->setItemData(0, pixmap, Qt::DecorationRole);//Set color palettes
// combobox->setStyleSheet("QComboBox { color: red}");
error=true; error=true;
} }
else { else {
combobox->setItemData(0, 0, Qt::DecorationRole);//Reset color palettes combobox->setItemData(0, 0, Qt::DecorationRole);//Reset color palettes
// combobox->setStyleSheet("color: black;");
// QTextEdit* htmlText=new QTextEdit(label->text()); // htmlText is any QString with html tags.
// label->setText(htmlText->toPlainText());
} }
} }
} }
@ -1144,3 +1100,5 @@ void ConfigVehicleTypeWidget::throwMultiRotorChannelConfigError(int numMotors)
m_aircraft->mrStatusLabel->setText(QString("<font color='red'>ERROR: Assign all %1 motor channels</font>").arg(numMotors)); m_aircraft->mrStatusLabel->setText(QString("<font color='red'>ERROR: Assign all %1 motor channels</font>").arg(numMotors));
} }
} }

View File

@ -0,0 +1,84 @@
/**
******************************************************************************
*
* @file configairframetwidget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
* @{
* @brief Airframe configuration panel
*****************************************************************************/
/*
* 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 CONFIGMULTIROTORWIDGET_H
#define CONFIGMULTIROTORWIDGET_H
#include "ui_airframe.h"
#include "../uavobjectwidgetutils/configtaskwidget.h"
#include "extensionsystem/pluginmanager.h"
#include "uavobjectmanager.h"
#include "uavobject.h"
#include "uavtalk/telemetrymanager.h"
#include <QtGui/QWidget>
#include <QList>
#include <QItemDelegate>
class Ui_Widget;
class ConfigMultiRotorWidget: public VehicleConfig
{
Q_OBJECT
public:
ConfigMultiRotorWidget(Ui_AircraftWidget *aircraft = 0, QWidget *parent = 0);
~ConfigMultiRotorWidget();
friend class ConfigVehicleTypeWidget;
private:
Ui_AircraftWidget *m_aircraft;
QWidget *uiowner;
QGraphicsSvgItem *quad;
bool setupQuad(bool pLayout);
bool setupHexa(bool pLayout);
bool setupOcto();
bool setupMultiRotorMixer(double mixerFactors[8][3]);
void setupMotors(QList<QString> motorList);
void setupQuadMotor(int channel, double roll, double pitch, double yaw);
virtual void ResetActuators(GUIConfigDataUnion* configData);
virtual QStringList getChannelDescriptions();
private slots:
virtual void setupUI(QString airframeType);
virtual void refreshWidgetsValues(QString frameType);
virtual QString updateConfigObjectsFromWidgets();
void throwConfigError(int numMotors);
protected:
signals:
void configurationChanged();
};
#endif // CONFIGMULTIROTORWIDGET_H

View File

@ -0,0 +1,256 @@
/**
******************************************************************************
*
* @file vehicleconfig.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
* @{
* @brief bit storage of config ui settings
*****************************************************************************/
/*
* 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 "cfg_vehicletypes/vehicleconfig.h"
#include "extensionsystem/pluginmanager.h"
#include "uavobjectmanager.h"
#include "uavobject.h"
#include "systemsettings.h"
#include <QDebug>
VehicleConfig::VehicleConfig(QWidget *parent) : ConfigTaskWidget(parent)
{
//Generate lists of mixerTypeNames, mixerVectorNames, channelNames
channelNames << "None";
for (int i = 0; i < (int)(VehicleConfig::CHANNEL_NUMELEM); i++) {
mixerTypes << QString("Mixer%1Type").arg(i+1);
mixerVectors << QString("Mixer%1Vector").arg(i+1);
channelNames << QString("Channel%1").arg(i+1);
}
// typedef enum { MIXERTYPE_DISABLED=0, MIXERTYPE_MOTOR=1, MIXERTYPE_SERVO=2,
//MIXERTYPE_CAMERAROLL=3, MIXERTYPE_CAMERAPITCH=4, MIXERTYPE_CAMERAYAW=5,
//MIXERTYPE_ACCESSORY0=6, MIXERTYPE_ACCESSORY1=7, MIXERTYPE_ACCESSORY2=8,
//MIXERTYPE_ACCESSORY3=9, MIXERTYPE_ACCESSORY4=10, MIXERTYPE_ACCESSORY5=11 } MixerTypeElem;
mixerTypeDescriptions << "Disabled" << "Motor" << "Servo" << "CameraRoll" << "CameraPitch"
<< "CameraYaw" << "Accessory0" << "Accessory1" << "Accessory2"
<< "Accessory3" << "Accessory4" << "Accessory5";
// This is needed because new style tries to compact things as much as possible in grid
// and on OSX the widget sizes of PushButtons is reported incorrectly:
// https://bugreports.qt-project.org/browse/QTBUG-14591
foreach( QPushButton * btn, findChildren<QPushButton*>() ) {
btn->setAttribute(Qt::WA_LayoutUsesWidgetRect);
}
}
VehicleConfig::~VehicleConfig()
{
// Do nothing
}
GUIConfigDataUnion VehicleConfig::GetConfigData() {
int i;
GUIConfigDataUnion configData;
// get an instance of systemsettings
SystemSettings * systemSettings = SystemSettings::GetInstance(getUAVObjectManager());
Q_ASSERT(systemSettings);
SystemSettings::DataFields systemSettingsData = systemSettings->getData();
// copy systemsettings -> local configData
for(i = 0; i < (int)(SystemSettings::GUICONFIGDATA_NUMELEM); i++)
configData.UAVObject[i]=systemSettingsData.GUIConfigData[i];
// sanity check
Q_ASSERT(SystemSettings::GUICONFIGDATA_NUMELEM ==
(sizeof(configData.UAVObject) / sizeof(configData.UAVObject[0])));
return configData;
}
void VehicleConfig::SetConfigData(GUIConfigDataUnion configData) {
int i;
// sanity check
Q_ASSERT(SystemSettings::GUICONFIGDATA_NUMELEM ==
(sizeof(configData.UAVObject) / sizeof(configData.UAVObject[0])));
// get an instance of systemsettings
SystemSettings * systemSettings = SystemSettings::GetInstance(getUAVObjectManager());
Q_ASSERT(systemSettings);
SystemSettings::DataFields systemSettingsData = systemSettings->getData();
// copy parameter configData -> systemsettings
for (i = 0; i < (int)(SystemSettings::GUICONFIGDATA_NUMELEM); i++)
systemSettingsData.GUIConfigData[i] = configData.UAVObject[i];
systemSettings->setData(systemSettingsData);
systemSettings->updated();
//emit ConfigurationChanged();
}
void VehicleConfig::ResetActuators(GUIConfigDataUnion* configData)
{
}
QStringList VehicleConfig::getChannelDescriptions()
{
QStringList channelDesc;
// init a channel_numelem list of channel desc defaults
for (int i=0; i < (int)(VehicleConfig::CHANNEL_NUMELEM); i++)
{
channelDesc.append(QString("-"));
}
return channelDesc;
}
/**
Helper function:
Sets the current index on supplied combobox to index
if it is within bounds 0 <= index < combobox.count()
*/
void VehicleConfig::setComboCurrentIndex(QComboBox* box, int index)
{
Q_ASSERT(box);
if (index >= 0 && index < box->count())
box->setCurrentIndex(index);
}
/**
Helper function:
enables/disables the named combobox within supplied uiowner
*/
void VehicleConfig::enableComboBox(QWidget* owner, QString boxName, bool enable)
{
QComboBox* box = qFindChild<QComboBox*>(owner, boxName);
if (box)
box->setEnabled(enable);
}
QString VehicleConfig::getMixerType(UAVDataObject* mixer, int channel)
{
Q_ASSERT(mixer);
QString mixerType = mixerTypeDescriptions[0]; //default to disabled
if (channel >= 0 && channel < mixerTypes.count()) {
UAVObjectField *field = mixer->getField(mixerTypes.at(channel));
Q_ASSERT(field);
if (field)
mixerType = field->getValue().toString();
}
return mixerType;
}
void VehicleConfig::setMixerType(UAVDataObject* mixer, int channel, MixerTypeElem mixerType)
{
Q_ASSERT(mixer);
qDebug() << QString("setMixerType channel %0, type %1").arg(channel).arg(mixerType);
if (channel >= 0 && channel < mixerTypes.count()) {
UAVObjectField *field = mixer->getField(mixerTypes.at(channel));
Q_ASSERT(field);
if (field) {
if (mixerType >= 0 && mixerType < mixerTypeDescriptions.count())
{
field->setValue(mixerTypeDescriptions[mixerType]);
mixer->updated();
}
}
}
}
void VehicleConfig::resetMixerVector(UAVDataObject* mixer, int channel)
{
Q_ASSERT(mixer);
if (channel >= 0 && channel < mixerVectors.count()) {
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 0);
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE2, 0);
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH, 0);
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, 0);
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, 0);
}
}
double VehicleConfig::getMixerVectorValue(UAVDataObject* mixer, int channel, MixerVectorElem elementName)
{
Q_ASSERT(mixer);
double value = 0;
if (channel >= 0 && channel < mixerVectors.count()) {
UAVObjectField *field = mixer->getField(mixerVectors.at(channel));
Q_ASSERT(field);
if (field) {
value = field->getDouble(elementName);
}
}
return value;
}
void VehicleConfig::setMixerVectorValue(UAVDataObject* mixer, int channel, MixerVectorElem elementName, double value)
{
Q_ASSERT(mixer);
qDebug() << QString("setMixerVectorValue channel %0, name %1, value %2").arg(channel).arg(elementName).arg(value);
if (channel >= 0 && channel < mixerVectors.count()) {
UAVObjectField *field = mixer->getField(mixerVectors.at(channel));
Q_ASSERT(field);
if (field) {
field->setDouble(value, elementName);
mixer->updated();
}
}
}
/**
Reset the contents of a field
*/
void VehicleConfig::resetField(UAVObjectField * field)
{
for (unsigned int i=0;i<field->getNumElements();i++) {
field->setValue(0,i);
}
}
/**
* Util function to get a pointer to the object manager
* @return pointer to the UAVObjectManager
*/
UAVObjectManager* VehicleConfig::getUAVObjectManager() {
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager * objMngr = pm->getObject<UAVObjectManager>();
Q_ASSERT(objMngr);
return objMngr;
}

View File

@ -0,0 +1,156 @@
/**
******************************************************************************
*
* @file vehicleconfig.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
* @{
* @brief bit storage of config ui settings
*****************************************************************************/
/*
* 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 GUIVEHICLECONFIG_H
#define GUIVEHICLECONFIG_H
#include "../uavobjectwidgetutils/configtaskwidget.h"
#include "extensionsystem/pluginmanager.h"
#include "uavobjectmanager.h"
#include "uavobject.h"
typedef struct {
uint VTOLMotorN:4;
uint VTOLMotorS:4;
uint VTOLMotorE:4;
uint VTOLMotorW:4;
uint VTOLMotorNW:4;
uint VTOLMotorNE:4;
uint VTOLMotorSW:4;
uint VTOLMotorSE:4; //32bits
uint TRIYaw:4;
quint32 padding:28; //64bits
quint32 padding1;
quint32 padding2; //128bits
} __attribute__((packed)) multiGUISettingsStruct;
typedef struct {
uint SwashplateType:3;
uint FirstServoIndex:2;
uint CorrectionAngle:9;
uint ccpmCollectivePassthroughState:1;
uint ccpmLinkCyclicState:1;
uint ccpmLinkRollState:1;
uint SliderValue0:7;
uint SliderValue1:7;
uint SliderValue2:7;//41bits
uint ServoIndexW:4;
uint ServoIndexX:4;
uint ServoIndexY:4;
uint ServoIndexZ:4;//57bits
uint Throttle:4;
uint Tail:4; //65bits
quint32 padding:31; //96bits
quint32 padding1; //128bits
} __attribute__((packed)) heliGUISettingsStruct;
typedef struct {
uint FixedWingThrottle:4;
uint FixedWingRoll1:4;
uint FixedWingRoll2:4;
uint FixedWingPitch1:4;
uint FixedWingPitch2:4;
uint FixedWingYaw1:4;
uint FixedWingYaw2:4;
uint padding:4; //32bits
quint32 padding1;
quint32 padding2;
quint32 padding3; //128bits
} __attribute__((packed)) fixedGUISettingsStruct;
typedef struct {
uint GroundVehicleThrottle1:4;
uint GroundVehicleThrottle2:4;
uint GroundVehicleSteering1:4;
uint GroundVehicleSteering2:4;
uint padding:16; //32bits
quint32 padding1;
quint32 padding2;
quint32 padding3; //128bits
} __attribute__((packed)) groundGUISettingsStruct;
typedef union
{
uint UAVObject[4]; //32bits * 4
heliGUISettingsStruct heli; //128bits
fixedGUISettingsStruct fixedwing;
multiGUISettingsStruct multi;
groundGUISettingsStruct ground;
} GUIConfigDataUnion;
class VehicleConfig: public ConfigTaskWidget
{
Q_OBJECT
public:
VehicleConfig(QWidget *parent = 0);
~VehicleConfig();
/* Enumeration options for field MixerType */
typedef enum { MIXERTYPE_DISABLED=0, MIXERTYPE_MOTOR=1, MIXERTYPE_SERVO=2, MIXERTYPE_CAMERAROLL=3, MIXERTYPE_CAMERAPITCH=4, MIXERTYPE_CAMERAYAW=5, MIXERTYPE_ACCESSORY0=6, MIXERTYPE_ACCESSORY1=7, MIXERTYPE_ACCESSORY2=8, MIXERTYPE_ACCESSORY3=9, MIXERTYPE_ACCESSORY4=10, MIXERTYPE_ACCESSORY5=11 } MixerTypeElem;
/* Array element names for field MixerVector */
typedef enum { MIXERVECTOR_THROTTLECURVE1=0, MIXERVECTOR_THROTTLECURVE2=1, MIXERVECTOR_ROLL=2, MIXERVECTOR_PITCH=3, MIXERVECTOR_YAW=4 } MixerVectorElem;
static GUIConfigDataUnion GetConfigData();
static void SetConfigData(GUIConfigDataUnion configData);
static void resetField(UAVObjectField * field);
static void setComboCurrentIndex(QComboBox* box, int index);
static void enableComboBox(QWidget* owner, QString boxName, bool enable);
double getMixerVectorValue(UAVDataObject* mixer, int channel, MixerVectorElem elementName);
void setMixerVectorValue(UAVDataObject* mixer, int channel, MixerVectorElem elementName, double value);
void resetMixerVector(UAVDataObject* mixer, int channel);
QString getMixerType(UAVDataObject* mixer, int channel);
void setMixerType(UAVDataObject* mixer, int channel, MixerTypeElem mixerType);
virtual void ResetActuators(GUIConfigDataUnion* configData);
virtual QStringList getChannelDescriptions();
QStringList channelNames;
QStringList mixerTypes;
QStringList mixerVectors;
QStringList mixerTypeDescriptions;
static const quint32 CHANNEL_NUMELEM = 10;
private:
static UAVObjectManager* getUAVObjectManager();
private slots:
public slots:
signals:
//void ConfigurationChanged();
protected:
};
#endif // GUIVEHICLECONFIG_H

View File

@ -31,6 +31,10 @@ HEADERS += configplugin.h \
configcamerastabilizationwidget.h \ configcamerastabilizationwidget.h \
configtxpidwidget.h \ configtxpidwidget.h \
outputchannelform.h \ outputchannelform.h \
cfg_vehicletypes/configmultirotorwidget.h \
cfg_vehicletypes/configgroundvehiclewidget.h \
cfg_vehicletypes/configfixedwingwidget.h \
cfg_vehicletypes/vehicleconfig.h \
configrevowidget.h \ configrevowidget.h \
config_global.h config_global.h
SOURCES += configplugin.cpp \ SOURCES += configplugin.cpp \
@ -62,7 +66,8 @@ SOURCES += configplugin.cpp \
cfg_vehicletypes/configgroundvehiclewidget.cpp \ cfg_vehicletypes/configgroundvehiclewidget.cpp \
cfg_vehicletypes/configfixedwingwidget.cpp \ cfg_vehicletypes/configfixedwingwidget.cpp \
cfg_vehicletypes/configccpmwidget.cpp \ cfg_vehicletypes/configccpmwidget.cpp \
outputchannelform.cpp outputchannelform.cpp \
cfg_vehicletypes/vehicleconfig.cpp
FORMS += airframe.ui \ FORMS += airframe.ui \
cc_hw_settings.ui \ cc_hw_settings.ui \
pro_hw_settings.ui \ pro_hw_settings.ui \

View File

@ -33,8 +33,8 @@
#include <QDebug> #include <QDebug>
#include <QDesktopServices> #include <QDesktopServices>
#include <QUrl> #include <QUrl>
#include <accels.h> #include "accels.h"
#include <gyros.h> #include "gyros.h"
ConfigCCAttitudeWidget::ConfigCCAttitudeWidget(QWidget *parent) : ConfigCCAttitudeWidget::ConfigCCAttitudeWidget(QWidget *parent) :
ConfigTaskWidget(parent), ConfigTaskWidget(parent),
@ -107,7 +107,6 @@ void ConfigCCAttitudeWidget::accelsUpdated(UAVObject * obj) {
attitudeSettingsData.GyroBias[2] = -z_gyro_bias; attitudeSettingsData.GyroBias[2] = -z_gyro_bias;
attitudeSettingsData.BiasCorrectGyro = AttitudeSettings::BIASCORRECTGYRO_TRUE; attitudeSettingsData.BiasCorrectGyro = AttitudeSettings::BIASCORRECTGYRO_TRUE;
AttitudeSettings::GetInstance(getObjectManager())->setData(attitudeSettingsData); AttitudeSettings::GetInstance(getObjectManager())->setData(attitudeSettingsData);
} else { } else {
// Possible to get here if weird threading stuff happens. Just ignore updates. // Possible to get here if weird threading stuff happens. Just ignore updates.
qDebug("Unexpected accel update received."); qDebug("Unexpected accel update received.");
@ -174,3 +173,10 @@ void ConfigCCAttitudeWidget::enableControls(bool enable)
ConfigTaskWidget::enableControls(enable); ConfigTaskWidget::enableControls(enable);
} }
void ConfigCCAttitudeWidget::updateObjectsFromWidgets()
{
ConfigTaskWidget::updateObjectsFromWidgets();
ui->zeroBiasProgress->setValue(0);
}

View File

@ -46,6 +46,8 @@ public:
explicit ConfigCCAttitudeWidget(QWidget *parent = 0); explicit ConfigCCAttitudeWidget(QWidget *parent = 0);
~ConfigCCAttitudeWidget(); ~ConfigCCAttitudeWidget();
virtual void updateObjectsFromWidgets();
private slots: private slots:
void accelsUpdated(UAVObject * obj); void accelsUpdated(UAVObject * obj);
void timeout(); void timeout();

View File

@ -27,6 +27,7 @@
#include "configoutputwidget.h" #include "configoutputwidget.h"
#include "outputchannelform.h" #include "outputchannelform.h"
#include "configvehicletypewidget.h"
#include "uavtalk/telemetrymanager.h" #include "uavtalk/telemetrymanager.h"
@ -39,9 +40,11 @@
#include <QMessageBox> #include <QMessageBox>
#include <QDesktopServices> #include <QDesktopServices>
#include <QUrl> #include <QUrl>
#include "mixersettings.h"
#include "actuatorcommand.h" #include "actuatorcommand.h"
#include "actuatorsettings.h" #include "actuatorsettings.h"
#include "systemalarms.h" #include "systemalarms.h"
#include "systemsettings.h"
#include "uavsettingsimportexport/uavsettingsimportexportfactory.h" #include "uavsettingsimportexport/uavsettingsimportexportfactory.h"
ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(parent),wasItMe(false) ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(parent),wasItMe(false)
@ -231,35 +234,35 @@ void ConfigOutputWidget::sendChannelTest(int index, int value)
/** /**
Request the current config from the board (RC Output) Request the current config from the board (RC Output)
*/ */
void ConfigOutputWidget::refreshOutputWidgetsValues(UAVObject *) void ConfigOutputWidget::refreshWidgetsValues(UAVObject * obj)
{ {
// Reset all channel assignements: Q_UNUSED(obj);
QList<OutputChannelForm*> outputChannelForms = findChildren<OutputChannelForm*>();
foreach(OutputChannelForm *outputChannelForm, outputChannelForms)
{
outputChannelForm->setAssignment("-");
}
// FIXME: Use static accessor method for retrieving channel assignments bool dirty=isDirty();
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
Q_ASSERT(pm);
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
Q_ASSERT(objManager);
// Get the channel assignements:
UAVDataObject * obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ActuatorSettings")));
Q_ASSERT(obj);
QList<UAVObjectField*> fieldList = obj->getFields();
foreach (UAVObjectField* field, fieldList) {
if (field->getUnits().contains("channel")) {
assignOutputChannel(obj,field->getName());
}
}
// Get Actuator Settings
ActuatorSettings *actuatorSettings = ActuatorSettings::GetInstance(getObjectManager()); ActuatorSettings *actuatorSettings = ActuatorSettings::GetInstance(getObjectManager());
Q_ASSERT(actuatorSettings); Q_ASSERT(actuatorSettings);
ActuatorSettings::DataFields actuatorSettingsData = actuatorSettings->getData(); ActuatorSettings::DataFields actuatorSettingsData = actuatorSettings->getData();
// get channel descriptions
QStringList ChannelDesc = ConfigVehicleTypeWidget::getChannelDescriptions();
// Initialize output forms
QList<OutputChannelForm*> outputChannelForms = findChildren<OutputChannelForm*>();
foreach(OutputChannelForm *outputChannelForm, outputChannelForms)
{
outputChannelForm->setAssignment(ChannelDesc[outputChannelForm->index()]);
// init min,max,neutral
int minValue = actuatorSettingsData.ChannelMin[outputChannelForm->index()];
int maxValue = actuatorSettingsData.ChannelMax[outputChannelForm->index()];
outputChannelForm->minmax(minValue, maxValue);
int neutral = actuatorSettingsData.ChannelNeutral[outputChannelForm->index()];
outputChannelForm->neutral(neutral);
}
// Get the SpinWhileArmed setting // Get the SpinWhileArmed setting
m_config->spinningArmed->setChecked(actuatorSettingsData.MotorsSpinWhileArmed == ActuatorSettings::MOTORSSPINWHILEARMED_TRUE); m_config->spinningArmed->setChecked(actuatorSettingsData.MotorsSpinWhileArmed == ActuatorSettings::MOTORSSPINWHILEARMED_TRUE);
@ -275,6 +278,8 @@ void ConfigOutputWidget::refreshOutputWidgetsValues(UAVObject *)
m_config->cb_outputRate1->setCurrentIndex(m_config->cb_outputRate1->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[0]))); m_config->cb_outputRate1->setCurrentIndex(m_config->cb_outputRate1->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[0])));
m_config->cb_outputRate2->setCurrentIndex(m_config->cb_outputRate2->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[1]))); m_config->cb_outputRate2->setCurrentIndex(m_config->cb_outputRate2->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[1])));
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
Q_ASSERT(pm);
UAVObjectUtilManager* utilMngr = pm->getObject<UAVObjectUtilManager>(); UAVObjectUtilManager* utilMngr = pm->getObject<UAVObjectUtilManager>();
if (utilMngr) { if (utilMngr) {
int board = utilMngr->getBoardModel(); int board = utilMngr->getBoardModel();

View File

@ -33,6 +33,7 @@
#include "uavobjectmanager.h" #include "uavobjectmanager.h"
#include "uavobject.h" #include "uavobject.h"
#include "uavobjectutilmanager.h" #include "uavobjectutilmanager.h"
#include "cfg_vehicletypes/vehicleconfig.h"
#include <QtGui/QWidget> #include <QtGui/QWidget>
#include <QList> #include <QList>
@ -58,7 +59,6 @@ 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; OutputChannelForm* getOutputChannelForm(const int index) const;
int mccDataRate; int mccDataRate;
UAVObject::Metadata accInitialData; UAVObject::Metadata accInitialData;
@ -69,7 +69,7 @@ private:
private slots: private slots:
void stopTests(); void stopTests();
void disableIfNotMe(UAVObject *obj); void disableIfNotMe(UAVObject *obj);
void refreshOutputWidgetsValues(UAVObject * obj = NULL); virtual void refreshWidgetsValues(UAVObject * obj=NULL);
void updateObjectsFromWidgets(); void updateObjectsFromWidgets();
void runChannelTests(bool state); void runChannelTests(bool state);
void sendChannelTest(int index, int value); void sendChannelTest(int index, int value);

View File

@ -103,22 +103,22 @@ ConfigVehicleTypeWidget::ConfigVehicleTypeWidget(QWidget *parent) : ConfigTaskWi
addUAVObject("MixerSettings"); addUAVObject("MixerSettings");
addUAVObject("ActuatorSettings"); addUAVObject("ActuatorSettings");
ffTuningInProgress = false; ffTuningInProgress = false;
ffTuningPhase = false; ffTuningPhase = false;
//Generate list of channels //Generate lists of mixerTypeNames, mixerVectorNames, channelNames
QStringList channels; channelNames << "None";
channels << "None"; for (int i = 0; i < ActuatorSettings::CHANNELADDR_NUMELEM; i++) {
for (unsigned int i = 0; i < ActuatorSettings::CHANNELADDR_NUMELEM; i++) {
mixerTypes << QString("Mixer%1Type").arg(i+1); mixerTypes << QString("Mixer%1Type").arg(i+1);
mixerVectors << QString("Mixer%1Vector").arg(i+1); mixerVectors << QString("Mixer%1Vector").arg(i+1);
channels << QString("Channel%1").arg(i+1); channelNames << QString("Channel%1").arg(i+1);
} }
QStringList airframeTypes; QStringList airframeTypes;
airframeTypes << "Fixed Wing" << "Multirotor" << "Helicopter" << "Ground" << "Custom"; airframeTypes << "Fixed Wing" << "Multirotor" << "Helicopter" << "Ground" << "Custom";
m_aircraft->aircraftType->addItems(airframeTypes); m_aircraft->aircraftType->addItems(airframeTypes);
m_aircraft->aircraftType->setCurrentIndex(0); //Set default vehicle to Fixed Wing m_aircraft->aircraftType->setCurrentIndex(0); //Set default vehicle to Fixed Wing
QStringList fixedWingTypes; QStringList fixedWingTypes;
@ -138,26 +138,12 @@ ConfigVehicleTypeWidget::ConfigVehicleTypeWidget(QWidget *parent) : ConfigTaskWi
m_aircraft->multirotorFrameType->addItems(multiRotorTypes); m_aircraft->multirotorFrameType->addItems(multiRotorTypes);
m_aircraft->multirotorFrameType->setCurrentIndex(1); //Set default model to "Quad +" m_aircraft->multirotorFrameType->setCurrentIndex(1); //Set default model to "Quad +"
// Now load all the channel assignements
//OLD STYLE: DO IT MANUALLY
// m_aircraft->triYawChannelBox->addItems(channels);
// m_aircraft->gvMotor1ChannelBox->addItems(channels);
// m_aircraft->gvMotor2ChannelBox->addItems(channels);
// m_aircraft->gvSteering1ChannelBox->addItems(channels);
// m_aircraft->gvSteering2ChannelBox->addItems(channels);
// m_aircraft->fwElevator1ChannelBox->addItems(channels);
// m_aircraft->fwElevator2ChannelBox->addItems(channels);
// m_aircraft->fwEngineChannelBox->addItems(channels);
// m_aircraft->fwRudder1ChannelBox->addItems(channels);
// m_aircraft->fwRudder2ChannelBox->addItems(channels);
// m_aircraft->fwAileron1ChannelBox->addItems(channels);
// m_aircraft->fwAileron2ChannelBox->addItems(channels);
//NEW STYLE: Loop through the widgets looking for all widgets that have "ChannelBox" in their name //NEW STYLE: Loop through the widgets looking for all widgets that have "ChannelBox" in their name
// The upshot of this is that ALL new ComboBox widgets for selecting the output channel must have "ChannelBox" in their name // The upshot of this is that ALL new ComboBox widgets for selecting the output channel must have "ChannelBox" in their name
foreach(QComboBox *combobox, this->findChildren<QComboBox*>(QRegExp("\\S+ChannelBo\\S+")))//FOR WHATEVER REASON, THIS DOES NOT WORK WITH ChannelBox. ChannelBo is sufficiently accurate foreach(QComboBox *combobox, this->findChildren<QComboBox*>(QRegExp("\\S+ChannelBo\\S+")))//FOR WHATEVER REASON, THIS DOES NOT WORK WITH ChannelBox. ChannelBo is sufficiently accurate
{ {
combobox->addItems(channels); combobox->addItems(channelNames);
} }
// Setup the Multirotor picture in the Quad settings interface // Setup the Multirotor picture in the Quad settings interface
@ -188,6 +174,27 @@ ConfigVehicleTypeWidget::ConfigVehicleTypeWidget(QWidget *parent) : ConfigTaskWi
m_aircraft->customMixerTable->setItemDelegateForRow(i, sbd); m_aircraft->customMixerTable->setItemDelegateForRow(i, sbd);
} }
// create and setup a MultiRotor config widget
m_multirotor = new ConfigMultiRotorWidget(m_aircraft);
m_multirotor->quad = quad;
m_multirotor->uiowner = this;
m_multirotor->setupUI(m_aircraft->multirotorFrameType->currentText());
// create and setup a GroundVehicle config widget
m_groundvehicle = new ConfigGroundVehicleWidget(m_aircraft);
m_groundvehicle->setupUI(m_aircraft->groundVehicleType->currentText() );
// create and setup a FixedWing config widget
m_fixedwing = new ConfigFixedWingWidget(m_aircraft);
m_fixedwing->setupUI(m_aircraft->fixedWingType->currentText() );
// create and setup a Helicopter config widget
m_heli = m_aircraft->widget_3;
m_heli->setupUI(QString("HeliCP"));
// initialize the ui to show the mixersettings tab
//mdl m_aircraft->tabWidget->setCurrentIndex(0);
//Connect aircraft type selection dropbox to callback function //Connect aircraft type selection dropbox to callback function
connect(m_aircraft->aircraftType, SIGNAL(currentIndexChanged(int)), this, SLOT(switchAirframeType(int))); connect(m_aircraft->aircraftType, SIGNAL(currentIndexChanged(int)), this, SLOT(switchAirframeType(int)));
@ -195,6 +202,7 @@ ConfigVehicleTypeWidget::ConfigVehicleTypeWidget(QWidget *parent) : ConfigTaskWi
connect(m_aircraft->fixedWingType, SIGNAL(currentIndexChanged(QString)), this, SLOT(setupAirframeUI(QString))); connect(m_aircraft->fixedWingType, SIGNAL(currentIndexChanged(QString)), this, SLOT(setupAirframeUI(QString)));
connect(m_aircraft->multirotorFrameType, SIGNAL(currentIndexChanged(QString)), this, SLOT(setupAirframeUI(QString))); connect(m_aircraft->multirotorFrameType, SIGNAL(currentIndexChanged(QString)), this, SLOT(setupAirframeUI(QString)));
connect(m_aircraft->groundVehicleType, SIGNAL(currentIndexChanged(QString)), this, SLOT(setupAirframeUI(QString))); connect(m_aircraft->groundVehicleType, SIGNAL(currentIndexChanged(QString)), this, SLOT(setupAirframeUI(QString)));
//mdl connect(m_heli->m_ccpm->ccpmType, SIGNAL(currentIndexChanged(QString)), this, SLOT(setupAirframeUI(QString)));
//Connect throttle curve reset pushbuttons to reset functions //Connect throttle curve reset pushbuttons to reset functions
connect(m_aircraft->fwThrottleReset, SIGNAL(clicked()), this, SLOT(resetFwMixer())); connect(m_aircraft->fwThrottleReset, SIGNAL(clicked()), this, SLOT(resetFwMixer()));
@ -220,19 +228,12 @@ ConfigVehicleTypeWidget::ConfigVehicleTypeWidget(QWidget *parent) : ConfigTaskWi
connect(m_aircraft->ffTestBox2, SIGNAL(clicked(bool)), this, SLOT(enableFFTest())); connect(m_aircraft->ffTestBox2, SIGNAL(clicked(bool)), this, SLOT(enableFFTest()));
connect(m_aircraft->ffTestBox3, SIGNAL(clicked(bool)), this, SLOT(enableFFTest())); connect(m_aircraft->ffTestBox3, SIGNAL(clicked(bool)), this, SLOT(enableFFTest()));
//WHAT DOES THIS DO?
enableControls(false);
refreshWidgetsValues();
// Connect the help pushbutton // Connect the help pushbutton
connect(m_aircraft->airframeHelp, SIGNAL(clicked()), this, SLOT(openHelp())); connect(m_aircraft->airframeHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
enableControls(false);
refreshWidgetsValues();
addToDirtyMonitor(); addToDirtyMonitor();
//Initialize GUI tabs //MOVING THIS FROM THE END OF THIS FUNCTION CAN CAUSE RUNTIME ERRORS DUE TO setupMultiRotorUI. WHY?
setupMultiRotorUI( m_aircraft->multirotorFrameType->currentText() );
setupGroundVehicleUI( m_aircraft->groundVehicleType->currentText() );
setupFixedWingUI( m_aircraft->fixedWingType->currentText() );
disableMouseWheelEvents(); disableMouseWheelEvents();
} }
@ -245,12 +246,95 @@ ConfigVehicleTypeWidget::~ConfigVehicleTypeWidget()
// Do nothing // Do nothing
} }
/**
Static function to get currently assigned channelDescriptions
for all known vehicle types; instantiates the appropriate object
then asks it to supply channel descs
*/
QStringList ConfigVehicleTypeWidget::getChannelDescriptions()
{
int i;
QStringList channelDesc;
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager * objMngr = pm->getObject<UAVObjectManager>();
Q_ASSERT(objMngr);
// get an instance of systemsettings
SystemSettings * systemSettings = SystemSettings::GetInstance(objMngr);
Q_ASSERT(systemSettings);
SystemSettings::DataFields systemSettingsData = systemSettings->getData();
switch (systemSettingsData.AirframeType)
{
// fixed wing
case SystemSettings::AIRFRAMETYPE_FIXEDWING:
case SystemSettings::AIRFRAMETYPE_FIXEDWINGELEVON:
case SystemSettings::AIRFRAMETYPE_FIXEDWINGVTAIL:
{
ConfigFixedWingWidget* fixedwing = new ConfigFixedWingWidget();
channelDesc = fixedwing->getChannelDescriptions();
}
break;
// helicp
case SystemSettings::AIRFRAMETYPE_HELICP:
{
ConfigCcpmWidget* heli = new ConfigCcpmWidget();
channelDesc = heli->getChannelDescriptions();
}
break;
//multirotor
case SystemSettings::AIRFRAMETYPE_VTOL:
case SystemSettings::AIRFRAMETYPE_TRI:
case SystemSettings::AIRFRAMETYPE_QUADX:
case SystemSettings::AIRFRAMETYPE_QUADP:
case SystemSettings::AIRFRAMETYPE_OCTOV:
case SystemSettings::AIRFRAMETYPE_OCTOCOAXX:
case SystemSettings::AIRFRAMETYPE_OCTOCOAXP:
case SystemSettings::AIRFRAMETYPE_OCTO:
case SystemSettings::AIRFRAMETYPE_HEXAX:
case SystemSettings::AIRFRAMETYPE_HEXACOAX:
case SystemSettings::AIRFRAMETYPE_HEXA:
{
ConfigMultiRotorWidget* multi = new ConfigMultiRotorWidget();
channelDesc = multi->getChannelDescriptions();
}
break;
// ground
case SystemSettings::AIRFRAMETYPE_GROUNDVEHICLECAR:
case SystemSettings::AIRFRAMETYPE_GROUNDVEHICLEDIFFERENTIAL:
case SystemSettings::AIRFRAMETYPE_GROUNDVEHICLEMOTORCYCLE:
{
ConfigGroundVehicleWidget* ground = new ConfigGroundVehicleWidget();
channelDesc = ground->getChannelDescriptions();
}
break;
default:
{
for (i=0; i < (int)(VehicleConfig::CHANNEL_NUMELEM); i++)
channelDesc.append(QString("-"));
}
break;
}
// for (i=0; i < channelDesc.count(); i++)
// qDebug() << QString("Channel %0 = %1").arg(i).arg(channelDesc[i]);
return channelDesc;
}
/** /**
Slot for switching the airframe type. We do it explicitely Slot for switching the airframe type. We do it explicitely
rather than a signal in the UI, because we want to force a fitInView of the quad shapes. rather than a signal in the UI, because we want to force a fitInView of the quad shapes.
This is because this method (fitinview) only works when the widget is shown. This is because this method (fitinview) only works when the widget is shown.
*/ */
void ConfigVehicleTypeWidget::switchAirframeType(int index){ void ConfigVehicleTypeWidget::switchAirframeType(int index)
{
m_aircraft->airframesWidget->setCurrentIndex(index); m_aircraft->airframesWidget->setCurrentIndex(index);
m_aircraft->quadShape->setSceneRect(quad->boundingRect()); m_aircraft->quadShape->setSceneRect(quad->boundingRect());
m_aircraft->quadShape->fitInView(quad, Qt::KeepAspectRatio); m_aircraft->quadShape->fitInView(quad, Qt::KeepAspectRatio);
@ -331,7 +415,6 @@ void ConfigVehicleTypeWidget::toggleRudder2(int index)
} }
} }
///////////////////////////////////////////////////////// /////////////////////////////////////////////////////////
/// Feed Forward Testing /// Feed Forward Testing
///////////////////////////////////////////////////////// /////////////////////////////////////////////////////////
@ -525,8 +608,10 @@ void ConfigVehicleTypeWidget::updateCustomThrottle2CurveValue(QList<double> list
/** /**
Refreshes the current value of the SystemSettings which holds the aircraft type Refreshes the current value of the SystemSettings which holds the aircraft type
*/ */
void ConfigVehicleTypeWidget::refreshWidgetsValues(UAVObject *) void ConfigVehicleTypeWidget::refreshWidgetsValues(UAVObject * o)
{ {
Q_UNUSED(o);
if(!allObjectsUpdated()) if(!allObjectsUpdated())
return; return;
@ -609,7 +694,7 @@ void ConfigVehicleTypeWidget::refreshWidgetsValues(UAVObject *)
if (frameType.startsWith("FixedWing")) { if (frameType.startsWith("FixedWing")) {
// Retrieve fixed wing settings // Retrieve fixed wing settings
refreshFixedWingWidgetsValues(frameType); m_fixedwing->refreshWidgetsValues(frameType);
} else if (frameType == "Tri" || } else if (frameType == "Tri" ||
frameType == "QuadX" || frameType == "QuadP" || frameType == "QuadX" || frameType == "QuadP" ||
@ -617,17 +702,18 @@ void ConfigVehicleTypeWidget::refreshWidgetsValues(UAVObject *)
frameType == "Octo" || frameType == "OctoV" || frameType == "OctoCoaxP" || frameType == "OctoCoaxX" ) { frameType == "Octo" || frameType == "OctoV" || frameType == "OctoCoaxP" || frameType == "OctoCoaxX" ) {
// Retrieve multirotor settings // Retrieve multirotor settings
refreshMultiRotorWidgetsValues(frameType); m_multirotor->refreshWidgetsValues(frameType);
} else if (frameType == "HeliCP") { } else if (frameType == "HeliCP") {
m_aircraft->widget_3->requestccpmUpdate(); setComboCurrentIndex(m_aircraft->aircraftType, m_aircraft->aircraftType->findText("Helicopter"));
m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Helicopter"));//"Helicopter" m_heli->refreshWidgetsValues(frameType);
} else if (frameType.startsWith("GroundVehicle")) { } else if (frameType.startsWith("GroundVehicle")) {
// Retrieve ground vehicle settings // Retrieve ground vehicle settings
refreshGroundVehicleWidgetsValues(frameType); m_groundvehicle->refreshWidgetsValues(frameType);
} else if (frameType == "Custom") { } else if (frameType == "Custom") {
m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Custom")); setComboCurrentIndex(m_aircraft->aircraftType, m_aircraft->aircraftType->findText("Custom"));
} }
@ -641,13 +727,13 @@ void ConfigVehicleTypeWidget::refreshWidgetsValues(UAVObject *)
*/ */
void ConfigVehicleTypeWidget::setupAirframeUI(QString frameType) void ConfigVehicleTypeWidget::setupAirframeUI(QString frameType)
{ {
bool dirty=isDirty(); bool dirty=isDirty();
if(frameType == "FixedWing" || frameType == "Elevator aileron rudder" || if(frameType == "FixedWing" || frameType == "Elevator aileron rudder" ||
frameType == "FixedWingElevon" || frameType == "Elevon" || frameType == "FixedWingElevon" || frameType == "Elevon" ||
frameType == "FixedWingVtail" || frameType == "Vtail"){ frameType == "FixedWingVtail" || frameType == "Vtail"){
setupFixedWingUI(frameType); m_fixedwing->setupUI(frameType);
} else if (frameType == "Tri" || frameType == "Tricopter Y" || }
else if (frameType == "Tri" || frameType == "Tricopter Y" ||
frameType == "QuadX" || frameType == "Quad X" || frameType == "QuadX" || frameType == "Quad X" ||
frameType == "QuadP" || frameType == "Quad +" || frameType == "QuadP" || frameType == "Quad +" ||
frameType == "Hexa" || frameType == "Hexacopter" || frameType == "Hexa" || frameType == "Hexacopter" ||
@ -659,12 +745,15 @@ void ConfigVehicleTypeWidget::setupAirframeUI(QString frameType)
frameType == "OctoCoaxX" || frameType == "Octo Coax X" ) { frameType == "OctoCoaxX" || frameType == "Octo Coax X" ) {
//Call multi-rotor setup UI //Call multi-rotor setup UI
setupMultiRotorUI(frameType); m_multirotor->setupUI(frameType);
}
else if (frameType == "HeliCP") {
m_heli->setupUI(frameType);
} }
else if (frameType == "GroundVehicleCar" || frameType == "Turnable (car)" || else if (frameType == "GroundVehicleCar" || frameType == "Turnable (car)" ||
frameType == "GroundVehicleDifferential" || frameType == "Differential (tank)" || frameType == "GroundVehicleDifferential" || frameType == "Differential (tank)" ||
frameType == "GroundVehicleMotorcyle" || frameType == "Motorcycle") { frameType == "GroundVehicleMotorcyle" || frameType == "Motorcycle") {
setupGroundVehicleUI(frameType); m_groundvehicle->setupUI(frameType);
} }
//SHOULDN'T THIS BE DONE ONLY IN QUAD SETUP, AND NOT ALL THE REST??? //SHOULDN'T THIS BE DONE ONLY IN QUAD SETUP, AND NOT ALL THE REST???
@ -685,26 +774,6 @@ void ConfigVehicleTypeWidget::resetField(UAVObjectField * field)
} }
} }
/**
Reset actuator values
*/
void ConfigVehicleTypeWidget::resetActuators()
{
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorSettings")));
Q_ASSERT(obj);
QList<UAVObjectField*> fieldList = obj->getFields();
// Reset all assignements first:
foreach (UAVObjectField* field, fieldList) {
// NOTE: we assume that all options in ActuatorSettings are a channel assignement
// except for the options called "ChannelBoxXXX"
if (field->getUnits().contains("channel")) {
field->setValue(field->getOptions().last());
}
}
}
/** /**
Updates the custom airframe settings based on the current airframe. Updates the custom airframe settings based on the current airframe.
@ -712,9 +781,14 @@ void ConfigVehicleTypeWidget::resetActuators()
*/ */
void ConfigVehicleTypeWidget::updateCustomAirframeUI() void ConfigVehicleTypeWidget::updateCustomAirframeUI()
{ {
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
UAVObjectField* field = obj->getField(QString("ThrottleCurve1"));
QList<double> curveValues; QList<double> curveValues;
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
Q_ASSERT(obj);
UAVObjectField* field = obj->getField(QString("ThrottleCurve1"));
if (field)
{
// If the 1st element of the curve is <= -10, then the curve // If the 1st element of the curve is <= -10, then the curve
// is a straight line (that's how the mixer works on the mainboard): // is a straight line (that's how the mixer works on the mainboard):
if (field->getValue(0).toInt() <= -10) { if (field->getValue(0).toInt() <= -10) {
@ -732,9 +806,13 @@ void ConfigVehicleTypeWidget::updateCustomAirframeUI()
else else
m_aircraft->customThrottle1Curve->initCurve(curveValues); m_aircraft->customThrottle1Curve->initCurve(curveValues);
} }
}
curveValues.clear();
field = obj->getField(QString("ThrottleCurve2")); field = obj->getField(QString("ThrottleCurve2"));
curveValues.clear(); if (field)
{
// If the 1st element of the curve is <= -10, then the curve // If the 1st element of the curve is <= -10, then the curve
// is a straight line (that's how the mixer works on the mainboard): // is a straight line (that's how the mixer works on the mainboard):
if (field->getValue(0).toInt() <= -10) { if (field->getValue(0).toInt() <= -10) {
@ -745,15 +823,23 @@ void ConfigVehicleTypeWidget::updateCustomAirframeUI()
} }
m_aircraft->customThrottle2Curve->initCurve(curveValues); m_aircraft->customThrottle2Curve->initCurve(curveValues);
} }
}
// Update the table: // Update the table:
for (int i=0; i<8; i++) { for (int i=0; i<8; i++) {
field = obj->getField(mixerTypes.at(i)); field = obj->getField(mixerTypes.at(i));
if (field)
{
QComboBox* q = (QComboBox*)m_aircraft->customMixerTable->cellWidget(0,i); QComboBox* q = (QComboBox*)m_aircraft->customMixerTable->cellWidget(0,i);
if (q)
{
QString s = field->getValue().toString(); QString s = field->getValue().toString();
q->setCurrentIndex(q->findText(s)); setComboCurrentIndex(q, q->findText(s));
//bool en = (s != "Disabled"); }
field = obj->getField(mixerVectors.at(i)); field = obj->getField(mixerVectors.at(i));
if (field)
{
int ti = field->getElementNames().indexOf("ThrottleCurve1"); int ti = field->getElementNames().indexOf("ThrottleCurve1");
m_aircraft->customMixerTable->item(1,i)->setText(field->getValue(ti).toString()); m_aircraft->customMixerTable->item(1,i)->setText(field->getValue(ti).toString());
ti = field->getElementNames().indexOf("ThrottleCurve2"); ti = field->getElementNames().indexOf("ThrottleCurve2");
@ -765,6 +851,8 @@ void ConfigVehicleTypeWidget::updateCustomAirframeUI()
ti = field->getElementNames().indexOf("Yaw"); ti = field->getElementNames().indexOf("Yaw");
m_aircraft->customMixerTable->item(5,i)->setText(field->getValue(ti).toString()); m_aircraft->customMixerTable->item(5,i)->setText(field->getValue(ti).toString());
} }
}
}
} }
@ -777,23 +865,25 @@ void ConfigVehicleTypeWidget::updateCustomAirframeUI()
*/ */
void ConfigVehicleTypeWidget::updateObjectsFromWidgets() void ConfigVehicleTypeWidget::updateObjectsFromWidgets()
{ {
qDebug()<<"updateObjectsFromWidgets"; UAVDataObject* obj;
UAVObjectField* field;
QString airframeType = "Custom"; //Sets airframe type default to "Custom" QString airframeType = "Custom"; //Sets airframe type default to "Custom"
if (m_aircraft->aircraftType->currentText() == "Fixed Wing") { if (m_aircraft->aircraftType->currentText() == "Fixed Wing") {
airframeType = updateFixedWingObjectsFromWidgets(); airframeType = m_fixedwing->updateConfigObjectsFromWidgets();
} else if (m_aircraft->aircraftType->currentText() == "Multirotor") { }
//update the mixer else if (m_aircraft->aircraftType->currentText() == "Multirotor") {
airframeType = updateMultiRotorObjectsFromWidgets(); airframeType = m_multirotor->updateConfigObjectsFromWidgets();
} else if (m_aircraft->aircraftType->currentText() == "Helicopter") { }
airframeType = "HeliCP"; else if (m_aircraft->aircraftType->currentText() == "Helicopter") {
m_aircraft->widget_3->sendccpmUpdate(); airframeType = m_heli->updateConfigObjectsFromWidgets();
} else if (m_aircraft->aircraftType->currentText() == "Ground") { }
airframeType = updateGroundVehicleObjectsFromWidgets(); else if (m_aircraft->aircraftType->currentText() == "Ground") {
} else { airframeType = m_groundvehicle->updateConfigObjectsFromWidgets();
airframeType = "Custom"; }
else {
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings"))); obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
UAVObjectField* field = obj->getField(QString("FeedForward")); field = obj->getField(QString("FeedForward"));
// Curve is also common to all quads: // Curve is also common to all quads:
field = obj->getField("ThrottleCurve1"); field = obj->getField("ThrottleCurve1");
@ -826,14 +916,13 @@ void ConfigVehicleTypeWidget::updateObjectsFromWidgets()
ti = field->getElementNames().indexOf("Yaw"); ti = field->getElementNames().indexOf("Yaw");
field->setValue(m_aircraft->customMixerTable->item(5,i)->text(),ti); field->setValue(m_aircraft->customMixerTable->item(5,i)->text(),ti);
} }
} }
// set the airframe type
//WHAT DOES THIS DO? obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("SystemSettings")));
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("SystemSettings"))); field = obj->getField(QString("AirframeType"));
UAVObjectField* field = obj->getField(QString("AirframeType"));
field->setValue(airframeType); field->setValue(airframeType);
updateCustomAirframeUI();
} }
/** /**
@ -845,6 +934,16 @@ void ConfigVehicleTypeWidget::openHelp()
QDesktopServices::openUrl( QUrl("http://wiki.openpilot.org/display/Doc/Airframe+configuration", QUrl::StrictMode) ); QDesktopServices::openUrl( QUrl("http://wiki.openpilot.org/display/Doc/Airframe+configuration", QUrl::StrictMode) );
} }
/**
Helper function:
Sets the current index on supplied combobox to index
if it is within bounds 0 <= index < combobox.count()
*/
void ConfigVehicleTypeWidget::setComboCurrentIndex(QComboBox* box, int index)
{
if (index >= 0 && index < box->count())
box->setCurrentIndex(index);
}
/** /**
WHAT DOES THIS DO??? WHAT DOES THIS DO???
@ -873,6 +972,9 @@ void ConfigVehicleTypeWidget::addToDirtyMonitor()
addWidget(m_aircraft->multiMotorChannelBox6); addWidget(m_aircraft->multiMotorChannelBox6);
addWidget(m_aircraft->multiMotorChannelBox7); addWidget(m_aircraft->multiMotorChannelBox7);
addWidget(m_aircraft->multiMotorChannelBox8); addWidget(m_aircraft->multiMotorChannelBox8);
addWidget(m_aircraft->mrPitchMixLevel);
addWidget(m_aircraft->mrRollMixLevel);
addWidget(m_aircraft->mrYawMixLevel);
addWidget(m_aircraft->triYawChannelBox); addWidget(m_aircraft->triYawChannelBox);
addWidget(m_aircraft->aircraftType); addWidget(m_aircraft->aircraftType);
addWidget(m_aircraft->fwEngineChannelBox); addWidget(m_aircraft->fwEngineChannelBox);
@ -884,44 +986,44 @@ void ConfigVehicleTypeWidget::addToDirtyMonitor()
addWidget(m_aircraft->fwRudder2ChannelBox); addWidget(m_aircraft->fwRudder2ChannelBox);
addWidget(m_aircraft->elevonSlider1); addWidget(m_aircraft->elevonSlider1);
addWidget(m_aircraft->elevonSlider2); addWidget(m_aircraft->elevonSlider2);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmType); addWidget(m_heli->m_ccpm->ccpmType);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmTailChannel); addWidget(m_heli->m_ccpm->ccpmTailChannel);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmEngineChannel); addWidget(m_heli->m_ccpm->ccpmEngineChannel);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmServoWChannel); addWidget(m_heli->m_ccpm->ccpmServoWChannel);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmServoXChannel); addWidget(m_heli->m_ccpm->ccpmServoXChannel);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmServoYChannel); addWidget(m_heli->m_ccpm->ccpmServoYChannel);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmSingleServo); addWidget(m_heli->m_ccpm->ccpmSingleServo);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmServoZChannel); addWidget(m_heli->m_ccpm->ccpmServoZChannel);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmAngleW); addWidget(m_heli->m_ccpm->ccpmAngleW);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmAngleX); addWidget(m_heli->m_ccpm->ccpmAngleX);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmCorrectionAngle); addWidget(m_heli->m_ccpm->ccpmCorrectionAngle);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmAngleZ); addWidget(m_heli->m_ccpm->ccpmAngleZ);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmAngleY); addWidget(m_heli->m_ccpm->ccpmAngleY);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmCollectivePassthrough); addWidget(m_heli->m_ccpm->ccpmCollectivePassthrough);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmLinkRoll); addWidget(m_heli->m_ccpm->ccpmLinkRoll);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmLinkCyclic); addWidget(m_heli->m_ccpm->ccpmLinkCyclic);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmRevoSlider); addWidget(m_heli->m_ccpm->ccpmRevoSlider);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmREVOspinBox); addWidget(m_heli->m_ccpm->ccpmREVOspinBox);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmCollectiveSlider); addWidget(m_heli->m_ccpm->ccpmCollectiveSlider);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmCollectivespinBox); addWidget(m_heli->m_ccpm->ccpmCollectivespinBox);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmCollectiveScale); addWidget(m_heli->m_ccpm->ccpmCollectiveScale);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmCollectiveScaleBox); addWidget(m_heli->m_ccpm->ccpmCollectiveScaleBox);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmCyclicScale); addWidget(m_heli->m_ccpm->ccpmCyclicScale);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmPitchScale); addWidget(m_heli->m_ccpm->ccpmPitchScale);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmPitchScaleBox); addWidget(m_heli->m_ccpm->ccpmPitchScaleBox);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmRollScale); addWidget(m_heli->m_ccpm->ccpmRollScale);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmRollScaleBox); addWidget(m_heli->m_ccpm->ccpmRollScaleBox);
addWidget(m_aircraft->widget_3->m_ccpm->SwashLvlPositionSlider); addWidget(m_heli->m_ccpm->SwashLvlPositionSlider);
addWidget(m_aircraft->widget_3->m_ccpm->SwashLvlPositionSpinBox); addWidget(m_heli->m_ccpm->SwashLvlPositionSpinBox);
addWidget(m_aircraft->widget_3->m_ccpm->CurveType); addWidget(m_heli->m_ccpm->CurveType);
addWidget(m_aircraft->widget_3->m_ccpm->NumCurvePoints); addWidget(m_heli->m_ccpm->NumCurvePoints);
addWidget(m_aircraft->widget_3->m_ccpm->CurveValue1); addWidget(m_heli->m_ccpm->CurveValue1);
addWidget(m_aircraft->widget_3->m_ccpm->CurveValue2); addWidget(m_heli->m_ccpm->CurveValue2);
addWidget(m_aircraft->widget_3->m_ccpm->CurveValue3); addWidget(m_heli->m_ccpm->CurveValue3);
addWidget(m_aircraft->widget_3->m_ccpm->CurveToGenerate); addWidget(m_heli->m_ccpm->CurveToGenerate);
addWidget(m_aircraft->widget_3->m_ccpm->CurveSettings); addWidget(m_heli->m_ccpm->CurveSettings);
addWidget(m_aircraft->widget_3->m_ccpm->ThrottleCurve); addWidget(m_heli->m_ccpm->ThrottleCurve);
addWidget(m_aircraft->widget_3->m_ccpm->PitchCurve); addWidget(m_heli->m_ccpm->PitchCurve);
addWidget(m_aircraft->widget_3->m_ccpm->ccpmAdvancedSettingsTable); addWidget(m_heli->m_ccpm->ccpmAdvancedSettingsTable);
} }

View File

@ -33,6 +33,12 @@
#include "uavobjectmanager.h" #include "uavobjectmanager.h"
#include "uavobject.h" #include "uavobject.h"
#include "uavtalk/telemetrymanager.h" #include "uavtalk/telemetrymanager.h"
#include "cfg_vehicletypes/configccpmwidget.h"
#include "cfg_vehicletypes/configfixedwingwidget.h"
#include "cfg_vehicletypes/configmultirotorwidget.h"
#include "cfg_vehicletypes/configgroundvehiclewidget.h"
#include <QtGui/QWidget> #include <QtGui/QWidget>
#include <QList> #include <QList>
#include <QItemDelegate> #include <QItemDelegate>
@ -47,54 +53,40 @@ public:
ConfigVehicleTypeWidget(QWidget *parent = 0); ConfigVehicleTypeWidget(QWidget *parent = 0);
~ConfigVehicleTypeWidget(); ~ConfigVehicleTypeWidget();
static QStringList getChannelDescriptions();
private: private:
Ui_AircraftWidget *m_aircraft; Ui_AircraftWidget *m_aircraft;
bool setupFrameFixedWing(QString airframeType);
bool setupFrameElevon(QString airframeType); ConfigCcpmWidget *m_heli;
bool setupFrameVtail(QString airframeType); ConfigFixedWingWidget *m_fixedwing;
bool setupQuad(bool pLayout); ConfigMultiRotorWidget *m_multirotor;
bool setupHexa(bool pLayout); ConfigGroundVehicleWidget *m_groundvehicle;
bool setupOcto();
bool setupGroundVehicleCar(QString airframeType);
bool setupGroundVehicleDifferential(QString airframeType);
bool setupGroundVehicleMotorcycle(QString airframeType);
void updateCustomAirframeUI(); void updateCustomAirframeUI();
bool setupMultiRotorMixer(double mixerFactors[8][3]);
void setupMotors(QList<QString> motorList);
void addToDirtyMonitor(); void addToDirtyMonitor();
void resetField(UAVObjectField * field); void resetField(UAVObjectField * field);
void resetMixer (MixerCurveWidget *mixer, int numElements, double maxvalue); void resetMixer (MixerCurveWidget *mixer, int numElements, double maxvalue);
void resetActuators();
//void setMixerChannel(int channelNumber, bool channelIsMotor, QList<double> vector);
void setupQuadMotor(int channel, double roll, double pitch, double yaw);
//void setMixerChannel(int channelNumber, bool channelIsMotor, QList<double> vector);
QStringList channelNames;
QStringList mixerTypes; QStringList mixerTypes;
QStringList mixerVectors; QStringList mixerVectors;
QGraphicsSvgItem *quad; QGraphicsSvgItem *quad;
bool ffTuningInProgress; bool ffTuningInProgress;
bool ffTuningPhase; bool ffTuningPhase;
UAVObject::Metadata accInitialData; UAVObject::Metadata accInitialData;
private slots: private slots:
virtual void refreshWidgetsValues(UAVObject * obj = NULL);
void refreshFixedWingWidgetsValues(QString frameType);
void refreshMultiRotorWidgetsValues(QString frameType);
void refreshGroundVehicleWidgetsValues(QString frameType);
void updateObjectsFromWidgets(); virtual void refreshWidgetsValues(UAVObject * o=NULL);
QString updateFixedWingObjectsFromWidgets(); virtual void updateObjectsFromWidgets();
QString updateMultiRotorObjectsFromWidgets();
QString updateGroundVehicleObjectsFromWidgets(); void setComboCurrentIndex(QComboBox* box, int index);
// void saveAircraftUpdate();
void setupAirframeUI(QString type); void setupAirframeUI(QString type);
void setupFixedWingUI(QString frameType);
void setupMultiRotorUI(QString frameType);
void setupGroundVehicleUI(QString frameType);
void throwMultiRotorChannelConfigError(int numMotors);
void throwFixedWingChannelConfigError(QString airframeType);
void throwGroundVehicleChannelConfigError(QString airframeType);
void toggleAileron2(int index); void toggleAileron2(int index);
void toggleElevator2(int index); void toggleElevator2(int index);

View File

@ -30,10 +30,11 @@ CLEAN_FLIGHT := YES
endif endif
# Set up targets # Set up targets
FW_TARGETS := $(addprefix fw_, coptercontrol) $(addprefix fw_, revolution) ALL_BOARDS := coptercontrol pipxtreme revolution
FW_TARGETS_TOOLS := $(addprefix fw_, coptercontrol) FW_TARGETS := $(addprefix fw_, $(ALL_BOARDS))
BL_TARGETS := $(addprefix bl_, coptercontrol) FW_TARGETS_TOOLS := $(addprefix fw_, $(ALL_BOARDS))
BU_TARGETS := $(addprefix bu_, coptercontrol) BL_TARGETS := $(addprefix bl_, $(ALL_BOARDS))
BU_TARGETS := $(addprefix bu_, $(ALL_BOARDS))
help: help:
@echo @echo

View File

@ -22,6 +22,8 @@ device=$(hdiutil attach "${TEMP_FILE}" | \
cp -r "${APP_PATH}" "/Volumes/${VOL_NAME}" cp -r "${APP_PATH}" "/Volumes/${VOL_NAME}"
#cp -r "${FW_DIR}" "/Volumes/${VOL_NAME}/firmware" #cp -r "${FW_DIR}" "/Volumes/${VOL_NAME}/firmware"
cp "${FW_DIR}/fw_coptercontrol-${PACKAGE_LBL}.opfw" "/Volumes/${VOL_NAME}/Firmware" cp "${FW_DIR}/fw_coptercontrol-${PACKAGE_LBL}.opfw" "/Volumes/${VOL_NAME}/Firmware"
cp "${FW_DIR}/fw_pipxtreme-${PACKAGE_LBL}.opfw" "/Volumes/${VOL_NAME}/Firmware"
cp "${FW_DIR}/fw_revolution-${PACKAGE_LBL}.opfw" "/Volumes/${VOL_NAME}/Firmware"
cp "${BUILD_DIR}/uavobject-synthetics/matlab/OPLogConvert.m" "/Volumes/${VOL_NAME}/Utilities" cp "${BUILD_DIR}/uavobject-synthetics/matlab/OPLogConvert.m" "/Volumes/${VOL_NAME}/Utilities"

View File

@ -1,25 +1,6 @@
<xml> <xml>
<object name="ActuatorSettings" singleinstance="true" settings="true"> <object name="ActuatorSettings" singleinstance="true" settings="true">
<description>Settings for the @ref ActuatorModule that controls the channel assignments for the mixer based on AircraftType</description> <description>Settings for the @ref ActuatorModule that controls the channel assignments for the mixer based on AircraftType</description>
<field name="FixedWingRoll1" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,Channel9,Channel10,None" defaultvalue="None"/>
<field name="FixedWingRoll2" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,Channel9,Channel10,None" defaultvalue="None"/>
<field name="FixedWingPitch1" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,Channel9,Channel10,None" defaultvalue="None"/>
<field name="FixedWingPitch2" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,Channel9,Channel10,None" defaultvalue="None"/>
<field name="FixedWingYaw1" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,Channel9,Channel10,None" defaultvalue="None"/>
<field name="FixedWingYaw2" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,Channel9,Channel10,None" defaultvalue="None"/>
<field name="FixedWingThrottle" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,Channel9,Channel10,None" defaultvalue="None"/>
<field name="VTOLMotorN" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,Channel9,Channel10,None" defaultvalue="None"/>
<field name="VTOLMotorNE" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,Channel9,Channel10,None" defaultvalue="None"/>
<field name="VTOLMotorE" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,Channel9,Channel10,None" defaultvalue="None"/>
<field name="VTOLMotorSE" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,Channel9,Channel10,None" defaultvalue="None"/>
<field name="VTOLMotorS" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,Channel9,Channel10,None" defaultvalue="None"/>
<field name="VTOLMotorSW" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,Channel9,Channel10,None" defaultvalue="None"/>
<field name="VTOLMotorW" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,Channel9,Channel10,None" defaultvalue="None"/>
<field name="VTOLMotorNW" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,Channel9,Channel10,None" defaultvalue="None"/>
<field name="GroundVehicleThrottle1" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,Channel9,Channel10,None" defaultvalue="None"/>
<field name="GroundVehicleThrottle2" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,Channel9,Channel10,None" defaultvalue="None"/>
<field name="GroundVehicleSteering1" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,Channel9,Channel10,None" defaultvalue="None"/>
<field name="GroundVehicleSteering2" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,Channel9,Channel10,None" defaultvalue="None"/>
<field name="ChannelUpdateFreq" units="Hz" type="uint16" elements="4" defaultvalue="50"/> <field name="ChannelUpdateFreq" units="Hz" type="uint16" elements="4" defaultvalue="50"/>
<field name="ChannelMax" units="us" type="int16" elements="10" defaultvalue="1000"/> <field name="ChannelMax" units="us" type="int16" elements="10" defaultvalue="1000"/>
<field name="ChannelNeutral" units="us" type="int16" elements="10" defaultvalue="1000"/> <field name="ChannelNeutral" units="us" type="int16" elements="10" defaultvalue="1000"/>

View File

@ -2,7 +2,7 @@
<object name="SystemSettings" singleinstance="true" settings="true"> <object name="SystemSettings" singleinstance="true" settings="true">
<description>Select airframe type. Currently used by @ref ActuatorModule to choose mixing from @ref ActuatorDesired to @ref ActuatorCommand</description> <description>Select airframe type. Currently used by @ref ActuatorModule to choose mixing from @ref ActuatorDesired to @ref ActuatorCommand</description>
<field name="AirframeType" units="" type="enum" elements="1" options="FixedWing,FixedWingElevon,FixedWingVtail,VTOL,HeliCP,QuadX,QuadP,Hexa,Octo,Custom,HexaX,OctoV,OctoCoaxP,OctoCoaxX,HexaCoax,Tri,GroundVehicleCar,GroundVehicleDifferential,GroundVehicleMotorcycle" defaultvalue="FixedWing"/> <field name="AirframeType" units="" type="enum" elements="1" options="FixedWing,FixedWingElevon,FixedWingVtail,VTOL,HeliCP,QuadX,QuadP,Hexa,Octo,Custom,HexaX,OctoV,OctoCoaxP,OctoCoaxX,HexaCoax,Tri,GroundVehicleCar,GroundVehicleDifferential,GroundVehicleMotorcycle" defaultvalue="FixedWing"/>
<field name="GUIConfigData" units="bits" type="uint32" elements="2" defaultvalue="0"/> <field name="GUIConfigData" units="bits" type="uint32" elements="4" defaultvalue="0"/>
<access gcs="readwrite" flight="readwrite"/> <access gcs="readwrite" flight="readwrite"/>
<telemetrygcs acked="true" updatemode="onchange" period="0"/> <telemetrygcs acked="true" updatemode="onchange" period="0"/>
<telemetryflight acked="true" updatemode="onchange" period="0"/> <telemetryflight acked="true" updatemode="onchange" period="0"/>