Dropped packets / Unable to set throughput limit & packet resend count
AnsweredHi, I am working with the blackfly GigE s camera, the c++ programming interface, and a Linux 22.04 machine. Currently I am running acquisition.cpp and my own modified version of acquisitionMod.cpp. Both versions of acquisition.cpp are setup to take 10 images, however, both only collect about 4 to 6 on each run.
This is the error message I receive,
"Image incomplete: Image has missing packets. Potential fixes include enabling jumbo packets and adjusting packet size/delay. For more information see https://www.flir.com/support-center/iis/machine-vision/application-note/troubleshooting-image-consistency-errors/..."
I read on your trouble shooting website that I should, 1, try to set the DeviceThroughputLimit and, 2, adjust the number of packet resends. These point are where my questions are located.
First, when I try to mess with DeviceThroughputLimit I am unable to access the node.
Here is my code,
Whenever I run this, the IsReadable and or IsWritable tests fail. So, my first question is what am I doing wrong here and or how do I fix this?
Second, the documentation on how to set the number of packet resends only seems to cover using the windows application, not how to set the number of packet resends using c++. My second question is how do I set the number of packet resends using c++?
Ultimately, I am trying to get my system to stop dropping packets, so if there is a better way to accomplish this, I would love to hear it. For now, these are the questions that I think will help me the most.
Thank you for your time!
-
Official comment
Hello,
The issue may be you are using an EnumerationPtr for your throughput limit, when it is an integer.
I used the following code in our simple Acquisition example and I was able to read, set, and read back the Throughput limit okay.
Can you please try this and see if it works for you?
Demos
//
// Set DeviceLinkThroughputLimit
// *** NOTES ***
// The node is checked for availability and writability prior to the
// setting of the node. DeviceLinkThroughputLimit is counted in
// Mbps. This information can be found out either by
// retrieving the unit with the GetUnit() method or by checking SpinView.
//
CIntegerPtr ptrDLThroughputLimit = nodeMap.GetNode("DeviceLinkThroughputLimit");
if (!IsReadable(ptrDLThroughputLimit) ||
!IsWritable(ptrDLThroughputLimit))
{
cout << "Unable to get or set DeviceLinkThroughputLimit. Aborting..." << endl << endl;
return -1;
}cout << "DeviceLinkThroughputLimit read as: " << ptrDLThroughputLimit->GetValue() << endl;
int iThroughputLimitToSet = 100000000;
ptrDLThroughputLimit->SetValue(iThroughputLimitToSet);
cout << "DeviceLinkThroughputLimit read as: " << ptrDLThroughputLimit->GetValue() << endl;
-
Hello,
Thank you for your post. If this becomes a larger troubleshooting issue, I suggest you make a support ticket at flir.custhelp.com/app/ask to debug your individual use case.
To answer your stated questions:
1. The node you want to write to set your throughput limit is DeviceLinkThroughputLimit, not DeviceLinkThroughputLimitMode. The DeviceLinkThroughputLimit node should be readable, and writeable assuming you are not streaming the camera.
Another option is to reserve some extra bandwidth for the packet resends by increasing the DeviceLinkBandwidthReserve value.
2. The dropped frames are due to a poor connection or lack of resources on the PC to keep up with the transferred data. Enabling packet resends and increasing the max number of packet resend requests in an option to try to recover from those errors. However, if you have too many dropped packets, you will not be able to resend the packets in time before the next frame so the image will end up being dropped.
To change the number of packet resend requests to use, you can use the GevMaximumNumberResendRequests node. If you are having issues finding that node via code, it is likely because you are on the camera nodemap, not the streaming nodemap. You can find examples of grabbing the Stream Parameters nodemap in our NodeMapInfo example and our BufferHandling example as starters. Specifically, you would use the following C++ code:
// Retrieve Stream Parameters device nodemap
Spinnaker::GenApi::INodeMap& sNodeMap = pCam->GetTLStreamNodeMap();Overall, to reduce dropped packets on your linux system, please try to:
- manage the throughput limit as much as possible (decrease it or add extra reserve bandwith) without sacrificing your target framerate.
- Ensure packet resend is enabled.
- check your host controller properties (increase transmit/receive buffers, use jumbo packets, etc.) as per the document you pointed at.If you continue to have issue, I think it is best to open a support ticket to handle your specific scenario.
Thank you,
Demos
0 -
Hello, did the above feedback help you set the DeviceLinkThroughput limit and the packet resends?
Did this help resolve your missing packets?
Thank you,
Demos
0 -
Unfortunately no, I tried accessing the "DeviceLinkThroughputLimit" node via the stream node map and was unsuccessful. I opened a help ticket as you suggested and the author of the ticket thought that DeviceLinkThroughputLimit node should be accessed through the regular node map. Just to be sure, I tried the regular node map, the deviceTL node map, and the stream TL node map, none of which worked. I have since replied to the help ticket explaining that the regular node map didn't work and I am waiting to hear back. Thank you for your concern. I have written a short program designed to only access this device link throughput limit and I'll include it in this message. Please note that I skip past a fair amount of error checking because this code will be thrown away.
#include "Spinnaker.h"#include "SpinGenApi/SpinnakerGenApi.h"#include <iostream>#include <sstream>using namespace Spinnaker;using namespace Spinnaker::GenApi;using namespace Spinnaker::GenICam;using namespace std;
int setThroughputLimit (CameraPtr pCam){try{pCam->Init();INodeMap& nodeMap = pCam->GetNodeMap();INodeMap& nodeMapTLDevice = pCam->GetTLDeviceNodeMap();INodeMap& nodeMapTLStream = pCam->GetTLStreamNodeMap();CEnumerationPtr ptrThroughputLimit = nodeMapTLDevice.GetNode("DeviceLinkThroughputLimit");if (!IsReadable(ptrThroughputLimit) ||!IsWritable(ptrThroughputLimit)){cout << "Unable to get device throughput limit (Enum retrieval). Aborting..." << endl << endl;pCam->DeInit(); // Ensure proper cleanupreturn -1; // Indicate failure}pCam->DeInit();cout<<"end of try"<<endl;}catch (Spinnaker::Exception& e){cout<<"start of catch"<<endl;cout << "Error: " << e.what() << endl;pCam->DeInit();}//cout<<"setThoughtput return"<<endl;return 0;}
int main (){SystemPtr system = System::GetInstance();CameraList camList = system->GetCameras();const unsigned int numCameras = camList.GetSize();if (numCameras == 0){// Clear camera list before releasing systemcamList.Clear();// Release systemsystem->ReleaseInstance();cout << "Not enough cameras!" << endl;return -1;}
CameraPtr pCam = nullptr;pCam = camList.GetByIndex(0);
setThroughputLimit(pCam);
pCam = nullptr;camList.Clear();system->ReleaseInstance();cout<<"Program finished"<< endl;return 0;}0 -
Using CIntegerPtr solved the problem! Thank you!
0
Please sign in to leave a comment.
Comments
5 comments