Подтвердить что ты не робот

3d Accelerometer рассчитать ориентацию

У меня есть значения акселерометра для 3-й оси (обычно, когда есть только гравитация, содержит данные от -1,0 до 1,0):

  float Rx;
  float Ry;
  float Rz;

Я делаю вычисления сомы, затем получаю углы для каждой оси.

  float R =  sqrt(pow(Rx,2)+pow(Ry,2)+pow(Rz,2));
  float Arx = acos(Rx/R)*180/M_PI;
  float Ary = acos(Ry/R)*180/M_PI;
  float Arz = acos(Rz/R)*180/M_PI;

Затем я устанавливаю значения для углов окна в opengl

rquad = Arx;
yquad = Ary;

Который вращает мое поле:

glRotatef(yquad,1.0f,0.0f,0.0f);
glRotatef(rquad,0.0f,1.0f,0.0f);

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

Обновление: Окончательный ответ в моем случае:

  rquad = -atan2(Rx/R, Rz/R)*180/M_PI;
  yquad = -atan2(Ry/R, Rz/R)*180/M_PI;
4b9b3361

Ответ 1

Правильный ответ:

Roll = atan2(Y, Z) * 180/M_PI;
Pitch = atan2(-X, sqrt(Y*Y + Z*Z)) * 180/M_PI;

Источник: http://www.freescale.com/files/sensors/doc/app_note/AN3461.pdf (стр. 10, 25 и 26)

Ответ

uesp неверен. Это похоже на приемлемое приближение, пока шаг и бросок не достигнут выше 45 градусов.

Я могу придерживаться другого соглашения об ориентации, но даже если вы меняете оси и инвертируете значения любым способом, вычисления uesp никогда не будут эквивалентными.

Ответ 2

В то время как ответ matteo верен, он не предоставляет полного, полного решения: Формулы верны:

Roll = atan2(Y, Z) * 180/M_PI;
Pitch = atan2(-X, sqrt(Y*Y + Z*Z)) * 180/M_PI;

Однако, когда шаг равен + 90/-90 градусов, а ось X вертикально направлена ​​вверх/вниз, нормальный выходной сигнал идеального акселерометра должен быть:

accX = -1  / accX = 1 
accY = 0
accZ = 0

Это означает, что roll angle of 0 degrees; верный. Но на практике выход акселерометра является шумным, и вы получите что-то ближе:

accX = -1  / accX = 1 
accY = 0.003
accZ = 0.004

Это может показаться небольшим, но это приведет к тому, что угол наклона рулона будет ~ 30 дрелей, что неверно.

Очевидным инстинктом было бы отфильтровать последние цифры, но это повлияло бы на точность, что не всегда приемлемо.

Компромисс, который очень хорошо объясняется в примечании к заметке, заключается в том, что он содержит очень небольшой процент показаний оси X акселерометра в формуле для roll:

Roll  = atan2( Y,   sign* sqrt(Z*Z+ miu*X*X));
sign  = 1 if accZ>0, -1 otherwise 
miu = 0.001

Ошибка, введенная таким образом, значительно меньше, чем предыдущий случай: 2-3 градуса при измерении рулона при тех же условиях, которые были описаны выше.

Ответ 3

Я пробовал рекомендованное решение (matteo's), и, хотя сначала казалось, что он отлично работает, я заметил, что когда шаг приближается к 90 градусам (начиная примерно с 70 градусов, но не обязательно согласовываясь между разными телефонами), рулон внезапно вспыхивает. Когда шаг составляет 90, рулон, который должен быть около 0, теперь составляет более 100 и продолжает увеличиваться до 180. Я пытаюсь придумать способ математически предотвратить это, если я ограничу рулон до + 90/-90 ведет себя нормально, но я не получаю диапазон, который я хочу (+ 180/-180): Math.atan2 (y, Math.sqrt((xx) + (zz))) * (180/Math.PI))

Ответ 4

Я использую следующие вычисления для преобразования наших показаний акселерометра в значения рулона и шага:

Roll = atan2( sqrt(Y*Y + X*X), Z) * 180/M_PI;
Pitch = atan2( sqrt(X*X + Z*Z), Y) * 180/M_PI;

Вам может потребоваться изменить значения X/Y/Z или перевести Roll/Pitch в зависимости от того, как определяются ваши акселерометры. Чтобы использовать их на дисплее, это просто:

glRotatef (Pitch, 0.0f, 0.0f, 1.0f);
glRotatef (Roll,  1.0f, 0.0f, 0.0f);