PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Winkelauswertung mit Accelerometer - Wo Werte zum Nullen einrechnen?



Cysign
18.12.2012, 14:45
Hallo,

ich möchte mit einem Beschleunigungssensor Winkel auswerten, um so Neigungswinkel und Drehung an einem Brett zu erfahren.
Dazu habe ich einen Beschleunigungssensor in einem Plastikgehäuse.
Allerdings kann ich den Sensor nicht 100% parallel zum Brett oder seinem Gehäuse ausrichten, weshalb ich auf einem absolut graden Tisch/Brett x Werte auslese, darauß den Mittelwert bilde und diese quasi zum 'Nullen' des Sensors verwenden möchte.

Wenn ich die Daten des Sensors nun mit µ (steht für X/Y/Z):

(asin(µ/sqrt( (x*x) + (y*y) + (z*z)))* 180 / 3.14159265)

auswerte, bekomme ich den Winkel der aktuellen Lage des Sensors ausgegeben.
Solange der Sensor nur in der Ebene liegt, kann ich meine auf der graden Ebene ausgelesenen Werte einfach bei den entsprechenden Winkeln addieren und somit den Sensor nutzen, um die Lage des Bretts bei 0° zu bestimmen.

Wenn ich nun allerdings den Winkel der Y-Achse ändere, verändere ich gleichzeitig den Winkel der X-Achse, da der Sensor nicht parallel zum Brett aufliegt.

Nun ist meine Überlegung, dass ich nicht erst die Sensordaten in WInkel umrechne und dann korrigiere, sondern dass ich zuerst den Korrekturfaktor einreechne und dann in die entsprechenden Winkel umrechne.

Die Sensordaten bestehen aus Werten um die +/-4100 pro Achse.

Wäre es logisch, dass der Winkel dann richtig angezeigt wird, wenn ich die Eichungs-Werte vor der Winkelberechnung einlese?

Oder muss ich einen Weg wählen, wie ich die Sensorkoordinaten auf den Weltkoordinaten projeziere?

Ich hoffe, mir kann hier jemand meine mathematischen Lücken füllen und mir zum Erfolg verhelfen :)

Dirk
18.12.2012, 15:25
Ich würde, wie du schon gesagt hast, den Sensor auf waagerechter Fläche nullen und mit den "kalibrierten" Werten rechnen.

Cysign
18.12.2012, 16:05
Nun ja, das ist der erste Schritt, den ich machen muss, um ne Relativität zur Erdbeschleunigung zu bekommen.
Aber wenn die Y-Achse nun gedreht wird und die X-Achse nicht 100% orthogonal zur bewegten Achse steht (weil der Sensor nicht 100% parallel zur Drehachse steht), beeinflusst der Y-Winkel den X-Winkel.

Ich könnte jetzt versuchen, eine Wertetabelle zu erstellen, damit ich weiß, bei welchem Winkel der X-Wert wie stark und in welcher Richtung beeinflusst wird...aber das wär sehr, sehr aufwändig und müsste bei jedem neuen Durchgang zur Kalibrierung (z.B. auf nem anderen Brett, ich bekomm den Sensor ja niemals auf zwei Brettern haargenau gleich ausgerichtet!) in zwei Positionen durchgeführt werden (einmal wenn der Sensor liegt und einmal, wenn er um 90° gekippt ist, damit man quasi eine virtuelle Ebene errechnen kann, auf der sich der Sensor dreht).


Die Korrekturwerte muss ich sowieso einfluießen lassen.
Aber würdest du diese in den Wertebereich des Sensors vor der Umrechnung in Winjkel (also bei den Werten +/- ~4100) oder nach der Umrechnung in Winkel einfließen lassen?

Dirk
18.12.2012, 21:10
Cysign:
Die Korrekturwerte muss ich sowieso einfluießen lassen. Aber würdest du diese in den Wertebereich des Sensors vor der Umrechnung in Winjkel (also bei den Werten +/- ~4100) oder nach der Umrechnung in Winkel einfließen lassen?
Ich würde das schon mit den ADC- bzw. Ausgabe-Werten machen.

Klar kann der Sensor nur in seinem eigenen Koordinatensystem messen. Die Umrechnung in ein anderes Koordinatensystems ("Brett") ist sehr aufwändig und bei deiner Anwendung (derselbe Sensor auf unterschiedlichen "Brettern" oder Gehäuseformen) auch kaum durchführbar. Auf welche Lage in Bezug auf den "Untergrund" soll sich denn der Sensor einstellen? Letztlich kann man ja auch nur eine Größe messen, wenn eine feste Beziehung zwischen "Messgerät" und "Messobjekt" definiert werden kann.

Cysign
18.12.2012, 22:00
Ich würde gerne die Y-Achse des Sensors mit der Länge des Bretts parallelisieren, damit ich in jeder Y-Lage den passenden X-Wert bestimmen kann (Y-Achse = Längskante des Bretts, x * kurze kante des Bretts. Z-Achse geht in die Höhe und wird von mir nicht benötigt).

Also meinst du, dass es mehr sinn macht, eine Vergleichstabelle automatisiert bei einer definierten Drehung als Messreferenz aufzunehmen und diese hinterher zu interpolieren, um den passenden X-Null-Winkel zu bekommen?

An den unterschiedlichen Brettern wird der Sensor annähernd gleich montiert. Aber halt nur zu 99,5% gleich.

Dirk
22.12.2012, 15:58
@Cysign: Ich kann wenig helfen, weil ich noch nicht genau weiss, was du messen willst.

Baust du prinzipiell so etwas: http://www.elv.de/output/controller.aspx?cid=74&detail=10&detail2=13927
... auch evtl. in 2 Ebenen oder auch noch die 3. Ebene (Z-Achse), also die Rotation des Brettes um eine Art zentrale Achse.

Fragen:
1. Um welche Achsen kippt das Brett? Um alle drei?
2. Auf welche Dreh-Achse kommt es dir an, d.h. welche willst du messen und welche ist/bleibt konstant?
3. Warum ist die Lage des Sensors auf dem Messobjekt variabel und nicht genau zu definieren?
4. Kannst du vielleicht einmal die konkrete Anwendung beschrieben?

Cysign
23.12.2012, 00:12
Ich möchte im Endeffekt die Neigung (nennen wir sie X-Achse) um die schmale Achse des Brettes messen. Da ich den Sensor aber nie 100% genau ausrichten kann und die Messwerte vom der Neigung um die Längsachse (nennen wie diese Y-Achse) somit abhängig sind, muss ich diesen Messfehler korrigieren.
Vom Prinzip her ist es also so etwas, was du da verlinkt hast.

1. Das Brett kippt um Y-Achse (lange Seite vom Brett) und um die X-Achse (kurze Seite vom Brett). Die Z-Achse (nach oben) benötige ich nicht.
2. Die Längsseite bleibt während des Messens konstant, ich möchte die X-Achse messen.
3. Die Lage ist variabel, weil ich den Sensor nicht fest verkleben kann, da ich ihn für mehrere Bretter nutzen muss. Ich kann ihn zwar versuchen präzise auszurichten, aber wenn er nicht 100% genau sitzt, beeinträchtigt das die Messwerte um bis zu 2° bei einer Drehung von 90°, was ich korrigieren möchte.

Ich versuche morgen mal eine Skizze zu zeichnen, woran es dann leichter fallen sollte, das Problem nachzuvollziehen. Aber jetzt muss ich erstmal tot umfallen ;)

rossir
23.12.2012, 18:59
Ich denke da ans Skalarprodukt. Und z ist dabei genau so wichtig!
Egal wie schief der Sensor in Deiner Box liegt. Hauptsache er ist darin irgendwie fixiert. Der Accelerometer Vektor (x,y,z) zeigt immer zum Erdmittelpunkt.

Kleb die Box irgendwo auf's gerade Brett, ließ den Sensor aus und nenne den Vektor A.
Dann neige das Brett um die y-Achse und der Sensor liefert Vektor B.
Mit Hilfe des Skalarproduktes A*B kannst Du den Neigungswinkel ausrechnen.

Das Skalarprodukt liefert Dir den Winkel zwischen den Brettebenen in 1 und 2. D.h. mit dem Skalarprodukt kannst Du nicht zwischen einer Neigung um y-Achse und/oder x-Achse unterscheiden.

Wahrscheinlich habe ich bis hierhin Dein Problem nicht gelöst aber hoffentlich ein wenig mit der Mathematik geholfen.

Cysign
01.01.2013, 08:00
So, hier mal eine grobe Übersicht. Ich hfofe, es ist verständlich. Der rosane Kasten soll der Sensor sein.

Der Sensor ist in der Box fixiert, die ich auf das Brett lege.
Das Brett ist zum Testen da, wo die X-Achse eingezeichnet ist, fixiert, so dass ich es zum Testen um den Winkel ß drehen kann.


24169

Da ich immer noch nicht so ganz durchblicke, ist mein Ansatz derzeit, dass ich das Brett langsam um ß drehe und dabei Nullwerte für α einlese. Um α auszuwerten werden diese Werte dann hinterher addiert.
Also wenn α bei ß 15° z.B. um 0,3° abweicht, kann ich anhand des Arrays ablesen, dass bei ß 15° a -0,3° sein muss, um eigentlich 0° anzuzeigen.

Cysign
18.03.2013, 11:55
So, nachdem ich mich nun etwas mehr mit der Materie auseinandergesetzt habe und der Sensor komischweweise bei Wiederholungsmessungen (ohne dass man ihn berührte/bewegte) Abweichungen in zu großem Maße aufweist, hab ich mich entschieden den Sensor ohne Gehäuse direkt auf der Platine mal unter die Lupe zu nehmen.
Vor allem auffällig ist, dass er in der Regel die ersten paar Minuten nach der Inbetriebnahme Werte ausspuckt, die etwa um 0,2° (Raw-daten in Winkel umgerechnet) von den Werten, die nach einigen Minuten ausspuckt abweichen. Für die gewünschte Anwendung ist das zu unpräzise.

Aus dem Grund möchte ich mich nun einem Oak Tilt (http://developer.toradex.com/files/toradex-dev/uploads/media/Oak/Datasheets/Oak_Tilt_Datasheet.pdf) widmen.
Hier bekomme ich die Koordinaten jedoch nicht als Rohdaten ausgespuckt, sondern direkt Winkel für Azimuth (Wikel in Bezug zur X-Achse um Z gedreht) und Zenith (Winkel zur Z-Achse).

Nun überlege ich, wie ich diese Winkel umrechnen kann, da ich eine Kalibrierungsemssung vornehmen möchte, die etwa parallel zur Y-Achse liegt und quasi den Winkel Z-X-darstellt.

ichbinsisyphos
18.03.2013, 13:36
Ich blick nicht ganz durch, was du da machst. Wenn du die Neigung um 3 Winkel willst, dann bestimmst du den Erdbeschleunigungsvektor in der Nullstellung und in jeder Lage neu. Dann berechnest du die Drehung um jeden Winkel relativ zu diesem Null-Erdbeschleunigungsvektor.

Cysign
18.03.2013, 14:03
Nun ja, der erste Sensor hat mir die Rohdaten der drei Achsen geliefert. xAcc_raw, yAcc_raw und zAcc_raw. Damit konnte ich die nötigen Winkel berechnen.

Der Sensor, den ich jetzt teste, liefert mit einen Winkel, der quasi die Drehung um die Z-Achse bestimmt (Azimuth) und einen Winkel, der den Winkel zur Z-Achse bestimmt (Zenith)

In dieser Wikipediagrafik entsprechend:
Azimuth (Sensor) = Azimuth (Grafik)
Zanith (Sensor) = Meridian (Grafik) = 90° - Höhe

http://upload.wikimedia.org/wikipedia/commons/9/9c/HorSys.svg

Somit kann die Lage eindeutig bestimmt werden, jedoch im dreidimensionalen Raum.
Für meine Messung benötige ich jedoch nur die Neigung um eine Achse. Sagen wir den Winkel (Grafik) zwischen Z- und X-Achse.
Um nun eine Kalibrierung vorzunehmen, richte ich den Sensor an bestimmten Messpunkten aus und errechne mir eine virtuelle Ebene, die quasi die 0°-Stellung des Sensors darstellt (man kann so einen Sensor nie 100% in einem Gehäuse ausrichten...daher ist die Kalibrierung nötig).

Mit dem alten Sensor habe ich nun den Winkel um die unwichtigere Achse ausgewertet und anhand dieser Winkelbestimmung die Relevante Achse mit meiner virtuellen Ebene verrechnet, um eine kalibrierte Neigung zu bekommen.
Das funktioniert aber nur, wenn ich die Sensorwerte für alle drei Achsen habe.

Nun überlege ich, wie ich aus dem Azimuth- und dem Zenith-Winkel des neuen Sensors pseudo-Rohdaten berechnen kann, damit ich diese mit meiner bereits existierenden Kalibrierung nutzen kann.

Sollte das nicht funktionieren, muss ich versuchen die beiden ausgegebenen Winkel auf eine Ebene zu projezieren.
Da ich den Winkel X-Z haben möchte:
Stell dir vor, du schaust entlang der Y-Achse und siehst die Z-Achse senkrecht vor die. Der ausgegebene Vektor stellt nun den gesuchten Winkel auf der X-Z-Ebene dar.
Ich weiß nur noch nicht, wie ich das projezieren kann und wie ich meine Kalibrierung dahin portieren kann.
Am einfachsten wäre es, wenn ich die Rohdaten des Sensors auslesen könnte.

Die Grundlage zur Auswertung des Sensors ist der beispielcode von Toradex:
http://files.toradex.com/Oak/Linux/OakLinux_0081.tar.bz2
im Unterordner src gibts die oaklinux.cpp, welche den Sensor erkennt und die Deviceinfos sowie die Daten ausliest.
Aber hier steig ich noch nicht so ganz durch. Ich muss gestehen, dass ich jetzt etliche Stunden gebraucht habe, den Code überhaupt so zu kompilieren, dass ich Sensorinfos bekommen habe.

Die Ausgabe des Beispielcodes sieht dann wie folgt aus:

Device Name: Toradex Inclinometer
Volatile User Device Name: oaktilt
Persistent User Device Name: oaktilt
Serial Number: 08490303
VendorID: 0x1b67 :: ProductID: 0x4 :: Version 0x104
Number of channels: 4
Report mode: 0
Led Mode: 0
Report rate: 2000
Sample rate: 2000

Channel 0:
Name: Frame Number [s]
Persistent user channel name: oaktilt
Volatile user channel name: oaktilt
Data type: 16 bits (unsigned)
Unit exponent: -3
Unit s (USB code 0x1001)

Channel 1:
Name: Acceleration [m/s2]
Persistent user channel name: Frame Number
Volatile user channel name: Frame Number
Data type: 16 bits (unsigned)
Unit exponent: -3
Unit m/s2 (USB code 0xe011)

Channel 2:
Name: Zenith [rad]
Persistent user channel name: Acceleration
Volatile user channel name: Acceleration
Data type: 16 bits (unsigned)
Unit exponent: -4
Unit rad (USB code 0x12)

Channel 3:
Name: Azimuth [rad]
Persistent user channel name: Angle from Z axis
Volatile user channel name: Angle from Z axis
Data type: 16 bits (unsigned)
Unit exponent: -4
Unit rad (USB code 0x12)

Frame Number [s]: 2003x10e-3
Acceleration [m/s2]: 9717x10e-3
Zenith [rad]: 37x10e-4
Azimuth [rad]: 31416x10e-4

Frame Number [s]: 1954x10e-3
Acceleration [m/s2]: 9768x10e-3
Zenith [rad]: 117x10e-4
Azimuth [rad]: 32660x10e-4

Frame Number [s]: 1907x10e-3
Acceleration [m/s2]: 9717x10e-3
Zenith [rad]: 30x10e-4
Azimuth [rad]: 25535x10e-4


Im Endeffekt geht es um die Messwerte, die in den letzten 3 Codeblocks ausgegeben werden:


Zenith [rad]: 30x10e-4
Azimuth [rad]: 25535x10e-4


Diese möchte ich umrechnen, um die Drehung um die Y-(oder X-)Achse zu bestimmen.

Cysign
19.03.2013, 07:37
So, ich bin nun endlich auf die Begriffe gestoßen, die mir weiterhelfen. Ich habe sphärische (Kugel-) Koordinaten und möchte diese umrechnen in kartesische Koordinaten :)

Dazu habe ich hier die nötige Formel gefunden: http://wwwex.physik.uni-ulm.de/lehre/krm-2008-2009/node56.html

Um die anzuwenden, muss ich zunächst rausfinden, was für ein Datentyp die Werte im C++-Quellcode haben und wie ich diese abgreife.
Dann werden die Koordinaten in kartesische Koordinaten umgerechnet und normiert.
Und dann wiederum hab ich endlich die Form der Koordinaten, die ich an meinen bieherigen Programmcode andocken kann.

Ich mach mich dann mal ran und hoffe, dass das so richtig ist ;)