1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-29 14:52:12 +01:00

Flight: Added ability to use additional TX inputs to tune attitude bias. Note this form of the calibration is temporary and will likely be replaced by a rotation matrix to deal with more general rotations.

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@1525 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
peabody124 2010-09-04 17:07:59 +00:00 committed by peabody124
parent aa909cf7dd
commit 45e8131a30
21 changed files with 170 additions and 11 deletions

View File

@ -176,6 +176,7 @@ SRC += $(OPUAVOBJ)/navigationdesired.c
SRC += $(OPUAVOBJ)/flightbatterystate.c
SRC += $(OPUAVOBJ)/attituderaw.c
SRC += $(OPUAVOBJ)/homelocation.c
SRC += $(OPUAVOBJ)/attitudesettings.c
endif
## PIOS Hardware (STM32F10x)

View File

@ -159,6 +159,7 @@ SRC += $(OPUAVOBJ)/ahrscalibration.c
SRC += $(OPUAVOBJ)/ahrssettings.c
SRC += $(OPUAVOBJ)/gpstime.c
SRC += $(OPUAVOBJ)/gpssatellites.c
SRC += $(OPUAVOBJ)/attitudesettings.c
endif
## PIOS Hardware (posix)

View File

@ -159,6 +159,7 @@ SRC += $(OPUAVOBJ)/ahrscalibration.c
SRC += $(OPUAVOBJ)/ahrssettings.c
SRC += $(OPUAVOBJ)/gpstime.c
SRC += $(OPUAVOBJ)/gpssatellites.c
SRC += $(OPUAVOBJ)/attitudesettings.c
endif
## PIOS Hardware (win32)

View File

@ -54,6 +54,7 @@
#include "attitudeactual.h"
#include "ahrssettings.h"
#include "attituderaw.h"
#include "attitudesettings.h"
#include "ahrsstatus.h"
#include "alarms.h"
#include "baroaltitude.h"
@ -446,6 +447,8 @@ static void load_gps_position(struct opahrs_msg_v1_req_update * update)
static void process_update(struct opahrs_msg_v1_rsp_update * update)
{
AttitudeActualData data;
AttitudeSettingsData attitudeSettings;
AttitudeSettingsGet(&attitudeSettings);
data.q1 = update->quaternion.q1;
data.q2 = update->quaternion.q2;
@ -455,8 +458,8 @@ static void process_update(struct opahrs_msg_v1_rsp_update * update)
float q[4] = {data.q1, data.q2, data.q3, data.q4};
float rpy[3];
Quaternion2RPY(q,rpy);
data.Roll = rpy[0];
data.Pitch = rpy[1];
data.Roll = rpy[0] - attitudeSettings.RollBias;
data.Pitch = rpy[1] - attitudeSettings.PitchBias;
data.Yaw = rpy[2];
if(data.Yaw < 0) data.Yaw += 360;

View File

@ -40,6 +40,7 @@
#include "manualcontrolcommand.h"
#include "actuatordesired.h"
#include "attitudedesired.h"
#include "attitudesettings.h"
// Private constants
@ -139,6 +140,19 @@ static void manualControlTask(void* parameters)
// Calculate throttle command in range +1 to -1
cmd.Throttle = scaleChannel( cmd.Channel[settings.Throttle], settings.ChannelMax[settings.Throttle],
settings.ChannelMin[settings.Throttle], settings.ChannelNeutral[settings.Throttle] );
if(settings.Accessory1 != MANUALCONTROLSETTINGS_ACCESSORY1_NONE)
cmd.Accessory1 = scaleChannel( cmd.Channel[settings.Accessory1], settings.ChannelMax[settings.Accessory1],
settings.ChannelMin[settings.Accessory1], settings.ChannelNeutral[settings.Accessory1] );
else
cmd.Accessory1 = 0;
if(settings.Accessory2 != MANUALCONTROLSETTINGS_ACCESSORY2_NONE)
cmd.Accessory2 = scaleChannel( cmd.Channel[settings.Accessory2], settings.ChannelMax[settings.Accessory2],
settings.ChannelMin[settings.Accessory2], settings.ChannelNeutral[settings.Accessory2] );
else
cmd.Accessory2 = 0;
// Update flight mode
flightMode = scaleChannel( cmd.Channel[settings.FlightMode], settings.ChannelMax[settings.FlightMode],
@ -208,6 +222,15 @@ static void manualControlTask(void* parameters)
attitude.Throttle = cmd.Throttle*stabSettings.ThrottleMax;
AttitudeDesiredSet(&attitude);
}
if( 1 ) { //TODO: Make what happens here depend on GCS
AttitudeSettingsData attitudeSettings;
AttitudeSettingsGet(&attitudeSettings);
// Hard coding a maximum bias of 30 for now... maybe mistake
attitudeSettings.PitchBias = cmd.Accessory1 * 30;
attitudeSettings.RollBias = cmd.Accessory2 * 30;
AttitudeSettingsSet(&attitudeSettings);
}
}
}

View File

@ -41,7 +41,7 @@
#define MANUALCONTROLCOMMAND_H
// Object constants
#define MANUALCONTROLCOMMAND_OBJID 990495372U
#define MANUALCONTROLCOMMAND_OBJID 540381354U
#define MANUALCONTROLCOMMAND_NAME "ManualControlCommand"
#define MANUALCONTROLCOMMAND_METANAME "ManualControlCommandMeta"
#define MANUALCONTROLCOMMAND_ISSINGLEINST 1
@ -77,6 +77,8 @@ typedef struct {
float Yaw;
float Throttle;
uint8_t FlightMode;
float Accessory1;
float Accessory2;
int16_t Channel[8];
} __attribute__((packed)) ManualControlCommandData;
@ -92,6 +94,8 @@ typedef enum { MANUALCONTROLCOMMAND_CONNECTED_FALSE=0, MANUALCONTROLCOMMAND_CONN
// Field FlightMode information
/* Enumeration options for field FlightMode */
typedef enum { MANUALCONTROLCOMMAND_FLIGHTMODE_MANUAL=0, MANUALCONTROLCOMMAND_FLIGHTMODE_STABILIZED=1, MANUALCONTROLCOMMAND_FLIGHTMODE_AUTO=2 } ManualControlCommandFlightModeOptions;
// Field Accessory1 information
// Field Accessory2 information
// Field Channel information
/* Number of elements for field Channel */
#define MANUALCONTROLCOMMAND_CHANNEL_NUMELEM 8

View File

@ -41,7 +41,7 @@
#define MANUALCONTROLSETTINGS_H
// Object constants
#define MANUALCONTROLSETTINGS_OBJID 2933673028U
#define MANUALCONTROLSETTINGS_OBJID 2185031164U
#define MANUALCONTROLSETTINGS_NAME "ManualControlSettings"
#define MANUALCONTROLSETTINGS_METANAME "ManualControlSettingsMeta"
#define MANUALCONTROLSETTINGS_ISSINGLEINST 1
@ -77,6 +77,8 @@ typedef struct {
uint8_t Yaw;
uint8_t Throttle;
uint8_t FlightMode;
uint8_t Accessory1;
uint8_t Accessory2;
int16_t ChannelMax[8];
int16_t ChannelNeutral[8];
int16_t ChannelMin[8];
@ -102,6 +104,12 @@ typedef enum { MANUALCONTROLSETTINGS_THROTTLE_CHANNEL0=0, MANUALCONTROLSETTINGS_
// Field FlightMode information
/* Enumeration options for field FlightMode */
typedef enum { MANUALCONTROLSETTINGS_FLIGHTMODE_CHANNEL0=0, MANUALCONTROLSETTINGS_FLIGHTMODE_CHANNEL1=1, MANUALCONTROLSETTINGS_FLIGHTMODE_CHANNEL2=2, MANUALCONTROLSETTINGS_FLIGHTMODE_CHANNEL3=3, MANUALCONTROLSETTINGS_FLIGHTMODE_CHANNEL4=4, MANUALCONTROLSETTINGS_FLIGHTMODE_CHANNEL5=5, MANUALCONTROLSETTINGS_FLIGHTMODE_CHANNEL6=6, MANUALCONTROLSETTINGS_FLIGHTMODE_CHANNEL7=7, MANUALCONTROLSETTINGS_FLIGHTMODE_NONE=8 } ManualControlSettingsFlightModeOptions;
// Field Accessory1 information
/* Enumeration options for field Accessory1 */
typedef enum { MANUALCONTROLSETTINGS_ACCESSORY1_CHANNEL0=0, MANUALCONTROLSETTINGS_ACCESSORY1_CHANNEL1=1, MANUALCONTROLSETTINGS_ACCESSORY1_CHANNEL2=2, MANUALCONTROLSETTINGS_ACCESSORY1_CHANNEL3=3, MANUALCONTROLSETTINGS_ACCESSORY1_CHANNEL4=4, MANUALCONTROLSETTINGS_ACCESSORY1_CHANNEL5=5, MANUALCONTROLSETTINGS_ACCESSORY1_CHANNEL6=6, MANUALCONTROLSETTINGS_ACCESSORY1_CHANNEL7=7, MANUALCONTROLSETTINGS_ACCESSORY1_NONE=8 } ManualControlSettingsAccessory1Options;
// Field Accessory2 information
/* Enumeration options for field Accessory2 */
typedef enum { MANUALCONTROLSETTINGS_ACCESSORY2_CHANNEL0=0, MANUALCONTROLSETTINGS_ACCESSORY2_CHANNEL1=1, MANUALCONTROLSETTINGS_ACCESSORY2_CHANNEL2=2, MANUALCONTROLSETTINGS_ACCESSORY2_CHANNEL3=3, MANUALCONTROLSETTINGS_ACCESSORY2_CHANNEL4=4, MANUALCONTROLSETTINGS_ACCESSORY2_CHANNEL5=5, MANUALCONTROLSETTINGS_ACCESSORY2_CHANNEL6=6, MANUALCONTROLSETTINGS_ACCESSORY2_CHANNEL7=7, MANUALCONTROLSETTINGS_ACCESSORY2_NONE=8 } ManualControlSettingsAccessory2Options;
// Field ChannelMax information
/* Number of elements for field ChannelMax */
#define MANUALCONTROLSETTINGS_CHANNELMAX_NUMELEM 8

View File

@ -86,6 +86,8 @@ static void setDefaults(UAVObjHandle obj, uint16_t instId)
data.Yaw = 2;
data.Throttle = 3;
data.FlightMode = 4;
data.Accessory1 = 8;
data.Accessory2 = 8;
data.ChannelMax[0] = 2000;
data.ChannelMax[1] = 2000;
data.ChannelMax[2] = 2000;

View File

@ -37,6 +37,7 @@
#include "attitudeactual.h"
#include "attitudedesired.h"
#include "attituderaw.h"
#include "attitudesettings.h"
#include "baroaltitude.h"
#include "exampleobject1.h"
#include "exampleobject2.h"
@ -77,6 +78,7 @@ void UAVObjectsInitializeAll()
AttitudeActualInitialize();
AttitudeDesiredInitialize();
AttitudeRawInitialize();
AttitudeSettingsInitialize();
BaroAltitudeInitialize();
ExampleObject1Initialize();
ExampleObject2Initialize();

View File

@ -43,6 +43,7 @@
657CEEC2121DC054007A1FBE /* navigationdesired.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = navigationdesired.c; sourceTree = "<group>"; };
657CEEC3121DC054007A1FBE /* navigationsettings.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = navigationsettings.c; sourceTree = "<group>"; };
657CF024121F49CD007A1FBE /* WMMInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMMInternal.h; sourceTree = "<group>"; };
657D267F1231F612002BBF95 /* attitudesettings.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = attitudesettings.xml; sourceTree = "<group>"; };
659ED317122226B60011010E /* ahrssettings.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = ahrssettings.xml; sourceTree = "<group>"; };
65B35D7F121C261E003EAD18 /* bin.pro */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = bin.pro; sourceTree = "<group>"; };
65B35D80121C261E003EAD18 /* openpilotgcs */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = openpilotgcs; sourceTree = "<group>"; };
@ -6705,6 +6706,7 @@
65B367E9121C2620003EAD18 /* attitudeactual.xml */,
65B367EA121C2620003EAD18 /* attitudedesired.xml */,
65B367EB121C2620003EAD18 /* attituderaw.xml */,
657D267F1231F612002BBF95 /* attitudesettings.xml */,
65209A1812208B0600453371 /* baroaltitude.xml */,
65B367ED121C2620003EAD18 /* exampleobject1.xml */,
65B367EE121C2620003EAD18 /* exampleobject2.xml */,

View File

@ -67,6 +67,12 @@ ManualControlCommand::ManualControlCommand(): UAVDataObject(OBJID, ISSINGLEINST,
FlightModeEnumOptions.append("Stabilized");
FlightModeEnumOptions.append("Auto");
fields.append( new UAVObjectField(QString("FlightMode"), QString(""), UAVObjectField::ENUM, FlightModeElemNames, FlightModeEnumOptions) );
QStringList Accessory1ElemNames;
Accessory1ElemNames.append("0");
fields.append( new UAVObjectField(QString("Accessory1"), QString("%"), UAVObjectField::FLOAT32, Accessory1ElemNames, QStringList()) );
QStringList Accessory2ElemNames;
Accessory2ElemNames.append("0");
fields.append( new UAVObjectField(QString("Accessory2"), QString("%"), UAVObjectField::FLOAT32, Accessory2ElemNames, QStringList()) );
QStringList ChannelElemNames;
ChannelElemNames.append("0");
ChannelElemNames.append("1");

View File

@ -49,6 +49,8 @@ public:
float Yaw;
float Throttle;
quint8 FlightMode;
float Accessory1;
float Accessory2;
qint16 Channel[8];
} __attribute__((packed)) DataFields;
@ -64,13 +66,15 @@ public:
// Field FlightMode information
/* Enumeration options for field FlightMode */
typedef enum { FLIGHTMODE_MANUAL=0, FLIGHTMODE_STABILIZED=1, FLIGHTMODE_AUTO=2 } FlightModeOptions;
// Field Accessory1 information
// Field Accessory2 information
// Field Channel information
/* Number of elements for field Channel */
static const quint32 CHANNEL_NUMELEM = 8;
// Constants
static const quint32 OBJID = 990495372U;
static const quint32 OBJID = 540381354U;
static const QString NAME;
static const bool ISSINGLEINST = 1;
static const bool ISSETTINGS = 0;

View File

@ -102,6 +102,26 @@ _fields = [ \
'2' : 'Auto',
}
),
uavobject.UAVObjectField(
'Accessory1',
'f',
1,
[
'0',
],
{
}
),
uavobject.UAVObjectField(
'Accessory2',
'f',
1,
[
'0',
],
{
}
),
uavobject.UAVObjectField(
'Channel',
'h',
@ -124,7 +144,7 @@ _fields = [ \
class ManualControlCommand(uavobject.UAVObject):
## Object constants
OBJID = 990495372
OBJID = 540381354
NAME = "ManualControlCommand"
METANAME = "ManualControlCommandMeta"
ISSINGLEINST = 1

View File

@ -114,6 +114,32 @@ ManualControlSettings::ManualControlSettings(): UAVDataObject(OBJID, ISSINGLEINS
FlightModeEnumOptions.append("Channel7");
FlightModeEnumOptions.append("None");
fields.append( new UAVObjectField(QString("FlightMode"), QString("channel"), UAVObjectField::ENUM, FlightModeElemNames, FlightModeEnumOptions) );
QStringList Accessory1ElemNames;
Accessory1ElemNames.append("0");
QStringList Accessory1EnumOptions;
Accessory1EnumOptions.append("Channel0");
Accessory1EnumOptions.append("Channel1");
Accessory1EnumOptions.append("Channel2");
Accessory1EnumOptions.append("Channel3");
Accessory1EnumOptions.append("Channel4");
Accessory1EnumOptions.append("Channel5");
Accessory1EnumOptions.append("Channel6");
Accessory1EnumOptions.append("Channel7");
Accessory1EnumOptions.append("None");
fields.append( new UAVObjectField(QString("Accessory1"), QString("channel"), UAVObjectField::ENUM, Accessory1ElemNames, Accessory1EnumOptions) );
QStringList Accessory2ElemNames;
Accessory2ElemNames.append("0");
QStringList Accessory2EnumOptions;
Accessory2EnumOptions.append("Channel0");
Accessory2EnumOptions.append("Channel1");
Accessory2EnumOptions.append("Channel2");
Accessory2EnumOptions.append("Channel3");
Accessory2EnumOptions.append("Channel4");
Accessory2EnumOptions.append("Channel5");
Accessory2EnumOptions.append("Channel6");
Accessory2EnumOptions.append("Channel7");
Accessory2EnumOptions.append("None");
fields.append( new UAVObjectField(QString("Accessory2"), QString("channel"), UAVObjectField::ENUM, Accessory2ElemNames, Accessory2EnumOptions) );
QStringList ChannelMaxElemNames;
ChannelMaxElemNames.append("0");
ChannelMaxElemNames.append("1");
@ -183,6 +209,8 @@ void ManualControlSettings::setDefaultFieldValues()
data.Yaw = 2;
data.Throttle = 3;
data.FlightMode = 4;
data.Accessory1 = 8;
data.Accessory2 = 8;
data.ChannelMax[0] = 2000;
data.ChannelMax[1] = 2000;
data.ChannelMax[2] = 2000;

View File

@ -49,6 +49,8 @@ public:
quint8 Yaw;
quint8 Throttle;
quint8 FlightMode;
quint8 Accessory1;
quint8 Accessory2;
qint16 ChannelMax[8];
qint16 ChannelNeutral[8];
qint16 ChannelMin[8];
@ -74,6 +76,12 @@ public:
// Field FlightMode information
/* Enumeration options for field FlightMode */
typedef enum { FLIGHTMODE_CHANNEL0=0, FLIGHTMODE_CHANNEL1=1, FLIGHTMODE_CHANNEL2=2, FLIGHTMODE_CHANNEL3=3, FLIGHTMODE_CHANNEL4=4, FLIGHTMODE_CHANNEL5=5, FLIGHTMODE_CHANNEL6=6, FLIGHTMODE_CHANNEL7=7, FLIGHTMODE_NONE=8 } FlightModeOptions;
// Field Accessory1 information
/* Enumeration options for field Accessory1 */
typedef enum { ACCESSORY1_CHANNEL0=0, ACCESSORY1_CHANNEL1=1, ACCESSORY1_CHANNEL2=2, ACCESSORY1_CHANNEL3=3, ACCESSORY1_CHANNEL4=4, ACCESSORY1_CHANNEL5=5, ACCESSORY1_CHANNEL6=6, ACCESSORY1_CHANNEL7=7, ACCESSORY1_NONE=8 } Accessory1Options;
// Field Accessory2 information
/* Enumeration options for field Accessory2 */
typedef enum { ACCESSORY2_CHANNEL0=0, ACCESSORY2_CHANNEL1=1, ACCESSORY2_CHANNEL2=2, ACCESSORY2_CHANNEL3=3, ACCESSORY2_CHANNEL4=4, ACCESSORY2_CHANNEL5=5, ACCESSORY2_CHANNEL6=6, ACCESSORY2_CHANNEL7=7, ACCESSORY2_NONE=8 } Accessory2Options;
// Field ChannelMax information
/* Number of elements for field ChannelMax */
static const quint32 CHANNELMAX_NUMELEM = 8;
@ -86,7 +94,7 @@ public:
// Constants
static const quint32 OBJID = 2933673028U;
static const quint32 OBJID = 2185031164U;
static const QString NAME;
static const bool ISSINGLEINST = 1;
static const bool ISSETTINGS = 1;

View File

@ -145,6 +145,44 @@ _fields = [ \
'8' : 'None',
}
),
uavobject.UAVObjectField(
'Accessory1',
'b',
1,
[
'0',
],
{
'0' : 'Channel0',
'1' : 'Channel1',
'2' : 'Channel2',
'3' : 'Channel3',
'4' : 'Channel4',
'5' : 'Channel5',
'6' : 'Channel6',
'7' : 'Channel7',
'8' : 'None',
}
),
uavobject.UAVObjectField(
'Accessory2',
'b',
1,
[
'0',
],
{
'0' : 'Channel0',
'1' : 'Channel1',
'2' : 'Channel2',
'3' : 'Channel3',
'4' : 'Channel4',
'5' : 'Channel5',
'6' : 'Channel6',
'7' : 'Channel7',
'8' : 'None',
}
),
uavobject.UAVObjectField(
'ChannelMax',
'h',
@ -201,7 +239,7 @@ _fields = [ \
class ManualControlSettings(uavobject.UAVObject):
## Object constants
OBJID = 2933673028
OBJID = 2185031164
NAME = "ManualControlSettings"
METANAME = "ManualControlSettingsMeta"
ISSINGLEINST = 1

View File

@ -47,7 +47,7 @@ NavigationSettings::NavigationSettings(): UAVDataObject(OBJID, ISSINGLEINST, ISS
fields.append( new UAVObjectField(QString("UpdatePeriod"), QString("ms"), UAVObjectField::UINT16, UpdatePeriodElemNames, QStringList()) );
QStringList AccelerationMaxElemNames;
AccelerationMaxElemNames.append("0");
fields.append( new UAVObjectField(QString("AccelerationMax"), QString("m/s²"), UAVObjectField::FLOAT32, AccelerationMaxElemNames, QStringList()) );
fields.append( new UAVObjectField(QString("AccelerationMax"), QString("m/s"), UAVObjectField::FLOAT32, AccelerationMaxElemNames, QStringList()) );
QStringList SpeedMaxElemNames;
SpeedMaxElemNames.append("0");
fields.append( new UAVObjectField(QString("SpeedMax"), QString("m/s"), UAVObjectField::FLOAT32, SpeedMaxElemNames, QStringList()) );

View File

@ -42,7 +42,8 @@ HEADERS += uavobjects_global.h \
gpssatellites.h \
positionactual.h \
flightbatterystate.h \
homelocation.h
homelocation.h \
attitudesettings.h
SOURCES += uavobject.cpp \
uavmetaobject.cpp \
uavobjectmanager.cpp \
@ -81,5 +82,6 @@ SOURCES += uavobject.cpp \
gpssatellites.cpp \
positionactual.cpp \
flightbatterystate.cpp \
homelocation.cpp
homelocation.cpp \
attitudesettings.cpp
OTHER_FILES += UAVObjects.pluginspec

View File

@ -39,6 +39,7 @@
#include "attitudeactual.h"
#include "attitudedesired.h"
#include "attituderaw.h"
#include "attitudesettings.h"
#include "baroaltitude.h"
#include "exampleobject1.h"
#include "exampleobject2.h"
@ -79,6 +80,7 @@ void UAVObjectsInitialize(UAVObjectManager* objMngr)
objMngr->registerObject( new AttitudeActual() );
objMngr->registerObject( new AttitudeDesired() );
objMngr->registerObject( new AttitudeRaw() );
objMngr->registerObject( new AttitudeSettings() );
objMngr->registerObject( new BaroAltitude() );
objMngr->registerObject( new ExampleObject1() );
objMngr->registerObject( new ExampleObject2() );

View File

@ -7,6 +7,8 @@
<field name="Yaw" units="%" type="float" elements="1"/>
<field name="Throttle" units="%" type="float" elements="1"/>
<field name="FlightMode" units="" type="enum" elements="1" options="Manual,Stabilized,Auto"/>
<field name="Accessory1" units="%" type="float" elements="1"/>
<field name="Accessory2" units="%" type="float" elements="1"/>
<field name="Channel" units="us" type="int16" elements="8"/>
<access gcs="readwrite" flight="readwrite"/>
<telemetrygcs acked="false" updatemode="manual" period="0"/>

View File

@ -7,6 +7,8 @@
<field name="Yaw" units="channel" type="enum" elements="1" options="Channel0,Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,None" defaultvalue="Channel2"/>
<field name="Throttle" units="channel" type="enum" elements="1" options="Channel0,Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,None" defaultvalue="Channel3"/>
<field name="FlightMode" units="channel" type="enum" elements="1" options="Channel0,Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,None" defaultvalue="Channel4"/>
<field name="Accessory1" units="channel" type="enum" elements="1" options="Channel0,Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,None" defaultvalue="None"/>
<field name="Accessory2" units="channel" type="enum" elements="1" options="Channel0,Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,None" defaultvalue="None"/>
<field name="ChannelMax" units="us" type="int16" elements="8" defaultvalue="2000"/>
<field name="ChannelNeutral" units="us" type="int16" elements="8" defaultvalue="1500"/>
<field name="ChannelMin" units="us" type="int16" elements="8" defaultvalue="1000"/>