安装Apollo时常见的错误总结和使用窍门
进入docker后编译时报错:ERROR: An error occurred during the fetch of repository 'zlib',如下图所示: 出现这个错误的原因是Apollo依赖protobuf库,而protobuf库又依赖zlib库。这些库都要从网上下载,而protobuf库提供的zlib下载链接是https://zlib.net/zlib-1.2.11.tar
1 缺少zlib
进入docker后编译时报错:ERROR: An error occurred during the fetch of repository 'zlib'
,如下图所示:
出现这个错误的原因是Apollo依赖protobuf库,而protobuf库又依赖zlib库。这些库都要从网上下载,而protobuf库提供的zlib下载链接是https://zlib.net/zlib-1.2.11.tar.gz,问题是这个链接已经失效了,下载当然会失败。
解决方法是替换新的可用链接,具体就是修改Apollo项目文件夹中的.cache/bazel/540135163923dd7d5820f3ee4b306b32/external/rules_proto/proto/private
文件夹里的dependencies.bzl
文件,将"zlib"的部分改成以下即可。
"zlib": {
"sha256": "629380c90a77b964d896ed37163f5c3a34f6e6d897311f1df2a7016355c45eff",
"build_file": "@com_google_protobuf//:third_party/zlib.BUILD",
"strip_prefix": "zlib-1.2.11",
"urls": [
"https://github.com/madler/zlib/archive/v1.2.11.tar.gz",
],
}
见微知著,从这个小问题便可以看出百度的Apollo自动驾驶项目居然需要从美国服务器下载很多的依赖库。而且一旦下载不成功就报错,这种严重依赖网络条件的安装方式对不熟悉Linux的用户来说实在是太不友好了,完全是逼着用户自学Linux,这不是欺负人不懂Linux吗。反正我是自学grep
命令,把文件夹里所有包含关键字“https://zlib.net/zlib-1.2.11.tar.gz”的位置导出到txt里,然后一个个看应该改哪一个文件。一个号称安全性很高的自动驾驶项目,安装起来居然需要一些不靠谱的时刻可能改变的网络链接,真是可笑。百度为什么不把所有依赖都放到自己家的网盘里提供一次性打包下载呢。
2 FATAL: mkdir('/apollo/.cache/bazel'): (error: 13): Permission denied
运行脚本sudo ./apollo.sh build_opt
编译源代码时报错,如下图。错误的原因可能是使用了sudo
,解决方法是直接用bash ./apollo.sh build_opt
,不要加sudo。但有时候错误是反过来的,也就是不用sudo会报错,这时试试用sudo即可。
3 Error response from daemon: Container is not running
我们重启电脑后,有时用bash docker/scripts/dev_into.sh
会无法进入docker中,报错如下:
Error response from daemon: Container 78fb863e2...... is not running
此时,只需要用docker start
重启docker容器即可,命令如下。
docker start apollo_dev_q
我的容器名字是apollo_dev_q
,换成你自己的即可,不知道自己的容器叫什么可以用docker ps -a
查看,如下图,就是最后一列的那个NAMES
栏中的。
容器名字在docker/scripts/dev_into.sh
脚本里有提示,是apollo_dev_
加上你的用户名。
DOCKER_USER="${USER}"
DEV_CONTAINER="apollo_dev_${USER}"
抄袭docker/scripts/dev_into.sh
脚本,我们直接在终端中输入docker exec -u ${USER} -it apollo_dev_${USER} /bin/bash
也能进入docker。这么看,无人驾驶其实就是计算机的一个分支。搞个无人驾驶还得学习Linux脚本和docker,好累啊,头发开始掉了。笔者感觉docker用起来非常别扭,特别不爽,所以我们以后用apollo第一件事就是想办法干掉docker。
1 如何单独编译一个模块
Apollo是用bazel编译的,与make(gcc)相比bazel编译起来有些慢(因为它可能做了很多优化)。所以我们如果只改动一个模块,可以只单独编译这个模块。方法就是在编译时加上模块的名字,例如我们只想编译planning模块可以输入:
bash ./apollo.sh build_opt planning
2 修改Bazel编译参数
Apollo采用的Bazel编译器的配置参数在apollo\tools\bazel.rc
中。例如,我们想取消“有声明但是没有使用的变量”这个讨厌的报错,直接注释掉这一行即可,如下(前面的#表示注释)
#build --copt="-Werror=unused-variable"
3 使用modules/tools里的小工具
modules/tools文件夹中都是一些小功能,有些是C++写的,有些是python写的。我们举几个例子。注意这些功能只能在docker环境中使用。
例如仿真时发送虚拟的障碍物,运行perception\garage_perception.bash脚本即可。仿照脚本,修改json文件中的内容可以改变障碍物的ID、位置、尺寸、速度等参数,还可以同时模拟多个障碍物,如下。
{
"id": 2,
"position": [-1868.59, -2990.91, 0.0],
"theta": 1.1659045405098132,
"length": 4,
"width": 2,
"height": 1,
"speed": 8.0,
"tracking_time": 1.0,
"type": "VEHICLE",
"trace": [[-1868.59, -2990.91, 0.0],
[-1845.16, -2994.59, 0.0],
[-1850.16, -3000.0, 0.0]]
}
如果是动态障碍物还需要预测轨迹,所以我们还要开启预测模块,如下:
cyber_launch start modules/prediction/launch/prediction.launch
再比如,manual_traffic_light是模拟十字路口红绿灯的程序,运行launch文件即可像启动其它节点一样启动,如下。修改dag文件中的interval
可以改变运行周期。默认是通过按键切换灯的颜色,你可以改成实际红绿灯的颜色根据定时轮换。
cyber_launch start modules/tools/manual_traffic_light/manual_traffic_light.launch
还有,我们可以在dreamview里通过鼠标发送routing的request路由消息,但是这样显然比较慢,我们可以用mock_routing里的mock_routing_request.py程序发。修改里面的waypoint
坐标即可,坐标可以从dreamview里的右下角查看。
python /apollo/modules/tools/mock_routing/mock_routing_demo_final.py
4 启动的节点或者程序如何关闭
节点程序按ctrl+| 即可关闭。但是有时节点程序运行起来可能无法关闭,或者是在后台运行的也无法在终端中通过按键关闭。这时,可以使用命令强制关闭,方法如下。
这里我以一个python文件为例讲解,假设我有一个叫haha.py的python文件在运行(不管是前台还是后台)。我们通过命令ps -ef
查看所有运行中的进程,找到haha的进程ID,然后用kill
命令杀死它,这样就能关闭任何程序了。当然这个操作有点麻烦,所以可以写一个命令组合,如下。
kill -9 `ps -ef|grep haha |grep -v grep|awk '{print $2}'| xargs`
kill
的作用是停止一个进程,即杀死它,加上-9
的意思是让进程立即退出。后面跟的是进程的ID号。ps -ef|grep haha |grep -v grep
是找出haha这个进程对应的进程ID,如果你有不只一个进程叫haha它都能找出来杀死,所以你的名字不能太模糊,不然会有同名的进程躺枪。awk '{print $2}'| xargs
是把搜出来的ID号变成命令行输入格式给kill。
所以运行这行命令就能终止一个程序了,只要把haha换成你自己的程序名即可。任何进程,不管是Apollo的节点还是ROS节点,不管是C++还是python程序,只要你知道它的名字都能杀死它。
当然,如果在docker环境中,操作是一样的。
5 log文件在哪里?
每次启动节点都会生成log文件,通过查阅log文件我们能找出问题。Apollo的log文件在Ubuntu的data\log
文件夹中,在docker中也能访问到这个文件夹,因为Apollo已经帮我们做了映射,就是apollo\data\log
,如下图。对这个文件夹的操作就等于对Ubuntu下的原始文件进行的操作,例如清除。
6 镜像在哪里?
你下载下来的docker镜像存储在/var/lib/docker
文件夹中,但是你看不到原名。可以使用docker save
命令将其取出来放到我们自己的文件夹下,下次就不用再次下载了。以最大的那个镜像为例,命令如下,镜像的名字放在后面,镜像会保存到我们自己的home路径下。如果不知道镜像的名字,用docker images
查看。
docker save -o dev-x86_64-18.04-20200914_0742.tar.gz e1359ff08479
7 在Dreamview中纯仿真
Apollo可以在纯仿真模式下运行。打开Dreamview中的Sim Control,然后启动routing、planning模块(定位模块和控制模块不需要启动),在Route页面用鼠标点击选择两个点作为起点和终点,再点Send Routing Request即可。
bash docker/scripts/dev_into.sh
./scripts/bootstrap.sh
8 用cyber_monitor查看话题
cyber_monitor 回车进入某个话题,如果想看某个话题的具体信息,选中 +[1 items]回车查看具体内容。按q退出界面。
1 const函数
自动驾驶对安全性的要求是非常高的,所以对代码质量自然也有很高的要求。为了追求安全性,百度Apollo项目中的函数在定义时能用const
的地方尽量都用了,这是一种好的编程习惯和推荐做法。当然,这会带来一些不便,我举个例子。
例如我想用一个均值滤波器,Apollo中已经有实现了。至于怎么用,我们仿照lon_controller.cc
类中的common::MeanFilter station_error_filter_;
来即可。
但是,假设我想在speed_decider.cc中的使用,就会出问题,例如在SpeedDecider::CreateFollowDecision
函数中使用speed = filter_.Update(speed);
,编译时会报错,如下。
error: passing ‘XXX’ as ‘this’ argument discards qualifiers [-fpermissive]
这个错误并不是说我们定义的滤波器有错误,或者用法有错误,而是放的地方不对。因为CreateFollowDecision
函数是个const
的,我们不能在里面修改成员变量。
bool CreateFollowDecision(const Obstacle& obstacle,
apollo::planning::ObjectDecisionType* const follow_decision) const;
更多推荐
所有评论(0)