diff --git a/DifferentialDrive.cpp b/DifferentialDrive.cpp
index 79ef43f..4998514 100644
--- a/DifferentialDrive.cpp
+++ b/DifferentialDrive.cpp
@@ -14,10 +14,10 @@ DifferentialDrive::DifferentialDrive(Motor *leftMotor, Motor *rightMotor) {
 
   float distance = this->wheelSeparation / 2;
   leftMotor->direction = Motor::Direction::CounterClockwise;
-  leftMotor->position.angle = -90;
+  leftMotor->position.horizontalAngle = -90;
   leftMotor->position.distance = distance;
   rightMotor->direction = Motor::Direction::Clockwise;
-  rightMotor->position.angle = 90;
+  rightMotor->position.horizontalAngle = 90;
   rightMotor->position.distance = distance;
 }
 
@@ -39,7 +39,7 @@ void DifferentialDrive::SetMotorTargetSpeeds(float leftSpeed,
     if (motor == nullptr)
       continue;
 
-    float xPosition = motors[motorIx]->position.angle;
+    float xPosition = motors[motorIx]->position.horizontalAngle;
     if (xPosition < 0)
       motor->SetTargetSpeed(leftSpeed);
     else if (xPosition > 0)
diff --git a/Motor.cpp b/Motor.cpp
index 3b5eb4f..c005d72 100644
--- a/Motor.cpp
+++ b/Motor.cpp
@@ -2,7 +2,9 @@
 
 #include <time.h>
 
-Motor::Motor() { type = (int)Thing::UncontrolledMotorType; }
+Motor::Motor() : Thing(0) { // for now, id should be set properly later
+  this->type = (int)Thing::UncontrolledMotorType;
+}
 
 float Motor::GetActualSpeed() { return this->currentTargetSpeed; }
 
diff --git a/NetworkSync.cpp b/NetworkSync.cpp
index abd2014..6e60913 100644
--- a/NetworkSync.cpp
+++ b/NetworkSync.cpp
@@ -25,12 +25,18 @@ void NetworkSync::ReceiveMessage(Roboid *roboid, unsigned char bytecount) {
   }
 }
 
+#include <Arduino.h>
+
 void NetworkSync::ReceiveNetworkId() {
   this->networkId = buffer[1];
 #ifdef RC_DEBUG
   printf("_Received network Id %d\n", this->networkId);
 #endif
+  delay(100);
   PublishModel(roboid);
+  delay(100);
+  if (roboid->actuationRoot != nullptr)
+    PublishRelativeThing(roboid->actuationRoot, true);
 }
 
 void NetworkSync::NewObject(InterestingThing *thing) {
@@ -50,29 +56,71 @@ void NetworkSync::NewObject(InterestingThing *thing) {
   // PublishTrackedObject(roboid, obj);
 }
 
+void NetworkSync::PublishRelativeThing(Thing *thing, bool recurse) {
+  Thing *parentThing = thing->GetParent();
+
+  unsigned char ix = 0;
+  buffer[ix++] = RelativePoseMsg;
+  buffer[ix++] = thing->id;
+  if (parentThing != nullptr)
+    buffer[ix++] = parentThing->id;
+  else
+    buffer[ix++] = 0x00;
+  SendSpherical(buffer, &ix, thing->position);
+  SendBuffer(ix);
+
+  delay(100);
+  PublishModel(thing);
+
+  delay(1000);
+  if (recurse) {
+    Thing *child = thing->GetChild(0);
+    if (child != nullptr)
+      PublishRelativeThing(child, true);
+  }
+}
+
 void NetworkSync::PublishModel(Roboid *roboid) {
   if (roboid->modelUrl == nullptr)
     return;
 
-  int len = strlen(roboid->modelUrl);
+  unsigned char len = strlen(roboid->modelUrl);
   if (len > 255)
     return;
 
   unsigned char ix = 0;
   buffer[ix++] = 0x90; // modelMsg
   buffer[ix++] = 0x00; // objectId
-  // SendVector3(buffer, &ix, position);
-  // Polar polar = Polar(Vector2(position));
-  // SendPolar(buffer, &ix, polar);
   Spherical s = Spherical(roboid->modelPosition);
   SendSpherical(buffer, &ix, s);
   SendFloat16(buffer, &ix, roboid->modelScale);
 
   buffer[ix++] = len;
-  // printf("send url %d, scale = %f \n", ix, sscale);
-  for (int urlIx = 0; urlIx < len; urlIx++) {
+  for (int urlIx = 0; urlIx < len; urlIx++)
     buffer[ix++] = roboid->modelUrl[urlIx];
-  }
+
+  SendBuffer(ix);
+}
+
+void NetworkSync::PublishModel(Thing *thing) {
+  if (thing->modelUrl == nullptr)
+    return;
+
+  unsigned char len = strlen(thing->modelUrl);
+  if (len > 255)
+    return;
+
+  unsigned char ix = 0;
+  buffer[ix++] = 0x90;      // modelMsg
+  buffer[ix++] = thing->id; // objectId
+  Spherical s = Spherical(thing->modelPosition);
+  SendSpherical(buffer, &ix, s);
+  SendFloat16(buffer, &ix, thing->modelScale);
+
+  buffer[ix++] = len;
+  for (int urlIx = 0; urlIx < len; urlIx++)
+    buffer[ix++] = thing->modelUrl[urlIx];
+
   SendBuffer(ix);
 }
 
@@ -87,151 +135,61 @@ void NetworkSync::DestroyObject(InterestingThing *thing) {
 #endif
 }
 
-void NetworkSync::SendPose(Roboid *roboid) {
-  if (roboid->propulsion == nullptr)
-    return;
+void NetworkSync::SendPose(Roboid *roboid, bool recurse) {
+  // if (roboid->propulsion == nullptr)
+  //   return;
 
-  Polar velocity = roboid->propulsion->GetVelocity();
-  Vector2 worldVelocity2 =
-      Vector2::Rotate(Vector2::forward * velocity.distance, velocity.angle);
-  Vector3 worldVelocity3 = Vector3(worldVelocity2.x, 0, worldVelocity2.y);
+  // Polar velocity = roboid->propulsion->GetVelocity();
+  // Vector2 worldVelocity2 =
+  //     Vector2::Rotate(Vector2::forward * velocity.distance, velocity.angle);
+  // Vector3 worldVelocity3 = Vector3(worldVelocity2.x, 0, worldVelocity2.y);
 
-  float angularVelocity = roboid->propulsion->GetAngularVelocity();
-  Vector3 worldAngularVelocity = Vector3(0, angularVelocity, 0);
+  // float angularVelocity = roboid->propulsion->GetAngularVelocity();
+  // Vector3 worldAngularVelocity = Vector3(0, angularVelocity, 0);
 
-  unsigned char buffer[3 + 12 + 12] = {
-      PoseMsg,
-      0, // objectId;
-      Pose_LinearVelocity | Pose_AngularVelocity,
-  };
-  unsigned char ix = 3;
-  SendVector3(buffer, &ix, worldVelocity3);
-  SendVector3(buffer, &ix, worldAngularVelocity);
+  // unsigned char buffer[3 + 12 + 12] = {
+  //     PoseMsg,
+  //     0, // objectId;
+  //     Pose_LinearVelocity | Pose_AngularVelocity,
+  // };
+  // unsigned char ix = 3;
+  // SendVector3(buffer, &ix, worldVelocity3);
+  // SendVector3(buffer, &ix, worldAngularVelocity);
 
+  // SendBuffer(ix);
+
+  unsigned char ix = 0;
+  buffer[ix++] = PoseMsg;
+  buffer[ix++] = 0x00;
+  buffer[ix++] = Pose_Position | Pose_Orientation;
+  SendSpherical(buffer, &ix, Spherical(roboid->GetPosition()));
+  SendQuat32(buffer, &ix, roboid->GetOrientation());
   SendBuffer(ix);
-}
 
-void NetworkSync::SendVector3(unsigned char *data, unsigned char *startIndex,
-                              const Vector3 v) {
-  SendSingle100(data, *startIndex, v.Right());
-  (*startIndex) += 4;
-  SendSingle100(data, *startIndex, v.Up());
-  (*startIndex) += 4;
-  SendSingle100(data, *startIndex, v.Forward());
-  (*startIndex) += 4;
-}
-
-void NetworkSync::SendQuaternion(unsigned char *data, const int startIndex,
-                                 const Quaternion q) {
-  Vector3 angles = Quaternion::ToAngles(q);
-  int ix = startIndex;
-  SendAngle8(data, ix++, angles.Right());
-  SendAngle8(data, ix++, angles.Up());
-  SendAngle8(data, ix++, angles.Forward());
-}
-
-void NetworkSync::SendPolar(unsigned char *data, unsigned char *startIndex,
-                            Polar p) {
-  SendAngle8(data, *startIndex, (const float)p.angle);
-  SendSingle100(data, (*startIndex) + 1, p.distance);
-}
-
-void NetworkSync::SendSpherical(unsigned char *data, unsigned char *startIndex,
-                                Spherical s) {
-  SendAngle8(data, (*startIndex)++, s.horizontalAngle);
-  SendAngle8(data, (*startIndex)++, s.verticalAngle);
-  // SendAngle8(data, startIndex++, s.distance);
-  SendFloat16(data, startIndex, s.distance);
-}
-
-// void NetworkSync::SendSpherical16(unsigned char *data, int startIndex,
-//                                   Spherical s) {
-//   SendAngle16(data, startIndex, s.horizontalAngle);
-//   SendAngle16(data, startIndex += 2, s.verticalAngle);
-//   SendSingle100(data, startIndex += 2, s.distance);
-// }
-
-// void NetworkSync::SendSpherical32(unsigned char *data, int startIndex,
-//                                   Spherical s) {
-//   SendAngle32(data, startIndex, s.horizontalAngle);
-//   SendAngle32(data, startIndex += 4, s.verticalAngle);
-//   SendSingle100(data, startIndex += 4, s.distance);
-// }
-
-void NetworkSync::SendQuat32(unsigned char *data, unsigned char *startIndex,
-                             const Quaternion q) {
-  unsigned char qx = (char)(q.x * 127 + 128);
-  unsigned char qy = (char)(q.y * 127 + 128);
-  unsigned char qz = (char)(q.z * 127 + 128);
-  unsigned char qw = (char)(q.w * 255);
-  if (q.w < 0) {
-    qx = -qx;
-    qy = -qy;
-    qz = -qz;
-    qw = -qw;
-  }
-  // Serial.printf(" (%d) %d:%d:%d:%d ", startIndex, qx, qy, qz, qw);
-  data[(*startIndex)++] = qx;
-  data[(*startIndex)++] = qy;
-  data[(*startIndex)++] = qz;
-  data[(*startIndex)++] = qw;
-}
-
-void NetworkSync::SendAngle8(unsigned char *data, unsigned int startIndex,
-                             const float angle) {
-  AngleUsing<signed char> packedAngle = AngleUsing<signed char>(angle);
-  data[startIndex] = packedAngle.GetValue();
-}
-
-// void NetworkSync::SendAngle16(unsigned char *data, unsigned int startIndex,
-//                               const float angle) {
-//   AngleUsing<signed short> packedAngle = AngleUsing<signed short>(angle);
-//   signed short value = packedAngle.GetValue();
-//   data[startIndex] = value >> 8;
-//   data[startIndex + 1] = value & 0xFF;
-// }
-
-// void NetworkSync::SendAngle32(unsigned char *data, unsigned int startIndex,
-//                               const float angle) {
-//   AngleUsing<signed long> packedAngle = AngleUsing<signed long>(angle);
-//   unsigned long value = packedAngle.GetValue();
-//   data[startIndex] = value >> 24 & 0xFF;
-//   data[startIndex + 1] = value >> 16 & 0xFF;
-//   data[startIndex + 2] = value >> 8 & 0xFF;
-//   data[startIndex + 3] = value & 0xFF;
-//   // Serial.printf(" %lu=%d:%d:%d:%d ", value, data[startIndex],
-//   //               data[startIndex + 1], data[startIndex + 2],
-//   //               data[startIndex + 3]);
-// }
-
-void NetworkSync::SendSingle100(unsigned char *data, unsigned int startIndex,
-                                float value) {
-  // Sends a float with truncated 2 decimal precision
-  Int32 intValue = value * 100;
-  SendInt32(data, startIndex, intValue);
-  // for (unsigned char ix = 0; ix < 4; ix++) {
-  //   data[startIndex + ix] = ((unsigned char *)&intValue)[ix];
-  // }
-}
-void NetworkSync::SendFloat16(unsigned char *data, unsigned char *startIndex,
-                              float value) {
-  float16 value16 = float16(value);
-  short binary = value16.getBinary();
-
-  data[(*startIndex)++] = (binary >> 8) & 0xFF;
-  data[(*startIndex)++] = binary & 0xFF;
-}
-
-void NetworkSync::SendInt32(unsigned char *data, unsigned int startIndex,
-                            Int32 value) {
-  for (unsigned char ix = 0; ix < 4; ix++) {
-    data[startIndex++] = ((unsigned char *)&value)[ix];
+  if (recurse) {
+    delay(10);
+    Thing *child = roboid->actuationRoot;
+    if (child != nullptr)
+      SendPose(child, true);
   }
 }
 
-// static unsigned char buffer[100];
+void NetworkSync::SendPose(Thing *thing, bool recurse) {
+  unsigned char ix = 0;
+  buffer[ix++] = PoseMsg;
+  buffer[ix++] = thing->id;
+  buffer[ix++] = Pose_Position | Pose_Orientation;
+  SendSpherical(buffer, &ix, thing->position);
+  SendQuat32(buffer, &ix, thing->orientation);
+  SendBuffer(ix);
 
-void NetworkSync::SendBuffer(unsigned char bufferSize) {}
+  if (recurse) {
+    delay(10);
+    Thing *child = thing->GetChild(0);
+    if (child != nullptr)
+      SendPose(child, true);
+  }
+}
 
 void NetworkSync::PublishClient() {
   unsigned char ix = 0;
@@ -242,6 +200,10 @@ void NetworkSync::PublishClient() {
 #ifdef RC_DEBUG
   printf("Sent new Client\n");
 #endif
+
+  // PublishModel(roboid);
+  // if (roboid->actuationRoot != nullptr)
+  //   PublishRelativeThing(roboid->actuationRoot, false);
 }
 
 void NetworkSync::PublishTrackedObjects(Roboid *roboid,
@@ -296,68 +258,6 @@ void NetworkSync::PublishTrackedObject(Roboid *roboid,
 #endif
 }
 
-// void NetworkSync::PublishTrackedObjects(Buffer sendBuffer,
-//                                         InterestingThing **objects) {
-//   for (unsigned char objIx = 0; objIx < Perception::maxObjectCount; objIx++)
-//   {
-//     InterestingThing *obj = objects[objIx];
-//     if (obj == nullptr)
-//       continue;
-//     if (obj->networkId != 0x00)
-//       continue; // object is external
-//     // if (obj->sensor->type == Thing::ExternalType)
-//     //   continue;
-
-//     // tmp
-//     obj->id = objIx;
-//     PublishTrackedObject(sendBuffer, obj);
-//   }
-// }
-
-// void NetworkSync::PublishTrackedObject(Buffer sendBuffer,
-//                                        InterestingThing *object) {
-//   Vector2 worldPosition2 =
-//       Vector2::Rotate(Vector2::forward * object->position.distance,
-//                       -object->position.horizontalAngle);
-//   Vector3 worldPosition3 = Vector3(worldPosition2.x, 0, worldPosition2.y);
-
-// #ifdef RC_DEBUG
-//   Serial.print("Send Pose ");
-//   Serial.print((int)object->id);
-//   Serial.print("  Position  ");
-//   Serial.print(worldPosition3.Right());
-//   Serial.print(", ");
-//   Serial.print(worldPosition3.Up());
-//   Serial.print(", ");
-//   Serial.println(worldPosition3.Forward());
-// #else
-//   const UInt16 bufferSize = 3 + 12;
-//   UInt8 buffer[bufferSize] = {
-//       PoseMsg,
-//       (UInt8)object->id,
-//       Pose_Position,
-//   };
-//   unsigned char ix = 3;
-//   SendVector3(buffer, &ix, worldPosition3);
-//   sendBuffer(buffer, bufferSize);
-// #endif
-// }
-
-// void NetworkSync::PublishRelativeObject(Buffer sendBuffer, UInt8 parentId,
-//                                         InterestingThing *object) {
-//   const UInt16 bufferSize = 4 + 12;
-//   UInt8 buffer[bufferSize] = {
-//       RelativePoseMsg,
-//       (UInt8)parentId,
-//       (UInt8)object->id,
-//       Pose_Position,
-//   };
-//   unsigned char ix = 4;
-//   SendSpherical(buffer, &ix, object->position);
-//   // SendVector3(buffer, ix, worldPosition3);
-//   sendBuffer(buffer, bufferSize);
-// }
-
 void NetworkSync::SendPoseMsg(Buffer sendBuffer, Roboid *roboid) {
   Polar velocity = roboid->propulsion->GetVelocity();
   Vector2 worldVelocity2 =
@@ -432,4 +332,112 @@ void NetworkSync::SendText(const char *s) {
     buffer[ix++] = s[urlIx];
 
   SendBuffer(ix);
-}
\ No newline at end of file
+}
+
+// Low-level functions
+
+void NetworkSync::SendVector3(unsigned char *data, unsigned char *startIndex,
+                              const Vector3 v) {
+  SendSingle100(data, *startIndex, v.Right());
+  (*startIndex) += 4;
+  SendSingle100(data, *startIndex, v.Up());
+  (*startIndex) += 4;
+  SendSingle100(data, *startIndex, v.Forward());
+  (*startIndex) += 4;
+}
+
+void NetworkSync::SendQuaternion(unsigned char *data, const int startIndex,
+                                 const Quaternion q) {
+  Vector3 angles = Quaternion::ToAngles(q);
+  int ix = startIndex;
+  SendAngle8(data, ix++, angles.Right());
+  SendAngle8(data, ix++, angles.Up());
+  SendAngle8(data, ix++, angles.Forward());
+}
+
+void NetworkSync::SendPolar(unsigned char *data, unsigned char *startIndex,
+                            Polar p) {
+  SendAngle8(data, *startIndex, (const float)p.angle);
+  SendSingle100(data, (*startIndex) + 1, p.distance);
+}
+
+void NetworkSync::SendSpherical(unsigned char *data, unsigned char *startIndex,
+                                Spherical s) {
+  SendAngle8(data, (*startIndex)++, s.horizontalAngle);
+  SendAngle8(data, (*startIndex)++, s.verticalAngle);
+  // SendAngle8(data, startIndex++, s.distance);
+  SendFloat16(data, startIndex, s.distance);
+}
+
+void NetworkSync::SendQuat32(unsigned char *data, unsigned char *startIndex,
+                             const Quaternion q) {
+  unsigned char qx = (char)(q.x * 127 + 128);
+  unsigned char qy = (char)(q.y * 127 + 128);
+  unsigned char qz = (char)(q.z * 127 + 128);
+  unsigned char qw = (char)(q.w * 255);
+  if (q.w < 0) {
+    qx = -qx;
+    qy = -qy;
+    qz = -qz;
+    qw = -qw;
+  }
+  // Serial.printf(" (%d) %d:%d:%d:%d ", startIndex, qx, qy, qz, qw);
+  data[(*startIndex)++] = qx;
+  data[(*startIndex)++] = qy;
+  data[(*startIndex)++] = qz;
+  data[(*startIndex)++] = qw;
+}
+
+void NetworkSync::SendAngle8(unsigned char *data, unsigned int startIndex,
+                             const float angle) {
+  AngleUsing<signed char> packedAngle = AngleUsing<signed char>(angle);
+  data[startIndex] = packedAngle.GetValue();
+}
+
+// void NetworkSync::SendAngle16(unsigned char *data, unsigned int startIndex,
+//                               const float angle) {
+//   AngleUsing<signed short> packedAngle = AngleUsing<signed short>(angle);
+//   signed short value = packedAngle.GetValue();
+//   data[startIndex] = value >> 8;
+//   data[startIndex + 1] = value & 0xFF;
+// }
+
+// void NetworkSync::SendAngle32(unsigned char *data, unsigned int startIndex,
+//                               const float angle) {
+//   AngleUsing<signed long> packedAngle = AngleUsing<signed long>(angle);
+//   unsigned long value = packedAngle.GetValue();
+//   data[startIndex] = value >> 24 & 0xFF;
+//   data[startIndex + 1] = value >> 16 & 0xFF;
+//   data[startIndex + 2] = value >> 8 & 0xFF;
+//   data[startIndex + 3] = value & 0xFF;
+//   // Serial.printf(" %lu=%d:%d:%d:%d ", value, data[startIndex],
+//   //               data[startIndex + 1], data[startIndex + 2],
+//   //               data[startIndex + 3]);
+// }
+
+void NetworkSync::SendSingle100(unsigned char *data, unsigned int startIndex,
+                                float value) {
+  // Sends a float with truncated 2 decimal precision
+  Int32 intValue = value * 100;
+  SendInt32(data, startIndex, intValue);
+  // for (unsigned char ix = 0; ix < 4; ix++) {
+  //   data[startIndex + ix] = ((unsigned char *)&intValue)[ix];
+  // }
+}
+void NetworkSync::SendFloat16(unsigned char *data, unsigned char *startIndex,
+                              float value) {
+  float16 value16 = float16(value);
+  short binary = value16.getBinary();
+
+  data[(*startIndex)++] = (binary >> 8) & 0xFF;
+  data[(*startIndex)++] = binary & 0xFF;
+}
+
+void NetworkSync::SendInt32(unsigned char *data, unsigned int startIndex,
+                            Int32 value) {
+  for (unsigned char ix = 0; ix < 4; ix++) {
+    data[startIndex++] = ((unsigned char *)&value)[ix];
+  }
+}
+
+void NetworkSync::SendBuffer(unsigned char bufferSize) {}
diff --git a/NetworkSync.h b/NetworkSync.h
index a0253ca..bba05f2 100644
--- a/NetworkSync.h
+++ b/NetworkSync.h
@@ -23,6 +23,7 @@ public:
   virtual void DestroyObject(InterestingThing *obj);
   virtual void NewObject(InterestingThing *obj);
   virtual void PublishModel(Roboid *obj);
+  void PublishModel(Thing *thing);
 
   /// @brief The id of a Pose message
   static const unsigned char PoseMsg = 0x10;
@@ -62,12 +63,14 @@ public:
   void SendPoseMsg(Buffer sendBuffer, Roboid *roboid);
   void SendDestroyObject(Buffer sendBuffer, InterestingThing *obj);
   void PublishNewObject();
+  void PublishRelativeThing(Thing *thing, bool recurse = false);
 
   void PublishTrackedObjects(Roboid *roboid, InterestingThing **objects);
 
   virtual void SendPosition(Vector3 worldPosition) {};
   virtual void SendPose(Vector3 worldPosition, Quaternion worldOrientation) {};
-  void SendPose(Roboid *roboid);
+  void SendPose(Roboid *roboid, bool recurse = true);
+  void SendPose(Thing *thing, bool recurse = true);
 
   void SendText(const char *s);
 
diff --git a/Perception.cpp b/Perception.cpp
index d813b10..ef2e96b 100644
--- a/Perception.cpp
+++ b/Perception.cpp
@@ -478,7 +478,7 @@ void Perception::Update(float currentTimeMs) {
 
       float distance = distanceSensor->GetDistance();
       if (distance >= 0) {
-        float angle = sensor->position.angle;
+        float angle = sensor->position.horizontalAngle;
         // Polar position = Polar(angle, distance);
         Polar position = Polar(distance, angle);
         AddTrackedObject(distanceSensor, position);
@@ -488,7 +488,8 @@ void Perception::Update(float currentTimeMs) {
       Switch *switchSensor = (Switch *)sensor;
       if (switchSensor->IsOn()) {
         // Polar position = Polar(sensor->position.angle, nearbyDistance);
-        Polar position = Polar(nearbyDistance, sensor->position.angle);
+        Polar position =
+            Polar(nearbyDistance, sensor->position.horizontalAngle);
         // AddTrackedObject(switchSensor, position);
       }
     } else {
diff --git a/Roboid.cpp b/Roboid.cpp
index 23a8016..f2a0417 100644
--- a/Roboid.cpp
+++ b/Roboid.cpp
@@ -64,12 +64,12 @@ void Roboid::Update(float currentTimeMs) {
                                          Vector3::up));
   }
 
-  if (networkSync != nullptr)
-    networkSync->NetworkUpdate(this);
-
   if (actuationRoot != nullptr)
     actuationRoot->Update(currentTimeMs);
 
+  if (networkSync != nullptr)
+    networkSync->NetworkUpdate(this);
+
   lastUpdateTimeMs = currentTimeMs;
 }
 
diff --git a/Sensor.cpp b/Sensor.cpp
index 82b20f0..3808d15 100644
--- a/Sensor.cpp
+++ b/Sensor.cpp
@@ -1,6 +1,5 @@
 #include "Sensor.h"
 
-Sensor::Sensor() {
-  // this->isSensor = true;
-  type = Thing::SensorType;
+Sensor::Sensor() : Thing(0) { // for now, id should be set properly later
+  this->type = Thing::SensorType;
 }
\ No newline at end of file
diff --git a/ServoMotor.cpp b/ServoMotor.cpp
index 451f2ac..641c57c 100644
--- a/ServoMotor.cpp
+++ b/ServoMotor.cpp
@@ -2,7 +2,8 @@
 
 #include "LinearAlgebra/FloatSingle.h"
 
-ServoMotor::ServoMotor() {
+ServoMotor::ServoMotor()
+    : Thing(0) { // for now, id should be set properly later
   this->type = Thing::ServoType;
   this->controlMode = ControlMode::Position;
   this->targetAngle = 0;
diff --git a/ServoMotor.h b/ServoMotor.h
index a32583e..0c8b795 100644
--- a/ServoMotor.h
+++ b/ServoMotor.h
@@ -9,6 +9,7 @@ class ServoMotor : public Thing {
 public:
   ServoMotor();
 
+  Vector3 rotationAxis = Vector3::up;
   float minAngle = -90.0F;
   float maxAngle = 90.0F;
 
diff --git a/Thing.cpp b/Thing.cpp
index 537a691..5fddcf6 100644
--- a/Thing.cpp
+++ b/Thing.cpp
@@ -2,7 +2,7 @@
 
 using namespace Passer::RoboidControl;
 
-Thing::Thing() : position(Polar::zero) {
+Thing::Thing(unsigned char id) : position(Polar::zero), id(id) {
   this->type = (unsigned int)Type::Undetermined;
   this->childCount = 0;
   this->parent = nullptr;
@@ -23,6 +23,14 @@ bool Thing::IsMotor() { return (type & Thing::MotorType) != 0; }
 
 bool Thing::IsSensor() { return (type & Thing::SensorType) != 0; }
 
+void Thing::SetModel(const char *url, Vector3 position, Quaternion orientation,
+                     float scale) {
+  this->modelUrl = url;
+  this->modelPosition = position;
+  this->modelOrientation = orientation;
+  this->modelScale = scale;
+}
+
 void Thing::SetParent(Thing *parent) { this->parent = parent; }
 
 Thing *Thing::GetParent() { return this->parent; }
diff --git a/Thing.h b/Thing.h
index 7bcb8da..bd1ec14 100644
--- a/Thing.h
+++ b/Thing.h
@@ -1,6 +1,7 @@
 #pragma once
 
 #include "LinearAlgebra/Polar.h"
+#include "LinearAlgebra/Quaternion.h"
 
 namespace Passer {
 namespace RoboidControl {
@@ -9,8 +10,10 @@ namespace RoboidControl {
 class Thing {
 public:
   /// @brief Default constructor for a Thing
-  Thing();
+  Thing(unsigned char id);
 
+  /// @char The id of the thing
+  unsigned char id;
   /// @brief The type of Thing
   unsigned int type;
 
@@ -33,7 +36,15 @@ public:
   /// @returns True when the Thing is a Sensor and False otherwise
   bool IsSensor();
 
-  Polar position;
+  Spherical position;
+  Quaternion orientation;
+
+  void SetModel(const char *url, Vector3 position = Vector3(0, 0, 0),
+                Quaternion orientation = Quaternion::identity, float scale = 1);
+  const char *modelUrl = nullptr;
+  Vector3 modelPosition = Vector3::zero;
+  Quaternion modelOrientation = Quaternion::identity;
+  float modelScale = 1;
 
   void SetParent(Thing *parent);
   Thing *GetParent();