Grafik Werbung
Grafik Werbung
Grafik Werbung

Programmierung in einer Messsoftware - Beispiel für GOM ATOS

Im folgenden wird die Programmierung innerhalb einer Messsoftware anhand eines kleinen Programms für die Software "ATOS Professional" bzw. "GOM Inspect Professional" / "GOM Suite" der GOM GmbH erläutert. Die Programmiersprache ist Python, die dort vollständig integriert ist.

Mit der Programmiersprache kann durch die Einbindung einer von GOM bereitgestellten Bibliothek auf nahezu alle Elemente im geöffneten Mess-Projekt zugegriffen werden, also auf Messobjekte wie Sollelemente und Istelemente, Ausrichtungen, Koordinatensysteme oder aus vorhandenen Elementen neu konstruierte Elemente. Da es sich bei Python um eine vollständige Programmiersprache mit umfangreicher Funktionalität handelt, ist eine entsprechend komplexe Programmlogik möglich sowohl in funktionsorientierter Programmierung als auch in objektorientierter Programmierung.

Die Programmierung innerhalb der Messsoftware kann neben der Automatisierung von Routinetätigkeiten auch dazu genutzt werden um eine Funktionalität bereitzustellen, die so nicht standardmäßig in der Messsoftware enthalten ist. In der Messsoftware von GOM kann zwar kugelförmig (also mit einem bestimmen "Suchradius") um ein Element herum selektiert werden, die Selektion selbst bezieht sich aber nur auf Sollnetze (=CAD-Daten) und/oder Istnetze (=Messdaten). Nicht möglich ist eine Selektion von (Regelgeometrie-)Elementen, ausgehend von einem bestimmten Element und innerhalb eines definierten Suchradius. Eine solche Funktion wird durch das im folgenden betrachtete Skript bereitgestellt (Download des Skript am Ende der Seite).

Ausgangspunkt sind importierte CAD-Daten und daran definierte Sollelemente in Form von Flächenpunkten P1..P9, wie im Bild dargestellt. Der Punkt P5 ist angewählt, also selektiert.

Bild mit einem CAD-Körper und neun Messpunkten

Das am Ende der Webseite downloadbare Skript enthält eine Funktion, welche nun um diesen Punkt herum innerhalb des Suchradius nach weiteren Elementen sucht, jedes gefundene Element in eine bestimmte Datenstruktur aufnimmt (in ein sogenanntes Dictionary) und anschließend an das Hauptprogramm übergibt:


# Funktion
def benachbarte_elemente (liste_soll_elemente, suchradius):
	import math
	wurzel = math.sqrt
	DEFAULT_NACHKOMMASTELLEN = 3
	
	# interne Funktion zur Berechnung des Abstands zwischen zwei Elementen bzw. zwischen deren "Mittelpunkten"
	def abstand(element1, element2):
		try:
			# Versuchen, die Koordinaten der beiden Elemente zu holen
			x1 = element1.center_coordinate.x
			y1 = element1.center_coordinate.y
			z1 = element1.center_coordinate.z
			x2 = element2.center_coordinate.x
			y2 = element2.center_coordinate.y
			z2 = element2.center_coordinate.z
		except RuntimeError:
			# Fehler: eines der Elemente hat keine "Mittelpunkt"-Koordinaten, also Rueckgabe eines Abstands 
			# nicht moeglich
			return(None)
		else:
			# Koordinaten sind vorhanden, also Abstand zwischen den "Mittelpunkten" berechnen und zurueckgeben
			abstand = wurzel( (x1-x2)**2 + (y1-y2)**2 + (z1-z2)**2 )
			return(round(abstand, DEFAULT_NACHKOMMASTELLEN))
	
	# leere Elementliste oder Suchradius <= Null abfangen
	if len(liste_soll_elemente)==0 or suchradius<=0:
		return(None)
	# Parameter ok
	else:
		# alle Soll-Elemente in eine Liste
		liste_soll_elemente_alle = [i for i in gom.ElementSelection ({'category': ['key', 'elements', 'explorer_category', 'nominal', 'object_family', 'geometrical_element']})]
		
		# Liste erzeugen mit allen Kombinationen aus den beiden Listen (selektierte Soll-Elemente und alle Elemente)
		liste_alle_kombinationen = [(x,y,abstand(x,y)) for x in liste_soll_elemente for y in liste_soll_elemente_alle if (x!=y and abstand(x,y)<suchradius)]
		
		# Dictionary erzeugen und mit Werten fuellen
		dictionary_ergebnis = {i:[] for i in liste_soll_elemente_selektiert}
		for i in liste_soll_elemente_selektiert:
			for j in liste_alle_kombinationen:
				if j[0]==i:
					dictionary_ergebnis[i] = dictionary_ergebnis[i] + [(j[1],j[2])]
			dictionary_ergebnis[i].sort(key = lambda eintrag: eintrag[1])
		
		# Ergebnis in Form eines Dictionary zurueckgeben
		return(dictionary_ergebnis)


Das Hauptprogramm gibt diese Datenstruktur dann im Editor-Ausgabefenster aus, denkbar sind aber auch andere Verarbeitungsmöglichkeiten innerhalb des Skripts. Der Aufruf zur Berechnung der benachbarten Elemente erfolgt durch das Hauptprogramm, wobei dieses der Funktion eine Liste der vom Anwender selektierten Elemente übergibt sowie den gewünschten Suchradius:


# Hauptprogramm
# alle selektierten Soll-Elemente in eine Liste
liste_soll_elemente_selektiert=[i for i in gom.ElementSelection (gom.app.project.inspection.filter( 'is_selected', True))]

# Funktion zur Bestimmung der benachbarten Elemente aufrufen, falls Soll-Elemente selektiert wurden
if len(liste_soll_elemente_selektiert) > 0:
	ergebnis = benachbarte_elemente( liste_soll_elemente_selektiert, 200)

# Ergebnis ausgeben, falls eines berechnet wurde
try:
	for i,j in ergebnis.items():
		print(i,'\n',j,'\n')
except:
	print('Es konnten keine benachbarten Soll-Elemente berechnet werden.')


Mit einem Suchradius=300 [mm] wird als Ergebnis dies ausgegeben:
gom.app.project.inspection['P 5']
  [(gom.app.project.inspection['P 6'], 138.974), (gom.app.project.inspection['P 3'], 176.131)]
		
Die erste Zeile ist das selektierte Punkt-Element (in GOM-softwareinterner Bezeichnung), in der zweiten Zeile folgt als Ergebnis eine Liste, welche alle Elemente (in diesem Beispiel Flächenpunkte) innerhalb des Suchradius enthält zusammen mit dem Abstand zum selektierten Element. Die innerhalb des Suchradius gefunden Elemente sind in der Liste dabei aufsteigend nach dem Abstand sortiert, das Element mit dem kleinsten Abstand ist also das erste in der Liste.


Werden mehrere Elemente selektiert (P1 und P9, wieder mit einem Suchradius von 300mm) und im Funktionsaufruf übergeben, so sieht die Programmausgabe beispielsweise so aus:
gom.app.project.inspection['P 1'] 
 [(gom.app.project.inspection['P 2'], 85.215), (gom.app.project.inspection['P 4'], 205.809)] 

gom.app.project.inspection['P 9'] 
 [(gom.app.project.inspection['P 7'], 131.894), (gom.app.project.inspection['P 8'], 208.924),
 (gom.app.project.inspection['P 6'], 276.274)] 
		
Für jeden der beiden selektierten Punkte gibt es eine Ergebnisliste, wobei es 300mm um den Punkt P1 zwei weitere Elemente gibt (P2 und P4) und um den Punkt P9 drei weitere Elemente (P7, P8 und P6).


Grafik DownloadDownload Skript (Version 1, PY-Datei als ZIP-Datei, ohne Gewähr auf fehlerfreie Funktionalität)


Weiter zu einer etwas abgewandelten Skript-Variante   Grafik Pfeil nach rechts