.NET Core 2.1 SDKをRaspberry Pi 3で動かしてみた

.NET Core SDKRaspberry Piに対応したようなので試してみました。

blogs.msdn.microsoft.com

ラズパイとOS

サポートしているのはRaspberry Pi 2以降で、ARMv6を使ったRaspberry Pi ZeroシリーズはNG。

また、Release NotesにあるSupported OS versionsのLinuxを見ると、Debian 9 / Ubuntu 18.04 のようです。

ARM32 support starts with Debian 9 and Ubuntu 18.04.

なので、

  • Raspberry Pi3 Model B
  • Ubuntu 18.04

でやってみることにしました。

OSインストール

ラズパイ向けのUbuntu 18.04イメージはUbuntu公式からは配布されていないようです。orz
ここに手間をかけたくないなぁ、、、ということで探し回ってみたところ、ここにありました。感謝。

SDFormatterで削除したマイクロSDに、Win32DiskImagerでubuntu-18.04-preinstalled-server-armhf+raspi3.img.xzを書き込んで、ラズパイで起動します。

起動時にサービスがFailしているような、、、気がしましたが、見なかったことにw

無事、OSが動きだしました。

ubuntu@ubuntu:~$ uname -a
Linux ubuntu 4.15.0-1010-raspi2 #11-Ubuntu SMP PREEMPT Tue Apr 24 06:27:17 UTC 2018 armv7l armv7l armv7l GNU/Linux
ubuntu@ubuntu:~$

.NET Core SDKインストール

Installing .NET Core on LinuxのUbuntu 18.04のとおりコマンドを実行します。

ubuntu@ubuntu:~$ wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.asc.gpg
ubuntu@ubuntu:~$ sudo mv microsoft.asc.gpg /etc/apt/trusted.gpg.d/
ubuntu@ubuntu:~$ wget -q https://packages.microsoft.com/config/ubuntu/18.04/prod.list
ubuntu@ubuntu:~$ sudo mv prod.list /etc/apt/sources.list.d/microsoft-prod.list
ubuntu@ubuntu:~$
ubuntu@ubuntu:~$ sudo apt-get install apt-transport-https
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
  apt-transport-https
0 upgraded, 1 newly installed, 0 to remove and 81 not upgraded.
Need to get 1692 B of archives.
After this operation, 152 kB of additional disk space will be used.
Get:1 http://ports.ubuntu.com/ubuntu-ports bionic/universe armhf apt-transport-https all 1.6.1 [1692 B]
Fetched 1692 B in 1s (2880 B/s)
Selecting previously unselected package apt-transport-https.
(Reading database ... 61793 files and directories currently installed.)
Preparing to unpack .../apt-transport-https_1.6.1_all.deb ...
Unpacking apt-transport-https (1.6.1) ...
Setting up apt-transport-https (1.6.1) ...
ubuntu@ubuntu:~$ sudo apt-get update
Get:1 https://packages.microsoft.com/ubuntu/18.04/prod bionic InRelease [2846 B]
Hit:2 http://ppa.launchpad.net/ubuntu-raspi2/ppa-rpi3/ubuntu bionic InRelease
Hit:3 http://ports.ubuntu.com/ubuntu-ports bionic InRelease
Hit:4 http://ports.ubuntu.com/ubuntu-ports bionic-updates InRelease
Get:5 https://packages.microsoft.com/ubuntu/18.04/prod bionic/main amd64 Packages [10.1 kB]
Hit:6 http://ppa.launchpad.net/ubuntu-raspi2/ppa/ubuntu bionic InRelease
Hit:7 http://ports.ubuntu.com/ubuntu-ports bionic-backports InRelease
Hit:8 http://ports.ubuntu.com/ubuntu-ports bionic-security InRelease
Fetched 13.0 kB in 5s (2569 B/s)
Reading package lists... Done
ubuntu@ubuntu:~$ sudo apt-get install dotnet-sdk-2.1
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package dotnet-sdk-2.1
E: Couldn't find any package by glob 'dotnet-sdk-2.1'
E: Couldn't find any package by regex 'dotnet-sdk-2.1'
ubuntu@ubuntu:~$

E: Unable to locate package dotnet-sdk-2.1と、dotnet-sdk-2.1が見つからないエラーになってしまいました。

ログを見ると気になる表記が。

Get:5 https://packages.microsoft.com/ubuntu/18.04/prod bionic/main amd64 Packages [10.1 kB]

おや?

cat /etc/apt/sources.list.d/microsoft-prod.list
deb [arch=amd64] https://packages.microsoft.com/ubuntu/18.04/prod bionic main

おやおや??

仕組みを理解しないまま、漁ってみるが、、、

f:id:matsujirushix:20180617110406p:plain

f:id:matsujirushix:20180617110518p:plain

arm向けのパッケージが見つからない。

どうやら、リポジトリにアップされていないようなので、、、
バイナリをダウンロードして、Installing .NET Core on LinuxのInstallation from a binary archiveのとおり、解凍とパス設定しました。

ubuntu@ubuntu:~$ wget https://download.microsoft.com/download/8/8/5/88544F33-836A-49A5-8B67-451C24709A8F/dotnet-sdk-2.1.300-linux-arm.tar.gz
ubuntu@ubuntu:~$ mkdir -p $HOME/dotnet && tar zxf dotnet-sdk-2.1.300-linux-arm.tar.gz -C $HOME/dotnet
ubuntu@ubuntu:~$ export PATH=$PATH:$HOME/dotnet

dotnetコマンドが使えるか確認。

ubuntu@ubuntu:~$ dotnet

Usage: dotnet [options]
Usage: dotnet [path-to-application]

Options:
  -h|--help         Display help.
  --info            Display .NET Core information.
  --list-sdks       Display the installed SDKs.
  --list-runtimes   Display the installed runtimes.

path-to-application:
  The path to an application .dll file to execute.
ubuntu@ubuntu:~$ cd
ubuntu@ubuntu:~$ dotnet

Usage: dotnet [options]
Usage: dotnet [path-to-application]

Options:
  -h|--help         Display help.
  --info            Display .NET Core information.
  --list-sdks       Display the installed SDKs.
  --list-runtimes   Display the installed runtimes.

path-to-application:
  The path to an application .dll file to execute.
ubuntu@ubuntu:~$

サンプルプログラムを実行してみる

ここ2. Create your app3. Run your appをやってみます。

ubuntu@ubuntu:~$ dotnet new console -o myApp
The template "Console Application" was created successfully.

Processing post-creation actions...
Running 'dotnet restore' on myApp/myApp.csproj...
  Restoring packages for /home/ubuntu/myApp/myApp.csproj...
  Installing Microsoft.NETCore.DotNetAppHost 2.1.0.
  Installing Microsoft.NETCore.DotNetHostResolver 2.1.0.
  Installing Microsoft.NETCore.DotNetHostPolicy 2.1.0.
  Installing NETStandard.Library 2.0.3.
  Installing Microsoft.NETCore.Targets 2.1.0.
  Installing Microsoft.NETCore.Platforms 2.1.0.
  Installing Microsoft.NETCore.App 2.1.0.
  Generating MSBuild file /home/ubuntu/myApp/obj/myApp.csproj.nuget.g.props.
  Generating MSBuild file /home/ubuntu/myApp/obj/myApp.csproj.nuget.g.targets.
  Restore completed in 15.86 sec for /home/ubuntu/myApp/myApp.csproj.

Restore succeeded.

ubuntu@ubuntu:~$ cd myApp
ubuntu@ubuntu:~/myApp$ cat Program.cs
using System;

namespace myApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}
ubuntu@ubuntu:~/myApp$ dotnet run
Hello World!
ubuntu@ubuntu:~/myApp$

おぉー
動いた♪

動いたけど、、、起動するまでに結構時間かかるなぁw

de:code 2018 に参加しました

5/22~23に開催された、de:code 2018にいろいろな立場で参加しました。
(有料イベントのため、発表内容の詳細は伏せます。)

Azure Sphere開発のデモ

4月のRSA Conferenceにマイクロソフトから突如発表された、Microsoft Azure Sphere

www.microsoft.com

SeeedはAzure Sphereのエコシステムパートナーということもあり、、、ブレイクアウトセッションで開発環境のデモンストレーションをしました。

f:id:matsujirushix:20180526204042p:plain

f:id:matsujirushix:20180526213912p:plain

後日、動画公開予定?

MVPパーソナルスポンサー

MVP事務局からMVP方々へ「セッションに関連するサンプルコードもしくはツールを公開したいので協力してちょ。」(意訳)という依頼があり、これは素晴らしい!ぜひとも協力せねばいかん!!と発起、セッションAD22のサンプルを申し込みして審査が通ったので、micro:bitとIoT Edge v2を連携するサンプルコードとドキュメントを提供しました。

f:id:matsujirushix:20180526205509p:plain

f:id:matsujirushix:20180526213440p:plain

当面、de:code参加者だけに公開。(de:code事務局からメールが出ている)

基調講演デモのお手伝い

セッションAD22を担当していたのがさっくるさんですが、基調講演のデモをすることになり、なんか成り行きで後方支援することになりました。(進捗確認とか、進捗確認など)

f:id:matsujirushix:20180526213703p:plain

感じたこと

  • 基調講演デモ、ちゃんと動くか心配で胃が痛かった。(いらぬ心配をしてしまったようだ...)
  • Sphereデモ、いろいろ心配していたけど、とても楽しかった。デモ動いたときに拍手もらえるとか感激。またやりたい。
  • IoTEdgeV2サンプルとドキュメント、ものすごく大変でした。もうね、2ヵ月くらい毎晩やり続けていた。おかげでIoTEdgeV2かなり詳しくなった。ドキュメント力は相変わらず低迷。
  • 開発者(関係者、参加者)の交流が希薄。フルタイム、セッションを聞くことが目的になってしまっているのではないだろうか。

iotedge-scott-or-notを動かす

//Build 2018のVision Keynoteで、Custom VisionRaspberry Piで動かしてScottかどうかを判定するデモ、Scott or notのソースが公開されていたので動かしてみたところ、いくつかハマり所があったので書いておきます。

youtu.be

デモのソース

デモのソースはgithubにアップされています。

github.com

modules配下にあるAzureFunctionContainerCustomVisionContainerStartupContainerの3つが、IoT Edgeで動かすモジュールです。それぞれのフォルダにDockerイメージを作るためのDockerfileとAzureIoTEdge拡張が使用するmodule.jsonがあります。
templates配下には、AzureIoTEdge拡張が使用するRaspberry Pi用とWindows用のdeployment.template.jsonがあります。

[RasPi] IoT Edgeの準備

ハードウェアは、Raspberry Pi 3 BにSense HATとカメラモジュールV2です。
ディスプレイは必須ではありませんが、カメラが撮影した画像が確認できるので、接続しておいたほうが良いです。

OSは、8GBのマイクロSDに2018-04-18-raspbian-stretch-lite.imgを書き込みます。ついでに、boot配下にsshファイルを作っておくと、sshが有効になるので少し便利です。

raspi-configを起動して、カメラとI2Cを有効化、カメラのパッケージをインストールして再起動します。

$ sudo raspi-config
5 Interfacing Options -> P1 Camera
5 Interfacing Options -> P5 I2C

そして、こちらの記事のStep 2からStep 5を実施します。

matsujirushi.hatenablog.jp

必要に応じて、Azure Container Registryの認証情報を設定しておきましよう。

$ sudo iotedgectl login --address decodecr.azurecr.io --username decodecr --password (password)

★追加作業

RTIMULibをホストに入れておかないと後々でエラーになるので、pipでインストールします。モジュールからファイル名指定で参照するので、バージョンを指定するようにしましょう。

$ sudo pip install RTIMULib==7.2.1b1

[PC] 開発環境の準備

わたしの開発環境は、すでに諸々インストールされているので確認できませんが、たぶん下記をインストールすればOKです。

あと、githubからソースをクローンする場合は、Git for Windowsも必要です。(zip形式でダウンロード、解凍する場合は不要です。)

gitコマンドでソースを開発環境にクローンします。

C:\Users\takashi\Desktop>git clone https://github.com/Azure-Samples/iotedge-scott-or-not.git
Cloning into 'iotedge-scott-or-not'...
remote: Counting objects: 65, done.
remote: Total 65 (delta 0), reused 0 (delta 0), pack-reused 65
Unpacking objects: 100% (65/65), done.

★追加作業

StartupContainerモジュールの/usr/lib/python2.7/dist-packages参照がさまざまな問題を引き起こします。(ImportError: No module named requests等)

問題を回避するために、createOptionsを下記に変更しておきましょう。

"createOptions": "{\"Env\": [\"DEVICE=RPI\", \"AZURE_ML_HOSTNAME=CustomVisionContainer\"],\"HostConfig\": { \"Binds\": [\"/home/pi/image:/home/pi/image\", \"/dev:/dev\", \"/usr/local/lib/python2.7/dist-packages/RTIMU.so:/usr/local/lib/python2.7/dist-packages/RTIMU.so\", \"/usr/local/lib/python2.7/dist-packages/RTIMULib-7.2.1b1.dist-info:/usr/local/lib/python2.7/dist-packages/RTIMULib-7.2.1b1.dist-info\" ],  \"Privileged\": true, \"PortBindings\":{\"8082/tcp\":[{\"HostPort\":\"8082\"}]}}}"

[PC] モジュールのDockerイメージをアップロード

templates\raspberry pi\deployment.template.jsonをルートフォルダにコピーします。

C:\Users\takashi\Desktop>cd iotedge-scott-or-not

C:\Users\takashi\Desktop\iotedge-scott-or-not>copy "templates\raspberry pi\deployment.template.json" .
        1 個のファイルをコピーしました。

modules\AzureFunctionContainer\module.jsonmodules\CustomVisionContainer\module.jsonmodules\StartupContainer\module.json内の[registry]を、Azure Container Registryのログインサーバー名に変更します。

f:id:matsujirushix:20180525224043p:plain

AzureFunctionContainerには、Logic Appの呼び出しコードが含まれています。Logic Appを用意するのが手間なので、この部分をコメントにします。

f:id:matsujirushix:20180525224951p:plain

ルートフォルダにあるdeployment.template.jsonを右クリックしてBuild IoT Edge Solutionを選択すると、Dockerイメージを作成、Azure Container Registryにアップロードします。

f:id:matsujirushix:20180525224523p:plain

[PC] IoT Edgeにモジュールを追加

IoT HubのIoT Edgeを設定して、モジュールのダウンロード、実行を指示します。
これらは、開発環境のVisual Studio Codeから設定することができます。

ルートフォルダにあるdeployment.template.jsonを右クリックしてGenerate IoT Edge Deployment Manifestを選択します。すると、config\deployment.jsonというファイルが作成されます。

config\deployment.jsonを右クリックしてCreate Deployment for IoT Edge Deviceを選択、一覧表示されたIoT Edgeから設定先を選択すると、IoT HubのIoT Edgeにモジュールのダウンロード、実行が指示されます。

f:id:matsujirushix:20180525225731p:plain

[RasPi] IoT Edgeを起動

$ sudo iotedgectl start

感想

  • IoT Edge extension for Visual Studio Code、まぁ便利。
  • とはいえ、このExtensionを過信してはいけない。(Arm/x64問題勃発)
  • RasPiのDockerイメージをWindows x64で作成しようとする行為が問題を増している。(RasPiで作成するなら、DockerイメージにRTIMULibを加えるだけなのに...)

Custom Vision on IoT Edge v2 (Docker) on Raspberry Pi

この記事の続きです。

matsujirushi.hatenablog.jp

前回は、Custom VisionのClassificationをDockerFileエクスポートして、UPボード(Ubuntu Server 16.04)で動かしました。今回は、このDockerFileエクスポートをRaspberry Pi 3 Model Bで動かしてみます。

RaspbianとDockerをインストール

過去記事のStep 1からStep 4までを実施して、Raspberry PiにRaspbianとDockerをインストールします。
過去記事のときのRaspbianは2018-03-13-raspbian-stretch-lite.imgでしたが、現在の最新は2018-04-18-raspbian-stretch-lite.imgなので、最新を使ってください。

なお、インストールされたDockerのバージョンは18.05.00でした。

$ docker --version
Docker version 18.05.0-ce, build f150324

DockerでCustomVisionを起動

Custom VisionでDockerFileエクスポートしたzipファイルをRaspberry Piにコピー、解凍して、docker buildします。

(やっぱりDockerFileはDockerfileにリネームが必要でした。)

すると、、、

No matching distribution found for tensorflow==1.5.0というエラーが発生して死亡orz

f:id:matsujirushix:20180513110752p:plain

PyPIのtensorflow 1.5.0にarmのパッケージがアップされていないのが原因のようです。

Dockerfileとrequirements.txt

//Build2018 Vision Keynoteのscott-or-notのソースがgithubに公開されている情報をキャッチしていたので、それを丸写しに参考にDockerfileapp/requirements.txtを書きかえてみました。

さっくるさん情報。アンテナはっておくの大事ですねw

で、書き換えたDockerfileapp/requirements.txtはこちら。

Dockerfile

FROM resin/rpi-raspbian:jessie

ADD app /app

# Install dependencies
RUN apt-get update && apt-get install -y \
        python3 \
        python3-pip \
        wget \
        build-essential \
        libjpeg-dev \
        python3-dev \
        zlib1g-dev

RUN pip3 install --upgrade pip
RUN pip install --upgrade setuptools
RUN pip install -r /app/requirements.txt
RUN pip install http://ci.tensorflow.org/view/Nightly/job/nightly-pi-python3/179/artifact/output-artifacts/tensorflow-1.7.0-cp34-none-any.whl

# Expose the port
EXPOSE 80

# Set the working directory
WORKDIR /app

# Run the flask server for the endpoints
CMD python3 app.py

app/requirements.txt

requests
Pillow
Flask
numpy

DockerでCustomVisionを起動(2回目)

動いたー!

$ docker build -t wio-module .
$ docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
wio-module           latest              6cc21d1089d4        7 seconds ago       739MB
resin/rpi-raspbian   jessie              248c8313f621        3 days ago          126MB
$ docker run -p 127.0.0.1:80:80 -d wio-module
5d455f69689c03de931e5168d938690a7e50b9563dfdf2e8c0aea7a7151e8e59

画像を投げてみる。

$ time curl -X POST http://127.0.0.1/image -H "Content-Type: application/octet-stream" --data-binary @IMG_0015.JPG
{"created":"2018-05-12T15:47:10.400908","id":"","iteration":"","predictions":[{"boundingBox":null,"probability":0.9996511936187744,"tagId":"","tagName":"Wio LTE"}],"project":""}

real    0m3.353s
user    0m0.031s
sys     0m0.040s
$ docker logs 5d455f69689c
Loading model...Success!
Loading labels...2 found. Success!
 * Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
172.17.0.1 - - [12/May/2018 15:47:01] "POST /image HTTP/1.1" 200 -

メモリ使用量は、、、なんか表示されないなぁ。

$ docker stats 5d455f69689c
CONTAINER ID        NAME                   CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
5d455f69689c        practical_mcclintock   0.04%               0B / 0B             0.00%               3.07MB / 12.6kB     13.6MB / 0B         0

感想

  • CustomVision、Raspberry Piでも動いた。
  • 環境構築に時間がかかった。すんなりできてもトータル2時間くらい?

Custom Vision on IoT Edge v2 (Docker)

いままでCustom Visionにはあまり興味が無かったのですが、Build 2018のVision KeynoteでCustom VisionをIoT Edge v2(Docker)で動かしていたようなので試してみました。

Custom Vision

データの用意が簡単そうな、Classificationでやってみることに。compactじゃないと後でDockerfileにエクスポートできないようなので、‘General(compact)`を選びます。

f:id:matsujirushix:20180510212143p:plain

手元に使えそうな、、、Wio LTEとWio 3Gの写真があったのでこれを買いました。

Custom Visonは初めてですが、なんとなくポチポチすれば大丈夫な感じですw
それぞれの写真にWio LTEもしくはWio 3Gのタグを付けます。
どうやら、各タグに最低5枚の写真を用意しなければいけないようです。

f:id:matsujirushix:20180510213136p:plain

で、Trainをポチっと。

f:id:matsujirushix:20180510213326p:plain

なんか出来たっぽい♪

Quick Testで、アップしていない画像をテストしてみます。

f:id:matsujirushix:20180510213457p:plain

あれ?
どちらも0%だと。

気を取り直して、条件良さそうな画像でテスト。

f:id:matsujirushix:20180510213704p:plain

83.7%でWio LTE。ちゃんと動いているようです。

じゃあ、ExportDockerFileを選んでみます。

f:id:matsujirushix:20180510213844p:plain

LinuxWindowsを選ばないといけないようなので、Linuxを選びます。

f:id:matsujirushix:20180510213956p:plain

Dockerfileの入った、zipファイルが取れました。2.57MB。

f:id:matsujirushix:20180510214232p:plain

Docker

手元にあるUPボードのUbuntu Server 16.04にzipファイルをコピー、解凍して、docker buildします。

$ docker build -t wio-module .
unable to prepare context: unable to evaluate symlinks in Dockerfile path: lstat /home/ubuntu/cv/Dockerfile: no such file or directory

あれれエラーw

ファイル名を変更して、再トライ。

$ docker build -t wio-module .
Sending build context to Docker daemon  2.938MB
Step 1/6 : FROM python
latest: Pulling from library/python
3d77ce4481b1: Downloading [=>                                                 ]  1.609MB/54.26MB
534514c83d69: Downloading [======>                                            ]  2.364MB/17.58MB
d562b1c3ac3f: Downloading [==>                                                ]  2.199MB/43.25MB
4b85e68dc01d: Waiting
a60ceaabb01c: Waiting
ba209b7a7239: Waiting
235ce1ab7310: Waiting
bd6e9cb6b441: Waiting

今度は問題なく動き出しました。(これどこにフィードバックしたらいいんだろう、、、まぁ、すでに気づいているはずだ。うんうん。)

10分ほどで完了。
結構デカイな。

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
wio-module          latest              fcc778e06ba7        8 seconds ago       1.1GB
python              latest              d69bc9d9b016        5 days ago          691MB

では、実行してみましょう。

$ docker run -p 127.0.0.1:80:80 -d wio-module
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
4eeaad81e990        wio-module          "/bin/sh -c 'python …"   8 seconds ago       Up 7 seconds        127.0.0.1:80->80/tcp   trusting_lichterman
$ docker logs 4eeaad81e990
 * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)

動いているっぽい。

適当な画像をcurlでPOSTしてみると、

$ time curl -X POST http://127.0.0.1/image -H "Content-Type: application/octet-stream" --data-binary @IMG_0015.JPG
{
  "created": "2018-05-10T13:09:01.371454",
  "id": "",
  "iteration": "",
  "predictions": [
    {
      "boundingBox": null,
      "probability": 0.9996715784072876,
      "tagId": "",
      "tagName": "Wio LTE"
    }
  ],
  "project": ""
}

real    0m1.364s
user    0m0.012s
sys     0m0.028s

オォー

動いているっぽい。

Dockerコンテナのログは、

$ docker logs 4eeaad81e990
 * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
2018-05-10 13:07:15.363135: I tensorflow/core/platform/cpu_feature_guard.cc:137] Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.1 SSE4.2
172.17.0.1 - - [10/May/2018 13:07:16] "POST /image HTTP/1.1" 200 -

POST来てますね♪

Dockerコンテナのメモリ使用量は115MBでした。

$ docker stats 4eeaad81e990
CONTAINER ID        NAME                  CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
4eeaad81e990        trusting_lichterman   0.03%               114.6MiB / 3.274GiB   3.42%               3.28MB / 12.3kB     0B / 0B             13

感想

  • ちょーお手軽簡単に、CustomVisionのローカル実行環境が立てれました。(ただし、Dockerの知識は必要。)
  • 中身はTensorFlowなのでGPUを使ってより高速化が可能?(HTTPのオーバーヘッドも結構ありそう?)

Python + Flask + TensorFlowで動いているようですが、詳しくは後日調べたいと思います。

ペイント3DをEnder-2に3Dプリント

ペイント3Dのライブラリに、なかなか良いコンテンツがあるので、、、3Dプリントしてみたいと思い、やってみました。

ペイント 3D

Windows 10に標準で追加された、ペイントの3D版。

f:id:matsujirushix:20180428161053p:plain

3Dライブラリから、好みのコンテンツを選びます。

今回は着地するワシを選びました。

f:id:matsujirushix:20180428161646p:plain

f:id:matsujirushix:20180428161725p:plain

いやぁ、それにしてもペイント3DのUI、すごいですね。

3D-CAD苦手なわたしでも、チョイチョイと操作できてしまう。

で、メニュー > 名前を付けて保存 > 3Dモデルを選んで、3Dプリンターで読み込めるファイル形式で保存する、、、のですが、GLB,FBX,3MFしか選べません。わたしの3Dプリンター(スライスするソフトはCURAの古いバージョン)がこれらに対応していないので、とりあえずFBXで保存します。

FBX -> STL

Fusion 360にアップロードして、3DプリントでSTLファイルにします。(このとき、3Dプリントユーティリティに送信のチェックは外します)

f:id:matsujirushix:20180428162609p:plain

3Dプリント

わたしの場合は、CURAの古いバージョンでSTLを開いて、GCODEをマイクロSDに書き込み、マイクロSDを3Dプリンターにセットして出力しました。

f:id:matsujirushix:20180428162837p:plain

結果

  • Fusion 360でFBX->STLにコンバートしないといけない。ちょっとめんどい。
  • ペイント3D、UIすごいね。

f:id:matsujirushix:20180428163317p:plain

IoT Edgeランタイムのネットワーク構成

IoT Edge v2はDocker技術を使って、各モジュールを分離して動かしています。
はたして、モジュール間はどういう感じでつながっているのか??疑問だったので調べることにしました。

今回は、IoT Edgeランタイム(システムモジュール)の、edgeAgentとedgeHubを調べました。

Network

各システムモジュールを調べる前に、Dockerに存在するNetworkを確認しておきましょう。

ubuntu@ubuntu:~$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
bc452e56bae2        azure-iot-edge      bridge              local
191c4158859e        bridge              bridge              local
e524d4a26c71        host                host                local
54549f043a71        none                null                local
ubuntu@ubuntu:~$

none, bridge, hostとは別に、azure-iot-edgeというブリッジが存在していました。

edgeAgent

edgeAgentのコンテナ情報を見てみましょう。

NetworkModeがazure-iot-edgeで、azure-iot-edgeネットワークにIP=172.18.0.2、GW=172.18.0.1で繋がっているようです。

ubuntu@ubuntu:~$ docker inspect edgeAgent
[
    {
...
        "Name": "/edgeAgent",
...
        "HostConfig": {
...
            "NetworkMode": "azure-iot-edge",
            "PortBindings": null,
...
        },
...
        "NetworkSettings": {
...
            "Networks": {
                "azure-iot-edge": {
...
                    "Gateway": "172.18.0.1",
                    "IPAddress": "172.18.0.2",
...
                }
            }
        }
    }
]
ubuntu@ubuntu:~$

edgeHub

一方、edgeHubは、NetworkModeがdefaultで、443/tcpと8883/tcpを外部に公開している?みたい。edgeAgentと同様に、azure-iot-edgeネットワークにIP=172.18.0.3、GW=172.18.0.1で繋がっているようです。

NetworkModeがdefaultって何だろう??Dockerよくわからん。

ubuntu@ubuntu:~$ docker inspect edgeHub
[
    {
...
        "Name": "/edgeHub",
...
        "HostConfig": {
...
            "NetworkMode": "default",
            "PortBindings": {
                "443/tcp": [
                    {
                        "HostIp": "",
                        "HostPort": "443"
                    }
                ],
                "8883/tcp": [
                    {
                        "HostIp": "",
                        "HostPort": "8883"
                    }
                ]
            },
...
        },
...
        "NetworkSettings": {
...
            "Networks": {
                "azure-iot-edge": {
...
                    "Gateway": "172.18.0.1",
                    "IPAddress": "172.18.0.3",
...
                }
            }
        }
    }
]
ubuntu@ubuntu:~$

tempSensor

気になったので、センサーデータをシミュレートする、tempSensorモジュールも見てみました。

ubuntu@ubuntu:~$ docker inspect tempSensor
[
    {
...
        "Name": "/tempSensor",
...
        "HostConfig": {
...
            "NetworkMode": "default",
            "PortBindings": null,
...
        },
...
        "NetworkSettings": {
...
            "Networks": {
                "azure-iot-edge": {
...
                    "Gateway": "172.18.0.1",
                    "IPAddress": "172.18.0.4",
...
                }
            }
        }
    }
]
ubuntu@ubuntu:~$

まとめ

コンテナ名 NetworkMode PortBindings 接続ネットワーク 接続ネットワークIP
edgeAgent azure-iot-edge azure-iot-edge 172.18.0.2
edgeHub default 443/tcp,8883/tcp azure-iot-edge 172.18.0.3
tempSensor default azure-iot-edge 172.18.0.4

なるほど。ということは、手作りモジュールはPortBindingsすれば外部からIP接続できるってことか。

うーむ、defaultって何だろう?