Newton selection and USD import design

Newton assets without ArticulationRootAPI

Investigation of how Newton should treat USD mechanisms that author rigid bodies and joints but no articulation root, with a concrete mapping from Isaac Lab's ArticulationData contract to Newton APIs for rootless and closed-loop mechanisms.

Executive summary

Keep the importer invariant

If a USD asset has no PhysicsArticulationRootAPI, Newton should not silently create partial articulation metadata. The local fix makes rootless joints consistently rootless.

Expose mechanisms, not just joints

Isaac Lab needs more than joint_pos and joint_vel. It needs an asset-level, batched state and command contract covering joints, bodies, root state, defaults, limits, and actuator metadata.

Make tree inference explicit

Invented articulations are a compatibility tool for FK, MuJoCo, and tree-only APIs. They should be opt-in because cyclic mechanisms require a spanning tree choice and loop-joint handling.

Recommendation: add a Newton-native MechanismView for rootless maximal-coordinate mechanisms, composed from JointView, BodyView, and a root/base policy. JointView is necessary, but not sufficient for Isaac Lab. Then add an explicit importer compatibility mode such as rootless_articulation_policy="infer_tree" for users who need tree-compatible tooling.

Raw data: asset analysis JSON and solver smoke JSON. External context: Isaac Lab PR isaac-sim/IsaacLab#6027, the Isaac Lab ArticulationData source, and the Isaac Lab Articulation source.

Importer baseline

The bug was not that Newton refused to treat a rootless asset as an articulation. The bug was that one special case did synthesize an articulation: a body-to-world fixed joint with no PhysicsArticulationRootAPI. That produced mixed metadata: the root joint belonged to articulation 0 while the rest of the asset remained in articulation -1.

The committed fix removes that special case. A no-root asset now imports consistently as a set of orphan joints. Normal finalize() raises and tells the caller to use skip_validation_joints=True; maximal-coordinate solvers can then consume the authored joint graph directly.

This is deliberately not a user experience endpoint. It is a better invariant: no USD articulation root means no Newton articulation metadata unless a caller explicitly requests compatibility inference.

What ArticulationData does

In Isaac Lab, ArticulationData is the cached tensor state behind Articulation.data. It is not just a convenience wrapper around joint arrays. It is the robot data contract used by tasks, managers, actuators, reset events, observations, rewards, termination logic, sensors, and randomization code.

The surrounding Articulation class owns the simulator view, applies actuator models, writes commands to simulation, and exposes finders such as find_joints() and find_bodies(). ArticulationData stores and lazily updates the tensors those systems read.

AreaWhat ArticulationData providesWhy Isaac Lab needs it
Identity and batchingbody_names, joint_names, tendon names, instance count, body count, joint count, and stable per-instance order.Task configs address joints and bodies by name expressions. Managers need deterministic indices and identical tensor shapes across environments.
Default reset statedefault_root_state, default_joint_pos, default_joint_vel, default mass, inertia, and default joint properties parsed from simulation or config.Reset events clone defaults, apply noise, clamp to limits, and write the state back into selected environments.
Root stateroot_state_w, root_link_state_w, root_com_state_w, plus sliced position, orientation, linear velocity, and angular velocity views.Locomotion rewards, base observations, commands, terminations, and resets need a consistent base convention even when the USD did not define an articulation root.
Body and link statebody_state_w, body_link_state_w, body_com_state_w, body_com_acc_w, and local COM poses.Rewards, contacts, frame transforms, sensors, termination checks, and domain randomization often operate on links, not just joints.
Joint statejoint_pos, joint_vel, and finite-difference joint_acc, shaped (num_instances, num_joints).Policies observe joint state, reset code writes joint state, and actuator models compute commands from joint position and velocity errors.
Joint propertiesPosition, velocity, and effort limits; stiffness; damping; armature; static, dynamic, and viscous friction; soft position and velocity limits; gear ratios.Isaac Lab uses these for clipping actions, configuring actuator models, randomizing dynamics, computing safety regions, and validating reset states.
Command buffersjoint_pos_target, joint_vel_target, joint_effort_target, computed_torque, and applied_torque.Explicit actuators produce torques from targets. Implicit actuators pass targets to the simulator. RL code expects both paths to use the same asset interface.
Derived observationsprojected_gravity_b, heading_w, root velocities in base frame, COM-derived link velocities, and sliced convenience tensors.Many standard locomotion and manipulation observations are built from these cached derived tensors.

Therefore, Isaac Lab does not only need a Newton API that can select joints. It needs a Newton API that can act as the canonical batched mechanism handle for reset, control, observation, reward, and property access.

What Isaac Lab needs from Newton

For rootless closed-loop assets, Isaac Lab needs a Newton object that can replace the simulator-facing role of an articulation view without claiming reduced-coordinate tree semantics. The core requirement is a batched mechanism interface: select one robot per environment, expose stable joint/body/root tensors, write resets and commands, and surface properties for actuator setup and randomization.

NeedNewton should provideNotes for no-root and closed-loop assets
Asset selectionPath or regex matching for bodies, joints, and shapes under a robot path, with explicit include/exclude filters.The workaround in PR #6027 assumes all bodies and joints in a world belong to the robot. Newton should not force Isaac Lab to make that assumption.
Stable indexingjoint_ids, body_ids, shape_ids, joint_coord_ids, joint_dof_ids, names, labels, and deterministic per-world ordering.Isaac Lab configs resolve names once, then use indices repeatedly. Reordering or hidden filtering must be explicit and reproducible.
Batched readsRoot, body, COM, and joint state tensors shaped by environment and selected entity: (num_envs, ...) or (num_envs, num_entities, ...).Use Warp gather/view kernels under the hood. Do not require Python indexing through global arrays for every task.
Batched writesPer-environment writes for root pose/velocity, body pose/velocity where meaningful, joint position/velocity state, joint targets, efforts, and external body wrenches.Reset code needs partial env_ids and partial joint_ids. It also expects cached data to be updated or invalidated consistently.
Actuator supportJoint target buffers, effort buffers, computed/applied effort reporting, and property tensors for explicit and implicit actuator models.Closed-loop mechanisms still need action clipping, PD control, effort limits, and actuator grouping by joint-name expressions.
Properties and defaultsDefault root state, default joint state, mass, inertia, joint limits, velocity limits, effort limits, stiffness, damping, armature, friction, soft limits, and gear ratios.These are not optional for RL. They are used in resets, randomization, action scaling, and actuator initialization.
Root/base policyA declared root body and base mode: fixed-base, authored floating-base, implicit floating-base, or no root state.No-root USDs do not tell Isaac Lab which body should become the base. Newton should require or infer this policy and expose it in the view.
Closed-loop semanticsLoop joints remain normal solver-visible constraints in maximal-coordinate solvers. Tree-only features are marked unavailable or require an inferred tree mode.Do not hide loop-closing joints from Kamino, XPBD, or Semi-Implicit just to satisfy ArticulationView-style APIs.
Unsupported tree featuresClear errors or capability flags for FK, Jacobians, mass matrices, and reduced-coordinate operations when no tree articulation exists.Isaac Lab can branch on capabilities if Newton reports them directly.

Concrete adapter surface

For Isaac Lab to remove a local ClosedLoopView workaround, Newton should provide enough of this surface directly or through a thin adapter:

CategoryExpected surfacePurpose
Counts and namescount, world_count, count_per_world, joint_coord_count, joint_dof_count, link_count, joint_names, joint_dof_names, body_names, link_names.Let Isaac Lab size buffers, resolve name expressions, and maintain one robot view per environment.
Index mapsjoint_ids, body_ids, shape_ids, joint_coord_ids, joint_dof_ids, per-world strides, and selected global-array offsets.Avoid raw-array guessing in Isaac Lab and make gathered tensors deterministic.
Base metadatais_fixed_base, is_floating_base, root_body_id, root_joint_id if authored, implicit_free_base, and capability flags.Replace the articulation-root assumption with an explicit base convention.
State readersget_root_transforms(), get_root_velocities(), get_link_transforms(), get_link_velocities(), get_body_coms(), get_dof_positions(), get_dof_velocities().Feed ArticulationData-style cached tensors for observations, rewards, and resets.
State writersSet root pose/velocity, joint position/velocity state, body pose/velocity when supported, and invalidate or refresh cached derived tensors.Support Isaac Lab reset events with partial env_ids and partial joint/body selections.
Command writersSet joint position targets, velocity targets, effort targets, direct joint forces, and external body forces/torques.Support both implicit target-based control and explicit actuator models.
Property accessRead and optionally write joint limits, velocity limits, effort limits, stiffness, damping, armature, friction, mass, inertia, soft limits, and gear ratio data.Support actuator initialization, action clipping, domain randomization, and safety limits.

The minimum useful API is not JointView; it is MechanismView. JointView should be the joint slice of that mechanism, but Isaac Lab needs the whole mechanism contract.

Proposed Newton API layers

The clean architecture is to separate selection from semantics. A rootless mechanism can be selected and controlled without pretending it is a reduced-coordinate articulation.

JointView

Selects joints by path/name/type, maps joints to coordinate and DOF ranges, reads and writes joint state, targets, controls, and joint properties.

BodyView

Selects bodies and shapes by path/name, reads body/link/COM transforms and velocities, applies body wrenches, and exposes mass, inertia, shape membership, and contact-facing ids.

MechanismView

Composes joint, body, and root/base access for one asset per environment. This is the Newton object Isaac Lab should adapt to for rootless mechanisms.

MechanismView should expose capability flags such as supports_fk, supports_mass_matrix, supports_loop_joints, supports_root_state, and supports_articulation_tree. Then Isaac Lab can distinguish a true articulation from a maximal-coordinate mechanism while keeping the same high-level reset/control/observation flow.

ArticulationView should stay tree-centric. Extending it until it accepts arbitrary rootless joint graphs would blur reduced-coordinate and maximal-coordinate semantics, and would hide solver-specific limitations.

Importer inference option

The importer can still synthesize a compatibility articulation for a connected joint component with no USD articulation root. This is useful for FK, MuJoCo, and existing tree-only APIs. It should be explicit because cyclic mechanisms require choosing a spanning tree and leaving loop-closing joints outside the tree.

Newton already has metadata that can represent this layout: articulation_start points at the first tree joint, articulation_end points after the regular tree joints, and the next articulation_start acts as the upper bound when include_loop_closing_joints=True. The ordered synthetic four-bar and boxes_fourbar.usda confirm that ArticulationView skips loop joints by default and includes them when requested.

RequirementReason
Partition each rootless connected component into a deterministic spanning tree plus loop-closing edges.Tree-compatible APIs need a unique parent chain, while maximal-coordinate solvers still need loop joints.
Emit or reorder joints so the tree block is contiguous and loop joints immediately follow it.ArticulationView assumes contiguous articulation joint ranges.
Add articulation metadata only for the tree block, and keep loop joints solver-visible.Kamino, XPBD, and Semi-Implicit should still see authored loop constraints.
Expose an import summary containing inferred root, tree joints, loop joints, and any reordered coordinates.Users and downstream libraries need to know what changed relative to the USD.
Put this behind rootless_articulation_policy="infer_tree"; keep "none" as the default.Silent articulation synthesis changes semantics and can surprise users who intentionally authored no articulation.

Importer inference is not a substitute for MechanismView. It is a compatibility mode for tree-only consumers.

Evidence from assets

A scan of newton/examples/assets found three jointed USD assets without PhysicsArticulationRootAPI: boxes_fourbar.usda, fourbar_pole_no_articulation.usda, and fourbar_pole_floating_no_articulation.usda. The table also includes two synthetic no-root stages used to isolate edge cases.

AssetImported jointsArticulationsJointView-style matchTree jointsLoop jointsInvented articulation probe
single_hinge_no_root101 joint, 1 coord[0]noneworks ArticulationView sees 1 joint.
ordered_fourbar_no_root505 joints, 4 coords[0,1,2,3][4]works default view sees 4 tree joints; include_loop_closing_joints=True sees all 5.
boxes_fourbar.usda404 joints, 4 coords[0,1,2][3]works existing order already has tree first, loop last.
fourbar_pole_no_articulation.usda606 joints, 5 coords[0,1,2,3,5][4]needs reorder post-import add_articulation() fails because tree joints are not contiguous.
fourbar_pole_floating_no_articulation.usda505 joints, 5 coords[0,1,2,4][3]needs reorder post-import add_articulation() fails because the loop joint appears before a tree-tail joint.

Interpretation: direct joint/body selection is robust to all five cases because it uses global model arrays. Inventing articulations is viable only when the importer emits a contiguous tree-joint block followed by loop-closing joints.

Solver smoke

The floating fourbar pole asset was imported with no articulation and finalized with skip_validation_joints=True. No FK was called. Each solver stepped 20 cached iterations after one warmup step; timings include Python overhead and are smoke-scale only.

SolverStatusArticulationsJoint articulation arrayFinite stateCached ms / step
XPBDok0[-1,-1,-1,-1,-1]yes2.65
Semi-Implicitok0[-1,-1,-1,-1,-1]yes0.31
Kaminook0[-1,-1,-1,-1,-1]yes5.59

These numbers are not intended as a solver comparison. They show that the consistent no-articulation model can be stepped by maximal-coordinate solvers without creating an articulation for selection.

Recommended implementation plan

  1. Add newton.selection.JointView for path matching over joint labels, joint-to-coordinate mapping, joint state reads/writes, target writes, effort writes, and joint property tensors.
  2. Add newton.selection.BodyView for body/link/COM state, shape membership, body properties, and body wrench application.
  3. Add newton.selection.MechanismView that composes JointView, BodyView, and a root/base policy for one asset per environment. This is the interface Isaac Lab should use for no-root assets.
  4. Expose Isaac Lab-critical metadata: stable joint/body names, per-world ordering, joint coordinate and DOF ids, body ids, shape ids, root body id, base mode, limits, effort/velocity limits, stiffness, damping, friction, armature, default states, mass, and inertia.
  5. Add batched gather/scatter kernels for state and command access. Avoid Python .numpy() indexing in production paths.
  6. Update the importer warning to point rootless-joint users at MechanismView for maximal-coordinate workflows and at the future inference option for tree-compatibility workflows.
  7. Add importer option rootless_articulation_policy="none" | "infer_tree". Keep "none" as default.
  8. When inference is enabled, build a deterministic spanning forest, emit tree joints first, emit loop joints immediately after each tree, and store an import summary of inferred tree and loop joints.
  9. Add regression coverage for the four cases in this report: open no-root chain, ordered four-bar, boxes_fourbar.usda, and both fourbar pole no-root variants.
  10. Coordinate with Isaac Lab so its Newton backend can adapt ArticulationData-style code to MechanismView without preserving a local ClosedLoopView clone.

Short version: do not force rootless mechanisms into ArticulationView just to make RL possible. Give Isaac Lab a Newton-native mechanism interface with the same practical data coverage as ArticulationData, and make articulation inference an explicit compatibility layer for tree-only consumers.

Last updated: 2026-06-09.