Replicator Isaac Extension [omni.replicator.isaac]
This extension builds upon omni.replicator to provide additional functionalities relevant to robotics.
Reinforcement Learning Domain Randomization
The following methods provide randomization functionalities of various parameters pertaining to omni.isaac.core.prims.RigidPrimView, omni.isaac.core.articulations.ArticulationView, and omni.isaac.core.SimulationContext. These methods are designed to perform randomizations in simulations where update to USD is disabled for faster simulation speed. These methods directly set randomized values to Physx as opposed to existing methods in omni.replicator.core, such as omni.replicator.core.modify.pose or omni.replicator.core.physics.physics_material, which utilizes USD APIs to set values and hence cannot be used when update to USD is disabled. Therefore, the following methods provided in omni.replicator.isaac are particularly useful for domain randomization in reinforcement learning (RL) as RL usecases benefit immensely from disabling update to USD to achieve faster simulation speed.
The following is a simple demo that showcases the workflow and the various features of
omni.replicator.isaac
for domain randomization. This demo script can be launched as
a standalone example, which can be found by going to Isaac Sim’s root directory and
go to standalone_examples/api/omni.replicator.isaac/randomization_demo.py
.
The omni.replicator.isaac
extension for domain randomization functions by constructing
an OmniGraph action graph, which consists of nodes that generate random values, regulate
frequency intervals of various randomizaiton properties, and write the random values to Physx.
This action graph gets executed according to the way in which the triggers are set up. Note
that it is necessesary to register the views to be randomized before constructing this action graph.
The first step is to create an entry point of the action graph using with dr.trigger.on_rl_frame(num_envs=num_envs):
.
It is worth noting that all views to be used with this extension must have the same number of
encapsulated prims, equaling num_envs
that is passed as an argument to the on_rl_frame
trigger.
After creating this entry point, there are two types of gates that determine when the nodes can write
to Physx: on_interval(interval)
and on_env_reset()
; these gates work in conjunction with
omni.replicator.isaac.physics_view.step_randomization(reset_inds)
. There exists an internal
step counter for every environment in the views. Everytime the step_randomization
method is called,
it resets the counter to zero for every environment listed in the reset_inds
argument while
incrementing the counter for every other environment. The on_interval(interval)
gate then ensures
the nodes to write to Physx whenever the counter for an environment is a multiple of the interval
argument. The on_env_reset()
gate writes to Physx whenever an environment’s counter gets reset by
the reset_inds
argument passed in the step_randomization
method.
Within each gate, the following methods can be used to randomize view properties: randomize_simulation_context
,
randomize_rigid_prim_view
and randomize_articulation_view
. For each of these methods, there
exists an operation
argument, which can be set to direct
, additive
, or scaling
. direct
sets the random values directly to Physx, while the behaviour of additive
and scaling
depends on
the gate it is controlled by. Under on_env_reset()
, additive
adds the random values to the default
values of a given attribute of the view, and scaling
multiplies the random values to the default values.
Under on_interval(interval)
, additive
and scaling
adds or multiplies the random values to the
last values set during on_env_reset()
. In essence, on_env_reset()
randomization should be treated
as correlated noise that lasts until the next reset, while on_interval(interval)
randomization should
be treated as uncorrelated noise.
After setting up this action graph, it is necessesary to run omni.replicator.core.orchestrator.run()
.
from omni.isaac.kit import SimulationApp
simulation_app = SimulationApp({"headless": False})
import numpy as np
from omni.isaac.core import World
from omni.isaac.core.prims.rigid_prim_view import RigidPrimView
from omni.isaac.core.articulations import ArticulationView
from omni.isaac.core.utils.prims import get_prim_at_path, define_prim
from omni.isaac.core.utils.stage import get_current_stage, add_reference_to_stage
from omni.isaac.nucleus import get_assets_root_path
from omni.isaac.core.objects import DynamicSphere
from omni.isaac.cloner import GridCloner
# create the world
world = World(stage_units_in_meters=1.0, physics_prim_path="/physicsScene", backend="numpy")
world.scene.add_default_ground_plane()
# set up grid cloner
cloner = GridCloner(spacing=1.5)
cloner.define_base_env("/World/envs")
define_prim("/World/envs/env_0")
# set up the first environment
DynamicSphere(prim_path="/World/envs/env_0/object", radius=0.1, position=np.array([0.75, 0.0, 0.2]))
add_reference_to_stage(
usd_path=get_assets_root_path()+ "/Isaac/Robots/Franka/franka.usd",
prim_path="/World/envs/env_0/franka",
)
# clone environments
num_envs = 4
prim_paths = cloner.generate_paths("/World/envs/env", num_envs)
env_pos = cloner.clone(source_prim_path="/World/envs/env_0", prim_paths=prim_paths)
# creates the views and set up world
object_view = RigidPrimView(prim_paths_expr="/World/envs/*/object", name="object_view")
franka_view = ArticulationView(prim_paths_expr="/World/envs/*/franka", name="franka_view")
world.scene.add(object_view)
world.scene.add(franka_view)
world.reset()
num_dof = franka_view.num_dof
# set up randomization with omni.replicator.isaac, imported as dr
import omni.replicator.isaac as dr
import omni.replicator.core as rep
dr.physics_view.register_simulation_context(world)
dr.physics_view.register_rigid_prim_view(object_view)
dr.physics_view.register_articulation_view(franka_view)
with dr.trigger.on_rl_frame(num_envs=num_envs):
with dr.gate.on_interval(interval=20):
dr.physics_view.randomize_simulation_context(
operation="scaling",
gravity=rep.distribution.uniform((1, 1, 0.0), (1, 1, 2.0)),
)
with dr.gate.on_interval(interval=50):
dr.physics_view.randomize_rigid_prim_view(
view_name=object_view.name,
operation="direct",
force=rep.distribution.uniform((0, 0, 2.5), (0, 0, 5.0)),
)
with dr.gate.on_interval(interval=10):
dr.physics_view.randomize_articulation_view(
view_name=franka_view.name,
operation="direct",
joint_velocities=rep.distribution.uniform(tuple([-2]*num_dof), tuple([2]*num_dof)),
)
with dr.gate.on_env_reset():
dr.physics_view.randomize_rigid_prim_view(
view_name=object_view.name,
operation="additive",
position=rep.distribution.normal((0.0, 0.0, 0.0), (0.2, 0.2, 0.0)),
velocity=[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
)
dr.physics_view.randomize_articulation_view(
view_name=franka_view.name,
operation="additive",
joint_positions=rep.distribution.uniform(tuple([-0.5]*num_dof), tuple([0.5]*num_dof)),
position=rep.distribution.normal((0.0, 0.0, 0.0), (0.2, 0.2, 0.0)),
)
rep.orchestrator.run()
frame_idx = 0
while simulation_app.is_running():
if world.is_playing():
reset_inds = list()
if frame_idx % 200 == 0:
# triggers reset every 200 steps
reset_inds = np.arange(num_envs)
dr.physics_view.step_randomization(reset_inds)
world.step(render=True)
frame_idx += 1
- trigger.on_rl_frame()
- Parameters
num_envs (int) – The number of environments corresponding to the number of prims encapsulated in the RigidPrimViews and ArticulationViews.
- gate.on_env_reset()
- gate.on_interval()
- Parameters
interval (int) – The frequency interval for randomization. The interval is incremented by omni.replicator.isaac.physics_view.step_randomization() call.
- physics_view.register_simulation_context() None
- Parameters
simulation_context (Union[omni.isaac.core.SimulationContext, omni.isaac.core.World]) – Registering the SimulationContext.
- physics_view.register_rigid_prim_view() None
- Parameters
rigid_prim_view (omni.isaac.core.prims.RigidPrimView) – Registering the RigidPrimView to be randomized.
- physics_view.register_articulation_view() None
- Parameters
articulation_view (omni.isaac.core.articulations.ArticulationView) – Registering the ArticulationView to be randomized.
- physics_view.randomize_simulation_context(gravity: Optional[omni.replicator.core.utils.ReplicatorItem] = None)
- Parameters
operation (str) – Can be “direct”, “additive”, or “scaling”. “direct” means random values are directly written into the view. “additive” means random values are added to the default values. “scaling” means random values are multiplied to the default values.
gravity (ReplicatorItem) – Randomizes the gravity vector of the simulation.
- physics_view.randomize_rigid_prim_view(operation: str = 'direct', num_buckets: Optional[int] = None, position: Optional[omni.replicator.core.utils.ReplicatorItem] = None, orientation: Optional[omni.replicator.core.utils.ReplicatorItem] = None, linear_velocity: Optional[omni.replicator.core.utils.ReplicatorItem] = None, angular_velocity: Optional[omni.replicator.core.utils.ReplicatorItem] = None, velocity: Optional[omni.replicator.core.utils.ReplicatorItem] = None, force: Optional[omni.replicator.core.utils.ReplicatorItem] = None, mass: Optional[omni.replicator.core.utils.ReplicatorItem] = None, inertia: Optional[omni.replicator.core.utils.ReplicatorItem] = None, material_properties: Optional[omni.replicator.core.utils.ReplicatorItem] = None, contact_offset: Optional[omni.replicator.core.utils.ReplicatorItem] = None, rest_offset: Optional[omni.replicator.core.utils.ReplicatorItem] = None) None
- Parameters
view_name (str) – The name of a registered RigidPrimView.
operation (str) – Can be “direct”, “additive”, or “scaling”. “direct” means random values are directly written into the view. “additive” means random values are added to the default values. “scaling” means random values are multiplied to the default values.
num_buckets (int) – Number of buckets to sample values from for material_properties randomization.
position (ReplicatorItem) – Randomizes the position of the prims.
orientation (ReplicatorItem) – Randomizes the orientation of the prims using euler angles (rad).
linear_velocity (ReplicatorItem) – Randomizes the linear velocity of the prims.
angular_velocity (ReplicatorItem) – Randomizes the angular velocity of the prims.
velocity (ReplicatorItem) – Randomizes the linear and angular velocity of the prims.
force (ReplicatorItem) – Applies a random force to the prims.
mass (ReplicatorItem) – Randomizes the mass of the prims. CPU pipeline only.
inertia (ReplicatorItem) – Randomizes the inertia of the prims. Takes in three values for the replicator distribution, corresponding to the diagonal elements of the inertia matrix. CPU pipeline only.
material_properties (ReplicatorItem) – Takes in three values for the replicator distriution, corresponding to static friction, dynamic friction, and restitution.
contact_offset (ReplicatorItem) – Randomizes the contact offset of the prims.
rest_offset (ReplicatorItem) – Randomizes the rest offset of the prims.
- physics_view.randomize_articulation_view(operation: str = 'direct', num_buckets: Optional[int] = None, stiffness: Optional[omni.replicator.core.utils.ReplicatorItem] = None, damping: Optional[omni.replicator.core.utils.ReplicatorItem] = None, joint_friction: Optional[omni.replicator.core.utils.ReplicatorItem] = None, position: Optional[omni.replicator.core.utils.ReplicatorItem] = None, orientation: Optional[omni.replicator.core.utils.ReplicatorItem] = None, linear_velocity: Optional[omni.replicator.core.utils.ReplicatorItem] = None, angular_velocity: Optional[omni.replicator.core.utils.ReplicatorItem] = None, velocity: Optional[omni.replicator.core.utils.ReplicatorItem] = None, joint_positions: Optional[omni.replicator.core.utils.ReplicatorItem] = None, joint_velocities: Optional[omni.replicator.core.utils.ReplicatorItem] = None, lower_dof_limits: Optional[omni.replicator.core.utils.ReplicatorItem] = None, upper_dof_limits: Optional[omni.replicator.core.utils.ReplicatorItem] = None, max_efforts: Optional[omni.replicator.core.utils.ReplicatorItem] = None, joint_armatures: Optional[omni.replicator.core.utils.ReplicatorItem] = None, joint_max_velocities: Optional[omni.replicator.core.utils.ReplicatorItem] = None, joint_efforts: Optional[omni.replicator.core.utils.ReplicatorItem] = None, body_masses: Optional[omni.replicator.core.utils.ReplicatorItem] = None, body_inertias: Optional[omni.replicator.core.utils.ReplicatorItem] = None, material_properties: Optional[omni.replicator.core.utils.ReplicatorItem] = None, tendon_stiffnesses: Optional[omni.replicator.core.utils.ReplicatorItem] = None, tendon_dampings: Optional[omni.replicator.core.utils.ReplicatorItem] = None, tendon_limit_stiffnesses: Optional[omni.replicator.core.utils.ReplicatorItem] = None, tendon_lower_limits: Optional[omni.replicator.core.utils.ReplicatorItem] = None, tendon_upper_limits: Optional[omni.replicator.core.utils.ReplicatorItem] = None, tendon_rest_lengths: Optional[omni.replicator.core.utils.ReplicatorItem] = None, tendon_offsets: Optional[omni.replicator.core.utils.ReplicatorItem] = None) None
- Parameters
view_name (str) – The name of a registered ArticulationView.
operation (str) – Can be “direct”, “additive”, or “scaling”. “direct” means random values are directly written into the view. “additive” means random values are added to the default values. “scaling” means random values are multiplied to the default values.
num_buckets (int) – Number of buckets to sample values from for material_properties randomization.
stiffness (ReplicatorItem) – Randomizes the stiffness of the joints in the articulation prims.
damping (ReplicatorItem) – Randomizes the damping of the joints in the articulation prims.
joint_friction (ReplicatorItem) – Randomizes the friction of the joints in the articulation prims.
position (ReplicatorItem) – Randomizes the root position of the prims.
orientation (ReplicatorItem) – Randomizes the root orientation of the prims using euler angles (rad).
linear_velocity (ReplicatorItem) – Randomizes the root linear velocity of the prims.
angular_velocity (ReplicatorItem) – Randomizes the root angular velocity of the prims.
velocity (ReplicatorItem) – Randomizes the root linear and angular velocity of the prims.
joint_positions (ReplicatorItem) – Randomizes the joint positions of the articulation prims.
joint_velocities (ReplicatorItem) – Randomizes the joint velocities of the articulation prims.
lower_dof_limits (ReplicatorItem) – Randomizes the lower joint limits of the articulation prims.
upper_dof_limits (ReplicatorItem) – Randomizes the upper joint limits of the articulation prims.
max_efforts (ReplicatorItem) – Randomizes the maximum joint efforts of the articulation prims.
joint_armatures (ReplicatorItem) – Randomizes the joint armatures of the articulation prims.
joint_max_velocities (ReplicatorItem) – Randomizes the maximum joint velocities of the articulation prims.
joint_efforts (ReplicatorItem) – Randomizes the joint efforts of the articulation prims.
body_masses (ReplicatorItem) – Randomizes the mass of each body in the articulation prims. The replicator distribution takes in K values, where K is the number of bodies in the articulation.
body_inertias (ReplicatorItem) – Randomizes the inertia of each body in the articulation prims. The replicator distribution takes in K * 3 values, where K is the number of bodies in the articulation.
material_properties (ReplicatorItem) – Randomizes the material properties of the bodies in the articulation.
tendon_stiffnesses (ReplicatorItem) – Randomizes the stiffnesses of the fixed tendons in the articulation. The replicator distribution takes in T values, where T is the number of tendons in the articulation.
tendon_dampings (ReplicatorItem) – Randomizes the dampings of the fixed tendons in the articulation. The replicator distribution takes in T values, where T is the number of tendons in the articulation.
tendon_limit_stiffnesses (ReplicatorItem) – Randomizes the limit stiffnesses of the fixed tendons in the articulation. The replicator distribution takes in T values, where T is the number of tendons in the articulation.
tendon_lower_limits (ReplicatorItem) – Randomizes the lower limits of the fixed tendons in the articulation. The replicator distribution takes in T values, where T is the number of tendons in the articulation.
tendon_upper_limits (ReplicatorItem) – Randomizes the upper limits of the fixed tendons in the articulation. The replicator distribution takes in T values, where T is the number of tendons in the articulation.
tendon_rest_lengths (ReplicatorItem) – Randomizes the rest lengths of the fixed tendons in the articulation. The replicator distribution takes in T values, where T is the number of tendons in the articulation.
tendon_offsets (ReplicatorItem) – Randomizes the offsets of the fixed tendons in the articulation. The replicator distribution takes in T values, where T is the number of tendons in the articulation.
- physics_view.step_randomization() None
- Parameters
reset_inds (Optional[Union[list, np.ndarray, torch.Tensor]]) – The indices corresonding to the prims to be reset in the views.
- utils.set_distribution_params(parameters: Dict) None
- Parameters
distribution (ReplicatorItem) – The replicator distribution object to be modified.
parameters (Dict) – A dictionary where the keys are the names of the replicator distribution parameters and the values are the parameter values to be set.
- utils.get_distribution_params(parameters: List[str]) List
- Parameters
distribution (ReplicatorItem) – A replicator distribution object.
parameters (List[str]) – A list of the names of the replicator distribution parameters.
- Returns
A list of the distribution parameters of the given replicator distribution object.
- Return type
List[str]
Pytorch Online Writer and Listener
The PytorchWriter and PytorchListener are APIs for using omni.replicator’s writer API to retrieve various data such as RGB from the specified cameras (supports multiple cameras) and provides them to the user in both default format (eg. PNG for RGB data) and batched pytorch tensors. The PytorchListener provides an API to directly retrieve data sent to the PytorchWriter without the need to access the stored by omni.replicator’s BackendDispatch.
- class PytorchWriter(*args: Any, **kwargs: Any)
- A custom writer that uses omni.replicator API to retrieve RGB data via render products
and formats them as tensor batches. The writer takes a PytorchListener which is able to retrieve pytorch tensors for the user directly after each writer call.
- Parameters
listener (PytorchListener) – A PytorchListener that is sent pytorch batch tensors at each write() call.
output_dir (str) – directory in which rgb data will be saved in PNG format by the backend dispatch. If not specified, the writer will not write rgb data as png and only ping the listener with batched tensors.
device (str) – device in which the pytorch tensor data will reside. Can be “cpu”, “cuda”, or any other format that pytorch supports for devices. Default is “cuda”.
- write(data: dict) None
Sends data captured by the attached render products to the PytorchListener and will write data to the output directory if specified during initialization.
- Parameters
data (dict) – Data to be pinged to the listener and written to the output directory if specified.
- class PytorchListener
A Observer/Listener that keeps track of updated data sent by the writer. Is passed in the initialization of a PytorchWriter at which point it is pinged by the writer after any data is passed to the writer.
- get_rgb_data() Optional[torch.Tensor]
Returns RGB data as a batched tensor from the current data stored.
- Returns
images in batched pytorch tensor form
- Return type
images (Optional[torch.Tensor])
- write_data(data: dict) None
Updates the existing data in the listener with the new data provided.
- Parameters
data (dict) – new data retrieved from writer.