Layer 2 — Sensors
Part of the OpenRAL public-symbol inventory. Hand-curated;
(LNN)markers are refreshed bytools/refresh_methods_linenos.py.
python/sensors/src/openral_sensors/catalog.py
Sensor catalog — vendor-agnostic registry of SensorSpec / SensorBundle factories.
class SensorSignature— Probe-side identifier (kind + canonical value) for catalog reverse-lookup. (L58) fields:kind, valueclass SensorCatalogEntry— One row in the catalog. (L87) fields:id, vendor, model, kind, factory, modalities, description, docs_url, signaturesclass SensorCatalog— In-memory registry. (L121)register(entry, *, replace=False) -> SensorCatalogEntry(L151)unregister(sensor_id) -> None(idempotent) (L174)get(sensor_id) -> SensorCatalogEntry— RaisesKeyErroron miss. (L180)__contains__(sensor_id) -> bool(L189)__len__() -> int(L193)__iter__() -> object(L197)keys() -> list[str]— Insertion order. (L201)list_ids() -> list[str]— Sorted alphabetically. (L205)entries() -> list[SensorCatalogEntry]— Sorted by id. (L209)filter(*, vendor=None, modality=None, kind=None) -> list[SensorCatalogEntry](L213)find_by_signature(signature) -> SensorCatalogEntry | None— Reverse-lookup foropenral detect. (L232)build(sensor_id, **kwargs) -> SensorSpec | SensorBundle(L253)- const
CATALOG = SensorCatalog()— global singleton. (L265)
Sensor SensorSpec factories — single-modality
Only the factories used by an active HAL adapter remain. Speculative vendor modules (orbbec, hokuyo, slamtec, livox, ouster, imu, tactile) were deleted; reintroduce them when a robot manifest needs them.
python/sensors/src/openral_sensors/force_torque.py
robotiq_ft300s_spec(name='wrist_ft', parent_frame='ee_link', rate_hz=100.0) -> SensorSpec— Robotiq FT 300-S, 6-axis, 100 Hz, UR-native. (L25)
python/sensors/src/openral_sensors/usb_uvc.py
_uvc_intrinsics(width, height, hfov_deg) -> IntrinsicsPinhole— Nominal pinhole intrinsics from sensor dims + hFOV. (L33)logitech_c920_spec(name='usb_cam', parent_frame='base_link', rate_hz=30.0, width=1920, height=1080) -> SensorSpec— Logitech C920 / C920e, 1080p UVC, 78° hFOV. (L48)
Sensor SensorBundle factories — multi-modality
python/sensors/src/openral_sensors/realsense.py
realsense_d435_bundle(name='realsense', parent_frame='base_link', serial_no='', rgb_rate_hz=30.0, depth_rate_hz=30.0, imu_rate_hz=400.0) -> SensorBundle(L104)realsense_d435i_bundle(...) -> SensorBundle— D435 + Bosch BMI085 IMU; delegates torealsense_d435_bundle. (L421)realsense_d415_bundle(...) -> SensorBundle— rolling-shutter IR stereo, 65°×40°, no IMU. (L456)bundle_to_node_params(bundle, serial_no='') -> NodeParams— Map torealsense2_cameranode params. (L203)generate_launch_py(bundle, serial_no='') -> str— Auto-generated ROS 2 launch file. (L277)calibrate_camera_cmd(sensor, chessboard_cols=8, chessboard_rows=6, square_size_m=0.025) -> list[str]— Buildros2 run camera_calibration cameracalibratorargv. (L346)
python/sensors/src/openral_sensors/luxonis.py
oak_d_pro_bundle(name='oak', parent_frame='base_link', mxid='', rgb_rate_hz=30.0, depth_rate_hz=30.0, imu_rate_hz=400.0, rgb_width=1920, rgb_height=1080, depth_width=1280, depth_height=800) -> SensorBundle— Luxonis OAK-D Pro RGB + global-shutter stereo depth (0.20–19 m, 71.86°×56°) + BNO086 IMU bundle, with nominal IMX378 / OV9282 intrinsics from the datasheet, linearly rescaled to non-default stream resolutions. Registered in the catalog asluxonis/oak_d_pro; recommended overhead RGB-D for theso101_boxscene. (L82)_scale_intrinsics(base, width, height) -> IntrinsicsPinhole— Thin wrapper delegating toopenral_core.scale_intrinsics_to; lets a caller pick a non-default stream resolution and still get a self-consistent (fx, fy, cx, cy). (L194)
python/sensors/src/openral_sensors/ros_publisher.py
ADR-0019 PR2 — generalised sensor → ROS 2 image publisher; non-GStreamer fallback to RosImagePublisher.
class SensorRosPublisher(*, reader, topic, rate_hz, node_name=None, frame_id=None, qos_depth=5, camera_info=None)— Background-thread publisher that polls anySensorReader.read_latest()and republishes assensor_msgs/Image. Lazy-imports rclpy; raisesRuntimeErroratstart()with install hint when ROS 2 isn't sourced. OptionalCameraInfocompanion topic at<topic>/camera_infowith RELIABLE QoS. Reader lifecycle (open/close) is owned by the caller. (L79)start() -> None— Init rclpy if needed, create publishers, spawn the pump thread. (L183)stop() -> None— Signal the pump thread, tear down publishers + node; idempotent. (L252)- prop
is_started,n_published,n_stale_skipped,topic,info_topic— Diagnostics surface consumed by theopenral_sensors_roslifecycle node. (L159)
python/sensors/src/openral_sensors/_reader_protocol.py
Internal Protocol shim mirroring openral_runner.SensorReader to avoid a sensors↔runner import cycle.
class SensorReaderLike(Protocol)— Structural alias withsensor_id,is_open,open,close,read_latest. (L27)