mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-03 16:39:01 -06:00 
			
		
		
		
	core: hid: Allow to calibrate gyro sensor
This commit is contained in:
		@@ -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()) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user