Android: 如何同步多个IMU传感器(Accelerometer/Gyroscope/Magnetic)?

Android: how to synchronise multiple IMU sensors(Accelerometer/Gyroscope/Magnetic)?

我目前正在开发一个 android 应用程序,该应用程序收集用于定位的 IMU 数据(加速度计、陀螺仪和磁场),这需要非常高的测量时间精度。所有三个传感器都设置为 SENSOR.DELAY.FASTEST,这是我的代码。

    @Override
    public void onSensorChanged(SensorEvent sensorEvent) {
        final float alpha = 0.97f;
        //in milliseconds since last boot
        time = SystemClock.elapsedRealtime();

        switch (sensorEvent.sensor.getType()){
            case Sensor.TYPE_ACCELEROMETER:
                Log.d(TAG,"TYPE_ACCELEROMETER: "+sensorEvent.timestamp);
                //System.arraycopy(sensorEvent.values,0,LastAccReading,0,sensorEvent.values.length);
                LastAccReading[0] = alpha * LastAccReading[0] + (1-alpha) * sensorEvent.values[0];
                LastAccReading[1] = alpha * LastAccReading[1] + (1-alpha) * sensorEvent.values[1];
                LastAccReading[2] = alpha * LastAccReading[2] + (1-alpha) * sensorEvent.values[2];
                break;

            case Sensor.TYPE_MAGNETIC_FIELD:
                Log.d(TAG,"TYPE_MAGNETIC_FIELD: "+sensorEvent.timestamp);
                //System.arraycopy(sensorEvent.values,0,LastMagReading,0,sensorEvent.values.length);
                LastMagReading[0] = alpha * LastMagReading[0] + (1-alpha) * sensorEvent.values[0];
                LastMagReading[1] = alpha * LastMagReading[1] + (1-alpha) * sensorEvent.values[1];
                LastMagReading[2] = alpha * LastMagReading[2] + (1-alpha) * sensorEvent.values[2];
                break;

            case Sensor.TYPE_GYROSCOPE:
                Log.d(TAG,"TYPE_GYROSCOPE: "+sensorEvent.timestamp);
                LastGyroReading[0] = sensorEvent.values[0];
                LastGyroReading[1] = sensorEvent.values[1];
                LastGyroReading[2] = sensorEvent.values[2];
        }

        // Rotation matrix based on current readings from accelerometer and magnetometer.
        SensorManager.getRotationMatrix(rotationMatrix, inclinationMatrix,
                LastAccReading, LastMagReading);
        // Express the updated rotation matrix as three orientation angles.
        SensorManager.getOrientation(rotationMatrix, orientationAngles);

        //Log.i("OrientationTestActivity",String.format("Orientation: %f, %f, %f", orientationAngles[0], orientationAngles[1], orientationAngles[2]));
    }

通过查看 sensorEvent.timestamp enter image description here 我可以看到加速度计和陀螺仪在 420Hz 左右具有相同的采样率,而磁场在 100Hz 左右要慢得多。并且加速度计和陀螺仪不会同时返回传感器值,这意味着在某个时间戳,三个传感器值中只有一个有效,另外两个会有几毫秒的时间偏移。

我能做些什么吗?提前致谢。

消费者传感器不是最准确的,并且会受到噪声和漂移的影响(查看任何 IMU 数据表以了解详细信息)。对于常见用例,它们足够准确。

任何基于 Android 的传感器至少需要符合 Android Compatibility Definition Document section on Sensors

由于设备中的传感器不是一个新主题,观看这个关于传感器融合的旧 Google 会谈视频可能会有所帮助:Sensor Fusion on Android Devices: A Revolution in Motion Processing

虽然您可能担心不同的时间戳,但我相信您想要的精度水平是不现实的,因为传感器具有噪声容限并且会漂移到它们的值。

至于开发人员在给定现有误差范围的情况下所做的事情,假设用例是人体运动,传感器数据通常会随时间 and/or 通过 low-pass 过滤器进行平均。对于大多数用例来说,这已经足够了,但正如 this article on ARCore and ARKit 中所述,在那些支持 AR 的设备上,认证这些设备中的传感器将需要更严格(且成本最高)的校准。

那些尝试 VR/AR 类型行为的人可能正在使用 SensorDirectChannel but be aware of the stated rate variance and hardware/OS limitations.