Isaac Sim Hello World

NVIDIA Omniverse™ Kit, the toolkit that Omniverse Isaac Sim uses to build its applications, provides a Python interpreter for scripting
This means every single GUI command, as well as many additional functions are available as Python APIs
However, the learning curve for interfacing with Omniverse Kit using Pixar’s USD Python API is steep and steps are frequently tedious
Therefore we’ve provided a set of APIs that are designed to be used in robotics applications, APIs that abstract away the complexity of USD APIs and merge multiple steps into one for frequently performed tasks
In this tutorial, we will present the concepts of Core APIs and how to use them
We will start with adding a cube to an empty stage, and we’ll build upon it to create a scene with multiple robots executing mulitple tasks simultaneously, as seen below

Learning Objectives

This tutorial series introduces the Core API
After this tutorial, you will learn
Creating a World and Scene as defined by the Core API
How to add a rigid body to the Stage and simulate it using python in Omniverse Isaac Sim
The difference between running python in an Extension Workflow vs a Standalone Workflow, and in Jupyter Notebook

Getting Started

Prerequisites
Intermediate knowledge in Python and asynchronous programming is required for this tutorial
Please download and install Visual Studio Code prior to beginning this tutorial
Please review Isaac Sim Interface and Isaac Sim Workflows prior to beginning this tutorial
IsaacSim_HelloWorld1
Begin by opening the Hello World example. Go to the top Menu Bar and Click Isaac Examples > Hello World
IsaacSim_HelloWorld3
The window for the Hello World example extension should now be visible in the workspace
IsaacSim_HelloWorld2
Click the Open Source Code button to launch the source code for editing in Visual Studio Code
IsaacSim_HelloWorld4
Click the Open Containing Folder button to open the directory containing the example files
This folder contains three files: hello_world.py, hello_world_extension.py, and init.py.
The hello_world.py script is where the logic of the application will be added, while the UI elements of the application will be added in hello_world_extension.py script and thus linked to the logic
(1)Click the LOAD button to load the World
IsaacSim_HelloWorld5
(2)click File > New From Stage Template > Empty to create a new stage, click Don’t Save when prompted to save the current stage
IsaacSim_HelloWorld6
(3)Click the LOAD button to load the World again
IsaacSim_HelloWorld7
(4)Open hello_world.py and press “Ctrl+S” to use the hot-reload feature. You will notice that the menu disappears from the workspace (because it was restarted)
IsaacSim_HelloWorld8
IsaacSim_HelloWorld9
(5)Open the example menu again and click the LOAD button
Begin adding to this example

Code Overview

This example inherits from BaseSample, which is a boilerplate extension application that sets up the basics for every robotics extension application
The following are a few examples of the actions BaseSample performs
(1)Loading the world with its corresponding assets using a button
(2)Clearing the world when a new stage is created
(3)Resetting the world’s objects to their default states
(4)Handling hot reloading
World is the core class that enables you to interact with the simulator in an easy and modular way
It handles many time-related events such as adding callbacks, stepping physics, resetting the scene, adding tasks (this will be covered later in Adding a Manipulator Robot), etc
A world contains an instance of a Scene. The Scene class manages simulation assets of interest in the USD Stage
It provides an easy API to add, manipulate, inspect, and reset different USD assets in the stage

from omni.isaac.examples.base_sample import BaseSample #boiler plate of a robotics extension application

class HelloWorld(BaseSample):
    def __init__(self) -> None:
        super().__init__()
        return

    # This function is called to setup the assets in the scene for the first time
    # Class variables should not be assigned here, since this function is not called
    # after a hot-reload, its only called to load the world starting from an EMPTY stage

    def setup_scene(self):
        # A world is defined in the BaseSample, can be accessed everywhere EXCEPT __init__
        world = self.get_world()
        world.scene.add_default_ground_plane() # adds a default ground plane to the scene
        return

-HelloWorld class extends BaseSample to create a simple simulation scene with a ground plane
It demonstrates the basic structure of an application using Omni Isaac Sim for robotics simulation, focusing on the initial setup of the simulation environment

Singleton World

World is a Singleton, which means only one World can exist while running Omniverse Isaac Sim
The code below demonstrates how to retrieve the current instance of the World across different files and extensions

from omni.isaac.examples.base_sample import BaseSample
from omni.isaac.core import World

class HelloWorld(BaseSample):
    def __init__(self) -> None:
        super().__init__()
        return

    def setup_scene(self):
        world = World.instance()
        world.scene.add_default_ground_plane()
        return

-Imports the World class from omni.isaac.core
This class is responsible for managing the simulation environment, and it implements the Singleton design pattern to ensure only one instance of the simulation world exists
-world = World.instance() retrieves the singleton instance of the World using the instance() method
This is how one ensures that the same instance of the world is accessed across different files and extensions in the Omniverse Isaac Sim environment

Adding to the Scene

Next, use the Python API to add a cube as a rigid body to the scene

from omni.isaac.examples.base_sample import BaseSample
import numpy as np
# Can be used to create a new cube or to point to an already existing cube in stage.
from omni.isaac.core.objects import DynamicCuboid

class HelloWorld(BaseSample):
    def __init__(self) -> None:
        super().__init__()
        return

    def setup_scene(self):
        world = self.get_world()
        world.scene.add_default_ground_plane()
        fancy_cube = world.scene.add(
            DynamicCuboid(
                prim_path="/World/random_cube", # The prim path of the cube in the USD stage
                name="fancy_cube", # The unique name used to retrieve the object from the scene later on
                position=np.array([0, 0, 1.0]), # Using the current stage units which is in meters by default.
                scale=np.array([0.5015, 0.5015, 0.5015]), # most arguments accept mainly numpy arrays.
                color=np.array([0, 0, 1.0]), # RGB channels, going from 0-1
            ))

        return

-fancy_cube = world.scene.add(DynamicCuboid(…)):
Adds a dynamic cuboid to the scene
The DynamicCuboid class is used to create a new cube or reference an existing one in the stage
-Scene Configuration
Configurated with a specific path in the Universal Scene Description (USD) stage, a unique name, a position, a scale, and a color
prim_path=”/World/random_cube”:
Specifies the path of the cuboid within the USD stage, essentially its address in the scene’s hierarchy
name=”fancy_cube”:
Sets a unique name for the object, useful for retrieving it later
position=np.array([0, 0, 1.0]):
Sets the cube’s position in the scene using a NumPy array, with the assumption that the stage units are in meters by default
scale=np.array([0.5015, 0.5015, 0.5015]):
Defines the size of the cube, indicating that most arguments for DynamicCuboid accept NumPy arrays
color=np.array([0, 0, 1.0]):
Specifies the cube’s color in RGB values, ranging from 0 to 1, with this specific array representing blue
(1)Press Ctrl+S to save the code and hot-reload Omniverse Isaac Sim
(2)Open the menu again
(3)click File > New From Stage Template > Empty, then the LOAD button
You need to perform this action if you change anything in the setup_scene
Otherwise, you only need to press the LOAD button
IsaacSim_HelloWorld10
(4)Press the PLAY button to start simulating the dynamic cube and see it falling
Video: https://drive.google.com/file/d/1iFA_RMKCzAf6ra8jlRqnlls0cdR2WM3F/view?usp=sharing

Inspecting Object Properties

isaac_ros_detectnet

Reference:
https://docs.omniverse.nvidia.com/isaacsim/latest/core_api_tutorials/tutorial_core_hello_world.html
https://docs.omniverse.nvidia.com/isaacsim/latest/introductory_tutorials/tutorial_intro_interface.html#isaac-sim-app-tutorial-intro-interface
https://docs.omniverse.nvidia.com/isaacsim/latest/introductory_tutorials/tutorial_intro_workflows.html#isaac-sim-app-tutorial-intro-workflows