diff --git a/.clang-tidy b/.clang-tidy
index 0114c5cb..3e74d3ba 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -94,12 +94,12 @@ modernize-replace-random-shuffle,
 modernize-return-braced-init-list,
 modernize-shrink-to-fit,
 modernize-unary-static-assert,
-modernize-use-auto,
+# modernize-use-auto,
 modernize-use-bool-literals,
 modernize-use-emplace,
 modernize-use-equals-default,
 modernize-use-equals-delete,
-modernize-use-nodiscard,
+# modernize-use-nodiscard
 modernize-use-noexcept,
 modernize-use-nullptr,
 modernize-use-override,
diff --git a/.gitignore b/.gitignore
index d007824c..c022d076 100644
--- a/.gitignore
+++ b/.gitignore
@@ -62,3 +62,5 @@ MvSdkLog
 id_rsa
 id_rsa.pub
 
+# Recording files
+record
\ No newline at end of file
diff --git a/.gitmodules b/.gitmodules
index 91dd969f..4d13bb24 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -11,6 +11,9 @@
 [submodule "rmcs_ws/src/fast_tf"]
 	path = rmcs_ws/src/fast_tf
 	url = https://github.com/qzhhhi/FastTF.git
+[submodule "rmcs_ws/src/rmcs_referee"]
+	path = rmcs_ws/src/rmcs_referee
+	url = https://github.com/Alliance-Algorithm/rmcs_referee
 [submodule "rmcs_ws/src/auto_aim"]
 	path = rmcs_ws/src/auto_aim
 	url = git@github.com:Alliance-Algorithm/auto_aim.git
diff --git a/rmcs_ws/src/rmcs_bringup/config/omni.yaml b/rmcs_ws/src/rmcs_bringup/config/omni.yaml
index 1c832763..8cf51dde 100644
--- a/rmcs_ws/src/rmcs_bringup/config/omni.yaml
+++ b/rmcs_ws/src/rmcs_bringup/config/omni.yaml
@@ -3,7 +3,7 @@ rmcs_executor:
     update_rate: 1000.0
     components:
       - rmcs_core::hardware::cboard::Status -> cboard_status
-      - rmcs_core::hardware::referee::Status -> referee_status
+      - rmcs_referee::Status -> referee_status
 
       - rmcs_core::controller::gimbal::GimbalController -> gimbal_controller
       - rmcs_core::controller::pid::ErrorPidController -> yaw_angle_pid_controller
@@ -26,7 +26,12 @@ rmcs_executor:
       - rmcs_core::broadcaster::TfBroadcaster -> tf_broadcaster
       - rmcs_core::broadcaster::ValueBroadcaster -> value_broadcaster
 
+      - rmcs_referee::command::Interaction -> referee_interaction
+      - rmcs_referee::command::interaction::Ui -> referee_ui
+      - rmcs_referee::app::ui::Infantry -> referee_ui_infantry
+
       - rmcs_core::hardware::cboard::Command -> cboard_command
+      - rmcs_referee::Command -> referee_command
 
       # - rmcs_core::hardware::cboard::GyroCalibrator -> gyro_calibrator
 
@@ -39,8 +44,8 @@ rmcs_executor:
 cboard_status:
   ros__parameters:
     path: /dev/ttyACM0
-    yaw_motor_zero_point: 5409
-    pitch_motor_zero_point: 391
+    yaw_motor_zero_point: 3088
+    pitch_motor_zero_point: 381
     imu_gx_bias: -0.001279
     imu_gy_bias: -0.001447
     imu_gz_bias: +0.002188
diff --git a/rmcs_ws/src/rmcs_core/src/hardware/referee/package/graphic.hpp b/rmcs_ws/src/rmcs_core/src/hardware/referee/package/graphic.hpp
deleted file mode 100644
index 33cee3f6..00000000
--- a/rmcs_ws/src/rmcs_core/src/hardware/referee/package/graphic.hpp
+++ /dev/null
@@ -1,205 +0,0 @@
-#pragma once
-
-#include "protocol.hpp"
-#include "send.hpp"
-
-#include <cstring>
-
-namespace rmcs_core::hardware::referee::ui {
-
-using namespace referee::package;
-using namespace referee::package::send;
-
-using Description = interact::ui::Description;
-
-using DeletePackage = Package<interact::Data<interact::ui::DeleteLayer>>;
-using DrawPackage1  = Package<interact::Data<interact::ui::Description>>;
-using DrawPackage2  = Package<interact::Data<interact::ui::Description2>>;
-using DrawPackage5  = Package<interact::Data<interact::ui::Description5>>;
-using DrawPackage7  = Package<interact::Data<interact::ui::Description7>>;
-using StringPackage = Package<interact::Data<interact::ui::String>>;
-
-enum class GraphicType { LINE, RECTANGLE, CIRCLE, ELLIPSE, ARC, FLOAT, INTEGER, STRING };
-enum class ColorType { SELF, YELLOW, GREEN, ORANGE, PURPLE_RED, PINK, BLUE, BLACK, WHITE };
-enum class OperationType { EMPTY, ADD, MODIFY, DELETE };
-
-class Graphic {
-public:
-    Graphic() = default;
-
-    virtual Description generate_description() = 0;
-
-    Description generate_basic_description() {
-        auto description = Description();
-
-        description.operate = static_cast<uint8_t>(this->operation);
-        description.color   = static_cast<uint8_t>(color);
-        description.name[0] = this->name[0];
-        description.name[1] = this->name[1];
-        description.name[2] = this->name[2];
-        description.layer   = this->layer;
-        description.width   = this->width;
-        (void)description.graphic;
-        (void)description.details_a;
-        (void)description.details_b;
-        (void)description.details_c;
-        (void)description.details_d;
-        (void)description.details_e;
-
-        return description;
-    }
-
-    void set_name(const char str[3]) {
-        std::strncpy(reinterpret_cast<char*>(name), str, sizeof(name));
-    }
-
-public:
-    OperationType operation;
-    ColorType color;
-    uint8_t name[3];
-    uint8_t layer;
-    uint16_t width;
-    uint16_t x;
-    uint16_t y;
-};
-
-class Line : public Graphic {
-public:
-    Description generate_description() override {
-        auto description = generate_basic_description();
-
-        description.graphic   = static_cast<uint8_t>(GraphicType::LINE);
-        description.details_d = this->end_x;
-        description.details_e = this->end_y;
-
-        return description;
-    }
-
-public:
-    uint16_t end_x;
-    uint16_t end_y;
-};
-
-class Rectangle : public Graphic {
-public:
-    Description generate_description() override {
-        auto description = generate_basic_description();
-
-        description.graphic   = static_cast<uint8_t>(GraphicType::RECTANGLE);
-        description.details_d = this->other_x;
-        description.details_e = this->other_y;
-
-        return description;
-    }
-
-public:
-    uint16_t other_x;
-    uint16_t other_y;
-};
-
-class Circle : public Graphic {
-public:
-    Description generate_description() override {
-        auto description = generate_basic_description();
-
-        description.graphic   = static_cast<uint8_t>(GraphicType::CIRCLE);
-        description.details_c = radius;
-
-        return description;
-    }
-
-public:
-    uint16_t radius;
-};
-
-class Ellipse : public Graphic {
-public:
-    Description generate_description() override {
-        auto description = generate_basic_description();
-
-        description.graphic   = static_cast<uint8_t>(GraphicType::ELLIPSE);
-        description.details_d = radius_x;
-        description.details_e = radius_y;
-
-        return description;
-    }
-
-public:
-    uint16_t radius_x;
-    uint16_t radius_y;
-};
-
-class Arc : public Graphic {
-public:
-    Description generate_description() override {
-        auto description = generate_basic_description();
-
-        description.graphic   = static_cast<uint8_t>(GraphicType::ARC);
-        description.details_d = radius_x;
-        description.details_e = radius_y;
-
-        return description;
-    }
-
-public:
-    uint16_t angle_start;
-    uint16_t angle_end;
-    uint16_t radius_x;
-    uint16_t radius_y;
-};
-
-class FLoat : public Graphic {
-public:
-    Description generate_description() override {
-        auto description = generate_basic_description();
-
-        description.graphic   = static_cast<uint8_t>(GraphicType::FLOAT);
-        description.details_a = font_size;
-        description.details_c = va_dot_lue >> 22;
-        description.details_d = va_dot_lue >> 11;
-        description.details_e = va_dot_lue >> 00;
-
-        return description;
-    }
-
-public:
-    uint16_t font_size;
-    uint32_t va_dot_lue;
-};
-
-class Integer : public Graphic {
-public:
-    Description generate_description() override {
-        auto description = generate_basic_description();
-
-        description.graphic   = static_cast<uint8_t>(GraphicType::INTEGER);
-        description.details_a = font_size;
-        description.details_c = value >> 22;
-        description.details_d = value >> 11;
-        description.details_e = value >> 00;
-
-        return description;
-    }
-
-public:
-    uint16_t font_size;
-    uint32_t value;
-};
-
-class String : public Graphic {
-public:
-    Description generate_description() override {
-        auto description = generate_basic_description();
-
-        description.graphic   = static_cast<uint8_t>(GraphicType::STRING);
-        description.details_a = font_size;
-        description.details_b = length;
-
-        return description;
-    }
-
-public:
-    uint16_t font_size;
-    uint16_t length;
-};
-} // namespace rmcs_core::hardware::referee::ui
\ No newline at end of file
diff --git a/rmcs_ws/src/rmcs_core/src/hardware/referee/package/protocol.hpp b/rmcs_ws/src/rmcs_core/src/hardware/referee/package/protocol.hpp
deleted file mode 100644
index d1338a0c..00000000
--- a/rmcs_ws/src/rmcs_core/src/hardware/referee/package/protocol.hpp
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma once
-
-#include <cstdint>
-
-namespace rmcs_core::hardware::referee::package {
-
-struct __attribute__((packed)) FrameHeader {
-    const uint8_t start = 0xA5;
-    uint16_t length;
-    uint8_t sequence;
-    uint8_t crc8;
-};
-
-template <typename SubPackageT>
-struct __attribute__((packed)) Package {
-    FrameHeader header;
-    uint16_t command;
-    SubPackageT data;
-    uint16_t crc16;
-};
-} // namespace rmcs_core::hardware::referee::package
diff --git a/rmcs_ws/src/rmcs_core/src/hardware/referee/package/receive.hpp b/rmcs_ws/src/rmcs_core/src/hardware/referee/package/receive.hpp
deleted file mode 100644
index 25293ac8..00000000
--- a/rmcs_ws/src/rmcs_core/src/hardware/referee/package/receive.hpp
+++ /dev/null
@@ -1,113 +0,0 @@
-#pragma once
-
-#include <cstddef>
-#include <cstdint>
-
-namespace rmcs_core::hardware::referee::package::receive {
-
-constexpr size_t frame_data_max_length = 1024;
-
-struct __attribute__((packed)) FrameHeader {
-    uint8_t start;
-    uint16_t data_length;
-    uint8_t sequence;
-    uint8_t crc8;
-};
-
-struct __attribute__((packed)) FrameBody {
-    uint16_t command_id;
-    uint8_t data[frame_data_max_length];
-};
-
-struct __attribute__((packed)) Frame {
-    FrameHeader header;
-    FrameBody body;
-};
-
-struct __attribute__((packed)) GameStatus {
-    uint8_t game_type  : 4;
-    uint8_t game_stage : 4;
-    uint16_t stage_remain_time;
-    uint64_t sync_timestamp;
-};
-
-struct __attribute__((packed)) GameRobotHp {
-    uint16_t red_1;
-    uint16_t red_2;
-    uint16_t red_3;
-    uint16_t red_4;
-    uint16_t red_5;
-    uint16_t red_7;
-    uint16_t red_outpost;
-    uint16_t red_base;
-    uint16_t blue_1;
-    uint16_t blue_2;
-    uint16_t blue_3;
-    uint16_t blue_4;
-    uint16_t blue_5;
-    uint16_t blue_7;
-    uint16_t blue_outpost;
-    uint16_t blue_base;
-};
-
-struct __attribute__((packed)) RobotStatus {
-    uint8_t robot_id;
-    uint8_t robot_level;
-    uint16_t current_hp;
-    uint16_t maximum_hp;
-    uint16_t shooter_barrel_cooling_value;
-    uint16_t shooter_barrel_heat_limit;
-    uint16_t chassis_power_limit;
-    uint8_t power_management_gimbal_output  : 1;
-    uint8_t power_management_chassis_output : 1;
-    uint8_t power_management_shooter_output : 1;
-};
-
-struct __attribute__((packed)) PowerHeatData {
-    uint16_t chassis_voltage;
-    uint16_t chassis_current;
-    float chassis_power;
-    uint16_t buffer_energy;
-    uint16_t shooter_17mm_1_barrel_heat;
-    uint16_t shooter_17mm_2_barrel_heat;
-    uint16_t shooter_42mm_barrel_heat;
-};
-
-struct __attribute__((packed)) RobotPosition {
-    float x;
-    float y;
-    float angle;
-};
-
-struct __attribute__((packed)) HurtData {
-    uint8_t armor_id : 4;
-    uint8_t reason   : 4;
-};
-
-struct __attribute__((packed)) ShootData {
-    uint8_t bullet_type;
-    uint8_t shooter_number;
-    uint8_t launching_frequency;
-    float initial_speed;
-};
-
-struct __attribute__((packed)) BulletAllowance {
-    uint16_t bullet_allowance_17mm;
-    uint16_t bullet_allowance_42mm;
-    uint16_t remaining_gold_coin;
-};
-
-struct __attribute__((packed)) GameRobotPosition {
-    float hero_x;
-    float hero_y;
-    float engineer_x;
-    float engineer_y;
-    float infantry_3_x;
-    float infantry_3_y;
-    float infantry_4_x;
-    float infantry_4_y;
-    float infantry_5_x;
-    float infantry_5_y;
-};
-
-} // namespace rmcs_core::hardware::referee::package::receive
\ No newline at end of file
diff --git a/rmcs_ws/src/rmcs_core/src/hardware/referee/package/send.hpp b/rmcs_ws/src/rmcs_core/src/hardware/referee/package/send.hpp
deleted file mode 100644
index 1633aa7f..00000000
--- a/rmcs_ws/src/rmcs_core/src/hardware/referee/package/send.hpp
+++ /dev/null
@@ -1,101 +0,0 @@
-#pragma once
-
-#include <cstdint>
-
-namespace rmcs_core::hardware::referee::package::send {
-
-/// @brief 0x0308
-/// @note robot -> player client
-/// @note map display | 3hz
-/// @note length 34
-namespace robot_map {}
-
-/// @brief 0x0307
-/// @note sentry -> player client
-/// @note map display | 1hz
-/// @note length 103
-namespace sentry_map {}
-
-/// @brief 0x0305
-/// @note lidar -> server -> player client
-/// @note map display | 10hz
-/// @note length 10
-namespace lidar_map {}
-
-/// @brief 0x0301
-/// @note robot -> robot | ui
-/// @note interact with robot | 30hz
-namespace interact {
-
-template <typename SubPackageT>
-struct __attribute__((packed)) Data {
-    uint16_t command;
-    uint16_t sender;
-    uint16_t receiver;
-    SubPackageT data;
-};
-
-/// @brief chat with other robot
-/// @note data length <= 112
-/// @note id 0x0200 ~ 0x02FF
-namespace chat {}
-
-/// @brief data for sentry
-/// @note data length equals 4
-/// @note id 0x0120
-namespace sentry {}
-
-/// @brief data for lidar
-/// @note data length equals 1
-/// @note id 0x0121
-namespace lidar {}
-
-/// @brief data for ui
-/// @note id 0x0100 ~ 0x0104 and 0x0110
-namespace ui {
-// 0x0100
-struct __attribute__((packed)) DeleteLayer {
-    uint8_t delete_type;
-    uint8_t layer;
-};
-
-// 0x0101
-struct __attribute__((packed)) Description {
-    uint8_t name[3];
-    uint8_t operate    : 3;
-    uint8_t graphic    : 3;
-    uint8_t layer      : 4;
-    uint8_t color      : 4;
-    uint16_t details_a : 9;
-    uint16_t details_b : 9;
-    uint16_t width     : 10;
-    uint16_t start_x   : 11;
-    uint16_t start_y   : 11;
-    uint16_t details_c : 10;
-    uint16_t details_d : 11;
-    uint16_t details_e : 11;
-};
-
-// 0x0102
-struct __attribute__((packed)) Description2 {
-    Description description[2];
-};
-
-// 0x0103
-struct __attribute__((packed)) Description5 {
-    Description description[5];
-};
-
-// 0x0104
-struct __attribute__((packed)) Description7 {
-    Description description[7];
-};
-
-// 0x0110
-struct __attribute__((packed)) String {
-    Description description;
-    uint8_t data[30];
-};
-} // namespace ui
-} // namespace interact
-} // namespace rmcs_core::hardware::referee::package::send
diff --git a/rmcs_ws/src/rmcs_core/src/hardware/referee/status.cpp b/rmcs_ws/src/rmcs_core/src/hardware/referee/status.cpp
deleted file mode 100644
index 1f0eae57..00000000
--- a/rmcs_ws/src/rmcs_core/src/hardware/referee/status.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-#include <rclcpp/node.hpp>
-
-#include "hardware/referee/package/receive.hpp"
-#include <rmcs_executor/component.hpp>
-#include <serial_util/crc/dji_crc.hpp>
-#include <serial_util/package_receive.hpp>
-
-namespace rmcs_core::hardware::referee {
-
-class Status
-    : public rmcs_executor::Component
-    , public rclcpp::Node {
-public:
-    Status()
-        : Node{get_component_name(), rclcpp::NodeOptions{}.automatically_declare_parameters_from_overrides(true)}
-        , logger_(get_logger()) {
-
-        try {
-            register_output(
-                "/referee/serial", serial_, get_parameter("path").as_string(), 115200,
-                serial::Timeout::simpleTimeout(0));
-        } catch (serial::IOException& ex) {
-            RCLCPP_ERROR(logger_, "Unable to open serial port: %s", ex.what());
-        }
-
-        register_output("/referee/robot/shooter/cooling", robot_shooter_cooling_, 0);
-        register_output("/referee/robot/shooter/heat_limit", robot_shooter_heat_limit_, 0);
-        register_output("/referee/robot/chassis_power", robot_chassis_power_, 0.0);
-    }
-
-    void update() override {
-        if (!serial_.active())
-            return;
-
-        if (cache_size_ >= sizeof(frame_.header)) {
-            auto frame_size = sizeof(frame_.header) + sizeof(frame_.body.command_id)
-                            + frame_.header.data_length + sizeof(uint16_t);
-            cache_size_ += serial_->read(
-                reinterpret_cast<uint8_t*>(&frame_) + cache_size_, frame_size - cache_size_);
-
-            if (cache_size_ == frame_size) {
-                cache_size_ = 0;
-                if (serial_util::dji_crc::verify_crc16(&frame_, frame_size)) {
-                    process_frame();
-                } else {
-                    RCLCPP_WARN(logger_, "Body crc16 invalid");
-                }
-            }
-        } else {
-            auto result = serial_util::receive_package(
-                *serial_, frame_.header, cache_size_, static_cast<uint8_t>(0xa5),
-                [](const package::receive::FrameHeader& header) {
-                    return serial_util::dji_crc::verify_crc8(header);
-                });
-            if (result == serial_util::ReceiveResult::HEADER_INVALID) {
-                RCLCPP_WARN(logger_, "Header start invalid");
-            } else if (result == serial_util::ReceiveResult::VERIFY_INVALID) {
-                RCLCPP_WARN(logger_, "Header crc8 invalid");
-            }
-        }
-    }
-
-private:
-    void process_frame() {
-        auto command_id = frame_.body.command_id;
-        if (command_id == 0x0001)
-            update_game_status();
-        if (command_id == 0x0003)
-            update_game_robot_hp();
-        else if (command_id == 0x0201)
-            update_robot_status();
-        else if (command_id == 0x0202)
-            update_power_heat_data();
-        else if (command_id == 0x0203)
-            update_robot_position();
-        else if (command_id == 0x0206)
-            update_hurt_data();
-        else if (command_id == 0x0207)
-            update_shoot_data();
-        else if (command_id == 0x0208)
-            update_bullet_allowance();
-        else if (command_id == 0x020B)
-            update_game_robot_position();
-    }
-
-    void update_game_status() {}
-
-    void update_game_robot_hp() {}
-
-    void update_robot_status() {
-        auto& data = reinterpret_cast<package::receive::RobotStatus&>(frame_.body.data);
-
-        *robot_shooter_cooling_    = data.shooter_barrel_cooling_value;
-        *robot_shooter_heat_limit_ = static_cast<int64_t>(1000) * data.shooter_barrel_heat_limit;
-    }
-
-    void update_power_heat_data() {
-        auto& data = reinterpret_cast<package::receive::PowerHeatData&>(frame_.body.data);
-        *robot_chassis_power_ = data.chassis_power;
-    }
-
-    void update_robot_position() {}
-
-    void update_hurt_data() {}
-
-    void update_shoot_data() {}
-
-    void update_bullet_allowance() {}
-
-    void update_game_robot_position() {}
-
-    rclcpp::Logger logger_;
-
-    OutputInterface<serial::Serial> serial_;
-    package::receive::Frame frame_;
-    size_t cache_size_ = 0;
-
-    OutputInterface<int64_t> robot_shooter_cooling_, robot_shooter_heat_limit_;
-    OutputInterface<double> robot_chassis_power_;
-};
-
-} // namespace rmcs_core::hardware::referee
-
-#include <pluginlib/class_list_macros.hpp>
-
-PLUGINLIB_EXPORT_CLASS(rmcs_core::hardware::referee::Status, rmcs_executor::Component)
\ No newline at end of file
diff --git a/rmcs_ws/src/rmcs_core/src/hardware/referee/ui.hpp b/rmcs_ws/src/rmcs_core/src/hardware/referee/ui.hpp
deleted file mode 100644
index 78e890c4..00000000
--- a/rmcs_ws/src/rmcs_core/src/hardware/referee/ui.hpp
+++ /dev/null
@@ -1,156 +0,0 @@
-#pragma once
-
-#include <eigen3/Eigen/Core>
-#include <rclcpp/logger.hpp>
-#include <rclcpp/node.hpp>
-
-#include <rmcs_executor/component.hpp>
-#include <serial_util/crc/dji_crc.hpp>
-#include <serial_util/package_receive.hpp>
-
-#include "package/graphic.hpp"
-
-namespace rmcs_core::hardware::referee {
-
-class UI
-    : public rmcs_executor::Component
-    , public rclcpp::Node {
-
-public:
-    UI()
-        : Node{get_component_name(), rclcpp::NodeOptions{}.automatically_declare_parameters_from_overrides(true)}
-        , logger_(get_logger()) {
-
-        register_input("/gimbal/auto_aim/origin_coordinate", coordinate_auto_aim_, false);
-
-        try {
-            register_output(
-                "/referee/serial", serial_, get_parameter("path").as_string(), 115200,
-                serial::Timeout::simpleTimeout(0));
-        } catch (serial::IOException& ex) {
-            RCLCPP_ERROR(logger_, "Unable to open serial port: %s", ex.what());
-        }
-    };
-
-    void update() override {}
-
-private:
-    void init_ui() {}
-
-    void draw_string(const ui::Description& description, const std::string& string) {
-        auto package                  = ui::StringPackage();
-        package.header.length         = 45;
-        package.command               = 0x0301;
-        package.data.command          = 0x0110;
-        package.data.sender           = sender_;
-        package.data.receiver         = receiver_;
-        package.data.data.description = description;
-        string.copy(reinterpret_cast<char*>(package.data.data.data), string.length());
-
-        this->write(reinterpret_cast<uint8_t*>(&package), sizeof(package));
-    }
-
-    template <typename T, typename... Args>
-    requires(std::is_same_v<T, uint8_t>) void delete_layer(T index, Args... args) {
-        assert(index > -1 && index < 10);
-        if (sizeof...(Args) != 0) {
-            delete_layer(args...);
-        }
-
-        auto package                  = ui::DeletePackage();
-        package.header.length         = 2;
-        package.command               = 0x0301;
-        package.data.command          = 0x0100;
-        package.data.sender           = sender_;
-        package.data.receiver         = receiver_;
-        package.data.data.delete_type = 1;
-        package.data.data.layer       = index;
-
-        this->write(reinterpret_cast<uint8_t*>(&package), sizeof(package));
-    }
-    void delete_layer() {
-        auto package                  = ui::DeletePackage();
-        package.header.length         = 2;
-        package.command               = 0x0301;
-        package.data.command          = 0x0100;
-        package.data.sender           = sender_;
-        package.data.receiver         = receiver_;
-        package.data.data.delete_type = 2;
-
-        this->write(reinterpret_cast<uint8_t*>(&package), sizeof(package));
-    }
-
-    void apply_description(const ui::Description& description) {
-        auto package          = ui::DrawPackage1();
-        package.header.length = 15;
-        package.command       = 0x0301;
-        package.data.command  = 0x0101;
-        package.data.sender   = sender_;
-        package.data.receiver = receiver_;
-        package.data.data     = description;
-
-        this->write(reinterpret_cast<uint8_t*>(&package), sizeof(package));
-    }
-
-    template <size_t n>
-    requires(n == 2 || n == 5 || n == 7)
-    void apply_description(const std::array<ui::Description, n>& description) {
-        if constexpr (n == 2) {
-            auto package          = ui::DrawPackage2();
-            package.header.length = 30;
-            package.command       = 0x0301;
-            package.data.command  = 0x0102;
-            package.data.sender   = sender_;
-            package.data.receiver = receiver_;
-
-            for (int i = 0; i < n; i++) {
-                package.data.data.description[i] = description[i];
-            }
-            this->write(reinterpret_cast<uint8_t*>(&package), sizeof(package));
-
-        } else if constexpr (n == 5) {
-            auto package          = ui::DrawPackage5();
-            package.header.length = 75;
-            package.command       = 0x0301;
-            package.data.command  = 0x0103;
-            package.data.sender   = sender_;
-            package.data.receiver = receiver_;
-
-            for (int i = 0; i < n; i++) {
-                package.data.data.description[i] = description[i];
-            }
-
-            this->write(reinterpret_cast<uint8_t*>(&package), sizeof(package));
-
-        } else if constexpr (n == 7) {
-            auto package          = ui::DrawPackage7();
-            package.header.length = 105;
-            package.command       = 0x0301;
-            package.data.command  = 0x0104;
-            package.data.sender   = sender_;
-            package.data.receiver = receiver_;
-
-            for (int i = 0; i < n; i++) {
-                package.data.data.description[i] = description[i];
-            }
-
-            this->write(reinterpret_cast<uint8_t*>(&package), sizeof(package));
-        }
-    }
-
-    size_t write(const uint8_t* data, size_t size) { return serial_->write(data, size); }
-
-private:
-    OutputInterface<serial::Serial> serial_;
-    rclcpp::Logger logger_;
-
-    InputInterface<Eigen::Vector2d> coordinate_auto_aim_;
-
-    uint16_t sender_;
-    uint16_t receiver_;
-};
-} // namespace rmcs_core::hardware::referee
-
-#include <pluginlib/class_list_macros.hpp>
-
-PLUGINLIB_EXPORT_CLASS(rmcs_core::hardware::referee::UI, rmcs_executor::Component)
\ No newline at end of file
diff --git a/rmcs_ws/src/rmcs_executor/include/rmcs_executor/component.hpp b/rmcs_ws/src/rmcs_executor/include/rmcs_executor/component.hpp
index 33a01d41..73487162 100644
--- a/rmcs_ws/src/rmcs_executor/include/rmcs_executor/component.hpp
+++ b/rmcs_ws/src/rmcs_executor/include/rmcs_executor/component.hpp
@@ -47,8 +47,8 @@ class Component {
         [[nodiscard]] bool ready() const { return data_pointer_ != nullptr; }
 
         void bind_directly(T& destination) {
-            if (active())
-                throw std::runtime_error("The interface has been activated");
+            if (ready())
+                throw std::runtime_error("The interface has already been bound to somewhere");
             activated     = true;
             data_pointer_ = &destination;
         }
diff --git a/rmcs_ws/src/rmcs_referee b/rmcs_ws/src/rmcs_referee
new file mode 160000
index 00000000..e540f87a
--- /dev/null
+++ b/rmcs_ws/src/rmcs_referee
@@ -0,0 +1 @@
+Subproject commit e540f87a1b3a3267ed1c8be8113299cb1aaef34e
diff --git a/rmcs_ws/src/serial_util/include/serial_util/crc/dji_crc.hpp b/rmcs_ws/src/serial_util/include/serial_util/crc/dji_crc.hpp
index 618e5676..46c5e259 100644
--- a/rmcs_ws/src/serial_util/include/serial_util/crc/dji_crc.hpp
+++ b/rmcs_ws/src/serial_util/include/serial_util/crc/dji_crc.hpp
@@ -7,7 +7,7 @@ namespace serial_util::dji_crc {
 namespace internal {
 
 template <typename TailT, typename T>
-auto& get_tail(T& data) {
+inline auto& get_tail(T& data) {
     return *reinterpret_cast<TailT*>(reinterpret_cast<size_t>(&data) + sizeof(T) - sizeof(uint8_t));
 }
 
@@ -31,8 +31,8 @@ constexpr uint8_t crc8_table[256] = {
     0x74, 0x2a, 0xc8, 0x96, 0x15, 0x4b, 0xa9, 0xf7, 0xb6, 0xe8, 0x0a, 0x54, 0xd7, 0x89, 0x6b, 0x35,
 };
 
-uint16_t CRC_INIT              = 0xffff;
-const uint16_t wCRC_Table[256] = {
+constexpr uint16_t crc16_init       = 0xffff;
+constexpr uint16_t crc16_table[256] = {
     0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3,
     0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
     0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210, 0x1399,
@@ -58,7 +58,7 @@ const uint16_t wCRC_Table[256] = {
 
 } // namespace internal
 
-uint8_t calculate_crc8(const void* data, size_t length) {
+inline uint8_t calculate_crc8(const void* data, size_t length) {
     auto* p     = reinterpret_cast<const uint8_t*>(data);
     auto result = internal::crc8_init;
     while (length--)
@@ -66,54 +66,54 @@ uint8_t calculate_crc8(const void* data, size_t length) {
     return result;
 }
 
-bool verify_crc8(const void* data, size_t length) {
+inline bool verify_crc8(const void* data, size_t length) {
     auto checksum = calculate_crc8(data, length - sizeof(uint8_t));
     return checksum == *(reinterpret_cast<const uint8_t*>(data) + length - sizeof(uint8_t));
 }
 template <typename T>
-bool verify_crc8(const T& package) {
+inline bool verify_crc8(const T& package) {
     static_assert(sizeof(T) > sizeof(uint8_t));
     return verify_crc8(&package, sizeof(package));
 }
 
-void append_crc8(void* data, size_t length) {
+inline void append_crc8(void* data, size_t length) {
     auto checksum = calculate_crc8(data, length - sizeof(uint8_t));
     *(reinterpret_cast<uint8_t*>(data) + length - sizeof(uint8_t)) = checksum;
 }
 template <typename T>
-void append_crc8(T& package) {
+inline void append_crc8(T& package) {
     static_assert(sizeof(T) > sizeof(uint8_t));
     append_crc8(&package, sizeof(package));
 }
 
-uint16_t calculate_crc16(const void* data, size_t length) {
+inline uint16_t calculate_crc16(const void* data, size_t length) {
     auto* p         = reinterpret_cast<const uint8_t*>(data);
-    uint16_t result = internal::CRC_INIT;
+    uint16_t result = internal::crc16_init;
     while (length--) {
-        result = (result >> 8) ^ internal::wCRC_Table[(result ^ (*p++)) & 0x00ff];
+        result = (result >> 8) ^ internal::crc16_table[(result ^ (*p++)) & 0x00ff];
     }
     return result;
 }
 
-bool verify_crc16(const void* data, size_t length) {
+inline bool verify_crc16(const void* data, size_t length) {
     auto checksum = calculate_crc16(data, length - sizeof(uint16_t));
     return checksum
         == *reinterpret_cast<const uint16_t*>(
                reinterpret_cast<const uint8_t*>(data) + length - sizeof(uint16_t));
 }
 template <typename T>
-bool verify_crc16(const T& package) {
+inline bool verify_crc16(const T& package) {
     static_assert(sizeof(T) > sizeof(uint16_t));
     return verify_crc16(&package, sizeof(package));
 }
 
-void append_crc16(void* data, size_t length) {
+inline void append_crc16(void* data, size_t length) {
     auto checksum = calculate_crc16(data, length - sizeof(uint16_t));
     *reinterpret_cast<uint16_t*>(reinterpret_cast<uint8_t*>(data) + length - sizeof(uint16_t)) =
         checksum;
 }
 template <typename T>
-void append_crc16(T& package) {
+inline void append_crc16(T& package) {
     static_assert(sizeof(T) > sizeof(uint16_t));
     append_crc16(&package, sizeof(package));
 }
