ke.sim

High-level Python simulation helpers built on the low-level PhysX bindings.

API overview

KangSimWorld

Owns a PhysX world, registered objects, commands, and world state.

GridCloner

Create batched objects on a grid before GPU broadphase initialization.

SimulationRuntime

Own a KangSimWorld and its execution lifecycle.

SimulationTimingConfig

Rates and safety limits for an App-driven simulation loop.

SimulationRunConfig

Run policy kept separate from physical simulation timing.

SimArticulation

Simulation-facing view for one registered articulation.

SimRigid

Simulation-facing view for one registered rigid object.

State return and lifetime rules

Simulation getters return Torch tensors on the configured state device. They are views into reusable state storage, not immutable snapshots; use tensor.clone() when data must survive later step(), refresh(), reset, or release() calls. Shape labels use N for environments, B for bodies, and D for DOFs.

API

Return and lifetime contract

SimArticulation, SimRigid, and batch get_*()

Tensor views backed by the world’s reusable state cache.

KangSimWorld.get_gpu_*()

Zero-copy CUDA views over PhysX GPU mirrors; fetching or stepping updates their contents.

ContactSensor.data / refresh()

Views over reused sensor output buffers; clone fields needed as snapshots.

KangSimWorld.get_articulation() / get_rigid()

Lightweight handles tied to the world; do not use them after world.release().

Invalid object IDs or names raise KeyError; incompatible shapes or configuration values raise ValueError; unavailable devices, uninitialized GPU state, and use after release raise RuntimeError.

class kangengine.sim.KangSimWorld(
num_envs: int = 1,
physics_config=None,
sim_dt: float | None = None,
add_ground: bool = False,
sim_device='cpu',
device=None,
state_device=None,
)[python]

Owns a PhysX world, registered objects, commands, and world state.

In CPU simulation, state is the canonical Python runtime state. In GPU simulation, PhysX GpuArrayView buffers are canonical and state is the latest explicit CPU/Torch snapshot refreshed by refresh() or step(refresh=True).

Parameters:
  • sim_device – Simulation backend/device. "cpu" is the default PhysX CPU path. "cuda" enables the experimental PhysX GPU path.

  • state_device – Torch device for world.state snapshot tensors. This is intentionally separate from sim_device.

  • device – Compatibility alias for state_device.

add_articulation(
data,
*,
env_id: int = 0,
obj_id: int = 0,
name: str = '',
config=None,
) SimArticulation
Return type:

SimArticulation

add_articulation_batch(
template,
*,
obj_id: int = 0,
name: str = '',
config=None,
env_ids=None,
) SimArticulationBatch

Create per-environment PhysX instances from one shared template.

Return type:

SimArticulationBatch

add_contact_sensor(target, body_ids=None, *, name: str = '')

Attach a GPU contact sensor to a simulation object or object view.

add_force_sensor(target, body_ids=None, *, name: str = '')

Attach a normal-force sensor to a simulation object or view.

add_mjcf_articulation(
mjcf_path: str,
*,
env_id: int = 0,
obj_id: int = 0,
name: str = '',
config=None,
order: str = 'DFS',
scale: float = 1.0,
) SimArticulation
Return type:

SimArticulation

add_rigid(
data,
*,
env_id: int = 0,
obj_id: int = 0,
name: str = '',
pos=None,
rot_xyzw=None,
density: float = 1.0,
collision_group: int | None = None,
contact_offset: float = 0.02,
rest_offset: float = 0.0,
kinematic: bool = False,
) SimRigid
Return type:

SimRigid

add_static_rigid(
data,
*,
env_id: int = 0,
obj_id: int = 0,
name: str = '',
pos=None,
rot_xyzw=None,
collision_group: int | None = None,
contact_offset: float = 0.02,
rest_offset: float = 0.0,
) SimRigid
Return type:

SimRigid

advance(duration: float, refresh: bool = True, apply_commands: bool = True)

Advance by a requested amount of simulation time using fixed steps.

duration never changes the PhysX timestep. The method converts it into as many whole sim_dt steps as are currently due and retains any fractional remainder for the next call. This is useful from an app fixed_update(fixed_dt) callback whose control frequency may differ from the world’s physics frequency.

For example, a 120 Hz world advances 2 substeps for 1 / 60 seconds and 4 substeps for 1 / 30 seconds. Durations smaller than sim_dt may execute no physics until enough time accumulates.

Parameters:
  • duration (float) – Requested simulation duration in seconds.

  • refresh (bool) – Forwarded to step() when at least one physics step is due.

  • apply_commands (bool) – Forwarded to step() when at least one physics step is due.

Returns:

The current world.state.

apply_body_forces()
apply_commands()

Submit the current dense CUDA link force/torque command buffers.

apply_resets()
articulation(env_id: int = 0, obj_id: int = 0)
articulation_gpu_index_view(
env_id: int | integer | Sequence[int] | ndarray | Tensor | None,
obj_id: int = 0,
)

Return a cached CUDA int32 logical-row index view for articulations.

articulation_gpu_row(env_id: int, obj_id: int = 0) int
Return type:

int

clear_body_forces()
clear_cmd(
env_id: int | integer | Sequence[int] | ndarray | Tensor | None = None,
obj_id: int | None = None,
)
clear_sensor_outputs()
create_articulation_template(data, *, config=None)

Precompute immutable articulation resources for repeated instances.

get_articulation(
env_id: int = 0,
obj_id: int = 0,
) SimArticulation
Return type:

SimArticulation

get_articulation_batch(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
obj_id: int = 0,
name: str | None = None,
) SimArticulationBatch
Return type:

SimArticulationBatch

get_gpu_articulation_centroidal_dynamics(*, compute: bool = True)

Return (centroidal_momentum_matrix, bias_force) CUDA blocks.

get_gpu_articulation_com_root(*, compute: bool = True)
get_gpu_articulation_com_world(*, compute: bool = True)
get_gpu_articulation_coriolis_forces(*, compute: bool = True)

Return lazy-computed generalized Coriolis/centrifugal forces.

get_gpu_articulation_dense_jacobians(*, compute: bool = True)

Return lazy-computed PhysX dense-Jacobian blocks.

Shape is [articulation_count, max_jacobian_rows * max_generalized_dofs]. For row i, reshape the leading rows * cols values using get_gpu_articulation_dynamics_shape(i).

get_gpu_articulation_dynamics_shape(articulation_row: int)

Return (jacobian_rows, generalized_dofs) for one GPU row.

get_gpu_articulation_gravity_forces(*, compute: bool = True)

Return lazy-computed generalized gravity-compensation forces.

get_gpu_articulation_joint_accelerations(*, fetch: bool = True)
get_gpu_articulation_joint_forces(*, fetch: bool = True)
get_gpu_articulation_joint_positions(*, fetch: bool = True)
get_gpu_articulation_joint_velocities(*, fetch: bool = True)

Return link COM acceleration [lin xyz, ang xyz].

Return the full articulation link mirror as a Torch CUDA view.

Layout is [articulation_count, max_links, 13] with [pos xyz, quat xyzw, linear velocity xyz, angular velocity xyz].

Return the writable [articulation, max_links, 3] force buffer.

Return the writable [articulation, max_links, 3] torque buffer.

get_gpu_articulation_mass_matrices(*, compute: bool = True)

Return lazy-computed PhysX mass-matrix blocks.

Each row begins with a packed n * n matrix, where n is that articulation’s generalized DOF count.

get_gpu_articulation_target_joint_positions(*, fetch: bool = True)
get_gpu_articulation_target_joint_velocities(*, fetch: bool = True)
get_gpu_contact_pair_body_refs(*, fetch: bool = True)
get_gpu_contact_pair_count(*, fetch: bool = True)
get_gpu_contact_pair_headers(*, fetch: bool = True)
get_gpu_contact_pairs(*, fetch: bool = True)
get_gpu_contact_point_count(*, fetch: bool = True)
get_gpu_contact_point_pair_indices(*, fetch: bool = True)
get_gpu_contact_points(*, fetch: bool = True)
get_gpu_rigid_accelerations(*, fetch: bool = True)

Return rigid COM accelerations as [lin xyz, ang xyz].

Shape is [rigid_count, 6]. The physics scene must be created with PhysicsConfig(enable_body_accelerations=True).

get_gpu_rigid_data(*, fetch: bool = True)

Return the full PhysX GPU rigid mirror as a Torch CUDA view.

get_mjcf_cache_size() int
Return type:

int

get_mjcf_load_count() int
Return type:

int

get_object(
env_id: int = 0,
obj_id: int = 0,
) SimArticulation | SimRigid
Return type:

SimArticulation | SimRigid

get_object_batch(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
obj_id: int = 0,
name: str | None = None,
) SimArticulationBatch | SimRigidBatch
Return type:

SimArticulationBatch | SimRigidBatch

get_rigid(env_id: int = 0, obj_id: int = 0) SimRigid
Return type:

SimRigid

get_rigid_batch(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
obj_id: int = 0,
name: str | None = None,
) SimRigidBatch
Return type:

SimRigidBatch

property gpu_system
init_gpu_system(
cuda_device_id: int | None = None,
stream_handle: int | None = None,
)

Initialize explicit PhysX GPU mirrors and cache rigid row mappings.

Call this after registering simulation objects and before using low-level GPU mirror apply/fetch paths. It intentionally performs a visible runtime boundary instead of hiding PhysX GPU warm-up inside a high-level setter.

load_mjcf(mjcf_path: str, scale: float = 1.0, order: str = 'DFS')
refresh()

Refresh and return world.state.

In GPU simulation this performs an explicit CPU/Torch snapshot update.

refresh_sensors()

Refresh all sensor modules, sharing raw producer fetches per frame.

release()
rigid(env_id: int = 0, obj_id: int = 0)
rigid_gpu_index_view(
env_id: int | integer | Sequence[int] | ndarray | Tensor | None,
obj_id: int = 0,
)

Return a cached CUDA int32 logical-row index view for rigid batches.

rigid_gpu_row(env_id: int, obj_id: int = 0) int
Return type:

int

set_body_force(
env_id: int | integer | Sequence[int] | ndarray | Tensor | None,
obj_id: int,
body_id: int,
force,
)
set_body_force_at_position(
env_id: int | integer | Sequence[int] | ndarray | Tensor | None,
obj_id: int,
body_id: int,
force,
position,
)
set_cmd(
env_id: int | integer | Sequence[int] | ndarray | Tensor | None,
obj_id: int,
cmd,
mode: ControlMode | str = ControlMode.POS,
kp: object | None = 200.0,
kd: object | None = 10.0,
)
set_dof_state(
env_id: int | integer | Sequence[int] | ndarray | Tensor | None,
obj_id: int,
positions,
velocities=None,
immediate: bool = False,
)

Copy dense CUDA wrench tensors into the PhysX command buffers.

set_gpu_dof_state_batch(env_ids, obj_id: int, state)

Queue CUDA DOF position/velocity pairs as one batch.

env_ids may be a one-dimensional CUDA int32/int64 tensor. It stays on device through row selection and the indexed PhysX apply call. state must be a contiguous float32 CUDA tensor shaped [N, num_dofs, 2].

set_gpu_root_state_batch(env_ids, obj_id: int, state)

Queue CUDA root states without creating per-environment reset objects.

env_ids may be a one-dimensional CUDA int32/int64 tensor. It stays on device through row selection and the indexed PhysX apply call. state must be a contiguous float32 CUDA tensor shaped [N, 13] with position, xyzw rotation, linear velocity, and angular velocity.

set_root_state(
env_id: int | integer | Sequence[int] | ndarray | Tensor | None,
obj_id: int,
pos,
rot_xyzw,
linear_velocity=None,
angular_velocity=None,
immediate: bool = False,
)
step(substeps: int = 1, refresh: bool = True, apply_commands: bool = True)

Advance simulation and return world.state.

Parameters:
  • substeps (int) – Number of PhysX simulation steps to run. 0 applies queued resets/commands and sensor cleanup without advancing time; this is useful for Direct GPU reset-only frames.

  • refresh (bool) – When True, refresh world.state before returning. GPU simulation users can set this to False and read canonical CUDA views directly to avoid CPU readback.

  • apply_commands (bool) – When True, flush queued root state/control commands before stepping. Set to False for reset-only frames that should not re-apply user commands.

For GPU simulation this returns a CPU/Torch snapshot. Use GPU view helpers for the latest canonical CUDA state when avoiding readback.

class kangengine.sim.SimArticulation(
env_id: int,
obj_id: int,
name: str,
articulation: object,
world: KangSimWorld | None = None,
) None[python]

Simulation-facing view for one registered articulation.

This is the lightweight public object users should grow into using. It keeps the native articulation accessible for compatibility, while routing common commands and state access through KangSimWorld.

env_id
obj_id
name
articulation
world
add_contact_sensor(body_ids=None, *, name: str = '')
add_force_sensor(body_ids=None, *, name: str = '')
property body_names
clear_cmd(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
)
property data
property env_ids
get_body_id(name: str) int
Return type:

int

get_body_pos(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (..., B, 3).

Return type:

Tensor

get_body_rot(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (..., B, 4).

Return type:

Tensor

get_data(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) SimObjectState
Return type:

SimObjectState

get_dof_force(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (..., D).

Return type:

Tensor

get_dof_pos(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (..., D).

Return type:

Tensor

get_dof_vel(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (..., D).

Return type:

Tensor

get_joint_id(name: str) int
Return type:

int

get_root_ang_vel(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (..., 3).

Return type:

Tensor

get_root_pos(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (..., 3).

Return type:

Tensor

get_root_rot(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (..., 4).

Return type:

Tensor

get_root_vel(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (..., 3).

Return type:

Tensor

property joint_names
property key
property num_bodies
property num_dofs
set_body_force(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None,
body_id: int,
force: Tensor,
) Self

Shape: (..., 3).

Return type:

Self

set_body_force_at_position(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None,
body_id: int,
force: Tensor,
position: Tensor,
) Self

Shape: force and position (..., 3).

Return type:

Self

set_cmd(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None,
cmd: Tensor,
mode: ControlMode | str = 'pos',
kp: float | Tensor | None = 200.0,
kd: float | Tensor | None = 10.0,
) Self

Shape: command and tensor gains (..., D).

Return type:

Self

set_dof_state(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None,
positions: Tensor,
velocities: Tensor | None = None,
immediate: bool = False,
) Self

Shape: (..., D).

Return type:

Self

set_root_state(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None,
pos: Tensor,
rot_xyzw: Tensor,
linear_velocity: Tensor | None = None,
angular_velocity: Tensor | None = None,
immediate: bool = False,
) Self

Shapes: position/velocity (..., 3), rotation (..., 4).

Return type:

Self

class kangengine.sim.SimArticulationBatch(
world: KangSimWorld,
obj_id: int,
env_ids: tuple[int, ...],
name: str = '',
) None[python]

Batched simulation-facing view for one logical articulation object.

world
obj_id
env_ids
name
add_contact_sensor(body_ids=None, *, name: str = '')
add_force_sensor(body_ids=None, *, name: str = '')
property articulation
property body_names
clear_cmd(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
)
property data
property first
get_body_id(name: str) int
Return type:

int

get_body_pos(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (N, B, 3).

Return type:

Tensor

get_body_rot(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (N, B, 4).

Return type:

Tensor

get_data(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) SimObjectState
Return type:

SimObjectState

get_dof_force(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (N, D).

Return type:

Tensor

get_dof_pos(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (N, D).

Return type:

Tensor

get_dof_vel(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (N, D).

Return type:

Tensor

get_joint_id(name: str) int
Return type:

int

get_root_ang_vel(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (N, 3).

Return type:

Tensor

get_root_pos(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (N, 3).

Return type:

Tensor

get_root_rot(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (N, 4).

Return type:

Tensor

get_root_vel(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (N, 3).

Return type:

Tensor

property joint_names
property key
property num_bodies
property num_dofs
property num_envs
property records
set_body_force(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None,
body_id: int,
force: Tensor,
) Self

Shape: (N, 3).

Return type:

Self

set_body_force_at_position(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None,
body_id: int,
force: Tensor,
position: Tensor,
) Self

Shape: force and position (N, 3).

Return type:

Self

set_cmd(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None,
cmd: Tensor,
mode: ControlMode | str = 'pos',
kp: float | Tensor | None = 200.0,
kd: float | Tensor | None = 10.0,
) Self

Shape: command and tensor gains (N, D).

Return type:

Self

set_dof_state(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None,
positions: Tensor,
velocities: Tensor | None = None,
immediate: bool = False,
) Self

Shape: (N, D).

Return type:

Self

set_root_state(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None,
pos: Tensor,
rot_xyzw: Tensor,
linear_velocity: Tensor | None = None,
angular_velocity: Tensor | None = None,
immediate: bool = False,
) Self

Shapes: position/velocity (N, 3), rotation (N, 4).

Return type:

Self

class kangengine.sim.SimRigid(
env_id: int,
obj_id: int,
name: str,
rigid: object,
world: KangSimWorld | None = None,
source_data: object | None = None,
) None[python]

Simulation-facing view for one registered rigid object.

env_id
obj_id
name
rigid
world
source_data
add_contact_sensor(body_ids=None, *, name: str = '')
add_force_sensor(body_ids=None, *, name: str = '')
property body_names
property data
property env_ids
get_body_id(name: str) int
Return type:

int

get_body_pos(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (..., B, 3).

Return type:

Tensor

get_body_rot(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (..., B, 4).

Return type:

Tensor

get_data(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) SimObjectState
Return type:

SimObjectState

get_root_ang_vel(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (..., 3).

Return type:

Tensor

get_root_pos(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (..., 3).

Return type:

Tensor

get_root_rot(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (..., 4).

Return type:

Tensor

get_root_vel(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (..., 3).

Return type:

Tensor

property key
property num_bodies
set_body_force(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None,
body_id: int,
force: Tensor,
) Self

Shape: (..., 3).

Return type:

Self

set_body_force_at_position(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None,
body_id: int,
force: Tensor,
position: Tensor,
) Self

Shape: force and position (..., 3).

Return type:

Self

set_collision_material(material)

Replace all collision shape materials on this rigid at runtime.

set_collision_material_overrides(material_overrides, data=None)

Apply named/indexed collision material overrides at runtime.

set_root_state(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None,
pos: Tensor,
rot_xyzw: Tensor,
linear_velocity: Tensor | None = None,
angular_velocity: Tensor | None = None,
immediate: bool = False,
) Self

Shapes: position/velocity (..., 3), rotation (..., 4).

Return type:

Self

class kangengine.sim.SimRigidBatch(
world: KangSimWorld,
obj_id: int,
env_ids: tuple[int, ...],
name: str = '',
) None[python]

Batched simulation-facing view for one logical rigid object.

world
obj_id
env_ids
name
add_contact_sensor(body_ids=None, *, name: str = '')
add_force_sensor(body_ids=None, *, name: str = '')
property body_names
property data
property first
get_body_id(name: str) int
Return type:

int

get_body_pos(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (N, B, 3).

Return type:

Tensor

get_body_rot(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (N, B, 4).

Return type:

Tensor

get_data(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) SimObjectState
Return type:

SimObjectState

get_root_ang_vel(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (N, 3).

Return type:

Tensor

get_root_pos(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (N, 3).

Return type:

Tensor

get_root_rot(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (N, 4).

Return type:

Tensor

get_root_vel(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None = None,
) Tensor

Shape: (N, 3).

Return type:

Tensor

property key
property num_bodies
property num_envs
property records
property rigid
set_body_force(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None,
body_id: int,
force: Tensor,
) Self

Shape: (N, 3).

Return type:

Self

set_body_force_at_position(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None,
body_id: int,
force: Tensor,
position: Tensor,
) Self

Shape: force and position (N, 3).

Return type:

Self

set_collision_material(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None,
material,
)

Replace collision shape materials for selected rigid env instances.

set_collision_material_overrides(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None,
material_overrides,
data=None,
)

Apply named/indexed material overrides to selected rigid env instances.

set_root_state(
env_ids: int | integer | Sequence[int] | ndarray | Tensor | None,
pos: Tensor,
rot_xyzw: Tensor,
linear_velocity: Tensor | None = None,
angular_velocity: Tensor | None = None,
immediate: bool = False,
) Self

Shapes: position/velocity (N, 3), rotation (N, 4).

Return type:

Self

class kangengine.sim.SimulationRuntime(
*,
state_access: Literal['snapshot', 'gpu'] = 'snapshot',
**world_kwargs,
)[python]

Own a KangSimWorld and its execution lifecycle.

Simulation objects must be registered on world before calling initialize(). state_access="snapshot" keeps the conventional world.state snapshot current. state_access="gpu" avoids that snapshot refresh and updates the canonical CUDA frame cache instead.

close() None

Release the owned world. This operation is idempotent.

Return type:

None

property device
flush(*, apply_commands: bool = False) object | None

Apply queued state without advancing simulation time.

Return type:

object | None

get_articulation_state(
obj_id: int,
) ArticulationStateView

Return current articulation tensors using the selected state path.

Return type:

ArticulationStateView

initialize() SimulationRuntime

Finalize the runtime after all simulation objects are registered.

Return type:

SimulationRuntime

property is_closed
property is_initialized
set_articulation_state(
obj_id: int,
env_ids: Tensor,
root_pos: Tensor,
root_rot: Tensor,
root_vel: Tensor,
root_ang_vel: Tensor,
dof_pos: Tensor,
dof_vel: Tensor,
) None

Shapes: env IDs (N,), root state (N, 3|4), DOFs (N, D).

Return type:

None

property sim_device
step(
substeps: int = 1,
*,
apply_commands: bool = True,
refresh_state: bool = True,
) object | None

Advance physics and optionally refresh the selected state path.

Return type:

object | None

property uses_gpu_sim
property uses_gpu_state
class kangengine.sim.ArticulationStateView(
root_pos: Tensor,
root_rot: Tensor,
root_vel: Tensor,
root_ang_vel: Tensor,
dof_pos: Tensor,
dof_vel: Tensor,
) None[python]

Torch tensors for control and reinforcement-learning loops.

Shapes:

root_pos: (N, 3). root_rot: (N, 4). root_vel: (N, 3). root_ang_vel: (N, 3). dof_pos: (N, D). dof_vel: (N, D).

root_pos
root_rot
root_vel
root_ang_vel
dof_pos
dof_vel
class kangengine.sim.SimulationTimingConfig(
render_hz: float = 60.0,
physics_hz: float = 120.0,
fixed_update_hz: float = 60.0,
max_catch_up_steps: int = 8,
max_frame_delta: float = 0.25,
) None[python]

Rates and safety limits for an App-driven simulation loop.

Rates are the writable source of truth. Time intervals are derived to avoid contradictory hz and dt settings.

render_hz
physics_hz
fixed_update_hz
max_catch_up_steps
max_frame_delta
property decimation

Physics substeps represented by one fixed update.

property fixed_dt

Duration in seconds of one App fixed update.

classmethod from_dt(
*,
physics_dt: float,
fixed_dt: float,
render_hz: float = 60.0,
max_catch_up_steps: int = 8,
max_frame_delta: float = 0.25,
) SimulationTimingConfig

Create a config at a boundary that already expresses time in dt.

Return type:

SimulationTimingConfig

property physics_dt

Duration in seconds of one physics substep.

property sim_dt

Compatibility alias for physics_dt.

class kangengine.sim.SimulationRunMode(*values)[python]

Bases: StrEnum

Select how a simulation runner relates simulation time to wall time.

HEADLESS_FAST = 'headless_fast'
OFFSCREEN_FAST = 'offscreen_fast'
PACED = 'paced'
class kangengine.sim.SimulationRunConfig(
mode: SimulationRunMode = SimulationRunMode.HEADLESS_FAST,
) None[python]

Run policy kept separate from physical simulation timing.

HEADLESS_FAST disables rendering for training. OFFSCREEN_FAST renders requested frames without waiting. PACED advances one step at a time and waits only when ahead of wall time.

mode
property render_enabled
property syncs_to_wall_clock
class kangengine.sim.SimulationPacer(run_config: SimulationRunConfig)[python]

Pace externally stepped simulations without introducing catch-up steps.

reset()
wait(step_dt: float) float

Wait in PACED mode and return the requested sleep duration.

Return type:

float

class kangengine.sim.ControlMode(*values)[python]

Bases: str, Enum

NONE = 'none'
POS = 'pos'
VEL = 'vel'
TORQUE = 'torque'
PD_EXPLICIT = 'pd_explicit'
class kangengine.sim.SimDevice(*values)[python]

Bases: str, Enum

Simulation backend/device selector for KangSimWorld.

CPU = 'cpu'
CUDA = 'cuda'
kangengine.state.ArticulationState

alias of SimObjectState

class kangengine.state.ArticulationStateCache(articulation, physics=None, device=None)[python]

Torch cache around ke.physics.Articulation flat state getters.

refresh_metadata()
refresh_into(
state: SimObjectState,
) SimObjectState
Return type:

SimObjectState

set_root(
pos,
rot_xyzw,
linear_velocity=None,
angular_velocity=None,
)
set_dofs(positions, velocities=None)
class kangengine.state.RigidStateCache(
rigid,
physics=None,
body_names=None,
local_pos=None,
local_rot=None,
device=None,
)[python]

State cache for one dynamic rigid body.

Compound rigid bodies expose one body slot per collision shape for MimicKit-style body APIs, while PhysX still simulates one rigid actor.

refresh_metadata()
refresh_into(
state: SimObjectState,
) SimObjectState
Return type:

SimObjectState

set_root(pos, rot_xyzw, linear_velocity=None, angular_velocity=None)
set_dofs(positions, velocities=None)
kangengine.state.ArticulationRecord

alias of ObjectRecord

Sensors

Simulation sensor abstractions and their result data.

class kangengine.sim.ContactSensorData(
contact_count: Tensor,
in_contact: Tensor,
net_impulse: Tensor,
sim_dt: float,
) None[python]

Per-environment, per-body Torch contact state.

Shapes:

contact_count: (N, B). in_contact: (N, B). net_impulse: (N, B, 3). net_force: (N, B, 3).

contact_count
in_contact
net_impulse
sim_dt
property net_force

(N, B, 3).

Type:

Shape

class kangengine.sim.ContactSensor(world, target, body_ids=None, *, name: str = '')[python]

GPU contact sensor attached to a rigid or articulation object view.

property contact_count

(N, B).

Type:

Shape

contact_points(
*,
refresh: bool = False,
) ContactPointData

Return this sensor’s current packed PhysX contact points on CUDA.

The returned tensors are intended as raw inputs for Python-side contact filtering, frame conversion, friction-cone construction, and wrench metrics. Boolean compaction allocates output tensors but does not copy contact data to the host.

Return type:

ContactPointData

property data
property in_contact

(N, B).

Type:

Shape

property net_force

(N, B, 3).

Type:

Shape

property net_impulse

(N, B, 3).

Type:

Shape

refresh() ContactSensorData

Refresh the world sensor batch and return this sensor’s CUDA data.

Return type:

ContactSensorData

release()
requires_contact_data = True
class kangengine.sim.ForceSensor(world, target, body_ids=None, *, name: str = '')[python]

Bases: ContactSensor

Normal contact-force sensor backed by PhysX solver impulses.

This does not include tangential friction impulse or a complete wrench.

property force

(N, B, 3).

Type:

Shape

property impulse

(N, B, 3).

Type:

Shape