Sib*_*ing 5 android quaternions gyroscope
官方开发文档提出了以下从3D旋转速率向量获取四元数的方法(wx, wy, wz).
// Create a constant to convert nanoseconds to seconds.
private static final float NS2S = 1.0f / 1000000000.0f;
private final float[] deltaRotationVector = new float[4]();
private float timestamp;
public void onSensorChanged(SensorEvent event) {
// This timestep's delta rotation to be multiplied by the current rotation
// after computing it from the gyro sample data.
if (timestamp != 0) {
final float dT = (event.timestamp - timestamp) * NS2S;
// Axis of the rotation sample, not normalized yet.
float axisX = event.values[0];
float axisY = event.values[1];
float axisZ = event.values[2];
// Calculate the angular speed of the sample
float omegaMagnitude = sqrt(axisX*axisX + axisY*axisY + axisZ*axisZ);
// Normalize the rotation vector if it's big enough to get the axis
// (that is, EPSILON should represent your maximum allowable margin of error)
if (omegaMagnitude > EPSILON) {
axisX /= omegaMagnitude;
axisY /= omegaMagnitude;
axisZ /= omegaMagnitude;
}
// Integrate around this axis with the angular speed by the timestep
// in order to get a delta rotation from this sample over the timestep
// We will convert this axis-angle representation of the delta rotation
// into a quaternion before turning it into the rotation matrix.
float thetaOverTwo = omegaMagnitude * dT / 2.0f;
float sinThetaOverTwo = sin(thetaOverTwo);
float cosThetaOverTwo = cos(thetaOverTwo);
deltaRotationVector[0] = sinThetaOverTwo * axisX;
deltaRotationVector[1] = sinThetaOverTwo * axisY;
deltaRotationVector[2] = sinThetaOverTwo * axisZ;
deltaRotationVector[3] = cosThetaOverTwo;
}
timestamp = event.timestamp;
float[] deltaRotationMatrix = new float[9];
SensorManager.getRotationMatrixFromVector(deltaRotationMatrix, deltaRotationVector);
// User code should concatenate the delta rotation we computed with the current rotation
// in order to get the updated rotation.
// rotationCurrent = rotationCurrent * deltaRotationMatrix;
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:
这是很从加速度情况不同,在那里,计算使用的加速度的合成加速度ALONG 3个轴是有意义的.
我真的很困惑,为什么得到的转速也可以与子旋转速率来计算绕 3个轴.这对我来说没有意义.
为什么这种方法 - 找到复合转速幅度 - 甚至可以工作?
Ale*_*cha 20
由于你的标题与你的问题不符,我正尽力回答.
陀螺仪不提供绝对方向(如ROTATION_VECTOR),但只围绕这些轴的旋转速度,它们被构建为"旋转".这是由于陀螺仪的设计和构造.想象一下下面的结构.黄金的东西是旋转,由于物理定律,它不想改变它的旋转.现在您可以旋转框架并测量这些旋转.

现在,如果你想获得的东西从陀螺仪的"当前旋转状态",你将有一个初始旋转开始,把它q0不断补充那些小小的旋转差,该陀螺仪绕轴线它测量:q1 = q0 + gyro0,q2 = q1 + gyro1,...
换句话说:陀螺仪为您提供了围绕三个构造轴旋转的差异,因此您不是组成绝对值而是组成小的增量.
现在这很一般,留下了几个未回答的问题:
取决于旋转的当前表示:如果使用旋转矩阵,则应按照注释中的建议执行简单的矩阵乘法(请注意,此矩阵乘法实现效率不高!):
/**
* Performs naiv n^3 matrix multiplication and returns C = A * B
*
* @param A Matrix in the array form (e.g. 3x3 => 9 values)
* @param B Matrix in the array form (e.g. 3x3 => 9 values)
* @return A * B
*/
public float[] naivMatrixMultiply(float[] B, float[] A) {
int mA, nA, mB, nB;
mA = nA = (int) Math.sqrt(A.length);
mB = nB = (int) Math.sqrt(B.length);
if (nA != mB)
throw new RuntimeException("Illegal matrix dimensions.");
float[] C = new float[mA * nB];
for (int i = 0; i < mA; i++)
for (int j = 0; j < nB; j++)
for (int k = 0; k < nA; k++)
C[i + nA * j] += (A[i + nA * k] * B[k + nB * j]);
return C;
}
Run Code Online (Sandbox Code Playgroud)
要使用此方法,假设mRotationMatrix保持当前状态,这两行执行以下操作:
SensorManager.getRotationMatrixFromVector(deltaRotationMatrix, deltaRotationVector);
mRotationMatrix = naivMatrixMultiply(mRotationMatrix, deltaRotationMatrix);
// Apply rotation matrix in OpenGL
gl.glMultMatrixf(mRotationMatrix, 0);
Run Code Online (Sandbox Code Playgroud)
如果您选择使用Quaternions,请再次想象mQuaternion包含当前状态:
// Perform Quaternion multiplication
mQuaternion.multiplyByQuat(deltaRotationVector);
// Apply Quaternion in OpenGL
gl.glRotatef((float) (2.0f * Math.acos(mQuaternion.getW()) * 180.0f / Math.PI),mQuaternion.getX(),mQuaternion.getY(), mQuaternion.getZ());
Run Code Online (Sandbox Code Playgroud)
这里描述了四元数乘法- 等式(23).请确保正确应用乘法,因为它不是可交换的!
如果您只想知道设备的旋转(我认为这是您最终想要的),我强烈推荐使用ROTATION_VECTOR-Sensor.另一方面,陀螺仪对于测量旋转速度非常精确,并且具有非常好的动态响应,但是受到漂移的影响并且不会给出绝对定向(磁北极或根据重力).
更新:如果您想查看完整示例,可以从https://bitbucket.org/apacha/sensor-fusion-demo下载简单演示应用程序的源代码.
我感觉合理。加速度传感器的工作原理通常是,当向被测轴施加力时,会产生一些可测量的量变化。例如,如果重力对测量该轴的传感器产生下拉作用,则它的导电性能会更好。现在您可以知道重力或某个方向上的加速度的拉力有多大。简单的。
与此同时,陀螺仪是旋转的东西(好吧,或者像调整过的跳水板一样沿直线来回弹跳)。陀螺仪正在旋转,现在您旋转,陀螺仪看起来会旋转得更快或更慢,具体取决于您旋转的方向。或者,如果你试图移动它,它会抵抗并试图继续按原来的方式移动。所以你只需通过测量它就可以得到旋转变化。然后,您必须通过整合一段时间内的所有变化来找出变化的力量。
通常这些东西都不是一个传感器。它们通常是 3 个不同的传感器,全部相互垂直排列,并测量不同的轴。有时所有传感器都在同一芯片上,但它们仍然是芯片上单独测量的不同东西。
| 归档时间: |
|
| 查看次数: |
12084 次 |
| 最近记录: |