Source code for isaaclab_newton.assets.cable_object.cable_object_data
# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
from __future__ import annotations
import weakref
from typing import TYPE_CHECKING
import warp as wp
from isaaclab.assets.cable_object.base_cable_object_data import BaseCableObjectData
from isaaclab.utils.warp import ProxyArray
from isaaclab_newton.physics import NewtonManager as SimulationManager
if TYPE_CHECKING:
from newton.selection import ArticulationView
[docs]
class CableObjectData(BaseCableObjectData):
"""Data container for a Newton cable object."""
__backend_name__: str = "newton"
"""The name of the backend for the cable object data."""
def __init__(self, root_view: ArticulationView, device: str) -> None:
"""Initialize the cable object data.
Args:
root_view: The cable articulation view.
device: The device used for processing.
"""
super().__init__(device)
self._root_view: ArticulationView = weakref.proxy(root_view)
self._create_simulation_bindings()
self._create_buffers()
self.update(0.0)
self.default_segment_pose_w = ProxyArray(wp.clone(self._segment_pose_w))
self.default_segment_velocity_w = ProxyArray(wp.clone(self._segment_velocity_w))
@property
def segment_pose_w(self) -> ProxyArray:
"""Segment actor-frame poses in the world frame.
Shape is (num_instances, num_segments), dtype ``wp.transformf``. Positions are in [m].
"""
return self._segment_pose_w_ta
@property
def segment_velocity_w(self) -> ProxyArray:
"""Segment COM velocities in the world frame.
Shape is (num_instances, num_segments), dtype ``wp.spatial_vectorf``, with units [m/s, rad/s].
"""
return self._segment_velocity_w_ta
[docs]
def update(self, dt: float) -> None:
"""Update the cable segment state.
Args:
dt: The time step [s].
"""
del dt
wp.copy(self._segment_pose_w[:, 0], self._sim_bind_root_pose_w)
wp.copy(self._segment_velocity_w[:, 0], self._sim_bind_root_velocity_w)
wp.copy(self._segment_pose_w[:, 1:], self._sim_bind_link_pose_w)
wp.copy(self._segment_velocity_w[:, 1:], self._sim_bind_link_velocity_w)
def _create_simulation_bindings(self) -> None:
"""Create bindings to Newton simulation data."""
model = SimulationManager.get_model()
state = SimulationManager.get_state_0()
self._num_instances = self._root_view.count
self._num_segments = self._root_view.link_count + 1
self._sim_bind_root_body_ids = self._root_view.get_attribute("joint_parent", model)[:, 0, 0].contiguous()
self._sim_bind_link_body_ids = self._root_view.get_attribute("joint_child", model)[:, 0].contiguous()
self._sim_bind_root_pose_w = state.body_q[self._sim_bind_root_body_ids]
self._sim_bind_root_velocity_w = state.body_qd[self._sim_bind_root_body_ids]
self._sim_bind_link_pose_w = self._root_view.get_link_transforms(state)[:, 0]
self._sim_bind_link_velocity_w = self._root_view.get_link_velocities(state)[:, 0]
def _create_buffers(self) -> None:
"""Create cable state buffers."""
shape = (self._num_instances, self._num_segments)
self._segment_pose_w = wp.empty(shape, dtype=wp.transformf, device=self.device)
self._segment_velocity_w = wp.empty(shape, dtype=wp.spatial_vectorf, device=self.device)
self._segment_pose_w_ta = ProxyArray(self._segment_pose_w)
self._segment_velocity_w_ta = ProxyArray(self._segment_velocity_w)