Source code for uwlab.devices.realsense_t265
# Copyright (c) 2024-2025, The UW Lab Project Developers.
# All Rights Reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
from __future__ import annotations
import torch
from enum import IntEnum
from typing import TYPE_CHECKING
from isaaclab.devices import DeviceBase
from isaaclab.utils.math import compute_pose_error
from uwlab.utils.math import create_axis_remap_function
if TYPE_CHECKING:
from .device_cfg import RealsenseT265Cfg
class Preset(IntEnum):
Custom = 0
Default = 1
Hand = 2
HighAccuracy = 3
HighDensity = 4
MediumDensity = 5
[docs]class RealsenseT265(DeviceBase):
[docs] def __init__(
self,
cfg: RealsenseT265Cfg,
device="cuda:0",
):
import pyrealsense2 as rs
self.cam_device_id = cfg.cam_device_id
self.device = device
self._additional_callbacks = dict()
self.pipeline = rs.pipeline() # type: ignore
self.config = rs.config() # type: ignore
self.ctx = rs.context() # type: ignore
self.t265_pipeline = rs.pipeline(self.ctx) # type: ignore
self.t265_config = rs.config() # type: ignore
self.t265_config.enable_device(self.cam_device_id)
self.t265_config.enable_stream(rs.stream.pose) # type: ignore
self.init_pose = torch.tensor([[0.0, 0.0, 0.0, 0.0, 0.0, 0.0]], device=device)
self.current_pose = self.init_pose.clone()
self.t265_pipeline.start(self.t265_config)
self.axis_remap_fn = create_axis_remap_function(forward="z", left="-x", up="y", device=self.device)
self.quat_error = None
def reset(self):
self.current_pose = self.init_pose.clone()
t265_frames = self.t265_pipeline.wait_for_frames()
pose_frame = t265_frames.get_pose_frame()
pose_data = pose_frame.get_pose_data()
self.initial_quat = torch.tensor(
[[pose_data.rotation.w, pose_data.rotation.x, pose_data.rotation.y, pose_data.rotation.z]],
device=self.device,
)
self.initial_pos = torch.tensor(
[[pose_data.translation.x, pose_data.translation.y, pose_data.translation.z]], device=self.device
)
def add_callback(self, key, func):
# camera does not have any callbacks
pass
[docs] def advance(self):
"""
Advance the device state, read the device translational and rotational data,
then transform them xyz rpy that makes intuitive sense in Isaac Sim world coordinates.
"""
t265_frames = self.t265_pipeline.wait_for_frames()
pose_frame = t265_frames.get_pose_frame()
pose_data = pose_frame.get_pose_data()
curr_quat = torch.tensor(
[[pose_data.rotation.w, pose_data.rotation.x, pose_data.rotation.y, pose_data.rotation.z]],
device=self.device,
)
curr_pos = torch.tensor(
[[pose_data.translation.x, pose_data.translation.y, pose_data.translation.z]], device=self.device
)
del_xyz, del_rpy = compute_pose_error(
curr_pos, curr_quat, self.initial_pos, self.initial_quat, rot_error_type="axis_angle"
)
del_xyz, del_rpy = self.axis_remap_fn(del_xyz, del_rpy)
self.current_pose[:, :3] = del_xyz
self.current_pose[:, 3:] = del_rpy
return self.current_pose