Rahmenprogramm PMD Kamera

Aus toolbox_interaktion
Wechseln zu: Navigation, Suche

Mit dem Pahmenprogramm der PMD Kamera wurde eine Schnittstelle geschaffen, die es ermöglicht über einen PC mit der Kamera zu kommunizieren. Die erhaltenen Daten werden dann mittels Funktionen (z.B. die Berechnung des mittleren Abstandes) verarbeitet. Die Ergebnisse dieser Funktionen (also die verarbeiteten Daten) können – falls gewünscht - per OSC Protokoll versendet werden. Das OSC Protokoll bietet eine standardisierte Schnittstelle. Deshalb können diese Ergebnisse dann universell verwendet werden. In diesem Rahmenprogramm können neue Funktionen hinzugefügt werden. Diese Funktionen verarbeiten die Informationen der Kamera nach den jeweiligen Bedürfnissen. Bereits realisiert sind eine einfache Maussteuerung, die Regelung der Lautstärke am PC und die schon oben erwähnte Berechnung des mittleren Abstandes.

Das Rahmenprogramm ist in C++ realisiert. Im Folgenden wird beschrieben, wie das Rahmenprogramm Aufgebaut ist, welche Funktionen implementiert wurden und wie es möglich ist weitere Funktionen in das Programm einzubinden.

Kommunikation zwischen PC und Kamera

Um überhaupt eine Verbindung mit der Kamer herstellen zu können, muss die Kamera mit dem beiliegenden Ethernet-Kabel mit dem PC verbunden sein. Außerdem müssen die richtigen Netzwerkeinstellungen, wie in Kapitel 3.1 beschrieben, vorgenommen werden:
Die IP Adressen des PCs und der Kamera müssen im gleichen Subnetzwerk liegen.

Grundprinzip der Kommunikation zwischen PC und Kamera

Bedienung des Rahmenprogramms

Benutzeroberfläche des Rahmenprogramms

Das Rahmenprogramm muss nicht installiert werden, es ist direkt als exe-Datei ausführbar. Dazu müssen allerdings im gleichen Verzeichnis die Dateien „o3d.W32.pcp“ und „pmdaccess2.dll“ vorhanden sein. Nach dem Programmaufruf erscheint eine grafische Benutzeroberfläche. Dort sind die wichtigsten Eingabemöglichkeiten vorhanden und drei Tabs mit den bereits realisierten Funktionen.
Es folgt eine Beschreibung der jeweiligen Bereiche und Eingabemöglichkeiten:

  • 1.) Der Bereich „Verbindung“ enthält ein Feld zur Eingabe der IP-Adresse der Kamera. Bei Klicken auf den Button „Verbinden“ wird versucht eine Verbindung herzustellen. Wenn dies nicht möglich ist (z.B. aufgrund einer falschen IP-Adresse oder einer Firewall) erscheint ein Fehler in der „Statusleiste“ (7.)).Ist eine Verbindung hergestellt, kann diese durch erneutes Klicken auf den gleichen Button (dieser heißt dann „Trennen“) getrennt werden. Nur wenn eine Verbindung hergestellt ist, kann der Datenabruf gestartet werden (siehe 6.)).
  • 2.) Im Bereich „Funktion“ sind die verschiedenen Tabs mit den realisierten Funktionen aufgeführt. Für eine genauere Beschreibung der drei bereits realisierten Funktionen findet siehe Kapitel 4.3.2 – Kapitel 4.3.4.
  • 3.) Alle Funktionen können mit einer „Aktiv“ - CheckBox separat aktiviert oder deaktiviert werden.
  • 4.) Für jede Funktion kann ein „aktiver Bereich“ angegeben werden. Nur in diesem virtuellen Würfel werden Kameradaten ausgewertet. Die x- und y-Richtung wird in Anzahl der Pixel angegeben, die z-Richtung (also die Entfernung zur Kamera) in Meter. Zum Bestätigen der Eingaben wird „Übernehmen“ (5.)) gedrückt. Die Eingaben werden dann auf Gültigkeit überprüft. Für die x- und y-Richtung gilt: Eingabe in ganzen Zahlen von 0 bis 49 bzw. 63 Pixel. Für die z-Richtung gilt: Eingabe in Meter, das Dezimaltrennzeichen ist das Komma: „ , “. Für alle Richtungen muss der „von“ – Wert kleiner oder gleich dem „bis“ – Wert liegen. Wird versucht, eine ungültige Eingabe zu übernehmen, dann wird ein Fehler (per MessageBox) ausgegeben und die „Aktiv“ – Checkbox (siehe 3.)) wird deaktiviert. Die ausführlichere Beschreibung des aktiven Bereichs findet im Kapitel 4.3.1, „Aktiver Bereich“ statt.
  • 5.) Der „Übernehmen“ – Button überprüft die Eingaben für den aktiven Bereich und übernimmt diese bei Gültigkeit. Außerdem wird der Wert der „Aktiv“ – CheckBox übernommen. Der „Übernehmen“ – Button gilt nur für die jeweilige Funktion.
  • 6.) Mit dem „Start“- und „Stop“-Button wird der Datenabruf von der Kamera gestartet und gestoppt. Der Datenabruf ist unabhängig davon, welche Funktionen gerade aktiviert sind. Der „Start“-Button ist nur bedienbar, wenn vorher eine Verbindung mit der Kamera hergestellt wurde (siehe 1.)).
  • 7.) Die „Statusleiste“ gibt mittels eines Farbquadrates und eines kurzen Informationstestes den aktuellen Status wider. Die Farben sind wie bei der Ampel gewählt:
    • grün: OK
    • gelb: Verbindung nicht hergestellt oder Datenabruf gestoppt#
    • rot: Fehler

Aktiver Bereich

x- und y- Koordinaten beim Blick in die Linse

Die von der Kamera aufgezeichneten Entfernungswerte sind unter Umständen nicht immer korrekt. Wenn beispielsweise sehr nahe und sehr entfernte Objekte zugleich im Bild sichtbar sind, dann können viele „Fehlpixel“ auftreten. Genauere Informationen hierzu im Kapitel 5, „Integrationszeit“.
Diese „Fehlpixel“ haben meist sehr geringe Entfernungen zur Kamera und treten auch häufig am Bildrand auf (dies ist allerdings auch vom jeweiligen Hintergrund abhängig). Aus diesem Grund war der erste Ansatz zur Lösung dieses Problems einen „aktiven Bereich“ zu definieren. Nur in diesem Bereich (ein virtueller Würfel im Raum) werden die Daten zur Weiterverarbeitung in den Funktionen verwendet.
Es wäre jetzt möglich, diesen aktiven Bereich einmal global einzugeben, sodass er dann für alle Funktionen gilt. Dies wäre aber von Nachteil, wenn man sich für zukünftige Projekte überlegt, dass verschiedene Funktionen auf verschiedene Bereiche angewendet werden sollen.
Deshalb ist hier eine aufwändigere Realisierung gewählt, nämlich ist für jede Funktion ein eigener aktiver Bereich definierbar. Dadurch können verschiedene Bereiche im Raum verschiedene Aktionen bewirken. Beispielsweise kann der mittlere Abstand der unteren Bildhälfte ausgegeben werden und die Lautstärkeregelung in der oberen Bildhälfte erfolgen. Beide Bildhälften beeinflussen sich theoretisch nicht. In der Praxis gibt es allerdings eine Beeinflussung, da bestimmte Objekte im unteren Bildabschnitt die oben erwähnten „Fehlpixel“ im oberen Bildabschnitt bewirken können. Wie bereits im vorherigen Kapitel unter 5.) erwähnt, erfolgt die Eingabe für die x- und y-Richtung in ganzen Zahlen von 0 bis 49 bzw. 63 Pixel. Für die z-Richtung gilt: Eingabe in Meter, das Dezimaltrennzeichen ist das Komma: „ , “. Folgende Abbildung zeigt die Zählweise der x- und y- Richtung, wenn man in die Linse der Kamera blickt.
Allerdings wird die praktische Anwendung eines „Mehr-Bereichs-Bildes“ noch durch die relativ geringe Auflösung der Kamera erschwert. Da das Bild aus 64 Zeilen und 50 Spalten besteht, führt eine Aufteilung des Bildes zu Bereichen, mit sehr wenigen Entfernungspixel.

Funktion Maussteuerung

Diese Funktion ermöglicht es, den Mauszeiger mit dem eigenen Finger zu steuern. Die Funktion bestimmt das Pixel mit dem geringsten Abstand zur Kamera als Position der Maus. Nun kann durch Bewegen des Fingers der Mauszeiger auf dem Bildschirm bewegt werden. Um mit der Maus einen Klick durchzuführen, muss der ausgestreckte Finger relativ schnell hoch und runter bewegt werden (möglichst mit gleicher Geschwindigkeit). Für einen Doppelklick muss der ausgestreckte Finger dementsprechend zwei Mal auf und ab bewegt werden.
Zusätzlich werden an den eigenen PC OSC-Nachrichten verschickt, die die Mausposition und den Klick anzeigen. Die Nachrichten haben folgende Form:

  /CURSOR/X  [wert]    	-> x-Position des Mauszeigers
  /CURSOR/Y  [wert]    	-> y-Position des Mauszeigers
  /CURSOR/LEFT  	-> Linksklick

[wert] ist eine float-Zahl zwischen 0 und 1 (0 bedeutet ganz links bzw. ganz unten).
Es werden relativ gute Ergebnisse erzielt, wenn die z-Richtung des aktiven Bereichs auf etwa von 0,3 m bis 0,6 m eingestellt wird.
Außerdem sollte die Hintergrundentfernung möglichst gering sein, im Idealfall steht direkt hinter dem Benutzer eine Wand. Das hat mit den bereits erwähnten „Fehlpixeln“ zu tun, genauere Informationen im Kapitel 5, „Integrationszeit“. Die Steuerung des Mauszeigers erfordert ein bisschen Übung, dass das Programm den Klick richtig erkennt. Natürlich ist auch eine fortschrittlichere Implementierung der Finger- und Klickerkennung für weitere Projekte denkbar.

Funktion mittlerer Abstand

Die Funktion „Mittlerer Abstand“ gibt, wie der Name schon verrät, den mittleren Abstand aller Pixel (im aktiven Bereich) zurück. Dieser wird zur Demonstration auf der Oberfläche der Funktion in einem Feld angezeigt. Außerdem wird der mittlere Abstand über OSC Protokoll an den eigenen PC verschickt. Die OSC-Nachricht hat folgende Form:

  /mittlerer Abstand:	[wert]	

[wert] ist wiederum eine float-Zahl, die dem mittleren Abstand in Meter entspricht.

Funktion Laustärke

Mit dieser Funktion wurde die Regelung der PC-Lautstärke anhand der Entfernung der Hand von der Kamera vorgenommen. Aus geringer Entfernung resultiert eine geringe Lautstärke, dementsprechend bei großer Entfernung große Lautstärke. Der Lautstärkebereich wird auf die Werte skaliert, die beim aktiven Bereich in z-Richtung eingegeben werden. Gute Ergebnisse werden z.B. im Bereich von 0 m bis 0,8 m erzielt. Zur Verdeutlichung: Bei dem im Beispiel erwähnten z-Bereich ist die PC-Lautstärke maximal, wenn die Hand 0,8 m vor der Kamera positioniert ist. Das OSC-Protokoll wird in dieser Funktion nicht verwendet.

Anmerkung zu den verschiedenen Windows-Versionen:
Unter WindowsXP funktioniert diese Funktion wie oben beschrieben. Der „Master-Volume“-Regler in der Lautstärkeregelung von Windows bewegt sich wie angegeben. Das heißt, dass beispielsweise beim Abspielen einer Musikdatei die Lautstärke geändert werden kann.
Bei neueren Windows Versionen wird für jedes Programm ein eigener Audio-Stream generiert. Damit ist das setzen des „Master-Volume“-Reglers nicht mehr möglich. Stattdessen wird ein Regler für das Rahmenprogramm generiert und dieser verschoben. Die Lautstärkeänderung beim Abspielen einer Musikdatei ist dann nicht zu hören. Hier könnte die Funktion angepasst werden, um beispielsweise die Lautstärke des Widergabeprogramms (z.B. Windows Media Player oder Winamp) direkt zu beeinflussen.

Programmtechnische Implementierung

Das Hauptprogramm wurde mit dem Microsoft Visual Studio 2008 bzw. Visual Studio 2008 Express unter C/C++ .NET programmiert. Es wird eine Windows-Forms Anwendung als Projekt verwendet. Dadurch stehen grafische Bedienelemente zur Verfügung.
Es wird deutlich empfohlen, die bereits erstellte Projektumgebung in Visual Studio zu übernehmen und das Programm anzupassen. Es ist relativ aufwändig, alle Eigenschaften und Abhängigkeiten so in eine Windows-Forms Anwendung zu übernehmen, dass das OSC Protokoll und die Kamerakommunikation funktionieren.
Um dennoch mit dem Visual Studio ein vollständig neues Projekt zu erzeugen, welches mit der Kamera kommunizieren und das OSC Protokoll verwenden kann, müssen mindestens folgende Eigenschaften gesetzt werden:
LINKER:
Zusätzliche Abhängigkeiten: pmdaccess2.lib; ws2_32.lib; winmm.lib
Zusätzliche Bibliotheksverzeichnisse: .\SDK\bin
C++:
Zusätzliche Includeverzeichnisse: .\; .\CAM; .\OSC\osc; .\OSC; .\SDK\include
Diese Verzeichnisangaben beziehen sich darauf, wenn im Projektverzeichnis von Visual Studio folgende Ordner existieren:

  • „CAM“: enthält Quelltext und Header zur Klasse „cam“, siehe nächstes Kapitel
  • „OSC“: enthält die nötigen Quelltexte zur OSC Implementierung aus dem „oscpack“, siehe Kapitel 4.4.2, „OSC“
  • „SDK“: enthält die von PMD gelieferten Quelltexte des SDKs , siehe nächstes Kapitel

Natürlich müssen die nötigen Ordner und Dateien auch zum Projekt hinzugefügt und die Header-Dateien inkludiert werden. (Sinnvollerweise in stdafx.h).
Außerdem muss in allen Quelltexten die Option „Common Language Runtime-Unterstützung (/clr)“ gesetzt werden. Mit der Option /clr:pure ist das Projekt nicht kompilierbar. Im Ausführungsverzeichnis des Programms müssen – wie bereits im Kapitel 4.3 erwähnt - die Dateien „o3d.W32.pcp“ und „pmdaccess2.dll“ vorhanden sein.

Klasse "cam"

Die Firma PMD stellt zur Kamera einen SDK zur Verfügung, welcher Bibliotheken und Funktionen bereitstellt, um die Kamera anzusprechen, zu konfigurieren und Daten abzurufen. Auf der Basis dieser Funktionen wurde die Klasse „cam“ erstellt. Eine genaue Beschreibung des SDK – und damit auch für die Methoden von „cam“ – befindet sich im „Programming Manual For 3D time-of-flight cameras“. Außerdem befinden sich in der Datei „cam.h“ ausführliche Kommentare zur Funktion und Verwendung jeder Methode.
Ein Objekt der Klasse „cam“ verwaltet die Kommunikation mit der Kamera und mittles einfach bedienbarer Methoden kann auf alle wichtigen Funktionen der Kamera zugegriffen werden.
Im Folgenden sind die wichtigsten Methoden kurz vorgestellt:

Init()
Init initialisiert die Verbindung mit der Kamera. Übergabeparameter sind die IP-Adresse der Kamera, das Source Plugin, das Processing Plugin und der Processing String. Alle diese Werte sind bereits vorbelegt, sodass einfach Init(IPAdresse) aufgerufen werden kann. IPAdresse ist vom Typ char*. Der Rückgabewert ist PMD_OK bei erfolgreicher Verbindung.

Update()
Update aktualisiert das Bild. Jetzt kann mit GetDistances ein Array von float-Werten der Entfernung jedes Pixels geholt werden. Rückgabewert: PMD_OK bei Erfolg.

GetDistances()
Diese Funktion schreibt die jeweiligen Werte in ein Array, welches als Übergabeparameter angegeben wird. Dieses Array muss groß genug sein, also für jedes Pixel ein Element. Um das sicherzustellen gibt es einen weiteren Übergabeparameter, der die Größe des Arrays angibt. Rückgabewert: PMD_OK bei Erfolg.
Anmerkung: Diese Funktion bezieht sich so lange aufs gleiche Bild, bis Update() ausgeführt wird.

Close()
Close schließt die Kameraverbindung. Rückgabewert: PMD_OK bei Erfolg.

Diese vier Funktionen genügen bereits, um eine Kameraverbindung herzustellen, periodisch Abstandswerte abzurufen und die Verbindung wieder zu schließen.

OSC - Open Sound Control

Beispielquelltext OSC Nachricht verschicken

Damit die Kamera möglichst universell eingesetzt werden kann, mussten wir uns für ein Kommunikationsprotokoll entscheiden, mit dem viele Anwendungen arbeiten und mit dem die Weiterverarbeitung der Kamerainformation einfach möglich ist. Dadurch haben wir uns für das OSC Protokoll entschieden, weil dieses Protokoll in der Bildverarbeitung mehrfach Anwendung findet, und somit die Kamera mit mehreren Anwendungen kommunizieren kann.

„Open Sound Control ist ein nachrichtenbasiertes Kommunikationsprotokoll, welches hauptsächlich für die Echtzeitverarbeitung von Sound über Netze und Multimedia-Installationen verwendet wird. (…) OSC ist unabhängig vom Transportprotokoll, wobei in der Regel jedoch UDP verwendet wird. Je nach Anforderung ist es aber auch möglich, OSC etwa über TCP oder eine serielle Schnittstelle zu transportieren. (…) Nachrichten werden in OSC auf denkbar einfache Art übermittelt. Ein OSC-Paket besteht aus seinen Daten und einem Byte, welcher die Länge der Daten angibt.“ (http://de.wikipedia.org/wiki/Open_Sound_Control)

In unserem Rahmenprogramm haben wir eine vorgefertigte Realisierung zum verschicken von OSC Nachrichten verwendet, das so genannte „oscpack“ in der Version 1.0.2. oscpack wird auf der Seite http://www.audiomulch.com/~rossb/code/oscpack/ zum Download bereitgestellt.

Aufbau und Ablauf des Rahmenprogramms

Schematische Darstellung des Programms

Das Rahmenprogramm benutzt die oben beschriebene Klasse „cam“ und das „oscpack“ um die Kommunikation mit der Kamera und das Verschicken von OSC Nachrichten bereitzustellen. Dabei greift „cam“ auf den SDK von PMD zurück. Außerdem ruft das Programm die implementierten Funktionen auf. Damit ergibt sich folgende schematische Darstellung.
Im Folgenden wird eine vereinfachte Variante des Programmablaufs beschrieben. Vor allem das Funktionsprinzip des Programms soll dadurch deutlich werden.

Nach Programmstart wird die Benutzeroberfläche angezeigt. Wird dann auf den „Verbinden“-Button geklickt, wird die IP-Adresse aus dem Textfeld gelesen und versucht eine Verbindung herzustellen. Dazu wird die Methode „Init()“ der Klasse „cam“ verwendet. Darauf hin wird geprüft ob eine Verbindung hergestellt werden kann, wenn nicht wird die Fehlermeldung auf der Statusleiste ausgegeben.
Auf den einzelnen Tabs der Funktionen befinden sich „Übernehmen“-Buttons, diese prüfen die Eingaben beim aktiven Bereich. Wenn die Eingaben korrekt sind, werden sie in static-Variablen gespeichert. Der Wert der jeweiligen CheckBox wird ebenfalls gespeichert. Dieser Wert wird ausgelesen um zu entscheiden, ob die Funktion ausgeführt wird.

Die „Start“- und „Stop“-Buttons dienen dazu, einen Timer zu starten. Dieser Timer läuft alle 100 ms ab, was dazu führt, dass 10 fps von der Kamera gelesen werden. Größere fps Werte sind wenig sinnvoll, da eine Testmessung ergeben hat, dass unter guten Bedingungen maximal 15 fps von der Kamera zu holen sind.

Wenn der Timer abgelaufen ist, wird eine Aktualisierung des Kamerabildes mit der „cam“-Methode „Update()“ durchgeführt. Danach wird geprüft ob die gespeicherten Werte der CheckBoxen der jeweiligen Funktionen aktiv sind. Genau diese Funktionen werden dann seriell ausgeführt. Danach wird der Timer neu gestartet. Das heißt, dass hier ein Polling stattfindet. Der Folgende Ablaufplan zeigt die prinzipielle Funktionsweise.[Ablaufplan]

Zählrichtung des Index im eindimensionalen float-Array

Den einzelnen Funktionen werden die Werte des aktiven Bereichs für x-, y- und z-Richtung übergeben. Außerdem wird beim Aufruf ein Zeiger auf das „cam“ Objekt übergeben, mittels dieses Zeigers können dann die Methoden der „cam“ Klasse aufgerufen werden. Beispielsweise kann ein Abstandsarray von der Kamera mit GetDistances() angefordert werden. Mit diesem Befehl wird ein eindimensionales float-Array abgerufen, welches die Abstandswerte für jeden Pixel enthält.

Um dieses Array jetzt komfortabel weiterverarbeiten zu können, haben wir die Funktion „aktiv_Bereich“ geschrieben. Dieser Funktion werden das erhaltene Array und die Parameter des aktiven Bereichs übergeben. Dann setzt diese Funktion alle Werte außerhalb des angegebenen aktiven Bereichs auf -1.

Das erhaltene Array ist eindimensional. Die folgenden Abbildungen machen die Zählweise der Indizes deutlich. Beim Blick auf die Linse beginnt das Array rechts oben beim Index 0 (blaues Kreuz). Der grüne Pfeil verdeutlicht die Zählrichtung.
Um die x- und y- Koordinaten des Bildes aus dem erhaltenen eindimensionalen Array zu erhalten, kann man folgende zwei Zeilen verwenden (C-Code):

  x = -i/64 +49;	
  y = -i%64 +63;

Dabei ist i der Index des eindimensionalen float-Arrays. Damit ergibt sich Koordinatensystem wie bereits in Abbildung 15 im Kapitel 4.3.1 dargestellt.

Hinzufügen neuer Funktionen

Das folgende Kapitel stellt eine art „HowTo“ dar und beschreibt, wie man neue Funktionen auf einfache Art zum bestehenden Programm hinzufügen kann. Als Beispiel dient eine vereinfachte Variante der Maussteuerung.

Schritt 1: Neue Registerkarte hinzufügen
Um eine neue Funktion in das Hauptprogramm einzufügen, muss man zuerst eine neue Registerkarte (Tab) auf der Grafikoberfläche hinzufügen. Hierbei ist zu beachten dass man mindesten eine Aktiv-CheckBox zur Aktivierung der Funktion und einen „Übernehmen“ Button in der Registerkarte realisiert. Falls man zusätzliche Parameter an die Kamera übergeben will oder den aktiven Bereich verwenden möchte, muss man diese Steuerelemente vorsehen. Ebenfalls wichtig ist, den Steuerelementen deutliche Namen zu vergeben. In den folgenden Quelltextbeispielen heißt der Übernehmen-Button „button_Maus_set“ und die Aktiv-CheckBox „checkBox_Maus_aktiv“.[Registerkarte auf Grafikoberfläche hinzufügen]

Schritt 2: Neue static Variablen definieren und deklarieren

Ausschnitt Quelltext des Hauptprogramms

Hier muss im Kopf des Hauptprogramms mindestens ein aktiv-Flag für diese Funktion als static deklariert und definiert werden. Außerdem werden alle Eingaben hier gespeichert, die der Funktion von der Programmoberfläche übergeben werden sollen. Die Eingaben werden vorher auf Gültigkeit geprüft (siehe nächster Schritt).

Wichtig ist, dass bei Programmstart alle static Variablen und ihre zugehörigen Steuerelemente den gleichen Wert besitzen. (z.B. ist die aktiv CheckBox und das aktiv-Flag bei Programmstart deaktiviert)



Schritt 3: Quelltext für „Übernehmen“ – Button hinzufügen

Quelltext für den Übernehmen-Button

Als nächstes wird der Quelltext für den Klick auf den „Übernehmen“ – Button geschrieben.
Der „Übernehmen“ – Button speichert den Wert der CheckBox im aktiv-Flag. Werden weitere Steuerelemente, z.B. TextBoxen, zur Eingabe verwendet und static-Variablen gesetzt, dann ist eine Fehlerbehandlung wichtig. Denn nur gültige Eingaben dürfen in die static-Variablen gespeichert werden.
Das heißt beispielsweise, dass für den aktiven Bereich nur Pixel zwischen 0 und 49 bzw. 63 eingegeben werden dürfen. Die Eingabe von Buchstaben oder nicht-ganzen Zahlen muss verhindert werden. Dazu wird am Besten eine Bildschirmmeldung (MessageBox) ausgegeben und das aktiv-Flag und die aktiv-CheckBox zurückgesetzt. Es darf nur ein kompletter Satz richtiger Werte gespeichert werden.

Zur Verdeutlichung am Beispiel der Maussteuerung und des aktiven Bereichs sollte man folgendes NICHT tun:

  • Prüfen ‚von’-Textfeld, von-Variable beschreiben
  • Prüfen ‚bis’-Textfeld, bis-Variable beschreiben

Denn wenn der ‚von’ Wert gültig ist und der ‚bis’ Wert nicht, dann steht in den static-Variablen:

  • von: neuer Wert
  • bis: alter Wert

Dies kann Probleme in den Funktionen verursachen, da diese Werte on-the-fly aktualisiert werden. Sobald der Timer abläuft wird die Funktion aufgerufen und die Parameter aus den static Variablen übergeben.

Besser ist, wenn man alles temporär speichert. Danach sollte man alle Werte prüfen. Wenn alle Bedingungen in Ordnung sind, dann kann man den ganzen Satz neuer Werte in die static-Variablen schreiben.

Schritt 4: Änderung im Timer

Quelltextausschnitt für den Timer

Wenn der Timer abgelaufen ist, wird die Funktion, je nachdem ob das static aktiv-Flag gesetzt ist oder nicht, aufgerufen. Hier werden auch die static Variablen an die Funktion übergeben.
Im Quelltext des Timers folgende Änderungen durchzuführen.
In der ersten if-Abfrage werden das Errorflag und das static aktiv-Flag ausgewertet. Die jeweilige Funktion wird nur aufgerufen, wenn das aktiv-Flag wahr ist. Das Error-Flag wird durchgegeben und gesetzt falls ein Fehler aufgetreten ist. Die folgenden Funktionen werden dann nicht mehr ausgeführt. Dies kann man aber je nach Wunsch abändern. Außerdem wird der Rückgabewert der Funktionen überprüft, falls das gewünscht wird. Bei einem Fehler kann das Error-Flag gesetzt werden und eine deutliche Bezeichnung des Fehlers auf der Statusleiste ausgegeben werden.
Sollte die Funktion größere Datenmengen zurückliefern, z.B. einen Statustext, muss hierfür ein Zeiger übergeben werden, dessen Ziel in der Funktion dann beschrieben wird.

Schritt 5: Der Funktionsheader

Inhalt von Maussteuerung

Nun zur Funktion selbst. Sie besteht aus einem Header und der Implementierung. Der Header enthält die Funktionsdeklaration und trägt den Namen der Funktion, also für die Maussteuerung: „Maussteuerung.h“
Eine Funktion, die auf die Kamera zugreift braucht mindestens einen Zeiger auf das Objekt der „cam“-Klasse (Typ: cam*) als Übergabeparameter. Außerdem werden weitere static Variablen aus dem Hauptprogramm übergeben, z.B. zur Realisierung des aktiven Bereichs. Der Funktionsaufruf im Timer ist in Schritt 4 beschrieben. Natürlich muss der Funktionsaufruf im Timer und die Funktionsdeklaration im Header der Funktion übereinstimmen. Der Header wird zum Projekt hinzugefügt und in stdafx.h eingetragen.

Alle in der Funktion benötigten Header können ebenfalls in stdafx.h eingetragen werden. Auszug aus stdafx.jpg

Schritt 6: Funktionsimplementierung
Die Implementierung trägt den gleichen Namen wie die Funktion (und der Header), z.B. Maussteuerung.cpp.

Auszug aus Maussteuerung.jpg
Auch die cpp-Datei muss zum Projekt hinzugefügt werden. Sollte in den Funktionen ein „Gedächtnis“ nötig sein, dann sollten static-Variablen verwendet werden.

Weblinks

PMD-Kamera
Quelltext des Rahmenprogramms