diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hid/emulated_controller.cpp | 6 | ||||
| -rw-r--r-- | src/core/hid/emulated_controller.h | 3 | ||||
| -rw-r--r-- | src/core/hid/motion_input.cpp | 21 | ||||
| -rw-r--r-- | src/core/hid/motion_input.h | 11 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_input_player.cpp | 3 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_input_player_widget.cpp | 20 |
6 files changed, 53 insertions, 11 deletions
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp index c7f0af71f..366880711 100644 --- a/src/core/hid/emulated_controller.cpp +++ b/src/core/hid/emulated_controller.cpp | |||
| @@ -688,6 +688,12 @@ void EmulatedController::SetMotionParam(std::size_t index, Common::ParamPackage | |||
| 688 | ReloadInput(); | 688 | ReloadInput(); |
| 689 | } | 689 | } |
| 690 | 690 | ||
| 691 | void EmulatedController::StartMotionCalibration() { | ||
| 692 | for (ControllerMotionInfo& motion : controller.motion_values) { | ||
| 693 | motion.emulated.Calibrate(); | ||
| 694 | } | ||
| 695 | } | ||
| 696 | |||
| 691 | void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback, std::size_t index, | 697 | void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback, std::size_t index, |
| 692 | Common::UUID uuid) { | 698 | Common::UUID uuid) { |
| 693 | if (index >= controller.button_values.size()) { | 699 | if (index >= controller.button_values.size()) { |
diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h index fa4ad7fae..88fad2f56 100644 --- a/src/core/hid/emulated_controller.h +++ b/src/core/hid/emulated_controller.h | |||
| @@ -290,6 +290,9 @@ public: | |||
| 290 | */ | 290 | */ |
| 291 | void SetMotionParam(std::size_t index, Common::ParamPackage param); | 291 | void SetMotionParam(std::size_t index, Common::ParamPackage param); |
| 292 | 292 | ||
| 293 | /// Auto calibrates the current motion devices | ||
| 294 | void StartMotionCalibration(); | ||
| 295 | |||
| 293 | /// Returns the latest button status from the controller with parameters | 296 | /// Returns the latest button status from the controller with parameters |
| 294 | ButtonValues GetButtonsValues() const; | 297 | ButtonValues GetButtonsValues() const; |
| 295 | 298 | ||
diff --git a/src/core/hid/motion_input.cpp b/src/core/hid/motion_input.cpp index b60478dbb..f56f2ae1d 100644 --- a/src/core/hid/motion_input.cpp +++ b/src/core/hid/motion_input.cpp | |||
| @@ -37,11 +37,17 @@ void MotionInput::SetGyroscope(const Common::Vec3f& gyroscope) { | |||
| 37 | gyro.y = std::clamp(gyro.y, -GyroMaxValue, GyroMaxValue); | 37 | gyro.y = std::clamp(gyro.y, -GyroMaxValue, GyroMaxValue); |
| 38 | gyro.z = std::clamp(gyro.z, -GyroMaxValue, GyroMaxValue); | 38 | gyro.z = std::clamp(gyro.z, -GyroMaxValue, GyroMaxValue); |
| 39 | 39 | ||
| 40 | // Auto adjust drift to minimize drift | 40 | // Auto adjust gyro_bias to minimize drift |
| 41 | if (!IsMoving(IsAtRestRelaxed)) { | 41 | if (!IsMoving(IsAtRestRelaxed)) { |
| 42 | gyro_bias = (gyro_bias * 0.9999f) + (gyroscope * 0.0001f); | 42 | gyro_bias = (gyro_bias * 0.9999f) + (gyroscope * 0.0001f); |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | // Adjust drift when calibration mode is enabled | ||
| 46 | if (calibration_mode) { | ||
| 47 | gyro_bias = (gyro_bias * 0.99f) + (gyroscope * 0.01f); | ||
| 48 | StopCalibration(); | ||
| 49 | } | ||
| 50 | |||
| 45 | if (gyro.Length() < gyro_threshold * user_gyro_threshold) { | 51 | if (gyro.Length() < gyro_threshold * user_gyro_threshold) { |
| 46 | gyro = {}; | 52 | gyro = {}; |
| 47 | } else { | 53 | } else { |
| @@ -107,6 +113,19 @@ void MotionInput::UpdateRotation(u64 elapsed_time) { | |||
| 107 | rotations += gyro * sample_period; | 113 | rotations += gyro * sample_period; |
| 108 | } | 114 | } |
| 109 | 115 | ||
| 116 | void MotionInput::Calibrate() { | ||
| 117 | calibration_mode = true; | ||
| 118 | calibration_counter = 0; | ||
| 119 | } | ||
| 120 | |||
| 121 | void MotionInput::StopCalibration() { | ||
| 122 | if (calibration_counter++ > CalibrationSamples) { | ||
| 123 | calibration_mode = false; | ||
| 124 | ResetQuaternion(); | ||
| 125 | ResetRotations(); | ||
| 126 | } | ||
| 127 | } | ||
| 128 | |||
| 110 | // Based on Madgwick's implementation of Mayhony's AHRS algorithm. | 129 | // Based on Madgwick's implementation of Mayhony's AHRS algorithm. |
| 111 | // https://github.com/xioTechnologies/Open-Source-AHRS-With-x-IMU/blob/master/x-IMU%20IMU%20and%20AHRS%20Algorithms/x-IMU%20IMU%20and%20AHRS%20Algorithms/AHRS/MahonyAHRS.cs | 130 | // https://github.com/xioTechnologies/Open-Source-AHRS-With-x-IMU/blob/master/x-IMU%20IMU%20and%20AHRS%20Algorithms/x-IMU%20IMU%20and%20AHRS%20Algorithms/AHRS/MahonyAHRS.cs |
| 112 | void MotionInput::UpdateOrientation(u64 elapsed_time) { | 131 | void MotionInput::UpdateOrientation(u64 elapsed_time) { |
diff --git a/src/core/hid/motion_input.h b/src/core/hid/motion_input.h index 482719359..11678983d 100644 --- a/src/core/hid/motion_input.h +++ b/src/core/hid/motion_input.h | |||
| @@ -23,6 +23,8 @@ public: | |||
| 23 | static constexpr float GyroMaxValue = 5.0f; | 23 | static constexpr float GyroMaxValue = 5.0f; |
| 24 | static constexpr float AccelMaxValue = 7.0f; | 24 | static constexpr float AccelMaxValue = 7.0f; |
| 25 | 25 | ||
| 26 | static constexpr std::size_t CalibrationSamples = 300; | ||
| 27 | |||
| 26 | explicit MotionInput(); | 28 | explicit MotionInput(); |
| 27 | 29 | ||
| 28 | MotionInput(const MotionInput&) = default; | 30 | MotionInput(const MotionInput&) = default; |
| @@ -49,6 +51,8 @@ public: | |||
| 49 | void UpdateRotation(u64 elapsed_time); | 51 | void UpdateRotation(u64 elapsed_time); |
| 50 | void UpdateOrientation(u64 elapsed_time); | 52 | void UpdateOrientation(u64 elapsed_time); |
| 51 | 53 | ||
| 54 | void Calibrate(); | ||
| 55 | |||
| 52 | [[nodiscard]] std::array<Common::Vec3f, 3> GetOrientation() const; | 56 | [[nodiscard]] std::array<Common::Vec3f, 3> GetOrientation() const; |
| 53 | [[nodiscard]] Common::Vec3f GetAcceleration() const; | 57 | [[nodiscard]] Common::Vec3f GetAcceleration() const; |
| 54 | [[nodiscard]] Common::Vec3f GetGyroscope() const; | 58 | [[nodiscard]] Common::Vec3f GetGyroscope() const; |
| @@ -61,6 +65,7 @@ public: | |||
| 61 | [[nodiscard]] bool IsCalibrated(f32 sensitivity) const; | 65 | [[nodiscard]] bool IsCalibrated(f32 sensitivity) const; |
| 62 | 66 | ||
| 63 | private: | 67 | private: |
| 68 | void StopCalibration(); | ||
| 64 | void ResetOrientation(); | 69 | void ResetOrientation(); |
| 65 | void SetOrientationFromAccelerometer(); | 70 | void SetOrientationFromAccelerometer(); |
| 66 | 71 | ||
| @@ -103,6 +108,12 @@ private: | |||
| 103 | 108 | ||
| 104 | // Use accelerometer values to calculate position | 109 | // Use accelerometer values to calculate position |
| 105 | bool only_accelerometer = true; | 110 | bool only_accelerometer = true; |
| 111 | |||
| 112 | // When enabled it will aggressively adjust for gyro drift | ||
| 113 | bool calibration_mode = false; | ||
| 114 | |||
| 115 | // Used to auto disable calibration mode | ||
| 116 | std::size_t calibration_counter = 0; | ||
| 106 | }; | 117 | }; |
| 107 | 118 | ||
| 108 | } // namespace Core::HID | 119 | } // namespace Core::HID |
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index 561a08dc5..2c2e7e47b 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp | |||
| @@ -479,6 +479,9 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i | |||
| 479 | param.Set("threshold", new_threshold / 1000.0f); | 479 | param.Set("threshold", new_threshold / 1000.0f); |
| 480 | emulated_controller->SetMotionParam(motion_id, param); | 480 | emulated_controller->SetMotionParam(motion_id, param); |
| 481 | }); | 481 | }); |
| 482 | context_menu.addAction(tr("Calibrate sensor"), [&] { | ||
| 483 | emulated_controller->StartMotionCalibration(); | ||
| 484 | }); | ||
| 482 | } | 485 | } |
| 483 | context_menu.exec(motion_map[motion_id]->mapToGlobal(menu_location)); | 486 | context_menu.exec(motion_map[motion_id]->mapToGlobal(menu_location)); |
| 484 | }); | 487 | }); |
diff --git a/src/yuzu/configuration/configure_input_player_widget.cpp b/src/yuzu/configuration/configure_input_player_widget.cpp index fe1ee2289..a188eef92 100644 --- a/src/yuzu/configuration/configure_input_player_widget.cpp +++ b/src/yuzu/configuration/configure_input_player_widget.cpp | |||
| @@ -582,9 +582,9 @@ void PlayerControlPreview::DrawDualController(QPainter& p, const QPointF center) | |||
| 582 | using namespace Settings::NativeMotion; | 582 | using namespace Settings::NativeMotion; |
| 583 | p.setPen(colors.outline); | 583 | p.setPen(colors.outline); |
| 584 | p.setBrush(colors.transparent); | 584 | p.setBrush(colors.transparent); |
| 585 | Draw3dCube(p, center + QPointF(-180, -5), | 585 | Draw3dCube(p, center + QPointF(-180, 90), |
| 586 | motion_values[Settings::NativeMotion::MotionLeft].euler, 20.0f); | 586 | motion_values[Settings::NativeMotion::MotionLeft].euler, 20.0f); |
| 587 | Draw3dCube(p, center + QPointF(180, -5), | 587 | Draw3dCube(p, center + QPointF(180, 90), |
| 588 | motion_values[Settings::NativeMotion::MotionRight].euler, 20.0f); | 588 | motion_values[Settings::NativeMotion::MotionRight].euler, 20.0f); |
| 589 | } | 589 | } |
| 590 | 590 | ||
| @@ -2926,14 +2926,14 @@ void PlayerControlPreview::DrawArrow(QPainter& p, const QPointF center, const Di | |||
| 2926 | void PlayerControlPreview::Draw3dCube(QPainter& p, QPointF center, const Common::Vec3f& euler, | 2926 | void PlayerControlPreview::Draw3dCube(QPainter& p, QPointF center, const Common::Vec3f& euler, |
| 2927 | float size) { | 2927 | float size) { |
| 2928 | std::array<Common::Vec3f, 8> cube{ | 2928 | std::array<Common::Vec3f, 8> cube{ |
| 2929 | Common::Vec3f{-1, -1, -1}, | 2929 | Common::Vec3f{-0.7f, -1, -0.5f}, |
| 2930 | {-1, 1, -1}, | 2930 | {-0.7f, 1, -0.5f}, |
| 2931 | {1, 1, -1}, | 2931 | {0.7f, 1, -0.5f}, |
| 2932 | {1, -1, -1}, | 2932 | {0.7f, -1, -0.5f}, |
| 2933 | {-1, -1, 1}, | 2933 | {-0.7f, -1, 0.5f}, |
| 2934 | {-1, 1, 1}, | 2934 | {-0.7f, 1, 0.5f}, |
| 2935 | {1, 1, 1}, | 2935 | {0.7f, 1, 0.5f}, |
| 2936 | {1, -1, 1}, | 2936 | {0.7f, -1, 0.5f}, |
| 2937 | }; | 2937 | }; |
| 2938 | 2938 | ||
| 2939 | for (Common::Vec3f& point : cube) { | 2939 | for (Common::Vec3f& point : cube) { |