需要根据 Sensor.TYPE_ORIENTATION 数据计算旋转矢量

发布于 2024-09-02 04:01:20 字数 1550 浏览 2 评论 0原文

我需要根据从 Sensor.TYPE_ORIENTATION 获得的数据计算旋转向量。

传感器数据的定义如下:

  • 必须重新计算值才能成为正确的 3d 位置:values[0]:方位角,磁北方向与 Y 轴之间的角度,围绕 Z 轴(0 到 359)。 0=北、90=东、180=南、270=西
  • 1:俯仰、旋转X 轴(-180 到 180),当 z 轴向 y 轴移动时为正值。
  • value[2]:滚动,绕 Y 轴旋转(-90 到 90),当 x 轴远离 z 轴时为正值

我需要所有三个值,如 Z 轴值(从 0 到 360 度) 。我尝试了很多,但不知道如何做到这一点:/

( 编辑:要了解工作代码背后的想法,请查看 DroidAR 框架,您可以在其中看到如何处理不同的事件类型。)

我还尝试使用 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 旋转向量,但我只是不知道该怎么做。如果你知道答案请告诉我。

编辑: 我应该补充一点,我想将这些值传递给 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 矩阵计算角度,但我认为必须有一个更简单的解决方案(?)

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 (?)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

_蜘蛛 2024-09-09 04:01:20

这应该可以工作(使用 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 中。在实际方向中,您将获得相对于您的实际位置指向北的矢量。

如果你想从相机的角度检测北方,你必须像这样改变最后一行代码

float[] outR = new float[16];
SensorManager.remapCoordinateSystem(R, SensorManager.AXIS_X, SensorManager.AXIS_Z, outR);
SensorManager.getOrientation(outR, actual_vals); 

This should work (using Sensor.TYPE_MAGNETIC_FIELD and Sensor.TYPE_ACCELEROMETER inputs)

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

Put this conde in your onSensorChanged. In actual_orientation you will have the vector that points to north respect to your actual position.

if you want to detect the north from the camera point of view you have to change the last line of code like this

float[] outR = new float[16];
SensorManager.remapCoordinateSystem(R, SensorManager.AXIS_X, SensorManager.AXIS_Z, outR);
SensorManager.getOrientation(outR, actual_vals); 
冧九 2024-09-09 04:01:20

好的,现在我有了一个解决方案,您必须按以下顺序进行 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 数据执行此操作,请告诉我。

ok now i got a solution, you have to do the openGl rotation in this order:

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

use this in combination with SensorManager.getOrientation and it will work. if someone knows how to do this with the Sensor.TYPE_ORIENTATION data, please let me know.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文