Working with Articulations and Kinematic Chains in the Newton Engine
Use ArticulationView to create tensor-friendly, batched views of rigid-body articulations for high-performance manipulation of joints, DOFs, and kinematic chains across multiple simulation worlds.
The Newton physics engine manages complex robotic systems through a specialized selection interface designed for batch operations. When working with articulations and kinematic chains in the Newton engine, developers leverage the ArticulationView class to build compact, regular memory layouts that treat selected bodies as dense tensors indexed by world and articulation instance.
Understanding ArticulationView Architecture
Public API and Internal Implementation
The public interface lives in newton/selection.py, which re-exports the implementation from the internal utility module:
# newton/selection.py
from ._src.utils.selection import ArticulationView
The core logic resides in newton/_src/utils/selection.py at lines 31-45, where the ArticulationView class parses the model, applies pattern-based filters, and computes contiguous or strided layouts for joints, DOFs, links, shapes, and MuJoCo tendons.
Core Data Structures
The view relies on two primary internal structures to describe memory layouts:
FrequencyLayout (lines 12-28): Describes the offset, stride-between-worlds, stride-within-worlds, and selected indices for a specific attribute frequency (e.g., JOINT, BODY, SHAPE).
Slice (lines 93-105): A hashable mimic of Python's slice object used for caching computed layouts.
Selection Workflow
The ArticulationView constructor executes a nine-step validation and layout process:
-
Pattern matching:
find_matching_ids(lines 63-76) scansmodel.articulation_labelagainst the user's glob pattern, returning per-world groups and global IDs. -
Validation: Articulations must be either all per-world or all global; mixed selection raises
ValueError. Uniform articulation counts per world are enforced. -
Template articulation: The first matching articulation (
arti_0) serves as a template to infer joint/link/shape ordering. -
Metadata gathering: Loops over template joints to collect IDs, names, types, DOF ranges, and associated link/shape IDs.
-
Stride computation: Calculates outer stride (distance between consecutive worlds) and inner stride (distance between articulations within a world). Non-uniform strides raise
ValueError. -
Filtering: Applies
include_*,exclude_*, and*_typesarguments to build sets of selected indices. -
Layout creation: Generates
FrequencyLayoutobjects forJOINT,JOINT_DOF,JOINT_COORD,BODY,SHAPE, and"mujoco:tendon"when present. -
Mask building: Creates
self.articulation_maskboolean array for fast kernel masking. -
Property exposure: Exposes
body_names,body_shapesas aliases for link data and records contiguity flags (self.joints_contiguous, etc.) for optimization hints.
Creating and Configuring Articulation Views
Instantiate a view by passing a Model instance and a selection pattern. Optional filters refine the selection to specific joints or links:
import newton as nt
model = nt.load_model("my_robot.usd")
view = nt.selection.ArticulationView(
model,
pattern="robot*", # select articulations with labels starting with "robot"
include_joints=["hip*", "knee"], # only hip and knee joints
exclude_links=["base_link"], # omit the base link from the view
)
print("Selected joints:", view.joint_names)
print("Selected links :", view.link_names)
The view prints a concise summary when verbose=True (default follows wp.config.verbose).
Reading and Writing Joint DOFs
The view provides tensor-friendly accessors for degrees of freedom (DOF) that maintain the (worlds, articulations, dof) layout:
state = nt.State(model)
# Get DOF positions for all worlds/articulations in the view
q = view.get_dof_positions(state) # shape: (worlds, artics, dof)
# Zero the first DOF of every articulation
q_np = q.numpy()
q_np[..., 0] = 0.0
view.set_dof_positions(state, q_np) # writes back to the state
Internally, get_dof_positions calls _get_attribute_array("joint_position", state) (lines 84-119), which resolves the dotted attribute name to the JOINT_DOF frequency layout and returns a Warp array view respecting the computed strides.
Accessing MuJoCo Tendon Attributes
When the model contains MuJoCo tendons, the view automatically creates a "mujoco:tendon" layout. Access tendon-specific attributes using dotted notation:
# Read tendon stiffness (custom frequency)
tendon_stiff = view.get_attribute("mujoco.tendon_stiffness", state)
print("Tendon names:", view.tendon_names)
print("Stiffness shape:", tendon_stiff.shape) # (worlds, artics, tendons)
The _get_attribute_array method handles the translation from "mujoco.tendon_stiffness" to the internal "mujoco:tendon" frequency, verifying that the view actually contains tendon data before returning the array view.
Using Views in Warp Kernels
ArticulationView objects can be passed directly to Warp kernels, enabling GPU-accelerated manipulation of articulation data:
@wp.kernel
def apply_ctrl(values: wp.array2d(dtype=float), view: nt.selection.ArticulationView):
# values: (world, dof) control signal
# Set joint torque directly through the view
torque = view._get_attribute_array("joint_torque", ctrl)
torque[:] = values
# Launch kernel
wp.launch(apply_ctrl, dim=(worlds, dof_per_articulation),
inputs=[control_signal, view])
The kernel receives a contiguous torque array when the view's joint layout is contiguous; otherwise, the underlying strides are handled automatically by the Warp array view.
Key Source Files
| File | Role | Direct link |
|---|---|---|
newton/selection.py |
Public re‑export of ArticulationView |
selection.py |
newton/_src/utils/selection.py |
Full implementation of ArticulationView, layout computation, tendon handling |
selection.py (internal) |
newton/_src/sim.py |
Defines Model, State, Control and the get_attribute_frequency helper used by the view |
sim.py |
newton/tests/test_kinematics.py |
Unit test that exercises ArticulationView for joint position / velocity extraction |
test_kinematics.py |
newton/tests/test_selection.py |
Comprehensive tests covering filtering, tendon discovery, and layout validation | test_selection.py |
Summary
- ArticulationView creates tensor-friendly views of kinematic chains within Newton's
Model, enabling batched operations across multiple worlds and robot instances. - The class computes strided layouts for joints, DOFs, links, shapes, and MuJoCo tendons, ensuring efficient GPU access through Warp arrays.
- Pattern matching via
find_matching_idssupports glob-style selection of articulations, with validation ensuring uniform per-world or global indexing. - Attribute access uses
_get_attribute_arrayto resolve dotted names (e.g.,mujoco.tendon_stiffness) into frequency-specific layouts, returning contiguous or strided Warp views. - The implementation spans
newton/_src/utils/selection.py(core logic) andnewton/selection.py(public API), with comprehensive test coverage intest_selection.py.
Frequently Asked Questions
What is the difference between global and per-world articulations in Newton?
Newton supports two indexing modes for articulations: per-world articulations exist independently within each simulation world, while global articulations share a single index across all worlds. ArticulationView requires that selected articulations be uniformly one mode or the other; mixing global and per-world indices raises a ValueError during construction.
How does ArticulationView handle non-contiguous memory layouts?
The view automatically detects contiguity via flags like self.joints_contiguous. When data is contiguous, ArticulationView returns dense Warp arrays for maximum kernel performance. For non-contiguous selections, the view computes custom strides and offsets through FrequencyLayout, allowing kernels to access scattered data correctly without manual index translation.
Can I filter articulations by specific joint types or link names?
Yes. The constructor accepts include_joints, exclude_joints, include_links, exclude_links, and type filters. These arguments apply after the initial pattern match, creating a subset view that only exposes the requested joints or links while maintaining the same tensor structure for the selected elements.
What is the performance cost of using ArticulationView in simulation loops?
ArticulationView incurs a one-time setup cost during construction to compute layouts and validate selections. At runtime, attribute access via _get_attribute_array returns zero-copy Warp array views, meaning there is no per-step overhead for GPU kernels. The view's boolean mask (articulation_mask) enables fast filtering in parallel kernels without host-device synchronization.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →