Package frc.rebuilt
Class FuelPhysicsSim
java.lang.Object
frc.rebuilt.FuelPhysicsSim
Full-field ball physics simulation for FRC 2026 REBUILT. Handles drag, Magnus lift, friction,
ball-ball collisions, wall bounces, hub scoring, sleeping, CCD, and robot interaction. Single
file, only depends on WPILib (wpimath + ntcore). Drop it into your sim and watch balls fly.
Physics: symplectic Euler integration, 3D angular velocity for Magnus (omega x v cross product), Coulomb friction with spin transfer, sequential impulse collision solver with warm starting and Baumgarte stabilization. Spatial hashing for ball-ball broadphase. Ball sleeping keeps 350+ resting balls under 2ms/tick.
Usage:
FuelPhysicsSim ballSim = new FuelPhysicsSim("Sim/Fuel");
ballSim.enable();
ballSim.placeFieldBalls(); // spawns all the game pieces
// in simulationPeriodic():
ballSim.configureRobot(width, length, bumperH, poseSupplier, speedsSupplier);
ballSim.tick(); // runs physics, publishes to NT
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classPhysics feature toggles.static classA hub that can be scored in.static classOne ball in the simulation. -
Constructor Summary
ConstructorsConstructorDescriptionDefault constructor, publishes to "Sim/FuelPositions".FuelPhysicsSim(String tableKey) New sim with default physics config.FuelPhysicsSim(String tableKey, FuelPhysicsSim.PhysicsConfig config) New sim with custom physics config. -
Method Summary
Modifier and TypeMethodDescriptionvoidaddIntakeZone(double xMin, double xMax, double yMin, double yMax, BooleanSupplier active) Add an intake zone without a callback.voidaddIntakeZone(double xMin, double xMax, double yMin, double yMax, BooleanSupplier active, Runnable callback) Add an intake zone.voidadvancePhysics(double dt) Advance physics by dt seconds.voidRemove every ball from the sim.voidconfigureRobot(double width, double length, double bumperHeight, int hopperSize, Supplier<Pose2d> poseSupplier, Supplier<ChassisSpeeds> speedsSupplier) Tell the sim about your robot so it can handle bumper collisions and intake pickup.voidconfigureRobot(double width, double length, double bumperHeight, Supplier<Pose2d> poseSupplier, Supplier<ChassisSpeeds> speedsSupplier) Tell the sim about your robot so it can handle bumper collisions and intake pickup.voiddisable()Pause the sim.voidenable()Turn the sim on.static doubleintstatic doublestatic doubleintintintstatic doublestatic doublestatic doublestatic doubledoublestatic doublestatic doubleintintintdoubleintdoubleintbooleanIs the sim running?voidlaunchBall(Translation3d pos, Translation3d vel, double spinRPM) Shoot a ball into the sim.voidlaunchBall(Translation3d pos, Translation3d vel, Translation3d omega) Shoot a ball with full 3D spin control.voidSpawn all game pieces in their starting positions (neutral zone + depots).voidPush ball positions and sim stats to NetworkTables for visualization.voidvoidvoidsetDeterministic(long seed) Lock the RNG seed so tests are repeatable.voidspawnBall(Translation3d pos) Drop a ball at this position, sitting on the ground.voidspawnBall(Translation3d pos, Translation3d vel) Drop a ball with some initial velocity.voidtick()Step the sim forward one period (20ms) and publish ball positions to NT.
-
Constructor Details
-
FuelPhysicsSim
New sim with default physics config. Publishes ball positions to the given NT path.- Parameters:
tableKey- where to publish in NetworkTables (e.g. "Sim/Fuel")
-
FuelPhysicsSim
New sim with custom physics config.- Parameters:
tableKey- where to publish in NetworkTablesconfig- physics feature toggles and tuning
-
FuelPhysicsSim
public FuelPhysicsSim()Default constructor, publishes to "Sim/FuelPositions".
-
-
Method Details
-
enable
public void enable()Turn the sim on. You still need to call tick() every cycle. -
disable
public void disable()Pause the sim. Balls freeze in place. -
isRunning
public boolean isRunning()Is the sim running? -
configureRobot
public void configureRobot(double width, double length, double bumperHeight, int hopperSize, Supplier<Pose2d> poseSupplier, Supplier<ChassisSpeeds> speedsSupplier) Tell the sim about your robot so it can handle bumper collisions and intake pickup.- Parameters:
width- robot width along Y axis (m)length- robot length along X axis (m)bumperHeight- bumper height (m)hopperSize- maximum number of balls the robot's hopper can hold; intake stops when fullposeSupplier- field-relative pose supplierspeedsSupplier- field-relative chassis speeds supplier
-
configureRobot
public void configureRobot(double width, double length, double bumperHeight, Supplier<Pose2d> poseSupplier, Supplier<ChassisSpeeds> speedsSupplier) Tell the sim about your robot so it can handle bumper collisions and intake pickup. Hopper capacity is unlimited.- Parameters:
width- robot width along Y axis (m)length- robot length along X axis (m)bumperHeight- bumper height (m)poseSupplier- field-relative pose supplierspeedsSupplier- field-relative chassis speeds supplier
-
addIntakeZone
public void addIntakeZone(double xMin, double xMax, double yMin, double yMax, BooleanSupplier active, Runnable callback) Add an intake zone. Balls that enter this box (in robot-relative coords) get picked up.- Parameters:
xMin- front edge in robot framexMax- back edge in robot frameyMin- left edge in robot frameyMax- right edge in robot frameactive- returns true when the intake is actually runningcallback- fires when a ball gets picked up
-
addIntakeZone
public void addIntakeZone(double xMin, double xMax, double yMin, double yMax, BooleanSupplier active) Add an intake zone without a callback. -
launchBall
Shoot a ball into the sim.- Parameters:
pos- where the ball leaves the launcher (field frame, meters)vel- launch velocity (field frame, m/s)spinRPM- backspin in RPM (positive = backspin = Magnus lift)
-
launchBall
Shoot a ball with full 3D spin control.- Parameters:
pos- launch position (field frame, meters)vel- launch velocity (field frame, m/s)omega- 3D angular velocity (rad/s)
-
spawnBall
Drop a ball at this position, sitting on the ground. -
spawnBall
Drop a ball with some initial velocity. -
clearBalls
public void clearBalls()Remove every ball from the sim. -
placeFieldBalls
public void placeFieldBalls()Spawn all game pieces in their starting positions (neutral zone + depots). -
tick
public void tick()Step the sim forward one period (20ms) and publish ball positions to NT. Does nothing if the sim isn't enabled. -
advancePhysics
public void advancePhysics(double dt) Advance physics by dt seconds. Splits into subticks for stability.- Parameters:
dt- time to advance (seconds)
-
publishPositions
public void publishPositions()Push ball positions and sim stats to NetworkTables for visualization. -
getBallCount
public int getBallCount() -
getBallsInFlight
public int getBallsInFlight() -
getBallsOnGround
public int getBallsOnGround() -
getBallPositions
-
getBallVelocities
-
getBallOmegas
-
getConfig
-
setConfig
-
setDeterministic
public void setDeterministic(long seed) Lock the RNG seed so tests are repeatable. -
getTotalKineticEnergy
public double getTotalKineticEnergy() -
getTotalPotentialEnergy
public double getTotalPotentialEnergy() -
getTotalMomentum
-
getTotalLaunched
public int getTotalLaunched() -
getTotalScored
public int getTotalScored() -
getTotalIntaked
public int getTotalIntaked() -
getLastLaunchSpeed
public double getLastLaunchSpeed() -
getBlueScore
public int getBlueScore() -
getRedScore
public int getRedScore() -
getBlueHub
-
getRedHub
-
getSleepingBallCount
public int getSleepingBallCount() -
getFieldLength
public static double getFieldLength() -
getFieldWidth
public static double getFieldWidth() -
getBallRadius
public static double getBallRadius() -
getBallMass
public static double getBallMass() -
getMomentOfInertia
public static double getMomentOfInertia() -
getDragAccelFactor
public static double getDragAccelFactor() -
getMagnusAccelFactor
public static double getMagnusAccelFactor() -
getFieldCOR
public static double getFieldCOR() -
getBallBallCOR
public static double getBallBallCOR() -
resetCounters
public void resetCounters()
-