OSVR接入HMD设备

来源:互联网 发布:网络伤感歌曲打包下载 编辑:程序博客网 时间:2024/04/30 19:00

推荐一本书<<金字塔原理>>,本文按照书中说提的“是什么,为什么,怎么做”,来说明如何把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的数据如下:
这里写图片描述

0 0