summaryrefslogtreecommitdiff
path: root/src/input_common/motion_input.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/input_common/motion_input.cpp')
-rw-r--r--src/input_common/motion_input.cpp110
1 files changed, 42 insertions, 68 deletions
diff --git a/src/input_common/motion_input.cpp b/src/input_common/motion_input.cpp
index e3aec04e1..c86a53106 100644
--- a/src/input_common/motion_input.cpp
+++ b/src/input_common/motion_input.cpp
@@ -2,43 +2,26 @@
2 2
3namespace InputCommon { 3namespace InputCommon {
4 4
5MotionInput::MotionInput(f32 new_kp, f32 new_ki, f32 new_kd) : kp(new_kp), ki(new_ki), kd(new_kd) { 5MotionInput::MotionInput(f32 new_kp, f32 new_ki, f32 new_kd)
6 accel = {}; 6 : kp(new_kp), ki(new_ki), kd(new_kd), quat{{0, 0, -1}, 0} {}
7 gyro = {};
8 gyro_drift = {};
9 gyro_threshold = 0;
10 rotations = {};
11
12 quat.w = 0;
13 quat.xyz[0] = 0;
14 quat.xyz[1] = 0;
15 quat.xyz[2] = -1;
16
17 real_error = {};
18 integral_error = {};
19 derivative_error = {};
20
21 reset_counter = 0;
22 reset_enabled = true;
23}
24 7
25void MotionInput::SetAcceleration(Common::Vec3f acceleration) { 8void MotionInput::SetAcceleration(const Common::Vec3f& acceleration) {
26 accel = acceleration; 9 accel = acceleration;
27} 10}
28 11
29void MotionInput::SetGyroscope(Common::Vec3f gyroscope) { 12void MotionInput::SetGyroscope(const Common::Vec3f& gyroscope) {
30 gyro = gyroscope - gyro_drift; 13 gyro = gyroscope - gyro_drift;
31 if (gyro.Length2() < gyro_threshold) { 14 if (gyro.Length2() < gyro_threshold) {
32 gyro = {}; 15 gyro = {};
33 } 16 }
34} 17}
35 18
36void MotionInput::SetQuaternion(Common::Quaternion<f32> quaternion) { 19void MotionInput::SetQuaternion(const Common::Quaternion<f32>& quaternion) {
37 quat = quaternion; 20 quat = quaternion;
38} 21}
39 22
40void MotionInput::SetGyroDrift(Common::Vec3f drift) { 23void MotionInput::SetGyroDrift(const Common::Vec3f& drift) {
41 drift = gyro_drift; 24 gyro_drift = drift;
42} 25}
43 26
44void MotionInput::SetGyroThreshold(f32 threshold) { 27void MotionInput::SetGyroThreshold(f32 threshold) {
@@ -53,11 +36,11 @@ void MotionInput::ResetRotations() {
53 rotations = {}; 36 rotations = {};
54} 37}
55 38
56bool MotionInput::IsMoving(f32 sensitivity) { 39bool MotionInput::IsMoving(f32 sensitivity) const {
57 return gyro.Length2() >= sensitivity || accel.Length() <= 0.9f || accel.Length() >= 1.1f; 40 return gyro.Length2() >= sensitivity || accel.Length() <= 0.9f || accel.Length() >= 1.1f;
58} 41}
59 42
60bool MotionInput::IsCalibrated(f32 sensitivity) { 43bool MotionInput::IsCalibrated(f32 sensitivity) const {
61 return real_error.Length() > sensitivity; 44 return real_error.Length() > sensitivity;
62} 45}
63 46
@@ -67,30 +50,30 @@ void MotionInput::UpdateRotation(u64 elapsed_time) {
67 50
68void MotionInput::UpdateOrientation(u64 elapsed_time) { 51void MotionInput::UpdateOrientation(u64 elapsed_time) {
69 // Short name local variable for readability 52 // Short name local variable for readability
70 f32 q1 = quat.w, q2 = quat.xyz[0], q3 = quat.xyz[1], q4 = quat.xyz[2]; 53 f32 q1 = quat.w;
71 f32 sample_period = elapsed_time / 1000000.0f; 54 f32 q2 = quat.xyz[0];
55 f32 q3 = quat.xyz[1];
56 f32 q4 = quat.xyz[2];
57 const f32 sample_period = elapsed_time / 1000000.0f;
72 58
73 auto normal_accel = accel.Normalized(); 59 const auto normal_accel = accel.Normalized();
74 auto rad_gyro = gyro * 3.1415926535f; 60 auto rad_gyro = gyro * 3.1415926535f;
75 rad_gyro.z = -rad_gyro.z; 61 rad_gyro.z = -rad_gyro.z;
76 62
77 // Ignore drift correction if acceleration is not present 63 // Ignore drift correction if acceleration is not present
78 if (normal_accel.Length() == 1.0f) { 64 if (normal_accel.Length() == 1.0f) {
79 f32 ax = -normal_accel.x; 65 const f32 ax = -normal_accel.x;
80 f32 ay = normal_accel.y; 66 const f32 ay = normal_accel.y;
81 f32 az = -normal_accel.z; 67 const f32 az = -normal_accel.z;
82 f32 vx, vy, vz;
83 Common::Vec3f new_real_error;
84 68
85 // Estimated direction of gravity 69 // Estimated direction of gravity
86 vx = 2.0f * (q2 * q4 - q1 * q3); 70 const f32 vx = 2.0f * (q2 * q4 - q1 * q3);
87 vy = 2.0f * (q1 * q2 + q3 * q4); 71 const f32 vy = 2.0f * (q1 * q2 + q3 * q4);
88 vz = q1 * q1 - q2 * q2 - q3 * q3 + q4 * q4; 72 const f32 vz = q1 * q1 - q2 * q2 - q3 * q3 + q4 * q4;
89 73
90 // Error is cross product between estimated direction and measured direction of gravity 74 // Error is cross product between estimated direction and measured direction of gravity
91 new_real_error.x = ay * vz - az * vy; 75 const Common::Vec3f new_real_error = {ay * vz - az * vy, az * vx - ax * vz,
92 new_real_error.y = az * vx - ax * vz; 76 ax * vy - ay * vx};
93 new_real_error.x = ax * vy - ay * vx;
94 77
95 derivative_error = new_real_error - real_error; 78 derivative_error = new_real_error - real_error;
96 real_error = new_real_error; 79 real_error = new_real_error;
@@ -108,15 +91,14 @@ void MotionInput::UpdateOrientation(u64 elapsed_time) {
108 rad_gyro += kd * derivative_error; 91 rad_gyro += kd * derivative_error;
109 } 92 }
110 93
111 f32 gx = rad_gyro.y; 94 const f32 gx = rad_gyro.y;
112 f32 gy = rad_gyro.x; 95 const f32 gy = rad_gyro.x;
113 f32 gz = rad_gyro.z; 96 const f32 gz = rad_gyro.z;
114 97
115 // Integrate rate of change of quaternion 98 // Integrate rate of change of quaternion
116 f32 pa, pb, pc; 99 const f32 pa = q2;
117 pa = q2; 100 const f32 pb = q3;
118 pb = q3; 101 const f32 pc = q4;
119 pc = q4;
120 q1 = q1 + (-q2 * gx - q3 * gy - q4 * gz) * (0.5f * sample_period); 102 q1 = q1 + (-q2 * gx - q3 * gy - q4 * gz) * (0.5f * sample_period);
121 q2 = pa + (q1 * gx + pb * gz - pc * gy) * (0.5f * sample_period); 103 q2 = pa + (q1 * gx + pb * gz - pc * gy) * (0.5f * sample_period);
122 q3 = pb + (q1 * gy - pa * gz + pc * gx) * (0.5f * sample_period); 104 q3 = pb + (q1 * gy - pa * gz + pc * gx) * (0.5f * sample_period);
@@ -129,41 +111,33 @@ void MotionInput::UpdateOrientation(u64 elapsed_time) {
129 quat = quat.Normalized(); 111 quat = quat.Normalized();
130} 112}
131 113
132std::array<Common::Vec3f, 3> MotionInput::GetOrientation() { 114std::array<Common::Vec3f, 3> MotionInput::GetOrientation() const {
133 std::array<Common::Vec3f, 3> orientation = {}; 115 const Common::Quaternion<float> quad{.xyz = {-quat.xyz[1], -quat.xyz[0], -quat.w},
134 Common::Quaternion<float> quad; 116 .w = -quat.xyz[2]};
135 117 const std::array<float, 16> matrix4x4 = quad.ToMatrix();
136 quad.w = -quat.xyz[2];
137 quad.xyz[0] = -quat.xyz[1];
138 quad.xyz[1] = -quat.xyz[0];
139 quad.xyz[2] = -quat.w;
140
141 std::array<float, 16> matrix4x4 = quad.ToMatrix();
142
143 orientation[0] = Common::Vec3f(matrix4x4[0], matrix4x4[1], matrix4x4[2]);
144 orientation[1] = Common::Vec3f(matrix4x4[4], matrix4x4[5], matrix4x4[6]);
145 orientation[2] = Common::Vec3f(matrix4x4[8], matrix4x4[9], matrix4x4[10]);
146 118
147 return orientation; 119 return {Common::Vec3f(matrix4x4[0], matrix4x4[1], matrix4x4[2]),
120 Common::Vec3f(matrix4x4[4], matrix4x4[5], matrix4x4[6]),
121 Common::Vec3f(matrix4x4[8], matrix4x4[9], matrix4x4[10])};
148} 122}
149 123
150Common::Vec3f MotionInput::GetAcceleration() { 124Common::Vec3f MotionInput::GetAcceleration() const {
151 return accel; 125 return accel;
152} 126}
153 127
154Common::Vec3f MotionInput::GetGyroscope() { 128Common::Vec3f MotionInput::GetGyroscope() const {
155 return gyro; 129 return gyro;
156} 130}
157 131
158Common::Quaternion<f32> MotionInput::GetQuaternion() { 132Common::Quaternion<f32> MotionInput::GetQuaternion() const {
159 return quat; 133 return quat;
160} 134}
161 135
162Common::Vec3f MotionInput::GetRotations() { 136Common::Vec3f MotionInput::GetRotations() const {
163 return rotations; 137 return rotations;
164} 138}
165 139
166void MotionInput::resetOrientation() { 140void MotionInput::ResetOrientation() {
167 if (!reset_enabled) { 141 if (!reset_enabled) {
168 return; 142 return;
169 } 143 }
@@ -182,4 +156,4 @@ void MotionInput::resetOrientation() {
182 reset_counter = 0; 156 reset_counter = 0;
183 } 157 }
184} 158}
185} // namespace InputCommon \ No newline at end of file 159} // namespace InputCommon