From bfa6d8deb6643e802f10ddcfe1e28ad1ada32b89 Mon Sep 17 00:00:00 2001 From: qing <1776177662@qq.com> Date: Thu, 13 Aug 2026 16:38:15 +0800 Subject: [PATCH] =?UTF-8?q?fix(pybot):=20=E5=BD=95=E5=88=B6=E6=97=B6?= =?UTF-8?q?=E6=94=B9=E7=94=A8=E5=90=8C=E6=AD=A5=20capture()=20=E6=8C=89?= =?UTF-8?q?=E9=9C=80=E6=8A=93=E5=B8=A7=EF=BC=8C=E9=81=BF=E5=85=8D=E5=B8=A7?= =?UTF-8?q?=E9=87=8D=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _grab_frame 从 camera.latest()(读后台队列)改为 camera.capture() (直接调 grabber 同步抓帧),确保每个微动作拿到独立帧而非队列中 可能重复的旧帧。Camera 新增 capture() 方法。 --- pybot/pybot/hd/camera.py | 6 ++++++ pybot/pybot/robot.py | 10 +++++----- pybot/tests/test_camera.py | 14 ++++++++++++++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/pybot/pybot/hd/camera.py b/pybot/pybot/hd/camera.py index cb63569..bf02603 100644 --- a/pybot/pybot/hd/camera.py +++ b/pybot/pybot/hd/camera.py @@ -69,6 +69,12 @@ class Camera: with self._lock: return self._queue[-1] if self._queue else None + def capture(self): + """同步抓一帧(按需,不从队列读);dry_run 或无 grabber 返回 None""" + if self._grabber is None: + return None + return self._grabber() + def snapshot(self): """队列快照 list(旧→新),供消费方批量取帧""" with self._lock: diff --git a/pybot/pybot/robot.py b/pybot/pybot/robot.py index 6ae6a6d..a30b486 100644 --- a/pybot/pybot/robot.py +++ b/pybot/pybot/robot.py @@ -254,13 +254,13 @@ class RobotStruct: return vec def _grab_frame(self, camera_var): - """从摄像头取最新帧;dry_run 或无帧时返回随机噪声帧""" + """从摄像头同步抓一帧;dry_run 或无帧时返回随机噪声帧""" import numpy as np if camera_var is not None: - result = camera_var.play({}) - if result is not None: - return result[1] # (timestamp, frame) - # dry_run 或队列空:随机噪声帧(用 camera 配置尺寸) + frame = camera_var.camera.capture() + if frame is not None: + return frame + # dry_run 或无 grabber:随机噪声帧(用 camera 配置尺寸) h, w = 480, 640 if camera_var is not None: cam = camera_var.camera diff --git a/pybot/tests/test_camera.py b/pybot/tests/test_camera.py index 5d0a932..c74f846 100644 --- a/pybot/tests/test_camera.py +++ b/pybot/tests/test_camera.py @@ -82,6 +82,20 @@ def test_dry_run_no_hardware(): assert cam.latest() is None +def test_capture_on_demand(): + """capture() 同步按需抓帧,每个微步一帧""" + cam = Camera(grabber=FakeGrabber()) + assert cam.capture() == 1 + assert cam.capture() == 2 # 每次调用递增,不复用队列 + assert cam.capture() == 3 + + +def test_capture_no_grabber(): + """dry_run 或未 setup 时 capture() 返回 None""" + cam = Camera(dry_run=True) + assert cam.capture() is None + + def test_camera_var_from_matrix(): robot = RobotStruct(CAMERA_MT, dry_run=True) cam = robot.M["cam0"].camera