I am looking to record mobile accelerometer data (x/y/z) and adjust it to be consistent irrespective of the orientation/rotation of the phone. The usecase here is to record and normalize these parameters while driving to detect turns/twists etc. A key element of this is to ensure that the reported data is independent of how the phone is oriented in the car. I am using gyronorm.js to get the device motion and orientation details.
I've looked at previous answers related to this topic on SO (such as this one) and have tried implementing their approach to get earth coordinates.
However, I am seeing readings completely change as I turn/twist my phone. Can anyone tell me what I'm doing wrong?
This is how I am calculating earth coordinates:
const deg2rad = Math.PI / 180;
let alpha = gdata.do.alpha;
let beta = gdata.do.beta;
let gamma = gdata.do.gamma;
let rotatematrix = this.getRotationMatrix(alpha * deg2rad, beta * deg2rad, gamma * deg2rad);
let relativeacc = new Array(3);
let earthacc = new Array(3);
let inv = new Array(9)
relativeacc[0] = gdata.dm.gx;
relativeacc[1] = gdata.dm.gy;
relativeacc[2] = gdata.dm.gz;
//console.log ("FIRST MATRIX")
mat3.invert(inv,rotatematrix);
//console.log ("SECOND MATRIX")
mat3.multiply(earthacc, inv, relativeacc);
let accEarthX = earthacc[0];
let accEarthY = earthacc[1];
let accEarthZ = earthacc[2];
let aMag = Math.sqrt(accEarthX*accEarthX + accEarthY*accEarthY + accEarthZ*accEarthZ)
console.log (`---RAW DATA --- ` + JSON.stringify(gdata));
console.log (`*** EARTH DATA X=${accEarthX}, Y=${accEarthY} Z=${accEarthZ}`)
This is the getRotationMatrix
code
// credit:https://stackoverflow.com/a/36662093/1361529
getRotationMatrix(alpha, beta, gamma) {
const getScreenOrientation = () => {
switch (window.screen.orientation || window.screen.mozOrientation) {
case 'landscape-primary':
return 90;
case 'landscape-secondary':
return -90;
case 'portrait-secondary':
return 180;
case 'portrait-primary':
return 0;
}
if (window.orientation !== undefined)
return window.orientation;
};
const screenOrientation = getScreenOrientation();
console.log ("SCREEN ORIENTATIIN = "+screenOrientation);
let out = [];
let _z = alpha;
let _x = beta;
let _y = gamma;
if (screenOrientation === 90) {
_x = - gamma;
_y = beta;
}
else if (screenOrientation === -90) {
_x = gamma;
_y = - beta;
}
else if (screenOrientation === 180) {
_x = - beta;
_y = - gamma;
}
else if (screenOrientation === 0) {
_x = beta;
_y = gamma;
}
let cX = Math.cos( _x );
let cY = Math.cos( _y );
let cZ = Math.cos( _z );
let sX = Math.sin( _x );
let sY = Math.sin( _y );
let sZ = Math.sin( _z );
out[0] = cZ * cY + sZ * sX * sY, // row 1, col 1
out[1] = cX * sZ, // row 2, col 1
out[2] = - cZ * sY + sZ * sX * cY , // row 3, col 1
out[3] = - cY * sZ + cZ * sX * sY, // row 1, col 2
out[4] = cZ * cX, // row 2, col 2
out[5] = sZ * sY + cZ * cY * sX, // row 3, col 2
out[6] = cX * sY, // row 1, col 3
out[7] = - sX, // row 2, col 3
out[8] = cX * cY // row 3, col 3
return out