HTC VIVE Tracker 作为一款优秀的VR设备,其有着非常好的定位精度,这时,我们就可以用这一设备来实现简单的开发,但是网上众多的教程中仅仅针对如何显示数据做了解读,但是,数据和我们自己编写的软件如何交互就成了一个一直困扰开发者的问题,这里,笔者提出一种解决思路来实现这一问题,关于HTC VIVE Tracker的简单介绍以及如何获取定位数据请参考博主的博客:HTC VIVE Tracker的二次开发(获取位置信息)

话不多说,这里先放上我们最终软件的一个效果图,供大家参考,这是笔者写的一个大软件,获取到两个Tracker的数据后效果大概就是这样的:

为了方便各位实际操作,笔者对原本的软件进行了精简,只实现数据接收这一块,大致的效果如下:软件下载地址:

这里大致说一下笔者的思路,就是在openvr获取到tracker的数据后我们通过TCP网口发送到本机地址上,再在自己写的软件上作为服务器端去接收vive传输的数据,这样我们就可以获取到tracker的数据并进行我们接下来的相关操作了,同时,这种方法也可以再连接其他设备(其他设备的数据发往本机地址,再在数据前加帧头,以便区分)

这里,首先是要对openvr的python文件添加tcp模块,使其收到数据后就向本机不停发送:修改后的opnver源代码(可以连接两台tracker,如果需要连接多台,其原理也是一致的) ,这里附上对于openvr的修改文件:openvr for double trackers

这里也附上核心代码:

HOST = 'localhost' #  or 'localhost'
PORT = 5050
BUFSIZ = 16
ADDR=(HOST,PORT)
tcpCliSock = socket(AF_INET,SOCK_STREAM)
tcpCliSock.connect(ADDR)
while True:#if interval:#with open("calibration.txt", "w+") as text_file:#while(True):start = time.time()txt = ""for i in range(1,int(num_device) + 1):for each in v.devices["tracker_1"].get_pose_euler():txt += "%.4f" % eachtxt += " "sleep_time = interval - (time.time() - start)if sleep_time > 0:time.sleep(sleep_time)for each in v.devices["tracker_2"].get_pose_euler():txt += "%.4f" % eachtxt += " "#print(txt, file = text_file)sleep_time = interval-(time.time()-start)if sleep_time>0:time.sleep(sleep_time)txt="ABCD"+txtprint(txt);tcpCliSock.send(txt.encode())tcpCliSock.close()

在完成发送端后,我们就可以进行我们的软件的编写了,其实就是模拟TCP的服务器端,不断的从本机接收数据(也就是Tracker的回传数据),这里关于TCP的编程可以参考博主的文章:C++ 网络编程下的socket编程(TCP\UDP),连接下位机,这里就不再赘述Socket部分的内容了,我们接收到数据之后就要对我们接收到的数据进行处理,我们在之前的博客里也提到过,Tracker回传的信息是由六个自由度构成的,这里我们对数据接收到之后就需要进行切割处理,来提取我们需要的数据以供后期使用,这里附上核心代码:

 int l_size = l_pCurSocket->Receive(l_buffer, PACKAGE_HEAD_SIZE);//读取包头;CString head = "";head.Format("%s", l_buffer);if (l_size <= 0){break;}Package_Head l_head;memcpy(&l_head, l_buffer, PACKAGE_HEAD_SIZE);memset(l_buffer, 0, SOCKET_TCP_BUFFER_SIZE);int l_bodySize = l_pCurSocket->Receive(l_buffer, l_head.dataLength);//读取包体;if (l_bodySize <= 0){break;}HandleMsg(l_head.messageType, &l_buffer);CString str;str.Format("%s", l_buffer);CString show = "";CString data = "";show = head + str;CString strAll = show;CStringList list;int curPos = 0;CString resToken = strAll.Tokenize(_T(" "), curPos);if (resToken != _T(""))list.AddTail(resToken);x = resToken;x_f = atof(x);GetDlgItem(IDC_X)->SetWindowText(x);resToken = strAll.Tokenize(_T(" "), curPos);if (resToken != _T(""))list.AddTail(resToken);y = resToken;y_f = atof(y);GetDlgItem(IDC_Y)->SetWindowText(y);resToken = strAll.Tokenize(_T(" "), curPos);if (resToken != _T(""))list.AddTail(resToken);z = resToken;z_f = atof(z);GetDlgItem(IDC_Z)->SetWindowText(z);resToken = strAll.Tokenize(_T(" "), curPos);if (resToken != _T(""))list.AddTail(resToken);yaw = resToken;yaw_f = atof(yaw);GetDlgItem(IDC_YAW)->SetWindowText(yaw);resToken = strAll.Tokenize(_T(" "), curPos);if (resToken != _T(""))list.AddTail(resToken);pitch = resToken;pitch_f = atof(pitch);GetDlgItem(IDC_PITCH)->SetWindowText(pitch);resToken = strAll.Tokenize(_T(" "), curPos);if (resToken != _T(""))list.AddTail(resToken);roll = resToken;roll_f = atof(roll);GetDlgItem(IDC_ROLL)->SetWindowText(roll);CString tracker = x + " " + y + " " + z + " " + yaw + " " + pitch + " " + roll;AddToInfRec(tracker, IDC_EDIT1, TRUE, TRUE);resToken = strAll.Tokenize(_T(" "), curPos);if (resToken != _T(""))list.AddTail(resToken);x_1 = resToken;x_1_f = atof(x_1);GetDlgItem(IDC_X_1)->SetWindowText(x_1);resToken = strAll.Tokenize(_T(" "), curPos);if (resToken != _T(""))list.AddTail(resToken);y_1 = resToken;y_1_f = atof(y_1);GetDlgItem(IDC_Y_1)->SetWindowText(y_1);resToken = strAll.Tokenize(_T(" "), curPos);if (resToken != _T(""))list.AddTail(resToken);z_1 = resToken;z_1_f = atof(z_1);GetDlgItem(IDC_Z_1)->SetWindowText(z_1);resToken = strAll.Tokenize(_T(" "), curPos);if (resToken != _T(""))list.AddTail(resToken);yaw_1 = resToken;yaw_1_f = atof(z_1);GetDlgItem(IDC_YAW_1)->SetWindowText(yaw_1);resToken = strAll.Tokenize(_T(" "), curPos);if (resToken != _T(""))list.AddTail(resToken);pitch_1 = resToken;pitch_1_f = atof(pitch_1);GetDlgItem(IDC_PITCH_1)->SetWindowText(pitch_1);resToken = strAll.Tokenize(_T(" "), curPos);if (resToken != _T(""))list.AddTail(resToken);roll_1 = resToken;roll_1_f = atof(roll_1);GetDlgItem(IDC_ROLL_1)->SetWindowText(roll_1);CString tracker1 = x_1 + " " + y_1 + " " + z_1 + " " + yaw_1 + " " + pitch_1 + " " + roll_1;AddToInfRec(tracker1, IDC_EDIT3, TRUE, TRUE);}

最后就是为我们的程序提供一个执行openvr的功能了,这里我们采用的是新建一个进程来执行,否则会导致接收数据之后整个程序的主进程就阻塞了:这里我们采用的是执行一个bat的批处理文件,当然读者也可以采用执行cmd命令的方法:

 WinExec("tracker.bat", SW_HIDE);

而bat文件的内容其实就是对应openvr中我们python文件的位置,比如笔者的test.py文件放在了D盘下的double文件夹下,批处理文件就是如下所示:

@echo off
d:
cd double
test.py

好了,基本的教程就是这些了

HTC VIVE Tracker的二次开发(实际操作篇)附软件相关推荐

  1. 视频教程-微信小程序开发【初级篇 / 附案例】-微信开发

    微信小程序开发[初级篇 / 附案例] 北风网讲师!瓢城Web俱乐部创始人,教学总监! 李炎恢 ¥129.00 立即订阅 扫码下载「CSDN程序员学院APP」,1000+技术好课免费看 APP订阅课程, ...

  2. HTC VIVE 安装,SteamVR,VRTK插件的使用,HTC VIVE Tracker的使用和外接按键测试

    1.Htc Vive安装教程 在把你的头显与控制器连到电脑上之前,我们首先要做的是先安好基站.基站的背面和低端各有一个固定孔,这样你可以把基站钉在墙上或者买支架将其撑起.大三角架安装示意图 Light ...

  3. UE4 + htc vive tracker + steamVR 蓝图 笔记心得

    在UE4使用 vive tracker时,需要注意一下几点: 1.先安装steamvr软件,打开htc 基站,打开vive tracker,将tracker 配对链接,校正tracker在房间里的位置 ...

  4. Htc Vive VR 手势识别插件教程 1.1 版本(附1.0版本教程PDF)

    VR手势识别插件教程1.1.1版本 VR手势识别插件教程1.1.1版本内容提纲 Htc Vive VR手势识别插件教程1.1.1版本.................................. ...

  5. visio二次开发___事件篇___事件分类

    用visio进行二次开发,不免要用到事件.这里把visio对象模型的所有事件列出来,方便大家查找.第一个事件列表的是按事件名称字母排序的:第二个代码片段是根据分类来展示的.需要注意的是,控件本身有一些 ...

  6. CAD 二次开发 图层操作(1)创建图层

    CAD二次开发的资料比较少,除了李冠亿先生的<深居浅出AutoCAD二次开发>这本书之外,目前没有找到合适的参考资料.现将自己工作中用的的一些方法贴出来.方便各位网友快速入门. #regi ...

  7. CAD 二次开发 图层操作(3)取得指定图层下的所有对象id

    对于CAD二次开发的人来说,可能需要对某一图层下的实体(点,线,面域,块,三维实体)进行不同的操作.下面的方法,即可实现获取指定图层名称下的所有实体ID. 输入参数为图层名称: 返回值为:对象主键集合 ...

  8. bim的二次开发需要什么语言_BIM软件的二次开发是什么?都需要做哪些准备?

    BIM技术已经成为这个时代中的新理念和新管理,那么在技术方面,BIM软件的二次开发是什么?包含哪些内容? 1.BIM图形引擎示例 WebGL技术是目前最为流行的,且支持度最高的Web图形技术之一.其支 ...

  9. C# AutoCAD Plant3d 二次开发准备操作

    Plant3d二次开发的文章实在是太少了, 我也是尝试了几天. 首先Plant3d二次开发需要引用的dll与AutoCAD需要引用的dll完全不相同. 需要去AutoCAD官网下载对应版本的AutoC ...

最新文章

  1. 第32章:MongoDB-索引--Capped固定集合
  2. boost::detail::sp_convertible相关的测试程序
  3. oracle12c考试内容,12c ocp考试内容
  4. java如何解压rar文件怎么打开,java解压rar文件
  5. 及时复盘的好处_复盘,组织和个人提升的一种特效工具
  6. 小程序分享如何自定义封面?
  7. ADO.NET 如何读取 Excel (下)
  8. Virtualbox 2.1突发性错误解决办法(也许是BUG)
  9. linux 命令快捷,Linux常见命令快捷方式(示例代码)
  10. class在java中_class在java里是什么意思
  11. javaweb开发后端常用技术_java web后端开发技术
  12. LoadRunner教程(7)-LoadRunner 创建测试场景
  13. Linux radius客户端,FreeRadius客户端基础配置及测试
  14. 【降维打击】解决加密视频录屏问题
  15. IDA F5堆栈不平衡的处理
  16. excel每行按模板导出为一个excel文件,可以指定列文本生成二维码或者条形码
  17. 关于黑马视频String 与int之间相互转化
  18. S32K116调试记录(1)SWD接口调试
  19. 学会这三招引流方法,让你的淘宝店铺流量暴增
  20. Java猿社区—Redis一篇系列—第一章、NoSql入门和概述

热门文章

  1. 硬盘重新分区怎么操作?硬盘分区软件推荐
  2. 常用的Dos界面指令及快捷键
  3. 笔记本电脑如何开启关闭触摸板?
  4. 迅为iTOP-STM32MP157开发板发布
  5. python相关职业-浅谈Python全栈开发工程师,让程序员都眼红的职业!
  6. 求职计算机科学,计算机科学*求职信
  7. 定义未清过账期间变式
  8. 学会这些终端快捷键,让你在Linux上的操作快100倍
  9. 警觉室内点缀污染闻气味判别陷误区
  10. win7玩CF不能全屏显示