Skip to content

Commit b10718f

Browse files
committed
Simplied PoseEstimationSubystem and Robot#driveWithAlignmentCommand(...)
1 parent 6721361 commit b10718f

File tree

4 files changed

+51
-98
lines changed

4 files changed

+51
-98
lines changed

src/main/java/frc/robot/CommandComposer.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,7 @@ public static Command moveOnSquare(double sideLength, double distanceTolerance,
157157
* @return a {@code Command} for moving the robot on a circle
158158
*/
159159
public static Command moveOnCircle(double radius, double initialAngularVelocity, double finalAngularVelocity,
160-
double distanceTolerance,
161-
double angleTolerance, double timeout) {
160+
double distanceTolerance, double angleTolerance, double timeout) {
162161

163162
Timer timer = new Timer();
164163

src/main/java/frc/robot/Robot.java

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
package frc.robot;
66

7-
import static edu.wpi.first.wpilibj2.command.Commands.*;
87
import static frc.robot.Constants.*;
98
import static frc.robot.Constants.RobotConstants.*;
109
import static frc.robot.subsystems.PoseEstimationSubsystem.*;
@@ -15,6 +14,7 @@
1514
import org.littletonrobotics.urcl.URCL;
1615
import org.photonvision.PhotonCamera;
1716

17+
import edu.wpi.first.math.geometry.Pose2d;
1818
import edu.wpi.first.math.geometry.Rotation2d;
1919
import edu.wpi.first.math.geometry.Transform2d;
2020
import edu.wpi.first.math.kinematics.ChassisSpeeds;
@@ -31,6 +31,7 @@
3131
import edu.wpi.first.wpilibj2.command.button.CommandPS4Controller;
3232
import frc.robot.Constants.ControllerConstants;
3333
import frc.robot.Constants.ControllerConstants.Button;
34+
import frc.robot.commands.drive.DriveCommand2Controllers;
3435
import frc.robot.subsystems.DriveSubsystem;
3536
import frc.robot.subsystems.PhotonCameraSimulator;
3637
import frc.robot.subsystems.PoseEstimationSubsystem;
@@ -64,6 +65,9 @@ public Robot() {
6465
m_autoSelector.addOption("Test DriveSubsystem", m_driveSubsystem.testCommand());
6566
SmartDashboard.putData("Auto Selector", m_autoSelector);
6667

68+
double distanceTolerance = 0.01;
69+
double angleToleranceInDegrees = 1.0;
70+
6771
m_testSelector.addOption("Check All Subsystems in Pitt", CommandComposer.testAllSubsystems());
6872
m_testSelector.addOption("Check All Subsystems on Field", CommandComposer.testAllSubsystems());
6973
m_testSelector.addOption("Check DriveSubsystem (Robot-Oriented F/B/L/R/LR/RR)", m_driveSubsystem.testCommand());
@@ -74,15 +78,16 @@ public Robot() {
7478
m_testSelector
7579
.addOption(
7680
"Check kDriveGearRatio and kWheelDiameter (F/B 6 feet)",
77-
CommandComposer.moveForwardBackward2Controllers(6, 0.01, 1));
81+
CommandComposer.moveForwardBackward2Controllers(6, distanceTolerance, angleToleranceInDegrees));
7882
m_testSelector
7983
.addOption(
8084
"Check PID Constants for Driving (5'x5' Square)",
81-
CommandComposer.moveOnSquare(Units.feetToMeters(5), 0.01, 1, 16));
85+
CommandComposer
86+
.moveOnSquare(Units.feetToMeters(5), distanceTolerance, angleToleranceInDegrees, 16));
8287
m_testSelector
8388
.addOption(
8489
"Check PID Constants for Driving (Unit Circle)",
85-
CommandComposer.moveOnCircle(1, 1, 3, 0.01, 1, 10));
90+
CommandComposer.moveOnCircle(1, 1, 3, distanceTolerance, angleToleranceInDegrees, 10));
8691
m_testSelector.addOption("Test Rotation", CommandComposer.testRotation());
8792
m_testSelector.addOption("Turn toward Tag 1", CommandComposer.turnTowardTag(1));
8893

@@ -114,7 +119,7 @@ public void bindDriveControls() {
114119
() -> -m_driverController.getLeftY(),
115120
() -> -m_driverController.getLeftX(),
116121
() -> m_driverController.getL2Axis() - m_driverController.getR2Axis(),
117-
new Transform2d(0.5, 0, Rotation2d.fromDegrees(180)), 2));
122+
new Transform2d(0.5, 0, Rotation2d.fromDegrees(180)), 2, 0.03, 3));
118123
}
119124

120125
/**
@@ -130,20 +135,30 @@ public void bindDriveControls() {
130135
* @param robotToTag the {@code Tranform2d} representing the pose of the
131136
* closest {@code AprilTag} relative to the robot when the robot is
132137
* aligned
133-
* @param isFieldRelative {@code Supplier} for determining whether or not
134-
* driving should be field relative.
138+
* @param distanceThresholdInMeters the maximum distance (in meters) within
139+
* which {@code AprilTag}s are considered
140+
* @param distanceTolerance the distance error in meters which is tolerable
141+
* @param angleToleranceInDegrees the angle error in degrees which is tolerable
135142
* @return a {@code Command} to automatically align the robot to the closest tag
136143
* while driving the robot with joystick input
137144
*/
138145
Command driveWithAlignmentCommand(DoubleSupplier forwardSpeed, DoubleSupplier strafeSpeed,
139-
DoubleSupplier rotation, Transform2d robotToTag, double distanceThresholdInMeters) {
140-
return run(() -> {
141-
ChassisSpeeds speeds = DriveSubsystem.chassisSpeeds(forwardSpeed, strafeSpeed, rotation);
142-
speeds = speeds.plus(
143-
m_poseEstimationSubsystem
144-
.chassisSpeedsTowardClosestTag(robotToTag, distanceThresholdInMeters));
145-
m_driveSubsystem.drive(speeds, true);
146-
});
146+
DoubleSupplier rotation, Transform2d robotToTag, double distanceThresholdInMeters, double distanceTolerance,
147+
double angleToleranceInDegrees) {
148+
return new DriveCommand2Controllers(m_driveSubsystem, () -> {
149+
Pose2d closestTagPose = m_poseEstimationSubsystem.closestTagPose(180, distanceThresholdInMeters);
150+
if (closestTagPose == null)
151+
return m_driveSubsystem.getPose();
152+
return m_poseEstimationSubsystem.odometryCentricPose(closestTagPose.plus(robotToTag));
153+
}, false, distanceTolerance, angleToleranceInDegrees) {
154+
155+
@Override
156+
public ChassisSpeeds chassisSpeeds() {
157+
ChassisSpeeds speeds = DriveSubsystem.chassisSpeeds(forwardSpeed, strafeSpeed, rotation);
158+
return speeds.plus(super.chassisSpeeds());
159+
}
160+
161+
};
147162
}
148163

149164
@Override

src/main/java/frc/robot/commands/drive/DriveCommand2Controllers.java

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ public void initialize() {
203203
m_targetPose = m_targetPoseSupplier.get();
204204
} catch (Exception e) {
205205
e.printStackTrace();
206+
m_targetPose = pose;
206207
}
207208
m_controllerXY.setTolerance(m_distanceTolerance);
208209
m_controllerYaw.setTolerance(m_angleTolerance);
@@ -216,27 +217,24 @@ public void initialize() {
216217
*/
217218
@Override
218219
public void execute() {
220+
m_driveSubsystem.drive(chassisSpeeds(), true);
221+
}
222+
223+
/**
224+
* Calculates the {@code ChassisSpeeds} to move the robot toward the target.
225+
*
226+
* @return the calculated {@code ChassisSpeeds} to move the robot toward the
227+
* target
228+
*/
229+
public ChassisSpeeds chassisSpeeds() {
219230
var currentPose = m_poseSupplier.get();
220231
if (m_continuousTargeting)
221232
try {
222233
m_targetPose = m_targetPoseSupplier.get();
223234
} catch (Exception e) {
224235
// e.printStackTrace();
225236
}
226-
m_driveSubsystem.drive(chassisSpeeds(currentPose, m_targetPose), true);
227-
}
228-
229-
/**
230-
* Calculates the {@code ChassisSpeeds} to move from the current {@code Pose2d}
231-
* toward the target {@code Pose2d}.
232-
*
233-
* @param currentPose the current {@code Pose2d}
234-
* @param targetPose the target {@code Pose2d}
235-
* @return the calculated {@code ChassisSpeeds} to move from the current
236-
* {@code Pose2d} toward the target {@code Pose2d}
237-
*/
238-
public ChassisSpeeds chassisSpeeds(Pose2d currentPose, Pose2d targetPose) {
239-
Translation2d current2target = targetPose.getTranslation()
237+
Translation2d current2target = m_targetPose.getTranslation()
240238
.minus(currentPose.getTranslation());
241239
double velocityX = 0, velocityY = 0;
242240
double distance = current2target.getNorm();
@@ -247,7 +245,7 @@ public ChassisSpeeds chassisSpeeds(Pose2d currentPose, Pose2d targetPose) {
247245
velocityY = speed * current2target.getAngle().getSin();
248246
}
249247
double angularVelocityRadiansPerSecond = m_controllerYaw
250-
.calculate(currentPose.getRotation().getRadians(), targetPose.getRotation().getRadians());
248+
.calculate(currentPose.getRotation().getRadians(), m_targetPose.getRotation().getRadians());
251249
angularVelocityRadiansPerSecond = applyThreshold(angularVelocityRadiansPerSecond, kTurnMinAngularSpeed);
252250
return new ChassisSpeeds(velocityX, velocityY, angularVelocityRadiansPerSecond);
253251
}

src/main/java/frc/robot/subsystems/PoseEstimationSubsystem.java

Lines changed: 7 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package frc.robot.subsystems;
22

33
import static frc.robot.Constants.*;
4-
import static frc.robot.Constants.DriveConstants.*;
54

65
import java.util.HashMap;
76
import java.util.Map;
@@ -15,14 +14,12 @@
1514

1615
import edu.wpi.first.math.VecBuilder;
1716
import edu.wpi.first.math.Vector;
18-
import edu.wpi.first.math.controller.PIDController;
1917
import edu.wpi.first.math.estimator.SwerveDrivePoseEstimator;
2018
import edu.wpi.first.math.geometry.Pose2d;
2119
import edu.wpi.first.math.geometry.Rotation2d;
2220
import edu.wpi.first.math.geometry.Transform2d;
2321
import edu.wpi.first.math.geometry.Transform3d;
2422
import edu.wpi.first.math.geometry.Translation2d;
25-
import edu.wpi.first.math.kinematics.ChassisSpeeds;
2623
import edu.wpi.first.math.numbers.N3;
2724
import edu.wpi.first.math.util.Units;
2825
import edu.wpi.first.networktables.NetworkTableInstance;
@@ -78,20 +75,6 @@ public class PoseEstimationSubsystem extends SubsystemBase {
7875
*/
7976
private final StructPublisher<Pose2d> m_estimatedPosePublisher;
8077

81-
/**
82-
* The {@code PIDController} for controlling the robot in the x and y
83-
* dimensions in meters (input: error in meters, output: velocity in meters per
84-
* second).
85-
*/
86-
private PIDController m_controllerXY;
87-
88-
/**
89-
* The {@code PIDController} for controlling the robot in the yaw
90-
* dimension in radians (input: error in radians, output: velocity in radians
91-
* per second).
92-
*/
93-
private PIDController m_controllerYaw;
94-
9578
/**
9679
* Constructs a {@code PoseEstimationSubsystem}.
9780
*
@@ -113,9 +96,6 @@ public PoseEstimationSubsystem(DriveSubsystem driveSubsystem) {
11396
m_estimatedPosePublisher = NetworkTableInstance.getDefault()
11497
.getStructTopic("/SmartDashboard/Pose@PoseEstimationSubsystem", Pose2d.struct)
11598
.publish();
116-
m_controllerXY = new PIDController(kDriveP, kDriveI, kDriveD);
117-
m_controllerYaw = new PIDController(kTurnP, kTurnI, kTurnD);
118-
m_controllerYaw.enableContinuousInput(0, 2 * Math.PI);
11999
}
120100

121101
/**
@@ -169,54 +149,15 @@ public Pose2d getEstimatedPose() {
169149
}
170150

171151
/**
172-
* Calculates the {@code ChassisSpeeds} to move the robot toward the closest
173-
* {@code AprilTag}.
174-
*
175-
* @param robotToTag the {@code Tranform2d} representing the pose of the
176-
* {@code AprilTag} relative to the robot when the robot is aligned
177-
* @param distanceThresholdInMeters the maximum distance (in meters) within
178-
* which {@code AprilTag}s are considered
179-
* @return the calculated {@code ChassisSpeeds} to move the robot toward the
180-
* closest {@code AprilTag}
181-
*/
182-
public ChassisSpeeds chassisSpeedsTowardClosestTag(Transform2d robotToTag, double distanceThresholdInMeters) {
183-
var currentRobotPose = getEstimatedPose();
184-
var closestTagPose = closestTagPose(180, distanceThresholdInMeters);
185-
if (closestTagPose == null)
186-
return new ChassisSpeeds();
187-
var targetRobotPose = closestTagPose.plus(robotToTag);
188-
return chassisSpeeds(currentRobotPose, targetRobotPose, m_controllerXY, m_controllerYaw);
189-
}
190-
191-
/**
192-
* Calculates the {@code ChassisSpeeds} to move from the current {@code Pose2d}
193-
* toward the target {@code Pose2d}.
152+
* Returns the odometry-centric {@code Pose2d} that corresponds to the specified
153+
* field-centric {@code Pose2d}.
194154
*
195-
* @param currentPose the current {@code Pose2d}
196-
* @param targetPose the target {@code Pose2d}
197-
* @param controllerXY the {@code PIDController} for controlling the robot in
198-
* the x and y dimensions in meters (input: error in meters, output:
199-
* velocity in meters per second)
200-
* @param controllerYaw the {@code PIDController} for controlling the robot in
201-
* the yaw dimension in radians (input: error in radians, output:
202-
* velocity in radians per second)
203-
* @return the calculated {@code ChassisSpeeds} to move from the current
204-
* {@code Pose2d} toward the target {@code Pose2d}
155+
* @param fieldCentricPose a field-centric {@code Pose2d}
156+
* @return the odometry-centric {@code Pose2d} that corresponds to the specified
157+
* field-centric {@code Pose2d}
205158
*/
206-
public ChassisSpeeds chassisSpeeds(Pose2d currentPose, Pose2d targetPose, PIDController controllerXY,
207-
PIDController controllerYaw) {
208-
Translation2d current2target = targetPose.minus(currentPose).getTranslation()
209-
.rotateBy(m_driveSubsystem.getPose().getRotation());
210-
double velocityX = 0, velocityY = 0;
211-
double distance = current2target.getNorm();
212-
if (distance > 0) {
213-
double speed = Math.abs(controllerXY.calculate(distance, 0));
214-
velocityX = speed * current2target.getAngle().getCos();
215-
velocityY = speed * current2target.getAngle().getSin();
216-
}
217-
double angularVelocityRadiansPerSecond = controllerYaw
218-
.calculate(currentPose.getRotation().getRadians(), targetPose.getRotation().getRadians());
219-
return new ChassisSpeeds(velocityX, velocityY, angularVelocityRadiansPerSecond);
159+
public Pose2d odometryCentricPose(Pose2d fieldCentricPose) {
160+
return m_driveSubsystem.getPose().plus(fieldCentricPose.minus(getEstimatedPose()));
220161
}
221162

222163
/**

0 commit comments

Comments
 (0)