Dynamic add usd file to scene with error

Hi everyone , I am a new beginner at Isaac Sim. I try to dynamic crate a 3d model to my scene, but every time I create it, the terminal shows the following picture error. I don’t know how to fix it. I used create_prim function to make it, is that a wrong way?

would you please provide more details and explain your steps

The following is my code:

# Copyright (c) 2020-2021, NVIDIA CORPORATION.  All rights reserved.
#
# NVIDIA CORPORATION and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto.  Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA CORPORATION is strictly prohibited.

from omni.isaac.examples.base_sample import BaseSample
from omni.isaac.core.objects import DynamicCuboid
from omni.isaac.core.utils.nucleus import find_nucleus_server
from omni.isaac.core.utils.stage import add_reference_to_stage
from omni.isaac.core.robots import Robot
from omni.isaac.core.utils.types import ArticulationAction
from omni.isaac.core.controllers import BaseController
from omni.isaac.core.utils.prims import create_prim
from omni.isaac.core.utils.prims import delete_prim
from omni.isaac.core.utils.rotations import euler_angles_to_quat
from omni.isaac.core.articulations import Articulation
from pxr import Usd, UsdLux, UsdGeom, Sdf, Gf, Tf, UsdPhysics
from omni.usd import get_context
from omni.physx.scripts import utils
# This extension includes several generic controllers that could be used with multiple robots
import carb
import numpy as np
import time
import math
from pxr import UsdPhysics
import omni
import socket , pickle
import threading
import asyncio
from omni.isaac.dynamic_control import _dynamic_control
from scipy.spatial.transform import Rotation
import copy

class TMController(BaseController):
    def __init__(self):
        super().__init__(name="TM_controller")
        # An open loop controller that uses a unicycle model
        print('controller initial success')
        return

    def forward(self,joint_positions):
        # A controller has to return an ArticulationAction
        #joint_positions = np.random.rand(6)       
        print('Move by socket pos') 
        return ArticulationAction(joint_positions = joint_positions)


class HelloWorld(BaseSample): 

    def __init__(self) -> None:
        super().__init__()
        self._widget_index = 1
        self._dc = _dynamic_control.acquire_dynamic_control_interface()
        self._linearDriveAPI = []
        self._prismaticJoint = []
        self._conveyor = []
        self._pos = [0,130,250,380,490,620] 
        self._run_index = 0
        return

    def setup_scene(self):
        world = self.get_world()
        add_reference_to_stage(usd_path="/home/quanta/Desktop/WorkingCopy/Robots/Collected_Conveyor0/Conveyor0.usd", prim_path="/Group")
       
        for i in range(7):
            cv = Conveyor()
            cv.ConveyorNo = i+1
            self._conveyor.append(cv) 
        return

    async def setup_post_load(self):
        self._world = self.get_world()
        self._controller = TMController()
        self._world.add_physics_callback("sim_step", callback_fn=self.physics_step)
        #------articulation controller---------
        self._conveyorThread = threading.Thread(target=self.DepolyPalet,args=())
        
        return
    
    def DepolyPalet(self):
        while True:
            if self._conveyor[0].carrier == None:                
                _thread = threading.Thread(target=asyncio.run, args=(self.AddPlate_aync(),))
                _thread.start()  
                #_thread.join()              
            time.sleep(1)
            #await asyncio.sleep(1)
        return
    async def setup_pre_reset(self):
        return

    async def setup_post_reset(self):
        self._controller.reset()
        await self._world.play_async()    
        return

    def world_cleanup(self):
        return
    
    def physics_step(self, step_size):
        if self._dc.is_simulating():
            for i in range(len(self._conveyor)):                
                if i < len(self._conveyor) -2:                  
                    if(self._conveyor[i+1].carrier == None and self._conveyor[i].carrier != None and self._conveyor[i].carrier.status == 1):
                        self._conveyor[i].carrier.status = 0
                        self._conveyor[i+1].carrier = copy.copy(self._conveyor[i].carrier)                                               
                        _thread = threading.Thread(target=self.MovePallet, args=(i,))
                        _thread.start()                          
        return

    def MovePallet(self,posIndex): 
        car = Articulation(prim_path= self._conveyor[posIndex].carrier.carrier_Name)
        target = car.get_world_pose()[0][1] - (self._pos[posIndex+1] - self._pos[posIndex])
        self._conveyor[posIndex].carrier.linearDriveAPI.CreateTargetPositionAttr(self._pos[posIndex+1])
        count = 0       
        while True:
            current = car.get_world_pose()[0][1]   
            print("Target Pos:",target,"Current:",current)
            if math.fabs(target - current) < 8 and math.fabs(target - current) > 0:
                self._conveyor[posIndex].status = 0
                break
            time.sleep(0.5)
            count = count + 1
            if count > 5:  
                self._conveyor[posIndex].carrier.linearDriveAPI.CreateTargetPositionAttr(self._pos[posIndex+1])    
                print("Reforce To Move")
                count = 0
        self._conveyor[posIndex].carrier =None        
        self._conveyor[posIndex+1].status = 1
        time.sleep(0.5)
        self._conveyor[posIndex+1].carrier.status = 1
        
        return

    async def _on_AddPlate_button_event_aync(self):
        self._linearDriveAPI.clear()
        platePath = '/Group/Carrier_{num:02d}'.format(num=self._widget_index) 
        rot = Rotation.from_euler('xyz', [0.7071, -0.7071, 0], degrees=True)
        rot_quat = rot.as_quat()
        create_prim(prim_path=platePath,#"/Group/Carrier_01",
                    prim_type="Xform",
                    position = np.array([77.6384, 63.1789, -178.758]),
                    scale=np.array([1,1,1]),
                    #orientation=euler_angles_to_quat(np.array([1.5707346, 0, -1.5707346])),#rot_quat,#np.array([90, -90, 0])#
                    usd_path="//home/quanta/Desktop/WorkingCopy/Robots/Carrier2.usd",
                    )                      
        #jointPath = '/Group/Conveyor_01/StartPos/prismaticJoint_{num:02d}'.format(num=self._widget_index)# {self._widget_index:02d}"
        jointPath = platePath+'/prismaticJoint_{num:02d}'.format(num=self._widget_index)
        stage = get_context().get_stage()
        
        prismaticJoint = UsdPhysics.PrismaticJoint.Define(stage, jointPath)
        prismaticJoint.CreateAxisAttr("X")
        prismaticJoint.CreateBody0Rel().SetTargets(["/Group/Conveyor_01/StartPos"])
        prismaticJoint.CreateBody1Rel().SetTargets([platePath])
        prismaticJoint.CreateLocalPos0Attr().Set(Gf.Vec3f(33.90559, -80.13061, 9.248482))
        prismaticJoint.CreateLocalRot0Attr().Set(Gf.Quatf(0.707,0,-0.707,0))
        self._prismaticJoint.append(prismaticJoint)
        print("Prismaticjoint:",len(self._prismaticJoint))
        # add linear drive
        linearDriveAPI = UsdPhysics.DriveAPI.Apply(stage.GetPrimAtPath(jointPath), "linear")
        linearDriveAPI.CreateTypeAttr("force")
        linearDriveAPI.CreateMaxForceAttr(10000000000)
        linearDriveAPI.CreateTargetVelocityAttr(0)
        linearDriveAPI.CreateTargetPositionAttr(0)
        linearDriveAPI.CreateDampingAttr(8000000.0)
        linearDriveAPI.CreateStiffnessAttr(10000000.0)
        #prismaticJoint.CreateLocalPos0Attr().Set(Gf.Vec3f(77.9125, 66.4155, -178.664))
        self._linearDriveAPI.append(linearDriveAPI)
        self._widget_index +=1
        return
    async def AddPlate_aync(self):
        platePath = '/Group/Carrier_{num:02d}'.format(num=self._widget_index) 
        create_prim(prim_path=platePath,#"/Group/Carrier_01",
                    prim_type="Xform",
                    position = np.array([77.6384, 63.1789, -178.758]),
                    scale=np.array([1,1,1]),
                    #orientation=euler_angles_to_quat(np.array([1.5707346, 0, -1.5707346])),#rot_quat,#np.array([90, -90, 0])#
                    usd_path="//home/quanta/Desktop/WorkingCopy/Robots/Carrier2.usd",
                    )   
        jointPath = platePath+'/prismaticJoint_{num:02d}'.format(num=self._widget_index)
        stage = get_context().get_stage()
        
        prismaticJoint = UsdPhysics.PrismaticJoint.Define(stage, jointPath)
        prismaticJoint.CreateAxisAttr("X")
        prismaticJoint.CreateBody0Rel().SetTargets(["/Group/Conveyor_01/StartPos"])
        prismaticJoint.CreateBody1Rel().SetTargets([platePath])
        prismaticJoint.CreateLocalPos0Attr().Set(Gf.Vec3f(33.90559, -80.13061, 9.248482))
        prismaticJoint.CreateLocalRot0Attr().Set(Gf.Quatf(0.707,0,-0.707,0))
        self._prismaticJoint.append(prismaticJoint)
        print("Prismaticjoint:",len(self._prismaticJoint))
        # add linear drive
        linearDriveAPI = UsdPhysics.DriveAPI.Apply(stage.GetPrimAtPath(jointPath), "linear")
        linearDriveAPI.CreateTypeAttr("force")
        linearDriveAPI.CreateMaxForceAttr(10000000000)
        linearDriveAPI.CreateTargetVelocityAttr(0)
        linearDriveAPI.CreateTargetPositionAttr(0)
        linearDriveAPI.CreateDampingAttr(8000000.0)
        linearDriveAPI.CreateStiffnessAttr(10000000.0)

        pallet = Pallet()
        pallet.carrier_Name = platePath
        pallet.jointPath = jointPath
        pallet.joint_Name = 'prismaticJoint_{num:02d}'.format(num=self._widget_index)
        pallet.prismaticJoint = prismaticJoint
        pallet.linearDriveAPI = linearDriveAPI        
        pallet.status = 1
        self._conveyor[0].carrier = pallet
        self._conveyor[0].status = 1

        self._widget_index +=1

        return
    async def _on_DelPlate_button_event_aync(self):        
        delete_prim(prim_path='/Group/Carrier_{num:02d}'.format(num=self._widget_index-1)) 
        delete_prim(prim_path='/Group/Conveyor_01/StartPos/prismaticJoint_{num:02d}'.format(num=self._widget_index-1))  
        self._linearDriveAPI.pop(0)     
        return
    async def _on_Move_button_event_aync(self):
        pos = [130,250,380,490,620] 
        self._linearDriveAPI[0].CreateTargetPositionAttr(pos[self._run_index])
        print("Move to position:",pos[self._run_index])
        self._run_index += 1
        if self._run_index == len(pos):
            self._run_index = 0
        return
 
    async def _on_Pause_button_event_aync(self):

        return
    async def _on_Stop_button_event_aync(self):
        self._conveyorThread.start()
        return   
class Pallet:
    def __init__(self, ):
        self.status = 0  # 0:Idel 1:Finish 
        self.carrier_Name = ""  # carrier name
        self.jointPath = ""
        self.joint_Name = ""
        self.prismaticJoint = None
        self.linearDriveAPI = None
        self.PosNo = 0 # in which conveyor
class Conveyor:
    def __init__(self,):
        self.carrier = None
        self.carrier_type = 0 # 0: crater 1:sled
        self.status = 0 # 0:empty 1:have item 
        self.ConveyorNo = -1

The following link is the video
IsaacSim Dynamic add

pxr Usd API is not meant for async authoring. Whenever creating or modifying values in the USD, you need to make it in the main thread, so you can modify your async calls to set a flag, and then have the USD updated in the main loop by consuming that flag.

Thanks for your answer Rgasoto. But I still not sure where is the main loop in Isaac Sim’s framework. Could you demonstrate an example for me and other users to know the main loop in Isaac Sim. Thank you!

In your code, the main loop would be in function physics_step. Alternatively, you can sync up with the viewport update by subscribing to the timeline step:

    def setup(self): #function where you set up your scene
            self._app_update_sub = (
                omni.kit.app.get_app().get_update_event_stream().create_subscription_to_pop(self._on_update_ui)
            )

    def _on_update_ui(self, step):
        do_stuff()

Thank you Rgasoto, best regards to you!!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.