VRPN的使用

来源:互联网 发布:网络教育哪个专业好考 编辑:程序博客网 时间:2024/06/05 16:41

VRPN是作为一个设备服务的角色。根据自己的设备来配置VRPN,随后就能够以标准方式,非常容易的连接到该服务来获取自己设备的数据。

VRPN是跨平台的,可以再许多OS上运行,包括Windows,Linux以及Mac。

VRPN分为三大类:

tracker:主要是位置(postion)和方位(orientation)信息

analog:主要是轴数据。游戏杆轴向数据,鼠标轴向数据

button:二进制按钮,游戏杆按钮以及鼠标按钮

比如,鼠标有一个2通道的模拟数据(x,y轴0~1)以及一个3通道的模拟数据(left middle right)。

一个指挥棒,典型的VR设备,具有追踪器,模拟数据。


首先对鼠标的验证步骤如下:


1.在此网址下载源码。解压,这里解压在F:/temp目录下,它自带了一个V9版的sln,可自己使用CMake VS2013编译,得到自己的VRPN.sln。


在配置工程时,会报一些关于DirectX的warning ,忽略它。继续Generate即可。


2.编译完VRPN.sln之后,得到服务端程序目录:

F:\temp\vrpn\buildout\server_src\Release


客户端程序目录:

F:\temp\vrpn\buildout\client_src\Release


3.打开目录F:\temp\vrpn\server_src,找到vrpn.cfg文件。 使用Notepad打开,找到#vrpn_Mouse Mouse0这行,去掉前面的#。





4.将文件vrpn.cfg拷贝到目录F:\temp\vrpn\buildout\server_src\Release下,CTL+Shift键打开Powershell,运行命令:.\vrpn_server.exe -v



5.再进入目录:F:\temp\vrpn\buildout\client_src\Release,同样使用Powershell运行命令:Mouse0@localhost



其中Mouse0为vrpn.cfg中指定的名字,localhost为服务的网络地址。

移动鼠标或者单击鼠标的左右或中间键时可看到如下输出:



编写一个VRPN客户端程序:

获取analog值测试,创建一个test的工程来测试:

#include "vrpn_Analog.h"#include <iostream>using namespace std;#if 1void VRPN_CALLBACK handle_analog(void *userData, const vrpn_ANALOGCB a){int nbChannels = a.num_channel;cout << "Analog: ";for (int i = 0; i < a.num_channel; i++){cout << a.channel[i] << " ";}cout << endl;}int main(int argc, char *argv[]){vrpn_Analog_Remote* vrpnAnalog = new vrpn_Analog_Remote("Mouse0@localhost");vrpnAnalog->register_change_handler(0, handle_analog);while (1){vrpnAnalog->mainloop();}return 0;}


编译这个需要

1.再添加一下头文件vrpn_analog.h的目录路径:



2.添加vrpn.lib库以及它的目录路径。如下:





编译完后,运行测试程序:



解释:


vrpn_Analog_Remote* vrpnAnalog = new vrpn_Analog_Remote("Mouse0@localhost");

vrpn_Analog_Remote是一个类,它可以让我们的设备连接到一个VRPN的服务,这个服务定义了一个具有模拟输出的驱动。它的构造函数参数是一个设备名加上服务的网络地址。

------------------------------------------------------------------------------------

vrpnAnalog->register_change_handler(0, handle_analog);

注册的回调函数,当有新的数据从vrpn server到来时,它就会被调用。

---------------------------------------------------------------------------------------------

void VRPN_CALLBACK handle_analog(void *userData, const vrpn_ANALOGCB a)
{
int nbChannels = a.num_channel;
cout << "Analog: ";
for (int i = 0; i < a.num_channel; i++)
{
cout << a.channel[i] << " ";
}
cout << endl;
}

该回调函数中有一个类型为vrpn_ANALOGCB的参数,它包含数组channel中已经更新的值。该Analog的通道号可以在vrpn_ANALOGCB结构体中的num_channel成员中找到。

因此下面只要确保vrpn_Analog_Remote对象能够正常更新即可。

while (1)
{
vrpnAnalog->mainloop();
}

=======================================

添加Button和Tracker的测试:

#include "vrpn_Tracker.h"#include "vrpn_Button.h"#include "vrpn_Analog.h"#include <iostream>using namespace std;#if 1void VRPN_CALLBACK handle_analog(void *userData, const vrpn_ANALOGCB a){int nbChannels = a.num_channel;cout << "Analog: ";for (int i = 0; i < a.num_channel; i++){cout << a.channel[i] << " ";}cout << endl;}void VRPN_CALLBACK handle_button(void *userData, const vrpn_BUTTONCB b){cout << "Button " << b.button << ": " << b.state << endl;}void VRPN_CALLBACK handle_tracker(void *userData, const vrpn_TRACKERCB t){cout << "Tracker " << t.sensor << " : " << t.pos[0] << "," << t.pos[1] << "," << t.pos[2] << endl;}int main(int argc, char *argv[]){vrpn_Analog_Remote* vrpnAnalog = new vrpn_Analog_Remote("Mouse0@localhost");vrpn_Button_Remote* vrpnButton = new vrpn_Button_Remote("Mouse0@localhost");vrpn_Tracker_Remote* vrpnTracker = new vrpn_Tracker_Remote("Tracker@localhost");vrpnAnalog->register_change_handler(0, handle_analog);vrpnButton->register_change_handler(0, handle_button);vrpnTracker->register_change_handler(0, handle_tracker);while (1){vrpnAnalog->mainloop();vrpnButton->mainloop();vrpnTracker->mainloop();}return 0;}

暂没有tracker设备,无法获取到,所以输出结果如下:



在vrpn中能够正常输出这些数据,是因为都有相对应的vrpn驱动程序,在不停的获取配置文件中设备的数据。


最后有可能vrpn server程序与vrpn client不在同一台他机器上,因此只需要在代码内修改vrpn服务的网络地址(修改上面的localhost),就可以实现server机访问client上设备数据。

http://www.vrgeeks.org/vrpn/tutorial---use-vrpn