Bug Description
In instinct_onboard/ros_nodes/camera_base.py, the camera_subprocess_func
loop ignores the return value of camera.refresh_camera_data(). This can
cause stale frames to be re-written to shared memory with an incremented
frame_counter, making the main process believe a new frame arrived.
Location
instinct_onboard/ros_nodes/camera_base.py, lines ~227-242 (depth) and
~244-251 (color), inside camera_subprocess_func.
Root Cause
CameraBase.refresh_camera_data() returns bool indicating whether new
data was acquired (True) or not (False).
RealsenseCamera.refresh_camera_data() only updates self._depth_data
when frames.get_depth_frame() is not None. If the depth frame is missing
from the frameset, _depth_data retains the previous frame.
- The subprocess loop discards the return value:
camera.refresh_camera_data() # return value ignored
if depth_buffer is not None:
depth_data = camera.get_depth_image()
if depth_data is not None: # passes — stale data is not None
depth_buffer[:] = depth_data
depth_header.frame_counter += 1 # counter incorrectly incremented
...
Consequence
- When
get_depth_frame() returns None, the previous frame is written to SHM
again with a new frame_counter and timestamp.
- The main process (
CameraProcessSpawner.refresh_camera_data) sees
frame_counter changed and treats the stale data as a fresh frame.
- Downstream agents receive an out-of-date depth observation with an updated
timestamp, which is indistinguishable from a real new frame.
- The same issue affects the color stream.
Trigger Condition
Rare: pipeline.wait_for_frames() succeeds but frames.get_depth_frame()
returns None (USB bandwidth jitter, IR projector transient, firmware sync
loss).
Suggested Fix
Option A — respect the return value in the subprocess loop:
got_new = camera.refresh_camera_data()
if depth_buffer is not None and got_new:
depth_data = camera.get_depth_image()
...
(Note: got_new is True if either depth or color was acquired, so this
is a coarse fix. A per-stream status would be more precise.)
Option B — invalidate the cached data when no new frame arrives:
# In RealsenseCamera.refresh_camera_data, when depth_frame is None:
self._depth_data = None
This makes the existing if depth_data is not None check correct, but
changes the "keep last frame" behavior that single-process consumers may
rely on.
Environment
- Ubuntu 22.04, ROS2 Humble
- Jetson Orin NX (ARM, weak memory order — the memory barriers in this file
suggest ARM is a deployment target)
Bug Description
In
instinct_onboard/ros_nodes/camera_base.py, thecamera_subprocess_funcloop ignores the return value of
camera.refresh_camera_data(). This cancause stale frames to be re-written to shared memory with an incremented
frame_counter, making the main process believe a new frame arrived.Location
instinct_onboard/ros_nodes/camera_base.py, lines ~227-242 (depth) and~244-251 (color), inside
camera_subprocess_func.Root Cause
CameraBase.refresh_camera_data()returnsboolindicating whether newdata was acquired (
True) or not (False).RealsenseCamera.refresh_camera_data()only updatesself._depth_datawhen
frames.get_depth_frame()is not None. If the depth frame is missingfrom the frameset,
_depth_dataretains the previous frame.Consequence
get_depth_frame()returns None, the previous frame is written to SHMagain with a new
frame_counterandtimestamp.CameraProcessSpawner.refresh_camera_data) seesframe_counterchanged and treats the stale data as a fresh frame.timestamp, which is indistinguishable from a real new frame.
Trigger Condition
Rare:
pipeline.wait_for_frames()succeeds butframes.get_depth_frame()returns None (USB bandwidth jitter, IR projector transient, firmware sync
loss).
Suggested Fix
Option A — respect the return value in the subprocess loop:
(Note:
got_newis True if either depth or color was acquired, so thisis a coarse fix. A per-stream status would be more precise.)
Option B — invalidate the cached data when no new frame arrives:
This makes the existing
if depth_data is not Nonecheck correct, butchanges the "keep last frame" behavior that single-process consumers may
rely on.
Environment
suggest ARM is a deployment target)