using System.Collections.Generic; using System.Linq; using UnityEngine; using UnscentedKalmanFilter; namespace ZIM { // 固定时间间隔下,预测位置轨迹 public class SimpleLocationEstimation { //public bool Initialized; public Vector2 Predict; Vector2 LastLocation; Vector2 LastSpeed; Vector2 LastAcc; float AccChangeScale; List Locations; // 卡尔曼滤波作用于速度 UKF filterx; UKF filtery; public SimpleLocationEstimation(float accChangeScale = 1) { Locations = new List(); AccChangeScale = accChangeScale; filterx = new UKF(); filtery = new UKF(); } public Vector2 Update(Vector2 loc) { if (Locations == null) { var newSpeed = loc - LastLocation; var newAcc = newSpeed - LastSpeed; var accPredict = newAcc + (newAcc - LastAcc) * AccChangeScale; var speedPredict = newSpeed + accPredict; //if (speedPredict.x * newSpeed.x < 0) // speedPredict.x = 0; //if (speedPredict.y * newSpeed.y < 0) // speedPredict.y = 0; //var LocationPredict = loc + speedPredict; filterx.Update(new double[] { speedPredict.x }); filtery.Update(new double[] { speedPredict.y }); var LocationPredict = loc + new Vector2((float)filterx.getState()[0], (float)filtery.getState()[0]); LastSpeed = newSpeed; LastAcc = newAcc; LastLocation = loc; return Predict = LocationPredict; //return Predict = new Vector2((float)filterx.getState()[0], (float)filtery.getState()[0]); } if (Locations.Count < 2) { Locations.Add(loc); } else { Locations.Add(loc); var speed = new Vector2[] { Locations.ElementAt(1) - Locations.ElementAt(0), Locations.ElementAt(2) - Locations.ElementAt(1) }; LastLocation = loc; LastSpeed = speed[1]; LastAcc = speed[1] - speed[0]; Locations = null; } return Predict = loc; } } }