Add example tests#836
Conversation
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
📝 WalkthroughWalkthroughAdds two Warp-agnostic vector helpers (vec_allclose, vec_inside_limits); introduces example-level testing (CLI --test, test_body_state/test_particle_state) with NaN/non-finite checks; updates many examples to forward CLI args into run(example, args) and to include concrete test implementations; extends test helpers and example registrations. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User as CLI
participant Runner as newton.examples.run
participant Tests as newton.tests.unittest_utils
participant Example as Example
participant Kernel as test_body_state/test_particle_state
User->>Runner: run(example, args)
Runner->>Runner: parse args / configure
alt --test mode
Runner->>Tests: find_nan_members(state_0,state_1,model,control,contacts)
Tests-->>Runner: list of offending members
alt offending members found
Runner->>User: raise descriptive ValueError (bad members)
else
Runner->>Example: Example.test()
Example->>Kernel: run per-entity tests (test_body_state/test_particle_state)
Kernel-->>Example: per-entity pass/fail
alt failures
Example->>Runner: raise ValueError with failing indices/names
end
end
else normal mode
Runner->>Example: enter simulation/render loop
end
Runner-->>User: exit
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests
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. Comment |
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
There was a problem hiding this comment.
Actionable comments posted: 11
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
newton/tests/test_examples.py (1)
1-1: Disable viewer for cloth.example_cloth_bending test
In newton/tests/test_examples.py, update the add_example_test call forcloth.example_cloth_bendingtouse_viewer=False(headless CI environments cannot launch the viewer).
🧹 Nitpick comments (14)
newton/examples/basic/example_basic_urdf.py (1)
128-144: Fix unused lambda parameters in test functions.The lambda functions in your test cases have unused parameters that static analysis tools are flagging. This is a common pattern in callback functions where not all parameters are always used.
Apply this diff to fix the unused parameter warnings:
- lambda q, qd: max(abs(qd)) < 0.1, + lambda q, qd: max(abs(qd)) < 0.1,- lambda q, qd: wp.abs(q[2] - 0.48) < 0.01, + lambda _, qd: wp.abs(_[2] - 0.48) < 0.01,Or alternatively, you can prefix unused parameters with underscore:
- lambda q, qd: max(abs(qd)) < 0.1, + lambda _q, qd: max(abs(qd)) < 0.1,- lambda q, qd: wp.abs(q[2] - 0.48) < 0.01, + lambda q, _qd: wp.abs(q[2] - 0.48) < 0.01,newton/examples/basic/example_basic_pendulum.py (1)
125-148: Enhance test robustness and fix unused lambda parameter.The test logic is comprehensive but could be improved for clarity and the unused parameter should be addressed.
Apply this diff to fix the unused parameter and improve readability:
- lambda q, qd: abs(q[0]) < 1e-5 and abs(q[1]) < 1.0 and q[2] < 5.0 and q[2] > 0.0, + lambda q, _qd: abs(q[0]) < 1e-5 and abs(q[1]) < 1.0 and q[2] < 5.0 and q[2] > 0.0,Consider splitting the position check into more granular tests for better error reporting:
newton.examples.test_body_state( self.model, self.state_0, - "pendulum links in correct area", - lambda q, _qd: abs(q[0]) < 1e-5 and abs(q[1]) < 1.0 and q[2] < 5.0 and q[2] > 0.0, + "pendulum links positioned correctly", + lambda q, _qd: abs(q[0]) < 1e-5 and abs(q[1]) < 1.0 and 0.0 < q[2] < 5.0, [0, 1], )newton/examples/robot/example_robot_cartpole.py (4)
113-120: Use tolerance for comparisons and silence unused arg.Exact equality on floats (
q[2] == 0.0) is brittle in Warp; prefer a small tolerance. Also, rename unusedqdto_.- newton.examples.test_body_state( + newton.examples.test_body_state( self.model, self.state_0, "cart is at ground level and has correct orientation", - lambda q, qd: q[2] == 0.0 and newton.utils.vec_allclose(q.q, wp.quat_identity()), + lambda q, _: wp.abs(q[2]) <= 1.0e-4 and newton.utils.vec_allclose(q.q, wp.quat_identity()), indices=[i * num_bodies_per_env for i in range(self.num_envs)], )Please confirm
q[2]is indeed the ground-axis for this example (z). If y is up, adjust accordingly. Based on learnings.
131-142: Apply Warp ops and tolerances to pole1 test.Same reasons as above; replace Python
absand exact zero.- lambda q, qd: qd[0] == 0.0 - and abs(qd[1]) > 0.05 - and qd[2] == 0.0 - and abs(qd[3]) > 0.3 - and qd[4] == 0.0 - and qd[5] == 0.0, + lambda _, qd: wp.abs(qd[0]) <= 1.0e-6 + and wp.abs(qd[1]) > 0.05 + and wp.abs(qd[2]) <= 1.0e-6 + and wp.abs(qd[3]) > 0.3 + and wp.abs(qd[4]) <= 1.0e-6 + and wp.abs(qd[5]) <= 1.0e-6,Confirm index semantics (linear vs angular ordering) to ensure each constraint targets the intended component.
143-154: Apply Warp ops and tolerances to pole2 test.Consistent with prior tests; replace Python
absand exact zero.- lambda q, qd: qd[0] == 0.0 - and abs(qd[1]) > 0.05 - and abs(qd[2]) > 0.05 - and abs(qd[3]) > 0.2 - and qd[4] == 0.0 - and qd[5] == 0.0, + lambda _, qd: wp.abs(qd[0]) <= 1.0e-6 + and wp.abs(qd[1]) > 0.05 + and wp.abs(qd[2]) > 0.05 + and wp.abs(qd[3]) > 0.2 + and wp.abs(qd[4]) <= 1.0e-6 + and wp.abs(qd[5]) <= 1.0e-6,Same note about spatial vector ordering applies.
155-179: Silence unused-arg lint in cross-env comparisons.Rename
qto_in lambdas; no behavior change.- lambda q, qd: newton.utils.vec_allclose(qd, env0_cart_vel), + lambda _, qd: newton.utils.vec_allclose(qd, env0_cart_vel), ... - lambda q, qd: newton.utils.vec_allclose(qd, env0_pole1_vel), + lambda _, qd: newton.utils.vec_allclose(qd, env0_pole1_vel), ... - lambda q, qd: newton.utils.vec_allclose(qd, env0_pole2_vel), + lambda _, qd: newton.utils.vec_allclose(qd, env0_pole2_vel),newton/examples/cloth/example_cloth_hanging.py (1)
187-201: Silence unused-arg lint and prefer Warp ops in tests.Rename unused lambda args to
_to satisfy Ruff ARG005. Current comparisons are fine otherwise.- newton.examples.test_particle_state( - self.state_0, - "particles are above the ground", - lambda q, qd: q[2] > 0.0, - ) + newton.examples.test_particle_state( + self.state_0, + "particles are above the ground", + lambda q, _: q[2] > 0.0, + ) ... - newton.examples.test_particle_state( - self.state_0, - "particles are within a reasonable volume", - lambda q, qd: newton.utils.vec_inside_limits(q, wp.vec3(min_x, -4.0, -1.8), wp.vec3(0.0, 7.0, 4.0)), - ) + newton.examples.test_particle_state( + self.state_0, + "particles are within a reasonable volume", + lambda q, _: newton.utils.vec_inside_limits(q, wp.vec3(min_x, -4.0, -1.8), wp.vec3(0.0, 7.0, 4.0)), + )newton/_src/utils/__init__.py (1)
199-219: Vector utils are Warp-safe and broadly reusable.
vec_allcloseandvec_inside_limitsusewp.static(len(a))andwp.abs, making them suitable within Warp kernels andcreate_warp_functioncontexts.Optional: add a helper for sup-norm to avoid ad hoc patterns like
max(abs(v))in tests:
@wp.func def vec_max_abs(a): return leaky_max(leaky_max(wp.abs(a[0]), wp.abs(a[1])), wp.abs(a[2]))(extend to 6D if needed).newton/examples/cloth/example_cloth_franka.py (1)
42-48: Remove unused localallclose(dead code).This duplicates
newton.utils.vec_allcloseand isn’t used.Apply outside the changed hunk:
-def allclose(a: wp.vec3, b: wp.vec3, rtol=1e-5, atol=1e-8): - return ( - wp.abs(a[0] - b[0]) <= (atol + rtol * wp.abs(b[0])) - and wp.abs(a[1] - b[1]) <= (atol + rtol * wp.abs(b[1])) - and wp.abs(a[2] - b[2]) <= (atol + rtol * wp.abs(b[2])) - )newton/tests/test_examples.py (2)
27-27: Add import of importlib to the imports section.The import statement is correctly placed but should be moved to the standard imports section at the top of the file for better organization and consistency with Python conventions.
91-91: Minor: Consider using a custom exception class.While the current approach works, consider creating a custom exception class for better error categorization and handling.
Based on static analysis hints
newton/examples/basic/example_basic_shapes.py (1)
143-143: Consider using the velocity parameter in test functions.The lambda functions in the test cases accept a
qdparameter (velocity) but don't use it. While this is functionally correct, you might consider either using the velocity in the tests or explicitly ignoring it to improve code clarity.Based on static analysis hints
If velocity isn't needed, you could make it explicit:
- lambda q, qd: newton.utils.vec_allclose(q, sphere_q, atol=1e-4), + lambda q, _: newton.utils.vec_allclose(q, sphere_q, atol=1e-4),Also applies to: 151-151, 159-159, 167-167
newton/examples/__init__.py (2)
384-384: Update all export list.The
__all__list should also includetest_particle_statesince it's a public utility function that users might want to import directly.Apply this diff:
-__all__ = ["create_parser", "init", "run", "test_body_state"] +__all__ = ["create_parser", "init", "run", "test_body_state", "test_particle_state"]
103-103: Consider custom exception classes for better error categorization.While the current string-based error messages are functional, consider creating custom exception classes for better error handling and categorization in testing frameworks.
Based on static analysis hints
Also applies to: 158-158, 183-183, 187-187, 191-191, 195-195, 199-199
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (40)
newton/_src/utils/__init__.py(3 hunks)newton/examples/__init__.py(5 hunks)newton/examples/__main__.py(1 hunks)newton/examples/basic/example_basic_joints.py(5 hunks)newton/examples/basic/example_basic_pendulum.py(3 hunks)newton/examples/basic/example_basic_shapes.py(5 hunks)newton/examples/basic/example_basic_urdf.py(3 hunks)newton/examples/basic/example_basic_viewer.py(1 hunks)newton/examples/cloth/example_cloth_bending.py(2 hunks)newton/examples/cloth/example_cloth_franka.py(3 hunks)newton/examples/cloth/example_cloth_hanging.py(4 hunks)newton/examples/cloth/example_cloth_style3d.py(2 hunks)newton/examples/cloth/example_cloth_twist.py(3 hunks)newton/examples/diffsim/example_diffsim_ball.py(1 hunks)newton/examples/diffsim/example_diffsim_cloth.py(1 hunks)newton/examples/diffsim/example_diffsim_drone.py(1 hunks)newton/examples/diffsim/example_diffsim_soft_body.py(1 hunks)newton/examples/diffsim/example_diffsim_spring_cage.py(1 hunks)newton/examples/example_replay_viewer.py(1 hunks)newton/examples/ik/example_ik_franka.py(1 hunks)newton/examples/ik/example_ik_h1.py(1 hunks)newton/examples/mpm/example_mpm_anymal.py(1 hunks)newton/examples/mpm/example_mpm_grain_rendering.py(1 hunks)newton/examples/mpm/example_mpm_granular.py(1 hunks)newton/examples/mpm/example_mpm_multi_material.py(1 hunks)newton/examples/robot/example_robot_allegro_hand.py(1 hunks)newton/examples/robot/example_robot_anymal_c_walk.py(1 hunks)newton/examples/robot/example_robot_anymal_d.py(2 hunks)newton/examples/robot/example_robot_cartpole.py(2 hunks)newton/examples/robot/example_robot_g1.py(2 hunks)newton/examples/robot/example_robot_h1.py(2 hunks)newton/examples/robot/example_robot_humanoid.py(1 hunks)newton/examples/robot/example_robot_policy.py(1 hunks)newton/examples/robot/example_robot_ur10.py(1 hunks)newton/examples/selection/example_selection_articulations.py(1 hunks)newton/examples/selection/example_selection_cartpole.py(1 hunks)newton/examples/selection/example_selection_materials.py(1 hunks)newton/examples/sensors/example_sensor_contact.py(1 hunks)newton/tests/test_examples.py(9 hunks)newton/utils.py(2 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-08-25T21:41:45.795Z
Learnt from: dylanturpin
PR: newton-physics/newton#634
File: newton/tests/test_examples.py:329-333
Timestamp: 2025-08-25T21:41:45.795Z
Learning: Newton examples use a centralized CLI argument parsing system in newton/examples/__init__.py. The create_parser() function defines common arguments like --device, --viewer, --output-path, and --num-frames, while init(parser) creates viewers based on parsed arguments. Individual example scripts don't need to define these flags themselves - they inherit them from the centralized system via the example_map and runpy execution.
Applied to files:
newton/examples/sensors/example_sensor_contact.pynewton/examples/robot/example_robot_policy.pynewton/examples/example_replay_viewer.pynewton/examples/mpm/example_mpm_granular.pynewton/examples/diffsim/example_diffsim_cloth.pynewton/examples/selection/example_selection_cartpole.pynewton/examples/diffsim/example_diffsim_drone.pynewton/examples/selection/example_selection_materials.pynewton/examples/mpm/example_mpm_multi_material.pynewton/examples/robot/example_robot_allegro_hand.pynewton/examples/mpm/example_mpm_anymal.pynewton/examples/diffsim/example_diffsim_ball.pynewton/examples/robot/example_robot_h1.pynewton/examples/robot/example_robot_humanoid.pynewton/examples/diffsim/example_diffsim_soft_body.pynewton/examples/cloth/example_cloth_style3d.pynewton/examples/robot/example_robot_anymal_d.pynewton/examples/robot/example_robot_cartpole.pynewton/examples/basic/example_basic_joints.pynewton/examples/mpm/example_mpm_grain_rendering.pynewton/examples/cloth/example_cloth_bending.pynewton/examples/ik/example_ik_franka.pynewton/examples/selection/example_selection_articulations.pynewton/examples/basic/example_basic_viewer.pynewton/examples/cloth/example_cloth_twist.pynewton/examples/__main__.pynewton/examples/robot/example_robot_ur10.pynewton/examples/basic/example_basic_pendulum.pynewton/examples/robot/example_robot_g1.pynewton/examples/ik/example_ik_h1.pynewton/examples/basic/example_basic_urdf.pynewton/examples/cloth/example_cloth_franka.pynewton/examples/__init__.pynewton/examples/basic/example_basic_shapes.pynewton/examples/diffsim/example_diffsim_spring_cage.py
📚 Learning: 2025-08-27T19:05:44.697Z
Learnt from: Milad-Rakhsha-NV
PR: newton-physics/newton#535
File: newton/tests/test_examples.py:320-414
Timestamp: 2025-08-27T19:05:44.697Z
Learning: In newton/examples/__init__.py, the robot policy example is registered with the key "robot_policy" (not "robot.example_robot_policy"), so tests should reference it as name="robot_policy".
Applied to files:
newton/examples/robot/example_robot_policy.pynewton/examples/robot/example_robot_h1.pynewton/examples/robot/example_robot_anymal_d.pynewton/examples/robot/example_robot_ur10.pynewton/tests/test_examples.pynewton/examples/robot/example_robot_g1.py
📚 Learning: 2025-08-12T18:04:06.577Z
Learnt from: nvlukasz
PR: newton-physics/newton#519
File: newton/_src/solvers/featherstone/kernels.py:75-75
Timestamp: 2025-08-12T18:04:06.577Z
Learning: The Newton physics framework requires nightly Warp builds, which means compatibility concerns with older stable Warp versions (like missing functions such as wp.spatial_adjoint) are not relevant for this project.
Applied to files:
newton/examples/basic/example_basic_urdf.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 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/examples/basic/example_basic_urdf.py
🧬 Code graph analysis (36)
newton/examples/sensors/example_sensor_contact.py (1)
newton/examples/__init__.py (1)
run(161-199)
newton/examples/robot/example_robot_policy.py (2)
newton/tests/test_examples.py (1)
run(100-204)newton/examples/__init__.py (1)
run(161-199)
newton/examples/mpm/example_mpm_granular.py (1)
newton/examples/__init__.py (1)
run(161-199)
newton/examples/diffsim/example_diffsim_cloth.py (2)
newton/tests/test_examples.py (1)
run(100-204)newton/examples/__init__.py (1)
run(161-199)
newton/examples/selection/example_selection_cartpole.py (1)
newton/examples/__init__.py (1)
run(161-199)
newton/examples/diffsim/example_diffsim_drone.py (1)
newton/examples/__init__.py (1)
run(161-199)
newton/examples/selection/example_selection_materials.py (2)
newton/tests/test_examples.py (1)
run(100-204)newton/examples/__init__.py (1)
run(161-199)
newton/examples/mpm/example_mpm_multi_material.py (1)
newton/tests/test_examples.py (1)
run(100-204)
newton/examples/robot/example_robot_allegro_hand.py (1)
newton/tests/test_examples.py (1)
run(100-204)
newton/examples/mpm/example_mpm_anymal.py (2)
newton/tests/test_examples.py (1)
run(100-204)newton/examples/__init__.py (1)
run(161-199)
newton/examples/diffsim/example_diffsim_ball.py (2)
newton/tests/test_examples.py (1)
run(100-204)newton/examples/__init__.py (1)
run(161-199)
newton/examples/robot/example_robot_h1.py (1)
newton/examples/__init__.py (2)
test_body_state(49-103)run(161-199)
newton/examples/robot/example_robot_humanoid.py (1)
newton/examples/__init__.py (1)
run(161-199)
newton/examples/diffsim/example_diffsim_soft_body.py (1)
newton/examples/__init__.py (1)
run(161-199)
newton/examples/cloth/example_cloth_style3d.py (2)
newton/examples/__init__.py (2)
test_particle_state(106-158)run(161-199)newton/_src/utils/__init__.py (1)
vec_inside_limits(211-218)
newton/examples/robot/example_robot_anymal_d.py (1)
newton/examples/__init__.py (2)
test_body_state(49-103)run(161-199)
newton/examples/robot/example_robot_cartpole.py (3)
newton/_src/sim/builder.py (1)
body_count(515-519)newton/examples/__init__.py (2)
test_body_state(49-103)run(161-199)newton/_src/utils/__init__.py (1)
vec_allclose(200-207)
newton/examples/basic/example_basic_joints.py (1)
newton/examples/__init__.py (2)
test_body_state(49-103)run(161-199)
newton/utils.py (1)
newton/_src/utils/__init__.py (2)
vec_allclose(200-207)vec_inside_limits(211-218)
newton/examples/mpm/example_mpm_grain_rendering.py (1)
newton/tests/test_examples.py (1)
run(100-204)
newton/examples/cloth/example_cloth_bending.py (2)
newton/examples/__init__.py (2)
test_particle_state(106-158)run(161-199)newton/_src/utils/__init__.py (1)
vec_inside_limits(211-218)
newton/examples/ik/example_ik_franka.py (1)
newton/examples/__init__.py (1)
run(161-199)
newton/examples/selection/example_selection_articulations.py (1)
newton/examples/__init__.py (1)
run(161-199)
newton/examples/basic/example_basic_viewer.py (2)
newton/tests/test_examples.py (1)
run(100-204)newton/examples/__init__.py (1)
run(161-199)
newton/examples/cloth/example_cloth_twist.py (2)
newton/examples/__init__.py (2)
test_particle_state(106-158)run(161-199)newton/_src/utils/__init__.py (1)
vec_inside_limits(211-218)
newton/examples/robot/example_robot_anymal_c_walk.py (2)
newton/examples/__init__.py (3)
test_body_state(49-103)init(295-338)run(161-199)newton/_src/utils/__init__.py (1)
vec_allclose(200-207)
newton/examples/robot/example_robot_ur10.py (2)
newton/tests/test_examples.py (1)
run(100-204)newton/examples/__init__.py (1)
run(161-199)
newton/examples/basic/example_basic_pendulum.py (2)
newton/_src/sim/builder.py (1)
add_joint_revolute(1366-1448)newton/examples/__init__.py (2)
test_body_state(49-103)run(161-199)
newton/examples/robot/example_robot_g1.py (1)
newton/examples/__init__.py (2)
test_body_state(49-103)run(161-199)
newton/examples/cloth/example_cloth_hanging.py (3)
newton/_src/sim/style3d/builder_style3d.py (1)
Style3DModelBuilder(38-698)newton/examples/__init__.py (2)
test_particle_state(106-158)run(161-199)newton/_src/utils/__init__.py (1)
vec_inside_limits(211-218)
newton/examples/ik/example_ik_h1.py (1)
newton/examples/__init__.py (1)
run(161-199)
newton/examples/basic/example_basic_urdf.py (2)
newton/examples/__init__.py (2)
test_body_state(49-103)run(161-199)newton/_src/sim/builder.py (1)
body_count(515-519)
newton/examples/cloth/example_cloth_franka.py (2)
newton/examples/__init__.py (3)
test_particle_state(106-158)test_body_state(49-103)run(161-199)newton/_src/utils/__init__.py (1)
vec_inside_limits(211-218)
newton/examples/__init__.py (4)
newton/_src/sim/state.py (1)
State(21-112)newton/_src/sim/contacts.py (1)
Contacts(23-93)newton/_src/sim/control.py (1)
Control(21-77)newton/tests/test_examples.py (1)
run(100-204)
newton/examples/basic/example_basic_shapes.py (4)
newton/_src/sim/builder.py (5)
add_body(1179-1241)add_shape_sphere(2522-2553)add_shape_capsule(2594-2634)add_shape_box(2555-2592)add_shape_mesh(2721-2754)newton/_src/solvers/xpbd/solver_xpbd.py (1)
SolverXPBD(40-660)newton/examples/__init__.py (2)
test_body_state(49-103)run(161-199)newton/_src/utils/__init__.py (1)
vec_allclose(200-207)
newton/examples/diffsim/example_diffsim_spring_cage.py (2)
newton/tests/test_examples.py (1)
run(100-204)newton/examples/__init__.py (1)
run(161-199)
🪛 Ruff (0.13.1)
newton/examples/robot/example_robot_h1.py
129-129: Unused lambda argument: qd
(ARG005)
135-135: Unused lambda argument: q
(ARG005)
newton/examples/cloth/example_cloth_style3d.py
177-177: Unused lambda argument: qd
(ARG005)
newton/examples/robot/example_robot_anymal_d.py
146-146: Unused lambda argument: qd
(ARG005)
152-152: Unused lambda argument: q
(ARG005)
newton/examples/robot/example_robot_cartpole.py
118-118: Unused lambda argument: qd
(ARG005)
125-125: Unused lambda argument: q
(ARG005)
135-135: Unused lambda argument: q
(ARG005)
147-147: Unused lambda argument: q
(ARG005)
163-163: Unused lambda argument: q
(ARG005)
170-170: Unused lambda argument: q
(ARG005)
177-177: Unused lambda argument: q
(ARG005)
newton/examples/basic/example_basic_joints.py
204-204: Unused lambda argument: q
(ARG005)
211-211: Unused lambda argument: q
(ARG005)
218-218: Unused lambda argument: q
(ARG005)
225-225: Unused lambda argument: q
(ARG005)
newton/examples/cloth/example_cloth_bending.py
136-136: Unused lambda argument: q
(ARG005)
142-142: Unused lambda argument: qd
(ARG005)
148-148: Unused lambda argument: qd
(ARG005)
newton/examples/cloth/example_cloth_twist.py
296-296: Unused lambda argument: qd
(ARG005)
301-301: Unused lambda argument: q
(ARG005)
newton/examples/robot/example_robot_anymal_c_walk.py
236-236: Unused lambda argument: qd
(ARG005)
242-242: Unused lambda argument: q
(ARG005)
newton/examples/basic/example_basic_pendulum.py
131-131: Unused lambda argument: qd
(ARG005)
newton/tests/test_examples.py
91-91: Avoid specifying long messages outside the exception class
(TRY003)
newton/examples/robot/example_robot_g1.py
136-136: Unused lambda argument: qd
(ARG005)
142-142: Unused lambda argument: q
(ARG005)
newton/examples/cloth/example_cloth_hanging.py
193-193: Unused lambda argument: qd
(ARG005)
199-199: Unused lambda argument: qd
(ARG005)
newton/examples/basic/example_basic_urdf.py
133-133: Unused lambda argument: q
(ARG005)
141-141: Unused lambda argument: qd
(ARG005)
newton/examples/cloth/example_cloth_franka.py
559-559: Unused lambda argument: qd
(ARG005)
564-564: Unused lambda argument: q
(ARG005)
570-570: Unused lambda argument: q
(ARG005)
newton/examples/__init__.py
103-103: Avoid specifying long messages outside the exception class
(TRY003)
158-158: Avoid specifying long messages outside the exception class
(TRY003)
183-183: Avoid specifying long messages outside the exception class
(TRY003)
187-187: Avoid specifying long messages outside the exception class
(TRY003)
191-191: Avoid specifying long messages outside the exception class
(TRY003)
195-195: Avoid specifying long messages outside the exception class
(TRY003)
199-199: Avoid specifying long messages outside the exception class
(TRY003)
newton/examples/basic/example_basic_shapes.py
143-143: Unused lambda argument: qd
(ARG005)
151-151: Unused lambda argument: qd
(ARG005)
159-159: Unused lambda argument: qd
(ARG005)
167-167: Unused lambda argument: qd
(ARG005)
🪛 GitHub Actions: GPU Unit Tests on AWS EC2
newton/examples/cloth/example_cloth_bending.py
[error] 139-139: SyntaxError: '(' was never closed in warp lambda source while creating Warp function during test_particle_state execution.
newton/tests/test_examples.py
[error] 193-193: Test failed: assertion 1 != 0. Coverage run for 'newton.examples.cloth.example_cloth_bending' exited with code 1.
🪛 GitHub Actions: Pull Request
newton/examples/robot/example_robot_anymal_c_walk.py
[error] 26-26: ModuleNotFoundError: No module named 'torch' while importing example_robot_anymal_c_walk in tests/test_examples.py. This caused the test module 'robot.example_robot_anymal_c_walk' not found during test_examples execution.
⏰ 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 (59)
newton/examples/diffsim/example_diffsim_spring_cage.py (1)
253-253: Pass args to runner: LGTMMatches the updated run(example, args) API in newton.examples.
newton/examples/robot/example_robot_ur10.py (1)
218-218: Args forwarding: LGTMCorrectly updates to run(example, args).
newton/examples/diffsim/example_diffsim_cloth.py (1)
227-227: Args forwarding: LGTMConsistent with the new runner signature.
newton/examples/robot/example_robot_anymal_d.py (1)
164-164: Args forwarding: LGTMRunner call now matches run(example, args).
newton/examples/selection/example_selection_articulations.py (1)
301-301: Args forwarding: LGTMCorrectly updates to run(example, args).
newton/examples/basic/example_basic_viewer.py (1)
194-194: Args forwarding: LGTMConsistent with newton.examples.run(example, args).
newton/examples/example_replay_viewer.py (1)
252-252: Args forwarding: LGTMMatches the updated run API.
newton/examples/robot/example_robot_h1.py (1)
147-147: Args forwarding: LGTMUpdated to run(example, args).
newton/examples/robot/example_robot_g1.py (1)
132-143: Fix Warp test function so it actually runs.
The test callbacks get JIT-compiled into Warp kernels. Indexing awp.transform(q[2]) and calling Python’smax(abs(qd))are not Warp-compatible, so the kernel compilation will raise at runtime whenargs.testtriggersexample.test(). Use Warp utilities to read the translation and velocity norm.newton.examples.test_body_state( self.model, self.state_0, "all bodies are above the ground", - lambda q, qd: q[2] > 0.0, + lambda q, qd: wp.transform_get_translation(q).z > 0.0, ) newton.examples.test_body_state( self.model, self.state_0, "all body velocities are small", - lambda q, qd: max(abs(qd)) < 0.001, + lambda q, qd: wp.length(qd) < 0.001, )⛔ Skipped due to learnings
Learnt from: nvlukasz PR: newton-physics/newton#519 File: newton/_src/solvers/featherstone/kernels.py:75-75 Timestamp: 2025-08-12T18:04:06.577Z Learning: The Newton physics framework requires nightly Warp builds, which means compatibility concerns with older stable Warp versions (like missing functions such as wp.spatial_adjoint) are not relevant for this project.Learnt from: dylanturpin PR: newton-physics/newton#806 File: newton/_src/sim/ik/ik_objectives.py:0-0 Timestamp: 2025-09-25T16:14:22.002Z 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.Learnt from: dylanturpin PR: newton-physics/newton#806 File: newton/_src/sim/ik/ik_objectives.py:0-0 Timestamp: 2025-09-25T16:14:22.002Z 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.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.newton/examples/diffsim/example_diffsim_drone.py (1)
821-821: LGTM! API update correctly implemented.The invocation has been properly updated to pass the parsed arguments to the run function, aligning with the new
run(example, args)signature.newton/utils.py (1)
91-92: LGTM! New utility functions correctly exposed.The
vec_allcloseandvec_inside_limitsfunctions are properly imported and exported through the public API. These utilities provide essential vector comparison capabilities for state validation in testing.Also applies to: 106-107
newton/examples/robot/example_robot_policy.py (1)
472-472: LGTM! API update correctly implemented.The invocation has been properly updated to pass the parsed arguments to the run function, aligning with the new
run(example, args)signature. Based on learnings from previous reviews, this robot policy example is correctly registered as "robot_policy" in the system.newton/examples/basic/example_basic_urdf.py (2)
30-30: LGTM! Import addition is appropriate.The import of
warp as wpis correctly added to support the test functions that use wp module functionality.
164-164: LGTM! API update correctly implemented.The invocation has been properly updated to pass the parsed arguments to the run function, aligning with the new
run(example, args)signature.newton/examples/diffsim/example_diffsim_soft_body.py (1)
377-377: LGTM! API update correctly implemented.The invocation has been properly updated to pass the parsed arguments to the run function, aligning with the new
run(example, args)signature.newton/examples/basic/example_basic_joints.py (3)
87-88: LGTM! Initial joint angle configuration is correct.Setting the revolute joint to π/2 radians provides a meaningful initial configuration for the joint demonstration.
137-151: LGTM! Ball joint configuration is properly implemented.The addition of rigid body configuration with zero density for the kinematic sphere parent and the RPY quaternion initialization for the ball joint provide good demonstration of the ball joint capabilities.
243-243: LGTM! API update correctly implemented.The invocation has been properly updated to pass the parsed arguments to the run function, aligning with the new
run(example, args)signature.newton/examples/basic/example_basic_pendulum.py (2)
59-65: LGTM! Pendulum orientation enhancement improves visualization.The addition of the rotation quaternion to orient the pendulum sideways provides better visual presentation for viewers, making the pendulum motion more apparent.
164-164: LGTM! API update correctly implemented.The invocation has been properly updated to pass the parsed arguments to the run function, aligning with the new
run(example, args)signature.newton/examples/robot/example_robot_anymal_c_walk.py (1)
231-246: Fix unused lambda parameters- lambda q, qd: q[2] > 0.2, + lambda q, _qd: q[2] > 0.2,- lambda q, qd: newton.utils.vec_allclose( + lambda _q, qd: newton.utils.vec_allclose(Verify that the height threshold (0.2 m) and forward‐velocity expectation (≈1 m/s) align with the simulated gait before merging.
newton/examples/cloth/example_cloth_twist.py (1)
315-315: Run signature update looks good.Forwarding
argstorun()matches the updated runner API.newton/examples/robot/example_robot_cartpole.py (1)
189-189: Run signature update looks good.Using
run(example, args)aligns with the new runner API.newton/examples/cloth/example_cloth_hanging.py (2)
62-64: Correct builder class for Style3D.Switch to
newton.Style3DModelBuilder()is appropriate for the style3d path.
235-235: Run signature update looks good.Passing
argstorun()is consistent with the new API.newton/_src/utils/__init__.py (1)
246-247: Export additions look correct.Including
vec_allcloseandvec_inside_limitsin__all__is consistent with their use in examples.newton/examples/cloth/example_cloth_franka.py (2)
24-24: Command comment update looks fine.No issues.
583-583: Run signature update looks good.Consistent with the new
run(example, args)API.newton/tests/test_examples.py (5)
87-91: LGTM: Module existence verification.The runtime verification to ensure the test module exists is a good defensive programming practice. The
ImportErrorhandling provides clear error messages when a referenced example module is missing.
147-147: Add --test flag to example execution.The command construction properly appends the
--testflag, which aligns with the PR's objective to enable test mode for examples. This ensures examples can be invoked in test mode to run their validation routines.
234-240: LGTM: New basic shapes test added.The addition of
basic.example_basic_shapestest with appropriate frame count is well-structured and consistent with the existing pattern.
261-271: LGTM: Multiple test configurations for cloth hanging.The addition of two test variants for
cloth.example_cloth_hangingwith different test suffixes ("vbd" and "style3d") and corresponding solver options provides good coverage of different solver backends.
314-314: Device assignment optimization for GPU-intensive examples.Moving specific robot examples (anymal_c_walk, g1, h1) from
test_devicestocuda_test_devicesis a sensible optimization, as these examples likely require GPU acceleration for reasonable performance and may have PyTorch dependencies that benefit from CUDA.Also applies to: 329-329, 336-336
newton/examples/basic/example_basic_shapes.py (5)
54-56: LGTM: Consistent body key assignments.The addition of
keyparameters toadd_body()calls provides meaningful identifiers for each body (sphere, capsule, box, mesh), which will be useful for debugging and the new test functionality. The implementation is consistent and follows a clear naming pattern.Also applies to: 60-62, 70-70, 87-87
94-94: LGTM: XPBD solver configuration with explicit iterations.The explicit
iterations=10parameter for theSolverXPBDconstructor improves clarity and aligns with the updated API. This provides better control over solver convergence behavior.
103-103: LGTM: Updated documentation comment.The comment correctly reflects that the forward kinematics step is required for maximal-coordinate solvers like XPBD, providing better context than the previous generic note.
138-169: LGTM: Comprehensive rest pose testing.The test implementation effectively validates that bodies settle into expected rest positions after simulation. The tests cover all major shapes and use appropriate tolerance values. The bunny test reasonably checks for basic physics constraints (staying above ground, minimal drift) rather than exact positioning due to its complex geometry.
185-185: LGTM: Updated run signature.The change to
newton.examples.run(example, args)correctly passes the parsed arguments, enabling the new test functionality and other argument-driven behavior.newton/examples/__init__.py (8)
17-17: LGTM: Import for Callable type annotation.The import of
Callablefromcollections.abcis appropriate for the new type annotations in the test functions.
37-46: LGTM: Non-finite value detection helper.The
_find_nonfinitefunction provides a robust way to detect problematic numerical values in Newton objects. The implementation correctly handlesNoneobjects and uses numpy'sisfinitefunction for reliable detection.
49-103: LGTM: Comprehensive body state testing utility.The
test_body_statefunction provides a well-designed testing framework that:
- Supports both Warp functions and Python callables via
wp.utils.create_warp_function- Uses GPU kernels for efficient batch testing
- Provides detailed error reporting with body keys
- Handles optional indices for selective testing
The implementation is robust and will be valuable for example validation.
106-158: LGTM: Particle state testing utility.The
test_particle_statefunction mirrors the design oftest_body_statebut for particle systems. The implementation is consistent and provides appropriate error reporting, though it could benefit from particle identifiers similar to how body keys are used.
161-161: LGTM: Updated run function signature.The change to accept both
exampleandargsparameters enables the new testing functionality and argument-driven behavior across examples.
173-174: LGTM: Example-specific test execution.The conditional execution of
example.test()when bothargs.testis enabled and the method exists provides a clean way for examples to implement custom validation logic.
178-199: LGTM: Generic finiteness validation.The comprehensive validation of Newton objects (state_0, state_1, contacts, model, control) for non-finite values provides excellent runtime verification. This will help catch numerical issues early in the testing process.
285-290: LGTM: Test mode argument addition.The addition of the
--testflag withBooleanOptionalActionfollows argparse best practices and integrates cleanly with the existing argument parser.newton/examples/__main__.py (1)
3-14: License header matches our standard.
Template aligns with the rest of the repo’s Apache-2.0 headers.newton/examples/robot/example_robot_humanoid.py (1)
127-127: Passingargsintorunkeeps this example compatible.
This forwards the parsed CLI/test options so the updated runner can perform its validations.newton/examples/mpm/example_mpm_anymal.py (1)
433-433: Runner invocation now matches the updated API.
argsis propagated, so test-mode hooks and nonfinite checks will run as intended.newton/examples/mpm/example_mpm_grain_rendering.py (1)
160-160: Args forwarding confirmed.
Keeps this grain-rendering example in sync with the newrun(example, args)signature.newton/examples/diffsim/example_diffsim_ball.py (1)
261-261:runcall updated appropriately.
Ensures the diffsim example participates in the shared args/test flow.newton/examples/selection/example_selection_cartpole.py (1)
199-199: Cartpole example now conforms to the new runner signature.
CLI/test arguments will flow into the shared runner just like the other examples.newton/examples/mpm/example_mpm_multi_material.py (1)
219-219: Updated runner call looks good.
Multi-material example also passesargs, enabling the shared validation logic.newton/examples/selection/example_selection_materials.py (1)
277-277: Args now forwarded to the runner.
Keeps the selection materials example compatible with the enhanced run flow.newton/examples/mpm/example_mpm_granular.py (1)
229-229: Forward args intorun.Good catch updating this call to satisfy the new
run(example, args)signature so tests get the CLI context they expect.newton/examples/ik/example_ik_franka.py (1)
177-177:runinvocation matches updated signature.Passing
argsthrough keeps the IK example wired into the shared test/CLI pipeline after the API change.newton/examples/robot/example_robot_allegro_hand.py (1)
210-210: Propagate parsed args to the runner.Thanks for updating the Allegro example to pass
args; this keeps its test path consistent with the revised harness.newton/examples/sensors/example_sensor_contact.py (1)
354-354: Runner call now forwards CLI args.This change ensures the sensor example benefits from the new test hooks and arg-driven behaviors.
newton/examples/ik/example_ik_h1.py (1)
193-193: Alignruncall with new API.Forwarding
argshere keeps the H1 IK example compatible with the shared runner logic.
There was a problem hiding this comment.
Actionable comments posted: 13
🧹 Nitpick comments (7)
newton/examples/robot/example_robot_h1.py (1)
125-136: Silence lint and prefer Warp-safe velocity norm check.Avoid unused lambda args and Python max/abs on Warp types; use wp.length.
Apply:
newton.examples.test_body_state( self.model, self.state_0, "all bodies are above the ground", - lambda q, qd: q[2] > 0.0, + lambda q, _qd: q[2] > 0.0, ) newton.examples.test_body_state( self.model, self.state_0, "all body velocities are small", - lambda q, qd: max(abs(qd)) < 0.001, + lambda _q, qd: wp.length(qd) < 1.0e-3, )Ruff ARG005 warnings resolved; wp.length(qd) is robust in Warp kernels. Please verify wp.length supports wp.spatial_vector on your current Warp version. Based on static analysis hints
newton/examples/robot/example_robot_anymal_d.py (1)
142-153: Same cleanups: unused args + Warp-friendly velocity check.Use underscore for unused parameters and wp.length for norms.
Apply:
newton.examples.test_body_state( self.model, self.state_0, "all bodies are above the ground", - lambda q, qd: q[2] > -0.006, + lambda q, _qd: q[2] > -0.006, ) newton.examples.test_body_state( self.model, self.state_0, "body velocities are small", - lambda q, qd: max(abs(qd)) < 0.1, + lambda _q, qd: wp.length(qd) < 0.1, )Resolves Ruff ARG005 and avoids Python builtins inside generated Warp code. Based on static analysis hints
newton/examples/cloth/example_cloth_style3d.py (1)
174-178: Silence unused-arg warning in lambdaRename the unused qd parameter to _qd to satisfy Ruff ARG005 without changing behavior.
- newton.examples.test_particle_state( - self.state_0, - "particles are within a reasonable volume", - lambda q, qd: newton.utils.vec_inside_limits(q, wp.vec3(-0.5, -0.2, 0.9), wp.vec3(0.5, 0.2, 1.6)), - ) + newton.examples.test_particle_state( + self.state_0, + "particles are within a reasonable volume", + lambda q, _qd: newton.utils.vec_inside_limits(q, wp.vec3(-0.5, -0.2, 0.9), wp.vec3(0.5, 0.2, 1.6)), + )newton/examples/robot/example_robot_anymal_c_walk.py (1)
231-247: Silence unused-arg warnings in lambdasRename unused parameters to underscores to satisfy Ruff ARG005.
- newton.examples.test_body_state( + newton.examples.test_body_state( self.model, self.state_0, "all bodies are above the ground", - lambda q, qd: q[2] > 0.2, + lambda q, _qd: q[2] > 0.2, ) newton.examples.test_body_state( self.model, self.state_0, "the robot is moving forward and not falling", - lambda q, qd: newton.utils.vec_allclose( + lambda _q, qd: newton.utils.vec_allclose( qd, wp.spatial_vector(0.0, 1.0, 0.0, 0.0, 0.0, 0.0), rtol=0.1, atol=0.15 ), indices=[0], )newton/examples/basic/example_basic_joints.py (1)
210-227: Silence unused-arg warnings in lambdasRename unused q to _q to satisfy Ruff ARG005.
- lambda q, qd: max(abs(qd)) < 1e-2, + lambda _q, qd: max(abs(qd)) < 1e-2, @@ - lambda q, qd: max(abs(qd)) < 1e-5, + lambda _q, qd: max(abs(qd)) < 1e-5, @@ - lambda q, qd: max(abs(qd)) < 3.0, + lambda _q, qd: max(abs(qd)) < 3.0,newton/examples/cloth/example_cloth_franka.py (1)
555-572: Silence unused-arg warnings in lambdasRename unused parameters to underscores to satisfy Ruff ARG005.
- newton.examples.test_particle_state( + newton.examples.test_particle_state( self.state_0, "particles are within a reasonable volume", - lambda q, qd: newton.utils.vec_inside_limits(q, wp.vec3(-0.34, -0.85, 0.03), wp.vec3(0.34, -0.13, 0.36)), + lambda q, _qd: newton.utils.vec_inside_limits(q, wp.vec3(-0.34, -0.85, 0.03), wp.vec3(0.34, -0.13, 0.36)), ) newton.examples.test_particle_state( self.state_0, "particle velocities are within a reasonable range", - lambda q, qd: max(abs(qd)) < 2.0, + lambda _q, qd: max(abs(qd)) < 2.0, ) newton.examples.test_body_state( self.model, self.state_0, "body velocities are within a reasonable range", - lambda q, qd: max(abs(qd)) < 0.7, + lambda _q, qd: max(abs(qd)) < 0.7, )newton/examples/cloth/example_cloth_bending.py (1)
132-137: Silence unused-arg warnings in lambdasRename unused parameters to underscores to satisfy Ruff ARG005.
- lambda q, qd: max(abs(qd)) < 0.1, + lambda _q, qd: max(abs(qd)) < 0.1, @@ - lambda q, qd: q[2] < 0.15, + lambda q, _qd: q[2] < 0.15,Also applies to: 145-151
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (40)
newton/_src/utils/__init__.py(3 hunks)newton/examples/__init__.py(5 hunks)newton/examples/__main__.py(1 hunks)newton/examples/basic/example_basic_joints.py(5 hunks)newton/examples/basic/example_basic_pendulum.py(3 hunks)newton/examples/basic/example_basic_shapes.py(5 hunks)newton/examples/basic/example_basic_urdf.py(3 hunks)newton/examples/basic/example_basic_viewer.py(1 hunks)newton/examples/cloth/example_cloth_bending.py(2 hunks)newton/examples/cloth/example_cloth_franka.py(3 hunks)newton/examples/cloth/example_cloth_hanging.py(4 hunks)newton/examples/cloth/example_cloth_style3d.py(2 hunks)newton/examples/cloth/example_cloth_twist.py(3 hunks)newton/examples/diffsim/example_diffsim_ball.py(1 hunks)newton/examples/diffsim/example_diffsim_cloth.py(1 hunks)newton/examples/diffsim/example_diffsim_drone.py(1 hunks)newton/examples/diffsim/example_diffsim_soft_body.py(1 hunks)newton/examples/diffsim/example_diffsim_spring_cage.py(1 hunks)newton/examples/example_replay_viewer.py(1 hunks)newton/examples/ik/example_ik_franka.py(1 hunks)newton/examples/ik/example_ik_h1.py(1 hunks)newton/examples/mpm/example_mpm_anymal.py(1 hunks)newton/examples/mpm/example_mpm_grain_rendering.py(1 hunks)newton/examples/mpm/example_mpm_granular.py(1 hunks)newton/examples/mpm/example_mpm_multi_material.py(1 hunks)newton/examples/robot/example_robot_allegro_hand.py(1 hunks)newton/examples/robot/example_robot_anymal_c_walk.py(1 hunks)newton/examples/robot/example_robot_anymal_d.py(2 hunks)newton/examples/robot/example_robot_cartpole.py(2 hunks)newton/examples/robot/example_robot_g1.py(2 hunks)newton/examples/robot/example_robot_h1.py(2 hunks)newton/examples/robot/example_robot_humanoid.py(1 hunks)newton/examples/robot/example_robot_policy.py(1 hunks)newton/examples/robot/example_robot_ur10.py(1 hunks)newton/examples/selection/example_selection_articulations.py(1 hunks)newton/examples/selection/example_selection_cartpole.py(1 hunks)newton/examples/selection/example_selection_materials.py(1 hunks)newton/examples/sensors/example_sensor_contact.py(1 hunks)newton/tests/test_examples.py(9 hunks)newton/utils.py(2 hunks)
👮 Files not reviewed due to content moderation or server errors (7)
- newton/examples/mpm/example_mpm_anymal.py
- newton/examples/ik/example_ik_franka.py
- newton/examples/diffsim/example_diffsim_soft_body.py
- newton/examples/sensors/example_sensor_contact.py
- newton/examples/diffsim/example_diffsim_cloth.py
- newton/examples/diffsim/example_diffsim_ball.py
- newton/examples/mpm/example_mpm_grain_rendering.py
🧰 Additional context used
🧠 Learnings (6)
📚 Learning: 2025-08-25T21:41:45.795Z
Learnt from: dylanturpin
PR: newton-physics/newton#634
File: newton/tests/test_examples.py:329-333
Timestamp: 2025-08-25T21:41:45.795Z
Learning: Newton examples use a centralized CLI argument parsing system in newton/examples/__init__.py. The create_parser() function defines common arguments like --device, --viewer, --output-path, and --num-frames, while init(parser) creates viewers based on parsed arguments. Individual example scripts don't need to define these flags themselves - they inherit them from the centralized system via the example_map and runpy execution.
Applied to files:
newton/examples/ik/example_ik_franka.pynewton/examples/mpm/example_mpm_granular.pynewton/examples/basic/example_basic_viewer.pynewton/examples/mpm/example_mpm_grain_rendering.pynewton/examples/ik/example_ik_h1.pynewton/examples/diffsim/example_diffsim_soft_body.pynewton/examples/basic/example_basic_pendulum.pynewton/examples/diffsim/example_diffsim_spring_cage.pynewton/examples/robot/example_robot_ur10.pynewton/examples/sensors/example_sensor_contact.pynewton/examples/robot/example_robot_g1.pynewton/examples/robot/example_robot_humanoid.pynewton/examples/robot/example_robot_anymal_d.pynewton/examples/basic/example_basic_joints.pynewton/examples/robot/example_robot_cartpole.pynewton/examples/diffsim/example_diffsim_cloth.pynewton/examples/diffsim/example_diffsim_drone.pynewton/examples/selection/example_selection_cartpole.pynewton/examples/basic/example_basic_urdf.pynewton/examples/__init__.pynewton/examples/mpm/example_mpm_multi_material.pynewton/examples/__main__.pynewton/examples/selection/example_selection_articulations.pynewton/examples/cloth/example_cloth_style3d.pynewton/examples/example_replay_viewer.pynewton/examples/selection/example_selection_materials.pynewton/examples/cloth/example_cloth_twist.pynewton/examples/robot/example_robot_allegro_hand.pynewton/examples/cloth/example_cloth_franka.pynewton/examples/cloth/example_cloth_bending.pynewton/examples/robot/example_robot_h1.pynewton/examples/basic/example_basic_shapes.pynewton/examples/mpm/example_mpm_anymal.py
📚 Learning: 2025-08-12T18:04:06.577Z
Learnt from: nvlukasz
PR: newton-physics/newton#519
File: newton/_src/solvers/featherstone/kernels.py:75-75
Timestamp: 2025-08-12T18:04:06.577Z
Learning: The Newton physics framework requires nightly Warp builds, which means compatibility concerns with older stable Warp versions (like missing functions such as wp.spatial_adjoint) are not relevant for this project.
Applied to files:
newton/examples/basic/example_basic_urdf.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 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/examples/basic/example_basic_urdf.py
📚 Learning: 2025-08-27T19:05:44.697Z
Learnt from: Milad-Rakhsha-NV
PR: newton-physics/newton#535
File: newton/tests/test_examples.py:320-414
Timestamp: 2025-08-27T19:05:44.697Z
Learning: In newton/examples/__init__.py, the robot policy example is registered with the key "robot_policy" (not "robot.example_robot_policy"), so tests should reference it as name="robot_policy".
Applied to files:
newton/examples/robot/example_robot_policy.pynewton/examples/robot/example_robot_allegro_hand.pynewton/examples/robot/example_robot_h1.py
📚 Learning: 2025-08-14T17:38:36.106Z
Learnt from: nvlukasz
PR: newton-physics/newton#519
File: newton/__init__.py:25-29
Timestamp: 2025-08-14T17:38:36.106Z
Learning: The Newton project prefers incremental __all__ building using __all__ += [...] pattern to group exports with their related imports, rather than a single consolidated __all__ at the end of the file.
Applied to files:
newton/utils.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/examples/basic/example_basic_shapes.py
🧬 Code graph analysis (36)
newton/examples/ik/example_ik_franka.py (1)
newton/examples/__init__.py (1)
run(161-199)
newton/examples/mpm/example_mpm_granular.py (1)
newton/examples/__init__.py (1)
run(161-199)
newton/examples/basic/example_basic_viewer.py (2)
newton/tests/test_examples.py (1)
run(100-204)newton/examples/__init__.py (1)
run(161-199)
newton/examples/mpm/example_mpm_grain_rendering.py (1)
newton/tests/test_examples.py (1)
run(100-204)
newton/examples/ik/example_ik_h1.py (2)
newton/tests/test_examples.py (1)
run(100-204)newton/examples/__init__.py (1)
run(161-199)
newton/examples/diffsim/example_diffsim_soft_body.py (2)
newton/tests/test_examples.py (1)
run(100-204)newton/examples/__init__.py (1)
run(161-199)
newton/examples/basic/example_basic_pendulum.py (2)
newton/_src/sim/builder.py (1)
add_joint_revolute(1366-1448)newton/examples/__init__.py (2)
test_body_state(49-103)run(161-199)
newton/examples/diffsim/example_diffsim_spring_cage.py (2)
newton/tests/test_examples.py (1)
run(100-204)newton/examples/__init__.py (1)
run(161-199)
newton/examples/robot/example_robot_ur10.py (1)
newton/examples/__init__.py (1)
run(161-199)
newton/examples/robot/example_robot_anymal_c_walk.py (2)
newton/examples/__init__.py (3)
test_body_state(49-103)init(295-338)run(161-199)newton/_src/utils/__init__.py (1)
vec_allclose(200-207)
newton/examples/sensors/example_sensor_contact.py (1)
newton/examples/__init__.py (1)
run(161-199)
newton/examples/robot/example_robot_g1.py (1)
newton/examples/__init__.py (2)
test_body_state(49-103)run(161-199)
newton/examples/robot/example_robot_humanoid.py (1)
newton/examples/__init__.py (1)
run(161-199)
newton/examples/robot/example_robot_anymal_d.py (1)
newton/examples/__init__.py (2)
test_body_state(49-103)run(161-199)
newton/examples/basic/example_basic_joints.py (1)
newton/examples/__init__.py (2)
test_body_state(49-103)run(161-199)
newton/examples/diffsim/example_diffsim_ball.py (1)
newton/examples/__init__.py (1)
run(161-199)
newton/examples/robot/example_robot_cartpole.py (3)
newton/_src/sim/builder.py (1)
body_count(515-519)newton/examples/__init__.py (2)
test_body_state(49-103)run(161-199)newton/_src/utils/__init__.py (1)
vec_allclose(200-207)
newton/examples/diffsim/example_diffsim_cloth.py (2)
newton/tests/test_examples.py (1)
run(100-204)newton/examples/__init__.py (1)
run(161-199)
newton/examples/diffsim/example_diffsim_drone.py (1)
newton/examples/__init__.py (1)
run(161-199)
newton/examples/selection/example_selection_cartpole.py (1)
newton/examples/__init__.py (1)
run(161-199)
newton/examples/basic/example_basic_urdf.py (2)
newton/examples/__init__.py (2)
test_body_state(49-103)run(161-199)newton/_src/sim/builder.py (1)
body_count(515-519)
newton/examples/__init__.py (6)
newton/_src/sim/state.py (1)
State(21-112)newton/_src/sim/contacts.py (1)
Contacts(23-93)newton/_src/sim/control.py (1)
Control(21-77)newton/tests/test_examples.py (1)
run(100-204)newton/examples/cloth/example_cloth_hanging.py (1)
test(187-200)newton/examples/robot/example_robot_cartpole.py (1)
test(112-179)
newton/examples/cloth/example_cloth_hanging.py (3)
newton/_src/sim/style3d/builder_style3d.py (1)
Style3DModelBuilder(38-698)newton/examples/__init__.py (2)
test_particle_state(106-158)run(161-199)newton/_src/utils/__init__.py (1)
vec_inside_limits(211-218)
newton/examples/robot/example_robot_policy.py (1)
newton/examples/__init__.py (1)
run(161-199)
newton/examples/mpm/example_mpm_multi_material.py (1)
newton/tests/test_examples.py (1)
run(100-204)
newton/examples/selection/example_selection_articulations.py (2)
newton/tests/test_examples.py (1)
run(100-204)newton/examples/__init__.py (1)
run(161-199)
newton/utils.py (1)
newton/_src/utils/__init__.py (2)
vec_allclose(200-207)vec_inside_limits(211-218)
newton/examples/cloth/example_cloth_style3d.py (2)
newton/examples/__init__.py (2)
test_particle_state(106-158)run(161-199)newton/_src/utils/__init__.py (1)
vec_inside_limits(211-218)
newton/examples/selection/example_selection_materials.py (2)
newton/tests/test_examples.py (1)
run(100-204)newton/examples/__init__.py (1)
run(161-199)
newton/examples/cloth/example_cloth_twist.py (2)
newton/examples/__init__.py (2)
test_particle_state(106-158)run(161-199)newton/_src/utils/__init__.py (1)
vec_inside_limits(211-218)
newton/examples/robot/example_robot_allegro_hand.py (1)
newton/tests/test_examples.py (1)
run(100-204)
newton/examples/cloth/example_cloth_franka.py (2)
newton/examples/__init__.py (3)
test_particle_state(106-158)test_body_state(49-103)run(161-199)newton/_src/utils/__init__.py (1)
vec_inside_limits(211-218)
newton/examples/cloth/example_cloth_bending.py (2)
newton/examples/__init__.py (2)
test_particle_state(106-158)run(161-199)newton/_src/utils/__init__.py (1)
vec_inside_limits(211-218)
newton/examples/robot/example_robot_h1.py (2)
newton/examples/__init__.py (2)
test_body_state(49-103)run(161-199)newton/tests/test_examples.py (1)
run(100-204)
newton/examples/basic/example_basic_shapes.py (4)
newton/_src/sim/builder.py (6)
add_body(1179-1241)add_shape_sphere(2522-2553)add_shape_capsule(2594-2634)add_shape_box(2555-2592)add_shape_mesh(2721-2754)finalize(4058-4416)newton/_src/solvers/xpbd/solver_xpbd.py (1)
SolverXPBD(40-660)newton/examples/__init__.py (2)
test_body_state(49-103)run(161-199)newton/_src/utils/__init__.py (1)
vec_allclose(200-207)
newton/examples/mpm/example_mpm_anymal.py (2)
newton/tests/test_examples.py (1)
run(100-204)newton/examples/__init__.py (1)
run(161-199)
🪛 Ruff (0.13.1)
newton/examples/basic/example_basic_pendulum.py
131-131: Unused lambda argument: qd
(ARG005)
newton/examples/robot/example_robot_anymal_c_walk.py
236-236: Unused lambda argument: qd
(ARG005)
242-242: Unused lambda argument: q
(ARG005)
newton/examples/robot/example_robot_g1.py
136-136: Unused lambda argument: qd
(ARG005)
142-142: Unused lambda argument: q
(ARG005)
newton/examples/robot/example_robot_anymal_d.py
146-146: Unused lambda argument: qd
(ARG005)
152-152: Unused lambda argument: q
(ARG005)
newton/examples/basic/example_basic_joints.py
204-204: Unused lambda argument: q
(ARG005)
211-211: Unused lambda argument: q
(ARG005)
218-218: Unused lambda argument: q
(ARG005)
225-225: Unused lambda argument: q
(ARG005)
newton/examples/robot/example_robot_cartpole.py
118-118: Unused lambda argument: qd
(ARG005)
125-125: Unused lambda argument: q
(ARG005)
135-135: Unused lambda argument: q
(ARG005)
147-147: Unused lambda argument: q
(ARG005)
163-163: Unused lambda argument: q
(ARG005)
170-170: Unused lambda argument: q
(ARG005)
177-177: Unused lambda argument: q
(ARG005)
newton/examples/basic/example_basic_urdf.py
133-133: Unused lambda argument: q
(ARG005)
141-141: Unused lambda argument: qd
(ARG005)
newton/examples/__init__.py
103-103: Avoid specifying long messages outside the exception class
(TRY003)
158-158: Avoid specifying long messages outside the exception class
(TRY003)
183-183: Avoid specifying long messages outside the exception class
(TRY003)
187-187: Avoid specifying long messages outside the exception class
(TRY003)
191-191: Avoid specifying long messages outside the exception class
(TRY003)
195-195: Avoid specifying long messages outside the exception class
(TRY003)
199-199: Avoid specifying long messages outside the exception class
(TRY003)
newton/examples/cloth/example_cloth_hanging.py
193-193: Unused lambda argument: qd
(ARG005)
199-199: Unused lambda argument: qd
(ARG005)
newton/examples/cloth/example_cloth_style3d.py
177-177: Unused lambda argument: qd
(ARG005)
newton/examples/cloth/example_cloth_twist.py
296-296: Unused lambda argument: qd
(ARG005)
301-301: Unused lambda argument: q
(ARG005)
newton/examples/cloth/example_cloth_franka.py
559-559: Unused lambda argument: qd
(ARG005)
564-564: Unused lambda argument: q
(ARG005)
570-570: Unused lambda argument: q
(ARG005)
newton/tests/test_examples.py
91-91: Avoid specifying long messages outside the exception class
(TRY003)
newton/examples/cloth/example_cloth_bending.py
136-136: Unused lambda argument: q
(ARG005)
142-142: Unused lambda argument: qd
(ARG005)
148-148: Unused lambda argument: qd
(ARG005)
newton/examples/robot/example_robot_h1.py
129-129: Unused lambda argument: qd
(ARG005)
135-135: Unused lambda argument: q
(ARG005)
newton/examples/basic/example_basic_shapes.py
143-143: Unused lambda argument: qd
(ARG005)
151-151: Unused lambda argument: qd
(ARG005)
159-159: Unused lambda argument: qd
(ARG005)
167-167: Unused lambda argument: qd
(ARG005)
🪛 GitHub Actions: Pull Request
newton/examples/robot/example_robot_anymal_c_walk.py
[error] 26-26: ModuleNotFoundError: No module named 'torch' while importing example_robot_anymal_c_walk during test_examples.
newton/tests/test_examples.py
[error] 311-311: Test module robot.example_robot_anymal_c_walk not found. ImportError raised while loading example tests.
🪛 GitHub Actions: GPU Unit Tests on AWS EC2
newton/tests/test_examples.py
[error] 193-193: Assertion failed in test_examples.py: 1 != 0. The covered cloth example test failed; Command 'coverage run --data-file=/tmp/tmp8tlsy0yw/tmp9pv1lj2_ -m newton.examples.cloth.example_cloth_bending --device cpu --test --viewer usd --output-path /var/snap/amazon-ssm-agent/12322/newton/newton/tests/outputs/cloth.example_cloth_bending_cpu.usd --num-frames 200' exited with code 1.
newton/examples/cloth/example_cloth_bending.py
[error] 160-160: SyntaxError: '(' was never closed while extracting warp lambda source (lambda q, qd: newton.utils.vec_inside_limits(...)).
🔇 Additional comments (31)
newton/examples/basic/example_basic_urdf.py (3)
29-31: Import of warp is correct and necessary.Required for device functions used in tests below.
164-164: Passing args into run() is correct.Matches newton.examples.run(example, args) behavior where args.test triggers example.test() and finiteness checks.
Ensure the tests invoke this example with --test to exercise the new checks.
136-144: Transform indexing bug and unused arg in lambda.q is a wp.transform; use q.p[2] for height. Also avoid Python lambda; pass a wp.func. This also resolves Ruff ARG005 for the unused qd.
Apply this diff:
- bodies_per_env = self.model.body_count // self.num_envs + bodies_per_env = self.model.body_count // self.num_envs newton.examples.test_body_state( self.model, self.state_0, "quadrupeds have reached the terminal height", - lambda q, qd: wp.abs(q[2] - 0.48) < 0.01, + at_terminal_height, # only select the root body of each environment indices=[i * bodies_per_env for i in range(self.num_envs)], )Add this device function near the imports:
@wp.func def at_terminal_height(q: wp.transform, _qd: wp.spatial_vector) -> bool: return wp.abs(q.p[2] - 0.48) < 0.01Please verify body_count % num_envs == 0 at runtime; if not, root-body indexing will be off. Based on relevant_code_snippets
newton/examples/__main__.py (1)
3-14: License header addition: LGTM.Matches Apache 2.0 template; no functional impact.
newton/_src/utils/__init__.py (3)
199-207: vec_allclose: Correct tolerance semantics; LGTM.Matches numpy’s abs(a-b) <= atol + rtol*abs(b); works with fixed-size Warp vectors.
210-218: vec_inside_limits: Straightforward and clear; LGTM.Loop unrolled via wp.static(len(a)) for fixed-size vectors.
246-248: Verify public re-export is wired up.Ensure newton/utils.py re-exports these for public access as documented.
Run:
newton/examples/example_replay_viewer.py (1)
252-252: API alignment: passing args into run() is correct.Keeps this entry point consistent with the updated runner signature.
newton/examples/selection/example_selection_materials.py (1)
277-277: API alignment: LGTM.Forwarding args to run() matches the new examples runner.
newton/examples/mpm/example_mpm_granular.py (1)
229-229: API alignment: LGTM.Args are now forwarded to the runner as expected.
newton/examples/robot/example_robot_ur10.py (1)
218-218: API alignment: LGTM. Also check for any remaining legacy call sites.This adopts run(example, args). Verify no other examples still call run(example) without args.
Run:
newton/examples/diffsim/example_diffsim_drone.py (1)
821-821: Forwardingargskeeps the example aligned with the updated runner API.Looks good—this ensures the CLI/test flags propagate into
newton.examples.run.newton/examples/robot/example_robot_allegro_hand.py (1)
210-210: Run invocation now matches the newrun(example, args)contract.No issues spotted; the example will honor
--testand other parsed flags.newton/examples/diffsim/example_diffsim_spring_cage.py (1)
253-253: Args passthrough torunlooks correct.This keeps the diff-sim example compatible with the updated runner.
newton/examples/robot/example_robot_policy.py (1)
472-472: Runner call updated appropriately.Passing
argshere ensures policy selection honors CLI/test flags.newton/examples/robot/example_robot_humanoid.py (1)
127-127:argsforwarding confirmed.The humanoid example now complies with the revised
newton.examples.runsignature.newton/examples/mpm/example_mpm_multi_material.py (1)
219-219: Runner call aligns with new signature.No problems here—
argsreaches the test harness as expected.newton/examples/selection/example_selection_articulations.py (1)
301-301: Updated runner invocation is correct.
argsis now propagated to handle--testand related options.newton/examples/selection/example_selection_cartpole.py (1)
199-199: Args propagation LGTM.This keeps the cartpole selection example compatible with the shared runner.
newton/examples/basic/example_basic_viewer.py (1)
194-194: Run signature update looks goodPassing args into run aligns with newton.examples.run(example, args).
newton/examples/cloth/example_cloth_style3d.py (1)
194-194: Run signature update looks goodConsistent with updated run(example, args).
newton/examples/ik/example_ik_h1.py (1)
193-193: Run signature update looks goodSwitch to run(example, args) is correct.
newton/examples/robot/example_robot_anymal_c_walk.py (2)
255-255: Run signature update looks goodrun(example, args) matches the new API.
26-57: Fix: guard optional torch dependency to prevent import-time failureTests fail importing this module when torch isn’t installed. Guard the import and the JIT-decorated function so the module can be imported, and short-circuit in main if torch is unavailable.
-import torch +try: + import torch + TORCH_AVAILABLE = True +except Exception: + TORCH_AVAILABLE = False-@torch.jit.script -def quat_rotate_inverse(q: torch.Tensor, v: torch.Tensor) -> torch.Tensor: +if TORCH_AVAILABLE: + @torch.jit.script + def quat_rotate_inverse(q: torch.Tensor, v: torch.Tensor) -> torch.Tensor: + # ... (body unchanged) + q_w = q[..., 3] + q_vec = q[..., :3] + a = v * (2.0 * q_w**2 - 1.0).unsqueeze(-1) + b = torch.cross(q_vec, v, dim=-1) * q_w.unsqueeze(-1) * 2.0 + if q_vec.dim() == 2: + c = q_vec * torch.bmm(q_vec.view(q.shape[0], 1, 3), v.view(q.shape[0], 3, 1)).squeeze(-1) * 2.0 + else: + c = q_vec * torch.einsum("...i,...i->...", q_vec, v).unsqueeze(-1) * 2.0 + return a - b + c +else: + def quat_rotate_inverse(q, v): + raise RuntimeError("Torch not available")Additionally, exit early in main if torch is missing to make the subprocess return 0 cleanly when the dependency isn’t present:
if __name__ == "__main__": - # Parse arguments and initialize viewer - viewer, args = newton.examples.init() + # Parse arguments and initialize viewer + import sys + if not TORCH_AVAILABLE: + print("Torch not available; skipping example_robot_anymal_c_walk") + sys.exit(0) + viewer, args = newton.examples.init()To ensure CI skips this example when torch is missing, please also verify test_examples marks it torch_required.
Run to confirm mapping:
newton/utils.py (1)
91-93: Re-exporting vec_allclose and vec_inside_limits is correctPublic surface now matches usage across examples/tests. Incremental all style is consistent.
Also applies to: 106-108
newton/examples/basic/example_basic_joints.py (3)
87-89: Initializing joint angle is fineSetting builder.joint_q[-1] to pi/2 is reasonable for a visible hinge pose.
151-152: Quaternion init for BALL joint looks goodUsing quat_rpy to seed initial orientation is appropriate.
243-244: Run signature update looks goodCorrectly updated to run(example, args).
newton/examples/cloth/example_cloth_franka.py (1)
583-584: Run signature update looks goodSwitch to run(example, args) is correct.
newton/examples/cloth/example_cloth_bending.py (1)
160-160: Run signature update looks goodrun(example, args) matches the new API.
newton/examples/basic/example_basic_shapes.py (1)
138-169: Fix transform handling in example tests
test_body_statepasses each body'swp.transforminto your lambda.newton.utils.vec_allcloseexpects vector-like inputs, and the lambdas use direct indexing (q[2], etc.). Running the example with--testwill make Warp compile this kernel and it aborts becausewp.transformisn’t subscriptable andvec_allclosecan’t iterate it. Compare the transform’s translation and rotation explicitly instead.sphere_q = wp.transform(0.0, -2.0, 0.5, 0.0, 0.0, 0.0, 1.0) newton.examples.test_body_state( self.model, self.state_0, "sphere at rest pose", - lambda q, qd: newton.utils.vec_allclose(q, sphere_q, atol=1e-4), + lambda q, qd: newton.utils.vec_allclose(q.p, sphere_q.p, atol=1e-4) + and newton.utils.vec_allclose(q.q, sphere_q.q, atol=1e-4), [0], ) capsule_q = wp.transform(0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0) newton.examples.test_body_state( self.model, self.state_0, "capsule at rest pose", - lambda q, qd: newton.utils.vec_allclose(q, capsule_q, atol=1e-4), + lambda q, qd: newton.utils.vec_allclose(q.p, capsule_q.p, atol=1e-4) + and newton.utils.vec_allclose(q.q, capsule_q.q, atol=1e-4), [1], ) box_q = wp.transform(0.0, 2.0, 0.25, 0.0, 0.0, 0.0, 1.0) newton.examples.test_body_state( self.model, self.state_0, "box at rest pose", - lambda q, qd: newton.utils.vec_allclose(q, box_q, atol=0.1), + lambda q, qd: newton.utils.vec_allclose(q.p, box_q.p, atol=0.1) + and newton.utils.vec_allclose(q.q, box_q.q, atol=0.1), [2], ) # we only test that the bunny didn't fall through the ground and didn't slide too far newton.examples.test_body_state( self.model, self.state_0, "bunny at rest pose", - lambda q, qd: q[2] > 0.01 and abs(q[0]) < 0.1 and abs(q[1] - 4.0) < 0.1, + lambda q, qd: q.p[2] > 0.01 and abs(q.p[0]) < 0.1 and abs(q.p[1] - 4.0) < 0.1, [3], )⛔ Skipped due to learnings
Learnt from: dylanturpin PR: newton-physics/newton#806 File: newton/_src/sim/ik/ik_objectives.py:0-0 Timestamp: 2025-09-25T16:14:22.002Z 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.Learnt from: dylanturpin PR: newton-physics/newton#806 File: newton/_src/sim/ik/ik_objectives.py:0-0 Timestamp: 2025-09-25T16:14:22.002Z 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.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.
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (5)
newton/examples/robot/example_robot_anymal_c_walk.py (1)
231-246: Optional: silence Ruff ARG005 in lambdasIf you keep the lambdas, rename unused parameters to
_to quiet ARG005.- lambda q, qd: q[2] > 0.2, + lambda q, _qd: q[2] > 0.2, @@ - lambda q, qd: newton.utils.vec_allclose(qd, forward_vel, rtol=0.1, atol=0.15), + lambda _q, qd: newton.utils.vec_allclose(qd, forward_vel, rtol=0.1, atol=0.15),newton/examples/selection/example_selection_materials.py (1)
255-261: Optional: silence Ruff ARG005 and prefer explicit underscore for unused argsRename the unused qd parameter to
_for clarity and to satisfy linters.- lambda q, qd: q[2] > 0.01, + lambda q, _qd: q[2] > 0.01,newton/examples/selection/example_selection_articulations.py (1)
287-293: Optional: silence Ruff ARG005 and prefer explicit underscore for unused argsRename the unused qd parameter to
_for clarity and to satisfy linters.- lambda q, qd: q[2] > 0.01, + lambda q, _qd: q[2] > 0.01,newton/examples/cloth/example_cloth_bending.py (1)
147-152: Optional: silence Ruff ARG005 for unused argRename the unused qd parameter to
_.- lambda q, qd: q[2] < 0.15, + lambda q, _qd: q[2] < 0.15,newton/examples/mpm/example_mpm_anymal.py (1)
34-34: Defer optional cross-example import to avoid hard import-time failures.Importing robot example utilities at module import time can break this example if that module isn’t available. Lazily import where used and provide a clear skip/fallback.
Apply this diff to remove the hard import:
-from newton.examples.robot.example_robot_anymal_c_walk import compute_obs, lab_to_mujoco, mujoco_to_labAdd this inside Example.init (near where you first use these symbols):
# Lazy import to avoid module-level failures if the example pack isn’t present try: from newton.examples.robot.example_robot_anymal_c_walk import compute_obs, lab_to_mujoco, mujoco_to_lab except ImportError as e: raise ImportError("Missing dependency: newton.examples.robot.example_robot_anymal_c_walk") from eIf preferred, I can wire this to gracefully skip tests when the module is absent instead of raising.
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (16)
newton/examples/__init__.py(5 hunks)newton/examples/basic/example_basic_joints.py(5 hunks)newton/examples/cloth/example_cloth_bending.py(2 hunks)newton/examples/cloth/example_cloth_franka.py(3 hunks)newton/examples/cloth/example_cloth_hanging.py(4 hunks)newton/examples/cloth/example_cloth_style3d.py(2 hunks)newton/examples/cloth/example_cloth_twist.py(3 hunks)newton/examples/mpm/example_mpm_anymal.py(5 hunks)newton/examples/robot/example_robot_allegro_hand.py(2 hunks)newton/examples/robot/example_robot_anymal_c_walk.py(1 hunks)newton/examples/robot/example_robot_humanoid.py(3 hunks)newton/examples/robot/example_robot_policy.py(2 hunks)newton/examples/selection/example_selection_articulations.py(2 hunks)newton/examples/selection/example_selection_cartpole.py(2 hunks)newton/examples/selection/example_selection_materials.py(2 hunks)newton/tests/test_examples.py(15 hunks)
🧰 Additional context used
🧠 Learnings (6)
📚 Learning: 2025-08-25T21:41:45.795Z
Learnt from: dylanturpin
PR: newton-physics/newton#634
File: newton/tests/test_examples.py:329-333
Timestamp: 2025-08-25T21:41:45.795Z
Learning: Newton examples use a centralized CLI argument parsing system in newton/examples/__init__.py. The create_parser() function defines common arguments like --device, --viewer, --output-path, and --num-frames, while init(parser) creates viewers based on parsed arguments. Individual example scripts don't need to define these flags themselves - they inherit them from the centralized system via the example_map and runpy execution.
Applied to files:
newton/examples/cloth/example_cloth_style3d.pynewton/examples/selection/example_selection_articulations.pynewton/examples/selection/example_selection_materials.pynewton/examples/robot/example_robot_allegro_hand.pynewton/examples/__init__.pynewton/examples/robot/example_robot_humanoid.pynewton/examples/selection/example_selection_cartpole.pynewton/examples/mpm/example_mpm_anymal.pynewton/examples/basic/example_basic_joints.pynewton/examples/cloth/example_cloth_franka.pynewton/examples/cloth/example_cloth_twist.pynewton/examples/cloth/example_cloth_bending.py
📚 Learning: 2025-08-27T19:05:44.697Z
Learnt from: Milad-Rakhsha-NV
PR: newton-physics/newton#535
File: newton/tests/test_examples.py:320-414
Timestamp: 2025-08-27T19:05:44.697Z
Learning: In newton/examples/__init__.py, the robot policy example is registered with the key "robot_policy" (not "robot.example_robot_policy"), so tests should reference it as name="robot_policy".
Applied to files:
newton/examples/robot/example_robot_allegro_hand.pynewton/tests/test_examples.pynewton/examples/robot/example_robot_policy.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/examples/mpm/example_mpm_anymal.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/examples/mpm/example_mpm_anymal.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/examples/mpm/example_mpm_anymal.py
📚 Learning: 2025-08-12T18:04:06.577Z
Learnt from: nvlukasz
PR: newton-physics/newton#519
File: newton/_src/solvers/featherstone/kernels.py:75-75
Timestamp: 2025-08-12T18:04:06.577Z
Learning: The Newton physics framework requires nightly Warp builds, which means compatibility concerns with older stable Warp versions (like missing functions such as wp.spatial_adjoint) are not relevant for this project.
Applied to files:
newton/examples/cloth/example_cloth_twist.pynewton/examples/cloth/example_cloth_bending.py
🧬 Code graph analysis (15)
newton/examples/cloth/example_cloth_style3d.py (2)
newton/examples/__init__.py (2)
test_particle_state(108-161)run(164-202)newton/_src/utils/__init__.py (1)
vec_inside_limits(211-218)
newton/examples/selection/example_selection_articulations.py (1)
newton/examples/__init__.py (2)
test_body_state(49-105)run(164-202)
newton/examples/selection/example_selection_materials.py (1)
newton/examples/__init__.py (2)
test_body_state(49-105)run(164-202)
newton/examples/robot/example_robot_allegro_hand.py (2)
newton/examples/__init__.py (1)
test_body_state(49-105)newton/tests/test_examples.py (1)
run(100-204)
newton/examples/__init__.py (4)
newton/_src/sim/state.py (1)
State(21-112)newton/_src/sim/contacts.py (1)
Contacts(23-93)newton/_src/sim/control.py (1)
Control(21-77)newton/tests/test_examples.py (1)
run(100-204)
newton/examples/robot/example_robot_humanoid.py (2)
newton/examples/__init__.py (2)
test_body_state(49-105)run(164-202)newton/tests/test_examples.py (1)
run(100-204)
newton/examples/robot/example_robot_anymal_c_walk.py (2)
newton/examples/__init__.py (3)
test_body_state(49-105)init(298-341)run(164-202)newton/_src/utils/__init__.py (1)
vec_allclose(200-207)
newton/examples/selection/example_selection_cartpole.py (3)
newton/_src/sim/builder.py (1)
body_count(515-519)newton/examples/__init__.py (2)
test_body_state(49-105)run(164-202)newton/_src/utils/__init__.py (1)
vec_allclose(200-207)
newton/examples/cloth/example_cloth_hanging.py (3)
newton/_src/sim/style3d/builder_style3d.py (1)
Style3DModelBuilder(38-698)newton/examples/__init__.py (2)
test_particle_state(108-161)run(164-202)newton/_src/utils/__init__.py (1)
vec_inside_limits(211-218)
newton/examples/mpm/example_mpm_anymal.py (4)
newton/examples/robot/example_robot_anymal_c_walk.py (1)
compute_obs(60-74)newton/examples/robot/example_robot_policy.py (1)
compute_obs(113-155)newton/_src/solvers/mujoco/solver_mujoco.py (1)
SolverMuJoCo(1136-2844)newton/examples/__init__.py (3)
test_body_state(49-105)test_particle_state(108-161)run(164-202)
newton/examples/basic/example_basic_joints.py (1)
newton/examples/__init__.py (2)
test_body_state(49-105)run(164-202)
newton/examples/cloth/example_cloth_franka.py (2)
newton/examples/__init__.py (2)
test_particle_state(108-161)test_body_state(49-105)newton/_src/utils/__init__.py (1)
vec_inside_limits(211-218)
newton/examples/cloth/example_cloth_twist.py (2)
newton/examples/__init__.py (2)
test_particle_state(108-161)run(164-202)newton/_src/utils/__init__.py (1)
vec_inside_limits(211-218)
newton/examples/cloth/example_cloth_bending.py (2)
newton/examples/__init__.py (2)
test_particle_state(108-161)run(164-202)newton/_src/utils/__init__.py (1)
vec_inside_limits(211-218)
newton/examples/robot/example_robot_policy.py (1)
newton/examples/__init__.py (2)
test_body_state(49-105)run(164-202)
🪛 Ruff (0.13.1)
newton/examples/cloth/example_cloth_style3d.py
180-180: Unused lambda argument: qd
(ARG005)
newton/examples/selection/example_selection_articulations.py
292-292: Unused lambda argument: qd
(ARG005)
newton/examples/selection/example_selection_materials.py
260-260: Unused lambda argument: qd
(ARG005)
newton/examples/robot/example_robot_allegro_hand.py
203-203: Unused lambda argument: qd
(ARG005)
newton/examples/__init__.py
91-91: Avoid specifying long messages outside the exception class
(TRY003)
105-105: Avoid specifying long messages outside the exception class
(TRY003)
148-148: Avoid specifying long messages outside the exception class
(TRY003)
161-161: Avoid specifying long messages outside the exception class
(TRY003)
186-186: Avoid specifying long messages outside the exception class
(TRY003)
190-190: Avoid specifying long messages outside the exception class
(TRY003)
194-194: Avoid specifying long messages outside the exception class
(TRY003)
198-198: Avoid specifying long messages outside the exception class
(TRY003)
202-202: Avoid specifying long messages outside the exception class
(TRY003)
newton/examples/robot/example_robot_humanoid.py
122-122: Unused lambda argument: qd
(ARG005)
128-128: Unused lambda argument: q
(ARG005)
newton/examples/robot/example_robot_anymal_c_walk.py
236-236: Unused lambda argument: qd
(ARG005)
243-243: Unused lambda argument: q
(ARG005)
newton/examples/selection/example_selection_cartpole.py
182-182: Unused lambda argument: qd
(ARG005)
189-189: Unused lambda argument: q
(ARG005)
199-199: Unused lambda argument: q
(ARG005)
211-211: Unused lambda argument: q
(ARG005)
newton/examples/cloth/example_cloth_hanging.py
193-193: Unused lambda argument: qd
(ARG005)
202-202: Unused lambda argument: qd
(ARG005)
newton/examples/mpm/example_mpm_anymal.py
297-297: Unused lambda argument: qd
(ARG005)
304-304: Unused lambda argument: q
(ARG005)
310-310: Unused lambda argument: qd
(ARG005)
newton/tests/test_examples.py
91-91: Avoid specifying long messages outside the exception class
(TRY003)
newton/examples/basic/example_basic_joints.py
204-204: Unused lambda argument: q
(ARG005)
211-211: Unused lambda argument: q
(ARG005)
218-218: Unused lambda argument: q
(ARG005)
225-225: Unused lambda argument: q
(ARG005)
newton/examples/cloth/example_cloth_franka.py
561-561: Unused lambda argument: qd
(ARG005)
566-566: Unused lambda argument: q
(ARG005)
572-572: Unused lambda argument: q
(ARG005)
newton/examples/cloth/example_cloth_twist.py
298-298: Unused lambda argument: qd
(ARG005)
303-303: Unused lambda argument: q
(ARG005)
newton/examples/cloth/example_cloth_bending.py
136-136: Unused lambda argument: q
(ARG005)
144-144: Unused lambda argument: qd
(ARG005)
150-150: Unused lambda argument: qd
(ARG005)
newton/examples/robot/example_robot_policy.py
417-417: Unused lambda argument: qd
(ARG005)
🪛 GitHub Actions: Pull Request
newton/examples/robot/example_robot_anymal_c_walk.py
[error] 26-26: ModuleNotFoundError: No module named 'torch'. Importing example_robot_anymal_c_walk requires PyTorch to be installed.
newton/tests/test_examples.py
[error] 311-311: ImportError: Test module robot.example_robot_anymal_c_walk not found. This followed a ModuleNotFoundError for torch during dynamic test discovery.
⏰ 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 (19)
newton/examples/basic/example_basic_joints.py (1)
199-226: Rename unused lambda parameters to satisfy lintRuff is still flagging the unused
qparameters (ARG005), so CI will keep failing. Please rename the unused arguments to_qacross these lambdas; this is the same lint issue that was called out earlier.newton.examples.test_body_state( self.model, self.state_0, "static bodies are not moving", - lambda q, qd: max(abs(qd)) == 0.0, + lambda _q, qd: max(abs(qd)) == 0.0, indices=[2, 4], ) newton.examples.test_body_state( self.model, self.state_0, "fixed link body has come to a rest", - lambda q, qd: max(abs(qd)) < 1e-2, + lambda _q, qd: max(abs(qd)) < 1e-2, indices=[0], ) newton.examples.test_body_state( self.model, self.state_0, "slider link body has come to a rest", - lambda q, qd: max(abs(qd)) < 1e-5, + lambda _q, qd: max(abs(qd)) < 1e-5, indices=[3], ) newton.examples.test_body_state( self.model, self.state_0, "movable links are not moving too fast", - lambda q, qd: max(abs(qd)) < 3.0, + lambda _q, qd: max(abs(qd)) < 3.0, indices=[1, 5], )newton/examples/cloth/example_cloth_style3d.py (1)
175-181: Rename unused lambda parameter to satisfy lintRuff (ARG005) complains about the unused
qdargument, which will block pre-commit. Rename it to_qd(or_) so CI passes.newton.examples.test_particle_state( self.state_0, "particles are within a reasonable volume", - lambda q, qd: newton.utils.vec_inside_limits(q, p_lower, p_upper), + lambda q, _qd: newton.utils.vec_inside_limits(q, p_lower, p_upper), )newton/examples/robot/example_robot_allegro_hand.py (1)
199-204: Correct transform access in Allegro hand testHere too,
qis awp.transform, soq[2]will throw once the Warp kernel runs. Access the position viaq.p[2], and mark the unused velocity argument to clear Ruff.newton.examples.test_body_state( self.model, self.state_0, "all bodies are above the ground", - lambda q, qd: q[2] > 0.9, + lambda q, _qd: q.p[2] > 0.9, )⛔ Skipped due to learnings
Learnt from: dylanturpin PR: newton-physics/newton#806 File: newton/_src/sim/ik/ik_objectives.py:0-0 Timestamp: 2025-09-25T16:14:22.002Z 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.Learnt from: dylanturpin PR: newton-physics/newton#806 File: newton/_src/sim/ik/ik_objectives.py:0-0 Timestamp: 2025-09-25T16:14:22.002Z 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.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.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.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.newton/examples/selection/example_selection_cartpole.py (2)
176-218: Confirm body index layout assumptionAssumes per-env bodies are contiguous and ordered [cart, pole1, pole2]. If asset order changes, indices will mismatch. Consider deriving indices from model.body_key names or ArticulationView metadata.
239-239: LGTM: updated runner signatureSwitched to run(example, args), aligned with the new API.
newton/examples/robot/example_robot_anymal_c_walk.py (2)
254-254: LGTM: updated runner signatureSwitched to run(example, args), aligned with the new API.
231-246: Fix CI import failure: gate top-level torch dependencyModule-level
import torchbreaks import in environments without PyTorch (see pipeline error). Defer/guard torch imports and JIT decorations so the module can be imported even when torch isn’t installed; raise a clear error only when executing this example.Suggested approach (changes outside this hunk):
- Replace top-level
import torchwith a guarded import and flag:
try:
import torch # type: ignore
TORCH_AVAILABLE = True
except Exception:
torch = None # type: ignore
TORCH_AVAILABLE = False- Define quat_rotate_inverse conditionally:
if TORCH_AVAILABLE:
@torch.jit.script
def quat_rotate_inverse(...): ...
else:
def quat_rotate_inverse(*_args, **_kwargs):
raise RuntimeError("This example requires PyTorch; install torch or skip it.")- Delay
from warp.torch import device_to_torchuntil inside Example.init and only if TORCH_AVAILABLE; otherwise raise a friendly error there.Alternatively, install torch in CI for this test matrix.
newton/examples/selection/example_selection_materials.py (1)
282-282: LGTM: updated runner signatureSwitched to run(example, args), aligned with the new API.
newton/examples/selection/example_selection_articulations.py (1)
309-309: LGTM: updated runner signatureSwitched to run(example, args), aligned with the new API.
newton/examples/cloth/example_cloth_bending.py (3)
162-162: LGTM: updated runner signatureSwitched to run(example, args), aligned with the new API.
132-138: Fix Warp lambda: Python max/abs breaks codegen
max(abs(qd))is not Warp-friendly and causes kernel generation errors. Usewp.length(qd)(or squared length) instead.- "particles have come close to a rest", - lambda q, qd: max(abs(qd)) < 0.1, + "particles have come close to a rest", + lambda _q, qd: wp.length(qd) < 0.1,
139-145: Avoid complex multi-arg lambdas for Warp; use a named @wp.funccreate_warp_function can fail to extract complex lambdas. Define a small Warp function and pass it instead.
- p_lower = wp.vec3(-3.0, -3.0, 0.0) - p_upper = wp.vec3(3.0, 3.0, 2.0) - newton.examples.test_particle_state( - self.state_0, - "particles are within a reasonable volume", - lambda q, qd: newton.utils.vec_inside_limits(q, p_lower, p_upper), - ) + p_lower = wp.vec3(-3.0, -3.0, 0.0) + p_upper = wp.vec3(3.0, 3.0, 2.0) + + @wp.func + def _within_bounds(q: wp.vec3, _qd: wp.vec3) -> bool: + return newton.utils.vec_inside_limits(q, p_lower, p_upper) + + newton.examples.test_particle_state( + self.state_0, + "particles are within a reasonable volume", + _within_bounds, + )newton/tests/test_examples.py (2)
224-224: Normalize option keys to underscores for consistency.use num_frames not num-frames; the builder will hyphenate automatically. Keeps style consistent and avoids mixed conventions.
Example fix (apply similarly across occurrences):
- test_options={"num-frames": 200}, + test_options={"num_frames": 200},- test_options_cpu={"width": 32, "height": 16, "num-frames": 10}, + test_options_cpu={"width": 32, "height": 16, "num_frames": 10},Based on learnings
Also applies to: 235-240, 251-251, 259-271, 277-279, 285-287, 293-295, 307-309, 315-316, 322-324, 331-331, 337-337, 344-346, 352-354, 360-360, 373-375, 382-382, 391-391, 398-398, 406-406, 415-416, 438-439, 469-470, 477-478, 485-486, 499-500, 508-509, 517-518, 526-527, 535-536, 549-550, 562-562, 570-570, 578-578
87-92: Don’t fail the whole suite on missing example modules; skip gracefully.Current import check raises ImportError and aborts CI. Skip the test when a module is absent.
Apply this diff:
- # verify the module exists - try: - importlib.import_module(f"newton.examples.{name}") - except ImportError as e: - raise ImportError(f"Test module {name} not found") from e + # verify the module exists; if missing, register a skipped test + try: + importlib.import_module(f"newton.examples.{name}") + except ImportError as e: + def _skipped(test, device): + test.skipTest(f"Example module newton.examples.{name} not found: {e}") + test_name = f"test_{name}_{test_suffix}" if test_suffix else f"test_{name}" + add_function_test(cls, test_name, _skipped, devices=devices, check_output=False) + returnAs per pipeline failures
newton/examples/cloth/example_cloth_franka.py (1)
555-573: Make test lambdas Warp-safe and silence unused-arg lint (ARG005).
max(abs(qd))won’t compile inside a Warp-created function.- Rename unused lambda params to
_to satisfy Ruff.Apply this diff:
newton.examples.test_particle_state( self.state_0, "particles are within a reasonable volume", - lambda q, qd: newton.utils.vec_inside_limits(q, p_lower, p_upper), + lambda q, _: newton.utils.vec_inside_limits(q, p_lower, p_upper), ) newton.examples.test_particle_state( self.state_0, "particle velocities are within a reasonable range", - lambda q, qd: max(abs(qd)) < 2.0, + lambda _, qd: wp.length(qd) < 2.0, ) newton.examples.test_body_state( self.model, self.state_0, "body velocities are within a reasonable range", - lambda q, qd: max(abs(qd)) < 0.7, + lambda _, qd: wp.length(qd) < 0.7, )As per coding guidelines and static analysis hints. Based on learnings
newton/examples/cloth/example_cloth_twist.py (1)
292-305: Use Warp intrinsics in test lambdas; fix unused params.Replace Python builtins and rename unused args to
_.Apply this diff:
newton.examples.test_particle_state( self.state_0, "particles are within a reasonable volume", - lambda q, qd: newton.utils.vec_inside_limits(q, p_lower, p_upper), + lambda q, _: newton.utils.vec_inside_limits(q, p_lower, p_upper), ) newton.examples.test_particle_state( self.state_0, "particle velocities are within a reasonable range", - lambda q, qd: max(abs(qd)) < 0.7, + lambda _, qd: wp.length(qd) < 0.7, )As per coding guidelines and static analysis hints. Based on learnings
newton/examples/cloth/example_cloth_hanging.py (1)
187-204: Silence unused-arg lint and keep Warp-compiled lambdas minimal.
qdisn’t used; rename to_to pass Ruff and keep the Warp-compiled callable clean.Apply this diff:
if self.solver_type != "style3d": # TODO(Style3D): handle ground collisions newton.examples.test_particle_state( self.state_0, "particles are above the ground", - lambda q, qd: q[2] > 0.0, + lambda q, _: q[2] > 0.0, ) min_x = -float(self.sim_width) * 0.11 p_lower = wp.vec3(min_x, -4.0, -1.8) p_upper = wp.vec3(0.1, 7.0, 4.0) newton.examples.test_particle_state( self.state_0, "particles are within a reasonable volume", - lambda q, qd: newton.utils.vec_inside_limits(q, p_lower, p_upper), + lambda q, _: newton.utils.vec_inside_limits(q, p_lower, p_upper), )As per static analysis hints
newton/examples/__init__.py (2)
42-45: Handle Warp extension types without__dict__.Core Newton types such as
newton.Model,State,Control, andContactsare Warp extension classes that don’t expose a Python__dict__. Hitting_find_nonfinite(model)therefore raisesAttributeError, so the new--testflow exits before reporting non-finite buffers. Add ahasattr(obj, "__dict__")guard with a safe fallback iteration (e.g.,dir()+getattr()) to keep the helper working across all Newton objects.- for key, attr in obj.__dict__.items(): + if hasattr(obj, "__dict__"): + members = obj.__dict__.items() + else: + members = ((name, getattr(obj, name)) for name in dir(obj) if not name.startswith("_")) + for key, attr in members:
103-105: Coerce body keys to strings before joining.
model.body_keycan contain NumPy/warp integers, so", ".join(failed_bodies)throwsTypeErrorwhen the failure path triggers. Convert each identifier tostr()first so the error message is always constructed.- failed_bodies = body_key[np.where(failures_np)[0]] - raise ValueError(f'Test "{test_name}" failed for the following bodies: [{", ".join(failed_bodies)}]') + failed_bodies = body_key[np.where(failures_np)[0]] + failed_labels = ", ".join(str(key) for key in np.atleast_1d(failed_bodies)) + raise ValueError(f'Test "{test_name}" failed for the following bodies: [{failed_labels}]')
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
asv/benchmarks/simulation/bench_cloth.py (1)
52-55: Fix missing args in second run() call (will raise TypeError)newton.examples.run now requires args; the call on Line 53 omits it and will fail at runtime. Apply the same args=None convention used above.
- newton.examples.run(self.example) + newton.examples.run(self.example, args=None)(Reference: run(example, args) in newton/examples/init.py.)
newton/examples/mpm/example_mpm_grain_rendering.py (1)
155-156: Use int for --points-per-particle.This flag is a count and is passed to
sample_render_grains(...); usingfloatrisks type issues.- parser.add_argument("--points-per-particle", "-ppp", type=float, default=8) + parser.add_argument("--points-per-particle", "-ppp", type=int, default=8)
🧹 Nitpick comments (3)
newton/examples/mpm/example_mpm_grain_rendering.py (1)
136-139: Avoid redundant np.prod on a scalar.
cell_volumeis already a scalar;np.prod(cell_volume)is an unnecessary no-op.- cell_volume = np.prod(cell_size) + cell_volume = np.prod(cell_size) ... - mass = np.prod(cell_volume) * density + mass = cell_volume * densitynewton/examples/__init__.py (1)
387-387: Export test_particle_state in all.It’s used as a public helper by examples; export it for consistency.
-__all__ = ["create_parser", "init", "run", "test_body_state"] +__all__ = ["create_parser", "init", "run", "test_body_state", "test_particle_state"]newton/examples/mpm/example_mpm_granular.py (1)
76-81: Use the MPM-wrapped model to initialize states. Replaceself.state_0 = self.model.state() self.state_1 = self.model.state()with
self.state_0 = mpm_model.state() self.state_1 = mpm_model.state()to automatically allocate MPM‐specific buffers (you may then drop the redundant
solver.enrich_state(…)calls).
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
asv/benchmarks/simulation/bench_cloth.py(1 hunks)newton/examples/__init__.py(5 hunks)newton/examples/mpm/example_mpm_grain_rendering.py(2 hunks)newton/examples/mpm/example_mpm_granular.py(2 hunks)newton/examples/mpm/example_mpm_multi_material.py(2 hunks)newton/tests/test_examples.py(15 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-25T21:41:45.795Z
Learnt from: dylanturpin
PR: newton-physics/newton#634
File: newton/tests/test_examples.py:329-333
Timestamp: 2025-08-25T21:41:45.795Z
Learning: Newton examples use a centralized CLI argument parsing system in newton/examples/__init__.py. The create_parser() function defines common arguments like --device, --viewer, --output-path, and --num-frames, while init(parser) creates viewers based on parsed arguments. Individual example scripts don't need to define these flags themselves - they inherit them from the centralized system via the example_map and runpy execution.
Applied to files:
newton/examples/mpm/example_mpm_granular.pynewton/examples/mpm/example_mpm_multi_material.pynewton/tests/test_examples.pynewton/examples/__init__.pynewton/examples/mpm/example_mpm_grain_rendering.py
📚 Learning: 2025-08-27T19:05:44.697Z
Learnt from: Milad-Rakhsha-NV
PR: newton-physics/newton#535
File: newton/tests/test_examples.py:320-414
Timestamp: 2025-08-27T19:05:44.697Z
Learning: In newton/examples/__init__.py, the robot policy example is registered with the key "robot_policy" (not "robot.example_robot_policy"), so tests should reference it as name="robot_policy".
Applied to files:
newton/tests/test_examples.py
🧬 Code graph analysis (5)
asv/benchmarks/simulation/bench_cloth.py (2)
newton/examples/__init__.py (1)
run(164-202)newton/tests/test_examples.py (1)
run(100-204)
newton/examples/mpm/example_mpm_granular.py (2)
newton/examples/__init__.py (2)
test_particle_state(108-161)run(164-202)newton/_src/utils/__init__.py (1)
vec_inside_limits(211-218)
newton/examples/mpm/example_mpm_multi_material.py (2)
newton/examples/__init__.py (1)
test_particle_state(108-161)newton/tests/test_examples.py (1)
run(100-204)
newton/examples/__init__.py (4)
newton/_src/sim/state.py (1)
State(21-112)newton/_src/sim/contacts.py (1)
Contacts(23-93)newton/_src/sim/control.py (1)
Control(21-77)newton/tests/test_examples.py (1)
run(100-204)
newton/examples/mpm/example_mpm_grain_rendering.py (2)
newton/examples/__init__.py (1)
test_particle_state(108-161)newton/tests/test_examples.py (1)
run(100-204)
🪛 Ruff (0.13.1)
newton/examples/mpm/example_mpm_granular.py
103-103: Unused lambda argument: qd
(ARG005)
112-112: Unused lambda argument: qd
(ARG005)
newton/examples/mpm/example_mpm_multi_material.py
108-108: Unused lambda argument: qd
(ARG005)
newton/tests/test_examples.py
91-91: Avoid specifying long messages outside the exception class
(TRY003)
newton/examples/__init__.py
91-91: Avoid specifying long messages outside the exception class
(TRY003)
105-105: Avoid specifying long messages outside the exception class
(TRY003)
148-148: Avoid specifying long messages outside the exception class
(TRY003)
161-161: Avoid specifying long messages outside the exception class
(TRY003)
186-186: Avoid specifying long messages outside the exception class
(TRY003)
190-190: Avoid specifying long messages outside the exception class
(TRY003)
194-194: Avoid specifying long messages outside the exception class
(TRY003)
198-198: Avoid specifying long messages outside the exception class
(TRY003)
202-202: Avoid specifying long messages outside the exception class
(TRY003)
newton/examples/mpm/example_mpm_grain_rendering.py
90-90: Unused lambda argument: qd
(ARG005)
🪛 GitHub Actions: Pull Request
newton/tests/test_examples.py
[error] 89-89: ImportError: Test module robot.example_robot_anymal_c_walk not found (likely due to missing torch dependency).
⏰ 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 Unit Tests on AWS EC2 (Pull Request)
- GitHub Check: Run GPU Benchmarks (Pull Request)
🔇 Additional comments (5)
asv/benchmarks/simulation/bench_cloth.py (1)
38-38: Update to new run() signature looks goodPassing args=None is appropriate for benchmarks so the test-only paths in run() remain disabled.
newton/tests/test_examples.py (2)
224-224: Use underscore option keys for consistency (auto-converted to hyphens).Prefer
num_frames(and other underscored keys) so_build_command_line_optionsconsistently emits the correct CLI flags.- test_options={"num-frames": 200}, + test_options={"num_frames": 200},Repeat similarly for other
"num-frames"occurrences in this file.Also applies to: 239-240, 251-251, 260-260, 269-271, 278-278, 285-285, 291-291, 305-306, 320-321, 342-343, 350-351, 466-467, 474-475, 482-483, 495-497, 505-506, 514-515, 523-524, 532-533, 546-547, 559-560, 567-568, 575-576
87-92: Don’t abort suite on missing example; register a skipped test instead.Gracefully handle ImportError by registering a test that calls skip at runtime.
- # verify the module exists - try: - importlib.import_module(f"newton.examples.{name}") - except ImportError as e: - raise ImportError(f"Test module {name} not found") from e + # verify the module exists; if missing, register a skipped test + try: + importlib.import_module(f"newton.examples.{name}") + except ImportError: + def _skip_missing(test, device): + test.skipTest(f"Test module {name} not found") + test_name = f"test_{name}_{test_suffix}" if test_suffix else f"test_{name}" + add_function_test(cls, test_name, _skip_missing, devices=devices, check_output=False) + returnnewton/examples/__init__.py (2)
37-46: Make _find_nonfinite robust for objects without dict.Some Newton/Warp types don’t expose
__dict__; fall back to iterating attributes viadir(...).- for key, attr in obj.__dict__.items(): + if hasattr(obj, "__dict__"): + members = obj.__dict__.items() + else: + members = ((name, getattr(obj, name)) for name in dir(obj) if not name.startswith("_")) + for key, attr in members: if isinstance(attr, wp.array): if not np.isfinite(attr.numpy()).all(): nonfinite_members.append(key)
103-106: Join failure labels as strings to avoid TypeError.
failed_bodiesmay contain non-strings (e.g., NumPy ints). Convert before joining.- raise ValueError(f'Test "{test_name}" failed for the following bodies: [{", ".join(failed_bodies)}]') + failed_labels = ", ".join(str(k) for k in failed_bodies.tolist()) + raise ValueError(f'Test "{test_name}" failed for the following bodies: [{failed_labels}]')
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
asv/benchmarks/simulation/bench_cloth.py (2)
38-38: Prefer consistent positionalNonefor clarityIn other examples we pass the second argument positionally. Using the keyword form here doesn’t add clarity—please stick with the positional
Nonefor consistency.
53-53: Optional: wrap args inNamespacefor future-proofingAlthough passing
Noneworks today, the runner now relies onargs.test. Consider handing a namespace with.test = Falseso future option additions don’t require touching the benchmarks again. Example:newton.examples.run(self.example, SimpleNamespace(test=False)).
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
asv/benchmarks/simulation/bench_cloth.py(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
asv/benchmarks/simulation/bench_cloth.py (2)
newton/examples/__init__.py (1)
run(164-202)newton/tests/test_examples.py (1)
run(100-204)
⏰ 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 Unit Tests on AWS EC2 (Pull Request)
- GitHub Check: Run GPU Benchmarks (Pull Request)
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
|
@eric-heiden We already saw these kind of error messages in the past. |
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (7)
newton/examples/robot/example_robot_g1.py (1)
133-144: Critical: Lambda callbacks use Python-only operations that break Warp kernel compilationThe lambdas passed to
test_body_stateuse Python indexing (q[2]) on awp.transformandmax(abs(qd))on awp.spatial_vector, which Warp cannot compile. When--testmode executes, the kernel generation will fail.This is a duplicate of a previous review comment. Define Warp-compatible helpers using intrinsics like
wp.transform_get_translationandwp.length:+@wp.func +def _body_above_ground(q: wp.transform, qd: wp.spatial_vector) -> bool: + return wp.transform_get_translation(q)[2] > 0.0 + +@wp.func +def _body_velocity_small(q: wp.transform, qd: wp.spatial_vector) -> bool: + return wp.length(qd.linear) < 1.0e-3 and wp.length(qd.angular) < 1.0e-3 + def test(self): newton.examples.test_body_state( self.model, self.state_0, "all bodies are above the ground", - lambda q, qd: q[2] > 0.0, + _body_above_ground, ) newton.examples.test_body_state( self.model, self.state_0, "all body velocities are small", - lambda q, qd: max(abs(qd)) < 0.001, + _body_velocity_small, )newton/examples/__init__.py (5)
42-42: Fix type hint: use wp.spatial_vectorThe type hint uses
wp.spatial_vectorfwhich is not a public Warp dtype. Usewp.spatial_vectorinstead:- test_fn: wp.Function | Callable[[wp.transform, wp.spatial_vectorf], bool], + test_fn: wp.Function | Callable[[wp.transform, wp.spatial_vector], bool],
94-94: Fix join on non-string body keys
model.body_keycan contain integers. When a failure occurs,", ".join(failed_bodies)will raiseTypeErrorbecause NumPy integers aren't strings. Convert identifiers to strings:- raise ValueError(f'Test "{test_name}" failed for the following bodies: [{", ".join(failed_bodies)}]') + failed_labels = ", ".join(str(k) for k in failed_bodies.tolist()) + raise ValueError(f'Test "{test_name}" failed for the following bodies: [{failed_labels}]')
136-137: Guard against missing particle buffers
state.particle_qorstate.particle_qdmay beNone(e.g., rigid-only examples). Add an early guard before accessingparticle_q.device:particle_q = state.particle_q particle_qd = state.particle_qd + if particle_q is None or particle_qd is None: + raise ValueError("Particle state is not available")
23-23: Critical: find_nan_members has blocking issuesThe imported
find_nan_membersfromnewton.tests.unittest_utilshas two critical problems based on past reviews and the provided snippet:
Missing
__dict__guard: Newton core types (Model,State,Control,Contacts) are Warp extension classes without a Python__dict__. Accessingobj.__dict__will raiseAttributeError.Incomplete check: The function only checks for NaN using
np.isnan()but should check for all nonfinite values (NaN, +inf, -inf) usingnp.isfinite().These issues should be fixed in
newton/tests/unittest_utils.py. Would you like me to generate a fix for that file?
378-378: Add test_particle_state to public exportsThe
test_particle_statefunction is a public helper but is not included in__all__:-__all__ = ["create_parser", "init", "run", "test_body_state"] +__all__ = ["create_parser", "init", "run", "test_body_state", "test_particle_state"]newton/examples/basic/example_basic_shapes.py (1)
174-181: Use wp.abs and lookup mesh index dynamicallyThe lambda uses Python
absinstead ofwp.abs, and hardcodes the mesh body index as[4]. Replace with Warp intrinsics and dynamic lookup:# we only test that the bunny didn't fall through the ground and didn't slide too far newton.examples.test_body_state( self.model, self.state_0, "bunny at rest pose", - lambda q, qd: q[2] > 0.01 and abs(q[0]) < 0.1 and abs(q[1] - 4.0) < 0.1, - [4], + lambda q, qd: q.p[2] > 0.01 and wp.abs(q.p[0]) < 0.1 and wp.abs(q.p[1] - 4.0) < 0.1, + [self.model.body_key.index("mesh")], )Note: Also changed
q[2]toq.p[2]to properly access the position component of the transform.
🧹 Nitpick comments (1)
newton/examples/basic/example_basic_shapes.py (1)
138-173: Rename unused lambda parameters to underscoreAll the test lambdas ignore the
qdparameter. Rename to_to indicate it's intentionally unused:newton.examples.test_body_state( self.model, self.state_0, "sphere at rest pose", - lambda q, qd: newton.utils.vec_allclose(q, sphere_q, atol=1e-4), + lambda q, _: newton.utils.vec_allclose(q, sphere_q, atol=1e-4), [0], ) # ... repeat for capsule, cylinder, boxApply similar changes to lines 144, 153, 162, and 171.
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
newton/examples/__init__.py(5 hunks)newton/examples/basic/example_basic_shapes.py(5 hunks)newton/examples/robot/example_robot_allegro_hand.py(4 hunks)newton/examples/robot/example_robot_g1.py(2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-25T21:41:45.795Z
Learnt from: dylanturpin
PR: newton-physics/newton#634
File: newton/tests/test_examples.py:329-333
Timestamp: 2025-08-25T21:41:45.795Z
Learning: Newton examples use a centralized CLI argument parsing system in newton/examples/__init__.py. The create_parser() function defines common arguments like --device, --viewer, --output-path, and --num-frames, while init(parser) creates viewers based on parsed arguments. Individual example scripts don't need to define these flags themselves - they inherit them from the centralized system via the example_map and runpy execution.
Applied to files:
newton/examples/basic/example_basic_shapes.py
🧬 Code graph analysis (4)
newton/examples/basic/example_basic_shapes.py (4)
newton/_src/sim/builder.py (1)
add_body(1179-1241)newton/_src/solvers/xpbd/solver_xpbd.py (1)
SolverXPBD(40-660)newton/examples/__init__.py (2)
test_body_state(38-94)run(153-193)newton/_src/utils/__init__.py (1)
vec_allclose(200-207)
newton/examples/robot/example_robot_allegro_hand.py (3)
newton/_src/sim/builder.py (1)
body_count(515-519)newton/examples/__init__.py (1)
test_body_state(38-94)newton/_src/utils/__init__.py (1)
vec_inside_limits(211-218)
newton/examples/__init__.py (3)
newton/tests/unittest_utils.py (1)
find_nan_members(256-265)newton/_src/sim/state.py (1)
State(21-112)newton/tests/test_examples.py (1)
run(98-202)
newton/examples/robot/example_robot_g1.py (1)
newton/examples/__init__.py (2)
test_body_state(38-94)run(153-193)
🪛 GitHub Actions: Pull Request
newton/examples/__init__.py
[error] 167-167: NotImplementedError: Example does not have a test method. Failure occurred while running 'coverage run --data-file=/tmp/tmpbpq29xfa/tmphjikd65l -m newton.examples.basic.example_basic_viewer --device cpu --test --viewer usd --output-path /home/runner/work/newton/newton/newton/tests/outputs/basic.example_basic_viewer_cpu.usd'.
🪛 Ruff (0.13.2)
newton/examples/basic/example_basic_shapes.py
144-144: Unused lambda argument: qd
(ARG005)
153-153: Unused lambda argument: qd
(ARG005)
162-162: Unused lambda argument: qd
(ARG005)
171-171: Unused lambda argument: qd
(ARG005)
179-179: Unused lambda argument: qd
(ARG005)
newton/examples/robot/example_robot_allegro_hand.py
210-210: Unused lambda argument: qd
(ARG005)
newton/examples/__init__.py
80-80: Avoid specifying long messages outside the exception class
(TRY003)
94-94: Avoid specifying long messages outside the exception class
(TRY003)
137-137: Avoid specifying long messages outside the exception class
(TRY003)
150-150: Avoid specifying long messages outside the exception class
(TRY003)
177-177: Avoid specifying long messages outside the exception class
(TRY003)
181-181: Avoid specifying long messages outside the exception class
(TRY003)
185-185: Avoid specifying long messages outside the exception class
(TRY003)
189-189: Avoid specifying long messages outside the exception class
(TRY003)
193-193: Avoid specifying long messages outside the exception class
(TRY003)
newton/examples/robot/example_robot_g1.py
137-137: Unused lambda argument: qd
(ARG005)
143-143: Unused lambda argument: q
(ARG005)
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
newton/examples/__init__.py (1)
92-94: Convert body keys to strings before joining.
failed_bodiescan contain non-string keys (e.g., NumPy ints), so", ".join(failed_bodies)raisesTypeError. Convert each key tostrbefore joining to keep the failure path working.- failed_bodies = body_key[np.where(failures_np)[0]] - raise ValueError(f'Test "{test_name}" failed for the following bodies: [{", ".join(failed_bodies)}]') + failed_bodies = body_key[np.where(failures_np)[0]] + failed_labels = ", ".join(str(key) for key in failed_bodies.tolist()) + raise ValueError(f'Test "{test_name}" failed for the following bodies: [{failed_labels}]')newton/examples/cloth/example_cloth_franka.py (1)
541-559: Replace Python builtins in Warp-compiled lambdas and rename unused args.This is the same issue flagged in the previous review. The lambda test callbacks use Python builtins (
max,abs) that are not Warp-compatible, and have unused parameters that should be renamed to_.Apply the previously suggested fix:
newton.examples.test_particle_state( self.state_0, "particles are within a reasonable volume", - lambda q, qd: newton.utils.vec_inside_limits(q, p_lower, p_upper), + lambda q, _: newton.utils.vec_inside_limits(q, p_lower, p_upper), ) newton.examples.test_particle_state( self.state_0, "particle velocities are within a reasonable range", - lambda q, qd: max(abs(qd)) < 2.0, + lambda _, qd: wp.length(qd) < 2.0, ) newton.examples.test_body_state( self.model, self.state_0, "body velocities are within a reasonable range", - lambda q, qd: max(abs(qd)) < 0.7, + lambda _, qd: wp.length(qd) < 0.7, )If you need separate bounds for angular vs. linear velocity components, use:
wp.length(wp.spatial_top(qd)) < w_max and wp.length(wp.spatial_bottom(qd)) < v_max
🧹 Nitpick comments (1)
newton/examples/__init__.py (1)
41-44: Use the public Warp spatial-vector type.Warp exposes
wp.spatial_vector, notwp.spatial_vectorf. Keeping the annotation as-is risksAttributeErrorat import time on newer Warp builds. Swap towp.spatial_vectorfor compatibility.
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
newton/examples/__init__.py(6 hunks)newton/examples/cloth/example_cloth_franka.py(9 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-25T21:41:45.795Z
Learnt from: dylanturpin
PR: newton-physics/newton#634
File: newton/tests/test_examples.py:329-333
Timestamp: 2025-08-25T21:41:45.795Z
Learning: Newton examples use a centralized CLI argument parsing system in newton/examples/__init__.py. The create_parser() function defines common arguments like --device, --viewer, --output-path, and --num-frames, while init(parser) creates viewers based on parsed arguments. Individual example scripts don't need to define these flags themselves - they inherit them from the centralized system via the example_map and runpy execution.
Applied to files:
newton/examples/cloth/example_cloth_franka.py
🧬 Code graph analysis (2)
newton/examples/cloth/example_cloth_franka.py (2)
newton/_src/sim/builder.py (1)
ModelBuilder(67-4471)newton/examples/__init__.py (1)
run(153-193)
newton/examples/__init__.py (4)
newton/tests/unittest_utils.py (1)
find_nan_members(256-265)newton/_src/sim/state.py (1)
State(21-112)newton/tests/test_examples.py (1)
run(98-202)newton/examples/cloth/example_cloth_franka.py (1)
test(541-559)
🪛 Ruff (0.13.2)
newton/examples/cloth/example_cloth_franka.py
547-547: Unused lambda argument: qd
(ARG005)
552-552: Unused lambda argument: q
(ARG005)
558-558: Unused lambda argument: q
(ARG005)
newton/examples/__init__.py
80-80: Avoid specifying long messages outside the exception class
(TRY003)
94-94: Avoid specifying long messages outside the exception class
(TRY003)
137-137: Avoid specifying long messages outside the exception class
(TRY003)
150-150: Avoid specifying long messages outside the exception class
(TRY003)
177-177: Avoid specifying long messages outside the exception class
(TRY003)
181-181: Avoid specifying long messages outside the exception class
(TRY003)
185-185: Avoid specifying long messages outside the exception class
(TRY003)
189-189: Avoid specifying long messages outside the exception class
(TRY003)
193-193: Avoid specifying long messages outside the exception class
(TRY003)
⏰ 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 (5)
newton/examples/cloth/example_cloth_franka.py (5)
167-176: LGTM! ModelBuilder initialization simplified.The removal of explicit gravity parameters and transformation arguments simplifies the initialization while maintaining correct behavior through default values and the gravity swap mechanism introduced later.
259-263: LGTM! Clever CUDA graph-compatible gravity swap.The use of Warp arrays for gravity values enables swapping between zero gravity (robot solver) and earth gravity (cloth solver) via
.assign()without invalidating CUDA graph captures. This maintains stable device memory pointers while allowing dynamic behavior changes.
506-521: LGTM! Correct gravity and particle simulation toggling.The logic correctly disables particle simulation and applies zero gravity for the robot solver, then restores both settings for the cloth solver. The updated comment on line 506 clearly explains the intent.
537-539: LGTM! Updated to new render API.The render method correctly uses the updated API, passing
sim_timetobegin_frameand logging state, aligning with the new render flow.
571-571: LGTM! Updated to new run() signature.The addition of the
argsparameter aligns with the API change that enables test execution via the--testCLI flag and generic NaN validation.
|
OK the tests are working now, thanks @Kenny-Vilella! The test time is not worse than before this PR, it seems actually slightly faster: 20min vs 22min on main. |
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Signed-off-by: Eric Heiden <eric-heiden@outlook.com>
Description
test()function for various examples and added some helper methods to assist with verifying the state of bodies and particlesexample_sensor_contact.pyappears to have issues on CPU, I've disable the CPU version for it now and assigned Investigate NaN issues in example_sensor_contact.py on CPU #860 to @camevor--testto its CLI argsbuilder.replicate()newton.examples.run(example, args)now requires an additionalargsinput that wasn't there beforeNewton Migration Guide
Please ensure the migration guide for warp.sim users is up-to-date with the changes made in this PR.
docs/migration.rstis up-to dateBefore your PR is "Ready for review"
newton/tests/test_examples.py)pre-commit run -aSummary by CodeRabbit
New Features
Tests
Chores