Obtained prime position data and replicator bbox data not match the captured image

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: NVIDIA RTX 5880 Ada Generation
  • Driver Version: 12.4

Topic Description

Detailed Description

(Describe the issue in detail, including what you were trying to do, what you expected to happen, and what actually happened)

  1. we use headless mode
  2. we use replicator to obtain the bbox position information on image, but they do not match
  3. we use issacim to obtain the 3d positions of a prim and get the 2d coordinates in the image, but the position is not right

Steps to Reproduce

  1. main
# set scene
world, viewport_api, stage, camera = set_scene()

i = 0
while simulation_app.is_running():
    # --- 器械1 ---
    # 将随机产生的位移、角度设置到器械关节并进行渲染 
    art_1 = dc.get_articulation("/RLND_8_G3_0")
    dc.wake_up_articulation(art_1)
    joint_angles_1 = [np.array([j1, j2, j3, j4, j5, 
                        j6, j7, j8, j9, j10,
                        j11, j12, j13])] # 设定随机值
    dc.set_articulation_dof_position_targets(art_1, joint_angles_1)

    # --- 器械2 ---    
    art_2 = dc.get_articulation("/RMBF_8_G3_0")
    dc.wake_up_articulation(art_2)
    joint_angles_2 = [np.array([j1, j2, j3, j4, j5, 
                        j6, j7, j8, j9, j10,
                        j11, j12, j13])] # 再次设定随机值
    dc.set_articulation_dof_position_targets(art_2, joint_angles_2)

    # Multiple rendering for smooth motion effects
    for j in range(60):   # note
        world.step(render=True)  

    # 获取渲染的图像
    get_viewport_img(save_img_path, save_image_name, viewport_api,i)

    # 获取第一把器械的bounding-box的信息从replicator里
    get_bbox_2d_loose()
    # 获取第一把器械的keypoints的2d位置信息从isaacsim里
    get_keypoints_2d()

    # 获取第二把器械的bounding-box的信息从replicator里
    get_bbox_2d_loose()
    # 获取第二把器械的keypoints的2d位置信息从isaacsim里
    get_keypoints_2d()

    # 把信息整合成labelme可读的json文件
    send_info_to_json_file()

    i += 1

  1. set scene
import omni.kit.commands
from omni.isaac.dynamic_control import _dynamic_control
from pxr import Sdf, Gf, UsdPhysics, UsdLux, PhysxSchema, UsdGeom
from omni.isaac.sensor import Camera
import omni.isaac.core.utils.numpy.rotations as rot_utils

def set_scene():
    # Setting up URDF import configuration  设置导入配置
    status, import_config = omni.kit.commands.execute("URDFCreateImportConfig")
    import_config.merge_fixed_joints = False
    import_config.convex_decomp = False #禁用凸分解
    import_config.import_inertia_tensor = True
    import_config.fix_base = False
    import_config.distance_scale = 100

    status, stage_path = omni.kit.commands.execute(
        "URDFParseAndImportFile",
        urdf_path=current_work_dir + "/GEM-8mm-urdf-meshes/urdf/instr_RLND-8_v2.urdf",   # surgical instrument 1
        import_config=import_config,
    )

    status, stage_path = omni.kit.commands.execute(
        "URDFParseAndImportFile",
        urdf_path=current_work_dir + "/urdf/robot_G2_2_2_FleshColor.urdf",   # SetupArmG
        import_config=import_config,
    )
    status, stage_path = omni.kit.commands.execute(
        "URDFParseAndImportFile",
        urdf_path=current_work_dir + "/GEM-8mm-urdf-meshes/urdf/instr_RMBF-8_v2.urdf", # surgical instrument 2
        import_config=import_config,
    )

    # Get stage handle
    stage = omni.usd.get_context().get_stage()

    # Add world
    from omni.isaac.core import World
    world = World()

    # Enable physics  设置物理环境
    scene = UsdPhysics.Scene.Define(stage, Sdf.Path("/physicsScene"))
    # Set gravity  设置重力
    scene.CreateGravityDirectionAttr().Set(Gf.Vec3f(0.0, 0.0, -1.0))
    scene.CreateGravityMagnitudeAttr().Set(9.81)
    # Set solver settings  配置物理求解器
    PhysxSchema.PhysxSceneAPI.Apply(stage.GetPrimAtPath("/physicsScene"))
    physxSceneAPI = PhysxSchema.PhysxSceneAPI.Get(stage, "/physicsScene")
    physxSceneAPI.CreateEnableCCDAttr(True)#连续碰撞
    physxSceneAPI.CreateEnableStabilizationAttr(True)
    physxSceneAPI.CreateEnableGPUDynamicsAttr(False)

    # Add ground plane
    omni.kit.commands.execute(
        "AddGroundPlaneCommand",
        stage=stage,
        planePath="/groundPlane",
        axis="Z",
        size=1500.0,
        position=Gf.Vec3f(0, 0, 0),
        color=Gf.Vec3f(0.5, 0.5, 0.5),   # Note!
    )

    # set joint angle
    dc = _dynamic_control.acquire_dynamic_control_interface()
    def set_joint_angles(yaw_deg, pitch_deg):
        # 获取articulation接口
        dc = _dynamic_control.acquire_dynamic_control_interface()
        articulation = dc.get_articulation("/SetupArmG2_2")
        
        if articulation == _dynamic_control.INVALID_HANDLE:
            print("Error: Articulation not found!")
            return

        # 新版API获取关节方式
        dof_states = dc.get_articulation_dof_states(articulation, _dynamic_control.STATE_ALL)
        
        # 设置关节角度(弧度)
        joints_config = {
            "A1234": np.deg2rad(yaw_deg),  # Z轴旋转
            "A5": np.deg2rad(pitch_deg)     # Y轴旋转
        }
        
        # 更新DOF状态
        for i in range(len(dof_states)):
            joint_name = dc.get_dof_name(dc.get_articulation_dof(articulation, i))
            if joint_name in joints_config:
                dof_states[i]["pos"] = joints_config[joint_name]
        
        # 应用新状态
        dc.set_articulation_dof_states(articulation, dof_states, _dynamic_control.STATE_ALL)
    # 示例:水平转向5° + 俯仰-5°
    set_joint_angles(5, -5)   

    # Add camera
    camera = Camera(
        prim_path="/SetupArmG2_2/L5/Camera",   # 相机在usd格式中的路径
        translation=np.array([-0.65, 0, -0.8]),# 相机相对于父Prim的位移
        frequency=60,#帧率
        resolution=(1920, 1080),#分辨率
        orientation=rot_utils.euler_angles_to_quats(np.array([0, 89, 129]), degrees=True)#欧拉角转四元数 plan b 旋转背景和相机
    )

    # Add some light and background images

    # Flash world after add object
    world.reset()
    camera.initialize()

    camera.set_resolution([1920, 1080])

    # Get viewport api, bind camera and adjust resolution 
    from omni.kit.viewport.utility import get_viewport_from_window_name
    viewport_api = get_viewport_from_window_name("Viewport")
    viewport_api.set_active_camera("/SetupArmG2_2/L5/Camera")   # 绑定场景所设置的相机(附加在机械臂上)
    viewport_api.resolution=(1920, 1080)
    
    world.step(render=True)
    
    return world,viewport_api, stage, camera

  1. capture image
from omni.kit.viewport.utility import capture_viewport_to_file
import time

def get_viewport_img(save_path, img_name, viewport_api, i):
    # Get image from specified viewport
    imgae_path = "path/to/img.png"
    capture_viewport_to_file(viewport_api, imgae_path)
    # Wait a bit to ensure the file is saved
    time.sleep(0.1)
  1. get bbox
from omni.isaac.core.utils.semantics import add_update_semantics
from omni.isaac.core.utils.extensions import enable_extension # isaacsim-v2023
enable_extension("omni.isaac.synthetic_utils")    # isaacsim-v2023
from omni.isaac.synthetic_utils import SyntheticDataHelper # isaacsim-v2022

def get_bbox_2d_loose(labelname, selected_prims_bbox, camera_prim):
    
    # 设置语义过滤器 labelname="器械名"
    # selected_prims_bbox = [一个器械里的多个零部件]
    for i in range(len(selected_prims_bbox)):
        G_instr = stage.GetPrimAtPath(selected_prims_bbox[i])
        add_update_semantics(G_instr, "object_"+str(i), type_label=labelname)

    sd.SyntheticData.Get().set_instance_mapping_semantic_filter(f"{labelname}:*")

    # camera prim是相机在isaacsim里面的prim路径
    rp = rep.create.render_product(camera_prim, (1920, 1080))

    bbox_2d_loose = rep.AnnotatorRegistry.get_annotator("bounding_box_2d_loose")
    bbox_2d_loose.attach(rp)

    rep.orchestrator.step() 

    bboxes_data = bbox_2d_loose.get_data() # 获得每个部位的bbox数据
    rect_data = bbox_fuse(bboxes_data) # 将每个部位的数据合并成一个bbox

    # 存储数据
    data = []
    
    # detach防止后续调用错误
    try:
        bbox_2d_loose.detach()
    except Exception:
        pass

    return data
  1. get 2d coordinates
def get_keypoints_2d(stage, camera, selected_prims):
    '''
    Get the 3D positon information of concerned keypoints
    input:
    selected_prims = ["prim1", "prim2", "prim3"]
    '''    
    # Get keypoints 3d pose
    timeline = omni.timeline.get_timeline_interface() # Get the current timecode
    timecode = timeline.get_current_time() * timeline.get_time_codes_per_seconds()

    for i, s in enumerate(selected_prims):
        curr_prim = stage.GetPrimAtPath(s) #获取场景中指定路径下的 USD 主体

        #获取指定 USD 主体在世界坐标系中的变换矩阵
        # pose = omni.usd.utils.get_world_transform_matrix(curr_prim, timecode) # isaacsim-v2022
        pose = omni.usd.get_world_transform_matrix(curr_prim, timecode) # isaacsim-v2023
        world_point = np.array([list(pose.ExtractTranslation())]) # keypoints-3d: 给定的世界变换矩阵 pose 中提取平移部分        
        image_coord = camera.get_image_coords_from_world_points(world_point)   # keypoints-2d: 相机捕获
        
        # 数据存储
        data= []
    return data

Error Messages

(If applicable, copy and paste any error messages you received)
Visualization not right

Screenshots or Videos

(If applicable, add screenshots or links to videos that demonstrate the issue)

Additional Information

What I’ve Tried

(Describe any troubleshooting steps you’ve already taken)

Related Issues

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

Additional Context

(Add any other context about the problem here)

It looks like you’re using Isaac Sim version 2023.1.0-hotfix.1, which is an older, unsupported version.

I recommend trying to reproduce your issue with the latest Isaac Sim 5.0.0 developer preview. This new version is built on Omniverse Kit 107 and includes numerous improvements and bug fixes that might resolve the discrepancies you’re seeing with prime position data and Replicator bbox data.

You can find more information about the latest version on GitHub - isaac-sim/IsaacSim: NVIDIA Isaac Sim™ is an open-source application on NVIDIA Omniverse for developing, simulating, and testing AI-driven robots in realistic virtual environments..

Please let us know if upgrading helps resolve your issue!

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