summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNarr the Reg <juangerman-13@hotmail.com>2023-05-08 19:17:27 +0200
committerNarr the Reg <juangerman-13@hotmail.com>2023-05-08 20:06:38 +0200
commit97bd6d641811cafc3ec99879fa53beda1a2334b5 (patch)
treeec3946ddaa935829006ceb2b46995fe493621dba
parentMerge pull request #10075 from Kelebek1/silence_nifm_spam (diff)
downloadyuzu-97bd6d641811cafc3ec99879fa53beda1a2334b5.tar
yuzu-97bd6d641811cafc3ec99879fa53beda1a2334b5.tar.gz
yuzu-97bd6d641811cafc3ec99879fa53beda1a2334b5.tar.bz2
yuzu-97bd6d641811cafc3ec99879fa53beda1a2334b5.tar.lz
yuzu-97bd6d641811cafc3ec99879fa53beda1a2334b5.tar.xz
yuzu-97bd6d641811cafc3ec99879fa53beda1a2334b5.tar.zst
yuzu-97bd6d641811cafc3ec99879fa53beda1a2334b5.zip
-rw-r--r--src/core/hid/emulated_controller.cpp6
-rw-r--r--src/core/hid/emulated_controller.h3
-rw-r--r--src/core/hid/motion_input.cpp21
-rw-r--r--src/core/hid/motion_input.h11
-rw-r--r--src/yuzu/configuration/configure_input_player.cpp3
5 files changed, 43 insertions, 1 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
ReloadInput();
}
+void EmulatedController::StartMotionCalibration() {
+ for (ControllerMotionInfo& motion : controller.motion_values) {
+ motion.emulated.Calibrate();
+ }
+}
+
void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback, std::size_t index,
Common::UUID uuid) {
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:
*/
void SetMotionParam(std::size_t index, Common::ParamPackage param);
+ /// Auto calibrates the current motion devices
+ void StartMotionCalibration();
+
/// Returns the latest button status from the controller with parameters
ButtonValues GetButtonsValues() const;
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) {
gyro.y = std::clamp(gyro.y, -GyroMaxValue, GyroMaxValue);
gyro.z = std::clamp(gyro.z, -GyroMaxValue, GyroMaxValue);
- // Auto adjust drift to minimize drift
+ // Auto adjust gyro_bias to minimize drift
if (!IsMoving(IsAtRestRelaxed)) {
gyro_bias = (gyro_bias * 0.9999f) + (gyroscope * 0.0001f);
}
+ // Adjust drift when calibration mode is enabled
+ if (calibration_mode) {
+ gyro_bias = (gyro_bias * 0.99f) + (gyroscope * 0.01f);
+ StopCalibration();
+ }
+
if (gyro.Length() < gyro_threshold * user_gyro_threshold) {
gyro = {};
} else {
@@ -107,6 +113,19 @@ void MotionInput::UpdateRotation(u64 elapsed_time) {
rotations += gyro * sample_period;
}
+void MotionInput::Calibrate() {
+ calibration_mode = true;
+ calibration_counter = 0;
+}
+
+void MotionInput::StopCalibration() {
+ if (calibration_counter++ > CalibrationSamples) {
+ calibration_mode = false;
+ ResetQuaternion();
+ ResetRotations();
+ }
+}
+
// Based on Madgwick's implementation of Mayhony's AHRS algorithm.
// 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
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:
static constexpr float GyroMaxValue = 5.0f;
static constexpr float AccelMaxValue = 7.0f;
+ static constexpr std::size_t CalibrationSamples = 300;
+
explicit MotionInput();
MotionInput(const MotionInput&) = default;
@@ -49,6 +51,8 @@ public:
void UpdateRotation(u64 elapsed_time);
void UpdateOrientation(u64 elapsed_time);
+ void Calibrate();
+
[[nodiscard]] std::array<Common::Vec3f, 3> GetOrientation() const;
[[nodiscard]] Common::Vec3f GetAcceleration() const;
[[nodiscard]] Common::Vec3f GetGyroscope() const;
@@ -61,6 +65,7 @@ public:
[[nodiscard]] bool IsCalibrated(f32 sensitivity) const;
private:
+ void StopCalibration();
void ResetOrientation();
void SetOrientationFromAccelerometer();
@@ -103,6 +108,12 @@ private:
// Use accelerometer values to calculate position
bool only_accelerometer = true;
+
+ // When enabled it will aggressively adjust for gyro drift
+ bool calibration_mode = false;
+
+ // Used to auto disable calibration mode
+ std::size_t calibration_counter = 0;
};
} // 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
param.Set("threshold", new_threshold / 1000.0f);
emulated_controller->SetMotionParam(motion_id, param);
});
+ context_menu.addAction(tr("Calibrate sensor"), [&] {
+ emulated_controller->StartMotionCalibration();
+ });
}
context_menu.exec(motion_map[motion_id]->mapToGlobal(menu_location));
});