IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Voir le flux RSS

Gouyon

[Actualité] Application Boussole pour Android

Noter ce billet
par , 05/06/2026 à 14h14 (1156 Affichages)
Pour valider les résultats d'une autre application, j'ai eu besoin d'une boussole. Dans un premier temps je me suis dis "bon il doit y en avoir un paquet sur le playstore" et puis je me suis dis finalement c'est une opportunité de développé quelque chose et de voir comment utiliser les capteurs d'un téléphone.

Alors inutile de dire que le démarrage à été difficile. La documentation est très succincte voir pas à jour et parfois complètement à coté de la plaque. Mr Embarcadero vos produits sont très bon mais pitié faite un gros effort sur la documentation. Finalement j'ai été sauvé par le livre Expert Delphi de Pawel Glowacki qui trainait dans ma bibliothèque. Dans lequel il y a tout un chapitre consacré aux capteur et qui est très explicite.

Donc sur ma fiche j'ai déposé les composants suivants:
  • un TOrientationSensor pour accès au capteur d'orientation
  • un TMotionSensor pour avoir l'attitude du téléphone dans l'espace. Ce n'est pas nécessaire au premier ordre mais indispensable si on veut des résultats corrects quelque soit l'orientation du téléphone.
  • un TTimer pour cadencer le rafraichissement de la boussole
  • un TBoussole qui est un composant graphique que j'ai développé voir mon billet Composants d'affichage FMX pour Delphi et qui va afficher la direction.


Et voici ce que ça donne

Nom : boussole1.JPG
Affichages : 54
Taille : 60,1 Ko

Et voici le code

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
unit BoussoleMainFrm;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, System.Sensors, FMX.Objects, Boussole,
  System.Sensors.Components, FMX.Layouts, FMX.Controls.Presentation, FMX.StdCtrls;

type
  TBoussoleForm = class(TForm)
    laBoussole: TOrientationSensor;
    visuBoussole: TBoussole;
    TimerBsl: TTimer;
    Path1: TPath;
    Layout1: TLayout;
    Accelero: TMotionSensor;
    Layout2: TLayout;
    Label4: TLabel;
    Label5: TLabel;
    SwBrtMoy: TSwitch;
    procedure majDirection(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure SwBrtMoySwitch(Sender: TObject);
  private
    { Déclarations privées }
    nb: integer;
    mzs, mxs, mys, axs, ays, azs: array [0 .. 4] of double;
  public
    { Déclarations publiques }
  end;

var
  BoussoleForm: TBoussoleForm;

implementation

uses math;
{$R *.fmx}

procedure TBoussoleForm.FormCreate(Sender: TObject);
begin
  nb := 0;
end;

procedure TBoussoleForm.majDirection(Sender: TObject);
var
  lmz, lmx, lmy, lax, lay, laz: double;
  lalpha: double;
  xh, yh, pitch, roll: double;
  I: integer;
begin
  // ATTENTION Si my est négatif quant on pointe vers le nord, il faut inverser mx et my
  lmx := laBoussole.Sensor.HeadingX;
  lmy := laBoussole.Sensor.HeadingY;
  lmz := laBoussole.Sensor.Headingz;
  // Calcul des angles de roulis et tangage
  lax := Accelero.Sensor.AccelerationX;
  lay := Accelero.Sensor.AccelerationY;
  // ATTENTION selon la convention de l'OS,
  // la sortie du capteur doit être inversée sinon le nord est au sud et vice versa
  laz := -Accelero.Sensor.AccelerationZ;

  if SwBrtMoy.IsChecked then
  begin
    if nb = 5 then
    begin
      for I := 0 to 3 do
      begin
        mxs[I] := mxs[I + 1];
        mys[I] := mys[I + 1];
        mzs[I] := mzs[I + 1];
        axs[I] := axs[I + 1];
        ays[I] := ays[I + 1];
        azs[I] := azs[I + 1];
      end;
    end
    else
      inc(nb);
    mxs[nb - 1] := lmx;
    mys[nb - 1] := lmy;
    mzs[nb - 1] := lmz;
    axs[nb - 1] := lax;
    ays[nb - 1] := lay;
    azs[nb - 1] := laz;

    lmx := 0;
    lmy := 0;
    lmz := 0;
    lax := 0;
    lay := 0;
    laz := 0;
    for I := 0 to nb - 1 do
    begin
      lmx := lmx + mxs[I];
      lmy := lmy + mys[I];
      lmz := lmz + mzs[I];
      lax := lax + axs[I];
      lay := lay + ays[I];
      laz := laz + azs[I];
    end;
    lmx := lmx / nb;
    lmy := lmy / nb;
    lmz := lmz / nb;
    lax := lax / nb;
    lay := lay / nb;
    laz := laz / nb;
  end;

  pitch := arctan2(-lax, sqrt(lay * lay + laz * laz));
  roll := arctan2(lay, laz);
  xh := lmx * cos(pitch) + lmz * sin(pitch);
  yh := lmx * sin(roll) * sin(pitch) + lmy * cos(roll) - lmz * sin(roll) * cos(pitch);
  lalpha := arctan2(-xh, yh);
  if lalpha < 0 then
    lalpha := lalpha + 2 * pi;
  visuBoussole.Valeur := lalpha / pi * 180;
end;

procedure TBoussoleForm.SwBrtMoySwitch(Sender: TObject);
begin
  nb := 0;
end;

end.
Quelque précisions

Le code aurait pu être beaucoup plus simple si mon téléphone avait eu accès à ces propriétes (MagHeading, TrueHeading, CompMagHeading, CompTrueHeading) du capteur d'orientation.
Malheureusement ce n'est pas le cas donc il a fallu écrire quelque chose de plus complexe.

Après quelques recherche j'ai trouvé que

  • HeadingX correspond à l'axe horizontal gauche/droite (pointe vers la droite de l'écran)
  • HeadingY correspond à l'axe horizontal bas/haut (pointe vers le haut de l'écran)
  • HeadingZ correspond à l'axe vertical (pointe vers l'extérieur de l'écran)


A partir de là en utilisant HeadingX et HeadingY on peut retrouver la direction grâce à la fonction arctan2. Ceci fonctionne bien si le téléphone est à plat sur une surface horizontale. Si ce n'est pas le cas il faut corriger les angles par rapport à l'orientation du téléphone dans l'espace.

Pour ceux que ça intéresse il s'agit de rotation de repère dans l'espace. On parle assez souvent d'angles d'Euler vous trouverez pas mal de documentation sur le sujet (Exemple)

Enfin afin d'augmenter un peu la précision j'ai ajouté la possibilité de moyenner les résultats pour avoir une mesure plus précise. ATTENTION c'est à n'utiliser que quand le téléphone est statique sinon les résultats ne sont pas terribles.

Envoyer le billet « Application Boussole pour Android » dans le blog Viadeo Envoyer le billet « Application Boussole pour Android » dans le blog Twitter Envoyer le billet « Application Boussole pour Android » dans le blog Google Envoyer le billet « Application Boussole pour Android » dans le blog Facebook Envoyer le billet « Application Boussole pour Android » dans le blog Digg Envoyer le billet « Application Boussole pour Android » dans le blog Delicious Envoyer le billet « Application Boussole pour Android » dans le blog MySpace Envoyer le billet « Application Boussole pour Android » dans le blog Yahoo

Mis à jour 06/06/2026 à 08h41 par Gouyon

Catégories
Programmation

Commentaires