Tests · sim helpers
Part of the OpenRAL public-symbol inventory. Hand-curated;
(LNN)markers are refreshed bytools/refresh_methods_linenos.py.
Shared subprocess + envelope wiring for the C++ safety-kernel digital-twin sim tests, pulled out of the four per-robot kernel-twin tests so each stays focused on its embodiment-specific assertions.
tests/sim/safety/_kernel_subprocess.py
Shared lifecycle helpers for kernel-twin tests.
isolated_domain_id() -> int— Pick an unusedROS_DOMAIN_IDso concurrent kernel subprocesses don't cross-talk. (L43)start_kernel(*, domain_id, robot_yaml, ...) -> subprocess.Popen— Launch theopenral_safety_kernelbinary with the test's robot manifest under an isolated DDS domain. (L133)terminate_kernel(proc, *, sigint_grace_s=2.0) -> int | None— SIGINT → SIGKILL teardown; returns the exit status (Noneif it outlived the SIGKILL wait). (L227)activate_kernel_node(domain_id, *, node_name="openral_safety_kernel") -> None— Run the configure → activate lifecycle transitions against the spawned kernel node (usesros2 lifecycle set …); extracted from the four kernel-twin tests so the lifecycle ceremony lives once. (L256)kernel_param_args_from_dict(params) -> list[str]— Format a dict of kernel parameters as-p key:=valueargv pairs, for tests that hand-roll specific envelope values rather than drive the kernel from a realRobotDescription. (L86)kernel_param_args(robot_description) -> list[str]— Synthesise the safety envelope from a robot manifest and emit each canonical field as a--ros-args -p key:=valueargv list (mirrorsdeploy_e2e.launch.pyin-process). (L101)
tests/integration/_ros2_control_stack.py
A real ros2_control graph with only the motors left out — controller_manager (ros2_control_node), real JointTrajectoryControllers, a real joint_state_broadcaster, mock_components/GenericSystem as the hardware. Shared by tests/sim/test_openarm_hal_ros2_control.py (the actuation path) and tests/integration/test_real_hal_estop_ros2_control_live.py (the e-stop path, issue #295).
unavailable() -> str | None— Why this host cannot run the stack (ros2CLI,rclpy, message packages, the five ros2_control packages), or None. Callerspytest.skipon it; the dependency is never faked. (L48)write_generic_system_urdf(path, *, name, joints) -> Path— Minimal serial-chain URDF whose<ros2_control>block isGenericSystem, one revolute joint per name with a position command interface and position + velocity state interfaces. The mock echoes commands into state, so a joint reads back what it was last told. (L79)write_controller_config(path, controllers, *, update_rate=100) -> Path—controller_managerparams: a broadcaster plus one JTC per{name: joints}entry. (L118)spawn(argv, log, env)/terminate(process)— One ROS node per process group; SIGINT → SIGKILL teardown that takesros2 run's child with it. (L141)bring_up(tmp, *, urdf, config, controllers)[contextmanager] —robot_state_publisher+ros2_control_node, then the spawner per controller (its exit code is the readiness signal). Children inheritROS_DOMAIN_ID; never setsROS_AUTOMATIC_DISCOVERY_RANGE(seetests/sim/conftest.pyfor the hang). (L164)driver_node(name)[contextmanager] —(node, spin)on a private rclpy context. (L254)wait_until(spin, predicate, timeout_s) -> bool— Poll, never a bare sleep; DDS discovery takes a beat. (L286)