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?