创建自己的 Omnigraph (python篇)

news2025/2/26 15:13:27

Omnigraph 是 Nvidia Omniverse 中一个强大的视觉化脚本工具,它让开发者能够以直观和灵活的方式创建复杂的行为和交互性。通过结合 Action GraphsPush Graphs,以及利用丰富的节点库,用户可以在 Omniverse 平台上构建出令人惊叹的虚拟世界。

omnigraph介绍icon-default.png?t=N7T8https://docs.omniverse.nvidia.com/extensions/latest/ext_omnigraph.html

在 Omnigraph 中,用户可以创建两种主要类型的图表:

  1. Action Graphs(动作图表):这类图表允许用户定义事件驱动的行为。这意味着你可以设置一系列的动作,这些动作会在满足特定条件或事件发生时被触发。这对于创建响应式场景、游戏逻辑或交互式模拟非常有用。

  2. Push Graphs(推送图表):与 Action Graphs 不同,Push Graphs 会持续评估其节点。这意味着图表中的每个节点都会不断地更新其状态,并根据输入数据进行计算。这种图表类型非常适合于需要实时数据处理和反馈的场景,如物理模拟、粒子效果或动态系统。

虽然Omniverse和isaac sim中已有了大量的 Omnigraph ,但是很多时候这些或这些的组合在实际开发中是不够的,那就需要自己去实现一些 Omnigraph ,本文将探讨如何使用python实现自定义的 Omnigraph 。

现有的Omnigraph 定义和描述icon-default.png?t=N7T8https://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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1960043.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Ubuntu虚拟机扩容笔记(各种方法都不行版)

1.背景介绍 最近需要对ubuntu的虚拟机下面的挂载根目录上的文件系统对应的硬盘进行扩容,在虚拟机管理平台对磁盘进行扩容后,在图形界面上尝试扩容: 尝试教程主要采用下面教程的第三种方法: Ubuntu22.04 Linux磁盘扩容/硬盘扩展…

【C++】学习笔记——C++11_1

文章目录 十九、C111. 统一的列表初始化{}初始化std::initializer_list 2. 声明autodecltypenullptr 4. 范围for5. STL中的一些变化新容器新方法 6. 右值引用和移动语句左值引用和右值引用 未完待续 十九、C11 1. 统一的列表初始化 {}初始化 在C98中,标准允许使用…

C++ map/set 函数用法解析

一 . set 1.1 set 是什么、关联/非关联式容器 se是一种关联式容器,主要用进行查找的工作。采用了key模型,判断数据在不在。不支持修改的操作。 序列式容器(线性表):vector / list /deque(单纯存储数据&am…

top命令从入门到精通

top命令从入门到精通 linux平台上一个可以用于性能监控、排查的神器。 响应参数 up:运行时长users:当前登陆了几个用户load average:运行负载 sleeping:休眠进程stopped:终止进程zombie:僵尸进程 us&…

Neutralinojs教程项目实战初体验(踩坑指南),干翻 electron

Neutralinojs 项目实战初体验(踩坑指南),干翻 electron Neutralinojs 官方文档 卧槽卧槽,!这个年轻人居然用浏览器把电脑关机了_哔哩哔哩_bilibili正是在下 本教程搭建的是纯原生项目,没有和其它前端框架…

【C++BFS】959. 由斜杠划分区域

本文涉及知识点 CBFS算法 LeetCode959. 由斜杠划分区域 在由 1 x 1 方格组成的 n x n 网格 grid 中,每个 1 x 1 方块由 ‘/’、‘’ 或空格构成。这些字符会将方块划分为一些共边的区域。 给定网格 grid 表示为一个字符串数组,返回 区域的数量 。 请注…

整理压缩JavaScript文件

你是不是会担心有专业人员通过你写的JavaScript语法来判断你的接口数据,今天就介绍一种可以封装你写的JavaScript的工具 环境:Windows10、node20.11.1、Vue/cli 5.0.8 uglify-js 是一个流行的 JavaScript 压缩工具,用于减少 JavaScript 文件…

angular入门基础教程(二)第一个angular组件

ng中的语法跟vue中是一样的插值语法,其实也是早期vue抄的ng的思路,使用{{variable}}形式,vue借鉴了ng和react,这个我们就不多了。 新建一个子组件 在项目根目录下面,执行 ng g component ./components/UserList这样…

Transformer——逐步详解架构和完整代码搭建

好久没更新博客,后面更新会勤一些。今天想聊一下Transformer,Transformer在NLP和CV领域都有着重要的价值,甚至可以看作是一个基础模型,这篇博客将通过详细代码深入解析Transformer模型总体架构图各个部分的的作用和搭建:论文链接&…

angular入门基础教程(九)依赖注入(DI)

依赖注入 Angular 中的依赖注入(DI)是框架最强大的特性之一。可以将依赖注入视为 Angular 在运行时为你的应用 提供所需资源的能力。依赖项可以是服务或其他资源。 使用服务的一种方式是作为与数据和 API 交互的方式。为了使服务可重用,应该…

晋升有望,5本易录用的计算机三四区潜力刊,通过率>50%,2个月超速接收,好发

今天模术狮给大家整理了5本让你晋升有望!易录用的计算机三区四区潜力刊,通过率>50%,2个月超速接收,好发! 1 DATA MINING AND KNOWLEDGE DISCOVERY 期刊简介:数据收集、存储和分发方面的进步产生…

Qt系统机制

Qt系统 Qt文件概述输入输出设备类QFileQFileInfoQt多线程Qt多线程常用API使用Qt多线程 线程安全互斥锁读写锁条件变量信号量 Qt网络QUdpSocketQNetworkDatagram设计一个UDP回显服务器QTcpServerQTcpSocketTcp版本的回显服务器HttpClient核心API Qt 音频Qt视频 Qt文件概述 ⽂件操…

阿里云服务器系统盘扩容后,宝塔面板不显示新容量的问题

1. 安装 growpart 扩展 yum install -y cloud-utils-growpart 2. 运行fdisk -l命令查看磁盘实际大小。 fdisk -l 用于:查看磁盘实际大小 说明:磁盘(/dev/vda)实际大小为:250 G。 3. 运行df -h命令查看磁盘分配大小。 df -h 用于:查看磁盘分配大小 4. 自适应分区扩容 g…

2024 Navicat Premium最新版简体中文版破解激活永久图文详细教程(亲测可用)

1.官网下载:下载地址 2.百度网盘下载:下载地址 3.未安装过的用户可直接跳过该步骤,如果已安装Navicat,记得先卸载干净,防止破解失效,卸载完成后执行补丁压缩包中的Navicat.bat脚本(一闪而过表示…

热门景区精准客流统计也能如此简单做到了

在热门景区,游客如织,如何实现精准的客流统计成为了景区管理者关注的重点。令人欣喜的是,如今这一难题已经有了简单而有效的解决方案。 一、景区应用客流统计的原因 首先,热门景区承载着巨大的游客流量,为了确保游客的…

如何使用git拉取gitee上面的项目/代码?(超简单)

一、下载git软件 下载地址:git官网地址 1.点击右边小电脑上的按钮下载 2.选择自己电脑对应的系统 3.基本都是默认,这里需要勾一下就ok 4.正在安装 2.使用git软件 1.如何打开git 找到你想要操作的文件夹,右击open git bash here就可以…

云计算实训16——关于web,http协议,https协议,apache,nginx的学习与认知

一、web基本概念和常识 1.Web Web 服务是动态的、可交互的、跨平台的和图形化的为⽤户提供的⼀种在互联⽹上浏览信息的服务。 2.web服务器(web server) 也称HTTP服务器(HTTP server),主要有 Nginx、Apache、Tomcat 等。…

【参会邀请】第四届区块链技术与信息安全国际会议(ICBCTIS 2024)诚邀相聚江城!

我们诚挚地邀请您参与第四届区块链技术与信息安全国际会议(ICBCTIS 2024)。本届会议将于2024年8月17日~19日在中国武汉召开。会议将围绕区块链技术与信息安全等相关研究领域,特邀国内外数位在此领域学术卓越的学者专家做相关致辞与报告&#…

一行Python代码实现神奇效果:创意编程实例

文末赠免费精品编程资料~~ 1. 基础中的魔法:打印艺术 目标:用一行代码打印出一个简单的图案,比如心形。 print( .join([**i for i in range(1, 6)] [ *4] [**i for i in range(5, 0, -1)]))解析: 我们利用列表推导式生成两部…

Halcon深度学习分类模型

1.Halcon20之后深度学习支持CPU训练模型,没有money买显卡的小伙伴有福了。但是缺点也很明显,就是训练速度超级慢,推理效果也没有GPU好,不过学习用足够。 2.分类模型是Halcon深度学习最简单的模型,可以用在物品分类&…