Skip to content

Commit ab01ba0

Browse files
Migrate OVPhysX contact-sensor pose binding onto OvPhysxView (view series, part 5) (#6232)
> ### 🔗 Stacked on top of #6224 (Part 1 — `OvPhysxView`) > Branched off #6224 as a sibling of the other migrations. Targets `develop`; until #6224 merges the diff includes the Part 1 `OvPhysxView` commits. **Please review #6224 first.** # Description Part 5 of the OVPhysX view-migration series — the **contact sensor**. This is the *partial* one: only the `RIGID_BODY_POSE` pose binding (the `track_pose` path) is a `TensorBinding` the view can manage, so only it is migrated. The **`ContactBinding`** (net forces via `read_net_forces`, force matrix via `read_force_matrix`) is a separate ovphysx wheel API that `OvPhysxView` does not wrap — it is left exactly as-is. * `_initialize_impl` builds an `OvPhysxView` for the pose binding (when `track_pose`) and obtains it via `binding_for(TT.RIGID_BODY_POSE)`; the count-mismatch check and the `pose_binding` accessor are unchanged. * The per-step pose read goes through `read_into(TT.RIGID_BODY_POSE, ...)` (cached reinterpret). * The `ContactBinding` create/read/destroy paths are untouched. * Internal refactor; no public API change. ## Type of change - [x] Internal refactor (non-breaking) ## Checklist - [x] I have run the `pre-commit` checks with `./isaaclab.sh --format` - [x] My changes generate no new warnings - [x] Changelog fragment (`.skip` — internal refactor, no bump) ## Testing `test_contact_sensor.py` — cpu: **9 passed, 4 skipped**; cuda: **9 passed, 4 skipped** (exercises both the ContactBinding force path and the migrated pose-tracking path).
1 parent cb1fa8f commit ab01ba0

2 files changed

Lines changed: 10 additions & 5 deletions

File tree

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

Whitespace-only changes.

source/isaaclab_ovphysx/isaaclab_ovphysx/sensors/contact_sensor/contact_sensor.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import isaaclab_ovphysx.tensor_types as TT
2424
from isaaclab_ovphysx.physics import OvPhysxManager
25+
from isaaclab_ovphysx.sim.views.ovphysx_view import OvPhysxView
2526

2627
from .contact_sensor_data import ContactSensorData
2728
from .kernels import (
@@ -92,6 +93,9 @@ def __init__(self, cfg: ContactSensorCfg):
9293
self._physx_instance: Any = None
9394
self._contact_binding: Any = None
9495
self._pose_binding: Any = None
96+
# The pose binding (track_pose only) is managed by an OvPhysxView; the ContactBinding
97+
# is a separate wheel API the view does not wrap.
98+
self._root_view: OvPhysxView | None = None
9599
# Pre-allocated read buffers, populated in _create_buffers.
96100
self._net_forces_flat_buf: wp.array | None = None
97101
self._force_matrix_flat_buf: wp.array | None = None
@@ -281,10 +285,8 @@ def has_contact_report(prim) -> bool:
281285
"per body."
282286
)
283287
single_pose_pattern = f"{base_glob}/{body_names[0]}"
284-
self._pose_binding = physx_instance.create_tensor_binding(
285-
pattern=single_pose_pattern,
286-
tensor_type=TT.RIGID_BODY_POSE,
287-
)
288+
self._root_view = OvPhysxView(physx_instance, pattern=single_pose_pattern, device=self._device)
289+
self._pose_binding = self._root_view.binding_for(TT.RIGID_BODY_POSE)
288290
if self._pose_binding.count != self._contact_binding.sensor_count:
289291
raise RuntimeError(
290292
"RIGID_BODY_POSE binding count mismatch."
@@ -378,7 +380,7 @@ def _update_buffers_impl(self, env_mask: wp.array | None = None) -> None:
378380

379381
if self.cfg.track_pose:
380382
# Read pose into [num_envs * num_sensors, 7] float32 -> view as transformf.
381-
self._pose_binding.read(self._poses_flat_buf)
383+
self._root_view.read_into(TT.RIGID_BODY_POSE, self._poses_flat_buf)
382384
poses_flat = self._poses_flat_buf.view(wp.transformf)
383385
wp.launch(
384386
split_flat_pose_to_pos_quat,
@@ -518,4 +520,7 @@ def _invalidate_initialize_callback(self, event) -> None:
518520
with contextlib.suppress(Exception):
519521
self._pose_binding.destroy()
520522
self._pose_binding = None
523+
# Drop the view too: it caches the same (now-destroyed) pose binding, so leaving it set
524+
# would keep a destroyed handle reachable. _initialize_impl rebuilds a fresh view on play.
525+
self._root_view = None
521526
self._physx_instance = None

0 commit comments

Comments
 (0)