Omnigraph 是 Nvidia Omniverse 中一个强大的视觉化脚本工具,它让开发者能够以直观和灵活的方式创建复杂的行为和交互性。通过结合 Action Graphs 和 Push Graphs,以及利用丰富的节点库,用户可以在 Omniverse 平台上构建出令人惊叹的虚拟世界。
omnigraph介绍https://docs.omniverse.nvidia.com/extensions/latest/ext_omnigraph.html
在 Omnigraph 中,用户可以创建两种主要类型的图表:
Action Graphs(动作图表):这类图表允许用户定义事件驱动的行为。这意味着你可以设置一系列的动作,这些动作会在满足特定条件或事件发生时被触发。这对于创建响应式场景、游戏逻辑或交互式模拟非常有用。
Push Graphs(推送图表):与 Action Graphs 不同,Push Graphs 会持续评估其节点。这意味着图表中的每个节点都会不断地更新其状态,并根据输入数据进行计算。这种图表类型非常适合于需要实时数据处理和反馈的场景,如物理模拟、粒子效果或动态系统。
虽然Omniverse和isaac sim中已有了大量的 Omnigraph ,但是很多时候这些或这些的组合在实际开发中是不够的,那就需要自己去实现一些 Omnigraph ,本文将探讨如何使用python实现自定义的 Omnigraph 。
现有的Omnigraph 定义和描述https://docs.omniverse.nvidia.com/extensions/latest/ext_omnigraph/node-library/node-library.html
打开 USD Composer 软件,(新版的Isaac sim里没有带 Node Description Editor)
点击:Window > Visual Scripting > Node Description Editor
这里演示做一个最简单的ros2 消息发布
一、创建一个OmniGraph模板和插件
property属性等介绍这里就不讲了,见 OmniGraph Developer 文档:
Attribute Type Definition — kit-omnigraph 1.26.2 documentation (nvidia.com)
填好内容后,依次点击:
Populate Extension -> Save Node -> Generate Blank Implementation -> Edit Node
保存创建的Node
单击“Edit Node” 后, 会在vscode里打开 python 文件,这是您的节点的模板,编辑该模版,就可以实施您的节点逻辑。
生成的python模板
二、实施自己的python节点逻辑
我们需要1hz频率不断发布一个ros2 string消息,并且将消息的索引打印出来,输出给前端显示。下面是对模板代码的更改,完成该需求:
"""
This is the implementation of the OGN node defined in ros2_easy_pub.ogn
"""
# Array or tuple values are accessed as numpy arrays so you probably need this import
import numpy
import omni
import carb
# OgnROS2CustomPythonNodeDatabase module is an autogenerated python module located in the extension and is used later on.
import rclpy
from std_msgs.msg import String
# BaseResetNode class is used for resetting the node when stopping and playing
from omni.isaac.core_nodes import BaseResetNode
class ros2_easy_pub:
"""
publish_ros2_msg
"""
@staticmethod
def internal_state():
return OgnROS2CustomPythonPubInternalState()
@staticmethod
def compute(db) -> bool:
"""Compute the outputs from the current input"""
state = db.per_instance_state
try:
if not state.initialized:
state.initialize_ros2_node('easy_ros2_pub')
rclpy.spin_once(state.node, timeout_sec=0.01)
db.outputs.index = state.index
except Exception as error:
# If anything causes your compute to fail report the error and return False
db.log_error(str(error))
return False
# Even if inputs were edge cases like empty arrays, correct outputs mean success
return True
@staticmethod
def release(node):
try:
state = OgnROS2CustomPythonPubInternalState.per_instance_internal_state(node)
except Exception:
state = None
if state is not None:
state.custom_reset()
class OgnROS2CustomPythonPubInternalState(BaseResetNode):
def __init__(self):
self.node = None
self.index = 0
super().__init__(initialize=False)
def initialize_ros2_node(self, node_name):
try:
rclpy.init()
except:
carb.log_error("init ros2 node failed!")
self.node = rclpy.create_node(node_name)
self.pub = self.node.create_publisher(String, 'chatter', 10)
timer_period = 1.0
self.tmr = self.node.create_timer(timer_period, self.timer_callback)
self.initialized = True
def timer_callback(self):
msg = String()
msg.data = 'Hello World: {0}'.format(self.index)
self.index += 1
# self.get_logger().info('Publishing: "{0}"'.format(msg.data))
self.pub.publish(msg)
carb.log_info(f"msg: {msg.data}")
# Overriding a function from BaseResetNode.
# This is automatically called when simulation is stopped.
# This is will also be called when the OmniGraph node is released.
def custom_reset(self):
if self.node:
self.node.destroy_node()
self.node = None
self.initialized = False
rclpy.try_shutdown()
这里程序是ros2消息发布,依赖ros2_bridge插件,所以需要在插件配置文件里,添加该插件。打开创建的扩展文件夹根目录,然后打开config/extension.toml
文件。查找[dependencies]
部分并在其下添加以下行。保存并关闭。
"omni.isaac.ros2_bridge" = {}
三、启用插件和验证开发的OmniGraph
在扩展管理器中,查找创建好的新扩展,这次创建的扩展名字叫 omni.new.extension ,我们直接搜索,在第三方插件那里即可显示出来。
由于需要ros2_bridge插件依赖,我们打开isaac sim,在里启动这个新建好的插件。 可以看到自己创建的插件都在User目录下。
然后打开 Action graph , 搜索自己定义的graph关键词就能看到创建的graph了
下面创建一个具体的Action Graph来测试:
ros消息可以顺利发布出来了,并且索引值也正常打印和输出传给前端界面
四、其它一些python ros2 OmniGraph的例子
官方为了我们更好理解摄像头和雷达的OmniGraph,开源了几个例子,在 isaac_sim 目录 exts\omni.isaac.ros2_bridge 里面以及 exts\omni.isaac.sensor 里面有激光等传感器,如 OgnIsaacPrintRTXLidarInfo 可以处理并打印原始RTX激光雷达数据,OgnROS2RtxLidarHelper 可以看到如何使用 replicator 发布激光点云数据,如果不会创建 OmniGraph,也可以直接在这些例程上修改。
可以看到创建定义和描述节点所需的两个文件.py
和.ogn