diff --git a/.gitignore b/.gitignore
index 3fc83b58662e303434f5d61f0d485163d7d22154..0979ed0c958d230c5a5b7f226a92e289446f7851 100755
--- a/.gitignore
+++ b/.gitignore
@@ -17,8 +17,25 @@ dfall_ws/src/CMakeLists.txt
 
 TAGS
 build-*
-Crazyflie.db
 
 # For LaTeX files in the wiki
 wiki/latex/*
 !wiki/latex/*.tex
+
+# NOTES:
+# > To keep track of configuration-type files that
+#   are part of the repository, BUT for whcih
+#   changes are NOT tracked.
+# > These files are "skipped" from tracking using
+#   the following syntax:
+#   >> git update-index --skip-worktree <FILENAME>
+# > The files that should be "skipped" are:
+#   >> dfall_ws/src/dfall_pkg/launch/Config.sh
+#   >> dfall_ws/src/dfall_pkg/param/Crazyflie.db
+# > To return these files to normal tracking use
+#   the following syntax:
+#   >> git update-index --no-skip-worktree <FILENAME>
+# > "Skipping" is a setting local to your copy of the
+#   repository because ".git ignoring" a file already
+#   in the repository does NOT stop changes from being
+#   tracked
diff --git a/crazyflie-firmware/README.md b/crazyflie-firmware/README.md
index c6e4a032ea30cd55ee9d62052c9f767107f2c9f4..40219f33fd4da81a2821048a67f42c3ac2fc6a08 100644
--- a/crazyflie-firmware/README.md
+++ b/crazyflie-firmware/README.md
@@ -6,7 +6,7 @@ https://github.com/bitcraze/crazyflie-firmware
 However, it is easiest to locate the official realease versions of the firmware from here:<br>
 https://github.com/bitcraze/crazyflie-release/releases
 
-The complete instructions for applying the patch are given separately for each firmware version.
+The complete instructions for applying the patch are given separately for each firmware version (currently only one firmware version).
 
 
 
@@ -38,9 +38,11 @@ To apply the patch, use the following sequence of commands:
 `git clone --recursive https://github.com/bitcraze/crazyflie-firmware.git`<br>
 `cd crazyflie-firmware`<br>
 `git checkout e27cd170b7eb8be7ed1cbbc9f5622b469d335d97`<br>
+Note that it is also possible to checkout this commit using the commit tag, i.e., using `git checkout 2020.02`
+
 
 **Step 2:** Apply the patch:<br>
-`git apply <folder_to_dfall-system_repository>/crazyflie_firmware/crazyflie-firmware-version-2019-09/firmware_modifications_for_version_2019-09.patch`<br>
+`git apply <folder_to_dfall-system_repository>/crazyflie_firmware/crazyflie-firmware-version-2020-20/firmware_modifications_for_version_2020-20.patch`<br>
 
 Now the repository is ready to compile. To do this, first make sure that you have
 installed the necessary toolchain as described above ([Install Compilation Toolchain](#install-compilation-toolchain)).
@@ -63,47 +65,4 @@ The pre-compiled binary files are already included in this repository. To update
 `<folder_to_dfall-system_repository>/crazyflie_firmware/crazyflie-firmware-version-2020-02/cf2-2020.02_withDfallPatch.bin`<br>
 
 To update the firmware of both the main processor and the nrf processor, select the file:<br>
-`<folder_to_dfall-system_repository>/crazyflie_firmware/crazyflie-firmware-version-2020-02/firmware-cf2-2020.02_withDfallPatch.zip`<br>
-
-
-
-
-
-## Firware Version 2017-06
-
-The hash of the exact commit to which this patch applies is:<br>
-`f4d21213d7ce37d7ed7338fad0f9a94a96cec191`
-As commited on Mon Feb 3 15:04:52 2020 +0100
-
-To apply the patch, use the following sequence of commands:
-
-**Step 1:** Clone the repository and checkout the appropriate commit:<br>
-`git clone --recursive https://github.com/bitcraze/crazyflie-firmware.git`<br>
-`cd crazyflie-firmware`<br>
-`git checkout f4d21213d7ce37d7ed7338fad0f9a94a96cec191`<br>
-
-**Step 2:** Apply the patch:<br>
-`git apply <folder_to_dfall-system_repository>/crazyflie_firmware/crazyflie-firmware-version-2017-06/firmware_modifications_for_version_2017-06.patch`<br>
-
-Now the repository is ready to compile. To do this, first make sure that you have
-installed the necessary toolchain as described above ([Install Compilation Toolchain](#install-compilation-toolchain)).
-
-**Step 3:** In the `crazyflie-firmware` folder where you applied the patch, compile the firmware using the following command:<br>
-`make PLATFORM=CF2`
-
-If everything is successful, you will see something like this:<br>
-
-<img src="success_building_for_version_2017-06.png" style="width: 400px;"/> <br><br>
-
-This should have created the binary file `cf2.bin`.
-
-**Step 4:** upload the binary to the crazyflie processor by following the instructions given here:<br>
-https://www.bitcraze.io/documentation/tutorials/getting-started-with-crazyflie-2-x/#update-fw<br>
-Instructions are also given in the wiki of this repository under:
-`/wiki/setup.md#firmware`
-
-The pre-compiled binary files are already included in this repository. To update the firmware of just the main processor, select the file:
-`<folder_to_dfall-system_repository>/crazyflie_firmware/crazyflie-firmware-version-2017-06/cf2-2017.06_withDfallPatch.bin`<br>
-
-To update the firmware of both the main processor and the nrf processor, select the file:<br>
-`<folder_to_dfall-system_repository>/crazyflie_firmware/crazyflie-firmware-version-2017-06/firmware-cf2-2017.06_withDfallPatch.zip`<br>
\ No newline at end of file
+`<folder_to_dfall-system_repository>/crazyflie_firmware/crazyflie-firmware-version-2020-02/firmware-cf2-2020.02_withDfallPatch.zip`<br>
\ No newline at end of file
diff --git a/crazyflie-firmware/crazyflie-firmware-version-2017-06/cf1-2017.06.bin b/crazyflie-firmware/crazyflie-firmware-version-2017-06/cf1-2017.06.bin
deleted file mode 100644
index 8fe23d6d7142ee791214be735a5bbe51bdea8024..0000000000000000000000000000000000000000
Binary files a/crazyflie-firmware/crazyflie-firmware-version-2017-06/cf1-2017.06.bin and /dev/null differ
diff --git a/crazyflie-firmware/crazyflie-firmware-version-2017-06/cf2-2017.06_withDfallPatch.bin b/crazyflie-firmware/crazyflie-firmware-version-2017-06/cf2-2017.06_withDfallPatch.bin
deleted file mode 100755
index 5f2a63f7b230e616de18d2fe1f5df25f36b6a7b3..0000000000000000000000000000000000000000
Binary files a/crazyflie-firmware/crazyflie-firmware-version-2017-06/cf2-2017.06_withDfallPatch.bin and /dev/null differ
diff --git a/crazyflie-firmware/crazyflie-firmware-version-2017-06/cf2_nrf-2017.05.bin b/crazyflie-firmware/crazyflie-firmware-version-2017-06/cf2_nrf-2017.05.bin
deleted file mode 100644
index e73ab57124abde79c75fe14a754a7ad40f0a7c59..0000000000000000000000000000000000000000
Binary files a/crazyflie-firmware/crazyflie-firmware-version-2017-06/cf2_nrf-2017.05.bin and /dev/null differ
diff --git a/crazyflie-firmware/crazyflie-firmware-version-2017-06/firmware-cf2-2017.06_withDfallPatch.zip b/crazyflie-firmware/crazyflie-firmware-version-2017-06/firmware-cf2-2017.06_withDfallPatch.zip
deleted file mode 100644
index 79ac384102115983868f12721c3e79117775817d..0000000000000000000000000000000000000000
Binary files a/crazyflie-firmware/crazyflie-firmware-version-2017-06/firmware-cf2-2017.06_withDfallPatch.zip and /dev/null differ
diff --git a/crazyflie-firmware/crazyflie-firmware-version-2017-06/firmware_modifications_for_version_2017-06.patch b/crazyflie-firmware/crazyflie-firmware-version-2017-06/firmware_modifications_for_version_2017-06.patch
deleted file mode 100644
index 0718a5654065db8dff377ef1f1a7568a524cc88d..0000000000000000000000000000000000000000
--- a/crazyflie-firmware/crazyflie-firmware-version-2017-06/firmware_modifications_for_version_2017-06.patch
+++ /dev/null
@@ -1,435 +0,0 @@
-diff --git a/src/modules/interface/attitude_controller.h b/src/modules/interface/attitude_controller.h
-index ad23ef0..f79b7d1 100644
---- a/src/modules/interface/attitude_controller.h
-+++ b/src/modules/interface/attitude_controller.h
-@@ -63,6 +63,11 @@ void attitudeControllerResetRollAttitudePID(void);
-  */
- void attitudeControllerResetPitchAttitudePID(void);
- 
-+/**
-+ * Reset controller yaw attitude PID
-+ */
-+void attitudeControllerResetYawAttitudePID(void);
-+
- /**
-  * Reset controller roll, pitch and yaw PID's.
-  */
-diff --git a/src/modules/interface/stabilizer_types.h b/src/modules/interface/stabilizer_types.h
-index 418cc0b..30d031b 100644
---- a/src/modules/interface/stabilizer_types.h
-+++ b/src/modules/interface/stabilizer_types.h
-@@ -144,6 +144,10 @@ typedef struct control_s {
-   int16_t pitch;
-   int16_t yaw;
-   float thrust;
-+  uint16_t cmd1;
-+  uint16_t cmd2;
-+  uint16_t cmd3;
-+  uint16_t cmd4;
- } control_t;
- 
- typedef enum mode_e {
-@@ -152,12 +156,24 @@ typedef enum mode_e {
-   modeVelocity
- } stab_mode_t;
- 
-+typedef enum pps_mode_e {
-+  modeDisabled = 0,
-+  modeMotors,
-+  modeRate,
-+  modeAngle
-+} pps_mode_t;
-+
- typedef struct setpoint_s {
-   uint32_t timestamp;
- 
-   attitude_t attitude;
-   attitude_t attitudeRate;
-   float thrust;
-+  pps_mode_t pps_mode;
-+  uint16_t cmd1;
-+  uint16_t cmd2;
-+  uint16_t cmd3;
-+  uint16_t cmd4;
-   point_t position;
-   velocity_t velocity;
-   bool velocity_body;
-diff --git a/src/modules/src/attitude_pid_controller.c b/src/modules/src/attitude_pid_controller.c
-index 8b5f4aa..f16288f 100644
---- a/src/modules/src/attitude_pid_controller.c
-+++ b/src/modules/src/attitude_pid_controller.c
-@@ -142,9 +142,14 @@ void attitudeControllerResetRollAttitudePID(void)
- 
- void attitudeControllerResetPitchAttitudePID(void)
- {
--    pidReset(&pidRoll);
-+    pidReset(&pidPitch);
- }
- 
-+void attitudeControllerResetYawAttitudePID(void)
-+{
-+    pidReset(&pidYaw);
-+}
-+
- void attitudeControllerResetAllPID(void)
- {
-   pidReset(&pidRoll);
-diff --git a/src/modules/src/controller_pid.c b/src/modules/src/controller_pid.c
-index 0e5e62d..516315a 100644
---- a/src/modules/src/controller_pid.c
-+++ b/src/modules/src/controller_pid.c
-@@ -51,9 +51,13 @@ void stateController(control_t *control, setpoint_t *setpoint,
-   }
- 
-   if (RATE_DO_EXECUTE(POSITION_RATE, tick)) {
--    positionController(&actuatorThrust, &attitudeDesired, setpoint, state);
-+      if(setpoint->pps_mode != modeMotors && setpoint->pps_mode != modeRate && setpoint->pps_mode != modeAngle)
-+      {
-+          positionController(&actuatorThrust, &attitudeDesired, setpoint, state);
-+      }
-   }
- 
-+
-   if (RATE_DO_EXECUTE(ATTITUDE_RATE, tick)) {
-     // Switch between manual and automatic position control
-     if (setpoint->mode.z == modeDisable) {
-@@ -63,7 +67,7 @@ void stateController(control_t *control, setpoint_t *setpoint,
-       attitudeDesired.roll = setpoint->attitude.roll;
-       attitudeDesired.pitch = setpoint->attitude.pitch;
-     }
--
-+    /* if everything is modeVelocity, skip this */
-     attitudeControllerCorrectAttitudePID(state->attitude.roll, state->attitude.pitch, state->attitude.yaw,
-                                 attitudeDesired.roll, attitudeDesired.pitch, attitudeDesired.yaw,
-                                 &rateDesired.roll, &rateDesired.pitch, &rateDesired.yaw);
-@@ -80,6 +84,12 @@ void stateController(control_t *control, setpoint_t *setpoint,
-       attitudeControllerResetPitchAttitudePID();
-     }
- 
-+    //added for PPSSafeController to make the Onboard Controller using the external YawRate. Pure speed controller, no position/500 small steps
-+    if (setpoint->mode.yaw == modeVelocity) {
-+      rateDesired.yaw = (-1) * setpoint->attitudeRate.yaw;
-+      attitudeControllerResetYawAttitudePID();
-+    }
-+
-     // TODO: Investigate possibility to subtract gyro drift.
-     attitudeControllerCorrectRatePID(sensors->gyro.x, -sensors->gyro.y, sensors->gyro.z,
-                              rateDesired.roll, rateDesired.pitch, rateDesired.yaw);
-@@ -100,19 +110,76 @@ void stateController(control_t *control, setpoint_t *setpoint,
-     control->thrust = actuatorThrust;
-   }
- 
--  if (control->thrust == 0)
-+  if(setpoint->pps_mode == modeMotors)
-   {
--    control->thrust = 0;
--    control->roll = 0;
--    control->pitch = 0;
--    control->yaw = 0;
--
--    attitudeControllerResetAllPID();
--    positionControllerResetAllPID();
--
--    // Reset the calculated YAW angle for rate control
--    attitudeDesired.yaw = state->attitude.yaw;
-+      control->roll = 0;
-+      control->pitch = 0;
-+      control->yaw = 0;
-+      control->cmd1 = setpoint->cmd1;
-+      control->cmd2 = setpoint->cmd2;
-+      control->cmd3 = setpoint->cmd3;
-+      control->cmd4 = setpoint->cmd4;
-+      if ((control->cmd1 == 0 && control->cmd2 == 0 && control->cmd3 == 0 && control->cmd4 == 0))
-+      {
-+          control->cmd1 = 0;
-+          control->cmd2 = 0;
-+          control->cmd3 = 0;
-+          control->cmd4 = 0;
-+          control->roll = 0;
-+          control->pitch = 0;
-+          control->yaw = 0;
-+
-+          attitudeControllerResetAllPID();
-+          positionControllerResetAllPID();
-+
-+          // Reset the calculated YAW angle for rate control
-+          attitudeDesired.yaw = state->attitude.yaw;
-+      }
-+  }
-+  else if(setpoint->pps_mode == modeRate || setpoint->pps_mode == modeAngle)
-+  {
-+      control->cmd1 = setpoint->cmd1;
-+      control->cmd2 = setpoint->cmd2;
-+      control->cmd3 = setpoint->cmd3;
-+      control->cmd4 = setpoint->cmd4;
-+      if ((control->cmd1 == 0 && control->cmd2 == 0 && control->cmd3 == 0 && control->cmd4 == 0))
-+      {
-+          control->cmd1 = 0;
-+          control->cmd2 = 0;
-+          control->cmd3 = 0;
-+          control->cmd4 = 0;
-+          control->roll = 0;
-+          control->pitch = 0;
-+          control->yaw = 0;
-+
-+          attitudeControllerResetAllPID();
-+          positionControllerResetAllPID();
-+
-+          // Reset the calculated YAW angle for rate control
-+          attitudeDesired.yaw = state->attitude.yaw;
-+      }
-   }
-+  else                          /* pps_mode == modeDisabled */
-+  {
-+      control->cmd1 = control->thrust;
-+      control->cmd2 = control->thrust;
-+      control->cmd3 = control->thrust;
-+      control->cmd4 = control->thrust;
-+      if (control->thrust == 0)
-+      {
-+          control->thrust = 0;
-+          control->roll = 0;
-+          control->pitch = 0;
-+          control->yaw = 0;
-+
-+          attitudeControllerResetAllPID();
-+          positionControllerResetAllPID();
-+
-+          // Reset the calculated YAW angle for rate control
-+          attitudeDesired.yaw = state->attitude.yaw;
-+      }
-+  }
-+
- }
- 
- 
-diff --git a/src/modules/src/crtp_commander_generic.c b/src/modules/src/crtp_commander_generic.c
-index 993dead..4370101 100644
---- a/src/modules/src/crtp_commander_generic.c
-+++ b/src/modules/src/crtp_commander_generic.c
-@@ -34,6 +34,8 @@
- #include "num.h"
- #include "FreeRTOS.h"
- 
-+/* #include "motors.h" */
-+
- /* The generic commander format contains a packet type and data that has to be
-  * decoded into a setpoint_t structure. The aim is to make it future-proof
-  * by easily allowing the addition of new packets for future use cases.
-@@ -67,6 +69,9 @@ enum packet_type {
-   cppmEmuType       = 3,
-   altHoldType       = 4,
-   hoverType         = 5,
-+  PPSMotorsType     = 8,
-+  PPSRateType       = 9,
-+  PPSAngleType      = 10,
- };
- 
- /* ---===== 2 - Decoding functions =====--- */
-@@ -292,6 +297,152 @@ static void hoverDecoder(setpoint_t *setpoint, uint8_t type, const void *data, s
-   setpoint->velocity_body = true;
- }
- 
-+struct PPSMotorsPacket_s {
-+    uint16_t cmd1;
-+    uint16_t cmd2;
-+    uint16_t cmd3;
-+    uint16_t cmd4;
-+} __attribute__((packed));
-+
-+static void PPSMotorsDecoder(setpoint_t *setpoint, uint8_t type, const void *data, size_t datalen)
-+{
-+    const struct PPSMotorsPacket_s *values = data;
-+    ASSERT(datalen == sizeof(struct PPSMotorsPacket_s));
-+
-+    /* we dont use position controller onboard */
-+	setpoint->mode.x = modeDisable;
-+	setpoint->mode.y = modeDisable;
-+	setpoint->mode.z = modeDisable;
-+
-+	setpoint->thrust = 0;
-+	setpoint->position.x = 0;
-+	setpoint->position.y = 0;
-+	setpoint->position.z = 0;
-+	setpoint->velocity.x = 0;
-+	setpoint->velocity.y = 0;
-+	setpoint->velocity.z = 0;
-+
-+    /* we dont use rate controller onboard either */
-+    setpoint->mode.roll = modeDisable;
-+    setpoint->mode.pitch = modeDisable;
-+    setpoint->mode.yaw = modeDisable;
-+
-+    setpoint->attitude.roll = 0;
-+    setpoint->attitude.pitch = 0;
-+    setpoint->attitude.yaw = 0;
-+    setpoint->attitudeRate.roll = 0;
-+    setpoint->attitudeRate.pitch = 0;
-+    setpoint->attitudeRate.yaw = 0;
-+
-+    /* update cmds */
-+
-+    setpoint->cmd1 = limitUint16(values->cmd1);
-+    setpoint->cmd2 = limitUint16(values->cmd2);
-+    setpoint->cmd3 = limitUint16(values->cmd3);
-+    setpoint->cmd4 = limitUint16(values->cmd4);
-+
-+    setpoint->pps_mode = modeMotors;
-+}
-+
-+struct PPSRatePacket_s {
-+    uint16_t cmd1;
-+    uint16_t cmd2;
-+    uint16_t cmd3;
-+    uint16_t cmd4;
-+    float roll_rate;
-+    float pitch_rate;
-+    float yaw_rate;
-+} __attribute__((packed));
-+
-+static void PPSRateDecoder(setpoint_t *setpoint, uint8_t type, const void *data, size_t datalen)
-+{
-+    const struct PPSRatePacket_s *values = data;
-+    ASSERT(datalen == sizeof(struct PPSRatePacket_s));
-+
-+    /* we dont use position controller onboard */
-+	setpoint->mode.x = modeDisable;
-+	setpoint->mode.y = modeDisable;
-+	setpoint->mode.z = modeDisable;
-+
-+	setpoint->thrust = 0;
-+	setpoint->position.x = 0;
-+	setpoint->position.y = 0;
-+	setpoint->position.z = 0;
-+	setpoint->velocity.x = 0;
-+	setpoint->velocity.y = 0;
-+	setpoint->velocity.z = 0;
-+
-+    /* we use rate controller onboard either */
-+    setpoint->mode.roll = modeVelocity;
-+    setpoint->mode.pitch = modeVelocity;
-+    setpoint->mode.yaw = modeVelocity;
-+
-+    setpoint->attitude.roll = 0;
-+    setpoint->attitude.pitch = 0;
-+    setpoint->attitude.yaw = 0;
-+    setpoint->attitudeRate.roll = values->roll_rate;
-+    setpoint->attitudeRate.pitch = values->pitch_rate;
-+    setpoint->attitudeRate.yaw = values->yaw_rate;
-+
-+    /* update cmds */
-+
-+    setpoint->cmd1 = limitUint16(values->cmd1);
-+    setpoint->cmd2 = limitUint16(values->cmd2);
-+    setpoint->cmd3 = limitUint16(values->cmd3);
-+    setpoint->cmd4 = limitUint16(values->cmd4);
-+
-+    setpoint->pps_mode = modeRate;
-+}
-+
-+struct PPSAnglePacket_s {
-+    uint16_t cmd1;
-+    uint16_t cmd2;
-+    uint16_t cmd3;
-+    uint16_t cmd4;
-+    float roll;
-+    float pitch;
-+    float yaw;
-+} __attribute__((packed));
-+
-+static void PPSAngleDecoder(setpoint_t *setpoint, uint8_t type, const void *data, size_t datalen)
-+{
-+    const struct PPSAnglePacket_s *values = data;
-+    ASSERT(datalen == sizeof(struct PPSRatePacket_s));
-+
-+    /* we dont use position controller onboard */
-+	setpoint->mode.x = modeDisable;
-+	setpoint->mode.y = modeDisable;
-+	setpoint->mode.z = modeDisable;
-+
-+	setpoint->thrust = 0;
-+	setpoint->position.x = 0;
-+	setpoint->position.y = 0;
-+	setpoint->position.z = 0;
-+	setpoint->velocity.x = 0;
-+	setpoint->velocity.y = 0;
-+	setpoint->velocity.z = 0;
-+
-+    /* we use position angle controller onboard */
-+    setpoint->mode.roll = modeAbs;
-+    setpoint->mode.pitch = modeAbs;
-+    setpoint->mode.yaw = modeAbs;
-+
-+    setpoint->attitude.roll = values->roll;
-+    setpoint->attitude.pitch = values->pitch;
-+    setpoint->attitude.yaw = values->yaw;
-+    setpoint->attitudeRate.roll = 0;
-+    setpoint->attitudeRate.pitch = 0;
-+    setpoint->attitudeRate.yaw = 0;
-+
-+    /* update cmds */
-+    setpoint->cmd1 = limitUint16(values->cmd1);
-+    setpoint->cmd2 = limitUint16(values->cmd2);
-+    setpoint->cmd3 = limitUint16(values->cmd3);
-+    setpoint->cmd4 = limitUint16(values->cmd4);
-+
-+    setpoint->pps_mode = modeAngle;
-+}
-+
-  /* ---===== 3 - packetDecoders array =====--- */
- const static packetDecoder_t packetDecoders[] = {
-   [stopType]          = stopDecoder,
-@@ -300,6 +451,9 @@ const static packetDecoder_t packetDecoders[] = {
-   [cppmEmuType]       = cppmEmuDecoder,
-   [altHoldType]       = altHoldDecoder,
-   [hoverType]         = hoverDecoder,
-+  [PPSMotorsType]     = PPSMotorsDecoder,
-+  [PPSRateType]       = PPSRateDecoder,
-+  [PPSAngleType]      = PPSAngleDecoder,
- };
- 
- /* Decoder switch */
-diff --git a/src/modules/src/power_distribution_stock.c b/src/modules/src/power_distribution_stock.c
-index 0e66c0b..79d5f2c 100644
---- a/src/modules/src/power_distribution_stock.c
-+++ b/src/modules/src/power_distribution_stock.c
-@@ -76,18 +76,19 @@ void powerDistribution(const control_t *control)
-   #ifdef QUAD_FORMATION_X
-     int16_t r = control->roll / 2.0f;
-     int16_t p = control->pitch / 2.0f;
--    motorPower.m1 = limitThrust(control->thrust - r + p + control->yaw);
--    motorPower.m2 = limitThrust(control->thrust - r - p - control->yaw);
--    motorPower.m3 =  limitThrust(control->thrust + r - p + control->yaw);
--    motorPower.m4 =  limitThrust(control->thrust + r + p - control->yaw);
-+    motorPower.m1 = limitThrust(control->cmd1 - r + p + control->yaw);
-+    motorPower.m2 = limitThrust(control->cmd2 - r - p - control->yaw);
-+    motorPower.m3 =  limitThrust(control->cmd3 + r - p + control->yaw);
-+    motorPower.m4 =  limitThrust(control->cmd4 + r + p - control->yaw);
-+
-   #else // QUAD_FORMATION_NORMAL
--    motorPower.m1 = limitThrust(control->thrust + control->pitch +
-+    motorPower.m1 = limitThrust(control->cmd1 + control->pitch +
-                                control->yaw);
--    motorPower.m2 = limitThrust(control->thrust - control->roll -
-+    motorPower.m2 = limitThrust(control->cmd2 - control->roll -
-                                control->yaw);
--    motorPower.m3 =  limitThrust(control->thrust - control->pitch +
-+    motorPower.m3 =  limitThrust(control->cmd3 - control->pitch +
-                                control->yaw);
--    motorPower.m4 =  limitThrust(control->thrust + control->roll -
-+    motorPower.m4 =  limitThrust(control->cmd4 + control->roll -
-                                control->yaw);
-   #endif
- 
-diff --git a/src/modules/src/stabilizer.c b/src/modules/src/stabilizer.c
-index eccc709..6b9fcc3 100644
---- a/src/modules/src/stabilizer.c
-+++ b/src/modules/src/stabilizer.c
-@@ -130,7 +130,6 @@ static void stabilizerTask(void* param)
-     commanderGetSetpoint(&setpoint, &state);
- 
-     sitAwUpdateSetpoint(&setpoint, &sensorData, &state);
--
-     stateController(&control, &setpoint, &sensorData, &state, tick);
- 
-     checkEmergencyStopTimeout();
diff --git a/crazyflie-firmware/crazyflie-firmware-version-2017-06/manifest.json b/crazyflie-firmware/crazyflie-firmware-version-2017-06/manifest.json
deleted file mode 100644
index 58f97a9ac6d1174015a31ee746aab63d97dba97a..0000000000000000000000000000000000000000
--- a/crazyflie-firmware/crazyflie-firmware-version-2017-06/manifest.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-    "version": 1,
-    "subversion": 1,
-    "release": "2017.06",
-    "files": {
-        "cf2-2017.06_withDfallPatch.bin": {
-            "platform": "cf2",
-            "target": "stm32",
-            "type": "fw",
-            "release": "2017.06",
-            "repository": "crazyflie-firmware"
-        },
-        "cf2_nrf-2017.05.bin": {
-            "platform": "cf2",
-            "target": "nrf51",
-            "type": "fw",
-            "release": "2017.05",
-            "repository": "crazyflie2-nrf-firmware"
-        },
-        "cf1-2017.06.bin": {
-            "platform": "cf1",
-            "target": "stm32",
-            "type": "fw",
-            "release": "2017.06",
-            "repository": "crazyflie-firmware"
-        }
-    }
-}
diff --git a/crazyflie-firmware/crazyflie-firmware-version-2020-02/cf2-2020.02_withDfallPatch.bin b/crazyflie-firmware/crazyflie-firmware-version-2020-02/cf2-2020.02_withDfallPatch.bin
index 01fe563354fc0d4ecf38feabf6440f162f703ee3..04fddf6eca9a4b1b9cac7f9c1162e74ae2a84f55 100755
Binary files a/crazyflie-firmware/crazyflie-firmware-version-2020-02/cf2-2020.02_withDfallPatch.bin and b/crazyflie-firmware/crazyflie-firmware-version-2020-02/cf2-2020.02_withDfallPatch.bin differ
diff --git a/crazyflie-firmware/crazyflie-firmware-version-2020-02/firmware-cf2-2020.02_withDfallPatch.zip b/crazyflie-firmware/crazyflie-firmware-version-2020-02/firmware-cf2-2020.02_withDfallPatch.zip
index 5b372f7f3eef8a006ae39c8c994eedd03ade5e98..fea06a8cc08ee07cdeeba670ba7d17ae49667a89 100644
Binary files a/crazyflie-firmware/crazyflie-firmware-version-2020-02/firmware-cf2-2020.02_withDfallPatch.zip and b/crazyflie-firmware/crazyflie-firmware-version-2020-02/firmware-cf2-2020.02_withDfallPatch.zip differ
diff --git a/crazyflie-firmware/crazyflie-firmware-version-2020-02/firmware_modifications_for_version_2020-02.patch b/crazyflie-firmware/crazyflie-firmware-version-2020-02/firmware_modifications_for_version_2020-02.patch
index 776fa60d4faf6946623680e6b87091a96c573656..6b2d1151426995f11f155d2bb8904bc54fe14748 100644
--- a/crazyflie-firmware/crazyflie-firmware-version-2020-02/firmware_modifications_for_version_2020-02.patch
+++ b/crazyflie-firmware/crazyflie-firmware-version-2020-02/firmware_modifications_for_version_2020-02.patch
@@ -15,7 +15,7 @@ index fe25dc0..fd69bdc 100644
   * Reset controller roll, pitch and yaw PID's.
   */
 diff --git a/src/modules/interface/stabilizer_types.h b/src/modules/interface/stabilizer_types.h
-index fc3e378..272cc88 100644
+index fc3e378..c51fdbd 100644
 --- a/src/modules/interface/stabilizer_types.h
 +++ b/src/modules/interface/stabilizer_types.h
 @@ -159,6 +159,10 @@ typedef struct control_s {
@@ -29,25 +29,10 @@ index fc3e378..272cc88 100644
  } control_t;
  
  typedef enum mode_e {
-@@ -167,6 +171,13 @@ typedef enum mode_e {
-   modeVelocity
- } stab_mode_t;
- 
-+typedef enum dfall_mode_e {
-+  modeDfallDisable = 0,
-+  modeDfallMotors,
-+  modeDfallRate,
-+  modeDfallAngle,
-+} dfall_mode_t;
-+
- typedef struct setpoint_s {
-   uint32_t timestamp;
- 
-@@ -174,6 +185,11 @@ typedef struct setpoint_s {
+@@ -174,11 +178,17 @@ typedef struct setpoint_s {
    attitude_t attitudeRate;  // deg/s
    quaternion_t attitudeQuaternion;
    float thrust;
-+  dfall_mode_t dfall_mode;
 +  uint16_t cmd1;
 +  uint16_t cmd2;
 +  uint16_t cmd3;
@@ -55,6 +40,13 @@ index fc3e378..272cc88 100644
    point_t position;         // m
    velocity_t velocity;      // m/s
    acc_t acceleration;       // m/s^2
+   bool velocity_body;       // true if velocity is given in body frame; false if velocity is given in world frame
+ 
++  bool useDfallAdjustmentsToControllerPID;
++
+   struct {
+     stab_mode_t x;
+     stab_mode_t y;
 diff --git a/src/modules/src/attitude_pid_controller.c b/src/modules/src/attitude_pid_controller.c
 index b7d707e..bcb02bc 100644
 --- a/src/modules/src/attitude_pid_controller.c
@@ -72,25 +64,10 @@ index b7d707e..bcb02bc 100644
  {
    pidReset(&pidRoll);
 diff --git a/src/modules/src/controller_pid.c b/src/modules/src/controller_pid.c
-index f4ecb75..4a9047c 100644
+index f4ecb75..673b5cc 100644
 --- a/src/modules/src/controller_pid.c
 +++ b/src/modules/src/controller_pid.c
-@@ -74,7 +74,13 @@ void controllerPid(control_t *control, setpoint_t *setpoint,
-   }
- 
-   if (RATE_DO_EXECUTE(POSITION_RATE, tick)) {
--    positionController(&actuatorThrust, &attitudeDesired, setpoint, state);
-+    // Check if the "dfall_mode" needs the position controller to run
-+    bool posControllIsNeeded_for_dfall_mode = (setpoint->dfall_mode != modeDfallMotors && setpoint->dfall_mode != modeDfallRate && setpoint->dfall_mode != modeDfallAngle);
-+    // Hence run the position controller only if needed
-+    if (posControllIsNeeded_for_dfall_mode)
-+    {
-+      positionController(&actuatorThrust, &attitudeDesired, setpoint, state);
-+    }
-   }
- 
-   if (RATE_DO_EXECUTE(ATTITUDE_RATE, tick)) {
-@@ -132,6 +138,9 @@ void controllerPid(control_t *control, setpoint_t *setpoint,
+@@ -132,6 +132,9 @@ void controllerPid(control_t *control, setpoint_t *setpoint,
      control->thrust = actuatorThrust;
    }
  
@@ -100,57 +77,57 @@ index f4ecb75..4a9047c 100644
    if (control->thrust == 0)
    {
      control->thrust = 0;
-@@ -150,6 +159,89 @@ void controllerPid(control_t *control, setpoint_t *setpoint,
+@@ -150,6 +153,92 @@ void controllerPid(control_t *control, setpoint_t *setpoint,
      // Reset the calculated YAW angle for rate control
      attitudeDesired.yaw = state->attitude.yaw;
    }
 +  */
 +
-+  // This set of "if:then:else" statements is used to specify
-+  // the "control->cmd{1,2,3,4}" depending on the "setpoint->dfall_mode"
-+  // And in all cases perform the check if either:
-+  // >> "control->thrust==0", or
-+  // >> "control->cmd{1,2,3,4}==0"
-+  // where the check performed is appropriate to the case.
-+  // The result of the check is used to set all commands to zero and
-+  // to reset all PIDs, if necessary.
-+
-+  // Default the check to false
-+  bool isZeroThrust = false;
-+
-+  if (setpoint->dfall_mode == modeDfallMotors)
++  // The following "if:then:else" statements is used to
++  // specify the "control->cmd{1,2,3,4}" depending on
++  // the boolean:
++  // >> "setpoint->useDfallAdjustmentsToControllerPID"
++  if (setpoint->useDfallAdjustmentsToControllerPID)
 +  {
 +    // Set the {roll,pitch,yaw} commands to zero
-+    control->roll = 0;
-+    control->pitch = 0;
-+    control->yaw = 0;
-+    // Copy across the per motor commands
-+    control->cmd1 = setpoint->cmd1;
-+    control->cmd2 = setpoint->cmd2;
-+    control->cmd3 = setpoint->cmd3;
-+    control->cmd4 = setpoint->cmd4;
-+    // Perform check for all thrust being zero
-+    if ((control->cmd1 == 0 && control->cmd2 == 0 && control->cmd3 == 0 && control->cmd4 == 0))
++    // if indicated by the respective mode
++    if (setpoint->mode.roll == modeDisable)
 +    {
-+      // Set the flag to true that thrusts are zero
-+      isZeroThrust = true;
++      control->roll = 0;
++      cmd_roll = 0.0;
 +    }
-+  }
-+  else if(setpoint->dfall_mode == modeDfallRate || setpoint->dfall_mode == modeDfallAngle)
-+  {
-+    // Copy across the per motor commands
-+    control->cmd1 = setpoint->cmd1;
-+    control->cmd2 = setpoint->cmd2;
-+    control->cmd3 = setpoint->cmd3;
-+    control->cmd4 = setpoint->cmd4;
-+    // Perform check for all thrust being zero
-+    if ((control->cmd1 == 0 && control->cmd2 == 0 && control->cmd3 == 0 && control->cmd4 == 0))
++    if (setpoint->mode.pitch == modeDisable)
++    {
++      control->pitch = 0;
++      cmd_pitch = 0.0;
++    }
++    if (setpoint->mode.yaw == modeDisable)
++    {
++      control->yaw = 0;
++      cmd_yaw = 0.0;
++    }
++    // Apply the per-motor commands differently
++    // depending on the Z-controller mode
++    if (setpoint->mode.z == modeDisable)
 +    {
-+      // Set the flag to true that thrusts are zero
-+      isZeroThrust = true;
++      // Copy across the per motor commands
++      control->cmd1 = setpoint->cmd1;
++      control->cmd2 = setpoint->cmd2;
++      control->cmd3 = setpoint->cmd3;
++      control->cmd4 = setpoint->cmd4;
++    }
++    else
++    {
++      // Add the setpoints on top of the
++      // "control thrust" computed by the
++      // PID controllers above
++      control->cmd1 = setpoint->cmd1 + control->thrust;
++      control->cmd2 = setpoint->cmd2 + control->thrust;
++      control->cmd3 = setpoint->cmd3 + control->thrust;
++      control->cmd4 = setpoint->cmd4 + control->thrust;
 +    }
 +  }
-+  // Otherwise, "setpoint->dfall_mode == modeDfallDisable"
++  // Otherwise, "setpoint->useDfallAdjustmentsToControllerPID == false"
 +  else
 +  {
 +    // Put the thrust value onto each motor
@@ -158,16 +135,13 @@ index f4ecb75..4a9047c 100644
 +    control->cmd2 = control->thrust;
 +    control->cmd3 = control->thrust;
 +    control->cmd4 = control->thrust;
-+    // If thrust is zero, then:
-+    if (control->thrust == 0)
-+    {
-+      // Set the flag to true that thrusts are zero
-+      isZeroThrust = true;
-+    }
 +  }
 +
-+  // If the flag idicates that thrusts are zero,
-+  // then set all commands to zero and reset the PIDs
++  // If all control commands are zero, i.e., if:
++  // >> "control->cmd{1,2,3,4}==0"
++  // then set all commands to zero and to reset
++  // all PIDs.
++  bool isZeroThrust = ((control->cmd1 == 0 && control->cmd2 == 0 && control->cmd3 == 0 && control->cmd4 == 0));
 +  if (isZeroThrust)
 +  {
 +    // Set all commands to zero
@@ -186,217 +160,412 @@ index f4ecb75..4a9047c 100644
 +
 +    // Reset the calculated YAW angle for rate control
 +    attitudeDesired.yaw = state->attitude.yaw;
++
++    // Update also the log variables to reflect this
++    cmd_thrust = 0.0;
++    cmd_roll = 0.0;
++    cmd_pitch = 0.0;
++    cmd_yaw = 0.0;
 +  }
  }
  
  
 diff --git a/src/modules/src/crtp_commander_generic.c b/src/modules/src/crtp_commander_generic.c
-index 1662fe4..84d0631 100644
+index 1662fe4..f6931a4 100644
 --- a/src/modules/src/crtp_commander_generic.c
 +++ b/src/modules/src/crtp_commander_generic.c
-@@ -71,6 +71,9 @@ enum packet_type {
+@@ -71,6 +71,7 @@ enum packet_type {
    hoverType         = 5,
    fullStateType     = 6,
    positionType      = 7,
-+  dfallMotorsType   = 8,
-+  dfallRateType     = 9,
-+  dfallAngleType    = 10,
++  dfallType         = 8,
  };
  
  /* ---===== 2 - Decoding functions =====--- */
-@@ -367,6 +370,180 @@ static void positionDecoder(setpoint_t *setpoint, uint8_t type, const void *data
-   setpoint->attitude.yaw = values->yaw;
+@@ -112,6 +113,9 @@ static void velocityDecoder(setpoint_t *setpoint, uint8_t type, const void *data
+   setpoint->mode.yaw = modeVelocity;
+ 
+   setpoint->attitudeRate.yaw = -values->yawrate;
++
++  // Turn off the "dfall mode adjustments"
++  setpoint->useDfallAdjustmentsToControllerPID = false;
  }
  
-+/* dfall motors mode decoder
-+ * disable all controllers, the motor commands provided are
-+ * set directly to the motors
-+ */
-+struct dfallMotorsPacket_s {
-+    uint16_t cmd1;
-+    uint16_t cmd2;
-+    uint16_t cmd3;
-+    uint16_t cmd4;
-+} __attribute__((packed));
+ /* zDistanceDecoder
+@@ -145,6 +149,9 @@ static void zDistanceDecoder(setpoint_t *setpoint, uint8_t type, const void *dat
+ 
+   setpoint->attitude.roll = values->roll;
+   setpoint->attitude.pitch = values->pitch;
 +
-+static void dfallMotorsDecoder(setpoint_t *setpoint, uint8_t type, const void *data, size_t datalen)
-+{
-+  const struct dfallMotorsPacket_s *values = data;
-+  ASSERT(datalen == sizeof(struct dfallMotorsPacket_s));
++  // Turn off the "dfall mode adjustments"
++  setpoint->useDfallAdjustmentsToControllerPID = false;
+ }
+ 
+ /* cppmEmuDecoder
+@@ -230,6 +237,9 @@ static void cppmEmuDecoder(setpoint_t *setpoint, uint8_t type, const void *data,
+   {
+     setpoint->thrust = 0;
+   }
 +
-+  // Disable the onboard position controllers
-+  setpoint->mode.x = modeDisable;
-+  setpoint->mode.y = modeDisable;
-+  setpoint->mode.z = modeDisable;
++  // Turn off the "dfall mode adjustments"
++  setpoint->useDfallAdjustmentsToControllerPID = false;
+ }
+ 
+ /* altHoldDecoder
+@@ -263,6 +273,9 @@ static void altHoldDecoder(setpoint_t *setpoint, uint8_t type, const void *data,
+ 
+   setpoint->attitude.roll = values->roll;
+   setpoint->attitude.pitch = values->pitch;
 +
-+  // And set their setpoint values to zero
-+  setpoint->thrust = 0;
-+  setpoint->position.x = 0;
-+  setpoint->position.y = 0;
-+  setpoint->position.z = 0;
-+  setpoint->velocity.x = 0;
-+  setpoint->velocity.y = 0;
-+  setpoint->velocity.z = 0;
-+
-+  // Disable the onboard orientation controllers
-+  setpoint->mode.roll  = modeDisable;
-+  setpoint->mode.pitch = modeDisable;
-+  setpoint->mode.yaw   = modeDisable;
-+
-+  // And set their setpoint values to zero
-+  setpoint->attitude.roll  = 0;
-+  setpoint->attitude.pitch = 0;
-+  setpoint->attitude.yaw   = 0;
-+  setpoint->attitudeRate.roll  = 0;
-+  setpoint->attitudeRate.pitch = 0;
-+  setpoint->attitudeRate.yaw   = 0;
++  // Turn off the "dfall mode adjustments"
++  setpoint->useDfallAdjustmentsToControllerPID = false;
+ }
+ 
+ /* hoverDecoder
+@@ -294,6 +307,9 @@ static void hoverDecoder(setpoint_t *setpoint, uint8_t type, const void *data, s
+   setpoint->velocity.y = values->vy;
+ 
+   setpoint->velocity_body = true;
 +
-+  // Tranfer the per-motor commands from the packet
-+  // to the respective setpoints
-+  setpoint->cmd1 = limitUint16(values->cmd1);
-+  setpoint->cmd2 = limitUint16(values->cmd2);
-+  setpoint->cmd3 = limitUint16(values->cmd3);
-+  setpoint->cmd4 = limitUint16(values->cmd4);
++  // Turn off the "dfall mode adjustments"
++  setpoint->useDfallAdjustmentsToControllerPID = false;
+ }
+ 
+ struct fullStatePacket_s {
+@@ -338,6 +354,9 @@ static void fullStateDecoder(setpoint_t *setpoint, uint8_t type, const void *dat
+   setpoint->mode.roll = modeDisable;
+   setpoint->mode.pitch = modeDisable;
+   setpoint->mode.yaw = modeDisable;
++
++  // Turn off the "dfall mode adjustments"
++  setpoint->useDfallAdjustmentsToControllerPID = false;
+ }
+ 
+ /* positionDecoder
+@@ -365,6 +384,313 @@ static void positionDecoder(setpoint_t *setpoint, uint8_t type, const void *data
+   setpoint->mode.yaw = modeAbs;
+ 
+   setpoint->attitude.yaw = values->yaw;
 +
-+  // Set the "dfall_mode" accordingly
-+  setpoint->dfall_mode = modeDfallMotors;
++  // Turn off the "dfall mode adjustments"
++  setpoint->useDfallAdjustmentsToControllerPID = false;
 +}
 +
-+/* dfall rate mode decoder
-+ * disable the position controllers and use the attitude controllers
-+ * in "velocity mode", i.e., use the onboard "rate controllers"
++/* dfall mode decoder
++ * set the mode of the onboard {x,y,z,roll,pitch,yaw}
++ * controllers based on the mode specification
++ * contained in the packet. A separate mode is
++ * specified for each of the four independent
++ * coordinates of {x,y,z,yaw}
 + */
-+struct dfallRatePacket_s {
-+    uint16_t cmd1;
-+    uint16_t cmd2;
-+    uint16_t cmd3;
-+    uint16_t cmd4;
-+    float roll_rate;
-+    float pitch_rate;
-+    float yaw_rate;
-+} __attribute__((packed));
-+
-+static void dfallRateDecoder(setpoint_t *setpoint, uint8_t type, const void *data, size_t datalen)
-+{
-+  const struct dfallRatePacket_s *values = data;
-+  ASSERT(datalen == sizeof(struct dfallRatePacket_s));
-+
-+  // Disable the onboard position controllers
-+  setpoint->mode.x = modeDisable;
-+  setpoint->mode.y = modeDisable;
-+  setpoint->mode.z = modeDisable;
 +
-+  // And set their setpoint values to zero
-+  setpoint->thrust = 0;
-+  setpoint->position.x = 0;
-+  setpoint->position.y = 0;
-+  setpoint->position.z = 0;
-+  setpoint->velocity.x = 0;
-+  setpoint->velocity.y = 0;
-+  setpoint->velocity.z = 0;
-+
-+  // Enable the onboard orientation controllers in
-+  // velocity mode, i.e., as rate controllers
-+  setpoint->mode.roll  = modeVelocity;
-+  setpoint->mode.pitch = modeVelocity;
-+  setpoint->mode.yaw   = modeVelocity;
-+
-+  // Set the angle setpoints to zero
-+  setpoint->attitude.roll  = 0;
-+  setpoint->attitude.pitch = 0;
-+  setpoint->attitude.yaw   = 0;
-+  // Transfer the angular rate commands from the packet
-+  // to the respective setpoints
-+  setpoint->attitudeRate.roll = values->roll_rate;
-+  setpoint->attitudeRate.pitch = values->pitch_rate;
-+  setpoint->attitudeRate.yaw = values->yaw_rate;
++#define DFALL_CONTROLLER_MODE_OFF            0
++#define DFALL_CONTROLLER_MODE_ANGULAR_RATE   1
++#define DFALL_CONTROLLER_MODE_ANGLE          2
++#define DFALL_CONTROLLER_MODE_VELOCITY       3
++#define DFALL_CONTROLLER_MODE_POSITION       4
 +
-+  // Tranfer the per-motor commands from the packet
-+  // to the respective setpoints
-+  setpoint->cmd1 = limitUint16(values->cmd1);
-+  setpoint->cmd2 = limitUint16(values->cmd2);
-+  setpoint->cmd3 = limitUint16(values->cmd3);
-+  setpoint->cmd4 = limitUint16(values->cmd4);
-+
-+  // Set the "dfall_mode" accordingly
-+  setpoint->dfall_mode = modeDfallRate;
-+}
-+
-+/* dfall angle mode decoder
-+ * disable the position controllers and use the attitude controllers
-+ * in "absolute mode", i.e., use the onboard "angle controllers"
-+ */
-+struct dfallAnglePacket_s {
++struct dfallPacket_s {
++    uint16_t controllerModes;
 +    uint16_t cmd1;
 +    uint16_t cmd2;
 +    uint16_t cmd3;
 +    uint16_t cmd4;
-+    float roll;
-+    float pitch;
-+    float yaw;
++    float xControllerSetpoint;
++    float yControllerSetpoint;
++    float zControllerSetpoint;
++    float yawControllerSetpoint;
 +} __attribute__((packed));
 +
-+static void dfallAngleDecoder(setpoint_t *setpoint, uint8_t type, const void *data, size_t datalen)
++static void dfallDecoder(setpoint_t *setpoint, uint8_t type, const void *data, size_t datalen)
 +{
-+  const struct dfallAnglePacket_s *values = data;
-+  ASSERT(datalen == sizeof(struct dfallRatePacket_s));
++  const struct dfallPacket_s *values = data;
++  ASSERT(datalen == sizeof(struct dfallPacket_s));
++
++  // DECODE THE 16-BIT INTEGER THAT ENCODES
++  // THE REQUESTED {x,y,z,yaw} CONTROLLER MODES
++  // > Each mode is encoded using 3 bits, stacked together as follows:
++  // ---------------------------------------------------------------
++  // |BIT   | 15 14 13 12 | 11 10  9 | 8  7  6 | 5  4  3 | 2  1  0 |
++  // |DESC. | free bits   | yaw_mode | z_mode  | y_mode  | x_mode  |
++  // ---------------------------------------------------------------
++
++  uint16_t mode_selector_bits = 7;
++
++  // EXTRACT THE MODE FOR EACH CONTROLLER
++  uint8_t x_controller_mode   = (values->controllerModes >> 0) & mode_selector_bits;
++  uint8_t y_controller_mode   = (values->controllerModes >> 3) & mode_selector_bits;
++  uint8_t z_controller_mode   = (values->controllerModes >> 6) & mode_selector_bits;
++  uint8_t yaw_controller_mode = (values->controllerModes >> 9) & mode_selector_bits;
++
++  // INITIALISE A BOOLEAN FOR TRACKING IF ANY
++  // OF THE CONTROLLER MODES ARE INVALID
++  bool invalid_controller_mode_requested = false;
++
++  // PROCESS THE X CONTROLLER
++  switch (x_controller_mode)
++  {
++    case DFALL_CONTROLLER_MODE_ANGULAR_RATE:
++      // Set the modes
++      setpoint->mode.x     = modeDisable;
++      setpoint->mode.pitch = modeVelocity;
++      // Set the setpoint
++      setpoint->position.x         = 0.0;
++      setpoint->velocity.x         = 0.0;
++      setpoint->attitude.pitch     = 0.0;
++      setpoint->attitudeRate.pitch = values->xControllerSetpoint;
++      break;
++
++    case DFALL_CONTROLLER_MODE_ANGLE:
++      // Set the modes
++      setpoint->mode.x     = modeDisable;
++      setpoint->mode.pitch = modeAbs;
++      // Set the setpoints
++      setpoint->position.x         = 0.0;
++      setpoint->velocity.x         = 0.0;
++      setpoint->attitude.pitch     = values->xControllerSetpoint;
++      setpoint->attitudeRate.pitch = 0.0;
++      break;
++
++    case DFALL_CONTROLLER_MODE_VELOCITY:
++      // Set the modes
++      setpoint->mode.x     = modeVelocity;
++      setpoint->mode.pitch = modeAbs;
++      // Set the setpoints
++      setpoint->position.x         = 0.0;
++      setpoint->velocity.x         = values->xControllerSetpoint;
++      setpoint->attitude.pitch     = 0.0;
++      setpoint->attitudeRate.pitch = 0.0;
++      break;
++
++    case DFALL_CONTROLLER_MODE_POSITION:
++      // Set the modes
++      setpoint->mode.x     = modeAbs;
++      setpoint->mode.pitch = modeAbs;
++      // Set the setpoints
++      setpoint->position.x         = values->xControllerSetpoint;
++      setpoint->velocity.x         = 0.0;
++      setpoint->attitude.pitch     = 0.0;
++      setpoint->attitudeRate.pitch = 0.0;
++      break;
++
++    case DFALL_CONTROLLER_MODE_OFF:
++      // Set the modes
++      setpoint->mode.x     = modeDisable;
++      setpoint->mode.pitch = modeDisable;
++      // Set the setpoints
++      setpoint->position.x         = 0.0;
++      setpoint->velocity.x         = 0.0;
++      setpoint->attitude.pitch     = 0.0;
++      setpoint->attitudeRate.pitch = 0.0;
++      break;
++
++    default:
++      // Set the flag that an invalid mode
++      // was requested
++      invalid_controller_mode_requested = true;
++      break;
++  }
++
++  // PROCESS THE Y CONTROLLER
++  switch (y_controller_mode)
++  {
++    case DFALL_CONTROLLER_MODE_ANGULAR_RATE:
++      // Set the modes
++      setpoint->mode.y    = modeDisable;
++      setpoint->mode.roll = modeVelocity;
++      // Set the setpoint
++      setpoint->position.y        = 0.0;
++      setpoint->velocity.y        = 0.0;
++      setpoint->attitude.roll     = 0.0;
++      setpoint->attitudeRate.roll = values->yControllerSetpoint;
++      break;
++
++    case DFALL_CONTROLLER_MODE_ANGLE:
++      // Set the modes
++      setpoint->mode.y    = modeDisable;
++      setpoint->mode.roll = modeAbs;
++      // Set the setpoints
++      setpoint->position.y        = 0.0;
++      setpoint->velocity.y        = 0.0;
++      setpoint->attitude.roll     = values->yControllerSetpoint;
++      setpoint->attitudeRate.roll = 0.0;
++      break;
++
++    case DFALL_CONTROLLER_MODE_VELOCITY:
++      // Set the modes
++      setpoint->mode.y    = modeVelocity;
++      setpoint->mode.roll = modeAbs;
++      // Set the setpoints
++      setpoint->position.y        = 0.0;
++      setpoint->velocity.y        = values->yControllerSetpoint;
++      setpoint->attitude.roll     = 0.0;
++      setpoint->attitudeRate.roll = 0.0;
++      break;
++
++    case DFALL_CONTROLLER_MODE_POSITION:
++      // Set the modes
++      setpoint->mode.y    = modeAbs;
++      setpoint->mode.roll = modeAbs;
++      // Set the setpoints
++      setpoint->position.y        = values->yControllerSetpoint;
++      setpoint->velocity.y        = 0.0;
++      setpoint->attitude.roll     = 0.0;
++      setpoint->attitudeRate.roll = 0.0;
++      break;
++
++    case DFALL_CONTROLLER_MODE_OFF:
++      // Set the modes
++      setpoint->mode.y    = modeDisable;
++      setpoint->mode.roll = modeDisable;
++      // Set the setpoints
++      setpoint->position.y        = 0.0;
++      setpoint->velocity.y        = 0.0;
++      setpoint->attitude.roll     = 0.0;
++      setpoint->attitudeRate.roll = 0.0;
++      break;
++
++    default:
++      // Set the flag that an invalid mode
++      // was requested
++      invalid_controller_mode_requested = true;
++      break;
++  }
++
++  // PROCESS THE Z CONTROLLER
++  switch (z_controller_mode)
++  {
++    case DFALL_CONTROLLER_MODE_VELOCITY:
++      // Set the mode
++      setpoint->mode.z = modeVelocity;
++      // Set the setpoints
++      setpoint->position.z = 0.0;
++      setpoint->velocity.z = values->zControllerSetpoint;
++      break;
++
++    case DFALL_CONTROLLER_MODE_POSITION:
++      // Set the mode
++      setpoint->mode.z = modeAbs;
++      // Set the setpoints
++      setpoint->position.z = values->zControllerSetpoint;
++      setpoint->velocity.z = 0.0;
++      break;
++
++    case DFALL_CONTROLLER_MODE_OFF:
++      // Set the mode
++      setpoint->mode.z = modeDisable;
++      // Set the setpoints
++      setpoint->position.z = 0.0;
++      setpoint->velocity.z = 0.0;
++      break;
++
++    case DFALL_CONTROLLER_MODE_ANGULAR_RATE:
++    case DFALL_CONTROLLER_MODE_ANGLE:
++    default:
++      // Set the flag that an invalid mode
++      // was requested
++      invalid_controller_mode_requested = true;
++      break;
++  }
 +
-+  // Disable the onboard position controllers
-+  setpoint->mode.x = modeDisable;
-+  setpoint->mode.y = modeDisable;
-+  setpoint->mode.z = modeDisable;
++  // PROCESS THE YAW CONTROLLER
++  switch (yaw_controller_mode)
++  {
++    case DFALL_CONTROLLER_MODE_ANGULAR_RATE:
++      // Set the mode
++      setpoint->mode.yaw = modeVelocity;
++      // Set the setpoint
++      setpoint->attitude.yaw     = 0.0;
++      setpoint->attitudeRate.yaw = values->yawControllerSetpoint;
++      break;
++
++    case DFALL_CONTROLLER_MODE_ANGLE:
++      // Set the modes
++      setpoint->mode.yaw = modeAbs;
++      // Set the setpoints
++      setpoint->attitude.roll     = values->yawControllerSetpoint;
++      setpoint->attitudeRate.roll = 0.0;
++      break;
++
++    case DFALL_CONTROLLER_MODE_OFF:
++      // Set the modes
++      setpoint->mode.yaw = modeDisable;
++      // Set the setpoints
++      setpoint->attitude.yaw     = 0.0;
++      setpoint->attitudeRate.yaw = 0.0;
++      break;
++
++    case DFALL_CONTROLLER_MODE_VELOCITY:
++    case DFALL_CONTROLLER_MODE_POSITION:
++    default:
++      // Set the flag that an invalid mode
++      // was requested
++      invalid_controller_mode_requested = true;
++      break;
++  }
 +
-+  // And set their setpoint values to zero
++  // Set the thrust setpoint to zero
 +  setpoint->thrust = 0;
-+  setpoint->position.x = 0;
-+  setpoint->position.y = 0;
-+  setpoint->position.z = 0;
-+  setpoint->velocity.x = 0;
-+  setpoint->velocity.y = 0;
-+  setpoint->velocity.z = 0;
-+
-+  // Enable the onboard orientation controllers in
-+  // absolute mode, i.e., as angle controllers
-+  setpoint->mode.roll  = modeAbs;
-+  setpoint->mode.pitch = modeAbs;
-+  setpoint->mode.yaw   = modeAbs;
-+
-+  // Transfer the angle commands from the packet
-+  // to the respective setpoints
-+  setpoint->attitude.roll = values->roll;
-+  setpoint->attitude.pitch = values->pitch;
-+  setpoint->attitude.yaw = values->yaw;
-+  // Set the angular rate setpoints to zero
-+  setpoint->attitudeRate.roll = 0;
-+  setpoint->attitudeRate.pitch = 0;
-+  setpoint->attitudeRate.yaw = 0;
 +
 +  // Tranfer the per-motor commands from the packet
 +  // to the respective setpoints
++  // NOTES:
++  // (1) this is performed regardless of the
++  //     "z_controller_mode" because the per motor
++  //     commands can be used for correcting steady-
++  //     state offsets in {x,y,yaw}.
++  // (2) if the "z_controller_mode" is in "POSITION"
++  //     or "VELOCITY" mode, then onboard controllers
++  //     will compute the main thurst controler, and
++  //     the user is expected to fill in cmd{1,2,3,4}
++  //     with only adjustment values.
 +  setpoint->cmd1 = limitUint16(values->cmd1);
 +  setpoint->cmd2 = limitUint16(values->cmd2);
 +  setpoint->cmd3 = limitUint16(values->cmd3);
 +  setpoint->cmd4 = limitUint16(values->cmd4);
 +
-+  // Set the "dfall_mode" accordingly
-+  setpoint->dfall_mode = modeDfallAngle;
-+}
++  // Set everything to off and zero if an invlaid
++  // controller mode was requested
++  if (invalid_controller_mode_requested)
++  {
++    // Set the modes
++    setpoint->mode.x     = modeDisable;
++    setpoint->mode.pitch = modeDisable;
++    setpoint->mode.y     = modeDisable;
++    setpoint->mode.roll  = modeDisable;
++    setpoint->mode.z     = modeDisable;
++    setpoint->mode.yaw   = modeDisable;
++
++    // Set the setpoints
++    setpoint->position.x         = 0.0;
++    setpoint->velocity.x         = 0.0;
++    setpoint->attitude.pitch     = 0.0;
++    setpoint->attitudeRate.pitch = 0.0;
++    setpoint->position.y         = 0.0;
++    setpoint->velocity.y         = 0.0;
++    setpoint->attitude.roll      = 0.0;
++    setpoint->attitudeRate.roll  = 0.0;
++    setpoint->position.z         = 0.0;
++    setpoint->velocity.z         = 0.0;
++    setpoint->attitude.yaw       = 0.0;
++    setpoint->attitudeRate.yaw   = 0.0;
++  }
 +
++  // Turn on the "dfall mode adjustments"
++  setpoint->useDfallAdjustmentsToControllerPID = true;
+ }
+ 
   /* ---===== 3 - packetDecoders array =====--- */
- const static packetDecoder_t packetDecoders[] = {
-   [stopType]          = stopDecoder,
-@@ -377,6 +554,9 @@ const static packetDecoder_t packetDecoders[] = {
+@@ -377,6 +703,7 @@ const static packetDecoder_t packetDecoders[] = {
    [hoverType]         = hoverDecoder,
    [fullStateType]     = fullStateDecoder,
    [positionType]      = positionDecoder,
-+  [dfallMotorsType]   = dfallMotorsDecoder,
-+  [dfallRateType]     = dfallRateDecoder,
-+  [dfallAngleType]    = dfallAngleDecoder,
++  [dfallType]         = dfallDecoder,
  };
  
  /* Decoder switch */
 diff --git a/src/modules/src/power_distribution_stock.c b/src/modules/src/power_distribution_stock.c
-index d3b7d8d..4e7f311 100644
+index d3b7d8d..072a699 100644
 --- a/src/modules/src/power_distribution_stock.c
 +++ b/src/modules/src/power_distribution_stock.c
 @@ -80,18 +80,18 @@ void powerDistribution(const control_t *control)
@@ -435,13 +604,10 @@ index d3b7d8d..4e7f311 100644
  
  LOG_GROUP_START(motor)
 -LOG_ADD(LOG_INT32, m4, &motorPower.m4)
--LOG_ADD(LOG_INT32, m1, &motorPower.m1)
--LOG_ADD(LOG_INT32, m2, &motorPower.m2)
--LOG_ADD(LOG_INT32, m3, &motorPower.m3)
-+LOG_ADD(LOG_UINT32, m1, &motorPower.m1)
-+LOG_ADD(LOG_UINT32, m2, &motorPower.m2)
-+LOG_ADD(LOG_UINT32, m3, &motorPower.m3)
-+LOG_ADD(LOG_UINT32, m4, &motorPower.m4)
+ LOG_ADD(LOG_INT32, m1, &motorPower.m1)
+ LOG_ADD(LOG_INT32, m2, &motorPower.m2)
+ LOG_ADD(LOG_INT32, m3, &motorPower.m3)
++LOG_ADD(LOG_INT32, m4, &motorPower.m4)
  LOG_GROUP_STOP(motor)
 diff --git a/src/modules/src/stabilizer.c b/src/modules/src/stabilizer.c
 index 372ec94..cb4f848 100644
diff --git a/crazyflie-firmware/success_building_for_version_2017-06.png b/crazyflie-firmware/success_building_for_version_2017-06.png
deleted file mode 100644
index f48fca5634c490355d66642170d49b5fe537af3f..0000000000000000000000000000000000000000
Binary files a/crazyflie-firmware/success_building_for_version_2017-06.png and /dev/null differ
diff --git a/crazyflie-firmware/success_building_for_version_2020-02.png b/crazyflie-firmware/success_building_for_version_2020-02.png
index 854299c68d6d3d49277d711d0e8608732f943949..62c3e54314a0fd24a7fbe4597521d22146530d38 100644
Binary files a/crazyflie-firmware/success_building_for_version_2020-02.png and b/crazyflie-firmware/success_building_for_version_2020-02.png differ
diff --git a/dfall_ws/src/dfall_pkg/CMakeLists.txt b/dfall_ws/src/dfall_pkg/CMakeLists.txt
index 292aec970604a3f4086a8bdc1fec47eb5c0d6664..1c4d9be33e6baf59676aa28724071a289fca1df0 100755
--- a/dfall_ws/src/dfall_pkg/CMakeLists.txt
+++ b/dfall_ws/src/dfall_pkg/CMakeLists.txt
@@ -249,16 +249,20 @@ endif()
 
 add_message_files(
   FILES
-  UnlabeledMarker.msg
-  CrazyflieData.msg
-  ViconData.msg
+  AreaBounds.msg
   ControlCommand.msg
   CrazyflieContext.msg
-  AreaBounds.msg
+  CrazyflieDB.msg
+  CrazyflieEntry.msg
+  CustomButton.msg
+  DebugMsg.msg
+  FlyingVehicleState.msg
+  GyroMeasurements.msg
   Setpoint.msg
   SetpointV2.msg
-  CrazyflieEntry.msg
-  CrazyflieDB.msg
+  UnlabeledMarker.msg
+  ViconData.msg
+  ViconSubscribeObjectName.msg
   #------------------------
   IntWithHeader.msg
   FloatWithHeader.msg
@@ -266,9 +270,6 @@ add_message_files(
   SetpointWithHeader.msg
   CustomButtonWithHeader.msg
   #------------------------
-  DebugMsg.msg
-  CustomButton.msg
-  ViconSubscribeObjectName.msg
 )
 
 ## Generate services in the 'srv' folder
@@ -280,6 +281,7 @@ add_message_files(
 add_service_files(
   FILES
   IntIntService.srv
+  IntStringService.srv
   Controller.srv
   CMRead.srv
   CMQuery.srv
@@ -287,6 +289,7 @@ add_service_files(
   CMUpdate.srv
   CMCommand.srv
   LoadYamlFromFilename.srv
+  GetDebugValuesService.srv
   GetSetpointService.srv
 )
 
@@ -391,41 +394,43 @@ endif()
 # add_executable(${PROJECT_NAME}_node src/dfall_pkg_node.cpp)
 
 if(VICON_LIBRARY)
-	add_executable(ViconDataPublisher       src/nodes/ViconDataPublisher.cpp)
+	add_executable(ViconDataPublisher        src/nodes/ViconDataPublisher.cpp)
 endif()
 
-add_executable(FlyingAgentClient         src/nodes/FlyingAgentClient.cpp
-                                         src/classes/GetParamtersAndNamespaces.cpp)
-add_executable(BatteryMonitor            src/nodes/BatteryMonitor.cpp
-                                         src/classes/GetParamtersAndNamespaces.cpp)
-add_executable(CrazyRadioEmulator        src/nodes/CrazyRadioEmulator.cpp
-                                         src/classes/GetParamtersAndNamespaces.cpp)
-add_executable(CsoneControllerService    src/nodes/CsoneControllerService.cpp
-                                         src/classes/GetParamtersAndNamespaces.cpp)
-add_executable(DefaultControllerService  src/nodes/DefaultControllerService.cpp
-                                         src/classes/GetParamtersAndNamespaces.cpp)
-add_executable(SafeControllerService     src/nodes/SafeControllerService.cpp)
-add_executable(DemoControllerService     src/nodes/DemoControllerService.cpp
-                                         src/classes/GetParamtersAndNamespaces.cpp)
-add_executable(StudentControllerService  src/nodes/StudentControllerService.cpp
-                                         src/classes/GetParamtersAndNamespaces.cpp)
-add_executable(MpcControllerService      src/nodes/MpcControllerService.cpp)
-add_executable(RemoteControllerService   src/nodes/RemoteControllerService.cpp
-                                         src/classes/GetParamtersAndNamespaces.cpp)
-add_executable(TuningControllerService   src/nodes/TuningControllerService.cpp
-                                         src/classes/GetParamtersAndNamespaces.cpp)
-add_executable(PickerControllerService   src/nodes/PickerControllerService.cpp
-                                         src/classes/GetParamtersAndNamespaces.cpp)
-add_executable(TemplateControllerService src/nodes/TemplateControllerService.cpp
-                                         src/classes/GetParamtersAndNamespaces.cpp)
+add_executable(FlyingAgentClient           src/nodes/FlyingAgentClient.cpp
+                                           src/classes/GetParamtersAndNamespaces.cpp)
+add_executable(AgentStatusForWebInterface  src/nodes/AgentStatusForWebInterface.cpp)
+add_executable(BatteryMonitor              src/nodes/BatteryMonitor.cpp
+                                           src/classes/GetParamtersAndNamespaces.cpp)
+add_executable(CrazyRadioEmulator          src/nodes/CrazyRadioEmulator.cpp
+                                           src/classes/QuadrotorSimulator.cpp
+                                           src/classes/GetParamtersAndNamespaces.cpp)
+add_executable(CsoneControllerService      src/nodes/CsoneControllerService.cpp
+                                           src/classes/GetParamtersAndNamespaces.cpp)
+add_executable(DefaultControllerService    src/nodes/DefaultControllerService.cpp
+                                           src/classes/GetParamtersAndNamespaces.cpp)
+# add_executable(SafeControllerService       src/nodes/SafeControllerService.cpp)
+# add_executable(DemoControllerService       src/nodes/DemoControllerService.cpp
+#                                            src/classes/GetParamtersAndNamespaces.cpp)
+add_executable(StudentControllerService    src/nodes/StudentControllerService.cpp
+                                           src/classes/GetParamtersAndNamespaces.cpp)
+# add_executable(MpcControllerService        src/nodes/MpcControllerService.cpp)
+add_executable(RemoteControllerService     src/nodes/RemoteControllerService.cpp
+                                           src/classes/GetParamtersAndNamespaces.cpp)
+add_executable(TuningControllerService     src/nodes/TuningControllerService.cpp
+                                           src/classes/GetParamtersAndNamespaces.cpp)
+add_executable(PickerControllerService     src/nodes/PickerControllerService.cpp
+                                           src/classes/GetParamtersAndNamespaces.cpp)
+add_executable(TemplateControllerService   src/nodes/TemplateControllerService.cpp
+                                           src/classes/GetParamtersAndNamespaces.cpp)
 add_executable(TestMotorsControllerService src/nodes/TestMotorsControllerService.cpp
-                                         src/classes/GetParamtersAndNamespaces.cpp)
-add_executable(CentralManagerService     src/nodes/CentralManagerService.cpp src/CrazyflieIO.cpp)
-add_executable(ParameterService          src/nodes/ParameterService.cpp)
+                                           src/classes/GetParamtersAndNamespaces.cpp)
+add_executable(CentralManagerService       src/nodes/CentralManagerService.cpp src/classes/CrazyflieIO.cpp)
+add_executable(ParameterService            src/nodes/ParameterService.cpp)
 
-add_executable(MocapEmulator             src/nodes/MocapEmulator.cpp
-                                         src/classes/QuadrotorSimulator.cpp
-                                         src/classes/GetParamtersAndNamespaces.cpp)
+add_executable(MocapEmulator               src/nodes/MocapEmulator.cpp
+                                           src/classes/QuadrotorSimulator.cpp
+                                           src/classes/GetParamtersAndNamespaces.cpp)
 
 
 
@@ -493,24 +498,25 @@ if(VICON_LIBRARY)
 	add_dependencies(ViconDataPublisher       dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
 endif()
 
-add_dependencies(FlyingAgentClient         dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
-add_dependencies(BatteryMonitor            dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
-add_dependencies(CrazyRadioEmulator        dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
-add_dependencies(CsoneControllerService    dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
-add_dependencies(DefaultControllerService  dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
-add_dependencies(SafeControllerService     dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
-add_dependencies(DemoControllerService     dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
-add_dependencies(StudentControllerService  dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
-add_dependencies(MpcControllerService      dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
-add_dependencies(RemoteControllerService   dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
-add_dependencies(TuningControllerService   dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
-add_dependencies(PickerControllerService   dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
-add_dependencies(TemplateControllerService dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
+add_dependencies(FlyingAgentClient           dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
+add_dependencies(AgentStatusForWebInterface  dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
+add_dependencies(BatteryMonitor              dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
+add_dependencies(CrazyRadioEmulator          dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
+add_dependencies(CsoneControllerService      dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
+add_dependencies(DefaultControllerService    dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
+# add_dependencies(SafeControllerService       dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
+# add_dependencies(DemoControllerService       dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
+add_dependencies(StudentControllerService    dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
+# add_dependencies(MpcControllerService        dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
+add_dependencies(RemoteControllerService     dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
+add_dependencies(TuningControllerService     dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
+add_dependencies(PickerControllerService     dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
+add_dependencies(TemplateControllerService   dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
 add_dependencies(TestMotorsControllerService dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
-add_dependencies(CentralManagerService     dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
-add_dependencies(ParameterService          dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
+add_dependencies(CentralManagerService       dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
+add_dependencies(ParameterService            dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
 
-add_dependencies(MocapEmulator             dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
+add_dependencies(MocapEmulator               dfall_pkg_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
 
 
 
@@ -547,28 +553,29 @@ if(VICON_LIBRARY)
 	target_link_libraries(ViconDataPublisher ${VICON_LIBRARY})
 endif()
 
-target_link_libraries(FlyingAgentClient         ${catkin_LIBRARIES})
-target_link_libraries(BatteryMonitor            ${catkin_LIBRARIES})
-target_link_libraries(CrazyRadioEmulator        ${catkin_LIBRARIES})
-target_link_libraries(CsoneControllerService    ${catkin_LIBRARIES})
-target_link_libraries(DefaultControllerService  ${catkin_LIBRARIES})
-target_link_libraries(SafeControllerService     ${catkin_LIBRARIES})
-target_link_libraries(DemoControllerService     ${catkin_LIBRARIES})
-target_link_libraries(StudentControllerService  ${catkin_LIBRARIES})
-if(Eigen3_FOUND)
-  target_link_libraries(MpcControllerService     ${catkin_LIBRARIES} Eigen3::Eigen)
-else()
-  target_link_libraries(MpcControllerService     ${catkin_LIBRARIES})
-endif()
-target_link_libraries(RemoteControllerService   ${catkin_LIBRARIES})
-target_link_libraries(TuningControllerService   ${catkin_LIBRARIES})
-target_link_libraries(PickerControllerService   ${catkin_LIBRARIES})
-target_link_libraries(TemplateControllerService ${catkin_LIBRARIES})
+target_link_libraries(FlyingAgentClient           ${catkin_LIBRARIES})
+target_link_libraries(AgentStatusForWebInterface  ${catkin_LIBRARIES})
+target_link_libraries(BatteryMonitor              ${catkin_LIBRARIES})
+target_link_libraries(CrazyRadioEmulator          ${catkin_LIBRARIES})
+target_link_libraries(CsoneControllerService      ${catkin_LIBRARIES})
+target_link_libraries(DefaultControllerService    ${catkin_LIBRARIES})
+# target_link_libraries(SafeControllerService       ${catkin_LIBRARIES})
+# target_link_libraries(DemoControllerService       ${catkin_LIBRARIES})
+target_link_libraries(StudentControllerService    ${catkin_LIBRARIES})
+# if(Eigen3_FOUND)
+#   target_link_libraries(MpcControllerService       ${catkin_LIBRARIES} Eigen3::Eigen)
+# else()
+#   target_link_libraries(MpcControllerService       ${catkin_LIBRARIES})
+# endif()
+target_link_libraries(RemoteControllerService     ${catkin_LIBRARIES})
+target_link_libraries(TuningControllerService     ${catkin_LIBRARIES})
+target_link_libraries(PickerControllerService     ${catkin_LIBRARIES})
+target_link_libraries(TemplateControllerService   ${catkin_LIBRARIES})
 target_link_libraries(TestMotorsControllerService ${catkin_LIBRARIES})
-target_link_libraries(CentralManagerService     ${catkin_LIBRARIES})
-target_link_libraries(ParameterService          ${catkin_LIBRARIES})
+target_link_libraries(CentralManagerService       ${catkin_LIBRARIES})
+target_link_libraries(ParameterService            ${catkin_LIBRARIES})
 
-target_link_libraries(MocapEmulator             ${catkin_LIBRARIES})
+target_link_libraries(MocapEmulator               ${catkin_LIBRARIES})
 
 
 if(Qt5_FOUND)
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/forms/enablecontrollerloadyamlbar.ui b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/forms/enablecontrollerloadyamlbar.ui
index d92fc08b2c7ba41f048c17b9d4c7bcdee4802863..9a431b5b4854d394344fa58de136469fde74bfae 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/forms/enablecontrollerloadyamlbar.ui
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/forms/enablecontrollerloadyamlbar.ui
@@ -6,7 +6,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>1572</width>
+    <width>1784</width>
     <height>403</height>
    </rect>
   </property>
@@ -30,87 +30,6 @@
      <property name="spacing">
       <number>12</number>
      </property>
-     <item row="1" column="5">
-      <widget class="QPushButton" name="load_yaml_tuning_button">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="minimumSize">
-        <size>
-         <width>60</width>
-         <height>50</height>
-        </size>
-       </property>
-       <property name="maximumSize">
-        <size>
-         <width>180</width>
-         <height>50</height>
-        </size>
-       </property>
-       <property name="text">
-        <string>Tuning</string>
-       </property>
-      </widget>
-     </item>
-     <item row="1" column="7">
-      <widget class="QPushButton" name="load_yaml_template_button">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="minimumSize">
-        <size>
-         <width>60</width>
-         <height>50</height>
-        </size>
-       </property>
-       <property name="maximumSize">
-        <size>
-         <width>180</width>
-         <height>50</height>
-        </size>
-       </property>
-       <property name="text">
-        <string>Template</string>
-       </property>
-      </widget>
-     </item>
-     <item row="0" column="2">
-      <widget class="QPushButton" name="enable_student_button">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="minimumSize">
-        <size>
-         <width>60</width>
-         <height>50</height>
-        </size>
-       </property>
-       <property name="maximumSize">
-        <size>
-         <width>180</width>
-         <height>50</height>
-        </size>
-       </property>
-       <property name="font">
-        <font>
-         <weight>50</weight>
-         <bold>false</bold>
-        </font>
-       </property>
-       <property name="text">
-        <string>Student</string>
-       </property>
-      </widget>
-     </item>
      <item row="0" column="0">
       <widget class="QLabel" name="enable_controller_label">
        <property name="sizePolicy">
@@ -145,149 +64,6 @@
        </property>
       </widget>
      </item>
-     <item row="1" column="2">
-      <widget class="QPushButton" name="load_yaml_student_button">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="minimumSize">
-        <size>
-         <width>60</width>
-         <height>50</height>
-        </size>
-       </property>
-       <property name="maximumSize">
-        <size>
-         <width>180</width>
-         <height>50</height>
-        </size>
-       </property>
-       <property name="text">
-        <string>Student</string>
-       </property>
-      </widget>
-     </item>
-     <item row="0" column="5">
-      <widget class="QPushButton" name="enable_tuning_button">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="minimumSize">
-        <size>
-         <width>60</width>
-         <height>50</height>
-        </size>
-       </property>
-       <property name="maximumSize">
-        <size>
-         <width>180</width>
-         <height>50</height>
-        </size>
-       </property>
-       <property name="text">
-        <string>Tuning</string>
-       </property>
-      </widget>
-     </item>
-     <item row="0" column="1">
-      <widget class="QPushButton" name="enable_default_button">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="minimumSize">
-        <size>
-         <width>60</width>
-         <height>50</height>
-        </size>
-       </property>
-       <property name="maximumSize">
-        <size>
-         <width>180</width>
-         <height>50</height>
-        </size>
-       </property>
-       <property name="font">
-        <font>
-         <weight>50</weight>
-         <bold>false</bold>
-        </font>
-       </property>
-       <property name="text">
-        <string>Default</string>
-       </property>
-      </widget>
-     </item>
-     <item row="0" column="4">
-      <widget class="QPushButton" name="enable_picker_button">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="minimumSize">
-        <size>
-         <width>60</width>
-         <height>50</height>
-        </size>
-       </property>
-       <property name="maximumSize">
-        <size>
-         <width>180</width>
-         <height>50</height>
-        </size>
-       </property>
-       <property name="font">
-        <font>
-         <weight>50</weight>
-         <bold>false</bold>
-        </font>
-       </property>
-       <property name="text">
-        <string>Picker</string>
-       </property>
-      </widget>
-     </item>
-     <item row="0" column="7">
-      <widget class="QPushButton" name="enable_template_button">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="minimumSize">
-        <size>
-         <width>60</width>
-         <height>50</height>
-        </size>
-       </property>
-       <property name="maximumSize">
-        <size>
-         <width>180</width>
-         <height>50</height>
-        </size>
-       </property>
-       <property name="font">
-        <font>
-         <weight>50</weight>
-         <bold>false</bold>
-        </font>
-       </property>
-       <property name="text">
-        <string>Template</string>
-       </property>
-      </widget>
-     </item>
      <item row="1" column="0">
       <widget class="QLabel" name="load_yaml_label">
        <property name="sizePolicy">
@@ -322,167 +98,440 @@
        </property>
       </widget>
      </item>
-     <item row="1" column="1">
-      <widget class="QPushButton" name="load_yaml_default_button">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="minimumSize">
-        <size>
-         <width>60</width>
-         <height>50</height>
-        </size>
-       </property>
-       <property name="maximumSize">
-        <size>
-         <width>180</width>
-         <height>50</height>
-        </size>
-       </property>
-       <property name="text">
-        <string>Default</string>
-       </property>
-      </widget>
-     </item>
-     <item row="0" column="8">
-      <spacer name="horizontalSpacer">
-       <property name="orientation">
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>40</width>
-         <height>20</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
-     <item row="0" column="6">
-      <widget class="QPushButton" name="enable_remote_button">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="minimumSize">
-        <size>
-         <width>60</width>
-         <height>50</height>
-        </size>
-       </property>
-       <property name="maximumSize">
-        <size>
-         <width>180</width>
-         <height>50</height>
-        </size>
-       </property>
-       <property name="text">
-        <string>Remote</string>
-       </property>
-      </widget>
-     </item>
-     <item row="1" column="6">
-      <widget class="QPushButton" name="load_yaml_remote_button">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="minimumSize">
-        <size>
-         <width>60</width>
-         <height>50</height>
-        </size>
-       </property>
-       <property name="maximumSize">
-        <size>
-         <width>180</width>
-         <height>50</height>
-        </size>
-       </property>
-       <property name="text">
-        <string>Remote</string>
-       </property>
-      </widget>
-     </item>
-     <item row="1" column="4">
-      <widget class="QPushButton" name="load_yaml_picker_button">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="minimumSize">
-        <size>
-         <width>60</width>
-         <height>50</height>
-        </size>
-       </property>
-       <property name="maximumSize">
-        <size>
-         <width>180</width>
-         <height>50</height>
-        </size>
-       </property>
-       <property name="text">
-        <string>Picker</string>
-       </property>
-      </widget>
-     </item>
-     <item row="0" column="3">
-      <widget class="QPushButton" name="enable_csone_button">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="minimumSize">
-        <size>
-         <width>60</width>
-         <height>50</height>
-        </size>
-       </property>
-       <property name="maximumSize">
-        <size>
-         <width>180</width>
-         <height>49</height>
-        </size>
-       </property>
-       <property name="text">
-        <string>CS1</string>
-       </property>
+     <item row="1" column="2">
+      <widget class="QWidget" name="widget_yamlButtons" native="true">
+       <layout class="QHBoxLayout" name="horizontalLayout_2">
+        <property name="leftMargin">
+         <number>0</number>
+        </property>
+        <property name="topMargin">
+         <number>0</number>
+        </property>
+        <property name="rightMargin">
+         <number>0</number>
+        </property>
+        <property name="bottomMargin">
+         <number>0</number>
+        </property>
+        <item>
+         <widget class="QPushButton" name="load_yaml_default_button">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>60</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>180</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="text">
+           <string>Default</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="load_yaml_student_button">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>60</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>180</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="text">
+           <string>Student</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="load_yaml_csone_button">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>60</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>180</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="text">
+           <string>CS1</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="load_yaml_picker_button">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>60</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>180</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="text">
+           <string>Picker</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="load_yaml_tuning_button">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>60</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>180</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="text">
+           <string>Tuning</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="load_yaml_remote_button">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>60</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>180</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="text">
+           <string>Remote</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="load_yaml_template_button">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>60</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>180</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="text">
+           <string>Template</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer_2">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
       </widget>
      </item>
-     <item row="1" column="3">
-      <widget class="QPushButton" name="load_yaml_csone_button">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="minimumSize">
-        <size>
-         <width>60</width>
-         <height>50</height>
-        </size>
-       </property>
-       <property name="maximumSize">
-        <size>
-         <width>180</width>
-         <height>50</height>
-        </size>
-       </property>
-       <property name="text">
-        <string>CS1</string>
-       </property>
+     <item row="0" column="2">
+      <widget class="QWidget" name="widget_enableButtons" native="true">
+       <layout class="QHBoxLayout" name="horizontalLayout_3">
+        <property name="leftMargin">
+         <number>0</number>
+        </property>
+        <property name="topMargin">
+         <number>0</number>
+        </property>
+        <property name="rightMargin">
+         <number>0</number>
+        </property>
+        <property name="bottomMargin">
+         <number>0</number>
+        </property>
+        <item>
+         <widget class="QPushButton" name="enable_default_button">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>60</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>180</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="font">
+           <font>
+            <weight>50</weight>
+            <bold>false</bold>
+           </font>
+          </property>
+          <property name="text">
+           <string>Default</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="enable_student_button">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>60</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>180</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="font">
+           <font>
+            <weight>50</weight>
+            <bold>false</bold>
+           </font>
+          </property>
+          <property name="text">
+           <string>Student</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="enable_csone_button">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>60</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>180</width>
+            <height>49</height>
+           </size>
+          </property>
+          <property name="text">
+           <string>CS1</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="enable_picker_button">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>60</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>180</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="font">
+           <font>
+            <weight>50</weight>
+            <bold>false</bold>
+           </font>
+          </property>
+          <property name="text">
+           <string>Picker</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="enable_tuning_button">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>60</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>180</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="text">
+           <string>Tuning</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="enable_remote_button">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>60</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>180</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="text">
+           <string>Remote</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="enable_template_button">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>60</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>180</width>
+            <height>50</height>
+           </size>
+          </property>
+          <property name="font">
+           <font>
+            <weight>50</weight>
+            <bold>false</bold>
+           </font>
+          </property>
+          <property name="text">
+           <string>Template</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
       </widget>
      </item>
     </layout>
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/forms/mainwindow.ui b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/forms/mainwindow.ui
index aa37362f82fe3ccd8e170ddccc5d29abb8e9f4e9..401d1042c7eac0c7f10b21c1d6f66b94ba5d6840 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/forms/mainwindow.ui
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/forms/mainwindow.ui
@@ -190,14 +190,14 @@
      <x>0</x>
      <y>0</y>
      <width>1862</width>
-     <height>26</height>
+     <height>47</height>
     </rect>
    </property>
    <widget class="QMenu" name="menuFile">
     <property name="title">
      <string>File</string>
     </property>
-    <addaction name="actionShowHide_Coordinator"/>
+    <addaction name="action_showHide_Coordinator"/>
    </widget>
    <widget class="QMenu" name="menuLoad_YAML">
     <property name="title">
@@ -205,6 +205,8 @@
     </property>
     <addaction name="action_LoadYAML_BatteryMonitor"/>
     <addaction name="action_LoadYAML_FlyingAgentClientConfig"/>
+    <addaction name="separator"/>
+    <addaction name="action_showHide_loadYamlBar"/>
    </widget>
    <widget class="QMenu" name="menuControllers">
     <property name="title">
@@ -233,7 +235,7 @@
    </attribute>
   </widget>
   <widget class="QStatusBar" name="statusBar"/>
-  <action name="actionShowHide_Coordinator">
+  <action name="action_showHide_Coordinator">
    <property name="text">
     <string>Hide Coordinator</string>
    </property>
@@ -344,6 +346,11 @@
     <string>CS1</string>
    </property>
   </action>
+  <action name="action_showHide_loadYamlBar">
+   <property name="text">
+    <string>Hide Yaml Buttons</string>
+   </property>
+  </action>
  </widget>
  <layoutdefault spacing="6" margin="11"/>
  <customwidgets>
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/controllertabs.h b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/controllertabs.h
index 08df7f2abf692151d88cdb129af0466fc6f39d29..d7bff72dee05aa975312b82d7a32184ac15c1db4 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/controllertabs.h
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/controllertabs.h
@@ -57,7 +57,7 @@
 // Include the DFALL message types
 //#include "dfall_pkg/IntWithHeader.h"
 //#include "dfall_pkg/SetpointWithHeader.h"
-#include "dfall_pkg/CrazyflieData.h"
+#include "dfall_pkg/FlyingVehicleState.h"
 #include "dfall_pkg/ViconData.h"
 #include "dfall_pkg/AreaBounds.h"
 #include "dfall_pkg/CrazyflieContext.h"
@@ -108,7 +108,7 @@ public slots:
 
 signals:
     void agentIDsToCoordinateChanged(QVector<int> agentIDs , bool shouldCoordinateAll);
-    void measuredPoseValueChanged(float x , float y , float z , float roll , float pitch , float yaw , bool occluded);
+    void measuredPoseValueChanged(float x , float y , float z , float roll , float pitch , float yaw , bool isValid);
     void poseDataUnavailableSignal();
 
 
@@ -146,6 +146,12 @@ private:
     // Sound effect for when the controller changes while flying
     //QSoundEffect m_soundEffect_controllerChanged;
 
+    // FLAG FOR WHAT DATA TO EMIT
+    // > For "poseDataMocap"
+    bool m_shouldEmitPoseDataMocap = true;
+    // > For "poseDataOnboard"
+    bool m_shouldEmitPoseDataOnboard = false;
+
 
 #ifdef CATKIN_MAKE
     // --------------------------------------------------- //
@@ -157,7 +163,9 @@ private:
 
     // SUBSRIBER
     // > For the pose data from a motion capture system
-    ros::Subscriber m_poseDataSubscriber;
+    ros::Subscriber m_poseDataMocapSubscriber;
+    // > For the pose data from a onboard state estimate
+    ros::Subscriber m_poseDataOnboardSubscriber;
     // > For the controller that is currently operating
     ros::Subscriber controllerUsedSubscriber;
 
@@ -171,10 +179,16 @@ private:
     // --------------------------------------------------- //
     // PRIVATE CALLBACKS IN RESPONSE TO ROS MESSAGES
 
+    // > For the data from the motion capture system, received on
+    //   "m_poseDataMocapSubscriber"
+    void poseDataMocapReceivedCallback(const dfall_pkg::ViconData& viconData);
+
+    // > For the data from onboard the flying agent, received on
+    //   "m_poseDataOnboardSubscriber"
+    void poseDataOnboardReceivedCallback(const dfall_pkg::FlyingVehicleState& vehicleState);
+
     // > For the controller currently operating, received on
     //   "controllerUsedSubscriber"
-    void poseDataReceivedCallback(const dfall_pkg::ViconData& viconData);
-
     void controllerUsedChangedCallback(const std_msgs::Int32& msg);
 
     // Get the paramters that specify the type and ID
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/csonecontrollertab.h b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/csonecontrollertab.h
index 5ba4e0551fd52aba071661895065dfd3b6e7d102..9bdef6b6c2c666f61d2e2ddc281977cb7ae477fc 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/csonecontrollertab.h
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/csonecontrollertab.h
@@ -114,7 +114,7 @@ public:
 
 public slots:
     void setAgentIDsToCoordinate(QVector<int> agentIDs , bool shouldCoordinateAll);
-    void setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool occluded);
+    void setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool isValid);
     void poseDataUnavailableSlot();
 
 
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/defaultcontrollertab.h b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/defaultcontrollertab.h
index 64f315c4f1710841b4c8bdb502a913f57fad39ab..c462a1b191142094733eb7a569260bc6f5b14459 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/defaultcontrollertab.h
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/defaultcontrollertab.h
@@ -89,7 +89,7 @@ public:
 
 public slots:
     void setAgentIDsToCoordinate(QVector<int> agentIDs , bool shouldCoordinateAll);
-    void setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool occluded);
+    void setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool isValid);
     void poseDataUnavailableSlot();
 
 
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/enablecontrollerloadyamlbar.h b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/enablecontrollerloadyamlbar.h
index c411e2d12fc07b1844615f6ed68c843a239e9aa0..888f6cad5dd905d34adfdc0eb07304ae6604ff6c 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/enablecontrollerloadyamlbar.h
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/enablecontrollerloadyamlbar.h
@@ -95,9 +95,15 @@ public:
     void showHideController_remote_changed();
     void showHideController_template_changed();
     void showHideController_csone_changed();
+
+    // PUBLIC METHOD FOR TOGGLING THE VISIBILITY OF THE YAML BAR
+    bool showHide_loadYamlBar_triggered();
+
+    // PUBLIC METHODS FOR ENABLING THE TEST MOTORS CONTROLLER
     void testMotors_triggered();
 
 
+
 public slots:
     void setAgentIDsToCoordinate(QVector<int> agentIDs , bool shouldCoordinateAll);
 
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/mainwindow.h b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/mainwindow.h
index 09cab55768363e2a94de5314c39ba75f9642b009..63a0e37630ce6f13d0a847caa0a9df5c8ffbf75d 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/mainwindow.h
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/mainwindow.h
@@ -122,7 +122,8 @@ private:
 
 private slots:
     // PRIVATE METHODS FOR MENU ITEM CALLBACKS
-    void on_actionShowHide_Coordinator_triggered();
+    void on_action_showHide_Coordinator_triggered();
+    void on_action_showHide_loadYamlBar_triggered();
     void on_action_LoadYAML_BatteryMonitor_triggered();
     void on_action_LoadYAML_FlyingAgentClientConfig_triggered();
 
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/pickercontrollertab.h b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/pickercontrollertab.h
index 52b79e13875c744e4351bcca11989c6a293cc87a..12270b725c154858df5857833257404ac045b3ec 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/pickercontrollertab.h
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/pickercontrollertab.h
@@ -117,7 +117,7 @@ public:
 
 public slots:
     void setAgentIDsToCoordinate(QVector<int> agentIDs , bool shouldCoordinateAll);
-    void setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool occluded);
+    void setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool isValid);
     void poseDataUnavailableSlot();
 
 
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/remotecontrollertab.h b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/remotecontrollertab.h
index 60d50bc203614b14d18b457e91d3acabe21704dc..1738a169395937dbe053b61ad41fdad9fb21c2dc 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/remotecontrollertab.h
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/remotecontrollertab.h
@@ -56,7 +56,7 @@
 //#include "dfall_pkg/IntWithHeader.h"
 #include "dfall_pkg/SetpointWithHeader.h"
 #include "dfall_pkg/CustomButtonWithHeader.h"
-#include "dfall_pkg/CrazyflieData.h"
+#include "dfall_pkg/FlyingVehicleState.h"
 #include "dfall_pkg/ViconSubscribeObjectName.h"
 
 // Include the DFALL service types
@@ -94,7 +94,7 @@ public:
 
 public slots:
     void setAgentIDsToCoordinate(QVector<int> agentIDs , bool shouldCoordinateAll);
-    void setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool occluded);
+    void setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool isValid);
     void poseDataUnavailableSlot();
 
 
@@ -176,8 +176,8 @@ private:
 
     // COPIED FROM PREVIOUS REMOTE CONTROLLER GUI
     // For receiving message with the data of the remote
-    void remoteDataCallback(const dfall_pkg::CrazyflieData& objectData);
-    void remoteControlSetpointCallback(const dfall_pkg::CrazyflieData& setpointData);
+    void remoteDataCallback(const dfall_pkg::FlyingVehicleState& objectData);
+    void remoteControlSetpointCallback(const dfall_pkg::FlyingVehicleState& setpointData);
 
 
     // For receiving message that the setpoint was changed
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/rosNodeThread_for_flyingAgentGUI.h b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/rosNodeThread_for_flyingAgentGUI.h
index 79c447e84f9131164b1faaef335d1d89c06e7ea4..bd16b6041d939a07934b0e5b42d59102741d7de2 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/rosNodeThread_for_flyingAgentGUI.h
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/rosNodeThread_for_flyingAgentGUI.h
@@ -52,7 +52,7 @@
 #include "dfall_pkg/CMCommand.h"
 
 //#include "dfall_pkg/UnlabeledMarker.h"
-//#include "dfall_pkg/CrazyflieData.h"
+//#include "dfall_pkg/FlyingVehicleState.h"
 //#include "dfall_pkg/ViconData.h"
 
 using namespace dfall_pkg;
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/studentcontrollertab.h b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/studentcontrollertab.h
index be7ed5f428526feac37a3651024fd53c41c22a30..587290b0b9c2a117d792c8ff3129baa18f9f8a35 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/studentcontrollertab.h
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/studentcontrollertab.h
@@ -90,7 +90,7 @@ public:
 
 public slots:
     void setAgentIDsToCoordinate(QVector<int> agentIDs , bool shouldCoordinateAll);
-    void setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool occluded);
+    void setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool isValid);
     void poseDataUnavailableSlot();
 
 
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/templatecontrollertab.h b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/templatecontrollertab.h
index 0f9377bb2fa435ca5b98dd792bbde4b863b6fbc2..119c326fe83ea55cd00df9745eeb3aa694e6bff4 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/templatecontrollertab.h
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/templatecontrollertab.h
@@ -92,7 +92,7 @@ public:
 
 public slots:
     void setAgentIDsToCoordinate(QVector<int> agentIDs , bool shouldCoordinateAll);
-    void setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool occluded);
+    void setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool isValid);
     void poseDataUnavailableSlot();
 
 
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/tuningcontrollertab.h b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/tuningcontrollertab.h
index cf8ecf0525abc397d37426452aef8d3c4a90bba1..d680c50cb4f22eb0f577da818073891af00a496b 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/tuningcontrollertab.h
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/tuningcontrollertab.h
@@ -112,7 +112,7 @@ public:
 
 public slots:
     void setAgentIDsToCoordinate(QVector<int> agentIDs , bool shouldCoordinateAll);
-    void setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool occluded);
+    void setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool isValid);
     void poseDataUnavailableSlot();
 
 
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/controllertabs.cpp b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/controllertabs.cpp
index c29d10d692ea6cf2e3e89f0bf6af1558c509b5b4..ebd02d934a4a4ebc75a16d2bceb273ea1d600354 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/controllertabs.cpp
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/controllertabs.cpp
@@ -202,6 +202,28 @@ ControllerTabs::ControllerTabs(QWidget *parent) :
 
 
 
+    // GET THE "onload" PARAMETERS FOR WHAT DATA TO EMIT
+    // > Create a "ros::NodeHandle" type local variable
+    //   "nodeHandle" as the current node, the "~" indcates
+    //   that "self" is the node handle assigned to this
+    //   variable.
+    ros::NodeHandle nodeHandle("~");
+    // > For "poseDataMocap"
+    if(!nodeHandle.getParam("onlaunch_shouldEmitPoseDataMocap", m_shouldEmitPoseDataMocap))
+    {
+        m_shouldEmitPoseDataMocap = false;
+        ROS_ERROR("[CONTROLLER TABS GUI] missing parameter 'onlaunch_shouldEmitPoseDataMocap'");
+    }
+    // > For "poseDataOnboard"
+    if(!nodeHandle.getParam("onlaunch_shouldEmitPoseDataOnboard", m_shouldEmitPoseDataOnboard))
+    {
+        m_shouldEmitPoseDataOnboard = false;
+        ROS_ERROR("[CONTROLLER TABS GUI] missing parameter 'onlaunch_shouldEmitPoseDataOnboard'");
+    }
+
+
+
+
     // CREATE A NODE HANDLE TO THIS GUI
     ros::NodeHandle nodeHandle_for_this_gui(this_namespace);
 
@@ -209,26 +231,39 @@ ControllerTabs::ControllerTabs(QWidget *parent) :
     ros::NodeHandle nodeHandle_dfall_root("/dfall");
 
     // CREATE THE SUBSCRIBER TO THE MOTION CAPTURE DATA
-    m_poseDataSubscriber = nodeHandle_dfall_root.subscribe("ViconDataPublisher/ViconData", 100, &ControllerTabs::poseDataReceivedCallback, this);
+    m_poseDataMocapSubscriber = nodeHandle_dfall_root.subscribe("ViconDataPublisher/ViconData", 3, &ControllerTabs::poseDataMocapReceivedCallback, this);
 
-    // CREATE THE SUBSCRIBER TO THE CONTROLLER THAT IS CURRENTLY OPERATING
-    // Only if this is an agent GUI
+    // CREATE THE SUBSCRIBER TO AGENT SPECIFIC TOPICS:
+    // i.e., only if this is an agent GUI
     if (m_type == TYPE_AGENT)
     {
+        // THE STATE ESTIMATE FROM ONBOARD THE FLYING AGENT
+        m_poseDataOnboardSubscriber = nodeHandle_for_this_gui.subscribe("CrazyRadio/CFStateEstimate", 3, &ControllerTabs::poseDataOnboardReceivedCallback, this);
+        // THE CONTROLLER THAT IS CURRENTLY OPERATING
         controllerUsedSubscriber = nodeHandle_for_this_gui.subscribe("FlyingAgentClient/ControllerUsed", 1, &ControllerTabs::controllerUsedChangedCallback, this);
     }
 
+    // NOTE: FOR THE "poseDataMocap" AND "poseDataOnboard"
+    // SUBSCRIBERS:
+    // > The second argument is the queue_size, and the
+    //   documentation states that:
+    //   "If messages are arriving too fast and you are
+    //    unable to keep up, roscpp will start throwing
+    //    away messages."
+    // > It is clearly stated that publisher queues throw
+    //   away old messages first, and subscriber queues
+    //   are likely the same.
+    // > As we are only interested in latest measurement
+    //   a short queue is used.
 
 
-    // CREATE A NODE HANDLE TO THE ROOT OF THE D-FaLL SYSTEM
-    ros::NodeHandle dfall_root_nodeHandle("/dfall");
 
     // > Publisher for the emergency stop button
-    //emergencyStopPublisher = dfall_root_nodeHandle.advertise<dfall_pkg::IntWithHeader>("EmergencyStop", 1);
+    //emergencyStopPublisher = nodeHandle_dfall_root.advertise<dfall_pkg::IntWithHeader>("EmergencyStop", 1);
 
     // > For changes in the database that defines {agentID,cfID,flying zone} links
-    //databaseChangedSubscriber = dfall_root_nodeHandle.subscribe("CentralManagerService/DBChanged", 1, &TopBanner::databaseChangedCallback, this);;
-    centralManagerDatabaseService = dfall_root_nodeHandle.serviceClient<dfall_pkg::CMQuery>("CentralManagerService/Query", false);
+    //databaseChangedSubscriber = nodeHandle_dfall_root.subscribe("CentralManagerService/DBChanged", 1, &TopBanner::databaseChangedCallback, this);;
+    centralManagerDatabaseService = nodeHandle_dfall_root.serviceClient<dfall_pkg::CMQuery>("CentralManagerService/Query", false);
 
 
 #endif
@@ -361,18 +396,18 @@ void ControllerTabs::setObjectNameForDisplayingPoseData( QString object_name )
 
 
 #ifdef CATKIN_MAKE
-// > For the controller currently operating, received on
-//   "controllerUsedSubscriber"
-void ControllerTabs::poseDataReceivedCallback(const dfall_pkg::ViconData& viconData)
+// > For the data from the motion capture system, received on
+//   "m_poseDataMocapSubscriber"
+void ControllerTabs::poseDataMocapReceivedCallback(const dfall_pkg::ViconData& viconData)
 {
     m_should_search_pose_data_for_object_name_mutex.lock();
     if (m_should_search_pose_data_for_object_name)
     {
-        for(std::vector<dfall_pkg::CrazyflieData>::const_iterator it = viconData.crazyflies.begin(); it != viconData.crazyflies.end(); ++it)
+        for(std::vector<dfall_pkg::FlyingVehicleState>::const_iterator it = viconData.crazyflies.begin(); it != viconData.crazyflies.end(); ++it)
         {
-            dfall_pkg::CrazyflieData pose_in_global_frame = *it;
+            dfall_pkg::FlyingVehicleState pose_in_global_frame = *it;
 
-            if(pose_in_global_frame.crazyflieName == m_object_name_for_emitting_pose_data)
+            if(pose_in_global_frame.vehicleName == m_object_name_for_emitting_pose_data)
             {
 
                 // Convert it into the local frame
@@ -387,15 +422,18 @@ void ControllerTabs::poseDataReceivedCallback(const dfall_pkg::ViconData& viconD
                 // float originZ = (area.zmin + area.zmax) / 2.0;
                 //pose_in_global_frame.z -= originZ;
 
-                emit measuredPoseValueChanged(
-                        pose_in_global_frame.x,
-                        pose_in_global_frame.y,
-                        pose_in_global_frame.z,
-                        pose_in_global_frame.roll,
-                        pose_in_global_frame.pitch,
-                        pose_in_global_frame.yaw,
-                        pose_in_global_frame.occluded
-                    );
+                if (m_shouldEmitPoseDataMocap)
+                {
+                    emit measuredPoseValueChanged(
+                            pose_in_global_frame.x,
+                            pose_in_global_frame.y,
+                            pose_in_global_frame.z,
+                            pose_in_global_frame.roll,
+                            pose_in_global_frame.pitch,
+                            pose_in_global_frame.yaw,
+                            pose_in_global_frame.isValid
+                        );
+                }
             }
         }
     }
@@ -407,6 +445,29 @@ void ControllerTabs::poseDataReceivedCallback(const dfall_pkg::ViconData& viconD
 
 
 
+#ifdef CATKIN_MAKE
+// > For the data from the motion capture system, received on
+//   "m_poseDataOnboardSubscriber"
+void ControllerTabs::poseDataOnboardReceivedCallback(const dfall_pkg::FlyingVehicleState& pose_in_local_frame)
+{
+    if (m_shouldEmitPoseDataOnboard)
+    {
+        emit measuredPoseValueChanged(
+                pose_in_local_frame.x,
+                pose_in_local_frame.y,
+                pose_in_local_frame.z,
+                pose_in_local_frame.roll,
+                pose_in_local_frame.pitch,
+                pose_in_local_frame.yaw,
+                pose_in_local_frame.isValid
+            );
+    }
+}
+#endif
+
+
+
+
 
 //    ----------------------------------------------------------------------------------
 //     CCCC   OOO   N   N  TTTTT  RRRR    OOO   L      L      EEEEE  RRRR
@@ -646,8 +707,11 @@ void ControllerTabs::setAgentIDsToCoordinate(QVector<int> agentIDs , bool should
         }
 
         // SUBSCRIBERS
-        // > For receiving message that the instant controller was changed
+
         m_change_highlighted_controller_mutex.lock();
+        // > For receiving the state estimate from onboard the fying agent
+        m_poseDataOnboardSubscriber = agent_base_nodeHandle.subscribe("CrazyRadio/CFStateEstimate", 3, &ControllerTabs::poseDataOnboardReceivedCallback, this);
+        // > For receiving messages that the instant controller was changed
         controllerUsedSubscriber = agent_base_nodeHandle.subscribe("FlyingAgentClient/ControllerUsed", 1, &ControllerTabs::controllerUsedChangedCallback, this);
         m_change_highlighted_controller_mutex.unlock();
     }
@@ -655,6 +719,7 @@ void ControllerTabs::setAgentIDsToCoordinate(QVector<int> agentIDs , bool should
     {
         // Unsubscribe
         m_change_highlighted_controller_mutex.lock();
+        m_poseDataOnboardSubscriber.shutdown();
         controllerUsedSubscriber.shutdown();
         m_change_highlighted_controller_mutex.unlock();
 
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/coordinatorrow.cpp b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/coordinatorrow.cpp
index eb55555bc6b40e703d2f6ec23c5d8113aea52005..a93a3d8fa82e6f48cd8f51e48b97a8e2cc2e32a9 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/coordinatorrow.cpp
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/coordinatorrow.cpp
@@ -625,7 +625,7 @@ void CoordinatorRow::loadCrazyflieContext()
     }
     // This updating of the radio only needs to be done by the actual agent's node
     //ros::NodeHandle nh("CrazyRadio");
-    //nh.setParam("crazyFlieAddress", m_context.crazyflieAddress);
+    //nh.setParam("crazyflieAddress", m_context.crazyflieAddress);
 #else
     // Set the Crazyflie Name String to be a question mark
     qstr_crazyflie_name.append("?");
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/csonecontrollertab.cpp b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/csonecontrollertab.cpp
index 401093fbe7b2f54dedc52a6e2c33f51e6375457e..37b301055cf06de4b73da0178a9e67f72a8f7d3e 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/csonecontrollertab.cpp
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/csonecontrollertab.cpp
@@ -43,7 +43,7 @@ CsoneControllerTab::CsoneControllerTab(QWidget *parent) :
     ui->setupUi(this);
 
     // Hide the two red frames that are used to indcated
-    // when pose data is occluded
+    // when pose data is NOT valid
     ui->red_frame_position_left->setVisible(false);
     ui->red_frame_position_right->setVisible(false);
 
@@ -632,10 +632,9 @@ void CsoneControllerTab::on_lineEdit_step_duration_editingFinished()
 //    ----------------------------------------------------------------------------------
 
 
-void CsoneControllerTab::setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool occluded)
+void CsoneControllerTab::setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool isValid)
 {
-    // Check if the object is occluded for this data
-    if (!occluded)
+    if (isValid)
     {
         // Ensure the red frames are not visible
         if ( ui->red_frame_position_left->isVisible() )
@@ -645,7 +644,8 @@ void CsoneControllerTab::setMeasuredPose(float x , float y , float z , float rol
     }
     else
     {
-        // Make visible the red frames to indicate occluded
+        // Make visible the red frames to indicate that
+        // measurement is NOT valid
         if ( !(ui->red_frame_position_left->isVisible()) )
             ui->red_frame_position_left->setVisible(true);
         if ( !(ui->red_frame_position_right->isVisible()) )
@@ -653,7 +653,7 @@ void CsoneControllerTab::setMeasuredPose(float x , float y , float z , float rol
     }
 
     // Pass the data through to the plotting function
-    if (!occluded)
+    if (isValid)
     {
         newDataForPerformingStepAndPlotting(x,pitch*RAD2DEG);
     }
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/defaultcontrollertab.cpp b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/defaultcontrollertab.cpp
index 7904b231a353462038bc78e437a2ee8707ce4377..171f3803c72e5430166256b92467d9c0ddae3123 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/defaultcontrollertab.cpp
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/defaultcontrollertab.cpp
@@ -43,7 +43,7 @@ DefaultControllerTab::DefaultControllerTab(QWidget *parent) :
     ui->setupUi(this);
 
     // Hide the two red frames that are used to indcated
-    // when pose data is occluded
+    // when pose data is NOT valid
     ui->red_frame_position_left->setVisible(false);
     ui->red_frame_position_right->setVisible(false);
 
@@ -126,9 +126,9 @@ DefaultControllerTab::~DefaultControllerTab()
 //    ----------------------------------------------------------------------------------
 
 
-void DefaultControllerTab::setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool occluded)
+void DefaultControllerTab::setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool isValid)
 {
-    if (!occluded)
+    if (isValid)
     {
         // INITIALISE A STRING VARIABLE FOR ADDING THE "+"
         QString qstr = "";
@@ -173,7 +173,8 @@ void DefaultControllerTab::setMeasuredPose(float x , float y , float z , float r
     }
     else
     {
-        // Make visible the red frames to indicate occluded
+        // Make visible the red frames to indicate that
+        // measurement is NOT valid
         if ( !(ui->red_frame_position_left->isVisible()) )
             ui->red_frame_position_left->setVisible(true);
         if ( !(ui->red_frame_position_right->isVisible()) )
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/enablecontrollerloadyamlbar.cpp b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/enablecontrollerloadyamlbar.cpp
index 8fc5ca827656558a05149d85dc0206b25868d239..31c95bdbcf0faae262b40e0220adca4cf7eab362 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/enablecontrollerloadyamlbar.cpp
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/enablecontrollerloadyamlbar.cpp
@@ -126,6 +126,24 @@ void EnableControllerLoadYamlBar::showHideController_csone_changed()
     ui->load_yaml_csone_button->setHidden( !(ui->load_yaml_csone_button->isHidden()) );
 }
 
+bool EnableControllerLoadYamlBar::showHide_loadYamlBar_triggered()
+{
+    bool bar_isHidden;
+    if (ui->load_yaml_label->isHidden())
+    {
+        ui->load_yaml_label->show();
+        ui->widget_yamlButtons->show();
+        bar_isHidden = false;
+    }
+    else
+    {
+        ui->load_yaml_label->hide();
+        ui->widget_yamlButtons->hide();
+        bar_isHidden = true;
+    }
+    return bar_isHidden;
+}
+
 
 
 // TEST MOTORS
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/mainwindow.cpp b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/mainwindow.cpp
index c29b832311aee31dfe59804f74483c6db8382c8d..e61244c2865eda33a47440de3c75c0be75fb3a9e 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/mainwindow.cpp
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/mainwindow.cpp
@@ -91,7 +91,7 @@ MainWindow::MainWindow(int argc, char **argv, QWidget *parent) :
         // Hide the coordinator part of the GUI
         ui->customWidget_coordinator->hide();
         // And make the menu item unavailable
-        ui->actionShowHide_Coordinator->setEnabled(false);
+        ui->action_showHide_Coordinator->setEnabled(false);
 
     }
 #endif
@@ -160,7 +160,7 @@ MainWindow::~MainWindow()
 }
 
 
-void MainWindow::on_actionShowHide_Coordinator_triggered()
+void MainWindow::on_action_showHide_Coordinator_triggered()
 {
     //ui->customWidget_enableControllerLoadYamlBar->setEnabled(false);
     if ( ui->customWidget_coordinator->isHidden() )
@@ -168,14 +168,32 @@ void MainWindow::on_actionShowHide_Coordinator_triggered()
         ui->customWidget_coordinator->show();
         ui->coordinator_to_main_panel_vertical_line->show();
         QString qstr = "Hide Coordinator";
-        ui->actionShowHide_Coordinator->setText(qstr);
+        ui->action_showHide_Coordinator->setText(qstr);
     }
     else
     {
         ui->customWidget_coordinator->hide();
         ui->coordinator_to_main_panel_vertical_line->hide();
         QString qstr = "Show Coordinator";
-        ui->actionShowHide_Coordinator->setText(qstr);
+        ui->action_showHide_Coordinator->setText(qstr);
+    }
+}
+
+
+void MainWindow::on_action_showHide_loadYamlBar_triggered()
+{
+    // Trigger the function to show/hide the bar
+    bool bar_isHidden = ui->customWidget_enableControllerLoadYamlBar->showHide_loadYamlBar_triggered();
+    // Update the text of the menu item
+    if ( bar_isHidden )
+    {
+        QString qstr = "Show Yaml Buttons";
+        ui->action_showHide_loadYamlBar->setText(qstr);
+    }
+    else
+    {
+        QString qstr = "Hide Yaml Buttons";
+        ui->action_showHide_loadYamlBar->setText(qstr);
     }
 }
 
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/pickercontrollertab.cpp b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/pickercontrollertab.cpp
index 0375c8f6901d39e108bcc4bff4a0c3fad2808c48..bba7f61dc6726aec38c126a8f18f0e99d8d2f06e 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/pickercontrollertab.cpp
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/pickercontrollertab.cpp
@@ -537,9 +537,9 @@ void PickerControllerTab::setpointChangedCallback(const dfall_pkg::SetpointWithH
 //    ----------------------------------------------------------------------------------
 
 
-void PickerControllerTab::setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool occluded)
+void PickerControllerTab::setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool isValid)
 {
-    if (!occluded)
+    if (isValid)
     {
         // INITIALISE A STRING VARIABLE FOR ADDING THE "+"
         QString qstr = "";
@@ -583,7 +583,8 @@ void PickerControllerTab::setMeasuredPose(float x , float y , float z , float ro
     }
     else
     {
-        // Make visible the red frames to indicate occluded
+        // Make visible the red frames to indicate that
+        // measurement is NOT valid
         if ( !(ui->frame_x_unavailable->isVisible()) )
         {
             ui->frame_x_unavailable  ->setVisible(true);
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/remotecontrollertab.cpp b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/remotecontrollertab.cpp
index 38385a277d9f12e0c75f65616fc3d0fad972e4e5..56d2dc988060445b083327e314ca175dd99f04ad 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/remotecontrollertab.cpp
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/remotecontrollertab.cpp
@@ -43,7 +43,7 @@ RemoteControllerTab::RemoteControllerTab(QWidget *parent) :
     ui->setupUi(this);
 
     // Hide the two red frames that are used to indcated
-    // when pose data is occluded
+    // when pose data is NOT valid
     ui->red_frame_position_left->setVisible(false);
     ui->red_frame_position_right->setVisible(false);
 
@@ -209,25 +209,17 @@ void RemoteControllerTab::on_deactivate_button_clicked()
 
 
 #ifdef CATKIN_MAKE
-void RemoteControllerTab::remoteDataCallback(const dfall_pkg::CrazyflieData& objectData)
+void RemoteControllerTab::remoteDataCallback(const dfall_pkg::FlyingVehicleState& objectData)
 {
-    // Check if the object is occluded
-    if (objectData.occluded)
+    // Check if the object date isValid
+    if (!objectData.isValid)
     {
-
-        // Make visible the red frames to indicate occluded
+        // Make visible the red frames to indicate that
+        // measurement is NOT valid
         if ( !(ui->red_frame_remote->isVisible()) )
+        {
             ui->red_frame_remote->setVisible(true);
-
-//        // Set the column heading label to have a red background
-//        // > IMPORTANT: Set the background auto fill property to true
-//        ui->remote_data_label->setAutoFillBackground(true);
-//        // > Get the pallette currently set for the label
-//        QPalette pal = ui->remote_roll_label->palette();
-//        // > Set the palette property that will change the background
-//        pal.setColor(QPalette::Window, QColor(Qt::red));
-//        // > Update the palette for the label
-//        ui->remote_data_label->setPalette(pal);
+        }
     }
     else
     {
@@ -237,25 +229,18 @@ void RemoteControllerTab::remoteDataCallback(const dfall_pkg::CrazyflieData& obj
         ui->remote_data_yaw  ->setText(QString::number( objectData.yaw   * RAD2DEG, 'f', 1));
         ui->remote_data_z    ->setText(QString::number( objectData.z,               'f', 2));
 
-
         // Ensure the red frames are not visible
         if ( ui->red_frame_remote->isVisible() )
+        {
             ui->red_frame_remote->setVisible(false);
-
-//        // Set the column heading label to have a "normal" background
-//        // > IMPORTANT: Set the background auto fill property to true
-//        ui->remote_data_label->setAutoFillBackground(false);
-//        // > Get the pallette currently set for the roll label
-//        QPalette pal = ui->remote_roll_label->palette();
-//        // > Update the palette for the column heading label
-//        ui->remote_data_label->setPalette(pal);
+        }
     }
 }
 #endif
 
 
 #ifdef CATKIN_MAKE
-void RemoteControllerTab::remoteControlSetpointCallback(const dfall_pkg::CrazyflieData& setpointData)
+void RemoteControllerTab::remoteControlSetpointCallback(const dfall_pkg::FlyingVehicleState& setpointData)
 {
     ui->remote_setpoint_roll ->setText(QString::number( setpointData.roll  * RAD2DEG, 'f', 1));
     ui->remote_setpoint_pitch->setText(QString::number( setpointData.pitch * RAD2DEG, 'f', 1));
@@ -308,9 +293,9 @@ void RemoteControllerTab::publish_custom_button_command(int button_index , QLine
 //    ----------------------------------------------------------------------------------
 
 
-void RemoteControllerTab::setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool occluded)
+void RemoteControllerTab::setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool isValid)
 {
-    if (!occluded)
+    if (isValid)
     {
         // INITIALISE A STRING VARIABLE FOR ADDING THE "+"
         QString qstr = "";
@@ -337,7 +322,8 @@ void RemoteControllerTab::setMeasuredPose(float x , float y , float z , float ro
     }
     else
     {
-        // Make visible the red frames to indicate occluded
+        // Make visible the red frames to indicate that
+        // measurement is NOT valid
         if ( !(ui->red_frame_position_left->isVisible()) )
             ui->red_frame_position_left->setVisible(true);
         if ( !(ui->red_frame_position_right->isVisible()) )
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/rosNodeThread_for_flyingAgentGUI.cpp b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/rosNodeThread_for_flyingAgentGUI.cpp
index 161b03ac9dad95a0aff307511e02adc9d18d9a3a..53d3b54ddd13f0a6288b8cd22bfaaeacc1e68a4a 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/rosNodeThread_for_flyingAgentGUI.cpp
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/rosNodeThread_for_flyingAgentGUI.cpp
@@ -82,7 +82,7 @@ bool rosNodeThread::init()
     ros::Time::init();
     ros::NodeHandle nh("~");
 
-    //m_vicon_subscriber = nh.subscribe("/ViconDataPublisher/ViconData", 100, &rosNodeThread::messageCallback, this);
+    //m_vicon_subscriber = nh.subscribe("/ViconDataPublisher/ViconData", 3, &rosNodeThread::messageCallback, this);
 
     // clients for db services:
     m_read_db_client = nh.serviceClient<CMRead>("/CentralManagerService/Read", false);
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/studentcontrollertab.cpp b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/studentcontrollertab.cpp
index 64207a97bc6be97ef37307dffa36f2ffa8044cad..6896bd7967aed13a4b08e711afe8d55adc9d5988 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/studentcontrollertab.cpp
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/studentcontrollertab.cpp
@@ -43,7 +43,7 @@ StudentControllerTab::StudentControllerTab(QWidget *parent) :
     ui->setupUi(this);
 
     // Hide the two red frames that are used to indcated
-    // when pose data is occluded
+    // when pose data is NOT valid
     ui->red_frame_position_left->setVisible(false);
     ui->red_frame_position_right->setVisible(false);
 
@@ -205,9 +205,9 @@ void StudentControllerTab::on_custom_button_5_clicked()
 //    ----------------------------------------------------------------------------------
 
 
-void StudentControllerTab::setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool occluded)
+void StudentControllerTab::setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool isValid)
 {
-    if (!occluded)
+    if (isValid)
     {
         // INITIALISE A STRING VARIABLE FOR ADDING THE "+"
         QString qstr = "";
@@ -252,7 +252,8 @@ void StudentControllerTab::setMeasuredPose(float x , float y , float z , float r
     }
     else
     {
-        // Make visible the red frames to indicate occluded
+        // Make visible the red frames to indicate that
+        // measurement is NOT valid
         if ( !(ui->red_frame_position_left->isVisible()) )
             ui->red_frame_position_left->setVisible(true);
         if ( !(ui->red_frame_position_right->isVisible()) )
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/templatecontrollertab.cpp b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/templatecontrollertab.cpp
index 24f9fb07fedae441a7de3f94e035e811fc603062..0d963a498f523047b83804710654c1cbbc4636e6 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/templatecontrollertab.cpp
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/templatecontrollertab.cpp
@@ -43,7 +43,7 @@ TemplateControllerTab::TemplateControllerTab(QWidget *parent) :
     ui->setupUi(this);
 
     // Hide the two red frames that are used to indcated
-    // when pose data is occluded
+    // when pose data is NOT valide
     ui->red_frame_position_left->setVisible(false);
     ui->red_frame_position_right->setVisible(false);
 
@@ -191,9 +191,9 @@ void TemplateControllerTab::on_custom_button_3_clicked()
 //    ----------------------------------------------------------------------------------
 
 
-void TemplateControllerTab::setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool occluded)
+void TemplateControllerTab::setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool isValid)
 {
-    if (!occluded)
+    if (isValid)
     {
         // INITIALISE A STRING VARIABLE FOR ADDING THE "+"
         QString qstr = "";
@@ -220,7 +220,8 @@ void TemplateControllerTab::setMeasuredPose(float x , float y , float z , float
     }
     else
     {
-        // Make visible the red frames to indicate occluded
+        // Make visible the red frames to indicate that
+        // measurement is NOT valid
         if ( !(ui->red_frame_position_left->isVisible()) )
             ui->red_frame_position_left->setVisible(true);
         if ( !(ui->red_frame_position_right->isVisible()) )
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/topbanner.cpp b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/topbanner.cpp
index baa47e7b143d517fe4eb0bf530d660786450994d..b2d401b726ffb595e4f2beeafd983efae5b1ab32 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/topbanner.cpp
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/topbanner.cpp
@@ -231,7 +231,7 @@ void TopBanner::loadCrazyflieContext(int ID_to_request_from_database , int emit_
 	}
 	// This updating of the radio only needs to be done by the actual agent's node
 	//ros::NodeHandle nh("CrazyRadio");
-	//nh.setParam("crazyFlieAddress", m_context.crazyflieAddress);
+	//nh.setParam("crazyflieAddress", m_context.crazyflieAddress);
 #else
 	// Set the Crazyflie Name String to be a question mark
 	qstr_crazyflie_name.append("?");
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/tuningcontrollertab.cpp b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/tuningcontrollertab.cpp
index f6578b3217df7ee6b9f04c7250610a5fb9e88b16..04f58ca425e320d586a6c83534c1a8fc483401f9 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/tuningcontrollertab.cpp
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/tuningcontrollertab.cpp
@@ -139,9 +139,9 @@ TuningControllerTab::~TuningControllerTab()
 //    ----------------------------------------------------------------------------------
 
 
-void TuningControllerTab::setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool occluded)
+void TuningControllerTab::setMeasuredPose(float x , float y , float z , float roll , float pitch , float yaw , bool isValid)
 {
-    if (!occluded)
+    if (isValid)
     {
         m_gain_setpoint_mutex.lock();
 
@@ -203,7 +203,8 @@ void TuningControllerTab::setMeasuredPose(float x , float y , float z , float ro
     }
     else
     {
-//        // Make visible the red frames to indicate occluded
+//        // Make visible the red frames to indicate that
+//        // measurement is NOT valid
 //        if ( !(ui->red_frame_position_left->isVisible()) )
 //            ui->red_frame_position_left->setVisible(true);
 //        if ( !(ui->red_frame_position_right->isVisible()) )
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/systemConfigGUI/include/crazyFly.h b/dfall_ws/src/dfall_pkg/GUI_Qt/systemConfigGUI/include/crazyFly.h
index d26b198cdb27abf3cf29ff3a9da7c182b1f68840..008ce939198a1e90be0e8c3dff5c9b70def2f5de 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/systemConfigGUI/include/crazyFly.h
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/systemConfigGUI/include/crazyFly.h
@@ -41,7 +41,7 @@
 
 #ifdef CATKIN_MAKE
 // Include the Crazyflie Data Struct
-#include "dfall_pkg/CrazyflieData.h"
+#include "dfall_pkg/FlyingVehicleState.h"
 // Include other classes
 #include "classes/GetParamtersAndNamespaces.h"
 #else
@@ -63,7 +63,7 @@ using namespace dfall_pkg;
 class crazyFly : public QGraphicsSvgItem
 {
 public:
-    explicit crazyFly(const CrazyflieData* p_crazyfly_msg, QString filename, QGraphicsItem * parent = 0);
+    explicit crazyFly(const FlyingVehicleState* p_crazyfly_msg, QString filename, QGraphicsItem * parent = 0);
     ~crazyFly();
     QRectF boundingRect() const;
 
@@ -71,7 +71,7 @@ public:
                const QStyleOptionGraphicsItem * option,
                QWidget * widget);
 
-    void updateCF(const CrazyflieData* p_crazyfly_msg);
+    void updateCF(const FlyingVehicleState* p_crazyfly_msg);
 
     std::string getName();
 
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/systemConfigGUI/include/mainguiwindow.h b/dfall_ws/src/dfall_pkg/GUI_Qt/systemConfigGUI/include/mainguiwindow.h
index 5d17177cbf0fff1ceafa4143166a2ed65946b9c7..9b4cfae589e46b806c973306b73714ad3d85f4fe 100755
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/systemConfigGUI/include/mainguiwindow.h
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/systemConfigGUI/include/mainguiwindow.h
@@ -206,7 +206,7 @@ private:
 
 #ifdef CATKIN_MAKE
     float getParameterFloat(ros::NodeHandle& nodeHandle, std::string name);
-    void getParameterFloatVector(ros::NodeHandle& nodeHandle, std::string name, std::vector<float>& val, int length);
+    void getParameterFloatVectorKnownLength(ros::NodeHandle& nodeHandle, std::string name, std::vector<float>& val, int length);
     int getParameterInt(ros::NodeHandle& nodeHandle, std::string name);
     void getParameterIntVectorWithKnownLength(ros::NodeHandle& nodeHandle, std::string name, std::vector<int>& val, int length);
     int getParameterIntVectorWithUnknownLength(ros::NodeHandle& nodeHandle, std::string name, std::vector<int>& val);
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/systemConfigGUI/include/rosNodeThread_for_systemConfigGUI.h b/dfall_ws/src/dfall_pkg/GUI_Qt/systemConfigGUI/include/rosNodeThread_for_systemConfigGUI.h
index 1a4f037cd6da979a8966426a1605ef1a639889b0..e74a75eb414e7e1a5e83c39e9c5bbfac19d04bdf 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/systemConfigGUI/include/rosNodeThread_for_systemConfigGUI.h
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/systemConfigGUI/include/rosNodeThread_for_systemConfigGUI.h
@@ -44,7 +44,7 @@
 #include <ros/ros.h>
 #include <ros/network.h>
 #include "dfall_pkg/UnlabeledMarker.h"
-#include "dfall_pkg/CrazyflieData.h"
+#include "dfall_pkg/FlyingVehicleState.h"
 #include "dfall_pkg/ViconData.h"
 
 using namespace dfall_pkg;
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/systemConfigGUI/src/crazyFly.cpp b/dfall_ws/src/dfall_pkg/GUI_Qt/systemConfigGUI/src/crazyFly.cpp
index 5bea8cf634de9e08be35f7f832bcd47ca0c9f8f9..417019b3eed75c7a2d3a68353e5634caa83468d4 100644
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/systemConfigGUI/src/crazyFly.cpp
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/systemConfigGUI/src/crazyFly.cpp
@@ -36,7 +36,7 @@
 #include <QBrush>
 
 
-crazyFly::crazyFly(const CrazyflieData* p_crazyfly_msg, QString filename, QGraphicsItem * parent)
+crazyFly::crazyFly(const FlyingVehicleState* p_crazyfly_msg, QString filename, QGraphicsItem * parent)
     : QGraphicsSvgItem(filename)
 {
     updateCF(p_crazyfly_msg);
@@ -83,11 +83,11 @@ std::string crazyFly::getName()
 }
 
 
-void crazyFly::updateCF(const CrazyflieData* p_crazyfly_msg)
+void crazyFly::updateCF(const FlyingVehicleState* p_crazyfly_msg)
 {
-    m_occluded = p_crazyfly_msg->occluded;
+    m_occluded = !(p_crazyfly_msg->isValid);
 
-    m_name = p_crazyfly_msg->crazyflieName;
+    m_name = p_crazyfly_msg->vehicleName;
     if(!m_occluded)             //if it is occluded, the info we got is useless
     {
         m_x = p_crazyfly_msg->x;
diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/systemConfigGUI/src/mainguiwindow.cpp b/dfall_ws/src/dfall_pkg/GUI_Qt/systemConfigGUI/src/mainguiwindow.cpp
index a93637d1cd0e41b52681f7678764f7596ae011ff..6e249d795bd68bc049307c6ffb1d4d8aada66698 100755
--- a/dfall_ws/src/dfall_pkg/GUI_Qt/systemConfigGUI/src/mainguiwindow.cpp
+++ b/dfall_ws/src/dfall_pkg/GUI_Qt/systemConfigGUI/src/mainguiwindow.cpp
@@ -417,7 +417,7 @@ void MainGUIWindow::updateNewViconData(const ptrToMessage& p_msg) //connected to
         int index_name_found;
         for(int j = 0; j < crazyfly_vector_size_before; j++)
         {
-            if(crazyflies_vector[j]->getName() == p_msg->crazyflies[i].crazyflieName)
+            if(crazyflies_vector[j]->getName() == p_msg->crazyflies[i].vehicleName)
             {
                 name_found = true; // name found. This can only happen once per i-iteration, names are unique
                 index_name_found = j; // index in already existing vector, to update it later (really needed?)
@@ -431,7 +431,7 @@ void MainGUIWindow::updateNewViconData(const ptrToMessage& p_msg) //connected to
         else                    //name not found, newly arrived, add it to the vector
         {
             // now, if name follows our format, put the corresponding number. If not, put the unknown image
-            std::string s = p_msg->crazyflies[i].crazyflieName;
+            std::string s = p_msg->crazyflies[i].vehicleName;
             std::smatch m;
             std::regex e ("CF([0-9]{2})");
 
@@ -473,7 +473,6 @@ void MainGUIWindow::updateNewViconData(const ptrToMessage& p_msg) //connected to
             {
                 if(crazyflies_vector[i]->isOccluded())
                 {
-                    // ROS_INFO("===================OCCLUDED");
                     if(crazyflies_vector[i]->isAddedToScene())
                     {
                         scene->removeItem(crazyflies_vector[i]);
@@ -500,7 +499,7 @@ void MainGUIWindow::updateNewViconData(const ptrToMessage& p_msg) //connected to
         bool name_found = false;
         for(int i = 0; i < p_msg->crazyflies.size(); i++)
         {
-            if(crazyflies_vector[j]->getName() == p_msg->crazyflies[i].crazyflieName)
+            if(crazyflies_vector[j]->getName() == p_msg->crazyflies[i].vehicleName)
             {
                 name_found = true;
             }
diff --git a/dfall_ws/src/dfall_pkg/crazyradio/CrazyRadio.py b/dfall_ws/src/dfall_pkg/crazyradio/CrazyRadio.py
index ae7a2c09405e26ad52d053f69eccb3406264b13b..fb0e3cf53fcea56b250d0eaceb46e3af1fbbee4c 100755
--- a/dfall_ws/src/dfall_pkg/crazyradio/CrazyRadio.py
+++ b/dfall_ws/src/dfall_pkg/crazyradio/CrazyRadio.py
@@ -33,21 +33,32 @@
 #    ----------------------------------------------------------------------------------
 
 
-import roslib; roslib.load_manifest('dfall_pkg')
+# Import the ROS library package
+import roslib
+# Load the "dfall package" manifest for ROS
+roslib.load_manifest('dfall_pkg')
+# Import the ROS-Python package
 import rospy
-from std_msgs.msg import Int32
+# Import standard messages
+from std_msgs.msg  import Int32
+# Import dfall_pkg messages
 from dfall_pkg.msg import ControlCommand
 from dfall_pkg.msg import IntWithHeader
+from dfall_pkg.msg import FlyingVehicleState
+from dfall_pkg.msg import GyroMeasurements
+# Import dfall_pkg services
 from dfall_pkg.srv import IntIntService
 
-
 # General import
 import time, sys
 import struct
 import logging
 
-import rosbag
-from rospkg import RosPack
+# Import the ROS bag package for logging
+#import rosbag
+#from rospkg import RosPack
+
+# Import the ROS standard message types
 from std_msgs.msg import Float32
 from std_msgs.msg import String
 
@@ -62,7 +73,7 @@ from cflib.crtp.crtpstack import CRTPPacket, CRTPPort
 
 import cflib.drivers.crazyradio
 
-# Logging import(*
+# Import the package for logging data back from the Crazyflie
 from cflib.crazyflie.log import LogConfig
 
 # Logging settings
@@ -72,9 +83,25 @@ logging.basicConfig(level=logging.ERROR)
 # CONTROLLER_ANGLE = 1
 # CONTROLLER_RATE = 0
 
-CF_COMMAND_TYPE_MOTORS =  8
-CF_COMMAND_TYPE_RATE   =  9
-CF_COMMAND_TYPE_ANGLE  = 10
+# CF_COMMAND_TYPE_MOTORS =  8
+# CF_COMMAND_TYPE_RATE   =  9
+# CF_COMMAND_TYPE_ANGLE  = 10
+
+CF_ONBOARD_CONTROLLER_MODE_OFF            = 0
+CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE   = 1
+CF_ONBOARD_CONTROLLER_MODE_ANGLE          = 2
+CF_ONBOARD_CONTROLLER_MODE_VELOCITY       = 3
+CF_ONBOARD_CONTROLLER_MODE_POSITION       = 4
+
+# CF_PACKET_DECODER_STOP_TYPE              = 0
+# CF_PACKET_DECODER_VELOCITY_WORLD_TYPE    = 1
+# CF_PACKET_DECODER_Z_DISTANCE_TYEP        = 2
+# CF_PACKET_DECODER_CPPM_EMU_TYPE          = 3
+# CF_PACKET_DECODER_ALT_HOLD_TYPE          = 4
+# CF_PACKET_DECODER_HOVER_TYPE             = 5
+# CF_PACKET_DECODER_FULL_STATE_TYPE        = 6
+# CF_PACKET_DECODER_POSITION_TYPE          = 7
+CF_PACKET_DECODER_DFALL_TYPE             = 8
 
 RAD_TO_DEG = 57.296
 
@@ -99,11 +126,27 @@ CMD_CRAZYFLY_TAKE_OFF   = 11
 CMD_CRAZYFLY_LAND       = 12
 CMD_CRAZYFLY_MOTORS_OFF = 13
 
-rp = RosPack()
-record_file = rp.get_path('dfall_pkg') + '/LoggingOnboard.bag'
-rospy.loginfo('afdsasdfasdfsadfasdfasdfasdfasdfasdfasdf')
-rospy.loginfo(record_file)
-bag = rosbag.Bag(record_file, 'w')
+# Types of flying vehicle states:
+#FLYING_VEHICLE_STATE_TYPE_NONE                        = 0
+#FLYING_VEHICLE_STATE_TYPE_MOCAP_MEASUREMENT           = 1
+FLYING_VEHICLE_STATE_TYPE_CRAZYFLIE_STATE_ESTIMATE    = 2
+#FLYING_VEHICLE_STATE_TYPE_12_STATE_ESTIMATE           = 3
+
+# Flying states
+STATE_MOTORS_OFF     = 1
+#STATE_TAKE_OFF       = 2
+#STATE_FLYING         = 3
+#STATE_LAND           = 4
+#STATE_UNAVAILABLE    = 5
+
+
+
+# Open the ROS bag for logging
+#rp = RosPack()
+#record_file = rp.get_path('dfall_pkg') + '/LoggingOnboard.bag'
+#rospy.loginfo('afdsasdfasdfsadfasdfasdfasdfasdfasdfasdf')
+#rospy.loginfo(record_file)
+#bag = rosbag.Bag(record_file, 'w')
 
 class CrazyRadioClient:
     """
@@ -113,19 +156,27 @@ class CrazyRadioClient:
     """
     def __init__(self):
 
-        # Setpoints to be sent to the CrazyFlie
-        self.roll = 0.0
-        self.pitch = 0.0
-        self.yaw = 0.0
-        self.motor1cmd = 0.0
-        self.motor2cmd = 0.0
-        self.motor3cmd = 0.0
-        self.motor4cmd = 0.0
+        # INITIALISE THE PROPERTIES OF THE OBJECT
+        # > For the status of the radio link
         self._status = DISCONNECTED
+        # > For the addess of the radio link
         self.link_uri = ""
-
-        self.status_pub = rospy.Publisher(node_name + '/CrazyRadioStatus', Int32, queue_size=1)
-        self.FlyingAgentClient_command_pub = rospy.Publisher('FlyingAgentClient/Command', IntWithHeader, queue_size=1)
+        # > For the name of the connected crazyflie
+        self.crazyflie_name = ""
+        # > For keeping track of the "flying state"
+        #   of the "FlyingAgentClient"
+        self._flyingState_of_flyingAgentClient = STATE_MOTORS_OFF
+
+        # > INIIALISE PUBLISHERS
+        # > For informing the network of the status of
+        #   the radio link
+        self.radio_status_publisher = rospy.Publisher(node_name + '/CrazyRadioStatus', Int32, queue_size=1)
+        # > For publishing commands on behalf of the
+        #   FlyingAgentClient, only used for publishing
+        #   "motor off" commands
+        self.flyingAgentClient_command_publisher = rospy.Publisher('FlyingAgentClient/Command', IntWithHeader, queue_size=1)
+
+        # PAUSE SHORTLY FOR THE PUBLISHERS TO BE REGISTERED IN ROS
         time.sleep(1.0)
 
         # Initialize the CrazyFlie and add callbacks
@@ -148,13 +199,16 @@ class CrazyRadioClient:
     def change_status_to(self, new_status):
         print "[CRAZY RADIO] status changed to: %s" % new_status
         self._status = new_status
-        self.status_pub.publish(new_status)
+        self.radio_status_publisher.publish(new_status)
 
     def get_status(self):
         return self._status
 
     def update_link_uri(self):
-        self.link_uri = "radio://" + rospy.get_param("~crazyFlieAddress")
+        self.link_uri = "radio://" + rospy.get_param("~crazyflieAddress")
+
+    def update_crazyflie_name(self):
+        self.crazyflie_name = rospy.get_param("~crazyflieName")
 
     def connect(self):
         # update link from ros params
@@ -167,60 +221,181 @@ class CrazyRadioClient:
 
     def disconnect(self):
         print "[CRAZY RADIO] sending Motors OFF command before disconnecting"
-        self._send_to_commander_motor(0, 0, 0, 0)
+        cf_client._send_to_commander(0, 0, 0, 0, CF_ONBOARD_CONTROLLER_MODE_OFF, 0, CF_ONBOARD_CONTROLLER_MODE_OFF, 0, CF_ONBOARD_CONTROLLER_MODE_OFF, 0, CF_ONBOARD_CONTROLLER_MODE_OFF, 0)
         # change state to motors OFF
         msg = IntWithHeader()
         msg.shouldCheckForAgentID = False
         msg.data = CMD_CRAZYFLY_MOTORS_OFF
-        self.FlyingAgentClient_command_pub.publish(msg)
+        self.flyingAgentClient_command_publisher.publish(msg)
         time.sleep(0.1)
         print "[CRAZY RADIO] Disconnecting from %s" % self.link_uri
         self._cf.close_link()
         self.change_status_to(DISCONNECTED)
 
-    def _data_received_callback(self, timestamp, data, logconf):
-        #print "log of stabilizer and battery: [%d][%s]: %s" % (timestamp, logconf.name, data)
+
+
+    def _data_received_battery_callback(self, timestamp, data, logconf):
+        # Initialise the variable for the data
         batteryVolt = Float32()
-        stabilizerYaw = Float32()
-        stabilizerPitch = Float32()
-        stabilizerRoll = Float32()
+        # Retrieve the values from the data packet received
         batteryVolt.data = data["pm.vbat"]
-        stabilizerYaw.data = data["stabilizer.yaw"]
-        stabilizerPitch.data = data["stabilizer.pitch"]
-        bag.write('batteryVoltage', batteryVolt)
-        bag.write('stabilizerYaw', stabilizerYaw)
-        bag.write('stabilizerPitch', stabilizerPitch)
-        bag.write('stabilizerRoll', stabilizerRoll)
-
-        #publish battery voltage for GUI
-        #cfbattery_pub.publish(std_msgs.Float32(batteryVolt.data))
-        # print "batteryVolt: %s" % batteryVolt
+
+        # Write data to the ROS bag
+        #bag.write('batteryVoltage', batteryVolt)
+
+        # Print out one value for DEBUGGING
+        #print "[CRAZY RADIO] DEBUGGING, received pm.vbat = %f" % batteryVolt.data
+
+        # Publish the battery voltage
         cfbattery_pub.publish(batteryVolt)
 
 
 
+    def _data_received_stateEstimate_callback(self, timestamp, data, logconf):
+        # Perform safety check if required
+        if (isEnabled_strictSafety):
+            # Estimate the height at the next measurement
+            height_at_next_measurement = data["stateEstimateZ.z"] / 1000.0 + (cfStateEstimate_polling_period / 1000.0) * (data["stateEstimateZ.vz"] / 1000.0)
+            # Turn-off if too high
+            if (height_at_next_measurement > maxHeight_for_strictSafety_meters):
+                # Publish a motors OFF command
+                msg = IntWithHeader()
+                msg.shouldCheckForAgentID = False
+                msg.data = CMD_CRAZYFLY_MOTORS_OFF
+                self.flyingAgentClient_command_publisher.publish(msg)
+                # Inform the user
+                rospy.logerr("[CRAZY RADIO] Height safety check failed, measured = %f, max allowed = %f" % (height_at_next_measurement, maxHeight_for_strictSafety_meters))
+
+        # Initialise the variable for the flying vehicle state
+        cfStateEstimate = FlyingVehicleState()
+
+        # Retrieve the values from the data packet received
+        # > (x,y,z) positions
+        cfStateEstimate.x  = data["stateEstimateZ.x"] / 1000.0
+        cfStateEstimate.y  = data["stateEstimateZ.y"] / 1000.0
+        cfStateEstimate.z  = data["stateEstimateZ.z"] / 1000.0
+        # > (x,y,z) velocities
+        cfStateEstimate.vx = data["stateEstimateZ.vx"] / 1000.0
+        cfStateEstimate.vy = data["stateEstimateZ.vy"] / 1000.0
+        cfStateEstimate.vz = data["stateEstimateZ.vz"] / 1000.0
+        # > (x,y,z) accelerations
+        #cfStateEstimate.ax = data["stateEstimateZ.ax"] / 1000.0
+        #cfStateEstimate.ay = data["stateEstimateZ.ay"] / 1000.0
+        #cfStateEstimate.az = data["stateEstimateZ.az"] / 1000.0
+        # > (roll,pitch,yaw) angles
+        cfStateEstimate.roll  =  data["stateEstimateZ.roll"]  / 1000.0
+        cfStateEstimate.pitch = -data["stateEstimateZ.pitch"] / 1000.0
+        cfStateEstimate.yaw   =  data["stateEstimateZ.yaw"]   / 1000.0
+        # > (roll,pitch,yaw) anglular rates (direct from gryo)
+        cfStateEstimate.rollRate  =  data["stateEstimateZ.rateRoll"]  / 1000.0
+        cfStateEstimate.pitchRate = -data["stateEstimateZ.ratePitch"] / 1000.0
+        cfStateEstimate.yawRate   =  data["stateEstimateZ.rateYaw"]   / 1000.0
+
+        # Print out one value for DEBUGGING
+        #print "[CRAZY RADIO] received (z,vz)  = ( %6.3f , %6.3f )" %( cfStateEstimate.z , cfStateEstimate.vz )
+        #print "[CRAZY RADIO] received (r,p,y) = ( %6.3f , %6.3f , %6.3f )" %( cfStateEstimate.roll*RAD_TO_DEG , cfStateEstimate.pitch*RAD_TO_DEG , cfStateEstimate.yaw*RAD_TO_DEG )
+
+        # Fill in the remaining details:
+        # > For the type
+        cfStateEstimate.type = FLYING_VEHICLE_STATE_TYPE_CRAZYFLIE_STATE_ESTIMATE
+        # > For the name
+        cfStateEstimate.vehicleName = self.crazyflie_name
+        # > For the validity flag
+        cfStateEstimate.isValid = True
+        # > For the acquiring time
+        cfStateEstimate.acquiringTime = 0.0
+
+        # Publish the state estimate
+        cfstateEstimate_pub.publish(cfStateEstimate)
+
+
+
+        # Initialise the variable for the gyroscope data
+        gyroMeasurements = GyroMeasurements()
+
+        # Retrieve the values from the data packet received
+        # > (roll,pitch,yaw) anglular rates (direct from gryo)
+        gyroMeasurements.rollrate  =  data["stateEstimateZ.rateRoll"] / 1000.0
+        gyroMeasurements.pitchrate = -data["stateEstimateZ.ratePitch"] / 1000.0
+        gyroMeasurements.yawrate   =  data["stateEstimateZ.rateYaw"] / 1000.0
+
+        # Fill in the name
+        gyroMeasurements.vehicleName = self.crazyflie_name
+
+        # Print out one value for DEBUGGING
+        #print "[CRAZY RADIO] gyro (r,p,y)     = ( %6.3f , %6.3f , %6.3f )" %( gyroMeasurements.rollrate*RAD_TO_DEG , gyroMeasurements.pitchrate*RAD_TO_DEG , gyroMeasurements.yawrate*RAD_TO_DEG )
+        
+        # Publish the gyroscope measurements
+        cfgyroMeasurements_pub.publish(gyroMeasurements)
+
+
+
     def _logging_error(self, logconf, msg):
         print "[CRAZY RADIO] Error when logging %s" % logconf.name
 
-    # def _init_logging(self):
+
 
     def _start_logging(self):
-        self.logconf = LogConfig("LoggingTest", battery_polling_period) # second variable is period in ms
-        self.logconf.add_variable("stabilizer.roll", "float");
-        self.logconf.add_variable("stabilizer.pitch", "float");
-        self.logconf.add_variable("stabilizer.yaw", "float");
-        self.logconf.add_variable("pm.vbat", "float");
-
-        self._cf.log.add_config(self.logconf)
-        if self.logconf.valid:
-            self.logconf.data_received_cb.add_callback(self._data_received_callback)
-            self.logconf.error_cb.add_callback(self._logging_error)
-            print "[CRAZY RADIO] logconf valid"
+
+        # A "LOGGING GROUP" FOR THE BATTERY VOLTAGE:
+
+        # Initialise a log config object
+        self.logconf_battery = LogConfig("LoggingBattery", period_in_ms=battery_polling_period)
+        # Add the varaibles to be logged
+        self.logconf_battery.add_variable("pm.vbat", "float");
+        # Add the log config to the crazyflie object
+        self._cf.log.add_config(self.logconf_battery)
+        if self.logconf_battery.valid:
+            self.logconf_battery.data_received_cb.add_callback(self._data_received_battery_callback)
+            self.logconf_battery.error_cb.add_callback(self._logging_error)
+            print "[CRAZY RADIO] The log config for the battery voltage is valid"
+        else:
+            print "[CRAZY RADIO] The log config for the battery voltage is invalid"
+
+        # A "LOGGING GROUP" FOR THE STATE ESTIMATE:
+
+        # Initialise a log config object
+        self.logconf_stateEstimate = LogConfig("LoggingStateEstimate", period_in_ms=cfStateEstimate_polling_period)
+        # Add the varaibles to be logged
+        # > (x,y,z) positions
+        self.logconf_stateEstimate.add_variable("stateEstimateZ.x",    "int16_t");
+        self.logconf_stateEstimate.add_variable("stateEstimateZ.y",    "int16_t");
+        self.logconf_stateEstimate.add_variable("stateEstimateZ.z",    "int16_t");
+        # > (x,y,z) velocities
+        self.logconf_stateEstimate.add_variable("stateEstimateZ.vx",   "int16_t");
+        self.logconf_stateEstimate.add_variable("stateEstimateZ.vy",   "int16_t");
+        self.logconf_stateEstimate.add_variable("stateEstimateZ.vz",   "int16_t");
+        # > (x,y,z) accelerations
+        #self.logconf_stateEstimate.add_variable("stateEstimateZ.ax",   "int16_t");
+        #self.logconf_stateEstimate.add_variable("stateEstimateZ.ay",   "int16_t");
+        #self.logconf_stateEstimate.add_variable("stateEstimateZ.az",   "int16_t");
+        # > (roll,pitch,yaw) angles
+        self.logconf_stateEstimate.add_variable("stateEstimateZ.roll",        "int16_t");
+        self.logconf_stateEstimate.add_variable("stateEstimateZ.pitch",       "int16_t");
+        self.logconf_stateEstimate.add_variable("stateEstimateZ.yaw",         "int16_t");
+        # > (roll,pitch,yaw) anglular rates (direct from gryo)
+        self.logconf_stateEstimate.add_variable("stateEstimateZ.rateRoll",    "int16_t");
+        self.logconf_stateEstimate.add_variable("stateEstimateZ.ratePitch",   "int16_t");
+        self.logconf_stateEstimate.add_variable("stateEstimateZ.rateYaw",     "int16_t");
+        # Add the log config to the crazyflie object
+        self._cf.log.add_config(self.logconf_stateEstimate)
+        if self.logconf_stateEstimate.valid:
+            self.logconf_stateEstimate.data_received_cb.add_callback(self._data_received_stateEstimate_callback)
+            self.logconf_stateEstimate.error_cb.add_callback(self._logging_error)
+            print "[CRAZY RADIO] The log config for the state estimate is valid"
         else:
-            print "[CRAZY RADIO] logconf invalid"
+            print "[CRAZY RADIO] The log config for the state estimate is invalid"
+
+
+        # START THE LOGGING FOR ALL THE "LOGGING GROUPS" ADDED
+        # > For the battery voltage
+        self.logconf_battery.start()
+        print "[CRAZY RADIO] Started the log config for the battery voltage"
+        # > For the state estimate
+        self.logconf_stateEstimate.start()
+        print "[CRAZY RADIO] Started the log config for the state estimate"
+
 
-        self.logconf.start()
-        print "[CRAZY RADIO] logconf start"
 
     def _connected(self, link_uri):
         """
@@ -232,7 +407,7 @@ class CrazyRadioClient:
         msg = IntWithHeader()
         msg.shouldCheckForAgentID = False
         msg.data = CMD_CRAZYFLY_MOTORS_OFF
-        cf_client.FlyingAgentClient_command_pub.publish(msg)
+        cf_client.flyingAgentClient_command_publisher.publish(msg)
 
         rospy.loginfo("[CRAZY RADIO] Connection to %s successful: " % link_uri)
         # Config for Logging
@@ -240,7 +415,6 @@ class CrazyRadioClient:
 
 
 
-
     def _connection_failed(self, link_uri, msg):
         """Callback when connection initial connection fails (i.e no Crazyflie
         at the specified address)"""
@@ -258,40 +432,100 @@ class CrazyRadioClient:
         self.change_status_to(DISCONNECTED)
         rospy.logwarn("[CRAZY RADIO] Disconnected from %s" % link_uri)
 
-        # change state to motors OFF
+        # CHANGE THE STATE TO "MOTORS OFF"
         msg = IntWithHeader()
         msg.shouldCheckForAgentID = False
         msg.data = CMD_CRAZYFLY_MOTORS_OFF
-        self.FlyingAgentClient_command_pub.publish(msg)
-
-        self.logconf.stop()
-        rospy.loginfo("logconf stopped")
-        self.logconf.delete()
-        rospy.loginfo("logconf deleted")
-
-    def _send_to_commander_motor(self, cmd1, cmd2, cmd3, cmd4):
+        self.flyingAgentClient_command_publisher.publish(msg)
+
+        # STOP AND DELETE ALL THE "LOGGING GROUPS"
+        # > For the battery voltage
+        self.logconf_battery.stop()
+        rospy.loginfo("The log config for the battery voltage was stopped")
+        self.logconf_battery.delete()
+        rospy.loginfo("The log config for the battery voltage was deleted")
+        # > For the state estimate
+        self.logconf_stateEstimate.stop()
+        rospy.loginfo("The log config for the state estimate was stopped")
+        self.logconf_stateEstimate.delete()
+        rospy.loginfo("The log config for the state estimate was deleted")
+
+
+
+    def _send_to_commander(self, cmd1, cmd2, cmd3, cmd4, x_mode , x_value, y_mode, y_value, z_mode, z_value, yaw_mode, yaw_value ):
+        # CONSTRUCT THE CONDENSED 16-BIT INTEGER THAT ENCODES
+        # THE REQUESTED {x,y,z,yaw} MODES
+        # > Each mode is encoded using 3 bits, stacked together as follows:
+        # ---------------------------------------------------------------
+        # |BIT   | 15 14 13 12 | 11 10  9 | 8  7  6 | 5  4  3 | 2  1  0 |
+        # |DESC. | free bits   | yaw_mode | z_mode  | y_mode  | x_mode  |
+        # ---------------------------------------------------------------
+        # > The python bitwise operators "<<" and "|" are used
+        #   to construct the 16-bit "cumulative" mode
+        modes_as_uint16 = (yaw_mode << 9) | (z_mode << 6) | (y_mode << 3) | (x_mode << 0)
+        #
+        # > To test the behaviour of this command, enter the following
+        #   into a python shell:
+        # >>> modes = (4 << 9) | (2 << 6) | (1 << 3) | (7 << 0)
+        # >>> "{0:b}".format(modes)
+        # > The second line should display the result '100010001111'
+        #   which encodes:
+        # --------------------------------------------------
+        # |BIT    | 11 10  9 | 8  7  6 | 5  4  3 | 2  1  0 |
+        # |O or 1 |  1  0  0 | 0  1  0 | 0  0  1 | 1  1  1 |
+        # |Value  | mode=4   | mode=2  | mode=1  | mode=7  |
+        # --------------------------------------------------
+        #
+        # > To extract a mode, an example code snippet is:
+        # >>> yaw_mode = (modes >> 9) & 7
+        # > The bitwise & operator with the number 7 serves to
+        #   select only the right-hand most 3 bits of (modes >> 9),
+        #   the last 3 bits of the variable modes after is has been
+        #   shifted to the right by 9 bits.
+        # > This syntax works in both python and plain-c
+
+        
+
+        # CONSTRUCT AND SEND THE COMMANDER PACKET
+        # > See hints at end of this file for an explanation
+        #   of the struct packing format, i.e., of '<HHHHHffff'
         pk = CRTPPacket()
         pk.port = CRTPPort.COMMANDER_GENERIC
-        pk.data = struct.pack('<BHHHH', CF_COMMAND_TYPE_MOTORS, cmd1, cmd2, cmd3, cmd4)
+        pk.data = struct.pack('<BHHHHHffff', CF_PACKET_DECODER_DFALL_TYPE, modes_as_uint16, cmd1, cmd2, cmd3, cmd4, x_value, y_value, z_value, yaw_value)
         self._cf.send_packet(pk)
 
-    def _send_to_commander_rate(self, cmd1, cmd2, cmd3, cmd4, roll_rate, pitch_rate, yaw_rate):
-        pk = CRTPPacket()
-        pk.port = CRTPPort.COMMANDER_GENERIC
-        pk.data = struct.pack('<BHHHHfff', CF_COMMAND_TYPE_RATE, cmd1, cmd2, cmd3, cmd4, roll_rate * RAD_TO_DEG, pitch_rate * RAD_TO_DEG, yaw_rate * RAD_TO_DEG)
-        self._cf.send_packet(pk)
+        # NOTES ON THE PACKING OF THE "pk.data" STRUCT
+        # > The "B" is the decoder type packed into 1 btye
+        # > The first "H" is the condense 2-byte integer
+        #   of four onboard controller modes
+        # > The next four "H" are the 2-byte per motor commands
+        # > The four "f" are the setpoints for each onboard controller
+        # > Hence the total size of the data is:
+        #   sizs('HHHHHffff') = 5*2bytes + 4*4bytes = 26bytes
+        # > This leaves 3 spare bytes before reaching the maximum
+        #   of 29 bytes as specified in the comment below
+
+        # DESCRIPTION OF THE CRAZYFLIE PACKETS
+        # > This is taken directly from the file
+        #   "crtp_commander_generic.c" in the
+        #   Crazyflie firmware
+        #
+        # The generic commander format contains a packet type and data that has to be
+        # decoded into a setpoint_t structure. The aim is to make it future-proof
+        # by easily allowing the addition of new packets for future use cases.
+        #
+        # The packet format is:
+        # +------+==========================+
+        # | TYPE |     DATA                 |
+        # +------+==========================+
+        #
+        # The type is defined bellow together with a decoder function that should take
+        # the data buffer in and fill up a setpoint_t structure.
+        # The maximum data size is 29 bytes.
+
+
 
-    def _send_to_commander_angle(self, cmd1, cmd2, cmd3, cmd4, roll, pitch, yaw):
-        pk = CRTPPacket()
-        pk.port = CRTPPort.COMMANDER_GENERIC
-        pk.data = struct.pack('<BHHHHfff', CF_COMMAND_TYPE_ANGLE, cmd1, cmd2, cmd3, cmd4, roll * RAD_TO_DEG, pitch * RAD_TO_DEG, yaw * RAD_TO_DEG)
-        self._cf.send_packet(pk)
 
-    # def _send_to_commander(self,roll, pitch, yaw, thrust, cmd1, cmd2, cmd3, cmd4, mode):
-    #     pk = CRTPPacket()
-    #     pk.port = CRTPPort.COMMANDER
-    #     pk.data = struct.pack('<fffHHHHHH', roll * RAD_TO_DEG, pitch * RAD_TO_DEG, yaw * RAD_TO_DEG, thrust, cmd1, cmd2, cmd3, cmd4, mode)
-    #     self._cf.send_packet(pk)
 
     def crazyRadioCommandCallback(self, msg):
         """Callback to tell CrazyRadio to reconnect"""
@@ -317,10 +551,10 @@ class CrazyRadioClient:
                     self.connect()
                 elif self.get_status() == CONNECTING:
                     print "[CRAZY RADIO] received command to CONNECT (current status is CONNECTING)"
-                    #self.status_pub.publish(CONNECTING)
+                    #self.radio_status_publisher.publish(CONNECTING)
                 elif self.get_status() == CONNECTED:
                     print "[CRAZY RADIO] received command to CONNECT (current status is CONNECTED)"
-                    #self.status_pub.publish(CONNECTED)
+                    #self.radio_status_publisher.publish(CONNECTED)
 
             elif msg.data == CMD_DISCONNECT:
                 if self.get_status() == CONNECTED:
@@ -328,10 +562,10 @@ class CrazyRadioClient:
                     self.disconnect()
                 elif self.get_status() == CONNECTING:
                     print "[CRAZY RADIO] received command to DISCONNECT (current status is CONNECTING)"
-                    #self.status_pub.publish(CONNECTING)
+                    #self.radio_status_publisher.publish(CONNECTING)
                 elif self.get_status() == DISCONNECTED:
                     print "[CRAZY RADIO] received command to DISCONNECT (current status is DISCONNECTED)"
-                    #self.status_pub.publish(DISCONNECTED)
+                    #self.radio_status_publisher.publish(DISCONNECTED)
 
 
 
@@ -342,23 +576,148 @@ class CrazyRadioClient:
 
 
 
+    def flyingStateCallback(self, msg):
+        """Callback for keeping track of the flying state"""
 
-def controlCommandCallback(data):
-    """Callback for controller actions"""
-    #rospy.loginfo("controller callback : %s, %s, %s", data.roll, data.pitch, data.yaw)
+        # > This is used to know when to reset the Crazyflie's
+        #   onboard Kalman filter.
+        # > The filter is reset when the state changes from
+        #   "motors off" to something else
+        # > This is required because the onboard state estimate
+        #   tends to drift when the Crazyflie stays on the ground
+        #   for an even a short amount of time
 
-    #cmd1..4 must not be 0, as crazyflie onboard controller resets!
-    #pitch and yaw are inverted on crazyflie controller
-    if data.onboardControllerType == CF_COMMAND_TYPE_MOTORS:
-        cf_client._send_to_commander_motor(data.motorCmd1, data.motorCmd2, data.motorCmd3, data.motorCmd4)
+        # The data in this message is always relevant because
+        # of the namespace of the message, hence there is no
+        # need to check the header.
 
-    elif data.onboardControllerType == CF_COMMAND_TYPE_RATE:
-        cf_client._send_to_commander_rate(data.motorCmd1, data.motorCmd2, data.motorCmd3, data.motorCmd4, data.roll, -data.pitch, -data.yaw)
+        # Get the new state from the message
+        new_flying_state = msg.data
+
+        # Get the current flying state into a local variable
+        current_flying_state = self._flyingState_of_flyingAgentClient
+
+        # Only consider the command if it is relevant
+        if ( \
+            (current_flying_state==STATE_MOTORS_OFF)
+            and \
+            not(new_flying_state==STATE_MOTORS_OFF) \
+        ):
+            # Call the CrazyRadio function that sets the
+            # paramter for reseting the onboard estimate
+            self._cf.param.set_value("kalman.resetEstimation", "1")
+            # Inform the user
+            #print "[CRAZY RADIO] reqested the Crazyflie to reset the onboard estimate"
 
-    elif data.onboardControllerType == CF_COMMAND_TYPE_ANGLE:
-        cf_client._send_to_commander_angle(data.motorCmd1, data.motorCmd2, data.motorCmd3, data.motorCmd4, data.roll, -data.pitch, -data.yaw)
-        # cf_client._send_to_commander(data.roll, -data.pitch, -data.yaw, 0, data.motorCmd1, data.motorCmd2, data.motorCmd3, data.motorCmd4, data.onboardControllerType)
+        # Update the class variable for keeping track of the
+        # current state
+        self._flyingState_of_flyingAgentClient = new_flying_state
+
+
+# END OF: class CrazyRadioClient:
+# ============================= #
+
+
+# ============================= #
+# CALL BACK WHEN A MESSAGE IS RECEIVED ON:
+# "FlyingAgentClient/ControlCommand"
+def controlCommandCallback(data):
+    """Callback for controller actions"""
 
+    # NOTE: cmd{1,...,4} must NOT be all 0, as this causes the
+    #       crazyflie onboard controller to reset!
+    # TODO: check if this note is still true!
+
+    # CHECK THE X-CONTROLLER MODE
+    # > Because the pitch is inverted on the crazyflie
+    # > And because the angles need to be converted to degrees
+    if ( \
+        (data.xControllerMode==CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE) \
+        or \
+        (data.xControllerMode==CF_ONBOARD_CONTROLLER_MODE_ANGLE) \
+    ):
+        # Negate the setpoint and convert to degrees
+        x_controller_setpoint = -data.xControllerSetpoint * RAD_TO_DEG;
+    #
+    else:
+        # Take the setpoint as is
+        x_controller_setpoint = data.xControllerSetpoint;
+
+    # CHECK THE Y-CONTROLLER MODE
+    # > Because the pitch is inverted on the crazyflie
+    # > And because the angles need to be converted to degrees
+    if ( \
+        (data.yControllerMode==CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE) \
+        or \
+        (data.yControllerMode==CF_ONBOARD_CONTROLLER_MODE_ANGLE) \
+    ):
+        # Convert the setpoint to degrees
+        y_controller_setpoint = data.yControllerSetpoint * RAD_TO_DEG;
+    #
+    else:
+        # Take the setpoint as is
+        y_controller_setpoint = data.yControllerSetpoint;
+
+    # CHECK THE Z-CONTROLLER MODE
+    # > Because the angle and angular rate modes are not allowed
+    if ( \
+        (data.zControllerMode==CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE) \
+        or \
+        (data.zControllerMode==CF_ONBOARD_CONTROLLER_MODE_ANGLE) \
+    ):
+        # Turn the z-controller off and inform the user
+        rospy.logerr("[CRAZY RADIO] z controller requested disallowed mode, now turning OFF the z-controller.")
+        z_controller_mode     = CF_ONBOARD_CONTROLLER_MODE_OFF;
+        z_controller_setpoint = 0.0;
+    #
+    else:
+        # Take the mode and setpoint as is
+        z_controller_mode     = data.zControllerMode;
+        z_controller_setpoint = data.zControllerSetpoint;
+
+    # CHECK THE YAW-CONTROLLER MODE
+    # > Because the yaw is inverted on the crazyflie
+    # > And because the angles need to be converted to degrees
+    # > And because the position and velocity modes are not allowed
+    if ( \
+        (data.yawControllerMode==CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE) \
+        or \
+        (data.yawControllerMode==CF_ONBOARD_CONTROLLER_MODE_ANGLE) \
+    ):
+        # Negate the setpoint and convert to degrees
+        yaw_controller_mode     = data.yawControllerMode;
+        yaw_controller_setpoint = data.yawControllerSetpoint * RAD_TO_DEG;
+    #
+    elif (data.yawControllerMode==CF_ONBOARD_CONTROLLER_MODE_OFF):
+        # Set the setpoint to zero
+        yaw_controller_mode     = data.yawControllerMode;
+        yaw_controller_setpoint = 0.0;
+    #
+    else:
+        # Set the yaw-controller  to zero angle setpoint and inform the user
+        rospy.logerr("[CRAZY RADIO] yaw controller requested disallowed mode, now turning to ANGULAR_RATE mode with zero setpoint.")
+        yaw_controller_mode     = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+        yaw_controller_setpoint = 0.0;
+
+
+    # PASS THE COMMAND TO THE SENDING FUNCTION
+    cf_client._send_to_commander(
+        data.motorCmd1,
+        data.motorCmd2,
+        data.motorCmd3,
+        data.motorCmd4,
+        data.xControllerMode,
+        x_controller_setpoint,
+        data.yControllerMode,
+        y_controller_setpoint,
+        z_controller_mode,
+        z_controller_setpoint,
+        yaw_controller_mode,
+        yaw_controller_setpoint,
+        )
+
+# END OF: def controlCommandCallback(data):
+# ============================= #
 
 
 
@@ -376,20 +735,37 @@ if __name__ == '__main__':
     ros_namespace = rospy.get_namespace()
 
 
-    # Initialize the low-level drivers (don't list the debug drivers)
+
+    # Initialize the low-level drivers
+    # > with the option set to NOT list the debug drivers)
     cflib.crtp.init_drivers(enable_debug_driver=False)
 
-    #wait until address parameter is set by FlyingAgentClient
-    while not rospy.has_param("~crazyFlieAddress"):
+    # Wait until address parameter is set by FlyingAgentClient
+    while not rospy.has_param("~crazyflieAddress"):
+        time.sleep(0.05)
+
+    # Wait until name parameter is set by FlyingAgentClient
+    # > Should be set at the same timie as the address
+    while not rospy.has_param("~crazyflieName"):
         time.sleep(0.05)
 
-    #use this following two lines to connect without data from CentralManager
+    # Use the following lines of code to connect without data
+    # from the "Central Manager":
     # radio_address = "radio://0/72/2M"
     # rospy.loginfo("manual address loaded")
 
     # Fetch the YAML paramter "battery polling period"
     global battery_polling_period
-    battery_polling_period = rospy.get_param(ros_namespace + "/CrazyRadio/battery_polling_period")
+    battery_polling_period = rospy.get_param(ros_namespace + "CrazyRadio/CrazyRadioCopyOfBatteryMonitor/battery_polling_period")
+
+    global cfStateEstimate_polling_period
+    cfStateEstimate_polling_period = rospy.get_param(ros_namespace + "CrazyRadio/CrazyRadioConfig/cfStateEstimate_polling_period")
+
+    global isEnabled_strictSafety
+    isEnabled_strictSafety = rospy.get_param(ros_namespace + "CrazyRadio/CrazyRadioConfig/isEnabled_strictSafety")
+
+    global maxHeight_for_strictSafety_meters
+    maxHeight_for_strictSafety_meters = rospy.get_param(ros_namespace + "CrazyRadio/CrazyRadioConfig/maxHeight_for_strictSafety_meters")
 
     # Fetch the YAML paramter "agentID" and "coordID"
     global m_agentID
@@ -398,18 +774,19 @@ if __name__ == '__main__':
     # Convert the coordinator ID to a zero-padded string
     coordID_as_string = format(coordID, '03')
 
-
     # Initialise a publisher for the battery voltage
     global cfbattery_pub
     cfbattery_pub = rospy.Publisher(node_name + '/CFBattery', Float32, queue_size=10)
 
+    # Initialise a publisher for the state estimate
+    global cfstateEstimate_pub
+    cfstateEstimate_pub = rospy.Publisher(node_name + '/CFStateEstimate', FlyingVehicleState, queue_size=10)
+
     # Initialise a "CrazyRadioClient" type variable that handles
     # all communication over the CrazyRadio
     global cf_client
     cf_client = CrazyRadioClient()
 
-    print "[CRAZY RADIO] DEBUG 2"
-
     # Subscribe to the commands for when to (dis-)connect the
     # CrazyRadio connection with the Crazyflie
     # > For the radio commands from the FlyingAgentClient of this agent
@@ -420,30 +797,204 @@ if __name__ == '__main__':
 
     # Advertise a Serice for the current status
     # of the Crazy Radio connect
-    s = rospy.Service(node_name + "/getCurrentCrazyRadioStatus", IntIntService , cf_client.getCurrentCrazyRadioStatusServiceCallback)
+    getCurrentCrazyRadioStatusService = rospy.Service(node_name + "/getCurrentCrazyRadioStatus", IntIntService , cf_client.getCurrentCrazyRadioStatusServiceCallback)
 
 
+    # Subscribe to the "flying state" of the FlyingAgentClient
+    # > This is used to determine when to reset the Crazyflie's
+    #   onboard Kalman filter
+    rospy.Subscriber("FlyingAgentClient/FlyingState", Int32, cf_client.flyingStateCallback)
 
+    # Sleep briefly to allow everything to start-up
     time.sleep(1.0)
 
+
+
+    # Subscribe to the "control commands" that are to be sent
+    # to the Crazyflie, i.e., commands of motor thrust and
+    # setpoints for the onboard controllers
     rospy.Subscriber("FlyingAgentClient/ControlCommand", ControlCommand, controlCommandCallback)
 
+
+
+    # Print out some information to the user.
     print "[CRAZY RADIO] Node READY :-)"
+
+    # Enter an endless while loop to keep the node alive.
     rospy.spin()
+
+
+
+    # SHUT DOWN THE NODE IF THE "ros::spin" IS CANCELLED
+
+    # Inform the user
     rospy.loginfo("[CRAZY RADIO] Turning off crazyflie")
 
-    cf_client._send_to_commander_motor(0, 0, 0, 0)
-    # change state to motors OFF
+    # Send the motors off command
+    cf_client._send_to_commander(0, 0, 0, 0, CF_ONBOARD_CONTROLLER_MODE_OFF, 0, CF_ONBOARD_CONTROLLER_MODE_OFF, 0, CF_ONBOARD_CONTROLLER_MODE_OFF, 0, CF_ONBOARD_CONTROLLER_MODE_OFF, 0)
+
+    # Send a "Motors OFF" on behalf of the "FlyingAgentClient"
+    # > This serves the purpose of changing the flying state
+    #   to the "Motors OFF" state
     msg = IntWithHeader()
     msg.shouldCheckForAgentID = False
     msg.data = CMD_CRAZYFLY_MOTORS_OFF
-    cf_client.FlyingAgentClient_command_pub.publish(msg)
-    #wait for client to send its commands
+    cf_client.flyingAgentClient_command_publisher.publish(msg)
+
+    # Allow some time for the command to be sent
     time.sleep(1.0)
 
 
-    bag.close()
-    rospy.loginfo("[CRAZY RADIO] bag closed")
 
+    # Close the ROS loggin bag
+    #bag.close()
+    #rospy.loginfo("[CRAZY RADIO] Logging bag closed")
+
+    # Close the CrazyRadio link
     cf_client._cf.close_link()
     rospy.loginfo("[CRAZY RADIO] Link closed")
+
+
+# ===================================== #
+# HINTS FOR THE FORMAT STRING USED IN
+# THE "struct.pack(...)" COMMANDS FOR
+# CONSTRUCTING THE DATA PACKAGES SENT
+# TO THE CRAZYFLIE
+#
+# COPIED FROM:
+# https://docs.python.org/3/library/struct.html#format-characters
+#
+# FORMAT CHARACTERS:
+# Format characters have the following meaning; the conversion
+# between C and Python values should be obvious given their
+# types. The ‘Standard size’ column refers to the size of the
+# packed value in bytes when using standard size; that is, when
+# the format string starts with one of '<', '>', '!' or '='.
+# When using native size, the size of the packed value is
+# platform-dependent.
+#
+# |----------------------------------------------------------|
+# | Format | C Type             | Python type | Size | Notes |
+# |--------------------------------------------------|-------|
+# | x      | pad byte           | no value    | 1    |       |
+# | c      | char               | bytes len 1 | 1    |       |
+# | b      | signed char        | integer     | 1    | (1)(2)|
+# | B      | unsigned char      | integer     | 1    | (2)   |
+# | ?      | _Bool              | bool        | 1    | (1)   |
+# | h      | short              | integer     | 2    | (2)   |
+# | H      | unsigned short     | integer     | 2    | (2)   |
+# | i      | int                | integer     | 4    | (2)   |
+# | I      | unsigned int       | integer     | 4    | (2)   |
+# | l      | long               | integer     | 4    | (2)   |
+# | L      | unsigned long      | integer     | 4    | (2)   |
+# | q      | long long          | integer     | 8    | (2)   |
+# | Q      | unsigned long long | integer     | 8    | (2)   |
+# | n      | ssize_t            | integer     |      | (3)   |
+# | N      | size_t             | integer     |      | (3)   |
+# | e      | (6)                | float       | 2    | (4)   |
+# | f      | float              | float       | 4    | (4)   |
+# | d      | double             | float       | 8    | (4)   |
+# | s      | char[]             | bytes       |      |       |
+# | p      | char[]             | bytes       |      |       |
+# | P      | void *             | integer     |      | (5)   |
+# |--------------------------------------------------|-------|
+#
+# Changed in version 3.3: Added support for the 'n'
+# and 'N' formats.
+#
+# Changed in version 3.6: Added support for the 'e'
+# format.
+#
+# Notes:
+#
+# (1) The '?' conversion code corresponds to the _Bool
+#     type defined by C99. If this type is not available,
+#     it is simulated using a char. In standard mode, it
+#     is always represented by one byte.
+#
+# (2) When attempting to pack a non-integer using any of
+#     the integer conversion codes, if the non-integer has
+#     a __index__() method then that method is called to
+#     convert the argument to an integer before packing.
+#
+#     Changed in version 3.2: Use of the __index__() method
+#     for non-integers is new in 3.2.
+#
+# (3) The 'n' and 'N' conversion codes are only available
+#     for the native size (selected as the default or with
+#     the '@' byte order character). For the standard size,
+#     you can use whichever of the other integer formats
+#     fits your application.
+#
+# (4) For the 'f', 'd' and 'e' conversion codes, the packed
+#     representation uses the IEEE 754 binary32, binary64 or
+#     binary16 format (for 'f', 'd' or 'e' respectively),
+#     regardless of the floating-point format used by the
+#     platform.
+#
+# (5) The 'P' format character is only available for the
+#     native byte ordering (selected as the default or with
+#     the '@' byte order character). The byte order character
+#     '=' chooses to use little- or big-endian ordering based
+#     on the host system. The struct module does not interpret
+#     this as native ordering, so the 'P' format is not
+#     available.
+#
+# (6) The IEEE 754 binary16 “half precision” type was
+#     introduced in the 2008 revision of the IEEE 754 standard.
+#     It has a sign bit, a 5-bit exponent and 11-bit precision
+#     (with 10 bits explicitly stored), and can represent
+#     numbers between approximately 6.1e-05 and 6.5e+04 at
+#     full precision. This type is not widely supported by C
+#     compilers: on a typical machine, an unsigned short can
+#     be used for storage, but not for math operations. See
+#     the Wikipedia page on the half-precision floating-point
+#     format for more information.
+#
+# A format character may be preceded by an integral repeat
+# count. For example, the format string '4h' means exactly the
+# same as 'hhhh'.
+#
+# Whitespace characters between formats are ignored; a count
+# and its format must not contain whitespace though.
+#
+# For the 's' format character, the count is interpreted as
+# the length of the bytes, not a repeat count like for the
+# other format characters; for example, '10s' means a single
+# 10-byte string, while '10c' means 10 characters. If a count
+# is not given, it defaults to 1. For packing, the string is
+# truncated or padded with null bytes as appropriate to make
+# it fit. For unpacking, the resulting bytes object always has
+# exactly the specified number of bytes. As a special case,
+# '0s' means a single, empty string (while '0c' means 0
+# characters).
+#
+# When packing a value x using one of the integer formats
+# ('b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q'), if x is
+# outside the valid range for that format then struct.error is
+# raised.
+#
+# Changed in version 3.1: In 3.0, some of the integer formats
+# wrapped out-of-range values and raised DeprecationWarning
+# instead of struct.error.
+#
+# The 'p' format character encodes a “Pascal string”, meaning
+# a short variable-length string stored in a fixed number of
+# bytes, given by the count. The first byte stored is the
+# length of the string, or 255, whichever is smaller. The
+# bytes of the string follow. If the string passed in to
+# pack() is too long (longer than the count minus 1), only
+# the leading count-1 bytes of the string are stored. If the
+# string is shorter than count-1, it is padded with null bytes
+# so that exactly count bytes in all are used. Note that for
+# unpack(), the 'p' format character consumes count bytes,
+# but that the string returned can never contain more than
+# 255 bytes.
+
+# For the '?' format character, the return value is either
+# True or False. When packing, the truth value of the argument
+# object is used. Either 0 or 1 in the native or standard bool
+# representation will be packed, and any non-zero value will
+# be True when unpacking.
+#
+# ===================================== #
\ No newline at end of file
diff --git a/dfall_ws/src/dfall_pkg/crazyradio/TestCF.py b/dfall_ws/src/dfall_pkg/crazyradio/TestCF.py
index 9598f8522e074e78f73cda20bb755eeb318cdf9e..0f3431c9e9cf2f87033f1ad84275a809057ba8e5 100755
--- a/dfall_ws/src/dfall_pkg/crazyradio/TestCF.py
+++ b/dfall_ws/src/dfall_pkg/crazyradio/TestCF.py
@@ -210,7 +210,7 @@ if __name__ == '__main__':
     cflib.crtp.init_drivers(enable_debug_driver=False)
 
     #wait until address parameter is set by FlyingAgentClient
-    # while not rospy.has_param("~crazyFlieAddress"):
+    # while not rospy.has_param("~crazyflieAddress"):
     #     time.sleep(0.05)
 
     #use this following two lines to connect without data from CentralManager
diff --git a/dfall_ws/src/dfall_pkg/include/nodes/CrazyflieIO.h b/dfall_ws/src/dfall_pkg/include/classes/CrazyflieIO.h
similarity index 100%
rename from dfall_ws/src/dfall_pkg/include/nodes/CrazyflieIO.h
rename to dfall_ws/src/dfall_pkg/include/classes/CrazyflieIO.h
diff --git a/dfall_ws/src/dfall_pkg/include/classes/GetParamtersAndNamespaces.h b/dfall_ws/src/dfall_pkg/include/classes/GetParamtersAndNamespaces.h
index 4174f8f453d5d4c22f40c0916735982e6b407f06..fb35125283a24eb5aef812eb98eee073c3031b74 100644
--- a/dfall_ws/src/dfall_pkg/include/classes/GetParamtersAndNamespaces.h
+++ b/dfall_ws/src/dfall_pkg/include/classes/GetParamtersAndNamespaces.h
@@ -107,15 +107,19 @@ using namespace dfall_pkg;
 
 
 // GET YAML PARAMETER FUNCTIONS
+std::string getParameterString(ros::NodeHandle& nodeHandle, std::string name);
 float getParameterFloat(ros::NodeHandle& nodeHandle, std::string name);
 int getParameterInt(ros::NodeHandle& nodeHandle, std::string name);
 bool getParameterBool(ros::NodeHandle& nodeHandle, std::string name);
 
-void getParameterFloatVector(ros::NodeHandle& nodeHandle, std::string name, std::vector<float>& val, int length);
+int getParameterStringVectorKnownLength(ros::NodeHandle& nodeHandle, std::string name, std::vector<std::string>& val, int length);
+int getParameterStringVectorUnknownLength(ros::NodeHandle& nodeHandle, std::string name, std::vector<std::string>& val);
+void getParameterFloatVectorKnownLength(ros::NodeHandle& nodeHandle, std::string name, std::vector<float>& val, int length);
+int getParameterFloatVectorUnnownLength(ros::NodeHandle& nodeHandle, std::string name, std::vector<float>& val);
 void getParameterIntVectorWithKnownLength(ros::NodeHandle& nodeHandle, std::string name, std::vector<int>& val, int length);
 int getParameterIntVectorWithUnknownLength(ros::NodeHandle& nodeHandle, std::string name, std::vector<int>& val);
 
-std::string getParameterString(ros::NodeHandle& nodeHandle, std::string name);
+
 
 
 
@@ -131,4 +135,7 @@ void constructNamespaceForCoordinator( int coordID, std::string & coord_namespac
 void constructNamespaceForCoordinatorParameterService( int coordID, std::string & coord_param_service_namespace );
 
 // Check the header of a message for whether it is relevant
-bool checkMessageHeader( int agentID , bool shouldCheckForAgentID , const std::vector<uint> & agentIDs );
\ No newline at end of file
+bool checkMessageHeader( int agentID , bool shouldCheckForAgentID , const std::vector<uint> & agentIDs );
+
+// FUNCTION FOR CONVERTING NEWTON TO MOTOR COMMAND
+float newtons2cmd_for_crazyflie( float thrust);
\ No newline at end of file
diff --git a/dfall_ws/src/dfall_pkg/include/classes/QuadrotorSimulator.h b/dfall_ws/src/dfall_pkg/include/classes/QuadrotorSimulator.h
index b520e0f052f48fb48e0bc4c83ad78d13fb885801..ec9de4ce6ba7973ca94a197a5f8db0e95c24cd46 100644
--- a/dfall_ws/src/dfall_pkg/include/classes/QuadrotorSimulator.h
+++ b/dfall_ws/src/dfall_pkg/include/classes/QuadrotorSimulator.h
@@ -101,6 +101,9 @@ class QuadrotorSimulator
 
 public:
 
+	// Empty Constructor
+	QuadrotorSimulator ();
+
 	// Default Constructor
 	QuadrotorSimulator ( std::string id );
 
@@ -111,6 +114,15 @@ public:
 
 public:
 
+	// The current state
+	std::vector<float> m_position          = {0.0,0.0,0.0};
+	std::vector<float> m_velocity          = {0.0,0.0,0.0};
+	std::vector<float> m_euler_angles      = {0.0,0.0,0.0};
+	std::vector<float> m_euler_velocities  = {0.0,0.0,0.0};
+
+
+private:
+
 	// Identifier String
 	std::string m_id_string = "none";
 
@@ -120,16 +132,6 @@ public:
 	// Mass of the quadrotor [kilograms]
 	float m_mass_in_kg = 0.032;
 
-	// The current state
-	std::vector<float> m_position          = {0.0,0.0,0.0};
-	std::vector<float> m_velocity          = {0.0,0.0,0.0};
-	std::vector<float> m_euler_angles      = {0.0,0.0,0.0};
-	std::vector<float> m_euler_velocities  = {0.0,0.0,0.0};
-
-
-
-private:
-	
 	// The flying state
 	bool m_isFlying = false;
 
@@ -194,6 +196,21 @@ private:
 
 public:
 
+	// Function to get the ID as a string
+	std::string get_id_string();
+
+	// Function to set the ID as a string
+	void set_id_string(std::string new_id_string);
+
+	// Function to get the mass in kilograms
+	float get_mass_in_kg();
+
+	// Function to set the mass in kilograms
+	void set_mass_in_kg(float new_mass_in_kg);
+
+	// Function to get the flying state
+	bool get_isFlying();
+
 	// Function to simulate the quadrotor for one time step
 	void simulate_for_one_time_step(float deltaT);
 
@@ -203,8 +220,7 @@ public:
 	// Function to update the commanding agent id
 	void update_commanding_agent_id( int new_commanding_agent_id );
 
-	// Function to get the flying state
-	bool getIsFlying();
+	
 
 	// Function to set the reset state
 	void setResetState_xyz_yaw(float x, float y, float z, float yaw);
diff --git a/dfall_ws/src/dfall_pkg/include/nodes/AgentStatusForWebInterface.h b/dfall_ws/src/dfall_pkg/include/nodes/AgentStatusForWebInterface.h
new file mode 100644
index 0000000000000000000000000000000000000000..c7dcef7ef98362f9bd8875a3c153612c31c96fb8
--- /dev/null
+++ b/dfall_ws/src/dfall_pkg/include/nodes/AgentStatusForWebInterface.h
@@ -0,0 +1,166 @@
+//    Copyright (C) 2020, The University of Melbourne, Department of Electrical and Electronic Engineering (EEE), Paul Beuchat
+//
+//    This file is part of D-FaLL-System.
+//    
+//    D-FaLL-System is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//    
+//    D-FaLL-System is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//    
+//    You should have received a copy of the GNU General Public License
+//    along with D-FaLL-System.  If not, see <http://www.gnu.org/licenses/>.
+//    
+//
+//    ----------------------------------------------------------------------------------
+//    DDDD        FFFFF        L     L           SSSS  Y   Y   SSSS  TTTTT  EEEEE  M   M
+//    D   D       F      aaa   L     L          S       Y Y   S        T    E      MM MM
+//    D   D  ---  FFFF  a   a  L     L     ---   SSS     Y     SSS     T    EEE    M M M
+//    D   D       F     a  aa  L     L              S    Y        S    T    E      M   M
+//    DDDD        F      aa a  LLLL  LLLL       SSSS     Y    SSSS     T    EEEEE  M   M
+//
+//
+//    DESCRIPTION:
+//    The service that provides data to the web interface
+//
+//    ----------------------------------------------------------------------------------
+
+
+
+
+
+//    ----------------------------------------------------------------------------------
+//    III  N   N   CCCC  L      U   U  DDDD   EEEEE   SSSS
+//     I   NN  N  C      L      U   U  D   D  E      S
+//     I   N N N  C      L      U   U  D   D  EEE     SSS
+//     I   N  NN  C      L      U   U  D   D  E          S
+//    III  N   N   CCCC  LLLLL   UUU   DDDD   EEEEE  SSSS
+//    ----------------------------------------------------------------------------------
+
+#include <stdlib.h>
+//#include <iostream>
+#include <string>
+
+#include <ros/ros.h>
+#include <ros/package.h>
+#include <ros/network.h>
+
+// Include the standard message types
+#include "std_msgs/Int32.h"
+//#include "std_msgs/Float32.h"
+//#include <std_msgs/String.h>
+
+// Include the DFALL message types
+#include "dfall_pkg/SetpointWithHeader.h"
+#include "dfall_pkg/FlyingVehicleState.h"
+#include "dfall_pkg/DebugMsg.h"
+
+// Include the DFALL service types
+#include "dfall_pkg/IntStringService.h"
+
+// Include the shared definitions
+#include "nodes/Constants.h"
+//#include "classes/GetParamtersAndNamespaces.h"
+
+// SPECIFY THE PACKAGE NAMESPACE
+using namespace dfall_pkg;
+//using namespace std;
+
+
+
+//    ----------------------------------------------------------------------------------
+//    DDDD   EEEEE  FFFFF  III  N   N  EEEEE   SSSS
+//    D   D  E      F       I   NN  N  E      S
+//    D   D  EEE    FFF     I   N N N  EEE     SSS
+//    D   D  E      F       I   N  NN  E          S
+//    DDDD   EEEEE  F      III  N   N  EEEEE  SSSS
+//    ----------------------------------------------------------------------------------
+
+
+
+
+
+//    ----------------------------------------------------------------------------------
+//    V   V    A    RRRR   III    A    BBBB   L      EEEEE   SSSS
+//    V   V   A A   R   R   I    A A   B   B  L      E      S
+//    V   V  A   A  RRRR    I   A   A  BBBB   L      EEE     SSS
+//     V V   AAAAA  R  R    I   AAAAA  B   B  L      E          S
+//      V    A   A  R   R  III  A   A  BBBB   LLLLL  EEEEE  SSSS
+//    ----------------------------------------------------------------------------------
+
+
+// The crazyradio status
+// > as received via messages
+int m_crazyradio_status = CRAZY_RADIO_STATE_DISCONNECTED;
+
+// The battery level
+// > as received via messages
+int m_battery_level = BATTERY_LEVEL_UNAVAILABLE;
+
+// The flying state of the agent
+// > as received via messages
+int m_agent_operating_state = STATE_UNAVAILABLE;
+
+// The instant controller,
+// > as received via messages
+int m_instant_controller = DEFAULT_CONTROLLER;
+
+// The setpoint of the default controller
+// > as received via messages
+float m_setpoint_default[4] = {0.0,0.0,0.4,0.0};
+
+// The setpoint of the student controller
+// > as received via messages
+float m_setpoint_student[4] = {0.0,0.0,0.4,0.0};
+
+// The debug values of the student controller
+// > as received via messages
+float m_debug_values_student[10] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
+
+// The current state estimate of the Crazyflie
+// > as received via messages
+float m_cf_state_estimate_xyz_rpy[6] = {0.0,0.0,0.0,0.0,0.0,0.0};
+
+
+
+
+
+//    ----------------------------------------------------------------------------------
+//    FFFFF  U   U  N   N   CCCC  TTTTT  III   OOO   N   N
+//    F      U   U  NN  N  C        T     I   O   O  NN  N
+//    FFF    U   U  N N N  C        T     I   O   O  N N N
+//    F      U   U  N  NN  C        T     I   O   O  N  NN
+//    F       UUU   N   N   CCCC    T    III   OOO   N   N
+//
+//    PPPP   RRRR    OOO   TTTTT   OOO   TTTTT  Y   Y  PPPP   EEEEE   SSSS
+//    P   P  R   R  O   O    T    O   O    T     Y Y   P   P  E      S
+//    PPPP   RRRR   O   O    T    O   O    T      Y    PPPP   EEE     SSS
+//    P      R  R   O   O    T    O   O    T      Y    P      E          S
+//    P      R   R   OOO     T     OOO     T      Y    P      EEEEE  SSSS
+//    ----------------------------------------------------------------------------------
+
+
+// Callbacks for messages with the status of things:
+// > For the status of the crazyradio
+void crazyRadioStatusCallback(const std_msgs::Int32& msg);
+// > For the battery level
+void newBatteryLevelCallback(const std_msgs::Int32& msg);
+// > For the flying state of the agent
+void agentOperatingStateCallback(const std_msgs::Int32& msg);
+// > For the instant controller
+void instantControllerChangedCallback(const std_msgs::Int32& msg);
+// > For the Default Controller Setpoint
+void defaultControllerSetpointChangedCallback(const SetpointWithHeader& newSetpoint);
+// > For the Student Controller Setpoint
+void studentControllerSetpointChangedCallback(const SetpointWithHeader& newSetpoint);
+// > For the Student Controller Debug Values
+void studentControllerDebugValuesCallback(const DebugMsg& newDebugMsg);
+// > For the State Estimate from the Crazyflie
+void cfStateEstimateCallback(const FlyingVehicleState & newStateEstimate);
+
+// Service callback for providing status to the Web Interface
+bool statusForWebInterfaceCallback(IntStringService::Request &request, IntStringService::Response &response);
\ No newline at end of file
diff --git a/dfall_ws/src/dfall_pkg/include/nodes/CentralManagerService.h b/dfall_ws/src/dfall_pkg/include/nodes/CentralManagerService.h
index 8d6f536eda2812023ce1912a623a1ce5f9df471e..cd2abf23cab94473518b1ffcc6395ee8d280ae91 100644
--- a/dfall_ws/src/dfall_pkg/include/nodes/CentralManagerService.h
+++ b/dfall_ws/src/dfall_pkg/include/nodes/CentralManagerService.h
@@ -61,7 +61,7 @@
 #include "dfall_pkg/CMCommand.h"
 
 // Include other classes
-#include "CrazyflieIO.h"
+#include "classes/CrazyflieIO.h"
 
 
 
diff --git a/dfall_ws/src/dfall_pkg/include/nodes/Constants.h b/dfall_ws/src/dfall_pkg/include/nodes/Constants.h
index 7c4b3dd4d687b629f6fb14a9902a4717a8aa4d49..4bd6a0942eecd09498cf4c702ac66fc8ddc93eaa 100644
--- a/dfall_ws/src/dfall_pkg/include/nodes/Constants.h
+++ b/dfall_ws/src/dfall_pkg/include/nodes/Constants.h
@@ -41,7 +41,6 @@
 //     UUU
 //    ----------------------------------------------------------------------------------
 
-
 // Conversions between degrees and radians
 #define RAD2DEG 180.0/PI
 #define DEG2RAD PI/180.0
@@ -64,8 +63,6 @@
 //    
 //    ----------------------------------------------------------------------------------
 
-
-
 // The types, i.e., agent or coordinator
 #define TYPE_INVALID      -1
 #define TYPE_COORDINATOR   1
@@ -111,6 +108,31 @@
 #define CF_COMMAND_TYPE_ANGLE  10
 
 
+#define CF_ONBOARD_CONTROLLER_MODE_OFF            0
+#define CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE   1
+#define CF_ONBOARD_CONTROLLER_MODE_ANGLE          2
+#define CF_ONBOARD_CONTROLLER_MODE_VELOCITY       3
+#define CF_ONBOARD_CONTROLLER_MODE_POSITION       4
+
+
+
+
+
+//    ----------------------------------------------------------------------------------
+//    
+//    
+//    
+//    
+//    
+//    ----------------------------------------------------------------------------------
+
+// Types of flying vehicle states:
+#define FLYING_VEHICLE_STATE_TYPE_NONE                        0
+#define FLYING_VEHICLE_STATE_TYPE_MOCAP_MEASUREMENT           1
+#define FLYING_VEHICLE_STATE_TYPE_CRAZYFLIE_STATE_ESTIMATE    2
+#define FLYING_VEHICLE_STATE_TYPE_12_STATE_ESTIMATE           3
+
+
 
 
 
@@ -175,6 +197,7 @@
 
 
 
+
 //    ----------------------------------------------------------------------------------
 //    BBBB     A    TTTTT  TTTTT  EEEEE  RRRR   Y   Y
 //    B   B   A A     T      T    E      R   R   Y Y
diff --git a/dfall_ws/src/dfall_pkg/include/nodes/CrazyRadioEmulator.h b/dfall_ws/src/dfall_pkg/include/nodes/CrazyRadioEmulator.h
index 03905238f5f1c6bcf7e760b8b76832e56306616f..a4af6736fc89346d2ec3a7a6aad2ff25b130ee60 100644
--- a/dfall_ws/src/dfall_pkg/include/nodes/CrazyRadioEmulator.h
+++ b/dfall_ws/src/dfall_pkg/include/nodes/CrazyRadioEmulator.h
@@ -57,13 +57,17 @@
 // Include the DFALL message types
 #include "dfall_pkg/IntWithHeader.h"
 #include "dfall_pkg/ControlCommand.h"
+#include "dfall_pkg/FlyingVehicleState.h"
 
 // Include the DFALL service types
 #include "dfall_pkg/IntIntService.h"
 
 // Include the shared definitions
 #include "nodes/Constants.h"
+
+// Include other classes
 #include "classes/GetParamtersAndNamespaces.h"
+#include "classes/QuadrotorSimulator.h"
 
 // SPECIFY THE PACKAGE NAMESPACE
 using namespace dfall_pkg;
@@ -112,6 +116,9 @@ int m_radio_state = CRAZY_RADIO_STATE_DISCONNECTED;
 // Timer for the battery voltage updates
 ros::Timer m_timer_battery_voltage_updates;
 
+// Timer for the state estimte updates
+ros::Timer m_timer_state_estimate_update;
+
 
 // PUBLISHERS
 
@@ -121,16 +128,21 @@ ros::Publisher crazyRadioStatusPublisher;
 // Publisher for sending a "Flying Agent Client Command"
 ros::Publisher flyingAgentClientCommandPublisher;
 
-// Publisher for the filtered battery voltage
+// Publisher for the raw battery voltage
 ros::Publisher batteryVoltagePublisher;
 
+// Publisher for the onboard state estimate
+ros::Publisher  cfStateEstimatorPublisher;
+
 // Publisher for the control commands
 // > Note this is not needed for the real CrazyRadio node because
 //   this command goes out over the radio, but for emulation we publish
 //   the control command
 ros::Publisher controlCommandPublisher;
 
-
+// Publisher for the simulation state
+// > This is used by the MocapEmulator node
+ros::Publisher  cfSimulationStatePublisher;
 
 
 
@@ -141,6 +153,11 @@ ros::Publisher controlCommandPublisher;
 // Frequency of requesting the battery voltage, in [seconds]
 float yaml_battery_polling_period_in_seconds = 0.2f;
 
+// Flag for whether to use height as a trigger for
+// publishing a motors-OFF command
+bool yaml_isEnabled_strictSafety = true;
+float yaml_maxHeight_for_strictSafety_meters = 1.2;
+
 // // Battery thresholds while in the "motors off" state, in [Volts]
 // float yaml_battery_voltage_threshold_lower_while_standby = 3.30f;
 // float yaml_battery_voltage_threshold_upper_while_standby = 4.20f;
@@ -155,6 +172,36 @@ float yaml_battery_polling_period_in_seconds = 0.2f;
 
 
 
+
+
+// VARIABLES FOR SIMULATING A QUAROTOR
+
+// A QUADROTORS SIMULATOR
+QuadrotorSimulator m_quadrotor_sim;
+
+// SIMULATION FREQUENCY FOR EMULATING A CRAZYFLIE
+//float yaml_cfStateEstimate_polling_period_in_seconds = 0.02f;
+float yaml_cfSimulation_frequency = 200.0;
+float yaml_cfSimulation_deltaT_in_seconds = 0.005;
+
+// HOW OFTEN TO PUBLISH THE SIMULATION STATE AS AN
+// ONBOARD ESTIMATE
+// > i.e., this integer divided by the
+//   "cfSimulation_frequency" gives the simulation
+//    equivalent of "cfStateEstimate_polling_period"
+int yaml_cfSimulation_stateEstimate_sendEvery = 4;
+
+// THE COEFFICIENT OF THE 16-BIT COMMAND TO THRUST CONVERSION
+std::vector<float> yaml_motorPoly = {5.484560e-4, 1.032633e-6, 2.130295e-11};
+
+// THE MIN AND MAX FOR SATURATING THE 16-BIT THRUST COMMANDS
+float yaml_command_sixteenbit_min = 1000.0f;
+float yaml_command_sixteenbit_max = 65000.0f;
+
+
+
+
+
 //    ----------------------------------------------------------------------------------
 //    FFFFF  U   U  N   N   CCCC  TTTTT  III   OOO   N   N
 //    F      U   U  NN  N  C        T     I   O   O  NN  N
@@ -195,8 +242,12 @@ bool getCurrentCrazyRadioStatusServiceCallback(IntIntService::Request &request,
 
 
 // UPDATE BATTERY VOLTAGE TIMER CALLBACK
-void update_battery_voltage_callback(const ros::TimerEvent&);
+void timerCallback_update_battery_voltage(const ros::TimerEvent&);
+
+// UPDATE STATE ESTIMATE TIMER CALLBACK
+void timerCallback_update_cfStateEstimate(const ros::TimerEvent&);
 
 // LOAD YAML PARAMETER FUNCTIONS
 void isReadyBatteryMonitorYamlCallback(const IntWithHeader & msg);
-void fetchBatteryMonitorYamlParameters(ros::NodeHandle& nodeHandle);
\ No newline at end of file
+void fetchBatteryMonitorYamlParameters(ros::NodeHandle& nodeHandle);
+void fetchCrazyRadioConfigYamlParameters(ros::NodeHandle& nodeHandle);
\ No newline at end of file
diff --git a/dfall_ws/src/dfall_pkg/include/nodes/DefaultControllerService.h b/dfall_ws/src/dfall_pkg/include/nodes/DefaultControllerService.h
index a838f2f2b2a8b8ca5ea03ede4742ae9f56b9c5f3..bb7a47f7d1f0f5bb61fb1d492fcef401ead9901e 100644
--- a/dfall_ws/src/dfall_pkg/include/nodes/DefaultControllerService.h
+++ b/dfall_ws/src/dfall_pkg/include/nodes/DefaultControllerService.h
@@ -44,7 +44,7 @@
 // These various headers need to be included so that this controller service can be
 // connected with the D-FaLL system.
 
-//some useful libraries
+// Include useful libraries
 #include <math.h>
 #include <stdlib.h>
 #include "ros/ros.h"
@@ -329,7 +329,7 @@ float yaml_integratorGain_forTauYaw = 0.0;
 // VARIABLES FOR THE ESTIMATOR
 
 // Frequency at which the controller is running
-float m_estimator_frequency = 200.0;
+float yaml_estimator_frequency = 200.0;
 
 // > A flag for which estimator to use:
 int yaml_estimator_method = ESTIMATOR_METHOD_FINITE_DIFFERENCE;
@@ -387,7 +387,9 @@ bool m_isAvailableContext = false;
 // Variable for each coordinate
 float m_symmetric_area_bounds_x = 0.5;
 float m_symmetric_area_bounds_y = 0.5;
-float m_symmetric_area_bounds_z = 0.5;
+//float m_symmetric_area_bounds_z = 0.5;
+float m_area_bounds_zmin = 0.0;
+float m_area_bounds_zmax = 1.0;
 
 // Service Client from which the "CrazyflieContext" is loaded
 ros::ServiceClient m_centralManager;
diff --git a/dfall_ws/src/dfall_pkg/include/nodes/DemoControllerService.h b/dfall_ws/src/dfall_pkg/include/nodes/DemoControllerService.h
index 111c7e4722b7253a962047a78d08a677233de335..a4791592b551052f5642c0d1a3d81b7ce338b2be 100644
--- a/dfall_ws/src/dfall_pkg/include/nodes/DemoControllerService.h
+++ b/dfall_ws/src/dfall_pkg/include/nodes/DemoControllerService.h
@@ -378,21 +378,6 @@ ros::Publisher my_current_xyz_yaw_publisher;
 ros::Subscriber xyz_yaw_to_follow_subscriber;
 
 
-// RELEVANT NOTES ABOUT THE VARIABLES DECLARE HERE:
-// The "CrazyflieData" type used for the "request" variable is a
-// structure as defined in the file "CrazyflieData.msg" which has the following
-// properties:
-//     string crazyflieName              The name given to the Crazyflie in the Vicon software
-//     float64 x                         The x position of the Crazyflie [metres]
-//     float64 y                         The y position of the Crazyflie [metres]
-//     float64 z                         The z position of the Crazyflie [metres]
-//     float64 roll                      The roll component of the intrinsic Euler angles [radians]
-//     float64 pitch                     The pitch component of the intrinsic Euler angles [radians]
-//     float64 yaw                       The yaw component of the intrinsic Euler angles [radians]
-//     float64 acquiringTime #delta t    The time elapsed since the previous "CrazyflieData" was received [seconds]
-//     bool occluded                     A boolean indicted whether the Crazyflie for visible at the time of this measurement
-
-
 
 
 
diff --git a/dfall_ws/src/dfall_pkg/include/nodes/FlyingAgentClient.h b/dfall_ws/src/dfall_pkg/include/nodes/FlyingAgentClient.h
index 61b6d33059caac567b9d635401da2ecb23fd3a4f..5e09499b58d66bf629711c54b55a296f47f249b9 100644
--- a/dfall_ws/src/dfall_pkg/include/nodes/FlyingAgentClient.h
+++ b/dfall_ws/src/dfall_pkg/include/nodes/FlyingAgentClient.h
@@ -55,7 +55,7 @@
 // Include the DFALL message types
 #include "dfall_pkg/IntWithHeader.h"
 #include "dfall_pkg/ViconData.h"
-#include "dfall_pkg/CrazyflieData.h"
+#include "dfall_pkg/FlyingVehicleState.h"
 #include "dfall_pkg/ControlCommand.h"
 #include "dfall_pkg/CrazyflieContext.h"
 #include "dfall_pkg/Setpoint.h"
@@ -124,30 +124,46 @@ std::string m_namespace_to_coordinator_parameter_service;
 
 
 
+// VARIABLES FOR SOTRING THE PARAMETERS OF WHICH
+// MEASUREMENT STREAMS TO USE
+bool yaml_shouldUse_mocapMeasurements = false;
+bool yaml_shouldUse_onboardEstimate   = false;
+
+// SUBSCRIBERS FOR THE MEASUREMENT STREAMS
+ros::Subscriber viconSubscriber;
+ros::Subscriber onboardEstimateSubscriber;
+
+
+
+// VARIABLES FOR AVAILABILITY AND VALIDITY OF MEASUREMENTS
+// > Boolen indicating if the Mocap data is availble
+bool m_isAvailable_measurement_data = false;
+// > Boolen indicating if the object is "long term" invalid
+bool m_isValid_measurement_data = false;
+// > Number of consecutive invalid measurements that triggers
+//   the "m_isValid_measurement_data" variable to be "false"
+int yaml_consecutive_invalid_threshold = 30;
+// > Timer that when triggered determines that the
+//   "m_isAvailable_measurement_data" variable becomes false
+ros::Timer m_timer_measurement_data_timeout_check;
+// > Time out duration after which measurement data is
+//   considered unavailable
+float yaml_measurement_timeout_duration = 1.0;
+
+
+
 // VARIABLES FOR THE MOTION CAPTURE DATA
 // > The index for which element in the "motion capture
 //   data" array is expected to match the name in
 //   "m_context", (negative numbers indicate unknown)
 int m_poseDataIndex = -1;
-// > Boolen indicating if the Mocap data is availble
-bool m_isAvailable_mocap_data = false;
-// > Boolen indicating if the object is "long term" occuled
-bool m_isOcculded_mocap_data = false;
-// > Number of consecutive occulsions that trigger the
-//   "m_isOcculded_mocap_data" variable to be "true"
-int yaml_consecutive_occulsions_threshold = 30;
-// > Timer that when triggered determines that the
-//   "m_isAvailable_mocap_data" variable becomes true
-ros::Timer m_timer_mocap_timeout_check;
-// > Time out duration after which Mocap is considered unavailable
-float yaml_mocap_timeout_duration = 1.0;
-
-// VARIABLES FOR GETTING MOTION CAPTURE DATA OF OTHER OBJECTS
+//  > The index for getting motion capture data of other
+//    objects
 int m_otherObjectPoseDataIndex = -1;
 
 
 
-// VARIABLES FOR STORING THE PARAMTER OF THE POSITION
+// VARIABLES FOR STORING THE PARAMETERS FOR THE POSITION
 // AND TILT ANGLE SAFTY CHECKS
 // > Boolean indicating whether the tilt angle check
 //   should be performed
@@ -276,21 +292,36 @@ ros::Publisher m_controllerUsedPublisher;
 void viconCallback(const ViconData& viconData);
 // > For extracting the pose data of an specific
 //   object by name
-int getPoseDataForObjectNameWithExpectedIndex(const ViconData& viconData, std::string name , int expected_index ,CrazyflieData& pose);
+int getPoseDataForObjectNameWithExpectedIndex(const ViconData& viconData, std::string name , int expected_index ,FlyingVehicleState& pose);
 // > For converting the global frame motion capture
 //   data to the local frame of this agent
-void coordinatesToLocal(CrazyflieData& cf);
-// > Callback run when motion capture data has not
-//   been receive for a specified time
-void timerCallback_mocap_timeout_check(const ros::TimerEvent&);
+void coordinatesToLocal(FlyingVehicleState& cf);
+
+
+
+// FUNCTIONS FOR HANDLING THE ONBOARD STATE ESTIMATE
+// > Callback run every time new state estimate
+//   data is available from onboard the flying vehicle
+void onboardEstimateCallback(const FlyingVehicleState& flyingVehicleState);
+
+
+
+// FUNCTIONS FOR CALLING THE CONTROLLER SERVICE
+// > For calling the controller service for the currently
+//   selected controller, and then sending the control
+//   command to the CrazyRadio node
+void callControllerServiceWithGivenData(FlyingVehicleState& dataForThisAgent, FlyingVehicleState& dataForOtherAgent);
 // > For sending a command, via the CrazyRadio, that
 //   the motors should be set to zero
 void sendZeroOutputCommandForMotors();
+// > Callback run when measurement data has not
+//   been received for a specified time
+void timerCallback_measurement_data_timeout_check(const ros::TimerEvent&);
 
 
 
 // FOR THE SAFETY CHECKS ON POSITION AND TILT ANGLE
-bool safetyCheck_on_positionAndTilt(CrazyflieData data);
+bool safetyCheck_on_positionAndTilt(FlyingVehicleState data);
 
 
 
diff --git a/dfall_ws/src/dfall_pkg/include/nodes/MocapEmulator.h b/dfall_ws/src/dfall_pkg/include/nodes/MocapEmulator.h
index ec94b908c16bd2c1ab25f188b2d66b9c90dc9c17..d73349f7da1e55dba4009506e239c6f103a57122 100644
--- a/dfall_ws/src/dfall_pkg/include/nodes/MocapEmulator.h
+++ b/dfall_ws/src/dfall_pkg/include/nodes/MocapEmulator.h
@@ -55,7 +55,7 @@
 // Include the DFALL message types
 #include "dfall_pkg/IntWithHeader.h"
 #include "dfall_pkg/ViconData.h"
-#include "dfall_pkg/CrazyflieData.h"
+#include "dfall_pkg/FlyingVehicleState.h"
 #include "dfall_pkg/ControlCommand.h"
 #include "dfall_pkg/CrazyflieContext.h"
 #include "dfall_pkg/AreaBounds.h"
@@ -129,6 +129,11 @@ float yaml_command_sixteenbit_max = 65000;
 // A VECTOR OF QUADROTORS
 std::vector<QuadrotorSimulator> m_quadrotor_fleet;
 
+// A VECTOR OF FLYING VEHICLE STATES
+std::vector<FlyingVehicleState> m_flying_fleet_states;
+std::vector<ros::Subscriber> m_flying_fleet_state_subscribers;
+std::vector<AreaBounds> m_flying_fleet_areaBounds;
+
 // PUBLISHER FOR THE MOTION CAPTURE DATA
 ros::Publisher m_mocapDataPublisher;
 
@@ -153,6 +158,10 @@ ros::ServiceClient m_centralManagerService;
 // CALLBACK FOR EVERYTIME MOCAP DATA SHOULD BE PUBLISHED
 void timerCallback_mocap_publisher(const ros::TimerEvent&);
 
+// CALLBACK FOR RECEIVEING CRAZYFLIE SIMULATION DATA
+// > This data is published by the CrazyRadioEmulator node
+void cfSimulationStateCallback(const FlyingVehicleState & msg);
+
 // FUNCTIONS FOR THE CONTEXT OF THIS AGENT
 // > Callback that the context database changed
 void crazyflieContextDatabaseChangedCallback(const std_msgs::Int32& msg);
diff --git a/dfall_ws/src/dfall_pkg/include/nodes/ParameterService.h b/dfall_ws/src/dfall_pkg/include/nodes/ParameterService.h
index d298e9e2b2456acf03f5aac57ed73ba69d341ee5..bed209750ff56561b977b3f6568dd38f94210bea 100644
--- a/dfall_ws/src/dfall_pkg/include/nodes/ParameterService.h
+++ b/dfall_ws/src/dfall_pkg/include/nodes/ParameterService.h
@@ -43,6 +43,7 @@
 
 #include <stdlib.h>
 #include <string>
+#include <map>
 
 #include <ros/ros.h>
 #include <ros/package.h>
@@ -65,6 +66,7 @@
 #include "nodes/Constants.h"
 
 
+
 //    ----------------------------------------------------------------------------------
 //    DDDD   EEEEE  FFFFF  III  N   N  EEEEE   SSSS
 //    D   D  E      F       I   NN  N  E      S
@@ -106,8 +108,15 @@ std::string m_base_namespace;
 
 // Publisher for passing a service request onto the
 // loadinging function
-ros::Publisher requestLoadYamlFilenamePublisher;
+ros::Publisher m_requestLoadYamlFilenamePublisher;
+
+// Vector of strings loaded from YAML file with the
+// file names of yaml files to load
+std::vector<std::string> yaml_filenames_provided;
 
+// Map of Publishers for informing the network that this
+// Parameter service node loaded a requested YAML file
+std::map<std::string, ros::Publisher> m_yamlParametersReadyForFetchPublisherMap;
 
 
 
diff --git a/dfall_ws/src/dfall_pkg/include/nodes/RemoteControllerService.h b/dfall_ws/src/dfall_pkg/include/nodes/RemoteControllerService.h
index a47c52b54922052e5da14b3eb3656cabaeba1d18..75b3273b46b541ef7ac05df07edbffdd45655d9d 100644
--- a/dfall_ws/src/dfall_pkg/include/nodes/RemoteControllerService.h
+++ b/dfall_ws/src/dfall_pkg/include/nodes/RemoteControllerService.h
@@ -109,26 +109,6 @@ using namespace dfall_pkg;
 
 // These constants are defined to make the code more readable and adaptable.
 
-// These constants define the modes that can be used for controller the Crazyflie 2.0,
-// the constants defined here need to be in agreement with those defined in the
-// firmware running on the Crazyflie 2.0.
-// The following is a short description about each mode:
-// MOTOR_MODE    In this mode the Crazyflie will apply the requested 16-bit per motor
-//               command directly to each of the motors
-// RATE_MODE     In this mode the Crazyflie will apply the requested 16-bit per motor
-//               command directly to each of the motors, and additionally request the
-//               body frame roll, pitch, and yaw angular rates from the PID rate
-//               controllers implemented in the Crazyflie 2.0 firmware.
-// ANGE_MODE     In this mode the Crazyflie will apply the requested 16-bit per motor
-//               command directly to each of the motors, and additionally request the
-//               body frame roll, pitch, and yaw angles from the PID attitude
-//               controllers implemented in the Crazyflie 2.0 firmware.
-
-// #define CF_COMMAND_TYPE_MOTOR   6
-// #define CF_COMMAND_TYPE_RATE    7
-// #define CF_COMMAND_TYPE_ANGLE   8
-
-
 // These constants define the controller used for computing the response in the
 // "calculateControlOutput" function
 // The following is a short description about each mode:
@@ -398,23 +378,6 @@ int m_coordID;
 
 
 
-// RELEVANT NOTES ABOUT THE VARIABLES DECLARE HERE:
-// The "CrazyflieData" type used for the "request" variable is a
-// structure as defined in the file "CrazyflieData.msg" which has the following
-// properties:
-//     string crazyflieName              The name given to the Crazyflie in the Vicon software
-//     float64 x                         The x position of the Crazyflie [metres]
-//     float64 y                         The y position of the Crazyflie [metres]
-//     float64 z                         The z position of the Crazyflie [metres]
-//     float64 roll                      The roll component of the intrinsic Euler angles [radians]
-//     float64 pitch                     The pitch component of the intrinsic Euler angles [radians]
-//     float64 yaw                       The yaw component of the intrinsic Euler angles [radians]
-//     float64 acquiringTime #delta t    The time elapsed since the previous "CrazyflieData" was received [seconds]
-//     bool occluded                     A boolean indicted whether the Crazyflie for visible at the time of this measurement
-
-
-
-
 
 //    ----------------------------------------------------------------------------------
 //    FFFFF  U   U  N   N   CCCC  TTTTT  III   OOO   N   N
diff --git a/dfall_ws/src/dfall_pkg/include/nodes/SafeControllerService.h b/dfall_ws/src/dfall_pkg/include/nodes/SafeControllerService.h
index 3a540f297544dfa279d053e34d8265c3e606ba61..2fa26a998ab4be3277d583b2256a126972fa9508 100644
--- a/dfall_ws/src/dfall_pkg/include/nodes/SafeControllerService.h
+++ b/dfall_ws/src/dfall_pkg/include/nodes/SafeControllerService.h
@@ -56,7 +56,7 @@
 
 // Include the DFALL message types
 #include "dfall_pkg/IntWithHeader.h"
-#include "dfall_pkg/CrazyflieData.h"
+#include "dfall_pkg/FlyingVehicleState.h"
 #include "dfall_pkg/Setpoint.h"
 #include "dfall_pkg/ControlCommand.h"
 #include "dfall_pkg/Controller.h"
@@ -155,7 +155,7 @@ std::vector<float>  setpoint(4);
 std::vector<float> defaultSetpoint(4);
 float saturationThrust;
 
-CrazyflieData previousLocation;
+FlyingVehicleState previousLocation;
 
 
 // Variable for the namespaces for the paramter services
@@ -199,7 +199,7 @@ void processFetchedParameters();
 
 // > For the GETPARAM()
 float getParameterFloat(ros::NodeHandle& nodeHandle, std::string name);
-void getParameterFloatVector(ros::NodeHandle& nodeHandle, std::string name, std::vector<float>& val, int length);
+void getParameterFloatVectorKnownLength(ros::NodeHandle& nodeHandle, std::string name, std::vector<float>& val, int length);
 int getParameterInt(ros::NodeHandle& nodeHandle, std::string name);
 void getParameterIntVectorWithKnownLength(ros::NodeHandle& nodeHandle, std::string name, std::vector<int>& val, int length);
 int getParameterIntVectorWithUnknownLength(ros::NodeHandle& nodeHandle, std::string name, std::vector<int>& val);
diff --git a/dfall_ws/src/dfall_pkg/include/nodes/StudentControllerService.h b/dfall_ws/src/dfall_pkg/include/nodes/StudentControllerService.h
index 91d6b3e89d67aec767d7c5cf8fe3a740a16a8497..bb04171a063e7ee268acf96ec43333676aaddcb1 100644
--- a/dfall_ws/src/dfall_pkg/include/nodes/StudentControllerService.h
+++ b/dfall_ws/src/dfall_pkg/include/nodes/StudentControllerService.h
@@ -69,6 +69,7 @@
 // Include the DFALL service types
 #include "dfall_pkg/LoadYamlFromFilename.h"
 #include "dfall_pkg/GetSetpointService.h"
+//#include "dfall_pkg/GetDebugValuesService.h"
 
 // Include the shared definitions
 #include "nodes/Constants.h"
@@ -167,10 +168,6 @@ float yaml_cf_mass_in_grams = 25.0;
 // The weight of the Crazyflie in Newtons, i.e., mg
 float m_cf_weight_in_newtons = yaml_cf_mass_in_grams * 9.81 / 1000.0;
 
-// > the coefficients of the 16-bit command to thrust conversion
-//std::vector<float> yaml_motorPoly(3);
-std::vector<float> yaml_motorPoly = {5.484560e-4, 1.032633e-6, 2.130295e-11};
-
 // > the frequency at which the controller is running
 float yaml_control_frequency = 200.0;
 
@@ -236,9 +233,6 @@ bool calculateControlOutput(Controller::Request &request, Controller::Response &
 // INTO AN (x,y) BODY FRAME ERROR
 void convertIntoBodyFrame(float stateInertial[9], float (&stateBody)[9], float yaw_measured);
 
-// CONVERSION FROM THRUST IN NEWTONS TO 16-BIT COMMAND
-float computeMotorPolyBackward(float thrust);
-
 // REQUEST SETPOINT CHANGE CALLBACK
 void requestSetpointChangeCallback(const SetpointWithHeader& newSetpoint);
 
diff --git a/dfall_ws/src/dfall_pkg/include/nodes/TestMotorsControllerService.h b/dfall_ws/src/dfall_pkg/include/nodes/TestMotorsControllerService.h
index bfe8717bd41138ae6754cba3bd40951ade020260..3619494211d700b273e9b6d19a2c983ca2f5f54c 100644
--- a/dfall_ws/src/dfall_pkg/include/nodes/TestMotorsControllerService.h
+++ b/dfall_ws/src/dfall_pkg/include/nodes/TestMotorsControllerService.h
@@ -123,68 +123,6 @@ int m_agentID;
 // The ID of the agent that can coordinate this node
 int m_coordID;
 
-// NAMESPACES FOR THE PARAMETER SERVICES
-// > For the paramter service of this agent
-std::string m_namespace_to_own_agent_parameter_service;
-// > For the parameter service of the coordinator
-std::string m_namespace_to_coordinator_parameter_service;
-
-
-
-// VARAIBLES FOR VALUES LOADED FROM THE YAML FILE
-// > the mass of the crazyflie, in [grams]
-float yaml_cf_mass_in_grams = 25.0;
-
-// > the frequency at which the controller is running
-float yaml_control_frequency = 200.0;
-
-// > the coefficients of the 16-bit command to thrust conversion
-//std::vector<float> yaml_motorPoly(3);
-std::vector<float> yaml_motorPoly = {5.484560e-4, 1.032633e-6, 2.130295e-11};
-
-
-// The min and max for saturating 16 bit thrust commands
-float yaml_command_sixteenbit_min = 1000;
-float yaml_command_sixteenbit_max = 60000;
-
-// > the default setpoint, the ordering is (x,y,z,yaw),
-//   with units [meters,meters,meters,radians]
-std::vector<float> yaml_default_setpoint = {0.0,0.0,0.4,0.0};
-
-// Boolean indiciating whether the "Debug Message" of this agent should be published or not
-bool yaml_shouldPublishDebugMessage = false;
-
-// Boolean indiciating whether the debugging ROS_INFO_STREAM should be displayed or not
-bool yaml_shouldDisplayDebugInfo = false;
-
-// The LQR Controller parameters for "LQR_RATE_MODE"
-std::vector<float> yaml_gainMatrixThrust_NineStateVector  =  { 0.00, 0.00, 0.98, 0.00, 0.00, 0.25, 0.00, 0.00, 0.00};
-std::vector<float> yaml_gainMatrixRollRate                =  { 0.00,-6.20, 0.00, 0.00,-3.00, 0.00, 5.20, 0.00, 0.00};
-std::vector<float> yaml_gainMatrixPitchRate               =  { 6.20, 0.00, 0.00, 3.00, 0.00, 0.00, 0.00, 5.20, 0.00};
-std::vector<float> yaml_gainMatrixYawRate                 =  { 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 2.30};
-
-
-
-// The weight of the Crazyflie in Newtons, i.e., mg
-float m_cf_weight_in_newtons = 0.0;
-
-// The location error of the Crazyflie at the "previous" time step
-float m_previous_stateErrorInertial[9];
-
-// The setpoint to be tracked, the ordering is (x,y,z,yaw),
-// with units [meters,meters,meters,radians]
-std::vector<float>  m_setpoint{0.0,0.0,0.4,0.0};
-
-
-
-
-// ROS Publisher for debugging variables
-ros::Publisher m_debugPublisher;
-
-// ROS Publisher for inform the network about
-// changes to the setpoin
-ros::Publisher m_setpointChangedPublisher;
-
 
 
 
@@ -211,27 +149,4 @@ ros::Publisher m_setpointChangedPublisher;
 // hence why the "main" function is at the bottom.
 
 // CONTROLLER COMPUTATIONS
-bool calculateControlOutput(Controller::Request &request, Controller::Response &response);
-
-// TRANSFORMATION OF THE (x,y) INERTIAL FRAME ERROR
-// INTO AN (x,y) BODY FRAME ERROR
-void convertIntoBodyFrame(float stateInertial[9], float (&stateBody)[9], float yaw_measured);
-
-// CONVERSION FROM THRUST IN NEWTONS TO 16-BIT COMMAND
-float computeMotorPolyBackward(float thrust);
-
-// REQUEST SETPOINT CHANGE CALLBACK
-void requestSetpointChangeCallback(const SetpointWithHeader& newSetpoint);
-
-// CHANGE SETPOINT FUNCTION
-void setNewSetpoint(float x, float y, float z, float yaw);
-
-// GET CURRENT SETPOINT SERVICE CALLBACK
-bool getCurrentSetpointCallback(GetSetpointService::Request &request, GetSetpointService::Response &response);
-
-// CUSTOM COMMAND RECEIVED CALLBACK
-void customCommandReceivedCallback(const CustomButtonWithHeader& commandReceived);
-
-// FOR LOADING THE YAML PARAMETERS
-void isReadyTemplateControllerYamlCallback(const IntWithHeader & msg);
-void fetchTemplateControllerYamlParameters(ros::NodeHandle& nodeHandle);
\ No newline at end of file
+bool calculateControlOutput(Controller::Request &request, Controller::Response &response);
\ No newline at end of file
diff --git a/dfall_ws/src/dfall_pkg/include/nodes/TuningControllerService.h b/dfall_ws/src/dfall_pkg/include/nodes/TuningControllerService.h
index 5534b1baa30f246f1f12df48770bcb77b184bc5f..cff8cd0ce3a893114031ecd0f50cfac2f18566a4 100644
--- a/dfall_ws/src/dfall_pkg/include/nodes/TuningControllerService.h
+++ b/dfall_ws/src/dfall_pkg/include/nodes/TuningControllerService.h
@@ -112,26 +112,6 @@
 
 // These constants are defined to make the code more readable and adaptable.
 
-// These constants define the modes that can be used for controller the Crazyflie 2.0,
-// the constants defined here need to be in agreement with those defined in the
-// firmware running on the Crazyflie 2.0.
-// The following is a short description about each mode:
-// MOTOR_MODE    In this mode the Crazyflie will apply the requested 16-bit per motor
-//               command directly to each of the motors
-// RATE_MODE     In this mode the Crazyflie will apply the requested 16-bit per motor
-//               command directly to each of the motors, and additionally request the
-//               body frame roll, pitch, and yaw angular rates from the PID rate
-//               controllers implemented in the Crazyflie 2.0 firmware.
-// ANGE_MODE     In this mode the Crazyflie will apply the requested 16-bit per motor
-//               command directly to each of the motors, and additionally request the
-//               body frame roll, pitch, and yaw angles from the PID attitude
-//               controllers implemented in the Crazyflie 2.0 firmware.
-
-#define CF_COMMAND_TYPE_MOTOR   6
-#define CF_COMMAND_TYPE_RATE    7
-#define CF_COMMAND_TYPE_ANGLE   8
-
-
 // These constants define the controller used for computing the response in the
 // "calculateControlOutput" function
 // The following is a short description about each mode:
@@ -436,23 +416,6 @@ int m_coordID;
 
 
 
-// RELEVANT NOTES ABOUT THE VARIABLES DECLARE HERE:
-// The "CrazyflieData" type used for the "request" variable is a
-// structure as defined in the file "CrazyflieData.msg" which has the following
-// properties:
-//     string crazyflieName              The name given to the Crazyflie in the Vicon software
-//     float64 x                         The x position of the Crazyflie [metres]
-//     float64 y                         The y position of the Crazyflie [metres]
-//     float64 z                         The z position of the Crazyflie [metres]
-//     float64 roll                      The roll component of the intrinsic Euler angles [radians]
-//     float64 pitch                     The pitch component of the intrinsic Euler angles [radians]
-//     float64 yaw                       The yaw component of the intrinsic Euler angles [radians]
-//     float64 acquiringTime #delta t    The time elapsed since the previous "CrazyflieData" was received [seconds]
-//     bool occluded                     A boolean indicted whether the Crazyflie for visible at the time of this measurement
-
-
-
-
 
 //    ----------------------------------------------------------------------------------
 //    FFFFF  U   U  N   N   CCCC  TTTTT  III   OOO   N   N
diff --git a/dfall_ws/src/dfall_pkg/launch/agent.launch b/dfall_ws/src/dfall_pkg/launch/agent.launch
index cccd6020e3fc39aedd190ba90a19c3bdce133683..0ed62bb46297b6ae7a1b30cb2974fcc45f5bd8bc 100755
--- a/dfall_ws/src/dfall_pkg/launch/agent.launch
+++ b/dfall_ws/src/dfall_pkg/launch/agent.launch
@@ -31,7 +31,16 @@
 				output = "screen"
 				type   = "CrazyRadio.py"
 				>
-				<rosparam command="load" file="$(find dfall_pkg)/param/BatteryMonitor.yaml" />
+				<rosparam
+					command = "load"
+					file    = "$(find dfall_pkg)/param/BatteryMonitor.yaml"
+					ns      = "CrazyRadioCopyOfBatteryMonitor"
+				/>
+				<rosparam
+					command = "load"
+					file    = "$(find dfall_pkg)/param/CrazyRadioConfig.yaml"
+					ns      = "CrazyRadioConfig"
+				/>
 			</node>
 		</group>
 		<group if="$(arg emulateRadio)">
@@ -41,7 +50,11 @@
 				output = "screen"
 				type   = "CrazyRadioEmulator"
 				>
-				<rosparam command="load" file="$(find dfall_pkg)/param/BatteryMonitor.yaml" />
+				<rosparam
+					command = "load"
+					file    = "$(find dfall_pkg)/param/CrazyRadioConfig.yaml"
+					ns      = "CrazyRadioConfig"
+				/>
 			</node>
 		</group>
 
@@ -147,6 +160,11 @@
 			>
 			<param name="type"     type="str"  value="agent" />
 			<param name="agentID"  value="$(arg agentID)" />
+			<rosparam
+				command = "load"
+				file    = "$(find dfall_pkg)/param/YamlFileNames.yaml"
+				ns      = "YamlFileNames"
+			/>
 			<rosparam
 				command = "load"
 				file    = "$(find dfall_pkg)/param/FlyingAgentClientConfig.yaml"
@@ -159,28 +177,13 @@
 			/>
 			<rosparam
 				command = "load"
-				file    = "$(find dfall_pkg)/param/SafeController.yaml"
-				ns      = "SafeController"
-			/>
-			<rosparam
-				command = "load"
-				file    = "$(find dfall_pkg)/param/RemoteController.yaml"
-				ns      = "RemoteController"
-			/>
-			<rosparam
-				command = "load"
-				file    = "$(find dfall_pkg)/param/TuningController.yaml"
-				ns      = "TuningController"
+				file    = "$(find dfall_pkg)/param/DefaultController.yaml"
+				ns      = "DefaultController"
 			/>
 			<rosparam
 				command = "load"
-				file    = "$(find dfall_pkg)/param/PickerController.yaml"
-				ns      = "PickerController"
-			/>
-			<rosparam
-				command = "load"
-				file    = "$(find dfall_pkg)/param/TemplateController.yaml"
-				ns      = "TemplateController"
+				file    = "$(find dfall_pkg)/param/StudentController.yaml"
+				ns      = "StudentController"
 			/>
 		</node>
 
@@ -193,10 +196,36 @@
 				output = "screen"
 				type   = "FlyingAgentGUI"
 				>
-				<param name="type"     type="str"  value="agent" />
-				<param name="agentID"  value="$(arg agentID)" />
+				<param
+					name="type"
+					type="str"
+					value="agent"
+				/>
+				<param
+					name="agentID"
+					value="$(arg agentID)"
+				/>
+				<param
+					name="onlaunch_shouldEmitPoseDataMocap"
+					type="bool"
+					value="true"
+				/>
+				<param
+					name="onlaunch_shouldEmitPoseDataOnboard"
+					type="bool"
+					value="false"
+				/>
 			</node>
 		</group>
+
+		<!-- AGENT STATUS FOR WEB INTERFACE -->
+		<node
+			pkg    = "dfall_pkg"
+			name   = "AgentStatusForWebInterface"
+			output = "screen"
+			type   = "AgentStatusForWebInterface"
+			>
+		</node>
 		
 	</group>
 
diff --git a/dfall_ws/src/dfall_pkg/launch/pi_agent.launch b/dfall_ws/src/dfall_pkg/launch/pi_agent.launch
new file mode 100755
index 0000000000000000000000000000000000000000..e54ae35197193d785326dce1ac3a01ab49bda64e
--- /dev/null
+++ b/dfall_ws/src/dfall_pkg/launch/pi_agent.launch
@@ -0,0 +1,153 @@
+<launch>
+
+	<!-- INPUT ARGUMENT OF THE AGENT's ID -->
+	<arg name="agentID" default="$(optenv DFALL_DEFAULT_AGENT_ID)" />
+
+	<!-- INPUT ARGUMENT OF THE COORDINATOR's ID -->
+	<arg name="coordID" default="$(optenv DFALL_DEFAULT_COORD_ID)" />
+
+	<!-- INPUT ARGUMENT FOR EMULATING THE CRAZY RADIO -->
+	<arg name="emulateRadio" default="false" />
+
+	<!-- Example of how to use the value in agentID -->
+    <!-- <param name="param" value="$(arg agentID)"/> -->
+
+    <!-- Example of how to specify the agentID from command line -->
+    <!-- roslaunch dfall_pkg agentID:=1 -->
+
+    <!-- Example of how to specify the withGUI from command line -->
+    <!-- roslaunch dfall_pkg withGUI:=false -->
+
+    <group ns="$(eval 'agent' + str(agentID).zfill(3))">
+
+		<!-- CRAZY RADIO -->
+		<group unless="$(arg emulateRadio)">
+			<node
+				pkg    = "dfall_pkg"
+				name   = "CrazyRadio"
+				output = "screen"
+				type   = "CrazyRadio.py"
+				>
+				<rosparam
+					command = "load"
+					file    = "$(find dfall_pkg)/param/BatteryMonitor.yaml"
+					ns      = "CrazyRadioCopyOfBatteryMonitor"
+				/>
+				<rosparam
+					command = "load"
+					file    = "$(find dfall_pkg)/param/CrazyRadioConfig.yaml"
+					ns      = "CrazyRadioConfig"
+				/>
+			</node>
+		</group>
+		<group if="$(arg emulateRadio)">
+			<node
+				pkg    = "dfall_pkg"
+				name   = "CrazyRadio"
+				output = "screen"
+				type   = "CrazyRadioEmulator"
+				>
+				<rosparam
+					command = "load"
+					file    = "$(find dfall_pkg)/param/CrazyRadioConfig.yaml"
+					ns      = "CrazyRadioConfig"
+				/>
+			</node>
+		</group>
+
+
+		<!-- FLYING AGENT CLIENT -->
+		<node
+			pkg    = "dfall_pkg"
+			name   = "FlyingAgentClient"
+			output = "screen"
+			type   = "FlyingAgentClient"
+			>
+			<param name="agentID" value="$(arg agentID)" />
+			<param name="coordID" value="$(arg coordID)" />
+		</node>
+
+		<!-- BATTERY MONITOR -->
+		<node
+			pkg    = "dfall_pkg"
+			name   = "BatteryMonitor"
+			output = "screen"
+			type   = "BatteryMonitor"
+			>
+		</node>
+
+		<!-- DEFAULT CONTROLLER -->
+		<node
+			pkg    = "dfall_pkg"
+			name   = "DefaultControllerService"
+			output = "screen"
+			type   = "DefaultControllerService"
+			>
+		</node>
+
+		<!-- STUDENT CONTROLLER -->
+		<node
+			pkg    = "dfall_pkg"
+			name   = "StudentControllerService"
+			output = "screen"
+			type   = "StudentControllerService"
+			>
+		</node>
+
+		<!-- TEST MOTORS CONTROLLER -->
+		<node
+			pkg    = "dfall_pkg"
+			name   = "TestMotorsControllerService"
+			output = "screen"
+			type   = "TestMotorsControllerService"
+			>
+		</node>
+
+		<!-- PARAMETER SERVICE -->
+		<node
+			pkg    = "dfall_pkg"
+			name   = "ParameterService"
+			output = "screen"
+			type   = "ParameterService"
+			>
+			<param name="type"     type="str"  value="agent" />
+			<param name="agentID"  value="$(arg agentID)" />
+			<rosparam
+				command = "load"
+				file    = "$(find dfall_pkg)/param/YamlFileNames.yaml"
+				ns      = "YamlFileNames"
+			/>
+			<rosparam
+				command = "load"
+				file    = "$(find dfall_pkg)/param/FlyingAgentClientConfig.yaml"
+				ns      = "FlyingAgentClientConfig"
+			/>
+			<rosparam
+				command = "load"
+				file    = "$(find dfall_pkg)/param/BatteryMonitor.yaml"
+				ns      = "BatteryMonitor"
+			/>
+			<rosparam
+				command = "load"
+				file    = "$(find dfall_pkg)/param/DefaultController.yaml"
+				ns      = "DefaultController"
+			/>
+			<rosparam
+				command = "load"
+				file    = "$(find dfall_pkg)/param/StudentController.yaml"
+				ns      = "StudentController"
+			/>
+		</node>
+
+		<!-- AGENT STATUS FOR WEB INTERFACE -->
+		<node
+			pkg    = "dfall_pkg"
+			name   = "AgentStatusForWebInterface"
+			output = "screen"
+			type   = "AgentStatusForWebInterface"
+			>
+		</node>
+
+	</group>
+
+</launch>
diff --git a/dfall_ws/src/dfall_pkg/launch/pi_master.launch b/dfall_ws/src/dfall_pkg/launch/pi_master.launch
new file mode 100755
index 0000000000000000000000000000000000000000..3165b14b65989eb9a2463611e0dad1b3d25f6588
--- /dev/null
+++ b/dfall_ws/src/dfall_pkg/launch/pi_master.launch
@@ -0,0 +1,40 @@
+<launch>
+
+	<!-- INPUT ARGUMENT FOR EMULATING THE MOTION CAPTURE -->
+	<arg name="emulateMocap" default="false" />
+
+	<!-- Example of how to specify the emulateMocap from command line -->
+    <!-- roslaunch dfall_pkg emulateMocap:=true -->
+
+	<!-- CENTRAL MANAGER -->
+	<node
+		pkg="dfall_pkg"
+		name="CentralManagerService"
+		output="screen"
+		type="CentralManagerService"
+		>
+	</node>
+
+	<!-- VICON DATA PUBLISHER -->
+	<group unless="$(arg emulateMocap)">
+		<node
+			pkg="dfall_pkg"
+			name="ViconDataPublisher"
+			output="screen"
+			type="ViconDataPublisher"
+			>
+			<rosparam command="load" file="$(find dfall_pkg)/param/ViconConfig.yaml" />
+		</node>
+	</group>
+	<group if="$(arg emulateMocap)">
+		<node
+			pkg="dfall_pkg"
+			name="ViconDataPublisher"
+			output="screen"
+			type="MocapEmulator"
+			>
+			<rosparam command="load" file="$(find dfall_pkg)/param/MocapEmulatorConfig.yaml" />
+		</node>
+	</group>
+
+</launch>
diff --git a/dfall_ws/src/dfall_pkg/msg/AreaBounds.msg b/dfall_ws/src/dfall_pkg/msg/AreaBounds.msg
index b367b15d881e07d6863e968894758df1abbdb421..5b82cabb545a104095e006efb460fa0d6669237f 100755
--- a/dfall_ws/src/dfall_pkg/msg/AreaBounds.msg
+++ b/dfall_ws/src/dfall_pkg/msg/AreaBounds.msg
@@ -4,5 +4,4 @@ float32 xmax
 float32 ymin
 float32 ymax
 float32 zmin
-float32 zmax
-
+float32 zmax
\ No newline at end of file
diff --git a/dfall_ws/src/dfall_pkg/msg/ControlCommand.msg b/dfall_ws/src/dfall_pkg/msg/ControlCommand.msg
index c75b1e2c646826cdccf6ddd23cec1f0a3f98d9a5..bf56eeb25bca68b2b4d1425b7b8c780c6fca8b20 100644
--- a/dfall_ws/src/dfall_pkg/msg/ControlCommand.msg
+++ b/dfall_ws/src/dfall_pkg/msg/ControlCommand.msg
@@ -1,9 +1,12 @@
-float32 roll
-float32 pitch
-float32 yaw
 uint16 motorCmd1
 uint16 motorCmd2
 uint16 motorCmd3
 uint16 motorCmd4
-uint8 onboardControllerType
-
+uint8 xControllerMode
+uint8 yControllerMode
+uint8 zControllerMode
+uint8 yawControllerMode
+float32 xControllerSetpoint
+float32 yControllerSetpoint
+float32 zControllerSetpoint
+float32 yawControllerSetpoint
\ No newline at end of file
diff --git a/dfall_ws/src/dfall_pkg/msg/CrazyflieContext.msg b/dfall_ws/src/dfall_pkg/msg/CrazyflieContext.msg
index 314275670853701f06ae18deb36ac18c139c4f2a..95974964c296edfe37dd85b0f1a34b1187bac7ee 100755
--- a/dfall_ws/src/dfall_pkg/msg/CrazyflieContext.msg
+++ b/dfall_ws/src/dfall_pkg/msg/CrazyflieContext.msg
@@ -1,3 +1,3 @@
 string crazyflieName
 string crazyflieAddress
-AreaBounds localArea
+AreaBounds localArea
\ No newline at end of file
diff --git a/dfall_ws/src/dfall_pkg/msg/CrazyflieDB.msg b/dfall_ws/src/dfall_pkg/msg/CrazyflieDB.msg
index a65dc00ec0ff10d42d5f97f88d6b3add6c2693d9..28ffc012bf7c1f8ee4f190a6442dc911e7c82318 100644
--- a/dfall_ws/src/dfall_pkg/msg/CrazyflieDB.msg
+++ b/dfall_ws/src/dfall_pkg/msg/CrazyflieDB.msg
@@ -1,2 +1 @@
-CrazyflieEntry[] crazyflieEntries
-
+CrazyflieEntry[] crazyflieEntries
\ No newline at end of file
diff --git a/dfall_ws/src/dfall_pkg/msg/CrazyflieData.msg b/dfall_ws/src/dfall_pkg/msg/CrazyflieData.msg
deleted file mode 100644
index 91ddb357d42ceee61cc6d88f76ee6d65633197e7..0000000000000000000000000000000000000000
--- a/dfall_ws/src/dfall_pkg/msg/CrazyflieData.msg
+++ /dev/null
@@ -1,9 +0,0 @@
-string crazyflieName
-float64 x
-float64 y
-float64 z
-float64 roll
-float64 pitch
-float64 yaw
-float64 acquiringTime #delta t
-bool occluded
diff --git a/dfall_ws/src/dfall_pkg/msg/CrazyflieEntry.msg b/dfall_ws/src/dfall_pkg/msg/CrazyflieEntry.msg
index 1bf527e228dcbd969357097a1bb37a6ff6f59af7..b8d7fd54b835c2ec23cd3e028da58bc6698767d6 100644
--- a/dfall_ws/src/dfall_pkg/msg/CrazyflieEntry.msg
+++ b/dfall_ws/src/dfall_pkg/msg/CrazyflieEntry.msg
@@ -1,3 +1,2 @@
 CrazyflieContext crazyflieContext
-uint32 studentID
-
+uint32 studentID
\ No newline at end of file
diff --git a/dfall_ws/src/dfall_pkg/msg/FlyingVehicleState.msg b/dfall_ws/src/dfall_pkg/msg/FlyingVehicleState.msg
new file mode 100644
index 0000000000000000000000000000000000000000..1e0b1c4ee9781e16d257712e03d4bd833d4d68ff
--- /dev/null
+++ b/dfall_ws/src/dfall_pkg/msg/FlyingVehicleState.msg
@@ -0,0 +1,16 @@
+uint32 type
+string vehicleName
+float64 x
+float64 y
+float64 z
+float64 vx
+float64 vy
+float64 vz
+float64 roll
+float64 pitch
+float64 yaw
+float64 rollRate
+float64 pitchRate
+float64 yawRate
+float64 acquiringTime #delta t
+bool isValid
\ No newline at end of file
diff --git a/dfall_ws/src/dfall_pkg/msg/GyroMeasurements.msg b/dfall_ws/src/dfall_pkg/msg/GyroMeasurements.msg
new file mode 100644
index 0000000000000000000000000000000000000000..79ec27399711444c0e6bbb3bf298b2ff2d69315a
--- /dev/null
+++ b/dfall_ws/src/dfall_pkg/msg/GyroMeasurements.msg
@@ -0,0 +1,4 @@
+string vehicleName
+float64 rollrate
+float64 pitchrate
+float64 yawrate
\ No newline at end of file
diff --git a/dfall_ws/src/dfall_pkg/msg/Setpoint.msg b/dfall_ws/src/dfall_pkg/msg/Setpoint.msg
index b3f94d9fbf6f8c0893c93e6e50e437a52bc71b6e..eb02bd5d08d8507d3de2b3df7ea3f7a61f13a7ea 100644
--- a/dfall_ws/src/dfall_pkg/msg/Setpoint.msg
+++ b/dfall_ws/src/dfall_pkg/msg/Setpoint.msg
@@ -1,4 +1,4 @@
 float64 x
 float64 y
 float64 z
-float64 yaw
+float64 yaw
\ No newline at end of file
diff --git a/dfall_ws/src/dfall_pkg/msg/UnlabeledMarker.msg b/dfall_ws/src/dfall_pkg/msg/UnlabeledMarker.msg
index c05b0c57394b6b2aa42c0e47fb51a3d9a6e32a83..a0b6cea0a09e4f9c1d26416146dce2602718aec2 100644
--- a/dfall_ws/src/dfall_pkg/msg/UnlabeledMarker.msg
+++ b/dfall_ws/src/dfall_pkg/msg/UnlabeledMarker.msg
@@ -1,4 +1,4 @@
 uint32 index
 float64 x
 float64 y
-float64 z
+float64 z
\ No newline at end of file
diff --git a/dfall_ws/src/dfall_pkg/msg/ViconData.msg b/dfall_ws/src/dfall_pkg/msg/ViconData.msg
index c263cdf9116fa84be514a184e4cd6b422308cb7c..ae8186553d2d9b9ef539d31c122e8b4b9d0fb4ff 100755
--- a/dfall_ws/src/dfall_pkg/msg/ViconData.msg
+++ b/dfall_ws/src/dfall_pkg/msg/ViconData.msg
@@ -1,3 +1,2 @@
-CrazyflieData[] crazyflies
-UnlabeledMarker[] markers
-
+FlyingVehicleState[] crazyflies
+UnlabeledMarker[] markers
\ No newline at end of file
diff --git a/dfall_ws/src/dfall_pkg/param/CrazyRadioConfig.yaml b/dfall_ws/src/dfall_pkg/param/CrazyRadioConfig.yaml
new file mode 100755
index 0000000000000000000000000000000000000000..58a5f31dc2a15f3bc00ced58fa91bf57ce4f8047
--- /dev/null
+++ b/dfall_ws/src/dfall_pkg/param/CrazyRadioConfig.yaml
@@ -0,0 +1,29 @@
+# Frequency of requesting the onboard state estimate, in [milliseconds]
+cfStateEstimate_polling_period: 20
+
+# Flag for whether to use height as a trigger for
+# publishing a motors-OFF command
+isEnabled_strictSafety: true
+maxHeight_for_strictSafety_meters: 1.8
+
+
+# ----------------------------------------------- #
+# THE FOLLOWING ARE USED FOR EMULATING A CRAZYFLIE:
+
+# SIMULATION FREQUENCY FOR EMULATING A CRAZYFLIE
+cfSimulation_frequency: 200
+
+# HOW OFTEN TO PUBLISH THE SIMULATION STATE AS AN
+# ONBOARD ESTIMATE
+# > i.e., this integer divided by the
+#   "cfSimulation_frequency" gives the simulation
+#    equivalent of "cfStateEstimate_polling_period"
+cfSimulation_stateEstimate_sendEvery: 4
+
+# QUADRATIC MOTOR REGRESSION EQUATION (a0, a1, a2)
+# > [Newtons] = a2 [cmd]^2 + a1 [cmd] + a0
+motorPoly : [5.484560e-4, 1.032633e-6, 2.130295e-11]
+
+# THE MIN AND MAX FOR SATURATING THE 16-BIT THRUST COMMANDS
+command_sixteenbit_min : 1000
+command_sixteenbit_max : 65000
\ No newline at end of file
diff --git a/dfall_ws/src/dfall_pkg/param/Crazyflie.db b/dfall_ws/src/dfall_pkg/param/Crazyflie.db
new file mode 100644
index 0000000000000000000000000000000000000000..90468eef837ca4d76cedd00054457304ade33888
--- /dev/null
+++ b/dfall_ws/src/dfall_pkg/param/Crazyflie.db
@@ -0,0 +1 @@
+1,CF01,0/0/2M/E7E7E7E701,0,-0.8,-0.8,-0.2,0.8,0.8,1.8
diff --git a/dfall_ws/src/dfall_pkg/param/DefaultController.yaml b/dfall_ws/src/dfall_pkg/param/DefaultController.yaml
index 2ae871658da4c35efa4ee54a1ac47f9f2245e164..a880a37cb6fa6a1e720be4a788377521c55f78b0 100644
--- a/dfall_ws/src/dfall_pkg/param/DefaultController.yaml
+++ b/dfall_ws/src/dfall_pkg/param/DefaultController.yaml
@@ -69,7 +69,7 @@ landing_spin_motors_time: 1.5
 mass : 30
 
 # Frequency of the controller, in [hertz]
-control_frequency : 200
+control_frequency : 50
 
 # Quadratic motor regression equation (a0, a1, a2)
 motorPoly : [5.484560e-4, 1.032633e-6, 2.130295e-11]
@@ -122,6 +122,9 @@ integratorGain_forTauYaw  :  0.05
 #       each of (x,y,z,roll,pitch,yaw)
 estimator_method : 1
 
+# Frequency of the estimator, in [hertz]
+estimator_frequency : 100
+
 # THE POINT MASS KALMAN FILTER (PMKF) GAINS AND ERROR EVOLUATION
 # > For the (x,y,z) position
 PMKF_Ahat_row1_for_positions  :  [  0.6723, 0.0034]
diff --git a/dfall_ws/src/dfall_pkg/param/FlyingAgentClientConfig.yaml b/dfall_ws/src/dfall_pkg/param/FlyingAgentClientConfig.yaml
index 6edb428394692da236ffb24a4c522657fb19c334..94b423c16324d79819f98455a74817a37970fa08 100755
--- a/dfall_ws/src/dfall_pkg/param/FlyingAgentClientConfig.yaml
+++ b/dfall_ws/src/dfall_pkg/param/FlyingAgentClientConfig.yaml
@@ -14,17 +14,22 @@ testMotorsController: "TestMotorsControllerService/TestMotorsController"
 # Controller for requests manoeuvres to be performed
 defaultController_requestManoeuvre: "DefaultControllerService/RequestManoeuvre"
 
+# Flags for which measurement streams to use
+shouldUse_mocapMeasurements: false
+shouldUse_onboardEstimate: true
+
 # Flag for whether to use angle for switching
 # to the Default Controller
 isEnabled_strictSafety: true
 maxTiltAngle_for_strictSafety_degrees: 70
 
-# Number of consecutive occulsions that will deem the
-# object as "long-term" occuled
-consecutive_occulsions_threshold: 30
+# Number of consecutive invalid measurements that
+# will deem the object as "long-term" unavailable
+consecutive_invalid_threshold: 30
 
-# Time out duration after which Mocap is considered unavailable
-mocap_timeout_duration: 2.0
+# Time out duration after which measurements are
+# considered unavailable
+measurement_timeout_duration: 2.0
 
 # Flag for whether the take-off should be performed
 # with the default controller
diff --git a/dfall_ws/src/dfall_pkg/param/MocapEmulatorConfig.yaml b/dfall_ws/src/dfall_pkg/param/MocapEmulatorConfig.yaml
index 898441b35b38134c07a687bf87ba38c3bd6b3251..633cacb786103403cd3949ed6ea6df1fcd88764d 100644
--- a/dfall_ws/src/dfall_pkg/param/MocapEmulatorConfig.yaml
+++ b/dfall_ws/src/dfall_pkg/param/MocapEmulatorConfig.yaml
@@ -1,5 +1,5 @@
 # FREQUENCY OF THE MOTION CAPTURE EMULATOR [Hertz]
-mocap_frequency : 200.0
+mocap_frequency : 100.0
 
 # QUADRATIC MOTOR REGRESSION EQUATION (a0, a1, a2)
 # > [Newtons] = a2 [cmd]^2 + a1 [cmd] + a0
diff --git a/dfall_ws/src/dfall_pkg/param/StudentController.yaml b/dfall_ws/src/dfall_pkg/param/StudentController.yaml
index 737fea73b48980c4701f4c8f15ec4a9f74d3e076..8a867e07c5b6a454d926ffb792ae4692a22b19e7 100644
--- a/dfall_ws/src/dfall_pkg/param/StudentController.yaml
+++ b/dfall_ws/src/dfall_pkg/param/StudentController.yaml
@@ -4,9 +4,11 @@ mass : 28
 # Frequency of the controller, in hertz
 control_frequency : 200
 
-# Quadratic motor regression equation (a0, a1, a2)
-motorPoly : [5.484560e-4, 1.032633e-6, 2.130295e-11]
-
 # The default setpoint, the ordering is (x,y,z,yaw),
 # with unit [meters,meters,meters,radians]
-default_setpoint : [0.0, 0.0, 0.4, 0.0]
\ No newline at end of file
+default_setpoint : [0.0, 0.0, 0.4, 0.0]
+
+# PID controller gain matrices
+proportionalgain_for_z : 4
+derivativegain_for_z : 1
+integralgain_for_z : 0.5
\ No newline at end of file
diff --git a/dfall_ws/src/dfall_pkg/param/YamlFileNames.yaml b/dfall_ws/src/dfall_pkg/param/YamlFileNames.yaml
index b61a3e84ba4f77f9e3e914e2d3741baeb4212d21..94ce721da5000f068ef9ec3f5581dc7565d3f456 100644
--- a/dfall_ws/src/dfall_pkg/param/YamlFileNames.yaml
+++ b/dfall_ws/src/dfall_pkg/param/YamlFileNames.yaml
@@ -1,4 +1,11 @@
-dictionary : {
-  'FlyingAgentClientConfig'   : 'FlyingAgentClientConfig' ,
-  'SafeController' : 'SafeController'
-}
+filenames : [
+  'BatteryMonitor',
+  'FlyingAgentClientConfig',
+  'CsoneControllerService',
+  'DefaultControllerService',
+  'PickerControllerService',
+  'RemoteControllerService',
+  'StudentControllerService',
+  'TemplateControllerService',
+  'TuningControllerService'
+]
diff --git a/dfall_ws/src/dfall_pkg/src/CrazyflieIO.cpp b/dfall_ws/src/dfall_pkg/src/classes/CrazyflieIO.cpp
similarity index 99%
rename from dfall_ws/src/dfall_pkg/src/CrazyflieIO.cpp
rename to dfall_ws/src/dfall_pkg/src/classes/CrazyflieIO.cpp
index 0f8625211fa2df7d2106313f89595d34c04a6c4b..a66320ce8aaed845ce9b1f9012aa15d845c40bd9 100644
--- a/dfall_ws/src/dfall_pkg/src/CrazyflieIO.cpp
+++ b/dfall_ws/src/dfall_pkg/src/classes/CrazyflieIO.cpp
@@ -36,7 +36,7 @@
 //    ----------------------------------------------------------------------------------
 
 
-#include "CrazyflieIO.h"
+#include "classes/CrazyflieIO.h"
 #include <stdlib.h>
 #include <ros/ros.h>
 #include <ros/package.h>
diff --git a/dfall_ws/src/dfall_pkg/src/classes/GetParamtersAndNamespaces.cpp b/dfall_ws/src/dfall_pkg/src/classes/GetParamtersAndNamespaces.cpp
index c0865950e3f37775a4998a69faf505e1a7942634..63e50c816c1214ba7efb80389d09ac8c6a11845d 100644
--- a/dfall_ws/src/dfall_pkg/src/classes/GetParamtersAndNamespaces.cpp
+++ b/dfall_ws/src/dfall_pkg/src/classes/GetParamtersAndNamespaces.cpp
@@ -78,79 +78,105 @@ std::string getParameterString(ros::NodeHandle& nodeHandle, std::string name)
 {
 	std::string val;
 	if(!nodeHandle.getParam(name, val)){
-        ROS_ERROR_STREAM("missing parameter '" << name << "'");
-    }
-    return val;
-}    
+		ROS_ERROR_STREAM("missing parameter '" << name << "'");
+	}
+	return val;
+}
 
 
 
 float getParameterFloat(ros::NodeHandle& nodeHandle, std::string name)
 {
-    float val;
-    if(!nodeHandle.getParam(name, val))
-    {
-        ROS_ERROR_STREAM("missing parameter '" << name << "'");
-    }
-    return val;
+	float val;
+	if(!nodeHandle.getParam(name, val))
+	{
+		ROS_ERROR_STREAM("missing parameter '" << name << "'");
+	}
+	return val;
 }
 
 
 
 int getParameterInt(ros::NodeHandle& nodeHandle, std::string name)
 {
-    int val;
-    if(!nodeHandle.getParam(name, val))
-    {
-        ROS_ERROR_STREAM("missing parameter '" << name << "'");
-    }
-    return val;
+	int val;
+	if(!nodeHandle.getParam(name, val))
+	{
+		ROS_ERROR_STREAM("missing parameter '" << name << "'");
+	}
+	return val;
 }
 
 
 
 bool getParameterBool(ros::NodeHandle& nodeHandle, std::string name)
 {
-    bool val;
-    if(!nodeHandle.getParam(name, val))
-    {
-        ROS_ERROR_STREAM("missing parameter '" << name << "'");
-    }
-    return val;
+	bool val;
+	if(!nodeHandle.getParam(name, val))
+	{
+		ROS_ERROR_STREAM("missing parameter '" << name << "'");
+	}
+	return val;
 }
 
 
 
-void getParameterFloatVector(ros::NodeHandle& nodeHandle, std::string name, std::vector<float>& val, int length)
+int getParameterStringVectorKnownLength(ros::NodeHandle& nodeHandle, std::string name, std::vector<std::string>& val, int length)
+{
+	if(!nodeHandle.getParam(name, val)){
+		ROS_ERROR_STREAM("missing parameter '" << name << "'");
+	}
+	if(val.size() != length) {
+		ROS_ERROR_STREAM("parameter '" << name << "' has wrong array length, " << length << " needed");
+	}
+}
+
+int getParameterStringVectorUnknownLength(ros::NodeHandle& nodeHandle, std::string name, std::vector<std::string>& val)
 {
-    if(!nodeHandle.getParam(name, val)){
-        ROS_ERROR_STREAM("missing parameter '" << name << "'");
-    }
-    if(val.size() != length) {
-        ROS_ERROR_STREAM("parameter '" << name << "' has wrong array length, " << length << " needed");
-    }
+	if(!nodeHandle.getParam(name, val)){
+		ROS_ERROR_STREAM("missing parameter '" << name << "'");
+	}
+	return val.size();
 }
 
 
 
-void getParameterIntVectorWithKnownLength(ros::NodeHandle& nodeHandle, std::string name, std::vector<int>& val, int length)
+void getParameterFloatVectorKnownLength(ros::NodeHandle& nodeHandle, std::string name, std::vector<float>& val, int length)
 {
-    if(!nodeHandle.getParam(name, val)){
-        ROS_ERROR_STREAM("missing parameter '" << name << "'");
-    }
-    if(val.size() != length) {
-        ROS_ERROR_STREAM("parameter '" << name << "' has wrong array length, " << length << " needed");
-    }
+	if(!nodeHandle.getParam(name, val)){
+		ROS_ERROR_STREAM("missing parameter '" << name << "'");
+	}
+	if(val.size() != length) {
+		ROS_ERROR_STREAM("parameter '" << name << "' has wrong array length, " << length << " needed");
+	}
 }
 
+int getParameterFloatVectorUnnownLength(ros::NodeHandle& nodeHandle, std::string name, std::vector<float>& val)
+{
+	if(!nodeHandle.getParam(name, val)){
+		ROS_ERROR_STREAM("missing parameter '" << name << "'");
+	}
+	return val.size();
+}
+
+
 
+void getParameterIntVectorWithKnownLength(ros::NodeHandle& nodeHandle, std::string name, std::vector<int>& val, int length)
+{
+	if(!nodeHandle.getParam(name, val)){
+		ROS_ERROR_STREAM("missing parameter '" << name << "'");
+	}
+	if(val.size() != length) {
+		ROS_ERROR_STREAM("parameter '" << name << "' has wrong array length, " << length << " needed");
+	}
+}
 
 int getParameterIntVectorWithUnknownLength(ros::NodeHandle& nodeHandle, std::string name, std::vector<int>& val)
 {
-    if(!nodeHandle.getParam(name, val)){
-        ROS_ERROR_STREAM("missing parameter '" << name << "'");
-    }
-    return val.size();
+	if(!nodeHandle.getParam(name, val)){
+		ROS_ERROR_STREAM("missing parameter '" << name << "'");
+	}
+	return val.size();
 }
 
 
@@ -242,4 +268,47 @@ bool checkMessageHeader( int agentID , bool shouldCheckForAgentID , const std::v
 	// If the function made it to here, then the message is
 	// NOT relevant, hence return false
 	return false;
+}
+
+//    ------------------------------------------------------------------------------
+//    N   N  EEEEE  W     W   TTTTT   OOO   N   N        CCCC  M   M  DDDD
+//    NN  N  E      W     W     T    O   O  NN  N       C      MM MM  D   D
+//    N N N  EEE    W     W     T    O   O  N N N  -->  C      M M M  D   D
+//    N  NN  E       W W W      T    O   O  N  NN       C      M   M  D   D
+//    N   N  EEEEE    W W       T     OOO   N   N        CCCC  M   M  DDDD
+//
+//     CCCC   OOO   N   N  V   V  EEEEE  RRRR    SSSS  III   OOO   N   N
+//    C      O   O  NN  N  V   V  E      R   R  S       I   O   O  NN  N
+//    C      O   O  N N N  V   V  EEE    RRRR    SSS    I   O   O  N N N
+//    C      O   O  N  NN   V V   E      R  R       S   I   O   O  N  NN
+//     CCCC   OOO   N   N    V    EEEEE  R   R  SSSS   III   OOO   N   N
+//    ----------------------------------------------------------------------------------
+
+
+// FUNCTION FOR CONVERTING NEWTON TO MOTOR COMMAND
+
+float newtons2cmd_for_crazyflie( float thrust)
+{
+	// Compute the 16-bit command that would produce the requested
+	// "thrust" based on the quadratic mapping that is described
+	// by the coefficients in the "yaml_motorPoly" variable.
+	static float motorPoly[3] = {5.484560e-4, 1.032633e-6, 2.130295e-11};
+
+	float cmd_16bit = (-motorPoly[1] + sqrt(motorPoly[1] * motorPoly[1] - 4 * motorPoly[2] * (motorPoly[0] - thrust))) / (2 * motorPoly[2]);
+
+	// Clip the cmd_16bit to avoid wrapping
+	if (cmd_16bit > 60000)
+	{
+		cmd_16bit = 60000;
+	}
+	else
+	{
+		if (cmd_16bit < 2000)
+		{
+			cmd_16bit = 0;
+		}
+	}
+
+	// Return the result
+	return cmd_16bit;	
 }
\ No newline at end of file
diff --git a/dfall_ws/src/dfall_pkg/src/classes/QuadrotorSimulator.cpp b/dfall_ws/src/dfall_pkg/src/classes/QuadrotorSimulator.cpp
index ff922c8fb7b3048a4ff5003280478d36cef5cf2a..b36f14648625c46374f8e9ee68fe48287412f18f 100644
--- a/dfall_ws/src/dfall_pkg/src/classes/QuadrotorSimulator.cpp
+++ b/dfall_ws/src/dfall_pkg/src/classes/QuadrotorSimulator.cpp
@@ -40,11 +40,27 @@
 
 
 
+// EMPTY CONSTRUCTOR
+QuadrotorSimulator::QuadrotorSimulator () :
+	m_gen_thrust( (std::random_device())() ),
+	m_dist_thrust(-0.03,0.03),
+	m_gen_body_x( (std::random_device())() ),
+	m_dist_body_x(-0.1,0.1),
+	m_gen_body_y( (std::random_device())() ),
+	m_dist_body_y(-0.1,0.1),
+	m_gen_body_z( (std::random_device())() ),
+	m_dist_body_z(-0.1,0.1)
+{
+	// Set the default ID string
+	this->set_id_string( "CF00" );
+	// Set the default mass
+	this->set_mass_in_kg( 0.032 );
+}
 
-
+// DEFAULT CONSTRUCTOR
 QuadrotorSimulator::QuadrotorSimulator ( std::string id ) :
 	m_gen_thrust( (std::random_device())() ),
-	m_dist_thrust(-0.02,0.02),
+	m_dist_thrust(-0.03,0.03),
 	m_gen_body_x( (std::random_device())() ),
 	m_dist_body_x(-0.1,0.1),
 	m_gen_body_y( (std::random_device())() ),
@@ -53,11 +69,14 @@ QuadrotorSimulator::QuadrotorSimulator ( std::string id ) :
 	m_dist_body_z(-0.1,0.1)
 {
 	// Set the input argument to the ID string
-	this->m_id_string = id;
+	this->set_id_string( id );
+	//this->m_id_string = id;
 	// Set the default mass
-	this->m_mass_in_kg = 0.032;
+	this->set_mass_in_kg( 0.032 );
+	//this->m_mass_in_kg = mass;
 }
 
+// PARAMETERIZED CONSTRUCTOR
 QuadrotorSimulator::QuadrotorSimulator ( std::string id , float mass ) :
 	m_gen_thrust( (std::random_device())() ),
 	m_dist_thrust(-0.1*mass*GRAVITY,0.1*mass*GRAVITY),
@@ -69,9 +88,9 @@ QuadrotorSimulator::QuadrotorSimulator ( std::string id , float mass ) :
 	m_dist_body_z(-0.1,0.1)
 {
 	// Set the input argument to the ID string
-	this->m_id_string = id;
+	this->set_id_string( id );
 	// Set the input argument to the mass
-	this->m_mass_in_kg = mass;
+	this->set_mass_in_kg( mass );
 }
 
 
@@ -92,6 +111,36 @@ QuadrotorSimulator::QuadrotorSimulator ( std::string id , float mass ) :
 //    ----------------------------------------------------------------------------------
 
 
+// Function to get the ID as a string
+std::string QuadrotorSimulator::get_id_string()
+{
+	return this->m_id_string;
+}
+
+// Function to set the ID as a string
+void QuadrotorSimulator::set_id_string(std::string new_id_string)
+{
+	this->m_id_string = new_id_string;
+}
+
+// Function to get the mass in kilograms
+float QuadrotorSimulator::get_mass_in_kg()
+{
+	return this->m_mass_in_kg;
+}
+
+// Function to set the mass in kilograms
+void QuadrotorSimulator::set_mass_in_kg(float new_mass_in_kg)
+{
+	this->m_mass_in_kg = new_mass_in_kg;
+}
+
+// Function to get the flying state
+bool QuadrotorSimulator::get_isFlying()
+{
+	return this->m_isFlying;
+}
+
 // Function to simulate the quadrotor for one time step
 void QuadrotorSimulator::simulate_for_one_time_step(float deltaT)
 {
@@ -201,6 +250,10 @@ void QuadrotorSimulator::simulate_for_one_time_step(float deltaT)
 		this->m_euler_angles[0] = new_roll;
 		this->m_euler_angles[1] = new_pitch;
 		this->m_euler_angles[2] = new_yaw;
+		// > For the Euler angular velocities
+		this->m_euler_velocities[0] = command_body_rate_x;
+		this->m_euler_velocities[1] = command_body_rate_y;
+		this->m_euler_velocities[2] = command_body_rate_z;
 
 
 
@@ -210,6 +263,8 @@ void QuadrotorSimulator::simulate_for_one_time_step(float deltaT)
 		{
 			// Reset the state
 			this->reset();
+			// Inform the user
+			ROS_INFO_STREAM("[QUADROTOR SIMULATOR] Quadrotor \"" << this->m_id_string << "\" reset due to roll or pitch exceeding 80 degrees." );
 		}
 
 	} // END OF: "if (this->m_isFlying)"
@@ -274,12 +329,6 @@ void QuadrotorSimulator::update_commanding_agent_id( int new_commanding_agent_id
 
 }
 
-// Function to get the flying state
-bool QuadrotorSimulator::getIsFlying()
-{
-	return this->m_isFlying;
-}
-
 // Function to set the reset state
 void QuadrotorSimulator::setResetState_xyz_yaw(float x, float y, float z, float yaw)
 {
@@ -322,33 +371,44 @@ void QuadrotorSimulator::print_details()
 void QuadrotorSimulator::control_commands_callback( const dfall_pkg::ControlCommand & msg )
 {
 	// Get the type of the command
-	int command_type = msg.onboardControllerType;
+	int x_mode   = msg.xControllerMode;
+	int y_mode   = msg.yControllerMode;
+	int z_mode   = msg.zControllerMode;
+	int yaw_mode = msg.yawControllerMode;
+
+	int command_type = 0;
+	if (
+		   (x_mode==CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE)
+		&& (y_mode==CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE)
+		&& (z_mode==CF_ONBOARD_CONTROLLER_MODE_OFF)
+		&& (yaw_mode==CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE)
+	)
+	{
+		command_type = 2;
+	}
+	if (
+		   (x_mode==CF_ONBOARD_CONTROLLER_MODE_OFF)
+		&& (y_mode==CF_ONBOARD_CONTROLLER_MODE_OFF)
+		&& (z_mode==CF_ONBOARD_CONTROLLER_MODE_OFF)
+		&& (yaw_mode==CF_ONBOARD_CONTROLLER_MODE_OFF)
+	)
+	{
+		command_type = 1;
+	}
+
 
 	// Switch based on the command type
 	// Adapt to the new state
 	switch(command_type)
 	{
-		case CF_COMMAND_TYPE_MOTORS:
+		case 1:
 		{
 			// Put the command into the class variables
 			this->update_current_control_command_rate(msg);
 			break;
 		}
-		case CF_COMMAND_TYPE_ANGLE:
-		{
-			if (this->m_isFlying)
-			{
-				// Set that the quadrotor is NOT flying
-				this->m_isFlying = false;
-				// Reset the state
-				this->reset();
-				// Inform the user
-				ROS_INFO_STREAM("[QUADROTOR SIMULATOR] Quadrotor \"" << this->m_id_string << "\" stopped simulating and reset becuase command is of type MOTORS or ANGLE");
-			}
-			break;
-		}
-
-		case CF_COMMAND_TYPE_RATE:
+		
+		case 2:
 		{
 			// Put the command into the class variables
 			this->update_current_control_command_rate(msg);
@@ -360,6 +420,20 @@ void QuadrotorSimulator::control_commands_callback( const dfall_pkg::ControlComm
 			//}
 			break;
 		}
+
+		default:
+		{
+			if (this->m_isFlying)
+			{
+				// Set that the quadrotor is NOT flying
+				this->m_isFlying = false;
+				// Reset the state
+				this->reset();
+				// Inform the user
+				ROS_INFO_STREAM("[QUADROTOR SIMULATOR] Quadrotor \"" << this->m_id_string << "\" stopped simulating and reset becuase command is NOT of type MOTORS or ANGULAR_RATE");
+			}
+			break;
+		}
 	}
 }
 
@@ -377,9 +451,9 @@ void QuadrotorSimulator::update_current_control_command_rate( const dfall_pkg::C
 	this->m_current_command_total_thurst = cmd1_in_newtons + cmd2_in_newtons + cmd3_in_newtons + cmd4_in_newtons;
 
 	// Update the body rate commands
-	this->m_current_command_body_rate_x = msg.roll;
-	this->m_current_command_body_rate_y = msg.pitch;
-	this->m_current_command_body_rate_z = msg.yaw;
+	this->m_current_command_body_rate_x = msg.yControllerSetpoint;
+	this->m_current_command_body_rate_y = msg.xControllerSetpoint;
+	this->m_current_command_body_rate_z = msg.yawControllerSetpoint;
 }
 
 // Callback for receiving flying state updates
diff --git a/dfall_ws/src/dfall_pkg/src/nodes/AgentStatusForWebInterface.cpp b/dfall_ws/src/dfall_pkg/src/nodes/AgentStatusForWebInterface.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..612fd244f8fed4808e77624b15091a7e1964784b
--- /dev/null
+++ b/dfall_ws/src/dfall_pkg/src/nodes/AgentStatusForWebInterface.cpp
@@ -0,0 +1,521 @@
+//    Copyright (C) 2020, The University of Melbourne, Department of Electrical and Electronic Engineering (EEE), Paul Beuchat
+//
+//    This file is part of D-FaLL-System.
+//    
+//    D-FaLL-System is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//    
+//    D-FaLL-System is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//    
+//    You should have received a copy of the GNU General Public License
+//    along with D-FaLL-System.  If not, see <http://www.gnu.org/licenses/>.
+//    
+//
+//    ----------------------------------------------------------------------------------
+//    DDDD        FFFFF        L     L           SSSS  Y   Y   SSSS  TTTTT  EEEEE  M   M
+//    D   D       F      aaa   L     L          S       Y Y   S        T    E      MM MM
+//    D   D  ---  FFFF  a   a  L     L     ---   SSS     Y     SSS     T    EEE    M M M
+//    D   D       F     a  aa  L     L              S    Y        S    T    E      M   M
+//    DDDD        F      aa a  LLLL  LLLL       SSSS     Y    SSSS     T    EEEEE  M   M
+//
+//
+//    DESCRIPTION:
+//    The service that provides data to the web interface
+//
+//    ----------------------------------------------------------------------------------
+
+
+
+
+
+// INCLUDE THE HEADER
+#include "nodes/AgentStatusForWebInterface.h"
+
+
+
+
+
+
+
+
+
+
+
+//    ----------------------------------------------------------------------------------
+//    FFFFF  U   U  N   N   CCCC  TTTTT  III   OOO   N   N
+//    F      U   U  NN  N  C        T     I   O   O  NN  N
+//    FFF    U   U  N N N  C        T     I   O   O  N N N
+//    F      U   U  N  NN  C        T     I   O   O  N  NN
+//    F       UUU   N   N   CCCC    T    III   OOO   N   N
+//
+//    III M   M PPPP  L     EEEEE M   M EEEEE N   N TTTTT   A   TTTTT III  OOO  N   N
+//     I  MM MM P   P L     E     MM MM E     NN  N   T    A A    T    I  O   O NN  N
+//     I  M M M PPPP  L     EEE   M M M EEE   N N N   T   A   A   T    I  O   O N N N
+//     I  M   M P     L     E     M   M E     N  NN   T   AAAAA   T    I  O   O N  NN
+//    III M   M P     LLLLL EEEEE M   M EEEEE N   N   T   A   A   T   III  OOO  N   N
+//    ----------------------------------------------------------------------------------
+
+
+
+// CALLBACKS FOR MESSAGES WITH THE STATUS OF THINGS
+
+// > For the status of the crazyradio
+void crazyRadioStatusCallback(const std_msgs::Int32& msg)
+{
+	m_crazyradio_status = msg.data;
+}
+
+// > For the battery level
+void newBatteryLevelCallback(const std_msgs::Int32& msg)
+{
+	m_battery_level = msg.data;
+}
+
+// > For the flying state of the agent
+void agentOperatingStateCallback(const std_msgs::Int32& msg)
+{
+	m_agent_operating_state = msg.data;
+}
+
+// > For the instant controller
+void instantControllerChangedCallback(const std_msgs::Int32& msg)
+{
+	m_instant_controller = msg.data;
+}
+
+// > For the Default Controller Setpoint
+void defaultControllerSetpointChangedCallback(const SetpointWithHeader& newSetpoint)
+{
+    m_setpoint_default[0] = newSetpoint.x;
+    m_setpoint_default[1] = newSetpoint.y;
+    m_setpoint_default[2] = newSetpoint.z;
+    m_setpoint_default[3] = newSetpoint.yaw;
+}
+
+// > For the Student Controller Setpoint
+void studentControllerSetpointChangedCallback(const SetpointWithHeader& newSetpoint)
+{
+    m_setpoint_student[0] = newSetpoint.x;
+    m_setpoint_student[1] = newSetpoint.y;
+    m_setpoint_student[2] = newSetpoint.z;
+    m_setpoint_student[3] = newSetpoint.yaw;
+}
+
+// > For the Student Controller Debug Values
+void studentControllerDebugValuesCallback(const DebugMsg& newDebugMsg)
+{
+    m_debug_values_student[0] = newDebugMsg.value_1;
+    m_debug_values_student[1] = newDebugMsg.value_2;
+    m_debug_values_student[2] = newDebugMsg.value_3;
+    m_debug_values_student[3] = newDebugMsg.value_4;
+    m_debug_values_student[4] = newDebugMsg.value_5;
+    m_debug_values_student[5] = newDebugMsg.value_6;
+    m_debug_values_student[6] = newDebugMsg.value_7;
+    m_debug_values_student[7] = newDebugMsg.value_8;
+    m_debug_values_student[8] = newDebugMsg.value_9;
+    m_debug_values_student[9] = newDebugMsg.value_10;
+}
+
+// > For the State Estimate from the Crazyflie
+void cfStateEstimateCallback(const FlyingVehicleState & newStateEstimate)
+{
+	// > For (x,y,z) positions
+	m_cf_state_estimate_xyz_rpy[0] = newStateEstimate.x;
+	m_cf_state_estimate_xyz_rpy[1] = newStateEstimate.y;
+	m_cf_state_estimate_xyz_rpy[2] = newStateEstimate.z;
+	// > For (roll,pitch,yaw) orientation
+	m_cf_state_estimate_xyz_rpy[3] = newStateEstimate.roll;
+	m_cf_state_estimate_xyz_rpy[4] = newStateEstimate.pitch;
+	m_cf_state_estimate_xyz_rpy[5] = newStateEstimate.yaw;
+}
+
+
+
+
+
+// SERVICE CALLBACK FOR PROVIDING STATUS TO THE WEB INTERFACE
+bool statusForWebInterfaceCallback(IntStringService::Request &request, IntStringService::Response &response)
+{
+	// Get the CrazyRadio status as a string
+	std::string crazyradio_status_string;
+	switch (m_crazyradio_status)
+	{
+		case CRAZY_RADIO_STATE_CONNECTED:
+		{
+			crazyradio_status_string = "connected";
+			break;
+		}
+		case CRAZY_RADIO_STATE_CONNECTING:
+		{
+			crazyradio_status_string = "connecting";
+			break;
+		}
+		case CRAZY_RADIO_STATE_DISCONNECTED:
+		{
+			crazyradio_status_string = "disconnected";
+			break;
+		}
+		default:
+		{
+			crazyradio_status_string = "unknown";
+			break;
+		}
+	}
+
+
+	// Get the Battery level as a string
+	std::string battery_level_string;
+	switch (m_battery_level)
+	{
+		case BATTERY_LEVEL_000:
+		{
+			battery_level_string = "000";
+			break;
+		}
+		case BATTERY_LEVEL_010:
+		{
+			battery_level_string = "010";
+			break;
+		}
+		case BATTERY_LEVEL_020:
+		{
+			battery_level_string = "020";
+			break;
+		}
+		case BATTERY_LEVEL_030:
+		{
+			battery_level_string = "030";
+			break;
+		}
+		case BATTERY_LEVEL_040:
+		{
+			battery_level_string = "040";
+			break;
+		}
+		case BATTERY_LEVEL_050:
+		{
+			battery_level_string = "050";
+			break;
+		}
+		case BATTERY_LEVEL_060:
+		{
+			battery_level_string = "060";
+			break;
+		}
+		case BATTERY_LEVEL_070:
+		{
+			battery_level_string = "070";
+			break;
+		}
+		case BATTERY_LEVEL_080:
+		{
+			battery_level_string = "080";
+			break;
+		}
+		case BATTERY_LEVEL_090:
+		{
+			battery_level_string = "090";
+			break;
+		}
+		case BATTERY_LEVEL_100:
+		{
+			battery_level_string = "100";
+			break;
+		}
+		case BATTERY_LEVEL_UNAVAILABLE:
+		{
+			battery_level_string = "unavailable";
+			break;
+		}
+		default:
+		{
+			battery_level_string = "unavailable";
+			break;
+		}
+	}
+
+	// Get the Flying status as a string
+	std::string flying_state_string;
+	switch (m_agent_operating_state)
+	{
+		case STATE_MOTORS_OFF:
+		{
+			flying_state_string = "motorsoff";
+			break;
+		}
+		case STATE_TAKE_OFF:
+		{
+			flying_state_string = "takeoff";
+			break;
+		}
+		case STATE_FLYING:
+		{
+			flying_state_string = "flying";
+			break;
+		}
+		case STATE_LAND:
+		{
+			flying_state_string = "land";
+			break;
+		}
+		case STATE_UNAVAILABLE:
+		{
+			flying_state_string = "unavailable";
+			break;
+		}
+		default:
+		{
+			flying_state_string = "unavailable";
+			break;
+		}
+	}
+
+	// Get the Flying status as a string
+	std::string instant_controller_string;
+	switch (m_instant_controller)
+	{
+		case DEFAULT_CONTROLLER:
+		{
+			instant_controller_string = "default";
+			break;
+		}
+		case DEMO_CONTROLLER:
+		{
+			instant_controller_string = "demo";
+			break;
+		}
+		case STUDENT_CONTROLLER:
+		{
+			instant_controller_string = "student";
+			break;
+		}
+		case MPC_CONTROLLER:
+		{
+			instant_controller_string = "mpc";
+			break;
+		}
+		case REMOTE_CONTROLLER:
+		{
+			instant_controller_string = "remote";
+			break;
+		}
+		case TUNING_CONTROLLER:
+		{
+			instant_controller_string = "tuning";
+			break;
+		}
+		case PICKER_CONTROLLER:
+		{
+			instant_controller_string = "picker";
+			break;
+		}
+		case TEMPLATE_CONTROLLER:
+		{
+			instant_controller_string = "template";
+			break;
+		}
+		case CSONE_CONTROLLER:
+		{
+			instant_controller_string = "csone";
+			break;
+		}
+		case TESTMOTORS_CONTROLLER:
+		{
+			instant_controller_string = "testmotors";
+			break;
+		}
+		default:
+		{
+			instant_controller_string = "none";
+			break;
+		}
+	}
+
+	// Concatenate the json together using a string stream
+	std::stringstream ss;
+	ss << "{";
+	ss << "\u0022crazyradiostatus\u0022: \u0022" << crazyradio_status_string << "\u0022";
+	ss << " , ";
+	ss << "\u0022batterylevel\u0022: \u0022" << battery_level_string << "\u0022";
+	ss << " , ";
+	ss << "\u0022flyingstate\u0022: \u0022" << flying_state_string << "\u0022";
+	ss << " , ";
+	ss << "\u0022instantcontroller\u0022: \u0022" << instant_controller_string << "\u0022";
+	ss << " , ";
+	ss << "\u0022setpointdefault\u0022:";
+	ss << "{";
+	ss << "\u0022x\u0022: " << std::setprecision(3) << std::fixed << m_setpoint_default[0];
+	ss << " , ";
+	ss << "\u0022y\u0022: " << std::setprecision(3) << std::fixed << m_setpoint_default[1];
+	ss << " , ";
+	ss << "\u0022z\u0022: " << std::setprecision(3) << std::fixed << m_setpoint_default[2];
+	ss << " , ";
+	ss << "\u0022yaw\u0022: " << std::setprecision(1) << std::fixed << m_setpoint_default[3]*RAD2DEG;
+	ss << "}";
+	ss << " , ";
+	ss << "\u0022setpointstudent\u0022:";
+	ss << "{";
+	ss << "\u0022x\u0022: " << std::setprecision(3) << std::fixed << m_setpoint_student[0];
+	ss << " , ";
+	ss << "\u0022y\u0022: " << std::setprecision(3) << std::fixed << m_setpoint_student[1];
+	ss << " , ";
+	ss << "\u0022z\u0022: " << std::setprecision(3) << std::fixed << m_setpoint_student[2];
+	ss << " , ";
+	ss << "\u0022yaw\u0022: " << std::setprecision(1) << std::fixed << m_setpoint_student[3]*RAD2DEG;
+	ss << "}";
+	ss << " , ";
+	ss << "\u0022stateestimate\u0022:";
+	ss << "{";
+	ss << "\u0022x\u0022: " << std::setprecision(3) << std::fixed << m_cf_state_estimate_xyz_rpy[0];
+	ss << " , ";
+	ss << "\u0022y\u0022: " << std::setprecision(3) << std::fixed << m_cf_state_estimate_xyz_rpy[1];
+	ss << " , ";
+	ss << "\u0022z\u0022: " << std::setprecision(3) << std::fixed << m_cf_state_estimate_xyz_rpy[2];
+	ss << " , ";
+	ss << "\u0022roll\u0022: "  << std::setprecision(1) << std::fixed << m_cf_state_estimate_xyz_rpy[3]*RAD2DEG;
+	ss << " , ";
+	ss << "\u0022pitch\u0022: " << std::setprecision(1) << std::fixed << m_cf_state_estimate_xyz_rpy[4]*RAD2DEG;
+	ss << " , ";
+	ss << "\u0022yaw\u0022: "   << std::setprecision(1) << std::fixed << m_cf_state_estimate_xyz_rpy[5]*RAD2DEG;
+	ss << "}";
+	ss << " , ";
+	ss << "\u0022debugvaluesstudent\u0022:";
+	ss << "{";
+	ss << "\u0022value1\u0022: "  << std::setprecision(3) << std::fixed << m_debug_values_student[0];
+	ss << " , ";
+	ss << "\u0022value2\u0022: "  << std::setprecision(3) << std::fixed << m_debug_values_student[1];
+	ss << " , ";
+	ss << "\u0022value3\u0022: "  << std::setprecision(3) << std::fixed << m_debug_values_student[2];
+	ss << " , ";
+	ss << "\u0022value4\u0022: "  << std::setprecision(3) << std::fixed << m_debug_values_student[3];
+	ss << " , ";
+	ss << "\u0022value5\u0022: "  << std::setprecision(3) << std::fixed << m_debug_values_student[4];
+	ss << " , ";
+	ss << "\u0022value6\u0022: "  << std::setprecision(3) << std::fixed << m_debug_values_student[5];
+	ss << " , ";
+	ss << "\u0022value7\u0022: "  << std::setprecision(3) << std::fixed << m_debug_values_student[6];
+	ss << " , ";
+	ss << "\u0022value8\u0022: "  << std::setprecision(3) << std::fixed << m_debug_values_student[7];
+	ss << " , ";
+	ss << "\u0022value9\u0022: "  << std::setprecision(3) << std::fixed << m_debug_values_student[8];
+	ss << " , ";
+	ss << "\u0022value10\u0022: " << std::setprecision(3) << std::fixed << m_debug_values_student[9];
+	ss << "}";
+	ss << "}";
+
+	//std::string s = ss.str();
+	// Put the string into the response
+	//response.data = "test of service for web interface";
+	//response.data = "{\"crazyradiostatus\": \"%d\"}", m_crazyradio_status;
+	response.data = ss.str();
+
+	// Return success
+	return true;
+}
+
+
+
+
+//    ----------------------------------------------------------------------------------
+//    M   M    A    III  N   N
+//    MM MM   A A    I   NN  N
+//    M M M  A   A   I   N N N
+//    M   M  AAAAA   I   N  NN
+//    M   M  A   A  III  N   N
+//    ----------------------------------------------------------------------------------
+
+int main(int argc, char* argv[])
+{
+	// Starting the ROS-node
+	ros::init(argc, argv, "AgentStatusForWebInterface");
+
+	// Create a "ros::NodeHandle" type local variable "nodeHandle"
+	// as the current node, the "~" indcates that "self" is the
+	// node handle assigned to this variable.
+	ros::NodeHandle nodeHandle("~");
+
+	// Get the namespace of this "AgentStatusForWebInterface" node
+	std::string m_namespace = ros::this_node::getNamespace();
+	ROS_INFO_STREAM("[AGENT STATUS FOR WEB INTERFACE] ros::this_node::getNamespace() =  " << m_namespace);
+
+
+
+
+
+	// SUBSCRIBERS
+
+	// FOR THE CRAZY RADIO STATUS:
+	// > Get a node handle to the Crazy Radio
+	std::string namespace_to_crazyradio = m_namespace + "/CrazyRadio";
+	ros::NodeHandle nodeHandle_to_crazyradio(namespace_to_crazyradio);
+	// > Subscribe to the topic
+	ros::Subscriber crazyRadioStatusSubscriber = nodeHandle_to_crazyradio.subscribe("CrazyRadioStatus", 1, crazyRadioStatusCallback);
+
+	// FOR THE BATTERY LEVEL
+	// > Get a node handle to the Battery Monitor
+	std::string namespace_to_BatteryMonitor = m_namespace + "/BatteryMonitor";
+	ros::NodeHandle nodeHandle_to_BatteryMonitor(namespace_to_BatteryMonitor);
+	// > Subscribe to the topic
+	ros::Subscriber newBatteryLevelSubscriber = nodeHandle_to_BatteryMonitor.subscribe("Level", 1, newBatteryLevelCallback);
+
+	// FOR THE FLYING STATE OF THE AGENT
+	// > Get a node handle to the Flying Agent Client
+	std::string namespace_to_FlyingAgentClient = m_namespace + "/FlyingAgentClient";
+	ros::NodeHandle nodeHandle_to_FlyingAgentClient(namespace_to_FlyingAgentClient);
+	// > Subscribe to the topic
+	ros::Subscriber agentOperatingStateSubscriber = nodeHandle_to_FlyingAgentClient.subscribe("FlyingState", 1, agentOperatingStateCallback);
+
+	// FOR THE INSTANT CONTROLLER
+	// > Subscribe to the topic
+	ros::Subscriber instantControllerSubscriber = nodeHandle_to_FlyingAgentClient.subscribe("ControllerUsed", 1, instantControllerChangedCallback);
+
+	// FOR THE DEFAULT CONTROLLER SETPOINT
+	// > Get a node handle to the Default Controller Service
+	std::string namespace_to_DefaultController = m_namespace + "/DefaultControllerService";
+	ros::NodeHandle nodeHandle_to_DefaultController(namespace_to_DefaultController);
+	// > Subscribe to the topic
+	ros::Subscriber defaultControllerSetpointChangedSubscriber = nodeHandle_to_DefaultController.subscribe("SetpointChanged", 1, defaultControllerSetpointChangedCallback);
+
+	// FOR THE STUDENT CONTROLLER SETPOINT
+	// > Get a node handle to the Student Controller Service
+	std::string namespace_to_StudentController = m_namespace + "/StudentControllerService";
+	ros::NodeHandle nodeHandle_to_StudentController(namespace_to_StudentController);
+	// > Subscribe to the topic
+	ros::Subscriber studentControllerSetpointChangedSubscriber = nodeHandle_to_StudentController.subscribe("SetpointChanged", 1, studentControllerSetpointChangedCallback);
+
+	// FOR THE DEBUG VALUES OF THE STUDENT CONTROLLER
+	// > Subscribe to the topic
+	ros::Subscriber studentControllerDebugValuesSubscriber = nodeHandle_to_StudentController.subscribe("DebugTopic", 1, studentControllerDebugValuesCallback);
+
+	// FOR THE STATE ESTIMATE FROM THE CRAZYFLIE
+	// > Get a node handle to the Crazy Radio node
+	std::string namespace_to_CrazyRadio = m_namespace + "/CrazyRadio";
+	ros::NodeHandle nodeHandle_to_CrazyRadio(namespace_to_CrazyRadio);
+	// > Subscribe to the topic
+	ros::Subscriber cfStateEstimateSubscriber = nodeHandle_to_CrazyRadio.subscribe("CFStateEstimate", 1, cfStateEstimateCallback);
+
+
+
+
+
+	// SERVICE SERVERS
+
+	// Service callback for provide status to the Web Interface
+	ros::ServiceServer statusForWebInterfaceService = nodeHandle.advertiseService("StatusAsJson", statusForWebInterfaceCallback);
+
+
+
+
+
+	// Inform the user the this node is ready
+	ROS_INFO("[AGENT STATUS FOR WEB INTERFACE] Ready :-)");
+	// Spin as a single-thread node
+	ros::spin();
+
+	return 0;
+}
diff --git a/dfall_ws/src/dfall_pkg/src/nodes/BatteryMonitor.cpp b/dfall_ws/src/dfall_pkg/src/nodes/BatteryMonitor.cpp
index 93f5a305abf457a3f457884c29998b656dedb357..748c5c374d5794b5c31974886337662eb49ca329 100644
--- a/dfall_ws/src/dfall_pkg/src/nodes/BatteryMonitor.cpp
+++ b/dfall_ws/src/dfall_pkg/src/nodes/BatteryMonitor.cpp
@@ -488,7 +488,11 @@ int main(int argc, char* argv[])
 
 	// FETCH ANY PARAMETERS REQUIRED FROM THE "PARAMETER SERVICES"
 
-	// Call the class function that loads the parameters for this class.
+	// Call the class function that loads the parameters
+	// from the "BatteryMonitor.yaml" file.
+	// > This is possible because that YAML file is added
+	//   to the parameter service when launched via the
+	//   "agent.launch" file.
 	fetchBatteryMonitorYamlParameters(nodeHandle_to_own_agent_parameter_service);
 
 
diff --git a/dfall_ws/src/dfall_pkg/src/nodes/CrazyRadioEmulator.cpp b/dfall_ws/src/dfall_pkg/src/nodes/CrazyRadioEmulator.cpp
index f056425244ab54703064bec427a62bf31c07f615..6ce70b498bafb2d42bcd365c82b022f26ea350c2 100644
--- a/dfall_ws/src/dfall_pkg/src/nodes/CrazyRadioEmulator.cpp
+++ b/dfall_ws/src/dfall_pkg/src/nodes/CrazyRadioEmulator.cpp
@@ -142,6 +142,9 @@ void connected_callback(const ros::TimerEvent&)
 
 	// Start the battery voltage updates
 	m_timer_battery_voltage_updates.start();
+
+	// Start the state estimate updates
+	m_timer_state_estimate_update.start();
 }
 
 void connection_failed()
@@ -152,6 +155,8 @@ void connection_failed()
 	change_radio_state_to(CRAZY_RADIO_STATE_DISCONNECTED);
 	// Stop the battery voltage updates
 	m_timer_battery_voltage_updates.stop();
+	// Stop the state estimate updates
+	m_timer_state_estimate_update.stop();
 }
 
 void connection_lost()
@@ -162,6 +167,8 @@ void connection_lost()
 	change_radio_state_to(CRAZY_RADIO_STATE_DISCONNECTED);
 	// Stop the battery voltage updates
 	m_timer_battery_voltage_updates.stop();
+	// Stop the state estimate updates
+	m_timer_state_estimate_update.stop();
 }
 
 
@@ -170,9 +177,10 @@ void disconnected_callback(const ros::TimerEvent&)
 {
 	// Update status to DISCONNECTED
 	change_radio_state_to(CRAZY_RADIO_STATE_DISCONNECTED);
-
 	// Stop the battery voltage updates
 	m_timer_battery_voltage_updates.stop();
+	// Stop the state estimate updates
+	m_timer_state_estimate_update.stop();
 }
 
 
@@ -261,7 +269,7 @@ bool getCurrentCrazyRadioStatusServiceCallback(IntIntService::Request &request,
 }
 
 
-void update_battery_voltage_callback(const ros::TimerEvent&)
+void timerCallback_update_battery_voltage(const ros::TimerEvent&)
 {
 	// Declare static paramters for the voltage
 	static float voltage_current = 4.2;
@@ -286,6 +294,84 @@ void update_battery_voltage_callback(const ros::TimerEvent&)
 
 
 
+void timerCallback_update_cfStateEstimate(const ros::TimerEvent&)
+{
+	// Declare static counter for publshing the state estimates
+	static int counter_since_last_send = 3;
+
+	// Increment the counter
+	counter_since_last_send++;
+
+	// Simulate the quadrotor for one time step
+	m_quadrotor_sim.simulate_for_one_time_step( yaml_cfSimulation_deltaT_in_seconds );
+
+	// Perform safety check if required
+	if (yaml_isEnabled_strictSafety)
+	{
+		// Estimate the height at the next measurement
+		float height_at_next_measurement = m_quadrotor_sim.m_position[2] + yaml_cfSimulation_deltaT_in_seconds * m_quadrotor_sim.m_velocity[2];
+		// Turn-off if too high
+		if (height_at_next_measurement > yaml_maxHeight_for_strictSafety_meters)
+		{
+			// Send the MOTORS-OFF command to the Flying Agent Client
+			IntWithHeader msg;
+			msg.shouldCheckForAgentID = false;
+			msg.data = CMD_CRAZYFLY_MOTORS_OFF;
+			flyingAgentClientCommandPublisher.publish(msg);
+			// Inform the user
+			ROS_ERROR_STREAM("[CRAZY RADIO] Height safety check failed, measured = " << height_at_next_measurement << ", max allowed = " << yaml_maxHeight_for_strictSafety_meters );
+		}
+	}
+
+	// Local variable for the data of this quadrotor
+	FlyingVehicleState quadrotor_data;
+
+	// Fill in the details
+	// > For the type
+	quadrotor_data.type = FLYING_VEHICLE_STATE_TYPE_CRAZYFLIE_STATE_ESTIMATE;
+	// > For the name
+	quadrotor_data.vehicleName = m_quadrotor_sim.get_id_string();
+	// > For the occulsion flag
+	quadrotor_data.isValid = true;
+	// > For position
+	quadrotor_data.x = m_quadrotor_sim.m_position[0];
+	quadrotor_data.y = m_quadrotor_sim.m_position[1];
+	quadrotor_data.z = m_quadrotor_sim.m_position[2];
+	// > For velocities
+	quadrotor_data.vx = m_quadrotor_sim.m_velocity[0];
+	quadrotor_data.vy = m_quadrotor_sim.m_velocity[1];
+	quadrotor_data.vz = m_quadrotor_sim.m_velocity[2];
+	// > For euler angles
+	quadrotor_data.roll  = m_quadrotor_sim.m_euler_angles[0];
+	quadrotor_data.pitch = m_quadrotor_sim.m_euler_angles[1];
+	quadrotor_data.yaw   = m_quadrotor_sim.m_euler_angles[2];
+	// > For euler angular rates
+	quadrotor_data.rollRate  = m_quadrotor_sim.m_euler_velocities[0];
+	quadrotor_data.pitchRate = m_quadrotor_sim.m_euler_velocities[1];
+	quadrotor_data.yawRate   = m_quadrotor_sim.m_euler_velocities[2];
+	// > For the acquiring time
+	quadrotor_data.acquiringTime = 0.0;
+
+	// Publish the current state on the "CFSimulationState"
+	// topic that is used by the MocapEmulator node
+	cfSimulationStatePublisher.publish(quadrotor_data);
+
+
+	// Publish the current state on the "CFStateEstimate"
+	// topic that emulates the Crazyflie
+	// > If counter indicates to do so
+	if (counter_since_last_send >= yaml_cfSimulation_stateEstimate_sendEvery)
+	{
+		cfStateEstimatorPublisher.publish(quadrotor_data);
+		// Reset the counter
+		counter_since_last_send = 0;
+	}
+}
+
+
+
+
+
 //    ----------------------------------------------------------------------------------
 //    L       OOO     A    DDDD
 //    L      O   O   A A   D   D
@@ -390,6 +476,52 @@ void fetchBatteryMonitorYamlParameters(ros::NodeHandle& nodeHandle)
 
 
 
+
+void fetchCrazyRadioConfigYamlParameters(ros::NodeHandle& nodeHandle)
+{
+	// Here we load the parameters that are specified in the file:
+	// BatteryMonitor.yaml
+
+	// Add the "CrazyRadioConfig" namespace to the "nodeHandle"
+	ros::NodeHandle nodeHandle_for_paramaters(nodeHandle, "CrazyRadioConfig");
+
+	// FLAG FOR WHETHER TO USE HEIGHT AS A TRIGGER FOR
+	// PUBLISHING A MOTORS-OFF COMMAND
+	yaml_isEnabled_strictSafety = getParameterBool(nodeHandle_for_paramaters,"isEnabled_strictSafety");
+	yaml_maxHeight_for_strictSafety_meters = getParameterFloat(nodeHandle_for_paramaters,"maxHeight_for_strictSafety_meters");
+
+	// SIMULATION FREQUENCY FOR EMULATING A CRAZYFLIE [Hertz]
+	float yaml_cfSimulation_frequency = getParameterFloat(nodeHandle_for_paramaters,"cfSimulation_frequency");
+
+	// HOW OFTEN TO PUBLISH THE SIMULATION STATE AS AN ONBOARD ESTIMATE
+	int yaml_cfSimulation_stateEstimate_sendEvery = getParameterInt(nodeHandle_for_paramaters,"cfSimulation_stateEstimate_sendEvery");
+
+	// THE COEFFICIENT OF THE 16-BIT COMMAND TO THRUST CONVERSION
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "motorPoly", yaml_motorPoly, 3);
+
+	// THE MIN AND MAX FOR SATURATING THE 16-BIT THRUST COMMANDS
+	yaml_command_sixteenbit_min = getParameterFloat(nodeHandle_for_paramaters, "command_sixteenbit_min");
+	yaml_command_sixteenbit_max = getParameterFloat(nodeHandle_for_paramaters, "command_sixteenbit_max");
+
+
+
+	// DEBUGGING: Print out one of the parameters that was loaded
+	//ROS_INFO_STREAM("[CRAZY RADIO EMULATOR] DEBUGGING: the fetched CrazyRadioConfig/cfSimulation_stateEstimate_sendEvery = " << yaml_cfSimulation_stateEstimate_sendEvery);
+
+
+
+	// PROCESS THE PARAMTERS
+	// Convert from Hertz to second
+	yaml_cfSimulation_deltaT_in_seconds = 1.0 / yaml_cfSimulation_frequency;
+
+	// DEBUGGING: Print out one of the processed values
+	ROS_INFO_STREAM("[CRAZY RADIO EMULATOR] DEBUGGING: after processing yaml_cfSimulation_deltaT_in_seconds = " << yaml_cfSimulation_deltaT_in_seconds);
+}
+
+
+
+
+
 //    ----------------------------------------------------------------------------------
 //    M   M    A    III  N   N
 //    MM MM   A A    I   NN  N
@@ -489,13 +621,49 @@ int main(int argc, char* argv[])
 	// Call the class function that loads the parameters for this class.
 	fetchBatteryMonitorYamlParameters(nodeHandle_to_own_agent_parameter_service);
 
+	// Call the class function that loads the parameters for this class.
+	fetchCrazyRadioConfigYamlParameters(nodeHandle);
 
 
-	// TIMER FOR THE BATTERY VOLTAGE
-	m_timer_battery_voltage_updates = nodeHandle.createTimer(ros::Duration(yaml_battery_polling_period_in_seconds), update_battery_voltage_callback, false);
+
+	// INITIALISE TIMER FOR THE BATTERY VOLTAGE
+	m_timer_battery_voltage_updates = nodeHandle.createTimer(ros::Duration(yaml_battery_polling_period_in_seconds), timerCallback_update_battery_voltage, false);
+	// > And stop it immediately
 	m_timer_battery_voltage_updates.stop();
 
 
+	// INITIALISE TIMER FOR THE STATE ESTIMATE PUBLISHER TIMER
+	m_timer_state_estimate_update = nodeHandle.createTimer(ros::Duration(yaml_cfSimulation_deltaT_in_seconds), timerCallback_update_cfStateEstimate, false);
+	// > And stop it immediately
+	m_timer_state_estimate_update.stop();
+
+
+
+
+	// INITIALISE THE QUADROTOR SIMULATOR
+	// > First convert the agentID to a zero-padded string
+	// Convert the agent ID to a zero padded string
+	std::ostringstream str_stream;
+	str_stream << std::setw(2) << std::setfill('0') << m_agentID;
+	std::string agentID_as_string(str_stream.str());
+	// > Initialise the quadrotor simulator class variable
+	m_quadrotor_sim = QuadrotorSimulator( "CF" + agentID_as_string , 0.032  );
+	// Set the agent id of quadrotor simulator
+	// > This determines which message topic the quadrotor
+	//   simulator subscribes to for commands
+	m_quadrotor_sim.update_commanding_agent_id( m_agentID );
+	// Set the reset state
+	m_quadrotor_sim.setResetState_xyz_yaw(0.0,0.0,0.0,0.0);
+	// Set the parameters for the 16-bit command to thrust conversion
+	m_quadrotor_sim.setParameters_for_16bitCommand_to_thrust_conversion(yaml_motorPoly[0], yaml_motorPoly[1], yaml_motorPoly[2], yaml_command_sixteenbit_min, yaml_command_sixteenbit_max);
+	// Reset the quadrotor
+	m_quadrotor_sim.reset();
+	// > Inform the user
+	ROS_INFO_STREAM("[CRAZY RADIO EMULATOR] Initilised quadrotor simulation with ID = " << m_quadrotor_sim.get_id_string() << ", and mass in kg = " << m_quadrotor_sim.get_mass_in_kg() );
+	ROS_INFO("[CRAZY RADIO EMULATOR] Initilised quadrotor simulation with details:");
+	m_quadrotor_sim.print_details();
+
+
 
 
 	// PUBLISHERS
@@ -513,12 +681,19 @@ int main(int argc, char* argv[])
 	// Publisher for the filtered battery voltage
 	batteryVoltagePublisher = nodeHandle.advertise<std_msgs::Float32>("CFBattery",1);
 
+	// Publisher for the onboard state estimate
+    cfStateEstimatorPublisher = nodeHandle.advertise<FlyingVehicleState>("CFStateEstimate",1);
+
 	// Publisher for the control commands
 	// > Note this is not needed for the real CrazyRadio node because
 	//   this command goes out over the radio, but for emulation we publish
 	//   the control command
 	controlCommandPublisher = nodeHandle.advertise<ControlCommand>("ControlCommand",1);
 
+	// Publisher for the simulation state
+	// > This is used by the MocapEmulator node
+	cfSimulationStatePublisher = nodeHandle.advertise<FlyingVehicleState>("CFSimulationState",1);
+
 
 	// SUBSCRIBERS
 
diff --git a/dfall_ws/src/dfall_pkg/src/nodes/CsoneControllerService.cpp b/dfall_ws/src/dfall_pkg/src/nodes/CsoneControllerService.cpp
index cc508b989834143b6e661078d137f67a7e2b62f5..64ffed038626413fb95d1cb51ffa06115c027875 100644
--- a/dfall_ws/src/dfall_pkg/src/nodes/CsoneControllerService.cpp
+++ b/dfall_ws/src/dfall_pkg/src/nodes/CsoneControllerService.cpp
@@ -82,23 +82,23 @@
 // following two properties:
 //
 // >> request.ownCrazyflie
-// This property is itself a structure of type "CrazyflieData",  which is
-// defined in the file "CrazyflieData.msg", and has the following properties
-// string crazyflieName
+// This property is itself a structure of type "FlyingVehicleState",  which is
+// defined in the file "FlyingVehicleState.msg", and has the following properties
+//     string vehicleName
 //     float64 x                         The x position of the Crazyflie [metres]
 //     float64 y                         The y position of the Crazyflie [metres]
 //     float64 z                         The z position of the Crazyflie [metres]
 //     float64 roll                      The roll component of the intrinsic Euler angles [radians]
 //     float64 pitch                     The pitch component of the intrinsic Euler angles [radians]
 //     float64 yaw                       The yaw component of the intrinsic Euler angles [radians]
-//     float64 acquiringTime #delta t    The time elapsed since the previous "CrazyflieData" was received [seconds]
-//     bool occluded                     A boolean indicted whether the Crazyflie for visible at the time of this measurement
+//     float64 acquiringTime #delta t    The time elapsed since the previous "FlyingVehicleState" was received [seconds]
+//     bool isValid                      A boolean indicted whether the Crazyflie for visible at the time of this measurement
 // The values in these properties are directly the measurement taken by the
 // motion capture system of the Crazyflie that is to be controlled by this
 // service.
 //
 // >> request.otherCrazyflies
-// This property is an array of "CrazyflieData" structures, what allows access
+// This property is an array of "FlyingVehicleState" structures, what allows access
 // to the motion capture measurements of other Crazyflies.
 //
 // The argument "response" is a structure that is expected to be filled in by
@@ -107,39 +107,52 @@
 // >> response.ControlCommand
 // This property is iteself a structure of type "ControlCommand", which is
 // defined in the file "ControlCommand.msg", and has the following properties:
-//     float32 roll                      The command sent to the Crazyflie for the body frame x-axis
-//     float32 pitch                     The command sent to the Crazyflie for the body frame y-axis
-//     float32 yaw                       The command sent to the Crazyflie for the body frame z-axis
-//     uint16 motorCmd1                  The command sent to the Crazyflie for motor 1
-//     uint16 motorCmd2                  The command sent to the Crazyflie for motor 1
-//     uint16 motorCmd3                  The command sent to the Crazyflie for motor 1
-//     uint16 motorCmd4                  The command sent to the Crazyflie for motor 1
-//     uint8 onboardControllerType       The flag sent to the Crazyflie for indicating how to implement the command
+//     uint16 motorCmd1                 The command sent to the Crazyflie for motor 1
+//     uint16 motorCmd2                 ... same for motor 2
+//     uint16 motorCmd3                 ... same for motor 3
+//     uint16 motorCmd4                 ... same for motor 4
+//     uint8 xControllerMode            The mode sent to the Crazyflie for what controller to run for the body frame x-axis
+//     uint8 yControllerMode            ... same body frame y-axis
+//     uint8 zControllerMode            ... same body frame z-axis
+//     uint8 yawControllerMode          ... same body frame yaw
+//     float32 xControllerSetpoint      The setpoint sent to the Crazyflie for the body frame x-axis controller
+//     float32 yControllerSetpoint      ... same body frame y-axis
+//     float32 zControllerSetpoint      ... same body frame z-axis
+//     float32 yawControllerSetpoint    ... same body frame yaw
 // 
-// IMPORTANT NOTES FOR "onboardControllerType"  AND AXIS CONVENTIONS
-// > The allowed values for "onboardControllerType" are in the "Defines"
-//   section in the header file, they are:
-//   - CF_COMMAND_TYPE_MOTORS
-//   - CF_COMMAND_TYPE_RATE
-//   - CF_COMMAND_TYPE_ANGLE
+// IMPORTANT NOTES FOR "{x,y,z,yaw}ControllerMode"  AND AXIS CONVENTIONS
+// > The allowed values for "{x,y,z,yaw}ControllerMode" are in the
+//   "Constants.h" header file, they are:
+//   - CF_ONBOARD_CONTROLLER_MODE_OFF
+//   - CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE
+//   - CF_ONBOARD_CONTROLLER_MODE_ANGLE
+//   - CF_ONBOARD_CONTROLLER_MODE_VELOCITY
+//   - CF_ONBOARD_CONTROLLER_MODE_POSITION
 //
-// > For most common option to use is CF_COMMAND_TYPE_RATE option.
+// > The most common option to use for the {x,y,yaw} controller is
+//   the CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE option.
 //
-// > For the CF_COMMAND_TYPE_RATE optoin:
-//   1) the ".roll", ".ptich", and ".yaw" properties of
-//      "response.ControlCommand" specify the angular rate in
-//      [radians/second] that will be requested from the PID controllers
-//      running in the Crazyflie 2.0 firmware.
-//   2) the ".motorCmd1" to ".motorCmd4" properties of
+// > The most common option to use for the {z} controller is
+//   the CF_ONBOARD_CONTROLLER_MODE_OFF option, and thus the
+//   body frame z-axis is controlled by the motorCmd{1,2,3,4}
+//   values that you set.
+//
+// > When the CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE is selected, then:
+//   1) the ".xControllerSetpoint", ".yControllerSetpoint", and
+//      ".yawControllerSetpoint" properties of "response.ControlCommand"
+//      specify the angular rate in [radians/second] that will be requested
+//      from the PID controllers running in the Crazyflie 2.0 firmware.
+//   2) the axis convention for the roll, pitch, and yaw body rates,
+//      i.e., as set in the {y,x,yaw}ControllerSetpoint properties of
+//      the "response.ControlCommand" that you return, is a right-hand
+//      coordinate axes with x-forward and z-upwards (i.e., the positive
+//      z-axis is aligned with the direction of positive thrust). To
+//      assist, the ASCII art below depicts this convention.
+//   3) the ".motorCmd1" to ".motorCmd4" properties of
 //      "response.ControlCommand" are the baseline motor commands
 //      requested from the Crazyflie, with the adjustment for body rates
 //      being added on top of this in the firmware (i.e., as per the
 //      code of the "distribute_power" found in the firmware).
-//   3) the axis convention for the roll, pitch, and yaw body rates
-//      returned in "response.ControlCommand" should use right-hand
-//      coordinate axes with x-forward and z-upwards (i.e., the positive
-//      z-axis is aligned with the direction of positive thrust). To
-//      assist, the following is an ASCII art of this convention.
 //
 // ASCII ART OF THE CRAZYFLIE 2.0 LAYOUT
 //
@@ -310,12 +323,24 @@ bool calculateControlOutput(Controller::Request &request, Controller::Response &
 	// > THIRD: perform the inner controller
 	pitchRate_forResponse = 5.0*(pitch_ref-request.ownCrazyflie.pitch);
 
-	// Put the computed body rate commands into the "response" variable
-	response.controlOutput.roll = rollRate_forResponse;
-	response.controlOutput.pitch = pitchRate_forResponse;
-	response.controlOutput.yaw = yawRate_forResponse;
 
 
+	// UPDATE THE "RETURN" THE VARIABLE NAMED "response"
+	// > i.e., put the computed body rate commands into the "response" variable
+
+	// Specify the mode of each controller
+	response.controlOutput.xControllerMode   = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+	response.controlOutput.yControllerMode   = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+	response.controlOutput.zControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+	response.controlOutput.yawControllerMode = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+
+	// Put the computed rates into the "response" variable
+	// > For roll, pitch, and yaw:
+	response.controlOutput.xControllerSetpoint   = pitchRate_forResponse;
+	response.controlOutput.yControllerSetpoint   = rollRate_forResponse;
+	response.controlOutput.zControllerSetpoint   = 0.0;
+	response.controlOutput.yawControllerSetpoint = yawRate_forResponse;
+
 
 
 	// PERFORM THE INTEGRATOR COMPUTATIONS
@@ -335,9 +360,8 @@ bool calculateControlOutput(Controller::Request &request, Controller::Response &
 	// Put the thrust commands into the "response" variable.
 	// The thrust adjustment computed by the controller need to be added to the
 	// the feed-forward thrust that "counter-acts" gravity.
-	// > NOTE: remember that the thrust is commanded per motor, so you sohuld
-	//         consider whether the "thrustAdjustment" computed by your
-	//         controller needed to be divided by 4 or not.
+	// > NOTE: remember that the thrust is commanded per motor, hence divide
+	//         the thrusts by 4.
 	// > NOTE: the "m_cf_weight_in_newtons" value is the total thrust required
 	//         as feed-forward. Assuming the the Crazyflie is symmetric, this
 	//         value is divided by four.
@@ -350,16 +374,6 @@ bool calculateControlOutput(Controller::Request &request, Controller::Response &
 	response.controlOutput.motorCmd3 = computeMotorPolyBackward(thrust_request_per_motor + cmd3_integral_adjustments);
 	response.controlOutput.motorCmd4 = computeMotorPolyBackward(thrust_request_per_motor + cmd4_integral_adjustments);
 
-	
-	// PREPARE AND RETURN THE VARIABLE "response"
-
-	// Choose the controller type use on-board the Crazyflie,
-	// it can be either be Motor, Rate, or Angle based
-	// response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_MOTORS;
-	response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_RATE;
-	// response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_ANGLE;
-
-
 
 
 	if (yaml_shouldPublishDebugMessage)
@@ -427,9 +441,9 @@ bool calculateControlOutput(Controller::Request &request, Controller::Response &
 
 		// An example of "printing out" the control actions computed.
 		ROS_INFO_STREAM("thrustAdjustment = " << thrustAdjustment);
-		ROS_INFO_STREAM("controlOutput.roll = " << response.controlOutput.roll);
-		ROS_INFO_STREAM("controlOutput.pitch = " << response.controlOutput.pitch);
-		ROS_INFO_STREAM("controlOutput.yaw = " << response.controlOutput.yaw);
+		ROS_INFO_STREAM("controlOutput.xControllerSetpoint   = " << response.controlOutput.xControllerSetpoint);
+		ROS_INFO_STREAM("controlOutput.yControllerSetpoint   = " << response.controlOutput.yControllerSetpoint);
+		ROS_INFO_STREAM("controlOutput.yawControllerSetpoint = " << response.controlOutput.yawControllerSetpoint);
 
 		// An example of "printing out" the per motor 16-bit command computed.
 		ROS_INFO_STREAM("controlOutput.cmd1 = " << response.controlOutput.motorCmd1);
@@ -989,7 +1003,7 @@ void fetchCsoneControllerYamlParameters(ros::NodeHandle& nodeHandle)
 
 	// > The co-efficients of the quadratic conversation from 16-bit motor
 	//   command to thrust force in Newtons
-	getParameterFloatVector(nodeHandle_for_paramaters, "motorPoly", yaml_motorPoly, 3);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "motorPoly", yaml_motorPoly, 3);
 
 	// > The min and max for saturating 16 bit thrust commands
 	yaml_command_sixteenbit_min = getParameterFloat(nodeHandle_for_paramaters, "command_sixteenbit_min");
@@ -997,7 +1011,7 @@ void fetchCsoneControllerYamlParameters(ros::NodeHandle& nodeHandle)
 
 	// The default setpoint, the ordering is (x,y,z,yaw),
 	// with unit [meters,meters,meters,radians]
-	getParameterFloatVector(nodeHandle_for_paramaters, "default_setpoint", yaml_default_setpoint, 4);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "default_setpoint", yaml_default_setpoint, 4);
 
 	// Boolean indiciating whether the "Debug Message" of this agent
 	// should be published or not
@@ -1009,10 +1023,10 @@ void fetchCsoneControllerYamlParameters(ros::NodeHandle& nodeHandle)
 
 	// The LQR Controller parameters
 	// The LQR Controller parameters for "LQR_MODE_RATE"
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixThrust_NineStateVector", yaml_gainMatrixThrust_NineStateVector, 9);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixRollRate",               yaml_gainMatrixRollRate,               9);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixPitchRate",              yaml_gainMatrixPitchRate,              9);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixYawRate",                yaml_gainMatrixYawRate,                9);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixThrust_NineStateVector", yaml_gainMatrixThrust_NineStateVector, 9);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixRollRate",               yaml_gainMatrixRollRate,               9);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixPitchRate",              yaml_gainMatrixPitchRate,              9);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixYawRate",                yaml_gainMatrixYawRate,                9);
 
 	// Integrator gains
 	yaml_integratorGain_forThrust = getParameterFloat(nodeHandle_for_paramaters, "integratorGain_forThrust");
diff --git a/dfall_ws/src/dfall_pkg/src/nodes/DefaultControllerService.cpp b/dfall_ws/src/dfall_pkg/src/nodes/DefaultControllerService.cpp
index 3e6cd6d9bec1c49c03596b4d92bda2d4195cd8e3..a412a8849b18df85af9723d256a8d7d4f1672d0d 100644
--- a/dfall_ws/src/dfall_pkg/src/nodes/DefaultControllerService.cpp
+++ b/dfall_ws/src/dfall_pkg/src/nodes/DefaultControllerService.cpp
@@ -279,19 +279,25 @@ void computeResponse_for_standby(Controller::Response &response)
 		m_current_state_changed = false;
 	}
 
-	// Fill in zero for the angle parts
-	response.controlOutput.roll  = 0.0;
-	response.controlOutput.pitch = 0.0;
-	response.controlOutput.yaw   = 0.0;
-
+	// Specify that all controllers are disabled
+	response.controlOutput.xControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+	response.controlOutput.yControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+	response.controlOutput.zControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+	response.controlOutput.yawControllerMode = CF_ONBOARD_CONTROLLER_MODE_OFF;
+
+	// Fill in zero for the controller setpoints
+	response.controlOutput.xControllerSetpoint   = 0.0;
+	response.controlOutput.yControllerSetpoint   = 0.0;
+	response.controlOutput.zControllerSetpoint   = 0.0;
+	response.controlOutput.yawControllerSetpoint = 0.0;
+	
 	// Fill in all motor thrusts as zero
 	response.controlOutput.motorCmd1 = 0.0;
 	response.controlOutput.motorCmd2 = 0.0;
 	response.controlOutput.motorCmd3 = 0.0;
 	response.controlOutput.motorCmd4 = 0.0;
 
-	// Specify that using a "motor type" of command
-	response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_MOTORS;
+	
 }
 
 
@@ -343,10 +349,17 @@ void computeResponse_for_takeoff_spin_motors(Controller::Response &response)
 		+ 1000.0
 		+ time_elapsed_proportion * yaml_takeoff_spin_motors_thrust;
 
-	// Fill in zero for the angle parts
-	response.controlOutput.roll  = 0.0;
-	response.controlOutput.pitch = 0.0;
-	response.controlOutput.yaw   = 0.0;
+	// Specify that all controllers are disabled
+	response.controlOutput.xControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+	response.controlOutput.yControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+	response.controlOutput.zControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+	response.controlOutput.yawControllerMode = CF_ONBOARD_CONTROLLER_MODE_OFF;
+
+	// Fill in zero for the controller setpoints
+	response.controlOutput.xControllerSetpoint   = 0.0;
+	response.controlOutput.yControllerSetpoint   = 0.0;
+	response.controlOutput.zControllerSetpoint   = 0.0;
+	response.controlOutput.yawControllerSetpoint = 0.0;
 
 	// Fill in all motor thrusts as the same
 	response.controlOutput.motorCmd1 = thrust_for_spinning;
@@ -354,8 +367,6 @@ void computeResponse_for_takeoff_spin_motors(Controller::Response &response)
 	response.controlOutput.motorCmd3 = thrust_for_spinning;
 	response.controlOutput.motorCmd4 = thrust_for_spinning;
 
-	// Specify that using a "motor type" of command
-	response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_MOTORS;
 
 	// Change to next state after specified time
 	if (m_time_in_seconds > yaml_takoff_spin_motors_time)
@@ -672,17 +683,23 @@ void computeResponse_for_landing_spin_motors(Controller::Response &response)
 	// Next stop using the controller and just spin the motors
 	else
 	{
-		// Fill in zero for the angle parts
-		response.controlOutput.roll  = 0.0;
-		response.controlOutput.pitch = 0.0;
-		response.controlOutput.yaw   = 0.0;
+		// Specify that all controllers are disabled
+		response.controlOutput.xControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+		response.controlOutput.yControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+		response.controlOutput.zControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+		response.controlOutput.yawControllerMode = CF_ONBOARD_CONTROLLER_MODE_OFF;
+
+		// Fill in zero for the controller setpoints
+		response.controlOutput.xControllerSetpoint   = 0.0;
+		response.controlOutput.yControllerSetpoint   = 0.0;
+		response.controlOutput.zControllerSetpoint   = 0.0;
+		response.controlOutput.yawControllerSetpoint = 0.0;
+
 		// Fill in all motor thrusts as the same
 		response.controlOutput.motorCmd1 = yaml_landing_spin_motors_thrust;
 		response.controlOutput.motorCmd2 = yaml_landing_spin_motors_thrust;
 		response.controlOutput.motorCmd3 = yaml_landing_spin_motors_thrust;
 		response.controlOutput.motorCmd4 = yaml_landing_spin_motors_thrust;
-		// Specify that using a "motor type" of command
-		response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_MOTORS;
 
 		// Change to next state after specified time
 		if ( m_time_in_seconds > (0.7*yaml_landing_spin_motors_time) )
@@ -782,73 +799,97 @@ void smoothSetpointChanges( float target_setpoint[4] , float (&current_setpoint)
 void performEstimatorUpdate_forStateInterial(Controller::Request &request)
 {
 
-	// PUT THE CURRENT MEASURED DATA INTO THE CLASS VARIABLE
-	// > for (x,y,z) position
-	m_current_xzy_rpy_measurement[0] = request.ownCrazyflie.x;
-	m_current_xzy_rpy_measurement[1] = request.ownCrazyflie.y;
-	m_current_xzy_rpy_measurement[2] = request.ownCrazyflie.z;
-	// > for (roll,pitch,yaw) angles
-	m_current_xzy_rpy_measurement[3] = request.ownCrazyflie.roll;
-	m_current_xzy_rpy_measurement[4] = request.ownCrazyflie.pitch;
-	m_current_xzy_rpy_measurement[5] = request.ownCrazyflie.yaw;
+	if (request.ownCrazyflie.type == FLYING_VEHICLE_STATE_TYPE_MOCAP_MEASUREMENT)
+	{
 
+		// PUT THE CURRENT MEASURED DATA INTO THE CLASS VARIABLE
+		// > for (x,y,z) position
+		m_current_xzy_rpy_measurement[0] = request.ownCrazyflie.x;
+		m_current_xzy_rpy_measurement[1] = request.ownCrazyflie.y;
+		m_current_xzy_rpy_measurement[2] = request.ownCrazyflie.z;
+		// > for (roll,pitch,yaw) angles
+		m_current_xzy_rpy_measurement[3] = request.ownCrazyflie.roll;
+		m_current_xzy_rpy_measurement[4] = request.ownCrazyflie.pitch;
+		m_current_xzy_rpy_measurement[5] = request.ownCrazyflie.yaw;
 
-	// RUN THE FINITE DIFFERENCE ESTIMATOR
-	performEstimatorUpdate_forStateInterial_viaFiniteDifference(request.isFirstControllerCall);
 
+		// RUN THE FINITE DIFFERENCE ESTIMATOR
+		performEstimatorUpdate_forStateInterial_viaFiniteDifference(request.isFirstControllerCall);
 
-	// RUN THE POINT MASS KALMAN FILTER ESTIMATOR
-	performEstimatorUpdate_forStateInterial_viaPointMassKalmanFilter(request.isFirstControllerCall);
 
+		// RUN THE POINT MASS KALMAN FILTER ESTIMATOR
+		performEstimatorUpdate_forStateInterial_viaPointMassKalmanFilter(request.isFirstControllerCall);
 
-	// FILLE IN THE STATE INERTIAL ESTIMATE TO BE USED FOR CONTROL
-	switch (yaml_estimator_method)
-	{
-		// Estimator based on finte differences
-		case ESTIMATOR_METHOD_FINITE_DIFFERENCE:
+
+		// FILLE IN THE STATE INERTIAL ESTIMATE TO BE USED FOR CONTROL
+		switch (yaml_estimator_method)
 		{
-			// Transfer the estimate
-			for(int i = 0; i < 9; ++i)
+			// Estimator based on finte differences
+			case ESTIMATOR_METHOD_FINITE_DIFFERENCE:
 			{
-				m_current_stateInertialEstimate[i]  = m_stateInterialEstimate_viaFiniteDifference[i];
+				// Transfer the estimate
+				for(int i = 0; i < 9; ++i)
+				{
+					m_current_stateInertialEstimate[i]  = m_stateInterialEstimate_viaFiniteDifference[i];
+				}
+				break;
 			}
-			break;
-		}
-		// Estimator based on Point Mass Kalman Filter
-		case ESTIMATOR_METHOD_POINT_MASS_PER_DIMENSION:
-		{
-			// Transfer the estimate
-			for(int i = 0; i < 9; ++i)
+			// Estimator based on Point Mass Kalman Filter
+			case ESTIMATOR_METHOD_POINT_MASS_PER_DIMENSION:
 			{
-				m_current_stateInertialEstimate[i]  = m_stateInterialEstimate_viaPointMassKalmanFilter[i];
+				// Transfer the estimate
+				for(int i = 0; i < 9; ++i)
+				{
+					m_current_stateInertialEstimate[i]  = m_stateInterialEstimate_viaPointMassKalmanFilter[i];
+				}
+				break;
 			}
-			break;
-		}
-		// Handle the exception
-		default:
-		{
-			// Display that the "yaml_estimator_method" was not recognised
-			ROS_INFO_STREAM("[DEFAULT CONTROLLER] ERROR: in the 'calculateControlOutput' function of the 'DefaultControllerService': the 'yaml_estimator_method' is not recognised.");
-			// Transfer the finite difference estimate by default
-			for(int i = 0; i < 9; ++i)
+			// Handle the exception
+			default:
 			{
-				m_current_stateInertialEstimate[i]  = m_stateInterialEstimate_viaFiniteDifference[i];
+				// Display that the "yaml_estimator_method" was not recognised
+				ROS_INFO_STREAM("[DEFAULT CONTROLLER] ERROR: in the 'calculateControlOutput' function of the 'DefaultControllerService': the 'yaml_estimator_method' is not recognised.");
+				// Transfer the finite difference estimate by default
+				for(int i = 0; i < 9; ++i)
+				{
+					m_current_stateInertialEstimate[i]  = m_stateInterialEstimate_viaFiniteDifference[i];
+				}
+				break;
 			}
-			break;
 		}
-	}
 
 
-	// NOW THAT THE ESTIMATORS HAVE ALL BEEN RUN, PUT THE CURRENT
-	// MEASURED DATA INTO THE CLASS VARIABLE FOR THE PREVIOUS 
-	// > for (x,y,z) position
-	m_previous_xzy_rpy_measurement[0] = m_current_xzy_rpy_measurement[0];
-	m_previous_xzy_rpy_measurement[1] = m_current_xzy_rpy_measurement[1];
-	m_previous_xzy_rpy_measurement[2] = m_current_xzy_rpy_measurement[2];
-	// > for (roll,pitch,yaw) angles
-	m_previous_xzy_rpy_measurement[3] = m_current_xzy_rpy_measurement[3];
-	m_previous_xzy_rpy_measurement[4] = m_current_xzy_rpy_measurement[4];
-	m_previous_xzy_rpy_measurement[5] = m_current_xzy_rpy_measurement[5];
+		// NOW THAT THE ESTIMATORS HAVE ALL BEEN RUN, PUT THE CURRENT
+		// MEASURED DATA INTO THE CLASS VARIABLE FOR THE PREVIOUS 
+		// > for (x,y,z) position
+		m_previous_xzy_rpy_measurement[0] = m_current_xzy_rpy_measurement[0];
+		m_previous_xzy_rpy_measurement[1] = m_current_xzy_rpy_measurement[1];
+		m_previous_xzy_rpy_measurement[2] = m_current_xzy_rpy_measurement[2];
+		// > for (roll,pitch,yaw) angles
+		m_previous_xzy_rpy_measurement[3] = m_current_xzy_rpy_measurement[3];
+		m_previous_xzy_rpy_measurement[4] = m_current_xzy_rpy_measurement[4];
+		m_previous_xzy_rpy_measurement[5] = m_current_xzy_rpy_measurement[5];
+	}
+	else if (request.ownCrazyflie.type == FLYING_VEHICLE_STATE_TYPE_CRAZYFLIE_STATE_ESTIMATE)
+	{
+		// Transfer the onboard estimate directly
+		// > For position
+		m_current_stateInertialEstimate[0]  = request.ownCrazyflie.x;
+		m_current_stateInertialEstimate[1]  = request.ownCrazyflie.y;
+		m_current_stateInertialEstimate[2]  = request.ownCrazyflie.z;
+		// > For velocities
+		m_current_stateInertialEstimate[3]  = request.ownCrazyflie.vx;
+		m_current_stateInertialEstimate[4]  = request.ownCrazyflie.vy;
+		m_current_stateInertialEstimate[5]  = request.ownCrazyflie.vz;
+		// > For euler angles
+		m_current_stateInertialEstimate[6]  = request.ownCrazyflie.roll;
+		m_current_stateInertialEstimate[7]  = request.ownCrazyflie.pitch;
+		m_current_stateInertialEstimate[8]  = request.ownCrazyflie.yaw;
+	}
+	else
+	{
+		ROS_ERROR_STREAM("[DEFAULT CONTROLLER] Received a request.ownCrazyflie with unrecognised type, request.ownCrazyflie.type = " << request.ownCrazyflie.type );
+	}
 }
 
 
@@ -870,9 +911,9 @@ void performEstimatorUpdate_forStateInterial_viaFiniteDifference(bool isFirstUpd
 	if (!isFirstUpdate)
 	{
 		// > for (x,y,z) velocities
-		m_stateInterialEstimate_viaFiniteDifference[3]  = (m_current_xzy_rpy_measurement[0] - m_previous_xzy_rpy_measurement[0]) * m_estimator_frequency;
-		m_stateInterialEstimate_viaFiniteDifference[4]  = (m_current_xzy_rpy_measurement[1] - m_previous_xzy_rpy_measurement[1]) * m_estimator_frequency;
-		m_stateInterialEstimate_viaFiniteDifference[5]  = (m_current_xzy_rpy_measurement[2] - m_previous_xzy_rpy_measurement[2]) * m_estimator_frequency;
+		m_stateInterialEstimate_viaFiniteDifference[3]  = (m_current_xzy_rpy_measurement[0] - m_previous_xzy_rpy_measurement[0]) * yaml_estimator_frequency;
+		m_stateInterialEstimate_viaFiniteDifference[4]  = (m_current_xzy_rpy_measurement[1] - m_previous_xzy_rpy_measurement[1]) * yaml_estimator_frequency;
+		m_stateInterialEstimate_viaFiniteDifference[5]  = (m_current_xzy_rpy_measurement[2] - m_previous_xzy_rpy_measurement[2]) * yaml_estimator_frequency;
 	}
 	else
 	{
@@ -1124,15 +1165,23 @@ void calculateControlOutput_viaLQR_givenError(float stateErrorBody[9], Controlle
 
 	// UPDATE THE "RETURN" THE VARIABLE NAMED "response"
 
-	// Put the computed rates and thrust into the "response" variable
+	// Specify the mode of each controller
+	response.controlOutput.xControllerMode   = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+	response.controlOutput.yControllerMode   = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+	response.controlOutput.zControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+	response.controlOutput.yawControllerMode = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+
+	// Put the computed rates into the "response" variable
 	// > For roll, pitch, and yaw:
-	response.controlOutput.roll  = rollRate_forResponse;
-	response.controlOutput.pitch = pitchRate_forResponse;
-	response.controlOutput.yaw   = yawRate_forResponse;
-	// > For the thrust adjustment we must add the feed-forward thrust to counter-act gravity.
-	// > NOTE: remember that the thrust is commanded per motor, so you sohuld
-	//         consider whether the "thrustAdjustment" computed by your
-	//         controller needed to be divided by 4 or not.
+	response.controlOutput.xControllerSetpoint   = pitchRate_forResponse;
+	response.controlOutput.yControllerSetpoint   = rollRate_forResponse;
+	response.controlOutput.zControllerSetpoint   = 0.0;
+	response.controlOutput.yawControllerSetpoint = yawRate_forResponse;
+
+	// Put the computed thrust into the "response" variable
+	// > On top of the thrust adjustment, we must add the feed-forward thrust to counter-act gravity.
+	// > NOTE: remember that the thrust is commanded per motor, hence divide
+	//         the thrusts by 4.
 	thrustAdjustment = thrustAdjustment / 4.0;
 	// > Compute the feed-forward force
 	float feed_forward_thrust_per_motor = m_cf_weight_in_newtons / 4.0 + newtons_int;
@@ -1142,11 +1191,6 @@ void calculateControlOutput_viaLQR_givenError(float stateErrorBody[9], Controlle
 	response.controlOutput.motorCmd3 = computeMotorPolyBackward(thrustAdjustment + feed_forward_thrust_per_motor + tau_x + tau_y - tau_z);
 	response.controlOutput.motorCmd4 = computeMotorPolyBackward(thrustAdjustment + feed_forward_thrust_per_motor + tau_x - tau_y + tau_z);
 
-	
-	// Specify that this controller is a rate controller
-	// response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_MOTOR;
-	response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_RATE;
-	// response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_ANGLE;
 
 
 	// An alternate debugging technique is to print out data directly to the
@@ -1155,9 +1199,9 @@ void calculateControlOutput_viaLQR_givenError(float stateErrorBody[9], Controlle
 	{
 		// An example of "printing out" the control actions computed.
 		ROS_INFO_STREAM("thrustAdjustment = " << thrustAdjustment);
-		ROS_INFO_STREAM("controlOutput.roll = " << response.controlOutput.roll);
-		ROS_INFO_STREAM("controlOutput.pitch = " << response.controlOutput.pitch);
-		ROS_INFO_STREAM("controlOutput.yaw = " << response.controlOutput.yaw);
+		ROS_INFO_STREAM("controlOutput.xControllerSetpoint   = " << response.controlOutput.xControllerSetpoint);
+		ROS_INFO_STREAM("controlOutput.yControllerSetpoint   = " << response.controlOutput.yControllerSetpoint);
+		ROS_INFO_STREAM("controlOutput.yawControllerSetpoint = " << response.controlOutput.yawControllerSetpoint);
 
 		// An example of "printing out" the "thrust-to-command" conversion parameters.
 		ROS_INFO_STREAM("motorPoly 0:" << yaml_motorPoly[0]);
@@ -1365,8 +1409,8 @@ void setNewSetpoint(float x, float y, float z, float yaw)
 	{
 		// Put the new setpoint into the class variable
 		m_setpoint[0] = clipToBounds( x , -m_symmetric_area_bounds_x , m_symmetric_area_bounds_x );
-		m_setpoint[1] = clipToBounds( y , -m_symmetric_area_bounds_y , m_symmetric_area_bounds_y );;
-		m_setpoint[2] = clipToBounds( z , -m_symmetric_area_bounds_z , m_symmetric_area_bounds_z );;
+		m_setpoint[1] = clipToBounds( y , -m_symmetric_area_bounds_y , m_symmetric_area_bounds_y );
+		m_setpoint[2] = clipToBounds( z , m_area_bounds_zmin , m_area_bounds_zmax );
 		m_setpoint[3] = yaw;
 	}
 
@@ -1555,47 +1599,31 @@ void crazyflieContextDatabaseChangedCallback(const std_msgs::Int32& msg)
 
 void loadCrazyflieContext()
 {
-    CMQuery contextCall;
-    contextCall.request.studentID = m_agentID;
-    ROS_INFO_STREAM("[DEFAULT CONTROLLER] AgentID:" << m_agentID);
-
-    CrazyflieContext new_context;
-
-    m_centralManager.waitForExistence(ros::Duration(-1));
-
-    if(m_centralManager.call(contextCall)) {
-        new_context = contextCall.response.crazyflieContext;
-        //ROS_INFO_STREAM("[DEFAULT CONTROLLER] CrazyflieContext:\n" << new_context);
-
-        //if((m_context.crazyflieName != "") && (new_context.crazyflieName != m_context.crazyflieName)) //linked crazyflie name changed and it was not empty before
-        //{
+	CMQuery contextCall;
+	contextCall.request.studentID = m_agentID;
+	ROS_INFO_STREAM("[DEFAULT CONTROLLER] AgentID:" << m_agentID);
 
-            // Motors off is done in python script now everytime we disconnect
+	CrazyflieContext new_context;
 
-            // send motors OFF and disconnect before setting m_context = new_context
-            // std_msgs::Int32 msg;
-            // msg.data = CMD_CRAZYFLY_MOTORS_OFF;
-            // commandPublisher.publish(msg);
+	m_centralManager.waitForExistence(ros::Duration(-1));
 
-            // ROS_INFO("[DEFAULT CONTROLLER] CF is now different for this student. Disconnect and turn it off");
+	if(m_centralManager.call(contextCall)) {
+		new_context = contextCall.response.crazyflieContext;
 
-            // IntWithHeader msg;
-            // msg.shouldCheckForAgentID = false;
-            // msg.data = CMD_DISCONNECT;
-            // m_crazyRadioCommandPublisher.publish(msg);
-        //}
+		m_symmetric_area_bounds_x = 0.5 * (new_context.localArea.xmax - new_context.localArea.xmin);
+		m_symmetric_area_bounds_y = 0.5 * (new_context.localArea.ymax - new_context.localArea.ymin);
+		//m_symmetric_area_bounds_z = 0.5 * (new_context.localArea.zmax - new_context.localArea.zmin);
 
-        m_symmetric_area_bounds_x = 0.5 * (new_context.localArea.xmax - new_context.localArea.xmin);
-        m_symmetric_area_bounds_y = 0.5 * (new_context.localArea.ymax - new_context.localArea.ymin);
-        m_symmetric_area_bounds_z = 0.5 * (new_context.localArea.zmax - new_context.localArea.zmin);
-        m_isAvailableContext = true;
+		m_area_bounds_zmin = new_context.localArea.zmin;
+		m_area_bounds_zmax = new_context.localArea.zmax;
 
-    }
-    else
-    {
-    	m_isAvailableContext = false;
-        ROS_ERROR("[DEFAULT CONTROLLER] Failed to load context. Waiting for next Save in DB by System Config node");
-    }
+		m_isAvailableContext = true;
+	}
+	else
+	{
+		m_isAvailableContext = false;
+		ROS_ERROR("[DEFAULT CONTROLLER] Failed to load context. Waiting for next Save in DB by System Config node");
+	}
 }
 
 
@@ -1782,7 +1810,7 @@ void fetchDefaultControllerYamlParameters(ros::NodeHandle& nodeHandle)
 
 	// > The co-efficients of the quadratic conversation from 16-bit
 	//   motor command to thrust force in Newtons
-	getParameterFloatVector(nodeHandle_for_paramaters, "motorPoly", yaml_motorPoly, 3);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "motorPoly", yaml_motorPoly, 3);
 
 	// The min and max for saturating 16 bit thrust commands
 	yaml_command_sixteenbit_min = getParameterFloat(nodeHandle_for_paramaters, "command_sixteenbit_min");
@@ -1790,7 +1818,7 @@ void fetchDefaultControllerYamlParameters(ros::NodeHandle& nodeHandle)
 
 	// The default setpoint, the ordering is (x,y,z,yaw),
 	// with unit [meters,meters,meters,radians]
-	getParameterFloatVector(nodeHandle_for_paramaters, "default_setpoint", yaml_default_setpoint, 4);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "default_setpoint", yaml_default_setpoint, 4);
 
 	// Boolean indiciating whether the "Debug Message" of this agent should be published or not
 	yaml_shouldPublishDebugMessage = getParameterBool(nodeHandle_for_paramaters, "shouldPublishDebugMessage");
@@ -1802,13 +1830,13 @@ void fetchDefaultControllerYamlParameters(ros::NodeHandle& nodeHandle)
 	yaml_controller_method = getParameterInt( nodeHandle_for_paramaters , "controller_method" );	
 
 	// The LQR Controller parameters for z-height
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixThrust_2StateVector", yaml_gainMatrixThrust_2StateVector, 2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixThrust_2StateVector", yaml_gainMatrixThrust_2StateVector, 2);
 	// The LQR Controller parameters for "CONTROLLER_MODE_LQR_RATE"
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixRollRate_3StateVector",   yaml_gainMatrixRollRate_3StateVector,  3);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixPitchRate_3StateVector",  yaml_gainMatrixPitchRate_3StateVector, 3);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixRollRate_3StateVector",   yaml_gainMatrixRollRate_3StateVector,  3);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixPitchRate_3StateVector",  yaml_gainMatrixPitchRate_3StateVector, 3);
 	// The LQR Controller parameters for "CONTROLLER_MODE_LQR_RATE"
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixRollAngle_2StateVector",   yaml_gainMatrixRollAngle_2StateVector,  2);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixPitchAngle_2StateVector",  yaml_gainMatrixPitchAngle_2StateVector, 2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixRollAngle_2StateVector",   yaml_gainMatrixRollAngle_2StateVector,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixPitchAngle_2StateVector",  yaml_gainMatrixPitchAngle_2StateVector, 2);
 	yaml_gainRollRate_fromAngle  = getParameterFloat(nodeHandle_for_paramaters, "gainRollRate_fromAngle");
 	yaml_gainPitchRate_fromAngle = getParameterFloat(nodeHandle_for_paramaters, "gainPitchRate_fromAngle");
 	// The LQR Controller parameters for yaw
@@ -1821,12 +1849,14 @@ void fetchDefaultControllerYamlParameters(ros::NodeHandle& nodeHandle)
 	
 	// A flag for which estimator to use:
 	yaml_estimator_method = getParameterInt( nodeHandle_for_paramaters , "estimator_method" );
+
+	yaml_estimator_frequency = getParameterFloat(nodeHandle_for_paramaters, "estimator_frequency");
 	
 	// THE POINT MASS KALMAN FILTER (PMKF) GAINS AND ERROR EVOLUATION
 	// > For the (x,y,z) position
-	getParameterFloatVector(nodeHandle_for_paramaters, "PMKF_Ahat_row1_for_positions",  yaml_PMKF_Ahat_row1_for_positions,  2);
-	getParameterFloatVector(nodeHandle_for_paramaters, "PMKF_Ahat_row2_for_positions",  yaml_PMKF_Ahat_row2_for_positions,  2);
-	getParameterFloatVector(nodeHandle_for_paramaters, "PMKF_Kinf_for_positions"     ,  yaml_PMKF_Kinf_for_positions     ,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "PMKF_Ahat_row1_for_positions",  yaml_PMKF_Ahat_row1_for_positions,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "PMKF_Ahat_row2_for_positions",  yaml_PMKF_Ahat_row2_for_positions,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "PMKF_Kinf_for_positions"     ,  yaml_PMKF_Kinf_for_positions     ,  2);
 
 
 
diff --git a/dfall_ws/src/dfall_pkg/src/nodes/DemoControllerService.cpp b/dfall_ws/src/dfall_pkg/src/nodes/DemoControllerService.cpp
index 7988825d0e6b7b62c58a5b4f8ff217bb0ad575ee..e83ad504ffa021e70db23c615178024a9dfb349c 100644
--- a/dfall_ws/src/dfall_pkg/src/nodes/DemoControllerService.cpp
+++ b/dfall_ws/src/dfall_pkg/src/nodes/DemoControllerService.cpp
@@ -80,22 +80,22 @@
 // The arument "request" is a structure provided to this service with the following two
 // properties:
 // request.ownCrazyflie
-// This property is itself a structure of type "CrazyflieData",  which is defined in the
-// file "CrazyflieData.msg", and has the following properties
-// string crazyflieName
+// This property is itself a structure of type "FlyingVehicleState",  which is defined in the
+// file "FlyingVehicleState.msg", and has the following properties
+//     string vehicleName
 //     float64 x                         The x position of the Crazyflie [metres]
 //     float64 y                         The y position of the Crazyflie [metres]
 //     float64 z                         The z position of the Crazyflie [metres]
 //     float64 roll                      The roll component of the intrinsic Euler angles [radians]
 //     float64 pitch                     The pitch component of the intrinsic Euler angles [radians]
 //     float64 yaw                       The yaw component of the intrinsic Euler angles [radians]
-//     float64 acquiringTime #delta t    The time elapsed since the previous "CrazyflieData" was received [seconds]
-//     bool occluded                     A boolean indicted whether the Crazyflie for visible at the time of this measurement
+//     float64 acquiringTime #delta t    The time elapsed since the previous "FlyingVehicleState" was received [seconds]
+//     bool isValid                      A boolean indicted whether the Crazyflie for visible at the time of this measurement
 // The values in these properties are directly the measurement taken by the Vicon
 // motion capture system of the Crazyflie that is to be controlled by this service
 //
 // request.otherCrazyflies
-// This property is an array of "CrazyflieData" structures, what allows access to the
+// This property is an array of "FlyingVehicleState" structures, what allows access to the
 // Vicon measurements of other Crazyflies.
 //
 // The argument "response" is a structure that is expected to be filled in by this
@@ -1526,7 +1526,7 @@ void fetchDemoControllerYamlParameters(ros::NodeHandle& nodeHandle)
 
 	// > The co-efficients of the quadratic conversation from 16-bit motor command to
 	//   thrust force in Newtons
-	getParameterFloatVector(nodeHandle_for_paraMaters, "motorPoly", motorPoly, 3);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "motorPoly", motorPoly, 3);
 
 	// > The boolean for whether to execute the convert into body frame function
 	shouldPerformConvertIntoBodyFrame = getParameterBool(nodeHandle_for_paraMaters, "shouldPerformConvertIntoBodyFrame");
@@ -1565,36 +1565,36 @@ void fetchDemoControllerYamlParameters(ros::NodeHandle& nodeHandle)
 	estimator_method = getParameterInt( nodeHandle_for_paraMaters , "estimator_method" );
 
 	// The LQR Controller parameters for "LQR_MODE_MOTOR"
-	getParameterFloatVector(nodeHandle_for_paraMaters, "gainMatrixMotor1",                 gainMatrixMotor1,                 12);
-	getParameterFloatVector(nodeHandle_for_paraMaters, "gainMatrixMotor2",                 gainMatrixMotor2,                 12);
-	getParameterFloatVector(nodeHandle_for_paraMaters, "gainMatrixMotor3",                 gainMatrixMotor3,                 12);
-	getParameterFloatVector(nodeHandle_for_paraMaters, "gainMatrixMotor4",                 gainMatrixMotor4,                 12);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "gainMatrixMotor1",                 gainMatrixMotor1,                 12);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "gainMatrixMotor2",                 gainMatrixMotor2,                 12);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "gainMatrixMotor3",                 gainMatrixMotor3,                 12);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "gainMatrixMotor4",                 gainMatrixMotor4,                 12);
 
 	// The LQR Controller parameters for "LQR_MODE_MOTOR"
-	getParameterFloatVector(nodeHandle_for_paraMaters, "gainMatrixThrust_TwelveStateVector", gainMatrixThrust_TwelveStateVector, 12);
-	getParameterFloatVector(nodeHandle_for_paraMaters, "gainMatrixRollTorque",               gainMatrixRollTorque,               12);
-	getParameterFloatVector(nodeHandle_for_paraMaters, "gainMatrixPitchTorque",              gainMatrixPitchTorque,              12);
-	getParameterFloatVector(nodeHandle_for_paraMaters, "gainMatrixYawTorque",                gainMatrixYawTorque,                12);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "gainMatrixThrust_TwelveStateVector", gainMatrixThrust_TwelveStateVector, 12);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "gainMatrixRollTorque",               gainMatrixRollTorque,               12);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "gainMatrixPitchTorque",              gainMatrixPitchTorque,              12);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "gainMatrixYawTorque",                gainMatrixYawTorque,                12);
 
 	// The LQR Controller parameters for "LQR_MODE_RATE"
-	getParameterFloatVector(nodeHandle_for_paraMaters, "gainMatrixThrust_NineStateVector", gainMatrixThrust_NineStateVector, 9);
-	getParameterFloatVector(nodeHandle_for_paraMaters, "gainMatrixRollRate",               gainMatrixRollRate,               9);
-	getParameterFloatVector(nodeHandle_for_paraMaters, "gainMatrixPitchRate",              gainMatrixPitchRate,              9);
-	getParameterFloatVector(nodeHandle_for_paraMaters, "gainMatrixYawRate",                gainMatrixYawRate,                9);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "gainMatrixThrust_NineStateVector", gainMatrixThrust_NineStateVector, 9);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "gainMatrixRollRate",               gainMatrixRollRate,               9);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "gainMatrixPitchRate",              gainMatrixPitchRate,              9);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "gainMatrixYawRate",                gainMatrixYawRate,                9);
 	
 	// The LQR Controller parameters for "LQR_MODE_ANGLE"
-	getParameterFloatVector(nodeHandle_for_paraMaters, "gainMatrixThrust_SixStateVector",  gainMatrixThrust_SixStateVector,  6);
-	getParameterFloatVector(nodeHandle_for_paraMaters, "gainMatrixRollAngle",              gainMatrixRollAngle,              6);
-	getParameterFloatVector(nodeHandle_for_paraMaters, "gainMatrixPitchAngle",             gainMatrixPitchAngle,             6);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "gainMatrixThrust_SixStateVector",  gainMatrixThrust_SixStateVector,  6);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "gainMatrixRollAngle",              gainMatrixRollAngle,              6);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "gainMatrixPitchAngle",             gainMatrixPitchAngle,             6);
 	
 	// The LQR Controller parameters for "LQR_MODE_ANGLE_RATE_NESTED"
-	getParameterFloatVector(nodeHandle_for_paraMaters, "gainMatrixThrust_SixStateVector_50Hz",  gainMatrixThrust_SixStateVector_50Hz,  6);
-	getParameterFloatVector(nodeHandle_for_paraMaters, "gainMatrixRollAngle_50Hz",              gainMatrixRollAngle_50Hz,              6);
-	getParameterFloatVector(nodeHandle_for_paraMaters, "gainMatrixPitchAngle_50Hz",             gainMatrixPitchAngle_50Hz,             6);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "gainMatrixThrust_SixStateVector_50Hz",  gainMatrixThrust_SixStateVector_50Hz,  6);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "gainMatrixRollAngle_50Hz",              gainMatrixRollAngle_50Hz,              6);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "gainMatrixPitchAngle_50Hz",             gainMatrixPitchAngle_50Hz,             6);
 
-	getParameterFloatVector(nodeHandle_for_paraMaters, "gainMatrixRollRate_Nested",             gainMatrixRollRate_Nested,             3);
-	getParameterFloatVector(nodeHandle_for_paraMaters, "gainMatrixPitchRate_Nested",            gainMatrixPitchRate_Nested,            3);
-	getParameterFloatVector(nodeHandle_for_paraMaters, "gainMatrixYawRate_Nested",              gainMatrixYawRate_Nested,              3);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "gainMatrixRollRate_Nested",             gainMatrixRollRate_Nested,             3);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "gainMatrixPitchRate_Nested",            gainMatrixPitchRate_Nested,            3);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "gainMatrixYawRate_Nested",              gainMatrixYawRate_Nested,              3);
 	
 	// The parameters for the "Angle Reponse Test" controller mode
 	angleResponseTest_pitchAngle_degrees = getParameterFloat(nodeHandle_for_paraMaters, "angleResponseTest_pitchAngle_degrees");
@@ -1607,13 +1607,13 @@ void fetchDemoControllerYamlParameters(ros::NodeHandle& nodeHandle)
 
 	// THE POINT MASS KALMAN FILTER (PMKF) GAINS AND ERROR EVOLUATION
 	// > For the (x,y,z) position
-	getParameterFloatVector(nodeHandle_for_paraMaters, "PMKF_Ahat_row1_for_positions",  PMKF_Ahat_row1_for_positions,  2);
-	getParameterFloatVector(nodeHandle_for_paraMaters, "PMKF_Ahat_row2_for_positions",  PMKF_Ahat_row2_for_positions,  2);
-	getParameterFloatVector(nodeHandle_for_paraMaters, "PMKF_Kinf_for_positions"     ,  PMKF_Kinf_for_positions     ,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "PMKF_Ahat_row1_for_positions",  PMKF_Ahat_row1_for_positions,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "PMKF_Ahat_row2_for_positions",  PMKF_Ahat_row2_for_positions,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "PMKF_Kinf_for_positions"     ,  PMKF_Kinf_for_positions     ,  2);
 	// > For the (roll,pitch,yaw) angles
-	getParameterFloatVector(nodeHandle_for_paraMaters, "PMKF_Ahat_row1_for_angles",  PMKF_Ahat_row1_for_angles,  2);
-	getParameterFloatVector(nodeHandle_for_paraMaters, "PMKF_Ahat_row2_for_angles",  PMKF_Ahat_row2_for_angles,  2);
-	getParameterFloatVector(nodeHandle_for_paraMaters, "PMKF_Kinf_for_angles"     ,  PMKF_Kinf_for_angles     ,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "PMKF_Ahat_row1_for_angles",  PMKF_Ahat_row1_for_angles,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "PMKF_Ahat_row2_for_angles",  PMKF_Ahat_row2_for_angles,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paraMaters, "PMKF_Kinf_for_angles"     ,  PMKF_Kinf_for_angles     ,  2);
 
 
 	// DEBUGGING: Print out one of the parameters that was loaded
diff --git a/dfall_ws/src/dfall_pkg/src/nodes/FlyingAgentClient.cpp b/dfall_ws/src/dfall_pkg/src/nodes/FlyingAgentClient.cpp
index 63445d1be767f07bddde21d22fa206d891c92277..6f4b4aa03591366cf3670e8b9669880287025592 100755
--- a/dfall_ws/src/dfall_pkg/src/nodes/FlyingAgentClient.cpp
+++ b/dfall_ws/src/dfall_pkg/src/nodes/FlyingAgentClient.cpp
@@ -59,7 +59,6 @@
 
 
 
-
 //    ----------------------------------------------------------------------------------
 //    M   M   OOO   TTTTT  III   OOO   N   N
 //    MM MM  O   O    T     I   O   O  NN  N
@@ -81,12 +80,9 @@ void viconCallback(const ViconData& viconData)
 	//       CAPTURE SYSTEM. HENCE ANY OPTERATIONS PERFORMED IN
 	//       THIS FUNCTION MUST BE NON-BLOCKING.
 
-	// Initialise a counter of consecutive frames of motion
-	// capture data where the agent is occuled
-	static int number_of_consecutive_occulsions = 0;
-
 	// Initilise a variable for the pose data of this agent
-	CrazyflieData poseDataForThisAgent;
+	FlyingVehicleState poseDataForThisAgent;
+	poseDataForThisAgent.isValid = false;
 
 	// Extract the pose data for the allocated object from the
 	// full motion capture array
@@ -94,9 +90,11 @@ void viconCallback(const ViconData& viconData)
 	//       indicates that the pose data was not found.
 	m_poseDataIndex = getPoseDataForObjectNameWithExpectedIndex( viconData, m_context.crazyflieName , m_poseDataIndex , poseDataForThisAgent );
 
+
+
 	// Initilise a variable for the pose data of another agent
-	CrazyflieData poseDataForOtherAgent;
-	poseDataForOtherAgent.occluded = true;
+	FlyingVehicleState poseDataForOtherAgent;
+	poseDataForOtherAgent.isValid = false;
 
 	// Extract the pose data for the other object from the
 	// full motion capture array
@@ -104,73 +102,231 @@ void viconCallback(const ViconData& viconData)
 	//       indicates that the pose data was not found.
 	//m_otherObjectPoseDataIndex = getPoseDataForObjectNameWithExpectedIndex( viconData, "NameOfOtherObject" , m_otherObjectPoseDataIndex , poseDataForOtherAgent );
 
-	// Detecting time-out of the motion capture data
-	// > Update the flag
-	m_isAvailable_mocap_data = true;
-	// > Stop any previous instance that might still be running
-	m_timer_mocap_timeout_check.stop();
-	// > Set the period again (second argument is reset)
-	m_timer_mocap_timeout_check.setPeriod( ros::Duration(yaml_mocap_timeout_duration), true);
-	// > Start the timer again
-	m_timer_mocap_timeout_check.start();
 
 
 	// Only continue if:
-	// (1) the pose for this agent was found, and
-	// (2) the controllers are actually available
-	// (2) the flying state is something other than MOTORS-OFF
+	// (1) the pose for this agent was found
+	if (m_poseDataIndex >= 0)
+	{
+		callControllerServiceWithGivenData(poseDataForThisAgent, poseDataForOtherAgent);
+	}
+	else
+	{
+		// Send the command to turn the motors off
+		sendZeroOutputCommandForMotors();
+	}
+}
+
+
+
+
+
+int getPoseDataForObjectNameWithExpectedIndex(const ViconData& viconData, std::string name , int expected_index , FlyingVehicleState& pose_to_fill_in)
+{
+	// Initialise an integer for the index where the object
+	// "name" is found
+	// > Initialise an negative to indicate not found
+	int object_index = -1;
+
+	// Get the length of the "pose data array"
+	int length_poseData = viconData.crazyflies.size();
+
+	// If the "expected index" is non-negative and less than
+	// the length of the data array, then attempt to check
+	// for a name match
 	if (
-		(m_poseDataIndex >= 0)
+		(0 <= expected_index)
 		and
-		(m_controllers_avialble)
+		(expected_index < length_poseData)
 	)
 	{
+		// Check if the names match
+		if (viconData.crazyflies[expected_index].vehicleName == name)
+		{
+			object_index = expected_index;
+		}
+	}
 
-        // If motors-off and testing motors
-        if (
-            m_flying_state == STATE_MOTORS_OFF
-            &&
-            m_controller_nominally_selected == TESTMOTORS_CONTROLLER
-            &&
-            m_testMotorsController.exists()
-            )
-        {
-            // Initliase the "Contrller" service call variable
-            Controller testMotorsCall;
+	// If not found, then iterate the data array looking
+	// for a name match
+	if (object_index < 0)
+	{
+		for( int i=0 ; i<length_poseData ; i++ )
+		{    
+			// Check if the names match
+			if(viconData.crazyflies[i].vehicleName == name)
+			{
+				object_index = i;
+			}
+		}
+	}
 
-            // Initialise a local boolean success variable
-            bool isSuccessful_testMotorsCall = false;
+	// If not found, then retrun, else fill in the pose data
+	if (object_index < 0)
+	{
+		return object_index;
+	}
+	else
+	{
+		pose_to_fill_in = viconData.crazyflies[object_index];
+		coordinatesToLocal(pose_to_fill_in);
+		return object_index;
+	}
+}
 
-            // Call the controller service client
-            isSuccessful_testMotorsCall = m_testMotorsController.call(testMotorsCall);
 
-            // Ensure success and enforce safety
-            if(isSuccessful_testMotorsCall)
-            {
-                m_commandForSendingToCrazyfliePublisher.publish(testMotorsCall.response.controlOutput);
-            }
-            else
-            {
-                // Let the user know that the controller call failed
-                ROS_ERROR_STREAM("[FLYING AGENT CLIENT] Failed to call test motors controller, valid: " << m_testMotorsController.isValid() << ", exists: " << m_testMotorsController.exists());
-                // Change back to the default controller
-                setControllerNominallySelected(DEFAULT_CONTROLLER);
-                // Send the command to turn the motors off
-                sendZeroOutputCommandForMotors();
-            }
-            return;
-        }
+void coordinatesToLocal(FlyingVehicleState& cf)
+{
+	// Get the area into a local variable
+	AreaBounds area = m_context.localArea;
+
+	// Shift the X-Y coordinates
+	float originX = (area.xmin + area.xmax) / 2.0;
+	float originY = (area.ymin + area.ymax) / 2.0;
+	cf.x -= originX;
+	cf.y -= originY;
+
+	// Shift the Z coordinate
+	// change Z origin to zero, i.e., to the table height, zero of global coordinates, instead of middle of the box
+	//float originZ = 0.0;
+	// float originZ = (area.zmin + area.zmax) / 2.0;
+	//cf.z -= originZ;
+}
+
+
+
+
+
+//    ---------------------------------------------------------------------------- %
+//     OOO   N   N  BBBB    OOO     A    RRRR   DDDD 
+//    O   O  NN  N  B   B  O   O   A A   R   R  D   D
+//    O   O  N N N  BBBB   O   O  A   A  RRRR   D   D
+//    O   O  N  NN  B   B  O   O  AAAAA  R   R  D   D
+//     OOO   N   N  BBBB    OOO   A   A  R   R  DDDD 
+//
+//    EEEEE   SSSS  TTTTT  III  M   M    A    TTTTT  EEEEE
+//    E      S        T     I   MM MM   A A     T    E    
+//    EEE     SSS     T     I   M M M  A   A    T    EEE  
+//    E          S    T     I   M   M  AAAAA    T    E    
+//    EEEEE  SSSS     T    III  M   M  A   A    T    EEEEE
+//    ---------------------------------------------------------------------------- %
+
+// FUNCTIONS FOR HANDLING THE ONBOARD STATE ESTIMATE
+// > Callback run every time new state estimate
+//   data is available from onboard the flying vehicle
+void onboardEstimateCallback(const FlyingVehicleState& flyingVehicleState)
+{
+	// Pass the receive data directly through
+	// > Copy into a local vairable first
+	FlyingVehicleState dataForThisAgent;
+	dataForThisAgent = flyingVehicleState;
+	
+	// Initialise an empty variable for the "other
+	// agent data" argument
+	FlyingVehicleState dataForOtherAgent;
+	dataForOtherAgent.isValid = false;
+
+	// Call the "call controller service" function
+	callControllerServiceWithGivenData( dataForThisAgent , dataForOtherAgent );
+}
+
+
+
+
+
+//    ----------------------------------------------------------------------------------
+//     CCCC    A    L      L    
+//    C       A A   L      L    
+//    C      A   A  L      L    
+//    C      AAAAA  L      L    
+//     CCCC  A   A  LLLLL  LLLLL
+//
+//     CCCC   OOO   N   N  TTTTT  RRRR    OOO   L      L      EEEEE  RRRR 
+//    C      O   O  NN  N    T    R   R  O   O  L      L      E      R   R
+//    C      O   O  N N N    T    RRRR   O   O  L      L      EEE    RRRR 
+//    C      O   O  N  NN    T    R   R  O   O  L      L      E      R   R
+//     CCCC   OOO   N   N    T    R   R   OOO   LLLLL  LLLLL  EEEEE  R   R
+//
+//     SSSS  EEEEE  RRRR   V   V  III   CCCC  EEEEE
+//    S      E      R   R  V   V   I   C      E    
+//     SSS   EEE    RRRR   V   V   I   C      EEE  
+//        S  E      R   R   V V    I   C      E    
+//    SSSS   EEEEE  R   R    V    III   CCCC  EEEEE
+//    ----------------------------------------------------------------------------------
+
+// FUNCTION FOR CALLING THE CONTROLLER SERVICE FOR THE
+// CURRENTLY SELECTED CONTROLLER, AND THEN SENDING THE
+// CONTROL COMMAND TO THE CRAZYRADIO NODE
+void callControllerServiceWithGivenData(FlyingVehicleState& dataForThisAgent, FlyingVehicleState& dataForOtherAgent)
+{
+
+	// Initialise a counter of consecutive frames of motion
+	// capture data where the agent is occuled
+	static int number_of_consecutive_invalid_measurements = 0;
+
+	// Detecting time-out of the measurement data
+	// > Update the flag
+	m_isAvailable_measurement_data = true;
+	// > Stop any previous instance that might still be running
+	m_timer_measurement_data_timeout_check.stop();
+	// > Set the period again (second argument is reset)
+	m_timer_measurement_data_timeout_check.setPeriod( ros::Duration(yaml_measurement_timeout_duration), true);
+	// > Start the timer again
+	m_timer_measurement_data_timeout_check.start();
+
+	// Only continue if:
+	// (1) the controllers are actually available
+	if (m_controllers_avialble)
+	{
+
+		// Call the "test motors" controller only if:
+		// (1) in the motors-off state, and
+		// (2) "test motors" controller is selected, and
+		// (3) "test motors" controller exists
+		if (
+			m_flying_state == STATE_MOTORS_OFF
+			&&
+			m_controller_nominally_selected == TESTMOTORS_CONTROLLER
+			&&
+			m_testMotorsController.exists()
+			)
+		{
+			// Initliase the "Contrller" service call variable
+			Controller testMotorsCall;
+
+			// Initialise a local boolean success variable
+			bool isSuccessful_testMotorsCall = false;
+
+			// Call the controller service client
+			isSuccessful_testMotorsCall = m_testMotorsController.call(testMotorsCall);
+
+			// Ensure success and enforce safety
+			if(isSuccessful_testMotorsCall)
+			{
+				m_commandForSendingToCrazyfliePublisher.publish(testMotorsCall.response.controlOutput);
+			}
+			else
+			{
+				// Let the user know that the controller call failed
+				ROS_ERROR_STREAM("[FLYING AGENT CLIENT] Failed to call test motors controller, valid: " << m_testMotorsController.isValid() << ", exists: " << m_testMotorsController.exists());
+				// Change back to the default controller
+				setControllerNominallySelected(DEFAULT_CONTROLLER);
+				// Send the command to turn the motors off
+				sendZeroOutputCommandForMotors();
+			}
+			return;
+		}
 
 
 
 		// Only continue if:
-		// (1) the agent is NOT occulded
-		if(!poseDataForThisAgent.occluded)
+		// (1) the agent's pose data is valid
+		if(dataForThisAgent.isValid)
 		{
 			// Update the flag
-			m_isOcculded_mocap_data = false;
+			m_isValid_measurement_data = true;
 			// Reset the "consecutive occulsions" flag
-			number_of_consecutive_occulsions = 0;
+			number_of_consecutive_invalid_measurements = 0;
 
 
 			// Only continue if:
@@ -182,13 +338,13 @@ void viconCallback(const ViconData& viconData)
 				Controller controllerCall;
 
 				// Fill in the pose data for this agent
-				controllerCall.request.ownCrazyflie = poseDataForThisAgent;
+				controllerCall.request.ownCrazyflie = dataForThisAgent;
 
 				// Fill in the pose data of another agaent, if the data
 				// is avaialable
-				if (m_otherObjectPoseDataIndex >= 0)
+				if (dataForOtherAgent.isValid)
 				{
-					controllerCall.request.otherCrazyflies.push_back(poseDataForOtherAgent);
+					controllerCall.request.otherCrazyflies.push_back(dataForOtherAgent);
 				}
 
 				// Fill in the "isFirstControllerCall" field
@@ -206,7 +362,7 @@ void viconCallback(const ViconData& viconData)
 				// PERFORM THE SAFTY CHECK (IF NOT THE DEFAULT CONTROLLER)
 				if ( getInstantController() != DEFAULT_CONTROLLER )
 				{
-					if ( !safetyCheck_on_positionAndTilt(poseDataForThisAgent) )
+					if ( !safetyCheck_on_positionAndTilt(dataForThisAgent) )
 					{
 						setInstantController(DEFAULT_CONTROLLER);
 						ROS_INFO_STREAM("[FLYING AGENT CLIENT] safety check failed, switching to DEFAULT CONTROLLER");
@@ -268,24 +424,24 @@ void viconCallback(const ViconData& viconData)
 		else
 		{
 			// Increment the number of consective occulations
-			number_of_consecutive_occulsions++;
+			number_of_consecutive_invalid_measurements++;
 			// Update the flag if this exceeds the threshold
 			if (
-				(!m_isOcculded_mocap_data)
+				(m_isValid_measurement_data)
 				and
-				(number_of_consecutive_occulsions > yaml_consecutive_occulsions_threshold)
+				(number_of_consecutive_invalid_measurements > yaml_consecutive_invalid_threshold)
 			)
 			{
 				// Update the flag
-				m_isOcculded_mocap_data = true;
+				m_isValid_measurement_data = false;
 				// Inform the user
-				ROS_ERROR_STREAM("[FLYING AGENT CLIENT] Agent was occluded for more than " << yaml_consecutive_occulsions_threshold << " consecutive frames." );
+				ROS_ERROR_STREAM("[FLYING AGENT CLIENT] Measurement data was invalid for more than " << yaml_consecutive_invalid_threshold << " consecutive measurements." );
 				// Send the command to turn the motors off
 				sendZeroOutputCommandForMotors();
 				// Update the flying state
 				requestChangeFlyingStateTo( STATE_MOTORS_OFF );
 			}
-		} // END OF: "if(!poseDataForThisAgent.occluded)"
+		} // END OF: "if(dataForThisAgent.isValid)"
 
 	}
 	else
@@ -293,112 +449,56 @@ void viconCallback(const ViconData& viconData)
 		// Send the command to turn the motors off
 		sendZeroOutputCommandForMotors();
 
-	} // END OF: "if ( (m_poseDataIndex >= 0) and (m_controllers_avialble) )"
-
-}
+	} // END OF: "if (m_controllers_avialble)"
 
 
+}
 
 
 
-int getPoseDataForObjectNameWithExpectedIndex(const ViconData& viconData, std::string name , int expected_index , CrazyflieData& pose_to_fill_in)
+// FUNCTION FOR SENDING A COMMAND, VIA THE CRAZYRADIO, THAT
+// THE MOTORS SHOULD BE SET TO ZERO
+void sendZeroOutputCommandForMotors()
 {
-    // Initialise an integer for the index where the object
-    // "name" is found
-    // > Initialise an negative to indicate not found
-    int object_index = -1;
-
-    // Get the length of the "pose data array"
-    int length_poseData = viconData.crazyflies.size();
-
-    // If the "expected index" is non-negative and less than
-    // the length of the data array, then attempt to check
-    // for a name match
-    if (
-        (0 <= expected_index)
-        and
-        (expected_index < length_poseData)
-    )
-    {
-        // Check if the names match
-        if (viconData.crazyflies[expected_index].crazyflieName == name)
-        {
-            object_index = expected_index;
-        }
-    }
-
-    // If not found, then iterate the data array looking
-    // for a name match
-    if (object_index < 0)
-    {
-        for( int i=0 ; i<length_poseData ; i++ )
-        {    
-            // Check if the names match
-            if(viconData.crazyflies[i].crazyflieName == name)
-            {
-                object_index = i;
-            }
-        }
-    }
-
-    // If not found, then retrun, else fill in the pose data
-    if (object_index < 0)
-    {
-        return object_index;
-    }
-    else
-    {
-        pose_to_fill_in = viconData.crazyflies[object_index];
-        coordinatesToLocal(pose_to_fill_in);
-        return object_index;
-    }
+	// Initialise a "control command" struct
+	// > Note that all value are set to zero by default
+	ControlCommand zeroOutput = ControlCommand();
+	// To be sure, set the controller mode and motor command anyway
+	// > Specify that all controllers are disabled
+	zeroOutput.xControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+	zeroOutput.yControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+	zeroOutput.zControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+	zeroOutput.yawControllerMode = CF_ONBOARD_CONTROLLER_MODE_OFF;
+	// Fill in all motor thrusts as zero
+	zeroOutput.motorCmd1 = 0.0;
+	zeroOutput.motorCmd2 = 0.0;
+	zeroOutput.motorCmd3 = 0.0;
+	zeroOutput.motorCmd4 = 0.0;
+	// Publish the command
+	m_commandForSendingToCrazyfliePublisher.publish(zeroOutput);
 }
 
 
-void coordinatesToLocal(CrazyflieData& cf)
-{
-	// Get the area into a local variable
-    AreaBounds area = m_context.localArea;
-
-    // Shift the X-Y coordinates
-    float originX = (area.xmin + area.xmax) / 2.0;
-    float originY = (area.ymin + area.ymax) / 2.0;
-    cf.x -= originX;
-    cf.y -= originY;
-
-    // Shift the Z coordinate
-    // change Z origin to zero, i.e., to the table height, zero of global coordinates, instead of middle of the box
-    //float originZ = 0.0;
-    // float originZ = (area.zmin + area.zmax) / 2.0;
-    //cf.z -= originZ;
-}
-
 
-void timerCallback_mocap_timeout_check(const ros::TimerEvent&)
+// CALLBACK FUNCTION RUN WHEN MEASUREMENT DATA HAS
+// NOT BEEN RECEIVED FOR A SPECIFIED TIME
+void timerCallback_measurement_data_timeout_check(const ros::TimerEvent&)
 {
 	// Update the flag
-	m_isAvailable_mocap_data = false;
+	m_isAvailable_measurement_data = false;
 	// Inform the user
-	ROS_ERROR_STREAM("[FLYING AGENT CLIENT] Motion Capture Data has been unavailable for " << yaml_mocap_timeout_duration << " seconds." );
+	ROS_ERROR_STREAM("[FLYING AGENT CLIENT] Measurement data has been unavailable for " << yaml_measurement_timeout_duration << " seconds." );
 	// Ensure that the motors are turned off
 	if ( !(m_flying_state==STATE_MOTORS_OFF) )
 	{
 		// Send the command to turn the motors off
-        sendZeroOutputCommandForMotors();
-        // Update the flying state
-        requestChangeFlyingStateTo( STATE_MOTORS_OFF );
+		sendZeroOutputCommandForMotors();
+		// Update the flying state
+		requestChangeFlyingStateTo( STATE_MOTORS_OFF );
 	}
 }
 
 
-void sendZeroOutputCommandForMotors()
-{
-	ControlCommand zeroOutput = ControlCommand(); //everything set to zero
-    zeroOutput.onboardControllerType = CF_COMMAND_TYPE_MOTORS; //set to motor_mode
-    m_commandForSendingToCrazyfliePublisher.publish(zeroOutput);
-}
-
-
 
 
 
@@ -417,62 +517,62 @@ void sendZeroOutputCommandForMotors()
 //    ----------------------------------------------------------------------------------
 
 // Checks if crazyflie is within allowed area
-bool safetyCheck_on_positionAndTilt(CrazyflieData data)
+bool safetyCheck_on_positionAndTilt(FlyingVehicleState data)
 {
-    // Check on the X position
-    float symmetric_bound_x = 0.5 * (m_context.localArea.xmax-m_context.localArea.xmin);
-    if((data.x < -symmetric_bound_x) or (data.x > symmetric_bound_x))
-    {
-        ROS_INFO_STREAM("[FLYING AGENT CLIENT] x safety failed");
-        return false;
-    }
-    // Check on the Y position
-    float symmetric_bound_y = 0.5 * (m_context.localArea.ymax-m_context.localArea.ymin);
-    if((data.y < -symmetric_bound_y) or (data.y > symmetric_bound_y))
-    {
-        ROS_INFO_STREAM("[FLYING AGENT CLIENT] y safety failed");
-        return false;
-    }
-    // Check on the Z position
-    if((data.z < m_context.localArea.zmin) or (data.z > m_context.localArea.zmax))
-    {
-        ROS_INFO_STREAM("[FLYING AGENT CLIENT] z safety failed");
-        return false;
-    }
+	// Check on the X position
+	float symmetric_bound_x = 0.5 * (m_context.localArea.xmax-m_context.localArea.xmin);
+	if((data.x < -symmetric_bound_x) or (data.x > symmetric_bound_x))
+	{
+		ROS_INFO_STREAM("[FLYING AGENT CLIENT] x safety failed");
+		return false;
+	}
+	// Check on the Y position
+	float symmetric_bound_y = 0.5 * (m_context.localArea.ymax-m_context.localArea.ymin);
+	if((data.y < -symmetric_bound_y) or (data.y > symmetric_bound_y))
+	{
+		ROS_INFO_STREAM("[FLYING AGENT CLIENT] y safety failed");
+		return false;
+	}
+	// Check on the Z position
+	if((data.z < m_context.localArea.zmin) or (data.z > m_context.localArea.zmax))
+	{
+		ROS_INFO_STREAM("[FLYING AGENT CLIENT] z safety failed");
+		return false;
+	}
 
-    // Check the title angle (if required)
-    // > The tilt anlge between the body frame and inertial frame z-axis is
-    //   give by:
-    //   tilt angle  =  1 / ( cos(roll)*cos(pitch) )
-    // > But this would be too sensitve to a divide by zero error, so instead
-    //   we just check if each angle separately exceeds the limit
-    if(yaml_isEnabled_strictSafety)
-    {
-        // Check on the ROLL angle
-        if(
-            (data.roll > yaml_maxTiltAngle_for_strictSafety_radians)
-            or
-            (data.roll < -yaml_maxTiltAngle_for_strictSafety_radians)
-        )
-        {
-            ROS_INFO_STREAM("[FLYING AGENT CLIENT] roll too big.");
-            return false;
-        }
-        // Check on the PITCH angle
-        if(
-            (data.pitch > yaml_maxTiltAngle_for_strictSafety_radians)
-            or
-            (data.pitch < -yaml_maxTiltAngle_for_strictSafety_radians)
-        )
-        {
-            ROS_INFO_STREAM("[FLYING AGENT CLIENT] pitch too big.");
-            return false;
-        }
-    }
+	// Check the title angle (if required)
+	// > The tilt anlge between the body frame and inertial frame z-axis is
+	//   give by:
+	//   tilt angle  =  1 / ( cos(roll)*cos(pitch) )
+	// > But this would be too sensitve to a divide by zero error, so instead
+	//   we just check if each angle separately exceeds the limit
+	if(yaml_isEnabled_strictSafety)
+	{
+		// Check on the ROLL angle
+		if(
+			(data.roll > yaml_maxTiltAngle_for_strictSafety_radians)
+			or
+			(data.roll < -yaml_maxTiltAngle_for_strictSafety_radians)
+		)
+		{
+			ROS_INFO_STREAM("[FLYING AGENT CLIENT] roll too big.");
+			return false;
+		}
+		// Check on the PITCH angle
+		if(
+			(data.pitch > yaml_maxTiltAngle_for_strictSafety_radians)
+			or
+			(data.pitch < -yaml_maxTiltAngle_for_strictSafety_radians)
+		)
+		{
+			ROS_INFO_STREAM("[FLYING AGENT CLIENT] pitch too big.");
+			return false;
+		}
+	}
 
-    // If the code makes it to here then all the safety checks passed,
-    // Hence return "true"
-    return true;
+	// If the code makes it to here then all the safety checks passed,
+	// Hence return "true"
+	return true;
 }
 
 
@@ -560,7 +660,7 @@ void requestChangeFlyingStateToTakeOff()
 	else
 	{
 		// Check that the Motion Capture data is available
-		if ( m_isAvailable_mocap_data and !m_isOcculded_mocap_data )
+		if ( m_isAvailable_measurement_data and m_isValid_measurement_data )
 		{
 			// Check whether a "controller" take-off should
 			// be performed, and that not already in the
@@ -614,13 +714,13 @@ void requestChangeFlyingStateToTakeOff()
 		else
 		{
 			// Inform the user of the problem
-			if (!m_isAvailable_mocap_data)
+			if (!m_isAvailable_measurement_data)
 			{
-				ROS_ERROR("[FLYING AGENT CLIENT] Take-off not possible because the motion capture data is unavailable.");
+				ROS_ERROR("[FLYING AGENT CLIENT] Take-off not possible because the measurement data is unavailable.");
 			}
-			if (m_isOcculded_mocap_data)
+			if (!m_isValid_measurement_data)
 			{
-				ROS_ERROR("[FLYING AGENT CLIENT] Take-off not possible because the object is \"long-term\" occuled.");
+				ROS_ERROR("[FLYING AGENT CLIENT] Take-off not possible because the object measurements are \"long-term\" invalid.");
 			}
 		}
 	}
@@ -1217,7 +1317,8 @@ void loadCrazyflieContext()
         m_context = new_context;
 
         ros::NodeHandle nh("CrazyRadio");
-        nh.setParam("crazyFlieAddress", m_context.crazyflieAddress);
+        nh.setParam("crazyflieAddress", m_context.crazyflieAddress);
+        nh.setParam("crazyflieName", m_context.crazyflieName);
     }
     else
     {
@@ -1394,22 +1495,26 @@ void isReadyFlyingAgentClientConfigYamlCallback(const IntWithHeader & msg)
 // > Load the paramters from the Client Config YAML file
 void fetchFlyingAgentClientConfigYamlParameters(ros::NodeHandle& nodeHandle)
 {
-    // Here we load the parameters that are specified in the file:
-    // FlyingAgentClientConfig.yaml
+	// Here we load the parameters that are specified in the file:
+	// FlyingAgentClientConfig.yaml
 
-    // Add the "FlyingAgentClientConfig" namespace to the "nodeHandle"
-    ros::NodeHandle nodeHandle_for_paramaters(nodeHandle, "FlyingAgentClientConfig");
+	// Add the "FlyingAgentClientConfig" namespace to the "nodeHandle"
+	ros::NodeHandle nodeHandle_for_paramaters(nodeHandle, "FlyingAgentClientConfig");
 
-    // Flag for whether to use angle for switching to the Safe Controller
-    yaml_isEnabled_strictSafety = getParameterBool(nodeHandle_for_paramaters,"isEnabled_strictSafety");
-    yaml_maxTiltAngle_for_strictSafety_degrees = getParameterFloat(nodeHandle_for_paramaters,"maxTiltAngle_for_strictSafety_degrees");
+	// Flags for which measurement streams to use
+	yaml_shouldUse_mocapMeasurements = getParameterBool(nodeHandle_for_paramaters,"shouldUse_mocapMeasurements");
+	yaml_shouldUse_onboardEstimate   = getParameterBool(nodeHandle_for_paramaters,"shouldUse_onboardEstimate");
 
-    // Number of consecutive occulsions that will deem the
-    // object as "long-term" occuled
-	yaml_consecutive_occulsions_threshold = getParameterInt(nodeHandle_for_paramaters,"consecutive_occulsions_threshold");
+	// Flag for whether to use angle for switching to the Safe Controller
+	yaml_isEnabled_strictSafety = getParameterBool(nodeHandle_for_paramaters,"isEnabled_strictSafety");
+	yaml_maxTiltAngle_for_strictSafety_degrees = getParameterFloat(nodeHandle_for_paramaters,"maxTiltAngle_for_strictSafety_degrees");
+
+	// Number of consecutive occulsions that will deem the
+	// object as "long-term" occuled
+	yaml_consecutive_invalid_threshold = getParameterInt(nodeHandle_for_paramaters,"consecutive_invalid_threshold");
 
 	// Time out duration after which Mocap is considered unavailable
-	yaml_mocap_timeout_duration = getParameterFloat(nodeHandle_for_paramaters,"mocap_timeout_duration");
+	yaml_measurement_timeout_duration = getParameterFloat(nodeHandle_for_paramaters,"measurement_timeout_duration");
 
 	// Flag for whether the take-off should be performed
 	//  with the default controller
@@ -1418,18 +1523,65 @@ void fetchFlyingAgentClientConfigYamlParameters(ros::NodeHandle& nodeHandle)
 	// Flag for whether the landing should be performed
 	// with the default controller
 	yaml_shouldPerfom_landing_with_defaultController = getParameterBool(nodeHandle_for_paramaters,"shouldPerfom_landing_with_defaultController");
-    
-    // DEBUGGING: Print out one of the parameters that was loaded
-    ROS_INFO_STREAM("[FLYING AGENT CLIENT] DEBUGGING: the fetched FlyingAgentClientConfig/isEnabled_strictSafety = " << yaml_isEnabled_strictSafety);
 
+	// DEBUGGING: Print out one of the parameters that was loaded
+	ROS_INFO_STREAM("[FLYING AGENT CLIENT] DEBUGGING: the fetched FlyingAgentClientConfig/isEnabled_strictSafety = " << yaml_isEnabled_strictSafety);
 
 
-    // PROCESS THE PARAMTERS
-    // Convert from degrees to radians
-    yaml_maxTiltAngle_for_strictSafety_radians = DEG2RAD * yaml_maxTiltAngle_for_strictSafety_degrees;
 
-    // DEBUGGING: Print out one of the processed values
-    ROS_INFO_STREAM("[FLYING AGENT CLIENT CONTROLLER] DEBUGGING: after processing yaml_maxTiltAngle_for_strictSafety_radians = " << yaml_maxTiltAngle_for_strictSafety_radians);
+	// PROCESS THE PARAMTERS
+	// Convert from degrees to radians
+	yaml_maxTiltAngle_for_strictSafety_radians = DEG2RAD * yaml_maxTiltAngle_for_strictSafety_degrees;
+
+	// Adjust the measurement subscribers
+	// > Localisation data from motion capture
+	if (yaml_shouldUse_mocapMeasurements)
+	{
+		// > Create a node handle to the root of the D-FaLL system
+		ros::NodeHandle nodeHandle_dfall_root("/dfall");
+		// > The second argument is the queue_size, and the
+		//   documentation states that:
+		//   "If messages are arriving too fast and you are
+		//    unable to keep up, roscpp will start throwing
+		//    away messages."
+		// > It is clearly stated that publisher queues throw
+		//   away old messages first, and subscriber queues
+		//   are likely the same.
+		// > As we are only interested in latest measurement
+		//   a short queue is used.
+		viconSubscriber = nodeHandle_dfall_root.subscribe("ViconDataPublisher/ViconData", 3, viconCallback);
+	}
+	else
+	{
+		viconSubscriber.shutdown();
+	}
+
+	// > Localisation from onboard the flying vehicle
+	if (yaml_shouldUse_onboardEstimate)
+	{
+		// > Create a node handle for the Crazyradio
+		std::string m_namespace = ros::this_node::getNamespace();
+		std::string namespace_to_crazy_radio = m_namespace + "/CrazyRadio";
+		ros::NodeHandle nodeHandle_to_crazy_radio(namespace_to_crazy_radio);
+		// > The second argument is the queue_size, and the
+		//   documentation states that:
+		//   "If messages are arriving too fast and you are
+		//    unable to keep up, roscpp will start throwing
+		//    away messages."
+		// > It is clearly stated that publisher queues throw
+		//   away old messages first, and subscriber queues
+		//   are likely the same.
+		// > As we are only interested in latest measurement
+		//   a short queue is used.
+		onboardEstimateSubscriber = nodeHandle_to_crazy_radio.subscribe("CFStateEstimate", 3, onboardEstimateCallback);
+	}
+	else
+	{
+		onboardEstimateSubscriber.shutdown();
+	}
+
+	// DEBUGGING: Print out one of the processed values
+	ROS_INFO_STREAM("[FLYING AGENT CLIENT CONTROLLER] DEBUGGING: after processing yaml_maxTiltAngle_for_strictSafety_radians = " << yaml_maxTiltAngle_for_strictSafety_radians);
 }
 
 
@@ -1563,9 +1715,9 @@ int main(int argc, char* argv[])
 
 	// INITIALISE THE MOTION CAPTURE TIME-OUT TIMER
 	// > And stop it immediately
-	m_isAvailable_mocap_data = false;
-	m_timer_mocap_timeout_check = nodeHandle.createTimer(ros::Duration(yaml_mocap_timeout_duration), timerCallback_mocap_timeout_check, true);
-	m_timer_mocap_timeout_check.stop();
+	m_isAvailable_measurement_data = false;
+	m_timer_measurement_data_timeout_check = nodeHandle.createTimer(ros::Duration(yaml_measurement_timeout_duration), timerCallback_measurement_data_timeout_check, true);
+	m_timer_measurement_data_timeout_check.stop();
 
 
 
@@ -1602,6 +1754,10 @@ int main(int argc, char* argv[])
 	constructNamespaceForCoordinator( m_coordID, namespace_to_coordinator );
 	ros::NodeHandle nodeHandle_to_coordinator(namespace_to_coordinator);
 
+	// CREATE A NODE HANDLE FOR THE CRAZYRADIO
+	std::string namespace_to_crazy_radio = m_namespace + "/CrazyRadio";
+	ros::NodeHandle nodeHandle_to_crazy_radio(namespace_to_crazy_radio);
+
 
 	// LOADING OF THIS AGENT'S CONTEXT
 	// Service cleint for loading the allocated flying
@@ -1620,13 +1776,41 @@ int main(int argc, char* argv[])
 
 
 	// LOCALISATION DATA FROM MOTION CAPTURE SYSTEM
-	//keeps 100 messages because otherwise ViconDataPublisher would override the data immediately
-	ros::Subscriber viconSubscriber = nodeHandle_dfall_root.subscribe("ViconDataPublisher/ViconData", 100, viconCallback);
+	// > The second argument is the queue_size, and the
+	//   documentation states that:
+	//   "If messages are arriving too fast and you are
+	//    unable to keep up, roscpp will start throwing
+	//    away messages."
+	// > It is clearly stated that publisher queues throw
+	//   away old messages first, and subscriber queues
+	//   are likely the same.
+	// > As we are only interested in latest measurement
+	//   a short queue is used.
+	if (yaml_shouldUse_mocapMeasurements)
+	{
+		viconSubscriber = nodeHandle_dfall_root.subscribe("ViconDataPublisher/ViconData", 3, viconCallback);
+	}
 
 
+	// LOCALISATION DATA FROM ONBOARD THE FLYING VEHICLE
+	// > The second argument is the queue_size, and the
+	//   documentation states that:
+	//   "If messages are arriving too fast and you are
+	//    unable to keep up, roscpp will start throwing
+	//    away messages."
+	// > It is clearly stated that publisher queues throw
+	//   away old messages first, and subscriber queues
+	//   are likely the same.
+	// > As we are only interested in latest measurement
+	//   a short queue is used.
+	if (yaml_shouldUse_onboardEstimate)
+	{
+		onboardEstimateSubscriber = nodeHandle_to_crazy_radio.subscribe("CFStateEstimate", 3, onboardEstimateCallback);
+	}
+
 
 	// PUBLISHER FOR COMMANDING THE CRAZYFLIE
-	// i.e., motorCmd{1,2,3,4}, roll, pitch, yaw, and onboardControllerType
+	// i.e., motorCmd{1,2,3,4}, and the {x,y,z,yaw} controller modes and setpoints
 	//ros::Publishers to advertise the control output
 	m_commandForSendingToCrazyfliePublisher = nodeHandle.advertise <ControlCommand>("ControlCommand", 1);
 
@@ -1660,9 +1844,7 @@ int main(int argc, char* argv[])
 
 
 	// SUBSCRIBER FOR CRAZY RADIO STATUS CHANGES
-	// crazyradio status. Connected, connecting or disconnected
-	std::string namespace_to_crazy_radio = m_namespace + "/CrazyRadio";
-	ros::NodeHandle nodeHandle_to_crazy_radio(namespace_to_crazy_radio);
+	// Crazyradio status: { connected , connecting , disconnected }
 	ros::Subscriber crazyRadioStatusSubscriber = nodeHandle_to_crazy_radio.subscribe("CrazyRadioStatus", 1, crazyRadioStatusCallback);
 
 
diff --git a/dfall_ws/src/dfall_pkg/src/nodes/MocapEmulator.cpp b/dfall_ws/src/dfall_pkg/src/nodes/MocapEmulator.cpp
index f4dfe8e42d2f63d9f50564f0fdc6e775da885587..54fa2eee667c074f288f84d2992baf5f2525403f 100644
--- a/dfall_ws/src/dfall_pkg/src/nodes/MocapEmulator.cpp
+++ b/dfall_ws/src/dfall_pkg/src/nodes/MocapEmulator.cpp
@@ -58,46 +58,51 @@
 
 void timerCallback_mocap_publisher(const ros::TimerEvent&)
 {
-	//ROS_INFO("[MOCAP EMULATOR] temp");
-
 	// Initilise a "ViconData" struct
 	// > This is defined in the "ViconData.msg" file
 	ViconData mocapData;
 
 	// Get the number of quadrotors
-	unsigned int quadrotor_count = m_quadrotor_fleet.size();
+	unsigned int quadrotor_count = m_flying_fleet_states.size();
 
 	// If there are any quadrotors:
 	if (quadrotor_count>0)
 	{
 
 		// Iterate through the vector of quadrotors
-		for(std::vector<QuadrotorSimulator>::iterator it = m_quadrotor_fleet.begin(); it != m_quadrotor_fleet.end(); ++it)
+		for(std::vector<FlyingVehicleState>::iterator it = m_flying_fleet_states.begin(); it != m_flying_fleet_states.end(); ++it)
 		{
 			// Access that current element as *it
 
 			// Get the index if needed
-			//int idx = std::distance( m_quadrotor_fleet.begin() , it );
+			int idx = std::distance( m_flying_fleet_states.begin() , it );
 
-			// Simulate the quadrotor for one time step
-			it->simulate_for_one_time_step( yaml_mocap_deltaT_in_seconds );
+			// Convert the state to global
+			float local_x  = it->x;
+			float local_y  = it->y;
+			float local_z  = it->z;
+			float global_x = local_x + (m_flying_fleet_areaBounds[idx].xmin + m_flying_fleet_areaBounds[idx].xmax) / 2.0;
+			float global_y = local_y + (m_flying_fleet_areaBounds[idx].ymin + m_flying_fleet_areaBounds[idx].ymax) / 2.0;
+			float global_z = local_z; // + (m_flying_fleet_areaBounds[idx].zmin + m_flying_fleet_areaBounds[idx].zmax) / 2.0;
 
 			// Local variable for the data of this quadrotor
-			CrazyflieData quadrotor_data;
+			FlyingVehicleState quadrotor_data;
 
 			// Fill in the details
+			// > For the type
+			quadrotor_data.type = FLYING_VEHICLE_STATE_TYPE_MOCAP_MEASUREMENT;
 			// > For the name
-			quadrotor_data.crazyflieName = it->m_id_string;
+			quadrotor_data.vehicleName = it->vehicleName;
 			// > For the occulsion flag
-			quadrotor_data.occluded = false;
+			quadrotor_data.isValid = it->isValid;
 			// > For position
-			quadrotor_data.x = it->m_position[0];
-			quadrotor_data.y = it->m_position[1];
-			quadrotor_data.z = it->m_position[2];
+			quadrotor_data.x = global_x;
+			quadrotor_data.y = global_y;
+			quadrotor_data.z = global_z;
 			// > For euler angles
-			quadrotor_data.roll  = it->m_euler_angles[0];
-			quadrotor_data.pitch = it->m_euler_angles[1];
-			quadrotor_data.yaw   = it->m_euler_angles[2];
+			quadrotor_data.roll  = it->roll;
+			quadrotor_data.pitch = it->pitch;
+			quadrotor_data.yaw   = it->yaw;
 			// > For the acquiring time
 			quadrotor_data.acquiringTime = 0.0;
 
@@ -114,6 +119,21 @@ void timerCallback_mocap_publisher(const ros::TimerEvent&)
 
 
 
+// CALLBACK FOR RECEIVEING CRAZYFLIE SIMULATION DATA
+// > This data is published by the CrazyRadioEmulator node
+void cfSimulationStateCallback(const FlyingVehicleState & msg)
+{
+	// Extract the id string
+	std::string id_as_string = msg.vehicleName;
+	// Convert the id to an integer
+	int id_as_int = std::stoi( id_as_string.substr( id_as_string.length()-2 ) );
+	// Update the corresponding entry of the "m_flying_fleet_states"
+	m_flying_fleet_states[id_as_int] = msg;
+}
+
+
+
+
 //    ----------------------------------------------------------------------------------
 //    L       OOO     A    DDDD
 //    L      O   O   A A   D   D
@@ -145,21 +165,21 @@ void loadContextForEachQuadrotor()
 
 	// Iterate through the quadrotors
 	// Iterate through the vector of quadrotors
-	for(std::vector<QuadrotorSimulator>::iterator it = m_quadrotor_fleet.begin(); it != m_quadrotor_fleet.end(); ++it)
+	for(std::vector<FlyingVehicleState>::iterator it = m_flying_fleet_states.begin(); it != m_flying_fleet_states.end(); ++it)
 	{
 		// Access that current element as *it
 
 		// Get the index if needed
-		//int idx = std::distance( m_quadrotor_fleet.begin() , it );
+		int idx = std::distance( m_flying_fleet_states.begin() , it );
 
 		// Local variable for the service call
 		CMQueryCrazyflieName contextCall;
 
 		// Set the name of this quadrotor
-		contextCall.request.crazyflieName = it->m_id_string;
+		contextCall.request.crazyflieName = it->vehicleName;
 
 		// Wait for the service to exist
-		m_centralManagerService.waitForExistence(ros::Duration(0.5));
+		m_centralManagerService.waitForExistence(ros::Duration(0));
 
 		// Local variable for the agent ID
 		int new_agent_id = -1;
@@ -176,28 +196,28 @@ void loadContextForEachQuadrotor()
 			// Update the reset position of the quadrotor simulator
 			// to be the center of the context
 			// > Get the area into a local variable
-    		AreaBounds area = new_context.localArea;
-    		// > Compute the X-Y coordinates
-			float new_reset_x = (area.xmin + area.xmax) / 2.0;
-			float new_reset_y = (area.ymin + area.ymax) / 2.0;
+			m_flying_fleet_areaBounds[idx] = new_context.localArea;
+			// > Compute the X-Y coordinates
+			//float new_reset_x = (area.xmin + area.xmax) / 2.0;
+			//float new_reset_y = (area.ymin + area.ymax) / 2.0;
 			// > Update the reset state
-    		it->setResetState_xyz_yaw(new_reset_x,new_reset_y,0.0,0.0);
+			//it->setResetState_xyz_yaw(new_reset_x,new_reset_y,0.0,0.0);
 
 			// Print out the new context
-			//ROS_INFO_STREAM("[MOCAP EMULATOR] Quadrotor simulator with ID \"" << it->m_id_string << "\" connected to agent ID " << new_agent_id << " in database.");
+			//ROS_INFO_STREAM("[MOCAP EMULATOR] Quadrotor simulator with ID \"" << it->get_id_string() << "\" connected to agent ID " << new_agent_id << " in database.");
 		}
 		else
 		{
-			// Let the user know that the "m_id_string" was not found
+			// Let the user know that the "id_string" was not found
 			// for this quadrotor simulation
-			ROS_INFO_STREAM("[MOCAP EMULATOR] Quadrotor simulator with ID \"" << it->m_id_string << "\" does not appear in the database.");
+			//ROS_INFO_STREAM("[MOCAP EMULATOR] Quadrotor simulator with ID \"" << it->get_id_string() << "\" does not appear in the database.");
 
 			// Set the "new agent id" to reflect this
 			new_agent_id = -1;
 		}
 
 		// Update the agent id of quadrotor simulator
-		it->update_commanding_agent_id( new_agent_id );
+		//it->update_commanding_agent_id( new_agent_id );
 	}
 }
 
@@ -220,35 +240,35 @@ void loadContextForEachQuadrotor()
 
 void fetchMocapEmulatorConfigYamlParameters()
 {
-    // Create a "ros::NodeHandle" type local variable
-    // "nodeHandle_for_paramaters"
-    // as the current node, the "~" indcates that "self"
-    // is the node handle assigned to this variable.
-    ros::NodeHandle nodeHandle_for_paramaters("~");
+	// Create a "ros::NodeHandle" type local variable
+	// "nodeHandle_for_paramaters"
+	// as the current node, the "~" indcates that "self"
+	// is the node handle assigned to this variable.
+	ros::NodeHandle nodeHandle_for_paramaters("~");
 
 	// FREQUENCY OF THE MOTION CAPTURE EMULATOR [Hertz]
 	yaml_mocap_frequency = getParameterFloat(nodeHandle_for_paramaters,"mocap_frequency");
 
 	// THE COEFFICIENT OF THE 16-BIT COMMAND TO THRUST CONVERSION
-	getParameterFloatVector(nodeHandle_for_paramaters, "motorPoly", yaml_motorPoly, 3);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "motorPoly", yaml_motorPoly, 3);
 
 	// THE MIN AND MAX FOR SATURATING THE 16-BIT THRUST COMMANDS
 	yaml_command_sixteenbit_min = getParameterFloat(nodeHandle_for_paramaters, "command_sixteenbit_min");
 	yaml_command_sixteenbit_max = getParameterFloat(nodeHandle_for_paramaters, "command_sixteenbit_max");
 
 
-    
-    // DEBUGGING: Print out one of the parameters that was loaded
-    ROS_INFO_STREAM("[MOCAP EMULATOR] DEBUGGING: the fetched mocap_frequency = " << yaml_mocap_frequency);
+
+	// DEBUGGING: Print out one of the parameters that was loaded
+	ROS_INFO_STREAM("[MOCAP EMULATOR] DEBUGGING: the fetched mocap_frequency = " << yaml_mocap_frequency);
 
 
 
-    // PROCESS THE PARAMTERS
-    // Convert from Hertz to second
-    yaml_mocap_deltaT_in_seconds = 1.0 / yaml_mocap_frequency;
+	// PROCESS THE PARAMTERS
+	// Convert from Hertz to second
+	yaml_mocap_deltaT_in_seconds = 1.0 / yaml_mocap_frequency;
 
-    // DEBUGGING: Print out one of the processed values
-    ROS_INFO_STREAM("[MOCAP EMULATOR] DEBUGGING: after processing yaml_mocap_deltaT_in_seconds = " << yaml_mocap_deltaT_in_seconds);
+	// DEBUGGING: Print out one of the processed values
+	ROS_INFO_STREAM("[MOCAP EMULATOR] DEBUGGING: after processing yaml_mocap_deltaT_in_seconds = " << yaml_mocap_deltaT_in_seconds);
 }
 
 
@@ -291,42 +311,57 @@ int main(int argc, char* argv[])
 
 
 
+	// CREATE A NODE HANDLE TO THE ROOT OF THE D-FaLL SYSTEM
+	ros::NodeHandle nodeHandle_dfall_root("/dfall");
+
+
+
 	// ADD QUADROTORS TO THE FLEET
 
-	for ( int i_quad=1 ; i_quad<3 ; i_quad++ )
+	for ( int i_quad=1 ; i_quad<4 ; i_quad++ )
 	{
-		// Create a string for the ID, zero padded
-		std::ostringstream str_stream;
-		str_stream << std::setw(2) << std::setfill('0') << i_quad;
-		std::string this_quad_id_as_string(str_stream.str());
-		// Create an instance of a quadrotor
-		QuadrotorSimulator quadsim("CF"+this_quad_id_as_string,0.032);
 		// Compute the x-coordinate of the reset state
 		float this_reset_x = float(i_quad-1) * 1.0 + 0.5;
-		// Set the reset state
-		quadsim.setResetState_xyz_yaw(this_reset_x,0.0,0.0,0.0);
-		// Set the parameters for the 16-bit command to thrust conversion
-		quadsim.setParameters_for_16bitCommand_to_thrust_conversion(yaml_motorPoly[0], yaml_motorPoly[1], yaml_motorPoly[2], yaml_command_sixteenbit_min, yaml_command_sixteenbit_max);
-		// Reset the quadrotor
-		quadsim.reset();
-		// Push back into the vector of resets
-		m_quadrotor_fleet.push_back(quadsim);
-	}
-
-	// Display the details of all quadrotors added
-	ROS_INFO_STREAM("[MOCAP EMULATOR] Added " << m_quadrotor_fleet.size() << " quadrotos with the following details:" );
 
-	// Iterate through the vector of quadrotors
-	for(std::vector<QuadrotorSimulator>::iterator it = m_quadrotor_fleet.begin(); it != m_quadrotor_fleet.end(); ++it)
-	{
-		// Access that current element as *it
+		// Create a string for the ID, zero padded
+		// > of length 2
+		std::ostringstream str_stream_02;
+		str_stream_02 << std::setw(2) << std::setfill('0') << i_quad;
+		std::string this_quad_id_as_string(str_stream_02.str());
+		// > of length 3
+		std::ostringstream str_stream_03;
+		str_stream_03 << std::setw(3) << std::setfill('0') << i_quad;
+		std::string this_agent_id_as_string(str_stream_03.str());
+
+		// Prepare a reset state of this flying vehicle
+		FlyingVehicleState this_state;
+		this_state.x       = 0.0f;
+		this_state.y       = 0.0f;
+		this_state.z       = 0.0f;
+		this_state.roll    = 0.0f;
+		this_state.pitch   = 0.0f;
+		this_state.yaw     = 0.0f;
+		this_state.isValid = false;
+		this_state.vehicleName = "CF"+this_quad_id_as_string;
+
+		// Push back into the vector of states
+		m_flying_fleet_states.push_back(this_state);
+
+		// Subscribe to the messages for this vehicle
+		m_flying_fleet_state_subscribers.push_back( nodeHandle_dfall_root.subscribe("agent"+this_agent_id_as_string+"/CrazyRadio/CFSimulationState", 50, cfSimulationStateCallback) );
+
+		// Set the Area Bounds
+		AreaBounds this_area;
+		this_area.xmin = -1.0f + this_reset_x;
+		this_area.xmax =  1.0f + this_reset_x;
+		this_area.ymin = -1.0f;
+		this_area.ymax =  1.0f;
+		this_area.zmin =  0.0f;
+		this_area.zmax =  2.0f;
+		m_flying_fleet_areaBounds.push_back( this_area );
+
+		ROS_INFO_STREAM("this_reset_x = " << this_reset_x);
 
-		// Get the index if needed
-		//int idx = std::distance( m_quadrotor_fleet.begin() , it );
-		
-		// Call the function to print out the details
-		it->print_details();
-		//(*it).print_details();
 	}
 
 
@@ -346,10 +381,6 @@ int main(int argc, char* argv[])
     m_mocapDataPublisher = nodeHandle.advertise<ViconData>("ViconData", 1);
 
 
-    // CREATE A NODE HANDLE TO THE ROOT OF THE D-FaLL SYSTEM
-	ros::NodeHandle nodeHandle_dfall_root("/dfall");
-
-
 
     // SUBSCRIBER FOR DATABASE CHANGES
     // > This is the database of tuples of the form:
diff --git a/dfall_ws/src/dfall_pkg/src/nodes/MpcControllerService.cpp b/dfall_ws/src/dfall_pkg/src/nodes/MpcControllerService.cpp
index 9a0545e31edbb227f31deb314f7443a02fe59a6e..675e5a323b9a50bde9683f2c4f8f7973787eabe4 100644
--- a/dfall_ws/src/dfall_pkg/src/nodes/MpcControllerService.cpp
+++ b/dfall_ws/src/dfall_pkg/src/nodes/MpcControllerService.cpp
@@ -174,20 +174,6 @@ std::string namespace_to_coordinator_parameter_service;
 int my_agentID = 0;
 
 
-// RELEVANT NOTES ABOUT THE VARIABLES DECLARE HERE:
-// The "CrazyflieData" type used for the "request" variable is a
-// structure as defined in the file "CrazyflieData.msg" which has the following
-// properties:
-//     string crazyflieName              The name given to the Crazyflie in the Vicon software
-//     float64 x                         The x position of the Crazyflie [metres]
-//     float64 y                         The y position of the Crazyflie [metres]
-//     float64 z                         The z position of the Crazyflie [metres]
-//     float64 roll                      The roll component of the intrinsic Euler angles [radians]
-//     float64 pitch                     The pitch component of the intrinsic Euler angles [radians]
-//     float64 yaw                       The yaw component of the intrinsic Euler angles [radians]
-//     float64 acquiringTime #delta t    The time elapsed since the previous "CrazyflieData" was received [seconds]
-//     bool occluded                     A boolean indicted whether the Crazyflie for visible at the time of this measurement
-
 
 
 
@@ -223,7 +209,7 @@ void setpointCallback(const Setpoint& newSetpoint);
 
 // LOAD PARAMETERS
 float getParameterFloat(ros::NodeHandle& nodeHandle, std::string name);
-void getParameterFloatVector(ros::NodeHandle& nodeHandle, std::string name, std::vector<float>& val, int length);
+void getParameterFloatVectorKnownLength(ros::NodeHandle& nodeHandle, std::string name, std::vector<float>& val, int length);
 int getParameterInt(ros::NodeHandle& nodeHandle, std::string name);
 void getParameterIntVectorWithKnownLength(ros::NodeHandle& nodeHandle, std::string name, std::vector<int>& val, int length);
 int getParameterIntVectorWithUnknownLength(ros::NodeHandle& nodeHandle, std::string name, std::vector<int>& val);
@@ -282,22 +268,22 @@ void performEstimatorUpdate_forStateInterial_viaPointMassKalmanFilter(float (&st
 // The arument "request" is a structure provided to this service with the following two
 // properties:
 // request.ownCrazyflie
-// This property is itself a structure of type "CrazyflieData",  which is defined in the
-// file "CrazyflieData.msg", and has the following properties
-// string crazyflieName
+// This property is itself a structure of type "FlyingVehicleState",  which is defined in the
+// file "FlyingVehicleState.msg", and has the following properties
+//     string vehicleName
 //     float64 x                         The x position of the Crazyflie [metres]
 //     float64 y                         The y position of the Crazyflie [metres]
 //     float64 z                         The z position of the Crazyflie [metres]
 //     float64 roll                      The roll component of the intrinsic Euler angles [radians]
 //     float64 pitch                     The pitch component of the intrinsic Euler angles [radians]
 //     float64 yaw                       The yaw component of the intrinsic Euler angles [radians]
-//     float64 acquiringTime #delta t    The time elapsed since the previous "CrazyflieData" was received [seconds]
-//     bool occluded                     A boolean indicted whether the Crazyflie for visible at the time of this measurement
+//     float64 acquiringTime #delta t    The time elapsed since the previous "FlyingVehicleState" was received [seconds]
+//     bool isValid                      A boolean indicted whether the Crazyflie for visible at the time of this measurement
 // The values in these properties are directly the measurement taken by the Vicon
 // motion capture system of the Crazyflie that is to be controlled by this service
 //
 // request.otherCrazyflies
-// This property is an array of "CrazyflieData" structures, what allows access to the
+// This property is an array of "FlyingVehicleState" structures, what allows access to the
 // Vicon measurements of other Crazyflies.
 //
 // The argument "response" is a structure that is expected to be filled in by this
@@ -718,26 +704,26 @@ void fetchYamlParameters(ros::NodeHandle& nodeHandle)
 
 	// > The co-efficients of the quadratic conversation from 16-bit motor command to
 	//   thrust force in Newtons
-	getParameterFloatVector(nodeHandle_for_MpcController, "motorPoly", motorPoly, 3);
+	getParameterFloatVectorKnownLength(nodeHandle_for_MpcController, "motorPoly", motorPoly, 3);
 
 
 	// DEBUGGING: Print out one of the parameters that was loaded
 	ROS_INFO_STREAM("[MPC CONTROLLER] DEBUGGING: the fetched CustomController/mass = " << cf_mass);
 
-    getParameterFloatVector(nodeHandle_for_MpcController, "gainMatrixRollRate_Nested",             gainMatrixRollRate_Nested,             3);
-	getParameterFloatVector(nodeHandle_for_MpcController, "gainMatrixPitchRate_Nested",            gainMatrixPitchRate_Nested,            3);
-	getParameterFloatVector(nodeHandle_for_MpcController, "gainMatrixYawRate_Nested",              gainMatrixYawRate_Nested,              3);
+    getParameterFloatVectorKnownLength(nodeHandle_for_MpcController, "gainMatrixRollRate_Nested",             gainMatrixRollRate_Nested,             3);
+	getParameterFloatVectorKnownLength(nodeHandle_for_MpcController, "gainMatrixPitchRate_Nested",            gainMatrixPitchRate_Nested,            3);
+	getParameterFloatVectorKnownLength(nodeHandle_for_MpcController, "gainMatrixYawRate_Nested",              gainMatrixYawRate_Nested,              3);
 
 
     // THE POINT MASS KALMAN FILTER (PMKF) GAINS AND ERROR EVOLUATION
 	// > For the (x,y,z) position
-	getParameterFloatVector(nodeHandle_for_MpcController, "PMKF_Ahat_row1_for_positions",  PMKF_Ahat_row1_for_positions,  2);
-	getParameterFloatVector(nodeHandle_for_MpcController, "PMKF_Ahat_row2_for_positions",  PMKF_Ahat_row2_for_positions,  2);
-	getParameterFloatVector(nodeHandle_for_MpcController, "PMKF_Kinf_for_positions"     ,  PMKF_Kinf_for_positions     ,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_MpcController, "PMKF_Ahat_row1_for_positions",  PMKF_Ahat_row1_for_positions,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_MpcController, "PMKF_Ahat_row2_for_positions",  PMKF_Ahat_row2_for_positions,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_MpcController, "PMKF_Kinf_for_positions"     ,  PMKF_Kinf_for_positions     ,  2);
 	// > For the (roll,pitch,yaw) angles
-	getParameterFloatVector(nodeHandle_for_MpcController, "PMKF_Ahat_row1_for_angles",  PMKF_Ahat_row1_for_angles,  2);
-	getParameterFloatVector(nodeHandle_for_MpcController, "PMKF_Ahat_row2_for_angles",  PMKF_Ahat_row2_for_angles,  2);
-	getParameterFloatVector(nodeHandle_for_MpcController, "PMKF_Kinf_for_angles"     ,  PMKF_Kinf_for_angles     ,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_MpcController, "PMKF_Ahat_row1_for_angles",  PMKF_Ahat_row1_for_angles,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_MpcController, "PMKF_Ahat_row2_for_angles",  PMKF_Ahat_row2_for_angles,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_MpcController, "PMKF_Kinf_for_angles"     ,  PMKF_Kinf_for_angles     ,  2);
 
 
 	// Call the function that computes details an values that are needed from these
@@ -780,7 +766,7 @@ float getParameterFloat(ros::NodeHandle& nodeHandle, std::string name)
     return val;
 }
 // This function DOES NOT NEED TO BE edited for successful completion of the classroom exercise
-void getParameterFloatVector(ros::NodeHandle& nodeHandle, std::string name, std::vector<float>& val, int length)
+void getParameterFloatVectorKnownLength(ros::NodeHandle& nodeHandle, std::string name, std::vector<float>& val, int length)
 {
     if(!nodeHandle.getParam(name, val)){
         ROS_ERROR_STREAM("missing parameter '" << name << "'");
diff --git a/dfall_ws/src/dfall_pkg/src/nodes/ParameterService.cpp b/dfall_ws/src/dfall_pkg/src/nodes/ParameterService.cpp
index 269f0a55fdacbe0a1c9219a8ec2eeedbe6074e90..4180b69d1ed5d062baa0da48388b3cba2bdeacef 100644
--- a/dfall_ws/src/dfall_pkg/src/nodes/ParameterService.cpp
+++ b/dfall_ws/src/dfall_pkg/src/nodes/ParameterService.cpp
@@ -76,84 +76,100 @@
 
 bool requestLoadYamlFilenameCallbackServiceCallback(LoadYamlFromFilename::Request &request, LoadYamlFromFilename::Response &response)
 {
-    // Put the flying state into the response variable
-    requestLoadYamlFilenamePublisher.publish(request.stringWithHeader);
+	// Put the flying state into the response variable
+	m_requestLoadYamlFilenamePublisher.publish(request.stringWithHeader);
 
-    // Put success into the response
-    response.data = 1;
+	// Put success into the response
+	response.data = 1;
 
-    // Return
-    return true;
+	// Return
+	return true;
 }
 
 void requestLoadYamlFilenameCallback(const StringWithHeader& yaml_filename_to_load_with_header)
 {
-    // LOAD THE YAML FILE
-
-    // Get the yaml file name requested
-    std::string yaml_filename_to_load = yaml_filename_to_load_with_header.data;
-    // Get the node handle to this parameter service
-    ros::NodeHandle nodeHandle("~");
-    // Instantiate a local variable for the command string that will be passed to the "system":
-    std::string cmd;
-    // Get the abolute path to "dfall_pkg":
-    std::string dfall_pkg_path = ros::package::getPath("dfall_pkg");
-    // Construct the system command string for (re-)loading the parameters:
-    cmd = "rosparam load " + dfall_pkg_path + "/param" + "/" + yaml_filename_to_load + ".yaml " + m_base_namespace + "/" + yaml_filename_to_load;
-    // Let the user know what is about to happen
-    ROS_INFO_STREAM("[PARAMETER SERVICE] The following path will be used for locating the .yaml file: " << dfall_pkg_path  << " The comand line string sent to the 'system' is: " << cmd );
-    // Send the "load yaml" command to the system
-    system(cmd.c_str());
-
-
-
-    // PUBLISH A MESSAGE THAT THE YAML FILE WAS LOADED
-
-    // Create publisher as a local variable, using the filename
-    // as the name of the message
-    ros::Publisher yamlParametersReadyForFetchPublisher = nodeHandle.advertise<IntWithHeader>(yaml_filename_to_load, 1, true);
-    //ros::spinOnce();
-    // Create a local variable for the message
-    IntWithHeader yaml_ready_msg;
-    // Specify with the data the "type" of this parameter service
-    switch (m_type)
-    {
-        case TYPE_AGENT:
-        {
-            yaml_ready_msg.data = LOAD_YAML_FROM_AGENT;
-            break;
-        }
-        case TYPE_COORDINATOR:
-        {
-            yaml_ready_msg.data = LOAD_YAML_FROM_COORDINATOR;
-            break;
-        }
-        default:
-        {
-            // Throw an error if the type is not recognised
-            ROS_ERROR("[PARAMETER SERVICE] The 'm_type' variable was not recognised.");
-            // Specify to load from the agent by default
-            yaml_ready_msg.data = LOAD_YAML_FROM_AGENT;
-            break;
-        }
-    }
-    // Copy across the boolean field
-    yaml_ready_msg.shouldCheckForAgentID = yaml_filename_to_load_with_header.shouldCheckForAgentID;
-    // Copy across the vector of IDs
-    if (yaml_filename_to_load_with_header.shouldCheckForAgentID)
-    {
-        for ( int i_ID=0 ; i_ID<yaml_filename_to_load_with_header.agentIDs.size() ; i_ID++ )
-        {
-            yaml_ready_msg.agentIDs.push_back(yaml_filename_to_load_with_header.agentIDs[i_ID]);
-        }
-    }
-    // Sleep to make the publisher known to ROS (in seconds)
-    ros::Duration(2.0).sleep();
-    // Send the message
-    yamlParametersReadyForFetchPublisher.publish(yaml_ready_msg);
-
-    // Inform the user that this was published
-    ROS_INFO_STREAM("[PARAMETER SERVICE] Published message that " << yaml_filename_to_load << " yaml parameters are ready." );
+	// LOAD THE YAML FILE
+
+	// Get the yaml file name requested
+	std::string yaml_filename_to_load = yaml_filename_to_load_with_header.data;
+	// Instantiate a local variable for the command string that will be passed to the "system":
+	std::string cmd;
+	// Get the abolute path to "dfall_pkg":
+	std::string dfall_pkg_path = ros::package::getPath("dfall_pkg");
+	// Construct the system command string for (re-)loading the parameters:
+	cmd = "rosparam load " + dfall_pkg_path + "/param" + "/" + yaml_filename_to_load + ".yaml " + m_base_namespace + "/" + yaml_filename_to_load;
+	// Let the user know what is about to happen
+	ROS_INFO_STREAM("[PARAMETER SERVICE] The following path will be used for locating the .yaml file: " << dfall_pkg_path  << " The comand line string sent to the 'system' is: " << cmd );
+	// Send the "load yaml" command to the system
+	system(cmd.c_str());
+
+
+
+	// PREPARE A MESSAGE THAT THE YAML FILE WAS LOADED
+
+	// Create a local variable for the message
+	IntWithHeader yaml_ready_msg;
+	// Specify with the data the "type" of this parameter service
+	switch (m_type)
+	{
+		case TYPE_AGENT:
+		{
+			yaml_ready_msg.data = LOAD_YAML_FROM_AGENT;
+			break;
+		}
+		case TYPE_COORDINATOR:
+		{
+			yaml_ready_msg.data = LOAD_YAML_FROM_COORDINATOR;
+			break;
+		}
+		default:
+		{
+			// Throw an error if the type is not recognised
+			ROS_ERROR("[PARAMETER SERVICE] The 'm_type' variable was not recognised.");
+			// Specify to load from the agent by default
+			yaml_ready_msg.data = LOAD_YAML_FROM_AGENT;
+			break;
+		}
+	}
+	// Copy across the boolean field
+	yaml_ready_msg.shouldCheckForAgentID = yaml_filename_to_load_with_header.shouldCheckForAgentID;
+	// Copy across the vector of IDs
+	if (yaml_filename_to_load_with_header.shouldCheckForAgentID)
+	{
+		for ( int i_ID=0 ; i_ID<yaml_filename_to_load_with_header.agentIDs.size() ; i_ID++ )
+		{
+			yaml_ready_msg.agentIDs.push_back(yaml_filename_to_load_with_header.agentIDs[i_ID]);
+		}
+	}
+
+	// PUBLISH A MESSAGE THAT THE YAML FILE WAS LOADED
+
+	// Check if the publisher is already in the "map"
+	if (m_yamlParametersReadyForFetchPublisherMap.count(yaml_filename_to_load) > 0)
+	{
+		// Send the message
+		m_yamlParametersReadyForFetchPublisherMap[yaml_filename_to_load].publish(yaml_ready_msg);
+		// Inform the user that this was published
+		ROS_INFO_STREAM("[PARAMETER SERVICE] Published message that " << yaml_filename_to_load << " yaml parameters are ready." );
+	}
+	else
+	{
+		// Create a publisher
+		// > using the filename as the name of the message
+		// > adding it to the map of publihsers to make the
+		//   next load faster
+		// Get the node handle to this parameter service
+		ros::NodeHandle nodeHandle("~");
+		m_yamlParametersReadyForFetchPublisherMap[yaml_filename_to_load] = nodeHandle.advertise<IntWithHeader>(yaml_filename_to_load, 1);
+		// Inform the user that this publisher was added
+		ROS_INFO_STREAM("[PARAMETER SERVICE] Added " << yaml_filename_to_load << " to the publisher map." );
+		// Sleep to make the publisher known to ROS (in seconds)
+		ros::Duration(2.0).sleep();
+		// Send the message
+		m_yamlParametersReadyForFetchPublisherMap[yaml_filename_to_load].publish(yaml_ready_msg);
+		// Inform the user that this was published
+		ROS_INFO_STREAM("[PARAMETER SERVICE] Published message that " << yaml_filename_to_load << " yaml parameters are ready." );
+	}
 }
 
 
@@ -162,89 +178,89 @@ void requestLoadYamlFilenameCallback(const StringWithHeader& yaml_filename_to_lo
 
 bool getTypeAndIDParameters()
 {
-    // Initialise the return variable as success
-    bool return_was_successful = true;
-
-    // Create a "ros::NodeHandle" type local variable "nodeHandle" as the current node,
-    // the "~" indcates that "self" is the node handle assigned to this variable.
-    ros::NodeHandle nodeHandle("~");
-
-    // Get the value of the "type" parameter into a local string variable
-    std::string type_string;
-    if(!nodeHandle.getParam("type", type_string))
-    {
-        // Throw an error if the agent ID parameter could not be obtained
-        ROS_ERROR("[PARAMETER SERVICE] Failed to get type");
-    }
-
-    // Set the "m_type" class variable based on this string loaded
-    if ((!type_string.compare("coordinator")))
-    {
-        m_type = TYPE_COORDINATOR;
-    }
-    else if ((!type_string.compare("agent")))
-    {
-        m_type = TYPE_AGENT;
-    }
-    else
-    {
-        // Set "m_type" to the value indicating that it is invlid
-        m_type = TYPE_INVALID;
-        return_was_successful = false;
-        ROS_ERROR("[PARAMETER SERVICE] The 'type' parameter retrieved was not recognised.");
-    }
-
-
-    // Construct the string to the namespace of this Paramater Service
-    switch (m_type)
-    {
-        case TYPE_AGENT:
-        {
-            // Get the value of the "agentID" parameter into the class variable "m_Id"
-            if(!nodeHandle.getParam("agentID", m_ID))
-            {
-                // Throw an error if the agent ID parameter could not be obtained
-                return_was_successful = false;
-                ROS_ERROR("[PARAMETER SERVICE] Failed to get agentID");
-            }
-            else
-            {
-                // Inform the user about the type and ID
-                ROS_INFO_STREAM("[PARAMETER SERVICE] Is of type AGENT with ID = " << m_ID);
-            }
-            break;
-        }
-
-        // A COORDINATOR TYPE PARAMETER SERVICE IS REQUESTED FROM:
-        // > The master GUI
-        case TYPE_COORDINATOR:
-        {
-            // Get the value of the "coordID" parameter into the class variable "m_Id"
-            if(!nodeHandle.getParam("coordID", m_ID))
-            {
-                // Throw an error if the coord ID parameter could not be obtained
-                return_was_successful = false;
-                ROS_ERROR("[PARAMETER SERVICE] Failed to get coordID");
-            }
-            else
-            {
-                // Inform the user about the type and ID
-                ROS_INFO_STREAM("[PARAMETER SERVICE] Is of type COORDINATOR with ID = " << m_ID);
-            }
-            break;
-        }
-
-        default:
-        {
-            // Throw an error if the type is not recognised
-            return_was_successful = false;
-            ROS_ERROR("[PARAMETER SERVICE] The 'm_type' variable was not recognised.");
-            break;
-        }
-    }
-
-    // Return
-    return return_was_successful;
+	// Initialise the return variable as success
+	bool return_was_successful = true;
+
+	// Create a "ros::NodeHandle" type local variable "nodeHandle" as the current node,
+	// the "~" indcates that "self" is the node handle assigned to this variable.
+	ros::NodeHandle nodeHandle("~");
+
+	// Get the value of the "type" parameter into a local string variable
+	std::string type_string;
+	if(!nodeHandle.getParam("type", type_string))
+	{
+		// Throw an error if the agent ID parameter could not be obtained
+		ROS_ERROR("[PARAMETER SERVICE] Failed to get type");
+	}
+
+	// Set the "m_type" class variable based on this string loaded
+	if ((!type_string.compare("coordinator")))
+	{
+		m_type = TYPE_COORDINATOR;
+	}
+	else if ((!type_string.compare("agent")))
+	{
+		m_type = TYPE_AGENT;
+	}
+	else
+	{
+		// Set "m_type" to the value indicating that it is invlid
+		m_type = TYPE_INVALID;
+		return_was_successful = false;
+		ROS_ERROR("[PARAMETER SERVICE] The 'type' parameter retrieved was not recognised.");
+	}
+
+
+	// Construct the string to the namespace of this Paramater Service
+	switch (m_type)
+	{
+		case TYPE_AGENT:
+		{
+			// Get the value of the "agentID" parameter into the class variable "m_Id"
+			if(!nodeHandle.getParam("agentID", m_ID))
+			{
+				// Throw an error if the agent ID parameter could not be obtained
+				return_was_successful = false;
+				ROS_ERROR("[PARAMETER SERVICE] Failed to get agentID");
+			}
+			else
+			{
+				// Inform the user about the type and ID
+				ROS_INFO_STREAM("[PARAMETER SERVICE] Is of type AGENT with ID = " << m_ID);
+			}
+			break;
+		}
+
+		// A COORDINATOR TYPE PARAMETER SERVICE IS REQUESTED FROM:
+		// > The master GUI
+		case TYPE_COORDINATOR:
+		{
+			// Get the value of the "coordID" parameter into the class variable "m_Id"
+			if(!nodeHandle.getParam("coordID", m_ID))
+			{
+				// Throw an error if the coord ID parameter could not be obtained
+				return_was_successful = false;
+				ROS_ERROR("[PARAMETER SERVICE] Failed to get coordID");
+			}
+			else
+			{
+				// Inform the user about the type and ID
+				ROS_INFO_STREAM("[PARAMETER SERVICE] Is of type COORDINATOR with ID = " << m_ID);
+			}
+			break;
+		}
+
+		default:
+		{
+			// Throw an error if the type is not recognised
+			return_was_successful = false;
+			ROS_ERROR("[PARAMETER SERVICE] The 'm_type' variable was not recognised.");
+			break;
+		}
+	}
+
+	// Return
+	return return_was_successful;
 }
 
 
@@ -253,47 +269,47 @@ bool getTypeAndIDParameters()
 
 bool constructNamespaces()
 {
-    // Initialise the return variable as success
-    bool return_was_successful = true;
-
-    // Get the namespace of this "ParameterService" node
-    std::string this_node_namespace = ros::this_node::getNamespace();
-    ROS_INFO_STREAM("[PARAMETER SERVICE] ros::this_node::getNamespace() =  " << this_node_namespace);
-
-    // Construct the string to the namespace of this Paramater Service
-    switch (m_type)
-    {
-        case TYPE_AGENT:
-        {
-            //m_base_namespace = ros::this_node::getNamespace();
-            //m_base_namespace = "/agent" + m_Id + '/' + "ParameterService";
-            m_base_namespace = this_node_namespace + '/' + "ParameterService";
-            ROS_INFO_STREAM("[PARAMETER SERVICE] .yaml file parameters will be loaded into the 'base' namespace: " << m_base_namespace);
-            break;
-        }
-
-        // A COORDINATOR TYPE PARAMETER SERVICE IS REQUESTED FROM:
-        // > The master GUI
-        case TYPE_COORDINATOR:
-        {
-            //m_base_namespace = ros::this_node::getNamespace();
-            //m_base_namespace = "/ParameterService";
-            m_base_namespace = this_node_namespace + '/' + "ParameterService";
-            ROS_INFO_STREAM("[PARAMETER SERVICE] .yaml file parameters will be loaded into the 'base' namespace: " << m_base_namespace);
-            break;
-        }
-
-        default:
-        {
-            // Throw an error if the type is not recognised
-            return_was_successful = false;
-            ROS_ERROR("[PARAMETER SERVICE] The 'm_type' type parameter was not recognised.");
-            break;
-        }
-    }
-
-    // Return
-    return return_was_successful;
+	// Initialise the return variable as success
+	bool return_was_successful = true;
+
+	// Get the namespace of this "ParameterService" node
+	std::string this_node_namespace = ros::this_node::getNamespace();
+	ROS_INFO_STREAM("[PARAMETER SERVICE] ros::this_node::getNamespace() =  " << this_node_namespace);
+
+	// Construct the string to the namespace of this Paramater Service
+	switch (m_type)
+	{
+		case TYPE_AGENT:
+		{
+			//m_base_namespace = ros::this_node::getNamespace();
+			//m_base_namespace = "/agent" + m_Id + '/' + "ParameterService";
+			m_base_namespace = this_node_namespace + '/' + "ParameterService";
+			ROS_INFO_STREAM("[PARAMETER SERVICE] .yaml file parameters will be loaded into the 'base' namespace: " << m_base_namespace);
+			break;
+		}
+
+		// A COORDINATOR TYPE PARAMETER SERVICE IS REQUESTED FROM:
+		// > The master GUI
+		case TYPE_COORDINATOR:
+		{
+			//m_base_namespace = ros::this_node::getNamespace();
+			//m_base_namespace = "/ParameterService";
+			m_base_namespace = this_node_namespace + '/' + "ParameterService";
+			ROS_INFO_STREAM("[PARAMETER SERVICE] .yaml file parameters will be loaded into the 'base' namespace: " << m_base_namespace);
+			break;
+		}
+
+		default:
+		{
+			// Throw an error if the type is not recognised
+			return_was_successful = false;
+			ROS_ERROR("[PARAMETER SERVICE] The 'm_type' type parameter was not recognised.");
+			break;
+		}
+	}
+
+	// Return
+	return return_was_successful;
 }
 
 
@@ -310,40 +326,69 @@ bool constructNamespaces()
 
 int main(int argc, char* argv[])
 {
-    // Starting the ROS-node
-    ros::init(argc, argv, "ParameterService");
-
-    // Create a "ros::NodeHandle" type local variable "nodeHandle" as the current node,
-    // the "~" indcates that "self" is the node handle assigned to this variable.
-    ros::NodeHandle nodeHandle("~");
-
-    // Get the type and ID of this parameter service
-    bool isValid_type_and_ID = getTypeAndIDParameters();
-
-    // Construct the namespace into which this parameter service
-    // loads yaml parameters
-    bool isValid_namespaces = constructNamespaces();
-
-    // Stall if the TYPE and ID are not valid
-    if ( !( isValid_type_and_ID && isValid_namespaces ) )
-    {
-        ROS_ERROR("[PARAMETER SERVICE] Service NOT FUNCTIONING :-)");
-        ros::spin();
-    }
-
-    // Subscribe to the messages that request loading a yaml file
-    ros::Subscriber requestLoadYamlFilenameSubscriber = nodeHandle.subscribe("requestLoadYamlFilename", 20, requestLoadYamlFilenameCallback);
-
-    // Publisher for publishing "internally" to the subscriber above
-    requestLoadYamlFilenamePublisher = nodeHandle.advertise <StringWithHeader>("requestLoadYamlFilename", 1);
-
-    // Advertise the service for requests to load a yaml file
-    ros::ServiceServer requestLoadYamlFilenameService = nodeHandle.advertiseService("requestLoadYamlFilename", requestLoadYamlFilenameCallbackServiceCallback);
-
-    // Inform the user the this node is ready
-    ROS_INFO("[PARAMETER SERVICE] Service ready :-)");
-    // Spin as a single-thread node
-    ros::spin();
-
-    return 0;
+	// Starting the ROS-node
+	ros::init(argc, argv, "ParameterService");
+
+	// Create a "ros::NodeHandle" type local variable "nodeHandle" as the current node,
+	// the "~" indcates that "self" is the node handle assigned to this variable.
+	ros::NodeHandle nodeHandle("~");
+
+	// Get the type and ID of this parameter service
+	bool isValid_type_and_ID = getTypeAndIDParameters();
+
+	// Construct the namespace into which this parameter service
+	// loads yaml parameters
+	bool isValid_namespaces = constructNamespaces();
+
+	// Stall if the TYPE and ID are not valid
+	if ( !( isValid_type_and_ID && isValid_namespaces ) )
+	{
+		ROS_ERROR("[PARAMETER SERVICE] Service NOT FUNCTIONING :-)");
+		ros::spin();
+	}
+
+	// Fetch the YAML parameter that itself is the array of
+	// YAML file name strings
+	ros::NodeHandle nodeHandle_to_yamlFileNames(nodeHandle, "YamlFileNames");
+	if(!nodeHandle_to_yamlFileNames.getParam("filenames", yaml_filenames_provided))
+	{
+		// Throw an error if the agent ID parameter could not be obtained
+		ROS_ERROR("[PARAMETER SERVICE] Failed to get filenames");
+	}
+	else
+	{
+		// Inform the user
+		ROS_INFO_STREAM("[PARAMETER SERVICE] loaded " << yaml_filenames_provided.size() << " filenames for which publishers will be prepared.");
+	}
+	
+
+	// For each for the filenames provided:
+	// > Create a publisher, using the filename as the name
+	//   of the message
+	// > Add the publisher to a "map", i.e., to a dictionary
+	// > Inform the user that this publisher was added
+	for (std::string filename_str : yaml_filenames_provided)
+	{
+		m_yamlParametersReadyForFetchPublisherMap[filename_str] = nodeHandle.advertise<IntWithHeader>(filename_str, 1);
+		ROS_INFO_STREAM("[PARAMETER SERVICE] Added " << filename_str << " to the publisher map." );
+	}
+
+
+	// Subscribe to the messages that request loading a yaml file
+	ros::Subscriber requestLoadYamlFilenameSubscriber = nodeHandle.subscribe("requestLoadYamlFilename", 20, requestLoadYamlFilenameCallback);
+
+	// Publisher for publishing "internally" to the subscriber above
+	m_requestLoadYamlFilenamePublisher = nodeHandle.advertise <StringWithHeader>("requestLoadYamlFilename", 1);
+
+	// Advertise the service for requests to load a yaml file
+	ros::ServiceServer requestLoadYamlFilenameService = nodeHandle.advertiseService("requestLoadYamlFilename", requestLoadYamlFilenameCallbackServiceCallback);
+
+	// Inform the user the this node is ready
+	ROS_INFO("[PARAMETER SERVICE] Service ready :-)");
+
+	// Enter an endless while loop to keep the node alive.
+	ros::spin();
+
+	// Return zero if the "ross::spin" is cancelled.
+	return 0;
 }
diff --git a/dfall_ws/src/dfall_pkg/src/nodes/PickerControllerService.cpp b/dfall_ws/src/dfall_pkg/src/nodes/PickerControllerService.cpp
index b30281bf67f157480077faf37d962938db4e5939..aa340b95b7329b0d8ae2e83810f57dc16e37d19e 100644
--- a/dfall_ws/src/dfall_pkg/src/nodes/PickerControllerService.cpp
+++ b/dfall_ws/src/dfall_pkg/src/nodes/PickerControllerService.cpp
@@ -291,56 +291,78 @@ void smoothSetpointChanges()
 //
 // The arument "request" is a structure provided to this service with the following two
 // properties:
-// request.ownCrazyflie
-// This property is itself a structure of type "CrazyflieData",  which is defined in the
-// file "CrazyflieData.msg", and has the following properties
-// string crazyflieName
+//
+// >> request.ownCrazyflie
+// This property is itself a structure of type "FlyingVehicleState",  which is defined in the
+// file "FlyingVehicleState.msg", and has the following properties
+//     string vehicleName
 //     float64 x                         The x position of the Crazyflie [metres]
 //     float64 y                         The y position of the Crazyflie [metres]
 //     float64 z                         The z position of the Crazyflie [metres]
 //     float64 roll                      The roll component of the intrinsic Euler angles [radians]
 //     float64 pitch                     The pitch component of the intrinsic Euler angles [radians]
 //     float64 yaw                       The yaw component of the intrinsic Euler angles [radians]
-//     float64 acquiringTime #delta t    The time elapsed since the previous "CrazyflieData" was received [seconds]
-//     bool occluded                     A boolean indicted whether the Crazyflie for visible at the time of this measurement
+//     float64 acquiringTime #delta t    The time elapsed since the previous "FlyingVehicleState" was received [seconds]
+//     bool isValid                      A boolean indicted whether the Crazyflie for visible at the time of this measurement
 // The values in these properties are directly the measurement taken by the Vicon
 // motion capture system of the Crazyflie that is to be controlled by this service
 //
-// request.otherCrazyflies
-// This property is an array of "CrazyflieData" structures, what allows access to the
+// >> request.otherCrazyflies
+// This property is an array of "FlyingVehicleState" structures, what allows access to the
 // Vicon measurements of other Crazyflies.
 //
-// The argument "response" is a structure that is expected to be filled in by this
-// service by this function, it has only the following property
-// response.ControlCommand
-// This property is iteself a structure of type "ControlCommand", which is defined in
-// the file "ControlCommand.msg", and has the following properties:
-//     float32 roll                      The command sent to the Crazyflie for the body frame x-axis
-//     float32 pitch                     The command sent to the Crazyflie for the body frame y-axis
-//     float32 yaw                       The command sent to the Crazyflie for the body frame z-axis
-//     uint16 motorCmd1                  The command sent to the Crazyflie for motor 1
-//     uint16 motorCmd2                  The command sent to the Crazyflie for motor 1
-//     uint16 motorCmd3                  The command sent to the Crazyflie for motor 1
-//     uint16 motorCmd4                  The command sent to the Crazyflie for motor 1
-//     uint8 onboardControllerType       The flag sent to the Crazyflie for indicating how to implement the command
+// The argument "response" is a structure that is expected to be filled in by
+// this service by this function, it has only the following property
+//
+// >> response.ControlCommand
+// This property is iteself a structure of type "ControlCommand", which is
+// defined in the file "ControlCommand.msg", and has the following properties:
+//     uint16 motorCmd1                 The command sent to the Crazyflie for motor 1
+//     uint16 motorCmd2                 ... same for motor 2
+//     uint16 motorCmd3                 ... same for motor 3
+//     uint16 motorCmd4                 ... same for motor 4
+//     uint8 xControllerMode            The mode sent to the Crazyflie for what controller to run for the body frame x-axis
+//     uint8 yControllerMode            ... same body frame y-axis
+//     uint8 zControllerMode            ... same body frame z-axis
+//     uint8 yawControllerMode          ... same body frame yaw
+//     float32 xControllerSetpoint      The setpoint sent to the Crazyflie for the body frame x-axis controller
+//     float32 yControllerSetpoint      ... same body frame y-axis
+//     float32 zControllerSetpoint      ... same body frame z-axis
+//     float32 yawControllerSetpoint    ... same body frame yaw
 // 
-// IMPORTANT NOTES FOR "onboardControllerType"  AND AXIS CONVENTIONS
-// > The allowed values for "onboardControllerType" are in the "Defines" section at the
-//   top of this file, they are:
-//   CF_COMMAND_TYPE_MOTOR
-//   CF_COMMAND_TYPE_RATE
-//   CF_COMMAND_TYPE_ANGLE.
-// > With CF_COMMAND_TYPE_RATE the ".roll", ".ptich", and ".yaw" properties of "response.ControlCommand"
-//   specify the angular rate in [radians/second] that will be requested from the
-//   PID controllers running in the Crazyflie 2.0 firmware.
-// > With CF_COMMAND_TYPE_RATE the ".motorCmd1" to ".motorCmd4" properties of "response.ControlCommand"
-//   are the baseline motor commands requested from the Crazyflie, with the adjustment
-//   for body rates being added on top of this in the firmware (i.e., as per the code
-//   of the "distribute_power" function provided in exercise sheet 2).
-// > With CF_COMMAND_TYPE_RATE the axis convention for the roll, pitch, and yaw body rates returned
-//   in "response.ControlCommand" should use right-hand coordinate axes with x-forward
-//   and z-upwards (i.e., the positive z-axis is aligned with the direction of positive
-//   thrust). To assist, teh following is an ASCII art of this convention:
+// IMPORTANT NOTES FOR "{x,y,z,yaw}ControllerMode"  AND AXIS CONVENTIONS
+// > The allowed values for "{x,y,z,yaw}ControllerMode" are in the
+//   "Constants.h" header file, they are:
+//   - CF_ONBOARD_CONTROLLER_MODE_OFF
+//   - CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE
+//   - CF_ONBOARD_CONTROLLER_MODE_ANGLE
+//   - CF_ONBOARD_CONTROLLER_MODE_VELOCITY
+//   - CF_ONBOARD_CONTROLLER_MODE_POSITION
+//
+// > The most common option to use for the {x,y,yaw} controller is
+//   the CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE option.
+//
+// > The most common option to use for the {z} controller is
+//   the CF_ONBOARD_CONTROLLER_MODE_OFF option, and thus the
+//   body frame z-axis is controlled by the motorCmd{1,2,3,4}
+//   values that you set.
+//
+// > When the CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE is selected, then:
+//   1) the ".xControllerSetpoint", ".yControllerSetpoint", and
+//      ".yawControllerSetpoint" properties of "response.ControlCommand"
+//      specify the angular rate in [radians/second] that will be requested
+//      from the PID controllers running in the Crazyflie 2.0 firmware.
+//   2) the axis convention for the roll, pitch, and yaw body rates,
+//      i.e., as set in the {y,x,yaw}ControllerSetpoint properties of
+//      the "response.ControlCommand" that you return, is a right-hand
+//      coordinate axes with x-forward and z-upwards (i.e., the positive
+//      z-axis is aligned with the direction of positive thrust). To
+//      assist, the ASCII art below depicts this convention.
+//   3) the ".motorCmd1" to ".motorCmd4" properties of
+//      "response.ControlCommand" are the baseline motor commands
+//      requested from the Crazyflie, with the adjustment for body rates
+//      being added on top of this in the firmware (i.e., as per the
+//      code of the "distribute_power" found in the firmware).
 //
 // ASCII ART OF THE CRAZYFLIE 2.0 LAYOUT
 //
@@ -650,15 +672,23 @@ void calculateControlOutput_viaLQRforRates(float stateErrorBody[12], Controller:
 
 	// UPDATE THE "RETURN" THE VARIABLE NAMED "response"
 
-	// Put the computed rates and thrust into the "response" variable
+	// Specify the mode of each controller
+	response.controlOutput.xControllerMode   = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+	response.controlOutput.yControllerMode   = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+	response.controlOutput.zControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+	response.controlOutput.yawControllerMode = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+
+	// Put the computed rates into the "response" variable
 	// > For roll, pitch, and yaw:
-	response.controlOutput.roll  = rollRate_forResponse;
-	response.controlOutput.pitch = pitchRate_forResponse;
-	response.controlOutput.yaw   = yawRate_forResponse;
-	// > For the thrust adjustment we must add the feed-forward thrust to counter-act gravity.
-	// > NOTE: remember that the thrust is commanded per motor, so you sohuld
-	//         consider whether the "thrustAdjustment" computed by your
-	//         controller needed to be divided by 4 or not.
+	response.controlOutput.xControllerSetpoint   = pitchRate_forResponse;
+	response.controlOutput.yControllerSetpoint   = rollRate_forResponse;
+	response.controlOutput.zControllerSetpoint   = 0.0;
+	response.controlOutput.yawControllerSetpoint = yawRate_forResponse;
+
+	// Put the computed thrust into the "response" variable
+	// > On top of the thrust adjustment, we must add the feed-forward thrust to counter-act gravity.
+	// > NOTE: remember that the thrust is commanded per motor, hence divide
+	//         the thrusts by 4.
 	thrustAdjustment = thrustAdjustment / 4.0;
 	// > Compute the feed-forward force
 	float feed_forward_thrust_per_motor = m_weight_total_in_newtons / 4.0;
@@ -668,11 +698,6 @@ void calculateControlOutput_viaLQRforRates(float stateErrorBody[12], Controller:
 	response.controlOutput.motorCmd3 = computeMotorPolyBackward(thrustAdjustment + feed_forward_thrust_per_motor);
 	response.controlOutput.motorCmd4 = computeMotorPolyBackward(thrustAdjustment + feed_forward_thrust_per_motor);
 
-	
-	// Specify that this controller is a rate controller
-	// response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_MOTOR;
-	response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_RATE;
-	// response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_ANGLE;
 
 
 	// An alternate debugging technique is to print out data directly to the
@@ -691,9 +716,9 @@ void calculateControlOutput_viaLQRforRates(float stateErrorBody[12], Controller:
 
 		// An example of "printing out" the control actions computed.
 		ROS_INFO_STREAM("thrustAdjustment = " << thrustAdjustment);
-		ROS_INFO_STREAM("controlOutput.roll = " << response.controlOutput.roll);
-		ROS_INFO_STREAM("controlOutput.pitch = " << response.controlOutput.pitch);
-		ROS_INFO_STREAM("controlOutput.yaw = " << response.controlOutput.yaw);
+		ROS_INFO_STREAM("controlOutput.xControllerSetpoint   = " << response.controlOutput.xControllerSetpoint);
+		ROS_INFO_STREAM("controlOutput.yControllerSetpoint   = " << response.controlOutput.yControllerSetpoint);
+		ROS_INFO_STREAM("controlOutput.yawControllerSetpoint = " << response.controlOutput.yawControllerSetpoint);
 
 		// An example of "printing out" the "thrust-to-command" conversion parameters.
 		ROS_INFO_STREAM("motorPoly 0:" << yaml_motorPoly[0]);
@@ -1228,7 +1253,7 @@ void fetchPickerControllerYamlParameters(ros::NodeHandle& nodeHandle)
 
 	// > The co-efficients of the quadratic conversation from 16-bit motor command to
 	//   thrust force in Newtons
-	getParameterFloatVector(nodeHandle_for_paramaters, "motorPoly", yaml_motorPoly, 3);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "motorPoly", yaml_motorPoly, 3);
 
 	// > The boolean for whether to execute the convert into body frame function
 	yaml_shouldPerformConvertIntoBodyFrame = getParameterBool(nodeHandle_for_paramaters, "shouldPerformConvertIntoBodyFrame");
@@ -1247,10 +1272,10 @@ void fetchPickerControllerYamlParameters(ros::NodeHandle& nodeHandle)
 	yaml_estimator_method = getParameterInt( nodeHandle_for_paramaters , "estimator_method" );
 
 	// The LQR Controller parameters for "LQR_MODE_RATE"
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixThrust_NineStateVector", yaml_gainMatrixThrust_NineStateVector, 9);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixRollRate",               yaml_gainMatrixRollRate,               9);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixPitchRate",              yaml_gainMatrixPitchRate,              9);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixYawRate",                yaml_gainMatrixYawRate,                9);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixThrust_NineStateVector", yaml_gainMatrixThrust_NineStateVector, 9);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixRollRate",               yaml_gainMatrixRollRate,               9);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixPitchRate",              yaml_gainMatrixPitchRate,              9);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixYawRate",                yaml_gainMatrixYawRate,                9);
 		
 	// 16-BIT COMMAND LIMITS
 	yaml_cmd_sixteenbit_min = getParameterFloat(nodeHandle_for_paramaters, "command_sixteenbit_min");
@@ -1258,13 +1283,13 @@ void fetchPickerControllerYamlParameters(ros::NodeHandle& nodeHandle)
 
 	// THE POINT MASS KALMAN FILTER (PMKF) GAINS AND ERROR EVOLUATION
 	// > For the (x,y,z) position
-	getParameterFloatVector(nodeHandle_for_paramaters, "PMKF_Ahat_row1_for_positions",  yaml_PMKF_Ahat_row1_for_positions,  2);
-	getParameterFloatVector(nodeHandle_for_paramaters, "PMKF_Ahat_row2_for_positions",  yaml_PMKF_Ahat_row2_for_positions,  2);
-	getParameterFloatVector(nodeHandle_for_paramaters, "PMKF_Kinf_for_positions"     ,  yaml_PMKF_Kinf_for_positions     ,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "PMKF_Ahat_row1_for_positions",  yaml_PMKF_Ahat_row1_for_positions,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "PMKF_Ahat_row2_for_positions",  yaml_PMKF_Ahat_row2_for_positions,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "PMKF_Kinf_for_positions"     ,  yaml_PMKF_Kinf_for_positions     ,  2);
 	// > For the (roll,pitch,yaw) angles
-	getParameterFloatVector(nodeHandle_for_paramaters, "PMKF_Ahat_row1_for_angles",  yaml_PMKF_Ahat_row1_for_angles,  2);
-	getParameterFloatVector(nodeHandle_for_paramaters, "PMKF_Ahat_row2_for_angles",  yaml_PMKF_Ahat_row2_for_angles,  2);
-	getParameterFloatVector(nodeHandle_for_paramaters, "PMKF_Kinf_for_angles"     ,  yaml_PMKF_Kinf_for_angles     ,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "PMKF_Ahat_row1_for_angles",  yaml_PMKF_Ahat_row1_for_angles,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "PMKF_Ahat_row2_for_angles",  yaml_PMKF_Ahat_row2_for_angles,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "PMKF_Kinf_for_angles"     ,  yaml_PMKF_Kinf_for_angles     ,  2);
 
 
 	// DEBUGGING: Print out one of the parameters that was loaded
diff --git a/dfall_ws/src/dfall_pkg/src/nodes/RemoteControllerService.cpp b/dfall_ws/src/dfall_pkg/src/nodes/RemoteControllerService.cpp
index e1e01f283eeb80461d021d89b2f19b111cb771af..6ca55d901e94bd7d8dc6e9458fcb832f632f0d02 100644
--- a/dfall_ws/src/dfall_pkg/src/nodes/RemoteControllerService.cpp
+++ b/dfall_ws/src/dfall_pkg/src/nodes/RemoteControllerService.cpp
@@ -79,54 +79,78 @@
 //
 // The arument "request" is a structure provided to this service with the following two
 // properties:
-// request.ownCrazyflie
-// This property is itself a structure of type "CrazyflieData",  which is defined in the
-// file "CrazyflieData.msg", and has the following properties
-// string crazyflieName
+
+// >> request.ownCrazyflie
+// This property is itself a structure of type "FlyingVehicleState",  which is defined in the
+// file "FlyingVehicleState.msg", and has the following properties
+//     string vehicleName
 //     float64 x                         The x position of the Crazyflie [metres]
 //     float64 y                         The y position of the Crazyflie [metres]
 //     float64 z                         The z position of the Crazyflie [metres]
 //     float64 roll                      The roll component of the intrinsic Euler angles [radians]
 //     float64 pitch                     The pitch component of the intrinsic Euler angles [radians]
 //     float64 yaw                       The yaw component of the intrinsic Euler angles [radians]
-//     float64 acquiringTime #delta t    The time elapsed since the previous "CrazyflieData" was received [seconds]
-//     bool occluded                     A boolean indicted whether the Crazyflie for visible at the time of this measurement
+//     float64 acquiringTime #delta t    The time elapsed since the previous "FlyingVehicleState" was received [seconds]
+//     bool isValid                      A boolean indicted whether the Crazyflie for visible at the time of this measurement
 // The values in these properties are directly the measurement taken by the Vicon
 // motion capture system of the Crazyflie that is to be controlled by this service
 //
-// request.otherCrazyflies
-// This property is an array of "CrazyflieData" structures, what allows access to the
+// >> request.otherCrazyflies
+// This property is an array of "FlyingVehicleState" structures, what allows access to the
 // Vicon measurements of other Crazyflies.
 //
 // The argument "response" is a structure that is expected to be filled in by this
 // service by this function, it has only the following property
-// response.ControlCommand
-// This property is iteself a structure of type "ControlCommand", which is defined in
-// the file "ControlCommand.msg", and has the following properties:
-//     float32 roll                      The command sent to the Crazyflie for the body frame x-axis
-//     float32 pitch                     The command sent to the Crazyflie for the body frame y-axis
-//     float32 yaw                       The command sent to the Crazyflie for the body frame z-axis
-//     uint16 motorCmd1                  The command sent to the Crazyflie for motor 1
-//     uint16 motorCmd2                  The command sent to the Crazyflie for motor 1
-//     uint16 motorCmd3                  The command sent to the Crazyflie for motor 1
-//     uint16 motorCmd4                  The command sent to the Crazyflie for motor 1
-//     uint8 onboardControllerType       The flag sent to the Crazyflie for indicating how to implement the command
+//
+// >> response.ControlCommand
+// This property is iteself a structure of type "ControlCommand", which is
+// defined in the file "ControlCommand.msg", and has the following properties:
+//     uint16 motorCmd1                 The command sent to the Crazyflie for motor 1
+//     uint16 motorCmd2                 ... same for motor 2
+//     uint16 motorCmd3                 ... same for motor 3
+//     uint16 motorCmd4                 ... same for motor 4
+//     uint8 xControllerMode            The mode sent to the Crazyflie for what controller to run for the body frame x-axis
+//     uint8 yControllerMode            ... same body frame y-axis
+//     uint8 zControllerMode            ... same body frame z-axis
+//     uint8 yawControllerMode          ... same body frame yaw
+//     float32 xControllerSetpoint      The setpoint sent to the Crazyflie for the body frame x-axis controller
+//     float32 yControllerSetpoint      ... same body frame y-axis
+//     float32 zControllerSetpoint      ... same body frame z-axis
+//     float32 yawControllerSetpoint    ... same body frame yaw
 // 
-// IMPORTANT NOTES FOR "onboardControllerType"  AND AXIS CONVENTIONS
-// > The allowed values for "onboardControllerType" are in the "Defines" section at the
-//   top of this file, they are MOTOR_MODE, RATE_MODE, OR ANGLE_MODE.
-// > In the classroom exercise we will only use the RATE_MODE.
-// > In RATE_MODE the ".roll", ".ptich", and ".yaw" properties of "response.ControlCommand"
-//   specify the angular rate in [radians/second] that will be requested from the
-//   PID controllers running in the Crazyflie 2.0 firmware.
-// > In RATE_MODE the ".motorCmd1" to ".motorCmd4" properties of "response.ControlCommand"
-//   are the baseline motor commands requested from the Crazyflie, with the adjustment
-//   for body rates being added on top of this in the firmware (i.e., as per the code
-//   of the "distribute_power" function provided in exercise sheet 2).
-// > In RATE_MODE the axis convention for the roll, pitch, and yaw body rates returned
-//   in "response.ControlCommand" should use right-hand coordinate axes with x-forward
-//   and z-upwards (i.e., the positive z-axis is aligned with the direction of positive
-//   thrust). To assist, teh following is an ASCII art of this convention:
+// IMPORTANT NOTES FOR "{x,y,z,yaw}ControllerMode"  AND AXIS CONVENTIONS
+// > The allowed values for "{x,y,z,yaw}ControllerMode" are in the
+//   "Constants.h" header file, they are:
+//   - CF_ONBOARD_CONTROLLER_MODE_OFF
+//   - CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE
+//   - CF_ONBOARD_CONTROLLER_MODE_ANGLE
+//   - CF_ONBOARD_CONTROLLER_MODE_VELOCITY
+//   - CF_ONBOARD_CONTROLLER_MODE_POSITION
+//
+// > The most common option to use for the {x,y,yaw} controller is
+//   the CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE option.
+//
+// > The most common option to use for the {z} controller is
+//   the CF_ONBOARD_CONTROLLER_MODE_OFF option, and thus the
+//   body frame z-axis is controlled by the motorCmd{1,2,3,4}
+//   values that you set.
+//
+// > When the CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE is selected, then:
+//   1) the ".xControllerSetpoint", ".yControllerSetpoint", and
+//      ".yawControllerSetpoint" properties of "response.ControlCommand"
+//      specify the angular rate in [radians/second] that will be requested
+//      from the PID controllers running in the Crazyflie 2.0 firmware.
+//   2) the axis convention for the roll, pitch, and yaw body rates,
+//      i.e., as set in the {y,x,yaw}ControllerSetpoint properties of
+//      the "response.ControlCommand" that you return, is a right-hand
+//      coordinate axes with x-forward and z-upwards (i.e., the positive
+//      z-axis is aligned with the direction of positive thrust). To
+//      assist, the ASCII art below depicts this convention.
+//   3) the ".motorCmd1" to ".motorCmd4" properties of
+//      "response.ControlCommand" are the baseline motor commands
+//      requested from the Crazyflie, with the adjustment for body rates
+//      being added on top of this in the firmware (i.e., as per the
+//      code of the "distribute_power" found in the firmware).
 //
 // ASCII ART OF THE CRAZYFLIE 2.0 LAYOUT
 //
@@ -293,15 +317,23 @@ void calculateControlOutput_forRemoteControl(float stateInertial[12], Controller
 
 	// UPDATE THE "RETURN" THE VARIABLE NAMED "response"
 
-	// Put the computed rates and thrust into the "response" variable
+	// Specify the mode of each controller
+	response.controlOutput.xControllerMode   = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+	response.controlOutput.yControllerMode   = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+	response.controlOutput.zControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+	response.controlOutput.yawControllerMode = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+
+	// Put the computed rates into the "response" variable
 	// > For roll, pitch, and yaw:
-	response.controlOutput.roll  = rollRate_forResponse;
-	response.controlOutput.pitch = pitchRate_forResponse;
-	response.controlOutput.yaw   = yawRate_forResponse;
-	// > For the thrust adjustment we must add the feed-forward thrust to counter-act gravity.
-	// > NOTE: remember that the thrust is commanded per motor, so you sohuld
-	//         consider whether the "thrustAdjustment" computed by your
-	//         controller needed to be divided by 4 or not.
+	response.controlOutput.xControllerSetpoint   = pitchRate_forResponse;
+	response.controlOutput.yControllerSetpoint   = rollRate_forResponse;
+	response.controlOutput.zControllerSetpoint   = 0.0;
+	response.controlOutput.yawControllerSetpoint = yawRate_forResponse;
+
+	// Put the computed thrust into the "response" variable
+	// > On top of the thrust adjustment, we must add the feed-forward thrust to counter-act gravity.
+	// > NOTE: remember that the thrust is commanded per motor, hence divide
+	//         the thrusts by 4.
 	float thrustAdjustment = thrustAdjustment_total / 4.0;
 	// > NOTE: the "gravity_force_quarter" value was already divided by 4 when
 	//         it was loaded/processes from the .yaml file.
@@ -310,19 +342,15 @@ void calculateControlOutput_forRemoteControl(float stateInertial[12], Controller
 	response.controlOutput.motorCmd3 = computeMotorPolyBackward(thrustAdjustment + gravity_force_quarter);
 	response.controlOutput.motorCmd4 = computeMotorPolyBackward(thrustAdjustment + gravity_force_quarter);
 
-	
-	// Specify that this controller is a rate controller
-	// response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_MOTORS;
-	response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_RATE;
-	// response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_ANGLE;
+
 
 	// Display some details (if requested)
 	if (shouldDisplayDebugInfo)
 	{
 		ROS_INFO_STREAM("thrust    =" << lqr_angleRateNested_prev_thrustAdjustment );
-		ROS_INFO_STREAM("rollrate  =" << response.controlOutput.roll );
-		ROS_INFO_STREAM("pitchrate =" << response.controlOutput.pitch );
-		ROS_INFO_STREAM("yawrate   =" << response.controlOutput.yaw );
+		ROS_INFO_STREAM("rollrate  =" << response.controlOutput.yControllerSetpoint );
+		ROS_INFO_STREAM("pitchrate =" << response.controlOutput.xControllerSetpoint );
+		ROS_INFO_STREAM("yawrate   =" << response.controlOutput.yawControllerSetpoint );
 	}
 
 }
@@ -363,11 +391,11 @@ void viconSubscribeObjectNameCallback(const ViconSubscribeObjectName& msg)
 //is called when new data from Vicon arrives
 void viconCallback(const ViconData& viconData)
 {
-	for(std::vector<CrazyflieData>::const_iterator it = viconData.crazyflies.begin(); it != viconData.crazyflies.end(); ++it)
+	for(std::vector<FlyingVehicleState>::const_iterator it = viconData.crazyflies.begin(); it != viconData.crazyflies.end(); ++it)
 	{
-		CrazyflieData objectData_in_globalFrame = *it;
+		FlyingVehicleState objectData_in_globalFrame = *it;
 
-		if(objectData_in_globalFrame.crazyflieName == viconObjectName_forRemote)
+		if(objectData_in_globalFrame.vehicleName == viconObjectName_forRemote)
         {
             
 			if (shouldPublishRemote_xyz_rpy)
@@ -382,8 +410,8 @@ void viconCallback(const ViconData& viconData)
 				ROS_INFO_STREAM("[REMOTE CONTROLLER] Remote [z,r,p,y] = [ " << objectData_in_globalFrame.z << " , " << objectData_in_globalFrame.roll << " , " << objectData_in_globalFrame.pitch << " , " << objectData_in_globalFrame.yaw << " ]" );
 			}
 
-			// Update the remote set-point is not occluded
-			if(!objectData_in_globalFrame.occluded)
+			// Update the remote set-point if the data isValid
+			if(objectData_in_globalFrame.isValid)
 			{
 
 				// Update the z height variable that is used when activating
@@ -417,7 +445,7 @@ void viconCallback(const ViconData& viconData)
 					}
 
 					// Publish the updated setpoint
-					CrazyflieData setpointToPublish;
+					FlyingVehicleState setpointToPublish;
 					setpointToPublish.roll  = setpointFromRemote_roll;
 					setpointToPublish.pitch = setpointFromRemote_pitch;
 					setpointToPublish.yaw   = setpointFromRemote_yaw;
@@ -688,14 +716,21 @@ void calculateControlOutput_viaLQR(float stateErrorBody[12], Controller::Request
 			// Display that the "controller_mode" was not recognised
 			ROS_INFO_STREAM("[REMOTE CONTROLLER] ERROR: in the 'calculateControlOutput' function of the 'RemoteControllerService': the 'controller_mode' is not recognised.");
 			// Set everything in the response to zero
-			response.controlOutput.roll       =  0;
-			response.controlOutput.pitch      =  0;
-			response.controlOutput.yaw        =  0;
-			response.controlOutput.motorCmd1  =  0;
-			response.controlOutput.motorCmd2  =  0;
-			response.controlOutput.motorCmd3  =  0;
-			response.controlOutput.motorCmd4  =  0;
-			response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_MOTORS;
+			// > Specify that all controllers are disabled
+			response.controlOutput.xControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+			response.controlOutput.yControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+			response.controlOutput.zControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+			response.controlOutput.yawControllerMode = CF_ONBOARD_CONTROLLER_MODE_OFF;
+			// > Fill in zero for the controller setpoints
+			response.controlOutput.xControllerSetpoint   = 0.0;
+			response.controlOutput.yControllerSetpoint   = 0.0;
+			response.controlOutput.zControllerSetpoint   = 0.0;
+			response.controlOutput.yawControllerSetpoint = 0.0;
+			// > Fill in all motor thrusts as zerp
+			response.controlOutput.motorCmd1 = 0.0;
+			response.controlOutput.motorCmd2 = 0.0;
+			response.controlOutput.motorCmd3 = 0.0;
+			response.controlOutput.motorCmd4 = 0.0;
 			break;
 		}
 	}
@@ -735,15 +770,23 @@ void calculateControlOutput_viaLQRforRates(float stateErrorBody[12], Controller:
 
 	// UPDATE THE "RETURN" THE VARIABLE NAMED "response"
 
-	// Put the computed rates and thrust into the "response" variable
+	// Specify the mode of each controller
+	response.controlOutput.xControllerMode   = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+	response.controlOutput.yControllerMode   = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+	response.controlOutput.zControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+	response.controlOutput.yawControllerMode = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+
+	// Put the computed rates into the "response" variable
 	// > For roll, pitch, and yaw:
-	response.controlOutput.roll  = rollRate_forResponse;
-	response.controlOutput.pitch = pitchRate_forResponse;
-	response.controlOutput.yaw   = yawRate_forResponse;
-	// > For the thrust adjustment we must add the feed-forward thrust to counter-act gravity.
-	// > NOTE: remember that the thrust is commanded per motor, so you sohuld
-	//         consider whether the "thrustAdjustment" computed by your
-	//         controller needed to be divided by 4 or not.
+	response.controlOutput.xControllerSetpoint   = pitchRate_forResponse;
+	response.controlOutput.yControllerSetpoint   = rollRate_forResponse;
+	response.controlOutput.zControllerSetpoint   = 0.0;
+	response.controlOutput.yawControllerSetpoint = yawRate_forResponse;
+
+	// Put the computed thrust into the "response" variable
+	// > On top of the thrust adjustment, we must add the feed-forward thrust to counter-act gravity.
+	// > NOTE: remember that the thrust is commanded per motor, hence divide
+	//         the thrusts by 4.
 	thrustAdjustment = thrustAdjustment / 4.0;
 	// > NOTE: the "gravity_force_quarter" value was already divided by 4 when
 	//   it was loaded/processes from the .yaml file.
@@ -752,11 +795,6 @@ void calculateControlOutput_viaLQRforRates(float stateErrorBody[12], Controller:
 	response.controlOutput.motorCmd3 = computeMotorPolyBackward(thrustAdjustment + gravity_force_quarter);
 	response.controlOutput.motorCmd4 = computeMotorPolyBackward(thrustAdjustment + gravity_force_quarter);
 
-	
-	// Specify that this controller is a rate controller
-	// response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_MOTORS;
-	response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_RATE;
-	// response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_ANGLE;
 
 
 	// An alternate debugging technique is to print out data directly to the
@@ -775,9 +813,9 @@ void calculateControlOutput_viaLQRforRates(float stateErrorBody[12], Controller:
 
 		// An example of "printing out" the control actions computed.
 		ROS_INFO_STREAM("thrustAdjustment = " << thrustAdjustment);
-		ROS_INFO_STREAM("controlOutput.roll = " << response.controlOutput.roll);
-		ROS_INFO_STREAM("controlOutput.pitch = " << response.controlOutput.pitch);
-		ROS_INFO_STREAM("controlOutput.yaw = " << response.controlOutput.yaw);
+		ROS_INFO_STREAM("controlOutput.xControllerSetpoint   = " << response.controlOutput.xControllerSetpoint);
+		ROS_INFO_STREAM("controlOutput.yControllerSetpoint   = " << response.controlOutput.yControllerSetpoint);
+		ROS_INFO_STREAM("controlOutput.yawControllerSetpoint = " << response.controlOutput.yawControllerSetpoint);
 
 		// An example of "printing out" the "thrust-to-command" conversion parameters.
 		ROS_INFO_STREAM("motorPoly 0:" << motorPoly[0]);
@@ -821,15 +859,23 @@ void calculateControlOutput_viaLQRforAngles(float stateErrorBody[12], Controller
 
 	// UPDATE THE "RETURN" THE VARIABLE NAMED "response"
 
-	// Put the computed rates and thrust into the "response" variable
+	// Specify the mode of each controller
+	response.controlOutput.xControllerMode   = CF_ONBOARD_CONTROLLER_MODE_ANGLE;
+	response.controlOutput.yControllerMode   = CF_ONBOARD_CONTROLLER_MODE_ANGLE;
+	response.controlOutput.zControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+	response.controlOutput.yawControllerMode = CF_ONBOARD_CONTROLLER_MODE_ANGLE;
+
+	// Put the computed angles into the "response" variable
 	// > For roll, pitch, and yaw:
-	response.controlOutput.roll  = rollAngle_forResponse;
-	response.controlOutput.pitch = pitchAngle_forResponse;
-	response.controlOutput.yaw   = setpoint[3];
-	// > For the thrust adjustment we must add the feed-forward thrust to counter-act gravity.
-	// > NOTE: remember that the thrust is commanded per motor, so you sohuld
-	//         consider whether the "thrustAdjustment" computed by your
-	//         controller needed to be divided by 4 or not.
+	response.controlOutput.xControllerSetpoint   = pitchAngle_forResponse;
+	response.controlOutput.yControllerSetpoint   = rollAngle_forResponse;
+	response.controlOutput.zControllerSetpoint   = 0.0;
+	response.controlOutput.yawControllerSetpoint = setpoint[3];
+
+	// Put the computed thrust into the "response" variable
+	// > On top of the thrust adjustment, we must add the feed-forward thrust to counter-act gravity.
+	// > NOTE: remember that the thrust is commanded per motor, hence divide
+	//         the thrusts by 4.
 	thrustAdjustment = thrustAdjustment / 4.0;
 	// > NOTE: the "gravity_force_quarter" value was already divided by 4 when
 	//         it was loaded/processes from the .yaml file.
@@ -838,13 +884,6 @@ void calculateControlOutput_viaLQRforAngles(float stateErrorBody[12], Controller
 	response.controlOutput.motorCmd3 = computeMotorPolyBackward(thrustAdjustment + gravity_force_quarter);
 	response.controlOutput.motorCmd4 = computeMotorPolyBackward(thrustAdjustment + gravity_force_quarter);
 
-	
-	// Specify that this controller is a rate controller
-	// response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_MOTORS;
-	// response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_RATE;
-	response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_ANGLE;
-
-
 }
 
 
@@ -926,15 +965,23 @@ void calculateControlOutput_viaLQRforAnglesRatesNested( float stateErrorBody[12]
 
 	// UPDATE THE "RETURN" THE VARIABLE NAMED "response"
 
-	// Put the computed rates and thrust into the "response" variable
+	// Specify the mode of each controller
+	response.controlOutput.xControllerMode   = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+	response.controlOutput.yControllerMode   = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+	response.controlOutput.zControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+	response.controlOutput.yawControllerMode = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+
+	// Put the computed rates into the "response" variable
 	// > For roll, pitch, and yaw:
-	response.controlOutput.roll  = rollRate_forResponse;
-	response.controlOutput.pitch = pitchRate_forResponse;
-	response.controlOutput.yaw   = yawRate_forResponse;
-	// > For the thrust adjustment we must add the feed-forward thrust to counter-act gravity.
-	// > NOTE: remember that the thrust is commanded per motor, so you sohuld
-	//         consider whether the "thrustAdjustment" computed by your
-	//         controller needed to be divided by 4 or not.
+	response.controlOutput.xControllerSetpoint   = pitchRate_forResponse;
+	response.controlOutput.yControllerSetpoint   = rollRate_forResponse;
+	response.controlOutput.zControllerSetpoint   = 0.0;
+	response.controlOutput.yawControllerSetpoint = yawRate_forResponse;
+
+	// Put the computed thrust into the "response" variable
+	// > On top of the thrust adjustment, we must add the feed-forward thrust to counter-act gravity.
+	// > NOTE: remember that the thrust is commanded per motor, hence divide
+	//         the thrusts by 4.
 	float thrustAdjustment = lqr_angleRateNested_prev_thrustAdjustment / 4.0;
 	// > NOTE: the "gravity_force_quarter" value was already divided by 4 when
 	//         it was loaded/processes from the .yaml file.
@@ -943,19 +990,15 @@ void calculateControlOutput_viaLQRforAnglesRatesNested( float stateErrorBody[12]
 	response.controlOutput.motorCmd3 = computeMotorPolyBackward(thrustAdjustment + gravity_force_quarter);
 	response.controlOutput.motorCmd4 = computeMotorPolyBackward(thrustAdjustment + gravity_force_quarter);
 
-	
-	// Specify that this controller is a rate controller
-	// response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_MOTORS;
-	response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_RATE;
-	// response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_ANGLE;
+
 
 	// Display some details (if requested)
 	if (shouldDisplayDebugInfo)
 	{
 		ROS_INFO_STREAM("thrust    =" << lqr_angleRateNested_prev_thrustAdjustment );
-		ROS_INFO_STREAM("rollrate  =" << response.controlOutput.roll );
-		ROS_INFO_STREAM("pitchrate =" << response.controlOutput.pitch );
-		ROS_INFO_STREAM("yawrate   =" << response.controlOutput.yaw );
+		ROS_INFO_STREAM("rollrate  =" << response.controlOutput.yControllerSetpoint );
+		ROS_INFO_STREAM("pitchrate =" << response.controlOutput.xControllerSetpoint );
+		ROS_INFO_STREAM("yawrate   =" << response.controlOutput.yawControllerSetpoint );
 	}
 }
 
@@ -1376,9 +1419,9 @@ void fetchRemoteControllerYamlParameters(ros::NodeHandle& nodeHandle)
 	remoteConrtolSetpointFactor_z      = getParameterFloat(nodeHandle_for_paramaters , "remoteConrtolSetpointFactor_z");
 
 	// LQR Gain matrix for tracking the angle commands from the Crazyflie
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixRollRate_forRemoteControl",   gainMatrixRollRate_forRemoteControl,    3);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixPitchRate_forRemoteControl",  gainMatrixPitchRate_forRemoteControl,   3);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixYawRate_forRemoteControl",    gainMatrixYawRate_forRemoteControl,     3);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixRollRate_forRemoteControl",   gainMatrixRollRate_forRemoteControl,    3);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixPitchRate_forRemoteControl",  gainMatrixPitchRate_forRemoteControl,   3);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixYawRate_forRemoteControl",    gainMatrixYawRate_forRemoteControl,     3);
 
 	// DEBUGGING: Print out one of the parameters that was loaded
 	ROS_INFO_STREAM("[REMOTE CONTROLLER] DEBUGGING: the fetched RemoteController/default_viconObjectName_forRemote = " << default_viconObjectName_forRemote);
@@ -1403,7 +1446,7 @@ void fetchRemoteControllerYamlParameters(ros::NodeHandle& nodeHandle)
 
 	// > The co-efficients of the quadratic conversation from 16-bit motor command to
 	//   thrust force in Newtons
-	getParameterFloatVector(nodeHandle_for_paramaters, "motorPoly", motorPoly, 3);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "motorPoly", motorPoly, 3);
 
 	// > The boolean for whether to execute the convert into body frame function
 	shouldPerformConvertIntoBodyFrame = getParameterBool(nodeHandle_for_paramaters, "shouldPerformConvertIntoBodyFrame");
@@ -1424,24 +1467,24 @@ void fetchRemoteControllerYamlParameters(ros::NodeHandle& nodeHandle)
 	yaml_estimator_method = getParameterInt( nodeHandle_for_paramaters , "estimator_method" );
 
 	// The LQR Controller parameters for "LQR_MODE_RATE"
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixThrust_NineStateVector", gainMatrixThrust_NineStateVector, 9);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixRollRate",               gainMatrixRollRate,               9);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixPitchRate",              gainMatrixPitchRate,              9);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixYawRate",                gainMatrixYawRate,                9);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixThrust_NineStateVector", gainMatrixThrust_NineStateVector, 9);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixRollRate",               gainMatrixRollRate,               9);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixPitchRate",              gainMatrixPitchRate,              9);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixYawRate",                gainMatrixYawRate,                9);
 	
 	// The LQR Controller parameters for "LQR_MODE_ANGLE"
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixThrust_SixStateVector",  gainMatrixThrust_SixStateVector,  6);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixRollAngle",              gainMatrixRollAngle,              6);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixPitchAngle",             gainMatrixPitchAngle,             6);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixThrust_SixStateVector",  gainMatrixThrust_SixStateVector,  6);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixRollAngle",              gainMatrixRollAngle,              6);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixPitchAngle",             gainMatrixPitchAngle,             6);
 	
 	// The LQR Controller parameters for "LQR_MODE_ANGLE_RATE_NESTED"
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixThrust_SixStateVector_50Hz",  gainMatrixThrust_SixStateVector_50Hz,  6);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixRollAngle_50Hz",              gainMatrixRollAngle_50Hz,              6);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixPitchAngle_50Hz",             gainMatrixPitchAngle_50Hz,             6);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixThrust_SixStateVector_50Hz",  gainMatrixThrust_SixStateVector_50Hz,  6);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixRollAngle_50Hz",              gainMatrixRollAngle_50Hz,              6);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixPitchAngle_50Hz",             gainMatrixPitchAngle_50Hz,             6);
 
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixRollRate_Nested",             gainMatrixRollRate_Nested,             3);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixPitchRate_Nested",            gainMatrixPitchRate_Nested,            3);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixYawRate_Nested",              gainMatrixYawRate_Nested,              3);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixRollRate_Nested",             gainMatrixRollRate_Nested,             3);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixPitchRate_Nested",            gainMatrixPitchRate_Nested,            3);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixYawRate_Nested",              gainMatrixYawRate_Nested,              3);
 
 	
 	// 16-BIT COMMAND LIMITS
@@ -1451,13 +1494,13 @@ void fetchRemoteControllerYamlParameters(ros::NodeHandle& nodeHandle)
 
 	// THE POINT MASS KALMAN FILTER (PMKF) GAINS AND ERROR EVOLUATION
 	// > For the (x,y,z) position
-	getParameterFloatVector(nodeHandle_for_paramaters, "PMKF_Ahat_row1_for_positions",  PMKF_Ahat_row1_for_positions,  2);
-	getParameterFloatVector(nodeHandle_for_paramaters, "PMKF_Ahat_row2_for_positions",  PMKF_Ahat_row2_for_positions,  2);
-	getParameterFloatVector(nodeHandle_for_paramaters, "PMKF_Kinf_for_positions"     ,  PMKF_Kinf_for_positions     ,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "PMKF_Ahat_row1_for_positions",  PMKF_Ahat_row1_for_positions,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "PMKF_Ahat_row2_for_positions",  PMKF_Ahat_row2_for_positions,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "PMKF_Kinf_for_positions"     ,  PMKF_Kinf_for_positions     ,  2);
 	// > For the (roll,pitch,yaw) angles
-	getParameterFloatVector(nodeHandle_for_paramaters, "PMKF_Ahat_row1_for_angles",  PMKF_Ahat_row1_for_angles,  2);
-	getParameterFloatVector(nodeHandle_for_paramaters, "PMKF_Ahat_row2_for_angles",  PMKF_Ahat_row2_for_angles,  2);
-	getParameterFloatVector(nodeHandle_for_paramaters, "PMKF_Kinf_for_angles"     ,  PMKF_Kinf_for_angles     ,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "PMKF_Ahat_row1_for_angles",  PMKF_Ahat_row1_for_angles,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "PMKF_Ahat_row2_for_angles",  PMKF_Ahat_row2_for_angles,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "PMKF_Kinf_for_angles"     ,  PMKF_Kinf_for_angles     ,  2);
 
 
 	// DEBUGGING: Print out one of the parameters that was loaded
@@ -1635,13 +1678,13 @@ int main(int argc, char* argv[]) {
 	ros::Subscriber viconSubscribeObjectNameSubscriber = nodeHandle.subscribe("ViconSubscribeObjectName", 1, viconSubscribeObjectNameCallback);
 
 	// Advertise the message topic of the Remote (y,roll,pitch,yaw)
-	remote_xyz_rpy_publisher = nodeHandle.advertise<CrazyflieData>("RemoteData", 1);
+	remote_xyz_rpy_publisher = nodeHandle.advertise<FlyingVehicleState>("RemoteData", 1);
 
 	// Subscribe to the message that triggers activates/deactivates remote control mode
 	ros::Subscriber shouldActivateSubscriber = nodeHandle.subscribe("Activate", 1, shouldActivateCallback);
 
 	// Advertise the message topic of the Remote (y,roll,pitch,yaw)
-	remote_control_setpoint_publisher = nodeHandle.advertise<CrazyflieData>("RemoteControlSetpoint", 1);
+	remote_control_setpoint_publisher = nodeHandle.advertise<FlyingVehicleState>("RemoteControlSetpoint", 1);
 
 
 
diff --git a/dfall_ws/src/dfall_pkg/src/nodes/SafeControllerService.cpp b/dfall_ws/src/dfall_pkg/src/nodes/SafeControllerService.cpp
index e9f1c08cfd6265c2585b4c14244354f0069a6178..ea4aa64b401207346d478de2f9db40c37d5a9a99 100755
--- a/dfall_ws/src/dfall_pkg/src/nodes/SafeControllerService.cpp
+++ b/dfall_ws/src/dfall_pkg/src/nodes/SafeControllerService.cpp
@@ -289,24 +289,24 @@ void fetchYamlParameters(ros::NodeHandle& nodeHandle)
 
     // > The co-efficients of the quadratic conversation from 16-bit motor command to
     //   thrust force in Newtons
-    getParameterFloatVector(nodeHandle_for_safeController, "motorPoly", motorPoly, 3);
+    getParameterFloatVectorKnownLength(nodeHandle_for_safeController, "motorPoly", motorPoly, 3);
     
     
     // > The row of the LQR matrix that commands body frame roll rate
-    getParameterFloatVector(nodeHandle_for_safeController, "gainMatrixRoll", gainMatrixRoll, 9);
+    getParameterFloatVectorKnownLength(nodeHandle_for_safeController, "gainMatrixRoll", gainMatrixRoll, 9);
     // > The row of the LQR matrix that commands body frame pitch rate
-    getParameterFloatVector(nodeHandle_for_safeController, "gainMatrixPitch", gainMatrixPitch, 9);
+    getParameterFloatVectorKnownLength(nodeHandle_for_safeController, "gainMatrixPitch", gainMatrixPitch, 9);
     // > The row of the LQR matrix that commands body frame yaw rate
-    getParameterFloatVector(nodeHandle_for_safeController, "gainMatrixYaw", gainMatrixYaw, 9);
+    getParameterFloatVectorKnownLength(nodeHandle_for_safeController, "gainMatrixYaw", gainMatrixYaw, 9);
     // > The row of the LQR matrix that commands thrust adjustment
-    getParameterFloatVector(nodeHandle_for_safeController, "gainMatrixThrust", gainMatrixThrust, 9);
+    getParameterFloatVectorKnownLength(nodeHandle_for_safeController, "gainMatrixThrust", gainMatrixThrust, 9);
 
     // > The gains for the point-mass Kalman filter
-    getParameterFloatVector(nodeHandle_for_safeController, "filterGain", filterGain, 6);
-    getParameterFloatVector(nodeHandle_for_safeController, "estimatorMatrix", estimatorMatrix, 2);
+    getParameterFloatVectorKnownLength(nodeHandle_for_safeController, "filterGain", filterGain, 6);
+    getParameterFloatVectorKnownLength(nodeHandle_for_safeController, "estimatorMatrix", estimatorMatrix, 2);
 
     // > The defailt setpoint of the controller
-    getParameterFloatVector(nodeHandle_for_safeController, "defaultSetpoint", defaultSetpoint, 4);
+    getParameterFloatVectorKnownLength(nodeHandle_for_safeController, "defaultSetpoint", defaultSetpoint, 4);
 
     // DEBUGGING: Print out one of the parameters that was loaded
     ROS_INFO_STREAM("[SAFE CONTROLLER] DEBUGGING: the fetched SafeController/mass = " << cf_mass);
@@ -346,7 +346,7 @@ float getParameterFloat(ros::NodeHandle& nodeHandle, std::string name)
     return val;
 }
 
-void getParameterFloatVector(ros::NodeHandle& nodeHandle, std::string name, std::vector<float>& val, int length)
+void getParameterFloatVectorKnownLength(ros::NodeHandle& nodeHandle, std::string name, std::vector<float>& val, int length)
 {
     if(!nodeHandle.getParam(name, val)){
         ROS_ERROR_STREAM("missing parameter '" << name << "'");
diff --git a/dfall_ws/src/dfall_pkg/src/nodes/StudentControllerService.cpp b/dfall_ws/src/dfall_pkg/src/nodes/StudentControllerService.cpp
index 4266a77b9b69f81534e15062e2555bf9d534f4b2..20c0131b793834925b081da783f1649bef283811 100644
--- a/dfall_ws/src/dfall_pkg/src/nodes/StudentControllerService.cpp
+++ b/dfall_ws/src/dfall_pkg/src/nodes/StudentControllerService.cpp
@@ -37,7 +37,27 @@
 #include "nodes/StudentControllerService.h"
 
 
+//    ---------------------------------------------------------------------------------------------------
+//     CCCC  L        A     SSSS   SSSS       V   V    A    RRRR   III    A    BBBB   L      EEEEE   SSSS
+//    C      L       A A   S      S           V   V   A A   R   R   I    A A   B   B  L      E      S    
+//    C      L      A   A   SSS    SSS        V   V  A   A  RRRR    I   A   A  BBBB   L      EEE     SSS 
+//    C      L      AAAAA      S      S        V V   AAAAA  R   R   I   AAAAA  B   B  L      E          S
+//     CCCC  LLLLL  A   A  SSSS   SSSS          V    A   A  R   R  III  A   A  BBBB   LLLLL  EEEEE  SSSS 
+//    ---------------------------------------------------------------------------------------------------
 
+//DECLARE YOUR CLASS VARIABLES BELOW HERE
+
+
+
+// VARIABLES FOR VALUES LOADED FROM THE YAML FILE
+// > the proportional gain for z control
+float yaml_kp_z = 1.0;
+
+// > the derivative gain for z control
+float yaml_kd_z = 1.0;
+
+// > the integral gain for z control
+float yaml_ki_z = 1.0;
 
 
 
@@ -80,64 +100,78 @@
 //
 // The arument "request" is a structure provided to this service with the following two
 // properties:
-// request.ownCrazyflie
-// This property is itself a structure of type "CrazyflieData",  which is defined in the
-// file "CrazyflieData.msg", and has the following properties
-// string crazyflieName
+//
+// >> request.ownCrazyflie
+// This property is itself a structure of type "FlyingVehicleState",  which is defined in the
+// file "FlyingVehicleState.msg", and has the following properties
+//     string vehicleName
 //     float64 x                         The x position of the Crazyflie [metres]
 //     float64 y                         The y position of the Crazyflie [metres]
 //     float64 z                         The z position of the Crazyflie [metres]
 //     float64 roll                      The roll component of the intrinsic Euler angles [radians]
 //     float64 pitch                     The pitch component of the intrinsic Euler angles [radians]
 //     float64 yaw                       The yaw component of the intrinsic Euler angles [radians]
-//     float64 acquiringTime #delta t    The time elapsed since the previous "CrazyflieData" was received [seconds]
-//     bool occluded                     A boolean indicted whether the Crazyflie for visible at the time of this measurement
+//     float64 acquiringTime #delta t    The time elapsed since the previous "FlyingVehicleState" was received [seconds]
+//     bool isValid                      A boolean indicted whether the Crazyflie for visible at the time of this measurement
 // The values in these properties are directly the measurement taken by the Vicon
 // motion capture system of the Crazyflie that is to be controlled by this service
 //
-// request.otherCrazyflies
-// This property is an array of "CrazyflieData" structures, what allows access to the
+// >> request.otherCrazyflies
+// This property is an array of "FlyingVehicleState" structures, what allows access to the
 // Vicon measurements of other Crazyflies.
 //
 // The argument "response" is a structure that is expected to be filled in by this
 // service by this function, it has only the following property
-// response.ControlCommand
-// This property is iteself a structure of type "ControlCommand", which is defined in
-// the file "ControlCommand.msg", and has the following properties:
-//     float32 roll                      The command sent to the Crazyflie for the body frame x-axis
-//     float32 pitch                     The command sent to the Crazyflie for the body frame y-axis
-//     float32 yaw                       The command sent to the Crazyflie for the body frame z-axis
-//     uint16 motorCmd1                  The command sent to the Crazyflie for motor 1
-//     uint16 motorCmd2                  The command sent to the Crazyflie for motor 1
-//     uint16 motorCmd3                  The command sent to the Crazyflie for motor 1
-//     uint16 motorCmd4                  The command sent to the Crazyflie for motor 1
-//     uint8 onboardControllerType       The flag sent to the Crazyflie for indicating how to implement the command
+//
+// >> response.ControlCommand
+// This property is iteself a structure of type "ControlCommand", which is
+// defined in the file "ControlCommand.msg", and has the following properties:
+//     uint16 motorCmd1                 The command sent to the Crazyflie for motor 1
+//     uint16 motorCmd2                 ... same for motor 2
+//     uint16 motorCmd3                 ... same for motor 3
+//     uint16 motorCmd4                 ... same for motor 4
+//     uint8 xControllerMode            The mode sent to the Crazyflie for what controller to run for the body frame x-axis
+//     uint8 yControllerMode            ... same body frame y-axis
+//     uint8 zControllerMode            ... same body frame z-axis
+//     uint8 yawControllerMode          ... same body frame yaw
+//     float32 xControllerSetpoint      The setpoint sent to the Crazyflie for the body frame x-axis controller
+//     float32 yControllerSetpoint      ... same body frame y-axis
+//     float32 zControllerSetpoint      ... same body frame z-axis
+//     float32 yawControllerSetpoint    ... same body frame yaw
 // 
-// IMPORTANT NOTES FOR "onboardControllerType"  AND AXIS CONVENTIONS
-// > The allowed values for "onboardControllerType" are in the "Defines"
-//   section in the header file, they are:
-//   - CF_COMMAND_TYPE_MOTORS
-//   - CF_COMMAND_TYPE_RATE
-//   - CF_COMMAND_TYPE_ANGLE
+// IMPORTANT NOTES FOR "{x,y,z,yaw}ControllerMode"  AND AXIS CONVENTIONS
+// > The allowed values for "{x,y,z,yaw}ControllerMode" are in the
+//   "Constants.h" header file, they are:
+//   - CF_ONBOARD_CONTROLLER_MODE_OFF
+//   - CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE
+//   - CF_ONBOARD_CONTROLLER_MODE_ANGLE
+//   - CF_ONBOARD_CONTROLLER_MODE_VELOCITY
+//   - CF_ONBOARD_CONTROLLER_MODE_POSITION
 //
-// > For completeing the class exercises it is only required to use
-//   the CF_COMMAND_TYPE_RATE option.
+// > The most common option to use for the {x,y,yaw} controller is
+//   the CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE option.
 //
-// > For the CF_COMMAND_TYPE_RATE optoin:
-//   1) the ".roll", ".ptich", and ".yaw" properties of
-//      "response.ControlCommand" specify the angular rate in
-//      [radians/second] that will be requested from the PID controllers
-//      running in the Crazyflie 2.0 firmware.
-//   2) the ".motorCmd1" to ".motorCmd4" properties of
+// > The most common option to use for the {z} controller is
+//   the CF_ONBOARD_CONTROLLER_MODE_OFF option, and thus the
+//   body frame z-axis is controlled by the motorCmd{1,2,3,4}
+//   values that you set.
+//
+// > When the CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE is selected, then:
+//   1) the ".xControllerSetpoint", ".yControllerSetpoint", and
+//      ".yawControllerSetpoint" properties of "response.ControlCommand"
+//      specify the angular rate in [radians/second] that will be requested
+//      from the PID controllers running in the Crazyflie 2.0 firmware.
+//   2) the axis convention for the roll, pitch, and yaw body rates,
+//      i.e., as set in the {y,x,yaw}ControllerSetpoint properties of
+//      the "response.ControlCommand" that you return, is a right-hand
+//      coordinate axes with x-forward and z-upwards (i.e., the positive
+//      z-axis is aligned with the direction of positive thrust). To
+//      assist, the ASCII art below depicts this convention.
+//   3) the ".motorCmd1" to ".motorCmd4" properties of
 //      "response.ControlCommand" are the baseline motor commands
 //      requested from the Crazyflie, with the adjustment for body rates
 //      being added on top of this in the firmware (i.e., as per the
 //      code of the "distribute_power" found in the firmware).
-//   3) the axis convention for the roll, pitch, and yaw body rates
-//      returned in "response.ControlCommand" should use right-hand
-//      coordinate axes with x-forward and z-upwards (i.e., the positive
-//      z-axis is aligned with the direction of positive thrust). To
-//      assist, the following is an ASCII art of this convention.
 //
 // ASCII ART OF THE CRAZYFLIE 2.0 LAYOUT
 //
@@ -188,20 +222,39 @@ bool calculateControlOutput(Controller::Request &request, Controller::Response &
 	stateErrorInertial[2] = request.ownCrazyflie.z - m_setpoint[2];
 
 	// Compute an estimate of the velocity
-	// > But only if this is NOT the first call to the controller
-	if (!request.isFirstControllerCall)
+	// > Via finite differences if receiveing
+	//   Motion Capture data
+	if (request.ownCrazyflie.type == FLYING_VEHICLE_STATE_TYPE_MOCAP_MEASUREMENT)
 	{
-		// > Compute as simply the derivative between the current and previous position
-		stateErrorInertial[3] = (stateErrorInertial[0] - m_previous_stateErrorInertial[0]) * yaml_control_frequency;
-		stateErrorInertial[4] = (stateErrorInertial[1] - m_previous_stateErrorInertial[1]) * yaml_control_frequency;
-		stateErrorInertial[5] = (stateErrorInertial[2] - m_previous_stateErrorInertial[2]) * yaml_control_frequency;
+		// > But only if this is NOT the first call
+		//   to the controller
+		if (!request.isFirstControllerCall)
+		{
+			// > Compute as simply the derivative between
+			//   the current and previous position
+			stateErrorInertial[3] = (stateErrorInertial[0] - m_previous_stateErrorInertial[0]) * yaml_control_frequency;
+			stateErrorInertial[4] = (stateErrorInertial[1] - m_previous_stateErrorInertial[1]) * yaml_control_frequency;
+			stateErrorInertial[5] = (stateErrorInertial[2] - m_previous_stateErrorInertial[2]) * yaml_control_frequency;
+		}
+		else
+		{
+			// Set the velocities to zero
+			stateErrorInertial[3] = 0.0;
+			stateErrorInertial[4] = 0.0;
+			stateErrorInertial[5] = 0.0;
+		}
+	}
+	// > Else, via finite difference if receiveing
+	//   onboard state estimate data
+	else if (request.ownCrazyflie.type == FLYING_VEHICLE_STATE_TYPE_CRAZYFLIE_STATE_ESTIMATE)
+	{
+		stateErrorInertial[3] = request.ownCrazyflie.vx;
+		stateErrorInertial[4] = request.ownCrazyflie.vy;
+		stateErrorInertial[5] = request.ownCrazyflie.vz;
 	}
 	else
 	{
-		// Set the velocities to zero
-		stateErrorInertial[3] = 0.0;
-		stateErrorInertial[4] = 0.0;
-		stateErrorInertial[5] = 0.0;
+		ROS_ERROR_STREAM("[STUDENT CONTROLLER] Received a request.ownCrazyflie with unrecognised type, request.ownCrazyflie.type = " << request.ownCrazyflie.type );
 	}
 
 	// Fill in the roll and pitch angle measurements directly
@@ -260,8 +313,10 @@ bool calculateControlOutput(Controller::Request &request, Controller::Response &
 	}
 
 	// Put the computed yaw rate into the "response" variable
-	response.controlOutput.yaw = yawRate_forResponse;
-
+	// > The "controller mode" specifies that it is an
+	//   angular rate setpoint
+	response.controlOutput.yawControllerMode     = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+	response.controlOutput.yawControllerSetpoint = yawRate_forResponse;
 
 
 
@@ -284,8 +339,9 @@ bool calculateControlOutput(Controller::Request &request, Controller::Response &
 		thrustAdjustment -= m_gainMatrixThrust[i] * stateErrorBody[i];
 	}
 
-	// Put the computed thrust adjustment into the "response" variable,
-	// as well as adding the feed-forward thrust to counter-act gravity.
+	// Put the computed thrust adjustment into the "response" variable.
+	// > On top of the thrust adjustment, we must add the feed-forward thrust
+	//   to counter-act gravity.
 	// > NOTE: remember that the thrust is commanded per motor, so you sohuld
 	//         consider whether the "thrustAdjustment" computed by your
 	//         controller needed to be divided by 4 or not.
@@ -293,12 +349,18 @@ bool calculateControlOutput(Controller::Request &request, Controller::Response &
 	//         as feed-forward. Assuming the the Crazyflie is symmetric, this
 	//         value is divided by four.
 	float feed_forward_thrust_per_motor = m_cf_weight_in_newtons / 4.0;
-	// > NOTE: the function "computeMotorPolyBackward" converts the input argument
+	// > NOTE: the function "newtons2cmd_for_crazyflie" converts the input argument
 	//         from Newtons to the 16-bit command expected by the Crazyflie.
-	response.controlOutput.motorCmd1 = computeMotorPolyBackward(thrustAdjustment + feed_forward_thrust_per_motor);
-	response.controlOutput.motorCmd2 = computeMotorPolyBackward(thrustAdjustment + feed_forward_thrust_per_motor);
-	response.controlOutput.motorCmd3 = computeMotorPolyBackward(thrustAdjustment + feed_forward_thrust_per_motor);
-	response.controlOutput.motorCmd4 = computeMotorPolyBackward(thrustAdjustment + feed_forward_thrust_per_motor);
+	response.controlOutput.motorCmd1 = newtons2cmd_for_crazyflie(thrustAdjustment + feed_forward_thrust_per_motor);
+	response.controlOutput.motorCmd2 = newtons2cmd_for_crazyflie(thrustAdjustment + feed_forward_thrust_per_motor);
+	response.controlOutput.motorCmd3 = newtons2cmd_for_crazyflie(thrustAdjustment + feed_forward_thrust_per_motor);
+	response.controlOutput.motorCmd4 = newtons2cmd_for_crazyflie(thrustAdjustment + feed_forward_thrust_per_motor);
+
+	// Set the onboard z-controller to be OFF
+	// > This is because we commands the motor thrusts and
+	//   hence an "inner" control loop is NOT needed onboard
+	//   to control the z-height
+	response.controlOutput.zControllerMode = CF_ONBOARD_CONTROLLER_MODE_OFF;
 
 	
 
@@ -322,7 +384,10 @@ bool calculateControlOutput(Controller::Request &request, Controller::Response &
 	}
 
 	// Put the computed pitch rate into the "response" variable
-	response.controlOutput.pitch = pitchRate_forResponse;
+	// > The "controller mode" specifies that it is an
+	//   angular rate setpoint
+	response.controlOutput.xControllerMode     = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+	response.controlOutput.xControllerSetpoint = pitchRate_forResponse;
 
 
 
@@ -347,17 +412,10 @@ bool calculateControlOutput(Controller::Request &request, Controller::Response &
 	}
 
 	// Put the computed roll rate into the "response" variable
-	response.controlOutput.roll = rollRate_forResponse;
-
-	
-	
-	// PREPARE AND RETURN THE VARIABLE "response"
-
-	// Choose the controller type use on-board the Crazyflie,
-	// it can be either be Motor, Rate, or Angle based
-	// response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_MOTORS;
-	response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_RATE;
-	// response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_ANGLE;
+	// > The "controller mode" specifies that it is an
+	//   angular rate setpoint
+	response.controlOutput.yControllerMode     = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+	response.controlOutput.yControllerSetpoint = rollRate_forResponse;
 
 
 
@@ -394,7 +452,10 @@ bool calculateControlOutput(Controller::Request &request, Controller::Response &
 	// The "DebugMsg" type has 10 properties from "value_1" to "value_10", all of
 	// type "float64" that you can fill in with data you would like to plot in
 	// real-time.
-	// debugMsg.value_1 = thrustAdjustment;
+	debugMsg.value_1 = thrustAdjustment;
+	debugMsg.value_2 = rollRate_forResponse;
+	debugMsg.value_3 = pitchRate_forResponse;
+	debugMsg.value_4 = yawRate_forResponse;
 	// ......................
 	// debugMsg.value_10 = your_variable_name;
 
@@ -409,21 +470,16 @@ bool calculateControlOutput(Controller::Request &request, Controller::Response &
 	// ROS_INFO_STREAM("x-coordinates: " << request.ownCrazyflie.x);
 	// ROS_INFO_STREAM("y-coordinates: " << request.ownCrazyflie.y);
 	// ROS_INFO_STREAM("z-coordinates: " << request.ownCrazyflie.z);
-	// ROS_INFO_STREAM("roll: " << request.ownCrazyflie.roll);
+	// ROS_INFO_STREAM("roll:  " << request.ownCrazyflie.roll);
 	// ROS_INFO_STREAM("pitch: " << request.ownCrazyflie.pitch);
-	// ROS_INFO_STREAM("yaw: " << request.ownCrazyflie.yaw);
+	// ROS_INFO_STREAM("yaw:   " << request.ownCrazyflie.yaw);
 	// ROS_INFO_STREAM("Delta t: " << request.ownCrazyflie.acquiringTime);
 
 	// An example of "printing out" the control actions computed.
 	// ROS_INFO_STREAM("thrustAdjustment = " << thrustAdjustment);
-	// ROS_INFO_STREAM("controlOutput.roll = " << response.controlOutput.roll);
-	// ROS_INFO_STREAM("controlOutput.pitch = " << response.controlOutput.pitch);
-	// ROS_INFO_STREAM("controlOutput.yaw = " << response.controlOutput.yaw);
-
-	// An example of "printing out" the "thrust-to-command" conversion parameters.
-	// ROS_INFO_STREAM("motorPoly 0:" << yaml_motorPoly[0]);
-	// ROS_INFO_STREAM("motorPoly 1:" << yaml_motorPoly[1]);
-	// ROS_INFO_STREAM("motorPoly 2:" << yaml_motorPoly[2]);
+	// ROS_INFO_STREAM("controlOutput.xControllerSetpoint   = " << response.controlOutput.xControllerSetpoint);
+	// ROS_INFO_STREAM("controlOutput.yControllerSetpoint   = " << response.controlOutput.yControllerSetpoint);
+	// ROS_INFO_STREAM("controlOutput.yawControllerSetpoint = " << response.controlOutput.yawControllerSetpoint);
 
 	// An example of "printing out" the per motor 16-bit command computed.
 	// ROS_INFO_STREAM("controlOutput.cmd1 = " << response.controlOutput.motorCmd1);
@@ -498,46 +554,6 @@ void convertIntoBodyFrame(float stateInertial[9], float (&stateBody)[9], float y
 
 
 
-//    ------------------------------------------------------------------------------
-//    N   N  EEEEE  W     W   TTTTT   OOO   N   N        CCCC  M   M  DDDD
-//    NN  N  E      W     W     T    O   O  NN  N       C      MM MM  D   D
-//    N N N  EEE    W     W     T    O   O  N N N  -->  C      M M M  D   D
-//    N  NN  E       W W W      T    O   O  N  NN       C      M   M  D   D
-//    N   N  EEEEE    W W       T     OOO   N   N        CCCC  M   M  DDDD
-//
-//     CCCC   OOO   N   N  V   V  EEEEE  RRRR    SSSS  III   OOO   N   N
-//    C      O   O  NN  N  V   V  E      R   R  S       I   O   O  NN  N
-//    C      O   O  N N N  V   V  EEE    RRRR    SSS    I   O   O  N N N
-//    C      O   O  N  NN   V V   E      R  R       S   I   O   O  N  NN
-//     CCCC   OOO   N   N    V    EEEEE  R   R  SSSS   III   OOO   N   N
-//    ----------------------------------------------------------------------------------
-
-// This function DOES NEED TO BE edited for successful completion of
-// the exercise
-float computeMotorPolyBackward(float thrust)
-{
-	// Compute the 16-bit command that would produce the requested
-	// "thrust" based on the quadratic mapping that is described
-	// by the coefficients in the "yaml_motorPoly" variable.
-	float cmd_16bit = (-yaml_motorPoly[1] + sqrt(yaml_motorPoly[1] * yaml_motorPoly[1] - 4 * yaml_motorPoly[2] * (yaml_motorPoly[0] - thrust))) / (2 * yaml_motorPoly[2]);
-
-
-
-	// > Could this formula compute a result "cmd_16bit" that is
-	//   greater than ((2^16)-1)?
-	// > What might happen when such a number is case as a 16-bit
-	//   integer? In other words, what is uint16(cmd_sixteen_bit)?
-
-
-
-	// Return the result
-	return cmd_16bit;
-}
-
-
-
-
-
 //    ----------------------------------------------------------------------------------
 //    N   N  EEEEE  W     W        SSSS  EEEEE  TTTTT  PPPP    OOO   III  N   N  TTTTT
 //    NN  N  E      W     W       S      E        T    P   P  O   O   I   NN  N    T
@@ -816,6 +832,15 @@ void fetchStudentControllerYamlParameters(ros::NodeHandle& nodeHandle)
 
 	// GET THE PARAMETERS:
 
+	// > the proportional gain for z control
+	yaml_kp_z = getParameterFloat(nodeHandle_for_paramaters , "proportionalgain_for_z");
+
+	// > the derivative gain for z control
+	yaml_kd_z = getParameterFloat(nodeHandle_for_paramaters , "derivativegain_for_z");
+
+	// > the proportional gain for z control
+	yaml_ki_z = getParameterFloat(nodeHandle_for_paramaters , "integralgain_for_z");
+
 	// > The mass of the crazyflie
 	yaml_cf_mass_in_grams = getParameterFloat(nodeHandle_for_paramaters , "mass");
 
@@ -826,13 +851,9 @@ void fetchStudentControllerYamlParameters(ros::NodeHandle& nodeHandle)
 	//   by the frequency at which the Vicon system provides position and attitude data
 	yaml_control_frequency = getParameterFloat(nodeHandle_for_paramaters, "control_frequency");
 
-	// > The co-efficients of the quadratic conversation from 16-bit motor command to
-	//   thrust force in Newtons
-	getParameterFloatVector(nodeHandle_for_paramaters, "motorPoly", yaml_motorPoly, 3);
-
 	// The default setpoint, the ordering is (x,y,z,yaw),
 	// with unit [meters,meters,meters,radians]
-	getParameterFloatVector(nodeHandle_for_paramaters, "default_setpoint", yaml_default_setpoint, 4);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "default_setpoint", yaml_default_setpoint, 4);
 
 
 
@@ -959,10 +980,6 @@ int main(int argc, char* argv[]) {
 
 	// > the mass of the crazyflie, in [grams]
 	yaml_cf_mass_in_grams = 25.0;
-	// > the coefficients of the 16-bit command to thrust conversion
-	yaml_motorPoly[0] = 5.484560e-4;
-	yaml_motorPoly[1] = 1.032633e-6;
-	yaml_motorPoly[2] = 2.130295e-11;
 	// > the frequency at which the controller is running
 	yaml_control_frequency = 200.0;
 	// > the default setpoint, the ordering is (x,y,z,yaw),
@@ -1066,6 +1083,8 @@ int main(int argc, char* argv[]) {
 	// And now we can instantiate the subscriber:
 	ros::Subscriber customCommandReceivedSubscriber_from_coord = nodeHandle_to_coordinator.subscribe("StudentControllerService/CustomButtonPressed", 1, customCommandReceivedCallback);
 
+	
+
 
 
     // Print out some information to the user.
diff --git a/dfall_ws/src/dfall_pkg/src/nodes/TemplateControllerService.cpp b/dfall_ws/src/dfall_pkg/src/nodes/TemplateControllerService.cpp
index 535d907c1d650d29a80ffa3b49beb4acc32be1f6..d92fa49846c30566517721edbeac77aacee71819 100644
--- a/dfall_ws/src/dfall_pkg/src/nodes/TemplateControllerService.cpp
+++ b/dfall_ws/src/dfall_pkg/src/nodes/TemplateControllerService.cpp
@@ -82,23 +82,23 @@
 // following two properties:
 //
 // >> request.ownCrazyflie
-// This property is itself a structure of type "CrazyflieData",  which is
-// defined in the file "CrazyflieData.msg", and has the following properties
-// string crazyflieName
+// This property is itself a structure of type "FlyingVehicleState",  which is
+// defined in the file "FlyingVehicleState.msg", and has the following properties
+//     string vehicleName
 //     float64 x                         The x position of the Crazyflie [metres]
 //     float64 y                         The y position of the Crazyflie [metres]
 //     float64 z                         The z position of the Crazyflie [metres]
 //     float64 roll                      The roll component of the intrinsic Euler angles [radians]
 //     float64 pitch                     The pitch component of the intrinsic Euler angles [radians]
 //     float64 yaw                       The yaw component of the intrinsic Euler angles [radians]
-//     float64 acquiringTime #delta t    The time elapsed since the previous "CrazyflieData" was received [seconds]
-//     bool occluded                     A boolean indicted whether the Crazyflie for visible at the time of this measurement
+//     float64 acquiringTime #delta t    The time elapsed since the previous "FlyingVehicleState" was received [seconds]
+//     bool isValid                      A boolean indicted whether the Crazyflie for visible at the time of this measurement
 // The values in these properties are directly the measurement taken by the
 // motion capture system of the Crazyflie that is to be controlled by this
 // service.
 //
 // >> request.otherCrazyflies
-// This property is an array of "CrazyflieData" structures, what allows access
+// This property is an array of "FlyingVehicleState" structures, what allows access
 // to the motion capture measurements of other Crazyflies.
 //
 // The argument "response" is a structure that is expected to be filled in by
@@ -107,39 +107,52 @@
 // >> response.ControlCommand
 // This property is iteself a structure of type "ControlCommand", which is
 // defined in the file "ControlCommand.msg", and has the following properties:
-//     float32 roll                      The command sent to the Crazyflie for the body frame x-axis
-//     float32 pitch                     The command sent to the Crazyflie for the body frame y-axis
-//     float32 yaw                       The command sent to the Crazyflie for the body frame z-axis
-//     uint16 motorCmd1                  The command sent to the Crazyflie for motor 1
-//     uint16 motorCmd2                  The command sent to the Crazyflie for motor 1
-//     uint16 motorCmd3                  The command sent to the Crazyflie for motor 1
-//     uint16 motorCmd4                  The command sent to the Crazyflie for motor 1
-//     uint8 onboardControllerType       The flag sent to the Crazyflie for indicating how to implement the command
+//     uint16 motorCmd1                 The command sent to the Crazyflie for motor 1
+//     uint16 motorCmd2                 ... same for motor 2
+//     uint16 motorCmd3                 ... same for motor 3
+//     uint16 motorCmd4                 ... same for motor 4
+//     uint8 xControllerMode            The mode sent to the Crazyflie for what controller to run for the body frame x-axis
+//     uint8 yControllerMode            ... same body frame y-axis
+//     uint8 zControllerMode            ... same body frame z-axis
+//     uint8 yawControllerMode          ... same body frame yaw
+//     float32 xControllerSetpoint      The setpoint sent to the Crazyflie for the body frame x-axis controller
+//     float32 yControllerSetpoint      ... same body frame y-axis
+//     float32 zControllerSetpoint      ... same body frame z-axis
+//     float32 yawControllerSetpoint    ... same body frame yaw
 // 
-// IMPORTANT NOTES FOR "onboardControllerType"  AND AXIS CONVENTIONS
-// > The allowed values for "onboardControllerType" are in the "Defines"
-//   section in the header file, they are:
-//   - CF_COMMAND_TYPE_MOTORS
-//   - CF_COMMAND_TYPE_RATE
-//   - CF_COMMAND_TYPE_ANGLE
+// IMPORTANT NOTES FOR "{x,y,z,yaw}ControllerMode"  AND AXIS CONVENTIONS
+// > The allowed values for "{x,y,z,yaw}ControllerMode" are in the
+//   "Constants.h" header file, they are:
+//   - CF_ONBOARD_CONTROLLER_MODE_OFF
+//   - CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE
+//   - CF_ONBOARD_CONTROLLER_MODE_ANGLE
+//   - CF_ONBOARD_CONTROLLER_MODE_VELOCITY
+//   - CF_ONBOARD_CONTROLLER_MODE_POSITION
 //
-// > For most common option to use is CF_COMMAND_TYPE_RATE option.
+// > The most common option to use for the {x,y,yaw} controller is
+//   the CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE option.
 //
-// > For the CF_COMMAND_TYPE_RATE optoin:
-//   1) the ".roll", ".ptich", and ".yaw" properties of
-//      "response.ControlCommand" specify the angular rate in
-//      [radians/second] that will be requested from the PID controllers
-//      running in the Crazyflie 2.0 firmware.
-//   2) the ".motorCmd1" to ".motorCmd4" properties of
+// > The most common option to use for the {z} controller is
+//   the CF_ONBOARD_CONTROLLER_MODE_OFF option, and thus the
+//   body frame z-axis is controlled by the motorCmd{1,2,3,4}
+//   values that you set.
+//
+// > When the CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE is selected, then:
+//   1) the ".xControllerSetpoint", ".yControllerSetpoint", and
+//      ".yawControllerSetpoint" properties of "response.ControlCommand"
+//      specify the angular rate in [radians/second] that will be requested
+//      from the PID controllers running in the Crazyflie 2.0 firmware.
+//   2) the axis convention for the roll, pitch, and yaw body rates,
+//      i.e., as set in the {y,x,yaw}ControllerSetpoint properties of
+//      the "response.ControlCommand" that you return, is a right-hand
+//      coordinate axes with x-forward and z-upwards (i.e., the positive
+//      z-axis is aligned with the direction of positive thrust). To
+//      assist, the ASCII art below depicts this convention.
+//   3) the ".motorCmd1" to ".motorCmd4" properties of
 //      "response.ControlCommand" are the baseline motor commands
 //      requested from the Crazyflie, with the adjustment for body rates
 //      being added on top of this in the firmware (i.e., as per the
 //      code of the "distribute_power" found in the firmware).
-//   3) the axis convention for the roll, pitch, and yaw body rates
-//      returned in "response.ControlCommand" should use right-hand
-//      coordinate axes with x-forward and z-upwards (i.e., the positive
-//      z-axis is aligned with the direction of positive thrust). To
-//      assist, the following is an ASCII art of this convention.
 //
 // ASCII ART OF THE CRAZYFLIE 2.0 LAYOUT
 //
@@ -263,17 +276,23 @@ bool calculateControlOutput(Controller::Request &request, Controller::Response &
 		yawRate_forResponse -= yaml_gainMatrixYawRate[i] * stateErrorBody[i];
 	}
 
-	// Put the computed body rate commands into the "response" variable
-	response.controlOutput.roll = rollRate_forResponse;
-	response.controlOutput.pitch = pitchRate_forResponse;
-	response.controlOutput.yaw = yawRate_forResponse;
-
-	// Put the thrust commands into the "response" variable.
-	// The thrust adjustment computed by the controller need to be added to the
-	// the feed-forward thrust that "counter-acts" gravity.
-	// > NOTE: remember that the thrust is commanded per motor, so you sohuld
-	//         consider whether the "thrustAdjustment" computed by your
-	//         controller needed to be divided by 4 or not.
+	// Specify the mode of each controller
+	response.controlOutput.xControllerMode   = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+	response.controlOutput.yControllerMode   = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+	response.controlOutput.zControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+	response.controlOutput.yawControllerMode = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+
+	// Put the computed rates into the "response" variable
+	// > For roll, pitch, and yaw:
+	response.controlOutput.xControllerSetpoint   = pitchRate_forResponse;
+	response.controlOutput.yControllerSetpoint   = rollRate_forResponse;
+	response.controlOutput.zControllerSetpoint   = 0.0;
+	response.controlOutput.yawControllerSetpoint = yawRate_forResponse;
+
+	// Put the computed thrust into the "response" variable
+	// > On top of the thrust adjustment, we must add the feed-forward thrust to counter-act gravity.
+	// > NOTE: remember that the thrust is commanded per motor, hence divide
+	//         the thrusts by 4.
 	// > NOTE: the "m_cf_weight_in_newtons" value is the total thrust required
 	//         as feed-forward. Assuming the the Crazyflie is symmetric, this
 	//         value is divided by four.
@@ -286,16 +305,6 @@ bool calculateControlOutput(Controller::Request &request, Controller::Response &
 	response.controlOutput.motorCmd3 = computeMotorPolyBackward(thrust_request_per_motor);
 	response.controlOutput.motorCmd4 = computeMotorPolyBackward(thrust_request_per_motor);
 
-	
-	// PREPARE AND RETURN THE VARIABLE "response"
-
-	// Choose the controller type use on-board the Crazyflie,
-	// it can be either be Motor, Rate, or Angle based
-	// response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_MOTORS;
-	response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_RATE;
-	// response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_ANGLE;
-
-
 
 
 	if (yaml_shouldPublishDebugMessage)
@@ -363,20 +372,15 @@ bool calculateControlOutput(Controller::Request &request, Controller::Response &
 
 		// An example of "printing out" the control actions computed.
 		ROS_INFO_STREAM("thrustAdjustment = " << thrustAdjustment);
-		ROS_INFO_STREAM("controlOutput.roll = " << response.controlOutput.roll);
-		ROS_INFO_STREAM("controlOutput.pitch = " << response.controlOutput.pitch);
-		ROS_INFO_STREAM("controlOutput.yaw = " << response.controlOutput.yaw);
+		ROS_INFO_STREAM("controlOutput.xControllerSetpoint   = " << response.controlOutput.xControllerSetpoint);
+		ROS_INFO_STREAM("controlOutput.yControllerSetpoint   = " << response.controlOutput.yControllerSetpoint);
+		ROS_INFO_STREAM("controlOutput.yawControllerSetpoint = " << response.controlOutput.yawControllerSetpoint);
 
 		// An example of "printing out" the per motor 16-bit command computed.
 		ROS_INFO_STREAM("controlOutput.cmd1 = " << response.controlOutput.motorCmd1);
 		ROS_INFO_STREAM("controlOutput.cmd3 = " << response.controlOutput.motorCmd2);
 		ROS_INFO_STREAM("controlOutput.cmd2 = " << response.controlOutput.motorCmd3);
 		ROS_INFO_STREAM("controlOutput.cmd4 = " << response.controlOutput.motorCmd4);
-
-		// An example of "printing out" the "thrust-to-command" conversion parameters.
-		// ROS_INFO_STREAM("motorPoly 0:" << yaml_motorPoly[0]);
-		// ROS_INFO_STREAM("motorPoly 1:" << yaml_motorPoly[1]);
-		// ROS_INFO_STREAM("motorPoly 2:" << yaml_motorPoly[2]);
 	}
 
 	// Return "true" to indicate that the control computation was
@@ -765,7 +769,7 @@ void fetchTemplateControllerYamlParameters(ros::NodeHandle& nodeHandle)
 
 	// > The co-efficients of the quadratic conversation from 16-bit motor
 	//   command to thrust force in Newtons
-	getParameterFloatVector(nodeHandle_for_paramaters, "motorPoly", yaml_motorPoly, 3);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "motorPoly", yaml_motorPoly, 3);
 
 	// > The min and max for saturating 16 bit thrust commands
 	yaml_command_sixteenbit_min = getParameterFloat(nodeHandle_for_paramaters, "command_sixteenbit_min");
@@ -773,7 +777,7 @@ void fetchTemplateControllerYamlParameters(ros::NodeHandle& nodeHandle)
 
 	// The default setpoint, the ordering is (x,y,z,yaw),
 	// with unit [meters,meters,meters,radians]
-	getParameterFloatVector(nodeHandle_for_paramaters, "default_setpoint", yaml_default_setpoint, 4);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "default_setpoint", yaml_default_setpoint, 4);
 
 	// Boolean indiciating whether the "Debug Message" of this agent
 	// should be published or not
@@ -785,10 +789,10 @@ void fetchTemplateControllerYamlParameters(ros::NodeHandle& nodeHandle)
 
 	// The LQR Controller parameters
 	// The LQR Controller parameters for "LQR_MODE_RATE"
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixThrust_NineStateVector", yaml_gainMatrixThrust_NineStateVector, 9);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixRollRate",               yaml_gainMatrixRollRate,               9);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixPitchRate",              yaml_gainMatrixPitchRate,              9);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixYawRate",                yaml_gainMatrixYawRate,                9);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixThrust_NineStateVector", yaml_gainMatrixThrust_NineStateVector, 9);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixRollRate",               yaml_gainMatrixRollRate,               9);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixPitchRate",              yaml_gainMatrixPitchRate,              9);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixYawRate",                yaml_gainMatrixYawRate,                9);
 
 	// > DEBUGGING: Print out one of the parameters that was loaded to
 	//   debug if the fetching of parameters worked correctly
diff --git a/dfall_ws/src/dfall_pkg/src/nodes/TestMotorsControllerService.cpp b/dfall_ws/src/dfall_pkg/src/nodes/TestMotorsControllerService.cpp
index 9dafb62fcc64fa75f58917cc8ef22c9c25556519..92c5b4a5bf42bdee7bd05955b995cdc3d0620c05 100644
--- a/dfall_ws/src/dfall_pkg/src/nodes/TestMotorsControllerService.cpp
+++ b/dfall_ws/src/dfall_pkg/src/nodes/TestMotorsControllerService.cpp
@@ -73,7 +73,7 @@
 //     CCCC   OOO   N   N    T    R   R   OOO   LLLLL       LLLLL   OOO    OOO   P
 //    ----------------------------------------------------------------------------------
 
-// This function is the callback that is linked to the "TemplateController"
+// This function is the callback that is linked to the "TestMotorsController"
 // service that is advertised in the main function. This must have arguments
 // that match the "input-output" behaviour defined in the "Controller.srv"
 // file (located in the "srv" folder)
@@ -82,23 +82,23 @@
 // following two properties:
 //
 // >> request.ownCrazyflie
-// This property is itself a structure of type "CrazyflieData",  which is
-// defined in the file "CrazyflieData.msg", and has the following properties
-// string crazyflieName
+// This property is itself a structure of type "FlyingVehicleState",  which is
+// defined in the file "FlyingVehicleState.msg", and has the following properties
+//     string vehicleName
 //     float64 x                         The x position of the Crazyflie [metres]
 //     float64 y                         The y position of the Crazyflie [metres]
 //     float64 z                         The z position of the Crazyflie [metres]
 //     float64 roll                      The roll component of the intrinsic Euler angles [radians]
 //     float64 pitch                     The pitch component of the intrinsic Euler angles [radians]
 //     float64 yaw                       The yaw component of the intrinsic Euler angles [radians]
-//     float64 acquiringTime #delta t    The time elapsed since the previous "CrazyflieData" was received [seconds]
-//     bool occluded                     A boolean indicted whether the Crazyflie for visible at the time of this measurement
+//     float64 acquiringTime #delta t    The time elapsed since the previous "FlyingVehicleState" was received [seconds]
+//     bool isValid                      A boolean indicted whether the Crazyflie for visible at the time of this measurement
 // The values in these properties are directly the measurement taken by the
 // motion capture system of the Crazyflie that is to be controlled by this
 // service.
 //
 // >> request.otherCrazyflies
-// This property is an array of "CrazyflieData" structures, what allows access
+// This property is an array of "FlyingVehicleState" structures, what allows access
 // to the motion capture measurements of other Crazyflies.
 //
 // The argument "response" is a structure that is expected to be filled in by
@@ -107,39 +107,52 @@
 // >> response.ControlCommand
 // This property is iteself a structure of type "ControlCommand", which is
 // defined in the file "ControlCommand.msg", and has the following properties:
-//     float32 roll                      The command sent to the Crazyflie for the body frame x-axis
-//     float32 pitch                     The command sent to the Crazyflie for the body frame y-axis
-//     float32 yaw                       The command sent to the Crazyflie for the body frame z-axis
-//     uint16 motorCmd1                  The command sent to the Crazyflie for motor 1
-//     uint16 motorCmd2                  The command sent to the Crazyflie for motor 1
-//     uint16 motorCmd3                  The command sent to the Crazyflie for motor 1
-//     uint16 motorCmd4                  The command sent to the Crazyflie for motor 1
-//     uint8 onboardControllerType       The flag sent to the Crazyflie for indicating how to implement the command
+//     uint16 motorCmd1                 The command sent to the Crazyflie for motor 1
+//     uint16 motorCmd2                 ... same for motor 2
+//     uint16 motorCmd3                 ... same for motor 3
+//     uint16 motorCmd4                 ... same for motor 4
+//     uint8 xControllerMode            The mode sent to the Crazyflie for what controller to run for the body frame x-axis
+//     uint8 yControllerMode            ... same body frame y-axis
+//     uint8 zControllerMode            ... same body frame z-axis
+//     uint8 yawControllerMode          ... same body frame yaw
+//     float32 xControllerSetpoint      The setpoint sent to the Crazyflie for the body frame x-axis controller
+//     float32 yControllerSetpoint      ... same body frame y-axis
+//     float32 zControllerSetpoint      ... same body frame z-axis
+//     float32 yawControllerSetpoint    ... same body frame yaw
 // 
-// IMPORTANT NOTES FOR "onboardControllerType"  AND AXIS CONVENTIONS
-// > The allowed values for "onboardControllerType" are in the "Defines"
-//   section in the header file, they are:
-//   - CF_COMMAND_TYPE_MOTORS
-//   - CF_COMMAND_TYPE_RATE
-//   - CF_COMMAND_TYPE_ANGLE
+// IMPORTANT NOTES FOR "{x,y,z,yaw}ControllerMode"  AND AXIS CONVENTIONS
+// > The allowed values for "{x,y,z,yaw}ControllerMode" are in the
+//   "Constants.h" header file, they are:
+//   - CF_ONBOARD_CONTROLLER_MODE_OFF
+//   - CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE
+//   - CF_ONBOARD_CONTROLLER_MODE_ANGLE
+//   - CF_ONBOARD_CONTROLLER_MODE_VELOCITY
+//   - CF_ONBOARD_CONTROLLER_MODE_POSITION
 //
-// > For most common option to use is CF_COMMAND_TYPE_RATE option.
+// > The most common option to use for the {x,y,yaw} controller is
+//   the CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE option.
 //
-// > For the CF_COMMAND_TYPE_RATE optoin:
-//   1) the ".roll", ".ptich", and ".yaw" properties of
-//      "response.ControlCommand" specify the angular rate in
-//      [radians/second] that will be requested from the PID controllers
-//      running in the Crazyflie 2.0 firmware.
-//   2) the ".motorCmd1" to ".motorCmd4" properties of
+// > The most common option to use for the {z} controller is
+//   the CF_ONBOARD_CONTROLLER_MODE_OFF option, and thus the
+//   body frame z-axis is controlled by the motorCmd{1,2,3,4}
+//   values that you set.
+//
+// > When the CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE is selected, then:
+//   1) the ".xControllerSetpoint", ".yControllerSetpoint", and
+//      ".yawControllerSetpoint" properties of "response.ControlCommand"
+//      specify the angular rate in [radians/second] that will be requested
+//      from the PID controllers running in the Crazyflie 2.0 firmware.
+//   2) the axis convention for the roll, pitch, and yaw body rates,
+//      i.e., as set in the {y,x,yaw}ControllerSetpoint properties of
+//      the "response.ControlCommand" that you return, is a right-hand
+//      coordinate axes with x-forward and z-upwards (i.e., the positive
+//      z-axis is aligned with the direction of positive thrust). To
+//      assist, the ASCII art below depicts this convention.
+//   3) the ".motorCmd1" to ".motorCmd4" properties of
 //      "response.ControlCommand" are the baseline motor commands
 //      requested from the Crazyflie, with the adjustment for body rates
 //      being added on top of this in the firmware (i.e., as per the
 //      code of the "distribute_power" found in the firmware).
-//   3) the axis convention for the roll, pitch, and yaw body rates
-//      returned in "response.ControlCommand" should use right-hand
-//      coordinate axes with x-forward and z-upwards (i.e., the positive
-//      z-axis is aligned with the direction of positive thrust). To
-//      assist, the following is an ASCII art of this convention.
 //
 // ASCII ART OF THE CRAZYFLIE 2.0 LAYOUT
 //
@@ -181,16 +194,25 @@ bool calculateControlOutput(Controller::Request &request, Controller::Response &
 	// computation here, or you may find it convienient to create functions
 	// to keep you code cleaner
 
+	// Initialise a static variable for counting time "ticks"
 	static int ticks = 0;
 
-
+	// Increment the time counter every time this function is called
 	ticks++;
 
+	// Specify that all controllers are disabled
+	response.controlOutput.xControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+	response.controlOutput.yControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+	response.controlOutput.zControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+	response.controlOutput.yawControllerMode = CF_ONBOARD_CONTROLLER_MODE_OFF;
 
-	response.controlOutput.roll = 0.0f;
-	response.controlOutput.pitch = 0.0f;
-	response.controlOutput.yaw = 0.0f;
+	// Fill in zero for the controller setpoints
+	response.controlOutput.xControllerSetpoint   = 0.0;
+	response.controlOutput.yControllerSetpoint   = 0.0;
+	response.controlOutput.zControllerSetpoint   = 0.0;
+	response.controlOutput.yawControllerSetpoint = 0.0;
 
+	// Fill in all motor thrusts as zero
 	response.controlOutput.motorCmd1 = 0;
 	response.controlOutput.motorCmd2 = 0;
 	response.controlOutput.motorCmd3 = 0;
@@ -212,14 +234,6 @@ bool calculateControlOutput(Controller::Request &request, Controller::Response &
 	}
 
 
-	// PREPARE AND RETURN THE VARIABLE "response"
-
-	// Choose the controller type use on-board the Crazyflie,
-	// it can be either be Motor, Rate, or Angle based
-	response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_MOTORS;
-	// response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_RATE;
-	// response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_ANGLE;
-
 
 	// Return "true" to indicate that the control computation was
 	// performed successfully
@@ -229,396 +243,6 @@ bool calculateControlOutput(Controller::Request &request, Controller::Response &
 
 
 
-//    ------------------------------------------------------------------------------
-//    RRRR    OOO   TTTTT    A    TTTTT  EEEEE       III  N   N  TTTTT   OOO
-//    R   R  O   O    T     A A     T    E            I   NN  N    T    O   O
-//    RRRR   O   O    T    A   A    T    EEE          I   N N N    T    O   O
-//    R  R   O   O    T    AAAAA    T    E            I   N  NN    T    O   O
-//    R   R   OOO     T    A   A    T    EEEEE       III  N   N    T     OOO
-//
-//    BBBB    OOO   DDDD   Y   Y       FFFFF  RRRR     A    M   M  EEEEE
-//    B   B  O   O  D   D   Y Y        F      R   R   A A   MM MM  E
-//    BBBB   O   O  D   D    Y         FFF    RRRR   A   A  M M M  EEE
-//    B   B  O   O  D   D    Y         F      R  R   AAAAA  M   M  E
-//    BBBB    OOO   DDDD     Y         F      R   R  A   A  M   M  EEEEE
-//    ----------------------------------------------------------------------------------
-
-// The arguments for this function are as follows:
-// stateInertial
-// This is an array of length 9 with the estimates the error of of the following values
-// relative to the sepcifed setpoint:
-//     stateInertial[0]    x position of the Crazyflie relative to the inertial frame origin [meters]
-//     stateInertial[1]    y position of the Crazyflie relative to the inertial frame origin [meters]
-//     stateInertial[2]    z position of the Crazyflie relative to the inertial frame origin [meters]
-//     stateInertial[3]    x-axis component of the velocity of the Crazyflie in the inertial frame [meters/second]
-//     stateInertial[4]    y-axis component of the velocity of the Crazyflie in the inertial frame [meters/second]
-//     stateInertial[5]    z-axis component of the velocity of the Crazyflie in the inertial frame [meters/second]
-//     stateInertial[6]    The roll  component of the intrinsic Euler angles [radians]
-//     stateInertial[7]    The pitch component of the intrinsic Euler angles [radians]
-//     stateInertial[8]    The yaw   component of the intrinsic Euler angles [radians]
-// 
-// stateBody
-// This is an empty array of length 9, this function should fill in all elements of this
-// array with the same ordering as for the "stateInertial" argument, expect that the (x,y)
-// position and (x,y) velocities are rotated into the body frame.
-//
-// yaw_measured
-// This is the yaw component of the intrinsic Euler angles in [radians] as measured by
-// the Vicon motion capture system
-//
-void convertIntoBodyFrame(float stateInertial[9], float (&stateBody)[9], float yaw_measured)
-{
-	float sinYaw = sin(yaw_measured);
-	float cosYaw = cos(yaw_measured);
-
-	// Fill in the (x,y,z) position estimates to be returned
-	stateBody[0] = stateInertial[0] * cosYaw  +  stateInertial[1] * sinYaw;
-	stateBody[1] = stateInertial[1] * cosYaw  -  stateInertial[0] * sinYaw;
-	stateBody[2] = stateInertial[2];
-
-	// Fill in the (x,y,z) velocity estimates to be returned
-	stateBody[3] = stateInertial[3] * cosYaw  +  stateInertial[4] * sinYaw;
-	stateBody[4] = stateInertial[4] * cosYaw  -  stateInertial[3] * sinYaw;
-	stateBody[5] = stateInertial[5];
-
-	// Fill in the (roll,pitch,yaw) estimates to be returned
-	stateBody[6] = stateInertial[6];
-	stateBody[7] = stateInertial[7];
-	stateBody[8] = stateInertial[8];
-}
-
-
-
-
-
-//    ------------------------------------------------------------------------------
-//    N   N  EEEEE  W     W   TTTTT   OOO   N   N        CCCC  M   M  DDDD
-//    NN  N  E      W     W     T    O   O  NN  N       C      MM MM  D   D
-//    N N N  EEE    W     W     T    O   O  N N N  -->  C      M M M  D   D
-//    N  NN  E       W W W      T    O   O  N  NN       C      M   M  D   D
-//    N   N  EEEEE    W W       T     OOO   N   N        CCCC  M   M  DDDD
-//
-//     CCCC   OOO   N   N  V   V  EEEEE  RRRR    SSSS  III   OOO   N   N
-//    C      O   O  NN  N  V   V  E      R   R  S       I   O   O  NN  N
-//    C      O   O  N N N  V   V  EEE    RRRR    SSS    I   O   O  N N N
-//    C      O   O  N  NN   V V   E      R  R       S   I   O   O  N  NN
-//     CCCC   OOO   N   N    V    EEEEE  R   R  SSSS   III   OOO   N   N
-//    ----------------------------------------------------------------------------------
-
-float computeMotorPolyBackward(float thrust)
-{
-	// Compute the 16-but command that would produce the requested
-	// "thrust" based on the quadratic mapping that is described
-	// by the coefficients in the "yaml_motorPoly" variable.
-	float cmd_16bit = (-yaml_motorPoly[1] + sqrt(yaml_motorPoly[1] * yaml_motorPoly[1] - 4 * yaml_motorPoly[2] * (yaml_motorPoly[0] - thrust))) / (2 * yaml_motorPoly[2]);
-
-	// Saturate the signal to be 0 or in the range [1000,65000]
-	if (cmd_16bit < yaml_command_sixteenbit_min)
-	{
-		cmd_16bit = 0;
-	}
-	else if (cmd_16bit > yaml_command_sixteenbit_max)
-	{
-		cmd_16bit = yaml_command_sixteenbit_max;
-	}
-	// Return the result
-	return cmd_16bit;
-}
-
-
-
-
-
-//    ----------------------------------------------------------------------------------
-//    N   N  EEEEE  W     W        SSSS  EEEEE  TTTTT  PPPP    OOO   III  N   N  TTTTT
-//    NN  N  E      W     W       S      E        T    P   P  O   O   I   NN  N    T
-//    N N N  EEE    W     W        SSS   EEE      T    PPPP   O   O   I   N N N    T
-//    N  NN  E       W W W            S  E        T    P      O   O   I   N  NN    T
-//    N   N  EEEEE    W W         SSSS   EEEEE    T    P       OOO   III  N   N    T
-//
-//     CCCC    A    L      L      BBBB     A     CCCC  K   K
-//    C       A A   L      L      B   B   A A   C      K  K
-//    C      A   A  L      L      BBBB   A   A  C      KKK
-//    C      AAAAA  L      L      B   B  AAAAA  C      K  K
-//     CCCC  A   A  LLLLL  LLLLL  BBBB   A   A   CCCC  K   K
-//    ----------------------------------------------------------------------------------
-
-
-// REQUEST SETPOINT CHANGE CALLBACK
-void requestSetpointChangeCallback(const SetpointWithHeader& newSetpoint)
-{
-	// Check whether the message is relevant
-	bool isRevelant = checkMessageHeader( m_agentID , newSetpoint.shouldCheckForAgentID , newSetpoint.agentIDs );
-
-	// Continue if the message is relevant
-	if (isRevelant)
-	{
-		// Check if the request if for the default setpoint
-		if (newSetpoint.buttonID == REQUEST_DEFAULT_SETPOINT_BUTTON_ID)
-		{
-			setNewSetpoint(
-					yaml_default_setpoint[0],
-					yaml_default_setpoint[1],
-					yaml_default_setpoint[2],
-					yaml_default_setpoint[3]
-				);
-		}
-		else
-		{
-			// Call the function for actually setting the setpoint
-			setNewSetpoint(
-					newSetpoint.x,
-					newSetpoint.y,
-					newSetpoint.z,
-					newSetpoint.yaw
-				);
-		}
-	}
-}
-
-
-// CHANGE SETPOINT FUNCTION
-void setNewSetpoint(float x, float y, float z, float yaw)
-{
-	// Put the new setpoint into the class variable
-	m_setpoint[0] = x;
-	m_setpoint[1] = y;
-	m_setpoint[2] = z;
-	m_setpoint[3] = yaw;
-
-	// Publish the change so that the network is updated
-	// (mainly the "flying agent GUI" is interested in
-	// displaying this change to the user)
-
-	// Instantiate a local variable of type "SetpointWithHeader"
-	SetpointWithHeader msg;
-	// Fill in the setpoint
-	msg.x   = x;
-	msg.y   = y;
-	msg.z   = z;
-	msg.yaw = yaw;
-	// Publish the message
-	m_setpointChangedPublisher.publish(msg);
-}
-
-
-// GET CURRENT SETPOINT SERVICE CALLBACK
-bool getCurrentSetpointCallback(GetSetpointService::Request &request, GetSetpointService::Response &response)
-{
-	// Directly put the current setpoint into the response
-	response.setpointWithHeader.x   = m_setpoint[0];
-	response.setpointWithHeader.y   = m_setpoint[1];
-	response.setpointWithHeader.z   = m_setpoint[2];
-	response.setpointWithHeader.yaw = m_setpoint[3];
-	// Return
-	return true;
-}
-
-
-
-
-
-//    ----------------------------------------------------------------------------------
-//     CCCC  U   U   SSSS  TTTTT   OOO   M   M
-//    C      U   U  S        T    O   O  MM MM
-//    C      U   U   SSS     T    O   O  M M M
-//    C      U   U      S    T    O   O  M   M
-//     CCCC   UUU   SSSS     T     OOO   M   M
-//
-//     CCCC   OOO   M   M  M   M    A    N   N  DDDD
-//    C      O   O  MM MM  MM MM   A A   NN  N  D   D
-//    C      O   O  M M M  M M M  A   A  N N N  D   D
-//    C      O   O  M   M  M   M  AAAAA  N  NN  D   D
-//     CCCC   OOO   M   M  M   M  A   A  N   N  DDDD
-//    ----------------------------------------------------------------------------------
-
-// CUSTOM COMMAND RECEIVED CALLBACK
-void customCommandReceivedCallback(const CustomButtonWithHeader& commandReceived)
-{
-	// Check whether the message is relevant
-	bool isRevelant = checkMessageHeader( m_agentID , commandReceived.shouldCheckForAgentID , commandReceived.agentIDs );
-
-	if (isRevelant)
-	{
-		// Extract the data from the message
-		int custom_button_index = commandReceived.button_index;
-		float float_data        = commandReceived.float_data;
-		//std::string string_data = commandReceived.string_data;
-
-		// Switch between the button pressed
-		switch(custom_button_index)
-		{
-
-			// > FOR CUSTOM BUTTON 1
-			case 1:
-			{
-				// Let the user know that this part of the code was triggered
-				ROS_INFO_STREAM("[TEMPLATE CONTROLLER] Button 1 received in controller, with message.float_data = " << float_data );
-				// Code here to respond to custom button 1
-				
-				break;
-			}
-
-			// > FOR CUSTOM BUTTON 2
-			case 2:
-			{
-				// Let the user know that this part of the code was triggered
-				ROS_INFO_STREAM("[TEMPLATE CONTROLLER] Button 2 received in controller, with message.float_data = " << float_data );
-				// Code here to respond to custom button 2
-
-				break;
-			}
-
-			// > FOR CUSTOM BUTTON 3
-			case 3:
-			{
-				// Let the user know that this part of the code was triggered
-				ROS_INFO_STREAM("[TEMPLATE CONTROLLER] Button 3 received in controller, with message.float_data = " << float_data );
-				// Code here to respond to custom button 3
-
-				break;
-			}
-
-			default:
-			{
-				// Let the user know that the command was not recognised
-				ROS_INFO_STREAM("[TEMPLATE CONTROLLER] A button clicked command was received in the controller but not recognised, message.button_index = " << custom_button_index << ", and message.float_data = " << float_data );
-				break;
-			}
-		}
-	}
-}
-
-
-
-
-
-//    ----------------------------------------------------------------------------------
-//    L       OOO     A    DDDD
-//    L      O   O   A A   D   D
-//    L      O   O  A   A  D   D
-//    L      O   O  AAAAA  D   D
-//    LLLLL   OOO   A   A  DDDD
-//
-//    PPPP     A    RRRR     A    M   M  EEEEE  TTTTT  EEEEE  RRRR    SSSS
-//    P   P   A A   R   R   A A   MM MM  E        T    E      R   R  S
-//    PPPP   A   A  RRRR   A   A  M M M  EEE      T    EEE    RRRR    SSS
-//    P      AAAAA  R  R   AAAAA  M   M  E        T    E      R  R       S
-//    P      A   A  R   R  A   A  M   M  EEEEE    T    EEEEE  R   R  SSSS
-//    ----------------------------------------------------------------------------------
-
-
-// CALLBACK NOTIFYING THAT THE YAML PARAMETERS ARE READY TO BE LOADED
-void isReadyTemplateControllerYamlCallback(const IntWithHeader & msg)
-{
-	// Check whether the message is relevant
-	bool isRevelant = checkMessageHeader( m_agentID , msg.shouldCheckForAgentID , msg.agentIDs );
-
-	// Continue if the message is relevant
-	if (isRevelant)
-	{
-		// Extract the data
-		int parameter_service_to_load_from = msg.data;
-		// Initialise a local variable for the namespace
-		std::string namespace_to_use;
-		// Load from the respective parameter service
-		switch(parameter_service_to_load_from)
-		{
-			// > FOR FETCHING FROM THE AGENT'S OWN PARAMETER SERVICE
-			case LOAD_YAML_FROM_AGENT:
-			{
-				ROS_INFO("[TEMPLATE CONTROLLER] Now fetching the TemplateController YAML parameter values from this agent.");
-				namespace_to_use = m_namespace_to_own_agent_parameter_service;
-				break;
-			}
-			// > FOR FETCHING FROM THE COORDINATOR'S PARAMETER SERVICE
-			case LOAD_YAML_FROM_COORDINATOR:
-			{
-				ROS_INFO("[TEMPLATE CONTROLLER] Now fetching the TemplateController YAML parameter values from this agent's coordinator.");
-				namespace_to_use = m_namespace_to_coordinator_parameter_service;
-				break;
-			}
-
-			default:
-			{
-				ROS_ERROR("[TEMPLATE CONTROLLER] Paramter service to load from was NOT recognised.");
-				namespace_to_use = m_namespace_to_own_agent_parameter_service;
-				break;
-			}
-		}
-		// Create a node handle to the selected parameter service
-		ros::NodeHandle nodeHandle_to_use(namespace_to_use);
-		// Call the function that fetches the parameters
-		fetchTemplateControllerYamlParameters(nodeHandle_to_use);
-	}
-}
-
-
-// LOADING OF THE YAML PARAMTERS
-void fetchTemplateControllerYamlParameters(ros::NodeHandle& nodeHandle)
-{
-	// Here we load the parameters that are specified in the file:
-	// TemplateController.yaml
-
-	// Add the "TemplateController" namespace to the "nodeHandle"
-	ros::NodeHandle nodeHandle_for_paramaters(nodeHandle, "TemplateController");
-
-
-
-	// GET THE PARAMETERS:
-
-	// > The mass of the crazyflie
-	yaml_cf_mass_in_grams = getParameterFloat(nodeHandle_for_paramaters , "mass");
-
-	// > The frequency at which the "computeControlOutput" is being called,
-	//   as determined by the frequency at which the motion capture system
-	//   provides position and attitude data
-	yaml_control_frequency = getParameterFloat(nodeHandle_for_paramaters, "control_frequency");
-
-	// > The co-efficients of the quadratic conversation from 16-bit motor
-	//   command to thrust force in Newtons
-	getParameterFloatVector(nodeHandle_for_paramaters, "motorPoly", yaml_motorPoly, 3);
-
-	// > The min and max for saturating 16 bit thrust commands
-	yaml_command_sixteenbit_min = getParameterFloat(nodeHandle_for_paramaters, "command_sixteenbit_min");
-	yaml_command_sixteenbit_max = getParameterFloat(nodeHandle_for_paramaters, "command_sixteenbit_max");
-
-	// The default setpoint, the ordering is (x,y,z,yaw),
-	// with unit [meters,meters,meters,radians]
-	getParameterFloatVector(nodeHandle_for_paramaters, "default_setpoint", yaml_default_setpoint, 4);
-
-	// Boolean indiciating whether the "Debug Message" of this agent
-	// should be published or not
-	yaml_shouldPublishDebugMessage = getParameterBool(nodeHandle_for_paramaters, "shouldPublishDebugMessage");
-
-	// Boolean indiciating whether the debugging ROS_INFO_STREAM should
-	// be displayed or not
-	yaml_shouldDisplayDebugInfo = getParameterBool(nodeHandle_for_paramaters, "shouldDisplayDebugInfo");
-
-	// The LQR Controller parameters
-	// The LQR Controller parameters for "LQR_MODE_RATE"
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixThrust_NineStateVector", yaml_gainMatrixThrust_NineStateVector, 9);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixRollRate",               yaml_gainMatrixRollRate,               9);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixPitchRate",              yaml_gainMatrixPitchRate,              9);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixYawRate",                yaml_gainMatrixYawRate,                9);
-
-	// > DEBUGGING: Print out one of the parameters that was loaded to
-	//   debug if the fetching of parameters worked correctly
-	ROS_INFO_STREAM("[TEMPLATE CONTROLLER] DEBUGGING: the fetched TemplateController/mass = " << yaml_cf_mass_in_grams);
-
-
-
-	// PROCESS THE PARAMTERS
-
-	// > Compute the feed-forward force that we need to counteract
-	//   gravity (i.e., mg) in units of [Newtons]
-	m_cf_weight_in_newtons = yaml_cf_mass_in_grams * 9.81/1000.0;
-
-	// DEBUGGING: Print out one of the computed quantities
-	ROS_INFO_STREAM("[TEMPLATE CONTROLLER] DEBUGGING: thus the weight of this agent in [Newtons] = " << m_cf_weight_in_newtons);
-}
-
-
 
 
 
@@ -677,141 +301,10 @@ int main(int argc, char* argv[]) {
 
 
 
-	// PARAMETER SERVICE NAMESPACE AND NODEHANDLES:
-
-	// NOTES:
-	// > The parameters that are specified thorugh the *.yaml files
-	//   are managed by a separate node called the "Parameter Service"
-	// > A separate node is used for reasons of speed and generality
-	// > To allow for a distirbuted architecture, there are two
-	//   "ParamterService" nodes that are relevant:
-	//   1) the one that is nested under the "m_agentID" namespace
-	//   2) the one that is nested under the "m_coordID" namespace
-	// > The following lines of code create the namespace (as strings)
-	//   to there two relevant "ParameterService" nodes.
-	// > The node handles are also created because they are needed
-	//   for the ROS Subscriptions that follow.
-
-	// Set the class variable "m_namespace_to_own_agent_parameter_service",
-	// i.e., the namespace of parameter service for this agent
-	m_namespace_to_own_agent_parameter_service = m_namespace + "/ParameterService";
-
-	// Set the class variable "m_namespace_to_coordinator_parameter_service",
-	// i.e., the namespace of parameter service for this agent's coordinator
-	constructNamespaceForCoordinatorParameterService( m_coordID, m_namespace_to_coordinator_parameter_service );
-
-	// Inform the user of what namespaces are being used
-	ROS_INFO_STREAM("[TEST MOTORS CONTROLLER] m_namespace_to_own_agent_parameter_service    =  " << m_namespace_to_own_agent_parameter_service);
-	ROS_INFO_STREAM("[TEST MOTORS CONTROLLER] m_namespace_to_coordinator_parameter_service  =  " << m_namespace_to_coordinator_parameter_service);
-
-	// Create, as local variables, node handles to the parameters services
-	ros::NodeHandle nodeHandle_to_own_agent_parameter_service(m_namespace_to_own_agent_parameter_service);
-	ros::NodeHandle nodeHandle_to_coordinator_parameter_service(m_namespace_to_coordinator_parameter_service);
-
-
-
-	// SUBSCRIBE TO "YAML PARAMTERS READY" MESSAGES
-
-	// The parameter service publishes messages with names of the form:
-	// /dfall/.../ParameterService/<filename with .yaml extension>
-	ros::Subscriber safeContoller_yamlReady_fromAgent = nodeHandle_to_own_agent_parameter_service.subscribe(  "TemplateController", 1, isReadyTemplateControllerYamlCallback);
-	ros::Subscriber safeContoller_yamlReady_fromCoord = nodeHandle_to_coordinator_parameter_service.subscribe("TemplateController", 1, isReadyTemplateControllerYamlCallback);
-
-
-
-	// GIVE YAML VARIABLES AN INITIAL VALUE
-	// This can be done either here or as part of declaring the
-	// variables in the header file
-
-
-
-
-	// FETCH ANY PARAMETERS REQUIRED FROM THE "PARAMETER SERVICES"
-
-	// The yaml files for the controllers are not added to
-	// "Parameter Service" as part of launching.
-	// The process for loading the yaml parameters is to send a
-	// service call containing the filename of the *.yaml file,
-	// and then a message will be received on the above subscribers
-	// when the paramters are ready.
-	// > NOTE IMPORTANTLY that by using a serice client
-	//   we stall the availability of this node until the
-	//   paramter service is ready
-
-	// Create the service client as a local variable
-	ros::ServiceClient requestLoadYamlFilenameServiceClient = nodeHandle_to_own_agent_parameter_service.serviceClient<LoadYamlFromFilename>("requestLoadYamlFilename", false);
-	// Create the service call as a local variable
-	LoadYamlFromFilename loadYamlFromFilenameCall;
-	// Specify the Yaml filename as a string
-	loadYamlFromFilenameCall.request.stringWithHeader.data = "TemplateController";
-	// Set for whom this applies to
-	loadYamlFromFilenameCall.request.stringWithHeader.shouldCheckForAgentID = false;
-	// Wait until the serivce exists
-	requestLoadYamlFilenameServiceClient.waitForExistence(ros::Duration(-1));
-	// Make the service call
-	if(requestLoadYamlFilenameServiceClient.call(loadYamlFromFilenameCall))
-	{
-		// Nothing to do in this case.
-		// The "isReadyTemplateControllerYamlCallback" function
-		// will be called once the YAML file is loaded
-	}
-	else
-	{
-		// Inform the user
-		ROS_ERROR("[TEST MOTORS CONTROLLER] The request load yaml file service call failed.");
-	}
-
-
-
-
     // PUBLISHERS AND SUBSCRIBERS
 
-    // Instantiate the class variable "m_debugPublisher" to be a
-    // "ros::Publisher". This variable advertises under the name
-    // "DebugTopic" and is a message with the structure defined
-    //  in the file "DebugMsg.msg" (located in the "msg" folder).
-    m_debugPublisher = nodeHandle.advertise<DebugMsg>("DebugTopic", 1);
-
-	// Instantiate the local variable "requestSetpointChangeSubscriber"
-	// to be a "ros::Subscriber" type variable that subscribes to the
-	// "RequestSetpointChange" topic and calls the class function
-	// "requestSetpointChangeCallback" each time a messaged is received
-	// on this topic and the message is passed as an input argument to
-	// the callback function. This subscriber will mainly receive
-	// messages from the "flying agent GUI" when the setpoint is changed
-	// by the user.
-	ros::Subscriber requestSetpointChangeSubscriber = nodeHandle.subscribe("RequestSetpointChange", 1, requestSetpointChangeCallback);
-
-	// Same again but instead for changes requested by the coordinator.
-	// For this we need to first create a node handle to the coordinator:
-	std::string namespace_to_coordinator;
-	constructNamespaceForCoordinator( m_coordID, namespace_to_coordinator );
-	ros::NodeHandle nodeHandle_to_coordinator(namespace_to_coordinator);
-	// And now we can instantiate the subscriber:
-	ros::Subscriber requestSetpointChangeSubscriber_from_coord = nodeHandle_to_coordinator.subscribe("TemplateControllerService/RequestSetpointChange", 1, requestSetpointChangeCallback);
-
-	// Instantiate the class variable "m_setpointChangedPublisher" to
-	// be a "ros::Publisher". This variable advertises under the name
-	// "SetpointChanged" and is a message with the structure defined
-	// in the file "SetpointWithHeader.msg" (located in the "msg" folder).
-	// This publisher is used by the "flying agent GUI" to update the
-	// field that displays the current setpoint for this controller.
-	m_setpointChangedPublisher = nodeHandle.advertise<SetpointWithHeader>("SetpointChanged", 1);
-
-	// Instantiate the local variable "getCurrentSetpointService" to be
-	// a "ros::ServiceServer" type variable that advertises the service
-	// called "GetCurrentSetpoint". This service has the input-output
-	// behaviour defined in the "GetSetpointService.srv" file (located
-	// in the "srv" folder). This service, when called, is provided with
-	// an integer (that is essentially ignored), and is expected to respond
-	// with the current setpoint of the controller. When a request is made
-	// of this service the "getCurrentSetpointCallback" function is called.
-	ros::ServiceServer getCurrentSetpointService = nodeHandle.advertiseService("GetCurrentSetpoint", getCurrentSetpointCallback);
-
-
-
     // Instantiate the local variable "service" to be a "ros::ServiceServer" type
-    // variable that advertises the service called "TemplateController". This service has
+    // variable that advertises the service called "TestMotorsController". This service has
     // the input-output behaviour defined in the "Controller.srv" file (located in the
     // "srv" folder). This service, when called, is provided with the most recent
     // measurement of the Crazyflie and is expected to respond with the control action
@@ -820,20 +313,6 @@ int main(int argc, char* argv[]) {
     // of this service the "calculateControlOutput" function is called.
     ros::ServiceServer service = nodeHandle.advertiseService("TestMotorsController", calculateControlOutput);
 
-    // Instantiate the local variable "customCommandSubscriber" to be a "ros::Subscriber"
-    // type variable that subscribes to the "GUIButton" topic and calls the class
-    // function "customCommandReceivedCallback" each time a messaged is received on this topic
-    // and the message received is passed as an input argument to the callback function.
-    ros::Subscriber customCommandReceivedSubscriber = nodeHandle.subscribe("CustomButtonPressed", 1, customCommandReceivedCallback);
-
-    // Same again but instead for changes requested by the coordinator.
-	// For this we need to first create a node handle to the coordinator:
-	//std::string namespace_to_coordinator;
-	//constructNamespaceForCoordinator( m_coordID, namespace_to_coordinator );
-	//ros::NodeHandle nodeHandle_to_coordinator(namespace_to_coordinator);
-	// And now we can instantiate the subscriber:
-	ros::Subscriber customCommandReceivedSubscriber_from_coord = nodeHandle_to_coordinator.subscribe("TemplateControllerService/CustomButtonPressed", 1, customCommandReceivedCallback);
-
 
 
     // Print out some information to the user.
@@ -844,4 +323,4 @@ int main(int argc, char* argv[]) {
 
     // Return zero if the "ross::spin" is cancelled.
     return 0;
-}
+}
\ No newline at end of file
diff --git a/dfall_ws/src/dfall_pkg/src/nodes/TuningControllerService.cpp b/dfall_ws/src/dfall_pkg/src/nodes/TuningControllerService.cpp
index d18bd7ee6ad97304e497a71f9699f2536ca41c7a..ab91b275c584e51c349e61ec1ee5d02f5193490b 100644
--- a/dfall_ws/src/dfall_pkg/src/nodes/TuningControllerService.cpp
+++ b/dfall_ws/src/dfall_pkg/src/nodes/TuningControllerService.cpp
@@ -79,54 +79,78 @@
 //
 // The arument "request" is a structure provided to this service with the following two
 // properties:
-// request.ownCrazyflie
-// This property is itself a structure of type "CrazyflieData",  which is defined in the
-// file "CrazyflieData.msg", and has the following properties
-// string crazyflieName
+//
+// >> request.ownCrazyflie
+// This property is itself a structure of type "FlyingVehicleState",  which is defined in the
+// file "FlyingVehicleState.msg", and has the following properties
+//     string vehicleName
 //     float64 x                         The x position of the Crazyflie [metres]
 //     float64 y                         The y position of the Crazyflie [metres]
 //     float64 z                         The z position of the Crazyflie [metres]
 //     float64 roll                      The roll component of the intrinsic Euler angles [radians]
 //     float64 pitch                     The pitch component of the intrinsic Euler angles [radians]
 //     float64 yaw                       The yaw component of the intrinsic Euler angles [radians]
-//     float64 acquiringTime #delta t    The time elapsed since the previous "CrazyflieData" was received [seconds]
-//     bool occluded                     A boolean indicted whether the Crazyflie for visible at the time of this measurement
+//     float64 acquiringTime #delta t    The time elapsed since the previous "FlyingVehicleState" was received [seconds]
+//     bool isValid                      A boolean indicted whether the Crazyflie for visible at the time of this measurement
 // The values in these properties are directly the measurement taken by the Vicon
 // motion capture system of the Crazyflie that is to be controlled by this service
 //
-// request.otherCrazyflies
-// This property is an array of "CrazyflieData" structures, what allows access to the
+// >> request.otherCrazyflies
+// This property is an array of "FlyingVehicleState" structures, what allows access to the
 // Vicon measurements of other Crazyflies.
 //
 // The argument "response" is a structure that is expected to be filled in by this
 // service by this function, it has only the following property
-// response.ControlCommand
-// This property is iteself a structure of type "ControlCommand", which is defined in
-// the file "ControlCommand.msg", and has the following properties:
-//     float32 roll                      The command sent to the Crazyflie for the body frame x-axis
-//     float32 pitch                     The command sent to the Crazyflie for the body frame y-axis
-//     float32 yaw                       The command sent to the Crazyflie for the body frame z-axis
-//     uint16 motorCmd1                  The command sent to the Crazyflie for motor 1
-//     uint16 motorCmd2                  The command sent to the Crazyflie for motor 1
-//     uint16 motorCmd3                  The command sent to the Crazyflie for motor 1
-//     uint16 motorCmd4                  The command sent to the Crazyflie for motor 1
-//     uint8 onboardControllerType       The flag sent to the Crazyflie for indicating how to implement the command
+//
+// >> response.ControlCommand
+// This property is iteself a structure of type "ControlCommand", which is
+// defined in the file "ControlCommand.msg", and has the following properties:
+//     uint16 motorCmd1                 The command sent to the Crazyflie for motor 1
+//     uint16 motorCmd2                 ... same for motor 2
+//     uint16 motorCmd3                 ... same for motor 3
+//     uint16 motorCmd4                 ... same for motor 4
+//     uint8 xControllerMode            The mode sent to the Crazyflie for what controller to run for the body frame x-axis
+//     uint8 yControllerMode            ... same body frame y-axis
+//     uint8 zControllerMode            ... same body frame z-axis
+//     uint8 yawControllerMode          ... same body frame yaw
+//     float32 xControllerSetpoint      The setpoint sent to the Crazyflie for the body frame x-axis controller
+//     float32 yControllerSetpoint      ... same body frame y-axis
+//     float32 zControllerSetpoint      ... same body frame z-axis
+//     float32 yawControllerSetpoint    ... same body frame yaw
 // 
-// IMPORTANT NOTES FOR "onboardControllerType"  AND AXIS CONVENTIONS
-// > The allowed values for "onboardControllerType" are in the "Defines" section at the
-//   top of this file, they are MOTOR_MODE, RATE_MODE, OR ANGLE_MODE.
-// > In the classroom exercise we will only use the RATE_MODE.
-// > In RATE_MODE the ".roll", ".ptich", and ".yaw" properties of "response.ControlCommand"
-//   specify the angular rate in [radians/second] that will be requested from the
-//   PID controllers running in the Crazyflie 2.0 firmware.
-// > In RATE_MODE the ".motorCmd1" to ".motorCmd4" properties of "response.ControlCommand"
-//   are the baseline motor commands requested from the Crazyflie, with the adjustment
-//   for body rates being added on top of this in the firmware (i.e., as per the code
-//   of the "distribute_power" function provided in exercise sheet 2).
-// > In RATE_MODE the axis convention for the roll, pitch, and yaw body rates returned
-//   in "response.ControlCommand" should use right-hand coordinate axes with x-forward
-//   and z-upwards (i.e., the positive z-axis is aligned with the direction of positive
-//   thrust). To assist, teh following is an ASCII art of this convention:
+// IMPORTANT NOTES FOR "{x,y,z,yaw}ControllerMode"  AND AXIS CONVENTIONS
+// > The allowed values for "{x,y,z,yaw}ControllerMode" are in the
+//   "Constants.h" header file, they are:
+//   - CF_ONBOARD_CONTROLLER_MODE_OFF
+//   - CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE
+//   - CF_ONBOARD_CONTROLLER_MODE_ANGLE
+//   - CF_ONBOARD_CONTROLLER_MODE_VELOCITY
+//   - CF_ONBOARD_CONTROLLER_MODE_POSITION
+//
+// > The most common option to use for the {x,y,yaw} controller is
+//   the CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE option.
+//
+// > The most common option to use for the {z} controller is
+//   the CF_ONBOARD_CONTROLLER_MODE_OFF option, and thus the
+//   body frame z-axis is controlled by the motorCmd{1,2,3,4}
+//   values that you set.
+//
+// > When the CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE is selected, then:
+//   1) the ".xControllerSetpoint", ".yControllerSetpoint", and
+//      ".yawControllerSetpoint" properties of "response.ControlCommand"
+//      specify the angular rate in [radians/second] that will be requested
+//      from the PID controllers running in the Crazyflie 2.0 firmware.
+//   2) the axis convention for the roll, pitch, and yaw body rates,
+//      i.e., as set in the {y,x,yaw}ControllerSetpoint properties of
+//      the "response.ControlCommand" that you return, is a right-hand
+//      coordinate axes with x-forward and z-upwards (i.e., the positive
+//      z-axis is aligned with the direction of positive thrust). To
+//      assist, the ASCII art below depicts this convention.
+//   3) the ".motorCmd1" to ".motorCmd4" properties of
+//      "response.ControlCommand" are the baseline motor commands
+//      requested from the Crazyflie, with the adjustment for body rates
+//      being added on top of this in the firmware (i.e., as per the
+//      code of the "distribute_power" found in the firmware).
 //
 // ASCII ART OF THE CRAZYFLIE 2.0 LAYOUT
 //
@@ -757,14 +781,21 @@ void calculateControlOutput_viaLQR(float stateErrorBody[12], Controller::Request
 			// Display that the "controller_mode" was not recognised
 			ROS_INFO_STREAM("[TUNING CONTROLLER] ERROR: in the 'calculateControlOutput' function of the 'TuningControllerService': the 'controller_mode' is not recognised.");
 			// Set everything in the response to zero
-			response.controlOutput.roll       =  0;
-			response.controlOutput.pitch      =  0;
-			response.controlOutput.yaw        =  0;
-			response.controlOutput.motorCmd1  =  0;
-			response.controlOutput.motorCmd2  =  0;
-			response.controlOutput.motorCmd3  =  0;
-			response.controlOutput.motorCmd4  =  0;
-			response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_MOTOR;
+			// > Specify that all controllers are disabled
+			response.controlOutput.xControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+			response.controlOutput.yControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+			response.controlOutput.zControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+			response.controlOutput.yawControllerMode = CF_ONBOARD_CONTROLLER_MODE_OFF;
+			// > Fill in zero for the controller setpoints
+			response.controlOutput.xControllerSetpoint   = 0.0;
+			response.controlOutput.yControllerSetpoint   = 0.0;
+			response.controlOutput.zControllerSetpoint   = 0.0;
+			response.controlOutput.yawControllerSetpoint = 0.0;
+			// > Fill in all motor thrusts as zerp
+			response.controlOutput.motorCmd1 = 0.0;
+			response.controlOutput.motorCmd2 = 0.0;
+			response.controlOutput.motorCmd3 = 0.0;
+			response.controlOutput.motorCmd4 = 0.0;
 			break;
 		}
 	}
@@ -804,15 +835,23 @@ void calculateControlOutput_viaLQRforRates(float stateErrorBody[12], Controller:
 
 	// UPDATE THE "RETURN" THE VARIABLE NAMED "response"
 
-	// Put the computed rates and thrust into the "response" variable
+	// Specify the mode of each controller
+	response.controlOutput.xControllerMode   = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+	response.controlOutput.yControllerMode   = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+	response.controlOutput.zControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+	response.controlOutput.yawControllerMode = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+
+	// Put the computed rates into the "response" variable
 	// > For roll, pitch, and yaw:
-	response.controlOutput.roll  = rollRate_forResponse;
-	response.controlOutput.pitch = pitchRate_forResponse;
-	response.controlOutput.yaw   = yawRate_forResponse;
-	// > For the thrust adjustment we must add the feed-forward thrust to counter-act gravity.
-	// > NOTE: remember that the thrust is commanded per motor, so you sohuld
-	//         consider whether the "thrustAdjustment" computed by your
-	//         controller needed to be divided by 4 or not.
+	response.controlOutput.xControllerSetpoint   = pitchRate_forResponse;
+	response.controlOutput.yControllerSetpoint   = rollRate_forResponse;
+	response.controlOutput.zControllerSetpoint   = 0.0;
+	response.controlOutput.yawControllerSetpoint = yawRate_forResponse;
+
+	// Put the computed thrust into the "response" variable
+	// > On top of the thrust adjustment, we must add the feed-forward thrust to counter-act gravity.
+	// > NOTE: remember that the thrust is commanded per motor, hence divide
+	//         the thrusts by 4.
 	thrustAdjustment = thrustAdjustment / 4.0;
 	// > NOTE: the "gravity_force_quarter" value was already divided by 4 when
 	//   it was loaded/processes from the .yaml file.
@@ -821,11 +860,6 @@ void calculateControlOutput_viaLQRforRates(float stateErrorBody[12], Controller:
 	response.controlOutput.motorCmd3 = computeMotorPolyBackward(thrustAdjustment + gravity_force_quarter);
 	response.controlOutput.motorCmd4 = computeMotorPolyBackward(thrustAdjustment + gravity_force_quarter);
 
-	
-	// Specify that this controller is a rate controller
-	// response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_MOTOR;
-	response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_RATE;
-	// response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_ANGLE;
 
 
 	// An alternate debugging technique is to print out data directly to the
@@ -844,14 +878,9 @@ void calculateControlOutput_viaLQRforRates(float stateErrorBody[12], Controller:
 
 		// An example of "printing out" the control actions computed.
 		ROS_INFO_STREAM("thrustAdjustment = " << thrustAdjustment);
-		ROS_INFO_STREAM("controlOutput.roll = " << response.controlOutput.roll);
-		ROS_INFO_STREAM("controlOutput.pitch = " << response.controlOutput.pitch);
-		ROS_INFO_STREAM("controlOutput.yaw = " << response.controlOutput.yaw);
-
-		// An example of "printing out" the "thrust-to-command" conversion parameters.
-		ROS_INFO_STREAM("motorPoly 0:" << motorPoly[0]);
-		ROS_INFO_STREAM("motorPoly 0:" << motorPoly[1]);
-		ROS_INFO_STREAM("motorPoly 0:" << motorPoly[2]);
+		ROS_INFO_STREAM("controlOutput.xControllerSetpoint   = " << response.controlOutput.xControllerSetpoint);
+		ROS_INFO_STREAM("controlOutput.yControllerSetpoint   = " << response.controlOutput.yControllerSetpoint);
+		ROS_INFO_STREAM("controlOutput.yawControllerSetpoint = " << response.controlOutput.yawControllerSetpoint);
 
 		// An example of "printing out" the per motor 16-bit command computed.
 		ROS_INFO_STREAM("controlOutput.cmd1 = " << response.controlOutput.motorCmd1);
@@ -890,15 +919,23 @@ void calculateControlOutput_viaLQRforAngles(float stateErrorBody[12], Controller
 
 	// UPDATE THE "RETURN" THE VARIABLE NAMED "response"
 
-	// Put the computed rates and thrust into the "response" variable
+	// Specify the mode of each controller
+	response.controlOutput.xControllerMode   = CF_ONBOARD_CONTROLLER_MODE_ANGLE;
+	response.controlOutput.yControllerMode   = CF_ONBOARD_CONTROLLER_MODE_ANGLE;
+	response.controlOutput.zControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+	response.controlOutput.yawControllerMode = CF_ONBOARD_CONTROLLER_MODE_ANGLE;
+
+	// Put the computed angles into the "response" variable
 	// > For roll, pitch, and yaw:
-	response.controlOutput.roll  = rollAngle_forResponse;
-	response.controlOutput.pitch = pitchAngle_forResponse;
-	response.controlOutput.yaw   = setpoint[3];
-	// > For the thrust adjustment we must add the feed-forward thrust to counter-act gravity.
-	// > NOTE: remember that the thrust is commanded per motor, so you sohuld
-	//         consider whether the "thrustAdjustment" computed by your
-	//         controller needed to be divided by 4 or not.
+	response.controlOutput.xControllerSetpoint   = pitchAngle_forResponse;
+	response.controlOutput.yControllerSetpoint   = rollAngle_forResponse;
+	response.controlOutput.zControllerSetpoint   = 0.0;
+	response.controlOutput.yawControllerSetpoint = setpoint[3];
+
+	// Put the computed thrust into the "response" variable
+	// > On top of the thrust adjustment, we must add the feed-forward thrust to counter-act gravity.
+	// > NOTE: remember that the thrust is commanded per motor, hence divide
+	//         the thrusts by 4.
 	thrustAdjustment = thrustAdjustment / 4.0;
 	// > NOTE: the "gravity_force_quarter" value was already divided by 4 when
 	//         it was loaded/processes from the .yaml file.
@@ -906,14 +943,6 @@ void calculateControlOutput_viaLQRforAngles(float stateErrorBody[12], Controller
 	response.controlOutput.motorCmd2 = computeMotorPolyBackward(thrustAdjustment + gravity_force_quarter);
 	response.controlOutput.motorCmd3 = computeMotorPolyBackward(thrustAdjustment + gravity_force_quarter);
 	response.controlOutput.motorCmd4 = computeMotorPolyBackward(thrustAdjustment + gravity_force_quarter);
-
-	
-	// Specify that this controller is a rate controller
-	// response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_MOTOR;
-	// response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_RATE;
-	response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_ANGLE;
-
-
 }
 
 
@@ -1013,15 +1042,23 @@ void calculateControlOutput_viaLQRforAnglesRatesNested( float stateErrorBody[12]
 
 	// UPDATE THE "RETURN" THE VARIABLE NAMED "response"
 
-	// Put the computed rates and thrust into the "response" variable
+	// Specify the mode of each controller
+	response.controlOutput.xControllerMode   = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+	response.controlOutput.yControllerMode   = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+	response.controlOutput.zControllerMode   = CF_ONBOARD_CONTROLLER_MODE_OFF;
+	response.controlOutput.yawControllerMode = CF_ONBOARD_CONTROLLER_MODE_ANGULAR_RATE;
+
+	// Put the computed rates into the "response" variable
 	// > For roll, pitch, and yaw:
-	response.controlOutput.roll  = rollRate_forResponse;
-	response.controlOutput.pitch = pitchRate_forResponse;
-	response.controlOutput.yaw   = yawRate_forResponse;
-	// > For the thrust adjustment we must add the feed-forward thrust to counter-act gravity.
-	// > NOTE: remember that the thrust is commanded per motor, so you sohuld
-	//         consider whether the "thrustAdjustment" computed by your
-	//         controller needed to be divided by 4 or not.
+	response.controlOutput.xControllerSetpoint   = pitchRate_forResponse;
+	response.controlOutput.yControllerSetpoint   = rollRate_forResponse;
+	response.controlOutput.zControllerSetpoint   = 0.0;
+	response.controlOutput.yawControllerSetpoint = yawRate_forResponse;
+
+	// Put the computed thrust into the "response" variable
+	// > On top of the thrust adjustment, we must add the feed-forward thrust to counter-act gravity.
+	// > NOTE: remember that the thrust is commanded per motor, hence divide
+	//         the thrusts by 4.
 	float thrustAdjustment = thrustAdjustment_200Hz / 4.0;
 	// > NOTE: the "gravity_force_quarter" value was already divided by 4 when
 	//         it was loaded/processes from the .yaml file.
@@ -1030,19 +1067,15 @@ void calculateControlOutput_viaLQRforAnglesRatesNested( float stateErrorBody[12]
 	response.controlOutput.motorCmd3 = computeMotorPolyBackward(thrustAdjustment + gravity_force_quarter);
 	response.controlOutput.motorCmd4 = computeMotorPolyBackward(thrustAdjustment + gravity_force_quarter);
 
-	
-	// Specify that this controller is a rate controller
-	// response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_MOTOR;
-	response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_RATE;
-	// response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_ANGLE;
+
 
 	// Display some details (if requested)
 	if (shouldDisplayDebugInfo)
 	{
 		ROS_INFO_STREAM("thrust    =" << lqr_angleRateNested_prev_thrustAdjustment );
-		ROS_INFO_STREAM("rollrate  =" << response.controlOutput.roll );
-		ROS_INFO_STREAM("pitchrate =" << response.controlOutput.pitch );
-		ROS_INFO_STREAM("yawrate   =" << response.controlOutput.yaw );
+		ROS_INFO_STREAM("rollrate  =" << response.controlOutput.yControllerSetpoint );
+		ROS_INFO_STREAM("pitchrate =" << response.controlOutput.xControllerSetpoint );
+		ROS_INFO_STREAM("yawrate   =" << response.controlOutput.yawControllerSetpoint );
 	}
 }
 
@@ -1481,20 +1514,20 @@ void fetchTuningControllerYamlParameters(ros::NodeHandle& nodeHandle)
 	// PARAMETERS SPECIFIC TO THE TUNING CONTROL FEATURE
 
 	/// Setpoint for the HORIZONTAL test
-	getParameterFloatVector(nodeHandle_for_paramaters, "test_horizontal_setpoint1", test_horizontal_setpoint1, 4);
-	getParameterFloatVector(nodeHandle_for_paramaters, "test_horizontal_setpoint2", test_horizontal_setpoint2, 4);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "test_horizontal_setpoint1", test_horizontal_setpoint1, 4);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "test_horizontal_setpoint2", test_horizontal_setpoint2, 4);
 
 	// Setpoint for the VERTICAL test
-	getParameterFloatVector(nodeHandle_for_paramaters, "test_vertical_setpoint1", test_vertical_setpoint1, 4);
-	getParameterFloatVector(nodeHandle_for_paramaters, "test_vertical_setpoint2", test_vertical_setpoint2, 4);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "test_vertical_setpoint1", test_vertical_setpoint1, 4);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "test_vertical_setpoint2", test_vertical_setpoint2, 4);
 
 	// Setpoint for the HEADING test
-	getParameterFloatVector(nodeHandle_for_paramaters, "test_heading_setpoint1", test_heading_setpoint1, 4);
-	getParameterFloatVector(nodeHandle_for_paramaters, "test_heading_setpoint2", test_heading_setpoint2, 4);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "test_heading_setpoint1", test_heading_setpoint1, 4);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "test_heading_setpoint2", test_heading_setpoint2, 4);
 
 	// Setpoint for the ALL test
-	getParameterFloatVector(nodeHandle_for_paramaters, "test_all_setpoint1", test_all_setpoint1, 4);
-	getParameterFloatVector(nodeHandle_for_paramaters, "test_all_setpoint2", test_all_setpoint2, 4);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "test_all_setpoint1", test_all_setpoint1, 4);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "test_all_setpoint2", test_all_setpoint2, 4);
 
 	// Parameters for flying in a circle
 	test_circle_radius = getParameterFloat(nodeHandle_for_paramaters, "test_circle_radius");
@@ -1536,7 +1569,7 @@ void fetchTuningControllerYamlParameters(ros::NodeHandle& nodeHandle)
 
 	// > The co-efficients of the quadratic conversation from 16-bit motor command to
 	//   thrust force in Newtons
-	getParameterFloatVector(nodeHandle_for_paramaters, "motorPoly", motorPoly, 3);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "motorPoly", motorPoly, 3);
 
 	// > The boolean for whether to execute the convert into body frame function
 	shouldPerformConvertIntoBodyFrame = getParameterBool(nodeHandle_for_paramaters, "shouldPerformConvertIntoBodyFrame");
@@ -1557,24 +1590,24 @@ void fetchTuningControllerYamlParameters(ros::NodeHandle& nodeHandle)
 	yaml_estimator_method = getParameterInt( nodeHandle_for_paramaters , "estimator_method" );
 
 	// The LQR Controller parameters for "LQR_MODE_RATE"
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixThrust_NineStateVector", gainMatrixThrust_NineStateVector, 9);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixRollRate",               gainMatrixRollRate,               9);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixPitchRate",              gainMatrixPitchRate,              9);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixYawRate",                gainMatrixYawRate,                9);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixThrust_NineStateVector", gainMatrixThrust_NineStateVector, 9);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixRollRate",               gainMatrixRollRate,               9);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixPitchRate",              gainMatrixPitchRate,              9);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixYawRate",                gainMatrixYawRate,                9);
 	
 	// The LQR Controller parameters for "LQR_MODE_ANGLE"
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixThrust_SixStateVector",  gainMatrixThrust_SixStateVector,  6);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixRollAngle",              gainMatrixRollAngle,              6);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixPitchAngle",             gainMatrixPitchAngle,             6);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixThrust_SixStateVector",  gainMatrixThrust_SixStateVector,  6);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixRollAngle",              gainMatrixRollAngle,              6);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixPitchAngle",             gainMatrixPitchAngle,             6);
 	
 	// The LQR Controller parameters for "LQR_MODE_ANGLE_RATE_NESTED"
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixThrust_SixStateVector_50Hz",  gainMatrixThrust_SixStateVector_50Hz,  6);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixRollAngle_50Hz",              gainMatrixRollAngle_50Hz,              6);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixPitchAngle_50Hz",             gainMatrixPitchAngle_50Hz,             6);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixThrust_SixStateVector_50Hz",  gainMatrixThrust_SixStateVector_50Hz,  6);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixRollAngle_50Hz",              gainMatrixRollAngle_50Hz,              6);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixPitchAngle_50Hz",             gainMatrixPitchAngle_50Hz,             6);
 
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixRollRate_Nested",             gainMatrixRollRate_Nested,             3);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixPitchRate_Nested",            gainMatrixPitchRate_Nested,            3);
-	getParameterFloatVector(nodeHandle_for_paramaters, "gainMatrixYawRate_Nested",              gainMatrixYawRate_Nested,              3);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixRollRate_Nested",             gainMatrixRollRate_Nested,             3);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixPitchRate_Nested",            gainMatrixPitchRate_Nested,            3);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "gainMatrixYawRate_Nested",              gainMatrixYawRate_Nested,              3);
 
 	
 	// 16-BIT COMMAND LIMITS
@@ -1584,13 +1617,13 @@ void fetchTuningControllerYamlParameters(ros::NodeHandle& nodeHandle)
 
 	// THE POINT MASS KALMAN FILTER (PMKF) GAINS AND ERROR EVOLUATION
 	// > For the (x,y,z) position
-	getParameterFloatVector(nodeHandle_for_paramaters, "PMKF_Ahat_row1_for_positions",  PMKF_Ahat_row1_for_positions,  2);
-	getParameterFloatVector(nodeHandle_for_paramaters, "PMKF_Ahat_row2_for_positions",  PMKF_Ahat_row2_for_positions,  2);
-	getParameterFloatVector(nodeHandle_for_paramaters, "PMKF_Kinf_for_positions"     ,  PMKF_Kinf_for_positions     ,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "PMKF_Ahat_row1_for_positions",  PMKF_Ahat_row1_for_positions,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "PMKF_Ahat_row2_for_positions",  PMKF_Ahat_row2_for_positions,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "PMKF_Kinf_for_positions"     ,  PMKF_Kinf_for_positions     ,  2);
 	// > For the (roll,pitch,yaw) angles
-	getParameterFloatVector(nodeHandle_for_paramaters, "PMKF_Ahat_row1_for_angles",  PMKF_Ahat_row1_for_angles,  2);
-	getParameterFloatVector(nodeHandle_for_paramaters, "PMKF_Ahat_row2_for_angles",  PMKF_Ahat_row2_for_angles,  2);
-	getParameterFloatVector(nodeHandle_for_paramaters, "PMKF_Kinf_for_angles"     ,  PMKF_Kinf_for_angles     ,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "PMKF_Ahat_row1_for_angles",  PMKF_Ahat_row1_for_angles,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "PMKF_Ahat_row2_for_angles",  PMKF_Ahat_row2_for_angles,  2);
+	getParameterFloatVectorKnownLength(nodeHandle_for_paramaters, "PMKF_Kinf_for_angles"     ,  PMKF_Kinf_for_angles     ,  2);
 
 
 	// DEBUGGING: Print out one of the parameters that was loaded
diff --git a/dfall_ws/src/dfall_pkg/src/nodes/ViconDataPublisher.cpp b/dfall_ws/src/dfall_pkg/src/nodes/ViconDataPublisher.cpp
index be04f3de12f27ea6762ce2ed125fd919b982156d..9d2a762cf232b0ab6595fe28fc99d620d633402a 100755
--- a/dfall_ws/src/dfall_pkg/src/nodes/ViconDataPublisher.cpp
+++ b/dfall_ws/src/dfall_pkg/src/nodes/ViconDataPublisher.cpp
@@ -30,12 +30,21 @@
 //    ----------------------------------------------------------------------------------
 
 
+// Include useful libraries
 #include <string.h>
-#include "DataStreamClient.h"
 #include "ros/ros.h"
+
+// Include the VICON Data Steam SDK header
+#include "DataStreamClient.h"
+
+// Include the DFALL message types
 #include "dfall_pkg/ViconData.h"
 #include "dfall_pkg/UnlabeledMarker.h"
 
+// Include the shared definitions
+#include "nodes/Constants.h"
+
+
 // #define TESTING_FAKE_DATA
 
 // notice that unit here are in milimeters
@@ -243,21 +252,29 @@ int main(int argc, char* argv[]) {
                 }
 
                 
-                //build message
-                CrazyflieData cfData;
-                cfData.crazyflieName = subjectName;
-
-                cfData.occluded = outputTranslation.Occluded;
-
-                cfData.x = outputTranslation.Translation[0] / 1000.0f;
-                cfData.y = outputTranslation.Translation[1] / 1000.0f;
-                cfData.z = outputTranslation.Translation[2] / 1000.0f;
-                cfData.roll = roll;
-                cfData.pitch = pitch;
-                cfData.yaw = yaw;
-                cfData.acquiringTime = totalViconLatency;
+                // Local variable for the data of this objcet
+                FlyingVehicleState object_data;
+                // Fill in the details
+                // > For the type
+                object_data.type = FLYING_VEHICLE_STATE_TYPE_MOCAP_MEASUREMENT;
+                // > For the name
+                object_data.vehicleName = subjectName;
+                // > For the occulsion flag
+                object_data.isValid = !outputTranslation.Occluded;
+                // > For position
+                object_data.x = outputTranslation.Translation[0] / 1000.0f;
+                object_data.y = outputTranslation.Translation[1] / 1000.0f;
+                object_data.z = outputTranslation.Translation[2] / 1000.0f;
+                // > For euler angles
+                object_data.roll = roll;
+                object_data.pitch = pitch;
+                object_data.yaw = yaw;
+                // > For the acquiring time
+                object_data.acquiringTime = totalViconLatency;
+
+                // Push back into the Vicon Data variable
                 // if(!outputTranslation.Occluded)
-                viconData.crazyflies.push_back(cfData);
+                viconData.crazyflies.push_back(object_data);
             }
             viconDataPublisher.publish(viconData);
         }
@@ -325,25 +342,27 @@ void testFakeData(ros::Publisher viconDataPublisher)
         f += 10/1000.0f;
         i++;
         // TODO: Fake CF data
-        CrazyflieData crazyfly;
+        FlyingVehicleState crazyfly;
+
+        crazyfly.type = FLYING_VEHICLE_STATE_TYPE_MOCAP_MEASUREMENT;
 
-        crazyfly.occluded = false;
+        crazyfly.isValid = true;
 
-        crazyfly.crazyflieName = "CF1";
+        crazyfly.vehicleName = "CF1";
         crazyfly.x = 0;
         crazyfly.y = 0;
         crazyfly.z = 0;
         crazyfly.yaw = 3.14159 * f;
         viconData.crazyflies.push_back(crazyfly);
 
-        crazyfly.crazyflieName = "CF2";
+        crazyfly.vehicleName = "CF2";
         crazyfly.x = 1;
         crazyfly.y = 1;
         crazyfly.z = 0;
         crazyfly.yaw = -3.14159 * f;
         viconData.crazyflies.push_back(crazyfly);
 
-        crazyfly.crazyflieName = "CF3";
+        crazyfly.vehicleName = "CF3";
         crazyfly.x = 1;
         crazyfly.y = -1;
         crazyfly.z = 0;
@@ -352,7 +371,7 @@ void testFakeData(ros::Publisher viconDataPublisher)
 
         if(i > 50 && i < 200)
         {
-            crazyfly.occluded = true;
+            crazyfly.isValid = true;
         }
 
         viconData.crazyflies.push_back(crazyfly);
diff --git a/dfall_ws/src/dfall_pkg/src/qualisys/QualisysDataPublisher.py b/dfall_ws/src/dfall_pkg/src/qualisys/QualisysDataPublisher.py
index cee7ce819acc2ca2bb836750de3b40ec0278e73c..043d9461ecb2df182e50821502673171584bddae 100755
--- a/dfall_ws/src/dfall_pkg/src/qualisys/QualisysDataPublisher.py
+++ b/dfall_ws/src/dfall_pkg/src/qualisys/QualisysDataPublisher.py
@@ -71,7 +71,7 @@ from std_msgs.msg import String
 
 # Import the D-FaLL message types
 from dfall_pkg.msg import ViconData
-from dfall_pkg.msg import CrazyflieData
+from dfall_pkg.msg import FlyingVehicleState
 from dfall_pkg.msg import UnlabeledMarker
 
 # General import
@@ -112,6 +112,11 @@ DEG_TO_RAD = 0.01745329
 #QTM_FILE = pkg_resources.resource_filename("qtm", "data/Demo.qtm")
 QTM_FILE = "none"
 
+# Types of flying vehicle states:
+#FLYING_VEHICLE_STATE_TYPE_NONE                        = 0
+FLYING_VEHICLE_STATE_TYPE_MOCAP_MEASUREMENT           = 1
+#FLYING_VEHICLE_STATE_TYPE_CRAZYFLIE_STATE_ESTIMATE    = 2
+#FLYING_VEHICLE_STATE_TYPE_12_STATE_ESTIMATE           = 3
 
 # OPEN THE ROS BAG FOR WRITING
 #rp = RosPack()
@@ -278,22 +283,25 @@ class QualisysQtmClient:
                 #print( "rotation = ", rotation )
 
                 # Initialise a "ViconData" struct
-                # > This is defined in the "CrazyflieData.msg" file
-                this_crazyflie_data = CrazyflieData();
+                # > This is defined in the "FlyingVehicleState.msg" file
+                this_crazyflie_data = FlyingVehicleState();
+
+                # Add the type
+                this_crazyflie_data.type = FLYING_VEHICLE_STATE_TYPE_MOCAP_MEASUREMENT;
 
                 # Add the name of this object
                 if current_body_index < len(self._list_of_body_names):
-                    this_crazyflie_data.crazyflieName = self._list_of_body_names[current_body_index]
+                    this_crazyflie_data.vehicleName = self._list_of_body_names[current_body_index]
                 else:
-                    this_crazyflie_data.crazyflieName = ''
+                    this_crazyflie_data.vehicleName = ''
 
                 # Check for "nan" as an indication of occulsion
                 if math.isnan(position.x):
                     # Fill in the occlusion flag
-                    this_crazyflie_data.occluded = True
+                    this_crazyflie_data.isValid = False
                 else:
                     # Fill in the occlusion flag
-                    this_crazyflie_data.occluded = False
+                    this_crazyflie_data.isValid = True
 
                     # Fill in the position data
                     this_crazyflie_data.x = position.x * 0.001
diff --git a/dfall_ws/src/dfall_pkg/srv/CMQueryCrazyflieName.srv b/dfall_ws/src/dfall_pkg/srv/CMQueryCrazyflieName.srv
index 85d54384396813d8517340233eb98bbb3c356a5d..4584a581e1e40879014aff300395cfd12f2e0edc 100755
--- a/dfall_ws/src/dfall_pkg/srv/CMQueryCrazyflieName.srv
+++ b/dfall_ws/src/dfall_pkg/srv/CMQueryCrazyflieName.srv
@@ -1,5 +1,4 @@
 string crazyflieName
 ---
 CrazyflieContext crazyflieContext
-uint32 studentID
-
+uint32 studentID
\ No newline at end of file
diff --git a/dfall_ws/src/dfall_pkg/srv/Controller.srv b/dfall_ws/src/dfall_pkg/srv/Controller.srv
index 979abc5c4bd047133bd520771cb712443331c16e..c10a6bad937af38985ac9c1d80410ff55d833ffc 100644
--- a/dfall_ws/src/dfall_pkg/srv/Controller.srv
+++ b/dfall_ws/src/dfall_pkg/srv/Controller.srv
@@ -1,5 +1,5 @@
 bool isFirstControllerCall
-CrazyflieData ownCrazyflie
-CrazyflieData[] otherCrazyflies
+FlyingVehicleState ownCrazyflie
+FlyingVehicleState[] otherCrazyflies
 ---
-ControlCommand controlOutput
+ControlCommand controlOutput
\ No newline at end of file
diff --git a/dfall_ws/src/dfall_pkg/srv/GetDebugValuesService.srv b/dfall_ws/src/dfall_pkg/srv/GetDebugValuesService.srv
new file mode 100644
index 0000000000000000000000000000000000000000..53783323b02f353692ed1af3f3608520dc9a57bf
--- /dev/null
+++ b/dfall_ws/src/dfall_pkg/srv/GetDebugValuesService.srv
@@ -0,0 +1,3 @@
+uint32 data
+---
+DebugMsg values
diff --git a/dfall_ws/src/dfall_pkg/srv/IntStringService.srv b/dfall_ws/src/dfall_pkg/srv/IntStringService.srv
new file mode 100644
index 0000000000000000000000000000000000000000..0c46a893757e9e93c86d10bb798cc6e37d357532
--- /dev/null
+++ b/dfall_ws/src/dfall_pkg/srv/IntStringService.srv
@@ -0,0 +1,3 @@
+uint32 data
+---
+string data
\ No newline at end of file
diff --git a/web_interface/html/agent.php b/web_interface/html/agent.php
new file mode 100644
index 0000000000000000000000000000000000000000..6b19f212ddb587e9b57aa7eba4e60362ecaabdda
--- /dev/null
+++ b/web_interface/html/agent.php
@@ -0,0 +1,91 @@
+<?php
+	include("page_header.html");
+?>
+
+
+<script src="js/sse_agentStatus.js?ver=0.1"></script>
+
+
+<div class="full-window-fixed">
+</div>
+
+<div class="max-width-full-heigth-fixed">
+
+	<div class="top-bar-container">
+		<table class="top-bar-buttons-table">
+			<tr>
+				<td class="top-bar-motorsoff-button-cell">
+					<button
+						class="button-push red motorsoff"
+						id="buttonMotorsOffForAgent"
+						onclick="sendRosMessage_outputLabelID('motorsoff', '')"
+						>
+						MOTORS-OFF
+						<div class="div-for-button-highlight-on-touchscreen red"></div>
+					</button>
+				</td>
+				<td class="top-bar-info-button-cell">
+					<button class="button-push blue info" onclick="checkForRosAgent()">
+						i
+						<div class="div-for-button-highlight-on-touchscreen blue"></div>
+					</button>
+				</td>
+			</tr>
+		</table>
+
+		<!--
+			<div class="top-bar-title">
+				Agent (IP <?php echo $_SERVER['REMOTE_ADDR']; ?>)
+			</div>
+		-->
+
+		<div class="top-bar-status-icons padbelow">
+			<div class="on-off-switch type2forstatusbar">
+				<input type="checkbox" id="checkboxTopBarStatus" onchange=checkboxTopBarStatus_changed()><label for="checkboxTopBarStatus"></label>
+			</div>
+			<img id="radio-icon" class="status-icon-radio" src="img/rf_disconnected.png">
+			<img id="battery-icon" class="status-icon-battery" src="img/battery_unavailable.png">
+			<img id="flying-state-icon" class="status-icon-flying-state" src="img/flying_state_unavailable.png">
+		</div>
+	</div>
+
+
+	<div class="main-tabs">
+		<input name="tabs" type="radio" id="main-tab-1" checked="checked" class="main-tab-input"/>
+		<label for="main-tab-1" class="main-tab-label">Code</label>
+		<div class="main-tab-panel">
+			<?php
+				include("agent_tab_code.html");
+			?>
+		</div>
+
+		<input name="tabs" type="radio" id="main-tab-2" class="main-tab-input"/>
+		<label for="main-tab-2" class="main-tab-label">Compile</label>
+		<div class="main-tab-panel">
+			<?php
+				include("agent_tab_compile.html");
+			?>
+		</div>
+
+		<input name="tabs" type="radio" id="main-tab-3" class="main-tab-input"/>
+		<label for="main-tab-3" class="main-tab-label">Launch</label>
+		<div class="main-tab-panel">
+			<?php
+				include("agent_tab_launch.html");
+			?>
+		</div>
+
+		<input name="tabs" type="radio" id="main-tab-4" class="main-tab-input"/>
+		<label for="main-tab-4" class="main-tab-label">Control</label>
+		<div class="main-tab-panel thin-padding">
+			<?php
+				include("agent_tab_control.php");
+			?>
+		</div>
+	</div>
+</div>
+
+
+<?php
+	include("page_footer.html");
+?>
\ No newline at end of file
diff --git a/web_interface/html/agent_control_tab_default.html b/web_interface/html/agent_control_tab_default.html
new file mode 100644
index 0000000000000000000000000000000000000000..f187738bbf6fadde4f1a5df6227202c80a1c9a92
--- /dev/null
+++ b/web_interface/html/agent_control_tab_default.html
@@ -0,0 +1,327 @@
+<br>
+
+<button
+	class="button-push navy fullwidth"
+	id="buttonControlEnableDefault"
+	onclick="sendRosMessage_outputLabelID('enabledefault', 'labelControlEnableDefault')"
+	>
+	enable
+	<div class="div-for-button-highlight-on-touchscreen navy"></div>
+</button>
+<div
+	style="text-align: center; display: block;"
+	id="labelControlEnableDefault"
+	>
+	&nbsp
+</div>
+
+<hr class="hr-basic navy">
+
+<h2 style="text-align: center;">
+	Adjust Setpoint
+</h2>
+
+<table style="margin-left: auto; margin-right: auto;">
+	<tr>
+		<td class="setpoint-label-cell">
+			x [m]
+		</td>
+		<td class="setpoint-increment-cell">
+			<button
+				class="button-push navy slim short10"
+				id="buttonDecrementControlDefaultSetpointX"
+				onclick="incrementInputFieldWithGivenID('inputControlDefaultSetpointX', -1.0 )"
+				>
+				-
+				<div class="div-for-button-highlight-on-touchscreen navy"></div>
+			</button>
+		</td>
+		<td class="setpoint-input-field-cell">
+			<input
+				class="setpoint-input-field"
+				id="inputControlDefaultSetpointX"
+				type="text"
+				name="x"
+				value="0.0"
+				step="0.1"
+				pattern="^[-+]?\d*(\.)?(\d?)*"
+				inputmode="none"
+				>
+		</td>
+		<td class="setpoint-increment-cell">
+			<button
+				class="button-push navy slim short10"
+				id="buttonIncrementControlDefaultSetpointX"
+				onclick="incrementInputFieldWithGivenID('inputControlDefaultSetpointX', 1.0 )"
+				>
+				+
+				<div class="div-for-button-highlight-on-touchscreen navy"></div>
+			</button>
+		</td>
+	</tr>
+	<tr>
+		<td class="setpoint-label-cell">
+			y [m]
+		</td>
+		<td class="setpoint-increment-cell">
+			<button
+				class="button-push navy slim short10"
+				id="buttonDecrementControlDefaultSetpointY"
+				onclick="incrementInputFieldWithGivenID('inputControlDefaultSetpointY', -1.0 )"
+				>
+				-
+				<div class="div-for-button-highlight-on-touchscreen navy"></div>
+			</button>
+		</td>
+		<td class="setpoint-input-field-cell">
+			<input
+				class="setpoint-input-field"
+				id="inputControlDefaultSetpointY"
+				type="text"
+				name="y"
+				value="0.0"
+				step="0.1"
+				pattern="^[-+]?\d*(\.)?(\d?)*"
+				inputmode="none"
+				>
+		</td>
+		<td class="setpoint-increment-cell">
+			<button
+				class="button-push navy slim short10"
+				id="buttonIncrementControlDefaultSetpointY"
+				onclick="incrementInputFieldWithGivenID('inputControlDefaultSetpointY', 1.0 )"
+				>
+				+
+				<div class="div-for-button-highlight-on-touchscreen navy"></div>
+			</button>
+		</td>
+	</tr>
+	<tr>
+		<td class="setpoint-label-cell">
+			z [m]
+		</td>
+		<td class="setpoint-increment-cell">
+			<button
+				class="button-push navy slim short10"
+				id="buttonDecrementControlDefaultSetpointZ"
+				onclick="incrementInputFieldWithGivenID('inputControlDefaultSetpointZ', -1.0 )"
+				>
+				-
+				<div class="div-for-button-highlight-on-touchscreen navy"></div>
+			</button>
+		</td>
+		<td class="setpoint-input-field-cell">
+			<input
+				class="setpoint-input-field"
+				id="inputControlDefaultSetpointZ"
+				type="text"
+				name="z"
+				value="0.4"
+				step="0.1"
+				pattern="^[-+]?\d*(\.)?(\d?)*"
+				inputmode="none"
+				>
+		</td>
+		<td class="setpoint-increment-cell">
+			<button
+				class="button-push navy slim short10"
+				id="buttonIncrementControlDefaultSetpointZ"
+				onclick="incrementInputFieldWithGivenID('inputControlDefaultSetpointZ', 1.0 )"
+				>
+				+
+				<div class="div-for-button-highlight-on-touchscreen navy"></div>
+			</button>
+		</td>
+	</tr>
+	<tr>
+		<td class="setpoint-label-cell">
+			yaw [deg]
+		</td>
+		<td class="setpoint-increment-cell">
+			<button
+				class="button-push navy slim short10"
+				id="buttonDecrementControlDefaultSetpointYaw"
+				onclick="incrementInputFieldWithGivenID('inputControlDefaultSetpointYaw', -1.0 )"
+				>
+				-
+				<div class="div-for-button-highlight-on-touchscreen navy"></div>
+			</button>
+		</td>
+		<td class="setpoint-input-field-cell">
+			<input
+				class="setpoint-input-field"
+				id="inputControlDefaultSetpointYaw"
+				type="text"
+				name="yaw"
+				value="0"
+				step="5"
+				pattern="^[-+]?\d*(\.)?(\d?)*"
+				inputmode="none"
+				>
+		</td>
+		<td class="setpoint-increment-cell">
+			<button
+				class="button-push navy slim short10"
+				id="buttonIncrementControlDefaultSetpointYaw"
+				onclick="incrementInputFieldWithGivenID('inputControlDefaultSetpointYaw', 1.0 )"
+				>
+				+
+				<div class="div-for-button-highlight-on-touchscreen navy"></div>
+			</button>
+		</td>
+	</tr>
+	<tr>
+		<td></td>
+		<td></td>
+		<td>
+			<button
+				class="button-push navy fullwidth"
+				id="buttonControlDefaultSetSetpoint"
+				onclick="setSetpointViaRosMessage_outputLabelID('default', 'inputControlDefaultSetpoint', 'labelControlDefaultSetSetpoint' )"
+				>
+				set
+				<div class="div-for-button-highlight-on-touchscreen navy"></div>
+			</button>
+		</td>
+		<td></td>
+	</tr>
+	<tr>
+		<td></td>
+		<td></td>
+		<td>
+			<div
+				style="text-align: center;"
+				id="labelControlDefaultSetSetpoint"
+				>
+				&nbsp
+			</div>
+		</td>
+		<td></td>
+	</tr>
+</table>
+
+<hr class="hr-basic navy">
+
+<br>
+
+<table class="mse-table">
+	<tr>
+		<td></td>
+		<td class="mse-column-title-cell">
+			<span class="mse-column-title-span-full-text">Measured<br>Pose</span>
+			<span class="mse-column-title-span-short-text">Meas.<br>Pose</span>
+		</td>
+		<td class="mse-column-title-cell">
+			<span class="mse-column-title-span-full-text">Error</span>
+			<span class="mse-column-title-span-short-text">Error</span>
+		</td>
+		<td class="mse-column-title-cell">
+			<span class="mse-column-title-span-full-text">Current<br>Setpoint</span>
+			<span class="mse-column-title-span-short-text">Curr.<br>Setp.</span>
+		</td>
+	</tr>
+	<tr>
+		<td class="mse-row-title-cell">
+			x
+		</td>
+		<td class="mse-data-cell" id="default-measurement-x">xx.xx</td>
+		<td class="mse-data-cell" id="default-error-x">xx.xx</td>
+		<td class="mse-data-cell" id="default-setpoint-x">xx.xx</td>
+	</tr>
+	<tr>
+		<td class="mse-row-title-cell">
+			y
+		</td>
+		<td class="mse-data-cell" id="default-measurement-y">xx.xx</td>
+		<td class="mse-data-cell" id="default-error-y">xx.xx</td>
+		<td class="mse-data-cell" id="default-setpoint-y">xx.xx</td>
+	</tr>
+	<tr>
+		<td class="mse-row-title-cell">
+			z
+		</td>
+		<td class="mse-data-cell" id="default-measurement-z">xx.xx</td>
+		<td class="mse-data-cell" id="default-error-z">xx.xx</td>
+		<td class="mse-data-cell" id="default-setpoint-z">xx.xx</td>
+	</tr>
+	<tr>
+		<td class="mse-row-title-cell">
+			yaw
+		</td>
+		<td class="mse-data-cell" id="default-measurement-yaw">xx.xx</td>
+		<td class="mse-data-cell" id="default-error-yaw">xx.xx</td>
+		<td class="mse-data-cell" id="default-setpoint-yaw">xx.xx</td>
+	</tr>
+	<tr>
+		<td class="mse-row-title-cell">
+			pitch
+		</td>
+		<td class="mse-data-cell" id="default-measurement-pitch">xx.xx</td>
+		<td></td>
+		<td></td>
+	</tr>
+	<tr>
+		<td class="mse-row-title-cell">
+			roll
+		</td>
+		<td class="mse-data-cell" id="default-measurement-roll">xx.xx</td>
+		<td></td>
+		<td></td>
+	</tr>
+	<tr>
+		<td colspan="4" class="mse-caption-below">
+			<b>NOTES:</b>
+		</td>
+	</tr>
+	<tr>
+		<td colspan="4" class="mse-caption-below">
+			<b>(x,y,z)</b> in meters
+		</td>
+	</tr>
+	<tr>
+		<td colspan="4" class="mse-caption-below">
+			<b>(roll,pitch,yaw)</b> in degrees
+		</td>
+	</tr>
+	<tr>
+		<td colspan="4" class="mse-caption-below">
+			<b>error =</b> measured - setpoint
+		</td>
+	</tr>
+	<tr>
+		<td colspan="4" class="mse-caption-below">
+			<b>~2Hz</b> data refresh rate
+		</td>
+	</tr>
+</table>
+
+<br>
+
+<hr class="hr-basic navy">
+
+<table class="git-table">
+	<tr>
+		<td class="git-button-cell">
+			<button
+				class="button-push navy fullwidth"
+				id="buttonLoadYamlDefault"
+				onclick="sendRosMessage_outputLabelID('loadyamldefault', 'labelLoadYamlDefault')"
+				>
+				Load YAML Paramters for Default Controller
+				<div class="div-for-button-highlight-on-touchscreen navy"></div>
+			</button>
+		</td>
+	</tr>
+	<tr>
+		<td
+			style="text-align: center;"
+			id="labelLoadYamlDefault"
+			>
+			&nbsp
+		</td>
+	</tr>
+</table>
+
+<hr class="hr-basic navy">
+
+<br><br><br><br>
\ No newline at end of file
diff --git a/web_interface/html/agent_control_tab_student.html b/web_interface/html/agent_control_tab_student.html
new file mode 100644
index 0000000000000000000000000000000000000000..57f0f48ec7ddce2e7737de7eee568f4b5ca198bc
--- /dev/null
+++ b/web_interface/html/agent_control_tab_student.html
@@ -0,0 +1,410 @@
+<br>
+
+<button
+	class="button-push navy fullwidth"
+	id="buttonControlEnableStudent"
+	onclick="sendRosMessage_outputLabelID('enablestudent', 'labelControlEnableStudent')"
+	>
+	enable
+	<div class="div-for-button-highlight-on-touchscreen navy"></div>
+</button>
+<div
+	style="text-align: center; display: block;"
+	id="labelControlEnableStudent"
+	>
+	&nbsp
+</div>
+
+<hr class="hr-basic navy">
+
+<h2 style="text-align: center;">
+	Adjust Setpoint
+</h2>
+
+<table style="margin-left: auto; margin-right: auto;">
+	<tr>
+		<td class="setpoint-label-cell">
+			x [m]
+		</td>
+		<td class="setpoint-increment-cell">
+			<button
+				class="button-push navy slim short10"
+				id="buttonDecrementControlStudentSetpointX"
+				onclick="incrementInputFieldWithGivenID('inputControlStudentSetpointX', -1.0 )"
+				>
+				-
+				<div class="div-for-button-highlight-on-touchscreen navy"></div>
+			</button>
+		</td>
+		<td class="setpoint-input-field-cell">
+			<input
+				class="setpoint-input-field"
+				id="inputControlStudentSetpointX"
+				type="text"
+				name="x"
+				value="0"
+				step="0.1"
+				pattern="^[-+]?\d*(\.)?(\d?)*"
+				inputmode="none"
+				>
+		</td>
+		<td class="setpoint-increment-cell">
+			<button
+				class="button-push navy slim short10"
+				id="buttonIncrementControlStudentSetpointX"
+				onclick="incrementInputFieldWithGivenID('inputControlStudentSetpointX', 1.0 )"
+				>
+				+
+				<div class="div-for-button-highlight-on-touchscreen navy"></div>
+			</button>
+		</td>
+	</tr>
+	<tr>
+		<td class="setpoint-label-cell">
+			y [m]
+		</td>
+		<td class="setpoint-increment-cell">
+			<button
+				class="button-push navy slim short10"
+				id="buttonDecrementControlStudentSetpointY"
+				onclick="incrementInputFieldWithGivenID('inputControlStudentSetpointY', -1.0 )"
+				>
+				-
+				<div class="div-for-button-highlight-on-touchscreen navy"></div>
+			</button>
+		</td>
+		<td class="setpoint-input-field-cell">
+			<input
+				class="setpoint-input-field"
+				id="inputControlStudentSetpointY"
+				type="text"
+				name="y"
+				value="0"
+				step="0.1"
+				pattern="^[-+]?\d*(\.)?(\d?)*"
+				inputmode="none"
+				>
+		</td>
+		<td class="setpoint-increment-cell">
+			<button
+				class="button-push navy slim short10"
+				id="buttonIncrementControlStudentSetpointY"
+				onclick="incrementInputFieldWithGivenID('inputControlStudentSetpointY', 1.0 )"
+				>
+				+
+				<div class="div-for-button-highlight-on-touchscreen navy"></div>
+			</button>
+		</td>
+	</tr>
+	<tr>
+		<td class="setpoint-label-cell">
+			z [m]
+		</td>
+		<td class="setpoint-increment-cell">
+			<button
+				class="button-push navy slim short10"
+				id="buttonDecrementControlStudentSetpointZ"
+				onclick="incrementInputFieldWithGivenID('inputControlStudentSetpointZ', -1.0 )"
+				>
+				-
+				<div class="div-for-button-highlight-on-touchscreen navy"></div>
+			</button>
+		</td>
+		<td class="setpoint-input-field-cell">
+			<input
+				class="setpoint-input-field"
+				id="inputControlStudentSetpointZ"
+				type="text"
+				name="z"
+				value="0.4"
+				step="0.1"
+				pattern="^[-+]?\d*(\.)?(\d?)*"
+				inputmode="none"
+				>
+		</td>
+		<td class="setpoint-increment-cell">
+			<button
+				class="button-push navy slim short10"
+				id="buttonIncrementControlStudentSetpointZ"
+				onclick="incrementInputFieldWithGivenID('inputControlStudentSetpointZ', 1.0 )"
+				>
+				+
+				<div class="div-for-button-highlight-on-touchscreen navy"></div>
+			</button>
+		</td>
+	</tr>
+	<tr>
+		<td class="setpoint-label-cell">
+			yaw [deg]
+		</td>
+		<td class="setpoint-increment-cell">
+			<button
+				class="button-push navy slim short10"
+				id="buttonDecrementControlStudentSetpointYaw"
+				onclick="incrementInputFieldWithGivenID('inputControlStudentSetpointYaw', -1.0 )"
+				>
+				-
+				<div class="div-for-button-highlight-on-touchscreen navy"></div>
+			</button>
+		</td>
+		<td class="setpoint-input-field-cell">
+			<input
+				class="setpoint-input-field"
+				id="inputControlStudentSetpointYaw"
+				type="text"
+				name="yaw"
+				value="0"
+				step="5"
+				pattern="^[-+]?\d*(\.)?(\d?)*"
+				inputmode="none"
+				>
+		</td>
+		<td class="setpoint-increment-cell">
+			<button
+				class="button-push navy slim short10"
+				id="buttonIncrementControlStudentSetpointYaw"
+				onclick="incrementInputFieldWithGivenID('inputControlStudentSetpointYaw', 1.0 )"
+				>
+				+
+				<div class="div-for-button-highlight-on-touchscreen navy"></div>
+			</button>
+		</td>
+	</tr>
+	<tr>
+		<td></td>
+		<td></td>
+		<td>
+			<button
+				class="button-push navy fullwidth"
+				id="buttonControlStudentSetSetpoint"
+				onclick="setSetpointViaRosMessage_outputLabelID('student', 'inputControlStudentSetpoint', 'labelControlStudentSetSetpoint' )"
+				>
+				set
+				<div class="div-for-button-highlight-on-touchscreen navy"></div>
+			</button>
+		</td>
+		<td></td>
+	</tr>
+	<tr>
+		<td></td>
+		<td></td>
+		<td>
+			<div
+				style="text-align: center;"
+				id="labelControlStudentSetSetpoint"
+				>
+				&nbsp
+			</div>
+		</td>
+		<td></td>
+	</tr>
+</table>
+
+<hr class="hr-basic navy">
+
+<br>
+
+<table class="mse-table">
+	<tr>
+		<td></td>
+		<td class="mse-column-title-cell">
+			<span class="mse-column-title-span-full-text">Measured<br>Pose</span>
+			<span class="mse-column-title-span-short-text">Meas.<br>Pose</span>
+		</td>
+		<td class="mse-column-title-cell">
+			<span class="mse-column-title-span-full-text">Error</span>
+			<span class="mse-column-title-span-short-text">Error</span>
+		</td>
+		<td class="mse-column-title-cell">
+			<span class="mse-column-title-span-full-text">Current<br>Setpoint</span>
+			<span class="mse-column-title-span-short-text">Curr.<br>Setp.</span>
+		</td>
+	</tr>
+	<tr>
+		<td class="mse-row-title-cell">
+			x
+		</td>
+		<td class="mse-data-cell" id="student-measurement-x">xx.xx</td>
+		<td class="mse-data-cell" id="student-error-x">xx.xx</td>
+		<td class="mse-data-cell" id="student-setpoint-x">xx.xx</td>
+	</tr>
+	<tr>
+		<td class="mse-row-title-cell">
+			y
+		</td>
+		<td class="mse-data-cell" id="student-measurement-y">xx.xx</td>
+		<td class="mse-data-cell" id="student-error-y">xx.xx</td>
+		<td class="mse-data-cell" id="student-setpoint-y">xx.xx</td>
+	</tr>
+	<tr>
+		<td class="mse-row-title-cell">
+			z
+		</td>
+		<td class="mse-data-cell" id="student-measurement-z">xx.xx</td>
+		<td class="mse-data-cell" id="student-error-z">xx.xx</td>
+		<td class="mse-data-cell" id="student-setpoint-z">xx.xx</td>
+	</tr>
+	<tr>
+		<td class="mse-row-title-cell">
+			yaw
+		</td>
+		<td class="mse-data-cell" id="student-measurement-yaw">xx.xx</td>
+		<td class="mse-data-cell" id="student-error-yaw">xx.xx</td>
+		<td class="mse-data-cell" id="student-setpoint-yaw">xx.xx</td>
+	</tr>
+	<tr>
+		<td class="mse-row-title-cell">
+			pitch
+		</td>
+		<td class="mse-data-cell" id="student-measurement-pitch">xx.xx</td>
+		<td></td>
+		<td></td>
+	</tr>
+	<tr>
+		<td class="mse-row-title-cell">
+			roll
+		</td>
+		<td class="mse-data-cell" id="student-measurement-roll">xx.xx</td>
+		<td></td>
+		<td></td>
+	</tr>
+	<tr>
+		<td colspan="4" class="mse-caption-below">
+			<b>NOTES:</b>
+		</td>
+	</tr>
+	<tr>
+		<td colspan="4" class="mse-caption-below">
+			<b>(x,y,z)</b> in meters
+		</td>
+	</tr>
+	<tr>
+		<td colspan="4" class="mse-caption-below">
+			<b>(roll,pitch,yaw)</b> in degrees
+		</td>
+	</tr>
+	<tr>
+		<td colspan="4" class="mse-caption-below">
+			<b>error =</b> measured - setpoint
+		</td>
+	</tr>
+	<tr>
+		<td colspan="4" class="mse-caption-below">
+			<b>~2Hz</b> data refresh rate
+		</td>
+	</tr>
+</table>
+
+<br>
+
+<hr class="hr-basic navy">
+
+<table class="git-table">
+	<tr>
+		<td class="git-button-cell">
+			<button
+				class="button-push navy fullwidth"
+				id="buttonLoadYamlStudent"
+				onclick="sendRosMessage_outputLabelID('loadyamlstudent', 'labelLoadYamlStudent')"
+				>
+				Load YAML Paramters for Student Controller
+				<div class="div-for-button-highlight-on-touchscreen navy"></div>
+			</button>
+		</td>
+	</tr>
+	<tr>
+		<td
+			style="text-align: center;"
+			id="labelLoadYamlStudent"
+			>
+			&nbsp
+		</td>
+	</tr>
+</table>
+
+<hr class="hr-basic navy">
+
+<br>
+
+<h2 style="text-align: center;">
+	Debug Values
+</h2>
+
+<table class="debug-values-table">
+	<tr>
+		<td></td>
+		<td class="debug-values-row-title-cell">
+			Value 1
+		</td>
+		<td class="debug-values-data-cell" id="debug-value1">xx.xx</td>
+	</tr>
+	<tr>
+		<td></td>
+		<td class="debug-values-row-title-cell">
+			Value 2
+		</td>
+		<td class="debug-values-data-cell" id="debug-value2">xx.xx</td>
+	</tr>
+	<tr>
+		<td></td>
+		<td class="debug-values-row-title-cell">
+			Value 3
+		</td>
+		<td class="debug-values-data-cell" id="debug-value3">xx.xx</td>
+	</tr>
+	<tr>
+		<td></td>
+		<td class="debug-values-row-title-cell">
+			Value 4
+		</td>
+		<td class="debug-values-data-cell" id="debug-value4">xx.xx</td>
+	</tr>
+	<tr>
+		<td></td>
+		<td class="debug-values-row-title-cell">
+			Value 5
+		</td>
+		<td class="debug-values-data-cell" id="debug-value5">xx.xx</td>
+	</tr>
+	<tr>
+		<td></td>
+		<td class="debug-values-row-title-cell">
+			Value 6
+		</td>
+		<td class="debug-values-data-cell" id="debug-value6">xx.xx</td>
+	</tr>
+	<tr>
+		<td></td>
+		<td class="debug-values-row-title-cell">
+			Value 7
+		</td>
+		<td class="debug-values-data-cell" id="debug-value7">xx.xx</td>
+	</tr>
+	<tr>
+		<td></td>
+		<td class="debug-values-row-title-cell">
+			Value 8
+		</td>
+		<td class="debug-values-data-cell" id="debug-value8">xx.xx</td>
+	</tr>
+	<tr>
+		<td></td>
+		<td class="debug-values-row-title-cell">
+			Value 9
+		</td>
+		<td class="debug-values-data-cell" id="debug-value9">xx.xx</td>
+	</tr>
+	<tr>
+		<td></td>
+		<td class="debug-values-row-title-cell">
+			Value 10
+		</td>
+		<td class="debug-values-data-cell" id="debug-value10">xx.xx</td>
+	</tr>
+</table>
+
+<br>
+
+<hr class="hr-basic navy">
+
+<br><br><br><br>
\ No newline at end of file
diff --git a/web_interface/html/agent_tab_code.html b/web_interface/html/agent_tab_code.html
new file mode 100644
index 0000000000000000000000000000000000000000..b93f163e3568906b9504a7038cdb123cb8891f78
--- /dev/null
+++ b/web_interface/html/agent_tab_code.html
@@ -0,0 +1,79 @@
+<body>
+	<div class="body-container">
+		<main style="text-align:left;">
+
+			<br>
+
+			<form action="upload.php" method="post" enctype="multipart/form-data">
+				Upload your code below.
+				<br>
+				<br>
+				<input class="file" type="file" id="myToUpload" name="fileToUpload">
+				<br>
+				<input type="submit" value="Upload Code" name="submit">
+			</form>
+
+			<br><br><br>
+
+
+			<input type="hidden" id="MAX_FILE_SIZE" name="MAX_FILE_SIZE" value="1000000" />
+
+
+			<hr class="hr-basic navy">
+
+			<label for="cppfileinput" class="file-input-label">
+				Select your StudentControllerService.<b>cpp</b> file
+			</label>
+			<br>
+			<form id="cppuploadform" action="upload_async.php" method="POST" enctype="multipart/form-data">
+				<input type="file" id="cppfileinput" name="cppfile" class="file-input" />
+			</form>
+
+			<br>
+
+			<div id="cppfileuploadstatus" class="file-upload-status-div">
+			&nbsp
+			</div>
+
+			<br>
+
+			<div id="cppfiledetails" class="file-input-details-div">
+			&nbsp
+			</div>
+
+			<br>
+
+			<hr class="hr-basic navy">
+
+			<label for="yamlfileinput" class="file-input-label">
+				Select your StudentControllerService.<b>yaml</b> file
+			</label>
+			<br>
+			<form id="yamluploadform" action="upload_async.php" method="POST" enctype="multipart/form-data">
+				<input type="file" id="yamlfileinput" name="yamlfile" class="file-input" />
+			</form>
+
+			<br>
+
+			<div id="yamlfileuploadstatus" class="file-upload-status-div">
+			&nbsp
+			</div>
+
+			<br>
+
+			<div id="yamlfiledetails" class="file-input-details-div">
+			&nbsp
+			</div>
+
+			<br>
+
+			<hr class="hr-basic navy">			
+
+			<br><br><br>
+
+			<div id="agentStatusDebuggingDiv"></div>
+
+			<br><br>
+		</main>
+	</div>
+</body>
\ No newline at end of file
diff --git a/web_interface/html/agent_tab_compile.html b/web_interface/html/agent_tab_compile.html
new file mode 100644
index 0000000000000000000000000000000000000000..f2f1bc60174f2d3f77e26970ef694024bbeeb4be
--- /dev/null
+++ b/web_interface/html/agent_tab_compile.html
@@ -0,0 +1,112 @@
+<body>
+	<div class="body-container">
+		<main style="text-align:left;">
+
+			<br>
+
+			<table class="git-table">
+				<tr>
+					<td class="git-button-cell left">
+						<button
+							class="button-push navy fullwidth"
+							id="buttonGitStatus"
+							onclick="callGit_outputLabelID_shouldAppend_shouldConfirm('status', 'terminalOutput', true, false)"
+							>
+							git status
+							<div class="div-for-button-highlight-on-touchscreen navy"></div>
+						</button> 
+					</td>
+					<td class="git-button-cell right">
+						<button
+							class="button-push navy fullwidth"
+							id="buttonGitPull"
+							onclick="callGit_outputLabelID_shouldAppend_shouldConfirm('pull', 'terminalOutput', true, false)"
+							>
+							git pull
+							<div class="div-for-button-highlight-on-touchscreen navy"></div>
+						</button> 
+					</td>
+				</tr>
+				<tr>
+					<td class="git-button-cell left">
+						<button
+							class="button-push navy fullwidth"
+							id="buttonGitDiff"
+							onclick="callGit_outputLabelID_shouldAppend_shouldConfirm('diff', 'terminalOutput', true, false)"
+							>
+							git diff
+							<div class="div-for-button-highlight-on-touchscreen navy"></div>
+						</button> 
+					</td>
+					<td class="git-button-cell right">
+						<button
+							class="button-push navy fullwidth"
+							id="buttonCatkinMake"
+							onclick="callGit_outputLabelID_shouldAppend_shouldConfirm('catkin_make', 'terminalOutput', false, false)"
+							>
+							catkin make
+							<div class="div-for-button-highlight-on-touchscreen navy"></div>
+						</button>
+						<!-- ALTERNATIVE FOR THIS BUTTON -->
+						<!-- onclick="callBashScript_outputLabelID_clearOtherLabels_clickOtherButtons('catkin_make', 'terminalOutput' , null, null)" -->
+					</td>
+				</tr>
+			</table>
+
+			<div class="git-checkout-label">git checkout</div>
+			<table class="git-table">
+				<tr>
+					<td class="git-button-cell left">
+						<button
+							class="button-push red fullwidth"
+							id="buttonGitCheckoutAll"
+							onclick="callGit_outputLabelID_shouldAppend_shouldConfirm('checkoutall', 'terminalOutput', true, true)"
+							>
+							all
+							<div class="div-for-button-highlight-on-touchscreen red"></div>
+						</button>
+					</td>
+					<td class="git-button-cell right">
+						<button
+							class="button-push red fullwidth"
+							id="buttonGitCheckoutMaster"
+							onclick="callGit_outputLabelID_shouldAppend_shouldConfirm('checkoutmaster', 'terminalOutput', true, true)"
+							>
+							master
+							<div class="div-for-button-highlight-on-touchscreen red"></div>
+						</button>
+					</td>
+				</tr>
+			</table>
+
+			<br><br>
+
+			
+
+			<table class="terminal-label-table">
+				<tr>
+					<td class="terminal-label-cell">
+						<div class="terminal-label">TERMINAL OUTPUT</div>
+					</td>
+					<td>
+						<button
+							class="button-push navy monospace short"
+							id="buttonGitCheckout"
+							onclick="clearLabelWithGivenID('terminalOutput')"
+							>
+							clear
+							<div class="div-for-button-highlight-on-touchscreen navy"></div>
+						</button>
+					</td>
+				</tr>
+			</table>
+
+			<div class="terminal-background">
+				<div class="terminal-contents" id="terminalOutput"></div>
+			</div>
+		
+			<br>
+
+		</main>
+	</div>
+</body>
\ No newline at end of file
diff --git a/web_interface/html/agent_tab_control.php b/web_interface/html/agent_tab_control.php
new file mode 100644
index 0000000000000000000000000000000000000000..77f93a7a5eb3c8308cfdbfed2dd07ba4790367a1
--- /dev/null
+++ b/web_interface/html/agent_tab_control.php
@@ -0,0 +1,97 @@
+<table class="git-table">
+	<tr>
+		<td class="git-button-cell left">
+			<button
+				class="button-push navy fullwidth"
+				id="buttonControlRadioDisconnect"
+				onclick="sendRosMessage_outputLabelID('disconnect', 'labelControlRadioDisconnect')"
+				>
+				disconnect
+				<div class="div-for-button-highlight-on-touchscreen navy"></div>
+			</button>
+		</td>
+		<td class="git-button-cell left">
+			<button
+				class="button-push navy fullwidth"
+				id="buttonControlRadioConnect"
+				onclick="sendRosMessage_outputLabelID('connect', 'labelControlRadioConnect')"
+				>
+				connect
+				<div class="div-for-button-highlight-on-touchscreen navy"></div>
+			</button>
+		</td>
+	</tr>
+	<tr>
+		<td
+			style="text-align: center;"
+			id="labelControlRadioDisconnect"
+			>
+			&nbsp
+		</td>
+		<td
+			style="text-align: center;"
+			id="labelControlRadioConnect"
+			>
+			&nbsp
+		</td>
+	</tr>
+	<tr>
+		<td class="git-button-cell left">
+			<button
+				class="button-push navy fullwidth"
+				id="buttonControlTakeoff"
+				onclick="sendRosMessage_outputLabelID('takeoff', 'labelControlTakeOff')"
+				>
+				take-off
+				<div class="div-for-button-highlight-on-touchscreen navy"></div>
+			</button> 
+		</td>
+		<td class="git-button-cell left">
+			<button
+				class="button-push navy fullwidth"
+				id="buttonControlLand"
+				onclick="sendRosMessage_outputLabelID('land', 'labelControlLand')"
+				>
+				land
+				<div class="div-for-button-highlight-on-touchscreen navy"></div>
+			</button> 
+		</td>
+	</tr>
+	<tr>
+		<td
+			style="text-align: center;"
+			id="labelControlTakeOff"
+			>
+			&nbsp
+		</td>
+		<td
+			style="text-align: center;"
+			id="labelControlLand"
+			>
+			&nbsp
+		</td>
+	</tr>
+</table>
+
+<br>
+
+<div class="control-tabs">
+	<input name="control-tabs" type="radio" id="control-tab-1" checked="checked" class="control-tab-input"/>
+	<label for="control-tab-1" class="control-tab-label">Default</label>
+	<div class="control-tab-panel" id="control-tab-panel-default">
+		<?php
+			include("agent_control_tab_default.html");
+		?>
+	</div>
+
+	<input name="control-tabs" type="radio" id="control-tab-2" class="control-tab-input"/>
+	<label for="control-tab-2" class="control-tab-label">Student</label>
+	<div class="control-tab-panel" id="control-tab-panel-student">
+		<?php
+			include("agent_control_tab_student.html");
+		?>
+	</div>
+
+</div>
+
+<br>
\ No newline at end of file
diff --git a/web_interface/html/agent_tab_launch.html b/web_interface/html/agent_tab_launch.html
new file mode 100644
index 0000000000000000000000000000000000000000..06c04845ae5b0578a2d69e209fdbb3d2f98a20c1
--- /dev/null
+++ b/web_interface/html/agent_tab_launch.html
@@ -0,0 +1,179 @@
+<body>
+	<div class="body-container">
+		<main style="text-align:left;">
+
+			<br>
+
+			<table class="ros-table">
+
+				<tr>
+					<td class="ros-button-cell">
+						<button
+							class="button-push navy fullwidth"
+							id="buttonRosMasterStatus"
+							onclick="callBashScript_outputLabelID_clearOtherLabels_clickOtherButtons('checkForRosMaster', 'rosMasterStatus', ['rosLaunchMasterStatus','killMasterStatus'], null)"
+							>
+							Check for ROS Master
+							<div class="div-for-button-highlight-on-touchscreen navy"></div>
+						</button>
+					</td>
+					<td class="ros-info-cell">
+						<div id="rosMasterStatus"></div>
+					</td>
+				</tr>
+
+				<tr>
+					<td class="ros-button-cell">
+						<button
+							class="button-push navy fullwidth"
+							id="buttonLaunchRosMaster"
+							onclick="roslaunch_outputLabelID_clearOtherLabels_clickOtherButtons('master', 'rosLaunchMasterStatus', ['rosMasterStatus','killMasterStatus'], ['buttonRosAgentStatus','buttonRosNodeList'])"
+							>
+							Launch ROS Master
+							<div class="div-for-button-highlight-on-touchscreen navy"></div>
+						</button>
+					</td>
+					<td class="ros-info-cell">
+						<div id="rosLaunchMasterStatus"></div>
+					</td>
+				</tr>
+				<tr>
+					<td>
+						<table>
+							<td class="switch-cell  pad-right">
+								<div class="on-off-switch type4">
+									<input type="checkbox" id="checkboxEmulateMocap"><label for="checkboxEmulateMocap"></label>
+								</div>
+							</td>
+							<td class="ros-info-cell">
+								Emulate motion capture
+							</td>
+						</table>
+					</td>
+					<td class="ros-info-cell">
+						&nbsp
+					</td>
+				</tr>
+				<tr>
+					<td class="ros-button-cell">
+						<button
+							class="button-push red fullwidth"
+							id="buttonKillRosMaster"
+							onclick="callBashScript_outputLabelID_clearOtherLabels_clickOtherButtons('killRosMaster', 'killMasterStatus', ['rosMasterStatus','rosLaunchMasterStatus'], ['buttonRosAgentStatus','buttonRosNodeList'])"
+							>
+							Kill ROS Master
+							<div class="div-for-button-highlight-on-touchscreen red"></div>
+						</button>
+					</td>
+					<td class="ros-info-cell">
+						<div id="killMasterStatus"></div>
+					</td>
+				</tr>
+
+			</table>
+
+			<br>
+			<hr class="hr-basic navy">
+			<br>
+
+			<table class="ros-table">
+
+				<tr>
+					<td class="ros-button-cell">
+						<button
+							class="button-push navy fullwidth"
+							id="buttonRosAgentStatus"
+							onclick="callBashScript_outputLabelID_clearOtherLabels_clickOtherButtons('checkForRosAgent', 'rosAgentStatus', ['rosLaunchAgentStatus','killAgentStatus'], 'buttonRosNodeList')"
+							>
+							Check for ROS Agent
+							<div class="div-for-button-highlight-on-touchscreen navy"></div>
+						</button>
+					</td>
+					<td class="ros-info-cell">
+						<div id="rosAgentStatus"></div>
+					</td>
+				</tr>
+
+				<tr>
+					<td class="ros-button-cell">
+						<button
+							class="button-push navy fullwidth"
+							id="buttonLaunchRosAgent"
+							onclick="roslaunch_outputLabelID_clearOtherLabels_clickOtherButtons('agent', 'rosLaunchAgentStatus', ['rosAgentStatus','killAgentStatus'], 'buttonRosNodeList')"
+							>
+							Launch ROS Agent
+							<div class="div-for-button-highlight-on-touchscreen navy"></div>
+						</button>
+					</td>
+					<td class="ros-info-cell">
+						<div id="rosLaunchAgentStatus"></div>
+					</td>
+				</tr>
+				<tr>
+					<td>
+						<table>
+							<td class="switch-cell pad-right">
+								<div class="on-off-switch type4">
+									<input type="checkbox" id="checkboxEmulateCrazyRadio"><label for="checkboxEmulateCrazyRadio"></label>
+								</div>
+							</td>
+							<td class="ros-info-cell">
+								Emulate CrazyRadio
+							</td>
+						</table>
+					</td>
+					<td class="ros-info-cell">
+						&nbsp
+					</td>
+				</tr>
+				<tr>
+					<td class="ros-button-cell">
+						<button
+							class="button-push red fullwidth"
+							id="buttonKillRosAgent"
+							onclick="callBashScript_outputLabelID_clearOtherLabels_clickOtherButtons('killRosAgent', 'killAgentStatus', ['rosAgentStatus','rosLaunchAgentStatus'], 'buttonRosNodeList')"
+							>
+							Kill ROS Agent
+							<div class="div-for-button-highlight-on-touchscreen red"></div>
+						</button>
+					</td>
+					<td class="ros-info-cell">
+						<div id="killAgentStatus"></div>
+					</td>
+				</tr>
+
+			</table>
+
+			<br>
+			<hr class="hr-basic navy">
+			<br>
+
+			<table class="ros-table">
+
+				<tr>
+					<td class="ros-button-cell">
+						<button
+							class="button-push navy fullwidth"
+							id ="buttonRosNodeList"
+							onclick="callBashScript_outputLabelID_clearOtherLabels_clickOtherButtons('rosnodeList', 'rosnodeList', null, null)"
+							>
+							List ROS Nodes
+							<div class="div-for-button-highlight-on-touchscreen navy"></div>
+						</button>
+					</td>
+					<td></td>
+				</tr>
+				
+			</table>
+
+			<table class="ros-table">
+				<tr>
+					<td class="ros-info-cell" style="height:100px;vertical-align:text-top;">
+						<div id="rosnodeList"></div>
+					</td>
+				</tr>
+			</table>
+
+		</main>
+	</div>
+</body>
\ No newline at end of file
diff --git a/web_interface/html/bashscripts/catkin_make.sh b/web_interface/html/bashscripts/catkin_make.sh
new file mode 100755
index 0000000000000000000000000000000000000000..96e9494ba1d7b485ca9998655113c87f3f617cff
--- /dev/null
+++ b/web_interface/html/bashscripts/catkin_make.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+#
+# Make the ROS commands available
+# NOTE: these paths should NOT use ~
+source /opt/ros/melodic/setup.bash
+#source /home/www-share/dfall/dfall-system/dfall_ws/devel/setup.bash
+source /home/www-share/dfall/dfall-system/dfall_ws/src/dfall_pkg/launch/Config.sh
+#
+# Change directory to the dfall-system repository
+cd /home/www-share/dfall/dfall-system/dfall_ws
+#
+# Call catkin_make
+catkin_make
\ No newline at end of file
diff --git a/web_interface/html/bashscripts/catkin_make_clean.sh b/web_interface/html/bashscripts/catkin_make_clean.sh
new file mode 100755
index 0000000000000000000000000000000000000000..1d6935cb9ccbd360d4e8604ebf6397d8e32e24cd
--- /dev/null
+++ b/web_interface/html/bashscripts/catkin_make_clean.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+#
+# Make the ROS commands available
+# NOTE: these paths should NOT use ~
+source /opt/ros/melodic/setup.bash
+#source /home/www-share/dfall/dfall-system/dfall_ws/devel/setup.bash
+source /home/www-share/dfall/dfall-system/dfall_ws/src/dfall_pkg/launch/Config.sh
+#
+# Change directory to the dfall-system repository
+cd /home/www-share/dfall/dfall-system/dfall_ws
+#
+# Call catkin_make
+catkin_make clean
\ No newline at end of file
diff --git a/web_interface/html/bashscripts/checkForRosAgent.sh b/web_interface/html/bashscripts/checkForRosAgent.sh
new file mode 100755
index 0000000000000000000000000000000000000000..27ef70f78d51d505eda246a3990eaeb2397d4c9e
--- /dev/null
+++ b/web_interface/html/bashscripts/checkForRosAgent.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# Make the ROS commands available
+# NOTE: these paths should NOT use ~
+source /opt/ros/melodic/setup.bash
+#source /home/www-share/dfall/dfall-system/dfall_ws/devel/setup.bash
+source /home/www-share/dfall/dfall-system/dfall_ws/src/dfall_pkg/launch/Config.sh
+#
+# Check that the ROS Master exists
+# > Note: the -q options converts the 
+#   grep output to a true/false
+if rosnode list | grep -q /rosout; then
+    # Check if the agent exists
+    if rosnode list | grep -q "$(printf "/dfall/agent%03d" $DFALL_DEFAULT_AGENT_ID)"; then
+        echo "Agent $DFALL_DEFAULT_AGENT_ID exists"
+    else
+        echo "Agent $DFALL_DEFAULT_AGENT_ID not found"
+    fi
+else
+    echo "ROS Master not found"
+fi
diff --git a/web_interface/html/bashscripts/checkForRosMaster.sh b/web_interface/html/bashscripts/checkForRosMaster.sh
new file mode 100755
index 0000000000000000000000000000000000000000..285240e74a28b08a95342273317cd6e5cf7f0b2e
--- /dev/null
+++ b/web_interface/html/bashscripts/checkForRosMaster.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+#
+# Make the ROS commands available
+# NOTE: these paths should NOT use ~
+source /opt/ros/melodic/setup.bash
+#
+# Perform the  check
+# > Note: the -q options converts the 
+#   grep output to a true/false
+if rosnode list | grep -q /rosout; then
+    echo "ROS Master exists"
+else
+    echo "ROS Master not found"
+fi
diff --git a/web_interface/html/bashscripts/gitCheckoutAll.sh b/web_interface/html/bashscripts/gitCheckoutAll.sh
new file mode 100755
index 0000000000000000000000000000000000000000..013f312c4ad88d824d2704de30804f7e159b322c
--- /dev/null
+++ b/web_interface/html/bashscripts/gitCheckoutAll.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+#
+# Change directory to the dfall-system repository
+cd /home/www-share/dfall/dfall-system/
+#
+# Call git
+git checkout .
\ No newline at end of file
diff --git a/web_interface/html/bashscripts/gitCheckoutMaster.sh b/web_interface/html/bashscripts/gitCheckoutMaster.sh
new file mode 100755
index 0000000000000000000000000000000000000000..b0320528b7a7d9f4016d8b9bdc762a5547f95966
--- /dev/null
+++ b/web_interface/html/bashscripts/gitCheckoutMaster.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+#
+# Change directory to the dfall-system repository
+cd /home/www-share/dfall/dfall-system/
+#
+# Call git
+git checkout master
\ No newline at end of file
diff --git a/web_interface/html/bashscripts/gitDiff.sh b/web_interface/html/bashscripts/gitDiff.sh
new file mode 100755
index 0000000000000000000000000000000000000000..bb2873913a4623f1b6405c16851dbb1acce0d6bd
--- /dev/null
+++ b/web_interface/html/bashscripts/gitDiff.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+#
+# Change directory to the dfall-system repository
+cd /home/www-share/dfall/dfall-system/
+#
+# Call git
+git diff
\ No newline at end of file
diff --git a/web_interface/html/bashscripts/gitPull.sh b/web_interface/html/bashscripts/gitPull.sh
new file mode 100755
index 0000000000000000000000000000000000000000..8849eb92815478f51126729ef5e9f90942b25820
--- /dev/null
+++ b/web_interface/html/bashscripts/gitPull.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+#
+# Change directory to the dfall-system repository
+cd /home/www-share/dfall/dfall-system/
+#
+# Call git
+sudo -u www-data git pull
\ No newline at end of file
diff --git a/web_interface/html/bashscripts/gitStatus.sh b/web_interface/html/bashscripts/gitStatus.sh
new file mode 100755
index 0000000000000000000000000000000000000000..5e60e9beb6d2a5f2c5c7624e4d70506a97ba96a3
--- /dev/null
+++ b/web_interface/html/bashscripts/gitStatus.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+#
+# Change directory to the dfall-system repository
+cd /home/www-share/dfall/dfall-system/
+#
+# Call git
+git status
\ No newline at end of file
diff --git a/web_interface/html/bashscripts/killRosAgent.sh b/web_interface/html/bashscripts/killRosAgent.sh
new file mode 100755
index 0000000000000000000000000000000000000000..1b687066cdf539004b42fc6a15f7dd9f48025a25
--- /dev/null
+++ b/web_interface/html/bashscripts/killRosAgent.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+#
+# Make the ROS commands available
+# NOTE: these paths should NOT use ~
+source /opt/ros/melodic/setup.bash
+#source /home/www-share/dfall/dfall-system/dfall_ws/devel/setup.bash
+source /home/www-share/dfall/dfall-system/dfall_ws/src/dfall_pkg/launch/Config.sh
+#
+# Check that the ROS Master exists
+# > Note: the -q options converts the 
+#   grep output to a true/false
+if rosnode list | grep -q /rosout; then
+	# Check that if the agent is already
+	# launched
+	if rosnode list | grep -q "$(printf "/dfall/agent%03d" $DFALL_DEFAULT_AGENT_ID)"; then
+		# Kill all nodes starting with
+		# /dfall/agentXXX/
+		rosnode list | grep "$(printf "/dfall/agent%03d" $DFALL_DEFAULT_AGENT_ID)" | xargs rosnode kill > /dev/null
+		echo "Agent $DFALL_DEFAULT_AGENT_ID killed"
+	else
+		echo "Agent $DFALL_DEFAULT_AGENT_ID not found"
+	fi
+else
+	echo "ROS Master not found"
+fi
diff --git a/web_interface/html/bashscripts/killRosMaster.sh b/web_interface/html/bashscripts/killRosMaster.sh
new file mode 100755
index 0000000000000000000000000000000000000000..8945b1caed5f16e39f3a5d8105a9848cb9e97010
--- /dev/null
+++ b/web_interface/html/bashscripts/killRosMaster.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+#
+# Make the ROS commands available
+# NOTE: these paths should NOT use ~
+source /opt/ros/melodic/setup.bash
+#source /home/www-share/dfall/dfall-system/dfall_ws/devel/setup.bash
+source /home/www-share/dfall/dfall-system/dfall_ws/src/dfall_pkg/launch/Config.sh
+#
+# Check that the ROS Master exists
+# > Note: the -q options converts the 
+#   grep output to a true/false
+if rosnode list | grep -q /rosout; then
+	# Kill all nodes
+	rosnode kill --all > /dev/null 2>&1 &
+	# The /rosout will respawn, so all kill any
+	# "roslaunch" process owned by the
+	# "www-data" user
+	pkill -u www-data roslaunch
+	# For debugging it is usefull to running the
+	# following commands on the server machine
+	# >> ps -aux
+	# >> pgrep -u www-data
+	# Inform the user
+	echo "Killed all ros nodes"
+else
+	echo "ROS Master not found"
+fi
diff --git a/web_interface/html/bashscripts/launchRosAgent.sh b/web_interface/html/bashscripts/launchRosAgent.sh
new file mode 100755
index 0000000000000000000000000000000000000000..a2ba643f4b1c0480cfd061e8b6417a57222ebaa0
--- /dev/null
+++ b/web_interface/html/bashscripts/launchRosAgent.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+#
+# Check that exactly one command is supplied
+if [ "$#" -ne 1 ]; then
+	echo "exactly one argument must be supplied"
+	exit 1
+fi
+#
+# Check that the first command supplied is valid
+if [ "$1" != "true" ] && [ "$1" != "false" ]; then
+	echo "emulate crazyradio = $1, is not a valid boolean."
+	exit 1
+fi
+#
+# Put the commands into variables for make things more readable
+emulateradio=$1
+#
+# Make the ROS commands available
+# NOTE: these paths should NOT use ~
+source /opt/ros/melodic/setup.bash
+source /home/www-share/dfall/dfall-system/dfall_ws/devel/setup.bash
+source /home/www-share/dfall/dfall-system/dfall_ws/src/dfall_pkg/launch/Config.sh
+#
+# Set the ROS log location
+export ROS_LOG_DIR=/var/www/html/.ros/log
+#
+# Mount the dfall workspace folder
+#sudo mount --bind /home/pbeuchat/gitrep/dfall/dfall-system/dfall_ws /var/www/html/dfall_ws
+#
+# Check that the ROS Master exists
+# > Note: the -q options converts the
+#   grep output to a true/false
+if rosnode list | grep -q /rosout; then
+	# Check that if the agent is already
+	# launched
+	if rosnode list | grep -q "$(printf "/dfall/agent%03d" $DFALL_DEFAULT_AGENT_ID)"; then
+		echo "Agent $DFALL_DEFAULT_AGENT_ID is already running"
+	else
+		nohup roslaunch dfall_pkg pi_agent.launch emulateRadio:=$emulateradio > /dev/null 2>&1 &
+		echo "Agent $DFALL_DEFAULT_AGENT_ID successfully launched"
+	fi
+else
+	echo "ROS Master not found"
+fi
diff --git a/web_interface/html/bashscripts/launchRosMaster.sh b/web_interface/html/bashscripts/launchRosMaster.sh
new file mode 100755
index 0000000000000000000000000000000000000000..a6b95473de16f8f038b32d60d1f1d7573bc88b33
--- /dev/null
+++ b/web_interface/html/bashscripts/launchRosMaster.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+#
+# Check that exactly one command is supplied
+if [ "$#" -ne 1 ]; then
+	echo "exactly one argument must be supplied"
+	exit 1
+fi
+#
+# Check that the first command supplied is valid
+if [ "$1" != "true" ] && [ "$1" != "false" ]; then
+	echo "emulate mocap = $1, is not a valid boolean."
+	exit 1
+fi
+#
+# Put the commands into variables for make things more readable
+emultemocap=$1
+#
+# Make the ROS commands available
+# NOTE: these paths should NOT use ~
+source /opt/ros/melodic/setup.bash
+source /home/www-share/dfall/dfall-system/dfall_ws/devel/setup.bash
+source /home/www-share/dfall/dfall-system/dfall_ws/src/dfall_pkg/launch/Config.sh
+#
+# Set the ROS log location
+export ROS_LOG_DIR=/var/www/html/.ros/log
+#
+# Mount the dfall workspace folder
+#sudo mount --bind /home/pbeuchat/gitrep/dfall/dfall-system/dfall_ws /var/www/html/dfall_ws
+#
+# Check that the ROS Master exists
+# > Note: the -q options converts the
+#   grep output to a true/false
+if rosnode list | grep -q /rosout; then
+	echo "ROS Master is already running"
+else
+	nohup roslaunch dfall_pkg pi_master.launch emulateMocap:=$emultemocap > /dev/null 2>&1 &
+	echo "ROS Master successfully launched"
+fi
\ No newline at end of file
diff --git a/web_interface/html/bashscripts/rosCrazyRadioCommand_forAgent.sh b/web_interface/html/bashscripts/rosCrazyRadioCommand_forAgent.sh
new file mode 100755
index 0000000000000000000000000000000000000000..1d826fd3e511fcea4340463145d149d7838eeb98
--- /dev/null
+++ b/web_interface/html/bashscripts/rosCrazyRadioCommand_forAgent.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+#
+# Check that exactly one command is supplied
+if [ "$#" -ne 1 ]; then
+	echo "exactly one argument must be supplied"
+	exit 1
+fi
+#
+# Check that the command supplied is valid
+if [ "$1" != "0" ] && [ "$1" != "1" ]; then
+	echo "command = $1, is not a valid option"
+	exit 1
+fi
+#
+# Put the command into a variable for make things more readable
+command=$1
+#
+# Make the ROS commands available
+# NOTE: these paths should NOT use ~
+source /opt/ros/melodic/setup.bash
+source /home/www-share/dfall/dfall-system/dfall_ws/devel/setup.bash
+source /home/www-share/dfall/dfall-system/dfall_ws/src/dfall_pkg/launch/Config.sh
+#
+# Check that the ROS Master exists
+# > Note: the -q options converts the
+#   grep output to a true/false
+if rosnode list | grep -q /rosout; then
+	# Convert the agent ID to a zero padded string
+	agentnamespace=$(printf "agent%03d" $DFALL_DEFAULT_AGENT_ID)
+	# Send the message
+	if [ "$command" == "0" ]; then
+		# Publish the request
+		temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/FlyingAgentClient/CrazyRadioCommand dfall_pkg/IntWithHeader "{data: 0, shouldCheckForAgentID: False}")"
+		# Return that the message was sent
+		echo "sent"
+	#
+	elif [ "$command" == "1" ]; then
+		# Publish the request
+		temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/FlyingAgentClient/CrazyRadioCommand dfall_pkg/IntWithHeader "{data: 1, shouldCheckForAgentID: False}")"
+		# Return that the message was sent
+		echo "sent"
+	else
+		# Return that the command is not recognised
+		echo "command = $command is not a valid option"
+	fi
+
+else
+	echo "ROS Master not found"
+fi
diff --git a/web_interface/html/bashscripts/rosFlyingStateCommand_forAgent.sh b/web_interface/html/bashscripts/rosFlyingStateCommand_forAgent.sh
new file mode 100755
index 0000000000000000000000000000000000000000..7564ca5b9e7642e6017211fd1969de701b1bfcc7
--- /dev/null
+++ b/web_interface/html/bashscripts/rosFlyingStateCommand_forAgent.sh
@@ -0,0 +1,69 @@
+#!/bin/bash
+#
+# Check that exactly one command is supplied
+if [ "$#" -ne 1 ]; then
+	echo "failed"
+	exit 1
+fi
+#
+# Check that the command supplied is valid
+if [ "$1" != "1" ] && [ "$1" != "2" ] && [ "$1" != "3" ] && [ "$1" != "4" ] && [ "$1" != "5" ] && [ "$1" != "6" ] && [ "$1" != "7" ] && [ "$1" != "8" ] && [ "$1" != "11" ] && [ "$1" != "12" ] && [ "$1" != "13" ]; then
+	echo "failed"
+	exit 1
+fi
+#
+# Put the command into a variable for make things more readable
+command=$1
+#
+# Make the ROS commands available
+# NOTE: these paths should NOT use ~
+source /opt/ros/melodic/setup.bash
+source /home/www-share/dfall/dfall-system/dfall_ws/devel/setup.bash
+source /home/www-share/dfall/dfall-system/dfall_ws/src/dfall_pkg/launch/Config.sh
+#
+# Check that the ROS Master exists
+# > Note: the -q options converts the
+#   grep output to a true/false
+if rosnode list | grep -q /rosout; then
+    # Convert the agent ID to a zero padded string
+    agentnamespace=$(printf "agent%03d" $DFALL_DEFAULT_AGENT_ID)    
+    # Send the message
+    if [ "$command" == "1" ]; then
+		temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/FlyingAgentClient/Command dfall_pkg/IntWithHeader '{data: 1, shouldCheckForAgentID: False}')"
+	fi
+	if [ "$command" == "2" ]; then
+		temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/FlyingAgentClient/Command dfall_pkg/IntWithHeader '{data: 2, shouldCheckForAgentID: False}')"
+	fi
+	if [ "$command" == "3" ]; then
+		temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/FlyingAgentClient/Command dfall_pkg/IntWithHeader '{data: 3, shouldCheckForAgentID: False}')"
+	fi
+	if [ "$command" == "4" ]; then
+		temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/FlyingAgentClient/Command dfall_pkg/IntWithHeader '{data: 4, shouldCheckForAgentID: False}')"
+	fi
+	if [ "$command" == "5" ]; then
+		temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/FlyingAgentClient/Command dfall_pkg/IntWithHeader '{data: 5, shouldCheckForAgentID: False}')"
+	fi
+	if [ "$command" == "6" ]; then
+		temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/FlyingAgentClient/Command dfall_pkg/IntWithHeader '{data: 6, shouldCheckForAgentID: False}')"
+	fi
+	if [ "$command" == "7" ]; then
+		temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/FlyingAgentClient/Command dfall_pkg/IntWithHeader '{data: 7, shouldCheckForAgentID: False}')"
+	fi
+	if [ "$command" == "8" ]; then
+		temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/FlyingAgentClient/Command dfall_pkg/IntWithHeader '{data: 8, shouldCheckForAgentID: False}')"
+	fi
+	if [ "$command" == "11" ]; then
+		temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/FlyingAgentClient/Command dfall_pkg/IntWithHeader '{data: 11, shouldCheckForAgentID: False}')"
+	fi
+	if [ "$command" == "12" ]; then
+		temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/FlyingAgentClient/Command dfall_pkg/IntWithHeader '{data: 12, shouldCheckForAgentID: False}')"
+	fi
+	if [ "$command" == "13" ]; then
+		temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/FlyingAgentClient/Command dfall_pkg/IntWithHeader '{data: 13, shouldCheckForAgentID: False}')"
+	fi
+    #
+    # Return that the message was sent
+    echo "sent"
+else
+    echo "ROS Master not found"
+fi
diff --git a/web_interface/html/bashscripts/rosGetCurrentSetpoint_forAgent.sh b/web_interface/html/bashscripts/rosGetCurrentSetpoint_forAgent.sh
new file mode 100755
index 0000000000000000000000000000000000000000..e7ce23f355c0d6ef16cf9ee3cb4d2e3bd9f5260f
--- /dev/null
+++ b/web_interface/html/bashscripts/rosGetCurrentSetpoint_forAgent.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+#
+# Check that exactly one command is supplied
+if [ "$#" -ne 1 ]; then
+	echo "failed"
+	exit 1
+fi
+#
+# Check that the command supplied is valid
+if [ "$1" != "default" ] && [ "$1" != "student" ]; then
+	echo "failed"
+	exit 1
+fi
+#
+# Put the command into a variable for make things more readable
+command=$1
+#
+# Make the ROS commands available
+# NOTE: these paths should NOT use ~
+source /opt/ros/melodic/setup.bash
+source /home/www-share/dfall/dfall-system/dfall_ws/devel/setup.bash
+source /home/www-share/dfall/dfall-system/dfall_ws/src/dfall_pkg/launch/Config.sh
+#
+# Check that the ROS Master exists
+# > Note: the -q options converts the
+#   grep output to a true/false
+if rosnode list | grep -q /rosout; then
+	# Convert the agent ID to a zero padded string
+	agentnamespace=$(printf "agent%03d" $DFALL_DEFAULT_AGENT_ID)    
+	# Send the message
+	if [ "$command" == "default" ]; then
+		temp="$(rosservice call /$ROS_NAMESPACE/$agentnamespace/DefaultControllerService/GetCurrentSetpoint 0)"
+	fi
+	if [ "$command" == "student" ]; then
+		temp="$(rosservice call /$ROS_NAMESPACE/$agentnamespace/StudentControllerService/GetCurrentSetpoint 0)"
+	fi
+	#
+	# Return that the message was sent
+	echo "$temp"
+else
+	echo "ROS Master not found"
+fi
diff --git a/web_interface/html/bashscripts/rosGetStatusJson_forAgent.sh b/web_interface/html/bashscripts/rosGetStatusJson_forAgent.sh
new file mode 100755
index 0000000000000000000000000000000000000000..8b2d573e3de679ffbbc3fb87c5c1940879d46b54
--- /dev/null
+++ b/web_interface/html/bashscripts/rosGetStatusJson_forAgent.sh
@@ -0,0 +1,82 @@
+#!/bin/bash
+#
+#
+# Check whether a command is supplied
+# > and put it into a more redable variable
+if [ "$#" -eq 0 ]; then
+	eventid="0"
+elif [ "$#" -eq 1 ]; then
+	eventid=$1
+else
+	echo "not allowed to supply two or more arguments"
+	exit 1
+fi
+#
+# Check that the command supplied is valid
+if ! [[ $eventid =~ ^[0-9]*$ ]]; then
+	echo "event id must be an integer, event id = $1"
+	exit 1
+fi
+#
+# Make the ROS commands available
+# NOTE: these paths should NOT use ~
+source /opt/ros/melodic/setup.bash
+source /home/www-share/dfall/dfall-system/dfall_ws/devel/setup.bash
+source /home/www-share/dfall/dfall-system/dfall_ws/src/dfall_pkg/launch/Config.sh
+#
+# Check that the ROS Master exists
+# > Note: the -q options converts the
+#   grep output to a true/false
+if rosnode list | grep -q /rosout; then
+	# Check if the agent exists
+	if rosnode list | grep -q "$(printf "/dfall/agent%03d" $DFALL_DEFAULT_AGENT_ID)"; then
+		# Set a flag that agent was found
+		agentfound="true"
+		# Convert the agent ID to a zero padded string
+		agentnamespace=$(printf "agent%03d" $DFALL_DEFAULT_AGENT_ID)    
+		# Perform the service call for the status json
+		statusjsonfull="$(rosservice call /$ROS_NAMESPACE/$agentnamespace/AgentStatusForWebInterface/StatusAsJson 0)"
+		# Cut out the "data: " from the start, and the single " at the end
+		statusjsoncut1="${statusjsonfull:7:${#statusjsonfull}-8}"
+		# Remove all new line characters followed by 2 spaces
+		statusjsoncut2=$(echo $statusjsoncut1|tr -d '\n  ')
+		# Remove all remaining new line characters
+		statusjsoncut3=$(echo $statusjsoncut2|tr -d '\n')
+		#statusjsoncut3=${statusjsoncut2//$'\n'/}
+		# Remove all carriage return characters
+		statusjsoncut4=$(echo $statusjsoncut3|tr -d '\r')
+		# Remove all tab characters
+		statusjsoncut5=$(echo $statusjsoncut4|tr -d '\t')
+		# Remove all remaining \ escape characters
+		statusjson=${statusjsoncut5//\\}
+		#
+		# Check that the status json is valid based on length
+		if [ ${#statusjsonfull} -le 1 ]; then
+			# Set a flag that agent was NOT found
+			agentfound="false"
+			# Set all other values to "not available (na)"
+			statusjson="\"na\""
+		fi
+		#
+	else
+		# Set a flag that agent was NOT found
+		agentfound="false"
+		# Set all other values to "not available (na)"
+		statusjson="\"na\""
+	fi
+else
+	# Set a flag that agent was NOT found
+	agentfound="false"
+	# Set all other values to "not available (na)"
+	statusjson="\"na\""
+fi
+
+# Return that the values collected
+echo "{"\
+	"\"id\": \"$eventid\","\
+	"\"agentfound\": \"$agentfound\","\
+	"\"statusjson\": $statusjson"\
+	"}"
+
+# DEBUGGING: For testing directly in terminal
+# rosservice call /dfall/agent001/AgentStatusForWebInterface/StatusAsJson 0
\ No newline at end of file
diff --git a/web_interface/html/bashscripts/rosLoadYaml_forAgent.sh b/web_interface/html/bashscripts/rosLoadYaml_forAgent.sh
new file mode 100755
index 0000000000000000000000000000000000000000..d2b2ecbed5f50179201c75a1a88159b2fd7b67b4
--- /dev/null
+++ b/web_interface/html/bashscripts/rosLoadYaml_forAgent.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+#
+# Check that exactly one command is supplied
+if [ "$#" -ne 1 ]; then
+	echo "failed"
+	exit 1
+fi
+#
+# Check that the command supplied is valid
+if [ "$1" != "default" ] && [ "$1" != "student" ]; then
+	echo "failed"
+	exit 1
+fi
+#
+# Put the command into a variable for make things more readable
+command=$1
+#
+# Make the ROS commands available
+# NOTE: these paths should NOT use ~
+source /opt/ros/melodic/setup.bash
+source /home/www-share/dfall/dfall-system/dfall_ws/devel/setup.bash
+source /home/www-share/dfall/dfall-system/dfall_ws/src/dfall_pkg/launch/Config.sh
+#
+# Check that the ROS Master exists
+# > Note: the -q options converts the
+#   grep output to a true/false
+if rosnode list | grep -q /rosout; then
+	# Check if the agent exists
+	if rosnode list | grep -q "$(printf "/dfall/agent%03d" $DFALL_DEFAULT_AGENT_ID)"; then
+		# Convert the agent ID to a zero padded string
+		agentnamespace=$(printf "agent%03d" $DFALL_DEFAULT_AGENT_ID)    
+		# Send the message
+		if [ "$command" == "default" ]; then
+			# Publish the request
+			temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/ParameterService/requestLoadYamlFilename dfall_pkg/StringWithHeader "{data: DefaultController, shouldCheckForAgentID: False}")"
+			# Return that the message was sent
+			echo "sent"
+		#
+		elif [ "$command" == "student" ]; then
+			# Publish the request
+			temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/ParameterService/requestLoadYamlFilename dfall_pkg/StringWithHeader "{data: StudentController, shouldCheckForAgentID: False}")"
+			# Return that the message was sent
+			echo "sent"
+		#
+		else
+			# Return that the command is not recognised
+			echo "controller = $command is not a valid option"
+		fi
+	else
+		echo "Agent $DFALL_DEFAULT_AGENT_ID not found"
+	fi
+else
+	echo "ROS Master not found"
+fi
diff --git a/web_interface/html/bashscripts/rosSetNewSetpoint_forAgent.sh b/web_interface/html/bashscripts/rosSetNewSetpoint_forAgent.sh
new file mode 100755
index 0000000000000000000000000000000000000000..26fd87560ea3b069324d033f35e23bd4b160de68
--- /dev/null
+++ b/web_interface/html/bashscripts/rosSetNewSetpoint_forAgent.sh
@@ -0,0 +1,79 @@
+#!/bin/bash
+#
+# Check that exactly five commands are supplied
+if [ "$#" -ne 5 ]; then
+	echo "exaclty five arguments must be supplied"
+	exit 1
+fi
+#
+# Check that the first command supplied is valid
+if [ "$1" != "default" ] && [ "$1" != "student" ]; then
+	echo "command = $1, is not a valid option."
+	exit 1
+fi
+#
+# Put the commands into variables for make things more readable
+command=$1
+xnew=$2
+ynew=$3
+znew=$4
+yawnew=$5
+#
+# Check that the new setpoint values are purely numerical
+# > For x:
+if ! [[ $xnew =~ ^[+-]?[0-9]+\.?[0-9]*$ ]];then
+	echo "x = $xnew, is not a float."
+	exit 1
+fi
+# > For y:
+if ! [[ $ynew =~ ^[+-]?[0-9]+\.?[0-9]*$ ]];then
+	echo "y = $ynew, is not a float."
+	exit 1
+fi
+# > For z:
+if ! [[ $znew =~ ^[+-]?[0-9]+\.?[0-9]*$ ]];then
+	echo "z = $znew, is not a float."
+	exit 1
+fi
+# > For yaw:
+if ! [[ $yawnew =~ ^[+-]?[0-9]+\.?[0-9]*$ ]];then
+	echo "yaw = $yawnew, is not a float."
+	exit 1
+fi
+#
+# Make the ROS commands available
+# NOTE: these paths should NOT use ~
+source /opt/ros/melodic/setup.bash
+source /home/www-share/dfall/dfall-system/dfall_ws/devel/setup.bash
+source /home/www-share/dfall/dfall-system/dfall_ws/src/dfall_pkg/launch/Config.sh
+#
+# Check that the ROS Master exists
+# > Note: the -q options converts the
+#   grep output to a true/false
+if rosnode list | grep -q /rosout; then
+	# Convert the agent ID to a zero padded string
+	agentnamespace=$(printf "agent%03d" $DFALL_DEFAULT_AGENT_ID)    
+	# Send the message
+	if [ "$command" == "default" ]; then
+		# Publish the request
+		temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/DefaultControllerService/RequestSetpointChange dfall_pkg/SetpointWithHeader "{x: $xnew, y: $ynew, z: $znew, yaw: $yawnew, shouldCheckForAgentID: False}")"
+		# Return that the message was sent
+		echo "sent"
+	#
+	elif [ "$command" == "student" ]; then
+		# Publish the request
+		temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/StudentControllerService/RequestSetpointChange dfall_pkg/SetpointWithHeader "{x: $xnew, y: $ynew, z: $znew, yaw: $yawnew, shouldCheckForAgentID: False}")"
+		# Return that the message was sent
+		echo "sent"
+	#
+	else
+		# Return that the command is not recognised
+		echo "controller = $command is not a valid option"
+	fi
+
+else
+	echo "ROS Master not found"
+fi
+
+# DEBUGGING: For testing directly in terminal
+# rostopic pub -1 /dfall/agent001/DefaultControllerService/RequestSetpointChange dfall_pkg/SetpointWithHeader {x: 0.0, y: 0.0, z: 0.1, yaw: 0, shouldCheckForAgentID: False}
\ No newline at end of file
diff --git a/web_interface/html/bashscripts/roscore.sh b/web_interface/html/bashscripts/roscore.sh
new file mode 100755
index 0000000000000000000000000000000000000000..36be7a3807b3208d28012c7b89fefeb7977649fe
--- /dev/null
+++ b/web_interface/html/bashscripts/roscore.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+echo "Now attempting roscore"
+source /opt/ros/melodic/setup.bash
+roscore
+echo "...attemp complete."
diff --git a/web_interface/html/bashscripts/rosnodeList.sh b/web_interface/html/bashscripts/rosnodeList.sh
new file mode 100755
index 0000000000000000000000000000000000000000..bec3e55d01fa9712e20548db963a00ec5c828e9a
--- /dev/null
+++ b/web_interface/html/bashscripts/rosnodeList.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+source /opt/ros/melodic/setup.bash
+rosnode list
\ No newline at end of file
diff --git a/web_interface/html/bashscripts/updatewebinterface.sh b/web_interface/html/bashscripts/updatewebinterface.sh
new file mode 100755
index 0000000000000000000000000000000000000000..3c82c1028c0936ca734a2ead8a8cb3dfaa8bb04c
--- /dev/null
+++ b/web_interface/html/bashscripts/updatewebinterface.sh
@@ -0,0 +1,133 @@
+#!/bin/bash
+#
+# Inform the user
+echo "Now starting the \"updatewebinterface.sh\" shell script"
+echo ""
+#
+# Put the web home as a variable
+wwwhome="/var/www/html"
+#
+# Put the dfall home as a variable
+dfallhome="/home/www-share/dfall/dfall-system/web_interface/html"
+#
+# Inform the user of the directories
+echo "Using the following directories:"
+echo ">> wwwhome = $wwwhome"
+echo ">> dfallhome = $dfallhome"
+echo ""
+#
+# Change directory to the web home
+cd $wwwhome
+echo "Changed directory to $wwwhome"
+echo ""
+#
+#
+#
+# REMOVE the contents of the js folder
+rm -v js/*.js
+echo "Removed the \"*.js\" contents of the \"js\" folder"
+rm -v js/*
+echo "Removed any other contents of the \"js\" folder"
+rmdir -v js
+echo "Removed the \"js\" folder"
+echo ""
+#
+# Make the javacript folder again
+mkdir -v js
+echo "Remade the \"js\" folder"
+# Copy the javscripts files
+cp -v $dfallhome"/js/"*.js $wwwhome"/js/"
+echo "Copied across the \"js\" folder contents"
+echo ""
+#
+#
+#
+# REMOVE the contents of the img folder
+rm -v img/*.*
+echo "Removed the \"*.*\" contents of the \"img\" folder"
+rm -v img/*
+echo "Removed any other contents of the \"img\" folder"
+rmdir -v img
+echo "Removed the \"img\" folder"
+echo ""
+#
+# Make the img folder again
+mkdir -v img
+echo "Remade the \"img\" folder"
+# Copy the img files
+cp -v $dfallhome"/img/"*.* $wwwhome"/img/"
+echo "Copied across the \"img\" folder contents"
+echo ""
+#
+#
+#
+# REMOVE the contents of the css folder
+rm -v css/*.css
+echo "Removed the \"*.css\" contents of the \"css\" folder"
+rm -v css/*
+echo "Removed any other contents of the \"css\" folder"
+rmdir -v css
+echo "Removed the \"css\" folder"
+echo ""
+#
+# Make the img folder again
+mkdir -v css
+echo "Remade the \"css\" folder"
+# Copy the img files
+cp -v $dfallhome"/css/"*.css $wwwhome"/css/"
+echo "Copied across the \"css\" folder contents"
+echo ""
+#
+#
+#
+# REMOVE the contents of the bashscripts folder
+rm -v bashscripts/*.sh
+echo "Removed all the contents of the \"bashscripts\" folder"
+rmdir -v bashscripts
+echo "Removed the \"bashscripts\" folder"
+echo ""
+#
+# Make the img folder again
+mkdir -v bashscripts
+echo "Remade the \"bashscripts\" folder"
+# Copy the bashscript files
+cp -v $dfallhome"/bashscripts/"*.sh $wwwhome"/bashscripts/"
+echo "Copied across the \"bashscripts\" folder contents"
+echo ""
+#
+#
+#
+# Remove the "uploads" folder, if it exists
+rm -v uploads/*
+echo "Removed all contents of the \"uploads\" folder"
+rmdir -v uploads
+echo "Removed the \"uploads\" folder"
+echo ""
+#
+# Make the uploads folder again
+mkdir -v uploads
+echo "Remade the \"uploads\" folder"
+echo ""
+#
+#
+#
+# REMOVE the contents of the wwwhome folder
+rm -v *.php
+rm -v *.html
+rm -v *.*
+echo "Removed all the contents of the \"wwwhome\" folder"
+echo ""
+#
+# Copy the html files
+cp -v $dfallhome"/"*.html $wwwhome"/"
+echo "Copied across the \"*.html\" files"
+echo ""
+# Copy the php files
+cp -v $dfallhome"/"*.php $wwwhome"/"
+echo "Copied across the \"*.php\" files"
+echo ""
+#
+#
+#
+# Add write access for the group to all files
+#chmod -R g+rw $wwwhome
diff --git a/web_interface/html/callBashScript.php b/web_interface/html/callBashScript.php
new file mode 100644
index 0000000000000000000000000000000000000000..c3b7401da1783e312ee76e0c0114ebbea26619eb
--- /dev/null
+++ b/web_interface/html/callBashScript.php
@@ -0,0 +1,102 @@
+<?php
+	// Get the bash script name
+	$scriptname = $_GET['scriptname']; 
+
+	// ONLY EXECUTE NAMES WITH AN EXACT MATHC
+
+	
+	// For the GIT tab
+	if ($scriptname == "gitStatus") {
+		$temp = shell_exec("./bashscripts/gitStatus.sh");
+		$output = "<pre>$temp</pre>";
+	}
+	elseif ($scriptname == "gitPull") {
+		$temp = shell_exec("./bashscripts/gitPull.sh");
+		$output = "<pre>$temp</pre>";
+	}
+	elseif ($scriptname == "gitDiff") {
+		$temp = shell_exec("./bashscripts/gitDiff.sh");
+		$output = "<pre>$temp</pre>";
+	}
+	elseif ($scriptname == "gitCheckoutAll") {
+		$temp = shell_exec("./bashscripts/gitCheckoutAll.sh");
+		$output = "<pre>$temp</pre>";
+	}
+	elseif ($scriptname == "gitCheckoutMaster") {
+		$temp = shell_exec("./bashscripts/gitCheckoutMaster.sh");
+		$output = "<pre>$temp</pre>";
+	}
+	elseif ($scriptname == "catkin_make") {
+		$temp = shell_exec("./bashscripts/catkin_make.sh");
+		$output = "<pre>$temp</pre>";
+	}
+	//
+	// For the LAUNCH tab
+	elseif ($scriptname == "checkForRosMaster") {
+		$output = shell_exec("./bashscripts/checkForRosMaster.sh");
+	}
+	//
+	// "launch Ros Master" is handled separately
+	// because it requires an input argument
+	//
+	elseif ($scriptname == "killRosMaster") {
+		$output = shell_exec("./bashscripts/killRosMaster.sh");
+	}
+	elseif ($scriptname == "checkForRosAgent") {
+		$output = shell_exec("./bashscripts/checkForRosAgent.sh");
+	}
+	//
+	// "launch Ros Agent" is handled separately
+	// because it requires an input argument
+	//
+	elseif ($scriptname == "killRosAgent") {
+		$output = shell_exec("./bashscripts/killRosAgent.sh");
+	}
+	elseif ($scriptname == "rosnodeList") {
+		$temp = shell_exec("./bashscripts/rosnodeList.sh");
+		$output = "<pre>$temp</pre>";
+	}
+	//
+	// For the CONTROL tab:
+	// { RADIO CONNECTION, TAKE-OFF, LAND, MOTORS-OFF, LOAD CONTROLLER }
+	elseif ($scriptname == "rosConnect") {
+		$output = shell_exec("./bashscripts/rosCrazyRadioCommand_forAgent.sh 0");
+	}
+	elseif ($scriptname == "rosDisconnect") {
+		$output = shell_exec("./bashscripts/rosCrazyRadioCommand_forAgent.sh 1");
+	}
+	elseif ($scriptname == "rosTakeoff") {
+		$output = shell_exec("./bashscripts/rosFlyingStateCommand_forAgent.sh 11");
+	}
+	elseif ($scriptname == "rosLand") {
+		$output = shell_exec("./bashscripts/rosFlyingStateCommand_forAgent.sh 12");
+	}
+	elseif ($scriptname == "rosMotorsoff") {
+		$output = shell_exec("./bashscripts/rosFlyingStateCommand_forAgent.sh 13");
+	}
+	elseif ($scriptname == "rosEnabledefault") {
+		$output = shell_exec("./bashscripts/rosFlyingStateCommand_forAgent.sh 1");
+	}
+	elseif ($scriptname == "rosEnablestudent") {
+		$output = shell_exec("./bashscripts/rosFlyingStateCommand_forAgent.sh 3");
+	}
+	// For the CONTROL tab:
+	// GET SETPOINT
+	elseif ($scriptname == "rosGetSetpointDefault") {
+		$output = shell_exec("./bashscripts/rosGetCurrentSetpoint_forAgent.sh default");
+	}
+	elseif ($scriptname == "rosGetSetpointStudent") {
+		$output = shell_exec("./bashscripts/rosGetCurrentSetpoint_forAgent.sh student");
+	}
+	// For the CONTROL tab:
+	// LOAD YAML PARAMETERS
+	elseif ($scriptname == "rosLoadYamlDefault") {
+		$output = shell_exec("./bashscripts/rosLoadYaml_forAgent.sh default");
+	}
+	elseif ($scriptname == "rosLoadYamlStudent") {
+		$output = shell_exec("./bashscripts/rosLoadYaml_forAgent.sh student");
+	}
+
+
+	echo "$output";
+?>
diff --git a/web_interface/html/callBashScript_roslaunch.php b/web_interface/html/callBashScript_roslaunch.php
new file mode 100644
index 0000000000000000000000000000000000000000..bca63740adedd618bd5286582927aafabd45160d
--- /dev/null
+++ b/web_interface/html/callBashScript_roslaunch.php
@@ -0,0 +1,60 @@
+<?php
+	// GET THE BASH SCRIPT NAME
+	$scriptname = $_GET['scriptname'];
+
+	// ONLY EXECUTE "SCRIPT NAMES" WITH AN EXACT MATCH
+	//
+	// > For the MASTER
+	if ($scriptname == "master")
+	{
+		// GET THE VALUES OF THE EMULATE MOCAP FLAG
+		// > This will be a string
+		$emulate_mocap = strtolower( $_GET['emulatemocap'] );
+		// Check that the new setpoint values are numerical
+		if (in_array($emulate_mocap, array("true", "1", "yes"), true))
+		{
+			$emulate_mocap = "true";
+		}
+		elseif (in_array($emulate_mocap, array("false", "0", "no"), true))
+		{
+			$emulate_mocap = "false";
+		}
+		else
+		{
+			echo "emulate mocap flag = $emulate_mocap, is not a boolean value.";
+			exit();
+		}
+		// Call the bash script for launching the master
+		$output = shell_exec("./bashscripts/launchRosMaster.sh $emulate_mocap");
+	}
+	//
+	// > For the AGENT
+	elseif ($scriptname == "agent")
+	{
+		// GET THE VALUES OF THE EMULATE MOCAP FLAG
+		// > This will be a string
+		$emulate_crazyradio = strtolower( $_GET['emulatecrazyradio'] );
+		// Check that the new setpoint values are numerical
+		if (in_array($emulate_crazyradio, array("true", "1", "yes"), true))
+		{
+			$emulate_crazyradio = "true";
+		}
+		elseif (in_array($emulate_crazyradio, array("false", "0", "no"), true))
+		{
+			$emulate_crazyradio = "false";
+		}
+		else
+		{
+			echo "emulate crazyradio flag = $emulate_crazyradio, is not a boolean value.";
+			exit();
+		}
+		// Call the bash script for launching the agent
+		$output = shell_exec("./bashscripts/launchRosAgent.sh $emulate_crazyradio");
+	}
+	else
+	{
+		$output = "launch name = $scriptname is not a valid option";
+	}
+
+	echo "$output";
+?>
diff --git a/web_interface/html/callBashScript_setNewSetpoint.php b/web_interface/html/callBashScript_setNewSetpoint.php
new file mode 100644
index 0000000000000000000000000000000000000000..2e44ae0c6df7e69af0ffe15b82028f21c14bba6c
--- /dev/null
+++ b/web_interface/html/callBashScript_setNewSetpoint.php
@@ -0,0 +1,47 @@
+<?php
+	// GET THE BASH SCRIPT NAME
+	$scriptname = $_GET['scriptname'];
+
+	// GET THE (x,y,z,yaw) VALUES OF THE NEW SETPOINT
+	// > These will be strings
+	$x_new = $_GET['x'];
+	$y_new = $_GET['y'];
+	$z_new = $_GET['z'];
+	$yaw_new = $_GET['yaw'];
+
+
+	// Check that the new setpoint values are numerical
+	if ( ! (is_numeric($x_new)) )
+	{
+		echo "x = $x_new, is not a numeric value.";
+		exit();
+	}
+	if ( ! (is_numeric($y_new)) )
+	{
+		echo "y = $y_new, is not a numeric value.";
+		exit();
+	}
+	if ( ! (is_numeric($z_new)) )
+	{
+		echo "z = $z_new, is not a numeric value.";
+		exit();
+	}
+	if ( ! (is_numeric($yaw_new)) )
+	{
+		echo "yaw = $yaw_new, is not a numeric value.";
+		exit();
+	}
+
+	// ONLY EXECUTE "SCRIPT NAMES" WITH AN EXACT MATCH
+	// For the CONTROL tab:
+	// GET SETPOINT
+	if ($scriptname == "rosSetSetpointDefault") {
+		$output = shell_exec("./bashscripts/rosSetNewSetpoint_forAgent.sh default $x_new $y_new $z_new $yaw_new");
+	}
+	elseif ($scriptname == "rosSetSetpointStudent") {
+		$output = shell_exec("./bashscripts/rosSetNewSetpoint_forAgent.sh student $x_new $y_new $z_new $yaw_new");
+	}
+
+
+	echo "$output";
+?>
diff --git a/web_interface/html/css/body.css b/web_interface/html/css/body.css
new file mode 100644
index 0000000000000000000000000000000000000000..021b02f565784c7234f6f53c110dcd96715dcfca
--- /dev/null
+++ b/web_interface/html/css/body.css
@@ -0,0 +1,112 @@
+/* RESTRICT PAGE WIDTH TO A MAXIMUM */
+.body-container
+{
+	position:      relative;
+	margin-top:    0px;
+	margin-bottom: 0px;
+	margin-left:   0px;
+	margin-right:  0px;
+	max-width:     800px;
+	padding:       0px;
+}
+
+
+/* MAIN STYLE */
+.body-container > main
+{
+	color: black;
+	font-family: 'Lato', Arial, sans-serif;
+	font-weight: 400;
+	margin-top:     0px;
+	margin-bottom:  0px;
+	margin-left:    0px;
+	margin-right:   0px;
+	padding-top:    0.2em;
+	padding-bottom: 1em;
+	padding-left:   30px;
+	padding-right:  30px;
+	text-align: left;
+	background: rgba(0,0,0,0.0);
+}
+
+.body-container > main a
+{
+	color: #a5d0ff;
+	text-decoration: none;
+	outline: none;
+}
+
+.body-container > main a:hover
+{
+	color: #60abff;
+}
+
+.body-container > main h1
+{
+	font-size: 3.2em;
+	line-height: 1.3;
+	margin: 0px;
+	font-weight: 350;
+}
+
+.body-container > main h2
+{
+	font-size: 1.4em;
+	line-height: 1.3;
+	margin: 0px;
+	padding-top: 0.1em;
+	padding-bottom: 0.2em;
+	padding-left: 20px;
+	padding-right: 20px;
+	font-weight: 400;
+}
+
+.body-container > main span
+{
+	display: block;
+	font-size: 55%;
+	color: black;
+	padding: 0 0 0.6em 0.1em;
+}
+
+.hr-basic
+{
+	background-color: white;
+	width: 100%;
+	height: 2px;
+	border: 0px solid black;
+}
+
+.hr-basic.navy
+{
+	background-color: #34495E;
+}
+
+
+/* SETTINGS FOR WHEN THE SCREEN IS SMALL */
+/* IMPORTANT NOTES:
+   The <meta> tag in the <head> of the page is
+   very important for determining the behaviour
+   this media trigger, i.e., the tag:
+   <meta name="viewport" content="width=device-width, initial-scale=1.0">
+   For example, with this tag the iPhone SE has
+   a "max-width"=320 and the same font sizes work
+   (approximately) on both a computer/laptop
+   browser and a smartphone browser. Whereas,
+   without this tag the iPhone SE has a
+   "mx-width"=768 and the sizes are much too small
+   when viewed on a smartphone.
+*/
+@media screen and (max-width: 420px)
+{
+	.body-container > main
+	{
+		padding-top:    0.2em;
+		padding-bottom: 1em;
+		padding-left:   0px;
+		padding-right:  0px;
+		font-size: 100%;
+		text-align: left;
+		//background: rgba(0,255,0,1.0);
+	}
+}
diff --git a/web_interface/html/css/buttons.css b/web_interface/html/css/buttons.css
new file mode 100644
index 0000000000000000000000000000000000000000..c69685cb5a59749b9a32dca80ac5773b99cd3050
--- /dev/null
+++ b/web_interface/html/css/buttons.css
@@ -0,0 +1,344 @@
+.button-push
+{
+	position: relative;
+	background-color: #ddd;
+	border: 1px solid #bbb;
+	border-radius: 6px;
+	color: #555;
+	text-shadow: 0 1px 0 rgba(0,0,0,.2);
+	margin:          0px;
+	padding-left:   30px;
+	padding-right:  30px;
+	padding-top:    15px;
+	padding-bottom: 15px;
+	text-align: center;
+	text-decoration: none;
+	display: inline-block;
+	font-size: 1.4em;
+	cursor: grabbing;
+
+	overflow: hidden;
+}
+
+
+.button-push:hover
+{
+	background-color: #eee;
+}
+
+.button-push:active
+{
+	background: #e9e9e9;
+	top: 1px;
+	text-shadow: none;
+	box-shadow: 0 1px 1px rgba(0, 0, 0, .3) inset;
+
+	
+}
+
+.button-push > .div-for-button-highlight-on-touchscreen
+{
+	content: "test";
+    position: absolute;
+    top: 0;
+    left: 0;
+    height: 100%;
+    width: 100%;
+    padding-bottom: 0;
+    border-radius: 0px;
+    background-color: #000;
+    transform: scale(1.0);
+    opacity: 0.0;
+}
+
+
+.div-for-button-highlight-on-touchscreen.red{   background-color: #000;}
+.div-for-button-highlight-on-touchscreen.green{ background-color: #000;}
+.div-for-button-highlight-on-touchscreen.blue{  background-color: #000;}
+.div-for-button-highlight-on-touchscreen.navy{  background-color: #eee;}
+
+
+/* THE FOLLOWING ACTUALLY ADDS THE ANIMATION */
+/*
+.button-push:focus:not(:active) > .div-for-button-highlight-on-touchscreen
+{
+	animation: click-animation 0.6s linear;
+	animation-fill-mode: backwards;
+}
+*/
+
+@keyframes click-animation {
+  0% {
+    opacity: 0.2;
+    transform: scale(1.0);
+  }
+  50% {
+    opacity: 0.50;
+    transform: scale(1.0);
+  }
+  70% {
+    opacity: 0.5;
+    transform: scale(1.0);
+  }
+  100% {
+    opacity: 0;
+    transform: scale(1.0);
+  }
+}
+
+
+
+
+
+
+
+
+
+/* SET THE DISPLAY STYLE TO BLOCK */
+.button-push.fullwidth
+{
+	display: block;
+	width: 100%;
+}
+
+/* SET THE FONT TO A FIXED WIDTH FONT */
+.button-push.monospace
+{
+	font-family: monospace;
+}
+
+/* SET THE TOP AND BOTTOM SPACING TO BE SMALL */
+.button-push.short
+{
+	padding-top:    3px;
+	padding-bottom: 3px;
+}
+.button-push.short5
+{
+	padding-top:    5px;
+	padding-bottom: 5px;
+}
+.button-push.short10
+{
+	padding-top:    5px;
+	padding-bottom: 5px;
+}
+
+/* SET THE LEFT AND RIGHT SPACING TO BE SMALL */
+.button-push.slim
+{
+	padding-left:  10px;
+	padding-right: 10px;
+}
+
+/* SET SIZING FOR THE MOTORS-OFF BUTTON */
+.button-push.motorsoff
+{
+	display: block;
+	width: 100%;
+	text-align: center;
+	font-weight: 600;
+}
+
+/* SET SIZING FOR THE MOTORS-OFF BUTTON */
+.button-push.info
+{
+	display: inline
+	width: 100%;
+	text-align: center;
+	font-weight: bolder;
+	font-size: 24px!important;
+	padding: 8px 20px;
+	vertical-align: middle;
+	overflow: hidden;
+	text-decoration: none;
+	white-space:nowrap;
+	border-radius: 50%;
+}
+
+
+
+
+
+/* SET THE APPEARANCE FOR WHEN DISABLED */
+.button-push[disabled], .button-push[disabled]:hover, .button-push[disabled]:active
+{
+	border-color: #eaeaea;
+	background: #fafafa;
+	cursor: default;
+	position: static;
+	color: #999;
+	/* Usually, !important should be avoided but here it's really needed :) */
+	/*
+	-moz-box-shadow: none !important;
+	-webkit-box-shadow: none !important;
+	box-shadow: none !important;
+	text-shadow: none !important;
+	*/
+	
+}
+
+
+/* SET COLOURS FOR RED BUTTON */
+.button-push.red
+{
+	background-color: #f44336;
+	border-color: #c43c35;
+	color: white;
+}
+
+.button-push.red:hover
+{
+	background-color: #ee5f5b;
+}
+
+.button-push.red:active
+{
+	background: #c43c35;
+}
+
+.red[disabled], .red[disabled]:hover, .red[disabled]:active
+{
+	border-color: #C43C35;
+	background: #C43C35;
+	color: #FFD3D3;
+}
+
+
+/* SET COLOURS FOR GREEN BUTTON */
+.button-push.green
+{
+	background-color: #57a957;
+	border-color: #57a957;
+	color: white;
+}
+
+.button-push.green:hover
+{
+	background-color: #62c462;
+}
+
+.button-push.green:active
+{
+	background: #57a957;
+}
+
+.green[disabled], .green[disabled]:hover, .green[disabled]:active
+{
+	border-color: #57A957;
+	background: #57A957;
+	color: #D2FFD2;
+}
+
+
+/* SET COLOURS FOR BLUE BUTTON */
+.button-push.blue
+{
+	background-color: #269CE9;
+	border-color: #269CE9;
+	color: white;
+}
+
+.button-push.blue:hover
+{
+	background-color: #70B9E8;
+}
+
+.button-push.blue:active
+{
+	background: #269CE9;
+}
+
+.blue[disabled], .blue[disabled]:hover, .blue[disabled]:active
+{
+	border-color: #269CE9;
+	background: #269CE9;
+	color: #93D5FF;
+}
+
+/* SET COLOURS FOR NAVY BUTTON */
+.button-push.navy
+{
+	background-color: #34495E;
+	border-color: #34495E;
+	color: white;
+}
+
+.button-push.navy:hover
+{
+	background-color: #748DA6;
+}
+
+.button-push.navy:active
+{
+	background: #34495E;
+}
+
+.navy[disabled], .navy[disabled]:hover, .navy[disabled]:active
+{
+	border-color: #34495E;
+	background: #34495E;
+	color: #93D5FF;
+}
+
+
+
+
+/* SETTINGS FOR WHEN THE SCREEN IS SMALL */
+@media screen and (max-width: 420px)
+{
+	.button-push
+	{
+		padding-left:   10px;
+		padding-right:  10px;
+		padding-top:    10px;
+		padding-bottom: 10px;
+		font-size: 1.2em;
+	}
+
+	.button-push.info
+	{
+		font-size: 28px!important;
+		padding: 8px 20px;
+	}
+
+	/* MAKE THE HOVER COLOUR THE SAME AS THE NORMAL COLOUR */
+	.button-push:hover{       background-color: #ddd;   }
+	.button-push.red:hover{   background-color: #f44336;}
+	.button-push.green:hover{ background-color: #57a957;}
+	.button-push.blue:hover{  background-color: #269CE9;}
+	.button-push.navy:hover{  background-color: #34495E;}
+
+	/* SET THE DISABLED HOVER COLOUR */
+	/* NEEDED AGAIN DESPITE BEING DONE ABOVE */
+	.red[disabled]:hover
+	{
+		border-color: #C43C35;
+		background: #C43C35;
+		color: #FFD3D3;
+	}
+	.green[disabled]:hover
+	{
+		border-color: #57A957;
+		background: #57A957;
+		color: #D2FFD2;
+	}
+	.blue[disabled]:hover
+	{
+		border-color: #269CE9;
+		background: #269CE9;
+		color: #93D5FF;
+	}
+	.navy[disabled]:hover
+	{
+		border-color: #34495E;
+		background: #34495E;
+		color: #93D5FF;
+	}
+
+	.button-push:hover:not(:active) > .div-for-button-highlight-on-touchscreen
+	{
+		animation: click-animation 0.7s ease-out;
+	}
+
+}
diff --git a/web_interface/html/css/buttons_from_some_website.css b/web_interface/html/css/buttons_from_some_website.css
new file mode 100644
index 0000000000000000000000000000000000000000..54e8dbe95480bf955682afaa6778da9559ec3aaa
--- /dev/null
+++ b/web_interface/html/css/buttons_from_some_website.css
@@ -0,0 +1,250 @@
+/*
+  TAKEN FROM:
+  https://codepen.io/ben_jammin/pen/syaCq
+*/
+
+/*
+body{ 
+    background:url(http://subtlepatterns.subtlepatterns.netdna-cdn.com/patterns/wild_oliva.png);
+}
+*/
+
+.centered {
+  margin:50px auto;
+  text-align:center;
+}
+
+.button::-moz-focus-inner{
+  border: 0;
+  padding: 0;
+}
+
+.button{
+  display: inline-block;
+  *display: inline;
+  zoom: 1;
+  padding: 6px 20px;
+  margin: 0;
+  cursor: pointer;
+  border: 1px solid #bbb;
+  overflow: visible;
+  font: bold 13px arial, helvetica, sans-serif;
+  text-decoration: none;
+  white-space: nowrap;
+  color: #555;
+
+  background-color: #ddd;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255,255,255,1)), to(rgba(255,255,255,0)));
+  background-image: -webkit-linear-gradient(top, rgba(255,255,255,1), rgba(255,255,255,0));
+  background-image: -moz-linear-gradient(top, rgba(255,255,255,1), rgba(255,255,255,0));
+  background-image: -ms-linear-gradient(top, rgba(255,255,255,1), rgba(255,255,255,0));
+  background-image: -o-linear-gradient(top, rgba(255,255,255,1), rgba(255,255,255,0));
+  background-image: linear-gradient(top, rgba(255,255,255,1), rgba(255,255,255,0));
+
+  -webkit-transition: background-color .2s ease-out;
+  -moz-transition: background-color .2s ease-out;
+  -ms-transition: background-color .2s ease-out;
+  -o-transition: background-color .2s ease-out;
+  transition: background-color .2s ease-out;
+  background-clip: padding-box; /* Fix bleeding */
+  -moz-border-radius: 3px;
+  -webkit-border-radius: 3px;
+  border-radius: 3px;
+  -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, .3), 0 2px 2px -1px rgba(0, 0, 0, .5), 0 1px 0 rgba(255, 255, 255, .3) inset;
+  -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, .3), 0 2px 2px -1px rgba(0, 0, 0, .5), 0 1px 0 rgba(255, 255, 255, .3) inset;
+  box-shadow: 0 1px 0 rgba(0, 0, 0, .3), 0 2px 2px -1px rgba(0, 0, 0, .5), 0 1px 0 rgba(255, 255, 255, .3) inset;
+  text-shadow: 0 1px 0 rgba(255,255,255, .9);
+
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -khtml-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.button:hover{
+  background-color: #eee;
+  color: #555;
+}
+
+.button:active{
+  background: #e9e9e9;
+  position: relative;
+  top: 1px;
+  text-shadow: none;
+  -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, .3) inset;
+  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .3) inset;
+  box-shadow: 0 1px 1px rgba(0, 0, 0, .3) inset;
+}
+
+.button[disabled], .button[disabled]:hover, .button[disabled]:active{
+  border-color: #eaeaea;
+  background: #fafafa;
+  cursor: default;
+  position: static;
+  color: #999;
+  /* Usually, !important should be avoided but here it's really needed :) */
+  -moz-box-shadow: none !important;
+  -webkit-box-shadow: none !important;
+  box-shadow: none !important;
+  text-shadow: none !important;
+}
+
+/* Smaller buttons styles */
+
+.button.small{
+  padding: 4px 12px;
+}
+
+/* Larger buttons styles */
+
+.button.large{
+  padding: 12px 30px;
+  text-transform: uppercase;
+}
+
+.button.large:active{
+  top: 2px;
+}
+
+/* Colored buttons styles */
+
+.button.green, .button.red, .button.blue {
+  color: #fff;
+  text-shadow: 0 1px 0 rgba(0,0,0,.2);
+  
+  background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255,255,255,.3)), to(rgba(255,255,255,0)));
+  background-image: -webkit-linear-gradient(top, rgba(255,255,255,.3), rgba(255,255,255,0));
+  background-image: -moz-linear-gradient(top, rgba(255,255,255,.3), rgba(255,255,255,0));
+  background-image: -ms-linear-gradient(top, rgba(255,255,255,.3), rgba(255,255,255,0));
+  background-image: -o-linear-gradient(top, rgba(255,255,255,.3), rgba(255,255,255,0));
+  background-image: linear-gradient(top, rgba(255,255,255,.3), rgba(255,255,255,0));
+}
+
+/* */
+
+.button.green{
+  background-color: #57a957;
+  border-color: #57a957;
+}
+
+.button.green:hover{
+  background-color: #62c462;
+}
+
+.button.green:active{
+  background: #57a957;
+}
+
+/* */
+
+.button.red{
+  background-color: #ca3535;
+  border-color: #c43c35;
+}
+
+.button.red:hover{
+  background-color: #ee5f5b;
+}
+
+.button.red:active{
+  background: #c43c35;
+}
+
+/* */
+
+.button.blue{
+  background-color: #269CE9;
+  border-color: #269CE9;
+}
+
+.button.blue:hover{
+  background-color: #70B9E8;
+}
+
+.button.blue:active{
+  background: #269CE9;
+}
+
+/* */
+
+.green[disabled], .green[disabled]:hover, .green[disabled]:active{
+  border-color: #57A957;
+  background: #57A957;
+  color: #D2FFD2;
+}
+
+.red[disabled], .red[disabled]:hover, .red[disabled]:active{
+  border-color: #C43C35;
+  background: #C43C35;
+  color: #FFD3D3;
+}
+
+.blue[disabled], .blue[disabled]:hover, .blue[disabled]:active{
+  border-color: #269CE9;
+  background: #269CE9;
+  color: #93D5FF;
+}
+
+/* Group buttons */
+
+.button-group,
+.button-group li{
+  display: inline-block;
+  *display: inline;
+  zoom: 1;
+}
+
+.button-group{
+  font-size: 0; /* Inline block elements gap - fix */
+  margin: 0;
+  padding: 0;
+  background: rgba(0, 0, 0, .1);
+  border-bottom: 1px solid rgba(0, 0, 0, .1);
+  padding: 7px;
+  -moz-border-radius: 7px;
+  -webkit-border-radius: 7px;
+  border-radius: 7px;
+}
+
+.button-group li{
+  margin-right: -1px; /* Overlap each right button border */
+}
+
+.button-group .button{
+  font-size: 13px; /* Set the font size, different from inherited 0 */
+  -moz-border-radius: 0;
+  -webkit-border-radius: 0;
+  border-radius: 0;
+}
+
+.button-group .button:active{
+  -moz-box-shadow: 0 0 1px rgba(0, 0, 0, .2) inset, 5px 0 5px -3px rgba(0, 0, 0, .2) inset, -5px 0 5px -3px rgba(0, 0, 0, .2) inset;
+  -webkit-box-shadow: 0 0 1px rgba(0, 0, 0, .2) inset, 5px 0 5px -3px rgba(0, 0, 0, .2) inset, -5px 0 5px -3px rgba(0, 0, 0, .2) inset;
+  box-shadow: 0 0 1px rgba(0, 0, 0, .2) inset, 5px 0 5px -3px rgba(0, 0, 0, .2) inset, -5px 0 5px -3px rgba(0, 0, 0, .2) inset;
+}
+
+.button-group li:first-child .button{
+  -moz-border-radius: 3px 0 0 3px;
+  -webkit-border-radius: 3px 0 0 3px;
+  border-radius: 3px 0 0 3px;
+}
+
+.button-group li:first-child .button:active{
+  -moz-box-shadow: 0 0 1px rgba(0, 0, 0, .2) inset, -5px 0 5px -3px rgba(0, 0, 0, .2) inset;
+  -webkit-box-shadow: 0 0 1px rgba(0, 0, 0, .2) inset, -5px 0 5px -3px rgba(0, 0, 0, .2) inset;
+  box-shadow: 0 0 1px rgba(0, 0, 0, .2) inset, -5px 0 5px -3px rgba(0, 0, 0, .2) inset;
+}
+
+.button-group li:last-child .button{
+  -moz-border-radius: 0 3px 3px 0;
+  -webkit-border-radius: 0 3px 3px 0;
+  border-radius: 0 3px 3px 0;
+}
+
+.button-group li:last-child .button:active{
+  -moz-box-shadow: 0 0 1px rgba(0, 0, 0, .2) inset, 5px 0 5px -3px rgba(0, 0, 0, .2) inset;
+  -webkit-box-shadow: 0 0 1px rgba(0, 0, 0, .2) inset, 5px 0 5px -3px rgba(0, 0, 0, .2) inset;
+  box-shadow: 0 0 1px rgba(0, 0, 0, .2) inset, 5px 0 5px -3px rgba(0, 0, 0, .2) inset;
+}
\ No newline at end of file
diff --git a/web_interface/html/css/debug_values_table.css b/web_interface/html/css/debug_values_table.css
new file mode 100644
index 0000000000000000000000000000000000000000..81e5fef1c21631861d2121933428323b406b80c5
--- /dev/null
+++ b/web_interface/html/css/debug_values_table.css
@@ -0,0 +1,91 @@
+.debug-values-table
+{
+	margin-left: auto;
+	margin-right: auto;
+	padding: 0;
+	border-collapse: collapse;
+	table-layout: fixed;
+	//border: 1px solid black;
+	//border-left: 2px solid black;
+}
+
+.debug-values-column-title-cell
+{
+	margin: 0;
+	padding-left:   10px;
+	padding-right:  10px;
+	padding-top:     2px;
+	padding-bottom:  2px;
+	font-size: 1.4em;
+	font-weight: bold;
+	text-align: center;
+	border: 1px solid black;
+}
+
+.debug-values-row-title-cell
+{
+	margin: 0;
+	padding-left:   10px;
+	padding-right:  10px;
+	padding-top:     2px;
+	padding-bottom:  2px;
+	font-size: 1.4em;
+	font-weight: bold;
+	text-align: center;
+	border: 1px solid black;
+}
+
+.debug-values-data-cell
+{
+	margin: 0;
+	padding-left:   10px;
+	padding-right:  10px;
+	padding-top:     2px;
+	padding-bottom:  2px;
+	font-size: 1.4em;
+	font-weight: normal;
+	font-family: monospace;
+	text-align: right;
+	border: 1px solid black;
+}
+
+.debug-values-caption-below
+{
+	margin: 0;
+	padding-left:   5px;
+	padding-right:  5px;
+	padding-top:    5px;
+	padding-bottom: 2px;
+	font-size: 1.2em;
+	font-weight: normal;
+	text-align: left;
+	//border: 1px solid black;
+}
+
+
+
+
+
+/* SETTINGS FOR WHEN THE SCREEN IS SMALL */
+@media screen and (max-width: 420px)
+{
+	.debug-values-column-title-cell
+	{
+		font-size: 1.2em;
+	}
+
+	.debug-values-row-title-cell
+	{
+		font-size: 1.2em;
+	}
+
+	.debug-values-data-cell
+	{
+		font-size: 1.2em;
+	}
+
+	.debug-values-caption-below
+	{
+		font-size: 1.0em;
+	}
+}
diff --git a/web_interface/html/css/default.css b/web_interface/html/css/default.css
new file mode 100644
index 0000000000000000000000000000000000000000..036f5f4219b938d58b38f083aef8b0d4da57b95b
--- /dev/null
+++ b/web_interface/html/css/default.css
@@ -0,0 +1,8 @@
+/* IMPORT THE FONT */
+@import url(https://fonts.googleapis.com/css?family=Lato:300,400,700);
+
+/* SET THE BACKGROUND COLOUR */
+body
+{
+	background: #34495e;
+}
\ No newline at end of file
diff --git a/web_interface/html/css/fileinput.css b/web_interface/html/css/fileinput.css
new file mode 100644
index 0000000000000000000000000000000000000000..43927246f37ed7b96e8075bf406dc560e5d6fdb6
--- /dev/null
+++ b/web_interface/html/css/fileinput.css
@@ -0,0 +1,62 @@
+.file-input-label
+{
+	margin:          0px;
+	padding-left:    0px;
+	padding-right:   0px;
+	padding-top:    10px;
+	padding-bottom: 10px;
+	text-align: left;
+	text-decoration: none;
+	display: inline-block;
+	font-size: 1.4em;
+}
+
+.file-input
+{
+	margin:          0px;
+	padding-left:    0px;
+	padding-right:   0px;
+	padding-top:    10px;
+	padding-bottom: 10px;
+	text-align: left;
+	text-decoration: none;
+	display: inline-block;
+	font-size: 1.0em;
+}
+
+.file-upload-status-div
+{
+	margin:          0px;
+	padding-left:    0px;
+	padding-right:   0px;
+	padding-top:    10px;
+	padding-bottom: 10px;
+	text-align: left;
+	text-decoration: none;
+	display: inline-block;
+	font-size: 1.0em;
+}
+
+.file-input-details-div
+{
+	margin:          0px;
+	padding-left:    0px;
+	padding-right:   0px;
+	padding-top:    10px;
+	padding-bottom: 10px;
+	text-align: left;
+	text-decoration: none;
+	display: inline-block;
+	font-size: 1.0em;
+}
+
+
+
+
+
+
+/* SETTINGS FOR WHEN THE SCREEN IS SMALL */
+@media screen and (max-width: 420px)
+{
+
+}
diff --git a/web_interface/html/css/layout.css b/web_interface/html/css/layout.css
new file mode 100644
index 0000000000000000000000000000000000000000..ec5d25d4b681939373255158aef2662a3572c310
--- /dev/null
+++ b/web_interface/html/css/layout.css
@@ -0,0 +1,356 @@
+.full-window-fixed
+{
+	position: fixed;
+	top: 0;
+	bottom: 0;
+	left: 0;
+  	right: 0;
+	background: #34495E;
+	width: 100%;
+	margin: 0;
+	padding: 0;
+}
+
+.max-width-full-heigth-fixed
+{
+	color: #fff;
+	font-family: 'Lato', Arial, sans-serif;
+	position: fixed;
+	top: 0;
+	bottom: 0;
+	left: 0px;
+	right: 0px;
+	margin-top:    0px;
+	margin-bottom: 0px;
+	margin-left:   auto;
+	margin-right:  auto;
+	max-width: 800px;
+	padding: 0px;
+	background: rgba(0,0,0,0.10);
+}
+
+.top-bar-container
+{
+	color: #fff;
+	font-family: 'Lato', Arial, sans-serif;
+	position: relative;
+	margin-top:    0px;
+	margin-bottom: 0px;
+	margin-left:   0px;
+	margin-right:  0px;
+	max-width: 800px;
+	padding: 0px;
+	background: none;
+}
+
+.top-bar-buttons-table
+{
+	position: relative;
+	width: 100%;
+	border: none;
+	border-spacing: 0px;
+	padding-top:    10px;
+	padding-bottom: 10px;
+	padding-left:   20px;
+	padding-right:  20px;
+	background: none;
+}
+
+.top-bar-motorsoff-button-cell
+{
+	padding-right: 10px;
+}
+
+.top-bar-info-button-cell
+{
+	width: 20px;
+}
+
+.top-bar-title
+{
+	position: relative;
+	width: 100%;
+	text-align: center;
+	font-size: 2.0em;
+	font-weight: 600;
+	padding-top:     0px;
+	padding-bottom:  0px;
+	padding-left:    0px;
+	padding-right:   0px;
+	background: none;
+	white-space: nowrap;
+	overflow-x: hidden;
+}
+.top-bar-title.padbelow
+{
+	padding-bottom: 10px;
+}
+
+.top-bar-subtitle
+{
+	position: relative;
+	width: 100%;
+	text-align: center;
+	font-size: 1.2em;
+	font-weight: 400;
+	padding-top:     0px;
+	padding-bottom:  0px;
+	padding-left:    0px;
+	padding-right:   0px;
+	background: none;
+	white-space: nowrap;
+	overflow-x: hidden;
+}
+
+.top-bar-subtitle.padbelow
+{
+	padding-bottom: 10px;
+}
+
+.top-bar-status-icons
+{
+	position: relative;
+	width: 100%;
+	text-align: center;
+	font-size: 1.2em;
+	font-weight: 400;
+	padding-top:     0px;
+	padding-bottom:  0px;
+	padding-left:    0px;
+	padding-right:   0px;
+	background: none;
+	white-space: nowrap;
+	overflow-x: hidden;
+}
+.top-bar-status-icons.padbelow
+{
+	padding-bottom: 5px;
+}
+
+
+.ros-table
+{
+	position: relative;
+	width: 100%;
+	table-layout: fixed;
+	border-spacing:  0px;
+	padding-top:     0px;
+	padding-bottom:  0px;
+	padding-left:    0px;
+	padding-right:   0px;
+	background: none;
+	//border: 1px solid black;
+}
+
+.ros-button-cell
+{
+	width: 50%;
+	padding-top:    5px;
+	padding-bottom: 5px;
+	padding-left:   0px;
+	padding-right:  0px;
+	//border: 1px solid black;
+}
+
+.ros-info-cell
+{
+	padding-left: 10px;
+	padding-right: 10px;
+	text-align: left;
+	//border: 1px solid black;
+}
+
+
+
+.switch-cell
+{
+	padding-top:    5px;
+	padding-bottom: 5px;
+	padding-left:   0px;
+	padding-right:  0px;
+	text-align: left;
+	//border: 1px solid black;
+}
+
+.switch-cell.pad-right
+{
+	padding-right:  5px;
+}
+
+.switch-cell.pad-left
+{
+	padding-left:   5px;
+}
+
+
+
+.git-table
+{
+	position: relative;
+	width: 100%;
+	table-layout: fixed;
+	border-spacing:  0px;
+	margin:          0px;
+	padding-top:     0px;
+	padding-bottom:  0px;
+	padding-left:    0px;
+	padding-right:   0px;
+	background: none;
+	//border: 1px solid black;
+}
+
+.git-button-cell
+{
+	width: 50%;
+	margin:          0px;
+	padding-top:     5px;
+	padding-bottom:  5px;
+	padding-left:    5px;
+	padding-right:   5px;
+	//border: 1px solid black;
+}
+
+.git-button-cell.left
+{
+	padding-left: 0px;
+}
+
+.git-button-cell.right
+{
+	padding-right: 0px;
+}
+
+
+.git-checkout-label
+{
+	color: #f44336;
+	font-family: monospace;
+	font-size: 1.4em;
+	font-weight: bold;
+	text-align: center;
+	margin-top: 10px;
+}
+
+
+.terminal-label-table
+{
+	position: relative;
+	table-layout: fixed;
+	border-spacing:  0px;
+	margin-left:   auto;
+	margin-right:  auto;
+	margin-bottom: 3px;
+	padding:         0px;
+	background: none;
+	//border: 1px solid black;
+}
+
+.terminal-label-cell
+{
+	padding-right:   5px;
+}
+
+.terminal-label
+{
+	color: #34495E;
+	font-family: monospace;
+	font-size: 1.4em;
+	font-weight: bold;
+	text-align: center;
+}
+
+.terminal-background
+{
+	position: relative;
+	width: 100%;
+	color: white;
+	background-color: #34495E;
+	margin:          0px;
+	padding-top:    10px;
+	padding-bottom: 10px;
+	padding-left:    0px;
+	padding-right:   0px;
+	border-radius:   5px;
+	overflow-x: auto;
+}
+
+.terminal-contents
+{
+	position: relative;
+	color: white;
+	background-color: none;
+	margin-top:     0px;
+	margin-bottom:  0px; 
+	margin-left:    5px; 
+	margin-right:   5px; 
+	padding:        0px;
+}
+
+.terminal-highligh-paragraph
+{
+	color: white;
+	background-color: #269CE9;
+	text-align: center;
+}
+
+.centered-table
+{
+	position: relative;
+	//table-layout: fixed;
+	border-spacing:  0px;
+	padding-top:     0px;
+	padding-bottom:  0px;
+	padding-left:    0px;
+	padding-right:   0px;
+	margin-left: auto;
+	margin-right: auto;
+	background: none;
+	//border: 1px solid black;
+}
+
+.centered-table-button-cell
+{
+	margin:          0px;
+	padding-top:     5px;
+	padding-bottom:  5px;
+	padding-left:    5px;
+	padding-right:   5px;
+	//border: 1px solid black;
+}
+
+
+/* SETTINGS FOR WHEN THE SCREEN IS SMALL */
+@media screen and (max-width: 420px)
+{
+	.top-bar-title
+	{
+		font-size: 1.5em;
+	}
+
+	.top-bar-title.padbelow
+	{
+		padding-bottom: 5px;
+	}
+
+	.top-bar-subtitle
+	{
+		font-size: 1.0em;
+	}
+
+	.top-bar-subtitle.padbelow
+	{
+		padding-bottom: 5px;
+	}
+
+	.ros-button-cell
+	{
+		width: 60%;
+	}
+
+	.terminal-background
+	{
+		width: 86%;
+		margin-left: 7%;
+	}
+
+}
\ No newline at end of file
diff --git a/web_interface/html/css/measurement_setpoint_error_table.css b/web_interface/html/css/measurement_setpoint_error_table.css
new file mode 100644
index 0000000000000000000000000000000000000000..48f0e7fcb54af2ce368cdb126c0f83b95b59cc44
--- /dev/null
+++ b/web_interface/html/css/measurement_setpoint_error_table.css
@@ -0,0 +1,151 @@
+.setpoint-label-cell
+{
+	margin: 0;
+	padding-top:    2px;
+	padding-bottom: 2px;
+	font-size: 1.4em;
+	font-weight: bold;
+	text-align: center;
+}
+
+.setpoint-increment-cell
+{
+	margin: 0;
+	padding-top:    5px;
+	padding-bottom: 5px;
+}
+
+.setpoint-input-field-cell
+{
+	margin: 0;
+	padding-top:    5px;
+	padding-bottom: 5px;
+}
+
+.setpoint-input-field
+{
+	width:7em;
+	margin: 0;
+	padding-top:    5px;
+	padding-bottom: 5px;
+	font-size: 1.4em;
+	font-family: monospace;
+	text-align: right;
+}
+
+
+
+
+
+.mse-table
+{
+	margin-left: auto;
+	margin-right: auto;
+	padding: 0;
+	border-collapse: collapse;
+	table-layout: fixed;
+	//border: 1px solid black;
+	//border-left: 2px solid black;
+}
+
+.mse-column-title-cell
+{
+	width: 28%;
+	margin: 0;
+	padding-left:   5px;
+	padding-right:  5px;
+	padding-top:    2px;
+	padding-bottom: 2px;
+	font-size: 1.4em;
+	font-weight: bold;
+	text-align: center;
+	border: 1px solid black;
+}
+
+.mse-column-title-span-full-text
+{
+	display: inline;
+}
+
+.mse-column-title-span-short-text
+{
+	display: none;
+}
+
+.mse-row-title-cell
+{
+	margin: 0;
+	padding-left:   2px;
+	padding-right:  2px;
+	padding-top:    2px;
+	padding-bottom: 2px;
+	font-size: 1.4em;
+	font-weight: bold;
+	text-align: center;
+	border: 1px solid black;
+}
+
+.mse-data-cell
+{
+	margin: 0;
+	padding-left:   5px;
+	padding-right:  5px;
+	padding-top:    2px;
+	padding-bottom: 2px;
+	font-size: 1.4em;
+	font-weight: normal;
+	font-family: monospace;
+	text-align: right;
+	border: 1px solid black;
+}
+
+.mse-caption-below
+{
+	margin: 0;
+	padding-left:   5px;
+	padding-right:  5px;
+	padding-top:    5px;
+	padding-bottom: 2px;
+	font-size: 1.2em;
+	font-weight: normal;
+	text-align: left;
+	//border: 1px solid black;
+}
+
+
+
+
+
+/* SETTINGS FOR WHEN THE SCREEN IS SMALL */
+@media screen and (max-width: 420px)
+{
+	.mse-column-title-cell
+	{
+		font-size: 1.2em;
+	}
+
+	.mse-row-title-cell
+	{
+		font-size: 1.2em;
+	}
+
+	.mse-column-title-span-full-text
+	{
+		display: none;
+	}
+
+	.mse-column-title-span-short-text
+	{
+		display: inline;
+	}
+
+	.mse-data-cell
+	{
+		font-size: 1.2em;
+	}
+
+	.mse-caption-below
+	{
+		font-size: 1.0em;
+	}
+}
diff --git a/web_interface/html/css/status_bar.css b/web_interface/html/css/status_bar.css
new file mode 100644
index 0000000000000000000000000000000000000000..936fc8f614551181e7ab24d9340f0797d8d64500
--- /dev/null
+++ b/web_interface/html/css/status_bar.css
@@ -0,0 +1,71 @@
+.status-icon-radio
+{
+	height: 40px;
+	width: 55px;
+	object-fit: contain;
+	text-align: center;
+	margin-left:     0px;
+	margin-right:    0px;
+	margin-top:      0px;
+	margin-bottom:   0px;
+	padding-left:   10px;
+	padding-right:  10px;
+	padding-top:     0px;
+	padding-bottom:  0px;
+}
+
+.status-icon-battery
+{
+	height: 40px;
+	width: 26px;
+	object-fit: contain;
+	text-align: center;
+	margin-left:     0px;
+	margin-right:    0px;
+	margin-top:      0px;
+	margin-bottom:   0px;
+	padding-left:   10px;
+	padding-right:  10px;
+	padding-top:     0px;
+	padding-bottom:  0px;
+}
+
+.status-icon-flying-state
+{
+	height: 40px;
+	width: 51px;
+	object-fit: contain;
+	text-align: center;
+	margin-left:     0px;
+	margin-right:    0px;
+	margin-top:      0px;
+	margin-bottom:   0px;
+	padding-left:   10px;
+	padding-right:  10px;
+	padding-top:     0px;
+	padding-bottom:  0px;
+}
+
+
+
+/* SETTINGS FOR WHEN THE SCREEN IS SMALL */
+@media screen and (max-width: 420px)
+{
+	.status-icon-radio
+	{
+		padding-left:   5px;
+		padding-right:  5px;
+	}
+
+	.status-icon-battery
+	{
+		padding-left:   5px;
+		padding-right:  5px;
+	}
+
+	.status-icon-flying-state
+	{
+		padding-left:   5px;
+		padding-right:  5px;
+	}
+}
\ No newline at end of file
diff --git a/web_interface/html/css/switches.css b/web_interface/html/css/switches.css
new file mode 100644
index 0000000000000000000000000000000000000000..2fcdce35b8cce2d5a87c0c5b9a406510ca5ab798
--- /dev/null
+++ b/web_interface/html/css/switches.css
@@ -0,0 +1,505 @@
+/* =========================== */
+/* ===   PLAIN SWITCH      === */
+/* =========================== */
+.on-off-switch-neighbouring-labelon-off-switch-neighbouring-label
+{
+	display: inline;
+	line-height: 90px;
+}
+
+.on-off-switch
+{
+	position: relative;
+	display: inline-block;
+}
+
+.on-off-switch:after, .on-off-switch:before
+{
+	font-family: Arial;
+	font-feature-settings: normal;
+	font-kerning: auto;
+	font-language-override: normal;
+	font-stretch: normal;
+	font-style: normal;
+	font-synthesis: weight style;
+	font-variant: normal;
+	font-weight: normal;
+	text-rendering: auto;
+}
+
+.on-off-switch label
+{
+	position: relative;
+	display: inline-block;
+
+	width: 90px;
+	height: 42px;
+	background: #ccc;
+	border-radius: 21px;
+	transition: 0.4s;
+}
+
+.on-off-switch label:after
+{
+	position: absolute;
+	left: 0;
+	top: -5px;
+	z-index: 2;
+
+	content: '';
+	
+	width: 50px;
+	height: 50px;
+	background: #fff;
+	border-radius: 100%;
+	box-shadow: 0 0 5px rgba(0,0,0,.2);
+	transition: 0.4s;
+}
+
+.on-off-switch input
+{
+	position: absolute;
+	left: 0;
+	top: 0;
+	z-index: 5;
+
+	width: 100%;
+	height: 100%;
+	opacity: 0;
+	cursor: pointer;
+}
+
+.on-off-switch input:hover + label:after
+{
+	box-shadow: 0 2px 15px 0 rgba(0, 0, 0, .2), 0 3px 8px 0 rgba(0, 0, 0, .15);
+}
+
+.on-off-switch input:checked + label:after
+{
+	left: 40px;
+}
+
+
+
+
+
+/* =========================== */
+/* ===   TYPE 1            === */
+/* =========================== */
+.on-off-switch.type1 input:checked + label
+{
+	background: #376FCB;
+}
+
+.on-off-switch.type1 input:checked + label:after
+{
+	background: #4285F4;
+}
+
+
+
+
+
+/* =========================== */
+/* ===   TYPE 2            === */
+/* =========================== */
+.on-off-switch.type2:after
+{
+	position: absolute;
+	top: 0px;
+	right: 15px;
+
+	content: '';
+
+	color: #666;
+	font-family: Arial;
+	font-size: 25px;
+	line-height: 48px;
+	font-weight: bold;
+}
+
+.on-off-switch.type2 label
+{
+	width: 90px;
+	height: 40px;
+	background: none;
+	border:3px solid #777;
+	border-radius: 23px;
+}
+
+.on-off-switch.type2 label:after
+{
+	top: 4px;
+	left: auto;
+	right: 4px;
+	overflow: hidden;
+
+	content: 'YES';
+	
+	width: 32px;
+	height: 32px;
+
+	color: #fff;
+	font-family: Arial;
+	font-size: 25px;
+	line-height: 32px;
+	text-align: center;
+	font-weight: bold;
+	text-indent: 100px;
+	background: #777;
+	box-shadow: none;
+	border-radius: 16px;
+
+	transform: translateX(-50px);
+	transition: all 0.4s 0.2s, width 0.2s linear, text-indent 0.4s linear;
+}
+
+.on-off-switch.type2 input:checked + label
+{
+	border-color: #329043;
+}
+
+.on-off-switch.type2 input:checked + label:after
+{
+	left: auto;
+
+	width: 82px;
+	text-indent: 0;
+	background: #3FB454;
+
+	transform: translateX(0px);
+	transition: all 0.4s, width 0.2s 0.4s linear, text-indent 0.3s 0.4s linear;
+}
+
+
+
+
+
+/* =========================== */
+/* ===   TYPE 2            === */
+/* =========================== */
+.on-off-switch.type2forstatusbar:after
+{
+	position: absolute;
+	top: 0px;
+	right: 12px;
+
+	content: '';
+
+	color: #ccc;
+	font-family: Arial;
+	font-size: 18px;
+	line-height: 40px;
+	font-weight: bold;
+}
+
+.on-off-switch.type2forstatusbar label
+{
+	width: 70px;
+	height: 32px;
+	background: none;
+	border:3px solid #ccc;
+	border-radius: 19px;
+}
+
+.on-off-switch.type2forstatusbar label:after
+{
+	top: 4px;
+	left: auto;
+	right: 4px;
+	overflow: hidden;
+
+	content: 'LIVE';
+
+	width: 24px;
+	height: 24px;
+
+	color: #fff;
+	font-family: Arial;
+	font-size: 18px;
+	line-height: 25px;
+	text-align: center;
+	font-weight: bold;
+	text-indent: 80px;
+	background: #ccc;
+	box-shadow: none;
+	border-radius: 12px;
+
+	transform: translateX(-38px);
+	transition: all 0.4s 0.2s, width 0.2s linear, text-indent 0.4s linear;
+}
+
+.on-off-switch.type2forstatusbar input:checked + label
+{
+	border-color: #269CE9;
+}
+
+.on-off-switch.type2forstatusbar input:checked + label:after
+{
+	left: auto;
+
+	width: 62px;
+	text-indent: 0;
+	background: #269CE9;
+
+	transform: translateX(0px);
+	transition: all 0.4s, width 0.2s 0.4s linear, text-indent 0.3s 0.4s linear;
+}
+
+
+
+
+
+/* =========================== */
+/* ===   TYPE 3            === */
+/* =========================== */
+.on-off-switch.type3 label
+{
+	width: 90px;
+	height: 42px;
+	border: 5px solid #555;
+	border-radius: 26px;
+	background: none;
+}
+
+.on-off-switch.type3 label:after
+{
+	top: 2px;
+	left: 2px;
+
+	width: 38px;
+	height: 38px;
+	background: #555;
+	box-shadow(none);
+}
+
+.on-off-switch.type3 input:checked + label
+{
+	border-color: #329043;
+}
+
+.on-off-switch.type3 input:checked + label:after
+{
+	left: 50px;
+	background: #3FB454;
+}
+
+
+
+
+
+/* =========================== */
+/* ===   TYPE 4            === */
+/* =========================== */
+.on-off-switch.type4:after
+{
+	position: absolute;
+	right: 15px;
+	bottom: 15px;
+
+	//content: '\f00c';
+	//content: '\274E';
+	//content: '\2715';
+	//content: '\2716';
+	//content: '\2717';
+	content: '\2718';
+	//content: '\274C';
+
+	color: #aaa;
+}
+
+.on-off-switch.type4:before
+{
+	position: absolute;
+	left: 15px;
+	bottom: 15px;
+	
+	//content: '\f00d';
+	//content: '\2705';
+	//content: '\2713';
+	content: '\2714';
+	
+	color: #fff;
+	z-index: 1;
+}
+
+.on-off-switch.type4 label
+{
+	width: 80px;
+	height: 42px;
+	border-radius: 21px;
+	background: #EAEAEA;
+	box-shadow: 0 0 1px 2px rgba(0,0,0,.15);
+}
+
+.on-off-switch.type4 label:after
+{
+	top: 0;
+
+	width: 42px;
+	height: 42px;
+}
+
+.on-off-switch.type4 input:checked + label
+{
+	background: #269CE9;
+}
+
+.on-off-switch.type4 input:checked + label:after
+{
+	left: 38px;
+}
+
+
+
+
+/* SETTINGS FOR WHEN THE SCREEN IS SMALL */
+@media screen and (max-width: 420px)
+{
+
+	/* =========================== */
+	/* ===   PLAIN SWITCH      === */
+	/* =========================== */
+	.on-off-switch-neighbouring-labelon-off-switch-neighbouring-label
+	{
+		line-height: 70px;
+	}
+
+	.on-off-switch label
+	{
+		width: 70px;
+		height: 32px;
+		border-radius: 16px;
+	}
+
+	.on-off-switch label:after
+	{
+		width: 40px;
+		height: 40px;
+	}
+
+	.on-off-switch input:checked + label:after
+	{
+		left: 30px;
+	}
+
+
+
+
+
+	/* =========================== */
+	/* ===   TYPE 2            === */
+	/* =========================== */
+	.on-off-switch.type2:after
+	{
+		top: 0px;
+		right: 12px;
+
+		content: '';
+
+		font-size: 18px;
+		line-height: 40px;
+		font-weight: bold;
+	}
+
+	.on-off-switch.type2 label
+	{
+		width: 70px;
+		height: 32px;
+		border:3px solid #777;
+		border-radius: 19px;
+	}
+
+	.on-off-switch.type2 label:after
+	{
+		top: 4px;
+		left: auto;
+		right: 4px;
+		overflow: hidden;
+
+		content: 'YES';
+		
+		width: 24px;
+		height: 24px;
+
+		font-size: 18px;
+		line-height: 25px;
+		font-weight: bold;
+		text-indent: 80px;
+		border-radius: 12px;
+
+		transform: translateX(-38px);
+	}
+
+	.on-off-switch.type2 input:checked + label:after
+	{
+		width: 62px;
+	}
+
+
+
+
+
+	/* =========================== */
+	/* ===   TYPE 3            === */
+	/* =========================== */
+	.on-off-switch.type3 label
+	{
+		width: 70px;
+		height: 32px;
+		border: 5px solid #555;
+		border-radius: 21px;
+	}
+
+	.on-off-switch.type3 label:after
+	{
+		top: 2px;
+		left: 2px;
+
+		width: 28px;
+		height: 28px;
+	}
+
+	.on-off-switch.type3 input:checked + label:after
+	{
+		left: 40px;
+	}
+
+
+
+
+
+	/* =========================== */
+	/* ===   TYPE 4            === */
+	/* =========================== */
+	.on-off-switch.type4:after
+	{
+		right: 10px;
+		bottom: 10px;
+	}
+
+	.on-off-switch.type4:before
+	{
+		left: 10px;
+		bottom: 10px;
+	}
+
+	.on-off-switch.type4 label
+	{
+		width: 60px;
+		height: 32px;
+		border-radius: 16px;
+	}
+
+	.on-off-switch.type4 label:after
+	{
+		width: 32px;
+		height: 32px;
+	}
+
+	.on-off-switch.type4 input:checked + label:after
+	{
+		left: 28px;
+	}
+
+}
\ No newline at end of file
diff --git a/web_interface/html/css/switches_from_some_website.css b/web_interface/html/css/switches_from_some_website.css
new file mode 100644
index 0000000000000000000000000000000000000000..226c385a100017f1945e5f27cd960d5a7dbaff84
--- /dev/null
+++ b/web_interface/html/css/switches_from_some_website.css
@@ -0,0 +1,548 @@
+/*
+  TAKEN FROM:
+  https://codepen.io/vineethtrv/pen/QbqMXE
+*/
+
+@import "compass/css3";
+*, *:after, *:before{
+  @include box-sizing(border-box);
+}
+$blue    : #4285F4;
+$green   : #4BD865;
+$warning :#FF980F;
+
+body{
+  text-align: center;
+  background: #eee;
+}
+section{
+ float: left;
+  min-width: 150px;
+  width: 33.33%;
+  padding:25px 0;
+  min-height: 100px;
+}
+/*=====================*/
+.checkbox{
+  position: relative;
+  display: inline-block;
+  
+  &:after, &:before{
+    font-family: FontAwesome;
+    font-feature-settings: normal;
+    font-kerning: auto;
+    font-language-override: normal;
+    font-stretch: normal;
+    font-style: normal;
+    font-synthesis: weight style;
+    font-variant: normal;
+    font-weight: normal;
+    text-rendering: auto;
+  }
+
+  label{
+    width: 90px;
+    height: 42px;
+    background: #ccc;
+    position: relative;
+    display: inline-block;
+    @include border-radius(46px);
+    @include transition(.4s);
+    &:after{
+      content: '';
+      position: absolute;
+      width: 50px;
+      height: 50px;
+      @include border-radius(100%);
+      left: 0;
+      top: -5px;
+       z-index: 2;
+      background: #fff;
+      @include box-shadow(0 0 5px rgba(0,0,0,.2));
+      @include transition(.4s);
+    }
+  }
+  input{
+    position: absolute;
+    left: 0;
+    top: 0;
+    width: 100%;
+    height: 100%;
+    z-index: 5;
+    opacity: 0;
+   cursor:pointer;
+    &:hover +label:after{
+      @include box-shadow(0 2px 15px 0 rgba(0, 0, 0, .2), 0 3px 8px 0 rgba(0, 0, 0, .15))
+    }
+    &:checked + label{
+      &:after{
+        left: 40px;
+      }
+    }
+        
+  }  
+}
+
+.model-1{
+  .checkbox{
+     input:checked + label{
+      background: $blue/1.2;
+      &:after{
+        background: $blue;
+      }
+    }
+  }
+}
+
+.model-2{
+  .checkbox{
+    label{
+      width: 75px;
+        &:after{
+          top: 0;
+          width:42px;
+          height: 42px;
+        }   
+    }
+    input:checked + label{
+      background: $green;
+      &:after{
+        left: 35px;
+      }
+    }
+  }
+}
+
+.model-3{
+  .checkbox{
+    label{
+      background: #fff;
+      border:1px solid #eee;
+      height: 38px;
+        &:after{
+          background: #bbb;
+          top: 3px;
+          left: 5px;
+          width:30px;
+          height: 30px;
+        }   
+    }
+    input:checked + label{
+      &:after{
+        background: $green/1.2;
+        left: 55px;
+      }
+    }
+  }
+}
+
+.model-4{
+  .checkbox{
+    label{
+      background: #bbb;
+      height: 25px;
+      width: 75px;
+        &:after{
+          background: #fff;
+          top: -8px;
+          width:38px;
+          height: 38px;
+        }
+    }
+    input:checked + label{
+      background: #77C2BB;
+      &:after{
+        background: #009688;
+        left: 40px;
+      }
+    }
+  }
+}
+.model-5{
+  .checkbox{
+    label{
+      background: #bbb;
+      height: 15px;
+      width: 85px;
+        &:after{
+          background: #fff;
+          top: -12px;
+          width:36px;
+          height: 36px;
+        }
+    }
+    input:hover + label:after{
+      @include scale(1.4);
+    }
+    input:checked + label{
+      background: $warning/1.4;
+      &:after{
+        background: $warning;
+        left: 50px;
+      }
+    }
+  }
+}
+.model-6{
+  .checkbox{
+    label{
+      background: #bbb;
+      height: 2px;
+      width: 60px;
+        &:after{
+          background: #bbb;
+          top: -16px;
+          width:32px;
+          height: 32px;
+        }
+    }
+    input:checked + label{
+      background: $blue/1.2;
+      &:after{
+        background:$blue;
+        left: 40px;
+      }
+    }
+  }
+}
+
+.model-7{
+  .checkbox{
+    label{
+      background: none;
+      border:5px solid #555;
+      height: 42px;
+        &:after{
+          background: #555;
+          @include box-shadow(none);
+          top: 2px;
+          left: 2px;
+          width:28px;
+          height: 28px;
+        }   
+    }
+    input:checked + label{
+      border-color:$green/1.5;
+      &:after{
+        background: $green/1.2;
+        left: 50px;
+      }
+    }
+  }
+}
+.model-8{
+  .checkbox{
+    label{
+      background: #ddd;
+      width: 95px;
+      @include border-radius(10px);
+        &:after{
+          background: #fff;
+          @include border-radius(10px);
+          top: 0;
+          width:60px;
+          height: 42px;
+        }   
+    }
+    input:checked + label{
+      background:$warning;
+      &:after{
+        left: 35px;
+      }
+    }
+  }
+}
+.model-9{
+  .checkbox{
+    label{
+      background: #aaa;
+      width: 90px;
+      height: 32px;
+      @include border-radius(20px);
+        &:after{
+          @include border-radius(20px);
+          top: 0;
+          width:50px;
+          height: 32px;
+        }   
+    }
+    input:checked + label{
+      background:$green/2;
+      &:after{
+        background: $green/1.4;
+        left: 40px;
+      }
+    }
+  }
+}
+.model-10{
+  .checkbox{
+    &:after{
+      content: '\f00d';
+      color: #aaa;
+     position: relative;
+      right: 30px;
+      bottom: 15px;
+    }
+    &:before{
+      content: '\f00c';
+       position: relative;
+      left: 35px;
+      bottom: 15px;
+      color: #fff;
+      z-index: 1;
+    }
+    label{
+      width: 80px;
+      background: #EAEAEA;
+      @include box-shadow(0 0 1px 2px rgba(0,0,0,.15));
+        &:after{
+          top: 0;
+          width:42px;
+          height: 42px;
+        }   
+    }
+    input:checked + label{
+      background: $green;
+      &:after{
+        left: 40px;
+      }
+    }
+  }
+}
+
+.model-11{
+  .checkbox{
+    &:after, &:before{
+      content: 'OFF';
+      position: absolute;
+      right: 10px;
+      top: 10px;
+      font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
+      font-size: 12px;
+      color: #90201F;
+    }
+    &:before{
+      content: 'ON';
+      left: -40px;
+      z-index: 1;
+      color: $green/2;
+    }
+    label{
+      background: #E3666C;
+      height: 32px;
+      @include border-radius(0);
+       @include box-shadow(0 0 1px 2px rgba(0,0,0,.2));
+        &:after{
+          background-color: #ffffff; 
+          @include filter-gradient(#ffffff, #ffffff, horizontal); 
+          @include background-image(linear-gradient(left,  #fff 30%,#ddd 45%,#fff 50%,#ddd 55%,#fff 70%));
+          @include border-radius(0);
+          @include box-shadow(none !important);
+          @include transition(.1s);
+          top: 0;
+          width:50px;
+          height: 32px;
+        }   
+    }
+    input:checked + label{
+      background:$green;
+      &:after{
+        left: 40px;
+      }
+    }
+  }
+}
+
+
+.model-12{
+  .checkbox{
+    background: #2B2B2D;
+    height: 40px;
+    width: 160px;
+     @include border-radius(50px);
+    &:after, &:before{
+      content: 'ON';
+      font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
+      line-height: 40px;
+      font-size: 12px;
+    }
+    &:before{
+      content: 'OFF';
+      z-index: 1;
+    }
+    label{
+      background: #1E1E1E;
+      height:10px;
+      width: 70px;
+      margin: 0 5px;
+       @include box-shadow(0 0 2px 2px rgba(0,0,0,.3) inset) ;
+        &:after{
+          background-color: #3F4545;
+          @include background-image(linear-gradient(top,  #666 0%,#3F4545 100%));
+          top: -9px;
+          width:27px;
+          height: 27px;
+        }
+      &:before{
+        content: '';
+        position: absolute;
+        width: 14px;
+        height: 14px;
+        @include border-radius(100%);
+        @include transition(.4s);
+        background:#151515;
+        z-index: 3;
+        left: 7px;
+        top: -2px;
+      }
+    }
+    input:checked + label{
+      &:after{
+        left: 45px;
+      }
+      &:before{
+        background: #94DA00;
+        @include box-shadow(0 0 5px #94DA00) ;
+        left: 52px;
+      }
+    }
+  }
+}
+.model-13{
+  .checkbox{
+    &:after{
+      content: 'NO';
+      font-family: Arial;
+      position: absolute;
+      color: #666;
+      top: 12px;
+      right: 15px;
+    }
+    label{
+      background: none;
+      border:3px solid #777;
+      height: 40px;
+       @include border-radius(20px);
+      
+        &:after{
+          content: 'YES';
+          font-family: Arial;
+          color: #fff;
+          line-height: 28px;
+          text-indent: 100px;
+          background: #777;
+          overflow: hidden;
+          @include box-shadow(none);
+          @include border-radius(14px);
+          @include translateX(-50px);
+           @include transition(all .4s .2s, width .2s linear, text-indent .4s linear);
+          
+          top: 3px;
+          left: auto;
+          right: 2px;
+          width:28px;
+          height: 28px;
+           
+        }   
+    }
+    input:checked + label{
+      border-color:$green/1.5;
+      &:after{
+        background: $green/1.2;
+        left: auto;
+        @include translateX(0px);
+        @include transition(all .4s, width .2s .4s linear, text-indent  .3s .4s linear);
+        width: 80px;
+        text-indent: 0;
+      }
+    }
+  }
+}
+
+.model-14{
+  .checkbox{
+    &:after, &:before{
+      content: 'OFF';
+      position: absolute;
+      right: 10px;
+      top: 10px;
+      font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
+      font-size: 12px;
+      color: #90201F;
+    }
+    &:before{
+      content: 'ON';
+      left: -40px;
+      z-index: 1;
+      color: $green/2;
+    }
+    label{
+      background:#fff;
+      height: 32px;
+      @include border-radius(0);
+       @include box-shadow(0 0 2px rgba(0,0,0,.2));
+        &:after{
+          background:  #90201F;
+          @include border-radius(0);
+          @include box-shadow(none !important);
+          @include transition(.3s);
+          top: 0;
+          width:40px;
+          height: 32px;
+        }   
+    }
+    input:checked + label{
+      &:after{
+         background:$green;
+        left: 50px;
+      }
+    }
+  }
+}
+.model-15{
+  .checkbox{
+      width: 94px;
+      height: 34px;
+      border: 2px solid #ddd;
+      background:$green/2;
+      @include border-radius(6px);
+      overflow: hidden;
+    &:after, label:before{
+      content: 'ON';
+      position: absolute;
+      left: 10px;
+      top: 8px;
+      font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
+      font-size: 12px;
+      color: #fff;
+    }
+    label:before{
+      content: 'OFF';
+      left:auto;
+      top: 8px;
+      right: 10px;
+      z-index: 1;
+    }
+    label{
+      background: #f00;
+      width: 90px;
+      height: 32px;
+      @include border-radius(4px);
+        &:after{
+          @include border-radius(4px);
+          @include box-shadow(none !important);
+          top: 0;
+          width:50px;
+          height: 32px;
+        }   
+    }
+    input:checked + label{
+      @include translateX(40px);
+      &:after{
+        left:0;
+      }
+    }
+  }
+}
+
diff --git a/web_interface/html/css/tabs_control.css b/web_interface/html/css/tabs_control.css
new file mode 100644
index 0000000000000000000000000000000000000000..7d0c8c4eaafdef028c7c12526fb3211698513973
--- /dev/null
+++ b/web_interface/html/css/tabs_control.css
@@ -0,0 +1,128 @@
+.control-tabs
+{
+	display: flex;
+	flex-wrap: wrap;
+	background: #efefef;
+	border: 1pt solid #34495E;
+	box-shadow: 0 48px 80px -32px rgba(0,0,0,0.3);
+	//top:    0px;
+	//bottom: 0px;
+	margin: 0px;
+}
+
+.control-tab-input {
+  position: absolute;
+  opacity: 0;
+}
+
+.control-tab-label
+{
+	width: auto;
+	padding-left:   30px;
+	padding-right:  30px;
+	padding-top:    20px;
+	padding-bottom: 20px;
+	background: #e5e5e5;
+	cursor: pointer;
+	font-weight: bold;
+	font-size: 18px;
+	color: #7f7f7f;
+	transition: background 0.0s, color 0.0s;
+}
+
+.control-tab-label:hover
+{
+	background: #d8d8d8;
+}
+
+.control-tab-label:active
+{
+	background: #ccc;
+}
+
+.control-tab-input:focus + .control-tab-label
+{
+	/*box-shadow: inset 0px 0px 0px 3px #2aa1c0*/;
+	z-index: 1;
+}
+
+.control-tab-input:checked + .control-tab-label
+{
+	background: #fff;
+	color: #000;
+}
+
+.control-tab-panel
+{
+	order: 99;
+	display: none;
+	position: relative;
+	margin-top:    0px;
+	margin-bottom: 0px;
+	margin-left:   0px;
+	margin-right:  0px;
+	width:100%;
+	padding-left:   20px;
+	padding-right:  20px;
+	padding-top:    10px;
+	padding-bottom: 10px;
+	background: #fff;
+	color:black;
+	overflow: hidden;
+	overflow-y: scroll;
+	border-left: 1px solid;
+	border-right: 1px solid;
+	border-width: 10px;
+	border-color: #c43c35;
+	/*
+	border-color: #c43c35;
+	border-color: #f44336;
+	border-color: #57a957;
+	*/
+}
+
+/* Make the respective panel visible when its tab-input is checked */
+.control-tab-input:checked + .control-tab-label + .control-tab-panel
+{
+	display: block;
+}
+
+
+
+
+/* SETTINGS FOR WHEN THE SCREEN IS SMALL */
+@media screen and (max-width: 600px)
+{
+	/* Make it an accordian */
+	.control-tab-label
+	{
+		width: 50%;
+		padding-left:   0px;
+		padding-right:  0px;
+		padding-top:    20px;
+		padding-bottom: 20px;
+		text-align: center;
+	}
+}
+
+/* SETTINGS FOR WHEN THE SCREEN IS SMALL */
+@media screen and (max-width: 420px)
+{
+	/* Make it an accordian */
+	.control-tab-label
+	{
+		width: 50%;
+		padding-left:   0px;
+		padding-right:  0px;
+		padding-top:    15px;
+		padding-bottom: 15px;
+		text-align: center;
+	}
+
+	.control-tab-panel
+	{
+		padding-left:   10px;
+		padding-right:  10px;
+	}
+
+}
\ No newline at end of file
diff --git a/web_interface/html/css/tabs_home.css b/web_interface/html/css/tabs_home.css
new file mode 100644
index 0000000000000000000000000000000000000000..0521ec250201be97c8052ba2ec61d3d73947c1b4
--- /dev/null
+++ b/web_interface/html/css/tabs_home.css
@@ -0,0 +1,135 @@
+.home-tabs
+{
+	display: flex;
+	flex-wrap: wrap;
+	background: #efefef;
+	//box-shadow: 0 48px 80px -32px rgba(0,0,0,0.3);
+	top:    0px;
+	bottom: 0px;
+	margin: 0px;
+}
+
+.home-tab-input {
+  position: absolute;
+  opacity: 0;
+}
+
+.home-tab-label
+{
+	width: auto;
+	padding-left:   30px;
+	padding-right:  30px;
+	padding-top:    20px;
+	padding-bottom: 20px;
+	background: #e5e5e5;
+	cursor: pointer;
+	font-weight: bold;
+	font-size: 18px;
+	color: #7f7f7f;
+	transition: background 0.0s, color 0.0s;
+}
+
+.home-tab-label:hover
+{
+	background: #d8d8d8;
+}
+
+.home-tab-label:active
+{
+	background: #ccc;
+}
+
+.home-tab-input:focus + .home-tab-label
+{
+	/*box-shadow: inset 0px 0px 0px 3px #2aa1c0*/;
+	z-index: 1;
+}
+
+.home-tab-input:checked + .home-tab-label
+{
+	background: #fff;
+	color: #000;
+}
+
+.home-tab-panel
+{
+	order: 99;
+	display: none;
+	position: absolute;
+	top: 0;
+	bottom: 0;
+	left:     0px;
+	right:    0px;
+	top:    235px;
+	bottom:   0px;
+	margin-top:      0px;
+	margin-bottom:   0px;
+	margin-left:     0px;
+	margin-right:    0px;
+	max-width:     800px;
+	padding-left:   20px;
+	padding-right:  20px;
+	padding-top:    10px;
+	padding-bottom: 10px;
+	background: #fff;
+	color:black;
+	overflow: hidden;
+	overflow-y: auto;
+}
+
+.home-tab-panel.thin-padding
+{
+	padding-left:   10px;
+	padding-right:  10px;
+}
+
+/* Make the respective panel visible when its tab-input is checked */
+.home-tab-input:checked + .home-tab-label + .home-tab-panel
+{
+	display: block;
+}
+
+
+
+
+/* SETTINGS FOR WHEN THE SCREEN IS SMALL */
+@media screen and (max-width: 600px)
+{
+	/* Make it an accordian */
+	.home-tab-label
+	{
+		width: 25%;
+		padding-left:   0px;
+		padding-right:  0px;
+		padding-top:    20px;
+		padding-bottom: 20px;
+		text-align: center;
+	}
+}
+
+/* SETTINGS FOR WHEN THE SCREEN IS SMALL */
+@media screen and (max-width: 420px)
+{
+	/* Make it an accordian */
+	.home-tab-label
+	{
+		width: 50%;
+		padding-left:   0px;
+		padding-right:  0px;
+		padding-top:    10px;
+		padding-bottom: 10px;
+		text-align: center;
+	}
+
+	.home-tab-panel
+	{
+		top: 185px;
+	}
+
+	.home-tab-panel.thin-padding
+	{
+		padding-left:   5px;
+		padding-right:  5px;
+	}
+	
+}
\ No newline at end of file
diff --git a/web_interface/html/css/tabs_main.css b/web_interface/html/css/tabs_main.css
new file mode 100644
index 0000000000000000000000000000000000000000..0fb1582f0727ec220dfd22952aa750e4324112ca
--- /dev/null
+++ b/web_interface/html/css/tabs_main.css
@@ -0,0 +1,155 @@
+.main-tabs
+{
+	display: flex;
+	flex-wrap: wrap;
+	background: #efefef;
+	//box-shadow: 0 48px 80px -32px rgba(0,0,0,0.3);
+	top:    0px;
+	bottom: 0px;
+	margin: 0px;
+}
+
+.main-tab-input {
+  position: absolute;
+  opacity: 0;
+}
+
+.main-tab-label
+{
+	width: auto;
+	padding-left:   30px;
+	padding-right:  30px;
+	padding-top:    20px;
+	padding-bottom: 20px;
+	background: #e5e5e5;
+	cursor: pointer;
+	font-weight: bold;
+	font-size: 18px;
+	color: #7f7f7f;
+	transition: background 0.0s, color 0.0s;
+}
+
+.main-tab-label:hover
+{
+	background: #d8d8d8;
+}
+
+.main-tab-label:active
+{
+	background: #ccc;
+}
+
+.main-tab-input:focus + .main-tab-label
+{
+	/*box-shadow: inset 0px 0px 0px 3px #2aa1c0*/;
+	z-index: 1;
+}
+
+.main-tab-input:checked + .main-tab-label
+{
+	background: #fff;
+	color: #000;
+}
+
+/* The "top" specification here is critical  */
+/* Use:                                      */
+/* 189px    when the top banner contains the */
+/*          motors-off button and agent IP   */
+/* 190px    when the top banner contains the */
+/*          motors-off button and status     */
+/*          icons                            */
+/* 229px    when the top banner contains the */
+/*          motors-off button, agent IP, and */
+/*          status icons.                    */
+.main-tab-panel
+{
+	order: 99;
+	display: none;
+	position: absolute;
+	top: 0;
+	bottom: 0;
+	left:     0px;
+	right:    0px;
+	top:    190px;
+	bottom:   0px;
+	margin-top:      0px;
+	margin-bottom:   0px;
+	margin-left:     0px;
+	margin-right:    0px;
+	max-width:     800px;
+	padding-left:   20px;
+	padding-right:  20px;
+	padding-top:    10px;
+	padding-bottom: 10px;
+	background: #fff;
+	color:black;
+	overflow: hidden;
+	overflow-y: auto;
+}
+
+.main-tab-panel.thin-padding
+{
+	padding-left:   10px;
+	padding-right:  10px;
+}
+
+/* Make the respective panel visible when its tab-input is checked */
+.main-tab-input:checked + .main-tab-label + .main-tab-panel
+{
+	display: block;
+}
+
+
+
+
+/* SETTINGS FOR WHEN THE SCREEN IS SMALL */
+@media screen and (max-width: 600px)
+{
+	/* Make it an accordian */
+	.main-tab-label
+	{
+		width: 25%;
+		padding-left:   0px;
+		padding-right:  0px;
+		padding-top:    20px;
+		padding-bottom: 20px;
+		text-align: center;
+	}
+}
+
+/* SETTINGS FOR WHEN THE SCREEN IS SMALL */
+@media screen and (max-width: 420px)
+{
+	/* Make it an accordian */
+	.main-tab-label
+	{
+		width: 25%;
+		padding-left:   0px;
+		padding-right:  0px;
+		padding-top:    10px;
+		padding-bottom: 10px;
+		text-align: center;
+	}
+
+	/* The "top" specification here is critical  */
+	/* Use:                                      */
+	/* 147px    when the top banner contains the */
+	/*          motors-off button and agent IP   */
+	/* 162px    when the top banner contains the */
+	/*          motors-off button and status     */
+	/*          icons                            */
+	/* 190px    when the top banner contains the */
+	/*          motors-off button, agent IP, and */
+	/*          status icons.                    */
+	.main-tab-panel
+	{
+		top: 162px;
+	}
+
+	.main-tab-panel.thin-padding
+	{
+		padding-left:   5px;
+		padding-right:  5px;
+	}
+	
+}
\ No newline at end of file
diff --git a/web_interface/html/home_tab_about.html b/web_interface/html/home_tab_about.html
new file mode 100644
index 0000000000000000000000000000000000000000..fdceac46c3b02e0aa99a8ab4c149d0ca8f4c1693
--- /dev/null
+++ b/web_interface/html/home_tab_about.html
@@ -0,0 +1,11 @@
+<body>
+	<div class="body-container">
+		<main style="text-align:left;">
+
+			<br>
+
+			Coming soon...
+
+		</main>
+	</div>
+</body>
\ No newline at end of file
diff --git a/web_interface/html/home_tab_enter.html b/web_interface/html/home_tab_enter.html
new file mode 100644
index 0000000000000000000000000000000000000000..9cbf127f892620c7e8849930f5fdd07de1e54251
--- /dev/null
+++ b/web_interface/html/home_tab_enter.html
@@ -0,0 +1,33 @@
+<body>
+	<div class="body-container">
+		<main style="text-align:left;">
+
+			<br>
+
+			<button class="button-push navy" onclick="window.location.href='agent.php'">
+				Enter as Agent
+				<div class="div-for-button-highlight-on-touchscreen navy"></div>
+			</button>
+
+			<br>
+
+			<p>
+				The agent interface allows you to transfer and compile code, launch the ROS nodes, and control the agent.
+			</p>
+
+			<br><br><br>
+
+			<button class="button-push navy" onclick="window.location.href='coord.php'">
+				Enter as Coordinator
+				<div class="div-for-button-highlight-on-touchscreen navy"></div>
+			</button>
+
+			<br>
+
+			<p>
+				The coordinator interface allows you to compile code, launch the ROS nodes, and control multiple agents simultaneously.
+			</p>
+
+		</main>
+	</div>
+</body>
\ No newline at end of file
diff --git a/web_interface/html/img/battery_20.png b/web_interface/html/img/battery_20.png
new file mode 100644
index 0000000000000000000000000000000000000000..cc7ae62ab7c662f7cf3e098e713232d2d6e0ae14
Binary files /dev/null and b/web_interface/html/img/battery_20.png differ
diff --git a/web_interface/html/img/battery_40.png b/web_interface/html/img/battery_40.png
new file mode 100644
index 0000000000000000000000000000000000000000..cea5ab35b9605910112dd8a7e2eda371c430894b
Binary files /dev/null and b/web_interface/html/img/battery_40.png differ
diff --git a/web_interface/html/img/battery_60.png b/web_interface/html/img/battery_60.png
new file mode 100644
index 0000000000000000000000000000000000000000..1f75257c3c1f44fc10f318274741942916b47b70
Binary files /dev/null and b/web_interface/html/img/battery_60.png differ
diff --git a/web_interface/html/img/battery_80.png b/web_interface/html/img/battery_80.png
new file mode 100644
index 0000000000000000000000000000000000000000..8224e7e1e2ed8e251f37f802b14ce4ebd9027f35
Binary files /dev/null and b/web_interface/html/img/battery_80.png differ
diff --git a/web_interface/html/img/battery_empty.png b/web_interface/html/img/battery_empty.png
new file mode 100644
index 0000000000000000000000000000000000000000..0bf35549aab7c7c0247cebd69a176d68ea67387c
Binary files /dev/null and b/web_interface/html/img/battery_empty.png differ
diff --git a/web_interface/html/img/battery_full.png b/web_interface/html/img/battery_full.png
new file mode 100644
index 0000000000000000000000000000000000000000..495383be5e346e624d7a92670fcf9ddb053f99ef
Binary files /dev/null and b/web_interface/html/img/battery_full.png differ
diff --git a/web_interface/html/img/battery_unavailable.png b/web_interface/html/img/battery_unavailable.png
new file mode 100644
index 0000000000000000000000000000000000000000..71765cfe18b1d7a915b7f92daf06df3b6558521f
Binary files /dev/null and b/web_interface/html/img/battery_unavailable.png differ
diff --git a/web_interface/html/img/battery_unknown.png b/web_interface/html/img/battery_unknown.png
new file mode 100644
index 0000000000000000000000000000000000000000..e20348f65a39bac7c0e40a2a4c0b338ef018dc03
Binary files /dev/null and b/web_interface/html/img/battery_unknown.png differ
diff --git a/web_interface/html/img/flying_state_disabling.png b/web_interface/html/img/flying_state_disabling.png
new file mode 100644
index 0000000000000000000000000000000000000000..667c8027f2b902f08f8e81d3120599a5ed151d48
Binary files /dev/null and b/web_interface/html/img/flying_state_disabling.png differ
diff --git a/web_interface/html/img/flying_state_enabling.png b/web_interface/html/img/flying_state_enabling.png
new file mode 100644
index 0000000000000000000000000000000000000000..ef2dc5bffa6d27edbb6c6ff1171cd77a5af5c20a
Binary files /dev/null and b/web_interface/html/img/flying_state_enabling.png differ
diff --git a/web_interface/html/img/flying_state_flying.png b/web_interface/html/img/flying_state_flying.png
new file mode 100644
index 0000000000000000000000000000000000000000..b0b51f3d42edbfad9f875c1faa413391c4f21de9
Binary files /dev/null and b/web_interface/html/img/flying_state_flying.png differ
diff --git a/web_interface/html/img/flying_state_off.png b/web_interface/html/img/flying_state_off.png
new file mode 100644
index 0000000000000000000000000000000000000000..70669664f07c12ef27a41f5b5fb918aff93da688
Binary files /dev/null and b/web_interface/html/img/flying_state_off.png differ
diff --git a/web_interface/html/img/flying_state_unavailable.png b/web_interface/html/img/flying_state_unavailable.png
new file mode 100644
index 0000000000000000000000000000000000000000..60f6878b603abc0ba5dd375765ff06ad36a397ab
Binary files /dev/null and b/web_interface/html/img/flying_state_unavailable.png differ
diff --git a/web_interface/html/img/flying_state_unknown.png b/web_interface/html/img/flying_state_unknown.png
new file mode 100644
index 0000000000000000000000000000000000000000..5c0c7337a103e5726af53def62e37ad22209c972
Binary files /dev/null and b/web_interface/html/img/flying_state_unknown.png differ
diff --git a/web_interface/html/img/rf_connected.png b/web_interface/html/img/rf_connected.png
new file mode 100644
index 0000000000000000000000000000000000000000..f9f3580113053f71fe86344e6f34a74e98c17b70
Binary files /dev/null and b/web_interface/html/img/rf_connected.png differ
diff --git a/web_interface/html/img/rf_connecting.png b/web_interface/html/img/rf_connecting.png
new file mode 100644
index 0000000000000000000000000000000000000000..5f1d4ca1b48496ecf1372e1a0f727058bbc24d95
Binary files /dev/null and b/web_interface/html/img/rf_connecting.png differ
diff --git a/web_interface/html/img/rf_disconnected.png b/web_interface/html/img/rf_disconnected.png
new file mode 100644
index 0000000000000000000000000000000000000000..0e99e624009059328820b317c908d337caf55ddc
Binary files /dev/null and b/web_interface/html/img/rf_disconnected.png differ
diff --git a/web_interface/html/index.php b/web_interface/html/index.php
new file mode 100644
index 0000000000000000000000000000000000000000..80216f485e17899c2ca4c2fa058d1ffdc569b76b
--- /dev/null
+++ b/web_interface/html/index.php
@@ -0,0 +1,60 @@
+<?php
+	include("page_header.html");
+?>
+
+<div class="full-window-fixed">
+</div>
+
+<div class="max-width-full-heigth-fixed">
+
+	<div class="top-bar-container">
+		<table class="top-bar-buttons-table">
+			<tr>
+				<td class="top-bar-motorsoff-button-cell">
+					<button class="button-push red motorsoff" disabled onclick="checkForRosAgent()">
+						MOTORS-OFF
+					</button>
+				</td>
+				<td class="top-bar-info-button-cell">
+					<button class="button-push blue info" onclick="checkForRosAgent()">
+						i
+						<div class="div-for-button-highlight-on-touchscreen blue"></div>
+					</button>
+				</td>
+			</tr>
+		</table>
+
+		<div class="top-bar-title">
+			Browser Interface
+		</div>
+		<div class="top-bar-subtitle">
+			for the D-FaLL System
+		</div>
+		<div class="top-bar-subtitle padbelow">
+			Connected to IP <?php echo $_SERVER['REMOTE_ADDR']; ?>
+		</div>
+	</div>
+
+	<div class="home-tabs">
+		<input name="tabs" type="radio" id="home-tab-1" checked="checked" class="home-tab-input"/>
+		<label for="home-tab-1" class="home-tab-label">Enter</label>
+		<div class="home-tab-panel">
+			<?php
+				include("home_tab_enter.html");
+			?>
+		</div>
+
+		<input name="tabs" type="radio" id="home-tab-2" class="home-tab-input"/>
+		<label for="home-tab-2" class="home-tab-label">About</label>
+		<div class="home-tab-panel">
+			<?php
+				include("home_tab_about.html");
+			?>
+		</div>
+	</div>
+</div>
+
+
+<?php
+	include("page_footer.html");
+?>
\ No newline at end of file
diff --git a/web_interface/html/js/callbashscript.js b/web_interface/html/js/callbashscript.js
new file mode 100644
index 0000000000000000000000000000000000000000..e494f3c1f444c1ef6b1b524b8c1dc65427cdd9f5
--- /dev/null
+++ b/web_interface/html/js/callbashscript.js
@@ -0,0 +1,169 @@
+function callBashScript_outputLabelID_clearOtherLabels_clickOtherButtons(bashscript, labelID, otherLabels, otherButtons)
+{
+	// Create a variable for sending an AJAX request
+	var xmlhttp = new XMLHttpRequest();
+	// Add the function to be run when the response is recieved
+	xmlhttp.onreadystatechange = function()
+	{
+		if (this.readyState == 4 && this.status == 200)
+		{
+			// Construct the return string
+			var base_string = "";
+			document.getElementById(labelID).innerHTML = base_string + this.responseText;
+			// Click the "other buttons" as requested
+			if (otherButtons)
+			{
+				if ( typeof(otherButtons) == "string" )
+				{
+					document.getElementById(otherButtons).click();
+				}
+				else if (otherButtons.constructor === Array)
+				{
+					for (otherButtonID of otherButtons)
+					{
+						if (otherButtonID)
+						{
+							if ( typeof(otherButtonID) == "string" )
+							{
+								document.getElementById(otherButtonID).click();
+							}
+						}
+					}
+				}
+			}
+
+		}
+		else
+		{
+			var display_message = getDisplayMessageForXMLHttpRequest(this);
+			document.getElementById(labelID).innerHTML = display_message;
+		}
+	};
+	xmlhttp.open("GET", "callBashScript.php?scriptname=" + bashscript, true);
+	xmlhttp.send();
+
+	// Clear the other labels as requested
+	if (otherLabels)
+	{
+		if ( typeof(otherLabels) == "string" )
+		{
+			document.getElementById(otherLabels).innerHTML = "";
+		}
+		else if (otherLabels.constructor === Array)
+		{
+			for (otherLabelID of otherLabels)
+			{
+				if (otherLabelID)
+				{
+					if ( typeof(otherLabelID) == "string" )
+					{
+						document.getElementById(otherLabelID).innerHTML = "";
+					}
+				}
+			}
+		}
+	}
+}
+
+
+
+function getDisplayMessageForXMLHttpRequest(xmlhttp)
+{
+	var base_string = "";
+	if (xmlhttp.readyState != 4)
+	{
+		base_string = base_string + "loading...";
+	}
+	else
+	{
+		if (xmlhttp.status != 204)
+		{
+			base_string = base_string + "Error " + xmlhttp.status + ": no content.";
+		}
+		else if (xmlhttp.status != 403)
+		{
+			base_string = base_string + "Error " + xmlhttp.status + ": request forbidden.";
+		}
+		else if (xmlhttp.status != 404)
+		{
+			base_string = base_string + "Error " + xmlhttp.status + ": page not found.";
+		}
+		else if (xmlhttp.status != 500)
+		{
+			base_string = base_string + "Error " + xmlhttp.status + ": internal server error.";
+		}
+		else if (xmlhttp.status != 501)
+		{
+			base_string = base_string + "Error " + xmlhttp.status + ": no implemented.";
+		}
+		else if (xmlhttp.status != 502)
+		{
+			base_string = base_string + "Error " + xmlhttp.status + ": bd gateway.";
+		}
+		else if (xmlhttp.status != 503)
+		{
+			base_string = base_string + "Error " + xmlhttp.status + ": service unavailable.";
+		}
+		else if (xmlhttp.status != 504)
+		{
+			base_string = base_string + "Error " + xmlhttp.status + ": gateway timeout.";
+		}
+		else
+		{
+			base_string = base_string + "Error " + xmlhttp.status;
+		}
+		
+	}
+	// Finally return the string
+	return base_string;
+}
+
+
+function getErrorMessageForXMLHttpRequest(xmlhttp)
+{
+	var base_string = "";
+	if (xmlhttp.readyState != 4 && xmlhttp.status != 200)
+	{
+		base_string = base_string + "readyState = " + xmlhttp.readyState + " and status = " + xmlhttp.status;
+	}
+	else if (xmlhttp.readyState != 4)
+	{
+		base_string = base_string + "status is good but readyState = " + xmlhttp.readyState;
+	}
+	else if (xmlhttp.status != 200)
+	{
+		base_string = base_string + "ready state is good but status = " + xmlhttp.status;
+	}
+	// Finally return the string
+	return base_string;
+}
+
+/*
+The "XMLHttpRequest" variable has the following:
+> CALLBACK FUNCTION: onreadystatechange
+  Defines a function to be called when the readyState property changes
+
+> PROPERTY: readyState
+  Holds the status of the XMLHttpRequest.
+  0: request not initialized
+  1: server connection established
+  2: request received
+  3: processing request
+  4: request finished and response is ready
+
+> PROPERTY status
+  200: "OK"
+  403: "Forbidden"
+  404: "Page not found"
+  For a complete list go to the Http Messages Reference
+
+> PROPERTY statusText
+  Returns the status-text (e.g. "OK" or "Not Found")
+
+> PROPERTY responseText
+  Returns the server response as a JavaScript string
+
+For more details see:
+https://www.w3schools.com/xml/ajax_xmlhttprequest_response.asp
+https://www.w3schools.com/tags/ref_httpmessages.asp
+*/
diff --git a/web_interface/html/js/callgit.js b/web_interface/html/js/callgit.js
new file mode 100644
index 0000000000000000000000000000000000000000..a23174c6fb7de4f60457a8f633b6488043acd1bb
--- /dev/null
+++ b/web_interface/html/js/callgit.js
@@ -0,0 +1,127 @@
+function callGit_outputLabelID_shouldAppend_shouldConfirm(gitCommand, labelID, shouldAppend, shouldConfirm)
+{
+	// Convert the "gitCommand" to a heding string
+	var heading_string = "<p class=\"terminal-highligh-paragraph\">";
+	var scriptname_for_php = "";
+	var confirm_alert_text = "";
+	if (gitCommand == "status")
+	{
+		heading_string = heading_string + "GIT STATUS";
+		scriptname_for_php = scriptname_for_php + "gitStatus";
+		confirm_alert_text = confirm_alert_text + "This will check the status of the repository.";
+	}
+	else if (gitCommand == "pull")
+	{
+		heading_string = heading_string + "GIT PULL";
+		scriptname_for_php = scriptname_for_php + "gitPull";
+		confirm_alert_text = confirm_alert_text + "This will pull the latest changes, and may fail if there are any conflicts.";
+	}
+	else if (gitCommand == "diff")
+	{
+		heading_string = heading_string + "GIT DIFF";
+		scriptname_for_php = scriptname_for_php + "gitDiff";
+		confirm_alert_text = confirm_alert_text + "This will show the difference between the current status and the previous commit.";
+	}
+	else if (gitCommand == "checkout")
+	{
+		heading_string = heading_string + "GIT CHECKOUT .";
+		scriptname_for_php = scriptname_for_php + "gitCheckout";
+		confirm_alert_text = confirm_alert_text + "This remove any changes and those changes can NOT be recovered.";
+	}
+	else if (gitCommand == "checkoutall")
+	{
+		heading_string = heading_string + "GIT CHECKOUT .";
+		scriptname_for_php = scriptname_for_php + "gitCheckoutAll";
+		confirm_alert_text = confirm_alert_text + "This remove any changes and those changes can NOT be recovered.";
+	}
+	else if (gitCommand == "checkoutmaster")
+	{
+		heading_string = heading_string + "GIT CHECKOUT MASTER";
+		scriptname_for_php = scriptname_for_php + "gitCheckoutMaster";
+		confirm_alert_text = confirm_alert_text + "This switches branch and the web interface does not offer the functionality to switch back.";
+	}
+	else if (gitCommand == "catkin_make")
+	{
+		heading_string = heading_string + "CATKIN_MAKE";
+		scriptname_for_php = scriptname_for_php + "catkin_make";
+		confirm_alert_text = confirm_alert_text + "This compiles the dfall-system code.";
+	}
+	// Add the end paragraph tag to the heading string
+	heading_string = heading_string + "</p>";
+
+	// Check the "shouldAppend" input argument
+	if ( typeof(shouldAppend) !== "boolean" )
+	{
+		shouldAppend = true;
+	}
+
+	// Check the "shouldConfirm" input argument
+	if ( typeof(shouldConfirm) !== "boolean" )
+	{
+		shouldConfirm = true;
+	}
+
+	// If required, confirm the user wants to perform this action
+	if (shouldConfirm)
+	{
+		var alert_response_bool = confirm(confirm_alert_text);
+		if (alert_response_bool == false)
+		{
+			// If false then the user pressed Cancel
+			return;
+		}
+	}
+	
+	// Create a variable for sending an AJAX request
+	var xmlhttp = new XMLHttpRequest();
+	// Add the function to be run when the response is recieved
+	xmlhttp.onreadystatechange = function()
+	{
+		if (this.readyState == 4 && this.status == 200)
+		{
+			// Construct and display the appropriate information
+			var base_string = "";
+			if (shouldAppend)
+			{
+				// Take a copy of the current contents
+				var current_contents = document.getElementById(labelID).innerHTML;
+				// Append the new contents to the start
+				document.getElementById(labelID).innerHTML = base_string + heading_string + "<br>" + this.responseText + "<br><br>" + current_contents;
+			}
+			else
+			{
+				document.getElementById(labelID).innerHTML = base_string + heading_string + "<br>" + this.responseText;
+			}
+
+		}
+		else
+		{
+			// Construct and display the appropriate information
+			var base_string = "";
+			var display_message = getDisplayMessageForXMLHttpRequest(this);
+			if (shouldAppend)
+			{
+				if (this.readyState == 4)
+				{
+					// Take a copy of the current contents
+					var current_contents = document.getElementById(labelID).innerHTML;
+					// Append the new contents to the start
+					document.getElementById(labelID).innerHTML = base_string + heading_string + "<br>" + display_message + "<br><br>" + current_contents;
+				}
+			}
+			else
+			{
+				if (this.readyState == 4)
+				{
+					document.getElementById(labelID).innerHTML = base_string + heading_string + "<br>" + display_message;
+				}
+				else
+				{
+					document.getElementById(labelID).innerHTML = base_string + display_message;
+				}
+			}
+		}
+	};
+	xmlhttp.open("GET", "callBashScript.php?scriptname=" + scriptname_for_php, true);
+	xmlhttp.send();
+}
\ No newline at end of file
diff --git a/web_interface/html/js/fileinput.js b/web_interface/html/js/fileinput.js
new file mode 100644
index 0000000000000000000000000000000000000000..82f5db061996becd9e65348ef0c34b69879e1b5c
--- /dev/null
+++ b/web_interface/html/js/fileinput.js
@@ -0,0 +1,150 @@
+function initializeFileInputs()
+{
+	// Get the input fields into variables
+	var cppfileinput  = document.getElementById("cppfileinput");
+	var yamlfileinput = document.getElementById("yamlfileinput");
+
+	// Add an event listener to each
+	cppfileinput.addEventListener( "change", cppFileInputChangedEvent,  false);
+	yamlfileinput.addEventListener("change", yamlFileInputChangedEvent, false);
+}
+
+
+
+function cppFileInputChangedEvent(event)
+{
+	// Get the file list object
+	// > There should only be one file
+	var files = event.target.files;
+
+	// Parse the file
+	parseFileDetails( files[0] , "cppfiledetails" );
+
+	// Upload the file
+	uploadFile( files[0] , "text/x-c++src" , "cppfileuploadstatus" , "cppuploadform" );
+}
+
+
+
+function yamlFileInputChangedEvent(event)
+{
+	// Get the file list object
+	// > There should only be one file
+	var files = event.target.files;
+
+	// Parse the file
+	parseFileDetails( files[0] , "yamlfiledetails" );
+
+	// Upload the file
+	uploadFile( files[0] , "application/x-yaml" , "yamlfileuploadstatus" , "yamluploadform" );
+}
+
+
+
+function parseFileDetails(file,detailsID)
+{
+	document.getElementById(detailsID).innerHTML = 
+		"<p>File information: <br>" +
+		"name: <strong>" + file.name + "</strong><br>" +
+		"type: <strong>" + file.type + "</strong><br>" +
+		"size: <strong>" + file.size + "</strong> bytes" +
+		"</p>";
+
+	// // display an image
+	// if (file.type.indexOf("image") == 0) {
+	// 	var reader = new FileReader();
+	// 	reader.onload = function(e) {
+	// 		Output(
+	// 			"<p><strong>" + file.name + ":</strong><br />" +
+	// 			'<img src="' + e.target.result + '" /></p>'
+	// 		);
+	// 	}
+	// 	reader.readAsDataURL(file);
+	// }
+
+	// // display text
+	// if (file.type.indexOf("text") == 0) {
+	// 	var reader = new FileReader();
+	// 	reader.onload = function(e) {
+	// 		Output(
+	// 			"<p><strong>" + file.name + ":</strong></p><pre>" +
+	// 			e.target.result.replace(/</g, "&lt;").replace(/>/g, "&gt;") +
+	// 			"</pre>"
+	// 		);
+	// 	}
+	// 	reader.readAsText(file);
+	// }
+
+}
+
+
+function uploadFile(file,expectedFileType,statusID,formID)
+{
+	// Create a variable for sending an AJAX request
+	var xmlhttp = new XMLHttpRequest();
+
+	if (
+		xmlhttp.upload
+		&&
+		file.type == expectedFileType
+		&&
+		file.size <= document.getElementById("MAX_FILE_SIZE").value
+	)
+	{
+
+		document.getElementById(statusID).innerHTML = "Upload progress 0%";
+
+		// create progress bar
+		//var o = $id("progress");
+		//var progress = o.appendChild(document.createElement("p"));
+		//progress.appendChild(document.createTextNode("upload " + file.name));
+
+
+		// progress bar
+		xmlhttp.upload.addEventListener("progress", function(event)
+		{
+			var percent_complete = parseInt( event.loaded / event.total * 100 );
+			//progress.style.backgroundPosition = pc + "% 0";
+			document.getElementById(statusID).innerHTML = "Upload progress " + percent_complete + "%";
+		}, false);
+
+		// file received/failed
+		xmlhttp.onreadystatechange = function(event)
+		{
+			//if (xmlhttp.readyState == 4) {
+			//	progress.className = (xmlhttp.status == 200 ? "success" : "failure");
+			//}
+			if (this.readyState == 4 && this.status == 200)
+			{
+				document.getElementById(statusID).innerHTML = "Upload complete." + this.responseText;
+			}
+		};
+
+		// start upload
+		xmlhttp.open("POST", "upload_async.php", true);
+		xmlhttp.setRequestHeader("X_FILENAME", file.name);
+		xmlhttp.send(file);
+
+	}
+	else
+	{
+		// Display an "ERROR" status
+		document.getElementById(statusID).innerHTML = "<strong>ERROR:</strong>";
+		// Check if upload was the cause of the error:
+		if (!(xmlhttp.upload))
+		{
+			document.getElementById(statusID).innerHTML += "<br>" + "XMLHttpRequest() does not support upload.";
+		}
+		// Check if file type is the cause of the error
+		if (!(file.type == expectedFileType))
+		{
+			document.getElementById(statusID).innerHTML += "<br>" + "file type = " + file.type + ", but it is required to be = " + expectedFileType;
+		}
+		// Check if file size is the cause of the error
+		if (!(file.size <= document.getElementById("MAX_FILE_SIZE").value))
+		{
+			document.getElementById(statusID).innerHTML += "<br>" + "file size = " + file.size + ", is greater than the max allowed of " + document.getElementById("MAX_FILE_SIZE").value + " bytes.";
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/web_interface/html/js/general.js b/web_interface/html/js/general.js
new file mode 100644
index 0000000000000000000000000000000000000000..033fa60d309eb7a709f1a600160fdfc68358e324
--- /dev/null
+++ b/web_interface/html/js/general.js
@@ -0,0 +1,46 @@
+function clearLabelWithGivenID(labelID)
+{
+	document.getElementById(labelID).innerHTML = "";
+}
+
+function roundToDecimalPlaces(value,decimals)
+{
+	return Number(Math.round(value+'e'+decimals)+'e-'+decimals);
+}
+
+function incrementInputFieldWithGivenID(inputID,multiplier)
+{
+	//document.getElementById(inputID).value = 2.0;
+
+	// Get the value of the input field
+	var current_value = parseFloat( document.getElementById(inputID).value );
+
+	// Get the increment of the input field
+	var increment_amount = document.getElementById(inputID).step;
+
+	// Check that the value is a number
+	if (isNaN(current_value))
+	{
+		current_value = 0.0;
+	}
+
+	// Compute the new value
+	var new_value = roundToDecimalPlaces( current_value + multiplier * increment_amount , 3 );
+
+	// Put the new value into the field
+	document.getElementById(inputID).value = new_value;
+}
+
+function putDefaultSetpointForGivenBaseID(inputBaseID)
+{
+	// Construct the ID for the (x,y,z,yaw) input fields
+	var inputID_forX   = inputBaseID + "X";
+	var inputID_forY   = inputBaseID + "Y";
+	var inputID_forZ   = inputBaseID + "Z";
+	var inputID_forYaw = inputBaseID + "Yaw";
+	// Set the default values
+	document.getElementById(inputID_forX).value = 0.0;
+	document.getElementById(inputID_forY).value = 0.0;
+	document.getElementById(inputID_forZ).value = 0.4;
+	document.getElementById(inputID_forYaw).value  = 0.0;
+}
\ No newline at end of file
diff --git a/web_interface/html/js/getSetpointViaRosServiceCall.js b/web_interface/html/js/getSetpointViaRosServiceCall.js
new file mode 100644
index 0000000000000000000000000000000000000000..baef75df8ac98fe23a4927d38fe2ec6d20b80994
--- /dev/null
+++ b/web_interface/html/js/getSetpointViaRosServiceCall.js
@@ -0,0 +1,71 @@
+function getSetpointViaRosServiceCall_outputLabelID(controllerName, labelID)
+{
+	// Convert the "controllerName" to a heading string
+	var scriptname_for_php = "";
+	if (controllerName == "default")
+	{
+		scriptname_for_php = scriptname_for_php + "rosGetSetpointDefault";
+	}
+	else if (controllerName == "student")
+	{
+		scriptname_for_php = scriptname_for_php + "rosGetSetpointStudent";
+	}
+
+	// Set the label to be sending
+	if(labelID){document.getElementById(labelID).innerHTML = "requesting...";}
+	
+	// Create a variable for sending an AJAX request
+	var xmlhttp = new XMLHttpRequest();
+	// Add the function to be run when the response is recieved
+	xmlhttp.onreadystatechange = function()
+	{
+		if (this.readyState == 4 && this.status == 200)
+		{
+			// Get the response into a string
+			var response_as_string = this.responseText;
+			//var response_as_struct = JSON.parse(response_as_string);
+
+			// Check that the string is not empty
+			if (response_as_string)
+			{
+				// NOTE: use https://regex101.com/ to get an explaination
+				// of the regular expressions used
+
+				// Get the x value
+				//var regex_for_x = new RegExp("(x: )([-+]?\d*\.?\d*)");
+				var regex_for_x = /(x: )([-+]?\d*\.?\d*)/;
+				var found_for_x = response_as_string.match(regex_for_x);
+				var x_value_as_float  = parseFloat( found_for_x[2] );
+				var x_value_as_string = x_value_as_float.toFixed(3);
+
+				// Construct and display the appropriate information
+				var base_string = "received x= ";
+				//if(labelID){document.getElementById(labelID).innerHTML = base_string + response_as_string;}
+				if(labelID){document.getElementById(labelID).innerHTML = base_string + x_value_as_string;}
+			}
+			else
+			{
+				// Construct and display the appropriate information
+				var base_string = "received empty response";
+				if(labelID){document.getElementById(labelID).innerHTML = base_string;}
+			}
+
+		}
+		else
+		{
+			// Construct and display the appropriate information
+			var base_string = "";
+			var display_message = getDisplayMessageForXMLHttpRequest(this);
+			if (this.readyState == 4)
+			{
+				if(labelID){document.getElementById(labelID).innerHTML = base_string + display_message;}
+			}
+			else
+			{
+				//if(labelID){document.getElementById(labelID).innerHTML = base_string + display_message;}
+			}
+		}
+	};
+	xmlhttp.open("GET", "callBashScript.php?scriptname=" + scriptname_for_php, true);
+	xmlhttp.send();
+}
\ No newline at end of file
diff --git a/web_interface/html/js/roslaunch.js b/web_interface/html/js/roslaunch.js
new file mode 100644
index 0000000000000000000000000000000000000000..0f537573e430598c7f10f7d17df65169ea76f19c
--- /dev/null
+++ b/web_interface/html/js/roslaunch.js
@@ -0,0 +1,110 @@
+function roslaunch_outputLabelID_clearOtherLabels_clickOtherButtons(launchName, labelID, otherLabels, otherButtons)
+{
+	// Convert the "controllerName" to a heading string
+	var scriptname_for_php = "";
+	if (launchName == "master")
+	{
+		scriptname_for_php = "master";
+	}
+	else if (launchName == "agent")
+	{
+		scriptname_for_php = "agent";
+	}
+	else
+	{
+		return;
+	}
+
+	// Get the booleans for emulation
+	emulated_mocap      = document.getElementById("checkboxEmulateMocap").checked;
+	emulated_crazyradio = document.getElementById("checkboxEmulateCrazyRadio").checked;
+
+	// Set the label to be sending
+	if(labelID){document.getElementById(labelID).innerHTML = "sending...";}
+
+	// Create a variable for sending an AJAX request
+	var xmlhttp = new XMLHttpRequest();
+	// Add the function to be run when the response is recieved
+	xmlhttp.onreadystatechange = function()
+	{
+		if (this.readyState == 4 && this.status == 200)
+		{
+			// Construct and display the appropriate information
+			var base_string = "";
+			if(labelID){document.getElementById(labelID).innerHTML = base_string + this.responseText;}
+			// Click the "other buttons" as requested
+			if (otherButtons)
+			{
+				if ( typeof(otherButtons) == "string" )
+				{
+					document.getElementById(otherButtons).click();
+				}
+				else if (otherButtons.constructor === Array)
+				{
+					for (otherButtonID of otherButtons)
+					{
+						if (otherButtonID)
+						{
+							if ( typeof(otherButtonID) == "string" )
+							{
+								document.getElementById(otherButtonID).click();
+							}
+						}
+					}
+				}
+			}
+
+		}
+		else
+		{
+			// Construct and display the appropriate information
+			var base_string = "";
+			var display_message = getDisplayMessageForXMLHttpRequest(this);
+			if (this.readyState == 4)
+			{
+				if(labelID){document.getElementById(labelID).innerHTML = base_string + display_message;}
+			}
+			else
+			{
+				//if(labelID){document.getElementById(labelID).innerHTML = base_string + display_message;}
+			}
+		}
+	};
+	if (launchName == "master")
+	{
+		xmlhttp.open("GET", "callBashScript_roslaunch.php?scriptname=" + scriptname_for_php + "&emulatemocap=" + emulated_mocap, true);
+		xmlhttp.send();
+	}
+	else if (launchName == "agent")
+	{
+		xmlhttp.open("GET", "callBashScript_roslaunch.php?scriptname=" + scriptname_for_php + "&emulatecrazyradio=" + emulated_crazyradio, true);
+		xmlhttp.send();
+	}
+	else
+	{
+		if(labelID){document.getElementById(labelID).innerHTML = "ERROR: launch name = " + launchName + " is not a valid option";}
+	}
+	
+
+	// Clear the other labels as requested
+	if (otherLabels)
+	{
+		if ( typeof(otherLabels) == "string" )
+		{
+			document.getElementById(otherLabels).innerHTML = "";
+		}
+		else if (otherLabels.constructor === Array)
+		{
+			for (otherLabelID of otherLabels)
+			{
+				if (otherLabelID)
+				{
+					if ( typeof(otherLabelID) == "string" )
+					{
+						document.getElementById(otherLabelID).innerHTML = "";
+					}
+				}
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/web_interface/html/js/sendRosMessage.js b/web_interface/html/js/sendRosMessage.js
new file mode 100644
index 0000000000000000000000000000000000000000..91bbd954e73e6fd31048ae6e88d0866ad28f043c
--- /dev/null
+++ b/web_interface/html/js/sendRosMessage.js
@@ -0,0 +1,77 @@
+function sendRosMessage_outputLabelID(rosMessage, labelID)
+{
+	// Convert the "rosMessage" to a heading string
+	var scriptname_for_php = "";
+	if (rosMessage == "connect")
+	{
+		scriptname_for_php = scriptname_for_php + "rosConnect";
+	}
+	else if (rosMessage == "disconnect")
+	{
+		scriptname_for_php = scriptname_for_php + "rosDisconnect";
+	}
+	else if (rosMessage == "takeoff")
+	{
+		scriptname_for_php = scriptname_for_php + "rosTakeoff";
+	}
+	else if (rosMessage == "land")
+	{
+		scriptname_for_php = scriptname_for_php + "rosLand";
+	}
+	else if (rosMessage == "motorsoff")
+	{
+		scriptname_for_php = scriptname_for_php + "rosMotorsoff";
+	}
+	else if (rosMessage == "enabledefault")
+	{
+		scriptname_for_php = scriptname_for_php + "rosEnabledefault";
+	}
+	else if (rosMessage == "enablestudent")
+	{
+		scriptname_for_php = scriptname_for_php + "rosEnablestudent";
+	}
+	else if (rosMessage == "loadyamldefault")
+	{
+		scriptname_for_php = scriptname_for_php + "rosLoadYamlDefault";
+	}
+	else if (rosMessage == "loadyamlstudent")
+	{
+		scriptname_for_php = scriptname_for_php + "rosLoadYamlStudent";
+	}
+
+
+
+	// Set the label to be sending
+	if(labelID){document.getElementById(labelID).innerHTML = "sending...";}
+	
+	// Create a variable for sending an AJAX request
+	var xmlhttp = new XMLHttpRequest();
+	// Add the function to be run when the response is recieved
+	xmlhttp.onreadystatechange = function()
+	{
+		if (this.readyState == 4 && this.status == 200)
+		{
+			// Construct and display the appropriate information
+			var base_string = "";
+			if(labelID){document.getElementById(labelID).innerHTML = base_string + this.responseText;}
+			//if(labelID){document.getElementById(labelID).innerHTML = base_string + "sent";}
+
+		}
+		else
+		{
+			// Construct and display the appropriate information
+			var base_string = "";
+			var display_message = getDisplayMessageForXMLHttpRequest(this);
+			if (this.readyState == 4)
+			{
+				if(labelID){document.getElementById(labelID).innerHTML = base_string + display_message;}
+			}
+			else
+			{
+				//if(labelID){document.getElementById(labelID).innerHTML = base_string + display_message;}
+			}
+		}
+	};
+	xmlhttp.open("GET", "callBashScript.php?scriptname=" + scriptname_for_php, true);
+	xmlhttp.send();
+}
\ No newline at end of file
diff --git a/web_interface/html/js/setSetpointViaRosMessage.js b/web_interface/html/js/setSetpointViaRosMessage.js
new file mode 100644
index 0000000000000000000000000000000000000000..fce3c8055e2b1cfe59a612409c0852a1aa749145
--- /dev/null
+++ b/web_interface/html/js/setSetpointViaRosMessage.js
@@ -0,0 +1,58 @@
+function setSetpointViaRosMessage_outputLabelID(controllerName, inputBaseID, labelID)
+{
+	// Convert the "controllerName" to a heading string
+	var scriptname_for_php = "";
+	if (controllerName == "default")
+	{
+		scriptname_for_php = scriptname_for_php + "rosSetSetpointDefault";
+	}
+	else if (controllerName == "student")
+	{
+		scriptname_for_php = scriptname_for_php + "rosSetSetpointStudent";
+	}
+
+	// Get the (x,y,z,yaw) values of the new setpoint
+	var inputID_forX   = inputBaseID + "X";
+	var inputID_forY   = inputBaseID + "Y";
+	var inputID_forZ   = inputBaseID + "Z";
+	var inputID_forYaw = inputBaseID + "Yaw";
+	x_new   = document.getElementById(inputID_forX).value;
+	y_new   = document.getElementById(inputID_forY).value;
+	z_new   = document.getElementById(inputID_forZ).value;
+	yaw_new = document.getElementById(inputID_forYaw).value / 57.29578;
+
+
+	// Set the label to be sending
+	if(labelID){document.getElementById(labelID).innerHTML = "sending...";}
+	
+	// Create a variable for sending an AJAX request
+	var xmlhttp = new XMLHttpRequest();
+	// Add the function to be run when the response is recieved
+	xmlhttp.onreadystatechange = function()
+	{
+		if (this.readyState == 4 && this.status == 200)
+		{
+			// Construct and display the appropriate information
+			var base_string = "";
+			if(labelID){document.getElementById(labelID).innerHTML = base_string + this.responseText;}
+			//if(labelID){document.getElementById(labelID).innerHTML = base_string + "sent";}
+
+		}
+		else
+		{
+			// Construct and display the appropriate information
+			var base_string = "";
+			var display_message = getDisplayMessageForXMLHttpRequest(this);
+			if (this.readyState == 4)
+			{
+				if(labelID){document.getElementById(labelID).innerHTML = base_string + display_message;}
+			}
+			else
+			{
+				//if(labelID){document.getElementById(labelID).innerHTML = base_string + display_message;}
+			}
+		}
+	};
+	xmlhttp.open("GET", "callBashScript_setNewSetpoint.php?scriptname=" + scriptname_for_php + "&x=" + x_new + "&y=" + y_new + "&z=" + z_new + "&yaw=" + yaw_new, true);
+	xmlhttp.send();
+}
\ No newline at end of file
diff --git a/web_interface/html/js/sse_agentStatus.js b/web_interface/html/js/sse_agentStatus.js
new file mode 100644
index 0000000000000000000000000000000000000000..34c1172d463b85763d2f5512174812fbeb2f47d7
--- /dev/null
+++ b/web_interface/html/js/sse_agentStatus.js
@@ -0,0 +1,468 @@
+let agentStatusEventSource;
+
+window.onload = function() {
+	document.getElementById("checkboxTopBarStatus").checked = false;
+};
+
+function checkboxTopBarStatus_changed()
+{
+	if ( document.getElementById("checkboxTopBarStatus").checked )
+	{
+		severSentAgentStatus_start();
+	}
+	else
+	{
+		severSentAgentStatus_stop();
+	}
+}
+
+
+function severSentAgentStatus_start()
+{
+	// Check is server sent events are supported
+	if (typeof(EventSource) == "undefined")
+	{
+		// Server-sent events are NOT supported
+		// Display this to the user
+		document.getElementById("agentStatusDebuggingDiv").innerHTML = "Server Sent Events are not supported by this browser.";
+		return;
+	}
+
+	// If the code makes it to here, then
+	// server sent events are supported
+
+	// Create the "EventSource" variable
+	agentStatusEventSource = new EventSource("sse_agentStatus.php");
+
+	// Handle the "onopen" event
+	agentStatusEventSource.onopen = function(eventSource)
+	{
+		// DEBUGGING: print out
+		//document.getElementById("agentStatusDebuggingDiv").innerHTML += "Event: on open <br>";
+	};
+
+	// Handle the "onerror" event
+	agentStatusEventSource.onerror = function(eventSource)
+	{
+		// DEBUGGING: print out
+		document.getElementById("agentStatusDebuggingDiv").innerHTML += "Event: on error <br>";
+
+		// Check is the event is still connecting
+		if (this.readyState == EventSource.CONNECTING)
+		{
+			// DEBUGGING: print out
+			document.getElementById("agentStatusDebuggingDiv").innerHTML += "Reconnecting (readyState = " + this.readyState + ")... <br>";
+		}
+		else
+		{
+			// DEBUGGING: print out
+			document.getElementById("agentStatusDebuggingDiv").innerHTML += "Error has occured. <br>";
+		}
+	};
+
+	// Handle the "message" event
+	//agentStatusEventSource.onmessage = function(eventSource)
+	agentStatusEventSource.addEventListener("message", function(eventSource)
+	{
+		// DEBUGGING: print out the whole message
+		//document.getElementById("agentStatusDebuggingDiv").innerHTML += "Event: message, data: " + eventSource.data + " <br>";
+	});
+
+	// Handle the "ping" event
+	agentStatusEventSource.addEventListener("agentstatus", function(eventSource)
+	{
+		// Extract "agent found" entry in the json
+		agent_found = JSON.parse(eventSource.data).agentfound;
+
+		// If the agent is found
+		if ( agent_found === "true" )
+		{
+			// Parse the status dictionary from the JSON
+			status_dict = JSON.parse(eventSource.data).statusjson;
+			
+			// Call the fuctions to update the status icons
+			// > For the Radio status:		
+			updateStatusIconRadio( status_dict.crazyradiostatus );
+			// > For the Battery level:
+			updateStatusIconBattery( status_dict.batterylevel );
+			// > For the Flying state:
+			updateStatusIconFlyingState( status_dict.flyingstate );
+			// > For the Instant controller:
+			updateStatusForInstantController( status_dict.instantcontroller );
+
+			// Call the function to update the "measurement,
+			// setpoint, error" tables
+			// > For the Default controller:
+			updateDefaultMseTable( status_dict.stateestimate , status_dict.setpointdefault );
+			// > For the Student controller:
+			updateStudentMseTable( status_dict.stateestimate , status_dict.setpointstudent );
+
+			// Call the function to update the "debug values" table
+			updateStudentDebugValuesTable( status_dict.debugvaluesstudent );
+
+			// DEBUGGING: print out the whole message
+			//document.getElementById("agentStatusDebuggingDiv").innerHTML += "Event: agent status, data: " + eventSource.data + " <br>";
+		}
+		// Otherwise, the agent is NOT found
+		else
+		{
+			// So set all the icons accordingly
+			// > For the Radio status:		
+			updateStatusIconRadio( "disconnected" );
+			// > For the Battery level:
+			updateStatusIconBattery( "unavailable" );
+			// > For the Flying state:
+			updateStatusIconFlyingState( "unavailable" );
+			// > For the Instant controller:
+			updateStatusForInstantController( "none" );
+
+			// Call the function to clear the "measurement,
+			// setpoint, error" tables
+			// > For the Default controller:
+			clearDefaultMseTable();
+			// > For the Student controller:
+			clearStudentMseTable();
+
+			// Call the function to clear the "debug values" table
+			clearStudentDebugValuesTable();
+
+			// DEBUGGING: print out the whole message
+			//document.getElementById("agentStatusDebuggingDiv").innerHTML += "Event: agent status, data: " + eventSource.data + " <br>";
+		}
+	});
+
+} // END OF: function severSentAgentStatus_start()
+
+
+
+
+
+function severSentAgentStatus_stop()
+{
+	// Check is server sent events are supported
+	if (typeof(EventSource) == "undefined")
+	{
+		// Server-sent events are NOT supported
+		// Display this to the user
+		document.getElementById("agentStatusDebuggingDiv").innerHTML = "Server Sent Events are not supported by this browser.";
+		return;
+	}
+
+	// If the code makes it to here, then
+	// server sent events are supported
+
+	// Close the "EventSource" variable
+	agentStatusEventSource.close();
+
+	// DEBUGGING: print out
+	//document.getElementById("agentStatusDebuggingDiv").innerHTML += "Closed. <br>";
+
+	// So set all the icons accordingly
+	// > For the Radio status:		
+	updateStatusIconRadio( "disconnected" );
+	// > For the Battery level:
+	updateStatusIconBattery( "unavailable" );
+	// > For the Flying state:
+	updateStatusIconFlyingState( "unavailable" );
+	// > For the Instant controller:
+	updateStatusForInstantController( "none" );
+
+	// Call the function to clear the "measurement,
+	// setpoint, error" tables
+	// > For the Default controller:
+	clearDefaultMseTable();
+	// > For the Student controller:
+	clearStudentMseTable();
+
+	// Call the function to clear the "debug values" table
+	clearStudentDebugValuesTable();
+
+} // END OF: function severSentAgentStatus_stop()
+
+
+
+function updateStatusIconRadio( status_string )
+{
+	if ( typeof status_string !== "string" )
+	{
+		// Default to disconnected
+		status_string = "disconnected";
+	}
+
+	switch ( status_string.toLowerCase() )
+	{
+		case "connected":
+			document.getElementById("radio-icon").src = "img/rf_connected.png";
+			break;
+		case "connecting":
+			document.getElementById("radio-icon").src = "img/rf_connecting.png";
+			break;
+		case "disconnected":
+			document.getElementById("radio-icon").src = "img/rf_disconnected.png";
+			break;
+		default:
+			document.getElementById("radio-icon").src = "img/rf_disconnected.png";
+	}
+
+} // END OF: "function updateStatusIconRadio( status_string )"
+
+
+
+function updateStatusIconBattery( level_string )
+{
+	if ( typeof level_string !== "string" )
+	{
+		// Default to unavailable
+		level_string = "unavailable";
+	}
+
+	switch ( level_string.toLowerCase() )
+	{
+		case "000":
+			document.getElementById("battery-icon").src = "img/battery_empty.png";
+			break;
+		case "010":
+			document.getElementById("battery-icon").src = "img/battery_20.png";
+			break;
+		case "020":
+			document.getElementById("battery-icon").src = "img/battery_20.png";
+			break;
+		case "030":
+			document.getElementById("battery-icon").src = "img/battery_40.png";
+			break;
+		case "040":
+			document.getElementById("battery-icon").src = "img/battery_40.png";
+			break;
+		case "050":
+			document.getElementById("battery-icon").src = "img/battery_60.png";
+			break;
+		case "060":
+			document.getElementById("battery-icon").src = "img/battery_60.png";
+			break;
+		case "070":
+			document.getElementById("battery-icon").src = "img/battery_80.png";
+			break;
+		case "080":
+			document.getElementById("battery-icon").src = "img/battery_80.png";
+			break;
+		case "090":
+			document.getElementById("battery-icon").src = "img/battery_full.png";
+			break;
+		case "100":
+			document.getElementById("battery-icon").src = "img/battery_full.png";
+			break;
+		case "unknown":
+			document.getElementById("battery-icon").src = "img/battery_unknown.png";
+			break;
+		case "unavailable":
+			document.getElementById("battery-icon").src = "img/battery_unavailable.png";
+			break;
+		default:
+			document.getElementById("battery-icon").src = "img/battery_unavailable.png";
+	}
+
+} // END OF: "function updateStatusIconBattery( level_string )"
+
+
+
+function updateStatusIconFlyingState( state_string )
+{
+	if ( typeof state_string !== "string" )
+	{
+		// Default to unavailable
+		state_string = "unavailable";
+	}
+
+	switch ( state_string.toLowerCase() )
+	{
+		case "motorsoff":
+			document.getElementById("flying-state-icon").src = "img/flying_state_off.png";
+			break;
+		case "takeoff":
+			document.getElementById("flying-state-icon").src = "img/flying_state_enabling.png";
+			break;
+		case "flying":
+			document.getElementById("flying-state-icon").src = "img/flying_state_flying.png";
+			break;
+		case "land":
+			document.getElementById("flying-state-icon").src = "img/flying_state_disabling.png";
+			break;
+		case "unavailable":
+			document.getElementById("flying-state-icon").src = "img/flying_state_unavailable.png";
+			break;
+		default:
+			document.getElementById("flying-state-icon").src = "img/flying_state_unavailable.png";
+	}
+
+} // END OF: "function updateStatusIconRadio( status_string )"
+
+
+
+function updateStatusForInstantController( controller_string )
+{
+	if ( typeof controller_string !== "string" )
+	{
+		// Default to unavailable
+		controller_string = "none";
+	}
+
+	// Colours:
+	// #c43c35    Dark Red
+	// #f44336    Light Red
+	// #57a957    Green
+
+	// Set all border colours to red
+	document.getElementById("control-tab-panel-default").style.borderColor = "#c43c35";
+	document.getElementById("control-tab-panel-student").style.borderColor = "#c43c35";
+
+	switch ( controller_string.toLowerCase() )
+	{
+		case "default":
+			document.getElementById("control-tab-panel-default").style.borderColor = "#57a957";
+			break;
+		case "student":
+			document.getElementById("control-tab-panel-student").style.borderColor = "#57a957";
+			break;
+	}
+
+} // END OF: "function updateStatusIconRadio( status_string )"
+
+
+function updateDefaultMseTable( measurement_dict , setpoint_dict )
+{
+	if ( (typeof measurement_dict !== "object") || (typeof setpoint_dict !== "object") )
+	{
+		// Call function to set fields to blank
+		clearDefaultMseTable();
+		return;
+	}
+
+	document.getElementById("default-measurement-x").innerHTML     = measurement_dict.x.toFixed(3);
+	document.getElementById("default-measurement-y").innerHTML     = measurement_dict.y.toFixed(3);
+	document.getElementById("default-measurement-z").innerHTML     = measurement_dict.z.toFixed(3);
+	document.getElementById("default-measurement-yaw").innerHTML   = measurement_dict.yaw.toFixed(3);
+	document.getElementById("default-measurement-pitch").innerHTML = measurement_dict.pitch.toFixed(1);
+	document.getElementById("default-measurement-roll").innerHTML  = measurement_dict.roll.toFixed(1);
+
+	document.getElementById("default-setpoint-x").innerHTML     = setpoint_dict.x.toFixed(3);
+	document.getElementById("default-setpoint-y").innerHTML     = setpoint_dict.y.toFixed(3);
+	document.getElementById("default-setpoint-z").innerHTML     = setpoint_dict.z.toFixed(3);
+	document.getElementById("default-setpoint-yaw").innerHTML   = setpoint_dict.yaw.toFixed(1);
+
+	document.getElementById("default-error-x").innerHTML     = (measurement_dict.x  -setpoint_dict.x  ).toFixed(3);
+	document.getElementById("default-error-y").innerHTML     = (measurement_dict.y  -setpoint_dict.y  ).toFixed(3);
+	document.getElementById("default-error-z").innerHTML     = (measurement_dict.z  -setpoint_dict.z  ).toFixed(3);
+	document.getElementById("default-error-yaw").innerHTML   = (measurement_dict.yaw-setpoint_dict.yaw).toFixed(1);
+
+} // END OF: "function updateDefaultMseTable( measurement_dict , setpoint_dict )"
+
+function clearDefaultMseTable()
+{
+	document.getElementById("default-measurement-x").innerHTML     = "xx.xx";
+	document.getElementById("default-measurement-y").innerHTML     = "xx.xx";
+	document.getElementById("default-measurement-z").innerHTML     = "xx.xx";
+	document.getElementById("default-measurement-yaw").innerHTML   = "xx.xx";
+	document.getElementById("default-measurement-pitch").innerHTML = "xx.xx";
+	document.getElementById("default-measurement-roll").innerHTML  = "xx.xx";
+
+	document.getElementById("default-setpoint-x").innerHTML     = "xx.xx";
+	document.getElementById("default-setpoint-y").innerHTML     = "xx.xx";
+	document.getElementById("default-setpoint-z").innerHTML     = "xx.xx";
+	document.getElementById("default-setpoint-yaw").innerHTML   = "xx.xx";
+
+	document.getElementById("default-error-x").innerHTML     = "xx.xx";
+	document.getElementById("default-error-y").innerHTML     = "xx.xx";
+	document.getElementById("default-error-z").innerHTML     = "xx.xx";
+	document.getElementById("default-error-yaw").innerHTML   = "xx.xx";
+
+} // END OF: "function clearDefaultMseTable()"
+
+
+
+function updateStudentMseTable( measurement_dict , setpoint_dict )
+{
+	if ( (typeof measurement_dict !== "object") || (typeof setpoint_dict !== "object") )
+	{
+		// Call function to set fields to blank
+		clearStudentMseTable();
+		return;
+	}
+
+	document.getElementById("student-measurement-x").innerHTML     = measurement_dict.x.toFixed(3);
+	document.getElementById("student-measurement-y").innerHTML     = measurement_dict.y.toFixed(3);
+	document.getElementById("student-measurement-z").innerHTML     = measurement_dict.z.toFixed(3);
+	document.getElementById("student-measurement-yaw").innerHTML   = measurement_dict.yaw.toFixed(3);
+	document.getElementById("student-measurement-pitch").innerHTML = measurement_dict.pitch.toFixed(1);
+	document.getElementById("student-measurement-roll").innerHTML  = measurement_dict.roll.toFixed(1);
+
+	document.getElementById("student-setpoint-x").innerHTML     = setpoint_dict.x.toFixed(3);
+	document.getElementById("student-setpoint-y").innerHTML     = setpoint_dict.y.toFixed(3);
+	document.getElementById("student-setpoint-z").innerHTML     = setpoint_dict.z.toFixed(3);
+	document.getElementById("student-setpoint-yaw").innerHTML   = setpoint_dict.yaw.toFixed(1);
+
+	document.getElementById("student-error-x").innerHTML     = (measurement_dict.x  -setpoint_dict.x  ).toFixed(3);
+	document.getElementById("student-error-y").innerHTML     = (measurement_dict.y  -setpoint_dict.y  ).toFixed(3);
+	document.getElementById("student-error-z").innerHTML     = (measurement_dict.z  -setpoint_dict.z  ).toFixed(3);
+	document.getElementById("student-error-yaw").innerHTML   = (measurement_dict.yaw-setpoint_dict.yaw).toFixed(1);
+
+} // END OF: "function updateStudentMseTable( measurement_dict , setpoint_dict )"
+
+function clearStudentMseTable()
+{
+	document.getElementById("student-measurement-x").innerHTML     = "xx.xx";
+	document.getElementById("student-measurement-y").innerHTML     = "xx.xx";
+	document.getElementById("student-measurement-z").innerHTML     = "xx.xx";
+	document.getElementById("student-measurement-yaw").innerHTML   = "xx.xx";
+	document.getElementById("student-measurement-pitch").innerHTML = "xx.xx";
+	document.getElementById("student-measurement-roll").innerHTML  = "xx.xx";
+
+	document.getElementById("student-setpoint-x").innerHTML     = "xx.xx";
+	document.getElementById("student-setpoint-y").innerHTML     = "xx.xx";
+	document.getElementById("student-setpoint-z").innerHTML     = "xx.xx";
+	document.getElementById("student-setpoint-yaw").innerHTML   = "xx.xx";
+
+	document.getElementById("student-error-x").innerHTML     = "xx.xx";
+	document.getElementById("student-error-y").innerHTML     = "xx.xx";
+	document.getElementById("student-error-z").innerHTML     = "xx.xx";
+	document.getElementById("student-error-yaw").innerHTML   = "xx.xx";
+
+} // END OF: "function clearStudentMseTable()"
+
+
+
+
+function updateStudentDebugValuesTable( values_dict )
+{
+	if (typeof values_dict !== "object")
+	{
+		// Call function to set fields to blank
+		clearStudentDebugValuesTable();
+		return;
+	}
+
+	document.getElementById("debug-value1").innerHTML  = values_dict.value1.toFixed(3);
+	document.getElementById("debug-value2").innerHTML  = values_dict.value2.toFixed(3);
+	document.getElementById("debug-value3").innerHTML  = values_dict.value3.toFixed(3);
+	document.getElementById("debug-value4").innerHTML  = values_dict.value4.toFixed(3);
+	document.getElementById("debug-value5").innerHTML  = values_dict.value5.toFixed(3);
+	document.getElementById("debug-value6").innerHTML  = values_dict.value6.toFixed(3);
+	document.getElementById("debug-value7").innerHTML  = values_dict.value7.toFixed(3);
+	document.getElementById("debug-value8").innerHTML  = values_dict.value8.toFixed(3);
+	document.getElementById("debug-value9").innerHTML  = values_dict.value9.toFixed(3);
+	document.getElementById("debug-value10").innerHTML = values_dict.value10.toFixed(3);
+
+} // END OF: "function updateStudentDebugValuesTable( values_dict )"
+
+function clearStudentDebugValuesTable()
+{
+	document.getElementById("debug-value1").innerHTML  = "xx.xx";
+	document.getElementById("debug-value2").innerHTML  = "xx.xx";
+	document.getElementById("debug-value3").innerHTML  = "xx.xx";
+	document.getElementById("debug-value4").innerHTML  = "xx.xx";
+	document.getElementById("debug-value5").innerHTML  = "xx.xx";
+	document.getElementById("debug-value6").innerHTML  = "xx.xx";
+	document.getElementById("debug-value7").innerHTML  = "xx.xx";
+	document.getElementById("debug-value8").innerHTML  = "xx.xx";
+	document.getElementById("debug-value9").innerHTML  = "xx.xx";
+	document.getElementById("debug-value10").innerHTML = "xx.xx";
+} // END OF: "function clearStudentDebugValuesTable()"
\ No newline at end of file
diff --git a/web_interface/html/page_footer.html b/web_interface/html/page_footer.html
new file mode 100644
index 0000000000000000000000000000000000000000..62d09b8221fb59ebb772816f5ff6f9976095615a
--- /dev/null
+++ b/web_interface/html/page_footer.html
@@ -0,0 +1 @@
+</html>
\ No newline at end of file
diff --git a/web_interface/html/page_header.html b/web_interface/html/page_header.html
new file mode 100644
index 0000000000000000000000000000000000000000..92c815de57e633259c3d13f5dde29ac9a0bf94e4
--- /dev/null
+++ b/web_interface/html/page_header.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+
+	<!-- Some technical meta data -->
+	<meta charset="UTF-8" />
+	<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 
+	<meta name="viewport" content="width=device-width, initial-scale=1.0"> 
+
+	<!-- META DATA ABOUT ME AND MY PAGE -->
+	<title>D-FaLL Web Interface</title>
+
+	<meta name="description" content="Web interface for controlling the D-FaLL-System" />
+
+	<meta name="author" content="Paul N. Beuchat">
+
+	<meta name="keywords" content="ethz, D-ITET, IfA, dfall, D-FaLL" />
+
+	<!-- Link the CSS files -->
+	<link rel="stylesheet" type="text/css" href="css/default.css?ver=0.1" />
+	<link rel="stylesheet" type="text/css" href="css/layout.css?ver=0.1" />
+	<link rel="stylesheet" type="text/css" href="css/body.css?ver=0.1" />
+	<link rel="stylesheet" type="text/css" href="css/buttons.css?ver=0.1" />
+	<link rel="stylesheet" type="text/css" href="css/switches.css?ver=0.1" />
+
+	<link rel="stylesheet" type="text/css" href="css/tabs_main.css?ver=0.1" />
+	<link rel="stylesheet" type="text/css" href="css/tabs_home.css?ver=0.1" />
+	<link rel="stylesheet" type="text/css" href="css/tabs_control.css?ver=0.1" />
+	<link rel="stylesheet" type="text/css" href="css/status_bar.css?ver=0.1" />
+	<link rel="stylesheet" type="text/css" href="css/measurement_setpoint_error_table.css?ver=0.1" />
+	<link rel="stylesheet" type="text/css" href="css/debug_values_table.css?ver=0.1" />
+
+	<!-- Link the JavaScript files -->
+	<script src="js/general.js?ver=0.1"></script>
+	<script src="js/callbashscript.js?ver=0.1"></script>
+	<script src="js/callgit.js?ver=0.1"></script>
+	<script src="js/roslaunch.js?ver=0.1"></script>
+	<script src="js/sendRosMessage.js?ver=0.1"></script>
+	<script src="js/setSetpointViaRosMessage.js?ver=0.1"></script>
+	<script src="js/getSetpointViaRosServiceCall.js?ver=0.1"></script>
+
+</head>
\ No newline at end of file
diff --git a/web_interface/html/phpinfo.php b/web_interface/html/phpinfo.php
new file mode 100644
index 0000000000000000000000000000000000000000..54bd1bc952e8c41d31c41cd53d4345b8e58ed466
--- /dev/null
+++ b/web_interface/html/phpinfo.php
@@ -0,0 +1 @@
+<?php echo 'Simple test for now'; ?>
diff --git a/web_interface/html/sse_agentStatus.php b/web_interface/html/sse_agentStatus.php
new file mode 100644
index 0000000000000000000000000000000000000000..60eeed050c0c046e9bd82d49ff6cc8b688679296
--- /dev/null
+++ b/web_interface/html/sse_agentStatus.php
@@ -0,0 +1,30 @@
+ <?php
+	//date_default_timezone_set("America/New_York");
+	header("Cache-Control: no-cache");
+	header("Content-Type: text/event-stream");
+	//header('Connection: keep-alive');
+
+	$event_id_counter = 0;
+
+	while (true) {
+		// Every second, send a "ping" event.
+
+		echo "event: agentstatus\n";
+
+		$output = shell_exec("./bashscripts/rosGetStatusJson_forAgent.sh " . $event_id_counter);
+
+		//$curDate = date(DATE_ISO8601);
+		//echo 'data: {"time": "' . $curDate . '"}';
+
+		echo "data: $output";
+		echo "\n\n";
+
+		// Send a simple message at random intervals.
+
+		$event_id_counter++;
+
+		ob_end_flush();
+		flush();
+		usleep(250000);
+	}
+?>
\ No newline at end of file
diff --git a/web_interface/html/updatewebinterface.php b/web_interface/html/updatewebinterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..663b75acb59c2ae4738bf642eb453ba449f278b4
--- /dev/null
+++ b/web_interface/html/updatewebinterface.php
@@ -0,0 +1,5 @@
+<?php
+	$temp = shell_exec("./bashscripts/updatewebinterface.sh");
+	$output = "<pre>$temp</pre>";
+	echo "$output";
+?>
diff --git a/web_interface/html/upload.php b/web_interface/html/upload.php
new file mode 100644
index 0000000000000000000000000000000000000000..0daebd7cce2ac346d35c8c0ae6dd8c20b0cb6861
--- /dev/null
+++ b/web_interface/html/upload.php
@@ -0,0 +1,22 @@
+<?php
+$target_dir = "uploads/";
+$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
+$uploadOk = 1;
+$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
+// Allow certain file formats
+if($imageFileType != "cpp") {
+    echo "Sorry, only C++ files are allowed. ";
+    $uploadOk = 0;
+}
+// Check if $uploadOk is set to 0 by an error
+if ($uploadOk == 0) {
+    echo "Your file was not uploaded.";
+// if everything is ok, try to upload file
+} else {
+    if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
+        echo "The file ". basename( $_FILES["fileToUpload"]["name"]). " has been uploaded.";
+    } else {
+        echo "Sorry, there was an error uploading your file.";
+    }
+}
+?>
\ No newline at end of file
diff --git a/web_interface/html/upload_async.php b/web_interface/html/upload_async.php
new file mode 100644
index 0000000000000000000000000000000000000000..324e92e621b0fc6d2e5c49f2fcf0e2ca2d5fe718
--- /dev/null
+++ b/web_interface/html/upload_async.php
@@ -0,0 +1,41 @@
+<?php
+
+	echo "DEBUG1";
+
+	$fn = (isset($_SERVER['HTTP_X_FILENAME']) ? $_SERVER['HTTP_X_FILENAME'] : false);
+
+	echo "DEBUG2";
+
+	echo "$fn";
+
+	if ($fn)
+	{
+		echo "DEBUG3";
+
+		// AJAX call
+		file_put_contents(
+			'uploads/' . $fn,
+			file_get_contents('php://input')
+		);
+		echo "$fn uploaded";
+		exit();
+
+	}
+	else
+	{
+		echo "DEBUG4";
+		// // form submit
+		// $files = $_FILES['fileselect'];
+
+		// foreach ($files['error'] as $id => $err) {
+		// 	if ($err == UPLOAD_ERR_OK) {
+		// 		$fn = $files['name'][$id];
+		// 		move_uploaded_file(
+		// 			$files['tmp_name'][$id],
+		// 			'uploads/' . $fn
+		// 		);
+		// 		echo "<p>File $fn uploaded.</p>";
+		// 	}
+		// }
+	}
+?>
\ No newline at end of file
diff --git a/web_interface/install_dfall_server_WIP.sh b/web_interface/install_dfall_server_WIP.sh
new file mode 100644
index 0000000000000000000000000000000000000000..a0aea03a682aa50494753963850817af99bde4cd
--- /dev/null
+++ b/web_interface/install_dfall_server_WIP.sh
@@ -0,0 +1,59 @@
+# Install the apache web server
+sudo apt install apache2
+
+# Install php
+sudo apt install php
+
+# DISABLE iPv6
+
+# CRTICAL TO GET THE gateway4 and nameserver correct
+# for example 192.168.0.1
+
+# Create a shared folder
+cd /home
+sudo mkdir www-share
+sudo chmod 777 www-share
+cd www-share
+sudo -u www-data mkdir dfall
+sudo -u www-data chmod 775 dfall
+
+# Clone the repository
+# NOTE: very important here is that the repository
+#       is cloned as the www-data user
+cd /home/www-share/dfall
+sudo -u www-data git clone https://gitlab.ethz.ch/dfall/dfall-system
+
+# Add the necessary line to the "/etc/sudoers" file
+# that allows the "www-data" user to execute
+# "git pull" commands
+# >> www-data ALL=(www-data) /usr/bin/git pull
+
+# Add the "www-data" user to the "plugdev" group
+# NOTE: this is the group nominated in the udev
+#       rules for the CrazyRadio (see the "install"
+#       folder). This allows a CrazyRadio node
+#       that is launched by the web interface to
+#       access the USB dongle.
+sudo usermod -a -G plugdev www-data
+
+# To confirm the group allocation, view the file:
+# >> less /etc/group
+
+# If you need to remove a user from a group, then:
+# SYNTAX: >> deluser <username> <groupname>
+# >> deluser www-data plugdev
+
+
+
+
+# ============================================ #
+# USEFUL COMMANDS
+#
+# The apache web server can be
+# {stop,start,restart,reload}
+# using the "systemctl" command as follows:
+#
+#sudo systemctl stop apache2.service
+#sudo systemctl start apache2.service
+#sudo systemctl restart apache2.service
+#sudo systemctl reload apache2.service
\ No newline at end of file