Skip to main content
Archived

This project has been archived by its maintainers, and is no longer receiving any updates.

License GitHub commit activity

⚠️ Deprecation Notice: Starting with Newton 1.3, actuators are created in and used exclusively from Newton's built-in newton.actuators module. This standalone newton-actuators package will no longer be maintained. Please migrate:

Newton Actuators

GPU-accelerated actuator library for physics simulations.

This library provides a collection of actuator implementations that integrate with physics simulation pipelines. Actuators read from simulation state arrays and write computed forces/torques back to control arrays.

Installation

pip install newton-actuators

Or install from source:

cd newton-actuators
pip install -e .

With PyTorch (for neural network actuators)

The ActuatorNetMLP and ActuatorNetLSTM actuators require PyTorch. Install the extra matching your CUDA version:

Using uv (index routing is automatic):

uv pip install "newton-actuators[torch-cu12]"   # CUDA 12.x
uv pip install "newton-actuators[torch-cu13]"   # CUDA 13.x

Using pip (requires manual --extra-index-url):

pip install "newton-actuators[torch-cu12]" --extra-index-url https://download.pytorch.org/whl/cu128
pip install "newton-actuators[torch-cu13]" --extra-index-url https://download.pytorch.org/whl/cu130

API Reference

Actuator Classes

Actuator Description Stateful Transmission
ActuatorPD Stateless PD controller No No
ActuatorPID PID controller with integral term Yes No
ActuatorDelayedPD PD controller with input delay Yes No
ActuatorDCMotor PD with DC motor velocity-dependent saturation No No
ActuatorRemotizedPD Delayed PD with angle-dependent torque limits Yes No
ActuatorNetMLP MLP network actuator with position/velocity history Yes No
ActuatorNetLSTM LSTM network actuator with recurrent hidden state Yes No

Control Laws

  • ActuatorPD: τ = clamp(constant + act + Kp·(target_pos - q) + Kd·(target_vel - v), ±max_force)
  • ActuatorPID: τ = clamp(constant + act + Kp·(target_pos - q) + Ki·∫e·dt + Kd·(target_vel - v), ±max_force)
  • ActuatorDelayedPD: Same as PD but with delayed targets (circular buffer)
  • ActuatorDCMotor: Same PD force computation, but torque is clamped to velocity-dependent bounds from the motor torque-speed curve: τ_max(v) = clamp(τ_sat·(1 - v/v_max), 0, effort_limit), τ_min(v) = clamp(τ_sat·(-1 - v/v_max), -effort_limit, 0), τ = clamp(τ, τ_min(v), τ_max(v))
  • ActuatorRemotizedPD: Same as DelayedPD, but torque limits are interpolated from an angle-dependent lookup table: τ_limit = interp(q, lookup_table)
  • ActuatorNetMLP: τ = clamp(network(cat(pos_error_history * pos_scale, vel_history * vel_scale)) * torque_scale, ±max_force) — history is maintained internally
  • ActuatorNetLSTM: τ = clamp(network(input, (h, c)), ±max_force) — hidden and cell state maintained internally

Base Class Methods

All actuators inherit from Actuator and provide these methods:

  • resolve_arguments(args) -> dict: (classmethod) Resolve user-provided arguments with defaults
  • is_stateful() -> bool: Returns True if the actuator maintains internal state
  • is_graphable() -> bool: Returns True if step() can be captured in a CUDA graph (False for torch-based NN actuators)
  • has_transmission() -> bool: Returns True if the actuator has a transmission phase
  • state() -> State | None: Returns a new state instance (None for stateless actuators)
  • step(sim_state, sim_control, current_state, next_state, dt): Execute one control step

State Classes

Stateful actuators use nested State classes:

  • ActuatorPID.State - Contains the integral term for PID control

  • ActuatorDelayedPD.State - Contains circular buffers for delayed targets

  • ActuatorRemotizedPD.State - Inherits ActuatorDelayedPD.State (same delay buffers)

  • ActuatorNetMLP.State - Contains position error and velocity history buffers

  • ActuatorNetLSTM.State - Contains LSTM hidden and cell state tensors

Workflow

  1. Create actuators with appropriate parameters
  2. Check statefulness: Call actuator.is_stateful() to determine if state management is needed
  3. Initialize states: For stateful actuators, create double-buffered states with actuator.state()
  4. Simulation loop: Call actuator.step() to compute forces
  5. Swap buffers: For stateful actuators, swap state buffers after each step
  6. Reset between episodes: Call state.reset() on any stateful actuator's state to zero internal buffers without reallocating

Examples

Stateless Actuator (ActuatorPD)

import warp as wp
from newton_actuators import ActuatorPD

# Create a PD actuator for 3 DOFs
indices = wp.array([0, 1, 2], dtype=wp.uint32)
pd_actuator = ActuatorPD(
    input_indices=indices,
    output_indices=indices,
    kp=wp.array([100.0, 100.0, 100.0], dtype=wp.float32),
    kd=wp.array([10.0, 10.0, 10.0], dtype=wp.float32),
    max_force=wp.array([50.0, 50.0, 50.0], dtype=wp.float32),
    constant_force=wp.array([0.0, 0.0, 0.0], dtype=wp.float32),
)

# In simulation loop - stateless actuators don't need state management
pd_actuator.step(sim_state, sim_control, None, None, dt=0.01)

Stateful Actuator (ActuatorPID)

import warp as wp
from newton_actuators import ActuatorPID

indices = wp.array([0, 1], dtype=wp.uint32)
pid_actuator = ActuatorPID(
    input_indices=indices,
    output_indices=indices,
    kp=wp.array([100.0, 100.0], dtype=wp.float32),
    ki=wp.array([10.0, 10.0], dtype=wp.float32),
    kd=wp.array([5.0, 5.0], dtype=wp.float32),
    max_force=wp.array([50.0, 50.0], dtype=wp.float32),
    integral_max=wp.array([10.0, 10.0], dtype=wp.float32),
    constant_force=wp.array([0.0, 0.0], dtype=wp.float32),
)

# Check if actuator needs state management
if pid_actuator.is_stateful():
    # Create double-buffered states
    state_a = pid_actuator.state()
    state_b = pid_actuator.state()

# Simulation loop with state swapping
current_state, next_state = state_a, state_b
for step in range(num_steps):
    pid_actuator.step(sim_state, sim_control, current_state, next_state, dt=0.01)
    current_state, next_state = next_state, current_state  # Swap buffers

Non-Graphable Stateful Actuator (ActuatorNetLSTM)

Network actuators (ActuatorNetMLP, ActuatorNetLSTM) are stateful but not CUDA-graphable due to Warp-PyTorch interop. Because their step() cannot be captured in a CUDA graph, double-buffering is not strictly required — you can pass the same state object as both current_state and next_state:

# Simple: single state object (fine when not using CUDA graphs)
state = lstm_actuator.state()
for step in range(num_steps):
    lstm_actuator.step(sim_state, sim_control, state, state, dt=0.01)

USD Parsing

The library includes utilities for parsing actuator definitions from USD files:

from newton_actuators import parse_actuator_prim

# Parse a USD prim with actuator attributes
result = parse_actuator_prim(prim)
if result is not None:
    actuator_class = result.actuator_class  # e.g., ActuatorPD
    target_paths = result.target_paths      # e.g., ["/World/Robot/Joint1"]
    kwargs = result.kwargs                   # e.g., {"kp": 100.0, "kd": 10.0}

License

Apache-2.0

Release files for newton-actuators 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for newton-actuators 0.1.1
File Interpreter ABI Platform
newton_actuators-0.1.1-py3-none-any.whl Python 3 none any Details

Release files / newton_actuators-0.1.1-py3-none-any.whl

Download URL newton_actuators-0.1.1-py3-none-any.whl
Size 37.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b94f1ca764107db7d0f18a303e9b5ab3451aa25d5d0d9a0a46714c728059e887
BLAKE2b-256 checksum
How to use checksums
3a6ef1a82265e4848cbb5ee146b3487bb89a13f45f91e377abce284e7ad596df
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 29, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.1 This release

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page