目標設定
HeadlessなRaspberry Pi3 Model Bを想定し,以下を実現することを目指す.
- Jupyter notebookが自動起動し,リモートPCからの接続を受け付ける.
- LANなしでPCと1対1で繋いでも,LANを介して繋いでもJupyterに接続できる.
- PythonからOpenCVを使うことができる.
想定する環境
- RPi3 : Raspberry Pi3本体
- PC : RPi3を操作するためのWindows / macOS / Linux機
の2つのデバイスが同一ネットワークに接続されているとする.より具体的には
- RPi3とPCがハブを介して接続している
- RPi3とPCが有線で1:1接続されている
のどちらでもよいとする.またPCが特にWindowsの場合は,Bonjour for Windowsをインストールしておくこととする.これはRPi3のIPアドレスが不明の場合でも,raspberrypi.local
という名前でアクセスできるようにするため(Raspbianのavahiデーモンが実現している機能).
制限事項
以下の点はあえて解決しないままとする.
- セキュリティについては必要最低限のまま(外部公開は想定しない).
- インストールがすべて終わった状態であればPCと1:1接続した際にインターネット接続がなくてもOKだが,インストール中はパッケージやソースコードをダウンロードするためにインターネット接続が必要.最初からPCと1:1接続する場合は,PC側でNATしてあげる必要がある.
- Windowsなら「インターネット接続の共有(ICS)」機能を使う.例えばPCが無線LANでインターネットに接続されているなら,無線インターフェースで「インターネット接続の共有」を有効にし,その際に「ホームネットワーク接続」としてRPiと接続している有線インタフェースを指定する.この設定を行うと「ホームネットワーク接続」で有効にしたインタフェースでDHCPサーバが動き始めるので,一度RPiとのLANケーブルを抜き差しすればRPiにDHCPでアドレスが割り当てられる.インストール後にインターネット接続の共有を解除してもよいし,このまま使い続けてもよい.
- RPi3を無線LANで接続しない.
- 無線LANのパスワードなどを設定する必要があるので,今回はパス.
- LANに複数台のRaspberry Piが存在する場合,
raspberrypi.local
がどのデバイスになるかは予測しがたい.LANには今回使用する1台だけが存在すると仮定する.
初期設定
以下ではOSとしてRaspbianを新規インストール,つまりディスクイメージをSDカードに書きこむところからスタートすることとする.
RaspbianのインストールとSSHアクセスの有効化
- RasobianをMicroSDにインストール.
- RASPBIAN STRETCH WITH DESKTOP (Version:November 2017)を使用.
- JAISTのミラーから2017-11-29-raspbian-stretch.zipを取得.
- 実際にはWindowsで作業したので,MicroSDのパーティションを全部消して(「コンピュータの管理」内の「ディスクの管理」より),SD Formatterでフォーマットしてから,Win32 Disk ImagerでOSイメージを書き込んだ.
- RASPBIAN STRETCH WITH DESKTOP (Version:November 2017)を使用.
- MicroSDをPCでマウントし,第1パーティション(FAT32.ラベルは「boot」.Windowsなら「boot」というボリューム名のついたドライブに見える)に
ssh
という名前の空のファイルを作る. - RPiを起動
SSH接続
上記のようにboot
パーティションにssh
というファイルが存在すると,ブート時にsshデーモンが起動する.そこでPCから
> ssh pi@raspberrypi.local
としてssh接続をする(デフォルトのユーザpi
の初期パスワードはraspberry
).なおPCがWindowsの場合,
などを使うことができるが,BoW環境のsshでは接続できない(/etc/resolv.conf
にDNSサーバが直書きされているからmDNSで名前解決できない?).
そのほかの設定
- 以下のインストール作業にはそれなりの時間がかかるので,
tmux
をインストールしておいて適宜detouchできるようにする. - 必要に応じて
lv
,vim
もインストールしておく.
Jupyter
インストール
pipでインストールする.
$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install python3 python3-dev build-essential python-pip
$ sudo pip3 install --upgrade pip
$ sudo pip3 install jupyter
設定
JNSを参考にJupyterの設定ファイル(~/.jupyter/jupyter_notebook_config.py
)を作る以下のスクリプトを作成して実行する.ただしパスワードは別途設定することにしてここでは書き込まない.
#!/bin/bash
# script name: configure_jupyter.sh
# last modified: 2017/03/05
# sudo: no
if [ $(id -u) = 0 ]
then
echo "to be run as $(logname)"
exit 1
fi
# generate config and create notebook directory
# if notebook directory exists, we keep it (-p)
# if configuration file exeists, we overwrite it (-y)
jupyter notebook -y --generate-config
cd $home
mkdir -p notebooks
target=~/.jupyter/jupyter_notebook_config.py
# set up dictionary of changes for jupyter_config.py
declare -A arr
app='c.NotebookApp'
arr+=(["$app.open_browser"]="$app.open_browser = False")
arr+=(["$app.ip"]="$app.ip ='*'")
arr+=(["$app.port"]="$app.port = 8888")
arr+=(["$app.enable_mathjax"]="$app.enable_mathjax = True")
arr+=(["$app.notebook_dir"]="$app.notebook_dir = '/home/$(logname)/notebooks'")
#arr+=(["$app.password"]="$app.password =\
#'sha1:81f7fe53c0e5:0c1ddb2ff6bb83d83639c29e4cf6b4cb30ff7617'")
# apply changes to jupyter_notebook_config.py
# change or append
for key in ${!arr[@]};do
if grep -qF $key ${target}; then
# key found -> replace line
sed -i "/${key}/c ${arr[${key}]}" $target
else
# key not found -> append line
echo "${arr[${key}]}" >> $target
fi
done
続いてパスワードを設定する.パスワードを設定しないと,毎回ランダムに決まるトークンを入力するように促されるのでかえって面倒.
$ jupyter notebook password
Enter password:
Verify password:
[NotebookPasswordApp] Wrote hashed password to /home/pi/.jupyter/jupyter_notebook_config.json
自動起動
Jupyterが自動起動するように設定(参考にしたサイト:https://qiita.com/mt08/items/edb9bcaeaa416d3e5319 ).
[Unit]
Description=Jupyter notebook
[Service]
Type=simple
PIDFile=/var/run/jupyter-notebook.pid
ExecStart=/usr/local/bin/jupyter notebook
User=pi
Group=pi
WorkingDirectory=/home/pi/notebooks
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
sudo systemctl start jupyter
sudo systemctl enable jupyter
sudo systemctl status jupyter
接続テスト
ここまででwebブラウザから http://raspberrypi.local:8888/ にアクセスすると,パスワードを入力する画面が表示されるはずである.接続できない場合,webブラウザのプロキシ設定も確認すること.
OpenCV
ここを参考にソースからビルドする(だいたいコンパイルに約2時間かかる.MicroSDのスピード次第?).ただしgcc-6の場合はエラーが出るので,途中でcmake/OpenCVPCHSupport.cmake
に
- SET(_PCH_isystem_prefix "-isystem")
+ SET(_PCH_isystem_prefix "-I")
を入れる点に注意(参考:OpenCV Issue #6517, OpenLightingProject Issue #1125).
sudo apt-get install -y build-essential cmake pkg-config
sudo apt-get install -y libjpeg-dev libtiff5-dev libjasper-dev libpng-dev
sudo apt-get install -y libatlas-base-dev gfortran libeigen3-dev
sudo apt-get install -y libgtk2.0-dev
sudo apt-get install -y libavcodec-dev libavformat-dev libswscale-dev libv4l-dev libxvidcore-dev libx264-dev
wget -O - http://github.com/opencv/opencv/archive/3.4.0.zip > opencv.zip
unzip opencv.zip
cd ~/opencv-3.4.0/
cat<<EOD | patch -p1
--- opencv-3.4.0.orig/cmake/OpenCVPCHSupport.cmake 2017-12-31 15:29:51.550167481 +0000
+++ opencv-3.4.0/cmake/OpenCVPCHSupport.cmake 2017-12-31 15:30:00.500101155 +0000
@@ -24,7 +24,7 @@
ENDIF()
SET(_PCH_include_prefix "-I")
- SET(_PCH_isystem_prefix "-isystem")
+ SET(_PCH_isystem_prefix "-I")
SET(_PCH_define_prefix "-D")
ELSEIF(CMAKE_GENERATOR MATCHES "^Visual.*$")
EOD
mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D INSTALL_PYTHON_EXAMPLES=ON \
-D BUILD_EXAMPLES=ON ..
make -j4
sudo make install
sudo ldconfig
そのほかのパッケージ
$ sudo pip3 install matplotlib scipy pandas scikit-learn scikit-image plotly
pandasのインストールにはそれなりの時間がかかる(1時間くらい).
動作確認
webブラウザで http://raspberrypi.local:8888/ にアクセスして,新しいnotebookを作る.以下を実行できればOK.
import numpy as np
import cv2
import matplotlib.pyplot as plt
print(cv2.__version__)
保存
この時点でのMicroSDをイメージファイルとして保存しておくと,同じことを他のRPiで行いたいときに便利かもしれない.Win32 Disk Imagerを使う場合,MicroSDに2つのパーティションがあるのでどちらのドライブを選択すれば…と迷うが,どちらでもよい.Read Only Allocated Partitions
にはチェックを入れること(そうしないと微妙にサイズが異なるMicroSDに書き込めなくなるというか,そういうことが無いように最初からやや小さめのパーティションを作っておくべきだし,バックアップするときもそれを反映させなさい,ということか?).