Вычислить матрицу вращения, используя магнитное поле

В полученном значении матрицы вращения он содержитpublic static boolean getRotationMatrix (float[] R, float[] I, float[] gravity, float[] geomagnetic) Вот как я могу рассчитатьfloat[] gravity? I found a sample of code where it calculate the orientation используя обаAccelerometer а также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));
}

Мои вопросы:

Is orientation value is the rotation matrix value? If no then how can i implement this code to get the rotation matrix value using magnetic? field?

Чтобы получить матрицу вращения, я использую этот код

 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);
}

Но проблема в том,getRotationMatrixFromVector это говорит undefine для датчика. Есть идеи?

Ответы на вопрос(2)

Решение Вопроса

Ориентация не является матрицей вращения, поскольку она предоставляет вам только углы, связанные с магнитным севером. Вы можете получитьrotation matrix (Направляющая косинусная матрица), которая поможет вам преобразовать координаты из кадра вашего устройства в кадр Земли следующим образом:

DCM from Wikipedia

with

azimuth = azimuth (radians)

pitch  = шаг (радианы)

roll  = крен (радианы)

 22 мая 2012 г., 11:19
Это может быть. Я делал это долгое время, вычисляя матрицу вращения по вектору, но это не давало мне хороших результатов (даже если я, возможно, сделал что-то не так). Все, что я знаю, это то, что решение, которое я вам дал, прекрасно работает (я все еще им пользуюсь) и просто в реализации.
 MBMJ22 мая 2012 г., 13:23
я нахожу матрицу вращения с помощью этогоif(success){ SensorManager.getOrientation(matrixR, matrixValues);//code here to display the matrix value      где matrixR - матрица вращения и дают мне результат. Но я не понимаю, использует ли она реальную систему координат?
 MBMJ22 мая 2012 г., 11:13
Спасибо. Посмотрите на мой второй код, где я пытаюсь получить 9 значений матрицы вращения. Это правильный способ получить эти значения

Я знаю, что это старая ветка, но в случае, если она помогает, для Android я думаю, что матрица вращения 3х3 фактически определяется вариацией утвержденного ответа. Чтобы быть конкретным, в Android матрица вращения

     (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θ

где

    φ = azimuth
    θ = pitch
    ψ = roll

которая соответствует матрице вращения Android 3x3 R [0] - R [8] (matrixR в вопросе) через

    R[0] R[1] R[2]
    R[3] R[4] R[5]
    R[6] R[7] R[8]
 15 авг. 2013 г., 09:19
@AlexanderPacha С чтениями изSensor.TYPE_MAGNETIC_FIELD а такжеSensor.TYPE_GRAVITY или жеSensor.TYPE_ACCELEROMETER, ты звонишьSensorManager.getRotationMatrix(…) чтобы получить матрицу вращения. Этот звонок дает вамR[0]…R[8] как описано в моем ответе здесь. Также есть вызов AndroidSensorManager.getOrientation(…) который принимает эту матрицу вращенияR[0]…R[8] чтобы дать вам азимут, шаг и крен.
 15 авг. 2013 г., 05:51
Не существует устаревшего датчика, который возвращает азимут, тангаж и крен (developer.android.com/reference/android/hardware/…). Для какого датчика вы использовали эти формулы и откуда вы их взяли?
 15 авг. 2013 г., 03:01
Не работает. Пробовал, но, к сожалению, вызывает искажения перспективы, если используется (устарело) Датчик ориентации.
 15 авг. 2013 г., 05:13
@ АлександрPacha Я думаю, вы что-то неправильно поняли. Это формула, которую Android использует внутри себя, и все, что они делают, это задают трехмерную матрицу вращения. Единственный вопрос заключается в том, что если вы используете функции Android (не устарели) для расчета версии азимута, высоты и угла наклона Android, то являются ли они правильной формулой для вычисления матрицы вращения Android R [0] ... R [8 ]. Перспектива тут не причем. Я до сих пор считаю, что это правильная формула.

Ваш ответ на вопрос