fix: /api/capture no longer moves the frame /api/rgb and /api/depth share
The 100 ms cache of get_rgb/get_depth/cached_frame served the latest aligned frame, so an /api/capture from another client between /api/rgb and /api/depth made the depth come from a newer frame than the color (with two clients on PC2, the multi-camera service and the pestle detector, this can happen). Older than R01: capture() already refreshed _last_frame then. The cache is now its own slot, renewed only by the cached readers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6a442e9f32
commit
5c97d166be
1 file changed
+16
-7
@@ -151,6 +151,8 @@ class RealSenseD435:
|
||||
self._raw: Optional[FrameAcquisition[RawFrameset]] = None
|
||||
self._aligned: Optional[FrameAcquisition[CameraFrame]] = None
|
||||
self._last_aligned_raw_seq = 0
|
||||
# The frame get_rgb/get_depth/cached_frame share for frame_cache_ms (see _cached_or_capture()).
|
||||
self._cached: Optional[CameraFrame] = None
|
||||
self._color_available: bool = True
|
||||
self._color_format = rs.format.bgr8
|
||||
self._usb_type: str = "unknown"
|
||||
@@ -364,6 +366,7 @@ class RealSenseD435:
|
||||
for thread in threads:
|
||||
thread.join(STOP_JOIN_S)
|
||||
self.device_index = None
|
||||
self._cached = None
|
||||
logger.info("RealSense camera closed")
|
||||
|
||||
def _start_acquisition(self) -> None:
|
||||
@@ -554,13 +557,19 @@ class RealSenseD435:
|
||||
return CameraFrame(rgb=rgb, depth=depth_mm, timestamp=time.time())
|
||||
|
||||
def _cached_or_capture(self) -> Optional[CameraFrame]:
|
||||
"""The latest ALIGNED frame if younger than frame_cache_ms, else the next one."""
|
||||
aligned = self._aligned
|
||||
if aligned is not None:
|
||||
_, last = aligned.latest()
|
||||
if last is not None and (time.time() - last.timestamp) * 1000.0 < self._frame_cache_ms:
|
||||
return last
|
||||
return self.capture()
|
||||
"""The frame the cached readers share if younger than frame_cache_ms, else the next aligned one.
|
||||
|
||||
Only these readers renew it: a capture() in between (e.g. /api/capture
|
||||
from another client) does not move it, so /api/rgb then /api/depth
|
||||
within frame_cache_ms return color and depth of ONE frame.
|
||||
"""
|
||||
cached = self._cached
|
||||
if cached is not None and (time.time() - cached.timestamp) * 1000.0 < self._frame_cache_ms:
|
||||
return cached
|
||||
frame = self.capture()
|
||||
if frame is not None:
|
||||
self._cached = frame
|
||||
return frame
|
||||
|
||||
def cached_frame(self) -> Optional[CameraFrame]:
|
||||
"""Like get_rgb()/get_depth(), but the whole frame (so its encodings can be shared)."""
|
||||
|
||||
Reference in new issue
Block a user