SimLoop¶
Run your FTC robot code on a laptop, deterministically, and get a log you can score.
Your Robot.init(), your subsystems and your OpMode run unchanged against fake hardware in a JVM unit
test. Time comes from a fake clock rather than the wall, so the same run produces the same log every
time. The log is a PsiKit RLOG, which AdvantageScope opens and which SimLoop's own loop package can
score automatically.
No robot, no Driver Station, no emulator. A test run is a few seconds.
What you open¶
Run SimLoop from your robot project's tests or simulation harness, then open the log it writes in AdvantageScope, in its own window, to see the run.
Status: alpha
v0.2.0-alpha.2 is the current release. The API may change between
alpha versions, so pin the exact version in your build. It needs FTC SDK 12.0. Questions go
to Discussions; bugs go to
Issues. v0.1.0-beta1 is superseded and gets no
fixes.
It has been used by one team, on one robot's code, and its physics has not yet been compared with a real robot. You are testing it. What has been tested says what has been checked and what has not.
Every feature lists what it does, one line each.
Match the docs to your dependency
These source docs can include changes newer than the published tag. For a build pinned to
v0.2.0-alpha.2, use the
docs at that tag.
The fastest way in¶
Copy one folder into your FTC project and add one line to TeamCode/build.gradle:
That folder carries every build setting SimLoop needs and a small example robot that drives itself, so
./gradlew :TeamCode:testDebugUnitTest passes two simulated tests immediately. You never clone this
repository. Installing it has the three steps, and then says exactly what the
folder is doing if you would rather wire it by hand.
Who this is for¶
Two readers, and the site is shaped for both.
A team that has written robot code but never a simulator. You know what a DcMotorEx is and what a
subsystem does. You do not need convincing that testing is good; you need the twenty lines of Gradle that
make it work and a first test that passes. Start at Installing it, then
Your first simulated test.
An AI agent writing code against this library. Every page states units and frame for every number, because those cannot be inferred from a signature. Every package page ends with what that package will not do, because the expensive failure is not a wrong call — it is confidently writing against a feature that does not exist. What it does not do is the page that matters most for that, and Index for AI agents is a flat list of every page and what is on it.
The idea in one paragraph¶
A robot loop reads hardware, decides, and writes hardware. SimLoop supplies SDK-compatible fakes:
FakeMotor implements DcMotorEx, and FakeHardwareMap extends HardwareMap. Robot code using the
supported methods can run against those devices. Plants model mechanism and drivetrain motion;
your test wires their state into sensors and supplies your robot's parameters through config
interfaces. SimLoop never imports your team's package. ScenarioRunner owns the fixed clock and
logging session, and your test asserts on the resulting log.
What is in it¶
| Package | What it gives you |
|---|---|
fakehardware |
Fake devices that implement the real SDK interfaces, including the IMU, Pinpoint, OTOS, Limelight 3A and REV sensors, and the FakeHardwareMap you hand to init(). |
plant |
The physics behind those fakes: drivetrain, 1-DOF and multi-DOF mechanisms, positional servos. |
config |
The interfaces your season code implements to state its own numbers. The one-way seam. |
sim |
FakeTimer, ScenarioRunner, and decoding an RLOG back to fields. |
opmode |
Running your OpMode or LinearOpMode unchanged, with scripted gamepads. |
simclock |
Moving your own timer code onto sim time without changing it. |
sim.live |
Driving from the keyboard, recording the session, and replaying it to the same log. |
field |
Game pieces with possession and physics, goals, field structures, and robot contact. |
sensor |
What a touch, distance or colour sensor on the robot sees on the field. |
vision |
Which game pieces and AprilTags a camera sees, and where, with distortion and occlusion. Synthetic frames for pixel pipelines, not photos. |
fit |
Fitting the motor model to a real robot log, and a sim-against-robot gap report. |
loop |
Scoring a run, and the automated edit-and-replay iteration built on top of it. |
viz |
Mechanisms, robot parts and shot arcs drawn into the log for AdvantageScope. |
The generated API reference — every class, method and field, with units and frame on every number — is
built by ./gradlew :SimLoop:apiDocs and ships in the release as SimLoop-<version>-javadoc.jar.
The rules it holds itself to¶
These are enforced by tests in the module, not by good intentions.
- No season imports. No file in
org.horizon36596.simloopimportsorg.firstinspires.ftc.teamcode. Season facts arrive through theconfiginterfaces. - Depends only on the FTC SDK 12.0 and PsiKit. No SolversLib, no follower library.
- Deterministic model time. Plants advance from the supplied
deltaTime; getters are pure reads. I/O waits and live pacing do not advance that clock. Robot code must use sim time too. - SDK-facing fakes. Robot code uses FTC SDK types. The fake devices implement their state and control interfaces; readings come from the simulation model. See the hardware guide for behavior and limits.
Help build SimLoop¶
SimLoop is built by Horizon (FTC 36596) for any FTC team, and other teams and simulator authors are welcome to add to it. It is season-agnostic, so what you add helps every season. Wanted most:
- New fake devices that replicate a real FTC SDK class, with tests against the SDK's behaviour.
- Field and game-piece models built from the general pieces in
field, never one game's field. - Documentation: a page that confused you, a missing unit, a missing example.
- Examples: worked tests for common robots.
- Interop with other tools: log formats, AdvantageScope layouts, replay and analysis tools.
Read CONTRIBUTING.md first. Small
starter tasks are in
docs/good-first-issues.md.
For anything bigger, start a
Discussion.