开发简介
- 开发主题:VR复位和定位追踪.
- 参与人员:helen,ice,bikasuo.(VR开发者QQ群:538874606)
- 项目代码
- gitter讨论链接
分享一下我们对于这方面问题的一些看法,文档可能存在一些错误和不足,希望能够得到大家的批评和建议,希望与大家一起将这部分内容做的更加完善,持续更新.可以随意复制使用,方便的话注明一下出处,不胜感谢!
复位
- 复位介绍
玩VR游戏的人经常能发现这样的现象,你坐在一个固定的位置上,开始游戏时,你可能是正对着游戏的正前方:
激情几分钟后,在回到这个画面时,面对相同的方向,实际显示的画面已经偏离了原来的方向,例如:
这是一个典型的陀螺仪漂移的情况,为了消除这异常情况,需要进行一次复位操作,使面面重新回到最初的方向上;或则当你在玩VR游戏时,移动头部调整到画面为正方向上时,你面对的方向是北,但是你想朝着方向为南的地方玩,这时需要在南方向上触发一个复位,将画面正方向”拉”过来;或则添加一些特殊功能,例如某些定位方案只有180度范围的定位,扩展定位方案从180—>360度,需要做”一键转身的功能”.目前市面上的各种VR设备都会提供复位的操作. 那么我们就来聊聊VR的复位功能.
复位包括,姿态(rotation)/位置(position)的复位.
姿态的复位:将当前姿态设置为新的原点,这个原点是指在应用的正面方向(多数情况为Yaw为0度的方向,这里暂时也只讨论Yaw为0度的正方向情况,openvr_survivor支持任意Yaw角度复位),**姿态的复位目前多数平台都只对Yaw方向执行复位操作,Pitch和Roll参与复位操作,因为磁力计能确保Yaw方向正确,而没有其他传感器能作为Pitch和Roll的准确位置参考,复位流程如下:
位置的复位:将当前位置设置为新的原点,这个原点是指位置为(0,0,0)的位置,这个比较好理解,在steamVR里是地上绿色圈圈的中心.目前位置定位的方案大多都是绝对坐标,没有累计漂移的问题,一般不需要复位位置.
- 如何实现复位功能
实现复位的操作,可以在平台层\应用层\硬件驱动层做这个操作,不论在哪层实现,实现起来的方法都一样,都是对被追踪物体的四元素进行处理.这里,关于复位功能的讨论,个人认为是在平台层实现复位的方法,然后向硬件驱动层和应用层分别提供接口来统一管理比较好,但steamVR目前的情况是没有统一,比较混乱另外复位的算法在几大平台都只提供接口,而不开放源代码,后来自己把复位功能实现,觉得这些并不复杂(花点时间大家基本都能实现),VR目前这行业处于技术爬坡,并且不挣钱的时候,没必要把这些功能封闭起来,浪费大部分开发者的时间,所以创建开源openvr_survivor项目,把一些VR基础技术实现,并分享,和更多的开发者一起推动VR的发展,额,想的有点多~.回归正题,复位功能实现的思路,之前在openvr的issue里讨论过.
按下复位按键或APP里的复位按钮(在触发前最好保持静止状态,这样yaw的角度会比较稳定),第一步先获取当前yaw角度值:
然后在每次上报物体四元素之前,对yaw做偏移:
对应的主要代码:
//get yaw offset
m_dRecenterYawOffset = simple_math::GetYawDegree(m_OriginRotation)
//DoOrientationRecenter
inline vr::HmdQuaternion_t DoOrientationRecenter(const vr::HmdQuaternion_t quaternion_origin,const double yaw_offset){
double yaw_degree_new,yaw_degree_origin
vr::HmdVector3d_t degree
vr::HmdQuaternion_t quaternion_dest
//get origin yaw from quaternion
degree = simple_math::QuaternionToEulerDegree(quaternion_origin)
yaw_degree_origin = degree.v[0]
LOG_EVERY_N(INFO,5 * 60) << "DoOrientationRecenter[0]:quat(" << quaternion_origin.w << "," << quaternion_origin.x << ","
<< quaternion_origin.y << "," << quaternion_origin.z << "),degree(" << degree.v[0] << "," << degree.v[1] << ","
<< degree.v[2] << "),yaw_offset=" << ya