Skip to content

Commit

Permalink
Change Motion Planner
Browse files Browse the repository at this point in the history
  • Loading branch information
suryatho committed Feb 2, 2024
1 parent bcabdf8 commit ad80215
Show file tree
Hide file tree
Showing 9 changed files with 338 additions and 442 deletions.
19 changes: 7 additions & 12 deletions src/main/java/frc/robot/RobotContainer.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@
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.FeedForwardCharacterization;
import frc.robot.commands.auto.TestAutos;
import frc.robot.subsystems.apriltagvision.AprilTagVision;
import frc.robot.subsystems.apriltagvision.AprilTagVisionConstants;
import frc.robot.subsystems.apriltagvision.AprilTagVisionIONorthstar;
Expand Down Expand Up @@ -161,17 +159,14 @@ public RobotContainer() {
.beforeStarting(() -> shooter.setCharacterizing(true))
.finallyDo(() -> shooter.setCharacterizing(false)));

autoChooser.addOption("4 Note Davis", TestAutos.fourNoteDavis(drive, intake));

// Testing autos paths
Function<File, Optional<Command>> trajectoryCommandFactory =
trajectoryFile -> {
Optional<Trajectory> trajectory = ChoreoTrajectoryReader.generate(trajectoryFile);
return trajectory.map(
traj ->
Commands.runOnce(
() -> robotState.resetPose(AllianceFlipUtil.apply(traj.getStartPose())),
drive)
() -> robotState.resetPose(AllianceFlipUtil.apply(traj.getStartPose())))
.andThen(drive.setTrajectoryCommand(traj)));
};
final File rootTrajectoryDir = new File(Filesystem.getDeployDirectory(), "choreo");
Expand All @@ -192,12 +187,12 @@ public RobotContainer() {
* edu.wpi.first.wpilibj2.command.button.JoystickButton}.
*/
private void configureButtonBindings() {
drive.setDefaultCommand(
DriveCommands.joystickDrive(
drive,
() -> -controller.getLeftY(),
() -> -controller.getLeftX(),
() -> -controller.getRightX()));
// drive.setDefaultCommand(
// DriveCommands.joystickDrive(
// drive,
// () -> -controller.getLeftY(),
// () -> -controller.getLeftX(),
// () -> -controller.getRightX()));
// controller.a().onTrue(DriveCommands.toggleCalculateShotWhileMovingRotation(drive));
controller
.a()
Expand Down
23 changes: 12 additions & 11 deletions src/main/java/frc/robot/commands/DriveCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import edu.wpi.first.math.kinematics.ChassisSpeeds;
import edu.wpi.first.wpilibj.DriverStation;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.Commands;
import frc.robot.FieldConstants;
import frc.robot.RobotState;
import frc.robot.subsystems.drive.Drive;
Expand Down Expand Up @@ -62,10 +61,12 @@ public static Command joystickDrive(

ChassisSpeeds speeds =
new ChassisSpeeds(
linearVelocity.getX() * DriveConstants.drivetrainConfig.maxLinearVelocity(),
linearVelocity.getY() * DriveConstants.drivetrainConfig.maxLinearVelocity(),
omega * DriveConstants.drivetrainConfig.maxAngularVelocity());
drive.setDriveInputSpeeds(speeds);
linearVelocity.getX() * DriveConstants.driveConfig.maxLinearVelocity(),
linearVelocity.getY() * DriveConstants.driveConfig.maxLinearVelocity(),
omega * DriveConstants.driveConfig.maxAngularVelocity());
drive.setDriveVelocity(
ChassisSpeeds.fromFieldRelativeSpeeds(
speeds, RobotState.getInstance().getEstimatedPose().getRotation()));
});
}

Expand All @@ -81,10 +82,10 @@ public static Command joystickDrive(
return shotData.goalHeading();
};

public static Command toggleCalculateShotWhileMovingRotation(Drive drive) {
return Commands.either(
drive.disableHeadingCommand(), // turn off
drive.setHeadingCommand(shotRotation), // turn on
drive.getMotionPlanner()::isHeadingControlled);
}
// public static Command toggleCalculateShotWhileMovingRotation(Drive drive) {
// return Commands.either(
// drive.disableHeadingCommand(), // turn off
// drive.setHeadingCommand(shotRotation), // turn on
// drive.getAutoMotionPlanner()::isHeadingControlled);
// }
}
13 changes: 6 additions & 7 deletions src/main/java/frc/robot/commands/auto/AutoCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,18 @@
import edu.wpi.first.wpilibj2.command.Commands;
import frc.robot.FieldConstants;
import frc.robot.RobotState;
import frc.robot.subsystems.drive.Drive;
import frc.robot.subsystems.superstructure.ShotCalculator;
import frc.robot.subsystems.superstructure.intake.Intake;
import frc.robot.util.AllianceFlipUtil;
import java.util.function.Supplier;

public class AutoCommands {
public static Command moveWhileShooting(Drive drive) {
return drive
.setHeadingCommand(AutoCommands::calculateShootHeading)
.andThen(Commands.waitSeconds(0.7))
.andThen(drive.disableHeadingCommand());
}
// public static Command moveWhileShooting(Drive drive) {
// return drive
// .setHeadingCommand(AutoCommands::calculateShootHeading)
// .andThen(Commands.waitSeconds(0.7))
// .andThen(drive.disableHeadingCommand());
// }

private static Rotation2d calculateShootHeading() {
Twist2d fieldVel = RobotState.getInstance().fieldVelocity();
Expand Down
22 changes: 11 additions & 11 deletions src/main/java/frc/robot/commands/auto/TestAutos.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
public class TestAutos {
private static final LoggedTunableNumber intakeDistance =
new LoggedTunableNumber(
"Auto/intakeDistance", DriveConstants.drivetrainConfig.trackwidthX() + 0.1);
"Auto/intakeDistance", DriveConstants.driveConfig.trackwidthX() + 0.1);

// bottom to top
private static AutoCommands.CircularRegion spikeIntakeRegion(int i) {
Expand Down Expand Up @@ -53,20 +53,20 @@ public static Command fourNoteDavis(Drive drive, Intake intake) {
new AutoCommands.RectangularRegion(new Translation2d(3.83, 5.99), 0.1, 0.5);
var fourthShotRegion =
new AutoCommands.RectangularRegion(new Translation2d(4.08, 7.18), 0.1, 0.5);
Command sequenceShots =
Commands.sequence(
AutoCommands.moveWhileShooting(drive),
AutoCommands.waitForRegion(() -> AllianceFlipUtil.apply(secondShotRegion)),
AutoCommands.moveWhileShooting(drive),
AutoCommands.waitForRegion(() -> AllianceFlipUtil.apply(thirdShotRegion)),
AutoCommands.moveWhileShooting(drive),
AutoCommands.waitForRegion(() -> AllianceFlipUtil.apply(fourthShotRegion)),
AutoCommands.moveWhileShooting(drive));
// Command sequenceShots =
// Commands.sequence(
// AutoCommands.moveWhileShooting(drive),
// AutoCommands.waitForRegion(() -> AllianceFlipUtil.apply(secondShotRegion)),
// AutoCommands.moveWhileShooting(drive),
// AutoCommands.waitForRegion(() -> AllianceFlipUtil.apply(thirdShotRegion)),
// AutoCommands.moveWhileShooting(drive),
// AutoCommands.waitForRegion(() -> AllianceFlipUtil.apply(fourthShotRegion)),
// AutoCommands.moveWhileShooting(drive));

return Commands.sequence(
resetPoseCommand(trajectory.getStartPose()),
drive.setTrajectoryCommand(trajectory),
Commands.parallel(sequenceIntake, sequenceShots));
Commands.parallel(sequenceIntake));
}

private static Command resetPoseCommand(Pose2d pose) {
Expand Down
172 changes: 172 additions & 0 deletions src/main/java/frc/robot/subsystems/drive/AutoMotionPlanner.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
package frc.robot.subsystems.drive;

import static frc.robot.subsystems.drive.DriveConstants.*;
import static frc.robot.util.trajectory.HolonomicDriveController.HolonomicDriveState;

import edu.wpi.first.math.geometry.Pose2d;
import edu.wpi.first.math.geometry.Rotation2d;
import edu.wpi.first.math.geometry.Translation2d;
import edu.wpi.first.math.geometry.Twist2d;
import edu.wpi.first.math.kinematics.ChassisSpeeds;
import edu.wpi.first.wpilibj.DriverStation;
import frc.robot.Constants;
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.Arrays;
import org.littletonrobotics.junction.Logger;

public class AutoMotionPlanner {
private static LoggedTunableNumber trajectoryLinearKp =
new LoggedTunableNumber("Trajectory/linearKp", trajectoryConstants.linearKp());
private static LoggedTunableNumber trajectoryLinearKd =
new LoggedTunableNumber("Trajectory/linearKd", trajectoryConstants.linearKd());
private static LoggedTunableNumber trajectoryThetaKp =
new LoggedTunableNumber("Trajectory/thetaKp", trajectoryConstants.thetaKp());
private static LoggedTunableNumber trajectoryThetaKd =
new LoggedTunableNumber("Trajectory/thetaKd", trajectoryConstants.thetaKd());
private static LoggedTunableNumber trajectoryLinearTolerance =
new LoggedTunableNumber(
"Trajectory/controllerLinearTolerance", trajectoryConstants.linearTolerance());
private static LoggedTunableNumber trajectoryThetaTolerance =
new LoggedTunableNumber(
"Trajectory/controllerThetaTolerance", trajectoryConstants.thetaTolerance());
private static LoggedTunableNumber trajectoryGoalLinearTolerance =
new LoggedTunableNumber(
"Trajectory/goalLinearTolerance", trajectoryConstants.goalLinearTolerance());
private static LoggedTunableNumber trajectoryGoalThetaTolerance =
new LoggedTunableNumber(
"Trajectory/goalThetaTolerance", trajectoryConstants.goalThetaTolerance());
private static LoggedTunableNumber trajectoryLinearVelocityTolerance =
new LoggedTunableNumber(
"Trajectory/goalLinearVelocityTolerance", trajectoryConstants.linearVelocityTolerance());
private static LoggedTunableNumber trajectoryAngularVelocityTolerance =
new LoggedTunableNumber(
"Trajectory/goalAngularVelocityTolerance",
trajectoryConstants.angularVelocityTolerance());

private Trajectory trajectory = null;
private Double startTime = null;
private Double currentTime = null;
private final HolonomicDriveController controller;

public AutoMotionPlanner() {
controller =
new HolonomicDriveController(
trajectoryLinearKp.get(),
trajectoryLinearKd.get(),
trajectoryThetaKp.get(),
trajectoryThetaKd.get());
configTrajectoryTolerances();
}

protected void setTrajectory(Trajectory trajectory) {
// Only set if not following trajectory or done with current one
if (this.trajectory == null || isFinished()) {
this.trajectory = trajectory;
controller.setGoalState(trajectory.getEndState());
controller.resetControllers();
startTime = null;
currentTime = null;
// Log poses
Logger.recordOutput(
"Trajectory/trajectoryPoses",
Arrays.stream(trajectory.getTrajectoryPoses())
.map(AllianceFlipUtil::apply)
.toArray(Pose2d[]::new));
}
}

/** Output setpoint chassis speeds in */
protected ChassisSpeeds update(double timestamp, Pose2d robot, Twist2d fieldVelocity) {
System.out.println(timestamp + " " + robot.toString() + " " + fieldVelocity.toString());
// If disabled reset everything and stop
if (DriverStation.isDisabled()) {
trajectory = null;
// Stop logs
Logger.recordOutput("Trajectory/trajectoryPoses", new Pose2d[] {});
Logger.recordOutput("Trajectory/setpointPose", new Pose2d());
Logger.recordOutput("Trajectory/speeds", new double[] {});
return new ChassisSpeeds();
}

// Tunable numbers
if (Constants.tuningMode) {
// Update PID Controllers
LoggedTunableNumber.ifChanged(
hashCode(),
pid -> controller.setPID(pid[0], pid[1], pid[2], pid[3]),
trajectoryLinearKp,
trajectoryLinearKd,
trajectoryThetaKp,
trajectoryThetaKp);
// Tolerances
LoggedTunableNumber.ifChanged(
hashCode(),
this::configTrajectoryTolerances,
trajectoryLinearTolerance,
trajectoryThetaTolerance,
trajectoryGoalLinearTolerance,
trajectoryGoalThetaTolerance,
trajectoryLinearVelocityTolerance,
trajectoryAngularVelocityTolerance);
}

// Reached end
if (isFinished() || trajectory == null) {
// Stop logs
Logger.recordOutput("Trajectory/trajectoryPoses", new Pose2d[] {});
Logger.recordOutput("Trajectory/setpointPose", new Pose2d());
Logger.recordOutput("Trajectory/speeds", new double[] {});
return new ChassisSpeeds();
}

if (startTime == null) {
startTime = timestamp;
}
currentTime = timestamp;

HolonomicDriveState currentState =
new HolonomicDriveState(robot, fieldVelocity.dx, fieldVelocity.dy, fieldVelocity.dtheta);
// Sample and flip state
HolonomicDriveState setpointState = trajectory.sample(currentTime - startTime);
setpointState = AllianceFlipUtil.apply(setpointState);
// calculate trajectory speeds
ChassisSpeeds speeds = controller.calculate(currentState, setpointState);

// Log trajectory data
Logger.recordOutput("Trajectory/setpointPose", setpointState.pose());
Logger.recordOutput(
"Trajectory/translationError", controller.getPoseError().getTranslation().getNorm());
Logger.recordOutput(
"Trajectory/rotationError", controller.getPoseError().getRotation().getRadians());
return speeds;
}

protected boolean isFinished() {
return trajectory != null
&& currentTime != null
&& startTime != null
&& currentTime - startTime >= trajectory.getDuration()
&& controller.atGoal();
}

private void configTrajectoryTolerances() {
controller.setControllerTolerance(
new Pose2d(
new Translation2d(
trajectoryLinearTolerance.get(), Rotation2d.fromRadians(Math.PI / 4.0)),
Rotation2d.fromRadians(trajectoryThetaTolerance.get())));
double velocityXTolerance = trajectoryLinearVelocityTolerance.get() / Math.sqrt(2.0);
controller.setGoalTolerance(
new HolonomicDriveState(
new Pose2d(
new Translation2d(
trajectoryGoalLinearTolerance.get(), Rotation2d.fromRadians(Math.PI / 4.0)),
Rotation2d.fromRadians(trajectoryGoalThetaTolerance.get())),
velocityXTolerance,
velocityXTolerance, // Same value
trajectoryAngularVelocityTolerance.get()));
}
}
Loading

0 comments on commit ad80215

Please sign in to comment.