Skip to content

Commit

Permalink
Added a few example trajectories for autos
Browse files Browse the repository at this point in the history
  • Loading branch information
suryatho committed Jan 15, 2024
1 parent c21fc66 commit 5f87912
Show file tree
Hide file tree
Showing 13 changed files with 2,018 additions and 61 deletions.
1,634 changes: 1,633 additions & 1 deletion src/main/deploy/pathplanner/navgrid.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/main/java/frc/robot/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
public final class Constants {
public static final int loopPeriodMs = 20;
public static final Mode currentMode = Mode.SIM;
public static final boolean tuningMode = true;
public static final boolean characterizationMode = false;

public static enum Mode {
Expand Down
48 changes: 45 additions & 3 deletions src/main/java/frc/robot/FieldConstants.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package frc.robot;

import edu.wpi.first.math.geometry.Translation2d;
import static edu.wpi.first.apriltag.AprilTagFields.k2024Crescendo;

import edu.wpi.first.apriltag.AprilTagFieldLayout;
import edu.wpi.first.math.geometry.*;
import edu.wpi.first.math.util.Units;
import java.io.IOException;

/**
* Contains various field dimensions and useful reference points. Dimensions are in meters, and sets
Expand All @@ -18,14 +22,16 @@ public class FieldConstants {
public static double fieldLength = Units.inchesToMeters(651.223);
public static double fieldWidth = Units.inchesToMeters(323.277);
public static double wingX = Units.inchesToMeters(229.201);

public static double podiumX = Units.inchesToMeters(126.75);
public static double startingLineX = Units.inchesToMeters(74.111);

public static Translation2d ampCenter =
new Translation2d(Units.inchesToMeters(72.455), Units.inchesToMeters(322.996));

/** Staging locations for each note */
public static final class StagingLocations {
public static double centerlineX = Units.inchesToMeters(fieldLength / 2);


// need to update
public static double centerlineFirstY = Units.inchesToMeters(29.638);
public static double centerlineSeparationY = Units.inchesToMeters(66);
Expand All @@ -50,4 +56,40 @@ public static final class StagingLocations {
}
}
}

/** Each corner of the speaker * */
public static final class Speaker {

/** Center of the speaker opening (blue alliance) */
public static Pose2d centerSpeakerOpening =
new Pose2d(0.0, fieldWidth - Units.inchesToMeters(104.0), new Rotation2d());
}

// corners (blue alliance origin)
public static Translation3d topRightSpeaker =
new Translation3d(
Units.inchesToMeters(18.055),
Units.inchesToMeters(238.815),
Units.inchesToMeters(13.091));

public static Translation3d topLeftSpeaker =
new Translation3d(
Units.inchesToMeters(18.055),
Units.inchesToMeters(197.765),
Units.inchesToMeters(83.091));

public static Translation3d bottomRightSpeaker =
new Translation3d(0.0, Units.inchesToMeters(238.815), Units.inchesToMeters(78.324));
public static Translation3d bottomLeftSpeaker =
new Translation3d(0.0, Units.inchesToMeters(197.765), Units.inchesToMeters(78.324));

public static AprilTagFieldLayout fieldLayout;

static {
try {
fieldLayout = AprilTagFieldLayout.loadFromResource(k2024Crescendo.m_resourceFile);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
30 changes: 30 additions & 0 deletions src/main/java/frc/robot/RobotContainer.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,32 @@

package frc.robot;

import com.pathplanner.lib.path.*;
import edu.wpi.first.math.geometry.Pose2d;
import edu.wpi.first.math.geometry.Rotation2d;
import edu.wpi.first.wpilibj.Filesystem;
import edu.wpi.first.wpilibj.GenericHID;
import edu.wpi.first.wpilibj.XboxController;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.Commands;
import edu.wpi.first.wpilibj2.command.button.CommandXboxController;
import frc.robot.commands.DriveCommands;
import frc.robot.commands.DriveTrajectory;
import frc.robot.commands.FeedForwardCharacterization;
import frc.robot.commands.autos.TestAutos;
import frc.robot.subsystems.drive.Drive;
import frc.robot.subsystems.drive.GyroIO;
import frc.robot.subsystems.drive.GyroIOPigeon2;
import frc.robot.subsystems.drive.ModuleIO;
import frc.robot.subsystems.drive.ModuleIOSim;
import frc.robot.subsystems.drive.ModuleIOSparkMax;
import frc.robot.subsystems.kitbotshooter.*;
import frc.robot.util.trajectory.ChoreoTrajectoryReader;
import frc.robot.util.trajectory.Trajectory;
import java.io.File;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import org.littletonrobotics.junction.networktables.LoggedDashboardChooser;
import org.littletonrobotics.junction.networktables.LoggedDashboardNumber;

Expand Down Expand Up @@ -113,6 +123,26 @@ public RobotContainer() {
shooter, shooter::runFlywheelVolts, shooter::getFlywheelVelocityRadPerSec),
Commands.runOnce(() -> shooter.setCurrentMode(null))));

// Testing autos paths
Function<File, Optional<Command>> trajectoryCommandFactory =
trajectoryFile -> {
Optional<Trajectory> trajectory = ChoreoTrajectoryReader.generate(trajectoryFile);
return trajectory.map(
traj ->
Commands.sequence(
Commands.runOnce(() -> drive.setPose(traj.startPose()), drive),
new DriveTrajectory(drive, traj)));
};
final File rootTrajectoryDir = new File(Filesystem.getDeployDirectory(), "choreo");
for (File trajectoryFile : Objects.requireNonNull(rootTrajectoryDir.listFiles())) {
trajectoryCommandFactory
.apply(trajectoryFile)
.ifPresent(
command -> {
autoChooser.addOption(trajectoryFile.getName(), command);
});
}

// Configure the button bindings
configureButtonBindings();
}
Expand Down
7 changes: 4 additions & 3 deletions src/main/java/frc/robot/commands/DriveCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.Commands;
import frc.robot.subsystems.drive.Drive;
import frc.robot.subsystems.drive.DriveConstants;
import java.util.function.DoubleSupplier;

public class DriveCommands {
Expand Down Expand Up @@ -60,9 +61,9 @@ public static Command joystickDrive(
// Convert to field relative speeds & send command
drive.runVelocity(
ChassisSpeeds.fromFieldRelativeSpeeds(
linearVelocity.getX() * drive.getMaxLinearSpeedMetersPerSec(),
linearVelocity.getY() * drive.getMaxLinearSpeedMetersPerSec(),
omega * drive.getMaxAngularSpeedRadPerSec(),
linearVelocity.getX() * DriveConstants.maxLinearSpeed,
linearVelocity.getY() * DriveConstants.maxLinearSpeed,
omega * DriveConstants.maxAngularSpeed,
drive.getRotation()));
},
drive);
Expand Down
124 changes: 124 additions & 0 deletions src/main/java/frc/robot/commands/DriveTrajectory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package frc.robot.commands;

import static frc.robot.util.trajectory.HolonomicDriveController.HolonomicDriveState;

import edu.wpi.first.math.controller.PIDController;
import edu.wpi.first.math.geometry.Pose2d;
import edu.wpi.first.math.kinematics.ChassisSpeeds;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj2.command.Command;
import frc.robot.subsystems.drive.Drive;
import frc.robot.subsystems.drive.DriveConstants;
import frc.robot.util.AllianceFlipUtil;
import frc.robot.util.LoggedTunableNumber;
import frc.robot.util.trajectory.HolonomicDriveController;
import frc.robot.util.trajectory.Trajectory;
import java.util.function.Supplier;
import org.littletonrobotics.junction.Logger;

public class DriveTrajectory extends Command {
private static final LoggedTunableNumber driveKp =
new LoggedTunableNumber("DriveTrajectory/DriveKp");
private static final LoggedTunableNumber driveKd =
new LoggedTunableNumber("DriveTrajectory/DriveKd");
private static final LoggedTunableNumber turnKp =
new LoggedTunableNumber("DriveTrajectory/TurnKp");
private static final LoggedTunableNumber turnKd =
new LoggedTunableNumber("DriveTrajectory/TurnKd");

// initialize tunable numbers to constants
static {
driveKp.initDefault(DriveConstants.trajectoryConstants().drivekp());
driveKd.initDefault(DriveConstants.trajectoryConstants().drivekd());
turnKp.initDefault(DriveConstants.trajectoryConstants().turnkp());
turnKd.initDefault(DriveConstants.trajectoryConstants().turnkd());
}

public static final PIDController linearController = new PIDController(0.0, 0.0, 0.0);
public static final PIDController thetaController = new PIDController(0.0, 0.0, 0.0);
public static final HolonomicDriveController controller =
new HolonomicDriveController(linearController, thetaController);

private final Drive drive;
private final Supplier<Trajectory> trajectorySupplier;
private Trajectory trajectory;
private final Timer timer = new Timer();

public DriveTrajectory(Drive drive, Supplier<Trajectory> trajectorySupplier) {
this.drive = drive;
this.trajectorySupplier = trajectorySupplier;

addRequirements(drive);
}

public DriveTrajectory(Drive drive, Trajectory trajectory) {
this(drive, () -> trajectory);
}

@Override
public void initialize() {
// Log trajectory
trajectory = trajectorySupplier.get();
Logger.recordOutput("Odometry/Trajectory", trajectory.getTrajectoryPoses());

// Reset all controllers
timer.reset();
timer.start();
linearController.reset();
thetaController.reset();

// Reset PID gains
linearController.setP(driveKp.get());
linearController.setD(driveKd.get());
thetaController.setP(turnKp.get());
thetaController.setD(turnKd.get());
}

@Override
public void execute() {
if (driveKp.hasChanged(hashCode())
|| driveKd.hasChanged(hashCode())
|| turnKp.hasChanged(hashCode())
|| turnKd.hasChanged(hashCode())) {
linearController.setP(driveKp.get());
linearController.setD(driveKd.get());
thetaController.setP(turnKp.get());
thetaController.setD(turnKd.get());
}

// sample and maybe flip trajectory state
HolonomicDriveState referenceState = trajectory.sample(timer.get());
referenceState = AllianceFlipUtil.apply(referenceState);

Pose2d referencePose = referenceState.pose();
Logger.recordOutput("Odometry/TrajectorySetpoint", referencePose);

ChassisSpeeds outputSpeeds = controller.calculate(drive.getPose(), referenceState);
drive.runVelocity(outputSpeeds);

Logger.recordOutput(
"Odometry/TrajectoryTranslationErrorMeters",
controller.getPoseError().getTranslation().getNorm());
Logger.recordOutput(
"Odometry/TrajectoryRotationErrorRadians", controller.getRotationError().getRadians());
Logger.recordOutput(
"Drive/autoSpeeds",
new double[] {
outputSpeeds.vxMetersPerSecond,
outputSpeeds.vyMetersPerSecond,
outputSpeeds.omegaRadiansPerSecond
});
}

@Override
public boolean isFinished() {
return timer.hasElapsed(trajectory.getDuration());
}

@Override
public void end(boolean interrupted) {
drive.stop();
Logger.recordOutput("Odometry/Trajectory", new Pose2d[] {});
Logger.recordOutput("Odometry/TrajectorySetpoint", new double[] {});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

public class FeedForwardCharacterization extends Command {
private static final double START_DELAY_SECS = 2.0;
private static final double RAMP_VOLTS_PER_SEC = 0.4;
private static final double RAMP_VOLTS_PER_SEC = 0.1;

private FeedForwardCharacterizationData data;
private final Consumer<Double> voltageConsumer;
Expand Down
Loading

0 comments on commit 5f87912

Please sign in to comment.