Package jsim.field

Class FieldSimulator

java.lang.Object
jsim.field.FieldSimulator

public final class FieldSimulator extends Object
High-level FRC field simulator that combines a SimWorld with pre-built field geometry and game-piece management tailored to AdvantageScope integration.

The field is static — it deflects game pieces and robots but cannot itself be moved. Game pieces are dynamic rigid bodies that collide with the field and each other. Robots are dynamic bodies that the user drives externally (e.g. via SimBody.getActuator() or SimBody.setPose()).

Typical usage:


 FieldSimulator sim = new FieldSimulator();

 SimBody robot = sim.addRobot(new SimBodyBuilder("Robot")
     .pose(new Pose3d(2, 4, 0.05, new Rotation3d()))
     .mass(50)
     .boxCollider(0.45, 0.45, 0.3)
     .material(Material.CARPET)
     .noGravity()
     .fixedRotation());

 GamePieceGripper gripper = sim.createGripper(robot, new Translation3d(0.5, 0, 0.1));

 GamePiece note = sim.spawnGamePiece("Note", new SimBodyBuilder("Note0")
     .position(8, 4, 0.18)
     .mass(0.235)
     .sphereCollider(0.18)
     .material(Material.RUBBER));

 // In simulationPeriodic():
 sim.step();
 Pose3d[] notePoses = sim.getGamePiecePoses("Note");
 Logger.recordOutput("FieldSimulation/NotePoses", notePoses);
 
  • Constructor Details

    • FieldSimulator

      public FieldSimulator()
      Create a simulator with the standard FRC field (16.46 m × 8.23 m) and the default 20 ms fixed timestep.
    • FieldSimulator

      public FieldSimulator(double fixedTimestepSeconds)
      Create a simulator with the standard FRC field and a custom fixed timestep.
      Parameters:
      fixedTimestepSeconds - physics timestep in seconds
    • FieldSimulator

      public FieldSimulator(double fixedTimestepSeconds, double fieldLengthM, double fieldWidthM)
      Create a simulator with a custom field size and timestep.
      Parameters:
      fixedTimestepSeconds - physics timestep in seconds
      fieldLengthM - field length along X (metres)
      fieldWidthM - field width along Y (metres)
  • Method Details

    • addRobot

      public SimBody addRobot(SimBodyBuilder builder)
      Add a robot body to the simulation.

      Robots are typically configured with .noGravity().fixedRotation() and driven by setting their pose or actuator forces each tick.

      Parameters:
      builder - configured body builder
      Returns:
      the resulting SimBody
    • spawnGamePiece

      public GamePiece spawnGamePiece(String variant, SimBodyBuilder builder)
      Spawn a game piece in the world. The piece collides with the field (floor and walls) and any robot bodies, and can be picked up by a GamePieceGripper.

      The variant string must match the gamepiece key in the AdvantageScope asset configuration (e.g. "Note" for 2024 Crescendo, "Coral" for 2025 Reefscape).

      Parameters:
      variant - AdvantageScope gamepiece variant name
      builder - configured body builder for physics properties
      Returns:
      the new GamePiece handle
    • removeGamePiece

      public void removeGamePiece(GamePiece piece)
      Remove a game piece from the simulation, releasing it from any gripper that holds it first.
      Parameters:
      piece - the piece to remove
    • createGripper

      public GamePieceGripper createGripper(SimBody robot, edu.wpi.first.math.geometry.Translation3d intakeOffset)
      Create a GamePieceGripper that mounts on robot at intakeOffset (in robot-local frame). The gripper's GamePieceGripper.update() is called automatically by step().
      Parameters:
      robot - the robot body the gripper is mounted on
      intakeOffset - hold-point position in the robot's local frame (metres)
      Returns:
      a new GamePieceGripper
    • step

      public void step()
      Advance physics by the configured fixed timestep, then update all active grippers so held pieces track the robot.

      Call once per robot loop iteration from simulationPeriodic().

    • getGamePiecePoses

      public edu.wpi.first.math.geometry.Pose3d[] getGamePiecePoses(String variant)
      Return the current Pose3d of every game piece matching variant.

      Log the returned array to AdvantageScope via AdvantageKit or NT4:

      
       Logger.recordOutput("FieldSimulation/NotePoses", sim.getGamePiecePoses("Note"));
       
      Parameters:
      variant - the variant name to filter by (case-sensitive)
      Returns:
      array of poses, one per matching piece, in spawn order
    • getAllGamePiecePoses

      public Map<String,edu.wpi.first.math.geometry.Pose3d[]> getAllGamePiecePoses()
      Return all game piece poses grouped by variant. Useful when multiple game piece types exist on the field simultaneously.
      Returns:
      map from variant name to pose array, in spawn order within each variant
    • getGamePieces

      public List<GamePiece> getGamePieces()
      Unmodifiable view of all game pieces currently in the simulation.
      Returns:
      all game pieces in spawn order
    • getWorld

      public SimWorld getWorld()
      Direct access to the underlying SimWorld for advanced use — custom force generators, additional bodies, sensors, etc.
      Returns:
      the underlying physics world