Code owners
Assign users and groups as approvers for specific file changes. Learn more.
utils.cpp 6.52 KiB
#include "utils.h"
#include "opencv2/core/version.hpp"
#include <random>
#include <iostream>
#include "VmbCPP/VmbCPP.h"
#include <VmbC/VmbCommonTypes.h>
#include <QDebug>
#include <QDir>
#include <QThread>
#include <QCoreApplication>
#include <QFile>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
using namespace VmbCPP;
namespace utils
{
const int APP_VERSION_MAJOR = 0;
const int APP_VERSION_MINOR = 2;
const int APP_VERSION_PATCH = 0;
std::atomic<bool> running(true);
int ncam(const int& n)
{
static const int _ncam = n;
#ifdef DEBUG
return 2;
#endif
return _ncam;
}
int threadsPerCam()
{
#ifdef DEBUG
return 8;
#else
return std::ceil(static_cast<double>(QThread::idealThreadCount()-2) / ncam() ); //round up! -2 for main and console
#endif
}
const QString getVersion()
{
return QString("# Recorder: %1.%2.%3").arg(APP_VERSION_MAJOR).arg(APP_VERSION_MINOR).arg(APP_VERSION_PATCH);
}
const QStringList getVersions()
{
VmbVersionInfo_t version;
VmbSystem::GetInstance().QueryVersion(version);
QStringList s;
s << "### Versions";
s << QString("# Recorder: %1.%2.%3").arg(APP_VERSION_MAJOR).arg(APP_VERSION_MINOR).arg(APP_VERSION_PATCH);
s << QString("# Vimba: %1.%2.%3").arg(version.major).arg(version.minor).arg(version.patch);
s << QString("# Qt: %1.%2.%3").arg(QT_VERSION_MAJOR).arg(QT_VERSION_MINOR).arg(QT_VERSION_PATCH);
s << QString("# openCV: %1.%2.%3").arg(CV_VERSION_MAJOR).arg(CV_VERSION_MINOR).arg(CV_VERSION_REVISION);
return s;
}
const QString errorCodeToMessage( VmbError_t err )
{
QString msg = "⚠️ ";
switch( err )
{
default: msg += "Unknown"; break;
case VmbErrorJustInfo: msg = ""; break; //custom
case VmbErrorSuccess: msg = "success! 😎"; break; //
case VmbErrorInternalFault: msg += "Unexpected fault in VmbApi or driver."; break;
case VmbErrorApiNotStarted: msg += "API not started."; break;
case VmbErrorNotFound: msg += "Not found."; break;
case VmbErrorBadHandle: msg += "Invalid handle "; break;
case VmbErrorDeviceNotOpen: msg += "Device not open."; break;
case VmbErrorInvalidAccess: msg += "Invalid access."; break;
case VmbErrorBadParameter: msg += "Bad parameter."; break;
case VmbErrorStructSize: msg += "Wrong DLL version."; break;
case VmbErrorMoreData: msg += "More data returned than memory provided."; break;
case VmbErrorWrongType: msg += "Wrong type."; break;
case VmbErrorInvalidValue: msg += "Invalid value."; break;
case VmbErrorTimeout: msg += "Timeout."; break;
case VmbErrorOther: msg += "TL error."; break;
case VmbErrorResources: msg += "Resource not available."; break;
case VmbErrorInvalidCall: msg += "Invalid call."; break;
case VmbErrorNoTL: msg += "TL not loaded."; break;
case VmbErrorNotImplemented: msg += "Not implemented."; break;
case VmbErrorNotSupported: msg += "Not supported."; break;
// ------------------------------- own errCodes -------------------------------
case errCamIdx: msg += "Camera index out of range."; break;
case errNoCams: msg += "no cameras found."; break;
case errRegisterCamObserver: msg += "cant register camobserver."; break;
case errLessCamsThanExpected: msg += "less cameras found, than expected"; break;
// ... add more
}
return msg;
}
bool parseConfig(QList<QPair<QString,QString>>& parsedCameras, seconds& recDuration)
{
qDebug() << "open " << configFile();
QFile file(configFile());
if (!file.open(QIODevice::ReadOnly))
{
qWarning() << "Failed. Could not open config: " + configFile();
return false;
}
QByteArray jsonData = file.readAll();
file.close();
QJsonParseError parseError;
QJsonDocument doc = QJsonDocument::fromJson(jsonData, &parseError);
if (parseError.error != QJsonParseError::NoError)
{
qWarning() << "Error parsing JSON:" << parseError.errorString();
return false;
}
if (!doc.isObject())
{
qWarning() << "JSON content is not an object";
return false;
}
QJsonObject jsonObject = doc.object();
// Parse recordDurationInSeconds
if (!jsonObject.contains("recordDurationInSeconds") || !jsonObject["recordDurationInSeconds"].isDouble())
{
qWarning() << "Missing or invalid recordDurationInSeconds";
return false;
}
recDuration = jsonObject["recordDurationInSeconds"].toInt() * 1s; //convert to s
// Parse outDir
if (!jsonObject.contains("outDir") || !jsonObject["outDir"].isString())
{
qWarning() << "Missing or invalid outDir";
return false;
}
outDir(jsonObject["outDir"].toString()); //set global
// Parse cameras
if (!jsonObject.contains("cameras") || !jsonObject["cameras"].isArray())
{
qWarning() << "Missing or invalid cameras array";
return false;
}
parsedCameras.clear();
QJsonArray camerasArray = jsonObject["cameras"].toArray();
for (const QJsonValue& value : camerasArray)
{
if (!value.isObject())
{
qWarning() << "Invalid camera entry:" << value;
continue;
}
QJsonObject cameraObject = value.toObject();
auto name = cameraObject["name"].toString();
auto ip = cameraObject["ip"].toString();
parsedCameras.append(qMakePair(name, ip));
}
ncam(parsedCameras.size()); //set global
qDebug() << "parsed recDuration:" << recDuration.count();
qDebug() << "parsed outDir:" << outDir();
qDebug() << "threads per cam:" << threadsPerCam();
return true;
}
//general basedir
QString outDir(QString dirname)
{
static QString _outDir;
if( _outDir.isEmpty() )
{
if( dirname.isEmpty() )
_outDir = QCoreApplication::applicationDirPath();
else
_outDir = dirname;
}
return _outDir;
}
// needed to find cams via ip
QString configFile(QString filename)
{
static QString _configFile;
if( _configFile.isEmpty() )
_configFile = filename;
return _configFile.isEmpty() ? utils::getFirstFileInAppDirEndingWith("json") : _configFile;
}
QString getFirstFileInAppDirEndingWith( QString const& suffix )
{
QDir dir(QCoreApplication::applicationDirPath());
QStringList files = dir.entryList(QStringList() << "*."+suffix, QDir::Files);
// QStringList const folders = source.entryList(QDir::NoDot | QDir::NoDotDot | QDir::Dirs);
auto file = files.first();
return files.isEmpty() || suffix.isEmpty() ? QString() : file;
}
// optional - only set cam settings when they changed
QString settingsFile(QString filename)
{
static QString _settingsFile;
if( _settingsFile.isEmpty() )
_settingsFile = filename;
return _settingsFile.isEmpty() ? utils::getFirstFileInAppDirEndingWith("xml") : _settingsFile;
}
} // namespace utils