#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; static void signalHandler(int sig) { cerr << endl << "=== SEGFAULT (signal " << sig << ") ===" << endl; exit(1); } static void printNode(Cvb::NodeMapPtr nodeMap, const char* name) { auto node = nodeMap->Node(name); if (!node) { cout << " " << name << " = (not found)" << endl; return; } auto e = std::dynamic_pointer_cast(node); if (e) { cout << " " << name << " = " << e->Value() << endl; return; } auto i = std::dynamic_pointer_cast(node); if (i) { cout << " " << name << " = " << i->Value() << endl; return; } auto b = std::dynamic_pointer_cast(node); if (b) { cout << " " << name << " = " << (b->Value() ? "true" : "false") << endl; return; } cout << " " << name << " = (unknown type)" << endl; } static void dumpNodeMapValues(Cvb::NodeMapPtr nodeMap, const string& base); static void dumpNodeMaps(Cvb::DevicePtr device, const string& prefix) { auto nodeMaps = device->NodeMaps(); for (const auto& [name, nodeMap] : nodeMaps) { if (!nodeMap) continue; string base = prefix + "_" + string(name.begin(), name.end()); try { string gcsFile = base + ".gcs"; nodeMap->SaveSettings(gcsFile); cout << " Saved " << gcsFile << endl; } catch (const exception& e) { cerr << " SaveSettings failed for " << base << ": " << e.what() << endl; } dumpNodeMapValues(nodeMap, base); } } static void dumpStreamNodeMaps(Cvb::CompositeStreamBasePtr stream, const string& prefix) { auto nodeMaps = stream->NodeMaps(); for (const auto& [name, nodeMap] : nodeMaps) { if (!nodeMap) continue; string base = prefix + "_" + string(name.begin(), name.end()); try { string gcsFile = base + ".gcs"; nodeMap->SaveSettings(gcsFile); cout << " Saved " << gcsFile << endl; } catch (const exception& e) { cerr << " SaveSettings failed for " << base << ": " << e.what() << endl; } dumpNodeMapValues(nodeMap, base); } } static void dumpNodeMapValues(Cvb::NodeMapPtr nodeMap, const string& base) { try { string txtFile = base + "_nodes.txt"; ofstream out(txtFile); auto nodes = nodeMap->Nodes(); for (const auto& [nodeName, node] : nodes) { string val; try { auto e = dynamic_pointer_cast(node); if (e) { val = e->Value(); } else { auto i = dynamic_pointer_cast(node); if (i) { val = to_string(i->Value()); } else { auto b = dynamic_pointer_cast(node); if (b) { val = b->Value() ? "true" : "false"; } else { auto f = dynamic_pointer_cast(node); if (f) { val = to_string(f->Value()); } else { auto s = dynamic_pointer_cast(node); if (s) { val = s->Value(); } else { auto ee = dynamic_pointer_cast(node); if (ee) { val = to_string(ee->NumericValue()) + " (" + ee->SymbolicValue() + ")"; } else { auto r = dynamic_pointer_cast(node); if (r) { val = "Addr=" + to_string(r->Address()) + " Len=" + to_string(r->Length()); } else { auto c = dynamic_pointer_cast(node); if (c) { val = "(Category: " + to_string(c->NodeCount()) + " subnodes)"; } else { auto cmd = dynamic_pointer_cast(node); if (cmd) { val = string("(Command: IsDone=") + (cmd->IsDone() ? "true" : "false") + ")"; } else { val = "(unsupported type: " + string(typeid(*node).name()) + ")"; } } } } } } } } } } catch (const exception& ex) { val = string("(read error: ") + ex.what() + ")"; } catch (...) { val = "(read error: unknown)"; } out << nodeName << " = " << val << "\n"; } out.close(); cout << " Saved " << txtFile << " (" << nodes.size() << " nodes)" << endl; } catch (const exception& e) { cerr << " Node dump failed for " << base << ": " << e.what() << endl; } } int main() { signal(SIGSEGV, signalHandler); signal(SIGBUS, signalHandler); cout << "=== MechMind CVB Acquisition Test (ImageStream) ===" << endl; cout << "CVB: /opt/cvb (14.01.007)" << endl; cout << "Stream type: ImageStream" << endl; // [1] Discover cout << "\n[1] Discovering..." << endl; auto cameras = Cvb::DeviceFactory::Discover(Cvb::DiscoverFlags::IgnoreVins); if (cameras.empty()) { cerr << "No devices" << endl; return 1; } for (size_t i = 0; i < cameras.size(); i++) { Cvb::String serial{"?"}, model{"?"}; cameras[i].TryGetProperty(Cvb::Driver::DiscoveryProperties::DeviceSerialNumber, serial); cameras[i].TryGetProperty(Cvb::Driver::DiscoveryProperties::DeviceModel, model); cout << " [" << i << "] " << model << " serial=" << serial << endl; } // [2] Open cout << "\n[2] Opening..." << endl; Cvb::DevicePtr device; try { device = Cvb::DeviceFactory::Open( cameras[0].AccessToken(), Cvb::AcquisitionStack::GenTL); } catch (const exception& e) { cerr << "Open error: " << e.what() << endl; return 1; } cout << " Opened OK" << endl; auto genDevice = dynamic_pointer_cast(device); if (!genDevice) { cerr << "Not GenICamDevice" << endl; return 1; } auto nodeMap = device->NodeMaps()["Device"]; if (!nodeMap) { cerr << "No Device NodeMap" << endl; return 1; } // [3] Read parameters cout << "\n[3] Device parameters:" << endl; printNode(nodeMap, "DeviceScanType"); printNode(nodeMap, "ComponentSelector"); printNode(nodeMap, "PixelFormat"); printNode(nodeMap, "AcquisitionMode"); printNode(nodeMap, "DataAcquisitionMethod"); printNode(nodeMap, "DataAcquisitionTriggerSource"); printNode(nodeMap, "LineScanTriggerSource"); printNode(nodeMap, "TriggerMode"); printNode(nodeMap, "Width"); printNode(nodeMap, "Height"); printNode(nodeMap, "PayloadSize"); printNode(nodeMap, "AcquisitionStatus"); // [4] Get stream (ImageStream) cout << "\n[4] Getting ImageStream..." << endl; auto imageStream = genDevice->Stream(0); if (!imageStream) { cerr << "No stream" << endl; return 1; } cout << " ImageStream(0): OK" << endl; // [5] FlowSet info cout << "\n[5] FlowSet info:" << endl; cout << " MinRequiredFlowSetCount = " << imageStream->MinRequiredFlowSetCount() << endl; auto flowInfo = imageStream->FlowSetInfo(); cout << " Flows: " << flowInfo.size() << endl; for (size_t i = 0; i < flowInfo.size(); i++) cout << " flow[" << i << "] size=" << flowInfo[i].Size << " alignment=" << flowInfo[i].Alignment << endl; // [6] DUMP node maps BEFORE Start() cout << "\n[6] Dumping node maps before Start()..." << endl; dumpNodeMaps(device, "pre_start"); dumpStreamNodeMaps(imageStream, "pre_start"); // [7] Set DataAcquisitionMethod to Nonstop (like SDK does) cout << "\n[7] Setting DataAcquisitionMethod = Nonstop..." << endl; try { auto acqMethodNode = nodeMap->Node("DataAcquisitionMethod"); if (acqMethodNode) { acqMethodNode->SetValue("Nonstop"); cout << " DataAcquisitionMethod = Nonstop" << endl; } } catch (const exception& e) { cerr << " Failed to set DataAcquisitionMethod: " << e.what() << endl; } // [8] Configure stream destination (IP + port) — avoid SIGSEGV cout << "\n[8] Configuring stream destination..." << endl; auto dsNodeMap = imageStream->NodeMap(Cvb::NodeMapID::DataStream); if (dsNodeMap) { try { auto ipNode = dsNodeMap->Node("StreamDestinationIP"); if (ipNode) { ipNode->SetValue(3232241419); cout << " StreamDestinationIP = 3232241419 (192.168.23.11)" << endl; } } catch (const exception& e) { cerr << " Failed to set StreamDestinationIP: " << e.what() << endl; } try { auto portNode = dsNodeMap->Node("StreamPort"); if (portNode) { portNode->SetValue(49152); cout << " StreamPort = 49152" << endl; } } catch (const exception& e) { cerr << " Failed to set StreamPort: " << e.what() << endl; } try { auto applyCmd = dsNodeMap->Node("StreamDestinationApply"); if (applyCmd) { applyCmd->Execute(); cout << " StreamDestinationApply executed" << endl; } } catch (const exception& e) { cerr << " Failed to execute StreamDestinationApply: " << e.what() << endl; } } else { cerr << " No TLDatastream node map!" << endl; } // [9] Pool + Start cout << "\n[9] Starting..." << endl; imageStream->RegisterManagedFlowSetPool(8); imageStream->Start(); cout << " Start() OK" << endl; cout << " AcquisitionState = " << static_cast(imageStream->AcquisitionState()) << endl; // [10] DUMP node maps AFTER Start() cout << "\n[10] Dumping node maps after Start()..." << endl; dumpNodeMaps(device, "post_start"); dumpStreamNodeMaps(imageStream, "post_start"); // [11] WaitFor loop cout << "\n[11] Waiting for images (5s max)..." << endl; auto startTime = chrono::steady_clock::now(); int frameCount = 0, timeoutCount = 0; bool gotData = false; while (true) { auto elapsed = chrono::duration_cast( chrono::steady_clock::now() - startTime).count(); if (elapsed >= 5) break; try { Cvb::MultiPartImagePtr image; Cvb::WaitStatus waitStatus; Cvb::NodeMapEnumerator enumerator; tie(image, waitStatus, enumerator) = imageStream->WaitFor(chrono::milliseconds(500)); if (waitStatus == Cvb::WaitStatus::Ok && image) { cout << " FRAME #" << ++frameCount << " parts=" << image->NumParts() << " w=" << image->Width() << " h=" << image->Height() << endl; gotData = true; } else if (waitStatus == Cvb::WaitStatus::Timeout) { if (++timeoutCount <= 3) cout << " Timeout #" << timeoutCount << endl; } else if (waitStatus == Cvb::WaitStatus::Abort) { cout << " Abort" << endl; break; } if (frameCount >= 3) break; } catch (const exception& e) { cerr << " WaitFor error: " << e.what() << endl; break; } } // [12] DUMP node maps AFTER WaitFor attempts cout << "\n[12] Dumping node maps after WaitFor..." << endl; dumpNodeMaps(device, "post_waitfor"); dumpStreamNodeMaps(imageStream, "post_waitfor"); // [13] Stop cout << "\n[13] Stopping..." << endl; imageStream->Stop(); cout << " Stopped" << endl; cout << "\n=== Summary ===" << endl; cout << " Frames: " << frameCount << endl; cout << " Timeouts: " << timeoutCount << endl; cout << " Got data: " << (gotData ? "yes" : "no") << endl; cout << "===============" << endl; return 0; }