[PICO VR眼镜]眼动追踪串流Unity开发与使用方法,眼动追踪打包报错问题解决(Eye Tracking)

news/2024/9/18 19:29:55/ 标签: vr, unity, 游戏引擎

前言

最近在做一个工作需要用到PICO4 Enterprise VR头盔里的眼动追踪功能,但是遇到了如下问题:

  1. 在Unity里面没法串流调试眼动追踪功能,根本获取不到Device,只能将整个场景build成APK,安装到头盔里,才能在代码里调用眼动追踪功能。这使得每次修改代码都要打包一次apk安装到头盔里,十分不方便,难以调试。
  2. PICO VR 官方提供的Eye Tracking教程里,获取到的眼睛朝向和位置是相对于Head这个位置的,而不是相对于XR Origin下的Camera的位置,这使得API不能直接拿来使用。
  3. Unity在引入PICO VR眼动跟踪代码后,编译时点击"build and run"后,会报错“NullReferenceException: Object reference not set to an instance of an object

鉴于以上问题网络上均没有人进行解答,以及个人没能得到PICO官方的技术支持情况下(三周内发了2封技术工单邮件+2次催线上客服),遂打算自己捣鼓一下写篇教程。

(点名批评PICO官方的技术支持不回复邮件的问题,明明就几个特别简单的问题,但是官方承诺的3-5个工作日内回复并没有做到,等了三周一封邮件也没回,这个过程还问了客服,客服表示会催技术人员回复,但等了一周半也没看到,放弃了orz)

更新补充:据说在PICO企业版官网提交企业版工单能得到官方较快的回复。

1. 如何在代码里使用眼动跟踪,并转换成世界坐标 或 摄像机坐标系

首先,检查眼动追踪是否能正常工作:

void Start()
{CheckEyeTracking();}
private void CheckEyeTracking()
{//Start PICO Eye Tracking ServiceTrackingStateCode trackingState;trackingState = (TrackingStateCode)PXR_MotionTracking.WantEyeTrackingService();Debug.Log("告知PICO想要眼动跟踪服务 trackingState: " + trackingState.ToString());//Check Eye Tracking able or notEyeTrackingMode eyeTrackingMode = EyeTrackingMode.PXR_ETM_NONE;bool supported = false;int supportedModesCount = 0;trackingState = (TrackingStateCode)PXR_MotionTracking.GetEyeTrackingSupported(ref supported, ref supportedModesCount, ref eyeTrackingMode);Debug.Log("检查是否有眼动跟踪功能 trackingState: "+ trackingState.ToString()+"  code  "+ supported);// Get Eye Tracking Statebool tracking = true;EyeTrackingState eyeTrackingState = new EyeTrackingState();trackingState = (TrackingStateCode)PXR_MotionTracking.GetEyeTrackingState(ref tracking, ref eyeTrackingState);Debug.Log("获取当前眼动跟踪状态 trackingState: " + trackingState.ToString());// Start Eye Tracking//这里要严谨点的话,应该要加上if条件判断是否有眼动跟踪功能,再选择开启该功能EyeTrackingStartInfo info = new EyeTrackingStartInfo();info.needCalibration = 1;info.mode = eyeTrackingMode;trackingState = (TrackingStateCode)PXR_MotionTracking.StartEyeTracking(ref info);Debug.Log("开始眼动跟踪状态 trackingState: " + trackingState.ToString());//Get Eye Tracking Data//获取眼动跟踪数据EyeTrackingDataGetInfo eyeData = new EyeTrackingDataGetInfo();eyeData.displayTime = 0;eyeData.flags = EyeTrackingDataGetFlags.PXR_EYE_DEFAULT| EyeTrackingDataGetFlags.PXR_EYE_POSITION| EyeTrackingDataGetFlags.PXR_EYE_ORIENTATION;EyeTrackingData eyeTrackingData = new EyeTrackingData();trackingState = (TrackingStateCode)PXR_MotionTracking.GetEyeTrackingData(ref eyeData, ref eyeTrackingData);Debug.Log("eyeData:  "+ eyeData.ToString() + " TrackingData:  " + eyeTrackingData.ToString());}

接下来,每帧都获取眼动数据,并将眼睛位置和眼睛朝向数据转换成世界坐标

public Transform origin;//在Unity主界面把XR Origin拖进来即可
private Matrix4x4 headPoseMatrix,originPoseMatrix;
private Vector3 combineEyeGazeVector, combineEyeGazeOriginOffset, combineEyeGazeOrigin;
private Vector3 combineEyeGazeVectorInWorldSpace, combineEyeGazeOriginInWorldSpace;
void Update()
{GetEyeTrackingData();
}private void GetEyeTrackingData()
{//获取head的局部转世界矩阵,该矩阵点乘head局部坐标系下坐标,则能转换为世界坐标系下的坐标PXR_EyeTracking.GetHeadPosMatrix(out headPoseMatrix);	//获取双眼(取中间位置)位于Head坐标系下的朝向信息GazeVectorPXR_EyeTracking.GetCombineEyeGazeVector(out combineEyeGazeVector);//获取双眼(取中间位置)位于Head坐标系下的位置信息GazePointPXR_EyeTracking.GetCombineEyeGazePoint(out combineEyeGazeOrigin);//获取眼睛的世界坐标combineEyeGazeOriginInWorldSpace = originPoseMatrix.MultiplyPoint(headPoseMatrix.MultiplyPoint(combineEyeGazeOrigin));//获取眼睛的朝向信息combineEyeGazeVectorInWorldSpace = originPoseMatrix.MultiplyVector(headPoseMatrix.MultiplyVector(combineEyeGazeVector));//highlighArea是我添加的一个手电筒高亮区域,能让用户更直观地查看眼睛看向位置highlighArea.transform.position = combineEyeGazeOriginInWorldSpace ;//LookRotation默认是以z轴旋转,如果要以y轴旋转的话可以在后面加上 ,Vector3.uphighlighArea.transform.rotation = Quaternion.LookRotation(combineEyeGazeVectorInWorldSpace);
/*        RaycastHit hit;if (Physics.Raycast(highlighArea.transform.position, combineEyeGazeVectorInWorldSpace, out hit, 1000f)){highlighArea.transform.LookAt(hit.point);}*/
}

简易效果图(透明圈处是一个作为highlighArea的圆锥区域):
在这里插入图片描述

至此,便已经能获取到PICO VR里眼动追踪的位置和朝向信息。

2. "Build and Run"报错

引入EyeTracking代码后,发现Build and Run时会报以下错误:
在这里插入图片描述

在这里插入图片描述
这是因为run的话会导致Unity找不到可供眼动追踪的设备,导致编译报错。

解决方法,只点击Build,而不是Build and Run:
在这里插入图片描述
Build完后,打开Pico Developer Center,依次点击"应用管理"->“安装包”->“安装本地应用”:
在这里插入图片描述
选择build好的apk即可,后续便能直接在眼镜里运行:
在这里插入图片描述

3.眼镜内调试的Trick

对于这种要build到眼镜里才能调试的功能,可以利用Unity提高的UI->Text组件进行调试。

即,在Unity场景下创建一个UI->Text对象,然后把对象拖到下面脚本的GazeDebugText变量上,便能在眼镜里看到相应数据输出了

public TMP_Text GazeDebugText;
private void GetEyeTrackingData()
{GazeDebugText.text = combineEyeGazeOrigin.ToString("F3");//F3是指精确到小数点后3位
}

效果:
在这里插入图片描述

4.如何在Unity里串流调用眼动追踪功能

B站视频:使用PICO头显在VR串流环境下进行眼动追踪

我个人是在看了这个视频后才知道PICO VR也能在Unity下串流使用眼动跟踪功能,但我没有进一步深入探究,据该视频UP主表示,PICO neo3 pro eye是可以串流的,该方法理应也适用于其他头盔。

在此处也表达下对UP主的感谢,在后台私信耐心细致替我解答问题。

原理:串流使用pico的眼动追踪功能,需要下载特定的串流软件和PICO系统版本,电脑端上用的是PICO企业版串流工具(普通版的串流工具不知道可不可以):在这里插入图片描述

在PICO端上则是自动保持串流软件更新到最新版本。

build成apk安装包之后,调用的SDK是正常使用的;串流时候的SDK会随business streaming一起安装,和apk的SDK不一样

business streaming安装后,sdk里会有一个用qt写的测试程序,可以试试看串流后眼动跟踪是否正常,测试程序不需要用steam;但是对头显的固件版本有要求:
在这里插入图片描述

在这里插入图片描述

如果经过测试后,eye tracking data什么的没有问题,后续可以串流Unity基于OpenXR进行开发。


http://www.ppmy.cn/news/1526246.html

相关文章

Oracle 11gR2打PSU补丁详细教程

1 说明 Oracle的PSU(Patch Set Update)补丁是Oracle公司为了其数据库产品定期发布的更新包,通常每季度发布一次。PSU包含了该季度内收集的一系列安全更新(CPU:Critical Patch Update)以及一些重要的错误修…

6芯7芯可旋转电连接器航空插头

概述 可旋转电航空插头是一种能够在旋转或相对运动的部件间稳定传输电气信号或电源的装置,广泛应用于航空航天、自动化设备、医疗设备等多个领域。它的核心在于精密的接触系统,由旋转端和固定端两部分组成,通过金属触点或导电环实现电气连接。…

Unity 粒子系统参数说明

一、Particle System 1. Duration(持续时间) 粒子系统运行一次所需的时间。它决定粒子系统持续播放的时间长度。 2. Looping(循环播放) 如果启用,粒子系统将在播放完一次后自动重新开始播放,直到你停止它…

SpringBoot框架Web开发

1. 控制器开发 (1) JSON的支持 Spring Boot默认支持JSON格式的数据交换,主要通过以下方式实现: 依赖:spring-boot-starter-web 依赖包已经包括了 Jackson,用于将Java对象序列化为JSON,以及将JSON反序列化为Java对象…

Protubuf入门

⼀、初识 ProtoBuf 1. 序列化概念 序列化和反序列化 序列化:把对象转换为字节序列的过程 称为对象的序列化。 反序列化:把字节序列恢复为对象的过程 称为对象的反序列化。 什么情况下需要序列化 存储数据:当你想把的内存中的对象状态…

Java零基础-replace(CharSequence target, CharSequence replacement)详解

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互…

2024年某大厂HW蓝队面试题分享

🤟 基于入门网络安全/黑客打造的资源包无偿分享中: 👉黑客&网络安全入门&进阶学习资源包 应急响应流程 1)首先判断服务器资产、影响范围以及严重程度,确认有没有必要将服务器下线隔离,然后根据服务…

【佳学基因检测】在织梦网站中, 创建或修改目录:/var/www/html/cp 失败! DedeTag Engine Create File False

【佳学基因检测】在织梦网站中, 创建或修改目录:/var/www/html/cp 失败! DedeTag Engine Create File False 在使用 DedeCMS(一个常用的内容管理系统)时,如果遇到“创建或修改目录:/var/www/html/cp 失败&…

工程师 - HUE(Humans in User Experience)介绍

HUE:Humans in User Experience(用户体验中的人类)是用户体验(UX)设计领域的一种概念或方法,强调在设计过程中考虑人的因素的重要性。它侧重于了解用户的需求、行为和情感,从而创造出更有效、更…

flask框架

Flask 1 flask简介 我们之所以在浏览器中输入localhost:8080然后就可以把webapps下面的项目文件以浏览器的方式打开,功臣在与tomcat。python语言写的项目,转换为web,Flask框架 轻量级web应用框架。 环境准备: pip install fl…

基于鸿蒙API10的RTSP播放器(七:亮度调节功能测试)

目标: 当我的手指在设备左方进行上下移动的时候,可以进行屏幕亮度的调节,在调节的同时,有实时的调节进度条显示 步骤: 界面逻辑:使用Stack() 组件,完成音量图标和进度条的组合显示&#xff0c…

鹏哥C语言自定义笔记重点(67-)

67. 68. 69. 70. 71.结构体内容 72.理解结构体的字节数 73. #pragma once //头文件中使用,功能是:防止头文件被多次引用 74.结构体传参 结论:结构体传参时,要传结构体地址。 75.位段 76.static是只能在该文件中看到,其他地方看不到 77.…

通俗理解矩阵的秩

通俗理解矩阵的秩 flyfish 一、通俗的理解 想象有一张表格(矩阵),表格里有很多数字。矩阵的秩告诉我们这个表格里的数据有多么“特别”或者“复杂”。 1. 行和列的概念: 矩阵是由行(横排的数字)和列&a…

vue + Lodop 制作可视化设计页面 实现打印设计功能(四)

历史: vue2 Lodop 制作可视化设计页面 实现打印设计功能(一) vue Lodop 制作可视化设计页面 实现打印设计功能(二) vue Lodop 制作可视化设计页面 实现打印设计功能(三) 前言&#xff1a…

uniapp vue3 梯形选项卡组件

实现的效果图&#xff1a; 切换选项卡显示不同的内容&#xff0c;把这个选项卡做成了一个组件&#xff0c;需要的自取。 // 组件名为 trapezoidalTab <template> <view class"pd24"><view class"nav"><!-- 左侧 --><view cla…

web基础之文件上传

1.下载安装 下载地址 链接&#xff1a;百度网盘-链接不存在 提取码&#xff1a;jhks 安装 直接把他放在phpstudy的WWW目录中。&#xff08;phpstudy的下载安装&#xff0c;可以自行百度一下&#xff09; 打开 访问地址&#xff1a;127.0.0.1/upload-labs 问题 这里可能…

MCU与SOC的区别

自动驾驶中 MCU 与 SoC 的区别 在自动驾驶系统中&#xff0c;**MCU&#xff08;微控制单元&#xff0c;Microcontroller Unit&#xff09;和SoC&#xff08;系统级芯片&#xff0c;System on Chip&#xff09;**都是关键的电子元件&#xff0c;但它们在性能、功能和应用领域等…

MATLAB在嵌入式系统设计中的最佳实践

嵌入式系统设计是一个复杂的过程&#xff0c;涉及硬件和软件的紧密集成。MATLAB提供了一套全面的解决方案&#xff0c;从算法开发到代码生成&#xff0c;再到硬件验证&#xff0c;极大地简化了这一过程。本文将探讨使用MATLAB进行嵌入式系统设计的最佳实践&#xff0c;包括模型…

10分钟在钉钉上增加一个AI机器人

您只需 10 分钟&#xff0c;无需任何编码&#xff0c;即可为您的组织在钉钉平台上创建一个有大模型能力加成的 AI 机器人。这个机器人可以全天候&#xff08;7x24&#xff09;响应用户咨询&#xff0c;还能解答私域问题&#xff0c;成为您业务的专属机器人&#xff0c;提升用户…

时序数据库 TDengine 的入门体验和操作记录

时序数据库 TDengine 的学习和使用经验 什么是 TDengine &#xff1f;什么是时序数据 &#xff1f;使用RPM安装包部署默认的网络端口 TDengine 使用TDengine 命令行&#xff08;CLI&#xff09;taosBenchmark服务器内存需求删库跑路测试 使用体验文档纠错 什么是 TDengine &…