Skip to content

sync

xiao_hei_vln.sync

Synchronization primitives that bridge ROS publish rates to the VLM tick.

LatestCache

One slot per logical channel; writers overwrite, readers snapshot atomically.

Designed for the latest-cache + VLM tick pattern documented in docs/task1_io_spec.md. Callbacks from many ROS subscribers can write concurrently; the VLM main loop calls snapshot() at its own cadence to produce a VLMInput.

Timestamp matching. The camera stream is the slow one, so at tick time the newest image is older than the newest pose. Pairing the two — which a plain latest-value cache does — lifts every mask against a pose the robot has already turned past, misplacing detections by up to ~17° while turning (measured in TASK 27). To avoid that, pose and registered_scan are kept as short histories and, at snapshot time, the entries whose stamps are nearest the image's stamp are returned. The image is the anchor because it is the laggard; when there is no image, or the streams have a gap wider than :data:_MATCH_WINDOW_S, the cache falls back to latest-value.

The question channel is sticky — once set it is returned in every subsequent snapshot until clear_question() is called.

snapshot(tick_id, tick_time)

Atomically read every slot into a single VLMInput.

pose and registered_scan are matched to the image's stamp (see the class docstring); the rest are latest-value.

LatestCache

xiao_hei_vln.sync.latest_cache

Thread-safe latest-value cache that feeds VLMInput snapshots.

LatestCache

One slot per logical channel; writers overwrite, readers snapshot atomically.

Designed for the latest-cache + VLM tick pattern documented in docs/task1_io_spec.md. Callbacks from many ROS subscribers can write concurrently; the VLM main loop calls snapshot() at its own cadence to produce a VLMInput.

Timestamp matching. The camera stream is the slow one, so at tick time the newest image is older than the newest pose. Pairing the two — which a plain latest-value cache does — lifts every mask against a pose the robot has already turned past, misplacing detections by up to ~17° while turning (measured in TASK 27). To avoid that, pose and registered_scan are kept as short histories and, at snapshot time, the entries whose stamps are nearest the image's stamp are returned. The image is the anchor because it is the laggard; when there is no image, or the streams have a gap wider than :data:_MATCH_WINDOW_S, the cache falls back to latest-value.

The question channel is sticky — once set it is returned in every subsequent snapshot until clear_question() is called.

snapshot(tick_id, tick_time)

Atomically read every slot into a single VLMInput.

pose and registered_scan are matched to the image's stamp (see the class docstring); the rest are latest-value.