本篇博客我们对前期的笔记进行小结,并以一个实际的例子为目标进行介绍。具体来说,结合前面这篇博客提到的搭建简易机器人的知识、这篇博客提到的利用键盘操控机器人的知识以及这篇博客提到的传感器数据和位姿真值的获取与保存,首先尝试自己搭建一个传感器小车(包含双目+IMU),然后通过Action Graph控制小车的移动,最后利用ROS进行数据的采集与保存。
1. 传感器小车搭建
1.1 应包含的传感器
因为我们想为SLAM服务,所以至少应该包含一个双目相机和一个IMU。双目相机同时采集左右目数据,IMU则记录一些运动观测量。对于相机传感器的插入,直接Create->Camera即可,对于IMU,则是Create->Isaac-Sensors->IMU Sensor。关于相机和IMU插入的具体注意事项(比如IMU必须放在具有物理属性的实体下等),参考对应博客1和2,此处不再赘述。
另外需要补充一点的是,对于相机和IMU传感器的相关设置,可以在对应的属性面板中进行。比如,对于相机,如下图,可以设置它的焦距等属性。
1.2 平台设计
这里,我们仿照Isaac Sim提供的Jetbot小车,搭建一个包含两个轮子的小车,同时在小车的前部有一个小球,以支撑小车本体,如下图所示。 此外。为了更加直观,也增加了相机的样子和车载设备,如下所示。 这样,我们就能初步搭建好一个小车的样子。
1.3 组装与层级关系
此时的小车是散装的,一运行各个部件就会“瓦解”,所以我们需要对各部分进行组装。而组装关系又与各部分的层级关系密切关联,所以放在一起说。但其实自己对这块理解的也不是很深入,只能说搭建的刚刚好能用,层级关系可能并不优美。欢迎探讨交流。
首先,我们可以考虑将小车的本体相关部分组装在一起(不包含左右两个轮子)。而根据前面的知识,将多个部分组装在一起可以通过将各个部分放到同一个Xform下或者Joint实现。所以,新建一个body Xform,将各部分放进来,如下。 这样,当我们移动整个body的时候,各部分就会跟着一起动了。当然,如果细心的话会发现,这里的粉色的camera_body是独立与body的。这个原因是camera_body下面,我们放置了IMU传感器。而在实际使用中发现,假如把camera_body放到body下面,运行的时候就会报Prim is not a rigid body的错误。这个错误会导致之后IMU的数据无法发布(针对这个问题,之后又试了一下,新建一个Cube然后添加IMU传感器,然后这个Cube放到Xform下面,倒不会报错。所以怀疑可能还是小车哪里设置有问题,但目前没找到)。但如果不把camera_body放到body下面,它就不会和其它部分一起动。为了解决这个问题,另一个选择是,利用Fixed Joint把body和camera_body连接到一起,如下。 所以你可以看到,camera_body下面还有个FixedJoint。这样,小车的身体部分就搭建完成了。然后就是要拼接轮子。根据前面的笔记,这也很简单,通过RevoluteJoint就可以实现。所以我们分别设置左右两个轮子即可,如下。 可以看到,这个RevoluteJoint连接的是body和left_wheel。最后,为了能利用Articulation Controller控制整个小车,我们需要把整个小车都放到一个Xform里。这里我们起了个名字,叫our_car。然后给这个Xform添加Articulation Root的物理属性即可(这里需要注意的是根据我搭建时的情况,Articulation Root好像只能控制两个RevoluteJoint,如果有多个似乎会报错)。这样,这个小车就搭建完成了。
1.4 一些细节
事实上,上面提到的步骤里,还有很多琐碎的细节。比如给各个部分添加物理属性、Xform的层级关系、Joint的连接等。这些内容只有自己亲自从零搭建才会发现问题,很多东西并不太好直接描述。事实上,为了搭建这个小车,也花了很多精力。如果遇到问题,一个比较好的解决办法是看一看Isaac Sim自带的一些机器人是怎么搭建的,都设置了什么属性,照葫芦画瓢。在搭建这个小车的时候,Jetbot是作为重点参考,但它是单目,也没有IMU传感器,所以又融合了之前笔记的知识。另外需要说明的是,从Isaac Assets里拖拽添加的Jetbot其实并非完整的文件。换句话说,为了简化,有些东西是隐藏的。这种插入的机器人,在它的根Xform上一般会有个小箭头的图标,如下所示。 如果我们选中根节点,在它的属性面板往下翻,就能看到References这个属性,这里有个Asset Path,如上图所示。可以看到,这个就是原始的模型文件地址,在网上。所以如果我们想看真正的源码,可以复制这个地址,然后下载该文件即可。比如Jetbot,真正的源码模型文件有30MB左右,里面包含了所有的模块和配置信息。
2. 构建Action Graph控制小车
因为我们搭建小车的时候就是按照比较标准的流程来的,所以,这里利用Action Graph控制小车和前面这篇博客里介绍的是相同的,这里不再赘述。核心就是Differential Controller和Articulation Controller,如下图。 可以看到,整体的框架和之前是一致的。第一步都是读取键盘的按键状态,然后根据不同状态计算不同速度,然后通过Differential Controller根据输入的速度、轮子的半径等参数生成速度指令,最后把这个速度指令传给Articulation Controller,完成对小车的控制。
3. 构建Action Graph发布数据
根据之前的介绍,可以利用ROS接口实现对于数据的发布,包括双目影像数据、IMU数据以及位姿真值数据。这些都已经介绍过了,此处不再赘述。搭建好的Action Graph如下。 各个部分的意义是比较明确的。对于影像数据,核心是ROS1 Camera Helper这个节点;对于IMU数据,核心是ROS1 Publish Imu节点;对于位姿真值,核心是Isaac Compute Odometry Node和ROS1 Publish Odometry。如果有不清楚的地方,可以参考以前博客对应部分:影像数据发布、IMU数据发布、位姿真值发布。
4. 实际运行测试
运行仿真环境,尝试用键盘控制小车,即可以看到小车开始运动,并且双目相机的内容也发生对应变化。 然后,我们可以启动ROS,可以进一步看到发布出来的ROS Topic,如下。包括IMU、双目数据以及双目影像。 如果我们对数据进行录制,保存成ROS Bag以后,也可以进一步查看相关信息。 以上仿真环境在Isaac Sim 2022.1.1版本测试通过。至此,我们便完成了在上一篇博客最后提出的目标。有没有什么问题呢?答案是肯定的。如果你细心的话会发现,这里IMU的帧率基本和相机相同,我们也从来没有显式地设置过IMU帧率。要解决这个问题,需要涉及其它方面知识。简单来说就是单纯使用这种图形化编辑和Action Graph的方式难以实现对帧率的控制,需要用到Isaac Sim提供的SDK接口来指定,这会在之后的笔记中进一步介绍。
本文作者原创,未经许可不得转载,谢谢配合