Skip to content

Use USD version of CartPole#564

Merged
eric-heiden merged 7 commits into
newton-physics:mainfrom
camevor:usd-example-cartpole
Aug 18, 2025
Merged

Use USD version of CartPole#564
eric-heiden merged 7 commits into
newton-physics:mainfrom
camevor:usd-example-cartpole

Conversation

@camevor

@camevor camevor commented Aug 18, 2025

Copy link
Copy Markdown
Member

Description

This change uses the USD version of CartPole in the CartPole example.
Resolves #567

Newton Migration Guide

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

  • New Features

    • Upgraded cart-pole scene to a two-pole layout with refined physics (masses, inertia, centers of mass), adjusted scales, and standardized units for more realistic behavior.
    • Added/updated joints to support the new two-pole configuration.
  • Chores

    • Examples now load the USD cart-pole asset and use the updated articulation name/path (cartPole) and structure; behavior and configuration remain otherwise consistent.

Signed-off-by: camevor <camevor@nvidia.com>
@camevor camevor requested a review from eric-heiden August 18, 2025 09:15
@coderabbitai

coderabbitai Bot commented Aug 18, 2025

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Refactors the cart-pole USD scene to CamelCase paths, Xform-wrapped bodies, adds a second pole, renames/updates joints and physics properties, and sets kilogramsPerUnit. Updates examples to load the USD asset via parse_usd instead of the previous URDF parse_urdf.

Changes

Cohort / File(s) Summary of changes
USD asset restructuring
newton/examples/assets/cartpole.usda
Renames defaultPrim to cartPole and sets kilogramsPerUnit=1; converts top-level rail/cart/pole Cube defs into Xform wrappers with nested collision Cubes; adds pole2; updates scales/transforms; adds mass/inertia/centerOfMass and PhysicsMassAPI on moving bodies; renames and adds joints (rootJoint path updates, railCartJoint, cartPoleJoint, polePoleJoint) and updates body references to /cartPole/....
Example loader switches
newton/examples/example_cartpole.py, newton/examples/example_mujoco.py, newton/examples/example_selection_cartpole.py
Replace newton.utils.parse_urdf(... cartpole.urdf ...) calls with newton.utils.parse_usd(... cartpole.usda ...); remove the previously passed floating=False/up_axis arguments where not applicable; update articulation lookup paths from /cartpole to /cartPole.

Sequence Diagram(s)

sequenceDiagram
  participant Example as Example code
  participant Assets as Assets (cartpole.usda)
  participant Parser as newton.utils.parse_usd
  participant Builder as ArticulationBuilder
  participant Scene as Simulation/Stage

  Example->>Assets: get_asset("cartpole.usda")
  Example->>Parser: parse_usd(asset_path, builder, opts)
  Parser->>Builder: emit bodies, joints, physics metadata
  Builder->>Scene: instantiate articulation at /cartPole
  Scene-->>Example: ready articulation (joints/bodies accessible)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

Possibly related PRs

Suggested reviewers

  • eric-heiden
  • Milad-Rakhsha-NV
  • adenzler-nvidia

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.

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

🧹 Nitpick comments (5)
newton/examples/assets/cartpole.usda (2)

92-113: Nested Cube under pole2 is misnamed "pole1" — rename for consistency

The nested Gprim under Xform "pole2" is currently named "pole1". While unique by full path, this is confusing and error-prone.

Apply this rename:

-        def Cube "pole1" (
+        def Cube "pole2" (
             prepend apiSchemas = ["PhysicsCollisionAPI"]
         )

129-138: Verify hinge anchor placement for cart-pole joint

localPos0 on the cart is set to (0.55, 0.0, 0), which places the hinge well outside the cart’s 0.2 length along X. Typically, the pole should hinge at the top center of the cart, i.e., around (0, 0, +half_cart_height). Consider moving the anchor to the cart’s top face.

Proposed adjustment:

-        point3f physics:localPos0 = (0.55, 0.0, 0)
+        # Hinge at the top center of the cart (cart scale along Z is 0.2 => half-height ~0.1)
+        point3f physics:localPos0 = (0.0, 0.0, 0.1)

Please verify visually/simulation-wise and tweak as needed to avoid initial interpenetration.

newton/examples/example_cartpole.py (3)

19-22: Update comment to reflect USD-based import (not URDF)

The example now loads from USD. Adjust the comment to prevent confusion.

-# from a URDF using newton.ModelBuilder().
+# from a USD stage using newton.ModelBuilder().

42-47: Switch to parse_usd is correct; consider applying stage up-axis automatically

The call looks good. Optionally pass apply_up_axis_from_stage=True to honor the stage’s upAxis (Z) in environments where the default differs.

-        newton.utils.parse_usd(
+        newton.utils.parse_usd(
             newton.examples.get_asset("cartpole.usda"),
             articulation_builder,
-            enable_self_collisions=False,
-            collapse_fixed_joints=True,
+            enable_self_collisions=False,
+            collapse_fixed_joints=True,
+            apply_up_axis_from_stage=True,
         )

63-65: Assumes exactly three joints per env; consider making this resilient to asset changes

Setting builder.joint_q[-3:] works with the current asset (prismatic + two revolutes). If the USD changes joint count/order, this will silently misinitialize. If available, prefer targeting joints by name/path via the importer’s mappings or by capturing joint indices at import time.

I can help wire this to importer-returned mappings or generate a small utility to resolve joint indices by path. Want me to draft that?

📜 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 11a7403 and f699461.

📒 Files selected for processing (2)
  • newton/examples/assets/cartpole.usda (2 hunks)
  • newton/examples/example_cartpole.py (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
newton/examples/example_cartpole.py (2)
newton/utils/import_usd.py (1)
  • parse_usd (34-1269)
newton/examples/__init__.py (1)
  • get_asset (31-32)
⏰ 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)
🔇 Additional comments (7)
newton/examples/assets/cartpole.usda (7)

7-11: Stage metrics and defaultPrim look correct

defaultPrim set to "cartPole" and kilogramsPerUnit added with metersPerUnit=1, upAxis="Z" — good choices and consistent.


26-31: Articulation root setup is appropriate

PhysicsArticulationRootAPI + PhysxArticulationAPI on /cartPole with self-collisions disabled matches the intended articulated rig.


32-45: Rail body/collision split LGTM

RigidBodyAPI is on the Xform and CollisionAPI on the nested Cube. This is the right pattern for separating body from shape. Fixed joint to world below completes the static base.


69-91: Pole1 mass properties correctly authored on the rigid body

PhysicsMassAPI is on the Xform and mass/inertia live there; CollisionAPI is on the nested Cube. Consistent and correct.


114-118: Fixed joint to world is fine

Referencing only body1 for PhysicsFixedJoint is valid to attach /cartPole/rail to world.


120-127: Prismatic joint setup LGTM

Axis along Y matches the rail scale (0.03, 8, 0.03) and limits [-4, 4] align with the track length.


140-149: Second pole joint looks correct

Hinge axis, local positions, and rotations are consistent with linking the tips of pole1 and pole2.

Comment thread newton/examples/assets/cartpole.usda
Signed-off-by: camevor <camevor@nvidia.com>
Signed-off-by: camevor <camevor@nvidia.com>
@camevor camevor marked this pull request as ready for review August 18, 2025 09:48

@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/examples/assets/cartpole.usda (1)

47-66: Mass/inertia moved to the body prim; color moved to the geom — exactly right

This addresses prior feedback about placing mass properties on the rigid body prim (Xform with PhysicsMassAPI) and visual color on the mesh prim. Thanks for fixing this.

🧹 Nitpick comments (4)
newton/examples/example_mujoco.py (1)

148-153: Minor: consider clarifying the “root pose” comment to “initial joint state”

Given this is a fixed-base articulation, the values immediately after parsing represent the cart prismatic DOF and the two pole angles, not a free-base root pose. Renaming the comment will prevent future confusion.

newton/examples/assets/cartpole.usda (3)

26-45: Articulation root and rail structure are reasonable

Using PhysicsArticulationRootAPI with a fixed joint to world via the rail is valid. The rail being an Xform with a Collision-only child is consistent with a static base.

If you intend the rail to be fully static, you can drop PhysicsRigidBodyAPI from the rail Xform to make that intent explicit and rely on the FixedJoint-to-world. Not critical, but can reduce ambiguity for consumers that infer dynamics from APIs.


55-58: Nit: replace tabs with spaces for consistency

There are a few lines indented with tabs; the rest uses spaces. While USD is whitespace-agnostic, mixed indentation can trip formatters and reviews.

Apply:

-		float3 physics:diagonalInertia = (0.1, 0.1, 0.1)
-		float physics:mass = 1
-		quatf physics:principalAxes = (1, 0, 0, 0)
+        float3 physics:diagonalInertia = (0.1, 0.1, 0.1)
+        float physics:mass = 1
+        quatf physics:principalAxes = (1, 0, 0, 0)
@@
-			color3f[] primvars:displayColor = [(0.3, 0.5, 0.7)]
+            color3f[] primvars:displayColor = [(0.3, 0.5, 0.7)]

Also applies to: 64-64


128-137: Cart–pole joint frames: please double-check anchor placement

The pole rotates about X, which is fine, but the cart anchor at (0.55, 0, 0) seems offset along X far beyond the cart’s half-extent (scale X=0.2). If this isn’t by design, consider moving the anchor near the cart’s top center and adjusting localPos1 accordingly.

📜 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 f699461 and d60f20f.

📒 Files selected for processing (4)
  • newton/examples/assets/cartpole.usda (2 hunks)
  • newton/examples/example_cartpole.py (2 hunks)
  • newton/examples/example_mujoco.py (1 hunks)
  • newton/examples/example_selection_cartpole.py (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • newton/examples/example_cartpole.py
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-12T18:07:17.267Z
Learnt from: nvlukasz
PR: newton-physics/newton#519
File: newton/utils.py:30-33
Timestamp: 2025-08-12T18:07:17.267Z
Learning: In newton/_src/utils/import_usd.py, the PXR/USD modules are lazily loaded using try-except blocks within the functions rather than at module import time, making it safe to import parse_usd at the module level without causing import-time failures for users without USD dependencies.

Applied to files:

  • newton/examples/example_selection_cartpole.py
📚 Learning: 2025-08-12T18:07:17.267Z
Learnt from: nvlukasz
PR: newton-physics/newton#519
File: newton/utils.py:30-33
Timestamp: 2025-08-12T18:07:17.267Z
Learning: In newton/_src/utils/import_usd.py, the PXR/USD modules are lazily loaded using try-except blocks within the functions (lines 109-111 and 1289-1291) rather than at module import time, making it safe to import parse_usd at the module level without causing import-time failures for users without USD dependencies.

Applied to files:

  • newton/examples/example_selection_cartpole.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 (8)
newton/examples/example_mujoco.py (1)

148-153: All CartPole examples now use the USD asset

Searches confirmed there are no parse_urdf calls loading cartpole.urdf in any example, and all CartPole examples (example_cartpole.py, example_mujoco.py, example_selection_cartpole.py) correctly invoke parse_usd with "cartpole.usda".

newton/examples/example_selection_cartpole.py (2)

89-89: ArticulationView path update to “/cartPole” is correct

Matches defaultPrim and root path in the USD asset; this will select the intended articulation(s).


56-62: All CartPole examples & tests correctly use the USD asset
Verified that:

  • example_selection_cartpole.py calls parse_usd(..., "cartpole.usda", …) with the proper flags and uses ArticulationView(self.model, "/cartPole", …).
  • example_cartpole.py and example_mujoco.py also reference cartpole.usda in their parse_usd calls.
  • test_examples.py includes both example_cartpole and example_selection_cartpole.

No further changes needed here.

newton/examples/assets/cartpole.usda (5)

7-10: Good: units and defaultPrim explicitly set

Adding kilogramsPerUnit=1 and renaming defaultPrim to "cartPole" improves clarity and loader consistency.


68-89: Pole1 body/geom and mass properties look correct

PhysicsMassAPI on the body and CollisionAPI on the child geom is aligned with USD physics conventions. Center of mass at the body origin matches your joint frames.


91-112: Addition of pole2 and its mass/inertia is consistent with pole1

The second pole mirrors pole1 and enables a double-pendulum configuration via the new joint below.


119-126: Verify prismatic axis and limits against intended motion direction

Axis is set to "Y" with limits -4..4. The rail geometry also stretches along Y, so this is self-consistent, but it differs from the common X-axis convention for CartPole. Please confirm this is intentional for your coordinate system.


139-148: Pole–pole joint addition looks good

Frames are consistent (top of pole1 to bottom of pole2) and axis matches the first hinge, enabling a double pendulum.

@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/examples/assets/cartpole.usda (1)

47-66: Mass properties correctly moved to the body Xform; color authored on the mesh

This addresses the earlier review about mass/inertia being on the shape. The body now carries PhysicsMassAPI attributes and the Cube carries displayColor — parsers will pick these up as intended.

🧹 Nitpick comments (4)
newton/examples/assets/cartpole.usda (3)

55-58: Nit: mixed tabs/spaces — standardize indentation

The lines authoring physics:diagonalInertia/mass/principalAxes and primvars:displayColor use tabs, while the rest of the file uses spaces. Standardize to spaces to avoid diffs/noise across editors.

Apply this whitespace-only diff:

-		float3 physics:diagonalInertia = (0.1, 0.1, 0.1)
-		float physics:mass = 1
-		quatf physics:principalAxes = (1, 0, 0, 0)
+        float3 physics:diagonalInertia = (0.1, 0.1, 0.1)
+        float physics:mass = 1
+        quatf physics:principalAxes = (1, 0, 0, 0)
@@
-			color3f[] primvars:displayColor = [(0.3, 0.5, 0.7)]
+            color3f[] primvars:displayColor = [(0.3, 0.5, 0.7)]

Also applies to: 64-64


128-137: Hinge anchor likely misplaced (localPos0 is along X, not Z/top of cart)

For a standard cart-pole, the hinge sits on the cart’s top face (Z half-extent), not offset along X. With cart scale z = 0.2, half-height is 0.1. Recommend moving the hinge anchor on the cart to z = +0.1.

Proposed fix:

 def PhysicsRevoluteJoint "cartPoleJoint"
 {
     rel physics:body0 = </cartPole/cart>
     rel physics:body1 = </cartPole/pole1>
     uniform token physics:axis = "X"
-    point3f physics:localPos0 = (0.55, 0.0, 0)
+    point3f physics:localPos0 = (0, 0, 0.1)
     point3f physics:localPos1 = (0, 0, -0.5)
     quatf physics:localRot0 = (1, 0, 0, 0)
     quatf physics:localRot1 = (1, 0, 0, 0)
 }

Please verify in the viewer that the pole bottom (localPos1 = (0,0,-0.5)) now meets the cart top without gaps/overlap, and that the swing plane remains about the X axis.


55-58: Consider letting the importer compute inertia from mass and geometry

The diagonalInertia/principalAxes are currently hard-coded and may not match the actual geometry scales and masses (e.g., poles at 0.25 kg with 1 m length). To avoid incorrect dynamics, either compute physically correct box inertia or omit these attributes so the importer computes inertia from shapes.

Option A (simplest): remove explicit inertia/axes so they’re derived:

@@
-        float3 physics:diagonalInertia = (0.1, 0.1, 0.1)
-        float physics:mass = 1
-        quatf physics:principalAxes = (1, 0, 0, 0)
+        float physics:mass = 1
@@
-        float3 physics:diagonalInertia = (0.1, 0.1, 0.1)
-        float physics:mass = 0.25
-        quatf physics:principalAxes = (1, 0, 0, 0)
+        float physics:mass = 0.25
@@
-        float3 physics:diagonalInertia = (0.1, 0.1, 0.1)
-        float physics:mass = 0.25
-        quatf physics:principalAxes = (1, 0, 0, 0)
+        float physics:mass = 0.25

Option B: if you want explicit inertia, I can provide the closed-form box inertia values matching your scales and masses.

Also applies to: 76-80, 99-103

newton/examples/example_mujoco.py (1)

148-153: Recommend aligning builder’s up‐axis with the USD stage

The USD file declares upAxis="Z", whereas ModelBuilder’s default is Y-up. To avoid unexpected rotations when loading Z-up stages, enable apply_up_axis_from_stage in the parse_usd call:

 newton.utils.parse_usd(
     newton.examples.get_asset("cartpole.usda"),
     articulation_builder,
     enable_self_collisions=False,
     collapse_fixed_joints=True,
+    apply_up_axis_from_stage=True,
 )

(optional — improves robustness when importing Z-up USD assets)

📜 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 f699461 and d60f20f.

📒 Files selected for processing (4)
  • newton/examples/assets/cartpole.usda (2 hunks)
  • newton/examples/example_cartpole.py (2 hunks)
  • newton/examples/example_mujoco.py (1 hunks)
  • newton/examples/example_selection_cartpole.py (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • newton/examples/example_cartpole.py
🧰 Additional context used
🧬 Code Graph Analysis (2)
newton/examples/example_mujoco.py (2)
newton/_src/utils/import_usd.py (1)
  • parse_usd (34-1274)
newton/examples/__init__.py (1)
  • get_asset (31-32)
newton/examples/example_selection_cartpole.py (2)
newton/_src/utils/import_usd.py (1)
  • parse_usd (34-1274)
newton/examples/__init__.py (1)
  • get_asset (31-32)
🔇 Additional comments (5)
newton/examples/assets/cartpole.usda (2)

7-11: Units and defaultPrim metadata look correct

Switching defaultPrim to "cartPole" and explicitly authoring kilogramsPerUnit = 1 aligns the stage with importer expectations and avoids unit ambiguity.


32-45: Good separation of body and shape for the rail

Wrapping the visual/collision Cube under an Xform with PhysicsRigidBodyAPI and keeping PhysicsCollisionAPI only on the Cube is the right pattern for rigid bodies in USD physics.

newton/examples/example_mujoco.py (1)

148-153: Switch to USD loader for CartPole — looks good

Replacing parse_urdf with parse_usd and pointing to cartpole.usda matches the asset changes and articulation path updates in this PR.

newton/examples/example_selection_cartpole.py (2)

56-62: USD migration call is consistent and minimal

Switching to parse_usd with the USD asset and keeping collapse_fixed_joints/enable_self_collisions mirrors other examples and the stage settings. With ModelBuilder(up_axis=Z) and stage upAxis=Z, no extra axis handling is needed.


89-89: ArticulationView path updated to “/cartPole” — correct

Matches the defaultPrim and articulation root in the USD stage.

@eric-heiden eric-heiden enabled auto-merge (squash) August 18, 2025 12:41
@eric-heiden eric-heiden merged commit d312edd into newton-physics:main Aug 18, 2025
11 checks passed
@camevor camevor deleted the usd-example-cartpole branch August 18, 2025 16:09
@coderabbitai coderabbitai Bot mentioned this pull request Aug 20, 2025
5 tasks
mzamoramora-nvidia pushed a commit to MiguelZamoraM/newton that referenced this pull request Aug 20, 2025
Signed-off-by: camevor <camevor@nvidia.com>
Co-authored-by: Eric Heiden <eheiden@nvidia.com>
Signed-off-by: Miguel Zamora <mazamoramora@nvidia.com>
eric-heiden added a commit to eric-heiden/newton that referenced this pull request Jan 28, 2026
Signed-off-by: camevor <camevor@nvidia.com>
Co-authored-by: Eric Heiden <eheiden@nvidia.com>
@coderabbitai coderabbitai Bot mentioned this pull request Feb 26, 2026
@coderabbitai coderabbitai Bot mentioned this pull request Mar 11, 2026
3 tasks
mmacklin pushed a commit to mmacklin/newton that referenced this pull request Apr 7, 2026
Signed-off-by: camevor <camevor@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.

Port cart-pole example to USD

2 participants