Skip to content
This repository was archived by the owner on Jan 4, 2021. It is now read-only.

Commit b525720

Browse files
committed
api v1.1.0 commit
1 parent f13cf75 commit b525720

File tree

7 files changed

+125
-22
lines changed

7 files changed

+125
-22
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
*.pfx
21
## Ignore Visual Studio temporary files, build results, and
32
## files generated by popular Visual Studio add-ons.
43

MetaWear.Test/DataProcessorTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
using MbientLab.MetaWear.Data;
1313

1414
namespace MbientLab.MetaWear.Test {
15-
class DataProcessorTest : UnitTestBase {
15+
abstract class DataProcessorTest : UnitTestBase {
1616
public DataProcessorTest() : base(typeof(ISwitch), typeof(ILed), typeof(IAccelerometerBmi160),
1717
typeof(IBarometerBmp280), typeof(IGpio), typeof(ILogging), typeof(IDataProcessor), typeof(ITemperature)) { }
1818
}

MetaWear.Test/SensorFusionBoschTest.cs

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,11 @@ public static IEnumerable InterpretDataTestCases {
151151
}
152152
}
153153

154-
[Parallelizable]
155-
[TestFixture]
156-
class SensorFusionBoschTest : UnitTestBase {
157-
private ISensorFusionBosch sensorFusion;
154+
abstract class SensorFusionBoschBaseTest : UnitTestBase {
155+
protected ISensorFusionBosch sensorFusion;
158156

159-
public SensorFusionBoschTest() : base(typeof(IAccelerometerBmi160), typeof(IGyroBmi160), typeof(IMagnetometerBmm150), typeof(ISensorFusionBosch)) { }
157+
public SensorFusionBoschBaseTest() : base(typeof(IAccelerometerBmi160), typeof(IGyroBmi160), typeof(IMagnetometerBmm150), typeof(ISensorFusionBosch)) {
158+
}
160159

161160
[SetUp]
162161
public async override Task SetUp() {
@@ -177,7 +176,7 @@ public async override Task SetUp() {
177176
[TestCaseSource(typeof(SensorFusionBoschTestDataClass), "ConfigureTestCases")]
178177
public void Configure(Mode mode, AccRange acc, GyroRange gyr, Sensor.AccelerometerBmi160.FilterMode accFilter, FilterMode gyroFilter) {
179178
byte[][] expected = null;
180-
byte[] configGyro100Hz = new byte[] {0x13, 0x03, (byte) (((int) gyroFilter << 4 ) | GyroBmi160Test.ODR_BITMASK[(int) OutputDataRate._100Hz]), GyroBmi160Test.RANGE_BITMASK[(int) gyr]};
179+
byte[] configGyro100Hz = new byte[] { 0x13, 0x03, (byte)(((int)gyroFilter << 4) | GyroBmi160Test.ODR_BITMASK[(int)OutputDataRate._100Hz]), GyroBmi160Test.RANGE_BITMASK[(int)gyr] };
181180

182181
switch (mode) {
183182
case Mode.Ndof:
@@ -213,7 +212,7 @@ public void Configure(Mode mode, AccRange acc, GyroRange gyr, Sensor.Acceleromet
213212
};
214213
break;
215214
}
216-
expected[1][2] |= (byte)((int) accFilter << 4);
215+
expected[1][2] |= (byte)((int)accFilter << 4);
217216

218217
sensorFusion.Configure(mode, acc, gyr, accExtra: new Object[] { accFilter }, gyroExtra: new object[] { gyroFilter });
219218

@@ -263,4 +262,48 @@ await producer.AddRouteAsync(source => source.Stream(data => {
263262
Assert.That(actual, Is.EqualTo(expected));
264263
}
265264
}
265+
266+
[Parallelizable]
267+
[TestFixture]
268+
class SensorFusionBoschTest : SensorFusionBoschBaseTest {
269+
public SensorFusionBoschTest() : base() {
270+
271+
}
272+
273+
[Test]
274+
public void ReadCalibration() {
275+
Assert.ThrowsAsync<InvalidOperationException>(async () => {
276+
await sensorFusion.ReadCalibrationStateAsync();
277+
});
278+
}
279+
}
280+
281+
[Parallelizable]
282+
[TestFixture]
283+
class SensorFusionBoschRev1Test : SensorFusionBoschBaseTest {
284+
public SensorFusionBoschRev1Test() : base() {
285+
platform.initResponse.moduleResponses[0x19][3] = 0x1;
286+
}
287+
288+
[SetUp]
289+
public async override Task SetUp() {
290+
await base.SetUp();
291+
292+
platform.customResponses.Add(new byte[] { 0x19, 0x8b },
293+
new byte[] { 0x19, 0x8b, 0x00, 0x01, 0x02 });
294+
}
295+
296+
[Test]
297+
public async Task ReadCalibration() {
298+
byte[][] expected = new byte[][] {
299+
new byte[] { 0x19, 0x8b }
300+
};
301+
ImuCalibrationState expectedState = new ImuCalibrationState(CalibrationAccuracy.Unreliable, CalibrationAccuracy.LowAccuracy, CalibrationAccuracy.MediumAccuracy);
302+
303+
var actual = await sensorFusion.ReadCalibrationStateAsync();
304+
305+
Assert.That(actual, Is.EqualTo(expectedState));
306+
Assert.That(platform.GetCommands(), Is.EqualTo(expected));
307+
}
308+
}
266309
}

MetaWear/Core/ISensorFusionBosch.cs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,47 @@ public override int GetHashCode() {
150150
return result;
151151
}
152152
}
153+
/// <summary>
154+
/// Container class holding the calibration state of the IMU sensors
155+
/// </summary>
156+
public struct ImuCalibrationState {
157+
/// <summary>
158+
/// Current calibration accuracy values for the accelerometer, gyroscope, and magnetometer respectively
159+
/// </summary>
160+
public readonly CalibrationAccuracy accelerometer, gyroscope, magnetometer;
161+
162+
public ImuCalibrationState(CalibrationAccuracy accelerometer, CalibrationAccuracy gyroscope, CalibrationAccuracy magnetometer) {
163+
this.accelerometer = accelerometer;
164+
this.gyroscope = gyroscope;
165+
this.magnetometer = magnetometer;
166+
}
167+
168+
public override bool Equals(object obj) {
169+
if (!(obj is ImuCalibrationState)) {
170+
return false;
171+
}
172+
173+
var state = (ImuCalibrationState)obj;
174+
return accelerometer == state.accelerometer &&
175+
gyroscope == state.gyroscope &&
176+
magnetometer == state.magnetometer;
177+
}
178+
179+
public override int GetHashCode() {
180+
var hashCode = -56290531;
181+
hashCode = hashCode * -1521134295 + accelerometer.GetHashCode();
182+
hashCode = hashCode * -1521134295 + gyroscope.GetHashCode();
183+
hashCode = hashCode * -1521134295 + magnetometer.GetHashCode();
184+
return hashCode;
185+
}
186+
187+
public override string ToString() {
188+
return string.Format("{{accelerometer: {0}, gyroscope: {1}, magnetometer: {2}{3}",
189+
Enum.GetName(typeof(CalibrationAccuracy), accelerometer),
190+
Enum.GetName(typeof(CalibrationAccuracy), gyroscope),
191+
Enum.GetName(typeof(CalibrationAccuracy), magnetometer), "}");
192+
}
193+
}
153194
}
154195
/// <summary>
155196
/// Bosch algorithm combining accelerometer, gyroscope, and magnetometer data for Bosch sensors.
@@ -212,5 +253,12 @@ void Configure(Mode mode = Mode.Ndof, AccRange ar = AccRange._16g, GyroRange gr
212253
/// </summary>
213254
/// <returns>Task that is completed when the settings are received</returns>
214255
Task PullConfigAsync();
256+
/// <summary>
257+
/// Reads the current calibration state from the sensor fusion algorithm. This function cannot be
258+
/// called until the sensor fusion algorithm is running and is only available on firmware v1.4.1+
259+
/// </summary>
260+
/// <returns>Current calibrartion state</returns>
261+
/// <exception cref="InvalidOperationException">If device is not using min required firmware</exception>
262+
Task<ImuCalibrationState> ReadCalibrationStateAsync();
215263
}
216264
}

MetaWear/Impl/SensorFusionBosch.cs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ internal static string createIdentifier(DataTypeBase dataType) {
4141

4242
private const byte ENABLE = 1, MODE = 2, OUTPUT_ENABLE = 3,
4343
CORRECTED_ACC = 4, CORRECTED_ROT = 5, CORRECTED_MAG = 6,
44-
QUATERNION = 7, EULER_ANGLES = 8, GRAVITY_VECTOR = 9, LINEAR_ACC = 0xa;
44+
QUATERNION = 7, EULER_ANGLES = 8, GRAVITY_VECTOR = 9, LINEAR_ACC = 0xa,
45+
CALIBRATION_STATUS = 0xb;
46+
private const byte CALIBRATION_STATE_REV = 1;
4547

4648
[DataContract]
4749
private class QuaternionDataType : DataTypeBase {
@@ -262,7 +264,7 @@ public override void Stop() {
262264
[DataMember] private byte dataEnableMask;
263265
[DataMember] private DataTypeBase corrAccType, corrAngVelType, corrBFieldType, quaternionType, eulerAnglesType, gravityType, linAccType;
264266

265-
private TimedTask<byte[]> readConfigTask;
267+
private TimedTask<byte[]> readValueTask;
266268

267269
private IAsyncDataProducer correctedAcc = null, correctedAngularVel = null, correctedMag = null,
268270
quaternion = null, eulerAngles = null,
@@ -346,8 +348,9 @@ internal override void aggregateDataType(ICollection<DataTypeBase> collection) {
346348
}
347349

348350
protected override void init() {
349-
readConfigTask = new TimedTask<byte[]>();
350-
bridge.addRegisterResponseHandler(Tuple.Create((byte)SENSOR_FUSION, Util.setRead(MODE)), response => readConfigTask.SetResult(response));
351+
readValueTask = new TimedTask<byte[]>();
352+
bridge.addRegisterResponseHandler(Tuple.Create((byte)SENSOR_FUSION, Util.setRead(MODE)), response => readValueTask.SetResult(response));
353+
bridge.addRegisterResponseHandler(Tuple.Create((byte)SENSOR_FUSION, Util.setRead(CALIBRATION_STATUS)), response => readValueTask.SetResult(response));
351354
}
352355

353356
public void Configure(Mode mode = Mode.Ndof, AccRange ar = AccRange._16g, GyroRange gr = GyroRange._2000dps,
@@ -494,9 +497,18 @@ public void Stop() {
494497
}
495498

496499
public async Task PullConfigAsync() {
497-
var response = await readConfigTask.Execute("Did not receive sensor fusion config within {0}ms", bridge.TimeForResponse,
500+
var response = await readValueTask.Execute("Did not receive sensor fusion config within {0}ms", bridge.TimeForResponse,
498501
() => bridge.sendCommand(new byte[] { (byte)SENSOR_FUSION, Util.setRead(MODE) }));
499502
mode = (Mode)response[2];
500503
}
504+
505+
public async Task<ImuCalibrationState> ReadCalibrationStateAsync() {
506+
if (bridge.lookupModuleInfo(SENSOR_FUSION).revision >= CALIBRATION_STATE_REV) {
507+
var response = await readValueTask.Execute("Did not received calibration state within {0}ms", bridge.TimeForResponse,
508+
() => bridge.sendCommand(new byte[] { (byte)SENSOR_FUSION, Util.setRead(CALIBRATION_STATUS) }));
509+
return new ImuCalibrationState((CalibrationAccuracy)response[2], (CalibrationAccuracy)response[3], (CalibrationAccuracy)response[4]);
510+
}
511+
throw new InvalidOperationException(string.Format("Minimun firmware v1.4.1 required to use this function (current is {0})", bridge.getFirmware().ToString()));
512+
}
501513
}
502514
}

MetaWear/MetaWear.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<DelaySign>false</DelaySign>
77
<AssemblyName>MbientLab.MetaWear</AssemblyName>
88
<RootNamespace>MbientLab.MetaWear</RootNamespace>
9-
<Version>1.0.15</Version>
9+
<Version>1.1.0</Version>
1010
</PropertyGroup>
1111

1212
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">

nuget/MetaWear.nuspec

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,28 @@
33
<metadata minClientVersion="4.1">
44
<id>MetaWear.CSharp</id>
55
<title>MetaWear C# SDK</title>
6-
<version>1.0.15</version>
6+
<version>1.1.0</version>
77
<authors>MbientLab</authors>
88
<owners>MbientLab</owners>
99
<licenseUrl>https://raw.githubusercontent.com/mbientlab/MetaWear-SDK-CSharp/master/LICENSE.md</licenseUrl>
1010
<projectUrl>https://github.com/mbientlab/MetaWear-SDK-CSharp</projectUrl>
1111
<requireLicenseAcceptance>false</requireLicenseAcceptance>
1212
<copyright>Copyright 2014 - 2018(c). MbientLab Inc</copyright>
13-
<summary>Platform agnostic C# SDK for MbientLab's sensor platform</summary>
14-
<releaseNotes>https://github.com/mbientlab/MetaWear-SDK-CSharp/releases/tag/1.0.15</releaseNotes>
13+
<summary>.NET Standard 2.0 MetaMotion / MetaWear C# SDK</summary>
14+
<releaseNotes>https://github.com/mbientlab/MetaWear-SDK-CSharp/releases/tag/1.1.0</releaseNotes>
1515
<description>
16-
Platform agnostic, .NET Standard 2.0 library for commuicating with MbientLab's sensor platform.
16+
Platform agnostic, .NET Standard 2.0 library for communicating with MetaMotion / MetaWear boards.
1717

18-
Due to its platform agnostic nature, this package is only an API for the boards' BLE communication protocol;
18+
Due to its platform agnostic nature, this package is only an API for the BLE communication protocol;
1919
users of this package will need to plugin their own BLE stack and file i/o code.
2020

21-
Check out the MetaWear.Win10 package for Windows 10 specific BLE and file plugs.
21+
Check out the MetaWear.Win10 and MetaWear.NetStandard packages for Windows 10 and NetStandard 2.0 specific
22+
plugins for this project.
2223
</description>
2324
<tags>metawear metamotion metatracker sensors netstandard2.0</tags>
2425
</metadata>
2526
<files>
2627
<file src="..\MetaWear\bin\Release\netstandard2.0\MbientLab.MetaWear.dll" target="lib\netstandard2.0" />
27-
<file src="..\MetaWear\bin\Release\netstandard2.0\MbientLab.MetaWear.xml" target="lib\netstandard2.0" />
28+
<file src="..\MetaWear\bin\Release\netstandar d2.0\MbientLab.MetaWear.xml" target="lib\netstandard2.0" />
2829
</files>
2930
</package>

0 commit comments

Comments
 (0)