diff --git a/Code/Control/Laptop_Code/ESP32_slave/ESP32_slave.ino b/Code/Control/Laptop_Code/ESP32_slave/ESP32_slave.ino
index 43434c83c03c63ad0020f1e3a5b5eea74064f01e..b642da5d681b7b1dbe90e8a5790c85d423950f15 100644
--- a/Code/Control/Laptop_Code/ESP32_slave/ESP32_slave.ino
+++ b/Code/Control/Laptop_Code/ESP32_slave/ESP32_slave.ino
@@ -316,5 +316,5 @@ void send_message(){
     Serial.println("Error sending the data");
   }
   //-------------------------------------------------------------------------------------
-  // delay(50); // delay 50 ms after send out the message 
+  delay(50); // delay 50 ms after send out the message 
 }
diff --git a/Code/Control/Laptop_Code/Previous_low_level/ESP32_slave/Camera.cpp b/Code/Control/Laptop_Code/Previous_low_level/ESP32_slave/Camera.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fb27cf808991a0b2083ca36f412ba1aa088527e6
--- /dev/null
+++ b/Code/Control/Laptop_Code/Previous_low_level/ESP32_slave/Camera.cpp
@@ -0,0 +1,91 @@
+#include "Camera.h"
+#include <Wire.h>
+#include <Arduino.h>
+#include <openmvrpc.h>
+
+Camera::Camera(openmv::rpc_i2c_master *intface){
+  interface = intface;
+}
+
+void Camera::exe_face_detection(){
+    struct { uint16_t x, y, w, h; } face_detection_result;
+    if (interface->call_no_args(F("face_detection"), &face_detection_result, sizeof(face_detection_result))) {
+        Serial.print(F("Largest Face Detected [x="));
+        Serial.print(face_detection_result.x);
+        Serial.print(F(", y="));
+        Serial.print(face_detection_result.y);
+        Serial.print(F(", w="));
+        Serial.print(face_detection_result.w);
+        Serial.print(F(", h="));
+        Serial.print(face_detection_result.h);
+        Serial.println(F("]"));
+    }
+}
+
+bool Camera::exe_apriltag_detection(int ID,int *x_temp,int *y_temp,int *angle_temp){
+    struct { uint16_t cx, cy, rot; } result;
+    if (interface->call(F("apriltags"), &ID, sizeof(ID), &result, sizeof(result))) {
+    }
+    if (result.cx == 0 && result.cy == 0 && result.rot == 0){
+      return false;
+    } else {
+      *x_temp = result.cx;
+      *y_temp = result.cy;
+      *angle_temp = result.rot;
+      return true;
+    }
+}
+  
+bool Camera::exe_color_detection(int8_t l_min, int8_t l_max, int8_t a_min, int8_t a_max, int8_t b_min, int8_t b_max){
+    int8_t color_thresholds[6] = {l_min, l_max, a_min, a_max, b_min, b_max};
+    short buff[128 + 1] = {};
+    if (interface->call(F("color_detection"), color_thresholds, sizeof(color_thresholds), buff, sizeof(buff)-1)) {
+          int i = 0;
+          while (buff[i] != '\0' && i<100) {
+            Serial.print(buff[i]);
+            i++;  
+          }
+          Serial.println("");
+    }
+    if (buff[0] == 0){ //no blob detected
+      return false;
+    } else {
+      return true;
+    }
+}
+
+bool Camera::exe_color_detection_biggestblob(int8_t l_min, int8_t l_max, int8_t a_min, int8_t a_max, int8_t b_min, int8_t b_max, int& x, int&y){
+  int8_t color_thresholds[6] = {l_min, l_max, a_min, a_max, b_min, b_max};
+  struct { uint16_t cx, cy; } color_detection_result;
+  if (interface->call(F("color_detection_single"), color_thresholds, sizeof(color_thresholds), &color_detection_result, sizeof(color_detection_result))) {
+    
+  }
+  x = color_detection_result.cx;
+  y = color_detection_result.cy;
+  if (x == 0 && y == 0){
+    return false;
+  } else {
+    return true;
+  }
+}
+
+
+bool Camera::exe_goalfinder(int8_t goal1, int8_t goal2, int8_t goal3, int&id, int&tx, int&ty, int&tz, int&rx, int&ry, int&rz){
+  int8_t goalid[3] = {goal1, goal2, goal3};
+  struct { uint16_t cid, ctx, cty, ctz, crx, cry, crz; } goalfinder_result;
+  if(interface->call(F("goalfinder"), goalid, sizeof(goalid), &goalfinder_result, sizeof(goalfinder_result))){
+    
+  }
+  if (goalfinder_result.crx == 0 && goalfinder_result.cry == 0){
+    return false;
+  } else {
+    id = goalfinder_result.cid;
+    tx = goalfinder_result.ctx;
+    ty = goalfinder_result.cty;
+    tz = goalfinder_result.ctz;
+    rx = goalfinder_result.crx;
+    ry = goalfinder_result.cry;
+    rz = goalfinder_result.crz;
+    return true;
+  }
+}
diff --git a/Code/Control/Laptop_Code/Previous_low_level/ESP32_slave/Camera.h b/Code/Control/Laptop_Code/Previous_low_level/ESP32_slave/Camera.h
new file mode 100644
index 0000000000000000000000000000000000000000..5a4536e6d0967e96fd5864e596b8f8f9f0312289
--- /dev/null
+++ b/Code/Control/Laptop_Code/Previous_low_level/ESP32_slave/Camera.h
@@ -0,0 +1,19 @@
+#ifndef CAMERA_H
+#define CAMERA_H
+#include <openmvrpc.h>
+
+class Camera 
+{
+  private:
+  openmv::rpc_i2c_master *interface;
+  
+  public:
+  Camera(openmv::rpc_i2c_master *intface);
+  void exe_face_detection(); // Face should be about 2ft away.
+  bool exe_apriltag_detection(int ID,int *x_temp,int *y_temp,int *angle_temp);
+  bool exe_color_detection(int8_t l_min, int8_t l_max, int8_t a_min, int8_t a_max, int8_t b_min, int8_t b_max);
+  bool exe_color_detection_biggestblob(int8_t l_min, int8_t l_max, int8_t a_min, int8_t a_max, int8_t b_min, int8_t b_max, int& x, int&y);
+  bool exe_goalfinder(int8_t goal1, int8_t goal2, int8_t goal3, int&id, int&tx, int&ty, int&tz, int&rx, int&ry, int&rz); //optional to add tag size as parameter?
+
+};
+#endif
diff --git a/Code/Control/Laptop_Code/Previous_low_level/ESP32_slave/ESP32_slave.ino b/Code/Control/Laptop_Code/Previous_low_level/ESP32_slave/ESP32_slave.ino
index 9f133bb5f337b1c4ff34ba590d9409bf3b9cea8f..37e23c4c1bba7cbbfc667484fad80b35460551a4 100644
--- a/Code/Control/Laptop_Code/Previous_low_level/ESP32_slave/ESP32_slave.ino
+++ b/Code/Control/Laptop_Code/Previous_low_level/ESP32_slave/ESP32_slave.ino
@@ -11,7 +11,8 @@
 // REPLACE WITH THE MAC Address of your receiver (MASTER) 
 // Slave: 40:F5:20:44:B6:4C 
 // uint8_t broadcastAddress[] = {0x3C, 0x61, 0x05, 0x4A, 0xCF, 0x00}; 
-uint8_t broadcastAddress[] = {0x40, 0xF5, 0x20, 0x44, 0xB6, 0x4C}; // #4 
+ uint8_t broadcastAddress[] = {0x40, 0xF5, 0x20, 0x44, 0xB6, 0x4C}; // #4 
+// uint8_t broadcastAddress[] = {0xc4, 0xDD, 0x57, 0x9E, 0x8A, 0x98}; // #3
 String success; 
  
 // Define variables to store incoming readings 
@@ -82,10 +83,10 @@ void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
   Serial.print("\r\nLast Packet Send Status:\t"); 
   Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail"); 
   if (status ==0){ 
-    success = "Delivery Success :)"; 
+    success = "Delivery Success 🙂"; 
   } 
   else{ 
-    success = "Delivery Fail :("; 
+    success = "Delivery Fail 🙁"; 
   } 
 } 
  
@@ -210,7 +211,7 @@ void loop()
     Sent_dist = 0; 
   } 
   // ========== lidar state info ========= 
-  if (Sent_dist < 300 && Sent_dist < 0){ 
+  if (Sent_dist < 300 && Sent_dist > 0){ 
     receivedData.DebugM = "found b"; 
   }else{ 
     receivedData.DebugM = "no b"; 
@@ -284,7 +285,7 @@ void print_received_Data(){
   Serial.println(Rec_dir3); 
   Serial.print("Rec_dir4:"); 
   Serial.println(Rec_dir4);     
-Serial.println("_________________________"); 
+Serial.println("_______________________"); 
   } 
   print_count +=1; 
 } 
@@ -316,4 +317,4 @@ void send_message(){
   } 
   //------------------------------------------------------------------------------------- 
   delay(50); // delay 50 ms after send out the message  
-} 
+}
diff --git a/Code/Control/Laptop_Code/Previous_low_level/ESP32_slave/utilities.cpp b/Code/Control/Laptop_Code/Previous_low_level/ESP32_slave/utilities.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7a90e33a9ea7f73c7ad525b0919f9c69b4928fda
--- /dev/null
+++ b/Code/Control/Laptop_Code/Previous_low_level/ESP32_slave/utilities.cpp
@@ -0,0 +1,83 @@
+#include <math.h>
+
+//Source: http://www.easyrgb.com/index.php?X=MATH&H=01#text1
+void lab2rgb( float l_s, float a_s, float b_s, float& R, float& G, float& B )
+{
+    float var_Y = ( l_s + 16. ) / 116.;
+    float var_X = a_s / 500. + var_Y;
+    float var_Z = var_Y - b_s / 200.;
+
+    if ( pow(var_Y,3) > 0.008856 ) var_Y = pow(var_Y,3);
+    else                      var_Y = ( var_Y - 16. / 116. ) / 7.787;
+    if ( pow(var_X,3) > 0.008856 ) var_X = pow(var_X,3);
+    else                      var_X = ( var_X - 16. / 116. ) / 7.787;
+    if ( pow(var_Z,3) > 0.008856 ) var_Z = pow(var_Z,3);
+    else                      var_Z = ( var_Z - 16. / 116. ) / 7.787;
+
+    float X = 95.047 * var_X ;    //ref_X =  95.047     Observer= 2°, Illuminant= D65
+    float Y = 100.000 * var_Y  ;   //ref_Y = 100.000
+    float Z = 108.883 * var_Z ;    //ref_Z = 108.883
+
+
+    var_X = X / 100. ;       //X from 0 to  95.047      (Observer = 2°, Illuminant = D65)
+    var_Y = Y / 100. ;       //Y from 0 to 100.000
+    var_Z = Z / 100. ;      //Z from 0 to 108.883
+
+    float var_R = var_X *  3.2406 + var_Y * -1.5372 + var_Z * -0.4986;
+    float var_G = var_X * -0.9689 + var_Y *  1.8758 + var_Z *  0.0415;
+    float var_B = var_X *  0.0557 + var_Y * -0.2040 + var_Z *  1.0570;
+
+    if ( var_R > 0.0031308 ) var_R = 1.055 * pow(var_R , ( 1 / 2.4 ))  - 0.055;
+    else                     var_R = 12.92 * var_R;
+    if ( var_G > 0.0031308 ) var_G = 1.055 * pow(var_G , ( 1 / 2.4 ) )  - 0.055;
+    else                     var_G = 12.92 * var_G;
+    if ( var_B > 0.0031308 ) var_B = 1.055 * pow( var_B , ( 1 / 2.4 ) ) - 0.055;
+    else                     var_B = 12.92 * var_B;
+
+    R = var_R * 255.;
+    G = var_G * 255.;
+    B = var_B * 255.;
+
+}
+
+
+
+
+
+//old codes
+
+//      motorVertical->setSpeed(0);
+//      motorVertical->run(FORWARD);
+//      // turn on motor
+//      motorVertical->run(RELEASE);
+//      Serial.println(SEEKING_SPEED);
+//      motorLeft->setSpeed(SEEKING_SPEED);
+//      motorLeft->run(FORWARD); 
+//      motorRight->setSpeed(SEEKING_SPEED);
+
+//    if (abs(Outputx) < 125){
+//      motorRight->setSpeed(BASE_SPEED - Outputx); 
+//      motorRight->run(BACKWARD);
+//      motorLeft->setSpeed(BASE_SPEED + Outputx); //this need to be higher
+//      motorLeft->run(BACKWARD);
+//    } else if (Outputx >= 125) { //propeller push in opposite direction, moving to the right
+//      motorRight->setSpeed(Outputx); 
+//      motorRight->run(FORWARD);
+//      motorLeft->setSpeed(255); //this need to be higher
+//      motorLeft->run(BACKWARD);
+//    } else {
+//      motorRight->setSpeed(255); 
+//      motorRight->run(BACKWARD);
+//      motorLeft->setSpeed(Outputx); //this need to be higher
+//      motorLeft->run(FORWARD);
+//    }
+
+//    motorVertical->setSpeed(0);
+//    motorVertical->run(FORWARD);
+//    // turn on motor
+//    motorVertical->run(RELEASE);
+//    motorLeft->setSpeed(0);
+//    motorLeft->run(FORWARD);
+//    motorRight->setSpeed(0);
+//    motorRight->run(BACKWARD);
+//      motorRight->run(BACKWARD);
diff --git a/Code/Control/Laptop_Code/Previous_low_level/ESP32_slave/utilities.h b/Code/Control/Laptop_Code/Previous_low_level/ESP32_slave/utilities.h
new file mode 100644
index 0000000000000000000000000000000000000000..a1ad9adbad7124479fd8d5168a7b1b24a915521c
--- /dev/null
+++ b/Code/Control/Laptop_Code/Previous_low_level/ESP32_slave/utilities.h
@@ -0,0 +1,8 @@
+#ifndef UTI_H
+#define UTI_H
+
+void lab2rgb( float l_s, float a_s, float b_s, float& R, float& G, float& B );
+void translateCodetoThreshold(int code);
+
+
+#endif
diff --git a/Code/Control/Laptop_Code/README.md b/Code/Control/Laptop_Code/README.md
index 538cd96562a819330f68bb4744d71b6897837b42..a19c8a625086acc4cbcf3c094426f04b6ba1f620 100644
--- a/Code/Control/Laptop_Code/README.md
+++ b/Code/Control/Laptop_Code/README.md
@@ -1,7 +1,10 @@
-Working on it
+[Progress] The overall logic is clear and tested! 
 
-![IO_digram](./README-asset/IO_digram.png)
+What to do next in python main:
 
-Main_control() 
-
-* to be continued
\ No newline at end of file
+- Have keyboard interruption in the python function
+  -  To tweak PID value while running the program
+  - To stop the balloon from being crazy 
+- The meter version April tag detection is still problematic so we need to tune that 
+- Use field test experiment to test PID
+- 
\ No newline at end of file
diff --git a/Code/Control/Laptop_Code/Test_keyboard/keyboard.py b/Code/Control/Laptop_Code/Test_keyboard/keyboard.py
new file mode 100644
index 0000000000000000000000000000000000000000..3e3f90dd9f57c9d900feea778072bfba92c54392
--- /dev/null
+++ b/Code/Control/Laptop_Code/Test_keyboard/keyboard.py
@@ -0,0 +1,162 @@
+import cv2
+import pygame
+
+kpx,kix,kdx = 1,0.2,0.5
+
+
+def auto_control():
+    print("auto_control function")
+
+def stop_all():
+    print("stop_all function")
+
+def manual_command(val1,val2,val3,val4,sign1,sign2,sign3,sign4):
+    pwm1 = val1
+    pwm2 = val2
+    pwm3 = val3
+    pwm4 = val4
+    dir1 = sign1
+    dir2 = sign2
+    dir3 = sign3
+    dir4 = sign4
+    return pwm1,pwm2,pwm3,pwm4,dir1,dir2,dir3,dir4
+
+def manual_control(Ctl_com):
+
+    if get_key("w"):
+        val = start_speed
+        Ctl_com = manual_command(val,val, 0, 0, "+","+","+","+")
+
+    elif get_key("s"):
+        val = start_speed
+        Ctl_com = manual_command(val, val, 0, 0, "-", "-", "+", "+")
+
+    if get_key("UP"):
+        val = start_speed
+
+        Ctl_com = manual_command(0,0, val, val, "+","+","+","+")
+    elif get_key("DOWN"):
+        val = start_speed
+        Ctl_com = manual_command(0,0, val, val, "+","+","-","-")
+
+    elif get_key("LEFT"):
+        val = start_speed
+        Ctl_com = manual_command(0,0, val, val, "+","+","-","+")
+
+    elif get_key("RIGHT"):
+        val = start_speed
+        Ctl_com = manual_command(0,0, val, val, "+","+","+","-")
+
+    return Ctl_com
+    # print("manual_control function")
+
+def decode_ctl(Ctl_com):
+    pwm1 = Ctl_com[0]
+    pwm2 = Ctl_com[1]
+    pwm3 = Ctl_com[2]
+    pwm4 = Ctl_com[3]
+    dir1 = Ctl_com[4]
+    dir2 = Ctl_com[5]
+    dir3 = Ctl_com[6]
+    dir4 = Ctl_com[7]
+    return pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4
+
+def dynamic_variable(str_name_v):
+
+    global kpx,kix,kdx,start_speed
+    if str_name_v == "kpx":
+        kpx = input("Enter your value: ")
+        print("kpx:{}".format(kpx))
+    elif str_name_v == "kix":
+        kix = input("Enter your value: ")
+        print("kix:{}".format(kix))
+    elif str_name_v == "kdx":
+        kdx = input("Enter your value: ")
+        print("kdx:{}".format(kdx))
+    elif str_name_v == "stsp":
+        start_speed = input("Enter your value: ")
+        print("start_speed:{}".format(start_speed))
+
+def variables_change_once():
+
+    str_name = input("Enter your variable: ")
+    dynamic_variable(str_name)
+
+    # print("variables_change function")
+
+def init():
+    pygame.init()
+    win= pygame.display.set_mode((400,400))
+
+def keyboard_stop(flag_s,print_count_s):
+
+    if get_key('q'):
+        flag_s = 0
+        print_count_s = 1
+    return flag_s,print_count_s
+
+def get_key(keyname):
+    ans = False
+    for eve in pygame.event.get(): pass
+    keyInput = pygame.key.get_pressed()
+    myKey = getattr(pygame,'K_{}'.format(keyname))
+
+    if keyInput[myKey]:
+        ans = True
+    pygame.display.update()
+    return ans
+
+if __name__ == '__main__':
+    global start_speed
+    start_speed = 70
+    Ctl_com = [0, 0, 0, 0, "+", "+", "+", "+"]
+    flag = 0
+    print_count = 1
+    init()
+    while True:
+
+        if get_key('a'):
+            flag = 1
+            while (flag == 1):
+                auto_control()
+
+                cap = cv2.VideoCapture(0)
+                ret, frame = cap.read()
+                if not ret:
+                    continue
+                cv2.imshow("image", frame)
+
+                flag, print_count = keyboard_stop(flag,print_count)
+                if flag == 0:
+                    cap.release()
+                    cv2.destroyAllWindows()
+
+        elif get_key('s'):
+            stop_all()
+            print("stop all motors")
+
+        elif get_key('m'):
+            flag = 2
+            while (flag == 2):
+                Ctl_command = manual_control(Ctl_com)
+                pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = decode_ctl(Ctl_command)
+                print("Ctl_com:{},{},{},{},{},{},{},{}".format(pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4))
+                flag, print_count = keyboard_stop(flag,print_count)
+
+        elif get_key('v'):
+            flag = 3
+            while (flag == 3):
+                variables_change_once()
+                flag = 0
+                print_count = 1
+                # flag, print_count = keyboard_stop(flag,print_count)
+                
+        elif get_key('k'): # kill the program
+            break
+
+        if print_count is not 0:
+            print("No subsystem is running")
+            print("kpx:{}".format(kpx))
+            print("kix:{}".format(kix))
+            print("kdx:{}".format(kdx))
+            print_count = 0
\ No newline at end of file
diff --git a/Code/Control/Laptop_Code/inputs.py b/Code/Control/Laptop_Code/inputs.py
deleted file mode 100644
index 6d4cf404632b89e9702c7b090aa8a9279c42ecbe..0000000000000000000000000000000000000000
--- a/Code/Control/Laptop_Code/inputs.py
+++ /dev/null
@@ -1,492 +0,0 @@
-def formatInput(inp):
-  tx, ty, tz, rx, ry, rz, d_lidar, debug = inp
-  t = [tx, ty, tz]
-  r = [rx, ry, rz]
-  return [t, r, d_lidar, debug]  
-  
-#include <esp_now.h>
-#include <WiFi.h>
-#include <SparkFun_VL53L1X.h>
-#include <Wire.h>
-#include <Adafruit_MotorShield.h>
-#include "LedPanel.h"
-#include <Arduino.h>
-#include <string>
-#include <vector>
-#include "Camera.h"
-#include <PID_v1.h>
-#include "utilities.h"
-
-# LIDAR
-SFEVL53L1X distanceSensor;
-budgetIndex = 4;
-budgetValue[7] = {15, 20, 33, 50, 100, 200, 500};
-LED = LED_BUILTIN;
-
-double Inputx, Outputx;
-double Inputy, Outputy;
-
-  
-broadcastAddress = [0x40, 0xF5, 0x20, 0x44, 0xB6, 0x4C] #4
-success = ""
-
-sentDebugM = ""
-count = 0
-count_var = 0
-print_count = 0
-change_count = 0
-
-strData = "";
-valData = 0.0;
-queData = "";
-Kpx = 2.0, Kix = 0.1, Kdx = 0.25;
-Kpy = 1.0, Kiy = 0.1, Kdy = 0.25;
-g1 = 0, g2 = 1, g3 = 2;
-goal_id = [g1, g2, g3]
-goal = [0,1,2]
-gbc = 0
-
-
-//Identify all the variables that will be used by the robot
-int findcolor = 1; //based on the same code from openMV. Determine the color you want to find
-char newPTCL = '1';
-int pau = 0;
-int displayTracking = 0;
-
-// =============================== All the setup ===========================================
-//Create the interface that will be used by the camera
-openmv::rpc_scratch_buffer<256> scratch_buffer; // All RPC objects share this buffer.
-openmv::rpc_i2c_master interface(0x12, 100000); //to make this more robust, consider making address and rate as constructor argument
-Camera cam(&interface);
-LedPanel panel(NUMPIXELS,PIN_PIXELS);
-// ========================== Motor part ====================================
-// Create the motor shield object with the default I2C address
-Adafruit_MotorShield AFMS = Adafruit_MotorShield();
-// changed
-Adafruit_DCMotor *motorVertical_L = AFMS.getMotor(1); 
-Adafruit_DCMotor *motorVertical_R = AFMS.getMotor(2);
-Adafruit_DCMotor *motorLeft = AFMS.getMotor(3);
-Adafruit_DCMotor *motorRight = AFMS.getMotor(4);
-// changed
-// ========================== PID part ====================================
-// Setup PID
-PID PID_x(&Inputx, &Outputx, &Setpointx, Kpx, Kix, Kdx, DIRECT);
-PID PID_y(&Inputy, &Outputy, &Setpointy, Kpy, Kiy, Kdy, DIRECT);
-
-//-------------------------------------------------------------------------------------
-typedef struct struct_message {
-  String StrD;
-  double ValD;
-  String DebugM;
-  String QueM;
-  String VarM;
-} struct_message;
-
-struct_message receivedData;
-//-------------------------------------------------------------------------------------
-// Callback when data is sent
-void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
-  print("\r\nLast Packet Send Status:\t");
-  print(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
-  
-  if (status ==0){
-    success = "Delivery Success :)";
-  }
-  else{
-    success = "Delivery Fail :(";
-  }
-}
-
-# Callback when data is received
-def OnDataRecv(*mac, *incomingData, dataLen):
-  memcpy(&receivedData, incomingData, sizeof(receivedData));
-  print("\ndata:");
-  print(receivedData.StrD);
-  print(receivedData.ValD);
-  print(receivedData.QueM);
-  
-  if (receivedData.QueM != "?"){
-    valData = receivedData.ValD;
-  }
-  
-  strData = receivedData.StrD;
-  queData = receivedData.QueM;
-  
-  count = 0;
-  count_var = 0;
-  print_count=0;
-  change_count = 0;
-  
-  print("queData:");
-  print(queData);
-
-def ball_detect(x, y):
-  if x == 0 and y == 0:
-    return False
-  else:
-    return True
-
-void send_message_var_once(){
-  if(count_var==0){
-    send_message(); 
-    count_var+=1;
-  }
-}
-
-
-void send_message_once(){
-  if(count==0){
-    send_message(); 
-    count+=1;
-    receivedData.DebugM = "";
-  }
-}
-
-def sendMessage(message):
-  esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &receivedData, sizeof(receivedData))
-  // esp_now_send(RxMACaddress, (uint8_t *) &sentData, sizeof(sentData));
-  if result == ESP_OK:
-    print("Sent with success")
-  else:
-    print("Error sending the data")
-  delay(100);
-
-def ChangeVariables():
-  # PID
-  Kpx = getDoubleVal(strData,"kpx",valData,Kpx);
-  Kix = getDoubleVal(strData,"kix",valData,Kix);
-  Kdx = getDoubleVal(strData,"kdx",valData,Kdx);
-  Kpy = getDoubleVal(strData,"kpy",valData,Kpy);
-  Kiy = getDoubleVal(strData,"kiy",valData,Kiy);
-  Kdy = getDoubleVal(strData,"kdy",valData,Kdy);
-  
-  # Goal ID
-  g1 = getIntVal(strData,"gda",valData,goal_id[0]);
-  g2 = getIntVal(strData,"gdb",valData,goal_id[1]);
-  g3 = getIntVal(strData,"gdc",valData,goal_id[2]);
-  goal_id[0] = g1;
-  goal_id[1] = g2;
-  goal_id[2] = g3;
-  
-  # Color Threshold
-  Lmin = getIntVal(strData,"tha",valData,threshold[0]);
-  Lmax = getIntVal(strData,"thb",valData,threshold[1]);
-  Amin = getIntVal(strData,"thc",valData,threshold[2]);
-  Amax = getIntVal(strData,"thd",valData,threshold[3]);
-  Bmin = getIntVal(strData,"the",valData,threshold[4]);
-  Bmax = getIntVal(strData,"thf",valData,threshold[5]);
-  threshold[0] = Lmin;
-  threshold[1] = Lmax;
-  threshold[2] = Amin;
-  threshold[3] = Amax;
-  threshold[4] = Bmin;
-  threshold[5] = Bmax;
-  
-  # base_speed, seeking_speed, LIDAR_Thres
-  base_speed = abs(getDoubleVal(strData,"bsp",valData,base_speed));
-  seeking_speed = abs(getDoubleVal(strData,"ssp",valData,seeking_speed));
-  LIDAR_Thres = getDoubleVal(strData,"lth",valData,LIDAR_Thres);
-
-  # Green Ball x, y
-  gbc = getDoubleVal(strData,"gbc",valData,gbc);
-  gbx = gbc /1000000;
-  gby = fmod(gbc,1000000)/1000;//(gbc.toInt() % 1000000)/1000;
-  gbd = fmod(gbc,1000); // gbc.toInt() % 1000;
-
-  # Setpoints
-  Setpointx = getDoubleVal(strData,"spx",valData,Setpointx);
-  Setpointy = getDoubleVal(strData,"spy",valData,Setpointy);
-
-  debug_ball_cap = getDoubleVal(strData,"dbc",valData,debug_ball_cap);
-
-def getDoubleVal(checkData, Ans, val, ori_val):
-  if checkData == Ans:
-    strData = ""
-    valData = 0.0
-    return val
-  else:
-    return ori_val
-
-def getIntVal(checkData, Ans, val, ori_val):
-  if checkData == Ans:
-    strData = ""
-    valData = 0.0
-    return int(val)
-  else:
-    return ori_val
-
-def print_allvariables():
-  if print_count <= 1:
-    print("---------------")
-    print("base speed:")
-    print(base_speed)
-    print("|")
-    print("seeking speed:")
-    print(seeking_speed);
-    print("|");
-    print("lidar thres:");
-    print(LIDAR_Thres);
-    
-    print("threshold:");
-    print(threshold[0]);
-    print("|");
-    print(threshold[1]);
-    print("|");
-    print(threshold[2]);
-    print("|");
-    print(threshold[3]);
-    print("|");
-    print(threshold[4]); 
-    print("|");   
-    print(threshold[5]);  
-    
-    print("gid:");
-    print(goal_id[0]);
-    print(goal_id[1]);
-    print(goal_id[2]);
-    
-    print("Kdx:");
-    print(Kdx);
-    print("|"); 
-    print("Kix:");
-    print(Kix);
-    print("|");
-    print("Kpx:");
-    print(Kpx);
-    print("|");
-    print("Kdy:");
-    print(Kdy);
-    print("|");
-    print("Kiy:");
-    print(Kiy);
-    print("|");
-    print("Kpy:");
-    print(Kpy);
-    print("|");
-
-    print("gbc:");
-    print(gbc);
-    print("|");
-    print("gbx:");
-    print(gbx);
-    print("|");
-    print("gby:");
-    print(gby);
-    print("gbd:");
-    print(gbd);
-    
-    print("---------------------------\n");
-    print_count +=1 ;
-  }
-}
-
-void seeking(){
-    moveVertical(0);
-    moveHorizontal(seeking_speed, 0);
-}
-
-# vel value should be between -255 to 255 with positive values moving the blimp upward.
-def moveVertical(vel):
-  if vel > 0:  # up
-    panel.singleLED(DEBUG_VERTICALSPEED, abs(vel), 0, 0)
-    motorVertical_L->setSpeed(abs((int) vel))
-    motorVertical_R->setSpeed(abs((int) vel)) 
-    motorVertical_L->run(BACKWARD)
-    motorVertical_R->run(FORWARD)
-  elif vel < 0:  # down
-    panel.singleLED(DEBUG_VERTICALSPEED, 0, 0, abs(vel))
-    motorVertical_L->setSpeed(abs((int) vel))
-    motorVertical_R->setSpeed(abs((int) vel))
-    motorVertical_L->run(FORWARD)
-    motorVertical_R->run(BACKWARD)
-  else:
-      panel.singleLED(DEBUG_VERTICALSPEED, 0, 0, 0)
-      motorVertical_L->setSpeed(0)
-      motorVertical_R->setSpeed(0)
-
-def moveHorizontal(vel_rot, vel_trn):
-  lspeed = -1*vel_rot + vel_trn
-  rspeed =  1*vel_rot + vel_trn
-
-  if lspeed > 0:
-    motorLeft->run(BACKWARD)   # make it move forward 
-  else:
-    motorLeft->run(FORWARD)
-  if rspeed > 0:
-    motorRight-> run(FORWARD)
-  else:
-    motorRight-> run(BACKWARD)  # make it move backward
-  displaySpeed(lspeed, rspeed)
-  motorLeft->setSpeed(min(MAX_SPEED, abs(lspeed )))
-  motorRight->setSpeed(min(MAX_SPEED, abs(rspeed)))
-
-def displaySpeed(lspeed, rspeed):
-  if lspeed < 0:
-    panel.singleLED(DEBUG_LSPEED, 0, 0, abs(lspeed))
-  else:
-    panel.singleLED(DEBUG_LSPEED, abs(lspeed), 0, 0)
-  
-  if rspeed < 0:
-    panel.singleLED(DEBUG_RSPEED, 0, 0, abs(rspeed))
-  else:
-    panel.singleLED(DEBUG_RSPEED, abs(rspeed), 0, 0)
-
-//When using the camera to detect objects such as colored blobs or april tags. This function is
-//useful when only a single object is the target. The approximate position will be marked with an
-//led turning white in the 8*4 panel of the NeoPixel LED Panel. Therefore, this function can be 
-//called assuming that you have created the LED panel object, which in this code is named "panel".
-//If the LED panel is called something else, just edit the code here
-void displayTrackedObject(int cx, int cy, int w_res, int h_res){
-  int lednum = 0;
-  int vertshift = 0;
-  panel.resetPanel();
-  lednum = cx/(w_res/8); //because lednum is an int, it will handle flooring the value
-  vertshift = cy/(h_res/4);
-  lednum = lednum + 8*vertshift;
-  panel.singleLED(lednum, 10, 10 , 10);
-}
-
-//This function translate a string of message into the constants for a PID controller. Ignoring the 
-//first command character, user can input any one, two, or all three parameter to be changed by identifying
-//the new parameter with the capital letter of that specific parameter, each separated with a space. 
-//Some of the valid msg examples are:
-//  - "P0.02"
-//  - "D1.23"
-//  - "P0.14 D9.5"
-//  - "P0.1 I0.1 D0.1"
-//
-//NOTE:
-//  - the parameter doesn't have to be in order. You can do DI or IP in whichever order as long as it follows a valid double value
-//  - while the function works if you passed a negative double, the PID controller will not and will produce error.
-//  - suggested command character: 'T'[uning]
-def setPIDConstants(msg, &p_constant, &i_constant, &d_constant):
-  new_p = Kpx
-  new_i = Kix
-  new_d = Kdx
-  
-  msgLen = msg.length()
-  startpoint = 0
-  endpoint = 0
-
-  for i in range(0, msgLen):
-    if msg[i] == 'P':
-      startpoint = i + 1
-      for j in range(i + 1, msgLen):
-        if msg[j] == ' ':
-          endpoint = j
-          break
-        else:
-          endpoint = msgLen
-      if endpoint > startpoint  # check to see if it is a valid value
-        new_p = msg.substring(startpoint, endpoint).toDouble()
-
-    if msg[i] == 'I':
-      startpoint = i + 1
-      for j in range(i + 1, msgLen):
-        if msg[j] == ' ':
-          endpoint = j
-          break
-        else:
-          endpoint = msgLen
-      if endpoint > startpoint # check to see if it is a valid value
-        new_i = msg.substring(startpoint, endpoint).toDouble()
-
-    if msg[i] == 'D':
-      startpoint = i + 1
-      for j in range(i + 1, msgLen + 1):
-        if msg[j] == ' ' or msg[j] == '\0':
-          endpoint = j
-          break
-        else:
-          endpoint = msgLen
-      if endpoint > startpoint # check to see if it is a valid value
-        new_d = msg.substring(startpoint, endpoint).toDouble()
-
-  ## Debugging
-  unsigned long t = millis();
-  
-  debugPIDConstants(DEBUG_KP, p_constant, new_p)
-  debugPIDConstants(DEBUG_KI, i_constant, new_i)
-  debugPIDConstants(DEBUG_KD, d_constant, new_d)
-  
-  p_constant = new_p
-  i_constant = new_i
-  d_constant = new_d
-  
-  while(millis() < t+2000):   # debugging LED will light up for 2 seconds
-    pass
-  
-  panel.singleLED(DEBUG_KP, 0, 0, 0)
-  panel.singleLED(DEBUG_KI, 0, 0, 0)
-  panel.singleLED(DEBUG_KD, 0, 0, 0)
-}
-
-def debugPIDConstants(lednum, oldval, newval):
-  if newval > oldval:
-    panel.singleLED(lednum, 0, 10, 0)
-  elif newval < oldval:
-    panel.singleLED(lednum, 10, 0, 0)
-  else:
-    panel.singleLED(lednum, 10, 10, 10)
-
-def loop(GB, T, R, d_LIDAR, Debug):
-  if change_count == 0:
-    if queData == "?":
-      QueryVariables()
-    else:
-      ChangeVariables()
-    change_count += 1
-  
-  panel.singleLED(DEBUG_BASESPEED, base_speed, base_speed, base_speed)
-  
-  ## Standby Mode
-  panel.singleLED(DEBUG_STATE, 10, 0, 0)
-  
-  ## Goal Finder
-  ID = -1;
-  x, y = 0, 0
-  
-  receivedData.DebugM = String(d_LIDAR)
-  
-  goalDetect = 1
-  if R[1] == 0 and R[2] == 0:
-    goalDetect = 0
-  
-  # ballDetect = cam.exe_color_detection_biggestblob(threshold[0], threshold[1], threshold[2], threshold[3], threshold[4], threshold[5], x, y)
-  ballDetect  = ball_detect(GB[0], GB[1])
-  
-  ballCapture = lidar.ball_capture()
-  
-  if ballCapture == 1 or debug_ball_cap == 1:  # Ball captured
-    if goalDetect:  # Goal detected
-      panel.singleLED(DEBUG_STATE, 0, 10, 0);
-      Inputx = T[0]/1.00;
-      Inputy = T[1]/1.00;
-      PID_x.Compute();
-      PID_y.Compute();
-      receivedData.DebugM = "det g mv2g";
-      send_message_once(); 
-      moveVertical(Outputy);
-      moveHorizontal(Outputx, base_speed);
-    else:  # Goal not detected
-      seeking(); 
-      receivedData.DebugM = "seeking2";
-      send_message_once(); 
-  else:  # Ball not captured
-    if ballDetect:  # Ball detected
-      receivedData.DebugM = "catching b";
-      send_message_once(); 
-      Inputx = GB[0]/1.00
-      Inputy = GB[1]/1.00
-      PID_x.Compute()
-      PID_y.Compute()
-      moveVertical(Outputy)
-      moveHorizontal(Outputx, base_speed)
-    else:  # Ball not detected
-      seeking()
-      receivedData.DebugM = "seeking1"
-      send_message_once()
-  
-  print_allvariables()
-  
-  sendMessage(PWM, Dir)
\ No newline at end of file
diff --git a/Code/Control/Laptop_Code/main.py b/Code/Control/Laptop_Code/main.py
deleted file mode 100644
index 8ce272caf98ce987307a4adfa7ff4d324b3b786b..0000000000000000000000000000000000000000
--- a/Code/Control/Laptop_Code/main.py
+++ /dev/null
@@ -1,327 +0,0 @@
-import time
-import serial
-import ball_detection.ball_detection as ball_detection
-import simple_pid.PID as PID
-import timeit
-
-
-from constants import *
-
-# ========= Serial Port I/O ===========
-
-def serial_port_in(serial_port):
-    '''
-    Description:
-        Take all ESP32_Master serial port's printIn and take all necessary input object
-
-    Input:
-        serial_port     :    serial.Serail object
-
-    Output:
-        tx, ty, tz, rx, ry, rz, LIDAR_dist, DebugM
-    '''
-
-    # DEBUG Verbose
-    print("initiating one round of serial in ...")
-
-    for i in range(7):
-        line = serial_port.readline()
-        val = int(line.decode())
-
-        if   i == 0:
-            tx = val
-        elif i == 1:
-            ty = val
-        elif i == 2:
-            tz = val
-        elif i == 3:
-            rx = val
-        elif i == 4:
-            ry = val
-        elif i == 5:
-            rz = val
-        elif i == 6:
-            LIDAR_dist = val
-
-    line = serial_port.readline()
-    debugM = line.decode()
-
-    # DEBUG Verbose
-    print("tx:{}".format(tx))
-    print("ty:{}".format(ty))
-    print("tz:{}".format(tz))
-    print("rx:{}".format(rx))
-    print("ry:{}".format(ry))
-    print("rz:{}".format(rz))
-    print("dist:{}".format(LIDAR_dist))
-    print(debugM)
-
-    return tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM
-
-
-def serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4):
-    '''
-    Description:
-        Feed to ESP32_Master to send ESP32_Slave necessary information
-        the format of sending is pwm are 3 digit space
-
-    Input:
-        serial_port                                     :   serial.Serail object
-        pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4  :   variables to send
-
-    Output:
-        None
-    '''
-
-    output_message = ''
-
-    for pwm_itr in [pwm1, pwm2, pwm3, pwm4]:
-        # print(pwm_itr)
-        if len(str(pwm_itr)) == 2:
-            output_message += '0'
-        elif len(str(pwm_itr)) == 1:
-            output_message += '00'
-        output_message += str(pwm_itr)
-        print(pwm_itr)
-
-    output_message = output_message + dir1 + dir2 +  dir3 +  dir4 + '\n'
-    print("serial out ...")
-    print(output_message)
-    serial_port.write(output_message.encode())
-
-
-# ====== supporting function in main control ====
-def ball_detect(gbx, gby):
-    '''
-    return True if green ball is detected
-    '''
-    if gbx == -1 and gby == -1:
-        return False
-    else:
-        return True
-
-def goal_detect(tx,ty):
-    '''
-    return True if April Tag is detected
-    '''
-    if tx == 0 and ty == 0:
-        return False
-    else:
-        return True
-
-def ball_capture(LIDAR_dist):
-    '''
-    return True if April Tag is detected
-    '''
-    if (LIDAR_dist < LIDAR_Thres) and (LIDAR_dist > 0):  # Ball captured
-        return True
-    else:
-        return False
-
-def stop_all():
-    pwm1, pwm2, pwm3, pwm4 = 0 , 0 , 0 , 0
-    dir1, dir2, dir3, dir4 = '+', '-', '+', '-'
-    return pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4
-
-def move2goal(tx, ty):
-    """
-    Description:
-        Given the center of the AT tx, ty. Call PID control to output the blimp
-        motor to manuver to the goal
-
-    Input:
-        tx    :    x component, center of April Tag
-        ty    :    y component, center of Aprol Tag
-
-    Output:
-        pwm1, pwm2, pwm3, pwm4
-        dir1, dir2, dir3, dir4
-    """
-    pass
-
-    # return pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4
-
-
-def seeking():
-    """
-    Description:
-        By default, when there ball is not determined capture, the manuver of the
-        motors to have it scan its surronding 360 degrees
-
-    Input:
-        none
-
-    Output:
-        pwm1, pwm2, pwm3, pwm4
-        dir1, dir2, dir3, dir4
-    """
-    pwm1, pwm2, pwm3, pwm4 = 0 , 0 , seeking_speed , seeking_speed
-    dir1, dir2, dir3, dir4 = '+', '+', '+', '-'
-
-    return int(pwm1), int(pwm2), int(pwm3), int(pwm4), dir1, dir2, dir3, dir4
-
-
-def move2ball(gbx, gby, gb_dist):
-    """
-    Description:
-        Given the center of x y dist of green ball detected. Call PID control to
-        output the blimp motor to manuver to the green ball
-
-    Input:
-        gbx     :  x component, center of green ball
-        gby     :  y component, center of green ball
-        gb_dist :  distance to green ball
-
-    Output:
-        pwm1, pwm2, pwm3, pwm4
-        dir1, dir2, dir3, dir4
-    """
-    inputx = gbx / 1.00
-    inputy = gby / 1.00
-
-    setpoint_x = 400
-    setpoint_y = 300  # ESP 32 Cam Center
-
-    pid_x = PID(kpx,kix,kdx,setpoint=setpoint_x)
-    pid_y = PID(kpy,kiy,kdy,setpoint=setpoint_y)
-
-
-    pid_x.auto_mode = True
-    pid_x.set_auto_mode(True, last_output=8.0)
-    pid_x.output_limits = (-255,255)
-    pid_y.output_limits = (-255,255)
-
-
-    outputx = pid_x(inputx)
-    outputy = pid_y(inputy)
-
-    # vertical
-    pwm1 = abs(outputy)
-    pwm2 = abs(outputy)
-
-    if(outputy > 0):
-        dir1 = '+'
-        dir2 = '+'
-    else:
-        dir1 = '-'
-        dir2 = '-'
-
-    # horizontal
-    lspeed = -1 * outputx + base_speed
-    rspeed =  1 * outputx + base_speed
-    pwm3 = min( abs(lspeed), 255)
-    pwm4 = min( abs(rspeed), 255)
-    if (lspeed > 0):
-        dir3 = '+'
-    else:
-        dir3 = '-'
-
-    if (rspeed > 0):
-        dir4 = '+'
-    else:
-        dir4 = '-'
-
-
-    return int(pwm1), int(pwm2), int(pwm3), int(pwm4), dir1, dir2, dir3, dir4
-
-
-
-#  =========== main control ===========
-
-def main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM):
-    '''
-    Description:
-        Given green ball information and AT information, the main control logic
-        to manuver the blimp motors
-
-    Input:
-        gbx, gby, gb_dist                   :   green ball information
-        tx, ty, tz, rx, ry, rz, LIDAR_dist  :   AirTag information
-        debugM                              :   Debug Message
-
-    Output:
-        pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4  :   Blimp motor manuver parameters
-    '''
-
-    # # placeholder
-    pwm1, pwm2, pwm3, pwm4 = 0 , 0 , 0 , 0
-    dir1, dir2, dir3, dir4 = '+', '-', '+', '-'
-
-    ballDetect  = ball_detect(gbx, gby)
-    ballCapture = ball_capture(LIDAR_dist)
-    goalDetect  = goal_detect(tx,ty)
-    # debug
-    ballCapture = 0
-    if ballCapture: # Ball captured
-        if goalDetect:  # Goal detected
-            stop_all()
-            #pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = move2goal(tx, ty)
-        else:  # Goal not detected
-            stop_all()
-            #pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = seeking()
-    else:  # Ball not captured
-        if ballDetect:  # Ball detected
-            pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = move2ball(gbx,gby,gb_dist)
-        else:  # Ball not detected
-            # stop_all()
-            pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = seeking()
-
-    return pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4
-
-
-
-# ===== Main Functions =====
-
-if __name__ == '__main__':
-    # =========== SET UP ============
-    # Defining Variables for ESP 32 Serial I/O
-    PORT = "COM6" # for Alienware
-    serial_port = serial.Serial(PORT, 115200)
-    serial_port.close()
-    serial_port.open()
-
-    # Weit Time
-    waitTime = 0.05
-
-    # Loading the PyTorch ML model for ball detection
-    model = ball_detection.returnModel(device, labelSet, modelLoc, modelFile)
-    #model = ball_detection.returnModel(modelAction, device, trainLoc, labelSet, modelLoc, modelFile)
-
-
-    # =========== DECLARE VARIABLES ===========
-    # ESP CAM In
-    gbx, gby  = -1, -1   # by default (-1 means no found green ball)
-    gb_dist = -1         # by default (-1 means no found green ball)
-
-    # Serial Port In
-    tx, ty, tz = 0, 0, 0  # by default (0 means no found AirTag)
-    rx, ry, rz = 0, 0, 0
-    LIDAR_dist = 0
-    debugM = 'Testing'
-
-    # Serial Port Out
-    pwm1, pwm2, pwm3, pwm4 = 0 , 0 , 0 , 0   # Not moving
-    dir1, dir2, dir3, dir4 = '+', '+', '+', '+'
-
-    # =========== LOOP FOREVER===========
-    # ESP32_SLAVE Talk First
-    gbx, gby, gb_dist = ball_detection.detectLive(model, minDetectionScore, showSight = True)
-    pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM)
-    serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4)
-
-    while True:
-        # ===== STEP 1: TAKE ALL INPUT =====
-        gbx, gby, gb_dist = ball_detection.detectLive(model, minDetectionScore, showSight = True)
-        line = serial_port.readline()
-
-        if line == b'SERIAL_IN_START\r\n':
-            tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM = serial_port_in(serial_port)
-            print("gbx,gby:{},{}".format(gbx,gby))
-
-        # ===== STEP 2: MAIN CONTROL LOOP =====
-        pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM)
-
-        # ===== STEP 3: FEED ALL OUTPUT =====
-        serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4)
-
-        time.sleep(waitTime)
diff --git a/Code/Control/Laptop_Code/NEW_main_zhiying_catchBall_test_2in1.py b/Code/Control/Laptop_Code/main_backup/NEW_main_zhiying_catchBall_test_2in1.py
similarity index 95%
rename from Code/Control/Laptop_Code/NEW_main_zhiying_catchBall_test_2in1.py
rename to Code/Control/Laptop_Code/main_backup/NEW_main_zhiying_catchBall_test_2in1.py
index ec638f1ae93576716c31dc69902ae93e097cbf6a..8eda29a48376484ef80c46a181726030e9941acd 100644
--- a/Code/Control/Laptop_Code/NEW_main_zhiying_catchBall_test_2in1.py
+++ b/Code/Control/Laptop_Code/main_backup/NEW_main_zhiying_catchBall_test_2in1.py
@@ -4,7 +4,6 @@ import ball_detection.ball_detection as ball_detection
 import simple_pid.PID as PID
 import timeit
 
-
 from constants import *
 
 # ========= Serial Port I/O ===========
@@ -72,7 +71,6 @@ def serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4)
     Output:
         None
     '''
-
     output_message = ''
 
     for pwm_itr in [pwm1, pwm2, pwm3, pwm4]:
@@ -90,7 +88,7 @@ def serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4)
     serial_port.write(output_message.encode())
 
 
-# ====== supporting function in main control ====
+# ====== Logic-directing Functions ====
 def ball_detect(gbx, gby):
     '''
     return True if green ball is detected
@@ -156,6 +154,7 @@ def seeking():
         dir1, dir2, dir3, dir4
     """
     pwm1, pwm2, pwm3, pwm4 = 0 , 0 , seeking_speed , seeking_speed
+    # pwm1, pwm2, pwm3, pwm4 = 0 , 0 , 70, 70
     dir1, dir2, dir3, dir4 = '+', '+', '+', '-'
 
     return int(pwm1), int(pwm2), int(pwm3), int(pwm4), dir1, dir2, dir3, dir4
@@ -176,22 +175,26 @@ def move2ball(gbx, gby, gb_dist):
         pwm1, pwm2, pwm3, pwm4
         dir1, dir2, dir3, dir4
     """
+    # base_speed = 70
+
+    # kdx,kix,kpx = 2,0.1,0.25
+    # kdy,kiy,kpy = 1,0.1,0.25
+    
     inputx = gbx / 1.00
     inputy = gby / 1.00
 
+    # ESP-Cam Center
     setpoint_x = 400
-    setpoint_y = 300  # ESP 32 Cam Center
-
-    pid_x = PID(kpx,kix,kdx,setpoint=setpoint_x)
-    pid_y = PID(kpy,kiy,kdy,setpoint=setpoint_y)
+    setpoint_y = 300
 
+    pid_x = PID(kpx, kix, kdx, setpoint = setpoint_x)
+    pid_y = PID(kpy, kiy, kdy, setpoint = setpoint_y)
 
     pid_x.auto_mode = True
-    pid_x.set_auto_mode(True, last_output=8.0)
+    pid_x.set_auto_mode(True, last_output = 8.0)
     pid_x.output_limits = (-255,255)
     pid_y.output_limits = (-255,255)
-
-
+    
     outputx = pid_x(inputx)
     outputy = pid_y(inputy)
 
@@ -215,19 +218,15 @@ def move2ball(gbx, gby, gb_dist):
         dir3 = '+'
     else:
         dir3 = '-'
-
     if (rspeed > 0):
         dir4 = '+'
     else:
         dir4 = '-'
 
-
     return int(pwm1), int(pwm2), int(pwm3), int(pwm4), dir1, dir2, dir3, dir4
 
 
-
 #  =========== main control ===========
-
 def main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM):
     '''
     Description:
@@ -242,8 +241,7 @@ def main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM):
     Output:
         pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4  :   Blimp motor manuver parameters
     '''
-
-    # # placeholder
+    # placeholder
     pwm1, pwm2, pwm3, pwm4 = 0 , 0 , 0 , 0
     dir1, dir2, dir3, dir4 = '+', '-', '+', '-'
 
@@ -269,9 +267,7 @@ def main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM):
     return pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4
 
 
-
-# ===== Main Functions =====
-
+# ===== Main Function =====
 if __name__ == '__main__':
     # =========== SET UP ============
     # Defining Variables for ESP 32 Serial I/O
@@ -303,12 +299,12 @@ if __name__ == '__main__':
     pwm1, pwm2, pwm3, pwm4 = 0 , 0 , 0 , 0   # Not moving
     dir1, dir2, dir3, dir4 = '+', '+', '+', '+'
 
-    # =========== LOOP FOREVER===========
     # ESP32_SLAVE Talk First
     gbx, gby, gb_dist = ball_detection.detectLive(model, minDetectionScore, showSight = True)
     pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM)
     serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4)
 
+    # =========== LOOP FOREVER===========
     while True:
         # ===== STEP 1: TAKE ALL INPUT =====
         gbx, gby, gb_dist = ball_detection.detectLive(model, minDetectionScore, showSight = True)
diff --git a/Code/Control/Laptop_Code/main_zhiying_catchBall_test_2in1.py b/Code/Control/Laptop_Code/main_backup/main_zhiying_catchBall_test_2in1.py
similarity index 96%
rename from Code/Control/Laptop_Code/main_zhiying_catchBall_test_2in1.py
rename to Code/Control/Laptop_Code/main_backup/main_zhiying_catchBall_test_2in1.py
index 175bdc22392b37dd7555134827dd3622cdcf5b62..1351ed3f4e4ee28a42c883b69fe7eeaa9381081c 100644
--- a/Code/Control/Laptop_Code/main_zhiying_catchBall_test_2in1.py
+++ b/Code/Control/Laptop_Code/main_backup/main_zhiying_catchBall_test_2in1.py
@@ -1,371 +1,371 @@
-import time
-import serial
-import ball_detection.ball_detection as ball_detection
-import simple_pid.PID as PID
-import timeit
-
-
-from constants import *
-
-# ========= Serial Port I/O ===========
-
-def serial_port_in(serial_port):
-    '''
-    Description:
-        Take all ESP32_Master serial port's printIn and take all necessary input object
-
-    Input:
-        serial_port     :    serial.Serail object
-
-    Output:
-        tx, ty, tz, rx, ry, rz, LIDAR_dist, DebugM
-    '''
-
-    # DEBUG Verbose
-    print("initiating one round of serial in ...")
-
-    for i in range(7):
-        line = serial_port.readline()
-        val = int(line.decode())
-
-        if   i == 0:
-            tx = val
-        elif i == 1:
-            ty = val
-        elif i == 2:
-            tz = val
-        elif i == 3:
-            rx = val
-        elif i == 4:
-            ry = val
-        elif i == 5:
-            rz = val
-        elif i == 6:
-            LIDAR_dist = val
-
-    line = serial_port.readline()
-    debugM = line.decode()
-
-    # DEBUG Verbose
-    print("tx:{}".format(tx))
-    print("ty:{}".format(ty))
-    print("tz:{}".format(tz))
-    print("rx:{}".format(rx))
-    print("ry:{}".format(ry))
-    print("rz:{}".format(rz))
-    print("dist:{}".format(LIDAR_dist))
-    print(debugM)
-
-    return tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM
-
-
-def serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4):
-    '''
-    Description:
-        Feed to ESP32_Master to send ESP32_Slave necessary information
-        the format of sending is pwm are 3 digit space
-
-    Input:
-        serial_port                                     :   serial.Serail object
-        pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4  :   variables to send
-
-    Output:
-        None
-    '''
-
-    output_message = ''
-
-    for pwm_itr in [pwm1, pwm2, pwm3, pwm4]:
-        # print(pwm_itr)
-        if len(str(pwm_itr)) == 2:
-            output_message += '0'
-        elif len(str(pwm_itr)) == 1:
-            output_message += '00'
-        output_message += str(pwm_itr)
-        print(pwm_itr)
-
-    output_message = output_message + dir1 + dir2 +  dir3 +  dir4 + '\n'
-    print("serial out ...")
-    print(output_message)
-    serial_port.write(output_message.encode())
-
-    # DEBUG Verbose
-
-
-
-
-
-# ====== supporting function in main control ====
-def ball_detect(gbx, gby):
-    '''
-    return True if green ball is detected
-    '''
-    if gbx == -1 and gby == -1:
-        return False
-    else:
-        return True
-
-def goal_detect(tx,ty):
-    '''
-    return True if April Tag is detected
-    '''
-    if tx == 0 and ty == 0:
-        return False
-    else:
-        return True
-
-def ball_capture(LIDAR_dist):
-    '''
-    return True if April Tag is detected
-    '''
-    if (LIDAR_dist < LIDAR_Thres) and (LIDAR_dist > 0):  # Ball captured
-        return True
-    else:
-        return False
-
-def stop_all():
-    pwm1, pwm2, pwm3, pwm4 = 0 , 0 , 0 , 0
-    dir1, dir2, dir3, dir4 = '+', '-', '+', '-'
-    return pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4
-
-def move2goal(tx, ty):
-    """
-    Description:
-        Given the center of the AT tx, ty. Call PID control to output the blimp
-        motor to manuver to the goal
-
-    Input:
-        tx    :    x component, center of April Tag
-        ty    :    y component, center of Aprol Tag
-
-    Output:
-        pwm1, pwm2, pwm3, pwm4
-        dir1, dir2, dir3, dir4
-    """
-    pass
-
-    # return pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4
-
-
-def seeking():
-    """
-    Description:
-        By default, when there ball is not determined capture, the manuver of the
-        motors to have it scan its surronding 360 degrees
-
-    Input:
-        none
-
-    Output:
-        pwm1, pwm2, pwm3, pwm4
-        dir1, dir2, dir3, dir4
-    """
-    pwm1, pwm2, pwm3, pwm4 = 0 , 0 , seeking_speed , seeking_speed
-    dir1, dir2, dir3, dir4 = '+', '+', '+', '-'
-
-    return int(pwm1), int(pwm2), int(pwm3), int(pwm4), dir1, dir2, dir3, dir4
-
-
-def move2ball(gbx, gby, gb_dist):
-    """
-    Description:
-        Given the center of x y dist of green ball detected. Call PID control to
-        output the blimp motor to manuver to the green ball
-
-    Input:
-        gbx     :  x component, center of green ball
-        gby     :  y component, center of green ball
-        gb_dist :  distance to green ball
-
-    Output:
-        pwm1, pwm2, pwm3, pwm4
-        dir1, dir2, dir3, dir4
-    """
-    inputx = gbx / 1.00
-    inputy = gby / 1.00
-
-    setpoint_x = 400
-    setpoint_y = 300  # ESP 32 Cam Center
-
-    pid_x = PID(kpx,kix,kdx,setpoint=setpoint_x)
-    pid_y = PID(kpy,kiy,kdy,setpoint=setpoint_y)
-
-
-    pid_x.auto_mode = True
-    pid_x.set_auto_mode(True, last_output=8.0)
-    pid_x.output_limits = (-255,255)
-    pid_y.output_limits = (-255,255)
-
-
-    outputx = pid_x(inputx)
-    outputy = pid_y(inputy)
-
-    # vertical
-    pwm1 = abs(outputy)
-    pwm2 = abs(outputy)
-
-    if(outputy > 0):
-        dir1 = '+'
-        dir2 = '+'
-    else:
-        dir1 = '-'
-        dir2 = '-'
-
-    # horizontal
-    lspeed = -1 * outputx + base_speed
-    rspeed =  1 * outputx + base_speed
-    pwm3 = min( abs(lspeed), 255)
-    pwm4 = min( abs(rspeed), 255)
-    if (lspeed > 0):
-        dir3 = '+'
-    else:
-        dir3 = '-'
-
-    if (rspeed > 0):
-        dir4 = '+'
-    else:
-        dir4 = '-'
-
-
-    return int(pwm1), int(pwm2), int(pwm3), int(pwm4), dir1, dir2, dir3, dir4
-
-
-
-#  =========== main control ===========
-
-def main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM):
-    '''
-    Description:
-        Given green ball information and AT information, the main control logic
-        to manuver the blimp motors
-
-    Input:
-        gbx, gby, gb_dist                   :   green ball information
-        tx, ty, tz, rx, ry, rz, LIDAR_dist  :   AirTag information
-        debugM                              :   Debug Message
-
-    Output:
-        pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4  :   Blimp motor manuver parameters
-    '''
-
-    # placeholder
-    pwm1, pwm2, pwm3, pwm4 = 0 , 0 , 0 , 0
-    dir1, dir2, dir3, dir4 = '+', '-', '+', '-'
-
-    ballDetect  = ball_detect(gbx, gby)
-    ballCapture = ball_capture(LIDAR_dist)
-    goalDetect  = goal_detect(tx,ty)
-    # debug
-    ballCapture = 0
-    if ballCapture: # Ball captured
-        if goalDetect:  # Goal detected
-            stop_all()
-            #pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = move2goal(tx, ty)
-        else:  # Goal not detected
-            stop_all()
-            #pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = seeking()
-    else:  # Ball not captured
-        if ballDetect:  # Ball detected
-            pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = move2ball(gbx,gby,gb_dist)
-        else:  # Ball not detected
-            pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = seeking()
-
-    return pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4
-
-
-
-# ===== Main Functions =====
-
-if __name__ == '__main__':
-    # =========== SET UP ============
-    # Defining Variables for ESP 32 Serial I/O
-    PORT = "COM6" # for Alienware
-    serial_port = serial.Serial(PORT, 115200)
-    serial_port.close()
-    serial_port.open()
-
-    # Weit Time
-    waitTime = 0.1
-
-    # Loading the PyTorch ML model for ball detection
-    model = ball_detection.returnModel(device, labelSet, modelLoc, modelFile)
-    #model = ball_detection.returnModel(modelAction, device, trainLoc, labelSet, modelLoc, modelFile)
-
-
-    # =========== DECLARE VARIABLES ===========
-    # ESP CAM In
-    gbx, gby  = -1, -1   # by default (-1 means no found green ball)
-    gb_dist = -1         # by default (-1 means no found green ball)
-
-    # Serial Port In
-    tx, ty, tz = 0, 0, 0  # by default (0 means no found AirTag)
-    rx, ry, rz = 0, 0, 0
-    LIDAR_dist = 0
-    debugM = 'Testing'
-
-    # Serial Port Out
-    pwm1, pwm2, pwm3, pwm4 = 0 , 0 , 0 , 0   # Not moving
-    dir1, dir2, dir3, dir4 = '+', '+', '+', '+'
-
-    count = 0
-    flg = 0
-    # =========== LOOP FOREVER===========
-    while True:
-
-        gbx, gby, gb_dist = ball_detection.detectLive(model, minDetectionScore, showSight = True)
-        # print("gbx,gby:{},{}".format(gbx,gby))
-        # tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM = serial_port_in(serial_port)
-
-        # ===== STEP 2: MAIN CONTROL LOOP =====
-        pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM)
-
-        # ===== STEP 3: FEED ALL OUTPUT =====
-        serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4)
-
-        time.sleep(0.1)
-
-        """
-        line = serial_port.readline()
-        if line == b'SERIAL_IN_START\r\n':
-            # start = time.time()
-            # print('I have been there')
-            # ===== STEP 1: TAKE ALL INPUT =====
-            gbx, gby, gb_dist = ball_detection.detectLive(model, minDetectionScore, showSight = True)
-            # print("gbx,gby:{},{}".format(gbx,gby))
-            tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM = serial_port_in(serial_port)
-
-            # ===== STEP 2: MAIN CONTROL LOOP =====
-            pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM)
-
-            # ===== STEP 3: FEED ALL OUTPUT =====
-            serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4)
-
-
-            # end = time.time()
-            # print("time:")
-            # print(end - start)
-        if count == 0:
-            # first time calling (call once)
-            print("bbb")
-            pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM)
-            serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4)
-            count +=1
-        """
-
-        """
-        if flg == 1:
-            print("1")
-            output_message = '100100000000+-++' + '\n'
-            serial_port.write(output_message.encode())
-
-            flg = 0
-            time.sleep(0.3)
-        elif flg == 0:
-            print("2")
-            output_message = '000000000000+-++' + '\n'
-            serial_port.write(output_message.encode())
-            flg = 1
-            time.sleep(0.3)
-        """
-
-        # time.sleep(waitTime)
+import time
+import serial
+import ball_detection.ball_detection as ball_detection
+import simple_pid.PID as PID
+import timeit
+
+
+from constants import *
+
+# ========= Serial Port I/O ===========
+
+def serial_port_in(serial_port):
+    '''
+    Description:
+        Take all ESP32_Master serial port's printIn and take all necessary input object
+
+    Input:
+        serial_port     :    serial.Serail object
+
+    Output:
+        tx, ty, tz, rx, ry, rz, LIDAR_dist, DebugM
+    '''
+
+    # DEBUG Verbose
+    print("initiating one round of serial in ...")
+
+    for i in range(7):
+        line = serial_port.readline()
+        val = int(line.decode())
+
+        if   i == 0:
+            tx = val
+        elif i == 1:
+            ty = val
+        elif i == 2:
+            tz = val
+        elif i == 3:
+            rx = val
+        elif i == 4:
+            ry = val
+        elif i == 5:
+            rz = val
+        elif i == 6:
+            LIDAR_dist = val
+
+    line = serial_port.readline()
+    debugM = line.decode()
+
+    # DEBUG Verbose
+    print("tx:{}".format(tx))
+    print("ty:{}".format(ty))
+    print("tz:{}".format(tz))
+    print("rx:{}".format(rx))
+    print("ry:{}".format(ry))
+    print("rz:{}".format(rz))
+    print("dist:{}".format(LIDAR_dist))
+    print(debugM)
+
+    return tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM
+
+
+def serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4):
+    '''
+    Description:
+        Feed to ESP32_Master to send ESP32_Slave necessary information
+        the format of sending is pwm are 3 digit space
+
+    Input:
+        serial_port                                     :   serial.Serail object
+        pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4  :   variables to send
+
+    Output:
+        None
+    '''
+
+    output_message = ''
+
+    for pwm_itr in [pwm1, pwm2, pwm3, pwm4]:
+        # print(pwm_itr)
+        if len(str(pwm_itr)) == 2:
+            output_message += '0'
+        elif len(str(pwm_itr)) == 1:
+            output_message += '00'
+        output_message += str(pwm_itr)
+        print(pwm_itr)
+
+    output_message = output_message + dir1 + dir2 +  dir3 +  dir4 + '\n'
+    print("serial out ...")
+    print(output_message)
+    serial_port.write(output_message.encode())
+
+    # DEBUG Verbose
+
+
+
+
+
+# ====== supporting function in main control ====
+def ball_detect(gbx, gby):
+    '''
+    return True if green ball is detected
+    '''
+    if gbx == -1 and gby == -1:
+        return False
+    else:
+        return True
+
+def goal_detect(tx,ty):
+    '''
+    return True if April Tag is detected
+    '''
+    if tx == 0 and ty == 0:
+        return False
+    else:
+        return True
+
+def ball_capture(LIDAR_dist):
+    '''
+    return True if April Tag is detected
+    '''
+    if (LIDAR_dist < LIDAR_Thres) and (LIDAR_dist > 0):  # Ball captured
+        return True
+    else:
+        return False
+
+def stop_all():
+    pwm1, pwm2, pwm3, pwm4 = 0 , 0 , 0 , 0
+    dir1, dir2, dir3, dir4 = '+', '-', '+', '-'
+    return pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4
+
+def move2goal(tx, ty):
+    """
+    Description:
+        Given the center of the AT tx, ty. Call PID control to output the blimp
+        motor to manuver to the goal
+
+    Input:
+        tx    :    x component, center of April Tag
+        ty    :    y component, center of Aprol Tag
+
+    Output:
+        pwm1, pwm2, pwm3, pwm4
+        dir1, dir2, dir3, dir4
+    """
+    pass
+
+    # return pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4
+
+
+def seeking():
+    """
+    Description:
+        By default, when there ball is not determined capture, the manuver of the
+        motors to have it scan its surronding 360 degrees
+
+    Input:
+        none
+
+    Output:
+        pwm1, pwm2, pwm3, pwm4
+        dir1, dir2, dir3, dir4
+    """
+    pwm1, pwm2, pwm3, pwm4 = 0 , 0 , seeking_speed , seeking_speed
+    dir1, dir2, dir3, dir4 = '+', '+', '+', '-'
+
+    return int(pwm1), int(pwm2), int(pwm3), int(pwm4), dir1, dir2, dir3, dir4
+
+
+def move2ball(gbx, gby, gb_dist):
+    """
+    Description:
+        Given the center of x y dist of green ball detected. Call PID control to
+        output the blimp motor to manuver to the green ball
+
+    Input:
+        gbx     :  x component, center of green ball
+        gby     :  y component, center of green ball
+        gb_dist :  distance to green ball
+
+    Output:
+        pwm1, pwm2, pwm3, pwm4
+        dir1, dir2, dir3, dir4
+    """
+    inputx = gbx / 1.00
+    inputy = gby / 1.00
+
+    setpoint_x = 400
+    setpoint_y = 300  # ESP 32 Cam Center
+
+    pid_x = PID(kpx,kix,kdx,setpoint=setpoint_x)
+    pid_y = PID(kpy,kiy,kdy,setpoint=setpoint_y)
+
+
+    pid_x.auto_mode = True
+    pid_x.set_auto_mode(True, last_output=8.0)
+    pid_x.output_limits = (-255,255)
+    pid_y.output_limits = (-255,255)
+
+
+    outputx = pid_x(inputx)
+    outputy = pid_y(inputy)
+
+    # vertical
+    pwm1 = abs(outputy)
+    pwm2 = abs(outputy)
+
+    if(outputy > 0):
+        dir1 = '+'
+        dir2 = '+'
+    else:
+        dir1 = '-'
+        dir2 = '-'
+
+    # horizontal
+    lspeed = -1 * outputx + base_speed
+    rspeed =  1 * outputx + base_speed
+    pwm3 = min( abs(lspeed), 255)
+    pwm4 = min( abs(rspeed), 255)
+    if (lspeed > 0):
+        dir3 = '+'
+    else:
+        dir3 = '-'
+
+    if (rspeed > 0):
+        dir4 = '+'
+    else:
+        dir4 = '-'
+
+
+    return int(pwm1), int(pwm2), int(pwm3), int(pwm4), dir1, dir2, dir3, dir4
+
+
+
+#  =========== main control ===========
+
+def main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM):
+    '''
+    Description:
+        Given green ball information and AT information, the main control logic
+        to manuver the blimp motors
+
+    Input:
+        gbx, gby, gb_dist                   :   green ball information
+        tx, ty, tz, rx, ry, rz, LIDAR_dist  :   AirTag information
+        debugM                              :   Debug Message
+
+    Output:
+        pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4  :   Blimp motor manuver parameters
+    '''
+
+    # placeholder
+    pwm1, pwm2, pwm3, pwm4 = 0 , 0 , 0 , 0
+    dir1, dir2, dir3, dir4 = '+', '-', '+', '-'
+
+    ballDetect  = ball_detect(gbx, gby)
+    ballCapture = ball_capture(LIDAR_dist)
+    goalDetect  = goal_detect(tx,ty)
+    # debug
+    ballCapture = 0
+    if ballCapture: # Ball captured
+        if goalDetect:  # Goal detected
+            stop_all()
+            #pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = move2goal(tx, ty)
+        else:  # Goal not detected
+            stop_all()
+            #pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = seeking()
+    else:  # Ball not captured
+        if ballDetect:  # Ball detected
+            pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = move2ball(gbx,gby,gb_dist)
+        else:  # Ball not detected
+            pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = seeking()
+
+    return pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4
+
+
+
+# ===== Main Functions =====
+
+if __name__ == '__main__':
+    # =========== SET UP ============
+    # Defining Variables for ESP 32 Serial I/O
+    PORT = "COM6" # for Alienware
+    serial_port = serial.Serial(PORT, 115200)
+    serial_port.close()
+    serial_port.open()
+
+    # Weit Time
+    waitTime = 0.1
+
+    # Loading the PyTorch ML model for ball detection
+    model = ball_detection.returnModel(device, labelSet, modelLoc, modelFile)
+    #model = ball_detection.returnModel(modelAction, device, trainLoc, labelSet, modelLoc, modelFile)
+
+
+    # =========== DECLARE VARIABLES ===========
+    # ESP CAM In
+    gbx, gby  = -1, -1   # by default (-1 means no found green ball)
+    gb_dist = -1         # by default (-1 means no found green ball)
+
+    # Serial Port In
+    tx, ty, tz = 0, 0, 0  # by default (0 means no found AirTag)
+    rx, ry, rz = 0, 0, 0
+    LIDAR_dist = 0
+    debugM = 'Testing'
+
+    # Serial Port Out
+    pwm1, pwm2, pwm3, pwm4 = 0 , 0 , 0 , 0   # Not moving
+    dir1, dir2, dir3, dir4 = '+', '+', '+', '+'
+
+    count = 0
+    flg = 0
+    # =========== LOOP FOREVER===========
+    while True:
+
+        gbx, gby, gb_dist = ball_detection.detectLive(model, minDetectionScore, showSight = True)
+        # print("gbx,gby:{},{}".format(gbx,gby))
+        # tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM = serial_port_in(serial_port)
+
+        # ===== STEP 2: MAIN CONTROL LOOP =====
+        pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM)
+
+        # ===== STEP 3: FEED ALL OUTPUT =====
+        serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4)
+
+        time.sleep(0.1)
+
+        """
+        line = serial_port.readline()
+        if line == b'SERIAL_IN_START\r\n':
+            # start = time.time()
+            # print('I have been there')
+            # ===== STEP 1: TAKE ALL INPUT =====
+            gbx, gby, gb_dist = ball_detection.detectLive(model, minDetectionScore, showSight = True)
+            # print("gbx,gby:{},{}".format(gbx,gby))
+            tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM = serial_port_in(serial_port)
+
+            # ===== STEP 2: MAIN CONTROL LOOP =====
+            pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM)
+
+            # ===== STEP 3: FEED ALL OUTPUT =====
+            serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4)
+
+
+            # end = time.time()
+            # print("time:")
+            # print(end - start)
+        if count == 0:
+            # first time calling (call once)
+            print("bbb")
+            pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM)
+            serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4)
+            count +=1
+        """
+
+        """
+        if flg == 1:
+            print("1")
+            output_message = '100100000000+-++' + '\n'
+            serial_port.write(output_message.encode())
+
+            flg = 0
+            time.sleep(0.3)
+        elif flg == 0:
+            print("2")
+            output_message = '000000000000+-++' + '\n'
+            serial_port.write(output_message.encode())
+            flg = 1
+            time.sleep(0.3)
+        """
+
+        # time.sleep(waitTime)
diff --git a/Code/Control/Laptop_Code/main_zhiying_seeking_indv_test.py b/Code/Control/Laptop_Code/main_backup/main_zhiying_seeking_indv_test.py
similarity index 87%
rename from Code/Control/Laptop_Code/main_zhiying_seeking_indv_test.py
rename to Code/Control/Laptop_Code/main_backup/main_zhiying_seeking_indv_test.py
index cfd5faa11965e62d3cba89a51e6b9330c40220de..f415d104b90fd622e712cf5861c29f2a12d57929 100644
--- a/Code/Control/Laptop_Code/main_zhiying_seeking_indv_test.py
+++ b/Code/Control/Laptop_Code/main_backup/main_zhiying_seeking_indv_test.py
@@ -1,336 +1,325 @@
-import time
-import serial
-import ball_detection.ball_detection as ball_detection
-import simple_pid.PID as PID
-
-from constants import *
-
-# ========= Serial Port I/O ===========
-
-def serial_port_in(serial_port):
-    '''
-    Description:
-        Take all ESP32_Master serial port's printIn and take all necessary input object
-
-    Input:
-        serial_port     :    serial.Serail object
-
-    Output:
-        tx, ty, tz, rx, ry, rz, LIDAR_dist, DebugM
-    '''
-
-    # DEBUG Verbose
-    print("initiating one round of serial in ...")
-
-    for i in range(7):
-        line = serial_port.readline()
-        val = int(line.decode())
-
-        if   i == 0:
-            tx = val
-        elif i == 1:
-            ty = val
-        elif i == 2:
-            tz = val
-        elif i == 3:
-            rx = val
-        elif i == 4:
-            ry = val
-        elif i == 5:
-            rz = val
-        elif i == 6:
-            LIDAR_dist = val
-
-    line = serial_port.readline()
-    debugM = line.decode()
-
-    # DEBUG Verbose
-    print("tx:{}".format(tx))
-    print("ty:{}".format(ty))
-    print("tz:{}".format(tz))
-    print("rx:{}".format(rx))
-    print("ry:{}".format(ry))
-    print("rz:{}".format(rz))
-    print("dist:{}".format(LIDAR_dist))
-    print(debugM)
-
-    return tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM
-
-
-def serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4):
-    '''
-    Description:
-        Feed to ESP32_Master to send ESP32_Slave necessary information
-        the format of sending is pwm are 3 digit space
-
-    Input:
-        serial_port                                     :   serial.Serail object
-        pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4  :   variables to send
-
-    Output:
-        None
-    '''
-
-    output_message = ''
-
-    for pwm_itr in [pwm1, pwm2, pwm3, pwm4]:
-        # print(pwm_itr)
-        if len(str(pwm_itr)) == 2:
-            output_message += '0'
-        elif len(str(pwm_itr)) == 1:
-            output_message += '00'
-        output_message += str(pwm_itr)
-        print(pwm_itr)
-
-    output_message = output_message + dir1 + dir2 +  dir3 +  dir4 + '\n'
-    serial_port.write(output_message.encode())
-
-    # DEBUG Verbose
-    print("serial out ...")
-    print(output_message)
-
-
-
-
-# ====== supporting function in main control ====
-def ball_detect(gbx, gby):
-    '''
-    return True if green ball is detected
-    '''
-    if gbx == -1 and gby == -1:
-        return False
-    else:
-        return True
-
-def goal_detect(tx,ty):
-    '''
-    return True if April Tag is detected
-    '''
-    if tx == 0 and ty == 0:
-        return False
-    else:
-        return True
-
-def ball_capture(LIDAR_dist):
-    '''
-    return True if April Tag is detected
-    '''
-    if (LIDAR_dist < LIDAR_Thres) and (LIDAR_dist > 0):  # Ball captured
-        return True
-    else:
-        return False
-
-def stop_all():
-    pwm1, pwm2, pwm3, pwm4 = 0 , 0 , 0 , 0
-    dir1, dir2, dir3, dir4 = '+', '-', '+', '-'
-    return pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4
-
-def move2goal(tx, ty):
-    """
-    Description:
-        Given the center of the AT tx, ty. Call PID control to output the blimp
-        motor to manuver to the goal
-
-    Input:
-        tx    :    x component, center of April Tag
-        ty    :    y component, center of Aprol Tag
-
-    Output:
-        pwm1, pwm2, pwm3, pwm4
-        dir1, dir2, dir3, dir4
-    """
-    pass
-
-    # return pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4
-
-
-def seeking():
-    """
-    Description:
-        By default, when there ball is not determined capture, the manuver of the
-        motors to have it scan its surronding 360 degrees
-
-    Input:
-        none
-
-    Output:
-        pwm1, pwm2, pwm3, pwm4
-        dir1, dir2, dir3, dir4
-    """
-    #pwm1, pwm2, pwm3, pwm4 = 0 , 0 , seeking_speed , seeking_speed
-    pwm1, pwm2, pwm3, pwm4 = 0 , 0 , 70, 70
-    dir1, dir2, dir3, dir4 = '+', '+', '+', '-'
-
-    return int(pwm1), int(pwm2), int(pwm3), int(pwm4), dir1, dir2, dir3, dir4
-
-
-def move2ball(gbx, gby, gb_dist):
-    """
-    Description:
-        Given the center of x y dist of green ball detected. Call PID control to
-        output the blimp motor to manuver to the green ball
-
-    Input:
-        gbx     :  x component, center of green ball
-        gby     :  y component, center of green ball
-        gb_dist :  distance to green ball
-
-    Output:
-        pwm1, pwm2, pwm3, pwm4
-        dir1, dir2, dir3, dir4
-    """
-    base_speed = 70
-
-    kdx,kix,kpx = 2,0.1,0.25
-    kdy,kiy,kpy = 1,0.1,0.25
-
-    inputx = gbx / 1.00
-    inputy = gby / 1.00
-
-    setpoint_x = 400
-    setpoint_y = 300  # ESP 32 Cam Center
-
-    pid_x = PID(kdx,kix,kpx,setpoint=setpoint_x)
-    pid_y = PID(kdy,kiy,kpy,setpoint=setpoint_y)
-
-
-    pid_x.auto_mode = True
-    pid_x.set_auto_mode(True, last_output=8.0)
-    pid_x.output_limits = (-255,255)
-    pid_y.output_limits = (-255,255)
-
-
-    outputx = pid_x(inputx)
-    outputy = pid_y(inputy)
-
-    # vertical
-    pwm1 = abs(outputy)
-    pwm2 = abs(outputy)
-
-    if(outputy > 0):
-        dir1 = '+'
-        dir2 = '+'
-    else:
-        dir1 = '-'
-        dir2 = '-'
-
-    # horizontal
-    lspeed = -1 * outputx + base_speed
-    rspeed =  1 * outputx + base_speed
-    pwm3 = abs(lspeed)
-    pwm4 = abs(rspeed)
-    if (lspeed > 0):
-        dir3 = '+'
-    else:
-        dir3 = '-'
-
-    if (rspeed > 0):
-        dir4 = '+'
-    else:
-        dir4 = '-'
-
-
-    return int(pwm1), int(pwm2), int(pwm3), int(pwm4), dir1, dir2, dir3, dir4
-
-
-
-#  =========== main control ===========
-
-def main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM):
-    '''
-    Description:
-        Given green ball information and AT information, the main control logic
-        to manuver the blimp motors
-
-    Input:
-        gbx, gby, gb_dist                   :   green ball information
-        tx, ty, tz, rx, ry, rz, LIDAR_dist  :   AirTag information
-        debugM                              :   Debug Message
-
-    Output:
-        pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4  :   Blimp motor manuver parameters
-    '''
-
-    # placeholder
-    pwm1, pwm2, pwm3, pwm4 = 0 , 0 , 0 , 0
-    dir1, dir2, dir3, dir4 = '+', '-', '+', '-'
-
-    ballDetect  = ball_detect(gbx, gby)
-    ballCapture = ball_capture(LIDAR_dist)
-    goalDetect  = goal_detect(tx,ty)
-    # debug
-    ballCapture = 0
-    if ballCapture: # Ball captured
-        if goalDetect:  # Goal detected
-            stop_all()
-            #pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = move2goal(tx, ty)
-        else:  # Goal not detected
-            stop_all()
-            #pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = seeking()
-    else:  # Ball not captured
-        if ballDetect:  # Ball detected
-            pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = move2ball(gbx,gby,gb_dist)
-        else:  # Ball not detected
-            pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = seeking()
-
-    return pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4
-
-
-
-# ===== Main Functions =====
-
-if __name__ == '__main__':
-    # =========== SET UP ============
-    # Defining Variables for ESP 32 Serial I/O
-    PORT = "COM6" # for Alienware
-    serial_port = serial.Serial(PORT, 115200)
-    serial_port.close()
-    serial_port.open()
-
-    # Weit Time
-    waitTime = 0.10
-
-    # Loading the PyTorch ML model for ball detection
-    model = ball_detection.returnModel(device, labelSet, modelLoc, modelFile)
-    #model = ball_detection.returnModel(modelAction, device, trainLoc, labelSet, modelLoc, modelFile)
-
-
-    # =========== DECLARE VARIABLES ===========
-    # ESP CAM In
-    gbx, gby  = -1, -1   # by default (-1 means no found green ball)
-    gb_dist = -1         # by default (-1 means no found green ball)
-
-    # Serial Port In
-    tx, ty, tz = 0, 0, 0  # by default (0 means no found AirTag)
-    rx, ry, rz = 0, 0, 0
-    LIDAR_dist = 0
-    debugM = 'Testing'
-
-    # Serial Port Out
-    pwm1, pwm2, pwm3, pwm4 = 0 , 0 , 0 , 0   # Not moving
-    dir1, dir2, dir3, dir4 = '+', '+', '+', '+'
-
-    count = 0
-    # =========== LOOP FOREVER===========
-    while True:
-        #gbx, gby, gb_dist = ball_detection.detectLive(model, minDetectionScore, showSight = True)
-        print("gbx,gby:{},{}".format(gbx,gby))
-
-        line = serial_port.readline()
-        if line == b'SERIAL_IN_START\r\n':
-            # ===== STEP 1: TAKE ALL INPUT =====
-            tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM = serial_port_in(serial_port)
-
-            # ===== STEP 2: MAIN CONTROL LOOP =====
-            pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM)
-
-            # ===== STEP 3: FEED ALL OUTPUT =====
-            serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4)
-
-        if count == 0:
-            # first time calling (call once)
-            pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM)
-            serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4)
-            # count +=1
-
-        time.sleep(waitTime)
+import time
+import serial
+import ball_detection.ball_detection as ball_detection
+import simple_pid.PID as PID
+import timeit
+
+from constants import *
+
+# ========= Serial Port I/O ===========
+
+def serial_port_in(serial_port):
+    '''
+    Description:
+        Take all ESP32_Master serial port's printIn and take all necessary input object
+
+    Input:
+        serial_port     :    serial.Serail object
+
+    Output:
+        tx, ty, tz, rx, ry, rz, LIDAR_dist, DebugM
+    '''
+
+    # DEBUG Verbose
+    print("initiating one round of serial in ...")
+
+    for i in range(7):
+        line = serial_port.readline()
+        val = int(line.decode())
+
+        if   i == 0:
+            tx = val
+        elif i == 1:
+            ty = val
+        elif i == 2:
+            tz = val
+        elif i == 3:
+            rx = val
+        elif i == 4:
+            ry = val
+        elif i == 5:
+            rz = val
+        elif i == 6:
+            LIDAR_dist = val
+
+    line = serial_port.readline()
+    debugM = line.decode()
+
+    # DEBUG Verbose
+    print("tx:{}".format(tx))
+    print("ty:{}".format(ty))
+    print("tz:{}".format(tz))
+    print("rx:{}".format(rx))
+    print("ry:{}".format(ry))
+    print("rz:{}".format(rz))
+    print("dist:{}".format(LIDAR_dist))
+    print(debugM)
+
+    return tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM
+
+
+def serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4):
+    '''
+    Description:
+        Feed to ESP32_Master to send ESP32_Slave necessary information
+        the format of sending is pwm are 3 digit space
+
+    Input:
+        serial_port                                     :   serial.Serail object
+        pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4  :   variables to send
+
+    Output:
+        None
+    '''
+    output_message = ''
+
+    for pwm_itr in [pwm1, pwm2, pwm3, pwm4]:
+        # print(pwm_itr)
+        if len(str(pwm_itr)) == 2:
+            output_message += '0'
+        elif len(str(pwm_itr)) == 1:
+            output_message += '00'
+        output_message += str(pwm_itr)
+        print(pwm_itr)
+
+    output_message = output_message + dir1 + dir2 +  dir3 +  dir4 + '\n'
+    print("serial out ...")
+    print(output_message)
+    serial_port.write(output_message.encode())
+
+
+# ====== Logic-directing Functions ====
+def ball_detect(gbx, gby):
+    '''
+    return True if green ball is detected
+    '''
+    if gbx == -1 and gby == -1:
+        return False
+    else:
+        return True
+
+def goal_detect(tx,ty):
+    '''
+    return True if April Tag is detected
+    '''
+    if tx == 0 and ty == 0:
+        return False
+    else:
+        return True
+
+def ball_capture(LIDAR_dist):
+    '''
+    return True if April Tag is detected
+    '''
+    if (LIDAR_dist < LIDAR_Thres) and (LIDAR_dist > 0):  # Ball captured
+        return True
+    else:
+        return False
+
+def stop_all():
+    pwm1, pwm2, pwm3, pwm4 = 0 , 0 , 0 , 0
+    dir1, dir2, dir3, dir4 = '+', '-', '+', '-'
+    return pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4
+
+def move2goal(tx, ty):
+    """
+    Description:
+        Given the center of the AT tx, ty. Call PID control to output the blimp
+        motor to manuver to the goal
+
+    Input:
+        tx    :    x component, center of April Tag
+        ty    :    y component, center of Aprol Tag
+
+    Output:
+        pwm1, pwm2, pwm3, pwm4
+        dir1, dir2, dir3, dir4
+    """
+    pass
+
+    # return pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4
+
+
+def seeking():
+    """
+    Description:
+        By default, when there ball is not determined capture, the manuver of the
+        motors to have it scan its surronding 360 degrees
+
+    Input:
+        none
+
+    Output:
+        pwm1, pwm2, pwm3, pwm4
+        dir1, dir2, dir3, dir4
+    """
+    # pwm1, pwm2, pwm3, pwm4 = 0 , 0 , seeking_speed , seeking_speed
+    pwm1, pwm2, pwm3, pwm4 = 0 , 0 , 70, 70
+    dir1, dir2, dir3, dir4 = '+', '+', '+', '-'
+
+    return int(pwm1), int(pwm2), int(pwm3), int(pwm4), dir1, dir2, dir3, dir4
+
+
+def move2ball(gbx, gby, gb_dist):
+    """
+    Description:
+        Given the center of x y dist of green ball detected. Call PID control to
+        output the blimp motor to manuver to the green ball
+
+    Input:
+        gbx     :  x component, center of green ball
+        gby     :  y component, center of green ball
+        gb_dist :  distance to green ball
+
+    Output:
+        pwm1, pwm2, pwm3, pwm4
+        dir1, dir2, dir3, dir4
+    """
+    base_speed = 70
+
+    kdx,kix,kpx = 2,0.1,0.25
+    kdy,kiy,kpy = 1,0.1,0.25
+
+    inputx = gbx / 1.00
+    inputy = gby / 1.00
+
+    # ESP-Cam Center
+    setpoint_x = 400
+    setpoint_y = 300
+
+    pid_x = PID(kpx, kix, kdx, setpoint = setpoint_x)
+    pid_y = PID(kpy, kiy, kdy, setpoint = setpoint_y)
+
+    pid_x.auto_mode = True
+    pid_x.set_auto_mode(True, last_output = 8.0)
+    pid_x.output_limits = (-255,255)
+    pid_y.output_limits = (-255,255)
+    
+    outputx = pid_x(inputx)
+    outputy = pid_y(inputy)
+
+    # Vertical
+    pwm1 = abs(outputy)
+    pwm2 = abs(outputy)
+
+    if(outputy > 0):
+        dir1 = '+'
+        dir2 = '+'
+    else:
+        dir1 = '-'
+        dir2 = '-'
+
+    # horizontal
+    lspeed = -1 * outputx + base_speed
+    rspeed =  1 * outputx + base_speed
+    pwm3 = abs(lspeed)
+    pwm4 = abs(rspeed)
+    if (lspeed > 0):
+        dir3 = '+'
+    else:
+        dir3 = '-'
+    if (rspeed > 0):
+        dir4 = '+'
+    else:
+        dir4 = '-'
+
+    return int(pwm1), int(pwm2), int(pwm3), int(pwm4), dir1, dir2, dir3, dir4
+
+
+#  =========== Main Control ===========
+def main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM):
+    '''
+    Description:
+        Given green ball information and AT information, the main control logic
+        to manuver the blimp motors
+
+    Input:
+        gbx, gby, gb_dist                   :   green ball information
+        tx, ty, tz, rx, ry, rz, LIDAR_dist  :   AirTag information
+        debugM                              :   Debug Message
+
+    Output:
+        pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4  :   Blimp motor manuver parameters
+    '''
+    # placeholder
+    pwm1, pwm2, pwm3, pwm4 = 0 , 0 , 0 , 0
+    dir1, dir2, dir3, dir4 = '+', '-', '+', '-'
+
+    ballDetect  = ball_detect(gbx, gby)
+    ballCapture = ball_capture(LIDAR_dist)
+    goalDetect  = goal_detect(tx, ty)
+    
+    ballCapture = 0  # debug
+    if ballCapture: # Ball captured
+        if goalDetect:  # Goal detected
+            stop_all()  # Debug
+            # pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = move2goal(tx, ty)
+        else:  # Goal not detected
+            stop_all()  # Debug
+            # pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = seeking()
+    else:  # Ball not captured
+        if ballDetect:  # Ball detected
+            pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = move2ball(gbx,gby,gb_dist)
+        else:  # Ball not detected
+            # stop_all()  # Debug
+            pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = seeking()
+    
+    return pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4
+
+
+# ===== Main Function =====
+if __name__ == '__main__':
+    # =========== SET UP ============
+    # Defining Variables for ESP 32 Serial I/O
+    PORT = "COM6" # for Alienware
+    serial_port = serial.Serial(PORT, 115200)
+    serial_port.close()
+    serial_port.open()
+
+    # Wait Time
+    waitTime = 0.10
+
+    # Loading the PyTorch ML model for ball detection
+    model = ball_detection.returnModel(device, labelSet, modelLoc, modelFile)
+    # model = ball_detection.returnModel(modelAction, device, trainLoc, labelSet, modelLoc, modelFile)
+
+
+    # =========== DECLARE VARIABLES ===========
+    # ESP CAM In
+    gbx, gby  = -1, -1   # by default (-1 means no found green ball)
+    gb_dist = -1         # by default (-1 means no found green ball)
+
+    # Serial Port In
+    tx, ty, tz = 0, 0, 0  # by default (0 means no found AirTag)
+    rx, ry, rz = 0, 0, 0
+    LIDAR_dist = 0
+    debugM = 'Testing'
+
+    # Serial Port Out
+    pwm1, pwm2, pwm3, pwm4 = 0 , 0 , 0 , 0   # Not moving
+    dir1, dir2, dir3, dir4 = '+', '+', '+', '+'
+
+    count = 0
+    # =========== LOOP FOREVER===========
+    while True:
+        #gbx, gby, gb_dist = ball_detection.detectLive(model, minDetectionScore, showSight = True)
+        print("gbx,gby:{},{}".format(gbx,gby))
+
+        line = serial_port.readline()
+        if line == b'SERIAL_IN_START\r\n':
+            # ===== STEP 1: TAKE ALL INPUT =====
+            tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM = serial_port_in(serial_port)
+
+            # ===== STEP 2: MAIN CONTROL LOOP =====
+            pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM)
+
+            # ===== STEP 3: FEED ALL OUTPUT =====
+            serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4)
+
+        if count == 0:
+            # first time calling (call once)
+            pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM)
+            serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4)
+            # count +=1
+
+        time.sleep(waitTime)
\ No newline at end of file
diff --git a/Code/Control/Laptop_Code/main_integrated_test.py b/Code/Control/Laptop_Code/main_integrated_test.py
index 1f1efaec3e203ba0e8f06debd4dda15db9cd2a30..41dad51d6a4eb16cef6c6e9336366e9c0256ecd9 100644
--- a/Code/Control/Laptop_Code/main_integrated_test.py
+++ b/Code/Control/Laptop_Code/main_integrated_test.py
@@ -4,7 +4,6 @@ import ball_detection.ball_detection as ball_detection
 import simple_pid.PID as PID
 import timeit
 
-
 from constants import *
 
 # ========= Serial Port I/O ===========
@@ -72,7 +71,6 @@ def serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4)
     Output:
         None
     '''
-
     output_message = ''
 
     for pwm_itr in [pwm1, pwm2, pwm3, pwm4]:
@@ -90,7 +88,7 @@ def serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4)
     serial_port.write(output_message.encode())
 
 
-# ====== supporting function in main control ====
+# ====== Logic-directing Functions ====
 def ball_detect(gbx, gby):
     '''
     return True if green ball is detected
@@ -104,7 +102,7 @@ def goal_detect(tx,ty):
     '''
     return True if April Tag is detected
     '''
-    if tx == 0 and ty == 0:
+    if tx == 100000 and ty == 100000:
         return False
     else:
         return True
@@ -123,7 +121,6 @@ def stop_all():
     dir1, dir2, dir3, dir4 = '+', '-', '+', '-'
     return pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4
 
-
 def move2goal(tx, ty):
     """
     Description:
@@ -161,11 +158,11 @@ def move2goal(tx, ty):
     pwm2 = abs(outputy)
 
     if(outputy > 0):
-        dir1 = '+'
-        dir2 = '+'
-    else:
         dir1 = '-'
         dir2 = '-'
+    else:
+        dir1 = '+'
+        dir2 = '+'
 
     # Horizontal
     lspeed = -1 * outputx + base_speed
@@ -184,8 +181,6 @@ def move2goal(tx, ty):
     return int(pwm1), int(pwm2), int(pwm3), int(pwm4), dir1, dir2, dir3, dir4
 
 
-
-
 def seeking():
     """
     Description:
@@ -223,23 +218,22 @@ def move2ball(gbx, gby, gb_dist):
     inputx = gbx / 1.00
     inputy = gby / 1.00
 
+    # ESP-Cam Center
     setpoint_x = 400
-    setpoint_y = 300  # ESP 32 Cam Center
-
-    pid_x = PID(kpx,kix,kdx,setpoint=setpoint_x)
-    pid_y = PID(kpy,kiy,kdy,setpoint=setpoint_y)
+    setpoint_y = 300
 
+    pid_x = PID(kpx, kix, kdx, setpoint = setpoint_x)
+    pid_y = PID(kpy, kiy, kdy, setpoint = setpoint_y)
 
     pid_x.auto_mode = True
-    pid_x.set_auto_mode(True, last_output=8.0)
+    pid_x.set_auto_mode(True, last_output = 8.0)
     pid_x.output_limits = (-255,255)
     pid_y.output_limits = (-255,255)
 
-
     outputx = pid_x(inputx)
     outputy = pid_y(inputy)
 
-    # vertical
+    # Vertical
     pwm1 = abs(outputy)
     pwm2 = abs(outputy)
 
@@ -250,28 +244,24 @@ def move2ball(gbx, gby, gb_dist):
         dir1 = '-'
         dir2 = '-'
 
-    # horizontal
+    # Horizontal
     lspeed = -1 * outputx + base_speed
     rspeed =  1 * outputx + base_speed
-    pwm3 = min( abs(lspeed), 255)
-    pwm4 = min( abs(rspeed), 255)
+    pwm3 = min(abs(lspeed), 255)
+    pwm4 = min(abs(rspeed), 255)
     if (lspeed > 0):
         dir3 = '+'
     else:
         dir3 = '-'
-
     if (rspeed > 0):
         dir4 = '+'
     else:
         dir4 = '-'
 
-
     return int(pwm1), int(pwm2), int(pwm3), int(pwm4), dir1, dir2, dir3, dir4
 
 
-
-#  =========== main control ===========
-
+#  =========== Main Control ===========
 def main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM):
     '''
     Description:
@@ -286,40 +276,36 @@ def main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM):
     Output:
         pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4  :   Blimp motor manuver parameters
     '''
-
-    # # placeholder
+    # placeholder
     pwm1, pwm2, pwm3, pwm4 = 0 , 0 , 0 , 0
     dir1, dir2, dir3, dir4 = '+', '-', '+', '-'
 
     ballDetect  = ball_detect(gbx, gby)
     ballCapture = ball_capture(LIDAR_dist)
-    goalDetect  = goal_detect(tx,ty)
+    goalDetect  = goal_detect(tx, ty)
 
-    # debug
     if ballCapture: # Ball captured
         if goalDetect:  # Goal detected
-            #stop_all()
+            # stop_all()  # Debug
             pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = move2goal(tx, ty)
         else:  # Goal not detected
-            #stop_all()
+            # stop_all()  # Debug
             pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = seeking()
     else:  # Ball not captured
         if ballDetect:  # Ball detected
             pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = move2ball(gbx,gby,gb_dist)
         else:  # Ball not detected
-            # stop_all()
+            # stop_all()  # Debug
             pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = seeking()
 
     return pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4
 
 
-
-# ===== Main Functions =====
-
+# ===== Main Function =====
 if __name__ == '__main__':
     # =========== SET UP ============
     # Defining Variables for ESP 32 Serial I/O
-    PORT = "COM20" # for Alienware
+    PORT = "COM6" # for Alienware
     serial_port = serial.Serial(PORT, 115200)
     serial_port.close()
     serial_port.open()
@@ -330,14 +316,13 @@ if __name__ == '__main__':
     # Loading the PyTorch ML model for ball detection
     model = ball_detection.returnModel(device, labelSet, modelLoc, modelFile)
 
-
     # =========== DECLARE VARIABLES ===========
     # ESP CAM In
     gbx, gby  = -1, -1   # by default (-1 means no found green ball)
     gb_dist = -1         # by default (-1 means no found green ball)
 
     # Serial Port In
-    tx, ty, tz = 0, 0, 0  # by default (0 means no found AirTag)
+    tx, ty, tz = 100000, 100000, 100000  # by default (0 means no found AirTag)
     rx, ry, rz = 0, 0, 0
     LIDAR_dist = 0
     debugM = 'Testing'
@@ -346,21 +331,19 @@ if __name__ == '__main__':
     pwm1, pwm2, pwm3, pwm4 = 0 , 0 , 0 , 0   # Not moving
     dir1, dir2, dir3, dir4 = '+', '+', '+', '+'
 
-    # =========== LOOP FOREVER===========
-    # Trigger the ESP32_SLAVE Talk First
+    # Trigger the ESP32_SLAVE to talk first
     gbx, gby, gb_dist = ball_detection.detectLive(model, minDetectionScore, showSight = True)
     pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM)
     serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4)
 
+    # =========== LOOP FOREVER===========
     while True:
         # ===== STEP 1: TAKE ALL INPUT =====
         gbx, gby, gb_dist = ball_detection.detectLive(model, minDetectionScore, showSight = True)
         line = serial_port.readline()
 
         if line == b'SERIAL_IN_START\r\n':
-
             tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM = serial_port_in(serial_port)
-
             print("gbx,gby:{},{}".format(gbx,gby))
             time.sleep(waitTime)
 
@@ -370,4 +353,4 @@ if __name__ == '__main__':
         # ===== STEP 3: FEED ALL OUTPUT =====
         serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4)
 
-        time.sleep(waitTime)
+        time.sleep(waitTime)
\ No newline at end of file
diff --git a/Code/Control/Laptop_Code/main_aaron_move2goal.py b/Code/Control/Laptop_Code/main_keyboard.py
similarity index 63%
rename from Code/Control/Laptop_Code/main_aaron_move2goal.py
rename to Code/Control/Laptop_Code/main_keyboard.py
index d92a1f5652a9827f6e495519ec13d66a65dd5a76..a7dd3dbbcfee30f6945160082bf6bf9d17d24bf1 100644
--- a/Code/Control/Laptop_Code/main_aaron_move2goal.py
+++ b/Code/Control/Laptop_Code/main_keyboard.py
@@ -2,6 +2,7 @@ import time
 import serial
 import ball_detection.ball_detection as ball_detection
 import simple_pid.PID as PID
+import cv2
 
 from constants import *
 
@@ -73,19 +74,18 @@ def serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4)
     output_message = ''
 
     for pwm_itr in [pwm1, pwm2, pwm3, pwm4]:
-        print(pwm_itr)
+        # print(pwm_itr)
         if len(str(pwm_itr)) == 2:
             output_message += '0'
         elif len(str(pwm_itr)) == 1:
             output_message += '00'
         output_message += str(pwm_itr)
+        print(pwm_itr)
 
     output_message = output_message + dir1 + dir2 +  dir3 +  dir4 + '\n'
-    serial_port.write(output_message.encode())
-
-    # DEBUG Verbose
     print("serial out ...")
     print(output_message)
+    serial_port.write(output_message.encode())
 
 
 # ====== Logic-directing Functions ====
@@ -102,7 +102,7 @@ def goal_detect(tx,ty):
     '''
     return True if April Tag is detected
     '''
-    if tx == 0 and ty == 0:
+    if tx == 100000 and ty == 100000:
         return False
     else:
         return True
@@ -116,13 +116,11 @@ def ball_capture(LIDAR_dist):
     else:
         return False
 
-# ======= Motion-based Functions ======
 def stop_all():
     pwm1, pwm2, pwm3, pwm4 = 0 , 0 , 0 , 0
     dir1, dir2, dir3, dir4 = '+', '-', '+', '-'
     return pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4
 
-
 def move2goal(tx, ty):
     """
     Description:
@@ -138,11 +136,11 @@ def move2goal(tx, ty):
         dir1, dir2, dir3, dir4
     """
     inputx = tx / 1.00
-    inputy = ty / 1.00
+    inputy = -1.00 * (ty + AT_goal_Delta) / 1.00 #
 
     # April Tag Center
-    setpoint_x1 = 160
-    setpoint_y1 = 120
+    setpoint_x1 = 0.0
+    setpoint_y1 = 0.0
 
     pid_x = PID(kdx_g, kix_g, kpx_g, setpoint = setpoint_x1)
     pid_y = PID(kdx_g, kiy_g, kpy_g, setpoint = setpoint_y1)
@@ -160,11 +158,11 @@ def move2goal(tx, ty):
     pwm2 = abs(outputy)
 
     if(outputy > 0):
-        dir1 = '+'
-        dir2 = '+'
-    else:
         dir1 = '-'
         dir2 = '-'
+    else:
+        dir1 = '+'
+        dir2 = '+'
 
     # Horizontal
     lspeed = -1 * outputx + base_speed
@@ -201,7 +199,8 @@ def seeking():
 
     return int(pwm1), int(pwm2), int(pwm3), int(pwm4), dir1, dir2, dir3, dir4
 
-def move2ball(gbx,gby,gb_dist):
+
+def move2ball(gbx, gby, gb_dist):
     """
     Description:
         Given the center of x y dist of green ball detected. Call PID control to
@@ -223,8 +222,8 @@ def move2ball(gbx,gby,gb_dist):
     setpoint_x = 400
     setpoint_y = 300
 
-    pid_x = PID(kdx_b, kix_b, kpx_b, setpoint = setpoint_x)
-    pid_y = PID(kdx_b, kiy_b, kpy_b, setpoint = setpoint_y)
+    pid_x = PID(kpx, kix, kdx, setpoint = setpoint_x)
+    pid_y = PID(kpy, kiy, kdy, setpoint = setpoint_y)
 
     pid_x.auto_mode = True
     pid_x.set_auto_mode(True, last_output = 8.0)
@@ -248,8 +247,8 @@ def move2ball(gbx,gby,gb_dist):
     # Horizontal
     lspeed = -1 * outputx + base_speed
     rspeed =  1 * outputx + base_speed
-    pwm3 = abs(lspeed)
-    pwm4 = abs(rspeed)
+    pwm3 = min(abs(lspeed), 255)
+    pwm4 = min(abs(rspeed), 255)
     if (lspeed > 0):
         dir3 = '+'
     else:
@@ -262,8 +261,7 @@ def move2ball(gbx,gby,gb_dist):
     return int(pwm1), int(pwm2), int(pwm3), int(pwm4), dir1, dir2, dir3, dir4
 
 
-#  =========== main control ===========
-
+#  =========== Main Control ===========
 def main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM):
     '''
     Description:
@@ -286,27 +284,118 @@ def main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM):
     ballCapture = ball_capture(LIDAR_dist)
     goalDetect  = goal_detect(tx, ty)
 
-    print("ballDetect  = ", ballDetect)
-    print("ballCapture = ", ballCapture)
-    print("goalDetect  = ", goalDetect)
-
     if ballCapture: # Ball captured
         if goalDetect:  # Goal detected
+            # stop_all()  # Debug
             pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = move2goal(tx, ty)
-        else:  # Goal not detectedpwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 =
+        else:  # Goal not detected
+            # stop_all()  # Debug
             pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = seeking()
     else:  # Ball not captured
         if ballDetect:  # Ball detected
             pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = move2ball(gbx,gby,gb_dist)
         else:  # Ball not detected
+            # stop_all()  # Debug
             pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = seeking()
 
     return pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4
 
+# ============= keyboard interruption ===================
+
+def init():
+    pygame.init()
+    win= pygame.display.set_mode((200,200))
+
+def keyboard_stop(flag_s,print_count_s):
 
+    if get_key('q'):
+        flag_s = 0
+        print_count_s = 1
+    return flag_s,print_count_s
 
-# ===== Main Functions =====
+def get_key(keyname):
+    ans = False
+    for eve in pygame.event.get(): pass
+    keyInput = pygame.key.get_pressed()
+    myKey = getattr(pygame,'K_{}'.format(keyname))
 
+    if keyInput[myKey]:
+        ans = True
+    pygame.display.update()
+    return ans
+
+def auto_control(serial_port):
+    # =================================== tested autonomous control ======================================================
+    # ===== STEP 1: TAKE ALL INPUT =====
+    waitTime = 0.05
+    gbx, gby, gb_dist = ball_detection.detectLive(model, minDetectionScore, showSight=True)
+    line = serial_port.readline()
+
+    if line == b'SERIAL_IN_START\r\n':
+        tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM = serial_port_in(serial_port)
+        print("gbx,gby:{},{}".format(gbx, gby))
+        time.sleep(waitTime)
+
+    # ===== STEP 2: MAIN CONTROL LOOP =====
+    pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist,
+                                                                  debugM)
+
+    # ===== STEP 3: FEED ALL OUTPUT =====
+    serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4)
+
+    time.sleep(waitTime)  # second
+    # =========================================================================================
+
+def decode_ctl(Ctl_com):
+    pwm1 = Ctl_com[0]
+    pwm2 = Ctl_com[1]
+    pwm3 = Ctl_com[2]
+    pwm4 = Ctl_com[3]
+    dir1 = Ctl_com[4]
+    dir2 = Ctl_com[5]
+    dir3 = Ctl_com[6]
+    dir4 = Ctl_com[7]
+    return pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4
+
+def manual_control(Ctl_com,serial_port):
+
+    if get_key("w"):
+        val = start_speed
+        Ctl_com = manual_command(val, val, 0, 0, "+", "+", "+", "+")
+
+    elif get_key("s"):
+        val = start_speed
+        Ctl_com = manual_command(val, val, 0, 0, "-", "-", "+", "+")
+
+    if get_key("UP"):
+        val = start_speed
+
+        Ctl_com = manual_command(0, 0, val, val, "+", "+", "+", "+")
+    elif get_key("DOWN"):
+        val = start_speed
+        Ctl_com = manual_command(0, 0, val, val, "+", "+", "-", "-")
+
+    elif get_key("LEFT"):
+        val = start_speed
+        Ctl_com = manual_command(0, 0, val, val, "+", "+", "-", "+")
+
+    elif get_key("RIGHT"):
+        val = start_speed
+        Ctl_com = manual_command(0, 0, val, val, "+", "+", "+", "-")
+
+    pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = decode_ctl(Ctl_com)
+
+    waitTime = 0.05
+
+    serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4)
+
+    time.sleep(waitTime)
+
+
+def variables_change():
+    pass
+
+# ===== Main Function =====
 if __name__ == '__main__':
     # =========== SET UP ============
     # Defining Variables for ESP 32 Serial I/O
@@ -316,7 +405,7 @@ if __name__ == '__main__':
     serial_port.open()
 
     # Weit Time
-    waitTime = 0.10
+    waitTime = 0.05
 
     # Loading the PyTorch ML model for ball detection
     model = ball_detection.returnModel(device, labelSet, modelLoc, modelFile)
@@ -327,7 +416,7 @@ if __name__ == '__main__':
     gb_dist = -1         # by default (-1 means no found green ball)
 
     # Serial Port In
-    tx, ty, tz = 0, 0, 0  # by default (0 means no found AirTag)
+    tx, ty, tz = 100000, 100000, 100000  # by default (0 means no found AirTag)
     rx, ry, rz = 0, 0, 0
     LIDAR_dist = 0
     debugM = 'Testing'
@@ -336,27 +425,45 @@ if __name__ == '__main__':
     pwm1, pwm2, pwm3, pwm4 = 0 , 0 , 0 , 0   # Not moving
     dir1, dir2, dir3, dir4 = '+', '+', '+', '+'
 
-    count = 0
+    # Trigger the ESP32_SLAVE to talk first
+    gbx, gby, gb_dist = ball_detection.detectLive(model, minDetectionScore, showSight = True)
+    pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM)
+    serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4)
+
+    Ctl_com = [0, 0, 0, 0, "+", "+", "+", "+"]
+    flag = 0
+    print_count = 1
+    init()
     # =========== LOOP FOREVER===========
     while True:
-        # gbx, gby, gb_dist = ball_detection.detectLive(model, minDetectionScore, showSight = True)
-        # print("gbx, gby: {}, {}".format(gbx, gby))
 
-        line = serial_port.readline()
-        if line == b'SERIAL_IN_START\r\n':
-            # ===== STEP 1: TAKE ALL INPUT =====
-            tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM = serial_port_in(serial_port)
+        if get_key('a'):
+            flag = 1
+            while (flag == 1):
+                auto_control(serial_port)
+                flag, print_count = keyboard_stop(flag,print_count)
+
+        elif get_key('s'):
+            stop_all()
+            print("stop all motors")
+
+        elif get_key('m'):
+            flag = 2
+            while (flag == 2):
+                manual_control(Ctl_com,serial_port)
+                flag, print_count = keyboard_stop(flag,print_count)
+
+        elif get_key('v'):
+            flag = 3
+            while (flag == 3):
+                variables_change()
+                flag, print_count = keyboard_stop(flag,print_count)
+        elif get_key('k'):
+            break
 
-            # ===== STEP 2: MAIN CONTROL LOOP =====
-            pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM)
+        if print_count is not 0:
+            print("No subsystem is running")
+            print_count = 0
 
-            # ===== STEP 3: FEED ALL OUTPUT =====
-            serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4)
 
-            time.sleep(waitTime)
 
-        if count == 0:
-            # first time calling (call once)
-            pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM)
-            serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4)
-            count +=1
diff --git a/Code/Control/Laptop_Code/main_zhiying_move2ball_indv_test.py b/Code/Control/Laptop_Code/main_zhiying_move2ball_indv_test.py
deleted file mode 100644
index da8bf923f35a56d2f1721593d70164aaf462d203..0000000000000000000000000000000000000000
--- a/Code/Control/Laptop_Code/main_zhiying_move2ball_indv_test.py
+++ /dev/null
@@ -1,334 +0,0 @@
-import time
-import serial
-import ball_detection.ball_detection as ball_detection
-import simple_pid.PID as PID
-
-from constants import *
-
-# ========= Serial Port I/O ===========
-
-def serial_port_in(serial_port):
-    '''
-    Description:
-        Take all ESP32_Master serial port's printIn and take all necessary input object
-
-    Input:
-        serial_port     :    serial.Serail object
-
-    Output:
-        tx, ty, tz, rx, ry, rz, LIDAR_dist, DebugM
-    '''
-
-    # DEBUG Verbose
-    print("initiating one round of serial in ...")
-
-    for i in range(7):
-        line = serial_port.readline()
-        val = int(line.decode())
-
-        if   i == 0:
-            tx = val
-        elif i == 1:
-            ty = val
-        elif i == 2:
-            tz = val
-        elif i == 3:
-            rx = val
-        elif i == 4:
-            ry = val
-        elif i == 5:
-            rz = val
-        elif i == 6:
-            LIDAR_dist = val
-
-    line = serial_port.readline()
-    debugM = line.decode()
-
-    # DEBUG Verbose
-    print("tx:{}".format(tx))
-    print("ty:{}".format(ty))
-    print("tz:{}".format(tz))
-    print("rx:{}".format(rx))
-    print("ry:{}".format(ry))
-    print("rz:{}".format(rz))
-    print("dist:{}".format(LIDAR_dist))
-    print(debugM)
-
-    return tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM
-
-
-def serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4):
-    '''
-    Description:
-        Feed to ESP32_Master to send ESP32_Slave necessary information
-        the format of sending is pwm are 3 digit space
-
-    Input:
-        serial_port                                     :   serial.Serail object
-        pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4  :   variables to send
-
-    Output:
-        None
-    '''
-
-    output_message = ''
-
-    for pwm_itr in [pwm1, pwm2, pwm3, pwm4]:
-        # print(pwm_itr)
-        if len(str(pwm_itr)) == 2:
-            output_message += '0'
-        elif len(str(pwm_itr)) == 1:
-            output_message += '00'
-        output_message += str(pwm_itr)
-        print(pwm_itr)
-
-    output_message = output_message + dir1 + dir2 +  dir3 +  dir4 + '\n'
-    serial_port.write(output_message.encode())
-
-    # DEBUG Verbose
-    print("serial out ...")
-    print(output_message)
-
-
-
-
-# ====== supporting function in main control ====
-def ball_detect(gbx, gby):
-    '''
-    return True if green ball is detected
-    '''
-    if gbx == -1 and gby == -1:
-        return False
-    else:
-        return True
-
-def goal_detect(tx,ty):
-    '''
-    return True if April Tag is detected
-    '''
-    if tx == 0 and ty == 0:
-        return False
-    else:
-        return True
-
-def ball_capture(LIDAR_dist):
-    '''
-    return True if April Tag is detected
-    '''
-    if (LIDAR_dist < LIDAR_Thres) and (LIDAR_dist > 0):  # Ball captured
-        return True
-    else:
-        return False
-
-def stop_all():
-    pwm1, pwm2, pwm3, pwm4 = 0 , 0 , 0 , 0
-    dir1, dir2, dir3, dir4 = '+', '-', '+', '-'
-    return pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4
-
-def move2goal(tx, ty):
-    """
-    Description:
-        Given the center of the AT tx, ty. Call PID control to output the blimp
-        motor to manuver to the goal
-
-    Input:
-        tx    :    x component, center of April Tag
-        ty    :    y component, center of Aprol Tag
-
-    Output:
-        pwm1, pwm2, pwm3, pwm4
-        dir1, dir2, dir3, dir4
-    """
-    pass
-
-    # return pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4
-
-
-def seeking():
-    """
-    Description:
-        By default, when there ball is not determined capture, the manuver of the
-        motors to have it scan its surronding 360 degrees
-
-    Input:
-        none
-
-    Output:
-        pwm1, pwm2, pwm3, pwm4
-        dir1, dir2, dir3, dir4
-    """
-    pass
-    # return pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4
-
-
-def move2ball(gbx, gby, gb_dist):
-    """
-    Description:
-        Given the center of x y dist of green ball detected. Call PID control to
-        output the blimp motor to manuver to the green ball
-
-    Input:
-        gbx     :  x component, center of green ball
-        gby     :  y component, center of green ball
-        gb_dist :  distance to green ball
-
-    Output:
-        pwm1, pwm2, pwm3, pwm4
-        dir1, dir2, dir3, dir4
-    """
-    base_speed = 70
-
-    kdx,kix,kpx = 2,0.1,0.25
-    kdy,kiy,kpy = 1,0.1,0.25
-
-    inputx = gbx / 1.00
-    inputy = gby / 1.00
-
-    setpoint_x = 400
-    setpoint_y = 300  # ESP 32 Cam Center
-
-    pid_x = PID(kdx,kix,kpx,setpoint=setpoint_x)
-    pid_y = PID(kdy,kiy,kpy,setpoint=setpoint_y)
-
-
-    pid_x.auto_mode = True
-    pid_x.set_auto_mode(True, last_output=8.0)
-    pid_x.output_limits = (-255,255)
-    pid_y.output_limits = (-255,255)
-
-
-    outputx = pid_x(inputx)
-    outputy = pid_y(inputy)
-
-    # vertical
-    pwm1 = abs(outputy)
-    pwm2 = abs(outputy)
-
-    if(outputy > 0):
-        dir1 = '+'
-        dir2 = '+'
-    else:
-        dir1 = '-'
-        dir2 = '-'
-
-    # horizontal
-    lspeed = -1 * outputx + base_speed
-    rspeed =  1 * outputx + base_speed
-    pwm3 = abs(lspeed)
-    pwm4 = abs(rspeed)
-    if (lspeed > 0):
-        dir3 = '+'
-    else:
-        dir3 = '-'
-
-    if (rspeed > 0):
-        dir4 = '+'
-    else:
-        dir4 = '-'
-
-
-    return int(pwm1), int(pwm2), int(pwm3), int(pwm4), dir1, dir2, dir3, dir4
-
-
-
-#  =========== main control ===========
-
-def main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM):
-    '''
-    Description:
-        Given green ball information and AT information, the main control logic
-        to manuver the blimp motors
-
-    Input:
-        gbx, gby, gb_dist                   :   green ball information
-        tx, ty, tz, rx, ry, rz, LIDAR_dist  :   AirTag information
-        debugM                              :   Debug Message
-
-    Output:
-        pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4  :   Blimp motor manuver parameters
-    '''
-
-    # placeholder
-    pwm1, pwm2, pwm3, pwm4 = 0 , 0 , 0 , 0
-    dir1, dir2, dir3, dir4 = '+', '-', '+', '-'
-
-    ballDetect  = ball_detect(gbx, gby)
-    ballCapture = ball_capture(LIDAR_dist)
-    goalDetect  = goal_detect(tx,ty)
-    # debug
-    ballCapture = 0
-    if ballCapture: # Ball captured
-        if goalDetect:  # Goal detected
-            stop_all()
-            #pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = move2goal(tx, ty)
-        else:  # Goal not detected
-            stop_all()
-            #pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = seeking()
-    else:  # Ball not captured
-        if ballDetect:  # Ball detected
-            pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = move2ball(gbx,gby,gb_dist)
-        else:  # Ball not detected
-            stop_all()
-            #pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = seeking()
-
-    return pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4
-
-
-
-# ===== Main Functions =====
-
-if __name__ == '__main__':
-    # =========== SET UP ============
-    # Defining Variables for ESP 32 Serial I/O
-    PORT = "COM6" # for Alienware
-    serial_port = serial.Serial(PORT, 115200)
-    serial_port.close()
-    serial_port.open()
-
-    # Weit Time
-    waitTime = 0.10
-
-    # Loading the PyTorch ML model for ball detection
-    model = ball_detection.returnModel(device, labelSet, modelLoc, modelFile)
-    #model = ball_detection.returnModel(modelAction, device, trainLoc, labelSet, modelLoc, modelFile)
-
-
-    # =========== DECLARE VARIABLES ===========
-    # ESP CAM In
-    gbx, gby  = -1, -1   # by default (-1 means no found green ball)
-    gb_dist = -1         # by default (-1 means no found green ball)
-
-    # Serial Port In
-    tx, ty, tz = 0, 0, 0  # by default (0 means no found AirTag)
-    rx, ry, rz = 0, 0, 0
-    LIDAR_dist = 0
-    debugM = 'Testing'
-
-    # Serial Port Out
-    pwm1, pwm2, pwm3, pwm4 = 0 , 0 , 0 , 0   # Not moving
-    dir1, dir2, dir3, dir4 = '+', '+', '+', '+'
-
-    count = 0
-    # =========== LOOP FOREVER===========
-    while True:
-        gbx, gby, gb_dist = ball_detection.detectLive(model, minDetectionScore, showSight = True)
-        print("gbx,gby:{},{}".format(gbx,gby))
-
-        line = serial_port.readline()
-        if line == b'SERIAL_IN_START\r\n':
-            # ===== STEP 1: TAKE ALL INPUT =====
-            tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM = serial_port_in(serial_port)
-
-            # ===== STEP 2: MAIN CONTROL LOOP =====
-            pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM)
-
-            # ===== STEP 3: FEED ALL OUTPUT =====
-            serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4)
-
-        if count == 0:
-            # first time calling (call once)
-            pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4 = main_control(gbx, gby, gb_dist, tx, ty, tz, rx, ry, rz, LIDAR_dist, debugM)
-            serial_port_out(serial_port, pwm1, pwm2, pwm3, pwm4, dir1, dir2, dir3, dir4)
-            # count +=1
-
-        time.sleep(waitTime)