ios - 将加速度数据调整到全球参考框架
问题描述
使用 Core Motion 时,加速度似乎总是相对于设备返回。这意味着如果您向上摇动设备屏幕,它将处于 +/-Z(取决于初始参考)如果您将设备转向一侧并上下摇动,与以前一样,加速度将在 + /-X 或 Y。
我想将此设备特定的加速度转换回“全局”框架。这意味着设备的相同物理运动会导致加速度数据在同一轴上返回,而不管设备在摇晃时的方向如何。
例如,如果我们上下摇晃设备,屏幕朝上,它会进入 z 轴,然后如果您旋转设备使屏幕朝前并进行同样的摇晃,z 轴仍会显示加速度,即使使用相对于设备,它是 Y 轴。
我一直在尝试将加速度旋转回初始姿态,看起来它有时有效,有时无效。我不相信轮换是正确的方法。我不确定它是否是合理的数学,或者有时只是随机看起来正确。
extension CMQuaternion {
var toSIMD: simd_quatd {
return simd_quatd(ix: x, iy: y, iz: z, r: w)
}
}
extension CMAcceleration {
var toSIMD: SIMD3<Double> {
return SIMD3<Double>(x,y,z)
}
}
然后像这样进行计算:
var reference: simd_quatd?
motionManager.startDeviceMotionUpdates(using: .xArbitraryZVertical, to: .main) { deviceMotion, error in
guard let deviceMotion = deviceMotion else { return }
let userAcceleration = deviceMotion.userAcceleration.toSIMD
let adjusted: SIMD3<Double>
if let ref = reference {
// rotate the userAccel by the inverse of the reference times the current attitude.
adjusted = simd_act(simd_mul( simd_inverse(ref.quaternion.toSIMD),deviceMotion.attitude.quaternion.toSIMD), userAcceleration)
} else {
reference = deviceMotion.attitude.quaternion.toSIMD
adjusted = userAcceleration
}
...
}
最终目标是将“上/下”组件放入 FFT 中,以尝试找出运动的频率。
旋转加速度矢量是正确的方法吗?有没有更好的方法来实现与姿态无关的加速度?或者更好的是,无论方向如何,都能找到设备运动的频率!
解决方案
我能够验证这确实是一种“旋转”加速度数据的方法。
作为注释而不是使用第一帧作为参考,我简化了它并使用了四元数
let referenceFrame = simd_inverse(simd_quatd(ix: 0,iy: 0,iz: 0,r: 1))
然后为了处理调整后的加速度我做:
let userAcceleration = motion.userAcceleration.toSIMD
let adjusted = simd_act(simd_mul(referenceFrame, motion.attitude.quaternion.toSIMD), userAcceleration)
adjusted
的 Z 分量将在全局框架中向上/向下。
我一直在实时执行此操作,没有任何问题。
推荐阅读
- python - Pyspark:to_timestamp 返回不正确的时间戳值
- powerbi - 如何防止电源查询获取合并源表的数据?
- jmeter - 将响应时间数据从 Jmeter 获取到 csv
- windows - 手动写入页表条目 (PTE) 时如何防止 Windows 内核锁定
- machine-learning - NLP 中如何处理字母文件?
- javascript - 如何在 Vuetify 中不使用“md/sm”将所有图块设置为特定宽度?
- json - 我可以在 C# 中反序列化 JSON 数组吗
- regex - grep(POSIX)正则表达式浮点数在单行空格之间
- php - Razorpay 通过令牌定期付款
- javascript - 我在运行 node.js 文件时出错