@poko_amu (poko amu)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

PC⇔カメラ間のパケットロスが解決できない

パケットロスが解決できない

Baslerカメラ(Ace2シリーズ)を使用し、3,4枚/sの速度で撮影しています。
撮影した画像はPythonで受け取り諸々処理をしますが、受け取る際にエラーが起きます。

元々は、aceシリーズのカラーカメラで撮影しており
わけあってace2シリーズのモノクロカメラに変更しました。

aceシリーズは3年程使っていましたが当不具合に遭遇したことはありませんでした。

カメラに何か問題がある気がしますが、カメラが変わったことで周辺のネットワーク類も見直しが必要なのかどうかも正直検討がついていないため質問させて頂きます。

エラーコード

とりあえず以下2つのコードで情報を取得しました。

grab_Result.ErrorCode
# エラーコード > 3774873620
grab_Result.GetErrorDescription()
# The buffer was incompletely grabbed ~~

すみません、メッセージは諸事情ですぐ出せないですが、ネットワークの設定を見直してね、的なことが書かれていました。
エラーコードで調べる公式が提案する解決策は以下です。同じようにパケットサイズやインターパケットディレイの設定見直しが書かれています。

エラー時の画像確認

とりあえずnumpyの.shapeで確認しました。
出力は、0だったり、(0,3312)だったり…。パケットロスっぽい出力ではありました。

設備構成

1つのパソコンに別系統でカメラが2台、それぞれインジェクターを介して繋がっています。

LANケーブルは全てカテ6になります。

{4180EFE7-FDCA-436E-BF8C-10B44803464C}.png

1Gbit/s通信を確保しているつもりです。

※ここでは必要ないと判断して図に入れてませんが、トリガーはハードウェアトリガーを使用しています。
Line1系統でRisingEdgeでトリガー設定しています。
(具体的には, ロボット → リレーコイル → カメラ の経路でトリガーを出しています)

それぞれの能力が分かるページリンクを載せておきます

カメラ

インジェクター

パソコン(Linux)

パソコンのNIC

カメラ ⇔ インジェクターのLAN

インジェクター ⇔ パソコンのLAN

python側の受け取り方(コード)

        while True:
            grab_Result = self.camera.RetrieveResult(pylon.waitForever, pylon.TimeoutHandling_Return)
            if grab_Result.GrabSucceeded():
                ImgNum = grab_Result.GetImageNumber() # 何枚目の画像か
                img = grab_Result.GetArray()  # 取得
                dict_num_img = {"IMG":img,"NUM":ImgNum}
                queue.put(dict_num_img)
                if ImgNum == self.max_shot_num:
                    break
                shot_num += 1

            else:
                Err_num = grab_Result.GetImageNumber()
                ErrCode = grab_Result.ErrorCode

上記コードを自作関数で実装しています。
動作はThredingを使用して並列処理させています(カメラ2台同時撮影)

発生頻度

前提として、
1サイクルで、1カメラ約30枚程度撮影しています。
3~4枚/s撮影するような負荷で15%程度の確率で発生します。

傾向としては後半が出やすく前半が出にくいみたいな傾向も無いです。

試したこと

01. パケットサイズ変更

パソコンのMTU カメラのパケットサイズ 結果
9000 8192 x
1500 1500 x

02.帯域幅オプティマイズ

カメラ側の帯域幅をPylonViewerの帯域マネージャーで最適化しました。
この操作により124MB > 112MBになりましたがパケロスでました。
極端に帯域幅を小さくしてももちろんパケロスでした。

03.送信データ量減

カラー画像の時より画像サイズが大きいため同等サイズに変更し、
カメラが送るデータ量を落としました
3312x2932 > 2500x2500
これもパケロスです。

04. Inter-Packet Delayの変更

これはどれだけいじってもダメでした。
デフォルト512で30000までいじりました。


他にも諸々やっていますが、一度質問として投稿させて頂きます
何でもいいのでお力を貸して頂けると幸いです…。

補足

・取得画像はモノクロで1枚3MBほどになります
・画像は動画のような取得方法ではなく単発撮影を繰り返しています
・使用していたaceシリーズのカメラ型式は「acA4112-8gc」

0 likes

3Answer

まずは問題が起きているのがどこなのかを判断しましょう

資料関係は登録しないと読めなさそうなので断念しましたがカメラに専用ソフトがあるようです。
一時的にこれを使用してパケットロスが発生するか判断出来ますか?
専用ソフトでパケットロスが発生しないのであればPython側の問題かも知れません
ほか色々書こうと思いましたがもっと詳しく書かれている記事があったので貼っておきます
このへんは参考にしてますか?

1Like

Comments

  1. @poko_amu

    Questioner

    コメントくださりありがとうございます。

    専用ソフトが恐らくPylonViewerのことだと思います。

    結論は、専用ソフトを使ってもパケットロスが発生していると思われます。
    構成はPythonをPylonViewerに置き換えたのみです

    先ほどはっきりパケロス発生してます!と断言出来ていない理由としては、パケットロスを表しそうなステータスが2つあるためです。

    ①Failed Buffer Count
    ②Failed Packet Count

    それぞれ説明は公式から引用します(以下の添付画像)

    {D582A381-604B-42F3-8E98-0E3ADC18D93E}.png

    どちらが発生してもパケットロスだと個人的には思っています。

    ここの正確な切り分けは直接Basler社の方へ問い合わせ中です。
    (そもそもこの問題のことも問い合わせてはいます)

  2. @poko_amu

    Questioner

    サイトのリンクもありがとうございます
    PylonViewerでも出ていそう、という判断でPython側の深追いはあまりしてないです

    とはいえ一度原点に返って、シンプルに画像を取得するだけのPythonコードを作成して検証しています

確認ですが、その設備構成で、カメラだけを a2A4096-9gmPRO に替えたところ問題が起こるようになった、ということでしょうか?それとも他に替わったものはあるでしょうか?
受信ソフトウェアは異なるものなのでしょうか?

1Like

Comments

  1. @poko_amu

    Questioner

    コメント下さりありがとうございます。

    おっしゃる通りです。
    カメラのみの変更になります

  2. 取得画像はモノクロで1枚3MBほどどいうことですが、旧カメラではどうでしたか?カラーだったということですのでもっと大きかったのかなと想像しますが、だとすれば転送量の増大による帯域オーバーという線は考えにくそうですね。

  3. @poko_amu

    Questioner

    そうですね
    実は画角サイズが前のカメラより増えてる関係で、500KBほど増加しております。

    この線も疑ってサイズを小さくして前のカメラよりデータ量を減らしても再発しました。

  4. プロトコルスタックはどういうものなんでしょう?
    カメラのドキュメントをざっと見ましたがそのあたりの説明は見当たりませんでした。
    それも以前のカメラと現在のカメラとでは仕組みは同等なのでしょうか。

    例えばの話ですが、トランスポート層がUDPで、そこでデータがロストした場合、上位の(SDK等を含む)アプリケーション層で(たとえば)タイムアウトの仕掛けで再送要求したところで、時間が経ちすぎていてカメラはもうそのデータを保持していない(次の画像で上書きしてしまっている)ので再送要求失敗、といったような仮説も成り立つかなと思います。
    (まあでも無線ならともかく、有線でちゃんとしたケーブルも使っていて、UDPだからといってそんなにロストするかな?と疑問ではありますが…もしケーブルが長いならうんと短くして実験してみるといいかもしれません。ダメ元でも)

  5. @poko_amu

    Questioner

    プロトコルスタックは考えてなかったです。
    私の方でも公式を探りましたが、情報は得られませんでした。

    ですが、以下の検証を行っています

    0.15secの等間隔で撮影を数百、数千繰り返したところ(画像は同じ)
    再送要求回数と失敗数がイコールになっていなかったので、
    再送した結果、送信できたりできなかったりしていそうだなと思いました。
    等間隔での撮影ですのでほぼ全て失敗のような結果であれば、上書きしている可能性はかなり高かったと言えそうでした。

    しかしながら、再送したのちに失敗、再送無し(1回目)で失敗もあるのか?
    そもそも再送要求は1回目で上手くいかなかったら絶対されるものなのか…。
    ここらへんもわかっていないので、調べるなり問い合わせるなりしてみます

  6. ここまで、カメラからは画像データが連続して送信されてくるものと勝手に思い込んでいました。そうだとすれば、カメラの一般仕様のところに

    フレームレート(デフォルト設定) 8.4fps
    9.5fps(Bandwidth ReserveモードがPerformanceに設定され、パケットサイズが4000に設定されている場合)

    と書かれているので、そのあたり(モードとかサイズとか)の設定はどうなのかな?というのがまず気になりました。おそらくいろいろ試されたとは思いますが。

    しかし、もしかして、単発の撮影コマンドを送信→画像データを受信(受信できるまで待ち、タイムアウトやエラーがあればリトライする)といったことを繰り返すような設計でしょうか?

    画像データを受信する際にネットワークでエラーがあった場合に、その画像データを諦めるのではなく、再送を要求してとにかく受け取ろうとする設計でしたら、カメラは自動で撮影を続けて自分のバッファを書き換えてしまうような動作モードになっていないことが望まれると思いますが、そのあたりはどうなんでしょうかね。そもそも、そうしたモード設定があるのかどうかもわからないですが。

  7. @poko_amu

    Questioner

    提示頂いた資料にある設定に関しては8.4fps側になりますね
    パケットサイズは1500~8192を色々設定してますがBandWidth Reserveに関しては今のところノータッチです。
    これを設定すると、前回のカメラのfps同等になるっていうところでやってみる価値がありそうです。シャッター間隔は8.4fpsに対して余裕はありますがカメラ内部処理で転送までに時間が掛かってる可能性も別の回答者の方から頂いてます。

    リトライするような設計であるかどうか?に関しては、Python側での話だと解釈しましたがそのような設計にはしてないです。カメラが一方的に送ってきた画像を取得するだけになってます。

すでに解決していればすみません。
カメラ1台に対して1fpsぐらいでシャッターを押した場合でも同じように問題が発生しますか?
今回変更されたのがカメラのみという事ですが、今回のカメラのフレームレートが8.4fpsとなっています。前回使用されていたAceシリーズのカメラがどの型番かわかりませんが
大体のカメラは今回のカメラよりフレームレートが高いです。
秒間2~3枚を撮影という事なので仕様上は問題なさそうですが、カメラ内部の処理+Paytonでの取得処理で2枚目以降の処理が間に合わなくなる場合がある等は考えられませんか?

1Like

Comments

  1. @poko_amu

    Questioner

    コメント下さりありがとうございます
    まだ解決にいたっておりません…

    前回使用カメラの型番は「acA4112-8gc」になります
    FPSは9.4と少し前回のカメラの方が高いです

    調査していてわかったことですが、
    撮影した画像はパソコンのバッファに仮置きされていくようで、
    Python側のスピードは影響しなさそうでした(バッファ数は決まっているので全くの無関係ではありません!)

    とはいえカメラ内部処理に関してはなんともいえないので、1fpsぐらいの速度間で撮影してみます。ありがとうございます

Your answer might help someone💌