Необходимо рассчитать вектор вращения по данным Sensor.TYPE_ORIENTATION - PullRequest
8 голосов
/ 18 мая 2010

Мне нужно вычислить вектор вращения из данных, которые я получаю от Sensor.TYPE_ORIENTATION.

Данные датчика определяются следующим образом:

  • значения должны быть пересчитаны, чтобы стать правильной трехмерной позицией: значения [0]: азимут, угол между магнитным северным направлением и осью Y, вокруг оси Z (от 0 до 359). 0 = север, 90 = восток, 180 = юг, 270 = запад
  • значения 1 : шаг, вращение вокруг оси X (от -180 до 180), с положительными значениями, когда ось z перемещается в направлении оси y.
  • значения [2]: крен, вращение вокруг оси Y (от -90 до 90), с положительными значениями, когда ось x отходит от оси z

Мне нужны все три значения, такие как значение оси Z (от 0 до 360 градусов). Я много пробовал, но не могу понять, как это сделать: /

(правка: Чтобы увидеть идею, лежащую в основе рабочего кода, взгляните на класс ActionWithSensorProcessing DroidAR framework , где вы можете увидеть, как могут обрабатываться различные типы событий.)

Я также попытался использовать Sensor.TYPE_ACCELEROMETER и Sensor.TYPE_MAGNETIC_FIELD, чтобы рассчитать этот 3d вектор самостоятельно. вот код:

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)

Но это не сработало, и я думаю, что это очень сложно. Держу пари, что есть простое решение, как пересчитать значения ensor.TYPE_ORIENTATION, чтобы сделать их вектором вращения 3d, но я просто не знаю, как это сделать. Если вы знаете ответ, пожалуйста, скажите мне.

EDIT: я должен добавить, что я хочу передать туда значения в OpenGL, чтобы выровнять его по оси следующим образом:

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

но из-за странных диапазонов значений я, очевидно, не могу этого сделать. та же проблема с значения из SensorManager.getOrientation, потому что они тоже переворачиваются при прохождении линии горизонта ..

другим решением было бы вычисление углов с использованием матрицы inR, но я думаю, что должно быть более простое решение (?)

Ответы [ 2 ]

12 голосов
/ 18 мая 2010

Это должно работать (с использованием входов 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);
 }

Поместите этот conde в свой onSensorChanged. В actual_orientation у вас будет вектор, указывающий на север относительно вашей фактической позиции.

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

float[] outR = new float[16];
SensorManager.remapCoordinateSystem(R, SensorManager.AXIS_X, SensorManager.AXIS_Z, outR);
SensorManager.getOrientation(outR, actual_vals); 
4 голосов
/ 23 мая 2010

хорошо, теперь у меня есть решение, вы должны сделать вращение 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, пожалуйста, сообщите мне.

...