4. 基于OminiGraph的仿真逻辑控制¶
4.1 OmniGraph简介¶
OmniGraph 是 Isaac Sim 的低代码开发工作流,它可以把仿真的角色、环境和物理场景组织起来,构成一个"脚本"(低代码形式)来实现具体仿真的任务逻辑。OmniGraph分为Action Graph(动作图,通过事件驱动完成场景任务逻辑)和Push Graph(推送图,用于评估场景任务各方面参数)。本节重点介绍Action Graph,通过本节的学习,可以通过低代码开发工作流实现机器人的仿真逻辑控制。
可以通过02章节的小车抵达某一目标位置的案例,重点理解其中的OmniGraph部分,来帮助理解OmniGraph是什么。以下是打开案例相关步骤
通过文件浏览器打开这一案例的USD文件,具体路径为"/isaac-sim/isaacsim_assets/Assets/Isaac/4.5/Isaac/Samples/OmniGraph/nova_carter_drive_to_goal.usd"

在打开USD资产文件过程中,如遇到如
2.3.3 文件浏览器章节的黑屏情况,可使用Reload进行重新加载渲染画面
通过USD场景树查找这一案例的ActionGraph并打开

案例的OmniGraph如下图所示,可以看到由四部分组成:
写入目标位点
获取小车位置
路径规划
小车行走
通过这四部分,实现了小车(角色)在工厂厂房(物理场景)行驶至目标位点(角色在物理场景的运动)。

4.2 OmniGraph界面介绍¶
Isaac Sim启动时不会默认打开OmniGraph(ActionGraph和PushGraph),可以通过Window > Graph Editor > Action Graph和Window > Graph Editor > Gereric Graph分别打开Action Graph和Push Graph,如下所示。

OmniGraph界面由八部分组成,具体描述如下表及图片所示。
| 编号 | 选项 | 说明 |
|---|---|---|
| 1 | Action Graph编辑器 | 提供Action Graph的可视化脚本编辑功能 |
| 2 | Push Graph编辑器 | 提供Push Graph的可视化脚本编辑功能 |
| 3 | 创建Graph | 创建一个新的Graph |
| 4 | 编辑Graph | 编辑一个原有的Graph |
| 5 | 展开节点 | 展开所有节点(能看到节点的属性) |
| 6 | 最小化节点 | 最小化所有节点(仅能看到节点已连接的属性) |
| 7 | 关闭节点 | 关闭所有节点(不能看到节点的属性,仅能看到节点类型) |
| 8 | 编辑 | 打开可视化脚本设置面板 |
| 9 | 视图 | 调整编辑器布局 |
| 10 | 搜索 | 通过显示名称或类别搜索节点 |
| 11 | 节点组 | 节点类型分组 |
| 12、14 | 节点 | 可拖拽至编辑器的节点 |
| 13 | 脚本编辑器 | 可视化脚本编辑器 |
| 15 | 节点属性 | 节点属性表格 |

4.3 OmniGraph入门¶
以下将从零开始,构建OmniGraph实现"两个物品组合到一起运动"。通过这个步骤,可实现OmniGraph入门。
4.3.1 准备场景¶
添加立方体(cube)和圆锥体(cone)来准备场景。如下所示。
点击Create > Mesh > Cube和Create > Mesh > Cone分别创建一个立方体和一个圆锥体。

4.3.2 设计OmniGraph¶
此处使用OmniGraph的Action Graph来完成特定事件的逻辑实现。
创建一个Action Graph
点击Window > Graph Editor > Action Graph打开Action Graph编辑器面板。

创建ActionGraph
在Action Graph编辑器中,点击"New Action Graph",这将在"defaultPrim"下创建一个空白的ActionGraph。

设置立方体的刚体属性
在进行下面的Action Graph配置前,我们还需要对立方体配置刚体属性,刚体属性定义了物体在物理仿真中的基本行为,确保其遵循牛顿力学规律。未设置刚体属性的几何体仅是一个
静态视觉模型,无法参与物理仿真计算。
为什么需要设置立方体的刚体属性?
因为Isaac Sim 使用 PhysX 或 OmniPhysics 作为物理引擎,这些引擎要求显式声明哪些物体参与动力学计算。未标记为刚体的物体默认被视为 静态碰撞体(Static Collider) 或 纯视觉对象。
同时默认情况下,立方体的视觉模型并不会具有物理碰撞体与碰撞网络,只有在立方体被设置为刚体属性时,立方体才能响应重力、碰撞和外力,实现逼真的物理仿真效果
立方体设置刚体属性整体步骤如下:
a. 选择要设置刚体的立方体
b. 依次选择:Property → add → Physics → Rigid Body with Colliders Preset
立方体刚体属性设置操作步骤示例如下:

为立方体设置刚体属性过后,能够在看到立方体的外围将会有一层碰撞网络,如下图的正方体,而没有设置刚体属性,则将不会显示碰撞网络,如下图的圆锥体

正方体与圆锥体都设置好刚体属性后效果如下:

创建正方体相关的"Read Prim Attribute"节点
将正方体(Cube)的Prim从USD场景树拖放到ActionGraph编辑器面板,在弹出对话框中,选择 Read Attribute,这将创建一个读取Prim属性节点,该节点可以从正方体(Cube)Prim中读取数据。

"Read Prim Attribute"节点属性配置
- 在
Action Graph栏选择"Read Prim Attribute"节点 - 在属性面板中将"Attribute Name"属性设置为"xformOp:translate",节点将读取正方体位置信息。

- 在
创建圆锥体相关的"Read Prim Attribute"节点
同样地,将圆锥体的Prim从USD场景树拖放到ActionGraph编辑器面板,在弹出对话框中,选择 Write Attribute,这将创建一个写入Prim属性节点,设置该节点"Attribute Name"属性为"xformOp:translate",节点将写入圆锥体位置信息。

新增常量节点用于设置立方体和圆锥体的距离
在Action Graph编辑器面板的搜索框中,键入“Constant Point3d”,将Constant Point3d节点拖放到图形编辑器中,且设置其Input属性值为(0,0,1),后续使立方体和圆锥体Z轴方向距离1m。

新增相加节点,使"Constant Point3d"常量值与立方体位置信息相加
新增"ADD"节点后,把"Constant Point3d"节点的Value连接至"ADD"节点的A输入值,把立方体的"Read Prim Attribute"连接至"ADD"节点的B输入值,使其两个值相加。

把相加后的值赋予圆锥体位置信息
把"ADD"节点的Sum值连接至圆锥体的"Read Prim Attribute"节点的Value值。

实现每一个时间步触发相加计算
新增"On Tick"节点,且连接"Tick"属性至"Write Prim Attribute"节点的"Exec In"属性,"On Tick"节点每隔一帧通过其Tick执行端口触发一个执行信号,使立方体的位置信息和常量信息相加且写入圆锥体位置信息。

- 开始播放,移动立方体,查看效果

4.4 OmniGraph实战案例¶
经过以上操作,相信你已经对于OmniGraph的基本操作已经熟悉,本部分将通过一个实际案例让你掌握使用OmniGraph实现机器人的简单控制。本案例使用Jetbot机器人及Action Graph,实现Jetbot前进任务。
4.4.1 场景搭建¶
在一个新的场景,通过"Create > Physics > Ground Plane"创建地面。

- 导入Jetbot机器人模型,将其放置地面。
注:Jetbot机器人模型路径保存至"/isaac-sim/isaacsim-assets/Assets/Isaac/4.5/Isaac/Robots/Jetbot/jetbot.usd"。

4.4.2 设计Action Graph¶
通过"Windows > Graph Editors > Action Graph"打开Action Graph编辑器。
新建Action Graph且搜索"controller"节点,将"Differential Controller"和"Articulation Controller"拖拽Action Graph编辑器内。
Differential Controller是差速控制器,可用于控制轮式机器人底盘运动,一般设置线速度和角速度;Articulation Controller是机器人运动的执行器,接受相关运动指令使机器人特定关节实现运动。

设置Articulation Controller的targetPrim属性为Jetbot的Prim路径,使其作用于Jetbot。

设置Differential Controller的wheelDistance(轮距)属性为0.1125、wheelRadius(轮子半径)属性为0.03、maxAngularSpeed(最大角速度)属性为0.2。

- 设置Acticulation Controller的Joint Names属性,使其作用于targetPrim的特定关节。
由于Jetbot底盘有"left_wheel_joint"和"right_wheel_joint"两个关节,而Articulation Controller仅有"jointNames"一个参数,因此需要将这两个关节名称通过数组的形式组织起来传入Articulation Controller。

搜索"token",拖拽两个"Constant Token"节点至Action Graph编辑器。

将这两个"Constant Token"节点的Inputs属性分别设置为"left_wheel_joint"和"right_wheel_joint"(分别对应Jetbot左右轮两个关节)

搜索"make array",将"Make Array"节点拖拽至Action Graph编辑器内

增加"Make Array"节点的Inputs属性,将"Array Type"设置为"token[]"。把两个"Constant Token"节点分别连接至"Make Array"节点。

将"Make Array"节点的Array输出值连接至"Articulation Controller"的"Joint Names"属性,使"Articulation Controller"控制Jetbot左右轮两个关节。

将"Differential Controller"的"Velocity Command"输出值输入至"Articulation Controller"的"Velocity Command"属性值,使Jetbot底盘两个关节拥有速度。

搜索"playback",将"On Playback Tick"节点拖拽至Action Graph编辑器,且将"On Playback Tick"节点的"Tick"输出赋予"Differential Controller"和"Articulation Controller"的"Exec In"属性值。当Isaac Sim开始播放时,"Diffential Controller"和"Articulation Controller"实时计算且应用至特定关节。

点击"Play"按钮,开启仿真模拟,调整"Differential Controller"的"Desired Angular Velocity"(角速度)属性和"Desired Linear Velocity"(线速度)属性,观察Jetbot运动变化。

以下是Jetbot底盘运动的Action Graph。

至此,你已经完成通过Action Graph控制轮式机器人的任务。我们简单梳理一下其中的核心,"Differential Controller"差速控制器用于发布小车的控制指令,"Articulation Controller"关节控制器用于执行小车的控制指令。"On Playback Tick"用于在仿真模拟时发出执行事件,让差速控制器和关节控制器进行实时计算。"Constant Token"和"Make Array"用于处理关节控制器的输入。通过这六个节点,Jetbot在仿真模拟时获取差速控制器的指令进行运动。
4.5 OmniGraph 节点介绍¶
Nvidia官方为OmniGraph构建了大量的节点,你可以利用其进行构建机器人任务逻辑。由于节点数量较多,以下表格将节点划分为不同类型,当构建机器人任务逻辑时查阅表格以及官方文档选择对应节点。
注:OmniGraph节点文档链接为:https://docs.omniverse.nvidia.com/extensions/latest/ext_omnigraph/node-library/node-library.html#
| 大类 | 子类 | 典型节点示例 |
|---|---|---|
| 数据操作 | Bundle处理 | Bundle Nodes, Bundle Constructor, Extract Bundle |
| 属性操作 | Copy Attributes, Insert Attribute, Rename Attributes | |
| 数组处理 | Array Fill, Array Resize, Make Array | |
| 几何处理 | 几何分析 | Length Along Curve, Bounding Box 3D |
| 几何生成 | Create Tube Topology, Curve Tube Positions | |
| 变形器 | Bend Deformer, Sine Deformer, Skin Deformer | |
| 物理模拟 | 物理场 | Force Field系列(Wind/Spherical/Drag等) |
| 粒子系统 | ParticleSystem, Emitter, VortexField | |
| 刚体模拟 | PhysxApplyRigidBody, PhysxSolver | |
| 流程控制 | 事件触发 | On Frame/Keyboard/Mouse系列 |
| 逻辑控制 | For Loop, Multigate, Flip Flop | |
| 状态管理 | Counter, Delay, Once | |
| 数学运算 | 基础运算 | Add/Multiply/Clamp系列 |
| 向量矩阵 | Dot Product, Matrix Multiply, Make Transformation Matrix | |
| 随机生成 | Random Boolean, Random Gaussian, Random Unit Vector | |
| 场景交互 | 摄像机控制 | Get Active Camera, Set Camera Position |
| 对象操作 | Get Prim Path, Set Xform, Translate To Target | |
| 场景生成 | Scatter系列节点,RandomTransform | |
| 材质与渲染 | 材质处理 | Assign Material, Material Randomizer |
| 渲染控制 | Render Preprocess Entry, Set Viewport Mode | |
| 传感器与输入 | 设备输入 | Read Gamepad/Keyboard/Mouse State |
| 传感器处理 | LidarAccumulator, Radar系列节点 | |
| 工具与调试 | 调试工具 | Debug Draw Lines/Points |
| 性能分析 | Timer, Frame Gate | |
| 示例与教程 | 学习案例 | 所有Tutorial Nodes系列,Example Node系列 |