Package frc.rebuilt

Class FuelPhysicsSim

java.lang.Object
frc.rebuilt.FuelPhysicsSim

public class FuelPhysicsSim extends Object
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
 
  • Constructor Details

    • FuelPhysicsSim

      public FuelPhysicsSim(String tableKey)
      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

      public FuelPhysicsSim(String tableKey, FuelPhysicsSim.PhysicsConfig config)
      New sim with custom physics config.
      Parameters:
      tableKey - where to publish in NetworkTables
      config - 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 full
      poseSupplier - field-relative pose supplier
      speedsSupplier - 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 supplier
      speedsSupplier - 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 frame
      xMax - back edge in robot frame
      yMin - left edge in robot frame
      yMax - right edge in robot frame
      active - returns true when the intake is actually running
      callback - 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

      public void launchBall(Translation3d pos, Translation3d vel, double spinRPM)
      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

      public void launchBall(Translation3d pos, Translation3d vel, Translation3d omega)
      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

      public void spawnBall(Translation3d pos)
      Drop a ball at this position, sitting on the ground.
    • spawnBall

      public void spawnBall(Translation3d pos, Translation3d vel)
      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

      public List<Translation3d> getBallPositions()
    • getBallVelocities

      public List<Translation3d> getBallVelocities()
    • getBallOmegas

      public List<Translation3d> getBallOmegas()
    • getConfig

      public FuelPhysicsSim.PhysicsConfig getConfig()
    • setConfig

      public void setConfig(FuelPhysicsSim.PhysicsConfig config)
    • setDeterministic

      public void setDeterministic(long seed)
      Lock the RNG seed so tests are repeatable.
    • getTotalKineticEnergy

      public double getTotalKineticEnergy()
    • getTotalPotentialEnergy

      public double getTotalPotentialEnergy()
    • getTotalMomentum

      public Translation3d 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

      public FuelPhysicsSim.ScoringTarget getBlueHub()
    • getRedHub

      public FuelPhysicsSim.ScoringTarget 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()