OSVR接入HMD设备

推荐一本书<<金字塔原理>>,本文按照书中说提的“是什么,为什么,怎么做”,来说明如何把HMD设备接入到OSVR上。

为什么要做OSVR插件

对于我们来说,后续要制作的产品是头盔,对于头盔设备通过插件接入OSVR优点如下:

  • 硬件插件,接入OSVR后,直接玩OSVR上的游戏,而不需要单独跟游戏公司来做联调,不会陷入先有鸡还是先有蛋的困境。
  • 分析插件,接入OSVR后,可以使单独的硬件功能更加丰富,如计步器,手势识别。
  • 提供丰富的参考资源(Ocluars,HTC,OSVR等),平台调试工具(BasicServer,vrpn_print_devices,Distortionizer等)。
    如果没有OSVR平台,每个设备都需要适配每个平台,如果有M台设备,有N个平台,那么他们之间的关系就有MXN种,维持这样的关系是极其麻烦的,设备和VR应用之间的关系如下图所示:
    这里写图片描述
    如果设备和应用程序都接入到OSVR上,那么设备只需要接入到OSVR中即可,而不要考虑具体的平台和应用,同样应用不需要考虑每一个设备的情况,它按照统一的接口获取设备的数据,对于设备来说他们只需要制作自己接入OSVR的插件即可,应用程序也只要使用OSVR的插件就可以正常工作了,关系如下图所示:
    这里写图片描述

OSVR插件是什么

OSVR插件,为上层应用程序提供数据,包含2类插件:分析插件和设备插件
分析插件:用于把底层上报的原始数据,解析、处理成上层需要的。例如,一个手势识别的插件,可以底层上报的XYZ坐标轴的值,转换、识别成具体的手势。
设备插件:用来接入具体的物理设备,用来为上层提供各种类型的数据。例如,VR眼镜的插件可以提供显示相关的参数,以及追踪器的坐标轴数据。

OSVR插件怎么做

如果HMD只是作为显示,则只需要修改json文件即可(json文档说明),如果需要提供追踪器数据,手势识别等功能,则需要制作插件。
以手上我们自己做得头显设备(此设备能够通过USB主动上报传感器的值即可)为例,来制作一个能够使此HMD接入OSVR-Core的插件。

加载插件

  • 拷贝demo源代码作为初始代码:”OSVR-Core\examples\plugin\selfcontained”,这里将拷贝后的文件夹命名为”osvr_plugin_oueh”,如下图所示:
    这里写图片描述
  • 将”com_osvr_example_selfcontained.cpp”文件重命名为”com_osvr_oueh_plugin.cpp”,将”com_osvr_example_selfcontained.json”文件重命名为”com_osvr_oueh_plugin.json”:
    这里写图片描述
  • 将“com_osvr_oueh_plugin.cpp”代码里,修改头文件,json配置以及OSVR_PLUGIN,代码修改如下:
    这里写图片描述
    这里写图片描述
    这里写图片描述
    同时添加一行”Hello World”打印信息:
    这里写图片描述
    • 修改CMake编译文件,修改内容如下:
      这里写图片描述

制作带读取分析HMD数据的插件

  • 打开CMake,选择源文件路径以及编译生成路径:
    这里写图片描述
  • 添加CMAKE_PREFIX_PATH变量:点击”Add Entry”按钮。在弹出的窗口中“Name”字段,输入“CMAKE_PREFIX_PATH”,在“Type”字段选择PATH。
    这里写图片描述
  • 然后点击”Value”字段的”…”,弹出文件夹选择窗口, 选择官方下载的运行环境包—这个文件夹包括bin,lib等目录。点击“OK”确认文件夹,然后再点击“OK”,完成添加,(此工具可以已传微云网盘)。
    这里写图片描述
  • 此时,你将返回到CMake的主界面,如下图所示(红色不是表示错误,表示修改的部分):
    这里写图片描述
  • 点击“Configure” 按键,点击“yes”生成目标文件夹,同时选择编译环境,我这里安装的是VS2015的update3,然后点击按钮”Finish”:
    这里写图片描述
    这里写图片描述
  • Configure之后,点击”Generate”,生成.sln文件:
    这里写图片描述
    这里写图片描述
  • 双击sln文件,选择relase版本,然后点击菜单”Build”—“Build solution”:
    这里写图片描述
    编译成功后,即生成你的插件文件(com_osvr_oueh_plugin.dll):
    这里写图片描述
    源文件修改补丁:点击这里获取

测试插件

CMD里运行BasicServer(此程序通过编译OSVR-core获得,这里上传一份我编译),来测试插件:
这里写图片描述
测试OK。
如果要被osvr_core加载,将此dll放入到D:\src\OSVR-Core\build_win64\bin\osvr-plugins-0\Release文件夹下,然后运行“osvr_server.exe osvr_server_config.json” 即可。

读取HMD上的传感器数据

HMD与PC用USB线连接,PC通过USB来读取HMD上的所有数据(包括加速度、陀螺仪、磁力计、手势坐标等),这里我们使用一个开源库:HIDAPI库,来读取HMD的数据。
HIDAPI获取、编译点击这里。拷贝出”hidapi.h“,”hidapi.lib“,”hidapi.dll”这3个文件。

  • 将HIDAPI库文件导入我们的工程,“com_osvr_oueh_plugin.cpp”文件添加:
    这里写图片描述
    同时,将”hidapi.h”、”hidapi.lib”文件拷贝到“com_osvr_oueh_plugin.cpp”文件的当前目录下。

  • 打开“com_osvr_oueh_plugin.cpp”文件,在“HardwareDetection”类中添加,通过HID接口读取HMD设备信息的代码:
    这里写图片描述
    这里写图片描述
    OSVR-Core会调用插件的operator方法,来检测设备是否连接。
    上面hid_open参数需要替换成你的设备的VID和PID,到这步就能够读取到HMD的设备基本信息。
    对于HMD设备,需要不断上报传感器数据,插件里AnalogExampleDevice类的update方法会被循环调用,我们可以在这里添加读取数据的代码:
    这里写图片描述
    读取函数:
    这里写图片描述
    如果HMD持续输出数据,这里就能读取到数据,将数据实时打出。

添加数据解析

上面已经能够将数据读出,我们这里将进一步对读出的数据进行解析。这里手上设备是以Oculars协议来传递追踪器数据,就以这个协议做解析获取追踪器数据,Oculars协议点击这里获取。
定义数据解析结构体:
这里写图片描述
协议解析函数:

int decode_h551_hmd_data(h551_hmd_data *hmd_data, u8 *buf, int size){u8 pos = 0;int temp[2];//for test//buf[8] = 255;buf[9] = 251;buf[10] = 176;buf[11] = 0;buf[12] = 181;buf[13] = 0;buf[14] = 31;buf[15] = 121;hmd_data->ReportID = buf[pos++];hmd_data->SampleCount = buf[pos++];hmd_data->Timestamp = buf[pos] + (buf[pos+1]<<8);pos += 2;//temp[0] = 0x4030201;//memcpy(&buf[8], (u8 *)&temp[0],4);//std::cout << "decode_h551_hmd_data: "<< "buf[8]:" <<int(buf[8])<<",buf[9]:" << int(buf[9])<<",buf[10]:" << int(buf[10]) << ",buf[11]:" << int(buf[11]) << std::endl;hmd_data->LastCommandID = buf[pos] + (buf[pos+1] << 8);pos += 2;hmd_data->Temperature = buf[pos] + (buf[pos+1] << 8);pos += 2;//memcpy((u8 *)temp,&buf[pos],8);//std::cout << "decode_h551_hmd_data: temp[0]=" << temp[0] << ",temp[1]:" <<temp[1]<<",pos="<<int(pos)<< std::endl;hmd_data->accel_X = buf[pos] | (buf[pos + 1] << 8) | ((buf[pos + 2] & 0x1F) << 16);hmd_data->accel_Y = ((buf[pos + 2] & 0xE0) >> 5) | (buf[pos + 3] << 3) | (buf[pos + 4] << 11) | ((buf[pos + 5] & 0x03) << 19);hmd_data->accel_Z = (buf[pos + 5] & 0xFC) >> 2 | (buf[pos + 6] << 6) | (buf[pos + 7] << 14);pos += 8;//memcpy((u8 *)temp, &buf[pos], 8);//hmd_data->gyro_X = temp[0] & 0x001FFFFF;//hmd_data->gyro_Y = (temp[0] << 20) + ((temp[1] & 0x000003FF) << 11);//hmd_data->gyro_Z = temp[1] << 9;hmd_data->gyro_X = buf[pos] | (buf[pos + 1] << 8) | ((buf[pos + 2] & 0x1F) << 16);hmd_data->gyro_Y = ((buf[pos + 2] & 0xE0) >> 5) | (buf[pos + 3] << 3) | (buf[pos + 4] << 11) | ((buf[pos + 5] & 0x03) << 19);hmd_data->gyro_Z = (buf[pos + 5] & 0xFC) >> 2 | (buf[pos + 6] << 6) | (buf[pos + 7] << 14);pos += 8;//only use sampe[0] data,not use sample[1] sample[2]pos += 2 * 16;hmd_data->MagX = buf[pos] + buf[pos+1] << 8;pos += 2;hmd_data->MagY = buf[pos] + buf[pos+1] << 8;pos += 2;hmd_data->MagZ = buf[pos] + buf[pos+1] << 8;pos += 2;//debug//std::cout << "decode_h551_hmd_data: pos= " << int(pos) << std::endl;std::cout << "ReportID=" << int(hmd_data->ReportID) << ",SampleCount=" << int(hmd_data->SampleCount) << ",Timestamp=" << hmd_data->Timestamp <<",LastCommandID=" << hmd_data->LastCommandID << ",Temputure=" << hmd_data->Temperature<< ",accel_X=" << hmd_data->accel_X << ",accel_Y=" << hmd_data->accel_Y << ",accel_Z=" << hmd_data->accel_Z << ",gyro_x=" << hmd_data->gyro_X << ",gyro_z=" << hmd_data->gyro_Z    << ",gyro_Z=" << hmd_data->gyro_Z << ",MagX=" << hmd_data->MagX << ",MagY=" << hmd_data->MagY << ",MagZ=" << hmd_data->MagZ << std::endl;return 0;} 

修改后的代码获取点击这里
编译后生成插件。

测试

将生成的插件文件(“com_osvr_oueh_plugin.dll”),拷贝到路径“OSVR-Core\build_win64\bin\osvr-plugins-0\Release”下
将”hidapi.dll”文件,拷贝到”OSVR-Core\build_win64\bin\Release”路径下,运行”osvr_server.exe osvr_server_config.json”,可以获取到HMD的数据如下:
这里写图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/1380534.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

迈德威视SDK

引入 代码 public class MVCamera : InterfaceCamera{#region 属性字段PictureBox pb_ShowImage;//图像框tSdkCameraDevInfo[] tCameraDevInfoList;CameraSdkStatus status;public static CameraHandle[] m_hCamera; // 句柄CAMERA_SNAP_PROC m_CaptureCallback;In…

MVVM 架构,ViewModel和LiveData(一)

MVVM 架构,ViewModel和LiveData(一) 标签&#xff08;空格分隔&#xff09;&#xff1a; 翻译计划 Android开发 原文链接 MVVM architecture, ViewModel and LiveData (Part 1) 正文 在Google I/O之间,Google推出了包含LiveData和ViewModel的组件架构,这有助于开发者们使用…

DRMM model

Paper 的引用&#xff1a; Guo J, Fan Y, Ai Q, et al. A deep relevance matching model for ad-hoc retrieval[C]//Proceedings of the 25th ACM International on Conference on Information and Knowledge Management. ACM, 2016: 55-64. Retrieval or Matching 论文中说到…

JVM(JAVA虚拟机)、DVM(Dalvik虚拟机)和ART虚拟机

一、什么是DVM&#xff0c;和JVM有什么不同&#xff1f; JVM是Java Virtual Machine&#xff0c;而DVM就是Dalvik Virtual Machine&#xff0c;是安卓中使用的虚拟机&#xff0c;所有安卓程序都运行在安卓系统进程里&#xff0c;每个进程对应着一个Dalvik虚拟机实例。他们都提…

关于Hdmi2.1,FRL,DSC,VRR,ALLM你需要知道这些

文章目录 TMDSFRLDSCVRRALLM相关设备Nvidia显卡电视游戏机显示器 注意的坑 最近在研究Hdmi相关内容&#xff08;看游戏设备hhh&#xff09;&#xff0c;网上很多信息都是零零碎碎的&#xff0c;结合自己的一些研究简单记录一下。 Hdmi&#xff0c;High Definition Multimedia I…

HDMI 2.1 VRR功能详解

7.6可变刷新率和快速更新 可变刷新率&#xff08;VRR&#xff09;允许图片在源完成准备后立即通过链路发送。在链路支持的最大字符速率大于给定视频定时所需的速率的情况下&#xff0c;Fast VActive&#xff08;FVA&#xff09;减少了传输图片所需的时间。这些特性提供了性能、…

VVC帧间预测(八)DMVR

解码端运动向量修正(Decoder side motion vector refinement ,DMVR)是为了提高merge模式下双向预测MV的准确性而提出的技术。双向预测是在list0和list1中分别找一个运动向量MV0和MV1&#xff0c;然后将MV0和MV1所指向的预测块进行加权得到最终的预测块。而DMVR不是直接使用MV0和…

ARVR技术 | AR, VR, MR和XR?想搞清楚不?

AR, VR, MR&#xff0c;现在还有XR ?这些缩写是什么?它们代表什么? 让我们快速梳理一下技术术语。 首先&#xff0c;虽然你可能熟悉其中的一些术语&#xff0c;如AR和VR, 但MR和XR对许多人来说仍然是新鲜的术语。 目前的共识是&#xff0c;所有这些互补形式的现实都落在一…

MDD(模型驱动开发)

前言导读 当下企业软件应用开发面临着需求复杂多变、新的需求和系统不断增长&#xff0c;软件系统变得越来越复杂&#xff0c;普通的软件开发方式难以快速满足用户需求。为了解决这些问题&#xff0c;就出现了很多新的方法&#xff0c;其中最突出的一个就是模型驱动开发 MDD &a…

RSCMVR

也是之前发了 ~~ 又带来马教授的~~ 神器稀疏卷积性能和稳健性超越ResNet 标题就是简写可好? 尽管深度神经网络在图像分类方面具有很强的经验性能&#xff08;empirical performance&#xff09;&#xff0c;但这类模型往往被视为「黑盒」&#xff0c;最为人诟病的就是「难以解…

EMD和VMD

作者&#xff1a;桂。 时间&#xff1a;2017-03-06 20:57:22 链接&#xff1a;http://www.cnblogs.com/xingshansi/p/6511916.html 前言 本文为Hilbert变换一篇的内容补充&#xff0c;主要内容为&#xff1a; 1&#xff09;EMD原理介绍 2&#xff09;代码分析 3&#xff09…

什么是MDM

MDM或移动设备管理是一种软件应用程序&#xff0c;用于管理企业中的终端&#xff0c;如笔记本电脑、智能手机、平板电脑等。随着越来越多的员工使用这些设备&#xff0c;各种形式和规模的企业现在都转向移动设备管理&#xff0c;以增强数据安全性并提高生产力。 MDM是什么意思…

AVS3中的AMVR和EMVR

在AVS2中运动预测中使用的MV都是1/4像素精度&#xff0c;通过在整像素间插值能显著提升非整像素运动预测的精度&#xff0c;同时带来的问题是随着MV精度的提高编码MVD所需的比特数也会增加。 AMVR AMVR支持的MVD编码5种精度的MVR{1/4,1/2,1,2,4}&#xff0c;索引为0到4&#x…

无线网络视频监控系统基本概念和术语

无线网络视频监控系统基本概念和术语 1.网络摄像机与模拟摄像机的区别 模拟摄像机&#xff0c;或称摄像头&#xff0c;输出CVBS模拟视频信号&#xff0c;PAL制或者NTSC制。模拟摄像机多采用CCD器件&#xff0c;目前也有采用CMOS器件的。有枪机、半球、球机等多种形式&#xff0…

掌握Python的X篇_27_Python中标准库文档查阅方法介绍

前面的博文介绍了python的基本语法、模块及其导入方法。前人将各种方法封装成模块、库、函数供我们使用&#xff0c;如何去使用前人做好的东西&#xff0c;那就需要去查阅文档。今天就介绍python中官方文档的查阅方式。对于初学者而言&#xff0c;python自带的文档就已经足够好…

基本动态规划问题的扩展

基本动态规划问题的扩展 应用动态规划可以有效的解决许多问题&#xff0c;其中有许多问题的数学模型&#xff0c;尤其对一些自从57年就开始研究的基本问题所应用的数学模型&#xff0c;都十分精巧。有关这些问题的解法&#xff0c;我们甚至可以视为标准——也就是最优的解法。…

shell脚本安装nginx

shell脚本原理 以删除桌面文件的脚本为例&#xff0c;执行脚本后&#xff0c;shell脚本将代码给内核&#xff0c;内核读取后执行命令&#xff0c;如果shell脚本也在桌面上&#xff0c;执行后这个脚本文件也会被删除。 变量 echo $SHELL$符表示SHELL是一个变量&#xff0c;变量…

Python(七十九)字符串的常用操作——字符串内容对齐操作的方法

❤️ 专栏简介&#xff1a;本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中&#xff0c;我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 &#xff1a;本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

docker实现Nginx

文章目录 1.docker 安装2.docker环境实现Nginx 1.docker 安装 1.使用环境为红帽8.1,添加源 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo2.安装 yum install docker-ce docker-ce-cli containerd.io显示出错 Docker C…

Vue [Day7] 综合案例

核心概念回顾 state&#xff1a;提供数据 getters&#xff1a;提供与state相关的计算属性 mutations&#xff1a;提供方法&#xff0c;用于修改state actions&#xff1a;存放异步操作 modules&#xff1a;存模块 功能分析 https://www.npmjs.com/package/json-server#ge…