我将数据从惯性传感器传输到C#应用程序。数据有点吵,所以我需要添加一个滤镜来平滑它。我有一个kalman过滤器实现,在给定数组时效果很好,但是我无法理解如何在常量数据流上使用它。
我有:
double sensorData; //the noisy value, constantly updating from another class.
过滤器:
public static double[] noisySine = new double[20] { 40, 41, 38, 40, 45, 42, 43, 44, 40, 38, 44, 45, 40, 39, 37, 41, 42, 70, 44, 42 };
public static double[] clean = new double[20];
public static void KalmanFilter(double[] noisy)
{
double A = double.Parse("1"); //factor of real value to previous real value
// double B = 0; //factor of real value to real control signal
double H = double.Parse("1");
double P = double.Parse("0.1");
double Q = double.Parse("0.125"); //Process noise.
double R = double.Parse("1"); //assumed environment noise.
double K;
double z;
double x;
//assign to first measured value
x = noisy[0];
for (int i = 0; i < noisy.Length; i++)
{
//get current measured value
z = noisy[i];
//time update - prediction
x = A * x;
P = A * P * A + Q;
//measurement update - correction
K = P * H / (H * P * H + R);
x = x + K * (z - H * x);
P = (1 - K * H) * P;
//estimated value
clean[i] = x;
Console.WriteLine(noisy[i] + " " + clean[i]);
}
}
如何流入double而不是数组,并返回(已过滤)的double?
谢谢。
答案 0 :(得分:0)
尝试以下代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
double[] input = {1.1,2.2,3.3,4.4};
byte[] bArray = input.Select(x => BitConverter.GetBytes(x)).SelectMany(y => y).ToArray();
MemoryStream inStream = new MemoryStream(bArray);
long length = inStream.Length;
byte[] outArray = new byte[length];
inStream.Read(outArray, 0, (int)length);
List<double> output = new List<double>();
for (int i = 0; i < bArray.Length; i += 8)
{
output.Add(BitConverter.ToDouble(outArray,i));
}
}
}
}
答案 1 :(得分:0)
创建此类:
public class KalmanFilter
{
private double A, H, Q, R, P, x;
public KalmanFilter(double A, double H, double Q, double R, double initial_P, double initial_x)
{
this.A = A;
this.H = H;
this.Q = Q;
this.R = R;
this.P = initial_P;
this.x = initial_x;
}
public double Output(double input)
{
// time update - prediction
x = A * x;
P = A * P * A + Q;
// measurement update - correction
double K = P * H / (H * P * H + R);
x = x + K * (input - H * x);
P = (1 - K * H) * P;
return x;
}
}
使用课程:
KalmanFilter filter = new KalmanFilter(1, 1, 0.125, 1, 0.1, noisySine[0]);
for (int i = 0; i < noisy.Length; i++) clean[i] = filter.Output(noisySine[i]);
答案 2 :(得分:0)
这是如何修改代码以流入double,并返回已过滤的double。
public static void KalmanTest()
{
double[] noisySine = new double[20] { 40, 41, 38, 40, 45, 42, 43, 44, 40, 38, 44, 45, 40, 39, 37, 41, 42, 70, 44, 42 };
for (int i = 0; i < noisySine.Length; i++)
{
Console.WriteLine(noisySine[i] + " " + KalmanFilter(noisySine[i]));
}
}
// assign default values
// for a new mwasurement, reset this values
public static double P = double.Parse("1"); // MUST be greater than 0
public static double clean = double.Parse("0"); // any value
public static double KalmanFilter(double noisy)
{
double A = double.Parse("1"); //factor of real value to previous real value
// double B = 0; //factor of real value to real control signal
double H = double.Parse("1");
double Q = double.Parse("0.125"); //Process noise.
double R = double.Parse("1"); //assumed environment noise.
double K;
double z;
double x;
//get current measured value
z = noisy;
//time update - prediction
x = A * clean;
P = A * P * A + Q;
//measurement update - correction
K = P * H / (H * P * H + R);
x = x + K * (z - H * x);
P = (1 - K * H) * P;
//estimated value
clean = x;
return clean;
}
注意:有一个错误。当此代码重复时,P很快变为接近R / 100000的值,并且此行为与噪声无关,因为在P计算中没有引用噪声或稳定读数。 干净的代码看起来像一个低通滤波器:
// assign default values
public static double clean = double.Parse("0"); // any value
public static double KalmanFilter(double noisy)
{
double K = double.Parse("0.125"); // noise 0 < K < 1
clean = clean + K * (noisy - clean);
return clean;
}