Skip to content

Conversation

iche033
Copy link
Contributor

@iche033 iche033 commented Jul 3, 2024

🦟 Bug fix

Summary

Contact point optimization for convex decomposed mesh collisions in bullet-featherstone plugin. This PR reduces the number of contact points generated for convex decomposed mesh collision by using a single contact manifold.

Previously when a mesh collision is decomposed into multiple convex hull shape, each convex hull shape has a corresponding contact manifold which can generate up to 4 contact points (4 is the default limit in bullet). This slows down sim especially when querying contact points (via GetContactsFromLastStep). This PR overrides the btCollisionDispatcher class in order to update the contact manifolds stored in bullet. It post processes the contact points, generates a single contact manifold for each collision associated with convex hull shapes, and clears the exiting contact manifolds.

Note: it would be more efficient if we can do this inside bullet to avoid generating all the contact manifolds in the first place.

Before: many points can be generated from one convex decomposed mesh collision.
bullet_mesh_contacts

After: limit contact points to <= 4
bullet_mesh_contacts_single_manifold

Here're remotery graphs showing before and after the fix for a scene with multiple convex decomposed meshes. Note objects were auto-deactivated when these graphs were captured.

Before: >200 contact points
bullet_deactivated_profile_cropped

After: 20 contact points
bullet_deactivated_with_fix_profile_cropped

Notable speedups are:

  • PhysicsPrivate::Step: 0.153ms -> 0.097ms
  • PhysicsPrivate::UpdateCollision: 0.528ms -> 0.135ms

Checklist

  • Signed all commits for DCO
  • Added tests
  • Updated documentation (as needed)
  • Updated migration guide (as needed)
  • Consider updating Python bindings (if the library has them)
  • codecheck passed (See contributing)
  • All tests passed (See test coverage)
  • While waiting for a review on your PR, please help review another open pull request to support the maintainers

Note to maintainers: Remember to use Squash-Merge and edit the commit message to match the pull request summary while retaining Signed-off-by messages.

iche033 added 2 commits July 3, 2024 02:10
Signed-off-by: Ian Chen <ichen@openrobotics.org>
Signed-off-by: Ian Chen <ichen@openrobotics.org>
@iche033 iche033 requested review from azeey, mxgrey and scpeters as code owners July 3, 2024 02:28
@github-actions github-actions bot added the 🎵 harmonic Gazebo Harmonic label Jul 3, 2024
iche033 added 7 commits July 3, 2024 02:36
Signed-off-by: Ian Chen <ichen@openrobotics.org>
Signed-off-by: Ian Chen <ichen@openrobotics.org>
…collision in get contacts from last step

Signed-off-by: Ian Chen <ichen@openrobotics.org>
Signed-off-by: Ian Chen <ichen@openrobotics.org>
Signed-off-by: Ian Chen <ichen@openrobotics.org>
@azeey
Copy link
Contributor

azeey commented Jul 10, 2024

Looks like there are several test failures in windows and I don't see any in the stable branch (https://build.osrfoundation.org/view/gz-harmonic/job/gz_physics-7-win/)

iche033 added 2 commits July 10, 2024 16:54
Signed-off-by: Ian Chen <ichen@openrobotics.org>
Signed-off-by: Ian Chen <ichen@openrobotics.org>
iche033 added 2 commits July 11, 2024 03:23
Signed-off-by: Ian Chen <ichen@openrobotics.org>
Signed-off-by: Ian Chen <ichen@openrobotics.org>
@iche033 iche033 marked this pull request as draft July 11, 2024 05:26
iche033 added 10 commits July 11, 2024 16:45
Signed-off-by: Ian Chen <ichen@openrobotics.org>
Signed-off-by: Ian Chen <ichen@openrobotics.org>
Signed-off-by: Ian Chen <ichen@openrobotics.org>
Signed-off-by: Ian Chen <ichen@openrobotics.org>
Signed-off-by: Ian Chen <ichen@openrobotics.org>
Signed-off-by: Ian Chen <ichen@openrobotics.org>
Signed-off-by: Ian Chen <ichen@openrobotics.org>
Signed-off-by: Ian Chen <ichen@openrobotics.org>
Signed-off-by: Ian Chen <ichen@openrobotics.org>
Signed-off-by: Ian Chen <ichen@openrobotics.org>
iche033 added 5 commits July 16, 2024 16:47
Signed-off-by: Ian Chen <ichen@openrobotics.org>
Signed-off-by: Ian Chen <ichen@openrobotics.org>
Signed-off-by: Ian Chen <ichen@openrobotics.org>
Signed-off-by: Ian Chen <ichen@openrobotics.org>
Signed-off-by: Ian Chen <ichen@openrobotics.org>
@iche033 iche033 marked this pull request as ready for review July 17, 2024 02:22
@iche033
Copy link
Contributor Author

iche033 commented Jul 17, 2024

Looks like there are several test failures in windows and I don't see any in the stable branch (https://build.osrfoundation.org/view/gz-harmonic/job/gz_physics-7-win/)

Fixed and this PR is ready for review again. The test failures were due to RTTI access violation when doing a dynamic_cast from btCollisionShape to btCompoundShape. I saw a similar issue reported in dartsim and fixed by adding pragmas in base classes but that's not viable here so I switched to static_cast.

@iche033 iche033 added the Bullet Bullet engine label Jul 22, 2024
@azeey azeey added the beta Targeting beta release of upcoming collection label Jul 29, 2024
@azeey azeey removed the beta Targeting beta release of upcoming collection label Sep 26, 2024
@azeey
Copy link
Contributor

azeey commented Feb 10, 2025

@azeey to review.

@azeey azeey added this to the Jetty Release milestone Jul 28, 2025
Copy link
Contributor

@azeey azeey left a comment

Choose a reason for hiding this comment

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

Well, this was not a walk in the park :), but I think I finally understand how things are working. I don't see any major problems, but it would be good to test what happens when objects are removed. Another point is about the ambiguity with the collision index. I'm wondering if we can find a way around that. No worries if you don't have time to tackle that right now though.

{
if (_childIndex >= 0 && _childIndex < childCount)
{
// todo(iche033) We do not have sufficient info to determine which
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems like something that could happen fairly frequently, i.e, a link that has a primitive collider as well as a convex decomposed mesh. Or it could be a link that has multiple convex decomposed mesh colliders. I guess returning nullptr here means that we won't be consolidating the contact points from this shape right? Just checking my understanding.

}

/////////////////////////////////////////////////
void GzCollisionDispatcher::RemoveManifoldByCollisionObject(
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think any of the for loops are entering the block. I checked this with a Coverage build locally. Can we add a test that covers this?

Copy link
Contributor Author

@iche033 iche033 Aug 9, 2025

Choose a reason for hiding this comment

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

updated MeshContact test in collisions.cc to remove the model with convex decomposed mesh collision. It should trigger this call. 15d4ede

{
const btCollisionShape *shape = _compoundShape->getChildShape(i);
if (this->HasConvexHullChildShapes(shape))
return nullptr;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we add a test that covers this?

auto manifoldIt = this->manifoldsToKeep.find(_manifold);
if (manifoldIt != this->manifoldsToKeep.end())
this->manifoldsToKeep.erase(manifoldIt);

Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to also remove it from customManifolds?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think this is only be called for contact manifolds owned by bullet, and not the custom ones created by gz-physics. I tested manually by removing models with convex decomposed collisions and did not notice that custom manifolds were passed to this function.

if (this->customManifolds.find(contactManifold) !=
this->customManifolds.end())
{
contactManifold->refreshContactPoints(ob0->getWorldTransform(),
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this necessary? Do you know that Bullet itself won't be doing this?

Copy link
Contributor Author

@iche033 iche033 Aug 9, 2025

Choose a reason for hiding this comment

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

I remember I had to keep this call for the multi body link transform to be updated. As a test, I dropped a model with convex decomposed collisions on the ground -> this worked fine, but as soon as I moved it to a different pose, its transforms are not updated.

// -> comopundShape -> convexShape0
// -> convexShape1
// A _childIndex of 1 is ambiguous as it could refer to either
// boxShape1 or convexShape1
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we use the getUserIndex or getUserPointer to help with this somehow?

Signed-off-by: Ian Chen <ichen@openrobotics.org>
@iche033
Copy link
Contributor Author

iche033 commented Aug 9, 2025

I addressed most of the comments but not all. I still need to figure out how to resolve the issue with ambiguous collision index and then add a test.

Copy link

codecov bot commented Aug 9, 2025

Codecov Report

❌ Patch coverage is 91.33858% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.54%. Comparing base (92e02c3) to head (15d4ede).
⚠️ Report is 67 commits behind head on gz-physics7.

Files with missing lines Patch % Lines
bullet-featherstone/src/SimulationFeatures.cc 72.00% 7 Missing ⚠️
bullet-featherstone/src/Base.cc 95.87% 4 Missing ⚠️
Additional details and impacted files
@@               Coverage Diff               @@
##           gz-physics7     #664      +/-   ##
===============================================
+ Coverage        78.32%   79.54%   +1.21%     
===============================================
  Files              140      144       +4     
  Lines             8069     8799     +730     
===============================================
+ Hits              6320     6999     +679     
- Misses            1749     1800      +51     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@azeey azeey removed this from the Jetty Release milestone Aug 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bullet Bullet engine 🎵 harmonic Gazebo Harmonic
Projects
Status: In review
Development

Successfully merging this pull request may close these issues.

2 participants