Skip to content

Commit 4b94eef

Browse files
Migrate OVPhysX FrameView + SceneDataBackend pose bindings onto OvPhysxView (view series) (#6233)
> ### 🔗 Stacked on top of #6224 (Part 1 — `OvPhysxView`) > Branched off #6224 as a sibling of the asset/sensor migrations. Targets `develop`; until #6224 merges the diff includes the Part 1 `OvPhysxView` commits. **Please review #6224 first.** # Description Two more `RIGID_BODY_POSE` binding consumers the asset (#6225-6227) and sensor (#6228-6232) passes didn't cover, migrated together in one PR: * **`OvPhysxFrameView`** (`sim/views/ovphysx_frame_view.py`) — the frame view that cameras / `XformPrim` use. Builds one `OvPhysxView` + `try_binding_for(RIGID_BODY_POSE)` (preserving its explicit "matched zero bodies" error, since the view rejects a 0-count binding), and reads via `read_into`. * **`OvPhysxSceneDataBackend`** (`physics/ovphysx_manager.py`) — the scene-data provider. Builds one `OvPhysxView` per distinct rigid-body pattern, stores it on the per-pattern entry, and reads via `read_into`; the per-entry merge into the transform buffer is unchanged. Both are internal refactors — **no public API change** (neither exposes a `root_view`). The `ContactBinding` is unrelated (separate wheel API; see #6232). The scene-data backend's bypass-init unit test hand-seeds the internal entry dict, so it now seeds a matching `view` stub with `read_into`. ## Type of change - [x] Internal refactor (non-breaking) ## Checklist - [x] I have run the `pre-commit` checks with `./isaaclab.sh --format` - [x] Changelog fragment (`.skip` — internal refactor, no bump) ## Testing * `test_views_xform_prim_ovphysx.py` — cpu: **18 passed**, cuda: **18 passed**. * `test_ovphysx_scene_data_backend.py` — **11 passed**.
1 parent ab01ba0 commit 4b94eef

4 files changed

Lines changed: 17 additions & 5 deletions

File tree

source/isaaclab_ovphysx/changelog.d/antoiner-feat-ovphysx_frameview_scenedata.skip

Whitespace-only changes.

source/isaaclab_ovphysx/isaaclab_ovphysx/physics/ovphysx_manager.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ def setup(self, physx, stage, device: str) -> None:
9898
device: Warp device string used to allocate the staging and merged buffers.
9999
"""
100100
from isaaclab_ovphysx import tensor_types as TT # local: keep heavy ovphysx out of module load
101+
from isaaclab_ovphysx.sim.views.ovphysx_view import OvPhysxView
101102

102103
self._physx = physx
103104
self._rigid_bindings = []
@@ -119,7 +120,8 @@ def setup(self, physx, stage, device: str) -> None:
119120
total_count = 0
120121
for pattern in sorted(patterns):
121122
try:
122-
pose_binding = physx.create_tensor_binding(pattern=pattern, tensor_type=TT.RIGID_BODY_POSE)
123+
view = OvPhysxView(physx, pattern=pattern, device=device)
124+
pose_binding = view.binding_for(TT.RIGID_BODY_POSE)
123125
except Exception as exc:
124126
logger.warning("Failed to create RIGID_BODY_POSE binding for %s: %s", pattern, exc)
125127
continue
@@ -141,6 +143,7 @@ def setup(self, physx, stage, device: str) -> None:
141143
self._rigid_bindings.append(
142144
{
143145
"pattern": pattern,
146+
"view": view,
144147
"pose": pose_binding,
145148
"pose_buf": pose_buf,
146149
"pose_buf_transformf": pose_buf_transformf,
@@ -175,7 +178,7 @@ def transforms(self) -> SceneDataFormat.Transform:
175178

176179
for entry in self._rigid_bindings:
177180
try:
178-
entry["pose"].read(entry["pose_buf"])
181+
entry["view"].read_into("rigid_body_pose", entry["pose_buf"])
179182
except Exception as exc:
180183
logger.warning("RIGID_BODY_POSE read failed for %s: %s", entry["pattern"], exc)
181184
continue

source/isaaclab_ovphysx/isaaclab_ovphysx/sim/views/ovphysx_frame_view.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ def _initialize_impl(self, physx: Any) -> None:
357357
``env_0`` replaced by the row's env_id.
358358
"""
359359
from isaaclab_ovphysx import tensor_types as TT # noqa: PLC0415
360+
from isaaclab_ovphysx.sim.views.ovphysx_view import OvPhysxView # noqa: PLC0415
360361

361362
xform_cache = UsdGeom.XformCache(Usd.TimeCode.Default())
362363
identity_xform7 = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]
@@ -406,15 +407,19 @@ def _initialize_impl(self, physx: Any) -> None:
406407
# 4. Create the RIGID_BODY_POSE binding (or operate in world-only mode).
407408
if patterns:
408409
pattern = patterns[0]
409-
self._pose_binding = physx.create_tensor_binding(pattern=pattern, tensor_type=TT.RIGID_BODY_POSE)
410-
if self._pose_binding.shape[0] == 0:
410+
self._root_view = OvPhysxView(physx, pattern=pattern, device=self._device)
411+
# ``try_binding_for`` returns None for a zero-match binding (the view rejects a
412+
# 0-count binding); surface that as the explicit zero-bodies error below.
413+
self._pose_binding = self._root_view.try_binding_for(TT.RIGID_BODY_POSE)
414+
if self._pose_binding is None:
411415
raise RuntimeError(
412416
f"OvPhysxFrameView: RIGID_BODY_POSE binding for pattern {pattern!r} matched zero bodies."
413417
)
414418
self._pose_buf = wp.zeros(self._pose_binding.shape, dtype=wp.float32, device=self._device)
415419
binding_paths: list[str] = list(self._pose_binding.prim_paths)
416420
else:
417421
# All prims resolved as world-attached: no binding needed; kernels only hit the -1 branch.
422+
self._root_view = None
418423
self._pose_binding = None
419424
self._pose_buf = wp.zeros((1, 7), dtype=wp.float32, device=self._device)
420425
binding_paths = []
@@ -613,7 +618,7 @@ def _current_body_q(self) -> wp.array:
613618
buffer ``[num_bodies]``.
614619
"""
615620
if self._pose_binding is not None:
616-
self._pose_binding.read(self._pose_buf)
621+
self._root_view.read_into("rigid_body_pose", self._pose_buf)
617622
return self._pose_buf.view(wp.transformf)
618623

619624
# ------------------------------------------------------------------

source/isaaclab_ovphysx/test/physics/test_ovphysx_scene_data_backend.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ def fake_read_b(dst):
186186
{
187187
"pattern": "/World/envs/env_*/Cube",
188188
"pose": SimpleNamespace(read=fake_read_a, prim_paths=["/Cube0", "/Cube1"]),
189+
"view": SimpleNamespace(read_into=lambda name, dst, _r=fake_read_a: _r(dst)),
189190
"pose_buf": buf_a,
190191
"pose_buf_transformf": buf_a_tf,
191192
"row_offset": 0,
@@ -194,6 +195,7 @@ def fake_read_b(dst):
194195
{
195196
"pattern": "/World/envs/env_*/Pole",
196197
"pose": SimpleNamespace(read=fake_read_b, prim_paths=["/Pole"]),
198+
"view": SimpleNamespace(read_into=lambda name, dst, _r=fake_read_b: _r(dst)),
197199
"pose_buf": buf_b,
198200
"pose_buf_transformf": buf_b_tf,
199201
"row_offset": 2,
@@ -324,6 +326,7 @@ def bad_read(dst):
324326
{
325327
"pattern": "/World/envs/env_*/Good",
326328
"pose": SimpleNamespace(read=good_read, prim_paths=["/Good"]),
329+
"view": SimpleNamespace(read_into=lambda name, dst, _r=good_read: _r(dst)),
327330
"pose_buf": buf_good,
328331
"pose_buf_transformf": buf_good_tf,
329332
"row_offset": 0,
@@ -332,6 +335,7 @@ def bad_read(dst):
332335
{
333336
"pattern": "/World/envs/env_*/Bad",
334337
"pose": SimpleNamespace(read=bad_read, prim_paths=["/Bad"]),
338+
"view": SimpleNamespace(read_into=lambda name, dst, _r=bad_read: _r(dst)),
335339
"pose_buf": buf_bad,
336340
"pose_buf_transformf": buf_bad_tf,
337341
"row_offset": 1,

0 commit comments

Comments
 (0)