Rev 1775 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1775 | Rev 1805 | ||
---|---|---|---|
Line 72... | Line 72... | ||
72 | #include "controlMixer.h" |
72 | #include "controlMixer.h" |
Line 73... | Line 73... | ||
73 | 73 | ||
74 | // For Servo_On / Off |
74 | // For Servo_On / Off |
Line 75... | Line -... | ||
75 | // #include "timer2.h" |
- | |
76 | - | ||
77 | #ifdef USE_MK3MAG |
- | |
78 | #include "mk3mag.h" |
- | |
79 | #include "gps.h" |
75 | // #include "timer2.h" |
Line 80... | Line 76... | ||
80 | #endif |
76 | |
81 | #define CHECK_MIN_MAX(value, min, max) {if(value < min) value = min; else if(value > max) value = max;} |
77 | #define CHECK_MIN_MAX(value, min, max) {if(value < min) value = min; else if(value > max) value = max;} |
82 | 78 | ||
Line 111... | Line 107... | ||
111 | */ |
107 | */ |
112 | int32_t angle[2], yawAngleDiff; |
108 | int32_t angle[2], yawAngleDiff; |
Line 113... | Line 109... | ||
113 | 109 | ||
Line 114... | Line 110... | ||
114 | int readingHeight = 0; |
110 | int readingHeight = 0; |
- | 111 | ||
115 | 112 | // Yaw angle and compass stuff. |
|
- | 113 | ||
- | 114 | // This is updated/written from MM3. Negative angle indicates invalid data. |
|
- | 115 | int16_t compassHeading = -1; |
|
116 | // compass course |
116 | |
- | 117 | // This is NOT updated from MM3. Negative angle indicates invalid data. |
|
- | 118 | int16_t compassCourse = -1; |
|
- | 119 | ||
117 | int16_t compassHeading = -1; // negative angle indicates invalid data. |
120 | // The difference between the above 2 (heading - course) on a -180..179 degree interval. |
- | 121 | // Not necessary. Never read anywhere. |
|
118 | int16_t compassCourse = -1; |
122 | // int16_t compassOffCourse = 0; |
119 | int16_t compassOffCourse = 0; |
123 | |
120 | uint16_t updateCompassCourse = 0; |
124 | uint8_t updateCompassCourse = 0; |
- | 125 | uint8_t compassCalState = 0; |
|
121 | uint8_t compassCalState = 0; |
126 | uint16_t ignoreCompassTimer = 500; |
122 | uint16_t badCompassHeading = 500; |
127 | |
Line 123... | Line 128... | ||
123 | int32_t yawGyroHeading; // Yaw Gyro Integral supported by compass |
128 | int32_t yawGyroHeading; // Yaw Gyro Integral supported by compass |
124 | int16_t yawGyroDrift; |
129 | int16_t yawGyroDrift; |
125 | 130 | ||
Line 126... | Line 131... | ||
126 | #define PITCHROLLOVER180 (GYRO_DEG_FACTOR_PITCHROLL * 180L) |
131 | #define PITCHROLLOVER180 (GYRO_DEG_FACTOR_PITCHROLL * 180L) |
Line 127... | Line 132... | ||
127 | #define PITCHROLLOVER360 (GYRO_DEG_FACTOR_PITCHROLL * 360L) |
132 | #define PITCHROLLOVER360 (GYRO_DEG_FACTOR_PITCHROLL * 360L) |
128 | #define YAWOVER360 (GYRO_DEG_FACTOR_YAW * 360L) |
133 | #define YAWOVER360 (GYRO_DEG_FACTOR_YAW * 360L) |
Line 129... | Line 134... | ||
129 | 134 | ||
130 | int16_t correctionSum[2] = {0,0}; |
135 | int16_t correctionSum[2] = { 0, 0 }; |
131 | 136 | ||
132 | // For NaviCTRL use. |
137 | // For NaviCTRL use. |
133 | int16_t averageAcc[2] = {0,0}, averageAccCount = 0; |
138 | int16_t averageAcc[2] = { 0, 0 }, averageAccCount = 0; |
134 | 139 | ||
135 | /* |
140 | /* |
Line 136... | Line 141... | ||
136 | * Experiment: Compensating for dynamic-induced gyro biasing. |
141 | * Experiment: Compensating for dynamic-induced gyro biasing. |
Line 149... | Line 154... | ||
149 | * constant speed, and 2) at small angles a, sin(a) ~= constant * a, |
154 | * constant speed, and 2) at small angles a, sin(a) ~= constant * a, |
150 | * it is hardly worth the trouble. |
155 | * it is hardly worth the trouble. |
151 | ************************************************************************/ |
156 | ************************************************************************/ |
Line 152... | Line 157... | ||
152 | 157 | ||
153 | int32_t getAngleEstimateFromAcc(uint8_t axis) { |
158 | int32_t getAngleEstimateFromAcc(uint8_t axis) { |
154 | return GYRO_ACC_FACTOR * (int32_t)filteredAcc[axis]; |
159 | return GYRO_ACC_FACTOR * (int32_t) filteredAcc[axis]; |
Line 155... | Line 160... | ||
155 | } |
160 | } |
156 | 161 | ||
157 | void setStaticAttitudeAngles(void) { |
162 | void setStaticAttitudeAngles(void) { |
158 | #ifdef ATTITUDE_USE_ACC_SENSORS |
163 | #ifdef ATTITUDE_USE_ACC_SENSORS |
159 | angle[PITCH] = getAngleEstimateFromAcc(PITCH); |
164 | angle[PITCH] = getAngleEstimateFromAcc(PITCH); |
160 | angle[ROLL] = getAngleEstimateFromAcc(ROLL); |
165 | angle[ROLL] = getAngleEstimateFromAcc(ROLL); |
161 | #else |
166 | #else |
162 | angle[PITCH] = angle[ROLL] = 0; |
167 | angle[PITCH] = angle[ROLL] = 0; |
Line 163... | Line 168... | ||
163 | #endif |
168 | #endif |
164 | } |
169 | } |
165 | 170 | ||
166 | /************************************************************************ |
171 | /************************************************************************ |
167 | * Neutral Readings |
172 | * Neutral Readings |
168 | ************************************************************************/ |
173 | ************************************************************************/ |
Line 169... | Line 174... | ||
169 | void attitude_setNeutral(void) { |
174 | void attitude_setNeutral(void) { |
170 | // Servo_Off(); // disable servo output. TODO: Why bother? The servos are going to make a jerk anyway. |
175 | // Servo_Off(); // disable servo output. TODO: Why bother? The servos are going to make a jerk anyway. |
171 | dynamicParams.AxisCoupling1 = dynamicParams.AxisCoupling2 = 0; |
- | |
172 | - | ||
173 | driftComp[PITCH] = driftComp[ROLL] = yawGyroDrift = driftCompYaw = 0; |
- | |
174 | correctionSum[PITCH] = correctionSum[ROLL] = 0; |
- | |
175 | - | ||
176 | // Calibrate hardware. |
- | |
177 | analog_calibrate(); |
- | |
178 | - | ||
179 | // reset gyro readings |
- | |
180 | // rate_ATT[PITCH] = rate_ATT[ROLL] = yawRate = 0; |
- | |
Line 181... | Line 176... | ||
181 | 176 | dynamicParams.AxisCoupling1 = dynamicParams.AxisCoupling2 = 0; |
|
182 | // reset gyro integrals to acc guessing |
177 | |
Line 183... | Line 178... | ||
183 | setStaticAttitudeAngles(); |
178 | driftComp[PITCH] = driftComp[ROLL] = yawGyroDrift = driftCompYaw = 0; |
184 | yawAngleDiff = 0; |
179 | correctionSum[PITCH] = correctionSum[ROLL] = 0; |
Line -... | Line 180... | ||
- | 180 | ||
- | 181 | // Calibrate hardware. |
|
- | 182 | analog_calibrate(); |
|
- | 183 | ||
- | 184 | // reset gyro readings |
|
- | 185 | // rate_ATT[PITCH] = rate_ATT[ROLL] = yawRate = 0; |
|
- | 186 | ||
- | 187 | // reset gyro integrals to acc guessing |
|
- | 188 | setStaticAttitudeAngles(); |
|
- | 189 | yawAngleDiff = 0; |
|
185 | 190 | ||
186 | // update compass course to current heading |
191 | // update compass course to current heading |
Line 187... | Line 192... | ||
187 | compassCourse = compassHeading; |
192 | compassCourse = compassHeading; |
188 | 193 | ||
189 | // Inititialize YawGyroIntegral value with current compass heading |
194 | // Inititialize YawGyroIntegral value with current compass heading |
190 | yawGyroHeading = (int32_t)compassHeading * GYRO_DEG_FACTOR_YAW; |
195 | yawGyroHeading = (int32_t) compassHeading * GYRO_DEG_FACTOR_YAW; |
191 | 196 | ||
192 | // Servo_On(); //enable servo output |
197 | // Servo_On(); //enable servo output |
193 | } |
198 | } |
194 | 199 | ||
195 | /************************************************************************ |
200 | /************************************************************************ |
196 | * Get sensor data from the analog module, and release the ADC |
201 | * Get sensor data from the analog module, and release the ADC |
197 | * TODO: Ultimately, the analog module could do this (instead of dumping |
202 | * TODO: Ultimately, the analog module could do this (instead of dumping |
- | 203 | * the values into variables). |
|
198 | * the values into variables). |
204 | * The rate variable end up in a range of about [-1024, 1023]. |
- | 205 | *************************************************************************/ |
|
199 | * The rate variable end up in a range of about [-1024, 1023]. |
206 | void getAnalogData(void) { |
200 | *************************************************************************/ |
207 | uint8_t axis; |
201 | void getAnalogData(void) { |
208 | |
202 | uint8_t axis; |
209 | for (axis = PITCH; axis <= ROLL; axis++) { |
203 | 210 | rate_PID[axis] = (gyro_PID[axis] + driftComp[axis]) |
|
204 | for (axis=PITCH; axis <=ROLL; axis++) { |
211 | / HIRES_GYRO_INTEGRATION_FACTOR; |
205 | rate_PID[axis] = (gyro_PID[axis] + driftComp[axis]) / HIRES_GYRO_INTEGRATION_FACTOR; |
212 | rate_ATT[axis] = (gyro_ATT[axis] + driftComp[axis]) |
206 | rate_ATT[axis] = (gyro_ATT[axis] + driftComp[axis]) / HIRES_GYRO_INTEGRATION_FACTOR; |
213 | / HIRES_GYRO_INTEGRATION_FACTOR; |
207 | differential[axis] = gyroD[axis]; |
214 | differential[axis] = gyroD[axis]; |
208 | averageAcc[axis] += acc[axis]; |
215 | averageAcc[axis] += acc[axis]; |
209 | } |
216 | } |
210 | 217 | ||
Line 211... | Line 218... | ||
211 | averageAccCount++; |
218 | averageAccCount++; |
212 | yawRate = yawGyro + driftCompYaw; |
219 | yawRate = yawGyro + driftCompYaw; |
213 | 220 | ||
214 | // We are done reading variables from the analog module. |
221 | // We are done reading variables from the analog module. |
215 | // Interrupt-driven sensor reading may restart. |
222 | // Interrupt-driven sensor reading may restart. |
216 | analogDataReady = 0; |
223 | analogDataReady = 0; |
217 | analog_start(); |
224 | analog_start(); |
218 | } |
225 | } |
219 | 226 | ||
220 | /* |
227 | /* |
221 | * This is the standard flight-style coordinate system transformation |
228 | * This is the standard flight-style coordinate system transformation |
222 | * (from airframe-local axes to a ground-based system). For some reason |
229 | * (from airframe-local axes to a ground-based system). For some reason |
223 | * the MK uses a left-hand coordinate system. The tranformation has been |
230 | * the MK uses a left-hand coordinate system. The tranformation has been |
- | 231 | * changed accordingly. |
|
224 | * changed accordingly. |
232 | */ |
- | 233 | void trigAxisCoupling(void) { |
|
- | 234 | int16_t cospitch = int_cos(angle[PITCH]); |
|
- | 235 | int16_t cosroll = int_cos(angle[ROLL]); |
|
225 | */ |
236 | int16_t sinroll = int_sin(angle[ROLL]); |
- | 237 | int16_t tanpitch = int_tan(angle[PITCH]); |
|
226 | void trigAxisCoupling(void) { |
238 | #define ANTIOVF 512 |
Line 227... | Line 239... | ||
227 | int16_t cospitch = int_cos(angle[PITCH]); |
239 | ACRate[PITCH] = ((int32_t) rate_ATT[PITCH] * cosroll - (int32_t) yawRate |
228 | int16_t cosroll = int_cos(angle[ROLL]); |
240 | * sinroll) / (int32_t) MATH_UNIT_FACTOR; |
229 | int16_t sinroll = int_sin(angle[ROLL]); |
241 | ACRate[ROLL] = rate_ATT[ROLL] + (((int32_t) rate_ATT[PITCH] * sinroll |
230 | int16_t tanpitch = int_tan(angle[PITCH]); |
242 | / ANTIOVF * tanpitch + (int32_t) yawRate * int_cos(angle[ROLL]) |
231 | #define ANTIOVF 512 |
243 | / ANTIOVF * tanpitch) / ((int32_t) MATH_UNIT_FACTOR / ANTIOVF |
232 | ACRate[PITCH] = ((int32_t) rate_ATT[PITCH] * cosroll - (int32_t)yawRate * sinroll) / (int32_t)MATH_UNIT_FACTOR; |
244 | * MATH_UNIT_FACTOR)); |
233 | ACRate[ROLL] = rate_ATT[ROLL] + (((int32_t)rate_ATT[PITCH] * sinroll / ANTIOVF * tanpitch + (int32_t)yawRate * int_cos(angle[ROLL]) / ANTIOVF * tanpitch) / ((int32_t)MATH_UNIT_FACTOR / ANTIOVF * MATH_UNIT_FACTOR)); |
245 | ACYawRate = ((int32_t) rate_ATT[PITCH] * sinroll) / cospitch |
234 | ACYawRate = ((int32_t) rate_ATT[PITCH] * sinroll) / cospitch + ((int32_t)yawRate * cosroll) / cospitch; |
246 | + ((int32_t) yawRate * cosroll) / cospitch; |
235 | } |
247 | } |
236 | 248 | ||
237 | // 480 usec with axis coupling - almost no time without. |
249 | // 480 usec with axis coupling - almost no time without. |
238 | void integrate(void) { |
250 | void integrate(void) { |
239 | // First, perform axis coupling. If disabled xxxRate is just copied to ACxxxRate. |
251 | // First, perform axis coupling. If disabled xxxRate is just copied to ACxxxRate. |
240 | uint8_t axis; |
252 | uint8_t axis; |
241 | if(!looping && (staticParams.GlobalConfig & CFG_AXIS_COUPLING_ACTIVE)) { |
253 | if (!looping && (staticParams.GlobalConfig & CFG_AXIS_COUPLING_ACTIVE)) { |
242 | // The rotary rate limiter bit is abused for selecting axis coupling algorithm instead. |
254 | // The rotary rate limiter bit is abused for selecting axis coupling algorithm instead. |
243 | trigAxisCoupling(); |
255 | trigAxisCoupling(); |
244 | } else { |
256 | } else { |
245 | ACRate[PITCH] = rate_ATT[PITCH]; |
257 | ACRate[PITCH] = rate_ATT[PITCH]; |
246 | ACRate[ROLL] = rate_ATT[ROLL]; |
258 | ACRate[ROLL] = rate_ATT[ROLL]; |
247 | ACYawRate = yawRate; |
259 | ACYawRate = yawRate; |
248 | } |
260 | } |
249 | 261 | ||
250 | /* |
262 | /* |
251 | * Yaw |
263 | * Yaw |
252 | * Calculate yaw gyro integral (~ to rotation angle) |
264 | * Calculate yaw gyro integral (~ to rotation angle) |
253 | * Limit yawGyroHeading proportional to 0 deg to 360 deg |
265 | * Limit yawGyroHeading proportional to 0 deg to 360 deg |
254 | */ |
266 | */ |
255 | yawGyroHeading += ACYawRate; |
267 | yawGyroHeading += ACYawRate; |
256 | yawAngleDiff += yawRate; |
268 | yawAngleDiff += yawRate; |
257 | 269 | ||
258 | if(yawGyroHeading >= YAWOVER360) { |
270 | if (yawGyroHeading >= YAWOVER360) { |
259 | yawGyroHeading -= YAWOVER360; // 360 deg. wrap |
271 | yawGyroHeading -= YAWOVER360; // 360 deg. wrap |
260 | } else if(yawGyroHeading < 0) { |
272 | } else if (yawGyroHeading < 0) { |
261 | yawGyroHeading += YAWOVER360; |
273 | yawGyroHeading += YAWOVER360; |
262 | } |
274 | } |
263 | 275 | ||
264 | /* |
276 | /* |
265 | * Pitch axis integration and range boundary wrap. |
277 | * Pitch axis integration and range boundary wrap. |
Line 266... | Line 278... | ||
266 | */ |
278 | */ |
267 | for (axis=PITCH; axis<=ROLL; axis++) { |
279 | for (axis = PITCH; axis <= ROLL; axis++) { |
268 | angle[axis] += ACRate[axis]; |
280 | angle[axis] += ACRate[axis]; |
269 | if(angle[axis] > PITCHROLLOVER180) { |
281 | if (angle[axis] > PITCHROLLOVER180) { |
270 | angle[axis] -= PITCHROLLOVER360; |
282 | angle[axis] -= PITCHROLLOVER360; |
271 | } else if (angle[axis] <= -PITCHROLLOVER180) { |
283 | } else if (angle[axis] <= -PITCHROLLOVER180) { |
272 | angle[axis] += PITCHROLLOVER360; |
284 | angle[axis] += PITCHROLLOVER360; |
273 | } |
285 | } |
274 | } |
286 | } |
275 | } |
287 | } |
276 | 288 | ||
277 | /************************************************************************ |
289 | /************************************************************************ |
278 | * A kind of 0'th order integral correction, that corrects the integrals |
290 | * A kind of 0'th order integral correction, that corrects the integrals |
279 | * directly. This is the "gyroAccFactor" stuff in the original code. |
291 | * directly. This is the "gyroAccFactor" stuff in the original code. |
- | 292 | * There is (there) also a drift compensation |
|
280 | * There is (there) also a drift compensation |
293 | * - it corrects the differential of the integral = the gyro offsets. |
281 | * - it corrects the differential of the integral = the gyro offsets. |
294 | * That should only be necessary with drifty gyros like ENC-03. |
282 | * That should only be necessary with drifty gyros like ENC-03. |
295 | ************************************************************************/ |
283 | ************************************************************************/ |
296 | void correctIntegralsByAcc0thOrder(void) { |
284 | void correctIntegralsByAcc0thOrder(void) { |
297 | // TODO: Consider changing this to: Only correct when integrals are less than ...., or only correct when angular velocities |
285 | // TODO: Consider changing this to: Only correct when integrals are less than ...., or only correct when angular velocities |
298 | // are less than ....., or reintroduce Kalman. |
286 | // are less than ....., or reintroduce Kalman. |
299 | // Well actually the Z axis acc. check is not so silly. |
287 | // Well actually the Z axis acc. check is not so silly. |
300 | uint8_t axis; |
288 | uint8_t axis; |
301 | int32_t correction; |
289 | int32_t correction; |
302 | if (!looping && acc[Z] >= -dynamicParams.UserParams[7] && acc[Z] |
290 | if(!looping && acc[Z] >= -dynamicParams.UserParams[7] && acc[Z] <= dynamicParams.UserParams[7]) { |
303 | <= dynamicParams.UserParams[7]) { |
291 | DebugOut.Digital[0] |= DEBUG_ACC0THORDER; |
304 | DebugOut.Digital[0] |= DEBUG_ACC0THORDER; |
292 | 305 | ||
293 | uint8_t permilleAcc = staticParams.GyroAccFactor; // NOTE!!! The meaning of this value has changed!! |
306 | uint8_t permilleAcc = staticParams.GyroAccFactor; // NOTE!!! The meaning of this value has changed!! |
294 | uint8_t debugFullWeight = 1; |
307 | uint8_t debugFullWeight = 1; |
295 | int32_t accDerived; |
308 | int32_t accDerived; |
296 | 309 | ||
297 | if((controlYaw < -64) || (controlYaw > 64)) { // reduce further if yaw stick is active |
310 | if ((controlYaw < -64) || (controlYaw > 64)) { // reduce further if yaw stick is active |
298 | permilleAcc /= 2; |
311 | permilleAcc /= 2; |
299 | debugFullWeight = 0; |
312 | debugFullWeight = 0; |
300 | } |
313 | } |
301 | 314 | ||
302 | if((maxControl[PITCH] > 64) || (maxControl[ROLL] > 64)) { // reduce effect during stick commands |
315 | if ((maxControl[PITCH] > 64) || (maxControl[ROLL] > 64)) { // reduce effect during stick commands |
303 | permilleAcc /= 2; |
316 | permilleAcc /= 2; |
304 | debugFullWeight = 0; |
317 | debugFullWeight = 0; |
305 | } |
318 | } |
306 | 319 | ||
- | 320 | if (debugFullWeight) |
|
307 | if (debugFullWeight) |
321 | DebugOut.Digital[1] |= DEBUG_ACC0THORDER; |
308 | DebugOut.Digital[1] |= DEBUG_ACC0THORDER; |
322 | else |
309 | else |
323 | DebugOut.Digital[1] &= ~DEBUG_ACC0THORDER; |
310 | DebugOut.Digital[1] &= ~DEBUG_ACC0THORDER; |
324 | |
- | 325 | /* |
|
311 | 326 | * Add to each sum: The amount by which the angle is changed just below. |
|
312 | /* |
327 | */ |
313 | * Add to each sum: The amount by which the angle is changed just below. |
328 | for (axis = PITCH; axis <= ROLL; axis++) { |
314 | */ |
329 | accDerived = getAngleEstimateFromAcc(axis); |
315 | for (axis=PITCH; axis<=ROLL; axis++) { |
330 | DebugOut.Analog[9 + axis] = (10 * accDerived) |
316 | accDerived = getAngleEstimateFromAcc(axis); |
331 | / GYRO_DEG_FACTOR_PITCHROLL; |
317 | DebugOut.Analog[9 + axis] = (10 * accDerived) / GYRO_DEG_FACTOR_PITCHROLL; |
332 | |
318 | 333 | // 1000 * the correction amount that will be added to the gyro angle in next line. |
|
319 | // 1000 * the correction amount that will be added to the gyro angle in next line. |
334 | correction = angle[axis]; //(permilleAcc * (accDerived - angle[axis])) / 1000; |
320 | correction = angle[axis]; //(permilleAcc * (accDerived - angle[axis])) / 1000; |
335 | angle[axis] = ((int32_t) (1000L - permilleAcc) * angle[axis] |
321 | angle[axis] = ((int32_t)(1000L - permilleAcc) * angle[axis] + (int32_t)permilleAcc * accDerived) / 1000L; |
336 | + (int32_t) permilleAcc * accDerived) / 1000L; |
322 | correctionSum[axis] += angle[axis] - correction; |
337 | correctionSum[axis] += angle[axis] - correction; |
323 | DebugOut.Analog[16+axis] = angle[axis] - correction; |
338 | DebugOut.Analog[16 + axis] = angle[axis] - correction; |
324 | } |
339 | } |
325 | } else { |
340 | } else { |
Line 326... | Line 341... | ||
326 | DebugOut.Digital[0] &= ~DEBUG_ACC0THORDER; |
341 | DebugOut.Digital[0] &= ~DEBUG_ACC0THORDER; |
327 | DebugOut.Digital[1] &= ~DEBUG_ACC0THORDER; |
342 | DebugOut.Digital[1] &= ~DEBUG_ACC0THORDER; |
328 | DebugOut.Analog[9] = 0; |
343 | DebugOut.Analog[9] = 0; |
Line 346... | Line 361... | ||
346 | * the error. This is then added to the dynamic offsets. |
361 | * the error. This is then added to the dynamic offsets. |
347 | ************************************************************************/ |
362 | ************************************************************************/ |
348 | // 2 times / sec. = 488/2 |
363 | // 2 times / sec. = 488/2 |
349 | #define DRIFTCORRECTION_TIME 256L |
364 | #define DRIFTCORRECTION_TIME 256L |
350 | void driftCorrection(void) { |
365 | void driftCorrection(void) { |
351 | static int16_t timer = DRIFTCORRECTION_TIME; |
366 | static int16_t timer = DRIFTCORRECTION_TIME; |
352 | int16_t deltaCorrection; |
367 | int16_t deltaCorrection; |
353 | uint8_t axis; |
368 | uint8_t axis; |
354 | if (! --timer) { |
369 | if (!--timer) { |
355 | timer = DRIFTCORRECTION_TIME; |
370 | timer = DRIFTCORRECTION_TIME; |
356 | for (axis=PITCH; axis<=ROLL; axis++) { |
371 | for (axis = PITCH; axis <= ROLL; axis++) { |
357 | // Take the sum of corrections applied, add it to delta |
372 | // Take the sum of corrections applied, add it to delta |
- | 373 | deltaCorrection = (correctionSum[axis] |
|
358 | deltaCorrection = (correctionSum[axis] * HIRES_GYRO_INTEGRATION_FACTOR + DRIFTCORRECTION_TIME / 2) / DRIFTCORRECTION_TIME; |
374 | * HIRES_GYRO_INTEGRATION_FACTOR + DRIFTCORRECTION_TIME / 2) |
- | 375 | / DRIFTCORRECTION_TIME; |
|
359 | // Add the delta to the compensation. So positive delta means, gyro should have higher value. |
376 | // Add the delta to the compensation. So positive delta means, gyro should have higher value. |
360 | driftComp[axis] += deltaCorrection / staticParams.GyroAccTrim; |
377 | driftComp[axis] += deltaCorrection / staticParams.GyroAccTrim; |
361 | CHECK_MIN_MAX(driftComp[axis], -staticParams.DriftComp, staticParams.DriftComp); |
378 | CHECK_MIN_MAX(driftComp[axis], -staticParams.DriftComp, staticParams.DriftComp); |
362 | // DebugOut.Analog[11 + axis] = correctionSum[axis]; |
379 | // DebugOut.Analog[11 + axis] = correctionSum[axis]; |
363 | 380 | ||
364 | DebugOut.Analog[18+axis] = deltaCorrection / staticParams.GyroAccTrim; |
381 | DebugOut.Analog[18 + axis] = deltaCorrection |
- | 382 | / staticParams.GyroAccTrim; |
|
365 | DebugOut.Analog[28+axis] = driftComp[axis]; |
383 | DebugOut.Analog[28 + axis] = driftComp[axis]; |
366 | 384 | ||
367 | correctionSum[axis] = 0; |
385 | correctionSum[axis] = 0; |
368 | } |
386 | } |
369 | } |
387 | } |
370 | } |
388 | } |
Line 371... | Line 389... | ||
371 | 389 | ||
372 | /************************************************************************ |
390 | /************************************************************************ |
373 | * Main procedure. |
391 | * Main procedure. |
374 | ************************************************************************/ |
392 | ************************************************************************/ |
375 | void calculateFlightAttitude(void) { |
393 | void calculateFlightAttitude(void) { |
376 | // part1: 550 usec. |
394 | // part1: 550 usec. |
377 | // part1a: 550 usec. |
395 | // part1a: 550 usec. |
378 | // part1b: 60 usec. |
396 | // part1b: 60 usec. |
379 | getAnalogData(); |
397 | getAnalogData(); |
380 | // end part1b |
398 | // end part1b |
381 | integrate(); |
399 | integrate(); |
382 | // end part1a |
400 | // end part1a |
383 | 401 | ||
384 | 402 | ||
385 | DebugOut.Analog[6] = ACRate[PITCH]; |
403 | DebugOut.Analog[6] = ACRate[PITCH]; |
386 | DebugOut.Analog[7] = ACRate[ROLL]; |
404 | DebugOut.Analog[7] = ACRate[ROLL]; |
387 | DebugOut.Analog[8] = ACYawRate; |
405 | DebugOut.Analog[8] = ACYawRate; |
388 | 406 | ||
389 | DebugOut.Analog[3] = rate_PID[PITCH]; |
407 | DebugOut.Analog[3] = rate_PID[PITCH]; |
390 | DebugOut.Analog[4] = rate_PID[ROLL]; |
408 | DebugOut.Analog[4] = rate_PID[ROLL]; |
391 | DebugOut.Analog[5] = yawRate; |
409 | DebugOut.Analog[5] = yawRate; |
392 | 410 | ||
393 | #ifdef ATTITUDE_USE_ACC_SENSORS |
411 | #ifdef ATTITUDE_USE_ACC_SENSORS |
394 | correctIntegralsByAcc0thOrder(); |
412 | correctIntegralsByAcc0thOrder(); |
395 | driftCorrection(); |
413 | driftCorrection(); |
396 | #endif |
414 | #endif |
397 | // end part1 |
415 | // end part1 |
Line 398... | Line 416... | ||
398 | } |
416 | } |
399 | 417 | ||
400 | void updateCompass(void) { |
418 | void updateCompass(void) { |
401 | int16_t w, v, r,correction, error; |
419 | int16_t w, v, r, correction, error; |
402 | 420 | ||
403 | if(compassCalState && !(MKFlags & MKFLAG_MOTOR_RUN)) { |
421 | if (compassCalState && !(MKFlags & MKFLAG_MOTOR_RUN)) { |
- | 422 | if (controlMixer_testCompassCalState()) { |
|
404 | if (controlMixer_testCompassCalState()) { |
423 | compassCalState++; |
- | 424 | if (compassCalState < 5) |
|
405 | compassCalState++; |
425 | beepNumber(compassCalState); |
406 | if(compassCalState < 5) beepNumber(compassCalState); |
426 | else |
407 | else beep(1000); |
427 | beep(1000); |
408 | } |
428 | } |
409 | } else { |
429 | } else { |
410 | // get maximum attitude angle |
430 | // get maximum attitude angle |
411 | w = abs(angle[PITCH] / 512); |
431 | w = abs(angle[PITCH] / 512); |
- | 432 | v = abs(angle[ROLL] / 512); |
|
412 | v = abs(angle[ROLL] / 512); |
433 | if (v > w) |
413 | if(v > w) w = v; |
434 | w = v; |
- | 435 | correction = w/8 + 1; |
|
414 | correction = w / 8 + 1; |
436 | // calculate the deviation of the yaw gyro heading and the compass heading |
415 | // calculate the deviation of the yaw gyro heading and the compass heading |
- | |
- | 437 | if (compassHeading < 0) |
|
416 | if (compassHeading < 0) error = 0; // disable yaw drift compensation if compass heading is undefined |
438 | error = 0; // disable yaw drift compensation if compass heading is undefined |
417 | else error = ((540 + compassHeading - (yawGyroHeading / GYRO_DEG_FACTOR_YAW)) % 360) - 180; |
439 | else |
- | 440 | if (abs(yawRate) > 128) { // spinning fast |
|
- | 441 | error = 0; |
|
- | 442 | } else { |
|
418 | if(abs(yawRate) > 128) { // spinning fast |
443 | // compassHeading - yawGyroHeading, on a -180..179 deg interval. |
419 | error = 0; |
444 | error = ((540 + compassHeading - (yawGyroHeading / GYRO_DEG_FACTOR_YAW)) % 360) - 180; |
420 | } |
445 | } |
- | 446 | if (!ignoreCompassTimer && w < 25) { |
|
421 | if(!badCompassHeading && w < 25) { |
447 | yawGyroDrift += error; |
422 | yawGyroDrift += error; |
448 | // Basically this gets set if we are in "fix" mode, and when starting. |
423 | if(updateCompassCourse) { |
449 | if (updateCompassCourse) { |
424 | beep(200); |
450 | beep(200); |
425 | yawGyroHeading = (int32_t)compassHeading * GYRO_DEG_FACTOR_YAW; |
451 | yawGyroHeading = (int32_t) compassHeading * GYRO_DEG_FACTOR_YAW; |
426 | compassCourse = compassHeading; //(int16_t)(yawGyroHeading / GYRO_DEG_FACTOR_YAW); |
452 | compassCourse = compassHeading; //(int16_t)(yawGyroHeading / GYRO_DEG_FACTOR_YAW); |
427 | updateCompassCourse = 0; |
453 | updateCompassCourse = 0; |
428 | } |
454 | } |
- | 455 | } |
|
- | 456 | yawGyroHeading += (error * 8) / correction; |
|
429 | } |
457 | |
430 | yawGyroHeading += (error * 8) / correction; |
458 | /* |
- | 459 | w = (w * dynamicParams.CompassYawEffect) / 32; |
|
- | 460 | w = dynamicParams.CompassYawEffect - w; |
|
- | 461 | */ |
|
431 | w = (w * dynamicParams.CompassYawEffect) / 32; |
462 | w = dynamicParams.CompassYawEffect - (w * dynamicParams.CompassYawEffect) / 32; |
- | 463 | ||
- | 464 | // As readable formula: |
|
- | 465 | // w = dynamicParams.CompassYawEffect * (1-w/32); |
|
432 | w = dynamicParams.CompassYawEffect - w; |
466 | |
433 | if(w >= 0) { |
467 | if (w >= 0) { // maxAttitudeAngle < 32 |
434 | if(!badCompassHeading) { |
468 | if (!ignoreCompassTimer) { |
435 | v = 64 + (maxControl[PITCH] + maxControl[ROLL]) / 8; |
469 | v = 64 + (maxControl[PITCH] + maxControl[ROLL]) / 8; |
436 | // calc course deviation |
470 | // yawGyroHeading - compassCourse on a -180..179 degree interval. |
437 | r = ((540 + (yawGyroHeading / GYRO_DEG_FACTOR_YAW) - compassCourse) % 360) - 180; |
471 | r = ((540 + yawGyroHeading / GYRO_DEG_FACTOR_YAW - compassCourse) % 360) - 180; |
438 | v = (r * w) / v; // align to compass course |
472 | v = (r * w) / v; // align to compass course |
439 | // limit yaw rate |
473 | // limit yaw rate |
- | 474 | w = 3 * dynamicParams.CompassYawEffect; |
|
440 | w = 3 * dynamicParams.CompassYawEffect; |
475 | if (v > w) |
- | 476 | v = w; |
|
441 | if (v > w) v = w; |
477 | else if (v < -w) |
442 | else if (v < -w) v = -w; |
478 | v = -w; |
- | 479 | yawAngleDiff += v; |
|
443 | yawAngleDiff += v; |
480 | } else { // wait a while |
444 | } |
481 | ignoreCompassTimer--; |
445 | else |
482 | } |
- | 483 | } else { // ignore compass at extreme attitudes for a while |
|
446 | { // wait a while |
484 | ignoreCompassTimer = 500; |
447 | badCompassHeading--; |
- | |
448 | } |
- | |
449 | } else { // ignore compass at extreme attitudes for a while |
- | |
450 | badCompassHeading = 500; |
- | |
451 | } |
485 | } |
Line 452... | Line 486... | ||
452 | } |
486 | } |
453 | } |
487 | } |
454 | 488 | ||
Line 459... | Line 493... | ||
459 | * will measure the effect of vibration, to use for later compensation. So, one should keep |
493 | * will measure the effect of vibration, to use for later compensation. So, one should keep |
460 | * the stick in the start-motors position for a few seconds, till all motors run (at the wrong |
494 | * the stick in the start-motors position for a few seconds, till all motors run (at the wrong |
461 | * speed unfortunately... must find a better way) |
495 | * speed unfortunately... must find a better way) |
462 | */ |
496 | */ |
463 | /* |
497 | /* |
464 | void attitude_startDynamicCalibration(void) { |
498 | void attitude_startDynamicCalibration(void) { |
465 | dynamicCalPitch = dynamicCalRoll = dynamicCalYaw = dynamicCalCount = 0; |
499 | dynamicCalPitch = dynamicCalRoll = dynamicCalYaw = dynamicCalCount = 0; |
466 | savedDynamicOffsetPitch = savedDynamicOffsetRoll = 1000; |
500 | savedDynamicOffsetPitch = savedDynamicOffsetRoll = 1000; |
467 | } |
501 | } |
468 | 502 | ||
469 | void attitude_continueDynamicCalibration(void) { |
503 | void attitude_continueDynamicCalibration(void) { |
470 | // measure dynamic offset now... |
504 | // measure dynamic offset now... |
471 | dynamicCalPitch += hiResPitchGyro; |
505 | dynamicCalPitch += hiResPitchGyro; |
472 | dynamicCalRoll += hiResRollGyro; |
506 | dynamicCalRoll += hiResRollGyro; |
473 | dynamicCalYaw += rawYawGyroSum; |
507 | dynamicCalYaw += rawYawGyroSum; |
474 | dynamicCalCount++; |
508 | dynamicCalCount++; |
475 | |
509 | |
476 | // Param6: Manual mode. The offsets are taken from Param7 and Param8. |
510 | // Param6: Manual mode. The offsets are taken from Param7 and Param8. |
477 | if (dynamicParams.UserParam6 || 1) { // currently always enabled. |
511 | if (dynamicParams.UserParam6 || 1) { // currently always enabled. |
478 | // manual mode |
512 | // manual mode |
479 | driftCompPitch = dynamicParams.UserParam7 - 128; |
513 | driftCompPitch = dynamicParams.UserParam7 - 128; |
480 | driftCompRoll = dynamicParams.UserParam8 - 128; |
514 | driftCompRoll = dynamicParams.UserParam8 - 128; |
481 | } else { |
515 | } else { |
482 | // use the sampled value (does not seem to work so well....) |
516 | // use the sampled value (does not seem to work so well....) |
483 | driftCompPitch = savedDynamicOffsetPitch = -dynamicCalPitch / dynamicCalCount; |
517 | driftCompPitch = savedDynamicOffsetPitch = -dynamicCalPitch / dynamicCalCount; |
484 | driftCompRoll = savedDynamicOffsetRoll = -dynamicCalRoll / dynamicCalCount; |
518 | driftCompRoll = savedDynamicOffsetRoll = -dynamicCalRoll / dynamicCalCount; |
485 | driftCompYaw = -dynamicCalYaw / dynamicCalCount; |
519 | driftCompYaw = -dynamicCalYaw / dynamicCalCount; |
486 | } |
520 | } |
487 | |
521 | |
488 | // keep resetting these meanwhile, to avoid accumulating errors. |
522 | // keep resetting these meanwhile, to avoid accumulating errors. |
489 | setStaticAttitudeIntegrals(); |
523 | setStaticAttitudeIntegrals(); |
490 | yawAngle = 0; |
524 | yawAngle = 0; |
491 | } |
525 | } |
492 | */ |
526 | */ |