我需要基于加速度计、陀螺仪和磁力计来计算线性加速度。我找到了一个针对Android的应用程序,可以完全实现我的要求:https://play.google.com/store/apps/details?id=com.kircherelectronics.fusedlinearacceleration
。https://github.com/KEOpenSource/FusedLinearAcceleration。
我正试图将其移植到纯Java中。因为代码的某些元素是基于虚拟传感器(重力传感器),所以我想通过计算基于三个基本传感器的重力方向来实现相同的结果。我读到可以使用低通滤波器(与Android <4.0相同)来计算重力的力量,但这种方法并不会给出非常精确的结果。
从Android 4.0开始,每个轴上的重力力被计算为传感器融合。我找到了负责这些测量的代码,但它是用CPP编写的:https://github.com/android/platform_frameworks_base/blob/ics-mr1/services/sensorservice/GravitySensor.cpp。
那里使用的方法称为“getRotationMatrix”。在SensorManager.java类中同样有相同的方法:https://gitorious.org/android-eeepc/base/source/9cb3e09ec49351401cf19b5ae5092dd9ca90a538:core/java/android/hardware/SensorManager.java#L1034。
需要四个参数:
其中一个仅仅是重力...我目前正在处理的代码类似于 https://github.com/KEOpenSource/FusedLinearAcceleration/blob/master/FusedLinearAcceleration/src/com/kircherelectronics/fusedlinearacceleration/sensor/LinearAccelerationSensor.java,除了引用SensorManager的方法。这些方法是从Android源代码中复制过来的: https://gitorious.org/android-eeepc/base/source/9cb3e09ec49351401cf19b5ae5092dd9ca90a538:core/java/android/hardware/SensorManager.java。 我没有找到任何关于如何在Java中实现这个的例子。 所以我的问题是:我怎样可以使用三个基本传感器实现方法(在java中),它返回与Android类似的重力方向数组(x,y,z),但不使用Android API。
我正试图将其移植到纯Java中。因为代码的某些元素是基于虚拟传感器(重力传感器),所以我想通过计算基于三个基本传感器的重力方向来实现相同的结果。我读到可以使用低通滤波器(与Android <4.0相同)来计算重力的力量,但这种方法并不会给出非常精确的结果。
从Android 4.0开始,每个轴上的重力力被计算为传感器融合。我找到了负责这些测量的代码,但它是用CPP编写的:https://github.com/android/platform_frameworks_base/blob/ics-mr1/services/sensorservice/GravitySensor.cpp。
那里使用的方法称为“getRotationMatrix”。在SensorManager.java类中同样有相同的方法:https://gitorious.org/android-eeepc/base/source/9cb3e09ec49351401cf19b5ae5092dd9ca90a538:core/java/android/hardware/SensorManager.java#L1034。
public static boolean getRotationMatrix(float[] R, float[] I,
float[] gravity, float[] geomagnetic) {
// TODO: move this to native code for efficiency
float Ax = gravity[0];
float Ay = gravity[1];
float Az = gravity[2];
final float Ex = geomagnetic[0];
final float Ey = geomagnetic[1];
final float Ez = geomagnetic[2];
float Hx = Ey*Az - Ez*Ay;
float Hy = Ez*Ax - Ex*Az;
float Hz = Ex*Ay - Ey*Ax;
final float normH = (float)Math.sqrt(Hx*Hx + Hy*Hy + Hz*Hz);
if (normH < 0.1f) {
// device is close to free fall (or in space?), or close to
// magnetic north pole. Typical values are > 100.
return false;
}
final float invH = 1.0f / normH;
Hx *= invH;
Hy *= invH;
Hz *= invH;
final float invA = 1.0f / (float)Math.sqrt(Ax*Ax + Ay*Ay + Az*Az);
Ax *= invA;
Ay *= invA;
Az *= invA;
final float Mx = Ay*Hz - Az*Hy;
final float My = Az*Hx - Ax*Hz;
final float Mz = Ax*Hy - Ay*Hx;
if (R != null) {
if (R.length == 9) {
R[0] = Hx; R[1] = Hy; R[2] = Hz;
R[3] = Mx; R[4] = My; R[5] = Mz;
R[6] = Ax; R[7] = Ay; R[8] = Az;
} else if (R.length == 16) {
R[0] = Hx; R[1] = Hy; R[2] = Hz; R[3] = 0;
R[4] = Mx; R[5] = My; R[6] = Mz; R[7] = 0;
R[8] = Ax; R[9] = Ay; R[10] = Az; R[11] = 0;
R[12] = 0; R[13] = 0; R[14] = 0; R[15] = 1;
}
}
if (I != null) {
// compute the inclination matrix by projecting the geomagnetic
// vector onto the Z (gravity) and X (horizontal component
// of geomagnetic vector) axes.
final float invE = 1.0f / (float)Math.sqrt(Ex*Ex + Ey*Ey + Ez*Ez);
final float c = (Ex*Mx + Ey*My + Ez*Mz) * invE;
final float s = (Ex*Ax + Ey*Ay + Ez*Az) * invE;
if (I.length == 9) {
I[0] = 1; I[1] = 0; I[2] = 0;
I[3] = 0; I[4] = c; I[5] = s;
I[6] = 0; I[7] =-s; I[8] = c;
} else if (I.length == 16) {
I[0] = 1; I[1] = 0; I[2] = 0;
I[4] = 0; I[5] = c; I[6] = s;
I[8] = 0; I[9] =-s; I[10]= c;
I[3] = I[7] = I[11] = I[12] = I[13] = I[14] = 0;
I[15] = 1;
}
}
return true;
}
需要四个参数:
float [] R, float [] I, float [] gravity, float [] Geomagnetic.
其中一个仅仅是重力...我目前正在处理的代码类似于 https://github.com/KEOpenSource/FusedLinearAcceleration/blob/master/FusedLinearAcceleration/src/com/kircherelectronics/fusedlinearacceleration/sensor/LinearAccelerationSensor.java,除了引用SensorManager的方法。这些方法是从Android源代码中复制过来的: https://gitorious.org/android-eeepc/base/source/9cb3e09ec49351401cf19b5ae5092dd9ca90a538:core/java/android/hardware/SensorManager.java。 我没有找到任何关于如何在Java中实现这个的例子。 所以我的问题是:我怎样可以使用三个基本传感器实现方法(在java中),它返回与Android类似的重力方向数组(x,y,z),但不使用Android API。