Completed things docs
This commit is contained in:
parent
346263d311
commit
09783d2103
@ -109,7 +109,7 @@ namespace RoboidControl {
|
|||||||
if (thing == null) {
|
if (thing == null) {
|
||||||
switch (msg.thingType) {
|
switch (msg.thingType) {
|
||||||
case (byte)Thing.Type.TouchSensor:
|
case (byte)Thing.Type.TouchSensor:
|
||||||
new TouchSensor(sender, msg.networkId, msg.thingId);
|
new TouchSensor(sender, msg.thingId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
11
src/Thing.cs
11
src/Thing.cs
@ -27,9 +27,10 @@ namespace RoboidControl {
|
|||||||
public const byte Servo = 0x08;
|
public const byte Servo = 0x08;
|
||||||
// Other
|
// Other
|
||||||
public const byte Roboid = 0x09;
|
public const byte Roboid = 0x09;
|
||||||
public const byte HUmanoid = 0x010;
|
public const byte HUmanoid = 0x0A;
|
||||||
public const byte ExternalSensor = 0x11;
|
public const byte ExternalSensor = 0x0B;
|
||||||
public const byte Animator = 0x40;
|
public const byte Animator = 0x0C;
|
||||||
|
public const byte DifferentialDrive = 0x0D;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Init
|
#region Init
|
||||||
@ -67,7 +68,7 @@ namespace RoboidControl {
|
|||||||
/// <param name="thingId">The ID of the thing, leave out or set to zero to generate an ID</param>
|
/// <param name="thingId">The ID of the thing, leave out or set to zero to generate an ID</param>
|
||||||
/// <param name="invokeEvent">Invoke a OnNewThing event when the thing has been created</param>
|
/// <param name="invokeEvent">Invoke a OnNewThing event when the thing has been created</param>
|
||||||
/// <note>The owner will be the same as the owner of the parent thing</note>
|
/// <note>The owner will be the same as the owner of the parent thing</note>
|
||||||
public Thing(Thing parent, byte thingType = Type.Undetermined, bool invokeEvent = true) : this(parent.owner, thingType, 0, invokeEvent) {
|
public Thing(Thing parent, byte thingType = Type.Undetermined, byte thingId = 0, bool invokeEvent = true) : this(parent.owner, thingType, thingId, invokeEvent) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -424,7 +425,7 @@ namespace RoboidControl {
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Function used to process binary data received for this thing
|
/// Function used to process binary data received for this thing
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="bytes">The binary data</param>
|
/// <param name="bytes">The binary data to process</param>
|
||||||
public virtual void ProcessBinary(byte[] bytes) {
|
public virtual void ProcessBinary(byte[] bytes) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,30 @@
|
|||||||
|
using LinearAlgebra;
|
||||||
|
|
||||||
namespace RoboidControl {
|
namespace RoboidControl {
|
||||||
|
|
||||||
/// @brief A thing which can move itself using a differential drive system
|
/// @brief A thing which can move itself using a differential drive system
|
||||||
///
|
///
|
||||||
/// @sa @link https://en.wikipedia.org/wiki/Differential_wheeled_robot @endlink
|
/// @sa @link https://en.wikipedia.org/wiki/Differential_wheeled_robot @endlink
|
||||||
public class DifferentialDrive : Thing {
|
public class DifferentialDrive : Thing {
|
||||||
/// @brief Create a differential drive without networking support
|
/// <summary>
|
||||||
public DifferentialDrive() { }
|
/// Create a differential drive without communication abilities
|
||||||
/// @brief Create a differential drive with networking support
|
/// </summary
|
||||||
/// @param participant The local participant
|
/// <param name="invokeEvent">Invoke a OnNewThing event when the thing has been created</param>
|
||||||
public DifferentialDrive(ParticipantUDP participant) : base(participant, Type.Undetermined) { }
|
public DifferentialDrive(bool invokeEvent = true) : base(Type.DifferentialDrive, invokeEvent) { }
|
||||||
|
/// <summary>
|
||||||
|
/// Create a differential drive for a participant
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="owner">The owning participant</param>
|
||||||
|
/// <param name="thingId">The ID of the thing, leave out or set to zero to generate an ID</param>
|
||||||
|
/// <param name="invokeEvent">Invoke a OnNewThing event when the thing has been created</param>
|
||||||
|
public DifferentialDrive(ParticipantUDP participant, byte thingId = 0, bool invokeEvent = true) : base(participant, Type.DifferentialDrive, thingId, invokeEvent) { }
|
||||||
|
/// <summary>
|
||||||
|
/// Create a new child differential drive
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="parent">The parent thing</param>
|
||||||
|
/// <param name="thingId">The ID of the thing, leave out or set to zero to generate an ID</param>
|
||||||
|
/// <param name="invokeEvent">Invoke a OnNewThing event when the thing has been created</param>
|
||||||
|
public DifferentialDrive(Thing parent, byte thingId = 0, bool invokeEvent = true) : base(parent, Type.DifferentialDrive, thingId, invokeEvent) { }
|
||||||
|
|
||||||
/// @brief Configures the dimensions of the drive
|
/// @brief Configures the dimensions of the drive
|
||||||
/// @param wheelDiameter The diameter of the wheels in meters
|
/// @param wheelDiameter The diameter of the wheels in meters
|
||||||
@ -17,21 +33,63 @@ namespace RoboidControl {
|
|||||||
/// These values are used to compute the desired wheel speed from the set
|
/// These values are used to compute the desired wheel speed from the set
|
||||||
/// linear and angular velocity.
|
/// linear and angular velocity.
|
||||||
/// @sa SetLinearVelocity SetAngularVelocity
|
/// @sa SetLinearVelocity SetAngularVelocity
|
||||||
public void SetDriveDimensions(float wheelDiameter, float wheelSeparation) { }
|
public void SetDriveDimensions(float wheelDiameter, float wheelSeparation) {
|
||||||
|
this.wheelRadius = wheelDiameter > 0 ? wheelDiameter / 2 : -wheelDiameter / 2;
|
||||||
|
this.wheelSeparation = wheelSeparation > 0 ? wheelSeparation : -wheelSeparation;
|
||||||
|
this.rpsToMs = wheelDiameter * Angle.pi;
|
||||||
|
|
||||||
|
float distance = this.wheelSeparation / 2;
|
||||||
|
if (this.leftWheel != null)
|
||||||
|
this.leftWheel.position = new Spherical(distance, Direction.left);
|
||||||
|
if (this.rightWheel != null)
|
||||||
|
this.rightWheel.position = new Spherical(distance, Direction.right);
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Congures the motors for the wheels
|
/// @brief Congures the motors for the wheels
|
||||||
/// @param leftWheel The motor for the left wheel
|
/// @param leftWheel The motor for the left wheel
|
||||||
/// @param rightWheel The motor for the right wheel
|
/// @param rightWheel The motor for the right wheel
|
||||||
public void SetMotors(Thing leftWheel, Thing rightWheel) { }
|
public void SetMotors(Thing leftWheel, Thing rightWheel) {
|
||||||
|
float distance = this.wheelSeparation / 2;
|
||||||
|
|
||||||
|
this.leftWheel = leftWheel;
|
||||||
|
if (this.leftWheel != null)
|
||||||
|
this.leftWheel.position = new Spherical(distance, Direction.left);
|
||||||
|
|
||||||
|
this.rightWheel = rightWheel;
|
||||||
|
if (this.rightWheel != null)
|
||||||
|
this.rightWheel.position = new Spherical(distance, Direction.right);
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Directly specify the speeds of the motors
|
/// @brief Directly specify the speeds of the motors
|
||||||
/// @param speedLeft The speed of the left wheel in degrees per second.
|
/// @param speedLeft The speed of the left wheel in degrees per second.
|
||||||
/// Positive moves the robot in the forward direction.
|
/// Positive moves the robot in the forward direction.
|
||||||
/// @param speedRight The speed of the right wheel in degrees per second.
|
/// @param speedRight The speed of the right wheel in degrees per second.
|
||||||
/// Positive moves the robot in the forward direction.
|
/// Positive moves the robot in the forward direction.
|
||||||
public void SetWheelVelocity(float speedLeft, float speedRight) { }
|
public void SetWheelVelocity(float speedLeft, float speedRight) {
|
||||||
|
if (this.leftWheel != null)
|
||||||
|
this.leftWheel.angularVelocity = new Spherical(speedLeft, Direction.left);
|
||||||
|
if (this.rightWheel != null)
|
||||||
|
this.rightWheel.angularVelocity = new Spherical(speedRight, Direction.right);
|
||||||
|
}
|
||||||
|
|
||||||
/// @copydoc RoboidControl::Thing::Update(unsigned long)
|
/// @copydoc RoboidControl::Thing::Update(unsigned long)
|
||||||
public override void Update(ulong currentMs, bool recursive = true) { }
|
public override void Update(ulong currentMs, bool recursive = true) {
|
||||||
|
if (this.linearVelocityUpdated) {
|
||||||
|
// this assumes forward velocity only....
|
||||||
|
float linearVelocity = this.linearVelocity.distance;
|
||||||
|
|
||||||
|
Spherical angularVelocity = this.angularVelocity;
|
||||||
|
float angularSpeed = angularVelocity.distance * Angle.Deg2Rad;
|
||||||
|
// Determine the rotation direction
|
||||||
|
if (angularVelocity.direction.horizontal < 0)
|
||||||
|
angularSpeed = -angularSpeed;
|
||||||
|
|
||||||
|
// wheel separation can be replaced by this.leftwheel.position.distance
|
||||||
|
float speedLeft = (linearVelocity + angularSpeed * this.wheelSeparation / 2) / this.wheelRadius * Angle.Rad2Deg;
|
||||||
|
float speedRight = (linearVelocity - angularSpeed * this.wheelSeparation / 2) / this.wheelRadius * Angle.Rad2Deg;
|
||||||
|
this.SetWheelVelocity(speedLeft, speedRight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief The radius of a wheel in meters
|
/// @brief The radius of a wheel in meters
|
||||||
protected float wheelRadius = 1.0f;
|
protected float wheelRadius = 1.0f;
|
||||||
|
74
src/Things/DigitalSensor.cs
Normal file
74
src/Things/DigitalSensor.cs
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace RoboidControl {
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A sensor which can detect touches
|
||||||
|
/// </summary>
|
||||||
|
public class DigitalSensor : Thing {
|
||||||
|
/// <summary>
|
||||||
|
/// Create a digital sensor without communication abilities
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="invokeEvent">Invoke a OnNewThing event when the thing has been created</param>
|
||||||
|
public DigitalSensor(bool invokeEvent = true) : base(Type.Switch, invokeEvent) { }
|
||||||
|
/// <summary>
|
||||||
|
/// Create a digital sensor for a participant
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="owner">The owning participant</param>
|
||||||
|
/// <param name="thingId">The ID of the thing, leave out or set to zero to generate an ID</param>
|
||||||
|
/// <param name="invokeEvent">Invoke a OnNewThing event when the thing has been created</param>
|
||||||
|
public DigitalSensor(Participant owner, byte thingId = 0, bool invokeEvent = true) : base(owner, Type.Switch, thingId, invokeEvent) { }
|
||||||
|
/// <summary>
|
||||||
|
/// Create a new child digital sensor
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="parent">The parent thing</param>
|
||||||
|
/// <param name="thingId">The ID of the thing, leave out or set to zero to generate an ID</param>
|
||||||
|
/// <param name="invokeEvent">Invoke a OnNewThing event when the thing has been created</param>
|
||||||
|
public DigitalSensor(Thing parent, byte thingId = 0, bool invokeEvent = true) : base(parent, Type.Switch, thingId, invokeEvent) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Value which is true when the sensor is touching something, false otherwise
|
||||||
|
/// </summary>
|
||||||
|
private bool _state = false;
|
||||||
|
public bool state {
|
||||||
|
get { return _state; }
|
||||||
|
set {
|
||||||
|
if (_state != value) {
|
||||||
|
_state = value;
|
||||||
|
}
|
||||||
|
stateUpdated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private bool stateUpdated = false;
|
||||||
|
|
||||||
|
#if UNITY_5_3_OR_NEWER
|
||||||
|
/// @copydoc Passer::RoboidControl::Thing::CreateComponent
|
||||||
|
public override void CreateComponent() {
|
||||||
|
this.component = Unity.DigitalSensor.Create(this);
|
||||||
|
this.component.core = this;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/// <summary>
|
||||||
|
/// Function used to generate binary data for this digital sensor
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A byte array with the binary data</returns>
|
||||||
|
/// <remark>The byte array will be empty when the digital status has not changed</remark>
|
||||||
|
public override byte[] GenerateBinary() {
|
||||||
|
if (!stateUpdated)
|
||||||
|
return Array.Empty<byte>();
|
||||||
|
|
||||||
|
byte[] bytes = new byte[1];
|
||||||
|
bytes[0] = (byte)(state ? 1 : 0);
|
||||||
|
stateUpdated = false;
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Function used to process binary data received for this digital sensor
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bytes">The binary data to process</param>
|
||||||
|
public override void ProcessBinary(byte[] bytes) {
|
||||||
|
this.state |= (bytes[0] == 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
//using System;
|
using System;
|
||||||
|
|
||||||
namespace RoboidControl {
|
namespace RoboidControl {
|
||||||
|
|
||||||
@ -6,27 +6,50 @@ namespace RoboidControl {
|
|||||||
/// A temperature sensor
|
/// A temperature sensor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class TemperatureSensor : Thing {
|
public class TemperatureSensor : Thing {
|
||||||
|
/// <summary>
|
||||||
|
/// Create a temperature sensor without communication abilities
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="invokeEvent">Invoke a OnNewThing event when the thing has been created</param>
|
||||||
|
public TemperatureSensor(bool invokeEvent = true) : base(Type.TemperatureSensor, invokeEvent) { }
|
||||||
|
/// <summary>
|
||||||
|
/// Create a temperature sensor for a participant
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="owner">The participant for with the sensor is needed</param>
|
||||||
|
/// <param name="thingId">The ID of the thing</param>
|
||||||
|
/// <param name="invokeEvent">Invoke a OnNewThing event when the thing has been created</param>
|
||||||
|
public TemperatureSensor(Participant owner, byte thingId = 0, bool invokeEvent = true) : base(owner, Type.TemperatureSensor, thingId, invokeEvent) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a new child temperature sensor
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="parent">The parent thing</param>
|
||||||
|
/// <param name="thingId">The ID of the thing, leave out or set to zero to generate an ID</param>
|
||||||
|
/// <param name="invokeEvent">Invoke a OnNewThing event when the thing has been created</param>
|
||||||
|
public TemperatureSensor(Thing parent, byte thingId = 0, bool invokeEvent = true) : base(parent, Type.TemperatureSensor, thingId, invokeEvent) { }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The measured temperature
|
/// The measured temperature
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float temperature = 0;
|
public float temperature = 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a temperature sensor with the given ID
|
/// Function used to generate binary data for this temperature sensor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="participant">The participant for with the sensor is needed</param>
|
/// <returns>A byte array with the binary data</returns>
|
||||||
/// <param name="networkId">The network ID of the sensor</param>
|
public override byte[] GenerateBinary() {
|
||||||
/// <param name="thingId">The ID of the thing</param>
|
byte[] bytes = new byte[2];
|
||||||
public TemperatureSensor(Participant participant, byte thingId) : base(participant, Type.TemperatureSensor, thingId) { }
|
byte ix = 0;
|
||||||
|
LowLevelMessages.SendFloat16(bytes, ref ix, this.temperature);
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Function to extract the temperature received in the binary message
|
/// Function to process the temperature from the binary data
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="bytes">The byte array</param>
|
/// <param name="bytes">The binary data to process</param>
|
||||||
public override void ProcessBinary(byte[] bytes) {
|
public override void ProcessBinary(byte[] bytes) {
|
||||||
byte ix = 0;
|
byte ix = 0;
|
||||||
this.temperature = LowLevelMessages.ReceiveFloat16(bytes, ref ix);
|
this.temperature = LowLevelMessages.ReceiveFloat16(bytes, ref ix);
|
||||||
//Console.WriteLine($"temperature {this.name} = {this.temperature} C");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,32 +6,29 @@ namespace RoboidControl {
|
|||||||
/// A sensor which can detect touches
|
/// A sensor which can detect touches
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class TouchSensor : Thing {
|
public class TouchSensor : Thing {
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a touch sensor
|
/// Create a touch sensor without communication abilities
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="owner">The participant for with the sensor is needed</param>
|
/// <param name="invokeEvent">Invoke a OnNewThing event when the thing has been created</param>
|
||||||
/// <param name="invokeEvent">True when the creation should trigger an event</param>
|
public TouchSensor(bool invokeEvent = true) : base(Type.TouchSensor, invokeEvent) { }
|
||||||
public TouchSensor(Participant owner) : base(owner, Type.TouchSensor) {
|
/// <summary>
|
||||||
Console.Write("TouchSensor constructor");
|
/// Create a touch sensor for a participant
|
||||||
//touchedSomething = false;
|
/// </summary>
|
||||||
//thisParticipant = owner;
|
/// <param name="owner">The owning participant</param>
|
||||||
}
|
/// <param name="thingId">The ID of the thing, leave out or set to zero to generate an ID</param>
|
||||||
|
/// <param name="invokeEvent">Invoke a OnNewThing event when the thing has been created</param>
|
||||||
public TouchSensor(Participant owner, byte networkId, byte thingId) : base(owner, networkId, thingId) {
|
public TouchSensor(Participant owner, byte thingId = 0, bool invokeEvent = true) : base(owner, Type.TouchSensor, thingId, invokeEvent) { }
|
||||||
// Console.Write("TouchSensor constructor");
|
/// <summary>
|
||||||
//touchedSomething = false;
|
/// Create a new child touch sensor
|
||||||
//thisParticipant = participant;
|
/// </summary>
|
||||||
}
|
/// <param name="parent">The parent thing</param>
|
||||||
|
/// <param name="thingId">The ID of the thing, leave out or set to zero to generate an ID</param>
|
||||||
public TouchSensor(Thing parent, bool invokeEvent = true) : base(parent, (byte)Type.TouchSensor, invokeEvent) { }
|
/// <param name="invokeEvent">Invoke a OnNewThing event when the thing has been created</param>
|
||||||
|
public TouchSensor(Thing parent, byte thingId = 0, bool invokeEvent = true) : base(parent, Type.TouchSensor, thingId, invokeEvent) { }
|
||||||
public ParticipantUDP thisParticipant;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Value which is true when the sensor is touching something, false otherwise
|
/// Value which is true when the sensor is touching something, false otherwise
|
||||||
/// </summary>
|
/// </summary>
|
||||||
//public bool touchedSomething = false;
|
|
||||||
private bool _touchedSomething = false;
|
private bool _touchedSomething = false;
|
||||||
public bool touchedSomething {
|
public bool touchedSomething {
|
||||||
get { return _touchedSomething; }
|
get { return _touchedSomething; }
|
||||||
@ -52,14 +49,27 @@ namespace RoboidControl {
|
|||||||
this.component.core = this;
|
this.component.core = this;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
/// <summary>
|
||||||
|
/// Function used to generate binary data for this touch sensor
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A byte array with the binary data</returns>
|
||||||
|
/// <remark>The byte array will be empty when the touch status has not changed</remark>
|
||||||
public override byte[] GenerateBinary() {
|
public override byte[] GenerateBinary() {
|
||||||
if (!touchUpdated)
|
if (!touchUpdated)
|
||||||
return new byte[0];
|
return Array.Empty<byte>();
|
||||||
|
|
||||||
byte[] buffer = new byte[1];
|
byte[] bytes = new byte[1];
|
||||||
buffer[0] = (byte)(touchedSomething ? 1 : 0);
|
bytes[0] = (byte)(touchedSomething ? 1 : 0);
|
||||||
touchUpdated = false;
|
touchUpdated = false;
|
||||||
return buffer;
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Function used to process binary data received for this touch sensor
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bytes">The binary data to process</param>
|
||||||
|
public override void ProcessBinary(byte[] bytes) {
|
||||||
|
this.touchedSomething |= (bytes[0] == 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user