本系列博客旨在记录自己在学习百度无人驾驶开源框架Apollo的心得和体会,欢迎大家阅读和点赞,并提出宝贵意见,大家相互学习,如需转载,请注明出处,谢谢!

电脑配置说明

为了顺利编译和运行Apollo 5.0和Apollo 5.5,主要对你电脑的内存和硬盘提出了需求。

官方建议的最小内存是6G,其实在编译脚本apollo.sh里检查的最小内存是2G,也就是说如果你电脑的内存小于2G就不会编译(应该不会有人拿2G内存的电脑来玩Apollo吧。。。),当然内存肯定是越大越好。 如果内存比较小,可以通过-j N减少并行编译线程数来减少编译时的资源占用,但是编译时间会变长。

另外就是硬盘存储空间, 硬盘大约需要40G左右,当然也是越多越好。 占用存储空间的主要有以下几个部分:
代码:不算很大,1G多点;
Docker镜像:这个比较大,默认占用根分区,而且会根据更新次数,使用次数增加,增长会比较快;
编译输出:编译后产生,大小相对固定(也比较大),占用用户主目录空间,主要存储在/home/<user_name>/.cache/bazel目录下;

为了让大家有一个参考,下面我列出我成功编译安装Apollo 5.0Apollo 5.5的电脑配置:

  • 系统:Ubuntu 18.04
  • 内存:16G
  • 硬盘:128G SSD
  • 显卡:Nvidia RTX 2070 Super 8G显存
  • 显卡驱动:430.50
  • cuda版本:10.1

Apollo 5.5编译安装步骤

1、显卡驱动和cuda安装

Apollo中感知模块使用了深度学习,需要用到显卡驱动和cuda库,并且Apollo要求显卡驱动版本在410以上,cuda版本在10.0以上。

此部分可以参考我的另一篇博客:Ubuntu18.04 RTX2070 显卡驱动、Cuda、cudnn和Pytorch深度学习环境配置

我最终是安装了430.50版本显卡驱动和10.1版本的cuda,别忘了cudnn也要安装。安装完成后使用nvidia-smi测试:

$ nvidia-smi 
Sun May 10 15:57:14 2020       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 430.50       Driver Version: 430.50       CUDA Version: 10.1     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce RTX 2070    Off  | 00000000:01:00.0  On |                  N/A |
|  0%   49C    P8    32W / 175W |   1353MiB /  7979MiB |      9%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      1433      G   /usr/lib/xorg/Xorg                            24MiB |
|    0      1541      G   /usr/bin/gnome-shell                          83MiB |
|    0      2445      G   /usr/lib/xorg/Xorg                           469MiB |
|    0      2611      G   /usr/bin/gnome-shell                         568MiB |
+-----------------------------------------------------------------------------+

2、docker-ce和nvidia-docker安装1

由于无人驾驶软件系统的复杂性,Apollo项目从一开始就利用Docker作为代码运行的配置环境,你可以将Docker当做是一种轻量化的虚拟机。

虚拟机是干什么的?虚拟机可以让你在Windows系统下像安装Office等普通软件一样安装Ubuntu等各种操作系统,这样你就可以不用头疼的装双系统就可以享受到同时使用多系统的快感。由于虚拟机是完全“虚拟”了一个全新的系统,包括硬件、软件等层面的抽象,导致虚拟机的启动、关闭都耗时较长。

而Docker则是另一种对系统的抽象,其提出了“容器”的思想,容器可以认为是一种“沙盒”,在这个容器中配置的所有环境都只会影响和保存在该容器中,容器由镜像创建而来,镜像与容器的关系类似C++中类和对象的关系,镜像可以创建多个容器,容器之间相互独立,互不影响。

对于Apollo项目来说,你只需要知道Apollo创建了一系列镜像,其中包含了所有用于编译和运行Apollo代码需要的配置环境,这样你就只需要在你的电脑上安装好Docker,然后下载Apollo提供的Docker镜像,就相当于配置好了Apollo代码编译所需的环境,是不是很酸爽~

另外,因为容器是一个独立于系统的另一个环境,为了能够在Docker中也能够使用GPU资源,我们还需要安装nvidia-docker

安装步骤

进入到下载好的apollo-5.5.0/docker/setup_host路径下,执行:

bash install_docker.sh
bash install_nvidia_docker.sh

其中安装nvidia-docker可能会有些警告,我没管,后面好像也能用。

安装完成后需要重启下电脑,否则执行docker的一些命令需要加sudo

测试

终端输入:

$docker -v
$nvidia-docker -v

得到类似结果(两个命令结果相同):

Docker version 19.03.8, build afacb8b7f0

成功。

3、Apollo镜像安装

在安装完Docker之后,如果你执行docker images你会发现此时Docker中还没有安装任何镜像。所以接下来我们需要安装Apollo 5.5所需的镜像文件:

进入到Apollo源码根目录,运行:

bash docker/scripts/dev_start.sh     //启动container

然后就是一段漫长的等待。。。,最好有一个比较稳定、速度较快的网络,并且建议你参考网上给你的Docker配置一个阿里云镜像加速源,这样下载速度会快很多。

成功之后会给出提示:

[INFO] Starting docker container "apollo_dev_zhanghm" ...
[WARNING] nvidia-docker is in deprecation!
[WARNING] Please install latest docker and nvidia-container-toolkit: https://github.com/NVIDIA/nvidia-docker/blob/master/README.md
++ local_volumes
++ set +x
+ nvidia-docker run -it -d --privileged --name apollo_dev_zhanghm --volumes-from apollo_map_volume-sunnyvale_big_loop_zhanghm --volumes-from apollo_map_volume-sunnyvale_loop_zhanghm --volumes-from apollo_map_volume-sunnyvale_with_two_offices_zhanghm --volumes-from apollo_map_volume-san_mateo_zhanghm --volumes-from apollo_yolo3d_volume_zhanghm --volumes-from apollo_localization_volume_zhanghm --volumes-from apollo_paddlepaddle_volume_zhanghm --volumes-from apollo_local_third_party_volume_zhanghm -e DISPLAY=:1 -e DOCKER_USER=zhanghm -e USER=zhanghm -e DOCKER_USER_ID=1000 -e DOCKER_GRP=zhanghm -e DOCKER_GRP_ID=1000 -e DOCKER_IMG=apolloauto/apollo:dev-18.04-x86_64-20191111_1530 -e USE_GPU=1 -e NVIDIA_VISIBLE_DEVICES=all -e NVIDIA_DRIVER_CAPABILITIES=compute,video,graphics,utility -v /home/zhanghm/Apollo_Auto/apollo-5.5.0:/apollo -v /home/zhanghm/.cache:/home/zhanghm/.cache -v /dev:/dev -v /media:/media -v /tmp/.X11-unix:/tmp/.X11-unix:rw -v /etc/localtime:/etc/localtime:ro -v /usr/src:/usr/src -v /lib/modules:/lib/modules --net host -w /apollo --add-host in_dev_docker:127.0.0.1 --add-host zhanghm-PC:127.0.0.1 --hostname in_dev_docker --shm-size 2G --pid=host -v /dev/null:/dev/raw1394 apolloauto/apollo:dev-18.04-x86_64-20191111_1530 /bin/bash
f9820e77c5a0d35858689f0b35f917ad55f9641b4884a47e25747c873c10b412
+ '[' 0 -ne 0 ']'
+ set +x
Adding group `zhanghm' (GID 1000) ...
Done.
Adding user `zhanghm' ...
Adding new user `zhanghm' (1000) with group `zhanghm' ...
The home directory `/home/zhanghm' already exists.  Not copying from `/etc/skel'.
[ OK ] Finished setting up Apollo docker environment. Now you can enter with: 
bash docker/scripts/dev_into.sh
[ OK ] Enjoy!

上述命令会首先下载所需要的所有镜像文件,并启动Docker镜像容器,命令执行完成后,你可以运行docker ps查看此时正在运行的容器:

CONTAINER ID        IMAGE                                                            COMMAND             CREATED              STATUS              PORTS               NAMES
04b2298cc6a8        apolloauto/apollo:dev-18.04-x86_64-20191111_1530                 "/bin/bash"         13 seconds ago       Up 10 seconds                           apollo_dev_zhanghm
1a7d24011b9c        apolloauto/apollo:local_third_party_volume-x86_64-latest         "/bin/sh"           13 seconds ago       Up 13 seconds                           apollo_local_third_party_volume_zhanghm
199394af8180        apolloauto/apollo:paddlepaddle_volume-x86_64-2.0.0               "/bin/sh"           22 seconds ago       Up 17 seconds                           apollo_paddlepaddle_volume_zhanghm
c6496d4db13d        apolloauto/apollo:localization_volume-x86_64-latest              "/bin/sh"           28 seconds ago       Up 27 seconds                           apollo_localization_volume_zhanghm
4797035a3d03        apolloauto/apollo:yolo3d_volume-x86_64-latest                    "/bin/sh"           33 seconds ago       Up 31 seconds                           apollo_yolo3d_volume_zhanghm
25bb687d33e4        apolloauto/apollo:map_volume-san_mateo-latest                    "/bin/sh"           39 seconds ago       Up 37 seconds                           apollo_map_volume-san_mateo_zhanghm
62d7e6309445        apolloauto/apollo:map_volume-sunnyvale_with_two_offices-latest   "/bin/sh"           48 seconds ago       Up 44 seconds                           apollo_map_volume-sunnyvale_with_two_offices_zhanghm
dda6a5b7f5f7        apolloauto/apollo:map_volume-sunnyvale_loop-latest               "/bin/bash"         55 seconds ago       Up 51 seconds                           apollo_map_volume-sunnyvale_loop_zhanghm
7264dc9a05dd        apolloauto/apollo:map_volume-sunnyvale_big_loop-latest           "/bin/sh"           About a minute ago   Up 59 seconds                           apollo_map_volume-sunnyvale_big_loop_zhanghm

参考:
Unbun16.04+Apolo5.0安装编译

4、源码编译

终于配置好环境到了关键的源码编译环节了,这也是最容易出各种错误的步骤。

首先我们需要启动容器:

bash docker/scripts/dev_start.sh     //启动container

然后进入到容器中:

bash docker/scripts/dev_into.sh      //进入container

此时你的终端路径会发生变化:
在这里插入图片描述
这就表明你已经在容器环境内了,该容器挂载了你的源码路径在容器中的/apollo路径下,所以你可以在主机中修改源码,在容器环境中对源码进行编译。

开始编译:

确保你已经在容器中,此时执行以下命令开始编译:

bash apollo.sh build    (要求电脑配置比较高)
或  bash apollo.sh build --local_resources 2048,1.0,1.0(我用的是这个,怕自己电脑编译卡死)

编译报错解决

错误1:

zhanghm@in_dev_docker:/apollo$ bash apollo.sh build --local_resources 2048,1.0,1.0
System check passed. Build continue ...
[WARNING] ESD CAN library supplied by ESD Electronics does not exist. If you need ESD CAN, please refer to third_party/can_card_library/esd_can/README.md.
Running build under GPU mode. GPU is required to run the build.
[INFO] Start building, please wait ...
INFO: Reading 'startup' options from /apollo/tools/bazel.rc: --batch_cpu_scheduling --host_jvm_args=-XX:-UseParallelGC
Extracting Bazel installation...
......
____Loading package: modules/perception/fusion/lib/data_fusion/shape_fusion/pbf_shape_fusion
____Loading package: modules/drivers/tools/image_decompress/proto
____Loading package: modules/planning/common/trajectory1d
____Loading package: modules/perception/camera/common/proto
____Loading package: modules/transform
____Loading package: modules/perception/camera/lib/obstacle/postprocessor/location_refiner
____Loading package: modules/perception/common/i_lib/algorithm
____Loading package: modules/planning/tasks/deciders/path_assessment_decider
____Loading package: modules/localization/msf/common/util
____Loading package: cyber/timer
____Loading package: cyber/node
[INFO] Building on x86_64...
[INFO] Building with --jobs=12 --ram_utilization_factor 80 for x86_64
INFO: Reading 'startup' options from /apollo/tools/bazel.rc: --batch_cpu_scheduling --host_jvm_args=-XX:-UseParallelGC
ERROR: (04-27 14:09:50.221) /apollo/modules/planning/tasks/deciders/rss_decider/BUILD:5:1: no such package '@ad_rss_lib//': Error cloning repository: Premature EOF caused by Premature EOF caused by Premature EOF and referenced by '//modules/planning/tasks/deciders/rss_decider:rss_decider'.
ERROR: (04-27 14:09:50.310) Analysis of target '//modules/planning:libplanning_component.so' failed; build aborted.
INFO: (04-27 14:09:50.311) Elapsed time: 3298.412s
============================
[ERROR] Build failed!
[INFO] Took 3305 seconds
============================

解决方案:
网络良好的时候再次编译,或参考:
https://blog.csdn.net/lo_bamboo/article/details/105214674
https://github.com/ApolloAuto/apollo/issues/9219

错误2:

ERROR: (05-12 13:30:49.332) /home/zhanghm/.cache/bazel/_bazel_zhanghm/540135163923dd7d5820f3ee4b306b32/external/com_github_grpc_grpc/BUILD:388:1: C++ compilation of rule '@com_github_grpc_grpc//:grpc_plugin_support' failed (Exit 1).
In file included from external/com_github_grpc_grpc/src/compiler/php_generator.cc:24:0:
external/com_github_grpc_grpc/src/compiler/php_generator_helpers.h: In function 'grpc::string grpc_php_generator::GetPHPServiceFilename(const FileDescriptor*, const ServiceDescriptor*, const string&)':
external/com_github_grpc_grpc/src/compiler/php_generator_helpers.h:51:23: error: 'const class google::protobuf::FileOptions' has no member named 'has_php_namespace'
   if (file->options().has_php_namespace()) {
                       ^
external/com_github_grpc_grpc/src/compiler/php_generator_helpers.h:52:39: error: 'const class google::protobuf::FileOptions' has no member named 'php_namespace'
     oss << ReplaceAll(file->options().php_namespace(), "\\", "/");
                                       ^
external/com_github_grpc_grpc/src/compiler/php_generator.cc: At global scope:
external/com_github_grpc_grpc/src/compiler/php_generator.cc:26:40: error: 'google::protobuf::compiler::php::GeneratedClassName' has not been declared
 using google::protobuf::compiler::php::GeneratedClassName;
                                        ^
external/com_github_grpc_grpc/src/compiler/php_generator.cc: In function 'grpc::string grpc_php_generator::{anonymous}::PackageName(const FileDescriptor*)':
external/com_github_grpc_grpc/src/compiler/php_generator.cc:49:23: error: 'const class google::protobuf::FileOptions' has no member named 'has_php_namespace'
   if (file->options().has_php_namespace()) {
                       ^
external/com_github_grpc_grpc/src/compiler/php_generator.cc:50:28: error: 'const class google::protobuf::FileOptions' has no member named 'php_namespace'
     return file->options().php_namespace();
                            ^
external/com_github_grpc_grpc/src/compiler/php_generator.cc: In function 'void grpc_php_generator::{anonymous}::PrintMethod(const MethodDescriptor*, grpc::protobuf::io::Printer*)':
external/com_github_grpc_grpc/src/compiler/php_generator.cc:74:58: error: 'GeneratedClassName' was not declared in this scope
       MessageIdentifierName(GeneratedClassName(input_type), input_type->file());
                                                          ^
external/com_github_grpc_grpc/src/compiler/php_generator.cc: In function 'grpc::string grpc_php_generator::{anonymous}::PackageName(const FileDescriptor*)':
external/com_github_grpc_grpc/src/compiler/php_generator.cc:54:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
INFO: (05-12 13:30:49.752) Elapsed time: 5.793s, Critical Path: 0.62s
============================
[ERROR] Build failed!
[INFO] Took 5 seconds
============================

解决方案:
删除掉编译产生的缓存文件(docker中):

sudo rm -rf /home/<username>/.cache

错误3:
提示ad-rss-lib库下载不下来,或者ad-rss-lib库下载很慢,或者其他与这个库相关的问题。

解决方案:
自己下载好这个库,下载地址,下载之后解压缩放在Apollo代码库下的tmp目录下(自己新建一个);
然后修改Apollo代码库中的WORKSPACE.in,将原来的:

#ad-rss-lib
#new_git_repository(
#    name = "ad_rss_lib",
#   build_file = "third_party/rss_lib.BUILD",
#    tag = "v1.1.0",
#   remote = "https://github.com/intel/ad-rss-lib",
#)

注释掉,然后加上:

new_local_repository(
    name = "ad_rss_lib",
    build_file = "third_party/rss_lib.BUILD",
    path = "/apollo/tmp/ad-rss-lib-1.1.0",
)

其中path路径指向的是你解压之后的ad-rss-lib-1.1.0文件夹路径。

编译结果文件存储位置及清理

编译产生的结果模块存储在$HOME/.cache/bazel路径下。

如果你想清理编译产生的文件,方法是在docker终端内执行:

bash apollo.sh cyber_clean

编译cyber_visualizer方法

cyber_visualizer定义在modules/tool/visualizer路径下,其是用Qt编写的一个类似ROS下的RViz的可视化界面,但还没有RViz那么强大,目前只可以用来订阅点云和图像消息,并进行可视化,其整体界面如下图所示:
在这里插入图片描述
Apollo 5.5默认没有编译cyber_visualizer,因此需要对源码做一些修改才使其能够成功编译:
1、修改docker/scripts/dev_start.shLine367
原来是:

-e NVIDIA_DRIVER_CAPABILITIES=compute,video,utility \

加上graphics选项得到:

-e NVIDIA_DRIVER_CAPABILITIES=compute,video,graphics,utility \

2、修改apollo.sh脚本Line123
原来是:

BUILD_TARGETS=`bazel query //modules/... union //cyber/... except //modules/tools/visualizer/... except //modules/v2x/... except //modules/map/tools/map_datachecker/... $DISABLE_CYBER_MODULES`

去掉其中的except //modules/tools/visualizer/...得到:

BUILD_TARGETS=`bazel query //modules/... union //cyber/... except //modules/v2x/... except //modules/map/tools/map_datachecker/... $DISABLE_CYBER_MODULES`

完成以上两处修改后,再执行:

bash docker/scripts/dev_start.sh     //启动container
bash docker/scripts/dev_into.sh      //进入container

进入到容器中,进行第三步:
3、安装一些qt5-default依赖

sudo apt-get update #如果有些报错没关系,只要下一步的qt5-default能安装上就行
sudo apt-get install qt5-default

4、重新编译Apollo 5.5

bash apollo.sh build

如果你之前已经编译过,现在是新增加编译cyber_visualizer,编译并不会耗时很长的。

编译成功后,在容器中就可以执行cyber_visualizer打开上面的界面了。

此时如果你播包:

cyber_recorder play -f apollo_2.0_camera_sample.record -l

cyber_visualizer界面上点击Show PointCloud,选择对应的ChannelName,点击Play,就可以成功看到最终的点云了。
在这里插入图片描述
注意上述播放的包并不是Apollo官方提供的record数据包,官方提供的demo_3.5.record中并没有点云数据,这是我用Apollo 5.0的modules/data/tools下的rosbag_to_record工具对Apollo 2.0中提供的apollo_2.0_camera_sample.bag进行转换得到的,大家可以直接从我的百度云盘下载转换后的数据包:
链接: https://pan.baidu.com/s/17S6mqFq8CMN-o6K3NsoiQg
提取码: 7wxf

该数据包里包含的所有话题为:
在这里插入图片描述
参考:
[1] 编译cyber_visualizer

5、开始运行

如果你是按照以上的步骤到这一步的,你只需要在Apollo源码根目录下执行:

bash scripts/bootstrap.sh

如果你已经编译运行过Apollo代码了,以后每次想要运行,只需要在Apollo源码根目录下依次执行:

bash docker/scripts/dev_start.sh     //启动container
bash docker/scripts/dev_into.sh      //进入container
bash scripts/bootstrap.sh

其中bash docker/scripts/dev_start.sh命令会依次检查是否安装了所需的镜像,所以可能需要几分钟的时间,请耐心等待。

然后在浏览器中输入以下链接打开Dreawview界面:
http://localhost:8888/

此时你就能看到这个画面:
在这里插入图片描述
恭喜你,运行成功。

demo测试

Apollo 5.5提供了离线测试数据包,你可以从该地址下载demo_3.5.record`文件,即Apollo 5.5的离线测试数据和Apollo 3.5是一样的。

下载完成后将其复制到apollo-5.5.0/data/bag路径下(或者你自己想要的路径),然后在Docker容器中执行:

cyber_recorder play -f data/bag/demo_3.5.record -l

此时你就能在Dreawview界面看到如下画面:
在这里插入图片描述
参考:
How to Launch and Run Apollo

Apollo 5.0编译安装步骤

我是先编译安装的Apollo 5.5,后面因为一些特殊的需要,又安装编译了Apollo 5.0,大体上步骤差不多,所以你基本上可以参考上述的Apollo 5.5编译安装步骤进行。

但在运行bash apollo.sh build --local_resources 2048,1.0,1.0出现了以下错误:

The 'build' command is only supported from within a workspace.

从网上找了一圈,都没找到解决方法,最后我看了一下Apollo 5.5源码中有WORKSPACEWORKSPACE.in两个文件,而Apollo 5.0中却只有WORKSPACE.in一个文件,所以我就复制了一下Apollo 5.0中的WORKSPACE.in文件,修改名为WORKSPACE,再次编译,成功了。。。

编译cyber_visualizer

Apollo 5.0中默认就会编译cyber_visualizer,但是当你运行cyber_visualizer可能会出现如下的错误:

Could not initialize GLX
Aborted (core dumped)

目前找到的解决方案是:
在容器中执行:

unset LD_PRELOAD

就可以成功运行。


  1. Apollo 5.0 升级OS到Ubuntu 18环境部署 ↩︎

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐