diff --git a/README.md b/README.md index dd18f13..805298f 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,9 @@ conda activate piper-teleop ### 3. Clone and Install Meta Quest Teleop Package -Clone the Meta Quest teleoperation repository inside this example directory and install it: +Clone the Meta Quest teleoperation repository and install it: + +**NOTE**: Make sure you're installing it inside the `piper-teleop` conda environment. ```bash git clone https://github.com/NeuracoreAI/meta_quest_teleop.git @@ -73,6 +75,8 @@ AgileX Piper Robot ## Usage +**IMPORTANT NOTE:** Make sure that you have followed the instructions to set up the meta quest (according to [meta_quest_teleop](https://github.com/NeuracoreAI/meta_quest_teleop) README instructions) and that your equipment are functioning before starting the examples. Same applies to the piper robot! + ### 1. Tune Teleoperation Parameters **Script**: `examples/1_tune_teleop_params.py` @@ -241,10 +245,6 @@ example_agilex/ ## Troubleshooting -### Python 3.10 issues - -Python 3.10 has known compatibility issues with some dependencies (e.g. certain versions of NumPy, PyTorch, or other packages). If you run into import errors, version conflicts, or odd runtime behaviour, try using Python 3.11 or 3.12 instead. - ### Import Errors - Ensure conda environment is activated: `conda activate piper-teleop` @@ -255,12 +255,14 @@ Python 3.10 has known compatibility issues with some dependencies (e.g. certain cd meta_quest_teleop pip install -e . cd .. + pip show meta_quest_teleop ``` ### Robot Communication Issues - Verify CAN interface is active: `ip link show can0` - You can activate CAN interface with: `bash scripts/piper/can_activate.sh can0 1000000` +- **NOTE:** you'll most probably need to activate the CAN interface when you first connect your robot to your machine. - Check robot power and CAN bus connection - Ensure robot is in the correct mode for control @@ -268,7 +270,7 @@ Python 3.10 has known compatibility issues with some dependencies (e.g. certain - Verify you're logged in: `neuracore login` - Check network connectivity to Neuracore servers -- Verify dataset/run names are correct +- Verify dataset names/run names/model paths are correct ## Safety Notes diff --git a/environment.yaml b/environment.yaml index 24b8a1c..2fc42d5 100644 --- a/environment.yaml +++ b/environment.yaml @@ -17,6 +17,7 @@ dependencies: - matplotlib - neuracore - neuracore_types + - pyrealsense2 diff --git a/examples/1_tune_teleop_params.py b/examples/1_tune_teleop_params.py index e82a7fb..e9393ed 100644 --- a/examples/1_tune_teleop_params.py +++ b/examples/1_tune_teleop_params.py @@ -20,10 +20,6 @@ # Add parent directory to path to import pink_ik_solver and piper_controller sys.path.insert(0, str(Path(__file__).parent.parent)) -# Add meta_quest_teleop to path -sys.path.insert(0, str(Path(__file__).parent.parent / "meta_quest_teleop")) - - from common.configs import ( CAMERA_FRAME_STREAMING_RATE, CONTROLLER_BETA, diff --git a/examples/2_collect_teleop_data_with_neuracore.py b/examples/2_collect_teleop_data_with_neuracore.py index a70ef29..d8972fb 100644 --- a/examples/2_collect_teleop_data_with_neuracore.py +++ b/examples/2_collect_teleop_data_with_neuracore.py @@ -22,10 +22,6 @@ # Add parent directory to path to import pink_ik_solver and piper_controller sys.path.insert(0, str(Path(__file__).parent.parent)) -# Add meta_quest_teleop to path -sys.path.insert(0, str(Path(__file__).parent.parent / "meta_quest_teleop")) - - from common.configs import ( CAMERA_FRAME_STREAMING_RATE, CONTROLLER_BETA, diff --git a/examples/4_rollout_neuracore_policy.py b/examples/4_rollout_neuracore_policy.py index 3c4b56b..7c83667 100644 --- a/examples/4_rollout_neuracore_policy.py +++ b/examples/4_rollout_neuracore_policy.py @@ -24,9 +24,6 @@ # Add parent directory to path to import pink_ik_solver and piper_controller sys.path.insert(0, str(Path(__file__).parent.parent)) -# Add meta_quest_teleop to path -sys.path.insert(0, str(Path(__file__).parent.parent / "meta_quest_teleop")) - from common.configs import ( CAMERA_FRAME_STREAMING_RATE, CAMERA_LOGGING_NAME, @@ -844,15 +841,12 @@ def update_visualization( ) visualizer.set_go_home_callback(lambda: home_robot(data_manager, robot_controller)) visualizer.set_run_policy_callback( - lambda: ( - run_policy( - data_manager, policy, policy_state, visualizer, model_input_order - ), - None, - )[1] + lambda: run_policy( + data_manager, policy, policy_state, visualizer, model_input_order + ) ) visualizer.set_start_policy_execution_callback( - lambda: (start_policy_execution(data_manager, policy_state), None)[1] + lambda: start_policy_execution(data_manager, policy_state) ) visualizer.set_run_and_start_policy_execution_callback( lambda: run_and_start_policy_execution( diff --git a/examples/common/robot_visualizer.py b/examples/common/robot_visualizer.py index 608d0a0..e8eb548 100644 --- a/examples/common/robot_visualizer.py +++ b/examples/common/robot_visualizer.py @@ -168,7 +168,7 @@ def update_toggle_robot_enabled_status(self, enabled: bool) -> None: ) def set_toggle_robot_enabled_status_callback( - self, callback: Callable[[], None] + self, callback: Callable[[], Any] ) -> None: """Set callback for toggle robot enabled status button. @@ -723,7 +723,7 @@ def get_ghost_robot_visibility(self) -> bool: return self._ghost_robot_urdf.show_visual return False - def set_run_policy_callback(self, callback: Callable[[], None]) -> None: + def set_run_policy_callback(self, callback: Callable[[], Any]) -> None: """Set callback for Run Policy button. Args: @@ -732,7 +732,7 @@ def set_run_policy_callback(self, callback: Callable[[], None]) -> None: if self._run_policy_button is not None: self._run_policy_button.on_click(lambda _: callback()) - def set_start_policy_execution_callback(self, callback: Callable[[], None]) -> None: + def set_start_policy_execution_callback(self, callback: Callable[[], Any]) -> None: """Set callback for Execute Policy button. Args: @@ -742,7 +742,7 @@ def set_start_policy_execution_callback(self, callback: Callable[[], None]) -> N self._start_policy_execution_button.on_click(lambda _: callback()) def set_run_and_start_policy_execution_callback( - self, callback: Callable[[], None] + self, callback: Callable[[], Any] ) -> None: """Set callback for Run and Execute Policy button. @@ -752,7 +752,7 @@ def set_run_and_start_policy_execution_callback( if self._run_and_start_policy_execution_button is not None: self._run_and_start_policy_execution_button.on_click(lambda _: callback()) - def set_play_policy_callback(self, callback: Callable[[], None]) -> None: + def set_play_policy_callback(self, callback: Callable[[], Any]) -> None: """Set callback for Play Policy button. Args: @@ -761,7 +761,7 @@ def set_play_policy_callback(self, callback: Callable[[], None]) -> None: if self._play_policy_button is not None: self._play_policy_button.on_click(lambda _: callback()) - def set_execution_mode_callback(self, callback: Callable[[], None]) -> None: + def set_execution_mode_callback(self, callback: Callable[[], Any]) -> None: """Set callback for execution mode dropdown. Args: @@ -770,7 +770,7 @@ def set_execution_mode_callback(self, callback: Callable[[], None]) -> None: if self._execution_mode_dropdown is not None: self._execution_mode_dropdown.on_update(lambda _: callback()) - def set_enable_robot_callback(self, callback: Callable[[], None]) -> None: + def set_enable_robot_callback(self, callback: Callable[[], Any]) -> None: """Set callback for Enable Robot button. Args: @@ -779,7 +779,7 @@ def set_enable_robot_callback(self, callback: Callable[[], None]) -> None: if self._enable_robot_handle is not None: self._enable_robot_handle.on_click(lambda _: callback()) - def set_disable_robot_callback(self, callback: Callable[[], None]) -> None: + def set_disable_robot_callback(self, callback: Callable[[], Any]) -> None: """Set callback for Disable Robot button. Args: @@ -788,7 +788,7 @@ def set_disable_robot_callback(self, callback: Callable[[], None]) -> None: if self._disable_robot_handle is not None: self._disable_robot_handle.on_click(lambda _: callback()) - def set_emergency_stop_callback(self, callback: Callable[[], None]) -> None: + def set_emergency_stop_callback(self, callback: Callable[[], Any]) -> None: """Set callback for Emergency Stop button. Args: @@ -797,7 +797,7 @@ def set_emergency_stop_callback(self, callback: Callable[[], None]) -> None: if self._emergency_stop_handle is not None: self._emergency_stop_handle.on_click(lambda _: callback()) - def set_go_home_callback(self, callback: Callable[[], None]) -> None: + def set_go_home_callback(self, callback: Callable[[], Any]) -> None: """Set callback for Go Home button. Args: diff --git a/examples/common/threads/quest_reader.py b/examples/common/threads/quest_reader.py index f4f830c..abd4502 100644 --- a/examples/common/threads/quest_reader.py +++ b/examples/common/threads/quest_reader.py @@ -1,12 +1,8 @@ """Quest reader thread - reads controller data and manages teleop state.""" -import sys import time import traceback -from pathlib import Path -# Add meta_quest_teleop to path -sys.path.insert(0, str(Path(__file__).parent.parent / "meta_quest_teleop")) from common.configs import CONTROLLER_DATA_RATE, GRIP_THRESHOLD from common.data_manager import DataManager, RobotActivityState from meta_quest_teleop.reader import MetaQuestReader diff --git a/scripts/oculus/monitor_hand_movement.py b/scripts/oculus/monitor_hand_movement.py index 7ad90fe..9a5416f 100755 --- a/scripts/oculus/monitor_hand_movement.py +++ b/scripts/oculus/monitor_hand_movement.py @@ -1,17 +1,12 @@ #!/usr/bin/env python3 """Monitor Meta Quest right hand controller movement and display flags for significant changes.""" -import sys import time from collections import deque -from pathlib import Path import numpy as np -from scipy.spatial.transform import Rotation - -sys.path.insert(0, str(Path(__file__).parent.parent.parent / "meta_quest_teleop")) - from meta_quest_teleop.reader import MetaQuestReader +from scipy.spatial.transform import Rotation class MovementMonitor: