New version of quadcopter software written to OO principles

Dependencies:   mbed MODSERIAL filter mbed-rtos ConfigFile PID PPM FreeIMU_external_magnetometer TinyGPS

Files at this revision

API Documentation at this revision

Comitter:
joe4465
Date:
Wed Apr 01 11:19:21 2015 +0000
Parent:
1:ec3521d90369
Child:
3:4823d6750629
Commit message:
Altitude hold with 2 PID's working. Exported to offline compiler

Changed in this revision

BaseStation/BaseStation.cpp Show annotated file Show diff for this revision Revisions of this file
BaseStation/BaseStation.h Show annotated file Show diff for this revision Revisions of this file
ConfigFileWrapper/ConfigFile.lib Show diff for this revision Revisions of this file
ConfigFileWrapper/ConfigFileWrapper.cpp Show diff for this revision Revisions of this file
ConfigFileWrapper/ConfigFileWrapper.h Show diff for this revision Revisions of this file
FlightController/FlightController.cpp Show annotated file Show diff for this revision Revisions of this file
FlightController/FlightController.h Show annotated file Show diff for this revision Revisions of this file
FlightController/MotorMixer/Motor/Motor.cpp Show diff for this revision Revisions of this file
FlightController/MotorMixer/Motor/Motor.h Show diff for this revision Revisions of this file
FlightController/MotorMixer/MotorMixer.cpp Show annotated file Show diff for this revision Revisions of this file
FlightController/MotorMixer/MotorMixer.h Show annotated file Show diff for this revision Revisions of this file
FlightController/RateController/RateController.cpp Show annotated file Show diff for this revision Revisions of this file
FlightController/RateController/RateController.h Show annotated file Show diff for this revision Revisions of this file
FlightController/StabController/StabController.cpp Show annotated file Show diff for this revision Revisions of this file
FlightController/StabController/StabController.h Show annotated file Show diff for this revision Revisions of this file
Global.h Show diff for this revision Revisions of this file
Global/ConfigFileWrapper/ConfigFile.lib Show annotated file Show diff for this revision Revisions of this file
Global/ConfigFileWrapper/ConfigFileWrapper.cpp Show annotated file Show diff for this revision Revisions of this file
Global/ConfigFileWrapper/ConfigFileWrapper.h Show annotated file Show diff for this revision Revisions of this file
Global/Global.h Show annotated file Show diff for this revision Revisions of this file
Global/Kalman/Kalman.cpp Show annotated file Show diff for this revision Revisions of this file
Global/Kalman/Kalman.h Show annotated file Show diff for this revision Revisions of this file
Global/MODSERIAL.lib Show annotated file Show diff for this revision Revisions of this file
Global/PidWrapper/PID.lib Show annotated file Show diff for this revision Revisions of this file
Global/PidWrapper/PidWrapper.cpp Show annotated file Show diff for this revision Revisions of this file
Global/PidWrapper/PidWrapper.h Show annotated file Show diff for this revision Revisions of this file
Global/filter.lib Show annotated file Show diff for this revision Revisions of this file
Global/mbed-rtos.lib Show annotated file Show diff for this revision Revisions of this file
MODSERIAL.lib Show diff for this revision Revisions of this file
NavigationController/AltitudeController/AltitudeController.cpp Show annotated file Show diff for this revision Revisions of this file
NavigationController/AltitudeController/AltitudeController.h Show annotated file Show diff for this revision Revisions of this file
NavigationController/NavigationController.cpp Show annotated file Show diff for this revision Revisions of this file
NavigationController/NavigationController.h Show annotated file Show diff for this revision Revisions of this file
PidWrapper/PID.lib Show diff for this revision Revisions of this file
PidWrapper/PidWrapper.cpp Show diff for this revision Revisions of this file
PidWrapper/PidWrapper.h Show diff for this revision Revisions of this file
Rc/Ppm.lib Show annotated file Show diff for this revision Revisions of this file
Rc/Rc.cpp Show annotated file Show diff for this revision Revisions of this file
Rc/Rc.h Show annotated file Show diff for this revision Revisions of this file
Rc/filter.lib Show diff for this revision Revisions of this file
Sensors/Gps/Gps.cpp Show annotated file Show diff for this revision Revisions of this file
Sensors/Gps/Gps.h Show annotated file Show diff for this revision Revisions of this file
Sensors/Gps/TinyGPS.lib Show annotated file Show diff for this revision Revisions of this file
Sensors/Imu/FreeIMU_external_magnetometer.lib Show annotated file Show diff for this revision Revisions of this file
Sensors/Imu/Imu.cpp Show annotated file Show diff for this revision Revisions of this file
Sensors/Imu/Imu.h Show annotated file Show diff for this revision Revisions of this file
Sensors/LidarLite.lib Show diff for this revision Revisions of this file
Sensors/LidarLitePwm.lib Show annotated file Show diff for this revision Revisions of this file
Sensors/MaxbotixDriver.lib Show diff for this revision Revisions of this file
Sensors/Sensors.cpp Show annotated file Show diff for this revision Revisions of this file
Sensors/Sensors.h Show annotated file Show diff for this revision Revisions of this file
Status/Status.cpp Show annotated file Show diff for this revision Revisions of this file
Status/Status.h Show annotated file Show diff for this revision Revisions of this file
Status/StatusLights/StatusLights.cpp Show annotated file Show diff for this revision Revisions of this file
Status/StatusLights/StatusLights.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-rtos.lib Show diff for this revision Revisions of this file
--- a/BaseStation/BaseStation.cpp	Wed Mar 04 18:53:43 2015 +0000
+++ b/BaseStation/BaseStation.cpp	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,342 @@
+#include "BaseStation.h"
+
+BaseStation::BaseStation(Status& status, Rc& rc, Sensors& sensors, NavigationController& navigationController, FlightController& flightController, ConfigFileWrapper& configFileWrapper, PinName wirelessPinTx, PinName wirelessPinRx) : _status(status), _rc(rc), _sensors(sensors), _navigationController(navigationController), _flightController(flightController), _configFileWrapper(configFileWrapper)
+{
+    _wireless = new MODSERIAL(wirelessPinTx, wirelessPinRx);
+    _wireless->baud(57600);
+    _wirelessSerialRxPos = 0;
+    
+    _thread = new Thread(&BaseStation::threadStarter, this, osPriorityNormal);
+    DEBUG("Base Station initialised\r\n");
+}
+
+BaseStation::~BaseStation(){}
+
+void BaseStation::threadStarter(void const *p)
+{
+    BaseStation *instance = (BaseStation*)p;
+    instance->threadWorker();
+}
+
+void BaseStation::threadWorker()
+{   
+    while(true)
+    {
+        //Check comms mode and print correct data back to PC application
+        Status::BaseStationMode mode = _status.getBaseStationMode();
+        
+        if(mode == Status::MOTOR_POWER)
+        {
+            MotorMixer::MotorPower motorPower = _flightController.getMotorPower();
+            
+            _wireless->printf("<M1=%1.2f:M2=%1.2f:M3=%1.2f:M4=%1.2f>",
+            motorPower.motor1, motorPower.motor2, motorPower.motor3, motorPower.motor4);
+        }
+        else if (mode == Status::PID_OUTPUTS)
+        {
+            PidWrapper::PidOutput pidOutputs = _flightController.getPidOutputs();
+            
+            _wireless->printf("<YPID=%1.2f:PPID=%1.2f:RPID=%1.2f>",
+            pidOutputs.yaw, pidOutputs.pitch, pidOutputs.roll);
+        }
+        else if (mode == Status::IMU_OUTPUTS)
+        {
+            Imu::Rate rate = _sensors.getRate();
+            Imu::Angle angle = _sensors.getAngle();
+            
+            _wireless->printf("<SY=%1.2f:SP=%1.2f:SR=%1.2f:RY=%1.2f:RP=%1.2f:RR=%1.2f>",
+            angle.yaw, angle.pitch, angle.roll, rate.yaw, rate.pitch, rate.roll);
+        }
+        else if (mode == Status::STATUS)
+        {                        
+            _wireless->printf("<Batt=%f:Armed=%d:Init=%d:FlightMode=%d:State=%d:NavMode=%d>",
+            _status.getBatteryLevel(), _status.getArmed(), _status.getInitialised(), _status.getFlightMode(), _status.getState(), _status.getNavigationMode());
+        }
+        else if (mode == Status::RC)
+        {
+            Rc::MappedRc mappedRc = _rc.getMappedRc();
+            Rc::RawRc rawRc = _rc.getRawRc();
+            
+            _wireless->printf("<MRCY=%1.2f:MRCP=%1.2f:MRCR=%1.2f:MRCT=%1.2f:RRC1=%1.2f:RRC2=%1.2f:RRC3=%1.2f:RRC4=%1.2f:RRC5=%1.2f:RRC6=%1.2f:RRC7=%1.2f:RRC8=%1.2f>",
+            mappedRc.yaw, mappedRc.pitch, mappedRc.roll, mappedRc.throttle, rawRc.channel0, rawRc.channel1, rawRc.channel2, rawRc.channel3, rawRc.channel4, rawRc.channel5, rawRc.channel6, rawRc.channel7);
+        }
+        else if (mode == Status::PID_TUNING)
+        {
+            PidWrapper::FlightControllerPidParameters flightControllerPidParameters = _flightController.getPidParameters();
+            PidWrapper::NavigationControllerPidParameters navigationControllerPidParameters = _navigationController.getPidParameters();
+            _wireless->printf("<RYPIDP=%1.8f:RYPIDI=%1.8f:RYPIDD=%1.8f:RPPIDP=%1.8f:RPPIDI=%1.8f:RPPIDD=%1.8f:RRPIDP=%1.8f:RRPIDI=%1.8f:RRPIDD=%1.8f:SYPIDP=%1.8f:SYPIDI=%1.8f:SYPIDD=%1.8f:SPPIDP=%1.8f:SPPIDI=%1.8f:SPPIDD=%1.8f:SRPIDP=%1.8f:SRPIDI=%1.8f:SRPIDD=%1.8f:ARPIDP=%1.8f:ARPIDI=%1.8f:ARPIDD=%1.8f:ASPIDP=%1.8f:ASPIDI=%1.8f:ASPIDD=%1.8f>",
+            flightControllerPidParameters.yawRate.p, flightControllerPidParameters.yawRate.i, flightControllerPidParameters.yawRate.d, 
+            flightControllerPidParameters.pitchRate.p, flightControllerPidParameters.pitchRate.i, flightControllerPidParameters.pitchRate.d, 
+            flightControllerPidParameters.rollRate.p, flightControllerPidParameters.rollRate.i, flightControllerPidParameters.rollRate.d, 
+            flightControllerPidParameters.yawStab.p, flightControllerPidParameters.yawStab.i, flightControllerPidParameters.yawStab.d, 
+            flightControllerPidParameters.pitchStab.p, flightControllerPidParameters.pitchStab.i, flightControllerPidParameters.pitchStab.d, 
+            flightControllerPidParameters.rollStab.p, flightControllerPidParameters.rollStab.i, flightControllerPidParameters.rollStab.d,
+            navigationControllerPidParameters.altitudeRate.p, navigationControllerPidParameters.altitudeRate.i, navigationControllerPidParameters.altitudeRate.d,
+            navigationControllerPidParameters.altitudeStab.p, navigationControllerPidParameters.altitudeStab.i, navigationControllerPidParameters.altitudeStab.d);
+        }
+        else if (mode == Status::GPS)
+        {
+            Gps::Value gpsValues = _sensors.getGpsValues();
+            
+            _wireless->printf("<GLat=%1.6f:GLon=%1.6f:GAlt=%1.2f:GInit=%d>",
+            gpsValues.latitude, gpsValues.longitude, gpsValues.altitude, gpsValues.fix);
+        }/*
+        else if (mode == Status::ZERO)
+        {
+                            _wirelessSerial.printf("<ZY=%1.6f:ZP=%1.6f:ZR=%1.6f>",
+                _zeroValues[0], _zeroValues[1], _zeroValues[2]);
+                break;
+            
+        }*/
+        else if (mode == Status::RATE_TUNING)
+        {
+            if(_status.getFlightMode() == Status::RATE)
+            {
+                PidWrapper::RatePidState ratePidState = _flightController.getRatePidState();
+                
+                //Yaw set point, Yaw actual, Yaw PID output
+                //Pitch set point, Pitch actual, Pitch PID output
+                //Roll set point, Roll actual, Roll PID output
+                _wireless->printf("<RYPIDS=%1.2f:RYPIDP=%1.2f:RYPIDO=%1.2f:RPPIDS=%1.2f:RPPIDP=%1.2f:RPPIDO=%1.2f:RRPIDS=%1.2f:RRPIDP=%1.2f:RRPIDO=%1.2f>",
+                ratePidState.yawRate.setPoint, ratePidState.yawRate.processValue, ratePidState.yawRate.output, ratePidState.pitchRate.setPoint, ratePidState.pitchRate.processValue, ratePidState.pitchRate.output, ratePidState.rollRate.setPoint, ratePidState.rollRate.processValue, ratePidState.rollRate.output);
+            }
+            else if (_status.getFlightMode() == Status::STAB)
+            {
+                PidWrapper::StabPidState stabPidState = _flightController.getStabPidState();
+                
+                //Yaw set point, Yaw actual, Yaw PID output
+                //Pitch set point, Pitch actual, Pitch PID output
+                //Roll set point, Roll actual, Roll PID output
+                _wireless->printf("<RYPIDS=%1.2f:RYPIDP=%1.2f:RYPIDO=%1.2f:RPPIDS=%1.2f:RPPIDP=%1.2f:RPPIDO=%1.2f:RRPIDS=%1.2f:RRPIDP=%1.2f:RRPIDO=%1.2f>",
+                stabPidState.yawRate.setPoint, stabPidState.yawRate.processValue, stabPidState.yawRate.output, stabPidState.pitchRate.setPoint, stabPidState.pitchRate.processValue, stabPidState.pitchRate.output, stabPidState.rollRate.setPoint, stabPidState.rollRate.processValue, stabPidState.rollRate.output);
+            }   
+        }
+        else if (mode == Status::STAB_TUNING)
+        {
+            if(_status.getFlightMode() == Status::RATE)
+            {
+                //Yaw set point, Yaw actual, Yaw PID output
+                //Pitch set point, Pitch actual, Pitch PID output
+                //Roll set point, Roll actual, Roll PID output
+                _wireless->printf("<SYPIDS=0:SYPIDP=0:SYPIDO=0:SPPIDS=0:SPPIDP=0:SPPIDO=0:SRPIDS=0:SRPIDP=0:SRPIDO=0>");
+            }
+            else if (_status.getFlightMode() == Status::STAB)
+            {
+                PidWrapper::StabPidState stabPidState = _flightController.getStabPidState();
+                
+                //Yaw set point, Yaw actual, Yaw PID output
+                //Pitch set point, Pitch actual, Pitch PID output
+                //Roll set point, Roll actual, Roll PID output
+                _wireless->printf("<SYPIDS=%1.2f:SYPIDP=%1.2f:SYPIDO=%1.2f:SPPIDS=%1.2f:SPPIDP=%1.2f:SPPIDO=%1.2f:SRPIDS=%1.2f:SRPIDP=%1.2f:SRPIDO=%1.2f>",
+                stabPidState.yawStab.setPoint, stabPidState.yawStab.processValue, stabPidState.yawStab.output, stabPidState.pitchStab.setPoint, stabPidState.pitchStab.processValue, stabPidState.pitchStab.output, stabPidState.rollStab.setPoint, stabPidState.rollStab.processValue, stabPidState.rollStab.output);
+            } 
+        }
+        else if (mode == Status::ALTITUDE)
+        {
+            Sensors::Altitude altitude = _sensors.getAltitude();            
+            _wireless->printf("<GAlt=%1.2f:CAlt=%1.2f:BAlt=%1.2f:LAlt=%1.2f>",
+            altitude.gps, altitude.computed, altitude.barometer, altitude.lidar);
+        }
+        else if (mode == Status::VELOCITY)
+        {
+            //Sensors::Velocity velocity = _sensors.getVelocity();
+            //_wireless->printf("<AVelX=%1.2f:AVelY=%1.2f:AVelZ=%1.2f:LVel=%1.2f:CVelX=%1.2f:CVelY=%1.2f:CVelZ=%1.2f>",
+            //velocity.accelX, velocity.accelY, velocity.accelZ, velocity.lidar, velocity.computedX, velocity.computedY, velocity.computedZ);      
+        }
+        else if (mode == Status::ALTITUDE_STATUS)
+        {
+            NavigationController::SetPoint setPoints = _navigationController.getSetPoint();
+            Sensors::Altitude altitude = _sensors.getAltitude();
+            _wireless->printf("<ACR=%1.2f:AT=%1.2f:ATHR=%1.2f:LAlt=%1.2f>",
+            setPoints.climbRate, setPoints.targetAltitude, (setPoints.throttle * 100), altitude.computed);      
+        }
+        
+        //Check for wireless serial command
+        while (_wireless->readable() > 0)
+        {
+            int c = _wireless->getc();
+                                                
+            switch (c)
+            {
+                case 60: // 
+                    _wirelessSerialRxPos = 0;
+                    break;
+                
+                case 10: // LF
+                case 13: // CR
+                case 62: // >
+                    checkCommand();
+                    break;
+                    
+                default:
+                    _wirelessSerialBuffer[_wirelessSerialRxPos++] = c;
+                    if (_wirelessSerialRxPos > 200)
+                    {
+                        _wirelessSerialRxPos = 0;
+                    }
+                    break;
+            }
+        }
+        
+        Thread::wait(200);
+    }
+}
+
+void BaseStation::checkCommand()
+{
+    int length = _wirelessSerialRxPos;
+    _wirelessSerialBuffer[_wirelessSerialRxPos] = 0;
+    _wirelessSerialRxPos = 0;
+
+    if (length < 1)
+    {
+        return;
+    }
+    
+    char command = _wirelessSerialBuffer[0];
+    double value = 0;
+    if(length > 1)
+    {
+        value = atof((char*)&_wirelessSerialBuffer[2]);
+    }
+    
+    PidWrapper::FlightControllerPidParameters flightControllerPidParameters = _flightController.getPidParameters();
+    PidWrapper::NavigationControllerPidParameters navigationControllerPidParameters = _navigationController.getPidParameters();
+    
+    switch (command)
+    {
+        case 'a':
+            navigationControllerPidParameters.altitudeRate.p = value;
+            _navigationController.setAltitudeRatePidParameters(navigationControllerPidParameters.altitudeRate);
+            break;
+            
+        case 'b':
+            navigationControllerPidParameters.altitudeRate.i = value;
+            _navigationController.setAltitudeRatePidParameters(navigationControllerPidParameters.altitudeRate);
+            break;
+            
+        case 'c':
+            navigationControllerPidParameters.altitudeRate.d = value;
+            _navigationController.setAltitudeRatePidParameters(navigationControllerPidParameters.altitudeRate);
+            break;
+            
+        case 'd':
+            navigationControllerPidParameters.altitudeStab.p = value;
+            _navigationController.setAltitudeStabPidParameters(navigationControllerPidParameters.altitudeStab);
+            break;
+            
+        case 'e':
+            navigationControllerPidParameters.altitudeStab.i = value;
+            _navigationController.setAltitudeStabPidParameters(navigationControllerPidParameters.altitudeStab);
+            break;
+            
+        case 'f':
+            navigationControllerPidParameters.altitudeStab.d = value;
+            _navigationController.setAltitudeStabPidParameters(navigationControllerPidParameters.altitudeStab);
+            break;
+            
+        case 'g':
+            _sensors.zeroAccel();
+            break;
+            
+        //Set PID values
+        case 'h':
+            flightControllerPidParameters.yawRate.p = value;
+            _flightController.setYawRatePidParameters(flightControllerPidParameters.yawRate);
+            break;
+            
+        case 'i':
+            flightControllerPidParameters.yawRate.i = value;
+            _flightController.setYawRatePidParameters(flightControllerPidParameters.yawRate);
+            break;
+            
+        case 'j':
+            flightControllerPidParameters.yawRate.d = value;
+            _flightController.setYawRatePidParameters(flightControllerPidParameters.yawRate);
+            break;
+            
+        case 'k':
+            flightControllerPidParameters.pitchRate.p = value;
+            _flightController.setPitchRatePidParameters(flightControllerPidParameters.pitchRate);
+            break;
+            
+        case 'l':
+            flightControllerPidParameters.pitchRate.i = value;
+            _flightController.setPitchRatePidParameters(flightControllerPidParameters.pitchRate); 
+            break;
+            
+        case 'm':
+            flightControllerPidParameters.pitchRate.d = value;
+            _flightController.setPitchRatePidParameters(flightControllerPidParameters.pitchRate);
+            break;
+            
+        case 'n':
+            flightControllerPidParameters.rollRate.p = value;
+            _flightController.setRollRatePidParameters(flightControllerPidParameters.rollRate);            
+            break;
+            
+        case 'o':
+            flightControllerPidParameters.rollRate.i = value;
+            _flightController.setRollRatePidParameters(flightControllerPidParameters.rollRate);    
+            break;
+            
+        case 'p':
+            flightControllerPidParameters.rollRate.d = value;
+            _flightController.setRollRatePidParameters(flightControllerPidParameters.rollRate);    
+            break;
+            
+        case 'q':
+            flightControllerPidParameters.yawStab.p = value;
+            _flightController.setYawStabPidParameters(flightControllerPidParameters.yawStab);    
+            break;
+            
+        case 'r':
+            flightControllerPidParameters.yawStab.i = value;
+            _flightController.setYawStabPidParameters(flightControllerPidParameters.yawStab);   
+            break;
+            
+        case 's':
+            flightControllerPidParameters.yawStab.d = value;
+            _flightController.setYawStabPidParameters(flightControllerPidParameters.yawStab);   
+            break;
+            
+        case 't':
+            flightControllerPidParameters.pitchStab.p = value;
+            _flightController.setPitchStabPidParameters(flightControllerPidParameters.pitchStab);   
+            break;
+            
+        case 'u':
+            flightControllerPidParameters.pitchStab.i = value;
+            _flightController.setPitchStabPidParameters(flightControllerPidParameters.pitchStab); 
+            break;
+            
+        case 'v':
+            flightControllerPidParameters.pitchStab.d = value;
+            _flightController.setPitchStabPidParameters(flightControllerPidParameters.pitchStab); 
+            break;
+            
+        case 'w':
+            flightControllerPidParameters.rollStab.p = value;
+            _flightController.setRollStabPidParameters(flightControllerPidParameters.rollStab); 
+            break;
+            
+        case 'x':
+            flightControllerPidParameters.rollStab.i = value;
+            _flightController.setRollStabPidParameters(flightControllerPidParameters.rollStab);
+            break;
+            
+        case 'y':
+            flightControllerPidParameters.rollStab.d = value;
+            _flightController.setRollStabPidParameters(flightControllerPidParameters.rollStab);
+            break;
+            
+        case 'z':
+            _status.setBaseStationMode(static_cast<Status::BaseStationMode>(value));
+            break;
+            
+        default:
+            break;
+    }
+    
+    return;
+}
\ No newline at end of file
--- a/BaseStation/BaseStation.h	Wed Mar 04 18:53:43 2015 +0000
+++ b/BaseStation/BaseStation.h	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,37 @@
+#include "mbed.h"
+#include "Global.h"
+#include "rtos.h"
+#include "MODSERIAL.h"
+#include "Rc.h"
+#include "Sensors.h"
+#include "Status.h"
+#include "NavigationController.h"
+#include "FlightController.h"
+
+#ifndef BaseStation_H
+#define BaseStation_H
+
+class BaseStation                
+{
+  public:             
+    BaseStation(Status& status, Rc& rc, Sensors& sensors, NavigationController& navigationController, FlightController& flightController, ConfigFileWrapper& configFileWrapper, PinName wirelessPinTx, PinName wirelessPinRx);   
+    ~BaseStation();   
+    
+  private:
+    static void threadStarter(void const *p);
+    void threadWorker();
+    void checkCommand();
+    
+    Thread* _thread;
+    MODSERIAL* _wireless;
+    Status& _status;
+    Rc& _rc;
+    Sensors& _sensors;
+    NavigationController& _navigationController;
+    FlightController& _flightController;
+    ConfigFileWrapper& _configFileWrapper;
+    char _wirelessSerialBuffer[255];
+    int _wirelessSerialRxPos;
+};
+
+#endif
\ No newline at end of file
--- a/ConfigFileWrapper/ConfigFile.lib	Wed Mar 04 18:53:43 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/shintamainjp/code/ConfigFile/#f6ceafabe9f8
--- a/ConfigFileWrapper/ConfigFileWrapper.cpp	Wed Mar 04 18:53:43 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,161 +0,0 @@
-#include "ConfigFileWrapper.h"
-
-ConfigFileWrapper::ConfigFileWrapper(){}
-
-ConfigFileWrapper::~ConfigFileWrapper(){}
-
-bool PidWrapper::initialise()
-{
-    _str = new char[1024];
-    loadSettings();
-    
-    DEBUG("Config file wrapper initialised");
-    return true; 
-}
-
-pidWrapper::PidParameters ConfigFileWrapper::getYawRateParameters()
-{
-    return _yawRateParameters;
-}
-
-pidWrapper::PidParameters ConfigFileWrapper::getPitchRateParameters()
-{
-    return _pitchRateParameters;
-}
-
-pidWrapper::PidParameters ConfigFileWrapper::getRollRateParameters()
-{
-    return _rollRateParameters;
-}
-
-pidWrapper::PidParameters ConfigFileWrapper::getYawStabParameters()
-{
-    return _yawStabParameters;
-}
-
-pidWrapper::PidParameters ConfigFileWrapper::getPitchStabParameters()
-{
-    return _pitchStabParameters;
-}
-
-pidWrapper::PidParameters ConfigFileWrapper::getRollStabParameters()
-{
-    return _rollStabParameters;
-}
-
-bool ConfigFileWrapper::setYawRateParameters(pidWrapper::PidParameters)
-{
-    return true;
-}
-
-bool ConfigFileWrapper::setPitchRateParameters(pidWrapper::PidParameters)
-{
-    return true;
-}
-
-bool ConfigFileWrapper::setRollRateParameters(pidWrapper::PidParameters)
-{
-    return true;
-}
-
-bool ConfigFileWrapper::setYawStabParameters(pidWrapper::PidParameters)
-{
-    return true;
-}
-
-bool ConfigFileWrapper::setPitchStabParameters(pidWrapper::PidParameters)
-{
-    return true;
-}
-
-bool ConfigFileWrapper::setRollStabParameters(pidWrapper::PidParameters)
-{
-    return true;
-}
-
-void ConfigFileWrapper::convertToCharArray(float number)
-{
-    sprintf(_str, "%1.8f", number );  
-}
-
-void ConfigFileWrapper::convertToCharArray(int number)
-{
-    sprintf(_str, "%d", number );  
-}
-
-void ConfigFileWrapper::loadSettings()
-{
-    char value[BUFSIZ];
-    
-    //Read a configuration file from a mbed.
-    if (!_configFile.read("/local/config.cfg"))
-    {
-        DEBUG("Config file does not exist\n\r");
-    }
-    else
-    {    
-        //Get values
-        if (_configFile.getValue("yawRatePIDControllerP", &value[0], sizeof(value))) _yawRateParameters.p = atof(value);
-        else DEBUG("Failed to get value for yawRatePIDControllerP\n\r");
-        
-        if (_configFile.getValue("yawRatePIDControllerI", &value[0], sizeof(value))) _yawRateParameters.i = atof(value);
-        else DEBUG("Failed to get value for yawRatePIDControllerI\n\r");
-
-        if (_configFile.getValue("yawRatePIDControllerD", &value[0], sizeof(value))) _yawRateParameters.d = atof(value);
-        else DEBUG("Failed to get value for yawRatePIDControllerD\n\r");
-
-        if (_configFile.getValue("pitchRatePIDControllerP", &value[0], sizeof(value))) _pitchRateParameters.p = atof(value);
-        else DEBUG("Failed to get value for pitchRatePIDControllerP\n\r");
-
-        if (_configFile.getValue("pitchRatePIDControllerI", &value[0], sizeof(value))) _pitchRateParameters.i = atof(value);
-        else DEBUG("Failed to get value for pitchRatePIDControllerI\n\r");
-
-        if (_configFile.getValue("pitchRatePIDControllerD", &value[0], sizeof(value))) _pitchRateParameters.d = atof(value);
-        else DEBUG("Failed to get value for pitchRatePIDControllerD\n\r");
-
-        if (_configFile.getValue("rollRatePIDControllerP", &value[0], sizeof(value))) _rollRateParameters.p = atof(value);
-        else DEBUG("Failed to get value for rollRatePIDControllerP\n\r");
-
-        if (_configFile.getValue("rollRatePIDControllerI", &value[0], sizeof(value))) _rollRateParameters.i = atof(value);
-        else DEBUG("Failed to get value for rollRatePIDControllerI\n\r");
-
-        if (_configFile.getValue("rollRatePIDControllerD", &value[0], sizeof(value))) _rollRateParameters.d = atof(value);
-        else DEBUG("Failed to get value for rollRatePIDControllerD\n\r");
-
-        
-        if (_configFile.getValue("yawStabPIDControllerP", &value[0], sizeof(value))) _yawStabParameters.p = atof(value);
-        else DEBUG("Failed to get value for yawStabPIDControllerP\n\r");
- 
-        if (_configFile.getValue("yawStabPIDControllerI", &value[0], sizeof(value))) _yawStabParameters.i = atof(value);
-        else DEBUG("Failed to get value for yawStabPIDControllerI\n\r");
-
-        if (_configFile.getValue("yawStabPIDControllerD", &value[0], sizeof(value))) _yawStabParameters.d = atof(value);
-        else DEBUG("Failed to get value for yawStabPIDControllerD\n\r");
-
-        if (_configFile.getValue("pitchStabPIDControllerP", &value[0], sizeof(value))) _pitchStabParameters.p = atof(value);
-        else DEBUG("Failed to get value for pitchStabPIDControllerP\n\r");
-
-        if (_configFile.getValue("pitchStabPIDControllerI", &value[0], sizeof(value))) _pitchStabParameters.i = atof(value);
-        else DEBUG("Failed to get value for pitchStabPIDControllerI\n\r");
-
-        if (_configFile.getValue("pitchStabPIDControllerD", &value[0], sizeof(value))) _pitchStabParameters.d = atof(value);
-        else DEBUG("Failed to get value for pitchStabPIDControllerD\n\r");
-
-        if (_configFile.getValue("rollStabPIDControllerP", &value[0], sizeof(value))) _rollStabParameters.p = atof(value);
-        else DEBUG("Failed to get value for rollStabPIDControllerP\n\r");
-
-        if (_configFile.getValue("rollStabPIDControllerI", &value[0], sizeof(value))) _rollStabParameters.i = atof(value);
-        else DEBUG("Failed to get value for rollStabPIDControllerI\n\r");
-
-        if (_configFile.getValue("rollStabPIDControllerD", &value[0], sizeof(value))) _rollStabParameters.d = atof(value);
-        else DEBUG("Failed to get value for rollStabPIDControllerD\n\r");
-
-        /*if (_configFile.getValue("zeroPitch", &value[0], sizeof(value))) _zeroValues[1] = atof(value);
-        else DEBUG("Failed to get value for zero pitch\n\r");
-
-        if (_configFile.getValue("zeroRoll", &value[0], sizeof(value))) _zeroValues[2] = atof(value);
-        else printf("Failed to get value for zero roll\n\r");*/
-    }
-    
-    DEBUG("Finished loading settings from config file\n\r");
-}
--- a/ConfigFileWrapper/ConfigFileWrapper.h	Wed Mar 04 18:53:43 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-#include "mbed.h"
-#include "Global.h"
-#include "ConfigFile.h"
-#include "PidWrapper.h"
-
-#ifndef ConfigFileWrapper_H
-#define ConfigFileWrapper_H
-
-class ConfigFileWrapper                   // begin declaration of the class
-{
-  public:                    // begin public section
-    ConfigFileWrapper();    // constructor
-    ~ConfigFileWrapper();
-    
-    bool initialise();
-    pidWrapper::PidParameters getYawRateParameters();
-    pidWrapper::PidParameters getPitchRateParameters();
-    pidWrapper::PidParameters getRollRateParameters();
-    pidWrapper::PidParameters getYawStabParameters();
-    pidWrapper::PidParameters getPitchStabParameters();
-    pidWrapper::PidParameters getRollStabParameters();
-    
-    bool setYawRateParameters(pidWrapper::PidParameters);
-    bool setPitchRateParameters(pidWrapper::PidParameters);
-    bool setRollRateParameters(pidWrapper::PidParameters);
-    bool setYawStabParameters(pidWrapper::PidParameters);
-    bool setPitchStabParameters(pidWrapper::PidParameters);
-    bool setRollStabParameters(pidWrapper::PidParameters);
-    
-  private:
-    ConfigFile _configFile;
-    char* _str
-    pidWrapper::PidParameters _yawRateParameters;
-    pidWrapper::PidParameters _pitchRateParameters;
-    pidWrapper::PidParameters _rollRateParameters;
-    pidWrapper::PidParameters _yawStabParameters;
-    pidWrapper::PidParameters _pitchStabParameters;
-    pidWrapper::PidParameters _rollStabParameters;
-    void convertToCharArray(float number);
-    void convertToCharArray(int number);
-    void loadSettings();
-};
-
-#endif
\ No newline at end of file
--- a/FlightController/FlightController.cpp	Wed Mar 04 18:53:43 2015 +0000
+++ b/FlightController/FlightController.cpp	Wed Apr 01 11:19:21 2015 +0000
@@ -1,24 +1,21 @@
 #include "FlightController.h"
 
-FlightController::FlightController(){}
+FlightController::FlightController(Status& status, Sensors& sensors, NavigationController& navigationController, ConfigFileWrapper& configFileWrapper, PinName motor1, PinName motor2, PinName motor3, PinName motor4)
+    : _status(status), _sensors(sensors), _navigationController(navigationController), _configFileWrapper(configFileWrapper)
+{
+    _motorMixer = new MotorMixer(motor1, motor2, motor3, motor4);
+    _rateController = new RateController(_sensors, _navigationController, _configFileWrapper);
+    _stabController = new StabController(_sensors, _navigationController, _configFileWrapper);   
+
+    _rtosTimer = new RtosTimer(&FlightController::threadStarter, osTimerPeriodic, (void*)this);
+    int updateTime = (1.0 / (float)FLIGHT_CONTROLLER_FREQUENCY) * 1000;
+    _rtosTimer->start(updateTime);
+    
+    DEBUG("Flight controller initialised\r\n");
+}
 
 FlightController::~FlightController(){}
 
-bool FlightController::initialise(Status& status, Sensors& sensors, NavigationController& navigationController, PinName motor1, PinName motor2, PinName motor3, PinName motor4)
-{
-    _status = status;
-    
-    _motorMixer.initialise(motor1, motor2, motor3, motor4);
-    _rateController.initialise(sensors, navigationController);
-    _stabController.initialise(sensors, navigationController);
-   
-    _rtosTimer = new RtosTimer(&FlightController::threadStarter, osTimerPeriodic, (void *)0);
-    int updateTime = (1.0 / FLIGHT_CONTROLLER_FREQUENCY) * 1000;
-    _rtosTimer->start(updateTime);
-    DEBUG("Flight controller initialised");
-    return true; 
-}
-
 void FlightController::threadStarter(void const *p)
 {
     FlightController *instance = (FlightController*)p;
@@ -26,37 +23,123 @@
 }
 
 void FlightController::threadWorker()
-{
-    //Struct to hold PID outputs
-    PidWrapper::PidOutputs pidOutputs;
+{   
+    Status::FlightMode flightMode = _status.getFlightMode();
+    
+    _sensors.updateImu();
     
-    //Check state is valid
+    if(flightMode == Status::RATE)
+    {
+        //Rate mode  
+        _pidOutputs = _rateController->compute(); 
+    }
+    else if (flightMode == Status::STAB)
+    {
+        //Stab mode
+        _pidOutputs = _stabController->compute();  
+    }
+      
     Status::State state = _status.getState();
+    NavigationController::SetPoint setPoints = _navigationController.getSetPoint();
+    
     if(state == Status::MANUAL || state == Status::STABILISED || state == Status::AUTO)  
     {
-        //State valid
-        Status::FlightMode flightMode = _status.getFlightMode();
-        if(flightMode == Status::RATE)
-        {
-            //Rate mode  
-            pidOutputs = _rateController.compute(); 
-        }
-        else if (flightMode == Status::STAB)
-        {
-            //Stab mode
-            pidOutputs = _stabController.compute();    
-        }
-        else
-        {
-            //Invalid state
-            _status.setState(Status::ABORT);
-            return;
-        }  
-        
-        _motorMixer.computePower(pidOutputs, throttle);       
+        _motorMixer->computePower(_pidOutputs, setPoints.throttle);
+    }      
+    else if(state == Status::GROUND_READY) 
+    {
+        _motorMixer->setPower(MOTORS_ARMED);
+        _rateController->reset();
+        _stabController->reset(); 
+    }
+    else if(state == Status::STANDBY)
+    {
+        _motorMixer->setPower(MOTORS_OFF);
+        _rateController->reset();
+        _stabController->reset();
     }
-    //Set motors to armed if state is ground ready
-    else if (state == Status::GROUND_READY) _motorMixer.setPower(MOTORS_ARMED);
     //Disable motors if state is not valid
-    else _motorMixer.setPower(MOTORS_OFF);
+    else _motorMixer->setPower(MOTORS_OFF);
+}
+
+MotorMixer::MotorPower FlightController::getMotorPower()
+{
+    return _motorMixer->getMotorPower();
+}
+
+PidWrapper::PidOutput FlightController::getPidOutputs()
+{
+    return _pidOutputs;  
+}
+
+PidWrapper::FlightControllerPidParameters FlightController::getPidParameters()
+{
+    return _stabController->getPidParameters();
+}
+
+void FlightController::setYawStabPidParameters(PidWrapper::PidParameter pidParameters)
+{
+    _stabController->setYawStabPidParameters(pidParameters);
+    _configFileWrapper.setYawStabParameters(pidParameters); 
+    Status::State state = _status.getState(); 
+    saveSettings();
+}
+
+void FlightController::setPitchStabPidParameters(PidWrapper::PidParameter pidParameters)
+{
+    _stabController->setPitchStabPidParameters(pidParameters);
+    _configFileWrapper.setPitchStabParameters(pidParameters);
+    saveSettings();
+}
+
+void FlightController::setRollStabPidParameters(PidWrapper::PidParameter pidParameters)
+{
+    _stabController->setRollStabPidParameters(pidParameters);
+    _configFileWrapper.setRollStabParameters(pidParameters);
+    saveSettings();
 }
+
+void FlightController::setYawRatePidParameters(PidWrapper::PidParameter pidParameters)
+{
+    _stabController->setYawRatePidParameters(pidParameters);
+    _rateController->setYawRatePidParameters(pidParameters);
+    _configFileWrapper.setYawRateParameters(pidParameters);
+    saveSettings();
+}
+
+void FlightController::setPitchRatePidParameters(PidWrapper::PidParameter pidParameters)
+{
+    _stabController->setPitchRatePidParameters(pidParameters);
+    _rateController->setPitchRatePidParameters(pidParameters);
+    _configFileWrapper.setPitchRateParameters(pidParameters);
+    saveSettings();
+}
+
+void FlightController::setRollRatePidParameters(PidWrapper::PidParameter pidParameters)
+{
+    _stabController->setRollRatePidParameters(pidParameters);
+    _rateController->setRollRatePidParameters(pidParameters);
+    _configFileWrapper.setRollRateParameters(pidParameters);
+    saveSettings();
+}
+
+void FlightController::saveSettings()
+{
+    Status::State state = _status.getState(); 
+    if(state == Status::STANDBY || state == Status::PREFLIGHT)
+    {
+        _sensors.enable(false);
+        _configFileWrapper.saveSettings();
+        _sensors.enable(true);
+    }   
+}
+
+PidWrapper::RatePidState FlightController::getRatePidState()
+{
+    return _rateController->getRatePidState();
+}
+
+PidWrapper::StabPidState FlightController::getStabPidState()
+{
+    return _stabController->getStabPidState();
+}
\ No newline at end of file
--- a/FlightController/FlightController.h	Wed Mar 04 18:53:43 2015 +0000
+++ b/FlightController/FlightController.h	Wed Apr 01 11:19:21 2015 +0000
@@ -6,6 +6,7 @@
 #include "PidWrapper.h"
 #include "RateController.h"
 #include "StabController.h"
+#include "ConfigFileWrapper.h"
 
 #ifndef FlightController_H
 #define FlightController_H
@@ -13,26 +14,35 @@
 class FlightController               
 {
   public:                  
-    FlightController(); 
+    FlightController(Status& status, Sensors& sensors, NavigationController& navigationController, ConfigFileWrapper& configFileWrapper, PinName motor1, PinName motor2, PinName motor3, PinName motor4); 
     ~FlightController();
     
-    bool initialise(Status& status, Sensors& sensors, NavigationController& navigationController, PinName motor1, PinName motor2, PinName motor3, PinName motor4);
-    PidWrapper::PidValues getyawRatePID();
-    PidWrapper::PidValues getPitchRatePID();
-    PidWrapper::PidValues getRollRatePID();
-    PidWrapper::PidValues getyawStabPID();
-    PidWrapper::PidValues getPitchStabPID();
-    PidWrapper::PidValues getRollStabPID();
     MotorMixer::MotorPower getMotorPower();
+    PidWrapper::PidOutput getPidOutputs();    
+    PidWrapper::FlightControllerPidParameters getPidParameters();
+    void setYawStabPidParameters(PidWrapper::PidParameter pidParameters);
+    void setPitchStabPidParameters(PidWrapper::PidParameter pidParameters);
+    void setRollStabPidParameters(PidWrapper::PidParameter pidParameters);
+    void setYawRatePidParameters(PidWrapper::PidParameter pidParameters);
+    void setPitchRatePidParameters(PidWrapper::PidParameter pidParameters);
+    void setRollRatePidParameters(PidWrapper::PidParameter pidParameters);
+    PidWrapper::RatePidState getRatePidState();
+    PidWrapper::StabPidState getStabPidState();
     
   private:
     static void threadStarter(void const *p);
     void threadWorker();
     RtosTimer* _rtosTimer;
-    Status _status;
-    MotorMixer _motorMixer;
-    RateController _rateController;
-    StabController _stabController;
+    RateController* _rateController;
+    StabController* _stabController;
+    void saveSettings();
+    Status& _status;
+    Sensors& _sensors;
+    NavigationController& _navigationController;
+    ConfigFileWrapper& _configFileWrapper;
+    MotorMixer* _motorMixer;
+    
+    PidWrapper::PidOutput _pidOutputs;
 };
 
 #endif
\ No newline at end of file
--- a/FlightController/MotorMixer/MotorMixer.cpp	Wed Mar 04 18:53:43 2015 +0000
+++ b/FlightController/MotorMixer/MotorMixer.cpp	Wed Apr 01 11:19:21 2015 +0000
@@ -1,83 +1,111 @@
 #include "MotorMixer.h"
 
-MotorMixer::MotorMixer(){}
-
-MotorMixer::~MotorMixer(){}
-
-bool MotorMixer::initialise(PinName motor1, PinName motor2, PinName motor3, PinName motor4)
-{
+MotorMixer::MotorMixer(PinName motor1, PinName motor2, PinName motor3, PinName motor4)
+{   
+    _motorPower = MotorPower();
+    
     _motor1 = new PwmOut(motor1);
     _motor2 = new PwmOut(motor2);
     _motor3 = new PwmOut(motor3);
     _motor4 = new PwmOut(motor4);
     
-    //Set frequency
-    float period = 1.0 / FLIGHT_CONTROLLER_FREQUENCY;
+    //Set period
+    double period = 1.0 / FLIGHT_CONTROLLER_FREQUENCY;
     _motor1->period(period);
     _motor2->period(period);
     _motor3->period(period);
     _motor4->period(period);
     
     //Disable
-    _motor1 = MOTORS_OFF;
-    _motor2 = MOTORS_OFF;
-    _motor2 = MOTORS_OFF;
-    _motor2 = MOTORS_OFF;
+    setPower(MOTORS_OFF);
     
-    DEBUG("Motor power initialised");
-    return true; 
+    DEBUG("Motor power initialised\r\n");  
 }
 
-void MotorMixer::computePower(PidWrapper::PidOutputs pidOutputs, float throttle)
-{
+MotorMixer::~MotorMixer(){}
+
+void MotorMixer::computePower(PidWrapper::PidOutput pidOutput, double throttle)
+{    
     //Calculate base power to apply from throttle - returns 1060 at min, 1860 at max
-    float basePower = MOTORS_MIN + (throttle * 800);
+    double basePower = MOTORS_MIN + (throttle * 800);
+    
+    MotorPower motorPower = MotorPower();
     
     //Map motor power - each PID returns -100 <-> 100
-    _motorPower.motor1 = basePower + pidOutputs.pitch + pidOutputs.roll + pidOutputs.yaw;
-    _motorPower.motor2 = basePower + pidOutputs.pitch - pidOutputs.roll - pidOutputs.yaw;
-    _motorPower.motor3 = basePower - pidOutputs.pitch - pidOutputs.roll + pidOutputs.yaw;
-    _motorPower.motor4 = basePower - pidOutputs.pitch + pidOutputs.roll - pidOutputs.yaw;
+    motorPower.motor1 = basePower + pidOutput.pitch + pidOutput.roll + pidOutput.yaw;
+    motorPower.motor2 = basePower + pidOutput.pitch - pidOutput.roll - pidOutput.yaw;
+    motorPower.motor3 = basePower - pidOutput.pitch - pidOutput.roll + pidOutput.yaw;
+    motorPower.motor4 = basePower - pidOutput.pitch + pidOutput.roll - pidOutput.yaw;
     
     //Specify intial motor power limits
-    float motorFix = 0;
-    float motorMin = _motorPower.motor1;
-    float motorMax = _motorPower.motor1;
+    double motorFix = 0;
+    double motorMin = motorPower.motor1;
+    double motorMax = motorPower.motor1;
     
     //Check motor power is within limits - if not add/remove constant to all motors to keep motor ratio the same
-    if(_motorPower.motor1 < motorMin) motorMin = _motorPower.motor1;
-    if(_motorPower.motor1 > motorMax) motorMax = _motorPower.motor1;
-    if(_motorPower.motor2 < motorMin) motorMin = _motorPower.motor2;
-    if(_motorPower.motor2 > motorMax) motorMax = _motorPower.motor2;
-    if(_motorPower.motor3 < motorMin) motorMin = _motorPower.motor3;
-    if(_motorPower.motor3 > motorMax) motorMax = _motorPower.motor3;
-    if(_motorPower.motor4 < motorMin) motorMin = _motorPower.motor4;
-    if(_motorPower.motor4 > motorMax) motorMax = _motorPower.motor4;
+    if(motorPower.motor1 < motorMin) motorMin = motorPower.motor1;
+    if(motorPower.motor1 > motorMax) motorMax = motorPower.motor1;
+    if(motorPower.motor2 < motorMin) motorMin = motorPower.motor2;
+    if(motorPower.motor2 > motorMax) motorMax = motorPower.motor2;
+    if(motorPower.motor3 < motorMin) motorMin = motorPower.motor3;
+    if(motorPower.motor3 > motorMax) motorMax = motorPower.motor3;
+    if(motorPower.motor4 < motorMin) motorMin = motorPower.motor4;
+    if(motorPower.motor4 > motorMax) motorMax = motorPower.motor4;
         
     //Check if min or max is outside of the limits
     if(motorMin < MOTORS_MIN) motorFix = MOTORS_MIN - motorMin;
     else if(motorMax > MOTORS_MAX) motorFix = MOTORS_MAX - motorMax;
     
     //Add/remove constant
-    _motorPower.motor1 += motorFix;
-    _motorPower.motor2 += motorFix;
-    _motorPower.motor3 += motorFix;
-    _motorPower.motor4 += motorFix;
+    motorPower.motor1 += motorFix;
+    motorPower.motor2 += motorFix;
+    motorPower.motor3 += motorFix;
+    motorPower.motor4 += motorFix;
+    
+    //Set motor power
+    setPower(motorPower);
+}
+
+void MotorMixer::computePower(double throttle)
+{    
+    //Calculate base power to apply from throttle - returns 1060 at min, 1860 at max
+    double basePower = MOTORS_MIN + (throttle * 800);
+    
+    MotorPower motorPower = MotorPower();
+    motorPower.motor1 = basePower;
+    motorPower.motor2 = basePower;
+    motorPower.motor3 = basePower;
+    motorPower.motor4 = basePower;
+    
+    //Set motor power
+    setPower(motorPower);
 }
 
-void MotorMixer::setPower(float motor1Power, float motor2Power, float motor3Power, float motor4Power)
+void MotorMixer::setPower(double motor1Power, double motor2Power, double motor3Power, double motor4Power)
 {
-    _motor1->pulsewidth_us(motor1Power);
-    _motor2->pulsewidth_us(motor2Power);
-    _motor3->pulsewidth_us(motor3Power);
-    _motor4->pulsewidth_us(motor4Power);
+    _motorPower.motor1 = motor1Power;
+    _motorPower.motor2 = motor2Power;
+    _motorPower.motor3 = motor3Power;
+    _motorPower.motor4 = motor4Power;
+    
+    #ifdef MOTORS_ENABLED
+        _motor1->pulsewidth_us(motor1Power);
+        _motor2->pulsewidth_us(motor2Power);
+        _motor3->pulsewidth_us(motor3Power);
+        _motor4->pulsewidth_us(motor4Power);
+    #endif
 }
 
-void MotorMixer::setPower(float motorPower)
+void MotorMixer::setPower(double motorPower)
 {
     setPower(motorPower, motorPower, motorPower, motorPower);
 }
 
+void MotorMixer::setPower(MotorMixer::MotorPower motorPower)
+{
+    setPower(motorPower.motor1, motorPower.motor2, motorPower.motor3, motorPower.motor4);
+}
+
 MotorMixer::MotorPower MotorMixer::getMotorPower()
 {
     return _motorPower;
--- a/FlightController/MotorMixer/MotorMixer.h	Wed Mar 04 18:53:43 2015 +0000
+++ b/FlightController/MotorMixer/MotorMixer.h	Wed Apr 01 11:19:21 2015 +0000
@@ -1,6 +1,7 @@
 #include "mbed.h"
 #include "Global.h"
 #include "PidWrapper.h"
+#include "NavigationController.h"
 
 #ifndef MotorMixer_H
 #define MotorMixer_H
@@ -8,21 +9,22 @@
 class MotorMixer
 {
   public:                 
-    MotorMixer();   
+    MotorMixer(PinName motor1, PinName motor2, PinName motor3, PinName motor4);   
     ~MotorMixer();
     
     struct MotorPower
     {
-       float motor1;
-       float motor2;
-       float motor3;
-       float motor4;
+       double motor1;
+       double motor2;
+       double motor3;
+       double motor4;
     };
     
-    bool initialise(PinName motor1, PinName motor2, PinName motor3, PinName motor4);
-    void computePower(PidWrapper::PidOutputs pidOutputs, float throttle);
-    void setPower(float motorPower);
-    void setPower(float motor1Power, float motor2Power, float motor3Power, float motor4Power);
+    void computePower(PidWrapper::PidOutput pidOutput, double throttle);
+    void computePower(double throttle);
+    void setPower(double motorPower);
+    void setPower(double motor1Power, double motor2Power, double motor3Power, double motor4Power);
+    void setPower(MotorMixer::MotorPower motorPower);
     MotorPower getMotorPower();
     
   private:
--- a/FlightController/RateController/RateController.cpp	Wed Mar 04 18:53:43 2015 +0000
+++ b/FlightController/RateController/RateController.cpp	Wed Apr 01 11:19:21 2015 +0000
@@ -1,39 +1,74 @@
 #include "RateController.h"
 
-RateController::RateController(){}
+RateController::RateController(Sensors& sensors, NavigationController& navigationController, ConfigFileWrapper& configFileWrapper) : _sensors(sensors), _navigationController(navigationController), _configFileWrapper(configFileWrapper)
+{
+    float updateTime = 1.0 / (float)FLIGHT_CONTROLLER_FREQUENCY;
+    _yawRatePidController.initialise(_configFileWrapper.getYawRateParameters(), IMU_YAW_RATE_MIN, IMU_YAW_RATE_MAX, RATE_PID_CONTROLLER_OUTPUT_MIN, RATE_PID_CONTROLLER_OUTPUT_MAX, updateTime);
+    _pitchRatePidController.initialise(_configFileWrapper.getPitchRateParameters(), IMU_PITCH_RATE_MIN, IMU_PITCH_RATE_MAX, RATE_PID_CONTROLLER_OUTPUT_MIN, RATE_PID_CONTROLLER_OUTPUT_MAX, updateTime);
+    _rollRatePidController.initialise(_configFileWrapper.getRollRateParameters(), IMU_ROLL_RATE_MIN, IMU_ROLL_RATE_MAX, RATE_PID_CONTROLLER_OUTPUT_MIN, RATE_PID_CONTROLLER_OUTPUT_MAX, updateTime);
+    
+    DEBUG("Rate controller initialised\r\n");
+}
 
 RateController::~RateController(){}
 
-bool RateController::initialise(Sensors& sensors, NavigationController& navigationController)
-{
-    _sensors = sensors;
-    _navigationController = navigationController;
+PidWrapper::PidOutput RateController::compute()
+{   
+    _setPoints = _navigationController.getSetPoint();
+    _rate = _sensors.getRate();
     
-    ConfigFileWrapper configFileWrapper = new ConfigFileWrapper();
-    configFileWrapper.initialise();
-    
-    _yawRatePidController.initialise(configFileWrapper.getYawRateParameters, IMU_YAW_RATE_MIN, IMU_YAW_RATE_MAX, RATE_PID_CONTROLLER_OUTPUT_MIN, RATE_PID_CONTROLLER_OUTPUT_MAX);
-    _pitchRatePidController.initialise(configFileWrapper.getPitchRateParameters, IMU_PITCH_RATE_MIN, IMU_PITCH_RATE_MAX, RATE_PID_CONTROLLER_OUTPUT_MIN, RATE_PID_CONTROLLER_OUTPUT_MAX);
-    _rollRatePidController.initialise(configFileWrapper.getRollRateParameters, IMU_ROLL_RATE_MIN, IMU_ROLL_RATE_MAX, RATE_PID_CONTROLLER_OUTPUT_MIN, RATE_PID_CONTROLLER_OUTPUT_MAX);
+    _pidOutputs.yaw = _yawRatePidController.compute(_setPoints.yaw, _rate.yaw);
+    _pidOutputs.pitch = _pitchRatePidController.compute(_setPoints.pitch, _rate.pitch);
+    _pidOutputs.roll = _rollRatePidController.compute(_setPoints.roll, _rate.roll);
+
+    return _pidOutputs;
+}
 
-    DEBUG("Rate controller initialised");
-    return true; 
+void RateController::reset()
+{
+    _yawRatePidController.reset();
+    _pitchRatePidController.reset();
+    _rollRatePidController.reset();
+}
+
+
+void RateController::setYawRatePidParameters(PidWrapper::PidParameter pidParameters)
+{
+    _yawRatePidController.setPidParameters(pidParameters);
+}
+
+void RateController::setPitchRatePidParameters(PidWrapper::PidParameter pidParameters)
+{
+    _pitchRatePidController.setPidParameters(pidParameters);
 }
 
-PidWrapper::PidOutputs RateController::compute()
+void RateController::setRollRatePidParameters(PidWrapper::PidParameter pidParameters)
 {
-    //Update rate PID process value with gyro rate
-    _yawRatePIDController->setProcessValue(_gyroRate[0]);
-    _pitchRatePIDController->setProcessValue(_gyroRate[1]);
-    _rollRatePIDController->setProcessValue(_gyroRate[2]);
+    _rollRatePidController.setPidParameters(pidParameters);
+}
+
+PidWrapper::RatePidState RateController::getRatePidState()
+{
+    PidWrapper::RatePidState ratePidState;
+    PidWrapper::PidState yawRatePidState;
+    PidWrapper::PidState pitchRatePidState;
+    PidWrapper::PidState rollRatePidState;
     
-    //Update rate PID set point with desired rate from RC
-    _yawRatePIDController->setSetPoint(_rcMappedCommands[0]);
-    _pitchRatePIDController->setSetPoint(_rcMappedCommands[1]);
-    _rollRatePIDController->setSetPoint(_rcMappedCommands[2]);
+    yawRatePidState.setPoint = _setPoints.yaw;
+    yawRatePidState.processValue = _rate.yaw;
+    yawRatePidState.output = _pidOutputs.yaw;
+    
+    pitchRatePidState.setPoint = _setPoints.pitch;
+    pitchRatePidState.processValue = _rate.pitch;
+    pitchRatePidState.output = _pidOutputs.pitch;
     
-    //Compute rate PID outputs
-    _ratePIDControllerOutputs[0] = _yawRatePIDController->compute();
-    _ratePIDControllerOutputs[1] = _pitchRatePIDController->compute();
-    _ratePIDControllerOutputs[2] = _rollRatePIDController->compute();
+    rollRatePidState.setPoint = _setPoints.roll;
+    rollRatePidState.processValue = _rate.roll;
+    rollRatePidState.output = _pidOutputs.roll;
+    
+    ratePidState.yawRate = yawRatePidState;
+    ratePidState.pitchRate = pitchRatePidState;
+    ratePidState.rollRate = rollRatePidState;
+    
+    return ratePidState;
 }
\ No newline at end of file
--- a/FlightController/RateController/RateController.h	Wed Mar 04 18:53:43 2015 +0000
+++ b/FlightController/RateController/RateController.h	Wed Apr 01 11:19:21 2015 +0000
@@ -2,6 +2,7 @@
 #include "Global.h"
 #include "PidWrapper.h"
 #include "ConfigFileWrapper.h"
+#include "NavigationController.h"
 
 #ifndef RateController_H
 #define RateController_H
@@ -9,18 +10,27 @@
 class RateController               
 {
   public:                  
-    RateController(); 
+    RateController(Sensors& sensors, NavigationController& navigationController, ConfigFileWrapper& configFileWrapper); 
     ~RateController();
     
-    bool initialise(Sensors& sensors, NavigationController& navigationController);
-    PidWrapper::PidOutputs compute();
+    PidWrapper::PidOutput compute();
+    void reset();
+    void setYawRatePidParameters(PidWrapper::PidParameter pidParameters);
+    void setPitchRatePidParameters(PidWrapper::PidParameter pidParameters);
+    void setRollRatePidParameters(PidWrapper::PidParameter pidParameters);
+    PidWrapper::RatePidState getRatePidState();
     
   private:
-    Sensors _sensors;
-    NavigationController _navigationController;
-    PidWrapper _yawRatePIDController;
-    PidWrapper _pitchRatePIDController;
-    PidWrapper _rollRatePIDController;
+    Sensors& _sensors;
+    NavigationController& _navigationController;
+    ConfigFileWrapper& _configFileWrapper;
+    PidWrapper _yawRatePidController;
+    PidWrapper _pitchRatePidController;
+    PidWrapper _rollRatePidController;
+    NavigationController::SetPoint _setPoints;
+    Imu::Rate _rate;
+    Imu::Angle _angle;
+    PidWrapper::PidOutput _pidOutputs;
 };
 
 #endif
\ No newline at end of file
--- a/FlightController/StabController/StabController.cpp	Wed Mar 04 18:53:43 2015 +0000
+++ b/FlightController/StabController/StabController.cpp	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,133 @@
+#include "StabController.h"
+
+StabController::StabController(Sensors& sensors, NavigationController& navigationController, ConfigFileWrapper& configFileWrapper) : _sensors(sensors), _navigationController(navigationController), _configFileWrapper(configFileWrapper)
+{
+    float updateTime = 1.0 / (float)FLIGHT_CONTROLLER_FREQUENCY;
+    _yawRatePidController.initialise(_configFileWrapper.getYawRateParameters(), IMU_YAW_RATE_MIN, IMU_YAW_RATE_MAX, RATE_PID_CONTROLLER_OUTPUT_MIN, RATE_PID_CONTROLLER_OUTPUT_MAX, updateTime);
+    _pitchRatePidController.initialise(_configFileWrapper.getPitchRateParameters(), IMU_PITCH_RATE_MIN, IMU_PITCH_RATE_MAX, RATE_PID_CONTROLLER_OUTPUT_MIN, RATE_PID_CONTROLLER_OUTPUT_MAX, updateTime);
+    _rollRatePidController.initialise(_configFileWrapper.getRollRateParameters(), IMU_ROLL_RATE_MIN, IMU_ROLL_RATE_MAX, RATE_PID_CONTROLLER_OUTPUT_MIN, RATE_PID_CONTROLLER_OUTPUT_MAX, updateTime);
+    _yawStabPidController.initialise(_configFileWrapper.getYawStabParameters(), IMU_YAW_ANGLE_MIN, IMU_YAW_ANGLE_MAX, IMU_YAW_RATE_MIN, IMU_YAW_RATE_MAX, updateTime);
+    _pitchStabPidController.initialise(_configFileWrapper.getPitchStabParameters(), IMU_PITCH_ANGLE_MIN, IMU_PITCH_ANGLE_MAX, IMU_PITCH_RATE_MIN, IMU_PITCH_RATE_MAX, updateTime);
+    _rollStabPidController.initialise(_configFileWrapper.getRollStabParameters(), IMU_ROLL_ANGLE_MIN, IMU_ROLL_ANGLE_MAX, IMU_ROLL_RATE_MIN, IMU_ROLL_RATE_MAX, updateTime);
+    
+    DEBUG("Stab controller initialised\r\n");
+}
+
+StabController::~StabController(){}
+
+PidWrapper::PidOutput StabController::compute()
+{   
+    _setPoints = _navigationController.getSetPoint();
+    _angle = _sensors.getAngle();
+    _rate = _sensors.getRate();   
+        
+    //_stabPidOutputs.yaw = _yawStabPidController.compute(_setPoints.yawTarget, _angle.yaw);
+    _stabPidOutputs.yaw = _yawStabPidController.compute(_setPoints.yawDifference, 0);
+    _stabPidOutputs.pitch = _pitchStabPidController.compute(_setPoints.pitch, _angle.pitch);
+    _stabPidOutputs.roll = _rollStabPidController.compute(_setPoints.roll, _angle.roll);
+
+    //If pilot commanding yaw
+    if(abs(_setPoints.yaw) >= 5) _stabPidOutputs.yaw = _setPoints.yaw;  //Feed to rate PID (overwriting stab PID output)
+    
+    _ratePidOutputs.yaw = _yawRatePidController.compute(_stabPidOutputs.yaw, _rate.yaw);
+    _ratePidOutputs.pitch = _pitchRatePidController.compute(_stabPidOutputs.pitch, _rate.pitch);
+    _ratePidOutputs.roll = _rollRatePidController.compute(_stabPidOutputs.roll, _rate.roll);
+    
+    return _ratePidOutputs;
+}
+
+PidWrapper::FlightControllerPidParameters StabController::getPidParameters()
+{
+    PidWrapper::FlightControllerPidParameters allPidParameters;
+    allPidParameters.yawStab = _yawStabPidController.getPidParameters();
+    allPidParameters.pitchStab = _pitchStabPidController.getPidParameters();
+    allPidParameters.rollStab = _rollStabPidController.getPidParameters();
+    allPidParameters.yawRate = _yawRatePidController.getPidParameters();
+    allPidParameters.pitchRate = _pitchRatePidController.getPidParameters();
+    allPidParameters.rollRate = _rollRatePidController.getPidParameters();
+    return allPidParameters;
+}
+
+void StabController::reset()
+{
+    _yawRatePidController.reset();
+    _pitchRatePidController.reset();
+    _rollRatePidController.reset();
+    _yawStabPidController.reset();
+    _pitchStabPidController.reset();
+    _rollStabPidController.reset();
+}
+
+void StabController::setYawStabPidParameters(PidWrapper::PidParameter pidParameters)
+{
+    _yawStabPidController.setPidParameters(pidParameters);
+}
+
+void StabController::setPitchStabPidParameters(PidWrapper::PidParameter pidParameters)
+{
+    _pitchStabPidController.setPidParameters(pidParameters);
+}
+
+void StabController::setRollStabPidParameters(PidWrapper::PidParameter pidParameters)
+{
+    _rollStabPidController.setPidParameters(pidParameters);
+}
+
+void StabController::setYawRatePidParameters(PidWrapper::PidParameter pidParameters)
+{
+    _yawRatePidController.setPidParameters(pidParameters);
+}
+
+void StabController::setPitchRatePidParameters(PidWrapper::PidParameter pidParameters)
+{
+    _pitchRatePidController.setPidParameters(pidParameters);
+}
+
+void StabController::setRollRatePidParameters(PidWrapper::PidParameter pidParameters)
+{
+    _rollRatePidController.setPidParameters(pidParameters);
+}
+
+PidWrapper::StabPidState StabController::getStabPidState()
+{
+    PidWrapper::StabPidState stabPidState;
+    PidWrapper::PidState yawRatePidState;
+    PidWrapper::PidState pitchRatePidState;
+    PidWrapper::PidState rollRatePidState;
+    PidWrapper::PidState yawStabPidState;
+    PidWrapper::PidState pitchStabPidState;
+    PidWrapper::PidState rollStabPidState;
+    
+    yawRatePidState.setPoint = _stabPidOutputs.yaw;
+    yawRatePidState.processValue = _rate.yaw;
+    yawRatePidState.output = _ratePidOutputs.yaw;
+    
+    pitchRatePidState.setPoint = _stabPidOutputs.pitch;
+    pitchRatePidState.processValue = _rate.pitch;
+    pitchRatePidState.output = _ratePidOutputs.pitch;
+    
+    rollRatePidState.setPoint = _stabPidOutputs.roll;
+    rollRatePidState.processValue = _rate.roll;
+    rollRatePidState.output = _ratePidOutputs.roll;
+    
+    yawStabPidState.setPoint = _setPoints.yawDifference;
+    yawStabPidState.processValue = 0;
+    yawStabPidState.output = _stabPidOutputs.yaw;
+    
+    pitchStabPidState.setPoint = _setPoints.pitch;
+    pitchStabPidState.processValue = _angle.pitch;
+    pitchStabPidState.output = _stabPidOutputs.pitch;
+    
+    rollStabPidState.setPoint = _setPoints.roll;
+    rollStabPidState.processValue = _angle.roll;
+    rollStabPidState.output = _stabPidOutputs.roll;
+    
+    stabPidState.yawRate = yawRatePidState;
+    stabPidState.pitchRate = pitchRatePidState;
+    stabPidState.rollRate = rollRatePidState;
+    stabPidState.yawStab = yawStabPidState;
+    stabPidState.pitchStab = pitchStabPidState;
+    stabPidState.rollStab = rollStabPidState;
+    
+    return stabPidState;
+}
\ No newline at end of file
--- a/FlightController/StabController/StabController.h	Wed Mar 04 18:53:43 2015 +0000
+++ b/FlightController/StabController/StabController.h	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,44 @@
+#include "mbed.h"
+#include "Global.h"
+#include "PidWrapper.h"
+#include "ConfigFileWrapper.h"
+#include "NavigationController.h"
+
+#ifndef StabController_H
+#define StabController_H
+
+class StabController               
+{
+  public:                  
+    StabController(Sensors& sensors, NavigationController& navigationController, ConfigFileWrapper& configFileWrapper); 
+    ~StabController();
+    
+    PidWrapper::PidOutput compute();
+    PidWrapper::FlightControllerPidParameters getPidParameters();
+    void reset();
+    void setYawStabPidParameters(PidWrapper::PidParameter pidParameters);
+    void setPitchStabPidParameters(PidWrapper::PidParameter pidParameters);
+    void setRollStabPidParameters(PidWrapper::PidParameter pidParameters);
+    void setYawRatePidParameters(PidWrapper::PidParameter pidParameters);
+    void setPitchRatePidParameters(PidWrapper::PidParameter pidParameters);
+    void setRollRatePidParameters(PidWrapper::PidParameter pidParameters);
+    PidWrapper::StabPidState getStabPidState();
+    
+  private:
+    Sensors& _sensors;
+    NavigationController& _navigationController;
+    ConfigFileWrapper& _configFileWrapper;
+    PidWrapper _yawRatePidController;
+    PidWrapper _pitchRatePidController;
+    PidWrapper _rollRatePidController;
+    PidWrapper _yawStabPidController;
+    PidWrapper _pitchStabPidController;
+    PidWrapper _rollStabPidController;
+    NavigationController::SetPoint _setPoints;
+    Imu::Rate _rate;
+    Imu::Angle _angle;
+    PidWrapper::PidOutput _stabPidOutputs;
+    PidWrapper::PidOutput _ratePidOutputs;
+};
+
+#endif
\ No newline at end of file
--- a/Global.h	Wed Mar 04 18:53:43 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-#include "mbed.h"
-
-#ifndef GLOBAL_H
-#define GLOBAL_H
-
-#if 1
-  #define DEBUG(a) printf(a)
-#else
-  #define DEBUG(a) (void)0
-#endif
-
-#define             IMU_YAW_ANGLE_MAX 180
-#define             IMU_YAW_ANGLE_MIN -180
-#define             IMU_ROLL_ANGLE_MAX 90
-#define             IMU_ROLL_ANGLE_MIN -90
-#define             IMU_PITCH_ANGLE_MAX 90
-#define             IMU_PITCH_ANGLE_MIN -90
-#define             IMU_YAW_RATE_MAX 360
-#define             IMU_YAW_RATE_MIN -360
-#define             IMU_ROLL_RATE_MAX 360
-#define             IMU_ROLL_RATE_MIN -360
-#define             IMU_PITCH_RATE_MAX 360
-#define             IMU_PITCH_RATE_MIN -360
-
-#define             RC_CHANNELS 8
-#define             RC_THROTTLE_CHANNEL 3
-#define             RC_IN_MAX 1900
-#define             RC_IN_MIN 1000
-#define             RC_OUT_MAX 1
-#define             RC_OUT_MIN 0
-#define             RC_YAW_RATE_MAX 180
-#define             RC_YAW_RATE_MIN -180
-#define             RC_ROLL_RATE_MAX 90
-#define             RC_ROLL_RATE_MIN -90
-#define             RC_PITCH_RATE_MAX 90
-#define             RC_PITCH_RATE_MIN -90
-#define             RC_ROLL_ANGLE_MAX 20
-#define             RC_ROLL_ANGLE_MIN -20
-#define             RC_PITCH_ANGLE_MAX 20
-#define             RC_PITCH_ANGLE_MIN -20
-#define             RC_THRUST_MAX 1
-#define             RC_THRUST_MIN 0
-#define             RC_VELOCITY_MAX 2.5
-#define             RC_VELOCITY_MIN 2.5
-
-#define             MOTORS_OFF 0
-#define             MOTORS_ARMED 1000
-#define             MOTORS_MIN 1060
-#define             MOTORS_MAX 1860
-
-#define             RATE_PID_CONTROLLER_OUTPUT_MAX 100
-#define             RATE_PID_CONTROLLER_OUTPUT_MIN -100
-
-#define             FLIGHT_CONTROLLER_FREQUENCY 500
-
-#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Global/ConfigFileWrapper/ConfigFile.lib	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/shintamainjp/code/ConfigFile/#f6ceafabe9f8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Global/ConfigFileWrapper/ConfigFileWrapper.cpp	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,346 @@
+#include "ConfigFileWrapper.h"
+
+ConfigFileWrapper::ConfigFileWrapper()
+{
+    _str = new char[1024];
+    loadSettings();
+    
+    DEBUG("Config file wrapper initialised\r\n");
+}
+
+ConfigFileWrapper::~ConfigFileWrapper(){}
+
+PidWrapper::PidParameter ConfigFileWrapper::getYawRateParameters()
+{
+    return _yawRateParameters;
+}
+
+PidWrapper::PidParameter ConfigFileWrapper::getPitchRateParameters()
+{
+    return _pitchRateParameters;
+}
+
+PidWrapper::PidParameter ConfigFileWrapper::getRollRateParameters()
+{
+    return _rollRateParameters;
+}
+
+PidWrapper::PidParameter ConfigFileWrapper::getYawStabParameters()
+{
+    return _yawStabParameters;
+}
+
+PidWrapper::PidParameter ConfigFileWrapper::getPitchStabParameters()
+{
+    return _pitchStabParameters;
+}
+
+PidWrapper::PidParameter ConfigFileWrapper::getRollStabParameters()
+{
+    return _rollStabParameters;
+}
+
+PidWrapper::PidParameter ConfigFileWrapper::getAltitudeRateParameters()
+{
+    return _altitudeRateParameters;
+}
+
+PidWrapper::PidParameter ConfigFileWrapper::getAltitudeStabParameters()
+{
+    return _altitudeStabParameters;
+}
+
+bool ConfigFileWrapper::setYawRateParameters(PidWrapper::PidParameter pidParameters)
+{
+    _yawRateParameters = pidParameters;
+    return true;
+}
+
+bool ConfigFileWrapper::setPitchRateParameters(PidWrapper::PidParameter pidParameters)
+{
+    _pitchRateParameters = pidParameters;
+    return true;
+}
+
+bool ConfigFileWrapper::setRollRateParameters(PidWrapper::PidParameter pidParameters)
+{
+    _rollRateParameters = pidParameters;
+    return true;
+}
+
+bool ConfigFileWrapper::setYawStabParameters(PidWrapper::PidParameter pidParameters)
+{
+    _yawStabParameters = pidParameters;
+    return true;
+}
+
+bool ConfigFileWrapper::setPitchStabParameters(PidWrapper::PidParameter pidParameters)
+{
+    _pitchStabParameters = pidParameters;
+    return true;
+}
+
+bool ConfigFileWrapper::setRollStabParameters(PidWrapper::PidParameter pidParameters)
+{
+    _rollStabParameters = pidParameters;
+    return true;
+}
+
+bool ConfigFileWrapper::setAltitudeRateParameters(PidWrapper::PidParameter pidParameters)
+{
+    _altitudeRateParameters = pidParameters;
+    return true;
+}
+
+bool ConfigFileWrapper::setAltitudeStabParameters(PidWrapper::PidParameter pidParameters)
+{
+    _altitudeStabParameters = pidParameters;
+    return true;
+}
+
+float ConfigFileWrapper::getAccelZeroPitch()
+{
+    return _accelZeroPitch;
+}
+
+float ConfigFileWrapper::getAccelZeroRoll()
+{
+    return _accelZeroRoll;
+}
+
+bool ConfigFileWrapper::setAccelZeroPitch(float value)
+{
+    _accelZeroPitch = value;
+    return true;
+}
+
+bool ConfigFileWrapper::setAccelZeroRoll(float value)
+{
+    _accelZeroRoll = value;
+    return true;
+}
+
+void ConfigFileWrapper::convertToCharArray(double number)
+{
+    sprintf(_str, "%1.8f", number );  
+}
+
+void ConfigFileWrapper::convertToCharArray(int number)
+{
+    sprintf(_str, "%d", number );  
+}
+
+void ConfigFileWrapper::loadSettings()
+{
+    char value[BUFSIZ];
+    
+    DEBUG("Loading settings from config file\n\r");
+    
+    //Read a configuration file from a mbed.
+    LocalFileSystem local("local");
+    if (!_configFile.read("/local/CONFIG.CFG"))
+    {
+        DEBUG("Config file does not exist\n\r");
+        return;
+    }
+    else
+    {    
+        //Get values
+        if (_configFile.getValue("yawRatePIDControllerP", &value[0], sizeof(value))) _yawRateParameters.p = atof(value);
+        else DEBUG("Failed to get value for yawRatePIDControllerP\n\r");
+        
+        if (_configFile.getValue("yawRatePIDControllerI", &value[0], sizeof(value))) _yawRateParameters.i = atof(value);
+        else DEBUG("Failed to get value for yawRatePIDControllerI\n\r");
+
+        if (_configFile.getValue("yawRatePIDControllerD", &value[0], sizeof(value))) _yawRateParameters.d = atof(value);
+        else DEBUG("Failed to get value for yawRatePIDControllerD\n\r");
+
+        if (_configFile.getValue("pitchRatePIDControllerP", &value[0], sizeof(value))) _pitchRateParameters.p = atof(value);
+        else DEBUG("Failed to get value for pitchRatePIDControllerP\n\r");
+
+        if (_configFile.getValue("pitchRatePIDControllerI", &value[0], sizeof(value))) _pitchRateParameters.i = atof(value);
+        else DEBUG("Failed to get value for pitchRatePIDControllerI\n\r");
+
+        if (_configFile.getValue("pitchRatePIDControllerD", &value[0], sizeof(value))) _pitchRateParameters.d = atof(value);
+        else DEBUG("Failed to get value for pitchRatePIDControllerD\n\r");
+
+        if (_configFile.getValue("rollRatePIDControllerP", &value[0], sizeof(value))) _rollRateParameters.p = atof(value);
+        else DEBUG("Failed to get value for rollRatePIDControllerP\n\r");
+
+        if (_configFile.getValue("rollRatePIDControllerI", &value[0], sizeof(value))) _rollRateParameters.i = atof(value);
+        else DEBUG("Failed to get value for rollRatePIDControllerI\n\r");
+
+        if (_configFile.getValue("rollRatePIDControllerD", &value[0], sizeof(value))) _rollRateParameters.d = atof(value);
+        else DEBUG("Failed to get value for rollRatePIDControllerD\n\r");
+
+        if (_configFile.getValue("yawStabPIDControllerP", &value[0], sizeof(value))) _yawStabParameters.p = atof(value);
+        else DEBUG("Failed to get value for yawStabPIDControllerP\n\r");
+ 
+        if (_configFile.getValue("yawStabPIDControllerI", &value[0], sizeof(value))) _yawStabParameters.i = atof(value);
+        else DEBUG("Failed to get value for yawStabPIDControllerI\n\r");
+
+        if (_configFile.getValue("yawStabPIDControllerD", &value[0], sizeof(value))) _yawStabParameters.d = atof(value);
+        else DEBUG("Failed to get value for yawStabPIDControllerD\n\r");
+
+        if (_configFile.getValue("pitchStabPIDControllerP", &value[0], sizeof(value))) _pitchStabParameters.p = atof(value);
+        else DEBUG("Failed to get value for pitchStabPIDControllerP\n\r");
+
+        if (_configFile.getValue("pitchStabPIDControllerI", &value[0], sizeof(value))) _pitchStabParameters.i = atof(value);
+        else DEBUG("Failed to get value for pitchStabPIDControllerI\n\r");
+
+        if (_configFile.getValue("pitchStabPIDControllerD", &value[0], sizeof(value))) _pitchStabParameters.d = atof(value);
+        else DEBUG("Failed to get value for pitchStabPIDControllerD\n\r");
+
+        if (_configFile.getValue("rollStabPIDControllerP", &value[0], sizeof(value))) _rollStabParameters.p = atof(value);
+        else DEBUG("Failed to get value for rollStabPIDControllerP\n\r");
+
+        if (_configFile.getValue("rollStabPIDControllerI", &value[0], sizeof(value))) _rollStabParameters.i = atof(value);
+        else DEBUG("Failed to get value for rollStabPIDControllerI\n\r");
+
+        if (_configFile.getValue("rollStabPIDControllerD", &value[0], sizeof(value))) _rollStabParameters.d = atof(value);
+        else DEBUG("Failed to get value for rollStabPIDControllerD\n\r");
+        
+        if (_configFile.getValue("altitudeRatePIDControllerP", &value[0], sizeof(value))) _altitudeRateParameters.p = atof(value);
+        else DEBUG("Failed to get value for altitudeRatePIDControllerP\n\r");
+        
+        if (_configFile.getValue("altitudeRatePIDControllerI", &value[0], sizeof(value))) _altitudeRateParameters.i = atof(value);
+        else DEBUG("Failed to get value for altitudeRatePIDControllerI\n\r");
+        
+        if (_configFile.getValue("altitudeRatePIDControllerD", &value[0], sizeof(value))) _altitudeRateParameters.d = atof(value);
+        else DEBUG("Failed to get value for altitudeRatePIDControllerD\n\r");
+        
+        if (_configFile.getValue("altitudeStabPIDControllerP", &value[0], sizeof(value))) _altitudeStabParameters.p = atof(value);
+        else DEBUG("Failed to get value for altitudeStabPIDControllerP\n\r");
+        
+        if (_configFile.getValue("altitudeStabPIDControllerI", &value[0], sizeof(value))) _altitudeStabParameters.i = atof(value);
+        else DEBUG("Failed to get value for altitudeStabPIDControllerI\n\r");
+        
+        if (_configFile.getValue("altitudeStabPIDControllerD", &value[0], sizeof(value))) _altitudeStabParameters.d = atof(value);
+        else DEBUG("Failed to get value for altitudeStabPIDControllerD\n\r");
+        
+        if (_configFile.getValue("accelZeroPitch", &value[0], sizeof(value))) _accelZeroPitch = atof(value);
+        else DEBUG("Failed to get value for accelZeroPitch\n\r");
+        
+        if (_configFile.getValue("accelZeroRoll", &value[0], sizeof(value))) _accelZeroRoll = atof(value);
+        else DEBUG("Failed to get value for accelZeroRoll\n\r");
+
+        /*if (_configFile.getValue("zeroPitch", &value[0], sizeof(value))) _zeroValues[1] = atof(value);
+        else DEBUG("Failed to get value for zero pitch\n\r");
+
+        if (_configFile.getValue("zeroRoll", &value[0], sizeof(value))) _zeroValues[2] = atof(value);
+        else printf("Failed to get value for zero roll\n\r");*/
+    }
+    
+    DEBUG("Finished loading settings from config file\n\r");
+}
+
+bool ConfigFileWrapper::saveSettings()
+{
+    DEBUG("Writing settings to config file\n\r");
+    
+    LocalFileSystem local("local");
+    if (!_configFile.read("/local/CONFIG.CFG"))
+    {
+        DEBUG("Config file does not exist\n\r");
+        return false;
+    }
+    else
+    {   
+        //Write values
+        convertToCharArray(_yawRateParameters.p);
+        if (!_configFile.setValue("yawRatePIDControllerP", _str)) DEBUG("Failed to write value for yawRatePIDControllerP\n\r");
+        
+        convertToCharArray(_yawRateParameters.i);
+        if (!_configFile.setValue("yawRatePIDControllerI", _str)) DEBUG("Failed to write value for yawRatePIDControllerI\n\r");
+        
+        convertToCharArray(_yawRateParameters.d);
+        if (!_configFile.setValue("yawRatePIDControllerD", _str)) DEBUG("Failed to write value for yawRatePIDControllerD\n\r");
+        
+        convertToCharArray(_pitchRateParameters.p);
+        if (!_configFile.setValue("pitchRatePIDControllerP", _str)) DEBUG("Failed to write value for pitchRatePIDControllerP\n\r");
+        
+        convertToCharArray(_pitchRateParameters.i);
+        if (!_configFile.setValue("pitchRatePIDControllerI", _str)) DEBUG("Failed to write value for pitchRatePIDControllerI\n\r");
+        
+        convertToCharArray(_pitchRateParameters.d);
+        if (!_configFile.setValue("pitchRatePIDControllerD", _str)) DEBUG("Failed to write value for pitchRatePIDControllerD\n\r");
+        
+        convertToCharArray(_rollRateParameters.p);
+        if (!_configFile.setValue("rollRatePIDControllerP", _str)) DEBUG("Failed to write value for rollRatePIDControllerP\n\r");
+        
+        convertToCharArray(_rollRateParameters.i);
+        if (!_configFile.setValue("rollRatePIDControllerI", _str)) DEBUG("Failed to write value for rollRatePIDControllerI\n\r");
+        
+        convertToCharArray(_rollRateParameters.d);
+        if (!_configFile.setValue("rollRatePIDControllerD", _str)) DEBUG("Failed to write value for rollRatePIDControllerD\n\r");
+    
+        convertToCharArray(_yawStabParameters.p);
+        if (!_configFile.setValue("yawStabPIDControllerP", _str)) DEBUG("Failed to write value for yawStabPIDControllerP\n\r");
+        
+        convertToCharArray(_yawStabParameters.i);
+        if (!_configFile.setValue("yawStabPIDControllerI", _str)) DEBUG("Failed to write value for yawStabPIDControllerI\n\r");
+        
+        convertToCharArray(_yawStabParameters.d);
+        if (!_configFile.setValue("yawStabPIDControllerD", _str)) DEBUG("Failed to write value for yawStabPIDControllerD\n\r");
+        
+        convertToCharArray(_pitchStabParameters.p);
+        if (!_configFile.setValue("pitchStabPIDControllerP", _str)) DEBUG("Failed to write value for pitchStabPIDControllerP\n\r");
+        
+        convertToCharArray(_pitchStabParameters.i);
+        if (!_configFile.setValue("pitchStabPIDControllerI", _str)) DEBUG("Failed to write value for pitchStabPIDControllerI\n\r");
+        
+        convertToCharArray(_pitchStabParameters.d);
+        if (!_configFile.setValue("pitchStabPIDControllerD", _str)) DEBUG("Failed to write value for pitchStabPIDControllerD\n\r");
+        
+        convertToCharArray(_rollStabParameters.p);
+        if (!_configFile.setValue("rollStabPIDControllerP", _str)) DEBUG("Failed to write value for rollStabPIDControllerP\n\r");
+        
+        convertToCharArray(_rollStabParameters.i);
+        if (!_configFile.setValue("rollStabPIDControllerI", _str)) DEBUG("Failed to write value for _rollStabPIDControllerI\n\r");
+        
+        convertToCharArray(_rollStabParameters.d);
+        if (!_configFile.setValue("rollStabPIDControllerD", _str)) DEBUG("Failed to write value for rollStabPIDControllerD\n\r");
+        
+        convertToCharArray(_altitudeRateParameters.p);
+        if (!_configFile.setValue("altitudeRatePIDControllerP", _str)) DEBUG("Failed to write value for altitudeRatePIDControllerP\n\r");
+        
+        convertToCharArray(_altitudeRateParameters.i);
+        if (!_configFile.setValue("altitudeRatePIDControllerI", _str)) DEBUG("Failed to write value for altitudeRatePIDControllerI\n\r");
+        
+        convertToCharArray(_altitudeRateParameters.d);
+        if (!_configFile.setValue("altitudeRatePIDControllerD", _str)) DEBUG("Failed to write value for altitudeRatePIDControllerD\n\r");
+        
+        convertToCharArray(_altitudeStabParameters.p);
+        if (!_configFile.setValue("altitudeStabPIDControllerP", _str)) DEBUG("Failed to write value for altitudeStabPIDControllerP\n\r");
+        
+        convertToCharArray(_altitudeStabParameters.i);
+        if (!_configFile.setValue("altitudeStabPIDControllerI", _str)) DEBUG("Failed to write value for altitudeStabPIDControllerI\n\r");
+        
+        convertToCharArray(_altitudeStabParameters.d);
+        if (!_configFile.setValue("altitudeStabPIDControllerD", _str)) DEBUG("Failed to write value for altitudeStabPIDControllerD\n\r");
+        
+        convertToCharArray(_accelZeroPitch);
+        if (!_configFile.setValue("accelZeroPitch", _str)) DEBUG("Failed to write value for accelZeroPitch\n\r");
+        
+        convertToCharArray(_accelZeroRoll);
+        if (!_configFile.setValue("accelZeroRoll", _str)) DEBUG("Failed to write value for accelZeroRoll\n\r");
+        
+    
+        //convertToCharArray(_zeroValues[1]);
+        //if (!_configFile.setValue("_zeroPitch", _str)) DEBUG("Failed to write value for zero pitch\n\r");
+        
+        //convertToCharArray(_zeroValues[2]);
+        //if (!_configFile.setValue("_zeroRoll", _str)) DEBUG("Failed to write value for zero roll\n\r");
+        
+        if (!_configFile.write("/local/CONFIG.CFG"))
+        {
+            DEBUG("Failure to write settings to configuration file.\n\r");
+            return false;
+        }
+        else
+        {
+            DEBUG("Successfully wrote settings to configuration file.\n\r");
+            return true;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Global/ConfigFileWrapper/ConfigFileWrapper.h	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,58 @@
+#include "mbed.h"
+#include "Global.h"
+#include "ConfigFile.h"
+#include "PidWrapper.h"
+
+#ifndef ConfigFileWrapper_H
+#define ConfigFileWrapper_H
+
+class ConfigFileWrapper                   // begin declaration of the class
+{
+  public:                    // begin public section
+    ConfigFileWrapper();    // constructor
+    ~ConfigFileWrapper();
+    
+    PidWrapper::PidParameter getYawRateParameters();
+    PidWrapper::PidParameter getPitchRateParameters();
+    PidWrapper::PidParameter getRollRateParameters();
+    PidWrapper::PidParameter getYawStabParameters();
+    PidWrapper::PidParameter getPitchStabParameters();
+    PidWrapper::PidParameter getRollStabParameters();
+    PidWrapper::PidParameter getAltitudeRateParameters();
+    PidWrapper::PidParameter getAltitudeStabParameters();
+    
+    bool setYawRateParameters(PidWrapper::PidParameter pidParameters);
+    bool setPitchRateParameters(PidWrapper::PidParameter pidParameters);
+    bool setRollRateParameters(PidWrapper::PidParameter pidParameters);
+    bool setYawStabParameters(PidWrapper::PidParameter pidParameters);
+    bool setPitchStabParameters(PidWrapper::PidParameter pidParameters);
+    bool setRollStabParameters(PidWrapper::PidParameter pidParameters);
+    bool setAltitudeRateParameters(PidWrapper::PidParameter pidParameters);
+    bool setAltitudeStabParameters(PidWrapper::PidParameter pidParameters);
+    
+    float getAccelZeroPitch();
+    float getAccelZeroRoll();
+    bool setAccelZeroPitch(float value);
+    bool setAccelZeroRoll(float value);
+    
+    bool saveSettings();
+    
+  private:
+    ConfigFile _configFile;
+    char* _str;
+    PidWrapper::PidParameter _yawRateParameters;
+    PidWrapper::PidParameter _pitchRateParameters;
+    PidWrapper::PidParameter _rollRateParameters;
+    PidWrapper::PidParameter _yawStabParameters;
+    PidWrapper::PidParameter _pitchStabParameters;
+    PidWrapper::PidParameter _rollStabParameters;
+    PidWrapper::PidParameter _altitudeRateParameters;
+    PidWrapper::PidParameter _altitudeStabParameters;
+    float _accelZeroPitch;
+    float _accelZeroRoll;
+    void convertToCharArray(double number);
+    void convertToCharArray(int number);
+    void loadSettings();
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Global/Global.h	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,64 @@
+#include "mbed.h"
+
+#ifndef GLOBAL_H
+#define GLOBAL_H
+
+#if 1
+  #define DEBUG(...) printf(__VA_ARGS__)
+#else
+  #define DEBUG(a) (void)0
+#endif
+
+#define MOTORS_ENABLED
+
+#define MOD(a) ((a > 180.0) ? (a - 360.0) : ((a < -180.0) ? (a + 360.0) : a))
+
+#define             IMU_YAW_ANGLE_MAX 180
+#define             IMU_YAW_ANGLE_MIN -180
+#define             IMU_ROLL_ANGLE_MAX 90
+#define             IMU_ROLL_ANGLE_MIN -90
+#define             IMU_PITCH_ANGLE_MAX 90
+#define             IMU_PITCH_ANGLE_MIN -90
+#define             IMU_YAW_RATE_MAX 360
+#define             IMU_YAW_RATE_MIN -360
+#define             IMU_ROLL_RATE_MAX 360
+#define             IMU_ROLL_RATE_MIN -360
+#define             IMU_PITCH_RATE_MAX 360
+#define             IMU_PITCH_RATE_MIN -360
+
+#define             RC_CHANNELS 8
+#define             RC_THROTTLE_CHANNEL 3
+#define             RC_IN_MAX 1900
+#define             RC_IN_MIN 1000
+#define             RC_OUT_MAX 1
+#define             RC_OUT_MIN 0
+#define             RC_YAW_RATE_MAX 180
+#define             RC_YAW_RATE_MIN -180
+#define             RC_ROLL_RATE_MAX 90
+#define             RC_ROLL_RATE_MIN -90
+#define             RC_PITCH_RATE_MAX 90
+#define             RC_PITCH_RATE_MIN -90
+#define             RC_ROLL_ANGLE_MAX 45
+#define             RC_ROLL_ANGLE_MIN -45
+#define             RC_PITCH_ANGLE_MAX 45
+#define             RC_PITCH_ANGLE_MIN -45
+#define             RC_THRUST_MAX 1
+#define             RC_THRUST_MIN 0
+#define             RC_DEAD_ZONE 0.1
+
+#define             MOTORS_OFF 0
+#define             MOTORS_ARMED 1060
+#define             MOTORS_MIN 1060
+#define             MOTORS_MAX 1860
+
+#define             RATE_PID_CONTROLLER_OUTPUT_MAX 100
+#define             RATE_PID_CONTROLLER_OUTPUT_MIN -100
+
+#define             ALTITUDE_MIN 0
+#define             ALTITUDE_MAX 1000
+#define             MAX_CLIMB_RATE 25
+#define             MIN_CLIMB_RATE -25
+
+#define             FLIGHT_CONTROLLER_FREQUENCY 500
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Global/Kalman/Kalman.cpp	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,31 @@
+#include "Kalman.h"
+
+Kalman::Kalman(double q, double r, double p, double intialValue)
+{
+    _kalmanState = KalmanState();
+    _kalmanState.q = q;
+    _kalmanState.r = r;
+    _kalmanState.p = p;
+    _kalmanState.x = intialValue;
+}
+
+Kalman::~Kalman(){}
+
+double Kalman::update(double predicted, double measurement)
+{
+  //prediction
+  _kalmanState.x = predicted * _kalmanState.x;
+  _kalmanState.p = _kalmanState.p + _kalmanState.q;
+
+  //measurement
+  _kalmanState.k = _kalmanState.p / (_kalmanState.p + _kalmanState.r);
+  _kalmanState.x = _kalmanState.x + _kalmanState.k * (measurement - _kalmanState.x);
+  _kalmanState.p = (1 - _kalmanState.k) * _kalmanState.p;
+  
+  return _kalmanState.x;
+}
+
+double Kalman::getEstimated()
+{
+    return _kalmanState.x;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Global/Kalman/Kalman.h	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,29 @@
+#include "mbed.h"
+#include "Global.h"
+
+#ifndef Kalman_H
+#define Kalman_H
+
+class Kalman                
+{
+  public:             
+    Kalman(double q, double r, double p, double intialValue);    
+    ~Kalman();
+    
+    struct KalmanState
+    {
+        double q; //process noise covariance
+        double r; //measurement noise covariance
+        double x; //value
+        double p; //estimation error covariance
+        double k; //kalman gain
+    };
+    
+    double update(double predicted, double measurement);
+    double getEstimated();
+    
+  private:
+    KalmanState _kalmanState;
+
+};
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Global/MODSERIAL.lib	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/AjK/code/MODSERIAL/#ae0408ebdd68
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Global/PidWrapper/PID.lib	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/aberk/code/PID/#6e12a3e5af19
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Global/PidWrapper/PidWrapper.cpp	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,51 @@
+#include "PidWrapper.h"
+
+PidWrapper::PidWrapper(){}
+
+PidWrapper::~PidWrapper(){}
+
+bool PidWrapper::initialise(PidParameter pidParameter, double inputMin, double inputMax, double outputMin, double outputMax, float updateTime)
+{
+    _pid = new PID(pidParameter.p, pidParameter.i, pidParameter.d, updateTime);
+    _pid->setInputLimits(inputMin, inputMax);
+    _pid->setOutputLimits(outputMin, outputMax);
+    _pid->setMode(AUTO_MODE);
+    _pid->setSetPoint(0.0);
+    _pid->setBias(0);
+    
+    DEBUG("PID wrapper initialised\r\n");
+    return true; 
+}
+
+double PidWrapper::compute(double setPoint, double processValue)
+{
+    _pid->setSetPoint(setPoint);
+    _pid->setProcessValue(processValue);
+    return _pid->compute();   
+}
+
+PidWrapper::PidParameter  PidWrapper::getPidParameters()
+{
+    PidWrapper::PidParameter pidParameters;
+    pidParameters.p = _pid->getPParam();    
+    pidParameters.i = _pid->getIParam(); 
+    pidParameters.d = _pid->getDParam(); 
+    
+    return pidParameters;
+}
+
+void PidWrapper::reset()
+{
+    _pid->reset();
+}
+
+void PidWrapper::setPidParameters(PidWrapper::PidParameter pidParameters)
+{
+    _pid->setTunings(pidParameters.p, pidParameters.i, pidParameters.d);
+    DEBUG("P %1.8f, I %1.8f, D %1.8f\r\n", pidParameters.p, pidParameters.i, pidParameters.d);
+}
+
+void PidWrapper::setBias(float bias)
+{
+    _pid->setBias(bias);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Global/PidWrapper/PidWrapper.h	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,79 @@
+#include "mbed.h"
+#include "Global.h"
+#include "PID.h"
+
+#ifndef PidWrapper_H
+#define PidWrapper_H
+
+class PidWrapper                   // begin declaration of the class
+{
+  public:                    // begin public section
+    PidWrapper();    // constructor
+    ~PidWrapper();
+    
+    struct PidOutput
+    {
+        double yaw;
+        double pitch;
+        double roll;
+    };
+    
+    struct PidParameter
+    {
+        double p;
+        double i;
+        double d;
+    };
+    
+    struct PidState
+    {
+        double setPoint;
+        double processValue;
+        double output;
+    };
+    
+    struct FlightControllerPidParameters
+    {
+        PidParameter yawRate;
+        PidParameter pitchRate;
+        PidParameter rollRate;
+        PidParameter yawStab;
+        PidParameter pitchStab;
+        PidParameter rollStab;
+    };
+    
+    struct NavigationControllerPidParameters
+    {
+        PidParameter altitudeRate;
+        PidParameter altitudeStab;
+    };
+    
+    struct RatePidState
+    {
+        PidState yawRate;
+        PidState pitchRate;
+        PidState rollRate;
+    };
+    
+    struct StabPidState
+    {
+        PidState yawRate;
+        PidState pitchRate;
+        PidState rollRate;
+        PidState yawStab;
+        PidState pitchStab;
+        PidState rollStab;
+    };
+    
+    bool initialise(PidParameter pidParameter, double inputMin, double inputMax, double outputMin, double outputMax, float updateTime);
+    double compute(double setPoint, double processValue);
+    PidWrapper::PidParameter getPidParameters();
+    void reset();
+    void setPidParameters(PidWrapper::PidParameter pidParameters);
+    void setBias(float bias);
+
+  private:
+    PID* _pid;
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Global/filter.lib	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/networker/code/filter/#9ce370b360ba
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Global/mbed-rtos.lib	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed-rtos/#721c3a93a7b8
--- a/MODSERIAL.lib	Wed Mar 04 18:53:43 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/AjK/code/MODSERIAL/#ae0408ebdd68
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NavigationController/AltitudeController/AltitudeController.cpp	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,55 @@
+#include "AltitudeController.h"
+
+AltitudeController::AltitudeController(Sensors& sensors, ConfigFileWrapper& configFileWrapper, Status& status) : 
+_sensors(sensors), _configFileWrapper(configFileWrapper), _status(status)
+{
+    double updateTime = (1.0 / ((float)FLIGHT_CONTROLLER_FREQUENCY / 10.0));
+    _altitudeRatePidController.initialise(_configFileWrapper.getAltitudeRateParameters(), MIN_CLIMB_RATE, MAX_CLIMB_RATE, (RC_THRUST_MIN + 0.2), (RC_THRUST_MAX - 0.2), updateTime);
+    _altitudeRatePidController.setBias(0.6); // Hover throttle
+    _altitudeStabPidController.initialise(_configFileWrapper.getAltitudeStabParameters(), ALTITUDE_MIN, ALTITUDE_MAX, MIN_CLIMB_RATE, MAX_CLIMB_RATE, updateTime );
+    
+    //_setPoints = new NavigationController::SetPoint();
+    
+    DEBUG("Altitude controller initialised\r\n");
+}
+
+AltitudeController::~AltitudeController(){}
+
+double AltitudeController::compute(double targetAltitude, double climbRate)
+{   
+    _altitude = _sensors.getAltitude();
+    float velocity = _sensors.getZVelocity();
+    
+    float altitudeStabPidOutput = _altitudeStabPidController.compute(targetAltitude, _altitude.computed);
+    
+    //If pilot commanding climb rate
+    if(_status.getDeadZone() == false) altitudeStabPidOutput = climbRate; //Feed to rate PID (overwriting stab PID output)
+    
+    float altitudeRatePidOutput = _altitudeRatePidController.compute(altitudeStabPidOutput, velocity);
+    
+    return altitudeRatePidOutput;
+}
+
+void AltitudeController::reset()
+{
+    _altitudeRatePidController.reset();
+    _altitudeStabPidController.reset();
+}
+
+PidWrapper::NavigationControllerPidParameters AltitudeController::getPidParameters()
+{
+    PidWrapper::NavigationControllerPidParameters allPidParameters;
+    allPidParameters.altitudeRate = _altitudeRatePidController.getPidParameters();
+    allPidParameters.altitudeStab = _altitudeStabPidController.getPidParameters();
+    return allPidParameters;
+}
+
+void AltitudeController::setAltitudeRatePidParameters(PidWrapper::PidParameter pidParameters)
+{
+    _altitudeRatePidController.setPidParameters(pidParameters);
+}
+
+void AltitudeController::setAltitudeStabPidParameters(PidWrapper::PidParameter pidParameters)
+{
+    _altitudeStabPidController.setPidParameters(pidParameters);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NavigationController/AltitudeController/AltitudeController.h	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,32 @@
+#ifndef AltitudeController_H
+#define AltitudeController_H
+
+#include "mbed.h"
+#include "Global.h"
+#include "PidWrapper.h"
+#include "Sensors.h"
+#include "ConfigFileWrapper.h"
+#include "Status.h"
+
+class AltitudeController               
+{
+  public:                  
+    AltitudeController(Sensors& sensors, ConfigFileWrapper& configFileWrapper, Status& status); 
+    ~AltitudeController();
+    
+    double compute(double targetAltitude, double climbRate);
+    void reset();
+    void setAltitudeRatePidParameters(PidWrapper::PidParameter pidParameters);
+    void setAltitudeStabPidParameters(PidWrapper::PidParameter pidParameters);
+    PidWrapper::NavigationControllerPidParameters getPidParameters();
+    
+  private:
+    Sensors& _sensors;
+    ConfigFileWrapper& _configFileWrapper;
+    Status& _status;
+    Sensors::Altitude _altitude;
+    PidWrapper _altitudeRatePidController;
+    PidWrapper _altitudeStabPidController;
+};
+
+#endif
\ No newline at end of file
--- a/NavigationController/NavigationController.cpp	Wed Mar 04 18:53:43 2015 +0000
+++ b/NavigationController/NavigationController.cpp	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,189 @@
+#include "NavigationController.h"
+
+NavigationController::NavigationController(Status& status, Sensors& sensors, Rc& rc, ConfigFileWrapper& configFileWrapper) : 
+_status(status), _sensors(sensors), _rc(rc), _configFileWrapper(configFileWrapper)
+{
+    _altitudeController = new AltitudeController(_sensors, _configFileWrapper, _status);
+    _altitudeHoldPidOutput = 0;
+    
+    _thread = new Thread(&NavigationController::threadStarter, this, osPriorityHigh);
+
+    DEBUG("Navigation controller initialised\r\n");    
+}
+
+NavigationController::~NavigationController(){}
+
+void NavigationController::threadStarter(void const *p)
+{
+    NavigationController *instance = (NavigationController*)p;
+    instance->threadWorker();
+}
+
+void NavigationController::threadWorker()
+{
+    while(true)
+    {
+        //Get latest sensor readings
+        _sensors.update();
+        
+        //Get state
+        _state = _status.getState();
+        
+        //Get navigation mode
+        _navigationMode = _status.getNavigationMode();
+        
+        //Get Rc commands
+        _mappedRc = _rc.getMappedRc();
+        
+        //Get angle
+        _angle = _sensors.getAngle();
+        
+        //Reset accel data if not flying
+        if(_state == Status::PREFLIGHT || _state == Status::STANDBY)
+        {
+            //Reset accel
+            _sensors.zeroAccel();
+        }
+        
+        //Update yaw target
+        if(abs(_mappedRc.yaw) >= 5 || _state == Status::PREFLIGHT || _state == Status::STANDBY) updateYawTarget();
+             
+        //Make sure we are initialised         
+        if(_state != Status::PREFLIGHT)
+        {            
+            //Update yaw difference
+            _setPoints.yawDifference = MOD(_setPoints.yawTarget - _angle.yaw); 
+            
+            if(_navigationMode == Status::NONE)
+            {
+                //Motors are directly controlled by rc remote
+                if(_mappedRc.throttle >= RC_DEAD_ZONE) _status.setMotorsSpinning(true);
+                else _status.setMotorsSpinning(false);
+                
+                //Update target altitude 
+                updateAltitudeTarget();
+            }
+            else if(_navigationMode == Status::ALTITUDE_HOLD)
+            {
+                //Check if throttle is in dead zone
+                if(_status.getDeadZone() == true) _setPoints.climbRate = 0;
+                else
+                {
+                    //Throttle not in dead zone so map to climb rate
+                    _setPoints.climbRate = map(_mappedRc.throttle, RC_THRUST_MIN, RC_THRUST_MAX, MIN_CLIMB_RATE, MAX_CLIMB_RATE);
+                    
+                    //Update target altitude
+                    updateAltitudeTarget();
+                }
+                
+                //Get PID output
+                _altitudeHoldPidOutput = _altitudeController->compute(_setPoints.targetAltitude, _setPoints.climbRate);
+            }
+            
+            if(_state == Status::STANDBY)  
+            {
+                _setPoints.yaw = 0;
+                _setPoints.pitch = 0;
+                _setPoints.roll = 0;
+                _setPoints.throttle = 0; 
+                
+                _altitudeController->reset();
+            }
+            else if(_state == Status::GROUND_READY)  
+            {
+                _setPoints.yaw = _mappedRc.yaw;
+                _setPoints.pitch = _mappedRc.pitch;
+                _setPoints.roll = _mappedRc.roll;
+                _setPoints.throttle = _mappedRc.throttle; 
+                
+                _altitudeController->reset();
+            }
+            else if(_state == Status::MANUAL)  
+            {
+                _setPoints.yaw = _mappedRc.yaw;
+                _setPoints.pitch = _mappedRc.pitch;
+                _setPoints.roll = _mappedRc.roll;
+                _setPoints.throttle = _mappedRc.throttle; 
+                
+                _altitudeController->reset();
+            }
+            else if(_state == Status::STABILISED)
+            {
+                _setPoints.yaw = _mappedRc.yaw;
+                _setPoints.pitch = _mappedRc.pitch;
+                _setPoints.roll = _mappedRc.roll;
+                _setPoints.throttle = _altitudeHoldPidOutput;
+            }
+            else if(_state == Status::AUTO)
+            {
+                //Waypoint navigation
+            }
+        }
+        //Not initialised
+        else
+        {
+            _setPoints.yaw = 0;
+            _setPoints.pitch = 0;
+            _setPoints.roll = 0;
+            _setPoints.throttle = 0;
+            
+            _altitudeController->reset();
+        }
+        
+        Thread::wait(20);
+    }
+}
+
+NavigationController::SetPoint NavigationController::getSetPoint()
+{
+    return _setPoints;
+}
+
+void NavigationController::updateYawTarget()
+{
+   _setPoints.yawTarget = _angle.yaw;
+}
+
+void NavigationController::updateAltitudeTarget()
+{
+    _altitude = _sensors.getAltitude();
+    _setPoints.targetAltitude = _altitude.computed;
+    
+    if(_setPoints.targetAltitude <= ALTITUDE_MIN) _setPoints.targetAltitude = ALTITUDE_MIN;
+    else if(_setPoints.targetAltitude >= ALTITUDE_MAX) _setPoints.targetAltitude = ALTITUDE_MAX;
+}
+  
+double NavigationController::map(double input, double inputMin, double inputMax, double outputMin, double outputMax)
+{
+    return (input - inputMin) * (outputMax - outputMin) / (inputMax - inputMin) + outputMin;
+}  
+
+PidWrapper::NavigationControllerPidParameters NavigationController::getPidParameters()
+{
+    return _altitudeController->getPidParameters();
+}
+
+void NavigationController::setAltitudeRatePidParameters(PidWrapper::PidParameter pidParameters)
+{
+    _altitudeController->setAltitudeRatePidParameters(pidParameters);
+    _configFileWrapper.setAltitudeRateParameters(pidParameters);
+    saveSettings();
+}
+
+void NavigationController::setAltitudeStabPidParameters(PidWrapper::PidParameter pidParameters)
+{
+    _altitudeController->setAltitudeStabPidParameters(pidParameters);
+    _configFileWrapper.setAltitudeStabParameters(pidParameters);
+    saveSettings();
+}
+
+void NavigationController::saveSettings()
+{
+    Status::State state = _status.getState(); 
+    if(state == Status::STANDBY || state == Status::PREFLIGHT)
+    {
+        _sensors.enable(false);
+        _configFileWrapper.saveSettings();
+        _sensors.enable(true);
+    }   
+}
\ No newline at end of file
--- a/NavigationController/NavigationController.h	Wed Mar 04 18:53:43 2015 +0000
+++ b/NavigationController/NavigationController.h	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,59 @@
+#ifndef NavigationController_H
+#define NavigationController_H
+
+#include "mbed.h"
+#include "Global.h"
+#include "Status.h"
+#include "rtos.h"
+#include "Rc.h"
+#include "Sensors.h"
+#include "AltitudeController.h"
+#include "ConfigFileWrapper.h"
+
+class NavigationController                
+{
+  public:             
+    NavigationController(Status& status, Sensors& sensors, Rc& rc, ConfigFileWrapper& configFileWrapper);    
+    ~NavigationController();
+    
+    struct SetPoint
+    {
+       double yaw;
+       double pitch;
+       double roll;
+       double throttle;
+       double yawTarget;
+       double yawDifference;
+       double climbRate;
+       double targetAltitude;
+    };
+    
+    SetPoint getSetPoint();
+    void updateYawTarget();
+    void updateAltitudeTarget();
+    PidWrapper::NavigationControllerPidParameters getPidParameters();
+    void setAltitudeRatePidParameters(PidWrapper::PidParameter pidParameters);
+    void setAltitudeStabPidParameters(PidWrapper::PidParameter pidParameters);
+    
+  private:
+    static void threadStarter(void const *p);
+    void threadWorker();
+    double map(double input, double inputMin, double inputMax, double outputMin, double outputMax);   
+    
+    Thread* _thread;
+    Status& _status;
+    Sensors& _sensors;
+    Rc& _rc;
+    ConfigFileWrapper& _configFileWrapper;
+    void saveSettings();
+    SetPoint _setPoints;
+    AltitudeController* _altitudeController;
+    Status::State _state;
+    Status::NavigationMode _navigationMode;
+    Rc::MappedRc _mappedRc;
+    Imu::Angle _angle;
+    Sensors::Altitude _altitude;
+    double _altitudeHoldPidOutput;
+};
+
+#endif
\ No newline at end of file
--- a/PidWrapper/PID.lib	Wed Mar 04 18:53:43 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/aberk/code/PID/#6e12a3e5af19
--- a/PidWrapper/PidWrapper.cpp	Wed Mar 04 18:53:43 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-#include "PidWrapper.h"
-
-PidWrapper::PidWrapper(){}
-
-PidWrapper::~PidWrapper(){}
-
-bool PidWrapper::initialise(PidParameters pidParameters, float inputMin, float inputMax, float outputMin, float outputMax)
-{
-    float updateTime = 1.0 / FLIGHT_CONTROLLER_FREQUENCY;
-    _pid = new PID(pidParameters.p, pidParameters.i, pidParameters.d, updateTime);
-    _pid->setInputLimits(inputMin, inputMax);
-    _pid->setOutoutLimits(outputMin, outputMax);
-    _pid->setMode(AUTO_MODE);
-    _pid->setSetPoint(0.0);
-    _pid->setBias(0);
-    
-    DEBUG("PID wrapper initialised");
-    return true; 
-}
-
-PidWrapper::PidValues pidWrapper::compute(PidValues pidValues)
-{
-    
-}
\ No newline at end of file
--- a/PidWrapper/PidWrapper.h	Wed Mar 04 18:53:43 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-#include "mbed.h"
-#include "Global.h"
-
-#ifndef PidWrapper_H
-#define PidWrapper_H
-
-class PidWrapper                   // begin declaration of the class
-{
-  public:                    // begin public section
-    PidWrapper();    // constructor
-    ~PidWrapper();
-    
-    struct PidOutputs
-    {
-        float yaw;
-        float pitch;
-        float roll;
-    };
-    
-    struct PidParameters
-    {
-        float p;
-        float i;
-        float d;
-    };
-    
-    struct PidValues
-    {
-        float setPoint;
-        float processValue;
-        float output;    
-    };
-    
-    bool initialise(PidParameters pidParameters, float inputMin, float inputMax, float outputMin, float outputMax);
-    PidValues compute(PidValues pidValues);
-    
-  private:
-    PID* _pid;
-};
-
-#endif
\ No newline at end of file
--- a/Rc/Ppm.lib	Wed Mar 04 18:53:43 2015 +0000
+++ b/Rc/Ppm.lib	Wed Apr 01 11:19:21 2015 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/joe4465/code/PPM/#b67f18c84c05
+http://mbed.org/users/joe4465/code/PPM/#d13b9e50312f
--- a/Rc/Rc.cpp	Wed Mar 04 18:53:43 2015 +0000
+++ b/Rc/Rc.cpp	Wed Apr 01 11:19:21 2015 +0000
@@ -10,102 +10,119 @@
 //Channel 6 is spare
 //Channel 7 is spare
 
-Rc::Rc(){}
+Rc::Rc(Status& status, PinName pin) : _status(status)
+{
+    _notConnectedIterator = 0;
+    _connectedIterator = 0;
+    _ppm = new Ppm(pin, RC_OUT_MIN, RC_OUT_MAX, RC_IN_MIN, RC_IN_MAX, RC_CHANNELS, RC_THROTTLE_CHANNEL);
+    _yawMedianFilter = new filter(5);
+    _pitchMedianFilter = new filter(5);
+    _rollMedianFilter = new filter(5);
+    _thrustMedianFilter = new filter(5);
+    _armMedianFilter = new filter(5);
+    _modeMedianFilter = new filter(5);
+
+    DEBUG("Rc initialised\r\n"); 
+}
 
 Rc::~Rc(){}
 
-bool Rc::initialise(Status& status, PinName pin)
-{
-    _status = status;
-    
-    _ppm = new Ppm(pin, RC_OUT_MIN, RC_OUT_MAX, RC_IN_MIN, RC_IN_MAX, RC_CHANNELS, RC_THROTTLE_CHANNEL);
-    _yawMedianFilter = new medianFilter(5);
-    _pitchMedianFilter = new medianFilter(5);
-    _rollMedianFilter = new medianFilter(5);
-    _thrustMedianFilter = new medianFilter(5);
-    
-    _thread = new Thread(&Rc::threadStarter, this, osPriorityHigh);
-    DEBUG("Rc initialised");
-    return true; 
-}
-
-void Rc::threadStarter(void const *p)
-{
-    Rc *instance = (Rc*)p;
-    instance->threadWorker();
-}
-
-void Rc::threadWorker()
-{
-    while(true)
-    {
-        float rc[8] = {0,0,0,0,0,0,0,0};
-        
-        //Get channel data - mapped to between 0 and 1
-        _ppm->GetChannelData(rc);
-        
-        //Put channel data into raw rc struct
-        _rawRc.channel0 = rc[0];
-        _rawRc.channel1 = rc[1];
-        _rawRc.channel2 = rc[2];
-        _rawRc.channel3 = rc[3];
-        _rawRc.channel4 = rc[4];
-        _rawRc.channel5 = rc[5];
-        _rawRc.channel6 = rc[6];
-        _rawRc.channel7 = rc[7];
-        
-        //Check whether transmitter is connected
-        if(_rawRc.channel2 != -1)
-        {
-            _status.setRcConnected(true);
-            
-            //Map yaw channel
-            _mappedRc.yaw = - _yawMedianFilter->process(Map(_rawRc.channel3, RC_OUT_MIN, RC_OUT_MAX, RC_YAW_RATE_MIN, RC_YAW_RATE_MAX));
-        
-            //Map thust channel
-            _mappedRc.throttle = _thrustMedianFilter->process(Map(_rawRc.channel2, RC_OUT_MIN, RC_OUT_MAX, RC_THRUST_MIN, RC_THRUST_MAX));
-        
-            //Map arm channel.
-            if(_rawRc.channel4 > 0.5) _status.setArmed(true);
-            else _status.setArmed(false);
-            
-            //Map mode channel
-            if(_rawRc.channel5 < 0.5) _status.setFlightMode(Status::STAB);
-            else _status.setFlightMode(Status::RATE);
-        
-            //Roll and pitch mapping depends on the mode
-            if(_status.getFlightMode() == Status::STAB)//Stability mode
-            {
-                //Roll
-                _mappedRc.roll = _rollMedianFilter->process(Map(_rawRc.channel0, RC_OUT_MIN, RC_OUT_MAX, RC_ROLL_ANGLE_MIN, RC_ROLL_ANGLE_MAX));
-                //Pitch
-                _mappedRc.pitch = _pitchMedianFilter->process(-Map(_rawRc.channel1, RC_OUT_MIN, RC_OUT_MAX, RC_PITCH_ANGLE_MIN, RC_PITCH_ANGLE_MAX)); //Needs to be reverse
-            }
-            else if(_status.getFlightMode() == Status::RATE)//Rate mode
-            {
-                //Roll
-                _mappedRc.roll = _rollMedianFilter->process(Map(_rawRc.channel0, RC_OUT_MIN, RC_OUT_MAX, RC_ROLL_RATE_MIN, RC_ROLL_RATE_MAX));
-                //Pitch
-                _mappedRc.pitch = _pitchMedianFilter->process(-Map(_rawRc.channel1, RC_OUT_MIN, RC_OUT_MAX, RC_PITCH_RATE_MIN, RC_PITCH_RATE_MAX)); //Needs to be reverse
-            }
-        }
-        else _status.setRcConnected(false);
-        
-        Thread::wait(20);
-    }
-}
-
-float Rc::Map(float input, float inputMin, float inputMax, float outputMin, float outputMax)
+double Rc::Map(double input, double inputMin, double inputMax, double outputMin, double outputMax)
 {
     return (input - inputMin) * (outputMax - outputMin) / (inputMax - inputMin) + outputMin;
 }
 
 Rc::MappedRc Rc::getMappedRc()
 {
-    return _mappedRc;
+    Rc::RawRc rawRc = getRawRc();
+    Rc::MappedRc mappedRc = MappedRc();
+    
+    //Check if transmitter is connected
+    if(rawRc.channel2 != -1)
+    {
+        if(_connectedIterator < 10) _connectedIterator++;
+        else
+        {
+            _notConnectedIterator = 0;
+            _status.setRcConnected(true);
+            
+            //Map yaw channel
+            mappedRc.yaw = _yawMedianFilter->process(-Map(rawRc.channel3, RC_OUT_MIN, RC_OUT_MAX, RC_YAW_RATE_MIN, RC_YAW_RATE_MAX));
+        
+            //Map thust channel
+            mappedRc.throttle = _thrustMedianFilter->process(Map(rawRc.channel2, RC_OUT_MIN, RC_OUT_MAX, RC_THRUST_MIN, RC_THRUST_MAX));
+            
+            //Manual mode
+            //Altitude mode
+            if(_status.getNavigationMode() == Status::ALTITUDE_HOLD)
+            {
+                float maxDeadZone = ((float)RC_THRUST_MAX / 2.0) + (float)RC_DEAD_ZONE;
+                float minDeadZone = ((float)RC_THRUST_MAX / 2.0)  - (float)RC_DEAD_ZONE;
+                if((minDeadZone < mappedRc.throttle) && (mappedRc.throttle <= maxDeadZone)) _status.setDeadZone(true);
+                else _status.setDeadZone(false);
+            }
+        
+            //Map arm channel.
+            rawRc.channel4 = _armMedianFilter->process(rawRc.channel4);
+            if(rawRc.channel4 > 0.5) _status.setArmed(true);
+            else _status.setArmed(false);
+            
+            //Map mode channel
+            rawRc.channel5 = _modeMedianFilter->process(rawRc.channel5);
+            //if(rawRc.channel5 > 0.5) _status.setFlightMode(Status::RATE);
+            //else _status.setFlightMode(Status::STAB);
+            if(rawRc.channel5 > 0.5) _status.setNavigationMode(Status::ALTITUDE_HOLD);
+            else _status.setNavigationMode(Status::NONE);
+        
+            //Roll and pitch mapping depends on the mode
+            if(_status.getFlightMode() == Status::STAB)//Stability mode
+            {
+                //Roll
+                mappedRc.roll = _rollMedianFilter->process(Map(rawRc.channel0, RC_OUT_MIN, RC_OUT_MAX, RC_ROLL_ANGLE_MIN, RC_ROLL_ANGLE_MAX));
+                //Pitch
+                mappedRc.pitch = _pitchMedianFilter->process(-Map(rawRc.channel1, RC_OUT_MIN, RC_OUT_MAX, RC_PITCH_ANGLE_MIN, RC_PITCH_ANGLE_MAX)); //Needs to be reverse
+            }
+            else if(_status.getFlightMode() == Status::RATE)//Rate mode
+            {
+                //Roll
+                mappedRc.roll = _rollMedianFilter->process(Map(rawRc.channel0, RC_OUT_MIN, RC_OUT_MAX, RC_ROLL_RATE_MIN, RC_ROLL_RATE_MAX));
+                //Pitch
+                mappedRc.pitch = _pitchMedianFilter->process(-Map(rawRc.channel1, RC_OUT_MIN, RC_OUT_MAX, RC_PITCH_RATE_MIN, RC_PITCH_RATE_MAX)); //Needs to be reverse
+            }
+        }
+    }
+    else if(_notConnectedIterator < 10) _notConnectedIterator++;
+    else
+    {
+        _status.setRcConnected(false);
+        _notConnectedIterator = 0;
+        _connectedIterator = 0;
+        mappedRc.yaw = 0;
+        mappedRc.pitch = 0;
+        mappedRc.roll = 0;
+        mappedRc.throttle = 0;
+    }
+    
+    return mappedRc;
 }
 
 Rc::RawRc Rc::getRawRc()
 {
-    return _rawRc;  
+    double rc[8] = {0,0,0,0,0,0,0,0};
+    Rc::RawRc rawRc = RawRc();
+        
+    //Get channel data - mapped to between 0 and 1
+    _ppm->GetChannelData(rc);
+    
+    //Put channel data into raw rc struct
+    rawRc.channel0 = rc[0];
+    rawRc.channel1 = rc[1];
+    rawRc.channel2 = rc[2];
+    rawRc.channel3 = rc[3];
+    rawRc.channel4 = rc[4];
+    rawRc.channel5 = rc[5];
+    rawRc.channel6 = rc[6];
+    rawRc.channel7 = rc[7];
+    
+    return rawRc;  
 }
\ No newline at end of file
--- a/Rc/Rc.h	Wed Mar 04 18:53:43 2015 +0000
+++ b/Rc/Rc.h	Wed Apr 01 11:19:21 2015 +0000
@@ -3,7 +3,6 @@
 #include "Ppm.h"
 #include "filter.h"
 #include "Status.h"
-#include "rtos.h"
 
 #ifndef Rc_H
 #define Rc_H
@@ -11,47 +10,45 @@
 class Rc                
 {
   public:             
-    Rc();    
+    Rc(Status& status, PinName pin);    
     ~Rc();
     
     struct MappedRc
     {
-       float roll;
-       float pitch;
-       float throttle;
-       float yaw;
+       double yaw;
+       double pitch;
+       double roll;
+       double throttle;
     };
     
     struct RawRc
     {
-        int channel0;
-        int channel1;
-        int channel2;
-        int channel3;
-        int channel4;
-        int channel5;
-        int channel6;
-        int channel7;    
+        double channel0;
+        double channel1;
+        double channel2;
+        double channel3;
+        double channel4;
+        double channel5;
+        double channel6;
+        double channel7;    
     };
     
-    bool initialise(Status& status, PinName pin);
     MappedRc getMappedRc();
     RawRc getRawRc();
     
   private:
-    static void threadStarter(void const *p);
-    void threadWorker();
-    float Map(float input, float inputMin, float inputMax, float outputMin, float outputMax);
+    double Map(double input, double inputMin, double inputMax, double outputMin, double outputMax);
     
     Ppm* _ppm;
-    Thread* _thread;
-    Status _status;
-    MappedRc _mappedRc;
-    RawRc _rawRc;
-    medianFilter* _yawMedianFilter;
-    medianFilter* _pitchMedianFilter;
-    medianFilter* _rollMedianFilter;
-    medianFilter* _thrustMedianFilter;
+    Status& _status;
+    filter* _yawMedianFilter;
+    filter* _pitchMedianFilter;
+    filter* _rollMedianFilter;
+    filter* _thrustMedianFilter;
+    filter* _armMedianFilter;
+    filter* _modeMedianFilter;
+    int _notConnectedIterator;
+    int _connectedIterator;
 };
 
 #endif
\ No newline at end of file
--- a/Rc/filter.lib	Wed Mar 04 18:53:43 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/networker/code/filter/#46a72e790df8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sensors/Gps/Gps.cpp	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,32 @@
+#include "Gps.h"
+
+Gps::Gps(PinName gpsPinTx, PinName gpsPinRx)
+{
+    _values = Value();
+    _gps = new MODSERIAL(gpsPinTx, gpsPinRx);
+    _gps->baud(115200);
+
+    DEBUG("GPS initialised\r\n");
+}
+
+Gps::~Gps(){}
+
+Gps::Value Gps::getValues()
+{
+    while(_gps->readable() > 0)
+    {
+        int c = _gps->getc();
+        if(_tinyGPS.encode(c))
+        {
+            unsigned long fix_age;
+            _tinyGPS.f_get_position(&_values.latitude, &_values.longitude, &fix_age);
+          
+            _values.altitude = _tinyGPS.f_altitude();
+            
+            if ((fix_age == TinyGPS::GPS_INVALID_AGE) || (fix_age > 5000)) _values.fix = false;
+            else _values.fix = true;
+        }
+    }
+
+    return _values;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sensors/Gps/Gps.h	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,31 @@
+#include "mbed.h"
+#include "Global.h"
+#include <TinyGPS.h>
+#include "MODSERIAL.h"
+
+#ifndef Gps_H
+#define Gps_H
+
+class Gps                
+{
+  public:             
+    Gps(PinName gpsPinTx, PinName gpsPinRx);    
+    ~Gps();
+    
+    struct Value
+    {
+        double latitude;
+        double longitude;
+        double altitude;
+        bool fix;
+    };
+    
+    Value getValues();
+    
+  private:
+    MODSERIAL *_gps;
+    TinyGPS _tinyGPS;
+    Value _values;
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sensors/Gps/TinyGPS.lib	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/shimniok/code/TinyGPS/#f522b8bdf987
--- a/Sensors/Imu/FreeIMU_external_magnetometer.lib	Wed Mar 04 18:53:43 2015 +0000
+++ b/Sensors/Imu/FreeIMU_external_magnetometer.lib	Wed Apr 01 11:19:21 2015 +0000
@@ -1,1 +1,1 @@
-http://developer.mbed.org/users/joe4465/code/FreeIMU_external_magnetometer/#48a0eae27bf1
+http://developer.mbed.org/users/joe4465/code/FreeIMU_external_magnetometer/#0065ffbcd39b
--- a/Sensors/Imu/Imu.cpp	Wed Mar 04 18:53:43 2015 +0000
+++ b/Sensors/Imu/Imu.cpp	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,152 @@
+#include "Imu.h"
+
+Imu::Imu(ConfigFileWrapper& configFileWrapper) :_configFileWrapper(configFileWrapper)
+{
+    _rate = Rate();
+    _angle = Angle();
+    
+    _accelZeroPitch = _configFileWrapper.getAccelZeroPitch();
+    _accelZeroRoll = _configFileWrapper.getAccelZeroRoll();
+    
+    Thread::wait(500);
+    _freeImu.init(true);
+    Thread::wait(500);
+    
+    _barometerZeroFilter = new filter(100);
+    _barometerFilter = new filter(5);
+    
+    _barometerZero = 0;
+    zeroBarometer();
+    
+    _velocity = 0;
+    _kalmanFilter = new Kalman(0.1, 32, 1, 0);
+    
+    DEBUG("IMU initialised\r\n");
+}
+
+Imu::~Imu(){}
+
+Imu::Rate Imu::getRate()
+{
+    float rate[3];
+    _freeImu.getRate(rate);
+
+    float yaw = rate[2];
+    float pitch = rate[0];
+    float roll = rate[1];
+    rate[0] = yaw;
+    rate[1] = pitch;
+    rate[2] = roll;
+    
+    _rate.yaw = rate[0];
+    _rate.pitch = rate[1];
+    _rate.roll = rate[2];
+    
+    return _rate;
+}
+
+Imu::Angle Imu::getAngle(bool bias)
+{
+    //Filter Z accel data
+    float values[9];
+    _freeImu.getValues(values);
+    _kalmanFilter->update(1, values[2]);
+    
+    //printf("%1.6f, %1.6f, %1.6f\n", values[0], values[1], values[2]);
+    
+    //Get angle
+    float angle[3];
+    _freeImu.getYawPitchRoll(angle);
+    
+    float yaw = -angle[0];
+    float pitch = angle[2];
+    float roll = -angle[1];
+    angle[0] = yaw;
+    angle[1] = pitch;
+    angle[2] = roll;
+    
+    if(bias == true)
+    {
+        _angle.yaw = angle[0];
+        _angle.pitch = angle[1];//; - _accelZeroPitch;
+        _angle.roll = angle[2];//; - _accelZeroRoll;
+    }
+    else
+    {
+        _angle.yaw = angle[0];
+        _angle.pitch = angle[1];
+        _angle.roll = angle[2];
+    }
+    
+    return _angle;
+}
+
+double Imu::getAltitude()
+{
+    float altitude = _barometerFilter->process(_freeImu.getBaroAlt());
+    float normalAltitude = (altitude - _barometerZero);
+    return (normalAltitude * 100);
+}
+
+float Imu::getVelocity(float time)
+{
+    //Get quat
+    float q[4];
+    _freeImu.getQ(q);
+
+    //Extract accelerometer data
+    float acc[3];
+    acc[0]= 0; //x
+    acc[1]= 0; //y
+    acc[2]= _kalmanFilter->getEstimated();
+    
+    //Gravity compensate
+    _freeImu.gravityCompensateAcc(acc, q);
+    
+    float zAcceleration = 0;
+    if(acc[2] < -0.01 ||  acc[2] > 0.01) zAcceleration = acc[2] * 9.8 * 100;
+    
+    _velocity += zAcceleration * time;
+    
+    return _velocity; //cm/s/s
+}
+
+float Imu::getVelocity()
+{
+    return _velocity; //cm/s/s
+}
+
+void Imu::zeroGyro()
+{
+    _freeImu.zeroGyro();
+}
+
+void Imu::setCurrentVelocity(float velocity)
+{
+    _velocity = velocity;
+}
+
+void Imu::zeroBarometer()
+{
+    for(int i = 0; i < 100; i++)
+    {
+        _barometerZero = _barometerFilter->process(_freeImu.getBaroAlt());
+    }
+    DEBUG("Barometer zero %f\r\n", _barometerZero);
+}
+
+void Imu::enable(bool enable)
+{
+    _freeImu.sample(enable);
+}
+
+void Imu::zeroAccel()
+{
+     Imu::Angle angle = getAngle(false);
+     _accelZeroPitch = angle.pitch;
+     _accelZeroRoll = angle.roll;
+     //DEBUG("Zero accel, pitch %f, roll %f\r\n", _accelZeroPitch, _accelZeroRoll);
+     //_configFileWrapper.setAccelZeroPitch(_accelZeroPitch);
+     //_configFileWrapper.setAccelZeroRoll(_accelZeroRoll); 
+     //_configFileWrapper.saveSettings();
+}
\ No newline at end of file
--- a/Sensors/Imu/Imu.h	Wed Mar 04 18:53:43 2015 +0000
+++ b/Sensors/Imu/Imu.h	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,65 @@
+#include "mbed.h"
+#include "Global.h"
+#include "FreeIMU.h"
+#include "filter.h"
+#include "ConfigFileWrapper.h"
+#include "Kalman.h"
+
+#ifndef Imu_H
+#define Imu_H
+
+class Imu                
+{
+  public:             
+    Imu(ConfigFileWrapper& configFileWrapper);    
+    ~Imu();
+    
+    struct Rate
+    {
+       double yaw;
+       double pitch;
+       double roll;
+    };
+    
+    struct Angle
+    {
+       double yaw;
+       double pitch;
+       double roll;
+    };  
+    
+    struct Velocity
+    {
+        double x;
+        double y;
+        double z;
+    };  
+    
+    void enable(bool enable);
+    
+    Rate getRate();
+    Angle getAngle(bool bias = true);
+    float getVelocity(float time);
+    float getVelocity();
+    double getAltitude();
+    
+    void zeroGyro();
+    void zeroBarometer();
+    void zeroAccel();
+    void setCurrentVelocity(float velocity);
+    
+  private:
+    FreeIMU _freeImu;
+    filter* _barometerZeroFilter;
+    filter* _barometerFilter;
+    Rate _rate;
+    Angle _angle;
+    float _velocity;
+    float _barometerZero;
+    ConfigFileWrapper& _configFileWrapper;
+    float _accelZeroPitch;
+    float _accelZeroRoll;
+    Kalman* _kalmanFilter;
+};
+
+#endif
\ No newline at end of file
--- a/Sensors/LidarLite.lib	Wed Mar 04 18:53:43 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://developer.mbed.org/users/akashvibhute/code/LidarLite/#8e6304ab38d2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sensors/LidarLitePwm.lib	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/joe4465/code/LidarLitePwm/#0b1f4404cb21
--- a/Sensors/MaxbotixDriver.lib	Wed Mar 04 18:53:43 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://developer.mbed.org/users/joe4465/code/MaxbotixDriver/#24d9d6d213aa
--- a/Sensors/Sensors.cpp	Wed Mar 04 18:53:43 2015 +0000
+++ b/Sensors/Sensors.cpp	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,160 @@
+#include "Sensors.h"
+
+Sensors::Sensors(Status& status, ConfigFileWrapper& configFileWrapper, PinName gpsPinTx, PinName gpsPinRx, PinName i2cSda, PinName i2cScl, PinName lidarInterrupt) : _status(status)
+{
+    _gpsValues = Gps::Value();
+    _position = Position();
+    _altitude = Altitude();
+    
+    //Initialise IMU
+    _imu = new Imu(configFileWrapper);
+    _imu->zeroGyro();
+    
+    //Initialise GPS
+    _gps = new Gps(gpsPinTx, gpsPinRx);
+    
+    //Initialise Lidar
+    _lidar = new LidarLitePwm(lidarInterrupt);
+    
+    //Initialise kalman
+    _altitudeKalmanFilter = new Kalman(0.75, 2, 1, 0);
+    
+    DEBUG("Sensors initialised\r\n");
+}
+
+Sensors::~Sensors(){}
+
+void Sensors::update()
+{
+    //Update GPS
+    updateGpsValues();
+    
+    //Update Altitude
+    updateAltitude();
+    
+    //updatePosition();
+}
+
+Imu::Rate Sensors::getRate()
+{
+    return _rate;
+}
+
+Imu::Angle Sensors::getAngle()
+{
+    return _angle;
+}
+
+Gps::Value Sensors::getGpsValues()
+{
+    return _gpsValues;
+}
+
+Sensors::Altitude Sensors::getAltitude()
+{
+    return _altitude;   
+}
+
+Sensors::Position Sensors::getPosition()
+{
+    return _position;   
+}
+
+double Sensors::getZVelocity()
+{
+    return _imu->getVelocity();
+}
+
+void Sensors::updateImu()
+{
+    _angle = _imu->getAngle();
+    _rate = _imu->getRate();
+    
+    return;
+}
+
+void Sensors::updateGpsValues()
+{
+    _gpsValues = _gps->getValues();
+}
+
+void Sensors::updateAltitude()
+{
+    _altitude.lidar = getLidarAltitude();  //cm
+    _altitude.barometer = _imu->getAltitude(); //cm
+    _altitude.gps = _gpsValues.altitude; //m
+    
+    //Update IMU velocity
+    double time = (1.0 / ((double)FLIGHT_CONTROLLER_FREQUENCY / 10.00)); // In seconds
+    double velocity = _imu->getVelocity(time);
+    
+    //Compute predicted altitude
+    double predictedAltitude = _altitude.computed + velocity;
+    
+    //Compute predicted change in altitude
+    double predictedChange = 1;
+    if(_altitude.computed != 0) predictedChange = predictedAltitude / _altitude.computed;
+    
+    //Compute estimated altitude
+    double estimatedAltitude = _altitudeKalmanFilter->update(predictedChange, _altitude.lidar);
+    
+    //Compute estimated velocity
+    double estimatedVelocity = estimatedAltitude - _altitude.computed;
+    
+    //Reset IMU velocity to estimated velocity
+    _imu->setCurrentVelocity(estimatedVelocity);
+    
+    //Save new altitude
+    _altitude.computed = estimatedAltitude;
+    
+    //printf("%1.6f, %1.6f, %1.6f\r\n", predictedAltitude, _altitude.lidar, _altitude.computed);
+}
+
+
+void Sensors::updatePosition()
+{
+    
+}
+
+void Sensors::zeroGyro()
+{
+    _imu->zeroGyro();
+}
+
+void Sensors::zeroBarometer()
+{
+    _imu->zeroBarometer();
+}
+
+void Sensors::enable(bool enable)
+{
+    _imu->enable(enable);
+}
+
+int Sensors::getLidarAltitude()
+{
+    Imu::Angle angles = getAngle();
+    int rawAltitude = _lidar->read();
+    
+    double oppAng = 0;
+    double multiplier = 0;  
+    int pitchAltitude = 0;
+    int rollAltitude = 0;
+    
+    //Calulate pitch altitude
+    oppAng = 90 - abs(angles.pitch);
+    multiplier = sin(oppAng*PI/180);
+    pitchAltitude = multiplier * rawAltitude;
+    
+    //Calulate roll altitude
+    oppAng = 90 - abs(angles.roll);
+    multiplier = sin(oppAng*PI/180);
+    rollAltitude = multiplier * rawAltitude;
+    
+    return (pitchAltitude + rollAltitude)/ 2;
+}
+
+void Sensors::zeroAccel()
+{
+    _imu->zeroAccel();
+}
\ No newline at end of file
--- a/Sensors/Sensors.h	Wed Mar 04 18:53:43 2015 +0000
+++ b/Sensors/Sensors.h	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,72 @@
+#include "mbed.h"
+#include "Global.h"
+#include "rtos.h"
+#include "Gps.h"
+#include "Imu.h"
+#include "Status.h"
+#include "LidarLitePwm.h"
+#include "Kalman.h"
+
+#ifndef Sensors_H
+#define Sensors_H
+
+#define PI 3.14159265
+
+class Sensors                
+{
+  public:             
+    Sensors(Status& status, ConfigFileWrapper& configFileWrapper, PinName gpsPinTx, PinName gpsPinRx, PinName i2cSda, PinName i2cScl, PinName lidarInterrupt);    
+    ~Sensors();
+    
+    struct Position
+    {
+        double accelX;
+        double accelY;
+        double accelZ;
+        double latitude;
+        double longitude;
+        double computedX;
+        double computedY;  
+    };
+    
+    struct Altitude
+    {
+        double lidar;
+        double barometer;
+        double gps;
+        double computed;
+    };
+    
+    void update();
+    Imu::Rate getRate();
+    Imu::Angle getAngle();
+    Gps::Value getGpsValues();
+    double getZVelocity();
+    Sensors::Altitude getAltitude();
+    Sensors::Position getPosition();
+    void enable(bool enable);
+    void zeroBarometer();
+    void updateImu();
+    void zeroAccel();
+    
+  private:
+    void zeroGyro();
+    void updateGpsValues();
+    void updateAltitude();
+    void updateVelocity();
+    void updatePosition();
+    int getLidarAltitude();
+    
+    Status& _status;
+    Imu::Rate _rate;
+    Imu::Angle _angle;
+    Position _position;
+    Altitude _altitude;
+    Gps::Value _gpsValues;
+    Imu* _imu;
+    Gps* _gps;
+    LidarLitePwm* _lidar;
+    Kalman* _altitudeKalmanFilter;
+};
+
+#endif
\ No newline at end of file
--- a/Status/Status.cpp	Wed Mar 04 18:53:43 2015 +0000
+++ b/Status/Status.cpp	Wed Apr 01 11:19:21 2015 +0000
@@ -1,12 +1,34 @@
 #include "Status.h"
 
-Status::Status(){}
+Status::Status()
+{
+    setFlightMode(STAB);
+    setBaseStationMode(STATUS);
+    setNavigationMode(NONE);
+    setBatteryLevel(0);
+    setRcConnected(false);
+    setArmed(false);
+    setMotorsSpinning(false);
+    setDeadZone(false);
+    setInitialised(false);
+    DEBUG("Status initialised\r\n");    
+}
 
 Status::~Status(){}
 
-bool Status::initialise()
+bool Status::update()
 {
-    setState(PREFLIGHT);
+         if(getInitialised() == false && getRcConnected() == false) setState(Status::PREFLIGHT);
+    else if(getInitialised() == true && getRcConnected() == false) setState(Status::PREFLIGHT);
+    else if(getInitialised() == true && getRcConnected() == true && getArmed() == false) setState(Status::STANDBY);
+    else if(getInitialised() == true && getRcConnected() == true && getArmed() == true && getMotorsSpinning() == false) setState(Status::GROUND_READY);
+    else if(getInitialised() == true && getRcConnected() == true && getArmed() == true && getMotorsSpinning() == true && getNavigationMode() == Status::NONE) setState(Status::MANUAL);
+    else if(getInitialised() == true && getRcConnected() == true && getArmed() == true && getMotorsSpinning() == true && getNavigationMode() == Status::POSITION_HOLD) setState(Status::AUTO);
+    else if(getInitialised() == true && getRcConnected() == true && getArmed() == true && getMotorsSpinning() == true && getNavigationMode() == Status::ALTITUDE_HOLD) setState(Status::STABILISED);
+
+    //else setState(Status::ERROR); 
+    
+    return true;
 }
 
 bool Status::setState(State state)
@@ -14,58 +36,77 @@
     switch(state)
     {
         case PREFLIGHT:
-            setFlightMode(NOT_SET);
-            setBaseStationMode(STATUS);
-            setBatteryLevel(0);
-            setArmed(false);
-            setInitialised(false);
+            if(_state != Status::PREFLIGHT)
+            {
+                _state = PREFLIGHT;
+                _statusLights.clear();
+                DEBUG("State set to PREFLIGHT\r\n");
+                return true;
+            }
+            _statusLights.preFlight();
             return true;
               
         case STANDBY:
-        
+            if(_state != Status::STANDBY)
+            {
+                _state = STANDBY;
+                _statusLights.clear();
+                DEBUG("State set to STANDBY\r\n");
+                return true;
+            }
+            _statusLights.standby();
             return true;
-              
             
         case GROUND_READY:
-        
+            if(_state != Status::GROUND_READY)
+            {
+                _state = GROUND_READY;
+                _statusLights.clear();
+                DEBUG("State set to GROUND_READY\r\n");
+                return true;
+            }
+            _statusLights.groundReady();
             return true;
-              
-            
+                 
         case MANUAL:
-        
-            return true;
-              
+            if(_state != Status::MANUAL)
+            {
+                _state = MANUAL;
+                _statusLights.clear();
+                DEBUG("State set to MANUAL\r\n");
+                return true;   
+            }
+            _statusLights.flying();
+            return true;              
         
         case STABILISED:
-            
-            return true;
+            if(_state != Status::STABILISED)
+            {
+                _state = STABILISED;
+                _statusLights.clear();
+                DEBUG("State set to STABILISED\r\n");
+                return true;   
+            }
+            _statusLights.flying();
+            return true;  
               
         
         case AUTO:
             
             return true;
               
-        
-        case ABORT:
             
-            return true;
-              
-            
-        case EMG_LAND:
-            
+        case ERROR:
+            if(_state != Status::ERROR)
+            {
+                _state = Status::ERROR;
+                _statusLights.clear();
+                DEBUG("State set to ERROR\r\n");
+                return true;
+            }
+            _statusLights.error();
             return true;
               
-            
-        case EMG_OFF:
-            
-            return true;
-              
-            
-        case GROUND_ERROR:
-            
-            return true;
-              
-        
         default:
             
             return false;
@@ -80,8 +121,13 @@
 
 bool Status::setFlightMode(FlightMode flightMode)
 {
-    _flightMode = flightMode;
-    return true;
+    if(flightMode != _flightMode)
+    {
+        _flightMode = flightMode;
+        DEBUG("Flight mode set to %d\r\n", _flightMode);
+        return true;
+    }
+    else return false;
 }
 
 Status::FlightMode Status::getFlightMode()
@@ -89,10 +135,31 @@
     return _flightMode;
 }
 
+bool Status::setNavigationMode(NavigationMode navigationMode)
+{
+    if(navigationMode != _navigationMode)
+    {
+        _navigationMode = navigationMode;
+        DEBUG("Navigation mode set to %d\r\n", _navigationMode);
+        return true;
+    }
+    else return false;
+}
+
+Status::NavigationMode Status::getNavigationMode()
+{
+    return _navigationMode;
+}
+
 bool Status::setBaseStationMode(BaseStationMode baseStationMode)
 {
-    _baseStationMode = baseStationMode;
-    return true;
+    if(baseStationMode != _baseStationMode)
+    {
+        _baseStationMode = baseStationMode;
+        DEBUG("Base station mode set to %d\r\n", _baseStationMode);
+        return true;
+    }
+    return false;
 }
 
 Status::BaseStationMode Status::getBaseStationMode()
@@ -100,21 +167,41 @@
     return _baseStationMode;
 }
 
-bool Status::setBatteryLevel(float batteryLevel)
+bool Status::setBatteryLevel(double batteryLevel)
 {
     _batteryLevel = batteryLevel;
     return true;
 }
 
-float Status::getBatteryLevel()
+double Status::getBatteryLevel()
 {
     return _batteryLevel;
 }
 
 bool Status::setArmed(bool armed)
 {
-    _armed = armed;
-    return true;
+    if(armed != _armed)
+    {
+        if(armed == false)
+        {
+            _armed = armed;
+            DEBUG("Armed set to %d\r\n", _armed);
+            return true;
+        }
+        else if (armed == true && _navigationMode == Status::NONE && getMotorsSpinning() == false)
+        {
+            _armed = armed;
+            DEBUG("Armed set to %d\r\n", _armed);
+            return true;
+        }
+        else if (armed == true && _navigationMode == Status::ALTITUDE_HOLD && getMotorsSpinning() == false && getDeadZone() == true)
+        {
+            _armed = armed;
+            DEBUG("Armed set to %d\r\n", _armed);
+            return true;
+        }
+    }
+    return false;
 }
 
 bool Status::getArmed()
@@ -124,8 +211,13 @@
 
 bool Status::setInitialised(bool initialised)
 {
-    _initialised = initialised;
-    return true;
+    if(initialised != _initialised)
+    {
+        _initialised = initialised;
+        DEBUG("Initialised set to %d\r\n", _initialised);
+        return true;
+    }
+    else return false;
 }
 
 bool Status::getInitialised()
@@ -135,11 +227,54 @@
 
 bool Status::setRcConnected(bool rcConnected)
 {
-    _rcConnected = rcConnected;
-    return true;
+    if(rcConnected != _rcConnected)
+    {
+        _rcConnected = rcConnected;
+        if(_rcConnected == false)
+        {
+            setArmed(false);
+            setMotorsSpinning(false);
+            setDeadZone(false);
+        }
+        DEBUG("Rc connected set to %d\r\n", _rcConnected);
+        return true;
+    }
+    else return false;
 }
 
 bool Status::getRcConnected()
 {
     return _rcConnected;
+}
+
+bool Status::setMotorsSpinning(bool flying)
+{
+    if(flying != _flying)
+    {
+        _flying = flying;
+        DEBUG("Flying set to %d\r\n", _flying);
+        return true;
+    }
+    else return false;
+}
+
+bool Status::getMotorsSpinning()
+{
+    return _flying;
+}
+
+bool Status::setDeadZone(bool deadZone)
+{
+    if(deadZone != _deadZone)
+    {
+        _deadZone = deadZone;
+        DEBUG("Dead zone set to %d\r\n", _deadZone);
+        return true;
+    }
+    else return false;
+}
+
+bool Status::getDeadZone()
+{
+    return _deadZone;
 }
\ No newline at end of file
--- a/Status/Status.h	Wed Mar 04 18:53:43 2015 +0000
+++ b/Status/Status.h	Wed Apr 01 11:19:21 2015 +0000
@@ -1,13 +1,15 @@
 #include "mbed.h"
+#include "Global.h"
+#include "StatusLights.h"
 
 #ifndef Status_H
 #define Status_H
 
-class Status                   // begin declaration of the class
+class Status                  
 {
-  public:                    // begin public section
-    Status();     // constructor
-    ~Status();                  // destructor
+  public:                    
+    Status();    
+    ~Status();                  
     
     enum State
     {
@@ -17,17 +19,20 @@
         MANUAL,
         STABILISED,
         AUTO,
-        ABORT,
-        EMG_LAND,
-        EMG_OFF,
-        GROUND_ERROR     
+        ERROR  
     };
     
     enum FlightMode
     {
         RATE,
-        STAB,
-        NOT_SET  
+        STAB
+    };
+    
+    enum NavigationMode
+    {
+        NONE,
+        ALTITUDE_HOLD,
+        POSITION_HOLD
     };
     
     enum BaseStationMode
@@ -36,40 +41,52 @@
         PID_OUTPUTS,
         IMU_OUTPUTS,
         STATUS,
-        MAPPED_RC,
+        RC,
         PID_TUNING,
         GPS,
         ZERO,
         RATE_TUNING,
         STAB_TUNING,
         ALTITUDE,
-        VELOCITY   
+        VELOCITY,
+        ALTITUDE_STATUS
     };
     
-    bool initialise();
-    bool setState(State state);
+    bool update();
     State getState();
     bool setFlightMode(FlightMode flightMode);
     FlightMode getFlightMode();
+    bool setNavigationMode(NavigationMode navigationMode);
+    NavigationMode getNavigationMode();
     bool setBaseStationMode(BaseStationMode baseStationMode);
     BaseStationMode getBaseStationMode();
-    bool setBatteryLevel(float batteryLevel);
-    float getBatteryLevel();
+    bool setBatteryLevel(double batteryLevel);
+    double getBatteryLevel();
     bool setArmed(bool armed);
     bool getArmed();
     bool setInitialised(bool initialised);
     bool getInitialised();
     bool setRcConnected(bool rcConnected);
     bool getRcConnected();
+    bool setMotorsSpinning(bool flying);
+    bool getMotorsSpinning();
+    bool setDeadZone(bool flying);
+    bool getDeadZone();
     
   private:             
     State _state; 
-    FlightMode _flightMode;             
+    FlightMode _flightMode;
+    NavigationMode _navigationMode;          
     BaseStationMode _baseStationMode;
-    float _batteryLevel;
+    StatusLights _statusLights;
+    bool setState(State state);
+    void flash();
+    double _batteryLevel;
     bool _armed;
     bool _initialised;
     bool _rcConnected;
+    bool _flying;
+    bool _deadZone;
 };
 
 #endif
\ No newline at end of file
--- a/Status/StatusLights/StatusLights.cpp	Wed Mar 04 18:53:43 2015 +0000
+++ b/Status/StatusLights/StatusLights.cpp	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,57 @@
+#include "StatusLights.h"
+
+StatusLights::StatusLights()
+{   
+    _ledState = 0;
+    _led1 = new DigitalOut(LED1);
+    _led2 = new DigitalOut(LED2);
+    _led3 = new DigitalOut(LED3);
+    _led4 = new DigitalOut(LED4);
+
+    DEBUG("Status lights initialised\r\n");
+}
+
+StatusLights::~StatusLights(){}
+
+void StatusLights::preFlight()
+{
+    _led1 -> write(!_led1 -> read());
+}
+
+void StatusLights::standby()
+{
+    _led2 -> write(!_led2 -> read());
+}
+
+void StatusLights::groundReady()
+{
+    _led3 -> write(!_led3 -> read());
+}
+
+void StatusLights::flying()
+{
+    _ledState++;
+    if (_ledState > 5) { _ledState = 0; }
+    
+    _led1 -> write(_ledState == 0);
+    _led2 -> write(_ledState == 1 || _ledState == 5);
+    _led3 -> write(_ledState == 2 || _ledState == 4);
+    _led4 -> write(_ledState == 3);
+}
+
+void StatusLights::error()
+{
+    _led1 -> write(!_led1 -> read());
+    _led2 -> write(!_led2 -> read());
+    _led3 -> write(!_led3 -> read());
+    _led4 -> write(!_led4 -> read());
+}
+
+void StatusLights::clear()
+{
+    _led1->write(0);   
+    _led2->write(0); 
+    _led3->write(0); 
+    _led4->write(0); 
+    _ledState = 0;
+}
--- a/Status/StatusLights/StatusLights.h	Wed Mar 04 18:53:43 2015 +0000
+++ b/Status/StatusLights/StatusLights.h	Wed Apr 01 11:19:21 2015 +0000
@@ -0,0 +1,31 @@
+#include "mbed.h"
+#include "Global.h"
+#include "rtos.h"
+#include "Gps.h"
+#include "Imu.h"
+
+#ifndef StatusLights_H
+#define StatusLights_H
+
+class StatusLights                
+{
+  public:             
+    StatusLights();    
+    ~StatusLights();
+    
+    void clear();
+    void preFlight();
+    void standby();
+    void groundReady();
+    void flying();
+    void error();
+    
+  private:
+    int _ledState;
+    DigitalOut* _led1;
+    DigitalOut* _led2;
+    DigitalOut* _led3;
+    DigitalOut* _led4;
+};
+
+#endif
\ No newline at end of file
--- a/main.cpp	Wed Mar 04 18:53:43 2015 +0000
+++ b/main.cpp	Wed Apr 01 11:19:21 2015 +0000
@@ -7,69 +7,53 @@
 #include "Rc.h"
 #include "FlightController.h"
 #include "NavigationController.h"
+#include "ConfigFileWrapper.h"
 
+//Debug serial
 MODSERIAL                           _debug(USBTX, USBRX);
 
-//Wireless Serial
-MODSERIAL                           _base(p9, p10);
-
-//GPS Serial
-//MODSERIAL                           _gps(p13, p14);
-
-//Onboard LED's
-//DigitalOut                          _led1(LED1);
-//DigitalOut                          _led2(LED2);
-//DigitalOut                          _led3(LED3);
-//DigitalOut                          _led4(LED4);
-
-//MaxBotix Ping sensor
-//Timer                               _maxBotixTimer;
-//Sonar                               _maxBotixSensor(p15, _maxBotixTimer);
-
-//Lidar
-//LidarLite                           _lidar(p28, p27);
-
-//Unused analog pins
+//Unused analog pins, set to DigitalOut to remove noise.
 DigitalOut                          _spare1(p16);
 DigitalOut                          _spare2(p17);
 DigitalOut                          _spare3(p18);
 DigitalOut                          _spare4(p19);
-
-//Classes
-Status                              _status;
-//Sensors                             *_sensors(_status, p13, p14, p15, p28, p27);
-//BaseStation                         *_baseStation(p9, p10);
-Rc                                  _rc;
-FlightController                    _flightController;
-//NavigationController                *_navigationController;           
-
+  
 int main()
 {
-    _base.baud(115200);
+    _debug.baud(115200);
     
     DEBUG("\r\n");  
     DEBUG("********************************************************************************\r\n");
     DEBUG("Starting Setup\r\n");
     DEBUG("********************************************************************************\r\n");
     
-    //Set Status
-    _status.initialise();
-    
-    //Initalise Base Station
-        
-    //Initialise RC
-    _rc.initialise(_status, p8);
+    ConfigFileWrapper _configFileWrapper = ConfigFileWrapper(); // No update
+    Thread::wait(100); 
+    Status _status = Status(); // 10 Hz called from main
+    Thread::wait(100); 
+    Sensors _sensors = Sensors(_status, _configFileWrapper, p13, p14, p28, p27, p15); // 50Hz called from navigation controller
+    Thread::wait(100); 
+    Rc _rc = Rc(_status, p8); // 50Hz called from navigation controller
+    Thread::wait(100); 
+    NavigationController _navigationController = NavigationController(_status, _sensors, _rc, _configFileWrapper); // 50Hz internal thread
+    Thread::wait(100); 
+    FlightController _flightController = FlightController(_status, _sensors, _navigationController, _configFileWrapper, p21, p22, p23, p24); // 500Hz internal thread
+    Thread::wait(100); 
+    BaseStation _baseStation = BaseStation(_status, _rc, _sensors, _navigationController, _flightController, _configFileWrapper, p9, p10); // 5Hz internal thread
+    Thread::wait(100); 
     
-    //Initialise Sensors
-    
-    //Initialise Navigation
-    
-    //Initialise Flight Controller
-    _flightController.initialise(_status, _sensors, _navigationController, p21, p22, p23, p24);
-    
-    
+    //Thread::wait(10000); 
     
     DEBUG("********************************************************************************\r\n");
     DEBUG("Finished Setup\r\n");
     DEBUG("********************************************************************************\r\n"); 
+    
+    _status.setInitialised(true);
+    
+    osThreadSetPriority(osThreadGetId(), osPriorityNormal);
+    while(true)
+    {
+        _status.update();
+        Thread::wait(100);   
+    }
 }
--- a/mbed-rtos.lib	Wed Mar 04 18:53:43 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/mbed_official/code/mbed-rtos/#721c3a93a7b8