diff options
Diffstat (limited to 'src/input_common/motion_input.cpp')
| -rw-r--r-- | src/input_common/motion_input.cpp | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/src/input_common/motion_input.cpp b/src/input_common/motion_input.cpp index c86a53106..88fddb1b9 100644 --- a/src/input_common/motion_input.cpp +++ b/src/input_common/motion_input.cpp | |||
| @@ -37,18 +37,25 @@ void MotionInput::ResetRotations() { | |||
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | bool MotionInput::IsMoving(f32 sensitivity) const { | 39 | bool MotionInput::IsMoving(f32 sensitivity) const { |
| 40 | return gyro.Length2() >= sensitivity || accel.Length() <= 0.9f || accel.Length() >= 1.1f; | 40 | return gyro.Length() >= sensitivity || accel.Length() <= 0.9f || accel.Length() >= 1.1f; |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | bool MotionInput::IsCalibrated(f32 sensitivity) const { | 43 | bool MotionInput::IsCalibrated(f32 sensitivity) const { |
| 44 | return real_error.Length() > sensitivity; | 44 | return real_error.Length() < sensitivity; |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | void MotionInput::UpdateRotation(u64 elapsed_time) { | 47 | void MotionInput::UpdateRotation(u64 elapsed_time) { |
| 48 | rotations += gyro * elapsed_time; | 48 | const f32 sample_period = elapsed_time / 1000000.0f; |
| 49 | if (sample_period > 0.1f) { | ||
| 50 | return; | ||
| 51 | } | ||
| 52 | rotations += gyro * sample_period; | ||
| 49 | } | 53 | } |
| 50 | 54 | ||
| 51 | void MotionInput::UpdateOrientation(u64 elapsed_time) { | 55 | void MotionInput::UpdateOrientation(u64 elapsed_time) { |
| 56 | if (!IsCalibrated(0.1f)) { | ||
| 57 | ResetOrientation(); | ||
| 58 | } | ||
| 52 | // Short name local variable for readability | 59 | // Short name local variable for readability |
| 53 | f32 q1 = quat.w; | 60 | f32 q1 = quat.w; |
| 54 | f32 q2 = quat.xyz[0]; | 61 | f32 q2 = quat.xyz[0]; |
| @@ -56,12 +63,20 @@ void MotionInput::UpdateOrientation(u64 elapsed_time) { | |||
| 56 | f32 q4 = quat.xyz[2]; | 63 | f32 q4 = quat.xyz[2]; |
| 57 | const f32 sample_period = elapsed_time / 1000000.0f; | 64 | const f32 sample_period = elapsed_time / 1000000.0f; |
| 58 | 65 | ||
| 66 | // ignore invalid elapsed time | ||
| 67 | if (sample_period > 0.1f) { | ||
| 68 | return; | ||
| 69 | } | ||
| 70 | |||
| 59 | const auto normal_accel = accel.Normalized(); | 71 | const auto normal_accel = accel.Normalized(); |
| 60 | auto rad_gyro = gyro * 3.1415926535f; | 72 | auto rad_gyro = gyro * 3.1415926535f * 2; |
| 73 | const f32 swap = rad_gyro.x; | ||
| 74 | rad_gyro.x = rad_gyro.y; | ||
| 75 | rad_gyro.y = -swap; | ||
| 61 | rad_gyro.z = -rad_gyro.z; | 76 | rad_gyro.z = -rad_gyro.z; |
| 62 | 77 | ||
| 63 | // Ignore drift correction if acceleration is not present | 78 | // Ignore drift correction if acceleration is not reliable |
| 64 | if (normal_accel.Length() == 1.0f) { | 79 | if (accel.Length() >= 0.75f && accel.Length() <= 1.25f) { |
| 65 | const f32 ax = -normal_accel.x; | 80 | const f32 ax = -normal_accel.x; |
| 66 | const f32 ay = normal_accel.y; | 81 | const f32 ay = normal_accel.y; |
| 67 | const f32 az = -normal_accel.z; | 82 | const f32 az = -normal_accel.z; |
| @@ -72,14 +87,14 @@ void MotionInput::UpdateOrientation(u64 elapsed_time) { | |||
| 72 | const f32 vz = q1 * q1 - q2 * q2 - q3 * q3 + q4 * q4; | 87 | const f32 vz = q1 * q1 - q2 * q2 - q3 * q3 + q4 * q4; |
| 73 | 88 | ||
| 74 | // Error is cross product between estimated direction and measured direction of gravity | 89 | // Error is cross product between estimated direction and measured direction of gravity |
| 75 | const Common::Vec3f new_real_error = {ay * vz - az * vy, az * vx - ax * vz, | 90 | const Common::Vec3f new_real_error = {az * vx - ax * vz, ay * vz - az * vy, |
| 76 | ax * vy - ay * vx}; | 91 | ax * vy - ay * vx}; |
| 77 | 92 | ||
| 78 | derivative_error = new_real_error - real_error; | 93 | derivative_error = new_real_error - real_error; |
| 79 | real_error = new_real_error; | 94 | real_error = new_real_error; |
| 80 | 95 | ||
| 81 | // Prevent integral windup | 96 | // Prevent integral windup |
| 82 | if (ki != 0.0f) { | 97 | if (ki != 0.0f && !IsCalibrated(0.05f)) { |
| 83 | integral_error += real_error; | 98 | integral_error += real_error; |
| 84 | } else { | 99 | } else { |
| 85 | integral_error = {}; | 100 | integral_error = {}; |
| @@ -112,13 +127,15 @@ void MotionInput::UpdateOrientation(u64 elapsed_time) { | |||
| 112 | } | 127 | } |
| 113 | 128 | ||
| 114 | std::array<Common::Vec3f, 3> MotionInput::GetOrientation() const { | 129 | std::array<Common::Vec3f, 3> MotionInput::GetOrientation() const { |
| 115 | const Common::Quaternion<float> quad{.xyz = {-quat.xyz[1], -quat.xyz[0], -quat.w}, | 130 | const Common::Quaternion<float> quad{ |
| 116 | .w = -quat.xyz[2]}; | 131 | .xyz = {-quat.xyz[1], -quat.xyz[0], -quat.w}, |
| 132 | .w = -quat.xyz[2], | ||
| 133 | }; | ||
| 117 | const std::array<float, 16> matrix4x4 = quad.ToMatrix(); | 134 | const std::array<float, 16> matrix4x4 = quad.ToMatrix(); |
| 118 | 135 | ||
| 119 | return {Common::Vec3f(matrix4x4[0], matrix4x4[1], matrix4x4[2]), | 136 | return {Common::Vec3f(matrix4x4[0], matrix4x4[1], -matrix4x4[2]), |
| 120 | Common::Vec3f(matrix4x4[4], matrix4x4[5], matrix4x4[6]), | 137 | Common::Vec3f(matrix4x4[4], matrix4x4[5], -matrix4x4[6]), |
| 121 | Common::Vec3f(matrix4x4[8], matrix4x4[9], matrix4x4[10])}; | 138 | Common::Vec3f(-matrix4x4[8], -matrix4x4[9], matrix4x4[10])}; |
| 122 | } | 139 | } |
| 123 | 140 | ||
| 124 | Common::Vec3f MotionInput::GetAcceleration() const { | 141 | Common::Vec3f MotionInput::GetAcceleration() const { |