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

卡尔曼滤波的5条公式

在这里插入图片描述

数学建模

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

import Jama.Matrix;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

public class KalmanGpsFilter4 {
    public static void main(String[] args) {
        List<ShipTrajectory> data=new ArrayList<>();
        data.add(new ShipTrajectory(1.,2.));
        data.add(new ShipTrajectory(3.,4.));
        data.add(new ShipTrajectory(5.,6.));
        dataClean(data);
    }

    static class ShipTrajectory{
        double JD;
        double WD;

        public ShipTrajectory(double JD, double WD) {
            this.JD = JD;
            this.WD = WD;
        }

        public double getJD() {
            return JD;
        }

        public void setJD(double JD) {
            this.JD = JD;
        }

        public double getWD() {
            return WD;
        }

        public void setWD(double WD) {
            this.WD = WD;
        }
    }
    //数据清洗-卡尔曼滤波对GPS轨迹数据清洗
    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;
    }
}

  • 3
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值