Take’s diary

Macとマイコンに関すること--ワクワクの製作日記

Jetson TX1+Openframeworks + ZED で人物認識しながら距離を測定する。

今回の表題は、

 何が何だかわからないと思いますが、次の動画と写真を見て下さい。

          

f:id:TAKEsan:20170111212738j:plain

左がZEDの左側のカメラから取り出した画面。右側がその画像の深度(グレースケールからカラーマップに変えてみた)。キーボードでHキーを打ち込むと、左下にHOG!!が表示されて、人物認識とカメラから人物までの距離測定のはじまりはじまりー。

f:id:TAKEsan:20170111212731p:plain

試しにiMacに表示させた人物写真をZEDに見せると.....認識している!!(距離が0.6m以下だと距離は表示されません)前回と比べるとスピードも内容も格段に進化しました。

 私の姿を認識して、距離を表示してます。TX1上のOpenframeworks、GPU を利用したHogOpenCVの人物認識職別器)で人を検出しながら、ZEDステレオカメラで人物までの距離を認識させるという、何かに役立つような役立たないような実験結果です。

 OpenCVHOGは、GPUを使ってもかなり重い処理。これにZEDの深度認識を組み合わせるのですから、TX1では、持ち前のGPUを最大限使っても悲鳴を上げそう。いつものようにかなり苦労して、やっと13fpsくらいまでになりました。13fpsで遅いって?。いえいえ。この前Intel JouleOpenCL(GPU)を利用して実行した結果が4.4fpsintel i7 6700K CPUオンリー環境で9fps前後ですから、そのスピードに驚嘆!!。しかも対象物までの距離なんか認識させないでですよー。

前回は、

 ofxKuZedアドオンを利用して、TX1上のOpenframeworksでZED カメラを動かして見ました。でも、かなり遅い。ZED SDK に入っているOpenCVサンプルの半分くらいのスピードでした。「面白くない」。原因がZED SDKマトリックスデータをいちいちOpenframeworksのピクセルデータに変換しているからとは分かっていたのですが、ソースを解析するには、このアドオン、あまりにも複雑過ぎます。そこで、もっと簡単なZEDアドオンを探して見ました。それがofxZED https://github.com/andsynchrony/ofxZEDofxKuZEDの作者が参考にしたアドオンだそうです。但し、最新版のZED SDKでは全く動きません。本人が正誤表を作っていますが、これでもダメ。さらに私なりに修正してやっと動きましたが、やはりピクセルデータ変換が災いしてofxKuZedより多少早い程度でした。

 今回はOpenCV のcv::Mat とofPixels間のポインタ受け渡しを利用して、高速にデータ変換が可能なことが分かったopenFrameworksでOpenCV3を使う - Qiitaので、これを利用。ofxZEDアドオンを大幅に変更したものを作りました。

結果は以下の通りです。

f:id:TAKEsan:20170111212813j:plain

ofxKuZed改良版。VGA(672x376)、深度は詳細モード(下に半分写っている白黒画面)で16.49fpsでしたが...。

f:id:TAKEsan:20170111212848j:plain

ofxZED改良版。ofxKuZedと同条件の上に、深度は白黒ではなくOpenCVのカラーマップでマッピングしてかなり負担があるにもかかわらず(3fpsくらい落ちる)、なんと約29fps出てます!!。深度画像なんか必要ない場合は、60fps超えで、HD720(1080x720)の場合は3020fps出ますぞー。

ofxZED改良版について。

 いちいちプログラムを説明してもなんだかなーですので、以下からダウンロード可能にしときました。

   ofxZED.zip

 興味のある方は、中のコメントを確認してみてください(私の理解できている範囲で結構詳細に書いときました)。コンパイル中ofConstants.hやEigenがらみのエラーが出る時は、前回の記事を参考に修正が必要です。

TX1の環境ですが。

  • JetPac 2.3.0以上がインストールしてあること。
  • Openframeworksがインストールしてあること。(以前の記事参照、TX1専用のOF-->ダウンロード可能にしときました!!
  • TX1には通常Openframeworksはインストールできません。インストールするには手順が必要です。最短で実行したい場合は以下の記事を参考に!!

takesan.hatenablog.com

  • Opencv2.4.13以上がインストールしてあること。(以前の記事参照)
  • ZED SDK 1.2.0がインストールしてあること。(以前の記事参照)2017/5/12現在ZED SDKが 2.0になってここで紹介しているプログラムは動きません。修正するつもりですが、バージョンを1.2.0に下げてインストールしてください。
  • ZED ステレオカメラが手元にあること。(当然!!)

※TX1以外のUbuntuマシンでもこのまま動くと思うが未確認。

 ダウンロードしたら解凍して、ofxZEDフォルダをTX1にインストールしたOpenframeworksの中のaddonsフォルダに入れるだけです。コピーが終わったら、ofxZED-->exampleに入って make -j4   でビルド。その後make run で実行です。

 今回は、動くだけです。精度をあまり重視していないので、ZEDのキャリブレーションファイル等は読み込んでいません。

 ofxZED-->srcの中にリンクフォルダzedが存在します。これはZED SDKの中にあるincludeに存在するzedフォルダへのリンクです。このままで良いと思いますがビルド中リンクエラーが出るときは確認して下さい。

HogDescriptorについて。

 OpenCVのHogDescriptorは、細部係数の調整が必要です。調整方法は以下を参考にさせていただきました。

OpenCVとVisual C++による画像処理と認識(13A)----- HOGDescriptorとSVMで人(歩行者)を検出する ----- -----

 この記事中で、検出ウインドウサイズ32x64はOpenCV2.4.13には存在しません。結果的に64x128が一番無難でした。記事の中ではあまり重視していませんがHOGDescriptor::detectMultiScale関数中のscaleの変更は、認識率やスピードの点で、かなり重要でした。参考ソースはCPUだけで実行していますが、今回はGPUライブラリを使っています。

やはり

 Hogは、py-faster-runやCaffeのObjectDetectionと比較すると、認識率ではかなりの開き(背景によって認識率が下がる)があります。次はこれらとZEDの組み合わせでしょうか?どうすればいいんでしょう。誰か教えて。

 

Jetson TX1 + Openframeworks + ofxkuzed で Zedステレオカメラの実験。

前回の記事で

 Jetson TX1にOpenframeworksを動かす環境ができました。どんどん面白い環境ができつつありますが、今回はZedステレオカメラを動かしてみます。この種のステレオカメラとしては、昨今話題になっているIntelのリアルセンスカメが存在します。これはKinectと同じように赤外線センサーで距離を認識するようなので、対象物が周囲と同じ温度になると「多分」距離を認識しなくなります。つまり、炎天下など、外部ではあまり役に立たないことになります。今回のZedステレオカメラは光学式なので、内外部共、周囲の温度の影響は受けませんが、暗闇では当然使い物になりません。両者とも一長一短。せっかくTX1とZEDを持ってるので、認識画像範囲の任意の点で、カメラからの距離を表示させるプログラムをOpenframeworksを使って作って見ました。

※TX1には通常Openframeworksはインストールできません。インストールするには手順が必要です。今まで成功した方はいないと思いますので、最短で実行したい場合は前回の記事を参考に!!

takesan.hatenablog.com

f:id:TAKEsan:20161226215458j:plain

                    今回の機器構成

f:id:TAKEsan:20161226224013j:plain

中央付近をマウスで指定してカメラからの距離を表示させているところ(赤い点と緑の距離)。720pで11fpsくらいです。VGA(672x376)に落とすと18fpsくらいにスピードが上がるので、今回の目標ほぼ達成。

         

 実際に距離を認識している動画。これはカメラ解像度が720p(1080x720)で距離を測定してます。カメラからの距離を確実に判別しているのがわかると思います。

 このZED、基本は2つのカメラを同時に動かして、左右画像を1つの画面に合成して出力しているだけなんです。OpenCVでもステレオカメラで画像深度を測定する例題があります。どうやらフォローするソフトが要なんですね。実行ライブラリはZED SDKをダウンロードすることで手に入りますが、ソースは公開していないようです。まー当然と言えば当然でしょうけど。

 ここの会社が公開しているサンプルとライブラリは、前にも紹介したように、なかなかなんですが、これをOpenframeworksに移植した熱意のある人がいます。「OfxkuZed」。https://github.com/kuflex/ofxKuZed

でも、このaddonは、Windows環境のOpenframeworksしかサポートしていません。Linuxの場合は自分でやってくださいですって。仕方ないので挑戦して見ました。結果的にリンクファイルオプションをどう追加するかだけの問題でした。

 まずZED SDKをダウンロードして、Examplesをビルドします。前バージョンではうまくコンパイルできなかったのですが、V1.2.0になってうまく行くようになりました。で、サンプルの中から、/usr/local/zed/sample/gpu/ogl-->の中にあるどちらかをコンパイルします(mkdir build --> cd build --> cmake .. --> makeの順で実行)。ビルドが成功したら(ここではopenGL_gpu_interropコンパイルした場合)、

/usr/local/zed/sample/gpu/ogl/openGL_gpu_interrop/build/CMakeFiles/ZED_openGL_gpu_interop.dir/link.txtファイル(まさに自分の環境に合ったリンクオプション!!)が、作成されるので、このデータをOpenframeworks環境のプロジェクトフォルダに入っているconfig,makeの中に追加してやります。この方法を使うと、自分の環境によってリンクファイルが自動でカスタマイズされるので超簡単。この前のOpenframeworksのインストールと同じように、真面目に働いているスクリプトが作り出すデータをぶんどっちゃおうという安易な発想です。

 試しにOfxkuZedのお試しサンプルzedExampleの中に入っているconfig.makeを以下に修正。中間付近の PROJECT_LDFLAGS= 以降が該当リンク部分です。多分このままでコンパイルできますが、できない場合は上記ZED SDKのexampleをコンパイルしてlink.txtの中身をコピーして見てください。一応変更したaddonと今回試して見た距離測定プログラムをダウンロード可能にしときます。一今後ZEDを使ったアプリを作成する場合は、このフォルダ(zedExample)をコピーすればOK。

ofxKuZed.zip 直

以下OfxkuZed-->zedExample-->config.make の中身

赤文字部分を追加する。

################################################################################

# CONFIGURE PROJECT MAKEFILE (optional)

#    This file is where we make project specific configurations.

################################################################################

  

################################################################################

# OF ROOT

#    The location of your root openFrameworks installation

#          (default) OF_ROOT = ../../..  

################################################################################

# OF_ROOT = ../../..

  

################################################################################

# PROJECT ROOT

#    The location of the project - a starting place for searching for files

#          (default) PROJECT_ROOT = . (this directory)

#      

################################################################################

# PROJECT_ROOT = .

  

################################################################################

# PROJECT SPECIFIC CHECKS

#    This is a project defined section to create internal makefile flags to  

#    conditionally enable or disable the addition of various features within  

#    this makefile.   For instance, if you want to make changes based on whether

#    GTK is installed, one might test that here and create a variable to check.  

################################################################################

# None

  

################################################################################

# PROJECT EXTERNAL SOURCE PATHS

#    These are fully qualified paths that are not within the PROJECT_ROOT folder.

#    Like source folders in the PROJECT_ROOT, these paths are subject to  

#    exlclusion via the PROJECT_EXLCUSIONS list.

#

#       (default) PROJECT_EXTERNAL_SOURCE_PATHS = (blank)  

#

#    Note: Leave a leading space when adding list items with the += operator

################################################################################

# PROJECT_EXTERNAL_SOURCE_PATHS =  

  

################################################################################

# PROJECT EXCLUSIONS

#    These makefiles assume that all folders in your current project directory  

#    and any listed in the PROJECT_EXTERNAL_SOURCH_PATHS are are valid locations

#    to look for source code. The any folders or files that match any of the  

#    items in the PROJECT_EXCLUSIONS list below will be ignored.

#

#    Each item in the PROJECT_EXCLUSIONS list will be treated as a complete  

#    string unless teh user adds a wildcard (%) operator to match subdirectories.

#    GNU make only allows one wildcard for matching.   The second wildcard (%) is

#    treated literally.

#

#         (default) PROJECT_EXCLUSIONS = (blank)

#

# Will automatically exclude the following:

#

# $(PROJECT_ROOT)/bin%

# $(PROJECT_ROOT)/obj%

# $(PROJECT_ROOT)/%.xcodeproj

#

#    Note: Leave a leading space when adding list items with the += operator

################################################################################

# PROJECT_EXCLUSIONS =

  

################################################################################

# PROJECT LINKER FLAGS

# These flags will be sent to the linker when compiling the executable.

#

# (default) PROJECT_LDFLAGS = -Wl,-rpath=./libs

#

#    Note: Leave a leading space when adding list items with the += operator

#

# Currently, shared libraries that are needed are copied to the  

# $(PROJECT_ROOT)/bin/libs directory.   The following LDFLAGS tell the linker to

# add a runtime path to search for those shared libraries, since they aren't  

# incorporated directly into the final executable application binary.

################################################################################

# PROJECT_LDFLAGS=-Wl,-rpath=./libs

PROJECT_LDFLAGS=-L/usr/lib/aarch64-linux-gnu/tegra   -L/usr/local/zed/lib   -L/usr/local/cuda-8.0/lib64   -L/usr/local/lib -rdynamic /usr/local/zed/lib/libsl_zed.so /usr/local/zed/lib/libsl_depthcore.so /usr/local/zed/lib/libsl_calibration.so /usr/local/zed/lib/libsl_tracking.so /usr/local/zed/lib/libsl_disparityFusion.so /usr/local/zed/lib/libsl_svorw.so /usr/local/zed/lib/libcudpp.so /usr/local/zed/lib/libcudpp_hash.so -lX11 -lpthread -lGLEW -lGLU -lGL /usr/local/lib/libopencv_videostab.so.2.4.13 /usr/local/lib/libopencv_ts.a /usr/local/lib/libopencv_superres.so.2.4.13 /usr/local/lib/libopencv_stitching.so.2.4.13 /usr/local/lib/libopencv_contrib.so.2.4.13 -lglut -lXmu -lXi /usr/local/cuda-8.0/lib64/libcudart.so /usr/local/cuda-8.0/lib64/libnppi.so /usr/local/cuda-8.0/lib64/libnpps.so -lGLU -lGL /usr/local/lib/libopencv_nonfree.so.2.4.13 /usr/local/lib/libopencv_ocl.so.2.4.13 /usr/local/lib/libopencv_gpu.so.2.4.13 /usr/local/lib/libopencv_photo.so.2.4.13 /usr/local/lib/libopencv_objdetect.so.2.4.13 /usr/local/lib/libopencv_legacy.so.2.4.13 /usr/local/lib/libopencv_video.so.2.4.13 /usr/local/lib/libopencv_ml.so.2.4.13 /usr/local/lib/libopencv_calib3d.so.2.4.13 /usr/local/lib/libopencv_features2d.so.2.4.13 /usr/local/lib/libopencv_highgui.so.2.4.13 /usr/local/lib/libopencv_imgproc.so.2.4.13 /usr/local/lib/libopencv_flann.so.2.4.13 /usr/local/lib/libopencv_core.so.2.4.13 /usr/local/cuda-8.0/lib64/libcudart.so /usr/local/cuda-8.0/lib64/libnppc.so /usr/local/cuda-8.0/lib64/libnppi.so /usr/local/cuda-8.0/lib64/libnpps.so /usr/local/cuda-8.0/lib64/libcublas.so /usr/local/cuda-8.0/lib64/libcufft.so -ldl -lm -lpthread -lrt -Wl,-rpath,/usr/lib/aarch64-linux-gnu/tegra:/usr/local/zed/lib:/usr/local/lib:/usr/local/cuda-8.0/lib64

  

################################################################################

# PROJECT DEFINES

#    Create a space-delimited list of DEFINES. The list will be converted into  

#    CFLAGS with the "-D" flag later in the makefile.

#

# (default) PROJECT_DEFINES = (blank)

#

#    Note: Leave a leading space when adding list items with the += operator

################################################################################

# PROJECT_DEFINES =  

  

################################################################################

# PROJECT CFLAGS

#    This is a list of fully qualified CFLAGS required when compiling for this  

#    project.   These CFLAGS will be used IN ADDITION TO the PLATFORM_CFLAGS  

#    defined in your platform specific core configuration files. These flags are

#    presented to the compiler BEFORE the PROJECT_OPTIMIZATION_CFLAGS below.  

#

# (default) PROJECT_CFLAGS = (blank)

#

#    Note: Before adding PROJECT_CFLAGS, note that the PLATFORM_CFLAGS defined in  

#    your platform specific configuration file will be applied by default and  

#    further flags here may not be needed.

#

#    Note: Leave a leading space when adding list items with the += operator

################################################################################

# PROJECT_CFLAGS =  

  

################################################################################

# PROJECT OPTIMIZATION CFLAGS

#    These are lists of CFLAGS that are target-specific.   While any flags could  

#    be conditionally added, they are usually limited to optimization flags.  

#    These flags are added BEFORE the PROJECT_CFLAGS.

#

#    PROJECT_OPTIMIZATION_CFLAGS_RELEASE flags are only applied to RELEASE targets.

#

# (default) PROJECT_OPTIMIZATION_CFLAGS_RELEASE = (blank)

#

#    PROJECT_OPTIMIZATION_CFLAGS_DEBUG flags are only applied to DEBUG targets.

#

# (default) PROJECT_OPTIMIZATION_CFLAGS_DEBUG = (blank)

#

#    Note: Before adding PROJECT_OPTIMIZATION_CFLAGS, please note that the  

#    PLATFORM_OPTIMIZATION_CFLAGS defined in your platform specific configuration  

#    file will be applied by default and further optimization flags here may not  

#    be needed.

#

#    Note: Leave a leading space when adding list items with the += operator

################################################################################

# PROJECT_OPTIMIZATION_CFLAGS_RELEASE =  

# PROJECT_OPTIMIZATION_CFLAGS_DEBUG =  

  

################################################################################

# PROJECT COMPILERS

#    Custom compilers can be set for CC and CXX

# (default) PROJECT_CXX = (blank)

# (default) PROJECT_CC = (blank)

#    Note: Leave a leading space when adding list items with the += operator

################################################################################

# PROJECT_CXX =  

# PROJECT_CC =

 

2017/1/12追記:それから、ofConstants.h にバグがあって、コンパイルエラーになります。これは随分前から指摘があって、まだ修正されていないようです。

Using Eigen library with Makefile (or Eclipse) - linux - openFrameworksに対策が記載されています。

f:id:TAKEsan:20170112135938p:plain

Openframeworksのディレクトリに行き、libs/openFrameworks/utils/ofConstants.hの中身185行目付近に(上図参照)

#ifdef Success

    #undef Success

#endif

を追加します。この後ofxKuZed-->zedExampleに行って make -j4    make run で今回の距離測定アプリの実行確認ができます。

2017/1/27追記:Camera.hpp で include error が出た場合は、/usr/local/zed/inclede/zed/Camera.hpp の最初の方4行について下記のように(赤字部分)自分の環境に合わせて絶対パスを書き込んでください。多分このように直せばOK。

#ifndef CAMERA_HPP

#define CAMERA_HPP

 

#include "zed/Mat.hpp"

#include "zed/utils/GlobalDefine.hpp"

#include </usr/local/cuda-8.0/include/cuda.h>

#include </usr/include/eigen3/Eigen/Core>

#include </usr/include/eigen3/Eigen/Eigen>

#include </usr/local/include/opencv2/opencv.hpp>

 ofxKuZedに入っている標準サンプルを実行してみると....。

 

       

      サンプルプログラムをそのまま実行720pで6fps程度しかスピードが出ません。

 TX1では遅い!!。が、ちゃんと動いてます。 ZED SDKのサンプルと比べるとOpenframeworksの実行画像に変換する手間がある分、スピードは明確に落ちているようです。でも機能を絞ればTX1でも十分に実用スピードになります。何と言ってもOpenframeworks上でのZED稼働により応用範囲が飛躍的に高まりますので、実験には十分な性能です。試しに720pからVGAに変更するとこうなります。

         

カメラ読み取り画像をVGA(672x376)に落とすと11fpsくらいに上がります。さらに不要な処理を削除すれば最大17fps程度にスピードアップ!!

 ZED SDKのExampleは一般受けを狙い3Dで立体化させて「わーっ」と言わせるものが大半ですが、この機器の一押しは画像深度ですから、使う側にとっては、カメラ画像の指定した部分が、カメラからどのくらいの距離か確認できればOKだと思います。一般的な距離センサーで測定できるのは狙った一点だけです。広範囲の測点を同時に計測するのは不可能。ZEDの価値は、その測点での圧倒的な優位性を如何にして利用するかだと、個人的には思ってます。できたのが冒頭の画像です。見た目は単純ですが、これを距離センサーで実現しようとすれば、到底不可能であることが経験者なら理解できると思うんですが。どうでしょうか?。ofxKuZedアドオンのGrayScale関数を利用してるので、0.6〜20mの範囲256段階での距離測定になります。測定上限は20m。上限を2.55mにすると精度は10mmになります(上限20mの場合、精度は78mm)。上限の範囲はキーボードから'0'、'9'を入力することで変更可能です。

 次回はなんと倍くらいにスピードアップ!!。画像中の人物を見つけ出して、その人物までの距離を測定させてみました。

takesan.hatenablog.com

 

                              では、また。

 

Jetson TX1 で Openframeworks 動いた。

諦めかけてたんですよね。

 そもそもTX1のアーキテクチャであるaarch64では、現状Openframeworksのインストールが不可能です。x86-64版でもarm7l版でも......。CPUが違うのだからしょうがない。何回も挑戦しているんですけど全くダメでした。でも、arm7l版を使って、プレビルドライブラリを再コンパイルすりゃー動くんじゃないかって想定のもと、ここ1週間でなんとかなりました。今後Pi3のOSが64bit版にならない限り、Openframeworksのaarc64標準版は発表されないような気がします。で、誰もやってないでしょうから、世界で初めてのインストール成功例だったりして.....。

※2017/1/12:TX1専用のOpenframeworksをアップロードできるようにしました。アップロードされる方は最後の方を確認して下さい。

f:id:TAKEsan:20161219211051j:plain

 鍵を握っているのは、poco、kiss、、tess2、glfw3と呼ばれる4つのライブラリ群と、4つのファイル

config.linuxarmv7l.default.mk、ostype.sh、ofAppGLFWWindow.cpp、config.shared.mk

でした。幸いOpenframeworks内部に、ライブラリ群をインストールするためのapothecaryと呼ばれるスクリプトが存在しているので、再インストールが可能です。が、その都度本来のaarch64をlinuxarmv7lやlinux64に名称を変更して実行させる必要があります。つまり実直なスクリプトを騙してarrch64版をインストールしちゃうという悪どい方法を使います。ファイルに関しては要所を変更すればOK。

 サンプルを動かしたら、なんと実行スピードはiMacと同等!!、逆にiMacより大巾に早いものがいくつかありました。今の所キー入力が難点。大文字のアルファベットと矢印キーだけしか使えません。直ったら紹介しますが、バイナリコードアプリで、TX1がCore i7 3.4GHz+Nvidia GPUが搭載されたiMacに勝つなんて驚くべきことですよね。

        

左がTX1、右がiMacの画面です。Openframeworksのサンプルを同時に走らせているところ。一番時間の必要な画像で、TX1が93fpsiMacが60fps出てます。ちなみにJouleは41fpsくらいです。TX1異常に早い。(iMacが古いといってもCore i7 3.4GHz GPUはGTX675ですよ!!)。Openframeworksには、フレームレートを変更する関数が存在しますが、ここを60fpsに指定するとちゃんと上限が60fpsになるので少し不思議なところ-->スピードリミッター的な部分が外れてしまったのか?

        

   ofxCVというOpenframeworks用のOpenCVアドオンを使って顔認識をさせてます。これも早い。

        

ofxBOX2Dというアドオンのサンプルを実行してます。こんなに早いのは経験無い。なんで早いんだろう? TX1専用のlibGL.soライブラリが相当最適化されている模様。

 前回Intel JouleでもOpenframeworksを動かしましたけれども、画像系の実行スピードは雲泥の差です。Jouleと比較してCPU能力の若干劣るTX1でも、内蔵されているGPU能力の優位性で、こんなにも差が出るなんてすごい。OpenframeworksのZEDステレオカメラアドオンがあり、かなり簡単に画像深度を利用したアプリケーションが作れるみたいなので、今後挑戦してみます。

 TX1に載せたOpenframeworksで、GPIOもMjpeg画像配信も、OSC通信も、ブラウザを介した制御も、高速で簡単に実現できるんです。これは使わない手はない!!。さらに、この前記事にしたTensorRTを使った学習済みディープラーニングライブラリと組み合わせることが実現できたら、Nividiaの難解なCameraライブラリや、画像表示ライブラリを使わなくて済むので、開発が10歩くらい進んでしまいます。

 ※この記事を書いてから1.5ヶ月後。本当に10歩ぐらい進んでしまいました。還暦過ぎて仕事の分野が違っても、ワクワクすればなんとかなるもんですね。

takesan.hatenablog.com

 Openframeworks インストール手順

 インストール手順はピンクの部分です。ピンク文字部分を順番に実行します。途中ファイル内容修正部分は青文字で記述してあります。私のTX1内部eMMCにインストールしているjetpac2.3.0には、何も手をつけていないので、再度インストール確認して見ましたが、下記の方法で問題なく動いています。

● インストールするOS確認

uname -a

表示内容は、

Linux tegra-ubuntu 3.10.96-tegra #1 SMP PREEMPT Wed Sep 28 17:51:08 PDT 2016 aarch64 aarch64 aarch64 GNU/Linux
Jetpack 2.3.0 です。(最新の2.3.1でも可能だと思う)
● 次に、G++のバージョン確認_

g++ --version

表示内容は、

   g++ (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609

最新のJetpacをインストールしていれば特に問題ありません。

● ホームへ移動
cd     でホームへ移動して
Openframeworksダウンロードページからdownload | openFrameworkslinux armv7版をダウンロードして解凍。フォルダ名称をof_v0.9.8とします。(なんでも良いが便宜上。以下そのまま実行できるので)ダウンロードしてフォルダ名称を変更したら、

sudo apt install cmake
nano ~/of_v0.9.8/scripts/apothecary/ostype.sh でostype.shの24行目を以下に変更
  【修正前】elif [ "$ARCH" == "armv7l" ] ; then
  【修正後】elif [ "$ARCH" == "aarch64" ] ; then  にする aarch64に変更

● Openframeworksで使用するライブラリ群のインストール
cd ~/of_v0.9.8/scripts/linux/ubuntu/
sudo ./install_dependencies.sh
アップグレードがあった場合はyでupgradeする。Openframeworksの依存ファイルもyでインストールする。
最後にEnterを押すとpocoインストールとなり、すぐError表示が出てStopするが、気にしない。
● Openframeworks付属のライブラリインストーラapothecaryでpoco、kiss、tess2をaarch64形式でインストール
sudo apt install curl
cd ~/of_v0.9.8/scripts/apothecary
sudo ./apothecary update poco      ——>ビルドに20分以上必要
sudo ./apothecary update kiss
nano ~/of_v0.9.8/scripts/apothecary/ostype.sh  でostype.shの25行目を以下に変更
  【修正前】OS="linuxarmv7l"
  【修正後】OS="linux64" にする。(騙す!!)
sudo ./apothecary update formulas/tess2/tess2.sh   エラーになるが気にしない。
cd ~/of_v0.9.8/scripts/apothecary/build/tess2/Build  ここに行って
make              サンプルファイルmake errorとなるが気にしない。
nano ~/of_v0.9.8/scripts/apothecary/ostype.sh  

でまたまたostype.shの25行目を以下に変更
  【修正前】 OS="linux64"
  【修正後】 OS="linuxarmv7l"   にする。(またまた騙す!!)
今度はpoco、kiss、tess2 のビルドでできた 拡張子.aファイル群(静的ライブラリ)を所定ディレクトリにコピー
cp libtess2.a ../../../../../libs/tess2/lib/linuxarmv7l/
cd ../..                                                –---> apothecary/buildへ移動
cp kiss/libkiss.a ../../../libs/kiss/lib/linuxarmv7l/
cp poco/lib/Linux/aarch64/*.a ../../../libs/poco/lib/linuxarmv7l/
● 入出力関連のライブラリglfw3をaarch64用にビルドして所定ディレクトリにコピー。
cd ~/of_v0.9.8/libs/glfw/lib/linuxarmv7l
git clone https://github.com/glfw/glfw.git
cd glfw
mkdir build
cd build
cmake ..
make -j4
sudo make install
cp src/libglfw3.a ../../ibglfw3.a

● Openframeworksのアプリケーションコンパイルに必要な          

        config.linuxarmv7l.default.mkの内容で全て修正(重ね書き)。
nano of_v0.9.8/libs/openFrameworksCompiled/project/linuxarmv7l/config.linuxarmv7l.default.mk
以下修正内容

###############################################################################
# CONFIGURE CORE PLATFORM MAKEFILE
# This file is where we make platform and architecture specific
# configurations. This file can be specified for a generic architecture or can
# be defined as variants. For instance, normally this file will be located in
# a platform specific subpath such as
#
# $(OF_ROOT)/libs/openFrameworksComplied/linux64
#
# This file will then be a generic platform file like:
#
# configure.linux64.default.make
#
# Or it can specify a specific platform variant like:
#
# configure.linuxarmv6l.raspberrypi.make
#
################################################################################

################################################################################
# include common rules
#
# all linux systems have several rules in common so most of them are included
# from the following file
#
################################################################################

include $(OF_SHARED_MAKEFILES_PATH)/config.linux.common.mk

################################################################################
# PLATFORM CFLAGS
# This is a list of fully qualified CFLAGS required when compiling for this
# platform. These flags will always be added when compiling a project or the
# core library. These flags are presented to the compiler AFTER the
# PLATFORM_OPTIMIZATION_CFLAGS below.
#
# Note: Leave a leading space when adding list items with the += operator
################################################################################
#PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/app/ofAppEGLWindow.cpp
#PLATFORM_CFLAGS = -Wall -std=c++11
PLATFORM_CFLAGS = -Wall -std=c++14 -DGCC_HAS_REGEX

################################################################################
# PLATFORM LIBRARIES
# These are library names/paths that are platform specific and are specified
# using names or paths. The library flag (i.e. -l) is prefixed automatically.
#
# PLATFORM_LIBRARIES are libraries that can be found in the library search
# paths.
# PLATFORM_STATIC_LIBRARIES is a list of required static libraries.
# PLATFORM_SHARED_LIBRARIES is a list of required shared libraries.
# PLATFORM_PKG_CONFIG_LIBRARIES is a list of required libraries that are
# under system control and are easily accesible via the package
# configuration utility (i.e. pkg-config)
#
# See the helpfile for the -l flag here for more information:
# http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html
#
# Note: Leave a leading space when adding list items with the += operator
################################################################################
#check gstreamer version
ifeq ($(CROSS_COMPILING),1)
ifdef TOOLCHAIN_ROOT
#You have specified TOOLCHAIN_ROOT with an environment variable
else
TOOLCHAIN_ROOT = /opt/cross/bin
endif
ifdef GCC_PREFIX
#You have specified GCC_PREFIX with an environment variable
else
GCC_PREFIX = arm-linux-gnueabihf
endif
PLATFORM_CXX = $(TOOLCHAIN_ROOT)/$(GCC_PREFIX)-g++
PLATFORM_CC = $(TOOLCHAIN_ROOT)/$(GCC_PREFIX)-gcc
PLATFORM_AR = $(TOOLCHAIN_ROOT)/$(GCC_PREFIX)-ar
PLATFORM_LD = $(TOOLCHAIN_ROOT)/$(GCC_PREFIX)-ld
SYSROOT=$(RPI_ROOT)
PLATFORM_CFLAGS += --sysroot=$(SYSROOT)
PLATFORM_HEADER_SEARCH_PATHS += $(SYSROOT)/usr/include/c++/5

PLATFORM_LIBRARY_SEARCH_PATHS += $(SYSROOT)/usr/lib/$(GCC_PREFIX)

PLATFORM_LDFLAGS += --sysroot=$(SYSROOT)
PLATFORM_LDFLAGS += -Wl,-rpath=$(SYSROOT)/usr/lib/$(GCC_PREFIX)
PLATFORM_LDFLAGS += -Wl,-rpath=$(SYSROOT)/lib/$(GCC_PREFIX)
PKG_CONFIG_LIBDIR=$(SYSROOT)/usr/lib/pkgconfig:$(SYSROOT)/usr/lib/arm-linux-gnueabihf/pkgconfig:$(SYSROOT)/usr/share/pkgconfig
endif

修正完了したら保存して終了。
● このままでは、キーボードが使えないのでofAppGLFWWindow.cppを修正
nano ~/of_v0.9.8/libs/openFrameworks/app/ofAppGLFWWindow.cpp

1138〜1150行目の修正
【修正前】
        default:
          key = codepoint;
          break;
     }

     ofAppGLFWWindow * instance = setCurrent(windowP_);
     if(action == GLFW_PRESS || action == GLFW_REPEAT){
        instance->events().notifyKeyPressed(key,keycode,scancode,codepoint);
     }else if (action == GLFW_RELEASE){
        instance->events().notifyKeyReleased(key,keycode,scancode,codepoint);
     }
  }
【修正後】試行錯誤の結果妥協した内容 actionに1を加算しないと入力キーを認識しない。
        default:
          key=keycode;
          break;
     }
     ofAppGLFWWindow * instance = setCurrent(windowP_);
     action+=1;
     if(codepoint==0){
         if(action == GLFW_PRESS ){

           instance->events().notifyKeyPressed(key,keycode,scancode,codepoint);
         }
     }
 }
● Openframeworksのアプリケーションコンパイルに必要なconfig.shared.mkを修正
of_v0.9.8/libs/openFrameworksCompiled/project/makefileCommon/config.shared.mk

91行目

   【修正前】 else ifeq ($(PLATFORM_ARCH),armv7l)
   【修正後】 else ifeq ($(PLATFORM_ARCH),aarch64)

Openframeworksのビルド
cd ~/of_v0.9.8/scripts/linux
./compileOF.sh -j4

エラーなければもう一息。エラーがあったら再度上記確認。
● 最後にlibGL.soをTX1専用のものに変更。
cd /usr/lib/aarch64-linux-gnu
sudo rm libGL.so
sudo ln -s /usr/lib/aarch64-linux-gnu/tegra/libGL.so libGL.so

これで一応インストールは終了。お好みのサンプルフォルダに行き(ここでは一番見た目が派手なやつ)
cd ~/of_v0.9.8/examples/3d/3DPrimitivesExample
webcameraをusbに接続して
make -j4
make run
でビルドして、動かすと。ものすごく早い!!(最初の画像参照)。キーボード入力は今の所1〜9、大文字アルファベットのA〜Z、矢印キーしか受け付けません。escキーは使えないので注意。(もっとも操作上はこれだけあれば十分ですけど)サンプルファイルは小文字入力が必要な場合は大文字に変更してください(ofAPP.cpp内部。keyPressed内に書かれた入力処理のみ受け付ける。keyReleasedに書かれている場合は、keyPressed部分に書き換えればOKです)。どうやらglfw3ライブラリに関してTX1の相性が悪いみたいですが、うまく行ったらまた書き込みます。

 TX1専用Openframeworks ダウンロード-->インストール手順

 上記の方法で必要なライブラリをプレビルドしたOpenframeworksがダウンロードできるようにしました。--->of_v0.9.8.zip (はてなブログでファイル容量の制限があるので、OFをシェイプアップするのに時間がかかりました。掲載が遅れてごめんなさい)

 ダウンロードして解凍します。iMacで圧縮したので余計なファイルが入っていますが、対象フォルダはof_v0.9.8です。

まず依存ファイルをインストール。

sudo apt install cmake

cd of_v0.9.8/scripts/linux/ubuntu/

sudo ./install_dependencies.sh 

かなり時間が必要。最後にpocoのインストールを聞かれるが、インストールしない。(インストールしても良いが意味なし。時間の無駄)

次にOFをコンパイル

cd ..
./compileOF.sh -j4

ここまではいつもの手順です。エラーが出る場合は、質問を受け付けますのでコメントを書いて下さい。最後にTX1 特有の変更。
cd /usr/lib/aarch64-linux-gnu 
sudo rm libGL.so
sudo ln -s /usr/lib/aarch64-linux-gnu/tegra/libGL.so libGL.so

これだけです。

 

                                   では また。

Intel Joule はEdisonやPi3 との価格差を超えられるか?

Intel Jouleを色々試してみて

 先月の段階で、Ubuntu developer potalよりUbuntuインストール方法が紹介されています。本体eMMCに自動的にインストールされるのですが、前回私の書いた記事より格段に簡単で、画面が安定している感じなので、今回紹介します。そしてmraaの実装と少し高度な動作確認。さらにはOpenCLの動作確認まで触れて見たいと思います。

f:id:TAKEsan:20161206144546j:plain

                                                                私の最終構成です。

f:id:TAKEsan:20161206144543j:plain

             OpenCLまで動いちゃいました

本体内部eMMCに、Ubuntu16.04をインストールする

 今月の初め(2016/12)にJouleにUbuntu14.04をインストールして、インストール煩雑さの挙句GPIO群が使えないなんて記事を書きました。その後Intel Edison ユーザー会https://www.facebook.com/groups/625317624253131/の Hirokazu Egashiraさんにヒントをいただいて、いろいろ試したらとても簡単にインストールできたのでご報告。

 まず、Intel Joule | Ubuntu developer portalに、JouleのUbuntuが発表されていました。最初はUbuntu Coreだけだと思っていたのが大間違いで、最後の方に自信なさげにUbuntu desktopインストール方法が書いてあります(Developer setup Install Ubuntu Classic (desktop) on the Intel Joule)。ただ、リンクされたファイル「tuchuck-xenial-desktop-iso-20161006-0.iso」ではインストール用のUSBが作れませんでした。で、諦めかけて以前Ubuntuのインストールで大変参考になった記事Installing Ubuntu on Intel Joule 570x |Intel Communitiesを見ていたら、最後の方にjosephwinstoniiさんがこの件を書いていました(この方は一体誰?)。よく見るとリンク先が違っているようです。本当は、 http://people.canonical.com/~platform/snappy/tuchuck/tuchuck-xenial-desktop-iso-20161006-0.isoだそうです。ダウンロードに、ものすごく時間がかかるのですが、これを使うと簡単にUbuntuインストール用のUSBメモリーが作れます(現在はリンクが治っている可能性がありますが)。あとはUbuntu developer portalの手順に従ってインストールするだけ。注意点はその記事にも書いてありますが、JouleのBIOSBIOS V#131に更新する必要があることです。

 Intelサイトに

software.intel.com

書いてあるんですが、JouleのBIOSをインストールできるのはWindows環境だけです。書き換えにはJouleと付属USB Cをつなぎます(電源は必要なし)が、接続したディバイスは時間が経つと自動的にキレてしまうようなので、最後のスクリプトを実行する前に、Windowsディバイスマネージャーで、接続されていることを確認してから、コマンドプロンプトスクリプトを実行することで上手くいきました。認識していない場合は、USBを刺し直します。これが失敗すると、今回の方法でUbuntuが上手くインストールできないので。確実にクリアすることが必要となります。

 次に自分の母艦環境(WindowsMacLinux)でUbuntuインストール用のUSBメモリを作ってください。あとは、JouleのUSB3.0へキーボード、ディスプレイ、UbuntuインストールUSBメモリを取り付けてBOOTマネージャーからUSBを指定するだけ。

f:id:TAKEsan:20161206151121j:plain

          Jouleを起動させてF2キーを押すと、こんな画面になります。

f:id:TAKEsan:20161206151122j:plain

         Boot Manegierを選択して、EFI USB Deviceを選択します。

 あっという間に本体eMMCにUbuntu16.04がインストールできちゃいます。(あっとといっても20分程度は必要)Reboot後、派手な初期画面が現れた後(2分程度)、途中で言語やキーボード、Wifiの設定を聞かれるので、基本的な環境を入力します。簡単簡単。「前回のは何だったんだろう」みたいな感じでした。ちなみにカーネルは 「4.4.0-1000-joule」で、Joule専用のようです。

 思い切ってOstroとはさよならすることにしました。WindowsLinuxの母艦とクロスコンパイルするならOstoroでも良いとは思いますが、Edison等とは違い、以下の様にSSDUbuntuをインストールすると、ビルドが相当早いので、母艦の必要性を感じなくなります。内部eMMCにインストールしたUbuntuが母艦の代わりとでも言いましょうか。蛇足ですが、容量の少ないJoule内蔵eMMCにインストールしたUbuntuには、apt updateとapt upgradeを実行した後、最小限のアプリのインストールに留めた方がよろしいかと思います。

Usb3.0に接続したSSDUSBメモリUbuntuをインストールする

 このままでも良いのですが、eMMCはもったいない(IntelはeMMCのを信用していない節があちこちに見受けられる)ことと、絶対容量が不足なので、どうしても外部から起動したくなりますが、USB外部記憶装置にインストールが可能です。

 まず本体eMMCで起動したjouleに外部SDやSSDを接続。さらにインストールUSBを接続します。

f:id:TAKEsan:20161206145100j:plain

今回接続しているSSDSanDisk(128Gで12,000円くらい)、キーボード・マウス兼用の無線アダプタ、インストールSDカードはSONY製を使いました。左上は、OpenCLテスト用に作ったSDカード。BuffaloのSDカードリードライターを使ってます。USBハブは当然3.0用ですよ。お間違えなく。

 次にUbuntuの世界で有名なGpartedをインストール。このソフトでインストールするディスク名称を調べ、一応全領域をext4でフォーマットします。

f:id:TAKEsan:20161206135923j:plain

GpatedでSSD内容を表示させています。すでにUbuntuをインストールしてあるので複数のパーテーションに分かれていますが、最初は全領域ext4でフォーマットします。右上にデイスク名称「sda」が表示されています。

インストールCDの install/predeed.cfg の中身を修正。2箇所(50,90行目付近)修正箇所があります。

f:id:TAKEsan:20161206142708j:plain

  50行目付近の赤線部分を変更。念のため以前の行はコメントをつけています。(元々はmmcblk0)

f:id:TAKEsan:20161206142707j:plain

               90行目付近も同じように修正します。

 この部分をmmcblk0からsda またはその他(環境によってディスク名が変わるのでgpartedで確認したディスク名)に変更して保存。

 修正が完了したらインストールUSBメモリ、外部記憶装置は外さないで、reboot後、F2でブートマネージャーを立ち上げ、Boot Option Menuを選択。今度は下の写真の様にEFI USB DIiviceが2つ出てきます。大雑把な方法ですが、空の方は選択してもブートマネージャに戻ってきますので、もし戻ってきた場合はEFI USB DIivice 1の方を選択すれば、本体eMMCと同じ様に、自動でpredeed.cfgに指定した空のディスクにインストールされます。なんか挙動がおかしかったら、(途中でインストール作業が止まってしまったら)再度リセットスイッチを押して本体eMMCでUbuntuを起動した後、predeed.cfgの中のディスク名称を再度確認してください。インストールできない原因は多分これだけです。正常であれば簡単にインストールできちゃいます。

f:id:TAKEsan:20161206135921j:plain

            Boot Option で EFI eMMC Deviceを選択するだけ。

 現在私はコンパクトSSDを使ってますが、安定して動いてます。早いこと早いこと。もう立派なUbuntuマシンです。Ubuntuディスクトップマシンを持ってるのですが、全く必要無くなってます。

 標準で使うUbuntuを決めたら最初にMraaインストールと動作確認

 JouleでPythonc++からGPIOを制御するには、mraaが最適です。何はともあれ、最初にmraaをインストールします。これが使えなければわざわざJoulを選択する意味がありません。色々な方法で試して見ましたが、最新のソースをダウンロードしてビルドしたものが一番安定している様です。

 ソースはhttps://github.com/intel-iot-devkit/mraaからダウンロード。解凍したフォルダに入ったら、以下を実行。

sudo apt-get install git build-essential swig3.0 python-dev nodejs-dev cmake libjson-c-dev

mkdir build

cd build

cmake ..

make

sudo make install

sudo ldconfig

sudo ldconfig -p | grep mraa

一応nano .bashrc で 最後に

export PYTHONPATH=$PYTHONPATH:$(dirname $(find /usr/local -name mraa.py))

を追加

 インストールしたら、ダウンロードしたファイルにPython のサンプル(mraa-master/examples/python)が入っているので、blink-io8.py---->内部の x=mraa.Gpio(8)をx=mraa.Gpio(101)に変更。sudo python blink-io8.py でボード上のLEDが点灯するはずです。sudoを付けないとGPIO制御ができないので注意。

f:id:TAKEsan:20161206142706j:plain

                       実行前

f:id:TAKEsan:20161206142705j:plain

どうせならってことでボード上のLEDを全部点滅して見ました(GPIO番号 100〜105)CPUモジュール上のLED 2個も点灯できました。

 ところが、オンボードLEDの点灯確認ができますが、手持ちのLEDをピンコネクタに取り付けたてみたのですが、どんなことをしても点灯できない!!。回路図を見ても全てのピンヘッダは3.3Vに昇圧されているのに.....。試しに予備で取っておいたOstroのSDカードで、Intelご自慢のOstroを起動して試してもダメ。なんてことでしょう。Ostroでも動かないなんて。だから取説のサンプルも基板上のLEDだけなんだと、妙に納得したりして.......。

 あ、そうそう。本体のSDカードフォルダに取り付けたSDカードにもインストールできると思いますが、16G以下に限られることと、転送速度が遅いためUbuntuでは体感スピードはかなり遅く感じます(前回検証)。CPUスピードは変わらないので、外部で使うならアリかもしれません。またOSをインストールしたSDカードを入れっぱなしにしておくとうまく起動できない場合があるので注意。

Joule EXpanson ボードのGPIOがmraaで動かない!!-->動いたぁ。

 肝心のGPIOピンに関して、i2cもPWMもGPIOも全く動く気配がありません。回路図を見るとちゃんと3.3Vレベルシフターが入っているし、宣伝でもピン出力は3.3Vと明記している。でもできない.....。ボード上のLEDは100~105番までちゃんとチカルのに。やっぱりカーネルがおかしいのかななどど考えたのですが、blink-io8.pyを利用してテスターでGPIOを確認すると、一瞬3.3Vになって1.8Vに戻る。OFFだと0V。どうやら内部レベルシフターが正常に働いていない。mraaは真面目に動いてるらしい...。80本のピンを3.3Vに昇圧するために実装している9つのレベルシフターが同時におかしくなるわけがないと思っていた矢先、またしてもHirokazu Egashiraさんからのヒントがありました。何でも非売品を買ったとか。それもJoule Ubuntuにインストールしたmraaで動くとか。ネットで探すと該当商品の説明がありました。

Gravity Expansion Shield for Intel Joule SKU: DFR0465 - Robot Wiki

おまけに回路図も真面目に掲載されています。Gravity Expansion Shield for Intel Joule Schematic

 このボードはExpansion Boardに差し込む形で、GPIOに特化したもの。Expansion Boardにセンサー類を直結すればいいのにと素人は思ってしまうのですが、理由があったんです。よく回路図を見ると全て4.7Kの抵抗が入っている。つまりPull Upが必要カモ。もしやと思いテスター片手に4.7k抵抗を大量に買ってテストして見ると、動きました!!。引っ張る電圧を5Vに変えると最大5Vになりました。これでバンザーイです。

 i2cはちょっと厄介。i2c-0は使えません。ユーザーに解放されているのはi2c-1以降のようです。さらにi2cdetectで12c-0以外はアドレスを確認できませんでしたが、Pull-Upすると動きます。i2c出力用にj12j13 2箇所ずつ同じポートが存在しますが 微妙です。私の場合、内部eMMCにインストールしたUbuntuでは、J13側。SSDではJ12側でしか反応しません。抵抗値が微妙の様ですが、i2cに関して一応4.7k抵抗をつけて動いた方ということで(測定器が欲しくなってきた)我慢。この辺りはIntelが資料を公開すれば、解消すると思われます。

 各GPIO接続方法は以下のとおり。抵抗1本でOKです。外部レベルシフターなど昇圧回路が必要無い点がGoodです。でもなんでこんなことをしなければならないのでしょうか?基盤が小さすぎたのかもしれません。

f:id:TAKEsan:20161206142709p:plain

こんな感じで、GPIO制御する場合はPull UPが必要みたいです。見た目でも信号を引っ張ってる感じが伝わってきます

f:id:TAKEsan:20161206142702j:plain

GPIO51番に接続したLEDを光らせる準備。Pull UP用に5Vを使用。LEDはLillypad用の抵抗付きLEDを使ってます。

 --->その後テストしてみましたが、SPIとUARTは初期設定時点でエラーになり(カーネル4.4.0-100 joule)ます。まだベータ版なのでしょうがないですね。この辺りForum: Intel® Joule™ |Intel Communitiesを見ると最新情報が確認できますが、やはり現時点では接続できないようです。方法が見つかったら追記します。

JouleのEXpanson ボードのピンヘッダは裏からも刺せる!!

 この頃気づいたのですが、これは初めて見る構造です。裏からも刺せる。L型のピンを使えばいい。ジュールはCPUが熱くなるので、迂闊に上部にCPUを跨ぐ様なボードを刺せません。結構使う側を考えたアイディアだと思います。

f:id:TAKEsan:20161206142701j:plain

ピンコネクタがスルーなのが確認できます。こんな感じで裏からもピンが刺せます!!良くできてますね。

JouleでOpenframeworksが動く!!

 私の実験用にはOpenframeworksは最適なC++フレームワークなので、これがインストールできてなんぼの世界なのですが、あっけなくインストールできました。全てのサンプルがソコソコ快適なスピードで動きます。画像処理中、若干息つきが出ますが、CPUスピードを調整すると格段に良くなることがわかりました。(sudo apt-get install indicator-cpufreq

 とりあえず、といっても2日間みっちり時間が必要でしたが、i2cとGPIOをMacで操作するWeb物を作って見ました。今まで作ってきたものの応用です。前回スイッチサイエンスRapiroボードで、Edison環境+Python flaskで作っていたものの中で、c++環境のスピードが要求されるプログラムをopenframeworksに組み替えました。いつもの非接触式赤外線センサー(OMRON D6T)とLEDとWebCameraを使用してます。

 今までは、ブラウザ上のボタン操作後、若干のタイムラグがあり、ボタンの反応が鈍かったのですが、前々からやりたかったofHTTPを応用した、カメラとセンサーの合成画像とLED点滅操作が、リアルタイムで操作できる様になりました。これが可能となれば、1年以上ブログを書いてきた今までの集大成ということになります。手順は、

  • Openframeworks linux64 Ubuntuインストールをマニュアルに従ってインストール
  • 今回必要Addonをaddonsにコピー(-masterは消すこと)     Openframeworksのディレクトリに入って

       cd addons
       git clone https://github.com/bakercp/ofxIO
       git clone https://github.com/bakercp/ofxMediaType
       git clone https://github.com/bakercp/ofxSSLManager
       git clone https://github.com/bakercp/ofxTaskQueue
       git clone https://github.com/bakercp/ofxNetworkUtils
       git clone https://github.com/bakercp/ofxJSON
       git clone https://github.com/bakercp/ofxHTTP
       git clone https://github.com/bakercp/ofxJSON
                         git clone https://github.com/bakercp/ofxJSONRPC

  • mraaとの連携ですが、新しく作成したプロジェクトディレクトリ内のファイルconfig.make中1箇所を修正。

f:id:TAKEsan:20161206150044j:plain

       config.makeの赤線部分を追加。要するにmraaライブラリを追加します。

 ofxIOのみ最近修正されたようなのですが、これが原因でコンパイルエラーが出ます。以前のofxIOに入れ替えればOKでした。ofxIOと今回作ったソースを一応ダウンロード可能にしときます。ofxIOを作った本人(開発者の一人)が気づくまで.....。今回作成したプログラムは、ofxHTTPとofxJONPRCで利用するサーバーを同一ポートで立ち上げるなどという作者が考えもつかなかった様なことを実験的に実行して見ましたが、ちゃんと動きました。ofxIO旧バージョンと今回作ったプログラムは、ここからダウンロードしてください。

http://d.hatena.ne.jp/TAKEsan/files/Joule-OF.zip

 解凍したファイルは「ofxIO」をaddonsへコピー。joule-jpeg-newはapp/myAppsヘコピー後フォルダに入ってmake -j4でビルド。sudo make runで実行できます。赤外線センサー(D6T)はスイッチサイエンスで手に入れることが可能(専用のケーブルが別売ですが必ず必要)。LEDは各自用意して下さい。D6Tセンサーはi2c-1へ接続、LEDは、+側がピン番号51接続としてます。

f:id:TAKEsan:20161206142703j:plain

     LedとOmton D6Tの接続状況。i2cはJ12側のi2c-1に接続。LEDはGPIO51番

どんなのかは下の動画をどうぞ。

         

左側はJoule直結ディスプレイ。右側はMacのサファリでJouleのip及びポート番号を指定してJouleを操作しているところです。D6T赤外線センサーは、認識画素数が4X4に対してJoule側で最大で200倍以上の補間をしてます。Mac側からLEDのオンオフ、温度分布のオンオフ、カラーマップの切り替え、補間精度の調整をリアルタイムで操作できました(動画ではLEDのオンオフがはっきり確認できませんでした。スンマセン)。カメラ画像は800X600でほぼリアルタイムですが、温度分布の方はD6Tの送信スピードが間に合わずギクシャクしているように感じます。こんなことはEdisonやPi zeroでは感じなかったので結構感激でした。

 何してんのかわかんないって?。センサーに温度を検知させててカメラ画像とシンクロさせてるんです。おまけで最高最低温度と検知した場所を表示させてマス。つまり安上がりのサーモグラフィーもどきってワケ。周囲より温度の高い「手先」に反応して動いてるでしょ。もちろん暗闇でも動きます。もともと16分割の温度しか検知できないなんて信じられます?。スイッチサイエンスさんが、わかりやすく解説していますMEMS温度センサを使おう | スイッチサイエンス マガジンが、これの大幅改良版です。

f:id:TAKEsan:20161206144547j:plain

   Mac側のサファリ画面です。左下にある5つのボタンでJouleをリアルタイムで操作できます。

 Openframeworksの長所でもある簡単に作成できるOSC通信で、WROOM02やらPi zeroやらとのデータ通信が高速にできることを確認しているので、Jouleとの連携が面白そうですが、目下の目標はJouleによるLeptonサーモセンサーの稼働です。先月号のトランジスタ技術にLEPTONの解説が掲載されてましたが、すでにPi zero でもWROOM02でも接続方法が確立している上に、画像配信まで実現しちゃってます(i2cでの温度取得も!!)ので私の方が2歩ぐらい進んじゃってるカモ。詳しくは過去記事をご覧下さい。でも、さすが専門誌だけあって、読み飛ばしていた英文マニュアルの要点を解説しているのでとても役に立ってます。

 Lepton との接続に関してEdisonでは苦い経験があるので、同じIntel系のJouleでうまく繋がるかどうかわかりませんが、トライしてみます。これが可能ならばLeptonを2つ繋げてステレオ・サーモセンサーができちゃったりして.....。階調の幅が相当あるので画素が少なくともなんとかなるような気が........。

 何と言ってもビルドのサクサク感が今後の開発意欲を高めてくれます。

JouleでOpenCLが動く!!

 これが実現できれば、内臓されたGPUIntel HD Graphics)を利用してさらにスピードアップさせたアプリが作れます。まだテスト段階ですが、物によりCPU単独の2倍程度早くなることが確認できました。海外の記事ではインストール失敗例ばかり(と言っても多分1人だけ)なので、今回の記事が最初だと思います。

 今回の記事でインストールしたUbuntuカーネルは、4.4.0-1000 jouleとなっていますが、OpenCLをインストールするには、4.7.0以上にする必要がある様です。危ないので(結果的にGPIO,PMWは使えるが、i2cが使えなくなった)、SDカードにインストールしたUbuntuUSB3.0接続)で試すのがおすすめ。

f:id:TAKEsan:20161206145101j:plain

       OpenCL実行用には、SDカードにインストールしたUbuntuを使いました。

 お試し用のSDカードにインストールしたUbuntuを立ち上げたら、まずカーネルをアップグレードします。

How to Install Linux Kernel 4.7.2 on Ubuntu 16.04 LTS - LinuxBabe.Comを参考に以下を実行。

wget kernel.ubuntu.com/~kernel-ppa/mainline/v4.7.2/linux-headers-4.7.2-040702_4.7.2-040702.201608201334_all.deb

 

wget kernel.ubuntu.com/~kernel-ppa/mainline/v4.7.2/linux-headers-4.7.2-040702-generic_4.7.2-040702.201608201334_amd64.deb

 

wget kernel.ubuntu.com/~kernel-ppa/mainline/v4.7.2/linux-image-4.7.2-040702-generic_4.7.2-040702.201608201334_amd64.deb

 

sudo dpkg -i linux-*4.7.2*.deb

 多少時間が必要ですが簡単にインストール可能。再度reboot。まともに動くかどうか心配でしたが、特に問題無く動きました。uname -a でバージョンを確認して カーネル4.7.2に変わっていればOK。

今度はOpenclをダウンロード。ダウンロード先は、

OpenCL™ Drivers and Runtimes for Intel® Architecture | Intel® Software

最初の方に説明しているSDKパッケージのlinux 64bit版をダウンロードして解凍。

 色々試して見ましたが、最終的にダメ元でトライした結果、ダウンロードしたディレクトリに入っているinstall_GUI.sh を実行するだけでOKでした。

 インストーラーはUbuntu14.04が基本で、途中「必要ライブラリが無い」と叱られますが、インストールを中断してメッセージに出たライブラリをapt-getでインストール。それでもエラーが出ますが気にせずに続けると、なんとなくインストールできます。

 GPUを認識していないんじゃ無いかって? この画面を見てください。ちゃんと認識してます!!

f:id:TAKEsan:20161206144543j:plain

   OpenCLを認識してます。Joule HDグラフィックス(GPU)とCPUの諸元が表示されました!!

 確認用に一番手っ取り早いOpenCV2.4.13をインストール。コンパイル中はかなりの頻度でGPUコンパイラが動いているので、一般コマンドも最適化されている可能性があります。インストール方法は以下の通り。

sudo apt-get install qt5-qmake

sudo apt-get install qt5-default

sudo apt-get purge python-pip

wget https://bootstrap.pypa.io/get-pip.py

sudo python get-pip.py

sudo add-apt-repository universe

sudo apt-get update

sudo apt-get install cmake git aptitude screen g++ libboost-all-dev \

libgflags-dev libgoogle-glog-dev protobuf-compiler libprotobuf-dev \

bc libblas-dev libatlas-dev libhdf5-dev libleveldb-dev liblmdb-dev \

libsnappy-dev libatlas-base-dev python-numpy libgflags-dev \

libgoogle-glog-dev python-skimage python-protobuf python-pandas

お好きなOpenCVをダウンロード解凍後(今回は2.4.13)ダウンロードしたフォルダに入って

make build

cd build

cmake  -D WITH_OPENCL=ON -D WITH_QT=ON -D WITH_OPENGL=ON -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF -DBUILD_EXAMPLES=ON -D BUILD_opencv_python2=ON -D PYTHON_EXECUTABLE=$(which python) ..

make

sudo make install

 これで簡単にOpenCVもインストールできます。コンパイルオプションにOPENCLを入れています。

 ダウンロードしたOpenCVの中に入っているOpenCL用のexample(oclディレクトリ内に存在)を実行して見ます。コンパイル方法は、

  g++ 該当ソース.cpp `pkg-config --cflags opencv` `pkg-config --libs opencv`

コンパイラが働いている証拠にOpenCLの中間ファイル(拡張子.clb)ができてます。

f:id:TAKEsan:20161206181431p:plain

oclサンプルのcppファイルをコンパイルした後、中間ファイル拡張子clbができていた。OpenCLがまともに動いてる!!

 実行できないのもありますが、次の2つのプログラムで実行内容を確認して見ました。

 まずfacedetect。これは遅い!!。GPUの恩恵は感じられません。認識用のデータは opencv-2.4.13/data/haarcascades_GPU/haarcascade_frontalface_alt2.xml を指定します。このデータ以外は実行できない様です。なんとなくGPUメモリが原因みたいな感じでした。もともとOpenCVの顔認識サンプルは、遅いことがわかっていたのですが、これはダメ。(Openframeworksの顔認識の方がはるかに早い!!)

 次にhog。これは人物を認識するプログラム。ちゃんとCPUの2倍早くなってることが判明。効率を追求すればこの倍は行く様に思われます。ちなみにTX1ではGPU ONで今回の5.3倍程度(CPUのみで1.9fpsなのでCPUスピードはJouleが若干上で、GPU ONだとTX1が遥かに上)のスピードでした。i7 6700K CPUオンリー環境でもJoule のGPU ONの2倍くらいのスピードなので、このサンプル自体OpenCVGPUのテストとしては、相当効率が悪い様です。

f:id:TAKEsan:20161206144544j:plain

Mac上で人物を表示させて、Jouleに接続したカメラで人物を認識させているところ。実際の人間ならもっと認識率が上がるカモ。GPUが4.4fps前後であることが確認できます。

         

GPUとCPUの切り替えをしている動画です。画面に映っているテレビ画面の動きでスピードの感覚が掴めると思います

 てな訳で一応ちゃんと動きました。外付けGPUにはとても叶いませんが、少しでも早いソフトを作りたい方は最適かと思いますが、いかんせんカーネル4.7.2では、i2cが使えません。(/dev にi2cポートが現れない)対処方法はインテルの資料待ちといったところでしょうか。また、内部エラーが時たま出るので、システムが不安定になります。付け加えると、GPUプログラム実行時Jouleモジュール自体、かなり発熱しますので冷却体制は万全に。

 やっと本題

Intel Joule はEdisonやPi3 との価格差を超えられるか?ですが、

  •  CPUスピードは、Edisonの10倍、Pi3の3倍くらいの差が確実に体感できる。
  • GPIO制御に特別の外付け回路が必要ない(抵抗が必要だが)。
  • 本体のみでプログラム開発がサクサク。
  • はるかに拡張性のあるUbuntu環境が簡単に実現できる。
  • Wifiが実用レベルで動く(Pi3やTX1と比較して非常に安定している)。
  • GPGPU(OpenCL)を使ったプログラムが組めるので、さらにスピードアップが期待できる。

 Ubuntuがノートパソコン並みにサクサク実行できて、GPIOが使えれば、価格差なんか糞食らえになっちゃいます。使用感の次元が違うので、この種の趣味を持つ者とすれば天国ですよね。でもEdison(WROOM02やPi zeroも!!)についてはIOT制御面での優位性は確実にありますので、これらを適所で組み合わせることで素晴らしいモノが作れると思います。

 Pi3を色々試してみると、どうしてもSDカードのスピードの壁に突き当たって来ます。Pi3ユーザーの一人として、こうしてJouleを色々実験してみると、私のPi3へのプログラム処理能力の期待度は、結局Jouleだったんだと分かって来ました。過去、私を含めた批判者の多いモジュールでしたが、Jouleについて初期の頃感じていた不満を1つ1つクリヤしていくと、計り知れない底力を秘めていることを感じてしまいます。

 Joule唯一の欠点は、外部へ持ち出した時、電源への配慮が必要なことでしょうか。 Ubuntu環境では、USB C へ3A程度の電源供給ではシステムが初期ダウンしてしまいます。基板上に電源用のパターンが存在しているので、この辺も追求したら楽しそう.....。

 結論になってませんが、そもそも比較する対象が違うっ。という曖昧な答えを出して今回は終了。

 少し長くなりましたが、今年はこれで終わりにします。これから少し家の修理とか、正月の準備とか、庭の手入れとかに精を出したいと思ってます。そのあたりで何か発見があればまた書きたいと思います。

 

                        では、また。あー疲れた。

 

 

 

Juneちゃん その後。

 やれIntel jouleやら、Nvidia TX1やら、ゲームパソコンやらちょしてる(仙台弁触ってるの意)事に限界を感じてきたので、今回は私のストーカー犬「ジュン」ちゃんの近況です。

 ところでトイプーって毛が抜けないの知ってました?ほっておくと着古した毛糸のセーターみたいに毛玉だらけになっちゃいます。初めの頃は知りませんでした。

 今年は3歳。夏バテ防止のためサマーカット(丸刈り!!)を2回ほど経験してやっとこうなりました。

f:id:TAKEsan:20161127194546j:plain

f:id:TAKEsan:20161127194547j:plain

 お腹のタプタプがチュッチュッチュッ〜なんですけとワンちゃんを飼ってない人はわからないでしょーね。

 モッップ状態。これがカワイくなるんでしょーか?。今までだとある程度長くなると形が整ってくるんですが、今回は全くダメ。基本のカットバランスがものすごく悪い。今までのトリマーさんが変わったみたいなのが大きな理由。変わったトリマーさんはどうやら初心者のようです。自分の娘みたいなもんなんで、「カワイ」くしたいのは飼い主のサガ。

 思い切って、違うところに頼んでみました。

f:id:TAKEsan:20161127201714j:plain

惚れ惚れするようないい女!!

f:id:TAKEsan:20161127201715j:plain

尻尾のくびれが......ソソル。

f:id:TAKEsan:20161127201716j:plain

セクシー!!

3日後

f:id:TAKEsan:20161127202629j:plain

今度のトリマーさんはまつ毛を残してくれたのに気づきましたました。

f:id:TAKEsan:20161127202632j:plain

まつげの先がキュンと跳ね上がってました。

f:id:TAKEsan:20161127202630j:plain

 思い切ってマスカラで黒くしようと思いましたが。気持ち悪くなるのでやめました。もう少し頭の先が伸びると最高。こんな感じで365日見つめられているのもなんか後ろめたさがあったりして.......。

                             ではまた。

   

 

 

 

 

Jetson TX1 で py-faster-rcnn を使ってmjpeg 配信できたら幸せ!! そのほかモロモロ。

てな、馬鹿げた表題をつけたものの、本当にできるんでしょうか?

 何に使うのかって?。外に持ち出すには最低7インチのディスプレイが必要です。配線や電源も考えなければいけません。これがケータイで代用できたらとっても便利。がさばるディスプレイの代わりにケータイを使うのが最終目的。

 TX1で物体を認識した動画を、iPhoneで受信!?。考えただけでザワーっとします。つまり、その作成過程を考えるだけで吐き気がっ。

 今回の記事はJetPack-2.3環境すなわち全部64bit環境な場合です。また、homeにプレインストールしてあるjetson_clocks.shを実行し、GPUクロックを最大にしてます。

f:id:TAKEsan:20161111105719p:plain

今回の最終形。1度に複数の物体を認識している(テレビの中の人物も)。これがTX1から送られたmjpeg動画の一部画像です。動いている様子は以下のMoveファイル参照。

ザワーの1回目

 まず肝心のPy-Faster-RCNNインストール。このダウンロードしたフォルダの中で、専用に修正されたCaffeのビルドが必要です。経験上すんなりとインストールできない予感があったのですが、やっぱり的中。少し探すとForumに書いてありました。要するにCuda8.0に対応してないとのこと、

https://devtalk.nvidia.com/default/topic/974063/jetson-tx1/caffe-failed-with-py-faster-rcnn-demo-py-on-tx1/

 これを参考(中程にNvidia担当者の回答がある)にすると、インストール自体は何て事ありません。説明が悪いだけ(私の英語力の問題か?)です。BLC Caffeは修正済みなので、この中からいくつかのライブラリをコピーして上書きしなさいですと。

 すなわち py-faster-rcnnをダウンロードして解凍すると、py-faster-rcnn->cafe-fast-rcnn の中身が改造されたcaffeのインストーラがあります。すでにBLVC Caffeの方はCuda8.0に対応しているので、ダミーでどこかにBLVC caffeをダウンロードして、この中身のライブラリを入れ替えればOK。

 入れ替えるファイルは、以下の11個のファイル(青の部分)だそうです。該当フォルダは黒の部分です。

include/caffe/util/:

cudnn.hpp

 

src/caffe/layers/:

cudnn_conv_layer.cu

cudnn_relu_layer.cpp

cudnn_relu_layer.cu

cudnn_sigmoid_layer.cpp

cudnn_sigmoid_layer.cu

cudnn_tanh_layer.cpp

cudnn_tanh_layer.cu

 

include/caffe/layers/:

cudnn_relu_layer.hpp

cudnn_sigmoid_layer.hpp

cudnn_tanh_layer.hpp

 すでにTX1にCaffeをインストールしていれば、依存ライブラリがインストールしてあるはずなので、あとはいつものMakefile.configの書き換え。内容は以前の記事を参考にしてください。いつものようにビルドして、以下の記事の

GitHub - rbgirshick/py-faster-rcnn: Faster R-CNN (Python implementation) -- see https://github.com/ShaoqingRen/faster_rcnn for the official MATLAB version

2番目あたりからpy-faster-rcnnをインストールすればOK。私の場合、

sudo pip install pyyaml

で、新たなPythonライブラリが必要でした。新たにビルドされたCaffeは、すでにインストールされているCaffe、Pycaffeと区別されるので、pathなどの追加は不要。

 TX1ではメモリーオーバーになるのでデモソースは、簡易型のデータでしか実行できません。この後のライブラリの容量を考えると、まーTestなので、それなりに認識すればいいのかと。

一応 py-faster-rcnn-->tools に入って、

python demo.py --net zf

その後の確認:TX1の同じフォーラムに書いてありましたが、GPUメモリをなるべく使わない方法=logout して他のコンピューターからSSH接続後同じプログラムを動かすと--net zf 無しでも動きました。画像の認識は上がりますが、スピードが極端に落ちます。動画として確認するなら--net zfをつけたほうが良いみたいです。)

 5つのテスト画像を読み込んで、認識結果を画像で表示します。GPUフル稼働でも1画面平均0.47秒くらいの認識スピードなので、動画にすると遅いこと確実 。遅いと言ってもCPUモードで実行すると平均28秒!!、なんと60倍くらい遅くなります。それよりははるかにマシ。Pi3だとどんだけ遅くなるんでしょうか?

 めげずにmJpeg配信のためにSimpleCVをインストール。py-faster-runのビルドに成功していれば、以下の2つを追加インストールでOK。

sudo apt-get install python-pygame

sudo pip install https://github.com/ingenuitas/SimpleCV/zipball/master

ざわーの2回目

 mJpeg配信とくればSimpleCV!!。同じPythonなので簡単に...。Camera画像の変換が重要な問題だとはわかっていたのですが、少し風邪気味でタダでもボケボケの頭が、さらにボーケボケ。構想2日、実務が半日で、やっとdemo.pyを書き直した物が次のソースです。一応動くだけですが。

id:TAKEsan の mjpeg.py

py-faster-rcnn-->toolsへ保存したら、40行目付近の

     js = JpegStreamer("tegra-ubuntu.local:8090")

の赤字部分を自分のip環境に変更して下さい。

cv2-->SimpleCVのイメージデータ変換(たった1行)だけがキモでした。ソースを全部コピー(最後の1行が見にくい)して mjpeg.py とかで名前を付けて保存。そしてUSBにカメラをつないだら、

                   python bokeboke.py --net zf   <-----直したつもりなのにボケボケでした

                   python mjpeg.py --net zf

を実行。MaciPhone のサファリからtegra-ubuntu.local:8090と打ち込めば、期待のpy-faster-rcnn動画が確認できます。TX1をバッテリー駆動させてiPhonのテザリング機能を使うことで、どこでも結果が確認できることになります。前にEdisonのFlask環境でGPIOとmjpeg画像を制御したことがあるので、応用すればTX1でもディープラーニング環境でGPIOの遠隔操作が可能のはずです。

 カメラ画像は1080X720で読み取ってますが、これより解像度が低いと、物体の認識率が下がるようです。認識に時間を取られるので解像度を下げても、あまり表示スピードが変わりません。色々試してみると面白い。mjpeg配信なので、本体直結のディスプレイでなくとも画像表示可能です。だから本体をログアウトさせても、他のコンピューターからSSH接続で動作可能。--net zf 無しで実行したい場合は、この方法で!!

結局の動画

 動画とは程遠いものですけど、少しバカな(反応の鈍い)ロボットの認識用として使えば、現実味を帯びてきます。ファインチューニングで個別画像をDIGITで追加学習させれば、「こんにちはTAKEsan」とか、こんにちは「Juneちゃん」(愛犬の名前)を言ってくれる!!(っと思う)。次の目標はこれで決まり。こう考えるとなんとなく顔がにんまりしてきます。さらに認識する種類を限定することで、大幅に早くなるような気がします。

                                

TX1で発信したmjpeg動画をiMacで表示させているところ。かなりスローで、3秒くらいの遅延がありますが、なんとなくいい感じ。 ちゃんとfaster-rcnnしてるでしょ。

 試しに、母艦GTX1080環境で実行すると(GTX1080もCoda8.0対応のため、TX1と同じようにCudaのライブラリを変更したらすんなり動いた)、やっぱり速い。図体がでかいので、背負って移動させるわけにもいかず、早くてもあんまり意味がありません。 

                                

母艦Ubuntu環境(i7 6700K とGTX1080)で同じソース画像をiMacで受信、Pythonなのに遅延がほとんどない。

幸せになったということで、py-faster-rcnnの実験については、これで終わり。

TX1環境のデープラーニング応用環境が現実味を帯びてきた

 この頃はもっぱらTX1Intel Jouleの個人的な性能評価やらインストール作業やらに熱中してしまって、まともにプログラム作成に向き合っていません。あっちこっちに首を突っ込んで当初の予定だったニューラルネットワークに関するお勉強がそっちのけになっています。

 まーその流れで。Jetson TX1の最先端はどちらに向かってるか探りを入れてみました。この方が鍵を握っているようです。

github.com

 Nividiaでは、Jetpack2.3になってから、TenserRCがどうのコウノト言ってますが、果たしてこれは何?。発売当初からFloat 16演算を行うと、スピードが1Tが出るとかなんですが、実質的な実現例が提示されていないばかりか、Float16のcaffeもイマイチ中途半端でした。ましてTensorRCはこのFloat16に特化したと言いながら、何も具体的な情報が無い。やっと重い腰をあげたみたいなので、以下実行結果を私なりの理解度でご報告。でも未だにTenserRCが何者なのか、わかっていない。

まずTorchはどうなったのか。

 この方が「できるできる」と言っていたものが、少し前にやっとgithubで公開されています。自分で試して見て初めてわかったんでしょうね。ちなみにTorchはTenserRCとは無関係。TX1のCuda8.0対応版です。

GitHub - dusty-nv/jetson-reinforcement: Deep reinforcement learning libraries for Jetson and online training

 記載されている手順通りで無事インストールできました。開始はいつものthではなく./deepRL-consoleでした。仕組みが理解できていませんがOpenblas、torch、torch7,cutorchが同時インストールされます。標準Luaライブラリは nn,cutorch、cunn、などがプレインストール。他のLuaライブラリは、Luaにパスを通せば簡単にインストールできます。例題はこんなのです。ピンポンゲームの学習。

                                


 以前入れた早稲田大学の白黒カラー化ソフトを実行させてみると。

takesan.hatenablog.com

(ソース中のargではコマンドラインで指定したファイルを認識しないので、直接ソースに画像指定してやります。この記事に書いてあるように追加のLuaライブラリが必要)
OpenBlas関連の実行時エラーが出ますが、ちゃんとカラー化できました。気になるテスト用に入っている風景写真の変換スピードは、以前のjetpack2.2と比較すると、60秒の実行時間に対して、今回は20秒40秒も実行スピード早いのです(i7 6700k+1080環境では4秒程度ですが)。データの読み込みや演算共格段の進歩が見られます。いよいよTorch+TX1がモバイル環境で現実味を帯びてきました。

TenserRT

 これはなかなかでした。DIGITSで作成した学習データの応用例です。

GitHub - dusty-nv/jetson-inference: Guide to deploying deep-learning inference networks and realtime object detection with TensorRT and Jetson TX1.

カメラを使ってリアルタイムで学習結果を表示します。

 まず30fpsくらいで、とにかく手当たり次第、物体認証結果を表示するプログラム。Caffeのexampleの中にあるWeb-Testを使えば私にもできそうな感じ(スピードはここまでは確実に上げられない)です。

       

どこを認識しているのかがわからない点が残念ですが、とにかく速い!!。せめて点くらい表示させたらいいのに....ブツブツ。

 物体の認識が組み合わさっているのに、目にも止まらぬ実行スピードです。出力単語をよく見ると、それらしい物体として認識されてます。

 次にリアルタイムObject-Detect認識をTX1で実現させたプログラム。人物群と物を同時に判断できるようです。(スピードを度外視すれば性能は今回取り上げたpy-faster-runが上!!)こちらはさすがにだいぶゆっくりですが、ホビーでは実用レベルです。すごい。

        

動画では判断しにくいですが、人物を見つけると青の四角が表示されます。今回実験したmjpeg画像に比較すると格段に速いことが確認できると思います。
 そもそも例題を実行すると、画像が上下逆!!。プログラムの中身を見て変更しようにも、複雑で何が何だかわからない。もっと単純にできなかったものなんでしょうか。評価用としては、プログラム中のコメントが少ないので解析に時間がかかりそうです。表示部分がおかしいような感じ。当分は、カメラをひっくり返せばいいことなんで、気にしない気にしない。
 この方は同じgithubページ上に16bitCaffeのインストールスクリプトも自信を持って書いてますけど、OSが1つ前のものなので、run testがうまくいきません。どうも他の記事を読んでも、TX1に関しては、神の存在だと思ってるみたいな気がしないでもない。内容の割に、質問や閲覧数が少ないのは、この辺りでアメリカのみなさんも引いてしまうんでしょうね。

 記事を発表している人物が、メーカー側ですから消費者として率直な感想を書きました。がっ、やってることは納得です。こういうものを見せられると、寒気が。つまり「機械が自分を守るための単純な何かについて、人間がヒントを与えた時。ニューラルは空恐ろしいほどの進化があるのかも」です。

 DIGITSで学習させたObject-Detectデータが使えるようなので、次の機会に試してみることにします。TX1のフォーラムでは、「こんなに遅いのに」的に言ってる人がいますが、要はどう応用して使うかの問題なので、基本的なスピードがこれならば、十分実用的だと思うのですが、いかがなものでしょうか。 

※2017/1/19:この後TX1へのOpenFrameworksインストールに成功して、OF上で上の動画より早く実行できるようになりました。おまけに入出力の「とっつきにくさ」が解消されます。

takesan.hatenablog.com

 jetpack2.3でOpenCVやZEDカメラSDKコンパイルができた

 OpenCVの例題や、ZEDカメラSDKコンパイル時にcudnn関連のエラーが出て困っていたのですが、対策がわかりました。

 Oencvライブラリを使ったソースの場合、aarch64に限ってコンパイルエラーになってしまうようです。この問題は近い将来修正されると思いますが、どちらもsampleに入っているCmakeLists.txtファイルの最初の方に、以下を記述するとOKでした。ZEDの場合は以下を記述し、なぜか2回cmakeを実行するとうまくいきます。

                        set(CUDA_USE_STATIC_CUDA_RUNTIME OFF)

TX1でもJouleでも内部eMMCはTRIMが実行できる。

 これはlinuxSSDを使ってるみなさんならご承知の通り、SSDの延命と実行スピードを維持するための必需品

      sudo fstrim -v /

です。これが実行できた=TRIMが実行できたです。本体内部のeMMC寿命=超お高い本体CPUの寿命につながりますので、思い出したらやってみましょう。

 

                              では、また。

Intel Joule にUbuntu14.04をインストールしてみた。

 Intel JouleにUbuntuをインストールして普通に動かせたら。かなりワクワクしますよね。

※11/24  かなり簡単にインンストールできるようになってます。現在執筆中!!

----->12/6  完了。下の記事参照。Ubuntu16.04、外付けSSDにも簡単にインストールできて、mraaでGPIOも制御できた上に、OpenCL(GPGPU)の動作確認までできちゃいました。

takesan.hatenablog.com

以下の記事はUbuntu14.04をインストールしたい場合参考にして下さい。 

f:id:TAKEsan:20161103220858j:plain

 画面のもたつきとGPIOの制御ができない(執筆時点では気付かなかったのですが、sudoをつければボード上のLED制御可能。多分Pull UPすれば、大部分のGPIO制御が可能です)ことを我慢すれば、ちゃんとしたものになったので、どんな状態なのかも画像でついでにご報告。今回は、この記事の

communities.intel.com

成功例を使わせていただきました。結局、記事を最初に書いたKhaosさんが説明している通りでした。後の方でMcCoolさんが補足していますが参考になりません。混乱するのでやめた方が良いと思われます。KhaosさんはかなりLinuxに精通しているらしく、私のような初心者では中間が抜け過ぎています。でも。最終的にインストールができてみると、こんな短い英文に、よくぞこんなに盛り込んだと思えるくらいヒントが隠されてます。今回は補足という形で記事を書きました。ただし、IntelからJoule版Ubuntuが正式発表されるまでの命です。

 私は本体eMMCにインストールしてしまったのですが、後で元に戻すのが厄介なのでSDカードにインストールした方がベターです。今回は、SDカードインストール方法を紹介します。インストール先を変更すれば、簡単に内部eMMCにもインストールできますが、あまりオススメできません。例によってlinux初心者+αなので力技で処理しています。なので精通している方はもっとインストール過程がスマートになると思います。

用意するもの

  • SDカード16G以上(Ubuntu実行用。価格が高くなるが、なるべくスピードの速いもの)
  • USB3.0用のSDカードリーダー
  • USBメモリ16G程度(インストールディスクとして使う)
  • USB3.0用のUSBハブ(4口程度がベター。補助電源なしでも今の所快適)
  • 専用のHDMIケーブル

 本体のSDカードフォルダはスピードが遅く(ubutu実行時入力が相当もたつく)16Gまでという壁があるのでUbuntuはインストールしない方が良いと思われます。今回はUSB3.0にSDカードリーダーを介したSDカードにUbuntuをインストールします。まー遅めのSSDと言いましょうか。Ubuntuを使う限りはサクサクです。USB3.0ですから本物の外付け小型SSDを付ければもっとサクサク。

 Ubuntuのインストールは、かなりスピードの速いソニーのUSM-W3というUSB3.0対応のUSBメモリでも試してみましたが、USB2.0並みの操作感でした。つまり遅くてUbuntu実行環境では使えません。今回の検証はUSB3.0対応カードリーダー+SanDisk Ultraです。また、Joule本体がかなり熱くなるので小さなFanが必要。無い方はウチワであおぎながら作業しましょう。

 f:id:TAKEsan:20161104080359j:plainf:id:TAKEsan:20161104080400j:plain

インストール準備

 まずインストール用USBメモリをを用意して、通常通りインストールディスクを作ります。最初から日本語化してある理研などのサイトからダウンロード。作成方法は他のサイトを当たって下さい。(今回はUbuntu14.04)

Joule本体にキーボードとHDMIディスプレーを本体につなぐ

 キーボードは、ファンクションキーである「F2」が直接打ち込める標準キーボード(無線やFnキーを押さないとF2を認識しない小型キーボードではBIOS設定ができなくなる可能性大)BIOS設定ではJIS標準キーボードだと特殊記号が文字化けするので、 = /  \  : + - の位置を入力時確認する必要があります。

インストール用のUSBメモリをUSBハブにつなぐ

  • Jouleの電源ON
  • 本体のランプが4つ点灯した頃F2キーを押す。
  • 画面がBIOS設定に切り替わるの矢印キーで以下を選択
  • Boot -> F2 -> Boot Manager -> EFI Internal Shell

f:id:TAKEsan:20161103220848j:plain

f:id:TAKEsan:20161103220854j:plain

f:id:TAKEsan:20161103220855j:plain

                                      ここで EFI Internal Shellを選択すると、f:id:TAKEsan:20161103220857j:plain

      Shell画面になる。画面ではfs0:を入力後lsコマンドを実行している

なんだか訳のわからない表示が出てきますが、Shellがスタートしています。なので普通のlinuxコマンドが実行できます。この状態になったら、最初に「UbuntuインストールUSBメモリ」を選びます。通常は、fs0: のようです。

  • fs0:  エンター

 必ず : を付けること。ここで装置記号を入力しないとShellコマンドが実行できません。記憶装置名を入力したら、lsなどのコマンドを入力して、ファイル構成を確認して見て、選択した記憶装置が正しいものかどうかチェック。違っている場合は慌てずにexitを入力すると初期状態に戻るのでもう一度やり直しすればOK。直接画面では肝心の FS◯◯ 部分がスクロールされてしまうので、内容がfs0:でない場合は、fs0: から Fs4:くらいまで試して見ます。多分Fs0:でOKですが.....。Ubuntuインストールディスクはrootにcasperというディレクトリができているのですぐに判別できます。(一応他のlinuxマシンでcasperディレクトリが存在するかどうか事前に確認しておくと、安心)

  • cd casper

を入力して、casperに入ったら、めんどくさいですが以下を入力。この時、特殊記号の入力に注意すること。この時点でキーボード配置を確認しておくと後々便利。

  • vmlinuz.efi initrd=/casper/initrd.lz file=/cdrom/preseed/ubuntu.seed boot=casper quiet splash ---

---まで一挙に入力したらエンター。スペルは正確に!!。

 ドキドキしますが、しばらくすると見慣れたUbuntuの画面が現れます。ただしこれはインストール用(CDイメージ)ですから他のアプリはインストールできません。とりあえずここで、ディスクトップ画面から家庭内のwifiに接続しておきます(簡単に接続できるはず)。Ubuntu画面が出てこないでシステムが止まってしまったら慌てずリセットボタン(パーワーボタン長押し)を押して、再挑戦。casperディレクトリの有無やスペルの確認をしてみて下さい。

 標準でGpartedがインストールされているので、USB3.0用カードリーダーに高速SDカードを挿してUSBハブに接続してから、Gpartedを起動させ、SDカードのフォーマットを行います。すでにsdaはインストールUSBメモリに割り当てられているので、新たにつないだSDカードはsdbの筈です。ここで新たに2つのパーテーション(sdbに)を作成しますが、詳しくはGpatedの使い方を確認してください。前方に500MiB程度のfat16、後方の残りをext4にフォーマットします。前方にfat16を作らないとJouleのBIOSがこのSDカードを認識しないのでここが重要なポイントとなります。

f:id:TAKEsan:20161103220856j:plain

この時は内部eMMCにインストールしたのでmmcblk0になっているが、SDカードはsdbになっているはず。パーテーションはこんな感じで2つ作る。(fat16,ext4ext4はsdb2になっていることになる)

あとは、sdb2を/に指定して通常のUbuntuインストールを実施します。インストールが終了したら、再起動しないでそのまま、yoctoがプレインストールされている内部eMMCの第一パーテーションの中身を全部sdb1にコピーします

   認識している外部記憶装置は、/media 以下に全部マウントされているので、端末を立ち上げ、sudo cp -a を使ってフォルダごとコピーします。/media 以下にぶら下がっているディレクトリは、こんがらがってしまうので、中身を確認して間違えないように名称を確認してください。(英数字の羅列になっている)つまり内部eMMCに作られているBOOT部分をそっくり新しく作ったSDカードの第一パーテーション(fat16フォーマット)にコピーしてしまうわけ。コピーするディレクトリ構成は2つだけです。

                            EFI

                                --BOOT

次に端末からSDカードの第一パーテーションに入って、sudo で ubuntuフォルダを作ります。フォルダ構成は(ubuntuフォルダは、EFIの直下にBOOTと同位置に作る)

                            EFI

                                --BOOT

                               --ubuntu

今度は今作ったubuntuフォルダに入って

       sudo cp -a /boot/* 現在のディレクト

を実行して第2パーテーションに作られたboot以下のファイルをめんどくさいので全部コピー。さらに端末から、今コピーしたファイルの中のvmlinuz-4.4.0-31-generic を vmlinuz-4.4.0-31-generic.efi に名称変更。これで下準備完成。

 チョット複雑そうですが、よく考えてみると簡単なことに気づくと思います。コピー方法はこの他にもmountコマンドを使うなり好きな方法で。

いよいよ起動

  • まずインストール用のUSBメモリを抜きます。
  • SDカードを挿したUSBカードはそのまま挿しっぱなし。
  • システムをrebootしてF2キーを押しBIOSを立ち上げます。
  • Reboot -> F2 -> Boot Maintenance Manager -> Boot Options ー> Add Boot Option  を選択

f:id:TAKEsan:20161103220849j:plain

  • 矢印キーでUSBカードらしき部分を選択します。選択した記憶装置が正しければ先ほど作ったubuntuフォルダが選択できるので

f:id:TAKEsan:20161103220850j:plain

              違う場合はEscで変更が可能です。

f:id:TAKEsan:20161103220852j:plain

 ここではBOOT名称はUSB-UBUNTUにしている。カーソルで選択してEnterを押さないと入力できない。スクリプトを入力しているところ。

名称は自分の好きな名前で。スクリプト

root=/dev/sda2 initrd=\\EFI\\ubuntu\\initrd.img-4.4.0-31-generic ro rootfstype=ext4

です。赤文字部分ですが、先ほどフォーマットした時はsdbですがubuntuインストールUSBメモリを抜いているので、自動的にsdaになります。数値は2なのでお間違いなく。F4キーを押して保存した後ESCキーを押してBIOS設定初期画面に戻った後

Boot Manager->今作った設定ファイル名選択で..................Ubuntuが起動!!

f:id:TAKEsan:20161103220855j:plain

          Boot Manager で先ほど作った USB-UBUNTUを選択

起動方法は順序を設定するより、Boot Managerから選択するのが一番確実なようです。

 注意点としては、UbuntuをインストールしたSDカードを抜いてしまうと、設定ファイルが消えてしまうようなので、再度起動スクリプトを書いてやる必要があること。まー暫定ですからガマンガマン。

Openframeworksインストール

 Openframeworksは、標準Linux64版をダウンロードすれば問題なくインストールできました。いつもの3D Exampleをビルドすると、スピードが早いものの「もたつき」があります。ただしコンパイルスピードがPi3とは比較にならないくらい早い。

         

その他

  • apt-getが確実に使えるので、pip、pygame、SimpleCVは簡単にインストールできました。pypyなんかもインストールできて、当然ですが標準Pythonより物によっては10倍以上早くなります。
  • SimpleCVを使ったMJPEG配信では、USBカメラはちゃんと認識するのですが、なぜか配信スピードがEdisonより大幅に遅くなってしまいます。

        

JouleでSimpleCVを使って配信した360X240のWebCamera映像をMacのサファリで表示している。ものすごく遅い。OpenframeworksのOfxHTTPを使えば改善できるかも。後からSimpleCVで顔認識させたら480X270で8〜10fpsくらい出る。不思議不思議。タイミングの問題か?

  • mraaはソースからビルドできますが、全くGPIOを認識しません(実行時GPIOエラー。USBが使えたとしても現段階ではJouleの本領を発揮できません)。
  • GPIOを無視すれば、音声までは試してませんが、動作がぎこちない部分はあるとしてもほとんどのアプリが動くと思われます。
  • Jouleはかなり頻繁にCPUクロックが変化(800〜2400kHz)するので、スピードを固定すると多少画像のギクシャク感が解消できるかもしれません。

https://software.intel.com/sites/default/files/comment/1716807/how-to-change-frequency-on-linux-pub.txt

その後

  sudo apt-get install indicator-cpufreq

でCPUスピードを簡単に変えられました。インストールしたらreboot後右上に表示されたインジケーターで調整。何もしないと直ぐに0.8GHzに変わるみたいです。だから直ぐに反応が鈍るのか...。フーム。

最後に

 今回はSDカードを使ってのUbuntuインストール方法でした。寿命のある内部eMMCを使わないだけ精神的に気が楽になります。失敗を恐れずに何回でも試行できますので、説明不足のところは挫折しないで最後まで頑張ってみてはどうでしょうか?。私ができたのだから必ず成功します。本家がUbuntu稼働を発表した時にはそれよりも良いものになったりして...。マサカねー。

 Jouleの内部eMMCはかなり性能が良いみたいです。LinuxSSD使用者ではおなじみのTrimコマンドを実行可能。延命とスピード維持を確保するため、たまにfstrimを実行した方が良いかもしれません。

  例: sudo fstrim -v /        

       (内部eMMCでブートした場合。SDカードなどの場合は / を変更)

 

                                では、また。