Skip to content

Add an option to pass Solimp / Solref joint values to MujocoWarp through the builder / model. #536#581

Merged
eric-heiden merged 4 commits into
newton-physics:mainfrom
vreutskyy:536-add-an-option-to-pass-solimp-solref-joint-values-to-mujocowarp-through-the-builder-model-2
Aug 20, 2025
Merged

Add an option to pass Solimp / Solref joint values to MujocoWarp through the builder / model. #536#581
eric-heiden merged 4 commits into
newton-physics:mainfrom
vreutskyy:536-add-an-option-to-pass-solimp-solref-joint-values-to-mujocowarp-through-the-builder-model-2

Conversation

@vreutskyy

@vreutskyy vreutskyy commented Aug 19, 2025

Copy link
Copy Markdown
Member

Description

This PR adds an option to pass global Solimp/Solref joint limit values to MujocoWarp through the SolverMuJoCo constructor. This helps reduce the performance gap between MJX assets and USD-converted assets by allowing users to provide extra joint parameters to MuJoCo.

Changes:

  • Added joint_solref_limit and joint_solimp_limit optional parameters to SolverMuJoCo.__init__()
  • These global parameters are applied to all joints with limits during the convert_to_mjc() process
  • Works for both linear (slide) and angular (hinge) joints

Usage:

# Create a model without solver parameters
model = builder.finalize()

# Pass global solver parameters when creating the solver
solver = newton.solvers.SolverMuJoCo(
    model,
    joint_solref_limit=(0.02, 1.0),  # Solver reference (time constants)
    joint_solimp_limit=(0.9, 0.95, 0.001, 0.5, 2.0),  # Solver impedance
)

Limitations:

  • All joints with limits receive the same solver parameters (no per-joint customization)
  • Parameters only affect joints that have limits enabled
  • No changes to Model/ModelBuilder classes or import functionality

Closes #536

Newton Migration Guide

Please ensure the migration guide for warp.sim users is up-to-date with the changes made in this MR.

  • The migration guide in docs/migration.rst is up-to-date
    • Note: This feature adds new optional parameters and doesn't break existing code, so no migration guide updates are needed

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
  • Necessary tests have been added and new examples are tested (see newton/tests/test_examples.py)
    • Added test_global_joint_solver_params in newton/tests/test_mujoco_solver.py
  • Documentation is up-to-date
    • Added docstring documentation for the new parameters in SolverMuJoCo.__init__()
  • Code passes formatting and linting checks with pre-commit run -a

Summary by CodeRabbit

  • New Features

    • Added optional global joint-limit solver settings for MuJoCo (configurable softness/stiffness) that apply automatically to all limited joints and default to MuJoCo behavior when unset.
  • Documentation

    • Updated parameter docs to describe the new global joint-limit solver options and their behavior.
  • Tests

    • Added a regression test confirming soft vs. stiff global joint-limit settings affect joint-limit penetration during simulation.

…ugh the builder / model. newton-physics#536

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>
@coderabbitai

coderabbitai Bot commented Aug 19, 2025

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Added optional global joint solver parameters to SolverMuJoCo (joint_solref_limit, joint_solimp_limit), stored them on the solver, and propagate them into per-joint params when a joint has a limited range. Added a test that compares joint-limit behavior for soft vs. stiff global solver params.

Changes

Cohort / File(s) Change Summary
MuJoCo solver parameters
newton/_src/solvers/mujoco/solver_mujoco.py
Added keyword-only constructor args `joint_solref_limit: tuple[float,float]
Tests
newton/tests/test_mujoco_solver.py
Added test_global_joint_solver_params to verify different joint-limit penetration behavior for soft vs. stiff global joint solver parameters over a short simulation.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Client
  participant SolverMuJoCo
  participant add_geoms as add_geoms()
  participant MuJoCo as MuJoCo Engine

  Client->>SolverMuJoCo: __init__(..., joint_solref_limit?, joint_solimp_limit?)
  note right of SolverMuJoCo: store optional global joint solver params

  SolverMuJoCo->>add_geoms: build joints from model/geoms
  add_geoms->>add_geoms: for each limited axis set joint_params["range"]
  alt global params provided
    add_geoms->>add_geoms: set joint_params["solref_limit"] = joint_solref_limit
    add_geoms->>add_geoms: set joint_params["solimp_limit"] = joint_solimp_limit
    note right of add_geoms: new wiring of solver params to joints
  end
  add_geoms->>MuJoCo: create joints with range (+ solref/solimp if present)
  MuJoCo-->>Client: simulation runs using per-joint solver settings
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Assessment against linked issues

Objective Addressed Explanation
Add option to pass Solimp/Solref joint values to MuJoCoWarp through builder/model (#536)

Assessment against linked issues: Out-of-scope changes

(none)

Suggested reviewers

  • vreutskyy

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.


📜 Recent review details

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

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 3c65971 and 3243a73.

📒 Files selected for processing (1)
  • newton/_src/solvers/mujoco/solver_mujoco.py (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • newton/_src/solvers/mujoco/solver_mujoco.py
⏰ 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). (4)
  • GitHub Check: Run GPU Benchmarks (Pull Request)
  • GitHub Check: Run GPU Unit Tests on AWS EC2 (Pull Request)
  • GitHub Check: run-newton-tests / newton-unittests (windows-latest)
  • GitHub Check: run-newton-tests / newton-unittests (ubuntu-latest)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 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.
    • 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.
  • 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 the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

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

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

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.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • 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.

@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: 3

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

1169-1171: Docstring clarity: explicitly state these apply only to limited joints

These globals are applied only when a joint has limits (limited=True). Make that explicit to avoid confusion.

-            joint_solref_limit (tuple[float, float] | None): Global solver reference parameters for all joint limits. If provided, applies these solref values to all joints created. Defaults to None (uses MuJoCo defaults).
-            joint_solimp_limit (tuple[float, float, float, float, float] | None): Global solver impedance parameters for all joint limits. If provided, applies these solimp values to all joints created. Defaults to None (uses MuJoCo defaults).
+            joint_solref_limit (tuple[float, float] | None): Global solver reference parameters for joint limits. If provided, applies these values to every joint that is limited (limited=True) during conversion. Defaults to None (uses MuJoCo defaults).
+            joint_solimp_limit (tuple[float, float, float, float, float] | None): Global solver impedance parameters for joint limits. If provided, applies these values to every joint that is limited (limited=True) during conversion. Defaults to None (uses MuJoCo defaults).

1175-1177: Validate input tuple lengths for new parameters

Defensive check to fail fast on malformed inputs (e.g., wrong tuple sizes) improves debuggability.

-        self.contact_stiffness_time_const = contact_stiffness_time_const
-        self.joint_solref_limit = joint_solref_limit
-        self.joint_solimp_limit = joint_solimp_limit
+        self.contact_stiffness_time_const = contact_stiffness_time_const
+        # Validate optional global joint limit params
+        if joint_solref_limit is not None and len(joint_solref_limit) != 2:
+            raise ValueError("joint_solref_limit must be a length-2 tuple (timeconst, dampratio).")
+        if joint_solimp_limit is not None and len(joint_solimp_limit) != 5:
+            raise ValueError("joint_solimp_limit must be a length-5 tuple.")
+        self.joint_solref_limit = joint_solref_limit
+        self.joint_solimp_limit = joint_solimp_limit

2371-2444: Multi-env parity: consider expanding jnt_solref/jnt_solimp across worlds

In multi-env mode, several arrays are tiled to all worlds. Joint limit solref/solimp are not expanded, which may lead to inconsistent behavior across worlds if MuJoCoWarp expects per-world copies. If MjWarpModel exposes these fields, add them to the expansion list.

         model_fields_to_expand = [
             # "qpos0",
             # "qpos_spring",
             # "body_pos",
             # "body_quat",
             "body_ipos",
             # "body_iquat",
             "body_mass",
             # "body_subtreemass",
             # "subtree_mass",
             "body_inertia",
             # "body_invweight0",
             # "body_gravcomp",
-            # "jnt_solref",
-            # "jnt_solimp",
+            # If present in MjWarpModel, expand joint limit params too
+            "jnt_solref",
+            "jnt_solimp",
             # "jnt_pos",
             # "jnt_axis",

If these fields are not present in MjWarpModel.dataclass_fields, this change is a no-op due to the guarded expansion loop.

📜 Review details

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

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 59a7d5a and 3c65971.

📒 Files selected for processing (2)
  • newton/_src/solvers/mujoco/solver_mujoco.py (4 hunks)
  • newton/tests/test_mujoco_solver.py (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-19T12:27:30.607Z
Learnt from: preist-nvidia
PR: newton-physics/newton#579
File: newton/examples/example_mujoco.py:350-354
Timestamp: 2025-08-19T12:27:30.607Z
Learning: In Newton examples, Example.use_mujoco is a high-level attribute that controls whether to use MuJoCo solver vs other solvers (like XPBD), while SolverMuJoCo.use_mujoco_cpu controls the backend within MuJoCo (CPU vs Warp). These are separate concepts serving different purposes - the PR rename only applies to the solver parameter, not the Example class attributes.

Applied to files:

  • newton/_src/solvers/mujoco/solver_mujoco.py
📚 Learning: 2025-08-19T12:27:30.607Z
Learnt from: preist-nvidia
PR: newton-physics/newton#579
File: newton/examples/example_mujoco.py:350-354
Timestamp: 2025-08-19T12:27:30.607Z
Learning: In Newton examples, there's a distinction between solver parameters and Example class attributes. The Example class can have its own use_mujoco attribute for controlling example-level behavior (like CUDA graphs, rendering logic), while the solver uses use_mujoco_cpu for backend selection. These serve different purposes and should not be conflated during API renames.

Applied to files:

  • newton/_src/solvers/mujoco/solver_mujoco.py
🧬 Code Graph Analysis (1)
newton/tests/test_mujoco_solver.py (3)
newton/_src/sim/builder.py (2)
  • ModelBuilder (68-4065)
  • add_joint_revolute (1015-1097)
newton/_src/sim/model.py (3)
  • state (441-474)
  • control (476-508)
  • collide (510-564)
newton/_src/solvers/mujoco/solver_mujoco.py (1)
  • SolverMuJoCo (1059-2575)
⏰ 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). (4)
  • GitHub Check: Run GPU Benchmarks (Pull Request)
  • GitHub Check: Run GPU Unit Tests on AWS EC2 (Pull Request)
  • GitHub Check: run-newton-tests / newton-unittests (ubuntu-latest)
  • GitHub Check: run-newton-tests / newton-unittests (windows-latest)

Comment thread newton/_src/solvers/mujoco/solver_mujoco.py
Comment thread newton/_src/solvers/mujoco/solver_mujoco.py
Comment thread newton/tests/test_mujoco_solver.py

@eric-heiden eric-heiden 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, LGTM!

…t-values-to-mujocowarp-through-the-builder-model-2
@eric-heiden eric-heiden enabled auto-merge (squash) August 20, 2025 03:19
eric-heiden and others added 2 commits August 20, 2025 06:20
…t-values-to-mujocowarp-through-the-builder-model-2
…t-values-to-mujocowarp-through-the-builder-model-2
@adenzler-nvidia

Copy link
Copy Markdown
Member

looks good as far as solref/solimp_limit goes. I don't see any information about whether that ticket was about limit vs friction, do we know?

@vreutskyy

Copy link
Copy Markdown
Member Author

looks good as far as solref/solimp_limit goes. I don't see any information about whether that ticket was about limit vs friction, do we know?

I believe it was as it's said in the title "... pass Solimp / Solref joint values to MujocoWarp...". No friction was mentioned.

@adenzler-nvidia

Copy link
Copy Markdown
Member

@AntoineRichard can you confirm this?

In the MuJoCo docs I see the following fields:
mjtNum solref_limit[mjNREF]; // solver reference: joint limits
mjtNum solimp_limit[mjNIMP]; // solver impedance: joint limits

mjtNum solref_friction[mjNREF]; // solver reference: dof friction
mjtNum solimp_friction[mjNIMP]; // solver impedance: dof friction

@vreutskyy

vreutskyy commented Aug 20, 2025

Copy link
Copy Markdown
Member Author

Sure. But the task only specifies "Solimp / Solref joint values"

@eric-heiden eric-heiden merged commit 3f9434f into newton-physics:main Aug 20, 2025
14 of 15 checks passed
@vreutskyy

Copy link
Copy Markdown
Member Author

I mean, I saw there's a bunch of solimp/solref in MuJoCo, but I only considered these two as they had 'joint' in their descriptions :)

mzamoramora-nvidia pushed a commit to MiguelZamoraM/newton that referenced this pull request Aug 20, 2025
…ugh the builder / model. newton-physics#536 (newton-physics#581)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>
Co-authored-by: Eric Heiden <eheiden@nvidia.com>
Signed-off-by: Miguel Zamora <mazamoramora@nvidia.com>
@coderabbitai coderabbitai Bot mentioned this pull request Dec 23, 2025
4 tasks
eric-heiden added a commit to eric-heiden/newton that referenced this pull request Jan 28, 2026
…ugh the builder / model. newton-physics#536 (newton-physics#581)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>
Co-authored-by: Eric Heiden <eheiden@nvidia.com>
vidurv-nvidia pushed a commit to vidurv-nvidia/newton that referenced this pull request Mar 6, 2026
# Description

<!--
Thank you for your interest in sending a pull request. Please make sure
to check the contribution guidelines.

Link:
https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html
-->

Add a note for warning msgs from ovd recording.

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

- Bug fix (non-breaking change which fixes an issue)
- New feature (non-breaking change which adds functionality)
- Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- This change requires a documentation update

## Screenshots

Please attach before and after screenshots of the change if applicable.

<!--
Example:

| Before | After |
| ------ | ----- |
| _gif/png before_ | _gif/png after_ |

To upload images to a PR -- simply drag and drop an image while in edit
mode and it should upload the image directly. You can then paste that
source into the above before/after sections.
-->

## 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

<!--
As you go through the checklist above, you can mark something as done by
putting an x character in it

For example,
- [x] I have done this task
- [ ] I have not done this task
-->

---------

Signed-off-by: matthewtrepte <mtrepte@nvidia.com>
mmacklin pushed a commit to mmacklin/newton that referenced this pull request Apr 7, 2026
…ugh the builder / model. newton-physics#536 (newton-physics#581)

Signed-off-by: Viktor Reutskyy <vreutskyy@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.

Add an option to pass Solimp / Solref joint values to MujocoWarp through the builder / model.

4 participants