Raspberry Pi4にシュミレーターの開発・実行環境を構築する

# はじめに
前回の記事[機械学習の初心者が某ゲームの防御貫通率を機械学習で算出してみる](https://qiita.com/kazuo-matsuda/items/4288dce375ef58b2b504)の続きです。

1. [各種データの収集と戦闘に使用される各種パラメータの算出](https://qiita.com/kazuo-matsuda/items/4288dce375ef58b2b504)
2. 【本記事の内容】シュミレーターの開発・実行環境の構築 
2. 戦闘プログラムの再現
3. 各キャラクターの作成
4. キャラクターと最低限のステータスを入力すると戦闘を再現できるWebコンテンツ
5. 相手と自分のPT情報を入力すると、勝つために必要な今後の行動（強化・キャラ取得）が表示されるシュミレーター

# シュミレーターの開発・実行環境にRaspberry Pi4を選択した理由
マシンパワーが必要なモデルは事前に作成し、AWSのLambdaで構築済みモデルをロードして動かそうと考えていました。
しかし、色々調べた結果、Lambdaの起動とモデルのロードに時間がかかるため、適切ではないと判断しました。

機械学習やDeep Learningが扱える安価な環境やマシンが無いかと探したところ、ちょうどRaspberry Pi4が発売されていました。
シュミレーターだけではなくAI+IoTの環境としても使えると思い、Raspberry Pi4を選択しました。

# 本記事で使用するハードとOS
+ 環境を構築するハード：Raspberry Pi4
+ 環境にインストールするOS：Rasbian Buster
+ 環境構築の準備をするOS：Mac（Catalina）

Raspberry Pi4ですが、電源の差し込み口がマイクロUSBからUSB-Cに変更されています。
また、Raspberry Pi3以前に比べてCPUの発熱量[^1]が上がっています。
Raspberry Pi4用の電源と[ファンが着いたケース](https://www.amazon.co.jp/gp/product/B07WC1P7ZY/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1)を一緒に購入した方が良いと思います。

[^1]: CPUの温度はファン付きのケースでも、アイドル状態で30℃、後述のインストールなどの作業時には40℃になります。

# Raspberry Pi4のヘッドレスセットアップ
Raspberry Pi4のCPUは64bitですが、Rasbianはまだ64bit対応をしていません。
そのため、64bitに対応しているUbuntu Serverをインストールしようと試みましたが、ヘッドレスセットアップに対応していませんでした。

仕方ないので、ヘッドレスセットアップに対応しているRasbianをインストールします。

## Etcherのインストール
SDカードにOSイメージを書き込むため、[Etcher](https://www.balena.io/etcher/)の公式ページからEtcherをダウンロードし、インストールします。

## Rasbian Busterイメージのダウンロード
Rasbian公式ページの[ダウンロードサイト](https://www.raspberrypi.org/downloads/raspbian/)から、Rasbian Busterのイメージをダウンロードします。

## Etcherを使用し、SDカードにUbuntu Serverイメージを書き込み
Etcherを使用し、Ubuntu ServerのイメージをSDカードに書き込みます。
直感的でわかりやすいUIなため、操作方法は割愛します。

## ヘッドレスセットアップに必要なファイルの作成
前項で作成したSDカードをマウントし、ヘッドレスセットアップに必要な下記の2ファイルを作成します。

+ wpa_supplicant.conf
+ ssh

### wpa_supplicant.confの作成
Raspberry Pi4をWiFiでネットワークに接続するために必要なファイルです。
Raspberry Pi4を有線LANで接続できる環境の人は作成不要です。

ファイルの内容は以下です。

``` wpa_supplicant.conf
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=JP

network={
        scan_ssid=1
        id_str="<接続名>"
        ssid="<WiFiのSSID>"
        psk="<WiFiに接続する際のパスフレーズ>"
}
```

家と外出先で接続先のWiFiを切り替える場合、下記のように`network`を複数設定します。
`priority`の数値が小さい順に接続されます。

``` wpa_supplicant.conf
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=JP

network={
        priority=2
        scan_ssid=1
        id_str="<接続名>"
        ssid="<WiFiのSSID>"
        psk="<WiFiに接続する際のパスフレーズ>"
}

network={
        priority=1
        scan_ssid=1
        id_str="out"
        ssid="<WiFiのSSID>"
        psk="<WiFiに接続する際のパスフレーズ>"
}
```

作成した上記の`wpa_supplicant.conf`ファイルをSDカードの直下に書き込みます。

### sshの作成
Macのターミナルを起動し、下記のコマンドを実行しSDカードの直下に`ssh`の空ファイルを作成します。

```
touch /Volumes/<SDカードのマウントポイント>/ssh
```

## Raspberry Pi4の起動
これまでの手順で作成したSDカードをRaspberry Pi4に挿し込み、起動します。

## SSHでRaspberry Pi4にログイン
Macのターミナルを起動し、下記のコマンドを実行しRaspberry Pi4に接続します。
Rasbian OSの初期ユーザーとパスワードは`pi/raspberry`です。

```
ssh pi@<Raspberry Pi4のIPアドレス>
```

Raspberry Pi4のIPアドレスがわからない場合、下記のコマンドでIPアドレスを特定します。
nmapはMacの標準コマンドではないため、[ポートスキャンツールnmapについて](https://qiita.com/SotaAtos/items/29b10a875b0371518d3c)などを参考にnmapをインストールします。

```
nmap -sP <ネットワークアドレス>/24
```

以降の記載は全てログイン先のRaspberry Pi4上で実施します。


## パスワードの変更
下記コマンドでパスワードを初期パスワードから変更します。

```
passwd
```

## ホスト名の設定
DHCPの接続ではIPアドレスが変更される可能性があります。
SSH接続の時、ホスト名でログインできるように下記のコマンドでホスト名を設定します。

```
sudo raspi-config
```

設定メニューが表示されます。
`2 Network Options`→`N1 Hostname`と選択します。
ホスト名の入力画面が表示されます。ホスト名を入力し、`<OK>`を選択します。

以後、`設定したホスト名.local`でRaspberry Pi4へSSH接続が可能です。

# 環境構築
開発とシュミレーターの実行に必要な環境を整えます。

## pipでキャッシュファイルを残さないように設定
キャッシュファイルが残っている場合、pipでのインストールでエラーが発生することがあります。
pipの設定ファイルに下記内容を追記し、キャッシュを無効化します。

``` /etc/pip.conf
[global]
no-cache-dir = false
```

## 機械学習・Deep Learningで必要なPythonのライブラリをインストール
Pythonの各種ライブラリをインストールします。
`apt`でインストールが可能なものは`apt`でインストールし、`apt`でインストールできないものは`pip3`でインストールします。

```
sudo apt install python-dev libatlas-base-dev gfortran
sudo apt install python3-numpy
sudo apt install python3-scipy
sudo apt install python3-pandas
pip3 install --no-cache-dir h5py
pip3 install tensorflow --no-cache-dir
pip3 install scikit-learn
```

## Mac上のVSCodeからリモート開発で必要なjediをインストール
Mac上のVSCodeからリモート接続して開発する場合、jediが必要になります。
`jedi`を下記コマンドでインストールします。

```
sudo apt install python3-jedi  
```

## AFPでファイル共有サーバーを構築
Raspberry Pi4上に各種ファイルをアップロードする際、簡単にアクセスできるよう`netatalk`を下記コマンドでインストールします。

```
sudo apt install netatalk
```

初期設定のままでは接続ができません。
設定ファイルを下記の内容で更新します。

``` /etc/netatalk/afp.conf
 [Homes]
 basedir regex = /home
```

Mac側で`Finder`を起動し、`移動`→`サーバーへの接続`と選択し、設定画面を表示します。
上部の接続先入力欄に`afp://<Raspberry Pi4のホスト名>.local`を入力し、`接続`をクリックします。
パスワード入力画面が表示されるため、`pi/<変更後のパスワード>`を入力して接続します。

接続完了後、Finderウィンドウの上部にある`pi's home`をFinderのサイドバーの`場所`部分にドラッグアンドドロップします。

## MySQL（mariadb）のインストール
シュミレーターでMySQLの使用を予定しています。
MySQL（mariadb）を下記コマンドでインストールします。

```
sudo apt install mariadb-server
```

下記コマンドで初期セットアップを実施します。

```
sudo mysql_secure_installation
```

対話形式のメニューが開始されます。全て**y**を選択します。

```
〜中略〜
Set root password? [Y/n] y
New password: <設定したいパスワード> 
Re-enter new password: <設定したいパスワード>
Password updated successfully!
Reloading privilege tables..
 ... Success!
〜中略〜
Remove anonymous users? [Y/n] y
 ... Success!
〜中略〜
Disallow root login remotely? [Y/n] y
 ... Success!
〜中略〜
Remove test database and access to it? [Y/n] y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!
〜中略〜
Reload privilege tables now? [Y/n] y
 ... Success!
```

DBのユーザーを作成します。ユーザー名はRaspberry PiのOS上に存在するアカウントを入力する必要があります。

```
sudo mariadb
CREATE USER 'pi'@'localhost' IDENTIFIED BY '<パスワード>';
```

データベースも作成し、先程作成したユーザーに全権限を付与します。

```
CREATE DATABASE <データベース名>;
GRANT ALL ON <データベース名>.* TO 'pi'@'localhost';
```

## Django（Webサーバー）のインストール
機械学習・Deep LearningではPythonを使用するため、WebサーバーもPythonで動作するDjangoを使用します。

### インストール
`sudo apt install python3-django`でインストールされるdjangoのバージョンは1.x系で古いため、2.x版をGitHubより取得してインストールします。

```
pip3 install git+https://github.com/django/django.git@stable/2.2.x  
```

REST APIのサーバーとしても使用するため、DjangoのREST API用のフレームワークを下記コマンドでインストールします。

```
pip3 install djangorestframework  
pip3 install django-filter  
```

### インストール結果確認
Djangoのインストール状態を確認するため、試験用にWebサイトを下記コマンドで作成します。

```
django-admin startproject mysite
```

上記コマンドを実行すると、コマンドを実行したフォルダに`mysite`が作成されます。
作成された`mysite`配下にWebサーバーのプログラムやコンテンツを配置します。

#### 受け付けるホスト名の変更
デフォルト設定では`127.0.0.1`に対してのアクセス以外は拒否されます。
Macからのリクエストを受け付けるため、ホスト名を設定ファイルに記載します。
作成された`mysite`に移動し、下記内容でファイルを更新します。

``` mysite/settings.py
ALLOWED_HOSTS = ['localhost', '<Raspberry Pi4のホスト名>.local']
```

#### サーバーの起動
下記コマンドでWebサーバーを起動します。

```
python3 manage.py runserver <Raspberry Pi4のホスト名>.local:8000  
```

Macでブラウザを起動し、URLに`http://<Raspberry Pi4のホスト名>.local:8000`を入力します。
下記画面が表示されれば、Djangoのインストールは正常に完了しています。

![スクリーンショット 2020-01-02 18.20.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321300/7a3af7bd-cefe-8ebc-62eb-03dd66bd18e4.png)

# 最後に
今回の記事は以上です。
次回は「4. キャラクターと最低限のステータスを入力すると戦闘を再現できるWebコンテンツ」のブラウザからアクセスできるところまでを記事にする予定です。