我的目标是制作一个可以在骑自行车时测量道路质量的 Android 移动应用程序 (SDK16+)。
我找到了一个适用于 Android 的传感器融合演示,我认为它会为我完成所有测量。
当手机未固定在某个方向时,如何仅获得垂直移动?
我的目标是制作一个可以在骑自行车时测量道路质量的 Android 移动应用程序 (SDK16+)。
我找到了一个适用于 Android 的传感器融合演示,我认为它会为我完成所有测量。
当手机未固定在某个方向时,如何仅获得垂直移动?
问题
这里的问题是你有两个坐标系统,你的设备的 dx、dy、dz 和你周围世界的 wX、wY、wZ。当您移动设备时,两者之间的关系会发生变化。
提出问题的另一种方法是说:
给定一个传感器读数 [dx, dy, dz],我如何找到与 wZ 平行的读数分量?
一个解法
幸运的是,方向传感器(例如 Android 自己的ROTATION_VECTOR
传感器)为这两个坐标系之间的转换提供了工具。
例如,ROTATION_VECTOR
传感器的输出以轴角表示的形式出现,表示您的设备从固定在世界框架中的某个“基础”旋转(另请参见:四元数)。
Android 提供了方法SensorManager#getRotationMatrixFromVector(float[] R, float[] rotationVector)
,该方法从传感器获取轴角表示并将其转换为旋转矩阵。旋转矩阵用于将一个参考系中给定的向量转换为另一个参考系(在本例中为 [ World -> Device ])。
现在,您想将设备框架中的测量值转换为世界框架吗?没问题。旋转矩阵的一个很好的特点是旋转矩阵的逆是相反变换的旋转矩阵(在我们的例子中是[设备->世界])。另一个更有趣的事情是旋转矩阵的逆矩阵只是它的转置。
因此,您的代码可以遵循以下行:
public void findVerticalComponentOfSensorValue() {
float[] rotationVectorOutput = ... // Get latest value from ROTATION_VECTOR sensor
float[] accelerometerValue = ... // Get latest value from ACCELEROMETER sensor
float[] rotationMatrix = new float[9]; // Both 9 and 16 works, depending on what you're doing with it
SensorManager.getRotationMatrixFromVector(rotationMatrix, rotationVectorOutput);
float[] accelerationInWorldFrame = matrixMult(
matrixTranspose(rotationMatrix),
accelerometerValue);
// Make your own methods for the matrix operations or find an existing library
accelerationInWorldFrame[2] // This is your vertical acceleration
}
现在,我并不是说这是最好的解决方案,但它应该做你所追求的。
免责声明
将使用传感器融合的设备(包括磁力计)绑在金属框架上可能会产生不一致的结果。由于您的指南针方向在这里无关紧要,我建议使用不涉及磁力计的传感器融合方法。