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._raw: Optional[FrameAcquisition[RawFrameset]] = None
|
||||||
self._aligned: Optional[FrameAcquisition[CameraFrame]] = None
|
self._aligned: Optional[FrameAcquisition[CameraFrame]] = None
|
||||||
self._last_aligned_raw_seq = 0
|
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_available: bool = True
|
||||||
self._color_format = rs.format.bgr8
|
self._color_format = rs.format.bgr8
|
||||||
self._usb_type: str = "unknown"
|
self._usb_type: str = "unknown"
|
||||||
@@ -364,6 +366,7 @@ class RealSenseD435:
|
|||||||
for thread in threads:
|
for thread in threads:
|
||||||
thread.join(STOP_JOIN_S)
|
thread.join(STOP_JOIN_S)
|
||||||
self.device_index = None
|
self.device_index = None
|
||||||
|
self._cached = None
|
||||||
logger.info("RealSense camera closed")
|
logger.info("RealSense camera closed")
|
||||||
|
|
||||||
def _start_acquisition(self) -> None:
|
def _start_acquisition(self) -> None:
|
||||||
@@ -554,13 +557,19 @@ class RealSenseD435:
|
|||||||
return CameraFrame(rgb=rgb, depth=depth_mm, timestamp=time.time())
|
return CameraFrame(rgb=rgb, depth=depth_mm, timestamp=time.time())
|
||||||
|
|
||||||
def _cached_or_capture(self) -> Optional[CameraFrame]:
|
def _cached_or_capture(self) -> Optional[CameraFrame]:
|
||||||
"""The latest ALIGNED frame if younger than frame_cache_ms, else the next one."""
|
"""The frame the cached readers share if younger than frame_cache_ms, else the next aligned one.
|
||||||
aligned = self._aligned
|
|
||||||
if aligned is not None:
|
Only these readers renew it: a capture() in between (e.g. /api/capture
|
||||||
_, last = aligned.latest()
|
from another client) does not move it, so /api/rgb then /api/depth
|
||||||
if last is not None and (time.time() - last.timestamp) * 1000.0 < self._frame_cache_ms:
|
within frame_cache_ms return color and depth of ONE frame.
|
||||||
return last
|
"""
|
||||||
return self.capture()
|
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]:
|
def cached_frame(self) -> Optional[CameraFrame]:
|
||||||
"""Like get_rgb()/get_depth(), but the whole frame (so its encodings can be shared)."""
|
"""Like get_rgb()/get_depth(), but the whole frame (so its encodings can be shared)."""
|
||||||
|
|||||||
Reference in new issue
Block a user