Skip to content

Switch to velocity-space ik to support all joint types#450

Merged
eric-heiden merged 3 commits into
newton-physics:mainfrom
dylanturpin:vel-space-ik
Aug 1, 2025
Merged

Switch to velocity-space ik to support all joint types#450
eric-heiden merged 3 commits into
newton-physics:mainfrom
dylanturpin:vel-space-ik

Conversation

@dylanturpin

@dylanturpin dylanturpin commented Jul 21, 2025

Copy link
Copy Markdown
Member

Description

Upgrades Newton’s IK to a velocity-space optimization. Δq is now produced in joint‑velocity space (like joint_qd) and integrated through Featherstone's jcalc_integrate(), letting us:

  • support every joint type (FREE, BALL, D6 …) under the analytic / autodiff back‑ends
  • pull Jacobian columns directly from the motion sub‑space with no joint type branching
  • keep the same API and benchmarks

Testing: test_ik.py now tests convergence for a free joint.

Interactive example: example_ik_interactive.py can be run with --floating to include a free joint connecting the base of the h1 robot to the world so the torso can move (as seen below).

output

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

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)
  • Documentation is up-to-date
  • Code passes formatting and linting checks with pre-commit run -a

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Added new inverse kinematics tests for models with both free and revolute joints, covering multiple Jacobian computation modes.
    • Introduced a floating base mode option in the interactive IK example, allowing the robot model to use a floating 6-DOF base.
  • Refactor

    • Unified inverse kinematics solver and objectives to consistently use joint degrees of freedom (DoFs) instead of joint coordinates, improving compatibility with complex joint types.
    • Streamlined coordinate handling in the interactive IK example to operate in world space when using the floating base mode.
    • Updated rotation objective to optionally disable quaternion error canonicalization for IK solving.
  • Bug Fixes

    • Corrected joint indexing and initialization in IK examples to ensure accurate joint state setup.
  • Tests

    • Expanded the test suite with additional convergence tests for free-plus-revolute and 6-DOF joint models.
    • Added Jacobian comparison tests for 6-DOF joint objectives.

@coderabbitai

coderabbitai Bot commented Jul 21, 2025

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The changes refactor the inverse kinematics (IK) system to consistently use joint degrees of freedom (DoFs) instead of joint coordinates for all solver, objective, and kernel computations. The interactive IK example is updated to operate in world coordinates, adjust joint indexing, and streamline solver invocation. New and expanded tests validate IK convergence for models with free and revolute joints. Additionally, a benchmark example disables quaternion error canonicalization in rotation objectives.

Changes

Files/Paths Change Summary
Interactive IK example
newton/examples/example_ik_interactive.py
Added floating parameter to support floating 6-DOF base; updated joint indexing, target coordinate handling, gizmo dragging logic, and solver call simplification. Added CLI argument for floating mode.
Inverse Kinematics core
newton/sim/ik.py
Refactored IK solver and objective classes to use DoFs instead of joint coordinates; replaced coordinate-based indexing and buffers with DoF-based equivalents; added new integration kernel; updated Jacobian and residual computations; removed obsolete kernels; added quaternion error canonicalization flag for rotation objectives.
IK tests
newton/tests/test_ik.py
Added new model builders with free and 6-DOF joints; added convergence tests for free, revolute, and D6 joints across multiple Jacobian modes; renamed existing planar joint tests; added Jacobian comparison tests for D6 joint models; registered all new tests in the test suite.
IK benchmark example
newton/examples/example_ik_benchmark.py
Modified RotationObjective construction to disable quaternion error canonicalization by passing canonicalize_quat_err=False.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Example (interactive IK)
    participant IKSolver
    participant Model

    User->>Example: Interact with gizmo (drag target)
    Example->>Example: Update target position (world coordinates)
    Example->>IKSolver: Call solve() with current joint_q and targets
    IKSolver->>Model: Evaluate FK with joint DoFs
    IKSolver->>IKSolver: Compute residuals/Jacobian (DoF-based)
    IKSolver->>IKSolver: Integrate dq_dof into joint_q
    IKSolver-->>Example: Return new joint_q
    Example-->>User: Update robot pose in UI
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~90 minutes

Possibly related PRs

Suggested reviewers

  • eric-heiden

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 70305c6 and 0597978.

📒 Files selected for processing (4)
  • newton/examples/example_ik_benchmark.py (1 hunks)
  • newton/examples/example_ik_interactive.py (14 hunks)
  • newton/sim/ik.py (37 hunks)
  • newton/tests/test_ik.py (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • newton/examples/example_ik_interactive.py
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: dylanturpin
PR: newton-physics/newton#450
File: newton/sim/ik.py:1286-1296
Timestamp: 2025-07-21T19:11:04.077Z
Learning: In Newton's IK system, the JointLimitObjective class intentionally only handles joints where DOF count equals coordinate count (1-1 mapping). This is appropriate because joint limits are typically only meaningful for simple joint types like revolute and prismatic joints, not complex joints like ball or free joints where DOF count != coordinate count.
📚 Learning: in newton's ik system, the jointlimitobjective class intentionally only handles joints where dof cou...
Learnt from: dylanturpin
PR: newton-physics/newton#450
File: newton/sim/ik.py:1286-1296
Timestamp: 2025-07-21T19:11:04.077Z
Learning: In Newton's IK system, the JointLimitObjective class intentionally only handles joints where DOF count equals coordinate count (1-1 mapping). This is appropriate because joint limits are typically only meaningful for simple joint types like revolute and prismatic joints, not complex joints like ball or free joints where DOF count != coordinate count.

Applied to files:

  • newton/tests/test_ik.py
  • newton/sim/ik.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). (2)
  • GitHub Check: Run GPU Benchmarks (Pull Request)
  • GitHub Check: Run GPU Unit Tests on AWS EC2 (Pull Request)
🔇 Additional comments (7)
newton/examples/example_ik_benchmark.py (1)

181-181: LGTM!

Good addition to explicitly set canonicalize_quat_err=False in the benchmark. This provides a test case for the new quaternion error handling mode.

newton/tests/test_ik.py (2)

70-122: Excellent test model builders for complex joint types!

The _build_free_plus_revolute and _build_single_d6 helper functions provide good test cases for the velocity-space IK implementation with different joint types.


211-261: Good coverage for floating base models!

The free joint convergence tests validate the velocity-space IK solver's ability to handle 6-DOF floating base models, which is a key improvement mentioned in the PR objectives.

newton/sim/ik.py (4)

481-539: Excellent velocity-space integration implementation!

The _integrate_dq_dof kernel correctly implements the velocity-space IK update by:

  • Using jcalc_integrate to handle all joint types (revolute, prismatic, ball, free, D6)
  • Treating the LM update dq_dof as a velocity with dt as the step size
  • Properly handling the joint-specific coordinate/DOF mappings

This is a clean implementation that achieves the PR's goal of supporting all joint types.


317-337: Well-structured motion subspace computation!

The _compute_motion_subspace method efficiently computes the motion subspace columns for analytic Jacobian computation by:

  • Using jcalc_motion to extract Jacobian columns directly without joint-type branching
  • Employing a 2D kernel launch pattern for better parallelization
  • Properly handling parent-child transformations

This implementation aligns with the PR objective of extracting Jacobian columns directly from the motion sub-space.


1250-1260: DOF-to-coordinate mapping correctly scoped for joint limits

The implementation intentionally handles only joints where DOF count equals coordinate count (1-1 mapping), which is appropriate since joint limits are typically meaningful only for simple joint types like revolute and prismatic joints.


1343-1344: Proper quaternion error handling with configurable canonicalization

The addition of the canonicalize_quat_err flag allows users to control whether the error quaternion is flipped for the shortest arc, providing flexibility for different use cases while maintaining backward compatibility with the default True value.

✨ 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.
    • 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 generate unit tests to generate unit tests for 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.

@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 (5)
newton/tests/test_ik.py (2)

65-68: Section header formatting consistency

Consider using consistent formatting for section headers. The other section uses a simple comment style (line 29), while this uses a more elaborate box style.

-# ----------------------------------------------------------------------------
-# helpers - FREE-REV
-# ----------------------------------------------------------------------------
-
+# ----------------------------------------------------------------------------
+# helpers: free-revolute baseline
+# ----------------------------------------------------------------------------

220-220: Consider making iteration count configurable

The free joint convergence test uses 60 iterations while the planar test uses 40. Consider making this a parameter or adding a comment explaining why free joints need more iterations.

Add a comment explaining the iteration count difference:

+        # Free joints have more DOFs and typically require more iterations to converge
         solver.solve(iterations=60)
newton/examples/example_ik_interactive.py (1)

217-218: Document the purpose of epsilon offset

Adding 1e-3 to all joint angles needs explanation. Is this for numerical stability or to avoid singularities?

+        # Add small epsilon to avoid numerical issues at joint limits or singularities
         for i in range(len(articulation_builder.joint_q)):
             articulation_builder.joint_q[i] += 1e-3
newton/sim/ik.py (2)

356-356: Redundant zero operation

The qd_zero array is already initialized to zeros and passed as zero velocities. Zeroing it again after integration seems unnecessary.

             device=self.device,
         )
-        self.qd_zero.zero_()

1177-1179: Magic number for joint limit range check

The threshold 9.9e5 for treating joint ranges as unlimited should be a named constant.

+    UNLIMITED_JOINT_RANGE = 9.9e5  # Threshold for treating joint limits as unlimited
+
     # treat huge ranges as no limit
-    if upper - lower > 9.9e5:
+    if upper - lower > UNLIMITED_JOINT_RANGE:
         return
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 6fc6074 and 5b3640bd89c24da3bdee6e8ecfb253c01f5edda2.

📒 Files selected for processing (3)
  • newton/examples/example_ik_interactive.py (12 hunks)
  • newton/sim/ik.py (26 hunks)
  • newton/tests/test_ik.py (5 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
newton/sim/ik.py (3)
newton/sim/state.py (1)
  • joint_dof_count (105-109)
newton/sim/builder.py (1)
  • joint_count (442-443)
newton/solvers/featherstone/kernels.py (2)
  • jcalc_integrate (406-537)
  • jcalc_motion (228-327)
⏰ 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 Unit Tests on AWS EC2 (Pull Request)
🔇 Additional comments (6)
newton/tests/test_ik.py (1)

354-363: Test organization looks good

The test registration is well-organized with clear sections for planar convergence, free-joint convergence, and Jacobian equality tests.

newton/examples/example_ik_interactive.py (2)

118-118: Significant weight increase for joint limits

The joint limit objective weight increased from 0.1 to 1.0 (10x increase). This could significantly affect the solver behavior and convergence. Please verify this is intentional.


474-474: _solve signature verified – no step_size parameter
I confirmed that _solve(self) in newton/examples/example_ik_interactive.py is defined without any parameters. Removing step_size from its invocation is therefore correct—no changes are needed.

Likely an incorrect or invalid review comment.

newton/sim/ik.py (3)

492-495: Excellent documentation for the integration kernel

The docstring clearly explains the velocity-space integration approach and its universal support for all joint types.


529-544: Clever use of jcalc_integrate for velocity-space updates

The implementation correctly treats the DOF update vector as acceleration with dt=1, effectively implementing velocity-space integration. This is an elegant solution that reuses existing Featherstone integration logic.


979-993: Efficient analytic Jacobian computation

The analytic Jacobian computation correctly uses motion subspace columns and properly handles world-space transformations for position objectives. The use of DOF masking with affects_dof is an efficient optimization.

Comment thread newton/sim/ik.py Outdated

@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 (1)
newton/sim/ik.py (1)

1286-1296: LGTM! The DOF-to-coordinate mapping is appropriately scoped.

Based on the retrieved learning, this 1:1 mapping is intentionally limited to joints where it makes sense (revolute, prismatic). Complex joints like ball/free joints with quaternion representations aren't expected to use joint limits.

🧹 Nitpick comments (3)
newton/tests/test_ik.py (1)

191-229: Consider adjusting the convergence threshold for free joints.

The convergence test for free joints uses a less strict error threshold (1e-3) compared to the planar test (1e-4), and requires more iterations (60 vs 40). While this may be appropriate given the increased complexity of free joints, consider documenting why different thresholds are necessary.

Add a comment explaining the rationale:

-        solver.solve(iterations=60)
+        # Free joints require more iterations and have a higher error tolerance
+        # due to their 6 DOF complexity (3 translation + 3 rotation)
+        solver.solve(iterations=60)
newton/examples/example_ik_interactive.py (1)

222-224: Document the purpose of the epsilon addition.

Adding 1e-3 to all joint angles for floating base models needs clarification. This could be to avoid singularities or numerical issues.

         if floating:
+            # Add small epsilon to avoid potential singularities in quaternion representation
             for i in range(len(articulation_builder.joint_q)):
                 articulation_builder.joint_q[i] += 1e-3
newton/sim/ik.py (1)

1154-1183: Verify joint limit behavior for large ranges.

The kernel treats ranges larger than 9.9e5 as "no limit", which seems like a magic number. Consider documenting this threshold or making it configurable.

Consider defining this as a constant:

+# Joint limit range threshold - ranges larger than this are treated as unbounded
+JOINT_LIMIT_UNBOUNDED_THRESHOLD = wp.constant(1e6)
+
 @wp.kernel
 def _limit_residuals(
     # ... parameters ...
 ):
     # ... code ...
-    # treat huge ranges as no limit
-    if upper - lower > 9.9e5:
+    # treat huge ranges as no limit
+    if upper - lower > JOINT_LIMIT_UNBOUNDED_THRESHOLD:
         return
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5b3640bd89c24da3bdee6e8ecfb253c01f5edda2 and 878bbaf1108221d051bf57018412441bf17adba1.

📒 Files selected for processing (3)
  • newton/examples/example_ik_interactive.py (14 hunks)
  • newton/sim/ik.py (26 hunks)
  • newton/tests/test_ik.py (5 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: dylanturpin
PR: newton-physics/newton#450
File: newton/sim/ik.py:1286-1296
Timestamp: 2025-07-21T19:11:04.055Z
Learning: In Newton's IK system, the JointLimitObjective class intentionally only handles joints where DOF count equals coordinate count (1-1 mapping). This is appropriate because joint limits are typically only meaningful for simple joint types like revolute and prismatic joints, not complex joints like ball or free joints where DOF count != coordinate count.
newton/examples/example_ik_interactive.py (2)

Learnt from: Kenny-Vilella
PR: #398
File: newton/examples/example_mujoco.py:352-352
Timestamp: 2025-07-14T03:57:29.670Z
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.

Learnt from: dylanturpin
PR: #450
File: newton/sim/ik.py:1286-1296
Timestamp: 2025-07-21T19:11:04.055Z
Learning: In Newton's IK system, the JointLimitObjective class intentionally only handles joints where DOF count equals coordinate count (1-1 mapping). This is appropriate because joint limits are typically only meaningful for simple joint types like revolute and prismatic joints, not complex joints like ball or free joints where DOF count != coordinate count.

newton/sim/ik.py (1)

Learnt from: dylanturpin
PR: #450
File: newton/sim/ik.py:1286-1296
Timestamp: 2025-07-21T19:11:04.055Z
Learning: In Newton's IK system, the JointLimitObjective class intentionally only handles joints where DOF count equals coordinate count (1-1 mapping). This is appropriate because joint limits are typically only meaningful for simple joint types like revolute and prismatic joints, not complex joints like ball or free joints where DOF count != coordinate count.

🧬 Code Graph Analysis (1)
newton/sim/ik.py (3)
newton/sim/state.py (1)
  • joint_dof_count (105-109)
newton/sim/builder.py (1)
  • joint_count (442-443)
newton/solvers/featherstone/kernels.py (2)
  • jcalc_integrate (406-537)
  • jcalc_motion (228-327)
⏰ 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 Unit Tests on AWS EC2 (Pull Request)
🔇 Additional comments (12)
newton/tests/test_ik.py (2)

29-30: LGTM!

The comment clearly distinguishes the planar 2-revolute baseline helper functions from the new free joint helpers.


65-102: LGTM!

The helper function correctly builds a model with a free joint followed by a revolute joint, which is essential for testing the velocity-space IK solver with complex joint types.

newton/examples/example_ik_interactive.py (4)

91-96: LGTM!

The variable renaming from num_links/num_coords to body_count/num_dofs correctly aligns with the IK solver's transition to DOF-based indexing.


208-224: LGTM! The joint offset adjustment is correct.

The conditional joint index offset (joint_q_offset = 0 if floating else -7) properly accounts for the 7 additional coordinates (3 position + 4 quaternion) present in floating base models.


269-273: LGTM! The coordinate system handling is well-designed.

The conditional logic correctly handles world coordinates for floating base models and local coordinates for fixed base models, maintaining consistency with the solver's expectations.


103-103: Initial pose copy for IK example is intentional
Copying model.joint_q into the solver’s initial guess ensures the IK routine starts from the URDF/MJCF–imported default configuration rather than an all-zero pose. This provides a more natural seed for interactive use. The test suite still explicitly zeroes joint arrays where needed, so no further changes are required.

newton/sim/ik.py (6)

78-79: LGTM!

The tile dimensions correctly use DOFs instead of coordinates, aligning with the velocity-space approach.


139-139: LGTM!

The zero velocity array qd_zero is appropriately initialized for FK evaluation when actual velocities aren't needed.


335-356: LGTM! The velocity-space integration is well-implemented.

The _integrate_dq method correctly:

  1. Launches the integration kernel for all joints across all problems
  2. Passes the velocity update dq_dof as the integration delta
  3. Zeros out the velocity array after integration to maintain consistency

479-544: Excellent implementation of velocity-space integration!

The _integrate_dq_dof kernel is well-designed:

  • Supports all joint types through jcalc_integrate
  • Correctly interprets dq_dof as a velocity update with dt integration
  • Proper thread indexing for parallel problem solving
  • Clear documentation of the integration approach

956-993: LGTM! The analytic position Jacobian correctly uses DOF indexing.

The kernel properly:

  • Iterates over DOFs instead of coordinates
  • Uses the affects_dof mask to skip irrelevant DOFs
  • Extracts motion subspace columns for velocity computation
  • Writes Jacobian entries at the correct DOF indices

1435-1461: LGTM! The rotation Jacobian correctly handles DOF-based computation.

The analytic rotation Jacobian kernel properly:

  • Uses DOF indexing throughout
  • Applies the affects_dof mask to skip irrelevant DOFs
  • Extracts only the angular velocity components from motion subspace
  • Correctly maps to Jacobian DOF columns

@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

♻️ Duplicate comments (1)
newton/sim/ik.py (1)

1286-1296: Appropriate DOF-to-coordinate mapping for joint limits.

The mapping correctly handles only joints where DOF count equals coordinate count, which aligns with the design intent that joint limits are meaningful only for simple joint types like revolute and prismatic joints.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5b3640bd89c24da3bdee6e8ecfb253c01f5edda2 and 878bbaf1108221d051bf57018412441bf17adba1.

📒 Files selected for processing (3)
  • newton/examples/example_ik_interactive.py (14 hunks)
  • newton/sim/ik.py (26 hunks)
  • newton/tests/test_ik.py (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • newton/tests/test_ik.py
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: dylanturpin
PR: newton-physics/newton#450
File: newton/sim/ik.py:1286-1296
Timestamp: 2025-07-21T19:11:04.055Z
Learning: In Newton's IK system, the JointLimitObjective class intentionally only handles joints where DOF count equals coordinate count (1-1 mapping). This is appropriate because joint limits are typically only meaningful for simple joint types like revolute and prismatic joints, not complex joints like ball or free joints where DOF count != coordinate count.
newton/examples/example_ik_interactive.py (1)

Learnt from: dylanturpin
PR: #450
File: newton/sim/ik.py:1286-1296
Timestamp: 2025-07-21T19:11:04.055Z
Learning: In Newton's IK system, the JointLimitObjective class intentionally only handles joints where DOF count equals coordinate count (1-1 mapping). This is appropriate because joint limits are typically only meaningful for simple joint types like revolute and prismatic joints, not complex joints like ball or free joints where DOF count != coordinate count.

newton/sim/ik.py (1)

Learnt from: dylanturpin
PR: #450
File: newton/sim/ik.py:1286-1296
Timestamp: 2025-07-21T19:11:04.055Z
Learning: In Newton's IK system, the JointLimitObjective class intentionally only handles joints where DOF count equals coordinate count (1-1 mapping). This is appropriate because joint limits are typically only meaningful for simple joint types like revolute and prismatic joints, not complex joints like ball or free joints where DOF count != coordinate count.

🧬 Code Graph Analysis (1)
newton/examples/example_ik_interactive.py (3)
newton/sim/model.py (1)
  • state (362-395)
newton/sim/state.py (2)
  • joint_coord_count (98-102)
  • joint_dof_count (105-109)
newton/sim/ik.py (2)
  • set_target_positions (1079-1086)
  • set_target_position (1070-1077)
⏰ 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 Unit Tests on AWS EC2 (Pull Request)
🔇 Additional comments (9)
newton/examples/example_ik_interactive.py (4)

75-75: LGTM! Clean implementation of floating base support.

The addition of the floating parameter is well-integrated throughout the initialization, properly propagated to model building, and follows consistent naming conventions.

Also applies to: 81-81, 96-96, 99-99


222-224: Verify the necessity of the epsilon offset for floating joints.

Adding a small epsilon (1e-3) to all joint angles when floating seems like a workaround. This could potentially mask underlying numerical issues or create unexpected initial poses.

Could you explain why this epsilon offset is necessary for floating base models? Consider documenting this requirement or investigating if there's a more principled approach.


269-273: Well-structured coordinate frame handling.

The conditional logic correctly manages target positions based on the floating mode - world coordinates for floating base, local coordinates for fixed base. The conversion is clean and the intent is clear.


398-404: Consistent coordinate transformation in dragging callbacks.

The position dragging logic correctly maintains the same coordinate frame convention as initialization - world space for floating base, local space for fixed base.

newton/sim/ik.py (5)

78-78: Clean refactoring to DOF-based dimensions.

The consistent replacement of coordinate-based dimensions with DOF-based dimensions throughout the solver initialization enables proper support for all joint types, including those where DOF count ≠ coordinate count (e.g., ball and free joints).

Also applies to: 83-84, 116-117, 139-139, 149-150


479-544: Excellent implementation of velocity-space integration.

The new integration kernel properly leverages Featherstone's jcalc_integrate to handle all joint types. The approach of treating dq_dof as acceleration with dt is mathematically sound and enables support for quaternion-based joints (ball, free) that were previously unsupported.


313-333: Well-implemented motion subspace computation.

The motion subspace computation correctly extracts the spatial motion vectors needed for analytic Jacobian calculations. Using jcalc_motion ensures compatibility with all joint types.

Also applies to: 546-594


1029-1030: Consistent DOF-based updates in PositionObjective.

The objective correctly updates all lookups and masks to use DOFs instead of coordinates. The affects_dof mask and dof_to_joint mapping ensure proper Jacobian sparsity.

Also applies to: 1033-1059, 1141-1142


1503-1504: Complete DOF-based refactoring in RotationObjective.

The rotation objective properly updates all DOF-related computations, maintaining consistency with the solver's new velocity-space approach.

Also applies to: 1509-1513, 1531-1532

Comment thread newton/examples/example_ik_interactive.py Outdated
@dylanturpin

Copy link
Copy Markdown
Member Author

Hi Eric. Wouldn't be the first time! But I think it's all there. Just changes to...

  • newton/tests/test_ik.py
  • newton/examples/example_ik_interactive.py
  • newton/sim/ik.py <-- the substantive stuff is here

Comment thread newton/sim/ik.py Outdated
Comment thread newton/tests/test_ik.py
Signed-off-by: Dylan Turpin <dylanturpin@gmail.com>

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

@eric-heiden eric-heiden enabled auto-merge (squash) August 1, 2025 08:24
@eric-heiden eric-heiden merged commit 154dbb1 into newton-physics:main Aug 1, 2025
11 checks passed
This was referenced Aug 22, 2025
eric-heiden added a commit to eric-heiden/newton that referenced this pull request Jan 28, 2026
…s#450)

Signed-off-by: Dylan Turpin <dylanturpin@gmail.com>
Co-authored-by: Eric Heiden <eheiden@nvidia.com>
@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
…ewton-physics#450)

# Description

Adds user guide on CloudXR Teleoperation on Kubernetes cluster.

## Type of change

- This change is a documentation update

## Screenshots

n/a

Did a proof read in a local build.

## 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
- [ ] 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
mmacklin pushed a commit to mmacklin/newton that referenced this pull request Apr 7, 2026
…s#450)

Signed-off-by: Dylan Turpin <dylanturpin@gmail.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.

2 participants