Skip to content

Add possibility to forward newton generated contacts into mujoco warp#370

Merged
eric-heiden merged 9 commits into
newton-physics:mainfrom
nvtw:dev/tw/newton_mujoco_contact_interop2
Jul 16, 2025
Merged

Add possibility to forward newton generated contacts into mujoco warp#370
eric-heiden merged 9 commits into
newton-physics:mainfrom
nvtw:dev/tw/newton_mujoco_contact_interop2

Conversation

@nvtw

@nvtw nvtw commented Jul 10, 2025

Copy link
Copy Markdown
Member

Description

Add possibility to forward newton generated contacts into mujoco warp
Required mujoco warp MR google-deepmind/mujoco_warp#484 to be merged first

Before your PR is "Ready for review"

  • All commits are signed-off to indicate that your contribution adheres to the Developer Certificate of Origin requirements
  • I understand that GitHub does not perform any GPU testing of this pull request
  • Necessary tests have been added
  • Documentation is up-to-date
  • Code passes formatting and linting checks with pre-commit run -a

Summary by CodeRabbit

  • New Features

    • Added an option to use Newton-generated contacts instead of MuJoCo's internal contact solver for simulations.
    • Improved shape-to-geometry mapping across multiple environments for more accurate contact handling.
  • Bug Fixes

    • Ensured correct indexing of shapes to MuJoCo geometries in multi-environment setups.
  • Tests

    • Introduced a new test verifying simulation behavior when using Newton contacts with MuJoCo.

Signed-off-by: twidmer <twidmer@nvidia.com>
@nvtw nvtw self-assigned this Jul 11, 2025

@adenzler-nvidia adenzler-nvidia left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you add some tests that verify this functionality?

Comment thread newton/solvers/mujoco/solver_mujoco.py Outdated
Comment thread newton/solvers/mujoco/solver_mujoco.py
Comment thread newton/solvers/mujoco/solver_mujoco.py
@coderabbitai

coderabbitai Bot commented Jul 14, 2025

Copy link
Copy Markdown
Contributor
📝 Walkthrough

"""

Walkthrough

This update adds the ability for the MuJoCoSolver to use Newton-generated contact data instead of MuJoCo's internal contact solver, controlled by a new parameter. Supporting device functions and kernels are introduced for contact conversion, and the model's mapping logic is extended. A new test verifies correct solver behavior with Newton contacts.

Changes

File(s) Change Summary
.../solver_mujoco.py Added Warp device functions and kernel to convert Newton contacts to MuJoCo Warp format. Modified MuJoCoSolver to support use_mujoco_contacts parameter controlling collision detection and contact injection. Extended geom-to-shape mapping for multi-environment setups.
.../test_mujoco_solver.py Added TestMuJoCoSolverNewtonContacts class with a test simulating a sphere on a plane using Newton contacts in MuJoCoSolver.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant MuJoCoSolver
    participant NewtonContacts
    participant MuJoCoWarp

    User->>MuJoCoSolver: Initialize (use_mujoco_contacts=False)
    MuJoCoSolver->>MuJoCoWarp: Set run_collision_detection=False
    loop Simulation Steps
        MuJoCoSolver->>NewtonContacts: Update collision contacts
        MuJoCoSolver->>MuJoCoSolver: convert_contacts_to_mjwarp()
        MuJoCoSolver->>MuJoCoWarp: Inject converted contacts
        MuJoCoSolver->>MuJoCoWarp: Step simulation
    end
Loading

Suggested reviewers

  • AntoineRichard

Poem

In the land of spheres and planes,
Where contacts must be true,
Newton’s touch now guides the way—
MuJoCo listens too!
With kernels, frames, and mappings neat,
The solver hops to a new beat.
🐇✨ Physics complete!
"""

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@nvtw nvtw had a problem deploying to external-pr-approval July 14, 2025 07:57 — with GitHub Actions Error
Signed-off-by: twidmer <twidmer@nvidia.com>
@nvtw nvtw force-pushed the dev/tw/newton_mujoco_contact_interop2 branch from ff1605c to 58ccbb8 Compare July 14, 2025 08:00

@coderabbitai coderabbitai 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.

Actionable comments posted: 0

♻️ Duplicate comments (2)
newton/solvers/mujoco/solver_mujoco.py (2)

263-271: Consider enhanced handling for global shapes.

The current implementation handles shape indices of -1 but may need additional logic for global shapes that are shared across environments, as mentioned in past review comments.

Also applies to: 294-304


1144-1146: Add safeguards for CPU version of MuJoCo.

While the warning for use_mujoco=True with use_mujoco_contacts=False is good, additional safeguards should be added to prevent runtime errors when using CPU MuJoCo with Newton contacts, as mentioned in past review comments.

         if use_mujoco and not use_mujoco_contacts:
             print("Setting use_mujoco_contacts to False has no effect when use_mujoco is True")
+            use_mujoco_contacts = True  # Force to True to prevent issues
 
         disableflags = 0

Also applies to: 1176-1178

🧹 Nitpick comments (2)
newton/solvers/mujoco/solver_mujoco.py (1)

2120-2142: Good implementation of multi-environment shape mapping.

The code correctly expands the shape-to-geom mapping to handle all environments when they are separated into different MuJoCo worlds. The warning about non-divisible shape counts is helpful for debugging.

Consider adding a debug log to report the number of shapes mapped:

         else:
             full_shape_mapping = shape_mapping
+        
+        if len(full_shape_mapping) > 0:
+            print(f"Mapped {len(full_shape_mapping)} Newton shapes to {len(shape_mapping)} MuJoCo geoms")

Also applies to: 2188-2194

newton/tests/test_mujoco_solver.py (1)

1116-1146: Improve test robustness by adding velocity checks and clarifying tolerance values.

The test logic is sound and properly validates the core Newton contact integration functionality. However, consider these improvements:

  1. Magic numbers: The tolerance multipliers (0.9 and 1.2) should be better documented or defined as named constants
  2. Settlement verification: The test only checks final position but doesn't verify the sphere has actually settled (velocity near zero)

Consider this enhanced version:

    def test_sphere_on_plane_with_newton_contacts(self):
        """Test that a sphere correctly collides with a plane using Newton contacts."""
        try:
            solver = MuJoCoSolver(self.model, use_mujoco_contacts=False)
        except ImportError as e:
            self.skipTest(f"MuJoCo or deps not installed. Skipping test: {e}")
            return

        sim_dt = 1.0 / 240.0
        num_steps = 120  # Simulate for 0.5 seconds to ensure it settles
+       
+       # Define tolerance constants for better readability
+       SPHERE_HEIGHT_TOLERANCE_LOWER = 0.9  # Allow 10% compression
+       SPHERE_HEIGHT_TOLERANCE_UPPER = 1.2  # Allow 20% above expected height
+       VELOCITY_SETTLING_THRESHOLD = 0.01   # Consider settled if velocity below this

        for _ in range(num_steps):
            self.contacts = self.model.collide(self.state_in)
            solver.step(self.state_in, self.state_out, self.control, self.contacts, sim_dt)
            self.state_in, self.state_out = self.state_out, self.state_in

        final_pos = self.state_in.body_q.numpy()[self.sphere_body_idx, :3]
        final_height = final_pos[2]  # Z-up in MuJoCo
+       final_velocity = self.state_in.body_qd.numpy()[self.sphere_body_idx, :3]
+       final_speed = np.linalg.norm(final_velocity)

        # The sphere should settle on the plane, with its center at its radius's height
        self.assertGreater(
            final_height,
-           self.sphere_radius * 0.9,
+           self.sphere_radius * SPHERE_HEIGHT_TOLERANCE_LOWER,
            f"Sphere fell through the plane. Final height: {final_height}",
        )
        self.assertLess(
            final_height,
-           self.sphere_radius * 1.2,
+           self.sphere_radius * SPHERE_HEIGHT_TOLERANCE_UPPER,
            f"Sphere is floating above the plane. Final height: {final_height}",
        )
+       
+       # Verify the sphere has settled (low velocity)
+       self.assertLess(
+           final_speed,
+           VELOCITY_SETTLING_THRESHOLD,
+           f"Sphere should have settled but still has velocity: {final_speed}",
+       )
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 067b4cd and ff1605c29e1725f94a9da37d65986be469b0816e.

📒 Files selected for processing (2)
  • newton/solvers/mujoco/solver_mujoco.py (7 hunks)
  • newton/tests/test_mujoco_solver.py (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: shi-eric
PR: newton-physics/newton#386
File: .github/workflows/aws-gpu-tests.yml:65-82
Timestamp: 2025-07-12T19:46:47.510Z
Learning: In the newton-physics/newton repository AWS GPU workflow, the workflow only triggers on `pull_request_target` and `push` events, not on `pull_request` events. The `pull_request_target` event is used for testing PRs from forks safely on AWS infrastructure.
Learnt from: Kenny-Vilella
PR: newton-physics/newton#398
File: newton/examples/example_mujoco.py:352-352
Timestamp: 2025-07-14T03:57:29.659Z
Learning: The use_mujoco option in newton/examples/example_mujoco.py is currently unsupported and causes crashes. The code automatically disables this option with a warning message when users attempt to enable it. This is intentionally kept as a placeholder for future implementation.
newton/solvers/mujoco/solver_mujoco.py (1)
Learnt from: Kenny-Vilella
PR: newton-physics/newton#398
File: newton/examples/example_mujoco.py:352-352
Timestamp: 2025-07-14T03:57:29.659Z
Learning: The use_mujoco option in newton/examples/example_mujoco.py is currently unsupported and causes crashes. The code automatically disables this option with a warning message when users attempt to enable it. This is intentionally kept as a placeholder for future implementation.
🧬 Code Graph Analysis (1)
newton/solvers/mujoco/solver_mujoco.py (3)
newton/sim/model.py (1)
  • Model (30-505)
newton/sim/state.py (1)
  • State (21-109)
newton/sim/contacts.py (1)
  • Contacts (23-84)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: run-newton-tests / newton-unittests (ubuntu-latest)
  • GitHub Check: run-newton-tests / newton-unittests (windows-latest)
  • GitHub Check: run-asv-benchmarks
🔇 Additional comments (8)
newton/solvers/mujoco/solver_mujoco.py (7)

61-87: LGTM! Well-implemented orthonormal frame construction.

The functions correctly compute orthogonal vectors and construct rotation matrices from normal vectors, with proper handling of edge cases like zero-length vectors.


93-137: LGTM! Contact writing function properly structured.

The function correctly writes all contact properties to MuJoCo Warp arrays, following the expected convention as referenced in the comment.


139-198: LGTM! Contact parameter mixing follows MuJoCo conventions.

The function correctly implements MuJoCo's contact parameter mixing rules, including priority-based selection, solmix-based averaging, and appropriate edge case handling.


285-285: Verify the normal vector negation is intentional.

The normal vector is negated here. Please confirm this is intentional to match MuJoCo's contact normal convention (pointing from body B to body A).


1195-1200: LGTM! Conditional contact handling properly implemented.

The step method correctly switches between MuJoCo's collision detection and Newton contact conversion based on the configuration flag.


1205-1253: LGTM! Contact conversion method properly structured.

The method correctly launches the conversion kernel with all required inputs and handles the clearing of collision-related arrays.


1116-1116: Clarify test coverage for the new functionality.

The PR objectives state that no new tests have been added, but the AI summary mentions a test class TestMuJoCoSolverNewtonContacts. Please clarify whether tests have been added and ensure adequate test coverage for the new use_mujoco_contacts parameter and contact conversion functionality.

Likely an incorrect or invalid review comment.

newton/tests/test_mujoco_solver.py (1)

1093-1115: Well-structured test setup with good parameterization.

The setUp method properly configures a simple sphere-plane collision scenario with appropriate stiffness and damping values. The test setup follows good practices by storing relevant parameters as instance variables for reuse.

@nvtw nvtw had a problem deploying to external-pr-approval July 14, 2025 08:00 — with GitHub Actions Error
@nvtw nvtw had a problem deploying to external-pr-approval July 14, 2025 08:01 — with GitHub Actions Error

@coderabbitai coderabbitai 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.

Actionable comments posted: 4

🧹 Nitpick comments (3)
newton/solvers/mujoco/solver_mujoco.py (3)

89-198: Consider optimizing the contact parameter computation.

The contact_params function contains complex branching logic that could impact GPU performance. The multiple conditional assignments for mix calculation might benefit from simplification.

Consider consolidating the mix calculation logic:

-    mix = solmix1 / (solmix1 + solmix2)
-    mix = wp.where((solmix1 < MJ_MINVAL) and (solmix2 < MJ_MINVAL), 0.5, mix)
-    mix = wp.where((solmix1 < MJ_MINVAL) and (solmix2 >= MJ_MINVAL), 0.0, mix)
-    mix = wp.where((solmix1 >= MJ_MINVAL) and (solmix2 < MJ_MINVAL), 1.0, mix)
-    mix = wp.where(p1 == p2, mix, wp.where(p1 > p2, 1.0, 0.0))
+    sum_mix = solmix1 + solmix2
+    mix = wp.where(sum_mix < MJ_MINVAL, 0.5, solmix1 / sum_mix)
+    mix = wp.where(p1 != p2, wp.where(p1 > p2, 1.0, 0.0), mix)

1120-1120: Document the default behavior and interaction with other flags.

The use_mujoco_contacts parameter defaults to True, which maintains backward compatibility. However, the interaction with use_mujoco flag could be better documented.

Consider adding more detailed documentation about the parameter interaction:

-            use_mujoco_contacts (bool): If True, use the MuJoCo contact solver. If False, use the Newton contact solver (newton contacts must be passed in through the step function in that case).
+            use_mujoco_contacts (bool): If True, use the MuJoCo contact solver. If False, use the Newton contact solver and newton contacts must be passed in through the step function. Note: This parameter has no effect when use_mujoco=True, as pure MuJoCo backend always uses MuJoCo contacts.

1148-1149: The warning message could be more descriptive.

The current warning is functional but could provide more guidance to users about the expected behavior.

-        if use_mujoco and not use_mujoco_contacts:
-            print("Setting use_mujoco_contacts to False has no effect when use_mujoco is True")
+        if use_mujoco and not use_mujoco_contacts:
+            print("WARNING: use_mujoco_contacts=False has no effect when use_mujoco=True. Pure MuJoCo backend always uses MuJoCo's contact solver.")
📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ff1605c29e1725f94a9da37d65986be469b0816e and 87f1dc5.

📒 Files selected for processing (2)
  • newton/solvers/mujoco/solver_mujoco.py (7 hunks)
  • newton/tests/test_mujoco_solver.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • newton/tests/test_mujoco_solver.py
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: shi-eric
PR: newton-physics/newton#386
File: .github/workflows/aws-gpu-tests.yml:65-82
Timestamp: 2025-07-12T19:46:47.510Z
Learning: In the newton-physics/newton repository AWS GPU workflow, the workflow only triggers on `pull_request_target` and `push` events, not on `pull_request` events. The `pull_request_target` event is used for testing PRs from forks safely on AWS infrastructure.
Learnt from: Kenny-Vilella
PR: newton-physics/newton#398
File: newton/examples/example_mujoco.py:352-352
Timestamp: 2025-07-14T03:57:29.659Z
Learning: The use_mujoco option in newton/examples/example_mujoco.py is currently unsupported and causes crashes. The code automatically disables this option with a warning message when users attempt to enable it. This is intentionally kept as a placeholder for future implementation.
newton/solvers/mujoco/solver_mujoco.py (1)
Learnt from: Kenny-Vilella
PR: newton-physics/newton#398
File: newton/examples/example_mujoco.py:352-352
Timestamp: 2025-07-14T03:57:29.659Z
Learning: The use_mujoco option in newton/examples/example_mujoco.py is currently unsupported and causes crashes. The code automatically disables this option with a warning message when users attempt to enable it. This is intentionally kept as a placeholder for future implementation.
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: run-newton-tests / newton-unittests (ubuntu-latest)
  • GitHub Check: run-newton-tests / newton-unittests (windows-latest)
  • GitHub Check: run-asv-benchmarks
🔇 Additional comments (4)
newton/solvers/mujoco/solver_mujoco.py (4)

61-87: LGTM: Well-implemented orthogonal vector generation and frame construction.

The orthogonals and make_frame functions correctly implement the mathematical operations needed for contact frame generation. The choice of fallback vectors and normalization handling is sound.


1209-1256: The contact conversion method implementation is comprehensive.

The method correctly launches the conversion kernel with all necessary parameters and handles data clearing. The parameter setup is thorough and matches the kernel signature.


2119-2124: Good addition of reverse mapping for geom-to-shape indexing.

Adding the reverse mapping (geom_to_shape_idx) is a necessary step for the multi-environment shape mapping that follows.


2127-2201: The multi-environment shape mapping logic is well-implemented.

The expansion of shape mapping to cover all environments is correctly implemented. The logic properly handles the case where multiple environments map to the same MuJoCo geom indices, and includes appropriate warning for edge cases.

The mathematical logic is sound:

  • Calculate shapes per environment
  • For each MuJoCo geom, determine the local shape index
  • Map all corresponding global shape indices to the same geom index
  • Handle the single-environment case as a fallback

Comment thread newton/solvers/mujoco/solver_mujoco.py
Comment thread newton/solvers/mujoco/solver_mujoco.py
Comment thread newton/solvers/mujoco/solver_mujoco.py
@eric-heiden eric-heiden temporarily deployed to external-pr-approval July 14, 2025 16:05 — with GitHub Actions Inactive

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

♻️ Duplicate comments (1)
newton/solvers/mujoco/solver_mujoco.py (1)

1199-1203: The conditional logic in the step method needs error handling.

The code correctly handles the two modes but lacks validation for required Newton contacts when use_mujoco_contacts=False.

This matches the previous review feedback about adding error handling for required Newton contacts.

📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 87f1dc5 and 2add78e.

📒 Files selected for processing (1)
  • newton/solvers/mujoco/solver_mujoco.py (7 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: shi-eric
PR: newton-physics/newton#386
File: .github/workflows/aws-gpu-tests.yml:65-82
Timestamp: 2025-07-12T19:46:47.510Z
Learning: In the newton-physics/newton repository AWS GPU workflow, the workflow only triggers on `pull_request_target` and `push` events, not on `pull_request` events. The `pull_request_target` event is used for testing PRs from forks safely on AWS infrastructure.
Learnt from: Kenny-Vilella
PR: newton-physics/newton#398
File: newton/examples/example_mujoco.py:352-352
Timestamp: 2025-07-14T03:57:29.659Z
Learning: The use_mujoco option in newton/examples/example_mujoco.py is currently unsupported and causes crashes. The code automatically disables this option with a warning message when users attempt to enable it. This is intentionally kept as a placeholder for future implementation.
newton/solvers/mujoco/solver_mujoco.py (1)
Learnt from: Kenny-Vilella
PR: newton-physics/newton#398
File: newton/examples/example_mujoco.py:352-352
Timestamp: 2025-07-14T03:57:29.659Z
Learning: The use_mujoco option in newton/examples/example_mujoco.py is currently unsupported and causes crashes. The code automatically disables this option with a warning message when users attempt to enable it. This is intentionally kept as a placeholder for future implementation.
🧬 Code Graph Analysis (1)
newton/solvers/mujoco/solver_mujoco.py (8)
newton/solvers/vbd/solver_vbd.py (1)
  • step (2147-2151)
newton/solvers/solver.py (1)
  • step (250-263)
newton/solvers/featherstone/solver_featherstone.py (1)
  • step (279-663)
newton/solvers/style3d/solver_style3d.py (1)
  • step (132-314)
newton/solvers/xpbd/solver_xpbd.py (1)
  • step (207-660)
newton/sim/model.py (1)
  • Model (30-508)
newton/sim/state.py (1)
  • State (21-109)
newton/sim/contacts.py (1)
  • Contacts (23-84)
🔇 Additional comments (9)
newton/solvers/mujoco/solver_mujoco.py (9)

94-137: The write_contact function looks correct and well-structured.

The function properly maps contact data from Newton format to MuJoCo Warp format, following the reference implementation. The parameter naming and data flow are clear.


142-197: The contact_params function correctly implements MuJoCo's contact parameter mixing.

The function properly handles priority-based parameter mixing and edge cases for small values. The logic follows the MuJoCo reference implementation.


1120-1120: The use_mujoco_contacts parameter addition is well-placed.

The parameter is correctly added to the constructor with a sensible default value and clear documentation.


1148-1149: The warning message for conflicting settings is helpful.

The warning appropriately informs users when use_mujoco_contacts=False has no effect with use_mujoco=True.


1180-1181: The collision detection flag setting is correct.

The code properly sets the MuJoCo Warp model's collision detection flag based on the use_mujoco_contacts parameter.


1209-1256: The convert_contacts_to_mjwarp method is well-implemented.

The method correctly launches the conversion kernel with all required parameters and handles the data flow properly.


2119-2148: The reverse mapping and environment expansion logic is correct.

The code properly creates reverse mappings and expands shape mappings to cover all environments. The logic handles multi-environment scenarios correctly.


2195-2201: The shape-to-geom mapping creation is properly implemented.

The code correctly creates the mapping array and handles the case where shapes might be out of bounds.


61-72: The orthogonals function has a potential division by zero issue.

The function doesn't handle the case where the input vector a has zero length properly. While there's a check on line 68, the normalization on line 67 could fail if a has zero length.

Apply this fix to handle zero-length vectors before normalization:

@wp.func
def orthogonals(a: wp.vec3):
    y = wp.vec3(0.0, 1.0, 0.0)
    z = wp.vec3(0.0, 0.0, 1.0)
+   if wp.length(a) == 0.0:
+       return wp.vec3(0.0, 0.0, 0.0), wp.vec3(0.0, 0.0, 0.0)
    b = wp.where((-0.5 < a[1]) and (a[1] < 0.5), y, z)
    b = b - a * wp.dot(a, b)
    b = wp.normalize(b)
-   if wp.length(a) == 0.0:
-       b = wp.vec3(0.0, 0.0, 0.0)
    c = wp.cross(a, b)
    return b, c

Likely an incorrect or invalid review comment.

Comment thread newton/solvers/mujoco/solver_mujoco.py
Comment thread newton/solvers/mujoco/solver_mujoco.py
# Conflicts:
#	newton/solvers/mujoco/solver_mujoco.py
@nvtw nvtw had a problem deploying to external-pr-approval July 15, 2025 06:17 — with GitHub Actions Error
@nvtw nvtw temporarily deployed to external-pr-approval July 15, 2025 06:50 — with GitHub Actions Inactive

@adenzler-nvidia adenzler-nvidia left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks!

@nvtw nvtw temporarily deployed to external-pr-approval July 16, 2025 06:49 — with GitHub Actions Inactive

@coderabbitai coderabbitai 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.

Actionable comments posted: 0

♻️ Duplicate comments (4)
newton/solvers/mujoco/solver_mujoco.py (4)

75-86: Add zero-length vector check to make_frame function.

The function calls wp.normalize(a) without checking if the vector has zero length, which can cause runtime errors.

This was flagged in a previous review. Apply the suggested fix:

@wp.func
def make_frame(a: wp.vec3):
+   if wp.length(a) == 0.0:
+       return wp.mat33(
+           1.0, 0.0, 0.0,
+           0.0, 1.0, 0.0,
+           0.0, 0.0, 1.0
+       )
    a = wp.normalize(a)
    b, c = orthogonals(a)
    
    # fmt: off
    return wp.mat33(
    a.x, a.y, a.z,
    b.x, b.y, b.z,
    c.x, c.y, c.z
  )
    # fmt: on

299-303: Fix world ID calculation for invalid body pairs.

The current logic defaults to worldid = 0 when both body_a and body_b are invalid (< 0), which incorrectly assigns contacts to environment 0.

This was flagged in previous reviews. Apply the suggested fix:

-   worldid = 0
-   if body_a >= 0:
-       worldid = body_a // bodies_per_env
-   elif body_b >= 0:
-       worldid = body_b // bodies_per_env
+   if body_a >= 0:
+       worldid = body_a // bodies_per_env
+   elif body_b >= 0:
+       worldid = body_b // bodies_per_env
+   else:
+       return  # both bodies invalid – skip this contact

1112-1113: Collision detection flag setting needs validation.

The code sets the collision detection flag but doesn't verify if the MuJoCo Warp model supports this configuration.

This was flagged in a previous review. Add validation:

        if self.mjw_model is not None:
+           if not hasattr(self.mjw_model.opt, 'run_collision_detection'):
+               raise ValueError("MuJoCo Warp version does not support disabling collision detection")
            self.mjw_model.opt.run_collision_detection = use_mujoco_contacts

1131-1135: Step function modification needs error handling.

The conditional logic properly handles the two contact modes, but lacks validation for required Newton contacts.

This was flagged in a previous review. Add validation:

                if self.mjw_model.opt.run_collision_detection:
                    self.mujoco_warp.step(self.mjw_model, self.mjw_data)
                else:
+                   if contacts is None or contacts.rigid_contact_count is None:
+                       raise ValueError("Newton contacts are required when use_mujoco_contacts=False")
                    self.convert_contacts_to_mjwarp(self.model, state_in, contacts)
                    self.mujoco_warp.step(self.mjw_model, self.mjw_data)
🧹 Nitpick comments (1)
newton/solvers/mujoco/solver_mujoco.py (1)

1079-1080: Warning message is helpful but could be more specific.

The warning correctly identifies when the parameter has no effect, but could be more explicit about the behavior.

Consider making the warning more specific:

-       print("Setting use_mujoco_contacts to False has no effect when use_mujoco is True")
+       print("Warning: use_mujoco_contacts=False has no effect when use_mujoco=True. MuJoCo CPU backend will always use its own contact solver.")
📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 245d379 and 9fb6594.

📒 Files selected for processing (1)
  • newton/solvers/mujoco/solver_mujoco.py (8 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: Kenny-Vilella
PR: newton-physics/newton#398
File: newton/examples/example_mujoco.py:352-352
Timestamp: 2025-07-14T03:57:29.659Z
Learning: The use_mujoco option in newton/examples/example_mujoco.py is currently unsupported and causes crashes. The code automatically disables this option with a warning message when users attempt to enable it. This is intentionally kept as a placeholder for future implementation.
newton/solvers/mujoco/solver_mujoco.py (1)
Learnt from: Kenny-Vilella
PR: newton-physics/newton#398
File: newton/examples/example_mujoco.py:352-352
Timestamp: 2025-07-14T03:57:29.659Z
Learning: The use_mujoco option in newton/examples/example_mujoco.py is currently unsupported and causes crashes. The code automatically disables this option with a warning message when users attempt to enable it. This is intentionally kept as a placeholder for future implementation.
🧬 Code Graph Analysis (1)
newton/solvers/mujoco/solver_mujoco.py (3)
newton/sim/model.py (1)
  • Model (30-508)
newton/sim/state.py (1)
  • State (21-109)
newton/sim/contacts.py (1)
  • Contacts (23-84)
🔇 Additional comments (7)
newton/solvers/mujoco/solver_mujoco.py (7)

94-137: Contact writing function looks correct.

The write_contact function properly maps input contact data to MuJoCo Warp output arrays with appropriate data transformations.


142-197: Contact parameters calculation is well-implemented.

The contact_params function correctly implements MuJoCo's contact parameter mixing logic, handling priority, solmix, and other contact properties appropriately.


200-344: Contact conversion kernel is comprehensive but needs validation.

The kernel correctly processes Newton contacts and converts them to MuJoCo Warp format, handling contact frames, distances, and parameters appropriately.


1050-1050: New parameter is well-documented and properly typed.

The use_mujoco_contacts parameter is correctly added with appropriate documentation and default value.

Also applies to: 1073-1073


1141-1189: Contact conversion method is well-implemented.

The convert_contacts_to_mjwarp method correctly launches the conversion kernel with appropriate parameters and device scoping.


2024-2098: Shape mapping extension is correctly implemented.

The logic properly extends the template environment shape mapping to cover all environments by calculating global shape indices and maintaining the correct mapping to MuJoCo geom indices.

The implementation correctly handles the case where multiple Newton environments map to the same MuJoCo geom indices, and includes appropriate warning for shape count validation.


61-72: Fix zero-length vector handling in orthogonals function.

The function checks for zero-length vectors at lines 68-69, but this check occurs after the normalize operation at line 67, which will fail on zero vectors.

Apply this fix to handle zero-length vectors properly:

@wp.func
def orthogonals(a: wp.vec3):
+   if wp.length(a) == 0.0:
+       return wp.vec3(0.0, 0.0, 0.0), wp.vec3(0.0, 0.0, 0.0)
    y = wp.vec3(0.0, 1.0, 0.0)
    z = wp.vec3(0.0, 0.0, 1.0)
    b = wp.where((-0.5 < a[1]) and (a[1] < 0.5), y, z)
    b = b - a * wp.dot(a, b)
    b = wp.normalize(b)
-   if wp.length(a) == 0.0:
-       b = wp.vec3(0.0, 0.0, 0.0)
    c = wp.cross(a, b)
    
    return b, c

Likely an incorrect or invalid review comment.

@nvtw nvtw enabled auto-merge (squash) July 16, 2025 07:10

@coderabbitai coderabbitai 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.

Actionable comments posted: 0

♻️ Duplicate comments (3)
newton/solvers/mujoco/solver_mujoco.py (3)

299-303: Fix world ID calculation for invalid body pairs.

The current logic defaults worldid = 0 when both body_a and body_b are negative, which incorrectly assigns contacts to environment 0. This was flagged in previous reviews but hasn't been addressed.

Apply this fix to handle invalid body pairs correctly:

-    worldid = 0
-    if body_a >= 0:
-        worldid = body_a // bodies_per_env
-    elif body_b >= 0:
-        worldid = body_b // bodies_per_env
+    if body_a >= 0:
+        worldid = body_a // bodies_per_env
+    elif body_b >= 0:
+        worldid = body_b // bodies_per_env
+    else:
+        return  # both bodies invalid – skip this contact

1137-1142: Add error handling for missing Newton contacts.

The conditional logic correctly handles the two contact modes, but there's no validation that Newton contacts are provided when use_mujoco_contacts=False. This was flagged in previous reviews but hasn't been addressed.

Add validation for required Newton contacts:

                if self.mjw_model.opt.run_collision_detection:
                    self.mujoco_warp.step(self.mjw_model, self.mjw_data)
                else:
+                   if contacts is None or contacts.rigid_contact_count is None:
+                       raise ValueError("Newton contacts are required when use_mujoco_contacts=False")
                    self.convert_contacts_to_mjwarp(self.model, state_in, contacts)
                    self.mujoco_warp.step(self.mjw_model, self.mjw_data)

75-86: Add zero-length vector handling before normalization.

The function normalizes the input vector a without checking if it has zero length, which could cause undefined behavior. Even though orthogonals handles zero-length vectors, the normalization should be protected.

Apply this fix to handle zero-length vectors:

@wp.func
def make_frame(a: wp.vec3):
+   if wp.length(a) == 0.0:
+       return wp.mat33(
+           1.0, 0.0, 0.0,
+           0.0, 1.0, 0.0,
+           0.0, 0.0, 1.0
+       )
    a = wp.normalize(a)
    b, c = orthogonals(a)
    
    # fmt: off
    return wp.mat33(
    a.x, a.y, a.z,
    b.x, b.y, b.z,
    c.x, c.y, c.z
  )
    # fmt: on
🧹 Nitpick comments (1)
newton/solvers/mujoco/solver_mujoco.py (1)

2038-2113: Complex but correct multi-environment shape mapping logic.

The logic correctly extends the template environment's shape mapping to all environments by calculating global shape indices. The implementation properly handles the case where multiple environments share the same MuJoCo geom indices.

Consider adding more inline comments to explain the mapping logic:

+           # Calculate the global Newton shape index for the current environment.
+           # Each environment has the same local structure, so we offset by env_idx * shapes_per_env
            global_shape_idx = env_idx * shapes_per_env + local_shape_idx
+           # All corresponding shapes map to the same MuJoCo geom index (since mj_model is single-env).
            full_shape_mapping[global_shape_idx] = geom_idx
📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9fb6594 and 5e3fb4f.

📒 Files selected for processing (1)
  • newton/solvers/mujoco/solver_mujoco.py (8 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: Kenny-Vilella
PR: newton-physics/newton#398
File: newton/examples/example_mujoco.py:352-352
Timestamp: 2025-07-14T03:57:29.659Z
Learning: The use_mujoco option in newton/examples/example_mujoco.py is currently unsupported and causes crashes. The code automatically disables this option with a warning message when users attempt to enable it. This is intentionally kept as a placeholder for future implementation.
newton/solvers/mujoco/solver_mujoco.py (1)
Learnt from: Kenny-Vilella
PR: newton-physics/newton#398
File: newton/examples/example_mujoco.py:352-352
Timestamp: 2025-07-14T03:57:29.659Z
Learning: The use_mujoco option in newton/examples/example_mujoco.py is currently unsupported and causes crashes. The code automatically disables this option with a warning message when users attempt to enable it. This is intentionally kept as a placeholder for future implementation.
🧬 Code Graph Analysis (1)
newton/solvers/mujoco/solver_mujoco.py (3)
newton/sim/model.py (1)
  • Model (30-508)
newton/sim/state.py (1)
  • State (21-109)
newton/sim/contacts.py (1)
  • Contacts (23-84)
🔇 Additional comments (8)
newton/solvers/mujoco/solver_mujoco.py (8)

61-72: Good implementation of orthogonal vector generation.

The function correctly handles zero-length input vectors by returning zero vectors, which addresses the edge case concern from previous reviews. The logic for generating orthogonal vectors is sound.


93-137: Well-implemented contact data writing function.

The function correctly writes all contact parameters to the appropriate output arrays with clear parameter mapping. The implementation is straightforward and follows the MuJoCo Warp pattern.


142-197: Correct implementation of contact parameter mixing.

The function properly implements the MuJoCo contact parameter mixing logic, including handling of priority-based selection and solmix-based blending. The edge case handling for zero solmix values is correct.


1052-1052: Good addition of contact solver control parameter.

The use_mujoco_contacts parameter with default True provides backward compatibility while enabling the new Newton contact functionality.


1083-1085: Helpful warning message for invalid configuration.

The warning appropriately informs users that the use_mujoco_contacts parameter has no effect when using the pure MuJoCo backend.


1118-1120: Correct collision detection flag setting.

The code properly sets the MuJoCo Warp collision detection flag based on the use_mujoco_contacts parameter, enabling the conditional contact processing logic.


1147-1195: Well-implemented contact conversion method.

The method correctly launches the conversion kernel with all necessary parameters, properly calculates bodies_per_env, and includes all required inputs and outputs for the kernel execution.


2022-2022: Good addition of reverse mapping for shape indices.

The geom_to_shape_idx dictionary provides the necessary reverse mapping from MuJoCo geom indices to Newton shape indices, which is needed for the multi-environment expansion logic.

@coderabbitai coderabbitai Bot mentioned this pull request Oct 16, 2025
4 tasks
@coderabbitai coderabbitai Bot mentioned this pull request Dec 16, 2025
4 tasks
@coderabbitai coderabbitai Bot mentioned this pull request Dec 25, 2025
4 tasks
eric-heiden added a commit to eric-heiden/newton that referenced this pull request Jan 28, 2026
…newton-physics#370)

Signed-off-by: twidmer <twidmer@nvidia.com>
Co-authored-by: Eric Heiden <eheiden@nvidia.com>
@coderabbitai coderabbitai Bot mentioned this pull request Feb 4, 2026
3 tasks
@coderabbitai coderabbitai Bot mentioned this pull request Mar 5, 2026
3 tasks
vidurv-nvidia pushed a commit to vidurv-nvidia/newton that referenced this pull request Mar 6, 2026
…ton-physics#370)

This PR adds a quickstart guide and various references to the setup
instructions for Isaac Lab

## Checklist

- [X] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./isaaclab.sh --format`
- [X] I have made corresponding changes to the documentation
- [X] 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 updated the changelog and the corresponding version in the
extension's `config/extension.toml` file
- [X] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there

---------

Signed-off-by: Michael Gussert <michael@gussert.com>
Co-authored-by: Kelly Guo <kellyg@nvidia.com>
mmacklin pushed a commit to mmacklin/newton that referenced this pull request Apr 7, 2026
…newton-physics#370)

Signed-off-by: twidmer <twidmer@nvidia.com>
Co-authored-by: Eric Heiden <eheiden@nvidia.com>
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.

3 participants