量产自动驾驶算法入门

做了调查大家对于自动驾驶入门的算法比较感兴趣那我专门讲下这一块,虽然目前还是有些新趋势的算法结构,但是思考一下,感觉基本功如果不扎实新算法也很难适应,所以还是回归基本算法,让大家能够比较舒适的入门。

自动驾驶软件相关的业务,驱动,标定,感知,融合,定位,地图,规划,控制。感知还要根据不同传感器分为激光,毫米波,超声波,视觉等。其他模块根据算法思路不同还要分深度学习派和传统算法派。不同算法派别根据具体算法细分还有很多知识点。

非常多,非常多的资料,教材这块各种学习平台,深蓝学院,udacity,知乎,b站,csdn,githib,论文网站,学习资料多到爆炸,因为非常多且任何一个子话题都有很深入的学习过程。所以迷茫是必然的

所以这个专题,我换一个思路来说自动驾驶的入门问题,讲一点共性的部分。核心不是说透一个算法,而是给大家一个牵引,不在这么多方向上迷失,不管你是想做自动驾驶的哪个方向,不管你是什么流派,这些工作大概率都绕不过去的,我们会优先进行罗列说明。如果已经有自己的功能方向了,就可以看下最后专业子领域需要关心的内容

一个问题对应一篇或者多篇文章,欢迎大家关注我的专栏,我会持续更新。

以下所有代码90%基于c++,10%涉及python,都在linux下,没win什么事,不要问问什么,行业就这样。或者看我其他回答。

top1-自动驾驶通识架构的理解

适用范围: 所有希望入门自动驾驶的工程师

自动驾驶的结构,我会在一些专门的回答里串行的再梳理下。首先说下重要性,不管你想学习哪个自动驾驶的功能模块的内容,或是自动驾驶云端的训练测试仿真模块,都需要对自动驾驶的整体有一个理解,这很重要,我一直强调"T"字形结构,如果没有这个意识,做单个功能模块可能会找不到这个模块的合理定位和分割面。相关的回答已经很多了,我这里罗列两个,有的大家可以先看起来。

https://zhuanlan.zhihu.com/p/264624915​zhuanlan.zhihu.com

传感器攻防战-一文汇总自动驾驶的那些传感器

https://zhuanlan.zhihu.com/p/258386315​zhuanlan.zhihu.com

软件定义汽车(1)-整车电子电气架构EEA

近两年,在自动驾驶领域有哪些技术进展?​www.zhihu.com

图标

无人驾驶,个人如何研究?​www.zhihu.com

图标

如果觉得这些信息还是不足以理解整个自动驾驶的技术栈,我会专门回答做一个串行的汇总,等我点时间,欢迎催更。开始下面讨论前,我这里写一段伪代码,大家可以通过这个代码大概理解整个自动驾驶的代码逻辑是如何的

====node1.cpp=====
init(){
m_config=LoadConfig("xxx/node1.config”);
m_fsm=LoadFiniteStateMachine();
//init some static variable..
}
step(){
m_timestamp=getCurrentTimeStamp();
m_msg1= recvmsg("CH1") //msg from node2.cpp
m_msg2= recvmsg("CH3") //msg from node3.cpp
m_var1=DoCalibration(m_msg1,m_timestamp);
// coordinate conversion and time sync
m_mid1=PreProc(m_var1,m_msg2); // msg preproc
m_fsm.Tick(); //status change
if(m_fsm.sts==1){
m_mid2=FilterMethod(m_mid1);//some filter method
m_mid3=AssociationMethod(m_mid2);
}
else if(m_fsm.sts==2){
m_mid3=DeepLearnMethod(m_mid1);
}
m_msg3=PostProc(m_mid3);
sendmsg("CH3",m_msg3) //send msg to node4.cpp
sendmsg("Monitor",m_msg3) //send msg to monitor.cpp
}
====node2.cpp=====
.......the same as the node1.cpp
====monitor.cpp=====
.......the same as the node1.cpp

任何机器人相关的代码,包括自动驾驶,不管你是使用apollo架构还是ROS2架构,或者量产的任何架构,都大致沿袭着这个结构模式,代码只是示意一个大致逻辑,为了尽可能精简并不严谨。大家看个大概。后面我会逐一介绍。

top2- 节点化,消息通讯模式与配置

适用范围: 所有希望入门类机器行业工程师

节点化这个概念很关键,不管你是通讯专业,车辆工程,计算计哪个专业出来的都必须理解节点化。

任何领域只要是机器人相关都应该知道的基本概念,节点化通俗的理解,你的一个完整应用会被剥离成“线程调度”和“算法功能”两个概念。如果你刚刚学会写代码,你会认为你要写这样的代码

void main(){
init();
while(1){
step();
sleep(1);
}

如果你学习了ROS等机器人架构,以及你量产中会碰到的基本上是

init(){
.....
}
step(){
.....
}
stop(){
....
}

形成节点化的思维很关键,原因有很多,模块化需求,面向SOA服务等等,核心再次强调是解耦了“线程调度”和“算法功能”两个概念。讨论调度是一个偏向硬件适配的概念,有串行,并行,动态的调度,具体再说。讨论算法功能,更多围绕软件概念展开,运行时长,最大运行时长,输入输出的通讯机制以及最重要的这个节点你核心希望实现什么逻辑或者功能。完整的应用是协调这两件事设计而成的结果,具体这里不展开,另外文章讨论。

好了调度我们不展开,这个是一个细分领域,你可以先简单理解为周期(100ms)被调用一次的程序。现在我们把目光聚焦在一个节点的输入输出上,这是实现一个功能的基本结构,有输入有输出,你就可以干活了。也就是如下部分。

init(){
m_config=LoadConfig("xxx/node1.config”);
}
step(){
m_msg1= recvmsg("CH1") //msg from node2.cpp
//do something from m_msg1 to m_msg3
sendmsg("Monitor",m_msg3) //send msg to monitor.cpp
}

输入输出有很多种模式,最简单的就是“配置”的输入,也就是一种节点启动后只加载一次的从文件输入到程序中的“通讯模式”。

配置的学习有很多种协议可以学习,比如protobuf,xml,json,yaml 各种协议适用场景不同,优缺点看需求,掌握他们的存储和读取是有意义的,也有一些像gflag的参数读取库可以学习使用,但这里强调最重要的部分是形成配置管理的思维,项目中很多初学算法的同学经常会这些技能,但就是爱在代码里直接写入一些参数,这种行为会给自己和别人后期带来非常多的麻烦。养成配置思维是工程化落地算法的基础。

具体还是专题文章展开(留空)

https://zhuanlan.zhihu.com/p/91313277​zhuanlan.zhihu.com

另外,在后期进行深度学习训练的过程中,这些配置技能也会被用于大规模深度学习样本数据的组织管理,比如protobuf(后面还有数据库)用处多多,所以想不明白也没关系,强迫自己学就是了。

接下来说正儿八经的聊“通讯模式”,学通讯专业的可能比较熟悉,但哪怕你不是这个专业,对通讯的理解也是了解自动驾驶的核心。通讯收到不同硬件通讯设备的约束(CAN,以太网,LVDS, 总线,共享内存等等),又需要满足不同的拓扑(单播,组播,广播,一对多,多对一,多对多),还要满足不用的特性(可靠通讯,低延时通讯,大带宽通讯)。可以用的第三方库从简单的到量产的(openDDS,zmq(zcm),lcm等等)。话题非常大,但是你可以简单的看这个问题,就是他为你的节点明确了输入的内容和节奏,明确了输出的内容和节奏,可以让你这个节点(应用)有效的支持更大功能的开发。这里还是会专题写文章进行讨论。

top3-状态机模式的开发

适应范围:所有自动驾驶软件工程师,特别是任务管理开发工程师或者软件架构工程师

说自动驾驶很少有人会谈状态机,但是我把他放top3是有原因的,任何自动驾驶的主模块(泊车,ACC,Pilot等核心L2-L4的应用)和子功能模块(涉及正常模式,失效模式,初始化模式A模式,B模式等),量产或是稍微复杂一点的时候,你基本逃不了各种状态和模式的切换问题。我发现初入自动驾驶的同学(甚至干了很多年的),面对这种问题,条件反射的会写出这种代码

if(status==1){
if(sub_status==2){
if(sub_sub_status==3){
}}}

按照“设计模式”要求,用这种多层if超过3层的,不用多解释,你一定需要切换为"状态机设计模式",别说用if else 能解决的为什么这么麻烦,做多了你就知道没有多少实际问题的是 if else可以解决的,学就是的,你会感谢我的。另外也别问我“这些是啥?和自动驾驶算法有什么关系?”如果工程都做不好,算法的复杂度你也一定hold不住,肯定的。

自动驾驶元老 Junior的规划子状态机

设计模式是一个写代码的大话题,其他模式你可以看看apollo的风格代码,虽然由于过于庞大,有些“过设计”我个人认为,但学习自动驾驶和设计模式的关系是不错的选择,你可以不掌握其他模式,但状态机模式请好好学学,可以让你换一个成熟的思维看待自动驾驶的工程问题。

这里还是强调“状态机思维”,如果你看到分场景分条件问题,你第一个想到用fsm来解决,而不是if else 你算真的入门了。这里状态机和自动驾驶的详细关系,还是专门文章解释。

这里为了方便大家学习,我比较了各种github上状态机的实现,我个人比较喜欢如下这个fsm作为入门,因为这个实现集成简单,架构扩展性强,它的示范样例是一个小游戏,我一看就懂了什么是状态机,以及它的关键概念,非常推荐,如果你已经熟悉状态机了,用什么就不重要,我还是说“状态机思维”“状态机设计模式”是最重要的。

https://github.com/r-lyeh-archived/fsm​github.com

top4-断点,监控,可视化,推向最终的功能安全思维

//恩,上班了,4-8下班了写

top5-多传感器时空同步与坐标系定义

 

top6-多种类型的滤波策略和最优化策略

 

top7-各种各样领域的评估函数

 

top8-聚类,数据关联与异常剔除

 

top9-数据驱动的思维(python数据分析,Docker,数据库与网络训练基础)

适用范围:扎实掌握以上8条,对算法有更高追求的工程师。

warning:最近在咨询中,我发现一些问题,由于深度学习非常火热,导致很多特别是跨专业且没有非常多相关经历的同学,可能为了获得更好的发展,全部投身深度学习领域。这是非常不理智的行为,真实情况往往反直觉,如果普通算法岗位是1比10的竞争,深度学习相关,可能是1比3000,但供需平衡下一方面考核会越发严格,可选岗位越发狭窄,另一方面薪资也会相对应降低,只有很少人可以获得非常好的收入。而很多不太被关心的领域比如地图,毫米波等往往能够获得性价比更好的工资。但是这么说也不是劝退,入门自动驾驶对这些概念有个10%的入门对未来发展也是非常好的,但前提是有一个夯实的基本工。只跑通一个网络就说会的,你在浪费自己时间。

深度学习如果你有5%的时间在调整网络,我认为已经算比例很高了,剩下的时间如果平台团队给力的,你可能在整理数据,写笔记,等数据出来。如果不靠谱的,你可能在纠结这么多外围工具的兼容问题。

我这里不想谈深度学习,这个我认为不是你的必备技能,我说说数据驱动,两者有什么区别,深度学习方法是实现数据驱动的方法之一,比如你觉得自己设置的车辆加速度很奇怪,你不是简单的选择拍脑袋再换个参数,而是采集了司机在加速时候产生的加速度并做了一些基本的分析,哪怕是excel,然后完善了自己的加速度设置,ok。你已经了解数据驱动的思维了。

数据驱动就是你在后台需要掌握的对数据的运维能力,包括数据的分析,数据的管理,工具组织等。

相比深度学习,掌握python,pandas这些数据分析工具,不仅是深度学习的基础,求职和解决问题的适用范围也更广泛一些,可以优先学习下,Docker+K8S估计做深度学习量产化的都知道,至少你必须掌握Docker,越早养成这个习惯,越早脱离反反复复的系统重装。具体回答里都有

无人驾驶,个人如何研究?​www.zhihu.com

图标

数据库也是除了计算机专业的一个一般学习盲区,数据库思维是配合着数据驱动思维才会变的有用的一种工具。可以入门学习的是sqlite(PYTHON内嵌)一般就满足要求了,大型数据库如果你不是专业DB,掌握不掌握也区别不大,自动驾驶领域用的比较多的是,MySql和PostgerSQL两种关系数据库 。还有一些非关系数据库redis(持久化缓存),mongodb(文档的数据库) 。专门文章介绍入门下sqlite。数据库不是一定要学,但学了数据库,你会对浩如烟海的数据管理有一个更清晰的认识,入门打开新世界还是很好地。

最后是深度学习基础入门,这个我不展开,也写了一个有趣的话题看能不能帮大家入门,但从这个专题角度出发我不推荐大家深入,不能贡献很大的成绩。很有价值但放最最后学习。先看个乐。

殷玮:深度学习入门(1)-我是一个渣男​zhuanlan.zhihu.com

最后总结下,掌握基本的数据分析和管理能力比深度学习的其他学习更为重要,有志于深度学习的,数据分析和管理的功底要打好。

top10-整车开发,软件开发,项目管理流程,你最不喜欢的那些XX流程

适用范围:参与中大型自动驾驶项目开发的工程师

可能车辆工程入门的还好一些,理解整车开发流程,但不太在乎软件开发流程,计算机专业的反过来,其他专业的估计就是蒙圈的状态。流程也算基本技能?算,流程的核心就是梳理人和人的关系问题,只要软件不是一个人写的,都会存在或大或小的流程。讲小了基本的ppt和技术演讲如果做不了,说明你对小块技术的理解并不到位,无法梳理到可以生动传达给别人的地步,说大了处理大块技术的组织问题时,你自己不写代码可以,但必须组织好很多人写代码,还要协调量产过程中的需求(整车开发流程),进度(项目管理流程)的关系问题。我放top10因为可能你自己搞搞可以绕过去,但是10%程度的掌握是每个工程师都需要具备的。

这里着重想谈下软件定义汽车以及功能安全全生命周期到底对自动驾驶研发和个人有什么关键性的影响,具体会在对应文章内展开(留白)。

文章转自https://zhuanlan.zhihu.com/p/266696464

posted @ 2021-01-19 15:40  半山半水  阅读(1325)  评论(0)    收藏  举报