Forum: Mikrocontroller und Digitale Elektronik Zustandsregelung Atmel AVR


von Franz S. (spanti)


Lesenswert?

Hallo Leute,
ich studiere Automatisierungstechnik an einer Universität und das ganze 
ist leider sehr theorielastig. Ich wollte nun einfach so für mich und um 
Erfahrung zu sammeln ein Modell aufbauen, welches von einem 
Microcontroller geregelt wird. Das Modell ist ein Wagen auf einem 
Balken, welcher in der Mitte drehbar gelagert ist. Dort wird über einen 
Motor der Drehwinkel geregelt. Man gibt die Position des Wagens auf dem 
Balken vor und über die Stellgröße u(Spannung) wird das dann 
ausgeregelt.
Ich habe das STK600 Evaluierungsboard von Atmel zuhause und habe das 
ganze Modell schon hergeleitet, etc. Mir geht es jetzt nur um den 
C-Code, wie ich das ganze machen muss um auf einem einfachen 
Microcontroller ohne einer DSpace box etc. einen Zustandsregler zu 
implementieren. Mir geht es auch um die Echtzeitfähigkeit, denn ich muss 
ja bei einem zeitdiskreten System die Abtastzeit genau einhalten, auch 
wie ich das ganze graphische aus Simulink bzw Scicos in c modellieren 
kann.
Wäre euch echt dankbar wenn ihr mir helfen könntet!
lg

von Karl H. (kbuchegg)


Lesenswert?

Franz Spanlang schrieb:

> Wäre euch echt dankbar wenn ihr mir helfen könntet!


Wieviel Erfahrung hast du bereits in der µC-Programmierung?
Kannst du mit Timern umgehen und dir so mittels einer ISR eine 
definierte Zeitbasis schaffen?

von Franz S. (spanti)


Lesenswert?

Hallo,
danke erstmal für die schnelle Antwort.
Mit µC Programmierung selbst habe ich noch eher wenig Erfahrung, C 
Programmieren selber geht ganz gut. Glaubst du es ist mit einem 
einfachen Interrupt genau genug? der µC braucht ja auch zum Errechnen 
einiges an Zeit und ich bin da skeptisch ob das dann genau genug ist... 
oder kann man die Rechenzeit vernachlässigen.
Hat vielleicht irgendjemand schon mal so eine Zustandsregelung auf einem 
µC implementiert, der/die mir den Sourcecode eventuell zukommenlassen 
könnte?

von blabla (Gast)


Lesenswert?

Mein Vorgehen wäre:

1) Modell und Regler herleiten
2) Simulieren in Simulink (discrete block für Regler) oder Subsystem mit 
externem Trigger.
3) Echtzeitfähigkeit ohne "Interrupt":
Einfach ermitteln wie lange der Algorithmus und Ein- und Ausgabe 
benötigt. Dann Abtastzeit mindestens 10 x größer wählen. Den 
Mikrocontroller so programmieren, dass er nach dem Algorithmus einfach 
entsprechend lange wartet.

von Karl H. (kbuchegg)


Lesenswert?

Franz Spanlang schrieb:

> einfachen Interrupt genau genug? der µC braucht ja auch zum Errechnen
> einiges an Zeit und ich bin da skeptisch ob das dann genau genug ist...

wie genau brauchst du es denn?

> oder kann man die Rechenzeit vernachlässigen.

Es geht doch in erster Linie nicht darum wie lange die Berechnung 
dauert, sondern darum wie genau du deine Delta-Abtastzeit hinkriegst.
Die Berechnung muss natürlich schneller gehen als dieses Delta, sonst 
hinkt die Berechnung hinterher.
Kommt drauf an, wie komplex die Berechnung ist, aber im allgemeinen sind 
µC schon sauschnell.

PS: Eine Millisekunde ist für einen µC schon seeehr lange. In dieser 
Zeit kann man schon viel machen.

von Franz S. (spanti)


Lesenswert?

Hallo,
okay das klingt logisch, es ist ja auch nur ein System 2.Ordnung deshalb 
dürfte sich die Rechenzeit in Grenzen halten.
Das mit der Echtzeitfähigkeit wäre also nun kein Problem mehr wenn ich 
das so mache. Mir geht es jetzt noch um den C-Code:
Das Programm müsste irgendwie so aussehen:
u = kappa*v -k^T*x
x= A*x+b*u
y = c^T*x

wobei u der Systemeingang ist,
kappa der Vorfaktor für eine stationäre Verstärkung von eins,
k^T(k transponiert) der Rückführvektor des Reglers (z.B. über LQR 
berechnet),
v die Stellgröße
x die Zustände,
A die diskrete Systemmatrix,
b der Vektor der mit dem Eingang(Spannung) verknüpft ist, auch diskret,
y der Ausgang
c^T ein Zeilenvektor um die bestimmten Zustände als Linearkombination 
herauszunehmen um auf den Ausgang zu kommen

Das ganze passiert dann zu jedem Abtastzeitpunkt Ta, nach Ausführung 
wartet der Algorithmus bis wieder ein Steuersignal kommt.
Soweit zu meiner Idee - könnte das so in etwa funktionieren? Das problem 
oben ist, dass ich zur Berechnung von u die Zustände aus dem letzten 
Schritt verwende, wenn ich die ersten beiden Zeilen umdrehe verwende ich 
das u aus dem letzten Schritt.
fg

von Karl H. (kbuchegg)


Lesenswert?

Franz Spanlang schrieb:
> Hallo,

> Soweit zu meiner Idee - könnte das so in etwa funktionieren?

Zum Modell kann ich so nichts weiter sagen.
Da bist du der Spezialist.

Wenn du die Transponierte und c^T auch noch händisch aufdröselst, dann 
sieht das erstmal gut aus. Sind ein paar Multiplikationen und 
Additionen.

> Das problem
> oben ist, dass ich zur Berechnung von u die Zustände aus dem letzten
> Schritt verwende,

Wo liegt da das Problem?
Genau dafür gibt es Variablen, damit man sich Werte aufheben kann.


Aber wenn du noch wenig Erfahrung mit µC hast, dann wird das alles ein 
wenig überdimensioniert für dich sein.
Du solltest erst mal den normalen Weg gehen:
* Led anschalten
* Led ausschalten
* Led blinken, mit Warteschleife
* Led blinken, mit Timer

Wenn du soweit bist, dann hast du auch den Dreh raus, wie man in einem 
AVR eine Funktion schreibt, die exakt alle 1 Millisekunde (+/- ein paar 
Nanosekunden) aufgerufen wird und Berechnungen macht.

von Purzel H. (hacky)


Lesenswert?

Solange man ohne floatingpoint durchkommt, geht's.

von Franz S. (spanti)


Lesenswert?

Karl heinz Buchegger schrieb:
> Aber wenn du noch wenig Erfahrung mit µC hast, dann wird das alles ein
>
> wenig überdimensioniert für dich sein.

also so Standardprogramme die kann ich schon, und ich glaube nicht dass 
das ganze am Programmieren scheitern wird, da der Code für die Regelung 
ja relativ simpel ist, das mit der Echtzeitfähigkeit, dass die 
Berechnung immer zur Abrastzeit erfolgt schaff ich sicher auch da google 
ich a Runde :)
Würde der Code oben so passen oder müsste der vielleicht so aussehen:

x= A*x+b*u
y = c^T*x
u = kappa*v -k^T*x

hier berechnet sich der neue Ausgang (die neuen Zustände) sowohl aus den 
Zuständen vom letzten Schritt, als auch vom Systemeingang vom letzten 
Schritt, und so ist ja auch ein diskretes System definiert. Ich glaube 
diese Lösung ist korrekt.

Ich bräuchte jetzt noch jemanden der mir bezüglich dem Code Auskunft 
gibt, das alles drum herum schaffe ich schon, nur wie der Code für mein 
Problem aussehen muss, ob ich das so machen kann wie vorhin beschrieben.
fg

von Franz S. (spanti)


Lesenswert?

Nebliger Tag schrieb:
> Solange man ohne floatingpoint durchkommt, geht's.

Also floating Point brauche ich ziemlich sicher, das ganze muss auf 
mindestens 3 Nachkommastellen genau sein. Aber ich denke die insgesamt 
vielleicht 10 floating point multiplikationen dürften dem µC auch keine 
ernsthaften Probleme machen.

Ich kriege den Winkel über ein ganz einfaches Poti rein, rechne intern 
den Winkel (Analogwert) in einen Winkel (radiant) um und rechne dann 
damit. Ich weiß auch gar nicht wie schnell sowas ungefähr sein muss 
damit es gut funktioniert. Genügt es die Abtastzeit einige Millisekunden 
groß zu wählen oder doch im µs bereich?
fg

von was_is_mit_du (Gast)


Lesenswert?

>Würde der Code oben so passen oder müsste der vielleicht so aussehen:
>
>x= A*x+b*u
>y = c^T*x
>u = kappa*v -k^T*x

Würde schon so passen, allerdings musst du die Vektor- und 
Matrixoperationen
in C explizit angeben.

von Klaus (Gast)


Lesenswert?

Franz Spanlang schrieb:
> lso floating Point brauche ich ziemlich sicher, das ganze muss auf
> mindestens 3 Nachkommastellen genau sein.

Denke mal ganz intensiv über Fixkomma-Rechnung nach. In sehr vielen 
Fällen brauch man auch für Nachkokmmastellen keine floating point 
Rechnungen.

von Purzel H. (hacky)


Lesenswert?

Vergiss floating point. Die 4 signifikanten Stellen gibt's einfacher und 
schneller mit 32bit Longint. Radianten braucht man auch nicht. Da muss 
man dann etwas kreativ sein.

von GastX (Gast)


Lesenswert?

Franz Spanlang schrieb:
> Also floating Point brauche ich ziemlich sicher, das ganze muss auf
> mindestens 3 Nachkommastellen genau sein. Aber ich denke die insgesamt
> vielleicht 10 floating point multiplikationen dürften dem µC auch keine
> ernsthaften Probleme machen.
>
> Ich kriege den Winkel über ein ganz einfaches Poti rein, rechne intern
> den Winkel (Analogwert) in einen Winkel (radiant) um und rechne dann
> damit. Ich weiß auch gar nicht wie schnell sowas ungefähr sein muss
> damit es gut funktioniert. Genügt es die Abtastzeit einige Millisekunden
> groß zu wählen oder doch im µs bereich?
> fg

In der Regel arbeitet man auf µC Basis ohne Fließkommazahlen. Das lässt 
sich prima mit Festkommaoperationen erledigen. Erfordert natürlich etwas 
Gehirnschmalz vorab.

von Franz S. (spanti)


Lesenswert?

GastX schrieb:
> In der Regel arbeitet man auf µC Basis ohne Fließkommazahlen. Das lässt
>
> sich prima mit Festkommaoperationen erledigen. Erfordert natürlich etwas
>
> Gehirnschmalz vorab.

Okay danke für die Info.
Also das ist dann gar nicht so leicht, aber i hab jetzt bissl 
herumprobiert und was herausgefunden: Ich berechne die ganzen Werte z.B. 
der A-Matrix und lasse die Kommastellen ganz normal drinnen. Dem µC 
übergebe ich die ganzen Zahlen aber anders.
Nehmen wir mal an es werden die Zahlen 5,32 und 4,71 miteinander 
multipliziert. Dann teile ich die auf in a=5, b=32,c=4 und d=71 (jede 
Zahl wird in Vor - und Nachkommastelle unterteilt).
Das Ergebnis : E = 5,32*4,71 = 25,0572
k ist die Anzahl der Nachkommastellen, also 100 in unserem Fall.
die Multiplikation vereinfacht sich folgendermaßen:
E = a*c+a*d/k+b*c/k+b*d/(k^2)
Da kommt tatsächlich das richtige raus. Kennt ihr dieses System schon 
weil auf diese Art und Weise ist es ja echt simpel 
Fließkommamultiplikationen durchzuführen :)
fg

von Karl H. (kbuchegg)


Lesenswert?

Franz Spanlang schrieb:

> Nehmen wir mal an es werden die Zahlen 5,32 und 4,71 miteinander
> multipliziert. Dann teile ich die auf in a=5, b=32,c=4 und d=71 (jede
> Zahl wird in Vor - und Nachkommastelle unterteilt).

Nein.
Das macht man eigentlich nicht so.

Was man macht, kennst du bereits:
Mann nimmt velfache.

Du kannst zb  5 Euro 32 Cent und 4 Euro 71 Cent miteinander addieren, 
indem du rechnest
    5.32
    4.71
  ------
   10.03    (10 Euro und 3 Cent)

und dafür Gleitkommaarithmetik brauchst.

Mann kann aber auch einfach alles in Cent rechnen. Und da ein Euro 100 
Cent hat:

     532
     471
    ----
    1003 Cent.

Und mit dem Wissen, dass ein Euro 100 Cent hat, sind das wiederrum 10 
Euro und 3 Cent. Aber: Diesmal hat man alles in den ganzen Zahlen 
gerechnet und keine Fliesskommaoperation gebraucht.

Im Grunde sucht man sich einfach nur ein geeignetes Vielfaches, in dem 
alle Zahlen dargestellt werden. Bei Euro und Cent bietet sich 100 
natürlich an. Das muss aber nicht so sein.

Anstelle von
5,32*4,71 = 25,0572
rechnet man dann
532 * 471 = 250572
und da du die Vereinbarung eines Faktors 100 hattest, ist das Ergebnis 
noch durch 100 zu dividieren:
532 * 471 = 250572 / 100 = 2505

Mit der Kentnis, dass du überall das Komma um 2 Stellen verschoben hast, 
gilt daher

    532  entspricht   5.32
    471  entspricht   4.71
   2505  entspricht  25.05

voila: das richtige Ergebnis (im Rahmen der Rechengenauigkeit auf 2 
Nachkommastellen)

Der Dezimalpunkt taucht nur bei der Ein/Ausgabe von Zahlen auf. Intern 
hat man immer ganze Zahlen, die einem Vielfachen der tatsächlichen 
Gleitkommazahl entsprechen. Welches dieses Vielfache ist, hängt von der 
Aufgabenstellung und den Zahlenbereichen ab. Man wählt es so, dass man 
noch genügend 'Nachkommastellen' hat, aber keine der notwendigen 
Berechnungen überläuft.

von Klaus (Gast)


Lesenswert?

Es geht noch viel einfacher. Du nimmst einfach implizit an, dass jede 
Zahl das 100fache des eigentlichen Wertes ist.

Um 5,32 und 4,71 zu multiplizieren nimmst du einfach 2 Variablen die 532 
und 471 enthalten. Dann einfach multiplizieren. Da du nun 2 mal den 
Faktor 100 drin hat, hast du nun einen Wert, der implizit das 10000fache 
der Zahl ist. Also 4 Nachkommastellen hat. Wenn du wieder 2 
Nachkommastellen haben willst, einfach durch 100 Teilen. Fertig.

Beim Addieren ist es noch einfacher. Da bleibt die Anzahl der 
Nachkommastellen immer gleich.

von Franz S. (spanti)


Lesenswert?

Hallo Leute,
ja das geht natürlich auch, aber durch dieses System die Kommastelle 
einfach "wegzulassen" wird mein Problem ziemlich kompliziert, weil meine 
Systemmatrix A und auch b von den ganzen Werten abhängt, die müsste ich 
dann auch alle dementsprechend anpassen. Ich glaube ich nehme doch mein 
System weil da kann ich die ganzen Werte so lassen wie sie sind, sind 
hald ein paar multiplikationen mehr aber des is ned so kritisch und ich 
bin mir dann auch sicher dass es stimmt.
Was anderes noch:
Das ganze System ist ja nicht linear und ich kann nur lineare Systeme 
berechnen. Ich habe das ganze jetzt um phi=0 und s=0 (Wagen steht in der 
Mitte) linearisiert. Kann ich z.B. 4 Systeme berechnen um verschiedene 
Punkte linearisiert, und dann am Anfang mit einer if-Abfrage im Programm 
schaun welches System jetzt an nähesten zutrifft in Bezug auf phi und s 
und dann mithilfe diesem dann den Ausgang berechnen?
fg

von Karl H. (kbuchegg)


Lesenswert?

> Das Ergebnis : E = 5,32*4,71 = 25,0572
> k ist die Anzahl der Nachkommastellen, also 100 in unserem Fall.
> die Multiplikation vereinfacht sich folgendermaßen:
> E = a*c+a*d/k+b*c/k+b*d/(k^2)

Mir ist nicht ganz klar, wie du damit operieren willst.
Als Ergebnis musst du ja wieder 2 Zahlen bekommen: Das Ergebnis 
aufgeteilt in Vorkomma und Nachkommaanteil.

von Franz S. (spanti)


Lesenswert?

ja das mach ich gfanz einfach so, ich multiplizier alles mit k^2:

E = a*c*k^2+a*d*k+b*c*k+b*d     (=250572)
aufgeteilt in Vorkommazahl(v) und Nachkommazahl(n):
v = E/k^2 = 250572/10000 = 25 (der hintere Teil wird ja weggeschnitten
Nachkomazahl:
n = (E-v*k^2)/k = (250572-25*10000)/100=05=5 (die führende 0 dabei ist 
egal und kann weggelassen werden)
Die division bei n ist deshalb nötig, weil sich die Länge der 
Nachkommastelle verdoppeln würde.
Das Ergebnis ist v=25, n=5 E=v+n/=25,05

fg

von Karl H. (kbuchegg)


Lesenswert?

Franz Spanlang schrieb:
> ja das mach ich gfanz einfach so, ich multiplizier alles mit k^2:

UNd wo ist da jetzt der Unterschied zu dem was wir vorgeschlagen haben. 
Ausser das du mehr Multiplikationen benötigst :-)

> Das Ergebnis ist v=25, n=5 E=v+n/=25,05

Sieht so aus als ob dein Ergebnis auch nicht mehr Nachkommastellen 
hochbringt. :-)

von Klaus (Gast)


Lesenswert?

Ganz ehrlich: Machs so wie 99% der anderen Programmierer auch ;)

Ich kann dir mir an Sicherheit grenzender Wahrscheinlichkeit sagen, dass 
dein Ansatz wesentlich komplizierter ist, als wenn du einfach alle Werte 
von vorneherein mit z.B. 10000 multiplizierst.

von Franz S. (spanti)


Lesenswert?

Ich muss mir das ganze nochmal durchdenken in wiefern das ganze 
Auswirkungen auf meine Systemmatrizen hat wenn ich die Werte einfach mit 
z.B. 1000 multipliziere. Der Vorteil meiner Variante ist, dass ich den 
Wert des Winkels nicht verändere, sondern die Zahl nur aufspalte.

Aber nun wieder zurück zum eingentlichen Thema. Hat noch wer Erfahrungen 
mit µC , C und Zustandsregler? Ist das eine Möglichkeint mit dem 
"schaltenden System" von oben die Linearisierungsfehler in Grenzen zu 
halten?
fg

von blabla (Gast)


Lesenswert?

0) Mein Tip für den Anfang und ein Sisosystem mit 2 Zuständen: nimm 
Fließkommazahlen und mache es dir nicht unnötig schwer!
Die Festkommasache kannst du danach anpacken.

Zum Zustandsregler:

>x= A*x+b*u
>y = c^T*x
>u = kappa*v -k^T*x"
1) So funktioniert es (noch) nicht: du brauchst noch einen Beobachter. 
Da du x zum regeln benötigst, aber nur y misst.
> Das problem
> oben ist, dass ich zur Berechnung von u die Zustände aus dem letzten
> Schritt verwende,

2) Falls du einen Zustands-Regler mit einem uC implementieren willst, 
dann musst du "zeitdiskrete / digitale  Regelungstechnik" verwenden. 
Eine Einführung dazu kannst du z.B. im Dourdomas oder Lunze finden.

3) Linearisierungsfehler halten sich - falls man schnell genug abtastet 
- oft in Grenzen.

von blabla (Gast)


Lesenswert?

Als Pseudocode:
Initialisierung:
xp=?; \\Anfangsschätzung
u = 0;

Eigentlicher Algorithmus in einer Schleife als "Sofortregler"
warten();
y=getInput(); \\Eingang einlesen (ADC)
xp=F*xp+L*(C*xp-y)+G*u; \\Beobachter
u=-K*xp-M*v;\\Zustandsrueckfuehrung
sendOutput(u); \\Ausgang stellen (PWM)

Eigentlicher Algorithmus in einer Schleife als "Prädiktiver Regler"
warten();
u=-K*xp-M*v;\\Zustandsrueckfuehrung
sendOutput(u); \\Ausgang stellen (PWM)
y=getInput(); \\Eingang einlesen (ADC)
xp=F*xp+L*(C*xp-y)+G*u; \\Beobachter


wobei:
u Eingang
xp geschaetzter Zustand
F zeitdiskrete Dynamikmatrix (aus A und Abtastzeit berechenbar)
G zeitdiskrete Eingangsmatrix (aus A,B und Abtastzeit berechenbar)
C "normale" Ausgangsmatrix
L Beobachterverstärkung (z.B. Polvorgabe - hängt von Reglerart ab)
K Reglerverstärkung (z.B. LQR)
v,M wie bei dir (M anstatt kappa)

von Franz S. (spanti)


Lesenswert?

Hallo,
danke für den ausführlichen Post. Ich mache natürlich alles zeitdiskret 
und habe auch Ahnung davon, ich hab die Matrizen blöderweise so 
bezeichnet wie sie auch im kontinuierlichen sind.

Könntest du mir bitte nochmals etwas genauer erklären warum man da einen 
Beobachter benötigt? ich berechne mir ja sozusagen alle Zustände über 
die Formel x= A*x+b*u. Oder anders ausgedrückt, wo ist das Problem bei 
meiner Realisierung ohne Beobachter? Weil auf den ersten Blick schaut 
das doch so aus als ob es funktionieren würde.
Ich habe genau vier Zustände, muss ich da alle 4 schätzen oder wie?
fg

von krischi (Gast)


Lesenswert?

Das funktioniert so nicht, weil du eben nur ein Modell deines Systems 
hast. Schlimmer noch ein linearisiertes Modell. Das bedeutet, dass deine 
Zustände mit der Zeit unweigerlich weglaufen und nichts mehr mit dem 
wirklichen Zustand zu tun haben.

Ein Beobachter ist ja letztlich auch nichts anderes als ein Regler, der 
die geschätzten Zustände so anpasst, dass der Fehler zwischen 
geschätztem und wirklichem Ausgangssignal verringert wird.

Wenn du alle 4 Zustände für deine Zustandsrückführung benötigst, dann 
musst du natürlich auch alle schätzen. Mitunter reicht auch eine 
Ausgangsrückführung, aber in deinem Fall brauchst du, wenn ich das 
richtig überblicke, alle 4.

Gruß

von blabla (Gast)


Lesenswert?

Krischi hat es gut erklärt, aber dass " die
Zustände mit der Zeit unweigerlich weglaufen und nichts mehr mit dem
wirklichen Zustand zu tun haben." hat (bei einem richtigen Modell) mit 
der Instabilität des Models zu tun.

Prinzipiell kann man auch einen reduzierten Beobachter verwenden und nur 
die 3 oder 2 nicht gemessenen Zustände schätzen - dies ist aber 
komplizierter.

von Franz S. (spanti)


Lesenswert?

Okay ist mir soweit logisch. Meine 4 Zustände sind Position, 
Geschwindigkeit, Winkel und Winkelgeschwindigkeit. Geregelt werden soll 
die Position. Welche der vier Zustände muss da jetzt gemessen werden? 
Die Geschwindigkeiten sind ja nicht so leicht zu messen... Teile ich 
dann das System auf in Zustände die ich normal berechne und in Zustände 
welche ich schätze?

Als Pseudocode:
Initialisierung:
x1=?; \\Anfangsschätzung
u = 0;

Eigentlicher Algorithmus in einer Schleife als "Sofortregler"
warten();
y=getInput(); \\Eingang einlesen (ADC)
x1=F1*x1+L*(C*x1-y)+G1*u; \\Beobachter
x2=F2*x2+G2*u
x3=F3*x3+G3*u
x4=F4*x4+G4*u
u=-K*[x1 x2 x3 x4]+M*v;\\Zustandsrueckfuehrung
sendOutput(u); \\Ausgang stellen (PWM)

wobei:
F1...F4 die einzelnen Zeilen aus der F Matrix sind, das gleiche bei G

ich steh bei dem ganzen noch ein bisschen auf der Leitung glaub ich...
fg

von Franz S. (spanti)


Lesenswert?

Was mich auch noch bissl stutzig macht:
Die nicht gemessenen Zustände schätzt man ja. Ein geschätzter Zustand 
ist z.B.
xp=F*xp+L*(C*xp-y)+G*u;
aber genau da steckt ja die Messung y drinnen??
fg

von blabla (Gast)


Lesenswert?

Wahrscheinlich kannst du (mit wenig Aufwand) nur die Position und den 
Winkel messen. Also nur 2 Zustände. Eine Aufteilung findet nicht statt.

Die L Matrix ist eine 4xq Matrix, wobei q die Anzahl der Messgrößen ist: 
also hier 2. Deine F-Matrix hat wahrscheinlich keine Diagonalform.

Also hast du (prinzipiell)
x1=F11*x1+F12*x2+F13*x3+F14*x4+L1*(C*x1-y)+G1*u; \\Beobachter
x2=F21*x1+F22*x2+F23*x3+F24*x4+L2*(C*x1-y)+G2*u;
...

Einige F Werte und G Werte sind wahrscheinlich 0.

Mein Tip: Schau dir das Thema Beobachter in einem guten Buch an.

von Franz S. (spanti)


Lesenswert?

Okay danke schön langsam wirds mir klar. Das heißt ich kann 1 bis 4 
Zustände messen. Wo liegt jetzt der Unterschied ob ich jetzt nur einen 
oder alle 4 Zustände messe? In der Genauigkeit? Weil dann würde es 
genügen wenn ich position und Winkel messe und diese für den Beobachter 
verwende, dann ist L ein 4x2 Matrix.

Vielen Dank schon mal, habts mir echt schon voll weitergeholfen.

Und was glaubt ihr, sollte ich wie oben gemeint ein hybrides System 
machen? Weil in die A-Matrix ist ja für alle Zustände = 0 eingesetzt 
worden. Da hätte ich ja einen großen Fehler wenn ich jetzt den Wagen auf 
z.B. +30cm positionieren möchte.
Ich könnte aber auch die Variable für den Weg in der A Matrix nicht 
generell gleich mit 0 einsetzen, sondern messen und dann den gemessenene 
Wert einsetzen und ausrechnen. Die Linearisierung würde dann immer um 
die aktuelle Position stattfinden und ist somit exakt. Die A-Matrix ist 
dann also nicht konstant, sondern vom Weg abhängig und ändert sich je 
nach Position des Wagens. Ginge das?
fg

von blabla (Gast)


Lesenswert?

Zum Messen: für jede Messgröße braucht man ein "Messgerät". Du musst 
genügend messen, damit das System "beobachtbar" ist.

Ja, dies geht unter bestimmten Bedingungen und nennt sich z.B. Gain 
scheduling. Ob es hier geht: keine Ahnung.
Exakt ist die Linearisierung trotzdem nicht und es ist keine sogenannte 
"exakte Linearisierung".

von RP6Conrad (Gast)


Lesenswert?

Das thema kann auch mit eine reine PID-regelung gemacht werden. Siehe 
mal dieses link an : 
http://www.roboternetz.de/phpBB2/viewtopic.php?t=43593

von Franz S. (spanti)


Lesenswert?

Hallo,
ja eine digitale PID Regelung möchte ich eventuell dann auch machen, 
aber da findet man eh einiges im Netz. Nur bezüglich Zustandsregelung is 
a bissl mager.

Also ich hab jetzt die Beobachtbarkeitsmatrix aufgestellt wenn ich Weg 
und Winkel messe, diese hat jedoch nicht vollen Rang. Was heißt das 
jetzt - is das sehr schlimm? Ich weiß nämlich nicht warum ich jetzt noch 
zusätzlich was messen sollte, weil theoretisch kann man sich die 
Geschwindigkeiten ja durch Ableiten ausrechnen also hab ich durch Messen 
von Weg und Winkel eigentlich schon die volle Information meines realen 
Systems.

fg

von Franz S. (spanti)


Lesenswert?

Ich habe das ganze jetzt nochmal mit der Beobachtbarkeit probiert, wenn 
ich als Ausgang NUR den Weg nehme - und da kommt raus dass die 
Beobachtbarkeitsmatrix vollen Rang hat, kann das schon sein?
der Vektor C hat die Form für Weg und Zeitmessung:
C = [1 1 0 0]
und nur für Wegmessung:
C = [1 0 0 0]
die A-Matrix:
[0 0 1 0
 0 0 0 1
 0 a 0 0
 b c 0 0]

Beobachtbarkeitsmatrix:
[   C
   C.A
  C.A.A
 C.A.A.A ]

Bist du dir da sicher dass ich das mit den zu messenden Größen mit der 
Beobachtbarkeitsmatrix überprüfe?
(oder muss ich für den Zeilenvektor bei der Weg und Winkelmessung eine 
Matrix nehmen?
[1 0 0 0
 0 1 0 0]
Dann würds Sinn machen, weil dann is beobachtbar.

fg

von blabla (Gast)


Lesenswert?

Falls du 2 unabhängige Messungen hast, dann ist die C-Matrix 2x4.

von Franz S. (spanti)


Lesenswert?

Hallo Leute,
also ich weiß jetzt soweit wies funktionieren würde. Noch eine kleine 
Frage: Bei meinem System habe ich einen Ausgang den ich regeln möchte, 
das ist der Weg wo der Wagen sich gerade befindet. Die C Matrix ist also 
eine 1x4 Matrix. Beim Zustandsbeobachter möchte ich aber 2 Messungen 
verwenden, den Weg und den Winkel, beide sind unabhängig voneinander. 
Diese Matrix ist 2x4.
Jetzt die Frage: Darf ich das so einfach machen dass ich bei System und 
Beobachter 2 verschiedene C Matrizen verwende (fürs System die 1x4 und 
fürn Beobachter die 2x4)?
Vielene Dank, und wenn wer noch Infos hat bezüglich dem ganzen was ich 
realisieren möchte, ich bin um jede Hilfe dankbar!
fg

von blabla (Gast)


Lesenswert?

Ja.

Bei einem Zustands-Reglerentwurf mit Polvorgabe oder LQR ist der Augang 
egal - der Regler und Reglerentwurf hängt nicht (explizit) davon ab.

von Franz S. (spanti)


Lesenswert?

Hallo Leute,
noch eine Frage zu meinem System: ich müsste das ganze ja um einen 
Arbeitspunkt linearisieren (um eine Position und um einen Winkel, die 
Geschwindigkeiten sind 0). Normalerweise bekomme ich durch Ableiten der 
Gleichung f(x,u) nach x die Systemmatrix A, wo ich dann die Werte 
einsetze um welche ich linearisiere. Könnte ich das ganze auch so 
machen, dass ich jetzt die Wegvariable (Position) nicht gleich von vorne 
herein in die A Matrix einsetze, sondern dass ich die allgemein drinnen 
behalte und bei jedem Taktzyklus des µC die aktuelle Position wo der 
Wagen sich gerade befindet einlese und in die A Matrix hineinschreibe - 
dann hätte ich immer - was zumindest die Position angeht - ein ziemlich 
gutes Verhalten meines "linearisierten" Systems zu meinem 
Originalsystem. Linear ist es ja dann eigentlich nicht mehr. Es würde 
dann hald auch noch der Rückführvektor des LQR Reglers und womöglich 
andere Matrizen auch vom Weg abhängig sein.
Was sagt ihr zu dieser Variante, funktioniert sowas, ist das eine gute 
Idee?
Vielen Dank!

von freddy (Gast)


Lesenswert?

Es ist keine so gute Idee. Vielleicht funktioniert es.

Du kannst evtl die Dynamik so besser beschreiben - aber nicht mehr so 
einfach einen Regler dafür entwerfen.

von Franz S. (spanti)


Lesenswert?

Hallo Leute,
also, ich bein jetzt dabei dass ich das ganze realisiere. Ich wollte nur 
nochmal grundsätzlich fragen, wie ihr das C-Programm aufbauen würdet:

Kann ich da alles einfach in einer Schlange durchschreiben, d.h. für 
jede Aufgabe eine Funktion schreiben (Messwerte einlesen, neue Zustände 
berechnen, ..., Stellgröße ausgeben) und die Funktionen dann ganz 
einfach nach der Reihe ablaufen lassen, oder wäre es besser, das ganze 
mittels Interrupts zu programmieren. Da ich noch nicht lange 
programmiere und von Interrupts noch gar keine Ahnung habe, wäre es mir 
lieber wenn die erste Variante auch funktionieren würde.

fg

von Franz S. (spanti)


Lesenswert?

Kann mir heirzu niemand einen Tipp geben?

von Karl H. (kbuchegg)


Lesenswert?

D.h. du hast es seit Montag nicht einfach mal ausprobiert?

Die Funktionen für Messwerte einlesen, Matrix berechnen, Stellgröße 
ausgeben, etc sind ja völlig identisch, egal ob du sie in einer 
Endlosschleife immer wieder rundum ausführst oder ob du einen Durchgang 
über einen Timer in definierten, regelmässigen Zeitintervallen anstösst.

Probiers einfach aus!
Selbst wenn du noch nie mit Timern und Interrupts gearbeitet hast, ist 
die eine Form in 15 Minuten in die andere Form überführt (und da ist das 
Lesen im Tutorial wie man mit Timern umgeht schon eingerechnet)

Wir können dir hier viel erzählen, aber eigene praktische Erfahrung ist 
durch nichts zu ersetzen.

von Franz S. (spanti)


Lesenswert?

okay, eine Frage hätt ich noch: Ich mach die Positionsmessung mittels 
der Methode mit dem Mausrad und Gabellichtschranke. Da krieg ich pro cm 
circa 20 Impulse. Kann des sein, dass ich da Probleme kriege, wenn 
während dem Berechnen einer Matrix am Eingang ein Impuls für die 
Positionsänderung ist? Kannes sein dass ich den nicht einlese? Ich 
müsste da dauerhaft irgendwie den ADC abfragen...

fg

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.