advantagekit
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAdvantageKit (2026)
AdvantageKit(2026版本)
Documentation sourced from docs.advantagekit.org. AdvantageKit is developed by Littleton Robotics (FRC 6328).
文档来源:docs.advantagekit.org。AdvantageKit由Littleton Robotics(FRC 6328)开发。
Core IO Layer Pattern
核心IO层模式
Every hardware-interacting subsystem uses three pieces:
- IO interface — declares and output methods
updateInputs() - IOInputs inner class — annotated , holds all sensor values
@AutoLog - Subsystem — depends on IO, calls in
processInputsperiodic()
The annotation generates a class — always instantiate the generated class, not the original.
@AutoLog<ClassName>AutoLoggedjava
// DriveIO.java
public interface DriveIO {
@AutoLog
class DriveIOInputs {
public double leftPositionRad = 0.0;
public double rightPositionRad = 0.0;
public double leftVelocityRadPerSec = 0.0;
public double rightVelocityRadPerSec = 0.0;
public double[] appliedVolts = new double[] {};
}
default void updateInputs(DriveIOInputs inputs) {}
default void setVoltage(double leftVolts, double rightVolts) {}
}
// Drive.java
public class Drive extends SubsystemBase {
private final DriveIO io;
private final DriveIOInputsAutoLogged inputs = new DriveIOInputsAutoLogged();
public Drive(DriveIO io) {
this.io = io;
}
@Override
public void periodic() {
io.updateInputs(inputs);
Logger.processInputs("Drive", inputs);
// All logic uses inputs.leftPositionRad, etc. — never calls hardware directly
}
public void setVoltage(double left, double right) {
io.setVoltage(left, right);
}
}每个与硬件交互的子系统包含三个部分:
- IO接口 — 声明和输出方法
updateInputs() - IOInputs内部类 — 标注,存储所有传感器数值
@AutoLog - 子系统 — 依赖IO层,在中调用
periodic()processInputs
@AutoLog<ClassName>AutoLoggedjava
// DriveIO.java
public interface DriveIO {
@AutoLog
class DriveIOInputs {
public double leftPositionRad = 0.0;
public double rightPositionRad = 0.0;
public double leftVelocityRadPerSec = 0.0;
public double rightVelocityRadPerSec = 0.0;
public double[] appliedVolts = new double[] {};
}
default void updateInputs(DriveIOInputs inputs) {}
default void setVoltage(double leftVolts, double rightVolts) {}
}
// Drive.java
public class Drive extends SubsystemBase {
private final DriveIO io;
private final DriveIOInputsAutoLogged inputs = new DriveIOInputsAutoLogged();
public Drive(DriveIO io) {
this.io = io;
}
@Override
public void periodic() {
io.updateInputs(inputs);
Logger.processInputs("Drive", inputs);
// All logic uses inputs.leftPositionRad, etc. — never calls hardware directly
}
public void setVoltage(double left, double right) {
io.setVoltage(left, right);
}
}IO Implementations
IO实现类
- — real hardware, talks to CAN devices
DriveIOSparkMax - — physics simulation
DriveIOSim - (interface default) — no-op for replay / unit tests
DriveIO
Inject the correct implementation in based on / .
RobotContainerRobot.isReal()isSimulation()- — 真实硬件实现,与CAN设备通信
DriveIOSparkMax - — 物理模拟实现
DriveIOSim - (接口默认实现)——重放/单元测试时的空实现
DriveIO
根据 / 在中注入正确的实现类。
Robot.isReal()isSimulation()RobotContainerLogger Initialization Order
Logger初始化顺序
Rule: call before instantiating any subsystem or .
Logger.start()RobotContainerjava
public class Robot extends LoggedRobot {
private RobotContainer robotContainer;
@Override
public void robotInit() {
// Configure data receivers BEFORE start()
Logger.addDataReceiver(new WPILOGWriter());
Logger.addDataReceiver(new NT4Publisher());
Logger.start(); // ← must be first
robotContainer = new RobotContainer(); // ← safe to create subsystems now
}
}规则:在实例化任何子系统或之前调用。
RobotContainerLogger.start()java
public class Robot extends LoggedRobot {
private RobotContainer robotContainer;
@Override
public void robotInit() {
// Configure data receivers BEFORE start()
Logger.addDataReceiver(new WPILOGWriter());
Logger.addDataReceiver(new NT4Publisher());
Logger.start(); // ← must be first
robotContainer = new RobotContainer(); // ← safe to create subsystems now
}
}Key Rules
核心规则
| Rule | Reason |
|---|---|
| Hardware access only inside IO implementations | Ensures all inputs are logged and replayable |
Use | FPGA timestamps are non-deterministic |
| Call logging APIs from main thread only | |
| Don't read subsystem inputs in constructors | Inputs are stale until first |
| Test replay regularly during development | Catches non-determinism early |
| 规则 | 原因 |
|---|---|
| 仅在IO实现类中访问硬件 | 确保所有输入都被记录且可重放 |
使用 | FPGA时间戳具有非确定性 |
| 仅从主线程调用日志API | |
| 不要在构造函数中读取子系统输入 | 首次 |
| 开发期间定期测试重放功能 | 尽早发现非确定性问题 |
Output Logging
输出日志记录
Log computed values for post-match analysis:
java
Logger.recordOutput("Drive/LeftVelocityError", setpoint - inputs.leftVelocityRadPerSec);
Logger.recordOutput("Odometry/Robot", poseEstimator.getEstimatedPosition());
Logger.recordOutput("Mechanism", mechanism2d);See references/output-logging.md for replay-based output generation and version control integration.
记录计算值用于赛后分析:
java
Logger.recordOutput("Drive/LeftVelocityError", setpoint - inputs.leftVelocityRadPerSec);
Logger.recordOutput("Odometry/Robot", poseEstimator.getEstimatedPosition());
Logger.recordOutput("Mechanism", mechanism2d);有关基于重放的输出生成和版本控制集成,请参阅**references/output-logging.md**。
Common Issues
常见问题
See references/common-issues.md for detailed guidance on:
- Non-deterministic data sources (NetworkTables, YAGSL, random, maps)
- Multithreading constraints
- Uninitialized inputs in constructors
有关以下内容的详细指导,请参阅**references/common-issues.md**:
- 非确定性数据源(NetworkTables、YAGSL、随机数、映射)
- 多线程限制
- 构造函数中未初始化的输入
Recording Inputs (Detail)
输入记录详情
See references/recording-inputs.md for:
- annotation and
@AutoLogclass namingAutoLogged - Units in input fields (naming convention vs. types)
Measure - IO implementation structure (real / sim / replay no-op)
- Dashboard inputs — ,
LoggedDashboardChooser, etc.LoggedNetworkNumber - Coprocessor / vision data via IO layer
有关以下内容,请参阅**references/recording-inputs.md**:
- 注解与
@AutoLog类命名规则AutoLogged - 输入字段中的单位(命名约定与类型对比)
Measure - IO实现类结构(真实/模拟/重放空实现)
- 仪表盘输入——、
LoggedDashboardChooser等LoggedNetworkNumber - 通过IO层处理协处理器/视觉数据