【Apollo源码分析】系列的第五部分【localization】
localization 是车辆 定位模块,是自动驾驶的核心模块之一。
目前Apollo的定位模块大概有1000行代码。
localization的输入:
- GPS全球信号
- IMU惯性测量单元信号
localization的输出:
- 由localization/proto/localization.proto文件描述的LocalizationEstimate定位信息
目前Apollo 1.0采用的是 RTK-GPS定位法。
RTK-GPS定位法:
- RTK(Real - time kinematic)载波相位差分技术,是实时处理两个测量站载波相位观测量的差分方法,将基准站采集的载波相位发给用户接收机,进行求差解算坐标。这是一种新的常用的GPS测量方法,以前的静态、快速静态、动态测量都需要事后进行解算才能获得厘米级的精度,而RTK是能够在野外实时得到厘米级定位精度的测量方法,它采用了载波相位动态实时差分方法,是GPS应用的重大里程碑,它的出现为工程放样、地形测图,各种控制测量带来了新曙光,极大地提高了外业作业效率。
- 高精度的GPS测量必须采用载波相位观测值,RTK定位技术就是基于载波相位观测值的实时动态定位技术,它能够实时地提供测站点在指定坐标系中的三维定位结果,并达到厘米级精度。在RTK作业模式下,基准站通过数据链将其观测值和测站坐标信息一起传送给流动站。流动站不仅通过数据链接收来自基准站的数据,还要采集GPS观测数据,并在系统内组成差分观测值进行实时处理,同时给出厘米级定位结果,历时不足一秒钟。流动站可处于静止状态,也可处于运动状态;可在固定点上先进行初始化后再进入动态作业,也可在动态条件下直接开机,并在动态环境下完成整周模糊度的搜索求解。在整周未知数解固定后,即可进行每个历元的实时处理,只要能保持四颗以上卫星相位观测值的跟踪和必要的几何图形,则流动站可随时给出厘米级定位结果。
GPS-RTK 至少有一个基准站接收机,一个流动站接收机。
基准站的接收机有两个任务:
- 1)接收卫星信号
- 2)把自己的观测量通过发送给流动站
流动站有三个任务:
- 1)接收卫星信号
- 2)接收基准站所发送的基准站观测量
- 3)对卫星信号与基准站观测量进行对比处理,从而对自己的观测量进行修正
关于RTK-GPS可以参阅:
[1]https://en.wikipedia.org/wiki/Real_Time_Kinematic
[2]https://baike.baidu.com/item/RTK
[3]https://www.zhihu.com/question/24471733/answer/28676022
[4]http://www.sbsm.gov.cn/article/zszygx/chzs/chkp/ddcl/200912/20091200059052.shtml
localization/main.cc
照例先看看 localization文件夹下面最重要的文件main.cc 写了什么:
#include "modules/common/apollo_app.h"
#include "modules/localization/localization.h"
APOLLO_MAIN(::apollo::localization::Localization)
结合common/apollo_app.h文件,上述代码一看便知是用于注册localization模块,并运行本模块。而本文件没有重写ApolloApp类就不能实例化,那么只能是localization.h文件重写了ApolloApp类。
localization/localization.h
class Localization : public apollo::common::ApolloApp
果然,Localization类继承了ApolloApp类,并重写了父类的纯虚函数接口。
重写的接口有:
std::string Name() const override;
模块名称
apollo::common::Status Init() override;
初始化步骤
apollo::common::Status Start() override;
模块执行内容
void Stop() override;
模块清理内容
以上全都是public访问权限。
本模块独有的 private函数有:
void RegisterLocalizationMethods();
工厂函数。注册RTK定位实例和CAMERA定位实例。
再看看localization.cc.cc文件源码:
std::string Localization::Name() const {
return FLAGS_localization_module_name;//模块名称
}
void Localization::RegisterLocalizationMethods() {
localization_factory_.Register(//工厂函数。注册RTK定位方法的实例。
LocalizationConfig::RTK,
[]() -> LocalizationBase* { return new RTKLocalization(); });
localization_factory_.Register(
LocalizationConfig::CAMERA,//工厂函数。注册CAMERA定位方法实例。
[]() -> LocalizationBase* { return new CameraLocalization(); });
}
Status Localization::Init() { //初始化操作,包括获取配置文件信息+注册定位方法实例
RegisterLocalizationMethods();
if (!apollo::common::util::GetProtoFromFile(FLAGS_localization_config_file,
&config_)) {
AERROR << "failed to load localization config file "
<< FLAGS_localization_config_file;
return Status(ErrorCode::LOCALIZATION_ERROR,
"failed to load localization config file: " +
FLAGS_localization_config_file);
}
return Status::OK();
}
Status L