Subversion Repositories FlightCtrl

Rev

Rev 2118 | Rev 2122 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1910 - 1
#include <stdlib.h>
2
#include <avr/io.h>
3
#include "eeprom.h"
4
#include "flight.h"
5
#include "output.h"
6
 
7
// Necessary for external control and motor test
8
#include "uart0.h"
9
#include "timer2.h"
2103 - 10
#include "analog.h"
1910 - 11
#include "attitude.h"
12
#include "controlMixer.h"
2104 - 13
#include "configuration.h"
1910 - 14
 
15
#define CHECK_MIN_MAX(value, min, max) {if(value < min) value = min; else if(value > max) value = max;}
16
 
17
/*
2099 - 18
 * target-directions integrals.
1910 - 19
 */
2099 - 20
int32_t target[3];
1910 - 21
 
2099 - 22
/*
23
 * Error integrals.
24
 */
25
int32_t error[3];
1910 - 26
 
2099 - 27
uint8_t reverse[3];
2104 - 28
int32_t maxError[3];
2099 - 29
int32_t IPart[3] = { 0, 0, 0 };
2104 - 30
PID_t airspeedPID[3];
1910 - 31
 
2104 - 32
int16_t controlServos[NUM_CONTROL_SERVOS];
1910 - 33
 
34
/************************************************************************/
35
/*  Neutral Readings                                                    */
36
/************************************************************************/
37
#define CONTROL_CONFIG_SCALE 10
38
 
2099 - 39
void flight_setGround(void) {
2102 - 40
        IPart[PITCH] = IPart[ROLL] = IPart[YAW] = 0;
41
        target[PITCH] = attitude[PITCH];
42
        target[ROLL] = attitude[ROLL];
43
        target[YAW] = attitude[YAW];
1910 - 44
}
45
 
2104 - 46
void flight_updateFlightParametersToFlightMode(void) {
47
        debugOut.analog[16] = currentFlightMode;
2119 - 48
        reverse[PITCH] = staticParams.servosReverse & CONTROL_SERVO_REVERSE_ELEVATOR;
49
        reverse[ROLL] = staticParams.servosReverse & CONTROL_SERVO_REVERSE_AILERONS;
50
        reverse[YAW] = staticParams.servosReverse & CONTROL_SERVO_REVERSE_RUDDER;
1910 - 51
 
2104 - 52
        // At a switch to angles, we want to kill errors first.
53
        // This should be triggered only once per mode change!
54
        if (currentFlightMode == FLIGHT_MODE_ANGLES) {
55
                target[PITCH] = attitude[PITCH];
56
                target[ROLL] = attitude[ROLL];
57
                target[YAW] = attitude[YAW];
58
        }
1910 - 59
 
2104 - 60
        for (uint8_t axis=0; axis<3; axis++) {
61
                maxError[axis] = (int32_t)staticParams.gyroPID[axis].iMax * GYRO_DEG_FACTOR;
62
        }
63
}
2102 - 64
 
2104 - 65
// Normal at airspeed = 10.
66
uint8_t calcAirspeedPID(uint8_t pid) {
2119 - 67
        if (!(staticParams.bitConfig & CFG_USE_AIRSPEED_PID)) {
2104 - 68
                return pid;
2102 - 69
        }
2104 - 70
 
2106 - 71
        uint16_t result = (pid * 10) / airspeedVelocity;
2104 - 72
 
2106 - 73
        if (result > 240 || airspeedVelocity == 0) {
2104 - 74
                result = 240;
75
        }
76
 
77
        return result;
1910 - 78
}
79
 
2104 - 80
void setAirspeedPIDs(void) {
81
        for (uint8_t axis = 0; axis<3; axis++) {
82
                airspeedPID[axis].P = calcAirspeedPID(dynamicParams.gyroPID[axis].P);
83
                airspeedPID[axis].I = calcAirspeedPID(dynamicParams.gyroPID[axis].I); // Should this be???
84
                airspeedPID[axis].D = dynamicParams.gyroPID[axis].D;
85
        }
86
}
87
 
2119 - 88
#define LOG_STICK_SCALE 8
89
#define LOG_P_SCALE 6
90
#define LOG_I_SCALE 10
91
#define LOG_D_SCALE 6
92
 
1910 - 93
/************************************************************************/
94
/*  Main Flight Control                                                 */
95
/************************************************************************/
96
void flight_control(void) {
2102 - 97
        // Mixer Fractions that are combined for Motor Control
2103 - 98
        int16_t term[4];
2099 - 99
 
2102 - 100
        // PID controller variables
101
        int16_t PDPart[3];
1910 - 102
 
2102 - 103
        static int8_t debugDataTimer = 1;
1910 - 104
 
2102 - 105
        // High resolution motor values for smoothing of PID motor outputs
106
        // static int16_t outputFilters[MAX_OUTPUTS];
1910 - 107
 
2102 - 108
        uint8_t axis;
1910 - 109
 
2104 - 110
        setAirspeedPIDs();
111
 
2103 - 112
        term[CONTROL_THROTTLE] = controls[CONTROL_THROTTLE];
1910 - 113
 
2102 - 114
        // These params are just left the same in all modes. In MANUAL and RATE the results are ignored anyway.
2119 - 115
        target[PITCH] += ((int32_t)controls[CONTROL_ELEVATOR] * staticParams.stickIElevator) >> LOG_STICK_SCALE;
116
        target[ROLL] += ((int32_t)controls[CONTROL_AILERONS] * staticParams.stickIAilerons) >> LOG_STICK_SCALE;
117
        target[YAW] += ((int32_t)controls[CONTROL_RUDDER] * staticParams.stickIRudder) >> LOG_STICK_SCALE;
1910 - 118
 
2102 - 119
        for (axis = PITCH; axis <= YAW; axis++) {
120
                if (target[axis] > OVER180) {
121
                        target[axis] -= OVER360;
2103 - 122
                } else if (target[axis] <= -OVER180) {
2104 - 123
                        target[axis] += OVER360;
2102 - 124
                }
1910 - 125
 
2102 - 126
                if (reverse[axis])
2119 - 127
                  error[axis] = target[axis] - attitude[axis];
128
                 else
129
                   error[axis] = attitude[axis] - target[axis];
2104 - 130
 
131
                if (error[axis] > maxError[axis]) {
2119 - 132
                  error[axis] = maxError[axis];
2104 - 133
                } else if (error[axis] < -maxError[axis]) {
2119 - 134
                  error[axis] =- maxError[axis];
2118 - 135
                } else {
136
                        // update I parts here for angles mode. Ĩ parts in rate mode is something different.
2102 - 137
                }
1910 - 138
 
2102 - 139
                /************************************************************************/
140
                /* Calculate control feedback from angle (gyro integral)                */
141
                /* and angular velocity (gyro signal)                                   */
142
                /************************************************************************/
2119 - 143
                if (currentFlightMode == FLIGHT_MODE_ANGLES || currentFlightMode == FLIGHT_MODE_RATE) {
144
                        PDPart[axis] = (((int32_t) gyro_PID[axis] * (int32_t) airspeedPID[axis].P) >> LOG_P_SCALE)
145
                                + (((int16_t)gyroD[axis] * (int16_t) airspeedPID[axis].D) >> LOG_D_SCALE);
2104 - 146
                        if (reverse[axis])
147
                                PDPart[axis] = -PDPart[axis];
148
                } else {
149
                        PDPart[axis] = 0;
150
                }
1910 - 151
 
2104 - 152
                if (currentFlightMode == FLIGHT_MODE_ANGLES) {
2119 - 153
                        int16_t anglePart = (int32_t)(error[axis] * (int32_t) airspeedPID[axis].I) >> LOG_I_SCALE;
2104 - 154
                        if (reverse[axis])
155
                                PDPart[axis] += anglePart;
156
                        else
157
                                PDPart[axis] -= anglePart;
158
                }
2118 - 159
 
2102 - 160
                // Add I parts here... these are integrated errors.
2119 - 161
                term[axis] = controls[axis] + PDPart[axis]; // + IPart[axis];
2102 - 162
        }
1910 - 163
 
2102 - 164
        debugOut.analog[12] = term[PITCH];
165
        debugOut.analog[13] = term[ROLL];
2103 - 166
        debugOut.analog[14] = term[YAW];
167
        debugOut.analog[15] = term[THROTTLE];
2099 - 168
 
2104 - 169
        for (uint8_t i = 0; i < NUM_CONTROL_SERVOS; i++) {
2102 - 170
                int16_t tmp;
171
                if (servoTestActive) {
2119 - 172
                        controlServos[i] = ((int16_t) servoTest[i] - 128) * 8;
2102 - 173
                } else {
174
                        // Follow the normal order of servos: Ailerons, elevator, throttle, rudder.
175
                        switch (i) {
176
                        case 0:
177
                                tmp = term[ROLL];
178
                                break;
179
                        case 1:
180
                                tmp = term[PITCH];
181
                                break;
182
                        case 2:
2103 - 183
                                tmp = term[THROTTLE];
2102 - 184
                                break;
185
                        case 3:
186
                                tmp = term[YAW];
187
                                break;
188
                        default:
189
                                tmp = 0;
190
                        }
191
                        // These are all signed and in the same units as the RC stuff in rc.c.
192
                        controlServos[i] = tmp;
193
                }
194
        }
1910 - 195
 
2103 - 196
        calculateControlServoValues();
1910 - 197
 
2102 - 198
        // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
199
        // Debugging
200
        // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
201
        if (!(--debugDataTimer)) {
202
                debugDataTimer = 24; // update debug outputs at 488 / 24 = 20.3 Hz.
2103 - 203
                debugOut.analog[0] = gyro_PID[PITCH]; // in 0.1 deg
204
                debugOut.analog[1] = gyro_PID[ROLL]; // in 0.1 deg
205
                debugOut.analog[2] = gyro_PID[YAW];
1910 - 206
 
2102 - 207
                debugOut.analog[3] = attitude[PITCH] / (GYRO_DEG_FACTOR / 10); // in 0.1 deg
208
                debugOut.analog[4] = attitude[ROLL] / (GYRO_DEG_FACTOR / 10); // in 0.1 deg
209
                debugOut.analog[5] = attitude[YAW] / (GYRO_DEG_FACTOR / 10);
2099 - 210
 
2102 - 211
                debugOut.analog[6] = target[PITCH] / (GYRO_DEG_FACTOR / 10); // in 0.1 deg
212
                debugOut.analog[7] = target[ROLL] / (GYRO_DEG_FACTOR / 10); // in 0.1 deg
213
                debugOut.analog[8] = target[YAW] / (GYRO_DEG_FACTOR / 10);
214
 
215
                debugOut.analog[9] = error[PITCH] / (GYRO_DEG_FACTOR / 10); // in 0.1 deg
216
                debugOut.analog[10] = error[ROLL] / (GYRO_DEG_FACTOR / 10); // in 0.1 deg
217
                debugOut.analog[11] = error[YAW] / (GYRO_DEG_FACTOR / 10);
218
 
219
                debugOut.analog[12] = term[PITCH];
220
                debugOut.analog[13] = term[ROLL];
221
                debugOut.analog[14] = term[YAW];
222
 
223
                //DebugOut.Analog[18] = (10 * controlIntegrals[CONTROL_ELEVATOR]) / GYRO_DEG_FACTOR_PITCHROLL; // in 0.1 deg
224
                //DebugOut.Analog[19] = (10 * controlIntegrals[CONTROL_AILERONS]) / GYRO_DEG_FACTOR_PITCHROLL; // in 0.1 deg
225
                //debugOut.analog[22] = (10 * IPart[PITCH]) / GYRO_DEG_FACTOR; // in 0.1 deg
226
                //debugOut.analog[23] = (10 * IPart[ROLL]) / GYRO_DEG_FACTOR; // in 0.1 deg
227
        }
1910 - 228
}