Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions SimLoop/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ does **not** do, and a flat index written for AI agents. Start at `docs/index.md
| `sim` | `FakeTimer` (the one clock), `ScenarioRunner` (the fixed-timestep tick loop plus the whole PsiKit lifecycle, and `runUntil` for a run of unknown length), and `RlogDecodedCompare` (field-by-field RLOG comparison for determinism tests). |
| `sim/live` | Live drive: a recorded, replayable gamepad input track (`GamepadInputTrack`), a keyboard-to-gamepad keymap (`KeyboardGamepadSource`), and `RealTimePacer`. |
| `field` | Field bookkeeping and game-piece simulation: the localizer-to-field frame transform, trigger and scoring volumes, obstacles, game-piece possession and rolling/flight physics, and a seeded random source. |
| `vision` | A simulated camera: lens and mount geometry, and which game pieces fall inside the image and where, as `CameraSighting`s. Geometry only; no image is rendered. |
| `vision` | A simulated camera: lens (optionally distorted) and mount geometry, which game pieces and AprilTags fall inside the image and where, with boxes, the robot body and other pieces in the way, and `SimFrameRenderer`'s synthetic RGB frames for running a pixel pipeline. Synthetic frames are flat colours, never for tuning thresholds. |
| `viz` | `MechanismSketch` and its definitions: a robot's joints drawn as a PsiKit mechanism for AdvantageScope. `ArticulatedRobotModel`: a joint tree that turns joint values into the component poses a custom AdvantageScope robot asset draws. |
| `loop` | Scoring runs from their logs and keeping the best: `RunResult` (a run read back from its RLOG), `Objective` and `Scorer` (measure), guardrails and `Gate` (accept or reject a candidate), and `LoopDriver` (last-best bookkeeping, `Milestone`s, the `StopReport`). It proposes nothing. |
| `fit` | Fitting the sim to a real robot log: `LeastSquares` (Householder QR, written out), `FirstOrderFit` (the plant model `FakeMotor` steps, plus friction), `RlogTimeSeries` (timestamped columns of an RLOG) and `GapReport` (the markdown sim-vs-real table). A season supplies its own key names and sim parameters. |
Expand Down Expand Up @@ -334,13 +334,15 @@ limelight.setRobotPose(fieldX, fieldY, fieldHeading); // or setRobotPoseFromLo
is an empty, invalid result, as on the robot; `stop()` keeps the last result, which goes stale.
- **Geometry** is `vision/SimTagCamera`: all four corners must be in the image and in front of the lens,
the tag must face the camera (optionally within `maxIncidenceDegrees`), be within range, and not be
behind an `ObstacleBox` given to `occluders(...)`. MegaTag2 uses the yaw you sent.
behind an `ObstacleBox` given to `occluders(...)` or `robotBody(...)` (robot frame). Tags may be tilted.
MegaTag2 uses the yaw you sent.
- **Optional:** seeded Gaussian noise on tx/ty and botpose (`noise(seed, ...)`, off by default,
byte-identical for a seed), capture and targeting latency, and a camera frame rate.
byte-identical for a seed) with `stdev_mt1`/`stdev_mt2` reporting its spread, seeded dropouts
(`dropout(seed, p)`), lens distortion on the pixel outputs (`distortion(k1, k2, p1, p2, k3)`), capture
and targeting latency, and a camera frame rate.
- **Your test JVM needs the real `org.json`** (`testRuntimeOnly "org.json:json:20250517"`); Android's
`android.jar` copy is a stub. `SimLoop/build.gradle` shows the line.
- **Not modelled:** non-AprilTag pipelines, lens distortion, blur and dropouts, tag-on-tag and robot-body
occlusion, tilted tags, stddevs, and the network-only calls (`uploadFieldmap`, snapshots, python,
- **Not modelled:** non-AprilTag pipelines, blur, tag-on-tag occlusion, and the network-only calls (`uploadFieldmap`, snapshots, python,
calibration), which throw. Robot-space poses use `+y` left; this has not been checked on a real 3A.

## Running a team's OpMode unchanged (`opmode/`)
Expand Down
Binary file added SimLoop/docs/assets/sim-frame-example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion SimLoop/docs/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ it does **not** do is on [What it does not do](limits.md).
- Limelight 3A: AprilTag results from the tags the robot can see, parsed by the SDK. [`fakehardware`](packages/fakehardware.md#limelight-3a)
- REV touch, 2m distance and Color Sensor V3 fakes, scripted or driven from the field. [`fakehardware`](packages/fakehardware.md#touch-distance-and-colour-sensors)
- Sensors driven from the field: range ray, colour probe, contact switch on a robot mount. [`sensor`](packages/sensor.md)
- Simulated camera: which pieces and AprilTags are in the image, and where. No rendering. [`vision`](packages/vision.md)
- Simulated camera: which pieces and AprilTags are in the image, and where, through a distorted lens, with boxes, the robot body and other pieces in the way. [`vision`](packages/vision.md)
- Synthetic camera frames: the scene drawn as RGB pixels for a real `VisionProcessor`, with ground-truth labels and a PNG writer. Flat colours, not for tuning thresholds. [`vision`](packages/vision.md#synthetic-frames-for-a-pixel-pipeline)

## Physics and field

Expand Down
2 changes: 1 addition & 1 deletion SimLoop/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ the log is what you assert on afterwards.
| [`sim.live`](packages/live.md) | Driving from the keyboard, recording the session, and replaying it to the same log. |
| [`field`](packages/field.md) | Game pieces with possession and physics, goals, field structures, and robot contact. |
| [`sensor`](packages/sensor.md) | What a touch, distance or colour sensor on the robot sees on the field. |
| [`vision`](packages/vision.md) | Which game pieces and AprilTags a camera sees, and where. No image. |
| [`vision`](packages/vision.md) | Which game pieces and AprilTags a camera sees, and where, with distortion and occlusion. Synthetic frames for pixel pipelines, not photos. |
| [`fit`](packages/fit.md) | Fitting the motor model to a real robot log, and a sim-against-robot gap report. |
| [`loop`](packages/loop.md) | Scoring a run, and the automated edit-and-replay iteration built on top of it. |
| [`viz`](packages/viz.md) | Mechanisms, robot parts and shot arcs drawn into the log for AdvantageScope. |
Expand Down
26 changes: 16 additions & 10 deletions SimLoop/docs/limits.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,29 @@ Game pieces do have physics: they roll, bounce, collide, fly and score
- **`ObstacleBox` has no top**, so pieces cannot rest on one. Use a `KinematicBody`.
- **The physics numbers are defaults** for a foam ball a few inches across. Measure yours.

## Vision is geometry only

`vision` says which pieces and AprilTags a camera would see and where, and `FakeLimelight3A` turns that
into Limelight results. There is **no image**. So:

- Colour thresholds, blob detection and lighting cannot be tested, and a synthetic scene must never be
used to tune them.
- No lens distortion, no motion blur, no dropouts. The robot's own body does not block the view.
## Vision: geometry, and drawings that are not photographs

`vision` says which pieces and AprilTags a camera would see and where, through a pinhole or a distorted
lens, with boxes, the robot's own body and other pieces in the way. `FakeLimelight3A` turns that into
Limelight results. `SimFrameRenderer` can also draw the scene as RGB pixels so a real pixel pipeline runs.
Those **synthetic frames are flat colours under one light, not camera images**. So:

- **Colour thresholds must never be tuned on synthetic frames.** A threshold that passes on one shows the
code path runs, nothing about real lighting. Tune on real photos from your camera.
- No shadows, highlights, textures, motion blur, rolling shutter, exposure or white balance. Synthetic tag
interiors do not decode as a real tag family.
- No roll. Only what you give as a box, a piece or a tag blocks the view; boxes are axis-aligned.
- No frame timing in `SimCamera` or the renderer: latency is your sim glue's job.
- Limelight: AprilTag pipelines only. Its network-only calls throw.
- **No webcams.** A `WebcamName` lookup fails in `init()`.
- **No webcams.** A `WebcamName` lookup fails in `init()`. Your sim glue hands frames to your processor
itself.

## Sensors are simple

- A distance sensor is a single ray, not a 25 degree cone, and sees every surface.
- A colour sensor reads one set of counts per kind of piece, whatever the distance or angle.
- No noise or drift on the IMU, Pinpoint, OTOS, distance or colour fakes. The Limelight has optional
seeded noise.
seeded noise and dropouts, and synthetic frames optional seeded pixel noise.
- No legacy `BNO055IMU`, and no generic I2C devices.

## It ships no field
Expand Down
7 changes: 4 additions & 3 deletions SimLoop/docs/llms.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ the right page instead of crawling navigation.

- **[Every feature](features.md)**: one line per feature, with a link to its page.
- **[What it does not do](limits.md)**: the authoritative list of what is out of scope. If a task needs
something on that list, there is no API for it; say so rather than searching. A rendered camera image,
something on that list, there is no API for it; say so rather than searching. A photoreal camera image,
intake rollers, a shipped field, a command scheduler and controller tuning are out of scope. Game-piece
physics, a geometry-only camera and fitting to a real log exist, each with stated limits.
physics, a camera with distortion and occlusion, synthetic frames (flat colours, never for tuning colour
thresholds) and fitting to a real log exist, each with stated limits.

## Pages

Expand All @@ -34,7 +35,7 @@ the right page instead of crawling navigation.
| [`sim.live`](packages/live.md) | Keyboard driving, recorded gamepad tracks, headless replay to the identical log, and how to use the unpublished keyboard-window module. | Driving the sim by hand, or replaying a session. |
| [`field`](packages/field.md) | Game pieces with possession and physics (roll, bounce, fly, score), goals, obstacles, kinematic and hinged bodies, the robot as boxes, robot contact, and `FieldFrameTransform`. Intaking is a box test. | Modelling game pieces or the field, or crossing between the two frames. |
| [`sensor`](packages/sensor.md) | `RangeFinder`, `ColorProbe`, `ContactSwitch`: what a sensor on a robot mount sees on the field, driving the sensor fakes. | Simulating touch, distance or colour sensors. |
| [`vision`](packages/vision.md) | `SimCamera`, `SimTagCamera`, lens and mount: which pieces and AprilTags a camera sees, and where. Geometry only. | Testing a vision pipeline's geometry. |
| [`vision`](packages/vision.md) | `SimCamera`, `SimTagCamera`, lens (with distortion), mount, `CameraOccluders`: which pieces and AprilTags a camera sees, and where. `SimFrameRenderer`: synthetic RGB frames for running a pixel pipeline, not for tuning it. | Testing a vision pipeline's geometry, or running a pixel pipeline end to end. |
| [`fit`](packages/fit.md) | `FirstOrderFit`, `GapReport`: the plant fitted to a real robot log, with standard errors and warnings. | Comparing the sim with a real robot. |
| [`loop`](packages/loop.md) | `RunResult`, `Objective`, `Guardrail`, `Scorer`, `Gate`, `LoopDriver`, `StopReport`. | Scoring a run or driving iteration. |
| [`viz`](packages/viz.md) | Mechanism and turret sketches, `ArticulatedRobotModel`, `ShotArc` for AdvantageScope. Inches and radians in, metres in the log. | Drawing a mechanism, robot parts or a shot. |
Expand Down
8 changes: 5 additions & 3 deletions SimLoop/docs/packages/fakehardware.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,10 @@ limelight.setRobotPose(fieldX, fieldY, fieldHeading); // or setRobotPoseFromLo

Robot code calls `start()`, `pipelineSwitch(i)`, `updateRobotOrientation(yawDeg)` and `getLatestResult()`
as usual and gets `botpose`, `getBotpose_MT2()` and fiducial results. Staleness and timestamps run on sim
time. Seeded noise, latency and a frame rate are optional on the builder. The geometry is
[`vision`](vision.md)'s `SimTagCamera`.
time. Optional on the builder: seeded noise (and the matching `getStddevMt1/Mt2`), seeded dropouts,
latency, a frame rate, lens distortion (`distortion(k1, k2, p1, p2, k3)`, which moves corner and centre
pixels) and the robot's own body as boxes (`robotBody(...)`). The geometry is [`vision`](vision.md)'s
`SimTagCamera`, so tilted tags in the layout work too.

**Your test JVM needs the real `org.json`:** `testRuntimeOnly "org.json:json:20250517"`. Android's copy
is a stub.
Expand Down Expand Up @@ -174,7 +176,7 @@ They are useful in a test and do not exist on real hardware, so never wire seaso
constructor performs. Every read and write **throws**, on purpose: there is no peripheral behind the
bus. The Pinpoint and OTOS fakes emulate their own register files instead.
- **No sensor noise or drift** on the IMU, Pinpoint, OTOS, distance or colour fakes. The Limelight has
optional seeded noise.
optional seeded noise and dropouts.
- **No webcams.** A `WebcamName` lookup fails in `init()` as on a robot without one.
- **No Limelight pipelines but AprilTags.** Network-only calls (field map upload, snapshots, Python,
calibration) throw.
Expand Down
2 changes: 1 addition & 1 deletion SimLoop/docs/packages/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ what that package will not do.
| [`loop`](loop.md) | once you score runs | Turning a log into a number, with guardrails on what may not get worse. |
| [`field`](field.md) | if you model game pieces | Possession, game-piece physics, goals, field structures. |
| [`sensor`](sensor.md) | if you use touch, distance or colour sensors | What a sensor on the robot sees or touches on the field. |
| [`vision`](vision.md) | if you use a camera | Which pieces and AprilTags a camera sees, and where. No image. |
| [`vision`](vision.md) | if you use a camera | Which pieces and AprilTags a camera sees, and where. Synthetic frames for pixel pipelines, not photos. |
| [`fit`](fit.md) | once you have a real robot log | Fits the motor model to the log and reports the sim-against-robot gap. |
| [`viz`](viz.md) | if you want to see it | Mechanisms, robot parts and shot arcs drawn into the log for AdvantageScope. |

Expand Down
Loading
Loading