• Tango 主要Unity API


    这两年虚拟现实VR和增强现实AR简直火的不要不要的,众多巨头都在发力,Google也推出了自己的AR技术解决方案,因为目前介绍Tango的中文资料还比较少,所以本人结合官网文档和自己的理解写了本文,如有错漏请不吝赐教。

    一、简介

    1. Tango是什么,可以用来干什么?

    Tango是Google的一个AR增强现实项目,配合其独特的移动设备和SDK可以方便的在应用中使用AR技术。

    2. Tango室内定位为什么有很高的精确度?

    众所周知,传统的定位技术(GPS\WIFI等)在室内定位上精度很低,那么Tango是怎么实现室内定位的呢?

    Tango采用的是“参照定位”,即相对于“初始位置”的一种定位方式,不涉及到卫星定位。它根据硬件设备的传感器,比如重力传感器、IMU陀螺仪等,获取移动设备相对于初始位置的“位移”和“旋转角度”,自己构建了一个“参照坐标系”,因此有较高的准确度。

    当然,还有其他一些软件技术手段,比如通过区域学习修正偏差等。

    3. 几个重要的概念

    Tango中如下3个概念,其实也算是3个功能模块。开发者通过设置TangoConfig对象的相应字段来选择开启哪些功能。

    a. 移动追踪(motion tracking)

    移动追踪指的是,Tango会记录追踪移动设备的在3D空间中的位置,位置数据包括地点和超像旋转角度等、实时报告给应用。

    b. 区域学习(Area Leaning)

    移动追踪只会反馈移动设备当前的坐标信息、对于设备“看”到的东西没有任何记忆,区域学习使移动设备能够看到和记住物理空间的关键视觉特征,比如边缘,角落等。

    区域学习会把看到的保存起来,下次再次“看”到的时候会进行匹配,利用这些数据修正误差(漂移修正),使得轨迹追踪、定位更加准确。

    c. 深度感知(Depth Perception)

    深度感知给予设备“明白”物体之间的距离,这是通过独特的硬件设备技术实现的,比如“结构光”、“光速飞行时间TOF”和Stereo立体测量

    4. Tango的简单使用方式

    在Android中,Tango是一个后台Sevice,负责AR工作。我们使用Tango的方式就是启动这个Service,与其进行交互。

    Tango主要有如下两个对象:

    private Tango mTango; //Tnago对象
    private TangoConfig mConfig;  //配置

    按照需求对TangoConfig类进行配置,下面代码配置了移动追踪和自动恢复

     private TangoConfig setupTangoConfig(Tango tango) {
    
            TangoConfig config = tango.getConfig(TangoConfig.CONFIG_TYPE_DEFAULT);
            //开启移动追踪功能
            config.putBoolean(TangoConfig.KEY_BOOLEAN_MOTIONTRACKING, true);
    
            // 自动恢复
            config.putBoolean(TangoConfig.KEY_BOOLEAN_AUTORECOVERY, true);
            return config;
        }

    初始化Tango,调用它的connect()方法。

     @Override
        protected void onResume() {
            super.onResume();
    
            mTango = new Tango(HelloMotionTrackingActivity.this, new Runnable() {
                @Override
                public void run() {
                    synchronized (HelloMotionTrackingActivity.this) {
                            mConfig = setupTangoConfig(mTango);
                            mTango.connect(mConfig);
                            startupTango(); //处理数据
                    }
                }
            });
        }

    通过回调处理数据,上一步中处理数据的方法是startupTango(),其源码如下

      private void startupTango() {
            //设置坐标参照系
            final ArrayList<TangoCoordinateFramePair> framePairs =
                    new ArrayList<TangoCoordinateFramePair>();
            framePairs.add(new TangoCoordinateFramePair(
                    TangoPoseData.COORDINATE_FRAME_START_OF_SERVICE,
                    TangoPoseData.COORDINATE_FRAME_DEVICE));
    
            // 通过回调获取和处理坐标数据
            mTango.connectListener(framePairs, new OnTangoUpdateListener() {
                @Override
                public void onPoseAvailable(final TangoPoseData pose) {
                    //在这里写处理移动追踪和区域学习数据的代码
                }
    
                @Override
                public void onXyzIjAvailable(TangoXyzIjData xyzIj) {
                    // We are not using onXyzIjAvailable for this app.
                }
    
                @Override
                public void onPointCloudAvailable(TangoPointCloudData pointCloud) {
                    // 如果开启深度感知,则在这里处理点阵信息
                }
    
                @Override
                public void onTangoEvent(final TangoEvent event) {
                    //在这里处理各种事件,比如鱼眼摄像头出问题,pose数据失效事件等
                }
    
                @Override
                public void onFrameAvailable(int cameraId) {
                    // We are not using onFrameAvailable for this application.
                }
            });
        }

    应用不在前台的时候,断开和Tango的连接(官网推荐的用法)

     @Override
        protected void onPause() {
            super.onPause();
            synchronized (this) {
                mTango.disconnect();
              }
        }

    二、开发者必备

    1. 学习资料

    2. 开发方式

    开发方式软件需求设备
    Java Android Android Studio、 TangoReleaseLibs(Tango SDK) Tango Device
    Unity Android Unity 5.2.1以上(配置好Android开发环境)、Tango Unity SDK Tango Device

    注:Android API版本 只支持 API Level 17 及以上,Tango Device是必须的,没有其独特的感应设备,Tango没办法正常工作。

    三、移动追踪(motion tracking)

    1. Tango的坐标数据——pose

    pose是Tango中的坐标表示,其具体的Java对象是TangoPoseData,其包含了两个信息:三维坐标、物体的朝向,其结构如下:

    struct PoseData {
        double orientation[4]; //朝向信息,四元数表示
        double translation[3]; //三维坐标信息
    }

    三维坐标系可以用下图表示,当我们正常站立手持移动设备面向自己的脸部时,X轴的正方向是向右的。


    image

    朝向信息,也可以说成旋转信息,如下图理解,三个方向上的旋转,用四元数表示(这个我不太懂,三个旋转用四元数表示好像是为了方便计算,具体请百度)。


    image

    2. pose的生命周期

    pose数据是有可能失效的,比如鱼眼摄像头发生了错误导致出错等。下图 是pose数据的状态转换图。


    image

    3. 应用获取和处理pose数据

    private void startupTango() {
            // 设置坐标参照系
            final ArrayList<TangoCoordinateFramePair> framePairs =
                    new ArrayList<TangoCoordinateFramePair>();
            framePairs.add(new TangoCoordinateFramePair(
                    TangoPoseData.COORDINATE_FRAME_START_OF_SERVICE,
                    TangoPoseData.COORDINATE_FRAME_DEVICE));
    
            // 在回调中获取坐标信息
            mTango.connectListener(framePairs, new OnTangoUpdateListener() {
                @Override
                public void onPoseAvailable(final TangoPoseData pose) {
                    logPose(pose);
                }
    
              });
        }
    
        /**
         *  打印坐标信息
         */
        private void logPose(TangoPoseData pose) {
            StringBuilder stringBuilder = new StringBuilder();
    
            float translation[] = pose.getTranslationAsFloats();
            stringBuilder.append("Position: " +
                    translation[0] + ", " + translation[1] + ", " + translation[2]);
    
            float orientation[] = pose.getRotationAsFloats();
            stringBuilder.append(". Orientation: " +
                    orientation[0] + ", " + orientation[1] + ", " +
                    orientation[2] + ", " + orientation[3]);
    
            Log.i(TAG, stringBuilder.toString());
        }

    四、区域学习(Area Leaning)

    1. ADF文件

    区域学习将设备“看到的信息”保存成ADF(Area Description File)文件,采用UUID进行唯一标识。ADF文件算是一种持久化的数据,可以重复利用。

    ADF文件实际上是一种键值对的文件形式,它其中保存了区域学习记录的信息,但是这些空间信息不需要也不允许开发者进行修改,其他官网公开的属性有如下几个:

    键值解释
    KEY_UUID UUID唯一标识
    KEY_NAME 文件的name
    KEY_TRANSFORMATION ADF到全局坐标的一个转换 (x, y, z, qx, qy, qz, qw)
    KEY_DATE_MS_SINCE_EPOCH ADF文件保存的时间

    此外,我们也可以加入一些自己定义的键值对信息。

    2. 区域重定位(区域匹配)

    如果载入使用以前的ADF文件,要实现正常的功能,必须进行一个重定位过程,用户要手持设备走到现实中与载入的ADF匹配的地域,tango会将环境信息和ADF文件信息做匹配,匹配成功了即意味着“重定位”成功。

    区域匹配是有可能失败的,Tango的区域匹配成功率与环境的“多样性”有关,如果环境很空旷,或者各个房间都是一模一样的,那么区域学习和匹配陈功率较低。如果环境中有各式各样的物品,那么成功率较高。

    3. 加载和使用ADF文件示例

    开启区域学习

    TangoConfig mConfig = mTango.getConfig(TangoConfig.CONFIG_TYPE_CURRENT);
    mConfig.putBoolean(TangoConfig.KEY_BOOLEAN_LEARNINGMODE, true);

    加载特定UUID标识的ADF文件

     mConfig.putString(TangoConfig.KEY_STRING_AREADESCRIPTION, uuid);

    获取最近所有的ADF文件

    ArrayList<String> fullUUIDList = new ArrayList<String>();
    
    fullUUIDList = mTango.listAreaDescriptions();

    保存当前的ADF文件,这个可能很耗时,不要在UI线程做(官方提供了SaveAdfTask来做这件事)。

    Tango.saveAreaDescription()

    在回调中处理区域学习的位置数据,因为文章开头有讲述,其他步骤省略了。

    @Override
    public void onPoseAvailable(TangoPoseData pose) {
    
    if (pose.baseFrame == TangoPoseData.COORDINATE_FRAME_AREA_DESCRIPTION
            && pose.targetFrame == TangoPoseData.COORDINATE_FRAME_DEVICE) {
        // 这个条件意味着移动设备到了一个新的位置
    }
    else if (pose.baseFrame == TangoPoseData.COORDINATE_FRAME_AREA_DESCRIPTION
            && pose.targetFrame == TangoPoseData.COORDINATE_FRAME_START_OF_SERVICE) {
        // 这个条件告诉我们,设备回到了ADF文件区域的开始位置,也意味着重定位过程成功。
        //开发者可以视其为重定位成功的信号
    }

    五、深度感知(Depth Perception)

    深度感知目前为平衡对设备和处理器的要求,理想的扫描距离为0.5米到4米之间,近距离物品扫描和手势检测并不完美。对于采用红外光技术的深度感知设备,在如下两种情况有可能工作不正常:

    • 环境中红外光在光源中占据较高比例,比如阳光和白炽灯照射的区域
    • 不反射红外光的物品难以被正常扫描

    深度感知的工作原理就是扫描摄像头照射的区域,对照射到的物品计算其空间位置,给出一大堆三维点阵的信息(point cloud)

    深度感知仍旧在回调里面编写获取数据的方法,回调中不能做耗时操作,如果上次回调没有完成,因为你无法获取最新的数据。

      @Override
      public void onPointCloudAvailable(final TangoPointCloudData pointCloudData) {
           //在这里处理点阵数据
        }

    六、 总结

    1. Tango功能总结

    功能数据表示对应的数据类用途
    移动追踪 三维坐标信息和物体的朝向信息 TangoPoseData 检测移动设备的位置和朝向
    区域学习 ADF文件 TangoAreaDescriptionMetaData 提高移动追踪的准确度、记忆空间信息(做室内导航)
    深度学习 点阵信息(一大堆三维坐标集合) TangoPointCloudData 扫描建模

     

     
  • 相关阅读:
    swagger的使用说明
    Springboot组件:全局异常处理
    打金?工作室?账号被封?游戏灰黑产离我们有多近
    如何用Pygame制作简单的贪吃蛇游戏
    函数式编程
    py接口自动化基础
    py类,实例
    高级特性
    css中margin负值的运用
    css多行文本溢出显示省略号
  • 原文地址:https://www.cnblogs.com/monkeyst/p/7084386.html
Copyright © 2020-2023  润新知