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. |