Skip to content

Commit

Permalink
Add MoveHub Support with Internal Motor and Tilt Sensor (#134)
Browse files Browse the repository at this point in the history
* Added support for MoveHub
* Added example for MoveHub
* Renamed DeviceTypes and HubType for MoveHub for clarity
* Changed MoveHub Tilt Sensor to disable percentage and removed workaround on port value single encoder when percentage was bigger than an sbyte
* No calibration support (unclear behavior, safer for now)
* Add support for Virtual Port AttachedHubIO messages during device connection

Co-authored-by: cornelius munz <[email protected]
  • Loading branch information
KeyDecoder authored Dec 31, 2020
1 parent 1da1b1a commit 9e89765
Show file tree
Hide file tree
Showing 21 changed files with 624 additions and 10 deletions.
25 changes: 25 additions & 0 deletions examples/SharpBrick.PoweredUp.Examples/ExampleMoveHubColors.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using System.Threading.Tasks;
using SharpBrick.PoweredUp;

namespace Example
{
public class ExampleMoveHubColors : BaseExample
{
public override async Task ExecuteAsync()
{
using (var moveHub = Host.FindByType<MoveHub>())
{
await moveHub.RgbLight.SetRgbColorsAsync(0x00, 0xff, 0x00);

await Task.Delay(2000);

await moveHub.RgbLight.SetRgbColorsAsync(0xff, 0x00, 0x00);

await Task.Delay(2000);

await moveHub.SwitchOffAsync();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.Threading.Tasks;
using SharpBrick.PoweredUp;

namespace Example
{
public class ExampleMoveHubExternalMediumLinearMotorControl : BaseExample
{
public override async Task ExecuteAsync()
{
using (var moveHub = Host.FindByType<MoveHub>())
{
// This is if you have a linear motor plugged into port D (ie. R2D2)
var externalMotor = moveHub.D.GetDevice<MediumLinearMotor>();

await externalMotor.SetAccelerationTimeAsync(3000);
await externalMotor.SetDecelerationTimeAsync(1000);
await externalMotor.StartSpeedForTimeAsync(2000, 90, 100, SpecialSpeed.Hold, SpeedProfiles.AccelerationProfile | SpeedProfiles.DecelerationProfile);

await Task.Delay(50000);

await moveHub.SwitchOffAsync();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Threading.Tasks;
using SharpBrick.PoweredUp;

namespace Example
{
public class ExampleMoveHubInternalTachoMotorControl : BaseExample
{
public override async Task ExecuteAsync()
{
using (var moveHub = Host.FindByType<MoveHub>())
{
var internalMotor = moveHub.MotorAtAB;
await internalMotor.StartSpeedAsync(50, 100);
await internalMotor.StartSpeedForTimeAsync(2000, 90, 100, SpecialSpeed.Hold, SpeedProfiles.AccelerationProfile | SpeedProfiles.DecelerationProfile);

await Task.Delay(3000);
await internalMotor.StopByBrakeAsync();

var leftMotor = moveHub.LeftMotorAtB;
var rightMotor = moveHub.RightMotorAtA;
await leftMotor.StartSpeedAsync(10, 100);
await leftMotor.StartSpeedForTimeAsync(1000, 10, 100, SpecialSpeed.Hold, SpeedProfiles.AccelerationProfile | SpeedProfiles.DecelerationProfile);
await rightMotor.StartSpeedAsync(90, 100);
await rightMotor.StartSpeedForTimeAsync(1000, 90, 100, SpecialSpeed.Hold, SpeedProfiles.AccelerationProfile | SpeedProfiles.DecelerationProfile);

await Task.Delay(2000);

await leftMotor.StopByBrakeAsync();
await rightMotor.StopByBrakeAsync();

await moveHub.SwitchOffAsync();
}
}
}
}
55 changes: 55 additions & 0 deletions examples/SharpBrick.PoweredUp.Examples/ExampleMoveHubTiltSensor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using SharpBrick.PoweredUp;

namespace Example
{
public class ExampleMoveHubTiltSensor : BaseExample
{
public override async Task ExecuteAsync()
{
using (var moveHub = Host.FindByType<MoveHub>())
{
var device = moveHub.TiltSensor;
await device.TiltConfigOrientationAsync(TiltConfigOrientation.Front);

// Note that you can only have 1 notification running at a time

await device.SetupNotificationAsync(device.ModeIndexTwoAxisFull, true, 1);
using var twoAxisFullSubscription = device.TwoAxisFullObservable.Subscribe(x => Log.LogWarning($"Two Axis Values - Roll: {x.roll}, Pitch: {x.pitch}"));

Console.WriteLine("Press any key to continue");
Console.ReadKey();

await device.SetupNotificationAsync(device.ModeIndexTwoAxisState, true, 1);
using var twoAxisStateSubscription = device.TwoAxisStateObservable.Subscribe(x => Log.LogWarning($"Two Axis State: {x}"));

Console.WriteLine("Press any key to continue");
Console.ReadKey();

await device.SetupNotificationAsync(device.ModeIndexThreeAxisState, true, 1);
using var threeAxisStateSubscription = device.ThreeAxisStateObservable.Subscribe(x => Log.LogWarning($"Three Axis State: {x}"));

Console.WriteLine("Press any key to continue");
Console.ReadKey();

await device.SetupNotificationAsync(device.ModeIndexThreeAxisFull, true, 1);
using var threeAxisFullSubscription = device.ThreeAxisFullObservable.Subscribe(x => Log.LogWarning($"Three Axis Values - Roll: {x.roll}, Pitch: {x.pitch}, Yaw: {x.yaw}"));

Console.WriteLine("Press any key to continue");
Console.ReadKey();

// This configures a minimum threshold for an impact to be registered (should be a light tap) and subscribes to the count of impacts
await device.TiltConfigImpactAsync(10, 1270);
await device.SetupNotificationAsync(device.ModeIndexImpacts, true, deltaInterval: 1);
using var impactSubscription = device.ImpactsObservable.Subscribe(x => Log.LogWarning($"Impact Count: {x.SI}"));

Console.WriteLine("Press any key to continue");
Console.ReadKey();

await moveHub.SwitchOffAsync();
}
}
}
}
8 changes: 7 additions & 1 deletion examples/SharpBrick.PoweredUp.Examples/Program.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Threading.Tasks;
using Example;

namespace SharpBrick.PoweredUp.Examples
{
Expand Down Expand Up @@ -43,7 +44,12 @@ static async Task Main(string[] args)
//example = new Example.ExampleMarioAccelerometer();
//example = new Example.ExampleDuploTrainBase();
//example = new Example.ExampleTechnicColorSensor();
example = new Example.ExampleTechnicDistanceSensor();
//example = new Example.ExampleTechnicDistanceSensor();
//example = new Example.ExampleTechnicMediumHubGestSensor();
//example = new Example.ExampleMoveHubInternalTachoMotorControl();
//example = new Example.ExampleMoveHubExternalMediumLinearMotorControl();
//example = new Example.ExampleMoveHubColors();
example = new Example.ExampleMoveHubTiltSensor();

// NOTE: Examples are programmed object oriented style. Base class implements methods Configure, DiscoverAsync and ExecuteAsync to be overwriten on demand.
await example.InitHostAndDiscoverAsync(enableTrace);
Expand Down
18 changes: 18 additions & 0 deletions src/SharpBrick.PoweredUp/Devices/Current.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,24 @@ public IEnumerable<byte[]> GetStaticPortInfoMessages(Version softwareVersion, Ve
0B-00-44-3B-01-04-6D-41-00-00-00
08-00-44-3B-01-05-10-00
0A-00-44-3B-01-80-01-01-04-00
",
(_, _, SystemType.LegoSystem_MoveHub) => @"
0B-00-43-3B-01-02-02-03-00-00-00
05-00-43-3B-02
11-00-44-3B-00-00-43-55-52-20-4C-00-00-00-00-00-00
0E-00-44-3B-00-01-00-00-00-00-00-F0-7F-45
0E-00-44-3B-00-02-00-00-00-00-00-00-C8-42
0E-00-44-3B-00-03-00-00-00-00-00-C0-18-45
0A-00-44-3B-00-04-6D-41-00-00
08-00-44-3B-00-05-10-00
0A-00-44-3B-00-80-01-01-04-00
11-00-44-3B-01-00-43-55-52-20-53-00-00-00-00-00-00
0E-00-44-3B-01-01-00-00-00-00-00-F0-7F-45
0E-00-44-3B-01-02-00-00-00-00-00-00-C8-42
0E-00-44-3B-01-03-00-00-00-00-00-C0-18-45
0A-00-44-3B-01-04-6D-41-00-00
08-00-44-3B-01-05-10-00
0A-00-44-3B-01-80-01-01-04-00
",
_ => throw new NotSupportedException(),
}).Trim().Split("\n").Select(s => BytesStringUtil.StringToData(s));
Expand Down
4 changes: 4 additions & 0 deletions src/SharpBrick.PoweredUp/Devices/DeviceFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ public Type GetTypeFromDeviceType(DeviceType deviceType)
DeviceType.DuploTrainBaseSpeaker => typeof(DuploTrainBaseSpeaker),
DeviceType.DuploTrainBaseColorSensor => typeof(DuploTrainBaseColorSensor),
DeviceType.DuploTrainBaseSpeedometer => typeof(DuploTrainBaseSpeedometer),
DeviceType.MoveHubInternalMotor => typeof(MoveHubInternalMotor),
DeviceType.MoveHubTiltSensor => typeof(MoveHubTiltSensor),
_ => null,
};

Expand Down Expand Up @@ -88,6 +90,8 @@ public static DeviceType GetDeviceTypeFromType(Type type)
nameof(DuploTrainBaseSpeaker) => DeviceType.DuploTrainBaseSpeaker,
nameof(DuploTrainBaseColorSensor) => DeviceType.DuploTrainBaseColorSensor,
nameof(DuploTrainBaseSpeedometer) => DeviceType.DuploTrainBaseSpeedometer,
nameof(MoveHubInternalMotor) => DeviceType.MoveHubInternalMotor,
nameof(MoveHubTiltSensor) => DeviceType.MoveHubTiltSensor,
_ => DeviceType.Unknown,
};
}
Expand Down
45 changes: 45 additions & 0 deletions src/SharpBrick.PoweredUp/Devices/MoveHubInternalMotor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using SharpBrick.PoweredUp.Protocol;
using SharpBrick.PoweredUp.Utils;

namespace SharpBrick.PoweredUp
{
public class MoveHubInternalMotor : TachoMotor, IPoweredUpDevice
{
public MoveHubInternalMotor()
: base()
{ }
public MoveHubInternalMotor(ILegoWirelessProtocol protocol, byte hubId, byte portId)
: base(protocol, hubId, portId)
{ }

public IEnumerable<byte[]> GetStaticPortInfoMessages(Version softwareVersion, Version hardwareVersion, SystemType systemType)
=> @"
0B-00-43-00-01-0F-03-06-00-07-00
07-00-43-00-02-06-00
11-00-44-00-00-00-50-4F-57-45-52-00-00-00-00-00-00
0E-00-44-00-00-01-00-00-C8-C2-00-00-C8-42
0E-00-44-00-00-02-00-00-C8-C2-00-00-C8-42
0E-00-44-00-00-03-00-00-C8-C2-00-00-C8-42
0A-00-44-00-00-04-50-43-54-00
08-00-44-00-00-05-00-10
0A-00-44-00-00-80-01-00-01-00
11-00-44-00-01-00-53-50-45-45-44-00-00-00-00-00-00
0E-00-44-00-01-01-00-00-C8-C2-00-00-C8-42
0E-00-44-00-01-02-00-00-C8-C2-00-00-C8-42
0E-00-44-00-01-03-00-00-C8-C2-00-00-C8-42
0A-00-44-00-01-04-50-43-54-00
08-00-44-00-01-05-10-10
0A-00-44-00-01-80-01-00-04-00
11-00-44-00-02-00-50-4F-53-00-00-00-00-00-00-00-00
0E-00-44-00-02-01-00-00-B4-C3-00-00-B4-43
0E-00-44-00-02-02-00-00-C8-C2-00-00-C8-42
0E-00-44-00-02-03-00-00-B4-C3-00-00-B4-43
0A-00-44-00-02-04-44-45-47-00
08-00-44-00-02-05-08-08
0A-00-44-00-02-80-01-02-04-00
".Trim().Split("\n").Select(s => BytesStringUtil.StringToData(s));
}
}
Loading

0 comments on commit 9e89765

Please sign in to comment.