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 bd79177a79d05cb8d14f5976d1ea5ab25cf9cd40..e848317a9561d340ffe22e4156c7c15d4f270e0b 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
@@ -204,7 +204,7 @@
      <string>LoadYAML</string>
     </property>
     <addaction name="action_LoadYAML_BatteryMonitor"/>
-    <addaction name="action_LoadYAML_ClientConfig"/>
+    <addaction name="action_LoadYAML_FlyingAgentClientConfig"/>
    </widget>
    <widget class="QMenu" name="menuControllers">
     <property name="title">
@@ -239,9 +239,9 @@
     <string>BatteryMonitor</string>
    </property>
   </action>
-  <action name="action_LoadYAML_ClientConfig">
+  <action name="action_LoadYAML_FlyingAgentClientConfig">
    <property name="text">
-    <string>ClientConfig</string>
+    <string>FlyingAgentClientConfig</string>
    </property>
   </action>
   <action name="action_showHideController_default">
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 2cfdc26874205d9e8c51fa7c46bf24568d0b0446..916869bd8ed40c3807059ec66cfe184db17b2f5f 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
@@ -124,7 +124,7 @@ private slots:
     // PRIVATE METHODS FOR MENU ITEM CALLBACKS
     void on_actionShowHide_Coordinator_triggered();
     void on_action_LoadYAML_BatteryMonitor_triggered();
-    void on_action_LoadYAML_ClientConfig_triggered();
+    void on_action_LoadYAML_FlyingAgentClientConfig_triggered();
 
     // FOR THE CONTROLLERS MENU
     void on_action_showHideController_default_changed();
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 239aa269a5e2794a8fc7daffe14aa0405ce65040..0a523fe34ee7aa2199456e18ef1cea04d7fa64e9 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
@@ -194,7 +194,7 @@ void MainWindow::on_action_LoadYAML_BatteryMonitor_triggered()
 }
 
 
-void MainWindow::on_action_LoadYAML_ClientConfig_triggered()
+void MainWindow::on_action_LoadYAML_FlyingAgentClientConfig_triggered()
 {
 #ifdef CATKIN_MAKE
     // Inform the user that the menu item was selected
@@ -203,7 +203,7 @@ void MainWindow::on_action_LoadYAML_ClientConfig_triggered()
     // Create a local variable for the message
     StringWithHeader yaml_filename_msg;
     // Specify the data
-    yaml_filename_msg.data = "ClientConfig";
+    yaml_filename_msg.data = "FlyingAgentClientConfig";
     // Set for whom this applies to
     yaml_filename_msg.shouldCheckForAgentID = false;
     // Send the message
diff --git a/dfall_ws/src/dfall_pkg/include/nodes/DefaultControllerConstants.h b/dfall_ws/src/dfall_pkg/include/nodes/DefaultControllerConstants.h
index e32c39e22a3328d17fc99d0f31459e8d836a75bd..a9beaf7ed658f18b79df4af6b7a30c9f250fed49 100644
--- a/dfall_ws/src/dfall_pkg/include/nodes/DefaultControllerConstants.h
+++ b/dfall_ws/src/dfall_pkg/include/nodes/DefaultControllerConstants.h
@@ -41,13 +41,15 @@
 
 // TO IDENITFY THE STATE OF THE DEFAULT CONTROLLER
 
-#define DEFAULT_CONTROLLER_STATE_UNKNOWN      -1
+#define DEFAULT_CONTROLLER_STATE_NORMAL        1
 #define DEFAULT_CONTROLLER_STATE_STANDBY      99
+#define DEFAULT_CONTROLLER_STATE_UNKNOWN      -1
 
 // > The sequence of states for a TAKE-OFF manoeuvre
 #define DEFAULT_CONTROLLER_STATE_TAKEOFF_SPIN_MOTORS      11
 #define DEFAULT_CONTROLLER_STATE_TAKEOFF_MOVE_UP          12
 #define DEFAULT_CONTROLLER_STATE_TAKEOFF_GOTO_SETPOINT    13
+#define DEFAULT_CONTROLLER_STATE_TAKEOFF_INTEGRATOR_ON    14
 
 // > The sequence of states for a LANDING manoeuvre
 #define DEFAULT_CONTROLLER_STATE_LANDING_MOVE_DOWN        21
diff --git a/dfall_ws/src/dfall_pkg/include/nodes/DefaultControllerService.h b/dfall_ws/src/dfall_pkg/include/nodes/DefaultControllerService.h
index 8900c471a72532ecc9012fbfb4fbf0d681e6380a..1fc29bdb216b8d58aab9129eb95b3253ca6d4c5e 100644
--- a/dfall_ws/src/dfall_pkg/include/nodes/DefaultControllerService.h
+++ b/dfall_ws/src/dfall_pkg/include/nodes/DefaultControllerService.h
@@ -104,10 +104,28 @@ using namespace dfall_pkg;
 
 // NOTE: many constants are already defined in the "Constant.h" header file
 
-// These constants define the method used for estimating the Inertial
-// frame state.
-// All methods are run at all times, this flag indicates which estimate
-// is passed onto the controller.
+// These constants define the method used for computing
+// the control actions from the state error estimates.
+// The following is a short description about each mode:
+//
+// CONTROLLER_METHOD_RATES
+//       Uses the poisition, linear velocity and angle
+//       error estimates to compute the rates
+//
+// CONTROLLER_METHOD_RATE_ANGLE_NESTED
+//       Uses the position and linear velocity error
+//       estimates to compute an angle, and then uses
+//       this as a reference to construct an angle error
+//       estimate and compute from that the rates
+//
+#define CONTROLLER_METHOD_RATES               1
+#define CONTROLLER_METHOD_RATE_ANGLE_NESTED   2   // (DEFAULT)
+
+
+// These constants define the method used for estimating
+// the Inertial frame state.
+// All methods are run at all times, this flag indicates
+// which estimate is passed onto the controller.
 // The following is a short description about each mode:
 //
 // ESTIMATOR_METHOD_FINITE_DIFFERENCE
@@ -160,21 +178,58 @@ float m_time_in_seconds = 0.0;
 float yaml_max_setpoint_change_per_second_horizontal = 0.1;
 float yaml_max_setpoint_change_per_second_vertical = 0.1;
 
+// Max error for z
+float yaml_max_setpoint_error_z = 0.4;
+
 // Max error for yaw angle
 float yaml_max_setpoint_error_yaw_degrees = 60.0;
 float yaml_max_setpoint_error_yaw_radians = 60.0 * DEG2RAD;
 
+// Max {roll,pitch} angle request
+float yaml_max_roll_pitch_request_degrees = 30.0;
+float yaml_max_roll_pitch_request_radians = 30.0 * DEG2RAD;
+
+// Theshold for {roll,pitch} angle beyond
+// which the motors are turned off
+float yaml_threshold_roll_pitch_for_turn_off_degrees = 70.0;
+float yaml_threshold_roll_pitch_for_turn_off_radians = 70.0 * DEG2RAD;
+
 // The thrust for take off spin motors
 float yaml_takeoff_spin_motors_thrust = 8000;
-// The time for the take off spin(-up) motors
-float takoff_spin_motots_time = 0.8;
+// The time for: take off spin(-up) motors
+float yaml_takoff_spin_motors_time = 0.8;
 
 // Height change for the take off move-up
 float yaml_takeoff_move_up_start_height = 0.1;
 float yaml_takeoff_move_up_end_height   = 0.4;
-// The time for the take off spin motors
+// The time for: take off spin motors
 float yaml_takoff_move_up_time = 1.2;
 
+// Minimum and maximum allowed time for: take off goto setpoint
+float yaml_takoff_goto_setpoint_min_time = 1.2;
+float yaml_takoff_goto_setpoint_max_time = 2.0;
+
+// Box within which to keep the integrator on
+// > Units of [meters]
+// > The box consider is plus/minus this value
+float yaml_takoff_integrator_on_box_horizontal = 0.25;
+float yaml_takoff_integrator_on_box_vertical   = 0.15;
+// The time for: take off integrator-on
+float yaml_takoff_integrator_on_time = 1.5;
+
+
+// Height change for the landing move-down
+float yaml_landing_move_down_end_height_setpoint  = 0.05;
+float yaml_landing_move_down_end_height_threshold = 0.10;
+// The time for: landing move-down
+float yaml_landing_move_down_time_max = 2.0;
+
+// The thrust for landing spin motors
+float yaml_landing_spin_motors_thrust = 10000;
+// The time for: landing spin motors
+float yaml_landing_spin_motors_time = 1.0;
+
+
 
 
 // The setpoint to be tracked, the ordering is (x,y,z,yaw),
@@ -244,12 +299,21 @@ bool yaml_shouldDisplayDebugInfo = false;
 
 // VARIABLES FOR THE CONTROLLER
 
-// The LQR Controller parameters for "CONTROLLER_MODE_LQR_RATE"
-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};
+// > A flag for which controller to use:
+int yaml_controller_method = CONTROLLER_METHOD_RATE_ANGLE_NESTED;
 
+// The LQR Controller parameters for z-height
+std::vector<float> yaml_gainMatrixThrust_2StateVector     =  { 0.98, 0.25};
+// The LQR Controller parameters for "CONTROLLER_METHOD_RATES"
+std::vector<float> yaml_gainMatrixRollRate_3StateVector   =  {-6.20,-3.00, 5.20};
+std::vector<float> yaml_gainMatrixPitchRate_3StateVector  =  { 6.20, 3.00, 5.20};
+// The LQR Controller parameters for "CONTROLLER_METHOD_RATE_ANGLE_NESTED"
+std::vector<float> yaml_gainMatrixRollAngle_2StateVector  =  {-0.20,-0.20};
+std::vector<float> yaml_gainMatrixPitchAngle_2StateVector =  { 0.20, 0.20};
+float yaml_gainRollRate_fromAngle   =  4.00;
+float yaml_gainPitchRate_fromAngle  =  4.00;
+// The LQR Controller parameters for yaw
+float yaml_gainYawRate_fromAngle    =  2.30;
 
 
 // VARIABLES FOR THE ESTIMATOR
@@ -259,9 +323,10 @@ float m_estimator_frequency = 200.0;
 
 // > A flag for which estimator to use:
 int yaml_estimator_method = ESTIMATOR_METHOD_FINITE_DIFFERENCE;
+
 // > The current state interial estimate,
 //   for use by the controller
-float m_current_stateInertialEstimate[12];
+float m_current_stateInertialEstimate[9];
 
 // > The measurement of the Crazyflie at the "current" time step,
 //   to avoid confusion
@@ -273,22 +338,17 @@ float m_previous_xzy_rpy_measurement[6];
 
 // > The full 12 state estimate maintained by the finite
 //   difference state estimator
-float m_stateInterialEstimate_viaFiniteDifference[12];
+float m_stateInterialEstimate_viaFiniteDifference[9];
 
 // > The full 12 state estimate maintained by the point mass
 //   kalman filter state estimator
-float m_stateInterialEstimate_viaPointMassKalmanFilter[12];
+float m_stateInterialEstimate_viaPointMassKalmanFilter[9];
 
 // THE POINT MASS KALMAN FILTER (PMKF) GAINS AND ERROR EVOLUATION
 // > For the (x,y,z) position
 std::vector<float> yaml_PMKF_Ahat_row1_for_positions  =  {  0.6723, 0.0034};
 std::vector<float> yaml_PMKF_Ahat_row2_for_positions  =  {-12.9648, 0.9352};
 std::vector<float> yaml_PMKF_Kinf_for_positions       =  {  0.3277,12.9648};
-// > For the (roll,pitch,yaw) angles
-std::vector<float> yaml_PMKF_Ahat_row1_for_angles     =  {  0.6954, 0.0035};
-std::vector<float> yaml_PMKF_Ahat_row2_for_angles     =  {-11.0342, 0.9448};
-std::vector<float> yaml_PMKF_Kinf_for_angles          =  {  0.3046,11.0342};
-
 
 
 // VARIABLES RELATING TO PUBLISHING
@@ -301,6 +361,11 @@ ros::Publisher m_debugPublisher;
 ros::Publisher m_setpointChangedPublisher;
 
 
+// ROS Publisher for sending motors-off command
+// to the flying agent client
+ros::Publisher m_motorsOffToFlyingAgentClientPublisher;
+
+
 
 
 
@@ -335,11 +400,28 @@ bool requestManoeuvreCallback(IntIntService::Request &request, IntIntService::Re
 // CONTROLLER COMPUTATIONS
 bool calculateControlOutput(Controller::Request &request, Controller::Response &response);
 
+// > For the normal state
+void computeResponse_for_normal(Controller::Response &response);
+// > For the standby state (also used for unknown state)
+void computeResponse_for_standby(Controller::Response &response);
+// > For the take-off phases
+void computeResponse_for_takeoff_move_up(Controller::Response &response);
+void computeResponse_for_takeoff_spin_motors(Controller::Response &response);
+void computeResponse_for_takeoff_goto_setpoint(Controller::Response &response);
+void computeResponse_for_takeoff_integrator_on(Controller::Response &response);
+// > For the landing phases
+void computeResponse_for_landing_move_down(Controller::Response &response);
+void computeResponse_for_landing_spin_motors(Controller::Response &response);
+
+
+// SMOOTHING SETPOINT CHANGES
+void smoothSetpointChanges( float target_setpoint[4] , float (&current_setpoint)[4] );
+
 // > This function constructs the error in the body frame
 //   before calling the appropriate control function
 void calculateControlOutput_viaLQR_givenSetpoint(float setpoint[4], float stateInertial[12], Controller::Response &response)
 // > The various functions that implement an LQR controller
-void calculateControlOutput_viaLQRforRates(float stateErrorBody[12], Controller::Response &response);
+void calculateControlOutput_viaLQR_givenError(float stateErrorBody[12], Controller::Response &response);
 
 // ESTIMATOR COMPUTATIONS
 void performEstimatorUpdate_forStateInterial(Controller::Request &request);
@@ -371,6 +453,9 @@ void publishCurrentSetpointAndState();
 // CUSTOM COMMAND RECEIVED CALLBACK
 void customCommandReceivedCallback(const CustomButtonWithHeader& commandReceived);
 
+// PUBLISH MOTORS-OFF MESSAGE TO FLYING AGENT CLIENT
+void publish_motors_off_to_flying_agent_client();
+
 // LOADING OF YAML PARAMETERS
 void isReadyDefaultControllerYamlCallback(const IntWithHeader & msg);
 void fetchDefaultControllerYamlParameters(ros::NodeHandle& nodeHandle);
\ No newline at end of file
diff --git a/dfall_ws/src/dfall_pkg/include/nodes/FlyingAgentClient.h b/dfall_ws/src/dfall_pkg/include/nodes/FlyingAgentClient.h
index f315d7de5fc251e0efd66439652b5683b72b60cf..215f13f252beaba98d7d84ee56ebd37818a2cc57 100644
--- a/dfall_ws/src/dfall_pkg/include/nodes/FlyingAgentClient.h
+++ b/dfall_ws/src/dfall_pkg/include/nodes/FlyingAgentClient.h
@@ -150,7 +150,7 @@ float yaml_mocap_timeout_duration = 1.0;
 bool yaml_isEnabled_strictSafety = true;
 // > The maximum allowed tilt angle, in degrees and radians
 float yaml_maxTiltAngle_for_strictSafety_degrees = 70;
-float m_maxTiltAngle_for_strictSafety_radians = 70 * DEG2RAD;
+float yaml_maxTiltAngle_for_strictSafety_radians = 70 * DEG2RAD;
 
 
 
@@ -192,15 +192,15 @@ int m_controller_nominally_selected;
 
 
 // VARIABLES FOR THE CONTROLER SERVIVCE CLIENTS
-// The default controller specified in the ClientConfig.yaml
+// The default controller specified in the FlyingAgentClientConfig.yaml
 ros::ServiceClient m_defaultController;
-// The Student controller specified in the ClientConfig.yaml
+// The Student controller specified in the FlyingAgentClientConfig.yaml
 ros::ServiceClient m_studentController;
-// The Tuning controller specified in the ClientConfig.yaml
+// The Tuning controller specified in the FlyingAgentClientConfig.yaml
 ros::ServiceClient m_tuningController;
-// The Picker controller specified in the ClientConfig.yaml
+// The Picker controller specified in the FlyingAgentClientConfig.yaml
 ros::ServiceClient m_pickerController;
-// The Template controller specified in the ClientConfig.yaml
+// The Template controller specified in the FlyingAgentClientConfig.yaml
 ros::ServiceClient m_templateController;
 
 
@@ -216,7 +216,7 @@ int m_crazyradio_status;
 CrazyflieContext m_context;
 
 // Service Client from which the "CrazyflieContext" is loaded
-ros::ServiceClient centralManager;
+ros::ServiceClient m_centralManager;
 
 // Publisher for the control actions to be sent on
 // to the Crazyflie (the CrazyRadio node listen to this
@@ -232,10 +232,10 @@ ros::Publisher m_flyingStatePublisher;
 //ros::Publisher commandPublisher;
 
 // Publisher Communication with crazyRadio node. Connect and disconnect
-ros::Publisher crazyRadioCommandPublisher;
+ros::Publisher m_crazyRadioCommandPublisher;
 
 // Publisher for which controller is currently being used
-ros::Publisher controllerUsedPublisher;
+ros::Publisher m_controllerUsedPublisher;
 
 
 
@@ -358,5 +358,5 @@ void timerCallback_for_createAllcontrollerServiceClients(const ros::TimerEvent&)
 
 
 // FOR LOADING THE YAML PARAMETERS
-void isReadyClientConfigYamlCallback(const IntWithHeader & msg);
-void fetchClientConfigYamlParameters(ros::NodeHandle& nodeHandle);
\ No newline at end of file
+void isReadyFlyingAgentClientConfigYamlCallback(const IntWithHeader & msg);
+void fetchFlyingAgentClientConfigYamlParameters(ros::NodeHandle& nodeHandle);
\ No newline at end of file
diff --git a/dfall_ws/src/dfall_pkg/launch/agent.launch b/dfall_ws/src/dfall_pkg/launch/agent.launch
index b97eae9ad8ee2991c23d157dbaf0c94c35a12c80..52a40b9441559c9293b0cf457e0ce058906a2990 100755
--- a/dfall_ws/src/dfall_pkg/launch/agent.launch
+++ b/dfall_ws/src/dfall_pkg/launch/agent.launch
@@ -130,8 +130,8 @@
 			<param name="agentID"  value="$(arg agentID)" />
 			<rosparam
 				command = "load"
-				file    = "$(find dfall_pkg)/param/ClientConfig.yaml"
-				ns      = "ClientConfig"
+				file    = "$(find dfall_pkg)/param/FlyingAgentClientConfig.yaml"
+				ns      = "FlyingAgentClientConfig"
 			/>
 			<rosparam
 				command = "load"
diff --git a/dfall_ws/src/dfall_pkg/launch/coordinator.launch b/dfall_ws/src/dfall_pkg/launch/coordinator.launch
index 9d10deafbab54aac2e35eb067f30e0ef6cedd7df..c9e7e15414acb8efb1d0361afd4768eb2f8e2ae1 100755
--- a/dfall_ws/src/dfall_pkg/launch/coordinator.launch
+++ b/dfall_ws/src/dfall_pkg/launch/coordinator.launch
@@ -44,7 +44,7 @@
 			/>
 			<rosparam
 				command = "load"
-				file    = "$(find dfall_pkg)/param/ClientConfig.yaml"
+				file    = "$(find dfall_pkg)/param/FlyingAgentClientConfig.yaml"
 				ns      = "SafeController"
 			/>
 		</node>
diff --git a/dfall_ws/src/dfall_pkg/param/DefaultController.yaml b/dfall_ws/src/dfall_pkg/param/DefaultController.yaml
index d64bc24ba812dd14c5bca9150d5f75387247eec8..d5b432c50f6b7a66a61ef4884ce5317c26ffb12d 100644
--- a/dfall_ws/src/dfall_pkg/param/DefaultController.yaml
+++ b/dfall_ws/src/dfall_pkg/param/DefaultController.yaml
@@ -2,23 +2,62 @@
 # PARAMTERS FOR THE TAKE-OFF AND LANDING MANOEUVRES
 
 # Max setpoint change per second
-max_setpoint_change_per_second_horizontal  :  0.20 # [meters]
-max_setpoint_change_per_second_vertical    :  0.10 # [meters]
+max_setpoint_change_per_second_horizontal  :  0.50 # [meters]
+max_setpoint_change_per_second_vertical    :  0.30 # [meters]
+
+# Max error for z
+max_setpoint_error_z: 0.4
 
 # Max error for yaw angle
 max_setpoint_error_yaw_degrees: 60
 
+# Max {roll,pitch} angle request
+max_roll_pitch_request_degrees: 30
+
+# Theshold for {roll,pitch} angle beyond
+# which the motors are turned off
+threshold_roll_pitch_for_turn_off_degrees: 70
+
 # The thrust for take off spin motors
 takeoff_spin_motors_thrust: 8000
-# The time for the take off spin motors
-takoff_spin_motots_time: 0.8
+# The time for: take off spin motors
+takoff_spin_motors_time: 0.8
 
 # Height change for the take off move-up
 takeoff_move_up_start_height: 0.1
 takeoff_move_up_end_height:   0.4
-# The time for the take off spin motors
+# The time for: take off move-up
 takoff_move_up_time: 1.2
 
+# Minimum and maximum allowed time for: take off goto setpoint
+takoff_goto_setpoint_min_time: 1.0
+takoff_goto_setpoint_max_time: 2.0
+
+# Box within which to keep the integrator on
+# > Units of [meters]
+# > The box consider is plus/minus this value
+takoff_integrator_on_box_horizontal: 0.25
+takoff_integrator_on_box_vertical:   0.15
+# The time for: take off integrator-on
+takoff_integrator_on_time: 1.5
+
+
+# Height change for the landing move-down
+landing_move_down_end_height_setpoint:  0.05
+landing_move_down_end_height_threshold: 0.10
+# The time for: landing move-down
+landing_move_down_time_max: 2.0
+
+# The thrust for landing spin motors
+landing_spin_motors_thrust: 10000
+# The time for: landing spin motors
+landing_spin_motors_time: 1.0
+
+
+# IMPORTANT NOTE: the times above should NOT be set
+# to zero because this will cause a divide by zero
+# crash.
+
 
 # ------------------------------------------------------
 # PARAMTERS THAT ARE STANDARD FOR A "CONTROLLER SERVICE"
@@ -46,11 +85,25 @@ shouldPublishDebugMessage : false
 # Boolean indiciating whether the debugging ROS_INFO_STREAM should be displayed or not
 shouldDisplayDebugInfo : false
 
-# The LQR Controller parameters for "mode = 3"
-gainMatrixThrust_NineStateVector    :  [ 0.00, 0.00, 0.98, 0.00, 0.00, 0.25, 0.00, 0.00, 0.00]
-gainMatrixRollRate                  :  [ 0.00,-6.20, 0.00, 0.00,-3.00, 0.00, 5.20, 0.00, 0.00]
-gainMatrixPitchRate                 :  [ 6.20, 0.00, 0.00, 3.00, 0.00, 0.00, 0.00, 5.20, 0.00]
-gainMatrixYawRate                   :  [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 2.30]
+# A flag for which controller to use, defined as:
+# 1  -  Rate controller
+# 2  -  Angle-Rate nested controller
+controller_method : 1
+
+# The LQR Controller parameters for z-height
+gainMatrixThrust_2StateVector     :  [ 0.98, 0.25]
+# The LQR Controller parameters for mode 1 (the Rate controller)
+gainMatrixRollRate_3StateVector   :  [-6.20,-3.00, 5.20]
+gainMatrixPitchRate_3StateVector  :  [ 6.20, 3.00, 5.20]
+# The LQR Controller parameters for mode 2 (Angle-nested)
+gainMatrixRollAngle_2StateVector  :  [-0.20,-0.20]
+gainMatrixPitchAngle_2StateVector :  [ 0.20, 0.20]
+gainRollRate_fromAngle   :  4.00
+gainPitchRate_fromAngle  :  4.00
+# The LQR Controller parameters for yaw
+gainYawRate_fromAngle    :  2.30
+
+
 
 # A flag for which estimator to use, defined as:
 # 1  -  Finite Different Method,
@@ -60,22 +113,10 @@ gainMatrixYawRate                   :  [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.0
 # 2  -  Point Mass Per Dimension Method
 #       Uses a 2nd order random walk estimator independently for
 #       each of (x,y,z,roll,pitch,yaw)
-# 3  -  Quad-rotor Model Based Method
-#       Uses the model of the quad-rotor and the previous inputs
 estimator_method : 1
 
 # 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]
 PMKF_Ahat_row2_for_positions  :  [-12.9648, 0.9352]
-PMKF_Kinf_for_positions       :  [  0.3277,12.9648]
-# > For the (roll,pitch,yaw) angles
-PMKF_Ahat_row1_for_angles     :  [  0.6954, 0.0035]
-PMKF_Ahat_row2_for_angles     :  [-11.0342, 0.9448]
-PMKF_Kinf_for_angles          :  [  0.3046,11.0342]
-
-#PMKF_Ahat_row1_for_angles     :  [  0.6723, 0.0034]
-#PMKF_Ahat_row2_for_angles     :  [-12.9648, 0.9352]
-#PMKF_Kinf_for_angles          :  [  0.3277,12.9648]
-
-
+PMKF_Kinf_for_positions       :  [  0.3277,12.9648]
\ No newline at end of file
diff --git a/dfall_ws/src/dfall_pkg/param/ClientConfig.yaml b/dfall_ws/src/dfall_pkg/param/FlyingAgentClientConfig.yaml
similarity index 85%
rename from dfall_ws/src/dfall_pkg/param/ClientConfig.yaml
rename to dfall_ws/src/dfall_pkg/param/FlyingAgentClientConfig.yaml
index b6d75db6044bcd6e65422b4a3779e17a71fae6b3..cf56b8e1450d342414ac32b562c5368e71b4b539 100755
--- a/dfall_ws/src/dfall_pkg/param/ClientConfig.yaml
+++ b/dfall_ws/src/dfall_pkg/param/FlyingAgentClientConfig.yaml
@@ -28,9 +28,4 @@ shouldPerfom_takeOff_with_defaultController: true
 
 # Flag for whether the landing should be performed
 # with the default controller
-shouldPerfom_landing_with_defaultController: true
-
-
-#battery_threshold_while_flying: 2.60       # in V
-#battery_threshold_while_motors_off: 3.30   # in V
-#battery_polling_period: 200                # in ms
\ No newline at end of file
+shouldPerfom_landing_with_defaultController: true
\ 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 53fd75c2ba6f14e86dfcd8e8809314c35fd9a8af..b61a3e84ba4f77f9e3e914e2d3741baeb4212d21 100644
--- a/dfall_ws/src/dfall_pkg/param/YamlFileNames.yaml
+++ b/dfall_ws/src/dfall_pkg/param/YamlFileNames.yaml
@@ -1,4 +1,4 @@
 dictionary : {
-  'ClientConfig'   : 'ClientConfig' ,
+  'FlyingAgentClientConfig'   : 'FlyingAgentClientConfig' ,
   'SafeController' : 'SafeController'
 }
diff --git a/dfall_ws/src/dfall_pkg/src/nodes/DefaultControllerService.cpp b/dfall_ws/src/dfall_pkg/src/nodes/DefaultControllerService.cpp
index 96711b818b4a02c5158931d0396cfef43ac7909b..c5e0188ebe84370fab0f3bc954db6cd644e02844 100644
--- a/dfall_ws/src/dfall_pkg/src/nodes/DefaultControllerService.cpp
+++ b/dfall_ws/src/dfall_pkg/src/nodes/DefaultControllerService.cpp
@@ -92,7 +92,13 @@ bool requestManoeuvreCallback(IntIntService::Request &request, IntIntService::Re
 			m_current_state = DEFAULT_CONTROLLER_STATE_TAKE_OFF_SPIN_MOTORS;
 			m_current_state_changed = true;
 			// Fill in the response duration in milliseconds
-			response.data = 3000;
+			response.data = 1000 *
+				int(
+					+ yaml_takoff_spin_motors_time
+					+ yaml_takoff_move_up_time
+					+ yaml_takoff_goto_setpoint_max_time
+					+ yaml_takoff_integrator_on_time
+				);
 			break;
 		}
 
@@ -106,7 +112,11 @@ bool requestManoeuvreCallback(IntIntService::Request &request, IntIntService::Re
 			m_current_state = DEFAULT_CONTROLLER_STATE_LANDING_MOVE_DOWN;
 			m_current_state_changed = true;
 			// Fill in the response duration in milliseconds
-			response.data = 2000;
+			response.data = 1000 *
+				int(
+					+ yaml_landing_move_down_time_max
+					+ yaml_landing_spin_motors_time
+				);
 			break;
 		}
 
@@ -175,6 +185,10 @@ bool calculateControlOutput(Controller::Request &request, Controller::Response &
 	// Switch between the possible states
 	switch (m_current_state)
 	{
+		case DEFAULT_CONTROLLER_STATE_NORMAL:
+			computeResponse_for_normal(response);
+			break;
+
 		case DEFAULT_CONTROLLER_STATE_TAKE_OFF_SPIN_MOTORS:
 			computeResponse_for_takeoff_spin_motors(response);
 			break;
@@ -183,13 +197,57 @@ bool calculateControlOutput(Controller::Request &request, Controller::Response &
 			computeResponse_for_takeoff_move_up(response);
 			break;
 
+		case DEFAULT_CONTROLLER_STATE_TAKEOFF_GOTO_SETPOINT:
+			computeResponse_for_takeoff_goto_setpoint(response);
+			break;
+
+		case DEFAULT_CONTROLLER_STATE_TAKEOFF_INTEGRATOR_ON:
+			computeResponse_for_takeoff_integrator_on(response);
+			break;
+
+		case DEFAULT_CONTROLLER_STATE_LANDING_MOVE_DOWN:
+			computeResponse_for_landing_move_down(response);
+			break;
+
+		case DEFAULT_CONTROLLER_STATE_LANDING_SPIN_MOTORS:
+			computeResponse_for_landing_spin_motors(response);
+			break;
+
+		case DEFAULT_CONTROLLER_STATE_STANDBY:
+		case DEFAULT_CONTROLLER_STATE_UNKNOWN:
+		default:
+			computeResponse_for_standby(response);
+			break;
 	}
 
-	
 
-	// CARRY OUT THE CONTROLLER COMPUTATIONS
-	// Call the function that performs the control computations for this mode
-	calculateControlOutput_viaLQRforRates(current_bodyFrameError,request,response);
+	// Change to standby state if the {roll,pitch}
+	// angles exceed the threshold
+	if (
+		(abs(m_current_stateInertialEstimate[6]) > yaml_threshold_roll_pitch_for_turn_off_radians)
+		or
+		(abs(m_current_stateInertialEstimate[7]) > yaml_threshold_roll_pitch_for_turn_off_radians)
+	)
+	{
+		// Inform the user
+		ROS_INFO("[DEFAULT CONTROLLER] Angle thereshold exceeded. Switch to state: standby");
+		// Reset the time variable
+		m_time_in_seconds = 0.0;
+		// Update the state accordingly
+		m_current_state = DEFAULT_CONTROLLER_STATE_STANDBY;
+		m_current_state_changed = true;
+		// Publish a command to the "Flying Agent Client"
+		// requesting the "MOTORS-OFF" state
+		publish_motors_off_to_flying_agent_client();
+	}
+
+
+	// If the state changed,
+	// then publish the setpoint so that the GUI is updated
+	if (m_current_state_changed)
+	{
+		publishCurrentSetpointAndState();
+	}
 
 
 	// PUBLISH THE DEBUG MESSAGE (if required)
@@ -198,11 +256,62 @@ bool calculateControlOutput(Controller::Request &request, Controller::Response &
 		construct_and_publish_debug_message(request,response);
 	}
 
+
 	// Return "true" to indicate that the control computation was performed successfully
 	return true;
 }
 
 
+void computeResponse_for_standby(Controller::Response &response)
+{
+	// Check if the state "just recently" changed
+	if (m_current_state_changed)
+	{
+		// PERFORM "ONE-OFF" OPERATIONS HERE
+		// Nothing to perform for this state
+		// Set the change flag back to false
+		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;
+
+	// 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;
+}
+
+
+void computeResponse_for_normal(Controller::Response &response)
+{
+	// Check if the state "just recently" changed
+	if (m_current_state_changed)
+	{
+		// PERFORM "ONE-OFF" OPERATIONS HERE
+		// Set the "m_setpoint_for_controller" variable
+		// to the current inertial estimate
+		m_setpoint_for_controller[0] = m_current_stateInertialEstimate[0];
+		m_setpoint_for_controller[1] = m_current_stateInertialEstimate[1];
+		m_setpoint_for_controller[2] = m_current_stateInertialEstimate[2];
+		m_setpoint_for_controller[3] = m_current_stateInertialEstimate[8];
+		// Set the change flag back to false
+		m_current_state_changed = false;
+	}
+
+	// Smooth out any setpoint changes
+	smoothSetpointChanges( m_setpoint , m_setpoint_for_controller );
+
+	// Call the LQR control function
+	calculateControlOutput_viaLQR_givenSetpoint(m_setpoint_for_controller, m_current_stateInertialEstimate, response);
+
+}
 
 
 void computeResponse_for_takeoff_spin_motors(Controller::Response &response)
@@ -216,12 +325,15 @@ void computeResponse_for_takeoff_spin_motors(Controller::Response &response)
 		m_current_state_changed = false;
 	}
 
+	// Compute the time elapsed as a proportion
+	float time_elapsed_proportion = m_time_in_seconds / yaml_takoff_spin_motors_time;
+	if (time_elapsed_proportion > 1.0)
+		time_elapsed_proportion = 1.0;
+
 	// Compute the "spinning" thrust
-	float thrust_for_spinning = 1000.0;
-	if (m_time_in_seconds < takoff_spin_motots_time)
-		thrust_for_spinning += yaml_takeoff_spin_motors_thrust * (m_time_in_seconds/takoff_spin_motots_time);
-	else
-		thrust_for_spinning += yaml_takeoff_spin_motors_thrust;
+	float thrust_for_spinning =
+		+ 1000.0
+		+ time_elapsed_proportion * yaml_takeoff_spin_motors_thrust;
 
 	// Fill in zero for the angle parts
 	response.controlOutput.roll  = 0.0;
@@ -238,7 +350,7 @@ void computeResponse_for_takeoff_spin_motors(Controller::Response &response)
 	response.controlOutput.onboardControllerType = CF_COMMAND_TYPE_MOTORS;
 
 	// Change to next state after specified time
-	if (m_time_in_seconds > takoff_spin_motots_time)
+	if (m_time_in_seconds > yaml_takoff_spin_motors_time)
 	{
 		// Inform the user
 		ROS_INFO("[DEFAULT CONTROLLER] Switch to state: take-off move up");
@@ -290,14 +402,292 @@ void computeResponse_for_takeoff_move_up(Controller::Response &response)
 	m_setpoint_for_controller[3] = initial_yaw + time_elapsed_proportion * yaw_start_to_end_diff;
 
 	// Call the LQR control function
-	calculateControlOutput_viaLQR_givenSetpoint(m_setpoint_for_controller, m_current_stateInertialEstimate, response)
+	calculateControlOutput_viaLQR_givenSetpoint(m_setpoint_for_controller, m_current_stateInertialEstimate, response);
 
+	// Change to next state after specified time
+	if (m_time_in_seconds > yaml_takoff_move_up_time)
+	{
+		// Inform the user
+		ROS_INFO("[DEFAULT CONTROLLER] Switch to state: take-off goto setpoint");
+		// Reset the time variable
+		m_time_in_seconds = 0.0;
+		// Update the state accordingly
+		m_current_state = DEFAULT_CONTROLLER_STATE_TAKEOFF_GOTO_SETPOINT;
+		m_current_state_changed = true;
+	}
 }
 
 
 
+void computeResponse_for_takeoff_goto_setpoint(Controller::Response &response)
+{
+	// Check if the state "just recently" changed
+	if (m_current_state_changed)
+	{
+		// PERFORM "ONE-OFF" OPERATIONS HERE
+		// Nothing to perform for this state
+		// Set the change flag back to false
+		m_current_state_changed = false;
+	}
+
+	// Smooth out any setpoint changes
+	smoothSetpointChanges( m_setpoint , m_setpoint_for_controller );
+
+	// Call the LQR control function
+	calculateControlOutput_viaLQR_givenSetpoint(m_setpoint_for_controller, m_current_stateInertialEstimate, response);
+
+	// If minimum time is passed,
+	// then check if near to the setpoint
+	if (m_time_in_seconds > yaml_takoff_goto_setpoint_min_time)
+	{
+		// Compute the current errors
+		float error_x = m_setpoint[0] - m_current_stateInertialEstimate[0];
+		float error_y = m_setpoint[1] - m_current_stateInertialEstimate[1];
+		float error_z = m_setpoint[2] - m_current_stateInertialEstimate[2];
+		// Check if within the "integrator on" box
+		// of the setpoint
+		if (
+			(abs(error_x) < yaml_takoff_integrator_on_box_horizontal)
+			and
+			(abs(error_y) < yaml_takoff_integrator_on_box_horizontal)
+			and
+			(abs(error_z) < yaml_takoff_integrator_on_box_vertical)
+		)
+		// Inform the user
+		ROS_INFO("[DEFAULT CONTROLLER] Switch to state: take-off integrator on");
+		// Reset the time variable
+		m_time_in_seconds = 0.0;
+		// Update the state accordingly
+		m_current_state = DEFAULT_CONTROLLER_STATE_TAKEOFF_INTEGRATOR_ON;
+		m_current_state_changed = true;
+	}
+
+	// Change to normal if the timeout is reched
+	if (m_time_in_seconds > yaml_takoff_goto_setpoint_max_time)
+	{
+		// Inform the user
+		ROS_INFO("[DEFAULT CONTROLLER] Did not reached the setpoint within the \"take-off goto setpoint\" allowed time. Switch to state: normal");
+		// Reset the time variable
+		m_time_in_seconds = 0.0;
+		// Update the state accordingly
+		m_current_state = DEFAULT_CONTROLLER_STATE_NORMAL;
+		m_current_state_changed = true;
+	}
+}
+
+
 
+void computeResponse_for_integrator_on(Controller::Response &response)
+{
+	// Check if the state "just recently" changed
+	if (m_current_state_changed)
+	{
+		// PERFORM "ONE-OFF" OPERATIONS HERE
+		// Set the "m_setpoint_for_controller" variable
+		// to the current setpoint
+		m_setpoint_for_controller[0] = m_setpoint[0];
+		m_setpoint_for_controller[1] = m_setpoint[1];
+		m_setpoint_for_controller[2] = m_setpoint[2];
+		m_setpoint_for_controller[3] = m_setpoint[3];
+		// Set the change flag back to false
+		m_current_state_changed = false;
+	}
 
+	// Call the LQR control function
+	calculateControlOutput_viaLQR_givenSetpoint(m_setpoint_for_controller, m_current_stateInertialEstimate, response);
+
+	// Change to next state after specified time
+	if (m_time_in_seconds > yaml_takoff_integrator_on_time)
+	{
+		// Inform the user
+		ROS_INFO("[DEFAULT CONTROLLER] Switch to state: normal");
+		// Reset the time variable
+		m_time_in_seconds = 0.0;
+		// Update the state accordingly
+		m_current_state = DEFAULT_CONTROLLER_STATE_NORMAL;
+		m_current_state_changed = true;
+	}
+}
+
+
+
+
+
+void computeResponse_for_landing_move_down(Controller::Response &response)
+{
+	// Initialise a static variable for the starting height and yaw
+	static float initial_height = 0.4;
+
+	// Check if the state "just recently" changed
+	if (m_current_state_changed)
+	{
+		// PERFORM "ONE-OFF" OPERATIONS HERE
+		// Set the current (x,y,yaw) location as the setpoint
+		m_setpoint_for_controller[0] = m_current_stateInertialEstimate[0];
+		m_setpoint_for_controller[1] = m_current_stateInertialEstimate[1];
+		m_setpoint_for_controller[3] = m_current_stateInertialEstimate[8];
+		// Store the current z
+		initial_height = m_current_stateInertialEstimate[2];
+		// Set the change flag back to false
+		m_current_state_changed = false;
+	}
+
+	// Compute the time elapsed as a proportion
+	float time_elapsed_proportion = m_time_in_seconds / (0.8*yaml_landing_move_down_time_max);
+	if (time_elapsed_proportion > 1.0)
+		time_elapsed_proportion = 1.0;
+
+	// Compute the z-height setpoint
+	m_setpoint_for_controller[2] = initial_height + time_elapsed_proportion * (yaml_landing_move_down_end_height_setpoint-initial_height);
+
+	// Call the LQR control function
+	calculateControlOutput_viaLQR_givenSetpoint(m_setpoint_for_controller, m_current_stateInertialEstimate, response);
+
+	// Check if within the threshold of zero
+	if (m_current_stateInertialEstimate[2] < yaml_landing_move_down_end_height_threshold)
+	{
+		// Inform the user
+		ROS_INFO("[DEFAULT CONTROLLER] Switch to state: landing spin motors");
+		// Reset the time variable
+		m_time_in_seconds = 0.0;
+		// Update the state accordingly
+		m_current_state = DEFAULT_CONTROLLER_STATE_LANDING_SPIN_MOTORS;
+		m_current_state_changed = true;
+	}
+
+	// Change to landing spin motors if the timeout is reached
+	if (m_time_in_seconds > yaml_landing_move_down_time_max)
+	{
+		// Inform the user
+		ROS_INFO("[DEFAULT CONTROLLER] Did not reached the setpoint within the \"landing move down\" allowed time. Switch to state: landing spin motors");
+		// Reset the time variable
+		m_time_in_seconds = 0.0;
+		// Update the state accordingly
+		m_current_state = DEFAULT_CONTROLLER_STATE_LANDING_SPIN_MOTORS;
+		m_current_state_changed = true;
+	}
+}
+
+
+void computeResponse_for_landing_spin_motors(Controller::Response &response)
+{
+	// Check if the state "just recently" changed
+	if (m_current_state_changed)
+	{
+		// PERFORM "ONE-OFF" OPERATIONS HERE
+		// Set the z setpoint
+		m_setpoint_for_controller[2] = yaml_landing_move_down_end_height_setpoint;
+		// Set the change flag back to false
+		m_current_state_changed = false;
+	}
+
+	// Compute the time elapsed as a proportion
+	float time_elapsed_proportion = m_time_in_seconds / yaml_landing_spin_motors_time;
+	if (time_elapsed_proportion > 1.0)
+		time_elapsed_proportion = 1.0;
+
+
+	// Start by using the controller and reducing the thrust
+	if (time_elapsed_proportion<0.5)
+	{
+		// Call the LQR control function
+		calculateControlOutput_viaLQR_givenSetpoint(m_setpoint_for_controller, m_current_stateInertialEstimate, response);
+		// Compute the desired "spinning" thrust
+		float thrust_for_spinning =
+			(1.0-time_elapsed_proportion)
+			*
+			computeMotorPolyBackward(m_cf_weight_in_newtons/4.0);
+		// Adjust the motor commands
+		response.controlOutput.motorCmd1 = thrust_for_spinning;
+		response.controlOutput.motorCmd2 = thrust_for_spinning;
+		response.controlOutput.motorCmd3 = thrust_for_spinning;
+		response.controlOutput.motorCmd4 = thrust_for_spinning;
+	}
+	// 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;
+		// 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 > yaml_landing_spin_motors_time)
+		{
+			// Inform the user
+			ROS_INFO("[DEFAULT CONTROLLER] Switch to state: standby");
+			// Reset the time variable
+			m_time_in_seconds = 0.0;
+			// Update the state accordingly
+			m_current_state = DEFAULT_CONTROLLER_STATE_STANDBY;
+			m_current_state_changed = true;
+		}
+	}	
+}
+
+
+//    ------------------------------------------------------------------------------
+//     SSSS  M   M   OOO    OOO   TTTTT  H   H
+//    S      MM MM  O   O  O   O    T    H   H
+//     SSS   M M M  O   O  O   O    T    HHHHH
+//        S  M   M  O   O  O   O    T    H   H
+//    SSSS   M   M   OOO    OOO     T    H   H
+//
+//     SSSS  EEEEE  TTTTT  PPPP    OOO   III  N   N  TTTTT
+//    S      E        T    P   P  O   O   I   NN  N    T
+//     SSS   EEE      T    PPPP   O   O   I   N N N    T
+//        S  E        T    P      O   O   I   N  NN    T
+//    SSSS   EEEEE    T    P       OOO   III  N   N    T
+//    ------------------------------------------------------------------------------
+
+
+void smoothSetpointChanges( float target_setpoint[4] , float (&current_setpoint)[4] )
+{
+	// SMOOTH THE Z-COORIDINATE
+	// > Compute the max allowed change
+	float max_for_z = yaml_max_setpoint_change_per_second_vertical  yaml_control_frequency;
+	// > Compute the current difference
+	float diff_for_z = target_setpoint[2] - current_setpoint[2];
+	// > Clip the difference to the maximum
+	if (diff_for_z > max_for_z)
+		diff_for_z = max_for_z;
+	else if (diff_for_z < -max_for_z)
+		diff_for_z = -max_for_z;
+	// > Update the current setpoint
+	current_setpoint[2] += diff_for_z;
+
+	// SMOOTH THE X-Y-COORIDINATES
+	// > Compute the max allowed change
+	float max_for_xy = yaml_max_setpoint_change_per_second_horizontal  yaml_control_frequency;
+	// > Compute the current difference
+	float diff_for_x  = target_setpoint[0] - current_setpoint[0];
+	float diff_for_y  = target_setpoint[1] - current_setpoint[1];
+	float diff_for_xy = sqrt( diff_for_x^2 + diff_for_y^2 );
+	// > Clip the difference to the maximum
+	if (diff_for_xy > max_for_xy)
+	{
+		// > Convert the difference to a proportion
+		float proportion_xy = max_for_xy / diff_for_xy;
+		// > Update the current setpoint
+		current_setpoint[0] += proportion_xy * diff_for_x;
+		current_setpoint[1] += proportion_xy * diff_for_y;
+	}
+	else
+	{
+		// > Update the current setpoint to be the
+		//   the target setpoint because it is within
+		//   reach
+		current_setpoint[0] = target_setpoint[0];
+		current_setpoint[1] = target_setpoint[1];
+	}	
+}
 
 
 
@@ -341,7 +731,7 @@ void performEstimatorUpdate_forStateInterial(Controller::Request &request)
 		case ESTIMATOR_METHOD_FINITE_DIFFERENCE:
 		{
 			// Transfer the estimate
-			for(int i = 0; i < 12; ++i)
+			for(int i = 0; i < 9; ++i)
 			{
 				m_current_stateInertialEstimate[i]  = m_stateInterialEstimate_viaFiniteDifference[i];
 			}
@@ -351,7 +741,7 @@ void performEstimatorUpdate_forStateInterial(Controller::Request &request)
 		case ESTIMATOR_METHOD_POINT_MASS_PER_DIMENSION:
 		{
 			// Transfer the estimate
-			for(int i = 0; i < 12; ++i)
+			for(int i = 0; i < 9; ++i)
 			{
 				m_current_stateInertialEstimate[i]  = m_stateInterialEstimate_viaPointMassKalmanFilter[i];
 			}
@@ -361,9 +751,9 @@ void performEstimatorUpdate_forStateInterial(Controller::Request &request)
 		default:
 		{
 			// Display that the "yaml_estimator_method" was not recognised
-			ROS_INFO_STREAM("[PICKER CONTROLLER] ERROR: in the 'calculateControlOutput' function of the 'PickerControllerService': the 'yaml_estimator_method' is 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 < 12; ++i)
+			for(int i = 0; i < 9; ++i)
 			{
 				m_current_stateInertialEstimate[i]  = m_stateInterialEstimate_viaFiniteDifference[i];
 			}
@@ -403,10 +793,6 @@ void performEstimatorUpdate_forStateInterial_viaFiniteDifference()
 	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;
-	// > for (roll,pitch,yaw) velocities
-	m_stateInterialEstimate_viaFiniteDifference[9]  = (m_current_xzy_rpy_measurement[3] - m_previous_xzy_rpy_measurement[3]) * m_estimator_frequency;
-	m_stateInterialEstimate_viaFiniteDifference[10] = (m_current_xzy_rpy_measurement[4] - m_previous_xzy_rpy_measurement[4]) * m_estimator_frequency;
-	m_stateInterialEstimate_viaFiniteDifference[11] = (m_current_xzy_rpy_measurement[5] - m_previous_xzy_rpy_measurement[5]) * m_estimator_frequency;
 }
 
 
@@ -415,8 +801,8 @@ void performEstimatorUpdate_forStateInterial_viaPointMassKalmanFilter()
 {
 	// PERFORM THE KALMAN FILTER UPDATE STEP
 	// > First take a copy of the estimator state
-	float temp_PMKFstate[12];
-	for(int i = 0; i < 12; ++i)
+	float temp_PMKFstate[9];
+	for(int i = 0; i < 9; ++i)
 	{
 		temp_PMKFstate[i]  = m_stateInterialEstimate_viaPointMassKalmanFilter[i];
 	}
@@ -431,16 +817,12 @@ void performEstimatorUpdate_forStateInterial_viaPointMassKalmanFilter()
 	m_stateInterialEstimate_viaPointMassKalmanFilter[2] = yaml_PMKF_Ahat_row1_for_positions[0]*temp_PMKFstate[2] + yaml_PMKF_Ahat_row1_for_positions[1]*temp_PMKFstate[5] + yaml_PMKF_Kinf_for_positions[0]*m_current_xzy_rpy_measurement[2];
 	m_stateInterialEstimate_viaPointMassKalmanFilter[5] = yaml_PMKF_Ahat_row2_for_positions[0]*temp_PMKFstate[2] + yaml_PMKF_Ahat_row2_for_positions[1]*temp_PMKFstate[5] + yaml_PMKF_Kinf_for_positions[1]*m_current_xzy_rpy_measurement[2];
 
-	// > roll  position and velocity:
-	m_stateInterialEstimate_viaPointMassKalmanFilter[6]  = yaml_PMKF_Ahat_row1_for_angles[0]*temp_PMKFstate[6] + yaml_PMKF_Ahat_row1_for_angles[1]*temp_PMKFstate[9]  + yaml_PMKF_Kinf_for_angles[0]*m_current_xzy_rpy_measurement[3];
-	m_stateInterialEstimate_viaPointMassKalmanFilter[9]  = yaml_PMKF_Ahat_row2_for_angles[0]*temp_PMKFstate[6] + yaml_PMKF_Ahat_row2_for_angles[1]*temp_PMKFstate[9]  + yaml_PMKF_Kinf_for_angles[1]*m_current_xzy_rpy_measurement[3];
-	// > pitch position and velocity:
-	m_stateInterialEstimate_viaPointMassKalmanFilter[7]  = yaml_PMKF_Ahat_row1_for_angles[0]*temp_PMKFstate[7] + yaml_PMKF_Ahat_row1_for_angles[1]*temp_PMKFstate[10] + yaml_PMKF_Kinf_for_angles[0]*m_current_xzy_rpy_measurement[4];
-	m_stateInterialEstimate_viaPointMassKalmanFilter[10] = yaml_PMKF_Ahat_row2_for_angles[0]*temp_PMKFstate[7] + yaml_PMKF_Ahat_row2_for_angles[1]*temp_PMKFstate[10] + yaml_PMKF_Kinf_for_angles[1]*m_current_xzy_rpy_measurement[4];
-	// > yaw   position and velocity:
-	m_stateInterialEstimate_viaPointMassKalmanFilter[8]  = yaml_PMKF_Ahat_row1_for_angles[0]*temp_PMKFstate[8] + yaml_PMKF_Ahat_row1_for_angles[1]*temp_PMKFstate[11] + yaml_PMKF_Kinf_for_angles[0]*m_current_xzy_rpy_measurement[5];
-	m_stateInterialEstimate_viaPointMassKalmanFilter[11] = yaml_PMKF_Ahat_row2_for_angles[0]*temp_PMKFstate[8] + yaml_PMKF_Ahat_row2_for_angles[1]*temp_PMKFstate[11] + yaml_PMKF_Kinf_for_angles[1]*m_current_xzy_rpy_measurement[5];
-}
+	// > for (roll,pitch,yaw) angles
+	//   (taken directly from the measurement):
+	m_stateInterialEstimate_viaPointMassKalmanFilter[6]  = m_current_xzy_rpy_measurement[3];
+	m_stateInterialEstimate_viaPointMassKalmanFilter[7]  = m_current_xzy_rpy_measurement[4];
+	m_stateInterialEstimate_viaPointMassKalmanFilter[8]  = m_current_xzy_rpy_measurement[5];
+}	
 
 
 
@@ -467,14 +849,10 @@ void calculateControlOutput_viaLQR_givenSetpoint(float setpoint[4], float stateI
 	stateInertial[2] = stateInertial[2] - setpoint[2];
 
 	// Clip the z-coordination to within the specified bounds
-	if (stateInertial[2] > 0.40f)
-	{
-		stateInertial[2] = 0.40f;
-	}
-	else if (stateInertial[2] < -0.40f)
-	{
-		stateInertial[2] = -0.40f;
-	}
+	if (stateInertial[2] > yaml_max_setpoint_error_z)
+		stateInertial[2] = yaml_max_setpoint_error_z;
+	else if (stateInertial[2] < -yaml_max_setpoint_error_z)
+		stateInertial[2] = -yaml_max_setpoint_error_z;
 
 	// Fill in the yaw angle error
 	// > This error should be "unwrapped" to be in the range
@@ -485,53 +863,110 @@ void calculateControlOutput_viaLQR_givenSetpoint(float setpoint[4], float stateI
 	while(yawError > PI) {yawError -= 2 * PI;}
 	while(yawError < -PI) {yawError += 2 * PI;}
 	// Clip the error to within the specified bounds
-		if (yawError>(PI/3))
-	{
-		yawError = (PI/3);
-	}
-	else if (yawError<(-PI/3))
-	{
-		yawError = (-PI/3);
-	}
+	if (yawError > yaml_max_setpoint_error_yaw_radians)
+		yawError = yaml_max_setpoint_error_yaw_radians;
+	else if (yawError < -yaml_max_setpoint_error_yaw_radians)
+		yawError = -yaml_max_setpoint_error_yaw_radians;
+
 	// > Finally, put the "yawError" into the "stateError" variable
 	stateInertial[8] = yawError;
 
 	// CONVERSION INTO BODY FRAME
-	// Convert the state erorr from the Inertial frame into the Body frame
+	// Initialise a variable for the body frame error
+	float bodyFrameError[9];
+	// Call the function to convert the state erorr from
+	// the Inertial frame into the Body frame
 	convertIntoBodyFrame(stateInertial, bodyFrameError, temp_stateInertial_yaw);
 
-	calculateControlOutput_viaLQRforRates(bodyFrameError, response);
+	calculateControlOutput_viaLQR_givenError(bodyFrameError, response);
 }
 
-void calculateControlOutput_viaLQRforRates(float stateErrorBody[12], Controller::Response &response)
+void calculateControlOutput_viaLQR_givenError(float stateErrorBody[12], Controller::Response &response)
 {
 	// PERFORM THE "u=Kx" LQR CONTROLLER COMPUTATION
 
+	// Compute the Z-CONTROLLER
+	// > provides the total thrust adjustment
+	float thrustAdjustment =
+		- yaml_gainMatrixThrust_2StateVector[0] * stateErrorBody[2]
+		- yaml_gainMatrixThrust_2StateVector[1] * stateErrorBody[5];
+
+	// Compute the YAW-CONTROLLER
+	// > provides the body frame yaw rate
+	float yawRate_forResponse =
+		- yaml_gainYawRate_fromAngle * stateErrorBody[8];
+
 	// Instantiate the local variables for the following:
 	// > body frame roll rate,
 	// > body frame pitch rate,
-	// > body frame yaw rate,
-	// > total thrust adjustment.
-	// These will be requested from the Crazyflie's on-baord "inner-loop" controller
-	float rollRate_forResponse = 0;
-	float pitchRate_forResponse = 0;
-	float yawRate_forResponse = 0;
-	float thrustAdjustment = 0;
-	
-	// Perform the "-Kx" LQR computation for the rates and thrust:
-	for(int i = 0; i < 9; ++i)
+	float rollRate_forResponse = 0.0;
+	float pitchRate_forResponse = 0.0;
+
+	// Switch between the differnt control method for
+	// the X-Y-CONTROLLER
+	switch (yaml_controller_method)
 	{
-		// BODY FRAME Y CONTROLLER
-		rollRate_forResponse  -= yaml_gainMatrixRollRate[i] * stateErrorBody[i];
-		// BODY FRAME X CONTROLLER
-		pitchRate_forResponse -= yaml_gainMatrixPitchRate[i] * stateErrorBody[i];
-		// BODY FRAME YAW CONTROLLER
-		yawRate_forResponse   -= yaml_gainMatrixYawRate[i] * stateErrorBody[i];
-		// > ALITUDE CONTROLLER (i.e., z-controller):
-		thrustAdjustment      -= yaml_gainMatrixThrust_NineStateVector[i] * stateErrorBody[i];
+		case CONTROLLER_METHOD_RATES:
+		{
+			// Compute the X-CONTROLLER
+			// > provides the body frame pitch rate
+			pitchRate_forResponse = 
+				- yaml_gainMatrixPitchRate_3StateVector[0] * stateErrorBody[0]
+				- yaml_gainMatrixPitchRate_3StateVector[1] * stateErrorBody[3]
+				- yaml_gainMatrixPitchRate_3StateVector[2] * stateErrorBody[7];
+
+			// Compute the Y-CONTROLLER
+			// > provides the body frame roll rate
+			rollRate_forResponse = 
+				- yaml_gainMatrixRollRate_3StateVector[0] * stateErrorBody[1]
+				- yaml_gainMatrixRollRate_3StateVector[1] * stateErrorBody[4]
+				- yaml_gainMatrixRollRate_3StateVector[2] * stateErrorBody[6];
+			break;
+		}
+
+		case CONTROLLER_METHOD_RATE_ANGLE_NESTED:
+		{
+			// Compute the X-CONTROLLER
+			// > Compute the desired pitch angle
+			float pitchAngle_desired = 
+				- yaml_gainMatrixPitchAngle_2StateVector[0] * stateErrorBody[0]
+				- yaml_gainMatrixPitchAngle_2StateVector[1] * stateErrorBody[3];
+			// Clip the request to within the specified limits
+			if (pitchAngle_desired > yaml_max_roll_pitch_request_radians)
+				pitchAngle_desired = yaml_max_roll_pitch_request_radians;
+			else if (pitchAngle_desired < -yaml_max_roll_pitch_request_radians)
+				pitchAngle_desired = -yaml_max_roll_pitch_request_radians;				
+			// > Compute the pitch rate
+			pitchRate_forResponse =
+				- yaml_gainPitchRate_fromAngle * (stateErrorBody[7] - pitchAngle_desired);
+
+			// Compute the Y-CONTROLLER
+			// > Compute the desired roll angle
+			float rollAngle_desired = 
+				- yaml_gainMatrixRollAngle_2StateVector[0] * stateErrorBody[1]
+				- yaml_gainMatrixRollAngle_2StateVector[1] * stateErrorBody[4];
+			// Clip the request to within the specified limits
+			if (rollAngle_desired > yaml_max_roll_pitch_request_radians)
+				rollAngle_desired = yaml_max_roll_pitch_request_radians;
+			else if (rollAngle_desired < -yaml_max_roll_pitch_request_radians)
+				rollAngle_desired = -yaml_max_roll_pitch_request_radians;
+			// > Compute the roll rate
+			rollRate_forResponse =
+				- yaml_gainRollRate_fromAngle * (stateErrorBody[6] - rollAngle_desired);
+
+			break;
+		}
+
+		default:
+		{
+			// Inform the user of the error
+			ROS_ERROR("[DEFAULT CONTROLLER] The variable \"yaml_controller_method\" is not recognised.");
+			break;
+		}
 	}
 
 
+
 	// UPDATE THE "RETURN" THE VARIABLE NAMED "response"
 
 	// Put the computed rates and thrust into the "response" variable
@@ -895,6 +1330,22 @@ void customCommandReceivedCallback(const CustomButtonWithHeader& commandReceived
 
 
 
+// PUBLISH MOTORS-OFF MESSAGE TO FLYING AGENT CLIENT
+void publish_motors_off_to_flying_agent_client()
+{
+	// Instantiate a local variable of type "IntWithHeader"
+	IntWithHeader msg;
+	// Fill in the MOTORS-OFF command
+	msg.data = CMD_CRAZYFLY_MOTORS_OFF;
+	// Fill in the header that this applies
+	msg.shouldCheckForAgentID = false;
+	// Publish the message
+	m_motorsOffToFlyingAgentClientPublisher.publish(msg);
+}
+
+
+
+
 
 //    ----------------------------------------------------------------------------------
 //    L       OOO     A    DDDD
@@ -977,19 +1428,53 @@ void fetchDefaultControllerYamlParameters(ros::NodeHandle& nodeHandle)
 	yaml_max_setpoint_change_per_second_horizontal = getParameterFloat(nodeHandle_for_paramaters , "max_setpoint_change_per_second_horizontal");
 	yaml_max_setpoint_change_per_second_vertical = getParameterFloat(nodeHandle_for_paramaters , "max_setpoint_change_per_second_vertical");
 	
+	// Max error for z
+	yaml_max_setpoint_error_z = = getParameterFloat(nodeHandle_for_paramaters , "max_setpoint_error_z");
+
 	// Max error for yaw angle
 	yaml_max_setpoint_error_yaw_degrees = getParameterFloat(nodeHandle_for_paramaters , "max_setpoint_error_yaw_degrees");
 
+	// Max {roll,pitch} angle request
+	yaml_max_roll_pitch_request_degrees = getParameterFloat(nodeHandle_for_paramaters , "max_roll_pitch_request_degrees");
+
+	// Theshold for {roll,pitch} angle beyond
+	// which the motors are turned off
+	yaml_threshold_roll_pitch_for_turn_off_degrees = getParameterFloat(nodeHandle_for_paramaters , "threshold_roll_pitch_for_turn_off_degrees");
+
 	// The thrust for take off spin motors
 	yaml_takeoff_spin_motors_thrust = getParameterFloat(nodeHandle_for_paramaters , "takeoff_spin_motors_thrust");
 	// The time for the take off spin(-up) motors
-	yaml_takoff_spin_motots_time = getParameterFloat(nodeHandle_for_paramaters , "takoff_spin_motots_time");
+	yaml_takoff_spin_motors_time = getParameterFloat(nodeHandle_for_paramaters , "takoff_spin_motors_time");
 
 	// Height change for the take off move-up
 	yaml_takeoff_move_up_height = getParameterFloat(nodeHandle_for_paramaters , "takeoff_move_up_height");
 	// The time for the take off spin motors
 	yaml_takoff_move_up_time = getParameterFloat(nodeHandle_for_paramaters , "takoff_move_up_time");
 
+	// Minimum and maximum allowed time for: take off goto setpoint
+	yaml_takoff_goto_setpoint_min_time = getParameterFloat(nodeHandle_for_paramaters , "takoff_goto_setpoint_min_time");
+	yaml_takoff_goto_setpoint_max_time = getParameterFloat(nodeHandle_for_paramaters , "takoff_goto_setpoint_max_time");
+
+	// Box within which to keep the integrator on
+	// > Units of [meters]
+	// > The box consider is plus/minus this value
+	yaml_takoff_integrator_on_box_horizontal = getParameterFloat(nodeHandle_for_paramaters , "takoff_integrator_on_box_horizontal");
+	yaml_takoff_integrator_on_box_vertical   = getParameterFloat(nodeHandle_for_paramaters , "takoff_integrator_on_box_vertical");
+	// The time for: take off integrator-on
+	yaml_takoff_integrator_on_time = getParameterFloat(nodeHandle_for_paramaters , "takoff_integrator_on_time");
+
+	// Height change for the landing move-down
+	yaml_landing_move_down_end_height_setpoint  = getParameterFloat(nodeHandle_for_paramaters , "landing_move_down_end_height_setpoint");
+	yaml_landing_move_down_end_height_threshold = getParameterFloat(nodeHandle_for_paramaters , "landing_move_down_end_height_threshold");
+	// The time for: landing move-down
+	yaml_landing_move_down_time_max = getParameterFloat(nodeHandle_for_paramaters , "landing_move_down_time_max");
+
+	// The thrust for landing spin motors
+	yaml_landing_spin_motors_thrust = getParameterFloat(nodeHandle_for_paramaters , "landing_spin_motors_thrust");
+	// The time for: landing spin motors
+	yaml_landing_spin_motors_time = getParameterFloat(nodeHandle_for_paramaters , "landing_spin_motors_time");
+
+
 
 
 	// ------------------------------------------------------
@@ -1022,14 +1507,24 @@ void fetchDefaultControllerYamlParameters(ros::NodeHandle& nodeHandle)
 	// Boolean indiciating whether the debugging ROS_INFO_STREAM should be displayed or not
 	yaml_shouldDisplayDebugInfo = getParameterBool(nodeHandle_for_paramaters, "shouldDisplayDebugInfo");
 	
-	// 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);
+	// > A flag for which controller to use:
+	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);
+	// 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);
+	// 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);
+	yaml_gainRollRate_fromAngle  = getParameterFloat(nodeHandle_for_paramaters, "gainRollRate_fromAngle");
+	yaml_gainPitchRate_fromAngle = getParameterFloat(nodeHandle_for_paramaters, "gainPitchRate_fromAngle");
+	// The LQR Controller parameters for yaw
+	yaml_gainYawRate_fromAngle = getParameterFloat(nodeHandle_for_paramaters, "gainYawRate_fromAngle");
 	
 	// A flag for which estimator to use:
-	yaml_estimator_method = getParameterInt( nodeHandle_for_paramaters , "estimator_method" );	
+	yaml_estimator_method = getParameterInt( nodeHandle_for_paramaters , "estimator_method" );
 	
 	// THE POINT MASS KALMAN FILTER (PMKF) GAINS AND ERROR EVOLUATION
 	// > For the (x,y,z) position
@@ -1059,6 +1554,16 @@ void fetchDefaultControllerYamlParameters(ros::NodeHandle& nodeHandle)
 	// > Conver the control frequency to a delta T
 	m_control_deltaT = 1.0 / yaml_control_frequency;
 
+	// Max error for yaw angle
+	yaml_max_setpoint_error_yaw_radians = DEG2RAD * yaml_max_setpoint_error_yaw_degrees;
+
+	// Max {roll,pitch} angle request
+	yaml_max_roll_pitch_request_radians = DEG2RAD * yaml_max_roll_pitch_request_degrees;
+
+	// Theshold for {roll,pitch} angle beyond
+	// which the motors are turned off
+	yaml_threshold_roll_pitch_for_turn_off_radians = DEG2RAD * yaml_threshold_roll_pitch_for_turn_off_degrees;
+
 	// DEBUGGING: Print out one of the computed quantities
 	ROS_INFO_STREAM("[DEFAULT CONTROLLER] DEBUGGING: thus the weight of this agent in [Newtons] = " << m_cf_weight_in_newtons);
 }
@@ -1281,7 +1786,18 @@ int main(int argc, char* argv[])
 	// will take to perform (in milliseconds)
 	ros::ServiceServer requestManoeuvreService = nodeHandle.advertiseService("RequestManoeuvre", requestManoeuvreCallback);
 
-
+	// Instantiate the class variable "m_motorsOffToFlyingAgentClientPublisher"
+	// to be a "ros::Publisher". This variable advertises under the
+	// name space:
+	// "FlyingAgentClient/Command"
+	// meaning that it is mimicing messages send by the "Fying
+	// Agent Client" node. The message sent has the structure
+	// defined in the file "IntWithHeader.msg".
+	// > First create a node handle to the base namespace
+	//   i.e., the namespace: "/dfall/agentXXX/"
+    ros::NodeHandle base_nodeHandle(m_namespace);
+    // > Now instantiate the publisher
+	m_motorsOffToFlyingAgentClientPublisher = base_nodeHandle.advertise<dfall_pkg::IntWithHeader>("FlyingAgentClient/Command", 1);
 
 
 
diff --git a/dfall_ws/src/dfall_pkg/src/nodes/FlyingAgentClient.cpp b/dfall_ws/src/dfall_pkg/src/nodes/FlyingAgentClient.cpp
index 288af49ad4b62593da4ef551a145c34f30186a53..d55fd3dcf603ce224a07de85940874ef2c513a99 100755
--- a/dfall_ws/src/dfall_pkg/src/nodes/FlyingAgentClient.cpp
+++ b/dfall_ws/src/dfall_pkg/src/nodes/FlyingAgentClient.cpp
@@ -377,9 +377,9 @@ bool safetyCheck_on_positionAndTilt(CrazyflieData data)
     {
         // Check on the ROLL angle
         if(
-            (data.roll > m_maxTiltAngle_for_strictSafety_radians)
+            (data.roll > yaml_maxTiltAngle_for_strictSafety_radians)
             or
-            (data.roll < -m_maxTiltAngle_for_strictSafety_radians)
+            (data.roll < -yaml_maxTiltAngle_for_strictSafety_radians)
         )
         {
             ROS_INFO_STREAM("[FLYING AGENT CLIENT] roll too big.");
@@ -387,9 +387,9 @@ bool safetyCheck_on_positionAndTilt(CrazyflieData data)
         }
         // Check on the PITCH angle
         if(
-            (data.pitch > m_maxTiltAngle_for_strictSafety_radians)
+            (data.pitch > yaml_maxTiltAngle_for_strictSafety_radians)
             or
-            (data.pitch < -m_maxTiltAngle_for_strictSafety_radians)
+            (data.pitch < -yaml_maxTiltAngle_for_strictSafety_radians)
         )
         {
             ROS_INFO_STREAM("[FLYING AGENT CLIENT] pitch too big.");
@@ -721,7 +721,7 @@ void setInstantController(int controller)
     // GUI" about this update to the instant controller
     std_msgs::Int32 controller_used_msg;
     controller_used_msg.data = controller;
-    controllerUsedPublisher.publish(controller_used_msg);
+    m_controllerUsedPublisher.publish(controller_used_msg);
 }
 
 
@@ -1006,9 +1006,9 @@ void loadCrazyflieContext()
 
     CrazyflieContext new_context;
 
-    centralManager.waitForExistence(ros::Duration(-1));
+    m_centralManager.waitForExistence(ros::Duration(-1));
 
-    if(centralManager.call(contextCall)) {
+    if(m_centralManager.call(contextCall)) {
         new_context = contextCall.response.crazyflieContext;
         ROS_INFO_STREAM("[FLYING AGENT CLIENT] CrazyflieContext:\n" << new_context);
 
@@ -1027,7 +1027,7 @@ void loadCrazyflieContext()
             IntWithHeader msg;
             msg.shouldCheckForAgentID = false;
             msg.data = CMD_DISCONNECT;
-            crazyRadioCommandPublisher.publish(msg);
+            m_crazyRadioCommandPublisher.publish(msg);
         }
 
         m_context = new_context;
@@ -1079,7 +1079,7 @@ void loadCrazyflieContext()
 void createControllerServiceClientFromParameterName( std::string paramter_name , ros::ServiceClient& serviceClient )
 {
     ros::NodeHandle nodeHandle_to_own_agent_parameter_service(m_namespace_to_own_agent_parameter_service);
-    ros::NodeHandle nodeHandle(nodeHandle_to_own_agent_parameter_service, "ClientConfig");
+    ros::NodeHandle nodeHandle(nodeHandle_to_own_agent_parameter_service, "FlyingAgentClientConfig");
 
     std::string controllerName;
     if(!nodeHandle.getParam(paramter_name, controllerName))
@@ -1096,7 +1096,7 @@ void createControllerServiceClientFromParameterName( std::string paramter_name ,
 void createIntIntServiceClientFromParameterName( std::string paramter_name , ros::ServiceClient& serviceClient )
 {
     ros::NodeHandle nodeHandle_to_own_agent_parameter_service(m_namespace_to_own_agent_parameter_service);
-    ros::NodeHandle nodeHandle(nodeHandle_to_own_agent_parameter_service, "ClientConfig");
+    ros::NodeHandle nodeHandle(nodeHandle_to_own_agent_parameter_service, "FlyingAgentClientConfig");
 
     std::string controllerName;
     if(!nodeHandle.getParam(paramter_name, controllerName))
@@ -1157,7 +1157,7 @@ void timerCallback_for_createAllcontrollerServiceClients(const ros::TimerEvent&)
 //    ----------------------------------------------------------------------------------
 
 
-void isReadyClientConfigYamlCallback(const IntWithHeader & msg)
+void isReadyFlyingAgentClientConfigYamlCallback(const IntWithHeader & msg)
 {
     // Check whether the message is relevant
     bool isRevelant = checkMessageHeader( m_agentID , msg.shouldCheckForAgentID , msg.agentIDs );
@@ -1175,14 +1175,14 @@ void isReadyClientConfigYamlCallback(const IntWithHeader & msg)
             // > FOR FETCHING FROM THE AGENT'S OWN PARAMETER SERVICE
             case LOAD_YAML_FROM_AGENT:
             {
-                ROS_INFO("[FLYING AGENT CLIENT] Now fetching the ClientConfig YAML parameter values from this agent.");
+                ROS_INFO("[FLYING AGENT CLIENT] Now fetching the FlyingAgentClientConfig 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("[FLYING AGENT CLIENT] Now fetching the ClientConfig YAML parameter values from this agent's coordinator.");
+                ROS_INFO("[FLYING AGENT CLIENT] Now fetching the FlyingAgentClientConfig YAML parameter values from this agent's coordinator.");
                 namespace_to_use = m_namespace_to_coordinator_parameter_service;
                 break;
             }
@@ -1197,20 +1197,20 @@ void isReadyClientConfigYamlCallback(const IntWithHeader & msg)
         // Create a node handle to the selected parameter service
         ros::NodeHandle nodeHandle_to_use(namespace_to_use);
         // Call the function that fetches the parameters
-        fetchClientConfigYamlParameters(nodeHandle_to_use);
+        fetchFlyingAgentClientConfigYamlParameters(nodeHandle_to_use);
     }
 }
 
 
 
 // > Load the paramters from the Client Config YAML file
-void fetchClientConfigYamlParameters(ros::NodeHandle& nodeHandle)
+void fetchFlyingAgentClientConfigYamlParameters(ros::NodeHandle& nodeHandle)
 {
     // Here we load the parameters that are specified in the file:
-    // ClientConfig.yaml
+    // FlyingAgentClientConfig.yaml
 
-    // Add the "ClientConfig" namespace to the "nodeHandle"
-    ros::NodeHandle nodeHandle_for_paramaters(nodeHandle, "ClientConfig");
+    // 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");
@@ -1232,16 +1232,16 @@ void fetchClientConfigYamlParameters(ros::NodeHandle& nodeHandle)
 	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 ClientConfig/isEnabled_strictSafety = " << yaml_isEnabled_strictSafety);
+    ROS_INFO_STREAM("[FLYING AGENT CLIENT] DEBUGGING: the fetched FlyingAgentClientConfig/isEnabled_strictSafety = " << yaml_isEnabled_strictSafety);
 
 
 
     // PROCESS THE PARAMTERS
     // Convert from degrees to radians
-    m_maxTiltAngle_for_strictSafety_radians = DEG2RAD * yaml_maxTiltAngle_for_strictSafety_degrees;
+    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 m_maxTiltAngle_for_strictSafety_radians = " << m_maxTiltAngle_for_strictSafety_radians);
+    ROS_INFO_STREAM("[FLYING AGENT CLIENT CONTROLLER] DEBUGGING: after processing yaml_maxTiltAngle_for_strictSafety_radians = " << yaml_maxTiltAngle_for_strictSafety_radians);
 }
 
 
@@ -1259,70 +1259,91 @@ void fetchClientConfigYamlParameters(ros::NodeHandle& nodeHandle)
 
 int main(int argc, char* argv[])
 {
-    // Starting the ROS-node
+	// Starting the ROS-node
 	ros::init(argc, argv, "FlyingAgentClient");
 
-    // Create a "ros::NodeHandle" type local variable named "nodeHandle",
-    // the "~" indcates that "self" is the node handle assigned.
+	// 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 node
-    std::string m_namespace = ros::this_node::getNamespace();
-    ROS_INFO_STREAM("[FLYING AGENT CLIENT] ros::this_node::getNamespace() =  " << m_namespace);
+	// Get the namespace of this node
+	std::string m_namespace = ros::this_node::getNamespace();
+	ROS_INFO_STREAM("[FLYING AGENT CLIENT] ros::this_node::getNamespace() =  " << m_namespace);
 
 
 
-    // AGENT ID AND COORDINATOR ID
+	// AGENT ID AND COORDINATOR ID
 
-    // Get the ID of the agent and its coordinator
-    bool isValid_IDs = getAgentIDandCoordIDfromClientNode( m_namespace + "/FlyingAgentClient" , &m_agentID , &m_coordID);
+	// NOTES:
+	// > If you look at the "Agent.launch" file in the "launch" folder,
+	//   you will see the following line of code:
+	//   <param name="agentID" value="$(optenv ROS_NAMESPACE)" />
+	//   This line of code adds a parameter named "agentID" to the
+	//   "FlyingAgentClient" node.
+	// > Thus, to get access to this "agentID" paremeter, we first
+	//   need to get a handle to the "FlyingAgentClient" node within which this
+	//   controller service is nested.
 
-    // Stall the node IDs are not valid
-    if ( !isValid_IDs )
-    {
-        ROS_ERROR("[FLYING AGENT CLIENT] Node NOT FUNCTIONING :-)");
-        ros::spin();
-    }
-    else
-    {
-        ROS_INFO_STREAM("[FLYING AGENT CLIENT] loaded agentID = " << m_agentID << ", and coordID = " << m_coordID);
-    }
 
+	// Get the ID of the agent and its coordinator
+	bool isValid_IDs = getAgentIDandCoordIDfromClientNode( m_namespace + "/FlyingAgentClient" , &m_agentID , &m_coordID);
 
+	// Stall the node IDs are not valid
+	if ( !isValid_IDs )
+	{
+		ROS_ERROR("[FLYING AGENT CLIENT] Node NOT FUNCTIONING :-)");
+		ros::spin();
+	}
+	else
+	{
+		ROS_INFO_STREAM("[FLYING AGENT CLIENT] loaded agentID = " << m_agentID << ", and coordID = " << m_coordID);
+	}
 
-    // PARAMETER SERVICE NAMESPACE AND NODEHANDLES:
 
-    // 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 );
+	// PARAMETER SERVICE NAMESPACE AND NODEHANDLES:
 
-    // Inform the user of what namespaces are being used
-    ROS_INFO_STREAM("[FLYING AGENT CLIENT] m_namespace_to_own_agent_parameter_service    =  " << m_namespace_to_own_agent_parameter_service);
-    ROS_INFO_STREAM("[FLYING AGENT CLIENT] m_namespace_to_coordinator_parameter_service  =  " << m_namespace_to_coordinator_parameter_service);
+	// 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.
 
-    // 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);
+	// 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("[FLYING AGENT CLIENT] m_namespace_to_own_agent_parameter_service    =  " << m_namespace_to_own_agent_parameter_service);
+	ROS_INFO_STREAM("[FLYING AGENT CLIENT] 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 clientConfig_yamlReady_fromAgent = nodeHandle_to_own_agent_parameter_service.subscribe(  "ClientConfig", 1, isReadyClientConfigYamlCallback);
-    ros::Subscriber clientConfig_yamlReady_fromCoord = nodeHandle_to_coordinator_parameter_service.subscribe("ClientConfig", 1, isReadyClientConfigYamlCallback);
 
-    //ros::Subscriber safeController_yamlReady_fromAgent = nodeHandle_to_own_agent_parameter_service.subscribe(  "SafeController", 1, isReadySafeControllerYamlCallback);
-    //ros::Subscriber safeController_yamlReady_fromCoord = nodeHandle_to_coordinator_parameter_service.subscribe("SafeController", 1, isReadySafeControllerYamlCallback);
+	// SUBSCRIBE TO "YAML PARAMTERS READY" MESSAGES
 
+	// The parameter service publishes messages with names of the form:
+	// /dfall/.../ParameterService/<filename with .yaml extension>
+	ros::Subscriber flyingAgentClientConfig_yamlReady_fromAgent = nodeHandle_to_own_agent_parameter_service.subscribe(  "FlyingAgentClientConfig", 1, isReadyFlyingAgentClientConfigYamlCallback);
+	ros::Subscriber flyingAgentClientConfig_yamlReady_fromCoord = nodeHandle_to_coordinator_parameter_service.subscribe("FlyingAgentClientConfig", 1, isReadyFlyingAgentClientConfigYamlCallback);
 
 
-    // GIVE YAML VARIABLES AN INITIAL VALUE
+	// GIVE YAML VARIABLES AN INITIAL VALUE
 
 	// This can be done either here or as part of declaring the
 	// variables in the header file
@@ -1331,183 +1352,174 @@ 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.
-    fetchClientConfigYamlParameters(nodeHandle_to_own_agent_parameter_service);
-    //fetchSafeControllerYamlParameters(nodeHandle_to_own_agent_parameter_service);
-
-
-
-
-
-    // INITIALISE ALL THE CONTROLLER SERVICE CLIENTS
-    // > This cannot be done directly here because the other nodes may
-    //   be currently unavailable. Hence, we start a timer for a few
-    //   seconds and in the call back all the controller service
-    //   clients are created.
-    m_controllers_avialble = false;
-    m_timer_for_createAllControllerServiceClients = nodeHandle.createTimer(ros::Duration(3), timerCallback_for_createAllcontrollerServiceClients, true);
-
+	// Call the class function that loads the parameters
+	// from the "FlyingAgentClientConfig.yaml" file.
+	// > This is possible because that YAML file is added
+	//   to the parameter service when launched via the
+	//   "agent.launch" file.
+	fetchFlyingAgentClientConfigYamlParameters(nodeHandle_to_own_agent_parameter_service);
 
 
 
 
-    // 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();
-    
 
-    // INITIALISE THE TAKE-OFF AND LANDING COMPLETE TIMERS
-    // > And stop it immediately
-    m_timer_takeoff_complete = nodeHandle.createTimer(ros::Duration(1.0), timerCallback_takeoff_complete, true);
-    m_timer_takeoff_complete.stop();
-    m_timer_land_complete = nodeHandle.createTimer(ros::Duration(1.0), timerCallback_takeoff_complete, true);
-    m_timer_land_complete.stop();
+	// INITIALISE ALL THE CONTROLLER SERVICE CLIENTS    
+	// > This cannot be done directly here because the other nodes may
+	//   be currently unavailable. Hence, we start a timer for a few
+	//   seconds and in the call back all the controller service
+	//   clients are created.
+	m_controllers_avialble = false;
+	m_timer_for_createAllControllerServiceClients = nodeHandle.createTimer(ros::Duration(3), timerCallback_for_createAllcontrollerServiceClients, true);
 
 
 
+	// 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();
 
 
-    // PUBLISHERS, SUBSCRIBERS, AND SERVICE CLIENTS
 
-	
+	// INITIALISE THE TAKE-OFF AND LANDING COMPLETE TIMERS
+	// > And stop it immediately
+	m_timer_takeoff_complete = nodeHandle.createTimer(ros::Duration(1.0), timerCallback_takeoff_complete, true);
+	m_timer_takeoff_complete.stop();
+	m_timer_land_complete = nodeHandle.createTimer(ros::Duration(1.0), timerCallback_takeoff_complete, true);
+	m_timer_land_complete.stop();
 
-    // CREATE A NODE HANDLE TO THE ROOT OF THE D-FaLL SYSTEM
-    ros::NodeHandle nodeHandle_dfall_root("/dfall");
 
-    // 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);
 
+	// INITIALISE THE CRAZY RADIO STATUS
+	m_crazyradio_status = CRAZY_RADIO_STATE_DISCONNECTED;
 
 
 
-    // SERVICE CLIENT FOR LOADING THE ALLOCATED FLYING ZONE
-    // AND OTHER CONTEXT DETAILS
+	// INITIALISE THE FLYING STATE AND PUBLISH
+	m_flying_state = STATE_MOTORS_OFF;
 
-    //ros::service::waitForService("/CentralManagerService/CentralManager");
-	centralManager = nodeHandle_dfall_root.serviceClient<CMQuery>("CentralManagerService/Query", false);
-	loadCrazyflieContext();
 
-    // Subscriber for when the Flying Zone Database changed
-    ros::Subscriber databaseChangedSubscriber = nodeHandle_dfall_root.subscribe("CentralManagerService/DBChanged", 1, crazyflieContextDatabaseChangedCallback);
 
-    // EMERGENCY STOP OF THE WHOLE "D-FaLL-System"
-    ros::Subscriber emergencyStopSubscriber = nodeHandle_dfall_root.subscribe("emergencyStop", 1, emergencyStopReceivedCallback);
 
-    // 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);
 
+	// PUBLISHERS, SUBSCRIBERS, AND SERVICE CLIENTS
 
 
-    // PUBLISHER FOR COMMANDING THE CRAZYFLIE
-    // i.e., motorCmd{1,2,3,4}, roll, pitch, yaw, and onboardControllerType
-	//ros::Publishers to advertise the control output
-	m_commandForSendingToCrazyfliePublisher = nodeHandle.advertise <ControlCommand>("ControlCommand", 1);
+	// CREATE A NODE HANDLE TO THE ROOT OF THE D-FaLL SYSTEM
+	ros::NodeHandle nodeHandle_dfall_root("/dfall");
 
-	//this topic lets the FlyingAgentClient listen to the terminal commands
-    //commandPublisher = nodeHandle.advertise<std_msgs::Int32>("Command", 1);
 
+	// 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);
 
 
-    // SUBSCRIBER FOR THE CHANGE STATE COMMANDS
-    // i.e., {TAKE-OFF,LAND,MOTORS-OFF,CONTROLLER SELECTION}
-    // > for the agent GUI
-    ros::Subscriber commandSubscriber_to_agent = nodeHandle.subscribe("Command", 1, flyingStateRequestCallback);
-    // > for the coord GUI
-    ros::Subscriber commandSubscriber_to_coord = nodeHandle_to_coordinator.subscribe("FlyingAgentClient/Command", 1, flyingStateRequestCallback);
+	// LOADING OF THIS AGENT'S CONTEXT
+	// Service cleint for loading the allocated flying
+	// zone and other context details
+	//ros::service::waitForService("/CentralManagerService/CentralManager");
+	m_centralManager = nodeHandle_dfall_root.serviceClient<CMQuery>("CentralManagerService/Query", false);
+	// Call the class function that uses this service
+	// client to load the context
+	loadCrazyflieContext();
+	// Subscriber for when the Flying Zone Database changed
+	ros::Subscriber databaseChangedSubscriber = nodeHandle_dfall_root.subscribe("CentralManagerService/DBChanged", 1, crazyflieContextDatabaseChangedCallback);
 
 
+	// EMERGENCY STOP OF THE WHOLE "D-FaLL-System"
+	ros::Subscriber emergencyStopSubscriber = nodeHandle_dfall_root.subscribe("emergencyStop", 1, emergencyStopReceivedCallback);
 
 
-    // PUBLISHER FOR THE CRAZYRADIO COMMANDS
-    // i.e., {CONNECT,DISCONNECT}
-    // This topic lets us use the terminal to communicate with
-    // the crazyRadio node even when the GUI is not launched
-    crazyRadioCommandPublisher = nodeHandle.advertise<IntWithHeader>("crazyRadioCommand", 1);
+	// 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);
 
 
 
-    // PUBLISHER FOR THE FLYING STATE
-    // Possible states: {MOTORS-OFF,TAKE-OFF,FLYING,LAND}
-    // This topic will publish flying state whenever it changes.
-    m_flyingStatePublisher = nodeHandle.advertise<std_msgs::Int32>("flyingState", 1);
+	// PUBLISHER FOR COMMANDING THE CRAZYFLIE
+	// i.e., motorCmd{1,2,3,4}, roll, pitch, yaw, and onboardControllerType
+	//ros::Publishers to advertise the control output
+	m_commandForSendingToCrazyfliePublisher = nodeHandle.advertise <ControlCommand>("ControlCommand", 1);
 
-    
 
-    // PUBLISHER FOR THE 
-    controllerUsedPublisher = nodeHandle.advertise<std_msgs::Int32>("controllerUsed", 1);
+	// SUBSCRIBER FOR THE CHANGE STATE COMMANDS
+	// i.e., {TAKE-OFF,LAND,MOTORS-OFF,CONTROLLER SELECTION}
+	// > for the agent GUI
+	ros::Subscriber commandSubscriber_to_agent = nodeHandle.subscribe("Command", 1, flyingStateRequestCallback);
+	// > for the coord GUI
+	ros::Subscriber commandSubscriber_to_coord = nodeHandle_to_coordinator.subscribe("FlyingAgentClient/Command", 1, flyingStateRequestCallback);
 
 
+	// PUBLISHER FOR THE CRAZYRADIO COMMANDS
+	// i.e., {CONNECT,DISCONNECT}
+	// This topic lets us use the terminal to communicate with
+	// the crazyRadio node even when the GUI is not launched
+	m_crazyRadioCommandPublisher = nodeHandle.advertise<IntWithHeader>("crazyRadioCommand", 1);
 
 
-    // crazy radio status
-    m_crazyradio_status = CRAZY_RADIO_STATE_DISCONNECTED;
+	// PUBLISHER FOR THE FLYING STATE
+	// Possible states: {MOTORS-OFF,TAKE-OFF,FLYING,LAND}
+	// This topic will publish flying state whenever it changes.
+	m_flyingStatePublisher = nodeHandle.advertise<std_msgs::Int32>("flyingState", 1);
 
-    // publish first flying state data
-    std_msgs::Int32 flying_state_msg;
-    flying_state_msg.data = m_flying_state;
-    m_flyingStatePublisher.publish(flying_state_msg);
 
-    // SafeControllerServicePublisher:
-    ros::NodeHandle namespaceNodeHandle = ros::NodeHandle();
-    //safeControllerServiceSetpointPublisher = namespaceNodeHandle.advertise<dfall_pkg::Setpoint>("SafeControllerService/Setpoint", 1);
-    //ros::Subscriber controllerSetpointSubscriber = namespaceNodeHandle.subscribe("student_GUI/ControllerSetpoint", 1, controllerSetPointCallback);
-    //ros::Subscriber safeSetpointSubscriber = namespaceNodeHandle.subscribe("SafeControllerService/Setpoint", 1, safeSetPointCallback);
+	// PUBLISHER FOR THE CONTROLLER CURRENTLY IN USE
+	// This publishes the "m_instant_controller" variable
+	// to reflect the controller that is actually called
+	// when motion capture data is received.
+	m_controllerUsedPublisher = nodeHandle.advertise<std_msgs::Int32>("controllerUsed", 1);
 
-    
 
-    
-    // crazyradio status. Connected, connecting or disconnected
-    ros::Subscriber crazyRadioStatusSubscriber = namespaceNodeHandle.subscribe("CrazyRadio/CrazyRadioStatus", 1, crazyRadioStatusCallback);
+	// 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);
+	ros::Subscriber crazyRadioStatusSubscriber = nodeHandle_to_crazy_radio.subscribe("CrazyRadio/CrazyRadioStatus", 1, crazyRadioStatusCallback);
 
 
+	// SUBSCRIBER FOR BATTERY STATE CHANGES
+	// The battery state change message from the Battery
+	// Monitor node
+	std::string namespace_to_battery_monitor = m_namespace + "/BatteryMonitor";
+	ros::NodeHandle nodeHandle_to_battery_monitor(namespace_to_battery_monitor);
+	ros::Subscriber CFBatterySubscriber = nodeHandle_to_battery_monitor.subscribe("ChangedStateTo", 1, batteryMonitorStateChangedCallback);
 
 
+	// SERVICE SERVER FOR OTHERS TO GET THE CURRENT FLYING STATE
+	// Advertise the service that return the "m_flying_state"
+	// variable when called upon
+	ros::ServiceServer getCurrentFlyingStateService = nodeHandle.advertiseService("getCurrentFlyingState", getCurrentFlyingStateServiceCallback);
 
-    // will publish battery state when it changes
-    //batteryStatePublisher = nodeHandle.advertise<std_msgs::Int32>("batteryState", 1);
 
-    // INITIALISE THE BATTERY VOLTAGE TO SOMETHING CLOSE TO FULL
-    // > This is used to prevent the "Low Battery" being trigged when the 
-    //   first battery voltage data is received
-    //m_battery_voltage = 4.2f;
-    // know the battery level of the CF
-    //ros::Subscriber CFBatterySubscriber = namespaceNodeHandle.subscribe("CrazyRadio/CFBattery", 1, CFBatteryCallback);
 
-    //setBatteryStateTo(BATTERY_STATE_NORMAL); //initialize battery state
 
-    // Subscribe to the battery state change message from the Battery Monitor node
-    std::string namespace_to_battery_monitor = m_namespace + "/BatteryMonitor";
-    ros::NodeHandle nodeHandle_to_battery_monitor(namespace_to_battery_monitor);
-    ros::Subscriber CFBatterySubscriber = nodeHandle_to_battery_monitor.subscribe("ChangedStateTo", 1, batteryMonitorStateChangedCallback);
 
+	// PUBLISH THE FLYING STATE
+	// Ideally the GUI receives this message
+	std_msgs::Int32 flying_state_msg;
+	flying_state_msg.data = m_flying_state;
+	m_flyingStatePublisher.publish(flying_state_msg);
 
-	//start with safe controller
-    m_flying_state = STATE_MOTORS_OFF;
-    setControllerNominallySelected(DEFAULT_CONTROLLER);
-    setInstantController(DEFAULT_CONTROLLER); //initialize this also, so we notify GUI
 
+	// SET THE INITIAL CONTROLLER
+	// This cannot be done before the publishers because
+	// the function also sets the "m_instant_controller"
+	// (as the "m_flying_state" is "STATE_MOTORS_OFF")
+	// and the function that sets the instant controller
+	// publishes a message with the information.
+	setControllerNominallySelected(DEFAULT_CONTROLLER);
 
-    // Advertise the service for the current flying state
-    ros::ServiceServer getCurrentFlyingStateService = nodeHandle.advertiseService("getCurrentFlyingState", getCurrentFlyingStateServiceCallback);
 
 
 
-    // Open a ROS "bag" to store data for post-analysis
-	// std::string package_path;
-	// package_path = ros::package::getPath("dfall_pkg") + "/";
-	// ROS_INFO_STREAM(package_path);
-	// std::string record_file = package_path + "LoggingFlyingAgentClient.bag";
-	// bag.open(record_file, rosbag::bagmode::Write);
 
-	ros::spin();
+	// Print out some information to the user.
+    ROS_INFO("[FLYING AGENT CLIENT] Ready :-)");
 
-	// Close the ROS "bag" that was opened to store data for post-analysis
-	//bag.close();
+    // Enter an endless while loop to keep the node alive.
+    ros::spin();
 
+    // Return zero if the "ross::spin" is cancelled.
     return 0;
 }