zoukankan      html  css  js  c++  java
  • 6.4学习记录

    对轨迹偏离进行优化
    package com.james.motion.sport_motion;

    import com.amap.api.maps.AMapUtils;
    import com.amap.api.maps.model.LatLng;

    import java.util.ArrayList;
    import java.util.List;

    /**
    * 轨迹优化工具类
    * <p>
    * 使用方法:
    * <p>
    * PathSmoothTool pathSmoothTool = new PathSmoothTool();
    * pathSmoothTool.setIntensity(2);//设置滤波强度,默认3
    * List<LatLng> mList = LatpathSmoothTool.kalmanFilterPath(list);
    */

    public class PathSmoothTool {

    private int mIntensity = 3;
    private float mThreshhold = 1.0f;
    private float mNoiseThreshhold = 10;

    public PathSmoothTool() {

    }

    public int getIntensity() {
    return mIntensity;
    }

    public void setIntensity(int mIntensity) {
    this.mIntensity = mIntensity;
    }

    public float getThreshhold() {
    return mThreshhold;
    }

    public void setThreshhold(float mThreshhold) {
    this.mThreshhold = mThreshhold;
    }

    public void setNoiseThreshhold(float mnoiseThreshhold) {
    this.mNoiseThreshhold = mnoiseThreshhold;
    }

    /**
    * 轨迹平滑优化
    *
    * @param originlist 原始轨迹list,list.size大于2
    * @return 优化后轨迹list
    */
    public List<LatLng> pathOptimize(List<LatLng> originlist) {
    synchronized (this) {
    List<LatLng> list = removeNoisePoint(originlist);//去噪
    List<LatLng> afterList = kalmanFilterPath(list, mIntensity);//滤波
    return reducerVerticalThreshold(afterList, mThreshhold);//抽稀
    }
    }

    /**
    * 轨迹线路滤波
    *
    * @param originlist 原始轨迹list,list.size大于2
    * @return 滤波处理后的轨迹list
    */
    public List<LatLng> kalmanFilterPath(List<LatLng> originlist) {
    return kalmanFilterPath(originlist, mIntensity);
    }


    /**
    * 轨迹去噪,删除垂距大于20m的点
    *
    * @param originlist 原始轨迹list,list.size大于2
    * @return
    */
    public List<LatLng> removeNoisePoint(List<LatLng> originlist) {
    return reduceNoisePoint(originlist, mNoiseThreshhold);
    }

    /**
    * 单点滤波
    *
    * @param lastLoc 上次定位点坐标
    * @param curLoc 本次定位点坐标
    * @return 滤波后本次定位点坐标值
    */
    public LatLng kalmanFilterPoint(LatLng lastLoc, LatLng curLoc) {
    return kalmanFilterPoint(lastLoc, curLoc, mIntensity);
    }

    /**
    * 轨迹抽稀
    *
    * @param inPoints 待抽稀的轨迹list,至少包含两个点,删除垂距小于mThreshhold的点
    * @return 抽稀后的轨迹list
    */
    public List<LatLng> reducerVerticalThreshold(List<LatLng> inPoints) {
    return reducerVerticalThreshold(inPoints, mThreshhold);
    }

    /********************************************************************************************************/
    /**
    * 轨迹线路滤波
    *
    * @param originlist 原始轨迹list,list.size大于2
    * @param intensity 滤波强度(1—5)
    * @return
    */
    private List<LatLng> kalmanFilterPath(List<LatLng> originlist, int intensity) {
    synchronized (this) {
    List<LatLng> kalmanFilterList = new ArrayList<LatLng>();
    if (originlist == null || originlist.size() <= 2)
    return kalmanFilterList;
    initial();//初始化滤波参数
    LatLng latLng = null;
    LatLng lastLoc = originlist.get(0);
    kalmanFilterList.add(lastLoc);
    for (int i = 1; i < originlist.size(); i++) {
    LatLng curLoc = originlist.get(i);
    latLng = kalmanFilterPoint(lastLoc, curLoc, intensity);
    if (latLng != null) {
    kalmanFilterList.add(latLng);
    lastLoc = latLng;
    }
    }
    return kalmanFilterList;
    }
    }

    /**
    * 单点滤波
    *
    * @param lastLoc 上次定位点坐标
    * @param curLoc 本次定位点坐标
    * @param intensity 滤波强度(1—5)
    * @return 滤波后本次定位点坐标值
    */
    private LatLng kalmanFilterPoint(LatLng lastLoc, LatLng curLoc, int intensity) {
    if (pdelt_x == 0 || pdelt_y == 0) {
    initial();
    }
    LatLng kalmanLatlng = null;
    if (lastLoc == null || curLoc == null) {
    return kalmanLatlng;
    }
    if (intensity < 1) {
    intensity = 1;
    } else if (intensity > 5) {
    intensity = 5;
    }
    for (int j = 0; j < intensity; j++) {
    kalmanLatlng = kalmanFilter(lastLoc.longitude, curLoc.longitude, lastLoc.latitude, curLoc.latitude);
    curLoc = kalmanLatlng;
    }
    return kalmanLatlng;
    }


    /***************************卡尔曼滤波开始********************************/
    private double lastLocation_x; //上次位置
    private double currentLocation_x;//这次位置
    private double lastLocation_y; //上次位置
    private double currentLocation_y;//这次位置
    private double estimate_x; //修正后数据
    private double estimate_y; //修正后数据
    private double pdelt_x; //自预估偏差
    private double pdelt_y; //自预估偏差
    private double mdelt_x; //上次模型偏差
    private double mdelt_y; //上次模型偏差
    private double gauss_x; //高斯噪音偏差
    private double gauss_y; //高斯噪音偏差
    private double kalmanGain_x; //卡尔曼增益
    private double kalmanGain_y; //卡尔曼增益

    private double m_R = 0;
    private double m_Q = 0;

    //初始模型
    private void initial() {
    pdelt_x = 0.001;
    pdelt_y = 0.001;
    // mdelt_x = 0;
    // mdelt_y = 0;
    mdelt_x = 5.698402909980532E-4;
    mdelt_y = 5.698402909980532E-4;
    }

    private LatLng kalmanFilter(double oldValue_x, double value_x, double oldValue_y, double value_y) {
    lastLocation_x = oldValue_x;
    currentLocation_x = value_x;
    gauss_x = Math.sqrt(pdelt_x * pdelt_x + mdelt_x * mdelt_x) + m_Q; //计算高斯噪音偏差
    kalmanGain_x = Math.sqrt((gauss_x * gauss_x) / (gauss_x * gauss_x + pdelt_x * pdelt_x)) + m_R; //计算卡尔曼增益
    estimate_x = kalmanGain_x * (currentLocation_x - lastLocation_x) + lastLocation_x; //修正定位点
    mdelt_x = Math.sqrt((1 - kalmanGain_x) * gauss_x * gauss_x); //修正模型偏差

    lastLocation_y = oldValue_y;
    currentLocation_y = value_y;
    gauss_y = Math.sqrt(pdelt_y * pdelt_y + mdelt_y * mdelt_y) + m_Q; //计算高斯噪音偏差
    kalmanGain_y = Math.sqrt((gauss_y * gauss_y) / (gauss_y * gauss_y + pdelt_y * pdelt_y)) + m_R; //计算卡尔曼增益
    estimate_y = kalmanGain_y * (currentLocation_y - lastLocation_y) + lastLocation_y; //修正定位点
    mdelt_y = Math.sqrt((1 - kalmanGain_y) * gauss_y * gauss_y); //修正模型偏差

    LatLng latlng = new LatLng(estimate_y, estimate_x);


    return latlng;
    }
    /***************************卡尔曼滤波结束**********************************/

    /***************************抽稀算法*************************************/
    private List<LatLng> reducerVerticalThreshold(List<LatLng> inPoints, float threshHold) {
    synchronized (this) {
    if (inPoints == null) {
    return null;
    }
    if (inPoints.size() <= 2) {
    return inPoints;
    }
    List<LatLng> ret = new ArrayList<LatLng>();
    for (int i = 0; i < inPoints.size(); i++) {
    LatLng pre = getLastLocation(ret);
    LatLng cur = inPoints.get(i);
    if (pre == null || i == inPoints.size() - 1) {
    ret.add(cur);
    continue;
    }
    LatLng next = inPoints.get(i + 1);
    double distance = calculateDistanceFromPoint(cur, pre, next);
    if (distance > threshHold) {
    ret.add(cur);
    }
    }
    return ret;
    }
    }

    private static LatLng getLastLocation(List<LatLng> oneGraspList) {
    if (oneGraspList == null || oneGraspList.size() == 0) {
    return null;
    }
    int locListSize = oneGraspList.size();
    LatLng lastLocation = oneGraspList.get(locListSize - 1);
    return lastLocation;
    }

    /**
    * 计算当前点到线的垂线距离
    *
    * @param p 当前点
    * @param lineBegin 线的起点
    * @param lineEnd 线的终点
    */
    private static double calculateDistanceFromPoint(LatLng p, LatLng lineBegin,
    LatLng lineEnd) {
    double A = p.longitude - lineBegin.longitude;
    double B = p.latitude - lineBegin.latitude;
    double C = lineEnd.longitude - lineBegin.longitude;
    double D = lineEnd.latitude - lineBegin.latitude;

    double dot = A * C + B * D;
    double len_sq = C * C + D * D;
    double param = dot / len_sq;

    double xx, yy;

    if (param < 0 || (lineBegin.longitude == lineEnd.longitude
    && lineBegin.latitude == lineEnd.latitude)) {
    xx = lineBegin.longitude;
    yy = lineBegin.latitude;
    // return -1;
    } else if (param > 1) {
    xx = lineEnd.longitude;
    yy = lineEnd.latitude;
    // return -1;
    } else {
    xx = lineBegin.longitude + param * C;
    yy = lineBegin.latitude + param * D;
    }
    return AMapUtils.calculateLineDistance(p, new LatLng(yy, xx));
    }

    /***************************抽稀算法结束*********************************/

    private List<LatLng> reduceNoisePoint(List<LatLng> inPoints, float threshHold) {
    synchronized (this) {
    if (inPoints == null) {
    return null;
    }
    if (inPoints.size() <= 2) {
    return inPoints;
    }
    List<LatLng> ret = new ArrayList<LatLng>();
    for (int i = 0; i < inPoints.size(); i++) {
    LatLng pre = getLastLocation(ret);
    LatLng cur = inPoints.get(i);
    if (pre == null || i == inPoints.size() - 1) {
    ret.add(cur);
    continue;
    }
    LatLng next = inPoints.get(i + 1);
    double distance = calculateDistanceFromPoint(cur, pre, next);
    if (distance < threshHold) {
    ret.add(cur);
    }
    }
    return ret;
    }
    }

    }
  • 相关阅读:
    struts2简介
    HDU 2842 Chinese Rings(矩阵高速功率+递归)
    Cocos2d-X中国象棋的发展《五岁以下儿童》摆棋
    【Python注意事项】如何理解python中间generator functions和yield表情
    [CSS] Design for Mobile First with Tachyons
    [Angular] Configurable NgModules
    [Angular] Using useExisting provider
    [Angular] Providers and useFactory
    [Angular] Using InjectionToken
    [Angular] Test Directive
  • 原文地址:https://www.cnblogs.com/blog-wangke/p/14871893.html
Copyright © 2011-2022 走看看