5. 优化函数Smoother
5.1 tracePath()
- 功能:此函数的功能就是要找到一条从
start 节点到goal 节点的路径path . - 参数:此处带入的初始节点指针
node 是已经找到的goal 的指针,i 是第回溯到第一个节点了,path 是回溯的路径.
本函数采用了递归调用的模式,不断去找node 的前任节点node->getPred() ,不断更新路径path ,知道node 为空指针nullptr ,意味着已经到了start 节点.
void Smoother::tracePath(const Node3D* node, int i, std::vector<Node3D> path) {
if (node == nullptr) {
this->path = path;
return;
}
i++;
path.push_back(*node);
tracePath(node->getPred(), i, path);
}
5.2 smoothPath()
- 功能:把
tracePath() 回溯到的路径path 进行优化 - 参数:
void Smoother::smoothPath(DynamicVoronoi& voronoi) {
}
5.2.1 初始化参数
包括voronoi的尺寸,最大叠代次数和路径长度.
this->voronoi = voronoi;
this->width = voronoi.getSizeX();
this->height = voronoi.getSizeY();
int iterations = 0;
int maxIterations = 500;
int pathLength = 0;
path 的数据结构是vector .而pathLength = path.size() ,意味着pathLength 的意思就是path 中节点的数量. totalWeight计算公式中的变量都是超参数,是固定值.
- wSmoothness 0.2
- wCurvature 0
- wVoronoi 0
- wObstacle 0.2
pathLength = path.size();
std::vector<Node3D> newPath = path;
float totalWeight = wSmoothness + wCurvature + wVoronoi + wObstacle;
5.2.2 开始叠代优化
while (iterations < maxIterations) {
for (int i = 2; i < pathLength - 2; ++i) {
...}
iterations++;
}
(1)从第三个点开始选取,每次选5个
Vector2D xim2(newPath[i - 2].getX(), newPath[i - 2].getY());
Vector2D xim1(newPath[i - 1].getX(), newPath[i - 1].getY());
Vector2D xi(newPath[i].getX(), newPath[i].getY());
Vector2D xip1(newPath[i + 1].getX(), newPath[i + 1].getY());
Vector2D xip2(newPath[i + 2].getX(), newPath[i + 2].getY());
Vector2D correction;
(2)如果有尖角,则跳过该点
if (isCusp(newPath, i)) { continue; }
如下图所示,左2就是一个尖角.
(3)分别进行障碍物修正obstacleTerm ,平滑度修正smoothnessTerm 和曲线修正curvatureTerm 不断累加修正值correction ,并判断修正后的节点还是否位于地图以内.
correction = correction - obstacleTerm(xi);
if (!isOnGrid(xi + correction)) { continue; }
correction = correction - smoothnessTerm(xim2, xim1, xi, xip1, xip2);
if (!isOnGrid(xi + correction)) { continue; }
correction = correction - curvatureTerm(xim1, xi, xip1);
if (!isOnGrid(xi + correction)) { continue; }
(4)对xi 节点进行修正,并且对xi 节点前一个节点的角度进行修正setT
xi = xi + alpha * correction/totalWeight;
newPath[i].setX(xi.getX());
newPath[i].setY(xi.getY());
Vector2D Dxi = xi - xim1;
newPath[i - 1].setT(std::atan2(Dxi.getY(), Dxi.getX()));
|