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

OSインストール

最新のRaspbianをダウンロードしてmicroSD焼きます。
現時点の最新、2019-07-10-raspbian-buster-lite.imgを使いました。
あと、sudo apt updatesudo apt upgradeも忘れずに実行。

NETCore 3.0インストール

最新のNET Core 3.0をダウンロード、インストールします。
現時点の最新はv3.0.100-preview9

まずはダウンロード。

wget https://download.visualstudio.microsoft.com/download/pr/33387ff2-7687-4564-a90d-28b9539e0d3b/f75a063b80fc5a94a4d35689aee8b108/dotnet-sdk-3.0.100-preview9-014004-linux-arm.tar.gz

RaspbianはARM32なので、Linux.NETCore BinariesにあるARM32をクリックすると、ダウンロードURLを得ることができます。

約113Mbytesのファイルでした。

次に、ダウンロードしたファイルを解凍します。

mkdir -p $HOME/dotnet && tar zxf dotnet-sdk-3.0.100-preview9-014004-linux-arm.tar.gz -C $HOME/dotnet

最後に、環境変数DOTNET_ROOTPATHに、解凍したディレクトリを設定します。
これは.bashrcの最後に以下を追加してログインし直し。

export DOTNET_ROOT=$HOME/dotnet
export PATH=$PATH:$HOME/dotnet

Hello World!

.NETCoreでコンパイル、実行できるか確認します。

dotnet new console -o myApp
cd myApp
dotnet run

Hello World!と表示されれば正常です。

Single-file executables

2回目以降でも、相変わらず起動に時間がかかるのですが、
f:id:matsujirushix:20190908165253p:plain

.NETCore3から使えるようになった(?)、Single-file executablesで、どれくらい起動時間が短縮されるか見てみましょう。

dotnet publish /p:PublishSingleFile=trueで実行ファイルを生成すると、
f:id:matsujirushix:20190908165825p:plain

エラーorz

あ、-rオプションでRuntime Identifierというのを指定する必要があるみたい。

気を取り直して、リトライ。

dotnet publish -r linux-arm /p:PublishSingleFile=true

できたっぽい。
f:id:matsujirushix:20190908170752p:plain

起動がクッソ速くなった。
f:id:matsujirushix:20190908170914p:plain

仕組みについては、ここに書いてあるようです。

ML.NET Object Detection

ML.NET Samplesにある、Object Detectionを動かしてみました。

github.com

Object Detectionサンプル

学習済みモデルTiny Yolo2を.NET Coreコンソールアプリ(+ML.NET)で動かすサンプルプログラムです。

実行

Visual StudioObjectDetection.slnを開いて実行するだけ。

こんな感じで、画像に含まれるオブジェクトをコンソールに表示します。

=====Identify the objects in the images=====

.....The objects in the image image1.jpg are detected as below....
car and its Confidence score: 0.9697261
car and its Confidence score: 0.6674223
person and its Confidence score: 0.5226038
car and its Confidence score: 0.5224892
car and its Confidence score: 0.4675334

.....The objects in the image image2.jpg are detected as below....
cat and its Confidence score: 0.6461141
cat and its Confidence score: 0.6400049

.....The objects in the image image3.jpg are detected as below....
chair and its Confidence score: 0.8405777
chair and its Confidence score: 0.7963627
diningtable and its Confidence score: 0.6056049
diningtable and its Confidence score: 0.3737413

.....The objects in the image image4.jpg are detected as below....
dog and its Confidence score: 0.7608147
person and its Confidence score: 0.6321325
dog and its Confidence score: 0.5967442
person and its Confidence score: 0.5730396
person and its Confidence score: 0.5551758

========= End of Process..Hit any Key ========

また、assets/images/output フォルダに、オブジェクトを検知した結果画像を保存します。

f:id:matsujirushix:20190901115438p:plain

処理時間

ここかな?というところに、Stopwatchを追加して測りました。

var sw = new System.Diagnostics.Stopwatch();
sw.Restart();
IList<YoloBoundingBox> detectedObjects = boundingBoxes.ElementAt(i);
sw.Stop();
Console.WriteLine($"Elapsed time = {sw.ElapsedMilliseconds}");

Surface Pro 4Core i7-6650U@2.20GHz)で、この結果でした。

Elapsed time = 1485
.....The objects in the image image1.jpg are detected as below....

Elapsed time = 1300
.....The objects in the image image2.jpg are detected as below....

Elapsed time = 1299
.....The objects in the image image3.jpg are detected as below....

Elapsed time = 1277
.....The objects in the image image4.jpg are detected as below....

Learn ML.NETのGet started in 10 minutesをやってみた

某氏と話していて「ML.NETいけるんじゃね?」(←だいぶ省略)と興味が湧いてきたのだが、Machine Learningよくわからないマンなので、、、
とりあえず、Get startedがあったので、Windowsでやってみました。

dotnet.microsoft.com

  1. Visual Studioをインストール → VS2019 16.2.3
  2. ML.NET Model Builder拡張をインストール → 16.0.1908.1402
  3. コンソールアプリ(.NET Core)プロジェクトを新規作成 → このときにソリューションとプロジェクトを同じディレクトリに配置しないこと
  4. プロジェクトにMachine Learningを追加 → Sentiment Analysisを選択

Time to trainの時間内に、さまざまなModelを試すみたい。

10秒
f:id:matsujirushix:20190831111821p:plain

30秒
f:id:matsujirushix:20190831111956p:plain

60秒
f:id:matsujirushix:20190831112732p:plain

最後にCodeを選択すると、自動的にソリューションにプロジェクトが2つ追加されました。

f:id:matsujirushix:20190831113410p:plain

ML.NET Model BuilderでTrainして、その結果がmyMLAppML.Modelライブラリとして生成されているようです。

で、myMLAppML.Modelライブラリを利用して推論するサンプルアプリがmyMLAppML.ConsoleAppアプリ

myMLAppML.ConsoleAppアプリのProgram.csを見ると、

MLContext mlContext = new MLContext();
ITransformer mlModel = mlContext.Model.Load(GetAbsolutePath(MODEL_FILEPATH), out DataViewSchema inputSchema);
var predEngine = mlContext.Model.CreatePredictionEngine<ModelInput, ModelOutput>(mlModel);

で、MODEL_FILEPATHからpredEngineを生成して、

ModelInput sampleData = CreateSingleDataSample(mlContext, DATA_FILEPATH);
ModelOutput predictionResult = predEngine.Predict(sampleData);

で、ModelInputをpredEngineに通してModelOutputを得ています。

MODEL_FILEPATHはMLModel.zipを指しており、これが学習済みモデルのようです。

MLModel.zipの中身は、

f:id:matsujirushix:20190831144210p:plain

なんだろ?
ML.NETのクラスをシリアライズした感じなのかな?

Visual Studioさえ入っていれば、VS拡張でササッとできてお手軽でした。

【メモ】IoT Plug and Playのデバイス実装コード

IoT Plug and PlayのAZ3166向けサンプルコードを調査。

github.com

★ ... Azure IoT SDK for C
☆ ... Azure IoT Device Workbench生成コード

main.ino

setup()
  connectIoTService()
    registerDeviceRetry()
      registerDevice()
        IoTHub_Init()★
        prov_dev_set_symmetric_key_info()★
        prov_dev_security_init()★
        Prov_Device_LL_Create()★
        Prov_Device_LL_Register_Device()★
        Prov_Device_LL_DoWork()★
        IoTHub_Deinit()★
    pnp_device_initialize()☆ ---> pnp_device.h/.c

loop()
  pnp_device_run()☆ ---> pnp_device.h/.c
  is_error_max()☆
  invokeDevKitPeripheral()

pnp_device.h/.c

pnp_device_initialize()
  tickcounter_create()★
  DigitalTwinClientHelper_InitializeDeviceHandle()☆
    IoTHub_Init()★
    IoTHubDeviceClient_LL_CreateFromConnectionString()★
    DigitalTwin_DeviceClient_LL_CreateFromDeviceHandle()★
  DeviceinfoInterface_Create()☆
    DigitalTwin_InterfaceClient_Create()★
  SensorsInterface_Create()☆
    DigitalTwin_InterfaceClient_Create()★
  LedsInterface_Create()☆
    DigitalTwin_InterfaceClient_Create()★
    DigitalTwin_InterfaceClient_SetCommandsCallback()★
  ScreenInterface_Create()☆
    DigitalTwin_InterfaceClient_Create()★
    DigitalTwin_InterfaceClient_SetCommandsCallback()★
  SettingsInterface_Create()☆
    DigitalTwin_InterfaceClient_Create()★
    DigitalTwin_InterfaceClient_SetPropertiesUpdatedCallback()★
  DigitalTwinClientHelper_RegisterInterfacesAndWait()☆
    DigitalTwin_DeviceClient_LL_RegisterInterfacesAsync()★
    DigitalTwin_DeviceClient_LL_DoWork()★
  DigitalTwinClientHelper_Check()☆
    DigitalTwin_DeviceClient_LL_DoWork()★
  DeviceinfoInterface_Property_ReportAll()☆
  tickcounter_get_current_ms()★
pnp_device_run()
  SensorsInterface_Telemetry_SendAll()☆
  DigitalTwinClientHelper_Check()☆
pnp_device_close()

digitaltwin_device_client_ll.h

DigitalTwin_DeviceClient_LL_CreateFromDeviceHandle()
DigitalTwin_DeviceClient_LL_RegisterInterfacesAsync()
DigitalTwin_DeviceClient_LL_DoWork()
DigitalTwin_DeviceClient_LL_Destroy()

digialtwin_interface_client.h

DigitalTwin_InterfaceClient_Create()
DigitalTwin_InterfaceClient_SetPropertiesUpdatedCallback()
DigitalTwin_InterfaceClient_SetCommandsCallback()
DigitalTwin_InterfaceClient_SendTelemetryAsync()
DigitalTwin_InterfaceClient_ReportPropertyAsync()
DigitalTwin_InterfaceClient_UpdateAsyncCommandStatusAsync()
DigitalTwin_InterfaceClient_Destroy()

考察

  • スケッチ -> Azure IoT Device Workbench生成コード -> Azure IoT SDK for C
  • 接続は、Privisoning -> IoTHubDeviceClient -> DigitalTwinDeviceClient
  • 低レベルは従来のIoTHubDeviceClientで、その上にDigitalTwinDeviceClientの模様
  • (Device Capability Modelから)Azure IoT Device Workbenchで生成したコードを使うと、項目毎のコールバック実装になる。(mxchip_iot_devkit_impl.h/.c)

Mbed Studioを使ってみた

前提条件

Windowsの場合は、Gitをインストールしておく必要があります。参照

サポートしているボード

今は、Mbed Enabledのボード全てではなく、一部のボードのみ対応しているようです。参照
何気に、Seeed Wio 3Gも入っていますね!

STMのNucleo/Discoveryシリーズが少ないのは意外でした。

インストール

ここからダウンロードして実行するだけ。
現時点のダウンロードファイルはMbedStudio-0.5.3.exeで、約800MBでした。

Getting Started

使い方をさらっと学ぶために、Getting startedをやってみましょう。

  1. ワークスペースを指定
  2. プログラムを作成(mbed-os-example-blinkyを選択)
  3. ターゲットを選択(FRDM-K64F(K64F)を選択)
  4. プロファイルを選択(Debugを選択)
  5. ビルド
  6. 実行

f:id:matsujirushix:20190824204237p:plain

うーん、GUI快適♪

感じたこと

  • mbed-cliも簡単にインストールできるようになっているようですが、こちらのほうがツールが別々にインストールされず1パックになっているので良さげ。
  • やっぱGUI使いやすい。
  • mbed-osのインポートやバージョン切り替えがメチャ早。(メニューにLibrary cacheという文字があるが何者か分からず。mbed-cliのrepository cachingのことかな?)
  • VSCodeのExtensionを追加することができない。これは悲しい。

結論は、かなりオススメなツールでした。
しばらく使ってみようと思います。

Jetson Nanoにファン追加

重いプログラムを走らせなくても、結構温度が上がるJetson Nano。

f:id:matsujirushix:20190818095757p:plain

チョー不安なので、ファンを追加することに。

どんなファンが取り付けできるの?

40mm角のファンが取り付けできるようですが、、、
ネットで検索すると、色々とハマりどころがあるらしい。

qiita.com

公式は、NF-A4x20を推奨しています。

noctua.at

12V品とか5V品とか、PWMとか。間違えやすいオプション設定があるので、購入時は注意しましょう。

  • NF-A4x20
  • 5V
  • PWM (4pin)

入手性が悪くて価格が高騰していたので、ネットを探し回って、送料込み2500円くらいで購入しました。

f:id:matsujirushix:20190818101134p:plain f:id:matsujirushix:20190818101225p:plain

ファンの取り付けネジ

ヒートシンクの穴に、3mmのネジが通らないorz
インチサイズなのかなこれ?

2.6mmのネジだと長いのが入手し辛いので、ヒートシンクの穴を(ダイソーの3mmピンバイスで)大きくしました。
アルミくずが基板に降りかかるといけないので、逆さに持って慎重に慎重に。

f:id:matsujirushix:20190818102052p:plain

ネジはこれらを用意。

  • ステンレス トラスねじ M3x25 4本
  • ステンレス ナット M3 4個

近所のロイヤルホームセンターで、計108円でした。

ファンの取り付け

ネジで止めて、ケーブル繋ぐだけ。

f:id:matsujirushix:20190818102513p:plain

ファンのON/OFF

ファンを取り付けただけでは回転しません。(--;)

sudo jetson_clocksコマンドで、ファンスピードが最大になります。

jetson_clocksについてはこちらが参考になります。 より詳しくしりたい人は、vi /usr/bin/jetson_clocks

結果

36℃くらいで安定になりました。(そもそも、部屋が暑い。)
ファンが分厚くて気に入らないので、もうちょっと薄いファンにしたい。

Jetson NanoでAzure IoT Edgeを動かす

Jetson Nanoで、Azure IoT Edgeが動くか確認します。

Jetson NanoにOSをセットアップ

こちらの手順に沿って、OSイメージをマイクロSDに書き込んでブートします。

developer.nvidia.com

現時点のOSイメージファイルはjetson-nano-sd-r32.2-2019-07-16.zipでした。

OSバージョンを確認

/etc/os-releaseuname -aで、OSバージョンを確認。

matsujirushi@jetsonnano:~$ cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.2 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.2 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
matsujirushi@jetsonnano:~$ uname -a
Linux jetsonnano 4.9.140-tegra #1 SMP PREEMPT Tue Jul 16 17:04:49 PDT 2019 aarch64 aarch64 aarch64 GNU/Linux
matsujirushi@jetsonnano:~$

Ubuntu 18.04.2 LTSaarch64でした。

Azure IoT Edgeのサポート状況

Azure IoT Edgeのサポート状況を確認すると、Ubuntu 18.04 ARM64はTier 1だがPublic preview

f:id:matsujirushix:20190812155313p:plain

Azure IoT Edgeをインストール

Azure IoT Edgeのインストール手順に従って、インストールします。

docs.microsoft.com

Jetson NanoのOSイメージにcurlが入っていなかったのでインストール。

sudo apt update
sudo apt install curl

インストール手順を実施。

curl https://packages.microsoft.com/config/ubuntu/18.04/multiarch/prod.list > ./microsoft-prod.list
sudo cp ./microsoft-prod.list /etc/apt/sources.list.d/
curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
sudo cp ./microsoft.gpg /etc/apt/trusted.gpg.d/
sudo apt-get update
sudo apt-get install moby-engine

エラー発生。

moby-engine (3.0.6) を展開しています...
dpkg: アーカイブ /var/cache/apt/archives/moby-engine_3.0.6_arm64.deb の処理中にエラーが発生しました (--unpack):
 '/usr/bin/docker-proxy' を上書きしようとしています。これはパッケージ docker.io 18.09.2-0ubuntu1~18.04.1 にも 存在します
dpkg-deb: エラー: ペースト subprocess was killed by signal (Broken pipe)
処理中にエラーが発生しました:
 /var/cache/apt/archives/moby-engine_3.0.6_arm64.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)

あぁ、なるほど。Dockerが既に入っているので、moby-engineでエラーなのか。

mobyの部分はスルーして継続。(マイクロソフトmoby-engineを推奨しているので、今回は推奨外の構成になります。)

sudo apt-get update
sudo apt-get install iotedge
sudo vi /etc/iotedge/config.yaml
sudo systemctl restart iotedge

とりあえず、Runtimeは動いてる感じ。

サンプルのモジュールを動かす

Simulated Temperature Sensorをデプロイしてみて、Azure IoT Hubにメッセージが送られてくるか確認。

f:id:matsujirushix:20190812165827p:plain

ちゃんと動いています。