test

Dependencies:   mbed BufferedSerial ConfigFile

Files at this revision

API Documentation at this revision

Comitter:
skyyoungsik
Date:
Wed Nov 28 13:06:23 2018 +0000
Parent:
0:3473b92e991e
Commit message:
test1

Changed in this revision

ConfigFile.lib Show annotated file Show diff for this revision Revisions of this file
PID.lib Show diff for this revision Revisions of this file
ROBOFRIEN_GUI/GUI_Config.h Show annotated file Show diff for this revision Revisions of this file
ROBOFRIEN_GUI/ROBOFRIEN_GUI.cpp Show annotated file Show diff for this revision Revisions of this file
ROBOFRIEN_GUI/ROBOFRIEN_GUI.h Show annotated file Show diff for this revision Revisions of this file
ROBOFRIEN_SUB_FUNC/Config.h Show diff for this revision Revisions of this file
ROBOFRIEN_SUB_FUNC/Function.h Show annotated file Show diff for this revision Revisions of this file
ROBOFRIEN_SUB_FUNC/ROBOFRIEN_BAT.cpp Show annotated file Show diff for this revision Revisions of this file
ROBOFRIEN_SUB_FUNC/ROBOFRIEN_BAT.h Show annotated file Show diff for this revision Revisions of this file
ROBOFRIEN_SUB_FUNC/ROBOFRIEN_LED.cpp Show annotated file Show diff for this revision Revisions of this file
ROBOFRIEN_SUB_FUNC/ROBOFRIEN_LED.h Show annotated file Show diff for this revision Revisions of this file
ROBOFRIEN_SUB_FUNC/ROBOFRIEN_MOTOR.cpp Show annotated file Show diff for this revision Revisions of this file
ROBOFRIEN_SUB_FUNC/ROBOFRIEN_MOTOR.h Show annotated file Show diff for this revision Revisions of this file
ROBOFRIEN_SUB_FUNC/ROBOFRIEN_PID.cpp Show annotated file Show diff for this revision Revisions of this file
ROBOFRIEN_SUB_FUNC/ROBOFRIEN_PID.h Show annotated file Show diff for this revision Revisions of this file
ROBOFRIEN_SUB_FUNC/ROBOFRIEN_SBUS.cpp Show annotated file Show diff for this revision Revisions of this file
ROBOFRIEN_SUB_FUNC/ROBOFRIEN_SBUS.h Show annotated file Show diff for this revision Revisions of this file
ROBOFRIEN_SUB_FUNC/ROBOFRIE_PID.cpp Show diff for this revision Revisions of this file
ROBOFRIEN_SUB_FUNC/eeprom.h Show annotated file Show diff for this revision Revisions of this file
SPATIAL/SPATIAL.cpp Show annotated file Show diff for this revision Revisions of this file
SPATIAL/SPATIAL.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.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ConfigFile.lib	Wed Nov 28 13:06:23 2018 +0000
@@ -0,0 +1,1 @@
+http://os.mbed.com/users/shintamainjp/code/ConfigFile/#f6ceafabe9f8
--- a/PID.lib	Tue Jun 12 01:05:50 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://os.mbed.com/users/aberk/code/PID/#6e12a3e5af19
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ROBOFRIEN_GUI/GUI_Config.h	Wed Nov 28 13:06:23 2018 +0000
@@ -0,0 +1,114 @@
+#pragma once
+
+#define MODEL_INFO      "ROBOFRIEN FCC "
+#define FIRMWARE_INFO 1.01
+
+#define interrupts() sei()
+#define noInterrupts() cli()
+#define TO_GCS 255
+#define FROM_FCS 0
+
+#define PIN_ULTRA_TRIG A8
+#define PIN_ULTRA_ECHO A9
+#define AHRS_INTERRUPT_PIN A10  // use pin A10 on Arduino Uno & most boards
+
+
+//// EEPROM //////
+// DPN1 //
+#define EEPROM_MODEL_TYPE1      0
+#define EEPROM_MODEL_TYPE2_UP   1
+#define EEPROM_MODEL_TYPE2_DOWN 2
+
+// DPN3 //
+#define EEPROM_RECV_MIN_1 30
+#define EEPROM_RECV_MIN_2 31
+#define EEPROM_RECV_MIN_3 32
+#define EEPROM_RECV_MIN_4 33
+#define EEPROM_RECV_MIN_5 34
+#define EEPROM_RECV_MIN_6 35
+#define EEPROM_RECV_MIN_7 36
+#define EEPROM_RECV_MIN_8 37
+
+#define EEPROM_RECV_NEU_1 38
+#define EEPROM_RECV_NEU_2 39
+#define EEPROM_RECV_NEU_3 40
+#define EEPROM_RECV_NEU_4 41
+#define EEPROM_RECV_NEU_5 42
+#define EEPROM_RECV_NEU_6 43
+#define EEPROM_RECV_NEU_7 44
+#define EEPROM_RECV_NEU_8 45
+
+#define EEPROM_RECV_MAX_1 46
+#define EEPROM_RECV_MAX_2 47
+#define EEPROM_RECV_MAX_3 48
+#define EEPROM_RECV_MAX_4 49
+#define EEPROM_RECV_MAX_5 50
+#define EEPROM_RECV_MAX_6 51
+#define EEPROM_RECV_MAX_7 52
+#define EEPROM_RECV_MAX_8 53
+
+// DPN 4 //
+#define EEPROM_MOTOR_MIN_1_UP      54
+#define EEPROM_MOTOR_MIN_1_DOWN    55
+#define EEPROM_MOTOR_MIN_2_UP      56
+#define EEPROM_MOTOR_MIN_2_DOWN    57
+#define EEPROM_MOTOR_MIN_3_UP      58
+#define EEPROM_MOTOR_MIN_3_DOWN    59
+#define EEPROM_MOTOR_MIN_4_UP      60
+#define EEPROM_MOTOR_MIN_4_DOWN    61
+#define EEPROM_MOTOR_MIN_5_UP      62
+#define EEPROM_MOTOR_MIN_5_DOWN    63
+#define EEPROM_MOTOR_MIN_6_UP      64
+#define EEPROM_MOTOR_MIN_6_DOWN    65
+#define EEPROM_MOTOR_MIN_7_UP      66
+#define EEPROM_MOTOR_MIN_7_DOWN    67
+#define EEPROM_MOTOR_MIN_8_UP      68
+#define EEPROM_MOTOR_MIN_8_DOWN    69
+
+// DPN 5 //
+#define EEPROM_HEADLIGHT_PERIOD     70
+#define EEPROM_HEADLIGHT_DUTYRATE   71
+#define EEPROM_SIDELIGHT_PERIOD     72
+#define EEPROM_SIDELIGHT_DUTYRATE   73
+
+// DPN 6 //
+#define EEPROM_AHRS_ROLL_GAP_UP      74
+#define EEPROM_AHRS_ROLL_GAP_DOWN    75
+#define EEPROM_AHRS_PITCH_GAP_UP     76
+#define EEPROM_AHRS_PITCH_GAP_DOWN   77
+#define EEPROM_AHRS_YAW_GAP_UP       78
+#define EEPROM_AHRS_YAW_GAP_DOWN     79
+
+
+#define EEPROM_AHRS_YAW_X_GAP_1      80
+#define EEPROM_AHRS_YAW_X_GAP_2      81
+#define EEPROM_AHRS_YAW_Y_GAP_1      82
+#define EEPROM_AHRS_YAW_Y_GAP_2      83
+#define EEPROM_AHRS_YAW_Z_GAP_1      84
+#define EEPROM_AHRS_YAW_Z_GAP_2      85
+
+#define EEPROM_AHRS_DECLINATION_ANGLE_UP    86
+#define EEPROM_AHRS_DECLINATION_ANGLE_DOWN  87
+
+// DPN 7 //
+#define EEPROM_LIMIT_ANGLE_ROLL_UP      88
+#define EEPROM_LIMIT_ANGLE_ROLL_DOWN    89
+#define EEPROM_LIMIT_ANGLE_PITCH_UP     90
+#define EEPROM_LIMIT_ANGLE_PITCH_DOWN   91
+#define EEPROM_LIMIT_RATE_ROLL_UP       92
+#define EEPROM_LIMIT_RATE_ROLL_DOWN     93
+#define EEPROM_LIMIT_RATE_PITCH_UP      94
+#define EEPROM_LIMIT_RATE_PITCH_DOWN    95
+#define EEPROM_LIMIT_RATE_YAW_UP        96
+#define EEPROM_LIMIT_RATE_YAW_DOWN      97
+
+// DPN 8  //
+// --Gain 1 //
+int EEPROM_GAIN_P_UP[20] =        {100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119};
+int EEPROM_GAIN_P_DOWN[20] =      {120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139};
+int EEPROM_GAIN_D_UP[20] =        {140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159};
+int EEPROM_GAIN_D_DOWN[20] =      {160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179};
+int EEPROM_GAIN_I_UP[20] =        {180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199};
+int EEPROM_GAIN_I_DOWN[20] =      {200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219};
+
+
--- a/ROBOFRIEN_GUI/ROBOFRIEN_GUI.cpp	Tue Jun 12 01:05:50 2018 +0000
+++ b/ROBOFRIEN_GUI/ROBOFRIEN_GUI.cpp	Wed Nov 28 13:06:23 2018 +0000
@@ -1,10 +1,16 @@
 #include "ROBOFRIEN_GUI.h"
+#include "GUI_Config.h"
 #include "eeprom.h"
-#include "Config.h"
 #include "BufferedSerial.h"
 
+#define PC_DEBUG        0
 
-BufferedSerial pc(USBTX, USBRX);
+#if PC_DEBUG
+    Serial pc(USBTX,USBRX);
+#else
+    BufferedSerial pc(p9, p10);      // tx, rx
+#endif
+
 
 uint8_t ISR_Modem_ID_Dept, ISR_Modem_ID_Dest;
 uint8_t ISR_Modem_DC_DPN, ISR_Modem_DC_DL;
@@ -19,11 +25,7 @@
 uint16_t model_type2;
 uint8_t pc_buffer[256],ex_pc_raw_buffer,pc_raw_buffer[256];
 uint8_t pc_buffer_cnt=0;
-int HomePointChksum,MarkerChksum;
 
-void ROBOFRIEN_GUI::pc_ascii_trans(char* input){
-    pc.printf(input);   pc.printf("\r\n");
-}
 
 void ROBOFRIEN_GUI::pc_rx_update(){
     while (pc.readable()){
@@ -90,7 +92,7 @@
     }
 }
 void ROBOFRIEN_GUI::Init(){    
-    pc.baud(38400);
+    pc.baud(115200);
     eeprom_init();
     /// EEPROM R/W ////
     // -------- MODEL -------------- //
@@ -130,6 +132,8 @@
     motor_min[1] = (int)eeprom_read(EEPROM_MOTOR_MIN_2_UP) * 256 + eeprom_read(EEPROM_MOTOR_MIN_2_DOWN);
     motor_min[2] = (int)eeprom_read(EEPROM_MOTOR_MIN_3_UP) * 256 + eeprom_read(EEPROM_MOTOR_MIN_3_DOWN);
     motor_min[3] = (int)eeprom_read(EEPROM_MOTOR_MIN_4_UP) * 256 + eeprom_read(EEPROM_MOTOR_MIN_4_DOWN);
+    motor_min[4] = (int)eeprom_read(EEPROM_MOTOR_MIN_5_UP) * 256 + eeprom_read(EEPROM_MOTOR_MIN_5_DOWN);
+    motor_min[5] = (int)eeprom_read(EEPROM_MOTOR_MIN_6_UP) * 256 + eeprom_read(EEPROM_MOTOR_MIN_6_DOWN);
 
     // --------- OUTPUT - LED ------------ //
     headlight_period = eeprom_read(EEPROM_HEADLIGHT_PERIOD);
@@ -140,9 +144,9 @@
     // --------- GAIN - LIMIT ANGLE ------- //
     limit_rollx100 = (int)eeprom_read(EEPROM_LIMIT_ANGLE_ROLL_UP) * 256 + eeprom_read(EEPROM_LIMIT_ANGLE_ROLL_DOWN) - 32767;
     limit_pitchx100 = (int)eeprom_read(EEPROM_LIMIT_ANGLE_PITCH_UP) * 256 + eeprom_read(EEPROM_LIMIT_ANGLE_PITCH_DOWN) - 32767;
-    limit_roll_rate = (int)eeprom_read(EEPROM_LIMIT_RATE_ROLL_UP) * 256 + eeprom_read(EEPROM_LIMIT_RATE_ROLL_DOWN) - 32767;
-    limit_pitch_rate = (int)eeprom_read(EEPROM_LIMIT_RATE_PITCH_UP) * 256 + eeprom_read(EEPROM_LIMIT_RATE_PITCH_DOWN) - 32767;
-    limit_yaw_rate = (int)eeprom_read(EEPROM_LIMIT_RATE_YAW_UP) * 256 + eeprom_read(EEPROM_LIMIT_RATE_YAW_DOWN) - 32767;
+    limit_roll_ratex100 = (int)eeprom_read(EEPROM_LIMIT_RATE_ROLL_UP) * 256 + eeprom_read(EEPROM_LIMIT_RATE_ROLL_DOWN) - 32767;
+    limit_pitch_ratex100 = (int)eeprom_read(EEPROM_LIMIT_RATE_PITCH_UP) * 256 + eeprom_read(EEPROM_LIMIT_RATE_PITCH_DOWN) - 32767;
+    limit_yaw_ratex100 = (int)eeprom_read(EEPROM_LIMIT_RATE_YAW_UP) * 256 + eeprom_read(EEPROM_LIMIT_RATE_YAW_DOWN) - 32767;
 
     // --------- GAIN - GAIN DATA --------- //
     for (int i = 0; i < 20; i++) {
@@ -184,25 +188,33 @@
                 if( (Modem_DATA[1] & 0b00010000) == 0b00010000)button[4] = !button[4];
                 // Home Point //
                 if( Modem_DATA[0] == 0){
-                    Homepoint_Lat = (long)Modem_DATA[3] * 16777216 + Modem_DATA[4] * 65536 + Modem_DATA[5] * 256 + Modem_DATA[6] - 90000000;
-                    Homepoint_Lng = (long)Modem_DATA[7] * 16777216 + Modem_DATA[8] * 65536 + Modem_DATA[9] * 256 + Modem_DATA[10] - 180000000;
-                    Homepoint_Alt = (long)Modem_DATA[11] * 256 + Modem_DATA[12] - 10000;
+                    Controller_Joystick[0]  = (Modem_DATA[2]*256 + Modem_DATA[3])-32767;
+                    Controller_Joystick[1]  = (Modem_DATA[4]*256 + Modem_DATA[5])-32767;
+                    Controller_Joystick[2]  = (Modem_DATA[6]*256 + Modem_DATA[7])-32767;
+                    Controller_Joystick[3]  = (Modem_DATA[8]*256 + Modem_DATA[9])-32767;
+                    Gimbal_Joystick[0]      = (Modem_DATA[10]*256 + Modem_DATA[11])-32767;
+                    Gimbal_Joystick[1]      = (Modem_DATA[12]*256 + Modem_DATA[13])-32767;
+                    Gimbal_Joystick[2]      = (Modem_DATA[14]*256 + Modem_DATA[15])-32767;
                 }else if(Modem_DATA[0] <= 20){
                     Marker_Mode[Modem_DATA[0]-1] = Modem_DATA[2];
                     Marker_Lat[Modem_DATA[0]-1] = (long)Modem_DATA[3] * 16777216 + Modem_DATA[4] * 65536 + Modem_DATA[5] * 256 + Modem_DATA[6] - 90000000;
                     Marker_Lng[Modem_DATA[0]-1] = (long)Modem_DATA[7] * 16777216 + Modem_DATA[8] * 65536 + Modem_DATA[9] * 256 + Modem_DATA[10] - 180000000;
                     Marker_Alt[Modem_DATA[0]-1] = (long)Modem_DATA[11] * 256 + Modem_DATA[12] - 10000;                    
                     Marker_Speed[Modem_DATA[0]-1] = (long)Modem_DATA[13] * 256 + Modem_DATA[14];
+                }else if( Modem_DATA[0] == 21){
+                    Homepoint_Lat = (long)Modem_DATA[3] * 16777216 + Modem_DATA[4] * 65536 + Modem_DATA[5] * 256 + Modem_DATA[6] - 90000000;
+                    Homepoint_Lng = (long)Modem_DATA[7] * 16777216 + Modem_DATA[8] * 65536 + Modem_DATA[9] * 256 + Modem_DATA[10] - 180000000;
+                    Homepoint_Alt = (long)Modem_DATA[11] * 256 + Modem_DATA[12] - 10000;
                 }
-                trans_flight_data(TO_GCS, Modem_DC_DPN);
+//                trans_flight_data(TO_GCS, Modem_DC_DPN);
             }
             else {
-                trans_configuration_data(TO_GCS, Modem_DC_DPN, Modem_DATA[0]);
+//                trans_configuration_data(TO_GCS, Modem_DC_DPN, Modem_DATA[0]);
             }
         }
         else {
             /// NOT REQUEST - WRITE TO FCS ///
-                trans_empty_data(TO_GCS, Modem_DC_DPN);
+//                trans_empty_data(TO_GCS, Modem_DC_DPN);
                 switch (Modem_DC_DPN) { // Check DPN //
                 case 0:
                     break;
@@ -212,7 +224,7 @@
                     eeprom_write(EEPROM_MODEL_TYPE1, (int)model_type1);
                     eeprom_write(EEPROM_MODEL_TYPE2_UP, (int)model_type2 / 256);
                     eeprom_write(EEPROM_MODEL_TYPE2_DOWN, (int)model_type2 % 256);
-                    eeprom_refresh();
+                    eeprom_refresh_bool = true;
                     break;
                 case 3:     /// RC Receiver ///
                     if ((Modem_DATA[0] >= 1) & (Modem_DATA[0] <= 8)) {
@@ -261,7 +273,7 @@
                             eeprom_write(EEPROM_RECV_MAX_8, cap_max[Modem_DATA[0] - 1] + 127);
                             break;
                         }
-                        eeprom_refresh();
+                        eeprom_refresh_bool = true;
                     }
                     break;
                 case 4:     // Motor - OUTPUT //
@@ -269,30 +281,44 @@
                     pwm_info[1] = (int)Modem_DATA[3] * 256 + Modem_DATA[4];
                     pwm_info[2] = (int)Modem_DATA[5] * 256 + Modem_DATA[6];
                     pwm_info[3] = (int)Modem_DATA[7] * 256 + Modem_DATA[8];
+                    pwm_info[4] = (int)Modem_DATA[9] * 256 + Modem_DATA[10];
+                    pwm_info[5] = (int)Modem_DATA[11] * 256 + Modem_DATA[12];
                     switch (Modem_DATA[0]) {
                     case 1:
                         motor_min[0] = pwm_info[0];
                         eeprom_write(EEPROM_MOTOR_MIN_1_UP, motor_min[0] / 256);
                         eeprom_write(EEPROM_MOTOR_MIN_1_DOWN, motor_min[0] % 256);
-                        eeprom_refresh();
+                        eeprom_refresh_bool = true;
                         break;
                     case 2:
                         motor_min[1] = pwm_info[1];
                         eeprom_write(EEPROM_MOTOR_MIN_2_UP, motor_min[1] / 256);
                         eeprom_write(EEPROM_MOTOR_MIN_2_DOWN, motor_min[1] % 256);
-                        eeprom_refresh();
+                        eeprom_refresh_bool = true;
                         break;
                     case 3:
                         motor_min[2] = pwm_info[2];
                         eeprom_write(EEPROM_MOTOR_MIN_3_UP, motor_min[2] / 256);
                         eeprom_write(EEPROM_MOTOR_MIN_3_DOWN, motor_min[2] % 256);
-                        eeprom_refresh();
+                        eeprom_refresh_bool = true;
                         break;
                     case 4:
                         motor_min[3] = pwm_info[3];
                         eeprom_write(EEPROM_MOTOR_MIN_4_UP, motor_min[3] / 256);
                         eeprom_write(EEPROM_MOTOR_MIN_4_DOWN, motor_min[3] % 256);
-                        eeprom_refresh();
+                        eeprom_refresh_bool = true;
+                        break;
+                    case 5:
+                        motor_min[4] = pwm_info[4];
+                        eeprom_write(EEPROM_MOTOR_MIN_5_UP, motor_min[4] / 256);
+                        eeprom_write(EEPROM_MOTOR_MIN_5_DOWN, motor_min[4] % 256);
+                        eeprom_refresh_bool = true;
+                        break;
+                    case 6:
+                        motor_min[5] = pwm_info[5];
+                        eeprom_write(EEPROM_MOTOR_MIN_6_UP, motor_min[5] / 256);
+                        eeprom_write(EEPROM_MOTOR_MIN_6_DOWN, motor_min[5] % 256);
+                        eeprom_refresh_bool = true;
                         break;
                     }
                     break;
@@ -305,7 +331,7 @@
                     eeprom_write(EEPROM_HEADLIGHT_DUTYRATE, headlight_dutyrate);
                     eeprom_write(EEPROM_SIDELIGHT_PERIOD, sidelight_period);
                     eeprom_write(EEPROM_SIDELIGHT_DUTYRATE, sidelight_dutyrate);
-                    eeprom_refresh();
+                    eeprom_refresh_bool = true;
                     break;
                 case 6:     // AHRS - ROLL , Pitch //
                             /// Attitude ///
@@ -327,26 +353,26 @@
                         declination_angle = (float)(((int)Modem_DATA[10] * 256 + Modem_DATA[11]) - 18000)/100.0;
                         eeprom_write(EEPROM_AHRS_DECLINATION_ANGLE_UP, (int)((declination_angle+180)*100)/256);
                         eeprom_write(EEPROM_AHRS_DECLINATION_ANGLE_DOWN, (int)((declination_angle+180)*100)%256);
-                        eeprom_refresh();
+                        eeprom_refresh_bool = true;
                     }
                     break;
                 case 7:     // Limit Angle //
                     limit_rollx100 = ((int)Modem_DATA[0] * 256 + Modem_DATA[1]) - 32767;
                     limit_pitchx100 = ((int)Modem_DATA[2] * 256 + Modem_DATA[3]) - 32767;
-                    limit_roll_rate = ((int)Modem_DATA[4] * 256 + Modem_DATA[5]) - 32767;
-                    limit_pitch_rate = ((int)Modem_DATA[6] * 256 + Modem_DATA[7]) - 32767;
-                    limit_yaw_rate = ((int)Modem_DATA[8] * 256 + Modem_DATA[9]) - 32767;
+                    limit_roll_ratex100 = ((int)Modem_DATA[4] * 256 + Modem_DATA[5]) - 32767;
+                    limit_pitch_ratex100 = ((int)Modem_DATA[6] * 256 + Modem_DATA[7]) - 32767;
+                    limit_yaw_ratex100 = ((int)Modem_DATA[8] * 256 + Modem_DATA[9]) - 32767;
                     eeprom_write(EEPROM_LIMIT_ANGLE_ROLL_UP, (limit_rollx100 + 32767) / 256);
                     eeprom_write(EEPROM_LIMIT_ANGLE_ROLL_DOWN, (limit_rollx100 + 32767) % 256);
                     eeprom_write(EEPROM_LIMIT_ANGLE_PITCH_UP, (limit_pitchx100 + 32767) / 256);
                     eeprom_write(EEPROM_LIMIT_ANGLE_PITCH_DOWN, (limit_pitchx100 + 32767) % 256);
-                    eeprom_write(EEPROM_LIMIT_RATE_ROLL_UP, (limit_roll_rate + 32767) / 256);
-                    eeprom_write(EEPROM_LIMIT_RATE_ROLL_DOWN, (limit_roll_rate + 32767) % 256);
-                    eeprom_write(EEPROM_LIMIT_RATE_PITCH_UP, (limit_pitch_rate + 32767) / 256);
-                    eeprom_write(EEPROM_LIMIT_RATE_PITCH_DOWN, (limit_pitch_rate + 32767) % 256);
-                    eeprom_write(EEPROM_LIMIT_RATE_YAW_UP, (limit_yaw_rate + 32767) / 256);
-                    eeprom_write(EEPROM_LIMIT_RATE_YAW_DOWN, (limit_yaw_rate + 32767) % 256);
-                    eeprom_refresh();
+                    eeprom_write(EEPROM_LIMIT_RATE_ROLL_UP, (limit_roll_ratex100 + 32767) / 256);
+                    eeprom_write(EEPROM_LIMIT_RATE_ROLL_DOWN, (limit_roll_ratex100 + 32767) % 256);
+                    eeprom_write(EEPROM_LIMIT_RATE_PITCH_UP, (limit_pitch_ratex100 + 32767) / 256);
+                    eeprom_write(EEPROM_LIMIT_RATE_PITCH_DOWN, (limit_pitch_ratex100 + 32767) % 256);
+                    eeprom_write(EEPROM_LIMIT_RATE_YAW_UP, (limit_yaw_ratex100 + 32767) / 256);
+                    eeprom_write(EEPROM_LIMIT_RATE_YAW_DOWN, (limit_yaw_ratex100 + 32767) % 256);
+                    eeprom_refresh_bool = true;
                     break;
                 case 8:
                     int gain_number = Modem_DATA[0];
@@ -360,7 +386,7 @@
                         eeprom_write(EEPROM_GAIN_D_DOWN[gain_number - 1], gain_dx100[gain_number - 1] % 256);
                         eeprom_write(EEPROM_GAIN_I_UP[gain_number - 1], gain_ix100[gain_number - 1] / 256);
                         eeprom_write(EEPROM_GAIN_I_DOWN[gain_number - 1], gain_ix100[gain_number - 1] % 256);    
-                        if(gain_number == 20)eeprom_refresh();
+                        if(gain_number == 20)eeprom_refresh_bool = true;
                     }
                     break;
             }
@@ -369,6 +395,24 @@
     }
 
 }
+
+void ROBOFRIEN_GUI::Trans(){
+    if ((Modem_ID_Dept == 255)&(Modem_ID_Dest == 0)) {
+        if (Modem_DC_REQUEST == 1) {
+            /// REQUST - READ FROM FCS ///
+            if (Modem_DC_DPN == 0) {
+                trans_flight_data(TO_GCS, Modem_DC_DPN);
+            }
+            else {
+                trans_configuration_data(TO_GCS, Modem_DC_DPN, Modem_DATA[0]);
+            }
+        }
+        else {
+            /// NOT REQUEST - WRITE TO FCS ///
+                trans_empty_data(TO_GCS, Modem_DC_DPN);
+        }
+    }
+}
 void ROBOFRIEN_GUI::trans_empty_data(int id_dest, int data_parse_num) {
     uint8_t Packet_SOF[2] = { 254,254 };
     uint8_t Packet_Identifier[2];
@@ -398,8 +442,11 @@
     modem_buffer[8] = Packet_CHKSUM[1];
     modem_buffer[9] = Packet_EOF[0];
     modem_buffer[10] = Packet_EOF[1];
+    TRANS_BUFFER_BUSY = true;
     for (int i = 0; i <= 10; i++) {
-        pc.putc(modem_buffer[i]);
+        TRANS_BUF[i] = modem_buffer[i];
+        TRANS_BUF_LEN = 11;
+//        pc.putc(modem_buffer[i]);
     }
 }
 
@@ -485,12 +532,12 @@
         Packet_DATA[1] = (limit_rollx100 + 32767) % 256;
         Packet_DATA[2] = (limit_pitchx100 + 32767) / 256;
         Packet_DATA[3] = (limit_pitchx100 + 32767) % 256;
-        Packet_DATA[4] = (limit_roll_rate + 32767) / 256;
-        Packet_DATA[5] = (limit_roll_rate + 32767) % 256;
-        Packet_DATA[6] = (limit_pitch_rate + 32767) / 256;
-        Packet_DATA[7] = (limit_pitch_rate + 32767) % 256;
-        Packet_DATA[8] = (limit_yaw_rate + 32767) / 256;
-        Packet_DATA[9] = (limit_yaw_rate + 32767) % 256;
+        Packet_DATA[4] = (limit_roll_ratex100 + 32767) / 256;
+        Packet_DATA[5] = (limit_roll_ratex100 + 32767) % 256;
+        Packet_DATA[6] = (limit_pitch_ratex100 + 32767) / 256;
+        Packet_DATA[7] = (limit_pitch_ratex100 + 32767) % 256;
+        Packet_DATA[8] = (limit_yaw_ratex100 + 32767) / 256;
+        Packet_DATA[9] = (limit_yaw_ratex100 + 32767) % 256;
         for (int i = 10; i <= 15; i++) Packet_DATA[i] = 0;
         break;
     case 8:
@@ -530,8 +577,11 @@
 modem_buffer[24] = Packet_CHKSUM[1];
 modem_buffer[25] = Packet_EOF[0];
 modem_buffer[26] = Packet_EOF[1];
+TRANS_BUFFER_BUSY = true;
 for (int i = 0; i <= 26; i++) {
-    pc.putc(modem_buffer[i]);
+    TRANS_BUF[i] = modem_buffer[i];
+    TRANS_BUF_LEN = 27;
+//    pc.putc(modem_buffer[i]);
 }
 }
 
@@ -556,28 +606,47 @@
     // DATA - Modem & State //
     if(Mode1 >= 15) Mode1 = 15;
     else if(Mode1 <= 0) Mode1 = 0;
-    if(Mode2 >= 15) Mode2 = 15;
-    else if(Mode2 <= 0) Mode2 = 0;
+    if(Alarm >= 15) Alarm = 15;
+    else if(Alarm <= 0) Alarm = 0;
     if(MissionState >= 15) MissionState = 15;
     else if(MissionState <= 0) MissionState = 0;
     if(CurrentMarker >= 20) CurrentMarker = 20;
     else if(CurrentMarker <= 0) CurrentMarker = 0;
+    int GainChksum = 0;
+    for(int i=0; i<20; i++){
+        GainChksum += (gain_px100[i]>>8);
+        GainChksum += (gain_px100[i]&0xFF);
+        GainChksum += (gain_dx100[i]>>8);
+        GainChksum += (gain_dx100[i]&0xFF);
+        GainChksum += (gain_ix100[i]>>8);
+        GainChksum += (gain_ix100[i]&0xFF);
+    }
     HomePointChksum = ((Homepoint_Lat + 90000000)/16777216) + ((Homepoint_Lat + 90000000)%16777216/65536) + ((Homepoint_Lat + 90000000)%65536/256) + ((Homepoint_Lat + 90000000)%256);
     HomePointChksum += ((Homepoint_Lng + 180000000)/16777216) + ((Homepoint_Lng + 180000000)%16777216/65536) + ((Homepoint_Lng + 180000000)%65536/256) + ((Homepoint_Lng + 180000000)%256);
     HomePointChksum += ((Homepoint_Alt + 10000)/256 + (Homepoint_Alt + 10000)%256);
     MarkerChksum = 0;
     for(int i=0; i<20; i++){
-        MarkerChksum += Marker_Mode[i];
-        MarkerChksum += (Marker_Lat[i]+90000000)/16777216 + (Marker_Lat[i]+90000000)%16777216/65536 + (Marker_Lat[i]+90000000)%65536/256 + (Marker_Lat[i]+90000000)%256;   
-        MarkerChksum += (Marker_Lng[i]+180000000)/16777216 + (Marker_Lng[i]+180000000)%16777216/65536 + (Marker_Lng[i]+180000000)%65536/256 + (Marker_Lng[i]+180000000)%256;
-        MarkerChksum += (Marker_Alt[i]+10000)/256 + (Marker_Alt[i]+10000)%256;
-        MarkerChksum += Marker_Speed[i]/256 + Marker_Speed[i]%256;   
+        MarkerChksum += (uint8_t)(Marker_Mode[i]);
+        MarkerChksum += (uint8_t)((Marker_Lat[i]+90000000)/16777216);
+        MarkerChksum += (uint8_t)((Marker_Lat[i]+90000000)%16777216/65536);
+        MarkerChksum += (uint8_t)((Marker_Lat[i]+90000000)%65536/256);
+        MarkerChksum += (uint8_t)((Marker_Lat[i]+90000000)%256);   
+        MarkerChksum += (uint8_t)((Marker_Lng[i]+180000000)/16777216);
+        MarkerChksum += (uint8_t)((Marker_Lng[i]+180000000)%16777216/65536);
+        MarkerChksum += (uint8_t)((Marker_Lng[i]+180000000)%65536/256);
+        MarkerChksum += (uint8_t)((Marker_Lng[i]+180000000)%256);
+        MarkerChksum += (uint8_t)((Marker_Alt[i]+10000)/256);
+        MarkerChksum += (uint8_t)((Marker_Alt[i]+10000)%256);
+        MarkerChksum += (uint8_t)(Marker_Speed[i]/256);
+        MarkerChksum += (uint8_t)(Marker_Speed[i]%256);   
     }
-    Packet_DATA[0] = Mode1 * 16 + Mode2;
+    Packet_DATA[0] = Mode1 * 16 + Alarm;
     Packet_DATA[1] = MissionState;
     Packet_DATA[2] = CurrentMarker;
+    if(Bat1 > 100) Bat1 = 100;
+    else if(Bat1 < 0) Bat1 = 0;
     Packet_DATA[3] = Bat1;
-    Packet_DATA[4] = Bat2;
+    Packet_DATA[4] = GainChksum%256;
     Packet_DATA[5] = button[0] * 1 + button[1] * 2 + button[2] * 4 + button[3] * 8 + button[4] * 16;
     Packet_DATA[6] = HomePointChksum%256;
     Packet_DATA[7] = MarkerChksum % 256;
@@ -658,10 +727,10 @@
     Packet_DATA[66] = (int)((DEBUGx100[4]))%256;
     Packet_DATA[67] = (int)((DEBUGx100[5]))/256;
     Packet_DATA[68] = (int)((DEBUGx100[5]))%256;
-    Packet_DATA[69] = (int)((DEBUGx100[6]))/256;
-    Packet_DATA[70] = (int)((DEBUGx100[6]))%256;
-    Packet_DATA[71] = (int)((DEBUGx100[7]))/256;
-    Packet_DATA[72] = (int)((DEBUGx100[7]))%256;
+    Packet_DATA[69] = (int)((DEBUGx100[6]+32767))/256;
+    Packet_DATA[70] = (int)((DEBUGx100[6]+32767))%256;
+    Packet_DATA[71] = (int)((DEBUGx100[7]+32767))/256;
+    Packet_DATA[72] = (int)((DEBUGx100[7]+32767))%256;
     // CHKSUM //
     unsigned int data_checksum = 0;
     for (int i = 0; i < data_length; i++) {
@@ -682,8 +751,11 @@
     modem_buffer[81] = Packet_CHKSUM[1];
     modem_buffer[82] = Packet_EOF[0];
     modem_buffer[83] = Packet_EOF[1];
+    TRANS_BUFFER_BUSY = true;
     for (int i = 0; i <= 83; i++) {
-        pc.putc(modem_buffer[i]);
+        TRANS_BUF[i] = modem_buffer[i];
+        TRANS_BUF_LEN = 84;
+//        pc.putc(modem_buffer[i]);
     }
 }
 
@@ -699,7 +771,7 @@
     eeprom_write(EEPROM_AHRS_PITCH_GAP_DOWN, (((unsigned long)(in_acc_bias_y * 10000 + 32767) % 256)));
     eeprom_write(EEPROM_AHRS_YAW_GAP_UP, (((unsigned long)(in_acc_bias_z * 10000 + 32767) / 256)));
     eeprom_write(EEPROM_AHRS_YAW_GAP_DOWN, (((unsigned long)(in_acc_bias_z * 10000 + 32767) % 256)));
-    eeprom_refresh();
+    eeprom_refresh_bool = true;
 }
 
 void ROBOFRIEN_GUI::write_compass_setting_to_eeprom(){
@@ -718,5 +790,46 @@
     eeprom_write(EEPROM_AHRS_YAW_Z_GAP_1, ( (uint32_t)(mag_z_avg + 32767)/256 ) );
     eeprom_write(EEPROM_AHRS_YAW_Z_GAP_2, ( (uint32_t)(mag_z_avg + 32767)%256 ) );
     
-    eeprom_refresh();
+    eeprom_refresh_bool = true;
+}
+
+int eeprom_refresh_cnt = 0;
+bool eeprom_refresh_cnt_bool = false;
+void ROBOFRIEN_GUI::SET_DATA(){
+    if( eeprom_refresh_bool == true){
+        // True 일때, False로 만들고, 10초동안 true로 변경되지 않으면 그때 eeprom_refresh 실시  ( 계속 써서 시스템 망가져서 ~ )
+        eeprom_refresh_bool = false;
+        eeprom_refresh_cnt_bool = true;
+        eeprom_refresh_cnt = 0;
+    }
+    if( eeprom_refresh_cnt_bool == true){
+        eeprom_refresh_cnt ++;
+        if(eeprom_refresh_cnt > 10){
+            eeprom_refresh();
+            eeprom_refresh_cnt = 0;
+            eeprom_refresh_cnt_bool = false;
+        }
+    }
 }
+
+void ROBOFRIEN_GUI::TRANS_BUFFER(){
+    if(TRANS_BUFFER_BUSY == true){
+        if( TRANS_BUF_CNT >= TRANS_BUF_LEN){
+            TRANS_BUF_CNT = 0;
+            TRANS_BUFFER_BUSY = false;
+        }else{
+            #if PC_DEBUG
+                pc.putc(TRANS_BUF[TRANS_BUF_CNT]);
+                TRANS_BUF_CNT ++;
+            #else
+                if(  (LPC_UART3->LSR & 0x20) ){
+                    LPC_UART3->THR = TRANS_BUF[TRANS_BUF_CNT];
+                    TRANS_BUF_CNT ++;                
+                }            
+            #endif
+//            }            
+        }
+    }else{
+        TRANS_BUF_CNT = 0;
+    }
+}
--- a/ROBOFRIEN_GUI/ROBOFRIEN_GUI.h	Tue Jun 12 01:05:50 2018 +0000
+++ b/ROBOFRIEN_GUI/ROBOFRIEN_GUI.h	Wed Nov 28 13:06:23 2018 +0000
@@ -8,21 +8,22 @@
 
 class ROBOFRIEN_GUI {
 public:
-    void pc_ascii_trans(char*);
     void pc_rx_update();
     bool rx_bool();
     void Init();
     void Refresh();
+    void SET_DATA();
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////// [H/M] HomePoint and Marker //////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
     signed long Homepoint_Lat, Homepoint_Lng, Homepoint_Alt;
     signed long Marker_Mode[20],Marker_Lat[20], Marker_Lng[20], Marker_Alt[20], Marker_Speed[20];
+    signed long Controller_Joystick[4], Gimbal_Joystick[3];
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////// [M/S] Mode and State ///////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
-    int8_t Mode1, Mode2,MissionState,CurrentMarker;
-    uint8_t Bat1,Bat2;
+    int8_t Mode1, Alarm,MissionState,CurrentMarker;
+    uint8_t Bat1;
     bool button[5];
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////// [GPS] GPS //////////////////////////////////////////////
@@ -47,7 +48,7 @@
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////// [E/D] Extra & Debug /////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////////////////////////////////    
-    uint16_t DEBUGx100[8];
+    int32_t DEBUGx100[8];
 
 
 
@@ -57,24 +58,31 @@
     uint8_t headlight_period, headlight_dutyrate, sidelight_period, sidelight_dutyrate;
     int16_t raw_cap[8];
     int16_t cap_min[8], cap_neu[8], cap_max[8];
-    int motor_min[4];
+    int motor_min[6];
     uint8_t Compass_Calibration_Mode;
     bool attitude_configuration_bool;
     float declination_angle;
     int16_t limit_rollx100, limit_pitchx100;
-    int32_t limit_roll_rate, limit_pitch_rate, limit_yaw_rate;
+    int32_t limit_roll_ratex100, limit_pitch_ratex100, limit_yaw_ratex100;
     int gain_px100[20], gain_dx100[20], gain_ix100[20];
     float mag_x_avg,mag_y_avg,mag_z_avg;
 //    float calibrate_gap_roll,calibrate_gap_pitch;
     float cal_accel_bias[3];
     uint8_t DPN_Info;
-    int pwm_info[4];
+    int pwm_info[6];
     void attitude_calibrate(float , float , float);
     void write_compass_setting_to_eeprom();
     void trans_flight_data(int id_dest, int data_parse_num);
+    void trans_configuration_data(int id_dest, int data_parse_num, int data_parse_detail_num);
+    void Trans();
+    void TRANS_BUFFER();
+    long MarkerChksum;
 private:
-    void trans_configuration_data(int id_dest, int data_parse_num, int data_parse_detail_num);
+    bool eeprom_refresh_bool;
     void trans_empty_data(int id_dest, int data_parse_num);
+    bool TRANS_BUFFER_BUSY;
+    uint8_t TRANS_BUF[100],TRANS_BUF_LEN,TRANS_BUF_CNT;
+    int HomePointChksum;
 };
 
 #endif
\ No newline at end of file
--- a/ROBOFRIEN_SUB_FUNC/Config.h	Tue Jun 12 01:05:50 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-#pragma once
-
-#define MODEL_INFO      "ROBOFRIEN FCC "
-#define FIRMWARE_INFO 1.01
-
-#define interrupts() sei()
-#define noInterrupts() cli()
-#define TO_GCS 255
-#define FROM_FCS 0
-
-#define PIN_ULTRA_TRIG A8
-#define PIN_ULTRA_ECHO A9
-#define AHRS_INTERRUPT_PIN A10  // use pin A10 on Arduino Uno & most boards
-
-
-//// EEPROM //////
-// DPN1 //
-#define EEPROM_MODEL_TYPE1      0
-#define EEPROM_MODEL_TYPE2_UP   1
-#define EEPROM_MODEL_TYPE2_DOWN 2
-
-// DPN3 //
-#define EEPROM_RECV_MIN_1 30
-#define EEPROM_RECV_MIN_2 31
-#define EEPROM_RECV_MIN_3 32
-#define EEPROM_RECV_MIN_4 33
-#define EEPROM_RECV_MIN_5 34
-#define EEPROM_RECV_MIN_6 35
-#define EEPROM_RECV_MIN_7 36
-#define EEPROM_RECV_MIN_8 37
-
-#define EEPROM_RECV_NEU_1 38
-#define EEPROM_RECV_NEU_2 39
-#define EEPROM_RECV_NEU_3 40
-#define EEPROM_RECV_NEU_4 41
-#define EEPROM_RECV_NEU_5 42
-#define EEPROM_RECV_NEU_6 43
-#define EEPROM_RECV_NEU_7 44
-#define EEPROM_RECV_NEU_8 45
-
-#define EEPROM_RECV_MAX_1 46
-#define EEPROM_RECV_MAX_2 47
-#define EEPROM_RECV_MAX_3 48
-#define EEPROM_RECV_MAX_4 49
-#define EEPROM_RECV_MAX_5 50
-#define EEPROM_RECV_MAX_6 51
-#define EEPROM_RECV_MAX_7 52
-#define EEPROM_RECV_MAX_8 53
-
-// DPN 4 //
-#define EEPROM_MOTOR_MIN_1_UP      54
-#define EEPROM_MOTOR_MIN_1_DOWN    55
-#define EEPROM_MOTOR_MIN_2_UP      56
-#define EEPROM_MOTOR_MIN_2_DOWN    57
-#define EEPROM_MOTOR_MIN_3_UP      58
-#define EEPROM_MOTOR_MIN_3_DOWN    59
-#define EEPROM_MOTOR_MIN_4_UP      60
-#define EEPROM_MOTOR_MIN_4_DOWN    61
-#define EEPROM_MOTOR_MIN_5_UP      62
-#define EEPROM_MOTOR_MIN_5_DOWN    63
-#define EEPROM_MOTOR_MIN_6_UP      64
-#define EEPROM_MOTOR_MIN_6_DOWN    65
-#define EEPROM_MOTOR_MIN_7_UP      66
-#define EEPROM_MOTOR_MIN_7_DOWN    67
-#define EEPROM_MOTOR_MIN_8_UP      68
-#define EEPROM_MOTOR_MIN_8_DOWN    69
-
-// DPN 5 //
-#define EEPROM_HEADLIGHT_PERIOD     70
-#define EEPROM_HEADLIGHT_DUTYRATE   71
-#define EEPROM_SIDELIGHT_PERIOD     72
-#define EEPROM_SIDELIGHT_DUTYRATE   73
-
-// DPN 6 //
-#define EEPROM_AHRS_ROLL_GAP_UP      74
-#define EEPROM_AHRS_ROLL_GAP_DOWN    75
-#define EEPROM_AHRS_PITCH_GAP_UP     76
-#define EEPROM_AHRS_PITCH_GAP_DOWN   77
-#define EEPROM_AHRS_YAW_GAP_UP       78
-#define EEPROM_AHRS_YAW_GAP_DOWN     79
-
-
-#define EEPROM_AHRS_YAW_X_GAP_1      80
-#define EEPROM_AHRS_YAW_X_GAP_2      81
-#define EEPROM_AHRS_YAW_Y_GAP_1      82
-#define EEPROM_AHRS_YAW_Y_GAP_2      83
-#define EEPROM_AHRS_YAW_Z_GAP_1      84
-#define EEPROM_AHRS_YAW_Z_GAP_2      85
-
-#define EEPROM_AHRS_DECLINATION_ANGLE_UP    86
-#define EEPROM_AHRS_DECLINATION_ANGLE_DOWN  87
-
-// DPN 7 //
-#define EEPROM_LIMIT_ANGLE_ROLL_UP      88
-#define EEPROM_LIMIT_ANGLE_ROLL_DOWN    89
-#define EEPROM_LIMIT_ANGLE_PITCH_UP     90
-#define EEPROM_LIMIT_ANGLE_PITCH_DOWN   91
-#define EEPROM_LIMIT_RATE_ROLL_UP       92
-#define EEPROM_LIMIT_RATE_ROLL_DOWN     93
-#define EEPROM_LIMIT_RATE_PITCH_UP      94
-#define EEPROM_LIMIT_RATE_PITCH_DOWN    95
-#define EEPROM_LIMIT_RATE_YAW_UP        96
-#define EEPROM_LIMIT_RATE_YAW_DOWN      97
-
-// DPN 8  //
-// --Gain 1 //
-int EEPROM_GAIN_P_UP[20] =        {100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119};
-int EEPROM_GAIN_P_DOWN[20] =      {120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139};
-int EEPROM_GAIN_D_UP[20] =        {140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159};
-int EEPROM_GAIN_D_DOWN[20] =      {160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179};
-int EEPROM_GAIN_I_UP[20] =        {180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199};
-int EEPROM_GAIN_I_DOWN[20] =      {200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219};
-
-
-const int PIN_BLDC_PWM1 = 46;       // PL3 //
-const int PIN_BLDC_PWM2 = 45;       // PL4 //
-const int PIN_BLDC_PWM3 = 44;       // PL5 //
-const int PIN_BLDC_PWM4 = 10;       // PB4 //
-const int PIN_BLDC_PWM5 = 9;        // PH6 //
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ROBOFRIEN_SUB_FUNC/Function.h	Wed Nov 28 13:06:23 2018 +0000
@@ -0,0 +1,61 @@
+#define M_PI 3.141592
+
+double deg2rad(double deg) {
+  return deg * (M_PI/180.0);
+}
+
+
+double getDistance(double lat1,double lon1,double lat2,double lon2) {
+  double R = 6371; // Radius of the earth in km
+  double dLat = deg2rad(lat2-lat1);  // deg2rad below
+  double dLon = deg2rad(lon2-lon1); 
+  double a = 
+    sin(dLat/2) * sin(dLat/2) +
+    cos(deg2rad(lat1)) * cos(deg2rad(lat2)) * 
+    sin(dLon/2) * sin(dLon/2)
+    ; 
+  double c = 2 * atan2(sqrt(a), sqrt(1-a)); 
+  double d = R * c; // Distance in km
+  d = d * 1000;     // Distance in meter
+  return d;
+}
+
+double MIN_MAX(double input, double min, double max){
+    double output;
+    if( input < min) output = min;
+    else if(input > max) output = max;
+    else output = input;
+    
+    return output;       
+}
+
+
+float bearing(float lat1,float lon1,float lat2,float lon2){
+
+    float teta1 = (lat1)*M_PI/180.0;
+    float teta2 = (lat2)*M_PI/180.0;;
+//    float delta1 = (lat2-lat1)*M_PI/180.0;;
+    float delta2 = (lon2-lon1)*M_PI/180.0;;
+
+    //==================Heading Formula Calculation================//
+
+    float y = sin(delta2) * cos(teta2);
+    float x = cos(teta1)*sin(teta2) - sin(teta1)*cos(teta2)*cos(delta2);
+    float brng = atan2(y,x);
+    brng = (brng)*180.0/M_PI;// radians to degrees
+    brng = ( ((int)brng + 360) % 360 ); 
+//    if(brng > 180) brng -= 360;
+    if(brng > 360) brng -= 360;
+    else if(brng < 0) brng += 360;
+    return brng;
+}
+
+float ABSOL(float input){
+    float output;
+    if( input > 0){
+        output = input;
+    }else{
+        output = -input;
+    }
+    return output;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ROBOFRIEN_SUB_FUNC/ROBOFRIEN_BAT.cpp	Wed Nov 28 13:06:23 2018 +0000
@@ -0,0 +1,22 @@
+#include "ROBOFRIEN_BAT.h"
+
+AnalogIn        BAT_ANALOG(A0);
+
+#define BAT_1CELL_MIN       3.8
+#define BAT_1CELL_MAX       4.1
+#define DC_DC_REFERENCE     3.3
+#define REGISTER_RATIO      11
+#define BAT_LPF             0.9
+
+void ROBOFRIEN_BAT::Init(int cell_info){
+    BAT_MIN = BAT_1CELL_MIN * cell_info;
+    BAT_MAX = BAT_1CELL_MAX * cell_info;
+}
+
+float ROBOFRIEN_BAT::update(){
+    float BAT_PERCENT = 0;
+    ORIGIN_DATA = BAT_ANALOG;
+    BAT_PERCENT = ((BAT_ANALOG*DC_DC_REFERENCE*REGISTER_RATIO)-BAT_MIN)/(BAT_MAX-BAT_MIN)*100;
+    LPF_BAT_DATA = LPF_BAT_DATA * BAT_LPF + BAT_PERCENT * (1-BAT_LPF);
+    return BAT_PERCENT;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ROBOFRIEN_SUB_FUNC/ROBOFRIEN_BAT.h	Wed Nov 28 13:06:23 2018 +0000
@@ -0,0 +1,18 @@
+#ifndef MBED_ROBOFRIEN_BAT_H
+#define MBED_ROBOFRIEN_BAT_H
+
+#include "mbed.h"
+
+
+
+class ROBOFRIEN_BAT {
+public:
+    void Init(int);
+    float update( );
+    float ORIGIN_DATA;
+private:
+    float BAT_MIN,BAT_MAX;
+    float LPF_BAT_DATA;
+};
+
+#endif
\ No newline at end of file
--- a/ROBOFRIEN_SUB_FUNC/ROBOFRIEN_LED.cpp	Tue Jun 12 01:05:50 2018 +0000
+++ b/ROBOFRIEN_SUB_FUNC/ROBOFRIEN_LED.cpp	Wed Nov 28 13:06:23 2018 +0000
@@ -2,13 +2,36 @@
 #include "millis.h"
 
 DigitalOut myled1(LED1);
+DigitalOut myled2(LED2);
+DigitalOut myled3(LED3);
 DigitalOut myled4(LED4);
 
 void ROBOFRIEN_LED::Init(){
     myled1 = 0;
+    myled2 = 0;
+    myled3 = 0;
     myled4 = 0;
 }
-
+void ROBOFRIEN_LED::ALARM(uint8_t ALARM_DATA){
+    switch(ALARM_DATA){
+        case 0:{        // NORMAL
+            myled2 = 0;
+            myled3 = 0;
+        }break;
+        case 1:{        // ALARM1
+            myled2 = 1;
+            myled3 = 0;            
+        }break;
+        case 2:{        // ALARM2
+            myled2 = 0;
+            myled3 = 1;            
+        }break;
+        case 3:{        // ALARM3
+            myled2 = 1;
+            myled3 = 1;            
+        }break;
+    }
+}
 int headlight_millis, sidelight_millis;
 void ROBOFRIEN_LED::update(uint8_t HD_PD, uint8_t HD_DR, uint8_t SD_PD, uint8_t SD_DR){
     //////// HEAD LIGHT /////////////
--- a/ROBOFRIEN_SUB_FUNC/ROBOFRIEN_LED.h	Tue Jun 12 01:05:50 2018 +0000
+++ b/ROBOFRIEN_SUB_FUNC/ROBOFRIEN_LED.h	Wed Nov 28 13:06:23 2018 +0000
@@ -10,6 +10,7 @@
 public:
     void Init();
     void update(uint8_t, uint8_t, uint8_t, uint8_t);
+    void ALARM(uint8_t);
     
 private:
 
--- a/ROBOFRIEN_SUB_FUNC/ROBOFRIEN_MOTOR.cpp	Tue Jun 12 01:05:50 2018 +0000
+++ b/ROBOFRIEN_SUB_FUNC/ROBOFRIEN_MOTOR.cpp	Wed Nov 28 13:06:23 2018 +0000
@@ -1,14 +1,14 @@
 #include "ROBOFRIEN_MOTOR.h"
 
-float PWM_TRIM[6] = {0.01, 0.01, 0.01, 0.01, 0.01, 0.01};
 float PWM_MIN = 1/3.0f;
 float PWM_MAX = 2/3.0f;
-PwmOut pwm1(p21);
-PwmOut pwm2(p22);
-PwmOut pwm3(p23);
-PwmOut pwm4(p24);
-PwmOut pwm5(p25);
-PwmOut pwm6(p26);
+
+PwmOut  pwm1(p21);
+PwmOut  pwm2(p22);
+PwmOut  pwm3(p23);
+PwmOut  pwm4(p24);
+PwmOut  pwm5(p25);
+PwmOut  pwm6(p26);
 
 void ROBOFRIEN_MOTOR::OFF(){
     pwm1.write(PWM_MIN);
@@ -36,14 +36,14 @@
     // Motor Power : 0 ~ 10000   
     float PWM_DATA[6];
     for(int i=0; i<6; i++){
-        PWM_DATA[i] = PWM_MIN + PWM_TRIM[i] + (1/3.0)*(Value[i]/10000.0);
+        PWM_DATA[i] = PWM_MIN + (PWM_MAX - PWM_MIN) * (Value[i]/10000.0);
         if(PWM_DATA[i] > PWM_MAX)PWM_DATA[i] = PWM_MAX;
     }
-    pwm1.period(PWM_DATA[0]);
-    pwm2.period(PWM_DATA[1]);
-    pwm3.period(PWM_DATA[2]);
-    pwm4.period(PWM_DATA[3]);
-    pwm5.period(PWM_DATA[4]);
-    pwm6.period(PWM_DATA[5]);
+    pwm1.write(PWM_DATA[0]);
+    pwm2.write(PWM_DATA[1]);
+    pwm3.write(PWM_DATA[2]);
+    pwm4.write(PWM_DATA[3]);
+    pwm5.write(PWM_DATA[4]);
+    pwm6.write(PWM_DATA[5]);
 }
 
--- a/ROBOFRIEN_SUB_FUNC/ROBOFRIEN_MOTOR.h	Tue Jun 12 01:05:50 2018 +0000
+++ b/ROBOFRIEN_SUB_FUNC/ROBOFRIEN_MOTOR.h	Wed Nov 28 13:06:23 2018 +0000
@@ -11,7 +11,7 @@
     void Init();
     void update();
     void OFF();
-    int16_t Value[6];
+    int16_t Value[6];       // 0 ~ 10000
 private:
 
 };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ROBOFRIEN_SUB_FUNC/ROBOFRIEN_PID.cpp	Wed Nov 28 13:06:23 2018 +0000
@@ -0,0 +1,37 @@
+#include "ROBOFRIEN_PID.h"
+
+
+#define OUTPUT_LIMIT      3000
+#define RAT_INTEGER_LIMIT   500
+void ROBOFRIEN_PID::Init(){
+    RAT_INTEGER[0] = 0;
+    RAT_INTEGER[1] = 0;
+    RAT_INTEGER[2] = 0;
+}
+
+void ROBOFRIEN_PID::update(){
+    output_Data[0] = err_Rate[0] * RAT_KP[0];       // P GAIN    
+    RAT_INTEGER[0] += err_Rate[0]/100.0 * RAT_KI[0];
+    output_Data[0] += RAT_INTEGER[0];
+    if(output_Data[0] > OUTPUT_LIMIT) output_Data[0] = OUTPUT_LIMIT;
+    else if(output_Data[0] < -OUTPUT_LIMIT) output_Data[0] = -OUTPUT_LIMIT;
+
+    output_Data[1] = err_Rate[1] * RAT_KP[1];       // P GAIN    
+    RAT_INTEGER[1] += err_Rate[1]/100.0 * RAT_KI[1];
+    output_Data[1] += RAT_INTEGER[1];
+    if(output_Data[1] > OUTPUT_LIMIT) output_Data[1] = OUTPUT_LIMIT;
+    else if(output_Data[1] < -OUTPUT_LIMIT) output_Data[1] = -OUTPUT_LIMIT;
+
+    output_Data[2] = err_Rate[2] * RAT_KP[2];       // P GAIN    
+    RAT_INTEGER[2] += err_Rate[2]/100.0 * RAT_KI[2];
+    output_Data[2] += RAT_INTEGER[2];
+    if(output_Data[2] > OUTPUT_LIMIT) output_Data[2] = OUTPUT_LIMIT;
+    else if(output_Data[2] < -OUTPUT_LIMIT) output_Data[2] = -OUTPUT_LIMIT;
+}
+
+void ROBOFRIEN_PID::RAT_INTEGER_RESET(){
+    RAT_INTEGER[0] = 0;
+    RAT_INTEGER[1] = 0;
+    RAT_INTEGER[2] = 0;
+}
+
--- a/ROBOFRIEN_SUB_FUNC/ROBOFRIEN_PID.h	Tue Jun 12 01:05:50 2018 +0000
+++ b/ROBOFRIEN_SUB_FUNC/ROBOFRIEN_PID.h	Wed Nov 28 13:06:23 2018 +0000
@@ -10,10 +10,13 @@
 public:
     void Init();
     void update( );
-    float err_Rate[3],err_Angle[3];
+    float err_Rate[3];
     float output_Data[3];
-    void ROLL_RATE_PID_RUN();
+    float RAT_KP[3], RAT_KD[3], RAT_KI[3];
+    float ANG_KP[3], ANG_KD[3], ANG_KI[3];
+    void RAT_INTEGER_RESET();
 private:
+    int16_t RAT_INTEGER[3];
 };
 
 #endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ROBOFRIEN_SUB_FUNC/ROBOFRIEN_SBUS.cpp	Wed Nov 28 13:06:23 2018 +0000
@@ -0,0 +1,115 @@
+#include "ROBOFRIEN_SBUS.h"
+#include "millis.h"
+#include "BufferedSerial.h"
+
+BufferedSerial SBUS_(p13,p14);
+
+#define CAP_MIN     487
+#define CAP_NEU     1024
+#define CAP_MAX     1561
+bool reverse_bool[16] = {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false};
+
+void ROBOFRIEN_SBUS::Init(){
+    SBUS_.baud(100000);
+    SBUS_.format(8, Serial::Even, 2);
+    CONTROLLER_STATE = SIGNAL_OFF;
+}
+
+uint8_t BIT_REVERSE(uint8_t INPUT){
+    uint8_t OUTPUT;
+    OUTPUT = INPUT << 7;
+    OUTPUT |= ( ((INPUT >> 1)&0b00000001) << 6 ); 
+    OUTPUT |= ( ((INPUT >> 2)&0b00000001) << 5 ); 
+    OUTPUT |= ( ((INPUT >> 3)&0b00000001) << 4 ); 
+    OUTPUT |= ( ((INPUT >> 4)&0b00000001) << 3 ); 
+    OUTPUT |= ( ((INPUT >> 5)&0b00000001) << 2 ); 
+    OUTPUT |= ( ((INPUT >> 6)&0b00000001) << 1 ); 
+    OUTPUT |= ( ((INPUT >> 7)&0b00000001) << 0 ); 
+    return OUTPUT;
+}
+uint16_t BIT11_REVERSE(uint16_t INPUT){
+    uint16_t OUTPUT;
+    INPUT = INPUT & 0b0000011111111111;
+    OUTPUT = INPUT << 10;
+    OUTPUT |= ( ((INPUT >> 1)&0b0000000000000001) << 9 ); 
+    OUTPUT |= ( ((INPUT >> 2)&0b0000000000000001) << 8 ); 
+    OUTPUT |= ( ((INPUT >> 3)&0b0000000000000001) << 7 ); 
+    OUTPUT |= ( ((INPUT >> 4)&0b0000000000000001) << 6 ); 
+    OUTPUT |= ( ((INPUT >> 5)&0b0000000000000001) << 5 ); 
+    OUTPUT |= ( ((INPUT >> 6)&0b0000000000000001) << 4 ); 
+    OUTPUT |= ( ((INPUT >> 7)&0b0000000000000001) << 3 ); 
+    OUTPUT |= ( ((INPUT >> 8)&0b0000000000000001) << 2 ); 
+    OUTPUT |= ( ((INPUT >> 9)&0b0000000000000001) << 1 ); 
+    OUTPUT |= ( ((INPUT >>10)&0b0000000000000001) << 0 ); 
+    OUTPUT = OUTPUT & 0b0000011111111111;
+    return OUTPUT;
+    
+}
+
+void ROBOFRIEN_SBUS::update(){
+    while( SBUS_.readable() > 0){
+        SBUS_ID[2] = SBUS_ID[1];
+        SBUS_ID[1] = SBUS_ID[0];
+        SBUS_ID[0] = BIT_REVERSE(SBUS_.getc());
+        SBUS_CNT ++;
+        if( start_bool == false ){
+            if( ( SBUS_ID[1] == 0b00000000 ) & ( SBUS_ID[0] == 0b11110000 ) ){
+                start_bool = true;
+                check_cnt = SBUS_CNT;
+                SBUS_CNT = 0;
+            }            
+        }else{
+            SBUS_BUFF[SBUS_CNT] = SBUS_ID[0];
+            if(SBUS_CNT == 24){
+                start_bool = false;
+                channel[ 0]  = ( (uint16_t)(SBUS_BUFF[ 1]&0b11111111)<<3 | (uint16_t)((uint16_t)SBUS_BUFF[ 2]&0b11100000)>>5 );
+                channel[ 1]  = ( (int16_t)(SBUS_BUFF[ 2]&0b00011111)<<6 | (int16_t)(SBUS_BUFF[ 3]&0b11111100)>>2 );
+                channel[ 2]  = ( (int16_t)(SBUS_BUFF[ 3]&0b00000011)<<9 | (int16_t)(SBUS_BUFF[ 4]&0b11111111)<<1 | (int16_t)(SBUS_BUFF[5]&0b10000000)>>7 );
+                channel[ 3]  = ( (int16_t)(SBUS_BUFF[ 5]&0b01111111)<<4 | (int16_t)(SBUS_BUFF[ 6]&0b11110000)>>4 );
+                channel[ 4]  = ( (int16_t)(SBUS_BUFF[ 6]&0b00001111)<<7 | (int16_t)(SBUS_BUFF[ 7]&0b11111110)>>1 );
+                channel[ 5]  = ( (int16_t)(SBUS_BUFF[ 7]&0b00000001)<<10| (int16_t)(SBUS_BUFF[ 8]&0b11111111)<<2 | (int16_t)(SBUS_BUFF[9]&0b11000000)>>6 );
+                channel[ 6]  = ( (int16_t)(SBUS_BUFF[ 9]&0b00111111)<<5 | (int16_t)(SBUS_BUFF[10]&0b11111000)>>3 );
+                channel[ 7]  = ( (int16_t)(SBUS_BUFF[10]&0b00000111)<<8 | (int16_t)(SBUS_BUFF[11]&0b11111111)>>0 );
+                channel[ 8]  = ( (int16_t)(SBUS_BUFF[11]&0b11111111)<<3 | (int16_t)(SBUS_BUFF[12]&0b11100000)>>5 );
+                channel[ 9]  = ( (int16_t)(SBUS_BUFF[12]&0b00011111)<<6 | (int16_t)(SBUS_BUFF[13]&0b11111100)>>2 );
+                channel[10]  = ( (int16_t)(SBUS_BUFF[13]&0b00000011)<<9 | (int16_t)(SBUS_BUFF[14]&0b11111111)<<1 | (int16_t)(SBUS_BUFF[15]&0b10000000)>>7 );
+                channel[11]  = ( (int16_t)(SBUS_BUFF[15]&0b01111111)<<4 | (int16_t)(SBUS_BUFF[16]&0b11110000)>>4 );
+                channel[12]  = ( (int16_t)(SBUS_BUFF[16]&0b00001111)<<7 | (int16_t)(SBUS_BUFF[17]&0b11111110)>>1 );
+                channel[13]  = ( (int16_t)(SBUS_BUFF[17]&0b00000001)<<10| (int16_t)(SBUS_BUFF[18]&0b11111111)<<2 | (int16_t)(SBUS_BUFF[19]&0b11000000)>>6 );
+                channel[14]  = ( (int16_t)(SBUS_BUFF[19]&0b00111111)<<5 | (int16_t)(SBUS_BUFF[20]&0b11111000)>>3 );
+                channel[15]  = ( (int16_t)(SBUS_BUFF[20]&0b00000111)<<8 | (int16_t)(SBUS_BUFF[21]&0b11111111)>>0 );
+                for(int i=0; i<16; i++){
+                    channel[ i]  = BIT11_REVERSE(channel[ i]);
+                    if( channel[i] < CAP_MIN ) channel[i] = CAP_MIN;
+                    else if( channel[i] > CAP_MAX ) channel[i] = CAP_MAX;
+                    channel[i] = (channel[i] - 1024) * 1000 / 537.0;
+                    // 487, 1024, 1561 //  RANGE : -1000 ~ 1000
+                }
+                if( channel[4] < -500 ){            // Motor OFF
+                    CONTROLLER_STATE = MOTOR_OFF;
+                }else if( channel[4] < 500) {       // Manual Mode
+                    if( channel[7] < -500){         // Manual - Attitude Mode
+                        if( channel[2] < -950){
+                            CONTROLLER_STATE = MOTOR_OFF;
+                        }else{
+                            CONTROLLER_STATE = MANUAL_ATTITUDE;                            
+                        }
+                    }else if( channel[7] < 500){    // Manual - Velocity Mode
+                        CONTROLLER_STATE = MANUAL_VELOCITY;  
+                    }else{                          // Manual - Position Mode
+                        CONTROLLER_STATE = MANUAL_POSITION;                          
+                    }
+                }else{                              // Auto Flight Mode
+                    CONTROLLER_STATE = AUTO_FLIGHT;                                                                      
+                    if( channel[ 5] < -500){
+                        HOMEPOINT_BOOL = false;
+                    }else if( channel[ 5] > 500){
+                        HOMEPOINT_BOOL = true;
+                    }else{
+                        HOMEPOINT_BOOL = false;
+                    }
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ROBOFRIEN_SUB_FUNC/ROBOFRIEN_SBUS.h	Wed Nov 28 13:06:23 2018 +0000
@@ -0,0 +1,38 @@
+#ifndef MBED_ROBOFRIEN_SBUS_H
+#define MBED_ROBOFRIEN_SBUS_H
+
+#include "mbed.h"
+
+
+#define SIGNAL_OFF              0
+#define MOTOR_OFF               1
+#define MANUAL_ATTITUDE         2
+#define MANUAL_VELOCITY         3
+#define MANUAL_POSITION         4
+#define AUTO_FLIGHT             5
+#define HOME_POINT              6
+
+class ROBOFRIEN_SBUS {
+public:
+    void Init();
+    void update();
+    bool end_bool,start_bool;  
+    bool read_check;  
+    int16_t channel[16];            // Range : -1000 ~ 1000
+    int check_cnt;
+    uint8_t CONTROLLER_STATE;
+    /* **** CONTROL STATE **** */
+    // 0 = SIGNAL OFF
+    // 1 = MOTOR OFF
+    // 2 = MANUAL - ATTITUDE
+    // 3 = MANUAL - VELOCITY
+    // 4 = MANUAL - POSITION
+    // 5 = AUTO FLIGHT
+    bool HOMEPOINT_BOOL;
+private:
+    uint8_t SBUS_CNT;
+    uint8_t SBUS_ID[3];
+    uint8_t SBUS_BUFF[25];
+};
+
+#endif
\ No newline at end of file
--- a/ROBOFRIEN_SUB_FUNC/ROBOFRIE_PID.cpp	Tue Jun 12 01:05:50 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-#include "ROBOFRIEN_PID.h"
-#include "PID.h"
-
-#define RATE 0.01
-PID ROLL_RATE_PID(10.0, 0.0, 0.0, RATE);
-
-void ROBOFRIEN_PID::Init(){
-    ROLL_RATE_PID.setInputLimits(0.0, 10.0);
-    ROLL_RATE_PID.setOutputLimits(0.0, 1.0);
-    ROLL_RATE_PID.setMode(AUTO_MODE);
-    ROLL_RATE_PID.setSetPoint(err_Angle[0]);
-}
-
-void ROBOFRIEN_PID::ROLL_RATE_PID_RUN(){
-    if(err_Rate[0] >= 0){
-        ROLL_RATE_PID.setProcessValue(err_Rate[0]);
-        output_Data[0] = ROLL_RATE_PID.compute();
-    }
-    else{
-        ROLL_RATE_PID.setProcessValue(-err_Rate[0]);
-        output_Data[0] = -ROLL_RATE_PID.compute();
-    }
-}
-
-void ROBOFRIEN_PID::update(){
-    ROLL_RATE_PID_RUN();
-}
-
-
--- a/ROBOFRIEN_SUB_FUNC/eeprom.h	Tue Jun 12 01:05:50 2018 +0000
+++ b/ROBOFRIEN_SUB_FUNC/eeprom.h	Wed Nov 28 13:06:23 2018 +0000
@@ -1,33 +1,64 @@
-#define eeprom_length 256
+#define eeprom_length 255
 
 
 LocalFileSystem local("local");               // Create the local filesystem under the name "local"
 
 volatile int eeprom_address[eeprom_length],eeprom_data[eeprom_length];
 void eeprom_init(){
+    int eeprom_chksum;
     FILE *file = fopen("/local/eeprom.txt", "r");  // Open "out.txt" on the local file system for writing    
     if(file == NULL){
         FILE *file = fopen("/local/eeprom.txt", "w");   // Write "out.txt ~~//
         for(int i=0; i<eeprom_length; i++){
             fprintf(file, "%d\t%d\r\n", i, 0);   
+            wait(0.0001);
         }        
-        fclose(file);
     }else{
         for(int i=0; i<eeprom_length; i++) {eeprom_address[i] = 0; eeprom_data[i] = 0; }
         for(int i=0; i<eeprom_length; i++){
             fscanf(file,"%d\t%d\r\n",&eeprom_address[i], &eeprom_data[i]);
-        }        
+            wait(0.0001);
+        }
+        int tmp;
+        fscanf(file,"%d\t%d\t\n",&tmp, &eeprom_chksum);
     }
     fclose(file);
+    int cal_eeprom_chksum = 0;
+    for(int i=0; i<eeprom_length; i++){
+        cal_eeprom_chksum += eeprom_data[i];
+    }
+    if( cal_eeprom_chksum != eeprom_chksum){
+        while(1){
+            DigitalOut myled1(LED1);
+            DigitalOut myled2(LED2);
+            DigitalOut myled3(LED3);
+            DigitalOut myled4(LED4);
+            myled1 = 1; myled2 = 1; myled3 = 1; myled4 = 1;
+            wait(1);
+            myled1 = 0; myled2 = 0; myled3 = 0; myled4 = 0;
+            wait(1);
+        }
+    }
 }
 
-void eeprom_refresh(){
+bool eeprom_refresh(){
     /// Write Data to EEPROM //
+    bool OUTPUT_VALUE = false;
+    int eeprom_chksum = 0;
+    __disable_irq();
     FILE *file = fopen("/local/eeprom.txt", "w");  // Open "out.txt" on the local file system for writing    
-    for(int i=0; i<eeprom_length; i++){
-        fprintf(file,"%d\t%d\r\n",i, eeprom_data[i]);
-    }
-    fclose(file);            
+//    if(file != NULL){
+        OUTPUT_VALUE = true;
+        for(int i=0; i<eeprom_length; i++){
+            fprintf(file,"%d\t%d\r\n",i, eeprom_data[i]);
+            wait(0.0001);
+            eeprom_chksum += eeprom_data[i];
+        }
+        fprintf(file,"%d\t%d",eeprom_length,eeprom_chksum);    
+//    }
+    fclose(file);
+    __enable_irq();
+    return OUTPUT_VALUE;
 }
 
 void eeprom_write(int addr, int data){
@@ -41,10 +72,3 @@
     
 }
 
-void eeprom_reset(){
-    FILE *file = fopen("/local/eeprom.txt", "w");  // Open "out.txt" on the local file system for writing    
-    for(int i=0; i<256; i++){
-        fprintf(file, "%d\t%d\r\n", i,0);   
-    }    
-    fclose(file);
-}
--- a/SPATIAL/SPATIAL.cpp	Tue Jun 12 01:05:50 2018 +0000
+++ b/SPATIAL/SPATIAL.cpp	Wed Nov 28 13:06:23 2018 +0000
@@ -7,6 +7,18 @@
 
 BufferedSerial SPATIAL_UART(p28, p27);      // tx, rx
 
+/* ****** 100Hz Receive ********** */
+// Packet ID : 42, Length : 12  --> Angural Velocity X,Y,Z (rad/s)
+// Packet ID : 39, Length : 12  --> Roll, Pitch, Yaw (rad)
+
+/* ****** 10Hz Receive *********** */
+// Packet ID : 35, Length = 12  --> NED Velocity X, Y, Z (m/s)
+// Packet ID : 32, Length = 24  --> System State Packet
+
+/* ****** 1Hz Receive *********** */
+// Packet ID : 22, Length = 14  --> Time Packet
+// Packet ID : 30, Length = 13  --> Satellites Packet
+
 //float 이랑 double 값뽑을때 쓰는거
 union FP8
 {
@@ -30,7 +42,12 @@
     return crc;
 }
 
-void SPATIAL::Init(){
+void SPATIAL::Init(int sensor_wait_input){
+    if( sensor_wait_input == 1){
+        SENSOR_WAIT_BOOL = true;
+    }else{
+        SENSOR_WAIT_BOOL = false;
+    }
     SPATIAL_UART.baud(115200);   
 }
 //이것은 SPATIAL에서 전송되는 각종 데이터를 받는 부분이다.
@@ -39,142 +56,281 @@
   while(SPATIAL_UART.readable() > 0) 
   {
     SPATIAL_ID[4] = SPATIAL_ID[3]; SPATIAL_ID[3] = SPATIAL_ID[2]; SPATIAL_ID[2] = SPATIAL_ID[1]; SPATIAL_ID[1] = SPATIAL_ID[0]; SPATIAL_ID[0] = SPATIAL_UART.getc();
-    if(SPATIAL_ID_20_BOOL == true){
-      SPATIAL_BUF[SPATIAL_BUF_CNT] = SPATIAL_ID[0];
-      if(SPATIAL_BUF_CNT >= 100){ SPATIAL_ID_20_BOOL = false; SPATIAL_ID_20_PARSING_BOOL = true;}
+    if((SPATIAL_ID_39_BOOL == true)|(SPATIAL_ID_42_BOOL == true)|(SPATIAL_ID_35_BOOL == true)|(SPATIAL_ID_32_BOOL == true)|(SPATIAL_ID_22_BOOL == true)|(SPATIAL_ID_30_BOOL == true)){
+//      SPATIAL_BUF[SPATIAL_BUF_CNT] = SPATIAL_ID[0];
+      if(SPATIAL_ID_39_BOOL == true) {
+          SPATIAL_39_BUF[SPATIAL_BUF_CNT] = SPATIAL_ID[0];
+          if(SPATIAL_BUF_CNT >= 12){ SPATIAL_ID_39_BOOL = false; SPATIAL_ID_39_PARSING_BOOL = true;}
+      }else if(SPATIAL_ID_42_BOOL == true) {
+          SPATIAL_42_BUF[SPATIAL_BUF_CNT] = SPATIAL_ID[0];
+          if(SPATIAL_BUF_CNT >= 12){ SPATIAL_ID_42_BOOL = false; SPATIAL_ID_42_PARSING_BOOL = true;} 
+      }else if(SPATIAL_ID_35_BOOL == true) {
+          SPATIAL_35_BUF[SPATIAL_BUF_CNT] = SPATIAL_ID[0];
+          if(SPATIAL_BUF_CNT >= 12){ SPATIAL_ID_35_BOOL = false; SPATIAL_ID_35_PARSING_BOOL = true;} 
+      }else if(SPATIAL_ID_32_BOOL == true) {
+          SPATIAL_32_BUF[SPATIAL_BUF_CNT] = SPATIAL_ID[0];
+          if(SPATIAL_BUF_CNT >= 24){ SPATIAL_ID_32_BOOL = false; SPATIAL_ID_32_PARSING_BOOL = true;} 
+      }else if(SPATIAL_ID_22_BOOL == true) {
+          SPATIAL_22_BUF[SPATIAL_BUF_CNT] = SPATIAL_ID[0];
+          if(SPATIAL_BUF_CNT >= 14){ SPATIAL_ID_22_BOOL = false; SPATIAL_ID_22_PARSING_BOOL = true;} 
+      }else if(SPATIAL_ID_30_BOOL == true) {
+          SPATIAL_30_BUF[SPATIAL_BUF_CNT] = SPATIAL_ID[0];
+          if(SPATIAL_BUF_CNT >= 13){ SPATIAL_ID_30_BOOL = false; SPATIAL_ID_30_PARSING_BOOL = true;} 
+      }
       SPATIAL_BUF_CNT ++;
     }
     else{
-      if((SPATIAL_ID[3] == 20) & (SPATIAL_ID[2] == 100))    //두번째 데이터가 '패킷넘버', 세번째 데이터가 '데이터랭쓰'임... 별도의 SOF가 없어서 이걸 기준으로함.
+      if((SPATIAL_ID[3] == 39) & (SPATIAL_ID[2] == 12))    //두번째 데이터가 '패킷넘버', 세번째 데이터가 '데이터랭쓰'임... 별도의 SOF가 없어서 이걸 기준으로함.
+      {
+        //첫 번째 데이터 : head LRC이며 계산식 돌린거랑 첫번째 데이터랑 일치하면 이 배열을 쓸거라는 의미.
+        if((uint8_t)((((uint32_t)SPATIAL_ID[3] + (uint32_t)SPATIAL_ID[2] + (uint32_t)SPATIAL_ID[1] + (uint32_t)SPATIAL_ID[0]) ^ 0xFF) + 1) == (uint8_t)SPATIAL_ID[4])
+        {
+          SPATIAL_ID_39_BOOL = true;
+          CRC_INPUT = (uint16_t)SPATIAL_ID[0]<<8 | (uint16_t)SPATIAL_ID[1];
+          SPATIAL_BUF_CNT = 0;
+        }
+      }        
+      else if((SPATIAL_ID[3] == 42) & (SPATIAL_ID[2] == 12))    //두번째 데이터가 '패킷넘버', 세번째 데이터가 '데이터랭쓰'임... 별도의 SOF가 없어서 이걸 기준으로함.
       {
         //첫 번째 데이터 : head LRC이며 계산식 돌린거랑 첫번째 데이터랑 일치하면 이 배열을 쓸거라는 의미.
         if((uint8_t)((((uint32_t)SPATIAL_ID[3] + (uint32_t)SPATIAL_ID[2] + (uint32_t)SPATIAL_ID[1] + (uint32_t)SPATIAL_ID[0]) ^ 0xFF) + 1) == (uint8_t)SPATIAL_ID[4])
         {
-          SPATIAL_ID_20_BOOL = true;
+          SPATIAL_ID_42_BOOL = true;
+          CRC_INPUT = (uint16_t)SPATIAL_ID[0]<<8 | (uint16_t)SPATIAL_ID[1];
+          SPATIAL_BUF_CNT = 0;
+        }
+      }        
+      else if((SPATIAL_ID[3] == 35) & (SPATIAL_ID[2] == 12))    //두번째 데이터가 '패킷넘버', 세번째 데이터가 '데이터랭쓰'임... 별도의 SOF가 없어서 이걸 기준으로함.
+      {
+        //첫 번째 데이터 : head LRC이며 계산식 돌린거랑 첫번째 데이터랑 일치하면 이 배열을 쓸거라는 의미.
+        if((uint8_t)((((uint32_t)SPATIAL_ID[3] + (uint32_t)SPATIAL_ID[2] + (uint32_t)SPATIAL_ID[1] + (uint32_t)SPATIAL_ID[0]) ^ 0xFF) + 1) == (uint8_t)SPATIAL_ID[4])
+        {
+          SPATIAL_ID_35_BOOL = true;
+          CRC_INPUT = (uint16_t)SPATIAL_ID[0]<<8 | (uint16_t)SPATIAL_ID[1];
+          SPATIAL_BUF_CNT = 0;
+        }
+      }        
+      else if((SPATIAL_ID[3] == 32) & (SPATIAL_ID[2] == 24))    //두번째 데이터가 '패킷넘버', 세번째 데이터가 '데이터랭쓰'임... 별도의 SOF가 없어서 이걸 기준으로함.
+      {
+        //첫 번째 데이터 : head LRC이며 계산식 돌린거랑 첫번째 데이터랑 일치하면 이 배열을 쓸거라는 의미.
+        if((uint8_t)((((uint32_t)SPATIAL_ID[3] + (uint32_t)SPATIAL_ID[2] + (uint32_t)SPATIAL_ID[1] + (uint32_t)SPATIAL_ID[0]) ^ 0xFF) + 1) == (uint8_t)SPATIAL_ID[4])
+        {
+          SPATIAL_ID_32_BOOL = true;
+          CRC_INPUT = (uint16_t)SPATIAL_ID[0]<<8 | (uint16_t)SPATIAL_ID[1];
+          SPATIAL_BUF_CNT = 0;
+        }
+      }        
+      else if((SPATIAL_ID[3] == 22) & (SPATIAL_ID[2] == 14))    //두번째 데이터가 '패킷넘버', 세번째 데이터가 '데이터랭쓰'임... 별도의 SOF가 없어서 이걸 기준으로함.
+      {
+        //첫 번째 데이터 : head LRC이며 계산식 돌린거랑 첫번째 데이터랑 일치하면 이 배열을 쓸거라는 의미.
+        if((uint8_t)((((uint32_t)SPATIAL_ID[3] + (uint32_t)SPATIAL_ID[2] + (uint32_t)SPATIAL_ID[1] + (uint32_t)SPATIAL_ID[0]) ^ 0xFF) + 1) == (uint8_t)SPATIAL_ID[4])
+        {
+          SPATIAL_ID_22_BOOL = true;
+          CRC_INPUT = (uint16_t)SPATIAL_ID[0]<<8 | (uint16_t)SPATIAL_ID[1];
+          SPATIAL_BUF_CNT = 0;
+        }
+      }        
+      else if((SPATIAL_ID[3] == 30) & (SPATIAL_ID[2] == 13))    //두번째 데이터가 '패킷넘버', 세번째 데이터가 '데이터랭쓰'임... 별도의 SOF가 없어서 이걸 기준으로함.
+      {
+        //첫 번째 데이터 : head LRC이며 계산식 돌린거랑 첫번째 데이터랑 일치하면 이 배열을 쓸거라는 의미.
+        if((uint8_t)((((uint32_t)SPATIAL_ID[3] + (uint32_t)SPATIAL_ID[2] + (uint32_t)SPATIAL_ID[1] + (uint32_t)SPATIAL_ID[0]) ^ 0xFF) + 1) == (uint8_t)SPATIAL_ID[4])
+        {
+          SPATIAL_ID_30_BOOL = true;
           CRC_INPUT = (uint16_t)SPATIAL_ID[0]<<8 | (uint16_t)SPATIAL_ID[1];
           SPATIAL_BUF_CNT = 0;
         }
       }        
     }
   }
+    SPATIAL_ID_42_Parsing();
+    SPATIAL_ID_39_Parsing();
+    SPATIAL_ID_35_Parsing();
+    SPATIAL_ID_32_Parsing();
+    SPATIAL_ID_22_Parsing();
+    SPATIAL_ID_30_Parsing();
+}
+
+void SPATIAL::SPATIAL_ID_22_Parsing(){
+    if(SPATIAL_ID_22_PARSING_BOOL == true){
+        SPATIAL_ID_22_PARSING_BOOL = false;
+        if(CRC_INPUT == calculate_crc16(SPATIAL_22_BUF,14)){
+            UNIX_TIME = (uint32_t)SPATIAL_22_BUF[0] + (uint32_t)SPATIAL_22_BUF[13]*100 + (uint32_t)SPATIAL_22_BUF[12]*10000 + (uint32_t)SPATIAL_22_BUF[11]*1000000;        
+        }   
+    }    
+}
+void SPATIAL::SPATIAL_ID_30_Parsing(){
+    if(SPATIAL_ID_30_PARSING_BOOL == true){
+        SPATIAL_ID_30_PARSING_BOOL = false;
+//            SATELLITE_NUM ++;
+//        if(CRC_INPUT == calculate_crc16(SPATIAL_30_BUF,13)){
+            SATELLITE_NUM = SPATIAL_30_BUF[8] + SPATIAL_30_BUF[9] + SPATIAL_30_BUF[10] + SPATIAL_30_BUF[11] + SPATIAL_30_BUF[12];
+//        }   
+    }    
 }
 
-void SPATIAL::SPATIAL_ID_20_Parsing()      //데이터 파싱을 실시함 여기서.
-{    
-    if(SPATIAL_ID_20_PARSING_BOOL == true)
-    {
-        SPATIAL_ID_20_PARSING_BOOL = false;
+void SPATIAL::SPATIAL_ID_35_Parsing(){
+    if(SPATIAL_ID_35_PARSING_BOOL == true){
+        SPATIAL_ID_35_PARSING_BOOL = false;
+        if(CRC_INPUT == calculate_crc16(SPATIAL_35_BUF,12)){
+            FP4 SPATIAL_Vx;       //이 과정은 4바이트로 흩어진 것을 하나의 float형으로 모으는 과정..
+            SPATIAL_Vx.DATA4[0] = SPATIAL_35_BUF[0];
+            SPATIAL_Vx.DATA4[1] = SPATIAL_35_BUF[1];
+            SPATIAL_Vx.DATA4[2] = SPATIAL_35_BUF[2];
+            SPATIAL_Vx.DATA4[3] = SPATIAL_35_BUF[3];
+            Vx = SPATIAL_Vx.F4;    //float형으로 짠. 단위는 역시 rad라서 고침.            
+            
+            FP4 SPATIAL_Vy;       //이 과정은 4바이트로 흩어진 것을 하나의 float형으로 모으는 과정..
+            SPATIAL_Vy.DATA4[0] = SPATIAL_35_BUF[4];
+            SPATIAL_Vy.DATA4[1] = SPATIAL_35_BUF[5];
+            SPATIAL_Vy.DATA4[2] = SPATIAL_35_BUF[6];
+            SPATIAL_Vy.DATA4[3] = SPATIAL_35_BUF[7];
+            Vy = SPATIAL_Vy.F4;    //float형으로 짠. 단위는 역시 rad라서 고침.            
+    
+            FP4 SPATIAL_Vz;       //이 과정은 4바이트로 흩어진 것을 하나의 float형으로 모으는 과정..
+            SPATIAL_Vz.DATA4[0] = SPATIAL_35_BUF[8];
+            SPATIAL_Vz.DATA4[1] = SPATIAL_35_BUF[9];
+            SPATIAL_Vz.DATA4[2] = SPATIAL_35_BUF[10];
+            SPATIAL_Vz.DATA4[3] = SPATIAL_35_BUF[11];
+            Vz = SPATIAL_Vz.F4;    //float형으로 짠. 단위는 역시 rad라서 고침.                
+            Vz = -Vz;
+            
+            /* ********** ECEF to Compass Heading ***** */
+            float B_Vx,B_Vy;
+            B_Vx = Vx * cos(YAW*M_PI/180.0) + Vy * sin(YAW*M_PI/180.0);
+            B_Vy = Vy * cos(YAW*M_PI/180.0) - Vx * sin(YAW*M_PI/180.0);
+            Vx = B_Vx;
+            Vy = B_Vy;
+        }   
+    }    
+}
+void SPATIAL::SPATIAL_ID_32_Parsing(){
+    if(SPATIAL_ID_32_PARSING_BOOL == true){
+        SPATIAL_ID_32_PARSING_BOOL = false;
+        if(CRC_INPUT == calculate_crc16(SPATIAL_32_BUF,24)){
+            HZ_CNT++;
+/*
+            SYSTEM_STATUS = (uint16_t)SPATIAL_32_BUF[0]<<8 | (uint16_t)SPATIAL_32_BUF[1];
+            FILTER_STATUS = (uint16_t)SPATIAL_32_BUF[2]<<8 | (uint16_t)SPATIAL_32_BUF[3];
 
-        if(CRC_INPUT == calculate_crc16(SPATIAL_BUF,100)){
-            UNIX_TIME = (uint32_t)SPATIAL_BUF[3]<<24 | (uint32_t)SPATIAL_BUF[4]<<16 | (uint32_t)SPATIAL_BUF[5]<<8 | (uint32_t)SPATIAL_BUF[6];        
-            UNIX_TIME /= 1000;
+            UNIX_TIME = (uint32_t)SPATIAL_32_BUF[4]<<24 | (uint32_t)SPATIAL_32_BUF[5]<<16 | (uint32_t)SPATIAL_32_BUF[6]<<8 | (uint32_t)SPATIAL_32_BUF[7];        
+            UNIX_TIME /= 100000;
+*/
             FP8 SPATIAL_LATITUDE;       //이 과정은 8바이트로 흩어진 것을 하나의 double형으로 모으는 과정..
-            SPATIAL_LATITUDE.DATA8[0] = SPATIAL_BUF[12];
-            SPATIAL_LATITUDE.DATA8[1] = SPATIAL_BUF[13];
-            SPATIAL_LATITUDE.DATA8[2] = SPATIAL_BUF[14];
-            SPATIAL_LATITUDE.DATA8[3] = SPATIAL_BUF[15];
-            SPATIAL_LATITUDE.DATA8[4] = SPATIAL_BUF[16];
-            SPATIAL_LATITUDE.DATA8[5] = SPATIAL_BUF[17];
-            SPATIAL_LATITUDE.DATA8[6] = SPATIAL_BUF[18];
-            SPATIAL_LATITUDE.DATA8[7] = SPATIAL_BUF[19];       //얘들을 모아서.     
+            SPATIAL_LATITUDE.DATA8[0] = SPATIAL_32_BUF[0];
+            SPATIAL_LATITUDE.DATA8[1] = SPATIAL_32_BUF[1];
+            SPATIAL_LATITUDE.DATA8[2] = SPATIAL_32_BUF[2];
+            SPATIAL_LATITUDE.DATA8[3] = SPATIAL_32_BUF[3];
+            SPATIAL_LATITUDE.DATA8[4] = SPATIAL_32_BUF[4];
+            SPATIAL_LATITUDE.DATA8[5] = SPATIAL_32_BUF[5];
+            SPATIAL_LATITUDE.DATA8[6] = SPATIAL_32_BUF[6];
+            SPATIAL_LATITUDE.DATA8[7] = SPATIAL_32_BUF[7];       //얘들을 모아서.     
             LATITUDE = SPATIAL_LATITUDE.F8 * RADIANS_TO_DEGREES;    //double형으로 짠. 라디안이라 고침.
     
     
     
             FP8 SPATIAL_LONGITUDE;       //이 과정은 8바이트로 흩어진 것을 하나의 double형으로 모으는 과정..
-            SPATIAL_LONGITUDE.DATA8[0] = SPATIAL_BUF[20];
-            SPATIAL_LONGITUDE.DATA8[1] = SPATIAL_BUF[21];
-            SPATIAL_LONGITUDE.DATA8[2] = SPATIAL_BUF[22];
-            SPATIAL_LONGITUDE.DATA8[3] = SPATIAL_BUF[23];
-            SPATIAL_LONGITUDE.DATA8[4] = SPATIAL_BUF[24];
-            SPATIAL_LONGITUDE.DATA8[5] = SPATIAL_BUF[25];
-            SPATIAL_LONGITUDE.DATA8[6] = SPATIAL_BUF[26];
-            SPATIAL_LONGITUDE.DATA8[7] = SPATIAL_BUF[27];       //얘들을 모아서.     
+            SPATIAL_LONGITUDE.DATA8[0] = SPATIAL_32_BUF[8];
+            SPATIAL_LONGITUDE.DATA8[1] = SPATIAL_32_BUF[9];
+            SPATIAL_LONGITUDE.DATA8[2] = SPATIAL_32_BUF[10];
+            SPATIAL_LONGITUDE.DATA8[3] = SPATIAL_32_BUF[11];
+            SPATIAL_LONGITUDE.DATA8[4] = SPATIAL_32_BUF[12];
+            SPATIAL_LONGITUDE.DATA8[5] = SPATIAL_32_BUF[13];
+            SPATIAL_LONGITUDE.DATA8[6] = SPATIAL_32_BUF[14];
+            SPATIAL_LONGITUDE.DATA8[7] = SPATIAL_32_BUF[15];       //얘들을 모아서.     
             LONGITUDE = SPATIAL_LONGITUDE.F8 * RADIANS_TO_DEGREES;    //double형으로 짠. 라디안이라 고침.
     
     
             FP8 SPATIAL_HEIGHT;       //이 과정은 8바이트로 흩어진 것을 하나의 double형으로 모으는 과정..
-            SPATIAL_HEIGHT.DATA8[0] = SPATIAL_BUF[28];
-            SPATIAL_HEIGHT.DATA8[1] = SPATIAL_BUF[29];
-            SPATIAL_HEIGHT.DATA8[2] = SPATIAL_BUF[30];
-            SPATIAL_HEIGHT.DATA8[3] = SPATIAL_BUF[31];
-            SPATIAL_HEIGHT.DATA8[4] = SPATIAL_BUF[32];
-            SPATIAL_HEIGHT.DATA8[5] = SPATIAL_BUF[33];
-            SPATIAL_HEIGHT.DATA8[6] = SPATIAL_BUF[34];
-            SPATIAL_HEIGHT.DATA8[7] = SPATIAL_BUF[35];       //얘들을 모아서.     
-            HEIGHT = SPATIAL_HEIGHT.F8 * RADIANS_TO_DEGREES;    //double형으로 짠. 라디안이라 고침.
-    
-    
-            FP4 SPATIAL_Vn;       //이 과정은 4바이트로 흩어진 것을 하나의 float형으로 모으는 과정..
-            SPATIAL_Vn.DATA4[0] = SPATIAL_BUF[36];
-            SPATIAL_Vn.DATA4[1] = SPATIAL_BUF[37];
-            SPATIAL_Vn.DATA4[2] = SPATIAL_BUF[38];
-            SPATIAL_Vn.DATA4[3] = SPATIAL_BUF[39];
-            Vn = SPATIAL_Vn.F4;    //float형으로 짠. 단위는 역시 rad라서 고침.            
-    
-    
-            FP4 SPATIAL_Ve;       //이 과정은 4바이트로 흩어진 것을 하나의 float형으로 모으는 과정..
-            SPATIAL_Ve.DATA4[0] = SPATIAL_BUF[40];
-            SPATIAL_Ve.DATA4[1] = SPATIAL_BUF[41];
-            SPATIAL_Ve.DATA4[2] = SPATIAL_BUF[42];
-            SPATIAL_Ve.DATA4[3] = SPATIAL_BUF[43];
-            Ve = SPATIAL_Ve.F4;    //float형으로 짠. 단위는 역시 rad라서 고침.            
-    
-            FP4 SPATIAL_Vd;       //이 과정은 4바이트로 흩어진 것을 하나의 float형으로 모으는 과정..
-            SPATIAL_Vd.DATA4[0] = SPATIAL_BUF[44];
-            SPATIAL_Vd.DATA4[1] = SPATIAL_BUF[45];
-            SPATIAL_Vd.DATA4[2] = SPATIAL_BUF[46];
-            SPATIAL_Vd.DATA4[3] = SPATIAL_BUF[47];
-            Vd = SPATIAL_Vd.F4;    //float형으로 짠. 단위는 역시 rad라서 고침.            
-    
-            Vd = -Vd;
-            
+            SPATIAL_HEIGHT.DATA8[0] = SPATIAL_32_BUF[16];
+            SPATIAL_HEIGHT.DATA8[1] = SPATIAL_32_BUF[17];
+            SPATIAL_HEIGHT.DATA8[2] = SPATIAL_32_BUF[18];
+            SPATIAL_HEIGHT.DATA8[3] = SPATIAL_32_BUF[19];
+            SPATIAL_HEIGHT.DATA8[4] = SPATIAL_32_BUF[20];
+            SPATIAL_HEIGHT.DATA8[5] = SPATIAL_32_BUF[21];
+            SPATIAL_HEIGHT.DATA8[6] = SPATIAL_32_BUF[22];
+            SPATIAL_HEIGHT.DATA8[7] = SPATIAL_32_BUF[23];       //얘들을 모아서.     
+            HEIGHT = SPATIAL_HEIGHT.F8;    //double형으로 짠. 라디안이라 고침.
+             
+        }   
+    }    
+}
+void SPATIAL::SPATIAL_ID_39_Parsing(){
+    if(SPATIAL_ID_39_PARSING_BOOL == true){
+        SPATIAL_ID_39_PARSING_BOOL = false;
+        if(CRC_INPUT == calculate_crc16(SPATIAL_39_BUF,12)){
             FP4 SPATIAL_ROLL;       //이 과정은 4바이트로 흩어진 것을 하나의 float형으로 모으는 과정..
-            SPATIAL_ROLL.DATA4[0] = SPATIAL_BUF[64];
-            SPATIAL_ROLL.DATA4[1] = SPATIAL_BUF[65];
-            SPATIAL_ROLL.DATA4[2] = SPATIAL_BUF[66];
-            SPATIAL_ROLL.DATA4[3] = SPATIAL_BUF[67];
+            SPATIAL_ROLL.DATA4[0] = SPATIAL_39_BUF[0];
+            SPATIAL_ROLL.DATA4[1] = SPATIAL_39_BUF[1];
+            SPATIAL_ROLL.DATA4[2] = SPATIAL_39_BUF[2];
+            SPATIAL_ROLL.DATA4[3] = SPATIAL_39_BUF[3];
             ROLL = SPATIAL_ROLL.F4 * RADIANS_TO_DEGREES;    //float형으로 짠. 단위는 역시 rad라서 고침.            
-    
+
             FP4 SPATIAL_PITCH;       //이 과정은 4바이트로 흩어진 것을 하나의 float형으로 모으는 과정..
-            SPATIAL_PITCH.DATA4[0] = SPATIAL_BUF[68];
-            SPATIAL_PITCH.DATA4[1] = SPATIAL_BUF[69];
-            SPATIAL_PITCH.DATA4[2] = SPATIAL_BUF[70];
-            SPATIAL_PITCH.DATA4[3] = SPATIAL_BUF[71];
+            SPATIAL_PITCH.DATA4[0] = SPATIAL_39_BUF[4];
+            SPATIAL_PITCH.DATA4[1] = SPATIAL_39_BUF[5];
+            SPATIAL_PITCH.DATA4[2] = SPATIAL_39_BUF[6];
+            SPATIAL_PITCH.DATA4[3] = SPATIAL_39_BUF[7];
             PITCH = SPATIAL_PITCH.F4 * RADIANS_TO_DEGREES;    //float형으로 짠. 단위는 역시 rad라서 고침.            
     
             FP4 SPATIAL_YAW;       //이 과정은 4바이트로 흩어진 것을 하나의 float형으로 모으는 과정..
-            SPATIAL_YAW.DATA4[0] = SPATIAL_BUF[72];
-            SPATIAL_YAW.DATA4[1] = SPATIAL_BUF[73];
-            SPATIAL_YAW.DATA4[2] = SPATIAL_BUF[74];
-            SPATIAL_YAW.DATA4[3] = SPATIAL_BUF[75];
-            YAW = SPATIAL_YAW.F4 * RADIANS_TO_DEGREES;    //float형으로 짠. 단위는 역시 rad라서 고침.            
+            SPATIAL_YAW.DATA4[0] = SPATIAL_39_BUF[8];
+            SPATIAL_YAW.DATA4[1] = SPATIAL_39_BUF[9];
+            SPATIAL_YAW.DATA4[2] = SPATIAL_39_BUF[10];
+            SPATIAL_YAW.DATA4[3] = SPATIAL_39_BUF[11];
+            YAW = SPATIAL_YAW.F4 * RADIANS_TO_DEGREES;    //float형으로 짠. 단위는 역시 rad라서 고침.                        
+            YAW += DECLINATION_ANGLE;
             
-            
+            if(YAW > 360) YAW -= 360;
+            else if(YAW < 0) YAW += 360;
+        }   
+    }    
+}
+void SPATIAL::SPATIAL_ID_42_Parsing(){
+    if(SPATIAL_ID_42_PARSING_BOOL == true){
+        SPATIAL_ID_42_PARSING_BOOL = false;
+        if(CRC_INPUT == calculate_crc16(SPATIAL_42_BUF,12)){
             FP4 SPATIAL_ROLL_RATE;       //이 과정은 4바이트로 흩어진 것을 하나의 float형으로 모으는 과정..
-            SPATIAL_ROLL_RATE.DATA4[0] = SPATIAL_BUF[76];
-            SPATIAL_ROLL_RATE.DATA4[1] = SPATIAL_BUF[77];
-            SPATIAL_ROLL_RATE.DATA4[2] = SPATIAL_BUF[78];
-            SPATIAL_ROLL_RATE.DATA4[3] = SPATIAL_BUF[79];
+            SPATIAL_ROLL_RATE.DATA4[0] = SPATIAL_42_BUF[0];
+            SPATIAL_ROLL_RATE.DATA4[1] = SPATIAL_42_BUF[1];
+            SPATIAL_ROLL_RATE.DATA4[2] = SPATIAL_42_BUF[2];
+            SPATIAL_ROLL_RATE.DATA4[3] = SPATIAL_42_BUF[3];
             ROLL_RATE = SPATIAL_ROLL_RATE.F4 * RADIANS_TO_DEGREES;    //float형으로 짠. 단위는 역시 rad라서 고침.            
     
             FP4 SPATIAL_PITCH_RATE;       //이 과정은 4바이트로 흩어진 것을 하나의 float형으로 모으는 과정..
-            SPATIAL_PITCH_RATE.DATA4[0] = SPATIAL_BUF[80];
-            SPATIAL_PITCH_RATE.DATA4[1] = SPATIAL_BUF[81];
-            SPATIAL_PITCH_RATE.DATA4[2] = SPATIAL_BUF[82];
-            SPATIAL_PITCH_RATE.DATA4[3] = SPATIAL_BUF[83];
+            SPATIAL_PITCH_RATE.DATA4[0] = SPATIAL_42_BUF[4];
+            SPATIAL_PITCH_RATE.DATA4[1] = SPATIAL_42_BUF[5];
+            SPATIAL_PITCH_RATE.DATA4[2] = SPATIAL_42_BUF[6];
+            SPATIAL_PITCH_RATE.DATA4[3] = SPATIAL_42_BUF[7];
             PITCH_RATE = SPATIAL_PITCH_RATE.F4 * RADIANS_TO_DEGREES;    //float형으로 짠. 단위는 역시 rad라서 고침.            
     
             FP4 SPATIAL_YAW_RATE;       //이 과정은 4바이트로 흩어진 것을 하나의 float형으로 모으는 과정..
-            SPATIAL_YAW_RATE.DATA4[0] = SPATIAL_BUF[84];
-            SPATIAL_YAW_RATE.DATA4[1] = SPATIAL_BUF[85];
-            SPATIAL_YAW_RATE.DATA4[2] = SPATIAL_BUF[86];
-            SPATIAL_YAW_RATE.DATA4[3] = SPATIAL_BUF[87];
-            YAW_RATE = SPATIAL_YAW_RATE.F4 * RADIANS_TO_DEGREES;    //float형으로 짠. 단위는 역시 rad라서 고침.            
-         
+            SPATIAL_YAW_RATE.DATA4[0] = SPATIAL_42_BUF[8];
+            SPATIAL_YAW_RATE.DATA4[1] = SPATIAL_42_BUF[9];
+            SPATIAL_YAW_RATE.DATA4[2] = SPATIAL_42_BUF[10];
+            SPATIAL_YAW_RATE.DATA4[3] = SPATIAL_42_BUF[11];
+            YAW_RATE = SPATIAL_YAW_RATE.F4 * RADIANS_TO_DEGREES;    //float형으로 짠. 단위는 역시 rad라서 고침.                                
+        }   
+    }    
+}
+
+bool SPATIAL::SPATIAL_STABLE(){
+    if(SENSOR_WAIT_BOOL == true){
+        if( (Vx<0.1) & (Vx>-0.1) & (Vy<0.1) & (Vy>-0.1) & (Vz<0.1) & (Vz>-0.1) ){
+            SENSOR_STABLE_CNT ++;
+        }else{
+            SENSOR_STABLE_CNT = 0;
         }
-
-
+        if( SENSOR_STABLE_CNT > 2000){
+            SENSOR_STABLE_OK = true;
+        }
+        ///////////////////////////////
+        if(SENSOR_STABLE_OK == true){
+            return true;
+        }else{
+            return false;
+        }        
+    }else{
+        return true;   
     }
 }
 
--- a/SPATIAL/SPATIAL.h	Tue Jun 12 01:05:50 2018 +0000
+++ b/SPATIAL/SPATIAL.h	Wed Nov 28 13:06:23 2018 +0000
@@ -4,24 +4,39 @@
 
 #include "mbed.h"
 
-
 class SPATIAL {
 public:
-    void Init();
-    void SPATIAL_ID_20_Parsing();
+    void Init(int);
     void SPATIAL_RECEIVE();
     
     double LATITUDE, LONGITUDE, HEIGHT;
-    float Vn, Ve, Vd, ROLL, PITCH, YAW, ROLL_RATE, PITCH_RATE, YAW_RATE;
+    float Vx, Vy, Vz, ROLL, PITCH, YAW, ROLL_RATE, PITCH_RATE, YAW_RATE;
     uint32_t UNIX_TIME;
-    bool SPATIAL_ID_20_BOOL, SPATIAL_ID_20_PARSING_BOOL;
+    bool SPATIAL_ID_39_BOOL, SPATIAL_ID_39_PARSING_BOOL;
+    bool SPATIAL_ID_42_BOOL, SPATIAL_ID_42_PARSING_BOOL;
+    bool SPATIAL_ID_35_BOOL, SPATIAL_ID_35_PARSING_BOOL;
+    bool SPATIAL_ID_32_BOOL, SPATIAL_ID_32_PARSING_BOOL;
+    bool SPATIAL_ID_30_BOOL, SPATIAL_ID_30_PARSING_BOOL;
+    bool SPATIAL_ID_22_BOOL, SPATIAL_ID_22_PARSING_BOOL;
+    int HZ_CNT;
     int SATELLITE_NUM;
+    uint8_t SYSTEM_STATUS,FILTER_STATUS;
+    bool SPATIAL_STABLE();
+    float DECLINATION_ANGLE;
 private:
     int SPATIAL_BUF_CNT;
-    unsigned char SPATIAL_BUF[100], SPATIAL_ID[5];
+    unsigned char SPATIAL_ID[5];
+    unsigned char SPATIAL_42_BUF[12], SPATIAL_39_BUF[12], SPATIAL_35_BUF[12], SPATIAL_32_BUF[24], SPATIAL_22_BUF[14], SPATIAL_30_BUF[13];
     uint16_t CRC_INPUT;
-
-
+    void SPATIAL_ID_39_Parsing();
+    void SPATIAL_ID_42_Parsing();
+    void SPATIAL_ID_35_Parsing();
+    void SPATIAL_ID_32_Parsing();
+    void SPATIAL_ID_30_Parsing();
+    void SPATIAL_ID_22_Parsing();
+    int SENSOR_STABLE_CNT;
+    bool SENSOR_STABLE_OK;
+    bool SENSOR_WAIT_BOOL;
 };
 
 
--- a/main.cpp	Tue Jun 12 01:05:50 2018 +0000
+++ b/main.cpp	Wed Nov 28 13:06:23 2018 +0000
@@ -1,217 +1,603 @@
 #include "mbed.h"
-
-
 #include <math.h>
-
+#include "Function.h"
 #include "millis.h"
 #include "SPATIAL.h"
 #include "ROBOFRIEN_GUI.h"
 #include "ROBOFRIEN_LED.h"
 #include "ROBOFRIEN_MOTOR.h"
 #include "ROBOFRIEN_PID.h"
+#include "ROBOFRIEN_SBUS.h"
+#include "ROBOFRIEN_BAT.h"
+
+
+
+/* ************  USER INTERFACE ************** */
+#define SENSOR_WAIT                 1
+#define THROTTLE_MAX                7000
+#define THROTTLE_BASE               4000
+#define THROTTLE_MIN                3000
+#define THROTTLE_CONTROL_LIMIT      1500
+#define LIMIT_PROGRESS_VELOCITY     10
+#define LIMIT_UP_VELOCITY           4
+#define LIMIT_DOWN_VELOCITY         2
+#define LIMIT_PLANE_VEL_INTEG       5           // Degree
+#define LIMIT_VERTICAL_VEL_INTEG    500
+/* ******************************************* */
+
+/* *************************** */
+// AutoFlight Sequence
+// 0. Wait to Start
+// 1. Take Off  (10m From Ground)
+// 2. Heading Align to Marker
+// 3. Go to Point ( Pitching & Altitude )
+// 4. Hovering
+// 5. Landing
+#define WAIT_TO_START   1
+#define TAKE_OFF        2
+#define HEADING_ALIGN   3
+#define GO_TO_POINT     4
+#define CHECK_MARKER    5
+#define LANDING         6
+#define WAIT            7
+int ex_AUTOFLIGHT_SEQUENCE;
+int AUTOFLIGHT_SEQUENCE = WAIT_TO_START;
+unsigned long AUTOFLIGHT_TIME_CNT;
+/* *************************** */
 
 ROBOFRIEN_GUI   GUI;
 ROBOFRIEN_LED   LED;
 ROBOFRIEN_MOTOR MOTOR;
 ROBOFRIEN_PID   PID;
 SPATIAL         SPATIAL;
+ROBOFRIEN_SBUS  SBUS;
+ROBOFRIEN_BAT   BAT;
 
 
 void GUI_UPDATE();
+void ALGORITHM();
+void ANGLE_CONTROL(double [3]);
+void PLANE_VEL_CONTROL(double, double, double *, double *);
+void VERTICAL_VEL_CONTROL(double, double *);
+void VEL_INTEG_RESET();
+float DEG_TO_METER(float , float , float , float );
 
-unsigned long millis_20hz, millis_100hz;
-int main() 
+unsigned long millis_100hz, millis_10hz, millis_200hz;
+double want_Angle[3];
+double want_Rate[3];
+double err_Angle[3];
+double THROTTLE_VALUE;
+double want_LNG, want_LAT, want_ALT;
+int main()
 {
-    GUI.Init();
-    LED.Init();
-    SPATIAL.Init();
-    MOTOR.Init();
-    PID.Init();
-    wait(1);
-    millisStart();    
-    while(1){
-        GUI.pc_rx_update();
-        LED.update(GUI.headlight_period, GUI.headlight_dutyrate, GUI.sidelight_period, GUI.sidelight_dutyrate );
-        SPATIAL.SPATIAL_RECEIVE();
-        SPATIAL.SPATIAL_ID_20_Parsing();
-        if( (millis() - millis_100hz ) > 10 ){
-            millis_100hz = millis();
-            PID.err_Angle[0] = 0;   PID.err_Angle[1] = 0;   PID.err_Angle[2] = 0;
-            float want_Rate[3] = {0,0,0};
-            PID.err_Rate[0] = (want_Rate[0] - SPATIAL.ROLL_RATE);
-            PID.err_Rate[1] = (want_Rate[1] - SPATIAL.PITCH_RATE);
-            PID.err_Rate[2] = (want_Rate[2] - SPATIAL.YAW_RATE);
-            PID.update();
-            MOTOR.Value[0] = 5000 + PID.output_Data[0]*3000;
-            MOTOR.Value[1] = 5000 + PID.output_Data[1]*3000;
-            MOTOR.Value[2] = 5000 + PID.output_Data[2]*3000;
-            MOTOR.Value[3] = 5000 + PID.err_Rate[0]*100;
-            MOTOR.Value[4] = 5000 + 0;
-            MOTOR.Value[5] = 5000 + 0;
-            MOTOR.update();
+  LED.Init();
+  MOTOR.Init();
+  wait(1);
+  SPATIAL.Init(SENSOR_WAIT);
+  SBUS.Init();
+  PID.Init();
+  GUI.Init();
+  BAT.Init(3);        // 3cell
+  millisStart();
+  while (1) {
+    GUI.pc_rx_update();
+    GUI.TRANS_BUFFER();
+    LED.update(GUI.headlight_period, GUI.headlight_dutyrate, GUI.sidelight_period, GUI.sidelight_dutyrate );
+    SPATIAL.SPATIAL_RECEIVE();
+    SBUS.update();
+    if ( ( millis() - millis_200hz ) > 5 ) {
+      millis_200hz = millis();
+      if ( SPATIAL.SPATIAL_STABLE() == false ) {
+        LED.ALARM(1);
+        if (GUI.button[0] == true) {
+          ALGORITHM();
+          MOTOR.update();
+        } else {
+          MOTOR.OFF();
         }
-        if( (millis() - millis_20hz )>50){
-            millis_20hz = millis();
-        }
-        if(GUI.rx_bool() == true){
-            GUI_UPDATE();
-            GUI.Refresh();
-        }
-        
+      } else {
+        LED.ALARM(0);
+        ALGORITHM();
+        MOTOR.update();
+      }
     }
+
+    if ( (millis() - millis_10hz ) > 100) {
+      millis_10hz = millis();
+      GUI_UPDATE();
+      GUI.Trans();
+      GUI.SET_DATA();
+    }
+    if (GUI.rx_bool() == true) {
+      GUI.Refresh();
+    }
+  }
 }
 
-void GUI_UPDATE(){
-    /////////////////////////////////////////////////////////////////////////////////////////////////////////
-    //////////////////////////////////////////// [M/S] Mode and State ///////////////////////////////////////
-    /////////////////////////////////////////////////////////////////////////////////////////////////////////
-    GUI.Mode1 = 0;
-    GUI.Mode2 = 0;
-    GUI.MissionState = 0;
-    GUI.CurrentMarker = 0;
-    GUI.Bat1 = 0;   // 21.6 ~ 24.6 ( 6cell )
-    GUI.Bat2 = 0;  // 11.1 ~ 12.6 ( 3cell )
-    // [ Button State & Home Point Chksum & Marker Chksum ] is change automatically in "ROBOFRIEN_GUI.cpp" //
-    // You Can not change this setting, just use it ///
-    if(GUI.button[0] == true) {}
-    else {}
-    if(GUI.button[1] == true) {}
-    else {}
-    if(GUI.button[2] == true) {}
-    else {}
-    if(GUI.button[3] == true) {}
-    else {}
-    if(GUI.button[4] == true) {}
-    else {}
-    
-    /////////////////////////////////////////////////////////////////////////////////////////////////////////
-    //////////////////////////////////////////////// [GPS] GPS //////////////////////////////////////////////
-    /////////////////////////////////////////////////////////////////////////////////////////////////////////
-    GUI.utc_time = SPATIAL.UNIX_TIME;
-    GUI.latitude = (SPATIAL.LATITUDE*1000000);
-    GUI.longitude = (SPATIAL.LONGITUDE*1000000);
-    GUI.altitude =  SPATIAL.HEIGHT*100;
-    GUI.SatNum = SPATIAL.SATELLITE_NUM;
-    /////////////////////////////////////////////////////////////////////////////////////////////////////////
-    ///////////////////////////////////////////////// AHRS //////////////////////////////////////////////////
-    /////////////////////////////////////////////////////////////////////////////////////////////////////////
-    GUI.rollx100 = (SPATIAL.ROLL * 100);
-    GUI.pitchx100 = (SPATIAL.PITCH * 100);
-    GUI.yawx100 = ((SPATIAL.YAW )* 100);
-    GUI.roll_ratex100 =  SPATIAL.ROLL_RATE * 100;
-    GUI.pitch_ratex100 =  SPATIAL.PITCH_RATE * 100;
-    GUI.yaw_ratex100 =  SPATIAL.YAW_RATE * 100;
-    GUI.VXx100 = SPATIAL.Ve * 100;
-    GUI.VYx100 = SPATIAL.Vn * 100;
-    GUI.VZx100 = SPATIAL.Vd * 100;
-    
-    /////////////////////////////////////////////////////////////////////////////////////////////////////////
-    ////////////////////////////////////////////// [C/P] CAP/PWM ////////////////////////////////////////////
-    /////////////////////////////////////////////////////////////////////////////////////////////////////////
-    GUI.pwm[0] = MOTOR.Value[0]/100;           // (0 ~ 10000) --> ( 0 ~ 100 )
-    GUI.pwm[1] = MOTOR.Value[1]/100;           // (0 ~ 10000) --> ( 0 ~ 100 )
-    GUI.pwm[2] = MOTOR.Value[2]/100;           // (0 ~ 10000) --> ( 0 ~ 100 )
-    GUI.pwm[3] = MOTOR.Value[3]/100;           // (0 ~ 10000) --> ( 0 ~ 100 )
-    GUI.pwm[4] = MOTOR.Value[4]/100;           // (0 ~ 10000) --> ( 0 ~ 100 )
-    GUI.pwm[5] = MOTOR.Value[5]/100;           // (0 ~ 10000) --> ( 0 ~ 100 )
-    
-    /////////////////////////////////////////////////////////////////////////////////////////////////////////
-    /////////////////////////////////////////// [E/D] Extra & Debug /////////////////////////////////////////
-    /////////////////////////////////////////////////////////////////////////////////////////////////////////
-    
-    GUI.DEBUGx100[0] = 0;
-    GUI.DEBUGx100[1] = 0;
-    GUI.DEBUGx100[2] = 0;
-    GUI.DEBUGx100[3] = 0;
-    GUI.DEBUGx100[4] = 0;
-    GUI.DEBUGx100[5] = 0;
-    GUI.DEBUGx100[6] = 0;
-    GUI.DEBUGx100[7] = 0;
-    
-    /////////////////////////////////////////////////////////////////////////////////////////////////////////
-    /////////////////////////////////////////// Configuration ///////////////////////////////////////////////
-    /////////////////////////////////////////////////////////////////////////////////////////////////////////
-    
-    ///////////////////////////// -----------------DPN 1-------------------- ////////////////////////////////
-    // You can set the this value from "Config.h"  ( EEPROM_MODEL_TYPE1, EEPROM_MODEL_TYPE2_UP, EEPROM_MODEL_TYPE2_DOWN ) //
-    
-    ///////////////////////////// -----------------DPN 2-------------------- ////////////////////////////////
-    // You can set the this value from "Config.h"  ( MODEL_INFO, FIRMWARE_INFO ) //
-    
-    ///////////////////////////// -----------------DPN 3-------------------- ////////////////////////////////
-    /// You can set the original value of receiver to [raw_cap] with scale down ( -127 ~ 127 ) ///
-    /// You can use the [cap_min[8], cap_neu[8], cap_max[8]] for calibration of RC receiver value //
-                
-    ///////////////////////////// -----------------DPN 4-------------------- ////////////////////////////////
-    /// You can use the [pwm_info , motor_min[4]] for calibration of motor pwm value //
-    
-    ///////////////////////////// -----------------DPN 5-------------------- ////////////////////////////////
-/*
-    LED.HeadlightPeriod = GUI.headlight_period;
-    LED.HeadlightDutyrate = GUI.headlight_dutyrate;
-    LED.SidelightPeriod = GUI.sidelight_period;
-    LED.SidelightDutyrate = GUI.sidelight_dutyrate;
-*/    
-    ///////////////////////////// -----------------DPN 6-------------------- ////////////////////////////////
-    /// You can set the original value of receiver to [raw_cap] with scale down ( -127 ~ 127 ) ///
-    /// You can use the [cap_min[8], cap_neu[8], cap_max[8]] for calibration of RC receiver value //
-    GUI.raw_cap[0] = (0 - 150)*2;                
-    GUI.raw_cap[1] = (0 - 150)*2;                
-    GUI.raw_cap[2] = (0 - 150)*2;                
-    GUI.raw_cap[3] = (0 - 150)*2;                
-    GUI.raw_cap[4] = (0 - 150)*2;                
-    GUI.raw_cap[5] = (0 - 150)*2;                
-    GUI.raw_cap[6] = 0;
-    GUI.raw_cap[7] = 0;
-    
-    if(GUI.attitude_configuration_bool == true){
-        GUI.attitude_configuration_bool = false;
-        // You can calibration of attitude (Roll, Pitch) //
-    //                GUI.attitude_calibrate(accelData[0]*aRes,accelData[1]*aRes,(accelData[2]*aRes-1));   
+
+uint8_t EX_CONTROLLER_STATE;
+bool MOTOR_FORCED_OFF_BOOL = true;
+void ALGORITHM() {       // 200 Hz //
+  /* *************************** */
+  /* ******* Want Angle ******** */
+  /* *************************** */
+  switch (SBUS.CONTROLLER_STATE) {
+    case SIGNAL_OFF: {
+        want_Angle[0] = 0;  want_Angle[1] = 0;  want_Angle[2] = SPATIAL.YAW;
+        THROTTLE_VALUE = 0;
+      } break;
+    case MOTOR_OFF: {
+        MOTOR_FORCED_OFF_BOOL = true;
+        want_Angle[0] = 0;  want_Angle[1] = 0;  want_Angle[2] = SPATIAL.YAW;
+        THROTTLE_VALUE = 0;
+      } break;
+    case MANUAL_ATTITUDE: {
+        MOTOR_FORCED_OFF_BOOL = false;
+        want_Angle[0] = ((SBUS.channel[0]) / 1000.0) * GUI.limit_rollx100 / 100.0;       // Want Angle : Roll
+        want_Angle[1] = ((SBUS.channel[1]) / 1000.0) * GUI.limit_pitchx100 / 100.0;      // Want Angle : Pitch
+        if ( (SBUS.channel[3] > 3) | (SBUS.channel[3] < -3) )  want_Angle[2] += ((SBUS.channel[3]) / 2000.0) / 200.0 * (GUI.limit_yaw_ratex100 / 100.0);
+        if ( want_Angle[2] > 360) want_Angle[2] -= 360;
+        else if ( want_Angle[2] < 0) want_Angle[2] += 360;
+        THROTTLE_VALUE = ((SBUS.channel[2] + 1000) / 2000.0 * THROTTLE_MAX);
+      } break;
+    case MANUAL_VELOCITY ... AUTO_FLIGHT: {         // MANUAL_VELOCITY(3), MANUAL_POSITION(4), AUTO_FLIGHT(5) //
+        //// [LNG]Longitude Up : East Face, Longitude Down : West Face
+        //// [LAT]Latitude Up : North Face, Latitude Down : South Face
+        if ( EX_CONTROLLER_STATE != SBUS.CONTROLLER_STATE) {
+          want_LAT = SPATIAL.LATITUDE;
+          want_LNG = SPATIAL.LONGITUDE;
+          want_ALT = SPATIAL.HEIGHT;
+          AUTOFLIGHT_TIME_CNT = 0;
+        }
+
+        double want_Vel[3];  // VEL[0] = X-axis, VEL[1] = Y-axis, VEL[2] = Z-axis
+        if ( SBUS.CONTROLLER_STATE == MANUAL_VELOCITY ) {
+          /* ******************************************************* */
+          /* ****************** MANUAL VELOCITY ******************** */
+          /* ******************************************************* */
+          MOTOR_FORCED_OFF_BOOL = false;
+          want_Vel[0] = -(SBUS.channel[1] / 1000.0) * LIMIT_PROGRESS_VELOCITY;
+          want_Vel[1] = (SBUS.channel[0] / 1000.0) * LIMIT_PROGRESS_VELOCITY;
+          if ( SBUS.channel[2] >= 0 )      want_Vel[2] = (SBUS.channel[2] / 1000.0) * LIMIT_UP_VELOCITY;
+          else if ( SBUS.channel[2] < 0 )  want_Vel[2] = (SBUS.channel[2] / 1000.0) * LIMIT_DOWN_VELOCITY;
+          if ( (SBUS.channel[3] > 3) | (SBUS.channel[3] < -3) )  want_Angle[2] += ((SBUS.channel[3]) / 2000.0) / 200.0 * (GUI.limit_yaw_ratex100 / 100.0);
+
+        } else {
+          if ( SBUS.CONTROLLER_STATE == MANUAL_POSITION ) {
+            /* ******************************************************* */
+            /* ****************** MANUAL POSITION ******************** */
+            /* ******************************************************* */
+            MOTOR_FORCED_OFF_BOOL = false;
+            double del_pos[3];
+            del_pos[0] = (-(SBUS.channel[1] / 1000.0) * LIMIT_PROGRESS_VELOCITY);  //divided by time
+            del_pos[1] = ((SBUS.channel[0] / 1000.0) * LIMIT_PROGRESS_VELOCITY);   //divided by time
+            if (SBUS.channel[2] >= 0)        del_pos[2] = ((SBUS.channel[2] / 1000.0) * LIMIT_UP_VELOCITY);  //divided by time
+            else if (SBUS.channel[2] < 0)    del_pos[2] = ((SBUS.channel[2] / 1000.0) * LIMIT_DOWN_VELOCITY);  //divided by time
+
+            double NED_del_pos[3];
+            NED_del_pos[0] = del_pos[0] * cos(SPATIAL.YAW * M_PI / 180.0) - del_pos[1] * sin(SPATIAL.YAW * M_PI / 180.0);
+            NED_del_pos[1] = del_pos[0] * sin(SPATIAL.YAW * M_PI / 180.0) + del_pos[1] * cos(SPATIAL.YAW * M_PI / 180.0);
+
+            if( (SBUS.channel[1] < 5) & (SBUS.channel[1] > -5) ) {}
+            else want_LAT += (NED_del_pos[0] / 200.0) / 110574.0;
+            if( (SBUS.channel[0] < 5) & (SBUS.channel[0] > -5) ) {}
+            else want_LNG += (NED_del_pos[1] / 200.0) / 111320.0;
+            if( (SBUS.channel[2] < 10) & (SBUS.channel[2] > -10) ) {}
+            else want_ALT += (del_pos[2] / 200.0);
+
+            if ( (SBUS.channel[3] > 3) | (SBUS.channel[3] < -3) )  want_Angle[2] += ((SBUS.channel[3]) / 2000.0) / 200.0 * (GUI.limit_yaw_ratex100 / 100.0);
+
+          } else if ( SBUS.CONTROLLER_STATE == AUTO_FLIGHT) {
+            /* ******************************************************* */
+            /* ******************    AUTO FLIGHT  ******************** */
+            /* ******************************************************* */
+            if (AUTOFLIGHT_SEQUENCE != ex_AUTOFLIGHT_SEQUENCE) {
+              AUTOFLIGHT_TIME_CNT = 0;
+            }
+            ex_AUTOFLIGHT_SEQUENCE = AUTOFLIGHT_SEQUENCE;
+            AUTOFLIGHT_TIME_CNT ++;
+            if ( AUTOFLIGHT_SEQUENCE == WAIT_TO_START) MOTOR_FORCED_OFF_BOOL = true;
+            else MOTOR_FORCED_OFF_BOOL = false;
+            switch (AUTOFLIGHT_SEQUENCE) {
+              case WAIT_TO_START: {
+                  if ( AUTOFLIGHT_TIME_CNT > (5 * 200) ) AUTOFLIGHT_SEQUENCE = TAKE_OFF;
+                  want_LAT = SPATIAL.LATITUDE;
+                  want_LNG = SPATIAL.LONGITUDE;
+                  want_ALT = SPATIAL.HEIGHT;
+                  want_Angle[2] = SPATIAL.YAW;
+                  break;
+                }
+              case TAKE_OFF: {            /// Take off [ Ground --> 5m ]  in 1m/s
+                  want_ALT += (1 / 200.0);
+                  if ( AUTOFLIGHT_TIME_CNT > (5 * 200)) {
+                    AUTOFLIGHT_SEQUENCE = CHECK_MARKER;
+                    GUI.CurrentMarker = 1;
+                  }
+                  break;
+                }
+              case HEADING_ALIGN: {
+                  float BEARING_ANGLE = bearing( SPATIAL.LATITUDE, SPATIAL.LONGITUDE, (float)(GUI.Marker_Lat[GUI.CurrentMarker - 1]) / 1000000.0, (float)(GUI.Marker_Lng[GUI.CurrentMarker - 1]) / 1000000.0);
+                  want_Angle[2] = BEARING_ANGLE;
+                  if ( ABSOL((BEARING_ANGLE - SPATIAL.YAW)) < 5 ) {
+                    if (AUTOFLIGHT_TIME_CNT > (3 * 200) ) AUTOFLIGHT_SEQUENCE = GO_TO_POINT;
+                  } else AUTOFLIGHT_TIME_CNT = 0;
+//                  GUI.DEBUGx100[0] = (BEARING_ANGLE + 100) * 100;
+//                  GUI.DEBUGx100[1] = (ABSOL((BEARING_ANGLE - SPATIAL.YAW)) + 100) * 100;
+                  break;
+                }
+              case GO_TO_POINT: {
+                  float Target_LAT = GUI.Marker_Lat[GUI.CurrentMarker - 1] / 1000000.0;
+                  float Target_LNG = GUI.Marker_Lng[GUI.CurrentMarker - 1] / 1000000.0;
+                  float Target_ALT = GUI.Marker_Alt[GUI.CurrentMarker - 1] / 100.0;
+//                  float BEARING_ANGLE = bearing( SPATIAL.LATITUDE, SPATIAL.LONGITUDE, (float)(GUI.Marker_Lat[GUI.CurrentMarker - 1]) / 1000000.0, (float)(GUI.Marker_Lng[GUI.CurrentMarker - 1]) / 1000000.0);
+//                  want_Angle[2] = BEARING_ANGLE;
+                  // 1ms ++
+                  /*                            if(Target_LAT > want_LAT) want_LAT += (1.5/200.0)/110574.0;
+                                              else want_LAT -= (1/200.0)/110574.0;
+                                              if(Target_LNG > want_LNG) want_LNG += (1.5/200.0)/111320.0;
+                                              else want_LNG -= (1/200.0)/111320.0;
+                                              if(Target_ALT > want_ALT) want_ALT += (1/200.0);
+                                              else want_ALT -= (1/200.0);
+                  */
+//                  want_LAT = Target_LAT;
+//                  want_LNG = Target_LNG;
+//                  want_ALT = Target_ALT;
+                  if(Target_LAT > want_LAT) want_LAT += (LIMIT_PROGRESS_VELOCITY/200.0)/110574.0;
+                  else want_LAT -= (LIMIT_PROGRESS_VELOCITY/200.0)/110574.0;
+                  if(Target_LNG > want_LNG) want_LNG += (LIMIT_PROGRESS_VELOCITY/200.0)/111320.0;
+                  else want_LNG -= (LIMIT_PROGRESS_VELOCITY/200.0)/111320.0;
+                  if(Target_ALT > want_ALT) want_ALT += (LIMIT_UP_VELOCITY/200.0);
+                  else want_ALT -= (LIMIT_DOWN_VELOCITY/200.0);
+
+                  bool escape_bool = false;
+                  float POSITION_DISTANCE;
+                  float HEIGHT_DISTANCE;
+                  POSITION_DISTANCE = DEG_TO_METER( want_LAT, want_LNG, SPATIAL.LATITUDE, SPATIAL.LONGITUDE );
+                  HEIGHT_DISTANCE = sqrt( (want_ALT - SPATIAL.HEIGHT) * (want_ALT - SPATIAL.HEIGHT) );
+                  if ( ( POSITION_DISTANCE < 5 ) & (HEIGHT_DISTANCE < 5)) {     // 5m
+                    if ( (POSITION_DISTANCE < 3) ) {                            // 3m
+                      if ( (POSITION_DISTANCE < 1) ) {                          // 1m
+                        ///////////// Target in the 1m OK !!!! /////////////////
+                        escape_bool = true;
+                        /////////////////////////////////////////////////
+                      }
+                      else {
+                        if ( AUTOFLIGHT_TIME_CNT > (5 * 200) ) escape_bool = true;       // Time Out //
+                      }
+                    }
+                    else {
+                      if ( AUTOFLIGHT_TIME_CNT > (5 * 200) ) escape_bool = true;           // Time Out //
+                    }
+                  }
+                  else {
+                    AUTOFLIGHT_TIME_CNT = 0;
+                  }
+                  if ( escape_bool == true) {
+                    AUTOFLIGHT_SEQUENCE = CHECK_MARKER;
+                    GUI.CurrentMarker ++;
+                  }
+                  // 1m내외
+                  break;
+                }
+              case CHECK_MARKER: {
+                  if (AUTOFLIGHT_TIME_CNT > (3 * 200) ) {
+                    if ( (GUI.Marker_Lat[GUI.CurrentMarker - 1] != 0) & (GUI.Marker_Lng[GUI.CurrentMarker - 1] != 0) ) {
+                      AUTOFLIGHT_SEQUENCE = HEADING_ALIGN;
+                    } else {
+                      AUTOFLIGHT_SEQUENCE = LANDING;
+                    }
+                  }
+                  break;
+                }
+              case LANDING: {
+                  want_ALT -= (0.5 / 200.0);    // 0.5m/s
+                  break;
+                }
+              case WAIT: {
+                  break;
+                }
+            }
+          }
+          double NED_want_vel[3];
+          NED_want_vel[0] = (want_LAT - SPATIAL.LATITUDE) * 110574.0 * (GUI.gain_px100[4] / 100.0);
+          NED_want_vel[1] = (want_LNG - SPATIAL.LONGITUDE) * 111320.0 * (GUI.gain_px100[5] / 100.0);
+          NED_want_vel[2] = (want_ALT - SPATIAL.HEIGHT) * (GUI.gain_px100[6] / 100.0);
+
+          want_Vel[0] = NED_want_vel[0] * cos(SPATIAL.YAW * M_PI / 180.0) + NED_want_vel[1] * sin(SPATIAL.YAW * M_PI / 180.0);
+          want_Vel[1] = NED_want_vel[1] * cos(SPATIAL.YAW * M_PI / 180.0) - NED_want_vel[0] * sin(SPATIAL.YAW * M_PI / 180.0);
+          want_Vel[2] = NED_want_vel[2];
+
+          float LIMIT_PROGRESS_VELOCITY_CALCULATED;
+          float POSITION_DISTANCE = DEG_TO_METER( want_LAT, want_LNG, SPATIAL.LATITUDE, SPATIAL.LONGITUDE );
+          if ( POSITION_DISTANCE < 20) LIMIT_PROGRESS_VELOCITY_CALCULATED = (0.04 * POSITION_DISTANCE + 0.2) * LIMIT_PROGRESS_VELOCITY;
+          else LIMIT_PROGRESS_VELOCITY_CALCULATED = LIMIT_PROGRESS_VELOCITY;
+
+          want_Vel[0] = MIN_MAX(want_Vel[0], -LIMIT_PROGRESS_VELOCITY_CALCULATED, LIMIT_PROGRESS_VELOCITY_CALCULATED);
+          want_Vel[1] = MIN_MAX(want_Vel[1], -LIMIT_PROGRESS_VELOCITY_CALCULATED, LIMIT_PROGRESS_VELOCITY_CALCULATED);
+          if (want_Vel[2] >= 0)        want_Vel[2] = MIN_MAX(want_Vel[2], -LIMIT_UP_VELOCITY, LIMIT_UP_VELOCITY);
+          else if (want_Vel[2] < 0)    want_Vel[2] = MIN_MAX(want_Vel[2], -LIMIT_DOWN_VELOCITY, LIMIT_DOWN_VELOCITY);
+
+        }
+
+        /* ********** WANT ANGLE GENERATE ************ */
+        PLANE_VEL_CONTROL(want_Vel[0], want_Vel[1], &want_Angle[0], &want_Angle[1]);
+        if ( want_Angle[2] > 360) want_Angle[2] -= 360;
+        else if ( want_Angle[2] < 0) want_Angle[2] += 360;
+
+        /* ********** THROTTLE VALUE GENRATE ************* */
+        VERTICAL_VEL_CONTROL(want_Vel[2], &THROTTLE_VALUE);
+        if (MOTOR_FORCED_OFF_BOOL == true) THROTTLE_VALUE = 0;
+
+      } break;
+  }
+  EX_CONTROLLER_STATE = SBUS.CONTROLLER_STATE;
+  /* ************************** */
+  /* ******* Want Rate ******** */
+  /* ************************** */
+  ANGLE_CONTROL( want_Angle );
+
+  if (GUI.DPN_Info == 0) {
+    if ( SBUS.CONTROLLER_STATE <= MOTOR_OFF) {
+      PID.RAT_INTEGER_RESET();
+      VEL_INTEG_RESET();
+      for (int i = 0; i < 6; i++) MOTOR.Value[i] = 0;
+    } else {
+      int MOTOR_MIN_DEADZONE  = 5;
+      for (int i = 0; i < 5; i++) {
+        if (GUI.motor_min[i] > 100)GUI.motor_min[i] = 100;
+      }
+      MOTOR.Value[0] = (GUI.motor_min[0] - MOTOR_MIN_DEADZONE) * 10 + THROTTLE_VALUE + PID.output_Data[0] / 2.0    - PID.output_Data[1] * 0.87    - PID.output_Data[2];
+      MOTOR.Value[1] = (GUI.motor_min[1] - MOTOR_MIN_DEADZONE) * 10 + THROTTLE_VALUE + PID.output_Data[0]        + 0                          + PID.output_Data[2];
+      MOTOR.Value[2] = (GUI.motor_min[2] - MOTOR_MIN_DEADZONE) * 10 + THROTTLE_VALUE + PID.output_Data[0] / 2.0    + PID.output_Data[1] * 0.87    - PID.output_Data[2];
+      MOTOR.Value[3] = (GUI.motor_min[3] - MOTOR_MIN_DEADZONE) * 10 + THROTTLE_VALUE - PID.output_Data[0] / 2.0    + PID.output_Data[1] * 0.87    + PID.output_Data[2];
+      MOTOR.Value[4] = (GUI.motor_min[4] - MOTOR_MIN_DEADZONE) * 10 + THROTTLE_VALUE - PID.output_Data[0]        + 0                          - PID.output_Data[2];
+      MOTOR.Value[5] = (GUI.motor_min[5] - MOTOR_MIN_DEADZONE) * 10 + THROTTLE_VALUE - PID.output_Data[0] / 2.0    - PID.output_Data[1] * 0.87    + PID.output_Data[2];
+      for (int i = 0; i < 6; i++) {
+        if ( MOTOR.Value[i] < ((GUI.motor_min[0] - MOTOR_MIN_DEADZONE) * 10 ) ) {
+          MOTOR.Value[i] = ((GUI.motor_min[0] - MOTOR_MIN_DEADZONE) * 10 );
+        }
+      }
     }
-    if(GUI.Compass_Calibration_Mode == 1){
-        // You can calibration of compass (Yaw)//   
+  } else if (GUI.DPN_Info == 4) {
+    MOTOR.Value[0] = (float)GUI.pwm_info[0] * 10;
+    MOTOR.Value[1] = (float)GUI.pwm_info[1] * 10;
+    MOTOR.Value[2] = (float)GUI.pwm_info[2] * 10;
+    MOTOR.Value[3] = (float)GUI.pwm_info[3] * 10;
+    MOTOR.Value[4] = (float)GUI.pwm_info[4] * 10;
+    MOTOR.Value[5] = (float)GUI.pwm_info[5] * 10;
+  }
+}
+
+
+void GUI_UPDATE() {
+  /////////////////////////////////////////////////////////////////////////////////////////////////////////
+  //////////////////////////////////////////// [M/S] Mode and State ///////////////////////////////////////
+  /////////////////////////////////////////////////////////////////////////////////////////////////////////
+  /* ************ MODE 1 ************* */
+  GUI.Mode1 = SBUS.CONTROLLER_STATE;
+  GUI.Alarm = !SPATIAL.SPATIAL_STABLE();
+
+  GUI.MissionState = AUTOFLIGHT_SEQUENCE;
+  GUI.Bat1 = BAT.update();
+  // [ Button State & Home Point Chksum & Marker Chksum ] is change automatically in "ROBOFRIEN_GUI.cpp" //
+  // You Can not change this setting, just use it ///
+  if (GUI.button[0] == true) {}
+  else {}
+  if (GUI.button[1] == true) {
+    AUTOFLIGHT_SEQUENCE = WAIT_TO_START;
+  }
+  else {}
+  if (GUI.button[2] == true) {}
+  else {}
+  if (GUI.button[3] == true) {}
+  else {}
+  if (GUI.button[4] == true) {}
+  else {}
+
+  /////////////////////////////////////////////////////////////////////////////////////////////////////////
+  //////////////////////////////////////////////// [GPS] GPS //////////////////////////////////////////////
+  /////////////////////////////////////////////////////////////////////////////////////////////////////////
+  GUI.utc_time = SPATIAL.UNIX_TIME;
+  GUI.latitude = (SPATIAL.LATITUDE * 1000000);
+  GUI.longitude = (SPATIAL.LONGITUDE * 1000000);
+  GUI.altitude =  SPATIAL.HEIGHT * 100;
+  GUI.SatNum = SPATIAL.SATELLITE_NUM;
+  /////////////////////////////////////////////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////// AHRS //////////////////////////////////////////////////
+  /////////////////////////////////////////////////////////////////////////////////////////////////////////
+  GUI.rollx100 = (SPATIAL.ROLL * 100);
+  GUI.pitchx100 = (SPATIAL.PITCH * 100);
+  GUI.yawx100 = ((SPATIAL.YAW ) * 100);
+  GUI.roll_ratex100 =  SPATIAL.ROLL_RATE * 100;
+  GUI.pitch_ratex100 =  SPATIAL.PITCH_RATE * 100;
+  GUI.yaw_ratex100 =  SPATIAL.YAW_RATE * 100;
+  GUI.VXx100 = SPATIAL.Vx * 100;
+  GUI.VYx100 = SPATIAL.Vy * 100;
+  GUI.VZx100 = SPATIAL.Vz * 100;
+
+  /////////////////////////////////////////////////////////////////////////////////////////////////////////
+  ////////////////////////////////////////////// [C/P] CAP/PWM ////////////////////////////////////////////
+  /////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+  GUI.cap[0] = SBUS.channel[0] / 10.0;
+  GUI.cap[1] = SBUS.channel[1] / 10.0;
+  GUI.cap[2] = SBUS.channel[2] / 10.0;
+  GUI.cap[3] = SBUS.channel[3] / 10.0;
+  GUI.cap[4] = SBUS.channel[4] / 10.0;
+  GUI.cap[5] = SBUS.channel[5] / 10.0;
+  GUI.cap[6] = SBUS.channel[6] / 10.0;
+  GUI.cap[7] = SBUS.channel[7] / 10.0;
+
+  GUI.pwm[0] = MOTOR.Value[0] / 100;         // (0 ~ 10000) --> ( 0 ~ 100 )
+  GUI.pwm[1] = MOTOR.Value[1] / 100;         // (0 ~ 10000) --> ( 0 ~ 100 )
+  GUI.pwm[2] = MOTOR.Value[2] / 100;         // (0 ~ 10000) --> ( 0 ~ 100 )
+  GUI.pwm[3] = MOTOR.Value[3] / 100;         // (0 ~ 10000) --> ( 0 ~ 100 )
+  GUI.pwm[4] = MOTOR.Value[4] / 100;         // (0 ~ 10000) --> ( 0 ~ 100 )
+  GUI.pwm[5] = MOTOR.Value[5] / 100;         // (0 ~ 10000) --> ( 0 ~ 100 )
+
+  /////////////////////////////////////////////////////////////////////////////////////////////////////////
+  /////////////////////////////////////////// [E/D] Extra & Debug /////////////////////////////////////////
+  /////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+  GUI.DEBUGx100[2] = (want_Angle[2] + 100) * 100;
+  GUI.DEBUGx100[3] = GUI.Controller_Joystick[3];
+  GUI.DEBUGx100[4] = GUI.Gimbal_Joystick[0];
+  GUI.DEBUGx100[5] = GUI.Gimbal_Joystick[1];
+  float PNU_RPM[2];
+  PNU_RPM[0] = sin( millis() / 10000.0 ) * 10000;
+  PNU_RPM[1] = cos( millis() / 10000.0 ) * 10000;
+  GUI.DEBUGx100[6] = PNU_RPM[0];
+  GUI.DEBUGx100[7] = PNU_RPM[1];
+
+  /////////////////////////////////////////////////////////////////////////////////////////////////////////
+  /////////////////////////////////////////// Configuration ///////////////////////////////////////////////
+  /////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+  ///////////////////////////// -----------------DPN 1-------------------- ////////////////////////////////
+  // You can set the this value from "Config.h"  ( EEPROM_MODEL_TYPE1, EEPROM_MODEL_TYPE2_UP, EEPROM_MODEL_TYPE2_DOWN ) //
+
+  ///////////////////////////// -----------------DPN 2-------------------- ////////////////////////////////
+  // You can set the this value from "Config.h"  ( MODEL_INFO, FIRMWARE_INFO ) //
+
+  ///////////////////////////// -----------------DPN 3-------------------- ////////////////////////////////
+  /// You can set the original value of receiver to [raw_cap] with scale down ( -127 ~ 127 ) ///
+  /// You can use the [cap_min[8], cap_neu[8], cap_max[8]] for calibration of RC receiver value //
+
+  ///////////////////////////// -----------------DPN 4-------------------- ////////////////////////////////
+  /// You can use the [pwm_info , motor_min[4]] for calibration of motor pwm value //
+
+  ///////////////////////////// -----------------DPN 5-------------------- ////////////////////////////////
+  /*
+      LED.HeadlightPeriod = GUI.headlight_period;
+      LED.HeadlightDutyrate = GUI.headlight_dutyrate;
+      LED.SidelightPeriod = GUI.sidelight_period;
+      LED.SidelightDutyrate = GUI.sidelight_dutyrate;
+  */
+  ///////////////////////////// -----------------DPN 6-------------------- ////////////////////////////////
+  /// You can set the original value of receiver to [raw_cap] with scale down ( -127 ~ 127 ) ///
+  /// You can use the [cap_min[8], cap_neu[8], cap_max[8]] for calibration of RC receiver value //
+  GUI.raw_cap[0] = (0 - 150) * 2;
+  GUI.raw_cap[1] = (0 - 150) * 2;
+  GUI.raw_cap[2] = (0 - 150) * 2;
+  GUI.raw_cap[3] = (0 - 150) * 2;
+  GUI.raw_cap[4] = (0 - 150) * 2;
+  GUI.raw_cap[5] = (0 - 150) * 2;
+  GUI.raw_cap[6] = 0;
+  GUI.raw_cap[7] = 0;
+
+  if (GUI.attitude_configuration_bool == true) {
+    GUI.attitude_configuration_bool = false;
+    // You can calibration of attitude (Roll, Pitch) //
+    //                GUI.attitude_calibrate(accelData[0]*aRes,accelData[1]*aRes,(accelData[2]*aRes-1));
+  }
+  if (GUI.Compass_Calibration_Mode == 1) {
+    // You can calibration of compass (Yaw)//
     //                if(ex_Compass_Calibration_Mode == 0){
-    //                    magnetic_offset_reset();                    
+    //                    magnetic_offset_reset();
     //                }else{
     //                    //// calibrating ... /////
-    //                    magnetic_calibration();                    
+    //                    magnetic_calibration();
     //                }
-    }else if(GUI.Compass_Calibration_Mode == 2){
-    //                // You can finish the calibration of compass   
+  } else if (GUI.Compass_Calibration_Mode == 2) {
+    //                // You can finish the calibration of compass
     //                //// write to eeprom ////
     //                GUI.Compass_Calibration_Mode = 0;
-    //                GUI.write_compass_setting_to_eeprom();     
-    }
-    //            ex_Compass_Calibration_Mode = GUI.Compass_Calibration_Mode;
-    
-    ///////////////////////////// -----------------DPN 7-------------------- ////////////////////////////////
-    /// You can use the [limit_rollx100, limit_pitchx100, limit_roll_rate, limit_pitch_rate, limit_yaw_rate] for limit the angle and angular velocity //
-    
-    ///////////////////////////// -----------------DPN 8-------------------- ////////////////////////////////
-    /// You can use the [gain_px100[20], gain_dx100[20], gain_ix100[20]] for gain tuning //
-    
-    /////////////////////////////////////////////////////////////////////////////////////////////////////////
-    //////////////////////////////////////////////// Refresh ////////////////////////////////////////////////
-    /////////////////////////////////////////////////////////////////////////////////////////////////////////
-//    GUI.trans_flight_data(255, 0);
-    GUI.pc_rx_update();
+    //                GUI.write_compass_setting_to_eeprom();
+  }
+  else if (GUI.Compass_Calibration_Mode == 3) {   // declination angle
+    SPATIAL.DECLINATION_ANGLE = GUI.declination_angle;
+  }
+  //            ex_Compass_Calibration_Mode = GUI.Compass_Calibration_Mode;
+
+  ///////////////////////////// -----------------DPN 7-------------------- ////////////////////////////////
+  /// You can use the [limit_rollx100, limit_pitchx100, limit_roll_ratex100, limit_pitch_ratex100, limit_yaw_ratex100] for limit the angle and angular velocity //
+
+  ///////////////////////////// -----------------DPN 8-------------------- ////////////////////////////////
+  /// You can use the [gain_px100[20], gain_dx100[20], gain_ix100[20]] for gain tuning //
+  /////////////////////////////////////////////////////////////////////////////////////////////////////////
+  //////////////////////////////////////////////// Refresh ////////////////////////////////////////////////
+  /////////////////////////////////////////////////////////////////////////////////////////////////////////
+  //    GUI.trans_flight_data(255, 0);
+  GUI.pc_rx_update();
+}
+
+void ANGLE_CONTROL(double IN_WANT_ANGLE[3]) {
+  /* ********* MIN - MAX ************* */
+  IN_WANT_ANGLE[0] = MIN_MAX(IN_WANT_ANGLE[0], -GUI.limit_rollx100 / 100.0, GUI.limit_rollx100 / 100.0 );
+  IN_WANT_ANGLE[1] = MIN_MAX(IN_WANT_ANGLE[1], -GUI.limit_pitchx100 / 100.0, GUI.limit_pitchx100 / 100.0 );
+  err_Angle[0] = IN_WANT_ANGLE[0] - SPATIAL.ROLL;
+  err_Angle[1] = IN_WANT_ANGLE[1] - SPATIAL.PITCH;
+  err_Angle[2] = IN_WANT_ANGLE[2] - SPATIAL.YAW;
+  if (err_Angle[2] > 180) err_Angle[2] -= 360;
+  else if (err_Angle[2] < -180) err_Angle[2] += 360;
+  want_Rate[0] = err_Angle[0] * GUI.gain_px100[0] / 100.0;    // Want Rate : Roll Rate
+  want_Rate[1] = err_Angle[1] * GUI.gain_dx100[0] / 100.0;    // Want Rate : Pitch Rate
+  want_Rate[2] = err_Angle[2] * GUI.gain_ix100[0] / 100.0;    // Want Rate : Yaw Rate
+  want_Rate[0] = MIN_MAX(want_Rate[0], -GUI.limit_roll_ratex100 / 100.0, GUI.limit_roll_ratex100 / 100.0);
+  want_Rate[1] = MIN_MAX(want_Rate[1], -GUI.limit_pitch_ratex100 / 100.0, GUI.limit_pitch_ratex100 / 100.0);
+  want_Rate[2] = MIN_MAX(want_Rate[2], -GUI.limit_yaw_ratex100 / 100.0, GUI.limit_yaw_ratex100 / 100.0);
+  PID.err_Rate[0] = (want_Rate[0] - SPATIAL.ROLL_RATE);
+  PID.err_Rate[1] = (want_Rate[1] - SPATIAL.PITCH_RATE);
+  PID.err_Rate[2] = (want_Rate[2] - SPATIAL.YAW_RATE);
+  PID.RAT_KP[0] = -GUI.gain_px100[1] / 100.0;
+  PID.RAT_KP[1] = -GUI.gain_px100[2] / 100.0;
+  PID.RAT_KP[2] = -GUI.gain_px100[3] / 100.0;
+  PID.RAT_KI[0] = -GUI.gain_ix100[1] / 100.0;
+  PID.RAT_KI[1] = -GUI.gain_ix100[2] / 100.0;
+  PID.RAT_KI[2] = -GUI.gain_ix100[3] / 100.0;
+  PID.update();
 }
-/*
-void DATA_OUTPUT(){
-    pc.printf("**** DATA ****\r\n");
-    pc.printf("UNIX_TIME : %f\r\n", UNIX_TIME);
-    pc.printf("LATITUDE : %f\r\n",LATITUDE);
-    pc.printf("LONGITUDE : %f\r\n",LONGITUDE);
-    pc.printf("HEIGHT : %f\r\n",HEIGHT);
-    pc.printf("Roll : %f\r\n",ROLL);
-    pc.printf("Pitch : %f\r\n",PITCH);
-    pc.printf("YAW : %f\r\n",YAW);
-    pc.printf("Roll Rate : %f\r\n",ROLL_RATE);
-    pc.printf("Pitch Rate : %f\r\n",PITCH_RATE);
-    pc.printf("YAW Rate : %f\r\n",YAW_RATE);
-    pc.printf("Vn : %f\r\n",Vn);
-    pc.printf("Ve : %f\r\n",Ve);
-    pc.printf("Vd : %f\r\n",Vd);
+
+double PLANE_VEL_INTEG[2];
+void PLANE_VEL_CONTROL(double IN_VEL_X, double IN_VEL_Y, double *OUTPUT_WANT_ROLL, double *OUTPUT_WANT_PITCH) {
+  double err_Vel[2];
+  err_Vel[0] = ( IN_VEL_X - SPATIAL.Vx );
+  err_Vel[1] = ( IN_VEL_Y - SPATIAL.Vy );
+  err_Vel[0] = MIN_MAX(err_Vel[0], -LIMIT_PROGRESS_VELOCITY, LIMIT_PROGRESS_VELOCITY);
+  err_Vel[1] = MIN_MAX(err_Vel[1], -LIMIT_PROGRESS_VELOCITY, LIMIT_PROGRESS_VELOCITY);
+  *OUTPUT_WANT_PITCH = -(err_Vel[0] * (GUI.gain_dx100[4] / 100.0));
+  *OUTPUT_WANT_ROLL  = +(err_Vel[1] * (GUI.gain_dx100[5] / 100.0));
+
+  /* ******** VEL PID - I **************** */
+  PLANE_VEL_INTEG[0] -= (err_Vel[0]) * (GUI.gain_ix100[4] / 100.0);
+  PLANE_VEL_INTEG[1] += (err_Vel[1]) * (GUI.gain_ix100[5] / 100.0);
+  PLANE_VEL_INTEG[0] = MIN_MAX(PLANE_VEL_INTEG[0], -LIMIT_PLANE_VEL_INTEG, LIMIT_PLANE_VEL_INTEG);
+  PLANE_VEL_INTEG[1] = MIN_MAX(PLANE_VEL_INTEG[1], -LIMIT_PLANE_VEL_INTEG, LIMIT_PLANE_VEL_INTEG);
+  *OUTPUT_WANT_PITCH += PLANE_VEL_INTEG[0];
+  *OUTPUT_WANT_ROLL  += PLANE_VEL_INTEG[1];
+
 }
-*/
\ No newline at end of file
+
+double VERTICAL_VEL_INTEG;
+void VERTICAL_VEL_CONTROL(double IN_VEL_Z, double *OUTPUT_THROTTLE_VALUE) {
+  double err_Vel_Z;
+  err_Vel_Z = IN_VEL_Z - SPATIAL.Vz;
+  if (err_Vel_Z >= 0) err_Vel_Z = MIN_MAX(err_Vel_Z, -LIMIT_UP_VELOCITY, LIMIT_UP_VELOCITY);
+  else err_Vel_Z = MIN_MAX(err_Vel_Z, -LIMIT_DOWN_VELOCITY, LIMIT_DOWN_VELOCITY);
+  *OUTPUT_THROTTLE_VALUE = (err_Vel_Z * 10) * (GUI.gain_dx100[6] / 100.0);
+
+  VERTICAL_VEL_INTEG += (err_Vel_Z) * (GUI.gain_ix100[6] / 100.0);
+  VERTICAL_VEL_INTEG = MIN_MAX(VERTICAL_VEL_INTEG, -LIMIT_VERTICAL_VEL_INTEG, LIMIT_VERTICAL_VEL_INTEG);
+  *OUTPUT_THROTTLE_VALUE += VERTICAL_VEL_INTEG;
+
+  *OUTPUT_THROTTLE_VALUE = MIN_MAX(*OUTPUT_THROTTLE_VALUE, -THROTTLE_CONTROL_LIMIT, THROTTLE_CONTROL_LIMIT);
+
+  *OUTPUT_THROTTLE_VALUE += THROTTLE_BASE;
+
+  *OUTPUT_THROTTLE_VALUE = MIN_MAX( *OUTPUT_THROTTLE_VALUE, THROTTLE_MIN, THROTTLE_MAX );
+
+}
+
+void VEL_INTEG_RESET() {
+  PLANE_VEL_INTEG[0] = 0; PLANE_VEL_INTEG[1] = 0; VERTICAL_VEL_INTEG = 0;
+}
+
+float DEG_TO_METER(float lat1, float lon1, float lat2, float lon2) {
+  float R = 6378.137;     // Radius of earth in KM
+  float dLat = lat2 * M_PI / 180.0 - lat1 * M_PI / 180.0;
+  float dLon = lon2 * M_PI / 180.0 - lon1 * M_PI / 180.0;
+  float a = sin(dLat / 2.0) * sin(dLat / 2.0) + cos(lat1 * M_PI / 180.0) * cos(lat2 * M_PI / 180.0) * sin(dLon / 2.0) * sin(dLon / 2.0);
+  float c = 2 * atan2(sqrt(a), sqrt(1 - a));
+  float d = R * c;
+  return d * 1000;    // meters
+}
--- a/mbed.bld	Tue Jun 12 01:05:50 2018 +0000
+++ b/mbed.bld	Wed Nov 28 13:06:23 2018 +0000
@@ -1,1 +1,1 @@
-https://os.mbed.com/users/mbed_official/code/mbed/builds/5aab5a7997ee
\ No newline at end of file
+http://mbed.org/users/mbed_official/code/mbed/builds/c0f6e94411f5
\ No newline at end of file