2012-02-28 2 views

ответ

22

Ее лучше использовать кватернион, чем углы Эйлера .... В крену, тангажу и рыскания значения могут быть получены из кватернионов с помощью этих формул:

roll = atan2(2*y*w - 2*x*z, 1 - 2*y*y - 2*z*z) 
pitch = atan2(2*x*w - 2*y*z, 1 - 2*x*x - 2*z*z) 
yaw = asin(2*x*y + 2*z*w) 

Он может быть реализован в виде:

CMQuaternion quat = self.motionManager.deviceMotion.attitude.quaternion; 
myRoll = radiansToDegrees(atan2(2*(quat.y*quat.w - quat.x*quat.z), 1 - 2*quat.y*quat.y - 2*quat.z*quat.z)) ; 
myPitch = radiansToDegrees(atan2(2*(quat.x*quat.w + quat.y*quat.z), 1 - 2*quat.x*quat.x - 2*quat.z*quat.z)); 
myYaw = radiansToDegrees(asin(2*quat.x*quat.y + 2*quat.w*quat.z)); 

где radianstoDegrees директива препроцессора реализации ed as:

#define radiansToDegrees(x) (180/M_PI)*x 

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

Более подробную информацию о конверсии можно найти здесь: tinkerforge и здесь: Conversion between Quaternions and Euler angles.

+1

Мне любопытно, в чем причина« лучше использовать Quaternion, чем Euler Angles »? – Jacksonkr

+0

Спасибо. Это работает хорошо. motionManager.deviceMotion.attitude.pitch/roll/yaw действительно неустойчивы. Мне интересно, почему Apple не исправляет их. –

1

тангаж, рыскание, крен из матрицы. Любые идеи, как я мог это сделать?

В каком порядке? Шаг, рыскание и рулон, обычно называемые углами Эйлера, не представляют вращения однозначно. В зависимости от того, как вы выполняете отдельные подвращения, вы получаете совершенно разные матрицы вращения.

Мои личные рекомендации: Не используйте углы Эйлера вообще, они просто требуют (числовые) проблемы. Используйте матрицу (вы уже знаете) или кватернион.

-1

Найдено это сам:

CMAttitude *currentAttitude = motionManager.deviceMotion.attitude;  

     if (currentAttitude == nil) 
     { 
      NSLog(@"Could not get device orientation."); 
      return; 
     } 
     else { 
      float PI = 3.14159265; 
      float yaw = currentAttitude.yaw * 180/PI; 
      float pitch = currentAttitude.pitch * 180/PI; 
      float roll = currentAttitude.roll * 180/PI; 

     } 
+1

'M_PI' будет более точным представлением pi и сохранит вам переменную;) –

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