CMAttitude - yaw,pitch,roll problem

gagagu

Erdapfel
Mitglied seit
25.03.15
Beiträge
2
Hallo Leute,
ich habe mir ein kleines Programm geschrieben um mein iPhone mit Opentrack als Headtracker zu verwenden. Hierzu habe ich zuerst mit core motion den CMAttitude verwendet und yaw,pitch,roll and opentrack gesendet. Das funktioniert leider immer nur teilweise. Da ich das Handy quasi vors Gesicht halte bekomme ich je nach Position (Drehung im 90 grad) komische Anzeigewerte. Außerdem verändern sich beim Bewegen des iPhone die anderen Achsen mit obwohl ich diese nicht drehe. Ich durchsuche schon seit Tagen das Internet nach hilfreichen Artikeln und habe etwas über das Gimbal Lock Problem gefunden. Dabei heisst es das man nciht die CMAttitude (yaw,pitch,roll) Werte nehmen soll, sondern über sog. quaternions yaw,pitch und roll errechen soll (was auch immer das ist). Leider führt das nicht zum gewünschten Ergebnis. Ich habe dann versucht das Koordinatensystem zu drehen, oder über ReferenceFrame zu arbeiten aber irgendwie klappt das auch nicht.

Also was will ich eigentlich?
Ich möchte mir das Handy vors Gesicht halten (landscape) und von da an yaw,pitch und roll ermitteln. Wenn ich mich um 90 Grad nach links oder rechts drehen soll das natürlich auch noch funktionieren.

Wie gesagt ich durchsuche schon seit Tagen das Internet und möchte mich schließlich an Euch wenden. Mathe ist leider nicht mein Steckenpferd.

Wenn mir jemand helfen könne wäre das echt super.

Mein Code ist übrigens in swift, ich kann mir aber auch objective-c beispiel code übersetzen.

Code:
  //let ref = CMAttitudeReferenceFrameXArbitraryCorrectedZVertical
  //let ref = CMAttitudeReferenceFrameXArbitraryZVertical
  //let ref = CMAttitudeReferenceFrameXMagneticNorthZVertical
  //let ref = CMAttitudeReferenceFrameXTrueNorthZVertical
 
  if manager.deviceMotionAvailable {
  //self.manager.showsDeviceMovementDisplay = true
  self.manager.deviceMotionUpdateInterval = 1.0 / 60.0
 
 
  //let queue = NSOperationQueue.mainQueue()
  //manager.startDeviceMotionUpdatesUsingReferenceFrame(ref, toQueue: queue, withHandler: {
  //  (data, error) in
 
  //  self.SetTrackingData(data.attitude)
  //})
 
  manager.startDeviceMotionUpdatesToQueue(queue) {
  (data, error) in
 
  self.SetTrackingData(data.attitude)
  }
  }



func SetTrackingData(data:CMAttitude) -> Void{
 var error: NSError?

 daten = NSMutableData()
 var x: Double = 0
 var quat : CMQuaternion = data.quaternion

 // drehen um x grad
 var rot : CMQuaternion = CMQuaternion(x: cos(90.0/2), y: 0.0, z: 0.0, w: sin(90.0/2))

 // finde in swift keine funktion zur Multiplizierung von quaterions
 var xx:Double = quat.x * rot.x - quat.y * rot.y - quat.z * rot.z - quat.w * rot.w
 var yy:Double = quat.x * rot.y + quat.y * rot.x - quat.z * rot.w + quat.w * rot.z
 var zz:Double = quat.x * rot.z + quat.y * rot.w + quat.z * rot.x - quat.w * rot.y
 var ww:Double = quat.x * rot.w - quat.y * rot.z + quat.z * rot.y + quat.w * rot.x
 var newquat :CMQuaternion = CMQuaternion(x: xx, y: yy, z: zz, w: ww)

 // yaw, roll,pitch errechnen in Grad
 var yaw = asin(2*(newquat.x * newquat.y - newquat.w * newquat.z)) * 180 / M_PI
 var pitch = atan2(2*(newquat.x * newquat.w - newquat.y * newquat.z),1 - 2 * newquat.x * newquat.x - 2 * newquat.z * newquat.z) * 180 / M_PI
 var roll = atan2(2*(newquat.y * newquat.w - newquat.x * newquat.z),1 - 2 * newquat.y * newquat.y - 2 * newquat.z * newquat.z) * 180 / M_PI

 println("yaw: \(yaw), pitch: \(pitch), roll: \(roll)")

 // senden per udp
 daten.appendData(NSData(bytes: &x, length: sizeof(Double)))
 daten.appendData(NSData(bytes: &x, length: sizeof(Double)))
 daten.appendData(NSData(bytes: &x, length: sizeof(Double)))
 daten.appendData(NSData(bytes: &yaw, length: sizeof(Double)))
 daten.appendData(NSData(bytes: &pitch, length: sizeof(Double)))
 daten.appendData(NSData(bytes: &roll, length: sizeof(Double)))

 if(Settings.getInstance.StreamData == false){
 self.SendTrackingData()
 }

 iflet error = error {
 self.Alert("Error on set tracking data. \(error.description)")
 self.navigationController?.navigationBarHidden = false
 self.navigationController?.popViewControllerAnimated(true)
 return
 }
}
 

gagagu

Erdapfel
Mitglied seit
25.03.15
Beiträge
2
Hallo,
ich habe eine Möglichkeit gefudnen die zu funktionieren scheint. Ich verwende die acceleration daten für roll und pitch und die device motion daten für yaw. Das funktioniert anscheinen gut.