Erstellen des Konnektors

Vision Connector Benutzerhandbuch

Portfolio
Industrial AI
Product
Vision Connector
Software version
1.2.0
Language
de-DE (translated by machine)

Gerüst

Navigieren Sie zum Stammverzeichnis des VCA-Treiber-Repositorys. Erstellen Sie das Skelett des neuen Kamera-Connectors. Verwenden Sie das Gerüstskript:

. /scaffolding.sh NumbersWithFileLogger

Nach dem Ausführen des Skripts CMakeLists.txt die Stammdateien, und CMakePresets.json sollten mit der neuen Konfiguration aktualisiert werden. Der Ordner ./drivers/numberswithfilelogger sollte mit folgender Struktur erstellt werden:

Treiber/

    numberswithfilelogger/ - Übergeordneter Ordner des neuen Kamera-Connectors

        include/ - Kopieren Sie die vom Kamerahersteller bereitgestellten C++-Header-Dateien hierher.

            Platzieren Sie 3rd-Party-Include-Dateien here.txt

        lib/ - Kopieren Sie die vom Kamerahersteller bereitgestellten Bibliotheksdateien hierher

            Platzieren Sie 3rd-Party-Bibliotheken here.txt

        Src/

            NumbersWithFileLoggerApi.cpp

            NumbersWithFileLoggerApi.h - Enthält die verfügbar gemachten Funktionen, die von VCA verwendet werden

            NumbersWithFileLoggerCamera.cpp - Enthält die Hauptlogik für die Kamera

            ZahlenMitDateiLoggerKamera.h

            NumbersWithFileLoggerConnector.cpp - Enthält die Hauptlogik für die Kameraerkennung und Kameraerstellung

            NumbersWithFileLoggerConnector.h

            NumbersWithFileLoggerPluginLogger.h - Enthält diese Kameraanschlüsse, spezifische Protokollierungsmakros und die Protokollierungsinstanz

    Tests/

        CMakeLists.txt - CMakeLists.txt Datei mit der Testkonfiguration

        testMain.cpp - Einstiegspunkt für die gtest-basierten Tests

    build.sh - Build-Skript zum Erstellen und Installieren der Release-Version dieses Kamera-Connectors

    CMakeLists.txt - Haupt CMakeLists.txt Datei des Kameraanschlusses

Vorbereiten der 3rd-Party-Abhängigkeiten

In diesem Schritt kopieren Sie alle vom Kamerahersteller bereitgestellten Header-Dateien in den Ordner "include" und die Bibliotheksdatei in den Ordner "lib". Die Header-Dateien werden automatisch eingebunden, aber die Kamera-Connector-Datei muss CMakeLists.txt manuell geändert werden, um die erforderlichen 3rd-Party-Bibliotheken zu verknüpfen.

In unserem Beispiel verwenden Sie diese beiden Ordner nicht. Die CMakeLists.txt Datei muss aktualisiert werden, damit der Kamera-Connector die OpenCV verwenden kann. Fügen Sie die folgenden Zeilen hinzu:

```

find_package(OpenCV ERFORDERLICH)

target_link_libraries(${LIBRARY_NAME} PRIVAT opencv_core opencv_videoio ${LIBS})

```

Die geänderte CMakeLists.txt Datei sieht in den betroffenen Bereichen wie folgt aus:

```

...

include_directories(${SDK_INCLUDE_DIR})

link_directories(${SDK_LIBRARY_DIR})

include_directories(${PROJECT_SOURCE_DIR}/einschließen)

link_directories(${PROJECT_SOURCE_DIR}/lib)

find_package(OpenCV ERFORDERLICH)

if(TESTEN VON STREQUAL "EIN")

   add_subdirectory(Prüfungen)

endif()

...

```

```

...

add_library(${LIBRARY_NAME} GETEILT ${PROJECT_SOURCES})

target_link_libraries(${LIBRARY_NAME} PRIVAT opencv_core opencv_videoio ${LIBS})

target_compile_options(${LIBRARY_NAME} PRIVAT -fno-gnu-einzigartig)

install(ZIELE ${LIBRARY_NAME} ZIEL ${LIBRARY_NAME})

...

```

Weitere Informationen zur Strukturierung der CMakeLists.txt Dateien finden Sie in den Beispielen.

Konfigurieren und Erstellen eines neuen benutzerdefinierten Kamera-Connectors

Nach dem Gerüstbau stehen neue Konfigurations- und Buildvoreinstellungen zur Verfügung. Um mit der Entwicklung des Kamera-Connectors fortzufahren, müssen Sie ein neues Projekt konfigurieren. Dies kann über die IDE oder über das Terminal erfolgen, indem Sie einen der folgenden Befehle ausführen:

```

cmake --preset numberswithfilelogger-debug

```

Oder:

```

cmake --preset numberswithfilelogger-release

```

Je nachdem, welcher Buildtyp erforderlich ist.

Obwohl der aktuelle NumbersWithFileLogger-Kameraconnector keine kamerabezogene Implementierung enthält, können Sie das Projekt dank des Gerüsts dennoch erstellen. Auch hier können Sie dies über die IDE oder über das Terminal tun, indem Sie einen der folgenden Befehle ausführen:

```

cmake --build --preset numberswithfilelogger-debug-build --target numberswithfilelogger

```

Oder:

```

cmake --build --preset numberswithfilelogger-release-build --target numberswithfilelogger

```

abhängig von der zuvor gewählten Konfiguration. Danach sollte die libnumberswithfilelogger.so Datei im Ausgabeverzeichnis generiert werden.

Implementieren der NumbersWithFileLoggerConnector-Klasse

Die CameraConnector-Klasse ist für das Ermitteln und Erstellen von Kameras verantwortlich. Die von NumbersWithFileLoggerConnector abgeleitete Klasse muss die kameraspezifische Logik zum Ermitteln und Erstellen enthalten.

In diesem Beispiel ändern Sie die discover-Methode so, dass sie eine Liste von Farben als eindeutige IDs für die möglichen Kameras zurückgibt.

Geänderter Code:

```

std::vector<std::string> NumbersWithFileLoggerConnector::d iscover() const

{

return {"rot", "grün", "blau", "schwarz"};

}

```

Nach dem Laden des endgültigen Kameraanschlusses in VCA wird diese Liste in der Benutzeroberfläche angezeigt:

Implementieren der NumbersWithFileLoggerCamera-Klasse

Im Vergleich zum CameraConnector ist die Camera-Klasse aufgrund ihrer Gesamtfunktionsweise komplexer. Definieren Sie daher zunächst eine Membervariable, damit Sie den Status der Kamera verfolgen können.

NumbersWithFileLoggerCamera.h aktualisiert:

```

privat:

   int m_width = 1920;

   int m_height = 1080;

   cv::Skalare m_backgroundColor;

   doppelter m_fontScale = 1,0;

   int m_thickness = 2;

   int m_baseline = 0;

   int m_fps = 1;

```

Mit diesen Variablen definieren Sie einen Standardzustand für die Kameras und können das Verhalten der Kameras zur Laufzeit ändern.

Aktualisieren Sie die Datei NumbersWithFileLoggerCamera.cpp Methode für Methode.

Aktualisieren Sie den Konstruktor NumbersWithFileLoggerCamera.cpp, um die Hintergrundfarbe festzulegen, die durch die eindeutige ID definiert wird:

```

NumbersWithFileLoggerCamera::NumbersWithFileLoggerCamera(const std::string& uniqueId) : Kamera(uniqueId)

{

   if (uniqueId == "rot")

    {

       m_backgroundColor = cv::Scalar(0, 0, 255);

    }

   else if (uniqueId == "grün")

    {

       m_backgroundColor = cv::Skalar(0, 255, 0);

    }

   else if (uniqueId == "blau")

    {

       m_backgroundColor = cv::Skalar(255, 0, 0);

    }

   oder

    {

       m_backgroundColor = cv::Skalar(0, 0, 0);

    }

}

```

Jetzt verfügen Sie über alle Variablensätze, die Sie zum Generieren und Erfassen von Bildern benötigen. Die aktualisierte acquireImage-Methode sieht wie folgt aus:

```

std::shared_ptr<VCA::SDK::v1::Image> NumbersWithFileLoggerCamera::acquireImage()

{

   increaseImageSequenceCounter();

   int fontFace = cv::FONT_HERSHEY_SIMPLEX;

   cv::Mat rawImage(m_height, m_width, CV_8UC3, m_backgroundColor);

   std::Zeichenfolgenzahl = std::to_string(imageSequenceCounter());

   cv::Size textSize = cv::getTextSize(Anzahl, Schriftart, m_fontScale, m_thickness, &m_baseline);

   int x = (rawImage.cols - textSize.width) / 2;

   int y = (rawImage.rows + textSize.height) / 2;

   cv::p utText(rawImage, number, cv::P oint(x, y), fontFace, m_fontScale, cv::Scalar(255, 255, 255), m_thickness);

   const auto totalElementCount = rawImage.total() * rawImage.elemSize();

   auto image = std::make_shared<SDK::v1::Image>();

   auto imageData =

       std::make_unique<SDK::v1::ImageData> (reinterpret_cast<uint8_t*>(rawImage.data), totalElementCount);

   const VCA::SDK::v1::ImageDetail imageDetail(

       VCA::SDK::v1::CameraInformation(cameraUniqueId(), "1"),

       VCA::SDK::v1::ImageInformation(imageSequenceCounter(), rawImage.cols, rawImage.rows, "BGR8"),

       VCA::SDK::v1::P TPInformation("Deaktiviert", "0"));

   image->addImagePart(std::move(imageData), imageDetail);

   std::this_thread::sleep_for(std::chrono::millisekunden(1000 / m_fps));

   Bild zurückgeben;

}

```

Mit Ausnahme von '''increaseImageSequenceCounter()''', mit dem Sie den angezeigten Zähler bis '''auto image = std::make_shared<SDK::v1::Image>();''' aktualisieren, ist alles OpenCV-spezifischer Code. Dieser Teil des Codes variiert von Kameraanbieter-API zu Kameraanbieter.

Der wichtige Teil besteht darin , '''ImageData''' und '''ImageDetail''' Objekte zu erstellen und sie dem '''Image''' als Bildteil hinzuzufügen.

Der '''ImageData''' Konstruktor verwendet zwei Parameter, einer ist der eigentliche Bildpuffer und der zweite ist die Größe des Puffers. Im '''ImageData''' Konstruktor wird der Puffer kopiert und der kopierte Puffer intern verwaltet.

Sie benötigen auch ein '''ImageDetail''' Objekt, um den Bildteil zum '''Image''' hinzuzufügen. Ein '''ImageDetail''' Objekt enthält die entscheidenden Informationen über den gegebenen Bildrahmen. Zu diesen Informationen gehören '''CameraInformation''', '''ImageInformation''' und '''PTPInformation'''.

Die '''CameraInformation''' enthält die eindeutige Kamera-ID und die Stream-ID.

Die '''ImageInformation''' enthält die Frame-Anzahl, die Breite und Höhe des Frames sowie das Pixelformat. Obwohl nicht jede Kamera oder jeder Anwendungsfall das Precision Time Protocol unterstützt, ist es notwendig, die '''PTPInformation''' für das '''ImageDetail''' Objekt bereitzustellen. In diesem Beispiel wird PTP nicht verwendet, daher wird der Status "Disabled" mit dem Wert 0 verwendet.

Da Sie sowohl '''ImageData''' als auch '''ImageDetail''' Objekte haben, können Sie sie dem '''Image''' hinzufügen und es zurückgeben, wenn es erfolgreich abgerufen wurde.

Mit der aktuellen Implementierung kann die NumbersWithFileLoggerCamera jetzt Bilder zurückgeben, jedoch nur mit der gleichen Standardkonfiguration. Sie müssen die Methoden '''getConfig''' und '''setConfig''' ändern, wenn Sie die Kamera und die aufgenommenen Bilder ändern möchten.

Die '''getConfig'''- Methode muss die Liste der von der Kamera unterstützten Parameter zurückgeben, wie z.B. FPS, Breite, Höhe usw. Die Parameterliste variiert von Kamera zu Kamera, auch für die gleiche Marke. Mit getConfig kann das VCA-UI die verfügbaren Konfigurationsoptionen der Kamera dynamisch anzeigen.

Der Befehl '''setConfig''' muss die Konfigurationsänderungen verarbeiten und eine Liste der geänderten Konfigurationseinträge zurückgeben, in unserem Fall Variablen und deren Änderungsstatus.

Die Implementierung von '''getConfig''' und '''setConfig''' ist wie folgt:

```

SDK::v1::CameraParameters NumbersWithFileLoggerCamera::getConfig()

{

   SDK::v1::CameraParameters cameraParameters;

   SDK::v1::KameraParameter widthCameraParameter;

   widthCameraParameter.setName("Breite");

   widthCameraParameter.setValue(std::to_string(m_width));

   widthCameraParameter.setType("int");

   widthCameraParameter.setDescription("Breite");

   widthCameraParameter.setReadOnly(falsch);

   SDK::v1::CameraParameter heightCameraParameter;

   heightCameraParameter.setName("Höhe");

    heightCameraParameter.setValue(std::to_string(m_height));

   heightCameraParameter.setType("int");

   heightCameraParameter.setDescription("Höhe");

   heightCameraParameter.setReadOnly(falsch);

   SDK::v1::CameraParameter fontScaleCameraParameter;

   fontScaleCameraParameter.setName("Schriftmaßstab");

   fontScaleCameraParameter.setValue(std::to_string(m_fontScale));

   fontScaleCameraParameter.setType("doppelt");

   fontScaleCameraParameter.setDescription("Schriftmaßstab");

   fontScaleCameraParameter.setReadOnly(falsch);

   SDK::v1::CameraParameter thicknessCameraParameter;

   thicknessCameraParameter.setName("Dicke");

   thicknessCameraParameter.setValue(std::to_string(m_thickness));

   thicknessCameraParameter.setType("int");

   thicknessCameraParameter.setDescription("Dicke");

   thicknessCameraParameter.setReadOnly(falsch);

   SDK::v1::CameraParameter fpsCameraParameter;

   fpsCameraParameter.setName("FPS");

   fpsCameraParameter.setValue(std::to_string(m_fps));

   fpsCameraParameter.setType("int");

   fpsCameraParameter.setDescription("FPS");

   fpsCameraParameter.setMin("1");

   fpsCameraParameter.setMax("1000");

   fpsCameraParameter.setReadOnly(falsch);

   cameraParameters.push_back(widthCameraParameter);

   cameraParameters.push_back(heightCameraParameter);

   cameraParameters.push_back(fontScaleCameraParameter);

   cameraParameters.push_back(thicknessCameraParameter);

   cameraParameters.push_back(fpsCameraParameter);

   cameraParameters zurückgeben;

}

```

```

SDK::v1::CameraParameterStatuses NumbersWithFileLoggerCamera::setConfig(const SDK::v1::CameraParameters& parametersToChange){    SDK::v1::CameraParameterStatuses parameterStatuses;    for (const auto& parameterToChange : parametersToChange)    {        const auto parameterName = parameterToChange.name();        const auto parameterValue = parameterToChange.value();        if (parameterName == "Breite")        {            m_width = std::stoi(parameterValue);       } else if (parameterName == "Höhe")        {            m_height = std::stoi(parameterValue);       } else if (parameterName == "Schriftmaßstab")        {            m_fontScale = std::stod(parameterValue);       } else if (parameterName == "Dicke")        {            m_thickness = std::stoi(parameterValue);       } else if (parameterName == "FPS")        {            m_fps = std::stoi(parameterValue);       } parameterStatuses.push_back(SDK::v1::CameraParameterStatus (parameterName, parameterValue, SDK::v1::CameraParameterStatus::        Status::OK));   } return parameterStatuses;} '''

Jetzt können Sie die Kamerakonfiguration über die VCA-Benutzeroberfläche ändern, während Sie die Kamera verwenden.

Hinzufügen einer internen Protokollierung

Um einen internen Dateilogger hinzuzufügen, müssen Sie eine neue '''logToFile''' Funktion in '''NumbersWithFileLoggerPluginLogger.h''' deklarieren und in '''NumbersWithFileLoggerPluginLogger.cpp''' definieren.

Fügen Sie Folgendes zu '''NumbersWithFileLoggerPluginLogger.h''' hinzu

```

void logToFile(VCA::SDK::v1::P luginLogLevel level, const std::string& msg, const std::string& file, int line);

```

und zu den '''NumbersWithFileLoggerPluginLogger.cpp'''

```

std::mutex file_mutex;

void logToFile([[maybe_unused]] VCA::SDK::v1::P luginLogLevel level, const std::string& msg, [[maybe_unused]] const std::string& file, [[maybe_unused]] int Zeile)

{

   versuchen

    {

       const std::lock_guard<std::mutex> Sperre(file_mutex);

       const auto filePath = "/logs/numbers_with_file_logger.txt";

       fs::create_directories(fs::p ath(filePath).parent_path());

       std::ofstream file(filePath, std::ios::app);

       if (!datei)

        {

           throw std::ios_base::failure("Fehler beim Öffnen der Protokolldatei");

        }

       Datei << msg << std::endl;

    }

   catch (const std::exception& ex)

    {

       std::cout << "Fehler: " << ex.what() << std::endl;

    }

}

```

Registrieren Sie diese Funktion beim Logger. Verwenden Sie den Konstruktor der Klasse ''''NumbersWithFileLoggerConnector'''. Da der Connector nur einmal von VCA selbst instanziiert wird, ist es sicher, diesen Konstruktor zum Initialisieren von Ressourcen oder, wie in unserem Fall, zum Registrieren der internen Protokollierung zu verwenden.

Aktualisieren des Konstruktors NumbersWithFileLoggerConnector:

```

#include "NumbersWithFileLoggerPluginLogger.h"

...

NumbersWithFileLoggerConnector::NumbersWithFileLoggerConnector()

{

   logger.registerCallback("NumbersWithFileLogger Logger", logToFile);

   LOG_NUMBERSWITHFILELOGGER_PLUGIN_INFO("Kameraanschluss initialisiert");

}

```