2017年10月14日土曜日

Docker道場で修行してきたまとめ



  • Docker=chroot+OverlayFS+カーネルのプロセス分離技術
  • 仮想OSとは概念が違う。仮想OSはBIOSより上をすべて差し替えるけど、Dockerは特定用途に必要なファイルだけ差し替える。下から全てなのか、上から必要最小限なのかの違い
  • 仮想OSぽいこともできるけど、それは狙ったものではないので、失敗することが多い。ネット上の批判はそのあたりに原因がある。
  • ソースコード以外の、たとえばデーモンやライブラリや設定ファイルにバージョン管理の概念を導入したもの
  • 開発環境と本番環境の同一性を保証するような用途に向く。または、使い捨てのアプリでも、親環境を汚さないで済む
  • 基本的にLinux系OSの上に、やりたいことに関連する依存部分すべてををDocker imageとして用意し、基本となるOSの上にDockerで用意した差分を当てることで、特定の用途として使えるようにしたもの
  • 基本Linuxで動く。macOSはUnix系なのでDocket for Macを使うことで動かすことが出来る。Windowsは、仕組みが違いすぎるので、Dicker for Windowsを使うことで、内部的に仮想Linuxを立ち上げることで動かしている
  • 最近はクラスタリングを便利にする方向に進化している
  • 元となるOSからの差分は、OverlayFSを使って、たくさんのレイヤーを重ねることで実現しており、変更はレイヤーごとで管理するので、仮想OS(すべてを一括管理)より入れ替えが楽。これにより開発中のテストや修正などが迅速に行える
  • Docker imageは、レイヤーに相当しており、実際にはファイルやサブディレクトリを含んだ1つの読み取り専用ディレクトリとして実装されている。(OverlayFSの下層レイヤーとして機能する)
  • Docker containerは、実行する度に作られる管理単位で、一つのDocker imageから複数のDocker containerを作ることが出来る
  • Docker containerは、OverlayFSを使っていることもあって、変更された分は最上位レイヤーに差分としてとして管理される。
  • コンテナの実行を終えたとき、最上位レイヤーは破棄されるので、残しておく必要があるときはdocker commitを使って保存しておく必要がある
  • レイヤーは複数重ねることが出来る。これにより基本部分や特定用途など、用途ごとに管理できる
  • レイヤーの層の分、OverlayFSでの重ね合わせが発生する。ファイルを1バイトでも変更すると、ファイル単位のcopy on writeが発生し、これが最大のオーバヘッドとなる。それ以外の部分のオーバヘッドは小さい。
  • Docker containerからは、親となるOSのディレクトリを直接マウントできるので、変化するデータは親のファイルシステムに保存するのが定石(じゃないと、遅くなる)
  • 仮想OSではないので、親のOSのディストリビューションや、バージョンに影響を受ける。基本的には動くように作っているはずだが、現実的には、同じディストリビューションの同じバージョンで動かす方がよい(ディストリビュービューターの努力依存)
  • 元になるOS部分と、一層目のレイヤーの境界線がわかりにくい。要はOS層の中で、マシンが違っても同じ実行を保証するための、共通因子がはっきり定義されてない印象。ただしこれは、元となるOS部分を限りなく薄くして、一層目のレイヤーを厚くすることで吸収するような方向に進化中とのこと
  • どこに使えば使えばいいのか、いまいち解りにくい
  • 市販の本は、既に古くなっている部分が多いのでオススメしない。 Dockerドキュメント日本語化プロジェクトをオススメする。
また、docker利用例としてros2とsagemathを思い出したので紹介しておきます。
  • ros2はRobot Operating System ver2です。ロボット開発にパッケージシステムや共通コンパイル環境を用意することで、車輪の再発明を抑制してみんなハッピー、みたいなものです。ただ、進化スピードが早いのと、周辺システムまで含めると巨大なので、コンパイルを通すのがしんどいです。おそらくそれをdockerを使って解決しているのだと思います。
  • sagemathは数学系の教育補助ソフトに分類されるのかな。jupyter notebookやsageなどを使って数式を書くと、それを解析的に解いてくれたり、グラフに書いてくれたりします。AIやってる人は結構使ってるはず。同様のものが無料のクラウドサービスとして運用されていますが、混むと遅くなるのでこちらでdocker imageも配布されているようです。(なので自分のマシンで立ち上げてもユーザ登録から始まった気がします)


2017年9月29日金曜日

動体追跡システムを作ってみた



以前からOpenCVを使って色々作ってみていたんだけど、画像加工や特徴点ベースのマッチングに使う、つまりアプリ全体を俯瞰してみるとコア部分ではあるけどあまり全面に出てこない部分で使っていたぐらいで、本格的にOpenCVと向き合ったのはこれが初めてかもしれない。

画像加工や解析の場合、ゴールは同じでも色々なアプローチがあって、各カテゴリごとにOpenCVのAPIとしてたくさんのアルゴリズムが実装されているんだけど、ちゃんと使いこなすためには論文を読んで理解しておく必要がある。(OpenCV自体では、APIの説明しかしてないので、パラメタの意味や使い分けは別途調べる必要がある)

また、理論的にいくつかのアプローチは除外できても、結局は複数のアプローチを実際に試してみることになるので、自分としても3歩進んで2歩下がる感があったり、このあたりを受託でやるとなると、発注者の理解を得るのはなかなか難しいなぁ、と思ったり。

閑話休題

さて、この動体追跡システムですが、製品として発売されているものもあるようで、そちらではスーパーの出入り口カメラを向けておき、出入り口前にボーダーラインを引いておくことで、来店数をカウントできるような機能もあるみたい。

また、コインパーキングの空き情報や、違法駐車の自動取締りなどにも使えそうなので、時間がある時にRaspberry pi3あたりで実装してみようかなと思っています。

こちらも事業化したいので、興味ある方は連絡ください。

2017年9月27日水曜日

赤外線暗視装置を作ってみた


秋月のネットで赤外線投光機キットを見つけて、勢いで車載用赤外線暗視装置(ドライブレコーダーを兼ねたもの)として作ってみたんだけど、同居しようと思っていたラズパイ3ではCANの処理が思ったより重かったのと、この投光器の光量ではあまり遠くまで見えなかったので、車載向けを諦めて持ち歩き可能にしたのがこちら。

5インチディスプレイも付けたので、OpenCVを使ってリアルタイム動画解析するのであれば、かえってこっちの方が良かったかもしれない。WiFiの無い現場でもUSBキーボードだけでパラメータ調整して再コンパイルできるからね。

途中で3Dプリンタが壊れてしまったのでケースは中途半端だけど、3Dプリンタさえ修理が終わればもうちょっと実用的になるはず。。。

gstreamerを使って遠隔地監視したり、motionを使って動体監視したりまでは試してみたんだけど、害獣駆除用の檻の扉の制御とかもやってみたいな。

色々応用できそうなので、うまく事業化できればいいなと思っています。興味持たれた方はご連絡ください。

2017年9月26日火曜日

CANから情報を取得して車載ナビに情報表示してみた


最近の車は自動運転に向けて各種センサーデータがCANというネットワークを介してやり取りされているんだけど、規格がオープンでネット上に情報がたくさんあり、必要な基板も中国から安く買えるようなので試しに作ってみたものがこれ。

昔はサーキットや峠に頻繁に行ってたけど、最近はそんな熱もすっかり冷めてしまったので、たまにミニサーキットに行きたくなった時に水温管理できればいいな、ぐらいのモチベーションで作ってみました。

自動運転に向けての各メーカーの取組みも各社それぞれで、車種ごとにも違うので、汎用性が薄いのが難点かな。自分用としてはいいけども。

上記のように、ちょっと汎用的な応用は難しいのかもしれませんが、特定用途であればいけそうです。興味ある方はご連絡ください。

2017年9月25日月曜日

室内測位システムで複数同時測位してみた

そういえば、YoutubeやFacebook/Twitterでは公開してたけど、ブログに書いてなかったなと思い出したので、整理したいと思う。

まずは、以前に作ったiBeaconを使った室内向け測位システム作ったよ を発展させて、複数同時に測位できるようにしたシステム。


このシステム用に、結局iBeaconも自作した(ファーム担当した)ので、追加機能など色々応用できそうなんだけど、iBeacon自体あまり聞かなくなったので惜しいなぁ。

とはいえ、IoTとしてだとビーコンとしてのアプローチは有効な選択肢の一つだと思うし、iBeaconは聞かなくなってきてもGoogleのEddystoneなどを使って多機能に進化したものは消えずに細々と使われ続ける気がする。

2016年7月6日水曜日


OpenROVのキットを去年の秋口に購入して、そのまま仕事が忙しくなってしまったため完成したのは正月頃で、今年のGWにやっと海で沈めてみれました。(北海道の冬の海中でひっかかるかも?と考えると、冬に試してみることはできなかった。。。)

OpenROVは海中用ドローンという珍しいジャンルなんですが、オープンハードウェアとオープンソフトウェアと組み合わせたもので、ハード的にはアクリル板をレーザーカッターで切り出したものを躯体とし、BeagleBone Black(Raspberry Piみたいなやつ)とArduinoを組み合わせたもので動いています。キットが届いた時はバラバラのパーツです。

海中では無線が使えないので、地上との通信は有線です。とはいえ、イーサネットケーブルを使うのではなく、PLC(電力線通信)用のアダプタを改造した2芯ケーブルを使って通信します。地上に出れば無線が使えるので、そこからは無線LANアダプタに接続して、タブレットやPCのブラウザを見ながら、キーボードやPS3のコントローラーなどを使ってコントロールします。(上記サムネイルの画面)

ソフト的には、BeagleBone Black内でLinuxが稼働しており、USBカメラの画像をnode.jsを使って表示・コントロールしています。Web技術者とも親和性が高い構成なので、思いつきで改造できそうです。実際に、ハードウェアや回路的にも、改造していくことを前提に作られています。

動画ではOpenROV本体を撮り忘れた(撮ったけど消えてしまった)ので、興味ある方は公式サイトをチェックしてみてください。

OpenROVは操作するのも楽しいですが、組み立てるのも楽しいですね。
こういう機能は、こういった要素で機能してるんだ、という発見がたくさんありました。

今は暇を見つけて集魚用撒き餌マシン(OpenROVアドオン?)を作ってます。

2015年4月1日水曜日

CakePHP 3.0でgitを使ったデプロイの覚書

ちょっと前にCakePHP 3.0がリリースされたようなので、落とし穴が多いことは覚悟で実践で使ってみた。

で、最初から躓いたのでメモを残す。

問題


普通、手元のPCに開発環境としてCakePHPを動かせる環境を作っておいて、こちらで開発&ある程度デバッグしたところで、本番サーバにgit経由などでデプロイするケースが多いと思う。

CakePHPも今はGitHubでホスティングされていることもあって、最初から運用を意識した.gitignoreが用意されているんだけども、
  1. 手元の開発環境で
    php composer.phar create-project --prefer-dist cakephp/app [app_name]
    して、CakePHP3のプロジェクトを新規作成
  2. このプロジェクト用gitリポジトリにgit commit&git push (このときgitignoreによりbin/logs/tmp/venderなどはコミットから外れる)
  3. 本番サーバでgit pull
としたとき、gitignoreで外されたvenderディレクトリ内のフレームワーク本体や、bin/logs/tmpなどディレクトリは、どうやって本番環境に持っていけばいいのかわからなかった。
公式ドキュメント調べても、特に書いてなかった。
リリースされたばっかりなので、ブログやstackoverflowなどにも載ってなかった。

解決方法


おそらく、上記3の後に、
  1. 本番環境側にもcomposerをインストール
    上記app_nameディレクトリに移動してから
    curl -s https://getcomposer.org/installer | php
  2. githubのcakephp/appからbin/logs/tmpを取ってくる。方法は色いろあると思うけど、以下のようにすると楽だった
    svn export https://github.com/cakephp/app/trunk/bin
    svn export https://github.com/cakephp/app/trunk/logs
    svn export https://github.com/cakephp/app/trunk/tmp 
    
  3. composerを使って依存関係にあるライブラリをvenderディレクトリに入れ、自動実行されるCakePHPのインストールスクリプトを使ってパーミッションも付与する
    php composer.phar -n install
のようにするのが正解ではないかと思う。みんな困るはずなので、そのうちもっとスマートな方法が提案される気もするけどね。

おまけ


CakePHP 3.0はPHPのintl extensionに依存してるんだけど、MacOSXの場合、homebrewを使ってintlモジュールを入れようとすると
brew install php53-intl
など、PHP本体とは別にintlモジュールを入れる必要があると書いてあることが多かった。

でも、実際に
brew search php5
で検索すると、-intlがついてるモジュールは見当たらない。

困ったので色々調べてみたら、ちょっと前からphp本体にintlモジュールを組み込んだ状態で配布する形式に変わったようだった。

なので、
brew install homebrew/php/php56
だけで最低動作環境はクリアできる。