Hi,
I did a small code example.
After a camera reset. I launch the example: impossible to read chunks.
If I restart the same application, it works, I can read chunks.
I think here the camera must start with its factory values.
You will find below the example based on composite image CVB sample.
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
/// \brief This MultiPart tutorial demonstrates an image acquisition where
/// the received composite contains a Bayer image and a converted
/// RGB8 image.
// ----------------------------------------------------------------------------
#include <iostream>
#include <string>
#include <vector>
#include <cvb/device_factory.hpp>
#include <cvb/global.hpp>
#include <cvb/driver/composite_stream.hpp>
#include <cvb/genapi/node_map_enumerator.hpp>
static const constexpr auto TIMEOUT = std::chrono::milliseconds(3000);
static const constexpr int NUM_ELEMENTS_TO_ACQUIRE = 10;
void PrintOutCompositePurpose(Cvb::CompositePtr composite);
void AnalyseCompositeAt(Cvb::CompositePtr composite, int index);
static std::map<Cvb::WaitStatus, const char*>
WAIT_ERROR_STATES
{
{Cvb::WaitStatus::Timeout, "timeout"},
{Cvb::WaitStatus::Abort, "abort"}
};
void SetValue_Int(Cvb::NodeMapPtr& nodemapcam, const char* featurename, int value)
{
auto node = nodemapcam->Node<Cvb::IntegerNode>(featurename);
if (node.get())
{
node->SetValue(value);
}
}
void SetValue_Bool(Cvb::NodeMapPtr& nodemapcam, const char* featurename, bool value)
{
auto node = nodemapcam->Node<Cvb::BooleanNode>(featurename);
if (node.get())
{
node->SetValue(value);
}
}
void SetValue_Enum(Cvb::NodeMapPtr& nodemapcam, const char* featurename, const char* value)
{
auto node = nodemapcam->Node<Cvb::EnumerationNode>(featurename);
if (node.get())
{
node->SetValue(value);
}
}
int main()
{
try
{
// discover transport layers
auto infoList = Cvb::DeviceFactory::Discover(Cvb::DiscoverFlags::IgnoreVins | Cvb::DiscoverFlags::IgnoreGevSD);
// can't continue the demo if there's no available device
if (infoList.empty())
throw std::runtime_error("There is no available device for this demonstration.");
bool camfound = false;
auto token = infoList[0].AccessToken();
for (auto& dicovereditem : infoList)
{
std::string s = dicovereditem.AccessToken().c_str();
if (strstr(s.c_str(), "192.168.13.1") != nullptr) // IP OF ATC6 ON MY MACHINE
{
camfound = true;
token = dicovereditem.AccessToken();
// ATTACH CHUNK (ATC6)
dicovereditem.SetParameter("AttachChunk", "1");
}
}
// instantiate the first device in the discovered list
auto device = Cvb::DeviceFactory::Open<Cvb::GenICamDevice>(token, Cvb::AcquisitionStack::GenTL);
//
//
auto nodes = device->NodeMap(CVB_LIT("Device"));
auto vendor = nodes->VendorName();
auto model = nodes->ModelName();
// MPN enable multipart
SetValue_Bool(nodes, "GevSCCFGMultiPart", true);
// Std::DeviceScanType -> Linescan3D
SetValue_Enum(nodes, "Std::DeviceScanType", "Linescan3D");
// MPN Std::ChunkModeActive
SetValue_Bool(nodes, "Std::ChunkModeActive", true);
// MPN Std::ChunkScanLineSelector: force to the first
SetValue_Int(nodes, "Std::ChunkScanLineSelector", 1);
// Select RegionSelector : prepare some values and disable regions
SetValue_Enum(nodes, "Std::RegionSelector", "Region0");
SetValue_Bool(nodes, "Std::RegionMode", false);
SetValue_Enum(nodes, "Std::RegionSelector", "Region1");
SetValue_Bool(nodes, "Std::RegionMode", false);
SetValue_Enum(nodes, "Std::RegionSelector", "Region2");
SetValue_Bool(nodes, "Std::RegionMode", false);
SetValue_Enum(nodes, "Std::RegionSelector", "Region3");
SetValue_Bool(nodes, "Std::RegionMode", false);
SetValue_Enum(nodes, "Std::RegionSelector", "Region0");
SetValue_Int(nodes, "Std::Height", 24);
SetValue_Int(nodes, "Std::OffsetY", 0);
SetValue_Enum(nodes, "Std::RegionSelector", "Region1");
SetValue_Int(nodes, "Std::Height", 24);
SetValue_Int(nodes, "Std::OffsetY", 32);
SetValue_Enum(nodes, "Std::RegionSelector", "Region2");
SetValue_Int(nodes, "Std::Height", 24);
SetValue_Int(nodes, "Std::OffsetY", 104);
SetValue_Enum(nodes, "Std::RegionSelector", "Region3");
SetValue_Int(nodes, "Std::Height", 24);
SetValue_Int(nodes, "Std::OffsetY", 204);
SetValue_Enum(nodes, "Std::RegionSelector", "Scan3dExtraction0");
SetValue_Int(nodes, "Std::Height", 850);
SetValue_Bool(nodes, "Std::RegionMode", true);
// only enable Region0
SetValue_Enum(nodes, "Std::RegionSelector", "Region0");
SetValue_Bool(nodes, "Std::RegionMode", true);
// REGION Scan3dExtraction0 and enable Reflectance+Scatter
SetValue_Enum(nodes, "Std::RegionSelector", "Scan3dExtraction0");
SetValue_Enum(nodes, "Std::ComponentSelector", "Range");
SetValue_Bool(nodes, "Std::ComponentEnable", false);
SetValue_Enum(nodes, "Std::ComponentSelector", "Reflectance");
SetValue_Bool(nodes, "Std::ComponentEnable", true);
SetValue_Enum(nodes, "Std::ComponentSelector", "Scatter");
SetValue_Bool(nodes, "Std::ComponentEnable", true);
SetValue_Bool(nodes, "Std::RegionMode", true);
// select extraction method
SetValue_Enum(nodes, "Std::Scan3dExtractionSelector", "Scan3dExtraction0");
SetValue_Enum(nodes, "Std::Scan3dExtractionMethod", "Threshold");
SetValue_Int(nodes, "Cust::Scan3dExtractionThresholdIntensity", 50);
// access the first data stream that belongs to the device and start
auto dataStream = device->Stream<Cvb::CompositeStream>();
// pour faire un reset de la comm car si on arrête l'appli en cours d'acquisition,
// on a des erreurs timeout d'acquisition à chaque fois que l'on relancait l'appli.
// Il fallait charger le VIN dans CVB puis relancer l'appli pour avoir les images.
// TryDeviceAbort() éviter le problème.
dataStream->TryDeviceAbort();
// Set a ring buffer
dataStream->RegisterManagedFlowSetPool(8);
dataStream->Start();
// acquire data
for (auto i = 0; i < NUM_ELEMENTS_TO_ACQUIRE; i++)
{
Cvb::CompositePtr composite;
Cvb::WaitStatus waitStatus;
Cvb::NodeMapEnumerator enumerator;
std::tie(composite, waitStatus, enumerator) = dataStream->WaitFor(TIMEOUT);
switch (waitStatus)
{
default:
{
std::cout << "wait status unknown.\n";
continue;
}
case Cvb::WaitStatus::Abort:
case Cvb::WaitStatus::Timeout:
{
std::cout << "wait status not ok: " << WAIT_ERROR_STATES[waitStatus] << "\n";
continue;
}
case Cvb::WaitStatus::Ok:
break;
}
PrintOutCompositePurpose(composite);
AnalyseCompositeAt(composite, i);
try
{
auto timestamp = nodes->Node<Cvb::IntegerNode>("Std::ChunkTimestamp");
std::cout << "ChunkTimestamp:" << timestamp->Value() << " WORKS ONLY THE SECOND LAUNCH APP AFTER REBOOT" << "\n";
}
catch (const std::exception& e)
{
std::cout << "ChunkTimestamp: ERROR !!!! (OCCURS AFTER CAMERA REBOOT)" << "\n";
}
//Cust::BufferTimestamp
auto vinnm = enumerator["VinBuffer"];
auto timestampVin = vinnm->Node<Cvb::IntegerNode>("Timestamp");
std::cout << "VinTimestamp:" << timestampVin->Value() << " NEVER WORKS WITH ATC6" << "\n";
timestampVin.reset();
vinnm.reset();
std::cout << "\n";
}
dataStream->Stop();
dataStream->TryDeviceAbort();
}
catch (const std::exception& e)
{
std::cout << e.what() << std::endl;
}
return 0;
}
/**
* @brief evaluates the given composite and passes the string version of the purpose to stdout
*
* @param composite Cvb::CompositePtr the composite pointer whose purpose is to be extracted.
*/
void PrintOutCompositePurpose(Cvb::CompositePtr composite)
{
auto purpose = composite->Purpose();
std::cout << "Composite purpose: ";
switch (purpose)
{
case Cvb::CompositePurpose::Custom: std::cout << "Custom\n"; break;
case Cvb::CompositePurpose::Image: std::cout << "Image\n"; break;
case Cvb::CompositePurpose::ImageList: std::cout << "Image List\n"; break;
case Cvb::CompositePurpose::MultiAoi: std::cout << "MultiAoi\n"; break;
case Cvb::CompositePurpose::RangeMap: std::cout << "RangeMap\n"; break;
case Cvb::CompositePurpose::PointCloud: std::cout << "PointCloud\n"; break;
case Cvb::CompositePurpose::ImageCube: std::cout << "ImageCube\n"; break;
default: std::cout << "Unknown\n"; break;
}
}
/**
* @brief from a given composite at a certain index prints out information about its content
*
* @param composite Cvb::CompositePtr, the composite to analyse
* @param index int index of the composite for printouts.
*/
void AnalyseCompositeAt(Cvb::CompositePtr composite, int index)
{
auto numberOfElements = composite->ItemCount();
if (numberOfElements < 2)
{
std::cout << "Number of elements in composite #" << index << " is less than expected (no multipart)\n";
return;
}
std::cout << "Multipart data with " << numberOfElements << " elements\n";
for (auto j = 0; j < numberOfElements; j++)
{
auto element = composite->ItemAt(j);
if (Cvb::holds_alternative<Cvb::ImagePtr>(element))
{
auto image = Cvb::get<Cvb::ImagePtr>(element);
auto plane0 = image->Plane(0);
auto dt = plane0.DataType();
auto h = image->Height();
auto linearAccess = image->Plane(0).LinearAccess();
std::cout << "acquired image: " << index << " at memory location: " << (uint64_t)linearAccess.BasePtr() << " datatype: " << dt.BytesPerPixel() <<
" xincr:" << linearAccess.XInc() << " yincr:" << linearAccess.YInc() << " height:" << h << " width:" << image->Width() << "\n";
}
else
std::cout << "Element " << j << " in composite " << index << " is not an image" << "\n";
}
}
I hope you will be able to find the issue.
Regards,
Mikael.