Forum: Digitale Signalverarbeitung / DSP / Machine Learning Merkwürdige Sprungantwort bei Hochpass


von Manfred M. (bittbeisser)


Angehängte Dateien:

Lesenswert?

Ich versuche seit einiger Zeit, mich in die DSP Welt einzuarbeiten. Da 
ich Dinge, die ich auch sehen kann, besser begreife, habe ich mir ein 
Tool zur grafischen Darstellung gebastelt. Im Frequenzbereich klappt das 
auch halbwegs. Dazu muss ich noch sagen, das die Kurven nicht berechnet 
werden, sondern quasi gemessen werden.

Aber jetzt wollte ich auch mal die Sprungantworten einiger 
Standardfilter darstellen und habe damit Probleme. Bei einem Hochpass 
weichen die Darstellungen recht deutlich von den Sollkurven, wie man sie 
in der Literatur findet, ab. Zuerst dachte ich es liegt vielleicht 
daran, das ich zumindest kurzzeitig die Nyquist Bedingung verletze, da 
ich mein Filter aus dem Stand mit Einzen vollpumpe. Aber auch wenn ich 
den Sprunganstieg auf mehrere Samples verteile, ändert das eigentlich 
nichts.

Kann mir jemand sagen, was ich falsch mache oder worauf ich achten muss?

von C Programmierer (Gast)


Lesenswert?

Ich geh mal davon aus, dass das Eingangssignal bei t=0 auf 1 Volt 
springt?

Offensichtlich ist der Hochpass falsch implementiert. Wie sieht denn 
dein Code dazu aus?

von derguteweka (Gast)


Lesenswert?

Moin,

Manfred M. schrieb:
> Kann mir jemand sagen, was ich falsch mache oder worauf ich achten muss?

Was soll denn nicht stimmen mit der Sprungantwort?
Erst isses 0, dann ist bisschen was los, dann beruhigt sich's wieder, 
aber geht nicht ganz auf 0 zurueck, also ist das was Hochpassartiges, 
was aber keine Nullstelle bei der Frequenz 0 hat, sondern "nur" 
Daempfung; aber ich wuerd' das schon als Hochpass sehen.
Was hattest du denn erwartet?

@C Programmierer: Was ist denn deiner Meinung nach "offensichtlich 
falsch implementiert" - ich find' da nix offensichtliches, auch mit 
angestrengtem Anstarren nicht...

Gruss
WK

von Manfred M. (bittbeisser)


Angehängte Dateien:

Lesenswert?

> Ich geh mal davon aus, dass das Eingangssignal bei t=0 auf 1 Volt
> springt?
Genau. Aber auch wenn es erst beim 2. Sample passiert, ändert es nichts.

> Wie sieht denn dein Code dazu aus?
Du willst jetzt hoffentlich nicht alle Module sehen? Also der 
eigentliche Filter Code sollte grundsätzlich funktionieren, wie das neue 
Bild im Frequenzbereich zeigt. Allerdings muss ich zugeben, das die 
Filterkoeffizienten etwas ungenau sind. Die Summe ist nicht Null, was 
man dann auch an der fehlerhaften Ruhelage sieht.

Der eigentliche Filtercode für mehrere Typen sieht so aus:
1
//      filter single values
2
//
3
double DIG_Filter::filters( double in ) {
4
    int it;     // tap (reg) index
5
    int ib;     // b coefficient index
6
    double  sum;
7
8
    inbuf[ix++] = in;       // store input and advance index to oldest sample
9
    if( ix >= num_taps )    // buffer is a circular buffer
10
        ix = 0;
11
    sum = 0.0;
12
    it = ix;
13
    for( ib = 0; ib < num_taps; ib++ ) {
14
        sum += b[ib] * inbuf[it++];
15
        if( it == num_taps )
16
            it = 0;
17
    }
18
    return sum;
19
}
Die eigentliche "Messung" passiert hier:
1
void MainWindow::View_Step( void ) {
2
    int     max_steps;
3
    int     i;
4
    double  mag;
5
    double  i_val;
6
    double  i_step;
7
    double  step_width;
8
    double  step_val;
9
    double  scale_end;
10
11
    if( !filter )
12
        return;     // no filter active
13
    max_steps = scope->width();
14
    step_width = 1000.0 / sample_rate;
15
    i_step = 2.0 / sample_rate;
16
    scope->clear();
17
    scope->refresh();
18
    scale_end = step_width * max_steps / 4;
19
    // set up the display scaling
20
    scope->scale( 4, 0, scale_end, "4.0", "t/ms", -1.0, 1.0, "3.2", "u" );
21
    step_val = 0;
22
    i_val = 0.0;
23
    filter->reset(); // clear the filter buffer
24
    for( i = 0; i < max_steps; i++ ) {
25
        mag = filter->filters( i_val );
26
        scope->plot( step_val, mag );
27
        step_val += step_width;
28
        if( i == 0 )
29
            i_val = 1.0;
30
    }
31
}
Wolltest Du das sehen?

von Manfred M. (bittbeisser)


Lesenswert?

> Was hattest du denn erwartet?
Na ja, die Überschwinger und die Vorgeschichte habe ich so in der 
Literatur noch nicht gesehen.

von derguteweka (Gast)


Lesenswert?

Moin,

Manfred M. schrieb:
> Na ja, die Überschwinger und die Vorgeschichte habe ich so in der
> Literatur noch nicht gesehen.

Dann guck' in andere Literatur :-)

Die Impulsantwort haengt halt stark vom Verfahren ab, mit dem die 
Koeffizientzen berechnet werden.
Durch die "Vorgeschichte" kriegt dein Hochpass ein "schoenes" 
Phasenverhalten, d.h. ziemlich konstante Gruppenlaufzeit.

Gruss
WK

von C Programmierer (Gast)


Lesenswert?

Ach so, ich dachte du redest von einem Hochpass erster Ordnung.

Hast du denn schon einen funktionierenden Tiefpass? Falls da das 
erwartete Ausgangssignal rauskommt, kannst du diesen nehmen, dann ist 
Eingangssignal-(Ausgang vom Tiefpass) = Ausgang vom Hochpass. Ansonsten 
kannst du ja mal ausprobieren wie die Impulsantwort aussieht.

Deein geplotteter Frequenzgang, ist das die Fouriertransformierte deines 
Ausgangssignals oder wie hast du den berechnet?

von C Programmierer (Gast)


Lesenswert?

@derguteweka: Meiner Erinnerung nach muss das Augangssignal zum 
Zeitpunkt t=0 einen Sprung haben und nach einiger Zeit auf 0 
zurückfallen. Hier gibts aber am Anfang keinen Sprung.

von Manfred M. (bittbeisser)


Lesenswert?

< Dann guck' in andere Literatur :-)
Was kannst Du da empfehlen? Also den viel zitierten DSP Guide habe ich 
gerade bestellt (Lieferzeit ca. 2 Wochen), da mir das online lesen zu 
anstrengend ist.

> Die Impulsantwort haengt halt stark vom Verfahren ab, mit dem die
Koeffizientzen berechnet werden.
Ok, da ist möglicherweise noch etwas zu verbessern. Den Code für die 
"optimalen Filter" habe ich irgendwo abgeschrieben. Kann jetzt aber 
nicht genau sagen wo, aber es sollten "optimale" Filter sein. Ich denke 
damit waren Butterworth Filter gemeint. Bei Tiefpässen passt das auch 
recht gut, falls nicht zu wenige Taps gewählt wurden, was sich dann in 
Abweichungen der Ruhelage bzw. Ausgangslage zeigt.

von derguteweka (Gast)


Lesenswert?

Manfred M. schrieb:
> Was kannst Du da empfehlen?
Die Frage hab' ich befuerchtet - hab' aber leider grad keine Empfehlung 
zur Hand.


> Ok, da ist möglicherweise noch etwas zu verbessern.
Naja, nicht unbedingt - es kommt halt drauf an, was du willst...

> Den Code für die
> "optimalen Filter" habe ich irgendwo abgeschrieben. Kann jetzt aber
> nicht genau sagen wo, aber es sollten "optimale" Filter sein.
Das sieht so aus als ob's ein Filter nach der "least squares" Methode 
ist.
Das hat halt diesen Ripple im Durchlass- und Sperrbereich, besonders im 
Uebergang. Dafuer eben konstante Gruppenlaufzeit.

> Ich denke
> damit waren Butterworth Filter gemeint.
Nein, ein Butterworth hat keinen Ripple in der Uebertragungsfunktion, 
aber dafuer auch keine konstante Gruppenlaufzeit.

Kommt immer drauf an, was du moechtest.
Wenn du ein Rezept fuer Frankfurter Kranz nachbaeckst, kommt halt keine 
Schwarzwaelder Kirsch raus, kann aber trotzdem lecker sein...

Gruss
WK

von Manfred M. (bittbeisser)


Angehängte Dateien:

Lesenswert?

Ups, das geht jetzt aber schneller als ich schreiben kann.

> Hast du denn schon einen funktionierenden Tiefpass?
Ja, und da sehe ich keine Probleme (siehe Anhang).

> Deein geplotteter Frequenzgang, ist das die Fouriertransformierte deines
Ausgangssignals oder wie hast du den berechnet?

Also wie anfangs angedeutet, die Kurven sind nicht berechnet, nur die 
Filter Parameter, die Kurven kommen dadurch zustande, das ich 
entsprechende Signale in die Filter schicke und dann sehe was hinten 
rauskommt. Im Frequenzbereich gibt es da einige Probleme wegen 
ungünstiger Phasenlage des Oszillators, der ja wegen der starren 
Phasenkopplung bei bestimmten Verhältnissen der Messfrequenz zur 
Abtastfrequenz niemals den gesuchten Maximalwert ergibt, aber dieses 
Problem sollte im Zeitbereich nicht auftreten.

Im Zeitbereich schicke ich erstmal so viele Samples in das Filter, wie 
es Taps hat (Einschwingvorgang). Dann mache ich 20 Messungen (mit 
wechselner Phasenlage nach 10 Samples) und versuche davon den 
Maximalwert zu erhaschen. Normalerweise funktioniert das, ausser bei 
bestimmten Frequenzverhältnissen. Eigentlich müsste ich dafür ein 
analoges Rekonstruktionsfilter haben. Aber diese Fehler äussern sich 
eigentlich nur in "Dropouts" bei bestimmtem markanten Frequenzen und 
sind eigentlich kein wirkliches Problem, da die Fehler offensichtlich 
sind.

von C Programmierer (Gast)


Lesenswert?

Also im Anhang sehe ich den Frequenzgang eines mehr oder weniger 
funktionierenden Tiefpasses. Aber der Frequenzgang deines Hochpass ist 
doch auch richtig. Nur die Sprungantwort dazu stimmt nicht. Deshalb hätt 
mich die Sprungantwort vom Tiefpass im Zeitbereich interessiert.

Ich verstehe nicht, was ein Oszillator damit zu tun haben soll und wo 
der Unterschied zwischen der Messfrequenz und der Abtastfrequenz sein 
soll.

von C Programmierer (Gast)


Lesenswert?

Ein villeicht etwas überdimensioniertes aber hilfreiches Buch könnte der 
Tietze-Schenk sein.

von Manfred M. (bittbeisser)


Angehängte Dateien:

Lesenswert?

Also welche Berechnungsmethode ich verwendet habe, kann ich jetzt nicht 
genau sagen, aber etliches habe ich von http://www.iowahills.com/ 
übernommen. Bei den Fensterfuktionen weiss ich das genau.

> Deshalb hätt mich die Sprungantwort vom Tiefpass im Zeitbereich interessiert.
Siehe Anhang.

> Ich verstehe nicht, was ein Oszillator damit zu tun haben soll ...
Das bezog sich auf den Frequenzgang. Da muss ich ja die Amplituden der 
einzelnen Abtastwerte zum jeweiligen Zeitpunkt und passend zur 
gewünschten Messfrequenz berechnen. Diesen Programmteil habe ich 
Oszillator genannt.

von derguteweka (Gast)


Lesenswert?

Moin,

C Programmierer schrieb:
> Nur die Sprungantwort dazu stimmt nicht.

Wieso soll die nicht stimmen? Da ist alles primapronto. Natuerlich sieht 
die Sprungantwort eines Butterworth-Hochpasses anders aus. Es ist halt 
kein Butterworth. Aber trotzdem ein Hochpass, sogar einer mit besserem 
Phasenverhalten als beim Butterworth.

Gruss
WK

von C Programmierer (Gast)


Lesenswert?

Manfred M. schrieb:
> Siehe Anhang.

Das sieht nach der richtigen Sprungantwort eines idealen Tiefpass aus. 
Nämlich das Integral der SI-Funktion über der Zeit.

Und wie ich schon vorher schrieb: Eingangssignal-(Ausgangssignal 
Tiefpass)=Ausgangssignal Hochpass.

In diesem Fall eine Spiegelung des Signals bei 0,5 V. D.h., wenn dir 
nichts besseres einfällt, kannst du deinen Hochpass aus deinem Tiefpass 
bauen, da der richtig funktioniert.

Manfred M. schrieb:
> Das bezog sich auf den Frequenzgang. Da muss ich ja die Amplituden der
> einzelnen Abtastwerte zum jeweiligen Zeitpunkt und passend zur
> gewünschten Messfrequenz berechnen.

Outch! Das ist viel zu kompliziert und viel zu ungenau (man muss auf 
einen eingeschwungenen Zustand warten, der theoretisch nie existiert). 
Für sowas gibts die Fourier-Transformation.

derguteweka schrieb:
> Wieso soll die nicht stimmen? Da ist alles primapronto.

Weil ein Tiefpass immer einen Sprung hat, wenn das Eingangssignal auch 
springt. Hier gibt es zwar einen Sprung aber eben zeitverzögert.

Bei diesem Filter hat der Nenner der Übertragungsfunktion eine höhere 
Ordnung als der Zähler. Daraus folgt, dass für gegen unendlich gehende 
Frequenzen die Amplitude gegen Null geht => Kein Hochpass.

Wenn das Signal vor dem Sprung um 1 Volt höher wäre, also der Sprung 
dort nicht vorhanden wäre, dann wäre es ein (idealer) Hochpass und 
ergäbe die oben gennante Spiegelung bei 0,5 V.

von derguteweka (Gast)


Lesenswert?

Moin,

C Programmierer schrieb:
> Das sieht nach der richtigen Sprungantwort eines idealen Tiefpass aus.
> Nämlich das Integral der SI-Funktion über der Zeit.
Jepp.

> Und wie ich schon vorher schrieb: Eingangssignal-(Ausgangssignal
> Tiefpass)=Ausgangssignal Hochpass.
Jepp.

> In diesem Fall eine Spiegelung des Signals bei 0,5 V. D.h., wenn dir
> nichts besseres einfällt, kannst du deinen Hochpass aus deinem Tiefpass
> bauen, da der richtig funktioniert.
Exakt so isses. Und so kann man auch die Impulsantwort aus dem 1. Post 
erhalten.

> Weil ein Tiefpass immer einen Sprung hat, wenn das Eingangssignal auch
> springt. Hier gibt es zwar einen Sprung aber eben zeitverzögert.

Ja, die Zeitverzoegerung muss sein, damit das Filter kausal ist. Die 
Zeitverzoegerung hat aber keinerlei Einfluss auf den Amplitudengang und 
macht nur bei der Phase eine lineare Verschiebung (=Erhoehung der 
Gruppenlaufzeit um eine Frequenzunabhaengige Konstante).


> Bei diesem Filter hat der Nenner der Übertragungsfunktion eine höhere
> Ordnung als der Zähler. Daraus folgt, dass für gegen unendlich gehende
> Frequenzen die Amplitude gegen Null geht => Kein Hochpass.
Neeneee, das waere ja s-Ebene. Wir sind aber doch in der z-Ebene; da 
geht nicht klein Omega gegen unendlich, sondern gross Omega gegen -1.

> Wenn das Signal vor dem Sprung um 1 Volt höher wäre, also der Sprung
> dort nicht vorhanden wäre, dann wäre es ein (idealer) Hochpass und
> ergäbe die oben gennante Spiegelung bei 0,5 V.
Uiuiui, dann waer's ein ganz komisches System (Eines, was vor Anregung 
schon bei 1 ist - das gibt Probleme mit der Linearitaet).
Anderer Vorschlag:
Du nimmst die Sprungantwort des Tiefpasses, also TP_sr_01.png.
Die spiegelst du an der Zeitachse, also so, dass sie nicht mehr gegen 
+1, sondern gegen -1 geht. Dann isses immernoch ein Tiefpass. Aber einer 
mit "Verstaerkung" von -1. Zu dieser Sprungantwort addierst du einen 
zeitlich verzoegerten "Einheitssprung", der so ungefaehr bei t=1.25ms 
losspringt. Dann hast du die Sprungantwort des Hochpasses, die euch 
nicht so dolle gefaellt.
Wie du oben schon schriebst:
> Und wie ich schon vorher schrieb: Eingangssignal-(Ausgangssignal
> Tiefpass)=Ausgangssignal Hochpass.
Also: alles bestens mit dem Hochpass, auch wenn der Ausgang den "Sprung" 
nicht bei t=0, sondern erst bei t=1.25ms hat - ist halt ein Hochpass mit 
einer Verzoegerung (die aber eben, ich kanns nur nochmal betonen, fuer 
einen "schoeneren" Phasengang/Gruppenlaufzeit als beim Kollegen 
Butterworth sorgt).

Gruss
WK

von Manfred M. (bittbeisser)


Lesenswert?

Ich habe inzwischen die ursprüngliche Quelle wiedergefunden: 
http://www.cardinalpeak.com/blog?p=1841 Welche Methode da verwendet 
wird, steht da nicht. Aber das wesentliche ist wohl dies:
1
Filter::Filter(filterType filt_t, int num_taps, double Fs, double Fx)
2
{
3
    ...
4
    m_lambda = M_PI * Fx / (Fs/2);
5
    ...
6
    init();
7
    if( m_filt_t == LPF ) designLPF();
8
    else if( m_filt_t == HPF ) designHPF();
9
    else ECODE(-5);
10
    return;
11
}
12
13
void 
14
Filter::designHPF()
15
{
16
    int n;
17
    double mm;
18
19
    for(n = 0; n < m_num_taps; n++){
20
        mm = n - (m_num_taps - 1.0) / 2.0;
21
        if( mm == 0.0 ) m_taps[n] = 1.0 - m_lambda / M_PI;
22
        else m_taps[n] = -sin( mm * m_lambda ) / (mm * M_PI);
23
    }
24
    return;
25
}

> Outch! Das ist viel zu kompliziert und viel zu ungenau (man muss auf
> einen eingeschwungenen Zustand warten, der theoretisch nie existiert).
> Für sowas gibts die Fourier-Transformation.
Ich bin ja auf diesem Gebiet kein Profi und ausserdem wollte ich etwas 
haben, was mir das tatsächliche Verhalten Zeigt, also auch die 
Auswirkungen von ungenauen Koeffizienten.

Und das mit dem eingeschwungenen Zustand ist kein Thema, denn FIR Filter 
sind immer endlich, da es keine Rückkopplung gibt. Man kann das auf dem 
ersten Bild auch gerade noch erkennen. Die Überschwinger hören bei 
2.65ms plötzlich auf. Das ist ziemlich genau die Länge des Filters 
(1000ms*127tabs/48000).

Aber diese Überschwinger habe ich noch nirgends woanders gesehen.

> Hier gibt es zwar einen Sprung aber eben zeitverzögert.
Ich bin mir nicht sicher, aber ich glaube diese Verzögerung gibt es bei 
allen FIR Filtern.

von C Programmierer (Gast)


Lesenswert?

derguteweka schrieb:
> Ja, die Zeitverzoegerung muss sein, damit das Filter kausal ist.

Nein, die Zeitverzögerung (des Sprungs) muss nicht sein. Den Sprung kann 
man auch zum Zeitpunkt t=0 stattfinden lassen.

derguteweka schrieb:
> Neeneee, das waere ja s-Ebene. Wir sind aber doch in der z-Ebene; da
> geht nicht klein Omega gegen unendlich, sondern gross Omega gegen -1.

Das kann sein. Mit der z-Ebene kenn ich mich nicht so aus. Aber da die 
maximal zulässige Frequenz kleiner als die halbe Abtastfrequenz ist, 
wirst du wohl recht haben.

derguteweka schrieb:
> Uiuiui, dann waer's ein ganz komisches System (Eines, was vor Anregung
> schon bei 1 ist - das gibt Probleme mit der Linearitaet).

Da haben wir aneinander vorbeigeredet. Ideal müsste die Sprungantwort 
bei t=0 und x = 1V beginnen und beim ca. 1,3 ms nach unten gehen (ohne 
Sprung).


Es handelt sich bei dem System um einen idealen Hochpass mit der 
Verstärkung 1 und einer darauf addierten Zeitverzögerung mit der 
Verstärkung 1 und einer Durchschaltkonstanten mit der Verstärkung -1.

Es sind also sogar 2 Fehler in den Koeffizienten vorhanden.

Ich hab mal eine Frequenzanalyse gemacht und das System ist zu meinem 
Erstaunen tatsächlich ein Hochpass.

@Manfred: Schau dir mal den in der mitte liegenden FIR-Koeffizienten an. 
Einer oder zwei davon müssten stark aus der Reihe der anderen fallen. Da 
musst du den Fehler suchen, warum dieser nicht gleichmäßig zu den 
anderen passt. Dort findest du den Fehler der daraufaddierten 
Zeitverzögerung. Danach müsstest gucken woher noch die 
Durchschaltkonstante kommt.

Manfred M. schrieb:
> Ich bin mir nicht sicher, aber ich glaube diese Verzögerung gibt es bei
> allen FIR Filtern.

Nein, der erste Koeffizient gibt die Verstärkung zum jeweils aktuellen 
Zeitpunkt an. Wenn der z.B. auf 1 ist und alle anderen auf 0, dann ist 
Eingangssignal = Ausgangssignal.

von C Programmierer (Gast)


Lesenswert?

Manfred M. schrieb:
> if( mm == 0.0 ) m_taps[n] = 1.0 - m_lambda / M_PI;

Da sehe ich den Fehler (bei dem mittleren FIR-Koeffizienten). Müsste es 
nicht heißen:
1
if( mm == 0.0 ) m_taps[n] = -m_lambda / M_PI;

, da der Grenzwert von "-sin( mm * m_lambda ) / (mm * M_PI)" für mm = 0 
nach meinem überfliegen = -m_lambda / M_PI ist?

von C Programmierer (Gast)


Lesenswert?

Kann es sein, dass dein Filter so richtig wäre und deine erwartete 
Sprungantwort ausgibt?
1
for(n = 0; n < m_num_taps; n++){
2
        mm = n - (m_num_taps - 1.0) / 2.0;
3
        if( mm == 0.0 ) m_taps[n] = 1.0 - m_lambda / M_PI;
4
        else m_taps[n] = 1.0-sin( mm * m_lambda ) / (mm * M_PI);
5
    }

von derguteweka (Gast)


Angehängte Dateien:

Lesenswert?

Moin,

> derguteweka schrieb:
>> Ja, die Zeitverzoegerung muss sein, damit das Filter kausal ist.
>
> Nein, die Zeitverzögerung (des Sprungs) muss nicht sein. Den Sprung kann
> man auch zum Zeitpunkt t=0 stattfinden lassen.

Nein; das Zauberwort in dem Link bei cardinalpeak.com ist: "linear 
phase".
Damit muss die Impulsantwort achsen- oder punktsymmetrisch sein; damit 
muss der Sprung verschoben sein, sonst ist das Filter nicht kausal.

> Da haben wir aneinander vorbeigeredet. Ideal müsste die Sprungantwort
> bei t=0 und x = 1V beginnen und beim ca. 1,3 ms nach unten gehen (ohne
> Sprung).
Ohne den Sprung waer's ein Tiefpass; wenn du aber ein System hast, was 
ohne Anregung schon irgendeinen konstanten Wert !=0 ausgibt, dann ist 
das nicht linear.


> Es handelt sich bei dem System um einen idealen Hochpass mit der
> Verstärkung 1 und einer darauf addierten Zeitverzögerung mit der
> Verstärkung 1 und einer Durchschaltkonstanten mit der Verstärkung -1.

Es ist ein idealer Tiefpass, der durch die addierte "Zeitverzoegerung" 
und das andere Gedoens zum Hochpass wird.

> Es sind also sogar 2 Fehler in den Koeffizienten vorhanden.
Neee, da ist alles OK. Ehrlich :-)

> Ich hab mal eine Frequenzanalyse gemacht und das System ist zu meinem
> Erstaunen tatsächlich ein Hochpass.
1
<loriot_mode=on>Ach<loriot_mode=off>

> @Manfred: Schau dir mal den in der mitte liegenden FIR-Koeffizienten an.
> Einer oder zwei davon müssten stark aus der Reihe der anderen fallen. Da
> musst du den Fehler suchen, warum dieser nicht gleichmäßig zu den
> anderen passt. Dort findest du den Fehler der daraufaddierten
> Zeitverzögerung. Danach müsstest gucken woher noch die
> Durchschaltkonstante kommt.
Ja genau, ein FIR-Koeffizient "tanzt" aus der Reihe, wenn er's nicht 
taete, waers kein Hochpass, sondern ein Tiefpass. Da gibts keinen 
Fehler, alles in Butter.

> Manfred M. schrieb:
>> Ich bin mir nicht sicher, aber ich glaube diese Verzögerung gibt es bei
>> allen FIR Filtern.
Wie ich oben schon schrub: Wenn man ein linearphasiges Filter haben 
will, dann muessen die Koeffizenten symmetrisch sein; das krieg ich 
kausal nur hin, wenn ich eben die Verzoegerung einbau'.
Wenn mir aber die Phase wurscht ist, dann kann ich natuerlich auch ein 
FIR Hochpass mit nicht symmetrischen Koeffizienten bauen, das hat dann 
eine Impuls/Sprungantwort aus dem "Bilderbuch".
Fuer das angepappte Bild hab' ich die Impulsantwort eines Butterworth 4. 
Ordnung einfach mal nach 32 Takten abgeschnitten; dann sieht man oben 
den Frequenzgang; die Sperrdaempfung ist recht schlecht geworden 
dadurch, es gibt bisschen Ripple im Durchlass und unten die 
Impulsantwort; und da ploppt sofort der erste Koeffizient 
hoch...jippiee...

Das eine ist halt Schwarzwaelder Kirsch, das andere Frankfurter Kranz. 
Beides Torten, aber doch verschieden.

Gruss
WK

von Manfred M. (bittbeisser)


Angehängte Dateien:

Lesenswert?

> @Manfred: Schau dir mal den in der mitte liegenden FIR-Koeffizienten an.
> Einer oder zwei davon müssten stark aus der Reihe der anderen fallen.
Also da kann ich jetzt keinerlei Abnormitäten erkennen. Der mittlere 
Wert ist  0.916666667 und die umliegenden Werte sind alle negativ aber 
symmetrisch zur Mitte.

@C Programmierer: Der erste Veränderungsvorschlag führt dazu, das dass 
Filter zu einem Tiefpass wird, dessen Sprungantwort um die x-Achse 
gespiegelt ist. Sieht auch komisch aus.

Der zweite Vorschlag sieht noch schlimmer aus. Das System scheint wild 
hin- und her zu schwingen. Aber mit etwas gutem Willen könnte man auch 
hier einen Tiefpass als Grundsystem vermuten.

Nach allem was ich jetzt gelesen habe, muss die Verzögerung bei FIR 
Filtern sein, damit sie kausal sind. Das war auch nicht mein Problem. 
Mich irritierten vielmehr die Überschwinger in der Sprungantwort und 
dass die Höhe der Maxima zu niedrig erscheint.

von C Programmierer (Gast)


Lesenswert?

@ Manfred:

Die Sprungantwort, die wir beide (oder zumindest ich) erwartet haben 
dürfte durch folgenden Code entstehen:
1
for(n = 0; n < m_num_taps; n++){
2
        mm = n - (m_num_taps - 1.0) / 2.0;
3
        if( mm == 0.0 ) m_taps[n] = - m_lambda / M_PI;
4
        else m_taps[n] = -sin( mm * m_lambda ) / (mm * M_PI);
5
    }
6
m_taps[0]+=1;

Dies ist aber nicht die Sprungantwort eines idealen HP. WK hat recht. 
Die Sprungantwort aus dem ersten Post ist richtig.

von Manfred M. (bittbeisser)


Angehängte Dateien:

Lesenswert?

> Dies ist aber nicht die Sprungantwort eines idealen HP.
Ja, die Sprungantwort sieht so aus, wie du sie zuvor beschrieben hast. 
Aber ich habe keine Ahnung was das für ein Gebilde ist. Im angehängten 
Bild habe ich auch mal meinen Code eingeblendet.

Der sieht etwas anders aus, da man bei Verwendung eines Ringpuffers für 
die Eingangsdaten die Koeffizienten eigentlich in umgekehrter 
Reihenfolge speichern muss, was aber nur zum Tragen kommt, wenn diese 
nicht symmetrisch sind.

Aber dieser Versuch hat mir zu einer neuen Erkenntnis verholfen. Diese 
Filter haben grundsätzlich Riples, und zwar:
 Ripleanzahl = halbe_Abtastfrequenz / Tabs

Und genau die Anzahl Riples, die in den HP Sperrbereich fallen, scheinen 
in der Sprungantwort durchzuschlagen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.