Skip to content

3D Field Visualization

MARSLib’s interactive 3D field visualizer helps you understand field layouts, AprilTag positions, and robot placement before you ever touch a real robot.

  • 2024 Crescendo: 54’ × 27’ field with source and amp zones.
  • 2023 Charged Up: Previous year’s field layout.
  • 2022 Rapid React: Historical field layouts.
  • Accurate swerve drive robot model.
  • Real-time position updates.
  • Heading and orientation display.
  • Module position indicators.
  • Official tag positions for current game.
  • Interactive 3D tag visualization.
  • Pose reference for vision testing.
  • Mouse: Rotate field view.
  • Scroll: Zoom in/out.
  • Right-click: Pan view.
  • Responsive: Works on all screen sizes.
<FieldVisualizer
field="CRESCENDO_2024"
showRobot={true}
showAprilTags={true}
/>
<FieldVisualizer
field="CRESCENDO_2024"
robotPosition={{
x: 8.0, // 8 meters from red wall
y: 4.0, // 4 meters from side wall
heading: Math.PI / 4 // 45 degrees
}}
/>
<FieldVisualizer
field="CRESCENDO_2024"
gamePieces={20} // Show 20 game pieces
showRobot={false}
/>
    
flowchart TD
  A["Field Length: 16.5m 54'"]
  B["Field Width: 8.2m 27'"]
  C["Red Alliance Zone: 3m deep"]
  D["Blue Alliance Zone: 3m deep"]
  E["Source Zones: 2m deep"]
  F["Amp Zones: 2.5m deep"]
  
  A --> G["Field Layout"]
  B --> G
  C --> G
  D --> G
  E --> G
  F --> G
  
  style A fill:#1a1a1a,stroke:#B32416,stroke-width:2px,color:#fff
  style B fill:#1a1a1a,stroke:#B32416,stroke-width:2px,color:#fff
  style C fill:#1a1a1a,stroke:#B32416,stroke-width:1px,color:#ff6b6b
  style D fill:#1a1a1a,stroke:#29b6f6,stroke-width:1px,color:#6bb6ff
  style E fill:#1a1a1a,stroke:#2a2a2a,stroke-width:1px,color:#e8e8e8
  style F fill:#1a1a1a,stroke:#2a2a2a,stroke-width:1px,color:#e8e8e8
  style G fill:#0a0a0a,stroke:#2a2a2a,stroke-width:2px,color:#e8e8e8

  

Red Alliance (Tags 1-6):

  • Tags 1-4: Along red alliance wall.
  • Tags 5-6: On source and amp zones.

Blue Alliance (Tags 7-12):

  • Tags 7-10: Along blue alliance wall.
  • Tags 11-12: On source and amp zones.

Use field visualizer to verify vision targeting.

// Test vision alignment to specific tag
Pose2d targetPose = new Pose2d(15.013, 2.743, new Rotation2d()); // Tag 2
Command alignCommand = new AlignToTagCommand(vision, drive, targetPose);
alignCommand.schedule();

Plan autonomous paths using field coordinates.

// Create path to pick up game piece
List<Pose2d> waypoints = List.of(
new Pose2d(1.5, 2.0, Rotation2d.fromDegrees(0)), // Start
new Pose2d(5.0, 2.0, Rotation2d.fromDegrees(45)), // Pick up piece
new Pose2d(8.0, 4.0, Rotation2d.fromDegrees(90)), // Move to center
new Pose2d(12.0, 6.0, Rotation2d.fromDegrees(180)) // Score
);
// Get field dimensions
const field2024 = FIELDS.CRESCENDO_2024;
console.log(field2024.dimensions); // { length: 16.541, width: 8.211, ... }
// Create layout with AprilTags
const layout = createFieldLayout('CRESCENDO_2024');
console.log(layout.aprilTags); // Array of tag positions
// Spawn game pieces
const pieces = spawnGamePieces('CRESCENDO_2024', 10);
console.log(pieces); // Array of game piece positions
  • X-axis: Length of field (0 to 16.5m)
  • Y-axis: Width of field (0 to 8.2m)
  • Z-axis: Height (0 = field surface)
  • Heading: Radians, 0 = facing +X direction.
const isValid = isInField(8.0, 4.0, field2024.dimensions);
console.log(isValid); // true - center of field is valid
  • Limit game pieces: Show 10-20 pieces for best performance.
  • Disable robot: Set showRobot={false} when not needed.
  • Field-only: Use minimal props for field-only visualization.
  • Rendering: <50ms per frame.
  • Memory usage: <50MB for full visualization.
  • Load time: <1 second for initial render.

Visualize autonomous routines before deploying.

// Plan path in simulation
Command auto = getPathPlannerAuto("ThreePiecePickup");
auto.schedule();
// Use field visualizer to verify path
// Check robot position at each waypoint

Verify AprilTag positions for vision targeting.

// Test vision to each tag
for (int tagId = 1; tagId <= 12; tagId++) {
Pose2d tagPose = getTagPose(tagId);
Command align = new AlignToTagCommand(vision, drive, tagPose);
align.schedule();
// Verify alignment using field visualizer
}

Plan starting positions and strategy.

// Blue alliance starting positions
Pose2d blue1 = new Pose2d(13.5, 2.0, Rotation2d.fromDegrees(180));
Pose2d blue2 = new Pose2d(13.5, 4.0, Rotation2d.fromDegrees(180));
Pose2d blue3 = new Pose2d(13.5, 6.0, Rotation2d.fromDegrees(180));

Create custom field layouts for practice.

const customField = {
name: 'Practice Field',
dimensions: {
length: 16.541,
width: 8.211,
allianceDepth: 3.0,
sourceDepth: 2.0,
ampDepth: 2.5,
},
gamePieces: [],
};

Overlay autonomous paths on field.

// Record robot trajectory during auto
List<Pose2d> trajectory = new ArrayList<>();
@Override
public void periodic() {
trajectory.add(drive.getPose());
}
// Visualize trajectory in AdvantageScope
Logger.recordOutput("Auto/TrajectoryX", trajectory.stream().mapToDouble(p -> p.getX()).toArray());
Logger.recordOutput("Auto/TrajectoryY", trajectory.stream().mapToDouble(p -> p.getY()).toArray());

Simulate interaction with other robots.

// Add defender robot to visualization
Pose2d defenderPos = new Pose2d(8.0, 3.0, Rotation2d.fromDegrees(90));
// Plan path around defender

Ready to visualize? Use the field visualizer to plan your autonomous routines!