从头开始摘树莓 - Day 2

等待树莓派 IP 的那一刻

昨天配置的 WiFi 热点,按我一直以来的操作,是用电脑开一个热点来凑合。我的电脑是 Windows 8.1,很方便,先打开一个有管理员权限的命令行,然后:

netsh wlan set hostednetwork mode=allow ssid=SSID key=PASSWORD
netsh wlan start hostednetwork
arp -a | findstr -i 192.168. | findstr /V 255

这时候是中午,我接着给树莓派上电,等了好久都没看到 IP,这就很气了。重复了几次,我开始怀疑是系统没正常启动,就查了查网上对树莓派指示灯的介绍。再仔细一看树莓派,居然红的电源灯会闪,这就不大对头了。于是我拿来手机充电器接上 USB 线,没过一会树莓派的 IP 就出现在电脑的 ARP 表里了。

哎,谜团终于揭开,但我已经把卡重做了,也只能硬着头皮从头来过。赶紧先用默认密码(pi:raspberry)连上树莓派的 SSH 再说(我用的是 Bitvise SSH Client,没遇到坑很好用),果然能上,全新的系统哈哈哈。

连上 SSH 之后的第一步:配置公钥登录

把公钥放进树莓派

  1. 先在 ~/ 下新建 .ssh 文件夹,然后把电脑中的公钥文件 id_rsa.pub 传到这个文件夹里,改名为 authorized_keys
  2. 然后退出 SSH 登录,重新试着用电脑中的私钥以 publickey 方式登录。如果失败就重来吧。
  3. 如果成功了就把密码登录禁用掉,至于改不改密码就无所谓了:
    sudo nano /etc/ssh/sshd_config,把 PasswordAuthentication 改成 noPubkeyAuthentication yes 的注释随手删掉就好,然后 Ctrl+X。
  4. 然后重启 SSH 服务器:sudo /etc/init.d/ssh restart
  5. 然后断开 SSH 连接,测试下 password 登录失效、pubkey 登录有效就好了。

搞定网络

连上我电脑开的无线热点之后,树莓派变得很奇怪,似乎连不上外网。实际上连 ping 电脑都 ping 不通,100% packet loss。搞了一个多小时,最后才突然想起来,电脑热点的共享配置忘了打开……

不过试着打开了共享,发现不知道什么原因,会把网络配置搞得一团糟(而以前根本不会这样子)。这才突然想起来,以前需要外网的时候都是让树莓派自己连接校园网的,现在系统还没配置完,连校园网也不大靠谱啊。而且我也懒得去把路由器调成小内网模式 = =

所以为了可持续发展,最后不得不使出代理大招,就是不开共享,用 Privoxy 开一个 HTTP 代理帮忙把请求传出去(请注意这里暂时不需要用到跨境用的梯子;顺便,这货官方有便携版,但似乎只有一部分版本号有)。最终如何测试效果呢?

export http_proxy=http://192.168.173.1:8118/
export https_proxy=http://192.168.173.1:8118/
curl http://ip.cn/

全局变量要用小写,别觉得看着难受就改成大写了,微笑。另外每次重启要是想连外网,都得手动配一次变量,没办法,省钱不用路由器嘛。

搞定网络当然不只是“网通了”那么简单,众所周知系统更新的源不处理一下的话,速度会慢到教你做人。USTC 在这方面真的为国内用户和教育系统做了很大贡献,就用他们的吧(还有 IPv6)。

一点提示:要根据发行版来写版本号。比如我的 sources.list 里原来写的是 stretch,所以我把 jessie 都改成 stretch 了。顺便 raspi.list 也得改,网上有些文章都不讲这个的。

sudo nano /etc/apt/sources.list

deb http://mirrors.ustc.edu.cn/raspbian/raspbian/ stretch main non-free contrib
deb-src http://mirrors.ustc.edu.cn/raspbian/raspbian/ stretch main non-free contrib

sudo nano /etc/apt/sources.list.d/raspi.list

deb http://mirrors.ustc.edu.cn/archive.raspberrypi.org/ stretch main ui

sudo apt-get update 能用之前我们得先修复一个问题:进了 sudo 会自动清除环境变量。sudo nano /etc/sudoers,然后:

Defaults env_reset
#找到上面这行,在下面加上下面这行
Defaults env_keep = "http_proxy https_proxy ftp_proxy DISPLAY XAUTHORITY"

更新系统

在继续我们的苦逼摘树莓旅程之前,先复习一下每次电脑重启之后要做的事情。

  1. 在电脑上确认外网正常,然后 netsh wlan start hostednetwork
  2. 给树莓派插上电,然后 arp -a | findstr -i 192.168. | findstr /V 255
  3. 根据看到的 IP 连接 SSH,然后打开电脑上的 Privoxy
  4. 在 SSH 里设置变量,我没设置成自动是想,谁知道这个 IP 啥时候会变,啥时候外网就直接通了:
    export http_proxy=http://192.168.173.1:8118/
    export https_proxy=http://192.168.173.1:8118/

然后学习一下几种 update 的区别

  • apt-get upgrade will not change what is installed (only versions),
  • apt-get dist-upgrade will install or remove packages as necessary to complete the upgrade,
  • apt upgrade will automatically install but not remove packages.
  • apt full-upgrade performs the same function as apt-get dist-upgrade.

这个时候我觉得可以来一发 dist-upgrade 了,反正我们什么都没装。

不过等等,这个过程中可能硬盘会莫名其妙地满。先用 df -h 一看,卧槽我 16G 的卡你才给我 4G 的系统大小?sudo raspi-config 7 号选项的 A1 可以一试,重启之后再看磁盘占用,美滋滋。

于是我们终于可以来这一句了:

sudo apt-get update && sudo apt-get dist-upgrade

等吧。注意在 upgrade 之前需要手动确认,想自动的话命令后面加上 -y --allow-unauthenticated。等的过程中可以先整理下 ~/ 下的文件夹,把没用的东西都删了,把准备用的程序传进去也行。(当然我这个时候是在奋力打字写这篇东西的。)

系统基本配置

趁着 apt-get upgrade 还没结束,先进  sudo raspi-config 逛逛,配置都挺简单的,按需求配置就可以了。其中对于时间而言,比较重要的是 Timezone(在 Localisation 里),Asia 里找 Shanghai、Harbin、Hong Kong、Chongqing 随便选一个。

一个忠告,建议不要改系统默认的语言,locale 可以生成中文的但不要设置默认,否则报错的时候搜索都不好搜(虽然看着神亲切)。退出来之后不知道为啥我的 sudo 不能用了,只能断电重启了之。

树莓派的时钟不对头,这还是个挺烦心的事情。这个事情主流有两种解决方案,一种是粗暴对时的 ntpdate,一种是慢慢把时间调整的 ntpd,后者效果更好,但前者简单。

不过我突然想起来,我们得用 HTTP 代理上网,那 NTP 肯定是用不了了。不过 superuser 上有一种简单粗暴的方法手动对时(此处假设 google.com 的时间是准的):

sudo date -u --set="$(curl -H 'Cache-Control: no-cache' -sD - http://google.com |grep '^Date:' |cut -d' ' -f3-6)"

 安装依赖环境

系统更新完了,我们先装上蓝牙的 Python 环境。记得当时为了调通蓝牙花了周末两整天的时间,不过这次不用踩坑试路,应该会容易一些了。

看了下文档,说 bluezero 需要 bluez 的版本至少是 5.43。看版本号可以用 bluetoothd -v,一看,还刚好就是 5.43。虽然说最新版 5.47 是 2017 年 9 月 14 日发布的,最近也有个很爆炸的蓝牙安全漏洞,但是我懒,就不装好了。但是我还是执行了 sudo apt-get install bluetooth bluez-tools

接着就是 sudo pip install bluezero -i https://pypi.mirrors.ustc.edu.cn/simple

这个时候我试了下跑蓝牙的 Python 程序,会报错( validate_object_path() argument 1 must be string, not None),才想起来那个安装文档里说得放一个东西。去 GitHub 下整个项目的 zip 包,然后把 examples/ukBaz.bluezero.conf 解压出来扔到树莓派的 ~/ 里,然后 sudo cp ukBaz.bluezero.conf /etc/dbus-1/system.d/.。好像还不行,就重启了,结果还是不行。

最后仔细一看才发现, bluezero 的版本从 0.0.3 升到 0.0.5,有些 API 的接口变了,我疯狂调用它的底层的实现也得改。上面那个错误是因为 broadcaster.Beacon().dongle.path 变成 broadcaster.Beacon().dongle.address 了,改完之后 Python 又报了一点错,按着改完,就能运行了。于是蓝牙偷懒搞定,晚上 7 点,吃饭去了。

安装 OpenCV

吃饭回来,准备这个非常著名难装的软件,记得当时视觉组的大佬们在 Windows 上装得死去活来的,最后还是乖乖用 Anaconda 解决了,幸好 Linux 还是简单一点。我们这边需要的依赖是 numpy、matplotlib 和 OpenCV+Python 等。

先装 numpy 吧(P.S. 没这么简单,请先 sudo apt-get install libblas-dev liblapack-dev,具体看后面!):sudo pip install numpy -i https://pypi.mirrors.ustc.edu.cn/simple

然后就可以开始 OpenCV 大业了,先疯狂看上一大堆文档,就试着弄吧。

  1. https://opencv.org/releases.html 下载 2.4 版本的 Source(GitHub 下载,梯子速度快)
  2. 安装依赖包(我们这项目不考虑视频解码):
    sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
    sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev
  3. 把 zip 包解压到树莓派的某个文件夹:unzip opencv-2.4.13.4.zip && cd opencv-2.4.13.4/
  4. 准备一个编译目的地的文件夹 mkdir build && cd build
  5. 通读一遍 CMakeLists.txt (大概 135 行开始),看看有什么 Flag 可以玩;好吧其实这篇介绍很不错:http://amritamaz.net/blog/opencv-config
  6. 我的需求可能跟你的需求不一样,总之我的建议是自己看一遍所有自己配置的 Flag 都是什么意思,最好用默认;我用的是开了优化的编译:
    cmake -D WITH_TBB=ON -D BUILD_TBB=ON -D WITH_OPENMP=ON -D CMAKE_BUILD_TYPE=RELEASE -D BUILD_EXAMPLES=OFF -D WITH_NVCUVID=ON -D WITH_CUDA=ON -D BUILD_DOCS=OFF -D BUILD_PERF_TESTS=OFF -D BUILD_TESTS=OFF -D WITH_OPENCL=ON CMAKE_INSTALL_PREFIX=/usr/local/ ..
    我的运行完会提示  CPACK_PACKAGE_VERSION does not match version provided by version.hpp header!,仔细看了下代码,CPACK_PACKAGE_VERSION 是拉本地 Git 库的版本号,所以可以直接忽略了。
  7. 接着就是愉快的编译时间,我开了四线程编译:make -j4
    我 21:55 开始编译的,22:37 编译完。
  8. 准备下 Python 的支持,cd lib && sudo cp cv2.so /usr/local/lib/python2.7/dist-packages/
  9. 然后自然是要跑一些简单测试的,参考网上的做法我们先用 SFTP 扔一张 cubik-cover.jpg 到 home 目录,然后:
pi@RASPBERRY:~/opencv-2.4.13.4/build/lib $ cd ~
pi@RASPBERRY:~ $ python
Python 2.7.13 (default, Jan 19 2017, 14:48:08)
[GCC 6.3.0 20170124] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> image = cv2.imread("cubik-cover.jpg")
>>> print image
[[[193 186 183]
 [193 186 183]
 [193 186 183]
 ..., # 略过好多
[ 41 39 38]
 [ 37 35 34]
 [ 38 36 35]]]
>>> cv2.imwrite("test1.png",image)
True

然后去下载一下 test1.png,果然文件变大了,转换成功了呢。此时是 22:53,这似乎意味着 OpenCV for Python 装好了。

不过到这里我没跑 sudo make install -j4,也不知道要不要,就试试呗。前面那段还挺慢,后面速度就变快了,3 分钟完事,哎,跑了总比不跑好嘛。

可以清理 APT 缓存庆祝一下:sudo apt-get clean

安装其他 Python 依赖

剩下的依赖我知道很容易装,看着自己程序的 import,然后试跑一下程序一点点来吧。

现在才发现忘下 scipy 了哈哈哈,然后它居然第一次安装失败了,然后我才看到文档说 don't use sudo pip, that will give problems... 这也挺娇气了。然而用官方的装法还是 fail 了。最后发现我之前 numpy 的装法没装优化(BLAS/LAPACK),可能有问题……于是只能在装完 BLAS/LAPACK 之后吃后悔药了。scipy 和 matplotlib 的安装速度是真的慢(用 pip 装的话还是单线程没进度条的编译),尤其是 scipy,编译下来得接近一个小时。

Update: 所以我 numpy 和 scipy 还是没装对……这里就把 scipy 的安装过程删了。具体请看下回分解。

python -m pip install --upgrade pip
sudo pip install cherrypy ws4py -i https://pypi.mirrors.ustc.edu.cn/simple
sudo apt-get install gcc gfortran python-dev libblas-dev liblapack-dev cython
pip 
pip install --user matplotlib -i https://pypi.mirrors.ustc.edu.cn/simple
# 下面这是 numpy 后悔药,不要用,因为最后是要卸载掉它的
sudo pip install numpy --upgrade -i https://pypi.mirrors.ustc.edu.cn/simple

所以,终于结束了。已经停电了,明天再来摘树莓吧。

“从头开始摘树莓 - Day 2”的一个回复

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

To respond on your own website, enter the URL of your response which should contain a link to this post's permalink URL. Your response will then appear (possibly after moderation) on this page. Want to update or remove your response? Update or delete your post and re-enter your post's URL again. (Find out more about Webmentions.)