主页传送门:📀 传送
主页传送门
感知开发流程
Apollo 自动驾驶感知的开发流程分为以下几个步骤:
- 模型训练
- 模型部署
- 测试和验证
环境要求
运行感知模块要求:
- 操作系统 ubuntu 18.04以上,
- 英伟达显卡。
满足环境要求之后,接下来我们详细介绍下这 3 个部分。
步骤一:模型训练
根据任务类型,例如 camera 感知、lidar 感知等,选择对应的模型,目前常见的 2d 图像目标识别模型有 YOLO, Faster-RCNN等,常见的Lidar目标识别模型有 Pointpillar 等,开发者根据自己的需要选择好对应的模型之后,可以用任意深度学习框架来训练模型,例如 paddlepaddle,pytorch,tensorflow 等。
Apollo 提供了基于 paddle3d
的预训练模型,根据公开数据集 nuscenes,KITTI,Waymo Open Dataset
等,提供state-of-art
的模型训练。
步骤二:模型部署
Apollo 中的感知任务,根据类型的不同分为红绿灯识别、车道线识别、3D 目标检测、目标跟踪、多传感器融合 等,每个任务实际上是一个任务流水线,分为几个步骤来完成,每个步骤称为一个 stage,每个 stage 中可以选择一个或者几个算法插件 (plugin),这样开发者可以根据自己需要开发新的 stage,或者沿用当前的任务流水线,替换不同的算法插件。
训练好的模型部署到 Apollo 感知模块,分为2种情况:
- 一种是针对已有模型,自己采集数据进行训练,或者进行兼容性的改动;
- 另一种是新增一种新的模型,并且部署到感知模块。
已有模型
如果是已有模型,可以根据不同的任务类型,以激光雷达感知任务为例,找到对应的任务流水线,查找到底是哪个阶段调用了深度学习模型,然后在对应的 Stage 中找到模型所在的目录,替换掉目录中的模型就可以了。激光雷达目标检测 point_pillars
模型的模型文件路径如下。
modules/perception/production/data/perception/lidar/models/detection/point_pillars
新增模型
如何添加 Lidar Detection模型:
- 添加模型文件。
将训练好的模型文件存放于modules/perception/production/data/perception/lidar/models/detection/xxx
目录下。 - 添加新的 Lidar Detector。
参考how_to_add_a_new_lidar_detector_algorithm,创建一个新的Lidar Detector。(访问不了的可以看这篇添加Lidar 算法) - 修改 Lidar Detector 以适配新的 Lidar Detection 模型。
- 创建并初始化 predictor。
新添加的 Detector 中的 init 函数主要用来对 predictor 进行配置并进行初始化,下面以CenterPointDetection::Init
为例进行说明,更具体请参考Paddle Inference C++ API
。
bool CenterPointDetection::Init(const LidarDetectorInitOptions &options) {
// 创建默认配置对象
paddle::AnalysisConfig config;
// 启用GPU
config.EnableUseGpu(1000, FLAGS_gpu_id);
// 设置预测模型路径
config.SetModel(FLAGS_center_point_model_file,
FLAGS_center_point_params_file);
// 是否开启TensorRT加速
if (FLAGS_use_trt) {
// 精度选择
paddle::AnalysisConfig::Precision precision;
if (FLAGS_trt_precision == 0) {
precision = paddle_infer::PrecisionType::kFloat32;
} else if (FLAGS_trt_precision == 1) {
precision = paddle_infer::PrecisionType::kHalf;
} else {
AERROR << "Tensorrt type can only support 0 or 1, but recieved is"
<< FLAGS_trt_precision << "\n";
return false;
}
config.EnableTensorRtEngine(1 << 30, 1, 3, precision, FLAGS_trt_use_static,
false);
// 载入动态shape文件
config.EnableTunedTensorRtDynamicShape(FLAGS_dynamic_shape_file, true);
// 是否使用反序列化
if (FLAGS_trt_use_static) {
config.SetOptimCacheDir(FLAGS_trt_static_dir);
}
}
// 是否开启IR优化
config.SwitchIrOptim(true);
// 创建predictor
predictor_ = paddle_infer::CreatePredictor(config);
return true;
}
- Detect() 函数的处理流程。
数据的预处理、推理、后处理、感知结果发布等流程都是在 Detect() 函数中实现的。获取点云数据的过程可以参考ceter_point_detector.cc 的 bool CenterPointDetection::Detect()
函数的流程即可。
- Detect() 函数包含了点云数据的预处理,前处理、推理、后处理、感知结果发布等流程。其中,点云数据的预处理主要包括
DownSample -> Fuse -> Shuffle
等流程,处理流程相对固定,通过CloudToArray()
函数,将预处理后的点云存储到了数组中,用户根据自己的模型需要,对存储到数组中的点云数据进行前处理即可。 - 后处理完成后,用户通过
GetObjects()
将目标级结果存储到 frame 中。用户需要确认自己模型输出的 3D bounding-box 的格式及顺序。
如何添加 Camera Detection 模型:
- 添加模型文件。
将训练好的模型文件存放于modules/perception/production/data/perception/camera/models/yolo_obstacle_detector/xxx
目录下。 - 添加新的Camera Detector。
参考 how_to_add_a_new_camera_detector_algorithm,创建一个新的Camera Detector。(访问不了的可以看这篇添加Camera算法) - 修改 Camera Detector 以适配新的 Camera Detection 模型。
- 根据模型结构修改对应的 proto 文件:Camera Detector 通过 blob 数据结构来管理和存储模型的输入和输出数据。用户需要根据模型结构,在该模型对应的 proto 文件中添加和对应的输入输出项,可参考
smoke.proto
文件的NetworkParam
字段,并添加对应的 proto 配置文件,参考smoke-config.pt
。 - 同 Lidar Detection 类似,Camera Detection 中的 Detect() 函数同样包含了图像数据的预处理,前处理、推理、后处理、感知结果发布等流程。通过
frame->data_provider->GetImage()
函数,用户可以获取图像数据,通过inference::ResizeGPU()
函数,可以对图像数据进行 resize 等预处理操作。 - 后处理完成后,用户需要根据模型的特点,将 2d bounding-box、3d bounding-box 存储到
std::vector<base::ObjectPtr>
结构中。具体可参考region_output.cc
中的get_smoke_objects_cpu
函数。
步骤三:测试和验证
模型部署完成之后,就可以通过播放 record 包的形式或者实际上车测试验证,推荐先播放 record 包进行测试,验证没有问题之后再进行实车的测试。
播放record包验证
本地启动 Apollo,进入 docker 之后,启动 perception 和 tf 模块,然后使用 cyber_record 播放 record 数据包,然后启动 cyber_monitor 查看感知检测结果的 topic 消息是否有输出。
如果喜欢的话,欢迎 🤞关注 👍点赞 💬评论 🤝收藏 🙌一起讨论 你的支持就是我✍️创作的动力! 💞💞💞