Skip to content
Open
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
5 changes: 3 additions & 2 deletions source/isaaclab/isaaclab/devices/device_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import torch
from abc import ABC, abstractmethod
from collections.abc import Callable
from dataclasses import dataclass, field
from dataclasses import dataclass, field, MISSING
from typing import Any

from isaaclab.devices.retargeter_base import RetargeterBase, RetargeterCfg
Expand All @@ -17,7 +17,8 @@
@dataclass
class DeviceCfg:
"""Configuration for teleoperation devices."""

device_type: type["DeviceBase"] = MISSING
teleoperation_active_default: bool = True
sim_device: str = "cpu"
retargeters: list[RetargeterCfg] = field(default_factory=list)

Expand Down
22 changes: 12 additions & 10 deletions source/isaaclab/isaaclab/devices/gamepad/se2_gamepad.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,6 @@
from ..device_base import DeviceBase, DeviceCfg


@dataclass
class Se2GamepadCfg(DeviceCfg):
"""Configuration for SE2 gamepad devices."""

v_x_sensitivity: float = 1.0
v_y_sensitivity: float = 1.0
omega_z_sensitivity: float = 1.0
dead_zone: float = 0.01


class Se2Gamepad(DeviceBase):
r"""A gamepad controller for sending SE(2) commands as velocity commands.
Expand Down Expand Up @@ -54,7 +45,7 @@ class Se2Gamepad(DeviceBase):

def __init__(
self,
cfg: Se2GamepadCfg,
cfg: "Se2GamepadCfg",
):
"""Initialize the gamepad layer.

Expand Down Expand Up @@ -209,3 +200,14 @@ def _resolve_command_buffer(self, raw_command: np.ndarray) -> np.ndarray:
command[command_sign] *= -1

return command


@dataclass
class Se2GamepadCfg(DeviceCfg):
"""Configuration for SE2 gamepad devices."""

device_type: type[Se2Gamepad] = Se2Gamepad
v_x_sensitivity: float = 1.0
v_y_sensitivity: float = 1.0
omega_z_sensitivity: float = 1.0
dead_zone: float = 0.01
22 changes: 12 additions & 10 deletions source/isaaclab/isaaclab/devices/gamepad/se3_gamepad.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,6 @@
from ..device_base import DeviceBase, DeviceCfg


@dataclass
class Se3GamepadCfg(DeviceCfg):
"""Configuration for SE3 gamepad devices."""

dead_zone: float = 0.01 # For gamepad devices
pos_sensitivity: float = 1.0
rot_sensitivity: float = 1.6
retargeters: None = None


class Se3Gamepad(DeviceBase):
"""A gamepad controller for sending SE(3) commands as delta poses and binary command (open/close).
Expand Down Expand Up @@ -61,7 +52,7 @@ class Se3Gamepad(DeviceBase):

def __init__(
self,
cfg: Se3GamepadCfg,
cfg: "Se3GamepadCfg",
):
"""Initialize the gamepad layer.

Expand Down Expand Up @@ -260,3 +251,14 @@ def _resolve_command_buffer(self, raw_command: np.ndarray) -> np.ndarray:
delta_command[delta_command_sign] *= -1

return delta_command


@dataclass
class Se3GamepadCfg(DeviceCfg):
"""Configuration for SE3 gamepad devices."""

device_type: type[Se3Gamepad] = Se3Gamepad
dead_zone: float = 0.01 # For gamepad devices
pos_sensitivity: float = 1.0
rot_sensitivity: float = 1.6
retargeters: None = None
20 changes: 11 additions & 9 deletions source/isaaclab/isaaclab/devices/keyboard/se2_keyboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,6 @@
from ..device_base import DeviceBase, DeviceCfg


@dataclass
class Se2KeyboardCfg(DeviceCfg):
"""Configuration for SE2 keyboard devices."""

v_x_sensitivity: float = 0.8
v_y_sensitivity: float = 0.4
omega_z_sensitivity: float = 1.0


class Se2Keyboard(DeviceBase):
r"""A keyboard controller for sending SE(2) commands as velocity commands.
Expand All @@ -50,7 +42,7 @@ class Se2Keyboard(DeviceBase):

"""

def __init__(self, cfg: Se2KeyboardCfg):
def __init__(self, cfg: "Se2KeyboardCfg"):
"""Initialize the keyboard layer.

Args:
Expand Down Expand Up @@ -178,3 +170,13 @@ def _create_key_bindings(self):
"NUMPAD_9": np.asarray([0.0, 0.0, -1.0]) * self.omega_z_sensitivity,
"X": np.asarray([0.0, 0.0, -1.0]) * self.omega_z_sensitivity,
}


@dataclass
class Se2KeyboardCfg(DeviceCfg):
"""Configuration for SE2 keyboard devices."""

device_type: type[Se2Keyboard] = Se2Keyboard
v_x_sensitivity: float = 0.8
v_y_sensitivity: float = 0.4
omega_z_sensitivity: float = 1.0
20 changes: 11 additions & 9 deletions source/isaaclab/isaaclab/devices/keyboard/se3_keyboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,6 @@
from ..device_base import DeviceBase, DeviceCfg


@dataclass
class Se3KeyboardCfg(DeviceCfg):
"""Configuration for SE3 keyboard devices."""

pos_sensitivity: float = 0.4
rot_sensitivity: float = 0.8
retargeters: None = None


class Se3Keyboard(DeviceBase):
"""A keyboard controller for sending SE(3) commands as delta poses and binary command (open/close).
Expand Down Expand Up @@ -58,7 +50,7 @@ class Se3Keyboard(DeviceBase):

"""

def __init__(self, cfg: Se3KeyboardCfg):
def __init__(self, cfg: "Se3KeyboardCfg"):
"""Initialize the keyboard layer.

Args:
Expand Down Expand Up @@ -202,3 +194,13 @@ def _create_key_bindings(self):
"C": np.asarray([0.0, 0.0, 1.0]) * self.rot_sensitivity,
"V": np.asarray([0.0, 0.0, -1.0]) * self.rot_sensitivity,
}


@dataclass
class Se3KeyboardCfg(DeviceCfg):
"""Configuration for SE3 keyboard devices."""

device_type: type[Se3Keyboard] = Se3Keyboard
pos_sensitivity: float = 0.4
rot_sensitivity: float = 0.8
retargeters: None = None
20 changes: 11 additions & 9 deletions source/isaaclab/isaaclab/devices/openxr/openxr_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from typing import Any

import carb

import isaaclab.devices as devices
from isaaclab.devices.openxr.common import HAND_JOINT_NAMES
from isaaclab.devices.retargeter_base import RetargeterBase

Expand All @@ -29,13 +29,6 @@
from isaacsim.core.prims import SingleXFormPrim


@dataclass
class OpenXRDeviceCfg(DeviceCfg):
"""Configuration for OpenXR devices."""

xr_cfg: XrCfg | None = None


class OpenXRDevice(DeviceBase):
"""An OpenXR-powered device for teleoperation and interaction.

Expand Down Expand Up @@ -78,7 +71,7 @@ class TrackingTarget(Enum):

def __init__(
self,
cfg: OpenXRDeviceCfg,
cfg: "OpenXRDeviceCfg",
retargeters: list[RetargeterBase] | None = None,
):
"""Initialize the OpenXR device.
Expand Down Expand Up @@ -300,3 +293,12 @@ def _on_teleop_command(self, event: carb.events.IEvent):
elif "reset" in msg:
if "RESET" in self._additional_callbacks:
self._additional_callbacks["RESET"]()


@dataclass
class OpenXRDeviceCfg(DeviceCfg):
"""Configuration for OpenXR devices."""

device_type: type[OpenXRDevice] = OpenXRDevice
xr_cfg: XrCfg | None = None
teleoperation_active_default: bool = False
22 changes: 12 additions & 10 deletions source/isaaclab/isaaclab/devices/spacemouse/se2_spacemouse.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,6 @@
from .utils import convert_buffer


@dataclass
class Se2SpaceMouseCfg(DeviceCfg):
"""Configuration for SE2 space mouse devices."""

v_x_sensitivity: float = 0.8
v_y_sensitivity: float = 0.4
omega_z_sensitivity: float = 1.0
sim_device: str = "cpu"


class Se2SpaceMouse(DeviceBase):
r"""A space-mouse controller for sending SE(2) commands as delta poses.
Expand All @@ -48,7 +39,7 @@ class Se2SpaceMouse(DeviceBase):

"""

def __init__(self, cfg: Se2SpaceMouseCfg):
def __init__(self, cfg: "Se2SpaceMouseCfg"):
"""Initialize the spacemouse layer.

Args:
Expand Down Expand Up @@ -168,3 +159,14 @@ def _run_device(self):
# additional callbacks
if "R" in self._additional_callbacks:
self._additional_callbacks["R"]


@dataclass
class Se2SpaceMouseCfg(DeviceCfg):
"""Configuration for SE2 space mouse devices."""

device_type: type[Se2SpaceMouse] = Se2SpaceMouse
v_x_sensitivity: float = 0.8
v_y_sensitivity: float = 0.4
omega_z_sensitivity: float = 1.0
sim_device: str = "cpu"
21 changes: 11 additions & 10 deletions source/isaaclab/isaaclab/devices/spacemouse/se3_spacemouse.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,6 @@
from .utils import convert_buffer


@dataclass
class Se3SpaceMouseCfg(DeviceCfg):
"""Configuration for SE3 space mouse devices."""

pos_sensitivity: float = 0.4
rot_sensitivity: float = 0.8
retargeters: None = None


class Se3SpaceMouse(DeviceBase):
"""A space-mouse controller for sending SE(3) commands as delta poses.

Expand All @@ -49,7 +40,7 @@ class Se3SpaceMouse(DeviceBase):

"""

def __init__(self, cfg: Se3SpaceMouseCfg):
def __init__(self, cfg: "Se3SpaceMouseCfg"):
"""Initialize the space-mouse layer.

Args:
Expand Down Expand Up @@ -191,3 +182,13 @@ def _run_device(self):
self._additional_callbacks["R"]()
if data[1] == 3:
self._read_rotation = not self._read_rotation


@dataclass
class Se3SpaceMouseCfg(DeviceCfg):
"""Configuration for SE3 space mouse devices."""

device_type: type[Se3SpaceMouse] = Se3SpaceMouse
pos_sensitivity: float = 0.4
rot_sensitivity: float = 0.8
retargeters: None = None
29 changes: 8 additions & 21 deletions source/isaaclab/isaaclab/devices/teleop_device_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,6 @@
# May fail if xr is not in use
from isaaclab.devices.openxr import OpenXRDevice, OpenXRDeviceCfg

# Map device types to their constructor and expected config type
DEVICE_MAP: dict[type[DeviceCfg], type[DeviceBase]] = {
Se3KeyboardCfg: Se3Keyboard,
Se3SpaceMouseCfg: Se3SpaceMouse,
Se3GamepadCfg: Se3Gamepad,
Se2KeyboardCfg: Se2Keyboard,
Se2GamepadCfg: Se2Gamepad,
Se2SpaceMouseCfg: Se2SpaceMouse,
OpenXRDeviceCfg: OpenXRDevice,
}


# Map configuration types to their corresponding retargeter classes
RETARGETER_MAP: dict[type[RetargeterCfg], type[RetargeterBase]] = {
Expand All @@ -53,7 +42,7 @@


def create_teleop_device(
device_name: str, devices_cfg: dict[str, DeviceCfg], callbacks: dict[str, Callable] | None = None
env, device_name: str, devices_cfg: dict[str, DeviceCfg], callbacks: dict[str, Callable] | None = None
) -> DeviceBase:
"""Create a teleoperation device based on configuration.

Expand All @@ -76,13 +65,8 @@ def create_teleop_device(
device_cfg = devices_cfg[device_name]
callbacks = callbacks or {}

# Check if device config type is supported
cfg_type = type(device_cfg)
if cfg_type not in DEVICE_MAP:
raise ValueError(f"Unsupported device configuration type: {cfg_type.__name__}")

# Get the constructor for this config type
constructor = DEVICE_MAP[cfg_type]
constructor = device_cfg.device_type

# Try to create retargeters if they are configured
retargeters = []
Expand All @@ -101,10 +85,13 @@ def create_teleop_device(

# Check if the constructor accepts retargeters parameter
constructor_params = inspect.signature(constructor).parameters
params = {}
if "retargeters" in constructor_params and retargeters:
device = constructor(cfg=device_cfg, retargeters=retargeters)
else:
device = constructor(cfg=device_cfg)
params["retargeters"] = retargeters
if "env" in constructor_params:
params["env"] = env

device = constructor(cfg=device_cfg, **params)

# Register callbacks
for key, callback in callbacks.items():
Expand Down