第587回 ではRISC-Vベースの“ AIoTカメラ” であるM5StickV の使い方を紹介しました。今回はM5StickV向けアプリケーションを開発する上で、あると便利なIDEの使い方を紹介しましょう。
MaixPy IDEとは
第587回 でも紹介したように、M5StickVはFreeRTOSの上でPythonが動いています。このPythonの実装が、MicroPython ベースのMaixPy です。MaixPyにはM5StickVのハードウェア関連のライブラリも取り込まれていますので、開発者は原則としてMaixPy/Pythonを用いてアプリケーションを作ることになります。
一般的な開発者であれば「自分の好みのエディター・開発環境」があるはずです[1] 。Pythonである以上、どのエディターでも問題にはならないでしょう。もちろん「公式が推奨するIDE」といった抽象的な選択肢もまた、「 自分の好み」の範疇です。ただし普通のテキストエディターをテキストエディットの機能だけ使うのであれば、M5StickVの開発は若干手間がかかるかもしれません。なぜなら作ったコードをテストしようとしたら、microSDカードに保存し、M5StickVに接続し、M5StickVをリセットする必要があるためです。
ひとつの解は第587回 の最後に紹介したMircopython-Editor を使う方法です。要するにM5StickVの実行環境上でテキストエディターを動かし、シリアルコンソール経由でエディットする方法です。実行環境上のファイルをちょっと変更したい場合は便利ですが、より本格的に開発しようとなるといろいろ機能不足な感は否めません。
そこで出てくるのが、今回紹介するMaixPy IDEです。GUIベースのIDEには、Pythonスクリプトの編集・実行機能、簡易的なコード保管機能、シリアルコンソールの取得に加えて、実行時カメラのライブ映像やカラーヒストグラムの表示まで備わっています。
図1 カメラの映像まで表示してくれる
もともとはカメラ搭載マイコン「OpenMV」向け開発環境OpenMV IDE を、M5StickVをはじめとするSiPEED製品用に作り直したものです。OpenMV IDE自身はQtCreatorがベースになっている ようです[2] 。
[2] OpenMV IDE/QtCreatorがベースになっていることから、MaixPy IDEのソースコードも公開されているだろうと探したのですが見つけられませんでした。Python環境であるMaixPyのGitHubサイト にIDE関連の不具合が報告されているため、MaixPy IDEとして公開されているソースコードリポジトリは今のところ存在しないのかもしれません。
MaixPy IDEのダウンロードと実行
MaixPy IDEはM5StickV Quick Startの「MaixPy IDE」 からインストーラーバイナリをダウンロードできます。2019年10月5日時点での最新版は「v0.2.4」です。プルダウンメニューから「linux-x86_64-0.2.4.run」を選択してダウンロードしてください。ちなみに120MBほどあります。
ダウンロードしたら実行権限を付けて実行しましょう。端末を開いて次のように実行します。
$ cd ~/ダウンロード
$ chmod +x maixpy-ide-linux-x86_64-0.2.4.run
$ ./maixpy-ide-linux-x86_64-0.2.4.run
GUIのみで行いたい場合はファイルブラウザーから該当ファイルを右クリックし、プロパティの「アクセス権」タブにある「プログラムとして実行可能」にチェックを入れて閉じます。再び右クリックすると「実行」が表示されるので、それを選択してください。
インストール手順自体は単に「次へ」を押していくだけです。
図2 インストールウィザードの開始
図3 インストール先の設定(500MB程度の空きが必要)
表示上は390MBになっていましたが、インストール後にdu
コマンドで見ると521MBでした。
図4 使用許諾への同意
図5 インストールの開始
図6 進捗状態の表示
図7 インストールの完了とMaixPy IDEの起動
インストールが完了したらMaixPy IDEを起動します。ちなみにMaixPy IDEの中からM5StickVのシリアルコンソールに接続するため、実行者の権限で「/dev/ttyUSB0
」などへのアクセス権が必要です。たとえば第587回 で紹介しているようにdialoutグループに所属しておいてください。
端末から直にMaixPy IDEを起動するなら、次のように実行します。
$ ~/maixpyide/bin/maixpyide
うまく起動できるようなら第433回 のように「.desktop
」ファイルを作っておくとよいでしょう。
MaixPy自体は非常にシンプルな画面です。ファイルを選択して、それを編集し、実機上で実行する、それだけです。
図8 MaixPy IDEの基本画面
初回起動時はあらかじめターゲットボードを選択しておいてください。「 ツール」の「Select Board」から「M5StickV」を選びます。
図9 ターゲットボードの選択
次にM5StickVをPCに接続し、MaixPy IDEから操作できるよう接続します。具体的には画面左下の緑色の鎖アイコンをクリックしてください。うまく行けば赤色のアイコンに変わるはずです。
図10 ターゲットボードの接続
選択しているPythonスクリプトを実行するには、画面左下の再生ボタンを押します。うまく動作すればカメラの映像が「フレームバッファ」に表示され、さらにカメラの映像に合わせてヒストグラムが変化するはずです。
図11 スクリプトの実行
画面中のスクリプトは「print(clock.fps())
」とFPSの値を標準出力に表示しています。画面下の「シリアルターミナル」を選択すると、標準出力の内容を表示するウィンドウが現れます。
図12 シリアルターミナルの表示
これでMaixPy IDEによる開発環境が整いました。あとは「いい感じ」のPythonスクリプトを書くだけですね。
シリアルコンソールが必要なGUIアプリをLXDで動かす
MaixPy IDEはインストーラー・実行環境ともにバイナリでのみ提供されているように見えます[3] 。どのようにビルドされたか不明なバイナリを、ホスト上で直接実行することに、そこはかとない不安を感じる人もいるかもしれません。
そこで今回は、MaixPy IDEをLXDコンテナ上で動かす方法も紹介しましょう。LXD上でGUIアプリケーションを動かす方法はこれまでにも、Scratch 2.0をLXD上で動かした第416回 、VivaldiをLXD上で動かした第420回 、Windows版のKindleをLXD上のWineで動かした第433回 で紹介してきました。これらはいずれも「X転送 over SSH」を利用して実現しています。今回はより効率的なX用のUnixドメインソケット「/tmp/.X11-unix/X0
」をホストとコンテナで共有する方法を解説します。
さらにM5StickVのようなホットプラグ可能なUSBシリアルコンソールをコンテナと共有する方法も合わせて紹介します。
あらかじめ次のようにMaixPy IDE用のコンテナを「maixpy」の名前で作成しておきます。LXDそのもののインストールや使い方については第521回 を参照してください[4] 。
$ lxc launch ubuntu:18.04 maixpy
Creating maixpy
Starting maixpy
[4] 本連載のLXD記事をベースにいくつか修正・追記を行った『ふわっと知りたいLXD』を技術書典7で公開しました。電子書籍版はBOOTH で、物理冊子版(電子書籍版ダウンロードコード付き)はとらのあな (通販サイトに加えて秋葉原店の技術書コーナーでも)とBOOTH で販売しているので、インターネットを活用できない環境でLXDを利用したい方はぜひご購入ください。なおBOOTHの物理書籍版は10月6日時点でまだ「入荷待ち」のようです。
GUIコンテナを作成する
今回の記事でいう、「 GUIコンテナ」とはホストとコンテナでX Window SystemのUnixドメインソケットを共有するコンテナを意味します。つまりホスト上ではXサーバーが動作していることが前提となります。さらにコンテナの中で動かせるのはX Window Systemに対応したアプリケーションのみです。Waylandオンリーなアプリケーションは今回の方法だけでは動作しませんので注意してください。GPUデバイスは共有しますので、コンテナに関連ライブラリーさえインストールされていれば、GPUアクセラレーションは機能します。
X Window SystemのUnixドメインソケット「/tmp/.X11-unix/X0
」はディスプレイマネージャーでログインした際のアカウントで作成されます。よってホストとコンテナでこのUinxドメインソケットを共有する場合は、コンテナの内外で同じUIDである必要があります。
$ ls -l /tmp/.X11-unix/X0
srwxrwxrwx 1 shibata shibata 0 10月 5 15:25 /tmp/.X11-unix/X0
ホストとコンテナの間でUIDを一致させる方法は第479回 に記載しています。とりあえずUbuntuコンテナ上の初期ユーザー「ubuntu」のUIDとGIDをそれぞれホストのインストール時に作成したユーザーのUID・GIDと同じ1000に設定したい場合は、次のコマンドを実行してください。
$ lxc config set maixpy raw.idmap 'both 1000 1000'
これはコンテナの再起動後から反映されます。しかしながら他にも設定項目があるので、先にそれを行ってしまいましょう。
Xアプリケーションを動かすためには、環境変数DISPLAY
が設定されている必要があります。これは通常はGUIログイン時に自動的に設定されるものです。LXDのGUIコンテナの場合、GUIログインはしないので明示的に指定する必要があります。普通に目の前のPCに自分自身のみがログインしているケースだとDISPLAY
には「:0
」が設定されているはずなのでハードコードしてしまいましょう。
$ lxc config set maixpy environment.DISPLAY ':0'
次にホスト上の/tmp/.X11-unix/X0
をコンテナからもアクセスできるようにします。ちなみにこの「X0
」の部分もログイン状態で変わりえます。LXDの文脈で言うdiskデバイスタイプで追加すると、コンテナからもアクセスできるようになります。
$ lxc config device add maixpy X0 disk path=/tmp/.X11-unix/X0 source=/tmp/.X11-unix/X0
コンテナのgpuデバイスタイプを利用すると、ホストのGPUデバイスにコンテナからもアクセスできます。GPUのアクセラレーション機能を使いたいなら必須です。これも追加しておきましょう。
$ lxc config device add maixpy gpu gpu
さらにX Window Systemアプリケーションを動かすために、必要なライブラリー群をインストールします。
$ lxc exec maixpy apt update
$ lxc exec maixpy -- apt install -y x11-apps x11-xserver-utils mesa-utils
最後にUIDとGIDのマッピングを反映させるために、インスタンスを再起動しておきます。
$ lxc restart maixpy
シリアルコンソールデバイスファイル名を固定化する
次にシリアルコンソールのデバイスファイル名を固定化します。LXDではホスト上のデバイスファイルをそのままコンテナに見せることが可能です。その際、デバイスファイル名を指定するのですが、シリアルコンソールデバイスはその認識順によって自動的に名前が割り振られます。このためM5StickVのようなUSBシリアルケーブルを使う場合、ケーブルをPCに繋いだタイミングによって「/dev/ttyUSB0
」だったり「/dev/ttyUSB1
」だったりと最後の数字が変わってしまうのです。
毎回違うファイル名になってしまうのは不便なので、固定的なデバイスファイル名を付けてしまいましょう。それには第555回 で紹介したudevが役に立ちます。
試しにM5StickVを繋いだ状態で、次のコマンドを入力し、USBデバイスの属性を表示させてみてください。この例の「ttyUSB0
」も、他のUSBシリアルコンソールが接続されている場合は別の名前になるので注意してください。
$ udevadm test-builtin usb_id /sys/class/tty/ttyUSB0
Load module index
Parsed configuration file /usr/lib/systemd/network/99-default.link
Created link configuration context.
ID_VENDOR=Kongou_Hikari
ID_VENDOR_ENC=Kongou\x20Hikari
ID_VENDOR_ID=0403
ID_MODEL=M5Stack_Intf
ID_MODEL_ENC=M5Stack\x20Intf
ID_MODEL_ID=6001
ID_REVISION=0400
ID_SERIAL=Kongou_Hikari_M5Stack_Intf_9952499745
ID_SERIAL_SHORT=9952499745
ID_TYPE=generic
ID_BUS=usb
ID_USB_INTERFACES=:ffffff:
ID_USB_INTERFACE_NUM=00
ID_USB_DRIVER=ftdi_sio
Unload module index
Unloaded link configuration context.
「Kongou Hikari」とはなんぞやというのが気になるところではありますが、今回使うのは「ID_SERIAL_SHORT=9952499745
」です。
一般的にUSBデバイスを特定する際は、ID_VENDOR_ID
やID_MODEL_ID
などを利用します。しかしながら上記の0403:6001はFTDIの「FT232 Serial (UART) IC」として登録されているIDです。つまりID_VENDOR_ID
やID_MODEL_ID
で確認すると、他のFTDI製チップを搭載したUSBシリアルデバイスまでマッチしてしまいます。
よってここでは「ID_SERIAL_SHORT=9952499745
」を用いて確実に特定のデバイスのみをマッチングさせることにしましょう。この値は、各M5StickVで異なるはずですので、それぞれ上記コマンドで確認した値に読み替えてください。
実際に作るデバイスファイルは「/dev/ttyUSBx
」へのシンボリックリンクとなる「/dev/ttyM5STICKV
」です。複数のM5StickVを同時に繋ぐのなら、シリアル番号ごとに名前を変更してください。udevの設定を行うために、ホスト上で次のコマンドを実行します。
cat <<EOF | sudo tee -a /etc/udev/rules.d/68-m5stick.rules
## For M5StickV
ACTION=="add", SUBSYSTEM=="tty", \\
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", \\
ATTRS{serial}=="9952499745", SYMLINK+="ttyM5STICKV"
EOF
この状態でM5StickVを接続すると、次のようなファイルが作られるはずです。
$ ls -l /dev/ttyM5STICKV
lrwxrwxrwx 1 root root 7 10月 6 21:13 /dev/ttyM5STICKV -> ttyUSB0
シリアルコンソールデバイスをコンテナから見えるようにする
M5StickVの接続によって自動的に作成されるようになった「/dev/ttyM5STICKV
」をコンテナから見えるように設定しましょう。
$ lxc config device add maixpy ttyM5STICKV unix-char \
source=/dev/ttyM5STICKV path=/dev/ttyUSB0 \
required=false uid=1000 gid=1000
Device ttyM5STICKV added to maixpy
シリアルコンソールデバイスはキャラクターデバイスとして作られるため「unix-char
」を指定しています。また、コンテナから見える名前は「/dev/ttyUSB0
」にしています。これはMaixPy IDEがどうやら「/dev/ttyUSBx
」しか見ていないような振る舞いをしているためです。
「required=false
」はUSBデバイスのようなホットプラグ可能なデバイス向けのオプションです。つまりコンテナ起動時に指定したデバイスが存在しなくてもエラーにしないための設定となります。UIDやGIDを設定しているのは、コンテナ内の一般ユーザーがシリアルコンソールを読み書きできるための対応です。
設定後の再起動は不要です。最後に実際にM5StickVを接続した状態で、コンテナ内部から「/dev/ttyM5STICKV
」が見えるか確認しておきましょう。
$ lxc exec maixpy ls /dev/ttyM5STICKV
/dev/ttyM5STICKV
MaixPy IDEのインストール
ここまででようやくMaixPy IDEの準備は整いました。あとはホストと同じようにインストーラーを実行するだけです。
ダウンロード済みのインストーラーイメージをコンテナの中にコピーして、lxc exec
コマンドで実行しましょう。ポイントはsudo
コマンドを使って一般ユーザー、Ubuntuコンテナをそのまま使っているなら「ubuntu」で実行していることです。
$ lxc file push ~/ダウンロード/maixpy-ide-linux-x86_64-0.2.4.run maixpy/home/ubuntu/
$ lxc exec maixpy -- sudo -i -u ubuntu ./maixpyide/bin/maixpyide
GUIコンテナとして正しく設定できていれば、ホスト上のディスプレイにインストーラーのダイアログが表示されます。もしうまく起動しない場合は、たとえばldd
コマンドで必要なライブラリーがコンテナ上に揃っているか確認してください。また、インストール後は~/maixpyide/bin/maixpyide
をlxc exec
しましょう。M5StickV上でのスクリプトの実行も含めてきちんと動作することを確認したら、第433回 のように「.desktop
」ファイルを作ると良いでしょう。