标签 Ubuntu 下的文章

Hello,Termux

程序员或多或少都有一颗Geek(极客)的心^0^。- Tony Bai

折腾开始。

这一切都源于前不久将手机换成了Xiaomi的MIX2。因为青睐开放的系统(相对于水果公司系统的封闭,当然Mac笔记本除外^0^),我长期使用Android平台的手机。但之前被三星Note3手机的“大屏”搞的不是很舒服,这两年一直用5寸及以下的手机,因为单手操作体验良好。MIX2的所谓“全面屏”概念又让我回归到了大屏时代。

除了大屏,现在手机“豪华”的硬件配置也让人惊叹:高通骁龙835,8核,最高主频 2.45GHz;6GB以上的LPDDR4x的双通道大内存,怪不得微软和高通都开始合作生产基于高通ARM处理器的Win10笔记本了,这配置支撑在笔记本上办公+浏览网页绰绰有余。不过对于不怎么玩游戏的我而言,这种配置仅仅用作手机日常功能有些浪费。于是有了“mobile coding”的想法和需求,至少现在是这样想的,冲动也好,伪需求也好,先实现了再说。

一、神器Termux,不仅仅是一个terminal emulator

所谓”mobile coding”不仅仅是要通过手机ssh到服务器端进行coding,还要支持在手机上搭建一个dev环境。dev环境这个需求是以往我安装的ConnectBot等ssh client端工具所无法提供的,而其他一些terminal工具,诸如Terminal Emulator for Android仅仅提供一些shell命令的支持,适合于那些喜爱使用命令行对Android机器进行管理的”administrator”们,但对dev环境的搭建支持有限的。于是神器Termux登场了。

Termux是什么?Termux首先是一个Android terminal emulator,可以像那些terminal工具一样,提供基本的shell操作命令;除此之外更为重要的是它不仅仅是一个terminal emulator。Termux提供了一套模拟的Linux环境,你可以在无需root、无需root、无需root的情况下,像在PC linux环境下一样进行各种Linux操作,包括使用apt工具进行安装包管理、定制shell、访问网络、编写源码、编译和运行程序,甚至将手机作为反向代理、负载均衡服务器或是Web服务器,又或是做一些羞羞的hack行为等。

1、安装

Termux仅支持Android 5.0及以上版本(估计现在绝大多数android机都满足这一条件)。在国内建议使用F-Droid安装Termux(先下载安装F-Droid,再在F-Droid内部搜索Termux,然后点击安装),国内的各种安装助手很少有对这个工具的支持。或是到apk4fun下载Termux的apk包(size非常小)到手机中安装(安装时需要连接着网络)。当前Termux的最新版本为0.54

在桌面点击安装后的Termux图标,我们就启动了一个Termux应用,见下图:

img{512x368}

2、Termux初始环境探索

Mix2手机的Android系统使用的是Android 7.1.1版本,桌面Launcher用的是MIUI 9.1稳定版,默认的shell是bash。通过Termux,我们可以查看Android 7.1.1.使用的Linux内核版本如下:

$uname -a
Linux localhost 4.4.21-perf-g6a9ee37d-06186-g2b2a77b #1 SMP PREEMPT Thu Oct 26 14:55:45 CST 2017 aarch64 Android

可以看出Linux内核是4.4.21,采用的CPU arch family是ARM aarch64

我再来看一下Termux提供的常见目录结构:

Home路径:

$cd ~/
$pwd
/data/data/com.termux/files/home

//或者通过环境变量HOME获取:

$echo $HOME
/data/data/com.termux/files/home

长期使用Linux的朋友可能会发现,这个HOME路径好是奇怪,一般的标准Linux发行版,比如Ubuntu都是在”/home”下放置用户目录,但termux环境中HOME路径却是一个奇怪的位置。在Termux官方Wiki中,我们得到的答案是:Termux是一个prefixed system。

这个prefix的含义我理解颇有些类似于我们在使用configure脚本时指定的–prefix参数的含义。我们在执行configure脚本时,如果不显式地给–prefix传入值,那么make install后,包将被install在标准位置;否则将被install在–prefix值所指定的位置。

prefixed system意味着Termux中所有binaries、libraries、configs都不是放在标准的位置,比如:/usr/bin、/bin、/usr/lib、/etc等下面。Termux expose了一个特殊的环境变量:PREFIX(类似于configure –prefix参数选项):

$echo $PREFIX
/data/data/com.termux/files/usr

$cd $PREFIX
$ls -F
bin/  etc/  include/  lib/  libexec/  share/  tmp/  var/

是不是有些似曾相识?但Termux的$PREFIX路径与标准linux的根路径下的目录结构毕竟还存在差别,但有着对应关系,这种对应关系大致是:

Termux的$PREFIX/bin  <=>  标准Linux环境的 /bin和/usr/bin
Termux的$PREFIX/lib  <=>  标准Linux环境的 /lib和/usr/lib
Termux的$PREFIX/var  <=>  标准Linux环境的 /var
Termux的$PREFIX/etc  <=>  标准Linux环境的 /etc

因此,基本可以认为Termux的$PREFIX/就对应于标准Linux的/路径。

3、更新源和包管理

Termux的牛逼之处在于它基于debian的APT包管理工具进行软件包的安装、管理和卸载,就像我们在Ubuntu下所做的那样,非常方便。

Termux自己维护了一个源,提供各种专门为termux定制的包:

# The main termux repository:
#deb [arch=all,aarch64] http://termux.net stable main

同时,termux-packages项目为开发者和爱好者提供了构建工具和脚本,通过这些工具和脚本,我们可以将自己需要的软件包编译为可以在termux运行的版本,并补充到Termux的源之中。我大致测试了一下官方这个源还是可用的,虽然初始连接的响应很缓慢。

国内清华大学维护了一个Termux的镜像源,你可以通过编辑 /data/data/com.termux/files/usr/etc/apt/sources.list文件或执行apt edit-sources命令编辑源(在Shell配置中添加export EDITOR=vi后,apt edit-sources才能启动编辑器进行编辑):

# The main termux repository:
#deb [arch=all,aarch64] http://termux.net stable main
deb [arch=all,aarch64] http://mirrors.tuna.tsinghua.edu.cn/termux stable main

剩下的操作与Ubuntu上的一模一样,无非apt update后,利用apt install安装你想要的包。目前Termux源中都有哪些包呢?可以通过apt list命令查看:

$apt list
Listing... Done
aapt/stable 7.1.2.33-1 aarch64
abduco/stable 0.6 aarch64
abook/stable 0.6.0pre2-1 aarch64
ack-grep/stable 2.18 all
alpine/stable 2.21 aarch64
angband/stable 4.1.0 aarch64
apache2/stable 2.4.29 aarch64
apache2-dev/stable 2.4.29 aarch64
apksigner/stable 0.4 all
apr/stable 1.6.3 aarch64
apr-dev/stable 1.6.3 aarch64
apr-util/stable 1.6.1 aarch64
apr-util-dev/stable 1.6.1 aarch64
apt/stable,now 1.2.12-3 aarch64 [installed]
apt-transport-https/stable 1.2.12-3 aarch64
... ...
zile/stable 2.4.14 aarch64
zip/stable 3.0-1 aarch64
zsh/stable,now 5.4.2-1 aarch64 [installed]

查看是否有需要更新的包列表:

$apt list --upgradable

以安装golang为例:

$apt install golang
....
$go version
go version go1.9.2 android/arm64

img{512x368}

Termux源中的包似乎更新的很勤奋,Go 1.9.2才发布没多久,这里已经是最新版本了,这点值得赞一个!

二、开发环境搭建

我的目标是mobile coding,需要在Termux上搭建一个dev环境,以Go环境为例。

1、sshd

在搭建和配置阶段,如果直接通过Android上的软键盘操作,即便屏再大,那个体验也是较差的。我们最好通过PC连到termux上去安装和配置,这就需要我们在Termux上搭建一个sshd server。下面是步骤:

$apt install openssh
$sshd

就这么简单,一个sshd的server就在termux的后台启动起来了。由于Termux没有root权限,无法listen数值小于1024的端口,因此termux上sshd默认的listen端口是8022。另外termux上的sshd server不支持用户名+密码的方式进行登录,只能用免密登录的方式,即将PC上的~/.ssh/id_rsa.pub写入termux上的~/.ssh/authorized_keys文件中。关于免密登录的证书生成方法和导入方式,网上资料已经汗牛充栋,这里就不赘述了。导入PC端的id_rsa.pub后,PC就可以通过下面命令登录termux了:

$ssh 10.88.46.79  -p 8022
Welcome to Termux!

Wiki:            https://wiki.termux.com
Community forum: https://termux.com/community
IRC channel:     #termux on freenode
Gitter chat:     https://gitter.im/termux/termux
Mailing list:    termux+subscribe@groups.io

Search packages:   pkg search <query>
Install a package: pkg install <package>
Upgrade packages:  pkg upgrade
Learn more:        pkg help

其中10.88.46.79是手机的wlan0网卡的IP地址,可以在termux中使用ip addr命令获得:

$ip addr show wlan0
34: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 3000
    ... ...
    inet 10.88.46.79/20 brd 10.88.47.255 scope global wlan0
       valid_lft forever preferred_lft forever
    ... ...

2、定制shell

Termux支持多种主流Shell,默认的Shell是Bash。很多开发者喜欢zsh + oh-my-zsh的组合,Termux也是支持的,安装起来也是非常简单的:

$ apt install git
$ apt install zsh
$ git clone git://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh
$ cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc
$ chsh zsh

与在PC上安装和配置zsh和oh-my-zsh没什么两样,你完全可以按照你在PC上的风格定制zsh的Theme等,我用的就是默认theme,所以也无需做太多变化,顶多定制一下PROMPT(~/.oh-my-zsh/themes/robbyrussell.zsh-theme中的PROMPT变量)的格式^0^。

3、安装vim-go

在terminal内进行Go开发,vim-go是必备之神器。vim-go以及相关自动补齐、snippet插件安装在不同平台上都是大同小异的,之前写过两篇《Golang开发环境搭建-Vim篇》和《vim-go更新小记》,大家可以参考。

不过这里有一个较为关键的问题,那就是Termux官方源中的vim 8.0缺少了对python和lua的支持:

 $vim --version|grep py
+cryptv          +linebreak       -python          +viminfo
+cscope          +lispindent      -python3         +vreplace
$vim --version|grep lua
+dialog_con      -lua             +rightleft       +windows

而一些插件又恰需要这些内置的支持,比如ultisnips需要vim自带py支持;neocomplete又依赖vim的lua支持。这样如果你还想要补齐和snippet特性,你就需要在Termux下面自己编译Vim的源码了(configure时加上对python和lua的支持)。

4、中文支持

无论是PC还是Termux使用的都是UTF8的内码格式,但是在安装完vim-go后,我试着用vim编辑一些简单的源码,发现在vim中输入的中文都是乱码。这里通过一个配置解决了该问题:

//~/.vimrc

添加一行:

set enc=utf8

至于其中的原理,可以参见我N年前写的《也谈VIM字符集编码设置》一文。

三、键盘适配

现阶段,写代码还是需要键盘输入的(憧憬未来^0^)。

1、软键盘

使用原生自带的默认软键盘在terminal中用vim进行coding,那得多执着啊,尤其是在vim大量使用ESC键的情况下(我都没找到原生键盘中ESC键在哪里:()。不过Termux倒是很具包容心,为原生软键盘提供了扩展支持:用两个上下音量键协助你输入一些原生键盘上没有或者难于输入的符号,比如(全部的模拟按键列表参见这里):

清理屏幕:用volume down + L 来模拟 ctrl + L
结束前台程序:用volume down + C 来模拟 ctrl + C
ESC:用volume up + E 来模拟
F1-F9: 用volume up + 1 ~ 9 来模拟

据网友提示:volume up + Q键可以打开扩展键盘键,包括ESC、CTRL、ALT等,感谢。

这样仅能满足临时的需要,要想更有效率的输入,我们需要Hacker’s Keyboard。顾名思义,Hacker’s Keyboard可以理解为专为Coding(无论出于何种目的)的人准备的。和Termux一样,你可以从F-droid安装该工具。启动该app后,app界面上有明确的使用说明,如果依旧不明确,还可以查看这篇图文并茂的文章:《How to Use Hacker’s Keyboard》。默认情况下,横屏时Hacker’s keyboard会使用”Full 5-row layout”,即全键盘,竖屏时,则是4-row layout。你可以通过“系统设置”中的“语言和输入法”配置中对其进行设置,让Hacker’s keyboard无论在横屏还是竖屏都采用全键盘(我们屏幕够大^0^):

img{512x368}
横屏

img{512x368}
竖屏

Hacker’s Keyboard无法支持中文输入,这点是目前的缺憾,不过我个人写代码时绝少使用中文,该问题忽略不计。

2、外接蓝牙键盘

Hacker’s Keyboard虽然一定程度提升了Coding时的输入效率,但也仅是权宜之计,长时间大规模通过软键盘输入依旧不甚可取,外接键盘是必须的。对于手机而言,目前最好的外接连接方式就是蓝牙。蓝牙键盘市面上现在有很多种,我选择了老牌大厂logitechK480。这款键盘缺点是便携性差点、按键有些硬,但按键大小适中;而那些超便携的蓝牙键盘普遍键帽太小,长时间Coding的体验是个问题。

img{512x368}

Termux对外接键盘的支持也是很好的,除了常规输入,通过键盘组合键Ctrl+Alt与其他字母的组合实现各种控制功能,比如:

ctrl + alt + c => 实现创建一个新的session;
ctrl + alt + 上箭头/下箭头 => 实现切换到上一个/下一个session的窗口;
ctrl + alt + f => 全屏
ctrl + alt +v => 粘贴
ctrl + alt + +/- => 实现窗口字体的放大/缩小

不过,外接键盘和Hacker’s keyboard有一个相同的问题,那就是针对Termux无法输入中文。我尝试了百度、搜狗等输入法,无论如何切换(正常在其他应用中,通过【shift + 空格】实现中英文切换)均只是输入英文。

四、存储

到目前为止,我们提到的路径都在termux的私有的内部存储(private internal storage)路径下,这类存储的特点是termux应用内部的、私有的,一旦termux被卸载,这些数据也将不复存在。Android下还有另外两种存储类型:shared internal storage和external storage。所谓shared internal storage是手机上所有App可以共享的存储空间,放在这个空间内的数据不会因为App被卸载掉而被删除掉;而外部存储(external storage)主要是指外部插入的SD Card的存储空间。

默认情况下,Termux只支持private internal storage,意味着你要做好数据备份,否则一旦误卸载termux,数据可就都丢失了;数据可以用git进行管理,并sync到云端。

Termux提供了一个名为termux-setup-storage的工具,可以让你在Termux下访问和使用shared internal storage和external storage;该工具是termux-tools的一部分,你可以通过apt install termux-tools来安装这些工具。

执行termux-setup-storage(注意:这个命令只能在手机上执行才能弹出授权对话框,通过远程ssh登录后执行没有任何效果)时,手机会弹出一个对话框,让你确认授权:

img{512x368}

一旦授权,termux-setup-storage就会在HOME目录下建立一个storage目录,该目录下的结构如下:

➜  /data/data/com.termux/files/home $tree storage
storage
├── dcim -> /storage/emulated/0/DCIM
├── downloads -> /storage/emulated/0/Download
├── movies -> /storage/emulated/0/Movies
├── music -> /storage/emulated/0/Music
├── pictures -> /storage/emulated/0/Pictures
└── shared -> /storage/emulated/0

6 directories, 0 files

我们看到在我的termux下,termux-setup-storage在storage下建立了6个符号链接,其中shared指向shared internal storage的根目录,即/storage/emulated/0;其余几个分别指向shared下的若干功能目录,比如:相册、音乐、电影、下载等。我的手机没有插SD卡,可能也不支持(市面上大多数手机都已经不支持了),如果插了一张SD卡,那么termux-setup-storage还会在storage目录下j建立一个符号链接指向在external storage上的一个termux private folder。

现在你就可以把数据放在shared internal storage和external storage上了,当然你也可以在Termux下自由访问shared internal storage上的数据了。

五、小结

Termux还设计了支持扩展的Addon机制,支持通过各种Addon来丰富Termux功能,提升其能力,这些算是高级功能,在这篇入门文章里就先不提及了。好了,接下来我就可以开始我的mobile coding了,充分利用碎片时间。后续在使用Termux+k480的过程中如果遇到什么具体的问题,我再来做针对性的解析。


微博:@tonybai_cn
微信公众号:iamtonybai
github.com: https://github.com/bigwhite

Hello, Apollo

要说目前哪个技术领域投资最火热,莫过于人工智能。而人工智能领域中最火的(或者说之一)肯定要算上自动驾驶。自动驾驶的概念不是什么新鲜的玩意了,只是随着近两年这一波人工智能的大热,自动驾驶又被推到了风口浪尖。各大汽车厂商、互联网公司也都跃跃欲试,准备给汽车这一“历经百年的黄金平台”做一次新的“赋能”。

今年7月5日,国内搜索引擎No.1企业百度在其首届百度AI开发者大会上发布了Apollo自动驾驶开放平台,同时百度也对外宣布baidu正式从互联网公司转型为一家人工智能公司。作为“错过了移动互联网时代”的典型公司代表,百度这次押宝人工智能,我觉得也是战略上迫不得已的选择:在现有现金牛“搜索广告业务”还能带来大量利润的时候,为抓住未来那头现金牛而进行的努力。而Apollo自动驾驶平台恰是百度人工智能战略的重要组成部分。

Apollo,阿波罗是古希腊神话中的光明之神,这个名字在西方文化中“自带光环”。提到Apollo,很多人还会想到半个多世纪前美国著名的“登月计划”。百度将其自动驾驶平台命名为Apollo,我猜测是有“借势之意”,即期望Apollo这个项目能在百度众多人工智能业务中拥有美好光明的前景。

作为技术人员,我们不能像一般媒体人员那样根据官方提供的“说辞”做宽泛的介绍,我们要与Apoll亲密接触,看看Apollo究竟是什么,究竟能做什么。这里就和大家一起来Say Hello to Apollo。

一、自动驾驶汽车- “百年黄金平台”的新时代赋能

在正式入门Apollo之前,还要说点“废话”。在接触Apollo之前,我从未认真思考过“汽车”这个平台,这次算是“顿悟”,虽然也算不上深刻。就我看来,汽车 是一个不可多得的“黄金平台”。作为一个平台,汽车已经有了上百年的历史,见证了人类科学技术的发展,是跨学科之集大成者。这百年多时间,任何新的、先进的民用技术都会赋能在汽车工业上。以一个长不足5米,重量不超过2t的一般家用乘用车为例,我们在其上面能看到先进的能源技术、材料技术、化工技术、电子技术、通讯技术以及精密的机械原件和组装技术等,可以说汽车为各个公司的创造力提供了展示的舞台。

就普通老百姓的衣食住行而言,汽车也是史无前例的高频使用典范,且是最直接、最贴近普通百姓生活的,这些都是飞机、火车等无法媲美的(如果非要选一个,那只有智能终端能与汽车媲美了,尤其是在集成度方面)。即便是到了科幻片中的漫天跑飞行器的时候,汽车也可能依旧是短距离交通的首选。当然届时的汽车很可能与我们此时的汽车大不相同了。随着时代的进步,汽车也在演化,日新月异的新技术、新材料、新能源对汽车的进一步赋能,因此汽车依旧是朝阳产业,这也是国际资本依旧积极群雄逐鹿汽车工业发展的根本原因了。比如:通过新能源方式赋能汽车的特斯拉、通过无人驾驶技术赋能的Google的waymo等。当然,不仅是从技术方面,从商业模式方面也有围绕着汽车这一平台创新的经典案例,典型的比如:uber滴滴等的高效出行以及近期日渐升温的共享汽车出行。

可以说,各大公司都在从自身优势出发,考虑如何为汽车这一百年黄金平台赋能。从这一点出发,我们就能大致理解百度Apollo的出现了:它是baidu结合自身的技术优势和数据优势拥抱汽车工业、为汽车做新时代赋能而迈出的重要一步。

二、Apollo的技术架构

Apollo是一套完整的自动驾驶技术方案,官方架构原图的截图较为模糊,这里自己画了一个简单的四层结构,每层内的模块暂未画出,因为不是本次入门的重点:

img{512x368}

按照上图,apollo自动驾驶分成四层技术栈,从下到上分别为:

1、Reference Vehicle Platform(参考车辆平台)

自动驾驶最终都要落地到车上,因此apollo抽象了一个”参考车辆平台”层,通过电子化的方式控制车辆的行驶行为。

Note: 在开发者大会上,百度展示了由美国创业公司AutonomouStuff基于Apollo 1.0开放平台改装而成的循迹自动驾驶车,这辆车是一辆美系的林肯MKZ。也就是说当前发布的Apollo适配林肯MKZ是没有问题的。但这款中型车对于普通开发者来说门槛算是稍高了。如果百度能拿出一款大众系、丰田系或至少也应该是一个本田系这样的车型,那对自动驾驶领域的开发者或者说爱好者来说,才是福利。相比而言,著名黑客George Hotz创立的自动驾驶技术公司comma.ai为其openpilot初始选用的车型则是Honda系的思域和CR-V,滥大街的车型,容易搞到,且低成本搞到,也容易改装。

2、Reference Hardware Platform(参考硬件平台)

这一层为自动驾驶汽车提供计算、感知、交互的硬件能力,包括计算单元(车载处理器设备)、GPS/IMU(惯性测量设备)、摄像头、激光雷达、声波雷达、HMI(人机接口)等。在发布的Apollo 1.0版本中,开放的硬件能力包括:计算单元、GPS/IMU(惯性测量设备)以及HMI。

3、Apollo open software Platform (开放软件平台)

这一层是百度Apollo 1.0开放的核心部分,见下图(蓝色的代表在apollo 1.0.0中已经开放的能力):

img{512x368}

从图中看到,这一层还可以分为三个子层,从下至上分别是:

  • apollo kernel层

这一层是运行于硬件上面的OS,对于自动驾驶这种实时性要求特别强的领域,这里显然只能是RTOS(实时操作系统)。Apollo 1.0开放的源码中包含一个”Apollo Kernel“的项目,在这个项目下汇集着可以满足实时性需求的OS kernel。当然目前还仅有一个选择:realtime linux kernel。这是apollo基于Linux Kernel 4.4.32+realtime patch定制的一款专用linux内核。

  • apollo platform层

在Kernel层的上面就是apollo的runtime framework了,提供platform级的支撑。Apollo 1.0同样也创建了一个专用项目:apollo-platform,用于汇集满足apollo平台级支撑需求的platform。当前该项目下也仅提供了一种选择:Apollo ROS,是基于ROS1的Indigo版二次开发后的定制版ROS。Apollo ROS基于自动驾驶需求出发,对ROS1主要做了三方面改进:

  • 为优化自动驾驶大量使用传感器引发很大的传输带宽需求, Apollo ROS改变基于socket的网络传输模式,大量采用共享内存的node间通信机制,减少传输中的数据拷贝,显著提升传输效率, 尤其是在满足一对多的传输场景下效果明显;

  • 从鲁棒性出发,使用RTPS(Real-Time Publish Subscribe)服务发现协议实现完全的P2P网络拓扑,避免原ROS的以Master作为拓扑网络的中心的单点故障问题;

  • 使用protobuf替代原ROSmessage,提供很好的向后兼容,避免接口升级后,不同版本的模块难以兼容的问题。

其实第二点改进也是ROS2正在做的事情。关于Apollo ROS的详尽变化,可以参考前不久百度工程师的一个分享:《Apollo代码开放框架—ROS 探索与实践》

  • apollo modules层

在这一层是apollo的功能modules,当前似乎依旧是基于ROS的package开发的,在github.com/ApolloAuto/apollo/modules/common/apollo_app.cc你大致能看出来一个ROS Package的开发模板。这一层提供诸如:规划(planning)、洞察(perception)、控制(control)、预测(prediction)、决策(decision)、定位等诸多功能。但Apollo 1.0仅仅开放了Control、Localization和HMI三个module,因为这三块足以构成Apollo 1.0提供的封闭场地循迹驾驶体系了。

4、Cloud Services(云端服务)

Apollo 1.0还开放了云端数据平台,以及唤醒万物的DuerOS能力。DuerOS也是Baidu人工智能战略的重要棋子,似乎也是目前Baidu在AI方面最为成熟的、应用最广的产品。当然这一层还包括仿真、高精度地图等服务,不过目前尚未开放。

三、上手Apollo

买不起林肯MKZ的童鞋也不要担心,Apollo 1.0提供了一个本地仿真工具,给你一个与Apollo亲密接触的途径,让你可以在PC上肆无忌惮地玩耍,毕竟Apollo 1.0仅提供封闭场地的寻迹能力,相对简单。

我们的重点是Apollo open software Platform这一层,而这一层中,我们不关心apollo kernel,只关心Apollo ROS和三个已经开放的apollo modules。

1、下载release版本

截至目前为止,Apollo仅发布了一个版本:apollo-v1.0.0,我们可以从github上将其下载到本地:

# wget -c https://github.com/ApolloAuto/apollo/archive/v1.0.0.tar.gz
# tar zxvf v1.0.0.tar.gz
# cd apollo-1.0.0
# ls -F
apollo_docker.sh*  apollo.doxygen  apollo.sh*  AUTHORS.md  BUILD  CPPLINT.cfg
docker/  docs/  LICENSE  modules/  README.md  scripts/  third_party/  tools/  WORKSPACE

注意:我的实验环境为ubuntu 16.04.1 amd64。

2、本地源码构建

对于基于Apollo这个framework的开发者,Apollo官方强烈建议直接采用官方预定义好的专用docker环境(for dev)。对于爱折腾的我而言,必须要在本地做一次源码构建,即使这个体验是糟糕的,甚至最终是失败的^0^。源码构建的命令很简单,一行即可:

# cd apollo-1.0.0
# bash apollo.sh build

在这个过程中,我遇到了两个错误:

  • bazel不存在

Apollo的构建依赖google出品的bazel构建工具,我个人对bazel并没有什么研究,这里先装上再说:

# echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" |  tee /etc/apt/sources.list.d/bazel.list
deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8

# curl https://bazel.build/bazel-release.pub.gpg | apt-key add -
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  3157  100  3157    0     0   3202      0 --:--:-- --:--:-- --:--:--  3201
OK

# apt-get update && apt-get install bazel
  • third_party/ros/setup.bash: No such file or directory

apollo的编译要依赖ros,但apollo并没有自带ros。我们需要到apollo platform那个项目中去下载Apollo ROS:

# wget -c https://github.com/ApolloAuto/apollo-platform/releases/download/1.0.0/ros-indigo-apollo-1.0.0.x86_64.tar.gz
# tar zxvf ros-indigo-apollo-1.0.0.x86_64.tar.gz
# cd ros
# ls -F
bin/  BUILD  env.sh*  etc/  include/  lib/  setup.bash  setup.sh  _setup_util.py*  setup.zsh  share/

将下载的ros目录copy到apollo-1.0.0/third_party下,并chmod +x third_party/ros/setup.bash。

我们再次执行bash apollo.sh build,这次执行前面的error和warning基本都消失了,apollo.sh脚本开始下载依赖包并编译:

# bash apollo.sh build
ROS_DISTRO was set to 'kinetic' before. Please make sure that the environment does not mix paths from different distributions.
[WARNING] ESD CAN library supplied by ESD Electronics does not exit.
[WARNING] If you need ESD CAN, please refer to third_party/can_card_library/esd_can/README.md
.
____Loading package: modules/common/util/testing
____Loading package: @com_github_grpc_grpc//
____Loading package: @google_styleguide//
____Loading package: @glog//
____Loading package: @eigen//
____Loading package: @gtest//
____Loading package: @civetweb//
____Loading package: @com_github_google_protobuf//
____Loading package: @websocketpp//
____Loading package: @curlpp//
Building on x86_64, with targets:
//tools/platforms:x86_64
//tools/platforms:aarch64
//modules/prediction:prediction
//modules/prediction:prediction_lib
... ...
//modules/common:log
//modules/canbus/proto:canbus_proto.pb
//:x86_64
//:arm64
WARNING: Running Bazel server needs to be killed, because the startup options are different.
INFO: Downloading https://github.com/google/boringssl/archive/master-with-bazel.zip via codeload.github.com: 2,750,374 bytes
INFO: Cloning https://github.com/madler/zlib: Receiving objects (3309 / 5016)
INFO: Downloading https://github.com/google/boringssl/archive/master-with-bazel.zip via codeload.github.com: 2,773,664 bytes
INFO: Cloning https://github.com/madler/zlib: Receiving objects (3314 / 5016)
INFO: Downloading https://github.com/google/boringssl/archive/master-with-bazel.zip via codeload.github.com: 2,795,584 bytes
INFO: Downloading https://github.com/google/boringssl/archive/master-with-bazel.zip via codeload.github.com: 13,504,198 bytes

INFO: Downloading https://github.com/google/boringssl/archive/master-with-bazel.zip via codeload.github.com: 13,522,008 bytes
INFO: Found 190 targets...
[34 / 41] Compiling external/com_github_google_protobuf/src/google/protobuf/compiler/java/java_message_lite.cc [for host]
[41 / 48] Compiling external/com_github_google_protobuf/src/google/protobuf/compiler/command_line_interface.cc [for host]
[157 / 163] Compiling external/com_github_google_protobuf/src/google/protobuf/compiler/javanano/javanano_enum.cc [for host]
[752 / 756] Compiling external/com_github_grpc_grpc/src/core/ext/client_config/resolver_result.c

ERROR: /root/test/apolloauto/apollo-1.0.0/modules/canbus/BUILD:32:1: Linking of rule '//modules/canbus:canbus' failed: gcc failed: error executing command /usr/bin/gcc -o bazel-out/local-dbg/bin/modules/canbus/canbus '-Wl,-rpath,$ORIGIN/../../_solib_k8/_U_S_Sthird_Uparty_Sros_Cros_Ucommon___Uthird_Uparty_Sros_Slib' ... (remaining 8 argument(s) skipped): com.google.devtools.build.lib.shell.BadExitStatusException: Process exited with status 1.
modules/canbus/main.cc:21: error: undefined reference to 'ros::init(int&, char**, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int)'
third_party/ros/include/ros/publisher.h:107: error: undefined reference to 'ros::console::initializeLogLocation(ros::console::LogLocation*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, ros::console::levels::Level)'
... ...
collect2: error: ld returned 1 exit status
INFO: Elapsed time: 578.172s, Critical Path: 26.62s
============================
[ERROR] Build failed!
[INFO] Took 597.189 seconds
============================

经过漫长的等待后,还是以失败告终。并且C++的错误输出分析起来真是好痛苦,于是暂时放弃本地源码编译。

3、pre-specified Docker dev环境

既然apollo已经为我们准备好了pre-specified Docker dev环境,我们不妨用一下,下载和启动该环境可以用下面命令:

# cd apollo-1.0.0
# bash docker/scripts/dev_start.sh

apolloauto/apollo:dev-latest这个image超级庞大,大约有7个G左右,所以你需要耐心等待一会儿了。docker运行起来后,我们在另外一个terminal windows下可以执行下面命令切入到该docker容器内部:

# bash docker/scripts/dev_into.sh
root@myhost: /apollo#

在dev container中,我们可以来编译一下apollo源码:

root@myhost:/apollo# bash apollo.sh build
... ...
Copyright (c) 2017 Various License Holders. All Rights Reserved
Apollo software is built on top of various other open source software packages,
a complete list of licenses are located at https://github.com/ApolloAuto/apollo/blob/master/third_party/ACKNOWLEDGEMENT.txt

You agree to the terms of all the License Agreements.

Type 'y' or 'Y' to agree to the license agreement above, or type any other key to exit
y[WARNING] ESD CAN library supplied by ESD Electronics does not exit.
[WARNING] If you need ESD CAN, please refer to third_party/can_card_library/esd_can/README.md
____Loading package: modules/monitor/common
____Loading package: modules/common/adapters
____Loading package: modules/dreamview/conf
____Loading package: modules/control/integration_tests
____Loading package: @google_styleguide//
____Loading package: @com_github_google_protobuf//
... ...
[502 / 1,099] Compiling external/com_github_grpc_grpc/src/core/ext/transport/chttp2/transport/hpack_encoder.c
[914 / 1,524] Compiling external/com_github_grpc_grpc/src/core/ext/census/tracing.c
[1,304 / 1,527] Linking modules/canbus/vehicle/libmessage_manager_base.a

INFO: Elapsed time: 371.151s, Critical Path: 260.93s
============================
[ OK ] Build passed!
[INFO] Took 401.521 seconds
============================

由于dev环境中相关的依赖已经就绪,因此无需过多干预,在漫长的一段等待后,我们看到编译ok了。

4、运行apollo demo

在dev enviroment中或apollo:release-latest中,我们都可以运行apollo的一个寻迹小车的demo。以apollo:release-latest image环境为例:

// 启动基于apollo:release-latest image的apollo container(image size大约为3G,耐心等待下载):

# cd apollo-1.0.0/
# bash docker/scripts/release_start.sh

//切入到容器中去
# bash docker/scripts/release_into.sh
root@myhost:/apollo#

在容器中启动HMI(human-machine interface):

root@myhost:/apollo# bash scripts/hmi.sh
Start roscore...
HMI ros node service running at localhost:8887
HMI running at http://localhost:8887

root@myhostr:/apollo# rosnode list
/hmi_ros_node_service
/rosout

可以看到,hmi.sh脚本启动了roscore(ros master节点和相关服务)以及hmi的service,我们打开浏览器,输入:http://host_ip:8887即可看到如下场景:

img{512x368}

在容器内继续执行如下命令,回放小车的轨迹数据:

# rosbag play -l ./docs/demo_guide/demo.bag

[ INFO] [1502809442.462789096]: Opening ./docs/demo_guide/demo.bag

Waiting 0.2 seconds after advertising topics... done.

Hit space to toggle paused, or 's' to step.
 [RUNNING]  Bag Time: 1497125289.756657   Duration: 20.614178 / 41.613536
 [RUNNING]  Bag Time: 1497125289.896669   Duration: 20.754189 / 41.613536
... ...

我们打开hmi页面上的Debug开关,点击右上角的”Dreamview”按钮,稍后片刻,你就会在新打开的页面上看到小车仿真寻迹行驶的场景了:

img{512x368}

最初实验时,由于没有在阿里云的防火墙打开8888端口,导致dreamview的websocket建立连接失败,dreamview页面始终无法显示出小车。后经与apollo team的ycool在线联调才发现这个问题。这个问题的解决方法也已更新到Apollo的FAQ中了。

四、小结

Baidu为apollo项目做了一个4年的规划(见下面的roadmap),并计划在2020年实现全路网自动驾驶,这个说法似乎有意避开了自动驾驶的级别,这个2020目标到底是L4呢还是L5呢?不过无论是L4还是L5,这个目标都十分有挑战啊。

img{512x368}

个人觉得:未来的L4、L5级别的自动驾驶一定不光光是依靠车辆自身的设备与算法,还要与道路基础设施相配合去实现。甚至是依赖车与车之间的通信才能做到全天候、全路况的自动驾驶。apollo虽然迈出了第一步,但任重道远,让我们拭目以待吧!


微博:@tonybai_cn
微信公众号:iamtonybai
github.com: https://github.com/bigwhite

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言进阶课 Go语言精进之路1 Go语言精进之路2 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats