Android SensorManager.getRotationMatrix yields wrong values

607 Views Asked by At

I'm building an android app which shall display the position of gps coordinates as points on a canvas on the camera picture, but I'm having trouble with figuring 2d point (on the phone screen) through which the gps coordinate can be seen.

As far as I know, the projection works by multiplying the camera matrix with the point that should be projected. The camera matrix can be obtained by multiplying the intrinsic matrix (I calculated the focal length using the chosen answer of this question: Converting Focal Length in millimeters to pixels - Android; the screen resolution of my phone is 1920x1080, 540 = 1080/2, 960 = 1920/2)

/ 935    0  540 \
|   0  935  960 |
\   0    0    1 /

with the extrinsic matrix (which is essentially the rotation matrix, as I set the camera to be at the origin 0|0|0).

I've calculated the relative position of the camera to the gps coordinate (in East North Up coordinates) which is 13|-4|2.


To check if it's working, I rotated the phone such that the position (I placed a lamp there) could be seen in the upper left corner of the screen and wrote down the rotation matrix. Then I repeated this procedure for upper right, lower right, lower left and center. The rotation matrices are:

Upper left:
    -0.17288628   0.77568847  -0.6069743
     0.19706762   0.6310352    0.75030595
     0.9650258    0.010102619 -0.2619604

Upper right:
     0.16115496   0.65267444   -0.7403008
    -0.13548408   0.75763404    0.6384627
     0.9775853   -0.0025924728  0.21052347

Lower right:
     0.18777268  -0.31702965  -0.9296416
     0.04068178   0.9481752   -0.31513295
     0.9813697    0.021353884  0.19093873

Lower left:
    -0.25916395   -0.19289172  -0.94637567
    -0.033540796   0.9810605   -0.19077612
     0.96525085   -0.017700095 -0.26072523

Center:
    -0.003970425   0.33063367  -0.94375074
    -0.011958062   0.94367504   0.33065745
     0.99992067    0.01259828   0.000206947

Projecting the coordinate (13|-4|2) using the rotation matrices above gave me these coordinates:

Upper left:   27 | 1069
Upper right: 397 |  698
Lower right: 682 |  673
Lower left:  203 |  586
Center:      308 |  711

This does not make sense for multiple reasons. One example is that upper right and lower left should not have (roughly) the same Y coordinate. The Point (13|-4|2) is correct, therefore I suppose that either the rotation matrices are wrong or that I missinterpreted them.

Any help is appreciated! Thanks in advance.


I retrieved the rotation matrix with the following code:

private SensorManager sensorManager;
private Sensor accelerometer;
private Sensor magnetometer;
private float[] gravityValues = new float[3];
private float[] geomagneticValues = new float[3];
private float[] rotationMatrix = new float[16];

/* constructor */ {
    sensorManager = (SensorManager) activity.getSystemService(SENSOR_SERVICE);
    accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    magnetometer = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);

    sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
    sensorManager.registerListener(this, magnetometer, SensorManager.SENSOR_DELAY_NORMAL);
}

@Override
public void onSensorChanged(SensorEvent event) {
    switch (event.sensor.getType()) {
        case Sensor.TYPE_ACCELEROMETER:
            gravityValues = Arrays.copyOf(event.values, event.values.length);
            break;
        case Sensor.TYPE_MAGNETIC_FIELD:
            geomagneticValues = Arrays.copyOf(event.values, event.values.length);
        default:
            break;
    }

    SensorManager.getRotationMatrix(rotationMatrix, null, gravityValues, geomagneticValues);
}

public float[] getRotationMatrix() {
    return rotationMatrix;
}

(https://developer.android.com/reference/android/hardware/SensorManager.html#getRotationMatrix(float[],%20float[],%20float[],%20float[]))

1

There are 1 best solutions below

0
On

According to Android sensor: getRotationMatrix() returns wrong values, why? SensorManager.getRotationMatrix may return inaccurate values if the device is accelerating. This was not the case in my test, but it means that I can not use this method to get my rotation matrix.