Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CMRotationMatrix (Attitude) is broken #2

Open
barksten opened this issue Mar 22, 2021 · 5 comments
Open

CMRotationMatrix (Attitude) is broken #2

barksten opened this issue Mar 22, 2021 · 5 comments

Comments

@barksten
Copy link
Contributor

When replacing vanilla CMMotionManager I get some flipped axes of the rotation matrix

I've stopped at a breakpoint in Attitude.init(_ attitude: CMAttitude) and let it assign self.quaternion
Comparing the rotation matrices yields the following results:

(lldb) po attitude.rotationMatrix
▿ CMRotationMatrix
  - m11 : -0.1969096064567566
  - m12 : 0.9799075722694397
  - m13 : -0.03173968195915222
  - m21 : -0.7388630509376526
  - m22 : -0.12703722715377808
  - m23 : 0.6617723703384399
  - m31 : 0.6444437503814697
  - m32 : 0.15376073122024536
  - m33 : 0.7490326166152954

(lldb) po self.rotationMatrix
▿ CMRotationMatrix
  - m11 : -0.19690976161972862
  - m12 : -0.7388631294669954
  - m13 : 0.6444438080182784
  - m21 : 0.979907719073764
  - m22 : -0.12703738138275833
  - m23 : 0.1537607421647839
  - m31 : -0.031739689326065
  - m32 : 0.6617724530725418
  - m33 : 0.7490325843885801

(lldb) 

Expected behavior
To have the same axes would be nice..

Environment

  • Xcode 12.4
  • Swift 5.3
  • OS iOS 14.4
@barksten
Copy link
Contributor Author

barksten commented Mar 22, 2021

Temporary workaround is to flip the matrix:

extension CMRotationMatrix {
    var flipped: Self {
        var flipped = CMRotationMatrix()
        flipped.m11 = self.m11
        flipped.m12 = self.m21
        flipped.m13 = self.m31
        flipped.m21 = self.m12
        flipped.m22 = self.m22
        flipped.m23 = self.m32
        flipped.m31 = self.m13
        flipped.m32 = self.m23
        flipped.m33 = self.m33
        return flipped
    }
}

@mbrandonw
Copy link
Member

Good find! Some of the math here file must be wrong or CoreMotion has a different basis than what we assume :/

Will look into it soon, but if the fix really is to transpose the matrix we'd be happy to except a PR to update that computed property.

@barksten
Copy link
Contributor Author

I'll give it a try later today. The hardest part is to write tests since the (core motion) framework types don't have any useful public constructors (I guess that's why you wrote your own implementations in the first place...)

@barksten
Copy link
Contributor Author

barksten commented Feb 24, 2022

Sorry, I have not worked on this in a while... Anyway, today I have some new findings:

I put a breakpoint inside DeviceMotion.init(_ deviceMotion: CMDeviceMotion):

po deviceMotion

QuaternionX -0.000882 QuaternionY -0.005251 QuaternionZ 0.932196 QuaternionW -0.361915 UserAccelX 0.001116 UserAccelY 0.000844 UserAccelZ -0.003047 RotationRateX -0.000685 RotationRateY 0.003429 RotationRateZ 0.000225 MagneticFieldX -15.539566 MagneticFieldY 8.030884 MagneticFieldZ -36.237579 MagneticFieldAccuracy 2 Heading 47.562225 SensorLocation 0 @ 667686.919423

po self.attitude
▿ Attitude
  ▿ quaternion : CMQuaternion
    - x : -0.000882195988422291
    - y : -0.005250768163730715
    - z : 0.9321958498359307
    - w : -0.36191515007517006

So far, so good.. if we continue:

po deviceMotion.attitude
CMAttitude Pitch: -0.524317, Roll: 0.312014, Yaw: -137.562226

po self.attitude.pitch * 180 / Double.pi
0.3120013533421466

po self.attitude.roll * 180 / Double.pi
-0.52432466754302

po self.attitude.yaw * 180 / Double.pi
-137.56508141514132

My conclusion is that the bases on CoreMotion is different than your assumptions and it's not just the rotation matrix that is broken.

For reference

I'll prepare a PR later tonight.

@barksten
Copy link
Contributor Author

barksten commented Mar 1, 2022

I've created a new PR with just the rotation matrix fix. The pitch/roll is still an issue. I've searched around the we in my quest to understand the quirks of CMQuaternion and have found this old SO post (unexpected results from glkquaternion conversion from cmquaternion)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants