Take’s diary

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

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

これだけです。

 

                                   では また。