Take’s diary

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

NVIDIA JETSON TX1 を動かしてみた!!

前回の記事から約2ヶ月

 その間にJETSON-TX1と言う、一昔前のGPU付きのパソコンが、PI並みに小型化されたすんごいボードを手に入れました。

f:id:TAKEsan:20160625205529j:plain

 ディープラーニング環境構築までかなり手間取ったのですが、一応入り口までたどり着いたので、記事にすることにしました。今話題のディープラーニングをドローンなどに組み込みやすくしたボードだそうです。ディスプレイにはPI用のIGZOディスプレイを使いました。

 今回はJetpack 2.2 Ubuntu(64bit)版でcaffeとtorch7のインストールと実行までをざっと書いてみます。Jetpack 2.1(32bit)との比較などもちらっと入れてみます。Jetpacとは、OS及びGPU関連のソフトとExample群がまとまったパッケージです。

まずMaclinuxデュアルブート

 母艦の対象は、64bit版ubuntu14.4 LTSです。余っていた外付けSSDを使いました。インストール方法は、ネット上で探してみてください。バーチャル環境ではJetpacがうまくTX1へ転送できないようです。さらに日本語化しない方がスムーズにインストールできました。 

 MacへのLinuxインストールが初めってだったのでかなり戸惑いました。Ubuntu母艦環境が構築できない方は、バージョンアップできないので、TX1を手に入れてもあまり意味ありません。

Jetpack64bit版をダウンロード

 といってもダウンロードされるのはスクリプトだけです。あとはマニュアルに沿ってインストール。勝手に必要ファイルをダウンロードしてくれます。

 TX1は一度電源を抜いて、POWERボタンを押した後、すぐリカバーボタンを押しっぱなし、続けてリセットボタンを押し、リセットボタンを離したら、2秒待ってリカバリースイッチを離すだそうです。多少タイミングがずれても順番がおかしくなければOKでした。

確認方法は lsusb コマンドをターミナルから入力して、Nvidiaで始まるUSB機器が接続されているかどうかです。これが確認できないと以下のインストールができないので注意。表示されない場合は再度TX1の接続をやり直してください。

 次にMacとTX1間を付属のUSBケーブルでつなぎます(付属のUSB3ケーブル)。ランケーブルはつながなくても、家庭内でWifi環境ができてればOK。その他には必ずHDMIディスプレイを接続しておくことが必要。(ただしWifiだとインストールに時間がかかります。以下Wifi環境でインストールしてます。)

インストーラを実行

 まず母艦に必要ファイルのダウンロードが実施されますが、時間帯によってはかなり遅くなります。問題なければ転送が始まり、終了すると自動起動されたターミナル画面表示が一旦止まります。(1回目は準備はどうですかなのでENTER

 この状態になる前に、エラーが出て先に進めない場合は、母艦のsudo apt-get updateを実行するとエラーが出ています。これを解決しないとTX1への転送が不可能になる(特にCUDA関連)ので母艦を調整する必要があります。ただし、サンプル関連だけが正常に転送できなくなるみたいなので、引っかかったインストール項目を外せばなんとかなります

 2回目で表示が止まったら、母艦からOSの転送終了後TX1が再起動されるので、Xwindow画面が出るまで気長に待ちます。この間TX1の画面が真っ暗なので不安になりますが、起動するまで5分ぐらい待ち、起動されたTX1で以下のことを実行。

  1. 設定からBrightr&locを選んで、画面がスリープされない設定にする。

       (ロックを抜け出す時、たまにマウスもキーボードも使えなくなる可能性あり)

  2. 表示画面を慎重に設定し直す(IGZO設定は回転や拡大設定が必要)

  3. ユーザーアカウントで Automatic login を必ずON

 どうやらTX1はIGZOとの相性が非常に悪く、これらを実行しないと再起動時、画面が真っ暗になり焦ります。その場合IGZOの電源を差し替えると多分表示されます。また、なぜか起動・終了時のログが表示されません。Pi3に接続したIGZOパネルは、表示が非常に遅かった記憶があるのですが、TX1では全く気になりません。Pi3の画像処理能力が追いついていないのでしょう。

 次にWifiの設定をTX1のXwindow上で実行します(ランケーブル接続しない場合)。で、ここまで終わったら母艦に戻ってENTER。母艦が自動的にIPを認識して、インストールがイーサネットに切り替わり再開されます。

さらに続けると

 途中フリーズしたように見えますが、動いてます。(TX1の該当フォルダを見てみると確実にファイル容量が増えていきます)ここで故障と勘違いして2回ほど初めからやり直してしまいました。これも相当時間が(長くて1時間)かかります。でやっと終了。ssh ubuntu@tegra-ubuntu.local (パスワードubuntu)で他のパソコンから接続が可能となります。

  ここら辺でTX1をapt-get update ,upgradeします。さらに最低限使いやすくするため、nano,Unity-tweak-tool、nautilus-open-terminalをapt-getでインストールしました。

caffe やSimpleCVに必要な依存ファイルのインストー

 新しく記事を書いたので、ここを参考にして下さい。時間はかかりますが、全部インストールすると、TX1のかなり手ごわいシステム構築に左右されないで、デープラーニングに専念できます。
takesan.hatenablog.com

Jetpack 64bit版の注意点

 32bit版では標準で付いていたfairfoxが付いていない(インストールしても動かない)。その代わりEpiphany Web Browserが付いています(Pi3のと同じ)。このブラウザは早いとかなんとか言われているのですが、Pi3では頻繁に止まり、だんだんスピードが落ちてくるので、私は好きじゃありません。だんだんスピードが遅くなるのはTX1も引き継いでいるようです。TX1の32bit版ではfairfoxがかなりいい線いっていましたので、今後のバジョンアップまで我慢。ちなみにChromeはインストールすらできませんでした。よく考えると、主にダウンロード用に使用するだけなので、今のままでも特に問題はありません。

 32bit版ではOpenCV4Tegraが、USB接続したWebCameraを認識しなかったのですが、64bit版も同様。WebCameraを使う場合は、標準OpenCVをインストールして、プログラム中でvideo1を指定すること。標準指定のvideo0では確実にエラーとなり、最悪システム全体がハングアップします。(これが分かるまで2日かかってしまいました。video0はどうやら開発ボードに付いているカメラのようですが、現状でOpencvから一般的な方法での接続は不可)修正すればOpenCV2.4のカメラを使用したexampleが実行できます。標準OpenCVPythonOpenCVインストールは上記私の記事を参考にして下さい。

 この後暫くしてから日本語環境にしてみましたが、頻繁にXwindowがハングしてしまうのでJetpacを再インストールする羽目になってしまいました。日本語環境にしないほうが安定して動くようです。

 OpenCVとは関係ありませんが試しにGPUを使ったCUDAサンプルプログラムを試してみると、こんな感じです。

       

 Pi3ではこんなことは絶対できません。すごい!!(金額もすごいけど)。無数の点の集まりを影付きで煙のように動かしています。

 TX1では32bit、64bitとも今の所Openframeworksは実行できません。(私としてはこれがかなりショック)

※2016/12 Openframeworksがインストールできました。ディープラーニングと合体させたらすごいことになりそう。 

                                 

 以下このボードの要、Caffeのインストール方法等を紹介します。まだNIVIDAホームページにも載ってませんので、かなり苦労しました(完了してみると大したことありませんが)。この時点で本体のeMMCは50%を超えてしまうので、SDカードへのインストールをお勧めします。開発ボードにはSATAコネクタも付いているので、余っているHDDなどがあれば、これにインストールしてもOKです。

TX1のGPUクロックレートを変更する方法が

https://devtalk.nvidia.com/default/topic/935300/jetson-tx1/deep-learning-inference-performance-validation-on-tx1/

に載っています。ここでは84480000Hzに変更していますが、他の記事を見るともう少し早くできます。つまり起動時の4倍になります。ただしこれを実行すると、画面の反応が相当もたつき出すので、画像を表示するソフトにはお勧めできません。(caffe,torch7等は問題無し。確実にスピード向上を実感できる)

※現時点(2016/11)ではJetpack2.3となり、video0の問題や画面のもたつきが解消された上に、動作スピードも大きく改善されています。この種のボードとしては、お世辞抜きで、最強になっていますので興味のある方は 、次の記事もどうぞ。
                                  

                                   

Intel Joule も確認してみました。ディープラーニングではTX1に完全に軍配が上がりますが、Ubuntuの使用勝手及びCPU性能はこちらの方が上でした。

                             

 Caffeのインストー

 今の所、本家のソースをダウンロードするのが無難です。NIVIDAで公開している32bit版のインストール方法

https://devtalk.nvidia.com/default/topic/935300/jetson-tx1/deep-learning-inference-performance-validation-on-tx1/

ではうまくいきません。(makeではなくmake all で一応コンパイル可能。またCUDA、cuDNNインストール部分は無視(この記事ではcuDNN32bit版をインストールしているため))。この記事の中のスピードTESTはかなり早く実行できるのですが、mnistなどの実行がfloat16ではできない。runtestもエラーが出て止まる。つまりかなり不安定=営業用でしょうね)これが実行できれば浮動小数点の精度を落としていてTX1ではスピード的にかなり有利なので、もう少し待つ必要がありそうです。しょうがないので、

      sudo apt-get install git

      git clone https://github.com/BVLC/caffe.git

ダウンロードしたcaffeディレクトリに入ってMakefile.config.exampleをMakefile.config に変更して、

      #USE_CUDNN :=1 の行を

       USE_CUDNN :=1 コメントを外す

      # CUSTOM_CXX := g++ の行を

       CUSTOM_CXX := g++-4.8 

に変更しました。この後

       make all -j4

でインストール開始。この設定でCUDA+cuDNNを使った最速モードでCaffeがインストールされます。

 コンパイルは、途中でNVCCを使ってることが確認できます。これは、GPUを最大限使ったコードを生成するコンパイルということを意味します。逆にNVCCが全く表示されなかったら設定がおかしいということです。MAKE中はワーニングは全く出ませんでした。このコンパイルも結構時間がかかります(20分程度)。うまくコンパイルできたら、make test -j3   make runtest でセルフテストが始まります。

  セルフテストがかなり長いので、初めの10分程度テスト状態が正常に動いているか確認した後は、ほったらかしにしておくのが最善。ビルドに失敗していたり、GPUがメモリーオーバーの場合、この間に大概errorが出て止まります。一部記事には数分なんて書いてありますが、何せ2000回程度のテストをランダムで行いますので、TX1ではものすごく長~い。テスト内容とテスト回数は乱数で決めてるので、運が良ければ早く終了するかもしれません。(セルフテストの実行時間はCPUスピードに比例するようです。Macで試してみたら、半分程度の時間で終了しました。)

 異常なければ、以下の様に涙の終了みたいなメッセージが出て終了。

f:id:TAKEsan:20160625205747p:plain

 エラーがなければすべての操作は正常に実行できることを意味しているようです。ただし、Caffe実行中GPUのメモリオーバーとなった場合は例外。こんな時はXwindow画面を低解像度に変更したりして、なるべくGPUの負担を軽減してやれば上手く行く様です。CaffeのGPUメモリは4Gを想定しているそうですが、TX1はCPU・GPUメモリが共用で4Gらしいので、Caffeのexampleを実行する限りGPUのメモリオーバーエラーにはなりません。

Python用のCaffeライブラリインストー

 画面を操作する等、複雑な処理を行う場合は、スクリプト言語としてPythonを標準で使用する様です。(mnistなどで学習の確認などを行う場合は必要なし)

   sudo apt-get purge python-pip

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

   sudo python get-pip.py

   (sudo apt-get install python-pipだと後からエラーが出る)

   for req in $(cat requirements.txt); do sudo pip install $req; done 

            (caffe/pythonフォルダ上で実行)

   sudo apt-get install python-dev python-numpy python-skimage

   cd ..

   make pycaffe

 終了後 .bashrcexport PYTHONPATH=~/caffe/python/:$PYTHONPATH として環境変数を設定する必要あり。(~/caffe部分は自分の環境による)

この辺りで再起動して、python 上で import caffe を入力してエラーが起きなければ構築完了。

Caffe付属の例題

 面白かったのは web-demoです。これは、実際の学習済みデータを使ったものですが、実行方法は
github.com

 に書いてあります。最後のapp.py -hを app.py -g に変更すると、GPUを使った最速モードになります。事前に sudo pip install flask でflaskライブラリをインストーする必要があります。

 TX1がサーバーになり、他のコンピューターのweb上でtegra-ubuntu.local:5000と入力すると、手持ちの写真をTX1が勉強した成果を教えてくれます。ちなみに今回の64bit版インストール以前に実行した32bit版では、GPU指定なしで認識に4.73秒。(ちゃんとプードルと答えている。すごおおーい)

f:id:TAKEsan:20160625205752p:plain

GPUをONすると0.422秒!!. 確かNIVIDA推奨のFP16caffeのGPUクロック最速だったと思います。

 これが、今回の64bit、GPU84480000Hzだとなんと0.207秒!!!!!!!!!。左下の数値に注目。

f:id:TAKEsan:20160625205745p:plain

 この数値の凄さというのは、私のMacCore i7 3.4Ghz)は、TX1のCPUスピードと比較すると約3倍(Pythonの簡単なテストで比較)高速であるため、仮にMacのCPUのみでこの写真を認識させたとした場合、1.6秒必要となり、そうなると7.7倍高速ということです。

 MacでCUDA+cuDNNを稼働させた場合は、TX1の3倍以上早くなるでしょうが、この大きさでこのスピードであれば、現状文句を言う人はいないのではないでしょうか。(この記事を書いた20日後にMacにcuDNNをONにしたCaffeをインストールして確認すると、CPUモードで0.271秒、GPUオプション有りで0.161秒でした。CPUモードが異常に早くなっています。MacのCPUモードでweb-testを実行させたところ、タイミングによってGPUモリーオーバーエラーが出ます。ということは、Mac版ではCPUモードでも何らかのルーチンでGPUを使っている可能性があります。でもTX1のGPUってかなり効率が良いんですね=Mac-->0.161秒,TX1-->0.207秒GPUコア数は私のMacの1/4。

 ちなみにTX1でSimpleCVもインストールできましたので、前にEdison用に作った顔認識のソースを動かしてみたら、

       

 こんな感じでした。これはTX1から顔認識画像をMJPEG配信しているところです。Pythonで実行していることを考えるとスピード的には十分(当然ですがEdisonとは比べ物にならない)です。(先に書きましたがプログラムソース中のビデオディバイス番号は1にすること。USBにwevCAMERAを接続すると ls /dev の実行で、最後の方にvideo1が表示されます。くれぐれも0にしないこと!!)

 OpenCVcやgpuサンプルでWebCameraを利用するプログラムを実行してみましたが、全てもっさりした動きでした(バイナリなのにSimpleCVとほとんど変わらない!!)。特にgpu版の顔認識サンプルcascadeclassfier_gpuは白黒表示にもかかわらず、感覚ではSimpleCV(今回試したWeb経由画像表示320x180ドット-->ディスプレイダイレクトではない!!)に明らかに負けています。ディスプレイへの表示部分がもたつくようですが、原因は今のところ不明

 もしTX1をロボットなどに組み込んで画像を確認するとすれば、テザリングをONにしたiPhone等を利用することになると思うので、当面SimpleCVで十分というところでしょうか。

 以前SimpleCVの動画を少しの工夫でflaskで配信した経験があるので、web-testとSimpleCVを組み合わせれば、Pythonでも動画の認識が簡単にできそうです。しかも0.5秒以内で。面白そうですね。その前にCaffeの本格的な勉強が必要ですけど。

 Pythonのライブラリではcv2、SimpleCVでカメラが使えますが、なぜかこちらもSimpleCVの方が表示スピードが速いような気がします。

 Jetpackについて現状では、入出力ディバイスの反応について色々不満もありますが、頻繁にバージョンアップされているので、今後が非常に楽しみです。

※この記事以降Jetpackは2.3にバージョンアップされ、画面のもたつき、Cameraの動作についての不満は解消されました。さらにCPU、GPUについてもなぜかスピードがかなり改善されて、上記web-testもなんと倍くらい早くなっています。 

 次回はTX1にtorch7をインストールして、早稲田大学で開発した白黒写真のカラー化ソフトを実行させてみます。50年以上前の写真に感激しました。

                                 

 MacLinuxが動いても、MacファンとすればOSXでCaffeを動かしてTX1と連携させたいですよね。Mac OSX10.11.5にcuDNNを有効にした高速Caffeのインストールに成功しました。やはりすごく早かった...。

                               

 

                                では、また。

 

Openframeworks で Pi3 7" タッチスクリーン LCD のタッチ機能を有効にする。

今回のテスト画面は

標準のGUI addonを使ったソースに変更した前回のD6Tプログラムを実行させてみるとこんな感じ。

                            

 OF標準のofxGuiを使ってスライダーをタッチスクリーン用に作って見ました。反応もまずまず。OF標準GUIを大きく設定すると、タッチスクリーンでも確実にタップできます。デザインもそんなに悪くありません。

                         

   こちらはofxBox2dのexample。60fps出てます。早っ!!。タッチスクリーンだと結構快適。

 スピードが要求されるソフトを作る時はRaspberry Pi 7" Touch Screen LCDがGood!!。フレームレートが60fpsってことはIGZOパネルと比べて2倍。視野率とか発色もかなり良。最大の欠点は表示範囲が狭いことですが、それさえ我慢すれば、IGZOパネルと比べてWEBもかなり早く表示されます。

 で、今回は以前別の基盤(UDOO)を取り付けていたスタンドをPi3+Raspberry Pi 7" Touch Screen LCDに載せ換えました。私のブログのヘッダーにつけている写真の全体像です。

          f:id:TAKEsan:20160504221848j:plain

      アンティーク感満載!!。Xscreenseverが動き出すと部屋のオブジェになります。

f:id:TAKEsan:20160504225933j:plainf:id:TAKEsan:20160504221849j:plain

           でも裏側は、結構雑だったりして......。

 雑貨コーナーで買ってきた真鍮製6,500円のフォトフレームに、特注の電圧計(協和電気計器株式会社)を付けたもの。電圧計は3V Maxにしました。ワニ口クリップをつけてアナログピンのテストに使ってます。

 タッチ機能をOFで使うための設定

 Pi3でOpenframeworksを実行させるとしたら、このディスプレイを使うと実行スピードや発色、フォントの取り扱い等、使い易さが抜群です。

 これでタッチ機能が使えれば、Pi3で本格的に独立したアプリケーションが比較的簡単に作れます。GUIを工夫すればiPhone並みのアプリが作れるのではないでしょうか?

 設定方法は、前々回のところで説明しましたが、~/of_v0.9.3_linuxarmv6l_release/libs/openFrameworks/app/ofAppEGLWindow.cpp

の中身を変更するだけで済みました。

まずevtest をインストール

  sudo apt-get install evtest

インストールしたら

  evtest

f:id:TAKEsan:20160504212456p:plain

                evtestを実行している様子

 表示された「FT5406 memory based driver」のイベント名を調べます 私の場合は、念のためUSBマウスを接続しているので event3 であること確認できます。

 今回キーボードの設定は変えませんので、マウス部分だけを修正。まず安全のため、ofAppEGLWindow.cppのバックアップを忘れずに。

変更箇所は、コメントで「By TAKEsan」が書き込まれている以下14行です。(ofAppEGLWindow.cppのソースを変更)

f:id:TAKEsan:20160504211955p:plain

           110行付近 event-mouse を event○○ に変更

f:id:TAKEsan:20160504211953p:plain

            200行付近 mouSescaleX、Yを 1.0fに変える

f:id:TAKEsan:20160504211951p:plain

          400行付近 ここも、mouSescaleX、Yを 1.0fに変える

f:id:TAKEsan:20160504211948p:plain

        1350行付近 /dev/input/by-path をdev/input/ に変更。上記2箇所

f:id:TAKEsan:20160504211944p:plain

1670行付近 上記6箇所(By TAKEsan 部分)。上から、2行追加。次の2箇所も追加。この4箇所追加した部分がタッチパネル設定のキモ。次にコメントを入れ(ofLogNotice部分)、最後にBTN_LEFTを330に変更。見にくいですが拡大すると文字が見えると思います。

 あとは通常どおりコンパイルするだけで、マウスの代わりにタッチディスプレイが使えるようになります。

試しに openframeworkのexamplesからgui guiexample のフォルダに入って 

 make

 make run

してみると、GUIメニューが小さすぎて指では操作しにくいのですが、マウスの代わりにタッチスクリーンが確実に機能します。更にプログラム中でGUIの大きさを変えることでタッチ機能を存分に使いこなせるようになります。

f:id:TAKEsan:20160504221851j:plain

                  庭に咲いたチューリップがあまりにも綺麗だったので。

 

ではまた。

ROBOX で T-GRASE フィラメントを試してみる。

T-GRASE フィラメントって聞いたことありますか?

f:id:TAKEsan:20160425190113j:plain

          最終的に成功した造形物。結構魅力的。

 ガラスのような光沢で透明感のあるフィラメントです。PETボトルの再生フィラメントの一種だそうです。このフィラメントを手に入れたので早々試してみます。

f:id:TAKEsan:20160425185917j:plain


 設定温度は標準で212℃〜224℃、ノズルが太いほど透明感が出るとのことなので、ROBOXの太い方のノズルを有効利用するには最適と思い。試してみました。
 そもそも。ROBOXには2本のノズルが付いていて(0.3mm,0.8mm)、基本NOMAL出力をしている者としては、現状全く0.8mmノズルを活用していません。これを使うのにうってつけ!!。

 ただ、現行のROBOX専用印刷ソフトAutoMakerV2.0.3は、結構バグがあります。自由にフィラメントの温度設定ができない上に、層の厚さを0.6mm以上にすると最下層の固着に0.3mmノズルが使えないばかりかRaft、Brimが全く印刷できません(専用フィラメントは全く問題なし)。この点に関しては、今後のバージョンアップを待つことにします。
 このため、最下層がまともにベッド(印刷台)に張り付きません。T-GRASE向きの造形物が全く作成できない!!
 しょうがないので、層の厚さを0.5mm設定にしてみると、気泡がたくさん入って透明感が出ない(比較写真参照)。これじゃーなんだかってことで、いつものように試行錯誤してやっと成功しました。最終的なヘッドとスピードの設定は以下の通り。透明にするための設定がターイヘンでした。

f:id:TAKEsan:20160425190110p:plain

層の暑さは0.75mm。充填密度は一応0。ペリメータは1層。トップ、ボトムの層は0にします。モデルは円柱のような物を作って、側だけを印刷するイメージです。底面を2ぐらいにすると当然底も印刷できます。

f:id:TAKEsan:20160425193117p:plain

主要なノズルは0.8mmに設定。押し出し幅は1層目とペリメータを1.2mmにします。ここもバグで、保存しても0.5mmに変更されてしまうので、印刷をする前に絶対に確認する必要あり。

f:id:TAKEsan:20160425190142p:plain

     印刷スピードで変更できるところは、全てT-GRASE推奨の8mm/sにする。
 フィラメントは搭載フィラメントの検出のチェックを外して、ABSフィラメントを設定にして、

f:id:TAKEsan:20160425190139p:plain

左の材料選択部分をABSとする。(CO-PET他4種類の材料が選択できますがABSが最良。ABSの溶解温度が235度となりT-Graseの上限となりますが、ROBOXにジャストフィット)このフィラメントはものすごく温度に敏感で、少しでも違う環境になると、気泡が無数に入り透明度が全くなくなります。ROBOXの場合はABSのCrystal Clearである必要があるようです。この設定では同じABSでも印刷台とノズルの温度設定が10度程度低くなります。それでも室内温度によって気泡の入り方が全く違います。庫内温度をなるべく下げる必要があるようです。印刷中気泡が目立つようになったら、本体一時停止ボタンを押して1分程度放置して多少冷やしてから再開すると、なぜか気泡がなくなります。昨日までうまくいっていたのに、気温の高い今日がダメだということは、庫内環境に敏感だということか?。このフィラメント手強くて面白い。

f:id:TAKEsan:20160425185916j:plain

今回のフィラメント設置には、前にブロンズフィラメントを使って大失敗した時に作ったフィラメント台を有効利用。

 層厚は、0.8mm前後にすると良いみたい。ベッドに押しつけないで、材料を柔らかめにして、表現が悪いですが垂れ流しみたいに造形させる。ベッドにノンオイルのヘアスプレーを吹きかけると完璧に張り付きました。

f:id:TAKEsan:20160425185915j:plain

層の厚さの違いによるプリントの比較は、以下の写真。

f:id:TAKEsan:20160425185913j:plain

 

f:id:TAKEsan:20160425185914j:plain

 一番左から層厚0.5、0,6、0,85mmです。最終的に0.75mmに落ち着きました。これだと最下層(ボトム)の平面もなんとか剥がれないでプリントできました。
 層が厚くなるとさすがに綺麗です。スンバラシイ。魅力的な光沢が出ます。造形物は、サポートを必要としないなだらかな曲線を使う円筒形のものが良さそう(今回の設定では、細かさを追求する造形には全く向きません)。一般的なフィラメントでは気になる、層の段差を逆手に取った作品が向きそうです。ちなみにこのフィラメントと印刷設定の特性を生かした小物がこれ。イヤリングだそうですが、なかなかのものができました。ガラスの質感です。ノーマル印刷では表面の凸凹が鋭利になってしまいますが、今回の設定では作品の味になります。

f:id:TAKEsan:20160425190116j:plain

でもPLAの透明でもこの設定なら....。

 と思って、比較してみました。左側がPLA、右がT-GRASE。全く違うでしょ。透明のPLAもかなり健闘していますが、艶と透明度それに表面反射の質がGrase!!。T-GRASEにこだわらないで0.8mmノズルは他の有色フィラメントでも面白い作品ができそうです。

f:id:TAKEsan:20160425190115j:plain

他のカットを少し紹介。

f:id:TAKEsan:20160425190024j:plain

f:id:TAKEsan:20160425190113j:plain

f:id:TAKEsan:20160426083904j:plain

f:id:TAKEsan:20160425190112j:plain

f:id:TAKEsan:20160425195512j:plain

f:id:TAKEsan:20160425190025j:plain

 T-GRASEフィラメントは、他にグリーンとダークグレーがあります。ペリメータの数を2〜3にすると厚みのある魅力的な作品ができそうです。

4月29日追記

 この後色々試したのですが、どうしてもたくさん気泡が入って透明ではなくなります(層厚0.85mmにしても上記写真の層厚0.5mmにした感じ)。良く見るとちょうど水が沸騰するように、ノズルから出てきた瞬間、小さな泡が膨張して気泡だらけになってしまいます。環境温度の違いだと思ってたのですが、ノズルの温度設定が高すぎるような.....。

 問題は違うところでした。プリントプロフィールで新しい設定をする時、エクストルージョンで層の高さを変更すると、次のタブ設定「2つのノズル」の押し出し巾が1.2mmから0.5mmに勝手に戻ってしまうことでした。設定を保存する場合は「2つのノズル」タブを開いた状態にして押し出し幅を確認してからの方が良さそう。

 多分押し出し巾を小さく設定すると、エクストルーターがフィラメントの押し出し圧力を調整するため、高速に押したり引いたりして、高周期の振動が生まれ、ノズルの先端で気泡が入ってしまうのでしょう。太い方のノズルが影響を受けるようです。この現象はPLAやABSでは全く起こりません。T-GRASEは特に敏感のようです。結局フィラメントプロフィールは上記設定。フィラメントは、若干低め温度設定となるClear CO-PETに落ち着きました。この設定だと、ABSより印刷開始時間が早くなります。

この設定で、

eyesofanother.com

 ここのページと質感が全く同じのものができました。しばらくハマリそう。

 

Pi3 で mraa を使う(OfとPythonでD6Tを動かす)

mraaって

 Edison用のIO制御ライブラリだと思ってたのですが、Piにインストールできることが分かりました。これを導入するとPythonからすごく簡単にIO制御できます。1回のインストールでC,C++でも使えます。Openframeworksからも使えたのでついでに紹介。今回は最終的にこんなものができました。
f:id:TAKEsan:20160420224633j:plain
オムロンの非接触赤外線センサーD6TをOpenframeworksを使って、Pi3+IGZOディスプレイで表示させた。本来4×4=16か所しか計測できないが、なんと64×64ドットに補間!!(前に作ったものだけど)。(今回はカラーマップを変更できるようにした)
f:id:TAKEsan:20160420224631j:plain
   別のカラーマップに変更して表示させてみた、
       
 実際動かしているところ。カラーマップを変更したり、補間レベルを調整しているところです。最高の64×64ドットでもまあまあのスピードでした。トニカク4×4が嘘みたいです。これを見ただけでは分かりにくいですけど、左右に動いているのが私の手。右側が顔です。なんとなく雰囲気が伝わってくると思います。つまりこのセンサーは使い様によってペットの動きに合わせた監視カメラや、太陽の動きに合わせた制御システムなんかが作れちゃったりしますのですぞ!!。
 ただ、mraaライブラリを使っても今までの経験では、SPIやI2Cで、センサーの性格上どうしても実行できない場合があります。その場合はライブラリを変える必要があります。Piの方がEdisonと比べてセンサーとの相性もいいみたいなので、大きさが許されるならPi3をIOTとして使う用途がたくさん出て来るのでは?(PiにインストールしたmraaはPWMピンの制御ができませんのでご注意を)
 今までの記事で、テスト用にオムロンのD6T非接触赤外線センサーを使っていたので、うまくいくかどうか確認しました。D6Tに関するPIのPythonでの実行方法は結構紹介されていますが、どれも必要以上に複雑で不安定。今回mraaを利用して自分で作って見たら、比べ物にならないくらい安定していました。
 Piの代表的なIO制御ライブラリであるWiringpi ではD6T特有のI2Cからデータを35バイト読み込むことがどうしてもできない(クロック又はコマンドの問題)。smbusを使った例ではD6Tの読み取りデータが全くダメ。ここでEdisonで使っていたmraaがとても簡単だったことを思い出し、mraaをPi3にインストールすることにしたワケです。

maraをPi3へインストール

 Pi3へのmraaインストールが結構手間取ったのでメモしておきます。
mraa はここから持ってくる
https://github.com/intel-iot-devkit/mraaMac でダウンロードして、解凍。forklift などでpiのhomeへディレクトリ名称をmraaに変更してコピー 
または、Pi3からhttps://github.com/intel-iot-devkit/mraa/archive/master.zipをダウンロードして解凍。
(一部紹介されているhttps://github.com/intel-iot-devkit/mraa.gitだとPythonからmraaが使えないので注意!!)
一応

  sudo apt-get install git
  sudo apt-get install make
sudo apt-get install cmake
  sudo apt-get install python-dev
  sudo apt-get install swig
前回cmakeのインストールが入っていませんでした。
で必要なライブラリをインストール。
Pi3 から
  cd mraa
  mkdir build
cd build <--前回入っていませんでした。ゴメンナサイ
  cmake .. -DBUILDSWIGNODE=OFF
  make
  sudo make install
  cd
ここでmraa.pyができているかどうか確認
sudo find / -name mraa.py
できていれば、mraa.pyが作られた場所が表示される。表示されなければmraa.pyができていないので最初からやり直し。
それから
  sudo ldconfig
  sudo ldconfig -p | grep mraa
を実行。
次に一応.bashrcと.profileのファイルにmraaライブラリのパスを書き込みます。
  nano ~/.bashrc
  nano ~/.profile
を実行し、両方の行の最後に
  export PYTHONPATH=$PYTHONPATH:$(dirname $(find /usr/local -name mraa.py))
を記入して保存終了。つまり起動時にmraaライブラリのパスを通します。

Pythonでの簡単なD6T温度表示プログラム

 ここでの表示は3桁の整数。10で割ると温度になる。カンタンカンタン!!

import mraa
import time
D6T_addr = 0x0A
D6T_cmd =  0x4C
tdata=[]
i=0
x = mraa.I2c(0)
while i<1000:
	x.address(D6T_addr)
	x.writeByte(D6T_cmd)
        time.sleep(0.01)
	y=x.read(35)  
	for var in range(0, 16):
		tdata.append((y[(var*2+2)]+(y[(var*2+3)]<<8)))
	print tdata
	tdata=[]
	i=i+1

 pi3ではmraaのi2cバス番号を0にします。その他にLチカも簡単にできたので、他のIO制御も多分OK。
コンソールでの表示結果はこんな感じ。
f:id:TAKEsan:20160420214009p:plain
尚GPIOピン番号はここに書いてあります。
http://iotdk.intel.com/docs/master/mraa/rasppi.html
        f:id:TAKEsan:20160420214513p:plain

Openframeworks編

 前回Pi3へのmraaのインストール方法を紹介しました。
takesan.hatenablog.comOpenframeworksの入力機器設定方法も書きました。この時はBluetoothキーボードとマウスでしたが、電源を2.5Aにしてもやはり今のところPi3ではエラー頻発で、Pi3自体がハングアップしてしまい、使いものにならないと結論。今は無線キーボードとマウスを使っています。
 但しevtestではf:id:TAKEsan:20160420214013p:plain
 このようになってしまい、どれが該当する機器なのかわからない(同じ機器名称が3箇所ダブっている)ので、前々回の前半2箇所のevent番号を変えてテストプログラムをコンパイルしてみて各々確認しました。今は安定してOpenframeworksで使用できています。

Openframeworksでのmraa実行方法

まずmraaを前回の方法でインストール。
変更箇所は2箇所です。
mraaを使うディレクトリのconfig.makeを修正。(2016/12/2 追記 下図中mraaを -mraa に変更してください。また bin/deta フォルダを作りcooperBlack.ttfを examples/fontSapesExample/bin/dataからコピーしてください)
f:id:TAKEsan:20160420214016p:plain
srcディレクトリのofApp.hにincludeを追加します。

#pragma once

#include "ofMain.h"
#include "mraa.hpp"     //  <---ここんとこを変更 mara.hpp をインクルード
class ofApp : public ofBaseApp{
	public:
		void setup();
		void update();
		void draw();
		
		void keyPressed(int key);
		void keyReleased(int key);
		void mouseMoved(int x, int y);
		void mouseDragged(int x, int y, int button);
		void mousePressed(int x, int y, int button);
		void mouseReleased(int x, int y, int button);
		void mouseEntered(int x, int y);
		void mouseExited(int x, int y);
		void windowResized(int w, int h);
		void dragEvent(ofDragInfo dragInfo);
		void gotMessage(ofMessage msg);
};

あとはmraaのC++関数がすべてOpenframeworksで使えるようになります。

D6TのOpenframeworksソース

 今回は以前作ったソースをそのまま利用しました。D6Tの4X4の読み取りデータを最高64X64に補間(ラグランジュ曲線利用)して表示させるものです。
 使うセンサーはオムロンD6T赤外線センサーだけです。接続は電源5V、SDA,SCL,GNDの4本だけ。結構膨大な計算量なのでPi3でどのくらいのスピードになるか興味深いところです。
 更に今回はOpenCVのカラーマップデータを利用して、いろいろなカラーマップに変更できるものを作ってみました。
冒頭の動画が実行結果です。表示スピードはほぼ満足。CPU稼働率は全体でたった6%!!
f:id:TAKEsan:20160420224638j:plain
D6T非接触赤外線センサーの接続状況。ブレッドボードは薄いバックスキンレザーを両面テープで貼り付けた。
f:id:TAKEsan:20160420224730j:plain
自作のPi3ケースの舞台裏
ofApp.hは上記ソース参照。

main.cpp
#include "ofMain.h"
#include "ofApp.h"

//========================================================================
int main( ){

	ofSetupOpenGL(1024,918, OF_WINDOW);			// <-------- setup the GL context

	// this kicks off the running of my app
	// can be OF_WINDOW or OF_FULLSCREEN
	// pass in width and height too:
	ofRunApp( new ofApp());

}
ofAPP.cpp

いやはや、カラーマップ部分が膨大。

#include "ofApp.h"
    // Equals the GNU Octave colormap "autumn".
            float rx1[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
            float gx1[] = { 0, 0.01587301587301587, 0.03174603174603174, 0.04761904761904762, 0.06349206349206349, 0.07936507936507936, 0.09523809523809523, 0.1111111111111111, 0.126984126984127, 0.1428571428571428, 0.1587301587301587, 0.1746031746031746, 0.1904761904761905, 0.2063492063492063, 0.2222222222222222, 0.2380952380952381, 0.253968253968254, 0.2698412698412698, 0.2857142857142857, 0.3015873015873016, 0.3174603174603174, 0.3333333333333333, 0.3492063492063492, 0.3650793650793651, 0.3809523809523809, 0.3968253968253968, 0.4126984126984127, 0.4285714285714285, 0.4444444444444444, 0.4603174603174603, 0.4761904761904762, 0.492063492063492, 0.5079365079365079, 0.5238095238095238, 0.5396825396825397, 0.5555555555555556, 0.5714285714285714, 0.5873015873015873, 0.6031746031746031, 0.6190476190476191, 0.6349206349206349, 0.6507936507936508, 0.6666666666666666, 0.6825396825396826, 0.6984126984126984, 0.7142857142857143, 0.7301587301587301, 0.746031746031746, 0.7619047619047619, 0.7777777777777778, 0.7936507936507936, 0.8095238095238095, 0.8253968253968254, 0.8412698412698413, 0.8571428571428571, 0.873015873015873, 0.8888888888888888, 0.9047619047619048, 0.9206349206349206, 0.9365079365079365, 0.9523809523809523, 0.9682539682539683, 0.9841269841269841, 1};
            float bx1[] = {  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    // Equals the GNU Octave colormap "bone".
            float rx2[] = { 0, 0.01388888888888889, 0.02777777777777778, 0.04166666666666666, 0.05555555555555555, 0.06944444444444445, 0.08333333333333333, 0.09722222222222221, 0.1111111111111111, 0.125, 0.1388888888888889, 0.1527777777777778, 0.1666666666666667, 0.1805555555555556, 0.1944444444444444, 0.2083333333333333, 0.2222222222222222, 0.2361111111111111, 0.25, 0.2638888888888889, 0.2777777777777778, 0.2916666666666666, 0.3055555555555555, 0.3194444444444444, 0.3333333333333333, 0.3472222222222222, 0.3611111111111111, 0.375, 0.3888888888888888, 0.4027777777777777, 0.4166666666666666, 0.4305555555555555, 0.4444444444444444, 0.4583333333333333, 0.4722222222222222, 0.4861111111111112, 0.5, 0.5138888888888888, 0.5277777777777778, 0.5416666666666667, 0.5555555555555556, 0.5694444444444444, 0.5833333333333333, 0.5972222222222222, 0.611111111111111, 0.6249999999999999, 0.6388888888888888, 0.6527777777777778, 0.6726190476190474, 0.6944444444444442, 0.7162698412698412, 0.7380952380952381, 0.7599206349206349, 0.7817460317460316, 0.8035714285714286, 0.8253968253968254, 0.8472222222222221, 0.8690476190476188, 0.8908730158730158, 0.9126984126984128, 0.9345238095238095, 0.9563492063492063, 0.978174603174603, 1};
            float gx2[] = { 0, 0.01388888888888889, 0.02777777777777778, 0.04166666666666666, 0.05555555555555555, 0.06944444444444445, 0.08333333333333333, 0.09722222222222221, 0.1111111111111111, 0.125, 0.1388888888888889, 0.1527777777777778, 0.1666666666666667, 0.1805555555555556, 0.1944444444444444, 0.2083333333333333, 0.2222222222222222, 0.2361111111111111, 0.25, 0.2638888888888889, 0.2777777777777778, 0.2916666666666666, 0.3055555555555555, 0.3194444444444444, 0.3353174603174602, 0.3544973544973544, 0.3736772486772486, 0.3928571428571428, 0.412037037037037, 0.4312169312169312, 0.4503968253968254, 0.4695767195767195, 0.4887566137566137, 0.5079365079365078, 0.5271164021164021, 0.5462962962962963, 0.5654761904761904, 0.5846560846560845, 0.6038359788359787, 0.623015873015873, 0.6421957671957671, 0.6613756613756612, 0.6805555555555555, 0.6997354497354497, 0.7189153439153438, 0.7380952380952379, 0.7572751322751322, 0.7764550264550264, 0.7916666666666666, 0.8055555555555555, 0.8194444444444444, 0.8333333333333334, 0.8472222222222222, 0.861111111111111, 0.875, 0.8888888888888888, 0.9027777777777777, 0.9166666666666665, 0.9305555555555555, 0.9444444444444444, 0.9583333333333333, 0.9722222222222221, 0.986111111111111, 1};
            float bx2[] = { 0, 0.01917989417989418, 0.03835978835978836, 0.05753968253968253, 0.07671957671957672, 0.09589947089947089, 0.1150793650793651, 0.1342592592592592, 0.1534391534391534, 0.1726190476190476, 0.1917989417989418, 0.210978835978836, 0.2301587301587301, 0.2493386243386243, 0.2685185185185185, 0.2876984126984127, 0.3068783068783069, 0.326058201058201, 0.3452380952380952, 0.3644179894179894, 0.3835978835978835, 0.4027777777777777, 0.4219576719576719, 0.4411375661375661, 0.4583333333333333, 0.4722222222222222, 0.4861111111111111, 0.5, 0.5138888888888888, 0.5277777777777777, 0.5416666666666666, 0.5555555555555556, 0.5694444444444444, 0.5833333333333333, 0.5972222222222222, 0.6111111111111112, 0.625, 0.6388888888888888, 0.6527777777777778, 0.6666666666666667, 0.6805555555555556, 0.6944444444444444, 0.7083333333333333, 0.7222222222222222, 0.736111111111111, 0.7499999999999999, 0.7638888888888888, 0.7777777777777778, 0.7916666666666666, 0.8055555555555555, 0.8194444444444444, 0.8333333333333334, 0.8472222222222222, 0.861111111111111, 0.875, 0.8888888888888888, 0.9027777777777777, 0.9166666666666665, 0.9305555555555555, 0.9444444444444444, 0.9583333333333333, 0.9722222222222221, 0.986111111111111, 1};
    // Equals the GNU Octave colormap "jet".
            float rx3[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.00588235294117645,0.02156862745098032,0.03725490196078418,0.05294117647058827,0.06862745098039214,0.084313725490196,0.1000000000000001,0.115686274509804,0.1313725490196078,0.1470588235294117,0.1627450980392156,0.1784313725490196,0.1941176470588235,0.2098039215686274,0.2254901960784315,0.2411764705882353,0.2568627450980392,0.2725490196078431,0.2882352941176469,0.303921568627451,0.3196078431372549,0.3352941176470587,0.3509803921568628,0.3666666666666667,0.3823529411764706,0.3980392156862744,0.4137254901960783,0.4294117647058824,0.4450980392156862,0.4607843137254901,0.4764705882352942,0.4921568627450981,0.5078431372549019,0.5235294117647058,0.5392156862745097,0.5549019607843135,0.5705882352941174,0.5862745098039217,0.6019607843137256,0.6176470588235294,0.6333333333333333,0.6490196078431372,0.664705882352941,0.6803921568627449,0.6960784313725492,0.7117647058823531,0.7274509803921569,0.7431372549019608,0.7588235294117647,0.7745098039215685,0.7901960784313724,0.8058823529411763,0.8215686274509801,0.8372549019607844,0.8529411764705883,0.8686274509803922,0.884313725490196,0.8999999999999999,0.9156862745098038,0.9313725490196076,0.947058823529412,0.9627450980392158,0.9784313725490197,0.9941176470588236,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0.9862745098039216,0.9705882352941178,0.9549019607843139,0.93921568627451,0.9235294117647062,0.9078431372549018,0.892156862745098,0.8764705882352941,0.8607843137254902,0.8450980392156864,0.8294117647058825,0.8137254901960786,0.7980392156862743,0.7823529411764705,0.7666666666666666,0.7509803921568627,0.7352941176470589,0.719607843137255,0.7039215686274511,0.6882352941176473,0.6725490196078434,0.6568627450980391,0.6411764705882352,0.6254901960784314,0.6098039215686275,0.5941176470588236,0.5784313725490198,0.5627450980392159,0.5470588235294116,0.5313725490196077,0.5156862745098039,0.5};
            float gx3[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.001960784313725483,0.01764705882352935,0.03333333333333333,0.0490196078431373,0.06470588235294117,0.08039215686274503,0.09607843137254901,0.111764705882353,0.1274509803921569,0.1431372549019607,0.1588235294117647,0.1745098039215687,0.1901960784313725,0.2058823529411764,0.2215686274509804,0.2372549019607844,0.2529411764705882,0.2686274509803921,0.2843137254901961,0.3,0.3156862745098039,0.3313725490196078,0.3470588235294118,0.3627450980392157,0.3784313725490196,0.3941176470588235,0.4098039215686274,0.4254901960784314,0.4411764705882353,0.4568627450980391,0.4725490196078431,0.4882352941176471,0.503921568627451,0.5196078431372548,0.5352941176470587,0.5509803921568628,0.5666666666666667,0.5823529411764705,0.5980392156862746,0.6137254901960785,0.6294117647058823,0.6450980392156862,0.6607843137254901,0.6764705882352942,0.692156862745098,0.7078431372549019,0.723529411764706,0.7392156862745098,0.7549019607843137,0.7705882352941176,0.7862745098039214,0.8019607843137255,0.8176470588235294,0.8333333333333333,0.8490196078431373,0.8647058823529412,0.8803921568627451,0.8960784313725489,0.9117647058823528,0.9274509803921569,0.9431372549019608,0.9588235294117646,0.9745098039215687,0.9901960784313726,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0.9901960784313726,0.9745098039215687,0.9588235294117649,0.943137254901961,0.9274509803921571,0.9117647058823528,0.8960784313725489,0.8803921568627451,0.8647058823529412,0.8490196078431373,0.8333333333333335,0.8176470588235296,0.8019607843137253,0.7862745098039214,0.7705882352941176,0.7549019607843137,0.7392156862745098,0.723529411764706,0.7078431372549021,0.6921568627450982,0.6764705882352944,0.6607843137254901,0.6450980392156862,0.6294117647058823,0.6137254901960785,0.5980392156862746,0.5823529411764707,0.5666666666666669,0.5509803921568626,0.5352941176470587,0.5196078431372548,0.503921568627451,0.4882352941176471,0.4725490196078432,0.4568627450980394,0.4411764705882355,0.4254901960784316,0.4098039215686273,0.3941176470588235,0.3784313725490196,0.3627450980392157,0.3470588235294119,0.331372549019608,0.3156862745098041,0.2999999999999998,0.284313725490196,0.2686274509803921,0.2529411764705882,0.2372549019607844,0.2215686274509805,0.2058823529411766,0.1901960784313728,0.1745098039215689,0.1588235294117646,0.1431372549019607,0.1274509803921569,0.111764705882353,0.09607843137254912,0.08039215686274526,0.06470588235294139,0.04901960784313708,0.03333333333333321,0.01764705882352935,0.001960784313725483,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
            float bx3[] = {0.5,0.5156862745098039,0.5313725490196078,0.5470588235294118,0.5627450980392157,0.5784313725490196,0.5941176470588235,0.6098039215686275,0.6254901960784314,0.6411764705882352,0.6568627450980392,0.6725490196078432,0.6882352941176471,0.7039215686274509,0.7196078431372549,0.7352941176470589,0.7509803921568627,0.7666666666666666,0.7823529411764706,0.7980392156862746,0.8137254901960784,0.8294117647058823,0.8450980392156863,0.8607843137254902,0.8764705882352941,0.892156862745098,0.907843137254902,0.9235294117647059,0.9392156862745098,0.9549019607843137,0.9705882352941176,0.9862745098039216,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0.9941176470588236,0.9784313725490197,0.9627450980392158,0.9470588235294117,0.9313725490196079,0.915686274509804,0.8999999999999999,0.884313725490196,0.8686274509803922,0.8529411764705883,0.8372549019607844,0.8215686274509804,0.8058823529411765,0.7901960784313726,0.7745098039215685,0.7588235294117647,0.7431372549019608,0.7274509803921569,0.7117647058823531,0.696078431372549,0.6803921568627451,0.6647058823529413,0.6490196078431372,0.6333333333333333,0.6176470588235294,0.6019607843137256,0.5862745098039217,0.5705882352941176,0.5549019607843138,0.5392156862745099,0.5235294117647058,0.5078431372549019,0.4921568627450981,0.4764705882352942,0.4607843137254903,0.4450980392156865,0.4294117647058826,0.4137254901960783,0.3980392156862744,0.3823529411764706,0.3666666666666667,0.3509803921568628,0.335294117647059,0.3196078431372551,0.3039215686274508,0.2882352941176469,0.2725490196078431,0.2568627450980392,0.2411764705882353,0.2254901960784315,0.2098039215686276,0.1941176470588237,0.1784313725490199,0.1627450980392156,0.1470588235294117,0.1313725490196078,0.115686274509804,0.1000000000000001,0.08431372549019622,0.06862745098039236,0.05294117647058805,0.03725490196078418,0.02156862745098032,0.00588235294117645,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    // Equals the GNU Octave colormap "rainbow".
            float rx4[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.9365079365079367, 0.8571428571428572, 0.7777777777777777, 0.6984126984126986, 0.6190476190476191, 0.53968253968254, 0.4603174603174605, 0.3809523809523814, 0.3015873015873018, 0.2222222222222223, 0.1428571428571432, 0.06349206349206415, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.03174603174603208, 0.08465608465608465, 0.1375661375661377, 0.1904761904761907, 0.2433862433862437, 0.2962962962962963, 0.3492063492063493, 0.4021164021164023, 0.4550264550264553, 0.5079365079365079, 0.5608465608465609, 0.6137566137566139, 0.666666666666667};
            float gx4[] = { 0, 0.03968253968253968, 0.07936507936507936, 0.119047619047619, 0.1587301587301587, 0.1984126984126984, 0.2380952380952381, 0.2777777777777778, 0.3174603174603174, 0.3571428571428571, 0.3968253968253968, 0.4365079365079365, 0.4761904761904762, 0.5158730158730158, 0.5555555555555556, 0.5952380952380952, 0.6349206349206349, 0.6746031746031745, 0.7142857142857142, 0.753968253968254, 0.7936507936507936, 0.8333333333333333, 0.873015873015873, 0.9126984126984127, 0.9523809523809523, 0.992063492063492, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.9841269841269842, 0.9047619047619047, 0.8253968253968256, 0.7460317460317465, 0.666666666666667, 0.587301587301587, 0.5079365079365079, 0.4285714285714288, 0.3492063492063493, 0.2698412698412698, 0.1904761904761907, 0.1111111111111116, 0.03174603174603208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
            float bx4[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.01587301587301582, 0.09523809523809534, 0.1746031746031744, 0.2539682539682535, 0.333333333333333, 0.412698412698413, 0.4920634920634921, 0.5714285714285712, 0.6507936507936507, 0.7301587301587302, 0.8095238095238093, 0.8888888888888884, 0.9682539682539679, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
    // Equals the GNU Octave colormap "ocean".
            float rx5[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.04761904761904762, 0.09523809523809523, 0.1428571428571428, 0.1904761904761905, 0.2380952380952381, 0.2857142857142857, 0.3333333333333333, 0.3809523809523809, 0.4285714285714285, 0.4761904761904762, 0.5238095238095238, 0.5714285714285714, 0.6190476190476191, 0.6666666666666666, 0.7142857142857143, 0.7619047619047619, 0.8095238095238095, 0.8571428571428571, 0.9047619047619048, 0.9523809523809523, 1};
            float gx5[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.02380952380952381, 0.04761904761904762, 0.07142857142857142, 0.09523809523809523, 0.119047619047619, 0.1428571428571428, 0.1666666666666667, 0.1904761904761905, 0.2142857142857143, 0.2380952380952381, 0.2619047619047619, 0.2857142857142857, 0.3095238095238095, 0.3333333333333333, 0.3571428571428572, 0.3809523809523809, 0.4047619047619048, 0.4285714285714285, 0.4523809523809524, 0.4761904761904762, 0.5, 0.5238095238095238, 0.5476190476190477, 0.5714285714285714, 0.5952380952380952, 0.6190476190476191, 0.6428571428571429, 0.6666666666666666, 0.6904761904761905, 0.7142857142857143, 0.7380952380952381, 0.7619047619047619, 0.7857142857142857, 0.8095238095238095, 0.8333333333333334, 0.8571428571428571, 0.8809523809523809, 0.9047619047619048, 0.9285714285714286, 0.9523809523809523, 0.9761904761904762, 1};
            float bx5[] = { 0, 0.01587301587301587, 0.03174603174603174, 0.04761904761904762, 0.06349206349206349, 0.07936507936507936, 0.09523809523809523, 0.1111111111111111, 0.126984126984127, 0.1428571428571428, 0.1587301587301587, 0.1746031746031746, 0.1904761904761905, 0.2063492063492063, 0.2222222222222222, 0.2380952380952381, 0.253968253968254, 0.2698412698412698, 0.2857142857142857, 0.3015873015873016, 0.3174603174603174, 0.3333333333333333, 0.3492063492063492, 0.3650793650793651, 0.3809523809523809, 0.3968253968253968, 0.4126984126984127, 0.4285714285714285, 0.4444444444444444, 0.4603174603174603, 0.4761904761904762, 0.492063492063492, 0.5079365079365079, 0.5238095238095238, 0.5396825396825397, 0.5555555555555556, 0.5714285714285714, 0.5873015873015873, 0.6031746031746031, 0.6190476190476191, 0.6349206349206349, 0.6507936507936508, 0.6666666666666666, 0.6825396825396826, 0.6984126984126984, 0.7142857142857143, 0.7301587301587301, 0.746031746031746, 0.7619047619047619, 0.7777777777777778, 0.7936507936507936, 0.8095238095238095, 0.8253968253968254, 0.8412698412698413, 0.8571428571428571, 0.873015873015873, 0.8888888888888888, 0.9047619047619048, 0.9206349206349206, 0.9365079365079365, 0.9523809523809523, 0.9682539682539683, 0.9841269841269841, 1};
    // Equals the GNU Octave colormap "summer".
            float rx6[] = { 0, 0.01587301587301587, 0.03174603174603174, 0.04761904761904762, 0.06349206349206349, 0.07936507936507936, 0.09523809523809523, 0.1111111111111111, 0.126984126984127, 0.1428571428571428, 0.1587301587301587, 0.1746031746031746, 0.1904761904761905, 0.2063492063492063, 0.2222222222222222, 0.2380952380952381, 0.253968253968254, 0.2698412698412698, 0.2857142857142857, 0.3015873015873016, 0.3174603174603174, 0.3333333333333333, 0.3492063492063492, 0.3650793650793651, 0.3809523809523809, 0.3968253968253968, 0.4126984126984127, 0.4285714285714285, 0.4444444444444444, 0.4603174603174603, 0.4761904761904762, 0.492063492063492, 0.5079365079365079, 0.5238095238095238, 0.5396825396825397, 0.5555555555555556, 0.5714285714285714, 0.5873015873015873, 0.6031746031746031, 0.6190476190476191, 0.6349206349206349, 0.6507936507936508, 0.6666666666666666, 0.6825396825396826, 0.6984126984126984, 0.7142857142857143, 0.7301587301587301, 0.746031746031746, 0.7619047619047619, 0.7777777777777778, 0.7936507936507936, 0.8095238095238095, 0.8253968253968254, 0.8412698412698413, 0.8571428571428571, 0.873015873015873, 0.8888888888888888, 0.9047619047619048, 0.9206349206349206, 0.9365079365079365, 0.9523809523809523, 0.9682539682539683, 0.9841269841269841, 1};
            float gx6[] = { 0.5, 0.5079365079365079, 0.5158730158730158, 0.5238095238095238, 0.5317460317460317, 0.5396825396825397, 0.5476190476190477, 0.5555555555555556, 0.5634920634920635, 0.5714285714285714, 0.5793650793650793, 0.5873015873015873, 0.5952380952380952, 0.6031746031746031, 0.6111111111111112, 0.6190476190476191, 0.626984126984127, 0.6349206349206349, 0.6428571428571428, 0.6507936507936508, 0.6587301587301587, 0.6666666666666666, 0.6746031746031746, 0.6825396825396826, 0.6904761904761905, 0.6984126984126984, 0.7063492063492063, 0.7142857142857143, 0.7222222222222222, 0.7301587301587301, 0.7380952380952381, 0.746031746031746, 0.753968253968254, 0.7619047619047619, 0.7698412698412698, 0.7777777777777778, 0.7857142857142857, 0.7936507936507937, 0.8015873015873016, 0.8095238095238095, 0.8174603174603174, 0.8253968253968254, 0.8333333333333333, 0.8412698412698413, 0.8492063492063492, 0.8571428571428572, 0.8650793650793651, 0.873015873015873, 0.8809523809523809, 0.8888888888888888, 0.8968253968253967, 0.9047619047619048, 0.9126984126984127, 0.9206349206349207, 0.9285714285714286, 0.9365079365079365, 0.9444444444444444, 0.9523809523809523, 0.9603174603174602, 0.9682539682539683, 0.9761904761904762, 0.9841269841269842, 0.9920634920634921, 1};
            float bx6[] = { 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4};
    // Equals the GNU Octave colormap "spring".
            float rx7[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
            float gx7[] = { 0, 0.01587301587301587, 0.03174603174603174, 0.04761904761904762, 0.06349206349206349, 0.07936507936507936, 0.09523809523809523, 0.1111111111111111, 0.126984126984127, 0.1428571428571428, 0.1587301587301587, 0.1746031746031746, 0.1904761904761905, 0.2063492063492063, 0.2222222222222222, 0.2380952380952381, 0.253968253968254, 0.2698412698412698, 0.2857142857142857, 0.3015873015873016, 0.3174603174603174, 0.3333333333333333, 0.3492063492063492, 0.3650793650793651, 0.3809523809523809, 0.3968253968253968, 0.4126984126984127, 0.4285714285714285, 0.4444444444444444, 0.4603174603174603, 0.4761904761904762, 0.492063492063492, 0.5079365079365079, 0.5238095238095238, 0.5396825396825397, 0.5555555555555556, 0.5714285714285714, 0.5873015873015873, 0.6031746031746031, 0.6190476190476191, 0.6349206349206349, 0.6507936507936508, 0.6666666666666666, 0.6825396825396826, 0.6984126984126984, 0.7142857142857143, 0.7301587301587301, 0.746031746031746, 0.7619047619047619, 0.7777777777777778, 0.7936507936507936, 0.8095238095238095, 0.8253968253968254, 0.8412698412698413, 0.8571428571428571, 0.873015873015873, 0.8888888888888888, 0.9047619047619048, 0.9206349206349206, 0.9365079365079365, 0.9523809523809523, 0.9682539682539683, 0.9841269841269841, 1};
            float bx7[] = { 1, 0.9841269841269842, 0.9682539682539683, 0.9523809523809523, 0.9365079365079365, 0.9206349206349207, 0.9047619047619048, 0.8888888888888888, 0.873015873015873, 0.8571428571428572, 0.8412698412698413, 0.8253968253968254, 0.8095238095238095, 0.7936507936507937, 0.7777777777777778, 0.7619047619047619, 0.746031746031746, 0.7301587301587302, 0.7142857142857143, 0.6984126984126984, 0.6825396825396826, 0.6666666666666667, 0.6507936507936508, 0.6349206349206349, 0.6190476190476191, 0.6031746031746033, 0.5873015873015873, 0.5714285714285714, 0.5555555555555556, 0.5396825396825398, 0.5238095238095238, 0.5079365079365079, 0.4920634920634921, 0.4761904761904762, 0.4603174603174603, 0.4444444444444444, 0.4285714285714286, 0.4126984126984127, 0.3968253968253969, 0.3809523809523809, 0.3650793650793651, 0.3492063492063492, 0.3333333333333334, 0.3174603174603174, 0.3015873015873016, 0.2857142857142857, 0.2698412698412699, 0.253968253968254, 0.2380952380952381, 0.2222222222222222, 0.2063492063492064, 0.1904761904761905, 0.1746031746031746, 0.1587301587301587, 0.1428571428571429, 0.126984126984127, 0.1111111111111112, 0.09523809523809523, 0.07936507936507942, 0.06349206349206349, 0.04761904761904767, 0.03174603174603174, 0.01587301587301593, 0};
    // Equals the GNU Octave colormap "cool".
            float rx8[] = { 0, 0.01587301587301587, 0.03174603174603174, 0.04761904761904762, 0.06349206349206349, 0.07936507936507936, 0.09523809523809523, 0.1111111111111111, 0.126984126984127, 0.1428571428571428, 0.1587301587301587, 0.1746031746031746, 0.1904761904761905, 0.2063492063492063, 0.2222222222222222, 0.2380952380952381, 0.253968253968254, 0.2698412698412698, 0.2857142857142857, 0.3015873015873016, 0.3174603174603174, 0.3333333333333333, 0.3492063492063492, 0.3650793650793651, 0.3809523809523809, 0.3968253968253968, 0.4126984126984127, 0.4285714285714285, 0.4444444444444444, 0.4603174603174603, 0.4761904761904762, 0.492063492063492, 0.5079365079365079, 0.5238095238095238, 0.5396825396825397, 0.5555555555555556, 0.5714285714285714, 0.5873015873015873, 0.6031746031746031, 0.6190476190476191, 0.6349206349206349, 0.6507936507936508, 0.6666666666666666, 0.6825396825396826, 0.6984126984126984, 0.7142857142857143, 0.7301587301587301, 0.746031746031746, 0.7619047619047619, 0.7777777777777778, 0.7936507936507936, 0.8095238095238095, 0.8253968253968254, 0.8412698412698413, 0.8571428571428571, 0.873015873015873, 0.8888888888888888, 0.9047619047619048, 0.9206349206349206, 0.9365079365079365, 0.9523809523809523, 0.9682539682539683, 0.9841269841269841, 1};
            float gx8[] = { 1, 0.9841269841269842, 0.9682539682539683, 0.9523809523809523, 0.9365079365079365, 0.9206349206349207, 0.9047619047619048, 0.8888888888888888, 0.873015873015873, 0.8571428571428572, 0.8412698412698413, 0.8253968253968254, 0.8095238095238095, 0.7936507936507937, 0.7777777777777778, 0.7619047619047619, 0.746031746031746, 0.7301587301587302, 0.7142857142857143, 0.6984126984126984, 0.6825396825396826, 0.6666666666666667, 0.6507936507936508, 0.6349206349206349, 0.6190476190476191, 0.6031746031746033, 0.5873015873015873, 0.5714285714285714, 0.5555555555555556, 0.5396825396825398, 0.5238095238095238, 0.5079365079365079, 0.4920634920634921, 0.4761904761904762, 0.4603174603174603, 0.4444444444444444, 0.4285714285714286, 0.4126984126984127, 0.3968253968253969, 0.3809523809523809, 0.3650793650793651, 0.3492063492063492, 0.3333333333333334, 0.3174603174603174, 0.3015873015873016, 0.2857142857142857, 0.2698412698412699, 0.253968253968254, 0.2380952380952381, 0.2222222222222222, 0.2063492063492064, 0.1904761904761905, 0.1746031746031746, 0.1587301587301587, 0.1428571428571429, 0.126984126984127, 0.1111111111111112, 0.09523809523809523, 0.07936507936507942, 0.06349206349206349, 0.04761904761904767, 0.03174603174603174, 0.01587301587301593, 0};
            float bx8[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
    // Equals the GNU Octave colormap "hsv".
            float rx9[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.9523809523809526, 0.8571428571428568, 0.7619047619047614, 0.6666666666666665, 0.5714285714285716, 0.4761904761904763, 0.3809523809523805, 0.2857142857142856, 0.1904761904761907, 0.0952380952380949, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.09523809523809557, 0.1904761904761905, 0.2857142857142854, 0.3809523809523809, 0.4761904761904765, 0.5714285714285714, 0.6666666666666663, 0.7619047619047619, 0.8571428571428574, 0.9523809523809523, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
            float gx9[] = { 0, 0.09523809523809523, 0.1904761904761905, 0.2857142857142857, 0.3809523809523809, 0.4761904761904762, 0.5714285714285714, 0.6666666666666666, 0.7619047619047619, 0.8571428571428571, 0.9523809523809523, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.9523809523809526, 0.8571428571428577, 0.7619047619047619, 0.6666666666666665, 0.5714285714285716, 0.4761904761904767, 0.3809523809523814, 0.2857142857142856, 0.1904761904761907, 0.09523809523809579, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
            float bx9[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.09523809523809523, 0.1904761904761905, 0.2857142857142857, 0.3809523809523809, 0.4761904761904762, 0.5714285714285714, 0.6666666666666666, 0.7619047619047619, 0.8571428571428571, 0.9523809523809523, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.9523809523809526, 0.8571428571428577, 0.7619047619047614, 0.6666666666666665, 0.5714285714285716, 0.4761904761904767, 0.3809523809523805, 0.2857142857142856, 0.1904761904761907, 0.09523809523809579, 0};
    // Equals the GNU Octave colormap "pink".
            float rx10[] = { 0, 0.1571348402636772, 0.2222222222222222, 0.2721655269759087, 0.3142696805273544, 0.3513641844631533, 0.3849001794597505, 0.415739709641549, 0.4444444444444444, 0.4714045207910317, 0.4969039949999532, 0.5211573066470477, 0.5443310539518174, 0.5665577237325317, 0.5879447357921312, 0.6085806194501846, 0.6285393610547089, 0.6478835438717, 0.6666666666666666, 0.6849348892187751, 0.7027283689263065, 0.7200822998230956, 0.7370277311900888, 0.753592220347252, 0.7663560447348133, 0.7732293307186413, 0.7800420555749596, 0.7867957924694432, 0.7934920476158722, 0.8001322641986387, 0.8067178260046388, 0.8132500607904444, 0.8197302434079591, 0.8261595987094034, 0.8325393042503717, 0.8388704928078611, 0.8451542547285166, 0.8513916401208816, 0.8575836609041332, 0.8637312927246217, 0.8698354767504924, 0.8758971213537393, 0.8819171036881968, 0.8878962711712378, 0.8938354428762595, 0.8997354108424372, 0.9055969413076769, 0.9114207758701963, 0.9172076325837248, 0.9229582069908971, 0.9286731730990523, 0.9343531843023135, 0.9399988742535192, 0.9456108576893002, 0.9511897312113418, 0.9567360740266436, 0.9622504486493763, 0.9677334015667416, 0.9731854638710686, 0.9786071518602129, 0.9839989676081821, 0.9893613995077727, 0.9946949227868761, 1};
            float gx10[] = { 0, 0.1028688999747279, 0.1454785934906616, 0.1781741612749496, 0.2057377999494559, 0.2300218531141181, 0.2519763153394848, 0.2721655269759087, 0.2909571869813232, 0.3086066999241838, 0.3253000243161777, 0.3411775438127727, 0.3563483225498992, 0.3708990935094579, 0.3849001794597505, 0.3984095364447979, 0.4114755998989117, 0.4241393401869012, 0.4364357804719847, 0.4483951394230328, 0.4600437062282361, 0.4714045207910317, 0.4824979096371639, 0.4933419132673033, 0.5091750772173156, 0.5328701692569688, 0.5555555555555556, 0.5773502691896257, 0.5983516452371671, 0.6186404847588913, 0.6382847385042254, 0.6573421981221795, 0.6758625033664688, 0.6938886664887108, 0.7114582486036499, 0.7286042804780002, 0.7453559924999299, 0.7617394000445604, 0.7777777777777778, 0.7934920476158723, 0.8089010988089465, 0.8240220541217402, 0.8388704928078611, 0.8534606386520677, 0.8678055195451838, 0.8819171036881968, 0.8958064164776166, 0.9094836413191612, 0.9172076325837248, 0.9229582069908971, 0.9286731730990523, 0.9343531843023135, 0.9399988742535192, 0.9456108576893002, 0.9511897312113418, 0.9567360740266436, 0.9622504486493763, 0.9677334015667416, 0.9731854638710686, 0.9786071518602129, 0.9839989676081821, 0.9893613995077727, 0.9946949227868761, 1};
            float bx10[] = { 0, 0.1028688999747279, 0.1454785934906616, 0.1781741612749496, 0.2057377999494559, 0.2300218531141181, 0.2519763153394848, 0.2721655269759087, 0.2909571869813232, 0.3086066999241838, 0.3253000243161777, 0.3411775438127727, 0.3563483225498992, 0.3708990935094579, 0.3849001794597505, 0.3984095364447979, 0.4114755998989117, 0.4241393401869012, 0.4364357804719847, 0.4483951394230328, 0.4600437062282361, 0.4714045207910317, 0.4824979096371639, 0.4933419132673033, 0.5039526306789697, 0.5143444998736397, 0.5245305283129621, 0.5345224838248488, 0.5443310539518174, 0.5539659798925444, 0.563436169819011, 0.5727497953228163, 0.5819143739626463, 0.5909368402852788, 0.5998236072282915, 0.6085806194501846, 0.6172133998483676, 0.6257270902992705, 0.6341264874742278, 0.642416074439621, 0.6506000486323554, 0.6586823467062358, 0.6666666666666666, 0.6745564876468501, 0.6823550876255453, 0.6900655593423541, 0.6976908246297114, 0.7052336473499384, 0.7237468644557459, 0.7453559924999298, 0.7663560447348133, 0.7867957924694432, 0.8067178260046388, 0.8261595987094034, 0.8451542547285166, 0.8637312927246217, 0.8819171036881968, 0.8997354108424372, 0.9172076325837248, 0.9343531843023135, 0.9511897312113418, 0.9677334015667416, 0.9839989676081821, 1};
    // Equals the GNU Octave colormap "hot".
            float rx11[] = { 0, 0.03968253968253968, 0.07936507936507936, 0.119047619047619, 0.1587301587301587, 0.1984126984126984, 0.2380952380952381, 0.2777777777777778, 0.3174603174603174, 0.3571428571428571, 0.3968253968253968, 0.4365079365079365, 0.4761904761904762, 0.5158730158730158, 0.5555555555555556, 0.5952380952380952, 0.6349206349206349, 0.6746031746031745, 0.7142857142857142, 0.753968253968254, 0.7936507936507936, 0.8333333333333333, 0.873015873015873, 0.9126984126984127, 0.9523809523809523, 0.992063492063492, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
            float gx11[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.03174603174603163, 0.0714285714285714, 0.1111111111111112, 0.1507936507936507, 0.1904761904761905, 0.23015873015873, 0.2698412698412698, 0.3095238095238093, 0.3492063492063491, 0.3888888888888888, 0.4285714285714284, 0.4682539682539679, 0.5079365079365079, 0.5476190476190477, 0.5873015873015872, 0.6269841269841268, 0.6666666666666665, 0.7063492063492065, 0.746031746031746, 0.7857142857142856, 0.8253968253968254, 0.8650793650793651, 0.9047619047619047, 0.9444444444444442, 0.984126984126984, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
            float bx11[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.04761904761904745, 0.1269841269841265, 0.2063492063492056, 0.2857142857142856, 0.3650793650793656, 0.4444444444444446, 0.5238095238095237, 0.6031746031746028, 0.6825396825396828, 0.7619047619047619, 0.8412698412698409, 0.92063492063492, 1};
//--------------------------------------------------------------
const float *rx,*gx,*bx;
uint8_t aaab[35];
float tdata[16],ttdata[3800],a,b,c,d;
int a1,b1,c1,d1,aaa,mouse,gray_color;
ofTrueTypeFont Font1,Font2,Font3;
string color_name;
mraa::I2c* i2c;
//--------------------------------------------------------------
float sp(int x){ 
  
    return (x-aaa)*(x-aaa*2)*(x-aaa*3)*a+x*(x-aaa*2)*(x-aaa*3)*b+x*(x-aaa)*(x-aaa*3)*c+x*(x-aaa)*(x-aaa*2)*d;
}
//--------------------------------------------------------------
void ofApp::setup(){

ofSetFrameRate(60);
i2c = new mraa::I2c(0);
// colormap
mouse=12;
aaa=1;
gray_color=256;
// Font
    Font1.load("cooperBlack.ttf", 30, true, true, true);
    Font2.load("cooperBlack.ttf", 58, true, true, true);
    Font3.load("cooperBlack.ttf", 20, true, true, true);
// Background color
    ofBackground( 0,0,0);
}
//--------------------------------------------------------------
void ofApp::update(){
// mraa i2c D6T 読み取り
i2c->address(0x0A);
i2c->writeByte(0x4C);
i2c->read(aaab,35);                  
  for(int i=0 ; i<=15 ; i++){
    int bbb=(aaab[i*2+2] | aaab[i*2+3]<<8);
    if(bbb>999) tdata[i]=tdata[i];
    else tdata[i]=bbb/10.0f;
  }
}
//--------------------------------------------------------------
void ofApp::draw(){
    //以前のソースを流用
    ofSetColor(255);
    ofDisableBlendMode();
 
        a1=-aaa*-aaa*2*-aaa*3;
        b1=aaa*(aaa-aaa*2)*(aaa-aaa*3);
        c1=aaa*2*(aaa*2-aaa)*(aaa*2-aaa*3);
        d1=aaa*3*(aaa*3-aaa)*(aaa*3-aaa*2);

        for(int y=0;y<4;y++){
            a=tdata[0+y*4]/a1;
            b=tdata[1+y*4]/b1;
            c=tdata[2+y*4]/c1;
            d=tdata[3+y*4]/d1;
            int xxx=y*aaa*(3*aaa+1);
            
            for (int xx=0 ;xx < aaa*3+1 ; xx++){
                ttdata[xx+xxx]=sp(xx);
             }
        }

        int yy1=aaa*3+1;
        float rmin=1000;
        float rmax=-10;
        for(int xx=0;xx<yy1;xx++){
            a=ttdata[xx]/a1;
            b=ttdata[xx+yy1*aaa]/b1;
            c=ttdata[xx+yy1*aaa*2]/c1;
            d=ttdata[xx+yy1*aaa*3]/d1;
            
            for(int yy=0;yy<yy1;yy++){ 
                ttdata[xx+yy1*yy]=sp(yy);
               if(ttdata[xx+yy1*yy] >= rmax) rmax=ttdata[xx+yy1*yy];             
               if(ttdata[xx+yy1*yy] <= rmin) rmin=ttdata[xx+yy1*yy];
            }
        }

        float omin=100;
        float omax=tdata[0];
        int min_no=0,max_no=0;
        
        for (int k=0; k<16; k++){
            if(tdata[k] >= omax) {omax=tdata[k]; max_no=k;}
            if(tdata[k] <= omin) {omin=tdata[k]; min_no=k;}
        }

        int min_R=(min_no%4)*aaa+int(min_no/4)*yy1*aaa;
        int max_R=(max_no%4)*aaa+int(max_no/4)*yy1*aaa;

        float pic=676.0/yy1; 
        if (mouse==12){
                for (int tt=0;tt<yy1*yy1;tt++){
                        int min_max=ofMap(ttdata[tt],omin, omax+0.5, 0, gray_color); 
                        ofSetColor(min_max,0,256-min_max,100);  
                        ofRect((tt%yy1)*pic+162,(tt/yy1)*pic+150,pic*1,pic*1); 
                }

        }
        else{
        	for (int tt=0;tt<yy1*yy1;tt++){
            		int min_max=ofMap(ttdata[tt],rmin, rmax+0.5, 0, gray_color); 
            		ofSetColor(ofFloatColor(rx[min_max],gx[min_max],bx[min_max]),100);  
	    		ofRect((tt%yy1)*pic+162,(tt/yy1)*pic+150,pic*1,pic*1); 
        	}
        }
            Font1.drawString(ofToString(ttdata[min_R],1),(min_R%yy1)*pic+162,(min_R/yy1)*pic+148+pic);
            Font1.drawString(ofToString(ttdata[max_R],1),(max_R%yy1)*pic+162,(max_R/yy1)*pic+148+pic);
            Font2.drawString(color_name,620,100);
            ofSetColor(255,210,0);
            Font2.drawString(" Pi3-D6T-44",20,110);
            ofSetColor(255,100,0);
            Font3.drawString("    Hit Left Right Up key!!",20,32);
            Font1.drawString("x "+ofToString(pow((aaa-1)*3+4,2)/16,1),865,800);
        ofSetColor(255);
}
//--------------------------------------------------------------
void ofApp::keyPressed(int key){
  switch(key) { 
  case  OF_KEY_UP:
          { 
	  mouse++;
	  gray_color=64;
	  if(mouse==13) mouse=1;
	  switch (mouse){
	  case 1:
	    rx=rx1;gx=gx1;bx=bx1;
	    color_name="autumn";
	    break;
	  case 2:    
	    rx=rx2;gx=gx2;bx=bx2;
	    color_name="bone";
	    break;
	  case 3:    
	    rx=rx3;gx=gx3;bx=bx3;
	    gray_color=256;
	    color_name="jet";
	    break;
	  case 4:    
	    rx=rx4;gx=gx4;bx=bx4;
	    color_name="rainbow";
	    break;
	  case 5:    
	    rx=rx5;gx=gx5;bx=bx5;
	    color_name="ocean";
	    break;	
	  case 6:    
	    rx=rx6;gx=gx6;bx=bx6;
	    color_name="summer";
	    break;
	  case 7:    
	    rx=rx7;gx=gx7;bx=bx7;
	    color_name="spring";
	    break;
	  case 8:    
	    rx=rx8;gx=gx8;bx=bx8;
	    color_name="cool";
	    break;
	  case 9:    
	    rx=rx9;gx=gx9;bx=bx9;
	    color_name="hsv";
	    break;
	  case 10:    
	    rx=rx10;gx=gx10;bx=bx10;
	    color_name="pink";
	     break;
	  case 11:    
	    rx=rx11;gx=gx11;bx=bx11;
	    color_name="hot";
	    break;
	  case 12:    
	    gray_color=256;
	    color_name="blood";
	    break;
          }
          }
          break;
  case  OF_KEY_LEFT:
          aaa--;
          if (aaa<1) aaa=20;
          break;  
  case  OF_KEY_RIGHT:
          aaa++;
          if (aaa>20) aaa=1; 
          break;
  }
}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){
}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){
}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseEntered(int x, int y){

}

//--------------------------------------------------------------
void ofApp::mouseExited(int x, int y){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){ 

}

では、また。

Pi3にインストールしたOpenframeworksが入力ディバイスを認識できない

結局認識できた!!

 前回Pi3にBlueToothキーボードとマウスをつないだことを書きました。マウスはなんとか我慢できますが、キーボードの接続がちょっとイマイチ。チャタリングがひどい。

 やはり電波の干渉と電源が原因なのでしょうか。まだ電源を2.5Aにしていないので、今度テストしてみます。Bluetooth使用時は時々linux全体が固まってしまいます。

 ぐちはともあれ、前から気になっていたPiのOpenframeworksでコンパイルしたアプリで、入力ディバイス(マウス、キーボード)が認識されたりされなかったりしていた原因と対策が、やっと解決できたのでメモします。

f:id:TAKEsan:20160410162419j:plain

 Pi3でOpenframeworksを実行している(BOX2DのExample)Bluetoothキーボード、マウスの認識確認

 有線で接続したキーボードとマウスは、とりあえず問題ありません。無線やBluetooth接続した時だけに起こります。この症状に関して、開発者も原因はPIの電源だとか言っていたのですが、どうやら違うみたいです。

 ヒントはここに書いてました。Touchscreen on a Raspberry Pi - arm - openFrameworksタッチディスプレイをマウスとして認識させるにはどうするかをやりとりしています。

どうやら /dev/input の中身をOpenframeworks側に認識させれば良いみたい。

 私自身linuxの仕組みが理解できていないので、色々調べたら、このディレクトリの中に認識された機器のイベント名が書き込まれているとのこと。ディレクトリ以外がソレ。

f:id:TAKEsan:20160410155603p:plain

ただ、このままでは機器名がわからないので、evtestというコマンドをインストールします。

sudo apt-get evtest

 インストールが終わったら、evtest で イベント名と対応する機器名が確認できます。ここでマウスとキーボードのイベント名をメモします。USB接続機器もBluetooth機器もここに設定されます。

f:id:TAKEsan:20160410155604p:plain

          event番号に対応した機器名称が確認できる

 それから、Openframeworks側のシステムプログラム Openframeworksディレクトリ/libs/openFrameworks/app の中にあるofAppEGLWindow.cppを変更します。

 変更箇所は、合計6箇所。Pi3にインストールした標準Openframeworksでは、

/dev/imput/by-pathの中を参照しているのが大きな原因だったみたい。ディレクトリパスとevent名称を変えてやります。

 つまり標準接続では問題ないが、ちょっと毛色の違った入力機器だと全くダメ。開発者の作りこみが少し甘かったみたいです。

100行付近の2箇所変更

filter_mouse 、filter_kbd 関数の中身 event名称を変更する。

f:id:TAKEsan:20160410155608p:plain

このときはキーボードをevent7、マウスをevent8に変更(コメントの下)本来であればマウス1とキーボード2

1300行付近のパスを4箇所変更

setupNativeMouse()、setupNativeKeyboard() 関数の中身.

ソース中のパス /dev/input/by-pass  を /dev/input に変更する

f:id:TAKEsan:20160410155606p:plain

f:id:TAKEsan:20160410155605p:plain

  変更部分は4箇所(各々*********コメントの下の行。とりあえず変更前の行はコメントを付けて残している

  間に合わせですが、修正して再コンパイルしたら、Bluetoothキーボード、マウスともあっけなく認識されました。

注意点

 接続状況によりevent番号が変更されてしまうので、注意が必要。その都度直すことになりそうですが、当分カメラとマウス、キーボードだけで、入力機器の差し替え等しない場合は、rebootしても、一定の番号になります。変更された場合は、最初の2箇所(event名称)を直すだけなので注意すれば何とかなりそうです。

 無線ドングル接続のキーボードとマウスも同じような設定でOKですが、マウス機能付きのキーボードの場合は、evtest他で正確なevent番号を再確認する必要がありそう。つまりこのようなキーボードを使わないほうが良さそうです。

 前回も書きましたが、今のところPi3へは、ARM6 の Openframeworksをインストールとなります。またBluetoothキーボードインストールは、コマンドラインから行います(マウス、スピーカーはXwindowのBlutoothでもOK)。

 とにかくPi3でのOpenframesのハードルが1つ無くなりました。

Blutooth があまりにも不安定なので(電源や電波帯の問題だけではない)、結局入力機器は無線に落ち着きました。この記事参照。

takesan.hatenablog.com

 

 

 

Pi3 が入る SHARPのIGZOディスプレイ ケースを作る

 Pi3が手に入ったので、

iGZO高精細ディスプレイスタンドも兼ねたケースを、ROBOXで作って見ました。

 前に他の方が作ったiGZOディスプレイケースのモデルデータをそのまま印刷して、爪のプリントに苦労したことを書きましたが、私の使用用途では華奢過ぎるので、もっとがっちり自立するものを目標に、独自のモデルを作ってみました。

f:id:TAKEsan:20160406203925j:plain

ディスプレイをケースの中に押し込みます

f:id:TAKEsan:20160406203924j:plain

 ディスプレイ基盤を取り付け、Pi3は別部品に取り付けて、本体の台形レールにはめ込むと、Pi3とディスプレイが合体。ガタつきはほとんど無し。

f:id:TAKEsan:20160406202610j:plainf:id:TAKEsan:20160406202609j:plain

専用の架台に載せたのがこれ。

f:id:TAKEsan:20160406202519j:plain 

f:id:TAKEsan:20160406202517j:plainf:id:TAKEsan:20160406202518j:plain

 3Dキャドソフト(Fusion360)も、各々のコマンドは少し練習するとさわりだけは理解できるのですが、自分の考える物を正確に作ろうとすると、途端に分からなくなってしまいます。でもパズルを解くようなもので結構頭を使うところが面白い。

f:id:TAKEsan:20160406202606p:plainf:id:TAKEsan:20160406202634p:plain

 今回使ったフィラメントは、ROBOX用のWoody Beech。出来上がりが升酒の升のような感じになります。層の段差が木目のように見えるので、全体的な印象はクラフト調でいい感じ。

f:id:TAKEsan:20160406202611j:plain

f:id:TAKEsan:20160406205559j:plainf:id:TAKEsan:20160406205601j:plain

 木の質感を出すには、各断面にある程度厚さが必要で、さらに全体的なボリュームを出すことにこだわったので、Nomalの出力時間は、本体約10時間、Pi3取り付け部分の部品出力が約4.5時間!!

 両方の部品とも気合いの2回目出力で、気に入る物ができました。

 このフィラメントの欠点は、表面がザラザラしているので、プリントの途中リールの中で絡みついてしまい、プリントが中断してしまう場合があることです。普通ならやり直せばいいのですが、何せ今回のモデルは、出力時間が長い。案の定9時間目ぐらいで中断してしまいました。今回かなり便利だと思ったのは、このプリンタはフィラメントの送り出しができなくなると、中断してくれる上にフィラメントの絡みつきを直してから継続プリントができるんです。この機能のおかげですごく助かりました。

 データはここです↓

IGZO-Stand.stl 直 IGZO-Pi.stl 直 IGZO.stl 直 

参考にしてみてください。

Pi3のケースは、PIMORONIで手に入れました。このケースごと収められます。

                                      f:id:TAKEsan:20160406205208j:plain

 裸のPi3でもちょっと上げ底をしてやればOK。

Pi3を一応試してみました。

 ブラウザの表示スピードが少し早くなりました。Pi2だとYahooの広告表示がかなり遅かったのですが、Pi3では気にならなくなりました。これでやっとブラウザが使えるようになった感じです。

 BlueToothマウス、キーボードはとりあえず使えます。キーボードが認識しなかったのでこの方の

倉庫のブログ: Raspberry Piに挑戦-Bluetoothキーボードの接続ブログを参考にしました。

 ただ、BlueToothマウスを使って、負荷の多いブラウザの表示を行うと、Pi3がハングしてしまいます。USBマウスだと問題ないので、電源の問題か?BlueToothキーボードもちょっとイマイチです。もう少し待つ必要がありそう。

 Openframeworksは、ARM6のものでコンパイル&実行可能。サンプルで幾つか動かないものがありましたが、私のよく使うグラフィックスやOSC通信、USBカメラ認識は問題ありませんでした。ただ、BlueToothマウス、キーボードともOpenframeworksの実行環境では認識しません(USBはOK)。スピードはいくらか早くなったかなレベル。IGZOディスプレイは30フレーム/秒が限度なので、この部分が足かせになっています。あとは、Openframeworks現行ARM6のバージョンアップに期待です。

 

 Pi3は現状全体的に少しのスピードアップですが、結構快適です。

 今は

 ブレッドボードをつなげてPIとして使ったり、Macの2ndディスプレイとして使ったりしてます。Macにつないだ時は1024x640にすると言うことなし。もう手放せません。

f:id:TAKEsan:20160531104632j:plain

 

 

 

 

Edison や Pi2 や Arduino と全く違うこと!!

ワンちゃんの紹介

 今日はTAKEsanが飼っているワンちゃんの紹介です。今年の3月末で3歳になるティーカッププードルのjuneです。私の家には6月に来たのでjune=ジュンにしました。

 何を隠そう....昔好きだったジャズシンガー「ジューン・クリスティー」(知る人ぞ知るSomething Cool!を歌った人)の名前を無理くり押し付けただけ。なんか場末のバーの雰囲気が................。

f:id:TAKEsan:20160320215253j:plain

 実は今から40年くらい前に黒いプードルを飼っていたのですが、ろくに世話をしないまま僅か6年で死んでしまいました。なんというか罪滅ぼしとでもいいましょうか。

 トイプードルは成犬体重は確定できないと医者に脅されながら、巨大になったらどうしようと心配しつつ、結局今は2.5kg。

 最初は、服従ポーズだと思っていたこの1等賞ポーズが、

f:id:TAKEsan:20160320215020j:plain

  実は、単純に気持ちいいだけだと分かったのは、今日この頃。

 いつもこんな感じで怒ってますが、

f:id:TAKEsan:20160320215052j:plain

 掃除機と格闘しすぎて、飼い主が掃除してる時は、

f:id:TAKEsan:20160320220701j:plain

袋に入れられてます。コーヒー色の鼻がチャーミング!!

 こんなわんこですが、家の近所の高台のこんな所が大好き

f:id:TAKEsan:20160320220656j:plain

仙台市内を一望できる穴場。 ここからは、仙台湾はもちろん遠く岩沼や石巻まで見渡せます。震災の後の大きな波も一望できたのでしょうね。あの日にこの視野の中で一体どのくらいの命が消えたのでしょうか?ここに来るたび少し悲しくなります。

 変なことしたらブログに書くぞーと言っても、

f:id:TAKEsan:20160320214946j:plain

これでメロメロ。

 私のブログの顔。ジュン子ちゃんの紹介でした。