55package frc .robot ;
66
77import static frc .robot .RobotContainer .shooterState ;
8- import static frc .robot .config .VisionConfig .photonPoseEstimatorForward ;
9- import static frc .robot .config .VisionConfig .result ;
108
119import edu .wpi .first .epilogue .Epilogue ;
1210import edu .wpi .first .epilogue .Logged ;
11+ import edu .wpi .first .math .geometry .Pose2d ;
1312import edu .wpi .first .wpilibj .DataLogManager ;
1413import edu .wpi .first .wpilibj .DriverStation ;
1514import edu .wpi .first .wpilibj .TimedRobot ;
15+ import edu .wpi .first .wpilibj .Timer ;
1616import edu .wpi .first .wpilibj .smartdashboard .SmartDashboard ;
1717import edu .wpi .first .wpilibj2 .command .Command ;
1818import edu .wpi .first .wpilibj2 .command .CommandScheduler ;
1919import frc .robot .commands .FlywheelCommand ;
2020import frc .robot .config .TunerConstants ;
21- import frc .robot .config .VisionConfig ;
2221import frc .robot .subsystems .CommandSwerveDrivetrain ;
23- import java .util .Optional ;
24- import org .photonvision .EstimatedRobotPose ;
2522
2623@ Logged
2724public 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}
0 commit comments