离线的前向三次样条曲线和体素网格

Matlab文件path_generator.m的目的是生成3个ply文件和correspondences.txt这里就是一个可优化的方向。

生成的的是3个离线的曲线,也就是local_planner\pathsstartPaths.ply, pathList.ply, paths.ply。 这3个文件都在localPlanner.cpp的main函数里使用

startPaths.ply文件的文件头

1
2
3
4
5
6
7
8
ply
format ascii 1.0
element vertex 707 # 点的总数
property float x
property float y
property float z
property int group_id
end_header

然后是很多的点,形式是0.842435 -0.113153 0.000000 2,依次是x,y,z,索引。可以用Cloud Compare打开
startPaths.ply
记录第一次采样的路径点,7个路径组,每个有101个点。每个都是三次样条曲线,根据Matlab中设置的参数,对称的每条路径依次偏移9°,每条路径有101个点,即0:0.01:1,按说起始点都是(0,0),也就是共用了原点,但是从CloudCompare里看,点数还是707,起点的y坐标相差很小很小,我认为这是Matlab的浮点数误差导致生成了7个起点

代码中对应函数readStartPaths:读取文件startPaths.ply,把其中的点都放入点云类型的变量startPaths

同理还有paths.ply
paths.ply
记录三次采样生成的所有路径点,仔细数一数,共有7x7x7=343条路径(第二次采样的路径组分成的7个不应统计), 这和论文里说的35x35=1225不同了。 每条路径有301个点,最右边的点,也就是x最大的点是(3, 0)。最上方的点大约(1.679, 2.486)
代码中对应函数readPaths: 读取文件paths.ply,把其中的点都放入点云类型的变量paths,但考虑 pointSkipNum

后两段段还是三次样条曲线,但生成的方式有所改变,不再是简单的1:0.01:2的遍历,而是对角度做了一定比例的缩放,并不是偏移-54°,而是偏移-44.55°和-55.96°。公式比较复杂,就不深入研究了

以最下方的曲线为例,三段的最后一个点的坐标如下:
第1段的最后一个点.png
第2段的最后一个点.png
第3段的最后一个点.png


pathList.ply
该文件记录了每条路径的最后一个路径点,共7x7x7=343个点
代码中对应函数readPathList: 读取文件pathList.ply,只加入变量pathListendDirPathList

体素网格的生成

path_generator.m中的部分如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 对于碰撞检查,使用覆盖了传感器范围的体素网格。
# 根据样条距离,传感器范围为 3.2*4.5 ,在该区域生成体素网格,在这里考虑了车辆半径的遮挡

voxelSize = 0.02;
searchRadius = 0.45;
# 根据pathList的形状确定的尺寸,比模拟路径的范围稍大点
offsetX = 3.2;
offsetY = 4.5;
# offsetX / voxelSize
voxelNumX = 161;
# 这里是 offsetY * 2 / voxelSize, 体素范围关于x轴对称
voxelNumY = 451;

fprintf('\nPreparing voxels\n');

indPoint = 1;
voxelPointNum = voxelNumX * voxelNumY;
# 一个有很多行 只有2列的矩阵
voxelPoints = zeros(voxelPointNum, 2);

# 在外层循环中,从外向内计算,同采样的路径一样,靠近车体的位置Y的宽度也会随着scaleY减小
for indX = 0 : voxelNumX - 1
x = offsetX - voxelSize * indX;
scaleY = x / offsetX + searchRadius / offsetY * (offsetX - x) / offsetX;
for indY = 0 : voxelNumY - 1
y = scaleY * (offsetY - voxelSize * indY);

voxelPoints(indPoint, 1) = x;
voxelPoints(indPoint, 2) = y;

indPoint = indPoint + 1;
end
end

# 所有坐标都存到了 voxelPoints, zeros(voxelPointNum, 1)相当于扩展了一列 0
plot3(voxelPoints(:, 1), voxelPoints(:, 2), zeros(voxelPointNum, 1), 'k.');
pause(1.0);

其实这里很简单,逐个计算voxelPoints,发现它是下图,x是一个点,点的间距只有0.02
voxelPoints的范围

matlab运行结果得到 fig图 如下,如果放大,会发现是密密麻麻的点
体素网格.jpg

再放大,会发现前向的模拟路径在里面

之所以把体素建模为梯形而不是三角形,应该是在起始点考虑了车辆的宽度。

correspondences表

correspondences.txt在代码中的readCorrespondences函数使用

path_generator.m中的代码如下:

1
2
3
4
5
6
fprintf('\nCollision checking\n');
# rangesearch(X,Y,r):寻找X集合中的点,其与 Y 集合中的点的距离小于r
# 这里就是寻找 paths 的点 和 体素集合中的点中小于搜索半径的点集合
# 记录路径点附近的所有体素网格
[ind, dis] = rangesearch(pathAll(1 : 2, :)', voxelPoints, searchRadius);
# ...... 剩余的省略

直接看文件,每行第一个数是体素网格的索引,即0~72610。 每行最后一个数是-1,在readCorrespondences函数会看到这是作为判断该网格是否有对应的路径。 二者中间就是pathListpathID,范围0~342
程序运行时,路径被放置在体素中心的障碍物所遮挡。 在这里,考虑以车辆的半径来计算遮挡,当然不是Matlab里的0.45

放大后的体素网格和路径,最右边
最右边的一堆体素网格没有任何路径,这就是txt文件中只有网格索引和-1的情况。