Forum: FPGA, VHDL & Co. PID Regler in VHDL


von Jan (Gast)


Lesenswert?

Hallo,

ich bin grade dabei einen PID Regler in VHDl zu schreiben.
Das Peoblem ist, dass der Anti-Windup nicht recht funktioniert und ich 
versteh grad nicht wieso. Wenn ich mir in Modelsim meinen Reglerausgang 
angucke, dann sieht es so aus, als ob mein regler immer erst einen Takt 
zu spät die Antiwindup Rechnung durchführt.

Hier mal mein Code:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
use ieee.math_real.all;
5
6
7
entity pid is
8
9
port(
10
      clk   :  in std_logic;
11
      reset :  in std_logic;
12
      w    :  in signed(31 downto 0) := "00000000000000000000000001100100";
13
      x     :  in signed(31 downto 0) := "00000000000000000000000000001111";
14
      y     :  out signed(31 downto 0) := (others => '0')
15
  );
16
end pid;
17
18
architecture Behavioral of pid is
19
20
signal e     : signed(31 downto 0) := (others => '0');
21
signal e_alt : signed(31 downto 0) := (others => '0');
22
signal e_sum : signed(31 downto 0) := (others => '0');
23
signal k_p   : signed(31 downto 0) := "00000000000000000000000000001010";
24
signal k_i   : signed(31 downto 0) := "00000000000000000000000000111100";
25
signal k_d   : signed(31 downto 0) := "00000000000000000000000000000001";
26
signal y_i   : signed(31 downto 0) := (others => '0');
27
28
29
begin
30
  Regler: process(clk,reset)
31
  begin
32
   
33
  if rising_edge(clk) then
34
    if reset = '0' then
35
      e_alt <= (others => '0');
36
      e_sum <= (others => '0');
37
      y_i <= (others => '0');
38
    else
39
    
40
      e  <= w - x;   --Regeldifferenz
41
42
      if y_i < x"000009C4" and y_i > x"00000005"  then
43
        e_sum <= e_sum + e;
44
      end if;
45
      
46
      y_i <= resize(((signed(k_p)*signed(e))+(signed(k_i)*signed(e_sum))+(signed(k_d)*(signed(e)-signed(e_alt))))/k_p,32);
47
      
48
      if y_i > x"000009C4" then
49
        y_i <= x"000009C4";
50
      elsif y_i < x"00000006" then
51
        y_i <= x"00000006";
52
      end if;
53
54
      e_alt <= e;
55
56
    end if;
57
  end if;
58
end process Regler;
59
60
y <= y_i;
61
62
end Behavioral;

Also der Bereich für y soll zwischen 6 und 2500 liegen. Leider wird wie 
gesagt immer erst einen Takt zu spät auf 2500 begrenzt...

Könnte das an Timing liegen oder überseh ich nur was simples?

Vielen Dank schonmal.

MfG

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Jan schrieb:
> überseh ich nur was simples?
Dein Stichwort heißt Latency und spielt sich da ab:
1
      y_i <= resize(((signed(k_p)*signed(e))+(signed(k_i)*signed(e_sum))+(signed(k_d)*(signed(e)-signed(e_alt))))/k_p,32);
2
      
3
      if y_i > x"000009C4" then -- hier wird noch der "alte" Wert von y_i verwendet
Es wird noch der "alte" Wert von y_i verwendet, weil Signale den "neuen" 
Wert erst am Ende des Prozesses zugewiesen bekommen.

von Jan (Gast)


Lesenswert?

Danke erstmal,
wäre es nun schlauer einen zweiten Prozess zu schreiben, der dann die if 
Anweisung enthält oder kann man das auch umgehen indem man zB anstatt 
Signalen Variable benutzt?

von Achim S. (Gast)


Lesenswert?

Ein zweiter Prozess nützt dir hier wenig. Aber hier kann man tatsächlich 
mal eine Variable einsetzen, um sich Ergebnis der Rechnung zu "merken" 
und um sich Schreibarbeit zu sparen.

Also ungefähr in der Art:

1
signal y_i: signed....
2
variable y_var:  ...
3
4
5
6
      y_var := resize(((signed(k_p)*signed(e))+(signed(k_i)*signed(e_sum))+(signed(k_d)*(signed(e)-signed(e_alt))))/k_p,32);
7
      
8
      if y_var > x"000009C4" then
9
        y_i <= x"000009C4";
10
      elsif y_var < x"00000006" then
11
        y_i <= x"00000006";
12
      else 
13
        y_i <= y_var;
14
      end if;

von Klaus F. (kfalser)


Lesenswert?

Jan schrieb:
> e  <= w - x;   --Regeldifferenz
>
>       if y_i < x"000009C4" and y_i > x"00000005"  then
>         e_sum <= e_sum + e;
>       end if;
>
>       y_i <=
> resize(((signed(k_p)*signed(e))+(signed(k_i)*signed(e_sum))+(signed(k_d) 
*(signed(e)-signed(e_alt))))/k_p,32);

e_sum und e haben das gleiche Problem.
Zu e_sum wird immer der Wert von e aus dem vorigen Zyklus dazugezählt 
und e_sum wird dann wieder einen Takt später verwendet.
Außerdem :
- Divisionen sind in VHDL nicht empfehlenswert
- PID-Regler ebensowenig, da ein FPGA dazu gedacht ist mit 100 MHz oder 
mehr zu laufen und es dürfte wenig Regelungsaufgaben geben, bei denen 
diese Regelungsfrequenz notwendig ist.

von Christoph Z. (christophz)


Lesenswert?

Klaus Falser schrieb:
> - PID-Regler ebensowenig, da ein FPGA dazu gedacht ist mit 100 MHz oder
> mehr zu laufen und es dürfte wenig Regelungsaufgaben geben, bei denen
> diese Regelungsfrequenz notwendig ist.

Zeiten ändern sich :-)

Das betrifft vor allem moderne anspruchsvolle Leistungselektronik:
Zum Einen kenne ich Anwendungen wo einzelne 300 MHz DSPs (12 $ das 
Stück) zu wenig Rechenleistung haben um bei 12,5 us (80 kHz) zu regeln.

Da beginnt man dann nach zu denken, ob man mehrere DSPs nehmen will oder 
ob eine FPGA basierte Lösung am Ende günstiger/flexibler ist.


Das andere Beispiel das ich mal gesehen habe, das mich selber erstaunt 
hat, war ein Motorumrichter aus dem Eisenbahnbereich 
(Traktionsumrichter). Auf der Steruerplatine war nirgends ein Prozessor 
zu sehen, sondern "nur" drei Spartan 3A.

Nehme nicht an, dass die auf dem MicroBlace ihre Regelalgorithmen laufen 
haben. (Gut möglich dass sie einen Soft-Core für langsame Sachen wie 
Temperaturüberwachung etc. drin haben).

Meine begründete Anhame ist eher, dass sie ihre Reglerstrukturen direkt 
mit Simulink entwickeln und testen und danach mit dem HDL-Coder den 
Reglern ins FPGA bringen.


Trotzdem, dividieren willst du immer noch nicht in einem FPGA :-)

von Klaus F. (kfalser)


Lesenswert?

Christoph Z. schrieb:
> Das betrifft vor allem moderne anspruchsvolle Leistungselektronik:
> Zum Einen kenne ich Anwendungen wo einzelne 300 MHz DSPs (12 $ das
> Stück) zu wenig Rechenleistung haben um bei 12,5 us (80 kHz) zu regeln.
>
> Da beginnt man dann nach zu denken, ob man mehrere DSPs nehmen will oder
> ob eine FPGA basierte Lösung am Ende günstiger/flexibler ist.

So hingestellt, möchte ich das bezweifeln.
Wenn der Algorithmus so kompliziert ist, dass ein DSP das nicht mit 80 
KHz schafft, dann ist ein FPGA sicher auch nicht die erste Wahl und ob 
Du dann mit einem FPGA zu 12$ das Stück auskommst, bezweifle ich noch 
mehr.

Bei bestimmten Funktionen kann ein FPGA Vorteile haben, z.B eine 
Stromüberwachung aim Microsekundenbereich, aber im Regler selbst?

: Bearbeitet durch User
von 132 (Gast)


Lesenswert?

Klaus Falser schrieb:
> Wenn der Algorithmus so kompliziert ist, dass ein DSP das nicht mit 80
> KHz schafft, dann ist ein FPGA sicher auch nicht die erste Wahl und ob
> Du dann mit einem FPGA zu 12$ das Stück auskommst, bezweifle ich noch
> mehr.

Was willst du denn machen wenn dir die DSPs nicht mehr reichen? Wieso 
kein FPGA? Die haben HW Multipliere und DSP Funktionalität ist doch auf 
FPGAs bedeutend besser als auf DSPs. Kostet halt ordentlich aber muss ja 
nicht. Gibt auch FPGAs für ~20€ die DSPs ohne mit der Wimper zu zucken 
in die Kiste klopfen. Die wenigsten Servocontroller die ich kenne kommen 
ohne FPGA aus. Warum sich auch mit einem DSP zum gleichen Preis 
rumärgern wenn auch ein FPGA geht den man ohnehin braucht. Da wird auch 
"nur" der Encoder der Rückkopplung ausgewertet, Clark&Park laufen neben 
2 PIDs. Ist doch wunderschön.

von Klaus F. (kfalser)


Lesenswert?

132 schrieb:
> Was willst du denn machen wenn dir die DSPs nicht mehr reichen? Wieso
> kein FPGA? Die haben HW Multipliere und DSP Funktionalität ist doch auf
> FPGAs bedeutend besser als auf DSPs. Kostet halt ordentlich aber muss ja
> nicht. Gibt auch FPGAs für ~20€ die DSPs ohne mit der Wimper zu zucken
> in die Kiste klopfen.

Redest Du aus Erfahrung oder nur so vom Hörensagen?
Nett, dass bei bestimmten Stichworten immer wieder alle auf die 
Diskussion anspringen.
Ich lasse mich auch gerne belehren von Leuten die das für professionelle 
Zwecke schon gemacht haben. Meines ist nur eine persönliche Meinung, 
basierend auf jahrelanger Erfahrung mit FPGAs und DSPs in Jugendjahren.
Zu Regelungsaufgaben mit FPGAs habe ich keine Erfahrung, das gebe ich 
zu.
Und ich habe auch nicht behauptet, dass FPGAs schlechter sind.
Ursprünglich habe ich nur behauptet, dass es wenig Regelungsaufgaben 
geben dürfte, die man mit 100 MHz Zykluszeit berechnen muss.

von Simon B. (icerise)


Lesenswert?

Hallo,

ich wärme den Threat nochmal auf.
Ich würde den Code gerne für meine VHDL Projekt nutzen. Mit Ersetzen der 
Signale durch Variablen läuft das auch soweit.
Sonst ist der PID Regler ja passend oder? (ich versteh die Materie nicht 
im Detail)
Meine Frage ist nur, das Ausgangssignal y_i muss ich jetzt aber noch auf 
den Sollwert aufaddieren um es dann an meinen Regel ADC weiterzugeben 
oder?

Gruß

von Andreas (Gast)


Lesenswert?

Simon B. schrieb:
> Meine Frage ist nur, das Ausgangssignal y_i muss ich jetzt aber noch auf
> den Sollwert aufaddieren um es dann an meinen Regel ADC weiterzugeben

Nein, da sonst nach einiger Zeit über dem Integrator der negative 
Sollwert steht.

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.