在Unity中通过C#使用Realsense T265

  • Post author:
  • Post category:其他

最近毕设在做这个,真的是好坑啊好坑啊好坑啊好坑啊好坑啊!!!!

Realsense的SDK安装就不说了,入正题

附一个SDK链接,有需要的自取:

链接:https://pan.baidu.com/s/125rL05NH84q0kHX5ytpMRw 
提取码:tqrn

一般来说Realsense是用C++写的,比如intel官方的例程就是这样的:

https://dev.intelrealsense.com/docs/codeguanwangshan-samples

不可否认C++确实有它的优势,快啊!但是我C++玩不熟练啊!!!项目又得用Unity和Leapmotion,JS Python也拜拜了,唯一能打通这仨玩意的就只有C#了,所以只能另辟蹊径。

官网上只有C++的例程和文档,不过intel也提供了C#的wrapper的,但是放在了Github上:

https://github.com/IntelRealSense/librealsense/tree/development/wrappers/csharp

Intel也有针对Unity的Wrapper:

https://github.com/IntelRealSense/librealsense/tree/development/wrappers/unity

我是用的unity这个unitypackage,导入之后能看到Assets/RealSenes SDK 2.0/Scence有个StartHere,可以先跑一下,看看正不正常。如果是T265的话应该只有一个SLAM(Pose),Play之后拿着RS动就能看到活动的轨迹了。

如果到这里能正常跑通,恭喜你基本上走通Intel写好的文档里的正确的部分了,接下来每一步都是一个坑。

首先Intel的Unity Wrapper里是没给例程的,所以你理所当然的会去C# Wrapper里看例程对不对?但是C#Wrapper里的路是走不通的。

Intel给的C#例程根本就跑不通啊好不好啊!!!我在Viewer里是正常获取RS信息的,但是C#里就不行,排查了一遍是因为没办法生成Pipeline。没办法生成Pipeline是因为Device List是空的,但是它真的就在那啊不然为啥Viewer是正常的呢?如果是C#环境没配置好,为啥Unity里的例程就正常运行了呢?经过接下来的研究,证明Intel的C#Wrapper页面里的代码只是用C#语法把C++的代码重新写了一遍,跟它提供的实际代码不一样。

在我们跑通的SLAM(Pose)中,使用了RS Device.cs获取RS返回的帧序列,然后将其中的Pose帧传递给RSPoseTransformer.cs。在后者中我们可以看到它要求提供一个Source,这个Source就是RS Device.cs。那么RS Device实际上就相当于Leapmotion Provider这样一个角色,先是通过

    public RsConfiguration DeviceConfiguration = new RsConfiguration
    {
        mode = RsConfiguration.Mode.Live,
        RequestedSerialNumber = string.Empty,
        Profiles = new RsVideoStreamRequest[] {
            new RsVideoStreamRequest {Stream = Stream.Depth, StreamIndex = -1, Width = 640, Height = 480, Format = Format.Z16 , Framerate = 30 },
            new RsVideoStreamRequest {Stream = Stream.Infrared, StreamIndex = -1, Width = 640, Height = 480, Format = Format.Y8 , Framerate = 30 },
            new RsVideoStreamRequest {Stream = Stream.Color, StreamIndex = -1, Width = 640, Height = 480, Format = Format.Rgb8 , Framerate = 30 }
        }
    };

实例化一个配置文件,然后通过

var cfg = DeviceConfiguration.ToPipelineConfig()

转换为Config类型的文件,传递给pipeline

ActiveProfile = m_pipeline.Start(cfg);

接着涉及到多线程的一些操作(你没看错,RS在Unity中是可选多线程的,但是这个多线程也仅涉及到stack frame的过程,凡是涉及MonoBehaviour的依然必须在Unity主线程中完成)就略过了,因为关系不大。总的来数RS Device.cs干的活就是从Device List中找到RS,启动它,然后创建帧序列FrameSet frame。

在第二个cs脚本中获取这个frame,然后提取其中包含的pose等等信息。期间还涉及到一个RS D435i和T265的内坐标向Unity的世界坐标转化的过程,具体的可以在这里找到

https://realsense.intel.com/how-to-getting-imu-data-from-d435i-and-t265/

当你学会使用这两个脚本的时候就可以自己写程序调用RS了。当你美滋滋地写好了程序,Play也正常,终于到Build

&Release这一步了,一运行,人傻了,RS跟死了一样一点动静都没有。再回Unity引擎,一点Play,又是正常的,在重新Build,运行,RS还是跟死了一样。Intel文档里一个字也没提这种情况,Stack Overflow和Unity Community什么的也没有,CSDN就更别提了,搜遍全网也只有这么一个帖子提到了这件事:

https://answers.unity.com/answers/1720942/view.html#

但是一看过去半年了也没人回复,心里凉了一半(帖子里2楼就是我,那时候还没找到解决方法)

后来鬼使神差,用x64架构Build了一下,化腐朽为神奇了,成功运行了。仔细一想,也对,开发RS的人如果有谁用的还不是64位,那也是够搞笑的了,不过好歹Realsense只支持64位这回事你Intel该提一句吧!

PS,同时使用Leapmotion和Realsense一定要用USB3.0以上的协议,USB2.0带宽不足以同时运行这两个,这俩会打架。通过无数次观察,Leapmotion似乎比较能打,能正常工作,Realsense一般是死机的那个。

 


版权声明:本文为ace0perfect原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。