duheng
2025-03-27 d2ccacb3317aa6310f1b1bb5eb19fbdecba39ff9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
namespace IBox.WinFrmUI
{
    public class FilterKalman
    {
        private double A = 1;
        private double B = 0;
        private double H = 1;
 
        private double R;
        private double Q;
 
        private double cov = double.NaN;
        private double x = double.NaN;
        public FilterKalman()
        {
 
        }
        /// <summary>
        /// 卡尔曼滤波
        /// </summary>
        public FilterKalman(double R, double Q, double A, double B, double H)
        {
            this.R = R;
            this.Q = Q;
 
            this.A = A;
            this.B = B;
            this.H = H;
 
            this.cov = double.NaN;
            this.x = double.NaN;
        }
 
        /// <summary>
        /// 
        /// </summary>
        public FilterKalman(double R, double Q)
        {
            this.R = R;
            this.Q = Q;
        }
 
        public double filter(double measurement, double u)
        {
            if (double.IsNaN(this.x))
            {
                this.x = (1 / this.H) * measurement;
                this.cov = (1 / this.H) * this.Q * (1 / this.H);
            }
            else
            {
                double predX = (this.A * this.x) + (this.B * u);
                double predCov = ((this.A * this.cov) * this.A) + this.Q;
 
                double K = predCov * this.H * (1 / ((this.H * predCov * this.H) + this.Q));
 
                this.x = predX + K * (measurement - (this.H * predX));
                this.cov = predCov - (K * this.H * predCov);
            }
            return this.x;
        }
 
        public double filter(double measurement)
        {
            double u = 0;
            if (double.IsNaN(this.x))
            {
                this.x = (1 / this.H) * measurement;
                this.cov = (1 / this.H) * this.Q * (1 / this.H);
            }
            else
            {
                double predX = (this.A * this.x) + (this.B * u);
                double predCov = ((this.A * this.cov) * this.A) + this.R;
 
                double K = predCov * this.H * (1 / ((this.H * predCov * this.H) + this.Q));
 
                this.x = predX + K * (measurement - (this.H * predX));
                this.cov = predCov - (K * this.H * predCov);
            }
            return this.x;
        }
 
        public double lastMeasurement()
        {
            return this.x;
        }
 
        public void setMeasurementNoise(double noise)
        {
            this.Q = noise;
        }
 
        public void setProcessNoise(double noise)
        {
            this.R = noise;
        }
    }
}