AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Kompass 2D

Ein Thema von schand99 · begonnen am 19. Jan 2015 · letzter Beitrag vom 21. Jan 2015
Antwort Antwort
Seite 1 von 2  1 2      
schand99

Registriert seit: 7. Nov 2013
Ort: Südtirol
43 Beiträge
 
Delphi XE8 Enterprise
 
#1

Kompass 2D

  Alt 19. Jan 2015, 15:32
Hallo,

versuche zur Zeit einen Kompass für mein Handy zu programmieren, dazu verwende ich die Heading X/Y/Z Werte des integrierten Magnetsensors. Leider habe ich aber große Schwierigkeiten den 3D-Vektor so auf das Handy-Display umzurechnen, dass dieser auch bei schräger Haltung des Gerätes noch nach Norden zeigt. Meine App funktioniert nur wenn das Smartphone schön flach auf dem Tisch liegt
Hätte jemand einen Tipp wie man das lösen könnte?

Danke,
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#2

AW: Kompass 2D

  Alt 19. Jan 2015, 16:04
Das sollte eigentlich erst dann ein Problem sein, wenn das Handy exakt senkrecht gehalten wird - bzw. so, dass der Vektor genau "durch" das Handy geht. Das lässt sich dann nicht mehr sinnvoll darstellen. Ansonsten musst du doch einfach nur den Vektor nehmen, und ihn in die XZ-Ebene projezieren (angenommen Nord=Z und X=Bildschirm-X), und ggf. noch auf eine fixe Länge skalieren fürs Zeichnen. Die Projektion ist da denkbar simpel: Einfach die Y-Komponente weg schmeissen, und Z dafür in den 2D Vektor einsetzen.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
schand99

Registriert seit: 7. Nov 2013
Ort: Südtirol
43 Beiträge
 
Delphi XE8 Enterprise
 
#3

AW: Kompass 2D

  Alt 19. Jan 2015, 16:19
Wenn Du das so schreibst klingt das einfach, nur leider bekomme ich es nicht hin.

Den Quellcode für 2D hab ich hier im Forum gefunden und etwas angepasst. Muss aber leider einräumen dass ich es nicht schaffe das HeadinZ so einzubauen dass ein Pfeil am Display halbwegs brauchbar nach Norden zeigt.

procedure GetWinkel()
begin
if Kompass.Sensor.Started = True then
Begin
if (Kompass.Sensor.HeadingY > 0) then
Winkel := 90 - arcTan(Kompass.Sensor.HeadingX / Kompass.Sensor.HeadingY) * 180 / PI
else if (Kompass.Sensor.HeadingY < 0) then
Winkel := 270 - arcTan(Kompass.Sensor.HeadingX / Kompass.Sensor.HeadingY) * 180 / PI
else if (Kompass.Sensor.HeadingY = 0) and (Kompass.Sensor.HeadingX < 0) then
Winkel := 180
else if (Kompass.Sensor.HeadingY = 0) and (Kompass.Sensor.HeadingX > 0) then
Winkel := 0;
end;
Winkel:=Abs(Winkel-360);
End;
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#4

AW: Kompass 2D

  Alt 19. Jan 2015, 20:54
Für sowas gibt es eigentlich die arctan2 Funktion.
Und zu dem Zeitpunkt, den du da hast, ist es bereits ein 2D-Vektor.

Möglicherweise ist auch der Kompasssensor nicht gut kalibriert, der kann sich durchaus "von selbst" verstellen und muss dann ggf. wieder kalibriert werden. Insbesondere wenn er mal an einem Magnetfeld war oder Eisenstücke in der Nähe sind.
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#5

AW: Kompass 2D

  Alt 19. Jan 2015, 22:15
Wie zeichnest du denn?

Ich würde empfehlen, mit Vektoren zu arbeiten und Winkel, wo es nur geht, komplett zu vermeiden. In Programmen mit Winkeln zu arbeiten ist immer sehr umständlich und außerdem langsam. Dazu kommen noch Probleme wie 360° = 0°. Meine wärmste Empfehlung: Lerne Vektorrechnung (Analytische Geometrie)! Kommt leider in der Schule viel zu kurz bzw. erst ziemlich spät. Aber mein Leben ist dadurch so viel einfacher geworden...

Um mal am Kompass-Beispiel zu zeigen: Ich nehme mal an, um den Zeiger zu zeichnen hast du irgendwo sowas stehen wie LineTo(Mitte.X + cos(Winkel)*Nadellänge, Mitte.Y + sin(Winkel*Nadellänge) . Das ist im Grunde von hinten durch die Brust ins Auge, weil du wahrscheinlich erst aus einem Vektor den Winkel gemacht hast, nur um dann den Winkel mit sin/cos wieder in einen Vektor zurückzuverwandeln.

Dabei braucht man den Winkel gar nicht. Sagen wir dein (2D-)Vektor heißt V und der zugehörige Winkel φ. Es gilt (immer): V.X = cos(φ) * Vektorlänge und V.Y = sin(φ) * Vektorlänge. Wenn du jetzt einen Vektor mit der Länge 1 haben willst, der in die gleiche Richtung zeigt, dann kannst du das ganz einfach, indem du die V.X und V.Y jeweils durch die Vektorlänge (Pythagoras: Länge = Sqrt(V.X² + V.Y²)) dividierst. Was kommt nun dabei raus? Klar: Ein neuer Vektor V’ mit V’.X = cos(φ) und V’.Y = sin(φ) (den Schritt nennt man übrigens auch normalisieren, und das Ergebnis ist ein sogenannter Einheitsvektor). Ja, und damit ist es jetzt ganz einfach, die Kompassnadel zu zeichnen: LineTo(Mitte.X + V’.X*Nadellänge, Mitte.Y + V’.Y*Nadellänge . Und wir haben kein einziges mal Sinus, Cosinus oder Arctan gebraucht. Deine ganze GetWinkel-Funktion wird überflüssig.

Jetzt gibt es natürlich noch ein kleines Problem: Der Vektor von deinem Sensor hat 3 Dimensionen. Du kannst aber leicht deinen gewünschten 2D-Vektor daraus berechnen, indem du eine der Komponenten X, Y oder Z einfach weglässt. Das hat Medium schon beschrieben.
  Mit Zitat antworten Zitat
schand99

Registriert seit: 7. Nov 2013
Ort: Südtirol
43 Beiträge
 
Delphi XE8 Enterprise
 
#6

AW: Kompass 2D

  Alt 20. Jan 2015, 15:50
Muss dem was "Namenloser" geschrieben hat zustimmen. Einen Vektor erst in einen Winkel umrechnen und nachher zum Zeichnen des Vektors dann wieder aus dem Winkel einen Vektor berechnen wäre tatsächlich ein unnötiger Umweg.
Leider benötige ich den Winkel für nachfolgende Berechnungen (Geocaching, möchte mir selbst eine App bauen die mir Richtung und Abstand zum Zielort anzeigt).
Aber dafür müsste ich es erstmal schaffen eine Kompassnadel zu zeichnen die auch halbwegs brauchbar nach Norden zeigt. Und da liegt das Problem, ich schaffe es nicht aus den Werten HeadingX, -Y und -Z eine brauchbare Kompassnadel zu zeichnen. Das simple Weglassen eines der Heading-Werte ist leider nicht die Lösung.
Die Heading-Werte ergeben zwar einen Vektor in der Einheit Tesla, allerdings blicke ich noch nicht genau durch wie die Werte zu interpretieren sind. Wie bereits geschrieben funktioniert der Kompass wenn das Smartphone flach auf dem Tisch liegt. Wird es aber um eine Achse leicht geneigt, dann stimmt die Richtung nicht mehr.
Es wäre naheliegend einfach HeadingZ zu ignorieren. Aber HeadingY eiert so seltsam rum dass mir so schön langsam die Lust am Basteln vergeht
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#7

AW: Kompass 2D

  Alt 20. Jan 2015, 16:06
Ohne das vor sich zu sehen, finde ich es gerade etwas schwierig sich genau vorzustellen was da wo wie schief laufen könnte. Hast du ggf. eine Möglichkeit, ein Video von der bisherigen Nadel auf deinem Handy zu machen, wie du es ein wenig bewegst? (So, dass man erkennen kann wie du es bewegst.) Auf Youtube oder so am besten.

Weisst du 100%ig welche der 3 Achsen Nord/Süd bezeichnet? Nicht, dass du genau diese mit Z weggelassen hast. Das würde das Herumeiern vielleicht erklären können. Und wenn alle Stricke reißen: Es gibt auch durchaus Handys, deren Magnetsensor nicht ganz so pralle ist. Hast du schon mal eine andere Kompass App probiert? Können die das besser mit deinem Handy?
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#8

AW: Kompass 2D

  Alt 20. Jan 2015, 16:31
Müsste eigentlich so funktionieren meiner Meinung nach. Könnte mir höchstens vorstellen, dass der Heading-Vektor entgegen unserer Annahme nicht relativ zum Display ist, sondern die Neigung des Displays schon herausgerechnet ist.
  Mit Zitat antworten Zitat
schand99

Registriert seit: 7. Nov 2013
Ort: Südtirol
43 Beiträge
 
Delphi XE8 Enterprise
 
#9

AW: Kompass 2D

  Alt 20. Jan 2015, 16:51
Hier ein mega Film: http://80.247.70.136/downloads/cmps.zip
Die App läuft auf einem Samsung Galaxy S3 mini (und ruckelt^^) genauso schräg wie auf einem Sony Xperia Z3 Compact.
Wäre für jeden Tipp dankbar.

Berechne jetzt so, die Variablen HeadX, -Y und -Z sind so deklariert dass sie auch in anderen Funktionen sichtbar sind.

procedure TStartup.Timer2Timer(Sender: TObject);
Var
Vek:Single;
begin
if Kompass.Sensor.Started = True then
Begin
HeadX := Kompass.Sensor.HeadingX;
HeadY := Kompass.Sensor.HeadingY;
HeadZ := Kompass.Sensor.HeadingZ;
Vek := Sqrt(Power(HeadX,2) + Power(HeadY,2));
HeadX:=HeadX/Vek;
HeadY:=HeadY/Vek;
end;
End;

Irre simpel da mit HeadX und HeadY gezeichnet wird, aber leider sehr stark lageabhängig und somit nutzlos.
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#10

AW: Kompass 2D

  Alt 20. Jan 2015, 16:59
Dem Video nach würde ich wirklich annehmen, dass Z die Nord/Süd-Achse ist. Zumindest wenn mich mein räumliches Vorstellungsvermögen (und das gedankliche de-projezieren ) nicht völlig verlassen hat. Probier doch einfach mal, was daraus wird wenn du Y oder X weg lässt.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:07 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz