Method ViroARScene.getCameraOrientationAsync() returns strange values in rotation array

336 views Asked by At

I'm developing a PoC with ViroReact lib but I'm getting strage values for the camera rotation.

Environment:

  • Device: Android 10. Xiaomi Mi 9
  • ViroReact 2.20.2

The ViroARScene.getCameraOrientationAsync() returns unexpected values in rotation array when I rotate the device over the y-axis, trying to keep the x and z axis fixed.

Specifically, when the y-axis reaches the -90º the x/z values change to +/180º and from this point the y-axis values are getting close to 0, for instance, instead of -135º the y-axis value is -45 with the x/z values in +/-180. In other words the y-axis values NEVER return an absolute value over 90.

Some examples (values have got an error margin of about 6 degrees):

  • Rotation expected: [0, -90, 0]. Returned rotation: [+/-180, -90, +/-180]
  • Rotation expected: [0, -135, 0]. Returned rotation: [+/-180, -45, +/-180]
  • Rotation expected: [0, -180, 0]. Returned rotation: [+/-180, 0, +/-180]

Questions:

  • Why the absolute value of y-axis is never greater than 90 ?
  • Why the x/z values change to +/-180º when I reach some point (+/-90º in y-axis) if I'm just rotating the device over the y-axis.
  • Is this the expeted behavior ? If so, could anyone explain these values (please).

The code to retrieve the values:

<ViroARScene onTrackingUpdated={this._onInitialized} anchorDetectionTypes={"PlanesVertical"}>
...
</ViroARScene>

_onInitialized(state, reason) {
    if (state === ViroConstants.TRACKING_NORMAL && reason === ViroConstants.TRACKING_REASON_NONE) {
      console.log('Tracking initiated');
      this._scene.getCameraOrientationAsync().then(
        (orientation) => {
          console.log('Cam rot:', round(orientation.rotation));
        });
    }
  }

I've also created a GitHub issue with some mockups to show the rotation values expected and returned: https://github.com/ViroCommunity/viro/issues/13

1

There are 1 answers

1
Abraham Brookes On

I think what you're coming up against might be Gimbal lock, which is the reason that a lot of 3d rotators are expressed in Quaternions, instead of the xyz (aka Euler - pronounced "oiler") system you are using now. It's probably expected behaviour for your system.

I'm not familiar with your platform but it might have built-in helpers or alternative methods you can use in order to work with Quaternions instead, if not then a solution for you might be to install a library (or write some code) that translates between Euler angles and Quaternions so that your calculations make more sense, if you are going to be spending time around the y-0.