卡尔曼滤波对GPS轨迹数据清洗(Java实现)

引言

由于本人学艺未精,此文章只是作为给自己笔记使用,不知道是否准确

卡尔曼滤波的5条公式

在这里插入图片描述

数学建模

  1. 首先分析状态变量X(t),由于GPS位移和速度都分为水平和垂直水平
    在这里插入图片描述
  2. 接着分析状态偏移矩阵
    在这里插入图片描述
    接着将上述式子转化成矩阵
    在这里插入图片描述
  3. 分析观测矩阵
    在这里插入图片描述
    将状态量带入得
    在这里插入图片描述

Java编程实现

 //数据清洗
    public static List<ShipTrajectory>  dataClean(List<ShipTrajectory> data){
        //时间间隔(时间间隔)
        double T = 1.0/900;
        //经度方差(水平位置)
        double JDFX = 5.8;
        //纬度方差(垂直位置)
        double WDFX = 1.3;
        //状态矩阵(初始值不重要,会自动更正)
        double[][] X_ARRAY = {
                {data.get(0).getJD()},
                {0},
                {data.get(0).getWD()},
                {0}
        };
        AtomicReference<Matrix> X = new AtomicReference<>(new Matrix(X_ARRAY));
        //状态协方差矩阵(初始值不重要,会自动更正)
        double[][] P_ARRAY = {
                {1,0,0,0},
                {0,1,0,0},
                {0,0,1,0},
                {0,0,0,1}
        };
        AtomicReference<Matrix> P = new AtomicReference<>(new Matrix(P_ARRAY));
        //状态转移矩阵
        double[][] F_ARRAY = {
                {1,T,0,0},
                {0,1,0,0},
                {0,0,1,T},
                {0,0,0,1}
        };
        Matrix F = new Matrix(F_ARRAY);
        //状态转移协方差矩阵(对误差忽略不计)
        double[][] Q_ARRAY ={
                {0.0001,0,0,0},
                {0,0.0001,0,0},
                {0,0,0.0001,0},
                {0,0,0,0.0001}
        };
        Matrix Q = new Matrix(Q_ARRAY);
        //观测矩阵(观测经度纬度)
        double[][] H_ARRAY = {
                {1,0,0,0},
                {0,0,1,0}
        };
        Matrix H = new Matrix(H_ARRAY);
        //观测噪声方差(对角线为各维度方差)
        double[][] R_ARRAY = {
                {JDFX,0},
                {0,WDFX},
        };
        Matrix R = new Matrix(R_ARRAY);
        //I 维度为4
        double[][] I_ARRAY = {
                {1,0,0,0},
                {0,1,0,0},
                {0,0,1,0},
                {0,0,0,1}
        };
        Matrix I = new Matrix(I_ARRAY);
        List<ShipTrajectory> removeShipList = new ArrayList<>();
        AtomicInteger i= new AtomicInteger();
        data.forEach(ship -> {
            try {
                i.getAndIncrement();
                //==============第1条式子==============
                Matrix X_ = F.times(X.get());
                //==============第2条式子==============
                Matrix P_ = F.times(P.get()).times(F.transpose()).plus(Q);
                //==============第3条式子==============
                Matrix K = P_.times(H.transpose()).times(H.times(P_).times(H.transpose()).plus(R).inverse());
                //==============第4条式子==============
                //水平位置
                double Px_tt=ship.getJD();
                //垂直位置
                double Py_tt=ship.getWD();
                double[][] Z_ARRAY = {
                        {Px_tt},
                        {Py_tt}
                };
                Matrix Z = new Matrix(Z_ARRAY);
                X.set(X_.plus(K.times(Z.minus(H.times(X_)))));
                //==============第5条式子==============
                P.set(I.minus(K.times(H)).times(P_));
                //==============数据清洗==============
                double abs = Math.abs(ship.getWD() - X.get().get(2, 0));
                double abs1 = Math.abs(ship.getJD() - X.get().get(0, 0));
                //清除噪声
                if(abs1>=0.8||abs>=0.8){
                    removeShipList.add(ship);
                    System.out.println();
                    System.out.println("\033[32;4m" + "======================================《《filter start》》 ===================================================" + "\033[0m");
                    System.out.println("序号: "+i.get()+"  old-JD:"+Px_tt+"  old-WD:"+Py_tt+"  new-JD:"+X.get().get(0,0)+"  new-WD:"+X.get().get(2,0));
                    System.out.println("\033[32;4m" + "=============================================================================================================" + "\033[0m");
                    System.out.println();
                }else {
                    System.out.println("序号: "+i.get()+"  old-JD:"+Px_tt+"  old-WD:"+Py_tt+"  new-JD:"+X.get().get(0,0)+"  new-WD:"+X.get().get(2,0));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        System.out.println("count :"+removeShipList.size());
        data.removeAll(removeShipList);
        return data;
    }

  • 6
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 25
    评论
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值