I used CVB library 2016.
I made a simple program that acquired images from camera using a direct translation of the C api for .Net. The camera is connected to the PC via Ethernet. The camera is trigger by an external component every 5 seconds.
The idea is to acquire the images from the camera with the related timestamp (timestamp when the image was acquired by the camera) and the imageId of the image.
Everything is going well (smooth) in a normal execution.
However I noticed during some tests, a really strange behavior when I overload the CPU, the disk and the network.
It happened that when I ask the timestamp from the image, using the CVB api, I got back a duplicated timestamp.
This is a really strange, indeed when I sniff the traffic from the camera to the pc (using wireshark), I noticed that the timestamp is never duplicated. Therefore I can concluded that the timestamp sent by the camera to the pc is correct and the problem is not in the camera itself. This test that I have performed (duplicated timestamp) is easy to reproduce and it occurs often when I overload the pc where the acquisition sw is running.
Did you know why this happens? I assume the image is retrieved in atomic why by the CVB library, therefore the Image Id and/or the timestamp cannot be duplicated.
Am I doing something wrong, or there is problem in the CVB library?
The simple task that acquire images from a single scanner is:
public async Task AcquireData(CancellationTokenSource cts)
{
var driverPath = Path.Combine(Environment.GetEnvironmentVariable("CVB"), "Drivers", "GenICam.vin");
using (var camera = DriverExtensions.TryOpenWithBufferCount(driverPath, NumDriverBuffers))
{
if (camera == null)
{
Console.WriteLine("Error loading driver: " + driverPath);
return;
}
camera.SetLockModeToOn();
camera.StartAcquisition();
// Starts a continuous acquisition of images in a seperate thread.
if (State != ScannerState.Initialized || Driver.IGrab2.G2Grab(m_Camera) < 0)
throw new ScannerException("Cannot grab image from the scanner.");
while (!cts.Token.IsCancellationRequested)
{
var image = m_Camera.WaitForNextImage(cts);
int DC_BUFFER_INFO_TIMESTAMP = 0x00000800;
int cmd = Driver.IDeviceControl.DeviceCtrlCmd(DC_BUFFER_INFO_TIMESTAMP, Cvb.Driver.IDeviceControl.DC_OPERATION.GET);
int res = Driver.IDeviceControl.DCStrCommand(m_Camera, cmd, "", out string pOutHex);
Console.WriteLine("{2} driver timestamp: {0} - res {1}", Convert.ToInt64(pOutHex, 16), res, m_Name);
ProcessImage(cts);
}
}
}
Yes. I have noticed duplicated timestamp using both way to retrieve the timestamp:
int cmd = Driver.IDeviceControl.DeviceCtrlCmd(DC_BUFFER_INFO_TIMESTAMP, Cvb.Driver.IDeviceControl.DC_OPERATION.GET);
and
Cvb.Driver.IGrab2.G2GetGrabStatus(m_DriverImage, Cvb.Driver.IGrab2.TGrabInfoCMD.GRAB_INFO_TIMESTAMP, out double reqAnswer);
I’m using the ring buffer with size 100.
The strange thing is that the imageID retrieved is NOT duplicated.
Below a a log extracted from my application:
Column explanation:
1: image ID retrieved from the driver (DeviceCtrlCmd)
2: image timestamp retrieved from the driver (DeviceCtrlCmd)
3: image ID retrieved from the image ring buffer (G2GetGrabStatus)
4: image timestamp retrieved from the image ring buffer (G2GetGrabStatus)
5: number of actually locked buffers (GRAB_INFO_NUMBER_IMAGES_LOCKED)
The log that I have attached is NOT correct (the correct version would have been without duplicated timestamp). Indeed, the 2nd and the 6th rows have the same duplicated timestamps. The log I have attached is an example of the output produced by my application.
The image id is NOTduplicated (first and second column).
What do you mean with: “Do you also see the problem when using the socket driver?” Do you mean using the api call: Driver.IDeviceControl.DeviceCtrlCmd(DC_BUFFER_INFO_TIMESTAMP, Cvb.Driver.IDeviceControl.DC_OPERATION.GET);.The answer is yes.
The version of the CVB that I have tried in which I have encountered duplicated timestamp are: 11.02.005 (x64) and 12.01.003.
I have upgraded the driver and I’m currently using CVB 2017 13.00.004.
In order to give you the GenICam.ini I should downgrade to the library of 2016 or older. At the moment is not easy for me.
I want to perform the same tests that I did with older libraries (11.02.005 (x64) and 12.01.003.), using the new version of 2017 and try to stress the system. I want to verify whether with the newer CVB library I have the same duplicated timestamp.
I’m acquiring data using filter driver (not socket driver).
From the link you have sent, the filter driver reduce the CPU load, therefore is a more suitable solution.
Should I try to switch to socket driver?
If I understand correctly from the last part of your answer, there is a bug in the previous version of the CVB, since everything is updated except its timestamp?
We are currently not aware of a bug as you see it. I’ve seen in the release notes that the timestamp handling has been fixed in certain chunk scenarios (I can’t check the source code as I am not in the office this week):
The time stamps on images with chunk data are now handled consistently. (Filter Driver)
Versions and GenICam.ini
I didn’t get the part with the versions and the GenICam.ini: do you have restrictions using :cvb: 2017? When updating we do not overwrite the GenICam.ini.
Filter Driver vs Socket Driver
Yes, the filter driver reduces CPU load because it reduces the number of kernel/user mode transitions: so you should use it in production. I asked it of you only to determine the source of the error as socket and filter driver have different implementations. Also this can be quickly tested without much work to be done. If you don’t see the duplicated time stamps with the socket driver, we have pinned down the module.
Support Ticket
If the issue remains we need to know the exact camera model and configuration (camera and GenICam.ini). You can also open a support ticket with us:
Versions and GenICam.ini
Sorry I misunderstand, I thought you were talking about the “GenICam.vin” and this one is overwritten when a new version of the CVB library is installed.
Filter Driver vs Socket Driver
I will make some test also using the socket driver as you suggested.
GenICam and camera model
I attached the GenICam.ini file. The model of the camera is: AT Automation Technology GmbH - C4-2350 GigE GenICam.zip (1.2 KB)
We were able to further investigate the error of an older timestamp under high system load by now. The error occurs when frames are corrupted due to missing packages under high system load. In order to create a “smooth” process when calling “wait” it will return everything in the image buffer as long as it is valid in the sense that the buffer is ok and there are no “hard” errors which would break the aquisition. This will then potentially also return corrupt frames and leave it to the developer to decide what to do with the image.
Checking the timestamp may yield an older timestamp if an image was only partly updated. To minimize this issue please try to:
Use more buffers for the ringbuffer to use (e.g. set higher NumBuffer in the %CVBDATA%Drivers/GenICam.ini).
If you test for corrupt buffers keep in mind that you still won’t know if the current frame is one of the corrupt buffers.
We plan on implementing a new feature which will allow the user to retrieve information on the state of the current image (if packages were lost or the image is 100 % fine) more easily.
Most of all: Make sure the system will not run under heavy load for a prolonged period of time.