OS X用GigE Visionカメラドライバ - その34 [OS X用GigE Vision]
もう10ヶ月前のことになるんだけど、無圧縮カメラのデータを1000BaseTで送るためのGigE Visionをおさらいして、それで通信するカメラをOS Xでも使えるようにしようとしていた。カメラ固有の機能を使うためには、それをXMLファイルに記述したGEN<i>CAMという規格に対応する必要がある。ところがこの規格が結構面倒で、実装に悩んでいた。とりあえず機能を記述したXMLファイルをカメラから読み出して、それを読める形にまとめ直して、必要な機能だけを直接ハードコードする形でずっとカメラを使っていた。
ところが、最近になって社長副社長のおともだちのツテで、それまで使っていたドイツの会社のカメラから、カナダの会社のカメラに切り替えることになった。めんどくさいんだけど少し安く手に入ることでもあるので諦めて切り替えることにした。ところがそのカナダのカメラのXMLが300kB以上ある。情報量としては原稿用紙200枚ぐらいの中編小説並み。それまでのドイツメーカのが20kBほどだったので人間が読んでもなんとかなったけど、もう限界。しかたないのでGEN<i>CAMに対応したコードを書くことにする....
なんでGEN<i>CAMに従ったコードを書くのがいやだったかというと、これとこれとこのコメントを読んでもらうとわかるけど、一番気に入らないところは、規格の中で実際にカメラとの通信をするGenTLというレイヤ(GEN<i>CAM規格の一部)が読み書きをブロックする、ということ。特に読み込みはGigE VisionではUDPでカメラに読み出し要求して、カメラはまたUDPで返す、ということになってネットワークが混んでなくても100m秒台のレイテンシがありえるが、その間read()関数は返ってこない。これをどう対処するかで悩んで、実装する気が失せていた。
尻に火がついてしまったので、とりあえずその点は置いておいて、とにかく実装を進められるようにする。
ずっと前にも書いたけど、GEN<i>CAMのノードは単一継承のスタイルになっているので、ノードをそのままObjective-Cのクラスに対応させるのが自然だろう。
カメラのユーザがカメラの機能を調べたり設定したりするのはCategoryツリーのRootからたどれるノードの名前ということになる。値の読み込みや設定はPortノードに対して行われることになって、Portノードは実際のカメラの読み書き機能のプロキシとなるようにプログラミングすればいい。
カメラ記述ファイルに文法誤りが含まれることはないと考えていいので、エラー処理をどうするか、ということにあまり悩む必要は無い。どのみちもし文法誤りがあればエラー回復は不可能で、そのカメラは使えない、ということになるだけである。
ノードの実装としてはクラスクラスタにして、XMLのノードから自動的にクラスが決定されるようにするのがわかりやすい。まじめなクラスクラスタの実装は面倒だし、ARC(Automatic Reference Counting)のもとでシングルトンの作り方がよくわからないので、例の「なんちゃってクラスクラスタ」を使うことになる。
これもまた膨大なもので、サマリの表だけでも28ページにわたっている。呆然としてしまう。この規格では機能はカテゴリに分類されている。
また、それぞれの機能はFeature Levelとして
とマークされている。Mは必ず実装されているがそれ以外は確認する必要がある、ということだろう。
さらに、Feature Visibitityとして
と分類されている。中二病的な表現が気に入らないが、意味はわかる。
とりあずMandatoryでBeginnerの印のついた機能だけ見ようと思ったら、Mandatoryはたったみっつ
ということで結局表をずっとみて必要だと思われるものをあげてみると
GigE Visionのほうの規格を見てみると例としてあがっていた。
ところが、最近になって社長副社長のおともだちのツテで、それまで使っていたドイツの会社のカメラから、カナダの会社のカメラに切り替えることになった。めんどくさいんだけど少し安く手に入ることでもあるので諦めて切り替えることにした。ところがそのカナダのカメラのXMLが300kB以上ある。情報量としては原稿用紙200枚ぐらいの中編小説並み。それまでのドイツメーカのが20kBほどだったので人間が読んでもなんとかなったけど、もう限界。しかたないのでGEN<i>CAMに対応したコードを書くことにする....
なんでGEN<i>CAMに従ったコードを書くのがいやだったかというと、これとこれとこのコメントを読んでもらうとわかるけど、一番気に入らないところは、規格の中で実際にカメラとの通信をするGenTLというレイヤ(GEN<i>CAM規格の一部)が読み書きをブロックする、ということ。特に読み込みはGigE VisionではUDPでカメラに読み出し要求して、カメラはまたUDPで返す、ということになってネットワークが混んでなくても100m秒台のレイテンシがありえるが、その間read()関数は返ってこない。これをどう対処するかで悩んで、実装する気が失せていた。
尻に火がついてしまったので、とりあえずその点は置いておいて、とにかく実装を進められるようにする。
8 GEN<i>CAM XMLファイルの解釈
前々回までで、GEN<i>CAM記述ファイルがどういう構造になっているのかだいたいわかった、ということにする。これを実装しよう。実装を優先させるために、本当はやりたくないけど、read()呼び出しはGenTLと同じようにブロックする方式で進めることにする。ちゃんと動くのを確認したあとで非同期な読み書きに変更しよう。ずっと前にも書いたけど、GEN<i>CAMのノードは単一継承のスタイルになっているので、ノードをそのままObjective-Cのクラスに対応させるのが自然だろう。
カメラのユーザがカメラの機能を調べたり設定したりするのはCategoryツリーのRootからたどれるノードの名前ということになる。値の読み込みや設定はPortノードに対して行われることになって、Portノードは実際のカメラの読み書き機能のプロキシとなるようにプログラミングすればいい。
カメラ記述ファイルに文法誤りが含まれることはないと考えていいので、エラー処理をどうするか、ということにあまり悩む必要は無い。どのみちもし文法誤りがあればエラー回復は不可能で、そのカメラは使えない、ということになるだけである。
ノードの実装としてはクラスクラスタにして、XMLのノードから自動的にクラスが決定されるようにするのがわかりやすい。まじめなクラスクラスタの実装は面倒だし、ARC(Automatic Reference Counting)のもとでシングルトンの作り方がよくわからないので、例の「なんちゃってクラスクラスタ」を使うことになる。
8.1 GEN<i>CAMの標準機能名
前回までに自分でまとめたものを読み直して、GEN<i>CAM記述ファイルがどういうものでどうやって解釈すればいいかはわかったということにする。しかしこの時点では機能のシンタクスがわかっただけで、機能の意味、セマンティクスはわからない。それはまた別の規格であるGEN<i>CAMのSFNC(Standard Feature Naming Convention)としてまとめられている。これもまた膨大なもので、サマリの表だけでも28ページにわたっている。呆然としてしまう。この規格では機能はカテゴリに分類されている。
- Device Control
- Image Format Control
- Acquisition Control
- Digital I/O Control
- Counter and Timer Control
- Event Control
- Analog Control
- LUT Control
- GenICam Control
- Transport layer Control
- Usr Set Control
- Chunk Data Control
- File Access Control
- Color transformation Control
- Action Control
- Source Control
- Transfer Control
- Sequencer Control
- Software Signal Control
また、それぞれの機能はFeature Levelとして
M | 必須/Mandatory |
R | 推奨/Recommend |
[O] | 任意/Optional |
とマークされている。Mは必ず実装されているがそれ以外は確認する必要がある、ということだろう。
さらに、Feature Visibitityとして
B | 初心者/Beginner |
E | 専門家/export |
G | 達人/Guru |
I | 不過視/Invisible |
と分類されている。中二病的な表現が気に入らないが、意味はわかる。
とりあずMandatoryでBeginnerの印のついた機能だけ見ようと思ったら、Mandatoryはたったみっつ
- Root 機能ツリーのルート
- Device 具体的なレジスタのプロキシ
- TLParamsLocked データ転送のときに変化してもらっては困るパラメータをロック/アンロック
ということで結局表をずっとみて必要だと思われるものをあげてみると
- AcuqisitionControlカテゴリ
- AcquisitionMode(フレームが単発か連続かなど)
- AcuqisitonStart
- AcquisitionStop
- TriggerSelector
- Width
- Height
- PixelFormat
- PixelFormatSelector
- AcquisitionFrameRate
- TriggerSelectorあるいはTriggerMode
- PayloadSize
GigE Visionのほうの規格を見てみると例としてあがっていた。
- Width
- Height
- PixelFormat
- PayloadSize
- AcquisitionMode
- AcquisitionStart
- AcquisitionStop
2015-12-13 21:37
nice!(0)
コメント(0)
トラックバック(0)
コメント 0