各位读者朋友,大家好。本次打造的自动驾驶仿真系统,涉及感知,预测,规控等多个模块(以规控算法为主,包括Polynomial预测,MCTS决策算法,通行走廊Corridor构建,QP/CILQR轨迹生成求解器,LQR+PID的控制器等),同时也支持其它相关规控算法的扩展(部署&开发自身感兴趣的算法),非常便捷。笔者在该系列中开发的规控算法主要依据专栏《自动驾驶Planning决策规划》中的章节逐步搭建,后续实践系列涉及的博客包括但不局限于以下内容:
《自动驾驶---打造自动驾驶系统之环境准备(一)》---已更新
《自动驾驶---打造自动驾驶系统之定位模块开发(二)》---已更新
《自动驾驶---打造自动驾驶系统之导航模块开发(三)》---已更新
《自动驾驶---打造自动驾驶系统之参考线平滑(四)》---已更新
《自动驾驶---打造自动驾驶系统之感知环境开发(五)》---已更新
《自动驾驶---打造自动驾驶系统之预测模块开发(六)》---已更新
《自动驾驶---打造自动驾驶系统之决策模块开发(七)》
《自动驾驶---打造自动驾驶系统之轨迹生成模块开发(八) 》
《自动驾驶---打造自动驾驶系统之控制模块开发(九)》
最终呈现的静态效果(无法直接贴视频)如下:
1 系统环境
笔者的环境是:Ubuntu 18.04 + ROS Melodic,当然18.04以上的环境也支持。
其它依赖库的安装参考之前的博客《自动驾驶---打造自动驾驶系统之环境准备(一)》,后续如果有遗漏,继续补充。
当然,如果各位读者朋友感兴趣或者在此过程中遇到相关问题,欢迎私信咨询!
2 决策模块
关于决策,笔者在之前的专栏中也详细介绍过多种方法:
《自动驾驶---Behavior Planning之MCTS》
《自动驾驶---Behavior Planning之EUDM》
本次主要介绍蒙特卡洛树搜索(MCTS)方法,算法详细介绍请参考上述博客。整体MCTS算法过程如下图所示,MCTS算法包含的4个主要步骤:
(1)Selection,选择合适的叶子节点进行进一步扩展;
(2)Expansion,针对选定的叶子节点进行搜索树扩展;
(3)Rollout(MCTS原文中使用的是Simulation,两者所表达的意思是一样的),推演该节点,直到终点或者其它条件退出;
(4)Backpropagation,基于将评估结果通过回溯更新整个蒙特卡洛搜索树。
示例代码:
// Define structures for Node and other necessary data types
struct MCTSNode {
std::vector<double> state;
double time;
int children;
int visits;
...
};
// selection function
MCTSNode* selection(MCTSNode* root) {
MCTSNode* currentNode = root;
while (!currentNode->children.empty()) {
double bestUCB = -std::numeric_limits<double>::max();
MCTSNode* bestChild = nullptr;
...
...
currentNode = bestChild;
}
return currentNode;
}
通过决策算法,可以直接生成一条粗糙的轨迹,是由算法中的Tree Node构成,后续可以通过平滑得到质量更好的轨迹,如下图所示。
3 量产
在量产当中,通过决策信息,不同的公司处理方式有两类,可参考笔者之前的博客《自动驾驶---Motion Planning之轨迹Path优化》《自动驾驶---Motion Planning之轨迹Speed优化》《自动驾驶---“火热的”时空联合规划》《自动驾驶---用于运动规划的CILQR求解器》,具体实施方案如下:
(1)通过决策的粗糙轨迹可以对障碍物打上决策的标签,常见的决策标签包括如下几类
- 跟车Follow
- 超车Lead
- 左侧绕行Keep Left
- 右侧绕行keep Right
- 刹车 Yield
对于每一个障碍物,如果有标签,后续可以构建可行驶空间,生成path boundary和speed boundary,后续构建二次规划问题求解即可得到最终的轨迹。
(2)通过决策的粗糙轨迹直接进行优化平滑,作为最终的行车轨迹
该方案存在的风险点在于,决策采样的轨迹,有的时候会发生跳变,不稳定,直接导致轨迹跳变,影响体感,但可以把上一帧的轨迹权重放到当前帧来优化,尽量减少轨迹的跳变。
常见的平滑算法包括:
- QP平滑(横纵分离优化)
- CILQR平滑(横纵联合优化)