Implementation:Facebookresearch Habitat lab XRInput
| Knowledge Sources | |
|---|---|
| Domains | Embodied_AI, Human_in_the_Loop |
| Last Updated | 2026-02-15 00:00 GMT |
Overview
XRInput manages the state of an XR (extended reality) input system, including head-mounted display (HMD) origin tracking and dual controller button, trigger, and thumbstick states.
Description
This module provides two classes for XR input management:
- XRController: Represents the state of a single XR controller. It tracks:
- Button states: held, down (just pressed), up (just released), and touched.
- Thumbstick axis values as a two-element list [x, y].
- Hand trigger and index trigger analog values (0.0 to 1.0).
- Whether the controller is currently in the user's hand (_is_controller_in_hand).
- A reset method that clears per-frame events and optionally resets continuous inputs.
- XRInput: Represents the full XR input system with two controllers (left and right), along with HMD origin position and rotation. It provides:
- controllers property: List of both XRController instances.
- left_controller and right_controller properties for direct access.
- origin_position and origin_rotation for HMD tracking data.
- A reset method that delegates to each controller's reset.
Constants NUM_CONTROLLERS (2), HAND_LEFT (0), and HAND_RIGHT (1) define the controller indices.
Usage
Use XRInput when building VR/XR-enabled HITL applications where users interact with the simulation using VR controllers. The input state is populated externally from the XR runtime and queried each frame by the application logic.
Code Reference
Source Location
- Repository: Facebookresearch_Habitat_lab
- File: habitat-hitl/habitat_hitl/core/xr_input.py
- Lines: 1-117
Signature
NUM_CONTROLLERS: Final[int] = 2
HAND_LEFT: Final[int] = 0
HAND_RIGHT: Final[int] = 1
class XRController:
def __init__(self):
...
def get_button(self, button) -> bool:
...
def get_button_down(self, button) -> bool:
...
def get_button_up(self, button) -> bool:
...
def get_button_touched(self, button) -> bool:
...
def get_thumbstick(self) -> list[float]:
...
def get_index_trigger(self) -> float:
...
def get_hand_trigger(self) -> float:
...
def get_is_controller_in_hand(self) -> bool:
...
def reset(self, reset_continuous_input: bool = True):
...
class XRInput:
def __init__(self):
...
@property
def controllers(self) -> list[XRController]:
...
@property
def left_controller(self) -> XRController:
...
@property
def right_controller(self) -> XRController:
...
@property
def origin_position(self) -> list[float]:
...
@property
def origin_rotation(self) -> list[float]:
...
def reset(self, reset_continuous_input: bool = True):
...
Import
from habitat_hitl.core.xr_input import XRInput, XRController, HAND_LEFT, HAND_RIGHT
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| (none) | - | - | Both XRInput and XRController constructors take no parameters. State is populated externally from the XR runtime. |
Outputs
| Name | Type | Description |
|---|---|---|
| get_button(button) | bool | Whether the specified XRButton is currently held. |
| get_button_down(button) | bool | Whether the specified XRButton was pressed this frame. |
| get_button_up(button) | bool | Whether the specified XRButton was released this frame. |
| get_button_touched(button) | bool | Whether the specified XRButton is currently being touched. |
| get_thumbstick() | list[float] | Two-element list [x, y] for the thumbstick axis values. |
| get_index_trigger() | float | Analog value (0.0-1.0) of the index trigger. |
| get_hand_trigger() | float | Analog value (0.0-1.0) of the hand/grip trigger. |
| get_is_controller_in_hand() | bool | Whether the controller is currently detected in the user's hand. |
| origin_position | list[float] | Three-element list [x, y, z] for HMD origin position. |
| origin_rotation | list[float] | Four-element list [x, y, z, w] for HMD origin rotation (quaternion). |
Usage Examples
Basic Usage
from habitat_hitl.core.xr_input import XRInput
from habitat_hitl.core.key_mapping import XRButton
xr_input = XRInput()
# In the frame update loop (state populated by XR runtime):
right = xr_input.right_controller
if right.get_button_down(XRButton.PRIMARY_INDEX_TRIGGER):
print("Right index trigger pressed!")
trigger_value = right.get_index_trigger()
print(f"Right index trigger analog: {trigger_value:.2f}")
thumbstick = right.get_thumbstick()
print(f"Right thumbstick: x={thumbstick[0]:.2f}, y={thumbstick[1]:.2f}")
# HMD tracking
print(f"HMD origin: {xr_input.origin_position}")
# Reset at end of frame
xr_input.reset()