Cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Orientation quaternion understanding

ANSWERED

I'm trying to get the angle between the normal of the display and the ground. 

Can someone show me how?

 

Here my test app:

 

/app/index.js

import document from "document";
import { OrientationSensor } from "orientation";
import { display } from "display";

display.autoOff = false;
let orientation = new OrientationSensor({ frequency: 5 });

let inputs=[
  document.getElementById("q0"),
  document.getElementById("q1"),
  document.getElementById("q2"),
  document.getElementById("q3")
];
let outputs=[
  document.getElementById("a0"),
  document.getElementById("a1"),
  document.getElementById("a2"),
  document.getElementById("a3")
];

function normalize(value){
  if (value>1) return 1;
  if (value<-1) return -1;
  return value;
}

function toDegrees(value){
  let res=value*180/Math.PI;
  return res.toFixed(0);
}

function onOrientationChanged(q){
  let qw=normalize(q[0]);
  var angle = 2 * Math.acos(qw);
  outputs[0].text=toDegrees(angle);
  let s=Math.sqrt(1-qw*qw);
  var angles=[0,0,0];
  for (var i=0;i<4;i++){
    inputs[i].text=q[i].toFixed(2);
    if (i>0){
      angles[i-1]=q[i]*angle;
      if (qw>=0.000001) angles[i-1]=angles[i-1]/s;
      outputs[i].text=toDegrees(angles[i-1]);
    }
  } 
  return angles;
}


onOrientationChanged([ 0.2088969, 0.5646126, 0.5646126, 0.5646126]); //expected x=90 y=90 z=90

orientation.onreading = function() {
  onOrientationChanged(orientation.quaternion);
};

setTimeout(function(){
  orientation.start();
},2500);

/resources/index.gui

<svg>
  
  <text x="5%" y="20%" text-length="6">w</text>
  <text x="5%" y="40%" text-length="6">x</text>
  <text x="5%" y="60%" text-length="6">y</text>
  <text x="5%" y="80%" text-length="6">z</text>

  <text id="q0" x="20%" y="20%" text-length="6">q0</text>
  <text id="q1" x="20%" y="40%" text-length="6">q1</text>
  <text id="q2" x="20%" y="60%" text-length="6">q2</text>
  <text id="q3" x="20%" y="80%" text-length="6">q3</text>
 
  <text id="a0" x="60%" y="20%" text-length="6">angle</text>
  <text id="a1" x="60%" y="40%" text-length="6">x angle</text>
  <text id="a2" x="60%" y="60%" text-length="6">y angle</text>
  <text id="a3" x="60%" y="80%" text-length="6">z angle</text>
 
</svg>
Best Answer
0 Votes
1 BEST ANSWER

Accepted Solutions

Here's a messy extract from a test of mine:

let orientation = new OrientationSensor({ frequency: 1 });
orientation.onreading = function() {
  let qr = orientation.quaternion[0];
  let qi = orientation.quaternion[1];
  let qj = orientation.quaternion[2];
  let qk = orientation.quaternion[3];
  
  // Roll:
  let t0 = 2 * (qr*qi + qj*qk);
  let t1 = 1 - 2*(qi*qi + qj*qj);
  let thetaX = Math.atan2(t0, t1)*180/3.14159;

  // Pitch:
  let t2 = 2 * (qr*qj - qk*qi);
  t2 = t2 > 1 ? 1 : t2;
  t2 = t2 < -1 ? -1 : t2;
  let thetaY = Math.asin(t2)*180/3.14159;

  // Yaw:
  let t3 = 2*(qr*qk + qi*qj);
  let t4 = 1 - 2*(qj*qj + qk*qk);
  let thetaZ = Math.atan2(t3, t4)*180/3.14159;

orientAXEl.text = Math.round(thetaX); orientAYEl.text = Math.round(thetaY); orientAZEl.text = Math.round(thetaZ); rollEl.groupTransform.rotate.angle = thetaX; // +x is pitch up pitchEl.groupTransform.rotate.angle = thetaY; // +y is roll right-wing-down yawEl.groupTransform.rotate.angle = thetaZ; // +z is yaw left } orientation.start();

It doesn't do quite what you want, but perhaps the roll, yaw and pitch angles will be more comprehensible and useful to you.

Peter McLennan
Gondwana Software

View best answer in original post

Best Answer
2 REPLIES 2

Here's a messy extract from a test of mine:

let orientation = new OrientationSensor({ frequency: 1 });
orientation.onreading = function() {
  let qr = orientation.quaternion[0];
  let qi = orientation.quaternion[1];
  let qj = orientation.quaternion[2];
  let qk = orientation.quaternion[3];
  
  // Roll:
  let t0 = 2 * (qr*qi + qj*qk);
  let t1 = 1 - 2*(qi*qi + qj*qj);
  let thetaX = Math.atan2(t0, t1)*180/3.14159;

  // Pitch:
  let t2 = 2 * (qr*qj - qk*qi);
  t2 = t2 > 1 ? 1 : t2;
  t2 = t2 < -1 ? -1 : t2;
  let thetaY = Math.asin(t2)*180/3.14159;

  // Yaw:
  let t3 = 2*(qr*qk + qi*qj);
  let t4 = 1 - 2*(qj*qj + qk*qk);
  let thetaZ = Math.atan2(t3, t4)*180/3.14159;

orientAXEl.text = Math.round(thetaX); orientAYEl.text = Math.round(thetaY); orientAZEl.text = Math.round(thetaZ); rollEl.groupTransform.rotate.angle = thetaX; // +x is pitch up pitchEl.groupTransform.rotate.angle = thetaY; // +y is roll right-wing-down yawEl.groupTransform.rotate.angle = thetaZ; // +z is yaw left } orientation.start();

It doesn't do quite what you want, but perhaps the roll, yaw and pitch angles will be more comprehensible and useful to you.

Peter McLennan
Gondwana Software
Best Answer

Perfect thank's

Best Answer
0 Votes