Calcular la matriz de rotación usando el campo magnético
Frecuentes
Visto 4,393 veces
2
En obtener el valor de la matriz de rotación que 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));
}
Mi pregunta es:
- ¿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, uso 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 sensor. ¿Alguna idea?
2 Respuestas
4
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 (Direction Cosine Matrix) que te ayudará a transformar las coordenadas del marco de tu dispositivo al marco de la Tierra de esta manera:
con
= acimut (radianes)
= paso (radianes)
= rollo (radianes)
contestado el 22 de mayo de 12 a las 10:05
1
Sé que este es un hilo antiguo, pero en caso de que ayude, para Android, creo que la matriz de rotación de 3x3 en realidad está dada por una variación de la respuesta aprobada. Para ser específicos, en Android la matriz de rotación es
(cosφ cosψ - sinφ sinψ sinθ) sinφ cosθ ( cosφ sinψ + sinφ cosψ sinθ) -(senφ cosψ + cosφ sinψ sinθ) cosφ cosθ (-sinφ sinψ + cosφ cosψ sinθ) -sinψ cosθ -sinθ cosφ cosθ
sin que importe
φ = acimut θ = cabeceo ψ = balanceo
que corresponde a la matriz de rotación de Android 3x3 R[0] a R[8] (matrixR 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]
Respondido 03 Abr '13, 19:04
No funciona. Lo probé, pero desafortunadamente causa distorsiones de perspectiva si se usa con el sensor de orientación (obsoleto). - Alejandro Pacha
@AlexanderPacha Creo que has entendido mal algo. Estas son las fórmulas que Android usa internamente, y todo lo que hacen es especificar una matriz de rotación 3D. La única pregunta es, si usa las funciones de Android (no obsoletas) para calcular la versión de Android de acimut, cabeceo y balanceo, ¿son estas la fórmula correcta para calcular la matriz de rotación de Android R[0]...R[8]. La perspectiva no tiene nada que ver con esto. Todavía creo que estas son las fórmulas correctas. - Estocásticamente
No hay ningún sensor no obsoleto que devuelva acimut, cabeceo y balanceo (desarrollador.android.com/reference/android/hardware/…). ¿Para qué sensor usó estas fórmulas y de dónde las tiene? - Alejandro Pacha
@AlexanderPacha Con las lecturas de Sensor.TYPE_MAGNETIC_FIELD
y Sensor.TYPE_GRAVITY
or Sensor.TYPE_ACCELEROMETER
, llama SensorManager.getRotationMatrix(…)
para obtener la matriz de rotación. Esta llamada te da la R[0]…R[8]
como se describe en mi respuesta aquí. También hay una llamada de Android SensorManager.getOrientation(…)
que toma esa matriz de rotación R[0]…R[8]
para darle acimut, cabeceo y balanceo. - Estocásticamente
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas android accelerometer sensors rotational-matrices magnetometer or haz tu propia pregunta.
Gracias. Mire mi segundo código donde estoy tratando de obtener los 2 valores de la matriz de rotación. ¿Es la forma correcta de obtener esos valores? MBMJ
Puede ser. Hice eso hace mucho tiempo, calcular la matriz de rotación de un vector no me dio buenos resultados (aunque tal vez hice algo mal). Todo lo que sé es que la solución que te di funciona perfectamente (todavía la uso) y es simple de implementar. - Peter Griffin
encuentro la matriz de rotación usando esto
if(success){ SensorManager.getOrientation(matrixR, matrixValues);//code here to display the matrix value
donde matrixR es la matriz de rotación y dame el resultado. Pero no entiendo, ¿está usando un sistema de coordenadas real? - MBMJ