Isaac Sim Version
4.2.0
4.1.0
4.0.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 3500 Ada Generation
- Driver Version: 565.57.01
Topic Description
Detailed Description
I am trying to use an action graph from Python code to create the tf tree of a robot. I followed the examples in the standalone application folder but have been without success so far.
Error Messages
[locobot_loader.py-3] 2025-01-28 21:02:03 [42,032ms] [Error] [ROS2BridgeHandler] Failed to create action graph: OmniGraphError: Failed to connect /ActionGraph/OnPlaybackTick.outputs:tick -> /ActionGraph/ReadSimTime.inputs:execIn [locobot_loader.py-3] [ERROR] [1738098123.600073694] [locobot_loader]: Failed to initialize LocobotLoader: Failed to setup ROS 2 bridge transforms [locobot_loader.py-3] Starting kit application with the following args: ['/home/ubuntu/anaconda3/envs/env_isaacsim/lib/python3.10/site-packages/isaacsim/exts/omni.isaac.kit/omni/isaac/kit/simulation_app.py', '/home/ubuntu/anaconda3/envs/env_isaacsim/lib/python3.10/site-packages/isaacsim/apps/omni.isaac.sim.python.kit', '--/app/tokens/exe-path=/home/ubuntu/.local/share/ov/pkg/isaac-sim-4.2.0/kit', '--/persistent/app/viewport/displayOptions=3094', '--/rtx/materialDb/syncLoads=True', '--/rtx/hydra/materialSyncLoads=True', '--/omni.kit.plugin/syncUsdLoads=True', '--/app/renderer/resolution/width=1024', '--/app/renderer/resolution/height=768', '--/app/window/width=1440', '--/app/window/height=900', '--/renderer/multiGpu/enabled=True', '--/app/fastShutdown=True', '--ext-folder', '/home/ubuntu/.local/share/ov/pkg/isaac-sim-4.2.0/exts', '--ext-folder', '/home/ubuntu/.local/share/ov/pkg/isaac-sim-4.2.0/apps', '--/physics/cudaDevice=0', '--portable'] [locobot_loader.py-3] Passing the following args to the base kit application: ['--ros-args', '-r', '__node:=locobot_loader'] [locobot_loader.py-3] Warp 1.2.1 initialized: [locobot_loader.py-3] CUDA Toolkit 11.8, Driver 12.7 [locobot_loader.py-3] Devices: [locobot_loader.py-3] "cpu" : "x86_64" [locobot_loader.py-3] "cuda:0" : "NVIDIA RTX 3500 Ada Generation Laptop GPU" (12 GiB, sm_89, mempool enabled) [locobot_loader.py-3] Kernel cache: [locobot_loader.py-3] /home/ubuntu/.cache/warp/1.2.1 [locobot_loader.py-3] Traceback (most recent call last): [locobot_loader.py-3] File "/home/ubuntu/stable_ws/install/stable_trail_robotic/lib/stable_trail_robotic/locobot_loader.py", line 260, in main [locobot_loader.py-3] loader = LocobotLoader() [locobot_loader.py-3] File "/home/ubuntu/stable_ws/install/stable_trail_robotic/lib/stable_trail_robotic/locobot_loader.py", line 89, in __init__ [locobot_loader.py-3] raise RuntimeError("Failed to setup ROS 2 bridge transforms") [locobot_loader.py-3] RuntimeError: Failed to setup ROS 2 bridge transforms [locobot_loader.py-3] [locobot_loader.py-3] During handling of the above exception, another exception occurred: [locobot_loader.py-3] [locobot_loader.py-3] Traceback (most recent call last): [locobot_loader.py-3] File "/home/ubuntu/stable_ws/install/stable_trail_robotic/lib/stable_trail_robotic/locobot_loader.py", line 271, in main [locobot_loader.py-3] if loader: [locobot_loader.py-3] UnboundLocalError: local variable 'loader' referenced before assignment [locobot_loader.py-3] [locobot_loader.py-3] During handling of the above exception, another exception occurred: [locobot_loader.py-3] [locobot_loader.py-3] Traceback (most recent call last): [locobot_loader.py-3] File "/home/ubuntu/stable_ws/install/stable_trail_robotic/lib/stable_trail_robotic/locobot_loader.py", line 281, in <module> [locobot_loader.py-3] main() [locobot_loader.py-3] File "/home/ubuntu/stable_ws/install/stable_trail_robotic/lib/stable_trail_robotic/locobot_loader.py", line 274, in main [locobot_loader.py-3] if loader: [locobot_loader.py-3] UnboundLocalError: local variable 'loader' referenced before assignment [locobot_loader.py-3] Fatal Python error: Segmentation fault [locobot_loader.py-3] [locobot_loader.py-3] Current thread 0x000071c292bea740 (most recent call first): [locobot_loader.py-3] <no Python frame> [locobot_loader.py-3] [locobot_loader.py-3] Extension modules: omni.mdl.pymdlsdk._pymdlsdk, psutil._psutil_linux, psutil._psutil_posix, numpy.core._multiarray_umath, numpy.core._multiarray_tests, numpy.linalg._umath_linalg, numpy.fft._pocketfft_internal, numpy.random._common, numpy.random.bit_generator, numpy.random._bounded_integers, numpy.random._mt19937, numpy.random.mtrand, numpy.random._philox, numpy.random._pcg64, numpy.random._sfc64, numpy.random._generator, torch._C, torch._C._fft, torch._C._linalg, torch._C._nested, torch._C._nn, torch._C._sparse, torch._C._special, scipy._lib._ccallback_c, scipy.sparse._sparsetools, _csparsetools, scipy.sparse._csparsetools, scipy.sparse.linalg._isolve._iterative, scipy.linalg._fblas, scipy.linalg._flapack, scipy.linalg._cythonized_array_utils, scipy.linalg._flinalg, scipy.linalg._solve_toeplitz, scipy.linalg._matfuncs_sqrtm_triu, scipy.linalg.cython_lapack, scipy.linalg.cython_blas, scipy.linalg._matfuncs_expm, scipy.linalg._decomp_update, scipy.sparse.linalg._dsolve._superlu, scipy.sparse.linalg._eigen.arpack._arpack, scipy.sparse.csgraph._tools, scipy.sparse.csgraph._shortest_path, scipy.sparse.csgraph._traversal, scipy.sparse.csgraph._min_spanning_tree, scipy.sparse.csgraph._flow, scipy.sparse.csgraph._matching, scipy.sparse.csgraph._reordering, scipy.spatial._ckdtree, scipy._lib.messagestream, scipy.spatial._qhull, scipy.spatial._voronoi, scipy.spatial._distance_wrap, scipy.spatial._hausdorff, scipy.special._ufuncs_cxx, scipy.special._ufuncs, scipy.special._specfun, scipy.special._comb, scipy.special._ellip_harm_2, scipy.spatial.transform._rotation, PIL._imaging, PIL._imagingft, scipy.ndimage._nd_image, _ni_label, scipy.ndimage._ni_label, osqp._osqp, multidict._multidict, yarl._quoting_c, aiohttp._helpers, aiohttp._http_writer, aiohttp._http_parser, aiohttp._websocket, _cffi_backend, frozenlist._frozenlist, scipy.io.matlab._mio_utils, scipy.io.matlab._streams, scipy.io.matlab._mio5_utils, yaml._yaml, cv2, rcl_interfaces.rcl_interfaces_s__rosidl_typesupport_c, builtin_interfaces.builtin_interfaces_s__rosidl_typesupport_c (total: 80) [ERROR] [locobot_loader.py-3]: process has died [pid 87398, exit code -11, cmd '/home/ubuntu/stable_ws/install/stable_trail_robotic/lib/stable_trail_robotic/locobot_loader.py --ros-args
Additional Information
What I’ve Tried
This is the code I implemented for that purpose
#!/usr/bin/env python3
import time
import logging
from typing import Optional, Dict, List, Tuple
import omni.graph.core as og
from omni.isaac.core.utils.extensions import enable_extension
from omni.isaac.core.utils import prims
import carb
class ROS2BridgeHandler:
"""Manages ROS 2 bridge functionality and graph nodes for Isaac Sim ROS 2 integration"""
def __init__(self, domain_id: int = 30):
"""Initialize ROS 2 bridge handler
Args:
domain_id (int): ROS_DOMAIN_ID for communication
"""
# Setup logging
self.logger = logging.getLogger("ROS2BridgeHandler")
self.logger.setLevel(logging.INFO)
# Store configuration
self._domain_id = domain_id
self._graph = None
# Initialize bridge extension
try:
enable_extension("omni.isaac.ros2_bridge")
time.sleep(1.0) # Give time for extension to load
self.logger.info("ROS 2 bridge extension enabled successfully")
except Exception as e:
self.logger.error(f"Failed to enable ROS 2 bridge extension: {str(e)}")
raise
def _validate_prim(self, prim_path: str) -> bool:
"""Validate if a prim path exists and is valid
Args:
prim_path (str): Path to validate
Returns:
bool: True if valid, False otherwise
"""
try:
if not prims.is_prim_path_valid(prim_path):
self.logger.error(f"Invalid prim path: {prim_path}")
return False
self.logger.info(f"Validated prim path: {prim_path}")
return True
except Exception as e:
self.logger.error(f"Error validating prim path: {str(e)}")
return False
def _create_graph_nodes(self, graph_path: str) -> Tuple[List, List]:
"""Create graph nodes and connections for ROS 2 bridge
Args:
graph_path (str): Path for the graph
Returns:
Tuple[List, List]: Nodes and connections lists
"""
# Base nodes required for all setups
nodes = [
("OnTick", "omni.graph.action.OnPlaybackTick"),
("ReadSimTime", "omni.isaac.core_nodes.IsaacReadSimulationTime"),
("Context", "omni.isaac.ros2_bridge.ROS2Context"),
("PublishTF", "omni.isaac.ros2_bridge.ROS2PublishTransformTree"),
("PublishClock", "omni.isaac.ros2_bridge.ROS2PublishClock"),
("QoSConfig", "omni.isaac.ros2_bridge.ROS2QoSProfile")
]
# Create base connections
connections = [
("OnTick.outputs:tick", "ReadSimTime.inputs:execIn"),
("OnTick.outputs:tick", "PublishTF.inputs:execIn"),
("OnTick.outputs:tick", "PublishClock.inputs:execIn"),
("ReadSimTime.outputs:simulationTime", "PublishTF.inputs:timeStamp"),
("ReadSimTime.outputs:simulationTime", "PublishClock.inputs:timeStamp"),
("Context.outputs:context", "PublishTF.inputs:context"),
("Context.outputs:context", "PublishClock.inputs:context"),
("QoSConfig.outputs:qosProfile", "PublishTF.inputs:qosProfile"),
("QoSConfig.outputs:qosProfile", "PublishClock.inputs:qosProfile")
]
return nodes, connections
def setup_transforms(self, prim_path: str, enable_joint_states: bool = True, parent_frame: str = "world") -> bool:
"""Setup ROS 2 transformations and joint states publishing"""
try:
# Validate inputs
if not self._validate_prim(prim_path):
return False
graph_path = "/ActionGraph"
try:
keys = og.Controller.Keys
# Create graph with exact pattern from documentation
self._graph = og.Controller.edit(
{
"graph_path": graph_path,
"evaluator_name": "execution"
},
{
keys.CREATE_NODES: [
("OnPlaybackTick", "omni.graph.action.OnPlaybackTick"),
("ReadSimTime", "omni.isaac.core_nodes.IsaacReadSimulationTime"),
("Context", "omni.isaac.ros2_bridge.ROS2Context"),
("PublishTF", "omni.isaac.ros2_bridge.ROS2PublishTransformTree"),
("PublishClock", "omni.isaac.ros2_bridge.ROS2PublishClock")
],
keys.CONNECT: [
("OnPlaybackTick.outputs:tick", "ReadSimTime.inputs:execIn"),
("OnPlaybackTick.outputs:tick", "PublishTF.inputs:execIn"),
("OnPlaybackTick.outputs:tick", "PublishClock.inputs:execIn"),
("ReadSimTime.outputs:simulationTime", "PublishTF.inputs:timeStamp"),
("ReadSimTime.outputs:simulationTime", "PublishClock.inputs:timeStamp"),
("Context.outputs:context", "PublishTF.inputs:context"),
("Context.outputs:context", "PublishClock.inputs:context")
],
keys.SET_VALUES: [
("Context.inputs:domain_id", self._domain_id),
("PublishTF.inputs:topicName", "/tf"),
("PublishTF.inputs:targetPrims", [prim_path]),
("PublishTF.inputs:parentFrameId", parent_frame),
("PublishClock.inputs:topicName", "/clock")
]
}
)
time.sleep(1.0)
if enable_joint_states:
og.Controller.edit(
self._graph,
{
keys.CREATE_NODES: [
("PublishJointState", "omni.isaac.ros2_bridge.ROS2PublishJointState")
],
keys.CONNECT: [
("OnPlaybackTick.outputs:tick", "PublishJointState.inputs:execIn"),
("ReadSimTime.outputs:simulationTime", "PublishJointState.inputs:timeStamp"),
("Context.outputs:context", "PublishJointState.inputs:context")
],
keys.SET_VALUES: [
("PublishJointState.inputs:topicName", "/joint_states"),
("PublishJointState.inputs:targetPrim", prim_path)
]
}
)
# Evaluate graph
og.Controller.evaluate_sync(self._graph)
time.sleep(0.5) # Give time for evaluation
self.logger.info("Successfully setup ROS 2 transforms")
return True
except Exception as e:
self.logger.error(f"Failed to create action graph: {str(e)}")
return False
except Exception as e:
self.logger.error(f"Failed to setup transforms: {str(e)}")
return False
def cleanup(self):
"""Cleanup graph resources"""
try:
if self._graph is not None:
og.Controller.clear(self._graph)
self._graph = None
self.logger.info("ROS 2 bridge cleanup successful")
except Exception as e:
self.logger.error(f"Error during cleanup: {str(e)}")