Kipp- und Neigungswinkel nur aus 3D Magnetfelddaten

Gast #2161320
Lesenswert?

Hallo

ich habe eine ziemlich allgemeine Frage bezüglich der Nutzung von 3D 
Magnetfeldsensoren:

- kann ich mit den Informationen von solch einem Sensor Kipp(pitch) und 
Neigungswinkel(roll) ermitteln

Ich bau gerade eine Lageregelung für eine mehrfach höhenverstellbare 
Plattform und habe bereits ein fusioniertes Signal von einem 3D-Gyro und 
einem 3D-Beschleunigungssensor.
Um die Genauigkeit und die Ausfallsicherheit zu erhöhen will ich mit 
einem 3D-Kompass (Magnetfeldsensor) Kipp- und Neigungswinkel ebenfalls 
berechnen und dann wieder fusionieren (vllt inform einer gewichteten 
Summe o.ä.).
Auf die Idee bin ich gekommen da ich denke das Beschleunigungssensoren 
und Magnetfeldsensoren dass selbe machen bis auf die Verdrehnung der 
Koordinatensysteme.
Da ich bereits einen funktionierenden Algorithmus für die 
Winkelberechnung durch den Beschleunigungssensor habe wollte ich diesen 
gern einfach so anpassen, dass ich den Verdrehungswinkel (Inklination 
ca. 67°) berücksichtige.
Auf meiner Suche nach möglichen Ansätzen habe ich viele Threads zur 
Ermittlung der Orientierung bzgl. Nordausrichtung mithilfe von 
Magnetfeldsensoren und zur Tiltkompensation unter Nutzung von 
Beschleunigungssensoren gefunden. Deshalb bin ich mir nicht mehr sicher 
ob ich bei meiner obigen Überlegung bzgl. des Zusammenhangs zwischen 
Beschleunigungs- und Magnetfeldsensoren nicht doch einen prinzipiellen 
Denkfehler habe.

zur Vollständigkeit hier der Code für den ADXL345 welchen ich für einen 
HMC5843 anpassen möchte:
1
void convert_ADXL(Uint16* data)
2
{
3
         //>>>>>>>Conversion begin<<<<<<<<      
4
         ADXL_dx=(((int)data[0])|((int)data[1]<<8));
5
         ADXL_dy=(((int)data[2])|((int)data[3]<<8));
6
         ADXL_dz=(((int)data[4])|((int)data[5]<<8));
7
         //>>>>>>>Conversion end<<<<<<<<<<
8
}
9

10
void ADXL_angle()
11
{
12
   //range fitting
13
   double const ADXL_x_norm = 0.955224;       // dx : 280 ... - 256 = 536 -> 512/536 = 0.955224;
14
   double const ADXL_y_norm = 0.966037;       // dy : 264 ... - 266 = 530 -> 512/530 = 0.966037;
15
   double const ADXL_z_norm = 0.994175;       // dz : 248 ... - 267 = 515 -> 512/515 = 0.994175;
16
   //zero-point shifting
17
   double const ADXL_x_null = -12.0000;       // x : (280 + x_null) * x_norm = 256;
18
   double const ADXL_y_null = 1.0002;          // y : (264 + y_null) * y_norm = 256;
19
   double const ADXL_z_null = 9.4999;          // z : (248 + z_null) * z_norm = 256;
20

21
   
22
   ADXL_xn = ADXL_dx;
23
   ADXL_xn += ADXL_x_null;
24
   ADXL_xn = (int)(double) ADXL_xn * ADXL_x_norm;
25
   ADXL_gxn = ADXL_xn*D2G;
26
   
27
   ADXL_yn = ADXL_dy;
28
   ADXL_yn += ADXL_y_null;
29
   ADXL_yn = (int)(double) ADXL_yn * ADXL_y_norm;
30
   ADXL_gyn = ADXL_yn*D2G;
31
   
32
   ADXL_zn = ADXL_dz;
33
   ADXL_zn += ADXL_z_null;
34
   ADXL_zn = (int)(double) ADXL_zn * ADXL_z_norm;
35
   ADXL_gzn = ADXL_zn*D2G;
36
   
37
   one_g=sqrt((ADXL_gxn*ADXL_gxn)+(ADXL_gyn*ADXL_gyn)+(ADXL_gzn*ADXL_gzn));
38
   
39
   ADXL_pitch = R2D*(atan(ADXL_gxn/(sqrt((ADXL_gyn*ADXL_gyn)+(ADXL_gzn*ADXL_gzn)))));
40
   ADXL_roll  = R2D*(atan(ADXL_gyn/(sqrt((ADXL_gxn*ADXL_gxn)+(ADXL_gzn*ADXL_gzn)))));
41
   ADXL_yaw   = R2D*(atan(ADXL_gzn/(sqrt((ADXL_gxn*ADXL_gxn)+(ADXL_gyn*ADXL_gyn)))));   
42
   
43
}


Vielen Dank für Ideen/Anregungen im Voraus.
Stephan

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren