diff --git a/Examples/BB2B/BB2B.cs b/Examples/BB2B/BB2B.cs
index 4f1c3cf..2a398ca 100644
--- a/Examples/BB2B/BB2B.cs
+++ b/Examples/BB2B/BB2B.cs
@@ -9,7 +9,7 @@ namespace RoboidControl {
readonly TouchSensor touchRight;
const float speed = 0.5f;
- public BB2B(Participant owner) : base(owner) {
+ public BB2B(Thing parent = default) : base(parent) {
this.name = "BB2B";
this.SetMotors(new Motor(this), new Motor(this));
this.SetDriveDimensions(0.064f, 0.128f);
diff --git a/Examples/BB2B/BB2B_Encoder.cs b/Examples/BB2B/BB2B_Encoder.cs
index f2b91df..21787c6 100644
--- a/Examples/BB2B/BB2B_Encoder.cs
+++ b/Examples/BB2B/BB2B_Encoder.cs
@@ -9,15 +9,15 @@ namespace RoboidControl {
readonly TouchSensor touchRight;
const float speed = 180.0f; // wheel rotation speed in degrees
- public BB2B_Encoder(Participant owner) : base(owner) {
+ public BB2B_Encoder(Thing parent) : base(parent) {
this.name = "BB2B";
this.SetDriveDimensions(0.064f, 0.128f);
// Update the basic motors to motors with encoder
- EncoderMotor leftMotor = new(this, new RelativeEncoder()) {
+ ControlledMotor leftMotor = new(this, new RelativeEncoder()) {
position = new Spherical(0.064f, Direction.left)
};
- EncoderMotor rightMotor = new(this, new RelativeEncoder()) {
+ ControlledMotor rightMotor = new(this, new RelativeEncoder()) {
position = new Spherical(0.064f, Direction.right)
};
this.SetMotors(leftMotor, rightMotor);
diff --git a/Examples/BB2B/Program.cs b/Examples/BB2B/Program.cs
index 10b0c67..7550097 100644
--- a/Examples/BB2B/Program.cs
+++ b/Examples/BB2B/Program.cs
@@ -3,7 +3,7 @@ using RoboidControl;
class Program {
static void Main() {
- BB2B bb2b = new(ParticipantUDP.Isolated());
+ BB2B bb2b = new();
while (true) {
bb2b.Update();
diff --git a/README.md b/README.md
index 7af367d..b576be8 100644
--- a/README.md
+++ b/README.md
@@ -11,3 +11,21 @@ The documentation for Roboid Control for C# is found at https://docs.roboidcontr
- RoboidControl::Thing
- RoboidControl::Participant
+
+# Get Started
+
+## Unity
+
+The Unity environment can use the same RoboidControl code as every other C# code, but needs a *starter* wrapper around it to make the things visibile. For example, to start the BB2B example in Unity one needs to write a BB2B_Starter.cs component as follows:
+```
+using RoboidControl.Unity;
+
+public class BB2B_Starter : SiteServer {
+ void Start() {
+ new RoboidControl.BB2B();
+ }
+}
+```
+This component then should be attached to a GameObject in the scene.
+
+It is possible to create a Site Server in Unity by just adding the `SiteServer` Component to a GameObject in the scene. When this is run, other roboids will be able to connect to this site then.
\ No newline at end of file
diff --git a/src/Participant.cs b/src/Participant.cs
index 4318467..a936b87 100644
--- a/src/Participant.cs
+++ b/src/Participant.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Net;
using System.Net.Sockets;
+using System.Reflection.Metadata;
namespace RoboidControl {
@@ -14,6 +15,13 @@ namespace RoboidControl {
/// It also maintains the communcation information to contact the participant.
/// It is used as a basis for the local participant, but also as a reference to remote participants.
public class Participant {
+
+ private Participant() {
+ this.root = Thing.CreateRoot(this);
+ this.root.name = "Root";
+ this.Add(this.root);
+ }
+
///
/// Create a new participant with the given communcation info
///
@@ -26,6 +34,10 @@ namespace RoboidControl {
this.udpClient = localParticipant.udpClient;
}
+ public static readonly Participant localParticipant = new();
+
+ public Thing root = null;
+
///
/// The Ip Address of a participant. When the participant is local, this contains 0.0.0.0
///
diff --git a/src/Participants/SiteServer.cs b/src/Participants/SiteServer.cs
index 8c38572..519f425 100644
--- a/src/Participants/SiteServer.cs
+++ b/src/Participants/SiteServer.cs
@@ -132,9 +132,9 @@ namespace RoboidControl {
protected virtual Thing ProcessNewThing(Participant sender, ThingMsg msg) {
return msg.thingType switch {
- Thing.Type.TouchSensor => new TouchSensor(sender, msg.thingId),
- Thing.Type.DifferentialDrive => new DifferentialDrive(sender, msg.thingId),
- _ => new Thing(sender, msg.thingType, msg.thingId),
+ //Thing.Type.TouchSensor => new TouchSensor(sender, msg.thingId),
+ //Thing.Type.DifferentialDrive => new DifferentialDrive(sender, msg.thingId),
+ _ => Thing.CreateRemote(sender, msg.thingType, msg.thingId)
};
}
diff --git a/src/Thing.cs b/src/Thing.cs
index af90a11..b9f9b29 100644
--- a/src/Thing.cs
+++ b/src/Thing.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using LinearAlgebra;
+using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection;
namespace RoboidControl {
@@ -26,10 +27,11 @@ namespace RoboidControl {
public const byte ControlledMotor = 0x06;
public const byte UncontrolledMotor = 0x07;
public const byte Servo = 0x08;
- public const byte IncrementalEncoder = 0x19;
+ public const byte RelativeEncoder = 0x19;
// Other
+ public const byte Root = 0x10;
public const byte Roboid = 0x09;
- public const byte HUmanoid = 0x0A;
+ public const byte Humanoid = 0x0A;
public const byte ExternalSensor = 0x0B;
public const byte Animator = 0x0C;
public const byte DifferentialDrive = 0x0D;
@@ -37,6 +39,29 @@ namespace RoboidControl {
#region Init
+ private Thing(Participant owner) {
+ this.type = Type.Root;
+
+ this.positionUpdated = true;
+ this.orientationUpdated = true;
+ this.hierarchyChanged = true;
+
+ this.owner = owner;
+ this.parent = null;
+ }
+
+ public static Thing CreateRoot(Participant owner) {
+ return new Thing(owner);
+ }
+
+ static Thing localRoot {
+ get {
+ Participant participant = Participant.localParticipant;
+ return participant.root;
+ }
+ }
+
+ /*
///
/// Create a new thing without communication abilities
///
@@ -66,6 +91,7 @@ namespace RoboidControl {
this.owner.updateQueue.Enqueue(e);
}
}
+ */
///
/// Create a new child thing
@@ -75,26 +101,33 @@ namespace RoboidControl {
/// The ID of the thing, leave out or set to zero to generate an ID
/// Invoke a OnNewThing event when the thing has been created
/// The owner will be the same as the owner of the parent thing
+ /*
public Thing(Thing parent, byte thingType = Type.Undetermined, byte thingId = 0, bool invokeEvent = true) : this(parent.owner, thingType, thingId, invokeEvent) {
this.parent = parent;
}
+ */
+ public Thing(byte thingType = Type.Undetermined, Thing parent = default) {
+ this.type = thingType;
- // ///
- // /// Create a new thing for the given participant
- // ///
- // /// The participant owning the thing
- // /// The network ID of the thing
- // /// The ID of the thing
- // /// The type of thing
- // public Thing(Participant owner, byte networkId, byte thingId, byte thingType = 0) {
- // this.owner = owner;
- // this.id = thingId;
- // this.type = thingType;
- // this.networkId = networkId;
- // // Console.Write($"New thing added to {owner}");
- // this.owner.Add(this);
- // InvokeNewThing(this);
- // }
+ this.positionUpdated = true;
+ this.orientationUpdated = true;
+ this.hierarchyChanged = true;
+
+ if (parent == default)
+ this.parent = Participant.localParticipant.root;
+ else
+ this.parent = parent;
+
+ this.owner = parent.owner;
+ this.owner.Add(this, true);
+ }
+
+ public static Thing CreateRemote(Participant owner, byte thingType, byte thingId) {
+ Thing remoteThing = new(thingType, owner.root) {
+ id = thingId
+ };
+ return remoteThing;
+ }
///
/// Function which can be used to create components in external engines.
diff --git a/src/Things/EncoderMotor.cs b/src/Things/ControlledMotor.cs
similarity index 91%
rename from src/Things/EncoderMotor.cs
rename to src/Things/ControlledMotor.cs
index 01d6ac6..fb5ad79 100644
--- a/src/Things/EncoderMotor.cs
+++ b/src/Things/ControlledMotor.cs
@@ -3,12 +3,12 @@ namespace RoboidControl {
/// @brief A motor with speed control
/// It uses a feedback loop from an encoder to regulate the speed
/// The speed is measured in revolutions per second.
- class EncoderMotor : Motor {
- public EncoderMotor(Thing parent, RelativeEncoder encoder) : base(parent) {
+ public class ControlledMotor : Motor {
+ public ControlledMotor(Thing parent, RelativeEncoder encoder) : base(parent) {
this.encoder = encoder;
}
// Upgrade an existing motor with an encoder
- public EncoderMotor(Motor motor, RelativeEncoder encoder) : base(motor.parent) {
+ public ControlledMotor(Motor motor, RelativeEncoder encoder) : base(motor.parent) {
this.motor = motor;
this.encoder = encoder;
}
@@ -50,7 +50,7 @@ namespace RoboidControl {
float pidP = 0.1F;
float pidD = 0.0F;
- float pidI = 0.0F;
+ //float pidI = 0.0F;
public override void Update(ulong currentTimeMs, bool recurse = false) {
float actualSpeed = this.encoder.angularSpeed;
diff --git a/src/Things/DifferentialDrive.cs b/src/Things/DifferentialDrive.cs
index 45203a8..271ea0d 100644
--- a/src/Things/DifferentialDrive.cs
+++ b/src/Things/DifferentialDrive.cs
@@ -6,11 +6,13 @@ namespace RoboidControl {
///
/// @sa @link https://en.wikipedia.org/wiki/Differential_wheeled_robot @endlink
public class DifferentialDrive : Thing {
+ /*
///
/// Create a differential drive without communication abilities
/// Invoke a OnNewThing event when the thing has been created
- public DifferentialDrive(bool invokeEvent = true) : base(Type.DifferentialDrive, invokeEvent) { }
+ public DifferentialDrive() : base(Type.DifferentialDrive) { }
+
///
/// Create a differential drive for a participant
///
@@ -28,15 +30,16 @@ namespace RoboidControl {
// sendBinary = true;
// owner.Send(new BinaryMsg(owner.networkId, this));
// this.updateQueue.Enqueue(new UpdateEvent(BinaryMsg.Id));
-
}
+ */
+
///
/// Create a new child differential drive
///
/// The parent thing
/// The ID of the thing, leave out or set to zero to generate an ID
/// Invoke a OnNewThing event when the thing has been created
- public DifferentialDrive(Thing parent, byte thingId = 0, bool invokeEvent = true) : base(parent, Type.DifferentialDrive, thingId, invokeEvent) { }
+ public DifferentialDrive(Thing parent) : base(Type.DifferentialDrive, parent) { }
/// @brief Configures the dimensions of the drive
/// @param wheelDiameter The diameter of the wheels in meters
@@ -101,9 +104,9 @@ namespace RoboidControl {
/// Positive moves the robot in the forward direction.
public void SetWheelAngularVelocity(float angularSpeedLeft, float angularSpeedRight) {
// This only works when the motor is a motor with encoder
- if (this.leftWheel is EncoderMotor leftMotor)
+ if (this.leftWheel is ControlledMotor leftMotor)
leftMotor.targetAngularSpeed = angularSpeedLeft;
- if (this.rightWheel is EncoderMotor rightMotor)
+ if (this.rightWheel is ControlledMotor rightMotor)
rightMotor.targetAngularSpeed = angularSpeedRight;
}
diff --git a/src/Things/DigitalSensor.cs b/src/Things/DigitalSensor.cs
index 2993580..3d1a19c 100644
--- a/src/Things/DigitalSensor.cs
+++ b/src/Things/DigitalSensor.cs
@@ -6,6 +6,7 @@ namespace RoboidControl {
/// A sensor which can detect touches
///
public class DigitalSensor : Thing {
+ /*
///
/// Create a digital sensor without communication abilities
///
@@ -18,13 +19,14 @@ namespace RoboidControl {
/// The ID of the thing, leave out or set to zero to generate an ID
/// Invoke a OnNewThing event when the thing has been created
public DigitalSensor(Participant owner, byte thingId = 0, bool invokeEvent = true) : base(owner, Type.Switch, thingId, invokeEvent) { }
+ */
///
/// Create a new child digital sensor
///
/// The parent thing
/// The ID of the thing, leave out or set to zero to generate an ID
/// Invoke a OnNewThing event when the thing has been created
- public DigitalSensor(Thing parent, byte thingId = 0, bool invokeEvent = true) : base(parent, Type.Switch, thingId, invokeEvent) { }
+ public DigitalSensor(Thing parent) : base(Type.Switch, parent) { }
///
/// Value which is true when the sensor is touching something, false otherwise
diff --git a/src/Things/DistanceSensor.cs b/src/Things/DistanceSensor.cs
index ad5f785..def58f9 100644
--- a/src/Things/DistanceSensor.cs
+++ b/src/Things/DistanceSensor.cs
@@ -9,19 +9,23 @@ namespace RoboidControl {
///
public float distance = 0;
+ /*
///
/// Constructor for a new distance sensor
///
/// The participant for which the sensor is needed
public DistanceSensor(Participant participant) : base(participant, Type.Undetermined) { }
+
///
/// Create a distance sensor with the given ID
///
/// The participant for with the sensor is needed
/// The network ID of the sensor
/// The ID of the thing
- public DistanceSensor(Participant owner, byte thingId) : base(owner, Type.TemperatureSensor, thingId) {
- }
+ public DistanceSensor(Participant owner, byte thingId) : base(owner, Type.TemperatureSensor, thingId) {}
+ */
+ public DistanceSensor(Thing parent): base(Type.DistanceSensor, parent) {}
+
#if UNITY_5_3_OR_NEWER
/// @copydoc Passer::RoboidControl::Thing::CreateComponent
diff --git a/src/Things/Motor.cs b/src/Things/Motor.cs
index 1b09654..e4ecad8 100644
--- a/src/Things/Motor.cs
+++ b/src/Things/Motor.cs
@@ -3,8 +3,8 @@ using LinearAlgebra;
namespace RoboidControl {
public class Motor : Thing {
- public Motor(bool invokeEvent = true) : base(Type.UncontrolledMotor, invokeEvent) { }
- public Motor(Thing parent, byte thingId = 0, bool invokeEvent = true) : base(parent, Type.UncontrolledMotor, thingId, invokeEvent) { }
+ //public Motor(bool invokeEvent = true) : base(Type.UncontrolledMotor, invokeEvent) { }
+ public Motor(Thing parent) : base(Type.UncontrolledMotor, parent) { }
/// @brief Motor turning direction
public enum Direction {
diff --git a/src/Things/RelativeEncoder.cs b/src/Things/RelativeEncoder.cs
index 5183f91..d3bc8b7 100644
--- a/src/Things/RelativeEncoder.cs
+++ b/src/Things/RelativeEncoder.cs
@@ -1,4 +1,6 @@
+using NUnit.Framework;
+
namespace RoboidControl {
/// @brief An Incremental Encoder measures the rotations of an axle using a rotary
@@ -9,7 +11,12 @@ namespace RoboidControl {
/// full rotation
/// @param distancePerRevolution The distance a wheel travels per full
/// rotation
+ /*
public RelativeEncoder(bool invokeEvent = true) : base(Type.IncrementalEncoder, invokeEvent) { }
+ */
+ public RelativeEncoder(Thing parent = default) : base(Type.RelativeEncoder, parent) {
+
+ }
protected float _rotationSpeed = 0;
/// @brief Get the rotation speed since the previous call
diff --git a/src/Things/TemperatureSensor.cs b/src/Things/TemperatureSensor.cs
index 6475d06..ecf548e 100644
--- a/src/Things/TemperatureSensor.cs
+++ b/src/Things/TemperatureSensor.cs
@@ -6,6 +6,7 @@ namespace RoboidControl {
/// A temperature sensor
///
public class TemperatureSensor : Thing {
+ /*
///
/// Create a temperature sensor without communication abilities
///
@@ -18,14 +19,14 @@ namespace RoboidControl {
/// The ID of the thing
/// Invoke a OnNewThing event when the thing has been created
public TemperatureSensor(Participant owner, byte thingId = 0, bool invokeEvent = true) : base(owner, Type.TemperatureSensor, thingId, invokeEvent) { }
-
+ */
///
/// Create a new child temperature sensor
///
/// The parent thing
/// The ID of the thing, leave out or set to zero to generate an ID
/// Invoke a OnNewThing event when the thing has been created
- public TemperatureSensor(Thing parent, byte thingId = 0, bool invokeEvent = true) : base(parent, Type.TemperatureSensor, thingId, invokeEvent) { }
+ public TemperatureSensor(Thing parent) : base(Type.TemperatureSensor, parent) { }
///
/// The measured temperature
diff --git a/src/Things/TouchSensor.cs b/src/Things/TouchSensor.cs
index 2198e6e..e2db699 100644
--- a/src/Things/TouchSensor.cs
+++ b/src/Things/TouchSensor.cs
@@ -6,6 +6,7 @@ namespace RoboidControl {
/// A sensor which can detect touches
///
public class TouchSensor : Thing {
+ /*
///
/// Create a touch sensor without communication abilities
///
@@ -18,13 +19,14 @@ namespace RoboidControl {
/// The ID of the thing, leave out or set to zero to generate an ID
/// Invoke a OnNewThing event when the thing has been created
public TouchSensor(Participant owner, byte thingId = 0, bool invokeEvent = true) : base(owner, Type.TouchSensor, thingId, invokeEvent) { }
+ */
///
/// Create a new child touch sensor
///
/// The parent thing
/// The ID of the thing, leave out or set to zero to generate an ID
/// Invoke a OnNewThing event when the thing has been created
- public TouchSensor(Thing parent, byte thingId = 0, bool invokeEvent = true) : base(parent, Type.TouchSensor, thingId, invokeEvent) {
+ public TouchSensor(Thing parent) : base(Type.TouchSensor, parent) {
this.name = "TouchSensor";
}
diff --git a/test/UnitTest1.cs b/test/UnitTest1.cs
index 46a3864..9fc8f79 100644
--- a/test/UnitTest1.cs
+++ b/test/UnitTest1.cs
@@ -65,7 +65,7 @@ namespace RoboidControl.test {
public void Test_ThingMsg() {
SiteServer siteServer = new(7681);
ParticipantUDP participant = new("127.0.0.1", 7681, 7682);
- Thing thing = new(participant) {
+ Thing thing = new() {
name = "First Thing",
modelUrl = "https://passer.life/extras/ant.jpg"
};