LiranBratt2121/frc-SOLID-robot-code
GitHub: LiranBratt2121/frc-SOLID-robot-code
一个基于行为优先级仲裁机制的 FRC 机器人 Kotlin 框架,用行为驱动取代传统按键绑定,实现更清晰的单行为状态控制和硬件解耦。
Stars: 0 | Forks: 0
# FRC 行为模型 - 2022 Rapid React
一个基于行为的 WPILib 机器人框架,使用 Kotlin 编写,用于 2022 FRC Rapid React 赛季。该机器人采用 swerve 底盘,配备抛射器、遮板、吸球器、供球器、攀爬器和视觉系统。
## 核心理念:行为系统
该机器人并非将每个按钮直接绑定到 `RobotContainer` 中的某个命令,而是通过**行为** 进行控制——即用于描述它们应当在何时激活以及激活后执行何种操作的对象。
`BehaviorManager` 在每个周期循环中运行:
1. 筛选出所有 `shouldRun()` 为 true 的行为
2. 选出 `priority()` 最高的一项
3. 调度其包含的命令,如果行为发生改变则取消上一个命令
同一时间仅有一个行为处于激活状态。并行操作(例如在行进间抛射)是通过在行为的命令内部使用 `alongWith`、`andThen` 和 `until` 来实现的。
### 行为列表
| 行为 | 优先级 | 触发条件 | 功能说明 |
|---|---|---|---|
| `ManualDriveBehavior` | 0 | 总是生效 | 操作手控制底盘 |
| `IntakeBehavior` | 5 | 吸球键按下 + 上方无球 | 部署吸球器,运行滚轮和供球器,直至球被装载 |
| `ShootBehavior` | 10 | 抛射键按下 + 持有球 | 阶段 1:自动瞄准 + 电机加速 + 调整遮板。阶段 2:供球,同时操作手进行手动驾驶 |
| `ClimbBehavior` | 20 | 攀爬模式已开启 | 使用右摇杆控制攀爬器;在行为内部对切换按钮进行边缘检测 |
## 架构
### 硬件抽象(组合优于继承)
子系统从不直接导入硬件类。它们将硬件**接口**作为构造函数参数接收:
```
io/
Motor.kt - setVoltage, setVelocityRpm, setPositionRotations, getVelocityRpm, ...
AbsoluteEncoder.kt
Gyro.kt
VisionCamera.kt
BeamBreak.kt
Solenoid.kt
io/mock/ - Simulation implementations (DCMotorSim, settable stubs)
io/talonfx/ - Real hardware (TalonFX via Phoenix 6)
```
控制逻辑(PID、Motion Magic)位于电机实现内部,而不是子系统内。子系统只需调用 `motor.setVelocityRpm(3000.0)`,具体的实现会决定是使用 Motion Magic、软件 PID 还是物理模拟。
### 子系统
```
subsystems/
drivetrain/
SwerveModule.kt - drive motor + steer motor + absolute encoder; steer PID with continuous input
DrivetrainSubsystem.kt - 4x SwerveModule + Gyro; SwerveDrivePoseEstimator; driveFieldRelative()
DriveCommands.kt - manualDriveCommand() and autoAimDriveCommand() as extension functions
shooter/ShooterSubsystem.kt - two motors; setTargetRpm(); isReady() within RPM tolerance
hood/HoodSubsystem.kt - position-controlled motor; setAngleDegrees(); isAtTarget()
intake/IntakeSubsystem.kt - roller motor + solenoid piston
feeder/FeederSubsystem.kt - motor + two beam-break sensors (bottom and top)
climber/ClimberSubsystem.kt - motor + limit switches
vision/VisionSubsystem.kt - plain class (no SubsystemBase); distance from pitch angle geometry
```
### 线路连接
```
SubsystemsModule.kt - creates all subsystems wired with mock implementations
BehaviorModule.kt - creates all behavior instances
RobotContainer.kt - wires SubsystemsModule -> BehaviorModule -> BehaviorManager
Robot.kt - calls behaviorManager.periodic() each loop
```
## 关键设计决策
**单一胜出行为**:同一时间只运行一个行为,从而强制保证机器人状态的清晰度。需要控制底盘的高优先级行为会将 `DrivetrainSubsystem` 作为依赖项,并将其包含在自身的命令中——底盘绝不会处于无人控制的状态。
**子系统中不含 PID**:子系统仅表达意图(`setVelocityRpm`),由具体实现决定如何操作。将 CTRE Motion Magic 替换为模拟 PID 无需对子系统进行任何修改。
**视觉系统不是子系统**:它不独占任何硬件,仅负责读取数据——因此没有理由继承 `SubsystemBase`。
**`ClimbMode` 状态位于 `ClimbBehavior` 中**:行为负责处理自身的激活逻辑,而非交由控制器或容器处理。
标签:2022赛季, Climber, DCMotorSim, Feeder, FRC, Intake, Kotlin, Phoenix 6, PID控制, Rapid React, Shooter, Swerve Drive, TalonFX, WPILib, 后台面板检测, 控制子系统, 机器人, 机器人框架, 模拟仿真, 状态机, 硬件抽象层, 自主瞄准, 自动化控制, 行为树模型, 视觉系统, 面向对象设计, 面向接口编程, 麦轮运动系统