Subsystems

This repository is built around a small set of reusable subsystem patterns.

Choose the closest existing pattern before creating a new subsystem type.

Flywheel

Use Flywheel for mechanisms controlled primarily by velocity or voltage.

Examples in this repo include:

  • shooter flywheel

  • indexers

  • conveyor

  • intake roller

This pattern works well when the mechanism behaves like a spinning wheel or roller and does not need independent position control.

PositionJoint

Use PositionJoint for mechanisms that need position control, profile constraints, or bounded motion.

Examples in this repo include:

  • hood

  • intake rack

This pattern is intended for pivots, elevators, racks, and similar mechanisms where position is the main control target.

Vision

Use Vision for pose-estimation and target-observation pipelines.

The vision subsystem in this repo is designed to:

  • collect observations from one or more vision sources

  • filter and validate those observations

  • forward accepted measurements into drivetrain pose estimation

The hardware abstraction is handled through VisionIO implementations for Limelight, PhotonVision, QuestNav, and simulation combinations.

Digital sensors and piece detection

Not every subsystem is a motorized mechanism.

This repo also includes:

  • DigitalSensor for binary hardware inputs

  • PieceDetection for target or game-piece style perception pipelines

These follow the same IO-driven architecture as the motor subsystems.

Drive subsystem

The drivetrain is more specialized than the reusable mechanism patterns above.

In this repo, the drivetrain is implemented separately as CommandSwerveDrivetrain because it owns:

  • odometry

  • vision measurement integration

  • PathPlanner and Choreo interactions

  • simulation pose synchronization

  • drive-specific telemetry

Treat drivetrain changes as higher-risk than changes to isolated mechanism subsystems.

How to choose a pattern

Ask these questions first:

  • Is the mechanism fundamentally velocity-controlled? Use Flywheel.

  • Is the mechanism fundamentally position-controlled? Use PositionJoint.

  • Is it just reporting state from hardware? Use a sensor-style subsystem.

  • Does it affect global robot motion or pose estimation? It may need a specialized subsystem.

Guidelines

  • Reuse Flywheel and PositionJoint aggressively.

  • Keep hardware details in the IO layer, not in the subsystem API.

  • Add a new subsystem pattern only if the control model is genuinely different.

  • Favor multiple small subsystems over one oversized subsystem with mixed responsibilities.