还是以这张图开始介绍吧。
之所以拿这张图看,主要我觉得它能够把复杂的apollo架构简单简明化,途中的箭头表示数据流动的方向,从图中不难发现,定位模块是基础,提供了高精地图,而且重要的是图中其他的模块都需要这个地图数据,因此我们就很清楚其重要性了。canbus是基于can总线通往下层控制器的,而perception是获取车上如lidar,radar,camera等传感器数据的模块,这两个模块都需要直接和相关的硬件配合才能工作。那另外四个(prediction,routing,planning,control)就是中间模块,进行数据处理,相关功能的实现。
以上是我自己进行的很不严格的分类,主要是因为我在学习过程中,还没有用外部硬件,所以现在就对中间的模块先下手吧。实际上当你多看几个模块后发现,中间的代码流程是及其相似的,几乎如出一辙,今天就从control总结吧。在介绍control前,还有一个需要说明下,apollo的每个模块都会用到common模块,common是一些基本的定义和实现,这里我就不写了,如果没看过的请尽量自己先去学习一下,相关博客已经有人写过了。包括下面所介绍的也默认读者对上一篇博客所提到的工具已经有所掌握了。
好了,言归正传,下面开始control的介绍。我用的apollo1.5版本源码,现在已经公开了2.0版本。control模块的功能代码中也有说明:功能为输入localization,chasiss和pad数据,来计算节气门,刹车和方向盘控制命令。
main.cc——进入模块 control。
#include "modules/common/apollo_app.h"
#include "modules/control/common/control_gflags.h"
#include "modules/control/control.h"
APOLLO_MAIN(apollo::control::Control);
很简单,仅仅调用了一个宏APOLLO_MAIN, 是common下在apollo_app.h文件中定义的,传入了Control类。从下图看到,传入的APP类型将用于后面模块的实例化,可以说是开辟新模块的接口。
#define APOLLO_MAIN(APP) \
int main(int argc, char **argv) { \
google::InitGoogleLogging(argv[0]); \
google::ParseCommandLineFlags(&argc, &argv, true); \
signal(SIGINT, apollo::common::apollo_app_sigint_handler); \
APP apollo_app_; \ //实例化
ros::init(argc, argv, apollo_app_.Name()); \ //注册节点
apollo_app_.Spin(); \
return 0;