2012-03-29 4 views
2

В настоящее время я работаю на линейном акселерометре с компенсацией наклона на телефоне Android. То, что я в основном хочу достичь, - это ускорение, которое находится в рамке земли, а не в рамке датчика. Я также хочу сделать мою векторную гравитацию свободной. Ось X акселерометра будет располагаться отдельно по оси x наземного транспортного средства. Поэтому компенсация рыскания (угол между осью x телефона и магнитным севером) не требуется.Удалите произвольную ось вращения из матрицы вращения

Для этого мы имеем 2 показания датчика:

1) вращения 3x3 матрица R (вращение от земли кадра к датчику кадра)

вектор ускорения 2) 3x1 а = (х , у, г)^Т от датчика рамы

Чтобы вручную удалить тяжести от a_transposed мы ча п просто определить вектор силы тяжести в земной раме:

г = (0,0,9.81)^Т

теперь я могу умножить силы тяжести с матрицей вращения R, и вычитать его из вектора. В результате a ' - вектор ускорения без силы тяжести.

а «= а - (R * г) (на этом шаге» не имеет то же значение, что и датчик программного обеспечения LINEAR_ACCELERATION в API)

Пока здесь все работает отлично.

Теперь я хочу, чтобы повернуть мою линейный вектор ускорения а» в земной раме без учета вращения Z-оси в учетную запись. Для того чтобы сделать это, сначала я вычислить обратную матрицу вращения R, которая равна tranpose его:

R^(- 1) = R^Т

Тогда я умножить на» с R^(- 1) и поверните его обратно к земле.

а «= R^(- 1) * а»

На этом этапе у меня есть данные линейное ускорение наклона компенсируется, если мой телефон сталкивается магнитный север, потому что я также поворачивать вокруг оси Z, которая не требуется. Мне нужно перерисовать его вокруг оси z, чтобы получить окончательный правильный результат. Для этого я вычислил угол Эйлера (вращение вокруг оси z) от матрицы вращения, которая является рысканием. И повернул мой вектор один раз в противоположном направлении, используя угол рыскания. Это должен быть последний шаг коррекции, но есть стоимость с использованием углов Эйлера.

Этот метод не работает, если я держу телефон непосредственно вверх, beacause, если угол наклона валка равен 90 градусам, и он вызывает карданный замок. Мой расчетный угол рыскания тогда неизвестен и мой обратный поворот не срабатывает.

Мой вопрос в том, как изменить/изменить матрицу вращения, чтобы я мог вращаться только вокруг оси x и y, игнорируя ось z, не используя углы эйлеров?

я alread проверил, но оно не помогло мне: How do I remove axis from a rotation matrix?

+0

Это неясно. Если телефон обращен к северу и ускоряет Восток, ** ** указывает на восток; в каком направлении вы хотите это указать? Если телефон направлен вверх и ускоряет Восток, ** ** указывает на восток; в каком направлении вы хотите это указать? – Beta

+0

Телефон будет помещен в автомобиль, а ось x телефона будет привязана осью x автомобиля, которая является передней стороной автомобиля (на отдельном шаге калибровки через gps). Если телефон стоит на север и ускоряется на восток, а ось x телефона указывает на восток, это нормально. – kolpazar

+0

Тогда, когда/почему вы должны «перерезать, чтобы получить окончательный правильный результат»? – Beta

ответ

0
a_geo = R^-1*(a_phone - R*g) = R^-1*a_phone - g 

так что все, что ты до сих пор проецировать свое беспристрастное ускорение в локальном географическом кадре (N, E, D или что-то). Если то, что вы хотите, это проекция на горизонтальную плоскость, вы просто аннулируют третья координата, позволяет сказать, что ваши индексы 1 основаны, как MATLAB или Fortran:

a_horiz=a_geo; a_horiz[3]=0; 

Или выражается с помощью матрицы,

a_horiz = [1,0,0; 
      0,1,0; 
      0,0,0] * a_geo; 

вы можете проецировать обратно на ось телефона,

R*a_horiz; 

Но это не ясно, если это действительно то, что вы хотите ... Я думаю, вы просто хотите применить вращение заголовка и иметь какое-то час ускорение по горизонтали вперед и горизонтальное боковое (правое) ускорение. Я не знаю ни одной простой трюк ... Просто распакуйте заголовок (как вы отметили, возможно, только если ваш телефон ось х не вертикально)

psi = atan2(R(1,2) , R(1,1)); 

Затем поверните горизонтальное ускорение

a_horiz_car = [ cos(psi) , sin(psi) , 0; 
       -sin(psi) , cos(psi) , 0; 
       0  ,  0 , 1] * a_horiz; 

Только Первые две координаты интересны, поэтому вы можете использовать матрицу 2x2.

+0

Спасибо за решение! – kolpazar

+0

Даже если бы была одна ошибка, которую я только что исправил в матрице [1,1,0; 1,1,0; 0,0,0], которые должны были быть [1,0,0; 0,1,0; 0,0,0] –

0

Есть ли у вашего устройства гироскопы и работает ли он 2.3 (API 9) или выше?

Если да, возможно, вы сможете использовать виртуальные датчики TYPE_GRAVITY и/или TYPE_LINEAR_ACCELERATION, чтобы получить то, что вы хотите напрямую.

Смежные вопросы