这一周是讲关于人工势场方法的一些基础内容。
Constructing Artificial Potential Fields
建立一个光滑函数,在目标处函数值最小。用梯度引导机器人过去。在二自由度场里,可以简单的选择距离的平方作为函数。这个函数是为了引导路径朝着目标点运动而设计的。
建立反推的势场,
ρ
返回距离。这个是为了防止机器人和障碍相撞而设计的。很多个障碍可以设计很多个反推势场,然后叠加起来就可以。
这里有一个小技巧: 图像角度可以用灰度的差表示距离。
可以把一个引力场和一个反推势场合起来,就可以得到了两种功能的势场。
下图解释:v的方向和梯度方向一样,v的大小可以自己定。可以是全程匀速,可以是接近目标的时候减速。
Quiver plot描述法。这只是一种描述方式。quiver是matlab中绘制二维矢量场的函数,使用该函数可以将矢量用二维箭头绘制出来。相关函数还有quiver3等。
梯度方法最大的优点是只需要机器人计算出人工势场函数f的梯度。更重要的是,只需要知道它的位置和局部的传感器数据。知道了自己的位置,就知道吸引的势场,可以朝着目标前进,用自己局部传感器的状态就知道了距离最近的障碍物距离,就可以知道了远离的势场。在附近的几个点就可以知道梯度的算法,这样自己速度的方向就知道了。
Issues with Local Minima
有的时候人工势场法不一定有解。 梯度算法都是这样。和初值选取有关。如果不小心找到了局部最优解怎么办,在问题发生之前很难探测到这类问题?解决方法可以使用启发式算法,但是有的时候会到达dead end,这时需要返回几步再寻找最优解。
Generalizing Potential Fields
很容易就产生了多个自由度的configuration space
人工构造一个引力场。设置一些控制点,使这些控制点的运动趋势远离障碍物,接近目标,按照梯度的方法接近要控制目标。例如,上一周作业里6自由度的机器人,就是把每个关节的位置当作一个自由度,控制这些地方。不过我觉得,上图中第二步如何计算控制点可能是一个比较大的问题。因为有些约束不容易直接和机器人的关节运动角度相对应。
关于作业要注意这么几个事情:
对于坐标系来讲,横着的坐标第一列坐标,纵向的坐标是第二列的坐标。
对于矩阵来讲,第几行是第一列坐标,第几列是第二列坐标。这两者刚好是反过来的。务必注意矩阵和坐标系之间的对应关系!正交化的最快方法:注意一定要检验norm不是0才能做除法。
normVDir = norm(v_direction); if normVDir > 1e-5 norm_v_direction = v_direction / normVDir; else norm_v_direction = v_direction; end
这里之所以说最快方法是因为在stackoverflow上查过了。(当时觉得norm函数太慢,后来发现自己写二范数还不如直接norm)
求梯度还可以这么求:假如f是一个二维数组,那么可以分别求它水平和竖直方向的梯度:
[gx, gy] = gradient (-f);
返回的 gx 和 gy 是和f一样维数的矩阵。 gx 是 ∂f/∂x , gy 是 ∂f/∂y ,那个-f是逆梯度的意思。具体用法可以参考这里。不过求梯度最好还是插值比较好,见第5条。
用图像处理的函数
bwdist
求与最近障碍物的距离的想法还是挺好的。可以把障碍部分的坐标对应的逻辑数字设置为1, 不是障碍的部分设置为0. 然后调用bwdist函数,在每个逻辑值为0的地方会返回距离最近的“1”的点的距离。如果使用[D,L] = bwdist(bw)
D就是距离,L是对应的距离最近的“1”的点的序号(按列从左到右)。参考这里。梯度表的生成过程:
有人说梯度表应该用插值,不应该用圆整。(应该用interp不应该用现在的round)好像确实interp更有意义一些。但是round计算速度比较快。这里插值都是2次插值,interp2函数。这个函数要用到meshgrid比较麻烦。
[gx1x, gx1y] = meshgrid(1:ncols, 1:nrows);
v_direction(1) = interp2(gx1x, gx1y, gx, route(i, 1), route(i, 2));两个要对应。