Skip to content

Homogenize contact sensor force semantics - #7382

Merged
ooctipus merged 8 commits into
isaac-sim:developfrom
yufengsjtu:feature/homogenize-contact-sensor-forces
Sep 4, 2026
Merged

Homogenize contact sensor force semantics#7382
ooctipus merged 8 commits into
isaac-sim:developfrom
yufengsjtu:feature/homogenize-contact-sensor-forces

Conversation

@yufengsjtu

@yufengsjtu yufengsjtu commented Aug 27, 2026

Copy link
Copy Markdown

Description

This PR clarifies and homogenizes the normal and friction contact-force contracts across the PhysX, Newton, and OVPhysX backends.

Summary

  • Unified the physical meaning of the same contact sensor data net_forces_w under different backends
  • Introduced explicit normal-force property names:
    • net_normal_forces_w
    • net_normal_forces_w_history
    • normal_force_matrix_w
    • normal_force_matrix_w_history
  • Renamed filtered friction forces to friction_force_matrix_w.
  • Added net_friction_forces_w for aggregate friction forces.
  • Retained the previous property names as deprecated aliases for migration.
  • Documented the total contact-force relationship:
    total_force = net_normal_forces_w + net_friction_forces_w.
  • Updated affected callers, tests, benchmarks, tutorials, and documentation.

Backend behavior

  • Newton now exposes aggregate and filtered friction forces. Normal forces are obtained by subtracting friction from Newton's total contact forces.
  • PhysX continues to expose filtered friction through get_friction_data. Aggregate friction is unavailable, so net_friction_forces_w raises NotImplementedError.
  • OVPhysX adopts the renamed normal-force API while retaining its existing unsupported friction behavior.

Visualization

Added force-vector visualization using separate markers for normal and friction forces:

  • Newton displays both aggregate normal and friction vectors.
  • PhysX displays aggregate normal-force vectors.
  • Arrow direction and length represent the world-frame force direction and magnitude.

Motivation

The previous contact sensor data had inconsistent physical semantics across backends. In particular, PhysX reported normal contact forces through net_forces_w, while Newton reported total contact forces, including both normal and friction components, through the same property.

Consequently, identical API usage could represent different physical quantities depending on the selected backend. The previous names also made it unclear whether a force was normal, frictional, total, aggregate, or filtered.

This PR establishes an explicit cross-backend contract and retains deprecated aliases to provide a migration path.

Type of change

  • New feature
  • Breaking change
  • Documentation update

Release backport

  • Backport this pull request to the active release branch after it merges into develop

Screenshots

PhysX normal-force visualization

image

Newton normal- and friction-force visualization

image

Validation

  • Added tests for Newton normal/friction force decomposition.
  • Added tests for deprecated force-property aliases.
  • Added tests for contact-force vector visualization.
  • Manually verified visualization with PhysX and Newton MJWarp.
  • Built the updated contact sensor documentation.

Checklist

  • I have read and understood the contribution guidelines
  • I have run the pre-commit checks with uv run isaaclab -f
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • I have added a changelog fragment under source/<pkg>/changelog.d/ for every touched package
  • I have added my name to CONTRIBUTORS.md or my name already exists there

Clarify normal and friction force contracts across backends, expose Newton friction data, and retain deprecated aliases for migration. Add force-vector visualization and update affected documentation, tests, and callers.
@yufengsjtu
yufengsjtu requested a review from a team August 27, 2026 10:02
@github-actions github-actions Bot added documentation Improvements or additions to documentation enhancement New feature or request isaac-lab Related to Isaac Lab team labels Aug 27, 2026
@greptile-apps

greptile-apps Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR makes contact-force semantics explicit and consistent across the shared, Newton, PhysX, and OVPhysX contact-sensor APIs.

  • Adds distinct aggregate and filtered normal/friction properties while retaining deprecated aliases.
  • Decomposes Newton total force into normal and friction components and updates relevant histories, tests, tasks, documentation, and benchmarks.
  • Adds normal- and friction-force vector visualization, with aggregate friction remaining unsupported by PhysX and OVPhysX.

Confidence Score: 4/5

The PR appears safe to merge, with a non-blocking Newton debug-visualization issue that can briefly display stale friction arrows after reset.

The force decomposition and cross-backend API migration are internally consistent, but Newton friction visualization bypasses the reset-aware sensor buffer and can render pre-reset contact values until the next step.

Files Needing Attention: source/isaaclab_newton/isaaclab_newton/sensors/contact_sensor/contact_sensor.py

Important Files Changed

Filename Overview
source/isaaclab_newton/isaaclab_newton/sensors/contact_sensor/contact_sensor.py Adds Newton force decomposition and vector visualization; friction visualization can briefly expose stale raw contact data after reset.
source/isaaclab_newton/isaaclab_newton/sensors/contact_sensor/contact_sensor_kernels.py Correctly separates Newton total and friction forces and preserves reset, history, environment-mask, and post-reset freshness handling.
source/isaaclab/isaaclab/sensors/contact_sensor/base_contact_sensor_data.py Defines explicit aggregate and filtered normal/friction contracts and warning-backed compatibility aliases.
source/isaaclab_physx/isaaclab_physx/sensors/contact_sensor/contact_sensor.py Renames normal-force buffers and adds aggregate normal-force visualization while preserving PhysX's filtered-friction limitation.
source/isaaclab_ov/isaaclab_ov/sensors/contact_sensor/contact_sensor.py Migrates OVPhysX contact buffers and kernels to the new normal-force names without changing unsupported friction behavior.
source/isaaclab/isaaclab/sensors/contact_sensor/visualization.py Introduces shared thresholded world-frame force-arrow construction and marker rendering.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  P[Backend contact data] --> N{Backend}
  N -->|Newton total + friction| D[Decompose total]
  D --> NN[net_normal_forces_w]
  D --> NF[net_friction_forces_w]
  N -->|PhysX / OVPhysX normal| NN
  N -->|Filtered contacts| NM[normal_force_matrix_w]
  N -->|Supported filtered friction| FM[friction_force_matrix_w]
  NN --> C[Tasks, rewards, and visualization]
  NF --> C
  NM --> C
  FM --> C
Loading

Reviews (1): Last reviewed commit: "Homogenize contact sensor force semantic..." | Re-trigger Greptile

Comment thread source/isaaclab_newton/isaaclab_newton/sensors/contact_sensor/contact_sensor.py Outdated

@isaaclab-review-bot isaaclab-review-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isaac Lab Review Bot

The contact-force API is consistently renamed and decomposed across the shared contract and all three backends, with deprecated aliases and migrated consumers. Two concrete issues remain in the new force-vector visualization: inconsistent arrow-length axes and Newton friction rendering that bypasses reset-aware owned buffers.

  • Design and architecture: The normal/friction split is propagated through the shared data interface, backend containers, Warp kernels, reset paths, documentation, and consumers. The shared visualizer is an appropriate cross-backend abstraction, but Newton should feed it through the same owned sensor buffers used by the public API rather than a raw backend view.
  • API: The canonical normal and friction names are documented, existing names remain warning-backed aliases, and backend limitations such as unsupported PhysX aggregate friction are explicit. Migration documentation and in-repository consumers have been updated consistently.
  • Implementation: The visualization computes dynamic length on scale axis 0 but derives its prototype length from axis 2, producing an incorrect tail offset. Newton friction visualization also reads the raw backend friction view, bypassing timestamp stale-data protection, reset zeroing, and the track_friction_forces buffer contract. Use the matching length axis and render from net_friction_forces_w when available.

Minor fixes needed. Posted 2 actionable findings inline.

Automated review; human maintainers own approval decisions.


self._visualizer = VisualizationMarkers(cfg)
self._force_scale = force_scale
self._prototype_length = marker_scale[2]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Warning · Implementation — Arrow length read from wrong scale axis

visualize() encodes the force magnitude into scales[:, 0], so index 0 is the arrow's length axis, but _prototype_length is taken from marker_scale[2]. displayed_lengths therefore mixes the Z extent with the X scale factor, and with the configured (0.04, 0.04, 0.2) arrow the tail offset is five times the drawn length, detaching arrows from the contact position. Read the prototype length from the same axis that is scaled.

Comment thread source/isaaclab_newton/isaaclab_newton/sensors/contact_sensor/contact_sensor.py Outdated
Comment thread uv.lock
Comment thread source/isaaclab_physx/test/sensors/test_contact_sensor.py Outdated
@kellyguo11 kellyguo11 moved this to In progress in Isaac Lab Sep 1, 2026
@kellyguo11

Copy link
Copy Markdown
Contributor

run-ci

@isaaclab-bot isaaclab-bot Bot added ci:run-docker Trigger the on-demand Docker and GPU CI workflow and removed ci:run-docker Trigger the on-demand Docker and GPU CI workflow labels Sep 1, 2026
@ooctipus

ooctipus commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

@yufengsjtu lets not deprecate net_force_w, we can alias it to normal force for physx and give a one time warning that net_force_w is normal force instead

yufengsjtu and others added 5 commits September 3, 2026 11:39
…ations

Keep net_forces_w as total force and friction_forces_w as aggregate friction.
Newton reports those quantities directly; PhysX and OVPhysX fall back to
normal or filtered-friction data and warn. Add friction history buffers.
@kellyguo11

Copy link
Copy Markdown
Contributor

run-ci

@isaaclab-bot isaaclab-bot Bot added ci:run-docker Trigger the on-demand Docker and GPU CI workflow and removed ci:run-docker Trigger the on-demand Docker and GPU CI workflow labels Sep 3, 2026
@ooctipus
ooctipus merged commit 5ea0a27 into isaac-sim:develop Sep 4, 2026
80 of 82 checks passed
@github-project-automation github-project-automation Bot moved this from In progress to Done in Isaac Lab Sep 4, 2026
@isaaclab-bot

isaaclab-bot Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Backported to release/3.0.0 as 8dd94cb.

isaaclab-bot Bot pushed a commit that referenced this pull request Sep 4, 2026
# Description

This PR clarifies and homogenizes the normal and friction contact-force
contracts across the PhysX, Newton, and OVPhysX backends.

## Summary
- Unified the physical meaning of the same contact sensor data
`net_forces_w` under different backends
- Introduced explicit normal-force property names:
  - `net_normal_forces_w`
  - `net_normal_forces_w_history`
  - `normal_force_matrix_w`
  - `normal_force_matrix_w_history`
- Renamed filtered friction forces to `friction_force_matrix_w`.
- Added `net_friction_forces_w` for aggregate friction forces.
- Retained the previous property names as deprecated aliases for
migration.
- Documented the total contact-force relationship:
  `total_force = net_normal_forces_w + net_friction_forces_w`.
- Updated affected callers, tests, benchmarks, tutorials, and
documentation.

## Backend behavior

- Newton now exposes aggregate and filtered friction forces. Normal
forces are obtained by subtracting friction from Newton's total contact
forces.
- PhysX continues to expose filtered friction through
`get_friction_data`. Aggregate friction is unavailable, so
`net_friction_forces_w` raises `NotImplementedError`.
- OVPhysX adopts the renamed normal-force API while retaining its
existing unsupported friction behavior.

## Visualization

Added force-vector visualization using separate markers for normal and
friction forces:

- Newton displays both aggregate normal and friction vectors.
- PhysX displays aggregate normal-force vectors.
- Arrow direction and length represent the world-frame force direction
and magnitude.

## Motivation

The previous contact sensor data had inconsistent physical semantics
across backends. In particular, PhysX reported normal contact forces
through `net_forces_w`, while Newton reported total contact forces,
including both normal and friction components, through the same
property.

Consequently, identical API usage could represent different physical
quantities depending on the selected backend. The previous names also
made it unclear whether a force was normal, frictional, total,
aggregate, or filtered.

This PR establishes an explicit cross-backend contract and retains
deprecated aliases to provide a migration path.

## Type of change

- New feature
- Breaking change
- Documentation update

## Release backport

- [x] <!-- backport-active-release --> Backport this pull request to the
active release branch after it merges into `develop`

## Screenshots

### PhysX normal-force visualization
<img width="836" height="545" alt="image"
src="https://github.com/user-attachments/assets/77cb3e1f-73ca-4e22-9143-5c008743521c"
/>

### Newton normal- and friction-force visualization
<img width="729" height="573" alt="image"
src="https://github.com/user-attachments/assets/7ce48ff5-8826-4285-b283-92d98f7cfae3"
/>


## Validation

- Added tests for Newton normal/friction force decomposition.
- Added tests for deprecated force-property aliases.
- Added tests for contact-force vector visualization.
- Manually verified visualization with PhysX and Newton MJWarp.
- Built the updated contact sensor documentation.

## Checklist

- [x] I have read and understood the [contribution
guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html)
- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`uv run isaaclab -f`
- [x] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] I have added a changelog fragment under
`source/<pkg>/changelog.d/` for every touched package
- [ ] I have added my name to `CONTRIBUTORS.md` or my name already
exists there

(cherry picked from commit 5ea0a27)
@ooctipus
ooctipus deleted the feature/homogenize-contact-sensor-forces branch September 4, 2026 04:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request isaac-lab Related to Isaac Lab team

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants