Last edited time: March 31, 2023 1:30 PM
Reference and prenotes
Paper link:https://ieeexplore.ieee.org/document/9158399
Code link:https://github.com/UnknownFreeOccupied/ufomap
主要是针对octomap的,framework去做对比和实验
voxel hashing:voxblox
Voxblox builds on [13] where they use a spatial hashing scheme and allocate blocks of fixed size when needed
octree-based: OctoMap
octomap对比于voxblox 可以更节约内存 or a fixed grid structure 保存在不同分辨率下的八叉树内
ufomap基于octomap来看: 每一个node都有一个占据值 去标识是否 occupancy/free/unknown 保存的是log-odds occupancy value
A probabilistic occupancy value is used in order to better handle sensor noise and dynamic environments
与octomap相同的是,每一个node有的是它所有children中的最大占据值,方便路径规划
但是octomap中我记得unknown的节点其实是空的(被剪掉的) 为了节约memory的操作,其实也不算 本身其不做 只是为了 memory save的原因 而不做吧?
nope duberg大哥说 即使是空的 octomap 还是给了pointer,一个pointer是8个bits,所以他们只是空了 剪掉了 但是pointer没剪掉 所以这就是为什么下面实验中 ufomap可以省空间的原因,因为ufomap是一个pointer到一个array 里面是children 看下面framework介绍 因为这个问题是我看完全文问的
UFOMap 保存三个 indicators i f , i u , i a i_f,i_u,i_a if,iu,ia
前两个指示 这个是否是free/unknown,而被占据的不需要再单独给出一个 因为有 occupancy value;
注意,当更新Octree时 indicator values 也会随着树向上传播 propagated upwards
最后一个则是判断所有children是否是一样的,主要是在自动pruning被禁止时 可以有相同的功能
自动pruning 意味着当数据被删除或者插入数据时,octree会自动pruned,而禁止他的主要原因是 我们想同时进行读取、插入和删除数据
而此 indicators 也可以提高 traversing 整个树的效率,比如当我们仅寻找unknown space的时候
问题区
indicator values 和 occupancy values不是同一个东西?
不是 indicator 是 0/1 occupancy value是一个float值
这里的 pruning 被禁止 可以有相同的功能是指?人为去判断是否要进行嘛?
[原文: i a i_a ia is useful in cases where automatic pruning has been disabled, but you still want the same behavior as if it were enabled. ]
是的 原文里 有 同时进行访问 插入 删除的时候 会禁止,这种情况下 就由 我们手动指定什么时候做 prune
pruned 操作在 code 中的体现?
不用管 用就行了
[原文:The third indicator, ia, indicates whether all of a node’s children are the same. ] 这里的判断是否是一样的是指 前面两个 indicators嘛?还是指 free/occupancy/unknown
感觉是的… 确认一下吧
MK: 根据Fig 2图c感觉应该就是(~if) | (~iu)。图里没给if iu都是0的情况,但ia=1应该不需要找children了,而if iu都是0说明全occupied,应该还要找到d_max为止
OctoMap 的节点状态 如下表示:
state ( n ) = { unknown if n is null pointer occupied if t o ≤ occ ( n ) free else. \operatorname{state}(n)= \begin{cases}\text { unknown } & \text { if } n \text { is null pointer } \\ \text { occupied } & \text { if } t_o \leq \operatorname{occ}(n) \\ \text { free } & \text { else. }\end{cases} state(n)=⎩ ⎨ ⎧ unknown occupied free if n is null pointer if to≤occ(n) else.
而 UFOMap 里的节点状态 进行了一点扩充 加入了另一个 t f t_f tf 阈值 来只是如果超过小于此 则说明是free状态
state ( n ) = { unknown if t f ≤ occ ( n ) ≤ t o occupied if t o < occ ( n ) free if t f > occ ( n ) \operatorname{state}(n)= \begin{cases}\text { unknown } & \text { if } t_f \leq \operatorname{occ}(n) \leq t_o \\ \text { occupied } & \text { if } t_o<\operatorname{occ}(n) \\ \text { free } & \text { if } t_f>\operatorname{occ}(n)\end{cases} state(n)=⎩ ⎨ ⎧ unknown occupied free if tf≤occ(n)≤to if to<occ(n) if tf>occ(n)
比如 设定 tf = 0.1 to=0.9,节点本身只有在确定自己是被占据/free的时候 才给状态 否则就是未知,这对于 exploration和reconstruction的任务 可以快速定位到 unknown 进行处理
再比如 设定 tf=0.5 to=0.9 则意味着 exploration algorithm 可以将注意力集中在 occupancy 区域. meaning you would target higher certainty about the occupied space.
tf=0.5 to=0.9的时候 为什么是 [meaning you would target higher certainty about the occupied space.] 主要是对occ的判断只和 to有关 to=0.9是不变的,只是说变unknown的条件更严格了吧?
是的 因为前面的是 tf=0.1 to=0.9 所以是对free和occupied都 严格; tf=0.5 to=0.9的画 就是只对occupied严格了,duberg说他应该写一个only
OctoMap: inner nodes and inner leaf nodes
UFOMap: inner nodes, inner leaf nodes, and leaf nodes. [多了一个leaf node]
以下为详细的解释:
下图是三个nodes的展示:
(b, c) 是 UFOMap的哈:
那这个inner leaf nodes存在的意义是?
名字 进行区分
这两句话 inner leaf node 和 leaf node都没有 children不是矛盾的嘛?
【我感觉是 区别应该是 是否有 indicators】
参考文献[15] 中文博客有一些解释:莫顿码:莫顿码是将多维数据转化为一维数据的编码
首先将 笛卡尔坐标系的 点云 c = ( c x , c y , c z ) ∈ R 3 c = (c_x,c_y,c_z) \in \R^3 c=(cx,cy,cz)∈R3 转到 octree node的index tuple k = ( k x , k y , k z ) ∈ N 0 3 k=(k_x,k_y,k_z) \in \N^3_0 k=(kx,ky,kz)∈N03 ,其中 k的计算为:
k j = ⌊ c j res ⌋ + 2 d max − 1 k_j=\left\lfloor\frac{c_j}{\text { res }}\right\rfloor+2^{d_{\max }-1} kj=⌊ res cj⌋+2dmax−1
如下图所示的通过交错表示 kj 的位,可以为 一个点云坐标闯进对应的 莫顿码 m
然后可以从根节点向下遍历到这个节点,原文 From the root node it is then possible to traverse down to the node by simply looking at the three bits of m m m that corresponds to the depth of the child and moving to that child
代码中 这里 右移 又左移 不就没有了定位到那个depth了嘛?
using code_t = uint64_t;
using depth_t = uint8_t;
/*!
* @brief Return the code at a specified depth
*
* @param depth The depth of the code
* @return Code The code at the specified depth
*/
constexpr Code toDepth(depth_t depth) const
{
code_t temp = 3 * depth;
return Code((code_ >> temp) << temp, depth);
// (code_ >> temp) << temp
}
因为 右移左移 可以有设0,当然ufomap2.0【还没发布】已经做了更聪明的方式
举个例子 [1111 1111] 经过 右移三位是 [1111 1],然后左移三位[1111 1000] 所以还是有区别的
终于 讲完了 不擅长的部分 虽然遗留的问题好像还是有点多 … 等等 问问duberg吧 作者在身边的好处就是这个 hhh
这一部分主要就是怎么根据点云进行生成occupancy value了,一共有三种方法 每一种都比前一种更快,但是更快的
参考 [17] 对于每一个点! trace a ray 减少从 传感器出发点 到 终点hit point之间所有grid的occupancy value,然后hit point的地方 占用值增加 【Same in OctoMap】
对于点先进行离散化 如果多个点落在同一个grid里 对这一个grid只做一次 ray casting 【Same in OctoMap】
Fast Discrete: ray casting 和 离散化 是在八叉树的不同深度进行的
其中 d 和 n 是可以调节的参数 用来平衡 效果和速度;举两个极端的例子:
其中为了 补偿 occupancy value在方法三 遇到 larger surface 下降的情况,the clearing 会有一个因子 1 2 d + 1 \frac{1}{2d+1} 2d+11
在所有方法中 occupancy grid都是以最高分辨率进行的更新,因此三种ray方案在occupancy 下 几乎是一样的 如上图四的比较
问题区
Ray marching is performed until n nodes, at that resolution, away from the end node. 远离end node是什么意思? 不太懂
是指 这个分辨率 还没到 end node 也就是leaf node
首先是关于区分 inner leaf node 和 leaf node ,因为OctoMap里面 他们都是一个 inner leaf node
从 [5] 中 我们得知 大多数 octree node 在OctoMap 里都是 inner leaf node [80-85%] 而在UFOMap里面 因为我们再次做了区分,所以这个值下降了71-81%,也就是说大部分节点 其实是leaf node,通过UFOMap的再次划分 即使是我们的树节点总数增加的情况下,也可以明显减少内存使用量 对比OctoMap 减少了三倍 【参考问题 ① 】
① 这个内存减少 如果 inner leaf node里面只存了log-odd value 再加上一个空指针 并不会耗多少memeory吧?所以减少的不是因为 我们把 inner leaf node区分开了吧? !!问一下duberg
因为实际上的octomap上存的虽然是空指针 但是一个指针 8bits, 即使空的 9*8=72,但是ufomap只需要一个pointer,也就是8个bits,然后指针指向children array开头,而octomap需要先做一个pointer指向parent的指针位置 然后再指向找到想到的那个children的pointer
图五则是不同的 ray 方案 也就是 2.4里提到的:
这里则是不同的操作的时间对比 主要和OctoMap对比
妙啊,然后有 作者Duberg 再旁边解释 也太爽了 hhhh 当然里面的解释还是我转述的哈,如果有啥不对的 不是Duberg哥的锅 是我的理解的锅
Duberg 大哥和我说 不用看内在代码 用就行了,寻思着 我写的C++技巧过多 你可能陷进去了
最后 February 22, 2023 更新一下用UFOMap做下游任务的一系列paper 现在ufomap的文档还没更新 所以使用者都是由作者手把手教学 hhh 等后面文档更新了 可能使用的人可以开始变得更多
赠人点赞 手有余香 ;正向回馈 才能更好开放记录 hhh