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

Commit

Permalink
api v1.2.0 commit
Browse files Browse the repository at this point in the history
  • Loading branch information
scaryghost committed Dec 27, 2018
1 parent b525720 commit 1203d8d
Show file tree
Hide file tree
Showing 19 changed files with 515 additions and 45 deletions.
85 changes: 82 additions & 3 deletions MetaWear.Test/DataProcessorTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@
using MbientLab.MetaWear.Peripheral.Led;
using MbientLab.MetaWear.Sensor.Temperature;
using MbientLab.MetaWear.Data;
using System.Collections.Generic;

namespace MbientLab.MetaWear.Test {
abstract class DataProcessorTest : UnitTestBase {
public DataProcessorTest() : base(typeof(ISwitch), typeof(ILed), typeof(IAccelerometerBmi160),
public DataProcessorTest() : base(typeof(ISwitch), typeof(ILed), typeof(IAccelerometerBmi160), typeof(IGyroBmi160),
typeof(IBarometerBmp280), typeof(IGpio), typeof(ILogging), typeof(IDataProcessor), typeof(ITemperature)) { }
}

Expand Down Expand Up @@ -481,6 +482,31 @@ public async Task CountData() {

Assert.That(count.Value, Is.EqualTo(492));
}

[Test]
public async Task CountAndTime() {
var barometer = metawear.GetModule<IBarometerBosch>();
var accelerometer = metawear.GetModule<IAccelerometer>();

DateTime? prev = null;
List<int> offsets = new List<int>();
await accelerometer.Acceleration.AddRouteAsync(source =>
source.Pack(2).Account(AccountType.Count).Stream()
);
await barometer.Pressure.AddRouteAsync(source => source.Account().Stream(_ => {
if (prev.HasValue) {
offsets.Add(Convert.ToInt32((_.Timestamp - prev.Value).TotalMilliseconds));
}
prev = _.Timestamp;
Console.WriteLine("time: " + _.Timestamp.ToString("MM/dd/yyyy hh:mm:ss.fffffff"));
}));

platform.sendMockResponse(new byte[] { 0x09, 0x03, 0x02, 0x72, 0xA4, 0x03, 0x00, 0x77, 0x6C, 0x84, 0x01 });
platform.sendMockResponse(new byte[] { 0x09, 0x03, 0x01, 0x8D, 0x00, 0x00, 0x00, 0x4E, 0xFF, 0x35, 0xFD, 0x79, 0x07, 0x4D, 0xFF, 0x35, 0xFD, 0x7D, 0x07 });
platform.sendMockResponse(new byte[] { 0x09, 0x03, 0x02, 0xA4, 0xA4, 0x03, 0x00, 0x05, 0x65, 0x84, 0x01 });

Assert.That(offsets, Is.EqualTo(new List<int>() { 73 }));
}
}

[Parallelizable]
Expand Down Expand Up @@ -594,7 +620,7 @@ public void ExtractData() {

Assert.That(actual, Is.EqualTo(expected));
}

[Test]
public void ExtractOffset() {
int[] expected = new int[] { 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 133, 0, 0, 0 };
Expand Down Expand Up @@ -645,7 +671,7 @@ public async Task HandleAccDataAsync() {
);
Acceleration actual = null;

await metawear.GetModule<IAccelerometer>().Acceleration.AddRouteAsync(source =>
await metawear.GetModule<IAccelerometer>().Acceleration.AddRouteAsync(source =>
source.HighPass(4).Stream(data => actual = data.Value<Acceleration>())
);
platform.sendMockResponse(new byte[] { 0x09, 0x03, 0x00, 0xef, 0xff, 0x29, 0x00, 0x16, 0x00 });
Expand Down Expand Up @@ -709,4 +735,57 @@ public async Task SplitOutput() {
}
}
}

[Parallelizable]
[TestFixture]
class TestFuser : DataProcessorTest {
[SetUp]
public async override Task SetUp() {
await base.SetUp();

var acc = metawear.GetModule<IAccelerometer>();
var gyro = metawear.GetModule<IGyroBmi160>();

await gyro.AngularVelocity.AddRouteAsync(source => source.Buffer().Name("gyro-buffer"));
await acc.Acceleration.AddRouteAsync(source => source.Fuse("gyro-buffer").Limit(20).Stream());
}

[Test]
public void CreateAccGyroFusion() {
byte[][] expected = new byte[][] {
new byte[] {0x09, 0x02, 0x13, 0x05, 0xff, 0xa0, 0x0f, 0x05},
new byte[] {0x09, 0x02, 0x03, 0x04, 0xff, 0xa0, 0x1b, 0x01, 0x00},
new byte[] {0x09, 0x02, 0x09, 0x03, 0x01, 0x60, 0x08, 0x13, 0x14, 0x00, 0x00, 0x00},
new byte[] {0x09, 0x03, 0x01},
new byte[] {0x09, 0x07, 0x02, 0x01}
};

Assert.That(platform.GetCommands(), Is.EqualTo(expected));
}

[Test]
public async Task HandleData() {
IData accData = null, gyroData = null;
metawear.LookupRoute(1).Subscribers[0].Attach(_ => {
var values = _.Value<IData[]>();
accData = values[0];
gyroData = values[1];
});


IData accRaw = null, gyroRaw = null;
var acc = metawear.GetModule<IAccelerometer>();
var gyro = metawear.GetModule<IGyroBmi160>();

await gyro.AngularVelocity.AddRouteAsync(source => source.Stream(_ => gyroRaw = _));
await acc.Acceleration.AddRouteAsync(source => source.Stream(_ => accRaw = _));

platform.sendMockResponse(new byte[] { 0x09, 0x03, 0x02, 0xf4, 0x0d, 0x3c, 0x39, 0x99, 0x11, 0x01, 0x80, 0xd6, 0x91, 0xd3, 0x67 });
platform.sendMockResponse(new byte[] { 0x03, 0x04, 0xf4, 0x0d, 0x3c, 0x39, 0x99, 0x11 });
platform.sendMockResponse(new byte[] { 0x13, 0x05, 0x01, 0x80, 0xd6, 0x91, 0xd3, 0x67 });

Assert.That(accData.Value<Acceleration>(), Is.EqualTo(accRaw.Value<Acceleration>()));
Assert.That(gyroData.Value<AngularVelocity>(), Is.EqualTo(gyroRaw.Value<AngularVelocity>()));
}
}
}
2 changes: 1 addition & 1 deletion MetaWear.Test/InitializeResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ static InitializeResponse() {
MODULE_RESPONSE.Add(typeof(INeoPixel), new byte[] {0x06, 0x80, 0x00, 0x00});
MODULE_RESPONSE.Add(typeof(IIBeacon), new byte[] {0x07, 0x80, 0x00, 0x00});
MODULE_RESPONSE.Add(typeof(IHaptic), new byte[] {0x08, 0x80, 0x00, 0x00});
MODULE_RESPONSE.Add(typeof(IDataProcessor), new byte[] {0x09, 0x80, 0x00, 0x02, 0x1c});
MODULE_RESPONSE.Add(typeof(IDataProcessor), new byte[] {0x09, 0x80, 0x00, 0x03, 0x1c});
MODULE_RESPONSE.Add(typeof(ILogging), new byte[] {0x0b, 0x80, 0x00, 0x02, 0x08, 0x80, 0x2b, 0x00, 0x00});
MODULE_RESPONSE.Add(typeof(ISerialPassthrough), new byte[] {0x0d, 0x80, 0x00, 0x01});
MODULE_RESPONSE.Add(typeof(IMacro), new byte[] {0x0f, 0x80, 0x00, 0x01, 0x08});
Expand Down
2 changes: 1 addition & 1 deletion MetaWear.Test/MetaWearBoardTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ class ModuleInfoDumpTest : UnitTestBase {
{"NeoPixel", new Dictionary<string, object>() { {"implementation", 0 }, {"revision", 0 } } },
{"IBeacon", new Dictionary<string, object>() { {"implementation", 0 }, {"revision", 0 } } },
{"Haptic", new Dictionary<string, object>() { {"implementation", 0 }, {"revision", 0 } } },
{"DataProcessor", new Dictionary<string, object>() { {"implementation", 0 }, {"revision", 2 }, { "extra", "[0x1c]" } } },
{"DataProcessor", new Dictionary<string, object>() { {"implementation", 0 }, {"revision", 3 }, { "extra", "[0x1c]" } } },
{"Event", new Dictionary<string, object>() { {"implementation", 0 }, {"revision", 0 }, { "extra", "[0x1c]" } } },
{"Logging", new Dictionary<string, object>() { {"implementation", 0 }, {"revision", 2 }, { "extra", "[0x08, 0x80, 0x2b, 0x00, 0x00]" } } },
{"Timer", new Dictionary<string, object>() { {"implementation", 0 }, {"revision", 0 }, { "extra", "[0x08]" } } },
Expand Down
136 changes: 134 additions & 2 deletions MetaWear.Test/SensorFusionBoschTest.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
using MbientLab.MetaWear.Core;
using MbientLab.MetaWear.Core.SensorFusionBosch;
using MbientLab.MetaWear.Data;
using MbientLab.MetaWear.Impl;
using MbientLab.MetaWear.Sensor;
using MbientLab.MetaWear.Sensor.GyroBmi160;
using NUnit.Framework;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace MbientLab.MetaWear.Test {
public class SensorFusionBoschTestDataClass {
public static IEnumerable ConfigModes => Enum.GetValues(typeof(Mode));

public static IEnumerable ConfigureTestCases {
get {
List<TestCaseData> testCases = new List<TestCaseData>();
Expand Down Expand Up @@ -276,6 +281,18 @@ public void ReadCalibration() {
await sensorFusion.ReadCalibrationStateAsync();
});
}

[Test]
public void Calibrate() {
Assert.ThrowsAsync<InvalidOperationException>(async () => {
try {
var cts = new CancellationTokenSource();
await sensorFusion.Calibrate(cts.Token);
} catch (AggregateException e) {
throw e.InnerException;
}
});
}
}

[Parallelizable]
Expand All @@ -289,8 +306,7 @@ public SensorFusionBoschRev1Test() : base() {
public async override Task SetUp() {
await base.SetUp();

platform.customResponses.Add(new byte[] { 0x19, 0x8b },
new byte[] { 0x19, 0x8b, 0x00, 0x01, 0x02 });
platform.customResponses.Add(new byte[] { 0x19, 0x8b }, new byte[] { 0x19, 0x8b, 0x00, 0x01, 0x02 });
}

[Test]
Expand All @@ -306,4 +322,120 @@ public async Task ReadCalibration() {
Assert.That(platform.GetCommands(), Is.EqualTo(expected));
}
}

[Parallelizable]
[TestFixture]
class SensorFusionBoschRev2Test : SensorFusionBoschRev1Test {
private static readonly byte[] ACC = new byte[] { 0x19, 0x0c, 0xf6, 0xff, 0x00, 0x00, 0x0a, 0x00, 0xe8, 0x03, 0x03, 0x00 },
GYRO = new byte[] { 0x19, 0x0d, 0x04, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00 },
MAG = new byte[] { 0x19, 0x0e, 0x66, 0x00, 0x17, 0xfd, 0x8a, 0xfc, 0x7f, 0x03, 0x01, 0x00 };

public SensorFusionBoschRev2Test() : base() {
platform.initResponse.moduleResponses[0x19][3] = 0x2;
}

[Test]
public void CalibrateCancelled() {
platform.customResponses.Remove(new byte[] { 0x19, 0x8b });
Assert.ThrowsAsync<TaskCanceledException>(async () => {
try {
var cts = new CancellationTokenSource();
cts.CancelAfter(5000);
await sensorFusion.Calibrate(cts.Token);
} catch (AggregateException e) {
throw e.InnerException;
}
});
}

[Test]
[TestCaseSource(typeof(SensorFusionBoschTestDataClass), "ConfigModes")]
public async Task Calibrate(Mode mode) {
byte[][] expected = null;

switch (mode) {
case Mode.Ndof:
expected = new byte[][] {
new byte[] { 0x19, 0x8b },
new byte[] { 0x19, 0x8c },
new byte[] { 0x19, 0x8d },
new byte[] { 0x19, 0x8e },
};
break;
case Mode.ImuPlus:
expected = new byte[][] {
new byte[] { 0x19, 0x8b },
new byte[] { 0x19, 0x8c },
new byte[] { 0x19, 0x8d },
};
break;
case Mode.Compass:
expected = new byte[][] {
new byte[] { 0x19, 0x8b },
new byte[] { 0x19, 0x8c },
new byte[] { 0x19, 0x8e },
};
break;
case Mode.M4g:
expected = new byte[][] {
new byte[] { 0x19, 0x8b },
new byte[] { 0x19, 0x8c },
new byte[] { 0x19, 0x8e },
};
break;
}

platform.customResponses[new byte[] { 0x19, 0x8b }] = new byte[] { 0x19, 0x8b, 0x03, 0x03, 0x03 };

var copy = (new byte[ACC.Length], new byte[GYRO.Length], new byte[MAG.Length]);
Array.Copy(ACC, copy.Item1, ACC.Length);
Array.Copy(GYRO, copy.Item2, GYRO.Length);
Array.Copy(MAG, copy.Item3, MAG.Length);
copy.Item1[1] |= 0x80;
copy.Item2[1] |= 0x80;
copy.Item3[1] |= 0x80;

platform.customResponses.Add(new byte[] { 0x19, 0x8c }, copy.Item1);
platform.customResponses.Add(new byte[] { 0x19, 0x8d }, copy.Item2);
platform.customResponses.Add(new byte[] { 0x19, 0x8e }, copy.Item3);

var cts = new CancellationTokenSource();
sensorFusion.Configure(mode: mode);
platform.commands.Clear();
var actual = await sensorFusion.Calibrate(cts.Token);

Assert.That(platform.GetCommands(), Is.EqualTo(expected));
}

[Test]
[TestCaseSource(typeof(SensorFusionBoschTestDataClass), "ConfigModes")]
public void WriteCalibrationData(Mode mode) {
var unwrapped = (ACC.Skip(2).ToArray(), GYRO.Skip(2).ToArray(), MAG.Skip(2).ToArray());
byte[][] expected = null;

ImuCalibrationData? data = null;
switch (mode) {
case Mode.Ndof:
data = new ImuCalibrationData(unwrapped.Item1, unwrapped.Item2, unwrapped.Item3);
expected = new byte[][] { ACC, GYRO, MAG };
break;
case Mode.ImuPlus:
data = new ImuCalibrationData(unwrapped.Item1, unwrapped.Item2, null);
expected = new byte[][] { ACC, GYRO };
break;
case Mode.Compass:
data = new ImuCalibrationData(unwrapped.Item1, null, unwrapped.Item3);
expected = new byte[][] { ACC, MAG };
break;
case Mode.M4g:
data = new ImuCalibrationData(unwrapped.Item1, null, unwrapped.Item3);
expected = new byte[][] { ACC, MAG };
break;
}

sensorFusion.WriteCalibrationData(data.Value);
Assert.That(platform.GetCommands(), Is.EqualTo(expected));
}
}
}
11 changes: 10 additions & 1 deletion MetaWear/Builder/IRouteComponent.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using MbientLab.MetaWear.Core;
using System;

namespace MbientLab.MetaWear.Builder {
/// <summary>
Expand Down Expand Up @@ -366,5 +367,13 @@ public interface IRouteComponent {
/// <param name="count">Number of input values to pack</param>
/// <returns>Component representing the accounter output</returns>
IRouteComponent Pack(byte count);

/// <summary>
/// Combines data from multiple sources into 1 packet, available on firmware v1.4.4+.
/// The additional data you want to combine must first be stored into a named buffer.
/// </summary>
/// <param name="bufferNames">Named buffer components holding the extra data to combine</param>
/// <returns>Component representing the fuser output</returns>
IRouteComponent Fuse(params string[] bufferNames);
}
}
Loading

0 comments on commit 1203d8d

Please sign in to comment.