在我的Android设备上,我可以读取一系列线性加速度值(在设备的坐标系中)和一组绝对方向值(在地球坐标系中)。我需要的是获得后一个坐标系中的线性加速度值。系统
我如何转换它们?
在Ali回复评论后编辑:
好吧,如果我理解正确,当我测量线性加速度时,手机的位置完全无关紧要,因为读数是在地球坐标系中给出的。正确?
但是我只是做了一个测试,我把手机放在不同的位置,并在不同的轴上加速。有3对图片 - 第一部分显示我如何放置设备(对不起我的Paint“掌握技能”),第二部分显示线性acc提供的数据读数。传感器:
现在 - 为什么在第三种情况下加速沿Z轴(而不是Y)发生,因为器件位置无关紧要?
答案 0 :(得分:42)
我终于设法解决了!因此,要在地球坐标系中获得加速度矢量,您需要:
float[16]
获取旋转矩阵(android.opengl.Matrix
以便SensorManager.getRotationMatrix()
类可以稍后使用)(使用SENSOR.TYPE_GRAVITY
和SENSOR.TYPE_MAGNETIC_FIELD
传感器值作为参数) ,android.opengl.Matrix.invertM()
来反转它(不是转置!),Sensor.TYPE_LINEAR_ACCELERATION
传感器获取线性加速度矢量(在设备的坐标系中。)android.opengl.Matrix.multiplyMV()
将旋转矩阵乘以线性加速度矢量。你有它!我希望我能为别人节省一些宝贵的时间。
感谢Edward Falk和Ali提示!!
答案 1 :(得分:15)
根据@ alex的回答,这是代码片段:
private float[] gravityValues = null;
private float[] magneticValues = null;
@Override
public void onSensorChanged(SensorEvent event) {
if ((gravityValues != null) && (magneticValues != null)
&& (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)) {
float[] deviceRelativeAcceleration = new float[4];
deviceRelativeAcceleration[0] = event.values[0];
deviceRelativeAcceleration[1] = event.values[1];
deviceRelativeAcceleration[2] = event.values[2];
deviceRelativeAcceleration[3] = 0;
// Change the device relative acceleration values to earth relative values
// X axis -> East
// Y axis -> North Pole
// Z axis -> Sky
float[] R = new float[16], I = new float[16], earthAcc = new float[16];
SensorManager.getRotationMatrix(R, I, gravityValues, magneticValues);
float[] inv = new float[16];
android.opengl.Matrix.invertM(inv, 0, R, 0);
android.opengl.Matrix.multiplyMV(earthAcc, 0, inv, 0, deviceRelativeAcceleration, 0);
Log.d("Acceleration", "Values: (" + earthAcc[0] + ", " + earthAcc[1] + ", " + earthAcc[2] + ")");
} else if (event.sensor.getType() == Sensor.TYPE_GRAVITY) {
gravityValues = event.values;
} else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
magneticValues = event.values;
}
}
答案 2 :(得分:4)
According to the documentation你可以在手机的坐标系中获得线性加速度。
您可以将任意矢量从手机坐标系转换为地球坐标系,方法是将其与旋转矩阵相乘。您可以从getRotationMatrix()获取旋转矩阵。
(也许已经有一个函数为你做这个乘法,但我不做Android编程,我不熟悉它的API。)
关于旋转矩阵的一个很好的教程是Direction Cosine Matrix IMU: Theory手稿。祝你好运!
答案 3 :(得分:1)
好的,首先,如果您尝试在Android上进行实际的惯性导航,那么您的工作就已经完成了。智能手机中使用的廉价小传感器不够精确。尽管如此,有一些有趣的工作已经完成了对小距离的内部导航,例如在建筑物内部。你可以挖掘这个主题的论文。谷歌“运动界面开发者大会”,您可能会发现一些有用的东西 - 这是几个月前Invensense举办的会议。
第二,不,线性加速度在设备坐标中,而不是世界坐标。你必须转换自己,这意味着要知道设备的三维方向。
您要做的是使用支持虚拟传感器TYPE_GRAVITY和TYPE_LINEAR_ACCELERATION的Android版本。你需要一个带陀螺仪的设备来获得合理准确和精确的读数。
在内部,系统结合了陀螺仪,加速度计和磁力计,以便为设备方向提供真正的值。这有效地将加速度计装置分成重力和加速度分量。
所以你要做的是为TYPE_GRAVITY,TYPE_LINEAR_ACCELERATION和TYPE_MAGNETOMETER设置传感器监听器。使用重力和磁力计数据作为SensorManager的输入。 getRotationMatrix()以获得将世界坐标转换为设备坐标的旋转矩阵,反之亦然。在这种情况下,您将需要“反之”部分。也就是说,将线性加速度输入转换为世界坐标,方法是将它们乘以方向矩阵的转置。