Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions docs/code_examples/basics/autonomous/Autonomous.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// --8<-- [start:full-example]
package frc.robot.commands;

import edu.wpi.first.wpilibj2.command.SequentialCommandGroup;
import edu.wpi.first.wpilibj2.command.WaitCommand;
import frc.robot.subsystems.Drivetrain;
import frc.robot.RobotPreferences;

public class Autonomous extends SequentialCommandGroup {
public Autonomous(Drivetrain drivetrain) {
addCommands(
new DriveDistance(drivetrain, RobotPreferences.autoDriveDistance()),
new WaitCommand(RobotPreferences.autoDelay()),
new ShooterUp()
);
}
}
// --8<-- [end:full-example]
48 changes: 48 additions & 0 deletions docs/code_examples/basics/autonomous/DriveDistance.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// --8<-- [start:full-example]
package frc.robot.commands;

import edu.wpi.first.wpilibj2.command.Command;
import frc.robot.subsystems.Drivetrain;
import frc.robot.RobotPreferences;

public class DriveDistance extends Command {

private final Drivetrain drivetrain;
// --8<-- [start:distance-field]
private final double distance;
// --8<-- [end:distance-field]

public DriveDistance(Drivetrain drivetrain, double inches) {
this.drivetrain = drivetrain;
// --8<-- [start:constructor-body]
this.distance = inches;
addRequirements(drivetrain);
// --8<-- [end:constructor-body]
}

@Override
public void initialize() {
drivetrain.resetDriveEncoder();
}

// Called repeatedly when this Command is scheduled to run
@Override
public void execute() {
drivetrain.arcadeDrive(RobotPreferences.driveDistanceSpeed(), 0.0);
}

// Make this return true when this Command no longer needs to run execute()
@Override
public boolean isFinished() {
// --8<-- [start:is-finished-body]
return drivetrain.getDriveEncoderDistance() >= distance;
// --8<-- [end:is-finished-body]
}

// Called once after isFinished returns true, or if the command is interrupted
@Override
public void end(boolean interrupted) {
drivetrain.arcadeDrive(0.0, 0.0);
}
}
// --8<-- [end:full-example]
15 changes: 15 additions & 0 deletions docs/code_examples/basics/autonomous/RobotContainer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package frc.robot;

import edu.wpi.first.wpilibj2.command.Command;
import frc.robot.commands.Autonomous;
import frc.robot.subsystems.Drivetrain;

public class RobotContainer {
private final Drivetrain m_drivetrain = new Drivetrain();

// --8<-- [start:get-autonomous-command]
public Command getAutonomousCommand() {
return new Autonomous(m_drivetrain);
}
// --8<-- [end:get-autonomous-command]
}
22 changes: 22 additions & 0 deletions docs/code_examples/basics/autonomous/RobotPreferences.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package frc.robot;

import edu.wpi.first.wpilibj.Preferences;

public class RobotPreferences {

// --8<-- [start:drive-distance-speed]
public static double driveDistanceSpeed() {
return Preferences.getDouble("driveDistanceSpeed", 0.5);
}
// --8<-- [end:drive-distance-speed]

// --8<-- [start:auto-delay-and-distance]
public static double autoDelay() {
return Preferences.getDouble("autoDelay", 5.0);
}

public static double autoDriveDistance() {
return Preferences.getDouble("autoDriveDistance", 12.0);
}
// --8<-- [end:auto-delay-and-distance]
}
92 changes: 92 additions & 0 deletions docs/code_examples/ctre_swerve/RobotContainer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.

package frc.robot;

import static edu.wpi.first.units.Units.MetersPerSecond;
import static edu.wpi.first.units.Units.RadiansPerSecond;
import static edu.wpi.first.units.Units.RotationsPerSecond;

import com.ctre.phoenix6.swerve.SwerveModule.DriveRequestType;
import com.ctre.phoenix6.swerve.SwerveRequest;
import edu.wpi.first.math.geometry.Rotation2d;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.Commands;
import edu.wpi.first.wpilibj2.command.button.CommandXboxController;
import edu.wpi.first.wpilibj2.command.button.RobotModeTriggers;
import frc.robot.generated.TunerConstants;
import frc.robot.subsystems.CommandSwerveDrivetrain;

public class RobotContainer
{
// --8<-- [start:fields]
// Top speed and angular rate the joysticks will command. kSpeedAt12Volts comes from the
// generated TunerConstants and reflects your robot's actual measured free speed.
private double MaxSpeed = TunerConstants.kSpeedAt12Volts.in(MetersPerSecond);
private double MaxAngularRate = RotationsPerSecond.of(0.75).in(RadiansPerSecond);

// A SwerveRequest is a reusable, mutable "what should the drivetrain do right now" object.
// FieldCentric drives relative to the field; a 10% deadband ignores joystick noise near zero.
private final SwerveRequest.FieldCentric drive = new SwerveRequest.FieldCentric()
.withDeadband(MaxSpeed * 0.1)
.withRotationalDeadband(MaxAngularRate * 0.1)
.withDriveRequestType(DriveRequestType.OpenLoopVoltage);

// Locks the wheels into an "X" pattern so the robot resists being pushed.
private final SwerveRequest.SwerveDriveBrake brake = new SwerveRequest.SwerveDriveBrake();

// Points every wheel in a given direction without driving — useful for diagnostics.
private final SwerveRequest.PointWheelsAt point = new SwerveRequest.PointWheelsAt();

private final CommandXboxController driverXbox = new CommandXboxController(0);

// Built from the generator's TunerConstants — this one call replaces the entire
// hand-written motor/encoder/kinematics setup a non-generated swerve project needs.
private final CommandSwerveDrivetrain drivetrain = TunerConstants.createDrivetrain();
// --8<-- [end:fields]

public RobotContainer()
{
configureBindings();
}

// --8<-- [start:configure-bindings]
private void configureBindings()
{
// Default command: continuously drive field-centric off the joystick.
// X is forward, Y is left (WPILib convention) — axes are negated because
// joysticks report negative Y when pushed forward.
drivetrain.setDefaultCommand(
drivetrain.applyRequest(() ->
drive.withVelocityX(-driverXbox.getLeftY() * MaxSpeed)
.withVelocityY(-driverXbox.getLeftX() * MaxSpeed)
.withRotationalRate(-driverXbox.getRightX() * MaxAngularRate)
)
);

// Apply the drivetrain's configured neutral mode while disabled.
final SwerveRequest.Idle idle = new SwerveRequest.Idle();
RobotModeTriggers.disabled().whileTrue(
drivetrain.applyRequest(() -> idle).ignoringDisable(true)
);

// Hold A to brake (lock wheels in an X).
driverXbox.a().whileTrue(drivetrain.applyRequest(() -> brake));

// Hold B to point all wheels toward the left stick's direction.
driverXbox.b().whileTrue(drivetrain.applyRequest(() ->
point.withModuleDirection(new Rotation2d(-driverXbox.getLeftY(), -driverXbox.getLeftX()))
));

// Re-zero field-centric heading — press this when the robot's "forward" drifts from
// the field's forward, e.g. at the start of teleop.
driverXbox.leftBumper().onTrue(drivetrain.runOnce(drivetrain::seedFieldCentric));
}
// --8<-- [end:configure-bindings]

public Command getAutonomousCommand()
{
return Commands.none();
}
}
92 changes: 92 additions & 0 deletions docs/code_examples/ctre_swerve/TunerConstants.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.

// This file is a TRIMMED, illustrative excerpt of what the CTRE Tuner X Swerve Project
// Generator actually produces in src/main/java/frc/robot/generated/TunerConstants.java.
// Do not hand-type this file — run the generator (see the tutorial) and let it fill in
// the real CAN IDs, gear ratios, and CANcoder offsets measured from your own robot.
// Full reference: https://v6.docs.ctr-electronics.com/en/stable/docs/tuner/tuner-swerve/index.html
package frc.robot.generated;

import static edu.wpi.first.units.Units.Inches;
import static edu.wpi.first.units.Units.Rotations;

import com.ctre.phoenix6.CANBus;
import com.ctre.phoenix6.configs.CANcoderConfiguration;
import com.ctre.phoenix6.configs.TalonFXConfiguration;
import com.ctre.phoenix6.swerve.SwerveDrivetrainConstants;
import com.ctre.phoenix6.swerve.SwerveModuleConstants;
import com.ctre.phoenix6.swerve.SwerveModuleConstantsFactory;
import edu.wpi.first.units.measure.Angle;
import edu.wpi.first.units.measure.Distance;
import frc.robot.subsystems.CommandSwerveDrivetrain;

public class TunerConstants
{
// --8<-- [start:canbus]
// The CAN bus every drivetrain device lives on: "rio" for the roboRIO's native bus,
// or the name assigned to a CANivore.
public static final CANBus kCANBus = new CANBus("canivore", "./logs/example.hoot");
// --8<-- [end:canbus]

private static final int kPigeonId = 1;

public static final SwerveDrivetrainConstants DrivetrainConstants = new SwerveDrivetrainConstants()
.withCANBusName(kCANBus.getName())
.withPigeon2Id(kPigeonId);

// Gear ratios and wheel radius, generated from your swerve module type selection.
private static final double kDriveGearRatio = 6.746_031_75;
private static final double kSteerGearRatio = 21.428_571_43;
private static final Distance kWheelRadius = Inches.of(2);

private static final SwerveModuleConstantsFactory<TalonFXConfiguration, TalonFXConfiguration, CANcoderConfiguration> ConstantCreator =
new SwerveModuleConstantsFactory<TalonFXConfiguration, TalonFXConfiguration, CANcoderConfiguration>()
.withDriveMotorGearRatio(kDriveGearRatio)
.withSteerMotorGearRatio(kSteerGearRatio)
.withWheelRadius(kWheelRadius);

// --8<-- [start:module-constants]
// Front-Left module: drive/steer motor CAN IDs, CANcoder ID, mounting location, and the
// CANcoder offset measured by the generator's self-test — note this is in ROTATIONS, not
// the degrees YAGSL's absoluteEncoderOffset uses.
private static final int kFrontLeftDriveMotorId = 3;
private static final int kFrontLeftSteerMotorId = 2;
private static final int kFrontLeftEncoderId = 1;
private static final Angle kFrontLeftEncoderOffset = Rotations.of(0.152_343_75);
private static final boolean kFrontLeftSteerMotorInverted = true;
private static final Distance kFrontLeftXPos = Inches.of(10);
private static final Distance kFrontLeftYPos = Inches.of(10);

public static final SwerveModuleConstants<TalonFXConfiguration, TalonFXConfiguration, CANcoderConfiguration> FrontLeft =
ConstantCreator.createModuleConstants(
kFrontLeftSteerMotorId, kFrontLeftDriveMotorId, kFrontLeftEncoderId, kFrontLeftEncoderOffset,
kFrontLeftXPos, kFrontLeftYPos, /* driveInverted */ false, kFrontLeftSteerMotorInverted, /* encoderInverted */ false);
// --8<-- [end:module-constants]

// FrontRight, BackLeft, and BackRight are generated the exact same way, each with their
// own CAN IDs, mounting location, and measured offset.
public static final SwerveModuleConstants<TalonFXConfiguration, TalonFXConfiguration, CANcoderConfiguration> FrontRight =
ConstantCreator.createModuleConstants(0, 1, 0, Rotations.of(-0.487_304_69),
Inches.of(10), Inches.of(-10), true, true, false);

public static final SwerveModuleConstants<TalonFXConfiguration, TalonFXConfiguration, CANcoderConfiguration> BackLeft =
ConstantCreator.createModuleConstants(6, 7, 3, Rotations.of(-0.219_482_42),
Inches.of(-10), Inches.of(10), false, true, false);

public static final SwerveModuleConstants<TalonFXConfiguration, TalonFXConfiguration, CANcoderConfiguration> BackRight =
ConstantCreator.createModuleConstants(4, 5, 2, Rotations.of(0.172_363_28),
Inches.of(-10), Inches.of(-10), true, true, false);

// --8<-- [start:create-drivetrain]
/**
* Creates the drivetrain with the generated constants for all four modules.
* This should only be called once, from RobotContainer.
*/
public static CommandSwerveDrivetrain createDrivetrain()
{
return new CommandSwerveDrivetrain(DrivetrainConstants, FrontLeft, FrontRight, BackLeft, BackRight);
}
// --8<-- [end:create-drivetrain]
}
8 changes: 8 additions & 0 deletions docs/code_examples/swerve/talonfx/controllerproperties.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"angleJoystickRadiusDeadband": 0.5,
"heading": {
"p": 0.4,
"i": 0,
"d": 0.01
}
}
26 changes: 26 additions & 0 deletions docs/code_examples/swerve/talonfx/modules/backleft.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"drive": {
"type": "talonfx",
"id": 7,
"canbus": "canivore"
},
"angle": {
"type": "talonfx",
"id": 8,
"canbus": "canivore"
},
"encoder": {
"type": "cancoder",
"id": 12,
"canbus": "canivore"
},
"inverted": {
"drive": false,
"angle": false
},
"absoluteEncoderOffset": 6.504,
"location": {
"front": -12,
"left": 12
}
}
26 changes: 26 additions & 0 deletions docs/code_examples/swerve/talonfx/modules/backright.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"drive": {
"type": "talonfx",
"id": 5,
"canbus": "canivore"
},
"angle": {
"type": "talonfx",
"id": 6,
"canbus": "canivore"
},
"encoder": {
"type": "cancoder",
"id": 11,
"canbus": "canivore"
},
"inverted": {
"drive": false,
"angle": false
},
"absoluteEncoderOffset": -18.281,
"location": {
"front": -12,
"left": -12
}
}
26 changes: 26 additions & 0 deletions docs/code_examples/swerve/talonfx/modules/frontleft.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"drive": {
"type": "talonfx",
"id": 4,
"canbus": "canivore"
},
"angle": {
"type": "talonfx",
"id": 3,
"canbus": "canivore"
},
"encoder": {
"type": "cancoder",
"id": 9,
"canbus": "canivore"
},
"inverted": {
"drive": false,
"angle": false
},
"absoluteEncoderOffset": -114.609,
"location": {
"front": 12,
"left": 12
}
}
Loading
Loading