• 卡尔曼滤波C++代码


      1 #include <ros/ros.h>
      2 #include <string>
      3 #include <stdlib.h>
      4 #include <iostream>
      5 #include <fstream>
      6 #include <string>
      7 #include <vector>
      8 #include <Eigen/Dense>
      9 #include <cmath>
     10 #include <limits>
     11  
     12 using namespace std;
     13 using Eigen::MatrixXd;
     14 
     15 //
     16 double generateGaussianNoise(double mu, double sigma)
     17 {
     18     const double epsilon = std::numeric_limits<double>::min();
     19     const double two_pi = 2.0*3.14159265358979323846;
     20  
     21     static double z0, z1;
     22     static bool generate;
     23     generate = !generate;
     24  
     25     if (!generate)
     26         return z1 * sigma + mu;
     27  
     28     double u1, u2;
     29     do
     30     {
     31         u1 = rand() * (1.0 / RAND_MAX);
     32         u2 = rand() * (1.0 / RAND_MAX);
     33     } while (u1 <= epsilon);
     34  
     35     z0 = sqrt(-2.0 * log(u1)) * cos(two_pi * u2);
     36     z1 = sqrt(-2.0 * log(u1)) * sin(two_pi * u2);
     37     return z0 * sigma + mu;
     38 }
     39 
     40 int main(int argc, char **argv)
     41 {
     42     std::cout<<"test qusetion2 start !"<<std::endl;
     43     ros::init(argc,argv,"question2_node");
     44     ros::NodeHandle node;
     45 
     46     ofstream fout("/media/kuang/code_test/result.txt");
     47     
     48     double generateGaussianNoise(double mu, double sigma);//随机高斯分布数列生成器函数
     49  
     50     const double delta_t = 0.1;//控制周期,100ms
     51     const int num = 100;//迭代次数
     52     const double acc = 10;//加速度,ft/m
     53  
     54     MatrixXd A(2, 2);
     55     A(0, 0) = 1;
     56     A(1, 0) = 0;
     57     A(0, 1) = delta_t;
     58     A(1, 1) = 1;
     59  
     60     MatrixXd B(2, 1);
     61     B(0, 0) = pow(delta_t, 2) / 2;
     62     B(1, 0) = delta_t;
     63  
     64     MatrixXd H(1, 2);//测量的是小车的位移,速度为0
     65     H(0, 0) = 1;
     66     H(0, 1) = 0;
     67  
     68     MatrixXd Q(2, 2);//过程激励噪声协方差,假设系统的噪声向量只存在速度分量上,且速度噪声的方差是一个常量0.01,位移分量上的系统噪声为0
     69     Q(0, 0) = 0;
     70     Q(1, 0) = 0;
     71     Q(0, 1) = 0;
     72     Q(1, 1) = 0.01;
     73  
     74     MatrixXd R(1, 1);//观测噪声协方差,测量值只有位移,它的协方差矩阵大小是1*1,就是测量噪声的方差本身。
     75     R(0, 0) = 10;
     76  
     77     //time初始化,产生时间序列
     78     vector<double> time(100, 0);
     79     for (decltype(time.size()) i = 0; i != num; ++i) {
     80         time[i] = i * delta_t;
     81         //cout<<time[i]<<endl;
     82     }
     83  
     84     MatrixXd X_real(2, 1);
     85     vector<MatrixXd> x_real, rand;
     86     //生成高斯分布的随机数
     87     for (int i = 0; i<100; ++i) {
     88         MatrixXd a(1, 1);
     89         a(0, 0) = generateGaussianNoise(0, sqrt(10));
     90         rand.push_back(a);
     91     }
     92     //生成真实的位移值
     93     for (int i = 0; i < num; ++i) {
     94         X_real(0, 0) = 0.5 * acc * pow(time[i], 2);
     95         X_real(1, 0) = 0;
     96         x_real.push_back(X_real);
     97     }
     98  
     99     //变量定义,包括状态预测值,状态估计值,测量值,预测状态与真实状态的协方差矩阵,估计状态和真实状态的协方差矩阵,初始值均为零
    100     MatrixXd X_evlt = MatrixXd::Constant(2, 1, 0), X_pdct = MatrixXd::Constant(2, 1, 0), Z_meas = MatrixXd::Constant(1, 1, 0),
    101         Pk = MatrixXd::Constant(2, 2, 0), Pk_p = MatrixXd::Constant(2, 2, 0), K = MatrixXd::Constant(2, 1, 0);
    102     vector<MatrixXd> x_evlt, x_pdct, z_meas, pk, pk_p, k;
    103     x_evlt.push_back(X_evlt);
    104     x_pdct.push_back(X_pdct);
    105     z_meas.push_back(Z_meas);
    106     pk.push_back(Pk);
    107     pk_p.push_back(Pk_p);
    108     k.push_back(K);
    109  
    110     //开始迭代
    111     for (int i = 1; i < num; ++i) {
    112         //预测值
    113         X_pdct = A * x_evlt[i - 1] + B * acc;
    114         x_pdct.push_back(X_pdct);
    115         //预测状态与真实状态的协方差矩阵,Pk'
    116         Pk_p = A * pk[i - 1] * A.transpose() + Q;
    117         pk_p.push_back(Pk_p);
    118         //K:2x1
    119         MatrixXd tmp(1, 1);
    120         tmp = H * pk_p[i] * H.transpose() + R;
    121         K = pk_p[i] * H.transpose() * tmp.inverse();
    122         k.push_back(K);
    123         //测量值z
    124         Z_meas = H * x_real[i] + rand[i];
    125         z_meas.push_back(Z_meas);
    126         //估计值
    127         X_evlt = x_pdct[i] + k[i] * (z_meas[i] - H * x_pdct[i]);
    128         x_evlt.push_back(X_evlt);
    129         //估计状态和真实状态的协方差矩阵,Pk
    130         Pk = (MatrixXd::Identity(2, 2) - k[i] * H) * pk_p[i];
    131         pk.push_back(Pk);
    132     }
    133  
    134     cout << "含噪声测量" << "  " << "后验估计" << "  " << "真值" << "  " << endl;
    135     for (int i = 0; i < num; ++i) {
    136         cout<<z_meas[i]<<"  "<<x_evlt[i](0,0)<<"  "<<x_real[i](0,0)<<endl;
    137         fout << z_meas[i] << "  " << x_evlt[i](0, 0) << "  " << x_real[i](0, 0) << endl;
    138     }
    139  
    140     fout.close();
    141     getchar();
    142     return 0;
    143 }
    144


    下面是python画图代码:
     1 #! /usr/bin/env python
     2 
     3 import os
     4 import math
     5 import matplotlib.pyplot as plt
     6 import numpy as np
     7 
     8 def mean(data):
     9     sum=0
    10     for i in data:
    11         sum = sum+i
    12     return sum/len(data) 
    13 
    14 if __name__ ==  "__main__":
    15 
    16     file1 = "/media/kuang/code_test/result.txt"
    17 
    18     frame=[]
    19     measure_noise = []
    20     post_eval = []
    21     groundtruth = [] 
    22     counter = 0
    23 
    24     # Read all data
    25     document1 = open(file1,'rw+')
    26     for line1 in document1:
    27         split_line1 = line1.split()
    28         counter = counter + 1 
    29         frame.append(counter)
    30         measure_noise.append(float(split_line1[0]))
    31     post_eval.append(float(split_line1[1]))
    32         groundtruth.append(float(split_line1[2]))
    33     document1.close()
    34 
    35     START = 0
    36     END = len(frame)-1 # 1000
    37     frame_sub = frame[START:END]
    38     measure_noise_sub = measure_noise[START:END]
    39     post_eval_sub = post_eval[START:END]
    40     groundtruth_sub = groundtruth[START:END]
    41     
    42     fig, ax1 = plt.subplots()
    43 
    44     color = 'blue'
    45     ax1.set_xlabel('Frame No.')
    46     ax1.set_ylabel('measure noise', color=color)
    47     ax1.set_ylim(-10,500)
    48     ax1.plot(frame_sub, measure_noise_sub,'s-', color=color)
    49     ax1.tick_params(axis='y', labelcolor=color)
    50     
    51     
    52     ax2 = ax1.twinx()  # instantiate a second axes that shares the same x-axis
    53     color = 'red'
    54     ax2.set_ylabel('post eval', labelpad=40,color=color)  # we already handled the x-label with ax1
    55     ax2.set_ylim(-10,500)
    56     ax2.plot(frame_sub, post_eval_sub, 's-',color=color)
    57     ax2.tick_params(axis='y',pad=30.0, labelcolor=color)
    58 
    59     ax3 = ax1.twinx()
    60     color = 'yellow'
    61     ax3.set_ylabel('groundtruth', color=color, labelpad=30)
    62     ax3.set_ylim(-10,500)
    63     ax3.tick_params(axis='y', labelcolor=color)
    64     ax3.plot(frame_sub, groundtruth_sub, 's-' , color=color)
    65     
    66 
    67     fig.tight_layout()  # otherwise the right y-label is slightly clipped
    68     ax1.grid()
    69     plt.title("Kalman Test")
    70     plt.show()
    71 
    72     # SAVE RESULT TO FILE   
  • 相关阅读:
    新概念英语第三册21-40课(转)
    多线程---线程通信
    多线程----线程同步
    多线程----线程创建的四种方式
    从0开始整合SSM框架-1.mybatis
    easyUI datagrid 动态绑定列名称
    java分享第五天(数组)
    java分享第四天(循环)
    java分享第三天(异常)
    java分享第二天(变量及命名规范)
  • 原文地址:https://www.cnblogs.com/kuangxionghui/p/10382124.html
Copyright © 2020-2023  润新知