Moin, ich brächte mal Hilfe bezüglich eines Reglerentwurfs in VHDL. Mein gegenwärtiges Problem : ich bekomme Quadratursignale aus einem Encoder, die ich in meinen FPGA einlese. Nun möchte ich zusätzlich zu der Position die Geschwindigkeit aus meinem Encoderblock ausgeben um beide Größen mit Hilfe eines PID Reglers zu regeln. Jetzt dachte ich, könnte ich einfach die Position ableiten und hätte dann die Geschwindigkeit, aber da hab ich wohl falsch gedacht... Kurzum, wie differenziert, bzw. integriert man in VHDL? Über Hilfe würde ich mich freuen! Beste Grüße Dave
Dave schrieb: > Kurzum, wie differenziert, bzw. integriert man in VHDL? Vergiss solche abstrakten Begriffe wie "differenzieren" und "integrieren" und "ableiten" vorerst mal. Für die Ermittlung einer Geschwindigkeit gibt es pragmatischerweise 2 Wege: 1. man misst die Zeit zwischen 2 Impulsen. Das ist ein wenig blöd, weil man dann für die Geschwindigkeit erst noch den Kehrwert bilden muss. Und es ist dumm, dass beim Stillstand die Zeit unendlich wird... 2. man nimmt ein feste Zeit und misst welche Strecke in dieser Zeit zurückgelegt wird.
:
Bearbeitet durch Moderator
Also Geschwindigkeit kann man schon aus dem Weg ermitteln. Ich schreibe das mal etwas abstahiert: angenommen du hast einen Takt /sek Das ganze musst di in einen Process machen, sofern du VHDL nutzt: diverse Variablen erstmal deklarieren und dann: geschwindigkeit <= pos_n - pos_n_1; pos_n_1<=pos_n; pos_n ist der aktuele Wert, pos_n_1 der Wert vom letzten Takt. So erhällst du Quasi die Geschwindigkeit (Weg/Takt) für den Fall, dass sich das Wegsignal pro Takt zu wenig ändert, summierst du das Ganze sagen wir 256x auf. Das Ganze Teilst du dann durch 256 (einfach die letzten 8 bit wegwerfen). und führst oben das mit dem Ergebnis aus. Das ist quasi differenzieren.... Integrieren geht ähnlich: integrierter_wert<=integrierter_wert+neuer_wert;
So in der Art hab ich mir das auch vorgestellt, aber so ganz versteh ich das noch nicht. Wenn ich das mal an dem Beispielcode von Lothar Miller festmache, müsste das doch ungefähr so aussehen:
1 | library IEEE; |
2 | use IEEE.STD_LOGIC_1164.ALL; |
3 | use IEEE.NUMERIC_STD.ALL; |
4 | |
5 | entity Encoder is |
6 | Port ( clk : in STD_LOGIC; |
7 | A : in STD_LOGIC; |
8 | B : in STD_LOGIC; |
9 | Position : out STD_LOGIC_VECTOR (31 downto 0); |
10 | Geschw : out STD_LOGIC_VECTOR (31 downto 0)); |
11 | end Encoder; |
12 | |
13 | architecture Behavioral of Encoder is |
14 | type zustaende is (Z00, Z01, Z11, Z10); |
15 | signal z : zustaende := Z00; |
16 | signal p : integer := 0; |
17 | signal g : integer := 0; |
18 | signal p_alt : integer := 0; |
19 | signal i : std_logic_vector(1 downto 0); |
20 | signal e : std_logic_vector(1 downto 0); |
21 | begin
|
22 | process begin -- Eintakten der asynchronen Signale |
23 | wait until rising_edge(clk); |
24 | i <= A & B; -- Zusammenfassen der Eingänge A und B |
25 | e <= i; |
26 | end process; |
27 | |
28 | process -- Weiterschalten und Zählen |
29 | variable cu, cd : std_logic := '0'; |
30 | begin
|
31 | wait until rising_edge(clk); |
32 | cu := '0'; -- lokale Werte |
33 | cd := '0'; |
34 | case z is |
35 | when Z00 => if (e = "01") then z <= Z01; cu := '1'; |
36 | elsif (e = "10") then z <= Z10; cd := '1'; |
37 | end if; |
38 | when Z01 => if (e = "11") then z <= Z11; cu := '1'; |
39 | elsif (e = "00") then z <= Z00; cd := '1'; |
40 | end if; |
41 | when Z11 => if (e = "10") then z <= Z10; cu := '1'; |
42 | elsif (e = "01") then z <= Z01; cd := '1'; |
43 | end if; |
44 | when Z10 => if (e = "00") then z <= Z00; cu := '1'; |
45 | elsif (e = "11") then z <= Z11; cd := '1'; |
46 | end if; |
47 | end case; |
48 | if (cu='1') then p <= p+1; |
49 | elsif (cd='1') then p <= p-1; |
50 | end if; |
51 | |
52 | g <= (p - p_alt); |
53 | p_alt <= p; |
54 | |
55 | end process; |
56 | |
57 | Position <= std_logic_vector(to_signed(p,32)); -- Position ausgeben |
58 | Geschw <= std_logic_vector(to_signed((g),32)); -- Geschwindigkeit ausgeben |
59 | end Behavioral; |
Als Ergebnis für die Geschwindigkeit, wenn ich jetzt mal noch seine Testbench dazuziehe, kriege ich jetzt als analgoges Signal leider nur 1 bzw. -1 raus, was ja irgendwie auch klar ist, da ich ja nur den alten vom aktuellen Wert abziehe...was verraff ich denn da?
Das ist ok so, das ist ja das Ergebnis der Differenziation. Bei einem Analogendocder bekämst du eben aus dem SIN (I-Signal) den COS und aus dem COS (Q-Signal) den invertierten SIN. Wozu brauchts Du die Differenziation? Für einen echten Differenzialquotient reicht das natürlich nicht. Da musst Du durch die Zeit teilen. Die müsstest du messen und das möglichst genau.
Also ich denke ich beschreibe mein Prfoblem mal etwas genauer: Für die Ansteuerung eines Piezomotors soll ein FPGA eingesetzt werden. Dieser übernimmt sowohl das generieren der Wellenform, als auch das einlesen und Regeln der Position, als auch der Geschwindigkeit. Wie bereits geschrieben, liest ein Encoder meine Position aus und gibt das Quadratursignal an meinen FPGA. Für die Regelung der Position und der Geschwindigkeit sollen zwei PID Regler zum Einsatz kommen. Nun dachte ich halt, das ich aus der Position, die ich ja habe, durch "Ableiten" die Geschwindigkeit errechne, die ich dann dem zweiten Regler übergebn kann. Soweit der Plan. Ich wüsste zur Zeit nicht, wie ich anderweitig eine Geschwindigekitsregelung in VHDL umsetzen könnte, außer halt über den oben genannten Weg.
Regeln kannst Du nur 1 von beiden! Entweder, du regelst die Geschwindkeit und nimmst die falsche Postition in Kauf oder Du regelst die Position und passt die Geschwindigkeit an. Nur 1 von beiden kann stimmen.
Dave schrieb: > Jetzt dachte ich, > könnte ich einfach die Position ableiten und hätte dann die > Geschwindigkeit, aber da hab ich wohl falsch gedacht... Du musst durchaus so verfahren, also den Differenzenquotient anstelle des Differenzialquotienten verwenden. Allerdings hast du in Deinem AB-Signal (Decoder) durch die Stufigkeit gefaltet mit der Abtastung bereits Harmonische enthalten, die zuvor gefiltert werden müssen, sonst erhälst Du als Differenzial mehr Artefakte der Spiegelfrequenzen, also eigentliche Wunschinformation. Du musst also dein Signal durch einen Tiefpass geben, dann abtasten und die abgetasteten Werte vergleichen. Die Differenz / Intervall ist dann der DQ = Delta Y / Delta T (dy/dt). Die Grenzfrequenz des Filters ist dabei entscheidend. (-Shannon).
Ralf schrieb: > Regeln kannst Du nur 1 von beiden! Entweder, du regelst die > Geschwindkeit und nimmst die falsche Postition in Kauf oder Du regelst > die Position und passt die Geschwindigkeit an. Nur 1 von beiden kann > stimmen. Das ist jetzt ein wenig Auffassungsfrage! Wenn beides wichtig ist, muss beides übewacht werden und beides in die Regelschleife einfliessen. Aber bitte nur mit EINEM Regler, der die Summe zweier (gewichteter) Kriterien erhält. Würde man zwei Regler nehmen, würden die gegeneinander arbeiten. Dave schrieb: > Nun dachte ich halt, das ich aus der Position, die ich ja habe, > durch "Ableiten" die Geschwindigkeit errechne, die ich dann dem > zweiten Regler übergebn Wie Du richtig interpretierst, sind beide eng verknüpft. Von daher regelst Du dadurch, dass Du einen Parameter steuerst, nämlich die Beschleunigung! Diese ergibt sich durch die Position Deines Solldrehfeldes, welches in Anrechnung des Motorwinkels einen Vorlauf haben muss. Der Vorlauf muss so gross sein, dass die Beschleunigung = Funktion (Winkeldifferenz, Winkel) - Bremskraft) genau der Änderung der Steuer-Geschwindkeit ist. Diese musst du BRECHNEN! und zwar so, dass du einen Kompromiss bildest zwischen der idealen statischen Sollgeschwindigkeit, die der Motor drehen soll und der fiktiven Geschwindigkeit, die zum Aufrechterhalt der Position nötig ist. Du hast also eine Positionsmessung, eine geglättete Position, daraus eine Geschwindigkeit und daraus eine errechnete Zielposition im nächsten time step, daraus eine Differenz zwischen Sollposition und wahrscheinlich erreichter, daraus eine relative Sollpositionsänderung und damit eine relative Geschwindigkeitsänderung und mit der Strategie von oben damit eine absolute Geschwindigkeitsänderung und damit eine Soll-Beschleunigung. Diese setzt Du ins Verhältnis zur IST Beschleunigung (ebenfalls gemessen) und ermittelst die Beschleunigungsänderung. Diese führt direkt in die Änderung des Drehfeldvorlaufs. Letztens steuerst Du nur also nur einen Parameter, nämlich das Drehfeld. Alles was unterwegs an Messungen und Kriterien oder Wissen einfliesst, muss als Strategie in eine Funktion führen, die auf diesen einen Parameter abgebildet wird. Je nachdem, wieviel Wissen du noch über das motorische System hast, (Momente, Verschmutzung, Federwirkung, Resonanz und Steigungen) kannst du die Änderungen = Differenziale mehr oder weniger gut präzisieren und feiner = leiser = stromsparender = verschleissärmer und auch schneller werden. Jeder Fehler, der aus Nichtwissen bei den Änderungen und der Steuerung gemacht wird, muss ansonsten im nächsten Schritt wieder weggeregelt werden. Interessant ist hierbei das exakte Wissen über die Funktion der Beschleunigung in Abhängigkeit des Winkels. Die ist infolge von Rotationstorsion, Reibung und vor allem Rastmomente nicht trivial. Mit einem einfachen PID-Regeler gelingt das nur gut, wenn man die Messungen passend nichtlinear aufarbeitet und den P.I.D. Parametern die richtigen Werte zuleitet. Ich habe mir seinerzeit ein Motormodell in VHDL gebaut, um ein ähnlich gelagertes Problem anzugehen.
Eines wollte ich noch bringen: Um zu verdeutlichen, warum zwei Regler nicht funktionieren: Angenommen, der Motor hängt etwas seiner idealen Position hinterher, hat aber eine etwas höhere Geschwindigkeit, als er haben soll. Eine Geschwindigkeitsregelung würde runterregeln. Wenn es es zwei verkettete Regeler sein sollen, müsste ein langsamer Regler eine im Vergleich zum Ideal erhöhte SOllgeschwindigkeit vorgeben, damit der Motor weiter aufholen kann. Das ist nur dann sinnvoll auszulegen, wenn ein schneller Regler innerhalb einer langsamen Schleife arbeitet. Mit einem Regler ist das wesentlich einfacher zu kontrollieren.
Moin, erstmal vielen Dank für eure Beiträge. Ich hätte vielleicht noch erwähnen sollen, dass es sich um einen Linearmotor handelt. Meine Idee wäre gewesen, eine Position und eine Geschw. vorzugeben, und der Motor würde dann bis kurz vor die Sollposition nur Geschwindigkeitsgeregelt und dann ab der Sollposition nur noch Positionsgeregelt arbeiten. Also wäre immer nur ein Regler aktiv. Oder hab ich da nen Denkfehler?
Dave schrieb: > Also wäre immer nur ein Regler aktiv. > Oder hab ich da nen Denkfehler? Ja, für so etwas nimmt man einen Kaskadenregler. Dein äußerer Regelkreis bekommt die Sollposition und Istposition und liefert eine Sollgeschwindigkeit. Die geht dann mit der berechneten Geschwindigkeit an den zweiten Regler. Das Stellsignal des zweiten Reglers geht dann an den Linearmotor. Die ganze digitale Regelungstechnik geht von einer zeitlich äquidistanten Abtastung aus. Dein Encoder liefert aber eine Weg äquidistante Abtastung. D.h. du musst deinen Weg berechnen und diesen Wert zeitlich abtasten. Da spielt das rein, was Jürgen oben beschrieben hat. Jedoch musst du mit dem Filtern vorsichtig sein, da du eine Regelung hast, die will mit möglichst aktuellen Werten arbeiten. Ewig lange Filter wirken wie eine Totzeit. Die Samplingfrequenz muss deutlich größer als die Taktfrequenz sein. Wenn deine Samplingfrequenz zu hoch ist, ist dein KI zu klein (fast Null) und dein KD zu groß (fast Eins). Eine Verdopplung der Samplingfrequenz halbiert KI und verdoppelt KD. Eventuell brauchst du für deine Regler unterschiedliche Samplingfrequenzen. Normalerweise simuliert man so einen Regelkreis erstmal mit Matlab/Simulink und gießt in nicht gleich in einen FPGA. Viel Erfolg Tom
Auch wenn es etwas länger her ist, eine kleine Note von Thomas zu Thomas: Thomas R. schrieb: > Die ganze digitale Regelungstechnik geht von einer zeitlich > äquidistanten Abtastung aus. N....ein, das ist durchaus nicht so. Sie geht nur von einer quantisierten Abtastung aus. Vereinfacht fallen dann die Differenziale nach der Zeit (größtenteils) weg, was sich bei Rechnungen besonders in der Komplexität im Nenners niederschlägt. Generell ist das absolut nicht so, daß man die weglassen könnte und es macht auch wenig Sinn, besonders im Bezug auf die hier vorgestellte Abtastproblematik.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.