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

[OP-724] Add camera gimbal filtering and feed forward options

This is a partial rework of Cossacs' camera gimbal software.

This patch adds LPF to airframe attitude used for camera stabilisation
and feed forward for camera actuators. Either of options can be
disabled on the compilation level to save flash and RAM if not
required.

Original Cossacs' code was optimized and code flow shortcuts were
added where applicable.
This commit is contained in:
Oleg Semyonov 2012-11-17 16:18:37 +02:00
parent ee333f1569
commit 8f5fb5aeb0
4 changed files with 498 additions and 141 deletions

View File

@ -79,6 +79,8 @@ TEST_FAULTS ?= NO
# Camera gimbal options
USE_INPUT_LPF ?= YES
USE_GIMBAL_LPF ?= YES
USE_GIMBAL_FF ?= YES
# List of optional modules to include
OPTMODULES =
@ -466,6 +468,14 @@ ifeq ($(USE_INPUT_LPF), YES)
CDEFS += -DUSE_INPUT_LPF
endif
ifeq ($(USE_GIMBAL_LPF), YES)
CDEFS += -DUSE_GIMBAL_LPF
endif
ifeq ($(USE_GIMBAL_FF), YES)
CDEFS += -DUSE_GIMBAL_FF
endif
# Declare all non-optional modules as built-in to force inclusion
CDEFS += ${foreach MOD, ${MODULES}, -DMODULE_$(MOD)_BUILTIN }

View File

@ -57,6 +57,7 @@
// Configuration
//
#define SAMPLE_PERIOD_MS 10
#define BOOT_DELAY 7000
// Private types
@ -64,13 +65,28 @@
static struct CameraStab_data {
portTickType lastSysTime;
float inputs[CAMERASTABSETTINGS_INPUT_NUMELEM];
float inputs_filtered[CAMERASTABSETTINGS_INPUT_NUMELEM];
#ifdef USE_GIMBAL_LPF
float attitudeFiltered[CAMERASTABSETTINGS_INPUT_NUMELEM];
#endif
#ifdef USE_GIMBAL_FF
float ffLastAttitude[CAMERASTABSETTINGS_INPUT_NUMELEM];
float ffLastAttitudeFiltered[CAMERASTABSETTINGS_INPUT_NUMELEM];
float ffFilterAccumulator[CAMERASTABSETTINGS_INPUT_NUMELEM];
#endif
} *csd;
// Private functions
static void attitudeUpdated(UAVObjEvent* ev);
static float bound(float val, float limit);
#ifdef USE_GIMBAL_FF
static void applyFeedForward(uint8_t index, float dT, float *attitude, CameraStabSettingsData *cameraStab);
#endif
/**
* Initialise the module, called on startup
* \returns 0 on success or -1 if initialisation failed
@ -100,7 +116,7 @@ int32_t CameraStabInitialize(void)
if (!csd)
return -1;
// make sure that all inputs[] and inputs_filtered[] are zeroed
// initialize camera state variables
memset(csd, 0, sizeof(struct CameraStab_data));
csd->lastSysTime = xTaskGetTickCount();
@ -139,15 +155,17 @@ static void attitudeUpdated(UAVObjEvent* ev)
CameraStabSettingsData cameraStab;
CameraStabSettingsGet(&cameraStab);
// Check how long since last update, time delta between calls in ms
// check how long since last update, time delta between calls in ms
portTickType thisSysTime = xTaskGetTickCount();
float dT = (thisSysTime > csd->lastSysTime) ?
(thisSysTime - csd->lastSysTime) / portTICK_RATE_MS :
(float)SAMPLE_PERIOD_MS / 1000.0f;
(float)((thisSysTime - csd->lastSysTime) * portTICK_RATE_MS) :
(float)SAMPLE_PERIOD_MS;
csd->lastSysTime = thisSysTime;
// Read any input channels and apply LPF
// process axes
for (uint8_t i = 0; i < CAMERASTABSETTINGS_INPUT_NUMELEM; i++) {
// read and process control input
if (cameraStab.Input[i] != CAMERASTABSETTINGS_INPUT_NONE) {
if (AccessoryDesiredInstGet(cameraStab.Input[i] - CAMERASTABSETTINGS_INPUT_ACCESSORY0, &accessory) == 0) {
float input_rate;
@ -158,38 +176,62 @@ static void attitudeUpdated(UAVObjEvent* ev)
case CAMERASTABSETTINGS_STABILIZATIONMODE_AXISLOCK:
input_rate = accessory.AccessoryVal * cameraStab.InputRate[i];
if (fabs(input_rate) > cameraStab.MaxAxisLockRate)
csd->inputs[i] = bound(csd->inputs[i] + input_rate * dT / 1000.0f, cameraStab.InputRange[i]);
csd->inputs[i] = bound(csd->inputs[i] + input_rate * 0.001f * dT, cameraStab.InputRange[i]);
break;
default:
PIOS_Assert(0);
}
}
}
// bypass LPF calculation if ResponseTime is zero
float rt = (float)cameraStab.ResponseTime[i];
if (rt)
csd->inputs_filtered[i] = (rt / (rt + dT)) * csd->inputs_filtered[i]
+ (dT / (rt + dT)) * csd->inputs[i];
else
csd->inputs_filtered[i] = csd->inputs[i];
// calculate servo output
float attitude;
switch (i) {
case CAMERASTABSETTINGS_INPUT_ROLL:
AttitudeActualRollGet(&attitude);
break;
case CAMERASTABSETTINGS_INPUT_PITCH:
AttitudeActualPitchGet(&attitude);
break;
case CAMERASTABSETTINGS_INPUT_YAW:
AttitudeActualYawGet(&attitude);
break;
default:
PIOS_Assert(0);
}
#ifdef USE_GIMBAL_LPF
if (cameraStab.ResponseTime) {
float rt = (float)cameraStab.ResponseTime;
attitude = csd->attitudeFiltered[i] = ((rt * csd->attitudeFiltered[i]) + (dT * attitude)) / (rt + dT);
}
#endif
#ifdef USE_GIMBAL_FF
if (cameraStab.FeedForward[i])
applyFeedForward(i, dT, &attitude, &cameraStab);
#endif
// set output channels (but wait BOOT_DELAY after board reset)
float output = bound((attitude + csd->inputs[i]) / cameraStab.OutputRange[i], 1.0f);
if (thisSysTime > (portTICK_RATE_MS * BOOT_DELAY )) {
switch (i) {
case CAMERASTABSETTINGS_INPUT_ROLL:
CameraDesiredRollSet(&output);
break;
case CAMERASTABSETTINGS_INPUT_PITCH:
CameraDesiredPitchSet(&output);
break;
case CAMERASTABSETTINGS_INPUT_YAW:
CameraDesiredYawSet(&output);
break;
default:
PIOS_Assert(0);
}
}
}
// Set output channels
float attitude;
float output;
AttitudeActualRollGet(&attitude);
output = bound((attitude + csd->inputs_filtered[CAMERASTABSETTINGS_INPUT_ROLL]) / cameraStab.OutputRange[CAMERASTABSETTINGS_OUTPUTRANGE_ROLL], 1.0f);
CameraDesiredRollSet(&output);
AttitudeActualPitchGet(&attitude);
output = bound((attitude + csd->inputs_filtered[CAMERASTABSETTINGS_INPUT_PITCH]) / cameraStab.OutputRange[CAMERASTABSETTINGS_OUTPUTRANGE_PITCH], 1.0f);
CameraDesiredPitchSet(&output);
AttitudeActualYawGet(&attitude);
output = bound((attitude + csd->inputs_filtered[CAMERASTABSETTINGS_INPUT_YAW]) / cameraStab.OutputRange[CAMERASTABSETTINGS_OUTPUTRANGE_YAW], 1.0f);
CameraDesiredYawSet(&output);
}
float bound(float val, float limit)
@ -198,6 +240,59 @@ float bound(float val, float limit)
(val < -limit) ? -limit :
val;
}
#ifdef USE_GIMBAL_FF
void applyFeedForward(uint8_t index, float dT, float *attitude, CameraStabSettingsData *cameraStab)
{
// compensate high feed forward values depending on gimbal type
float gimbalTypeCorrection = 1.0f;
switch (cameraStab->GimbalType) {
case CAMERASTABSETTINGS_GIMBALTYPE_YAWROLLPITCH:
if (index == CAMERASTABSETTINGS_INPUT_ROLL) {
float pitch;
AttitudeActualPitchGet(&pitch);
gimbalTypeCorrection = (cameraStab->OutputRange[CAMERASTABSETTINGS_OUTPUTRANGE_PITCH] - fabs(pitch))
/ cameraStab->OutputRange[CAMERASTABSETTINGS_OUTPUTRANGE_PITCH];
}
break;
case CAMERASTABSETTINGS_GIMBALTYPE_YAWPITCHROLL:
if (index == CAMERASTABSETTINGS_INPUT_PITCH) {
float roll;
AttitudeActualRollGet(&roll);
gimbalTypeCorrection = (cameraStab->OutputRange[CAMERASTABSETTINGS_OUTPUTRANGE_ROLL] - fabs(roll))
/ cameraStab->OutputRange[CAMERASTABSETTINGS_OUTPUTRANGE_ROLL];
}
break;
default:
PIOS_Assert(0);
}
// apply feed forward
float accumulator = csd->ffFilterAccumulator[index];
accumulator += (*attitude - csd->ffLastAttitude[index]) * (float)cameraStab->FeedForward[index] * gimbalTypeCorrection;
csd->ffLastAttitude[index] = *attitude;
*attitude += accumulator;
float filter = (float)((accumulator > 0.0f) ? cameraStab->AccelTime : cameraStab->DecelTime) / dT;
if (filter < 1.0f)
filter = 1.0f;
accumulator -= accumulator / filter;
csd->ffFilterAccumulator[index] = accumulator;
*attitude += accumulator;
// apply acceleration limit
float delta = *attitude - csd->ffLastAttitudeFiltered[index];
float maxDelta = (float)cameraStab->MaxAccel * 0.001f * dT;
if (fabs(delta) > maxDelta) {
// we are accelerating too hard
*attitude = csd->ffLastAttitudeFiltered[index] + ((delta > 0.0f) ? maxDelta : -maxDelta);
}
csd->ffLastAttitudeFiltered[index] = *attitude;
}
#endif // USE_GIMBAL_FF
/**
* @}
*/

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>786</width>
<height>566</height>
<height>745</height>
</rect>
</property>
<property name="sizePolicy">
@ -64,8 +64,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>741</width>
<height>559</height>
<width>745</width>
<height>687</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
@ -130,7 +130,7 @@
<property name="minimumSize">
<size>
<width>0</width>
<height>130</height>
<height>110</height>
</size>
</property>
<property name="maximumSize">
@ -285,7 +285,7 @@ have to define channel output range using Output configuration tab.</string>
<item row="2" column="0">
<widget class="QLabel" name="label_43">
<property name="text">
<string>Output Range</string>
<string>Output Range (Angle)</string>
</property>
</widget>
</item>
@ -390,7 +390,7 @@ margin:1px;</string>
<property name="minimumSize">
<size>
<width>0</width>
<height>250</height>
<height>187</height>
</size>
</property>
<property name="maximumSize">
@ -403,9 +403,6 @@ margin:1px;</string>
<string>Advanced Settings (Control)</string>
</property>
<layout class="QGridLayout" name="gridLayout_8">
<property name="verticalSpacing">
<number>6</number>
</property>
<item row="0" column="3">
<widget class="QLabel" name="label_32">
<property name="minimumSize">
@ -653,34 +650,6 @@ AxisLock: camera remembers tracking attitude. Input controls the rate of deflect
</property>
</widget>
</item>
<item row="5" column="3">
<widget class="QSpinBox" name="yawResponseTime">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>Input low-pass filter response time for yaw axis, ms.
This option smoothes the stick input. Zero value disables LPF.</string>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>150</number>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:ResponseTime</string>
<string>element:Yaw</string>
<string>haslimits:no</string>
<string>scale:1</string>
<string>buttongroup:1</string>
</stringlist>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QComboBox" name="pitchStabilizationMode">
<property name="focusPolicy">
@ -759,34 +728,6 @@ AxisLock: camera remembers tracking attitude. Input controls the rate of deflect
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QSpinBox" name="pitchResponseTime">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>Input low-pass filter response time for pitch axis, ms.
This option smoothes the stick input. Zero value disables LPF.</string>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>150</number>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:ResponseTime</string>
<string>element:Pitch</string>
<string>haslimits:no</string>
<string>scale:1</string>
<string>buttongroup:1</string>
</stringlist>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="rollStabilizationMode">
<property name="focusPolicy">
@ -865,59 +806,24 @@ AxisLock: camera remembers tracking attitude. Input controls the rate of deflect
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="rollResponseTime">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>Input low-pass filter response time for roll axis, ms.
This option smoothes the stick input. Zero value disables LPF.</string>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>150</number>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:ResponseTime</string>
<string>element:Roll</string>
<string>haslimits:no</string>
<string>scale:1</string>
<string>buttongroup:1</string>
</stringlist>
</property>
</widget>
</item>
<item row="6" column="0">
<item row="5" column="0">
<widget class="QLabel" name="label_36">
<property name="text">
<string>MaxAxisLockRate</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_37">
<property name="text">
<string>Response Time</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_38">
<property name="text">
<string>Input Rate</string>
<string>Input Rate (Speed)</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_39">
<property name="text">
<string>Input Range</string>
<string>Input Range (Angle)</string>
</property>
</widget>
</item>
@ -928,14 +834,14 @@ This option smoothes the stick input. Zero value disables LPF.</string>
</property>
</widget>
</item>
<item row="6" column="2" colspan="2">
<item row="5" column="2" colspan="2">
<widget class="QLabel" name="label_41">
<property name="text">
<string>(the same value for Roll, Pitch, Yaw)</string>
</property>
</widget>
</item>
<item row="6" column="1">
<item row="5" column="1">
<widget class="QDoubleSpinBox" name="MaxAxisLockRate">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
@ -973,12 +879,356 @@ value.</string>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="minimumSize">
<size>
<width>0</width>
<height>162</height>
</size>
</property>
<property name="title">
<string>Expert Settings (Attitude Filter and Feed Forward)</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="1">
<widget class="QLabel" name="label_49">
<property name="minimumSize">
<size>
<width>0</width>
<height>16</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
color: rgb(255, 255, 255);
border-radius: 5;
font: bold 12px;
margin:1px;</string>
</property>
<property name="text">
<string>Roll</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="minimumSize">
<size>
<width>0</width>
<height>16</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
color: rgb(255, 255, 255);
border-radius: 5;
font: bold 12px;
margin:1px;</string>
</property>
<property name="text">
<string>Pitch</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="label_51">
<property name="minimumSize">
<size>
<width>0</width>
<height>16</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
color: rgb(255, 255, 255);
border-radius: 5;
font: bold 12px;
margin:1px;</string>
</property>
<property name="text">
<string>Yaw</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="rollFeedForward">
<property name="toolTip">
<string>Roll servo feed forward acceleration
Range: 0-25, 0 disables feed forward for the axis (default).
Good starting value is 2-7.
Too high value may burn your servo!</string>
</property>
<property name="maximum">
<number>25</number>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:FeedForward</string>
<string>element:Roll</string>
<string>haslimits:no</string>
<string>scale:1</string>
<string>buttongroup:1</string>
</stringlist>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="pitchFeedForward">
<property name="toolTip">
<string>Pitch servo feed forward acceleration
Range: 0-25, 0 disables feed forward for the axis (default).
Good starting value is 2-7.
Too high value may burn your servo!</string>
</property>
<property name="maximum">
<number>25</number>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:FeedForward</string>
<string>element:Pitch</string>
<string>haslimits:no</string>
<string>scale:1</string>
<string>buttongroup:1</string>
</stringlist>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QSpinBox" name="yawFeedForward">
<property name="toolTip">
<string>Yaw servo feed forward acceleration
Range: 0-25, 0 disables feed forward for the axis (default).
Good starting value is 2-7.
Too high value may burn your servo!</string>
</property>
<property name="maximum">
<number>25</number>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:FeedForward</string>
<string>element:Yaw</string>
<string>haslimits:no</string>
<string>scale:1</string>
<string>buttongroup:1</string>
</stringlist>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_47">
<property name="text">
<string>Gimbal Type:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="gimbalType">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>Gimbal type
Used to limit feed forward acceleration at extreme angles.</string>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:GimbalType</string>
<string>buttongroup:1</string>
</stringlist>
</property>
<item>
<property name="text">
<string>Yaw-Roll-Pitch</string>
</property>
</item>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="label_48">
<property name="text">
<string>FF Accel Time Constant</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QSpinBox" name="accelTime">
<property name="toolTip">
<string>Feed forward acceleration time constant
Range: 0-50ms, default is 5.
The same value is used for all axes.</string>
</property>
<property name="maximum">
<number>50</number>
</property>
<property name="value">
<number>5</number>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:AccelTime</string>
<string>buttongroup:1</string>
</stringlist>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>AF Response Time</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="responseTime">
<property name="toolTip">
<string>Attitude filter response time
Range: 0-250ms, 0 disables filter (default).
Smoothes estimated airframe attitude used by camera stabilization.
The same value is used for all axes.</string>
</property>
<property name="maximum">
<number>250</number>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:ResponseTime</string>
<string>buttongroup:1</string>
</stringlist>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLabel" name="label_5">
<property name="text">
<string>FF Decel Time Constant</string>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QSpinBox" name="decelTime">
<property name="toolTip">
<string>Feed forward deceleration time constant
Range: 0-50ms, default is 5.
The same value is used for all axes.</string>
</property>
<property name="maximum">
<number>50</number>
</property>
<property name="value">
<number>5</number>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:DecelTime</string>
<string>buttongroup:1</string>
</stringlist>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QLabel" name="label_6">
<property name="text">
<string>FF Max Acceleration</string>
</property>
</widget>
</item>
<item row="4" column="3">
<widget class="QSpinBox" name="maxAccel">
<property name="toolTip">
<string>Feed forward maximum acceleration
Range: 0-1000, default is 500.
The same value is used for all axes.</string>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>500</number>
</property>
<property name="objrelation" stdset="0">
<stringlist>
<string>objname:CameraStabSettings</string>
<string>fieldname:MaxAccel</string>
<string>buttongroup:1</string>
</stringlist>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>FF Servo Acceleration</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Input configuration also provides smoothing for controls. Look for RT options on the RC Input tab.</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="minimumSize">
<size>
<width>0</width>
<height>71</height>
<height>50</height>
</size>
</property>
<property name="maximumSize">
@ -1005,13 +1255,10 @@ value.</string>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>

View File

@ -4,10 +4,15 @@
<field name="Input" units="channel" type="enum" elementnames="Roll,Pitch,Yaw" options="Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5,None" defaultvalue="None"/>
<field name="InputRange" units="deg" type="uint8" elementnames="Roll,Pitch,Yaw" defaultvalue="20"/>
<field name="InputRate" units="deg/s" type="uint8" elementnames="Roll,Pitch,Yaw" defaultvalue="50"/>
<field name="ResponseTime" units="ms" type="uint16" elementnames="Roll,Pitch,Yaw" defaultvalue="150"/>
<field name="StabilizationMode" units="" type="enum" elementnames="Roll,Pitch,Yaw" options="Attitude,AxisLock" defaultvalue="Attitude"/>
<field name="MaxAxisLockRate" units="deg/s" type="float" elements="1" defaultvalue="1"/>
<field name="OutputRange" units="deg" type="uint8" elementnames="Roll,Pitch,Yaw" defaultvalue="20"/>
<field name="ResponseTime" units="ms" type="uint8" elements="1" defaultvalue="0"/>
<field name="GimbalType" units="" type="enum" elements="1" options="Yaw-Roll-Pitch,Yaw-Pitch-Roll" defaultvalue="Yaw-Roll-Pitch"/>
<field name="FeedForward" units="" type="uint8" elementnames="Roll,Pitch,Yaw" defaultvalue="0"/>
<field name="MaxAccel" units="units/sec" type="uint16" elements="1" defaultvalue="500"/>
<field name="AccelTime" units="ms" type="uint8" elements="1" defaultvalue="5"/>
<field name="DecelTime" units="ms" type="uint8" elements="1" defaultvalue="5"/>
<access gcs="readwrite" flight="readwrite"/>
<telemetrygcs acked="true" updatemode="onchange" period="0"/>
<telemetryflight acked="true" updatemode="onchange" period="0"/>