# Environment ARNOLD is built on [NVIDIA Isaac Sim](https://developer.nvidia.com/isaac-sim), a robotic simulation application that provides photo-realistic and physically-accurate simulations for robotics research and development. In ARNOLD, the photo-realistic rendering is powered by GPU-enabled ray tracing, and the physics simulation is based on PhysX 5.0. The figure below gives an illustration of the simulation and rendering. ```{image} multi_view.png --- width: 75% alt: Multi-view rendering --- ``` ARNOLD contains 20 diverse scenes and 40 distinct objects. Their compositions amount to abundant environments. In `environment/parameters.py` we define some basic classes for scene construction and physics simulation, *e.g.*, `SceneParameters` and `ObjectPhysicsProperties`. They make the scene components disentangled and can be modified friendly. ## Scenes ### Loading ARNOLD scenes originate from [3D-Front dataset](https://tianchi.aliyun.com/specials/promotion/alibaba-3d-scene-dataset). We formulate a pipeline to parse the 3D-Front scenes to USD format (preferred in Omniverse). Make sure you have prepared the **assets** (see [Setup](../setup/index.md)). Besides, you can refer to [USDify](https://github.com/arnold-benchmark/Usdify) if you are interested in the pipeline of converting the scene format. Loading scenes mainly encompasses the `add_reference_to_stage` function: ```python def add_reference_to_stage(usd_path: str, prim_path: str, prim_type: str = "Xform") -> Usd.Prim: ``` ### Collision We set collisions and other attributes for different objects inside the scene: ```python def setStaticCollider(prim, approximationShape="none", custom_execute_fn=None): setColliderSubtree(prim, approximationShape, custom_execute_fn) # set collisions for a room setStaticCollider(furniture_prim, approximationShape=CONVEXHULL) setStaticCollider(room_struct_prim, approximationShape="none") ``` `furniture_prim` holds all the furniture and `room_struct_prim` defines all the walls. Currently, the wall geometry is very complicated. And the default collision mechanism might cause issues (huge amount of VRAM *etc.*). Thus, we use the convex hull for furniture and default collision for the walls. You can disable the wall collision. Or you can decompose the walls into simple geometries like a collection of blocks. For example, you can refer to [collision processing](https://github.com/SarahWeiii/CoACD). ### Texture After setting collisions, we set the scene materials. Make sure you have prepared the **materials**. Or you can use custom `mtl` files. We use the following command to create a material in Isaac Sim: ```python omni.kit.commands.execute( "CreateMdlMaterialPrim", mtl_url=floor_material_url, mtl_name=floor_mtl_name, mtl_path=floor_material_prim_path, select_new_prim=False, ) ``` Then we can bind the materials to prims through: ```python omni.kit.commands.execute( "BindMaterial", prim_path=floor_prim.GetPath(), material_path=floor_material_prim_path, strength=UsdShade.Tokens.strongerThanDescendants ) ``` Here we leverage some functions from low-level API which is not documented very well. For more information, you can refer to [USD documentation](https://openusd.org/release/api/index.html). Even though it is a CPP documentation, you can find equivalent python functions. ## Objects Loading objects is similar to loading scenes. In particular, when we load drawers and cabinets, we re-process the handle for better collision. For fluid simulation, you can enable or disable isosurface for realistic simulation. Detailed settings about the objects are introduced in [Physics](#physics). ## Robot We use a 7-DoF Franka Emika Panda manipulator with a parallel gripper in ARNOLD for task execution. The agent has direct control over its seven joints and its gripper. We represent end-effector actions with three spatial coordinates for translation and quaternion for rotation. We utilize the built-in motion planner of Isaac Sim to transform the end-effector action back to the space of robot joints for execution. Currently, our tasks do not involve navigation, *i.e.*, the robot base remains fixed during task execution. ## Observation ARNOLD provides five cameras around the robot for visual input. Their placements are shown in the illustrative rendering example at the top of this page. Each camera renders RGB-D image at a resolution of 128×128 by default. Notably, the rendering in ARNOLD is stochastic due to the ray tracing sampling process. In addition to the visual observation, other auxiliary observations can be accessed, *e.g.*, camera parameters, robot base pose, and part-level semantic mask. See how to access them in [Data](../data/index.md). ## Rendering There are two types of rendering modes in Isaac Sim: ray tracing and path tracing. Ray tracing can work in real-time. Path tracing is quite slow but renders at a much higher quality. To switch rendering mode, check the `get_simulation()` function in `environment/runner_utils.py`. Check [Omniverse RTX Renderer Overview](https://docs.omniverse.nvidia.com/materials-and-rendering/latest/rtx-renderer_overview.html) for more details on rendering. Two rendering modes are visualized as below, left is ray tracing and right is path tracing. ```{image} ray_tracing.png --- width: 49% alt: Ray tracing --- ``` ```{image} path_tracing.png --- width: 49% alt: Path tracing --- ``` ## Physics To ensure physically-realistic simulation, we assign physics parameters to objects, including weight and friction for rigid-body objects, and cohesion, surface tension, and viscosity for fluids. Fluids are simulated using the GPU-accelerated position-based-dynamics (PBD) method. And we provide an optional surface construction process using marching cubes for higher rendering quality. This may cause slower rendering and is controlled by a `bool` argument `iso_surface`. In `environment/physics_utils.py` we define some helper functions to set up physics properties. For example, as grasping is done through friction in Issac Sim, we need to apply a physical material for all graspable parts. You can refer to the `set_physics_material` function. ```python def set_physics_material(stage, prim: Usd.Prim, object_physics_properties: ObjectPhysicsProperties): """ Set up physic material for prim at Path """ ``` Articulation simulation depends on joint properties. To set joint properties for prismatic joint or revolute joint, you can refer to the `set_joint_properties` function in `environment/physics_utils.py`. ``` def set_joint_properties(stage, prim, damping_cofficient): ``` If you want to add new properties, you can refer to [USD documentation](https://openusd.org/release/api/index.html) and make educated guesses about what functions to use. The fluid simulation involves two files `environment/fluid_constants.py` and `environment/fluid_utils.py`, where fluid parameters and construction process are defined. In addition, the isosurface mode can be enabled for more realistic fluid simulation by setting `iso_surface` to `True` in `configs/default.yaml`.