diff --git a/README.md b/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..c3230c1a1ec51585324e82b038daf4e89eb321d3
--- /dev/null
+++ b/README.md
@@ -0,0 +1,26 @@
+## 상업용 드론 안정성 인증 시스템 
+
+### 사용 센서 및 액츄에이터
+- 1. Sensor
+    - 초음파 센서 (HC-SR04) : 2 EA
+    - 자이로 센서 (MPU6050) : 1 EA
+- 2. Actuator
+    - 서보모터 (SG90) : 2 EA
+    - RGB : 4 EA
+
+### 구현 시스템
+
+- 1. 충돌회피 시스템  
+- 2. 배송물 평형유지 시스템
+
+#### 충돌회피 시스템
+
+<img src="/uploads/5a1d74c3b12474cac9db5876da56734d/readme_1.PNG" width="65%" height="65%">
+
+- 참고 코드 : w4_client_velocity.c , server.c
+
+#### 배송물 평형유지 시스템
+
+<img src="/uploads/a884968f935932e59fcb92e775064761/readme_2.PNG" width="65%" height="65%">
+
+- 참고 코드 : Gyro.c, server.c
\ No newline at end of file
diff --git a/server.c b/server.c
new file mode 100644
index 0000000000000000000000000000000000000000..8d9c148b0871c64907c802f6d95aeddeea5a175d
--- /dev/null
+++ b/server.c
@@ -0,0 +1,565 @@
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+
+#include <time.h>
+
+#define IN 0
+#define OUT 1
+#define LOW 0
+#define HIGH 1
+
+#define R1 4
+#define G1 17
+#define B1 27
+
+#define R2 22
+#define G2 5
+#define B2 6
+
+#define R3 23
+#define G3 24
+#define B3 25
+
+#define R4 16
+#define G4 20
+#define B4 21
+
+#define BUFFER_MAX 45
+#define DIRECTION_MAX 45
+#define VALUE_MAX 256
+char clipara_rgb[6];
+char clipara_motor[6];
+int exitcode=0;
+
+
+static int PWMExport(int pwmnum){
+    char buffer[BUFFER_MAX];
+    int bytes_written;
+    int fd;
+
+    fd = open("/sys/class/pwm/pwmchip0/unexport", O_WRONLY);
+    if(-1 == fd){
+        fprintf(stderr, "Failed to open in unexport!\n");
+        return(-1);
+    }
+
+    bytes_written = snprintf(buffer, BUFFER_MAX, "%d", pwmnum);
+    write(fd, buffer, bytes_written);
+    close(fd);
+
+    sleep(1);
+    fd = open("/sys/class/pwm/pwmchip0/export", O_WRONLY);
+    if(-1 == fd){
+        fprintf(stderr, "Failed to open in export!\n");
+        return(-1);
+    }
+    bytes_written = snprintf(buffer, BUFFER_MAX, "%d", pwmnum);
+    write(fd, buffer, bytes_written);
+    close(fd);
+    sleep(1);
+    return(0);
+}
+
+static int PWMEnable(int pwmnum){
+    static const char s_unenable_str[] = "0";
+    static const char s_enable_str[] = "1";
+
+    char path[DIRECTION_MAX];
+    int fd;
+
+    snprintf(path, DIRECTION_MAX, "/sys/class/pwm/pwmchip0/pwm%d/enable", pwmnum);
+    fd = open(path, O_WRONLY);
+    if(-1 == fd){
+        fprintf(stderr, "Failed to open in enalbe!\n");
+        return(-1);
+    }
+
+    write(fd, s_unenable_str, strlen(s_unenable_str));
+    close(fd);
+
+    fd = open(path, O_WRONLY);
+    if(-1 == fd){
+        fprintf(stderr, "Failed to open in enalbe!\n");
+        return(-1);
+    }
+
+    write(fd, s_enable_str, strlen(s_enable_str));
+    close(fd);
+    return(0);
+}
+
+static int PWMWritePeriod(int pwmnum, int value){
+    char s_values_str[VALUE_MAX];
+    char path[VALUE_MAX];
+    int fd,byte;
+
+    snprintf(path, VALUE_MAX, "/sys/class/pwm/pwmchip0/pwm%d/period", pwmnum);
+    fd = open(path, O_WRONLY);
+    if(-1 == fd){
+        fprintf(stderr, "Failed to open in period!\n");
+        return(-1);
+    }
+
+    byte = snprintf(s_values_str, VALUE_MAX, "%d", value);
+
+    if(-1 == write(fd,s_values_str,byte)){
+        fprintf(stderr, "Failed to write value in period!\n");
+        return(-1);
+    }
+
+    close(fd);
+    return(0);
+}
+
+static int PWMWriteDutyCycle(int pwmnum, int value){
+    char path[VALUE_MAX];
+    char s_values_str[VALUE_MAX];
+    int fd, byte;
+
+    snprintf(path, VALUE_MAX, "/sys/class/pwm/pwmchip0/pwm%d/duty_cycle", pwmnum);
+    fd = open(path, O_WRONLY);
+    if(-1 == fd){
+        fprintf(stderr, "Failed to open in duty_cycle!\n");
+        return(-1);
+    }
+
+    byte = snprintf(s_values_str, VALUE_MAX, "%d", value);
+
+    if(-1 == write(fd, s_values_str, byte)){
+        fprintf(stderr, "Failed to write value! in duty_cycle\n");
+        close(fd);
+        return(-1);
+    }
+
+    close(fd);
+    return(0);
+}
+
+
+static int GPIOUnexport(int pin){
+   char buffer[BUFFER_MAX];
+   ssize_t bytes_written;
+   int fd;
+   
+   fd=open("/sys/class/gpio/unexport",O_WRONLY);
+   if(-1==fd){
+      fprintf(stderr,"falied to pen unexport\n");
+      return -1;
+   }
+   
+   bytes_written=snprintf(buffer,BUFFER_MAX,"%d",pin);
+   write(fd,buffer,bytes_written);
+   close(fd);
+   return 0;
+}
+
+static int GPIODirection(int pin,int dir){
+      static const char s_directions_str[]="in\0out";
+      
+   
+   char path[DIRECTION_MAX]="/sys/class/gpio/gpio%d/direction";
+   int fd;
+   
+   snprintf(path, DIRECTION_MAX, "/sys/class/gpio/gpio%d/direction",pin);
+   
+   fd=open(path,O_WRONLY);
+   if(-1==fd){
+       fprintf(stderr,"%d pin err ",pin);
+      fprintf(stderr,"Failed to open gpio direction for writing!\n");
+      return -1;
+   }
+   
+   if(-1==write(fd,&s_directions_str[IN == dir ? 0 :3], IN==dir ? 2:3)){
+      fprintf(stderr,"failed to set direction!\n");
+      return -1;
+   }
+   
+   close(fd);
+   return 0;
+}
+
+static int GPIOExport(int pin){
+
+   char buffer[BUFFER_MAX];
+   ssize_t bytes_written;
+   int fd;
+   
+   fd=open("/sys/class/gpio/export",O_WRONLY);
+   if(-1==fd){
+      fprintf(stderr, "failed export wr");
+      return 1;
+   }
+   bytes_written=snprintf(buffer,BUFFER_MAX, "%d", pin);
+   write(fd,buffer,bytes_written);
+   close(fd);
+   return 0;
+}
+
+
+static int GPIOWrite(int pin, int value){
+      static const char s_values_str[] ="01";
+      
+      char path[VALUE_MAX];
+      int fd;
+
+      
+      snprintf(path,VALUE_MAX, "/sys/class/gpio/gpio%d/value",pin);
+      fd=open(path,O_WRONLY);
+      if(-1==fd){
+         fprintf(stderr,"failed open gpio write\n");
+         return -1;
+      }
+      
+      //0 1 selection
+      if(1!=write(fd,&s_values_str[LOW==value ? 0:1],1)){
+         fprintf(stderr,"failed to write value\n");
+         return -1;
+      }
+      close(fd);
+      return 0;
+}
+static int GPIORead(int pin){
+    char path[VALUE_MAX];
+    char value_str[3];
+    int fd;
+
+    snprintf(path, VALUE_MAX, "/sys/class/gpio/gpio%d/value",pin);
+    fd=open(path, O_RDONLY);
+    if(-1==fd){
+        fprintf(stderr,"failed to open gpio value for reading\n");
+        return -1;
+    }
+
+    if(-1==read(fd,value_str,3)){
+        fprintf(stderr,"failed to read val\n");
+        return -1;
+    }
+    close(fd);
+
+    return(atoi(value_str));
+}
+
+void error_handling(char *message){
+    fputs(message,stderr);
+    fputc('\n',stderr);
+    exit(1);
+}
+
+int unexport_GPIOs(){
+    //Enable GPIO pins
+    if (-1 == GPIOUnexport(R1) || -1 == GPIOUnexport(R2)|| -1 == GPIOUnexport(R3)|| -1 == GPIOUnexport(R4)|| -1 == GPIOUnexport(G1)|| -1 == GPIOUnexport(G2)|| -1 == GPIOUnexport(G3)
+    || -1 == GPIOUnexport(G4)|| -1 == GPIOUnexport(B1)|| -1 == GPIOUnexport(B2)|| -1 == GPIOUnexport(B3)|| -1 == GPIOUnexport(B4))
+        return -1;
+    return 0;
+}
+int export_GPIOs(){
+    //Enable GPIO pins
+    if (-1 == GPIOExport(R1) || -1 == GPIOExport(R2)|| -1 == GPIOExport(R3)|| -1 == GPIOExport(R4)|| -1 == GPIOExport(G1)|| -1 == GPIOExport(G2)|| -1 == GPIOExport(G3)
+    || -1 == GPIOExport(G4)|| -1 == GPIOExport(B1)|| -1 == GPIOExport(B2)|| -1 == GPIOExport(B3)|| -1 == GPIOExport(B4))
+        return -1;
+    return 0;
+}
+int direction_GPIOs(){
+    if(-1==GPIODirection(R1,OUT)||-1==GPIODirection(R2,OUT)||-1==GPIODirection(R3,OUT)||-1==GPIODirection(R4,OUT)||-1==GPIODirection(G1,OUT)||-1==GPIODirection(G2,OUT)
+    ||-1==GPIODirection(G3,OUT)||-1==GPIODirection(G4,OUT)||-1==GPIODirection(B1,OUT)||-1==GPIODirection(B2,OUT)||-1==GPIODirection(B3,OUT)||-1==GPIODirection(B4,OUT))
+        return -1;
+    return 0;
+}
+int turnOffRGBs(){
+    if(-1==GPIOWrite(R1,0)||-1==GPIOWrite(G1,0)||-1==GPIOWrite(B1,0)||-1==GPIOWrite(R2,0)||-1==GPIOWrite(G2,0)||-1==GPIOWrite(B2,0)
+    ||-1==GPIOWrite(R3,0)||-1==GPIOWrite(G3,0)||-1==GPIOWrite(B3,0)||-1==GPIOWrite(R4,0)||-1==GPIOWrite(G4,0)||-1==GPIOWrite(B4,0))
+        return -1;
+    return 0;
+}
+
+int RGB_setting(int position,int r,int g,int b){
+    int Rn,Gn,Bn;
+    if(position==1){
+        Rn=R1; Gn=G1; Bn=B1;
+    }else if(position==2){
+        Rn=R2; Gn=G2; Bn=B2;
+    }else if(position==3){
+        Rn=R3; Gn=G3; Bn=B3;
+    }if(position==4){
+        Rn=R4; Gn=G4; Bn=B4;
+    }
+
+    if(-1==GPIOWrite(Rn,r)||-1==GPIOWrite(Gn,g)||-1==GPIOWrite(Bn,b))
+        return -1;
+    return 0;
+}
+
+int RGB_8steps(int pos,int step){
+    int r,g,b;
+     for (int i = 2; i >= 0; --i) { //8자리 숫자까지 나타냄
+        int result = step >> i & 1;
+        if(i==2)
+            r=result;
+        if(i==1)
+            g=result;
+        if(i==0)
+            b=result;
+    }
+    RGB_setting(pos,r,g,b);
+}
+
+int motor_speed(int step){
+    if(step==0){
+        return 0;
+    }else if(step==1){
+        return 500;
+    }else if(step==2){
+        return 100;
+    }
+}
+    
+    void step3_motor_speed(int pwmnum,int step,int period){
+        double f=0.0;
+         int speed=motor_speed(step);
+         if(step==0){
+            PWMWriteDutyCycle(pwmnum,0);    
+            return;
+         }
+            
+
+        f=0.05;        
+        PWMWriteDutyCycle(pwmnum,period*f);
+        usleep(speed*1000);
+         f=0.990;
+        PWMWriteDutyCycle(pwmnum,period*f);
+        usleep(speed*1000);
+    }
+
+void *motor_thread(){
+fprintf(stderr,"motor thread\n");
+    int period=9000000;
+    PWMExport(0); //pwm0 is gpio18
+    PWMWritePeriod(0,period);
+    PWMWriteDutyCycle(0,0);
+    PWMEnable(0);
+
+    
+    while(1){
+        
+        int d1=clipara_motor[1]-48;
+        
+        // printf("thr 1 motor %d\n",d1);
+        if(d1==-48){
+            usleep(10*1000);
+            continue;
+        }
+        step3_motor_speed(0,d1,period);
+       
+        
+    }
+
+    
+}
+
+void *motor_thread2(){
+    // fprintf(stderr,"motor thread\n");
+    int period=9000000;
+
+    PWMExport(1); //pwm0 is gpio18
+    PWMWritePeriod(1,period);
+    PWMWriteDutyCycle(1,0);
+    PWMEnable(1);
+    
+    int speed=1000;
+    while(1){
+        int d2=clipara_motor[2]-48;
+        // printf("thr 2 motor %d\n",d2);
+        // printf("thr 2 %s",clipara_motor);
+        if(d2==-48){
+            usleep(10*1000);
+            continue;
+        }
+        step3_motor_speed(1,d2,period);
+        
+    }
+}
+
+
+void *rgb_thread(){
+
+    if(-1==export_GPIOs())
+        return 1;
+    //Set GPIO directions
+    if (-1 ==direction_GPIOs())
+        return (2);
+    if (-1 == turnOffRGBs())
+        return (3);
+    
+     int c=0;
+    while(1){
+         if(exitcode==1){
+            turnOffRGBs();
+            break;
+        }
+        int d1=clipara_rgb[1]-48;
+        int d2=clipara_rgb[2]-48;
+        int d3=clipara_rgb[3]-48;
+        int d4=clipara_rgb[4]-48;
+        if(d1==-48&&d1==d2&&d1==d3&&d1==d4){
+            continue;
+        }
+        // printf("clipara_rgb: %s ",clipara_rgb);
+        // printf("%d %d %d %d \n",d1,d2,d3,d4);
+        RGB_8steps(1,d1);
+        RGB_8steps(2,d2);
+        RGB_8steps(3,d3);
+         RGB_8steps(4,d4);
+       
+        usleep(1000*50);
+    }
+
+}
+
+int serv_sock=-1;
+struct sockaddr_in serv_addr;
+
+void *rcv_cli(){
+    int clnt_sock2=-1;
+    struct sockaddr_in clnt_addr2;
+    socklen_t clnt_addr_size;
+    int str_len;
+    char msg2[6];
+    if (clnt_sock2 < 0)
+        {
+            clnt_addr_size = sizeof(clnt_addr2);
+            clnt_sock2 = accept(serv_sock, (struct sockaddr *)&clnt_addr2,
+                            &clnt_addr_size);
+            if (clnt_sock2 == -1)
+                error_handling("accept() error");
+        }
+     while (1)
+    {
+        str_len=read(clnt_sock2,msg2,sizeof(msg2));
+        if(str_len==-1)
+            error_handling("read() error");
+        
+        if(msg2[0]=='s'){
+            strcpy(clipara_rgb,msg2);
+
+        }else{
+            strcpy(clipara_motor,msg2);
+            
+        }
+        printf("received msg2 -> %s\n",msg2);
+        usleep(10 * 1000);
+    }
+    close(clnt_sock2);
+}
+int main(int argc, char *argv[])
+{
+    int state = 1;
+    int prev_state = 1;
+    int light = 0;
+
+    int clnt_sock= -1;
+    struct sockaddr_in  clnt_addr;
+    socklen_t clnt_addr_size;
+    
+    char msg[6];
+    char msg2[6];
+    int str_len;
+    
+    pthread_t p_thread[2];
+    int thr_id;
+    int status;
+
+    char p1[] = "thread_1";
+    char p2[] = "thread_2";
+
+    if(argc==3){
+        exitcode=1;
+        fprintf(stderr,"all stopped\n");
+        return 0;
+    }
+    fprintf(stderr,"%d",argc);
+
+    thr_id = pthread_create(&p_thread[0], NULL, motor_thread, NULL);
+    if(thr_id < 0){
+        perror("thread create error : ");
+        exit(0);
+        usleep(1000);
+    }
+     thr_id = pthread_create(&p_thread[1], NULL, motor_thread2, NULL);
+    if(thr_id < 0){
+        perror("thread create error : ");
+        exit(0);
+        usleep(1000);
+    }
+    thr_id = pthread_create(&p_thread[2], NULL, rgb_thread, NULL);
+    if(thr_id < 0){
+        perror("thread create error : ");
+        exit(0);
+        usleep(1000);
+    }
+
+    if (argc != 2)
+    {
+        printf("Usage : %s <port>\n", argv[0]);
+    }
+
+    serv_sock = socket(PF_INET, SOCK_STREAM, 0);
+    if (serv_sock == -1)
+        error_handling("socket() error");
+
+    memset(&serv_addr, 0, sizeof(serv_addr));
+    serv_addr.sin_family = AF_INET;
+    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+    serv_addr.sin_port = htons(atoi(argv[1]));
+    
+    if (bind(serv_sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1)
+        error_handling("bind() error");
+    if (listen(serv_sock, 5) == -1)
+        error_handling("listen() error");
+   
+    if (clnt_sock < 0)
+    {
+        clnt_addr_size = sizeof(clnt_addr);
+        clnt_sock = accept(serv_sock, (struct sockaddr *)&clnt_addr,
+                           &clnt_addr_size);
+        if (clnt_sock == -1)
+            error_handling("accept() error");
+    }
+    
+     thr_id = pthread_create(&p_thread[0], NULL, rcv_cli, NULL);
+    if(thr_id < 0){
+        perror("thread create error : ");
+        exit(0);
+        usleep(1000);
+    }
+    while (1)
+    {
+        str_len=read(clnt_sock,msg,sizeof(msg));
+        if(str_len==-1)
+            error_handling("read() error");
+
+        if(msg[0]=='s'){
+            
+            strcpy(clipara_rgb,msg);
+
+        }else{
+            strcpy(clipara_motor,msg);
+            
+        }
+        printf("received msg -> %s\n",msg);
+        usleep(10 * 1000);
+    }
+    close(clnt_sock);
+    close(serv_sock);
+    // //Disable GPIO pins
+    if (-1==unexport_GPIOs())
+        return (4);
+    return (0);
+}
\ No newline at end of file