Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FRC-Robot-Shooting-While_Moving-Simulator

A real-time 3D desktop simulator for FRC teams to visualize shoot-on-the-move behavior: robot motion, turret aiming, flywheel/hood setpoints, latency-aware prediction, actuator limits, and ball trajectories.

License: The Unlicense (do whatever you want)


What this is for

This repo is a tuning + teaching lab:

  • see how latency + actuator slew limits affect “would we actually shoot?”
  • validate solver stability (no crazy setpoint jitter)
  • understand lead/compensation when the robot is translating + rotating
  • iterate on tolerances and constraints before you burn practice time on a real bot

It’s not a full WPILib sim and it’s not a perfect physics engine—this is a visual + practical approximation that’s fast enough to run interactively.


Quickstart

Requirements

  • Python 3.12+ recommended
  • Main deps:
    • numpy
    • PyQt5
    • pyvista
    • pyvistaqt

Install (venv recommended)

Windows (PowerShell):

python -m venv .venv
. .\.venv\Scripts\Activate.ps1
pip install -U pip
pip install numpy pyqt5 pyvista pyvistaqt

Linux / macOS:

python3 -m venv .venv
source .venv/bin/activate
pip install -U pip
pip install numpy pyqt5 pyvista pyvistaqt

Run

python main.py

Controls / How to use

Modes (automatic)

The simulator has two “shooting behaviors” depending on where you are:

1) GOAL mode (inside the scoring zone)

  • When the robot is inside the scoring zone, the sim ignores Space and runs normal “shoot into goal” logic.

  • Fire decision is based on:

    • in scoring zone
    • actuators READY
    • shot sim indicates a hit (within hit radius)

2) DUMP mode (hold Space outside the zone)

  • When the robot is outside the scoring zone, holding Space enables a “zone dump” behavior:

    • turret is commanded toward a world-fixed direction (World X-)
    • if that yaw is impossible (turret limits), it picks the closest reachable yaw
    • it stays active while Space is held even if you keep driving / turning
    • it will still shoot even if the dump shot wouldn’t hit the goal (that’s the point: dumping)

Safety behavior in dump mode:

  • if the robot spins and the commanded turret angle would cause a big discontinuous jump (the “360 realignment” vibe), firing is temporarily blocked for a short moment so it doesn’t spam shots during the weird transition.

Keyboard (teleop)

  • Arrow keys: drive robot
  • Shift: slow mode (scale down translation + rotation)
  • M: toggle teleop on/off
  • Space: dump mode only outside scoring zone (inside zone it does nothing)

UI tabs

  • Params: change robot constraints, shooter constraints, physics, solver tuning
  • State: watch live computed values (ready, miss distance, predicted fire time, etc.)

How the shooting pipeline works (high level)

Each tick (fixed-step ~60 Hz):

  1. Robot motion

    • either autopilot path (swerve-ish) or teleop (arrow keys)
    • translation and rotation are accel-limited
  2. Solver (throttled)

    • runs ~20–30 Hz (not every render frame)
    • predicts robot pose at fire_latency + time_to_ready
    • finds turret yaw / rpm (and optionally hood) to minimize miss
  3. Actuators step

    • turret, hood, flywheel move toward the desired setpoints with rate limits
  4. READY gate

    • checks yaw/hood/rpm errors vs tolerances
  5. Fire gate

    • if firing conditions are true, emits pulses at a configured ball rate (visual rate limiter)
  6. Visualization

    • current shot path, predicted (planned) shot path, vectors, ghost pose, trail

Fire logic (what makes a ball “leave”)

There are 3 layers:

1) “READY”

Ready means the modeled actuators are close enough:

  • turret yaw error ≤ turret_ready_tol_deg
  • hood error ≤ hood_ready_tol_deg
  • rpm error ≤ rpm_ready_tol

2) “Would fire”

  • GOAL mode: READY && in_zone && sim_hit_now
  • DUMP mode: READY && space_held && outside_zone && (not in dump realign block window)

3) Fire rate limiter (ball stream)

Even if would_fire stays true, balls spawn at a max rate using FireGate:

  • ball rate is controlled by the UI (Ball rate (balls/s))

Coordinate system + field model

  • Field axes:

    • x = field length direction
    • y = field width direction
  • The field dimensions in make_field() currently assume:

    • field: 57 ft (x) × 24 ft (y)
    • scoring zone: 182.11 in in the x direction (full width in y)
  • Goal is a 3D point (or “top entry” ring model if you switch goal_type).


Parameter reference (what each knob means)

Below is a “what it does” map matching the Params UI and ShooterParams.

Target (Goal)

  • Goal X/Y/Z (m): the target point in field coordinates.

Robot Motion (Autopilot)

  • Path speed multiplier: scales the autopilot velocity profile frequency/magnitude.
  • Path radius multiplier: changes how wide the autopilot loop is.
  • Max speed (m/s) (vmax): speed clamp for robot translation.
  • Max accel (m/s²) (amax): accel clamp for robot translation.

Teleop (Keyboard)

  • Enable teleop: arrow keys drive instead of autopilot.
  • Teleop max speed (m/s): teleop translation speed cap.
  • Teleop max accel (m/s²): teleop translation accel cap.
  • Teleop omega max (deg/s): yaw rate limit.
  • Teleop alpha max (deg/s²): yaw accel limit.
  • Shift slow factor: multiplies teleop commands while Shift is held.

Turret Constraints

  • Turret min/max (deg) (turret_min_deg, turret_max_deg): hard yaw travel limits relative to robot.
  • Turret slew rate (deg/s) (turret_slew_rate_dps): max turret speed.
  • Turret ready tolerance (deg) (turret_ready_tol_deg): max yaw error allowed for READY.

Hood (Elevation) Constraints

  • Solve hood angle (solve_for_hood): if on, solver selects hood; if off, uses fixed hood.
  • Hood angle (deg) (hood_fixed_deg): fixed elevation when not solving hood.
  • Hood min/max (deg): hood travel limits.
  • Hood rate (deg/s) (hood_rate_dps): hood speed limit.
  • Hood ready tolerance (deg) (hood_ready_tol_deg): max hood error allowed for READY.

Flywheel (RPM) Constraints

  • Solve flywheel RPM (auto) (solve_for_rpm): if on, solver picks RPM; if off, you can effectively “lock” it.
  • RPM init: initial flywheel rpm at reset and when params re-apply.
  • RPM min/max: solver/search clamp range.
  • Flywheel accel limit (rpm/s) (flywheel_accel_rpm_s): spool rate limit.
  • RPM ready tolerance (rpm) (rpm_ready_tol): max rpm error allowed for READY.
  • Wheel radius (m) (wheel_radius_m): used for rpm→exit-speed mapping.
  • Slip factor (slip_factor): accounts for ball slip/contact losses.
  • Exit speed factor (exit_speed_factor): additional scaling to match reality.

Exit speed approx: exit_speed = wheel_surface_speed * slip_factor * exit_speed_factor

Ball Physics

  • Enable drag (enable_drag): aerodynamic drag on the ball.
  • Cd (Cd): drag coefficient.
  • Enable Magnus (enable_magnus): simplified spin lift model.
  • Magnus k (magnus_k): lift scaling constant (very approximate).
  • Spin (rev/s) (spin_rps): spin rate used for Magnus.
  • Enable fired balls (visual): spawns moving sphere actors (purely visual).
  • Ball rate (balls/s): max firing pulse rate when would_fire is true.

Solver + Smoothing

  • Fire latency (s) (fire_latency_s): delay between “decide to shoot” and ball release.
  • Hit radius (m) (hit_radius_m): how close to the goal counts as a hit (also used in “ok”).
  • Sim dt (s) (rt_dt): time step for internal trajectory sim.
  • Sim tmax (s) (rt_tmax): max simulated time-of-flight.
  • Yaw/RPM/Hood samples (rt_*_samples): legacy UI knobs kept for compatibility; the current “instant solver” uses its own instant_* parameters internally.
  • Output smoothing τ (s) (output_smooth_tau_s): low-pass filtering on setpoints (reduces twitch).
  • Continuity weight (continuity_weight): penalizes big jumps from previous solution (reduces snapping).

What you’re seeing in the 3D view

  • Robot + turret (solid): current pose
  • Ghost robot + turret (transparent): predicted pose at fire time
  • Velocity vector (green) and accel vector (orange)
  • Aim line (yellow): where the turret is pointing from predicted pose
  • Shot path now:
    • green if it would fire (and is “good” under current logic)
    • red otherwise
  • Planned path (blue/gray): trajectory from predicted pose + desired setpoints

Repo structure

project/
  main.py          # entry point
  src/
    sim_window.py    # Qt window + render + tick loop + gating logic
    ui_panels.py     # Params + State UI
    field_world.py   # field geometry + zones + robot motion models
    shooter_logic.py # physics, solver, actuator stepping, dump/landing helper
    ball_logic.py    # pooled ball actors + fire rate limiter
    geom2d.py        # small vector helpers
  assets/
    FieldImage2026.svg

Notes / realism disclaimer

This is simplified on purpose:

  • no wheel slip changes, ball compression, hood friction, shot-to-shot variance
  • drag/magnus are approximations
  • field obstacles aren’t modeled

But it is great for: constraints + latency intuition + solver stability and tuning tradeoffs.


About

A real-time 3D shooter simulator for FRC teams to simulate field oriented shooting on the move for the 2026 game Rebuilt

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages