large-scale-DRL-exploration 代码阅读(五)
接下来的代码主要剩余:worker 强化学习中的收集经验的部分
还有就是主要是探索、构建环境相关的代码了;和强化学习关系不是很大了,即探索部分。
agent.py
- map_info: 机器人实时构建的地图,初始化是一个和真实地图尺寸一样,但都是未知栅格状态的地图
updating_map:机器人周围的局部探索范围地图,尺寸大于感知范围,在这个局部范围提取边界点和生成视点,做探索规划
python 语法
1. a = np.array([10, 20, 30, 20])
np.where(a == 20)
返回一个元组,a 是几维就返回几维的元组,每一维是一个数组,存放的是相应的在这一维的索引。
如:a 是 1D:(array([1, 3]),) # 长度为1的元组
b = np.array([[1, 2],
[3, 2]])
np.where(b == 2)
return: (array([0, 1]), array([1, 1]))
元组长度 = 数组维度 = 2
第一个数组 → 行索引
第二个数组 → 列索引
组合起来表示满足条件的位置:(0,1) 和 (1,1)
2. np.lib.pad(unknown, ((1, 1), (1, 1)), 'constant', constant_values=0)
在unknown 这个2D矩阵的最左侧右侧上册下册均padding 一行一列 0 常数
unknown[2:][:, 1:x_len + 1]
取2d数组的第2行到最后一行和第一列到第 x_len 列
从0开始的
np.where(map_info.map.ravel(order='F') == FREE)[0]
map_info.map.ravel(order='F') 2D 数组按列展成1D数组
np.where() 返回元组
[0] 取元组第一个元素,展成1D了,所以本质上这个元组只有一维,长度为1,然后这个维度里面才是数组,存储的是在这一维上==FREE的元素的索引。
np.intersect1d(frontier_cell_1, frontier_cell_2)
两个数组的交集
x = np.linspace(0, x_len - 1, x_len)
np.linspace(start, stop, num)
start:起始值stop:终止值(包含在内)num:生成的样本点个数返回:等间距的
num个点组成的 一维数组
t1, t2 = np.meshgrid(x, y)
np.meshgrid 用于生成二维网格坐标矩阵。
x:一维数组,表示 列坐标y:一维数组,表示 行坐标返回两个矩阵:
t1:每个格子的 x坐标t2:每个格子的 y坐标
举例(小网格 3×3): so nine cells
x = [0, 1, 2]
y = [0, 1, 2]
t1, t2 = np.meshgrid(x, y)
t1:
[[0, 1, 2],
[0, 1, 2],
[0, 1, 2]]
t2:
[[0, 0, 0],
[1, 1, 1],
[2, 2, 2]]
解释:
t1[i,j]→ 第i行、第j列的 x坐标t2[i,j]→ 第i行、第j列的 y坐标
也就是说 (t1[i,j], t2[i,j]) 就是第 i,j 个格子的二维索引。
注意这里是 行 i 对应 y,列 j 对应 x
cells = np.vstack([t1.T.ravel(), t2.T.ravel()]).T
(1) t1.T
对
t1做转置转置后保证**列优先展平(Fortran 顺序)**和之前
ravel(order='F')的索引对应2️⃣ 为什么要
.T?前面前沿检测的索引是 列优先(order='F')) 展平的:
前面的操作一直是按列优先
如果直接
t1.ravel(),展开顺序是 按行优先(默认 C 风格)列优先展开 (
order='F')) 的顺序才和前面的索引匹配
(2) .ravel()
将二维矩阵展平为一维数组
t1.T.ravel()→ 所有格子的 x 坐标按列优先排列t2.T.ravel()→ 所有格子的 y 坐标按列优先排列
(3) np.vstack([..., ...])
把两个一维数组 垂直堆叠(stack vertically)
结果是一个 2×N 的数组:
[[x0, x1, x2, ..., xN-1],
[y0, y1, y2, ..., yN-1]]
(4) .T
转置一次,把形状改成 N×2:
[[x0, y0],
[x1, y1],
[x2, y2],
...
[xN-1, yN-1]]
3️⃣ 小例子(3×3 网格)
x = [0, 1, 2]
y = [0, 1, 2]
t1, t2 = np.meshgrid(x, y)
cells = np.vstack([t1.T.ravel(), t2.T.ravel()]).T
print(cells)
t1:
[[0 0]
[0 1]
[0 2]
[1 0]
[1 1]
[1 2]
[2 0]
[2 1]
[2 2]]
cells = np.vstack([t1.T.ravel(), t2.T.ravel()]).T
frontier_cell = cells[frontier_cell_indices]
cells = np.array([
[0,0], [0,1], [0,2],
[1,0], [1,1], [1,2],
[2,0], [2,1], [2,2]
])
frontier_cell_indices = np.array([1, 5, 7])
frontier_cell = cells[frontier_cell_indices]
print(frontier_cell)
输出:
[[0 1]
[1 2]
[2 1]]
downsampled_data = set(map(tuple, voxel_dict.values()))
这一行代码的作用是 把下采样后的点从 NumPy 数组转换成集合形式
1️⃣ voxel_dict.values()
voxel_dict是一个字典,每个体素只保留了一个点voxel_dict.values()返回字典中所有保留的点,是一个 可迭代对象每个点本身是一个 NumPy 数组,形状
(2,),表示(x, y)坐标
2️⃣ map(tuple, ...)
NumPy 数组不能直接作为集合的元素,因为数组 不可哈希
用
map(tuple, ...)把每个点从数组转换成 元组(x, y)元组是可哈希的,可以放进 Python 集合中
3️⃣ set(...)
将所有元组放入集合,得到 去重后的点集
保证每个体素只保留一个点,同时方便后续做集合运算
