Rev 1646 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1646 | Rev 1775 | ||
---|---|---|---|
Line 57... | Line 57... | ||
57 | #include <avr/io.h> |
57 | #include <avr/io.h> |
Line 58... | Line 58... | ||
58 | 58 | ||
59 | #include "attitude.h" |
59 | #include "attitude.h" |
Line -... | Line 60... | ||
- | 60 | #include "dongfangMath.h" |
|
- | 61 | ||
- | 62 | // For scope debugging only! |
|
60 | #include "dongfangMath.h" |
63 | #include "rc.h" |
61 | 64 | ||
Line 62... | Line 65... | ||
62 | // where our main data flow comes from. |
65 | // where our main data flow comes from. |
- | 66 | #include "analog.h" |
|
Line 63... | Line 67... | ||
63 | #include "analog.h" |
67 | |
64 | 68 | #include "configuration.h" |
|
Line 65... | Line 69... | ||
65 | #include "configuration.h" |
69 | #include "output.h" |
Line 82... | Line 86... | ||
82 | * things functionally without side effects) but this is shorter and probably |
86 | * things functionally without side effects) but this is shorter and probably |
83 | * faster too. |
87 | * faster too. |
84 | * The variables are overwritten at each attitude calculation invocation - the values |
88 | * The variables are overwritten at each attitude calculation invocation - the values |
85 | * are not preserved or reused. |
89 | * are not preserved or reused. |
86 | */ |
90 | */ |
87 | int16_t rate[2], yawRate; |
91 | int16_t rate_ATT[2], yawRate; |
Line 88... | Line 92... | ||
88 | 92 | ||
89 | // With different (less) filtering |
93 | // With different (less) filtering |
90 | int16_t rate_PID[2]; |
94 | int16_t rate_PID[2]; |
Line 103... | Line 107... | ||
103 | 107 | ||
104 | /* |
108 | /* |
105 | * Gyro integrals. These are the rotation angles of the airframe compared to the |
109 | * Gyro integrals. These are the rotation angles of the airframe compared to the |
106 | * horizontal plane, yaw relative to yaw at start. |
110 | * horizontal plane, yaw relative to yaw at start. |
107 | */ |
111 | */ |
Line 108... | Line 112... | ||
108 | int32_t angle[2], yawAngle; |
112 | int32_t angle[2], yawAngleDiff; |
Line 109... | Line 113... | ||
109 | 113 | ||
110 | int readingHeight = 0; |
114 | int readingHeight = 0; |
111 | 115 | ||
112 | // compass course |
116 | // compass course |
113 | int16_t compassHeading = -1; // negative angle indicates invalid data. |
117 | int16_t compassHeading = -1; // negative angle indicates invalid data. |
114 | int16_t compassCourse = -1; |
118 | int16_t compassCourse = -1; |
115 | int16_t compassOffCourse = 0; |
- | |
116 | uint16_t updateCompassCourse = 0; |
- | |
117 | uint8_t compassCalState = 0; |
119 | int16_t compassOffCourse = 0; |
118 | 120 | uint16_t updateCompassCourse = 0; |
|
- | 121 | uint8_t compassCalState = 0; |
|
Line 119... | Line 122... | ||
119 | // uint8_t FunnelCourse = 0; |
122 | uint16_t badCompassHeading = 500; |
120 | uint16_t badCompassHeading = 500; |
123 | int32_t yawGyroHeading; // Yaw Gyro Integral supported by compass |
121 | int32_t yawGyroHeading; // Yaw Gyro Integral supported by compass |
124 | int16_t yawGyroDrift; |
Line 122... | Line 125... | ||
122 | 125 | ||
Line -... | Line 126... | ||
- | 126 | #define PITCHROLLOVER180 (GYRO_DEG_FACTOR_PITCHROLL * 180L) |
|
- | 127 | #define PITCHROLLOVER360 (GYRO_DEG_FACTOR_PITCHROLL * 360L) |
|
- | 128 | #define YAWOVER360 (GYRO_DEG_FACTOR_YAW * 360L) |
|
123 | #define PITCHROLLOVER180 (GYRO_DEG_FACTOR_PITCHROLL * 180L) |
129 | |
124 | #define PITCHROLLOVER360 (GYRO_DEG_FACTOR_PITCHROLL * 360L) |
130 | int16_t correctionSum[2] = {0,0}; |
125 | #define YAWOVER360 (GYRO_DEG_FACTOR_YAW * 360L) |
131 | |
126 | 132 | // For NaviCTRL use. |
|
127 | int16_t correctionSum[2] = {0,0}; |
133 | int16_t averageAcc[2] = {0,0}, averageAccCount = 0; |
128 | 134 | ||
129 | /* |
135 | /* |
Line 130... | Line 136... | ||
130 | * Experiment: Compensating for dynamic-induced gyro biasing. |
136 | * Experiment: Compensating for dynamic-induced gyro biasing. |
Line 162... | Line 168... | ||
162 | ************************************************************************/ |
168 | ************************************************************************/ |
163 | void attitude_setNeutral(void) { |
169 | void attitude_setNeutral(void) { |
164 | // Servo_Off(); // disable servo output. TODO: Why bother? The servos are going to make a jerk anyway. |
170 | // Servo_Off(); // disable servo output. TODO: Why bother? The servos are going to make a jerk anyway. |
165 | dynamicParams.AxisCoupling1 = dynamicParams.AxisCoupling2 = 0; |
171 | dynamicParams.AxisCoupling1 = dynamicParams.AxisCoupling2 = 0; |
Line 166... | Line 172... | ||
166 | 172 | ||
167 | dynamicOffset[PITCH] = dynamicOffset[ROLL] = 0; |
173 | driftComp[PITCH] = driftComp[ROLL] = yawGyroDrift = driftCompYaw = 0; |
Line 168... | Line 174... | ||
168 | correctionSum[PITCH] = correctionSum[ROLL] = 0; |
174 | correctionSum[PITCH] = correctionSum[ROLL] = 0; |
169 | 175 | ||
170 | // Calibrate hardware. |
176 | // Calibrate hardware. |
171 | analog_calibrate(); |
177 | analog_calibrate(); |
172 | 178 | ||
Line 173... | Line 179... | ||
173 | // reset gyro readings |
179 | // reset gyro readings |
174 | rate[PITCH] = rate[ROLL] = yawRate = 0; |
180 | // rate_ATT[PITCH] = rate_ATT[ROLL] = yawRate = 0; |
175 | 181 | ||
Line 176... | Line 182... | ||
176 | // reset gyro integrals to acc guessing |
182 | // reset gyro integrals to acc guessing |
177 | setStaticAttitudeAngles(); |
183 | setStaticAttitudeAngles(); |
Line 178... | Line 184... | ||
178 | yawAngle = 0; |
184 | yawAngleDiff = 0; |
Line 189... | Line 195... | ||
189 | /************************************************************************ |
195 | /************************************************************************ |
190 | * Get sensor data from the analog module, and release the ADC |
196 | * Get sensor data from the analog module, and release the ADC |
191 | * TODO: Ultimately, the analog module could do this (instead of dumping |
197 | * TODO: Ultimately, the analog module could do this (instead of dumping |
192 | * the values into variables). |
198 | * the values into variables). |
193 | * The rate variable end up in a range of about [-1024, 1023]. |
199 | * The rate variable end up in a range of about [-1024, 1023]. |
194 | * When scaled down by CONTROL_SCALING, the interval is about [-256, 256]. |
- | |
195 | *************************************************************************/ |
200 | *************************************************************************/ |
196 | void getAnalogData(void) { |
201 | void getAnalogData(void) { |
197 | uint8_t axis; |
202 | uint8_t axis; |
Line 198... | Line 203... | ||
198 | 203 | ||
199 | for (axis=PITCH; axis <=ROLL; axis++) { |
204 | for (axis=PITCH; axis <=ROLL; axis++) { |
200 | rate_PID[axis] = (gyro_PID[axis] + dynamicOffset[axis]) / HIRES_GYRO_INTEGRATION_FACTOR; |
205 | rate_PID[axis] = (gyro_PID[axis] + driftComp[axis]) / HIRES_GYRO_INTEGRATION_FACTOR; |
201 | rate[axis] = (gyro_ATT[axis] + dynamicOffset[axis]) / HIRES_GYRO_INTEGRATION_FACTOR; |
206 | rate_ATT[axis] = (gyro_ATT[axis] + driftComp[axis]) / HIRES_GYRO_INTEGRATION_FACTOR; |
- | 207 | differential[axis] = gyroD[axis]; |
|
202 | differential[axis] = gyroD[axis]; |
208 | averageAcc[axis] += acc[axis]; |
203 | } |
209 | } |
- | 210 | ||
204 | 211 | averageAccCount++; |
|
Line 205... | Line 212... | ||
205 | yawRate = yawGyro + dynamicOffsetYaw; |
212 | yawRate = yawGyro + driftCompYaw; |
206 | 213 | ||
207 | // We are done reading variables from the analog module. |
214 | // We are done reading variables from the analog module. |
208 | // Interrupt-driven sensor reading may restart. |
215 | // Interrupt-driven sensor reading may restart. |
Line 219... | Line 226... | ||
219 | void trigAxisCoupling(void) { |
226 | void trigAxisCoupling(void) { |
220 | int16_t cospitch = int_cos(angle[PITCH]); |
227 | int16_t cospitch = int_cos(angle[PITCH]); |
221 | int16_t cosroll = int_cos(angle[ROLL]); |
228 | int16_t cosroll = int_cos(angle[ROLL]); |
222 | int16_t sinroll = int_sin(angle[ROLL]); |
229 | int16_t sinroll = int_sin(angle[ROLL]); |
223 | int16_t tanpitch = int_tan(angle[PITCH]); |
230 | int16_t tanpitch = int_tan(angle[PITCH]); |
224 | #define ANTIOVF 1024 |
231 | #define ANTIOVF 512 |
225 | ACRate[PITCH] = ((int32_t) rate[PITCH] * cosroll - (int32_t)yawRate * sinroll) / (int32_t)MATH_UNIT_FACTOR; |
232 | ACRate[PITCH] = ((int32_t) rate_ATT[PITCH] * cosroll - (int32_t)yawRate * sinroll) / (int32_t)MATH_UNIT_FACTOR; |
226 | ACRate[ROLL] = rate[ROLL] + (((int32_t)rate[PITCH] * sinroll / ANTIOVF * tanpitch + (int32_t)yawRate * int_cos(angle[ROLL]) / ANTIOVF * tanpitch) / ((int32_t)MATH_UNIT_FACTOR / ANTIOVF * 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)); |
227 | ACYawRate = ((int32_t) rate[PITCH] * sinroll) / cospitch + ((int32_t)yawRate * cosroll) / cospitch; |
234 | ACYawRate = ((int32_t) rate_ATT[PITCH] * sinroll) / cospitch + ((int32_t)yawRate * cosroll) / cospitch; |
228 | } |
235 | } |
Line -... | Line 236... | ||
- | 236 | ||
229 | 237 | // 480 usec with axis coupling - almost no time without. |
|
230 | void integrate(void) { |
238 | void integrate(void) { |
231 | // First, perform axis coupling. If disabled xxxRate is just copied to ACxxxRate. |
239 | // First, perform axis coupling. If disabled xxxRate is just copied to ACxxxRate. |
232 | uint8_t axis; |
- | |
233 | 240 | uint8_t axis; |
|
234 | if(!looping && (staticParams.GlobalConfig & CFG_AXIS_COUPLING_ACTIVE)) { |
241 | if(!looping && (staticParams.GlobalConfig & CFG_AXIS_COUPLING_ACTIVE)) { |
235 | // The rotary rate limiter bit is abused for selecting axis coupling algorithm instead. |
242 | // The rotary rate limiter bit is abused for selecting axis coupling algorithm instead. |
236 | trigAxisCoupling(); |
243 | trigAxisCoupling(); |
237 | } else { |
244 | } else { |
238 | ACRate[PITCH] = rate[PITCH]; |
245 | ACRate[PITCH] = rate_ATT[PITCH]; |
239 | ACRate[ROLL] = rate[ROLL]; |
246 | ACRate[ROLL] = rate_ATT[ROLL]; |
240 | ACYawRate = yawRate; |
247 | ACYawRate = yawRate; |
Line 241... | Line 248... | ||
241 | } |
248 | } |
242 | 249 | ||
243 | /* |
250 | /* |
244 | * Yaw |
251 | * Yaw |
245 | * Calculate yaw gyro integral (~ to rotation angle) |
252 | * Calculate yaw gyro integral (~ to rotation angle) |
246 | * Limit yawGyroHeading proportional to 0 deg to 360 deg |
253 | * Limit yawGyroHeading proportional to 0 deg to 360 deg |
247 | */ |
- | |
248 | yawGyroHeading += ACYawRate; |
- | |
249 | 254 | */ |
|
Line 250... | Line 255... | ||
250 | // Why is yawAngle not wrapped 'round? |
255 | yawGyroHeading += ACYawRate; |
251 | yawAngle += ACYawRate; |
256 | yawAngleDiff += yawRate; |
252 | 257 | ||
253 | if(yawGyroHeading >= YAWOVER360) { |
258 | if(yawGyroHeading >= YAWOVER360) { |
Line 281... | Line 286... | ||
281 | // are less than ....., or reintroduce Kalman. |
286 | // are less than ....., or reintroduce Kalman. |
282 | // Well actually the Z axis acc. check is not so silly. |
287 | // Well actually the Z axis acc. check is not so silly. |
283 | uint8_t axis; |
288 | uint8_t axis; |
284 | int32_t correction; |
289 | int32_t correction; |
285 | if(!looping && acc[Z] >= -dynamicParams.UserParams[7] && acc[Z] <= dynamicParams.UserParams[7]) { |
290 | if(!looping && acc[Z] >= -dynamicParams.UserParams[7] && acc[Z] <= dynamicParams.UserParams[7]) { |
286 | DebugOut.Digital[0] = 1; |
291 | DebugOut.Digital[0] |= DEBUG_ACC0THORDER; |
Line 287... | Line 292... | ||
287 | 292 | ||
288 | uint8_t permilleAcc = staticParams.GyroAccFactor; // NOTE!!! The meaning of this value has changed!! |
293 | uint8_t permilleAcc = staticParams.GyroAccFactor; // NOTE!!! The meaning of this value has changed!! |
289 | uint8_t debugFullWeight = 1; |
294 | uint8_t debugFullWeight = 1; |
Line 290... | Line 295... | ||
290 | int32_t accDerived; |
295 | int32_t accDerived; |
291 | 296 | ||
292 | if((maxControl[PITCH] > 64) || (maxControl[ROLL] > 64)) { // reduce effect during stick commands |
297 | if((controlYaw < -64) || (controlYaw > 64)) { // reduce further if yaw stick is active |
293 | permilleAcc /= 2; |
298 | permilleAcc /= 2; |
294 | debugFullWeight = 0; |
299 | debugFullWeight = 0; |
295 | } |
300 | } |
296 | 301 | ||
297 | if(abs(controlYaw) > 25) { // reduce further if yaw stick is active |
302 | if((maxControl[PITCH] > 64) || (maxControl[ROLL] > 64)) { // reduce effect during stick commands |
298 | permilleAcc /= 2; |
303 | permilleAcc /= 2; |
- | 304 | debugFullWeight = 0; |
|
- | 305 | } |
|
- | 306 | ||
- | 307 | if (debugFullWeight) |
|
- | 308 | DebugOut.Digital[1] |= DEBUG_ACC0THORDER; |
|
Line 299... | Line 309... | ||
299 | debugFullWeight = 0; |
309 | else |
300 | } |
310 | DebugOut.Digital[1] &= ~DEBUG_ACC0THORDER; |
301 | 311 | ||
302 | /* |
312 | /* |
303 | * Add to each sum: The amount by which the angle is changed just below. |
313 | * Add to each sum: The amount by which the angle is changed just below. |
304 | */ |
314 | */ |
305 | for (axis=PITCH; axis<=ROLL; axis++) { |
315 | for (axis=PITCH; axis<=ROLL; axis++) { |
306 | accDerived = getAngleEstimateFromAcc(axis); |
316 | accDerived = getAngleEstimateFromAcc(axis); |
307 | DebugOut.Analog[9 + axis] = (10 * accDerived) / GYRO_DEG_FACTOR_PITCHROLL; |
317 | DebugOut.Analog[9 + axis] = (10 * accDerived) / GYRO_DEG_FACTOR_PITCHROLL; |
308 | 318 | ||
309 | // 1000 * the correction amount that will be added to the gyro angle in next line. |
- | |
310 | correction = angle[axis]; //(permilleAcc * (accDerived - angle[axis])) / 1000; |
319 | // 1000 * the correction amount that will be added to the gyro angle in next line. |
311 | angle[axis] = ((int32_t)(1000 - permilleAcc) * angle[axis] + (int32_t)permilleAcc * accDerived) / 1000L; |
- | |
312 | - | ||
313 | correctionSum[axis] += angle[axis] - correction; |
- | |
314 | - | ||
315 | // There should not be a risk of overflow here, since the integrals do not exceed a few 100000. |
- | |
316 | // change = ((1000 - permilleAcc) * angle[axis] + permilleAcc * accDerived) / 1000 - angle[axis] |
- | |
317 | // = (1000 * angle[axis] - permilleAcc * angle[axis] + permilleAcc * accDerived) / 1000 - angle[axis] |
- | |
318 | // = (- permilleAcc * angle[axis] + permilleAcc * accDerived) / 1000 |
- | |
319 | // = permilleAcc * (accDerived - angle[axis]) / 1000 |
320 | correction = angle[axis]; //(permilleAcc * (accDerived - angle[axis])) / 1000; |
320 | 321 | angle[axis] = ((int32_t)(1000L - permilleAcc) * angle[axis] + (int32_t)permilleAcc * accDerived) / 1000L; |
|
321 | // Experiment: Do not acutally apply the correction. See if drift compensation does that. |
- | |
322 | // angle[axis] += correction / 1000; |
- | |
323 | } |
322 | correctionSum[axis] += angle[axis] - correction; |
- | 323 | DebugOut.Analog[16+axis] = angle[axis] - correction; |
|
- | 324 | } |
|
- | 325 | } else { |
|
324 | 326 | DebugOut.Digital[0] &= ~DEBUG_ACC0THORDER; |
|
- | 327 | DebugOut.Digital[1] &= ~DEBUG_ACC0THORDER; |
|
- | 328 | DebugOut.Analog[9] = 0; |
|
- | 329 | DebugOut.Analog[10] = 0; |
|
- | 330 | ||
- | 331 | DebugOut.Analog[16] = 0; |
|
325 | DebugOut.Digital[1] = debugFullWeight; |
332 | DebugOut.Analog[17] = 0; |
326 | } else { |
333 | // experiment: Kill drift compensation updates when not flying smooth. |
Line 327... | Line 334... | ||
327 | DebugOut.Digital[0] = 0; |
334 | correctionSum[PITCH] = correctionSum[ROLL] = 0; |
328 | } |
335 | } |
Line 346... | Line 353... | ||
346 | uint8_t axis; |
353 | uint8_t axis; |
347 | if (! --timer) { |
354 | if (! --timer) { |
348 | timer = DRIFTCORRECTION_TIME; |
355 | timer = DRIFTCORRECTION_TIME; |
349 | for (axis=PITCH; axis<=ROLL; axis++) { |
356 | for (axis=PITCH; axis<=ROLL; axis++) { |
350 | // Take the sum of corrections applied, add it to delta |
357 | // Take the sum of corrections applied, add it to delta |
351 | deltaCorrection = ((correctionSum[axis] + DRIFTCORRECTION_TIME / 2) * HIRES_GYRO_INTEGRATION_FACTOR) / DRIFTCORRECTION_TIME; |
358 | deltaCorrection = (correctionSum[axis] * HIRES_GYRO_INTEGRATION_FACTOR + DRIFTCORRECTION_TIME / 2) / DRIFTCORRECTION_TIME; |
352 | // Add the delta to the compensation. So positive delta means, gyro should have higher value. |
359 | // Add the delta to the compensation. So positive delta means, gyro should have higher value. |
353 | dynamicOffset[axis] += deltaCorrection / staticParams.GyroAccTrim; |
360 | driftComp[axis] += deltaCorrection / staticParams.GyroAccTrim; |
354 | CHECK_MIN_MAX(dynamicOffset[axis], -staticParams.DriftComp, staticParams.DriftComp); |
361 | CHECK_MIN_MAX(driftComp[axis], -staticParams.DriftComp, staticParams.DriftComp); |
355 | DebugOut.Analog[11 + axis] = correctionSum[axis]; |
362 | // DebugOut.Analog[11 + axis] = correctionSum[axis]; |
- | 363 | ||
- | 364 | DebugOut.Analog[18+axis] = deltaCorrection / staticParams.GyroAccTrim; |
|
356 | DebugOut.Analog[28 + axis] = dynamicOffset[axis]; |
365 | DebugOut.Analog[28+axis] = driftComp[axis]; |
- | 366 | ||
357 | correctionSum[axis] = 0; |
367 | correctionSum[axis] = 0; |
358 | } |
368 | } |
359 | } |
369 | } |
360 | } |
370 | } |
Line 361... | Line 371... | ||
361 | 371 | ||
362 | /************************************************************************ |
372 | /************************************************************************ |
363 | * Main procedure. |
373 | * Main procedure. |
364 | ************************************************************************/ |
374 | ************************************************************************/ |
- | 375 | void calculateFlightAttitude(void) { |
|
- | 376 | // part1: 550 usec. |
|
- | 377 | // part1a: 550 usec. |
|
365 | void calculateFlightAttitude(void) { |
378 | // part1b: 60 usec. |
- | 379 | getAnalogData(); |
|
366 | getAnalogData(); |
380 | // end part1b |
- | 381 | integrate(); |
|
- | 382 | // end part1a |
|
Line 367... | Line 383... | ||
367 | integrate(); |
383 | |
368 | 384 | ||
369 | DebugOut.Analog[6] = ACRate[PITCH]; |
385 | DebugOut.Analog[6] = ACRate[PITCH]; |
Line 376... | Line 392... | ||
376 | 392 | ||
377 | #ifdef ATTITUDE_USE_ACC_SENSORS |
393 | #ifdef ATTITUDE_USE_ACC_SENSORS |
378 | correctIntegralsByAcc0thOrder(); |
394 | correctIntegralsByAcc0thOrder(); |
379 | driftCorrection(); |
395 | driftCorrection(); |
- | 396 | #endif |
|
380 | #endif |
397 | // end part1 |
Line 381... | Line -... | ||
381 | } |
- | |
382 | 398 | } |
|
383 | /* |
399 | |
Line 384... | Line 400... | ||
384 | void updateCompass(void) { |
400 | void updateCompass(void) { |
- | 401 | int16_t w, v, r,correction, error; |
|
385 | int16_t w, v, r,correction, error; |
402 | |
- | 403 | if(compassCalState && !(MKFlags & MKFLAG_MOTOR_RUN)) { |
|
- | 404 | if (controlMixer_testCompassCalState()) { |
|
- | 405 | compassCalState++; |
|
386 | |
406 | if(compassCalState < 5) beepNumber(compassCalState); |
387 | if(compassCalState && !(MKFlags & MKFLAG_MOTOR_RUN)) { |
407 | else beep(1000); |
388 | setCompassCalState(); |
408 | } |
389 | } else { |
409 | } else { |
390 | // get maximum attitude angle |
410 | // get maximum attitude angle |
391 | w = abs(pitchAngle / 512); |
411 | w = abs(angle[PITCH] / 512); |
392 | v = abs(rollAngle / 512); |
412 | v = abs(angle[ROLL] / 512); |
393 | if(v > w) w = v; |
413 | if(v > w) w = v; |
394 | correction = w / 8 + 1; |
414 | correction = w / 8 + 1; |
395 | // 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 |
396 | if (compassHeading < 0) error = 0; // disable yaw drift compensation if compass heading is undefined |
416 | if (compassHeading < 0) error = 0; // disable yaw drift compensation if compass heading is undefined |
397 | else error = ((540 + compassHeading - (yawGyroHeading / GYRO_DEG_FACTOR_YAW)) % 360) - 180; |
417 | else error = ((540 + compassHeading - (yawGyroHeading / GYRO_DEG_FACTOR_YAW)) % 360) - 180; |
398 | if(abs(yawRate) > 128) { // spinning fast |
418 | if(abs(yawRate) > 128) { // spinning fast |
- | 419 | error = 0; |
|
399 | error = 0; |
420 | } |
400 | } |
421 | if(!badCompassHeading && w < 25) { |
401 | if(!badCompassHeading && w < 25) { |
422 | yawGyroDrift += error; |
402 | if(updateCompassCourse) { |
423 | if(updateCompassCourse) { |
403 | beep(200); |
424 | beep(200); |
404 | yawGyroHeading = (int32_t)compassHeading * GYRO_DEG_FACTOR_YAW; |
425 | yawGyroHeading = (int32_t)compassHeading * GYRO_DEG_FACTOR_YAW; |
405 | compassCourse = (int16_t)(yawGyroHeading / GYRO_DEG_FACTOR_YAW); |
426 | compassCourse = compassHeading; //(int16_t)(yawGyroHeading / GYRO_DEG_FACTOR_YAW); |
406 | updateCompassCourse = 0; |
427 | updateCompassCourse = 0; |
407 | } |
428 | } |
408 | } |
429 | } |
409 | yawGyroHeading += (error * 8) / correction; |
430 | yawGyroHeading += (error * 8) / correction; |
410 | w = (w * dynamicParams.CompassYawEffect) / 32; |
431 | w = (w * dynamicParams.CompassYawEffect) / 32; |
411 | w = dynamicParams.CompassYawEffect - w; |
432 | w = dynamicParams.CompassYawEffect - w; |
412 | if(w >= 0) { |
433 | if(w >= 0) { |
413 | if(!badCompassHeading) { |
434 | if(!badCompassHeading) { |
414 | v = 64 + (maxControlPitch + maxControlRoll) / 8; |
435 | v = 64 + (maxControl[PITCH] + maxControl[ROLL]) / 8; |
415 | // calc course deviation |
436 | // calc course deviation |
416 | r = ((540 + (yawGyroHeading / GYRO_DEG_FACTOR_YAW) - compassCourse) % 360) - 180; |
437 | r = ((540 + (yawGyroHeading / GYRO_DEG_FACTOR_YAW) - compassCourse) % 360) - 180; |
417 | v = (r * w) / v; // align to compass course |
438 | v = (r * w) / v; // align to compass course |
418 | // limit yaw rate |
439 | // limit yaw rate |
419 | w = 3 * dynamicParams.CompassYawEffect; |
440 | w = 3 * dynamicParams.CompassYawEffect; |
420 | if (v > w) v = w; |
441 | if (v > w) v = w; |
421 | else if (v < -w) v = -w; |
442 | else if (v < -w) v = -w; |
422 | yawAngle += v; |
443 | yawAngleDiff += v; |
423 | } |
444 | } |
424 | else |
- | |
425 | { // wait a while |
445 | else |
426 | badCompassHeading--; |
446 | { // wait a while |
427 | } |
447 | badCompassHeading--; |
428 | } |
- | |
429 | else { // ignore compass at extreme attitudes for a while |
448 | } |
430 | badCompassHeading = 500; |
449 | } else { // ignore compass at extreme attitudes for a while |
431 | } |
450 | badCompassHeading = 500; |
Line 432... | Line 451... | ||
432 | } |
451 | } |
433 | } |
452 | } |
434 | */ |
453 | } |
435 | 454 | ||
Line 455... | Line 474... | ||
455 | dynamicCalCount++; |
474 | dynamicCalCount++; |
Line 456... | Line 475... | ||
456 | |
475 | |
457 | // Param6: Manual mode. The offsets are taken from Param7 and Param8. |
476 | // Param6: Manual mode. The offsets are taken from Param7 and Param8. |
458 | if (dynamicParams.UserParam6 || 1) { // currently always enabled. |
477 | if (dynamicParams.UserParam6 || 1) { // currently always enabled. |
459 | // manual mode |
478 | // manual mode |
460 | dynamicOffsetPitch = dynamicParams.UserParam7 - 128; |
479 | driftCompPitch = dynamicParams.UserParam7 - 128; |
461 | dynamicOffsetRoll = dynamicParams.UserParam8 - 128; |
480 | driftCompRoll = dynamicParams.UserParam8 - 128; |
462 | } else { |
481 | } else { |
463 | // use the sampled value (does not seem to work so well....) |
482 | // use the sampled value (does not seem to work so well....) |
464 | dynamicOffsetPitch = savedDynamicOffsetPitch = -dynamicCalPitch / dynamicCalCount; |
483 | driftCompPitch = savedDynamicOffsetPitch = -dynamicCalPitch / dynamicCalCount; |
465 | dynamicOffsetRoll = savedDynamicOffsetRoll = -dynamicCalRoll / dynamicCalCount; |
484 | driftCompRoll = savedDynamicOffsetRoll = -dynamicCalRoll / dynamicCalCount; |
466 | dynamicOffsetYaw = -dynamicCalYaw / dynamicCalCount; |
485 | driftCompYaw = -dynamicCalYaw / dynamicCalCount; |
Line 467... | Line 486... | ||
467 | } |
486 | } |
468 | |
487 | |
469 | // keep resetting these meanwhile, to avoid accumulating errors. |
488 | // keep resetting these meanwhile, to avoid accumulating errors. |