Raspbian Stretch Lite (CUI のみの環境で) Docker コンテナにいる Julia の グラフ描画結果を fbi によって描画する

# 本日は

先日は Raspbian Stretch with desktop （要するに普通のPCの感覚でGUIが使える環境） を OS とする　RaspberryPi3 上で Julia 環境を Docker を用いて構築しました.

もちろんCUIの環境 Raspbian Stretch Lite でも動かすことができます。
今回はCUIの環境で動かしてみましょう。そして画像などを画面上に描画してみましょう。

# 環境構築(前提）

ラズパイ布教用にセットアップも書いておこうと思います。

[sentdexさんのYouTubeのチュートリアル](https://www.youtube.com/watch?v=RpseX2ylEuw&list=PLQVvvaa0QuDesV8WWHLLXW_avmTzHmJLv&index=1) も参考になります。

## Raspbian の導入
[Raspbian Stretch Lite](https://www.raspberrypi.org/downloads/raspbian/) のイメージをダウンロードします。なんか３つあるんだけれど(´・ω・｀)と戸惑いますが左下の Lite のやつを選択します。Download ZIPを押します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/135978/a822c2d4-eff9-0864-544c-deecfa35839d.png)

これを解凍したイメージをマイクロSDカードに焼きます。個人的には Etcherが便利だと感じます。 Windows, Mac, Ubuntuどれでも使えてます。

https://www.balena.io/etcher/

ラズパイにSDカードを指して起動すると見慣れた黒いターミナルが開くと思います。これでベース環境が整いました。

Docker の導入はこちらに書きました。

- [RaspberryPi 3 で 動作する Julia 環境を Docker で構築します。](https://qiita.com/SatoshiTerasaki/items/09c019c8742eacc2dff0)

# HDMIでモニターと接続

ラズパイをメイン機として使うなど、キーボード、モニターを直接ラズパイに接続して運用する場合を想定しています。
画像描画はフレームバッファを制御することで実現させる方法がよく知られているようです。

## Dockerを使わない場合

```console
$ sudo apt install fbi
# 引数やオプションを確認
$ fbi -help
This program displays images using the Linux framebuffer device.
Supported formats: PhotoCD, jpeg, ppm, gif, tiff, xwd, bmp, png,
webp. It tries to use ImageMagick's convert for unknown file formats.

usage: fbi [ options ] file1 file2 ... fileN

    -h  -help               print this help text 
    -V  -version            print fbi version number 
        -store              write cmd line args to config file 
    -l  -list <arg>         read image filelist from file <arg> 
    -P  -text               switch into text reading mode 
    -a  -autozoom           automagically pick useful zoom factor 
        -(no)autoup           like the above, but upscale only      
        -(no)autodown         like the above, but downscale only    
        -(no)fitwidth         use width only for autoscaling        
    -v  -(no)verbose        show filenames all the time             
    -u  -(no)random         show files in a random order            
    -1  -(no)once           don't loop (for use with -t)            
        -(no)comments       display image comments                  
    -e  -(no)edit           enable editing commands (see man page)  
        -(no)backup           create backup files when editing      
        -(no)preserve         preserve timestamps when editing      
        -(no)readahead      read ahead images into cache            
        -cachemem <arg>     image cache size in megabytes           
        -blend <arg>        image blend time in miliseconds         
    -T  -vt <arg>           start on virtual console <arg>          
    -s  -scroll <arg>       scroll image by <arg> pixels            
    -t  -timeout <arg>      load next image after <arg> sec without user input 
    -r  -resolution <arg>   pick PhotoCD resolution (1..5)          
    -g  -gamma <arg>        set display gamma (doesn't work on all hardware) 
    -f  -font <arg>         use font <arg> (anything fontconfig accepts) 
    -d  -device <arg>       use framebuffer device <arg>            
    -m  -mode <arg>         use video mode <arg> (from /etc/fb.modes) 

Large images can be scrolled using the cursor keys.  Zoom in/out
works with '+' and '-'.  Use ESC or 'q' to quit.  Space and PgDn
show the next, PgUp shows the previous image. Jumping to a image
works with <i>g.  Return acts like Space but additionally prints
prints the filename of the currently displayed image to stdout.
# さぁ画像を描画してみよう
$ fbi -T 1 nanikano_gazou.png
```

fim というのもあるみたいですね。

- [How to Display Images on Raspbian Command Line with fim](https://www.raspberrypi-spy.co.uk/2014/09/how-to-display-images-on-raspbian-command-line/)

どちらでもいいと思います。

## Dockerを使う場合

あまり情報がなかったのでいろいろトライアンドエラーをして以下のように落ち着きました。

```console
$ cat run_container.sh
sudo docker run --rm -it --privileged \
-v ${PWD}:/work \
-w /work \
terasakisatoshi/myjulia:linux bash
$ bash run_container.sh
root@xxxxxxx # julia
julia > savefig(plot(sin, -pi, pi), "sin_curve.png")
julia> exit()
root@xxxxxxx # fbi -T 1 -t 1 -1 sin_curve.png
```

`/dev/tty1` へのパーミッション問題で苦しみました.
-d でオプションで通してもいいんですが、fbi 実行ご画面が真っ暗でなんもできない。最終的には
`--privileged` オプションを有効にすることで落ち着きましたがまだモヤモヤする。

- [Docker privileged オプションについて](https://qiita.com/muddydixon/items/d2982ab0846002bf3ea8)

fbi コマンドで `-t 1 -1` をする理由はこのオプションをつけておかないと画像を描画した後元のターミナルに戻ってこない場合があるからです。 `-1` がミソっぽい。 Docker使わない場合はスムーズに切り替えられるんですけどね・・・。
一方で fim を使おうとすると真っ暗な画面しかでないので今は諦めています。

- [Kill fbi frame buffer process, after x time
](https://stackoverflow.com/questions/16990522/kill-fbi-frame-buffer-process-after-x-time)

## 動かしている様子

![image.png](https://qiita-image-store.s3.amazonaws.com/0/135978/f2d4c633-02d9-ee77-65fd-659db1fca28a.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/135978/50430563-16b9-b4d7-5181-b1ab6c93302c.png)

## shell でラップする

こんな感じの `run.sh` をつくっておいて 

```shell
#!/bin/bash
sudo docker run --rm -it --privileged \
-v ${PWD}:/work \
-w /work \
terasakisatoshi/myjulia:rpi3 "$@"
```

`$ chmod +x run.sh` で実行権限与えておけばコンテナの中で`やりたい`ことを `./run.sh やりたいこと` で実現できます。

```
# ラズパイのターミナルの中で操作

# Julia のコードを動かす
$ ./run.sh julia somefile.jl
# Python のコードを動かす
$ ./run.sh python somefile.py
# 対話コンソールが出る
$ ./run.sh bash
# PythonのREPLがでる
$ ./run.sh python
# Julia のREPLがでる
$ ./run.sh julia
# これでもよい
$ ./run.sh
```

# SSH で操作する

```console
# Mac terminalで操作。 -X　オプションを忘れずに！
$ ssh -X pi@raspberrypy.local
# on RPI3 terminal
$ cat run_container.sh
docker run --rm -it \
-e DISPLAY=$DISPLAY \
-v $HOME/.Xauthority:/root/.Xauthority:rw \
--net host \
-v $(pwd):/work \
-w /work \
terasakisatoshi/myjulia:rpi3 bash
$ bash run_container.sh
# imagemagick の機能を使う
root@xxxxxx# display your_image.png
```

Dockerの引数は次のリンク先を参考にしました。

- [SSH 接続先で走っている Docker コンテナ内で実行した X アプリの GUI を SSH クライアントで表示する](https://qiita.com/aoksh/items/1a386ee87594e67784c4)

# 個人的いろいろチップとデール

## Font size を変える

Full HD のモニターだと文字が小さいのでサイズを変更したいお気持ちがあったので

[How To Change The Command Line Font Size](https://www.raspberrypi-spy.co.uk/2014/04/how-to-change-the-command-line-font-size/)

`/etc/default/console-setup` を開いて下記のように設定します。

```
FONTFACE="Terminus"
FONTSIZE="16x32"
```


## Caps lock キーを Ctrl にする

`/etc/default/keyboard` を nano などのエディタで `XKBOPTIONS` を下記のように設定する。

```
XKBOPTIONS="ctrl:nocaps"
```

## nano のシンタックスハイライト

Julia 用の nanorc を作っている人がいるみたい。うごきました。

- https://github.com/Naereen/nanorc/blob/master/julia.nanorc
- [自分好みにあわせてカスタマイズしてみました](https://gist.github.com/terasakisatoshi/881d69ed67ab1f77e4a3edaadcf5bd91)

私は平和主義なのでエディタは nano でいいんじゃないかな（遠い目）。


Vim, Emacs で環境構築、バリバリ開発できるためのエディタブートキャンプあったら入ってみたいですね。

### micro editor というものがあるらしい

最近知りました。

- [micro editor](https://github.com/zyedidia/micro)
- [いま熱い最新スクリーンエディタmicro ことはじめ](https://qiita.com/tadsan/items/f0747f09ea5ce863f2ec)

で早速なんとなくこんな [感じのキーバインディング](https://gist.github.com/terasakisatoshi/8cdfdd229bb82ba18ddc77700b3f9332) にしてみました。

### さいきんいーまっくすもなれてきた

[こんなかんじのせってい](https://gist.github.com/terasakisatoshi/feecfc1d3161618630fbf68f93c39d9e)
でテーマを変えることができるようです。ファイル名は `hoge-theme.el` という命名で管理しないといけないです。

ラズパイのCUIにおいてEmacsで表示できる色を `M-x list-color-display`  でみると
`black, red, green, yellow, blue, magenta, cyan, white` となかなか制限のあるテーマの設定をする必要があることがわかりました。（回避策ありましたら喜ぶ人が増えると思います。）

## ターミナルウィンドウを調節したい

GNU screen を用いています。 screen vs tmux 的なのもあるみたいですが、正直なところどっちでもいいともいます。

screen はモニターが一枚という物理制約の中で情報量を多く取るのに便利ですね。

~/.screenrc に色々と設定を書き込んでいます [例えばこんな感じ](https://gist.github.com/terasakisatoshi/34716057e076753faaeb7f5f0f6615a6).

```
vbell off
```

をしておくと screen 起動中に何かコマンドミスやエラーが起きた時に画面がチカチカする(画面を点滅させて視覚的にベルを鳴らす)のを抑えるのに役立ちます。ベルは結構目を刺激するのでOFFにしておいた方が良いでしょう。（英語で visual bell という概念があるのを知りました）。

- [How do I completely disable bell in screen (both visual and audio)
](https://stackoverflow.com/questions/23813869/how-do-i-completely-disable-bell-in-screen-both-visual-and-audio)

## SSHするとき IP 忘れた

複数台LANに接続していなければこれで問題ない.

```
$ ssh pi@raspberrypi.local
```

複数台管理するときはHostnameを変更することをおすすめします。

```
$ ssh pi@henkousitahostname.local
```

的なので行けるはず。

## ラズパイ以外のPCからファイルを編集したい

sshfs を知った時は感動しましたね。

```console
# MacやUbuntuのターミナルで操作する
$ mkdir rpiwork
$ sshfs pi@raspberrypi.local:/home/pi/work rpiwork
$ cd rpiwork
$ ls
ラズパイに入っているファイルが列挙される
```

最近だとVSCodeでいろいろ操作なんてのもあるみたいです。

ソフトウェア学習コスト高くない？