无论用户如何握住手机,我都会搜索一种检测手机移动的方法.
一些例子:
背景是我想要识别用户是否将手机从口袋中取出(例如向上拉30-40厘米,也可以在水平方向上拉几厘米).
我认为因此我必须从userAcceleration和态度中获得一个组合.但我没有找到正确的数学..
我实际上是想用QRKode将3D对象放在QRCode上 为此我使用AVCaptureDevice来检测QRCode并建立QRCode的区域,它给我一个CGRect.然后,我在CGRect的每个点上进行一次hitTest来获得平均3D坐标,如下所示:
positionGiven = SCNVector3(0, 0, 0)
for column in Int(qrZone.origin.x)...2*Int(qrZone.origin.x + qrZone.width) {
for row in Int(qrZone.origin.y)...2*Int(qrZone.origin.y + qrZone.height) {
for result in sceneView.hitTest(CGPoint(x: CGFloat(column)/2,y:CGFloat(row)/2), types: [.existingPlaneUsingExtent,.featurePoint]) {
positionGiven.x+=result.worldTransform.columns.3.x
positionGiven.y+=result.worldTransform.columns.3.y
positionGiven.z+=result.worldTransform.columns.3.z
cpts += 1
}
}
}
positionGiven.x=positionGiven.x/cpts
positionGiven.y=positionGiven.y/cpts
positionGiven.z=positionGiven.z/cpts
Run Code Online (Sandbox Code Playgroud)
但是hitTest没有检测到任何结果并冻结相机,而当我通过屏幕上的触摸进行hitTest时它可以工作.你知道它为什么不起作用吗?你有其他想法可以帮助我实现我想做的事吗?
我已经考虑过使用CoreMotion进行3D翻译,它可以让我倾斜设备,但这看起来真的很乏味.我也听说过可以锁定场景坐标以匹配相机方向的ARWorldAlignmentCamera,但我不知道如何使用它!
编辑:我每次触摸屏幕时尝试移动我的3D对象并且hitTest为正,并且它非常准确!我真的不明白为什么像素区域上的hitTest不起作用...
编辑2:以下是在屏幕上使用2-5次触摸的hitTest的代码:
@objc func touch(sender : UITapGestureRecognizer) {
for result in sceneView.hitTest(CGPoint(x: sender.location(in: view).x,y: sender.location(in: view).y), types: [.existingPlaneUsingExtent,.featurePoint]) {
//Pop up …Run Code Online (Sandbox Code Playgroud) 我在为Core Motion实例化我的CMMotionManager对象时遇到了崩溃.这是在运行iOS 12.0.1的iPhone X上.
我可以通过单视图应用程序使用以下视图控制器可靠地重现这一点.
import UIKit
import CoreMotion
class ViewController: UIViewController {
var motion: CMMotionManager?
override func viewDidLoad() {
super.viewDidLoad()
// This causes a crash on iPhone Xs, iOS 12.0.1
self.motion = CMMotionManager()
}
}
Run Code Online (Sandbox Code Playgroud)
完整示例项目位于https://github.com/doctorcolinsmith/motiontestcrash/tree/master
运行上面的代码时,我在调试器中输出以下输出的线程上出现故障.
=================================================================
Main Thread Checker: UI API called on a background thread: -[UIApplication applicationState]
PID: 3634, TID: 630341, Thread name: com.apple.CoreMotion.MotionThread, Queue name: com.apple.root.default-qos.overcommit, QoS: 0
Backtrace:
4 libobjc.A.dylib 0x000000019b0d3894 <redacted> + 56
5 CoreMotion 0x00000001a19337a4 CoreMotion + 305060
6 CoreMotion 0x00000001a1933cd8 …Run Code Online (Sandbox Code Playgroud) 使用CMAttitude的正确方法是什么:multiplyByInverseOfAttitude?
假设iOS5设备平放在桌面上,在启动CMMotionManager后:
CMMotionManager *motionManager = [[CMMotionManager alloc]init];
[motionManager startDeviceMotionUpdatesUsingReferenceFrame:
CMAttitudeReferenceFrameXTrueNorthZVertical];
Run Code Online (Sandbox Code Playgroud)
稍后,获取CMDeviceMotion对象:
CMDeviceMotion *deviceMotion = [motionManager deviceMotion];
Run Code Online (Sandbox Code Playgroud)
我希望[deviceMotion attitude]反映设备从True North的旋转.
通过观察,[deviceMotion userAcceleration]报告设备参考框架中的加速度.也就是说,将设备左右移动(保持平放在桌面上)可以记录x轴上的加速度.将设备旋转90°(仍然是平坦的)并将设备左右移动仍然会报告x加速度.
转换[deviceMotion userAcceleration]以获得南北/东西加速而不是左右/前后加速的正确方法是什么?
CMAttitude multiplyByInverseOfAttitude似乎是不必要的,因为已经指定了参考框架,并且从文档中不清楚如何将态度应用于CMAcceleration.
我有一个应用程序,当用户在对象周围走动时记录角度,同时将设备(最好)指向对象的中心.角度会根据用户的命令重置 - 因此参考态度会重置.
使用欧拉角产生万向节锁,所以我目前使用四元数并以这种方式计算角度:
double angleFromLastPosition = acos(fromLastPositionAttitude.quaternion.w) * 2.0f;
Run Code Online (Sandbox Code Playgroud)
这样可以提供良好的精度,并且它可以很好地工作,因为设备的俯仰和偏航不会改变.换句话说,当角度显示360度时,我最终在与圆的开始相同的位置.
问题1:如果设备的偏航和俯仰稍微改变(用户不直接指向物体的中心),angleFromLastPosition也是如此.我理解这一部分,因为我的角度公式只显示了3D空间中两个设备态度之间的角度.
场景:
问题1是,如何仅使用四元数计算设备的滚动,并忽略其他两个轴的变化(至少在某个合理的度数范围内).
问题2:如果我旋转一点然后完全冻结设备(在三脚架上没有任何振动),angleFromLastPosition以大约10-20秒的1度漂移,并且看起来不是线性的.换句话说,它首先快速漂移,然后大幅减速.有时我根本没有漂移 - 如果设备静止,角度是坚如磐石的.这让我迷失了解正在发生的事情.
问题2,这里发生了什么,我该如何处理漂移?
我经历了不少文章和教程,目前四元数学已经超出了我的范围,希望有人能够提供一些提示,链接或几行代码.
我收到CMLogItem来自 swift 的 CoreMotion 查询(可能是加速度计、陀螺仪)。现在,我想获取该样本的时间戳,最好是 Date() 对象。s 具有类型 的CMLogItem属性。.timestampTimeInterval
该文档告诉我以下内容:
CMLogItem 类定义了一个只读时间戳属性,用于记录进行运动事件测量的时间。
但是,我不确定如何将此时间戳转换为 Date() 对象,因为我不知道时间戳指的是什么。
另一个文档说:
时间戳是自设备启动以来的时间量(以秒为单位)。
但这看起来真的很奇怪,我不明白为什么苹果会创建如此不一致且复杂的 API。
我一直在这里找到的iphone增强现实框架之上构建, 但遗憾的是,在没有陀螺仪的手机(即3GS)上,它不起作用(正如它所说的那样).
有没有人知道修复它使运动传感器和指南针标题相反?或者是否有人会如此富裕地为这样的框架提供代码?
我需要一种方法来使矢量工作,如果不可能,我将需要推进并只使用标题.
所以我有这个应用程序我正在努力你可以通过倾斜设备(加速度计)在屏幕上滚动球.我怎样才能改变下面的代码,这样我就不必将手机保持平衡,并将其作为我的中立平衡点.我想要的是,无论你在应用程序加载时对设备的任何倾斜,这都是神经平衡点.从当前角度来看,您握住设备即中性点.中立平衡点意味着球几乎仍然存在的点.希望这清楚我想要什么.该应用程序也只是landscapeRight.
注意下面的代码100%正常工作,就像它需要它为我的应用程序工作.我需要保持手机平放滚动球...
CGRect screenRect;
CGFloat screenHeight;
CGFloat screenWidth;
double currentMaxAccelX;
double currentMaxAccelY;
@property (strong, nonatomic) CMMotionManager *motionManager;
-(id)initWithSize:(CGSize)size {
//init several sizes used in all scene
screenRect = [[UIScreen mainScreen] bounds];
screenHeight = screenRect.size.height;
screenWidth = screenRect.size.width;
if (self = [super initWithSize:size]) {
self.motionManager = [[CMMotionManager alloc] init];
self.motionManager.accelerometerUpdateInterval = .2;
[self.motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue currentQueue]
withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {
[self outputAccelertionData:accelerometerData.acceleration];
if(error)
{
NSLog(@"%@", error);
}
}];
}
return self;
}
-(void)outputAccelertionData:(CMAcceleration)acceleration{
currentMaxAccelX = 0;
currentMaxAccelY = 0;
if(fabs(acceleration.x) …Run Code Online (Sandbox Code Playgroud) 我尝试在Swift中使用运动管理器,但我的更新块中的日志从不打印.
var motionManager: CMMotionManager = CMMotionManager()
motionManager.accelerometerUpdateInterval = 0.01
println(motionManager.deviceMotionAvailable) // print true
println(motionManager.deviceMotionActive) // print false
motionManager.startDeviceMotionUpdatesToQueue(NSOperationQueue.currentQueue(), withHandler:{
deviceManager, error in
println("Test") // no print
})
println(motionManager.deviceMotionActive) // print false
Run Code Online (Sandbox Code Playgroud)
我的Objective-C实现工作正常.有谁知道为什么我的更新块没有被调用?
最近,我在 Xcode 中记录了很多来自 CoreMotion 框架的奇怪警告,这些警告与功能相关getLocationForBundleID:
[Client] {"msg":"#NullIsland Either the latitude or longitude was exactly 0! That's highly unlikely", "latIsZero":0, "lonIsZero":0}
[Client] {"msg":"#NullIsland Received a latitude or longitude from getLocationForBundleID that was exactly zero", "latIsZero":0, "lonIsZero":0, "location":'28 5B E0 D7 EB 7F 00 00'}
Run Code Online (Sandbox Code Playgroud)
我没有看到我的应用程序有任何故障。所以也许这些日志可以被忽略,但无论如何它们都很烦人。
我的问题是:
如何纠正潜在错误?
我怎样才能停止这些警告?
core-motion ×10
ios ×7
swift ×4
3d ×1
arkit ×1
gyroscope ×1
ios12 ×1
ios7 ×1
iphone ×1
objective-c ×1
qr-code ×1
quaternions ×1
rotation ×1
sprite-kit ×1