Skip to content

[FEATURE] Add support of link filtering to contact sensors. - #2772

Merged
duburcqa merged 3 commits into
Genesis-Embodied-AI:mainfrom
jsw7460:feature/contact-force-filter-link-idx
Jul 21, 2026
Merged

[FEATURE] Add support of link filtering to contact sensors.#2772
duburcqa merged 3 commits into
Genesis-Embodied-AI:mainfrom
jsw7460:feature/contact-force-filter-link-idx

Conversation

@jsw7460

@jsw7460 jsw7460 commented May 12, 2026

Copy link
Copy Markdown
Contributor

ContactForceSensor now accepts filter_link_idx, mirroring ContactSensor: contacts with the sensor link whose other participant is one of the listed links are excluded from the reported force. The filter is applied on both ground-truth-update paths; the vectorized zerocopy path and the _kernel_get_contacts_forces kernel.
Adds test_contact_force_sensor_filter_link_idx.

Description

ContactForceSensor now accepts filter_link_idx (default ()), mirroring
ContactSensor from #2655: contacts with the sensor link whose other
participant is one of the listed links are excluded from the reported force.

- `_kernel_get_contacts_forces` (the kernel fallback): takes
  `filter_links_idx` and skips a contact for a sensor when the counterpart
  is in that sensor's filter list;
- `filtered_sensor_idx` gates the comparison so sensors without a filter
  keep the cheap path (same optimisation as `ContactSensor`).

Related Issue

Resolves #2771

Motivation and Context

ContactSensor already filters its boolean by counterpart link, but ContactForceSensor only reported the total contact force on the link, with no way to scope it (e.g. "force on a foot from the ground, excluding self-contact").

How Has This Been / Can This Be Tested?

  pytest tests/test_sensors.py::test_contact_force_sensor_filter_link_idx tests/test_sensors.py::test_contact_sensor_filter_link_idx

test_contact_force_sensor_filter_link_idx puts a box on the floor (env 0) / a box on the floor with another box stacked on top (env 1), with two ContactForce sensors on the bottom box — one plain, one with filter_link_idx (floor.link_start,). It asserts the filtered sensor reads ~0 in env 0 and reads only the top box's downward push in env 1, while the unfiltered sensor reads the net contact force in both.

Checklist:

  • I read the CONTRIBUTING document.
  • I followed the Submitting Code Changes section of CONTRIBUTING document.
  • I tagged the title correctly (including BUG FIX/FEATURE/MISC/BREAKING)
  • I updated the documentation accordingly or no change is needed.
  • [ x] I tested my changes and added instructions on how to test it for reviewers.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

@Milotrince

Copy link
Copy Markdown
Member

This feature has already been implemented by #2655 .

@jsw7460

jsw7460 commented May 12, 2026

Copy link
Copy Markdown
Contributor Author

@Milotrince
Hi, thank you for #2655 !
But #2655 added filter_link_idx only to gs.sensors.Contact (the boolean contact sensor), not to gs.sensors.ContactForce (the force-vector sensor).

What I'm after here is a ContactForce sensor that sums only the force from contacts with a given subset of links — e.g. "force on a foot from the ground, excluding self-contact" — which
isn't possible today since ContactForce reports the total contact force on the link.

@Milotrince
Milotrince force-pushed the feature/contact-force-filter-link-idx branch from d42940d to 6f1b2ea Compare July 8, 2026 00:26
@Milotrince Milotrince changed the title [FEATURE] Add filter_link_idx to ContactForceSensor. [FEATURE] Add filter_link_idx to contact sensors. Jul 8, 2026
@Milotrince

Copy link
Copy Markdown
Member

I rebased your branch and updated to extend the filtering to ContactDepthProbe and KinematicTaxel as well as ContactProbe!

@Milotrince
Milotrince force-pushed the feature/contact-force-filter-link-idx branch from 6f1b2ea to 1358dea Compare July 8, 2026 01:29
@Milotrince Milotrince added the ready for review First pass review complete and ready for final review and merge. label Jul 8, 2026
Milotrince
Milotrince previously approved these changes Jul 8, 2026
@Milotrince
Milotrince force-pushed the feature/contact-force-filter-link-idx branch 2 times, most recently from 82e30bd to 37e6118 Compare July 11, 2026 00:06
@github-actions

Copy link
Copy Markdown

⚠️ Abnormal Benchmark Result Detected ➡️ Report

@Milotrince
Milotrince force-pushed the feature/contact-force-filter-link-idx branch 2 times, most recently from 645ea78 to d8a6312 Compare July 14, 2026 21:19
Comment thread genesis/utils/misc.py Outdated
Comment thread genesis/options/sensors/options.py Outdated
Comment thread genesis/options/sensors/options.py Outdated
@Milotrince Milotrince removed the ready for review First pass review complete and ready for final review and merge. label Jul 17, 2026
@duburcqa
duburcqa force-pushed the feature/contact-force-filter-link-idx branch 2 times, most recently from c634870 to ce4e11d Compare July 21, 2026 12:27
@duburcqa

Copy link
Copy Markdown
Collaborator

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ce4e11ddf8

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread genesis/engine/sensors/kinematic_tactile.py Outdated
@duburcqa
duburcqa force-pushed the feature/contact-force-filter-link-idx branch from ce4e11d to 7cc560a Compare July 21, 2026 13:43
duburcqa
duburcqa previously approved these changes Jul 21, 2026
@duburcqa

Copy link
Copy Markdown
Collaborator

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: 7cc560ab9c

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

ContactForceSensor now accepts filter_link_idx, mirroring ContactSensor:
contacts with the sensor link whose other participant is one of the
listed links are excluded from the reported force. The filter is applied
on both ground-truth-update paths -- the vectorized zerocopy path (same
4D contact-vs-filter broadcast as ContactSensor, applied to the per-side
contact masks before they are aggregated) and the
_kernel_get_contacts_forces kernel (a small per-contact loop over the
sensor's filter list). As in ContactSensor, filtered_sensor_idx gates
the more expensive comparison so sensors without a filter keep the cheap
path. Covers this in test_contact_sensor_filter_link_idx alongside the Contact sensor.
ContactProbe, ContactDepthProbe, and KinematicTaxel now accept
filter_link_idx, mirroring the Contact/ContactForce semantics: a contact
with the sensor link is dropped when its counterpart link is in the
filter list. The three share the counterpart check via a
_func_link_is_filtered device helper threaded into both contact-depth
query funcs and their kernels, and a FilterableTactileProbeSensorOptionsMixin
so the point-cloud tactile sensors (Elastomer/Proximity), which sample a
point cloud rather than solver contacts, do not expose the option.

Consolidate the existing contact-force filtering while here:
- the kernel now uses the shared _func_link_is_filtered helper instead of
  open-coding the per-contact filter flags;
- the zerocopy filter masking (identical in Contact and ContactForce) is
  factored into _drop_filtered_counterpart_contacts;
- the build-time padding is factored into misc.append_filter_links_idx
  (used by all five sensors) and the range validation into
  options._validate_filter_link_idx.

The filter table keeps at least one column so the no-filter case is still
a valid kernel argument. Covers this in test_kinematic_contact_probe_box_sphere_support.
@duburcqa
duburcqa force-pushed the feature/contact-force-filter-link-idx branch from 7cc560a to 2107e29 Compare July 21, 2026 14:04
…aycast path.

Builds on the two preceding contributor commits and addresses the review feedback:

- Replace the free _validate_filter_link_idx and the separate
  FilterableTactileProbeSensorOptionsMixin with a single ContactFilterOptionsMixin
  shared by Contact, ContactForce, and the solver-contact tactile probes, so the
  generic sensor options no longer reference links.
- Replace misc.append_filter_links_idx with a shared ContactFilterMetadataMixin
  that owns the per-sensor filter table and its fast-path index.
- Apply the tactile counterpart filter where each sensor's per-(env, sensor)
  contact/geom list is built (_kernel_build_sensor_geom_idx for SDF,
  _kernel_build_sensor_contact_idx for raycast) -- before the per-sensor contact
  cap, so both contact-depth backends honor it and a large filtered manifold
  cannot starve an allowed contact, leaving the per-probe hot kernels untouched.
- Re-home the tests into tests/sensors/ and add regression coverage, including
  the prefilter-cap starvation case.
@duburcqa
duburcqa force-pushed the feature/contact-force-filter-link-idx branch from 2107e29 to ec68096 Compare July 21, 2026 14:32
@duburcqa duburcqa changed the title [FEATURE] Add filter_link_idx to contact sensors. [FEATURE] Add support of link filtering to contact sensors. Jul 21, 2026
@duburcqa
duburcqa merged commit 6855e47 into Genesis-Embodied-AI:main Jul 21, 2026
4 checks passed
jsw7460 added a commit to jsw7460/Genesis that referenced this pull request Jul 23, 2026
…sis-Embodied-AI#2772)

Genesis upstream added first-class link filtering to the contact
sensors (ContactFilterOptionsMixin.filter_link_idx on Contact,
ContactForce, and the tactile probes), superseding the local
ContactForceSensor filter patch this fork carried. Drop the local
patch and take the upstream implementation wholesale: contact_force.py
and options.py now match upstream exactly, so the fork no longer
diverges and future pulls stop conflicting. The filter_link_idx option
name and semantics are unchanged, so downstream callers keep working.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Add filter_link_idx to ContactForceSensor

3 participants