REBUILT 2026 supports full WPILib desktop simulation including ground-truth drivetrain physics, vision simulation, and fuel (game piece) trajectory simulation. All simulation-specific logic is isolated inside a singleDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/robototes/REBUILT2026/llms.txt
Use this file to discover all available pages before exploring further.
SimWrapper class so that Robot and the rest of the codebase remain unaware of whether they are running on a real robot or on a desktop.
Running the simulator
Start the simulation
Run the Gradle simulation task from the project root:The WPILib Simulation GUI opens automatically because
wpi.sim.addGui().defaultEnabled = true is set in build.gradle.High-fidelity vision (optional)
Add This flag is read as a JVM system property (
-PhighFidelityVision=true to switch all three cameras from 320 × 240 to 1280 × 800 with tighter calibration noise:highFidelityVision) inside VisionSimConstants and affects resolution, calibration error, minimum target area, and distance-variance scale.JVM heap flags You do not need to set these manually.
-Xmx2G -Xms2G are applied automatically to every simulate* Gradle task via build.gradle:SimWrapper — unified simulation entry point
SimWrapper is the single object that owns every simulation concern. It is constructed in Robot only when Robot.isSimulation() is true, and the reference is null on a real robot:
SimWrapper holds:
| Field | Type | Purpose |
|---|---|---|
m_groundTruthSim | GroundTruthSimInterface | Tracks the real physics pose independently of odometry |
m_visionSims | List<VisionSimInterface> | One VisionSim per camera (three cameras: A, B, C) |
m_sharedVisionSystemSim | VisionSystemSim | Shared PhotonVision scene — updated once per cycle |
m_simDebugField | Field2d | SmartDashboard field widget for pose visualization |
m_showVisionOnField | ShowVisionOnField | Draws estimated pose, module positions, and ground-truth pose on the Field2d |
m_groundTruthPosePublisher | StructPublisher<Pose2d> | Publishes DriveState/GroundTruthPose to NetworkTables for AdvantageScope |
SimWrapper lifecycle
robotPeriodic()
Called from Robot.robotPeriodic() before VisionSubsystem.update(). This ensures that the Limelight NetworkTables entries are populated with fresh synthetic vision data before any code in the same loop reads them:
SimWrapper.robotPeriodic(), every camera’s VisionSimInterface::periodic is called, which runs pose estimation and writes botpose_wpiblue, botpose_orb_wpiblue, and all other Limelight-format entries to the relevant limelight-* NetworkTable.
simulationPeriodic()
Called from Robot.simulationPeriodic(). Runs in order:
- Ground-truth physics —
m_groundTruthSim.simulationPeriodic()integrates the drivetrain chassis speeds to advance the ground-truth pose and publishes telemetry to SmartDashboard. - Vision scene update —
m_sharedVisionSystemSim.update(groundTruthPose)moves all simulated cameras to the ground-truth position so they see the correct AprilTags. - NT publish —
m_groundTruthPosePublisher.set(groundTruthPose)sends the ground-truth pose toDriveState/GroundTruthPose. - Field2d visualization —
m_showVisionOnFielddraws both the odometry-estimated pose (with swerve modules) and the ground-truth pose on the sharedField2d.
GroundTruthSim
GroundTruthSim (created by GroundTruthSimFactory) drives the CTRE SwerveDrivetrain simulation loop. Each call to simulationPeriodic() integrates the drivetrain’s reported ChassisSpeeds forward in time to advance a Pose2d that represents the robot’s physical location — independent of any drift introduced into the pose estimator. The ground-truth pose is published to SmartDashboard under Sim/GroundTruth/* and to DriveState/GroundTruthPose via NetworkTables.
RobotSim and FuelSim
RobotSim wraps FuelSim into a single game-piece simulation object. It is constructed alongside SimWrapper in Robot:
RobotSim registers the robot’s geometry (0.8 m × 0.8 m, 0.7 m bumper height) and an intake bounding box with FuelSim, and starts the physics thread.
resetFuelSim() is called at the start of autonomous to clear all field fuel and respawn the starting configuration:
FuelSim.launchFuel() models fuel game pieces being launched with full ballistics (gravity, optional air resistance, coefficient-of-restitution collisions with the field, hubs, and trench). The sim launcher command calls:
Fuel Simulation/Fuels and the running score is published to Fuel Simulation/Score.