githubEdit

folder-treeOrganizing Configs in Constants

As your robot grows, managing configuration across multiple subsystems can become unwieldy. YAMS supports a clean pattern where you define all your configs in a centralized Constants file, then bind them to subsystems at construction time using .withSubsystem().

The Problem

Without organization, each subsystem file contains its own configuration inline:

// ArmSubsystem.java - config mixed with subsystem logic
public class ArmSubsystem extends SubsystemBase {
  private final Arm arm;
  
  public ArmSubsystem() {
    SmartMotorControllerConfig smcConfig = new SmartMotorControllerConfig(this)
        .withGearing(new MechanismGearing(GearBox.fromReductionStages(5, 4, 3)))
        .withClosedLoopController(5, 0, 0.1)
        .withFeedforward(new ArmFeedforward(0.1, 0.3, 0.5, 0.01))
        .withTrapezoidalProfile(RotationsPerSecond.of(1.0), RotationsPerSecondPerSecond.of(2.0));
    
    SmartMotorController smc = new TalonFXWrapper(new TalonFX(1), DCMotor.getKrakenX60(1), smcConfig);
    
    ArmConfig armConfig = new ArmConfig(smc)
        .withLength(Inches.of(18))
        .withMass(Pounds.of(5))
        // ... more config
    
    this.arm = new Arm(armConfig);
  }
}

This approach has drawbacks:

  • Configs are scattered across many files

  • Hard to compare settings between mechanisms

  • Tuning requires opening multiple files

  • CAN IDs, motor types, and gear ratios are buried in subsystem code

The Solution: Centralized Constants with withSubsystem()

YAMS configs can be created without a subsystem reference, then bound later using .withSubsystem(). This enables a clean separation:

Then in your subsystems, use .withSubsystem() to bind the config:

Benefits of This Pattern

Benefit
Description

Single Source of Truth

All CAN IDs, gear ratios, PID gains in one file

Easy Comparison

See all mechanism configs side-by-side

Faster Tuning

Change gains without navigating subsystem files

Cleaner Subsystems

Subsystem classes focus on behavior, not configuration

Reusable Configs

Share base configs between similar mechanisms

Complete Example: Constants File

Complete Example: Subsystem Using Constants

Organizing Multiple Config Files

For larger robots, you may want to split configs into separate files:

circle-info

Important: When using this pattern, you must call .withSubsystem() before passing the config to a SmartMotorController, and .withSmartMotorController() before passing to a Mechanism class. YAMS will throw an exception if you forget.

When NOT to Use This Pattern

This pattern adds a layer of indirection. For simple robots with 1-2 mechanisms, inline configuration may be clearer. Consider using centralized configs when:

  • You have 3+ mechanisms

  • Multiple team members tune different subsystems

  • You want to quickly compare settings across mechanisms

  • You're building a constants dashboard or config loader

Last updated