Magnetometer ∞-förmige Kalibrierung

In Mobiltelefonen und anderen Geräten, die einen elektronischen 3-Achsen-Kompass verwenden, wird eine ∞/8/S-förmige Bewegung verwendet, um das Magnetometer zu kalibrieren, wie in diesen Videos gezeigt .

Warum wird diese Bewegung ausgeführt, was ist die Theorie, und kann jemand einen Beispiel-C-Code geben, um sie zu implementieren?

Sie müssen meine andere ähnliche Frage durchgehen, die weitere Informationen enthält.


Einige zusätzliche Informationen zu dieser speziellen Frage: Die Plattform ist 8-Bit AtMega32 und verwendet AVR Studio 5.

Bis jetzt habe ich es versucht: Ich habe versucht, den Durchschnitt der Vektorwerte des Magnetometers, der die Form macht, durch 2 zu teilen. Nachdenken kann bei der Berechnung von Offsets helfen. Ich denke, dass die beiden identischen Teile / Seiten der Form das Magnetfeld der Erde aufheben und die Offset-Werte ausgeben. Ich könnte falsch liegen. Aber speziell für die formbasierte Kalibrierung bin ich hier gerade. Ich denke, die Kalibrierung funktioniert so. Die Idee ist herauszufinden, ob das so funktioniert?


Ok, der Code, mit dem ich die Offsets berechnen und später einfach vom rohen magnetischen 3D-Vektor subtrahieren kann. Ich könnte völlig falsch liegen und habe keine Erklärung, wie es funktioniert. Nach dem Video und den auf der Kugel aufgetragenen Daten zu sehen, hat irgendwie meinen Gedanken beschleunigt und ich habe diesen Gedanken in Form einer Gleichung verwendet. B)

Code:

Die Funktionen Read_accl();und Read_magnato(1);lesen die Sensordaten aus. Ich hoffe der Code ist selbsterklärend. In der Hoffnung, dass kluge Leute dies sicherlich auf viel bessere Weise nutzen werden. :\

void InfinityShapedCallibration()
{
    unsigned char ProcessStarted = 0;
    unsigned long cnt = 0; 

    while (1)
    {

            Read_accl();

            // Keep reading Acc data
            // Detect Horizontal position
            // Detect Upside down position
            // Then detect the Horizontal position again.
            // Meanwhile an infinity shaped movement will be created.
            // Sum up all the data, divide by the count, divide by 2 .
            // !We've offsets.          

                if (ProcessStarted!=3)
                {
                //
                    //USART_Transmit_String("\r");
                    //rprintfFloat(4, g_structAccelerometerData.accx_RAW);
                    //USART_Transmit_String(",");
                    //rprintfFloat(4, g_structAccelerometerData.accy_RAW);
                    //USART_Transmit_String(",");
                    //rprintfFloat(4, g_structAccelerometerData.accz_RAW);

                }


            if (
             abs( g_structAccelerometerData.accx_RAW) < 100 
            && abs(g_structAccelerometerData.accy_RAW) < 100 
            && g_structAccelerometerData.accz_RAW < -350 
            && ProcessStarted != 2 && ProcessStarted != 3 && ProcessStarted != 1 )
            {
                ProcessStarted = 1; 
            }   

            if (ProcessStarted==1)
            { 

            Read_magnato(1);

                structMagnetometerOffsetDataToEEPROM.Off_X += g_structMegnetometerData.magx_RAW;
                structMagnetometerOffsetDataToEEPROM.Off_Y += g_structMegnetometerData.magy_RAW;
                structMagnetometerOffsetDataToEEPROM.Off_Z += g_structMegnetometerData.magz_RAW;

                cnt++;

            }               
                if ( g_structAccelerometerData.accz_RAW > 350 
                && ProcessStarted==1)
                {
                    ProcessStarted = 2; 
                }

                if ( g_structAccelerometerData.accz_RAW < -350 
                && ProcessStarted == 2 )
                {
                    ProcessStarted=3; 
                    structMagnetometerOffsetDataToEEPROM.Off_X /= cnt;
                    structMagnetometerOffsetDataToEEPROM.Off_X /= 2;

                    structMagnetometerOffsetDataToEEPROM.Off_Y /= cnt;
                    structMagnetometerOffsetDataToEEPROM.Off_Y /= 2;

                    structMagnetometerOffsetDataToEEPROM.Off_Z /= cnt;
                    structMagnetometerOffsetDataToEEPROM.Off_Z /= 2;  

                    UpdateOFFSETDATAinEEPROM();  

                    break;

                } 
    }   
} 

Nachdem ich diese Offsets erhalten hatte, verwendete ich sie wie folgt:

void main()
{
...

Read_magnato(1);
        g_structMegnetometerData.magx_RAW -= structMagnetometerOffsetDataToEEPROM.Off_X ;
        g_structMegnetometerData.magy_RAW -= structMagnetometerOffsetDataToEEPROM.Off_Y ;
        g_structMegnetometerData.magz_RAW -= structMagnetometerOffsetDataToEEPROM.Off_Z ;
...
}

Wie ich erwähnt habe.

Diese Frage braucht viel Hilfe. Benötigen Sie Hilfe bei der Programmierung? Theorie über Magnetometer? Welche Plattform? Was hast du probiert oder nachgeschaut?
ist die Zahl 8 nicht einfach eine Geste, um die Kalibrierung einzuleiten?
Ich weiß nicht, warum sich die Leute so verhalten, als wären sie Roboter. Ich habe einen Link für die gleiche Arbeit gegeben. Ich habe viel daran gearbeitet und Leute, ohne es zu wissen, stimmen es einfach ab. Ich hasse es, wenn meine Frage wegen meiner unklaren Frage abgelehnt wird. Bitte fragen Sie, was benötigt wird, bevor Sie es ablehnen. Ich brenne wirklich darauf, Ergebnisse zu bekommen, und Leute denken nicht einmal nach, bevor sie es ablehnen. Es fühlt sich schlecht an und versucht, mich davon abzuhalten, in die richtige Richtung zu arbeiten. Bitte, ich brauche keine Hilfe bei der Abstimmung.
@Kellenjb: Ich arbeite an einer IMU mit einem einfachen 8-Bit-Atmega32. Ich habe versucht, daran zu arbeiten und kam zu dem Schluss, dass ein 32-Bit-uC wie die Verwendung eines Schwerts anstelle einer Nadel ist. (Entschuldigung für mein Rätsel:)) Ich habe versucht, alle RAW-Werte des Magnetometers zu addieren, der die Form bildet. Teilen Sie dann durch die Anzahl der Eingänge. Denken kann bei der Berechnung des Offsets helfen. Ich denke, dass die beiden identischen Teile / Seiten der Form das Magnetfeld der Erde aufheben und die Offset-Werte ausgeben. Ich könnte falsch liegen. Aber speziell für die formbasierte Kalibrierung bin ich hier gerade. Ich denke, die ...
... Ich denke, die ... Kalibrierung funktioniert so. Die Idee ist, herauszufinden, ob das auf diese Weise funktioniert.
@geometrisch: Nein, die Formgebung in Luft ist der Prozess für die Kalibrierung. Das sagt das Video.
@Rahul2047 Fahren Sie fort und bearbeiten Sie Ihre Frage mit allen von Ihnen angegebenen Details. Dies wird dazu beitragen, Ihre Frage etwas anzuheben, und es für die Leute in Zukunft einfacher machen, sie zu finden, wenn sie dieselbe Frage haben. Ich kenne die Antwort auf Ihre Frage nicht, ich versuche nur, Ihnen zu helfen, jemanden zu finden, der es weiß.
@ Rahul2047 Ok, ich glaube, ich weiß, wie es funktioniert. Werde in Kürze eine Antwort posten. Haben Sie das Datenblatt gelesen, das ich Ihrer vorherigen Antwort beigefügt habe? Ich denke, mit den Down-Votes, wenn Sie etwas detaillierter gefragt wurden, z. Beschreibung der S / 8-Form und wie sie häufig in Telefonen verwendet wird, Beschreibung dessen, was in diesen verlinkten Videos enthalten ist, damit die Leute nicht durchklicken müssen, wenn sie dies nicht möchten usw., ist eine bessere Frage.
Das Problem war nicht die Frage, sondern die Anzahl der Leute auf dieser Seite, die Fragen ablehnen, einfach weil sie mit dem Thema nicht vertraut genug sind, um zu verstehen, was gefragt wurde. Wenn Sie es nicht wissen, lassen Sie es einfach!
@ChrisStratton Du hast wahrscheinlich Recht. Meine Erfahrung mit Stackexchange-Sites ist, dass je spezifischer die Frage ist, desto weniger wahrscheinlich ist, dass sie abgelehnt wird. Auf den ersten Blick scheint der Umfang dieser Frage zu groß. Bevor eine Ablehnung aufgezeichnet wird, sollte der Wähler vielleicht gefragt werden, ob eine Bearbeitung die Frage verbessern würde.
Für diejenigen, die nur abstimmen: Lernen Sie von: stackoverflow.com/users/248123/andand
@ChrisStratton, bei den Magnetometern, die ich mir zuvor angesehen habe, musste ich die Kalibrierung nicht selbst implementieren, sie war intern. Das ist eine Erinnerung an eine lange Zeit. Ich habe das Gefühl, dass die Benutzer die Frage etwas zu weit gefasst fanden, um herauszufinden, was in eine Kalibrierung einfließen würde. Denken Sie daran, dass 2 Upvotes zu einer Frage 5 Downvotes annullieren, sodass der Benutzer nicht wirklich Gefahr läuft, schnell Reputation zu verlieren.
@Rahul2047 Kannst du den Code posten, den du gerade verwendest?
Ich kann einen Teil des Codes hier einfügen. Dies kann erklären, wie der auf Unendlichkeitsformen basierende Algorithmus funktioniert, oder verbessert werden. Wird das reichen?
das wäre toll. Ich muss die Magnetometerkalibrierung selbst implementieren, daher ist diese Frage ziemlich gut. habe eine einfache Kalibrierungsmethode hinzugefügt, die ich gefunden habe.
@geometrisch : Ich habe den Code angegeben, den ich setzen durfte. :)
@ Rahul2047 Der Code ist ein guter Versuch, die Offsets zu finden, aber es scheint, dass er nur Werte in der umgekehrten Position aufzeichnet. Anstatt all der 'if'-Anweisungen in Ihrem Code sollten Sie auch die 'switch'-Anweisung verwenden, um einen Zustandsautomaten zu implementieren. Vertrauen Sie mir, Sie werden froh sein. Wenn wir davon ausgehen, dass die „Kugel“ nicht verformt ist, können Sie die Offsets meiner Meinung nach ganz einfach mit den Werten der 8/S-Methode ermitteln. Ich bin mir noch nicht ganz sicher, wie ich das rechnen soll, aber ich versuche es herauszufinden.
@geometrika: Hmm k .. der halbe Teil scheint zu fehlen .. Ich werde es korrigieren, es versuchen und es erneut posten. Das scheint der Zufall gewesen zu sein. :) :P . Ich denke, if (ProcessStarted==1 || ProcessStarted==2) { Read_magnato(1); structMagnetometerOffsetDataToEEPROM.Off_X += g_structMegnetometerData.magx_RAW; structMagnetometerOffsetDataToEEPROM.Off_Y += g_structMegnetometerData.magy_RAW; structMagnetometerOffsetDataToEEPROM.Off_Z += g_structMegnetometerData.magz_RAW; cnt++; }sollte funktionieren?

Antworten (1)

Das 8/S-förmige Muster wird verwendet, um Magnetometer in Mobiltelefonen und anderen Geräten zu kalibrieren.

Hintergrund

Typische Magnetometer aus der Handyzeit messen die magnetische Feldstärke entlang dreier orthogonaler Achsen, z. B.:

m = m x ich ^ + m j ȷ ^ + m z k ^

Mit der Größe des Feldes gegeben durch

m = m x 2 + m j 2 + m z 2

und der Rotationswinkel von jeder Achse als

θ k = cos 1 m k m ,  wo  k [ x , j , z ]

Kalibrierung

Da das Magnetfeld der Erde relativ konstant ist, sollte die Größe des vom Magnetometer gemessenen as-Feldes auch konstant sein, unabhängig von der Ausrichtung des Sensors. dh wenn man den Sensor herumdreht und zeichnet m x , m j , und m z in 3D sollten die Pfade die Oberfläche einer Kugel mit konstantem Radius darstellen.

Idealerweise sollte es so aussehen:

Kugel

Aufgrund von Hart- und Weicheiseneffekten und anderen Verzerrungen sieht es jedoch am Ende wie eine deformierte Kugel aus:

deformiert

Dies liegt daran, dass sich die vom Sensor gemessene Größe des Magnetfelds mit der Ausrichtung ändert. Das Ergebnis ist, dass die Richtung des Magnetfelds, wenn es nach den obigen Formeln berechnet wird, von der wahren Richtung abweicht.

Eine Kalibrierung muss durchgeführt werden, um jeden der drei Achsenmesswerte so anzupassen, dass die Größe unabhängig von der Ausrichtung konstant ist – Sie können sich das so vorstellen, als ob die deformierte Kugel zu einer perfekten Kugel verzerrt werden muss. Der LSM303- Anwendungshinweis enthält viele detaillierte Anweisungen dazu.

Was ist also mit dem Muster der Figur 8!?

Wenn Sie das Muster der Figur 8 ausführen, wird ein Teil der darüber liegenden verformten Kugel „nachgezeichnet“. Aus den erhaltenen Koordinaten kann die Deformation der Kugel abgeschätzt und die Kalibrierungskoeffizienten erhalten werden. Ein gutes Muster ist eines, das den größten Orientierungsbereich durchläuft und daher die größte Abweichung von der wahren konstanten Größe schätzt.

Um die Form der verformten Kugel abzuschätzen , kann eine Ellipsenanpassung nach der Methode der kleinsten Quadrate verwendet werden. Auch hierzu gibt der LSM303 Application Note Hinweise.

Eine einfache Methode für eine Grundkalibrierung

Wenn Sie keine Weicheisenverzerrung annehmen, wird die deformierte Kugel laut App-Hinweis nicht gekippt. Daher kann eine einfache Methode für eine Grundkalibrierung möglich sein:

  • Finden Sie den maximalen und minimalen Wert für jede Achse und erhalten Sie den 1/2-Bereich und den Nullpunkt

r k = 1 2 ( max ( m k ) Mindest ( m k ) )

z k = max ( m k ) r k

  • Verschieben und skalieren Sie jede Achsenmessung

m k ' = m k z k r k

  • Berechnen Sie die Werte wie zuvor, außer mit m k '

Dies basiert auf dem hier gefundenen Code.

Lösen mit der Methode der kleinsten Quadrate

Der MATLAB-Code zum Lösen mit der Methode der kleinsten Quadrate ist unten dargestellt. Der Code geht von einer Variablen aus, magbei der die Spalten die xyz-Werte sind.

H = [mag(:,1), mag(:,2), mag(:,3), - mag(:,2).^2, - mag(:,3).^2, ones(size(mag(:,1)))];
w = mag(:,1).^2;
X = (H'*H)\H'*w;
offX = X(1)/2;
offY = X(2)/(2*X(4));
offZ = X(3)/(2*X(5));
temp = X(6) + offX^2 + X(4)*offY^2 + X(5)*offZ^2;
scaleX = sqrt(temp);
scaleY = sqrt(temp / X(4));
scaleZ= sqrt(temp / X(5));

Um eine dynamische Achterkalibrierung durchzuführen, könnten Sie die Routine der kleinsten Quadrate bei jedem neuen Messwert ausführen und beenden, wenn sich die Offset- und Skalierungsfaktoren stabilisiert haben.

Das Magnetfeld der Erde

Beachten Sie, dass das Magnetfeld der Erde normalerweise nicht parallel zur Oberfläche verläuft und es möglicherweise eine große nach unten gerichtete Komponente gibt.

Hallo, das ist eine bemerkenswerte Anstrengung, die Sie unternommen haben, um den Weg für das Problem mit dem Muster in Abbildung 8 freizumachen. Jetzt kann ich einige meiner früheren Arbeiten mit der aktuellen Arbeit verbinden. Ich habe einige Verbesserungen gesehen, aber nicht bis zur Marke. Wie ich bereits erklärt habe Nur Frage; die NEWS werden korrekt angezeigt, indem die Ausgabedaten verwendet werden, nachdem die 8-Form erstellt wurde, und dann die Hälfte des Durchschnitts aller Vektoren erhalten wird. Überraschenderweise funktioniert es für den horizontalen Plan (per Zufall). Also bin ich wieder an der gleichen Stelle von wo ich mit der Arbeit am 8-Form-Algo begonnen habe. Ich werde nach "Least Square" zurückkommen. Ich bin jedoch nicht in der Lage, den Zufall zu verstehen.
... In meinem Fall scheint auch die Kugel auf der Z-Achse deformiert zu sein. Bitte beachten Sie, dass mir der Effekt von hartem und weichem Eisen auf der gezeichneten 3D-Kugel bekannt ist. Ich werde versuchen, es noch einmal in 3D zu zeichnen. Mal sehen.
@ Rahul2047 Nun, ich hoffe nur, dass es richtig ist, aber es ergibt für mich Sinn. Ich muss eine ähnliche Kalibrierung für ein Instrument durchführen, das ich baue, aber ich bin noch nicht ganz in der Lage, den Code zu implementieren.
Ich frage mich, dass für Telefone, die normalerweise nur an der Richtung in der horizontalen Ebene interessiert sind, eine einfache Geste alle erforderlichen Punkte abdeckt. Benutzt du matlab? Es ist einfach, die Passform dort zu machen. Kleinste Quadrate bezieht sich auf die Fehlermessmethode.
hm hm Ich habe Angst, wenn mein Magnetometer nur in der horizontalen Ebene funktioniert. Ich kann Matlab nicht verwenden, aber Octave. Ich studiere immer noch 'Least Square'. Bisher sah es so aus, als ob das 'Least Square' in keinem 8-Bit-UC an Bord verwendet werden kann. Und mein Gerät muss bei Bedarf an Bord kalibriert werden. Oder ist „Least Square“ ein einmaliger Prozess, nur um die Fehlerschätzung zu modellieren und die Ausgabegleichung zu verwenden, wann immer die Kalibrierung benötigt wird. Ich denke nicht. :) Nachdem ich umsetzbares Wissen gesammelt habe, werde ich es mit Octave versuchen. Arbeite derzeit am Plotten der 3D-Kugel.
Ich habe viel von Ihrer Art, Antworten zu schreiben, gelernt. \m/
Eigentlich habe ich wenig Erfahrung mit der Umsetzung der kleinsten Quadrate. Die App-Notiz besagt, dass die verzerrte Kugel nicht geneigt ist, es sei denn, es gibt eine Weicheisenverzerrung.
Einige der Bildlinks in diesem Artikel sind kaputt gegangen. Können Sie die Bilder erneut hinzufügen? SE hat jetzt eine Funktion, die die Bilder hochlädt und sie lokal speichert, um zukünftigen Bruch zu verhindern. Vielen Dank!