-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Adds contact point location reporting to ContactSensor #2842
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds contact point location reporting to ContactSensor #2842
Conversation
Hi! Thanks so much for implementing this feature. I really appreciate the effort! I had previously attempted a first version in #2026 and ran into similar performance issues. I was curious: have you tested this implementation in simulation with more than 1000 environments? I'd be interested to know how it impacts simulation time, and whether the reported forces per point remain accurate at that scale. |
@virgilio96upm
|
Signed-off-by: James Tigue <166445701+jtigue-bdai@users.noreply.github.com>
Thank you @ooctipus for helping vectorize the operations. This should be good to review. |
Just review, LGTM! Thank you James for bringing this great feature. |
Signed-off-by: Kelly Guo <kellyg@nvidia.com>
Update: After multiple attempts, this issue was resolved by increasing maxContactDataCount to 2000. I've tried implementing the changes from PR #2842 with Isaac Sim 5.0.0 and Isaac Lab 2.2.0, and encountered issues in my contact-rich environment. Specifically, the runtime error involves contact data handling and CUDA assertions: contact data points exceed the predefined buffer limit, leading to PyTorch index out-of-bounds errors on the GPU, and ultimately a CUDA device-side assertion failure. Error Logs
|
Thanks for trying out, |
Instead of doing some prechecks, I might be more inclined to think this is a problematic implementation. The code: rel = torch.arange(max_count, device=counts.device).unsqueeze(0).expand(counts.size(0), max_count)
pts = buffer_contact_points[buffer_start_indices.view(-1).unsqueeze(1) + rel] In this code, if the result of We know Perhaps the original implementation here attempted to accelerate via parallel processing, but it actually caused errors. However, if we adopt the correct implementation below, I'm concerned that it may not be as efficient as the current version. (Refer to NVIDIA's official RigidContactView example): import omni.physics.tensors as tensors
sim_view = tensors.create_simulation_view("warp")
rigid_contact_view = sim_view.create_rigid_contact_view("/World/Cube_*") # This assumes that the prims referenced by "/World/Cube_*" were already created in the stage
forces, points, normals, distances, counts, start_indices = rigid_contact_view.get_contact_data(dt) # Get the detailed contact data between sensors and filter prims per patch
forces_np = forces.numpy().reshape(rigid_contact_view.max_contact_data_count) # Reshape the obtained array in a 1D numpy array on the host
points_np = points.numpy().reshape(rigid_contact_view.max_contact_data_count * 3) # Reshape the obtained array in a 1D numpy array on the host
normals_np = normals.numpy().reshape(rigid_contact_view.max_contact_data_count * 3) # Reshape the obtained array in a 1D numpy array on the host
distances_np = distances.numpy().reshape(rigid_contact_view.max_contact_data_count) # Reshape the obtained array in a 1D numpy array on the host
counts_np = counts.numpy().reshape(rigid_contact_view.sensor_count, rigid_contact_view.filter_count) # Reshape the obtained array in a 2D numpy array on the host
start_indices_np = start_indices.numpy().reshape(rigid_contact_view.sensor_count, rigid_contact_view.filter_count) # Reshape the obtained array in a 2D numpy array on the host
start_indices_ij = start_indices_np[i, j]
count_ij = counts_np[i, j]
if count_ij > 0:
forces_ij = forces_np[start_indices_ij:start_indices_ij + count_ij] * normals_np[start_indices_ij:start_indices_ij + count_ij]
force_aggregate = numpy.sum(forces_ij, axis=0) |
@zhexulong good catch — the bug was doing advanced indexing before masking via max_count, which can produce OOB when a row’s count < max_count (especially for the last block). I switched to build a flat index of only valid contacts, then aggregating on device. This keeps it safe and still O(total_valid_contacts) with no host hops.
This code block is passing the tests, could you please try if it works for you as well? If it does, we can replace the original implementation with this new one. |
@ooctipus But even if For me, the actual issue with the previous error should be that the contact count[-1] (the fifth return value of
However, I'm not sure if Isaac Lab has a responsibility to provide additional prompts to users of this feature beyond this warning, informing them that if your maxContactDataCount is too small, the contact data you obtain will be incomplete and the contact_pos_w you get may be inaccurate. If necessary, perhaps a pre-check is also necessary? You can refer to the definition of the data structure returned by
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Thank you @jtigue-bdai
Signed-off-by: ooctipus <zhengyuz@nvidia.com>
Signed-off-by: James Tigue <166445701+jtigue-bdai@users.noreply.github.com>
# Description This PR: - Adds ContactSensorCfg.track_contact_points to toggle tracking of contact point locations between sensor bodies and filtered bodies. - Adds ContactSensorCfg.max_contact_data_per_prim to configure the maximum amount of contacts per sensor body. - Adds ContactSensorData.contact_pos_w data field for tracking contact point locations. Fixes # (issue) <!-- As a practice, it is recommended to open an issue to have discussions on the proposed pull request. This makes it easier for the community to keep track of what is being developed or added, and if a given feature is demanded by more than one party. --> ## Type of change <!-- As you go through the list, delete the ones that are not applicable. --> - New feature (non-breaking change which adds functionality) ## Checklist - [ ] I have run the [`pre-commit` checks](https://pre-commit.com/) with `./isaaclab.sh --format` - [ ] 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 updated the changelog and the corresponding version in the extension's `config/extension.toml` file - [ ] I have added my name to the `CONTRIBUTORS.md` or my name already exists there --------- Signed-off-by: James Tigue <166445701+jtigue-bdai@users.noreply.github.com> Signed-off-by: Kelly Guo <kellyg@nvidia.com> Signed-off-by: ooctipus <zhengyuz@nvidia.com> Co-authored-by: Ashwin Khadke <133695616+akhadke-bdai@users.noreply.github.com> Co-authored-by: Kelly Guo <kellyg@nvidia.com> Co-authored-by: ooctipus <zhengyuz@nvidia.com>
Description
This PR:
Fixes # (issue)
Type of change
Checklist
pre-commit
checks with./isaaclab.sh --format
config/extension.toml
fileCONTRIBUTORS.md
or my name already exists there