302 lines
9.6 KiB
C#
302 lines
9.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using Passer.LinearAlgebra;
|
|
|
|
namespace Passer.RoboidControl {
|
|
|
|
/// <summary>
|
|
/// A thing is the primitive building block
|
|
/// </summary>
|
|
[Serializable]
|
|
public class Thing {
|
|
|
|
#region Types
|
|
|
|
#endregion Types
|
|
|
|
#region Properties
|
|
|
|
public delegate void ChangeHandler();
|
|
public delegate void SphericalHandler(Spherical v);
|
|
public delegate void ThingHandler(Thing t);
|
|
|
|
/// <summary>
|
|
/// The participant to which this thing belongs
|
|
/// </summary>
|
|
public RemoteParticipant participant;
|
|
|
|
/// <summary>
|
|
/// The network ID of this thing.
|
|
/// </summary>
|
|
public byte networkId;
|
|
/// <summary>
|
|
/// The ID of this thing
|
|
/// </summary>
|
|
public byte id;
|
|
|
|
/// <summary>
|
|
/// Predefined thing types
|
|
/// </summary>
|
|
public enum Type {
|
|
Undetermined,
|
|
// Sensor
|
|
Switch,
|
|
DistanceSensor,
|
|
DirectionalSensor,
|
|
TemperatureSensor,
|
|
// Motor
|
|
ControlledMotor,
|
|
UncontrolledMotor,
|
|
Servo,
|
|
// Other
|
|
Roboid,
|
|
Humanoid,
|
|
ExternalSensor
|
|
};
|
|
/// <summary>
|
|
/// The type of this thing. This can be either a Thing::Type (needs casting)
|
|
/// or a byte value for custom types.
|
|
/// </summary>
|
|
public byte type;
|
|
|
|
/// <summary>
|
|
/// Event which is triggered when the parent changes
|
|
/// </summary>
|
|
public event ChangeHandler OnParentChanged = delegate { };
|
|
private Thing _parent;
|
|
/// <summary>
|
|
/// The parent of this thing
|
|
/// </summary>
|
|
public Thing parent {
|
|
get => _parent;
|
|
set {
|
|
if (_parent == value)
|
|
return;
|
|
|
|
if (value == null) {
|
|
_parent?.RemoveChild(this);
|
|
_parent = null;
|
|
}
|
|
else {
|
|
value.AddChild(this);
|
|
OnParentChanged?.Invoke();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Attach a thing as a child of this thing
|
|
/// </summary>
|
|
/// <param name="child">The thing to attach as a child</param>
|
|
public void AddChild(Thing child) {
|
|
if (children.Find(thing => thing == child) != null)
|
|
return;
|
|
child._parent = this;
|
|
children.Add(child);
|
|
}
|
|
/// <summary>
|
|
/// Remove the given thing as a child of this thing
|
|
/// </summary>
|
|
/// <param name="child">The child to remove</param>
|
|
public void RemoveChild(Thing child) {
|
|
children.Remove(child);
|
|
}
|
|
|
|
/// <summary>
|
|
/// The list of children of this thing
|
|
/// </summary>
|
|
[NonSerialized]
|
|
public List<Thing> children = new List<Thing>();
|
|
|
|
/// <summary>
|
|
/// Event which is triggered when the name changes
|
|
/// </summary>
|
|
public event ChangeHandler OnNameChanged = delegate { };
|
|
private string _name = "";
|
|
/// <summary>
|
|
/// The name of the thing
|
|
/// </summary>
|
|
public virtual string name {
|
|
get => _name;
|
|
set {
|
|
if (_name != value) {
|
|
_name = value;
|
|
OnNameChanged?.Invoke();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// An URL pointing to the location where a model of the thing can be found
|
|
/// </summary>
|
|
public string modelUrl = "";
|
|
|
|
/// <summary>
|
|
/// Event triggered when the position has changed
|
|
/// </summary>
|
|
public event ChangeHandler OnPositionChanged = delegate { };
|
|
private Spherical _position = Spherical.zero;
|
|
/// <summary>
|
|
/// The position of the thing in local space, in meters.
|
|
/// </summary>
|
|
public Spherical position {
|
|
get { return _position; }
|
|
set {
|
|
if (_position != value) {
|
|
_position = value;
|
|
OnPositionChanged?.Invoke();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Event triggered when the orientation has changed
|
|
/// </summary>
|
|
public event ChangeHandler OnOrientationChanged = delegate { };
|
|
private SwingTwist _orientation = SwingTwist.zero;
|
|
/// <summary>
|
|
/// The orientation of the thing in local space
|
|
/// </summary>
|
|
public SwingTwist orientation {
|
|
get { return _orientation; }
|
|
set {
|
|
if (_orientation != value) {
|
|
_orientation = value;
|
|
OnOrientationChanged?.Invoke();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Event triggered when the linear velocity has changed
|
|
/// </summary>
|
|
public event SphericalHandler OnLinearVelocityChanged = delegate { };
|
|
private Spherical _linearVelocity = Spherical.zero;
|
|
/// <summary>
|
|
/// The linear velocity of the thing in local space in meters per second
|
|
/// </summary>
|
|
public Spherical linearVelocity {
|
|
get => _linearVelocity;
|
|
set {
|
|
if (_linearVelocity != value) {
|
|
_linearVelocity = value;
|
|
OnLinearVelocityChanged?.Invoke(_linearVelocity);
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// The angular velocity of the thing in local space
|
|
/// </summary>
|
|
public Spherical angularVelocity = Spherical.zero;
|
|
|
|
#if UNITY_5_3_OR_NEWER
|
|
/// <summary>
|
|
/// A reference to the representation of the thing in Unity
|
|
/// </summary>
|
|
[NonSerialized]
|
|
public Unity.Thing component = null;
|
|
#endif
|
|
|
|
#endregion Properties
|
|
|
|
#region Init
|
|
|
|
/// <summary>
|
|
/// Create a new thing for the given participant
|
|
/// </summary>
|
|
/// <param name="participant">The participant for which this thing is created</param>
|
|
/// <param name="invokeEvent">True when a new thing event should be triggered</param>
|
|
public Thing(RemoteParticipant participant, bool invokeEvent = false) {
|
|
this.participant = participant;
|
|
if (invokeEvent)
|
|
InvokeNewThing(this);
|
|
}
|
|
/// <summary>
|
|
/// Create a new thing for the given participant
|
|
/// </summary>
|
|
/// <param name="participant">The participant for which this thing is created</param>
|
|
/// <param name="networkId">The network ID of the thing</param>
|
|
/// <param name="thingId">The ID of the thing</param>
|
|
/// <param name="thingType">The type of thing</param>
|
|
public Thing(RemoteParticipant participant, byte networkId, byte thingId, byte thingType = 0) {
|
|
this.participant = participant;
|
|
this.id = thingId;
|
|
this.type = thingType;
|
|
this.networkId = networkId;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Function which can be used to create components in external engines.
|
|
/// </summary>
|
|
/// 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
|
|
/// <summary>
|
|
/// Convience function for use in Unity which removes the need for a currentTime argument
|
|
/// </summary>
|
|
public void Update() {
|
|
Update((ulong)UnityEngine.Time.time * 1000);
|
|
}
|
|
#endif
|
|
/// <summary>
|
|
/// Update this thing
|
|
/// </summary>
|
|
/// <param name="currentTime">The current time in milliseconds</param>
|
|
public virtual void Update(ulong currentTime) {
|
|
// should recurse over children...
|
|
}
|
|
|
|
/// <summary>
|
|
/// Function used to generate binary data for this thing
|
|
/// </summary>
|
|
/// <returns>a byte array with the binary data</returns>
|
|
/// @sa Passer::RoboidControl::BinaryMsg
|
|
public virtual byte[] GenerateBinary() { return new byte[0]; }
|
|
|
|
/// <summary>
|
|
/// Function used to process binary data received for this thing
|
|
/// </summary>
|
|
/// <param name="bytes">The binary data</param>
|
|
public virtual void ProcessBinary(byte[] bytes) {
|
|
}
|
|
|
|
#endregion Update
|
|
|
|
/// <summary>
|
|
/// Event triggered when a new thing has been created
|
|
/// </summary>
|
|
public static event ThingHandler OnNewThing = delegate { };
|
|
/// <summary>
|
|
/// Trigger the creation for the given thing
|
|
/// </summary>
|
|
/// <param name="thing">The created thing</param>
|
|
public static void InvokeNewThing(Thing thing) {
|
|
OnNewThing?.Invoke(thing);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check if the thing has the given properaties
|
|
/// </summary>
|
|
/// <param name="thing">The thing to check</param>
|
|
/// <param name="networkId">The network ID to compare to</param>
|
|
/// <param name="thingId">The thing ID to compare to</param>
|
|
/// <returns>True when the thing has the given properties</returns>
|
|
public static bool IsThing(Thing thing, byte networkId, byte thingId) {
|
|
if (thing == null)
|
|
return false;
|
|
return (thing.networkId == networkId) && (thing.id == thingId);
|
|
}
|
|
|
|
}
|
|
}
|