@nitro: Ich hab ja gar nix gegen Komplementär-Filter.....
Warum ich 1kHz Raw Gyro und DMP haben möchte? Ganz Einfach: den Winkel über DMP zu bekommen ist faktisch viel besser, asl ihn über den Beschleunigungssensor zu kriegen, weniger drift bei Bewegung.
Ich will ja das Gyro-Signal gar nicht integrieren, sondern nur für 0-Drehgeschwindigkeit (grad/s) haben.
@Andreas: das, was Du geschrieben hast, ist nicht der Komplementärfilter, den nitro meint.
gyroRoll ist Drehrate in deg/s!
Der Vorschlag von nitro integriert das Gyrosignal hochpassgefiltert zum Winkel auf! In diesem Fall wäre Wingelabweichung die Regelgröße, in meinem Code ist es Abweichung von 0 grad/s.
Wahrscheinlich funktioniert es bei in meinem Fall nur deshalb so gut, weil ich davor im Loop auch den Tiefpassfilter aus Version 036 benutze (..das hatte ich in 039 bei meinem Video auch gemacht). Jedenfalls sorgt diese Kombination im Moment dafür, dass nun auch die Version 041 bei mir stabil läuft, während sie davor im Ruhezustand pendelte (?!):
void loop()
{
count++;
sampleTimePID = (micros()-timer)/1000000.0/CC_FACTOR; // in Seconds!
timer = micros();
// Update raw Gyro
updateRawGyroData(&gyroRoll,&gyroPitch);
// Optional Low Pass Filter for Gyro Signal
// filter it with exponentially weighed moving average (EWMA)
#ifdef LP_FILTER_GYRO
gyroPitch = LP_ALPHA_GYRO * gyroPitch + (1.0-LP_ALPHA_GYRO) * gyroPitchOld;
gyroPitchOld=gyroPitch;
gyroRoll = LP_ALPHA_GYRO * gyroRoll + (1.0-LP_ALPHA_GYRO) * gyroRollOld;
gyroRollOld=gyroRoll;
#endif
// Loop Time 530 us
// Update ACC data approximately at 50Hz to save calculation time.
if(count == 20)
{
mpu.getAcceleration(&x_val,&y_val,&z_val);
sampleTimeACC = (micros()-timerACC)/1000.0/CC_FACTOR; // in Seconds * 1000.0 to account for factor 1000 in parameters
timerACC=timer;
//{Serial.print(sampleTimeACC,5);Serial.print(" ");Serial.println(sampleTimePID,5);}
}
if(count == 21) rollAngleACC =atan2(-y_val,-z_val)*57.2957795;
if(count == 22)
{
pitchAngleACC =-atan2(-x_val,-z_val)*57.2957795;
count=0;
}
//Serial.println( (micros()-timer)/CC_FACTOR);
gyroRoll = (1 - config.accelWeight/1000)*gyroRoll + config.accelWeight * (rollAngleACC - rollSetpoint)/sampleTimeACC;
gyroPitch = (1 - config.accelWeight/1000)*gyroPitch + config.accelWeight * (pitchAngleACC - pitchSetpoint)/sampleTimeACC;
pitchPID = ComputePID(sampleTimePID,gyroPitch,0.0, &pitchErrorSum, &pitchErrorOld,config.gyroPitchKp,config.gyroPitchKi,config.gyroPitchKd,maxDegPerSecondPitch);
rollPID = ComputePID(sampleTimePID,gyroRoll,0.0, &rollErrorSum, &rollErrorOld,config.gyroRollKp,config.gyroRollKi,config.gyroRollKd,maxDegPerSecondRoll);
pitchDevider = constrain(maxDegPerSecondPitch / (pitchPID + 0.000001), -15000,15000);
pitchDirection = sgn(pitchDevider) * config.dirMotorPitch;
rollDevider = constrain(maxDegPerSecondRoll / (rollPID + 0.000001), -15000,15000);
rollDirection = sgn(rollDevider) * config.dirMotorRoll;
sCmd.readSerial();
}
Das Spiegelvideo ist nun ähnlich wie mein letztes Video mit der Version 039, wobei die Möglichkeit über das Terminal und "GC" den Gyro-Offset zur Laufzeit neu zu kalibrieren ein Vorteil ist.
http://www.youtube.com/watch?v=vMGqux20BRg