Hallo =)
Ich möchte - nun als praktische Anwendung der Regelungstechnik +
Digitaler Signalverarbeitung - eine Motorsteuerung bauen. Es geht hier
erst einmal um das Berechnen/Anzeigen der Winkelposition und der
Geschwindigkeit.
Ich habe sowohl Digisiv, Nachrichtentechnik und Steuerungs- und
Regelungstechnik in der Uni gehört, die theoretischen Grundlagen sollten
da sein. Aber die praktische Umsetzung natürlich nicht -.-
Los gehts:
An der Motorwelle ist ein Inkrementalencoder befestigt, mit 5000
Steps/Umdrehung. Der Encoder hat einen Quadraturausgang, der über einen
Pegelwandler mit einem STM32 verbunden ist. Der uC besitzt in Hardware
einen Encodereingang. Da der STM32 4-fach Abtastet ergeben sich 20000
Counts/Umdrehung. Das Counter Reset Register habe ich auch auf 20000
eingestellt, weil ich damit dann genau detekieren kann, wie viele
Umdrehungen stattgefunden haben (oder würdet ihr den Wert höher
ansetzen, das Register ist 16 Bit breit).
Nun wird mit 100Hz dieses Register abgetastet, in einen Puffer
geschrieben und per UART rausgeschickt. Per Matlab greife ich auf die
serielle Schnittstelle zu und baue aus den Hex Werten meine Zahlen
zusammen.
Weil nach einer Umdrehung der Überlauf kommt, ist die Kurve natürlich
unstetig. Ich habe versucht, mir die Kurve stetig fortzusetzen, indem
ich die Sprungstellen detektiere (ganz primitiv):
1
n=1
2
for i=1:ende
3
if((angle(i) > 1.8e4 && angle(i+1) < 0.05e4))
4
sprung_hoch(n)=i
5
n++
6
end
Die Grenzen sind erstmal willkürlich gesetzt. Wenn es da vernünftige
Vorschläge gibt, wie ich die berechnen kann, immer her damit ;)
Das ganze für sprung_runter analog.
Dann addiere bzw subtrahiere ich ab den jeweiligen Sprungstellen 20000.
Die Kurve sieht dann auch schön fortgesetzt aus.
Von den "kontinuierlichen" Winkeldaten möchte ich dann die
Geschwindigkeit berechnen, also Differenzenquotient von je zwei
benachbarten Werten. Da geht die Sache natürlich schon los, es wird sehr
zackelig. Diese Werte habe ich mit einem moving average Filter
(einfacher FIR, mit den 16 Koeffizienten 1/16). Sieht besser aus (halt
geglättet), aber in einem anderen Thread wurde bereits angemerkt, dass
dies nicht der richtige Weg sein könnte.
Soweit der Stand der Dinge.
Jetzt habe ich einige Fragen (es geht momentan um die Nachbearbeitung
einer Messkurve in Matlab. Es geht noch nicht um die Regelung!)
- Die Abtastfrequenz sollte mehr als doppelt so hoch sein, wie die
Grenzfrequenz/Signalfrequenz des Signals. Aber wie ist die
Grenzfrequenz? Da ich noch gar keinen Filter angewendet habe wird das
Signal ja kaum bandbegrenzt sein.
- Was ist überhaupt die "Signalfrequenz"? Die Drehfrequenz des Winkels?
Die kann ja u.U. ziemlich groß werden ;) Ich nehme daher mal
3000u/min=50u/s an. Pro Umdrehung gibts 4*5000 Steps -> 1e6 steps/s.
Krass :D. Wenn ich zweimal abtasten möchte bei dem Register, das bei
20000 überläuft muss ich mit 100Hz abtasten: 1e6
steps/s/20000steps=50/s. Doppelt soviel -> >100Hz. Stimmt das?
- Muss ich das aufgezeichnete Winkelsignal jetzt fortsetzen, wie oben
beschrieben, oder ist es sinniger das als eine Art Sägezahn Signal
aufzufassen? Fortgesetzt wirkt es halt realistisch, gibt den echten
Winkel an.
- Wenn ich langsamer als mit 3000u/min drehe habe ich mehr Abtastpunkte
pro Umdrehung. Da könnten z.B. auch Ausreißer drin sein, wie glätte ich
die?
- Sollte man mit den Abtastpunkten weiter rechnen (und durch Ausreißer
heftige Sprünge in Kauf nehmen), oder sollte man versuchen das Signal zu
interpolieren und damit wieder quasi Analog machen (splines?)?
- Sollte ich ein (möglichst ideales) Eingangsfilter (TP) mit 50Hz
ansetzen? Dadurch bekäme ich jedoch höhere Umdrehungen nicht mit, oder
gingen die eh im Alias unter?
- Matlab bietet ja diverse Filter an, die einen besseren Frequenzgang
haben, als der einfache Differenzenquotent : v(n)=(q(n+1)-q(n))/T, der
eher Hochpass als Tiefpasscharakteristik aufweist. Aber wenn ich die
anwende, erhalte ich dann überhaupt noch die Geschwindigkeit? Wenn ich
eine höhere Ordnung wähle könnte doch auch schon die Beschleunigung
rauskommen?
- Wie glätte ich am besten meine zackeligen Kurven ohne relevante
Informationen zu verlieren?
In der Theorie gabs nämlich immer eine wunderschöne gerade, stetige
Kurve eines Motors, da musste nix mehr geglättet werden, sowas haben wir
einfach nicht gelernt :/
Und je nachdem, wie groß der Aufwand oben wird (z.B. mit
Eingangsfilter), wie soll man denn sowas in dem uC in Echtzeit zur
Regelung verwenden? Geht doch garnicht? Ich kann doch nur aus den paar
Werten, die ich gerade habe eine Geschwindigkeit berechnen. Wenn die
schon zackelig sind, wie soll die Regelung da vernünftig klar kommen?
Ihr seht, Fragen über Fragen. Ich bedanke mich ganz herzliche bei
denjenigen, die sich das Spektakel hier durchgelesen haben.
Wenn noch was unklar ist, fragt nach ich Antworte zeitnah ;)
Danke und schöne Grüße!
:-) schrieb:> Die Abtastfrequenz sollte mehr als doppelt so hoch sein, wie die> Grenzfrequenz/Signalfrequenz des Signals.
Du willst das Signal ja nicht mehr rekonstruieren daher musst du nicht
mit der doppelten Frequez abtasten.
Chris schrieb:> Du willst das Signal ja nicht mehr rekonstruieren daher musst du nicht> mit der doppelten Frequez abtasten.
Das ist meines Erachtens ein Blödsinn, woher soll man dann wissen ob der
Motor zwischen zwei Abtastpunkten 1,2 oder 100 Umdrehungen gemacht hat?
Du kannst mit Deinem Winkelgeber eine ganze Umdrehung auflösen
(Genauigkeit = Anzahl der Schritte ist für diese Überlegung egal).
Damit Du nun JEDE Umdrehung in Deinen Messergebnissen siehst musst Du
den Winkelgeber mindestens doppelt so häufig auslesen als der Motor
maximal drehen kann (darf).
Das heißt mit einer Abtastrate von 100Hz (=Ausleserate aus dem Register)
darf der Motor nur mit 50Hz (50 Umdrehungen pro Sekunde) laufen.
Die Abtastzeitpunkte müssen natürlich EXAKT 1/100s auseinander liegen.
Die Auflösung (Anzahl der Schritte für eine vollständige Umdrehung) ist
egal für die Berechnung der Abtastrate. Die Auflösung der Winkel
(=Anzahl der Schritte für eine Umdrehung) entspricht der Quantisierung
Deines Eingangssignals und hat nichts mit dem Shannontheorem zu tun.
Selbst wenn Du nur mit z.B. 4 Schritten Deine Umdrehung auflöst, d.h.
pro pi/2 einen Wert, musst Du mit einer Rate Abtasten die mindestens
doppelt so hoch ist wie Deine maximale Umdrehungen/s.
Zitat:
> - Wie glätte ich am besten meine zackeligen Kurven ohne relevante> Informationen zu verlieren?
Wie genau willst Du eigentlich die Geschwindigkeit Deines Motors messen?
Gemittelt, sagen wir über eine (mehrere) vollständige Umdrehungen, oder
instantan während einer Umdrehung?
Wie im anderen thread schon besprochen, Dein Filter v[n] = (x[n+1] -
x[n]) *0.5 ist akausal. Da wirds schwierig mit einer Echtzeitregelung.
Für mein Verständis bedeutet die Formel auch folgendes: Wo ist der Motor
in Zukunft, davon ziehe ich die Gegenwart ab und das ist (ich habe die
Skalierungen 1/T usw. nun nicht notiert, da Du sowieso äquidistant
(hoffentlich) abtastest und dieser Faktor nur eine Multiplikation mit
einer Konstanten bedeuten würde) meine Gegenwärtige Geschwindigkeit.
Ich habe gelernt das die Momentangeschwindigkeit so berechnet wird:
Wo war das Objekt vorher, wo ist es jetzt -> "Ort jetzt - Ort
vorher"/Zeit
bzw. wenn Du den einfachsten Differenziator verwenden willst v[n] = x[n]
- x[n-1] .
Hast Du den Link durchgearbeitet aus dem anderen Thread?
lg
russenbaer
Hallo Russenbär.
Das ganze klingt soweit logisch und nachvollziehbar. Selbst wenn ich nur
wenige Steps/Umdrehung hätte, müsste ich trotzdem mehr als doppelt so
schnell abtasten, wie der Motor läuft.
Ich habe übrigens noch ein Register, das mir die Dreh- bzw Zählrichtung
angibt, aber das nur am Rand.
Zu deiner Befürchtung: Die Abtastpunke sind äquidistant und der
Interrupt des Timers hat eine hohe Priorität.
Der Motor hat eine Nenndrehzahl von 3000u/min @ 40V. Auf die 40V werden
wir eher nicht kommen (der wird später per PWM geregelt), er soll eher
Positionen genau anfahren können. Daher reicht eine Mittelung über z.B.
eine oder eine halbe Umdrehung nicht, sondern die
Geschwindigkeitsberechnung sollte in möglichst kurzen Zeitabständen
erfolgen.
Es soll später zwei Betriebsmodi geben. Einmal Geschwindigkeiten
"abfahren" (aus einer Tabelle zum Beispiel), oder Winkel anfahren (bei
beiden Modi wird der Motor - wenn überhaupt 1 oder 2 Umdrehungen machen,
mehr nicht. Aber in beide Richtungen).
Das Auslesen per Matlab ist jetzt erst einmal fürs Aufnehmen der
Motorkennlinie und der Sprungantwort gedacht.
Ja den Artikel habe ich durchgelesen und denke auch verstanden. Der
"normale" Vorwärtsdifferenzenquotient ist akausal, ja. Für Echtzeit eher
blöd. Wie gesagt, der kam mir nur am "natürlichsten" vor. Hier die
anderen Varianten:
http://de.wikipedia.org/wiki/Differenzenquotient#Varianten
Ich habe die in deinem Link angegebene Variante mit dem schöneren
Frequenzgang ausprobiert. Der erzeugt schon eine hübschere Kurve, aber
sollte ich den auch in der Echtzeitregelung Verwenden? Gespeichert habe
ich die Werte ja eh, denke das Berechnen dauert auch nicht so lang, aber
ist das sinnvoll vom Physikalischen her?
Noch was: Falls aus irgendeinem Grund die Drehzahl des Motors doch mal
höher als die angestrebten 50/s(kurzzeitig) sind, so bekomme ich
Aliaseffekte. Dann wird unter Umständen eine falsche Geschwindigkeit
angenommen. Sollte man daher das Signal vorher noch durch den Tiefpass
jagen (wie z.B. in NT Grundsätzlich gemacht wurde), oder ist das in der
Praxis (hier im uC) nicht erforderlich?
Vielleicht mache ich mir ja auch zu viele Gedanken, so eine blöde
Motorsteuerung haben schon viele gebaut Google zufolge, solche Gedanken
wurden sich da irgendwie nicht gemacht :D
Danke für eure Hilfe!
Ich muss mich leider korrigieren: Der Filter aus dem Artikel macht
deutlich ausgefranstere Kurven, als der einfache diff Filter. Werde
gleich mal ein Bild anhängen.
Und noch was: eigentlich gilt das Abtasttheorem ja nur für Sinusförmige
Kurven. Bedeutet hier: Ich müsste eigentlich noch viel höher abtasten,
wollte ich das eigentliche Signal rekonstruieren.
Das war nur nochmal eine kleine Korrektur meiner Gedanken oben ;)
:-) schrieb:> Und noch was: eigentlich gilt das Abtasttheorem ja nur für Sinusförmige>> Kurven.
Es gibt für die höchste Frequenz in Deinem Sigal. Das ist der
tiefrequenteste Sinus innhalb der Quadraturpulse also Fkator 2 x
Frequenz.
Nach oben kann man das theoretisch bis unendlich fortsetzen, muss es
aber nicht. Es reicht die 5. oberwelle, die eine guten Kompromiss
darstellt, weil Du mit dem Sinus ohne eine Oberwelle die Phase
schlechter messen kannst - wegen der Ungeaugikeiten.