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

Merge remote-tracking branch 'origin/os/features/pid-tuning-from-transmitter-next' into next

This commit is contained in:
James Cotton 2012-03-05 00:18:17 -06:00
commit 11e7f58b63
17 changed files with 1159 additions and 74 deletions

View File

@ -48,10 +48,6 @@ ENABLE_DEBUG_PINS ?= NO
# Set to Yes to enable the AUX UART which is mapped on the S1 (Tx) and S2 (Rx) servo outputs
ENABLE_AUX_UART ?= NO
USE_GPS ?= YES
USE_I2C ?= YES
# Set to YES when using Code Sourcery toolchain
CODE_SOURCERY ?= YES
@ -64,16 +60,41 @@ endif
FLASH_TOOL = OPENOCD
# List of modules to include
OPTMODULES = CameraStab ComUsbBridge Altitude
# Optional module and driver defaults
USE_CAMERASTAB ?= YES
USE_COMUSBBRIDGE ?= YES
USE_GPS ?= YES
USE_TXPID ?= YES
USE_I2C ?= NO
USE_ALTITUDE ?= NO
TEST_FAULTS ?= NO
# List of optional modules to include
OPTMODULES =
ifeq ($(USE_CAMERASTAB), YES)
OPTMODULES += CameraStab
endif
ifeq ($(USE_COMUSBBRIDGE), YES)
OPTMODULES += ComUsbBridge
endif
ifeq ($(USE_GPS), YES)
OPTMODULES += GPS
endif
ifeq ($(USE_TXPID), YES)
OPTMODULES += TxPID
endif
ifeq ($(USE_ALTITUDE), YES)
ifeq ($(USE_I2C), YES)
OPTMODULES += Altitude
else
$(error "Altitude module (USE_ALTITUDE=YES) requires i2c (USE_I2C=YES)")
endif
endif
ifeq ($(TEST_FAULTS), YES)
OPTMODULES += Fault
endif
# List of mandatory modules to include
MODULES = Attitude Stabilization Actuator ManualControl FirmwareIAP
# Telemetry must be last to grab the optional modules (why?)
MODULES += Telemetry
@ -183,6 +204,7 @@ SRC += $(OPUAVSYNTHDIR)/taskinfo.c
SRC += $(OPUAVSYNTHDIR)/mixerstatus.c
SRC += $(OPUAVSYNTHDIR)/ratedesired.c
SRC += $(OPUAVSYNTHDIR)/baroaltitude.c
SRC += $(OPUAVSYNTHDIR)/txpidsettings.c
endif

View File

@ -0,0 +1,42 @@
/**
******************************************************************************
* @addtogroup OpenPilotModules OpenPilot Modules
* @{
* @addtogroup TxPIDModule TxPID Module
* @{
*
* @file txpid.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011.
* @brief Optional module to tune PID settings using R/C transmitter.
*
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* 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 TXPID_H
#define TXPID_H
#include "openpilot.h"
int32_t TxPIDInitialize(void);
#endif // TXPID_H
/**
* @}
* @}
*/

View File

@ -0,0 +1,336 @@
/**
******************************************************************************
* @addtogroup OpenPilotModules OpenPilot Modules
* @{
* @addtogroup TxPIDModule TxPID Module
* @brief Optional module to tune PID settings using R/C transmitter.
* Updates PID settings in RAM in real-time using configured Accessory channels as controllers.
* @{
*
* @file txpid.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011.
* @brief Optional module to tune PID settings using R/C transmitter.
*
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* 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
*/
/**
* Output object: StabilizationSettings
*
* This module will periodically update values of stabilization PID settings
* depending on configured input control channels. New values of stabilization
* settings are not saved to flash, but updated in RAM. It is expected that the
* module will be enabled only for tuning. When desired values are found, they
* can be read via GCS and saved permanently. Then this module should be
* disabled again.
*
* UAVObjects are automatically generated by the UAVObjectGenerator from
* the object definition XML file.
*
* Modules have no API, all communication to other modules is done through UAVObjects.
* However modules may use the API exposed by shared libraries.
* See the OpenPilot wiki for more details.
* http://wiki.openpilot.org/display/Doc/OpenPilot+Architecture
*
*/
#include "openpilot.h"
#include "txpidsettings.h"
#include "accessorydesired.h"
#include "manualcontrolcommand.h"
#include "stabilizationsettings.h"
#include "flightstatus.h"
#include "hwsettings.h"
//
// Configuration
//
#define SAMPLE_PERIOD_MS 200
#define TELEMETRY_UPDATE_PERIOD_MS 0 // 0 = update on change (default)
// Sanity checks
#if (TXPIDSETTINGS_PIDS_NUMELEM != TXPIDSETTINGS_INPUTS_NUMELEM) || \
(TXPIDSETTINGS_PIDS_NUMELEM != TXPIDSETTINGS_MINPID_NUMELEM) || \
(TXPIDSETTINGS_PIDS_NUMELEM != TXPIDSETTINGS_MAXPID_NUMELEM)
#error Invalid TxPID UAVObject definition (inconsistent number of field elements)
#endif
// Private types
// Private variables
// Private functions
static void updatePIDs(UAVObjEvent* ev);
static uint8_t update(float *var, float val);
static float scale(float val, float inMin, float inMax, float outMin, float outMax);
/**
* Initialise the module, called on startup
* \returns 0 on success or -1 if initialisation failed
*/
int32_t TxPIDInitialize(void)
{
bool txPIDEnabled;
uint8_t optionalModules[HWSETTINGS_OPTIONALMODULES_NUMELEM];
HwSettingsInitialize();
HwSettingsOptionalModulesGet(optionalModules);
if (optionalModules[HWSETTINGS_OPTIONALMODULES_TXPID] == HWSETTINGS_OPTIONALMODULES_ENABLED)
txPIDEnabled = true;
else
txPIDEnabled = false;
if (txPIDEnabled) {
TxPIDSettingsInitialize();
AccessoryDesiredInitialize();
UAVObjEvent ev = {
.obj = AccessoryDesiredHandle(),
.instId = 0,
.event = 0,
};
EventPeriodicCallbackCreate(&ev, updatePIDs, SAMPLE_PERIOD_MS / portTICK_RATE_MS);
#if (TELEMETRY_UPDATE_PERIOD_MS != 0)
// Change StabilizationSettings update rate from OnChange to periodic
// to prevent telemetry link flooding with frequent updates in case of
// control channel jitter.
// Warning: saving to flash with this code active will change the
// StabilizationSettings update rate permanently. Use Metadata via
// browser to reset to defaults (telemetryAcked=true, OnChange).
UAVObjMetadata metadata;
StabilizationSettingsInitialize();
StabilizationSettingsGetMetadata(&metadata);
metadata.telemetryAcked = 0;
metadata.telemetryUpdateMode = UPDATEMODE_PERIODIC;
metadata.telemetryUpdatePeriod = TELEMETRY_UPDATE_PERIOD_MS;
StabilizationSettingsSetMetadata(&metadata);
#endif
return 0;
}
return -1;
}
/* stub: module has no module thread */
int32_t TxPIDStart(void)
{
return 0;
}
MODULE_INITCALL(TxPIDInitialize, TxPIDStart)
/**
* Update PIDs callback function
*/
static void updatePIDs(UAVObjEvent* ev)
{
if (ev->obj != AccessoryDesiredHandle())
return;
TxPIDSettingsData inst;
TxPIDSettingsGet(&inst);
if (inst.UpdateMode == TXPIDSETTINGS_UPDATEMODE_NEVER)
return;
uint8_t armed;
FlightStatusArmedGet(&armed);
if ((inst.UpdateMode == TXPIDSETTINGS_UPDATEMODE_WHENARMED) &&
(armed == FLIGHTSTATUS_ARMED_DISARMED))
return;
StabilizationSettingsData stab;
StabilizationSettingsGet(&stab);
AccessoryDesiredData accessory;
uint8_t needsUpdate = 0;
// Loop through every enabled instance
for (uint8_t i = 0; i < TXPIDSETTINGS_PIDS_NUMELEM; i++) {
if (inst.PIDs[i] != TXPIDSETTINGS_PIDS_DISABLED) {
float value;
if (inst.Inputs[i] == TXPIDSETTINGS_INPUTS_THROTTLE) {
ManualControlCommandThrottleGet(&value);
value = scale(value,
inst.ThrottleRange[TXPIDSETTINGS_THROTTLERANGE_MIN],
inst.ThrottleRange[TXPIDSETTINGS_THROTTLERANGE_MAX],
inst.MinPID[i], inst.MaxPID[i]);
} else if (AccessoryDesiredInstGet(inst.Inputs[i] - TXPIDSETTINGS_INPUTS_ACCESSORY0, &accessory) == 0) {
value = scale(accessory.AccessoryVal, -1.0, 1.0, inst.MinPID[i], inst.MaxPID[i]);
} else {
continue;
}
switch (inst.PIDs[i]) {
case TXPIDSETTINGS_PIDS_ROLLRATEKP:
needsUpdate |= update(&stab.RollRatePID[STABILIZATIONSETTINGS_ROLLRATEPID_KP], value);
break;
case TXPIDSETTINGS_PIDS_ROLLRATEKI:
needsUpdate |= update(&stab.RollRatePID[STABILIZATIONSETTINGS_ROLLRATEPID_KI], value);
break;
case TXPIDSETTINGS_PIDS_ROLLRATEKD:
needsUpdate |= update(&stab.RollRatePID[STABILIZATIONSETTINGS_ROLLRATEPID_KD], value);
break;
case TXPIDSETTINGS_PIDS_ROLLRATEILIMIT:
needsUpdate |= update(&stab.RollRatePID[STABILIZATIONSETTINGS_ROLLRATEPID_ILIMIT], value);
break;
case TXPIDSETTINGS_PIDS_ROLLATTITUDEKP:
needsUpdate |= update(&stab.RollPI[STABILIZATIONSETTINGS_ROLLPI_KP], value);
break;
case TXPIDSETTINGS_PIDS_ROLLATTITUDEKI:
needsUpdate |= update(&stab.RollPI[STABILIZATIONSETTINGS_ROLLPI_KI], value);
break;
case TXPIDSETTINGS_PIDS_ROLLATTITUDEILIMIT:
needsUpdate |= update(&stab.RollPI[STABILIZATIONSETTINGS_ROLLPI_ILIMIT], value);
break;
case TXPIDSETTINGS_PIDS_PITCHRATEKP:
needsUpdate |= update(&stab.PitchRatePID[STABILIZATIONSETTINGS_PITCHRATEPID_KP], value);
break;
case TXPIDSETTINGS_PIDS_PITCHRATEKI:
needsUpdate |= update(&stab.PitchRatePID[STABILIZATIONSETTINGS_PITCHRATEPID_KI], value);
break;
case TXPIDSETTINGS_PIDS_PITCHRATEKD:
needsUpdate |= update(&stab.PitchRatePID[STABILIZATIONSETTINGS_PITCHRATEPID_KD], value);
break;
case TXPIDSETTINGS_PIDS_PITCHRATEILIMIT:
needsUpdate |= update(&stab.PitchRatePID[STABILIZATIONSETTINGS_PITCHRATEPID_ILIMIT], value);
break;
case TXPIDSETTINGS_PIDS_PITCHATTITUDEKP:
needsUpdate |= update(&stab.PitchPI[STABILIZATIONSETTINGS_PITCHPI_KP], value);
break;
case TXPIDSETTINGS_PIDS_PITCHATTITUDEKI:
needsUpdate |= update(&stab.PitchPI[STABILIZATIONSETTINGS_PITCHPI_KI], value);
break;
case TXPIDSETTINGS_PIDS_PITCHATTITUDEILIMIT:
needsUpdate |= update(&stab.PitchPI[STABILIZATIONSETTINGS_PITCHPI_ILIMIT], value);
break;
case TXPIDSETTINGS_PIDS_ROLLPITCHRATEKP:
needsUpdate |= update(&stab.RollRatePID[STABILIZATIONSETTINGS_ROLLRATEPID_KP], value);
needsUpdate |= update(&stab.PitchRatePID[STABILIZATIONSETTINGS_PITCHRATEPID_KP], value);
break;
case TXPIDSETTINGS_PIDS_ROLLPITCHRATEKI:
needsUpdate |= update(&stab.RollRatePID[STABILIZATIONSETTINGS_ROLLRATEPID_KI], value);
needsUpdate |= update(&stab.PitchRatePID[STABILIZATIONSETTINGS_PITCHRATEPID_KI], value);
break;
case TXPIDSETTINGS_PIDS_ROLLPITCHRATEKD:
needsUpdate |= update(&stab.RollRatePID[STABILIZATIONSETTINGS_ROLLRATEPID_KD], value);
needsUpdate |= update(&stab.PitchRatePID[STABILIZATIONSETTINGS_PITCHRATEPID_KD], value);
break;
case TXPIDSETTINGS_PIDS_ROLLPITCHRATEILIMIT:
needsUpdate |= update(&stab.RollRatePID[STABILIZATIONSETTINGS_ROLLRATEPID_ILIMIT], value);
needsUpdate |= update(&stab.PitchRatePID[STABILIZATIONSETTINGS_PITCHRATEPID_ILIMIT], value);
break;
case TXPIDSETTINGS_PIDS_ROLLPITCHATTITUDEKP:
needsUpdate |= update(&stab.RollPI[STABILIZATIONSETTINGS_ROLLPI_KP], value);
needsUpdate |= update(&stab.PitchPI[STABILIZATIONSETTINGS_PITCHPI_KP], value);
break;
case TXPIDSETTINGS_PIDS_ROLLPITCHATTITUDEKI:
needsUpdate |= update(&stab.RollPI[STABILIZATIONSETTINGS_ROLLPI_KI], value);
needsUpdate |= update(&stab.PitchPI[STABILIZATIONSETTINGS_PITCHPI_KI], value);
break;
case TXPIDSETTINGS_PIDS_ROLLPITCHATTITUDEILIMIT:
needsUpdate |= update(&stab.RollPI[STABILIZATIONSETTINGS_ROLLPI_ILIMIT], value);
needsUpdate |= update(&stab.PitchPI[STABILIZATIONSETTINGS_PITCHPI_ILIMIT], value);
break;
case TXPIDSETTINGS_PIDS_YAWRATEKP:
needsUpdate |= update(&stab.YawRatePID[STABILIZATIONSETTINGS_YAWRATEPID_KP], value);
break;
case TXPIDSETTINGS_PIDS_YAWRATEKI:
needsUpdate |= update(&stab.YawRatePID[STABILIZATIONSETTINGS_YAWRATEPID_KI], value);
break;
case TXPIDSETTINGS_PIDS_YAWRATEKD:
needsUpdate |= update(&stab.YawRatePID[STABILIZATIONSETTINGS_YAWRATEPID_KD], value);
break;
case TXPIDSETTINGS_PIDS_YAWRATEILIMIT:
needsUpdate |= update(&stab.YawRatePID[STABILIZATIONSETTINGS_YAWRATEPID_ILIMIT], value);
break;
case TXPIDSETTINGS_PIDS_YAWATTITUDEKP:
needsUpdate |= update(&stab.YawPI[STABILIZATIONSETTINGS_YAWPI_KP], value);
break;
case TXPIDSETTINGS_PIDS_YAWATTITUDEKI:
needsUpdate |= update(&stab.YawPI[STABILIZATIONSETTINGS_YAWPI_KI], value);
break;
case TXPIDSETTINGS_PIDS_YAWATTITUDEILIMIT:
needsUpdate |= update(&stab.YawPI[STABILIZATIONSETTINGS_YAWPI_ILIMIT], value);
break;
default:
PIOS_Assert(0);
}
}
}
if (needsUpdate)
StabilizationSettingsSet(&stab);
}
/**
* Scales input val from [inMin..inMax] range to [outMin..outMax].
* If val is out of input range (inMin <= inMax), it will be bound.
* (outMin > outMax) is ok, in that case output will be decreasing.
*
* \returns scaled value
*/
static float scale(float val, float inMin, float inMax, float outMin, float outMax)
{
// bound input value
if (val > inMax) val = inMax;
if (val < inMin) val = inMin;
// normalize input value to [0..1]
if (inMax <= inMin)
val = 0.0;
else
val = (val - inMin) / (inMax - inMin);
// update output bounds
if (outMin > outMax) {
float t = outMin;
outMin = outMax;
outMax = t;
val = 1.0 - val;
}
return (outMax - outMin) * val + outMin;
}
/**
* Updates var using val if needed.
* \returns 1 if updated, 0 otherwise
*/
static uint8_t update(float *var, float val)
{
if (*var != val) {
*var = val;
return 1;
}
return 0;
}
/**
* @}
*/
/**
* @}
*/

View File

@ -302,6 +302,13 @@ void SavedAction::connectWidget(QWidget *widget, ApplyMode applyMode)
this, SLOT(spinBoxValueChanged(int)));
connect(spinBox, SIGNAL(valueChanged(QString)),
this, SLOT(spinBoxValueChanged(QString)));
} else if (QDoubleSpinBox *doubleSpinBox = qobject_cast<QDoubleSpinBox *>(widget)) {
doubleSpinBox->setValue(m_value.toDouble());
//qDebug() << "SETTING VALUE" << doubleSpinBox->value();
connect(doubleSpinBox, SIGNAL(valueChanged(double)),
this, SLOT(doubleSpinBoxValueChanged(double)));
connect(doubleSpinBox, SIGNAL(valueChanged(QString)),
this, SLOT(doubleSpinBoxValueChanged(QString)));
} else if (QLineEdit *lineEdit = qobject_cast<QLineEdit *>(widget)) {
lineEdit->setText(m_value.toString());
//qDebug() << "SETTING TEXT" << lineEdit->text();
@ -336,6 +343,8 @@ void SavedAction::apply(QSettings *s)
setValue(lineEdit->text());
else if (QSpinBox *spinBox = qobject_cast<QSpinBox *>(m_widget))
setValue(spinBox->value());
else if (QDoubleSpinBox *doubleSpinBox = qobject_cast<QDoubleSpinBox *>(m_widget))
setValue(doubleSpinBox->value());
else if (PathChooser *pathChooser = qobject_cast<PathChooser *>(m_widget))
setValue(pathChooser->path());
if (s)
@ -383,6 +392,22 @@ void SavedAction::spinBoxValueChanged(QString value)
setValue(value);
}
void SavedAction::doubleSpinBoxValueChanged(double value)
{
QDoubleSpinBox *doubleSpinBox = qobject_cast<QDoubleSpinBox *>(sender());
QTC_ASSERT(doubleSpinBox, return);
if (m_applyMode == ImmediateApply)
setValue(value);
}
void SavedAction::doubleSpinBoxValueChanged(QString value)
{
QDoubleSpinBox *doubleSpinBox = qobject_cast<QDoubleSpinBox *>(sender());
QTC_ASSERT(doubleSpinBox, return);
if (m_applyMode == ImmediateApply)
setValue(value);
}
void SavedAction::pathChooserEditingFinished()
{
PathChooser *pathChooser = qobject_cast<PathChooser *>(sender());

View File

@ -92,6 +92,8 @@ private:
Q_SLOT void actionTriggered(bool);
Q_SLOT void spinBoxValueChanged(int);
Q_SLOT void spinBoxValueChanged(QString);
Q_SLOT void doubleSpinBoxValueChanged(double);
Q_SLOT void doubleSpinBoxValueChanged(QString);
QVariant m_value;
QVariant m_defaultValue;

View File

@ -27,6 +27,7 @@ HEADERS += configplugin.h \
defaulthwsettingswidget.h \
inputchannelform.h \
configcamerastabilizationwidget.h \
configtxpidwidget.h \
outputchannelform.h \
config_global.h
SOURCES += configplugin.cpp \
@ -53,6 +54,7 @@ SOURCES += configplugin.cpp \
defaulthwsettingswidget.cpp \
inputchannelform.cpp \
configcamerastabilizationwidget.cpp \
configtxpidwidget.cpp \
outputchannelform.cpp
FORMS += airframe.ui \
cc_hw_settings.ui \
@ -67,5 +69,6 @@ FORMS += airframe.ui \
defaulthwsettings.ui \
inputchannelform.ui \
camerastabilization.ui \
outputchannelform.ui
outputchannelform.ui \
txpid.ui
RESOURCES += configgadget.qrc

View File

@ -16,7 +16,8 @@
<file>images/hw_config.png</file>
<file>images/gyroscope.png</file>
<file>images/TX.svg</file>
<file>images/camera.png</file>
<file>images/TX2.svg</file>
<file>images/camera.png</file>
<file>images/txpid.png</file>
</qresource>
</RCC>

View File

@ -34,6 +34,7 @@
#include "configoutputwidget.h"
#include "configstabilizationwidget.h"
#include "configcamerastabilizationwidget.h"
#include "configtxpidwidget.h"
#include "config_pro_hw_widget.h"
#include "config_cc_hw_widget.h"
#include "defaultattitudewidget.h"
@ -85,6 +86,8 @@ ConfigGadgetWidget::ConfigGadgetWidget(QWidget *parent) : QWidget(parent)
qwd = new ConfigCameraStabilizationWidget(this);
ftw->insertTab(ConfigGadgetWidget::camerastabilization, qwd, QIcon(":/configgadget/images/camera.png"), QString("Camera Stab"));
qwd = new ConfigTxPIDWidget(this);
ftw->insertTab(ConfigGadgetWidget::txpid, qwd, QIcon(":/configgadget/images/txpid.png"), QString("TxPID"));
// qwd = new ConfigPipXtremeWidget(this);
// ftw->insertTab(5, qwd, QIcon(":/configgadget/images/PipXtreme.png"), QString("PipXtreme"));

View File

@ -50,7 +50,7 @@ class ConfigGadgetWidget: public QWidget
public:
ConfigGadgetWidget(QWidget *parent = 0);
~ConfigGadgetWidget();
enum widgetTabs {hardware=0, aircraft, input, output, ins, stabilization, camerastabilization};
enum widgetTabs { hardware = 0, aircraft, input, output, ins, stabilization, camerastabilization, txpid };
public slots:
void onAutopilotConnect();

View File

@ -0,0 +1,105 @@
/**
******************************************************************************
*
* @file configtxpidswidget.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
* @{
* @brief The Configuration Gadget used to configure TxPID module
*****************************************************************************/
/*
* 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 "configtxpidwidget.h"
#include "txpidsettings.h"
#include "hwsettings.h"
ConfigTxPIDWidget::ConfigTxPIDWidget(QWidget *parent) : ConfigTaskWidget(parent)
{
m_txpid = new Ui_TxPIDWidget();
m_txpid->setupUi(this);
addApplySaveButtons(m_txpid->Apply, m_txpid->Save);
// Cannot use addUAVObjectToWidgetRelation() for OptionaModules enum because
// QCheckBox returns bool (0 or -1) and this value is then set to enum instead
// or enum options
connect(HwSettings::GetInstance(getObjectManager()), SIGNAL(objectUpdated(UAVObject *)), this, SLOT(refreshValues()));
connect(m_txpid->Apply, SIGNAL(clicked()), this, SLOT(applySettings()));
connect(m_txpid->Save, SIGNAL(clicked()), this, SLOT(saveSettings()));
addUAVObjectToWidgetRelation("TxPIDSettings", "PIDs", m_txpid->PID1, TxPIDSettings::PIDS_INSTANCE1);
addUAVObjectToWidgetRelation("TxPIDSettings", "PIDs", m_txpid->PID2, TxPIDSettings::PIDS_INSTANCE2);
addUAVObjectToWidgetRelation("TxPIDSettings", "PIDs", m_txpid->PID3, TxPIDSettings::PIDS_INSTANCE3);
addUAVObjectToWidgetRelation("TxPIDSettings", "Inputs", m_txpid->Input1, TxPIDSettings::INPUTS_INSTANCE1);
addUAVObjectToWidgetRelation("TxPIDSettings", "Inputs", m_txpid->Input2, TxPIDSettings::INPUTS_INSTANCE2);
addUAVObjectToWidgetRelation("TxPIDSettings", "Inputs", m_txpid->Input3, TxPIDSettings::INPUTS_INSTANCE3);
addUAVObjectToWidgetRelation("TxPIDSettings", "MinPID", m_txpid->MinPID1, TxPIDSettings::MINPID_INSTANCE1);
addUAVObjectToWidgetRelation("TxPIDSettings", "MinPID", m_txpid->MinPID2, TxPIDSettings::MINPID_INSTANCE2);
addUAVObjectToWidgetRelation("TxPIDSettings", "MinPID", m_txpid->MinPID3, TxPIDSettings::MINPID_INSTANCE3);
addUAVObjectToWidgetRelation("TxPIDSettings", "MaxPID", m_txpid->MaxPID1, TxPIDSettings::MAXPID_INSTANCE1);
addUAVObjectToWidgetRelation("TxPIDSettings", "MaxPID", m_txpid->MaxPID2, TxPIDSettings::MAXPID_INSTANCE2);
addUAVObjectToWidgetRelation("TxPIDSettings", "MaxPID", m_txpid->MaxPID3, TxPIDSettings::MAXPID_INSTANCE3);
addUAVObjectToWidgetRelation("TxPIDSettings", "ThrottleRange", m_txpid->ThrottleMin, TxPIDSettings::THROTTLERANGE_MIN);
addUAVObjectToWidgetRelation("TxPIDSettings", "ThrottleRange", m_txpid->ThrottleMax, TxPIDSettings::THROTTLERANGE_MAX);
addUAVObjectToWidgetRelation("TxPIDSettings", "UpdateMode", m_txpid->UpdateMode);
enableControls(false);
populateWidgets();
refreshWidgetsValues();
}
ConfigTxPIDWidget::~ConfigTxPIDWidget()
{
// Do nothing
}
void ConfigTxPIDWidget::refreshValues()
{
HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
HwSettings::DataFields hwSettingsData = hwSettings->getData();
m_txpid->TxPIDEnable->setChecked(
hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_TXPID] == HwSettings::OPTIONALMODULES_ENABLED);
}
void ConfigTxPIDWidget::applySettings()
{
HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
HwSettings::DataFields hwSettingsData = hwSettings->getData();
hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_TXPID] =
m_txpid->TxPIDEnable->isChecked() ? HwSettings::OPTIONALMODULES_ENABLED : HwSettings::OPTIONALMODULES_DISABLED;
hwSettings->setData(hwSettingsData);
}
void ConfigTxPIDWidget::saveSettings()
{
applySettings();
UAVObject *obj = HwSettings::GetInstance(getObjectManager());
saveObjectToSD(obj);
}
/**
@}
@}
*/

View File

@ -0,0 +1,50 @@
/**
******************************************************************************
*
* @file configtxpidwidget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
* @{
* @brief The Configuration Gadget used to configure TxPID module
*****************************************************************************/
/*
* 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 CONFIGTXPIDWIDGET_H
#define CONFIGTXPIDWIDGET_H
#include "ui_txpid.h"
#include "configtaskwidget.h"
class ConfigTxPIDWidget : public ConfigTaskWidget
{
Q_OBJECT
public:
ConfigTxPIDWidget(QWidget *parent = 0);
~ConfigTxPIDWidget();
private:
Ui_TxPIDWidget *m_txpid;
private slots:
void refreshValues();
void applySettings();
void saveSettings();
};
#endif // CONFIGTXPIDWIDGET_H

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

View File

@ -0,0 +1,512 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TxPIDWidget</class>
<widget class="QWidget" name="TxPIDWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>720</width>
<height>567</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_2">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>702</width>
<height>497</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QCheckBox" name="TxPIDEnable">
<property name="toolTip">
<string>This module will periodically update values of stabilization PID settings
depending on configured input control channels. New values of stabilization
settings are not saved to flash, but updated in RAM. It is expected that the
module will be enabled only for tuning. When desired values are found, they
can be read via GCS and saved permanently. Then this module should be
disabled again.
Up to 3 separate PID options (or option pairs) can be selected and updated.</string>
</property>
<property name="text">
<string>Enable TxPID module</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>After enabling the module, you must power cycle before using and configuring.</string>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>10</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QGroupBox" name="groupBox_6">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>100</height>
</size>
</property>
<property name="title">
<string>Module Settings</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<widget class="QLabel" name="label_51">
<property name="text">
<string>PID option</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_50">
<property name="text">
<string>Control Source</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="label_49">
<property name="text">
<string>Min</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QLabel" name="label">
<property name="text">
<string>Max</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_47">
<property name="text">
<string>Instance 1</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="PID1">
<property name="toolTip">
<string>Select PID option or option pair to update.
Set to Disabled if not used.</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QComboBox" name="Input1">
<property name="toolTip">
<string>Select input used as a control source for this instance.
It can be one of Accessory channels or Throttle channel.
If Accessory channel is chosen then its range [0..1] will be mapped
to PID range [Min..Max] defined for this instance.
If Throttle channel is chosen then Throttle range [Min..Max] will
be mapped to PID range [Min..Max] defined for this instance. If
Throttle is out of bounds then PID Min and Max values will be used
accordingly.
Note that it is possible to set PID Min &gt; Max. In that case increasing
control input value will decrease the PID option value. This can be
used, for instance, to decrease PID value when increasing Throttle.</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QDoubleSpinBox" name="MinPID1">
<property name="toolTip">
<string>Minimum PID value mapped to Accessory channel = 0 or
Throttle channel lesser or equal to Throttle Min value.</string>
</property>
<property name="decimals">
<number>6</number>
</property>
<property name="singleStep">
<double>0.000100000000000</double>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QDoubleSpinBox" name="MaxPID1">
<property name="toolTip">
<string>Maximum PID value mapped to Accessory channel = 1 or
Throttle channel greater or equal to Throttle Max value.</string>
</property>
<property name="decimals">
<number>6</number>
</property>
<property name="singleStep">
<double>0.000100000000000</double>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_48">
<property name="text">
<string>Instance 2</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="PID2">
<property name="toolTip">
<string>Select PID option or option pair to update.
Set to Disabled if not used.</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QComboBox" name="Input2">
<property name="toolTip">
<string>Select input used as a control source for this instance.
It can be one of Accessory channels or Throttle channel.
If Accessory channel is chosen then its range [0..1] will be mapped
to PID range [Min..Max] defined for this instance.
If Throttle channel is chosen then Throttle range [Min..Max] will
be mapped to PID range [Min..Max] defined for this instance. If
Throttle is out of bounds then PID Min and Max values will be used
accordingly.
Note that it is possible to set PID Min &gt; Max. In that case increasing
control input value will decrease the PID option value. This can be
used, for instance, to decrease PID value when increasing Throttle.</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QDoubleSpinBox" name="MinPID2">
<property name="toolTip">
<string>Minimum PID value mapped to Accessory channel = 0 or
Throttle channel lesser or equal to Throttle Min value.</string>
</property>
<property name="decimals">
<number>6</number>
</property>
<property name="singleStep">
<double>0.000100000000000</double>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="QDoubleSpinBox" name="MaxPID2">
<property name="toolTip">
<string>Maximum PID value mapped to Accessory channel = 1 or
Throttle channel greater or equal to Throttle Max value.</string>
</property>
<property name="decimals">
<number>6</number>
</property>
<property name="singleStep">
<double>0.000100000000000</double>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_52">
<property name="text">
<string>Instance 3</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="PID3">
<property name="toolTip">
<string>Select PID option or option pair to update.
Set to Disabled if not used.</string>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QComboBox" name="Input3">
<property name="toolTip">
<string>Select input used as a control source for this instance.
It can be one of Accessory channels or Throttle channel.
If Accessory channel is chosen then its range [0..1] will be mapped
to PID range [Min..Max] defined for this instance.
If Throttle channel is chosen then Throttle range [Min..Max] will
be mapped to PID range [Min..Max] defined for this instance. If
Throttle is out of bounds then PID Min and Max values will be used
accordingly.
Note that it is possible to set PID Min &gt; Max. In that case increasing
control input value will decrease the PID option value. This can be
used, for instance, to decrease PID value when increasing Throttle.</string>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QDoubleSpinBox" name="MinPID3">
<property name="toolTip">
<string>Minimum PID value mapped to Accessory channel = 0 or
Throttle channel lesser or equal to Throttle Min value.</string>
</property>
<property name="decimals">
<number>6</number>
</property>
<property name="singleStep">
<double>0.000100000000000</double>
</property>
</widget>
</item>
<item row="3" column="4">
<widget class="QDoubleSpinBox" name="MaxPID3">
<property name="toolTip">
<string>Maximum PID value mapped to Accessory channel = 1 or
Throttle channel greater or equal to Throttle Max value.</string>
</property>
<property name="decimals">
<number>6</number>
</property>
<property name="singleStep">
<double>0.000100000000000</double>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Update Mode</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QComboBox" name="UpdateMode">
<property name="toolTip">
<string>PID values update mode which can be set to:
- Never: this disables PID updates (but module still will be run if enabled),
- When Armed: PID updated only when system is armed,
- Always: PID updated always regardless of arm state.
Since the GCS updates GUI PID values in real time on change, could be
tricky to change other PID values from the GUI if the module is enabled
and constantly updates stabilization settings object. As a workaround,
this option can be used to temporarily disable updates or enable them
only when system is armed without disabling the module.</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Throttle Range</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QDoubleSpinBox" name="ThrottleMin">
<property name="toolTip">
<string>Throttle channel lower bound mapped to PID Min value</string>
</property>
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QDoubleSpinBox" name="ThrottleMax">
<property name="toolTip">
<string>Throttle channel upper bound mapped to PID Max value</string>
</property>
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Min</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Max</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="4" column="0">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<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>
</widget>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="message">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="submitButtons">
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<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>
<widget class="QPushButton" name="Apply">
<property name="toolTip">
<string>Send settings to the board but do not save to the non-volatile memory</string>
</property>
<property name="text">
<string>Apply</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="Save">
<property name="toolTip">
<string>Send settings to the board and save to the non-volatile memory</string>
</property>
<property name="text">
<string>Save</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<tabstops>
<tabstop>TxPIDEnable</tabstop>
<tabstop>Apply</tabstop>
<tabstop>Save</tabstop>
<tabstop>scrollArea</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@ -2650,53 +2650,6 @@
<version>UAVGadgetManagerV1</version>
</Mode2>
<Mode3>
<showToolbars>false</showToolbars>
<splitter>
<side0>
<classId>OPMapGadget</classId>
<gadget>
<activeConfiguration>default</activeConfiguration>
</gadget>
<type>uavGadget</type>
</side0>
<side1>
<side0>
<classId>ModelViewGadget</classId>
<gadget>
<activeConfiguration>Test Quad X</activeConfiguration>
</gadget>
<type>uavGadget</type>
</side0>
<side1>
<side0>
<classId>DialGadget</classId>
<gadget>
<activeConfiguration>Attitude</activeConfiguration>
</gadget>
<type>uavGadget</type>
</side0>
<side1>
<classId>DialGadget</classId>
<gadget>
<activeConfiguration>Compass</activeConfiguration>
</gadget>
<type>uavGadget</type>
</side1>
<splitterOrientation>1</splitterOrientation>
<splitterSizes>@Variant(AAAACQAAAAA=)</splitterSizes>
<type>splitter</type>
</side1>
<splitterOrientation>2</splitterOrientation>
<splitterSizes>@Variant(AAAACQAAAAIAAAACAAABiwAAAAIAAADs)</splitterSizes>
<type>splitter</type>
</side1>
<splitterOrientation>1</splitterOrientation>
<splitterSizes>@Variant(AAAACQAAAAIAAAACAAAD1AAAAAIAAAGB)</splitterSizes>
<type>splitter</type>
</splitter>
<version>UAVGadgetManagerV1</version>
</Mode3>
<Mode4>
<showToolbars>false</showToolbars>
<splitter>
<side0>
@ -2751,8 +2704,8 @@
<type>splitter</type>
</splitter>
<version>UAVGadgetManagerV1</version>
</Mode4>
<Mode5>
</Mode3>
<Mode4>
<showToolbars>false</showToolbars>
<splitter>
<side0>
@ -2822,8 +2775,8 @@
<type>splitter</type>
</splitter>
<version>UAVGadgetManagerV1</version>
</Mode5>
<Mode6>
</Mode4>
<Mode5>
<showToolbars>false</showToolbars>
<splitter>
<side0>
@ -2869,30 +2822,30 @@
<type>splitter</type>
</splitter>
<version>UAVGadgetManagerV1</version>
</Mode6>
</Mode5>
</UAVGadgetManager>
<ViewGroup_Default>@ByteArray(AAAA/wAAAAD9AAAAAAAABQAAAALCAAAABAAAAAQAAAABAAAACPwAAAAA)</ViewGroup_Default>
<Workspace>
<Icon1>:/core/images/ah.png</Icon1>
<Icon10>:/core/images/openpilot_logo_64.png</Icon10>
<Icon2>:/core/images/config.png</Icon2>
<Icon3>:/core/images/world.png</Icon3>
<Icon4>:/core/images/scopes.png</Icon4>
<Icon5>:/core/images/joystick.png</Icon5>
<Icon6>:/core/images/cog.png</Icon6>
<Icon3>:/core/images/scopes.png</Icon3>
<Icon4>:/core/images/joystick.png</Icon4>
<Icon5>:/core/images/cog.png</Icon5>
<Icon6>:/core/images/openpilot_logo_64.png</Icon6>
<Icon7>:/core/images/openpilot_logo_64.png</Icon7>
<Icon8>:/core/images/openpilot_logo_64.png</Icon8>
<Icon9>:/core/images/openpilot_logo_64.png</Icon9>
<NumberOfWorkspaces>6</NumberOfWorkspaces>
<Icon10>:/core/images/openpilot_logo_64.png</Icon10>
<NumberOfWorkspaces>5</NumberOfWorkspaces>
<Workspace1>Flight data</Workspace1>
<Workspace10>Workspace10</Workspace10>
<Workspace2>Configuration</Workspace2>
<Workspace3>Flight Planner</Workspace3>
<Workspace4>Scopes</Workspace4>
<Workspace5>HITL</Workspace5>
<Workspace6>Firmware</Workspace6>
<Workspace3>Scopes</Workspace3>
<Workspace4>HITL</Workspace4>
<Workspace5>Firmware</Workspace5>
<Workspace6>Workspace6</Workspace6>
<Workspace7>Workspace7</Workspace7>
<Workspace8>Workspace8</Workspace8>
<Workspace9>Workspace9</Workspace9>
<Workspace10>Workspace10</Workspace10>
</Workspace>
</gcs>

View File

@ -72,6 +72,7 @@ HEADERS += $$UAVOBJECT_SYNTHETICS/accessorydesired.h \
$$UAVOBJECT_SYNTHETICS/gcsreceiver.h \
$$UAVOBJECT_SYNTHETICS/receiveractivity.h \
$$UAVOBJECT_SYNTHETICS/attitudesettings.h \
$$UAVOBJECT_SYNTHETICS/txpidsettings.h \
$$UAVOBJECT_SYNTHETICS/cameradesired.h \
$$UAVOBJECT_SYNTHETICS/faultsettings.h
@ -125,5 +126,6 @@ SOURCES += $$UAVOBJECT_SYNTHETICS/accessorydesired.cpp \
$$UAVOBJECT_SYNTHETICS/gcsreceiver.cpp \
$$UAVOBJECT_SYNTHETICS/receiveractivity.cpp \
$$UAVOBJECT_SYNTHETICS/attitudesettings.cpp \
$$UAVOBJECT_SYNTHETICS/txpidsettings.cpp \
$$UAVOBJECT_SYNTHETICS/cameradesired.cpp \
$$UAVOBJECT_SYNTHETICS/faultsettings.cpp

View File

@ -16,7 +16,7 @@
<field name="USB_HIDPort" units="function" type="enum" elements="1" options="USBTelemetry,Disabled" defaultvalue="USBTelemetry"/>
<field name="USB_VCPPort" units="function" type="enum" elements="1" options="USBTelemetry,ComBridge,Disabled" defaultvalue="Disabled"/>
<field name="OptionalModules" units="" type="enum" elementnames="CameraStab,GPS,ComUsbBridge,Fault,Altitude" options="Disabled,Enabled" defaultvalue="Disabled"/>
<field name="OptionalModules" units="" type="enum" elementnames="CameraStab,GPS,ComUsbBridge,Fault,Altitude,TxPID" options="Disabled,Enabled" defaultvalue="Disabled"/>
<field name="DSMxBind" units="" type="uint8" elements="1" defaultvalue="0"/>
<access gcs="readwrite" flight="readwrite"/>

View File

@ -0,0 +1,29 @@
<xml>
<object name="TxPIDSettings" singleinstance="true" settings="true">
<description>Settings used by @ref TxPID optional module to tune PID settings using R/C transmitter</description>
<field name="UpdateMode" units="option" type="enum" elements="1" options="Never,When Armed,Always" defaultvalue="When Armed"/>
<field name="Inputs" units="channel" type="enum"
elementnames="Instance1,Instance2,Instance3"
options="Throttle,Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5"
defaultvalue="Throttle,Accessory0,Accessory1"/>
<field name="ThrottleRange" units="%" type="float" elements="2" elementnames="Min,Max" defaultvalue="0.20,0.80"/>
<field name="PIDs" units="option" type="enum"
elementnames="Instance1,Instance2,Instance3"
options="Disabled,
Roll Rate.Kp, Pitch Rate.Kp, Roll+Pitch Rate.Kp, Yaw Rate.Kp,
Roll Rate.Ki, Pitch Rate.Ki, Roll+Pitch Rate.Ki, Yaw Rate.Ki,
Roll Rate.Kd, Pitch Rate.Kd, Roll+Pitch Rate.Kd, Yaw Rate.Kd,
Roll Rate.ILimit, Pitch Rate.ILimit, Roll+Pitch Rate.ILimit, Yaw Rate.ILimit,
Roll Attitude.Kp, Pitch Attitude.Kp, Roll+Pitch Attitude.Kp, Yaw Attitude.Kp,
Roll Attitude.Ki, Pitch Attitude.Ki, Roll+Pitch Attitude.Ki, Yaw Attitude.Ki,
Roll Attitude.ILimit, Pitch Attitude.ILimit, Roll+Pitch Attitude.ILimit, Yaw Attitude.ILimit"
defaultvalue="Disabled"/>
<field name="MinPID" units="" type="float" elementnames="Instance1,Instance2,Instance3" defaultvalue="0"/>
<field name="MaxPID" units="" type="float" elementnames="Instance1,Instance2,Instance3" defaultvalue="0"/>
<access gcs="readwrite" flight="readwrite"/>
<telemetrygcs acked="true" updatemode="onchange" period="0"/>
<telemetryflight acked="true" updatemode="onchange" period="0"/>
<logging updatemode="never" period="0"/>
</object>
</xml>