Apollo 5.0源码学习笔记(一)| 感知模块 | 感知框架总览
Apollo 5.0 感知模块
新特征: 在线传感器标定服务、手动相机标定、CIPO目标检测、灭点检测。
大体上包括:
3D障碍物感知:
主要有是三个主要部分提供3D障碍物感知:lidar、radar和fusion模块。
Radar感知:
Obstacle Results Fusion:
用来融合lidar和radar的检测结果。
融合中有publish-sensor
的概念,apollo中publish-sensor
是lidar,即对radar结果进行缓存,lidar结果用来触发融合动作,因此融合输出频率等于publish-sensor的频率。Apollo保留所有传感器结果,每个融合目标丢失存活时间根据传感器不同,一个目标必须至少有一个传感器结果存活。Apollo在近距离里提供lidar和radar的融合结果,在远距离只有radar结果。
传感器结果到融合序列关联: 传感器目标与融合目标进行匹配时,首先匹配相同传感器相同的跟踪ID,然后建立二分图,对没有匹配上的那些结果进行匈牙利匹配,距离损失矩阵是通过计算anchor点的欧氏距离完成。
Motion Fusion: 使用基于自适应卡尔曼滤波的CA模型做运动估计,运动状态量包括anchor point位置、速度和加速度。在激光跟踪和radar检测中提供位置和速度的不确定性,将所有的这些状态和不确定量输入给自适应卡尔曼滤波,来得到融合结果。滤波过程使用击穿阈值来抵消更新增益的过估计。
工厂模式分析
Apollo感知模块中因为考虑到接口的统一性和实现的方便,使用了大量的工厂模式方法来对基类进行定义,方便根据配置参数来选择实例化不同的类,从而完成不同的功能类组合。
lib/registerer
路径下定义了工厂模式:ObjectFactory
类定义为没有拷贝和赋值的类,包含一个NewInstance
的公有函数:
class ObjectFactory {
public:
ObjectFactory() {}
virtual ~ObjectFactory() {}
virtual Any NewInstance() { return Any(); }
ObjectFactory(const ObjectFactory &) = delete;
ObjectFactory &operator=(const ObjectFactory &) = delete;
private:
};
例如radar/lib/interface/base_tracker.h
中基类BaseTracker类最后定义:
PERCEPTION_REGISTER_REGISTERER(BaseTracker);
#define PERCEPTION_REGISTER_TRACKER(name) \
PERCEPTION_REGISTER_CLASS(BaseTracker, name)
则会利用PERCEPTION_REGISTER_REGISTERER
宏定义一个BaseTrackerRegisterer
类,该类定义了很多静态公有函数,主要经常用到的是GetInstanceByName
函数,可以用来查询已经注册的哪些跟踪算法类,从而构造一个实例;
而PERCEPTION_REGISTER_TRACKER
宏能够在匿名命名空间下定义一个ObjectFactory##name
的类,该类继承自ObjectFactory
类,并且重载了函数NewInstance
,使得函数返回Any(new name())
,即构造了这个name
类的一个实例。
例如定义在radar/lib/tracker/conti_ars_tracker
下的ContiArsTracker
类,继承自BaseTracker
类,它的cpp文件最后调用了PERCEPTION_REGISTER_TRACKER(ContiArsTracker)
,从而会定义一个ObjectFactoryContiArsTracker
类。
感知模块参数配置
Apollo通过定义在modules/perception/lib/config_manager/config_manager.h
下的ConfigManager
单例模式类来进行参数配置,配置参数定义格式在:modules/perception/proto/perception_config_schema.proto
中定义,所有实际使用的配置参数实现都在modules/perception/production
文件夹下,由config_manager.config
文件定义。
所有ConfigManager
类中保存了perception_config_schema.proto中定义的每个ModelConfigProto
,以一个std::map<std::string, ModelConfig *> model_config_map_
类型变量存储所有配置参数,各个子模块的类都是通过lib::ConfigManager::Instance()->GetModelConfig
函数指定model_name(其实一般就是类名)
来载入某个类所需要的配置参数,其实也就是从production
路径下的conf文件夹中对应子模块文件夹下的modules
中的conf文件中载入对应参数。
上一篇: Javascript贪吃蛇
下一篇: openpyxl的一些常用代码