Rev 2164 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1612 | dongfang | 1 | #include <stdlib.h> |
2 | #include <avr/io.h> |
||
2189 | - | 3 | #include <math.h> |
4 | //#include "eeprom.h" |
||
1612 | dongfang | 5 | #include "flight.h" |
1845 | - | 6 | #include "output.h" |
2189 | - | 7 | //#include "uart0.h" |
1612 | dongfang | 8 | |
9 | // Necessary for external control and motor test |
||
2189 | - | 10 | //#include "twimaster.h" |
1612 | dongfang | 11 | #include "attitude.h" |
2189 | - | 12 | #include "analog.h" |
1612 | dongfang | 13 | #include "controlMixer.h" |
1775 | - | 14 | #include "commands.h" |
2052 | - | 15 | #include "heightControl.h" |
2189 | - | 16 | #include "definitions.h" |
17 | #include "debug.h" |
||
1612 | dongfang | 18 | |
2052 | - | 19 | #ifdef USE_MK3MAG |
20 | #include "mk3mag.h" |
||
21 | #include "compassControl.h" |
||
22 | #endif |
||
23 | |||
2189 | - | 24 | int16_t targetHeading; |
2055 | - | 25 | int32_t IPart[2]; |
2189 | - | 26 | FlightMode_t flight_flightMode = FM_UNINITALIZED; |
27 | int16_t minThrottle, maxThrottle; |
||
1612 | dongfang | 28 | |
29 | /************************************************************************/ |
||
30 | /* Filter for motor value smoothing (necessary???) */ |
||
31 | /************************************************************************/ |
||
2189 | - | 32 | /* |
33 | int16_t motorFilter(int16_t newvalue, int16_t oldvalue) { |
||
34 | switch (staticParams.motorSmoothing) { |
||
35 | case 0: |
||
36 | return newvalue; |
||
37 | case 1: |
||
38 | return (oldvalue + newvalue) / 2; |
||
39 | case 2: |
||
40 | if (newvalue > oldvalue) |
||
41 | return (1 * (int16_t) oldvalue + newvalue) / 2; //mean of old and new |
||
42 | else |
||
43 | return newvalue - (oldvalue - newvalue) * 1; // 2 * new - old |
||
44 | case 3: |
||
45 | if (newvalue < oldvalue) |
||
46 | return (1 * (int16_t) oldvalue + newvalue) / 2; //mean of old and new |
||
47 | else |
||
48 | return newvalue - (oldvalue - newvalue) * 1; // 2 * new - old |
||
49 | default: |
||
50 | return newvalue; |
||
51 | } |
||
52 | } |
||
53 | */ |
||
54 | |||
55 | void resetIParts(void) { |
||
56 | IPart[X] = IPart[Y] = 0; |
||
57 | } |
||
58 | |||
59 | void flight_setMode(FlightMode_t _flightMode) { |
||
60 | if (flight_flightMode != _flightMode) { |
||
61 | resetIParts(); |
||
62 | flight_flightMode = _flightMode; |
||
1841 | - | 63 | } |
1612 | dongfang | 64 | } |
65 | |||
2189 | - | 66 | // To be called only when necessary. |
67 | void flight_setParameters(void) { |
||
68 | minThrottle = staticParams.minThrottle << LOG_CONTROL_BYTE_SCALING; |
||
69 | maxThrottle = staticParams.maxThrottle << LOG_CONTROL_BYTE_SCALING; |
||
1612 | dongfang | 70 | } |
71 | |||
2189 | - | 72 | // A heuristic when the yaw attitude cannot be used for yaw control because the airframe is near-vertical or inverted. |
73 | // Fum of abs(pitch) and abs(roll) greater than 75 degrees or about 1.3 radians. |
||
74 | uint8_t isHeadingUnaccountable(void) { |
||
75 | int16_t x = attitude[X]; |
||
76 | if (x<0) x = -x; |
||
77 | int16_t y = attitude[Y]; |
||
78 | if (y<0) y = -y; |
||
79 | int32_t result = (int32_t)x + y; |
||
80 | return result >= (long)(1.3 * INT16DEG_PI_FACTOR); |
||
1612 | dongfang | 81 | } |
82 | |||
2189 | - | 83 | void flight_setGround(void) { |
84 | resetIParts(); |
||
85 | targetHeading = attitude[Z]; |
||
86 | } |
||
87 | |||
88 | void flight_takeOff(void) { |
||
2058 | - | 89 | // This is for GPS module to mark home position. |
90 | // TODO: What a disgrace, change it. |
||
2189 | - | 91 | // MKFlags |= MKFLAG_CALIBRATE; |
2055 | - | 92 | HC_setGround(); |
93 | #ifdef USE_MK3MAG |
||
94 | attitude_resetHeadingToMagnetic(); |
||
2189 | - | 95 | compass_setTakeoffHeading(attitude[YAW]); |
2055 | - | 96 | #endif |
1612 | dongfang | 97 | } |
98 | |||
99 | /************************************************************************/ |
||
100 | /* Main Flight Control */ |
||
101 | /************************************************************************/ |
||
102 | void flight_control(void) { |
||
103 | |||
1841 | - | 104 | // PID controller variables |
2189 | - | 105 | float PID; |
1612 | dongfang | 106 | |
1841 | - | 107 | // High resolution motor values for smoothing of PID motor outputs |
2189 | - | 108 | // static int16_t motorFilters[MAX_MOTORS]; |
1612 | dongfang | 109 | |
2189 | - | 110 | throttleTerm = controls[CONTROL_THROTTLE]; // in the -1000 to 1000 range there about. |
1612 | dongfang | 111 | |
2189 | - | 112 | if (throttleTerm > 200 && (MKFlags & MKFLAG_MOTOR_RUN)) { |
2055 | - | 113 | // increment flight-time counter until overflow. |
114 | if (isFlying != 0xFFFF) |
||
115 | isFlying++; |
||
116 | } |
||
117 | /* |
||
118 | * When standing on the ground, do not apply I controls and zero the yaw stick. |
||
119 | * Probably to avoid integration effects that will cause the copter to spin |
||
120 | * or flip when taking off. |
||
121 | */ |
||
122 | if (isFlying < 256) { |
||
123 | flight_setGround(); |
||
2189 | - | 124 | if (isFlying == 255) |
2055 | - | 125 | flight_takeOff(); |
126 | } |
||
127 | |||
1841 | - | 128 | // This check removed. Is done on a per-motor basis, after output matrix multiplication. |
2189 | - | 129 | if (throttleTerm < minThrottle) |
130 | throttleTerm = minThrottle; |
||
131 | else if (throttleTerm > maxThrottle) |
||
132 | throttleTerm = maxThrottle; |
||
1612 | dongfang | 133 | |
2189 | - | 134 | // This is where control affects the target heading. It also (later) directly controls yaw. |
135 | targetHeading -= ((int32_t)controls[CONTROL_YAW] * YAW_STICK_INTEGRATION_SCALER_LSHIFT16) >> 16; |
||
136 | int16_t headingError; |
||
1775 | - | 137 | |
2189 | - | 138 | if (isHeadingUnaccountable()) { |
139 | // inverted flight. Attitude[Z] is off by PI and we should react in the oppisite direction! |
||
140 | debugOut.digital[0] |= DEBUG_INVERTED; |
||
141 | headingError = 0; |
||
142 | } else { |
||
143 | debugOut.digital[0] &= ~DEBUG_INVERTED; |
||
144 | headingError = attitude[Z] - targetHeading; |
||
145 | } |
||
2058 | - | 146 | |
2189 | - | 147 | // Ahaa. Wait. Here is pretty much same check. |
148 | if (headingError < -YAW_I_LIMIT) { |
||
2055 | - | 149 | headingError = -YAW_I_LIMIT; |
2189 | - | 150 | targetHeading = attitude[Z] + YAW_I_LIMIT; |
151 | } else if (headingError > YAW_I_LIMIT) { |
||
2055 | - | 152 | headingError = YAW_I_LIMIT; |
2189 | - | 153 | targetHeading = attitude[Z] - YAW_I_LIMIT; |
1841 | - | 154 | } |
2189 | - | 155 | |
156 | //debugOut.analog[24] = targetHeading; |
||
157 | //debugOut.analog[25] = attitude[Z]; |
||
158 | //debugOut.analog[26] = headingError; |
||
159 | //debugOut.analog[27] = positiveDynamic; |
||
160 | //debugOut.analog[28] = negativeDynamic; |
||
1775 | - | 161 | |
2189 | - | 162 | // Yaw P part. |
163 | PID = ((int32_t)gyro_control[Z] * YAW_RATE_SCALER_LSHIFT16 * dynamicParams.yawGyroP) >> 16; |
||
2055 | - | 164 | |
2189 | - | 165 | if (flight_flightMode != FM_RATE) { |
166 | PID += ((int32_t)headingError * ATT_P_SCALER_LSHIFT16 * dynamicParams.yawGyroI) >> 16; |
||
1841 | - | 167 | } |
1867 | - | 168 | |
2189 | - | 169 | yawTerm = PID + controls[CONTROL_YAW]; |
170 | // yawTerm = limitYawToThrottle(yawTerm); |
||
2053 | - | 171 | |
172 | /************************************************************************/ |
||
173 | /* Calculate control feedback from angle (gyro integral) */ |
||
174 | /* and angular velocity (gyro signal) */ |
||
175 | /************************************************************************/ |
||
2189 | - | 176 | for (uint8_t axis = CONTROL_ROLL; axis <= CONTROL_PITCH; axis++) { |
177 | if (flight_flightMode == FM_RETURN_TO_LEVEL) { |
||
178 | // Control. |
||
179 | // The P part is attitude error. |
||
180 | PID = (((int32_t)attitude[axis] * ATT_P_SCALER_LSHIFT16 * dynamicParams.attGyroP) >> 16) + controls[axis]; |
||
181 | // The I part is attitude error integral. |
||
182 | IPart[axis] += PID; |
||
183 | // The D part is rate. |
||
184 | PID += ((int32_t)gyro_control[axis] * RATE_P_SCALER_LSHIFT16 * dynamicParams.attGyroD) >> 16; |
||
1841 | - | 185 | } else { |
2189 | - | 186 | // We want: Normal stick gain, full stick deflection should drive gyros halfway towards saturation. |
187 | // If that is not enough, then fully towards saturation. |
||
188 | PID = (((int32_t)gyro_control[axis] * RATE_P_SCALER_LSHIFT16 * dynamicParams.rateGyroP) >> 16) + controls[axis]; |
||
189 | IPart[axis] += PID; |
||
190 | PID -= ((int32_t)gyroD[axis] * dynamicParams.rateGyroD) >> 8; |
||
1841 | - | 191 | } |
1612 | dongfang | 192 | |
2189 | - | 193 | // PDPart += (gyroD[axis] * (int16_t) dynamicParams.gyroD) / 16; |
194 | // Right now, let us ignore I. |
||
195 | // term[axis] = PDPart - controls[axis] + (((int32_t) IPart[axis] * ki) >> 14); |
||
196 | term[axis] = PID; |
||
2055 | - | 197 | term[axis] += (dynamicParams.levelCorrection[axis] - 128); |
198 | |||
2189 | - | 199 | debugOut.analog[12 + axis] = term[axis]; |
1841 | - | 200 | } |
1775 | - | 201 | |
2189 | - | 202 | //debugOut.analog[14] = yawTerm; |
203 | //debugOut.analog[15] = throttleTerm; |
||
204 | //debugOut.analog[15] = IPart[0] / 1000; |
||
205 | |||
1841 | - | 206 | // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
207 | // Universal Mixer |
||
208 | // Each (pitch, roll, throttle, yaw) term is in the range [0..255 * CONTROL_SCALING]. |
||
209 | // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
||
1612 | dongfang | 210 | |
2189 | - | 211 | debugOut.analog[9] = controls[CONTROL_PITCH]; |
212 | debugOut.analog[10] = controls[CONTROL_YAW]; |
||
213 | debugOut.analog[11] = controls[CONTROL_THROTTLE]; |
||
1612 | dongfang | 214 | } |