Subversion Repositories FlightCtrl

Compare Revisions

Ignore whitespace Rev 2101 → Rev 2102

/branches/dongfang_FC_fixedwing/flight.c
7,9 → 7,6
// Necessary for external control and motor test
#include "uart0.h"
 
// for scope debugging
// #include "rc.h"
 
#include "timer2.h"
#include "attitude.h"
#include "controlMixer.h"
32,7 → 29,7
uint8_t reverse[3];
int32_t IPart[3] = { 0, 0, 0 };
 
int16_t servos[MAX_SERVOS];
int16_t controlServos[MAX_CONTROL_SERVOS];
 
/************************************************************************/
/* Neutral Readings */
40,41 → 37,38
#define CONTROL_CONFIG_SCALE 10
 
void flight_setGround(void) {
IPart[PITCH] = IPart[ROLL] = IPart[YAW] = 0;
target[PITCH] = attitude[PITCH];
target[ROLL] = attitude[ROLL];
target[YAW] = attitude[YAW];
IPart[PITCH] = IPart[ROLL] = IPart[YAW] = 0;
target[PITCH] = attitude[PITCH];
target[ROLL] = attitude[ROLL];
target[YAW] = attitude[YAW];
}
 
void switchToFlightMode(FlightMode_t flightMode) {
if (flightMode == FLIGHT_MODE_MANUAL) {
pFactor[PITCH] = 0;
pFactor[ROLL] = 0;
pFactor[YAW] = 0;
} else if (flightMode == FLIGHT_MODE_RATE) {
pFactor[PITCH] = 0; //staticParams...;
pFactor[ROLL] = 0; //staticParams...;
pFactor[YAW] = 0; //staticParams...;
}
if (flightMode == FLIGHT_MODE_MANUAL || FLIGHT_MODE_RATE) {
iFactor[PITCH] = 0;
iFactor[ROLL] = 0;
iFactor[YAW] = 0;
} else if (flightMode == FLIGHT_MODE_ANGLES) {
iFactor[PITCH] = 0; //staticParams...;
iFactor[ROLL] = 0; //staticParams...;
iFactor[YAW] = 0; //staticParams...;
// When entering this mode, we want to avoid jerks from accumulated uncorrected errors.
target[PITCH] = attitude[PITCH];
target[ROLL] = attitude[ROLL];
target[YAW] = attitude[YAW];
}
// this should be followed by a call to switchToFlightMode!!
void updateFlightParametersToFlightMode(uint8_t flightMode) {
debugOut.analog[15] = flightMode;
 
dFactor[PITCH] = staticParams.gyroPitchD / CONTROL_CONFIG_SCALE;
dFactor[ROLL] = staticParams.gyroRollD / CONTROL_CONFIG_SCALE;
dFactor[YAW] = staticParams.gyroYawD / CONTROL_CONFIG_SCALE;
reverse[CONTROL_ELEVATOR] = staticParams.controlServosReverse
& CONTROL_SERVO_REVERSE_ELEVATOR;
reverse[CONTROL_AILERONS] = staticParams.controlServosReverse
& CONTROL_SERVO_REVERSE_AILERONS;
reverse[CONTROL_RUDDER] = staticParams.controlServosReverse
& CONTROL_SERVO_REVERSE_RUDDER;
 
// TODO: Set reverse also.
for (uint8_t i = 0; i < 3; i++) {
if (flightMode == FLIGHT_MODE_MANUAL) {
pFactor[i] = 0;
dFactor[i] = 0;
} else if(flightMode == FLIGHT_MODE_RATE || flightMode == FLIGHT_MODE_ANGLES) {
pFactor[i] = staticParams.gyroPID[i].P;
dFactor[i] = staticParams.gyroPID[i].D;
}
 
if (flightMode == FLIGHT_MODE_ANGLES) {
iFactor[i] = staticParams.gyroPID[i].I;
} else if(flightMode == FLIGHT_MODE_RATE || flightMode == FLIGHT_MODE_MANUAL) {
iFactor[i] = 0;
}
}
}
 
/************************************************************************/
81,120 → 75,130
/* Main Flight Control */
/************************************************************************/
void flight_control(void) {
// Mixer Fractions that are combined for Motor Control
int16_t throttleTerm, term[3];
// Mixer Fractions that are combined for Motor Control
int16_t throttleTerm, term[3];
 
// PID controller variables
int16_t PDPart[3];
// PID controller variables
int16_t PDPart[3];
 
static int8_t debugDataTimer = 1;
static int8_t debugDataTimer = 1;
 
// High resolution motor values for smoothing of PID motor outputs
// static int16_t outputFilters[MAX_OUTPUTS];
// High resolution motor values for smoothing of PID motor outputs
// static int16_t outputFilters[MAX_OUTPUTS];
 
uint8_t axis;
uint8_t axis;
 
// TODO: Check modern version.
// calculateFlightAttitude();
// TODO: Check modern version.
// controlMixer_update();
throttleTerm = controls[CONTROL_THROTTLE];
// TODO: Check modern version.
// calculateFlightAttitude();
// TODO: Check modern version.
// controlMixer_update();
throttleTerm = 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;
// 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;
 
for (axis = PITCH; axis <= YAW; axis++) {
if (target[axis] > OVER180) {
target[axis] -= OVER360;
} else if (attitude[axis] <= -OVER180) {
attitude[axis] += OVER360;
}
for (axis = PITCH; axis <= YAW; axis++) {
if (target[axis] > OVER180) {
target[axis] -= OVER360;
} else if (attitude[axis] <= -OVER180) {
attitude[axis] += OVER360;
}
 
if (reverse[axis])
error[axis] = attitude[axis] + target[axis];
else
error[axis] = attitude[axis] - target[axis];
if (error[axis] > OVER180) {
error[axis] -= OVER360;
} else if (error[axis] <= -OVER180) {
error[axis] += OVER360;
}
if (reverse[axis])
error[axis] = attitude[axis] + target[axis];
else
error[axis] = attitude[axis] - target[axis];
if (error[axis] > OVER180) {
error[axis] -= OVER360;
} else if (error[axis] <= -OVER180) {
error[axis] += OVER360;
}
 
/************************************************************************/
/* 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);
if (reverse[axis])
PDPart[axis] = -PDPart[axis];
/************************************************************************/
/* 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);
if (reverse[axis])
PDPart[axis] = -PDPart[axis];
 
int16_t anglePart = (error[axis] * iFactor[axis]) >> 10;
if (reverse[axis])
PDPart[axis] += anglePart;
else
PDPart[axis] -= anglePart;
int16_t anglePart = (error[axis] * iFactor[axis]) >> 10;
if (reverse[axis])
PDPart[axis] += anglePart;
else
PDPart[axis] -= anglePart;
 
// Add I parts here... these are integrated errors.
// When an error wraps, actually its I part should be negated or something...
// Add I parts here... these are integrated errors.
// When an error wraps, actually its I part should be negated or something...
 
term[axis] = controls[axis] + PDPart[axis] + IPart[axis];
}
term[axis] = controls[axis] + PDPart[axis] + IPart[axis];
}
 
debugOut.analog[12] = term[PITCH];
debugOut.analog[13] = term[ROLL];
debugOut.analog[14] = throttleTerm;
debugOut.analog[15] = term[YAW];
debugOut.analog[12] = term[PITCH];
debugOut.analog[13] = term[ROLL];
debugOut.analog[14] = throttleTerm;
debugOut.analog[15] = term[YAW];
 
for (uint8_t i = 0; i < MAX_SERVOS; i++) {
int16_t tmp;
if (servoTestActive) {
servos[i] = ((int16_t) servoTest[i] - 128) * 4;
} else {
// Follow the normal order of servos: Ailerons, elevator, throttle, rudder.
switch (i) {
case 0:
tmp = term[ROLL];
break;
case 1:
tmp = term[PITCH];
break;
case 2:
tmp = throttleTerm;
break;
case 3:
tmp = term[YAW];
break;
default:
tmp = 0;
}
// These are all signed and in the same units as the RC stuff in rc.c.
servos[i] = tmp;
}
}
for (uint8_t i = 0; i < MAX_CONTROL_SERVOS; i++) {
int16_t tmp;
if (servoTestActive) {
controlServos[i] = ((int16_t) servoTest[i] - 128) * 4;
} else {
// Follow the normal order of servos: Ailerons, elevator, throttle, rudder.
switch (i) {
case 0:
tmp = term[ROLL];
break;
case 1:
tmp = term[PITCH];
break;
case 2:
tmp = throttleTerm;
break;
case 3:
tmp = term[YAW];
break;
default:
tmp = 0;
}
// These are all signed and in the same units as the RC stuff in rc.c.
controlServos[i] = tmp;
}
}
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Debugging
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if (!(--debugDataTimer)) {
debugDataTimer = 24; // update debug outputs at 488 / 24 = 20.3 Hz.
debugOut.analog[0] = attitude[PITCH] / (GYRO_DEG_FACTOR / 10); // in 0.1 deg
debugOut.analog[1] = attitude[ROLL] / (GYRO_DEG_FACTOR / 10); // in 0.1 deg
debugOut.analog[2] = attitude[YAW] / (GYRO_DEG_FACTOR / 10);
calculateControlServoValues;
 
debugOut.analog[3] = target[PITCH] / (GYRO_DEG_FACTOR / 10); // in 0.1 deg
debugOut.analog[4] = target[ROLL] / (GYRO_DEG_FACTOR / 10); // in 0.1 deg
debugOut.analog[5] = target[YAW] / (GYRO_DEG_FACTOR / 10);
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Debugging
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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[6] = error[PITCH] / (GYRO_DEG_FACTOR / 10); // in 0.1 deg
debugOut.analog[7] = error[ROLL] / (GYRO_DEG_FACTOR / 10); // in 0.1 deg
debugOut.analog[8] = error[YAW] / (GYRO_DEG_FACTOR / 10);
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
debugOut.analog[5] = attitude[YAW] / (GYRO_DEG_FACTOR / 10);
 
//DebugOut.Analog[18] = (10 * controlIntegrals[CONTROL_ELEVATOR]) / GYRO_DEG_FACTOR_PITCHROLL; // in 0.1 deg
//DebugOut.Analog[19] = (10 * controlIntegrals[CONTROL_AILERONS]) / GYRO_DEG_FACTOR_PITCHROLL; // in 0.1 deg
//debugOut.analog[22] = (10 * IPart[PITCH]) / GYRO_DEG_FACTOR; // in 0.1 deg
//debugOut.analog[23] = (10 * IPart[ROLL]) / GYRO_DEG_FACTOR; // in 0.1 deg
}
debugOut.analog[6] = target[PITCH] / (GYRO_DEG_FACTOR / 10); // in 0.1 deg
debugOut.analog[7] = target[ROLL] / (GYRO_DEG_FACTOR / 10); // in 0.1 deg
debugOut.analog[8] = target[YAW] / (GYRO_DEG_FACTOR / 10);
 
debugOut.analog[9] = error[PITCH] / (GYRO_DEG_FACTOR / 10); // in 0.1 deg
debugOut.analog[10] = error[ROLL] / (GYRO_DEG_FACTOR / 10); // in 0.1 deg
debugOut.analog[11] = error[YAW] / (GYRO_DEG_FACTOR / 10);
 
debugOut.analog[12] = term[PITCH];
debugOut.analog[13] = term[ROLL];
debugOut.analog[14] = term[YAW];
 
//DebugOut.Analog[18] = (10 * controlIntegrals[CONTROL_ELEVATOR]) / GYRO_DEG_FACTOR_PITCHROLL; // in 0.1 deg
//DebugOut.Analog[19] = (10 * controlIntegrals[CONTROL_AILERONS]) / GYRO_DEG_FACTOR_PITCHROLL; // in 0.1 deg
//debugOut.analog[22] = (10 * IPart[PITCH]) / GYRO_DEG_FACTOR; // in 0.1 deg
//debugOut.analog[23] = (10 * IPart[ROLL]) / GYRO_DEG_FACTOR; // in 0.1 deg
}
}