Перевод векторов акселерометра с координат устройства на землю - PullRequest
0 голосов
/ 26 марта 2019

Я исследовал Интернет и StackOverflow, чтобы найти способ перевода векторов акселерометра Android из системы координат устройства в системы координат Земли.Я использую Sensor.TYPE_ROTATION_VECTOR, чтобы сделать это.Я получаю доступ к датчикам, используя NativeScript и использую MathJS для выполнения матричных вычислений.

  1. Я беру вектор вращения, используя Sensor.TYPE_ROTATION_VECTOR
  2. Я вычисляю матрицу вращения, следуя коду 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 Я попытался инвертировать и транспонировать обе эти матрицы вращения.
  3. Теперь я умножил матрицу вращения (пробовал нормально, инвертировано и транспонировал) на матрицу [[accel.x], [accel.y], [accel.z], [0.0]] (матрица 4x1)
  4. Когда я смотрю на мои недавно переведенные значения ускорения, они вообще не вращаются.Если я укажу ось 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

1 Ответ

0 голосов
/ 29 марта 2019

Плагин NativeScript-Accelerometer-Advanced закодирован неправильно. Вычислять кватернионное значение единицы q0 не нужно, поскольку это обеспечивается датчиком. Деление на силу тяжести (9,81 м / с ^ 2) не является необходимым, поскольку оно не включено в датчики. Я исправил это в своей локальной копии, и мой метод ротации работает правильно: 1. Получить вектор вращения 2. Рассчитать матрицу вращения 3. Инвертировать матрицу вращения 4. Умножьте инвертированную матрицу вращения на вектор акселерометра с добавлением [1.0] в качестве 4-й строки

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...