Skip to content

Shape scaling issue with MuJoCo solver #714#1012

Merged
adenzler-nvidia merged 3 commits into
newton-physics:mainfrom
vreutskyy:714-shape-scaling-issue-with-mujoco-solver
Oct 31, 2025
Merged

Shape scaling issue with MuJoCo solver #714#1012
adenzler-nvidia merged 3 commits into
newton-physics:mainfrom
vreutskyy:714-shape-scaling-issue-with-mujoco-solver

Conversation

@vreutskyy

@vreutskyy vreutskyy commented Oct 30, 2025

Copy link
Copy Markdown
Member

Description

This PR fixes the shape scaling issue with the MuJoCo solver when using multiple worlds with different scales. Closes #714.

Problem

The MuJoCo solver was incorrectly handling shape transformations across multiple worlds with different scales. The issue was caused by shape_incoming_xform being computed from world0's geometry data and then incorrectly applied to all worlds, resulting in visual shapes being displayed correctly but collision shapes being wrong in scaled worlds.

Solution

  1. Removed shape_incoming_xform - This field was the root cause of the scaling issue. It has been completely removed from the solver and all related computations.

  2. Added proper mesh transform support - The solver now correctly handles mesh transformations by applying mesh transformations in the update_geom_properties_kernel for mesh geoms

Tests Added

  • test_shape_scaling_across_worlds - Verifies that shapes maintain correct offsets when worlds have different scales
  • test_mesh_geoms_across_worlds - Verifies that mesh geoms with non-zero mesh_pos are handled correctly across worlds

Limitations

Scaling still won't work for meshes. It works only for primitive shapes.

Newton Migration Guide

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

  • The migration guide in docs/migration.rst is up to date

Before your PR is "Ready for review"

  • Necessary tests have been added and new examples are tested (see newton/tests/test_examples.py)
  • Documentation is up-to-date
  • Code passes formatting and linting checks with pre-commit run -a

Summary by CodeRabbit

  • New Features

    • Improved mesh geometry handling: mesh transforms are correctly composed with geometry transforms for accurate position/orientation.
    • Shape-to-geom mapping updated to pass mesh metadata so mesh centers and orientations are tracked per-geometry.
  • Tests

    • Added tests for shape scaling across worlds.
    • Added tests for mesh geometry placement and mesh-center consistency across worlds.

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

coderabbitai Bot commented Oct 30, 2025

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Renamed and repurposed shape-mapping kernel and removed per-shape incoming-transform state. Geom property kernel now accepts geom_type/geom_dataid and mesh transforms (mesh_pos/mesh_quat); mesh transforms are composed with geom transforms before writing geom_pos/geom_quat. Tests added for scaling and mesh geoms across worlds.

Changes

Cohort / File(s) Change Summary
Kernel refactor & mesh transform handling
newton/_src/solvers/mujoco/solver_mujoco.py
Renamed update_incoming_shape_xform_kernelupdate_shape_mappings_kernel, removed shape_incoming_xform handling and related public attribute. Updated update_geom_properties_kernel signature to accept geom_type, GEOM_TYPE_MESH, geom_dataid, mesh_pos, mesh_quat. Implemented mesh-transform composition for mesh geoms and patched mjw_model to ensure mesh_pos exists. Updated call sites (e.g., add_geoms) to match new signatures and dataflow.
Tests: MuJoCo solver geometry
newton/tests/test_mujoco_solver.py
Added test_shape_scaling_across_worlds and test_mesh_geoms_across_worlds. Removed reliance on shape_incoming_xform in tests and clarified body-local coordinate expectations.

Sequence Diagram(s)

sequenceDiagram
    participant Solver
    participant MapKer as update_shape_mappings_kernel
    participant PropKer as update_geom_properties_kernel
    participant MJModel as mjw_model

    Note over Solver,MapKer: New mapping phase
    Solver->>MapKer: geom_to_shape_idx, geom_is_static, mapping arrays
    MapKer-->>Solver: full_shape_mapping, reverse_shape_mapping

    Note over Solver,PropKer: Geom property update (mesh-aware)
    Solver->>PropKer: geom_type, geom_dataid, mesh_pos, mesh_quat, geom transforms
    alt geom_type == GEOM_TYPE_MESH
        PropKer->>PropKer: compose(mesh_pos/mesh_quat, geom_transform)
    end
    PropKer-->>MJModel: write geom_pos, geom_quat
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

  • Focus review on: update_geom_properties_kernel transform composition correctness (order and math), all updated kernel call sites (e.g., add_geoms), and mjw_model mesh field patching.
  • Verify tests test_shape_scaling_across_worlds and test_mesh_geoms_across_worlds reflect intended coordinate spaces and use new mesh fields.

Possibly related PRs

Suggested reviewers

  • eric-heiden
  • adenzler-nvidia
  • jvonmuralt

Pre-merge checks and finishing touches

✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "Shape scaling issue with MuJoCo solver #714" clearly and directly summarizes the primary change in the changeset. It identifies both the specific problem (shape scaling issue) and the affected component (MuJoCo solver), matching the main objectives of the PR which are to fix incorrect shape transformation handling across multiple worlds with different scales. The title is concise, specific, and accurately reflects the core focus of the implementation changes and tests added.
Linked Issues Check ✅ Passed The code changes directly address the core objectives from linked issue #714. The PR removes the flawed shape_incoming_xform mechanism that incorrectly computed transforms from world0's data and applied them to all worlds, replacing it with proper per-world mesh transform support applied in update_geom_properties_kernel. The two test methods test_shape_scaling_across_worlds and test_mesh_geoms_across_worlds validate that shapes maintain correct offsets when worlds have different scales and that mesh geometries are handled correctly, which directly satisfies the requirement that collision geometry should respect per-environment scale consistently across multiple worlds.
Docstring Coverage ✅ Passed Docstring coverage is 90.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • 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

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov

codecov Bot commented Oct 30, 2025

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

@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

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

1141-1152: Consider using a named constant for mesh geom type.

The mesh transform logic is correct. The check if geom_type[geom_idx] == 7: uses a magic number where 7 represents mjGEOM_MESH. While the comment clarifies this, consider defining a module-level constant for improved maintainability:

MJGEOM_MESH = 7

Then use: if geom_type[geom_idx] == MJGEOM_MESH:

📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6c71866 and c90066e.

📒 Files selected for processing (2)
  • newton/_src/solvers/mujoco/solver_mujoco.py (6 hunks)
  • newton/tests/test_mujoco_solver.py (3 hunks)
🧰 Additional context used
🧠 Learnings (12)
📚 Learning: 2025-10-10T10:47:41.082Z
Learnt from: nvtw
PR: newton-physics/newton#899
File: newton/tests/test_rigid_contact.py:214-268
Timestamp: 2025-10-10T10:47:41.082Z
Learning: In `newton/tests/test_rigid_contact.py`, using `add_shape_plane(width=0, length=0)` for an infinite plane works correctly with the collision system and does not cause degenerate AABB issues in the test scenario `test_shape_collisions_gjk_mpr_multicontact`.

Applied to files:

  • newton/tests/test_mujoco_solver.py
📚 Learning: 2025-08-18T15:56:26.587Z
Learnt from: adenzler-nvidia
PR: newton-physics/newton#552
File: newton/_src/solvers/mujoco/solver_mujoco.py:0-0
Timestamp: 2025-08-18T15:56:26.587Z
Learning: In Newton's MuJoCo solver, when transforming joint axes from Newton's internal frame to MuJoCo's expected frame, use wp.quat_rotate(joint_rot, axis) not wp.quat_rotate_inv(joint_rot, axis). The joint_rot represents rotation from joint-local to body frame, so forward rotation is correct.

Applied to files:

  • newton/tests/test_mujoco_solver.py
  • newton/_src/solvers/mujoco/solver_mujoco.py
📚 Learning: 2025-09-25T16:14:22.033Z
Learnt from: dylanturpin
PR: newton-physics/newton#806
File: newton/_src/sim/ik/ik_objectives.py:0-0
Timestamp: 2025-09-25T16:14:22.033Z
Learning: In NVIDIA Warp's Newton physics library, wp.transform supports direct numerical indexing (e.g., body_tf[0], body_tf[1], body_tf[2] for position and body_tf[3], body_tf[4], body_tf[5], body_tf[6] for quaternion components) to access its elements. This is the standard API used throughout the codebase.

Applied to files:

  • newton/tests/test_mujoco_solver.py
  • newton/_src/solvers/mujoco/solver_mujoco.py
📚 Learning: 2025-08-12T05:17:34.423Z
Learnt from: shi-eric
PR: newton-physics/newton#521
File: newton/examples/example_cloth_hanging.py:36-36
Timestamp: 2025-08-12T05:17:34.423Z
Learning: The STYLE3D solver in Newton is a new solver that did not exist in warp.sim, so it does not require any migration documentation.

Applied to files:

  • newton/tests/test_mujoco_solver.py
📚 Learning: 2025-08-19T12:27:30.629Z
Learnt from: preist-nvidia
PR: newton-physics/newton#579
File: newton/examples/example_mujoco.py:350-354
Timestamp: 2025-08-19T12:27:30.629Z
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-12T17:51:37.474Z
Learnt from: nvlukasz
PR: newton-physics/newton#519
File: newton/geometry.py:16-22
Timestamp: 2025-08-12T17:51:37.474Z
Learning: In the Newton public API refactor, common geometry symbols like ParticleFlags and ShapeFlags are now exposed at the top level in newton/__init__.py rather than through newton.geometry. The newton/geometry.py module is intentionally focused only on broad-phase collision detection classes (BroadPhaseAllPairs, BroadPhaseExplicit, BroadPhaseSAP).

Applied to files:

  • newton/_src/solvers/mujoco/solver_mujoco.py
📚 Learning: 2025-08-19T12:27:30.629Z
Learnt from: preist-nvidia
PR: newton-physics/newton#579
File: newton/examples/example_mujoco.py:350-354
Timestamp: 2025-08-19T12:27:30.629Z
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
📚 Learning: 2025-09-18T07:05:56.836Z
Learnt from: gdaviet
PR: newton-physics/newton#750
File: newton/_src/solvers/implicit_mpm/solve_rheology.py:969-986
Timestamp: 2025-09-18T07:05:56.836Z
Learning: In newton/_src/solvers/implicit_mpm/solve_rheology.py, transposed_strain_mat parameter cannot be None - the type signature was corrected to reflect this guarantee, eliminating the need for None checks when accessing transposed_strain_mat.offsets.

Applied to files:

  • newton/_src/solvers/mujoco/solver_mujoco.py
📚 Learning: 2025-09-22T21:08:31.901Z
Learnt from: dylanturpin
PR: newton-physics/newton#806
File: newton/examples/ik/example_ik_franka.py:121-123
Timestamp: 2025-09-22T21:08:31.901Z
Learning: In the newton physics framework, when creating warp arrays for IK solver joint variables using wp.array(self.model.joint_q, shape=(1, coord_count)), the resulting array acts as a reference/pointer to the original model's joint coordinates, so updates from the IK solver automatically reflect in the model's joint_q buffer used for rendering, despite the general warp documentation suggesting copies are made by default.

Applied to files:

  • newton/_src/solvers/mujoco/solver_mujoco.py
📚 Learning: 2025-09-22T21:08:31.901Z
Learnt from: dylanturpin
PR: newton-physics/newton#806
File: newton/examples/ik/example_ik_franka.py:121-123
Timestamp: 2025-09-22T21:08:31.901Z
Learning: In the newton physics framework, when creating warp arrays for IK solver joint variables using wp.array(self.model.joint_q, shape=(1, coord_count)), the resulting array acts as a reference/pointer to the original model's joint coordinates, so updates from the IK solver automatically reflect in the model's joint_q buffer used for rendering.

Applied to files:

  • newton/_src/solvers/mujoco/solver_mujoco.py
📚 Learning: 2025-08-25T20:10:59.536Z
Learnt from: dylanturpin
PR: newton-physics/newton#634
File: newton/examples/ik/example_ik_franka.py:0-0
Timestamp: 2025-08-25T20:10:59.536Z
Learning: In Newton's IK examples, when creating solver arrays with `wp.array(source_array, shape=new_shape)`, this creates a view into the same underlying memory rather than a copy. This means updates to the reshaped array are automatically reflected in the original array without needing explicit copy operations like `wp.copy()`.

Applied to files:

  • newton/_src/solvers/mujoco/solver_mujoco.py
📚 Learning: 2025-09-25T16:14:22.033Z
Learnt from: dylanturpin
PR: newton-physics/newton#806
File: newton/_src/sim/ik/ik_objectives.py:0-0
Timestamp: 2025-09-25T16:14:22.033Z
Learning: wp.transform in NVIDIA Warp supports indexing using numerical indices (e.g., body_tf[0], body_tf[3], etc.) to access translation and rotation components. The indexing approach used in the Newton codebase is valid and compiles correctly.

Applied to files:

  • newton/_src/solvers/mujoco/solver_mujoco.py
🧬 Code graph analysis (1)
newton/tests/test_mujoco_solver.py (2)
newton/_src/sim/builder.py (2)
  • add_shape_sphere (2866-2900)
  • finalize (4455-4841)
newton/_src/geometry/types.py (7)
  • finalize (102-109)
  • finalize (237-254)
  • vertices (219-220)
  • vertices (223-225)
  • indices (228-229)
  • indices (232-234)
  • Mesh (116-300)
⏰ 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). (2)
  • GitHub Check: Run GPU Benchmarks (Pull Request)
  • GitHub Check: Run GPU Unit Tests on AWS EC2 (Pull Request)
🔇 Additional comments (8)
newton/_src/solvers/mujoco/solver_mujoco.py (4)

1034-1069: LGTM! Kernel renamed and repurposed appropriately.

The renaming from update_incoming_shape_xform_kernel to update_shape_mappings_kernel better reflects its current purpose of computing shape index mappings without transform calculations.


2445-2448: LGTM! Good defensive programming.

The patch ensures mesh_pos exists on mjw_model, providing compatibility with different versions of mujoco_warp.


2483-2496: LGTM! Kernel call correctly updated.

The call to update_shape_mappings_kernel properly provides all required parameters and matches the new kernel signature.


2777-2805: LGTM! Kernel call properly updated with mesh parameters.

The call to update_geom_properties_kernel correctly passes the new mesh-related parameters (geom_type, geom_dataid, mesh_pos, mesh_quat) from the MuJoCo Warp model.

newton/tests/test_mujoco_solver.py (4)

893-932: LGTM! Test correctly updated for body-local coordinates.

The clarifying comments about body-local coordinates and the direct use of shape_transforms align with the removal of shape_incoming_xform in the solver implementation.


1103-1148: LGTM! Test properly validates dynamic geom property updates.

The test correctly verifies that position and orientation updates work in body-local coordinates after the removal of shape_incoming_xform.


1738-1817: LGTM! Excellent test coverage for shape scaling across worlds.

This test directly addresses the PR's main objective (issue #714) by verifying that shapes maintain correct body-local offsets when different worlds use different scales. The test structure is clear and the assertions validate the expected behavior.


1818-1950: LGTM! Comprehensive test for mesh geom handling across worlds.

This test effectively validates that:

  1. mesh_pos is correctly retrieved from the MuJoCo model
  2. The mesh centering transform is properly applied to geom positions
  3. The composition mesh_tf * shape_tf correctly adds mesh_pos to the shape's local offset

The test expectations align perfectly with the kernel implementation at lines 1146-1151 in the solver.

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

Thank you, just 1 small nitpick.

Comment thread newton/_src/solvers/mujoco/solver_mujoco.py Outdated
Comment thread newton/_src/solvers/mujoco/solver_mujoco.py
@adenzler-nvidia adenzler-nvidia dismissed their stale review October 30, 2025 14:56

dismissing review because of benchmark failure, we should look into that.

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

Copy link
Copy Markdown
Member Author

Fun fact: MJWarp stores the real component of a quaternion as q[0] (which is q.x), perhaps following MuJoCo's convention. It even has special math functions different from Warp's built-in which treats q[3] (q.w) as real component. What a mess :)

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

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

1143-1157: Consider adding bounds check for mesh_id.

The mesh transform composition logic is correct, including the quaternion conversion from MuJoCo's (w,x,y,z) to Warp's (x,y,z,w) convention. However, there's no validation that mesh_id is within bounds before accessing mesh_pos[mesh_id] and mesh_quat[mesh_id].

Consider adding a bounds check:

     if geom_type[geom_idx] == GEOM_TYPE_MESH:
         mesh_id = geom_dataid[geom_idx]
+        if mesh_id >= 0 and mesh_id < mesh_pos.shape[0]:
             mesh_p = mesh_pos[mesh_id]
             mesh_q = mesh_quat[mesh_id]
             mesh_tf = wp.transform(mesh_p, wp.quat(mesh_q.y, mesh_q.z, mesh_q.w, mesh_q.x))
             tf = tf * mesh_tf
📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c90066e and bad8c7b.

📒 Files selected for processing (1)
  • newton/_src/solvers/mujoco/solver_mujoco.py (6 hunks)
🧰 Additional context used
🧠 Learnings (14)
📓 Common learnings
Learnt from: adenzler-nvidia
Repo: newton-physics/newton PR: 552
File: newton/_src/solvers/mujoco/solver_mujoco.py:0-0
Timestamp: 2025-08-18T15:56:26.587Z
Learning: In Newton's MuJoCo solver, when transforming joint axes from Newton's internal frame to MuJoCo's expected frame, use wp.quat_rotate(joint_rot, axis) not wp.quat_rotate_inv(joint_rot, axis). The joint_rot represents rotation from joint-local to body frame, so forward rotation is correct.
📚 Learning: 2025-08-19T12:27:30.629Z
Learnt from: preist-nvidia
Repo: newton-physics/newton PR: 579
File: newton/examples/example_mujoco.py:350-354
Timestamp: 2025-08-19T12:27:30.629Z
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-12T05:17:34.423Z
Learnt from: shi-eric
Repo: newton-physics/newton PR: 521
File: newton/examples/example_cloth_hanging.py:36-36
Timestamp: 2025-08-12T05:17:34.423Z
Learning: The Newton migration guide (docs/migration.rst) is specifically for documenting how to migrate existing warp.sim functionality to Newton equivalents. New Newton-only features that didn't exist in warp.sim do not need migration documentation.

Applied to files:

  • newton/_src/solvers/mujoco/solver_mujoco.py
📚 Learning: 2025-09-18T07:05:56.836Z
Learnt from: gdaviet
Repo: newton-physics/newton PR: 750
File: newton/_src/solvers/implicit_mpm/solve_rheology.py:969-986
Timestamp: 2025-09-18T07:05:56.836Z
Learning: In newton/_src/solvers/implicit_mpm/solve_rheology.py, transposed_strain_mat parameter cannot be None - the type signature was corrected to reflect this guarantee, eliminating the need for None checks when accessing transposed_strain_mat.offsets.

Applied to files:

  • newton/_src/solvers/mujoco/solver_mujoco.py
📚 Learning: 2025-08-19T12:27:30.629Z
Learnt from: preist-nvidia
Repo: newton-physics/newton PR: 579
File: newton/examples/example_mujoco.py:350-354
Timestamp: 2025-08-19T12:27:30.629Z
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
📚 Learning: 2025-08-12T17:51:37.474Z
Learnt from: nvlukasz
Repo: newton-physics/newton PR: 519
File: newton/geometry.py:16-22
Timestamp: 2025-08-12T17:51:37.474Z
Learning: In the Newton public API refactor, common geometry symbols like ParticleFlags and ShapeFlags are now exposed at the top level in newton/__init__.py rather than through newton.geometry. The newton/geometry.py module is intentionally focused only on broad-phase collision detection classes (BroadPhaseAllPairs, BroadPhaseExplicit, BroadPhaseSAP).

Applied to files:

  • newton/_src/solvers/mujoco/solver_mujoco.py
📚 Learning: 2025-08-12T05:17:34.423Z
Learnt from: shi-eric
Repo: newton-physics/newton PR: 521
File: newton/examples/example_cloth_hanging.py:36-36
Timestamp: 2025-08-12T05:17:34.423Z
Learning: The STYLE3D solver in Newton is a new solver that did not exist in warp.sim, so it does not require any migration documentation.

Applied to files:

  • newton/_src/solvers/mujoco/solver_mujoco.py
📚 Learning: 2025-09-22T21:08:31.901Z
Learnt from: dylanturpin
Repo: newton-physics/newton PR: 806
File: newton/examples/ik/example_ik_franka.py:121-123
Timestamp: 2025-09-22T21:08:31.901Z
Learning: In the newton physics framework, when creating warp arrays for IK solver joint variables using wp.array(self.model.joint_q, shape=(1, coord_count)), the resulting array acts as a reference/pointer to the original model's joint coordinates, so updates from the IK solver automatically reflect in the model's joint_q buffer used for rendering, despite the general warp documentation suggesting copies are made by default.

Applied to files:

  • newton/_src/solvers/mujoco/solver_mujoco.py
📚 Learning: 2025-09-22T21:08:31.901Z
Learnt from: dylanturpin
Repo: newton-physics/newton PR: 806
File: newton/examples/ik/example_ik_franka.py:121-123
Timestamp: 2025-09-22T21:08:31.901Z
Learning: In the newton physics framework, when creating warp arrays for IK solver joint variables using wp.array(self.model.joint_q, shape=(1, coord_count)), the resulting array acts as a reference/pointer to the original model's joint coordinates, so updates from the IK solver automatically reflect in the model's joint_q buffer used for rendering.

Applied to files:

  • newton/_src/solvers/mujoco/solver_mujoco.py
📚 Learning: 2025-08-25T20:10:59.536Z
Learnt from: dylanturpin
Repo: newton-physics/newton PR: 634
File: newton/examples/ik/example_ik_franka.py:0-0
Timestamp: 2025-08-25T20:10:59.536Z
Learning: In Newton's IK examples, when creating solver arrays with `wp.array(source_array, shape=new_shape)`, this creates a view into the same underlying memory rather than a copy. This means updates to the reshaped array are automatically reflected in the original array without needing explicit copy operations like `wp.copy()`.

Applied to files:

  • newton/_src/solvers/mujoco/solver_mujoco.py
📚 Learning: 2025-08-18T15:56:26.587Z
Learnt from: adenzler-nvidia
Repo: newton-physics/newton PR: 552
File: newton/_src/solvers/mujoco/solver_mujoco.py:0-0
Timestamp: 2025-08-18T15:56:26.587Z
Learning: In Newton's MuJoCo solver, when transforming joint axes from Newton's internal frame to MuJoCo's expected frame, use wp.quat_rotate(joint_rot, axis) not wp.quat_rotate_inv(joint_rot, axis). The joint_rot represents rotation from joint-local to body frame, so forward rotation is correct.

Applied to files:

  • newton/_src/solvers/mujoco/solver_mujoco.py
📚 Learning: 2025-09-25T16:14:22.033Z
Learnt from: dylanturpin
Repo: newton-physics/newton PR: 806
File: newton/_src/sim/ik/ik_objectives.py:0-0
Timestamp: 2025-09-25T16:14:22.033Z
Learning: In NVIDIA Warp's Newton physics library, wp.transform supports direct numerical indexing (e.g., body_tf[0], body_tf[1], body_tf[2] for position and body_tf[3], body_tf[4], body_tf[5], body_tf[6] for quaternion components) to access its elements. This is the standard API used throughout the codebase.

Applied to files:

  • newton/_src/solvers/mujoco/solver_mujoco.py
📚 Learning: 2025-08-12T17:52:15.009Z
Learnt from: nvlukasz
Repo: newton-physics/newton PR: 519
File: newton/_src/utils/import_mjcf.py:226-231
Timestamp: 2025-08-12T17:52:15.009Z
Learning: In the Newton codebase, when passing array-like objects (numpy arrays, lists, tuples) to wp.vec3(), the consistent pattern is to use the unpacking operator: wp.vec3(*array) rather than wp.vec3(array). This pattern is used throughout newton/_src/utils/import_mjcf.py and newton/_src/core/types.py.

Applied to files:

  • newton/_src/solvers/mujoco/solver_mujoco.py
📚 Learning: 2025-09-25T16:14:22.033Z
Learnt from: dylanturpin
Repo: newton-physics/newton PR: 806
File: newton/_src/sim/ik/ik_objectives.py:0-0
Timestamp: 2025-09-25T16:14:22.033Z
Learning: wp.transform in NVIDIA Warp supports indexing using numerical indices (e.g., body_tf[0], body_tf[3], etc.) to access translation and rotation components. The indexing approach used in the Newton codebase is valid and compiles correctly.

Applied to files:

  • 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). (1)
  • GitHub Check: Run GPU Benchmarks (Pull Request)
🔇 Additional comments (4)
newton/_src/solvers/mujoco/solver_mujoco.py (4)

1036-1069: LGTM! Kernel rename and signature simplification.

The kernel rename from update_incoming_shape_xform_kernel to update_shape_mappings_kernel accurately reflects its focused responsibility: mapping shape indices without transform corrections. The removal of shape_transform handling aligns with the PR objective to eliminate the shape_incoming_xform field.


1092-1096: Good addition of mesh transform parameters.

The new parameters enable per-mesh transform handling. Passing GEOM_TYPE_MESH as a kernel parameter is a clean approach that avoids hardcoded magic numbers while still allowing the value to be used in conditionals.


2489-2500: LGTM! Kernel invocation updated correctly.

The invocation of update_shape_mappings_kernel properly matches the new signature, passing the shape mapping arrays and receiving the bidirectional index mappings.


2793-2797: Mesh field parameters passed correctly.

The kernel invocation properly passes the new mesh-related fields: geom_type, the MuJoCo mesh constant, geom_dataid, and the mesh transform arrays. This aligns with the updated kernel signature.

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

@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 - yes the quaternion stuff is annoying, especially the fact that they reuse the wp.quat type for this. I would have gone for a vec4 with custom math to avoid the confusion..

@adenzler-nvidia adenzler-nvidia merged commit 570ebf2 into newton-physics:main Oct 31, 2025
18 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Dec 16, 2025
3 tasks
eric-heiden pushed a commit to eric-heiden/newton that referenced this pull request Jan 28, 2026
…sics#1012)

Signed-off-by: Viktor Reutskyy <vreutskyy@nvidia.com>
mmacklin pushed a commit to mmacklin/newton that referenced this pull request Apr 7, 2026
…sics#1012)

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

Shape scaling issue with MuJoCo solver

2 participants