{"action":"created","issue":{"url":"https://api.github.com/repos/cleanflight/cleanflight/issues/2469","repository_url":"https://api.github.com/repos/cleanflight/cleanflight","labels_url":"https://api.github.com/repos/cleanflight/cleanflight/issues/2469/labels{/name}","comments_url":"https://api.github.com/repos/cleanflight/cleanflight/issues/2469/comments","events_url":"https://api.github.com/repos/cleanflight/cleanflight/issues/2469/events","html_url":"https://github.com/cleanflight/cleanflight/issues/2469","id":185774943,"number":2469,"title":"Fix the angle calculation","user":{"login":"mkschreder","id":4483721,"avatar_url":"https://avatars.githubusercontent.com/u/4483721?v=3","gravatar_id":"","url":"https://api.github.com/users/mkschreder","html_url":"https://github.com/mkschreder","followers_url":"https://api.github.com/users/mkschreder/followers","following_url":"https://api.github.com/users/mkschreder/following{/other_user}","gists_url":"https://api.github.com/users/mkschreder/gists{/gist_id}","starred_url":"https://api.github.com/users/mkschreder/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mkschreder/subscriptions","organizations_url":"https://api.github.com/users/mkschreder/orgs","repos_url":"https://api.github.com/users/mkschreder/repos","events_url":"https://api.github.com/users/mkschreder/events{/privacy}","received_events_url":"https://api.github.com/users/mkschreder/received_events","type":"User","site_admin":false},"labels":[{"id":211618588,"url":"https://api.github.com/repos/cleanflight/cleanflight/labels/requires-feedback","name":"requires-feedback","color":"bfe5bf","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":9,"created_at":"2016-10-27T20:42:24Z","updated_at":"2016-10-31T11:53:48Z","closed_at":null,"body":"In all versions of cleanflight the imu code calculates pitch and roll angles from DCM vectors as follows: \n\n```\nself->attitude.values.roll = lrintf(atan2_approx(self->rMat[2][1], self->rMat[2][2]) * (1800.0f / M_PIf));\nself->attitude.values.pitch = lrintf(((0.5f * M_PIf) - acos_approx(-self->rMat[2][0])) * (1800.0f / M_PIf));\n```\n\nThis is incorrect and results in huge variations of pitch and roll around the singularity point when nose is pointing down. \n\nThe correct way is like this: \n\n```\n    float px = self->rMat[2][0];\n    float py = self->rMat[2][1];\n    float pz = self->rMat[2][2];\n    float sign_z = (pz > 0) - (pz < 0); \n\n    self->attitude.values.roll = lrintf(atan2_approx(py, sign_z * sqrtf(pz * pz + 0.01f * px * px)) * (1800.0f / M_PIf));  \n    self->attitude.values.pitch = lrintf(atan2_approx(-px, sqrtf(py * py + pz * pz)) * (1800.0f / M_PIf)); \n```\n\nThis still results in a singularity but the adverse effects are quite minimal and only similar to when you look down in an fpv game where your camera is euler angle based - the error only effects the heading which can become random as opposed to both pitch and roll as in current cleanflight approach. \n\nFor reference see this application note eq 37 and 38: \nhttps://www.nxp.com/files/sensors/doc/app_note/AN3461.pdf\n"},"comment":{"url":"https://api.github.com/repos/cleanflight/cleanflight/issues/comments/257275187","html_url":"https://github.com/cleanflight/cleanflight/issues/2469#issuecomment-257275187","issue_url":"https://api.github.com/repos/cleanflight/cleanflight/issues/2469","id":257275187,"user":{"login":"ledvinap","id":2318015,"avatar_url":"https://avatars.githubusercontent.com/u/2318015?v=3","gravatar_id":"","url":"https://api.github.com/users/ledvinap","html_url":"https://github.com/ledvinap","followers_url":"https://api.github.com/users/ledvinap/followers","following_url":"https://api.github.com/users/ledvinap/following{/other_user}","gists_url":"https://api.github.com/users/ledvinap/gists{/gist_id}","starred_url":"https://api.github.com/users/ledvinap/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ledvinap/subscriptions","organizations_url":"https://api.github.com/users/ledvinap/orgs","repos_url":"https://api.github.com/users/ledvinap/repos","events_url":"https://api.github.com/users/ledvinap/events{/privacy}","received_events_url":"https://api.github.com/users/ledvinap/received_events","type":"User","site_admin":false},"created_at":"2016-10-31T11:53:48Z","updated_at":"2016-10-31T11:53:48Z","body":"@mkschreder : Well, my 3d imagination is a bit too poor for this. Takes time ...\r\n\r\nIt makes sense, at least for display purposes ... I would still prefer singularity-free solution, but that will take some time .. \r\n\r\n\r\n"}}
{"actor":{"display_login":"ledvinap"}}