aravis解析 その3 [aravis]
aravis解析の続き。今日はmacOSへのインストールと、接続されたカメラ個々に特有な操作をするためにGen<i>Camノードツリーを読んでカメラの機能を探すにはどうするかという話....
macOSで単なるviewerを動作させるなら、arv-viewerではなくArvBufferからNSBitmapImageRepを作ってNSViewに表示するほうがずっと簡単で手っ取り早い。viewer抜きでインストールするなら手動でその依存ライブラリだけをインストールしてaravisをコンパイルすればいい。
僕の環境の場合やはりhomebrewを使って、最低限のものだけインストールして
で、できた。
この中でPKG_CONFIG_PATHのexportは、macOSの一部としてlibffiがあってconflictする、というメッセージが出たからで、確かに/usr/libにあった。macOSは自分に不要なものはばっさり切り落とすくせに、必要なものは知らん顔して勝手に入れる。こういうのかなわんよな。
また--disable-dependency-trackingのオプションは、これなしだとconfigureが失敗して
と出たからで、何が違うのかよくわからない。
homebrewをインストールする前にXcodeのコマンドラインツールがインストールしてあったし、そのあとhomebrewで他のツールもちょこっとインストールしていたので、違う環境では要求される手順やライブラリが違うかもしれない。
ちなみに、こないだ会社で使ってる別のマシンにインストールしたら--disable-dependency-trackingオプションがなくてもできた。わからん。
ArvCameraで可能なカメラの一般的な操作以外のカメラ固有の属性機能にアクセスしたい場合は、このツリーをたどる必要がある。
で得られる。
カメラ固有の属性をfeatureと呼んでいる。例えば整数値を持つfeatureなら
で読み書きできる。featureは文字列で指定する。set関数は、それが成功したかどうかはわからない(GenTL(Gen<i>Cam規格の一部でトランスポート層に関するAPI規格)に素直に従うと自動的にそうなる)。setしてから読みだして値が変わっていれば成功、とみなすことになるだろう。
カメラに対するコマンド(例えばソフトウェアトリガの発行など)は
で実行できる。
featureを使えばArvCameraでできる操作も同じように可能で、場合によってはより詳細な読み書きができる場合(例えばシャッタが秒単位の浮動小数点ではなくベースクロックの何個分などというような)もある。
しかし上の関数の呼び出し形式からわかるように、ArvDeviceからfeatureを読み書きするためには、カメラがどんなfeatureをどんな名前で持っていて、それがどんな型なのかをあらかじめ知っている必要がある。
aravisがライブラリの機能として提供していてもいいのではないかとも思う。
Gen<i>Camカメラ記述ファイルはXML形式で、aravisはlibxml2を使ってパースしている。パースした結果のGen<i>CamノードもGObjectのオブジェクトになっている。aravisでは
Gen<i>Camでは 解析済みGen<i>Camのノードツリーはデバイスオブジェクトから
で得られる。これがツリーになってるのでそれを辿ることになる。全部辿らなくてもGen<i>Cam規格ではRootという名前のついたカテゴリノードにユーザが操作できるfeatureが列挙されているはずなので、それを辿ればいいはずである。
具体的には
などとすればいい。
これはまずArvCameraオブジェクトからArvDeviceオブジェクトを得て、それからさらにGen<i>Camのノードツリーを取ってくる。そのツリーからRootの名前を持つノードを得る。これはGen<i>Camのカテゴリノードのはずである。
Gen<i>CamのカテゴリノードもGObjectのオブジェクトになっているので、オブジェクトタイプを調べればカテゴリノードかどうかがわかる。ARV_IS_GC_CATEGORY()は引数がカテゴリノードオブジェクトならtrueを返すマクロである。そしてそうならその要素になっているはずのfeatureノードを取ってくればいい。GSListというのはGObjectの配列オブジェクト(双方向のリンクトリストらしい)である。
カメラによっては(というか最近のカメラはたいてい)Rootカテゴリノードの下にさらにカテゴリノードがあってfeatureが分類されている。その場合はfeatureノード列挙を入れ子にすればいい。
そうするとカメラユーザが操作可能なすべてのfeatureの名前が得られるはずである。
名前がわかればArvDeviceオブジェクトの関数
で、そのfeatureノードを得ることができる。featureノードは実際にはGen<i>CamのpFeatureの種類に従ってArvGcFeatureNodeのサブクラスとして
3 macOSへのインストール
現在aravisはREADME.mdにあるようにaravisはmacOSを直接サポートしていないが、homebrewでインストールできるようになっている。ただし、homebrewはarv-viewer(サンプルコード兼動作チェック用のカメラ画像リアルタイム表示アプリ)を一緒にインストールしようとして大量に依存ライブラリを呼び込んでしまう。macOSで単なるviewerを動作させるなら、arv-viewerではなくArvBufferからNSBitmapImageRepを作ってNSViewに表示するほうがずっと簡単で手っ取り早い。viewer抜きでインストールするなら手動でその依存ライブラリだけをインストールしてaravisをコンパイルすればいい。
僕の環境の場合やはりhomebrewを使って、最低限のものだけインストールして
$ brew install glib intltool gettext $ brew link --force gettext $ brew install libusb $ brew link --force libusb $ brew install pkg-config $ export PKG_CONFIG_PATH="/usr/local/opt/libffi/lib/pkgconfig" $ ./configure --enable-usb --disable-viewer --disable-gst-plugin --disable-dependency-tracking $ make $ sudo make install
この中でPKG_CONFIG_PATHのexportは、macOSの一部としてlibffiがあってconflictする、というメッセージが出たからで、確かに/usr/libにあった。macOSは自分に不要なものはばっさり切り落とすくせに、必要なものは知らん顔して勝手に入れる。こういうのかなわんよな。
また--disable-dependency-trackingのオプションは、これなしだとconfigureが失敗して
config.status: error: Something went wrong bootstrapping makefile fragments for automatic dependency tracking. Try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking).
homebrewをインストールする前にXcodeのコマンドラインツールがインストールしてあったし、そのあとhomebrewで他のツールもちょこっとインストールしていたので、違う環境では要求される手順やライブラリが違うかもしれない。
ちなみに、こないだ会社で使ってる別のマシンにインストールしたら--disable-dependency-trackingオプションがなくてもできた。わからん。
3.1 カメラ固有の操作
カメラの一般的な属性や操作、例えばピクセル数やシャッタやゲインの調整はArvCameraオブジェクトからできることがわかった。 aravisはカメラが持っているGen<i>Cam準拠のXML文字列を読み込んで、Gen<i>Camのノードツリーに展開する。そのノードツリーを解析してカメラの持っている属性や機能を知って保持し、ArvCameraやArvDeviceへの操作を行う関数は、最終的にこれらのノードを使ってカメラのレジスタをアクセスしている。ArvCameraで可能なカメラの一般的な操作以外のカメラ固有の属性機能にアクセスしたい場合は、このツリーをたどる必要がある。
3.1.1 カメラのfeature
カメラ固有の属性や操作のためにはArvDeviceオブジェクトを使う。デバイスオブジェクトはカメラからArvDevice *arv_camera_get_device (ArvCamera *camera);
カメラ固有の属性をfeatureと呼んでいる。例えば整数値を持つfeatureなら
void arv_device_get_integer_feature_bounds (ArvDevice *device, const char *feature, gint64 *min, gint64 *max); void arv_device_set_integer_feature_value (ArvDevice *device, const char *feature, gint64 value); gint64 arv_device_get_integer_feature_value (ArvDevice *device, const char *feature);
カメラに対するコマンド(例えばソフトウェアトリガの発行など)は
void arv_device_execute_command (ArvDevice *device, const char *feature);
featureを使えばArvCameraでできる操作も同じように可能で、場合によってはより詳細な読み書きができる場合(例えばシャッタが秒単位の浮動小数点ではなくベースクロックの何個分などというような)もある。
しかし上の関数の呼び出し形式からわかるように、ArvDeviceからfeatureを読み書きするためには、カメラがどんなfeatureをどんな名前で持っていて、それがどんな型なのかをあらかじめ知っている必要がある。
3.1.2 featureの列挙
カメラがどんなfeatureを持っているか、を知る手段はaravisには用意されていない。そのためにはカメラの取説から文字列を拾うか、あるいはカメラが持っているGen<i>Cam準拠のカメラ記述ファイルを読む必要があるらしい。aravisがライブラリの機能として提供していてもいいのではないかとも思う。
3.1.3 aravisのGen<i>Camのノードオブジェクト
aravis本体に代わってfeatureをGen<i>Camカメラ記述ファイルから読み出す方法を考えてみる。Gen<i>Camカメラ記述ファイルはXML形式で、aravisはlibxml2を使ってパースしている。パースした結果のGen<i>CamノードもGObjectのオブジェクトになっている。aravisでは
- ArvGc
- ArvGcFeatureNode
- ArvGcPropertyNode
Gen<i>Camでは 解析済みGen<i>Camのノードツリーはデバイスオブジェクトから
ArvGc *arv_device_get_genicam (ArvDevice *device);
具体的には
ArvCamera *camera; ArvDevice *device = arv_camera_get_device (camera); ArvGc *gc = arv_device_get_genicam (device); ArvGcNode *node = arv_gc_get_node (gc, "Root"); if (ARV_IS_GC_CATEGORY(node)) { GSList *clist = (GSList *)arv_gc_category_get_features (node); guint len = g_slist_length(clist); // featureノードを列挙する }
Gen<i>CamのカテゴリノードもGObjectのオブジェクトになっているので、オブジェクトタイプを調べればカテゴリノードかどうかがわかる。ARV_IS_GC_CATEGORY()は引数がカテゴリノードオブジェクトならtrueを返すマクロである。そしてそうならその要素になっているはずのfeatureノードを取ってくればいい。GSListというのはGObjectの配列オブジェクト(双方向のリンクトリストらしい)である。
カメラによっては(というか最近のカメラはたいてい)Rootカテゴリノードの下にさらにカテゴリノードがあってfeatureが分類されている。その場合はfeatureノード列挙を入れ子にすればいい。
そうするとカメラユーザが操作可能なすべてのfeatureの名前が得られるはずである。
名前がわかればArvDeviceオブジェクトの関数
ArvGcNode *arv_device_get_feature (ArvDevice *device, const char *feature);
- ArvGcEnumEntry
- ArvGcRegisterDescriptionNode
- ArvGcGroupNode
- ArvGcBoolean
- ArvGcCategory
- ArvGcCommand
- ArvGcConverter
- ArvGcEnumeration
- ArvGcFloatNode
- ArvGcIntegerNode
- ArvGcPort
- ArvGcRegisterNode
- ArvGcStructEntryNode
- ArvGcSwissKnife
2019-06-22 21:29
nice!(0)
コメント(0)
コメント 0