【问题标题】:pitch returned by getOrientation function is wronggetOrientation 函数返回的音高错误
【发布时间】:2021-06-03 16:00:16
【问题描述】:

旧的Sensor.TYPE_ORIENTATION 传感器返回 -180° 和 180° 之间的俯仰角。这是一个不错的 API,它包含过滤功能并且效果很好。遗憾的是,Sensor.TYPE_ORIENTATION 已被弃用,并且无法在现代手机上使用。

Sensor.TYPE_ORIENTATION 的有福替换是 Context.SENSOR_SERVICETYPE_MAGNETIC_FIELD 以及 SensorManager.getRotationMatrix()SensorManager.getOrientation() 函数的复杂组合。在过滤方面,您只能靠自己。 (顺便说一句,我使用了 iirj - 我在 Stackoverflow 上找到的琐碎低通滤波器效果不如 Sensor.TYPE_ORIENTATION 所做的那样)

getOrientation 的文档声称它返回 -π 到 π 之间的间距。这不可能是真的,因为实现是 values[1] = (float) Math.asin(-R[7]);asin 返回的值在 -π/2 和 π/2 之间)

有什么方法可以从旋转矩阵中获得完整的 360° 俯仰和横滚?

【问题讨论】:

标签: android matrix geometry android-sensors


【解决方案1】:

这是一个known issue,Google 不会修复它。我基于Gregory G. Slabaugh's paper创建了自己的getOrientation函数

// Based on pseudo code from http://www.close-range.com/docs/Computing_Euler_angles_from_a_rotation_matrix.pdf
object EulerAngleHelper {
    private const val R11 = 0
    private const val R12 = 1
    private const val R13 = 2
    private const val R21 = 3
    private const val R22 = 4
    private const val R23 = 5
    private const val R31 = 6
    private const val R32 = 7
    private const val R33 = 8
    private const val AZIMUTH = 0
    private const val PITCH = 1
    private const val ROLL = 2
    private const val PHI_Z = AZIMUTH
    private const val PSI_X = PITCH
    private const val THETA_Y = ROLL

    fun getOrientation(r: DoubleArray, values: DoubleArray): DoubleArray {
        when {
            r[R31] < -0.98 -> {
                values[PHI_Z] = 0.0 // Anything; can set to 0
                values[THETA_Y] = Math.PI / 2
                values[PSI_X] = values[PHI_Z] + atan2(r[R12], r[R13])
            }
            r[R31] > 0.98 -> {
                values[PHI_Z] = 0.0 // Anything; can set to 0
                values[THETA_Y] = -Math.PI / 2
                values[PSI_X] = values[PHI_Z] + atan2(-r[R12], -r[R13])
            }
            else -> {
                values[THETA_Y] = -asin(r[R31])
                val cosTheta = cos(values[THETA_Y])
                values[PSI_X] = atan2(r[R32] / cosTheta, r[R33] / cosTheta)
                values[PHI_Z] = atan2(r[R21] / cosTheta, r[R11] / cosTheta)
            }
        }
        return values
    }
}

我只测试了俯仰和滚动。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-28
    • 2014-07-24
    • 2021-12-13
    • 2021-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多