testing.sim

High-level Python API for the libstp simulator.

This module wraps raccoon.sim (the pybind11 bindings) with ergonomic helpers so a team’s pytest can do:

from raccoon.testing.sim import use_scene

with use_scene("empty_table.ftmap",
               robot=my_robot_config,
               start=(50, 50, 0)):
    await drive_forward(cm=30).run_step(robot)
    assert pose().x == pytest.approx(80.0, abs=2.0)

The context manager configures the process-wide MockPlatform singleton to talk to a fresh SimWorld for the duration of the block, then detaches on exit so subsequent code paths see the stock mock HAL.

Only available when the wheel is built with DRIVER_BUNDLE=mock — the raccoon.sim.mock submodule must be present. Importing this module on a wombat-bundle wheel raises RuntimeError.

This module lives under raccoon.testing because it is exclusively a test-harness concern; the actual C++ sim bindings still live at raccoon.sim. Historically this API was at raccoon.step.sim — that path remains as a deprecation shim and will be removed in a future release.

Classes

LineSensorMount

DistanceSensorMount

SimRobotConfig

Sim-side counterpart to the team's GenericRobot geometry/kinematics.

Functions

configure(, auto_tick, auto_tick_max_step_sec)

Attach a fresh sim to the MockPlatform singleton.

detach(→ None)

Disconnect any attached sim. The mock HAL goes back to zero odometry.

pose(→ raccoon.sim.Pose2D)

Return the sim's current ground-truth pose (cm, cm, rad).

yaw_rate(→ float)

Return the sim's current yaw rate in rad/s.

tick(→ None)

Manually advance the sim. Use this for fully deterministic tests.

use_scene(, auto_tick, auto_tick_max_step_sec)

Context manager: attach the sim for the duration of a with block.

Module Contents

class testing.sim.LineSensorMount
analog_port: int
forward_cm: float
strafe_cm: float
name: str = ''
class testing.sim.DistanceSensorMount
analog_port: int
forward_cm: float
strafe_cm: float
mount_angle_rad: float = 0.0
max_range_cm: float = 100.0
name: str = ''
class testing.sim.SimRobotConfig

Sim-side counterpart to the team’s GenericRobot geometry/kinematics.

Defaults match a typical Botball wombat. Override fields that differ on your robot — they must agree with whatever the real Drive / DifferentialKinematics were constructed with so the sim physics matches what the motion controllers expect.

width_cm: float = 18.0
length_cm: float = 18.0
rotation_center_forward_cm: float = 0.0
rotation_center_strafe_cm: float = 0.0
wheel_radius_m: float = 0.03
track_width_m: float = 0.15
wheelbase_m: float = 0.15
left_motor_port: int = 0
right_motor_port: int = 1
left_motor_inverted: bool = False
right_motor_inverted: bool = False
max_wheel_velocity_rad_s: float = 30.0
motor_time_constant_sec: float = 0.05
ticks_to_rad: float = 0.0043633231299858195
viscous_drag_coeff: float = 0.0
coulomb_friction_rad_s2: float = 0.0
bemf_noise_stddev: float = 0.0
line_sensors: List[LineSensorMount] = []
distance_sensors: List[DistanceSensorMount] = []
testing.sim.configure(scene: str | pathlib.Path, *, robot: SimRobotConfig | None = None, start: PoseLike = (0.0, 0.0, 0.0), auto_tick: bool = True, auto_tick_max_step_sec: float = 0.05) None

Attach a fresh sim to the MockPlatform singleton.

After this returns, motor commands written through any HAL Motor drive the simulated chassis, and OdometryBridge::readOdometry reports its pose. Auto-tick is enabled by default so a real motion loop reading odometry on its own schedule will see the sim advance with wall time.

testing.sim.detach() None

Disconnect any attached sim. The mock HAL goes back to zero odometry.

testing.sim.pose() raccoon.sim.Pose2D

Return the sim’s current ground-truth pose (cm, cm, rad).

testing.sim.yaw_rate() float

Return the sim’s current yaw rate in rad/s.

testing.sim.tick(dt_seconds: float) None

Manually advance the sim. Use this for fully deterministic tests.

testing.sim.use_scene(scene: str | pathlib.Path, *, robot: SimRobotConfig | None = None, start: PoseLike = (0.0, 0.0, 0.0), auto_tick: bool = True, auto_tick_max_step_sec: float = 0.05) Iterator[None]

Context manager: attach the sim for the duration of a with block.

Example:

with use_scene("empty_table.ftmap", start=(20, 50, 0)):
    await drive_forward(cm=30).run_step(my_robot)
    x, y, _ = pose()
    assert x == pytest.approx(50, abs=2)