This repository has been archived by the owner on May 1, 2024. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* Add Magnetometer code and samples * Add Tests for Magnetomoter * Add docs and adjust time intervals to match Android * Update magnetometer to use events. * Ensure monitor check is added. * Cleanup magnetomter vased on feedback * Tweak data update on ios * Add accelerometer and gyroscope. * Update tests * Update docs with units. * Cleanup tests * Gyro calibrated only . * Add all sensors test page. Ensure Android sensors work across stops * Use sensor name instead of ID (was api 24+) * Check for null on sensors * Update IsMonitoring to match compass * Make @Redth feel better about IsMonitoring * Cleanup try/catch for @Redth
- Loading branch information
1 parent
8c69fa1
commit 267edd1
Showing
53 changed files
with
2,698 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
using Microsoft.Caboodle; | ||
using Xunit; | ||
|
||
namespace Caboodle.Tests | ||
{ | ||
public class Accelerometer_Tests | ||
{ | ||
public Accelerometer_Tests() | ||
{ | ||
Accelerometer.Stop(); | ||
} | ||
|
||
[Fact] | ||
public void IsSupported_On_NetStandard() => | ||
Assert.Throws<NotImplementedInReferenceAssemblyException>(() => Accelerometer.IsSupported); | ||
|
||
[Fact] | ||
public void Monitor_On_NetStandard() => | ||
Assert.Throws<NotImplementedInReferenceAssemblyException>(() => Accelerometer.Start(SensorSpeed.Normal)); | ||
|
||
[Fact] | ||
public void IsMonitoring_Default_On_NetStandard() => | ||
Assert.False(Accelerometer.IsMonitoring); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
using Microsoft.Caboodle; | ||
using Xunit; | ||
|
||
namespace Caboodle.Tests | ||
{ | ||
public class Gyroscope_Tests | ||
{ | ||
public Gyroscope_Tests() | ||
{ | ||
Gyroscope.Stop(); | ||
} | ||
|
||
[Fact] | ||
public void IsSupported_On_NetStandard() => | ||
Assert.Throws<NotImplementedInReferenceAssemblyException>(() => Gyroscope.IsSupported); | ||
|
||
[Fact] | ||
public void Monitor_On_NetStandard() => | ||
Assert.Throws<NotImplementedInReferenceAssemblyException>(() => Gyroscope.Start(SensorSpeed.Normal)); | ||
|
||
[Fact] | ||
public void IsMonitoring_Default_On_NetStandard() => | ||
Assert.False(Gyroscope.IsMonitoring); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
using Microsoft.Caboodle; | ||
using Xunit; | ||
|
||
namespace Caboodle.Tests | ||
{ | ||
public class Magnetometer_Tests | ||
{ | ||
public Magnetometer_Tests() | ||
{ | ||
Magnetometer.Stop(); | ||
} | ||
|
||
[Fact] | ||
public void IsSupported_On_NetStandard() => | ||
Assert.Throws<NotImplementedInReferenceAssemblyException>(() => Magnetometer.IsSupported); | ||
|
||
[Fact] | ||
public void Monitor_On_NetStandard() => | ||
Assert.Throws<NotImplementedInReferenceAssemblyException>(() => Magnetometer.Start(SensorSpeed.Normal)); | ||
|
||
[Fact] | ||
public void IsMonitoring_Default_On_NetStandard() => | ||
Assert.False(Magnetometer.IsMonitoring); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
using Android.Hardware; | ||
using Android.Runtime; | ||
|
||
namespace Microsoft.Caboodle | ||
{ | ||
public static partial class Accelerometer | ||
{ | ||
internal static bool IsSupported => | ||
Platform.SensorManager?.GetDefaultSensor(SensorType.Accelerometer) != null; | ||
|
||
static AccelerometerListener listener; | ||
static Sensor accelerometer; | ||
|
||
internal static void PlatformStart(SensorSpeed sensorSpeed) | ||
{ | ||
var delay = SensorDelay.Normal; | ||
switch (sensorSpeed) | ||
{ | ||
case SensorSpeed.Normal: | ||
delay = SensorDelay.Normal; | ||
break; | ||
case SensorSpeed.Fastest: | ||
delay = SensorDelay.Fastest; | ||
break; | ||
case SensorSpeed.Game: | ||
delay = SensorDelay.Game; | ||
break; | ||
case SensorSpeed.Ui: | ||
delay = SensorDelay.Ui; | ||
break; | ||
} | ||
|
||
listener = new AccelerometerListener(); | ||
accelerometer = Platform.SensorManager.GetDefaultSensor(SensorType.Accelerometer); | ||
Platform.SensorManager.RegisterListener(listener, accelerometer, delay); | ||
} | ||
|
||
internal static void PlatformStop() | ||
{ | ||
if (listener == null || accelerometer == null) | ||
{ | ||
return; | ||
} | ||
|
||
Platform.SensorManager.UnregisterListener(listener, accelerometer); | ||
listener.Dispose(); | ||
listener = null; | ||
} | ||
} | ||
|
||
internal class AccelerometerListener : Java.Lang.Object, ISensorEventListener | ||
{ | ||
public AccelerometerListener() | ||
{ | ||
} | ||
|
||
public void OnAccuracyChanged(Sensor sensor, [GeneratedEnum] SensorStatus accuracy) | ||
{ | ||
} | ||
|
||
public void OnSensorChanged(SensorEvent e) | ||
{ | ||
var data = new AccelerometerData(e.Values[0], e.Values[1], e.Values[2]); | ||
Accelerometer.OnChanged(data); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
using System; | ||
using CoreMotion; | ||
using Foundation; | ||
|
||
namespace Microsoft.Caboodle | ||
{ | ||
public static partial class Accelerometer | ||
{ // Timing intervales to match android sensor speeds in seconds | ||
// https://stackoverflow.com/questions/10044158/android-sensors | ||
internal const double FastestInterval = .02; | ||
internal const double GameInterval = .04; | ||
internal const double UiInterval = .08; | ||
internal const double NormalInterval = .225; | ||
|
||
internal static bool IsSupported => | ||
Platform.MotionManager?.AccelerometerAvailable ?? false; | ||
|
||
internal static void PlatformStart(SensorSpeed sensorSpeed) | ||
{ | ||
var manager = Platform.MotionManager; | ||
switch (sensorSpeed) | ||
{ | ||
case SensorSpeed.Fastest: | ||
manager.AccelerometerUpdateInterval = FastestInterval; | ||
break; | ||
case SensorSpeed.Game: | ||
manager.AccelerometerUpdateInterval = GameInterval; | ||
break; | ||
case SensorSpeed.Normal: | ||
manager.AccelerometerUpdateInterval = NormalInterval; | ||
break; | ||
case SensorSpeed.Ui: | ||
manager.AccelerometerUpdateInterval = UiInterval; | ||
break; | ||
} | ||
|
||
manager.StartAccelerometerUpdates(NSOperationQueue.CurrentQueue, DataUpdated); | ||
} | ||
|
||
static void DataUpdated(CMAccelerometerData data, NSError error) | ||
{ | ||
if (data == null) | ||
return; | ||
|
||
var field = data.Acceleration; | ||
var accelData = new AccelerometerData(field.X, field.Y, field.Z); | ||
OnChanged(accelData); | ||
} | ||
|
||
internal static void PlatformStop() => | ||
Platform.MotionManager?.StopAccelerometerUpdates(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
namespace Microsoft.Caboodle | ||
{ | ||
public static partial class Accelerometer | ||
{ | ||
internal static bool IsSupported => | ||
throw new NotImplementedInReferenceAssemblyException(); | ||
|
||
internal static void PlatformStart(SensorSpeed sensorSpeed) => | ||
throw new NotImplementedInReferenceAssemblyException(); | ||
|
||
internal static void PlatformStop() => | ||
throw new NotImplementedInReferenceAssemblyException(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
using System; | ||
|
||
namespace Microsoft.Caboodle | ||
{ | ||
public static partial class Accelerometer | ||
{ | ||
public static event AccelerometerChangedEventHandler ReadingChanged; | ||
|
||
public static bool IsMonitoring { get; private set; } | ||
|
||
public static void Start(SensorSpeed sensorSpeed) | ||
{ | ||
if (!IsSupported) | ||
{ | ||
throw new FeatureNotSupportedException(); | ||
} | ||
|
||
if (IsMonitoring) | ||
{ | ||
return; | ||
} | ||
|
||
IsMonitoring = true; | ||
|
||
UseSyncContext = sensorSpeed == SensorSpeed.Normal || sensorSpeed == SensorSpeed.Ui; | ||
try | ||
{ | ||
PlatformStart(sensorSpeed); | ||
} | ||
catch | ||
{ | ||
IsMonitoring = false; | ||
throw; | ||
} | ||
} | ||
|
||
public static void Stop() | ||
{ | ||
if (!IsMonitoring) | ||
{ | ||
return; | ||
} | ||
|
||
IsMonitoring = false; | ||
|
||
try | ||
{ | ||
PlatformStop(); | ||
} | ||
catch | ||
{ | ||
IsMonitoring = true; | ||
throw; | ||
} | ||
} | ||
|
||
internal static bool UseSyncContext { get; set; } | ||
|
||
internal static void OnChanged(AccelerometerData reading) | ||
=> OnChanged(new AccelerometerChangedEventArgs(reading)); | ||
|
||
internal static void OnChanged(AccelerometerChangedEventArgs e) | ||
{ | ||
if (ReadingChanged == null) | ||
return; | ||
|
||
if (UseSyncContext) | ||
{ | ||
Platform.BeginInvokeOnMainThread(() => ReadingChanged?.Invoke(e)); | ||
} | ||
else | ||
{ | ||
ReadingChanged?.Invoke(e); | ||
} | ||
} | ||
} | ||
|
||
public delegate void AccelerometerChangedEventHandler(AccelerometerChangedEventArgs e); | ||
|
||
public class AccelerometerChangedEventArgs : EventArgs | ||
{ | ||
internal AccelerometerChangedEventArgs(AccelerometerData reading) => Reading = reading; | ||
|
||
public AccelerometerData Reading { get; } | ||
} | ||
|
||
public struct AccelerometerData | ||
{ | ||
internal AccelerometerData(double x, double y, double z) | ||
{ | ||
AccelerometerX = x; | ||
AccelerometerY = y; | ||
AccelerometerZ = z; | ||
} | ||
|
||
public double AccelerometerX { get; } | ||
|
||
public double AccelerometerY { get; } | ||
|
||
public double AccelerometerZ { get; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
using Windows.Devices.Sensors; | ||
using WindowsAccelerometer = Windows.Devices.Sensors.Accelerometer; | ||
|
||
namespace Microsoft.Caboodle | ||
{ | ||
public static partial class Accelerometer | ||
{ | ||
// Magic numbers from https://docs.microsoft.com/en-us/uwp/api/windows.devices.sensors.compass.reportinterval#Windows_Devices_Sensors_Compass_ReportInterval | ||
internal const uint FastestInterval = 8; | ||
internal const uint GameInterval = 22; | ||
internal const uint NormalInterval = 33; | ||
|
||
static WindowsAccelerometer sensor; | ||
|
||
internal static WindowsAccelerometer DefaultSensor => | ||
WindowsAccelerometer.GetDefault(); | ||
|
||
internal static bool IsSupported => | ||
DefaultSensor != null; | ||
|
||
internal static void PlatformStart(SensorSpeed sensorSpeed) | ||
{ | ||
sensor = DefaultSensor; | ||
var interval = NormalInterval; | ||
switch (sensorSpeed) | ||
{ | ||
case SensorSpeed.Fastest: | ||
interval = FastestInterval; | ||
break; | ||
case SensorSpeed.Game: | ||
interval = GameInterval; | ||
break; | ||
} | ||
|
||
sensor.ReportInterval = sensor.MinimumReportInterval >= interval ? sensor.MinimumReportInterval : interval; | ||
|
||
sensor.ReadingChanged += DataUpdated; | ||
} | ||
|
||
static void DataUpdated(object sender, AccelerometerReadingChangedEventArgs e) | ||
{ | ||
var reading = e.Reading; | ||
var data = new AccelerometerData(reading.AccelerationX, reading.AccelerationY, reading.AccelerationZ); | ||
OnChanged(data); | ||
} | ||
|
||
internal static void PlatformStop() | ||
{ | ||
if (sensor == null) | ||
return; | ||
|
||
sensor.ReadingChanged -= DataUpdated; | ||
} | ||
} | ||
} |
Oops, something went wrong.