diff options
Diffstat (limited to '')
-rw-r--r-- | src/core/hid/emulated_controller.cpp | 35 | ||||
-rw-r--r-- | src/core/hid/emulated_controller.h | 8 | ||||
-rw-r--r-- | src/core/hid/input_converter.cpp | 2 | ||||
-rw-r--r-- | src/core/hid/motion_input.cpp | 21 | ||||
-rw-r--r-- | src/core/hid/motion_input.h | 11 |
5 files changed, 57 insertions, 20 deletions
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp index ecab85893..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()) { @@ -979,7 +985,6 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback emulated.SetUserGyroThreshold(raw_status.gyro.x.properties.threshold); emulated.UpdateRotation(raw_status.delta_timestamp); emulated.UpdateOrientation(raw_status.delta_timestamp); - force_update_motion = raw_status.force_update; auto& motion = controller.motion_state[index]; motion.accel = emulated.GetAcceleration(); @@ -1618,19 +1623,6 @@ NpadGcTriggerState EmulatedController::GetTriggers() const { MotionState EmulatedController::GetMotions() const { std::unique_lock lock{mutex}; - - // Some drivers like mouse motion need constant refreshing - if (force_update_motion) { - for (auto& device : motion_devices) { - if (!device) { - continue; - } - lock.unlock(); - device->ForceUpdate(); - lock.lock(); - } - } - return controller.motion_state; } @@ -1696,8 +1688,21 @@ void EmulatedController::DeleteCallback(int key) { callback_list.erase(iterator); } -void EmulatedController::TurboButtonUpdate() { +void EmulatedController::StatusUpdate() { turbo_button_state = (turbo_button_state + 1) % (TURBO_BUTTON_DELAY * 2); + + // Some drivers like key motion need constant refreshing + for (std::size_t index = 0; index < motion_devices.size(); ++index) { + const auto& raw_status = controller.motion_values[index].raw_status; + auto& device = motion_devices[index]; + if (!raw_status.force_update) { + continue; + } + if (!device) { + continue; + } + device->ForceUpdate(); + } } NpadButton EmulatedController::GetTurboButtonMask() const { diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h index 6e01f4e12..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; @@ -415,8 +418,8 @@ public: */ void DeleteCallback(int key); - /// Swaps the state of the turbo buttons - void TurboButtonUpdate(); + /// Swaps the state of the turbo buttons and updates motion input + void StatusUpdate(); private: /// creates input devices from params @@ -528,7 +531,6 @@ private: bool is_configuring{false}; bool system_buttons_enabled{true}; f32 motion_sensitivity{Core::HID::MotionInput::IsAtRestStandard}; - bool force_update_motion{false}; u32 turbo_button_state{0}; // Temporary values to avoid doing changes while the controller is in configuring mode diff --git a/src/core/hid/input_converter.cpp b/src/core/hid/input_converter.cpp index 53b00b1f9..4ccb1c596 100644 --- a/src/core/hid/input_converter.cpp +++ b/src/core/hid/input_converter.cpp @@ -86,7 +86,7 @@ Common::Input::MotionStatus TransformToMotion(const Common::Input::CallbackStatu .range = 1.0f, .offset = 0.0f, }; - status.delta_timestamp = 5000; + status.delta_timestamp = 1000; status.force_update = true; status.accel.x = { .value = 0.0f, 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 |