8

I need to calculate a rotation vector out of the data i get from Sensor.TYPE_ORIENTATION.

The sensor data is defined like this:

  • the values have to be recalculated to become a correct 3d position: values[0]: Azimuth, angle between the magnetic north direction and the Y axis, around the Z axis (0 to 359). 0=North, 90=East, 180=South, 270=West
  • values1: Pitch, rotation around X axis (-180 to 180), with positive values when the z-axis moves toward the y-axis.
  • values[2]: Roll, rotation around Y axis (-90 to 90), with positive values when the x-axis moves away from the z-axis

I need all three values like the Z axis value (from 0 to 360 degree). I tried a lot but cant figure out how to do this :/

( edit: To see the idea behind in working code take a look at the class ActionWithSensorProcessing of the DroidAR framework there you can see how the different event types can be processed.)

i also tried to use Sensor.TYPE_ACCELEROMETER and Sensor.TYPE_MAGNETIC_FIELD to calculate this 3d vector on my own. here is the code:

final float[] inR = new float[16];
// load inR matrix from current sensor data:
SensorManager.getRotationMatrix(inR, null, gravityValues, geomagneticValues);
float[] orientation = new float[3];
SensorManager.getOrientation(inR, orientation);
mapMagAndAcclDataToVector(orientation); //here i do some *360 stuff
orientetionChanged(orientation); //then the correct values are passed (in theorie)

But this didn't work and i think it is much to complicated. So i bet there is a simple solution how to recalc the values of ensor.TYPE_ORIENTATION to make them a 3d rotation vector, but i just dont know how to do it. If you know the answer please tell me.

EDIT: i should add that i want to pass there values to OpenGL to align it to the axis like this:

gl.glRotatef(values[1], 1, 0, 0);
gl.glRotatef(values[2], 0, 1, 0);
gl.glRotatef(values[0], 0, 0, 1);

but because of the strange value ranges i obviously cant do this. the same problem with the values from SensorManager.getOrientation because they flip too when you pass the horizon line..

another solution would be to calculate the angles using the inR matrix but i think there must be an easier solution (?)

4

2 に答える 2

12

これは機能するはずです (Sensor.TYPE_MAGNETIC_FIELD および Sensor.TYPE_ACCELEROMETER 入力を使用)

switch (event.sensor.getType()) {
    case Sensor.TYPE_MAGNETIC_FIELD:
        magnitude_values = event.values.clone();
        sensorReady = true;
        break;
    case Sensor.TYPE_ACCELEROMETER:
        accelerometer_values = event.values.clone();
    }   

    if (magnitude_values != null && accelerometer_values != null && sensorReady) {
        sensorReady = false;

        float[] R = new float[16];
        float[] I = new float[16];

        SensorManager.getRotationMatrix(R, I, this.accelerometer_values, this.magnitude_values);

        float[] actual_orientation = new float[3];
        SensorManager.getOrientation(R, actual_orientation);
 }

このコンデを onSensorChanged に入れてください。actual_orientation には、実際の位置に対して北を指すベクトルがあります。

カメラの視点から北を検出したい場合は、コードの最後の行を次のように変更する必要があります

float[] outR = new float[16];
SensorManager.remapCoordinateSystem(R, SensorManager.AXIS_X, SensorManager.AXIS_Z, outR);
SensorManager.getOrientation(outR, actual_vals); 
于 2010-05-18T14:45:48.657 に答える
4

さて、私は解決策を得ました、あなたはこの順序でopenGlローテーションをしなければなりません:

gl.glRotatef(values[2], 0, 1, 0);
gl.glRotatef(values[1], 1, 0, 0);
gl.glRotatef(values[0], 0, 0, 1);

これをSensorManager.getOrientationと組み合わせて使用​​すると、機能します。誰かがSensor.TYPE_ORIENTATIONデータを使用してこれを行う方法を知っている場合は、私に知らせてください。

于 2010-05-23T12:29:41.207 に答える