自动驾驶定位算法-直方图滤波(Histogram Filter)定位

2024-04-11 02:04

本文主要是介绍自动驾驶定位算法-直方图滤波(Histogram Filter)定位,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

自动驾驶定位算法-直方图滤波(Histogram Filter)定位

image

附赠自动驾驶学习资料和量产经验:链接

1、直方图滤波(Histogram Filter)的算法思想

image

image

image

2、1D直方图滤波在自动驾驶定位的应用

如下图所示,无人驾驶汽车在一维的宽度为5m的世界重复循环,因为世界是循环的,所以如果无人驾驶汽车到了最右侧,再往前走一步,它就又回到了最左侧的位置。

image

自动驾驶汽车上安装有Sensor可以检测车辆当前所在位置的颜色,但Sensor本身的存在一定检测错误率,即Sensor对颜色的检测不是100%准确的;

无人驾驶汽车以自认为1m/step的恒定速度向右运动,车辆运动本身也存在误差,即向车辆发出的控制命令是向右移动2m,而实际的车辆运动结果可能是待在原地不动,可能向右移动1m,也可能向右移动3m。

2.1 数学模型

image

2.2 利用直方图滤波(Histogram Filter)进行车辆定位的过程

image

image

3、2D直方图滤波在自动驾驶定位中的应用(一)

1D的直方图滤波可以很好的帮助我们理解直方图滤波的原理以及在如何应用在自动驾驶的定位过程中。但是1D的直方图滤波在实际应用中几乎是不存在的,所以我们从更偏向应用的角度,看看2D直方图滤波在自动驾驶定位中是如何工作的。

3.1 定义二维地图

首先定义一张二维地图,R和G代表地图块的颜色:R为红色,G为绿色。每个地图块的大小根据实际应用而定,比如0.0125m*0.125m、0.025m*0.025m等。地图块越小,定位精度越高,但是地图数据量和计算量也就越大;反之,地图块越大,定位精度越低,但数据量和计算量也相应较低。

grid = [[R,G,G,G,R,R,R],[G,G,R,G,R,G,R],[G,R,G,G,G,G,R],[R,R,G,R,G,G,G],[R,G,R,G,R,R,R],[G,R,R,R,G,R,G],[R,R,R,G,R,G,G],
]

t=0时刻,车辆不知道自己处于地图中的具体位置,转化为数学表述,就是车辆在各个地图块的置信度相同,代码如下:

def initialize_beliefs(grid):height = len(grid)width = len(grid[0])area = height * widthbelief_per_cell = 1.0 / areabeliefs = []for i in range(height):row = []for j in range(width):row.append(belief_per_cell)beliefs.append(row)return beliefs

初始置信度如下:

0.020  0.020  0.020  0.020  0.020  0.020  0.020  
0.020  0.020  0.020  0.020  0.020  0.020  0.020  
0.020  0.020  0.020  0.020  0.020  0.020  0.020  
0.020  0.020  0.020  0.020  0.020  0.020  0.020  
0.020  0.020  0.020  0.020  0.020  0.020  0.020  
0.020  0.020  0.020  0.020  0.020  0.020  0.020  
0.020  0.020  0.020  0.020  0.020  0.020  0.020 

置信度的可视化如下,红色星星位置为车辆的真实初始实际位置,蓝色圈大小代表置信度的高低,蓝色圈越大,置信度越高,蓝色圈越小,置信度越低。t=0时刻,车辆不确定自己的位置,所以各个位置的置信度相等。

image

3.2 运动更新

车辆运动模型简化为x、y两个方向的运动,同时由于运动的不确定性,需要对运动后的位置增加概率性信息。

代码如下:

def move(dy, dx, beliefs, blurring):height = len(beliefs)width = len(beliefs[0])new_G = [[0.0 for i in range(width)] for j in range(height)]for i, row in enumerate(beliefs):for j, cell in enumerate(row):new_i = (i + dy ) % heightnew_j = (j + dx ) % widthnew_G[int(new_i)][int(new_j)] = cellreturn blur(new_G, blurring)

3.3 观测更新

观测更新的过程中,当观测的Color等于地图块的Color时,hit=1, bel=beliefs[i][j] * p_hit;当观测到的Color不等于地图块的Color时,hit=0, bel=beliefs[i][j] * p_miss。

代码如下:

def sense(color, grid, beliefs, p_hit, p_miss):new_beliefs = []height = len(grid)width = len(grid[0])# loop through all grid cellsfor i in range(height):row = []for j in range(width):hit = (color == grid[i][j])row.append(beliefs[i][j] * (hit * p_hit + (1-hit) * p_miss))new_beliefs.append(row)s = sum(map(sum, new_beliefs))for i in range(height):for j in range(width):new_beliefs[i][j] = new_beliefs[i][j] / sreturn new_beliefs

3.4 运行定位流程

单次直方图滤波定位过程中,先进行观测更新,再进行运动更新。

def run(self, num_steps=1):for i in range(num_steps):self.sense()dy, dx = self.random_move()self.move(dy,dx)

设置运动更新的不确定度为0.1,观测更新的错误率:每隔100次观测出现一次观测错误,车辆的真实初始位置为(3,3),注意,这个真实位置车辆自己并不知道,我们只是为了仿真而设置的值。

blur = 0.1
p_hit = 100.0
init_pos = (3,3)
simulation = sim.Simulation(grid, blur, p_hit, init_pos)simulation.run(1)
simulation.show_beliefs()
show_rounded_beliefs(simulation.beliefs)

经过一次直方图滤波定位之后,各个位置的置信度已经发生了变化。

0.003  0.002  0.036  0.002  0.037  0.003  0.038  
0.003  0.037  0.002  0.002  0.001  0.002  0.037  
0.038  0.038  0.003  0.036  0.002  0.002  0.003  
0.038  0.004  0.038  0.003  0.037  0.038  0.038  
0.003  0.038  0.039  0.038  0.003  0.037  0.003  
0.038  0.038  0.038  0.003  0.037  0.003  0.003  
0.038  0.003  0.002  0.002  0.038  0.038  0.038 

置信度的可视化效果如下。可以看到,车辆已经对自己的置信度有了一定的认知,但是还是有大量的可能位置需要进一步确认。

image

连续执行直方图滤波100次,各个位置置信度的数值如下:

0.008  0.000  0.000  0.000  0.000  0.016  0.016  
0.032  0.001  0.000  0.000  0.001  0.032  0.833  
0.016  0.000  0.000  0.000  0.000  0.025  0.017  
0.001  0.000  0.000  0.000  0.000  0.000  0.000  
0.000  0.000  0.000  0.000  0.000  0.000  0.000  
0.000  0.000  0.000  0.000  0.000  0.000  0.000  
0.000  0.000  0.000  0.000  0.000  0.000  0.000

置信度的可视化效果如下,可以看到,车辆已经83.3%的概率可以确定自己所处的位置了。

image

4、2D直方图滤波在自动驾驶定位中的应用(二)

image

车辆的运动模型代码如下:

def motion_model(x, u):F = np.array([[1.0, 0, 0, 0],[0, 1.0, 0, 0],[0, 0, 1.0, 0],[0, 0, 0, 0]])B = np.array([[DT * math.cos(x[2, 0]), 0],[DT * math.sin(x[2, 0]), 0],[0.0, DT],[1.0, 0.0]])x = F @ x + B @ ureturn x

4.1 运动更新

运动更新的过程与前面谈到的车辆运动模型一致,车辆运动有不确定性,所以增加了Gaussian Filter用来处理不确定性。还有一个细节,就是车辆运动距离和直方图滤波的分块地图之间的转换关系:

x_shift = Δ x / map_x_resolution

y_shift = Δ y / map_y_resolution

代码如下:

# grid_map是网格地图,u=(v,w)是车辆运动的控制参数,yaw是车辆朝向
def motion_update(grid_map, u, yaw):# DT是时间间隔grid_map.dx += DT * math.cos(yaw) * u[0]grid_map.dy += DT * math.sin(yaw) * u[0]# grid_map.xy_reso是地图分辨率x_shift = grid_map.dx // grid_map.xy_resoy_shift = grid_map.dy // grid_map.xy_resoif abs(x_shift) >= 1.0 or abs(y_shift) >= 1.0:  # map should be shiftedgrid_map = map_shift(grid_map, int(x_shift), int(y_shift))grid_map.dx -= x_shift * grid_map.xy_resogrid_map.dy -= y_shift * grid_map.xy_reso# MOTION_STD是车辆运动不确定性的标准差grid_map.data = gaussian_filter(grid_map.data, sigma=MOTION_STD)return grid_map

4.2 观测更新

这个例子中通过测量车辆到LandMark的距离来确定自身的位置,LandMark的位置都是已知的。

image

def calc_gaussian_observation_pdf(gmap, z, iz, ix, iy, std):# predicted rangex = ix * gmap.xy_reso + gmap.minxy = iy * gmap.xy_reso + gmap.minyd = math.sqrt((x - z[iz, 1]) ** 2 + (y - z[iz, 2]) ** 2)# likelihoodpdf = (1.0 - norm.cdf(abs(d - z[iz, 0]), 0.0, std))return pdf#z=[(车辆到Landmark的测量距离,Landmark的x坐标,Landmark的y坐标),...],z是所有Landmark测量距离和位置的集合,std是测量误差的标准差
def observation_update(gmap, z, std):for iz in range(z.shape[0]):for ix in range(gmap.xw):for iy in range(gmap.yw):gmap.data[ix][iy] *= calc_gaussian_observation_pdf(gmap, z, iz, ix, iy, std)# 概率归一化gmap = normalize_probability(gmap)return gmap

4.3 运行定位流程

设置地图和测量相关参数:

DT = 0.1  # time tick [s]
MAX_RANGE = 10.0  # maximum observation range
MOTION_STD = 1.0  # standard deviation for motion gaussian distribution
RANGE_STD = 3.0  # standard deviation for observation gaussian distribution# grid map param
XY_RESO = 0.5  # xy grid resolution
MINX = -15.0
MINY = -5.0
MAXX = 15.0
MAXY = 25.0# Landmark Position
RF_ID = np.array([[10.0, 0.0],[10.0, 10.0],[0.0, 15.0],[-5.0, 20.0]])
# 车辆的初始位置(for simulation)
xTrue = np.zeros((4, 1))

通过Observation模拟自动驾驶车辆对各个LandMark的观测结果和车辆速度的误差。

def observation(xTrue, u, RFID):xTrue = motion_model(xTrue, u)z = np.zeros((0, 3))for i in range(len(RFID[:, 0])):dx = xTrue[0, 0] - RFID[i, 0]dy = xTrue[1, 0] - RFID[i, 1]d = math.sqrt(dx ** 2 + dy ** 2)if d <= MAX_RANGE:# add noise to range observationdn = d + np.random.randn() * NOISE_RANGEzi = np.array([dn, RFID[i, 0], RFID[i, 1]])z = np.vstack((z, zi))# add noise to speedud = u[:, :]ud[0] += np.random.randn() * NOISE_SPEEDreturn xTrue, z, ud

执行车辆定位流程:

    while SIM_TIME >= time:time += DTprint("Time:", time)u = calc_input()yaw = xTrue[2, 0]  # Orientation is knownxTrue, z, ud = observation(xTrue, u, RF_ID)grid_map = histogram_filter_localization(grid_map, u, z, yaw)

定位效果如下:

image

这篇关于自动驾驶定位算法-直方图滤波(Histogram Filter)定位的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/892785

相关文章

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

Open3D 基于法线的双边滤波

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 输入参数: 输出参数: 参数影响: 2.2完整代码 三、实现效果 3.1原始点云 3.2滤波后点云 Open3D点云算法汇总及实战案例汇总的目录地址: Open3D点云算法与点云深度学习案例汇总(长期更新)-CSDN博客 一、概述         基于法线的双边

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

秋招最新大模型算法面试,熬夜都要肝完它

💥大家在面试大模型LLM这个板块的时候,不知道面试完会不会复盘、总结,做笔记的习惯,这份大模型算法岗面试八股笔记也帮助不少人拿到过offer ✨对于面试大模型算法工程师会有一定的帮助,都附有完整答案,熬夜也要看完,祝大家一臂之力 这份《大模型算法工程师面试题》已经上传CSDN,还有完整版的大模型 AI 学习资料,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

dp算法练习题【8】

不同二叉搜索树 96. 不同的二叉搜索树 给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。 示例 1: 输入:n = 3输出:5 示例 2: 输入:n = 1输出:1 class Solution {public int numTrees(int n) {int[] dp = new int