前两章讲了定位的概率方法,是一个低维度感知问题,假设地图已知。
但有些情况地图未知,或者不准确。
因此建图可以让部署机器人更容易,也会让机器人更能适应环境变化。
建图是真正的自动机器人的核心竞争力之一。
建图难在:
影响建图的难度的因素有:
尺寸,感知和执行的噪声,感知模糊度(不同地方的相似度),闭环场景。
本章首先假设定位已知,然后介绍一系列算法,统称为occupancy grids。
占据栅格地图课从有噪、不确定的测量数据中构建连续的地图。
其思想是用一个在均匀分布的栅格中的随机变量场来表示地图。
每一个随机变量都是二值的,对应其位置是否被占据。
占据栅格地图算法实现了这些随机变量的后验概率估计。
这种地图的用处在于后加工(post-processing)。
因为SLAM产生的地图不适于路径规划与导航,
因此经常在SLAM之后使用占据栅格地图地图算法。
目标是计算地图后验 p ( m ∣ z 1 : t , x 1 : t ) p(m|z_{1:t},x_{1:t}) p(m∣z1:t,x1:t)。
由于假设位姿信息已知,因此无需控制信息 u u u。
算法使用的是高分辨率的栅格,最常用的领域是二维建筑平面图。
算法也可以泛化至三维,但计算量很大。
把第 i i i个格子记为 m i \bm{m}_i mi;
栅格地图由有限多个格子构成,即 m = ∑ i m i m=\sum_i\bm{m}_i m=∑imi。
每个 m i \bm{m}_i mi都可以取两个值,1为占据,0为自由。
表达式 p ( m i = 1 ) p(\bm{m}_i=1) p(mi=1)和 p ( m i ) p(\bm{m}_i) p(mi)均指格子被占据的概率。
地图后验的问题在于其维度。
解决的标准做法是估计所有小格子的概率,即 p ( m i ∣ z 1 : t , x 1 : t p(\bm{m}_i|z_{1:t},x_{1:t} p(mi∣z1:t,x1:t。
这样就不能表征相邻格子之间的相关性,即假设格子间独立:
p ( m ∣ z 1 : t , x 1 : t ) = Π i p ( m i ∣ z 1 : t , x 1 : t p(m|z_{1:t},x_{1:t})=\Pi_i p(\bm{m}_i|z_{1:t},x_{1:t} p(m∣z1:t,x1:t)=Πip(mi∣z1:t,x1:t
可以使用二项贝叶斯滤波器来估计每个格子的值,参考章节4.1.4。
滤波器中使用log-odds表示,即
l t , i = log p ( m i ∣ z 1 : t , x 1 : t ) 1 − p ( m i ∣ z 1 : t , x 1 : t ) l_{t,i}=\log\frac{p(\bm{m}_i|z_{1:t},x_{1:t})}{1-p(\bm{m}_i|z_{1:t},x_{1:t})} lt,i=log1−p(mi∣z1:t,x1:t)p(mi∣z1:t,x1:t)
这种表达的优点是可以回避逼近0值或1值时的数值不稳定问题。
由log-odds ratio计算概率表达式:
p ( m i ∣ z 1 : t , x 1 : t ) = 1 − 1 1 + exp { l t , i } p(\bm{m}_i|z_{1:t},x_{1:t})=1-\frac{1}{1+\exp \{l_{t,i}\}} p(mi∣z1:t,x1:t)=1−1+exp{lt,i}1
算法 occupancy_grid_mapping( { l t − 1 , i } , x t , z t \{l_{t-1,i}\},x_t,z_t {lt−1,i},xt,zt):
1····for all cells m i \bm{m}_i mi do
2········if m i \bm{m}_i mi in perceptual field of z t z_t zt then
3············ l t , i = l t − 1 , i + inverse_sensor_model ( m i , x t , z t ) − l 0 l_{t,i}=l_{t-1,i}+\textbf{inverse\_sensor\_model}(\bm{m}_i,x_t,z_t)-l_0 lt,i=lt−1,i+inverse_sensor_model(mi,xt,zt)−l0
4········else
5············ l t , i = l t − 1 , i l_{t,i}=l_{t-1,i} lt,i=lt−1,i
6········endif
7····endfor
8····return ${l_{t,i}}
算法中使用inverse_sensor_model(即 p ( m i ∣ z t , x t ) p(\bm{m}_i|z_t,x_t) p(mi∣zt,xt))来更新。
对于锥状测距传感器的逆测量模型为:
前面的算法都只使用传感器数据来更新地图,但还可以使用机器人占据的空间信息;
这个信息可以加进inverse传感器模型中。
不同传感器建图的方法不同:
如对于双目,可以把得到的视差图投影到二维空间上,然后对结果用高斯核卷积。
有两种方法可以处理多种传感器的数据:
称 p ( m i ∣ x , z ) p(\bm{m}_i|x,z) p(mi∣x,z)为逆的原因是:
它根据由这个世界造成的测量数据,提供关于这个世界的信息。
下面推导逆测量模型。
根据贝叶斯定律:
p ( m i ∣ x , z ) = η ∫ m : m ( i ) = m i p ( z ∣ x , m ) p ( m d m p(\bm{m}_i|x,z)=\eta \int_{m:m(i)=\bm{m}_i}p(z|x,m)p(m_dm p(mi∣x,z)=η∫m:m(i)=mip(z∣x,m)p(mdm$
即对第 i i i个格子取值为 m i \bm{m}_i mi的所有地图积分。
很明显,地图太多,无法积分,需要近似。
近似算法包括使用测量模型生成样本,然后使用函数近似器来近似这个逆。
生成($x_t{[k]} z_t{[k]}\ \bm{m}_i^{[k]})样本的步骤如下:
这样一系列三元组可以作为训练集。
这个做法有点低效,因为它并没有利用一些逆传感器模型的特性,如:
可以把以上作为限制条件,加入样本生成中,以减小数据集大小。
为了训练函数,需要一个近似的误差函数,如使用BP算法的神经网络。
训练集的格式为: input [ i ] → occ ( m i ) [ i ] \text{input}^{[i]} → \text{occ}(\bm{m}_i)^{[i]} input[i]→occ(mi)[i]。
假设每个训练数据都相互独立,记函数近似器的参数为 W W W,则训练集的可能性为
Π i p ( m i [ k ] ∣ input [ k ] , W ) \Pi_i p(\bm{m}_i^{[k]}|\text{input}^{[k]},W) Πip(mi[k]∣input[k],W);
其log为 J ( W ) = ∑ i log p ( m i [ k ] ∣ input [ k ] , W ) J(W)=\sum_i \log p(\bm{m}_i^{[k]}|\text{input}^{[k]},W) J(W)=∑ilogp(mi[k]∣input[k],W)。
训练即最小化函数值J。
记函数近似器为 f ( input [ k ] , W ) f(\text{input}^{[k]}, W) f(input[k],W),输出为0到1之间的数(即占据可能性);
也就是:
p ( m i [ k ] ∣ input [ k ] , W ) = { f ( input [ k ] , W ) i f m i [ k ] = 1 1 − f ( input [ k ] , W ) i f m i [ k ] = 0 p(\bm{m}_i^{[k]}|\text{input}^{[k]},W)=\left\{ \begin{aligned} f(\text{input}^{[k]},W)\ \ \ \ & if \bm{m}_i^{[k]}=1 \\ 1 - f(\text{input}^{[k]},W)\ \ \ \ & if \bm{m}_i^{[k]}=0 \end{aligned} \right. p(mi[k]∣input[k],W)=⎩⎨⎧f(input[k],W) 1−f(input[k],W) ifmi[k]=1ifmi[k]=0
即
p ( m i [ k ] ∣ input [ k ] , W ) = f ( input [ k ] , W ) m i [ k ] ( 1 − f ( input [ k ] , W ) ) 1 − m i [ k ] p(\bm{m}_i^{[k]}|\text{input}^{[k]},W)= f(\text{input}^{[k]},W)^{\bm{m}_i^{[k]}} (1 - f(\text{input}^{[k]},W))^{1-\bm{m}_i^{[k]}} p(mi[k]∣input[k],W)=f(input[k],W)mi[k](1−f(input[k],W))1−mi[k]
将上式带入前文 J ( W ) J(W) J(W)的定义,可以得到误差函数:
J ( W ) = − ∑ i m i [ k ] log f ( input [ k ] , W ) + ( 1 − m i [ k ] ) log ( 1 − f ( input [ k ] , W ) ) J(W)=-\sum_i \bm{m}_i^{[k]}\log f(\text{input}^{[k]},W) +(1-\bm{m}_i^{[k]})\log (1-f(\text{input}^{[k]},W)) J(W)=−i∑mi[k]logf(input[k],W)+(1−mi[k])log(1−f(input[k],W))
在样例中,输入的数据是极坐标系下的相对坐标。
在写这本书的时候,学习逆向测量模型的工作较少。
前文假设地图可以解构成相互独立的小格子。
这样一个因数分解导致问题:
因为一个格子可能被多个测量覆盖,且相邻格子有相关性,,所以可能产生矛盾的测量;
导致某个格子的置信度取决于两个测量的频率。
本质上,这是因为测量覆盖多个格子,所以格子间有相关性。
有一个算法可以结合这些相关性,算法输出后验的模式(mode)。
模式的定义是地图的最大后验的log,也就是
m ∗ = argmax m log p ( m ∣ z 1 : t , x 1 : t ) m^*=\text{argmax}_m \log p(m|z_{1:t},x_{1:t}) m∗=argmaxmlogp(m∣z1:t,x1:t)。
地图的后验包括一个地图的先验和一个测量的可能性,即:
log p ( m ∣ z 1 : t , x 1 : t ) = log p ( z 1 : t ∣ x 1 : t , m ) + log p ( m ) \log p(m|z_{1:t},x_{1:t}) = \log p(z_{1:t}|x_{1:t},m) + \log p(m) logp(m∣z1:t,x1:t)=logp(z1:t∣x1:t,m)+logp(m)
右式的第一项可以分解成所有的测量的log,即 log p ( z t ∣ x t , m ) \log p(z_t|x_t,m) logp(zt∣xt,m)。
而第二项是先验的和,即 log p ( m ) = M log ( 1 − p ( m i ) ) + ∑ i ( l 0 ) m i \log p(m) = M\log(1-p(\bm{m}_i))+\sum_i(l_0)^{\bm{m}_i} logp(m)=Mlog(1−p(mi))+∑i(l0)mi
由于上式左边与地图无关,因此最大后验的地图为:
m ∗ = argmax m ∑ t log p ( z t ∣ x t , m ) + ∑ i ( l 0 ) i m m^*=\text{argmax}_m \sum_t \log p(z_t|x_t,m) + \sum_i (l_0)^\bm{m}_i m∗=argmaxm∑tlogp(zt∣xt,m)+∑i(l0)im
可以使用爬坡算法来最大化这个log概率。
算法的优化起点是一张所有格子都free的地图,然后通过翻转某些格子,来提高概率。
对于这种算法,地图先验不能太靠近1,否则会返回一个全占据的地图。
这种算法只能返回一个局部极大值。但实践中,很少有局部极值。
算法 MAP_occupancy_grid_mapping( x 1 : t , z 1 : t x_{1:t}, z_{1:t} x1:t,z1:t):
1····set m = { 0 } m=\{0\} m={0}
2····repeat until convergence
3········for all cells m i \bm{m}_i mi do
4············ m i = argmax k = 0 , 1 ( l 0 ) k + ∑ t log measurement_model ( z t , x t , m with m i = k ) m_i = \text{argmax}_{k=0,1}(l_0)^k + \sum_t \log \textbf{measurement\_model}(z_t,x_t,m \text{with}\ \bm{m}_i=k) mi=argmaxk=0,1(l0)k+∑tlogmeasurement_model(zt,xt,mwith mi=k)
5········endfor
6····endrepeat
7····return m m m
MAP的主旨是对整个时间轴的测量数据做统一优化。
MAP的问题和解决:
本章中所有算法都需要位姿已知,因此并不能解决普遍的建图问题。