2

In get rotation matrix value it contains public static boolean getRotationMatrix (float[] R, float[] I, float[] gravity, float[] geomagnetic) Here how can i calculate the float[] gravity? I found a sample of code where it calculate the orientation using both Accelerometer and 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));
}

My questions are :

  • 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?

To get the rotation matrix i use this code

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

But the problem is this getRotationMatrixFromVector is says undefine for sensor.Any idea?

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
MBMJ
  • 5,323
  • 8
  • 32
  • 51

2 Answers2

4

Orientation is not a rotation matrix as it only provides you angles related to magnetic North. You can obtain the rotation matrix (Direction Cosine Matrix) that will help you to transform coordinates from your device frame to the Earth's frame this way :

DCM from Wikipedia

with

azimuth = azimuth (radians)

pitch = pitch (radians)

roll = roll (radians)

PeterGriffin
  • 910
  • 8
  • 19
  • Thanks.Look at my 2nd code where i am trying to get the 9 values of the rotation matrix,Is it the right way to get those values – MBMJ May 22 '12 at 09:13
  • It might be. I did that a long time a go, computing the rotation matrix from a vector didn't give me good results (even though I maybe did something wrong). All I know is that the solution I gave you works perfectly (I still use it) and is simple to implement. – PeterGriffin May 22 '12 at 09:19
  • i find the rotation matrix by using this `if(success){ SensorManager.getOrientation(matrixR, matrixValues);//code here to display the matrix value` where matrixR is the rotation matrix and give me the result.But i do not understand is it using real co-ordinate system? – MBMJ May 22 '12 at 11:23
1

I know that this is an old thread but in case it helps, for Android I think the 3x3 rotation matrix is actually given by a variation of the approved answer. To be specific, in Android the rotation matrix is

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

where

    φ = azimuth
    θ = pitch
    ψ = roll

which corresponds to the 3x3 Android rotation matrix R[0] to R[8] (matrixR in the question) via

    R[0] R[1] R[2]
    R[3] R[4] R[5]
    R[6] R[7] R[8]
Stochastically
  • 7,616
  • 5
  • 30
  • 58
  • Does not work. Tried it, but unfortunately causes perspective distortions if used with (deprecated) Orientation Sensor. – Alexander Pacha Aug 15 '13 at 01:01
  • @AlexanderPacha I think you've mis-understood something. These are the formula that Android uses internally, and all they're doing is specifying a 3D rotation matrix. The only question is, if you use Android's (non-deprecated) functions to calculate Android's version of azimuth, pitch and roll, are these the right formula to calculate Android rotation matrix R[0]...R[8]. Perspective is nothing to do with this. I still believe that these are the correct formula. – Stochastically Aug 15 '13 at 03:13
  • There is no non-deprecated sensor that returns azimuth, pitch and roll (http://developer.android.com/reference/android/hardware/SensorEvent.html#values). For which sensor did you use these formulas and where do you have them from? – Alexander Pacha Aug 15 '13 at 03:51
  • @AlexanderPacha With the readings from `Sensor.TYPE_MAGNETIC_FIELD` and `Sensor.TYPE_GRAVITY` or `Sensor.TYPE_ACCELEROMETER`, you call `SensorManager.getRotationMatrix(…)` to get the rotation matrix. This call gives you the `R[0]…R[8]` as described by my answer here. There's also an Android call `SensorManager.getOrientation(…)` which takes that rotation matrix `R[0]…R[8]` to give you azimuth, pitch and roll. – Stochastically Aug 15 '13 at 07:19