Hallo,
für ein Projekt im Rahmen des Studiums benötige ich u.a. einen
PID-Regler, der von ein FPGA realisiert werden soll.
Da ich abgesehen von einigen Grundlagen in der Vorlesung mir VHDL
größtenteils selbst beigebracht habe, möchte ich die erfahrenen Benutzer
in diesem Forum mal zu ihrer Meinung fragen, ob der Code so
funktionieren kann.
Die Simulation in Modelsim mit einer PT1-Strecke funktioniert soweit und
der Code läßt sich auch synthetisieren ohne allzu viel Logik zu belegen.
Da ich jedoch z.Zt. noch keine Möglichkeit habe, den Regler in einem
realen FPGA zu testen und ich gehört habe, das eine funktionierende
Simulation nicht zwangsläufig auch bedeutet, dass der Code im FPGA
funktioniert, wollte ich mal eure Meinung hören. Realisiert werden soll
das Ganze mit einem Spartan3E250.
Der Code basiert grundsätzlich auf einem PID-Regler in C, den ich für
das FPGA entsprechend angepasst habe.
Gerechnet wird nur mit ganzen Zahlen, wobei anschließend durch
verschiedene 2er-Potenzen dividiert wird. Dies wird mit den definierten
Konstanten erledigt. Es wird ausschließlich mit Funktionen aus
numeric_std gerechnet.
Für den jeweiligen P, I und D-Anteil gibt es Ober- und Untergrenzen um
einen Überlauf zu vermeiden.
Insbesondere würde mich noch interessieren, ob die Anweisungen INNERHALB
des Prozesses mit Sicherheit nacheinander abgearbeitet werden unabhängig
von Gatterlaufzeiten o.ä.?
Hier also der Code:
Die Anweisungen werden dann "nacheinander" abgearbeitet, wenn Du das
Ergebnis in einer anderen Operation wieder benutzt. Das "Nacheinander"
ist, wie Du schon meintest, von den Laufzeiten abhängig. Du musst also
schauen, ob dein Timing noch stimmt. Wenn Du zu viele Operationen
hintereinander ausführst ist es möglich, dass bis zum nächsten Takt das
eigentliche Ergebnis nicht bereitgestellt wird.
Zur Simulation:
Wenn Du eine Post-Map Simulation ausführst und diese das richtige
Ergebnis liefert, dann sollte es auch auf dem FPGA funktionieren. Bei
Post-Map sind Signal- und Gatterlaufzeiten eingerechnet und Du kannst
Dir die "reale" Verzögerung anschauen ...
Wenn das ganze System synchron arbeitet und alle ankommenden und
abgehenden Signale abgecklockt werden, dann genügt es, die PERIOD
constraint richtig zu setzen. Das Synthesetool rechnet die Gatter-Delays
dann korrekt ein und liefert eine Warnung, wenn diese die PERIOD
übersteigen.
Dein PID-Regler stimmt zwar im Prinzip, aber ein 10 Hz Takt ist fast
eine Beleidigung für ein FPGA.
Zwar kann man einen 10 Hz Takt durch Herunterteilen eines schnelleren
Taktes herstellen, solche Signale sollte man aber nicht als Takt
verwenden.
Auch die DLL's des Spartan-FPGA's eignen sich vermutlich (müsste man
nachschauen) nicht, um so einen langsamen Takt zu erzeugen.
Falls man es wirklich so ähnlich machen will, sollte man ein
Clock-Enable Signal erzeugen, das alle 100 ms für einen Taktpuls auf '1'
geht und das Aktualisieren des Reglers auslöst.
Der Kode muss dabei aber umgeschrieben werden, weil in diesem Fall die
Berechnung innerhalb eines Taktzyklus erfolgen muss.
Die Lösung dafür heißt entweder Pipelining, oder kompliziertere
Constraints, die sich "Multicycle-Path" nennen.
Leider ist dies alles komplizierter als die Lösung, die Du jetzt hast,
aber solch ein PID-Regler mit 10 Hz am FGPA ergibt doch sonst keinen
Sinn, oder?
@Martin:
Auf welchen Wert sollte die PERIOD constraint dann gesetzt werden?
Mir wird eine maximal mögliche Taktrate von ca. 33 MHz angegeben, hat
das was damit zu tun?
@Klaus:
Es ist klar, dass ein FPGA normalerweise mit wesentlich schnelleren
Taktraten arbeitet, den 10 Hz-Takt teile ich tatsächlich von 66 MHz
herunter, können denn dadurch Probleme entstehen?
Der PID-Regler soll eine Heizung regeln, also ein sehr träges System, so
dass eigentlich keine höheren Taktraten erforderlich wären, aber es wäre
natürlich auch möglich die Taktrate zu erhöhen.
@ Tobias W. (eagle2010)
>Auf welchen Wert sollte die PERIOD constraint dann gesetzt werden?
Im einfachsten Fall auf die Frequenz des Taktes. Passt schon, auch wenn
es theoretisch mit einem Multicycle-Constraints besser wäre.
>Mir wird eine maximal mögliche Taktrate von ca. 33 MHz angegeben, hat>das was damit zu tun?
Ja. reicht doch für dich.
>herunter, können denn dadurch Probleme entstehen?
Nicht wenn man es richtig (tm ) macht.
>Der PID-Regler soll eine Heizung regeln, also ein sehr träges System, so>dass eigentlich keine höheren Taktraten erforderlich wären, aber es wäre>natürlich auch möglich die Taktrate zu erhöhen.
Nobel geht die Welt zu Grunde. Heizungsreglung mit FPGA. ;-)
MfG
Falk
Amania wrote:
> hi Tobias , deine Code läuft nicht in Xilinx oder ?
Doch, er lässt sich in der ISE sowohl synthetisieren als auch
simulieren. Warum nicht?
@ Amania (Gast)
>Dateianhang: Unbenannt.JPG (184,5 KB, 3 Downloads)Bildformate!!!
Ausserdem ist es nicht wirklich schwer, die Fehlermeldungen als Text zu
kopieren und zu posten. Eieieieieiei.
MFG
Falk
Amania wrote:
> ich habe eifach deine code in ISE kopieren und synthetisieren lassen ,> es gab aber viele Fehler . Wie ist es bei dir ?
Hast Du die Libraries richtig eingebunden (IEEE.NUMERIC_STD.ALL
eingebunden und IEEE.STD_LOGIC_ARITH.ALL sowie
IEEE.STD_LOGIC_UNSIGNED.ALL deaktiviert)?
>Hast Du die Libraries richtig eingebunden (IEEE.NUMERIC_STD.ALL>eingebunden und IEEE.STD_LOGIC_ARITH.ALL sowie>IEEE.STD_LOGIC_UNSIGNED.ALL deaktiviert)?
Böse... IEEE.STD_LOGIC_ARITH und IEEE.STD_LOGIC_UNSIGNED sollte man
nicht benutzen. Die sind teilweise Hersteller abhängig. Nur das
IEEE.NUMERIC_STD sollte noch verwendet werden.
@tobias: ich habe einfach deine Code koppiert und laufen lassen . wenn
die
obere Code richtig , dh. ich muss nicht ändern , aber läuft bei mir
nicht , kann ich das Ergebnis von Simulation bei dir sehen ?
Mathi wrote:
>>Hast Du die Libraries richtig eingebunden (IEEE.NUMERIC_STD.ALL>>eingebunden und IEEE.STD_LOGIC_ARITH.ALL sowie>>IEEE.STD_LOGIC_UNSIGNED.ALL deaktiviert)?>> Böse... IEEE.STD_LOGIC_ARITH und IEEE.STD_LOGIC_UNSIGNED sollte man> nicht benutzen. Die sind teilweise Hersteller abhängig. Nur das> IEEE.NUMERIC_STD sollte noch verwendet werden.
Ja, richtig. Genau aus diesem Grund wurden ja IEEE.STD_LOGIC_ARITH und
IEEE.STD_LOGIC_UNSIGNED NICHT eingebunden!
@Amania:
Lässt sich denn der Code jetzt synthetisieren?
Ich sollte vielleicht noch dazu sagen, dass man für eine erfolgreiche
Simulation noch eine Regelstrecke simulieren muss (z.B. PT1).
tobias :
- achso , natürlich brauch man noch PT1 und Rückführung , kannst du bei
Gelegenheit , di code von PT1 Strecke hochladen , das wäre sehr nett .
- und noch eine Frage , wie kannst du die Abtastzeit Ta berechnen ?
Hi Tobias.
Kannst du mir erklären wie du die Konstanten MKp, MTn, MTv, sowie Tn, Tv
festgelegt hast?
Sowie die Berechnungsformeln für yi und yd.
Habe die Berchnungs bzw. Realsisierungsvorschrift für einen PID
vorliegen, kann mir aber deine nicht erklären. Vielleicht hast du ein
paar Minuten und postest mal eine kurze Erklärung.
Danke.Ciao
Hallo Ronny,
es ist ja schon etwas länger her, dass ich den PID-Regler programmiert
habe, aber ich versuche mal, mich zu erinnern...
Der Sinn der Konstanten MKp, MTn und MTv ist der, dass ich
ausschließlich mit Ganzzahlen rechnen möchte, d.h. ich multipliziere
erst z.B. Kp mit MKp und dividiere schließlich das Ergebnis der
Berechnung wieder durch MKp. Um dividieren zu können muss MKp eine
2er-Potenz (2^x) sein. (s. dazu
http://webber.physik.uni-freiburg.de/~hon/vorlss02/Literatur/Ingenieurswiss/Regelungstechnik/ProgrammiereRegelung.pdf
- Abschnitt 4.2)
Dies bedeutet, ich habe z.B. den Faktor MTn so gewählt, dass die
Konstante TaTnM = (Ta / Tn) * MTn (gerundet) ein hinreichend genaues
Ergebnis gibt (dafür sollte MTn möglichst groß sein, aber auch nicht zu
groß, da TaTnM nicht größer als 200 sein sollte, um in der weiteren
Berechnung einen Überlauf zu vermeiden). Die Faktoren Mxx sollen also so
gewählt werden, dass die damit berechneten Konstanten < 200 sind.
Die Regler-Parameter Kp, Tn und Tv werden nach den üblichen Verfahren
zur Regelereinstellung an der realen Regelstrecke festgelegt (z.B.
Ziegler-Nichols oder Chien, Hrones und Reswick).
Die Berechnungen von yi und yd entsprechen eigentlich den
Berechnungsvorschriften für I- und D-Anteil bei nummerischer Rechnung.
Der I-Anteil berechnet sich ja z.B. in integraler Form wie folgt:
Das Integral lässt sich aber auch durch die Summe von
nummerisch berechnen:
Daraus folgt, dass yi berechnet werden kann, wenn das vorheriger
Ergebnis für yi bekannt ist:
Dies - in Verbindung mit den Faktoren für die Ganzzahlarithmetik - ist
genau dass, was ich in meiner Routine für die Berechnung des I-Anteils
mache.
Analog funktioniert eigentlich auch die Berechnung des D-Anteils, nur
dass hier immer die Differenz zwischen e und dem vorherigen e (ealt)
herangezogen wird:
Ich hoffe, die Erklärungen konnten weiterhelfen.
Gruß
Tobias
Hallo Tobias.
Danke für deine schnelle Antwort.
Ja stimmt nach langem rechnen habe ich das erkannt.
Und danke für den Link, der ist sehr hilfreich.
Ich habe den Regler jetzt mal ausprobiert. Allerdings, bekomme ich wie
befürchtet die Zeitprobleme.
Siehe auch:
Der Code muss dabei aber umgeschrieben werden, weil in diesem Fall die
Berechnung innerhalb eines Taktzyklus erfolgen muss.
Die Lösung dafür heißt entweder Pipelining, oder kompliziertere
Constraints, die sich "Multicycle-Path" nennen.
Leider ist dies alles komplizierter als die Lösung, die Du jetzt hast,
aber solch ein PID-Regler mit 10 Hz am FGPA ergibt doch sonst keinen
Sinn, oder?
Hast du dich damit nochmal beschäftigt?
Ciao
Hallo,
da ja bei mir wie gesagt die 10 Hz schon mehr als ausreichend waren,
weil es sich um eine Temperaturregelung handelt, war die Zeit kein
Problem. Ich habe mich also nicht mit Pipelining o.ä. beschäftigt.
Wenn ich das richtig gelesen habe, willst Du damit einen Motor regeln?
Welche Frequenz benötigst Du denn für den Regler? Wenn ich mich nicht
irre, war bei meinem Code die Maximalfrequenz, die Xilinx ISE angegeben
hat, ca. 40 MHz.
Gruß
Tobias
Hallo,
ja es soll ein Motor angesteuert werden. Ich habe einen Lagesensor der
mir einen Wert liefert. Diesen nutze ich um ein PWM zu erzeugen und
steuere somit einen Motor an. Ja bei mir ist das alles sehr zeitkritsch,
da die Ansteuerung sehr des Motors sehr schnell sein muss und der Sensor
auf eine schnelle Lageänderung reagiert. Habe das Altera MaxII was einen
BoardTakt von 66MHz hat.
Gruß Ronny