从头开始摘树莓 - 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”的一个回复

发表评论

电子邮件地址不会被公开。 必填项已用*标注