

Subsystem là đơn vị tổ chức cơ bản của robot trong command-based paradigm (mô hình lập trình dựa trên command).
Một subsystem là một lớp trừu tượng (abstraction) đại diện cho một tập hợp phần cứng robot hoạt động cùng nhau như một khối thống nhất.
Subsystem đóng gói (encapsulate) phần cứng này, “che giấu” nó khỏi phần còn lại của mã robot (ví dụ: các command) và giới hạn quyền truy cập chỉ thông qua các phương thức public của subsystem.
Việc giới hạn truy cập theo cách này mang lại:
Một vị trí duy nhất để đặt các đoạn code có thể bị lặp lại ở nhiều nơi (ví dụ: scale công suất motor, kiểm tra limit switch)
Tránh việc trùng lặp logic nếu nội bộ subsystem bị lộ ra ngoài
Cho phép thay đổi cách triển khai (implementation) của subsystem mà không ảnh hưởng đến phần còn lại của code robot
→ Điều này giúp việc chỉnh sửa lớn trở nên dễ dàng hơn nhiều khi yêu cầu thiết kế thay đổi.
Subsystems và CommandScheduler
Subsystems cũng là xương sống (backbone) của hệ thống quản lý tài nguyên (resource management) của CommandScheduler.
Các command có thể khai báo tài nguyên cần dùng bằng cách chỉ ra subsystem mà chúng tương tác
Scheduler sẽ không bao giờ chạy đồng thời hai command cùng yêu cầu một subsystem
Nếu bạn cố gắng schedule một command yêu cầu subsystem đang được sử dụng:
Command đang chạy sẽ bị ngắt (interrupt) nếu nó được đánh dấu là interruptible
Hoặc command mới sẽ bị bỏ qua
Default Commands (Command mặc định)
Subsystem có thể được gán một default command – command này sẽ tự động chạy khi subsystem không bị command nào khác sử dụng.
Điều này rất hữu ích cho:
Các hành động nền liên tục (background actions), ví dụ:
Điều khiển drive
Giữ arm tại một setpoint
Chức năng tương tự cũng có thể được thực hiện trong phương thức periodic() của subsystem, phương thức này được gọi mỗi lần scheduler chạy.
Khuyến nghị:
Team nên nhất quán trong codebase:
chọn default command hoặc periodic() cho một loại hành vi, tránh trộn lẫn bừa bãi.
Trong FTCLib, subsystem được biểu diễn bằng interface Subsystem.
Creating a Subsystem (Tạo Subsystem)
Cách được khuyến nghị cho đa số người dùng là kế thừa (extend) lớp trừu tượng SubsystemBase, như trong command-based template.
Lớp này tự động gọi phương thức register() trong constructor để đăng ký subsystem với scheduler
→ điều này bắt buộc để periodic() được gọi khi scheduler chạy.
Chú giải:
register()giúp scheduler biết subsystem này tồn tạiNếu không register,
periodic()sẽ không bao giờ chạy
Advanced Usage (Sử dụng nâng cao)
Người dùng nâng cao có thể tự tạo một class và implement trực tiếp interface Subsystem nếu cần nhiều quyền kiểm soát hơn.
Creating a Simple Subsystem (Tạo Subsystem đơn giản)
Subsystems rất dễ tạo. Chúng kết hợp nhiều phần cứng để thực hiện một hoặc nhiều nhiệm vụ cụ thể, vì vậy chúng là đơn vị tổ chức cơ bản trong command system.
Ví dụ đơn giản dưới đây:
Chú giải:
Subsystem này đóng gói servo điều khiển gripper
Command bên ngoài không thao tác trực tiếp servo, chỉ gọi
grab()/release()
Setting Default Commands (Thiết lập Command mặc định)
Default command là command chạy tự động khi subsystem không bị command khác sử dụng.
Có hai cách thiết lập:

