Subversion Repositories FlightCtrl

Rev

Rev 1796 | Rev 1854 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1796 Rev 1821
Line 92... Line 92...
92
/*
92
/*
93
 * Offset values. These are the raw gyro and acc. meter sums when the copter is
93
 * Offset values. These are the raw gyro and acc. meter sums when the copter is
94
 * standing still. They are used for adjusting the gyro and acc. meter values
94
 * standing still. They are used for adjusting the gyro and acc. meter values
95
 * to be centered on zero.
95
 * to be centered on zero.
96
 */
96
 */
97
volatile int16_t gyroOffset[3] = {
-
 
98
        512 * GYRO_SUMMATION_FACTOR_PITCHROLL,
97
volatile int16_t gyroOffset[3] = { 512 * GYRO_SUMMATION_FACTOR_PITCHROLL, 512
99
        512 * GYRO_SUMMATION_FACTOR_PITCHROLL,
98
                * GYRO_SUMMATION_FACTOR_PITCHROLL, 512 * GYRO_SUMMATION_FACTOR_YAW };
100
        512 * GYRO_SUMMATION_FACTOR_YAW
-
 
101
};
-
 
Line 102... Line -...
102
 
-
 
103
volatile int16_t accOffset[3] = {
99
 
104
        512 * ACC_SUMMATION_FACTOR_PITCHROLL,
100
volatile int16_t accOffset[3] = { 512 * ACC_SUMMATION_FACTOR_PITCHROLL, 512
105
        512 * ACC_SUMMATION_FACTOR_PITCHROLL,
-
 
106
        512 * ACC_SUMMATION_FACTOR_Z
-
 
Line 107... Line 101...
107
};
101
                * ACC_SUMMATION_FACTOR_PITCHROLL, 512 * ACC_SUMMATION_FACTOR_Z };
108
 
102
 
109
/*
103
/*
110
 * This allows some experimentation with the gyro filters.
104
 * This allows some experimentation with the gyro filters.
Line 174... Line 168...
174
 * re-enabling ADC, the real limit is (how much?) lower.
168
 * re-enabling ADC, the real limit is (how much?) lower.
175
 * The acc. sensor is sampled even if not used - or installed
169
 * The acc. sensor is sampled even if not used - or installed
176
 * at all. The cost is not significant.
170
 * at all. The cost is not significant.
177
 */
171
 */
Line 178... Line 172...
178
 
172
 
179
const uint8_t channelsForStates[] PROGMEM = {
-
 
180
  AD_GYRO_PITCH,
-
 
181
  AD_GYRO_ROLL,
173
const uint8_t channelsForStates[] PROGMEM = { AD_GYRO_PITCH, AD_GYRO_ROLL,
Line 182... Line -...
182
  AD_GYRO_YAW,
-
 
183
 
-
 
184
  AD_ACC_PITCH,
174
                AD_GYRO_YAW,
185
  AD_ACC_ROLL,
175
 
186
  AD_AIRPRESSURE,
-
 
187
 
-
 
188
  AD_GYRO_PITCH,
176
                AD_ACC_PITCH, AD_ACC_ROLL, AD_AIRPRESSURE,
189
  AD_GYRO_ROLL,
177
 
190
  AD_ACC_Z,       // at 8, measure Z acc.
-
 
191
 
-
 
192
  AD_GYRO_PITCH,
178
                AD_GYRO_PITCH, AD_GYRO_ROLL, AD_ACC_Z, // at 8, measure Z acc.
Line 193... Line 179...
193
  AD_GYRO_ROLL,
179
 
194
  AD_GYRO_YAW,    // at 11, finish yaw gyro
180
                AD_GYRO_PITCH, AD_GYRO_ROLL, AD_GYRO_YAW, // at 11, finish yaw gyro
195
 
181
 
Line 220... Line 206...
220
  ADMUX &= ~((1 << REFS1)|(1 << REFS0)|(1 << ADLAR));
206
        ADMUX &= ~((1 << REFS1) | (1 << REFS0) | (1 << ADLAR));
221
  // set muxer to ADC adc_channel 0 (0 to 7 is a valid choice)
207
        // set muxer to ADC adc_channel 0 (0 to 7 is a valid choice)
222
  ADMUX = (ADMUX & 0xE0) | AD_GYRO_PITCH;
208
        ADMUX = (ADMUX & 0xE0) | AD_GYRO_PITCH;
223
  //Set ADC Control and Status Register A
209
        //Set ADC Control and Status Register A
224
  //Auto Trigger Enable, Prescaler Select Bits to Division Factor 128, i.e. ADC clock = SYSCKL/128 = 156.25 kHz
210
        //Auto Trigger Enable, Prescaler Select Bits to Division Factor 128, i.e. ADC clock = SYSCKL/128 = 156.25 kHz
225
  ADCSRA = (0<<ADEN)|(0<<ADSC)|(0<<ADATE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(0<<ADIE);
211
        ADCSRA = (0 << ADEN) | (0 << ADSC) | (0 << ADATE) | (1 << ADPS2) | (1
-
 
212
                        << ADPS1) | (1 << ADPS0) | (0 << ADIE);
226
  //Set ADC Control and Status Register B
213
        //Set ADC Control and Status Register B
227
  //Trigger Source to Free Running Mode
214
        //Trigger Source to Free Running Mode
228
  ADCSRB &= ~((1 << ADTS2)|(1 << ADTS1)|(1 << ADTS0));
215
        ADCSRB &= ~((1 << ADTS2) | (1 << ADTS1) | (1 << ADTS0));
229
  // Start AD conversion
216
        // Start AD conversion
230
  analog_start();
217
        analog_start();
231
  // restore global interrupt flags
218
        // restore global interrupt flags
232
  SREG = sreg;
219
        SREG = sreg;
233
}
220
}
Line -... Line 221...
-
 
221
 
234
 
222
void measureNoise(const int16_t sensor,
235
void measureNoise(const int16_t sensor, volatile uint16_t* const noiseMeasurement, const uint8_t damping) {
223
                volatile uint16_t* const noiseMeasurement, const uint8_t damping) {
236
  if (sensor > (int16_t)(*noiseMeasurement)) {
224
        if (sensor > (int16_t) (*noiseMeasurement)) {
237
    *noiseMeasurement = sensor;
225
                *noiseMeasurement = sensor;
238
  } else if (-sensor > (int16_t)(*noiseMeasurement)) {
226
        } else if (-sensor > (int16_t) (*noiseMeasurement)) {
239
    *noiseMeasurement = -sensor;
227
                *noiseMeasurement = -sensor;
Line 256... Line 244...
256
 * Interrupt Service Routine for ADC            
244
 * Interrupt Service Routine for ADC            
257
 * Runs at 312.5 kHz or 3.2 µs. When all states are
245
 * Runs at 312.5 kHz or 3.2 µs. When all states are
258
 * processed the interrupt is disabled and further
246
 * processed the interrupt is disabled and further
259
 * AD conversions are stopped.
247
 * AD conversions are stopped.
260
 *****************************************************/
248
 *****************************************************/
261
ISR(ADC_vect) {
249
ISR(ADC_vect)
-
 
250
{
262
  static uint8_t ad_channel = AD_GYRO_PITCH, state = 0;
251
        static uint8_t ad_channel = AD_GYRO_PITCH, state = 0;
263
  static uint16_t sensorInputs[8] = {0,0,0,0,0,0,0,0};
252
        static uint16_t sensorInputs[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
264
  static uint16_t pressureAutorangingWait = 25;
253
        static uint16_t pressureAutorangingWait = 25;
265
  uint16_t rawAirPressure;
254
        uint16_t rawAirPressure;
266
  uint8_t i, axis;
255
        uint8_t i, axis;
Line 296... Line 285...
296
    if (ACC_REVERSED[PITCH])
285
                if (ACC_REVERSED[PITCH])
297
      acc[PITCH] = accOffset[PITCH] - sensorInputs[AD_ACC_PITCH];
286
                        acc[PITCH] = accOffset[PITCH] - sensorInputs[AD_ACC_PITCH];
298
    else
287
                else
299
      acc[PITCH] = sensorInputs[AD_ACC_PITCH] - accOffset[PITCH];
288
                        acc[PITCH] = sensorInputs[AD_ACC_PITCH] - accOffset[PITCH];
Line 300... Line 289...
300
 
289
 
-
 
290
                filteredAcc[PITCH] = (filteredAcc[PITCH] * (ACC_FILTER - 1) + acc[PITCH])
301
    filteredAcc[PITCH] = (filteredAcc[PITCH] * (ACC_FILTER-1) + acc[PITCH]) / ACC_FILTER;
291
                                / ACC_FILTER;
302
    measureNoise(acc[PITCH], &accNoisePeak[PITCH], 1);
292
                measureNoise(acc[PITCH], &accNoisePeak[PITCH], 1);
Line 303... Line 293...
303
    break;
293
                break;
304
   
294
 
305
  case 13: // roll axis acc.
295
        case 13: // roll axis acc.
306
    if (ACC_REVERSED[ROLL])
296
                if (ACC_REVERSED[ROLL])
307
      acc[ROLL] = accOffset[ROLL] - sensorInputs[AD_ACC_ROLL];
297
                        acc[ROLL] = accOffset[ROLL] - sensorInputs[AD_ACC_ROLL];
308
    else
298
                else
-
 
299
                        acc[ROLL] = sensorInputs[AD_ACC_ROLL] - accOffset[ROLL];
309
      acc[ROLL] = sensorInputs[AD_ACC_ROLL] - accOffset[ROLL];
300
                filteredAcc[ROLL] = (filteredAcc[ROLL] * (ACC_FILTER - 1) + acc[ROLL])
310
    filteredAcc[ROLL] = (filteredAcc[ROLL] * (ACC_FILTER-1) + acc[ROLL]) / ACC_FILTER;
301
                                / ACC_FILTER;
Line 311... Line 302...
311
    measureNoise(acc[ROLL], &accNoisePeak[ROLL], 1);
302
                measureNoise(acc[ROLL], &accNoisePeak[ROLL], 1);
312
    break;
303
                break;
Line 354... Line 345...
354
    DebugOut.Analog[31] = simpleAirPressure;
345
                DebugOut.Analog[31] = simpleAirPressure;
Line 355... Line 346...
355
 
346
 
356
    if (simpleAirPressure < MIN_RANGES_EXTRAPOLATION * rangewidth) {
347
                if (simpleAirPressure < MIN_RANGES_EXTRAPOLATION * rangewidth) {
357
      // Danger: pressure near lower end of range. If the measurement saturates, the 
348
                        // Danger: pressure near lower end of range. If the measurement saturates, the
358
      // copter may climb uncontrolledly... Simulate a drastic reduction in pressure.
349
                        // copter may climb uncontrolledly... Simulate a drastic reduction in pressure.
-
 
350
                        airPressureSum += (int16_t) MIN_RANGES_EXTRAPOLATION * rangewidth
-
 
351
                                        + (simpleAirPressure - (int16_t) MIN_RANGES_EXTRAPOLATION
359
      airPressureSum += (int16_t)MIN_RANGES_EXTRAPOLATION * rangewidth + (simpleAirPressure - (int16_t)MIN_RANGES_EXTRAPOLATION * rangewidth) * PRESSURE_EXTRAPOLATION_COEFF;
352
                                                        * rangewidth) * PRESSURE_EXTRAPOLATION_COEFF;
360
    } else if (simpleAirPressure > MAX_RANGES_EXTRAPOLATION * rangewidth) {
353
                } else if (simpleAirPressure > MAX_RANGES_EXTRAPOLATION * rangewidth) {
361
      // Danger: pressure near upper end of range. If the measurement saturates, the 
354
                        // Danger: pressure near upper end of range. If the measurement saturates, the
362
      // copter may descend uncontrolledly... Simulate a drastic increase in pressure.
355
                        // copter may descend uncontrolledly... Simulate a drastic increase in pressure.
-
 
356
                        airPressureSum += (int16_t) MAX_RANGES_EXTRAPOLATION * rangewidth
-
 
357
                                        + (simpleAirPressure - (int16_t) MAX_RANGES_EXTRAPOLATION
363
      airPressureSum += (int16_t)MAX_RANGES_EXTRAPOLATION * rangewidth + (simpleAirPressure - (int16_t)MAX_RANGES_EXTRAPOLATION * rangewidth) * PRESSURE_EXTRAPOLATION_COEFF;
358
                                                        * rangewidth) * PRESSURE_EXTRAPOLATION_COEFF;
364
    } else {
359
                } else {
365
      // normal case.
360
                        // normal case.
366
      // If AIRPRESSURE_SUMMATION_FACTOR is an odd number we only want to add half the double sample.
361
                        // If AIRPRESSURE_SUMMATION_FACTOR is an odd number we only want to add half the double sample.
367
      // The 2 cases above (end of range) are ignored for this.
362
                        // The 2 cases above (end of range) are ignored for this.
Line 372... Line 367...
372
    }
367
                }
Line 373... Line 368...
373
 
368
 
374
    // 2 samples were added.
369
                // 2 samples were added.
375
    pressureMeasurementCount += 2;
370
                pressureMeasurementCount += 2;
376
    if (pressureMeasurementCount >= AIRPRESSURE_SUMMATION_FACTOR) {
371
                if (pressureMeasurementCount >= AIRPRESSURE_SUMMATION_FACTOR) {
-
 
372
                        filteredAirPressure = (filteredAirPressure * (AIRPRESSURE_FILTER - 1)
377
      filteredAirPressure = (filteredAirPressure * (AIRPRESSURE_FILTER-1) + airPressureSum + AIRPRESSURE_FILTER/2) / AIRPRESSURE_FILTER;
373
                                        + airPressureSum + AIRPRESSURE_FILTER / 2) / AIRPRESSURE_FILTER;
378
      pressureMeasurementCount = airPressureSum = 0;
374
                        pressureMeasurementCount = airPressureSum = 0;
Line 379... Line 375...
379
    }
375
                }
Line 392... Line 388...
392
    //    gyro with a wider range, and helps counter saturation at full control.
388
                //    gyro with a wider range, and helps counter saturation at full control.
Line 393... Line 389...
393
 
389
 
394
    if (staticParams.GlobalConfig & CFG_ROTARY_RATE_LIMITER) {
390
                if (staticParams.GlobalConfig & CFG_ROTARY_RATE_LIMITER) {
395
      if (tempGyro < SENSOR_MIN_PITCHROLL) {
391
                        if (tempGyro < SENSOR_MIN_PITCHROLL) {
396
        tempGyro = tempGyro * EXTRAPOLATION_SLOPE - EXTRAPOLATION_LIMIT;
-
 
397
      }
392
                                tempGyro = tempGyro * EXTRAPOLATION_SLOPE - EXTRAPOLATION_LIMIT;
398
      else if (tempGyro > SENSOR_MAX_PITCHROLL) {
393
                        } else if (tempGyro > SENSOR_MAX_PITCHROLL) {
-
 
394
                                tempGyro = (tempGyro - SENSOR_MAX_PITCHROLL) * EXTRAPOLATION_SLOPE
399
        tempGyro = (tempGyro - SENSOR_MAX_PITCHROLL) * EXTRAPOLATION_SLOPE + SENSOR_MAX_PITCHROLL;
395
                                                + SENSOR_MAX_PITCHROLL;
400
      }
396
                        }
Line 401... Line 397...
401
    }
397
                }
402
 
398
 
Line 406... Line 402...
406
    } else {
402
                } else {
407
      tempOffsetGyro = (tempGyro - gyroOffset[axis]) * GYRO_FACTOR_PITCHROLL;
403
                        tempOffsetGyro = (tempGyro - gyroOffset[axis]) * GYRO_FACTOR_PITCHROLL;
408
    }
404
                }
Line 409... Line 405...
409
 
405
 
410
    // 3) Scale and filter.
406
                // 3) Scale and filter.
-
 
407
                tempOffsetGyro = (gyro_PID[axis] * (GYROS_PID_FILTER - 1) + tempOffsetGyro)
Line 411... Line 408...
411
    tempOffsetGyro = (gyro_PID[axis] * (GYROS_PID_FILTER-1) + tempOffsetGyro) / GYROS_PID_FILTER;
408
                                / GYROS_PID_FILTER;
412
 
409
 
-
 
410
                // 4) Measure noise.
Line 413... Line 411...
413
    // 4) Measure noise.
411
                measureNoise(tempOffsetGyro, &gyroNoisePeak[axis],
414
    measureNoise(tempOffsetGyro, &gyroNoisePeak[axis], GYRO_NOISE_MEASUREMENT_DAMPING);
412
                                GYRO_NOISE_MEASUREMENT_DAMPING);
-
 
413
 
Line 415... Line 414...
415
 
414
                // 5) Differential measurement.
416
    // 5) Differential measurement. 
415
                gyroD[axis] = (gyroD[axis] * (GYROS_D_FILTER - 1) + (tempOffsetGyro
Line 417... Line 416...
417
    gyroD[axis] = (gyroD[axis] * (GYROS_D_FILTER-1) + (tempOffsetGyro - gyro_PID[axis])) / GYROS_D_FILTER;
416
                                - gyro_PID[axis])) / GYROS_D_FILTER;
Line 430... Line 429...
430
    } else {
429
                } else {
431
      tempOffsetGyro = (tempGyro - gyroOffset[axis]) * GYRO_FACTOR_PITCHROLL;
430
                        tempOffsetGyro = (tempGyro - gyroOffset[axis]) * GYRO_FACTOR_PITCHROLL;
432
    }
431
                }
Line 433... Line 432...
433
   
432
 
434
    // 2) Filter.
433
                // 2) Filter.
-
 
434
                gyro_ATT[axis] = (gyro_ATT[axis] * (GYROS_ATT_FILTER - 1) + tempOffsetGyro)
435
    gyro_ATT[axis] = (gyro_ATT[axis] * (GYROS_ATT_FILTER-1) + tempOffsetGyro) / GYROS_ATT_FILTER;
435
                                / GYROS_ATT_FILTER;
Line 436... Line 436...
436
    break;
436
                break;
437
   
437
 
438
  case 17:
438
        case 17:
Line 446... Line 446...
446
    state = 0;
446
                state = 0;
447
    for (i=0; i<8; i++) {
447
                for (i = 0; i < 8; i++) {
448
      sensorInputs[i] = 0;
448
                        sensorInputs[i] = 0;
449
    }
449
                }
450
    break;
450
                break;
-
 
451
        default: {
451
  default: {} // do nothing.
452
        } // do nothing.
452
  }
453
        }
Line 453... Line 454...
453
 
454
 
454
  // set up for next state.
455
        // set up for next state.
455
  ad_channel = pgm_read_byte(&channelsForStates[state]);
456
        ad_channel = pgm_read_byte(&channelsForStates[state]);
Line 456... Line 457...
456
  // ad_channel = channelsForStates[state];
457
        // ad_channel = channelsForStates[state];
457
     
458
 
458
  // set adc muxer to next ad_channel
459
        // set adc muxer to next ad_channel
-
 
460
        ADMUX = (ADMUX & 0xE0) | ad_channel;
459
  ADMUX = (ADMUX & 0xE0) | ad_channel;
461
        // after full cycle stop further interrupts
460
  // after full cycle stop further interrupts
462
        if (state)
Line 461... Line 463...
461
  if(state) analog_start();
463
                analog_start();
462
}
464
}
463
 
465
 
Line 481... Line 483...
481
      deltaOffsets[axis] += rawGyroSum[axis];
483
                        deltaOffsets[axis] += rawGyroSum[axis];
482
    }
484
                }
483
  }
485
        }
Line 484... Line 486...
484
 
486
 
485
  for (axis=PITCH; axis<=YAW; axis++) {
487
        for (axis = PITCH; axis <= YAW; axis++) {
-
 
488
                gyroOffset[axis] = (deltaOffsets[axis] + GYRO_OFFSET_CYCLES / 2)
486
    gyroOffset[axis] =  (deltaOffsets[axis] + GYRO_OFFSET_CYCLES/2) / GYRO_OFFSET_CYCLES;
489
                                / GYRO_OFFSET_CYCLES;
487
    DebugOut.Analog[20+axis] = gyroOffset[axis];
490
                DebugOut.Analog[20 + axis] = gyroOffset[axis];
Line 488... Line 491...
488
  }
491
        }
489
 
492
 
Line 521... Line 524...
521
      deltaOffset[axis] += acc[axis];
524
                        deltaOffset[axis] += acc[axis];
522
    }
525
                }
523
  }
526
        }
Line 524... Line 527...
524
 
527
 
525
  for (axis=PITCH; axis<=YAW; axis++) {
528
        for (axis = PITCH; axis <= YAW; axis++) {
-
 
529
                filteredDelta = (deltaOffset[axis] + ACC_OFFSET_CYCLES / 2)
526
    filteredDelta = (deltaOffset[axis] + ACC_OFFSET_CYCLES / 2) / ACC_OFFSET_CYCLES;
530
                                / ACC_OFFSET_CYCLES;
527
    accOffset[axis] += ACC_REVERSED[axis] ? -filteredDelta : filteredDelta;
531
                accOffset[axis] += ACC_REVERSED[axis] ? -filteredDelta : filteredDelta;
Line 528... Line 532...
528
  }
532
        }
529
 
533