-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds flare command for approaching target at distance
- Loading branch information
Showing
1 changed file
with
124 additions
and
0 deletions.
There are no files selected for viewing
124 changes: 124 additions & 0 deletions
124
src/main/java/frc/robot/commands/teleop/DistanceToTargetCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
package frc.robot.commands.teleop; | ||
|
||
import java.util.function.Supplier; | ||
|
||
import edu.wpi.first.math.MathUtil; | ||
import edu.wpi.first.math.controller.ProfiledPIDController; | ||
import edu.wpi.first.math.geometry.Pose2d; | ||
import edu.wpi.first.math.geometry.Translation2d; | ||
import edu.wpi.first.math.kinematics.ChassisSpeeds; | ||
import edu.wpi.first.math.trajectory.TrapezoidProfile; | ||
import edu.wpi.first.math.util.Units; | ||
import frc.robot.Constants; | ||
import frc.robot.commands.OdometryHeadingCommand; | ||
import frc.robot.commands.interfaces.AutoDrivableCommand; | ||
import frc.robot.coordinates.PolarCoordinate; | ||
import frc.robot.subsystems.AutoDrive; | ||
import frc.robot.subsystems.Heading; | ||
|
||
/** | ||
* Drive a certain distance from a point - regardless of angle - and maintain that | ||
* distance away from the point. Will attempt to face target while driving towards | ||
* target. | ||
*/ | ||
public class DistanceToTargetCommand extends OdometryHeadingCommand implements AutoDrivableCommand { | ||
|
||
private Translation2d targetMeters; | ||
private double distanceMeters; | ||
private Supplier<Pose2d> poseSupplier; | ||
private Supplier<ChassisSpeeds> chassisSpeedsProvider; | ||
private AutoDrive autoDrive; | ||
|
||
private ProfiledPIDController distanceController; | ||
|
||
private double output = 0.0; | ||
|
||
public DistanceToTargetCommand(double distanceMeters, Supplier<Pose2d> poseSupplier, Supplier<ChassisSpeeds> chassisSpeedsProvider, AutoDrive autoDrive, Heading heading) { | ||
this(Constants.kHub, distanceMeters, poseSupplier, chassisSpeedsProvider, autoDrive, heading); | ||
} | ||
|
||
public DistanceToTargetCommand(Translation2d targetMeters, double distanceMeters, Supplier<Pose2d> poseSupplier, Supplier<ChassisSpeeds> chassisSpeedsProvider, AutoDrive autoDrive, Heading heading) { | ||
super(targetMeters, poseSupplier, heading); | ||
|
||
this.targetMeters = targetMeters; | ||
this.distanceMeters = distanceMeters; | ||
this.poseSupplier = poseSupplier; | ||
this.chassisSpeedsProvider = chassisSpeedsProvider; | ||
this.autoDrive = autoDrive; | ||
|
||
final double maxSpeed = 0.8; // 80% of maximum speed | ||
final double maxVelocityMetersPerSecond = Constants.Swerve.MAX_VELOCITY_METERS_PER_SECOND * maxSpeed; | ||
distanceController = new ProfiledPIDController(3, 0.0, 0.0, | ||
// Use max speed above. Come up to max speed in one second | ||
new TrapezoidProfile.Constraints( | ||
maxVelocityMetersPerSecond, | ||
maxVelocityMetersPerSecond | ||
) | ||
); | ||
// Tolerance for our distance is within ~2 inches (should be Good Enough™️) | ||
distanceController.setTolerance(Units.inchesToMeters(2)); | ||
|
||
addRequirements(autoDrive); | ||
} | ||
|
||
@Override | ||
public void initialize() { | ||
super.initialize(); | ||
|
||
autoDrive.setDelegate(this); | ||
|
||
// Set our initial setpoint for our profiled PID controllers | ||
// to avoid a JUMP to their starting values on first run | ||
PolarCoordinate robotCoordinate = getRobotCoordinate(); | ||
distanceController.reset( | ||
robotCoordinate.getRadiusMeters(), | ||
chassisSpeedsProvider.get().vxMetersPerSecond | ||
); | ||
} | ||
|
||
@Override | ||
public void execute() { | ||
super.execute(); | ||
|
||
PolarCoordinate robotCoordinate = getRobotCoordinate(); | ||
output = distanceController.calculate( | ||
robotCoordinate.getRadiusMeters(), | ||
distanceMeters | ||
); | ||
|
||
// Clamp to some max speed (should be between [0.0, 1.0]) | ||
final double maxSpeed = 1.0; | ||
output = MathUtil.clamp( | ||
output, | ||
-maxSpeed, | ||
maxSpeed | ||
); | ||
} | ||
|
||
@Override | ||
public void end(boolean interrupted) { | ||
super.end(interrupted); | ||
|
||
autoDrive.clearDelegate(); | ||
} | ||
|
||
private PolarCoordinate getRobotCoordinate() { | ||
// Find our robot polar coordinate relative to the target | ||
return PolarCoordinate.fromFieldCoordinate( | ||
poseSupplier.get().getTranslation(), | ||
targetMeters | ||
); | ||
} | ||
|
||
public AutoDrive.State calculate(double forward, double strafe, boolean isFieldOriented) { | ||
// Use our distanController output calculation as our forward value. | ||
// Driver can strafe during this command. Forward should be forward to the robot. | ||
// Note that this command assumes we're facing the target (use with Heading) | ||
return new AutoDrive.State( | ||
-output, | ||
strafe, | ||
false | ||
); | ||
} | ||
|
||
} |