3rd stack GENTL (no VIN) : how to get timestamp

Hello,
I am working with an ATC6 camera and a dala Linea 2g GIGE camera.
I use multipart image (because of ATC6).
For ATC6, I can get timestamp and other info in chuck datas.

For Linea, I would like to retrive timestamp. I can do it with end of line meta data. But there must be something standard with CVB++ initialized with GENTL flag. I konw how to get it from the VIN, but not using CVB++ GenTL.

I’ve initialized my datastream with :slightly_smiling_face:
m_dataStream = m_device->Stream<Cvb::CompositeStream>();
How can I get the timestamp (moment image was triggered)?
Best regards,
Mikael.

Hi @Mikael,

did you activate AttachChunk when using the GenTL?
You can refere to here (only samples for .NET and Python): https://forum.commonvisionblox.com/t/using-chunk-data-in-cvb/1895

Otherwise you could use this C++ code snippet to activate AttachChunk using GenTL:

auto vinDeviceNodemap = VinDeviceNodeMap(dev);
auto AttachChunk_node = vinDeviceNodemap->Node<Cvb::BooleanNode>(Cvb::String("AttachChunk"));
AttachChunk_node ->SetValue(true);

Afterwards handling ChunkData is equal to using the vin driver.

Hi Simon,
with Dalsa Linea, I get an exception:

Node[Cost::AttachChunk] : no write access to node

There are no chunkdata with Dalsa Linea.

If I use this below, it seems to give the timestamp after the image is received in the PC. Not the frame trigger timestamp.

std::tie(multiPartImage, waitStatus, enumeratorNodeMap) = streams[streamIndex]->WaitFor(TIMEOUT);

auto vinBufferNodemap = enumeratorNodeMap["VinBuffer"];

auto timeStamp = vinBufferNodemap->Node<Cvb::IntegerNode>("Timestamp")->Value();

How can I get frame trigger timestamp? Using VIN it was possible, I think with GenTL there must be something. I’ve checked it using end of line metadata.

Regards,
Mikael.

Hi @Mikael,
there are multiple reasons why this is not working.

Using the EndOfLineMetadata of the Linea differs from handling Metadata/Chunk Data from different camera models.
In case of the Linea EndOfLineMetadata means that all information is added to the camera image using the last pixels for each line. The number of used pixels is depending on the number and type of activated metadata.
Here are example images from the Linea grabbed using the GenICam Browser:
Without Metadata:

With Metadata Active (ExposureTime and Timestamp):

The number of pixels per line stays equal to 2048 for the Linea 2K, so you will loose information from the pixels used for Metadata.

Now extracting these data from code in CVB could look like this:

using Stemmer.Cvb;
using Stemmer.Cvb.Driver;
using Stemmer.Cvb.GenApi;

namespace CVB_LineaMetadata
{
  internal class Program
  {
    static void Main(string[] args)
    {
      DiscoveryInformationList discoveryList = DeviceFactory.Discover(DiscoverFlags.IgnoreVins);
      if (discoveryList[0].AccessToken.Contains("Linea"))
      {
        //discoveryList[0].SetParameter("AttachChunk", "1");
        //Open Linea using GenTL
        using (Device device = DeviceFactory.Open(discoveryList[0]))
        {
          Stream stream = device.Stream;
          NodeMap nodemap = device.NodeMaps[NodeMapNames.Device];

          //Activating Metadata
          EnumerationNode metadatamode = nodemap["Cust::endOfLineMetadataMode"] as EnumerationNode;
          metadatamode.Value = "Active";
          EnumerationNode metadataContentSelector = nodemap["Cust::endOfLineMetadataContentSelector"] as EnumerationNode;
          EnumerationNode metadataContentActivationMode = nodemap["endOfLineMetadataContentActivationMode"] as EnumerationNode;
          metadataContentSelector.Value = "ExposureTime";
          metadataContentActivationMode.Value = "True";
          metadataContentSelector.Value = "Timestamp";
          metadataContentActivationMode.Value = "True";

          //Get Metadata Size
          long metadataPixelCount = (nodemap["Cust::endOfLineMetadataPixelCount"] as IntegerNode).Value;
          //Get Line Width
          long linewidth = (nodemap["Std::Width"] as IntegerNode).Value;
          long imageheight = (nodemap["Std::Height"] as IntegerNode).Value;
          byte[,] metadata = new byte[imageheight, metadataPixelCount];
          int offsetMetadata = (int)(linewidth - 1 - metadataPixelCount);
          //Start Stream
          stream.Start();
          for (int i = 0; i < 10; i++)
          {
            using(Image image = stream.Wait())
            {
              LinearAccessData<byte> imageData = image.Planes[0].GetLinearAccess<byte>();
              for(int y = 0; y < imageheight; y++)
              {
                for(int x = 0; x < metadataPixelCount; x++)
                {
                  metadata[y,x] = imageData[(x+ offsetMetadata), y];
                }
              }
              //Decode Metadata...
            }
          }
          stream.Abort();
        }
      }
    }
  }
}

Note that Chunk Data do not need to be activated on the driver side as theese are not Chunk Data in this context and just data that are written to the transmitted image.

To receive the FrameTriggerTimestamp you would need to use a completely different approach.
You will need to use Event handling to receive Cust::EventValidFrameTriggerTimestamp for each valid frame trigger. How to use event data, please have a look here.

Hi Simon,
I’ve used end of line metadata that is why I discovered that the timestamp from “VinBuffer” is not the frame trigger timestamp. This timestamp is more than 100ms after the last line timestamp in the image (in end of line metadata): it is probably a timestamp after the image is received in the PC. Which is not a reliable timestamp (if I make no mitake).
→ this is strange, I have big doubts with this timestamp! A timestamp must come from the camera with the image.

If I compare with GENICAM.VIN, using “DCBinaryCommand DC_BUFFER_INFO_TIMESTAMP” was reliable and associtated to frame trigger and coming from the camera.

Using GenTL should also give the same results. So where is the problem?

Regards,
Mikael.

Hi @Mikael,

the best option to get the correct timestamp from the camera would be using the StreamImage Class for image acquisition which will contain the camera timestamp as using “DCBinaryCommand DC_BUFFER_INFO_TIMESTAMP”.

You could also read the timestamp from the last or first acquired line using EndOfLineMetadata. Depending on which timestamp you really require.
Third option is to use the Event Data mentioned above from the camera where you can exactly specify which event should be tracked (Valid Frame Trigger, Frame Start, Frame End)

Thanks Simon,

I am using an ATC6 camera and Linea 2k camera (and later a linea swir).
Because of ATC6, I used for all cams a composite stream.
I cannot fing RawTimeStamp in that case (or I did not find the way to do it).

How can I do to get RawTimeStamp? Was composite stream the good choice?

Regards,
Mikael.

Dear @Mikael

pleas see the following code to acquire the GEV Timestamp from the VinBuffer using 3rd generation image acquisition stack:

auto devices = DeviceFactory::Discover(DiscoverFlags::IgnoreVins);
auto device = DeviceFactory::Open<GenICamDevice>(devices[0].AccessToken(), AcquisitionStack::GenTL);
auto stream = device->Stream<CompositeStream>(); // default: index = 0 (1)
stream->Start(); // (2)
for (int i = 0; i < 10; ++i)
{
  CompositePtr composite;
  WaitStatus status;
  NodeMapEnumerator nodeMaps;
  std::tie(composite, status, nodeMaps) = stream->Wait(); // C++14 (3)
  auto [composite, status, nodeMaps] = stream->Wait(); // C++17 (3)
  auto vinBufferNodemap = nodeMaps["VinBuffer"];
  auto bufferTimpestamp = vinBufferNodemap->Node<Cvb::IntegerNode>("Timestamp")->Value();
}
stream->Abort(); // (4)

Instead of CompositeStream you can use ImageStream for the Dalsa Linea.
This will give you the timestamp of acquisition start from the camera.
When I read the VinBuffer Nodemap Timestamp and compare it to the timestamps from my first and last line the result is as as follows:
VinBuffer-Timestamp: 3897064003
First Line: 3897064013
Last Line: 3897166313
So the VinBuffer Timestamp is to an earlier stage as the first line is acquired.

Hi Simon,
I understand my mistake.
I was reading Metadata on the previous image!!!
So the timestamp was always different from the timestamp given by “VinBuffer”.
Sorry for ennoying you about this.
Now I can see the timestamp has roughtly the same value than the timestamp in metadata of the first line.
Thanks for your help.
Mikael.

Hi @Mikael,

sounds good! I am happy that I could be of help.