Calcular la matriz de rotación utilizando el campo magnético.
-
12-12-2019 - |
Pregunta
En obtener el valor de la matriz de rotación contiene public static boolean getRotationMatrix (float[] R, float[] I, float[] gravity, float[] geomagnetic)
Aquí ¿cómo puedo calcular el float[] gravity
?Encontré una muestra de código donde calcula el orientation
usando ambos Accelerometer
y Magnetic field
boolean success = SensorManager.getRotationMatrix(
matrixR,
matrixI,
valuesAccelerometer,
valuesMagneticField);
if(success){
SensorManager.getOrientation(matrixR, matrixValues);
double azimuth = Math.toDegrees(matrixValues[0]);
double pitch = Math.toDegrees(matrixValues[1]);
double roll = Math.toDegrees(matrixValues[2]);
readingAzimuth.setText("Azimuth: " + String.valueOf(azimuth));
readingPitch.setText("Pitch: " + String.valueOf(pitch));
readingRoll.setText("Roll: "+String.valueOf(roll));
}
Mis preguntas son:
- ¿El valor de orientación es el valor de la matriz de rotación?
- Si no, ¿cómo puedo implementar este código para obtener el valor de la matriz de rotación usando magnético?¿campo?
Para obtener la matriz de rotación utilizo este código
public void onSensorChanged(SensorEvent sensorEvent) {
if (timestamp != 0) {
final double dT = (sensorEvent.timestamp - timestamp) * NS2S;
double magneticX = sensorEvent.values[0];
double magneticY = sensorEvent.values[1];
double magneticZ = sensorEvent.values[2];
double omegaMagnitude =Math.sqrt(magneticX*magneticX + magneticY*magneticY + magneticZ*magneticZ);
if (omegaMagnitude > EPSILON) {
magneticX /= omegaMagnitude;
magneticY /= omegaMagnitude;
magneticZ /= omegaMagnitude;
}
double thetaOverTwo = omegaMagnitude * dT / 2.0f;
double sinThetaOverTwo =Math.sin(thetaOverTwo);
double cosThetaOverTwo = Math.cos(thetaOverTwo);
deltaRotationVector[0] = (double) (sinThetaOverTwo * magneticX);
deltaRotationVector[1] = (double) (sinThetaOverTwo * magneticY);
deltaRotationVector[2] = (double) (sinThetaOverTwo * magneticZ);
deltaRotationVector[3] = cosThetaOverTwo;
}
double[] deltaRotationMatrix = new double[9];
SensorManager.getRotationMatrixFromVector(deltaRotationMatrix, deltaRotationVector);
}
Pero el problema es este getRotationMatrixFromVector
dice indefinido para el sensor. ¿Alguna idea?
Solución
La orientación no es una matriz de rotación, ya que solo proporciona ángulos relacionados con el norte magnético.Puedes obtener el matriz de rotación (Matriz coseno de dirección) que le ayudará a transformar las coordenadas desde el marco de su dispositivo al marco de la Tierra de esta manera:
con
= azimut (radianes)
= tono (radianes)
= rodar (radianes)
Otros consejos
Sé que este es un hilo antiguo, pero en caso de que ayude, para Android creo que la matriz de rotación 3x3 en realidad viene dada por una variación de la respuesta aprobada.Para ser específico, en Android la matriz de rotación es
(cosφ cosψ - sinφ sinψ sinθ) sinφ cosθ ( cosφ sinψ + sinφ cosψ sinθ) -(sinφ cosψ + cosφ sinψ sinθ) cosφ cosθ (-sinφ sinψ + cosφ cosψ sinθ) -sinψ cosθ -sinθ cosφ cosθ
dónde
φ = azimuth θ = pitch ψ = roll
que corresponde a la matriz de rotación de Android 3x3 R [0] a R [8] (matrizR en la pregunta) a través de
R[0] R[1] R[2] R[3] R[4] R[5] R[6] R[7] R[8]