Synchronizing IDS GigE Vision cameras with PTP

アプリケーションで複数のカメラからの画像データを処理する必要がある場合、正確な時刻または正しい時間的順序での画像を記録が、その後の処理に重要であることが多くあります。タイムスタンプを提供すれば、さまざまな画像データへの時間基準を確立することができます。ただし、カメラのタイムベースが正確に一致することが重要です。IDS GigE Vision カメラは、Precision Time Protocol(PTP)を使用して、ファームウェア 2.2 以降と簡単に同期することができます。

PTP を使用した IDS GigE Vision カメラの同期

Precision Time Protocol(PTP)は、ネットワーク経由で接続されたデバイスの時刻同期を可能にする時刻同期規格(IEEE1588)です。この規格をサポートするカメラは、指定された周期でタイムマスターと同期メッセージを交換します。各送受信時のタイムスタンプ情報に基づいて、カメラの内部カウンターが高精度で補正され、同期を合わせることができます。

すべての IDS GigE Vision カメラは、カメラファームウェアバージョン 2.2 を搭載することで PTP 互換になります。

PTP は USB 接続用に定義されたものではないため、このアプリケーションノートでは IDS GigE Vision カメラについてのみ言及します。

IEEE1588 タイムスタンプは、1970 年 1 月 1 日 00:00 をゼロ時刻として設定したエポックタイマーで、分解能 1 ns(1 GHz)を提供します。一方、ネットワークデバイス間の時刻同期の精度は、遅延や信号ランタイムの精度が低いため、マイクロ秒程度の範囲です。

PTP の使用例

PTP は、画像コンテンツの時間参照を使用するさまざまなアプリケーションの基礎を形成するベーステクノロジーです。これは、アプリケーションの要件とネットワークインフラの複雑さに応じて別々に生成することができます。

1. 相対タイムスタンプ同期

この場合、すべてのカメラは同じネットワークにあります。1 台のカメラがマスターで、それ以外のカメラはスレーブです。すべてのスレーブカメラのタイムスタンプはマスターカメラと同期されます。カメラは絶対タイムスタンプ(実時刻)を提供しておらず、追加の作業がなければ同期的にトリガーすることもできません。

利点:

  • 相対タイムスタンプは、アプリケーションで、すべてのカメラの画像記録の時間割り当てを確立します。最初の画像と、異なるカメラの画像間の時間差です。
  • 相対タイムスタンプは、追加の作業や特別なネットワークインフラへのコストなしで生成することができます。

2. 絶対時間とのタイムスタンプ同期

この場合、ネットワークカメラを外部のマスターと同期させます。この PTP マスターは、同期精度が著しく低下するハードウェアサポートを行わずに、いわゆる「ハードウェアタイムスタンプ」をサポートするネットワークカードでも可能です。必要はハードウェアに加え、PTP をサポートするソフトウェアも必要です(IDS peak には含まれません)。

利点:

  • グローバル(実)タイムスタンプを持つ画像コンテンツを、アプリケーションの制限を超えて実時刻参照を持つ他のどの情報とも関連付けることができます。
  • 画像コンテンツは、グローバル時刻参照を使用する他のアプリケーションや評価に使用することができます。

PTP の使用:「相対同期"

次のセクションでは、2 台の PTP 対応ネットワークカメラ間でタイムスタンプの「相対同期」を確立する方法の一例について説明します。

ハードウェアのセットアップ

ファームウェア 2.2 を搭載した 2 台の異なる IDS GigE Vision カメラ(GV-526xFA-C と GV-504xCP-M)を同じネットワークスイッチに接続します。追加のホスト PC は、カメラの制御と設定にのみ使用できます。カメラの PTP 同期には関与しません。

ソフトウェアのセットアップ

すべての PTP 設定機能は、"PtpControl" カテゴリのカメラの機能ノードマップにあります。これらの機能は、ファームウェアバージョン 2.2 以降で使用できます。PTP 同期を設定するには、ホスト PC の IDS peak のインストール先の Vision Cockpit を使用します。

台のカメラを PTP マスターとして設定する

GV-526xFA-C カメラを PTP マスターデバイスとして設定します。Vision Cockpit でカメラを開き、"PtpEnable" を "True" に設定して PTP をアクティブにします。また、"PtpSlaveOnly" を "False" に設定して、マスターロールを引き受けるアクセス権限をカメラに付与します。

# Configure master camera
PtpEnable = True
PtpSlaveOnly = False

もう 1 台のカメラを PTP スレーブとして設定する

GV-504xCP-M を PTP スレーブデバイスとして設定します。ここでも "PtpEnable" を "True" に設定して PTO をアクティブにします。ただし今度は、カメラをスレーブデバイスとしての動作のみに制限します。そのため、"PtpSlaveOnly" は "True" に設定されたままにします。

# Configure slave camera
PtpEnable = True
PtpSlaveOnly = True

マスタースレーブ階層の確立

マスターデバイスとスレーブデバイスを設定すると、すぐにマスタースレーブ階層が自動的に確立されます。これは、マスターカメラの場合、"PtpStatus" が "Listening " から "Master" に変わることで確認できます。 スレーブカメラの場合、まず "PtpStatus が "Listening" から "Uncalibrated" に変わり、さらにマスターカメラとの同期が完了した後 "Slave" に変わることを確認して認識できます。

カメラのマスタースレーブ階層が新しい PTP 機能を使用して確立されると、「相対同期」は完了です。

タイムスタンプの有効化

今同期したカメラとその画像データをユーザーのアプリケーションで使用する場合は、タイムスタンプ(およびチャンクデータ)のメタデータとしての転送をアクティブにする必要があります。
まず、"ChunkModeActive" を "True" に設定してチャンクデータと画像バッファの転送をアクティブにします。次に、"ChunkSelector" で " Timestamp" を選択し、それを "ChunkEnable" スイッチでアクティブにします。

# activate chunk data creation
ChunkModeActive = True
 
# enable "ChunkTimestamp"
ChunkSelector = Timestamp
ChunkEnable = True

これより、カメラは各画像収集と共にタイムスタンプを生成し、画像バッファ(チャンクデータ内)と共にホスト PC に転送します。チャンクデータとタイムスタンプは、Vision Standard ソフトウェアで読み取ることができます。

# image acquisition configuration for both cameras
LineSelector = Line2
LineMode = Output
LineSource = PPS
TriggerSelector = ExposureStart
TriggerMode = On
TriggerSource = Line2
 
# Limit bandwidth on both cameras
DeviceLinkThroughputLimit = 60000000
 
# Start acquisition on both cameras
Execute AcquisitionStart
同期された PPS トリガー信号により、カメラの画像収集が同じ時刻に発生する
同期された PPS トリガー信号により、カメラの画像収集が同じ時刻に発生する

タイムスタンプを読み取る

アプリケーションでタイムスタンプを画像コンテンツと共に処理するには、現在のイメージバッファのチャンクデータを読み取る必要があります。チャンクデータは、メモリレイアウトが通常不明の製造元固有のペイロードバッファであるため、個々のメタデータはノードマップを使用して読み取られます。このため、既存のすべてのメタデータは、標準の API を使用してアクセスできるように、GenTL からその標準化されたノード名と共に、ノードマップに転送されます。

4 月上旬の IDS peak 1.1 アップデートでは、IDS peak API を使用して非常に簡単にタイムスタンプおよびその他のすべてのチャンクデータを抽出して処理できるようになります。以下のソースコードスニペットでは、画像バッファから正確なタイムスタンプを抽出する方法の例を示します。チャンクデータの処理を説明する完全なソースコードのサンプルは、IDS peak SDK(バージョン 1.1 以降)のインストールパッケージにも含まれています。

// Get buffer from device's datastream
const auto buffer = m_dataStream->WaitForFinishedBuffer(5000);
 
// check buffer for chunks
if (buffer->HasChunks())
{
    // update nodemap with current chunk data
    m_nodemapRemoteDevice->UpdateChunkNodes(buffer);
 
    // Get the value of the timestamp chunk
    const auto chunktimestamp = m_nodemapRemoteDevice->FindNode<peak::core::nodes::FloatNode>("ChunkTimestamp")->Value();
}