Subsystems

Subsystems

Cách tổ chức subsystem để chia robot thành các khối chức năng độc lập.

Cách tổ chức subsystem để chia robot thành các khối chức năng độc lập.

Level

Advanced

Source

Source

Author

Author

FTC Lib

FTC Lib

Translator

Translator

FTC26749 aDudu

FTC26749 aDudu

Date Published

Date Published

Jan 18, 2026

Jan 18, 2026

import: com.arcrobotics.ftclib.command.Subsystem
import: com.arcrobotics.ftclib.command.Subsystem

Subsystemđơ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.

import com.arcrobotics.ftclib.command.SubsystemBase;
public class ExampleSubsystem extends SubsystemBase {
  /**
   * Creates a new ExampleSubsystem.
   */
  public ExampleSubsystem() {
  }
  @Override
  public void periodic() {
    // This method will be called once per scheduler run
  }
}
import com.arcrobotics.ftclib.command.SubsystemBase;
public class ExampleSubsystem extends SubsystemBase {
  /**
   * Creates a new ExampleSubsystem.
   */
  public ExampleSubsystem() {
  }
  @Override
  public void periodic() {
    // This method will be called once per scheduler run
  }
}

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ại

  • Nế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 classimplement 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:

package org.firstinspires.ftc.robotcontroller.external.samples.CommandSample;
import com.arcrobotics.ftclib2.command.SubsystemBase;
import com.qualcomm.robotcore.hardware.HardwareMap;
import com.qualcomm.robotcore.hardware.Servo;
/**
 * A gripper mechanism that grabs a stone from the quarry.
 * Centered around the Skystone game for FTC that was done in the 2019
 * to 2020 season.
 */
public class GripperSubsystem extends SubsystemBase {
    private final Servo mechRotation;
    public GripperSubsystem(final HardwareMap hMap, final String name) {
        mechRotation = hMap.get(Servo.class, name);
    }
    /**
     * Grabs a stone.
     */
    public void grab() {
        mechRotation.setPosition(0.76);
    }
    /**
     * Releases a stone.
     */
    public void release() {
        mechRotation.setPosition(0);
    }
}
package org.firstinspires.ftc.robotcontroller.external.samples.CommandSample;
import com.arcrobotics.ftclib2.command.SubsystemBase;
import com.qualcomm.robotcore.hardware.HardwareMap;
import com.qualcomm.robotcore.hardware.Servo;
/**
 * A gripper mechanism that grabs a stone from the quarry.
 * Centered around the Skystone game for FTC that was done in the 2019
 * to 2020 season.
 */
public class GripperSubsystem extends SubsystemBase {
    private final Servo mechRotation;
    public GripperSubsystem(final HardwareMap hMap, final String name) {
        mechRotation = hMap.get(Servo.class, name);
    }
    /**
     * Grabs a stone.
     */
    public void grab() {
        mechRotation.setPosition(0.76);
    }
    /**
     * Releases a stone.
     */
    public void release() {
        mechRotation.setPosition(0);
    }
}

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:

Cách 1 – Qua CommandScheduler

CommandScheduler.getInstance()
    .setDefaultCommand(exampleSubsystem, exampleCommand);
CommandScheduler.getInstance()
    .setDefaultCommand(exampleSubsystem, exampleCommand);

Cách 2 – Qua Subsystem (đơn giản hơn)

exampleSubsystem.setDefaultCommand(exampleCommand);
exampleSubsystem.setDefaultCommand(exampleCommand);

ADUDU

A proud team of passionate Robotics Enthusiasts competing in nation-wide Technology competitions in Vietnam, the FIRST Tech Challenge and the FIRST Robotics Competition.

Copyright ©

, all rights reserved

Made by aDudu's Programming Department

made by aDudu

made by aDudu

Subsystems