Отрегулируйте данные ускорения для глобальной системы отсчета - PullRequest
0 голосов
/ 16 апреля 2020

При работе с Core Motion ускорение всегда возвращается по отношению к устройству. Это означает, что если вы потрясете экран устройства вверх, он будет в +/- Z (в зависимости от исходного задания), если затем повернуть устройство в сторону и встряхнуть вверх и вниз, так же, как и раньше, ускорение будет в + / -X или Y.

Я хочу преобразовать это устройство, указывающее c ускорение, обратно в «глобальный» кадр. Это означает, что при одинаковых физических движениях устройства данные ускорения возвращаются на одну и ту же ось независимо от ориентации устройства при встряхивании.

Например, если мы встряхиваем устройство вверх и вниз, с экраном вверх, оно попадает в 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
    }
...
}

Конечная цель - поместить компонент «вверх / вниз» в БПФ, чтобы попытаться найти частоту движения.

Является ли вращение вектора ускорения правильным подходом? Есть ли лучший способ добиться независимого ускорения? Или, что еще лучше, найдите частоту движения устройства независимо от ориентации!

1 Ответ

0 голосов
/ 17 апреля 2020

Мне удалось убедиться, что это действительно способ «вращать» данные ускорения.

В качестве примечания вместо того, чтобы использовать первый кадр в качестве эталона, я упростил его и использовал кватернион

let referenceFrame = simd_inverse(simd_quatd(ix: 0,iy: 0,iz: 0,r: 1))

, затем для обработки скорректированного ускорения я делаю: * Z-компонент 1008 *

let userAcceleration = motion.userAcceleration.toSIMD

let adjusted = simd_act(simd_mul(referenceFrame, motion.attitude.quaternion.toSIMD), userAcceleration)

adjusted будет затем вверх / вниз в глобальном фрейме.

Я делал это в режиме реального времени без каких-либо проблем.

...