Menu

URG3D: Transmission timeout

2019-07-24
2021-02-19
  • akira hayasaka

    akira hayasaka - 2019-07-24

    お世話になっております。
    URG 3D libraryを使って、北陽電機YVT-35LXに接続しています。ライブラリ内のexampleを参考にして接続しているのですが、たまに一発でコネクションが確立できず、何度か試みてると接続される、という現象が起きています。毎回再現するというわけではなく、一発で接続できる場合もあります。いったん接続が確立されると、安定してデータが取れているようです。

    接続できない場合のログを見ると、
    [ error ] error urg3d_high_blocking_init -1
    もしくは
    [ error ] error urg3d_high_blocking_wait_finished_initialize -1
    と出ており、接続確立の処理がリターンしています。どちらの関数かは場合によってまちまちです。

    ためしに、
    define DEBUG_COMMON
    define DEBUG_LOW
    のコメントアウトをはずしてコンパイルすると、Transmission timeoutが返ってきています。
    タイムアウトになる原因、どんなものがあるのか、もし知見をお持ちでしたらお教えいただけますでしょうか?

    以下ログです。

    receive_num = 101
    sizeof(*header) = 24
    header->mark = VSSP
    header->type = VER
    header->status  = 000
    header->header_length = 24
    header->length = 101
    header->received_time_ms = 2690756
    header->send_time_ms = 2690756
    *length_data = 77
    strlen(data) = 77
    data = vend:Hokuyo Automatic Co.,Ltd.
    prod:YVT-35LX
    firm:443
    prot:2.1
    seri:H1834073
    
    receive_num = -1
    receive_num = 403
    sizeof(*header) = 24
    header->mark = VSSP
    header->type = GET
    header->status  = 000
    header->header_length = 24
    header->length = 403
    header->received_time_ms = 2690758
    header->send_time_ms = 2690761
    *length_data = 379
    strlen(data) = 379
    data = GET:tblv
    0AAB,0BA9,0CA5,0DA0,0E96,0F88,1073,1158,1234,1307,13CF,148C,153C,15E0,1675,16FC,1773,1831,18E1,1877,17DA,1773,16FC,1675,15E0,153C,148C,13CF,1307,1234,1158,1073,0F88,0E96,0DA0,0CA5,0BA9,0AAB,09AD,08B0,07B6,06BF,05CD,04E2,03FD,0321,024F,0186,00C9,0019,FF77,FEE1,FE5B,FDE3,FD7C,FCDF,FC75,FD25,FDE3,FE5B,FEE1,FF77,0019,00C9,0186,024F,0321,03FD,04E2,05CD,06BF,07B6,08B0,09AD
    
    receive_num = 1460
    sizeof(*header) = 24
    header->mark = VSSP
    header->type = _ri
    header->status  = 000
    header->header_length = 24
    header->length = 504
    header->received_time_ms = 0
    header->send_time_ms = 2690762
    *length_data = 480
    strlen(data) = 1
    data = 
    
    receive_num = -1
    sizeof(*header) = 24
    header->mark = VSSP
    header->type = _ri
    header->status  = 000
    header->header_length = 24
    header->length = 500
    header->received_time_ms = 0
    header->send_time_ms = 2690762
    *length_data = 476
    strlen(data) = 1
    data = 
    
    receive_num = -1
    receive_num = -1
    receive_num = -1
    receive_num = 10024
    sizeof(*header) = 24
    header->mark = VSSP
    header->type = _ri
    header->status  = 000
    header->header_length = 24
    header->length = 496
    header->received_time_ms = 0
    header->send_time_ms = 2690763
    *length_data = 472
    strlen(data) = 1
    data = 
    
    receive_num = 1508
    sizeof(*header) = 24
    header->mark = VSSP
    header->type = _ri
    header->status  = 000
    header->header_length = 24
    header->length = 500
    header->received_time_ms = 0
    header->send_time_ms = 2690763
    *length_data = 476
    strlen(data) = 1
    data = 
    
    receive_num = 500
    sizeof(*header) = 24
    header->mark = VSSP
    header->type = _ri
    header->status  = 000
    header->header_length = 24
    header->length = 500
    header->received_time_ms = 0
    header->send_time_ms = 2690764
    *length_data = 476
    strlen(data) = 1
    data = 
    
    receive_num = 504
    sizeof(*header) = 24
    header->mark = VSSP
    header->type = _ri
    header->status  = 000
    header->header_length = 24
    header->length = 504
    header->received_time_ms = 0
    header->send_time_ms = 2690764
    *length_data = 480
    strlen(data) = 1
    data = 
    
    receive_num = 1008
    sizeof(*header) = 24
    header->mark = VSSP
    header->type = _ri
    header->status  = 000
    header->header_length = 24
    header->length = 504
    header->received_time_ms = 0
    header->send_time_ms = 2690765
    *length_data = 480
    strlen(data) = 1
    data = 
    
    receive_num = 500
    sizeof(*header) = 24
    header->mark = VSSP
    header->type = _ri
    header->status  = 000
    header->header_length = 24
    header->length = 500
    header->received_time_ms = 0
    header->send_time_ms = 2690765
    *length_data = 476
    strlen(data) = 1
    data = 
    
    receive_num = 500
    sizeof(*header) = 24
    header->mark = VSSP
    header->type = _ri
    header->status  = 000
    header->header_length = 24
    header->length = 504
    header->received_time_ms = 0
    header->send_time_ms = 2690765
    *length_data = 480
    strlen(data) = 1
    data = 
    
    receive_num = 500
    sizeof(*header) = 24
    header->mark = VSSP
    header->type = _ri
    header->status  = 000
    header->header_length = 24
    header->length = 504
    header->received_time_ms = 0
    header->send_time_ms = 2690766
    *length_data = 480
    strlen(data) = 1
    data = 
    
    receive_num = 500
    sizeof(*header) = 24
    header->mark = VSSP
    header->type = _ri
    header->status  = 000
    header->header_length = 24
    header->length = 500
    header->received_time_ms = 0
    header->send_time_ms = 2690767
    *length_data = 476
    strlen(data) = 1
    data = 
    
    receive_num = -1
    sizeof(*header) = 24
    header->mark = VSSP
    header->type = _ri
    header->status  = 000
    header->header_length = 24
    header->length = 500
    header->received_time_ms = 0
    header->send_time_ms = 2690767
    *length_data = 476
    strlen(data) = 1
    data = 
    
    receive_num = -1
    sizeof(*header) = 24
    header->mark = VSSP
    header->type = _ri
    header->status  = 000
    header->header_length = 24
    header->length = 500
    header->received_time_ms = 0
    header->send_time_ms = 2690767
    *length_data = 476
    strlen(data) = 1
    data = 
    
    receive_num = -1
    sizeof(*header) = 24
    header->mark = VSSP
    header->type = _ri
    header->status  = 000
    header->header_length = 24
    header->length = 504
    header->received_time_ms = 0
    header->send_time_ms = 2690768
    *length_data = 480
    strlen(data) = 1
    data = 
    
    receive_num = -1
    sizeof(*header) = 24
    header->mark = VSSP
    header->type = GET
    header->status  = 000
    header->header_length = 24
    header->length = 403
    header->received_time_ms = 2690770
    header->send_time_ms = 2690771
    *length_data = 379
    strlen(data) = 379
    data = GET:tblh
    0000,02E0,05C1,08A1,0B81,0E62,1142,1422,1703,19E3,1CC3,1FA4,2284,2565,2845,2B25,2E06,33C6,3F48,4AC9,508A,536A,564A,592B,5C0B,5EEB,61CC,64AC,678D,6A6D,6D4D,702E,730E,75EE,78CF,7BAF,7E8F,8170,8450,8730,8A11,8CF1,8FD1,92B2,9592,9872,9B53,9E33,A114,A3F4,A6D4,A9B5,AC95,AF75,B256,B816,C398,CF19,D4DA,D7BA,DA9A,DD7B,E05B,E33C,E61C,E8FC,EBDD,EEBD,F19D,F47E,F75E,FA3E,FD1F,FFFF
    
    receive_num = 91
    sizeof(*header) = 24
    header->mark = VSSP
    header->type = _ri
    header->status  = 000
    header->header_length = 24
    header->length = 500
    header->received_time_ms = 0
    header->send_time_ms = 2690784
    *length_data = 476
    strlen(data) = 1
    data = 
    
    receive_num = 500
    sizeof(*header) = 24
    header->mark = VSSP
    header->type = _ri
    header->status  = 000
    header->header_length = 24
    header->length = 500
    header->received_time_ms = 0
    header->send_time_ms = 2690785
    *length_data = 476
    strlen(data) = 1
    data = 
    
    receive_num = 500
    sizeof(*header) = 24
    header->mark = VSSP
    header->type = _ri
    header->status  = 000
    header->header_length = 24
    header->length = 500
    header->received_time_ms = 0
    header->send_time_ms = 2690793
    *length_data = 476
    strlen(data) = 1
    data = 
    
    receive_num = -1
    sizeof(*header) = 24
    header->mark = VSSP
    header->type = _ri
    header->status  = 000
    header->header_length = 24
    header->length = 500
    header->received_time_ms = 0
    header->send_time_ms = 2690793
    *length_data = 476
    strlen(data) = 1
    data = 
    
    receive_num = 500
    sizeof(*header) = 24
    header->mark = VSSP
    header->type = _ri
    header->status  = 000
    header->header_length = 24
    header->length = 500
    header->received_time_ms = 0
    header->send_time_ms = 2690793
    *length_data = 476
    strlen(data) = 1
    data = 
    
    receive_num = 1000
    sizeof(*header) = 24
    header->mark = VSSP
    header->type = _ri
    header->status  = 000
    header->header_length = 24
    header->length = 500
    header->received_time_ms = 0
    header->send_time_ms = 2690794
    *length_data = 476
    strlen(data) = 1
    data = 
    
    receive_num = 1000
    sizeof(*header) = 24
    header->mark = VSSP
    header->type = _er
    header->status  = 022
    header->header_length = 24
    header->length = 45
    header->received_time_ms = 0
    header->send_time_ms = 2690812
    *length_data = 21
    strlen(data) = 21
    data = Transmission timeout
    
     

    Last edit: akira hayasaka 2019-07-24
  • HUANG da

    HUANG da - 2019-07-25

    「Transmission timeout」について、一番考えられる原因はHOST側受信バッファー満タンでYVTが送信できなくなることです。

    YVTが約290KiB/sのデータ量は発生します。ログから見ると、urg3d_libraryがOSから受信したデータは21099バイトですが、処理されたデータは10972バイト。10127バイト分はurg3d_libraryの受信バッファーに残っています。OSのTCP受信バッファーの状況は分かりませんが、データ溜まっているかとも考えられます。

    お使いの環境を教えてもらいませんか?

     
  • akira hayasaka

    akira hayasaka - 2019-07-25

    環境は、
    windows10
    visial studio 2017
    で、openFrameworksというc++のフレームワークにurg3d_libraryをソースコードとして取り込んで使っています。

    なるほどです。
    urg3d_library内のサンプルは、一定量受信してCSVに保存するようになっていますが、今回僕が作っているものは、常時データを受信し続けてそれを解析し続けるような作りになっています。違うところというとそこなので、常にurg3d_libraryが受信したデータが空になるまでループを回すようなロジックにするべきということですね。
    ちなみに、urg3d_libraryからurg3d_high_get_measurement_dataなどでデータを取得しないでいると、urg3d_libraryは新しいデータをOSから受信できない、つまり古いデータがurg3d_library内に残り続けるということになりますか?

     
  • akira hayasaka

    akira hayasaka - 2019-07-25

    連投して申し訳ありません。
    例えば、サンプルの high_1_frame_4_vfield_2_hfield_data_file.c で、
    urg3d_next_receive_ready(&urg) == falseだった場合、10秒スリープしているのは、どういった意図なのかご存じでしたら教えていただけますか?

     

    Last edit: akira hayasaka 2019-07-25
  • HUANG da

    HUANG da - 2019-07-26

    ちなみに、urg3d_libraryからurg3d_high_get_measurement_dataなどでデータを取得しないでいると、urg3d_libraryは新しいデータをOSから受信できない、つまり古いデータがurg3d_library内に残り続けるということになりますか?

    urg3d_libraryは自分の受信threadを持ちませんので、urg3d_libraryのAPIを呼ばないと受信できません。urg3d_high_get_measurement_dataなどでデータを取得APIを呼んだ時、urg3d_libraryがOSのTCP受信バッファーから受信データをurg3d_libraryの受信バッファーにできるだけ多く受け取ります。APIは自分の処理分のみ、urg3d_libraryの受信バッファーから取り出して処理します。ですので、センサがデータ送信中の時、データ取得APIを呼ばないと、データがurg3d_libraryの受信バッファーまたはOSのTCP受信バッファーに溜まります。

    サンプルの high_1_frame_4_vfield_2_hfield_data_file.c で、
    urg3d_next_receive_ready(&urg) == falseだった場合、10秒スリープしているのは、どういった意図なのかご存じでしたら教えていただけますか?

    urg3d_next_receive_ready(&urg) == falseはheader未受信または受信未完了状態です。10ミリ秒の待ちをして、次の受信を行います。

     
  • akira hayasaka

    akira hayasaka - 2019-07-26

    なるほど、ご説明ありがとうございます。理解しました。
    スリープの方、usleepはマイクロ秒なんですね。失礼しました。

     
  • Takuya Minagawa

    Takuya Minagawa - 2021-02-19

    同じ症状が出ているのですが、具体的にどのようなコードを書けば、urg3d_libraryの受信バッファーまたはOSのTCP受信バッファーをクリアできるのでしょうか?

     
  • akira hayasaka

    akira hayasaka - 2021-02-19

    https://github.com/Akira-Hayasaka/ofxVSSP/blob/e65b027fb54f53e68f68926c227e5b2d06c25d52/src/ofxVSSP.h#L99

    僕は、別スレッドをフリーランさせて、urg3d_next_receive_ready = true の場合、urg3d_high_get_measurement_data し続けるようにしてます。
    これで問題なく動いてるのですが、意図的にクリアする方法あるんですかね。

     
  • kobayashi rin

    kobayashi rin - 2021-02-19

    urg3d_libraryがOSのTCP受信バッファーから受信データをurg3d_libraryの受信バッファーにできるだけ多く受け取ります。

    urg3d_libraryの受信バッファーはセンサ接続時の処理にあるurg3d_tcpclient_buffer_initで初期化されます。ただし、OS側のバッファとのデータの整合性が取れなくなるので、推奨いたしません。
    (OSのTCP受信バッファーのクリア方法はstackoverflow などの一般的なQ&Aサイトで確認してください。)

    sampleではエラーで計測データが取得できなかった場合エラーコードを確認し、最上位の桁が0であれば(Transmission timeoutなどの各種タイムアウトや、初期化中の場合)そのままデータ取得を続行する処理になっています。
    urg3d_tcpclient.hの#define URG3D_MAX_RX_BUFFER_BIT (16)を増やす解決方法もあります。

     
  • Takuya Minagawa

    Takuya Minagawa - 2021-02-19

    ありがとうございました!試してみます。

     

Anonymous
Anonymous

Add attachments
Cancel