Germer Sogorb

Last update 04.03.2014

 

bo5

Kalibrierung und Kompensierung des Magnetometers

HMC5883L

 

Kalibrierung

Die Bestimmung des Headings oder azimutale Richtung lässt sich durch die einfache Formel

                            Heading = arctan ( y/x )  rad

beschreiben, vorausgesetzt, der Sensor liegt einigermaßen horizontal (X-Achse zeigt in die gesuchte Richtung). Ist diese Voraussetzung nicht gegeben, muss die geneigte Lage des Magnetometers kompensiert werden. Der Erfolg eines Neigungskompensationsverfahrens (Compass Tilt Compensation) hängt von der Qualität der Magnetometer Raw Daten ab, womit spätestens jetzt kein Weg daran vorbei führt, den Magnetometer kalibrieren zu müssen.

Unter idealen Umständen liegen die vom Magnetometer gelieferten Punkte (X,Y,Z) bei Veränderung seiner Lage in allen Richtungen auf der Oberfläche einer perfekten Kugel und zentriert auf dem (0,0,0) Punkt. In Wirklichkeit gibt es immer eine oder mehrere Störquellen in der Umgebung, die das Magnetfeld beeinflussen. Dieses hat eine Verschiebung und/oder Deformierung der Kugel (jetzt Ellipsoid) als Folge. In dem Fall sind die Berechnungen, die auf ein bestimmtes Verhältnis zwischen zwei Achsen basieren, nicht korrekt. Unter diesen Umständen ist eine Hard und/oder Soft Iron Calibration notwendig.

Die Hard Iron Calibration korrigiert die Raw Daten des Magnetometers vor ihrer Verwendung mit einem Offset für jeden Achse, womit die Kugel auf den Punkt (0,0,0) zentriert wird. Die Soft Iron Calibration gestaltet sich schwieriger, weil durch ein etwas komplizierteres mathematisches Verfahren der Ellipsoid in eine Kugel umgewandelt wird. Hierfür wird jeder Raw Punkt des Magnetometers unter Berücksichtigung aller Achsen vor der Verwendung angepasst. Es ist empfehlenswert sich über diese beide Phänomene sowie die nötige Kalibrierungsmethoden zu informieren.

 

Visualisierung der Magnetometer Daten

Die primäre Aufgabe ist es, Daten sammeln. Mit dem Processing Sketch (unten Link zum herunterladen) kann man sich durchs Drehen in alle Richtungen die Punkte darstellen lassen. Darauf zu achten ist, dass man versucht, in sämtlichen Positionen mindestens ein Punkt aufzuzeichnen. Im gleichen Verzeichnis wird eine Datei mit einem Punkt pro Zeile erzeugt.

 

uncalc

 

images

Processing Code

 

 

Abbildung 1: Darstellung der Magnetometer Daten vor der Kalibrierung

 

 

 

Soft  and Hard Iron Calibration

Berechnung der Offset- und Gain-Werten

 

Das Programm Magneto bietet sich dafür an. Um das für die aufgezeichneten Daten passende magnetisches Feld berechnen zu können, muss man erst mal von der Seite http://www.ngdc.noaa.gov/geomag-web das magnetische Feld der eigenen Region bestimmen. Mit Hilfe der Anleitung dieses Tools kann man den gesuchten Wert berechnen:

To obtain Gravitaion Field (raw format):
1) get the Total Field for your location from here:   http://www.ngdc.noaa.gov/geomag-web (tab Magnetic Field)
   es. Total Field = 47,241.3 nT

2) Convert this values to Gauss (1nT = 10E-5G)  es. Total Field = 47,241.3 nT = 0.47241G

3) Convert Total Field to Raw value Total Field, which is the Raw Gravitaion Field we are searching for Read your magnetometer datasheet and find your gain value, which should be the same of the collected raw points
   es. on HMC5883L, given +_ 1.3 Ga as Sensor Field Range settings
       Gain (LSB/Gauss) = 1090
       Raw Total Field = Gain * Total Field
       0.47241 * 1090 = ~515

Jetzt brauchen wird nur die vorhin aufgezeichnete Datei und die Kalibrierung kann starten. Die Ausgabe des Tools kann so aussehen:

magneto_snapshot

Abbildung 2: Ausgabe Werte von Magneto für das augezeichnete File und das berechnete magnetische Feld

 

Mit dem passenden Code auf der Arduino Seite können wir diese Werte folgendermaßen verwenden:

  #define X 0
  #define Y 1
  #define Z 2
  compass.getValues(&fx,&fy,&fz);    

  //Soft an dHard Iron Calibration
  //Values calculated by Magneto
  double cal_matrix[3][3]={ { 1.225909, -0.012273, -0.007109},
                                           {-0.012273,  0.956366, -0.007113},
                                           {-0.007109, -0.007113,  0.905245}} ; 
  double cal_offsets[3] = {36.067906, -112.466159, -10.944752}; 
  fx += cal_offsets[X];
  fy += cal_offsets[Y];
  fz += cal_offsets[Z];
  fx = cal_matrix[X][X]*fx + cal_matrix[X][Y]*fy + cal_matrix[X][Z]*fz;
  fy = cal_matrix[Y][X]*fx + cal_matrix[Y][Y]*fy + cal_matrix[Y][Z]*fz;
  fz = cal_matrix[Z][X]*fx + cal_matrix[Z][Y]*fy + cal_matrix[Z][Z]*fz;

 

Anbei aber auch der Code in C++ für die Kalibrierung der Daten einer Datei zum Testen, bevor man es im Arduino Sketch einbaut:

images

Calibate.C++

cal

Abbildung 3: Darstellung der kalibrierten Magnetometer Daten

 

 

Compass Tilt compensation - Neigungskompensation

Ausreichende Theorie über Neigungskompensation eines elektronischen Kompasses mit der Nutzung eines Accelerometers ist im Dokument http://freescale.com.hk/files/sensors/doc/app_note/AN4248.pdf  zu finden.  Die Bedingung einer erfolgreichen Neigungskompensation ist eine perfekte Kalibrierung der Magnetometer Daten, daher werden immer die Werte X, Y, und Z durch die Soft and Hard Iron Compensation verarbeitet, bevor man mit Neigungskompensation anfangen kann.

Bedingt dadurch, dass jeder sein Sensor Board unterschiedlich am Zielort einbaut, ist die erste Aufgabe die Festlegung aller 3 Achsen und ihrer Richtungen (Vorzeichen).  Um die Formel vom oben genannten Dokument ohne Änderung verwenden zu können, müssen die Achsen identifiziert und unter Umständen umbenannt werden. Beispielweise liegt unser Gy-80 Board im Gehäuse vertikal. Der X-Achse zeigt in die Kompass Richtung, Y- und Z-Achsen sind aber miteinander vertauscht.

 

Implementierung

Der Aufruf der Funktion für die Neigungskompensation berücksichtigt das Vertauschen der Y und Z Achsen

double cfx, cfy, cfz, compensated_heading;
 //we change Axis y and z
compensated_heading = CompensateHeading( fXg, fZg, fYg, fx, fz, fy, cfx, cfy, cfz);

 

TiltCompEqu-1

float CompensateHeading( double ax, double ay, double az,
                                         double mx, double my, double mz,
                                         double &cmx, double &cmy, double &cmz )
{
  double _roll = atan2( ay, -az);
  double _pitch = atan2( (ax), ((ay*sin(_roll))+(-az*cos(_roll))) );   
 

  cmx = mx*cos(_pitch) + (my)*sin(_pitch)*sin(_roll) + (mz)*sin(_pitch)*cos(_roll);
  cmy = my*cos(_roll) - (mz)*sin(_roll); 
  cmz = -mx*sin(_pitch) + my*cos(_pitch)*sin(_roll) + mz*cos(_pitch)*cos(_roll);
  .......
}

 

TiltCompEq-2

....
  float heading = atan2(cmy, cmx); 
  float declinationAngle = 0.0457;
  heading += declinationAngle; 
  if(heading < 0)
    heading += 2*PI;   
    if(heading > 2*PI)
    heading -= 2*PI;  
  float headingDegrees = heading * 180/M_PI;
 }

 

[Home] [Home-Deutsch] [ÜberUns] [Kontakt] [Astronomie] [Reise] [Home-Espanol]