While going through the documentation, i was able to replicate the amr_navigation.py for my forklift, but right now the path is random and i want my forklift/carter to move to the point i want for that i created an empty Xform and placed in the scene and the translate were x = -24, y = 0, z=0. but i am unable to move it to that point, It would be great if you could help me with this and even suggest changes in my code.
NOTE:-
# *** Run the code, fix camera positions in viewport, press ENTER in terminal to start recording ***
“”“Generate offline synthetic dataset with Carter NAV movement”“”
import argparse
import json
import math
import os
import random
import threading
import yaml
from isaacsim import SimulationApp
config = {
"launch_config": {
"renderer": "RaytracedLighting",
"headless": False,
},
"resolution": \[1920, 1080\],
"rt_subframes": 4,
"num_frames": 800,
"env_url": "/Isaac/Environments/Simple_Warehouse/full_warehouse.usd",
"writer": "BasicWriter",
"writer_config": {
"output_dir": "\_out_custom_sdg_forklift",
"rgb": True,
"bounding_box_2d_tight": True,
"semantic_segmentation": True,
"bounding_box_3d": True,
"occlusion": True,
},
"clear_previous_semantics": True,
"forklift": {
"url": "/Isaac/Props/Forklift/forklift.usd",
"class": "forklift",
},
"cone": {
"url": "/Isaac/Environments/Simple_Warehouse/Props/S_TrafficCone.usd",
"class": "traffic_cone",
},
"pallet": {
"url": "/Isaac/Environments/Simple_Warehouse/Props/SM_PaletteA_01.usd",
"class": "pallet",
},
"cardbox": {
"url": "/Isaac/Environments/Simple_Warehouse/Props/SM_CardBoxD_04.usd",
"class": "cardbox",
},
"close_app_after_run": True,
}
import carb
parser = argparse.ArgumentParser()
parser.add_argument(“–config”, required=False, help=“Include specific config parameters (json or yaml)”)
args, unknown = parser.parse_known_args()
args_config = {}
if args.config and os.path.isfile(args.config):
print("File exist")
with open(args.config, "r") as f:
if args.config.endswith(".json"):
args_config = json.load(f)
elif args.config.endswith(".yaml"):
args_config = yaml.safe_load(f)
else:
carb.log_warn(f"File {args.config} is not json or yaml, will use default config")
else:
if args.config:
carb.log_warn(f"File {args.config} does not exist, will use default config")
if “writer_config” in args_config:
config\["writer_config"\].clear()
config.update(args_config)
simulation_app = SimulationApp(launch_config=config[“launch_config”])
import carb.settings
import omni.replicator.core as rep
import omni.usd
import omni.timeline
import scene_based_sdg_utils
from isaacsim.core.utils import prims
from isaacsim.core.utils.rotations import euler_angles_to_quat
from isaacsim.core.utils.stage import get_current_stage, open_stage
from isaacsim.core.utils.stage import add_reference_to_stage
from isaacsim.storage.native import get_assets_root_path
from pxr import Gf, UsdGeom, UsdPhysics, PhysxSchema
assets_root_path = get_assets_root_path()
if assets_root_path is None:
carb.log_error("Could not get nucleus server path, closing application..")
simulation_app.close()
print(f"[scene_based_sdg] Loading Stage {config[‘env_url’]}")
if not open_stage(assets_root_path + config[“env_url”]):
carb.log_error(f"Could not open stage {config\['env_url'\]}, closing application..")
simulation_app.close()
rep.orchestrator.set_capture_on_play(False)
carb.settings.get_settings().set(“rtx/post/dlss/execMode”, 0)
stage = get_current_stage()
if config[“clear_previous_semantics”]:
scene_based_sdg_utils.remove_previous_semantics(stage)
# ================================================================
# ✅ COLLISION FIX
# ================================================================
physics_scene_path = “/physicsScene”
if not stage.GetPrimAtPath(physics_scene_path).IsValid():
physics_scene = UsdPhysics.Scene.Define(stage, physics_scene_path)
physx_scene = PhysxSchema.PhysxSceneAPI.Apply(stage.GetPrimAtPath(physics_scene_path))
physx_scene.GetEnableCCDAttr().Set(True)
physx_scene.GetEnableGPUDynamicsAttr().Set(False)
physx_scene.GetBroadphaseTypeAttr().Set("MBP")
print("\[scene_based_sdg\] Physics scene with CCD + MBP created.")
else:
physx_scene = PhysxSchema.PhysxSceneAPI.Apply(stage.GetPrimAtPath(physics_scene_path))
physx_scene.GetEnableCCDAttr().Set(True)
physx_scene.GetEnableGPUDynamicsAttr().Set(False)
physx_scene.GetBroadphaseTypeAttr().Set("MBP")
print("\[scene_based_sdg\] Physics scene patched with CCD + MBP.")
# ================================================================
# CARTER NAV
# ================================================================
add_reference_to_stage(
usd_path=assets_root_path + "/Isaac/Samples/Replicator/OmniGraph/nova_carter_nav_only.usd",
prim_path="/NavWorld/CarterNav"
)
# ================================================================
# FORKLIFT WRAPPER
# ================================================================
wrapper_path = “/NavWorld/CarterNav/chassis_link/ForkliftWrapper”
forklift_path = wrapper_path + “/Forklift”
wrapper_prim = stage.DefinePrim(wrapper_path, “Xform”)
add_reference_to_stage(
usd_path=assets_root_path + config\["forklift"\]\["url"\],
prim_path=forklift_path
)
wrapper_xform = UsdGeom.Xformable(wrapper_prim)
wrapper_xform.ClearXformOpOrder()
wrapper_xform.AddOrientOp().Set(Gf.Quatf(0.707, Gf.Vec3f(0, 0, 0.707)))
# ================================================================
# HIDE CARTER VISUALS
# ================================================================
carter_visual = stage.GetPrimAtPath(“/NavWorld/CarterNav/chassis_link/visuals”)
if carter_visual and carter_visual.HasAttribute(“visibility”):
carter_visual.GetAttribute("visibility").Set("invisible")
# ================================================================
# PALLET
# ================================================================
pallet_prim = prims.create_prim(
prim_path="/World/Pallet",
position=(0.0, -1.5, 0.0),
orientation=euler_angles_to_quat(\[0, 0, 0\]),
usd_path=assets_root_path + config\["pallet"\]\["url"\],
semantic_label=config\["pallet"\]\["class"\],
)
# ================================================================
# SEMANTIC LABEL ON FORKLIFT
# ================================================================
forklift_prim = stage.GetPrimAtPath(forklift_path)
if forklift_prim.IsValid():
try:
from isaacsim.core.utils.semantics import add_update_semantics
add_update_semantics(forklift_prim, config\["forklift"\]\["class"\])
except Exception:
pass
foklift_pos_gf = Gf.Vec3d(0.0, 0.0, 0.0)
pallet_pos_gf = Gf.Vec3d(0.0, -1.5, 0.0)
# ================================================================
# REGISTER RANDOMIZATION GRAPHS
# ================================================================
scene_based_sdg_utils.register_scatter_boxes(pallet_prim, assets_root_path, config)
scene_based_sdg_utils.register_cone_placement(forklift_prim, assets_root_path, config)
scene_based_sdg_utils.register_lights_placement(forklift_prim, pallet_prim)
# ================================================================
# simulate_falling_objects BEFORE timeline.play()
# ================================================================
print(“[scene_based_sdg] Running falling objects simulation…”)
scene_based_sdg_utils.simulate_falling_objects(forklift_prim, assets_root_path, config)
print(“[scene_based_sdg] Falling objects done.”)
for _ in range(20):
simulation_app.update()
# ================================================================
# CAMERAS
# ================================================================
warehouse_cam_left = rep.create.camera(name=“WarehouseCamLeft”)
warehouse_cam_right = rep.create.camera(name=“WarehouseCamRight”)
with warehouse_cam_left:
rep.modify.pose(
position=(-26.38117, -23.45436, 6.06221),
rotation=(79.57776, 0.0, -34.79463)
)
with warehouse_cam_right:
rep.modify.pose(
position=(5.23387, -19.65781, 6.58365),
rotation=(77.64104, 0.0, 42.62757)
)
resolution = tuple(config[“resolution”])
warehouse_left_rp = rep.create.render_product(warehouse_cam_left, resolution, name=“WarehouseLeft”)
warehouse_right_rp = rep.create.render_product(warehouse_cam_right, resolution, name=“WarehouseRight”)
rps = [warehouse_left_rp, warehouse_right_rp]
for rp in rps:
rp.hydra_texture.set_updates_enabled(False)
# ================================================================
# START TIMELINE
# ================================================================
timeline = omni.timeline.get_timeline_interface()
timeline.play()
print(“[scene_based_sdg] Warming up Carter articulation (200 ticks)…”)
for _ in range(200):
simulation_app.update()
# ================================================================
# CARTER PRIM HANDLES
# ================================================================
nav_target = stage.GetPrimAtPath(“/NavWorld/CarterNav/targetXform”)
carter = stage.GetPrimAtPath(“/NavWorld/CarterNav/chassis_link”)
if not nav_target.IsValid():
carb.log_error("targetXform not found")
simulation_app.close()
# ================================================================
# SPEED BOOST
# ================================================================
try:
nav_prim = stage.GetPrimAtPath("/NavWorld/CarterNav")
for attr_name, val in \[
("maxSpeed", 20.0),
("maxAcceleration", 18.0),
("maxAngularSpeed", 200.0),
\]:
attr = nav_prim.GetAttribute(attr_name)
if attr and attr.IsValid():
attr.Set(val)
print("\[scene_based_sdg\] Speed attributes set.")
except Exception as e:
print(f"\[scene_based_sdg\] Speed boost skipped: {e}")
# ================================================================
# FIXED DESTINATION NAVIGATION
# ================================================================
DESTINATION = (-24.79925, 0.0, 0.0)
# ================================================================
# INITIAL NAV TARGET
# ================================================================
nav_target.GetAttribute(“xformOp:translate”).Set(DESTINATION)
print(f"[scene_based_sdg] Moving Carter to destination: {DESTINATION}")
for _ in range(50):
simulation_app.update()
carter_pos = carter.GetAttribute(“xformOp:translate”).Get()
print(f"[scene_based_sdg] Carter position after init: {carter_pos}")
# ================================================================
# DISTANCE CHECK
# ================================================================
def distance_to_destination():
try:
c = carter.GetAttribute("xformOp:translate").Get()
if c is None:
return 999.0
return (
(c\[0\] - DESTINATION\[0\]) \*\* 2 +
(c\[1\] - DESTINATION\[1\]) \*\* 2
) \*\* 0.5
except Exception:
return 999.0
# ================================================================
# CAMERA SETUP — press ENTER in terminal
# ================================================================
print(“\n” + “=”*60)
print(" CAMERA SETUP MODE")
print(" Carter + Forklift are moving in the viewport now")
print(" Adjust WarehouseCamLeft and WarehouseCamRight")
print(" → Press ENTER in terminal when ready to record")
print(“=”*60 + “\n”)
while simulation_app.is_running():
simulation_app.update()
try:
import msvcrt
if msvcrt.kbhit():
key = msvcrt.getch()
if key == b'\\r':
break
except Exception:
pass
print(“[scene_based_sdg] Starting SDG pipeline…”)
timeline.play()
for _ in range(50):
simulation_app.update()
# ================================================================
# WRITER SETUP
# ================================================================
if not os.path.isabs(config[“writer_config”][“output_dir”]):
config\["writer_config"\]\["output_dir"\] = os.path.join(
os.getcwd(), config\["writer_config"\]\["output_dir"\]
)
print(f"[scene_based_sdg] Output directory = {config[‘writer_config’][‘output_dir’]}")
writer_type = config.get(“writer”, “BasicWriter”)
if writer_type not in rep.WriterRegistry.get_writers():
carb.log_error(f"Writer type {writer_type} not found")
simulation_app.close()
writer = rep.WriterRegistry.get(writer_type)
writer_kwargs = config[“writer_config”]
print(f"[scene_based_sdg] Initializing {writer_type} with: {writer_kwargs}")
writer.initialize(**writer_kwargs)
# ================================================================
# REPLICATOR TRIGGERS
# ================================================================
with rep.trigger.on_frame():
rep.randomizer.scatter_boxes()
rep.randomizer.randomize_lights()
with rep.trigger.on_custom_event(“randomize_cones”):
rep.randomizer.place_cones()
# ================================================================
# ENABLE RENDER PRODUCTS + ATTACH WRITER
# ================================================================
for rp in rps:
rp.hydra_texture.set_updates_enabled(True)
writer.attach(rps)
# ================================================================
# MAIN SDG LOOP
# ================================================================
rt_subframes = 1
num_frames = config.get(“num_frames”, 0)
print(f"[scene_based_sdg] Running SDG for {num_frames} frames")
for i in range(num_frames):
print(f"\[scene_based_sdg\] \\t Capturing frame {i}")
if i % 200 == 0:
rep.utils.send_og_event(event_name="randomize_cones")
rep.orchestrator.step(
delta_time=1/60,
pause_timeline=False,
rt_subframes=1
)
# ================================================================
# FINALISE
# ================================================================
rep.orchestrator.wait_until_complete()
writer.detach()
for rp in rps:
rp.destroy()
close_app_after_run = config.get(“close_app_after_run”, True)
if config[“launch_config”][“headless”]:
pass
elif not close_app_after_run:
print("\[scene_based_sdg\] App will stay open. Close manually.")
while simulation_app.is_running():
simulation_app.update()
simulation_app.close()