NVIDIA Omniverse和Isaac Sim笔记6:双目和IMU传感器数据的获取与保存

Dec 31,2022   6247 words   23 min

Tags: SLAM

在之前的这篇笔记中,我们介绍了如何将采集到的影像数据、机器人位姿真值以ROS Topic的形式发布出来,并通过ROS Bag工具进行保存。 这篇笔记中我们进一步研究两个内容:一个是在上次的发布单目影像的基础上尝试发布双目影像,另一个是学习如何在Isaac Sim中使用IMU传感器,并将相关数据发布给ROS。

1.双目相机的数据采集与保存

双目相机的数据采集和保存其实和单目“一模一样”,只是把单个相机的流程再重复一遍,下面具体讲解。

1.1 双目相机搭建

首先,我们新建一个立方体,以此作为双目相机的本体,然后,分别插入两个相机,将它们放到立方体“里面”,这样相机就随着立方体一起运动了,如下。 如何实现相机和立方体的绑定呢?一个非常简单的办法就是用Xform。具体而言就是将立方体和两个相机都放在同一个Xfrom下。当然,为了便于辨识,我们可以将两个相机改个名字。这样,当我们移动顶层的Xfrom的时候,立方体和相机就会一起动了。这样,我们的双目相机就搭建完成了。当然,你可能觉得这个双目相机有点丑。尽管确实如此,但需要说明的是,即使是再高级、好看的相机,本质上都是通过这种方式构建的。之所以让你觉得好看,只是因为做了很多外观和Mesh。举个例子,比如Jetbot里的相机,可以看到,其实就是由一堆材质和一个Camera对象构成的。 另外,为了场景中有一些内容,更好看一些,随便在场景中插入一些物体,我们就能看到双目的影像了,如下。 之后我们就可以构造Action Graph了。

1.2 Action Graph搭建

Action Graph的构造其实和这篇笔记介绍的单目相机是一样的,唯一的不同是,这里我们对两个相机分别构造两个pipeline。构造好的Action Graph如下图所示。 在这里,我们其实对之前的Action Graph进行了一定精简,把一些常量给直接写到了相关节点里,比如Viewport的ID、Set Active Camera的Camera Path、Camera Helper中的Topic Name属性。另外,不清楚是不是版本更新导致的API变化还是其它原因。Get Prim Path的输出现在没有办法连接到Set Active Camera的Camera Path输出端口。在之前2022.1.1版本里是可以的(比如这篇笔记里的介绍),但现在2022.2.0就会提示Get Prim Path的输出与Set Active Camera的输入类型不符。所以如果你也遇到这个问题,可以考虑像我一样,直接把相关变量写到属性里。

1.3 实际测试

在构造Action Graph以后,我们就可以运行仿真环境了。如下图所示,我们利用rqt_image_view工具可视化Isaac Sim发布的左右影像Topic。通过移动我们构造的“双目相机”,可以看到,输出的影像Topic是在同步变化的。 这样,我们便实际完成了对双目相机的仿真。

1.4 数据保存

最后,我们当然可以利用ROS Bag工具将Isaac Sim发布的双目影像录下来,然后可以利用rqt工具查看相关信息,如下。 可以看到,总体而言,左右相机的Topic是时间对齐的。

2.Isaac Sim中的IMU基本介绍

Isaac Sim给我们预置好了很多机器人相关的专用传感器,很好用。这些传感器都是通过叫做Isaac Sensor Extension实现的。在Isaac Sim中,可以点击菜单栏Create->Isaac->Sensors就可以看到了,如下图所示。 另外简单说一下,我们之前在插入Camera的时候,其实直接Create->Camera就可以了。换句话说,可以看出,相机是非常基础的传感器,在整个Omniverse体系里都支持。但是IMU等与机器人相关的更专业的传感器,则是由Isaac提供支持。比如,你可以打开Omniverse Create,看看Create菜单里是否有没有其它传感器。

另外,IMU传感器是和之前提到的Camera是不同的,它属于一种Physics Based Sensors。根据这个官方文档的描述,Isaac Sim中的Physics Based Sensors都是基于CPU物理模拟,这种模拟只有在渲染完成以后才会生效。换句话说,在我们编辑环境的时候,这些传感器是不会实时工作,只有在我们运行场景以后,相关数据才会被生成。

最后,官方也提供了一个IMU Sensor的示例Demo。我们可以在菜单栏中点击Isaac Samples->Sensors->IMU直接加载运行,如下图所示。 运行以后,效果如下所示。 通过这个例子,我们可以简单了解IMU传感器是如何添加、使用的。

3.IMU数据获取与发布

在上面的部分,我们简单了解了Isaac中的IMU传感器。下一步我们简单介绍如何使用IMU,包括如何构建Action Graph读取IMU的数据、把IMU数据发布给ROS等。本部分主要参考这篇官方文档,有改动。

3.1 IMU传感器添加

首先,为了视觉上看起来更像是个传感器,我们可以先添加一个立方体,然后选中它,再添加的IMU,这样新添加的IMU就在我们这个立方体的层级下面了,就可以实现和立方体一起运动的效果,完成效果如下所示。 看起来一切正常,没有什么问题。但如果你仔细观察Isaac Sim的控制台输出,会看到红色的这么一句错误“Failed to create imu sensor, parent is not found or invalid”,如上图所示。提示我们IMU没有创建成功,因为没有父对象或者父对象无效。你可能会很纳闷,明明不是有立方体父对象吗?为什么还不成功。这就是我们需要注意的一个细节。IMU作为Isaac Sim中的一种“物理传感器”,必须依附于具有物理属性的对象上。如果我们直接新建了一个Cube,默认是没有物理属性的。因此,对它添加IMU,就会报上面的错误。定位了问题,解决它也就很简单了,那就是按照之前这篇笔记介绍的,在属性面板中点击Add->Physics,对立方体添加物理属性即可,比如选择普通的Rigid Body With Colliders Preset。完成之后,再次尝试添加IMU,就不再会报错了。

添加好IMU传感器以后,我们需要获取它的观测数据才有意义,不然我们也没必要大费周章地研究IMU。这里我们提供两种方式来获取IMU数据,一种是将IMU观测直接输出到Isaac的控制台中,另一种则是将IMU观测发布到ROS。但事实上,不管是哪一种,真正获取IMU观测数据的节点都是相同的,那就是Isaac Read IMU Node,只是最后的输出节点不同,一个是通过Print Text将结果输出到控制台,一个是通过ROS1 Publish IMU发布。下面分别介绍。

3.2 输出观测到Isaac控制台
3.2.1 Action Graph搭建

读取IMU观测的核心是Read IMU Node节点,所以我们在Action Graph中先添加一个,如下所示。 从它的输入、输出可以看出,它肯定需要一个On Playback Tick节点作为触发信号,并且要指定IMU的全称路径。它的输出包含角速度、线加速度和相对朝向四元素。在右边的属性面板中可以看到,它们分别是以vector和quaternion表示的。所以读取数据非常简单,添加一个On Playback Tick节点,并指定IMU路径即可(注意是input:imuPrim属性,不是Relationship下面的IMU Prim。如果只修改Relationship下面的IMU Prim,系统会报错,如果修改了input:imuPrim属性,则Relationship下面的IMU Prim也自动对应修改了),如下。 如果你运行仿真环境,这就可以正常工作了,只是说我们没有把数据展示出来。所以我们可以利用Print Text节点展示这些数据,如下所示。 可以看到,它需要一个触发信号,而我们已经添加了On Playback Tick节点。这里稍微需要注意的是,Print Text既然叫这个名字,它只能接收String类型的输入,而Read IMU Node节点前面说了输出的是vector和quaternion。不过没关系,我们可以用To String节点将输出结果转换一下就可以使用了,这里我们输出角速度。 这样构造好的Action Graph如上图所示。

3.2.2 实际测试

我们运行仿真环境,然后再切换到Isaac Sim的Console,可以看到,控制台中实时输出了IMU记录的角速度观测。 当然,这里面有个潜在的小细节。如果你看不到Console中有任何信息输出,那么很有可能是输出信息的Level不对。默认情况下Print Text的信息是Info级别,而在默认情况下Console是显示Warning和Error级别的信息。所以如果遇到这个问题,把Info级别的输出也显示就可以了(当然你也可以修改Print Text的级别为Warning或Error),并不是我们搭建传感器或者构造Action Graph的问题。至此,我们完成了对IMU数据的读取并且输出到了控制台中。

3.3 发布观测到ROS
3.3.1 Action Graph搭建

和前面类似的,我们获取IMU数据的节点还是Read IMU Node,不同之处在于,我们不再使用Print Text,而是ROS1 Publish Imu,如下。 可以看到,类似的,它也需要一个输入触发信号,然后就是要发布的角速度、线加速度、朝向,以及Topic Name、Timestamp等信息。这其实和我们上篇笔记中提到的ROS Camera Helper是类似的。所以,我们仿照之前的做法,按照它的要求,构建Action Graph,如下所示。 这样就完成了Action Graph的构建。

3.3.2 实际测试

打开终端,运行roscore,然后启动仿真环境,通过rqt工具就可以看到发布出来的Topic信息了。 这样,我们便完成了对IMU的数据读取以及发布到ROS的目标。

3.3.3 IMU观测数据保存

前面既然我们已经实现了将观测数据发布到ROS,那么对于数据保存就比较简单了,利用ROS Bag工具录制发布的Topic即可。可以直接参考之前的笔记,这里不再赘述。

4.进阶实例1:单目+IMU的采集与保存

在掌握了以上的基础知识以后,我们就可以灵活应用了,比如我们搭建一个简易的相机+IMU传感器,并输出、保存数据。

4.1 传感器搭建

如下图所示,我们以一个圆柱当作相机,立方体作为本体。 这样我们就完成了一个非常简易的单目+IMU传感器。这里有几点需要注意,首先是添加的圆柱,我们需要按照之前笔记说的,给它添加物理属性。第二是,我们要把圆柱和立方体绑定在一起,不然我们是“散装的”。如何绑定也非常简单,与之前这篇笔记介绍的类似,选中圆柱体和立方体,右键,然后选择Create->Physics->Joint,这里因为我们要固联,所以选择Fixed Joint即可。这样,当我们再次运行仿真环境,就会发现,立方体以及它里面的IMU、圆柱体以及它里面的相机就同时运动了,如下所示。

4.2 Action Graph构建

分别结合上次笔记影像发布的内容和这篇笔记IMU观测发布的内容,很快可以搭建好如下Action Graph。 这里,我们用同一个On Playback Tick节点触发了两条pipeline,一条是IMU数据读取与发布,一条是相机数据影像读取与发布。由于是同一信号源,所以这里IMU和影像的数据帧率是相同的。

4.3 实际测试

如下所示,运行仿真环境,就可以看到,影像和IMU数据同步发布了。

4.4 数据保存

最后,我们当然可以利用ROS Bag工具对发布的影像和IMU Topic进行录制,比如下面是录制的一小段数据。

5.进阶实例2:双目+IMU的采集与保存

有了实例1的基础,双目+IMU的例子就会变得简单一些。只是在上面的基础上再增加一个相机数据获取与发布的pipeline即可。

5.1 传感器搭建

如下图所示,我们增加了一个圆柱体作为另一个相机(可以直接选择已有的相机,选择Duplicate即可)。当然了,为了区分,可以把相关组件重命名一下。 这里也有一些稍微需要讲解的内容,就是两个圆柱体相机和立方体绑定的事情。前面说了,我们是通过Fixed Joint固联相机和立方体。而Fixed Joint的对象只能有两个,所以我们不能同时选中两个相机和立方体,把他们通过Fixed Joint固联。所以解决办法就是分别选择左相机和立方体,然后右相机和立方体。另外,如果我们使用Duplicate方式,那么记得重新编辑一下Fixed Joint,不然新相机的相对位置关系会错位。

5.2 Action Graph构建

有了上面的基础,双目相机的影像发布就比较简单了,构建的Action Graph如下所示。

5.3 实际测试

运行仿真环境,可以看到如下效果。 正如同前面在这篇笔记中说的关于Viewport的知识,如果出现没有对应Topic的发布,那可能是因为有一些已有的Viewport被其它数据占用,可以把Isaac Sim关了重开就好了。

5.4 数据保存

最后,利用ROS Bag工具,即可实现数据的录制。

6.进阶实例3:双目+IMU+真值保存

有了上面实例2的基础,再配合我们之前这篇笔记提到的保存位姿真值的知识,我们还可以构建出更复杂的功能。构造的Action Graph如下。 这里我们发布的是Cube的位姿真值。最后我们录制数据,录好的Bag包信息如下。 查看Topic帧率如下所示。 至此,我们便完成了对双目、IMU相关数据的采集和录制,本篇笔记到此结束。在下一篇博客中,我们将以先前的笔记为基础,尝试搭建出自己可以控制的机器人小车,小车搭配双目+IMU传感器,发布数据并且通过ROS保存。

7.参考资料

  • [1] https://docs.omniverse.nvidia.com/app_isaacsim/app_isaacsim/tutorial_advanced_omnigraph_imu_sensor.html
  • [2] https://docs.omniverse.nvidia.com/app_isaacsim/app_isaacsim/isaac_sim_sensors_physics_based_imu.html
  • [3] https://docs.omniverse.nvidia.com/app_isaacsim/app_isaacsim/ext_omni_isaac_sensor.html#isaac-sim-sensors

本文作者原创,未经许可不得转载,谢谢配合

返回顶部