Skip to content

Commit 6ce3996

Browse files
committed
add vision
1 parent f0b8004 commit 6ce3996

3 files changed

Lines changed: 59 additions & 28 deletions

File tree

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

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,29 @@
55
package frc.robot;
66

77
import static frc.robot.RobotContainer.shooterState;
8-
import static frc.robot.config.VisionConfig.photonPoseEstimatorForward;
9-
import static frc.robot.config.VisionConfig.result;
108

119
import edu.wpi.first.epilogue.Epilogue;
1210
import edu.wpi.first.epilogue.Logged;
11+
import edu.wpi.first.math.geometry.Pose2d;
1312
import edu.wpi.first.wpilibj.DataLogManager;
1413
import edu.wpi.first.wpilibj.DriverStation;
1514
import edu.wpi.first.wpilibj.TimedRobot;
15+
import edu.wpi.first.wpilibj.Timer;
1616
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
1717
import edu.wpi.first.wpilibj2.command.Command;
1818
import edu.wpi.first.wpilibj2.command.CommandScheduler;
1919
import frc.robot.commands.FlywheelCommand;
2020
import frc.robot.config.TunerConstants;
21-
import frc.robot.config.VisionConfig;
2221
import frc.robot.subsystems.CommandSwerveDrivetrain;
23-
import java.util.Optional;
24-
import org.photonvision.EstimatedRobotPose;
2522

2623
@Logged
2724
public class Robot extends TimedRobot {
2825
private Command m_autonomousCommand;
2926
private final CommandSwerveDrivetrain drivetrain = TunerConstants.createDrivetrain();
27+
// last time we injected a synthetic vision measurement (seconds, FPGA time)
28+
private double m_lastSimVisionTime = 0.0;
29+
// whether we've injected a one-time offset vision measurement for testing
30+
private boolean m_injectedOffset = false;
3031

3132
private final RobotContainer m_robotContainer;
3233

@@ -39,22 +40,19 @@ public Robot() {
3940

4041
@Override
4142
public void robotPeriodic() {
42-
CommandScheduler.getInstance().run();
43-
Optional<EstimatedRobotPose> visionEst =
44-
VisionConfig.photonPoseEstimatorForward.estimateCoprocMultiTagPose(result);
45-
if (visionEst.isEmpty()) {
46-
visionEst = VisionConfig.photonPoseEstimatorForward.estimateLowestAmbiguityPose(result);
47-
} else {
48-
drivetrain.addVisionMeasurement(
49-
photonPoseEstimatorForward
50-
.estimateAverageBestTargetsPose(result)
51-
.get()
52-
.estimatedPose
53-
.toPose2d(),
54-
visionEst.get().timestampSeconds);
55-
}
5643
SmartDashboard.putString("shoot-state", shooterState);
5744
SmartDashboard.putString("shoot-on", FlywheelCommand.isOn);
45+
try {
46+
var pose = drivetrain.getState().Pose;
47+
SmartDashboard.putNumber("OdometryX", pose.getX());
48+
SmartDashboard.putNumber("OdometryY", pose.getY());
49+
SmartDashboard.putNumber("OdometryRotDeg", pose.getRotation().getDegrees());
50+
SmartDashboard.putNumber("SimVisionLastInject", m_lastSimVisionTime);
51+
System.out.printf(
52+
"ODOM X=%.3f Y=%.3f R=%.2f SimVision=%.3f\n",
53+
pose.getX(), pose.getY(), pose.getRotation().getDegrees(), m_lastSimVisionTime);
54+
} catch (Exception ignored) {
55+
}
5856
}
5957

6058
@Override
@@ -109,5 +107,25 @@ public void testExit() {}
109107
public void simulationInit() {}
110108

111109
@Override
112-
public void simulationPeriodic() {}
110+
public void simulationPeriodic() {
111+
double now = Timer.getFPGATimestamp();
112+
if (now - m_lastSimVisionTime >= 0.1) {
113+
m_lastSimVisionTime = now;
114+
try {
115+
var truePose = drivetrain.getState().Pose;
116+
// After 3 seconds, inject a single offset measurement (+1m X) to observe correction
117+
if (!m_injectedOffset && now > 3.0) {
118+
Pose2d offsetPose =
119+
new Pose2d(truePose.getX() + 1.0, truePose.getY(), truePose.getRotation());
120+
drivetrain.addVisionMeasurement(offsetPose, now);
121+
System.out.println("SIM INJECT: OFFSET +1.0m X at " + now);
122+
m_injectedOffset = true;
123+
} else {
124+
drivetrain.addVisionMeasurement(truePose, now);
125+
}
126+
} catch (Exception e) {
127+
DriverStation.reportError("Sim vision injection failed: " + e.getMessage(), false);
128+
}
129+
}
130+
}
113131
}

src/main/java/frc/robot/config/VisionConfig.java

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,25 @@
22

33
import edu.wpi.first.apriltag.AprilTagFieldLayout;
44
import edu.wpi.first.apriltag.AprilTagFields;
5+
import edu.wpi.first.math.Matrix;
6+
import edu.wpi.first.math.VecBuilder;
57
import edu.wpi.first.math.geometry.Rotation3d;
68
import edu.wpi.first.math.geometry.Transform3d;
9+
import edu.wpi.first.math.numbers.N1;
10+
import edu.wpi.first.math.numbers.N3;
711
import edu.wpi.first.math.util.Units;
8-
import java.util.Optional;
9-
import org.photonvision.EstimatedRobotPose;
1012
import org.photonvision.PhotonPoseEstimator;
1113
import org.photonvision.targeting.PhotonPipelineResult;
1214

1315
public class VisionConfig {
1416
public static PhotonPipelineResult result = new PhotonPipelineResult();
15-
public static final String CAMERA_NAME = "forwardAprilTag"; // left
17+
public static final String FRONT_CAMERA_NAME = "forwardAprilTag";
18+
// Per-camera measurement standard deviations: [x (m), y (m), theta (rad)]
19+
public static final Matrix<N3, N1> FRONT_VISION_STDDEVS =
20+
VecBuilder.fill(0.05, 0.05, Units.degreesToRadians(3.0));
21+
public static final Matrix<N3, N1> REAR_VISION_STDDEVS =
22+
VecBuilder.fill(0.10, 0.10, Units.degreesToRadians(5.0));
23+
public static final String REAR_CAMERA_NAME = "rearAprilTag";
1624
public static final AprilTagFieldLayout LAYOUT =
1725
AprilTagFieldLayout.loadField(AprilTagFields.k2026RebuiltAndymark);
1826
public static final PhotonPoseEstimator.PoseStrategy STRATEGY =
@@ -23,7 +31,10 @@ public class VisionConfig {
2331
Units.inchesToMeters(-11.55),
2432
Units.inchesToMeters(14.88),
2533
new Rotation3d(0.0, Units.degreesToRadians(16), 0.0));
26-
Optional<EstimatedRobotPose> visionEst = Optional.empty();
27-
public static PhotonPoseEstimator photonPoseEstimatorForward =
28-
new PhotonPoseEstimator(LAYOUT, FORWARD_CAMERA_POSITION);
34+
public static final Transform3d REAR_CAMERA_POSITION =
35+
new Transform3d(
36+
Units.inchesToMeters(0.0),
37+
Units.inchesToMeters(0.0),
38+
Units.inchesToMeters(0.0),
39+
new Rotation3d(0.0, Units.degreesToRadians(0.0), 0.0));
2940
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
import edu.wpi.first.wpilibj2.command.SubsystemBase;
44
import frc.robot.config.VisionConfig;
55
import org.photonvision.PhotonCamera;
6-
import org.photonvision.estimation.*;
76

87
public class Vision extends SubsystemBase {
9-
public static final PhotonCamera FrontCameraApril = new PhotonCamera(VisionConfig.CAMERA_NAME);
8+
public static final PhotonCamera FrontCameraApril =
9+
new PhotonCamera(VisionConfig.FRONT_CAMERA_NAME);
10+
public static final PhotonCamera RearCameraApril =
11+
new PhotonCamera(VisionConfig.REAR_CAMERA_NAME);
1012
}

0 commit comments

Comments
 (0)