Class ScenarioRunner
DrivetrainSimTest, Batch 2.2's SlideSimTest)
re-typed the same ~20 lines: create the RLOG directory, reset/wire/start PsiKit's Logger, tick a
FakeTimer inside a periodicBeforeUser()/periodicAfterUser() bracket, call
Logger.end(), then re-check by hand that the writer thread didn't overflow or emit nothing. This
class is that boilerplate, written once.
What stays with the caller. This class is season-agnostic core (architecture §3, domain R7): it
knows nothing about a specific robot's motors, plants, or subsystems. Building the fake hardware,
commanding the robot, advancing its plants, and deciding what to log each tick is scenario-specific
behavior the caller supplies as a ScenarioRunner.ScenarioBody. The SimRobotConfig parameter is not read by this
class at all — it is recorded as PsiKit metadata purely so a human opening the RLOG in AdvantageScope (or
a future Phase-3 scorer) can see which robot config a run used, the same way opModeName is.
Trustworthy by construction. run(java.lang.String, org.horizon36596.simloop.config.SimRobotConfig, org.horizon36596.simloop.sim.FakeTimer, int, double, java.nio.file.Path, org.horizon36596.simloop.sim.ScenarioRunner.ScenarioBody) throws if PsiKit's async writer queue overflowed
(BACKLOG B3 — cycles silently dropped) or if the resulting RLOG is missing or empty (BACKLOG B11) — a
scenario whose log cannot be trusted for replay is a defect the moment it happens, not something every
caller should have to re-check after the fact.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic interfaceOne scenario's per-tick behavior: command the robot, advance its fake hardware/plants, log fields. -
Method Summary
Modifier and TypeMethodDescriptionstatic voidrun(String opModeName, SimRobotConfig config, FakeTimer timer, int ticks, double deltaTimeSeconds, Path rlogPath, ScenarioRunner.ScenarioBody body) Runsticksfixed-timestep sim ticks againsttimer, writing everything PsiKit logs torlogPath.
-
Method Details
-
run
public static void run(String opModeName, SimRobotConfig config, FakeTimer timer, int ticks, double deltaTimeSeconds, Path rlogPath, ScenarioRunner.ScenarioBody body) Runsticksfixed-timestep sim ticks againsttimer, writing everything PsiKit logs torlogPath.- Parameters:
opModeName- recorded as PsiKit metadata ("OpMode"), shown in AdvantageScopeconfig- the robot's sim config for this scenario; recorded as metadata only (see class javadoc) — this class does not read a robot's motors/plants from ittimer- the deterministic clock (domain R5) this scenario runs on; the caller constructs it (and must wire any sim-side infra to it, e.g.HeadlessRobotInitInfra) BEFORE calling this method, since that wiring has to happen before the robot under test is builtticks- number of sim ticks to rundeltaTimeSeconds- fixed per-tick time step (sim-harness §3);timeradvances by this once per tick, beforebody.tick(deltaTimeSeconds)runsrlogPath- caller-chosen output file, e.g.Paths.get("build", "sim", "run1.rlog")body- the scenario's per-tick behavior (seeScenarioRunner.ScenarioBody)- Throws:
IllegalStateException- if the RLOG this run produced cannot be trusted, for any of four reasons: PsiKit's async writer queue overflowed (BACKLOG B3); the file is missing or empty (BACKLOG B11); it decodes to a different number of frames than ticks were run (BACKLOG B32); or the writer thread stopped making progress while the producer waited for it. All four are the same statement - the log is not a record of the run - and none of them is affected by what the caller's own trajectory checks found
-