Hallo zusammen.
Code:
function xest = fcn(yk, x, xkm1)
....
for 1=1:1:k
...
xest = xk;
xkm1 = xk
i = i+1;
end
end
liefert:
Data 'xest' (#61) is inferred as a variable size matrix, while its
specified type is something else.
Was bedeutet das?
und wie kann ich das beheben?
VG, Tom
Hallo,
Was willst Du tu, d.h. was ist die Absicht hinter dem Code?
Der Code schaut ziemlich sinnlos aus.
xest und xkm1 wird bei jedem Schleifendurchlauf von xk überschrieben.
lg
Markus B. schrieb:> Hallo,> Was willst Du tu, d.h. was ist die Absicht hinter dem Code?> Der Code schaut ziemlich sinnlos aus.> xest und xkm1 wird bei jedem Schleifendurchlauf von xk überschrieben.>> lg
Also ich möchte die drei Gleichungen des EKF (Extended Kalman Filter)
implementieren.
Das war nur ein gedanklicher Erguss, schließlich gings ja um die
Fehlermeldung.
n = 4;
R=0.0142^2; %Kovarianz des Messrauschen;
Q=0.005^2*eye(n); %Kovarianz des Systemrauschen
T = 0.02; %Sampletime
Der Code:
function [x_k, P_k] = EKF(yk, xkm1, Pkm1, ukm1)
%Definieren der Jacobimatrix
J_k=@(xkm1)[0, 1, 0, 0; xkm1(1) xkm1(3) 1 0; sin(xkm1(2)) xkm1(4) 1 0; 1
0 0 xkm1(1)*xkm1(2)];
I = eye(4)
Phi = I+T*F_k; %Transitionsmatrix (Taylorrehihe die nach lin. Glied
abegbrochen wird)
H = [1 0 0 0]; %Messvektor
Ps_k = Phi*Pkm1*Phi'+Q; % Prädiktive Kovarianzmatrix
K_k = Ps_k*H'*inv(H*Ps_k*H'+R); %Kalman Matrix
P_k = (eye(4)-K_k*H)*Ps_k*(eye(4)-K_k*H)'+K_k*R*K_k'; %Korrigierte
Kovarianzmatrix
x_k = Phi*xkm1+H*ukm1 + K_k*(yk-H*Phi*xkm1-H*1*ukm1); % korrigierter
Zustandsvektor
end
Dieser Ansatz führt gleich auf mehrer Probleme.
Zb Bei der Funktion J. Diese kann nicht mit einer Matrix verrechnet
werden, muss aber in jedem Abtastschritt neu berechnet werden.
Anforderungen:
Ich brauche eineFunktion f die Abhängig ist von den Zustandgrößen.
Hiermit wird die Jacobi-matrix bestimmt (in jedem Schritt). Damit lässt
sich zunächst im Prädiktoschritt eine Kovarianzmatrix berechnen.
Weiterhin die Kalmanmatrix. Anschließend kann die korrigierte Kovarianz
und der korrigierte Zustandsvektor bestimmt werden.
Mit dem normalen * werden immer Matrixmultiplikationen ausgeführt. Falls
Du elementeweise multiplizieren bzw. dividieren wills muss .* bzw ./
verwendet werden. Dabei müssen die Matrizen exakt die gleiche Dimension
haben.
lg
Inzwischen habe ich eine Lösung mit Hilfe symbolischer Variablen
gefunden.
Allerdings bekomme ich dann:
The function 'syms' is not supported for standalone code Generation.
Um die Fragestellung nochmals auf den Punkt zu bringen.
Ich benötige ein Programm, dass beginnend mit einem Startvektor x0 =
[x10 x20 x30 x40]'
Die Ableitung der Vektorunktion f an der Stelle x0 berechnet
(Jacobimatrix).
Habe ich mit einer externen Funktion gelöst.
Nun soll mit dieser die Kovarianzen etc berechnet werden.
Nur der Startvektor ist das Problem, weil ich den ja nur beim ersten
Schritt brache.
Die Variablen xkm1 usw. kommen vom Modell als Eingangsgrößen. das ist
eine Matlab-Function
Falls Du Dich wunderst warum nur spärliche Hilfe kommt, könnte es daran
liegen, dass Du Dein Problem nicht klar beschreibst.
Kenne mich zwar nicht sonderlich mit den Sachen aus die Du machen
möchtest, aber Matlab kann ich ganz passabel. Bitte vollständiges M-File
das den Fehler reproduziert, wenn Du Hilfe möchtest.
Karl schrieb:> Falls Du Dich wunderst warum nur spärliche Hilfe kommt, könnte es> daran> liegen, dass Du Dein Problem nicht klar beschreibst.> Kenne mich zwar nicht sonderlich mit den Sachen aus die Du machen> möchtest, aber Matlab kann ich ganz passabel. Bitte vollständiges M-File> das den Fehler reproduziert, wenn Du Hilfe möchtest.
M-File Steht oben...
Das Problem ist wie folgt zu erläutern.
ich möchte eine Funktion f, die eine nicht-lineare Funktion des
Zustandsvektors x(t) und des Eingangsgrößenvektors u(t) ist,
differenzieren.
Die Funktion f sei zB. folgender Form:
Nun soll die Funktion f in jedem Schritt k differenziert werden, und
zwar am zugehörigen Zustansvektor x_k.
Das ist der Hauptpunkt der Berechnungen.
Ich habe es so versucht
function J = Jacobi(x)
coder.extrinsic('syms')
%Parameter
...
syms x1 x2 x3
f = ...
J = subs(jacobian(f), [x1 x2 x3],x)
end
Willst du symbolisch oder numerisch rechnen? Ich schätze letzteres,
daher lass das mit dem syms!
Soll das was in Simulink werden?
Oben schreibst du was davon, dass die Startwerte nicht initialisiert
sind. Warum tust du das dann nicht? Ist es Simulink? Da kann man für
Blöcke/Parameter normalerweise Startwerte angeben.
Ist es "normales" Matlab: Entweder Startwerte von außen initialisieren,
oder in der Funktion behandeln und den ersten Aufruf von darauf
folgenden unterscheiden. Mit exist() und isempty() findest du heraus, ob
die Variablen schon existieren...
Jan K. schrieb:> Willst du symbolisch oder numerisch rechnen? Ich schätze> letzteres,> daher lass das mit dem syms!>> Soll das was in Simulink werden?>> Oben schreibst du was davon, dass die Startwerte nicht initialisiert> sind. Warum tust du das dann nicht? Ist es Simulink? Da kann man für> Blöcke/Parameter normalerweise Startwerte angeben.>> Ist es "normales" Matlab: Entweder Startwerte von außen initialisieren,> oder in der Funktion behandeln und den ersten Aufruf von darauf> folgenden unterscheiden. Mit exist() und isempty() findest du heraus, ob> die Variablen schon existieren...
Es ist sowohl Matlab(M) als auch Simulink(Si). Ich habe eine
Matlab-function in mein Si-Modell eingebunden. mir ist es egal ob
numerisch oder symbolisch. Symbolisch müsste dann irgendwann ersetzt
werden durch die entsprechenden numerischen Werte.
Es muss on jedem k-ten Schritt der insgesamt 1001 Schritte die
Jacobimatrix berechnet werden. Dann die übrigen Matrizen. Eigentlich ist
es nur gefordert einige Startwerte einzulesen und anschließend mit den
kontinuierlich geschätzten werten weiter zu rechnen.
Okay, du brauchst die partiellen Ableitungen nur von den Zuständen,
nicht von der Zeit? Bin mir nicht sicher, ob das numerisch Sinn macht,
du brauchst ja definitiv "Umgebungswerte" deiner Funktion zum
numerischen Ableiten.
http://www.mathworks.com/matlabcentral/fileexchange/13490-adaptive-robust-numerical-differentiation
Ist jedenfalls eine Toolbox, mit der du experimentieren könntest.
Wenn sich die Funktion aber nicht ändert, wieso berechnest du die
Jacobian nicht analytisch vorab und baust sie in Simulink ein? Dafür
gibts hier 1, 2 nützliche Funktionen, damit du das nicht abtippen musst:
https://www.mathworks.com/help/symbolic/code-generation.html
Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
Groß- und Kleinschreibung verwenden
Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang