diff --git a/pps_ws/src/d_fall_pps/CMakeLists.txt b/pps_ws/src/d_fall_pps/CMakeLists.txt
index 09af57d22ad7089d8bf2bb13052ea6f20b9906fa..81579ef9f643443074a398f3c99e24aa8eccd704 100755
--- a/pps_ws/src/d_fall_pps/CMakeLists.txt
+++ b/pps_ws/src/d_fall_pps/CMakeLists.txt
@@ -230,6 +230,7 @@ add_service_files(
   CMQuery.srv
   CMUpdate.srv
   CMCommand.srv
+  LoadYamlFromFilename.srv
 )
 
 ## Generate actions in the 'action' folder
@@ -326,6 +327,8 @@ add_executable(PPSClient                 src/nodes/PPSClient.cpp
                                          src/classes/GetParamtersAndNamespaces.cpp)
 add_executable(BatteryMonitor            src/nodes/BatteryMonitor.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)
@@ -412,6 +415,7 @@ endif()
 
 add_dependencies(PPSClient                 d_fall_pps_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
 add_dependencies(BatteryMonitor            d_fall_pps_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
+add_dependencies(DefaultControllerService  d_fall_pps_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
 add_dependencies(SafeControllerService     d_fall_pps_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
 add_dependencies(DemoControllerService     d_fall_pps_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
 add_dependencies(StudentControllerService  d_fall_pps_generate_messages_cpp ${catkin_EXPORTED_TARGETS})
@@ -463,6 +467,7 @@ endif()
 
 target_link_libraries(PPSClient                 ${catkin_LIBRARIES})
 target_link_libraries(BatteryMonitor            ${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})
diff --git a/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/include/Constants_for_Qt_compile.h b/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/include/Constants_for_Qt_compile.h
index 93f79577d92fd390d0a9b049e8e7ca50e4ff1c3d..d96707d4ea9d913932c4364b16345c01e6fdfc43 100644
--- a/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/include/Constants_for_Qt_compile.h
+++ b/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/include/Constants_for_Qt_compile.h
@@ -49,6 +49,38 @@
 
 
 
+
+
+//    ----------------------------------------------------------------------------------
+//    
+//    
+//    
+//    
+//    
+//    ----------------------------------------------------------------------------------
+
+
+
+// The types, i.e., agent or coordinator
+#define TYPE_INVALID      -1
+#define TYPE_COORDINATOR   1
+#define TYPE_AGENT         2
+
+
+
+
+
+
+//    ----------------------------------------------------------------------------------
+//    
+//    
+//    
+//    
+//    
+//    ----------------------------------------------------------------------------------
+
+
+
 // Types PPS firmware
 #define CF_COMMAND_TYPE_MOTORS 6
 #define CF_COMMAND_TYPE_RATE   7
@@ -145,12 +177,16 @@
 
 
 
+//    ----------------------------------------------------------------------------------
+//    
+//    
+//    
+//    
+//    
+//    ----------------------------------------------------------------------------------
 
-// The types, i.e., agent or coordinator
-#define TYPE_INVALID      -1
-#define TYPE_COORDINATOR   1
-#define TYPE_AGENT         2
-
+// For standard buttons in the GUI
+#define REQUEST_DEFAULT_SETPOINT_BUTTON_ID    100
 
 
 
diff --git a/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/include/controllertabs.h b/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/include/controllertabs.h
index 7aad04c8c5296835b92b63aba5f5962a70719a4b..a4d11624d21eb22cceac82e97ee775aa07c8ba8c 100644
--- a/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/include/controllertabs.h
+++ b/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/include/controllertabs.h
@@ -52,6 +52,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 poseDataUnavailableSignal();
 
diff --git a/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/include/defaultcontrollertab.h b/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/include/defaultcontrollertab.h
index c8a3a4a919864f445ce8e063c374039374a2d98b..68edb4ea2d980a4c0f4cf7acd3a85855e4d3128b 100644
--- a/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/include/defaultcontrollertab.h
+++ b/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/include/defaultcontrollertab.h
@@ -46,6 +46,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 poseDataUnavailableSlot();
 
@@ -90,12 +91,13 @@ private:
 
 
 #ifdef CATKIN_MAKE
-    // Variable for storing the default setpoint
-    d_fall_pps::SetpointWithHeader m_defaultSetpoint;
-
     // PUBLISHER
     // > For requesting the setpoint to be changed
     ros::Publisher requestSetpointChangePublisher;
+
+    // SUBSCRIBER
+    // > For being notified when the setpoint is changed
+    ros::Subscriber setpointChangedSubscriber;
 #endif
 
 
@@ -104,6 +106,9 @@ private:
 
 
 #ifdef CATKIN_MAKE
+    // For receiving message that the setpoint was changed
+    void setpointChangedCallback(const d_fall_pps::SetpointWithHeader& newSetpoint);
+
     // Fill the header for a message
     void fillSetpointMessageHeader( d_fall_pps::SetpointWithHeader & msg );
 
diff --git a/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/src/controllertabs.cpp b/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/src/controllertabs.cpp
index aafb53da1629859fcb401560f280724a929e951b..d71401287e10bae9b049e929ffa8231bb8def3cd 100644
--- a/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/src/controllertabs.cpp
+++ b/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/src/controllertabs.cpp
@@ -34,6 +34,17 @@ ControllerTabs::ControllerTabs(QWidget *parent) :
             ui->default_controller_tab_widget , &DefaultControllerTab::poseDataUnavailableSlot
         );
 
+
+    // CONNECT TO THE COORDINATOR SIGNAL TO BE ALWAYS UPDATED
+    // WITH THE LIST OF AGENT IDs TO COORDINATE
+    // This is passed from this "controller tabs widget" to
+    // each of the controller tabs. The signal is simply
+    // "passed through"
+    QObject::connect(
+            this , &ControllerTabs::agentIDsToCoordinateChanged ,
+            ui->default_controller_tab_widget , &DefaultControllerTab::setAgentIDsToCoordinate
+        );
+
     
 
 
@@ -148,23 +159,8 @@ void ControllerTabs::poseDataReceivedCallback(const d_fall_pps::ViconData& vicon
 
 void ControllerTabs::setAgentIDsToCoordinate(QVector<int> agentIDs , bool shouldCoordinateAll)
 {
-
-    // Lock the mutex
-    m_agentIDs_toCoordinate_mutex.lock();
-    // Add the "coordinate all" flag
-    m_shouldCoordinateAll = shouldCoordinateAll;
-    // Clear the previous list of agent IDs
-    m_vector_of_agentIDs_toCoordinate.clear();
-    // Copy across the agent IDs, if necessary
-    if (!shouldCoordinateAll)
-    {
-        for ( int irow = 0 ; irow < agentIDs.length() ; irow++ )
-        {
-            m_vector_of_agentIDs_toCoordinate.push_back( agentIDs[irow] );
-        }
-    }
-    // Unlock the mutex
-    m_agentIDs_toCoordinate_mutex.unlock();
+    // Simply pass on the signal to the tabs
+    emit agentIDsToCoordinateChanged( agentIDs , shouldCoordinateAll );
 }
 
 
diff --git a/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/src/defaultcontrollertab.cpp b/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/src/defaultcontrollertab.cpp
index 56aaf802665a67e9fc1634182b5cc2643b9ac9cb..147a43ba57c542b5a46b0d80665e2791498107e6 100644
--- a/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/src/defaultcontrollertab.cpp
+++ b/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/src/defaultcontrollertab.cpp
@@ -36,15 +36,16 @@ DefaultControllerTab::DefaultControllerTab(QWidget *parent) :
     // CREATE A NODE HANDLE TO THIS GUI
     ros::NodeHandle nodeHandle_for_this_gui(this_namespace);
 
-    // CREATE THE COMMAND PUBLISHER
+    // CREATE THE REQUEST SETPOINT CHANGE PUBLISHER
     requestSetpointChangePublisher = nodeHandle_for_this_gui.advertise<d_fall_pps::SetpointWithHeader>("DefaultControllerService/RequestSetpointChange", 1);
 
+    // SUBSCRIBE TO SETPOINT CHANGES
+    // Only if this is an agent GUI
+    if (m_type == TYPE_AGENT)
+    {
+        setpointChangedSubscriber = nodeHandle_for_this_gui.subscribe("DefaultControllerService/SetpointChanged", 1, &DefaultControllerTab::setpointChangedCallback, this);
+    }
 
-    // Set the default setpoint
-    m_defaultSetpoint.x   = 0.0f;
-    m_defaultSetpoint.y   = 0.0f;
-    m_defaultSetpoint.z   = 0.5f;
-    m_defaultSetpoint.yaw = 0.0f;
 #endif
 
 }
@@ -130,6 +131,83 @@ void DefaultControllerTab::poseDataUnavailableSlot()
 
 
 
+
+
+
+
+
+
+
+//    ----------------------------------------------------------------------------------
+//     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
+//
+//     CCCC  H   H    A    N   N   GGGG  EEEEE  DDDD
+//    C      H   H   A A   NN  N  G      E      D   D
+//    C      HHHHH  A   A  N N N  G      EEE    D   D
+//    C      H   H  AAAAA  N  NN  G   G  E      D   D
+//     CCCC  H   H  A   A  N   N   GGGG  EEEEE  DDDD
+//
+//     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
+//    ----------------------------------------------------------------------------------
+
+
+#ifdef CATKIN_MAKE
+void DefaultControllerTab::setpointChangedCallback(const d_fall_pps::SetpointWithHeader& newSetpoint)
+{
+    // INITIALISE A STRING VARIABLE FOR ADDING THE "+"
+    QString qstr = "";
+
+    // EXTRACT THE SETPOINT
+    float x = newSetpoint.x;
+    float y = newSetpoint.y;
+    float z = newSetpoint.z;
+    float yaw = newSetpoint.yaw;
+
+    // UPDATE THE SETPOINT COLUMN
+    if (x < 0.0f) qstr = ""; else qstr = "+";
+    ui->lineEdit_setpoint_current_x->setText(qstr + QString::number( x, 'f', 3));
+    if (y < 0.0f) qstr = ""; else qstr = "+";
+    ui->lineEdit_setpoint_current_y->setText(qstr + QString::number( y, 'f', 3));
+    if (z < 0.0f) qstr = ""; else qstr = "+";
+    ui->lineEdit_setpoint_current_z->setText(qstr + QString::number( z, 'f', 3));
+
+    if (yaw < 0.0f) qstr = ""; else qstr = "+";
+    ui->lineEdit_setpoint_current_yaw->setText(qstr + QString::number( yaw * RAD2DEG, 'f', 3));
+}
+#endif
+
+
+
+
+
+
+
+
+
+
+//    ----------------------------------------------------------------------------------
+//    RRRR   EEEEE   QQQ   U   U  EEEEE   SSSS  TTTTT     N   N  EEEEE  W     W
+//    R   R  E      Q   Q  U   U  E      S        T       NN  N  E      W     W
+//    RRRR   EEE    Q   Q  U   U  EEE     SSS     T       N N N  EEE    W     W 
+//    R   R  E      Q  Q   U   U  E          S    T       N  NN  E       W W W
+//    R   R  EEEEE   QQ Q   UUU   EEEEE  SSSS     T       N   N  EEEEE    W W
+//
+//     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 DefaultControllerTab::publishSetpoint(float x, float y, float z, float yaw)
 {
 #ifdef CATKIN_MAKE
@@ -143,7 +221,7 @@ void DefaultControllerTab::publishSetpoint(float x, float y, float z, float yaw)
     msg.x   = x;
     msg.y   = y;
     msg.z   = z;
-    msg.yaw = yaw;
+    msg.yaw = yaw * DEG2RAD;
 
     // Publish the setpoint
     this->requestSetpointChangePublisher.publish(msg);
@@ -224,8 +302,23 @@ void DefaultControllerTab::on_set_setpoint_button_clicked()
 void DefaultControllerTab::on_default_setpoint_button_clicked()
 {
 #ifdef CATKIN_MAKE
-    // Call the function to publish the setpoint
-    publishSetpoint(m_defaultSetpoint.x, m_defaultSetpoint.y, m_defaultSetpoint.z, m_defaultSetpoint.yaw );
+    // Publish this as a blank setpoint with the 
+    // "buttonID" field set appropriately
+
+    // Initialise the message as a local variable
+    d_fall_pps::SetpointWithHeader msg;
+
+    // Fill the header of the message
+    fillSetpointMessageHeader( msg );
+
+    // Fill in the (x,y,z,yaw) values
+    msg.buttonID = REQUEST_DEFAULT_SETPOINT_BUTTON_ID;
+
+    // Publish the default setpoint button press
+    this->requestSetpointChangePublisher.publish(msg);
+
+    // Inform the user about the change
+    ROS_INFO_STREAM("[DEFAULT CONTROLLER GUI] Published request for setpoint change to the default");
 #endif
 }
 
@@ -416,6 +509,99 @@ void DefaultControllerTab::on_yaw_increment_minus_button_clicked()
 
 
 
+//    ----------------------------------------------------------------------------------
+//      A     GGGG  EEEEE  N   N  TTTTT     III  DDDD    SSSS
+//     A A   G      E      NN  N    T        I   D   D  S
+//    A   A  G      EEE    N N N    T        I   D   D   SSS
+//    AAAAA  G   G  E      N  NN    T        I   D   D      S
+//    A   A   GGGG  EEEEE  N   N    T       III  DDDD   SSSS
+//    ----------------------------------------------------------------------------------
+
+
+void DefaultControllerTab::setAgentIDsToCoordinate(QVector<int> agentIDs , bool shouldCoordinateAll)
+{
+
+    // Lock the mutex
+    m_agentIDs_toCoordinate_mutex.lock();
+    // Add the "coordinate all" flag
+    m_shouldCoordinateAll = shouldCoordinateAll;
+    // Clear the previous list of agent IDs
+    m_vector_of_agentIDs_toCoordinate.clear();
+    // Copy across the agent IDs, if necessary
+    if (!shouldCoordinateAll)
+    {
+        for ( int irow = 0 ; irow < agentIDs.length() ; irow++ )
+        {
+            m_vector_of_agentIDs_toCoordinate.push_back( agentIDs[irow] );
+        }
+    }
+    // Unlock the mutex
+    m_agentIDs_toCoordinate_mutex.unlock();
+
+
+#ifdef CATKIN_MAKE
+    // If there is only one agent to coordinate,
+    // then subscribe to the relevant data
+    if (agentIDs.length() == 1)
+    {
+
+        // // > Create the appropriate node handle
+        QString agent_base_namespace = "/dfall/agent" + QString::number(agentIDs[0]).rightJustified(3, '0');
+        ros::NodeHandle agent_base_nodeHandle(agent_base_namespace.toStdString());
+
+        // // > Request the current flying state
+        // ros::ServiceClient getCurrentFlyingStateService = agent_base_nodeHandle.serviceClient<d_fall_pps::IntIntService>("PPSClient/getCurrentFlyingState", false);
+        // d_fall_pps::IntIntService getFlyingStateCall;
+        // getFlyingStateCall.request.data = 0;
+        // getCurrentFlyingStateService.waitForExistence(ros::Duration(2.0));
+        // if(getCurrentFlyingStateService.call(getFlyingStateCall))
+        // {
+        //     setFlyingState(getFlyingStateCall.response.data);
+        // }
+        // else
+        // {
+        //     setFlyingState(STATE_UNAVAILABLE);
+        // }
+
+        // // > Request the current status of the crazy radio
+        // ros::ServiceClient getCurrentCrazyRadioStateService = agent_base_nodeHandle.serviceClient<d_fall_pps::IntIntService>("CrazyRadio/getCurrentCrazyRadioStatus", false);
+        // d_fall_pps::IntIntService getCrazyRadioCall;
+        // getCrazyRadioCall.request.data = 0;
+        // getCurrentCrazyRadioStateService.waitForExistence(ros::Duration(2.0));
+        // if(getCurrentCrazyRadioStateService.call(getCrazyRadioCall))
+        // {
+        //     setCrazyRadioStatus(getCrazyRadioCall.response.data);
+        // }
+        // else
+        // {
+        //     setCrazyRadioStatus(CRAZY_RADIO_STATE_DISCONNECTED);
+        // }
+
+
+        // SUBSCRIBERS
+        // > For receiving message that the setpoint was changed
+        setpointChangedSubscriber = agent_base_nodeHandle.subscribe("DefaultControllerService/SetpointChanged", 1, &DefaultControllerTab::setpointChangedCallback, this);
+    }
+    else
+    {
+        // Unsubscribe
+        setpointChangedSubscriber.shutdown();
+
+        // Set information back to the default
+        ui->lineEdit_setpoint_current_x->setText("xx.xx");
+        ui->lineEdit_setpoint_current_y->setText("xx.xx");
+        ui->lineEdit_setpoint_current_z->setText("xx.xx");
+        ui->lineEdit_setpoint_current_yaw->setText("xx.xx");
+
+    }
+#endif
+}
+
+
+
+
+
+
 //    ----------------------------------------------------------------------------------
 //    M   M   SSSS   GGG      H   H  EEEEE    A    DDDD   EEEEE  RRRR
 //    MM MM  S      G   G     H   H  E       A A   D   D  E      R   R
diff --git a/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/src/enablecontrollerloadyamlbar.cpp b/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/src/enablecontrollerloadyamlbar.cpp
index 2890865534f0f48097abf5f06a36b1a127bc7f0c..135fab04895da4edee344a057c55f2513abea0f3 100644
--- a/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/src/enablecontrollerloadyamlbar.cpp
+++ b/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/src/enablecontrollerloadyamlbar.cpp
@@ -137,7 +137,18 @@ void EnableControllerLoadYamlBar::on_load_yaml_student_button_clicked()
 
 void EnableControllerLoadYamlBar::on_load_yaml_default_button_clicked()
 {
-
+    #ifdef CATKIN_MAKE
+    // Create a local variable for the message
+    d_fall_pps::StringWithHeader yaml_filename_msg;
+    // Set for whom this applies to
+    fillStringMessageHeader(yaml_filename_msg);
+    // Specify the data
+    yaml_filename_msg.data = "DefaultController";
+    // Send the message
+    m_requestLoadYamlFilenamePublisher.publish(yaml_filename_msg);
+    // Inform the user that the menu item was selected
+    ROS_INFO("[ENABLE CONTROLLER LOAD YAML GUI BAR] Load Default Controller YAML was clicked.");
+#endif
 }
 
 
diff --git a/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/src/mainwindow.cpp b/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/src/mainwindow.cpp
index cfd33ca8fc32650c81e72946bc7657bb6d67a89a..58f17f9d672367d1e5233bfaf8cb6292a2341ac6 100644
--- a/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/src/mainwindow.cpp
+++ b/pps_ws/src/d_fall_pps/GUI_Qt/flyingAgentGUI/src/mainwindow.cpp
@@ -95,21 +95,25 @@ MainWindow::MainWindow(int argc, char **argv, QWidget *parent) :
 
     // CONNECT TO THE COORDINATOR SIGNAL TO BE ALWAYS UPDATED
     // WITH THE LIST OF AGENT IDs TO COORDINATE
-    // Connect the "should coordinate value changed" signal to
-    // the respective slot
+    // This is passed from the "coordinator" to the elements
+    // in the main part of the GUI, namely to the:
+    // > "top banner",
+    // > "connect,start,stop bar",
+    // > "enable controller, load yaml bar", and
+    // > "controller tabs widget".
     QObject::connect(
             ui->customWidget_coordinator , &Coordinator::agentIDsToCoordinateChanged ,
-            ui->customWidget_connectStartStopBar , &ConnectStartStopBar::setAgentIDsToCoordinate
+            ui->customWidget_topBanner , &TopBanner::setAgentIDsToCoordinate
             );
 
     QObject::connect(
             ui->customWidget_coordinator , &Coordinator::agentIDsToCoordinateChanged ,
-            ui->customWidget_enableControllerLoadYamlBar , &EnableControllerLoadYamlBar::setAgentIDsToCoordinate
+            ui->customWidget_connectStartStopBar , &ConnectStartStopBar::setAgentIDsToCoordinate
             );
 
     QObject::connect(
             ui->customWidget_coordinator , &Coordinator::agentIDsToCoordinateChanged ,
-            ui->customWidget_topBanner , &TopBanner::setAgentIDsToCoordinate
+            ui->customWidget_enableControllerLoadYamlBar , &EnableControllerLoadYamlBar::setAgentIDsToCoordinate
             );
 
     QObject::connect(
diff --git a/pps_ws/src/d_fall_pps/include/nodes/Constants.h b/pps_ws/src/d_fall_pps/include/nodes/Constants.h
index 3389835206d622359a88917b67ad18df10db7b16..fd4d1d4fcf29c6b76782f79f803ec6f93bd7a988 100644
--- a/pps_ws/src/d_fall_pps/include/nodes/Constants.h
+++ b/pps_ws/src/d_fall_pps/include/nodes/Constants.h
@@ -53,6 +53,25 @@
 
 
 
+//    ----------------------------------------------------------------------------------
+//    
+//    
+//    
+//    
+//    
+//    ----------------------------------------------------------------------------------
+
+
+
+// The types, i.e., agent or coordinator
+#define TYPE_INVALID      -1
+#define TYPE_COORDINATOR   1
+#define TYPE_AGENT         2
+
+
+
+
+
 //    ----------------------------------------------------------------------------------
 //    
 //    
@@ -192,11 +211,16 @@
 
 
 
-// The types, i.e., agent or coordinator
-#define TYPE_INVALID      -1
-#define TYPE_COORDINATOR   1
-#define TYPE_AGENT         2
+//    ----------------------------------------------------------------------------------
+//    
+//    
+//    
+//    
+//    
+//    ----------------------------------------------------------------------------------
 
+// For standard buttons in the GUI
+#define REQUEST_DEFAULT_SETPOINT_BUTTON_ID    100
 
 
 
diff --git a/pps_ws/src/d_fall_pps/include/nodes/DefaultControllerService.h b/pps_ws/src/d_fall_pps/include/nodes/DefaultControllerService.h
new file mode 100644
index 0000000000000000000000000000000000000000..b88fa8e2d13a1ea256914875ee955ec4109e0429
--- /dev/null
+++ b/pps_ws/src/d_fall_pps/include/nodes/DefaultControllerService.h
@@ -0,0 +1,237 @@
+//    Copyright (C) 2017, ETH Zurich, D-ITET, Paul Beuchat, Angel Romero, Cyrill Burgener, Marco Mueller, Philipp Friedli
+//
+//    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 fall-back controller
+//
+//    ----------------------------------------------------------------------------------
+
+
+
+
+
+//    ----------------------------------------------------------------------------------
+//    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
+//    ----------------------------------------------------------------------------------
+
+// These various headers need to be included so that this controller service can be
+// connected with the D-FaLL system.
+
+//some useful libraries
+#include <math.h>
+#include <stdlib.h>
+#include "ros/ros.h"
+#include <ros/package.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 "d_fall_pps/IntWithHeader.h"
+#include "d_fall_pps/StringWithHeader.h"
+#include "d_fall_pps/SetpointWithHeader.h"
+#include "d_fall_pps/ViconData.h"
+#include "d_fall_pps/Setpoint.h"
+#include "d_fall_pps/ControlCommand.h"
+#include "d_fall_pps/Controller.h"
+#include "d_fall_pps/DebugMsg.h"
+#include "d_fall_pps/CustomButton.h"
+
+// Include the DFALL service types
+#include "d_fall_pps/LoadYamlFromFilename.h"
+
+// Include the shared definitions
+#include "nodes/Constants.h"
+
+// Include other classes
+#include "classes/GetParamtersAndNamespaces.h"
+
+// Need for having a ROS "bag" to store data for post-analysis
+//#include <rosbag/bag.h>
+
+
+
+
+
+// Namespacing the package
+using namespace d_fall_pps;
+
+
+
+
+
+//    ----------------------------------------------------------------------------------
+//    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
+//    ----------------------------------------------------------------------------------
+
+// These constants are defined to make the code more readable and adaptable.
+
+// NOTE: manz constants are already defined in the "Constant.h" header file
+
+
+
+
+
+//    ----------------------------------------------------------------------------------
+//    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 ID of the agent that this node is monitoring
+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;
+
+
+
+
+// The mass of the crazyflie, in [grams]
+float yaml_cf_mass_in_grams = 25.0;
+
+// 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};
+
+// Frequency at which the controller is running
+float yaml_control_frequency = 200.0;
+
+// The min and max for saturating 16 bit thrust commands
+float yaml_command_sixteenbit_min = 1000;
+float yaml_command_sixteenbit_max = 65000;
+
+// The default setpoint, the ordering is (x,y,z,yaw),
+// with unit [meters,meters,meters,radians]
+std::vector<float> yaml_default_setpoint = {0.0,0.0,0.4,0.0};
+
+
+
+// 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];
+
+std::vector<float>  m_setpoint{0.0,0.0,0.4,0.0};     // The setpoints for (x,y,z) position and yaw angle, in that order
+
+
+// The LQR Controller parameters for "LQR_RATE_MODE"
+std::vector<float> m_gainMatrixRollRate    =  { 0.00,-1.71, 0.00, 0.00,-1.33, 0.00, 5.12, 0.00, 0.00};
+std::vector<float> m_gainMatrixPitchRate   =  { 1.71, 0.00, 0.00, 1.33, 0.00, 0.00, 0.00, 5.12, 0.00};
+std::vector<float> m_gainMatrixYawRate     =  { 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 2.84};
+std::vector<float> m_gainMatrixThrust      =  { 0.00, 0.00, 0.19, 0.00, 0.00, 0.08, 0.00, 0.00, 0.00};
+
+
+// ROS Publisher for debugging variables
+ros::Publisher m_debugPublisher;
+
+// ROS Publisher for inform the network about
+// changes to the setpoin
+ros::Publisher m_setpointChangedPublisher;
+
+
+
+// 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
+//    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
+//    ----------------------------------------------------------------------------------
+
+// These function prototypes are not strictly required for this code to
+// complile, but adding the function prototypes here means the the functions
+// can be written below in any order. If the function prototypes are not
+// included then the function need to written below in an order that ensure
+// each function is implemented before it is called from another function,
+// 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);
+
+// CUSTOM COMMAND RECEIVED CALLBACK
+void customCommandReceivedCallback(const CustomButton& commandReceived);
+
+
+// > For the LOADING of YAML PARAMETERS
+void isReadyDefaultControllerYamlCallback(const IntWithHeader & msg);
+void fetchDefaultControllerYamlParameters(ros::NodeHandle& nodeHandle);
\ No newline at end of file
diff --git a/pps_ws/src/d_fall_pps/include/nodes/ParameterService.h b/pps_ws/src/d_fall_pps/include/nodes/ParameterService.h
index 011ff0c73baa4186b05bb15e610f950c15b17d3a..75d5172928d0792a955debcbc01809dd8b22da0e 100644
--- a/pps_ws/src/d_fall_pps/include/nodes/ParameterService.h
+++ b/pps_ws/src/d_fall_pps/include/nodes/ParameterService.h
@@ -58,6 +58,9 @@
 //#include "d_fall_pps/FloatWithHeader.h"
 #include "d_fall_pps/StringWithHeader.h"
 
+// Include the DFALL service types
+#include "d_fall_pps/LoadYamlFromFilename.h"
+
 // Include the shared definitions
 #include "nodes/Constants.h"
 
@@ -101,6 +104,10 @@ int m_ID = 0;
 // The namespace into which this parameter service loads yaml parameters
 std::string m_base_namespace;
 
+// Publisher for passing a service request onto the
+// loadinging function
+ros::Publisher requestLoadYamlFilenamePublisher;
+
 
 
 
@@ -119,7 +126,7 @@ std::string m_base_namespace;
 //    P      R   R   OOO     T     OOO     T      Y    P      EEEEE  SSSS
 //    ----------------------------------------------------------------------------------
 
-void requestLoadControllerYamlCallback(const std_msgs::Int32& msg);
+bool requestLoadYamlFilenameCallbackServiceCallback(LoadYamlFromFilename::Request &request, LoadYamlFromFilename::Response &response);
 
 void requestLoadYamlFilenameCallback(const StringWithHeader& yamlFilenameToLoad);
 
diff --git a/pps_ws/src/d_fall_pps/include/nodes/StudentControllerService.h b/pps_ws/src/d_fall_pps/include/nodes/StudentControllerService.h
index 8eea640a9f5e8a92d778757f8e86be50b117124e..7d440b25ef09187e8e01410ea7d6affbf38cd48c 100644
--- a/pps_ws/src/d_fall_pps/include/nodes/StudentControllerService.h
+++ b/pps_ws/src/d_fall_pps/include/nodes/StudentControllerService.h
@@ -55,7 +55,7 @@
 #include "std_msgs/Float32.h"
 #include <std_msgs/String.h>
 
-//the generated structs from the msg-files have to be included
+// Include the DFALL message types
 #include "d_fall_pps/IntWithHeader.h"
 #include "d_fall_pps/StringWithHeader.h"
 #include "d_fall_pps/ViconData.h"
@@ -65,6 +65,9 @@
 #include "d_fall_pps/DebugMsg.h"
 #include "d_fall_pps/CustomButton.h"
 
+// Include the DFALL service types
+#include "d_fall_pps/LoadYamlFromFilename.h"
+
 // Include the shared definitions
 #include "nodes/Constants.h"
 
diff --git a/pps_ws/src/d_fall_pps/launch/Agent.launch b/pps_ws/src/d_fall_pps/launch/Agent.launch
index bb994eb31df45deb508c13f4107f60f93d0da668..2c97814356f996fc45087b00d2c4d6427fe6fb67 100755
--- a/pps_ws/src/d_fall_pps/launch/Agent.launch
+++ b/pps_ws/src/d_fall_pps/launch/Agent.launch
@@ -47,6 +47,15 @@
 			>
 		</node>
 
+		<!-- DEFAULT CONTROLLER -->
+		<node
+			pkg    = "d_fall_pps"
+			name   = "DefaultControllerService"
+			output = "screen"
+			type   = "DefaultControllerService"
+			>
+		</node>
+
 		<!-- SAFE CONTROLLER -->
 		<node
 			pkg    = "d_fall_pps"
diff --git a/pps_ws/src/d_fall_pps/msg/SetpointWithHeader.msg b/pps_ws/src/d_fall_pps/msg/SetpointWithHeader.msg
index 9198063bc304eeb821d802752c48b99e2f7402de..ff412908b37d14516ae13d70209dd218c95b2277 100644
--- a/pps_ws/src/d_fall_pps/msg/SetpointWithHeader.msg
+++ b/pps_ws/src/d_fall_pps/msg/SetpointWithHeader.msg
@@ -5,4 +5,4 @@ float64 yaw
 bool isChecked
 uint32 buttonID
 bool shouldCheckForAgentID
-uint8[] agentIDs
\ No newline at end of file
+uint32[] agentIDs
\ No newline at end of file
diff --git a/pps_ws/src/d_fall_pps/param/DefaultController.yaml b/pps_ws/src/d_fall_pps/param/DefaultController.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..3c208ca7a7f77c05e4570bee4e0c62a0eb02ae3b
--- /dev/null
+++ b/pps_ws/src/d_fall_pps/param/DefaultController.yaml
@@ -0,0 +1,16 @@
+# The mass of the crazyflie, in [grams]
+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 min and max for saturating 16 bit thrust commands
+command_sixteenbit_min : 1000
+command_sixteenbit_max : 65000
+
+# 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
diff --git a/pps_ws/src/d_fall_pps/src/nodes/DefaultControllerService.cpp b/pps_ws/src/d_fall_pps/src/nodes/DefaultControllerService.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fe37b42c2eec7e7ad03ef1c088d16d400ffe4be8
--- /dev/null
+++ b/pps_ws/src/d_fall_pps/src/nodes/DefaultControllerService.cpp
@@ -0,0 +1,962 @@
+//    Copyright (C) 2017, ETH Zurich, D-ITET, Paul Beuchat, Angel Romero, Cyrill Burgener, Marco Mueller, Philipp Friedli
+//
+//    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 fall-back controller
+//
+//    ----------------------------------------------------------------------------------
+
+
+
+
+
+// INCLUDE THE HEADER
+#include "nodes/DefaultControllerService.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
+//    ----------------------------------------------------------------------------------
+
+
+
+
+
+//    ------------------------------------------------------------------------------
+//     OOO   U   U  TTTTT  EEEEE  RRRR 
+//    O   O  U   U    T    E      R   R
+//    O   O  U   U    T    EEE    RRRR
+//    O   O  U   U    T    E      R  R
+//     OOO    UUU     T    EEEEE  R   R
+//
+//     CCCC   OOO   N   N  TTTTT  RRRR    OOO   L           L       OOO    OOO   PPPP
+//    C      O   O  NN  N    T    R   R  O   O  L           L      O   O  O   O  P   P
+//    C      O   O  N N N    T    RRRR   O   O  L           L      O   O  O   O  PPPP
+//    C      O   O  N  NN    T    R  R   O   O  L           L      O   O  O   O  P
+//     CCCC   OOO   N   N    T    R   R   OOO   LLLLL       LLLLL   OOO    OOO   P
+//    ----------------------------------------------------------------------------------
+
+// This function is the callback that is linked to the "DefaultController" 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)
+//
+// 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
+//     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
+// 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
+// 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
+// 
+// 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
+//
+// > For completeing the class exercises it is only required to use
+//   the CF_COMMAND_TYPE_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
+//      "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
+//
+//  > This is a top view,
+//  > M1 to M4 stand for Motor 1 to Motor 4,
+//  > "CW"  indicates that the motor rotates Clockwise,
+//  > "CCW" indicates that the motor rotates Counter-Clockwise,
+//  > By right-hand axis convention, the positive z-direction points our of the screen,
+//  > This being a "top view" means tha the direction of positive thrust produced
+//    by the propellers is also out of the screen.
+//
+//        ____                         ____
+//       /    \                       /    \
+//  (CW) | M4 |           x           | M1 | (CCW)
+//       \____/\          ^          /\____/
+//            \ \         |         / /
+//             \ \        |        / /
+//              \ \______ | ______/ /
+//               \        |        /
+//                |       |       |
+//        y <-------------o       |
+//                |               |
+//               / _______________ \
+//              / /               \ \
+//             / /                 \ \
+//        ____/ /                   \ \____
+//       /    \/                     \/    \
+// (CCW) | M3 |                       | M2 | (CW)
+//       \____/                       \____/
+//
+//
+//
+// This function WILL NEED TO BE edited for successful completion of the PPS exercise
+bool calculateControlOutput(Controller::Request &request, Controller::Response &response)
+{
+
+	// This is the "start" of the outer loop controller, add all your control
+	// computation here, or you may find it convienient to create functions
+	// to keep you code cleaner
+
+
+	// Define a local array to fill in with the state error
+	float stateErrorInertial[9];
+
+	// Fill in the (x,y,z) position error
+	stateErrorInertial[0] = request.ownCrazyflie.x - m_setpoint[0];
+	stateErrorInertial[1] = request.ownCrazyflie.y - m_setpoint[1];
+	stateErrorInertial[2] = request.ownCrazyflie.z - m_setpoint[2];
+
+	// Compute an estimate of the velocity
+	// > 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;
+
+	// Fill in the roll and pitch angle measurements directly
+	stateErrorInertial[6] = request.ownCrazyflie.roll;
+	stateErrorInertial[7] = request.ownCrazyflie.pitch;
+
+	// Fill in the yaw angle error
+	// > This error should be "unwrapped" to be in the range
+	//   ( -pi , pi )
+	// > First, get the yaw error into a local variable
+	float yawError = request.ownCrazyflie.yaw - m_setpoint[3];
+	// > Second, "unwrap" the yaw error to the interval ( -pi , pi )
+	while(yawError > PI) {yawError -= 2 * PI;}
+	while(yawError < -PI) {yawError += 2 * PI;}
+	// > Third, put the "yawError" into the "stateError" variable
+	stateErrorInertial[8] = yawError;
+
+
+	// CONVERSION INTO BODY FRAME
+	// Conver the state erorr from the Inertial frame into the Body frame
+	// > Note: the function "convertIntoBodyFrame" is implemented in this file
+	//   and by default does not perform any conversion. The equations to convert
+	//   the state error into the body frame should be implemented in that function
+	//   for successful completion of the PPS exercise
+	float stateErrorBody[9];
+	convertIntoBodyFrame(stateErrorInertial, stateErrorBody, request.ownCrazyflie.yaw);
+
+
+	// SAVE THE STATE ERROR TO BE USED NEXT TIME THIS FUNCTION IS CALLED
+	// > as we have already used previous error we can now update it update it
+	for(int i = 0; i < 9; ++i)
+	{
+		m_previous_stateErrorInertial[i] = stateErrorInertial[i];
+	}
+
+
+
+	
+	// YAW CONTROLLER
+
+	// Perform the "-Kx" LQR computation for the yaw rate
+	// to respond with
+	float yawRate_forResponse = 0;
+	for(int i = 0; i < 9; ++i)
+	{
+		yawRate_forResponse -= m_gainMatrixYawRate[i] * stateErrorBody[i];
+	}
+	// Put the computed yaw rate into the "response" variable
+	response.controlOutput.yaw = yawRate_forResponse;
+
+
+
+
+	// ALITUDE CONTROLLER (i.e., z-controller)
+	
+	// Perform the "-Kx" LQR computation for the thrust adjustment
+	// to use for computing the response with
+	float thrustAdjustment = 0;
+	for(int i = 0; i < 9; ++i)
+	{
+		thrustAdjustment -= m_gainMatrixThrust[i] * stateErrorBody[i];
+	}
+
+	// Add the feed-forward thrust before putting in the response
+	float feed_forward_thrust_per_motor = m_cf_weight_in_newtons / 4.0;
+	float thrust_per_motor = thrustAdjustment + feed_forward_thrust_per_motor;
+
+	// > NOTE: the function "computeMotorPolyBackward" converts the
+	//         input argument from Newtons to the 16-bit command
+	//         expected by the Crazyflie.
+	response.controlOutput.motorCmd1 = computeMotorPolyBackward(thrust_per_motor);
+	response.controlOutput.motorCmd2 = computeMotorPolyBackward(thrust_per_motor);
+	response.controlOutput.motorCmd3 = computeMotorPolyBackward(thrust_per_motor);
+	response.controlOutput.motorCmd4 = computeMotorPolyBackward(thrust_per_motor);
+
+	
+	// BODY FRAME X CONTROLLER
+
+	// Perform the "-Kx" LQR computation for the pitch rate
+	// to respoond with
+	float pitchRate_forResponse = 0;
+	for(int i = 0; i < 9; ++i)
+	{
+		pitchRate_forResponse -= m_gainMatrixPitchRate[i] * stateErrorBody[i];
+	}
+	// Put the computed pitch rate into the "response" variable
+	response.controlOutput.pitch = pitchRate_forResponse;
+
+
+
+
+	// BODY FRAME Y CONTROLLER
+
+	// Instantiate the local variable for the roll rate that will be requested
+	// from the Crazyflie's on-baord "inner-loop" controller
+	
+
+	// Perform the "-Kx" LQR computation for the roll rate
+	// to respoond with
+	float rollRate_forResponse = 0;
+	for(int i = 0; i < 9; ++i)
+	{
+		rollRate_forResponse -= m_gainMatrixRollRate[i] * stateErrorBody[i];
+	}
+	// Put the computed roll rate into the "response" variable
+	response.controlOutput.roll = rollRate_forResponse;
+
+	
+	
+	// PREPARE AND RETURN THE VARIABLE "response"
+
+	/*choosing the Crazyflie onBoard controller type.
+	it can 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;
+
+
+
+
+
+	//  ***********************************************************
+	//  DDDD   EEEEE  BBBB   U   U   GGGG       M   M   SSSS   GGGG
+	//  D   D  E      B   B  U   U  G           MM MM  S      G
+	//  D   D  EEE    BBBB   U   U  G           M M M   SSS   G
+	//  D   D  E      B   B  U   U  G   G       M   M      S  G   G
+	//  DDDD   EEEEE  BBBB    UUU    GGGG       M   M  SSSS    GGGG
+
+	// DEBUGGING CODE:
+	// As part of the D-FaLL-System we have defined a message type names"DebugMsg".
+	// By fill this message with data and publishing it you can display the data in
+	// real time using rpt plots. Instructions for using rqt plots can be found on
+	// the wiki of the D-FaLL-System repository
+
+	// Instantiate a local variable of type "DebugMsg", see the file "DebugMsg.msg"
+	// (located in the "msg" folder) to see the full structure of this message.
+	DebugMsg debugMsg;
+
+	// Fill the debugging message with the data provided by Vicon
+	debugMsg.vicon_x = request.ownCrazyflie.x;
+	debugMsg.vicon_y = request.ownCrazyflie.y;
+	debugMsg.vicon_z = request.ownCrazyflie.z;
+	debugMsg.vicon_roll = request.ownCrazyflie.roll;
+	debugMsg.vicon_pitch = request.ownCrazyflie.pitch;
+	debugMsg.vicon_yaw = request.ownCrazyflie.yaw;
+
+	// Fill in the debugging message with any other data you would like to display
+	// in real time. For example, it might be useful to display the thrust
+	// adjustment computed by the z-altitude controller.
+	// 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_10 = your_variable_name;
+
+	// Publish the "debugMsg"
+	m_debugPublisher.publish(debugMsg);
+
+	// An alternate debugging technique is to print out data directly to the
+	// command line from which this node was launched.
+
+	// An example of "printing out" the data from the "request" argument to the
+	// command line. This might be useful for debugging.
+	// 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("pitch: " << request.ownCrazyflie.pitch);
+	// 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]);
+
+	// 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);
+
+	// Return "true" to indicate that the control computation was performed successfully
+	return true;
+	}
+
+
+
+
+//    ------------------------------------------------------------------------------
+//    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
+//
+// This function WILL NEED TO BE edited for successful completion of the PPS exercise
+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
+//    ----------------------------------------------------------------------------------
+
+// This function DOES NEED TO BE edited for successful completion of
+// the exercise
+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
+//
+//     GGG   U   U  III        CCCC    A    L      L      BBBB     A     CCCC  K   K
+//    G   G  U   U   I        C       A A   L      L      B   B   A A   C      K  K
+//    G      U   U   I        C      A   A  L      L      BBBB   A   A  C      KKK
+//    G   G  U   U   I        C      AAAAA  L      L      B   B  AAAAA  C      K  K
+//     GGGG   UUU   III        CCCC  A   A  LLLLL  LLLLL  BBBB   A   A   CCCC  K   K
+//    ----------------------------------------------------------------------------------
+
+
+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
+				);
+		}
+	}
+}
+
+
+
+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 netwrok 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);
+}
+
+
+
+
+
+//    ----------------------------------------------------------------------------------
+//     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 CustomButton& commandReceived)
+{
+	// Extract the data from the message
+	int custom_button_index   = commandReceived.button_index;
+	float custom_command_code = commandReceived.command_code;
+
+	// 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("[DEFAULT CONTROLLER] Button 1 received in controller.");
+			// 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("[DEFAULT CONTROLLER] Button 2 received in controller.");
+			// 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("[DEFAULT CONTROLLER] Button 3 received in controller, with command code:" << custom_command_code );
+			// Code here to respond to custom button 3
+
+			break;
+		}
+
+		default:
+		{
+			// Let the user know that the command was not recognised
+			ROS_INFO_STREAM("[DEMO CONTROLLER] A button clicked command was received in the controller but not recognised, message.button_index = " << custom_button_index << ", and message.command_code = " << custom_command_code );
+			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
+//    ----------------------------------------------------------------------------------
+
+
+// This function DOES NOT NEED TO BE edited for successful completion
+// ofthe exercise
+void isReadyDefaultControllerYamlCallback(const IntWithHeader & msg)
+{
+	// Check whether the message is relevant
+	bool isRevelant = checkMessageHeader( m_agentID , msg.shouldCheckForID , 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("[DEFAULT CONTROLLER] Now fetching the DefaultController 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("[DEFAULT CONTROLLER] Now fetching the DefaultController YAML parameter values from this agent's coordinator.");
+				namespace_to_use = m_namespace_to_coordinator_parameter_service;
+				break;
+			}
+
+			default:
+			{
+				ROS_ERROR("[DEFAULT 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
+		fetchDefaultControllerYamlParameters(nodeHandle_to_use);
+	}
+}
+
+
+// This function CAN BE edited for successful completion of the
+// exercise, and the use of parameters fetched from the YAML file
+// is highly recommended to make tuning of your controller easier
+// and quicker.
+void fetchDefaultControllerYamlParameters(ros::NodeHandle& nodeHandle)
+{
+	// Here we load the parameters that are specified in the file:
+	// DefaultController.yaml
+
+	// Add the "DefaultController" namespace to the "nodeHandle"
+	ros::NodeHandle nodeHandle_for_paramaters(nodeHandle, "DefaultController");
+
+
+
+	// GET THE PARAMETERS:
+
+	// The mass of the crazyflie, in [grams]
+	yaml_cf_mass_in_grams = getParameterFloat(nodeHandle_for_paramaters , "mass");
+
+	// > The frequency at which the "computeControlOutput" function
+	//   is being called, as determined by the frequency at which
+	//   the Motion Caption (Vicon) system provides pose data, i.e.,
+	//   measurement of (x,y,z) position and (roll,pitch,yaw) attitude.
+	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);
+
+
+
+	// > DEBUGGING: Print out one of the parameters that was loaded to
+	//   debug if the fetching of parameters worked correctly
+	ROS_INFO_STREAM("[DEFAULT CONTROLLER] DEBUGGING: the fetched DefaultController/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("[DEFAULT CONTROLLER] DEBUGGING: thus the weight of this agent in [Newtons] = " << m_cf_weight_in_newtons);
+}
+
+
+
+
+
+//    ----------------------------------------------------------------------------------
+//    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
+//    ----------------------------------------------------------------------------------
+
+// This function DOES NOT NEED TO BE edited for successful completion of the PPS exercise
+int main(int argc, char* argv[]) {
+
+	// Starting the ROS-node
+	ros::init(argc, argv, "DefaultControllerService");
+
+	// 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 "DefaultControllerService" node
+	std::string m_namespace = ros::this_node::getNamespace();
+	ROS_INFO_STREAM("[DEFAULT CONTROLLER] ros::this_node::getNamespace() =  " << m_namespace);
+
+
+
+	// AGENT ID AND COORDINATOR ID
+
+	// 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
+	//   "PPSClient" node.
+	// > Thus, to get access to this "agentID" paremeter, we first
+	//   need to get a handle to the "PPSClient" node within which this
+	//   controller service is nested.
+
+
+	// Get the ID of the agent and its coordinator
+	bool isValid_IDs = getAgentIDandCoordIDfromClientNode( m_namespace + "/PPSClient" , &m_agentID , &m_coordID);
+
+	// Stall the node IDs are not valid
+	if ( !isValid_IDs )
+	{
+		ROS_ERROR("[DEFAULT CONTROLLER] Node NOT FUNCTIONING :-)");
+		ros::spin();
+	}
+	else
+	{
+		ROS_INFO_STREAM("[DEFAULT CONTROLLER] loaded agentID = " << m_agentID << ", and coordID = " << m_coordID);
+	}
+
+
+
+	// 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("[DEFAULT CONTROLLER] m_namespace_to_own_agent_parameter_service    =  " << m_namespace_to_own_agent_parameter_service);
+	ROS_INFO_STREAM("[DEFAULT 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(  "DefaultController", 1, isReadyDefaultControllerYamlCallback);
+	ros::Subscriber safeContoller_yamlReady_fromCoord = nodeHandle_to_coordinator_parameter_service.subscribe("DefaultController", 1, isReadyDefaultControllerYamlCallback);
+
+
+
+	// 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 = "DefaultController";
+	// Set for whom this applies to
+	loadYamlFromFilenameCall.request.stringWithHeader.shouldCheckForID = 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 "isReadyDefaultControllerYamlCallback" function
+		// will be called once the YAML file is loaded
+	}
+	else
+	{
+	// Inform the user
+		ROS_ERROR("[DEFAULT 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 "newSetpointRequestSubscriber" to
+	// be a "ros::Subscriber" type variable that subscribes to the
+	// "NewSetpointRequest" topic and calls the class function
+	// "newSetpointRequestCallback" 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("DefaultControllerService/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 "service" to be a "ros::ServiceServer" type
+	// variable that advertises the service called "DefaultController". 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
+	// that should be sent via the Crazyradio and requested from the Crazyflie, i.e.,
+	// this is where the "outer loop" controller function starts. When a request is made
+	// of this service the "calculateControlOutput" function is called.
+	ros::ServiceServer service = nodeHandle.advertiseService("DefaultController", 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("GUIButton", 1, customCommandReceivedCallback);
+
+	// Create a "ros::NodeHandle" type local variable "namespace_nodeHandle" that points
+	// to the name space of this node, i.e., "d_fall_pps" as specified by the line:
+	//     "using namespace d_fall_pps;"
+	// in the "DEFINES" section at the top of this file.
+	ros::NodeHandle namespace_nodeHandle(ros::this_node::getNamespace());
+
+	// Print out some information to the user.
+	ROS_INFO("[DEFAULT CONTROLLER] 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/pps_ws/src/d_fall_pps/src/nodes/ParameterService.cpp b/pps_ws/src/d_fall_pps/src/nodes/ParameterService.cpp
index 825f8108ea949cc30ea95be52f461b86650753f1..917e7fa042e3b64ec9ed398adba161f55edd4eab 100644
--- a/pps_ws/src/d_fall_pps/src/nodes/ParameterService.cpp
+++ b/pps_ws/src/d_fall_pps/src/nodes/ParameterService.cpp
@@ -74,170 +74,17 @@
 
 
 
-/*
-void requestLoadControllerYamlCallback(const std_msgs::Int32& msg)
+bool requestLoadYamlFilenameCallbackServiceCallback(LoadYamlFromFilename::Request &request, LoadYamlFromFilename::Response &response)
 {
-    // Extract from the "msg" for which controller the YAML
-    // parameters should be loaded
-    int controller_to_load_yaml = msg.data;
+    // Put the flying state into the response variable
+    requestLoadYamlFilenamePublisher.publish(request.stringWithHeader);
 
-    ROS_INFO_STREAM("[PARAMETER SERVICE] Received the message to load YAML parameters from file into cache");
+    // Put success into the response
+    response.data = 1;
 
-
-    // Instantiate a local varaible to confirm that something can actually be loaded
-    // from a YAML file
-    bool isValidToAttemptLoad = true;
-
-    // Instantiate a local variable for the string that will be passed to the "system"
-    std::string cmd;
-
-    // Get the abolute path to "d_fall_pps"
-    std::string d_fall_pps_path = ros::package::getPath("d_fall_pps");
-
-    // Switch between loading for the different controllers
-    //    ----------------------------------------
-    // FOR THE SAFE CONTROLLER
-    if (
-        ((controller_to_load_yaml==LOAD_YAML_SAFE_CONTROLLER_COORDINATOR) && (m_type==TYPE_COORDINATOR))
-        ||
-        ((controller_to_load_yaml==LOAD_YAML_SAFE_CONTROLLER_AGENT)       && (m_type==TYPE_AGENT))
-    )
-    {
-        // Re-load the parameters of the safe controller:
-        cmd = "rosparam load " + d_fall_pps_path + "/param/SafeController.yaml " + m_base_namespace + "/SafeController";
-    }
-    //    ----------------------------------------
-    // FOR THE DEMO CONTROLLER
-    else if (
-        ((controller_to_load_yaml==LOAD_YAML_DEMO_CONTROLLER_COORDINATOR) && (m_type==TYPE_COORDINATOR))
-        ||
-        ((controller_to_load_yaml==LOAD_YAML_DEMO_CONTROLLER_AGENT)       && (m_type==TYPE_AGENT))
-    )
-    {
-        // Re-load the parameters of the demo controller:
-        cmd = "rosparam load " + d_fall_pps_path + "/param/DemoController.yaml " + m_base_namespace + "/DemoController";
-    }
-    //    ----------------------------------------
-    // FOR THE STUDENT CONTROLLER
-    else if (
-        ((controller_to_load_yaml==LOAD_YAML_STUDENT_CONTROLLER_COORDINATOR) && (m_type==TYPE_COORDINATOR))
-        ||
-        ((controller_to_load_yaml==LOAD_YAML_STUDENT_CONTROLLER_AGENT)       && (m_type==TYPE_AGENT))
-    )
-    {
-        // Re-load the parameters of the demo controller:
-        cmd = "rosparam load " + d_fall_pps_path + "/param/StudentController.yaml " + m_base_namespace + "/StudentController";
-    }
-    //    ----------------------------------------
-    // FOR THE MPC CONTROLLER
-    else if (
-        ((controller_to_load_yaml==LOAD_YAML_MPC_CONTROLLER_COORDINATOR) && (m_type==TYPE_COORDINATOR))
-        ||
-        ((controller_to_load_yaml==LOAD_YAML_MPC_CONTROLLER_AGENT)       && (m_type==TYPE_AGENT))
-    )
-    {
-        // Re-load the parameters of the demo controller:
-        cmd = "rosparam load " + d_fall_pps_path + "/param/MpcController.yaml " + m_base_namespace + "/MpcController";
-    }
-    //    ----------------------------------------
-    // FOR THE REMOTE CONTROLLER
-    else if (
-        ((controller_to_load_yaml==LOAD_YAML_REMOTE_CONTROLLER_COORDINATOR) && (m_type==TYPE_COORDINATOR))
-        ||
-        ((controller_to_load_yaml==LOAD_YAML_REMOTE_CONTROLLER_AGENT)       && (m_type==TYPE_AGENT))
-    )
-    {
-        // Re-load the parameters of the demo controller:
-        cmd = "rosparam load " + d_fall_pps_path + "/param/RemoteController.yaml " + m_base_namespace + "/RemoteController";
-    }
-    //    ----------------------------------------
-    // FOR THE TUNING CONTROLLER
-    else if (
-        ((controller_to_load_yaml==LOAD_YAML_TUNING_CONTROLLER_COORDINATOR) && (m_type==TYPE_COORDINATOR))
-        ||
-        ((controller_to_load_yaml==LOAD_YAML_TUNING_CONTROLLER_AGENT)       && (m_type==TYPE_AGENT))
-    )
-    {
-        // Re-load the parameters of the demo controller:
-        cmd = "rosparam load " + d_fall_pps_path + "/param/TuningController.yaml " + m_base_namespace + "/TuningController";
-    }
-    //    ----------------------------------------
-    // FOR THE PICKER CONTROLLER
-    else if (
-        ((controller_to_load_yaml==LOAD_YAML_PICKER_CONTROLLER_COORDINATOR) && (m_type==TYPE_COORDINATOR))
-        ||
-        ((controller_to_load_yaml==LOAD_YAML_PICKER_CONTROLLER_AGENT)       && (m_type==TYPE_AGENT))
-    )
-    {
-        // Re-load the parameters of the demo controller:
-        cmd = "rosparam load " + d_fall_pps_path + "/param/PickerController.yaml " + m_base_namespace + "/PickerController";
-    }
-    else
-    {
-        // Let the user know that the command was not recognised
-        ROS_INFO_STREAM("[PARAMETER SERVICE] > Nothing to load for this parameter service with.");
-        ROS_INFO_STREAM("[PARAMETER SERVICE] > The message received has 'controller_to_load_yaml'   =  " << controller_to_load_yaml);
-        ROS_INFO_STREAM("[PARAMETER SERVICE] > And the type of this Parameter Service is 'm_type'  =  " << m_type);
-        // Set the boolean that prevents the fetch message from being sent
-        isValidToAttemptLoad = false;
-    }
-
-
-    // Only bother with ttempting to loaded the .yaml file, and subseuently send the "ready for fetch"
-    // message if something can actually be loaded from a YAML file
-    if (isValidToAttemptLoad)
-    {
-        // 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: " << d_fall_pps_path  << " The comand line string sent to the 'system' is: " << cmd );
-
-        // Re-load the parameters by pass the command line string via a "system" call
-        // > i.e., this replicates pasting this string in a new terminal window and pressing enter
-        system(cmd.c_str());
-
-        // Pause breifly to ensure that the yaml file is fully loaded
-        ros::Duration(0.5).sleep();
-
-        // Instantiate a local varaible to confirm that something was actually loaded from
-        // a YAML file
-        bool isReadyForFetch = true;
-    
-        // Instantiate a local variable for the fetch message
-        std_msgs::Int32 fetch_msg;
-        // Fill in the data of the fetch message
-        fetch_msg.data = controller_to_load_yaml;
-        // Fill in the data of the fetch message
-        // switch(controller_to_load_yaml)
-        // {
-        //     case (LOAD_YAML_SAFE_CONTROLLER_COORDINATOR):
-        //         fetch_msg.data = FETCH_YAML_SAFE_CONTROLLER_FROM_COORDINATOR;
-        //         break;
-        //     case (LOAD_YAML_DEMO_CONTROLLER_COORDINATOR):
-        //         fetch_msg.data = FETCH_YAML_DEMO_CONTROLLER_FROM_COORDINATOR;
-        //         break;
-        //     case (LOAD_YAML_SAFE_CONTROLLER_AGENT):
-        //         fetch_msg.data = FETCH_YAML_SAFE_CONTROLLER_FROM_OWN_AGENT;
-        //         break;
-        //     case (LOAD_YAML_DEMO_CONTROLLER_AGENT):
-        //         fetch_msg.data = FETCH_YAML_DEMO_CONTROLLER_FROM_OWN_AGENT;
-        //         break;
-        //     default:
-        //         // Let the user know that the command was not recognised
-        //         ROS_INFO("Unknown 'controller to load yaml' command, thus a 'ready to fetch' message will NOT be published.");
-        //         // Set the boolean that prevents the fetch message from being sent
-        //         isReadyForFetch = false;
-        //         break;
-        // }
-        // Send a message that the YAML parameter have been loaded and hence are
-        // ready to be fetched (i.e., using getparam())
-        if (isReadyForFetch)
-        {
-            controllerYamlReadyForFetchPublisher.publish(fetch_msg);
-        }
-    }
+    // Return
+    return true;
 }
-*/
-
-
 
 void requestLoadYamlFilenameCallback(const StringWithHeader& yaml_filename_to_load_with_header)
 {
@@ -487,6 +334,12 @@ int main(int argc, char* argv[])
     // Subscribe to the messages that request loading a yaml file
     ros::Subscriber requestLoadYamlFilenameSubscriber = nodeHandle.subscribe("requestLoadYamlFilename", 1, 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 getCurrentFlyingStateService = nodeHandle.advertiseService("requestLoadYamlFilename", requestLoadYamlFilenameCallbackServiceCallback);
+
     // Inform the user the this node is ready
     ROS_INFO("[PARAMETER SERVICE] Service ready :-)");
     // Spin as a single-thread node
diff --git a/pps_ws/src/d_fall_pps/src/nodes/StudentControllerService.cpp b/pps_ws/src/d_fall_pps/src/nodes/StudentControllerService.cpp
index d738c68816520804ceaced1e82c753d3dd0e77c4..12ba738ba34f59d59ecb38116acdfc5ac1bd9043 100644
--- a/pps_ws/src/d_fall_pps/src/nodes/StudentControllerService.cpp
+++ b/pps_ws/src/d_fall_pps/src/nodes/StudentControllerService.cpp
@@ -846,30 +846,38 @@ int main(int argc, char* argv[]) {
 
 	// 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 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
-	// message containing the filename of the *.yaml file, and
-	// then a message will be received on the above subscribers
+	// 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.
-
-	// Create a publisher for request the yaml load
-	// > created as a local variable
-	// > note importantly that the final argument is "true", this
-	//   enables "latching" on the connection. When a connection is 
-	//   latched, the last message published is saved and
-	//   automatically sent to any future subscribers that connect. 
-    ros::Publisher requestLoadYamlFilenamePublisher = nodeHandle_to_own_agent_parameter_service.advertise<StringWithHeader>("requestLoadYamlFilename", 1, true);
-	// Create a local variable for the message
-    StringWithHeader yaml_filename_msg;
-    // Specify the data
-    yaml_filename_msg.data = "StudentController";
-    // Set for whom this applies to
-    yaml_filename_msg.shouldCheckForID = false;
-    // Sleep to make the publisher known to ROS (in seconds)
-    //ros::Duration(1.0).sleep();
-    // Send the message
-    requestLoadYamlFilenamePublisher.publish(yaml_filename_msg);
+	// > 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 = "StudentController";
+	// Set for whom this applies to
+	loadYamlFromFilenameCall.request.stringWithHeader.shouldCheckForID = 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 "isReadyStudentControllerYamlCallback" function
+		// will be called once the YAML file is loaded
+	}
+	else
+	{
+	// Inform the user
+		ROS_ERROR("[STUDENT CONTROLLER] The request load yaml file service call failed.");
+	}
 
 
 
diff --git a/pps_ws/src/d_fall_pps/srv/LoadYamlFromFilename.srv b/pps_ws/src/d_fall_pps/srv/LoadYamlFromFilename.srv
new file mode 100644
index 0000000000000000000000000000000000000000..c3f841a95dd3a56131ad8f98aae09857281498db
--- /dev/null
+++ b/pps_ws/src/d_fall_pps/srv/LoadYamlFromFilename.srv
@@ -0,0 +1,3 @@
+StringWithHeader stringWithHeader
+---
+uint32 data