Я исследовал Интернет и StackOverflow, чтобы найти способ перевода векторов акселерометра Android из системы координат устройства в системы координат Земли.Я использую Sensor.TYPE_ROTATION_VECTOR, чтобы сделать это.Я получаю доступ к датчикам, используя NativeScript и использую MathJS для выполнения матричных вычислений.
- Я беру вектор вращения, используя Sensor.TYPE_ROTATION_VECTOR
- Я вычисляю матрицу вращения, следуя коду Android для getRotationMatrixFromVector() дано в https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/hardware/SensorManager.java.
--- 2.1 Я вычисляю q0, q1 = acceleration.x, q2 = acceleration.y, q3 = ускорение.z --- 2.2 Я попытался вычислить матрицу вращения, используя оба числа с плавающей запятой [9] и float [16] размеров матрицы, но я не могу заставить их работать.--- 2.3 Я попытался инвертировать и транспонировать обе эти матрицы вращения. - Теперь я умножил матрицу вращения (пробовал нормально, инвертировано и транспонировал) на матрицу [[accel.x], [accel.y], [accel.z], [0.0]] (матрица 4x1)
- Когда я смотрю на мои недавно переведенные значения ускорения, они вообще не вращаются.Если я укажу ось x моего устройства в направлении севера Земли и ускорю ее в этом направлении, мой acceleration.x будет> 1, а другие значения почти 0. Здесь мой ускорение.y должно быть переведено в> 1.Точно так же, если я укажу ось Y моего устройства к небу и ускорю его в этом направлении, мой acceleration.y будет читать> 1, когда мой ускорение.z должно читать> 1.
Может кто-нибудь сказать мне, что я делаю не так в этих шагах?Похоже, что консенсус заключается в том, чтобы захватить вектор вращения, преобразовать его в матрицу вращения, инвертировать матрицу, а затем умножить эту инвертированную матрицу на вектор акселерометра.Это не работает для меня.Спасибо,
var r;
var rinv;
accelerometer.startAccelerometerUpdates(function (accel) {
if (accel.sensortype == 11) {
var q0 = Math.sqrt(1 - accel.x*accel.x - accel.y*accel.y - accel.z*accel.z);
var q1 = accel.x;
var q2 = accel.y;
var q3 = accel.z;
//calculate rotation matrix from unit quaternion
var sq1 = 2*q1*q1;
var sq2 = 2*q2*q2;
var sq3 = 2*q3*q3;
var q1q2 = 2*q1*q2;
var q3q0 = 2*q3*q0;
var q1q3 = 2*q1*q3;
var q2q0 = 2*q2*q0;
var q2q3 = 2*q2*q3;
var q1q0 = 2*q1*q0;
//r = math.matrix([[1-sq2-sq3,q1q2-q3q0,q1q3+q2q0],[q1q2+q3q0,1-sq1-sq3,q2q3-q1q0],[q1q3-q2q0,q2q3+q1q0,1-sq1-sq2]]);
r = math.matrix([[1-sq2-sq3,q1q2-q3q0,q1q3+q2q0,0.0],[q1q2+q3q0,1-sq1-sq3,q2q3-q1q0,0.0],[q1q3-q2q0,q2q3+q1q0,1-sq1-sq2,0.0],[0.0,0.0,0.0,1.0]]);
rinv = math.inv(r);
}
if (accel.sensortype == 10) {
//filter accelerometer errors
if (Math.abs(accel.x) < 10 || Math.abs(accel.y) < 10 || Math.abs(accel.z) < 10) {
if ((Math.abs(accel.x) > .15 && Math.abs(accel.x)/oldAX < 2) || (Math.abs(accel.y) > .15 && Math.abs(accel.y)/oldAY < 2) || (Math.abs(accel.z) > .15 && Math.abs(accel.z)/oldAZ < 2)) { //filter errors in accelerometer
var Ad = math.matrix([[accel.x],[accel.y],[accel.z],[0.0]]);
//transform acceleration values from device coordinates to Earth coordinates
var Ag = math.multiply(rinv,Ad);
var ax = Ag.get([0,0]);
var ay = Ag.get([1,0]);
var az = Ag.get([2,0]);
if (ax > 1 || ay > 1 || az > 1) { //only show large values for easier analyses
page.getViewById("rotationLabel").text = "Earth Axes Acceleration \n x: " + ax + "\ny: " + ay + "\nz: " + az;
}
Я ожидаю, что значения акселерометра устройства будут переведены в систему координат Земли, как на этой странице в части вектора вращения.https://developer.android.com/guide/topics/sensors/sensors_motion