Skip to content
This repository was archived by the owner on May 15, 2024. It is now read-only.

Commit 56bc8dc

Browse files
MrnikbobjeffRedth
authored andcommitted
GH-337 Android Low Pass Filter (#354)
* Implemented low pass filter as requested by issue 337 * Added value to sample page. * Updated docs for ApplyLowPassFilter * Enabled ApplyLowPassFilter Switch on Android, disabled on all other platforms * Moved LowPassFilter to shared, removed unnecessary usings. * Updated Docs
1 parent 0a61964 commit 56bc8dc

File tree

10 files changed

+88
-1
lines changed

10 files changed

+88
-1
lines changed

Samples/Samples/View/CompassPage.xaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
<StackLayout>
1212
<Label Text="Monitor compass for changes." FontAttributes="Bold" Margin="12" />
1313

14+
<Switch IsToggled="{Binding CompassApplyLowPassFilter}" >
15+
<Switch.IsVisible>
16+
<OnPlatform x:TypeArguments="x:Boolean" Android="True" Default="False"/>
17+
</Switch.IsVisible>
18+
</Switch>
19+
1420
<ScrollView>
1521
<Grid Padding="12,0,12,12">
1622
<Grid.RowDefinitions>

Samples/Samples/ViewModel/CompassViewModel.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class CompassViewModel : BaseViewModel
1010
{
1111
bool compass1IsActive;
1212
bool compass2IsActive;
13+
bool compassApplyLowPassFilter;
1314
double compass1;
1415
double compass2;
1516
int speed1 = 2;
@@ -43,6 +44,16 @@ public bool Compass2IsActive
4344
set => SetProperty(ref compass2IsActive, value);
4445
}
4546

47+
public bool CompassApplyLowPassFilter
48+
{
49+
get => compassApplyLowPassFilter;
50+
set
51+
{
52+
SetProperty(ref compassApplyLowPassFilter, value);
53+
Compass.ApplyLowPassFilter = value;
54+
}
55+
}
56+
4657
public double Compass1
4758
{
4859
get => compass1;

Xamarin.Essentials/Compass/Compass.android.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ internal static void PlatformStop()
5454

5555
class SensorListener : Java.Lang.Object, ISensorEventListener, IDisposable
5656
{
57+
LowPassFilter filter = new LowPassFilter();
5758
float[] lastAccelerometer = new float[3];
5859
float[] lastMagnetometer = new float[3];
5960
bool lastAccelerometerSet;
@@ -92,6 +93,11 @@ void ISensorEventListener.OnSensorChanged(SensorEvent e)
9293
SensorManager.GetRotationMatrix(r, null, lastAccelerometer, lastMagnetometer);
9394
SensorManager.GetOrientation(r, orientation);
9495
var azimuthInRadians = orientation[0];
96+
if (Compass.ApplyLowPassFilter)
97+
{
98+
filter.Add(azimuthInRadians);
99+
azimuthInRadians = filter.Average();
100+
}
95101
var azimuthInDegress = (Java.Lang.Math.ToDegrees(azimuthInRadians) + 360.0) % 360.0;
96102

97103
var data = new CompassData(azimuthInDegress);

Xamarin.Essentials/Compass/Compass.shared.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.Threading;
32

43
namespace Xamarin.Essentials
54
{
@@ -11,6 +10,8 @@ public static partial class Compass
1110

1211
public static bool IsMonitoring { get; private set; }
1312

13+
public static bool ApplyLowPassFilter { get; set; }
14+
1415
public static void Start(SensorSpeed sensorSpeed)
1516
{
1617
if (!IsSupported)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace Xamarin.Essentials
5+
{
6+
class LowPassFilter
7+
{
8+
const int length = 10;
9+
10+
float sin;
11+
float cos;
12+
Queue<float> history = new Queue<float>(length);
13+
14+
internal void Add(float radians)
15+
{
16+
sin += (float)Math.Sin(radians);
17+
18+
cos += (float)Math.Cos(radians);
19+
20+
history.Enqueue(radians);
21+
22+
if (history.Count > length)
23+
{
24+
var old = history.Dequeue();
25+
26+
sin -= (float)Math.Sin(old);
27+
28+
cos -= (float)Math.Cos(old);
29+
}
30+
}
31+
32+
internal float Average()
33+
{
34+
var size = history.Count;
35+
36+
return (float)Math.Atan2(sin / size, cos / size);
37+
}
38+
}
39+
}

docs/en/FrameworksIndex/xamarin-essentials-android.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
<Member Id="E:Xamarin.Essentials.Compass.ReadingChanged" />
6868
<Member Id="M:Xamarin.Essentials.Compass.Start(Xamarin.Essentials.SensorSpeed)" />
6969
<Member Id="M:Xamarin.Essentials.Compass.Stop" />
70+
<Member Id="P:Xamarin.Essentials.Compass.ApplyLowPassFilter" />
7071
<Member Id="P:Xamarin.Essentials.Compass.IsMonitoring" />
7172
</Type>
7273
<Type Name="Xamarin.Essentials.CompassChangedEventArgs" Id="T:Xamarin.Essentials.CompassChangedEventArgs">

docs/en/FrameworksIndex/xamarin-essentials-ios.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
<Member Id="E:Xamarin.Essentials.Compass.ReadingChanged" />
6868
<Member Id="M:Xamarin.Essentials.Compass.Start(Xamarin.Essentials.SensorSpeed)" />
6969
<Member Id="M:Xamarin.Essentials.Compass.Stop" />
70+
<Member Id="P:Xamarin.Essentials.Compass.ApplyLowPassFilter" />
7071
<Member Id="P:Xamarin.Essentials.Compass.IsMonitoring" />
7172
<Member Id="P:Xamarin.Essentials.Compass.ShouldDisplayHeadingCalibration" />
7273
</Type>

docs/en/FrameworksIndex/xamarin-essentials-uwp.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
<Member Id="E:Xamarin.Essentials.Compass.ReadingChanged" />
6868
<Member Id="M:Xamarin.Essentials.Compass.Start(Xamarin.Essentials.SensorSpeed)" />
6969
<Member Id="M:Xamarin.Essentials.Compass.Stop" />
70+
<Member Id="P:Xamarin.Essentials.Compass.ApplyLowPassFilter" />
7071
<Member Id="P:Xamarin.Essentials.Compass.IsMonitoring" />
7172
</Type>
7273
<Type Name="Xamarin.Essentials.CompassChangedEventArgs" Id="T:Xamarin.Essentials.CompassChangedEventArgs">

docs/en/FrameworksIndex/xamarin-essentials.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
<Member Id="E:Xamarin.Essentials.Compass.ReadingChanged" />
6868
<Member Id="M:Xamarin.Essentials.Compass.Start(Xamarin.Essentials.SensorSpeed)" />
6969
<Member Id="M:Xamarin.Essentials.Compass.Stop" />
70+
<Member Id="P:Xamarin.Essentials.Compass.ApplyLowPassFilter" />
7071
<Member Id="P:Xamarin.Essentials.Compass.IsMonitoring" />
7172
</Type>
7273
<Type Name="Xamarin.Essentials.CompassChangedEventArgs" Id="T:Xamarin.Essentials.CompassChangedEventArgs">

docs/en/Xamarin.Essentials/Compass.xml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,26 @@
1717
</remarks>
1818
</Docs>
1919
<Members>
20+
<Member MemberName="ApplyLowPassFilter">
21+
<MemberSignature Language="C#" Value="public static bool ApplyLowPassFilter { get; set; }" />
22+
<MemberSignature Language="ILAsm" Value=".property bool ApplyLowPassFilter" />
23+
<MemberSignature Language="DocId" Value="P:Xamarin.Essentials.Compass.ApplyLowPassFilter" />
24+
<MemberType>Property</MemberType>
25+
<AssemblyInfo>
26+
<AssemblyName>Xamarin.Essentials</AssemblyName>
27+
<AssemblyVersion>1.0.0.0</AssemblyVersion>
28+
</AssemblyInfo>
29+
<ReturnValue>
30+
<ReturnType>System.Boolean</ReturnType>
31+
</ReturnValue>
32+
<Docs>
33+
<summary>Applies a moving average filter on the Android implementation. Unused on other platforms</summary>
34+
<value>If a low pass filter is applied</value>
35+
<remarks>
36+
<para></para>
37+
</remarks>
38+
</Docs>
39+
</Member>
2040
<Member MemberName="IsMonitoring">
2141
<MemberSignature Language="C#" Value="public static bool IsMonitoring { get; }" />
2242
<MemberSignature Language="ILAsm" Value=".property bool IsMonitoring" />

0 commit comments

Comments
 (0)