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 << \; for( int i=0; i < a.num_channel; i++ ) { cout << a.channel[i] << \; } cout << endl; } 这个回调有一个vrpn_ANALOGCB参数,包含了在'channel'数组中的更新值。Analog的channels的数目可以在vrpn_ANALOGCB结构的num_channel成员中找到。
现在我们唯一要确定的是vrpn_Analog_Remote对象能够正确的更新。 while(1) { vrpnAnalog->mainloop(); } 2014-03-25
DTrack :http://www.hitlab.utas.edu.au/wiki/DTrack
在VisionSpace中,Studio是一个跟踪系统,它有能力观察反射回来被标记物的位置和角度的变化。现在可获得的标记物是”Spikey”,”Glasses”,”Flystick2”,后来又有了按钮和八向轮(analog joystick)。所有的这些标记物都可以同时被成功的捕捉。对于“Glasses”并不建议在用于头部跟踪的其他时候使用,因为当速度很快时这些会不再显示而失去信号。
由于在场景中只有四个相机,因此每一个标记物必须有三个点。
通过VRPN获得被标记物
Vrpn是一个开源的软件接口,她为在虚拟显示软件中使用的跟踪设备之间的交
流提供软件接口。DTrack能很好的支持VRPN,不管是被标记物还是flysticks,只要是能在VRPN客户端得到的设备。
由于VRPN将DTrack作为一个单独的设备,尽管它由多个独立的带有按钮的标记,每个标记被认为是在一组TrackerRemote ButtonRemote DTrack AnalogRemote中的一个单独传感器。被标记物的位置和角度数据在一个TrackRemote中编码,然而每个flystick的按钮和模拟杆在一个ButtonRemote和AnalogRemote中编码。每个ButtonRemote将为每个flystick分配8按钮(max)和2个类似物(水平/垂直)。
来自ButtonRemote和AnalogRemote设备的数据是没有身份可以区分的标记的,只有TrackerRemote设备,这可能会导致轻微的混乱如果被动标记和Flysticks同时使用。每个ButtonRemote将有8按钮分配给每个Flystick2 Flystick2 # 1小组编号,Flystick2 # 2地位等等;AnalogRemote也是如此,但每个Flystick2 有2个类似物。
VRPN:Flystick2 DTrack Console Application
准备: 一个C++编译器,VRPN(编译了库文件和头文件)
创建一个新的C++项目,你将需要3个文件:Flystick.h,Flystick.cpp,VRPNFlystickConsole.cpp(主要的方法都在这个函数中)。然后包含一些VRPN头文件到你的项目中:vrpn_Tracker.h,vrpn_Button.h,vrpn_Analog.h,quat.h(在quat包中)。
编写Flystick头文件:
在头文件中定义Flystick类
我们需要在每次更新时保存这些数据,包括位置,角度,analog,button。定义如下:
每次调用mainloop()时vrpn将会根据server处理更新信息。处理完后将会调用我们写的更新函数,一些此类模板如下:
还需要添加两个函数:
Flystick类的实现非常简单,我们只需要初始化的静态变量,编写一个构造函数和更新函数,回调函数在头文件处理更新Flystick的状态,首先初始化静态变量:
我们使用DTrack VRPN server 的地址初始化我们所创建的每一个远程遥控,注册回调函数并且忽略远程遥控端的警告。
回调函数将会被用户频繁的调用,因为它只处理在缓存中的旧的UDP包,如果程序需要很长时间打电话给UpdateFlystick这可能引入一些滞后的标记。
为了提供独立的输出,我们提供了一个非常简单的主函数,它将会持续不断的更新和输出flystick的状态直到程序结束。VRPNFlystickConsole.cpp:
#include \#include \#include
int _tmain(int argc, _TCHAR* argv[]) {
Flystick *flystick = new Flystick(\
// Endless update loop while (true) {
// Update the flystick remotes flystick->UpdateFlystick();
// Clear console system(\
// Output updated data
printf(\%d\\nY: %d\\nZ: %d\flystick->_position[0], flystick->_position[1], flystick->_position[2]); printf(\flystick->_eulerOrientation[0], flystick->_eulerOrientation[2]);
%d\\nPitch: %d\\nRoll: %d\flystick->_eulerOrientation[1],
printf(\0 Pressed? %i\\nButton 1 Pressed? %i\\nButton 2 Pressed? %i\\nButton 3 Pressed? %i\\nButton 4 Pressed? %i\\nButton 5 Pressed? %i\
flystick->_buttonState[0], flystick->_buttonState[1], flystick->_buttonState[2], flystick->_buttonState[3], flystick->_buttonState[4], flystick->_buttonState[5]); printf(\stick:\\nHorizontal: %d\\nVertical: flystick->_analogHorizontal, flystick->_analogVertical); }
return 0;
%d\