AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Orientationsensor, Floatanimation

Ein Thema von derseitzer · begonnen am 10. Mai 2017 · letzter Beitrag vom 17. Mai 2017
Antwort Antwort
derseitzer

Registriert seit: 12. Okt 2016
235 Beiträge
 
Delphi 10 Seattle Professional
 
#1

Orientationsensor, Floatanimation

  Alt 10. Mai 2017, 16:38
Hey Leute, hatte schonmal hier geschrieben,aber nach 4 Seiten im Forum fange ich lieber nochmal an
Ich drehe eine TSphere mithilfe des Orientationsensors.(z.B. Orientationsensor.sensor.HeadingX)
Ich übergebe mithilfe eines Timers diese Werte entweder an eine TFloatAnimation die dann den TSphere.Rotationangle verändert.

Probleme: Wenn das Handy eigentlich nicht bewegt wird, bewegt sich eben trotzdem alles hin und her (liegt sehr wahrscheinlich am Sensor).

Kann mir jemand einen besseren Sensor vorschlagen den ich benutzen könnte? Mit dem Motionsensor habe ich es auch versucht aber mein Handy hat nur 0 zurückgegeben..
Hat vielleicht jemand schon mit so etwas zutun gehabt und kann mir ein Beispiel oder Tipp geben, damit sich meine Tsphere fließend und nicht ruckelnd bewegt (obwohl das handy still gehalten wird und sich alles erst auspendeln muss)?

P.S. habe ein S7 Edge

Geändert von derseitzer (10. Mai 2017 um 17:33 Uhr)
  Mit Zitat antworten Zitat
Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
719 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Orientationsensor, Floatanimation

  Alt 11. Mai 2017, 16:06
Wie im anderen Thread erwähnt: Geh in die System.Android.Sensors.pas und setze einen Breakpoint bei function TNativeSensor.LastValue: ASensorEvent;. Dann siehst du, was alles an Events ankommt. (Siehe auch die anderen Posts mit Hinweis auf das Embarcadero Beispiel Programm, welches dir alle Sensoren deines Geräts auflistet.)

Gut nutzbar sind alle Vektoren welche nicht schief zu unserem Standort zeigen. Der Sensor, welche dir einen Vektor auf "magnetisch Nord" zurückgibt ist keine gute Wahl (zeigt schief zu unserer Ebene; Umrechnen ist angesagt). Der Schwerkraftsensor zeigt senkrecht nach unten und ist eine gute Wahl.

Das Ruckeln kannst du (siehe deine andere Frage) mit Glättung/Regression verhindern oder zumindest vermindern.
Glättung/Regression zum Beispiel bei Wikipedia. Falls du Maple oder Mathematica hast, dann kannst du mit diesen Paketen rumspielen.

Eine sehr, sehr einfache Glättung ist zum Beispiel:

Wert(neu) := 1/(n+1)*(Messwert + n*Wert) wobei für kleine n der Wert natürlich rascher in Richtung Messwerte läuft, aber dafür anfälliger ist für "Schwankungen/Ruckeln".

Du könntest auch lineare Regression verwenden. Du würdest dabei zum Beispiel die letzten 10 Messwerte betrachten und eine Gerade g:y=ax+b suchen, für welche die 10 Messwerte möglichst nahe* bei g liegen.
[*nahe=Du forderst zum Beispiel, dass die Summe über alle Quadrate von (Messwert(x)-g(x)) minimal sein soll.]

Nach dem Glätten:
Du kannst zusätzlich einen Wert c definieren, welcher bestimmt, ob du den neuen geglätteten Wert w ausgibst, oder den zuletzt ausgegebenen Wert v stehen lässt: Wenn abs(w-v) < c, dann lässt du v stehen. [Deine Kugel würde sich also nicht bewegen, solange die neuen Glättungswerte maximal c vom momentanen angezeigten Wert abweichen.]
(Du musst dir aber bewusst sein, dass der angezeigte Wert dann jeweils maximal c vom "effektiven" Wert abweichen kann. Du könntest hier leicht ein "Feinjustieren" einbauen, wenn du das benötigst.)


So könntest du mittels linearer Regression aus IN Messwert den OUT Anzeigewert ermitteln.

Delphi-Quellcode:
 type
    TGlaetten = class // Lineare Regression
      private
        FMesswerteAnzahl : integer;
        FMesswerte : array of double;
        FZeitStempel : array of TDateTime;
        FAusgabeWert : double;
        FBand : double;
      public
        Constructor Create( MesswerteAnzahl : integer; Band : double );
        function wert( neuerwert : double ) : double;
    end;

var glaettenX, glaettenY, glaettenZ: TGlaetten;


constructor TGlaetten.Create( MesswerteAnzahl : integer; Band : double );
begin
  FBand := Band;
  FMesswerteAnzahl := MesswerteAnzahl;
  setlength( FMessWerte, FMesswerteAnzahl );
  setlength( FZeitStempel, FMesswerteAnzahl );
end;


function TGlaetten.wert(neuerwert: Double) : double;
var anzahlmesswerte, imband, i : integer;
    wert_regression, b1, b2, sumx, sumy, sumxx, sumxy, x, y, glw, sum : double;

    // Infos zum Beispiel auf: https://de.wikipedia.org/wiki/Lineare_Regression

begin
  if ( length( FMessWerte ) = FMesswerteAnzahl ) then
  begin
    Move( FZeitStempel[1], FZeitStempel[0],sizeof(double)*(FMesswerteAnzahl-1));
    Move( FMessWerte[1], FMessWerte[0],sizeof(double)*(FMesswerteAnzahl-1));

    

    FMessWerte[ FMesswerteAnzahl-1 ] := neuerwert;
    FZeitStempel[ FMesswerteAnzahl-1 ] := now;

    sumxy := 0;
    sumxx := 0;
    sumx := 0;
    sumy := 0;

    for i := 0 to FMesswerteAnzahl-1 do
    begin
      x := ( FZeitStempel[i] - FZeitStempel[0] )*24*60*60*10;
      y := FMesswerte[i];
      sumxy := sumxy + x*y;
      sumxx := sumxx + x*x;

      sumx := sumx + x;
      sumy := sumy + y;
    end;

    // y = b1 + b2x
    b2 := ( FMesswerteAnzahl*sumxy - sumx*sumy )/( FMesswerteAnzahl*sumxx - sumx*sumx );
    b1 := ( sumxx*sumy - sumx*sumxy )/( FMesswerteAnzahl*sumxx - sumx*sumx );

    x := ( FZeitStempel[FMesswerteAnzahl-1] - FZeitStempel[0] )*24*60*60*10;
    wert_regression := b1 + b2*x;

    if abs( FAusgabeWert - wert_regression ) > FBand then FAusgabeWert := wert_regression;
  end;
  Result := FAusgabeWert;
end;


Zum Beispiel im FormCreate:
10 = du willst die letzten 10 Messwerte beachten für die lineare Regression
2 = wenn der zuletzt ausgegebene Wert und der neu errechnete Wert näher als 2 beieinander liegen, dann soll TGlaetten.wert(.) den bisherigen Wert zurückgeben.

Delphi-Quellcode:
procedure TOrientationSensorForm.FormCreate(Sender: TObject);
begin
  glaettenX := Tglaetten.Create( 10, 2 );
  glaettenY := Tglaetten.Create( 10, 2 );
  glaettenZ := Tglaetten.Create( 10, 2 );
end;

Zum Beispiel Tilt glätten:
Du übergibst IN Sensorwert und erhältst OUT den anzuzeigenden Wert.

Delphi-Quellcode:
...
  lbTiltX.Text := floattostr(glaettenX.wert(OrientationSensor1.Sensor.TiltX));
  lbTiltY.Text := floattostr(glaettenY.wert(OrientationSensor1.Sensor.Tilty));
  lbTiltZ.Text := floattostr(glaettenZ.wert(OrientationSensor1.Sensor.Tiltz));
...
Michael Gasser

Geändert von Michael II (11. Mai 2017 um 18:27 Uhr)
  Mit Zitat antworten Zitat
derseitzer

Registriert seit: 12. Okt 2016
235 Beiträge
 
Delphi 10 Seattle Professional
 
#3

AW: Orientationsensor, Floatanimation

  Alt 17. Mai 2017, 14:31
Danke dir Michael!!! habe alles soweit verstanden und werde es probieren nur verstehe ich nicht was du mit der system.android.sensors.pas meinst.. wo sollte ich die finden?
Wie ich den Schwerkraftsensor bei Delphi benutzen kann weiß ich nicht genau.. ich weiß nur das ich diesen Orientationsensor und den Motionsensor verwenden kann.. eventuell ist da dann ein befehl den ich noch suchen muss.. da werde ich mich nochmal genauer informieren.
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 23:50 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