Hallo,
bastel zurzeit an einem System mit dem ich die Neigung von einem
dynamisch Bewegten System erfassen kann, das funktioniert auch schon
ganz gut, allerdings will ich noch versuchen das optimum
herauszukitzeln.
Der ganze Aufbau besteht aus einem Atmega8, einen dreiachsen
Beschleunigungssensor (ADXL330) und dem Gyro (MLX90609), die bestimmung
des Winkels mittels des Beschleunigungssesors funktioniert auch schon
ganz gut, naja der Gyro ist noch verbesserungswürdig.
Jetzt zu dem eigentlichen Problem, da der ganze aufbau ja sehr
empfindlich auf erschütterungen reagiert und somit das Messergebnis
verfälscht, dachte ich mir das ich da mal nen Kalman-Filter drüberjagen
könnte, also ein wenig im i-net gesucht und dann auf folgender seite:
http://home.arcor.de/uffmann/ARTIST3.htm auch einen code dazu gefunden,
allerdings habe ich einige Fragen dazu.
1
staticconstfloatdt=0.0041;// Die Aktualisierungsrate
2
3
// Die zwei Zustände, der Winkel und die Gyro Schräglage
4
floatangle=0.0;
5
floatq_bias=0.0;
6
floatrate=0.0;
7
8
floatangle_err;
9
floatC_0;
10
11
// Die Kofaktor Matrix
12
staticfloatP[2][2]={
13
{1,0},
14
{0,1},
15
};
16
17
staticconstfloatR_angle=.2;// Rauschen des Beschleunigungssensors
18
staticconstfloatQ_angle=0.001;// Trust Verhältnis von Winkel zum Gyro
19
staticconstfloatQ_gyro=0.001;// Trust Verhältnis von Winkel zum Gyro
20
21
22
/******** Gyro Messung, Kalman Filtern ********/
23
voidStateUpdate(constfloatq_m)
24
{
25
constfloatq=q_m-q_bias;// Die wahre Schräglage rausrechnen
C_0=1;// Beziehung zwischen aktueller Messung und alter
53
54
constfloatPCt_0=C_0*P[0][0];
55
constfloatPCt_1=C_0*P[1][0];
56
constfloatE=R_angle+C_0*PCt_0;// E = C P C' + R (Fehler schätzen)
57
constfloatK_0=PCt_0/E;// K = P C' inv(E) (Die Kalman Filter verstärkung berechnen)
58
constfloatK_1=PCt_1/E;// K = P C' inv(E) (Die Kalman Filter verstärkung berechnen)
59
constfloatt_0=PCt_0;// P = P - K C P (Kofaktor Matrix aktualisieren)
60
constfloatt_1=C_0*P[0][1];// P = P - K C P (Kofaktor Matrix aktualisieren)
61
62
P[0][0]-=K_0*t_0;
63
P[0][1]-=K_0*t_1;
64
P[1][0]-=K_1*t_0;
65
P[1][1]-=K_1*t_1;
66
67
angle+=K_0*angle_err;// X += K * err (Differenz zwischen geschätzten Winkel und gemessenen)
68
q_bias+=K_1*angle_err;// X += K * err (Differenz zwischen Drehraten Winkel und gemessenen)
69
}
Jetzt meine Fragen zu den abgebildeten Funktionen, woher kriege ich
jetzt die Variable die den Winkel Kalman gefiltert enthält, da die
Funktionen ja keinen Rückgabewert haben, oder wird dieser in einer
globalen Variable verstaut?
Achtung, die Kommentare hab ich zum Code hinzugefügt und müssen nicht
richtig sein.
TOM wrote:
> angle und q_bias sind die Zustandsgrößen des Systems und gleichzeitig> die Ausgänge, da die Ausgangsmatrix ja 1 ist
d.h. ich musst lediglich die beiden funktionen aufrufen und zur ausgabe
auf meinem display später die korriegierten variablen angle und q_bias
benutzen, wenn ich das richtig verstehe?
Dann noch eine Frage zu den Übergabewerten der Funktionen, in welchen
form müssen die vorliegen, als Winkel oder "raw" so wie sie der
jeweilige sensor ausgiebt.
naja ich denke mal, die die kalmanfilter verstehen,
programmieren nicht .. und die die programmieren, verstehen
kalman filter nicht. das ist so ein dilema^^
da die funktionen weder zeigern nehmen, noch was zurückgeben
so werden sie sicher über globale variablen die werte
zurückgeben.
Hallo Patrick,
> Dann noch eine Frage zu den Übergabewerten der Funktionen, in welchen> form müssen die vorliegen, als Winkel oder "raw" so wie sie der> jeweilige sensor ausgiebt.
Ich kenne jetzt Deinen Sensor nicht, aber ich denke mal, dass der eine
variable Spannung erzeugt, die Du per ADC einliest - d.h. Du hast
erstmal ganzzahlige Werte, die umgerechnet werden müssen (per Tabelle
oder Berechnung).
Bei Winkelberechnungen werden Winkel gerne im Bogenmaß-Format verwendet,
deshalb auch float als Parametertyp.
Gruß Santi
>> naja ich denke mal, die die kalmanfilter verstehen,>> programmieren nicht .. und die die programmieren, verstehen>> kalman filter nicht. das ist so ein dilema^^
widerspruch :-)
Orientiere dich nicht zu sehr an dem Code, schreib dir das Ganze mal in
Zustandraumdarstellung auf und dir werden die Skalierungen der Variablen
klar. Angle ist einfach der Winkel, der ja in der Prädiktion durch
Integration von q über dt berechnet wird.
Santiago m. H. wrote:
> Ich kenne jetzt Deinen Sensor nicht, aber ich denke mal, dass der eine> variable Spannung erzeugt, die Du per ADC einliest - d.h. Du hast> erstmal ganzzahlige Werte, die umgerechnet werden müssen (per Tabelle> oder Berechnung).> Bei Winkelberechnungen werden Winkel gerne im Bogenmaß-Format verwendet,> deshalb auch float als Parametertyp.>> Gruß Santi
Danke ersteinmal für die noch eingetroffenen Antworten, ja du vermutest
schon richtig das ich die Werte des Beschleunigungssensors Analog
einlesen, wobei ich dann je nach Stellung des Sensors ein
proportionalens Spannungssignal erfasse, den Gyro lese ich allerdings
per SPI aus, sprich digital, da ich relativ neu in Microcontroller bin,
kam zwei verschiedene Varianten zum auslesen in Frage, damit ich dabei
auch noch was neues lerne.
Hier ein paar infos zu den eingesetzten Sensoren:
http://www.analog.com/en/mems-and-sensors/imems-accelerometers/adxl330/products/product.htmlhttp://www.melexis.com/ProdMain.aspx?nID=582
Habe mich mittlerweile ein wenig mit dem Kalman Filter beschäftigt und
herausgefunden das eure vermutungen Richtig waren die variablen angle
und q_bias tatsächlich die rückgabewerte als globale variable
darstellen.
Naja das ganze funktioniert zwar schon ganz schön allerdings werde ich
wohl nicht darum herumkommen, mich noch ein bisschen tiefer in die
Thematik einzuarbeiten.