Stehst du vor der Herausforderung, leistungsstarke native Bildverarbeitung mit einem flexiblen webbasierten Anwendungs-Framework zu kombinieren? Fragst du dich, ob hybride Apps wirklich performant genug sind? Und wie integrierst du Spezialgeräte statt nur Standardhardware? Diese Fragen haben mich fasziniert, und ich habe eine Lösung gefunden, die wiederverwendbar ist.
Bild-Spezialisten: Industrielle Kameras
Die Verwendung von industriellen Kameras hat in verschiedenen Anwendungsgebieten an Bedeutung gewonnen. Diese Kameras sind speziell für industrielle Bildverarbeitungsaufgaben konzipiert. Sie finden unter Anderem Anwendung in Bereichen wie Qualitätskontrolle, Robotik oder Medizintechnik.
Kameras wie die Baumer VLU-02M bieten eine Reihe von Vorteilen, beispielsweise:
- Hohe Bildqualität: Dank hochwertiger Sensoren können detaillierte und präzise Bilder erfasst werden.
- Hohe Bildraten: Mit bis zu 160 fps sind sie ideal für Anwendungen, die schnelle Bewegungen oder Prozesse erfassen müssen.
- Flexible Anpassung: Mit der Möglichkeit, Belichtungszeiten von 0,004 bis 60000 ms einzustellen, können sie an verschiedene Lichtverhältnisse und Anwendungen angepasst werden.
Kamerahersteller wie Baumer stellen in der Regel ein SDK (Software Development Kit) bereit, das die Integration ihrer Kameras in C/C++-Programme ermöglicht. Das ist besonders vorteilhaft für eine schnelle und systemnahe Datenverarbeitung. Dennoch ist eine effektive, leistungsfähige und benutzerfreundliche Anwendungssoftware unerlässlich, um die Kamera zu steuern und ihre Bilder anzuzeigen. Diese Software muss je nach Anwendungszweck, Zielgruppe und Kontext individuell angepasst werden. Moderne und flexible Software-Frameworks für plattformunabhängige Anwendungen verwenden jedoch oft andere Programmiersprachen als C++.
Electron: ein Allrounder-Framework für
plattformunabhängige Apps
Electron ist ein beliebtes Open-Source-Framework, basierend auf Node.js, welches es Entwicklern ermöglicht, plattformübergreifende Desktop-Anwendungen mit Webtechnologien wie HTML, CSS und JavaScript bzw. TypeScript zu erstellen. Das bietet eine Reihe von Vorteilen für die App-Entwicklung:
- Plattformübergreifend: Mit Electron können Entwickler eine einzige Codebasis verwenden, um Anwendungen für verschiedene Betriebssysteme wie Windows oder MacOS zu erstellen, in Verbindung mit Ionics Capacitor ist der Code auch für mobile Apps nutzbar.
- Vertraute Standards: UI-/UX-Designer und Software-Entwickler können ihre bestehenden Webentwicklungsfähigkeiten und -tools nutzen, ohne eine neue Programmiersprache oder Technologie erlernen zu müssen.
- Anpassbare Benutzeroberfläche: Mit Webtechnologien ist es einfacher, moderne und ansprechende Benutzeroberflächen zu erstellen, die sich leicht anpassen und skalieren lassen.
- Große Community und Ressourcen: Zugang zu einer aktiven Community, zahlreichen Bibliotheken und Ressourcen für die Entwicklung von Electron-Apps.
- Schnelle Entwicklung und Prototyping: Dank der schnellen Iteration und des Live-Reload-Features können Entwickler Änderungen in Echtzeit sehen, was die Entwicklung und das Prototyping
beschleunigt. - Integration mit Backend-Services: Electron-Anwendungen können leicht mit verschiedenen Backend-Services und APIs integriert werden, um erweiterte Funktionen und Datenverarbeitung zu
ermöglichen. - Sicherheit: Electron bietet Sicherheitsfunktionen wie Content-Security-Policy, um Cross-Site-ScriptingAngriffe zu verhindern und die Anwendungssicherheit zu verbessern.
Trotz aller Vorteile ist der höhere Ressourcenverbrauch im Vergleich zu nativen Anwendungen eine Herausforderung, speziell in der Bildverarbeitung. Und während Electron zwar Zugriff auf übliche Systemressourcen bietet, ist im Falle einer speziellen Industriekamera natürlich notwendig, außerhalb der bereitgestellten Features eine eigene Erweiterungen zu schaffen, um Steuer- und Bilddaten mit der Hersteller-SDK auszutauschen.
Vorteile der C++-Integration mit Electron
Ziel meines Projekts war es, hier eine Brücke zu schaffen, um die Vorteile zweier Welten zu kombinieren: leistungsfähige native Bildverarbeitung und flexibles Anwendungs-Framework.
- Zugriff auf Hardware-Ressourcen: Durch die native Integration können Sie direkt auf die Funktionen und Eigenschaften der Kamera zugreifen und diese steuern.
- Hochperformante Bildverarbeitung: C++ ermöglicht eine effiziente und schnelle Verarbeitung von Bilddaten, was besonders wichtig für Echtzeitanwendungen ist, um in diesem Falle eine hohe Framerate zu erzielen.
- Skalierbarkeit und Flexibilität: Electron ermöglicht die Entwicklung plattformübergreifender
Desktop-Apps mit Web-Technologien, während C++ Leistung und Effizienz bietet.
Herausforderungen bei Electron+Native-Projekten
Die Entwicklung von Electron-Apps mit nativer Integration bringt einige Herausforderungen mit sich. Im Beispielprojekt konnte ich diese kennen und meistern lernen:
- Nebenläufigkeit: Während die Kameradaten nativ in den Puffer gelesen werden, soll die Anwendung nicht warten bzw. blockieren.
- Komplexität der Konfiguration: Die Einbindung von externen C++-Bibliotheken und SDKs in ein Electron-Projekt kann komplex und zeitaufwändig sein. Fehler sind oft nur mittels Tests einzugrenzen.
- Debugging: Das Debugging von C++-Code in Kombination mit JavaScript kann herausfordernd sein. Um wenigstens die Konsole für Ausgaben nutzen zu können, bietet sich nur ein Zugriff auf die LogFunktion über NAPI an.
- Sandboxing und IPC: Die Trennung von Haupt- und Renderer-Prozess in Electron erfordert den Einsatz von Inter-Process-Communication-Mechanismen (IPC) wie der Context-Bridge, um sicher und effizient Daten zwischen den Prozessen auszutauschen.
Meine Heransgehensweise und Lösung
Erste Test-App mit C++
Vor der Integration in Electron habe ich eine erste, rein native C++-Anwendung, mit OpenGL-Ausgabe gebaut, um die Baumer-GAPI-SDK und die Bildausgabe zu testen. Dies ermöglichte mir, die Grundlagen zu verstehen und die Funktionen der Kamera zu überprüfen. Ich implementierte einen eigenen Thread (std::thread), der sich um das regelmäßige Auslesen des Kamera-Bilds kümmerte. Zudem implementierte ich eine Testbild-Funktion, um die Funktion meiner Datenschnittstellen selbst ohne verbundene Kamera oder bei nicht auffindbaren SDK-Bibliotheken testen und so auch Konfigurationsprobleme eingrenzen zu können.
Konfiguration und Umsetzung als NAPI-Addon
Meine Lösung mit Electron bestand anschließend darin, daraus ein C++-NAPI-Addon zu entwickeln, welches Speicher allokiert, Bilddatenpuffer der Kamera hinein schreibt und bspw. auch die Belichtungszeit steuert. NAPI (Native Application Programming Interface) ist eine node.js-Technologie für den Zugriff auf native APIs und Bibliotheken in Node.js-Modulen.
Damit das C++-NAPI-Addon korrekten Zugriff auf die statischen sowie dynamischen Baumer-SDKBibliotheken sowie C++-Headerfiles hat, war die Konfiguration sorgfältig einzurichten. Electron nutzt für die Kompilierung von Node.js-Modulen node-gyp, meine native/binding.gyp -Datei sieht dazu wie folgt aus (Auszug):
Anschließend konnte ich die tatsächlichen Funktionen in meiner native.cpp implementieren, die ich für Electron bereitstellen möchte. Im Beispiel (Auszug) werden das aktuelle Bild der Kamera sowie die eingestellte Belichtungszeit ausgelesen – die Funktionen dafür werden per NAPI exportiert. Die übergebenen Daten-Objekte (bspw. Napi::Uint8Array ) werden bei Javascript-seitigem Aufruf direkt Übergabe an Electron bereitgestellt, was einen schnellstmöglichen anwendungsseitigen Zugriff bedeutet.
Einbindung in die Electron-App und Context-Bridge für die Renderer-Sandbox
Seitens Electron/Javascript können die exportierten Funktion aufgerufen werden. Ich habe den eigentlichen NAPI-Aufruf in der Hauptroutine (main.js) jedoch wiederum über IPC der (in Electron aus Sicherheitsgründen entkoppelten) Render-Sandbox bereitgestellt. Die Aufrufe und Funktionsrückgaben werden demnach durchgereicht.
Hier meine main.js (Auszug):
In meiner preload.js habe ich die ContextBridge dazu wie folgt vorbereitet:
Renderer-seitiger Aufruf
Die eigentliche Electron-Benutzeroberfläche ist dann in index.html definiert, welche meinen RendererScript einbindet:
Dieser Renderer (Auszug aus meiner renderer.js ) ruft letztlich die Daten ab:
Resümee
Durch die sorgfältige Konfiguration und Umsetzung der IPC-Mechanismen konnte ich eine performante und stabile Lösung für die Live-Ausgabe des Kamerabildes in meiner Electron-App realisieren. Der Mehraufwand
durch den NAPI-Export sowie die IPC-Vermittlung zwischen Haupt- und Renderer-Sandbox wird belohnt durch eine maximal schnelle Darstellung der Bilder.
Insgesamt war die Entwicklung des Projekts mit der Baumer VLU-02M Kamera und Electron eine spannende, aber lohnende Erfahrung. Die Kombination von industrieller Bildverarbeitung, C++- Programmierung und Electron-Entwicklung bietet großes Potenzial für innovative Anwendungen und Lösungen. Der Ansatz lässt sich auch auf andere native Datenquellen und Funktionen anwenden, sei es für effiziente Bild- oder Signalverarbeitung, Einbindung neuer Hardware-Ressourcen, komplexe Algorithmen oder die Analyse großer Datenmengen.
Wir werden künftig die Lösung sicher wieder aufgreifen – für Produkte, die Nutzer lieben.
Über den Autor
Martin
Martin ist ein kreativer und qualitätsbewusster Software-Entwickler mit Schwerpunkt C++ sowie Erfahrung in Anwendungs-Entwicklung, Audioverarbeitung, Java, C#, Web und DevOps. Er hat Forschungs-Background im Bereich Usability & Accessibility und hat als Start-Up-Gründer eine mobile medizinische App an den Markt gebracht. Seine Leidenschaft ist es, an Lösungen zu tüfteln, die Nutzern helfen und Spaß machen.
Häufig gestellte Fragen:
Warum ist die Kombination von industriellen Kameras und Electron-Apps revolutionär?
Die Integration von hochleistungsfähigen industriellen Kameras in Electron-Apps ermöglicht die Nutzung leistungsstarker Bildverarbeitungsfunktionen in plattformübergreifenden Desktop-Anwendungen. Dies eröffnet neue Möglichkeiten für Anwendungen in Bereichen wie Qualitätskontrolle, Robotik und Medizintechnik, indem es die Flexibilität von Webtechnologien mit der Leistungsfähigkeit von Industriekameras vereint.
Welche Vorteile bieten industrielle Kameras wie die Baumer VLU-02M?
Industrielle Kameras wie die Baumer VLU-02M bieten eine hohe Bildqualität, hohe Bildraten und flexible Anpassungsmöglichkeiten. Sie sind speziell für industrielle Bildverarbeitungsaufgaben konzipiert und eignen sich ideal für Anwendungen, die schnelle Bewegungen oder Prozesse erfassen müssen.t
Warum wurde Electron als Framework für die Entwicklung dieser Anwendungen gewählt?
Electron ermöglicht es Entwicklern, plattformübergreifende Desktop-Anwendungen mit Webtechnologien wie HTML, CSS und JavaScript zu erstellen. Dadurch können sie ihre bestehenden Webentwicklungsfähigkeiten nutzen und moderne, ansprechende Benutzeroberflächen erstellen, während sie gleichzeitig auf eine große Community und Ressourcen zugreifen können.
Welche Herausforderungen bringt die Entwicklung von Electron-Apps mit nativer Integration mit sich?
Die Entwicklung von Electron-Apps mit nativer Integration erfordert die Bewältigung von Herausforderungen wie Nebenläufigkeit, Komplexität der Konfiguration, Debugging und die Implementierung von Inter-Process-Communication-Mechanismen (IPC) für die sichere und effiziente Datenkommunikation zwischen Haupt- und Renderer-Prozessen.
Wie wurde die Lösung für die Einbindung von Industriekameras in Electron-Apps umgesetzt?
Die Lösung beinhaltet die Entwicklung eines C++-NAPI-Addons, das den direkten Zugriff auf die Funktionen und Eigenschaften der Kamera ermöglicht. Durch die sorgfältige Konfiguration und Implementierung von IPC-Mechanismen wurde eine performante und stabile Lösung für die Live-Ausgabe des Kamerabildes in der Electron-App realisiert, wodurch eine maximale Bildrate erreicht wird