Compare commits

...

4 Commits

Author SHA1 Message Date
be167722e7 Improved network sync 2025-04-22 17:47:22 +02:00
86b12a7326 Static participant list 2025-04-22 12:00:27 +02:00
97fdd74950 Handle name msg 2025-04-22 09:39:42 +02:00
62cc00b694 Improved compatibility with C++ 2025-04-18 17:25:07 +02:00
10 changed files with 214 additions and 163 deletions

View File

@ -17,11 +17,9 @@ namespace RoboidControl.Unity {
[field: SerializeField] [field: SerializeField]
public RoboidControl.Thing core { get; set; } public RoboidControl.Thing core { get; set; }
private string modelUrl = null; public SiteServer participant;
// protected virtual void Awake() { private string modelUrl = null;
// core.OnPoseChanged += PoseChanged;
// }
/// <summary> /// <summary>
/// Set the core C# thing /// Set the core C# thing
@ -45,18 +43,22 @@ namespace RoboidControl.Unity {
new("Thing") : new("Thing") :
new(core.name); new(core.name);
Thing component = gameObj.AddComponent<Thing>(); Thing component = gameObj.AddComponent<Thing>();
component.Init(core);
return component;
}
component.core = core; protected void Init(RoboidControl.Thing core) {
this.core = core;
this.participant = FindAnyObjectByType<SiteServer>();
if (core.parent != null && core.parent.component != null) if (core.parent != null && core.parent.component != null)
gameObj.transform.SetParent(core.parent.component.transform, false); this.transform.SetParent(core.parent.component.transform, false);
if (core.position != null) if (core.position != null)
gameObj.transform.localPosition = core.position.ToVector3(); this.transform.localPosition = core.position.ToVector3();
if (core.orientation != null) if (core.orientation != null)
gameObj.transform.localRotation = core.orientation.ToQuaternion(); this.transform.localRotation = core.orientation.ToQuaternion();
core.OnPoseChanged += component.PoseChanged; core.OnPoseChanged += this.PoseChanged;
return component;
} }
/// <summary> /// <summary>
@ -74,7 +76,8 @@ namespace RoboidControl.Unity {
// this.transform.localPosition = core.position.ToVector3(); // this.transform.localPosition = core.position.ToVector3();
if (core.angularVelocity != null && core.angularVelocity.distance != 0) { if (core.angularVelocity != null && core.angularVelocity.distance != 0) {
Vector3 angularVelocity = core.angularVelocity.ToVector3(); // Vector3 angularVelocity = core.angularVelocity.ToVector3();
// Debug.Log(angularVelocity);
Vector3 axis = core.angularVelocity.direction.ToVector3(); Vector3 axis = core.angularVelocity.direction.ToVector3();
this.transform.localRotation *= Quaternion.AngleAxis(core.angularVelocity.distance * Time.deltaTime, axis); this.transform.localRotation *= Quaternion.AngleAxis(core.angularVelocity.distance * Time.deltaTime, axis);
//this.transform.localRotation *= Quaternion.Euler(angularVelocity * Time.deltaTime); //this.transform.localRotation *= Quaternion.Euler(angularVelocity * Time.deltaTime);
@ -90,10 +93,16 @@ namespace RoboidControl.Unity {
this.modelUrl = core.modelUrl; this.modelUrl = core.modelUrl;
} }
if (core.nameChanged) {
if (this.gameObject.name != core.name)
this.gameObject.name = core.name;
core.nameChanged = false;
}
} }
private void PoseChanged() { private void PoseChanged() {
// Debug.Log($"{this} pose changed"); //Debug.Log($"{this} pose changed");
if (core.positionUpdated) if (core.positionUpdated)
this.transform.localPosition = core.position.ToVector3(); this.transform.localPosition = core.position.ToVector3();
if (core.orientationUpdated) if (core.orientationUpdated)

View File

@ -8,7 +8,7 @@ namespace RoboidControl.Unity {
/// </summary> /// </summary>
public class TouchSensor : Thing { public class TouchSensor : Thing {
public SiteServer participant; // public SiteServer participant;
/// <summary> /// <summary>
/// The core touch sensor /// The core touch sensor
/// </summary> /// </summary>
@ -24,18 +24,6 @@ namespace RoboidControl.Unity {
participant = FindAnyObjectByType<SiteServer>(); participant = FindAnyObjectByType<SiteServer>();
SetCoreThing(new RoboidControl.TouchSensor(participant.site)); SetCoreThing(new RoboidControl.TouchSensor(participant.site));
} }
// Somehow this does not work.
// Rigidbody rb = GetComponentInParent<Rigidbody>();
// if (rb == null) {
// RoboidControl.Thing thing = core;
// while (thing.parent != null)
// thing = thing.parent;
// Thing unityThing = thing.component;
// rb = unityThing.gameObject.AddComponent<Rigidbody>();
// rb.isKinematic = true;
// }
} }
/// <summary> /// <summary>
@ -48,6 +36,8 @@ namespace RoboidControl.Unity {
new(core.name) : new(core.name) :
new("Touch Sensor"); new("Touch Sensor");
TouchSensor component = gameObj.AddComponent<TouchSensor>(); TouchSensor component = gameObj.AddComponent<TouchSensor>();
component.Init(core);
Rigidbody rb = gameObj.AddComponent<Rigidbody>(); Rigidbody rb = gameObj.AddComponent<Rigidbody>();
rb.isKinematic = true; rb.isKinematic = true;
@ -55,17 +45,6 @@ namespace RoboidControl.Unity {
collider.radius = 0.01f; collider.radius = 0.01f;
collider.isTrigger = true; collider.isTrigger = true;
component.core = core;
component.participant = FindAnyObjectByType<SiteServer>();
core.thisParticipant = component.participant.site;
if (core.parent != null && core.parent.component != null) {
gameObj.transform.SetParent(core.parent.component.transform, false);
}
if (core.position != null)
gameObj.transform.localPosition = core.position.ToVector3();
if (gameObj.transform.parent != null && gameObj.transform.localPosition.magnitude > 0) { if (gameObj.transform.parent != null && gameObj.transform.localPosition.magnitude > 0) {
collider.radius = Vector3.Distance(gameObj.transform.position, gameObj.transform.parent.position) / 2; collider.radius = Vector3.Distance(gameObj.transform.position, gameObj.transform.parent.position) / 2;
gameObj.transform.position = (gameObj.transform.position + gameObj.transform.parent.position) / 2; gameObj.transform.position = (gameObj.transform.position + gameObj.transform.parent.position) / 2;
@ -80,12 +59,14 @@ namespace RoboidControl.Unity {
if (this.transform.root == other.transform.root) if (this.transform.root == other.transform.root)
return; return;
Debug.Log($"*** {this} Touch");
this.coreSensor.touchedSomething = true; this.coreSensor.touchedSomething = true;
} }
private void OnTriggerExit(Collider other) { private void OnTriggerExit(Collider other) {
if (other.isTrigger) if (other.isTrigger)
return; return;
Debug.Log($"*** {this} Touch end");
this.coreSensor.touchedSomething = false; this.coreSensor.touchedSomething = false;
} }
} }

View File

@ -21,8 +21,8 @@ namespace RoboidControl {
/// The ID of the thing /// The ID of the thing
/// </summary> /// </summary>
public byte thingId; public byte thingId;
public Thing thing; public Thing thing;
/// <summary> /// <summary>
/// The length of the data /// The length of the data
/// </summary> /// </summary>
@ -56,10 +56,10 @@ namespace RoboidControl {
} }
/// @copydoc Passer::RoboidControl::IMessage::Serialize /// @copydoc Passer::RoboidControl::IMessage::Serialize
public override byte Serialize(ref byte[] buffer) { public override byte Serialize(ref byte[] buffer) {
if (buffer.Length < BinaryMsg.length + this.data.Length || this.data.Length == 0) if (buffer.Length < BinaryMsg.length + this.data.Length || this.data.Length == 0)
return 0; return 0;
#if DEBUG #if DEBUG
System.Console.WriteLine($"Send BinaryMsg [{this.networkId}/{this.thingId}] {this.dataLength}"); System.Console.WriteLine($"Send BinaryMsg [{this.networkId}/{this.thingId}] {this.dataLength}");
#endif #endif

View File

@ -31,7 +31,10 @@ namespace RoboidControl {
this.thingId = thingId; this.thingId = thingId;
} }
/// @copydoc Passer::RoboidControl::IMessage::IMessage(byte[] buffer) /// @copydoc Passer::RoboidControl::IMessage::IMessage(byte[] buffer)
public DestroyMsg(byte[] buffer) : base(buffer) { } public DestroyMsg(byte[] buffer) : base(buffer) {
this.networkId = buffer[1];
this.thingId = buffer[2];
}
/// @copydoc Passer::RoboidControl::IMessage::Serialize /// @copydoc Passer::RoboidControl::IMessage::Serialize
public override byte Serialize(ref byte[] buffer) { public override byte Serialize(ref byte[] buffer) {

View File

@ -96,12 +96,10 @@ namespace RoboidControl {
if (thing.positionUpdated || force) { if (thing.positionUpdated || force) {
this.position = thing.position; this.position = thing.position;
this.poseType |= Pose_Position; this.poseType |= Pose_Position;
//thing.positionUpdated = false; // this is also reset in Thing.update, leave it out here?
} }
if (thing.orientationUpdated || force) { if (thing.orientationUpdated || force) {
this.orientation = thing.orientation; this.orientation = thing.orientation;
this.poseType |= Pose_Orientation; this.poseType |= Pose_Orientation;
//thing.orientationUpdated = false; // this is also reset in Thing.update, leave it out here?
} }
if (thing.linearVelocityUpdated) { if (thing.linearVelocityUpdated) {
this.linearVelocity = thing.linearVelocity; this.linearVelocity = thing.linearVelocity;
@ -139,6 +137,12 @@ namespace RoboidControl {
/// @copydoc Passer::RoboidControl::IMessage::Serialize /// @copydoc Passer::RoboidControl::IMessage::Serialize
public override byte Serialize(ref byte[] buffer) { public override byte Serialize(ref byte[] buffer) {
if (poseType == 0)
return 0;
#if DEBUG
System.Console.WriteLine($"Send PoseMsg [{this.networkId}/{this.thingId}] {this.poseType}");
#endif
byte ix = 0; byte ix = 0;
buffer[ix++] = PoseMsg.Id; buffer[ix++] = PoseMsg.Id;
buffer[ix++] = this.networkId; buffer[ix++] = this.networkId;

View File

@ -42,7 +42,7 @@ namespace RoboidControl {
/// <summary> /// <summary>
/// The things managed by this participant /// The things managed by this participant
/// </summary> /// </summary>
protected readonly List<Thing> things = new List<Thing>(); public readonly List<Thing> things = new List<Thing>();
public virtual void Update(ulong currentTimeMS = 0) { public virtual void Update(ulong currentTimeMS = 0) {
int n = this.things.Count; int n = this.things.Count;
@ -54,6 +54,38 @@ namespace RoboidControl {
} }
public static List<Participant> participants = new List<Participant>();
public static Participant GetParticipant(string ipAddress, int port) {
//Console.WriteLine($"Get Participant {ipAddress}:{port}");
foreach (Participant participant in Participant.participants) {
if (participant.ipAddress == ipAddress && participant.port == port)
return participant;
}
return null;
}
public static Participant GetParticipant(int participantId) {
//Console.WriteLine($"Get Participant [participantId]");
foreach (Participant participant in Participant.participants) {
if (participant.networkId == participantId)
return participant;
}
return null;
}
public static Participant AddParticipant(string ipAddress, int port) {
Console.WriteLine($"New Participant {ipAddress}:{port}");
Participant participant = new(ipAddress, port) {
networkId = (byte)(Participant.participants.Count + 1)
};
Participant.participants.Add(participant);
return participant;
}
public static void AddParticipant(Participant participant) {
Participant foundParticipant = Participant.GetParticipant(participant.networkId);
if (foundParticipant == null)
Participant.participants.Add(participant);
}
/// <summary> /// <summary>
/// Get a thing with the given ids /// Get a thing with the given ids
/// </summary> /// </summary>

View File

@ -15,6 +15,9 @@ namespace RoboidControl {
public string name = "Participant"; public string name = "Participant";
public bool isIsolated = false;
public Participant remoteSite;
public IPEndPoint endPoint = null; public IPEndPoint endPoint = null;
public UdpClient udpClient = null; public UdpClient udpClient = null;
public string broadcastIpAddress = "255.255.255.255"; public string broadcastIpAddress = "255.255.255.255";
@ -23,19 +26,13 @@ namespace RoboidControl {
#region Init #region Init
/// <summary>
/// Create a porticiapnt
/// </summary>
public ParticipantUDP() {
//senders.Add(this);
}
/// <summary> /// <summary>
/// Create a participant with the give UDP port /// Create a participant with the give UDP port
/// </summary> /// </summary>
/// <param name="port">The port number on which to communicate</param> /// <param name="port">The port number on which to communicate</param>
public ParticipantUDP(int port) : this() { public ParticipantUDP(int port = 0) : base("127.0.0.1", port) {
this.port = port; if (this.port == 0)
this.isIsolated = true;
} }
/// <summary> /// <summary>
@ -43,17 +40,16 @@ namespace RoboidControl {
/// </summary> /// </summary>
/// <param name="ipAddress">The ip address of the site server</param> /// <param name="ipAddress">The ip address of the site server</param>
/// <param name="port">The port number of the site server</param> /// <param name="port">The port number of the site server</param>
public ParticipantUDP(string ipAddress = "0.0.0.0", int port = 7681) : this() { public ParticipantUDP(string ipAddress, int port = 7681, int localPort = 7681) : base("127.0.0.1", localPort) {
this.ipAddress = ipAddress; if (this.port == 0)
this.port = port; this.isIsolated = true;
else
this.remoteSite = new Participant(ipAddress, port);
this.udpClient = new UdpClient(); this.endPoint = new IPEndPoint(IPAddress.Any, localPort);
this.udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, port)); // local port this.udpClient = new UdpClient(localPort);
// this.endPoint = new IPEndPoint(IPAddress.Parse(ipAddress), port); // for sending
// this.udpClient = new UdpClient(port); // for receiving
// this.udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, port));
this.udpClient.BeginReceive(new AsyncCallback(result => ReceiveUDP(result)), null); this.udpClient.BeginReceive(new AsyncCallback(result => ReceiveUDP(result)), null);
} }
/// <summary> /// <summary>
@ -73,60 +69,46 @@ namespace RoboidControl {
return isolatedParticipant; return isolatedParticipant;
} }
public List<Participant> owners = new List<Participant>(); // public List<Participant> owners = new List<Participant>();
public Participant GetParticipant(string ipAddress, int port) { // public Participant GetParticipant(string ipAddress, int port) {
//Console.WriteLine($"Get Participant {ipAddress}:{port}"); // //Console.WriteLine($"Get Participant {ipAddress}:{port}");
foreach (Participant sender in owners) { // foreach (Participant sender in owners) {
if (sender.ipAddress == ipAddress && sender.port == port) // if (sender.ipAddress == ipAddress && sender.port == port)
return sender; // return sender;
} // }
return null; // return null;
} // }
public Participant AddParticipant(string ipAddress, int port) { // public Participant AddParticipant(string ipAddress, int port) {
Console.WriteLine($"New Participant {ipAddress}:{port}"); // Console.WriteLine($"New Participant {ipAddress}:{port}");
Participant participant = new(ipAddress, port) { // Participant participant = new(ipAddress, port) {
networkId = (byte)(this.owners.Count + 1) // networkId = (byte)(this.owners.Count + 1)
}; // };
owners.Add(participant); // owners.Add(participant);
return participant; // return participant;
}
protected readonly Dictionary<byte, Func<Participant, byte, byte, Thing>> thingMsgProcessors = new();
// public delegate Thing ThingConstructor(Participant sender, byte networkId, byte thingId);
// public void Register(byte thingType, ThingConstructor constr) {
// thingMsgProcessors[thingType] = new Func<Participant, byte, byte, Thing>(constr);
// } // }
// public void Register<ThingClass>(Thing.Type thingType) where ThingClass : Thing { // protected readonly Dictionary<byte, Func<Participant, byte, byte, Thing>> thingMsgProcessors = new();
// Register<ThingClass>((byte)thingType);
// }
// public void Register<ThingClass>(byte thingType) where ThingClass : Thing {
// thingMsgProcessors[thingType] = (participant, networkId, thingId) =>
// Activator.CreateInstance(typeof(ThingClass), participant, networkId, thingId) as ThingClass;
// Console.WriteLine($"Registering {typeof(ThingClass)} for thing type {thingType}");
// }
#endregion Init #endregion Init
#region Update #region Update
protected void ReceiveUDP(IAsyncResult result) { protected void ReceiveUDP(IAsyncResult result) {
if (this.udpClient == null || this.endPoint == null) // UnityEngine.Debug.Log("received");
if (this.udpClient == null) // || this.endPoint == null)
return; return;
byte[] data = this.udpClient.EndReceive(result, ref this.endPoint); byte[] data = this.udpClient.EndReceive(result, ref endPoint);
// This does not yet take multi-packet messages into account! // This does not yet take multi-packet messages into account!
if (this.endPoint == null) if (endPoint == null)
return; return;
// We can receive our own publish (broadcast) packages. How do we recognize them???? // We can receive our own publish (broadcast) packages. How do we recognize them????
// It is hard to determine our source port // It is hard to determine our source port
string ipAddress = this.endPoint.Address.ToString(); string ipAddress = endPoint.Address.ToString();
Participant remoteParticipant = GetParticipant(ipAddress, this.endPoint.Port); Participant remoteParticipant = GetParticipant(ipAddress, endPoint.Port);
remoteParticipant ??= AddParticipant(ipAddress, this.endPoint.Port); remoteParticipant ??= AddParticipant(ipAddress, endPoint.Port);
ReceiveData(data, remoteParticipant); ReceiveData(data, remoteParticipant);
@ -147,24 +129,47 @@ namespace RoboidControl {
this.nextPublishMe = currentTimeMS + this.publishInterval; this.nextPublishMe = currentTimeMS + this.publishInterval;
} }
UpdateMyThings(currentTimeMS);
UpdateOtherThings(currentTimeMS);
}
protected virtual void UpdateMyThings(ulong currentTimeMS) {
int n = this.things.Count; int n = this.things.Count;
for (int ix = 0; ix < n; ix++) { for (int ix = 0; ix < n; ix++) {
Thing thing = this.things[ix]; Thing thing = this.things[ix];
if (thing != null && thing.parent == null) { if (thing == null || thing.parent != null)
thing.Update(currentTimeMS, true); continue;
// if (this.isIsolated == false) {
if (thing.owner != this) { // should not happen.... thing.Update(currentTimeMS, true);
PoseMsg poseMsg = new(thing.owner.networkId, thing); if (this.isIsolated || this.networkId == 0)
this.Send(thing.owner, poseMsg); continue;
BinaryMsg binaryMsg = new(thing.owner.networkId, thing);
this.Send(thing.owner, binaryMsg); // Send to remote site
} PoseMsg poseMsg = new(thing.owner.networkId, thing);
this.Send(this.remoteSite, poseMsg);
BinaryMsg binaryMsg = new(thing.owner.networkId, thing);
this.Send(this.remoteSite, binaryMsg);
}
}
protected virtual void UpdateOtherThings(ulong currentTimeMS) {
for (int ownerIx = 0; ownerIx < Participant.participants.Count; ownerIx++) {
Participant participant = Participant.participants[ownerIx];
if (participant == null || participant == this)
continue;
participant.Update(currentTimeMS);
if (this.isIsolated)
continue;
foreach (Thing thing in participant.things) {
PoseMsg poseMsg = new(thing.owner.networkId, thing);
this.Send(participant, poseMsg);
BinaryMsg binaryMsg = new(thing.owner.networkId, thing);
this.Send(participant, binaryMsg);
} }
} }
for (int ownerIx = 0; ownerIx < this.owners.Count; ownerIx++) {
Participant owner = this.owners[ownerIx];
owner.Update(currentTimeMS);
}
} }
public virtual void Publish() { public virtual void Publish() {
@ -271,7 +276,8 @@ namespace RoboidControl {
// result = await TextMsg.Receive(dataStream, client, packetSize); // result = await TextMsg.Receive(dataStream, client, packetSize);
break; break;
case DestroyMsg.Id: // 0x20 / 32 case DestroyMsg.Id: // 0x20 / 32
// result = await DestroyMsg.Receive(dataStream, client, packetSize); this.Process(sender, new DestroyMsg(data));
// result = await DestroyMsg.Receive(dataStream, client, packetSize);
break; break;
default: default:
break; break;
@ -342,17 +348,21 @@ namespace RoboidControl {
thing.position = msg.position; thing.position = msg.position;
if ((msg.poseType & PoseMsg.Pose_Orientation) != 0) if ((msg.poseType & PoseMsg.Pose_Orientation) != 0)
thing.orientation = msg.orientation; thing.orientation = msg.orientation;
if ((msg.poseType & PoseMsg.Pose_LinearVelocity) != 0) if ((msg.poseType & PoseMsg.Pose_LinearVelocity) != 0) {
thing.linearVelocity = msg.linearVelocity; thing.linearVelocity = msg.linearVelocity;
if ((msg.poseType & PoseMsg.Pose_AngularVelocity) != 0) //Console.Write($"linear velocity = {thing.linearVelocity.ToVector3()}");
}
if ((msg.poseType & PoseMsg.Pose_AngularVelocity) != 0) {
thing.angularVelocity = msg.angularVelocity; thing.angularVelocity = msg.angularVelocity;
//Console.Write($"angular velocity = {thing.angularVelocity.ToVector3()}");
}
} }
} }
protected virtual void Process(Participant sender, BinaryMsg msg) { protected virtual void Process(Participant sender, BinaryMsg msg) {
#if DEBUG // #if DEBUG
Console.WriteLine($"Participant: Process BinaryMsg [{msg.networkId}/{msg.thingId}] {msg.dataLength}"); // Console.WriteLine($"Participant: Process BinaryMsg [{msg.networkId}/{msg.thingId}] {msg.dataLength}");
#endif // #endif
Thing thing = sender.Get(msg.networkId, msg.thingId); Thing thing = sender.Get(msg.networkId, msg.thingId);
thing?.ProcessBinary(msg.data); thing?.ProcessBinary(msg.data);
} }
@ -366,7 +376,7 @@ namespace RoboidControl {
protected virtual void Process(Participant sender, DestroyMsg msg) { protected virtual void Process(Participant sender, DestroyMsg msg) {
#if DEBUG #if DEBUG
Console.WriteLine($"Participant: Process ThingMsg [{msg.networkId}/{msg.thingId}]"); Console.WriteLine($"Participant: Process Destroy Msg [{msg.networkId}/{msg.thingId}]");
#endif #endif
} }

View File

@ -9,27 +9,18 @@ namespace RoboidControl {
/// </summary> /// </summary>
public class SiteServer : ParticipantUDP { public class SiteServer : ParticipantUDP {
public SiteServer(int port = 7681) : this("0.0.0.0", port) { }
/// <summary> /// <summary>
/// Create a new site server /// Create a new site server
/// </summary> /// </summary>
/// <param name="port"></param> /// <param name="port"></param>
public SiteServer(string ipAddress = "0.0.0.0", int port = 7681) : base() { public SiteServer(int port = 7681) : base(port) {
this.name = "Site Server"; this.name = "Site Server";
this.ipAddress = ipAddress;
this.port = port;
this.endPoint = new IPEndPoint(IPAddress.Parse(ipAddress), port); // for sending
Console.Write($"Prepare receive on port {port}"); Console.Write($"Prepare receive on port {port}");
this.udpClient = new UdpClient(port); // for receiving this.endPoint = new IPEndPoint(IPAddress.Any, port);
this.udpClient.BeginReceive( this.udpClient = new UdpClient(port);
new AsyncCallback(result => ReceiveUDP(result)), this.udpClient.BeginReceive(new AsyncCallback(result => ReceiveUDP(result)), null);
new Tuple<UdpClient, IPEndPoint>(this.udpClient, new(IPAddress.Any, port)));
// Register<TouchSensor>(Thing.Type.TouchSensor);
} }
/// <summary> /// <summary>
@ -39,44 +30,59 @@ namespace RoboidControl {
this.udpClient?.Close(); this.udpClient?.Close();
} }
protected override void UpdateMyThings(ulong currentTimeMS) {
int n = this.things.Count;
for (int ix = 0; ix < n; ix++) {
Thing thing = this.things[ix];
if (thing == null || thing.parent != null)
continue;
thing.Update(currentTimeMS, true);
if (this.isIsolated || this.networkId == 0)
continue;
// Send to all other participants
foreach (Participant participant in Participant.participants) {
if (participant == null || participant == this)
continue;
PoseMsg poseMsg = new(thing.owner.networkId, thing);
this.Send(participant, poseMsg);
BinaryMsg binaryMsg = new(thing.owner.networkId, thing);
this.Send(participant, binaryMsg);
}
}
}
public override void Publish() { public override void Publish() {
} }
protected override void Process(Participant sender, ParticipantMsg msg) { protected override void Process(Participant sender, ParticipantMsg msg) {
base.Process(sender, msg); base.Process(sender, msg);
//if (msg.networkId == 0) { //if (msg.networkId == 0) {
//Console.WriteLine($"{this.name} received New Participant -> {sender.networkId}"); //Console.WriteLine($"{this.name} received New Participant -> {sender.networkId}");
this.Send(sender, new NetworkIdMsg(sender.networkId)); this.Send(sender, new NetworkIdMsg(sender.networkId));
//} //}
} }
protected override void Process(Participant sender, NetworkIdMsg msg) { } protected override void Process(Participant sender, NetworkIdMsg msg) { }
protected override void Process(Participant sender, ThingMsg msg) { protected override void Process(Participant sender, ThingMsg msg) {
Console.WriteLine($"SiteServer: Process thing [{msg.networkId}/{msg.thingId}]"); Console.WriteLine($"SiteServer: Process thing [{msg.networkId}/{msg.thingId}] {msg.thingType} {msg.parentId} ");
Thing thing = sender.Get(msg.networkId, msg.thingId); Thing thing = sender.Get(msg.networkId, msg.thingId);
if (thing == null) { if (thing == null) {
Thing newThing = null; thing = new Thing(sender, msg.networkId, msg.thingId, msg.thingType);
// if (thingMsgProcessors.TryGetValue(msg.thingType, out Func<Participant, byte, byte, Thing> msgProcessor)) { // Console.WriteLine("Created generic new core thing");
// //Console.WriteLine("Found thing message processor");
// if (msgProcessor != null)
// newThing = msgProcessor(sender, msg.networkId, msg.thingId);
// } // }
// if (newThing == null) { }
newThing = new Thing(sender, msg.networkId, msg.thingId, msg.thingType);
// Console.WriteLine("Created generic new core thing"); if (msg.parentId != 0) {
// } Thing parentThing = Get(msg.networkId, msg.parentId);
if (msg.parentId != 0) { if (parentThing == null)
Thing parentThing = Get(msg.networkId, msg.parentId); Console.WriteLine($"Could not find parent [{msg.networkId}/{msg.parentId}]");
if (parentThing == null) else
Console.WriteLine($"Could not find parent [{msg.networkId}/{msg.parentId}]"); thing.parent = parentThing;
else
newThing.parent = parentThing;
}
//Console.WriteLine("Adding to remote sender");
//sender.Add(newThing, false, true);
} }
} }
} }
} }

View File

@ -225,7 +225,6 @@ namespace RoboidControl {
[NonSerialized] [NonSerialized]
protected List<Thing> children = new(); protected List<Thing> children = new();
private string _name = ""; private string _name = "";
/// <summary> /// <summary>
/// The name of the thing /// The name of the thing
@ -235,6 +234,7 @@ namespace RoboidControl {
set { set {
if (_name != value) { if (_name != value) {
_name = value; _name = value;
nameChanged = true;
OnNameChanged?.Invoke(); OnNameChanged?.Invoke();
} }
} }
@ -243,6 +243,7 @@ namespace RoboidControl {
/// Event which is triggered when the name changes /// Event which is triggered when the name changes
/// </summary> /// </summary>
public event ChangeHandler OnNameChanged = delegate { }; public event ChangeHandler OnNameChanged = delegate { };
public bool nameChanged = false;
/// <summary> /// <summary>
/// An URL pointing to the location where a model of the thing can be found /// An URL pointing to the location where a model of the thing can be found
@ -366,6 +367,8 @@ namespace RoboidControl {
OnPoseChanged?.Invoke(); OnPoseChanged?.Invoke();
this.positionUpdated = false; this.positionUpdated = false;
this.orientationUpdated = false; this.orientationUpdated = false;
this.linearVelocityUpdated = false;
this.angularVelocityUpdated = false;
// should recurse over children... // should recurse over children...
if (recursively) { if (recursively) {

View File

@ -19,7 +19,7 @@ namespace RoboidControl {
} }
public TouchSensor(Participant owner, byte networkId, byte thingId) : base(owner, networkId, thingId) { public TouchSensor(Participant owner, byte networkId, byte thingId) : base(owner, networkId, thingId) {
Console.Write("TouchSensor constructor"); // Console.Write("TouchSensor constructor");
//touchedSomething = false; //touchedSomething = false;
//thisParticipant = participant; //thisParticipant = participant;
} }
@ -36,26 +36,29 @@ namespace RoboidControl {
public bool touchedSomething { public bool touchedSomething {
get { return _touchedSomething; } get { return _touchedSomething; }
set { set {
_touchedSomething = value; if (_touchedSomething != value) {
if (thisParticipant != null && this.owner != thisParticipant) { touchUpdated = true;
BinaryMsg msg = new(networkId, this); _touchedSomething = value;
foreach (Participant remoteParticipant in thisParticipant.owners)
thisParticipant.Send(remoteParticipant, msg);
} }
} }
} }
private bool touchUpdated = false;
#if UNITY_5_3_OR_NEWER #if UNITY_5_3_OR_NEWER
/// @copydoc Passer::RoboidControl::Thing::CreateComponent /// @copydoc Passer::RoboidControl::Thing::CreateComponent
public override void CreateComponent() { public override void CreateComponent() {
System.Console.Write("Create touch sensor component"); // System.Console.Write("Create touch sensor component");
this.component = Unity.TouchSensor.Create(this); this.component = Unity.TouchSensor.Create(this);
this.component.core = this; this.component.core = this;
} }
#endif #endif
public override byte[] GenerateBinary() { public override byte[] GenerateBinary() {
if (!touchUpdated)
return new byte[0];
byte[] buffer = new byte[1]; byte[] buffer = new byte[1];
buffer[0] = (byte)(touchedSomething ? 1 : 0); buffer[0] = (byte)(touchedSomething ? 1 : 0);
touchUpdated = false;
return buffer; return buffer;
} }
} }