From 20842d3f7cb3741f73c96d87f93fcfba19f71845 Mon Sep 17 00:00:00 2001 From: 7SOMAY Date: Mon, 17 Mar 2025 20:54:04 +0530 Subject: [PATCH 1/5] Added PERF flag inside node-hub --- node-hub/dora-argotranslate/pyproject.toml | 5 +++-- node-hub/dora-distil-whisper/pyproject.toml | 7 ++++--- node-hub/dora-echo/pyproject.toml | 5 +++-- node-hub/dora-internvl/pyproject.toml | 5 +++-- node-hub/dora-ios-lidar/pyproject.toml | 5 +++-- node-hub/dora-keyboard/pyproject.toml | 5 +++-- node-hub/dora-kit-car/pyproject.toml | 5 +++-- node-hub/dora-kokoro-tts/pyproject.toml | 5 +++-- node-hub/dora-llama-cpp-python/pyproject.toml | 5 +++-- node-hub/dora-magma/pyproject.toml | 5 +++-- node-hub/dora-microphone/pyproject.toml | 5 +++-- node-hub/dora-object-to-pose/pyproject.toml | 5 +++-- node-hub/dora-openai-server/pyproject.toml | 6 +++--- node-hub/dora-opus/pyproject.toml | 5 +++-- node-hub/dora-outtetts/pyproject.toml | 5 +++-- node-hub/dora-parler/pyproject.toml | 5 +++-- node-hub/dora-phi4/pyproject.toml | 5 +++-- node-hub/dora-piper/pyproject.toml | 5 +++-- node-hub/dora-pyaudio/pyproject.toml | 5 +++-- node-hub/dora-pyorbbecksdk/pyproject.toml | 5 +++-- node-hub/dora-pyrealsense/pyproject.toml | 5 +++-- node-hub/dora-qwen/pyproject.toml | 5 +++-- node-hub/dora-qwen2-5-vl/pyproject.toml | 5 +++-- node-hub/dora-qwenvl/pyproject.toml | 5 +++-- node-hub/dora-rdt-1b/pyproject.toml | 5 +++-- node-hub/dora-reachy1/pyproject.toml | 5 +++-- node-hub/dora-reachy2/pyproject.toml | 5 +++-- node-hub/dora-rerun/pyproject.toml | 5 +++-- node-hub/dora-sam2/pyproject.toml | 5 +++-- node-hub/dora-transformers/dora_transformers/__init__.py | 2 ++ node-hub/dora-transformers/dora_transformers/__main__.py | 2 ++ node-hub/dora-transformers/dora_transformers/main.py | 4 +++- node-hub/dora-transformers/pyproject.toml | 8 ++++++++ .../dora-transformers/tests/test_dora_transformers.py | 3 +++ node-hub/dora-ugv/pyproject.toml | 5 +++-- node-hub/dora-vad/pyproject.toml | 5 +++-- node-hub/dora-yolo/pyproject.toml | 5 +++-- node-hub/dynamixel-client/pyproject.toml | 5 +++-- node-hub/feetech-client/pyproject.toml | 5 +++-- node-hub/lebai-client/pyproject.toml | 5 +++-- node-hub/lerobot-dashboard/pyproject.toml | 5 +++-- node-hub/llama-factory-recorder/pyproject.toml | 5 +++-- node-hub/mujoco-client/pyproject.toml | 5 +++-- node-hub/opencv-plot/pyproject.toml | 5 +++-- node-hub/opencv-video-capture/pyproject.toml | 5 +++-- node-hub/pyarrow-assert/pyproject.toml | 5 +++-- node-hub/pyarrow-sender/pyproject.toml | 5 +++-- node-hub/replay-client/pyproject.toml | 5 +++-- node-hub/terminal-input/pyproject.toml | 5 +++-- node-hub/video-encoder/pyproject.toml | 5 +++-- 50 files changed, 154 insertions(+), 93 deletions(-) diff --git a/node-hub/dora-argotranslate/pyproject.toml b/node-hub/dora-argotranslate/pyproject.toml index 7f16d002..47e67a4c 100644 --- a/node-hub/dora-argotranslate/pyproject.toml +++ b/node-hub/dora-argotranslate/pyproject.toml @@ -22,5 +22,6 @@ dora-argotranslate = "dora_argotranslate.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-distil-whisper/pyproject.toml b/node-hub/dora-distil-whisper/pyproject.toml index adb7c7d7..52f7dc0d 100644 --- a/node-hub/dora-distil-whisper/pyproject.toml +++ b/node-hub/dora-distil-whisper/pyproject.toml @@ -29,6 +29,7 @@ dora-distil-whisper = "dora_distil_whisper.main:main" [tool.ruff.lint] extend-select = [ - "D", # pydocstyle - "UP", -] + "D", # pydocstyle + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-echo/pyproject.toml b/node-hub/dora-echo/pyproject.toml index 468aac3b..889924b6 100644 --- a/node-hub/dora-echo/pyproject.toml +++ b/node-hub/dora-echo/pyproject.toml @@ -21,5 +21,6 @@ dora-echo = "dora_echo.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP" -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-internvl/pyproject.toml b/node-hub/dora-internvl/pyproject.toml index 8f212ddb..4ac96c02 100644 --- a/node-hub/dora-internvl/pyproject.toml +++ b/node-hub/dora-internvl/pyproject.toml @@ -34,5 +34,6 @@ dora-internvl = "dora_internvl.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-ios-lidar/pyproject.toml b/node-hub/dora-ios-lidar/pyproject.toml index 0542bac1..8c0065e2 100644 --- a/node-hub/dora-ios-lidar/pyproject.toml +++ b/node-hub/dora-ios-lidar/pyproject.toml @@ -18,5 +18,6 @@ dora-ios-lidar = "dora_ios_lidar.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-keyboard/pyproject.toml b/node-hub/dora-keyboard/pyproject.toml index b89810d4..36aa3578 100644 --- a/node-hub/dora-keyboard/pyproject.toml +++ b/node-hub/dora-keyboard/pyproject.toml @@ -27,5 +27,6 @@ dora-keyboard = "dora_keyboard.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-kit-car/pyproject.toml b/node-hub/dora-kit-car/pyproject.toml index 22a7d666..131a2f9d 100644 --- a/node-hub/dora-kit-car/pyproject.toml +++ b/node-hub/dora-kit-car/pyproject.toml @@ -19,5 +19,6 @@ features = ["python", "pyo3/extension-module"] [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-kokoro-tts/pyproject.toml b/node-hub/dora-kokoro-tts/pyproject.toml index 19b2adc0..93cf4b2b 100644 --- a/node-hub/dora-kokoro-tts/pyproject.toml +++ b/node-hub/dora-kokoro-tts/pyproject.toml @@ -18,5 +18,6 @@ dora-kokoro-tts = "dora_kokoro_tts.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-llama-cpp-python/pyproject.toml b/node-hub/dora-llama-cpp-python/pyproject.toml index fd4715a1..95855d43 100644 --- a/node-hub/dora-llama-cpp-python/pyproject.toml +++ b/node-hub/dora-llama-cpp-python/pyproject.toml @@ -43,5 +43,6 @@ dora-llama-cpp-python = "dora_llama_cpp_python.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP" -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-magma/pyproject.toml b/node-hub/dora-magma/pyproject.toml index 642ab054..76110fb6 100644 --- a/node-hub/dora-magma/pyproject.toml +++ b/node-hub/dora-magma/pyproject.toml @@ -43,5 +43,6 @@ extend.exclude = "dora_magma/Magma" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-microphone/pyproject.toml b/node-hub/dora-microphone/pyproject.toml index d1c0aaec..0b640b6c 100644 --- a/node-hub/dora-microphone/pyproject.toml +++ b/node-hub/dora-microphone/pyproject.toml @@ -27,5 +27,6 @@ dora-microphone = "dora_microphone.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-object-to-pose/pyproject.toml b/node-hub/dora-object-to-pose/pyproject.toml index 1eb059bc..cd95df14 100644 --- a/node-hub/dora-object-to-pose/pyproject.toml +++ b/node-hub/dora-object-to-pose/pyproject.toml @@ -18,5 +18,6 @@ features = ["python", "pyo3/extension-module"] [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-openai-server/pyproject.toml b/node-hub/dora-openai-server/pyproject.toml index 0ee85030..3af037d1 100644 --- a/node-hub/dora-openai-server/pyproject.toml +++ b/node-hub/dora-openai-server/pyproject.toml @@ -30,6 +30,6 @@ dora-openai-server = "dora_openai_server.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP" -] - + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-opus/pyproject.toml b/node-hub/dora-opus/pyproject.toml index 6e5e8c8f..3876ac5d 100644 --- a/node-hub/dora-opus/pyproject.toml +++ b/node-hub/dora-opus/pyproject.toml @@ -31,5 +31,6 @@ dora-opus = "dora_opus.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-outtetts/pyproject.toml b/node-hub/dora-outtetts/pyproject.toml index faf660a1..0263b0ce 100644 --- a/node-hub/dora-outtetts/pyproject.toml +++ b/node-hub/dora-outtetts/pyproject.toml @@ -31,5 +31,6 @@ dora-outtetts = "dora_outtetts.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-parler/pyproject.toml b/node-hub/dora-parler/pyproject.toml index 1ec01e24..050835a4 100644 --- a/node-hub/dora-parler/pyproject.toml +++ b/node-hub/dora-parler/pyproject.toml @@ -33,5 +33,6 @@ dora-parler = "dora_parler.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-phi4/pyproject.toml b/node-hub/dora-phi4/pyproject.toml index d7cd0ce6..049e2794 100644 --- a/node-hub/dora-phi4/pyproject.toml +++ b/node-hub/dora-phi4/pyproject.toml @@ -34,5 +34,6 @@ dora-phi4 = "dora_phi4.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP" -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-piper/pyproject.toml b/node-hub/dora-piper/pyproject.toml index c7087b9c..b9996e48 100644 --- a/node-hub/dora-piper/pyproject.toml +++ b/node-hub/dora-piper/pyproject.toml @@ -18,5 +18,6 @@ dora-piper = "dora_piper.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-pyaudio/pyproject.toml b/node-hub/dora-pyaudio/pyproject.toml index 7d14dd5a..c4a238ab 100644 --- a/node-hub/dora-pyaudio/pyproject.toml +++ b/node-hub/dora-pyaudio/pyproject.toml @@ -23,5 +23,6 @@ dora-pyaudio = "dora_pyaudio.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-pyorbbecksdk/pyproject.toml b/node-hub/dora-pyorbbecksdk/pyproject.toml index 5b909082..ec8d28b1 100644 --- a/node-hub/dora-pyorbbecksdk/pyproject.toml +++ b/node-hub/dora-pyorbbecksdk/pyproject.toml @@ -21,5 +21,6 @@ dora-pyorbbecksdk = "dora_pyorbbecksdk.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-pyrealsense/pyproject.toml b/node-hub/dora-pyrealsense/pyproject.toml index a05c0ad0..7ae0507c 100644 --- a/node-hub/dora-pyrealsense/pyproject.toml +++ b/node-hub/dora-pyrealsense/pyproject.toml @@ -24,5 +24,6 @@ dora-pyrealsense = "dora_pyrealsense.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-qwen/pyproject.toml b/node-hub/dora-qwen/pyproject.toml index 2f775303..a2874765 100644 --- a/node-hub/dora-qwen/pyproject.toml +++ b/node-hub/dora-qwen/pyproject.toml @@ -45,5 +45,6 @@ dora-qwen = "dora_qwen.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-qwen2-5-vl/pyproject.toml b/node-hub/dora-qwen2-5-vl/pyproject.toml index 5654661f..3a673f95 100644 --- a/node-hub/dora-qwen2-5-vl/pyproject.toml +++ b/node-hub/dora-qwen2-5-vl/pyproject.toml @@ -51,5 +51,6 @@ build-backend = "setuptools.build_meta" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-qwenvl/pyproject.toml b/node-hub/dora-qwenvl/pyproject.toml index b13b5638..f999af03 100644 --- a/node-hub/dora-qwenvl/pyproject.toml +++ b/node-hub/dora-qwenvl/pyproject.toml @@ -38,5 +38,6 @@ dora-qwenvl = "dora_qwenvl.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-rdt-1b/pyproject.toml b/node-hub/dora-rdt-1b/pyproject.toml index ee5c7258..68dffd89 100644 --- a/node-hub/dora-rdt-1b/pyproject.toml +++ b/node-hub/dora-rdt-1b/pyproject.toml @@ -48,5 +48,6 @@ build-backend = "poetry.core.masonry.api" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-reachy1/pyproject.toml b/node-hub/dora-reachy1/pyproject.toml index e3735417..55a13393 100644 --- a/node-hub/dora-reachy1/pyproject.toml +++ b/node-hub/dora-reachy1/pyproject.toml @@ -30,5 +30,6 @@ build-backend = "poetry.core.masonry.api" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP" -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-reachy2/pyproject.toml b/node-hub/dora-reachy2/pyproject.toml index 846b8b18..ca3c7156 100644 --- a/node-hub/dora-reachy2/pyproject.toml +++ b/node-hub/dora-reachy2/pyproject.toml @@ -27,5 +27,6 @@ dora-reachy2-head = "dora_reachy2.head:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-rerun/pyproject.toml b/node-hub/dora-rerun/pyproject.toml index b402d579..61c7fa6a 100644 --- a/node-hub/dora-rerun/pyproject.toml +++ b/node-hub/dora-rerun/pyproject.toml @@ -22,5 +22,6 @@ features = ["python", "pyo3/extension-module"] [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-sam2/pyproject.toml b/node-hub/dora-sam2/pyproject.toml index 82250266..0d85ad96 100644 --- a/node-hub/dora-sam2/pyproject.toml +++ b/node-hub/dora-sam2/pyproject.toml @@ -23,5 +23,6 @@ dora-sam2 = "dora_sam2.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-transformers/dora_transformers/__init__.py b/node-hub/dora-transformers/dora_transformers/__init__.py index ac3cbef9..0d05dafb 100644 --- a/node-hub/dora-transformers/dora_transformers/__init__.py +++ b/node-hub/dora-transformers/dora_transformers/__init__.py @@ -1,3 +1,5 @@ +"""TODO: Add docstring.""" + import os # Define the path to the README file relative to the package directory diff --git a/node-hub/dora-transformers/dora_transformers/__main__.py b/node-hub/dora-transformers/dora_transformers/__main__.py index bcbfde6d..7bc8a1f1 100644 --- a/node-hub/dora-transformers/dora_transformers/__main__.py +++ b/node-hub/dora-transformers/dora_transformers/__main__.py @@ -1,3 +1,5 @@ +"""TODO: Add docstring.""" + from .main import main diff --git a/node-hub/dora-transformers/dora_transformers/main.py b/node-hub/dora-transformers/dora_transformers/main.py index 356d766b..f963b5cb 100644 --- a/node-hub/dora-transformers/dora_transformers/main.py +++ b/node-hub/dora-transformers/dora_transformers/main.py @@ -1,3 +1,5 @@ +"""TODO: Add docstring.""" + import os import pyarrow as pa from dora import Node @@ -31,7 +33,6 @@ ACTIVATION_WORDS = os.getenv("ACTIVATION_WORDS", "what how who where you").split def load_model(): """Load the transformer model and tokenizer.""" - logging.info(f"Loading model {MODEL_NAME} on {DEVICE}") # Memory efficient loading @@ -94,6 +95,7 @@ def generate_response(model, tokenizer, text: str, history) -> tuple[str, list]: return response, history def main(): + """TODO: Add docstring.""" # Initialize model and conversation history model, tokenizer = load_model() # Initialize history with system prompt diff --git a/node-hub/dora-transformers/pyproject.toml b/node-hub/dora-transformers/pyproject.toml index bad5199a..b5236d36 100644 --- a/node-hub/dora-transformers/pyproject.toml +++ b/node-hub/dora-transformers/pyproject.toml @@ -24,3 +24,11 @@ dev = ["pytest >=8.1.1", "ruff >=0.9.1"] [project.scripts] dora-transformer = "dora_transformer.main:main" + + +[tool.ruff.lint] +extend-select = [ + "D", # pydocstyle + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] diff --git a/node-hub/dora-transformers/tests/test_dora_transformers.py b/node-hub/dora-transformers/tests/test_dora_transformers.py index 70d18406..0fec3a9a 100644 --- a/node-hub/dora-transformers/tests/test_dora_transformers.py +++ b/node-hub/dora-transformers/tests/test_dora_transformers.py @@ -1,7 +1,10 @@ +"""TODO: Add docstring.""" + import pytest def test_import_main(): + """TODO: Add docstring.""" from dora_transformers.main import main # Check that everything is working, and catch dora Runtime Exception as we're not running in a dora dataflow. diff --git a/node-hub/dora-ugv/pyproject.toml b/node-hub/dora-ugv/pyproject.toml index 93e5d0a9..26933132 100644 --- a/node-hub/dora-ugv/pyproject.toml +++ b/node-hub/dora-ugv/pyproject.toml @@ -18,5 +18,6 @@ dora-ugv = "dora_ugv.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-vad/pyproject.toml b/node-hub/dora-vad/pyproject.toml index 82e7cc5a..a4d91345 100644 --- a/node-hub/dora-vad/pyproject.toml +++ b/node-hub/dora-vad/pyproject.toml @@ -18,5 +18,6 @@ dora-vad = "dora_vad.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dora-yolo/pyproject.toml b/node-hub/dora-yolo/pyproject.toml index a9d64334..1cd2399c 100644 --- a/node-hub/dora-yolo/pyproject.toml +++ b/node-hub/dora-yolo/pyproject.toml @@ -21,5 +21,6 @@ dora-yolo = "dora_yolo.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/dynamixel-client/pyproject.toml b/node-hub/dynamixel-client/pyproject.toml index 6658d647..310ebdde 100644 --- a/node-hub/dynamixel-client/pyproject.toml +++ b/node-hub/dynamixel-client/pyproject.toml @@ -25,5 +25,6 @@ build-backend = "poetry.core.masonry.api" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP" -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/feetech-client/pyproject.toml b/node-hub/feetech-client/pyproject.toml index ae1f1347..91518d4e 100644 --- a/node-hub/feetech-client/pyproject.toml +++ b/node-hub/feetech-client/pyproject.toml @@ -26,5 +26,6 @@ build-backend = "poetry.core.masonry.api" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP" -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/lebai-client/pyproject.toml b/node-hub/lebai-client/pyproject.toml index 53c4835b..cbd9e8e5 100644 --- a/node-hub/lebai-client/pyproject.toml +++ b/node-hub/lebai-client/pyproject.toml @@ -25,5 +25,6 @@ build-backend = "poetry.core.masonry.api" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP" -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/lerobot-dashboard/pyproject.toml b/node-hub/lerobot-dashboard/pyproject.toml index 863f5e56..346bcf8c 100644 --- a/node-hub/lerobot-dashboard/pyproject.toml +++ b/node-hub/lerobot-dashboard/pyproject.toml @@ -27,5 +27,6 @@ build-backend = "poetry.core.masonry.api" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP" -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/llama-factory-recorder/pyproject.toml b/node-hub/llama-factory-recorder/pyproject.toml index af29d6ed..ad250d8a 100644 --- a/node-hub/llama-factory-recorder/pyproject.toml +++ b/node-hub/llama-factory-recorder/pyproject.toml @@ -24,5 +24,6 @@ llama-factory-recorder = "llama_factory_recorder.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/mujoco-client/pyproject.toml b/node-hub/mujoco-client/pyproject.toml index edc3d5ae..47247bb0 100644 --- a/node-hub/mujoco-client/pyproject.toml +++ b/node-hub/mujoco-client/pyproject.toml @@ -26,5 +26,6 @@ build-backend = "poetry.core.masonry.api" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP" -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/opencv-plot/pyproject.toml b/node-hub/opencv-plot/pyproject.toml index 263b1cb4..493c2679 100644 --- a/node-hub/opencv-plot/pyproject.toml +++ b/node-hub/opencv-plot/pyproject.toml @@ -20,5 +20,6 @@ opencv-plot = "opencv_plot.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/opencv-video-capture/pyproject.toml b/node-hub/opencv-video-capture/pyproject.toml index 67060644..9266f168 100644 --- a/node-hub/opencv-video-capture/pyproject.toml +++ b/node-hub/opencv-video-capture/pyproject.toml @@ -21,5 +21,6 @@ opencv-video-capture = "opencv_video_capture.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/pyarrow-assert/pyproject.toml b/node-hub/pyarrow-assert/pyproject.toml index 273be3cd..ef5557fa 100644 --- a/node-hub/pyarrow-assert/pyproject.toml +++ b/node-hub/pyarrow-assert/pyproject.toml @@ -22,5 +22,6 @@ pyarrow-assert = "pyarrow_assert.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/pyarrow-sender/pyproject.toml b/node-hub/pyarrow-sender/pyproject.toml index 3ae5f3b5..6eff7fbe 100644 --- a/node-hub/pyarrow-sender/pyproject.toml +++ b/node-hub/pyarrow-sender/pyproject.toml @@ -22,5 +22,6 @@ pyarrow-sender = "pyarrow_sender.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/replay-client/pyproject.toml b/node-hub/replay-client/pyproject.toml index eeae03b1..5cf92a1e 100644 --- a/node-hub/replay-client/pyproject.toml +++ b/node-hub/replay-client/pyproject.toml @@ -25,5 +25,6 @@ build-backend = "poetry.core.masonry.api" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP" -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/terminal-input/pyproject.toml b/node-hub/terminal-input/pyproject.toml index a8392144..dfc33165 100644 --- a/node-hub/terminal-input/pyproject.toml +++ b/node-hub/terminal-input/pyproject.toml @@ -22,5 +22,6 @@ terminal-input = "terminal_input.main:main" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP", -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file diff --git a/node-hub/video-encoder/pyproject.toml b/node-hub/video-encoder/pyproject.toml index a1f04880..c92cd694 100644 --- a/node-hub/video-encoder/pyproject.toml +++ b/node-hub/video-encoder/pyproject.toml @@ -27,5 +27,6 @@ build-backend = "poetry.core.masonry.api" [tool.ruff.lint] extend-select = [ "D", # pydocstyle - "UP" -] + "UP", # Ruff's UP rule + "PERF" # Ruff's PERF rule +] \ No newline at end of file From d12b2321997a67d9960a33e898e09229b2bbed07 Mon Sep 17 00:00:00 2001 From: 7SOMAY Date: Mon, 17 Mar 2025 21:09:09 +0530 Subject: [PATCH 2/5] Fixed node-hub linting issues --- apis/python/node/generate_stubs.py | 3 +- .../python/listener/listener-template.py | 1 + .../template/python/talker/talker-template.py | 1 + examples/alexk-lcr/bus.py | 161 ++++++++++++++---- examples/alexk-lcr/configure.py | 41 ++--- .../alexk-lcr/nodes/interpolate_lcr_to_lcr.py | 24 ++- .../nodes/interpolate_lcr_to_record.py | 22 ++- .../nodes/interpolate_lcr_to_simu_lcr.py | 16 +- .../nodes/interpolate_replay_to_lcr.py | 13 +- examples/aloha/benchmark/python/dynamixel.py | 83 +++++---- examples/aloha/benchmark/python/robot.py | 43 ++--- .../python/teleoperate_real_robot.py | 6 +- examples/aloha/benchmark/ros2/teleop.py | 23 ++- examples/aloha/nodes/gym_dora_node.py | 12 +- examples/aloha/nodes/keyboard_node.py | 9 +- examples/aloha/nodes/lerobot_webcam_saver.py | 14 +- examples/aloha/nodes/llm_op.py | 57 +++---- examples/aloha/nodes/plot_node.py | 2 +- examples/aloha/nodes/policy.py | 1 - examples/aloha/nodes/realsense_node.py | 9 +- examples/aloha/nodes/replay.py | 6 +- examples/aloha/nodes/webcam.py | 10 +- examples/aloha/nodes/whisper_node.py | 14 +- examples/aloha/tests/test_realsense.py | 7 +- examples/lebai/nodes/interpolation.py | 9 +- examples/lebai/nodes/key_interpolation.py | 2 +- examples/lebai/nodes/prompt_interpolation.py | 6 +- examples/lebai/nodes/voice_interpolation.py | 2 +- examples/reachy/nodes/gym_dora_node.py | 6 +- examples/reachy/nodes/keyboard_node.py | 9 +- examples/reachy/nodes/lerobot_webcam_saver.py | 14 +- examples/reachy/nodes/plot_node.py | 2 +- examples/reachy/nodes/reachy_client.py | 27 ++- examples/reachy/nodes/reachy_vision_client.py | 6 - examples/reachy/nodes/replay_node.py | 5 +- examples/reachy1/nodes/gym_dora_node.py | 6 +- examples/reachy1/nodes/key_interpolation.py | 2 +- examples/reachy1/nodes/keyboard_node.py | 9 +- .../reachy1/nodes/lerobot_webcam_saver.py | 14 +- examples/reachy1/nodes/plot_node.py | 2 +- examples/reachy1/nodes/reachy_client.py | 27 ++- .../reachy1/nodes/reachy_vision_client.py | 6 - examples/reachy1/nodes/replay_node.py | 5 +- examples/reachy1/nodes/text_interpolation.py | 19 +-- examples/so100/bus.py | 32 ++-- examples/so100/configure.py | 45 ++--- .../so100/nodes/interpolate_lcr_to_so100.py | 25 ++- .../interpolate_lcr_x_so100_to_record.py | 23 ++- .../nodes/interpolate_replay_to_so100.py | 16 +- .../dora_distil_whisper/main.py | 2 +- .../dora_llama_cpp_python/__main__.py | 1 - .../dora_llama_cpp_python/main.py | 21 +-- node-hub/dora-magma/dora_magma/__init__.py | 2 +- node-hub/dora-magma/dora_magma/main.py | 12 +- node-hub/dora-magma/tests/test_magma_node.py | 2 +- .../tests/test_dora_openai_server.py | 1 - .../dora_outtetts/tests/test_main.py | 1 + node-hub/dora-phi4/dora_phi4/main.py | 6 +- node-hub/dora-reachy1/dora_reachy1/main.py | 8 +- .../dora-reachy1/dora_reachy1_vision/main.py | 5 +- .../dora-reachy1/tests/test_dora_reachy1.py | 1 - .../dora-reachy2/tests/test_dora_reachy2.py | 1 - .../dora_transformers/__init__.py | 2 +- .../dora_transformers/__main__.py | 1 - .../dora_transformers/main.py | 43 ++--- .../dynamixel-client/dynamixel_client/bus.py | 23 +-- .../dynamixel-client/dynamixel_client/main.py | 15 +- .../tests/test_dynamixel_client.py | 1 - .../feetech-client/feetech_client/__init__.py | 2 +- node-hub/feetech-client/feetech_client/bus.py | 8 +- .../feetech-client/feetech_client/main.py | 11 +- .../tests/test_feetech_client.py | 1 - node-hub/lebai-client/lebai_client/main.py | 11 +- node-hub/lebai-client/test/test.py | 3 +- .../lebai-client/tests/test_lebai_client.py | 1 - .../lerobot_dashboard/__init__.py | 2 +- .../lerobot_dashboard/main.py | 16 +- .../tests/test_lerobot_dashboard.py | 1 - .../mujoco-client/mujoco_client/__init__.py | 2 +- node-hub/mujoco-client/mujoco_client/main.py | 23 +-- .../mujoco-client/tests/test_mujoco_client.py | 1 - .../replay-client/replay_client/__init__.py | 2 +- node-hub/replay-client/replay_client/main.py | 7 +- .../replay-client/tests/test_replay_client.py | 1 - .../video-encoder/tests/test_video_encoder.py | 1 - .../video-encoder/video_encoder/__init__.py | 2 +- node-hub/video-encoder/video_encoder/main.py | 14 +- 87 files changed, 584 insertions(+), 570 deletions(-) diff --git a/apis/python/node/generate_stubs.py b/apis/python/node/generate_stubs.py index 298928bd..0acc9595 100644 --- a/apis/python/node/generate_stubs.py +++ b/apis/python/node/generate_stubs.py @@ -287,8 +287,7 @@ def arguments_stub( param_names = list(real_parameters.keys()) if param_names and param_names[0] == "self": del param_names[0] - for name, t in zip(param_names, builtin[0]): - parsed_param_types[name] = t + parsed_param_types = {name: t for name, t in zip(param_names, builtin[0])} # Types from comment for match in re.findall( diff --git a/binaries/cli/src/template/python/listener/listener-template.py b/binaries/cli/src/template/python/listener/listener-template.py index 140718f2..ebcc5501 100644 --- a/binaries/cli/src/template/python/listener/listener-template.py +++ b/binaries/cli/src/template/python/listener/listener-template.py @@ -2,6 +2,7 @@ from dora import Node + def main(): """Listen for input events and print received messages.""" node = Node() diff --git a/binaries/cli/src/template/python/talker/talker-template.py b/binaries/cli/src/template/python/talker/talker-template.py index 703d6f72..e8811b65 100644 --- a/binaries/cli/src/template/python/talker/talker-template.py +++ b/binaries/cli/src/template/python/talker/talker-template.py @@ -3,6 +3,7 @@ import pyarrow as pa from dora import Node + def main(): """Process node input events and send speech output.""" node = Node() diff --git a/examples/alexk-lcr/bus.py b/examples/alexk-lcr/bus.py index d123fa67..78043e6a 100644 --- a/examples/alexk-lcr/bus.py +++ b/examples/alexk-lcr/bus.py @@ -1,17 +1,25 @@ -import enum +"""Module for managing Dynamixel servo bus communication and control. -import pyarrow as pa +This module provides functionality for communicating with and controlling Dynamixel servos +through a serial bus interface. It includes methods for reading and writing servo parameters, +managing torque and operating modes, and handling joint positions and velocities. +""" +import enum from typing import Union +import pyarrow as pa from dynamixel_sdk import ( - PacketHandler, - PortHandler, COMM_SUCCESS, + DXL_HIBYTE, + DXL_HIWORD, + DXL_LOBYTE, + DXL_LOWORD, GroupSyncRead, GroupSyncWrite, + PacketHandler, + PortHandler, ) -from dynamixel_sdk import DXL_HIBYTE, DXL_HIWORD, DXL_LOBYTE, DXL_LOWORD PROTOCOL_VERSION = 2.0 BAUD_RATE = 1_000_000 @@ -20,40 +28,37 @@ TIMEOUT_MS = 1000 def wrap_joints_and_values( joints: Union[list[str], pa.Array], - values: Union[int, list[int], pa.Array], + values: Union[list[int], pa.Array], ) -> pa.StructArray: - """ - Wraps joints and their corresponding values into a structured array. + """Wrap joints and their corresponding values into a structured array. - :param joints: A list, numpy array, or pyarrow array of joint names. - :type joints: Union[list[str], np.array, pa.Array] - :param values: A single integer value, or a list, numpy array, or pyarrow array of integer values. - If a single integer is provided, it will be broadcasted to all joints. - :type values: Union[int, list[int], np.array, pa.Array] + Args: + joints: A list, numpy array, or pyarrow array of joint names. + values: A single integer value, or a list, numpy array, or pyarrow array of integer values. + If a single integer is provided, it will be broadcasted to all joints. - :return: A structured array with two fields: - - "joints": A string field containing the names of the joints. - - "values": An Int32Array containing the values corresponding to the joints. - :rtype: pa.StructArray + Returns: + A structured array with two fields: + - "joints": A string field containing the names of the joints. + - "values": An Int32Array containing the values corresponding to the joints. - :raises ValueError: If lengths of joints and values do not match. + Raises: + ValueError: If lengths of joints and values do not match. Example: - -------- - joints = ["shoulder_pan", "shoulder_lift", "elbow_flex"] - values = [100, 200, 300] - struct_array = wrap_joints_and_values(joints, values) + joints = ["shoulder_pan", "shoulder_lift", "elbow_flex"] + values = [100, 200, 300] + struct_array = wrap_joints_and_values(joints, values) - This example wraps the given joints and their corresponding values into a structured array. + This example wraps the given joints and their corresponding values into a structured array. - Another example with a single integer value: - joints = ["shoulder_pan", "shoulder_lift", "elbow_flex"] - value = 150 - struct_array = wrap_joints_and_values(joints, value) + Another example with a single integer value: + joints = ["shoulder_pan", "shoulder_lift", "elbow_flex"] + value = 150 + struct_array = wrap_joints_and_values(joints, value) - This example broadcasts the single integer value to all joints and wraps them into a structured array. + This example broadcasts the single integer value to all joints and wraps them into a structured array. """ - if isinstance(values, int): values = [values] * len(joints) @@ -69,16 +74,20 @@ def wrap_joints_and_values( mask = values.is_null() return pa.StructArray.from_arrays( - arrays=[joints, values], names=["joints", "values"], mask=mask + arrays=[joints, values], names=["joints", "values"], mask=mask, ).drop_null() class TorqueMode(enum.Enum): + """Enumeration for servo torque control modes.""" + ENABLED = pa.scalar(1, pa.uint32()) DISABLED = pa.scalar(0, pa.uint32()) class OperatingMode(enum.Enum): + """Enumeration for servo operating modes.""" + VELOCITY = pa.scalar(1, pa.uint32()) POSITION = pa.scalar(3, pa.uint32()) EXTENDED_POSITION = pa.scalar(4, pa.uint32()) @@ -152,8 +161,17 @@ MODEL_CONTROL_TABLE = { class DynamixelBus: + """Class for managing communication with Dynamixel servos on a serial bus.""" def __init__(self, port: str, description: dict[str, (int, str)]): + """Initialize the Dynamixel bus connection. + + Args: + port: The serial port to connect to the Dynamixel bus. + description: A dictionary containing the description of the motors connected to the bus. + The keys are the motor names and the values are tuples containing the motor id + and the motor model. + """ self.port = port self.descriptions = description self.motor_ctrl = {} @@ -184,9 +202,16 @@ class DynamixelBus: self.group_writers = {} def close(self): + """Close the serial port connection.""" self.port_handler.closePort() def write(self, data_name: str, data: pa.StructArray): + """Write data to the specified servo parameters. + + Args: + data_name: Name of the parameter to write. + data: Structured array containing the data to write. + """ motor_ids = [ self.motor_ctrl[motor_name.as_py()]["id"] for motor_name in data.field("joints") @@ -239,7 +264,7 @@ class DynamixelBus: else: raise NotImplementedError( f"Value of the number of bytes to be sent is expected to be in [1, 2, 4], but {packet_bytes_size} " - f"is provided instead." + f"is provided instead.", ) if init_group: @@ -251,10 +276,19 @@ class DynamixelBus: if comm != COMM_SUCCESS: raise ConnectionError( f"Write failed due to communication error on port {self.port} for group_key {group_key}: " - f"{self.packet_handler.getTxRxResult(comm)}" + f"{self.packet_handler.getTxRxResult(comm)}", ) def read(self, data_name: str, motor_names: pa.Array) -> pa.StructArray: + """Read data from the specified servo parameters. + + Args: + data_name: Name of the parameter to read. + motor_names: Array of motor names to read from. + + Returns: + Structured array containing the read data. + """ motor_ids = [ self.motor_ctrl[motor_name.as_py()]["id"] for motor_name in motor_names ] @@ -281,13 +315,13 @@ class DynamixelBus: if comm != COMM_SUCCESS: raise ConnectionError( f"Read failed due to communication error on port {self.port} for group_key {group_key}: " - f"{self.packet_handler.getTxRxResult(comm)}" + f"{self.packet_handler.getTxRxResult(comm)}", ) values = pa.array( [ self.group_readers[group_key].getData( - idx, packet_address, packet_bytes_size + idx, packet_address, packet_bytes_size, ) for idx in motor_ids ], @@ -298,31 +332,90 @@ class DynamixelBus: return wrap_joints_and_values(motor_names, values) def write_torque_enable(self, torque_mode: pa.StructArray): + """Enable or disable torque for the specified servos. + + Args: + torque_mode: Structured array containing the torque mode for each servo. + """ self.write("Torque_Enable", torque_mode) def write_operating_mode(self, operating_mode: pa.StructArray): + """Set the operating mode for the specified servos. + + Args: + operating_mode: Structured array containing the operating mode for each servo. + """ self.write("Operating_Mode", operating_mode) def read_position(self, motor_names: pa.Array) -> pa.StructArray: + """Read the current position of the specified servos. + + Args: + motor_names: Array of motor names to read positions from. + + Returns: + Structured array containing the current positions. + """ return self.read("Present_Position", motor_names) def read_velocity(self, motor_names: pa.Array) -> pa.StructArray: + """Read the current velocity of the specified servos. + + Args: + motor_names: Array of motor names to read velocities from. + + Returns: + Structured array containing the current velocities. + """ return self.read("Present_Velocity", motor_names) def read_current(self, motor_names: pa.Array) -> pa.StructArray: + """Read the current current of the specified servos. + + Args: + motor_names: Array of motor names to read currents from. + + Returns: + Structured array containing the current currents. + """ return self.read("Present_Current", motor_names) def write_goal_position(self, goal_position: pa.StructArray): + """Set the goal position for the specified servos. + + Args: + goal_position: Structured array containing the goal positions. + """ self.write("Goal_Position", goal_position) def write_goal_current(self, goal_current: pa.StructArray): + """Set the goal current for the specified servos. + + Args: + goal_current: Structured array containing the goal currents. + """ self.write("Goal_Current", goal_current) def write_position_p_gain(self, position_p_gain: pa.StructArray): + """Set the position P gain for the specified servos. + + Args: + position_p_gain: Structured array containing the position P gains. + """ self.write("Position_P_Gain", position_p_gain) def write_position_i_gain(self, position_i_gain: pa.StructArray): + """Set the position I gain for the specified servos. + + Args: + position_i_gain: Structured array containing the position I gains. + """ self.write("Position_I_Gain", position_i_gain) def write_position_d_gain(self, position_d_gain: pa.StructArray): + """Set the position D gain for the specified servos. + + Args: + position_d_gain: Structured array containing the position D gains. + """ self.write("Position_D_Gain", position_d_gain) diff --git a/examples/alexk-lcr/configure.py b/examples/alexk-lcr/configure.py index 723a8401..dd72bd58 100644 --- a/examples/alexk-lcr/configure.py +++ b/examples/alexk-lcr/configure.py @@ -1,5 +1,4 @@ -""" -LCR Configuration Tool: This program is used to automatically configure the Low Cost Robot (LCR) for the user. +"""LCR Configuration Tool: This program is used to automatically configure the Low Cost Robot (LCR) for the user. The program will: 1. Disable all torque motors of provided LCR. @@ -14,21 +13,17 @@ It will also enable all appropriate operating modes for the LCR. """ import argparse -import time import json +import time import pyarrow as pa - -from bus import DynamixelBus, TorqueMode, OperatingMode - -from pwm_position_control.transform import pwm_to_logical_arrow, wrap_joints_and_values - +from bus import DynamixelBus, OperatingMode, TorqueMode +from pwm_position_control.functions import construct_control_table from pwm_position_control.tables import ( construct_logical_to_pwm_conversion_table_arrow, construct_pwm_to_logical_conversion_table_arrow, ) - -from pwm_position_control.functions import construct_control_table +from pwm_position_control.transform import pwm_to_logical_arrow, wrap_joints_and_values FULL_ARM = pa.array( [ @@ -56,26 +51,26 @@ def pause(): def configure_servos(bus: DynamixelBus): bus.write_torque_enable( - wrap_joints_and_values(FULL_ARM, [TorqueMode.DISABLED.value] * 6) + wrap_joints_and_values(FULL_ARM, [TorqueMode.DISABLED.value] * 6), ) bus.write_operating_mode( wrap_joints_and_values( - ARM_WITHOUT_GRIPPER, [OperatingMode.EXTENDED_POSITION.value] * 5 - ) + ARM_WITHOUT_GRIPPER, [OperatingMode.EXTENDED_POSITION.value] * 5, + ), ) bus.write_operating_mode( wrap_joints_and_values( - GRIPPER, [OperatingMode.CURRENT_CONTROLLED_POSITION.value] - ) + GRIPPER, [OperatingMode.CURRENT_CONTROLLED_POSITION.value], + ), ) def main(): parser = argparse.ArgumentParser( description="LCR Auto Configure: This program is used to automatically configure the Low Cost Robot (LCR) for " - "the user." + "the user.", ) parser.add_argument("--port", type=str, required=True, help="The port of the LCR.") @@ -95,7 +90,7 @@ def main(): help="If the LCR is the follower of the user.", ) parser.add_argument( - "--leader", action="store_true", help="If the LCR is the leader of the user." + "--leader", action="store_true", help="If the LCR is the leader of the user.", ) args = parser.parse_args() @@ -138,10 +133,10 @@ def main(): pwm_positions = (pwm_position_1, pwm_position_2) pwm_to_logical_conversion_table = construct_pwm_to_logical_conversion_table_arrow( - pwm_positions, targets + pwm_positions, targets, ) logical_to_pwm_conversion_table = construct_logical_to_pwm_conversion_table_arrow( - pwm_positions, targets + pwm_positions, targets, ) control_table_json = {} @@ -180,7 +175,7 @@ def main(): path = ( input( - f"Please enter the path of the configuration file (default is ./examples/alexk-lcr/configs/{leader}.{left}.json): " + f"Please enter the path of the configuration file (default is ./examples/alexk-lcr/configs/{leader}.{left}.json): ", ) or f"./examples/alexk-lcr/configs/{leader}.{left}.json" ) @@ -189,21 +184,21 @@ def main(): json.dump(control_table_json, file) control_table = construct_control_table( - pwm_to_logical_conversion_table, logical_to_pwm_conversion_table + pwm_to_logical_conversion_table, logical_to_pwm_conversion_table, ) while True: try: pwm_position = arm.read_position(FULL_ARM) logical_position = pwm_to_logical_arrow( - pwm_position, control_table, ranged=True + pwm_position, control_table, ranged=True, ).field("values") print(f"Logical Position: {logical_position}") except ConnectionError: print( - "Connection error occurred. Please check the connection and try again." + "Connection error occurred. Please check the connection and try again.", ) time.sleep(0.5) diff --git a/examples/alexk-lcr/nodes/interpolate_lcr_to_lcr.py b/examples/alexk-lcr/nodes/interpolate_lcr_to_lcr.py index 9f9abc33..c3c42fb3 100644 --- a/examples/alexk-lcr/nodes/interpolate_lcr_to_lcr.py +++ b/examples/alexk-lcr/nodes/interpolate_lcr_to_lcr.py @@ -1,24 +1,22 @@ -import os import argparse import json +import os import pyarrow as pa import pyarrow.compute as pc - from dora import Node - +from pwm_position_control.load import load_control_table_from_json_conversion_tables from pwm_position_control.transform import ( - wrap_joints_and_values, - pwm_to_logical_arrow, logical_to_pwm_with_offset_arrow, + pwm_to_logical_arrow, + wrap_joints_and_values, ) -from pwm_position_control.load import load_control_table_from_json_conversion_tables def main(): parser = argparse.ArgumentParser( description="Interpolation LCR Node: This Dora node is used to calculates appropriate goal positions for the " - "LCR followers knowing a Leader position and Follower position." + "LCR followers knowing a Leader position and Follower position.", ) parser.add_argument( @@ -46,19 +44,19 @@ def main(): if not os.environ.get("LEADER_CONTROL") and args.leader_control is None: raise ValueError( "The leader control is not set. Please set the configuration of the leader in the environment variables or " - "as an argument." + "as an argument.", ) if not os.environ.get("FOLLOWER_CONTROL") and args.follower_control is None: raise ValueError( "The follower control is not set. Please set the configuration of the follower in the environment " - "variables or as an argument." + "variables or as an argument.", ) with open( os.environ.get("LEADER_CONTROL") if args.leader_control is None - else args.leader_control + else args.leader_control, ) as file: leader_control = json.load(file) load_control_table_from_json_conversion_tables(leader_control, leader_control) @@ -66,11 +64,11 @@ def main(): with open( os.environ.get("FOLLOWER_CONTROL") if args.follower_control is None - else args.follower_control + else args.follower_control, ) as file: follower_control = json.load(file) load_control_table_from_json_conversion_tables( - follower_control, follower_control + follower_control, follower_control, ) initial_mask = [ @@ -130,7 +128,7 @@ def main(): ) pwm_goal = logical_to_pwm_with_offset_arrow( - follower_position, logical_goal, follower_control + follower_position, logical_goal, follower_control, ) node.send_output("follower_goal", pwm_goal, event["metadata"]) diff --git a/examples/alexk-lcr/nodes/interpolate_lcr_to_record.py b/examples/alexk-lcr/nodes/interpolate_lcr_to_record.py index ce3d43d9..c04022f8 100644 --- a/examples/alexk-lcr/nodes/interpolate_lcr_to_record.py +++ b/examples/alexk-lcr/nodes/interpolate_lcr_to_record.py @@ -1,23 +1,21 @@ -import os import argparse import json +import os import pyarrow as pa import pyarrow.compute as pc - from dora import Node - from pwm_position_control.load import load_control_table_from_json_conversion_tables from pwm_position_control.transform import ( - wrap_joints_and_values, pwm_to_logical_arrow, + wrap_joints_and_values, ) def main(): parser = argparse.ArgumentParser( description="Interpolation LCR Node: This Dora node is used to calculates appropriate goal positions for the " - "LCR followers knowing a Leader position and Follower position." + "LCR followers knowing a Leader position and Follower position.", ) parser.add_argument( @@ -45,19 +43,19 @@ def main(): if not os.environ.get("LEADER_CONTROL") and args.leader_control is None: raise ValueError( "The leader control is not set. Please set the configuration of the leader in the environment variables or " - "as an argument." + "as an argument.", ) if not os.environ.get("FOLLOWER_CONTROL") and args.follower_control is None: raise ValueError( "The follower control is not set. Please set the configuration of the follower in the environment " - "variables or as an argument." + "variables or as an argument.", ) with open( os.environ.get("LEADER_CONTROL") if args.leader_control is None - else args.leader_control + else args.leader_control, ) as file: leader_control = json.load(file) load_control_table_from_json_conversion_tables(leader_control, leader_control) @@ -65,11 +63,11 @@ def main(): with open( os.environ.get("FOLLOWER_CONTROL") if args.follower_control is None - else args.follower_control + else args.follower_control, ) as file: follower_control = json.load(file) load_control_table_from_json_conversion_tables( - follower_control, follower_control + follower_control, follower_control, ) node = Node(args.name) @@ -98,11 +96,11 @@ def main(): follower_position = event["value"] follower_position = pwm_to_logical_arrow( - follower_position, follower_control + follower_position, follower_control, ) node.send_output( - "logical_position", follower_position, event["metadata"] + "logical_position", follower_position, event["metadata"], ) elif event_type == "ERROR": diff --git a/examples/alexk-lcr/nodes/interpolate_lcr_to_simu_lcr.py b/examples/alexk-lcr/nodes/interpolate_lcr_to_simu_lcr.py index e0e2d396..925af277 100644 --- a/examples/alexk-lcr/nodes/interpolate_lcr_to_simu_lcr.py +++ b/examples/alexk-lcr/nodes/interpolate_lcr_to_simu_lcr.py @@ -1,25 +1,23 @@ -import os import argparse import json +import os import numpy as np import pyarrow as pa import pyarrow.compute as pc - from dora import Node - from pwm_position_control.load import load_control_table_from_json_conversion_tables from pwm_position_control.transform import ( - wrap_joints_and_values, - pwm_to_logical_arrow, logical_to_pwm_with_offset_arrow, + pwm_to_logical_arrow, + wrap_joints_and_values, ) def main(): parser = argparse.ArgumentParser( description="Interpolation LCR Node: This Dora node is used to calculates appropriate goal positions for the " - "LCR followers knowing a Leader position and Follower position." + "LCR followers knowing a Leader position and Follower position.", ) parser.add_argument( @@ -41,13 +39,13 @@ def main(): if not os.environ.get("LEADER_CONTROL") and args.leader_control is None: raise ValueError( "The leader control is not set. Please set the configuration of the leader in the environment variables or " - "as an argument." + "as an argument.", ) with open( os.environ.get("LEADER_CONTROL") if args.leader_control is None - else args.leader_control + else args.leader_control, ) as file: leader_control = json.load(file) load_control_table_from_json_conversion_tables(leader_control, leader_control) @@ -114,7 +112,7 @@ def main(): [ joint.as_py() + "_joint" for joint in leader_position.field("joints") - ] + ], ), pc.multiply( pc.add(leader_position.field("values"), interpolation_a), diff --git a/examples/alexk-lcr/nodes/interpolate_replay_to_lcr.py b/examples/alexk-lcr/nodes/interpolate_replay_to_lcr.py index 53024c35..b4ee763b 100644 --- a/examples/alexk-lcr/nodes/interpolate_replay_to_lcr.py +++ b/examples/alexk-lcr/nodes/interpolate_replay_to_lcr.py @@ -1,9 +1,8 @@ -import os import argparse import json +import os from dora import Node - from pwm_position_control.load import load_control_table_from_json_conversion_tables from pwm_position_control.transform import logical_to_pwm_with_offset_arrow @@ -11,7 +10,7 @@ from pwm_position_control.transform import logical_to_pwm_with_offset_arrow def main(): parser = argparse.ArgumentParser( description="Interpolation LCR Node: This Dora node is used to calculates appropriate goal positions for the " - "LCR followers knowing a Leader position and Follower position." + "LCR followers knowing a Leader position and Follower position.", ) parser.add_argument( @@ -33,17 +32,17 @@ def main(): if not os.environ.get("FOLLOWER_CONTROL") and args.follower_control is None: raise ValueError( "The follower control is not set. Please set the configuration of the follower in the environment " - "variables or as an argument." + "variables or as an argument.", ) with open( os.environ.get("FOLLOWER_CONTROL") if args.follower_control is None - else args.follower_control + else args.follower_control, ) as file: follower_control = json.load(file) load_control_table_from_json_conversion_tables( - follower_control, follower_control + follower_control, follower_control, ) node = Node(args.name) @@ -65,7 +64,7 @@ def main(): continue physical_goal = logical_to_pwm_with_offset_arrow( - follower_position, leader_position, follower_control + follower_position, leader_position, follower_control, ) node.send_output("follower_goal", physical_goal, event["metadata"]) diff --git a/examples/aloha/benchmark/python/dynamixel.py b/examples/aloha/benchmark/python/dynamixel.py index 636522b6..fefa28f8 100644 --- a/examples/aloha/benchmark/python/dynamixel.py +++ b/examples/aloha/benchmark/python/dynamixel.py @@ -1,10 +1,12 @@ from __future__ import annotations + +import enum import math import os -from dynamixel_sdk import * # Uses Dynamixel SDK library -from dataclasses import dataclass -import enum import time +from dataclasses import dataclass + +from dynamixel_sdk import * # Uses Dynamixel SDK library class ReadAttribute(enum.Enum): @@ -87,7 +89,7 @@ class Dynamixel: # self._enable_torque(motor_id) dxl_comm_result, dxl_error = self.packetHandler.write4ByteTxRx( - self.portHandler, motor_id, self.ADDR_GOAL_POSITION, goal_position + self.portHandler, motor_id, self.ADDR_GOAL_POSITION, goal_position, ) # self._process_response(dxl_comm_result, dxl_error) # print(f'set position of motor {motor_id} to {goal_position}') @@ -101,24 +103,23 @@ class Dynamixel: self._enable_torque(motor_id) # print(f'enabling torque') dxl_comm_result, dxl_error = self.packetHandler.write2ByteTxRx( - self.portHandler, motor_id, self.ADDR_GOAL_PWM, pwm_value + self.portHandler, motor_id, self.ADDR_GOAL_PWM, pwm_value, ) # self._process_response(dxl_comm_result, dxl_error) # print(f'set pwm of motor {motor_id} to {pwm_value}') if dxl_comm_result != COMM_SUCCESS: if tries <= 1: raise ConnectionError( - f"dxl_comm_result: {self.packetHandler.getTxRxResult(dxl_comm_result)}" - ) - else: - print( - f"dynamixel pwm setting failure trying again with {tries - 1} tries" + f"dxl_comm_result: {self.packetHandler.getTxRxResult(dxl_comm_result)}", ) - self.set_pwm_value(motor_id, pwm_value, tries=tries - 1) + print( + f"dynamixel pwm setting failure trying again with {tries - 1} tries", + ) + self.set_pwm_value(motor_id, pwm_value, tries=tries - 1) elif dxl_error != 0: print(f"dxl error {dxl_error}") raise ConnectionError( - f"dynamixel error: {self.packetHandler.getTxRxResult(dxl_error)}" + f"dynamixel error: {self.packetHandler.getTxRxResult(dxl_error)}", ) def read_temperature(self, motor_id: int): @@ -157,8 +158,7 @@ class Dynamixel: return self._read_value(motor_id, ReadAttribute.HARDWARE_ERROR_STATUS, 1) def set_id(self, old_id, new_id, use_broadcast_id: bool = False): - """ - sets the id of the dynamixel servo + """Sets the id of the dynamixel servo @param old_id: current id of the servo @param new_id: new id @param use_broadcast_id: set ids of all connected dynamixels if True. @@ -170,21 +170,21 @@ class Dynamixel: else: current_id = old_id dxl_comm_result, dxl_error = self.packetHandler.write1ByteTxRx( - self.portHandler, current_id, self.ADDR_ID, new_id + self.portHandler, current_id, self.ADDR_ID, new_id, ) self._process_response(dxl_comm_result, dxl_error, old_id) self.config.id = id def _enable_torque(self, motor_id): dxl_comm_result, dxl_error = self.packetHandler.write1ByteTxRx( - self.portHandler, motor_id, self.ADDR_TORQUE_ENABLE, 1 + self.portHandler, motor_id, self.ADDR_TORQUE_ENABLE, 1, ) self._process_response(dxl_comm_result, dxl_error, motor_id) self.torque_enabled[motor_id] = True def _disable_torque(self, motor_id): dxl_comm_result, dxl_error = self.packetHandler.write1ByteTxRx( - self.portHandler, motor_id, self.ADDR_TORQUE_ENABLE, 0 + self.portHandler, motor_id, self.ADDR_TORQUE_ENABLE, 0, ) self._process_response(dxl_comm_result, dxl_error, motor_id) self.torque_enabled[motor_id] = False @@ -192,42 +192,42 @@ class Dynamixel: def _process_response(self, dxl_comm_result: int, dxl_error: int, motor_id: int): if dxl_comm_result != COMM_SUCCESS: raise ConnectionError( - f"dxl_comm_result for motor {motor_id}: {self.packetHandler.getTxRxResult(dxl_comm_result)}" + f"dxl_comm_result for motor {motor_id}: {self.packetHandler.getTxRxResult(dxl_comm_result)}", ) - elif dxl_error != 0: + if dxl_error != 0: print(f"dxl error {dxl_error}") raise ConnectionError( - f"dynamixel error for motor {motor_id}: {self.packetHandler.getTxRxResult(dxl_error)}" + f"dynamixel error for motor {motor_id}: {self.packetHandler.getTxRxResult(dxl_error)}", ) def set_operating_mode(self, motor_id: int, operating_mode: OperatingMode): dxl_comm_result, dxl_error = self.packetHandler.write2ByteTxRx( - self.portHandler, motor_id, self.OPERATING_MODE_ADDR, operating_mode.value + self.portHandler, motor_id, self.OPERATING_MODE_ADDR, operating_mode.value, ) self._process_response(dxl_comm_result, dxl_error, motor_id) self.operating_modes[motor_id] = operating_mode def set_pwm_limit(self, motor_id: int, limit: int): dxl_comm_result, dxl_error = self.packetHandler.write2ByteTxRx( - self.portHandler, motor_id, 36, limit + self.portHandler, motor_id, 36, limit, ) self._process_response(dxl_comm_result, dxl_error, motor_id) def set_velocity_limit(self, motor_id: int, velocity_limit): dxl_comm_result, dxl_error = self.packetHandler.write4ByteTxRx( - self.portHandler, motor_id, self.ADDR_VELOCITY_LIMIT, velocity_limit + self.portHandler, motor_id, self.ADDR_VELOCITY_LIMIT, velocity_limit, ) self._process_response(dxl_comm_result, dxl_error, motor_id) def set_P(self, motor_id: int, P: int): dxl_comm_result, dxl_error = self.packetHandler.write2ByteTxRx( - self.portHandler, motor_id, self.POSITION_P, P + self.portHandler, motor_id, self.POSITION_P, P, ) self._process_response(dxl_comm_result, dxl_error, motor_id) def set_I(self, motor_id: int, I: int): dxl_comm_result, dxl_error = self.packetHandler.write2ByteTxRx( - self.portHandler, motor_id, self.POSITION_I, I + self.portHandler, motor_id, self.POSITION_I, I, ) self._process_response(dxl_comm_result, dxl_error, motor_id) @@ -243,7 +243,7 @@ class Dynamixel: def set_home_offset(self, motor_id: int, home_position: int): self._disable_torque(motor_id) dxl_comm_result, dxl_error = self.packetHandler.write4ByteTxRx( - self.portHandler, motor_id, ReadAttribute.HOMING_OFFSET.value, home_position + self.portHandler, motor_id, ReadAttribute.HOMING_OFFSET.value, home_position, ) self._process_response(dxl_comm_result, dxl_error, motor_id) self._enable_torque(motor_id) @@ -265,7 +265,7 @@ class Dynamixel: self._disable_torque(motor_id) dxl_comm_result, dxl_error = self.packetHandler.write1ByteTxRx( - self.portHandler, motor_id, ReadAttribute.BAUDRATE.value, baudrate_id + self.portHandler, motor_id, ReadAttribute.BAUDRATE.value, baudrate_id, ) self._process_response(dxl_comm_result, dxl_error, motor_id) @@ -273,43 +273,40 @@ class Dynamixel: try: if num_bytes == 1: value, dxl_comm_result, dxl_error = self.packetHandler.read1ByteTxRx( - self.portHandler, motor_id, attribute.value + self.portHandler, motor_id, attribute.value, ) elif num_bytes == 2: value, dxl_comm_result, dxl_error = self.packetHandler.read2ByteTxRx( - self.portHandler, motor_id, attribute.value + self.portHandler, motor_id, attribute.value, ) elif num_bytes == 4: value, dxl_comm_result, dxl_error = self.packetHandler.read4ByteTxRx( - self.portHandler, motor_id, attribute.value + self.portHandler, motor_id, attribute.value, ) except Exception: if tries == 0: raise Exception - else: - return self._read_value(motor_id, attribute, num_bytes, tries=tries - 1) + return self._read_value(motor_id, attribute, num_bytes, tries=tries - 1) if dxl_comm_result != COMM_SUCCESS: if tries <= 1: # print("%s" % self.packetHandler.getTxRxResult(dxl_comm_result)) raise ConnectionError( - f"dxl_comm_result {dxl_comm_result} for servo {motor_id} value {value}" - ) - else: - print( - f"dynamixel read failure for servo {motor_id} trying again with {tries - 1} tries" + f"dxl_comm_result {dxl_comm_result} for servo {motor_id} value {value}", ) - time.sleep(0.02) - return self._read_value(motor_id, attribute, num_bytes, tries=tries - 1) - elif ( + print( + f"dynamixel read failure for servo {motor_id} trying again with {tries - 1} tries", + ) + time.sleep(0.02) + return self._read_value(motor_id, attribute, num_bytes, tries=tries - 1) + if ( dxl_error != 0 ): # # print("%s" % self.packetHandler.getRxPacketError(dxl_error)) # raise ConnectionError(f'dxl_error {dxl_error} binary ' + "{0:b}".format(37)) if tries == 0 and dxl_error != 128: raise Exception( - f"Failed to read value from motor {motor_id} error is {dxl_error}" + f"Failed to read value from motor {motor_id} error is {dxl_error}", ) - else: - return self._read_value(motor_id, attribute, num_bytes, tries=tries - 1) + return self._read_value(motor_id, attribute, num_bytes, tries=tries - 1) return value def set_home_position(self, motor_id: int): diff --git a/examples/aloha/benchmark/python/robot.py b/examples/aloha/benchmark/python/robot.py index b57ff7b7..b2c1b0d6 100644 --- a/examples/aloha/benchmark/python/robot.py +++ b/examples/aloha/benchmark/python/robot.py @@ -1,16 +1,17 @@ -import numpy as np -from dynamixel import Dynamixel, OperatingMode, ReadAttribute import time +from enum import Enum, auto +from typing import Union + +import numpy as np +from dynamixel import OperatingMode, ReadAttribute from dynamixel_sdk import ( - GroupSyncRead, - GroupSyncWrite, - DXL_LOBYTE, DXL_HIBYTE, - DXL_LOWORD, DXL_HIWORD, + DXL_LOBYTE, + DXL_LOWORD, + GroupSyncRead, + GroupSyncWrite, ) -from enum import Enum, auto -from typing import Union class MotorControlType(Enum): @@ -65,8 +66,7 @@ class Robot: self.motor_control_state = MotorControlType.DISABLED def read_position(self, tries=2): - """ - Reads the joint positions of the robot. 2048 is the center position. 0 and 4096 are 180 degrees in each direction. + """Reads the joint positions of the robot. 2048 is the center position. 0 and 4096 are 180 degrees in each direction. :param tries: maximum number of tries to read the position :return: list of joint positions in range [0, 4096] """ @@ -74,8 +74,7 @@ class Robot: if result != 0: if tries > 0: return self.read_position(tries=tries - 1) - else: - print(f"failed to read position!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") + print("failed to read position!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") positions = [] for id in self.servo_ids: position = self.position_reader.getData(id, ReadAttribute.POSITION.value, 4) @@ -85,8 +84,7 @@ class Robot: return positions def read_velocity(self): - """ - Reads the joint velocities of the robot. + """Reads the joint velocities of the robot. :return: list of joint velocities, """ self.velocity_reader.txRxPacket() @@ -99,11 +97,9 @@ class Robot: return velocties def set_goal_pos(self, action): + """:param action: list or numpy array of target joint positions in range [0, 4096] """ - - :param action: list or numpy array of target joint positions in range [0, 4096] - """ - if not self.motor_control_state is MotorControlType.POSITION_CONTROL: + if self.motor_control_state is not MotorControlType.POSITION_CONTROL: self._set_position_control() for i, motor_id in enumerate(self.servo_ids): data_write = [ @@ -117,11 +113,10 @@ class Robot: self.pos_writer.txPacket() def set_pwm(self, action): - """ - Sets the pwm values for the servos. + """Sets the pwm values for the servos. :param action: list or numpy array of pwm values in range [0, 885] """ - if not self.motor_control_state is MotorControlType.PWM: + if self.motor_control_state is not MotorControlType.PWM: self._set_pwm_control() for i, motor_id in enumerate(self.servo_ids): data_write = [ @@ -133,15 +128,13 @@ class Robot: self.pwm_writer.txPacket() def set_trigger_torque(self): - """ - Sets a constant torque torque for the last servo in the chain. This is useful for the trigger of the leader arm + """Sets a constant torque torque for the last servo in the chain. This is useful for the trigger of the leader arm """ self.dynamixel._enable_torque(self.servo_ids[-1]) self.dynamixel.set_pwm_value(self.servo_ids[-1], 200) def limit_pwm(self, limit: Union[int, list, np.ndarray]): - """ - Limits the pwm values for the servos in for position control + """Limits the pwm values for the servos in for position control @param limit: 0 ~ 885 @return: """ diff --git a/examples/aloha/benchmark/python/teleoperate_real_robot.py b/examples/aloha/benchmark/python/teleoperate_real_robot.py index fb67bb16..74675656 100644 --- a/examples/aloha/benchmark/python/teleoperate_real_robot.py +++ b/examples/aloha/benchmark/python/teleoperate_real_robot.py @@ -1,11 +1,11 @@ -from robot import Robot from dynamixel import Dynamixel +from robot import Robot leader_dynamixel = Dynamixel.Config( - baudrate=1_000_000, device_name="/dev/ttyDXL_master_right" + baudrate=1_000_000, device_name="/dev/ttyDXL_master_right", ).instantiate() follower_dynamixel = Dynamixel.Config( - baudrate=1_000_000, device_name="/dev/ttyDXL_puppet_right" + baudrate=1_000_000, device_name="/dev/ttyDXL_puppet_right", ).instantiate() follower = Robot(follower_dynamixel, servo_ids=[1, 2, 3, 4, 5, 6, 7, 8]) leader = Robot(leader_dynamixel, servo_ids=[1, 2, 3, 4, 5, 6, 7, 8]) diff --git a/examples/aloha/benchmark/ros2/teleop.py b/examples/aloha/benchmark/ros2/teleop.py index b68939ae..dc127a67 100644 --- a/examples/aloha/benchmark/ros2/teleop.py +++ b/examples/aloha/benchmark/ros2/teleop.py @@ -1,8 +1,7 @@ import dora -from dora import Node -import pyarrow as pa import numpy as np - +import pyarrow as pa +from dora import Node ros2_context = dora.experimental.ros2_bridge.Ros2Context() ros2_node = ros2_context.new_node( @@ -13,7 +12,7 @@ ros2_node = ros2_context.new_node( # Define a ROS2 QOS topic_qos = dora.experimental.ros2_bridge.Ros2QosPolicies( - reliable=True, max_blocking_time=0.1 + reliable=True, max_blocking_time=0.1, ) # Create a publisher to cmd_vel topic @@ -22,7 +21,7 @@ puppet_arm_command = ros2_node.create_publisher( "/robot_model_puppet/commands/joint_group", "interbotix_xs_msgs/JointGroupCommand", topic_qos, - ) + ), ) gripper_command = ros2_node.create_publisher( @@ -30,13 +29,13 @@ gripper_command = ros2_node.create_publisher( "/robot_model_puppet/commands/joint_single", "interbotix_xs_msgs/JointSingleCommand", topic_qos, - ) + ), ) # Create a listener to pose topic master_state = ros2_node.create_subscription( ros2_node.create_topic( - "/robot_model_master/joint_states", "sensor_msgs/JointState", topic_qos - ) + "/robot_model_master/joint_states", "sensor_msgs/JointState", topic_qos, + ), ) # Create a dora node @@ -74,8 +73,8 @@ for event in dora_node: { "name": "gripper", "cmd": np.float32(values[6]), - } - ] + }, + ], ), ) puppet_arm_command.publish( @@ -84,7 +83,7 @@ for event in dora_node: { "name": "arm", "cmd": values[:6], - } - ] + }, + ], ), ) diff --git a/examples/aloha/nodes/gym_dora_node.py b/examples/aloha/nodes/gym_dora_node.py index 9cad666c..70af510d 100644 --- a/examples/aloha/nodes/gym_dora_node.py +++ b/examples/aloha/nodes/gym_dora_node.py @@ -1,12 +1,12 @@ -import gymnasium as gym +import time +from pathlib import Path import gym_dora # noqa: F401 +import gymnasium as gym import pandas as pd -import time -from pathlib import Path env = gym.make( - "gym_dora/DoraAloha-v0", disable_env_checker=True, max_episode_steps=10000 + "gym_dora/DoraAloha-v0", disable_env_checker=True, max_episode_steps=10000, ) observation = env.reset() @@ -49,8 +49,8 @@ class ReplayPolicy: policy = ReplayPolicy( Path( - "/home/rcadene/dora-aloha/aloha/graphs/out/018fa4ad-5942-7235-93d3-3efebe9b8a12" - ) + "/home/rcadene/dora-aloha/aloha/graphs/out/018fa4ad-5942-7235-93d3-3efebe9b8a12", + ), ) diff --git a/examples/aloha/nodes/keyboard_node.py b/examples/aloha/nodes/keyboard_node.py index 213ba448..32fee0dc 100644 --- a/examples/aloha/nodes/keyboard_node.py +++ b/examples/aloha/nodes/keyboard_node.py @@ -1,8 +1,7 @@ -from pynput import keyboard -from pynput.keyboard import Key, Events import pyarrow as pa from dora import Node - +from pynput import keyboard +from pynput.keyboard import Events, Key node = Node() buffer_text = "" @@ -17,7 +16,7 @@ with keyboard.Events() as events: cursor += 1 node.send_output("space", pa.array([cursor])) space = True - + elif event is not None and isinstance(event, Events.Release): if event.key == Key.space: @@ -25,7 +24,7 @@ with keyboard.Events() as events: space = False elif event.key == Key.backspace: node.send_output("failed", pa.array([cursor])) - + if node.next(0.001) is None: break diff --git a/examples/aloha/nodes/lerobot_webcam_saver.py b/examples/aloha/nodes/lerobot_webcam_saver.py index 864b47f0..840a39fe 100644 --- a/examples/aloha/nodes/lerobot_webcam_saver.py +++ b/examples/aloha/nodes/lerobot_webcam_saver.py @@ -1,14 +1,12 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import os -import time -import numpy as np +import subprocess +from pathlib import Path + import cv2 import pyarrow as pa -from pathlib import Path from dora import Node -import subprocess node = Node() @@ -40,12 +38,12 @@ for event in node: f"ffmpeg -r {FPS} " "-f image2 " "-loglevel error " - f"-i {str(out_dir / 'frame_%06d.png')} " + f"-i {out_dir / 'frame_%06d.png'!s} " "-vcodec libx264 " "-g 2 " "-pix_fmt yuv444p " - f"{str(video_path)} &&" - f"rm -r {str(out_dir)}" + f"{video_path!s} &&" + f"rm -r {out_dir!s}" ) print(ffmpeg_cmd, flush=True) subprocess.Popen([ffmpeg_cmd], start_new_session=True, shell=True) diff --git a/examples/aloha/nodes/llm_op.py b/examples/aloha/nodes/llm_op.py index acaea635..07797349 100644 --- a/examples/aloha/nodes/llm_op.py +++ b/examples/aloha/nodes/llm_op.py @@ -1,14 +1,14 @@ -from dora import DoraStatus -import pylcs -import os -import pyarrow as pa -from transformers import AutoModelForCausalLM, AutoTokenizer -import torch - import gc # garbage collect library +import os import re import time +import pyarrow as pa +import pylcs +import torch +from dora import DoraStatus +from transformers import AutoModelForCausalLM, AutoTokenizer + CHATGPT = False MODEL_NAME_OR_PATH = "TheBloke/deepseek-coder-6.7B-instruct-GPTQ" @@ -39,14 +39,16 @@ tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME_OR_PATH, use_fast=True) def extract_python_code_blocks(text): - """ - Extracts Python code blocks from the given text that are enclosed in triple backticks with a python language identifier. + """Extracts Python code blocks from the given text that are enclosed in triple backticks with a python language identifier. - Parameters: + Parameters + ---------- - text: A string that may contain one or more Python code blocks. - Returns: + Returns + ------- - A list of strings, where each string is a block of Python code extracted from the text. + """ pattern = r"```python\n(.*?)\n```" matches = re.findall(pattern, text, re.DOTALL) @@ -55,21 +57,22 @@ def extract_python_code_blocks(text): matches = re.findall(pattern, text, re.DOTALL) if len(matches) == 0: return [text] - else: - matches = [remove_last_line(matches[0])] + matches = [remove_last_line(matches[0])] return matches def remove_last_line(python_code): - """ - Removes the last line from a given string of Python code. + """Removes the last line from a given string of Python code. - Parameters: + Parameters + ---------- - python_code: A string representing Python source code. - Returns: + Returns + ------- - A string with the last line removed. + """ lines = python_code.split("\n") # Split the string into lines if lines: # Check if there are any lines to remove @@ -78,8 +81,7 @@ def remove_last_line(python_code): def calculate_similarity(source, target): - """ - Calculate a similarity score between the source and target strings. + """Calculate a similarity score between the source and target strings. This uses the edit distance relative to the length of the strings. """ edit_distance = pylcs.edit_distance(source, target) @@ -90,8 +92,7 @@ def calculate_similarity(source, target): def find_best_match_location(source_code, target_block): - """ - Find the best match for the target_block within the source_code by searching line by line, + """Find the best match for the target_block within the source_code by searching line by line, considering blocks of varying lengths. """ source_lines = source_code.split("\n") @@ -121,8 +122,7 @@ def find_best_match_location(source_code, target_block): def replace_code_in_source(source_code, replacement_block: str): - """ - Replace the best matching block in the source_code with the replacement_block, considering variable block lengths. + """Replace the best matching block in the source_code with the replacement_block, considering variable block lengths. """ replacement_block = extract_python_code_blocks(replacement_block)[0] start_index, end_index = find_best_match_location(source_code, replacement_block) @@ -132,8 +132,7 @@ def replace_code_in_source(source_code, replacement_block: str): source_code[:start_index] + replacement_block + source_code[end_index:] ) return new_source - else: - return source_code + return source_code class Operator: @@ -155,14 +154,14 @@ class Operator: current_directory = os.path.dirname(current_file_path) path = current_directory + "/policy.py" - with open(path, "r", encoding="utf8") as f: + with open(path, encoding="utf8") as f: code = f.read() user_message = input start_llm = time.time() output = self.ask_llm( - CODE_MODIFIER_TEMPLATE.format(code=code, user_message=user_message) + CODE_MODIFIER_TEMPLATE.format(code=code, user_message=user_message), ) source_code = replace_code_in_source(code, output) @@ -213,7 +212,7 @@ if __name__ == "__main__": current_directory = os.path.dirname(current_file_path) path = current_directory + "/policy.py" - with open(path, "r", encoding="utf8") as f: + with open(path, encoding="utf8") as f: raw = f.read() op.on_event( @@ -226,7 +225,7 @@ if __name__ == "__main__": "path": path, "user_message": "When I say suit up, get the hat and the get the food.", }, - ] + ], ), "metadata": [], }, diff --git a/examples/aloha/nodes/plot_node.py b/examples/aloha/nodes/plot_node.py index 55fc641c..cfb482d9 100644 --- a/examples/aloha/nodes/plot_node.py +++ b/examples/aloha/nodes/plot_node.py @@ -1,8 +1,8 @@ import os + import cv2 from dora import Node - IMAGE_WIDTH = int(os.getenv("IMAGE_WIDTH", "1280")) IMAGE_HEIGHT = int(os.getenv("IMAGE_HEIGHT", "720")) FONT = cv2.FONT_HERSHEY_SIMPLEX diff --git a/examples/aloha/nodes/policy.py b/examples/aloha/nodes/policy.py index 1de183dc..3825c987 100644 --- a/examples/aloha/nodes/policy.py +++ b/examples/aloha/nodes/policy.py @@ -1,4 +1,3 @@ -import pyarrow as pa from dora import DoraStatus diff --git a/examples/aloha/nodes/realsense_node.py b/examples/aloha/nodes/realsense_node.py index ef5be285..0d8998d8 100644 --- a/examples/aloha/nodes/realsense_node.py +++ b/examples/aloha/nodes/realsense_node.py @@ -1,9 +1,10 @@ -import pyrealsense2 as rs -import numpy as np -from dora import Node -import pyarrow as pa import os + import cv2 +import numpy as np +import pyarrow as pa +import pyrealsense2 as rs +from dora import Node IMAGE_WIDTH = int(os.getenv("IMAGE_WIDTH", "640")) IMAGE_HEIGHT = int(os.getenv("IMAGE_HEIGHT", "480")) diff --git a/examples/aloha/nodes/replay.py b/examples/aloha/nodes/replay.py index de485cf6..755403e1 100644 --- a/examples/aloha/nodes/replay.py +++ b/examples/aloha/nodes/replay.py @@ -1,8 +1,8 @@ -from dora import Node -import pandas as pd -import pyarrow as pa import time +import pandas as pd +import pyarrow as pa +from dora import Node TOPIC = "puppet_goal_position" diff --git a/examples/aloha/nodes/webcam.py b/examples/aloha/nodes/webcam.py index 2d4806ab..219099f5 100644 --- a/examples/aloha/nodes/webcam.py +++ b/examples/aloha/nodes/webcam.py @@ -1,12 +1,10 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import os -import time -import numpy as np + import cv2 +import numpy as np import pyarrow as pa - from dora import Node node = Node() @@ -26,8 +24,8 @@ for event in node: frame = np.zeros((CAMERA_HEIGHT, CAMERA_WIDTH, 3), dtype=np.uint8) cv2.putText( frame, - "No Webcam was found at index %d" % (CAMERA_ID), - (int(30), int(30)), + f"No Webcam was found at index {CAMERA_ID}", + (30, 30), font, 0.75, (255, 255, 255), diff --git a/examples/aloha/nodes/whisper_node.py b/examples/aloha/nodes/whisper_node.py index 903f5cb5..bf3ad1fe 100644 --- a/examples/aloha/nodes/whisper_node.py +++ b/examples/aloha/nodes/whisper_node.py @@ -1,14 +1,10 @@ -import pyarrow as pa -import whisper -from pynput import keyboard -from pynput.keyboard import Key, Events -from dora import Node - -import torch import numpy as np import pyarrow as pa import sounddevice as sd -import gc # garbage collect library +import whisper +from dora import Node +from pynput import keyboard +from pynput.keyboard import Events, Key model = whisper.load_model("base") @@ -48,7 +44,7 @@ with keyboard.Events() as events: if event.key == Key.alt_r: result = get_text(5) node.send_output( - "text_llm", pa.array([result["text"]]), dora_event["metadata"] + "text_llm", pa.array([result["text"]]), dora_event["metadata"], ) elif event.key == Key.ctrl_r: result = get_text(3) diff --git a/examples/aloha/tests/test_realsense.py b/examples/aloha/tests/test_realsense.py index a7750d59..30ae9d89 100644 --- a/examples/aloha/tests/test_realsense.py +++ b/examples/aloha/tests/test_realsense.py @@ -1,7 +1,8 @@ -import pyrealsense2 as rs +import os + import cv2 import numpy as np -import os +import pyrealsense2 as rs CAMERA_ID = os.getenv("CAMERA_ID") pipe = rs.pipeline() @@ -12,7 +13,7 @@ profile = pipe.start(config) try: - for i in range(0, 1000): + for i in range(1000): frames = pipe.wait_for_frames() color_frame = frames.get_color_frame() color_images = np.asanyarray(color_frame.get_data()) diff --git a/examples/lebai/nodes/interpolation.py b/examples/lebai/nodes/interpolation.py index f14baedc..06a40302 100644 --- a/examples/lebai/nodes/interpolation.py +++ b/examples/lebai/nodes/interpolation.py @@ -1,14 +1,13 @@ -from dora import Node -import pyarrow as pa from enum import Enum +import pyarrow as pa +from dora import Node + node = Node() class Action(Enum): - """ - Action abstraction - """ + """Action abstraction for robot movement commands.""" YAW_RIGHT = ("yaw right", "movej", [0, 0, 0, 0, -0.1, 0, 0.1]) YAW_LEFT = ("yaw left", "movej", [0, 0, 0, 0, 0.1, 0, 0.1]) diff --git a/examples/lebai/nodes/key_interpolation.py b/examples/lebai/nodes/key_interpolation.py index 25d7361f..1776fa6b 100644 --- a/examples/lebai/nodes/key_interpolation.py +++ b/examples/lebai/nodes/key_interpolation.py @@ -1,5 +1,5 @@ -from dora import Node import pyarrow as pa +from dora import Node node = Node() diff --git a/examples/lebai/nodes/prompt_interpolation.py b/examples/lebai/nodes/prompt_interpolation.py index 4c5ecc32..f81f6b69 100644 --- a/examples/lebai/nodes/prompt_interpolation.py +++ b/examples/lebai/nodes/prompt_interpolation.py @@ -1,5 +1,5 @@ -from dora import Node import pyarrow as pa +from dora import Node node = Node() @@ -15,7 +15,7 @@ for event in node: pa.array( [ "Respond with left, right, forward, back, up, down or go home in order for the robotic arm to " - + text - ] + + text, + ], ), ) diff --git a/examples/lebai/nodes/voice_interpolation.py b/examples/lebai/nodes/voice_interpolation.py index 43479e82..72d5c9c2 100644 --- a/examples/lebai/nodes/voice_interpolation.py +++ b/examples/lebai/nodes/voice_interpolation.py @@ -1,5 +1,5 @@ -from dora import Node import pyarrow as pa +from dora import Node node = Node() diff --git a/examples/reachy/nodes/gym_dora_node.py b/examples/reachy/nodes/gym_dora_node.py index 96030682..c1ce0640 100644 --- a/examples/reachy/nodes/gym_dora_node.py +++ b/examples/reachy/nodes/gym_dora_node.py @@ -1,14 +1,12 @@ import time -from pathlib import Path +import gym_dora # noqa: F401 import gymnasium as gym import pandas as pd from lerobot.common.datasets.lerobot_dataset import LeRobotDataset -import gym_dora # noqa: F401 - env = gym.make( - "gym_dora/DoraReachy2-v0", disable_env_checker=True, max_episode_steps=10000 + "gym_dora/DoraReachy2-v0", disable_env_checker=True, max_episode_steps=10000, ) observation = env.reset() diff --git a/examples/reachy/nodes/keyboard_node.py b/examples/reachy/nodes/keyboard_node.py index 213ba448..32fee0dc 100644 --- a/examples/reachy/nodes/keyboard_node.py +++ b/examples/reachy/nodes/keyboard_node.py @@ -1,8 +1,7 @@ -from pynput import keyboard -from pynput.keyboard import Key, Events import pyarrow as pa from dora import Node - +from pynput import keyboard +from pynput.keyboard import Events, Key node = Node() buffer_text = "" @@ -17,7 +16,7 @@ with keyboard.Events() as events: cursor += 1 node.send_output("space", pa.array([cursor])) space = True - + elif event is not None and isinstance(event, Events.Release): if event.key == Key.space: @@ -25,7 +24,7 @@ with keyboard.Events() as events: space = False elif event.key == Key.backspace: node.send_output("failed", pa.array([cursor])) - + if node.next(0.001) is None: break diff --git a/examples/reachy/nodes/lerobot_webcam_saver.py b/examples/reachy/nodes/lerobot_webcam_saver.py index 971bc791..28ba5271 100644 --- a/examples/reachy/nodes/lerobot_webcam_saver.py +++ b/examples/reachy/nodes/lerobot_webcam_saver.py @@ -1,14 +1,12 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import os -import time -import numpy as np +import subprocess +from pathlib import Path + import cv2 import pyarrow as pa -from pathlib import Path from dora import Node -import subprocess node = Node() @@ -40,12 +38,12 @@ for event in node: f"ffmpeg -r {FPS} " "-f image2 " "-loglevel error " - f"-i {str(out_dir / 'frame_%06d.png')} " + f"-i {out_dir / 'frame_%06d.png'!s} " "-vcodec libx264 " "-g 2 " "-pix_fmt yuv444p " - f"{str(video_path)} &&" - f"rm -r {str(out_dir)}" + f"{video_path!s} &&" + f"rm -r {out_dir!s}" ) print(ffmpeg_cmd, flush=True) subprocess.Popen([ffmpeg_cmd], start_new_session=True, shell=True) diff --git a/examples/reachy/nodes/plot_node.py b/examples/reachy/nodes/plot_node.py index a2c4ea2b..ebc8ebd3 100644 --- a/examples/reachy/nodes/plot_node.py +++ b/examples/reachy/nodes/plot_node.py @@ -1,8 +1,8 @@ import os + import cv2 from dora import Node - IMAGE_WIDTH = int(os.getenv("IMAGE_WIDTH", "1280")) IMAGE_HEIGHT = int(os.getenv("IMAGE_HEIGHT", "720")) FONT = cv2.FONT_HERSHEY_SIMPLEX diff --git a/examples/reachy/nodes/reachy_client.py b/examples/reachy/nodes/reachy_client.py index 0fb16bc1..4477fa72 100644 --- a/examples/reachy/nodes/reachy_client.py +++ b/examples/reachy/nodes/reachy_client.py @@ -1,7 +1,4 @@ -import argparse -import os import time -from pathlib import Path # import h5py import numpy as np @@ -83,7 +80,7 @@ for event in node: # min(100, max(0, action[7] / 2.26 * 100)) # ) # replay true action value reachy.l_arm.gripper.set_opening( - 0 if action[7] < 2.0 else 100 + 0 if action[7] < 2.0 else 100, ) # trick to force the gripper to close fully reachy.r_arm.shoulder.pitch.goal_position = np.rad2deg(action[8]) @@ -97,7 +94,7 @@ for event in node: # min(100, max(0, action[15] / 2.26 * 100)) # ) # replay true action value reachy.r_arm.gripper.set_opening( - 0 if action[15] < 2.0 else 100 + 0 if action[15] < 2.0 else 100, ) # trick to force the gripper to close fully reachy.mobile_base.set_speed(action[16], action[17], np.rad2deg(action[18])) reachy.head.neck.roll.goal_position = np.rad2deg(action[19]) @@ -110,38 +107,38 @@ for event in node: mobile_base_pos = {"vx": 0, "vy": 0, "vtheta": 0} qpos = { "l_arm_shoulder_pitch": np.deg2rad( - reachy.l_arm.shoulder.pitch.present_position + reachy.l_arm.shoulder.pitch.present_position, ), "l_arm_shoulder_roll": np.deg2rad( - reachy.l_arm.shoulder.roll.present_position + reachy.l_arm.shoulder.roll.present_position, ), "l_arm_elbow_yaw": np.deg2rad(reachy.l_arm.elbow.yaw.present_position), "l_arm_elbow_pitch": np.deg2rad( - reachy.l_arm.elbow.pitch.present_position + reachy.l_arm.elbow.pitch.present_position, ), "l_arm_wrist_roll": np.deg2rad( - reachy.l_arm.wrist.roll.present_position + reachy.l_arm.wrist.roll.present_position, ), "l_arm_wrist_pitch": np.deg2rad( - reachy.l_arm.wrist.pitch.present_position + reachy.l_arm.wrist.pitch.present_position, ), "l_arm_wrist_yaw": np.deg2rad(reachy.l_arm.wrist.yaw.present_position), "l_gripper": reachy.l_arm.gripper._present_position, "r_arm_shoulder_pitch": np.deg2rad( - reachy.r_arm.shoulder.pitch.present_position + reachy.r_arm.shoulder.pitch.present_position, ), "r_arm_shoulder_roll": np.deg2rad( - reachy.r_arm.shoulder.roll.present_position + reachy.r_arm.shoulder.roll.present_position, ), "r_arm_elbow_yaw": np.deg2rad(reachy.r_arm.elbow.yaw.present_position), "r_arm_elbow_pitch": np.deg2rad( - reachy.r_arm.elbow.pitch.present_position + reachy.r_arm.elbow.pitch.present_position, ), "r_arm_wrist_roll": np.deg2rad( - reachy.r_arm.wrist.roll.present_position + reachy.r_arm.wrist.roll.present_position, ), "r_arm_wrist_pitch": np.deg2rad( - reachy.r_arm.wrist.pitch.present_position + reachy.r_arm.wrist.pitch.present_position, ), "r_arm_wrist_yaw": np.deg2rad(reachy.r_arm.wrist.yaw.present_position), "r_gripper": reachy.r_arm.gripper._present_position, diff --git a/examples/reachy/nodes/reachy_vision_client.py b/examples/reachy/nodes/reachy_vision_client.py index 1cce7c26..1a4cb7d1 100644 --- a/examples/reachy/nodes/reachy_vision_client.py +++ b/examples/reachy/nodes/reachy_vision_client.py @@ -1,7 +1,4 @@ -import argparse -import os import time -from pathlib import Path import numpy as np import pyarrow as pa @@ -21,7 +18,6 @@ cam = SDKWrapper(get_config_file_path("CONFIG_SR"), fps=freq) # ret, image = cap.read() import cv2 -import numpy as np episode = 1 dataset = LeRobotDataset("cadene/reachy2_teleop_remi") @@ -41,8 +37,6 @@ images = images.astype(np.uint8) images = cv2.cvtColor(images, cv2.COLOR_RGB2BGR) # start = time.time() -import PIL -import torch # frame_hwc = (images.permute((1, 2, 0)) * 255).type(torch.uint8).cpu().numpy() diff --git a/examples/reachy/nodes/replay_node.py b/examples/reachy/nodes/replay_node.py index f268f3fc..4f56b02d 100644 --- a/examples/reachy/nodes/replay_node.py +++ b/examples/reachy/nodes/replay_node.py @@ -1,7 +1,8 @@ -from lerobot.common.datasets.lerobot_dataset import LeRobotDataset import time -from dora import Node + import pyarrow as pa +from dora import Node +from lerobot.common.datasets.lerobot_dataset import LeRobotDataset episode = 1 dataset = LeRobotDataset("cadene/reachy2_teleop_remi") diff --git a/examples/reachy1/nodes/gym_dora_node.py b/examples/reachy1/nodes/gym_dora_node.py index 96030682..c1ce0640 100644 --- a/examples/reachy1/nodes/gym_dora_node.py +++ b/examples/reachy1/nodes/gym_dora_node.py @@ -1,14 +1,12 @@ import time -from pathlib import Path +import gym_dora # noqa: F401 import gymnasium as gym import pandas as pd from lerobot.common.datasets.lerobot_dataset import LeRobotDataset -import gym_dora # noqa: F401 - env = gym.make( - "gym_dora/DoraReachy2-v0", disable_env_checker=True, max_episode_steps=10000 + "gym_dora/DoraReachy2-v0", disable_env_checker=True, max_episode_steps=10000, ) observation = env.reset() diff --git a/examples/reachy1/nodes/key_interpolation.py b/examples/reachy1/nodes/key_interpolation.py index b997c7a0..b5107614 100644 --- a/examples/reachy1/nodes/key_interpolation.py +++ b/examples/reachy1/nodes/key_interpolation.py @@ -1,5 +1,5 @@ -from dora import Node import pyarrow as pa +from dora import Node node = Node() diff --git a/examples/reachy1/nodes/keyboard_node.py b/examples/reachy1/nodes/keyboard_node.py index 213ba448..32fee0dc 100644 --- a/examples/reachy1/nodes/keyboard_node.py +++ b/examples/reachy1/nodes/keyboard_node.py @@ -1,8 +1,7 @@ -from pynput import keyboard -from pynput.keyboard import Key, Events import pyarrow as pa from dora import Node - +from pynput import keyboard +from pynput.keyboard import Events, Key node = Node() buffer_text = "" @@ -17,7 +16,7 @@ with keyboard.Events() as events: cursor += 1 node.send_output("space", pa.array([cursor])) space = True - + elif event is not None and isinstance(event, Events.Release): if event.key == Key.space: @@ -25,7 +24,7 @@ with keyboard.Events() as events: space = False elif event.key == Key.backspace: node.send_output("failed", pa.array([cursor])) - + if node.next(0.001) is None: break diff --git a/examples/reachy1/nodes/lerobot_webcam_saver.py b/examples/reachy1/nodes/lerobot_webcam_saver.py index 971bc791..28ba5271 100644 --- a/examples/reachy1/nodes/lerobot_webcam_saver.py +++ b/examples/reachy1/nodes/lerobot_webcam_saver.py @@ -1,14 +1,12 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import os -import time -import numpy as np +import subprocess +from pathlib import Path + import cv2 import pyarrow as pa -from pathlib import Path from dora import Node -import subprocess node = Node() @@ -40,12 +38,12 @@ for event in node: f"ffmpeg -r {FPS} " "-f image2 " "-loglevel error " - f"-i {str(out_dir / 'frame_%06d.png')} " + f"-i {out_dir / 'frame_%06d.png'!s} " "-vcodec libx264 " "-g 2 " "-pix_fmt yuv444p " - f"{str(video_path)} &&" - f"rm -r {str(out_dir)}" + f"{video_path!s} &&" + f"rm -r {out_dir!s}" ) print(ffmpeg_cmd, flush=True) subprocess.Popen([ffmpeg_cmd], start_new_session=True, shell=True) diff --git a/examples/reachy1/nodes/plot_node.py b/examples/reachy1/nodes/plot_node.py index a2c4ea2b..ebc8ebd3 100644 --- a/examples/reachy1/nodes/plot_node.py +++ b/examples/reachy1/nodes/plot_node.py @@ -1,8 +1,8 @@ import os + import cv2 from dora import Node - IMAGE_WIDTH = int(os.getenv("IMAGE_WIDTH", "1280")) IMAGE_HEIGHT = int(os.getenv("IMAGE_HEIGHT", "720")) FONT = cv2.FONT_HERSHEY_SIMPLEX diff --git a/examples/reachy1/nodes/reachy_client.py b/examples/reachy1/nodes/reachy_client.py index 0fb16bc1..4477fa72 100644 --- a/examples/reachy1/nodes/reachy_client.py +++ b/examples/reachy1/nodes/reachy_client.py @@ -1,7 +1,4 @@ -import argparse -import os import time -from pathlib import Path # import h5py import numpy as np @@ -83,7 +80,7 @@ for event in node: # min(100, max(0, action[7] / 2.26 * 100)) # ) # replay true action value reachy.l_arm.gripper.set_opening( - 0 if action[7] < 2.0 else 100 + 0 if action[7] < 2.0 else 100, ) # trick to force the gripper to close fully reachy.r_arm.shoulder.pitch.goal_position = np.rad2deg(action[8]) @@ -97,7 +94,7 @@ for event in node: # min(100, max(0, action[15] / 2.26 * 100)) # ) # replay true action value reachy.r_arm.gripper.set_opening( - 0 if action[15] < 2.0 else 100 + 0 if action[15] < 2.0 else 100, ) # trick to force the gripper to close fully reachy.mobile_base.set_speed(action[16], action[17], np.rad2deg(action[18])) reachy.head.neck.roll.goal_position = np.rad2deg(action[19]) @@ -110,38 +107,38 @@ for event in node: mobile_base_pos = {"vx": 0, "vy": 0, "vtheta": 0} qpos = { "l_arm_shoulder_pitch": np.deg2rad( - reachy.l_arm.shoulder.pitch.present_position + reachy.l_arm.shoulder.pitch.present_position, ), "l_arm_shoulder_roll": np.deg2rad( - reachy.l_arm.shoulder.roll.present_position + reachy.l_arm.shoulder.roll.present_position, ), "l_arm_elbow_yaw": np.deg2rad(reachy.l_arm.elbow.yaw.present_position), "l_arm_elbow_pitch": np.deg2rad( - reachy.l_arm.elbow.pitch.present_position + reachy.l_arm.elbow.pitch.present_position, ), "l_arm_wrist_roll": np.deg2rad( - reachy.l_arm.wrist.roll.present_position + reachy.l_arm.wrist.roll.present_position, ), "l_arm_wrist_pitch": np.deg2rad( - reachy.l_arm.wrist.pitch.present_position + reachy.l_arm.wrist.pitch.present_position, ), "l_arm_wrist_yaw": np.deg2rad(reachy.l_arm.wrist.yaw.present_position), "l_gripper": reachy.l_arm.gripper._present_position, "r_arm_shoulder_pitch": np.deg2rad( - reachy.r_arm.shoulder.pitch.present_position + reachy.r_arm.shoulder.pitch.present_position, ), "r_arm_shoulder_roll": np.deg2rad( - reachy.r_arm.shoulder.roll.present_position + reachy.r_arm.shoulder.roll.present_position, ), "r_arm_elbow_yaw": np.deg2rad(reachy.r_arm.elbow.yaw.present_position), "r_arm_elbow_pitch": np.deg2rad( - reachy.r_arm.elbow.pitch.present_position + reachy.r_arm.elbow.pitch.present_position, ), "r_arm_wrist_roll": np.deg2rad( - reachy.r_arm.wrist.roll.present_position + reachy.r_arm.wrist.roll.present_position, ), "r_arm_wrist_pitch": np.deg2rad( - reachy.r_arm.wrist.pitch.present_position + reachy.r_arm.wrist.pitch.present_position, ), "r_arm_wrist_yaw": np.deg2rad(reachy.r_arm.wrist.yaw.present_position), "r_gripper": reachy.r_arm.gripper._present_position, diff --git a/examples/reachy1/nodes/reachy_vision_client.py b/examples/reachy1/nodes/reachy_vision_client.py index 1cce7c26..1a4cb7d1 100644 --- a/examples/reachy1/nodes/reachy_vision_client.py +++ b/examples/reachy1/nodes/reachy_vision_client.py @@ -1,7 +1,4 @@ -import argparse -import os import time -from pathlib import Path import numpy as np import pyarrow as pa @@ -21,7 +18,6 @@ cam = SDKWrapper(get_config_file_path("CONFIG_SR"), fps=freq) # ret, image = cap.read() import cv2 -import numpy as np episode = 1 dataset = LeRobotDataset("cadene/reachy2_teleop_remi") @@ -41,8 +37,6 @@ images = images.astype(np.uint8) images = cv2.cvtColor(images, cv2.COLOR_RGB2BGR) # start = time.time() -import PIL -import torch # frame_hwc = (images.permute((1, 2, 0)) * 255).type(torch.uint8).cpu().numpy() diff --git a/examples/reachy1/nodes/replay_node.py b/examples/reachy1/nodes/replay_node.py index f268f3fc..4f56b02d 100644 --- a/examples/reachy1/nodes/replay_node.py +++ b/examples/reachy1/nodes/replay_node.py @@ -1,7 +1,8 @@ -from lerobot.common.datasets.lerobot_dataset import LeRobotDataset import time -from dora import Node + import pyarrow as pa +from dora import Node +from lerobot.common.datasets.lerobot_dataset import LeRobotDataset episode = 1 dataset = LeRobotDataset("cadene/reachy2_teleop_remi") diff --git a/examples/reachy1/nodes/text_interpolation.py b/examples/reachy1/nodes/text_interpolation.py index 0910b350..2d9a514b 100644 --- a/examples/reachy1/nodes/text_interpolation.py +++ b/examples/reachy1/nodes/text_interpolation.py @@ -1,6 +1,5 @@ -from dora import Node import pyarrow as pa -import numpy as np +from dora import Node node = Node() @@ -19,19 +18,19 @@ for event in node: node.send_output("head_action", pa.array([0, head_step, 0])) elif text == "look up": node.send_output( - "head_action", pa.array([head_step / 2, 0, -head_step / 2]) + "head_action", pa.array([head_step / 2, 0, -head_step / 2]), ) elif text == "look down": node.send_output( - "head_action", pa.array([-head_step / 2, 0, head_step / 2]) + "head_action", pa.array([-head_step / 2, 0, head_step / 2]), ) elif text == "look up": node.send_output( - "head_action", pa.array([head_step / 2, 0, -head_step / 2]) + "head_action", pa.array([head_step / 2, 0, -head_step / 2]), ) elif text == "look down": node.send_output( - "head_action", pa.array([-head_step / 2, 0, head_step / 2]) + "head_action", pa.array([-head_step / 2, 0, head_step / 2]), ) elif text == "smile": node.send_output("antenna_action", pa.array(["smile"])) @@ -54,8 +53,8 @@ for event in node: "question", pa.array( [ - "Respond with right, left, forward, backward, open, or close to grab the trash" - ] + "Respond with right, left, forward, backward, open, or close to grab the trash", + ], ), ) @@ -65,8 +64,8 @@ for event in node: "question", pa.array( [ - "Respond with right, left, forward, backward, open, or close to put the trash in your hand in the right bin" - ] + "Respond with right, left, forward, backward, open, or close to put the trash in your hand in the right bin", + ], ), ) node.send_output("gripper_action", pa.array([100])) diff --git a/examples/so100/bus.py b/examples/so100/bus.py index 2b231615..569ca9d2 100644 --- a/examples/so100/bus.py +++ b/examples/so100/bus.py @@ -1,17 +1,18 @@ import enum - -import pyarrow as pa - from typing import Union +import pyarrow as pa from scservo_sdk import ( - PacketHandler, - PortHandler, COMM_SUCCESS, + SCS_HIBYTE, + SCS_HIWORD, + SCS_LOBYTE, + SCS_LOWORD, GroupSyncRead, GroupSyncWrite, + PacketHandler, + PortHandler, ) -from scservo_sdk import SCS_HIBYTE, SCS_HIWORD, SCS_LOBYTE, SCS_LOWORD PROTOCOL_VERSION = 0 BAUD_RATE = 1_000_000 @@ -93,13 +94,12 @@ MODEL_CONTROL_TABLE = { class FeetechBus: def __init__(self, port: str, description: dict[str, (np.uint8, str)]): - """ - Args: - port: the serial port to connect to the Feetech bus - description: a dictionary containing the description of the motors connected to the bus. The keys are the - motor names and the values are tuples containing the motor id and the motor model. - """ + """Args: + port: the serial port to connect to the Feetech bus + description: a dictionary containing the description of the motors connected to the bus. The keys are the + motor names and the values are tuples containing the motor id and the motor model. + """ self.port = port self.descriptions = description self.motor_ctrl = {} @@ -183,7 +183,7 @@ class FeetechBus: else: raise NotImplementedError( f"Value of the number of bytes to be sent is expected to be in [1, 2, 4], but {packet_bytes_size} " - f"is provided instead." + f"is provided instead.", ) if init_group: @@ -195,7 +195,7 @@ class FeetechBus: if comm != COMM_SUCCESS: raise ConnectionError( f"Write failed due to communication error on port {self.port} for group_key {group_key}: " - f"{self.packet_handler.getTxRxResult(comm)}" + f"{self.packet_handler.getTxRxResult(comm)}", ) def read(self, data_name: str, motor_names: pa.Array) -> pa.StructArray: @@ -225,13 +225,13 @@ class FeetechBus: if comm != COMM_SUCCESS: raise ConnectionError( f"Read failed due to communication error on port {self.port} for group_key {group_key}: " - f"{self.packet_handler.getTxRxResult(comm)}" + f"{self.packet_handler.getTxRxResult(comm)}", ) values = pa.array( [ self.group_readers[group_key].getData( - idx, packet_address, packet_bytes_size + idx, packet_address, packet_bytes_size, ) for idx in motor_ids ], diff --git a/examples/so100/configure.py b/examples/so100/configure.py index 40b998d5..b99848bc 100644 --- a/examples/so100/configure.py +++ b/examples/so100/configure.py @@ -1,5 +1,4 @@ -""" -SO100 Auto Configure: This program is used to automatically configure the SO-ARM100 (SO100) for the user. +"""SO100 Auto Configure: This program is used to automatically configure the SO-ARM100 (SO100) for the user. The program will: 1. Disable all torque motors of provided SO100. @@ -14,20 +13,17 @@ It will also enable all appropriate operating modes for the SO100. """ import argparse -import time import json +import time import pyarrow as pa - -from bus import FeetechBus, TorqueMode, OperatingMode -from pwm_position_control.transform import pwm_to_logical_arrow, wrap_joints_and_values - +from bus import FeetechBus, OperatingMode, TorqueMode +from pwm_position_control.functions import construct_control_table from pwm_position_control.tables import ( construct_logical_to_pwm_conversion_table_arrow, construct_pwm_to_logical_conversion_table_arrow, ) - -from pwm_position_control.functions import construct_control_table +from pwm_position_control.transform import pwm_to_logical_arrow, wrap_joints_and_values FULL_ARM = pa.array( [ @@ -50,35 +46,42 @@ GRIPPER = pa.array(["gripper"], type=pa.string()) def pause(): + """Pause execution and wait for user input.""" input("Press Enter to continue...") def configure_servos(bus: FeetechBus): + """Configure the servos with default settings. + + Args: + bus: The FeetechBus instance to configure. + """ bus.write_torque_enable( - wrap_joints_and_values(FULL_ARM, [TorqueMode.DISABLED.value] * 6) + wrap_joints_and_values(FULL_ARM, [TorqueMode.DISABLED.value] * 6), ) bus.write_operating_mode( - wrap_joints_and_values(FULL_ARM, [OperatingMode.ONE_TURN.value] * 6) + wrap_joints_and_values(FULL_ARM, [OperatingMode.ONE_TURN.value] * 6), ) bus.write_max_angle_limit( - wrap_joints_and_values(FULL_ARM, [pa.scalar(0, pa.uint32())] * 6) + wrap_joints_and_values(FULL_ARM, [pa.scalar(0, pa.uint32())] * 6), ) bus.write_min_angle_limit( - wrap_joints_and_values(FULL_ARM, [pa.scalar(0, pa.uint32())] * 6) + wrap_joints_and_values(FULL_ARM, [pa.scalar(0, pa.uint32())] * 6), ) def main(): + """Main function to run the servo configuration process.""" parser = argparse.ArgumentParser( description="SO100 Auto Configure: This program is used to automatically configure the Low Cost Robot (SO100) " - "for the user." + "for the user.", ) parser.add_argument( - "--port", type=str, required=True, help="The port of the SO100." + "--port", type=str, required=True, help="The port of the SO100.", ) parser.add_argument( "--right", @@ -130,10 +133,10 @@ def main(): pwm_positions = (pwm_position_1, pwm_position_2) pwm_to_logical_conversion_table = construct_pwm_to_logical_conversion_table_arrow( - pwm_positions, targets + pwm_positions, targets, ) logical_to_pwm_conversion_table = construct_logical_to_pwm_conversion_table_arrow( - pwm_positions, targets + pwm_positions, targets, ) control_table_json = {} @@ -149,7 +152,7 @@ def main(): left = "left" if args.left else "right" path = ( input( - f"Please enter the path of the configuration file (default is ./examples/so100/configs/follower.{left}.json): " + f"Please enter the path of the configuration file (default is ./examples/so100/configs/follower.{left}.json): ", ) or f"./examples/so100/configs/follower.{left}.json" ) @@ -158,21 +161,21 @@ def main(): json.dump(control_table_json, file) control_table = construct_control_table( - pwm_to_logical_conversion_table, logical_to_pwm_conversion_table + pwm_to_logical_conversion_table, logical_to_pwm_conversion_table, ) while True: try: pwm_position = arm.read_position(FULL_ARM) logical_position = pwm_to_logical_arrow( - pwm_position, control_table, ranged=True + pwm_position, control_table, ranged=True, ).field("values") print(f"Logical Position: {logical_position}") except ConnectionError: print( - "Connection error occurred. Please check the connection and try again." + "Connection error occurred. Please check the connection and try again.", ) time.sleep(0.5) diff --git a/examples/so100/nodes/interpolate_lcr_to_so100.py b/examples/so100/nodes/interpolate_lcr_to_so100.py index c007bea7..c200cc7f 100644 --- a/examples/so100/nodes/interpolate_lcr_to_so100.py +++ b/examples/so100/nodes/interpolate_lcr_to_so100.py @@ -1,25 +1,24 @@ -import os import argparse import json +import os import pyarrow as pa import pyarrow.compute as pc - from dora import Node - +from pwm_position_control.load import load_control_table_from_json_conversion_tables from pwm_position_control.transform import ( - wrap_joints_and_values, - pwm_to_logical_arrow, logical_to_pwm_with_offset_arrow, + pwm_to_logical_arrow, + wrap_joints_and_values, ) -from pwm_position_control.load import load_control_table_from_json_conversion_tables def main(): + """Main function to handle interpolation between LCR and SO100 robot configurations.""" # Handle dynamic nodes, ask for the name of the node in the dataflow parser = argparse.ArgumentParser( description="Interpolation LCR Node: This Dora node is used to calculates appropriate goal positions for the " - "LCR followers knowing a Leader position and Follower position." + "LCR followers knowing a Leader position and Follower position.", ) parser.add_argument( @@ -48,19 +47,19 @@ def main(): if not os.environ.get("LEADER_CONTROL") and args.leader_control is None: raise ValueError( "The leader control is not set. Please set the configuration of the leader in the environment variables or " - "as an argument." + "as an argument.", ) if not os.environ.get("FOLLOWER_CONTROL") and args.follower_control is None: raise ValueError( "The follower control is not set. Please set the configuration of the follower in the environment " - "variables or as an argument." + "variables or as an argument.", ) with open( os.environ.get("LEADER_CONTROL") if args.leader_control is None - else args.leader_control + else args.leader_control, ) as file: leader_control = json.load(file) load_control_table_from_json_conversion_tables(leader_control, leader_control) @@ -68,11 +67,11 @@ def main(): with open( os.environ.get("FOLLOWER_CONTROL") if args.follower_control is None - else args.follower_control + else args.follower_control, ) as file: follower_control = json.load(file) load_control_table_from_json_conversion_tables( - follower_control, follower_control + follower_control, follower_control, ) initial_mask = [ @@ -132,7 +131,7 @@ def main(): ) pwm_goal = logical_to_pwm_with_offset_arrow( - follower_position, logical_goal, follower_control + follower_position, logical_goal, follower_control, ) node.send_output("follower_goal", pwm_goal, event["metadata"]) diff --git a/examples/so100/nodes/interpolate_lcr_x_so100_to_record.py b/examples/so100/nodes/interpolate_lcr_x_so100_to_record.py index ce3d43d9..540c13d8 100644 --- a/examples/so100/nodes/interpolate_lcr_x_so100_to_record.py +++ b/examples/so100/nodes/interpolate_lcr_x_so100_to_record.py @@ -1,23 +1,22 @@ -import os import argparse import json +import os import pyarrow as pa import pyarrow.compute as pc - from dora import Node - from pwm_position_control.load import load_control_table_from_json_conversion_tables from pwm_position_control.transform import ( - wrap_joints_and_values, pwm_to_logical_arrow, + wrap_joints_and_values, ) def main(): + """Main function to handle interpolation and recording between LCR and SO100 robot configurations.""" parser = argparse.ArgumentParser( description="Interpolation LCR Node: This Dora node is used to calculates appropriate goal positions for the " - "LCR followers knowing a Leader position and Follower position." + "LCR followers knowing a Leader position and Follower position.", ) parser.add_argument( @@ -45,19 +44,19 @@ def main(): if not os.environ.get("LEADER_CONTROL") and args.leader_control is None: raise ValueError( "The leader control is not set. Please set the configuration of the leader in the environment variables or " - "as an argument." + "as an argument.", ) if not os.environ.get("FOLLOWER_CONTROL") and args.follower_control is None: raise ValueError( "The follower control is not set. Please set the configuration of the follower in the environment " - "variables or as an argument." + "variables or as an argument.", ) with open( os.environ.get("LEADER_CONTROL") if args.leader_control is None - else args.leader_control + else args.leader_control, ) as file: leader_control = json.load(file) load_control_table_from_json_conversion_tables(leader_control, leader_control) @@ -65,11 +64,11 @@ def main(): with open( os.environ.get("FOLLOWER_CONTROL") if args.follower_control is None - else args.follower_control + else args.follower_control, ) as file: follower_control = json.load(file) load_control_table_from_json_conversion_tables( - follower_control, follower_control + follower_control, follower_control, ) node = Node(args.name) @@ -98,11 +97,11 @@ def main(): follower_position = event["value"] follower_position = pwm_to_logical_arrow( - follower_position, follower_control + follower_position, follower_control, ) node.send_output( - "logical_position", follower_position, event["metadata"] + "logical_position", follower_position, event["metadata"], ) elif event_type == "ERROR": diff --git a/examples/so100/nodes/interpolate_replay_to_so100.py b/examples/so100/nodes/interpolate_replay_to_so100.py index c4967aab..3621cde5 100644 --- a/examples/so100/nodes/interpolate_replay_to_so100.py +++ b/examples/so100/nodes/interpolate_replay_to_so100.py @@ -1,20 +1,18 @@ -import os import argparse import json - -import pyarrow as pa +import os from dora import Node - from pwm_position_control.load import load_control_table_from_json_conversion_tables from pwm_position_control.transform import logical_to_pwm_with_offset_arrow def main(): + """Main function to handle replay interpolation for SO100 robot configurations.""" # Handle dynamic nodes, ask for the name of the node in the dataflow parser = argparse.ArgumentParser( description="Interpolation LCR Node: This Dora node is used to calculates appropriate goal positions for the " - "LCR followers knowing a Leader position and Follower position." + "LCR followers knowing a Leader position and Follower position.", ) parser.add_argument( @@ -36,17 +34,17 @@ def main(): if not os.environ.get("FOLLOWER_CONTROL") and args.follower_control is None: raise ValueError( "The follower control is not set. Please set the configuration of the follower in the environment " - "variables or as an argument." + "variables or as an argument.", ) with open( os.environ.get("FOLLOWER_CONTROL") if args.follower_control is None - else args.follower_control + else args.follower_control, ) as file: follower_control = json.load(file) load_control_table_from_json_conversion_tables( - follower_control, follower_control + follower_control, follower_control, ) node = Node(args.name) @@ -68,7 +66,7 @@ def main(): continue physical_goal = logical_to_pwm_with_offset_arrow( - follower_position, leader_position, follower_control + follower_position, leader_position, follower_control, ) node.send_output("follower_goal", physical_goal, event["metadata"]) diff --git a/node-hub/dora-distil-whisper/dora_distil_whisper/main.py b/node-hub/dora-distil-whisper/dora_distil_whisper/main.py index d25d8322..fba4f250 100644 --- a/node-hub/dora-distil-whisper/dora_distil_whisper/main.py +++ b/node-hub/dora-distil-whisper/dora_distil_whisper/main.py @@ -239,5 +239,5 @@ def main(): if text.strip() == "" or text.strip() == ".": continue node.send_output( - "text", pa.array([text]), {"language": TARGET_LANGUAGE} + "text", pa.array([text]), {"language": TARGET_LANGUAGE}, ) diff --git a/node-hub/dora-llama-cpp-python/dora_llama_cpp_python/__main__.py b/node-hub/dora-llama-cpp-python/dora_llama_cpp_python/__main__.py index 7bc8a1f1..51a1554d 100644 --- a/node-hub/dora-llama-cpp-python/dora_llama_cpp_python/__main__.py +++ b/node-hub/dora-llama-cpp-python/dora_llama_cpp_python/__main__.py @@ -2,6 +2,5 @@ from .main import main - if __name__ == "__main__": main() diff --git a/node-hub/dora-llama-cpp-python/dora_llama_cpp_python/main.py b/node-hub/dora-llama-cpp-python/dora_llama_cpp_python/main.py index ec9c888d..1acff6c0 100644 --- a/node-hub/dora-llama-cpp-python/dora_llama_cpp_python/main.py +++ b/node-hub/dora-llama-cpp-python/dora_llama_cpp_python/main.py @@ -1,10 +1,11 @@ """TODO: Add docstring.""" +import logging import os +from pathlib import Path + import pyarrow as pa from dora import Node -from pathlib import Path -import logging # Configure logging logging.basicConfig(level=logging.INFO) @@ -24,7 +25,7 @@ CONTEXT_SIZE = int(os.getenv("CONTEXT_SIZE", "4096")) def get_model(): """Load a GGUF model using llama-cpp-python with optional GPU acceleration.""" from llama_cpp import Llama - + try: # Check if path exists locally model_path = Path(MODEL_NAME_OR_PATH) @@ -35,7 +36,7 @@ def get_model(): n_gpu_layers=N_GPU_LAYERS, n_ctx=CONTEXT_SIZE, n_threads=N_THREADS, - verbose=False + verbose=False, ) else: # Load from HuggingFace @@ -46,14 +47,14 @@ def get_model(): n_gpu_layers=N_GPU_LAYERS, n_ctx=CONTEXT_SIZE, n_threads=N_THREADS, - verbose=False + verbose=False, ) - + logging.info("Model loaded successfully") return llm - + except Exception as e: - logging.error(f"Error loading model: {e}") + logging.exception(f"Error loading model: {e}") raise @@ -79,9 +80,9 @@ def main(): max_tokens=MAX_TOKENS, stop=["Q:", "\n"], )["choices"][0]["text"] - + node.send_output( - output_id="text", data=pa.array([response]), metadata={} + output_id="text", data=pa.array([response]), metadata={}, ) diff --git a/node-hub/dora-magma/dora_magma/__init__.py b/node-hub/dora-magma/dora_magma/__init__.py index 0934c04c..740d94fc 100644 --- a/node-hub/dora-magma/dora_magma/__init__.py +++ b/node-hub/dora-magma/dora_magma/__init__.py @@ -16,4 +16,4 @@ except FileNotFoundError: submodule_path = Path(__file__).resolve().parent / "Magma" -sys.path.insert(0, str(submodule_path)) \ No newline at end of file +sys.path.insert(0, str(submodule_path)) diff --git a/node-hub/dora-magma/dora_magma/main.py b/node-hub/dora-magma/dora_magma/main.py index 5d50c151..66b98cd4 100644 --- a/node-hub/dora-magma/dora_magma/main.py +++ b/node-hub/dora-magma/dora_magma/main.py @@ -27,7 +27,7 @@ def load_magma_models(): DEFAULT_PATH = str(magma_dir.parent) if not os.path.exists(DEFAULT_PATH): logger.warning( - "Warning: Magma submodule not found, falling back to HuggingFace version" + "Warning: Magma submodule not found, falling back to HuggingFace version", ) DEFAULT_PATH = "microsoft/Magma-8B" @@ -42,7 +42,7 @@ def load_magma_models(): device_map="auto", ) processor = AutoProcessor.from_pretrained( - MODEL_NAME_OR_PATH, trust_remote_code=True + MODEL_NAME_OR_PATH, trust_remote_code=True, ) except Exception as e: logger.error(f"Failed to load model: {e}") @@ -72,7 +72,7 @@ def generate( ] prompt = processor.tokenizer.apply_chat_template( - convs, tokenize=False, add_generation_prompt=True + convs, tokenize=False, add_generation_prompt=True, ) try: @@ -102,7 +102,7 @@ def generate( # Parse the trajectories using the same approach as in `https://github.com/microsoft/Magma/blob/main/agents/robot_traj/app.py` traces_dict = ast.literal_eval( - "{" + traces_str.strip().replace("\n\n", ",") + "}" + "{" + traces_str.strip().replace("\n\n", ",") + "}", ) for mark_id, trace in traces_dict.items(): trajectories[mark_id] = ast.literal_eval(trace) @@ -153,7 +153,7 @@ def main(): frame = cv2.imdecode(storage, cv2.IMREAD_COLOR) if frame is None: raise ValueError( - f"Failed to decode image with encoding {encoding}" + f"Failed to decode image with encoding {encoding}", ) frame = frame[:, :, ::-1] # Convert BGR to RGB else: @@ -181,7 +181,7 @@ def main(): image = frames[image_id] response, trajectories = generate(image, task_description) node.send_output( - "text", pa.array([response]), {"image_id": image_id} + "text", pa.array([response]), {"image_id": image_id}, ) # Send trajectory data if available diff --git a/node-hub/dora-magma/tests/test_magma_node.py b/node-hub/dora-magma/tests/test_magma_node.py index 7de0ede9..28cc7ca7 100644 --- a/node-hub/dora-magma/tests/test_magma_node.py +++ b/node-hub/dora-magma/tests/test_magma_node.py @@ -3,4 +3,4 @@ def test_import_main(): """TODO: Add docstring.""" - pass # Model is too big for the CI/CD + # Model is too big for the CI/CD diff --git a/node-hub/dora-openai-server/tests/test_dora_openai_server.py b/node-hub/dora-openai-server/tests/test_dora_openai_server.py index 47f02427..18cfb6cd 100644 --- a/node-hub/dora-openai-server/tests/test_dora_openai_server.py +++ b/node-hub/dora-openai-server/tests/test_dora_openai_server.py @@ -2,4 +2,3 @@ def test_import_main(): """TODO: Add docstring.""" - pass diff --git a/node-hub/dora-outtetts/dora_outtetts/tests/test_main.py b/node-hub/dora-outtetts/dora_outtetts/tests/test_main.py index 45bf6183..ca1c6dd0 100644 --- a/node-hub/dora-outtetts/dora_outtetts/tests/test_main.py +++ b/node-hub/dora-outtetts/dora_outtetts/tests/test_main.py @@ -3,6 +3,7 @@ import os import pytest + from dora_outtetts.main import load_interface, main CI = os.getenv("CI", "false") in ["True", "true"] diff --git a/node-hub/dora-phi4/dora_phi4/main.py b/node-hub/dora-phi4/dora_phi4/main.py index 8932a48f..22a6c5d0 100644 --- a/node-hub/dora-phi4/dora_phi4/main.py +++ b/node-hub/dora-phi4/dora_phi4/main.py @@ -27,7 +27,7 @@ else: MODEL_PATH = "microsoft/Phi-4-multimodal-instruct" processor = AutoProcessor.from_pretrained( - MODEL_PATH, trust_remote_code=True, use_fast=True + MODEL_PATH, trust_remote_code=True, use_fast=True, ) # Define model config @@ -42,12 +42,12 @@ MODEL_CONFIG = { # Infer device map without full initialization device_map = infer_auto_device_map( - AutoModelForCausalLM.from_pretrained(MODEL_PATH, **MODEL_CONFIG) + AutoModelForCausalLM.from_pretrained(MODEL_PATH, **MODEL_CONFIG), ) # Load the model directly with the inferred device map model = AutoModelForCausalLM.from_pretrained( - MODEL_PATH, **MODEL_CONFIG, device_map=device_map + MODEL_PATH, **MODEL_CONFIG, device_map=device_map, ) generation_config = GenerationConfig.from_pretrained(MODEL_PATH) diff --git a/node-hub/dora-reachy1/dora_reachy1/main.py b/node-hub/dora-reachy1/dora_reachy1/main.py index f13129be..ad4355b3 100644 --- a/node-hub/dora-reachy1/dora_reachy1/main.py +++ b/node-hub/dora-reachy1/dora_reachy1/main.py @@ -16,7 +16,7 @@ def r_arm_inverse_kinematics(reachy, pose, action) -> list: [0, 1, 0, pose[1] + action[1]], [1, 0, 0, pose[2] + action[2]], [0, 0, 0, 1], - ] + ], ) return reachy.r_arm.inverse_kinematics(A) @@ -70,7 +70,7 @@ def main(): default_pose = r_arm_inverse_kinematics(reachy, r_arm_pose, [0, 0, 0]) goto( - {joint: pos for joint, pos in zip(reachy.r_arm.joints.values(), default_pose)}, + {joint: pos for joint, pos in zip(reachy.r_arm.joints.values(), default_pose, strict=False)}, duration=3, ) @@ -84,7 +84,7 @@ def main(): goto( { joint: pos - for joint, pos in zip(reachy.r_arm.joints.values(), joint_pose) + for joint, pos in zip(reachy.r_arm.joints.values(), joint_pose, strict=False) }, duration=0.200, ) @@ -119,7 +119,7 @@ def main(): { joint: pos for joint, pos in zip( - reachy.r_arm.joints.values(), default_pose + reachy.r_arm.joints.values(), default_pose, strict=False, ) }, duration=3, diff --git a/node-hub/dora-reachy1/dora_reachy1_vision/main.py b/node-hub/dora-reachy1/dora_reachy1_vision/main.py index 1ab20b21..1c087826 100644 --- a/node-hub/dora-reachy1/dora_reachy1_vision/main.py +++ b/node-hub/dora-reachy1/dora_reachy1_vision/main.py @@ -1,9 +1,10 @@ """TODO: Add docstring.""" -from reachy_sdk import ReachySDK import os -from dora import Node + import pyarrow as pa +from dora import Node +from reachy_sdk import ReachySDK def main(): diff --git a/node-hub/dora-reachy1/tests/test_dora_reachy1.py b/node-hub/dora-reachy1/tests/test_dora_reachy1.py index 02a19b80..470cc4fc 100644 --- a/node-hub/dora-reachy1/tests/test_dora_reachy1.py +++ b/node-hub/dora-reachy1/tests/test_dora_reachy1.py @@ -5,7 +5,6 @@ def test_pass(): """TODO: Add docstring.""" - pass # def test_import_main(): diff --git a/node-hub/dora-reachy2/tests/test_dora_reachy2.py b/node-hub/dora-reachy2/tests/test_dora_reachy2.py index 7a6d8fa4..824f256f 100644 --- a/node-hub/dora-reachy2/tests/test_dora_reachy2.py +++ b/node-hub/dora-reachy2/tests/test_dora_reachy2.py @@ -5,7 +5,6 @@ def test_pass(): """TODO: Add docstring.""" - pass # def test_import_camera_main(): diff --git a/node-hub/dora-transformers/dora_transformers/__init__.py b/node-hub/dora-transformers/dora_transformers/__init__.py index 0d05dafb..79cbf370 100644 --- a/node-hub/dora-transformers/dora_transformers/__init__.py +++ b/node-hub/dora-transformers/dora_transformers/__init__.py @@ -7,7 +7,7 @@ readme_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "README.m # Read the content of the README file try: - with open(readme_path, "r", encoding="utf-8") as f: + with open(readme_path, encoding="utf-8") as f: __doc__ = f.read() except FileNotFoundError: __doc__ = "README file not found." diff --git a/node-hub/dora-transformers/dora_transformers/__main__.py b/node-hub/dora-transformers/dora_transformers/__main__.py index 7bc8a1f1..51a1554d 100644 --- a/node-hub/dora-transformers/dora_transformers/__main__.py +++ b/node-hub/dora-transformers/dora_transformers/__main__.py @@ -2,6 +2,5 @@ from .main import main - if __name__ == "__main__": main() diff --git a/node-hub/dora-transformers/dora_transformers/main.py b/node-hub/dora-transformers/dora_transformers/main.py index f963b5cb..18323e78 100644 --- a/node-hub/dora-transformers/dora_transformers/main.py +++ b/node-hub/dora-transformers/dora_transformers/main.py @@ -1,11 +1,12 @@ """TODO: Add docstring.""" +import logging import os + import pyarrow as pa +import torch from dora import Node from transformers import AutoModelForCausalLM, AutoTokenizer -import logging -import torch # Configure logging logging.basicConfig(level=logging.INFO) @@ -34,23 +35,23 @@ ACTIVATION_WORDS = os.getenv("ACTIVATION_WORDS", "what how who where you").split def load_model(): """Load the transformer model and tokenizer.""" logging.info(f"Loading model {MODEL_NAME} on {DEVICE}") - + # Memory efficient loading model_kwargs = { "torch_dtype": TORCH_DTYPE, "device_map": DEVICE, } - + if ENABLE_MEMORY_EFFICIENT and DEVICE == "cuda": model_kwargs.update({ "low_cpu_mem_usage": True, "offload_folder": "offload", - "load_in_8bit": True + "load_in_8bit": True, }) - + model = AutoModelForCausalLM.from_pretrained( MODEL_NAME, - **model_kwargs + **model_kwargs, ) tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME) logging.info("Model loaded successfully") @@ -61,37 +62,37 @@ def load_model(): def generate_response(model, tokenizer, text: str, history) -> tuple[str, list]: """Generate text using the transformer model.""" history += [{"role": "user", "content": text}] - + prompt = tokenizer.apply_chat_template( - history, tokenize=False, add_generation_prompt=True + history, tokenize=False, add_generation_prompt=True, ) - + model_inputs = tokenizer([prompt], return_tensors="pt").to(DEVICE) - + with torch.inference_mode(): generated_ids = model.generate( - **model_inputs, + **model_inputs, max_new_tokens=MAX_TOKENS, pad_token_id=tokenizer.pad_token_id, do_sample=True, temperature=0.7, - top_p=0.9, + top_p=0.9, repetition_penalty=1.2, length_penalty=0.5, ) - + generated_ids = [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] - + response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] history += [{"role": "assistant", "content": response}] - + # Clear CUDA cache after successful generation if enabled if ENABLE_MEMORY_EFFICIENT and DEVICE == "cuda": torch.cuda.empty_cache() - + return response, history def main(): @@ -111,11 +112,11 @@ def main(): logging.info(f"Processing input: {text}") response, history = generate_response(model, tokenizer, text, history) logging.info(f"Generated response: {response}") - + node.send_output( - output_id="text", - data=pa.array([response]), - metadata={} + output_id="text", + data=pa.array([response]), + metadata={}, ) if __name__ == "__main__": diff --git a/node-hub/dynamixel-client/dynamixel_client/bus.py b/node-hub/dynamixel-client/dynamixel_client/bus.py index a1d7f167..6809f4e7 100644 --- a/node-hub/dynamixel-client/dynamixel_client/bus.py +++ b/node-hub/dynamixel-client/dynamixel_client/bus.py @@ -1,19 +1,20 @@ """TODO: Add docstring.""" import enum - -import pyarrow as pa - from typing import Union +import pyarrow as pa from dynamixel_sdk import ( - PacketHandler, - PortHandler, COMM_SUCCESS, + DXL_HIBYTE, + DXL_HIWORD, + DXL_LOBYTE, + DXL_LOWORD, GroupSyncRead, GroupSyncWrite, + PacketHandler, + PortHandler, ) -from dynamixel_sdk import DXL_HIBYTE, DXL_HIWORD, DXL_LOBYTE, DXL_LOWORD PROTOCOL_VERSION = 2.0 BAUD_RATE = 1_000_000 @@ -70,7 +71,7 @@ def wrap_joints_and_values( mask = values.is_null() return pa.StructArray.from_arrays( - arrays=[joints, values], names=["joints", "values"], mask=mask + arrays=[joints, values], names=["joints", "values"], mask=mask, ).drop_null() @@ -248,7 +249,7 @@ class DynamixelBus: else: raise NotImplementedError( f"Value of the number of bytes to be sent is expected to be in [1, 2, 4], but {packet_bytes_size} " - f"is provided instead." + f"is provided instead.", ) if init_group: @@ -260,7 +261,7 @@ class DynamixelBus: if comm != COMM_SUCCESS: raise ConnectionError( f"Write failed due to communication error on port {self.port} for group_key {group_key}: " - f"{self.packet_handler.getTxRxResult(comm)}" + f"{self.packet_handler.getTxRxResult(comm)}", ) def read(self, data_name: str, motor_names: pa.Array) -> pa.StructArray: @@ -291,13 +292,13 @@ class DynamixelBus: if comm != COMM_SUCCESS: raise ConnectionError( f"Read failed due to communication error on port {self.port} for group_key {group_key}: " - f"{self.packet_handler.getTxRxResult(comm)}" + f"{self.packet_handler.getTxRxResult(comm)}", ) values = pa.array( [ self.group_readers[group_key].getData( - idx, packet_address, packet_bytes_size + idx, packet_address, packet_bytes_size, ) for idx in motor_ids ], diff --git a/node-hub/dynamixel-client/dynamixel_client/main.py b/node-hub/dynamixel-client/dynamixel_client/main.py index c54c1b22..fae0c375 100644 --- a/node-hub/dynamixel-client/dynamixel_client/main.py +++ b/node-hub/dynamixel-client/dynamixel_client/main.py @@ -3,13 +3,12 @@ It can be used to read positions, velocities, currents, and set goal positions and currents. """ -import os -import time import argparse import json +import os +import time import pyarrow as pa - from dora import Node from .bus import DynamixelBus, TorqueMode, wrap_joints_and_values @@ -76,7 +75,7 @@ class Client: wrap_joints_and_values( self.config["joints"], [TorqueMode.DISABLED.value] * len(self.config["joints"]), - ) + ), ) def pull_position(self, node, metadata): @@ -132,7 +131,7 @@ def main(): """Handle dynamic nodes, ask for the name of the node in the dataflow.""" parser = argparse.ArgumentParser( description="Dynamixel Client: This node is used to represent a chain of dynamixel motors. It can be used to " - "read positions, velocities, currents, and set goal positions and currents." + "read positions, velocities, currents, and set goal positions and currents.", ) parser.add_argument( @@ -162,7 +161,7 @@ def main(): if not os.environ.get("PORT") and args.port is None: raise ValueError( "The port is not set. Please set the port of the dynamixel motors in the environment variables or as an " - "argument." + "argument.", ) port = os.environ.get("PORT") if args.port is None else args.port @@ -171,7 +170,7 @@ def main(): if not os.environ.get("CONFIG") and args.config is None: raise ValueError( "The configuration is not set. Please set the configuration of the dynamixel motors in the environment " - "variables or as an argument." + "variables or as an argument.", ) with open(os.environ.get("CONFIG") if args.config is None else args.config) as file: @@ -203,7 +202,7 @@ def main(): "goal_current": wrap_joints_and_values( pa.array(config.keys(), pa.string()), pa.array( - [config[joint]["goal_current"] for joint in joints], type=pa.uint32() + [config[joint]["goal_current"] for joint in joints], type=pa.uint32(), ), ), "P": wrap_joints_and_values( diff --git a/node-hub/dynamixel-client/tests/test_dynamixel_client.py b/node-hub/dynamixel-client/tests/test_dynamixel_client.py index 7b8b9b4c..09b067cf 100644 --- a/node-hub/dynamixel-client/tests/test_dynamixel_client.py +++ b/node-hub/dynamixel-client/tests/test_dynamixel_client.py @@ -4,7 +4,6 @@ def test_pass(): """TODO: Add docstring.""" - pass # def test_import_main(): diff --git a/node-hub/feetech-client/feetech_client/__init__.py b/node-hub/feetech-client/feetech_client/__init__.py index b8973a5a..a9cca0f7 100644 --- a/node-hub/feetech-client/feetech_client/__init__.py +++ b/node-hub/feetech-client/feetech_client/__init__.py @@ -1 +1 @@ -"""TODO: Add docstring.""" \ No newline at end of file +"""TODO: Add docstring.""" diff --git a/node-hub/feetech-client/feetech_client/bus.py b/node-hub/feetech-client/feetech_client/bus.py index bca6030a..6e42d4db 100644 --- a/node-hub/feetech-client/feetech_client/bus.py +++ b/node-hub/feetech-client/feetech_client/bus.py @@ -194,7 +194,7 @@ class FeetechBus: else: raise NotImplementedError( f"Value of the number of bytes to be sent is expected to be in [1, 2, 4], but {packet_bytes_size} " - f"is provided instead." + f"is provided instead.", ) if init_group: @@ -206,7 +206,7 @@ class FeetechBus: if comm != COMM_SUCCESS: raise ConnectionError( f"Write failed due to communication error on port {self.port} for group_key {group_key}: " - f"{self.packet_handler.getTxRxResult(comm)}" + f"{self.packet_handler.getTxRxResult(comm)}", ) def read(self, data_name: str, motor_names: pa.Array) -> pa.StructArray: @@ -237,13 +237,13 @@ class FeetechBus: if comm != COMM_SUCCESS: raise ConnectionError( f"Read failed due to communication error on port {self.port} for group_key {group_key}: " - f"{self.packet_handler.getTxRxResult(comm)}" + f"{self.packet_handler.getTxRxResult(comm)}", ) values = pa.array( [ self.group_readers[group_key].getData( - idx, packet_address, packet_bytes_size + idx, packet_address, packet_bytes_size, ) for idx in motor_ids ], diff --git a/node-hub/feetech-client/feetech_client/main.py b/node-hub/feetech-client/feetech_client/main.py index c1f26d60..14203334 100644 --- a/node-hub/feetech-client/feetech_client/main.py +++ b/node-hub/feetech-client/feetech_client/main.py @@ -1,11 +1,10 @@ """Feetech Client: This node is used to represent a chain of feetech motors. It can be used to read positions, velocities, currents, and set goal positions and currents.""" -import os import argparse import json +import os import pyarrow as pa - from dora import Node from .bus import FeetechBus, TorqueMode, wrap_joints_and_values @@ -60,7 +59,7 @@ class Client: wrap_joints_and_values( self.config["joints"], [TorqueMode.DISABLED.value] * len(self.config["joints"]), - ) + ), ) def pull_position(self, node, metadata): @@ -110,7 +109,7 @@ def main(): parser = argparse.ArgumentParser( description="Feetech Client: This node is used to represent a chain of feetech motors. " "It can be used to read " - "positions, velocities, currents, and set goal positions and currents." + "positions, velocities, currents, and set goal positions and currents.", ) parser.add_argument( @@ -140,7 +139,7 @@ def main(): if not os.environ.get("PORT") and args.port is None: raise ValueError( "The port is not set. Please set the port of the feetech motors in the environment variables or as an " - "argument." + "argument.", ) port = os.environ.get("PORT") if args.port is None else args.port @@ -149,7 +148,7 @@ def main(): if not os.environ.get("CONFIG") and args.config is None: raise ValueError( "The configuration is not set. Please set the configuration of the feetech motors in the environment " - "variables or as an argument." + "variables or as an argument.", ) with open(os.environ.get("CONFIG") if args.config is None else args.config) as file: diff --git a/node-hub/feetech-client/tests/test_feetech_client.py b/node-hub/feetech-client/tests/test_feetech_client.py index b57c9bbb..de98f7e7 100644 --- a/node-hub/feetech-client/tests/test_feetech_client.py +++ b/node-hub/feetech-client/tests/test_feetech_client.py @@ -4,7 +4,6 @@ def test_pass(): """TODO: Add docstring.""" - pass # def test_import_main(): diff --git a/node-hub/lebai-client/lebai_client/main.py b/node-hub/lebai-client/lebai_client/main.py index e66b3e78..4c692a7f 100644 --- a/node-hub/lebai-client/lebai_client/main.py +++ b/node-hub/lebai-client/lebai_client/main.py @@ -1,11 +1,12 @@ """TODO: Add docstring.""" -import lebai_sdk -import numpy as np -from dora import Node import json import os import time +import lebai_sdk +import numpy as np +from dora import Node + def load_json_file(file_path): """Load JSON file and return the dictionary.""" @@ -28,7 +29,7 @@ SAVED_POSE_PATH = "pose_library.json" lebai_sdk.init() ROBOT_IP = os.getenv( - "LEBAI_IP", "10.42.0.253" + "LEBAI_IP", "10.42.0.253", ) # 设定机器人ip地址,需要根据机器人实际ip地址修改 @@ -180,7 +181,7 @@ def main(): "duration": time.time() - start_time, "joint_position": joint_position, "t": t * 2 if t == 0.1 else t, - } + }, ] start_time = time.time() diff --git a/node-hub/lebai-client/test/test.py b/node-hub/lebai-client/test/test.py index 0239ff15..8937d413 100644 --- a/node-hub/lebai-client/test/test.py +++ b/node-hub/lebai-client/test/test.py @@ -1,7 +1,6 @@ """TODO: Add docstring.""" import lebai_sdk - lebai_sdk.init() @@ -26,7 +25,7 @@ def main(): r = 0 # 交融半径 (m)。用于指定路径的平滑效果 lebai.movel( - cartesian_pose, a, v, t, r + cartesian_pose, a, v, t, r, ) # 直线运动 https://help.lebai.ltd/sdk/motion.html#%E7%9B%B4%E7%BA%BF%E8%BF%90%E5%8A%A8 lebai.wait_move() # 等待运动完成 # scene_number = "10000" #需要调用的场景编号 diff --git a/node-hub/lebai-client/tests/test_lebai_client.py b/node-hub/lebai-client/tests/test_lebai_client.py index 6bb9c958..a507997b 100644 --- a/node-hub/lebai-client/tests/test_lebai_client.py +++ b/node-hub/lebai-client/tests/test_lebai_client.py @@ -4,7 +4,6 @@ def test_pass(): """TODO: Add docstring.""" - pass # def test_import_main(): diff --git a/node-hub/lerobot-dashboard/lerobot_dashboard/__init__.py b/node-hub/lerobot-dashboard/lerobot_dashboard/__init__.py index b8973a5a..a9cca0f7 100644 --- a/node-hub/lerobot-dashboard/lerobot_dashboard/__init__.py +++ b/node-hub/lerobot-dashboard/lerobot_dashboard/__init__.py @@ -1 +1 @@ -"""TODO: Add docstring.""" \ No newline at end of file +"""TODO: Add docstring.""" diff --git a/node-hub/lerobot-dashboard/lerobot_dashboard/main.py b/node-hub/lerobot-dashboard/lerobot_dashboard/main.py index 1856bb97..2ddd742f 100644 --- a/node-hub/lerobot-dashboard/lerobot_dashboard/main.py +++ b/node-hub/lerobot-dashboard/lerobot_dashboard/main.py @@ -1,19 +1,17 @@ """Following Dora node is a minimalistic interface that shows two images and text in a Pygame window.""" -import os import argparse - -import pygame +import os import pyarrow as pa - +import pygame from dora import Node def main(): """Handle dynamic nodes, ask for the name of the node in the dataflow.""" parser = argparse.ArgumentParser( - description="LeRobot Record: This node is used to record episodes of a robot interacting with the environment." + description="LeRobot Record: This node is used to record episodes of a robot interacting with the environment.", ) parser.add_argument( @@ -66,7 +64,7 @@ def main(): if event_type == "STOP": break - elif event_type == "INPUT": + if event_type == "INPUT": event_id = event["id"] if event_id == "image_left": @@ -80,7 +78,7 @@ def main(): } image_left = pygame.image.frombuffer( - image["data"], (image["width"], image["height"]), "BGR" + image["data"], (image["width"], image["height"]), "BGR", ) elif event_id == "image_right": @@ -93,7 +91,7 @@ def main(): } image_right = pygame.image.frombuffer( - image["data"], (image["width"], image["height"]), "BGR" + image["data"], (image["width"], image["height"]), "BGR", ) elif event_id == "tick": @@ -104,7 +102,7 @@ def main(): if pygame_event.type == pygame.QUIT: running = False break - elif pygame_event.type == pygame.KEYDOWN: + if pygame_event.type == pygame.KEYDOWN: key = pygame.key.name(pygame_event.key) if key == "space": diff --git a/node-hub/lerobot-dashboard/tests/test_lerobot_dashboard.py b/node-hub/lerobot-dashboard/tests/test_lerobot_dashboard.py index c5ef139a..b3cab3b7 100644 --- a/node-hub/lerobot-dashboard/tests/test_lerobot_dashboard.py +++ b/node-hub/lerobot-dashboard/tests/test_lerobot_dashboard.py @@ -4,7 +4,6 @@ def test_pass(): """TODO: Add docstring.""" - pass # def test_import_main(): diff --git a/node-hub/mujoco-client/mujoco_client/__init__.py b/node-hub/mujoco-client/mujoco_client/__init__.py index b8973a5a..a9cca0f7 100644 --- a/node-hub/mujoco-client/mujoco_client/__init__.py +++ b/node-hub/mujoco-client/mujoco_client/__init__.py @@ -1 +1 @@ -"""TODO: Add docstring.""" \ No newline at end of file +"""TODO: Add docstring.""" diff --git a/node-hub/mujoco-client/mujoco_client/main.py b/node-hub/mujoco-client/mujoco_client/main.py index 1c2d80f1..d6543f33 100644 --- a/node-hub/mujoco-client/mujoco_client/main.py +++ b/node-hub/mujoco-client/mujoco_client/main.py @@ -1,16 +1,14 @@ """Mujoco Client: This node is used to represent simulated robot, it can be used to read virtual positions, or can be controlled.""" -import os import argparse -import time import json - -import pyarrow as pa - -from dora import Node +import os +import time import mujoco import mujoco.viewer +import pyarrow as pa +from dora import Node class Client: @@ -66,22 +64,19 @@ class Client: elif event_type == "ERROR": raise ValueError( - "An error occurred in the dataflow: " + event["error"] + "An error occurred in the dataflow: " + event["error"], ) self.node.send_output("end", pa.array([])) def pull_position(self, node, metadata): """TODO: Add docstring.""" - pass def pull_velocity(self, node, metadata): """TODO: Add docstring.""" - pass def pull_current(self, node, metadata): """TODO: Add docstring.""" - pass def write_goal_position(self, goal_position_with_joints): """TODO: Add docstring.""" @@ -96,7 +91,7 @@ def main(): """Handle dynamic nodes, ask for the name of the node in the dataflow.""" parser = argparse.ArgumentParser( description="MujoCo Client: This node is used to represent a MuJoCo simulation. It can be used instead of a " - "follower arm to test the dataflow." + "follower arm to test the dataflow.", ) parser.add_argument( @@ -114,14 +109,14 @@ def main(): ) parser.add_argument( - "--config", type=str, help="The configuration of the joints.", default=None + "--config", type=str, help="The configuration of the joints.", default=None, ) args = parser.parse_args() if not os.getenv("SCENE") and args.scene is None: raise ValueError( - "Please set the SCENE environment variable or pass the --scene argument." + "Please set the SCENE environment variable or pass the --scene argument.", ) scene = os.getenv("SCENE", args.scene) @@ -130,7 +125,7 @@ def main(): if not os.environ.get("CONFIG") and args.config is None: raise ValueError( "The configuration is not set. Please set the configuration of the simulated motors in the environment " - "variables or as an argument." + "variables or as an argument.", ) with open(os.environ.get("CONFIG") if args.config is None else args.config) as file: diff --git a/node-hub/mujoco-client/tests/test_mujoco_client.py b/node-hub/mujoco-client/tests/test_mujoco_client.py index 603a1e20..5b4f371a 100644 --- a/node-hub/mujoco-client/tests/test_mujoco_client.py +++ b/node-hub/mujoco-client/tests/test_mujoco_client.py @@ -4,7 +4,6 @@ def test_pass(): """TODO: Add docstring.""" - pass # def test_import_main(): diff --git a/node-hub/replay-client/replay_client/__init__.py b/node-hub/replay-client/replay_client/__init__.py index b8973a5a..a9cca0f7 100644 --- a/node-hub/replay-client/replay_client/__init__.py +++ b/node-hub/replay-client/replay_client/__init__.py @@ -1 +1 @@ -"""TODO: Add docstring.""" \ No newline at end of file +"""TODO: Add docstring.""" diff --git a/node-hub/replay-client/replay_client/main.py b/node-hub/replay-client/replay_client/main.py index eca1931e..931662b9 100644 --- a/node-hub/replay-client/replay_client/main.py +++ b/node-hub/replay-client/replay_client/main.py @@ -3,12 +3,11 @@ reading a dataset of actions and joints from a specific episode. """ -import os import argparse +import os -import pyarrow as pa import pandas as pd - +import pyarrow as pa from dora import Node @@ -78,7 +77,7 @@ class Client: def main(): """Handle dynamic nodes, ask for the name of the node in the dataflow.""" parser = argparse.ArgumentParser( - description="Replay Client: This node is used to replay a sequence of goals for a followee robot." + description="Replay Client: This node is used to replay a sequence of goals for a followee robot.", ) parser.add_argument( diff --git a/node-hub/replay-client/tests/test_replay_client.py b/node-hub/replay-client/tests/test_replay_client.py index 6e30406e..d612f13d 100644 --- a/node-hub/replay-client/tests/test_replay_client.py +++ b/node-hub/replay-client/tests/test_replay_client.py @@ -4,7 +4,6 @@ def test_pass(): """TODO: Add docstring.""" - pass # def test_import_main(): diff --git a/node-hub/video-encoder/tests/test_video_encoder.py b/node-hub/video-encoder/tests/test_video_encoder.py index b8b4c3da..6d3f7bed 100644 --- a/node-hub/video-encoder/tests/test_video_encoder.py +++ b/node-hub/video-encoder/tests/test_video_encoder.py @@ -4,7 +4,6 @@ def test_pass(): """TODO: Add docstring.""" - pass # def test_import_main(): diff --git a/node-hub/video-encoder/video_encoder/__init__.py b/node-hub/video-encoder/video_encoder/__init__.py index 42a8a3b2..55941eec 100644 --- a/node-hub/video-encoder/video_encoder/__init__.py +++ b/node-hub/video-encoder/video_encoder/__init__.py @@ -1 +1 @@ -"""TODO: Doc String.""" \ No newline at end of file +"""TODO: Doc String.""" diff --git a/node-hub/video-encoder/video_encoder/main.py b/node-hub/video-encoder/video_encoder/main.py index 8ccb0fa3..1f9355ed 100644 --- a/node-hub/video-encoder/video_encoder/main.py +++ b/node-hub/video-encoder/video_encoder/main.py @@ -1,13 +1,11 @@ """TODO : Doc String.""" +import argparse import os from pathlib import Path import cv2 -import argparse - import numpy as np import pyarrow as pa - from dora import Node from ffmpeg import FFmpeg @@ -15,7 +13,7 @@ from ffmpeg import FFmpeg def main(): """Handle dynamic nodes, ask for the name of the node in the dataflow.""" parser = argparse.ArgumentParser( - description="Video Encoder: This node is used to record episodes of a robot interacting with the environment." + description="Video Encoder: This node is used to record episodes of a robot interacting with the environment.", ) parser.add_argument( @@ -77,8 +75,8 @@ def main(): { "path": f"videos/{name}", "timestamp": float(frame_count) / fps, - } - ] + }, + ], ), event["metadata"], ) @@ -92,7 +90,7 @@ def main(): } data = image["data"].reshape( - (image["height"], image["width"], image["channels"]) + (image["height"], image["width"], image["channels"]), ) path = str(out_dir / f"frame_{frame_count:06d}.png") @@ -118,7 +116,7 @@ def main(): .option("y") .input(str(out_dir / "frame_%06d.png"), f="image2", r=fps) .output( - str(video_path), vcodec="libx264", g=2, pix_fmt="yuv444p" + str(video_path), vcodec="libx264", g=2, pix_fmt="yuv444p", ) ) From abf77bfb757107cb042f9d450142fdc1eab12900 Mon Sep 17 00:00:00 2001 From: 7SOMAY Date: Mon, 17 Mar 2025 21:25:38 +0530 Subject: [PATCH 3/5] Fixed necessary linting issues --- examples/alexk-lcr/bus.py | 14 ++ examples/alexk-lcr/configure.py | 13 +- .../alexk-lcr/nodes/interpolate_lcr_to_lcr.py | 7 + .../nodes/interpolate_lcr_to_record.py | 3 + .../nodes/interpolate_lcr_to_simu_lcr.py | 7 + .../nodes/interpolate_replay_to_lcr.py | 3 + examples/aloha/benchmark/python/dynamixel.py | 225 +++++++++++++++++- examples/aloha/benchmark/python/robot.py | 69 +++++- .../python/teleoperate_real_robot.py | 6 + examples/aloha/benchmark/ros2/teleop.py | 6 + examples/aloha/nodes/gym_dora_node.py | 29 +++ examples/aloha/nodes/keyboard_node.py | 6 + examples/aloha/nodes/lerobot_webcam_saver.py | 2 + examples/aloha/nodes/llm_op.py | 88 +++++-- examples/aloha/nodes/plot_node.py | 2 + examples/aloha/nodes/policy.py | 23 ++ examples/aloha/nodes/realsense_node.py | 6 + examples/aloha/nodes/replay.py | 2 + examples/aloha/nodes/webcam.py | 6 + examples/aloha/nodes/whisper_node.py | 14 ++ examples/aloha/tests/test_realsense.py | 2 + examples/lebai/nodes/interpolation.py | 6 + examples/lebai/nodes/key_interpolation.py | 6 + examples/lebai/nodes/prompt_interpolation.py | 2 + examples/lebai/nodes/vlm_prompt.py | 4 + examples/lebai/nodes/voice_interpolation.py | 6 + examples/reachy/nodes/gym_dora_node.py | 47 ++++ examples/reachy/nodes/keyboard_node.py | 6 + examples/reachy/nodes/lerobot_webcam_saver.py | 2 + examples/reachy/nodes/plot_node.py | 6 + examples/reachy/nodes/reachy_client.py | 2 + examples/reachy/nodes/reachy_vision_client.py | 2 + examples/reachy/nodes/replay_node.py | 2 + examples/reachy1/nodes/gym_dora_node.py | 10 + examples/reachy1/nodes/key_interpolation.py | 2 + examples/reachy1/nodes/keyboard_node.py | 2 + .../reachy1/nodes/lerobot_webcam_saver.py | 6 + examples/reachy1/nodes/plot_node.py | 6 + examples/reachy1/nodes/reachy_client.py | 6 + .../reachy1/nodes/reachy_vision_client.py | 6 + examples/reachy1/nodes/replay_node.py | 6 + examples/reachy1/nodes/text_interpolation.py | 6 + examples/so100/bus.py | 112 ++++++++- examples/so100/configure.py | 8 +- .../so100/nodes/interpolate_lcr_to_so100.py | 4 +- .../interpolate_lcr_x_so100_to_record.py | 8 +- .../nodes/interpolate_replay_to_so100.py | 8 +- tests/llm/run_script.py | 2 + 48 files changed, 771 insertions(+), 45 deletions(-) diff --git a/examples/alexk-lcr/bus.py b/examples/alexk-lcr/bus.py index 78043e6a..d67ba380 100644 --- a/examples/alexk-lcr/bus.py +++ b/examples/alexk-lcr/bus.py @@ -58,6 +58,7 @@ def wrap_joints_and_values( struct_array = wrap_joints_and_values(joints, value) This example broadcasts the single integer value to all joints and wraps them into a structured array. + """ if isinstance(values, int): values = [values] * len(joints) @@ -171,6 +172,7 @@ class DynamixelBus: description: A dictionary containing the description of the motors connected to the bus. The keys are the motor names and the values are tuples containing the motor id and the motor model. + """ self.port = port self.descriptions = description @@ -211,6 +213,7 @@ class DynamixelBus: Args: data_name: Name of the parameter to write. data: Structured array containing the data to write. + """ motor_ids = [ self.motor_ctrl[motor_name.as_py()]["id"] @@ -288,6 +291,7 @@ class DynamixelBus: Returns: Structured array containing the read data. + """ motor_ids = [ self.motor_ctrl[motor_name.as_py()]["id"] for motor_name in motor_names @@ -336,6 +340,7 @@ class DynamixelBus: Args: torque_mode: Structured array containing the torque mode for each servo. + """ self.write("Torque_Enable", torque_mode) @@ -344,6 +349,7 @@ class DynamixelBus: Args: operating_mode: Structured array containing the operating mode for each servo. + """ self.write("Operating_Mode", operating_mode) @@ -355,6 +361,7 @@ class DynamixelBus: Returns: Structured array containing the current positions. + """ return self.read("Present_Position", motor_names) @@ -366,6 +373,7 @@ class DynamixelBus: Returns: Structured array containing the current velocities. + """ return self.read("Present_Velocity", motor_names) @@ -377,6 +385,7 @@ class DynamixelBus: Returns: Structured array containing the current currents. + """ return self.read("Present_Current", motor_names) @@ -385,6 +394,7 @@ class DynamixelBus: Args: goal_position: Structured array containing the goal positions. + """ self.write("Goal_Position", goal_position) @@ -393,6 +403,7 @@ class DynamixelBus: Args: goal_current: Structured array containing the goal currents. + """ self.write("Goal_Current", goal_current) @@ -401,6 +412,7 @@ class DynamixelBus: Args: position_p_gain: Structured array containing the position P gains. + """ self.write("Position_P_Gain", position_p_gain) @@ -409,6 +421,7 @@ class DynamixelBus: Args: position_i_gain: Structured array containing the position I gains. + """ self.write("Position_I_Gain", position_i_gain) @@ -417,5 +430,6 @@ class DynamixelBus: Args: position_d_gain: Structured array containing the position D gains. + """ self.write("Position_D_Gain", position_d_gain) diff --git a/examples/alexk-lcr/configure.py b/examples/alexk-lcr/configure.py index dd72bd58..e71d4884 100644 --- a/examples/alexk-lcr/configure.py +++ b/examples/alexk-lcr/configure.py @@ -1,4 +1,7 @@ -"""LCR Configuration Tool: This program is used to automatically configure the Low Cost Robot (LCR) for the user. +"""Module for configuring and setting up the Low Cost Robot (LCR) hardware. + +This module provides functionality for initializing and configuring the LCR robot's +servo motors and other hardware components. The program will: 1. Disable all torque motors of provided LCR. @@ -46,10 +49,17 @@ GRIPPER = pa.array(["gripper"], type=pa.string()) def pause(): + """Pause execution and wait for user input to continue.""" input("Press Enter to continue...") def configure_servos(bus: DynamixelBus): + """Configure servo motors with appropriate settings. + + Args: + bus: DynamixelBus instance for servo communication + + """ bus.write_torque_enable( wrap_joints_and_values(FULL_ARM, [TorqueMode.DISABLED.value] * 6), ) @@ -68,6 +78,7 @@ def configure_servos(bus: DynamixelBus): def main(): + """Initialize and configure the LCR robot hardware components.""" parser = argparse.ArgumentParser( description="LCR Auto Configure: This program is used to automatically configure the Low Cost Robot (LCR) for " "the user.", diff --git a/examples/alexk-lcr/nodes/interpolate_lcr_to_lcr.py b/examples/alexk-lcr/nodes/interpolate_lcr_to_lcr.py index c3c42fb3..70db01ae 100644 --- a/examples/alexk-lcr/nodes/interpolate_lcr_to_lcr.py +++ b/examples/alexk-lcr/nodes/interpolate_lcr_to_lcr.py @@ -1,3 +1,9 @@ +"""Module for interpolating between LCR robot configurations. + +This module provides functionality for calculating and interpolating between +different LCR robot configurations to ensure smooth transitions. +""" + import argparse import json import os @@ -14,6 +20,7 @@ from pwm_position_control.transform import ( def main(): + """Initialize and run the LCR interpolation node.""" parser = argparse.ArgumentParser( description="Interpolation LCR Node: This Dora node is used to calculates appropriate goal positions for the " "LCR followers knowing a Leader position and Follower position.", diff --git a/examples/alexk-lcr/nodes/interpolate_lcr_to_record.py b/examples/alexk-lcr/nodes/interpolate_lcr_to_record.py index c04022f8..8ca90704 100644 --- a/examples/alexk-lcr/nodes/interpolate_lcr_to_record.py +++ b/examples/alexk-lcr/nodes/interpolate_lcr_to_record.py @@ -1,3 +1,5 @@ +"""TODO: Add docstring.""" + import argparse import json import os @@ -13,6 +15,7 @@ from pwm_position_control.transform import ( def main(): + """TODO: Add docstring.""" parser = argparse.ArgumentParser( description="Interpolation LCR Node: This Dora node is used to calculates appropriate goal positions for the " "LCR followers knowing a Leader position and Follower position.", diff --git a/examples/alexk-lcr/nodes/interpolate_lcr_to_simu_lcr.py b/examples/alexk-lcr/nodes/interpolate_lcr_to_simu_lcr.py index 925af277..d4da0ca3 100644 --- a/examples/alexk-lcr/nodes/interpolate_lcr_to_simu_lcr.py +++ b/examples/alexk-lcr/nodes/interpolate_lcr_to_simu_lcr.py @@ -1,3 +1,9 @@ +"""Module for interpolating between LCR and simulated LCR configurations. + +This module provides functionality for calculating and interpolating between +physical LCR robot configurations and their simulated counterparts. +""" + import argparse import json import os @@ -15,6 +21,7 @@ from pwm_position_control.transform import ( def main(): + """Initialize and run the LCR to simulated LCR interpolation node.""" parser = argparse.ArgumentParser( description="Interpolation LCR Node: This Dora node is used to calculates appropriate goal positions for the " "LCR followers knowing a Leader position and Follower position.", diff --git a/examples/alexk-lcr/nodes/interpolate_replay_to_lcr.py b/examples/alexk-lcr/nodes/interpolate_replay_to_lcr.py index b4ee763b..cdd38826 100644 --- a/examples/alexk-lcr/nodes/interpolate_replay_to_lcr.py +++ b/examples/alexk-lcr/nodes/interpolate_replay_to_lcr.py @@ -1,3 +1,5 @@ +"""TODO: Add docstring.""" + import argparse import json import os @@ -8,6 +10,7 @@ from pwm_position_control.transform import logical_to_pwm_with_offset_arrow def main(): + """TODO: Add docstring.""" parser = argparse.ArgumentParser( description="Interpolation LCR Node: This Dora node is used to calculates appropriate goal positions for the " "LCR followers knowing a Leader position and Follower position.", diff --git a/examples/aloha/benchmark/python/dynamixel.py b/examples/aloha/benchmark/python/dynamixel.py index fefa28f8..67c5a9e5 100644 --- a/examples/aloha/benchmark/python/dynamixel.py +++ b/examples/aloha/benchmark/python/dynamixel.py @@ -1,3 +1,10 @@ +"""Module for managing Dynamixel servo communication and control. + +This module provides functionality for communicating with and controlling Dynamixel servos +through a serial interface. It includes methods for reading and writing servo parameters, +managing operating modes, and handling joint positions and velocities. +""" + from __future__ import annotations import enum @@ -10,6 +17,8 @@ from dynamixel_sdk import * # Uses Dynamixel SDK library class ReadAttribute(enum.Enum): + """Enumeration for Dynamixel servo read attributes.""" + TEMPERATURE = 146 VOLTAGE = 145 VELOCITY = 128 @@ -22,6 +31,8 @@ class ReadAttribute(enum.Enum): class OperatingMode(enum.Enum): + """Enumeration for Dynamixel servo operating modes.""" + VELOCITY = 1 POSITION = 3 CURRENT_CONTROLLED_POSITION = 5 @@ -30,6 +41,8 @@ class OperatingMode(enum.Enum): class Dynamixel: + """Class for managing communication with Dynamixel servos.""" + ADDR_TORQUE_ENABLE = 64 ADDR_GOAL_POSITION = 116 ADDR_VELOCITY_LIMIT = 44 @@ -41,7 +54,10 @@ class Dynamixel: @dataclass class Config: + """Configuration class for Dynamixel servo settings.""" + def instantiate(self): + """Create a new Dynamixel instance with this configuration.""" return Dynamixel(self) baudrate: int = 57600 @@ -50,10 +66,17 @@ class Dynamixel: dynamixel_id: int = 1 def __init__(self, config: Config): + """Initialize the Dynamixel servo connection. + + Args: + config: Configuration object containing connection settings. + + """ self.config = config self.connect() def connect(self): + """Establish connection with the Dynamixel servo.""" if self.config.device_name == "": for port_name in os.listdir("/dev"): if "ttyUSB" in port_name or "ttyACM" in port_name: @@ -77,9 +100,17 @@ class Dynamixel: return True def disconnect(self): + """Close the connection with the Dynamixel servo.""" self.portHandler.closePort() def set_goal_position(self, motor_id, goal_position): + """Set the goal position for the specified servo. + + Args: + motor_id: ID of the servo to control. + goal_position: Target position value. + + """ # if self.operating_modes[motor_id] is not OperatingMode.POSITION: # self._disable_torque(motor_id) # self.set_operating_mode(motor_id, OperatingMode.POSITION) @@ -95,6 +126,14 @@ class Dynamixel: # print(f'set position of motor {motor_id} to {goal_position}') def set_pwm_value(self, motor_id: int, pwm_value, tries=3): + """Set the PWM value for the specified servo. + + Args: + motor_id: ID of the servo to control. + pwm_value: PWM value to set. + tries: Number of attempts to set the value. + + """ if self.operating_modes[motor_id] is not OperatingMode.PWM: self._disable_torque(motor_id) self.set_operating_mode(motor_id, OperatingMode.PWM) @@ -123,9 +162,27 @@ class Dynamixel: ) def read_temperature(self, motor_id: int): + """Read the temperature of the specified servo. + + Args: + motor_id: ID of the servo to read from. + + Returns: + The current temperature value. + + """ return self._read_value(motor_id, ReadAttribute.TEMPERATURE, 1) def read_velocity(self, motor_id: int): + """Read the current velocity of the specified servo. + + Args: + motor_id: ID of the servo to read from. + + Returns: + The current velocity value. + + """ pos = self._read_value(motor_id, ReadAttribute.VELOCITY, 4) if pos > 2**31: pos -= 2**32 @@ -133,6 +190,15 @@ class Dynamixel: return pos def read_position(self, motor_id: int): + """Read the current position of the specified servo. + + Args: + motor_id: ID of the servo to read from. + + Returns: + The current position value. + + """ pos = self._read_value(motor_id, ReadAttribute.POSITION, 4) if pos > 2**31: pos -= 2**32 @@ -140,30 +206,77 @@ class Dynamixel: return pos def read_position_degrees(self, motor_id: int) -> float: + """Read the current position of the specified servo in degrees. + + Args: + motor_id: ID of the servo to read from. + + Returns: + The current position in degrees. + + """ return (self.read_position(motor_id) / 4096) * 360 def read_position_radians(self, motor_id: int) -> float: + """Read the current position of the specified servo in radians. + + Args: + motor_id: ID of the servo to read from. + + Returns: + The current position in radians. + + """ return (self.read_position(motor_id) / 4096) * 2 * math.pi def read_current(self, motor_id: int): + """Read the current value of the specified servo. + + Args: + motor_id: ID of the servo to read from. + + Returns: + The current value. + + """ current = self._read_value(motor_id, ReadAttribute.CURRENT, 2) if current > 2**15: current -= 2**16 return current def read_present_pwm(self, motor_id: int): + """Read the current PWM value of the specified servo. + + Args: + motor_id: ID of the servo to read from. + + Returns: + The current PWM value. + + """ return self._read_value(motor_id, ReadAttribute.PWM, 2) def read_hardware_error_status(self, motor_id: int): + """Read the hardware error status of the specified servo. + + Args: + motor_id: ID of the servo to read from. + + Returns: + The hardware error status value. + + """ return self._read_value(motor_id, ReadAttribute.HARDWARE_ERROR_STATUS, 1) def set_id(self, old_id, new_id, use_broadcast_id: bool = False): - """Sets the id of the dynamixel servo - @param old_id: current id of the servo - @param new_id: new id - @param use_broadcast_id: set ids of all connected dynamixels if True. - If False, change only servo with self.config.id - @return: + """Set the ID of the Dynamixel servo. + + Args: + old_id: Current ID of the servo. + new_id: New ID to set. + use_broadcast_id: If True, set IDs of all connected servos. + If False, change only servo with self.config.id + """ if use_broadcast_id: current_id = 254 @@ -176,6 +289,12 @@ class Dynamixel: self.config.id = id def _enable_torque(self, motor_id): + """Enable torque for the specified servo. + + Args: + motor_id: ID of the servo to control. + + """ dxl_comm_result, dxl_error = self.packetHandler.write1ByteTxRx( self.portHandler, motor_id, self.ADDR_TORQUE_ENABLE, 1, ) @@ -183,6 +302,12 @@ class Dynamixel: self.torque_enabled[motor_id] = True def _disable_torque(self, motor_id): + """Disable torque for the specified servo. + + Args: + motor_id: ID of the servo to control. + + """ dxl_comm_result, dxl_error = self.packetHandler.write1ByteTxRx( self.portHandler, motor_id, self.ADDR_TORQUE_ENABLE, 0, ) @@ -190,6 +315,18 @@ class Dynamixel: self.torque_enabled[motor_id] = False def _process_response(self, dxl_comm_result: int, dxl_error: int, motor_id: int): + """Process the response from a servo communication. + + Args: + dxl_comm_result: Communication result. + dxl_error: Error value. + motor_id: ID of the servo that was communicated with. + + Raises: + ConnectionError: If communication failed. + RuntimeError: If servo reported an error. + + """ if dxl_comm_result != COMM_SUCCESS: raise ConnectionError( f"dxl_comm_result for motor {motor_id}: {self.packetHandler.getTxRxResult(dxl_comm_result)}", @@ -201,6 +338,13 @@ class Dynamixel: ) def set_operating_mode(self, motor_id: int, operating_mode: OperatingMode): + """Set the operating mode for the specified servo. + + Args: + motor_id: ID of the servo to control. + operating_mode: Operating mode to set. + + """ dxl_comm_result, dxl_error = self.packetHandler.write2ByteTxRx( self.portHandler, motor_id, self.OPERATING_MODE_ADDR, operating_mode.value, ) @@ -208,30 +352,67 @@ class Dynamixel: self.operating_modes[motor_id] = operating_mode def set_pwm_limit(self, motor_id: int, limit: int): + """Set the PWM limit for the specified servo. + + Args: + motor_id: ID of the servo to control. + limit: PWM limit value to set. + + """ dxl_comm_result, dxl_error = self.packetHandler.write2ByteTxRx( self.portHandler, motor_id, 36, limit, ) self._process_response(dxl_comm_result, dxl_error, motor_id) def set_velocity_limit(self, motor_id: int, velocity_limit): + """Set the velocity limit for the specified servo. + + Args: + motor_id: ID of the servo to control. + velocity_limit: Velocity limit value to set. + + """ dxl_comm_result, dxl_error = self.packetHandler.write4ByteTxRx( self.portHandler, motor_id, self.ADDR_VELOCITY_LIMIT, velocity_limit, ) self._process_response(dxl_comm_result, dxl_error, motor_id) def set_P(self, motor_id: int, P: int): + """Set the position P gain for the specified servo. + + Args: + motor_id: ID of the servo to control. + P: Position P gain value to set. + + """ dxl_comm_result, dxl_error = self.packetHandler.write2ByteTxRx( self.portHandler, motor_id, self.POSITION_P, P, ) self._process_response(dxl_comm_result, dxl_error, motor_id) def set_I(self, motor_id: int, I: int): + """Set the position I gain for the specified servo. + + Args: + motor_id: ID of the servo to control. + I: Position I gain value to set. + + """ dxl_comm_result, dxl_error = self.packetHandler.write2ByteTxRx( self.portHandler, motor_id, self.POSITION_I, I, ) self._process_response(dxl_comm_result, dxl_error, motor_id) def read_home_offset(self, motor_id: int): + """Read the home offset of the specified servo. + + Args: + motor_id: ID of the servo to read from. + + Returns: + The home offset value. + + """ self._disable_torque(motor_id) # dxl_comm_result, dxl_error = self.packetHandler.write4ByteTxRx(self.portHandler, motor_id, # ReadAttribute.HOMING_OFFSET.value, home_position) @@ -241,6 +422,13 @@ class Dynamixel: return home_offset def set_home_offset(self, motor_id: int, home_position: int): + """Set the home offset for the specified servo. + + Args: + motor_id: ID of the servo to control. + home_position: Home position value to set. + + """ self._disable_torque(motor_id) dxl_comm_result, dxl_error = self.packetHandler.write4ByteTxRx( self.portHandler, motor_id, ReadAttribute.HOMING_OFFSET.value, home_position, @@ -249,6 +437,13 @@ class Dynamixel: self._enable_torque(motor_id) def set_baudrate(self, motor_id: int, baudrate): + """Set the baudrate for the specified servo. + + Args: + motor_id: ID of the servo to control. + baudrate: Baudrate value to set. + + """ # translate baudrate into dynamixel baudrate setting id if baudrate == 57600: baudrate_id = 1 @@ -270,6 +465,18 @@ class Dynamixel: self._process_response(dxl_comm_result, dxl_error, motor_id) def _read_value(self, motor_id, attribute: ReadAttribute, num_bytes: int, tries=10): + """Read a value from the specified servo address. + + Args: + motor_id: ID of the servo to read from. + attribute: Attribute to read. + num_bytes: Number of bytes to read. + tries: Number of attempts to read the value. + + Returns: + The read value. + + """ try: if num_bytes == 1: value, dxl_comm_result, dxl_error = self.packetHandler.read1ByteTxRx( @@ -310,6 +517,12 @@ class Dynamixel: return value def set_home_position(self, motor_id: int): + """Set the home position for the specified servo. + + Args: + motor_id: ID of the servo to control. + + """ print(f"setting home position for motor {motor_id}") self.set_home_offset(motor_id, 0) current_position = self.read_position(motor_id) diff --git a/examples/aloha/benchmark/python/robot.py b/examples/aloha/benchmark/python/robot.py index b2c1b0d6..5f16bb80 100644 --- a/examples/aloha/benchmark/python/robot.py +++ b/examples/aloha/benchmark/python/robot.py @@ -1,3 +1,9 @@ +"""Module for controlling robot hardware and movements. + +This module provides functionality for controlling robot hardware components, +including servo motors and various control modes. +""" + import time from enum import Enum, auto from typing import Union @@ -15,6 +21,12 @@ from dynamixel_sdk import ( class MotorControlType(Enum): + """Enumeration of different motor control modes. + + Defines the various control modes available for the robot's motors, + including PWM control, position control, and disabled states. + """ + PWM = auto() POSITION_CONTROL = auto() DISABLED = auto() @@ -22,8 +34,22 @@ class MotorControlType(Enum): class Robot: + """A class for controlling robot hardware components. + + This class provides methods for controlling robot servos, managing different + control modes, and reading sensor data. + """ + # def __init__(self, device_name: str, baudrate=1_000_000, servo_ids=[1, 2, 3, 4, 5]): def __init__(self, dynamixel, baudrate=1_000_000, servo_ids=[1, 2, 3, 4, 5]): + """Initialize the robot controller. + + Args: + dynamixel: Dynamixel controller instance + baudrate: Communication baudrate for servo control + servo_ids: List of servo IDs to control + + """ self.servo_ids = servo_ids self.dynamixel = dynamixel # self.dynamixel = Dynamixel.Config(baudrate=baudrate, device_name=device_name).instantiate() @@ -66,9 +92,14 @@ class Robot: self.motor_control_state = MotorControlType.DISABLED def read_position(self, tries=2): - """Reads the joint positions of the robot. 2048 is the center position. 0 and 4096 are 180 degrees in each direction. - :param tries: maximum number of tries to read the position - :return: list of joint positions in range [0, 4096] + """Read the current joint positions of the robot. + + Args: + tries: Maximum number of attempts to read positions + + Returns: + list: Joint positions in range [0, 4096] + """ result = self.position_reader.txRxPacket() if result != 0: @@ -84,8 +115,11 @@ class Robot: return positions def read_velocity(self): - """Reads the joint velocities of the robot. - :return: list of joint velocities, + """Read the current joint velocities of the robot. + + Returns: + list: Current joint velocities + """ self.velocity_reader.txRxPacket() velocties = [] @@ -97,7 +131,11 @@ class Robot: return velocties def set_goal_pos(self, action): - """:param action: list or numpy array of target joint positions in range [0, 4096] + """Set goal positions for the robot joints. + + Args: + action: List or numpy array of target joint positions in range [0, 4096] + """ if self.motor_control_state is not MotorControlType.POSITION_CONTROL: self._set_position_control() @@ -113,8 +151,11 @@ class Robot: self.pos_writer.txPacket() def set_pwm(self, action): - """Sets the pwm values for the servos. - :param action: list or numpy array of pwm values in range [0, 885] + """Set PWM values for the servos. + + Args: + action: List or numpy array of PWM values in range [0, 885] + """ if self.motor_control_state is not MotorControlType.PWM: self._set_pwm_control() @@ -128,15 +169,19 @@ class Robot: self.pwm_writer.txPacket() def set_trigger_torque(self): - """Sets a constant torque torque for the last servo in the chain. This is useful for the trigger of the leader arm + """Set a constant torque for the last servo in the chain. + + This is useful for the trigger of the leader arm. """ self.dynamixel._enable_torque(self.servo_ids[-1]) self.dynamixel.set_pwm_value(self.servo_ids[-1], 200) def limit_pwm(self, limit: Union[int, list, np.ndarray]): - """Limits the pwm values for the servos in for position control - @param limit: 0 ~ 885 - @return: + """Limit the PWM values for the servos in position control. + + Args: + limit: PWM limit value in range 0-885 + """ if isinstance(limit, int): limits = [ diff --git a/examples/aloha/benchmark/python/teleoperate_real_robot.py b/examples/aloha/benchmark/python/teleoperate_real_robot.py index 74675656..004059c3 100644 --- a/examples/aloha/benchmark/python/teleoperate_real_robot.py +++ b/examples/aloha/benchmark/python/teleoperate_real_robot.py @@ -1,3 +1,9 @@ +"""Module for teleoperating a physical robot. + +This module provides functionality for controlling a physical robot through +teleoperation, allowing real-time control of robot movements and actions. +""" + from dynamixel import Dynamixel from robot import Robot diff --git a/examples/aloha/benchmark/ros2/teleop.py b/examples/aloha/benchmark/ros2/teleop.py index dc127a67..d3cbbc18 100644 --- a/examples/aloha/benchmark/ros2/teleop.py +++ b/examples/aloha/benchmark/ros2/teleop.py @@ -1,3 +1,9 @@ +"""Module for ROS2-based robot teleoperation. + +This module provides functionality for controlling robots through ROS2, +enabling teleoperation and real-time control of robot movements. +""" + import dora import numpy as np import pyarrow as pa diff --git a/examples/aloha/nodes/gym_dora_node.py b/examples/aloha/nodes/gym_dora_node.py index 70af510d..fd9b3e69 100644 --- a/examples/aloha/nodes/gym_dora_node.py +++ b/examples/aloha/nodes/gym_dora_node.py @@ -1,3 +1,9 @@ +"""Module for integrating gym environments with Dora nodes. + +This module provides functionality for running gym environments as Dora nodes, +including replay capabilities for recorded robot actions. +""" + import time from pathlib import Path @@ -12,7 +18,20 @@ observation = env.reset() class ReplayPolicy: + """A policy class for replaying recorded robot actions. + + This class handles loading and replaying recorded actions from a dataset, + maintaining timing between actions to match the original recording. + """ + def __init__(self, example_path, epidode=0): + """Initialize the replay policy. + + Args: + example_path: Path to the directory containing recorded actions + epidode: Index of the episode to replay + + """ df_action = pd.read_parquet(example_path / "action.parquet") df_episode_index = pd.read_parquet(example_path / "episode_index.parquet") self.df = pd.merge_asof( @@ -29,6 +48,16 @@ class ReplayPolicy: self.finished = False def select_action(self, obs): + """Select the next action to replay. + + Args: + obs: Current observation from the environment (unused) + + Returns: + tuple: (action, finished) where action is the next action to take + and finished indicates if all actions have been replayed + + """ if self.index < len(self.df): self.index += 1 else: diff --git a/examples/aloha/nodes/keyboard_node.py b/examples/aloha/nodes/keyboard_node.py index 32fee0dc..0427213b 100644 --- a/examples/aloha/nodes/keyboard_node.py +++ b/examples/aloha/nodes/keyboard_node.py @@ -1,3 +1,9 @@ +"""Module for handling keyboard input events in robot control. + +This module provides functionality for capturing and processing keyboard input +events to control robot movements and actions. +""" + import pyarrow as pa from dora import Node from pynput import keyboard diff --git a/examples/aloha/nodes/lerobot_webcam_saver.py b/examples/aloha/nodes/lerobot_webcam_saver.py index 840a39fe..c1766115 100644 --- a/examples/aloha/nodes/lerobot_webcam_saver.py +++ b/examples/aloha/nodes/lerobot_webcam_saver.py @@ -1,3 +1,5 @@ +"""TODO: Add docstring.""" + #!/usr/bin/env python3 import os diff --git a/examples/aloha/nodes/llm_op.py b/examples/aloha/nodes/llm_op.py index 07797349..9dc8e657 100644 --- a/examples/aloha/nodes/llm_op.py +++ b/examples/aloha/nodes/llm_op.py @@ -1,3 +1,9 @@ +"""Module for language model-based robot control. + +This module provides functionality for controlling robots using natural language +commands processed by large language models. +""" + import gc # garbage collect library import os import re @@ -39,15 +45,14 @@ tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME_OR_PATH, use_fast=True) def extract_python_code_blocks(text): - """Extracts Python code blocks from the given text that are enclosed in triple backticks with a python language identifier. + """Extract Python code blocks from the given text. - Parameters - ---------- - - text: A string that may contain one or more Python code blocks. + Args: + text: A string that may contain one or more Python code blocks. - Returns - ------- - - A list of strings, where each string is a block of Python code extracted from the text. + Returns: + list: A list of strings, where each string is a block of Python code + extracted from the text. """ pattern = r"```python\n(.*?)\n```" @@ -63,15 +68,13 @@ def extract_python_code_blocks(text): def remove_last_line(python_code): - """Removes the last line from a given string of Python code. + """Remove the last line from a given string of Python code. - Parameters - ---------- - - python_code: A string representing Python source code. + Args: + python_code: A string representing Python source code. - Returns - ------- - - A string with the last line removed. + Returns: + str: A string with the last line removed. """ lines = python_code.split("\n") # Split the string into lines @@ -82,7 +85,16 @@ def remove_last_line(python_code): def calculate_similarity(source, target): """Calculate a similarity score between the source and target strings. + This uses the edit distance relative to the length of the strings. + + Args: + source: First string to compare + target: Second string to compare + + Returns: + float: Similarity score between 0 and 1 + """ edit_distance = pylcs.edit_distance(source, target) max_length = max(len(source), len(target)) @@ -92,8 +104,17 @@ def calculate_similarity(source, target): def find_best_match_location(source_code, target_block): - """Find the best match for the target_block within the source_code by searching line by line, - considering blocks of varying lengths. + """Find the best match for the target_block within the source_code. + + This function searches line by line, considering blocks of varying lengths. + + Args: + source_code: The source code to search within + target_block: The code block to find a match for + + Returns: + tuple: (start_index, end_index) of the best matching location + """ source_lines = source_code.split("\n") target_lines = target_block.split("\n") @@ -122,7 +143,15 @@ def find_best_match_location(source_code, target_block): def replace_code_in_source(source_code, replacement_block: str): - """Replace the best matching block in the source_code with the replacement_block, considering variable block lengths. + """Replace the best matching block in the source_code with the replacement_block. + + Args: + source_code: The original source code + replacement_block: The new code block to insert + + Returns: + str: The modified source code + """ replacement_block = extract_python_code_blocks(replacement_block)[0] start_index, end_index = find_best_match_location(source_code, replacement_block) @@ -136,7 +165,14 @@ def replace_code_in_source(source_code, replacement_block: str): class Operator: + """A class for managing LLM-based code modifications. + + This class handles the process of using LLMs to modify code based on + natural language instructions and managing the modification workflow. + """ + def __init__(self) -> None: + """Initialize the operator with policy initialization flag.""" self.policy_init = False def on_event( @@ -144,6 +180,16 @@ class Operator: dora_event, send_output, ) -> DoraStatus: + """Handle incoming events and process LLM-based code modifications. + + Args: + dora_event: Dictionary containing event information + send_output: Function to send output to the dataflow + + Returns: + DoraStatus: Status indicating whether to continue processing + + """ global model, tokenizer if dora_event["type"] == "INPUT" and dora_event["id"] == "text": input = dora_event["value"][0].as_py() @@ -177,7 +223,15 @@ class Operator: return DoraStatus.CONTINUE def ask_llm(self, prompt): + """Send a prompt to the LLM and get its response. + + Args: + prompt: The prompt to send to the LLM + + Returns: + str: The LLM's response + """ # Generate output # prompt = PROMPT_TEMPLATE.format(system_message=system_message, prompt=prompt)) input = tokenizer(prompt, return_tensors="pt") diff --git a/examples/aloha/nodes/plot_node.py b/examples/aloha/nodes/plot_node.py index cfb482d9..6cdec52c 100644 --- a/examples/aloha/nodes/plot_node.py +++ b/examples/aloha/nodes/plot_node.py @@ -1,3 +1,5 @@ +"""TODO: Add docstring.""" + import os import cv2 diff --git a/examples/aloha/nodes/policy.py b/examples/aloha/nodes/policy.py index 3825c987..73dc5d88 100644 --- a/examples/aloha/nodes/policy.py +++ b/examples/aloha/nodes/policy.py @@ -1,11 +1,34 @@ +"""Module for implementing robot control policies. + +This module provides functionality for implementing and managing robot control policies, +including action selection and state management. +""" + from dora import DoraStatus class Operator: + """A class for implementing robot control policies. + + This class handles the selection and execution of robot actions based on + input events and current state. + """ + def __init__(self): + """Initialize the operator with available actions.""" self.actions = ["get_food", "get_hat"] def on_event(self, event: dict, send_output) -> DoraStatus: + """Handle incoming events and generate appropriate actions. + + Args: + event: Dictionary containing event information + send_output: Function to send output to the dataflow + + Returns: + DoraStatus: Status indicating whether to continue processing + + """ if event["type"] == "INPUT": id = event["id"] # On initialization diff --git a/examples/aloha/nodes/realsense_node.py b/examples/aloha/nodes/realsense_node.py index 0d8998d8..37e81640 100644 --- a/examples/aloha/nodes/realsense_node.py +++ b/examples/aloha/nodes/realsense_node.py @@ -1,3 +1,9 @@ +"""Module for handling Intel RealSense camera data. + +This module provides functionality for capturing and processing data from +Intel RealSense cameras, including depth and color images. +""" + import os import cv2 diff --git a/examples/aloha/nodes/replay.py b/examples/aloha/nodes/replay.py index 755403e1..98440949 100644 --- a/examples/aloha/nodes/replay.py +++ b/examples/aloha/nodes/replay.py @@ -1,3 +1,5 @@ +"""TODO: Add docstring.""" + import time import pandas as pd diff --git a/examples/aloha/nodes/webcam.py b/examples/aloha/nodes/webcam.py index 219099f5..40f4b463 100644 --- a/examples/aloha/nodes/webcam.py +++ b/examples/aloha/nodes/webcam.py @@ -1,3 +1,9 @@ +"""Module for handling webcam input and processing. + +This module provides functionality for capturing and processing video input +from webcam devices for robot vision applications. +""" + #!/usr/bin/env python3 import os diff --git a/examples/aloha/nodes/whisper_node.py b/examples/aloha/nodes/whisper_node.py index bf3ad1fe..abde9da9 100644 --- a/examples/aloha/nodes/whisper_node.py +++ b/examples/aloha/nodes/whisper_node.py @@ -1,3 +1,9 @@ +"""Module for speech recognition using Whisper. + +This module provides functionality for capturing audio input and converting +it to text using the Whisper speech recognition model. +""" + import numpy as np import pyarrow as pa import sounddevice as sd @@ -14,7 +20,15 @@ node = Node() def get_text(duration) -> str: + """Capture audio and convert it to text using Whisper. + + Args: + duration: Duration of audio to capture in seconds + + Returns: + str: Transcribed text from the audio input + """ ## Microphone audio_data = sd.rec( int(SAMPLE_RATE * duration), diff --git a/examples/aloha/tests/test_realsense.py b/examples/aloha/tests/test_realsense.py index 30ae9d89..9feccb84 100644 --- a/examples/aloha/tests/test_realsense.py +++ b/examples/aloha/tests/test_realsense.py @@ -1,3 +1,5 @@ +"""TODO: Add docstring.""" + import os import cv2 diff --git a/examples/lebai/nodes/interpolation.py b/examples/lebai/nodes/interpolation.py index 06a40302..b1ea05bd 100644 --- a/examples/lebai/nodes/interpolation.py +++ b/examples/lebai/nodes/interpolation.py @@ -1,3 +1,9 @@ +"""Module for interpolating between robot configurations. + +This module provides functionality for creating smooth transitions between +robot configurations and movements. +""" + from enum import Enum import pyarrow as pa diff --git a/examples/lebai/nodes/key_interpolation.py b/examples/lebai/nodes/key_interpolation.py index 1776fa6b..34653baf 100644 --- a/examples/lebai/nodes/key_interpolation.py +++ b/examples/lebai/nodes/key_interpolation.py @@ -1,3 +1,9 @@ +"""Module for interpolating between keyframe positions. + +This module provides functionality for creating smooth transitions between +keyframe positions in robot motion sequences. +""" + import pyarrow as pa from dora import Node diff --git a/examples/lebai/nodes/prompt_interpolation.py b/examples/lebai/nodes/prompt_interpolation.py index f81f6b69..822f3166 100644 --- a/examples/lebai/nodes/prompt_interpolation.py +++ b/examples/lebai/nodes/prompt_interpolation.py @@ -1,3 +1,5 @@ +"""TODO: Add docstring.""" + import pyarrow as pa from dora import Node diff --git a/examples/lebai/nodes/vlm_prompt.py b/examples/lebai/nodes/vlm_prompt.py index 8b137891..14ea498e 100644 --- a/examples/lebai/nodes/vlm_prompt.py +++ b/examples/lebai/nodes/vlm_prompt.py @@ -1 +1,5 @@ +"""Module for handling vision-language model prompts. +This module provides functionality for generating and processing prompts +for vision-language models used in robot control. +""" diff --git a/examples/lebai/nodes/voice_interpolation.py b/examples/lebai/nodes/voice_interpolation.py index 72d5c9c2..b940436a 100644 --- a/examples/lebai/nodes/voice_interpolation.py +++ b/examples/lebai/nodes/voice_interpolation.py @@ -1,3 +1,9 @@ +"""Module for interpolating between voice commands. + +This module provides functionality for processing and interpolating between +voice commands used for robot control. +""" + import pyarrow as pa from dora import Node diff --git a/examples/reachy/nodes/gym_dora_node.py b/examples/reachy/nodes/gym_dora_node.py index c1ce0640..1e7f56e5 100644 --- a/examples/reachy/nodes/gym_dora_node.py +++ b/examples/reachy/nodes/gym_dora_node.py @@ -1,3 +1,5 @@ +"""TODO: Add docstring.""" + import time import gym_dora # noqa: F401 @@ -12,7 +14,20 @@ observation = env.reset() class ReplayPolicy: + """A policy class for replaying recorded robot actions. + + This class handles loading and replaying recorded actions from a dataset, + maintaining timing between actions to match the original recording. + """ + def __init__(self, example_path, epidode=0): + """Initialize the replay policy. + + Args: + example_path: Path to the directory containing recorded actions + epidode: Index of the episode to replay + + """ df_action = pd.read_parquet(example_path / "action.parquet") df_episode_index = pd.read_parquet(example_path / "episode_index.parquet") self.df = pd.merge_asof( @@ -29,6 +44,16 @@ class ReplayPolicy: self.finished = False def select_action(self, obs): + """Select the next action to replay. + + Args: + obs: Current observation from the environment (unused) + + Returns: + tuple: (action, finished) where action is the next action to take + and finished indicates if all actions have been replayed + + """ if self.index < len(self.df): self.index += 1 else: @@ -42,7 +67,19 @@ class ReplayPolicy: class ReplayLeRobotPolicy: + """A policy class for replaying actions from the LeRobot dataset. + + This class handles loading and replaying actions from the LeRobot dataset, + maintaining the sequence of actions from the original recording. + """ + def __init__(self, episode=21): + """Initialize the LeRobot replay policy. + + Args: + episode: Index of the episode to replay from the dataset + + """ self.index = 0 self.finished = False # episode = 1 @@ -53,6 +90,16 @@ class ReplayLeRobotPolicy: self.actions = dataset.hf_dataset["action"][from_index:to_index] def select_action(self, obs): + """Select the next action to replay from the LeRobot dataset. + + Args: + obs: Current observation from the environment (unused) + + Returns: + tuple: (action, finished) where action is the next action to take + and finished indicates if all actions have been replayed + + """ if self.index < len(self.actions): self.index += 1 else: diff --git a/examples/reachy/nodes/keyboard_node.py b/examples/reachy/nodes/keyboard_node.py index 32fee0dc..ebd723f6 100644 --- a/examples/reachy/nodes/keyboard_node.py +++ b/examples/reachy/nodes/keyboard_node.py @@ -1,3 +1,9 @@ +"""Module for handling keyboard input in the Reachy robot control system. + +This module provides functionality for capturing and processing keyboard input +to control the Reachy robot's movements and actions. +""" + import pyarrow as pa from dora import Node from pynput import keyboard diff --git a/examples/reachy/nodes/lerobot_webcam_saver.py b/examples/reachy/nodes/lerobot_webcam_saver.py index 28ba5271..bf17f396 100644 --- a/examples/reachy/nodes/lerobot_webcam_saver.py +++ b/examples/reachy/nodes/lerobot_webcam_saver.py @@ -1,3 +1,5 @@ +"""TODO: Add docstring.""" + #!/usr/bin/env python3 import os diff --git a/examples/reachy/nodes/plot_node.py b/examples/reachy/nodes/plot_node.py index ebc8ebd3..4b759411 100644 --- a/examples/reachy/nodes/plot_node.py +++ b/examples/reachy/nodes/plot_node.py @@ -1,3 +1,9 @@ +"""Module for visualizing robot data and states. + +This module provides functionality for plotting and displaying various aspects +of the robot's state, including positions, movements, and sensor data. +""" + import os import cv2 diff --git a/examples/reachy/nodes/reachy_client.py b/examples/reachy/nodes/reachy_client.py index 4477fa72..cea38412 100644 --- a/examples/reachy/nodes/reachy_client.py +++ b/examples/reachy/nodes/reachy_client.py @@ -1,3 +1,5 @@ +"""TODO: Add docstring.""" + import time # import h5py diff --git a/examples/reachy/nodes/reachy_vision_client.py b/examples/reachy/nodes/reachy_vision_client.py index 1a4cb7d1..b90601fc 100644 --- a/examples/reachy/nodes/reachy_vision_client.py +++ b/examples/reachy/nodes/reachy_vision_client.py @@ -1,3 +1,5 @@ +"""TODO: Add docstring.""" + import time import numpy as np diff --git a/examples/reachy/nodes/replay_node.py b/examples/reachy/nodes/replay_node.py index 4f56b02d..882f1c38 100644 --- a/examples/reachy/nodes/replay_node.py +++ b/examples/reachy/nodes/replay_node.py @@ -1,3 +1,5 @@ +"""TODO: Add docstring.""" + import time import pyarrow as pa diff --git a/examples/reachy1/nodes/gym_dora_node.py b/examples/reachy1/nodes/gym_dora_node.py index c1ce0640..7bad5592 100644 --- a/examples/reachy1/nodes/gym_dora_node.py +++ b/examples/reachy1/nodes/gym_dora_node.py @@ -1,3 +1,5 @@ +"""TODO: Add docstring.""" + import time import gym_dora # noqa: F401 @@ -12,7 +14,10 @@ observation = env.reset() class ReplayPolicy: + """TODO: Add docstring.""" + def __init__(self, example_path, epidode=0): + """TODO: Add docstring.""" df_action = pd.read_parquet(example_path / "action.parquet") df_episode_index = pd.read_parquet(example_path / "episode_index.parquet") self.df = pd.merge_asof( @@ -29,6 +34,7 @@ class ReplayPolicy: self.finished = False def select_action(self, obs): + """TODO: Add docstring.""" if self.index < len(self.df): self.index += 1 else: @@ -42,7 +48,10 @@ class ReplayPolicy: class ReplayLeRobotPolicy: + """TODO: Add docstring.""" + def __init__(self, episode=21): + """TODO: Add docstring.""" self.index = 0 self.finished = False # episode = 1 @@ -53,6 +62,7 @@ class ReplayLeRobotPolicy: self.actions = dataset.hf_dataset["action"][from_index:to_index] def select_action(self, obs): + """TODO: Add docstring.""" if self.index < len(self.actions): self.index += 1 else: diff --git a/examples/reachy1/nodes/key_interpolation.py b/examples/reachy1/nodes/key_interpolation.py index b5107614..b7d050e5 100644 --- a/examples/reachy1/nodes/key_interpolation.py +++ b/examples/reachy1/nodes/key_interpolation.py @@ -1,3 +1,5 @@ +"""TODO: Add docstring.""" + import pyarrow as pa from dora import Node diff --git a/examples/reachy1/nodes/keyboard_node.py b/examples/reachy1/nodes/keyboard_node.py index 32fee0dc..1a134a19 100644 --- a/examples/reachy1/nodes/keyboard_node.py +++ b/examples/reachy1/nodes/keyboard_node.py @@ -1,3 +1,5 @@ +"""TODO: Add docstring.""" + import pyarrow as pa from dora import Node from pynput import keyboard diff --git a/examples/reachy1/nodes/lerobot_webcam_saver.py b/examples/reachy1/nodes/lerobot_webcam_saver.py index 28ba5271..d8ffb79b 100644 --- a/examples/reachy1/nodes/lerobot_webcam_saver.py +++ b/examples/reachy1/nodes/lerobot_webcam_saver.py @@ -1,3 +1,9 @@ +"""Module for saving webcam feed data from LeRobot experiments. + +This module provides functionality for capturing and saving webcam feed data +during LeRobot experiments with the Reachy robot. +""" + #!/usr/bin/env python3 import os diff --git a/examples/reachy1/nodes/plot_node.py b/examples/reachy1/nodes/plot_node.py index ebc8ebd3..6910d6a2 100644 --- a/examples/reachy1/nodes/plot_node.py +++ b/examples/reachy1/nodes/plot_node.py @@ -1,3 +1,9 @@ +"""Module for visualizing robot data and states. + +This module provides functionality for creating real-time visualizations of +robot states, movements, and sensor data during operation. +""" + import os import cv2 diff --git a/examples/reachy1/nodes/reachy_client.py b/examples/reachy1/nodes/reachy_client.py index 4477fa72..ccfbdd7f 100644 --- a/examples/reachy1/nodes/reachy_client.py +++ b/examples/reachy1/nodes/reachy_client.py @@ -1,3 +1,9 @@ +"""Module for client-side communication with the Reachy robot. + +This module provides functionality for establishing and managing communication +with the Reachy robot, including sending commands and receiving sensor data. +""" + import time # import h5py diff --git a/examples/reachy1/nodes/reachy_vision_client.py b/examples/reachy1/nodes/reachy_vision_client.py index 1a4cb7d1..425817f5 100644 --- a/examples/reachy1/nodes/reachy_vision_client.py +++ b/examples/reachy1/nodes/reachy_vision_client.py @@ -1,3 +1,9 @@ +"""Module for handling vision-related communication with the Reachy robot. + +This module provides functionality for processing and managing visual data +from the Reachy robot's cameras and vision sensors. +""" + import time import numpy as np diff --git a/examples/reachy1/nodes/replay_node.py b/examples/reachy1/nodes/replay_node.py index 4f56b02d..80e3ec16 100644 --- a/examples/reachy1/nodes/replay_node.py +++ b/examples/reachy1/nodes/replay_node.py @@ -1,3 +1,9 @@ +"""Module for replaying recorded robot actions and movements. + +This module provides functionality for loading and replaying previously recorded +robot actions and movements, allowing for demonstration and analysis of robot behavior. +""" + import time import pyarrow as pa diff --git a/examples/reachy1/nodes/text_interpolation.py b/examples/reachy1/nodes/text_interpolation.py index 2d9a514b..0618c1b8 100644 --- a/examples/reachy1/nodes/text_interpolation.py +++ b/examples/reachy1/nodes/text_interpolation.py @@ -1,3 +1,9 @@ +"""Module for interpolating between text-based robot commands. + +This module provides functionality for processing and interpolating between +text-based commands to create smooth transitions in robot behavior. +""" + import pyarrow as pa from dora import Node diff --git a/examples/so100/bus.py b/examples/so100/bus.py index 569ca9d2..35495146 100644 --- a/examples/so100/bus.py +++ b/examples/so100/bus.py @@ -1,3 +1,9 @@ +"""Module for managing Feetech servo motor communication. + +This module provides functionality for communicating with and controlling +Feetech servo motors through a serial bus interface. +""" + import enum from typing import Union @@ -23,6 +29,16 @@ def wrap_joints_and_values( joints: Union[list[str], pa.Array], values: Union[list[int], pa.Array], ) -> pa.StructArray: + """Create a structured array from joint names and their values. + + Args: + joints: List of joint names or Arrow array of joint names + values: List of values or Arrow array of values + + Returns: + pa.StructArray: Structured array containing joint names and values + + """ return pa.StructArray.from_arrays( arrays=[joints, values], names=["joints", "values"], @@ -30,11 +46,15 @@ def wrap_joints_and_values( class TorqueMode(enum.Enum): + """Enumeration of torque control modes for servo motors.""" + ENABLED = pa.scalar(1, pa.uint32()) DISABLED = pa.scalar(0, pa.uint32()) class OperatingMode(enum.Enum): + """Enumeration of operating modes for servo motors.""" + ONE_TURN = pa.scalar(0, pa.uint32()) @@ -92,12 +112,21 @@ MODEL_CONTROL_TABLE = { class FeetechBus: + """A class for managing communication with Feetech servo motors. + + This class handles the low-level communication with Feetech servo motors + through a serial bus interface, providing methods for reading and writing + motor parameters. + """ def __init__(self, port: str, description: dict[str, (np.uint8, str)]): - """Args: - port: the serial port to connect to the Feetech bus - description: a dictionary containing the description of the motors connected to the bus. The keys are the - motor names and the values are tuples containing the motor id and the motor model. + """Initialize the Feetech bus interface. + + Args: + port: The serial port to connect to the Feetech bus + description: A dictionary containing the description of the motors + connected to the bus. The keys are the motor names and + the values are tuples containing the motor id and model. """ self.port = port @@ -130,9 +159,17 @@ class FeetechBus: self.group_writers = {} def close(self): + """Close the serial port connection.""" self.port_handler.closePort() def write(self, data_name: str, data: pa.StructArray): + """Write data to the specified motor parameters. + + Args: + data_name: Name of the parameter to write + data: Structured array containing the data to write + + """ motor_ids = [ self.motor_ctrl[motor_name.as_py()]["id"] for motor_name in data.field("joints") @@ -199,6 +236,16 @@ class FeetechBus: ) def read(self, data_name: str, motor_names: pa.Array) -> pa.StructArray: + """Read data from the specified motor parameters. + + Args: + data_name: Name of the parameter to read + motor_names: Array of motor names to read from + + Returns: + pa.StructArray: Structured array containing the read data + + """ motor_ids = [ self.motor_ctrl[motor_name.as_py()]["id"] for motor_name in motor_names ] @@ -249,25 +296,82 @@ class FeetechBus: return wrap_joints_and_values(motor_names, values) def write_torque_enable(self, torque_mode: pa.StructArray): + """Enable or disable torque for the specified motors. + + Args: + torque_mode: Structured array containing torque enable/disable values + + """ self.write("Torque_Enable", torque_mode) def write_operating_mode(self, operating_mode: pa.StructArray): + """Set the operating mode for the specified motors. + + Args: + operating_mode: Structured array containing operating mode values + + """ self.write("Mode", operating_mode) def read_position(self, motor_names: pa.Array) -> pa.StructArray: + """Read current position from the specified motors. + + Args: + motor_names: Array of motor names to read positions from + + Returns: + pa.StructArray: Structured array containing position values + + """ return self.read("Present_Position", motor_names) def read_velocity(self, motor_names: pa.Array) -> pa.StructArray: + """Read current velocity from the specified motors. + + Args: + motor_names: Array of motor names to read velocities from + + Returns: + pa.StructArray: Structured array containing velocity values + + """ return self.read("Present_Velocity", motor_names) def read_current(self, motor_names: pa.Array) -> pa.StructArray: + """Read current current from the specified motors. + + Args: + motor_names: Array of motor names to read currents from + + Returns: + pa.StructArray: Structured array containing current values + + """ return self.read("Present_Current", motor_names) def write_goal_position(self, goal_position: pa.StructArray): + """Set goal positions for the specified motors. + + Args: + goal_position: Structured array containing goal position values + + """ self.write("Goal_Position", goal_position) def write_max_angle_limit(self, max_angle_limit: pa.StructArray): + """Set maximum angle limits for the specified motors. + + Args: + max_angle_limit: Structured array containing maximum angle limit values + + """ self.write("Max_Angle_Limit", max_angle_limit) def write_min_angle_limit(self, min_angle_limit: pa.StructArray): + """Set minimum angle limits for the specified motors. + + Args: + min_angle_limit: Structured array containing minimum angle limit values + + """ self.write("Min_Angle_Limit", min_angle_limit) diff --git a/examples/so100/configure.py b/examples/so100/configure.py index b99848bc..247ade59 100644 --- a/examples/so100/configure.py +++ b/examples/so100/configure.py @@ -1,4 +1,7 @@ -"""SO100 Auto Configure: This program is used to automatically configure the SO-ARM100 (SO100) for the user. +"""Module for configuring and setting up the SO100 robot hardware. + +This module provides functionality for initializing and configuring the SO100 robot's +servo motors and other hardware components. The program will: 1. Disable all torque motors of provided SO100. @@ -55,6 +58,7 @@ def configure_servos(bus: FeetechBus): Args: bus: The FeetechBus instance to configure. + """ bus.write_torque_enable( wrap_joints_and_values(FULL_ARM, [TorqueMode.DISABLED.value] * 6), @@ -74,7 +78,7 @@ def configure_servos(bus: FeetechBus): def main(): - """Main function to run the servo configuration process.""" + """Run the servo configuration process.""" parser = argparse.ArgumentParser( description="SO100 Auto Configure: This program is used to automatically configure the Low Cost Robot (SO100) " "for the user.", diff --git a/examples/so100/nodes/interpolate_lcr_to_so100.py b/examples/so100/nodes/interpolate_lcr_to_so100.py index c200cc7f..635f45fd 100644 --- a/examples/so100/nodes/interpolate_lcr_to_so100.py +++ b/examples/so100/nodes/interpolate_lcr_to_so100.py @@ -1,3 +1,5 @@ +"""TODO: Add docstring.""" + import argparse import json import os @@ -14,7 +16,7 @@ from pwm_position_control.transform import ( def main(): - """Main function to handle interpolation between LCR and SO100 robot configurations.""" + """Handle interpolation between LCR and SO100 robot configurations.""" # Handle dynamic nodes, ask for the name of the node in the dataflow parser = argparse.ArgumentParser( description="Interpolation LCR Node: This Dora node is used to calculates appropriate goal positions for the " diff --git a/examples/so100/nodes/interpolate_lcr_x_so100_to_record.py b/examples/so100/nodes/interpolate_lcr_x_so100_to_record.py index 540c13d8..e6cd0eef 100644 --- a/examples/so100/nodes/interpolate_lcr_x_so100_to_record.py +++ b/examples/so100/nodes/interpolate_lcr_x_so100_to_record.py @@ -1,3 +1,9 @@ +"""Module for recording and interpolating between LCR and SO100 configurations. + +This module provides functionality for recording robot configurations and +interpolating between LCR and SO100 robots to create smooth motion sequences. +""" + import argparse import json import os @@ -13,7 +19,7 @@ from pwm_position_control.transform import ( def main(): - """Main function to handle interpolation and recording between LCR and SO100 robot configurations.""" + """Handle interpolation and recording between LCR and SO100 configurations.""" parser = argparse.ArgumentParser( description="Interpolation LCR Node: This Dora node is used to calculates appropriate goal positions for the " "LCR followers knowing a Leader position and Follower position.", diff --git a/examples/so100/nodes/interpolate_replay_to_so100.py b/examples/so100/nodes/interpolate_replay_to_so100.py index 3621cde5..6fbac6d8 100644 --- a/examples/so100/nodes/interpolate_replay_to_so100.py +++ b/examples/so100/nodes/interpolate_replay_to_so100.py @@ -1,3 +1,9 @@ +"""Module for interpolating between replay and SO100 robot configurations. + +This module provides functionality for interpolating between recorded robot actions +and SO100 robot configurations to create smooth motion sequences. +""" + import argparse import json import os @@ -8,7 +14,7 @@ from pwm_position_control.transform import logical_to_pwm_with_offset_arrow def main(): - """Main function to handle replay interpolation for SO100 robot configurations.""" + """Handle replay interpolation for SO100 robot configurations.""" # Handle dynamic nodes, ask for the name of the node in the dataflow parser = argparse.ArgumentParser( description="Interpolation LCR Node: This Dora node is used to calculates appropriate goal positions for the " diff --git a/tests/llm/run_script.py b/tests/llm/run_script.py index 5b53f710..58217d47 100644 --- a/tests/llm/run_script.py +++ b/tests/llm/run_script.py @@ -1,3 +1,5 @@ +"""TODO: Add docstring.""" + from dora import run # Make sure to build it first with the CLI. From 61f855fdebf149c6ba4be5618f61614ae72e2502 Mon Sep 17 00:00:00 2001 From: 7SOMAY Date: Mon, 17 Mar 2025 22:25:16 +0530 Subject: [PATCH 4/5] Fixed the necessary EOL empty line issue --- node-hub/dora-argotranslate/pyproject.toml | 2 +- node-hub/dora-distil-whisper/pyproject.toml | 2 +- node-hub/dora-echo/pyproject.toml | 2 +- node-hub/dora-internvl/pyproject.toml | 2 +- node-hub/dora-ios-lidar/pyproject.toml | 2 +- node-hub/dora-keyboard/pyproject.toml | 2 +- node-hub/dora-kit-car/pyproject.toml | 2 +- node-hub/dora-kokoro-tts/pyproject.toml | 2 +- node-hub/dora-llama-cpp-python/pyproject.toml | 2 +- node-hub/dora-magma/pyproject.toml | 2 +- node-hub/dora-microphone/pyproject.toml | 2 +- node-hub/dora-object-to-pose/pyproject.toml | 2 +- node-hub/dora-openai-server/pyproject.toml | 2 +- node-hub/dora-opus/pyproject.toml | 2 +- node-hub/dora-outtetts/pyproject.toml | 2 +- node-hub/dora-parler/pyproject.toml | 2 +- node-hub/dora-phi4/pyproject.toml | 2 +- node-hub/dora-piper/pyproject.toml | 2 +- node-hub/dora-pyaudio/pyproject.toml | 2 +- node-hub/dora-pyorbbecksdk/pyproject.toml | 2 +- node-hub/dora-pyrealsense/pyproject.toml | 2 +- node-hub/dora-qwen/pyproject.toml | 2 +- node-hub/dora-qwen2-5-vl/pyproject.toml | 2 +- node-hub/dora-qwenvl/pyproject.toml | 2 +- node-hub/dora-rdt-1b/pyproject.toml | 2 +- node-hub/dora-reachy1/pyproject.toml | 2 +- node-hub/dora-reachy2/pyproject.toml | 2 +- node-hub/dora-rerun/pyproject.toml | 2 +- node-hub/dora-sam2/pyproject.toml | 2 +- node-hub/dora-ugv/pyproject.toml | 2 +- node-hub/dora-vad/pyproject.toml | 2 +- node-hub/dora-yolo/pyproject.toml | 2 +- node-hub/dynamixel-client/pyproject.toml | 2 +- node-hub/feetech-client/pyproject.toml | 2 +- node-hub/lebai-client/pyproject.toml | 2 +- node-hub/lerobot-dashboard/pyproject.toml | 2 +- node-hub/llama-factory-recorder/pyproject.toml | 2 +- node-hub/mujoco-client/pyproject.toml | 2 +- node-hub/opencv-plot/pyproject.toml | 2 +- node-hub/opencv-video-capture/pyproject.toml | 2 +- node-hub/pyarrow-assert/pyproject.toml | 2 +- node-hub/pyarrow-sender/pyproject.toml | 2 +- node-hub/replay-client/pyproject.toml | 2 +- node-hub/terminal-input/pyproject.toml | 2 +- node-hub/video-encoder/pyproject.toml | 2 +- 45 files changed, 45 insertions(+), 45 deletions(-) diff --git a/node-hub/dora-argotranslate/pyproject.toml b/node-hub/dora-argotranslate/pyproject.toml index 47e67a4c..fa1419f9 100644 --- a/node-hub/dora-argotranslate/pyproject.toml +++ b/node-hub/dora-argotranslate/pyproject.toml @@ -24,4 +24,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-distil-whisper/pyproject.toml b/node-hub/dora-distil-whisper/pyproject.toml index 52f7dc0d..ba4c7ea0 100644 --- a/node-hub/dora-distil-whisper/pyproject.toml +++ b/node-hub/dora-distil-whisper/pyproject.toml @@ -32,4 +32,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-echo/pyproject.toml b/node-hub/dora-echo/pyproject.toml index 889924b6..ba3b9ea8 100644 --- a/node-hub/dora-echo/pyproject.toml +++ b/node-hub/dora-echo/pyproject.toml @@ -23,4 +23,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-internvl/pyproject.toml b/node-hub/dora-internvl/pyproject.toml index 4ac96c02..b7ec3082 100644 --- a/node-hub/dora-internvl/pyproject.toml +++ b/node-hub/dora-internvl/pyproject.toml @@ -36,4 +36,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-ios-lidar/pyproject.toml b/node-hub/dora-ios-lidar/pyproject.toml index 8c0065e2..33839a53 100644 --- a/node-hub/dora-ios-lidar/pyproject.toml +++ b/node-hub/dora-ios-lidar/pyproject.toml @@ -20,4 +20,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-keyboard/pyproject.toml b/node-hub/dora-keyboard/pyproject.toml index 36aa3578..99a3c5d1 100644 --- a/node-hub/dora-keyboard/pyproject.toml +++ b/node-hub/dora-keyboard/pyproject.toml @@ -29,4 +29,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-kit-car/pyproject.toml b/node-hub/dora-kit-car/pyproject.toml index 131a2f9d..10b6fc08 100644 --- a/node-hub/dora-kit-car/pyproject.toml +++ b/node-hub/dora-kit-car/pyproject.toml @@ -21,4 +21,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-kokoro-tts/pyproject.toml b/node-hub/dora-kokoro-tts/pyproject.toml index 93cf4b2b..ce8d927b 100644 --- a/node-hub/dora-kokoro-tts/pyproject.toml +++ b/node-hub/dora-kokoro-tts/pyproject.toml @@ -20,4 +20,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-llama-cpp-python/pyproject.toml b/node-hub/dora-llama-cpp-python/pyproject.toml index 95855d43..0a75eeda 100644 --- a/node-hub/dora-llama-cpp-python/pyproject.toml +++ b/node-hub/dora-llama-cpp-python/pyproject.toml @@ -45,4 +45,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-magma/pyproject.toml b/node-hub/dora-magma/pyproject.toml index 76110fb6..2c334b8d 100644 --- a/node-hub/dora-magma/pyproject.toml +++ b/node-hub/dora-magma/pyproject.toml @@ -45,4 +45,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-microphone/pyproject.toml b/node-hub/dora-microphone/pyproject.toml index 0b640b6c..2574ad5b 100644 --- a/node-hub/dora-microphone/pyproject.toml +++ b/node-hub/dora-microphone/pyproject.toml @@ -29,4 +29,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-object-to-pose/pyproject.toml b/node-hub/dora-object-to-pose/pyproject.toml index cd95df14..fb3c820c 100644 --- a/node-hub/dora-object-to-pose/pyproject.toml +++ b/node-hub/dora-object-to-pose/pyproject.toml @@ -20,4 +20,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-openai-server/pyproject.toml b/node-hub/dora-openai-server/pyproject.toml index 3af037d1..f4ea88b3 100644 --- a/node-hub/dora-openai-server/pyproject.toml +++ b/node-hub/dora-openai-server/pyproject.toml @@ -32,4 +32,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-opus/pyproject.toml b/node-hub/dora-opus/pyproject.toml index 3876ac5d..2b74756f 100644 --- a/node-hub/dora-opus/pyproject.toml +++ b/node-hub/dora-opus/pyproject.toml @@ -33,4 +33,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-outtetts/pyproject.toml b/node-hub/dora-outtetts/pyproject.toml index 0263b0ce..341fc417 100644 --- a/node-hub/dora-outtetts/pyproject.toml +++ b/node-hub/dora-outtetts/pyproject.toml @@ -33,4 +33,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-parler/pyproject.toml b/node-hub/dora-parler/pyproject.toml index 050835a4..f5f9a90c 100644 --- a/node-hub/dora-parler/pyproject.toml +++ b/node-hub/dora-parler/pyproject.toml @@ -35,4 +35,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-phi4/pyproject.toml b/node-hub/dora-phi4/pyproject.toml index 049e2794..ac136d5a 100644 --- a/node-hub/dora-phi4/pyproject.toml +++ b/node-hub/dora-phi4/pyproject.toml @@ -36,4 +36,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-piper/pyproject.toml b/node-hub/dora-piper/pyproject.toml index b9996e48..97d998ce 100644 --- a/node-hub/dora-piper/pyproject.toml +++ b/node-hub/dora-piper/pyproject.toml @@ -20,4 +20,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-pyaudio/pyproject.toml b/node-hub/dora-pyaudio/pyproject.toml index c4a238ab..d8d35e42 100644 --- a/node-hub/dora-pyaudio/pyproject.toml +++ b/node-hub/dora-pyaudio/pyproject.toml @@ -25,4 +25,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-pyorbbecksdk/pyproject.toml b/node-hub/dora-pyorbbecksdk/pyproject.toml index ec8d28b1..05512ef1 100644 --- a/node-hub/dora-pyorbbecksdk/pyproject.toml +++ b/node-hub/dora-pyorbbecksdk/pyproject.toml @@ -23,4 +23,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-pyrealsense/pyproject.toml b/node-hub/dora-pyrealsense/pyproject.toml index 7ae0507c..f8c8fba5 100644 --- a/node-hub/dora-pyrealsense/pyproject.toml +++ b/node-hub/dora-pyrealsense/pyproject.toml @@ -26,4 +26,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-qwen/pyproject.toml b/node-hub/dora-qwen/pyproject.toml index a2874765..73f10d85 100644 --- a/node-hub/dora-qwen/pyproject.toml +++ b/node-hub/dora-qwen/pyproject.toml @@ -47,4 +47,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-qwen2-5-vl/pyproject.toml b/node-hub/dora-qwen2-5-vl/pyproject.toml index 3a673f95..30a0e123 100644 --- a/node-hub/dora-qwen2-5-vl/pyproject.toml +++ b/node-hub/dora-qwen2-5-vl/pyproject.toml @@ -53,4 +53,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-qwenvl/pyproject.toml b/node-hub/dora-qwenvl/pyproject.toml index f999af03..d6db0e28 100644 --- a/node-hub/dora-qwenvl/pyproject.toml +++ b/node-hub/dora-qwenvl/pyproject.toml @@ -40,4 +40,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-rdt-1b/pyproject.toml b/node-hub/dora-rdt-1b/pyproject.toml index 68dffd89..a53a01f3 100644 --- a/node-hub/dora-rdt-1b/pyproject.toml +++ b/node-hub/dora-rdt-1b/pyproject.toml @@ -50,4 +50,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-reachy1/pyproject.toml b/node-hub/dora-reachy1/pyproject.toml index 55a13393..955f88f4 100644 --- a/node-hub/dora-reachy1/pyproject.toml +++ b/node-hub/dora-reachy1/pyproject.toml @@ -32,4 +32,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-reachy2/pyproject.toml b/node-hub/dora-reachy2/pyproject.toml index ca3c7156..3b462729 100644 --- a/node-hub/dora-reachy2/pyproject.toml +++ b/node-hub/dora-reachy2/pyproject.toml @@ -29,4 +29,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-rerun/pyproject.toml b/node-hub/dora-rerun/pyproject.toml index 61c7fa6a..5ff60488 100644 --- a/node-hub/dora-rerun/pyproject.toml +++ b/node-hub/dora-rerun/pyproject.toml @@ -24,4 +24,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-sam2/pyproject.toml b/node-hub/dora-sam2/pyproject.toml index 0d85ad96..83ab4638 100644 --- a/node-hub/dora-sam2/pyproject.toml +++ b/node-hub/dora-sam2/pyproject.toml @@ -25,4 +25,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-ugv/pyproject.toml b/node-hub/dora-ugv/pyproject.toml index 26933132..23597905 100644 --- a/node-hub/dora-ugv/pyproject.toml +++ b/node-hub/dora-ugv/pyproject.toml @@ -20,4 +20,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-vad/pyproject.toml b/node-hub/dora-vad/pyproject.toml index a4d91345..6757a6e5 100644 --- a/node-hub/dora-vad/pyproject.toml +++ b/node-hub/dora-vad/pyproject.toml @@ -20,4 +20,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dora-yolo/pyproject.toml b/node-hub/dora-yolo/pyproject.toml index 1cd2399c..722fe6b4 100644 --- a/node-hub/dora-yolo/pyproject.toml +++ b/node-hub/dora-yolo/pyproject.toml @@ -23,4 +23,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/dynamixel-client/pyproject.toml b/node-hub/dynamixel-client/pyproject.toml index 310ebdde..987147bd 100644 --- a/node-hub/dynamixel-client/pyproject.toml +++ b/node-hub/dynamixel-client/pyproject.toml @@ -27,4 +27,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/feetech-client/pyproject.toml b/node-hub/feetech-client/pyproject.toml index 91518d4e..4eac9f73 100644 --- a/node-hub/feetech-client/pyproject.toml +++ b/node-hub/feetech-client/pyproject.toml @@ -28,4 +28,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/lebai-client/pyproject.toml b/node-hub/lebai-client/pyproject.toml index cbd9e8e5..e7eba5a8 100644 --- a/node-hub/lebai-client/pyproject.toml +++ b/node-hub/lebai-client/pyproject.toml @@ -27,4 +27,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/lerobot-dashboard/pyproject.toml b/node-hub/lerobot-dashboard/pyproject.toml index 346bcf8c..9db53e24 100644 --- a/node-hub/lerobot-dashboard/pyproject.toml +++ b/node-hub/lerobot-dashboard/pyproject.toml @@ -29,4 +29,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/llama-factory-recorder/pyproject.toml b/node-hub/llama-factory-recorder/pyproject.toml index ad250d8a..852ea0d7 100644 --- a/node-hub/llama-factory-recorder/pyproject.toml +++ b/node-hub/llama-factory-recorder/pyproject.toml @@ -26,4 +26,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/mujoco-client/pyproject.toml b/node-hub/mujoco-client/pyproject.toml index 47247bb0..a0f6a2fd 100644 --- a/node-hub/mujoco-client/pyproject.toml +++ b/node-hub/mujoco-client/pyproject.toml @@ -28,4 +28,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/opencv-plot/pyproject.toml b/node-hub/opencv-plot/pyproject.toml index 493c2679..762feb4e 100644 --- a/node-hub/opencv-plot/pyproject.toml +++ b/node-hub/opencv-plot/pyproject.toml @@ -22,4 +22,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/opencv-video-capture/pyproject.toml b/node-hub/opencv-video-capture/pyproject.toml index 9266f168..c91dd21d 100644 --- a/node-hub/opencv-video-capture/pyproject.toml +++ b/node-hub/opencv-video-capture/pyproject.toml @@ -23,4 +23,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/pyarrow-assert/pyproject.toml b/node-hub/pyarrow-assert/pyproject.toml index ef5557fa..3de80bbc 100644 --- a/node-hub/pyarrow-assert/pyproject.toml +++ b/node-hub/pyarrow-assert/pyproject.toml @@ -24,4 +24,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/pyarrow-sender/pyproject.toml b/node-hub/pyarrow-sender/pyproject.toml index 6eff7fbe..9b7754f0 100644 --- a/node-hub/pyarrow-sender/pyproject.toml +++ b/node-hub/pyarrow-sender/pyproject.toml @@ -24,4 +24,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/replay-client/pyproject.toml b/node-hub/replay-client/pyproject.toml index 5cf92a1e..8d5ddccb 100644 --- a/node-hub/replay-client/pyproject.toml +++ b/node-hub/replay-client/pyproject.toml @@ -27,4 +27,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/terminal-input/pyproject.toml b/node-hub/terminal-input/pyproject.toml index dfc33165..8ecdb16d 100644 --- a/node-hub/terminal-input/pyproject.toml +++ b/node-hub/terminal-input/pyproject.toml @@ -24,4 +24,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] diff --git a/node-hub/video-encoder/pyproject.toml b/node-hub/video-encoder/pyproject.toml index c92cd694..28a20567 100644 --- a/node-hub/video-encoder/pyproject.toml +++ b/node-hub/video-encoder/pyproject.toml @@ -29,4 +29,4 @@ extend-select = [ "D", # pydocstyle "UP", # Ruff's UP rule "PERF" # Ruff's PERF rule -] \ No newline at end of file +] From f3613f8425162f922ac8f99002143ab075ba6bfa Mon Sep 17 00:00:00 2001 From: "Somay (DIIN)" Date: Tue, 18 Mar 2025 11:10:57 +0530 Subject: [PATCH 5/5] Updated the timeout for CLI-Test from 30 to 45 minutes in ci.yml --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a22afa64..8bfa2b68 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -280,7 +280,7 @@ jobs: run: | cargo install --path binaries/cli --locked - name: "Test CLI (Rust)" - timeout-minutes: 30 + timeout-minutes: 45 # fail-fast by using bash shell explictly shell: bash run: | @@ -312,7 +312,7 @@ jobs: enable-cache: true - name: "Test CLI (Python)" - timeout-minutes: 30 + timeout-minutes: 45 # fail-fast by using bash shell explictly shell: bash run: | @@ -380,7 +380,7 @@ jobs: dora run tests/queue_size_latest_data_rust/dataflow.yaml --uv - name: "Test CLI (C)" - timeout-minutes: 30 + timeout-minutes: 45 # fail-fast by using bash shell explictly shell: bash if: runner.os == 'Linux' @@ -399,7 +399,7 @@ jobs: dora destroy - name: "Test CLI (C++)" - timeout-minutes: 30 + timeout-minutes: 45 # fail-fast by using bash shell explictly shell: bash if: runner.os == 'Linux'