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?
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?
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
> 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
doubleDIG_Filter::filters(doublein){
4
intit;// tap (reg) index
5
intib;// b coefficient index
6
doublesum;
7
8
inbuf[ix++]=in;// store input and advance index to oldest sample
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
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?
@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.
< 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.
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
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.
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.
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.
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
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.
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
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:
> 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.
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.
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?
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
> @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.
> 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.