Subversion Repositories FlightCtrl

Compare Revisions

Ignore whitespace Rev 2102 → Rev 2103

/branches/dongfang_FC_fixedwing/analog.c
43,7 → 43,7
int16_t gyro_PID[3];
int16_t gyro_ATT[3];
int16_t gyroD[3];
int16_t gyroDWindow[2][GYRO_D_WINDOW_LENGTH];
int16_t gyroDWindow[3][GYRO_D_WINDOW_LENGTH];
uint8_t gyroDWindowIdx = 0;
//int16_t dHeight;
//uint32_t gyroActivity;
119,21 → 119,6
uint16_t simpleAirPressure;
uint16_t airspeedVelocity;
 
// Value of AIRPRESSURE_OVERSAMPLING samples, with range, filtered.
// int32_t filteredAirPressure;
 
#define MAX_AIRPRESSURE_WINDOW_LENGTH 32
int16_t airPressureWindow[MAX_AIRPRESSURE_WINDOW_LENGTH];
int32_t windowedAirPressure;
uint8_t windowPtr = 0;
 
// Partial sum of AIRPRESSURE_SUMMATION_FACTOR samples.
int32_t airPressureSum;
 
// The number of samples summed into airPressureSum so far.
uint8_t pressureMeasurementCount;
 
 
/*
* Battery voltage, in units of: 1k/11k / 3V * 1024 = 31.03 per volt.
* That is divided by 3 below, for a final 10.34 per volt.
225,11 → 210,6
//Trigger Source to Free Running Mode
ADCSRB &= ~((1<<ADTS2)|(1<<ADTS1)|(1<<ADTS0));
 
for (uint8_t i=0; i<MAX_AIRPRESSURE_WINDOW_LENGTH; i++) {
airPressureWindow[i] = 0;
}
windowedAirPressure = 0;
 
startAnalogConversionCycle();
 
// restore global interrupt flags
322,6 → 302,7
int16_t tempOffsetGyro[3], tempGyro;
debugOut.digital[0] &= ~DEBUG_SENSORLIMIT;
 
for (uint8_t axis=0; axis<3; axis++) {
tempGyro = rawGyroValue(axis);
/*
376,6 → 357,7
// dampenGyroActivity();
gyro_ATT[PITCH] = tempOffsetGyro[PITCH];
gyro_ATT[ROLL] = tempOffsetGyro[ROLL];
gyro_ATT[YAW] = tempOffsetGyro[YAW];
 
if (++gyroDWindowIdx >= IMUConfig.gyroDWindowLength) {
gyroDWindowIdx = 0;
402,7 → 384,6
#ifdef USE_MK3MAG
magneticHeading = volatileMagneticHeading;
#endif
 
}
 
void analog_setNeutral() {
430,7 → 411,7
}
 
void analog_calibrateGyros(void) {
#define GYRO_OFFSET_CYCLES 32
#define GYRO_OFFSET_CYCLES 64
uint8_t i, axis;
int32_t offsets[3] = { 0, 0, 0 };
gyro_calibrate();
/branches/dongfang_FC_fixedwing/attitude.c
28,12 → 28,7
* The variables are overwritten at each attitude calculation invocation - the values
* are not preserved or reused.
*/
int16_t rate_ATT[3];
 
// With different (less) filtering
int16_t rate_PID[3];
int16_t differential[3];
 
/*
* Gyro integrals. These are the rotation angles of the airframe compared to the
* horizontal plane, yaw relative to yaw at start.
86,13 → 81,8
*************************************************************************/
void getAnalogData(void) {
uint8_t axis;
 
analog_update();
 
for (axis = PITCH; axis <= YAW; axis++) {
rate_PID[axis] = gyro_PID[axis];
rate_ATT[axis] = gyro_ATT[axis];
differential[axis] = gyroD[axis];
}
}
 
110,7 → 100,7
*/
 
for (axis = PITCH; axis <= YAW; axis++) {
attitude[axis] += rate_ATT[axis];
attitude[axis] += gyro_ATT[axis];
if (attitude[axis] > OVER180) {
attitude[axis] -= OVER360;
} else if (attitude[axis] <= -OVER180) {
/branches/dongfang_FC_fixedwing/configuration.c
104,7 → 104,7
}
 
void configuration_setFlightParameters(uint8_t newFlightMode) {
updateFlightParametersToFlightMode(currentFlightMode = newFlightMode);
flight_updateFlightParametersToFlightMode(currentFlightMode = newFlightMode);
}
 
// Called after a change in configuration parameters, as a hook for modules to take over changes.
136,6 → 136,10
staticParams.emergencyThrottle = 35;
staticParams.emergencyFlightDuration = 30;
 
staticParams.stickIElevator = 80;
staticParams.stickIAilerons = 120;
staticParams.stickIRudder = 40;
 
// Outputs
staticParams.outputFlash[0].bitmask = 1; //0b01011111;
staticParams.outputFlash[0].timing = 15;
165,8 → 169,10
void IMUConfig_default(void) {
IMUConfig.gyroPIDFilterConstant = 1;
IMUConfig.gyroDFilterConstant = 1;
IMUConfig.accFilterConstant = 10;
IMUConfig.rateTolerance = 120;
IMUConfig.gyroDWindowLength = 3;
IMUConfig.gyroQuadrant = 0;
IMUConfig.imuReversedFlags = 0;
gyro_setDefaultParameters();
}
 
/branches/dongfang_FC_fixedwing/controlMixer.c
107,7 → 107,7
*/
 
void controlMixer_periodicTask(void) {
int16_t tempPRTY[4] = { 0, 0, 0, 0 };
int16_t tempPRYT[4] = { 0, 0, 0, 0 };
 
// Decode commands.
uint8_t rcCommand = (RC_getSignalQuality() >= SIGNAL_OK) ? RC_getCommand() : COMMAND_NONE;
139,18 → 139,18
}
// This will init the values (not just add to them).
RC_periodicTaskAndPRTY(tempPRTY);
RC_periodicTaskAndPRYT(tempPRYT);
 
// Add external control to RC
EC_periodicTaskAndPRTY(tempPRTY);
EC_periodicTaskAndPRYT(tempPRYT);
 
FC_periodicTaskAndPRTY(tempPRTY);
FC_periodicTaskAndPRYT(tempPRYT);
 
// Commit results to global variable and also measure control activity.
controls[CONTROL_THROTTLE] = tempPRTY[CONTROL_THROTTLE];
controls[CONTROL_ELEVATOR] = tempPRTY[CONTROL_ELEVATOR];
controls[CONTROL_AILERONS] = tempPRTY[CONTROL_AILERONS];
controls[CONTROL_RUDDER] = tempPRTY[CONTROL_RUDDER];
controls[CONTROL_THROTTLE] = tempPRYT[CONTROL_THROTTLE];
controls[CONTROL_ELEVATOR] = tempPRYT[CONTROL_ELEVATOR];
controls[CONTROL_AILERONS] = tempPRYT[CONTROL_AILERONS];
controls[CONTROL_RUDDER] = tempPRYT[CONTROL_RUDDER];
// dampenControlActivity();
// We can safely do this even with a bad signal - the variables will not have been updated then.
/branches/dongfang_FC_fixedwing/controlMixer.h
23,12 → 23,12
#define SIGNAL_GOOD 4
 
/*
* The PRTY arrays
* The PRYT arrays
*/
#define CONTROL_ELEVATOR 0
#define CONTROL_AILERONS 1
#define CONTROL_THROTTLE 2
#define CONTROL_RUDDER 3
#define CONTROL_RUDDER 2
#define CONTROL_THROTTLE 3
 
/*
* Looping flags.
/branches/dongfang_FC_fixedwing/eeprom.h
31,6 → 31,7
void paramSet_readOrDefault(void);
void channelMap_readOrDefault(void);
void IMUConfig_readOrDefault(void);
void IMUConfig_writeToEEprom(void);
 
uint8_t paramSet_readFromEEProm(uint8_t setnumber);
void paramSet_writeToEEProm(uint8_t setnumber);
/branches/dongfang_FC_fixedwing/externalControl.c
4,8 → 4,6
 
ExternalControl_t externalControl;
uint8_t externalControlActive = 0;
// int16_t EC_PRTY[4];
// TODO: Who is going to call this
 
void EC_setNeutral(void) {
// if necessary. From main.c.
19,13 → 17,13
externalControl.digital[0] = 0x55;
}
 
void EC_periodicTaskAndPRTY(int16_t* PRTY) {
void EC_periodicTaskAndPRYT(int16_t* PRYT) {
if (externalControlActive) {
externalControlActive--;
PRTY[CONTROL_ELEVATOR] += externalControl.pitch * 8;
PRTY[CONTROL_AILERONS] += externalControl.roll * 8;
PRTY[CONTROL_THROTTLE] += externalControl.throttle * 8;
PRTY[CONTROL_RUDDER] += externalControl.yaw * 8;
PRYT[CONTROL_ELEVATOR] += externalControl.pitch * 8;
PRYT[CONTROL_AILERONS] += externalControl.roll * 8;
PRYT[CONTROL_THROTTLE] += externalControl.throttle * 8;
PRYT[CONTROL_RUDDER] += externalControl.yaw * 8;
}
}
 
/branches/dongfang_FC_fixedwing/externalControl.h
20,7 → 20,7
extern ExternalControl_t externalControl;
extern uint8_t externalControlActive;
 
void EC_periodicTaskAndPRTY(int16_t* PRTY);
void EC_periodicTaskAndPRYT(int16_t* PRYT);
uint8_t EC_getArgument(void);
uint8_t EC_getCommand(void);
int16_t EC_getVariable(uint8_t varNum);
/branches/dongfang_FC_fixedwing/failsafeControl.c
4,7 → 4,7
#include "flight.h"
#include "output.h"
 
void FC_periodicTaskAndPRTY(uint16_t* PRTY) {
void FC_periodicTaskAndPRYT(uint16_t* PRYT) {
if (controlMixer_getSignalQuality() <= SIGNAL_BAD) { // the rc-frame signal is not reveived or noisy
if (controlMixer_didReceiveSignal) {
beepRCAlarm(); // Only make alarm if a control signal was received before the signal loss.
12,5 → 12,5
}
}
 
void FC_setNeutral() {
void FC_setNeutral(void) {
}
/branches/dongfang_FC_fixedwing/failsafeControl.h
1,3 → 1,3
#include <inttypes.h>
void FC_setNeutral(void);
void FC_periodicTaskAndPRTY(int16_t* PRTY);
void FC_periodicTaskAndPRYT(int16_t* PRYT);
/branches/dongfang_FC_fixedwing/flight.c
8,6 → 8,7
#include "uart0.h"
 
#include "timer2.h"
#include "analog.h"
#include "attitude.h"
#include "controlMixer.h"
 
44,14 → 45,14
}
 
// this should be followed by a call to switchToFlightMode!!
void updateFlightParametersToFlightMode(uint8_t flightMode) {
debugOut.analog[15] = flightMode;
void flight_updateFlightParametersToFlightMode(uint8_t flightMode) {
debugOut.analog[16] = flightMode;
 
reverse[CONTROL_ELEVATOR] = staticParams.controlServosReverse
reverse[PITCH] = staticParams.controlServosReverse
& CONTROL_SERVO_REVERSE_ELEVATOR;
reverse[CONTROL_AILERONS] = staticParams.controlServosReverse
reverse[ROLL] = staticParams.controlServosReverse
& CONTROL_SERVO_REVERSE_AILERONS;
reverse[CONTROL_RUDDER] = staticParams.controlServosReverse
reverse[YAW] = staticParams.controlServosReverse
& CONTROL_SERVO_REVERSE_RUDDER;
 
for (uint8_t i = 0; i < 3; i++) {
76,7 → 77,7
/************************************************************************/
void flight_control(void) {
// Mixer Fractions that are combined for Motor Control
int16_t throttleTerm, term[3];
int16_t term[4];
 
// PID controller variables
int16_t PDPart[3];
92,18 → 93,18
// calculateFlightAttitude();
// TODO: Check modern version.
// controlMixer_update();
throttleTerm = controls[CONTROL_THROTTLE];
term[CONTROL_THROTTLE] = controls[CONTROL_THROTTLE];
 
// These params are just left the same in all modes. In MANUAL and RATE the results are ignored anyway.
target[PITCH] += controls[CONTROL_ELEVATOR] * staticParams.stickIElevator;
target[ROLL] += controls[CONTROL_AILERONS] * staticParams.stickIAilerons;
target[YAW] += controls[CONTROL_RUDDER] * staticParams.stickIRudder;
target[PITCH] += (controls[CONTROL_ELEVATOR] * staticParams.stickIElevator) >> 6;
target[ROLL] += (controls[CONTROL_AILERONS] * staticParams.stickIAilerons) >> 6;
target[YAW] += (controls[CONTROL_RUDDER] * staticParams.stickIRudder) >> 6;
 
for (axis = PITCH; axis <= YAW; axis++) {
if (target[axis] > OVER180) {
target[axis] -= OVER360;
} else if (attitude[axis] <= -OVER180) {
attitude[axis] += OVER360;
} else if (target[axis] <= -OVER180) {
target[axis] += OVER360;
}
 
if (reverse[axis])
120,8 → 121,8
/* Calculate control feedback from angle (gyro integral) */
/* and angular velocity (gyro signal) */
/************************************************************************/
PDPart[axis] = (((int32_t) rate_PID[axis] * pFactor[axis]) >> 6)
+ ((differential[axis] * (int16_t) dFactor[axis]) >> 4);
PDPart[axis] = (((int32_t) gyro_PID[axis] * pFactor[axis]) >> 6)
+ ((gyroD[axis] * (int16_t) dFactor[axis]) >> 4);
if (reverse[axis])
PDPart[axis] = -PDPart[axis];
 
139,8 → 140,8
 
debugOut.analog[12] = term[PITCH];
debugOut.analog[13] = term[ROLL];
debugOut.analog[14] = throttleTerm;
debugOut.analog[15] = term[YAW];
debugOut.analog[14] = term[YAW];
debugOut.analog[15] = term[THROTTLE];
 
for (uint8_t i = 0; i < MAX_CONTROL_SERVOS; i++) {
int16_t tmp;
156,7 → 157,7
tmp = term[PITCH];
break;
case 2:
tmp = throttleTerm;
tmp = term[THROTTLE];
break;
case 3:
tmp = term[YAW];
169,7 → 170,7
}
}
 
calculateControlServoValues;
calculateControlServoValues();
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Debugging
176,9 → 177,9
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if (!(--debugDataTimer)) {
debugDataTimer = 24; // update debug outputs at 488 / 24 = 20.3 Hz.
debugOut.analog[0] = rate_PID[PITCH]; // in 0.1 deg
debugOut.analog[1] = rate_PID[ROLL]; // in 0.1 deg
debugOut.analog[2] = rate_PID[YAW];
debugOut.analog[0] = gyro_PID[PITCH]; // in 0.1 deg
debugOut.analog[1] = gyro_PID[ROLL]; // in 0.1 deg
debugOut.analog[2] = gyro_PID[YAW];
 
debugOut.analog[3] = attitude[PITCH] / (GYRO_DEG_FACTOR / 10); // in 0.1 deg
debugOut.analog[4] = attitude[ROLL] / (GYRO_DEG_FACTOR / 10); // in 0.1 deg
/branches/dongfang_FC_fixedwing/flight.h
12,6 → 12,7
#define PITCH 0
#define ROLL 1
#define YAW 2
#define THROTTLE 3
 
#define MAX_CONTROL_SERVOS 4
 
18,7 → 19,7
extern int16_t controlServos[MAX_CONTROL_SERVOS];
 
void flight_control(void);
void transmitMotorThrottleData(void);
void flight_setNeutral(void);
void flight_updateFlightParametersToFlightMode(uint8_t flightMode);
 
#endif //_FLIGHT_H
/branches/dongfang_FC_fixedwing/isqrt.S
0,0 → 1,203
;-----------------------------------------------------------------------------;
; Fast integer squareroot routines for avr-gcc project (C)ChaN, 2008
; http://elm-chan.org/docs/avrlib/sqrt32.S
;-----------------------------------------------------------------------------;
; uint16_t isqrt32 (uint32_t n);
; uint8_t isqrt16 (uint16_t n);
; uint16_t ihypot (int16_t x, int16_t y);
 
;-----------------------------------------------------------------------------:
; 32bit integer squareroot
;-----------------------------------------------------------------------------;
; uint16_t isqrt32 (
; uint32_t n
; );
;
; Return Value:
; Squareroot of n.
;
; Size = 53 words
; Clock = 532..548 cycles
; Stack = 0 byte
 
.global isqrt32
.func isqrt32
 
isqrt32:
clr r0
clr r18
clr r19
clr r20
ldi r21, 1
clr r27
clr r30
clr r31
ldi r26, 16
1: lsl r22
rol r23
rol r24
rol r25
rol r0
rol r18
rol r19
rol r20
lsl r22
rol r23
rol r24
rol r25
rol r0
rol r18
rol r19
rol r20
brpl 2f
add r0, r21
adc r18, r27
adc r19, r30
adc r20, r31
rjmp 3f
2: sub r0, r21
sbc r18, r27
sbc r19, r30
sbc r20, r31
3: lsl r21
rol r27
rol r30
andi r21, 0b11111000
ori r21, 0b00000101
sbrc r20, 7
subi r21, 2
dec r26
brne 1b
lsr r30
ror r27
ror r21
lsr r30
ror r27
ror r21
mov r24, r21
mov r25, r27
ret
.endfunc
 
 
 
;-----------------------------------------------------------------------------:
; 16bit integer squareroot
;-----------------------------------------------------------------------------;
; uint8_t isqrt16 (
; uint16_t n
; );
;
; Return Value:
; Squareroot of n.
;
; Size = 33 words
; Clock = 181..189 cycles
; Stack = 0 byte
 
.global isqrt16
.func isqrt16
 
isqrt16:
clr r18
clr r19
ldi r20, 1
clr r21
ldi r22, 8
1: lsl r24
rol r25
rol r18
rol r19
lsl r24
rol r25
rol r18
rol r19
brpl 2f
add r18, r20
adc r19, r21
rjmp 3f
2: sub r18, r20
sbc r19, r21
3: lsl r20
rol r21
andi r20, 0b11111000
ori r20, 0b00000101
sbrc r19, 7
subi r20, 2
dec r22
brne 1b
lsr r21
ror r20
lsr r21
ror r20
mov r24, r20
ret
.endfunc
 
 
 
;-----------------------------------------------------------------------------:
; 16bit integer hypot (megaAVR is required)
;-----------------------------------------------------------------------------;
; uint16_t ihypot (
; int16_t x,
; int16_t y
; );
;
; Return Value:
; Squareroot of (x*x + y*y)
;
; Size = 42 words
; Clock = 581..597 cycles
; Stack = 0 byte
 
.global ihypot
.func ihypot
 
ihypot:
clr r26
sbrs r25, 7
rjmp 1f
com r24
com r25
adc r24, r26
adc r25, r26
1: sbrs r23, 7
rjmp 2f
com r22
com r23
adc r22, r26
adc r23, r26
2: mul r22, r22
movw r18, r0
mul r23, r23
movw r20, r0
mul r22, r23
add r19, r0
adc r20, r1
adc r21, r26
add r19, r0
adc r20, r1
adc r21, r26
mul r24, r24
movw r30, r0
mul r25, r25
add r18, r30
adc r19, r31
adc r20, r0
adc r21, r1
mul r24, r25
add r19, r0
adc r20, r1
adc r21, r26
add r19, r0
adc r20, r1
adc r21, r26
movw r24, r20
movw r22, r18
clr r1
rjmp isqrt32
.endfunc
 
 
 
/branches/dongfang_FC_fixedwing/isqrt.h
0,0 → 1,11
#ifndef _ISQRT_H
#define _ISQRT_H
 
#include <inttypes.h>
 
// coded in assembler file
extern uint16_t isqrt32(uint32_t n);
extern uint8_t isqrt16(uint16_t n);
extern uint16_t ihypot(int16_t x, int16_t y);
 
#endif // _ISQRT_H
/branches/dongfang_FC_fixedwing/rc.c
154,7 → 154,7
 
#define RC_SCALING 4
 
uint8_t getControlModeSwitch() {
uint8_t getControlModeSwitch(void) {
int16_t channel = RCChannel(CH_MODESWITCH) + POT_OFFSET;
uint8_t flightMode = channel < 256/3 ? FLIGHT_MODE_MANUAL :
(channel > 256*2/3 ? FLIGHT_MODE_ANGLES : FLIGHT_MODE_RATE);
175,8 → 175,8
return lastRCCommand;
}
 
int16_t channel = RCChannel(CH_MODESWITCH) + POT_OFFSET;
if (channel <= -32) { // <= 900 us
int16_t channel = RCChannel(CH_THROTTLE);
if (channel <= -140) { // <= 900 us
if (commandTimer == COMMAND_TIMER) {
lastRCCommand = COMMAND_GYROCAL;
}
183,7 → 183,10
if (commandTimer <= COMMAND_TIMER) {
commandTimer++;
}
} else commandTimer = 0;
} else {
commandTimer = 0;
lastRCCommand = COMMAND_NONE;
}
return lastRCCommand;
}
 
194,17 → 197,20
/*
* Get Pitch, Roll, Throttle, Yaw values
*/
void RC_periodicTaskAndPRTY(int16_t* PRTY) {
void RC_periodicTaskAndPRYT(int16_t* PRYT) {
if (RCQuality) {
RCQuality--;
PRTY[CONTROL_ELEVATOR] = RCChannel(CH_ELEVATOR) * RC_SCALING;
PRTY[CONTROL_AILERONS] = RCChannel(CH_AILERONS) * RC_SCALING;
PRTY[CONTROL_THROTTLE] = RCChannel(CH_THROTTLE) * RC_SCALING;
PRTY[CONTROL_RUDDER] = RCChannel(CH_RUDDER) * RC_SCALING;
 
debugOut.analog[16] = PRTY[CONTROL_ELEVATOR];
debugOut.analog[17] = PRTY[CONTROL_THROTTLE];
debugOut.analog[20] = RCChannel(CH_ELEVATOR);
debugOut.analog[21] = RCChannel(CH_AILERONS);
debugOut.analog[22] = RCChannel(CH_RUDDER);
debugOut.analog[23] = RCChannel(CH_THROTTLE);
 
PRYT[CONTROL_ELEVATOR] = RCChannel(CH_ELEVATOR) * RC_SCALING;
PRYT[CONTROL_AILERONS] = RCChannel(CH_AILERONS) * RC_SCALING;
PRYT[CONTROL_RUDDER] = RCChannel(CH_RUDDER) * RC_SCALING;
PRYT[CONTROL_THROTTLE] = RCChannel(CH_THROTTLE) * RC_SCALING;
 
uint8_t command = COMMAND_NONE; //RC_getStickCommand();
if (lastRCCommand == command) {
// Keep timer from overrunning.
/branches/dongfang_FC_fixedwing/rc.h
32,7 → 32,7
*/
 
// void RC_periodicTask(void);
void RC_periodicTaskAndPRTY(int16_t* PRTY);
void RC_periodicTaskAndPRYT(int16_t* PRYT);
uint8_t RC_getArgument(void);
uint8_t RC_getCommand(void);
int16_t RC_getVariable(uint8_t varNum);
/branches/dongfang_FC_fixedwing/timer2.c
126,13 → 126,15
 
void calculateControlServoValues(void) {
int16_t value;
for (uint8_t axis=0; axis<3; axis++) {
for (uint8_t axis=0; axis<4; axis++) {
value = controlServos[axis];
value /= 2;
value *= 2;
servoValues[axis] = value + NEUTRAL_PULSELENGTH;
}
debugOut.analog[18] = servoValues[0];
debugOut.analog[19] = servoValues[2];
debugOut.analog[24] = servoValues[0];
debugOut.analog[25] = servoValues[1];
debugOut.analog[26] = servoValues[2];
debugOut.analog[27] = servoValues[3];
}
 
void calculateFeaturedServoValues(void) {
144,11 → 146,11
 
for (axis=0; axis<2; axis++) {
value = featuredServoValue(axis);
servoValues[axis + 3] = value;
servoValues[axis + 4] = value;
}
for (axis=2; axis<MAX_SERVOS; axis++) {
value = 128 * SCALE_FACTOR;
servoValues[axis + 3] = value;
servoValues[axis + 4] = value;
}
 
recalculateServoTimes = 0;
/branches/dongfang_FC_fixedwing/uart0.c
95,24 → 95,24
"Error Y ",
"Term P ",
"Term R ",
"Term Y ",
"FlightMode ", //15
"RC P ",
"RC Thr ",
"ServoFinal P ",
"ServoFinal T ",
"control act wghd", //20
"acc vector wghd ",
"Height[dm] ",
"dHeight ",
"acc vector ",
"EFT ", //25
"naviPitch ",
"naviRoll ",
"tolerance ",
"Gyro Act Cont. ",
"GPS altitude ", //30
"GPS vert accura "
"Throttle ",
"Term Y ", //15
"Flight mode ",
" ",
" ",
" ",
"RC P ", //20
"RC R ",
"RC T ",
"RC Y ",
"Servo P ",
"Servo R ", //25
"Servo T ",
"Servo Y ",
" ",
" . ",
" ", //30
" "
};
 
/****************************************************************/