Cannot create articulation view when running extension

Note: For any Isaac Lab topics, please submit your topic to its GitHub repo (GitHub - isaac-sim/IsaacLab: Unified framework for robot learning built on NVIDIA Isaac Sim) following the instructions provided on Isaac Lab’s Contributing Guidelines (Contribution Guidelines — Isaac Lab Documentation).

Please provide all relevant details below before submitting your post. This will help the community provide more accurate and timely assistance. After submitting, you can check the appropriate boxes. Remember, you can always edit your post later to include additional information if needed.

Isaac Sim Version

4.5.0
4.2.0
4.1.0
4.0.0
4.5.0
2023.1.1
2023.1.0-hotfix.1
Other (please specify):

Operating System

Ubuntu 22.04
Ubuntu 20.04
Windows 11
Windows 10
Other (please specify):

GPU Information

  • Model:
  • Driver Version:

Topic Description

Detailed Description

I am trying to create an extension that will allow me to configure reinforcement learning parameters in isaac sim. I am making use of the stable baselines 3 model to train a model. Isaac sim environment is wrapped withing a custom gym environment to support stable baseline 3. When I run this setup via python.sh everything works but when running it via extension, I am unable to create an articulation view because the api is not able to find the physics context.

Error Messages


Additional Information

What I’ve Tried

waiting till the physics scene is loaded but that doesnt seem to be the issue.

Related Issues

(If you’re aware of any related issues or forum posts, please link them here)

Additional Context

Here is the Bittle class that is causing the issue :

from isaacsim import SimulationApp

simulation_app = SimulationApp({“headless”: False}) # start the simulation app, with GUI open

from isaacsim.core.api import SimulationContext
from isaacsim.core.utils.prims import is_prim_path_valid, get_prim_at_path
from isaacsim.core.prims import Articulation
from isaacsim.core.api import World
from isaacsim.sensors.physics import _sensor
from isaacsim.core.simulation_manager import IsaacEvents, SimulationManager
from omni.isaac.core.utils.stage import open_stage
open_stage(“/home/dafodilrat/Documents/bu/RASTIC/rl_world.usd”)

from pxr import UsdGeom, Sdf
from scipy.spatial.transform import Rotation as R
import time
import numpy as np
from omni.isaac.core.utils.stage import is_stage_loading
import omni.physics.tensors as tensors

class Bittle():

def __init__(self):
    
    self.robot_prim = "/World/bittle"
    self.world = World(stage_units_in_meters=1.0)
    self.wait_for_prim(self.robot_prim)
    self.wait_for_prim("/World/PhysicsScene")
    self.reset()

def reset(self):
    
    # Wait for prims


    prim = get_prim_at_path(self.robot_prim)
    if not prim.HasAttribute("articulation:root"):
        attr = prim.CreateAttribute("articulation:root", Sdf.ValueTypeNames.Bool)
        attr.Set(True)
        print("Marked as articulation root")
    else:
        print("Already has articulation:root =", prim.GetAttribute("articulation:root").Get())

    # simulation_view = tensors.create_simulation_view("torch")
    # articulation_view = simulation_view.create_articulation_view("/world/bittle*")

    # Safe physics init
    # self.sim.initialize_physics()
    # phy = SimulationManager.get_physics_sim_view()
    # print("physics :",phy)
    # print("device :",SimulationManager.get_physics_sim_device())


    self.world.reset()
    self.robot_view = Articulation(self.robot_prim)
    self.robot_view.initialize()
    self.reset()
    self.enforce_vel_limits()

    print("Simulation started")

def wait_for_prim(self, path, timeout=5.0):
    t0 = time.time()
    while not is_prim_path_valid(path):
        if time.time() - t0 > timeout:
            raise RuntimeError(f"Timed out waiting for prim: {path}")
        time.sleep(0.05)

def set_robot_action(self, action):
    # Optional: uncomment if step still crashes
    # if getattr(self.sim, "_physics_context", None) is None:
    #     print("[Warning] Physics not ready")
    #     return
    self.robot_view.set_joint_positions(action)
    self.world.step(render=True)

def get_robot_dof(self):
    num_dofs = self.robot_view.num_dof
    joint_names = self.robot_view.dof_names
    limits = self.robot_view.get_dof_limits()[0]
    return num_dofs, limits[:, 0], limits[:, 1]

def get_curr_robot_pose(self):
    imu = _sensor.acquire_imu_sensor_interface()
    imu_data = imu.get_sensor_reading(self.robot_prim + "/base_frame_link/Imu_Sensor")
    quat = imu_data.orientation
    r = R.from_quat([quat[0], quat[1], quat[2], quat[3]])
    roll, pitch, yaw = r.as_euler('xyz', degrees=False)
    pos, _ = self.robot_view.get_world_poses()
    return pos[0], [roll, pitch, yaw]

def get_robot_observation(self):
    pos, ori = self.get_curr_robot_pose()
    angles = self.robot_view.get_joint_positions()[0]
    vel = self.robot_view.get_joint_velocities()[0]
    return [pos, ori, angles, vel]

def is_running(self):
    return self.world.is_playing()

def reset_simulation(self):
    self.reset()

def enforce_vel_limits(self):

    joint_names = self.robot_view.dof_names
    
    for name in joint_names:
        joint_path = f"{self.robot_prim}/joints/{name}"
        joint_prim = get_prim_at_path(joint_path)
        if not joint_prim.IsValid():
            print(f"[Warning] Joint not found: {joint_path}")
            continue
        attr = joint_prim.GetAttribute("physics:joint:velocityLimit")
        if not attr.IsValid():
            attr = joint_prim.CreateAttribute("physics:joint:velocityLimit", Sdf.ValueTypeNames.Float)
        attr.Set(90.0)
        print(f"Enforced velocity limit on {name}")

def get_valid_positions_on_terrain(self, prim_path="/GroundPlane", n_samples=10):
    
    self.wait_for_prim(prim_path)

    mesh_prim = get_prim_at_path(prim_path + "/CollisionMesh")
    if not mesh_prim:
        raise ValueError(f"No prim found at path: {prim_path}/CollisionMesh")

    mesh = UsdGeom.Mesh(mesh_prim)
    points_attr = mesh.GetPointsAttr()
    points = points_attr.Get()

    if not points:
        raise RuntimeError("Mesh points attribute could not be read.")

    # Convert points to NumPy array
    point_array = np.array([[p[0], p[1], p[2]] for p in points])
    min_bounds = np.min(point_array, axis=0)
    max_bounds = np.max(point_array, axis=0)

    z_const = min_bounds[2]  # assume terrain is flat at this Z

    positions = []
    for _ in range(n_samples):
        x = np.random.uniform(min_bounds[0], max_bounds[0])
        y = np.random.uniform(min_bounds[1], max_bounds[1])
        positions.append((x, y, z_const))

    return positions

if name == “main”:

b = Bittle()

Hi @haroonhidayath45 thanks for your question! Could you share rl_world.usd so I can try reproducing this? Thanks!

This is the project repo, I have changed the files a bit but the idea is still the same and the issue persists.

I have ditched RL world in favor of just building everything via the python calls so that should not be required anymore.

The ext folder contains the custom view extension that is causing the issue.

test.py file opens isaac sim via the api and starts the training.

The ext.py (the main file of the extension) pretty much does the same but with isaac sim aldready running and the extension loaded in.

command to run test.py ./python.sh -m alpha.exts.customView.customView.test

command to open isaac sim with custom extension ./isaac-sim.sh --ext-folder alpha/exts replace alpha with the folder name where the repo is cloned to.

Pressing the start training button should reproduce the error.

NOTE : you have to manually enable the extension in isaac sim. searching RL viewport under thrid party extension should show the extension

Hi, apologies again for late followups. Could you share how you are setting up IsaacLab for it to be importable through the extension?

After cloning the repository, an updating some imports (I had to use relative imports and change line 10 in ext.py to from .PPO import PPOAgent as stb3_PPO), I’m not able to get your isaaclab import in TrainingGround.py to work with the normal IsaacLab installation procedure.

Same problem. Have you found any solution?

Hi @haroonhidayath45, very sorry this issue remained unresolved for so long. Looking through your codebase it seems like one issue that stands out is that in ext.py, the extension imports from .world import Environment, but environment.py imports:

  from omni.isaac.core.simulation_context import SimulationContext                                                                                                                                                               

and creates a World(…) instance followed by world.reset() and world.play().

When running standalone via python.sh, SimulationApp bootstraps the entire Kit runtime. But inside an extension, Kit is already running — you don’t own the
app lifecycle. Creating a new World instance and calling world.reset() / world.play() inside an extension conflicts with the already-running Kit timeline.

Don’t create SimulationApp or World in extension mode. Instead, get the existing simulation context:

  from omni.isaac.core.simulation_context import SimulationContext                                              
  sim_ctx = SimulationContext.instance()               
  # or just use the timeline directly:                 
  timeline = omni.timeline.get_timeline_interface()   

The error was likely caused by instantiating SimulationContext or World inside of the extension (which it already was instantiated in the Isaac Sim app) and invalidating the SimulationView.

Hello!

We noticed that this topic hasn’t received any recent updates from anyone reporting this issue, so we are closing it for now to help keep the forum organized.

If you are still experiencing this issue or have related questions, please create a GitHub Discussion or Issue in the Isaac Sim repository and include a link to this topic along with updated details. Mentioning or linking to this original topic provides helpful context and makes it easier for others to assist you.

Thank you for being part of the NVIDIA Isaac Sim community.

Best regards,
The NVIDIA Isaac Sim Forum Team