ControlCore compatibility

This commit is contained in:
Pascal Serrarens 2024-12-10 13:03:09 +01:00
parent 181deae258
commit f05ab5c742
11 changed files with 141 additions and 89 deletions

View File

@ -2,7 +2,7 @@
#include "Messages.h" #include "Messages.h"
DirectionalSensor::DirectionalSensor() { DirectionalSensor::DirectionalSensor() : Sensor() {
this->type = DirectionalSensor::Type; this->type = DirectionalSensor::Type;
this->vector = Spherical16::zero; this->vector = Spherical16::zero;
} }

View File

@ -15,10 +15,12 @@ DistanceSensor::DistanceSensor(float triggerDistance) : DistanceSensor() {
} }
float DistanceSensor::GetDistance() { float DistanceSensor::GetDistance() {
if (distance < minRange || distance > maxRange) if (this->distance < minRange || this->distance > maxRange)
return -1; // invalid distance return INFINITY; // invalid distance
return distance; float d = this->distance;
this->distance = INFINITY;
return d;
}; };
bool DistanceSensor::ObjectNearby() { bool DistanceSensor::ObjectNearby() {

View File

@ -14,7 +14,7 @@ Angle8 Messages::ReceiveAngle8(unsigned char *buffer,
float Messages::ReceiveFloat16(unsigned char *buffer, float Messages::ReceiveFloat16(unsigned char *buffer,
unsigned char *startIndex) { unsigned char *startIndex) {
unsigned char ix = *startIndex; unsigned char ix = *startIndex;
unsigned short value = buffer[ix++] << 8 | buffer[ix]; unsigned short value = buffer[ix++] << 8 | buffer[ix++];
float16 f = float16(); float16 f = float16();
f.setBinary(value); f.setBinary(value);
@ -27,10 +27,10 @@ Spherical16 Messages::ReceiveSpherical16(unsigned char *buffer,
float distance = ReceiveFloat16(buffer, startIndex); float distance = ReceiveFloat16(buffer, startIndex);
Angle8 horizontal8 = ReceiveAngle8(buffer, startIndex); Angle8 horizontal8 = ReceiveAngle8(buffer, startIndex);
Angle16 horizontal = Angle16::Binary(horizontal8.GetBinary() * 255); Angle16 horizontal = Angle16::Binary(horizontal8.GetBinary() * 256);
Angle8 vertical8 = ReceiveAngle8(buffer, startIndex); Angle8 vertical8 = ReceiveAngle8(buffer, startIndex);
Angle16 vertical = Angle16::Binary(vertical8.GetBinary() * 255); Angle16 vertical = Angle16::Binary(vertical8.GetBinary() * 256);
Spherical16 s = Spherical16(distance, horizontal, vertical); Spherical16 s = Spherical16(distance, horizontal, vertical);
return s; return s;
@ -63,6 +63,7 @@ void Messages::SendPolar(unsigned char *buffer, unsigned char *startIndex,
void Messages::SendSpherical16(unsigned char *buffer, unsigned char *startIndex, void Messages::SendSpherical16(unsigned char *buffer, unsigned char *startIndex,
Spherical16 s) { Spherical16 s) {
// Receive first does distance...
SendAngle8(buffer, (*startIndex)++, s.direction.horizontal.InDegrees()); SendAngle8(buffer, (*startIndex)++, s.direction.horizontal.InDegrees());
SendAngle8(buffer, (*startIndex)++, s.direction.vertical.InDegrees()); SendAngle8(buffer, (*startIndex)++, s.direction.vertical.InDegrees());
SendFloat16(buffer, startIndex, s.distance); SendFloat16(buffer, startIndex, s.distance);

View File

@ -16,8 +16,8 @@ void NetworkPerception::ProcessPacket(Roboid *roboid, unsigned char *buffer,
#endif #endif
switch (buffer[0]) { switch (buffer[0]) {
case NetworkSync::CreateMsg: case NetworkSync::ThingMsg:
ReceiveCreateMsg(buffer, roboid); ReceiveThingMsg(buffer, roboid);
break; break;
case NetworkSync::InvestigateMsg: case NetworkSync::InvestigateMsg:
ReceiveInvestigateMsg(buffer, roboid); ReceiveInvestigateMsg(buffer, roboid);
@ -31,7 +31,7 @@ void NetworkPerception::ProcessPacket(Roboid *roboid, unsigned char *buffer,
} }
} }
void NetworkPerception::ReceiveCreateMsg(unsigned char *data, Roboid *roboid) { void NetworkPerception::ReceiveThingMsg(unsigned char *data, Roboid *roboid) {
unsigned char networkId = data[1]; unsigned char networkId = data[1];
unsigned char objectId = data[2]; unsigned char objectId = data[2];
unsigned char objectType = data[3]; unsigned char objectType = data[3];
@ -50,30 +50,33 @@ void NetworkPerception::ReceiveCreateMsg(unsigned char *data, Roboid *roboid) {
void NetworkPerception::ReceiveInvestigateMsg(unsigned char *data, void NetworkPerception::ReceiveInvestigateMsg(unsigned char *data,
Roboid *roboid) { Roboid *roboid) {
unsigned char networkId = data[1]; unsigned char networkId = data[1];
unsigned char objectId = data[2]; unsigned char thingId = data[2];
#if RC_DEBUG // #if RC_DEBUG
printf("Received InvestigateMsg [%d/%d]\n", networkId, objectId); printf("Received InvestigateMsg [%d/%d]\n", networkId, thingId);
#endif // #endif
if (networkId != roboid->networkSync->networkId) if (networkId != roboid->networkSync->networkId)
// We only response to investigation requests for our own objects // We only response to investigation requests for our own objects
return; return;
if (objectId == 0x00) { if (thingId == 0x00) {
// They are investigating the roboid itself! // They are investigating the roboid itself!
if (roboid->modelUrl != nullptr) if (roboid->modelUrl != nullptr)
roboid->networkSync->SendModel(roboid); // roboid->networkSync->SendModel(roboid);
roboid->networkSync->SendThingInfo(roboid);
} else { } else {
InterestingThing *thing = Thing *thing = roboid->FindChild(thingId, true);
roboid->perception->FindTrackedObject(0x00, objectId); if (thing != nullptr)
if (thing == nullptr) roboid->networkSync->SendThingInfo(thing);
else {
InterestingThing *interestingThing =
roboid->perception->FindTrackedObject(0x00, thingId);
if (interestingThing == nullptr)
return; return;
// roboid->networkSync->NewObject(thing); roboid->networkSync->SendThingInfo(interestingThing, false);
// roboid->networkSync->SendThing(thing); }
// roboid->networkSync->SendModel(thing);
roboid->networkSync->SendThingInfo(thing, false);
} }
} }
@ -117,7 +120,8 @@ void NetworkPerception::ReceivePlane(unsigned char *data, Roboid *roboid) {
originPosition = roboid->worldOrigin->position; originPosition = roboid->worldOrigin->position;
} }
Spherical16 position = originPosition + originOrientation * worldPosition; Spherical16 position = originPosition + originOrientation * worldPosition;
// printf("Received plane (%f %f %f) (%f %f %f) %f %f %f\n", worldPosition.x, // printf("Received plane (%f %f %f) (%f %f %f) %f %f %f\n",
// worldPosition.x,
// worldPosition.y, worldPosition.z, roboidPosition.x, // worldPosition.y, worldPosition.z, roboidPosition.x,
// roboidPosition.y, roboidPosition.z, position.distance, // roboidPosition.y, roboidPosition.z, position.distance,
// (float)position.horizontalAngle, (float)position.verticalAngle); // (float)position.horizontalAngle, (float)position.verticalAngle);

View File

@ -12,7 +12,7 @@ public:
void ProcessPacket(Roboid *roboid, unsigned char *buffer, int packetsize); void ProcessPacket(Roboid *roboid, unsigned char *buffer, int packetsize);
protected: protected:
void ReceiveCreateMsg(unsigned char *data, Roboid *roboid); void ReceiveThingMsg(unsigned char *data, Roboid *roboid);
void ReceiveInvestigateMsg(unsigned char *data, Roboid *roboid); void ReceiveInvestigateMsg(unsigned char *data, Roboid *roboid);
void ReceivePoseMsg(unsigned char *data, Roboid *roboid); void ReceivePoseMsg(unsigned char *data, Roboid *roboid);
void ReceiveTypedObject(unsigned char *data, Roboid *roboid); void ReceiveTypedObject(unsigned char *data, Roboid *roboid);

View File

@ -24,33 +24,62 @@ NetworkSync::NetworkSync(Roboid *roboid) {
this->networkId = 0; this->networkId = 0;
} }
#include <Arduino.h>
void NetworkSync::ReceiveMessage(Roboid *roboid, unsigned char bytecount) { void NetworkSync::ReceiveMessage(Roboid *roboid, unsigned char bytecount) {
// printf("Received msgId %d, length %d\n", buffer[0], bytecount);
networkPerception->ProcessPacket(roboid, buffer, bytecount); networkPerception->ProcessPacket(roboid, buffer, bytecount);
switch (buffer[0]) { switch (buffer[0]) {
case NetworkIdMsg: case NetworkIdMsg:
ReceiveNetworkId(); ReceiveNetworkId();
break; break;
case BytesMsg: case CustomMsg:
ReceiveBytes(); ReceiveCustom(bytecount);
break; break;
} }
} }
// Actually, this is a kind of investigate... void NetworkSync::PublishClient() {
unsigned char ix = 0;
buffer[ix++] = ClientMsg;
buffer[ix++] = this->networkId;
PublishBuffer(ix);
#ifdef RC_DEBUG
SERIALPORT.printf("Publish Device\n");
#endif
}
void NetworkSync::ReceiveNetworkId() { void NetworkSync::ReceiveNetworkId() {
this->networkId = buffer[1]; this->networkId = buffer[1];
#ifdef RC_DEBUG #ifdef RC_DEBUG
SERIALPORT.printf("Received network Id %d\n", this->networkId); SERIALPORT.printf("Received network Id %d\n", this->networkId);
#endif #endif
SendThingInfo(roboid, true); SendThingInfo(roboid, true);
printf("completed\n");
} }
void NetworkSync::ReceiveBytes() { void NetworkSync::SendInvestigate(InterestingThing *thing) {
unsigned char ix = 0;
buffer[ix++] = InvestigateMsg;
buffer[ix++] = thing->networkId;
buffer[ix++] = thing->id;
SendBuffer(ix);
#ifdef RC_DEBUG
printf("Sent Investigate [%d/%d]\n", thing->networkId, thing->id);
#endif
}
void NetworkSync::ReceiveCustom(unsigned char packetSize) {
unsigned char ix = 1; // first byte is the msgId unsigned char ix = 1; // first byte is the msgId
unsigned char networkId = buffer[ix++]; unsigned char networkId = buffer[ix++];
unsigned char thingId = buffer[ix++]; unsigned char thingId = buffer[ix++];
unsigned char len = buffer[ix++]; // unsigned char len = buffer[ix++];
unsigned char len = packetSize - 3;
printf("Custom size = %d\n", len);
if (len > 0) {
unsigned char *bytes = new unsigned char[len]; unsigned char *bytes = new unsigned char[len];
// printf("Received %d bytes for [%d/%d]\n", len, networkId, thingId); // printf("Received %d bytes for [%d/%d]\n", len, networkId, thingId);
for (unsigned char bytesIx = 0; bytesIx < len; bytesIx++) for (unsigned char bytesIx = 0; bytesIx < len; bytesIx++)
@ -58,22 +87,12 @@ void NetworkSync::ReceiveBytes() {
// networkId is not used right now, we assume networkId == 0 // networkId is not used right now, we assume networkId == 0
Thing *thing = roboid->FindChild(thingId); Thing *thing = roboid->FindChild(thingId);
// printf("Found thing %d\n", thing); printf("Found thing %s\n", thing->name);
if (thing != nullptr) if (thing != nullptr)
thing->ProcessBytes(bytes); thing->ProcessBytes(bytes);
delete bytes; delete bytes;
} }
void NetworkSync::PublishClient() {
unsigned char ix = 0;
buffer[ix++] = DeviceMsg;
buffer[ix++] = this->networkId;
PublishBuffer(ix);
#ifdef RC_DEBUG
SERIALPORT.printf("Publish Device\n");
#endif
} }
void NetworkSync::PublishState(Roboid *roboid) { void NetworkSync::PublishState(Roboid *roboid) {
@ -85,6 +104,8 @@ void NetworkSync::SendThingInfo(Thing *thing, bool recurse) {
SendThing(thing); SendThing(thing);
SendName(thing); SendName(thing);
SendModel(thing); SendModel(thing);
SendCustom(thing);
SendPose(thing, true, false);
if (recurse) { if (recurse) {
for (unsigned char childIx = 0; childIx < thing->childCount; childIx++) { for (unsigned char childIx = 0; childIx < thing->childCount; childIx++) {
@ -100,9 +121,10 @@ void NetworkSync::SendThing(Thing *thing) {
return; return;
unsigned char ix = 0; unsigned char ix = 0;
buffer[ix++] = CreateMsg; buffer[ix++] = ThingMsg;
buffer[ix++] = this->networkId;
buffer[ix++] = thing->id; buffer[ix++] = thing->id;
buffer[ix++] = thing->type; buffer[ix++] = (unsigned char)thing->type;
Thing *parentThing = thing->GetParent(); Thing *parentThing = thing->GetParent();
if (parentThing != nullptr) if (parentThing != nullptr)
buffer[ix++] = parentThing->id; buffer[ix++] = parentThing->id;
@ -111,7 +133,7 @@ void NetworkSync::SendThing(Thing *thing) {
SendBuffer(ix); SendBuffer(ix);
#ifdef RC_DEBUG #ifdef RC_DEBUG
printf("Sent Thing [%d/%d] %d\n", networkId, thing->id, thing->type); printf("Sent Thing [%d/%d] %d\n", networkId, thing->id, (byte)thing->type);
#endif #endif
} }
@ -125,6 +147,7 @@ void NetworkSync::SendName(Thing *thing) {
unsigned char ix = 0; unsigned char ix = 0;
buffer[ix++] = NameMsg; buffer[ix++] = NameMsg;
buffer[ix++] = this->networkId;
buffer[ix++] = thing->id; buffer[ix++] = thing->id;
buffer[ix++] = len; buffer[ix++] = len;
@ -149,9 +172,10 @@ void NetworkSync::SendModel(Thing *thing) {
unsigned char ix = 0; unsigned char ix = 0;
buffer[ix++] = ModelMsg; buffer[ix++] = ModelMsg;
buffer[ix++] = this->networkId;
buffer[ix++] = thing->id; // objectId buffer[ix++] = thing->id; // objectId
Spherical16 s = Spherical16::zero; // Spherical(thing->modelPosition); // Spherical16 s = Spherical16::zero; // Spherical(thing->modelPosition);
Messages::SendSpherical16(buffer, &ix, s); // Messages::SendSpherical16(buffer, &ix, s);
Messages::SendFloat16(buffer, &ix, thing->modelScale); Messages::SendFloat16(buffer, &ix, thing->modelScale);
buffer[ix++] = len; buffer[ix++] = len;
@ -161,12 +185,24 @@ void NetworkSync::SendModel(Thing *thing) {
SendBuffer(ix); SendBuffer(ix);
} }
void NetworkSync::SendCustom(Thing *thing) {
unsigned char ix = 0;
buffer[ix++] = NetworkSync::CustomMsg;
buffer[ix++] = this->networkId;
buffer[ix++] = thing->id;
thing->SendBytes(buffer, &ix);
if (ix > 3) // When ix <= 3 then there is no custom data
SendBuffer(ix);
}
void NetworkSync::SendDestroyThing(InterestingThing *thing) { void NetworkSync::SendDestroyThing(InterestingThing *thing) {
if (networkId == 0) // We're not connected to a site yet if (networkId == 0) // We're not connected to a site yet
return; return;
unsigned char ix = 0; unsigned char ix = 0;
buffer[ix++] = DestroyMsg; buffer[ix++] = DestroyMsg;
buffer[ix++] = this->networkId;
buffer[ix++] = thing->id; buffer[ix++] = thing->id;
SendBuffer(ix); SendBuffer(ix);
@ -175,20 +211,21 @@ void NetworkSync::SendDestroyThing(InterestingThing *thing) {
#endif #endif
} }
void NetworkSync::SendPose(Thing *thing, bool recurse) { void NetworkSync::SendPose(Thing *thing, bool force, bool recurse) {
if (this->networkId == 0) // We're not connected to a site yet if (this->networkId == 0) // We're not connected to a site yet
return; return;
thing->positionUpdated |= thing->GetLinearVelocity().distance > 0; thing->positionUpdated |= thing->GetLinearVelocity().distance > 0;
thing->orientationUpdated |= thing->GetAngularVelocity().distance > 0; thing->orientationUpdated |= thing->GetAngularVelocity().distance > 0;
if (thing->positionUpdated || thing->orientationUpdated) { if (force || thing->positionUpdated || thing->orientationUpdated) {
unsigned char ix = 0; unsigned char ix = 0;
buffer[ix++] = PoseMsg; buffer[ix++] = PoseMsg;
buffer[ix++] = this->networkId;
buffer[ix++] = thing->id; buffer[ix++] = thing->id;
unsigned char pattern = 0; unsigned char pattern = 0;
if (thing->positionUpdated) if (force || thing->positionUpdated)
pattern |= Pose_Position; pattern |= Pose_Position;
if (thing->orientationUpdated) if (force || thing->orientationUpdated)
pattern |= Pose_Orientation; pattern |= Pose_Orientation;
buffer[ix++] = pattern; buffer[ix++] = pattern;
Messages::SendSpherical16(buffer, &ix, thing->position); Messages::SendSpherical16(buffer, &ix, thing->position);
@ -214,7 +251,7 @@ void NetworkSync::SendPose(Thing *thing, bool recurse) {
for (unsigned char childIx = 0; childIx < thing->childCount; childIx++) { for (unsigned char childIx = 0; childIx < thing->childCount; childIx++) {
Thing *child = thing->GetChild(childIx); Thing *child = thing->GetChild(childIx);
if (child != nullptr) if (child != nullptr)
SendPose(thing->GetChild(childIx), true); SendPose(thing->GetChild(childIx), force, recurse);
} }
} }
} }
@ -300,6 +337,7 @@ void NetworkSync::PublishTrackedObject(Roboid *roboid,
unsigned char ix = 0; unsigned char ix = 0;
buffer[ix++] = PoseMsg; // Position2DMsg; buffer[ix++] = PoseMsg; // Position2DMsg;
buffer[ix++] = this->networkId;
buffer[ix++] = thing->id; // objectId; buffer[ix++] = thing->id; // objectId;
buffer[ix++] = Pose_Position | Pose_Orientation; buffer[ix++] = Pose_Position | Pose_Orientation;
Messages::SendSpherical16(buffer, &ix, worldPosition); Messages::SendSpherical16(buffer, &ix, worldPosition);
@ -313,17 +351,6 @@ void NetworkSync::PublishTrackedObject(Roboid *roboid,
thing->updated = false; thing->updated = false;
} }
void NetworkSync::SendInvestigate(InterestingThing *thing) {
unsigned char ix = 0;
buffer[ix++] = InvestigateMsg;
buffer[ix++] = thing->networkId;
buffer[ix++] = thing->id;
SendBuffer(ix);
#ifdef RC_DEBUG
printf("Sent Investigate [%d/%d]\n", thing->networkId, thing->id);
#endif
}
void NetworkSync::SendText(const char *s) { void NetworkSync::SendText(const char *s) {
unsigned char length; unsigned char length;
for (length = 0; length < 253; length++) { for (length = 0; length < 253; length++) {

View File

@ -27,6 +27,7 @@ public:
void SendThing(Thing *thing); void SendThing(Thing *thing);
void SendName(Thing *roboid); void SendName(Thing *roboid);
void SendModel(Thing *thing); void SendModel(Thing *thing);
void SendCustom(Thing *thing);
/// @brief The id of a Pose message /// @brief The id of a Pose message
static const unsigned char PoseMsg = 0x10; static const unsigned char PoseMsg = 0x10;
@ -51,13 +52,13 @@ public:
static const unsigned char AngVelocity2DMsg = 0x46; static const unsigned char AngVelocity2DMsg = 0x46;
static const unsigned char Position2DMsg = 0x61; static const unsigned char Position2DMsg = 0x61;
static const unsigned char Velocity2DMsg = 0x62; static const unsigned char Velocity2DMsg = 0x62;
static const unsigned char CreateMsg = 0x80; static const unsigned char ThingMsg = 0x80;
static const unsigned char InvestigateMsg = 0x81; static const unsigned char InvestigateMsg = 0x81;
static const unsigned char ModelMsg = 0x90; static const unsigned char ModelMsg = 0x90;
static const unsigned char NameMsg = 0x91; static const unsigned char NameMsg = 0x91;
static const unsigned char DeviceMsg = 0xA0; static const unsigned char ClientMsg = 0xA0;
static const unsigned char NetworkIdMsg = 0xA1; static const unsigned char NetworkIdMsg = 0xA1;
static const unsigned char BytesMsg = 0xB1; static const unsigned char CustomMsg = 0xB1;
typedef void (*Buffer)(UInt8 *buffer, UInt16 bufferSize); typedef void (*Buffer)(UInt8 *buffer, UInt16 bufferSize);
@ -74,7 +75,7 @@ public:
virtual void SendPose(Spherical16 worldPosition, virtual void SendPose(Spherical16 worldPosition,
SwingTwist16 worldOrientation) {}; SwingTwist16 worldOrientation) {};
// void SendPose(Roboid* roboid, bool recurse = true); // void SendPose(Roboid* roboid, bool recurse = true);
void SendPose(Thing *thing, bool recurse = true); void SendPose(Thing *thing, bool force = 0, bool recurse = true);
virtual void SendText(const char *s); virtual void SendText(const char *s);
void SendInt(const int x); void SendInt(const int x);
@ -86,7 +87,7 @@ protected:
NetworkPerception *networkPerception; NetworkPerception *networkPerception;
void ReceiveNetworkId(); void ReceiveNetworkId();
void ReceiveBytes(); void ReceiveCustom(unsigned char packetSize);
void PublishState(Sensor *sensor); void PublishState(Sensor *sensor);

View File

@ -22,6 +22,7 @@ Roboid::Roboid() : Thing(0) {
this->networkSync = nullptr; this->networkSync = nullptr;
this->position = Spherical16::zero; this->position = Spherical16::zero;
this->orientation = SwingTwist16::identity; this->orientation = SwingTwist16::identity;
this->lastUpdateTimeMs = 0;
} }
Roboid::Roboid(Propulsion *propulsion) : Roboid() { Roboid::Roboid(Propulsion *propulsion) : Roboid() {
@ -31,8 +32,11 @@ Roboid::Roboid(Propulsion *propulsion) : Roboid() {
} }
void Roboid::Update(unsigned long currentTimeMs) { void Roboid::Update(unsigned long currentTimeMs) {
if (perception != nullptr) if (this->lastUpdateTimeMs == 0)
perception->Update(currentTimeMs); this->lastUpdateTimeMs = currentTimeMs;
// if (perception != nullptr)
// perception->Update(currentTimeMs);
if (propulsion != nullptr) { if (propulsion != nullptr) {
propulsion->Update(currentTimeMs); propulsion->Update(currentTimeMs);

View File

@ -2,7 +2,7 @@
#include "Roboid.h" #include "Roboid.h"
Sensor::Sensor() : Thing(0) { // for now, id should be set properly later Sensor::Sensor() : Thing() { // for now, id should be set properly later
this->type = Thing::SensorType; this->type = Thing::SensorType;
} }

View File

@ -4,6 +4,16 @@
using namespace Passer::RoboidControl; using namespace Passer::RoboidControl;
int Thing::lastThingId = 1;
Thing::Thing() {
this->id = lastThingId++;
this->type = (unsigned int)Type::Undetermined;
this->childCount = 0;
this->parent = nullptr;
this->children = nullptr;
}
Thing::Thing(unsigned char id) : id(id) { Thing::Thing(unsigned char id) : id(id) {
// this->position = SphericalOf<signed short>::zero; // this->position = SphericalOf<signed short>::zero;
this->type = (unsigned int)Type::Undetermined; this->type = (unsigned int)Type::Undetermined;

View File

@ -11,6 +11,7 @@ namespace RoboidControl {
/// @brief A thing is a functional component on a robot /// @brief A thing is a functional component on a robot
class Thing { class Thing {
public: public:
Thing();
/// @brief Default constructor for a Thing /// @brief Default constructor for a Thing
Thing(unsigned char id); Thing(unsigned char id);
@ -108,9 +109,11 @@ public:
const char *modelUrl = nullptr; const char *modelUrl = nullptr;
float modelScale = 1; float modelScale = 1;
virtual void ProcessBytes(unsigned char *bytes) {} virtual void SendBytes(unsigned char *buffer, unsigned char *ix) {};
virtual void ProcessBytes(unsigned char *bytes) {};
protected: protected:
static int lastThingId;
/// @brief Bitmask for Motor type /// @brief Bitmask for Motor type
static const unsigned int MotorType = 0x8000; static const unsigned int MotorType = 0x8000;
/// @brief Bitmap for Sensor type /// @brief Bitmap for Sensor type