From f0a903c98f4974eed9bb9598c7e9e7aad907dba0 Mon Sep 17 00:00:00 2001 From: Ben Zhang <5977478+ben-z@users.noreply.github.com> Date: Tue, 10 Jun 2025 01:23:33 -0700 Subject: [PATCH 1/4] Fix unable to set camera width/height to non-default (#1225) --- .../common/cameras/opencv/camera_opencv.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/lerobot/common/cameras/opencv/camera_opencv.py b/lerobot/common/cameras/opencv/camera_opencv.py index 7a2f1b324..3e9370fc4 100644 --- a/lerobot/common/cameras/opencv/camera_opencv.py +++ b/lerobot/common/cameras/opencv/camera_opencv.py @@ -225,16 +225,19 @@ class OpenCVCamera(Camera): def _validate_width_and_height(self) -> None: """Validates and sets the camera's frame capture width and height.""" - success = self.videocapture.set(cv2.CAP_PROP_FRAME_WIDTH, float(self.capture_width)) - actual_width = int(round(self.videocapture.get(cv2.CAP_PROP_FRAME_WIDTH))) - if not success or self.capture_width != actual_width: - raise RuntimeError(f"{self} failed to set capture_width={self.capture_width} ({actual_width=}).") + width_success = self.videocapture.set(cv2.CAP_PROP_FRAME_WIDTH, float(self.capture_width)) + height_success = self.videocapture.set(cv2.CAP_PROP_FRAME_HEIGHT, float(self.capture_height)) - success = self.videocapture.set(cv2.CAP_PROP_FRAME_HEIGHT, float(self.capture_height)) - actual_height = int(round(self.videocapture.get(cv2.CAP_PROP_FRAME_HEIGHT))) - if not success or self.capture_height != actual_height: + actual_width = int(round(self.videocapture.get(cv2.CAP_PROP_FRAME_WIDTH))) + if not width_success or self.capture_width != actual_width: raise RuntimeError( - f"{self} failed to set capture_height={self.capture_height} ({actual_height})." + f"{self} failed to set capture_width={self.capture_width} ({actual_width=}, {width_success=})." + ) + + actual_height = int(round(self.videocapture.get(cv2.CAP_PROP_FRAME_HEIGHT))) + if not height_success or self.capture_height != actual_height: + raise RuntimeError( + f"{self} failed to set capture_height={self.capture_height} ({actual_height=}, {height_success=})." ) @staticmethod From f5335fe6966a5a627f95db00ca030edf2452f4c3 Mon Sep 17 00:00:00 2001 From: Daisuke Sato Date: Tue, 10 Jun 2025 18:05:08 +0900 Subject: [PATCH 2/4] Update tutorial link (#1250) --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 22685525b..8462634f4 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@

-

+

Build Your Own SO-101 Robot!

@@ -48,11 +48,11 @@

Train it in minutes with a few simple moves on your laptop.

Then sit back and watch your creation act autonomously! 🤯

-

+

See the full SO-101 tutorial here.

Want to take it to the next level? Make your SO-101 mobile by building LeKiwi!

-

Check out the LeKiwi tutorial and bring your robot to life on wheels.

+

Check out the LeKiwi tutorial and bring your robot to life on wheels.

LeKiwi mobile robot From 885d0ca6180d777c5a74e9b9517f4f15e7abf9b5 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 10 Jun 2025 10:31:08 +0000 Subject: [PATCH 3/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../src/components/videos-player.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lerobot/html_dataset_visualizer/src/components/videos-player.tsx b/lerobot/html_dataset_visualizer/src/components/videos-player.tsx index 69c31b137..ddc1f3187 100644 --- a/lerobot/html_dataset_visualizer/src/components/videos-player.tsx +++ b/lerobot/html_dataset_visualizer/src/components/videos-player.tsx @@ -171,7 +171,7 @@ export const VideosPlayer = ({ } } }; - + videoRefs.current.forEach((video) => { if (video) { // If already ready, call the handler immediately @@ -182,7 +182,7 @@ export const VideosPlayer = ({ } } }); - + return () => { videoRefs.current.forEach((video) => { if (video) { @@ -191,7 +191,7 @@ export const VideosPlayer = ({ }); }; }, []); - + return ( <> {/* Error message */} From 2889f3a06adf10161f69b687fb0e2486fe87a37f Mon Sep 17 00:00:00 2001 From: Sarunas Kalade Date: Tue, 10 Jun 2025 04:42:54 -0600 Subject: [PATCH 4/4] update KochFollower.get_observation() so it returns same observation structure as SO101 (#1248) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- lerobot/common/robots/koch_follower/koch_follower.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lerobot/common/robots/koch_follower/koch_follower.py b/lerobot/common/robots/koch_follower/koch_follower.py index 9ba506b4b..64ece25f2 100644 --- a/lerobot/common/robots/koch_follower/koch_follower.py +++ b/lerobot/common/robots/koch_follower/koch_follower.py @@ -20,7 +20,6 @@ from functools import cached_property from typing import Any from lerobot.common.cameras.utils import make_cameras_from_configs -from lerobot.common.constants import OBS_STATE from lerobot.common.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError from lerobot.common.motors import Motor, MotorCalibration, MotorNormMode from lerobot.common.motors.dynamixel import ( @@ -175,11 +174,9 @@ class KochFollower(Robot): if not self.is_connected: raise DeviceNotConnectedError(f"{self} is not connected.") - obs_dict = {} - # Read arm position start = time.perf_counter() - obs_dict[OBS_STATE] = self.bus.sync_read("Present_Position") + obs_dict = self.bus.sync_read("Present_Position") obs_dict = {f"{motor}.pos": val for motor, val in obs_dict.items()} dt_ms = (time.perf_counter() - start) * 1e3 logger.debug(f"{self} read state: {dt_ms:.1f}ms")