Forum: Mikrocontroller und Digitale Elektronik Kipp- und Neigungswinkel nur aus 3D Magnetfelddaten


von Stephan (Gast)


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

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.