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

OP-138 Start of the new Mixer configuration interface, for fixed wing only. This does not work yet, takes a long time to fully implement.

The system settings UAVObject is updated, you will have to recompile your firmware. If you want to take a look and let me know, please do!



git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@1737 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
edouard 2010-09-24 20:39:37 +00:00 committed by edouard
parent fa4818542e
commit eedf85a5ac
11 changed files with 478 additions and 95 deletions

View File

@ -78,7 +78,7 @@ typedef struct {
// Field information
// Field AirframeType information
/* Enumeration options for field AirframeType */
typedef enum { SYSTEMSETTINGS_AIRFRAMETYPE_FIXEDWING=0, SYSTEMSETTINGS_AIRFRAMETYPE_FIXEDWINGELEVON=1, SYSTEMSETTINGS_AIRFRAMETYPE_VTOL=2, SYSTEMSETTINGS_AIRFRAMETYPE_HELICP=3 } SystemSettingsAirframeTypeOptions;
typedef enum { SYSTEMSETTINGS_AIRFRAMETYPE_FIXEDWING=0, SYSTEMSETTINGS_AIRFRAMETYPE_FIXEDWINGELEVON=1, SYSTEMSETTINGS_AIRFRAMETYPE_FIXEDWINGVTAIL=2, SYSTEMSETTINGS_AIRFRAMETYPE_VTOL=3, SYSTEMSETTINGS_AIRFRAMETYPE_HELICP=4, SYSTEMSETTINGS_AIRFRAMETYPE_QUADX=5, SYSTEMSETTINGS_AIRFRAMETYPE_QUADP=6, SYSTEMSETTINGS_AIRFRAMETYPE_HEXA=7, SYSTEMSETTINGS_AIRFRAMETYPE_OCTO=8, SYSTEMSETTINGS_AIRFRAMETYPE_CUSTOM=9 } SystemSettingsAirframeTypeOptions;
// Generic interface functions

View File

@ -69,7 +69,7 @@
<item>
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>0</number>
<number>3</number>
</property>
<widget class="QWidget" name="fixedWing">
<property name="enabled">
@ -78,14 +78,7 @@
<property name="autoFillBackground">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="0,1">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Fixed Wing</string>
</property>
</widget>
</item>
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="0">
<item>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
@ -99,12 +92,12 @@
</sizepolicy>
</property>
<property name="text">
<string>Airframe type:</string>
<string>Airplane type:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox"/>
<widget class="QComboBox" name="fixedWingType"/>
</item>
<item>
<spacer name="horizontalSpacer_3">
@ -121,6 +114,136 @@
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>Channel Assignment</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="fwEngineLabel">
<property name="text">
<string>Engine</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="fwEngineChannel"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="fwAileron1Label">
<property name="text">
<string>Aileron 1</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="fwAileron1Channel"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="fwAileron2Label">
<property name="text">
<string>Aileron 2</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="fwElevator1Label">
<property name="text">
<string>Elevator 1</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="fwElevator1Channel"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="fwRudderLabel">
<property name="text">
<string>Rudder</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QComboBox" name="fwRudderChannel"/>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="fwAileron2Channel"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="fwElevator2Label">
<property name="text">
<string>Elevator 2</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="fwElevator2Channel"/>
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QLabel" name="label_13">
<property name="text">
<string>Throttle Curve</string>
</property>
</widget>
</item>
<item>
<widget class="MixerCurveWidget" name="fixedWingThrottle" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>250</width>
<height>250</height>
</size>
</property>
<property name="sizeIncrement">
<size>
<width>10</width>
<height>10</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
@ -148,7 +271,55 @@
</widget>
</item>
<item>
<layout class="QFormLayout" name="formLayout_2"/>
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="label_15">
<property name="text">
<string>Frame type:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="multirotorFrameType"/>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_14">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
@ -174,6 +345,17 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="custom">
<layout class="QVBoxLayout" name="verticalLayout_9">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Custom / Advanced setup UI</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
@ -228,6 +410,14 @@
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>MixerCurveWidget</class>
<extends>QWidget</extends>
<header>mixercurvewidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>

View File

@ -41,25 +41,46 @@ ConfigAirframeWidget::ConfigAirframeWidget(QWidget *parent) : ConfigTaskWidget(p
m_aircraft->setupUi(this);
// Now connect the widget to the ManualControlCommand / Channel UAVObject
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
/*
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
/*
UAVObject *obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("SystemSettings")));
UAVObject *obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("SystemSettings")));
QString fieldName = QString("AirframeType");
UAVObjectField *field = obj->getField(fieldName);
m_aircraft->aircraftType->addItems(field->getOptions());
*/
QStringList airframeTypes;
airframeTypes << "Fixed Wing" << "Multirotor" << "Helicopter";
airframeTypes << "Fixed Wing" << "Multirotor" << "Helicopter" << "Custom";
m_aircraft->aircraftType->addItems(airframeTypes);
m_aircraft->aircraftType->setCurrentIndex(1);
QStringList fixedWingTypes;
fixedWingTypes << "Elevator aileron rudder" << "Elevon" << "Vtail";
m_aircraft->fixedWingType->addItems(fixedWingTypes);
QStringList multiRotorTypes;
multiRotorTypes << "Quad +" << "Quad X" << "Hexacopter" << "Octocopter";
m_aircraft->multirotorFrameType->addItems(multiRotorTypes);
QStringList channels;
channels << "None" << "Channel0" << "Channel1" << "Channel2" <<
"Channel3" << "Channel4" << "Channel5" << "Channel6" << "Channel7";
// Now load all the channel assignements for fixed wing
m_aircraft->fwElevator1Channel->addItems(channels);
m_aircraft->fwElevator2Channel->addItems(channels);
m_aircraft->fwEngineChannel->addItems(channels);
m_aircraft->fwRudderChannel->addItems(channels);
m_aircraft->fwAileron1Channel->addItems(channels);
m_aircraft->fwAileron2Channel->addItems(channels);
requestAircraftUpdate();
connect(m_aircraft->saveAircraftToSD, SIGNAL(clicked()), this, SLOT(saveAircraftUpdate()));
connect(m_aircraft->saveAircraftToRAM, SIGNAL(clicked()), this, SLOT(sendAircraftUpdate()));
connect(m_aircraft->getAircraftCurrent, SIGNAL(clicked()), this, SLOT(requestAircraftUpdate()));
connect(m_aircraft->fixedWingType, SIGNAL(currentIndexChanged(QString)), this, SLOT(setupAirframeUI(QString)));
connect(parent, SIGNAL(autopilotConnected()),this, SLOT(requestAircraftUpdate()));
@ -87,10 +108,207 @@ void ConfigAirframeWidget::requestAircraftUpdate()
Q_ASSERT(obj);
obj->requestUpdate();
UAVObjectField *field = obj->getField(QString("AirframeType"));
m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText(field->getValue().toString()));
Q_ASSERT(field);
// m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText(field->getValue().toString()));
// At this stage, we will need to have some hardcoded settings in this code, this
// is not ideal, but here you go.
QString frameType = field->getValue().toString();
setupAirframeUI(frameType);
// Load the throttle curve for fixed wing frames:
if (frameType.startsWith("FixedWing")) {
obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("MixerSettings")));
Q_ASSERT(obj);
obj->requestUpdate();
field = obj->getField(QString("ThrottleCurve1"));
Q_ASSERT(field);
QList<double> curveValues;
// 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):
if (field->getValue(0).toInt() <= -10) {
for (double i=0; i<field->getNumElements(); i++) {
curveValues.append(-1.0 + 2*i/(field->getNumElements()-1));
}
} else {
for (unsigned int i=0; i < field->getNumElements(); i++) {
curveValues.append(field->getValue(i).toDouble());
}
}
m_aircraft->fixedWingThrottle->initCurve(curveValues);
// Then retrieve how channels are setup
obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ActuatorSettings")));
Q_ASSERT(obj);
field = obj->getField(QString("FixedWingThrottle"));
Q_ASSERT(field);
m_aircraft->fwEngineChannel->setCurrentIndex(m_aircraft->fwEngineChannel->findText(field->getValue().toString()));
field = obj->getField(QString("FixedWingRoll1"));
Q_ASSERT(field);
m_aircraft->fwAileron1Channel->setCurrentIndex(m_aircraft->fwAileron1Channel->findText(field->getValue().toString()));
field = obj->getField(QString("FixedWingRoll2"));
Q_ASSERT(field);
m_aircraft->fwAileron2Channel->setCurrentIndex(m_aircraft->fwAileron2Channel->findText(field->getValue().toString()));
field = obj->getField(QString("FixedWingPitch1"));
Q_ASSERT(field);
m_aircraft->fwElevator1Channel->setCurrentIndex(m_aircraft->fwElevator1Channel->findText(field->getValue().toString()));
field = obj->getField(QString("FixedWingPitch2"));
Q_ASSERT(field);
m_aircraft->fwElevator2Channel->setCurrentIndex(m_aircraft->fwElevator2Channel->findText(field->getValue().toString()));
field = obj->getField(QString("FixedWingYaw"));
Q_ASSERT(field);
m_aircraft->fwRudderChannel->setCurrentIndex(m_aircraft->fwRudderChannel->findText(field->getValue().toString()));
}
}
/**
\brief Sets up the mixer depending on Airframe type. Accepts either system settings or
combo box entry from airframe type, as those do not overlap.
*/
void ConfigAirframeWidget::setupAirframeUI(QString frameType)
{
if (frameType == "FixedWing" || frameType == "Elevator aileron rudder") {
// Setup the UI
m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Fixed Wing"));
m_aircraft->fixedWingType->setCurrentIndex(m_aircraft->fixedWingType->findText("Elevator aileron rudder"));
m_aircraft->fwRudderChannel->setEnabled(true);
m_aircraft->fwRudderLabel->setEnabled(true);
m_aircraft->fwElevator1Channel->setEnabled(true);
m_aircraft->fwElevator1Label->setEnabled(true);
m_aircraft->fwElevator2Channel->setEnabled(true);
m_aircraft->fwElevator2Label->setEnabled(true);
} else if (frameType == "FixedWingElevon" || frameType == "Elevon") {
m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Fixed Wing"));
m_aircraft->fixedWingType->setCurrentIndex(m_aircraft->fixedWingType->findText("Elevon"));
m_aircraft->fwElevator1Channel->setEnabled(false);
m_aircraft->fwElevator1Label->setEnabled(false);
m_aircraft->fwElevator2Channel->setEnabled(false);
m_aircraft->fwElevator2Label->setEnabled(false);
m_aircraft->fwRudderChannel->setEnabled(true);
m_aircraft->fwRudderLabel->setEnabled(true);
} else if (frameType == "FixedWingVtail" || frameType == "Vtail") {
m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Fixed Wing"));
m_aircraft->fixedWingType->setCurrentIndex(m_aircraft->fixedWingType->findText("Vtail"));
m_aircraft->fwRudderChannel->setEnabled(false);
m_aircraft->fwRudderLabel->setEnabled(false);
m_aircraft->fwElevator1Channel->setEnabled(true);
m_aircraft->fwElevator1Label->setEnabled(true);
m_aircraft->fwElevator2Channel->setEnabled(true);
m_aircraft->fwElevator2Label->setEnabled(true);
}
}
/**
Setup Elevator/Aileron/Rudder airframe.
If both Aileron channels are set to 'None' (EasyStar), do Pitch/Rudder mixing
Returns False if impossible to create the mixer.
*/
bool ConfigAirframeWidget::setupFrameFixedWing()
{
// Check coherence:
// - At least Pitch and either Roll or Yaw
if (m_aircraft->fwElevator1Channel->currentText() == "None" ||
((m_aircraft->fwAileron1Channel->currentText() == "None") &&
(m_aircraft->fwRudderChannel->currentText() == "None"))) {
// TODO: explain the problem in the UI
return false;
}
// Now setup the channels:
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorSettings")));
Q_ASSERT(obj);
QList<UAVObjectField*> fieldList = obj->getFields();
foreach (UAVObjectField* field, fieldList) {
// NOTE: we assume that all options in ActuatorSettings are a channel assignement
// except for the options called "ChannelXXX"
if (field->getUnits().contains("channel")) {
field->setValue(field->getOptions().last());
}
}
// Elevator
UAVObjectField *field = obj->getField("FixedWingPitch1");
Q_ASSERT(field);
field->setValue(m_aircraft->fwElevator1Channel->currentText());
field = obj->getField("FixedWingPitch2");
Q_ASSERT(field);
field->setValue(m_aircraft->fwElevator2Channel->currentText());
// Aileron
field = obj->getField("FixedWingRoll1");
Q_ASSERT(field);
field->setValue(m_aircraft->fwAileron1Channel->currentText());
field = obj->getField("FixedWingRoll2");
Q_ASSERT(field);
field->setValue(m_aircraft->fwAileron2Channel->currentText());
// Rudder
field = obj->getField("FixedWingYaw");
Q_ASSERT(field);
field->setValue(m_aircraft->fwRudderChannel->currentText());
// Throttle
field = obj->getField("FixedWingThrottle");
Q_ASSERT(field);
field->setValue(m_aircraft->fwEngineChannel->currentText());
obj->updated();
// Save the curve:
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
Q_ASSERT(obj);
field = obj->getField("ThrottleCurve1");
QList<double> curve = m_aircraft->fixedWingThrottle->getCurve();
for (int i=0;i<curve.length();i++) {
field->setValue(curve.at(i),i);
}
// ... 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
QStringList mixerTypes;
mixerTypes << "Mixer0Type" << "Mixer1Type" << "Mixer2Type" << "Mixer3Type"
<< "Mixer4Type" << "Mixer5Type" << "Mixer6Type" << "Mixer7Type";
QStringList mixerVectors;
mixerVectors << "Mixer0Vector" << "Mixer1Vector" << "Mixer2Vector" << "Mixer3Vector"
<< "Mixer4Vector" << "Mixer5Vector" << "Mixer6Vector" << "Mixer7Vector";
// Disable all
foreach(QString mixer, mixerTypes) {
field = obj->getField(mixer);
Q_ASSERT(field);
field->setValue("Disabled");
}
// and set only the relevant channels:
// Engine
int eng = m_aircraft->fwEngineChannel->currentIndex()-1;
field = obj->getField(mixerTypes.at(eng));
field->setValue("Motor");
field = obj->getField(mixerVectors.at(eng));
// First of all reset the vector
for (int i=0;i<field->getNumElements();i++) {
field->setValue(0,i);
}
int ti = field->getElementNames().indexOf("ThrottleCurve1");
field->setValue(1, ti);
obj->updated();
return true;
}
/**
Setup Elevon
*/
/*
void ConfigAirframeWidget::setupFrameElevon()
{
// Check coherence:
// - At least Aileron1 and Aileron 2
}
*/
/**
Sends the config to the board (airframe type)
@ -99,10 +317,25 @@ void ConfigAirframeWidget::sendAircraftUpdate()
{
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
QString airframeType;
if (m_aircraft->aircraftType->currentText() == "Fixed Wing") {
if (m_aircraft->fixedWingType->currentText() == "Elevator aileron rudder" ) {
airframeType = "FixedWing";
setupFrameFixedWing();
} else if (m_aircraft->fixedWingType->currentText() == "Elevon") {
airframeType = "FixedWingElevon";
} else { // Vtail
airframeType = "FixedWingVtail";
}
} else {
airframeType = "FixedWing";
}
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("SystemSettings")));
Q_ASSERT(obj);
UAVObjectField* field = obj->getField(QString("AirframeType"));
field->setValue(m_aircraft->aircraftType->currentText());
field->setValue(airframeType);
obj->updated();
}

View File

@ -46,12 +46,15 @@ public:
~ConfigAirframeWidget();
private:
Ui_AircraftWidget *m_aircraft;
Ui_AircraftWidget *m_aircraft;
bool setupFrameFixedWing();
private slots:
void requestAircraftUpdate();
void sendAircraftUpdate();
void saveAircraftUpdate();
private slots:
void requestAircraftUpdate();
void sendAircraftUpdate();
void saveAircraftUpdate();
void setupAirframeUI(QString type);
};

View File

@ -56,60 +56,6 @@ QList<Edge *> Node::edges() const
return edgeList;
}
void Node::calculateForces()
{
if (!scene() || scene()->mouseGrabberItem() == this) {
newPos = pos();
return;
}
// Sum up all forces pushing this item away
qreal xvel = 0;
qreal yvel = 0;
foreach (QGraphicsItem *item, scene()->items()) {
Node *node = qgraphicsitem_cast<Node *>(item);
if (!node)
continue;
QLineF line(mapFromItem(node, 0, 0), QPointF(0, 0));
qreal dx = line.dx();
qreal dy = line.dy();
double l = 2.0 * (dx * dx + dy * dy);
if (l > 0) {
xvel += (dx * 150.0) / l;
yvel += (dy * 150.0) / l;
}
}
// Now subtract all forces pulling items together
double weight = (edgeList.size() + 1) * 10;
foreach (Edge *edge, edgeList) {
QPointF pos;
if (edge->sourceNode() == this)
pos = mapFromItem(edge->destNode(), 0, 0);
else
pos = mapFromItem(edge->sourceNode(), 0, 0);
xvel += pos.x() / weight;
yvel += pos.y() / weight;
}
if (qAbs(xvel) < 0.1 && qAbs(yvel) < 0.1)
xvel = yvel = 0;
QRectF sceneRect = scene()->sceneRect();
newPos = pos() + QPointF(xvel, yvel);
newPos.setX(qMin(qMax(newPos.x(), sceneRect.left() + 10), sceneRect.right() - 10));
newPos.setY(qMin(qMax(newPos.y(), sceneRect.top() + 10), sceneRect.bottom() - 10));
}
bool Node::advance()
{
if (newPos == pos())
return false;
setPos(newPos);
return true;
}
QRectF Node::boundingRect() const
{
@ -127,19 +73,21 @@ QPainterPath Node::shape() const
void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
{
/*
painter->setPen(Qt::NoPen);
painter->setBrush(Qt::darkGray);
painter->drawEllipse(-7, -7, 20, 20);
*/
QRadialGradient gradient(-3, -3, 10);
if (option->state & QStyle::State_Sunken) {
gradient.setCenter(3, 3);
gradient.setFocalPoint(3, 3);
gradient.setColorAt(1, QColor(Qt::yellow).light(120));
gradient.setColorAt(0, QColor(Qt::darkYellow).light(120));
gradient.setColorAt(1, QColor("#1c870b").light(120));
gradient.setColorAt(0, QColor("#116703").light(120));
} else {
gradient.setColorAt(0, Qt::yellow);
gradient.setColorAt(1, Qt::darkYellow);
gradient.setColorAt(0, "#1c870b");
gradient.setColorAt(1, "#116703");
}
painter->setBrush(gradient);
painter->setPen(QPen(Qt::black, 0));
@ -157,9 +105,14 @@ QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value)
case ItemPositionChange: {
if (!vertical)
break;
// Foce node to move vertically
// Force node to move vertically
QPointF newPos = value.toPointF();
newPos.setX(pos().x());
// Stay inside graph
if (newPos.y() < 0)
newPos.setY(0);
if (newPos.y() > graph->height())
newPos.setY(graph->height());
return newPos;
}
case ItemPositionHasChanged:

View File

@ -50,8 +50,6 @@ public:
int type() const { return Type; }
void verticalMove(bool flag);
void calculateForces();
bool advance();
QRectF boundingRect() const;
QPainterPath shape() const;

View File

@ -67,12 +67,6 @@ MixerCurveWidget::MixerCurveWidget(QWidget *parent) : QGraphicsView(parent)
scene->setSceneRect(plot->boundingRect());
setScene(scene);
QList<double> list;
list << 0 << 0.3 << 0.6 << -0.4 << -0.8;
initCurve(list);
qDebug() << getCurve();
}
MixerCurveWidget::~MixerCurveWidget()

View File

@ -47,8 +47,14 @@ SystemSettings::SystemSettings(): UAVDataObject(OBJID, ISSINGLEINST, ISSETTINGS,
QStringList AirframeTypeEnumOptions;
AirframeTypeEnumOptions.append("FixedWing");
AirframeTypeEnumOptions.append("FixedWingElevon");
AirframeTypeEnumOptions.append("FixedWingVtail");
AirframeTypeEnumOptions.append("VTOL");
AirframeTypeEnumOptions.append("HeliCP");
AirframeTypeEnumOptions.append("QuadX");
AirframeTypeEnumOptions.append("QuadP");
AirframeTypeEnumOptions.append("Hexa");
AirframeTypeEnumOptions.append("Octo");
AirframeTypeEnumOptions.append("Custom");
fields.append( new UAVObjectField(QString("AirframeType"), QString(""), UAVObjectField::ENUM, AirframeTypeElemNames, AirframeTypeEnumOptions) );
// Initialize object

View File

@ -50,7 +50,7 @@ public:
// Field information
// Field AirframeType information
/* Enumeration options for field AirframeType */
typedef enum { AIRFRAMETYPE_FIXEDWING=0, AIRFRAMETYPE_FIXEDWINGELEVON=1, AIRFRAMETYPE_VTOL=2, AIRFRAMETYPE_HELICP=3 } AirframeTypeOptions;
typedef enum { AIRFRAMETYPE_FIXEDWING=0, AIRFRAMETYPE_FIXEDWINGELEVON=1, AIRFRAMETYPE_FIXEDWINGVTAIL=2, AIRFRAMETYPE_VTOL=3, AIRFRAMETYPE_HELICP=4, AIRFRAMETYPE_QUADX=5, AIRFRAMETYPE_QUADP=6, AIRFRAMETYPE_HEXA=7, AIRFRAMETYPE_OCTO=8, AIRFRAMETYPE_CUSTOM=9 } AirframeTypeOptions;
// Constants

View File

@ -47,8 +47,14 @@ _fields = [ \
{
'0' : 'FixedWing',
'1' : 'FixedWingElevon',
'2' : 'VTOL',
'3' : 'HeliCP',
'2' : 'FixedWingVtail',
'3' : 'VTOL',
'4' : 'HeliCP',
'5' : 'QuadX',
'6' : 'QuadP',
'7' : 'Hexa',
'8' : 'Octo',
'9' : 'Custom',
}
),
]

View File

@ -1,7 +1,7 @@
<xml>
<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>
<field name="AirframeType" units="" type="enum" elements="1" options="FixedWing,FixedWingElevon,VTOL, HeliCP" defaultvalue="FixedWing"/>
<field name="AirframeType" units="" type="enum" elements="1" options="FixedWing,FixedWingElevon,FixedWingVtail,VTOL,HeliCP,QuadX,QuadP,Hexa,Octo,Custom" defaultvalue="FixedWing"/>
<access gcs="readwrite" flight="readwrite"/>
<telemetrygcs acked="true" updatemode="onchange" period="0"/>
<telemetryflight acked="true" updatemode="onchange" period="0"/>