| name | nextftc |
| description | Helps write FTC robot code using the NextFTC command-based framework. Use when creating OpModes, commands, subsystems, gamepad bindings, or integrating with Pedro Pathing. |
| license | MIT |
| compatibility | Claude Code, Codex CLI, VS Code Copilot, Cursor |
| metadata | {"author":"ncssm-robotics","version":"1.1.0","category":"framework"} |
NextFTC
NextFTC is a command-based framework for FTC robotics written in Kotlin. It provides structured patterns for commands, subsystems, and gamepad bindings.
Quick Start
Dependencies (build.dependencies.gradle)
implementation 'dev.nextftc:ftc:1.0.1'
implementation 'dev.nextftc:hardware:1.0.1' // Optional: hardware wrappers
implementation 'dev.nextftc:bindings:1.0.1' // Gamepad bindings
implementation 'dev.nextftc:control:1.0.0' // PID/feedforward
implementation 'dev.nextftc.extensions:pedro:1.0.0' // Pedro Pathing
Key Imports
import dev.nextftc.ftc.NextFTCOpMode
import dev.nextftc.ftc.Gamepads
import dev.nextftc.ftc.ActiveOpMode
import dev.nextftc.ftc.components.BulkReadComponent
import dev.nextftc.core.commands.Command
import dev.nextftc.core.commands.utility.LambdaCommand
import dev.nextftc.core.commands.utility.InstantCommand
import dev.nextftc.core.commands.groups.SequentialGroup
import dev.nextftc.core.commands.groups.ParallelGroup
import dev.nextftc.core.commands.delays.Delay
import dev.nextftc.core.components.Component
import dev.nextftc.core.components.SubsystemComponent
import dev.nextftc.core.components.BindingsComponent
import dev.nextftc.core.subsystems.Subsystem
import dev.nextftc.extensions.pedro.PedroComponent
import dev.nextftc.extensions.pedro.PedroDriverControlled
import dev.nextftc.extensions.pedro.FollowPath
Basic TeleOp
@TeleOp(name = "My TeleOp")
class MyTeleOp : NextFTCOpMode() {
init {
addComponents(
BulkReadComponent,
BindingsComponent,
PedroComponent(Constants::createFollower)
)
}
override fun onStartButtonPressed() {
PedroDriverControlled(
Gamepads.gamepad1.leftStickY,
Gamepads.gamepad1.leftStickX,
Gamepads.gamepad1.rightStickX,
false
)()
Gamepads.gamepad2.a whenBecomesTrue LiftCommand()
}
}
Basic Autonomous
@Autonomous(name = "My Auto")
class MyAuto : NextFTCOpMode() {
init {
addComponents(
BulkReadComponent,
PedroComponent(Constants::createFollower)
)
}
override fun onStartButtonPressed() {
SequentialGroup(
FollowPath(path1, holdEnd = true),
Delay(0.5.seconds),
FollowPath(path2, holdEnd = true)
)()
}
}
Core Concepts
| Concept | Description |
|---|
| Commands | Units of code that execute (start, update, stop, isDone) |
| Subsystems | Collections of hardware + commands for a mechanism |
| Components | Modular lifecycle hooks added to OpModes |
| Command Groups | Sequential or parallel execution of commands |
Components
Components are modular lifecycle hooks with pre/post methods for all OpMode phases:
| OpMode Phase | Component Methods |
|---|
onInit() | preInit() / postInit() |
onWaitForStart() | preWaitForStart() / postWaitForStart() |
onStartButtonPressed() | preStartButtonPressed() / postStartButtonPressed() |
onUpdate() | preUpdate() / postUpdate() |
onStop() | preStop() / postStop() |
Add to OpModes via addComponents():
| Component | Purpose |
|---|
BulkReadComponent | Efficient hardware reads |
BindingsComponent | Enable gamepad bindings |
SubsystemComponent(...) | Register subsystems |
PedroComponent(factory) | Pedro Pathing integration |
See COMPONENTS.md for full lifecycle details.
Command Scheduling
myCommand()
CommandManager.scheduleCommand(cmd)
SequentialGroup(cmd1, cmd2, cmd3)()
ParallelGroup(cmd1, cmd2)()
Delay(0.5.seconds)
Anti-Patterns
Don't: Forget to schedule commands
SequentialGroup(path1, path2)
SequentialGroup(path1, path2)()
Don't: Block in command update()
override fun update() {
Thread.sleep(100)
while (!sensorReady) { }
}
override fun update() {
}
override fun isDone() = sensorReady
Don't: Forget required components
class MyTeleOp : NextFTCOpMode() {
override fun onStartButtonPressed() {
Gamepads.gamepad1.a whenBecomesTrue cmd
}
}
class MyTeleOp : NextFTCOpMode() {
init {
addComponents(BindingsComponent)
}
}
Don't: Access hardware before init
class MyOp : NextFTCOpMode() {
val motor = hardwareMap.get(...)
}
class MyOp : NextFTCOpMode() {
lateinit var motor: DcMotor
override fun onInit() {
motor = hardwareMap.get(...)
}
}
Reference Documentation