Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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`
Expand Down Expand Up @@ -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`
Expand All @@ -255,20 +255,22 @@ 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

### Neuracore Connection Issues

- 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

Expand Down
1 change: 1 addition & 0 deletions environment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ dependencies:
- matplotlib
- neuracore
- neuracore_types
- pyrealsense2



4 changes: 0 additions & 4 deletions examples/1_tune_teleop_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 0 additions & 4 deletions examples/2_collect_teleop_data_with_neuracore.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
14 changes: 4 additions & 10 deletions examples/4_rollout_neuracore_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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(
Expand Down
20 changes: 10 additions & 10 deletions examples/common/robot_visualizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -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:
Expand All @@ -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:
Expand All @@ -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.

Expand All @@ -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:
Expand All @@ -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:
Expand All @@ -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:
Expand All @@ -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:
Expand All @@ -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:
Expand All @@ -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:
Expand Down
4 changes: 0 additions & 4 deletions examples/common/threads/quest_reader.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down
7 changes: 1 addition & 6 deletions scripts/oculus/monitor_hand_movement.py
Original file line number Diff line number Diff line change
@@ -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:
Expand Down