基于后置摄像头的CoreLocation标题(增强现实) [英] CoreLocation heading base on back camera (Augmented reality)

查看:181
本文介绍了基于后置摄像头的CoreLocation标题(增强现实)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个增强现实视图,它将指向一个方向的对象。但是,当您面向相机时,CoreLocation标题无法正常工作(当您在一楼时,请指向20层楼的顶部)。

I would like to create an augmented reality view that is going to point an object in a direction. However, the CoreLocation heading is not working correctly when you are facing upwards with your camera (say to a top of a 20-storeys building when you are on the ground floor).

这是相反的方向(可能是指向电话顶部的方向)。

It is giving the opposite direction (probably the direction that is pointing by the top of the phone).

我尝试了一些方法让它适用于相机指向的方向,例如:

I have tried a few methods to get it to work for the direction the camera is pointing, such as:

1,当设备方向> 45时+180度度数(不够准确,突然方向偏离10~20度)

1, +180 degree when the device orientation is > 45 degree (not accurate enough, suddenly the direction goes off by 10~20 degree)

2,尝试使用CMMotionManager计算下面的教程中的公式。
http://www.loveelectronics.co .uk / Tutorials / 13 / tilt-compensated-compass-arduino-tutorial

2, attempted to calculate using CMMotionManager with formula from the below tutorial. http://www.loveelectronics.co.uk/Tutorials/13/tilt-compensated-compass-arduino-tutorial.

3,尝试使用ios deviceMotion.magneticField模拟来自android的逻辑deviceMotion.gravity。

3, attempted to simulate logic from android using ios deviceMotion.magneticField and deviceMotion.gravity.

4,使用旋转矩阵(堆栈溢出中的其他一些帖子,但不准确)

4, use rotation matrix (some other post in stack overflow, but not accurate)

    double heading = M_PI + atan2(self.altitudeData.rotationMatrix.m22, self.altitudeData.rotationMatrix.m12);
    heading = heading*180/M_PI;

我已经不知道还有什么可以尝试让它正确。我知道有一些应用程序(一些可以看到太阳和星星的应用程序)正确地执行它。

I am running out of idea what else could I try to get it right. I know there are some apps out there (some app that can see the sun and star) that is doing it correctly.

推荐答案

经过大量的研究和测试。我最终使用GLKit进行计算,因为它也省去了很多麻烦。只要把它留在这里就可以解决这个问题。

After much of research and testing. I ended up using GLKit for the calculation, as it saves me lots of trouble as well. Just leave it here for anyone who happen to get to this question.

首先,我用CMAttitudeReferenceFrameXTrueNorthZVertical开始了CMMotionManager设备运动更新。

First, I started the CMMotionManager device motion updates with CMAttitudeReferenceFrameXTrueNorthZVertical.

self.hasMotion = NO;
CMMotionManager *cmmotionManager = [[CMMotionManager alloc] init];
[cmmotionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXTrueNorthZVertical
                                                     toQueue:[[NSOperationQueue alloc] init]
                                                 withHandler:^ (CMDeviceMotion *motion, NSError *error) {
                                                     self.hasMotion = YES;


                                                 }];
self.motionManager = cmmotionManager;

从我在网上找到的一些代码中使用CoreMotion旋转绘制一个openGL世界并将其与从屏幕到3D世界获得一个点:

From some codes that I found on the web to draw an openGL world using CoreMotion rotation and mix it with getting a point from screen to 3D world:

float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(45.0f), aspect, 0.1f, 100.0f);

CMRotationMatrix r = self.motionManager.deviceMotion.attitude.rotationMatrix;
GLKMatrix4 camFromIMU = GLKMatrix4Make(r.m11, r.m12, r.m13, 0,
                                       r.m21, r.m22, r.m23, 0,
                                       r.m31, r.m32, r.m33, 0,
                                       0,     0,     0,     1);

GLKMatrix4 viewFromCam = GLKMatrix4Translate(GLKMatrix4Identity, 0, 0, 0);
GLKMatrix4 imuFromModel = GLKMatrix4Identity;
GLKMatrix4 viewModel = GLKMatrix4Multiply(imuFromModel, GLKMatrix4Multiply(camFromIMU, viewFromCam));
bool isInvertible;
GLKMatrix4 modelView = GLKMatrix4Invert(viewModel, &isInvertible);

int viewport[4];
viewport[0] = 0.0f;
viewport[1] = 0.0f;
viewport[2] = self.view.frame.size.width;
viewport[3] = self.view.frame.size.height;

bool success;
//assume center of the view
GLKVector3 vector3 = GLKVector3Make(self.view.frame.size.width/2, self.view.frame.size.height/2, 1.0);     
GLKVector3 calculatedPoint = GLKMathUnproject(vector3, modelView, projectionMatrix, viewport, &success);
if(success)
{
    //CMAttitudeReferenceFrameXTrueNorthZVertical always point x to true north
    //with that, -y become east in 3D world
    float angleInRadian = atan2f(-calculatedPoint.y, calculatedPoint.x);
    return angleInRadian;
}

这篇关于基于后置摄像头的CoreLocation标题(增强现实)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆