Skip to content

Commit f495912

Browse files
Align OVPhysX ContactSensor parity with PhysX/Newton
Three small parity fixes that came out of a code review against the PhysX/Newton implementations: * Rename ``update_net_forces_kernel`` to ``update_net_forces_ovphysx_kernel``. PhysX ships a kernel of the same name with a different signature (env-major vs sensor-major index order); the explicit suffix prevents a confusing compile error if someone cross-imports. * ``ContactSensor.body_names`` now returns ``list[str]`` (never ``None``) and raises a clear ``RuntimeError`` if accessed before initialization, matching the PhysX contract. * Add ``_set_debug_vis_impl`` and a no-op ``_debug_vis_callback`` to the OVPhysX ContactSensor. The kitless OVPhysX flow has no Kit renderer, so the implementations log a one-shot warning and otherwise no-op, but the hooks are wired so ``cfg.debug_vis=True`` surfaces an explicit message instead of silently doing nothing.
1 parent 2578b48 commit f495912

2 files changed

Lines changed: 47 additions & 5 deletions

File tree

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

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from __future__ import annotations
1010

1111
import contextlib
12+
import logging
1213
import re
1314
from collections.abc import Sequence
1415
from typing import TYPE_CHECKING, Any
@@ -28,12 +29,14 @@
2829
reset_contact_sensor_kernel,
2930
split_flat_pose_to_pos_quat,
3031
unpack_contact_buffer_data, # noqa: F401 -- reserved for v2 contact-points support
31-
update_net_forces_kernel,
32+
update_net_forces_ovphysx_kernel,
3233
)
3334

3435
if TYPE_CHECKING:
3536
from .contact_sensor_cfg import ContactSensorCfg
3637

38+
logger = logging.getLogger(__name__)
39+
3740

3841
class ContactSensor(BaseContactSensor):
3942
"""An ovphysx contact reporting sensor.
@@ -131,9 +134,19 @@ def num_sensors(self) -> int:
131134
return self._num_sensors
132135

133136
@property
134-
def body_names(self) -> list[str] | None:
137+
def body_names(self) -> list[str]:
138+
"""The leaf-prim names of the sensor bodies.
139+
140+
Raises:
141+
RuntimeError: If accessed before the sensor has been initialized
142+
(matches the eager non-``None`` contract PhysX provides).
143+
"""
135144
if not self._body_names:
136-
return None
145+
raise RuntimeError(
146+
"OvPhysxContactSensor.body_names accessed before initialization. "
147+
"Step the simulation once (or wait for PhysicsEvent.PHYSICS_READY) so the "
148+
"sensor can discover its bodies."
149+
)
137150
return list(self._body_names)
138151

139152
@property
@@ -330,7 +343,7 @@ def _update_buffers_impl(self, env_mask: wp.array | None = None) -> None:
330343
force_matrix_flat = None
331344

332345
wp.launch(
333-
update_net_forces_kernel,
346+
update_net_forces_ovphysx_kernel,
334347
dim=(self._num_envs, self._num_sensors),
335348
inputs=[
336349
net_forces_flat,
@@ -453,6 +466,35 @@ def compute_first_air(self, dt: float, abs_tol: float = 1.0e-8) -> ProxyArray:
453466
)
454467
return self._data._first_transition_ta
455468

469+
"""
470+
Debug visualization
471+
"""
472+
473+
def _set_debug_vis_impl(self, debug_vis: bool) -> None:
474+
"""Toggle contact-marker visibility.
475+
476+
The kitless OVPhysX flow has no Kit-based renderer, so visualization
477+
markers are effectively invisible. The hook is still wired so that
478+
callers setting ``cfg.debug_vis=True`` get an explicit warning rather
479+
than silent no-op behaviour.
480+
"""
481+
if debug_vis and not getattr(self, "_warned_debug_vis_unavailable", False):
482+
logger.warning(
483+
"OVPhysX ContactSensor: debug visualization markers are not rendered under the "
484+
"kitless OVPhysX flow (no Kit renderer present). The hook runs but marker "
485+
"geometry will not appear."
486+
)
487+
self._warned_debug_vis_unavailable = True
488+
489+
def _debug_vis_callback(self, event) -> None:
490+
"""Per-frame visualization update.
491+
492+
Under kitless OVPhysX this is a no-op -- there is no renderer driving
493+
the per-frame marker positions. The method exists so the base
494+
sensor's debug-vis lifecycle hooks have a callable target.
495+
"""
496+
return
497+
456498
"""
457499
Internal simulation callbacks.
458500
"""

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ def compute_first_transition_kernel(
187187

188188

189189
@wp.kernel
190-
def update_net_forces_kernel(
190+
def update_net_forces_ovphysx_kernel(
191191
# in
192192
net_forces_flat: wp.array(dtype=wp.vec3f),
193193
net_forces_matrix_flat: wp.array2d(dtype=wp.vec3f),

0 commit comments

Comments
 (0)