diff --git a/.gitignore b/.gitignore
index 2602af4..3a21083 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,5 @@
DoxyGen/DoxyWarnLogfile.txt
.vscode/settings.json
-test/bin
-test/obj
-/bin
-/obj
+**bin
+**obj
**.meta
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..ee82cc1
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,14 @@
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "C#: BB2B Debug",
+ "type": "dotnet",
+ "request": "launch",
+ "projectPath": "${workspaceFolder}/Examples/BB2B/BB2B.csproj"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Examples/BB2B/BB2B.csproj b/Examples/BB2B/BB2B.csproj
new file mode 100644
index 0000000..3499cad
--- /dev/null
+++ b/Examples/BB2B/BB2B.csproj
@@ -0,0 +1,11 @@
+
+
+
+ Exe
+ net5.0
+
+
+
+
+
+
diff --git a/Examples/BB2B/Program.cs b/Examples/BB2B/Program.cs
new file mode 100644
index 0000000..d30d335
--- /dev/null
+++ b/Examples/BB2B/Program.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Diagnostics;
+using System.Threading;
+using RoboidControl;
+
+class BB2B {
+ static void Main() {
+ // The robot's propulsion is a differential drive
+ DifferentialDrive bb2b = new DifferentialDrive();
+ // Is has a touch sensor at the front left of the roboid
+ TouchSensor touchLeft = new TouchSensor(bb2b);
+ // and other one on the right
+ TouchSensor touchRight = new TouchSensor(bb2b);
+
+ // Do forever:
+ while (true) {
+ Console.Write("A");
+ // The left wheel turns forward when nothing is touched on the right side
+ // and turn backward when the roboid hits something on the right
+ float leftWheelSpeed = (touchRight.touchedSomething) ? -600.0f : 600.0f;
+ // The right wheel does the same, but instead is controlled by
+ // touches on the left side
+ float rightWheelSpeed = (touchLeft.touchedSomething) ? -600.0f : 600.0f;
+ // When both sides are touching something, both wheels will turn backward
+ // and the roboid will move backwards
+ bb2b.SetWheelVelocity(leftWheelSpeed, rightWheelSpeed);
+
+ // Update the roboid state
+ bb2b.Update(true);
+
+ // and sleep for 100ms
+ Thread.Sleep(100);
+ }
+ }
+}
\ No newline at end of file
diff --git a/LinearAlgebra/Angle.cs.meta b/LinearAlgebra/Angle.cs.meta
deleted file mode 100644
index 2b65666..0000000
--- a/LinearAlgebra/Angle.cs.meta
+++ /dev/null
@@ -1,2 +0,0 @@
-fileFormatVersion: 2
-guid: ee99a6777ed47f743be8068c6ede98c8
\ No newline at end of file
diff --git a/LinearAlgebra/Direction.cs.meta b/LinearAlgebra/Direction.cs.meta
deleted file mode 100644
index 206e1a6..0000000
--- a/LinearAlgebra/Direction.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 9975e4702de32624e8d3deaf84669f2f
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/LinearAlgebra/Quat32.cs.meta b/LinearAlgebra/Quat32.cs.meta
deleted file mode 100644
index c3f81a4..0000000
--- a/LinearAlgebra/Quat32.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 96aa3cf18eaeb574d9265704d68000da
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/LinearAlgebra/Spherical.cs.meta b/LinearAlgebra/Spherical.cs.meta
deleted file mode 100644
index 5ba10b9..0000000
--- a/LinearAlgebra/Spherical.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 33f05ee51ff6f7042b3e22723bcfc4f5
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/LinearAlgebra/SwingTwist.cs.meta b/LinearAlgebra/SwingTwist.cs.meta
deleted file mode 100644
index 0c64209..0000000
--- a/LinearAlgebra/SwingTwist.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 003a6ec763b101642b0589486f087aef
-MonoImporter:
- externalObjects: {}
- serializedVersion: 2
- defaultReferences: []
- executionOrder: 0
- icon: {instanceID: 0}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/RoboidControl.sln b/RoboidControl.sln
new file mode 100644
index 0000000..daf2834
--- /dev/null
+++ b/RoboidControl.sln
@@ -0,0 +1,39 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31903.59
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test", "test\test.csproj", "{B65BB41E-5A93-46FC-BA68-B865F50D57BD}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{D6086F71-404B-4D18-BBE9-45947ED33DB2}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BB2B", "Examples\BB2B\BB2B.csproj", "{488F28B2-A2CC-4E32-8D3B-7DB4EB1485F9}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RoboidControl", "src\RoboidControl.csproj", "{72BFCD03-FA78-4D0B-8B36-32301D60D6DD}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B65BB41E-5A93-46FC-BA68-B865F50D57BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B65BB41E-5A93-46FC-BA68-B865F50D57BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B65BB41E-5A93-46FC-BA68-B865F50D57BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B65BB41E-5A93-46FC-BA68-B865F50D57BD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {488F28B2-A2CC-4E32-8D3B-7DB4EB1485F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {488F28B2-A2CC-4E32-8D3B-7DB4EB1485F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {488F28B2-A2CC-4E32-8D3B-7DB4EB1485F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {488F28B2-A2CC-4E32-8D3B-7DB4EB1485F9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {72BFCD03-FA78-4D0B-8B36-32301D60D6DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {72BFCD03-FA78-4D0B-8B36-32301D60D6DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {72BFCD03-FA78-4D0B-8B36-32301D60D6DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {72BFCD03-FA78-4D0B-8B36-32301D60D6DD}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {488F28B2-A2CC-4E32-8D3B-7DB4EB1485F9} = {D6086F71-404B-4D18-BBE9-45947ED33DB2}
+ EndGlobalSection
+EndGlobal
diff --git a/LinearAlgebra/Angle.cs b/src/LinearAlgebra/Angle.cs
similarity index 100%
rename from LinearAlgebra/Angle.cs
rename to src/LinearAlgebra/Angle.cs
diff --git a/LinearAlgebra/Direction.cs b/src/LinearAlgebra/Direction.cs
similarity index 100%
rename from LinearAlgebra/Direction.cs
rename to src/LinearAlgebra/Direction.cs
diff --git a/LinearAlgebra/Matrix.cs b/src/LinearAlgebra/Matrix.cs
similarity index 100%
rename from LinearAlgebra/Matrix.cs
rename to src/LinearAlgebra/Matrix.cs
diff --git a/LinearAlgebra/Quat32.cs b/src/LinearAlgebra/Quat32.cs
similarity index 100%
rename from LinearAlgebra/Quat32.cs
rename to src/LinearAlgebra/Quat32.cs
diff --git a/LinearAlgebra/Quaternion.cs b/src/LinearAlgebra/Quaternion.cs
similarity index 100%
rename from LinearAlgebra/Quaternion.cs
rename to src/LinearAlgebra/Quaternion.cs
diff --git a/LinearAlgebra/Spherical.cs b/src/LinearAlgebra/Spherical.cs
similarity index 100%
rename from LinearAlgebra/Spherical.cs
rename to src/LinearAlgebra/Spherical.cs
diff --git a/LinearAlgebra/SwingTwist.cs b/src/LinearAlgebra/SwingTwist.cs
similarity index 100%
rename from LinearAlgebra/SwingTwist.cs
rename to src/LinearAlgebra/SwingTwist.cs
diff --git a/LinearAlgebra/Vector2.cs b/src/LinearAlgebra/Vector2.cs
similarity index 100%
rename from LinearAlgebra/Vector2.cs
rename to src/LinearAlgebra/Vector2.cs
diff --git a/LinearAlgebra/Vector3.cs b/src/LinearAlgebra/Vector3.cs
similarity index 100%
rename from LinearAlgebra/Vector3.cs
rename to src/LinearAlgebra/Vector3.cs
diff --git a/LinearAlgebra/float16.cs b/src/LinearAlgebra/float16.cs
similarity index 100%
rename from LinearAlgebra/float16.cs
rename to src/LinearAlgebra/float16.cs
diff --git a/Participant.cs b/src/LocalParticipant.cs
similarity index 83%
rename from Participant.cs
rename to src/LocalParticipant.cs
index 175dbe5..3350485 100644
--- a/Participant.cs
+++ b/src/LocalParticipant.cs
@@ -9,7 +9,7 @@ namespace RoboidControl {
///
/// A participant is used for communcation between things
///
- public class Participant : RemoteParticipant {
+ public class LocalParticipant : Participant {
public byte[] buffer = new byte[1024];
public ulong publishInterval = 3000; // = 3 seconds
@@ -26,7 +26,7 @@ namespace RoboidControl {
///
/// Create a porticiapnt
///
- public Participant() {
+ public LocalParticipant() {
//senders.Add(this);
}
@@ -34,16 +34,16 @@ namespace RoboidControl {
/// Create a participant with the give UDP port
///
/// The port number on which to communicate
- // public Participant(int port) : this() {
- // this.port = port;
- // }
+ public LocalParticipant(int port) : this() {
+ this.port = port;
+ }
///
/// Create a new participant for a site at the given address and port
///
/// The ip address of the site server
/// The port number of the site server
- public Participant(string ipAddress = "0.0.0.0", int port = 7681) : this() {
+ public LocalParticipant(string ipAddress = "0.0.0.0", int port = 7681) : this() {
this.ipAddress = ipAddress;
this.port = port;
@@ -61,35 +61,42 @@ namespace RoboidControl {
///
/// UDP client to use for communication
/// The port number on which to communicate
- public Participant(UdpClient udpClient, int port) : this() {
+ public LocalParticipant(UdpClient udpClient, int port) : this() {
this.udpClient = udpClient;
this.port = port;
}
- public List owners = new List();
+ private static LocalParticipant isolatedParticipant = null;
+ public static LocalParticipant Isolated() {
+ if (isolatedParticipant == null)
+ isolatedParticipant = new LocalParticipant(0);
+ return isolatedParticipant;
+ }
- public RemoteParticipant GetParticipant(string ipAddress, int port) {
+ public List owners = new List();
+
+ public Participant GetParticipant(string ipAddress, int port) {
//Console.WriteLine($"Get Participant {ipAddress}:{port}");
- foreach (RemoteParticipant sender in owners) {
+ foreach (Participant sender in owners) {
if (sender.ipAddress == ipAddress && sender.port == port)
return sender;
}
return null;
}
- public RemoteParticipant AddParticipant(string ipAddress, int port) {
+ public Participant AddParticipant(string ipAddress, int port) {
Console.WriteLine($"New Participant {ipAddress}:{port}");
- RemoteParticipant participant = new(ipAddress, port) {
+ Participant participant = new(ipAddress, port) {
networkId = (byte)(this.owners.Count + 1)
};
owners.Add(participant);
return participant;
}
- protected readonly Dictionary> thingMsgProcessors = new();
+ protected readonly Dictionary> thingMsgProcessors = new();
- public delegate Thing ThingConstructor(RemoteParticipant sender, byte networkId, byte thingId);
+ public delegate Thing ThingConstructor(Participant sender, byte networkId, byte thingId);
public void Register(byte thingType, ThingConstructor constr) {
- thingMsgProcessors[thingType] = new Func(constr);
+ thingMsgProcessors[thingType] = new Func(constr);
}
public void Register(Thing.Type thingType) where ThingClass : Thing {
@@ -118,7 +125,7 @@ namespace RoboidControl {
// We can receive our own publish (broadcast) packages. How do we recognize them????
// It is hard to determine our source port
string ipAddress = this.endPoint.Address.ToString();
- RemoteParticipant remoteParticipant = GetParticipant(ipAddress, this.endPoint.Port);
+ Participant remoteParticipant = GetParticipant(ipAddress, this.endPoint.Port);
remoteParticipant ??= AddParticipant(ipAddress, this.endPoint.Port);
ReceiveData(data, remoteParticipant);
@@ -161,7 +168,7 @@ namespace RoboidControl {
#region Send
- public void SendThingInfo(RemoteParticipant remoteParticipant, Thing thing) {
+ public void SendThingInfo(Participant remoteParticipant, Thing thing) {
Console.WriteLine("Send thing info");
this.Send(remoteParticipant, new ThingMsg(this.networkId, thing));
this.Send(remoteParticipant, new NameMsg(this.networkId, thing));
@@ -169,7 +176,7 @@ namespace RoboidControl {
this.Send(remoteParticipant, new BinaryMsg(this.networkId, thing));
}
- public bool Send(RemoteParticipant remoteParticipant, IMessage msg) {
+ public bool Send(Participant remoteParticipant, IMessage msg) {
int bufferSize = msg.Serialize(ref this.buffer);
if (bufferSize <= 0)
return true;
@@ -220,7 +227,7 @@ namespace RoboidControl {
#region Receive
- public void ReceiveData(byte[] data, RemoteParticipant remoteParticipant) {
+ public void ReceiveData(byte[] data, Participant remoteParticipant) {
byte msgId = data[0];
if (msgId == 0xFF) {
// Timeout
@@ -268,9 +275,9 @@ namespace RoboidControl {
#region Process
- protected virtual void Process(RemoteParticipant sender, ParticipantMsg msg) { }
+ protected virtual void Process(Participant sender, ParticipantMsg msg) { }
- protected virtual void Process(RemoteParticipant sender, NetworkIdMsg msg) {
+ protected virtual void Process(Participant sender, NetworkIdMsg msg) {
Console.WriteLine($"{this.name} receive network id {this.networkId} {msg.networkId}");
if (this.networkId != msg.networkId) {
this.networkId = msg.networkId;
@@ -279,27 +286,27 @@ namespace RoboidControl {
}
}
- protected virtual void Process(RemoteParticipant sender, InvestigateMsg msg) { }
+ protected virtual void Process(Participant sender, InvestigateMsg msg) { }
- protected virtual void Process(RemoteParticipant sender, ThingMsg msg) {
+ protected virtual void Process(Participant sender, ThingMsg msg) {
//Console.WriteLine($"Participant: Process thing [{msg.networkId}/{msg.thingId}]");
}
- protected virtual void Process(RemoteParticipant sender, NameMsg msg) {
+ protected virtual void Process(Participant sender, NameMsg msg) {
//Console.WriteLine($"Participant: Process name [{msg.networkId}/{msg.thingId}] {msg.name}");
Thing thing = sender.Get(msg.networkId, msg.thingId);
if (thing != null)
thing.name = msg.name;
}
- protected virtual void Process(RemoteParticipant sender, ModelUrlMsg msg) {
+ protected virtual void Process(Participant sender, ModelUrlMsg msg) {
//Console.WriteLine($"Participant: Process model [{msg.networkId}/{msg.thingId}] {msg.url}");
Thing thing = sender.Get(msg.networkId, msg.thingId);
if (thing != null)
thing.modelUrl = msg.url;
}
- protected virtual void Process(RemoteParticipant sender, PoseMsg msg) {
+ protected virtual void Process(Participant sender, PoseMsg msg) {
//Console.WriteLine($"Participant: Process pose [{msg.networkId}/{msg.thingId}] {msg.poseType}");
Thing thing = sender.Get(msg.networkId, msg.thingId);
if (thing != null) {
@@ -320,15 +327,15 @@ namespace RoboidControl {
}
}
- protected virtual void Process(RemoteParticipant sender, BinaryMsg msg) {
+ protected virtual void Process(Participant sender, BinaryMsg msg) {
// Console.WriteLine($"Participant: Process binary [{msg.networkId}/{msg.thingId}]");
Thing thing = sender.Get(msg.networkId, msg.thingId);
thing?.ProcessBinary(msg.bytes);
}
- protected virtual void Process(RemoteParticipant sender, TextMsg temsgxt) { }
+ protected virtual void Process(Participant sender, TextMsg temsgxt) { }
- protected virtual void Process(RemoteParticipant sender, DestroyMsg msg) { }
+ protected virtual void Process(Participant sender, DestroyMsg msg) { }
private void ForwardMessage(IMessage msg) {
// foreach (Participant client in senders) {
diff --git a/Messages/BinaryMsg.cs b/src/Messages/BinaryMsg.cs
similarity index 100%
rename from Messages/BinaryMsg.cs
rename to src/Messages/BinaryMsg.cs
diff --git a/Messages/DestroyMsg.cs b/src/Messages/DestroyMsg.cs
similarity index 100%
rename from Messages/DestroyMsg.cs
rename to src/Messages/DestroyMsg.cs
diff --git a/Messages/InvestigateMsg.cs b/src/Messages/InvestigateMsg.cs
similarity index 100%
rename from Messages/InvestigateMsg.cs
rename to src/Messages/InvestigateMsg.cs
diff --git a/Messages/LowLevelMessages.cs b/src/Messages/LowLevelMessages.cs
similarity index 100%
rename from Messages/LowLevelMessages.cs
rename to src/Messages/LowLevelMessages.cs
diff --git a/Messages/Messages.cs b/src/Messages/Messages.cs
similarity index 100%
rename from Messages/Messages.cs
rename to src/Messages/Messages.cs
diff --git a/Messages/ModelUrlMsg.cs b/src/Messages/ModelUrlMsg.cs
similarity index 100%
rename from Messages/ModelUrlMsg.cs
rename to src/Messages/ModelUrlMsg.cs
diff --git a/Messages/NameMsg.cs b/src/Messages/NameMsg.cs
similarity index 100%
rename from Messages/NameMsg.cs
rename to src/Messages/NameMsg.cs
diff --git a/Messages/NetworkIdMsg.cs b/src/Messages/NetworkIdMsg.cs
similarity index 100%
rename from Messages/NetworkIdMsg.cs
rename to src/Messages/NetworkIdMsg.cs
diff --git a/Messages/ParticipantMsg.cs b/src/Messages/ParticipantMsg.cs
similarity index 100%
rename from Messages/ParticipantMsg.cs
rename to src/Messages/ParticipantMsg.cs
diff --git a/Messages/PoseMsg.cs b/src/Messages/PoseMsg.cs
similarity index 100%
rename from Messages/PoseMsg.cs
rename to src/Messages/PoseMsg.cs
diff --git a/Messages/TextMsg.cs b/src/Messages/TextMsg.cs
similarity index 100%
rename from Messages/TextMsg.cs
rename to src/Messages/TextMsg.cs
diff --git a/Messages/ThingMsg.cs b/src/Messages/ThingMsg.cs
similarity index 100%
rename from Messages/ThingMsg.cs
rename to src/Messages/ThingMsg.cs
diff --git a/RemoteParticipant.cs b/src/Participant.cs
similarity index 94%
rename from RemoteParticipant.cs
rename to src/Participant.cs
index ee5a0b9..53f637e 100644
--- a/RemoteParticipant.cs
+++ b/src/Participant.cs
@@ -6,7 +6,7 @@ namespace RoboidControl {
///
/// A reference to a participant, possibly on a remote location
///
- public class RemoteParticipant {
+ public class Participant {
///
/// The internet address of the participant
///
@@ -24,13 +24,13 @@ namespace RoboidControl {
///
/// Default constructor
///
- public RemoteParticipant() {}
+ public Participant() { }
///
/// Create a new remote participant
///
/// The IP address of the participant
/// The UDP port of the participant
- public RemoteParticipant(string ipAddress, int port) {
+ public Participant(string ipAddress, int port) {
this.ipAddress = ipAddress;
this.port = port;
}
@@ -68,7 +68,8 @@ namespace RoboidControl {
if (invokeEvent)
Thing.InvokeNewThing(thing);
// Console.Write($"Add thing {ipAddress}:{port}[{networkId}/{thing.id}]");
- } else {
+ }
+ else {
if (thing != foundThing) {
// should be: find first non-existing id...
thing.id = (byte)this.things.Count;
diff --git a/ControlCore.csproj b/src/RoboidControl.csproj
similarity index 100%
rename from ControlCore.csproj
rename to src/RoboidControl.csproj
diff --git a/SiteServer.cs b/src/SiteServer.cs
similarity index 87%
rename from SiteServer.cs
rename to src/SiteServer.cs
index ab21e80..ce2d178 100644
--- a/SiteServer.cs
+++ b/src/SiteServer.cs
@@ -7,7 +7,7 @@ namespace RoboidControl {
///
/// A site server is a participant which provides a shared simulated environment
///
- public class SiteServer : Participant {
+ public class SiteServer : LocalParticipant {
public SiteServer(int port = 7681) : this("0.0.0.0", port) { }
@@ -28,7 +28,7 @@ namespace RoboidControl {
this.udpClient.BeginReceive(
new AsyncCallback(result => ReceiveUDP(result)),
new Tuple(this.udpClient, new(IPAddress.Any, port)));
-
+
Register(Thing.Type.TouchSensor);
}
@@ -42,21 +42,21 @@ namespace RoboidControl {
public override void Publish() {
}
- protected override void Process(RemoteParticipant remoteParticipant, ParticipantMsg msg) {
+ protected override void Process(Participant remoteParticipant, ParticipantMsg msg) {
if (msg.networkId == 0) {
Console.WriteLine($"{this.name} received New Client -> {remoteParticipant.networkId}");
this.Send(remoteParticipant, new NetworkIdMsg(remoteParticipant.networkId));
}
}
- protected override void Process(RemoteParticipant sender, NetworkIdMsg msg) { }
+ protected override void Process(Participant sender, NetworkIdMsg msg) { }
- protected override void Process(RemoteParticipant sender, ThingMsg msg) {
+ protected override void Process(Participant sender, ThingMsg msg) {
//Console.WriteLine($"SiteServer: Process thing [{msg.networkId}/{msg.thingId}]");
Thing thing = sender.Get(msg.networkId, msg.thingId);
if (thing == null) {
Thing newThing = null;
- if (thingMsgProcessors.TryGetValue(msg.thingType, out Func msgProcessor)) {
+ if (thingMsgProcessors.TryGetValue(msg.thingType, out Func msgProcessor)) {
//Console.WriteLine("Found thing message processor");
if (msgProcessor != null)
newThing = msgProcessor(sender, msg.networkId, msg.thingId);
diff --git a/Thing.cs b/src/Thing.cs
similarity index 88%
rename from Thing.cs
rename to src/Thing.cs
index f87f81d..3f12b62 100644
--- a/Thing.cs
+++ b/src/Thing.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using Passer.LinearAlgebra;
namespace RoboidControl {
@@ -12,28 +13,6 @@ namespace RoboidControl {
#region Types
- #endregion Types
-
- #region Properties
-
- public delegate void ChangeHandler();
- public delegate void SphericalHandler(Spherical v);
- public delegate void ThingHandler(Thing t);
-
- ///
- /// The participant to which this thing belongs
- ///
- public RemoteParticipant owner;
-
- ///
- /// The network ID of this thing.
- ///
- public byte networkId;
- ///
- /// The ID of this thing
- ///
- public byte id;
-
///
/// Predefined thing types
///
@@ -54,6 +33,81 @@ namespace RoboidControl {
Humanoid,
ExternalSensor
};
+
+ #endregion Types
+
+ #region Init
+
+ public Thing(byte thingType = (byte)Type.Undetermined) : this(LocalParticipant.Isolated(), thingType) {
+ }
+
+ public Thing(Participant owner, byte thingType = (byte)Type.Undetermined) {
+ this.owner = owner;
+ this.type = thingType;
+ }
+
+ public Thing(Thing parent, byte thingType = (byte)Type.Undetermined) : this(parent.owner, thingType) {
+ this.parent = parent;
+ }
+
+ ///
+ /// Create a new thing for the given participant
+ ///
+ /// The participant for which this thing is created
+ /// True when a new thing event should be triggered
+ public Thing(Participant owner, bool invokeEvent = false) {
+ this.owner = owner;
+ //owner.Add(this);
+ if (invokeEvent)
+ InvokeNewThing(this);
+ }
+ ///
+ /// Create a new thing for the given participant
+ ///
+ /// The participant for which this thing is created
+ /// The network ID of the thing
+ /// The ID of the thing
+ /// The type of thing
+ public Thing(Participant participant, byte networkId, byte thingId, byte thingType = 0) {
+ this.owner = participant;
+ this.id = thingId;
+ this.type = thingType;
+ this.networkId = networkId;
+ }
+
+ ///
+ /// Function which can be used to create components in external engines.
+ ///
+ /// Currently this is used to create GameObjects in Unity
+ public virtual void CreateComponent() {
+#if UNITY_5_3_OR_NEWER
+ this.component = Unity.Thing.Create(this);
+ this.component.core = this;
+#endif
+ }
+
+ #endregion Init
+
+ #region Properties
+
+ public delegate void ChangeHandler();
+ public delegate void SphericalHandler(Spherical v);
+ public delegate void ThingHandler(Thing t);
+
+ ///
+ /// The participant to which this thing belongs
+ ///
+ public Participant owner;
+
+ ///
+ /// The network ID of this thing.
+ ///
+ public byte networkId;
+ ///
+ /// The ID of this thing
+ ///
+ public byte id;
+
///
/// The type of this thing. This can be either a Thing::Type (needs casting)
/// or a byte value for custom types.
@@ -201,62 +255,30 @@ namespace RoboidControl {
#endregion Properties
- #region Init
-
- ///
- /// Create a new thing for the given participant
- ///
- /// The participant for which this thing is created
- /// True when a new thing event should be triggered
- public Thing(RemoteParticipant owner, bool invokeEvent = false) {
- this.owner = owner;
- //owner.Add(this);
- if (invokeEvent)
- InvokeNewThing(this);
- }
- ///
- /// Create a new thing for the given participant
- ///
- /// The participant for which this thing is created
- /// The network ID of the thing
- /// The ID of the thing
- /// The type of thing
- public Thing(RemoteParticipant participant, byte networkId, byte thingId, byte thingType = 0) {
- this.owner = participant;
- this.id = thingId;
- this.type = thingType;
- this.networkId = networkId;
- }
-
- ///
- /// Function which can be used to create components in external engines.
- ///
- /// Currently this is used to create GameObjects in Unity
- public virtual void CreateComponent() {
-#if UNITY_5_3_OR_NEWER
- this.component = Unity.Thing.Create(this);
- this.component.core = this;
-#endif
- }
-
- #endregion Init
-
#region Update
-#if UNITY_5_3_OR_NEWER
+ // #if UNITY_5_3_OR_NEWER
///
/// Convience function for use in Unity which removes the need for a currentTime argument
///
- public void Update() {
- Update((ulong)UnityEngine.Time.time * 1000);
+ public void Update(bool recursive = false) {
+ Update(TimeManager.GetCurrentTimeMilliseconds(), recursive);
}
-#endif
+ // #endif
///
/// Update this thing
///
/// The current time in milliseconds
- public virtual void Update(ulong currentTime) {
+ public virtual void Update(ulong currentTimeMs, bool recursive = false) {
// should recurse over children...
+ if (recursive) {
+ for (byte childIx = 0; childIx < this.children.Count; childIx++) {
+ Thing child = this.children[childIx];
+ if (child == null)
+ continue;
+ child.Update(currentTimeMs, recursive);
+ }
+ }
}
///
diff --git a/src/Things/DifferentialDrive.cs b/src/Things/DifferentialDrive.cs
new file mode 100644
index 0000000..8dcfb2e
--- /dev/null
+++ b/src/Things/DifferentialDrive.cs
@@ -0,0 +1,51 @@
+namespace RoboidControl {
+
+ /// @brief A thing which can move itself using a differential drive system
+ ///
+ /// @sa @link https://en.wikipedia.org/wiki/Differential_wheeled_robot @endlink
+ public class DifferentialDrive : Thing {
+ /// @brief Create a differential drive without networking support
+ public DifferentialDrive() { }
+ /// @brief Create a differential drive with networking support
+ /// @param participant The local participant
+ public DifferentialDrive(LocalParticipant participant) : base(participant, false) { }
+
+ /// @brief Configures the dimensions of the drive
+ /// @param wheelDiameter The diameter of the wheels in meters
+ /// @param wheelSeparation The distance between the wheels in meters
+ ///
+ /// These values are used to compute the desired wheel speed from the set
+ /// linear and angular velocity.
+ /// @sa SetLinearVelocity SetAngularVelocity
+ public void SetDriveDimensions(float wheelDiameter, float wheelSeparation) { }
+ /// @brief Congures the motors for the wheels
+ /// @param leftWheel The motor for the left wheel
+ /// @param rightWheel The motor for the right wheel
+ public void SetMotors(Thing leftWheel, Thing rightWheel) { }
+
+ /// @brief Directly specify the speeds of the motors
+ /// @param speedLeft The speed of the left wheel in degrees per second.
+ /// Positive moves the robot in the forward direction.
+ /// @param speedRight The speed of the right wheel in degrees per second.
+ /// Positive moves the robot in the forward direction.
+
+ public void SetWheelVelocity(float speedLeft, float speedRight) { }
+
+ /// @copydoc RoboidControl::Thing::Update(unsigned long)
+ public override void Update(ulong currentMs, bool recursive = true) { }
+
+ /// @brief The radius of a wheel in meters
+ protected float wheelRadius = 1.0f;
+ /// @brief The distance between the wheels in meters
+ protected float wheelSeparation = 1.0f;
+
+ /// @brief Convert revolutions per second to meters per second
+ protected float rpsToMs = 1.0f;
+
+ /// @brief The left wheel
+ protected Thing leftWheel = null;
+ /// @brief The right wheel
+ protected Thing rightWheel = null;
+ };
+
+} // namespace RoboidControl
\ No newline at end of file
diff --git a/Sensors/DistanceSensor.cs b/src/Things/DistanceSensor.cs
similarity index 85%
rename from Sensors/DistanceSensor.cs
rename to src/Things/DistanceSensor.cs
index ade3998..c83d940 100644
--- a/Sensors/DistanceSensor.cs
+++ b/src/Things/DistanceSensor.cs
@@ -13,14 +13,14 @@ namespace RoboidControl {
/// Constructor for a new distance sensor
///
/// The participant for which the sensor is needed
- public DistanceSensor(RemoteParticipant participant) : base(participant, true) { }
+ public DistanceSensor(Participant participant) : base(participant, true) { }
///
/// 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(RemoteParticipant participant, byte networkId, byte thingId) : base(participant, networkId, thingId, (byte)Type.TemperatureSensor) {
+ public DistanceSensor(Participant participant, byte networkId, byte thingId) : base(participant, networkId, thingId, (byte)Type.TemperatureSensor) {
}
#if UNITY_5_3_OR_NEWER
diff --git a/Sensors/TemperatureSensor.cs b/src/Things/TemperatureSensor.cs
similarity index 86%
rename from Sensors/TemperatureSensor.cs
rename to src/Things/TemperatureSensor.cs
index b0d6860..6f7e009 100644
--- a/Sensors/TemperatureSensor.cs
+++ b/src/Things/TemperatureSensor.cs
@@ -17,7 +17,7 @@ namespace RoboidControl {
/// The participant for with the sensor is needed
/// The network ID of the sensor
/// The ID of the thing
- public TemperatureSensor(Participant participant, byte networkId, byte thingId) : base(participant, networkId, thingId, (byte)Type.TemperatureSensor) {}
+ public TemperatureSensor(LocalParticipant participant, byte networkId, byte thingId) : base(participant, networkId, thingId, (byte)Type.TemperatureSensor) { }
///
/// Function to extract the temperature received in the binary message
diff --git a/Sensors/TouchSensor.cs b/src/Things/TouchSensor.cs
similarity index 80%
rename from Sensors/TouchSensor.cs
rename to src/Things/TouchSensor.cs
index 1474e4a..22dc290 100644
--- a/Sensors/TouchSensor.cs
+++ b/src/Things/TouchSensor.cs
@@ -7,7 +7,25 @@ namespace RoboidControl {
///
public class TouchSensor : Thing {
- public Participant thisParticipant;
+ ///
+ /// Create a touch sensor
+ ///
+ /// The participant for with the sensor is needed
+ /// True when the creation should trigger an event
+ public TouchSensor(Participant owner, bool invokeEvent = true) : base(owner, invokeEvent) {
+ //touchedSomething = false;
+ //thisParticipant = owner;
+ }
+
+ public TouchSensor(Participant owner, byte networkId, byte thingId) : base(owner, networkId, thingId) {
+ Console.Write("TouchSensor constructor");
+ //touchedSomething = false;
+ //thisParticipant = participant;
+ }
+
+ public TouchSensor(Thing parent) : base(parent) { }
+
+ public LocalParticipant thisParticipant;
///
/// Value which is true when the sensor is touching something, false otherwise
@@ -18,30 +36,14 @@ namespace RoboidControl {
get { return _touchedSomething; }
set {
_touchedSomething = value;
- if (thisParticipant != null && this.owner != thisParticipant ) {
+ if (thisParticipant != null && this.owner != thisParticipant) {
BinaryMsg msg = new(networkId, this);
- foreach (RemoteParticipant remoteParticipant in thisParticipant.owners)
+ foreach (Participant remoteParticipant in thisParticipant.owners)
thisParticipant.Send(remoteParticipant, msg);
}
}
}
- ///
- /// Create a touch sensor
- ///
- /// The participant for with the sensor is needed
- /// True when the creation should trigger an event
- public TouchSensor(RemoteParticipant owner, bool invokeEvent = true) : base(owner, invokeEvent) {
- //touchedSomething = false;
- //thisParticipant = owner;
- }
-
- public TouchSensor(RemoteParticipant owner, byte networkId, byte thingId) : base(owner, networkId, thingId) {
- Console.Write("TouchSensor constructor");
- //touchedSomething = false;
- //thisParticipant = participant;
- }
-
#if UNITY_5_3_OR_NEWER
/// @copydoc Passer::RoboidControl::Thing::CreateComponent
public override void CreateComponent() {
diff --git a/src/TimeManger.cs b/src/TimeManger.cs
new file mode 100644
index 0000000..875f459
--- /dev/null
+++ b/src/TimeManger.cs
@@ -0,0 +1,22 @@
+using System.Diagnostics;
+
+namespace RoboidControl {
+ public static class TimeManager {
+ private static readonly Stopwatch _stopwatch = new Stopwatch();
+
+ ///
+ /// Static constructor to start the stopwatch
+ ///
+ static TimeManager() {
+ _stopwatch.Start();
+ }
+
+ ///
+ /// Method to get the current time in milliseconds
+ ///
+ /// The current time in milliseconds
+ public static ulong GetCurrentTimeMilliseconds() {
+ return (ulong)_stopwatch.ElapsedMilliseconds;
+ }
+ }
+}
\ No newline at end of file
diff --git a/test.meta b/test.meta
deleted file mode 100644
index 89fd01d..0000000
--- a/test.meta
+++ /dev/null
@@ -1,8 +0,0 @@
-fileFormatVersion: 2
-guid: 239400f5314a5aa4bac98db5861f77a7
-folderAsset: yes
-DefaultImporter:
- externalObjects: {}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/test.sln b/test.sln
deleted file mode 100644
index 5ab05c5..0000000
--- a/test.sln
+++ /dev/null
@@ -1,36 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 17
-VisualStudioVersion = 17.0.31903.59
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCore", "ControlCore.csproj", "{F2DEE6B0-AF41-454E-AAC8-9E1E3ACC769F}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test", "test\test.csproj", "{2C350E2B-9DDA-4037-BAE5-E12AB7A52398}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {6601071A-9E9C-42E1-95EA-0A36C5D718E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6601071A-9E9C-42E1-95EA-0A36C5D718E4}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6601071A-9E9C-42E1-95EA-0A36C5D718E4}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {6601071A-9E9C-42E1-95EA-0A36C5D718E4}.Release|Any CPU.Build.0 = Release|Any CPU
- {DD7238DA-DBEF-4D6A-98DB-6FE28BBDB75D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {DD7238DA-DBEF-4D6A-98DB-6FE28BBDB75D}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {DD7238DA-DBEF-4D6A-98DB-6FE28BBDB75D}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {DD7238DA-DBEF-4D6A-98DB-6FE28BBDB75D}.Release|Any CPU.Build.0 = Release|Any CPU
- {F2DEE6B0-AF41-454E-AAC8-9E1E3ACC769F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {F2DEE6B0-AF41-454E-AAC8-9E1E3ACC769F}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {F2DEE6B0-AF41-454E-AAC8-9E1E3ACC769F}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {F2DEE6B0-AF41-454E-AAC8-9E1E3ACC769F}.Release|Any CPU.Build.0 = Release|Any CPU
- {2C350E2B-9DDA-4037-BAE5-E12AB7A52398}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {2C350E2B-9DDA-4037-BAE5-E12AB7A52398}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {2C350E2B-9DDA-4037-BAE5-E12AB7A52398}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {2C350E2B-9DDA-4037-BAE5-E12AB7A52398}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
-EndGlobal
diff --git a/test/UnitTest1.cs b/test/UnitTest1.cs
index be1bd9c..27012a9 100644
--- a/test/UnitTest1.cs
+++ b/test/UnitTest1.cs
@@ -5,7 +5,7 @@ using NUnit.Framework;
using RoboidControl;
-namespace ControlCore.test {
+namespace RoboidControl.test {
public class Tests {
[SetUp]
public void Setup() {
@@ -13,7 +13,7 @@ namespace ControlCore.test {
[Test]
public void Test_Participant() {
- Participant participant = new Participant("127.0.0.1", 7682);
+ LocalParticipant participant = new LocalParticipant("127.0.0.1", 7682);
ulong milliseconds = (ulong)DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
ulong startTime = milliseconds;
@@ -46,7 +46,7 @@ namespace ControlCore.test {
[Test]
public void Test_SiteParticipant() {
SiteServer siteServer = new SiteServer(7681);
- Participant participant = new Participant("127.0.0.1", 7681);
+ LocalParticipant participant = new LocalParticipant("127.0.0.1", 7681);
ulong milliseconds = (ulong)DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
ulong startTime = milliseconds;
@@ -64,8 +64,8 @@ namespace ControlCore.test {
[Test]
public void Test_ThingMsg() {
SiteServer siteServer = new SiteServer(7681);
- Participant participant = new Participant("127.0.0.1");
- Thing thing = new Thing(participant) {
+ LocalParticipant participant = new LocalParticipant("127.0.0.1");
+ Thing thing = new Thing(participant, false) {
name = "First Thing",
modelUrl = "https://passer.life/extras/ant.jpg"
};
diff --git a/test/test.csproj b/test/test.csproj
index 1c81788..309ab05 100644
--- a/test/test.csproj
+++ b/test/test.csproj
@@ -13,7 +13,7 @@
-
+