Skip to content

Conversation

@matafela
Copy link
Collaborator

@matafela matafela commented Dec 1, 2025

Description

Support contact fetching for rigid object and articulation link.

  • Rigid object contact fetching, see example: scripts/tutorials/sim/fetch_contact.pyscripts/tutorials/sim/fetch_contact.py
  • Articulation link contact fetching, see example: ``

TODO:

  • Rigid object contact fetching
  • Articulation link contact fetching

Type of change

  • New feature (non-breaking change which adds functionality)

Checklist

  • I have run the black . command to format the code base.
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works
  • Dependencies have been updated, if applicable.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds contact fetching functionality for rigid objects and articulation links in the simulation. The implementation provides a filtering mechanism to retrieve contact information from physics simulations, including contact positions, normals, friction forces, impulses, and distances. The PR includes a new ContactReport data structure, configuration classes for filtering contacts, and methods in SimulationManager to fetch and filter contact data.

  • Adds ContactReport dataclass and ContactFilterCfg configuration for managing contact queries
  • Implements get_contact() method in SimulationManager with GPU and CPU support
  • Provides an example script demonstrating rigid object contact fetching

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 19 comments.

Show a summary per file
File Description
scripts/tutorials/sim/fetch_contact.py New tutorial script demonstrating contact fetching for rigid objects
embodichain/lab/sim/contact.py New ContactReport dataclass to store and filter contact data
embodichain/lab/sim/cfg.py Adds ContactFilterCfg and ArticulationContactFilterCfg configuration classes
embodichain/lab/sim/sim_manager.py Implements get_contact() method and internal contact buffer management
embodichain/lab/sim/objects/rigid_object.py Adds all_env_ids property for accessing environment indices
embodichain/lab/sim/objects/articulation.py Adds all_env_ids property and updates get_user_ids() signature to support link-specific queries
embodichain/lab/sim/objects/gizmo.py Updates import from dexsim.render to dexsim.engine for GizmoController

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +18 to +19
This script demonstrates how to create a simulation scene using SimulationManager.
It shows the basic setup of simulation context, adding objects, and sensors.
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

The docstring is incorrect. This script demonstrates contact fetching, not general scene setup with sensors. Update to accurately describe the script's purpose.

Suggested change
This script demonstrates how to create a simulation scene using SimulationManager.
It shows the basic setup of simulation context, adding objects, and sensors.
This script demonstrates how to fetch and process contact information between rigid objects
in a simulation using SimulationManager. It shows how to set up the simulation, add objects,
and retrieve contact reports for analysis.

Copilot uses AI. Check for mistakes.
contact_positions = contact_report.contact_data[:, 0:3]
contact_normals = contact_report.contact_data[:, 3:6]
contact_frictions = contact_report.contact_data[:, 6:9]
contact_impluses = contact_report.contact_data[:, 9]
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

Corrected spelling of 'impluses' to 'impulses'.

Suggested change
contact_impluses = contact_report.contact_data[:, 9]
contact_impulses = contact_report.contact_data[:, 9]

Copilot uses AI. Check for mistakes.
for link_name in link_names:
if link_name not in all_link_names:
logger.log_warning(
f"Link {link_name} not found in articulation {articulation_cfg.uid}."
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

Incorrect attribute access. Should use articulation_cfg.articulation_uid instead of articulation_cfg.uid, as the field is named articulation_uid in ArticulationContactFilterCfg (line 1141).

Suggested change
f"Link {link_name} not found in articulation {articulation_cfg.uid}."
f"Link {link_name} not found in articulation {articulation_cfg.articulation_uid}."

Copilot uses AI. Check for mistakes.
all_link_names = articulation.link_names()
link_names = (
all_link_names
if articulation_cfg.link_name_list is None
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

The condition checks if link_name_list is None, but the default is an empty list [] (line 1144). This check will never be true. Change condition to if not articulation_cfg.link_name_list or update the default to None.

Suggested change
if articulation_cfg.link_name_list is None
if not articulation_cfg.link_name_list

Copilot uses AI. Check for mistakes.
(self.item_env_ids, articulation.all_env_ids)
)

# build user_id to env_id map
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

Potential runtime error if item_user_ids is empty. Add a check before computing max() to handle the case when no items are found, e.g., if self.item_user_ids.numel() == 0: return.

Suggested change
# build user_id to env_id map
# build user_id to env_id map
if self.item_user_ids.numel() == 0:
return

Copilot uses AI. Check for mistakes.
Comment on lines +168 to +170
contact_user_ids = (
contact_report.contact_user_ids
) # user can use userid to identify which object the contact belongs to, using rigid_object.get_user_id()
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

Variable contact_user_ids is not used.

Suggested change
contact_user_ids = (
contact_report.contact_user_ids
) # user can use userid to identify which object the contact belongs to, using rigid_object.get_user_id()

Copilot uses AI. Check for mistakes.
Comment on lines +171 to +173
contact_env_ids = (
contact_report.contact_env_ids
) # contact belongs to which environment
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

Variable contact_env_ids is not used.

Suggested change
contact_env_ids = (
contact_report.contact_env_ids
) # contact belongs to which environment

Copilot uses AI. Check for mistakes.
cube1 = sim.get_rigid_object("cube1")
filtered_contact_report = contact_report.filter_by_user_ids(
cube1.get_user_ids()
)
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

Variable filtered_contact_report is not used.

Suggested change
)
)
# Example usage: print number of filtered contacts for cube1
n_filtered = filtered_contact_report.contact_data.shape[0]
print(f"[INFO]: Filtered contacts for cube1: {n_filtered}")
if n_filtered > 0:
print(f"[INFO]: Filtered contact positions for cube1: {filtered_contact_report.contact_data[:, 0:3]}")

Copilot uses AI. Check for mistakes.

import argparse
import time
import torch
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

Import of 'torch' is not used.

Suggested change
import torch

Copilot uses AI. Check for mistakes.
PhysicalAttr,
)
from dexsim.render import GizmoController
from dexsim.engine import GizmoController
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

Import of 'GizmoController' is not used.

Suggested change
from dexsim.engine import GizmoController

Copilot uses AI. Check for mistakes.
@matafela matafela changed the title Draft: add contact fetching add contact fetching Dec 4, 2025
@yuecideng yuecideng added physics Things related to physics sensor Virtual sensor for computing observation from simulation labels Dec 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

physics Things related to physics sensor Virtual sensor for computing observation from simulation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants