"""Modul zur Erstellung und Speicherung von Optikprofilen.
Das Modul enthält Methoden zum Speichern und Einlesen von Optikprofilen und
verwendet dafür Funktionen zur Datei- und Stringmanipulation.
"""
import hilfsfunktionen
[Doku]class Optik():
[Doku] def __init__(self):
"""Wird aufgerufen, wenn ein Optik-Objekt erzeugt wird.
Der Konstruktior deklariert und initialisiert Profil-relevante
Variablen.
"""
# Allgemeine Daten initialisieren
self.kunde = "Neuer Kunde"
self.artikelnummer = "1.000000"
self.seite = 0
self.kruemmung = "planar"
self.vorschub = 1000
# Reinigungsparameter initialisieren
self.loesungsmittel: 200
self.druck: 45.0
self.linsenradius: 18.0
self.servowinkel: 1530
self.drehzahl: 90
self.wiederholungen: 0
self.x_offset: 10.0
self.z_offset: 0.0
self.oberflaechen_radius: 0.0
# Geschachtelte Liste deklarieren
self.profilkoordinaten = [[], []]
[Doku] def profil_einlesen(self, pfad):
"""Liest ein vorhandes Profil ein.
Der Inhalt einer Profildatei liegt immer im Format ``attribut:wert``
vor. Kommentarzeilen werden mit dem Zeichen ``#`` gekennzeichnet und
beim zeilenweisen Einlesen verworfen. Der eingelesene Inhalt wird
anschließend in teils verschachtelten (2-dimensionalen) Listen
gespeichert.
Note:
Eine Profildatei hat immer die Endung ``*.profil`` und muss,
wenn nicht in den Grundeinstellungen anders definiert, im
Verzeichnis ``~\Python\linsenfischer\profile`` abgelegt sein.
Sie besteht grundsätzlich aus den drei Abschnitten
**Allgemeine Daten**, **Reinigungsparameter** und aus den
optionalen **Profilkoordinaten**.
Args:
pfad (str): Pfad zur Profildatei z.B.
``\home\wild\Python\linsenfischer\profile\\achromat_1.profil``
Raises:
Eine Exception wird geworfen, wenn eine Problem beim Öffnen der
Profildatei auftritt.
"""
try:
profil_datei = open(pfad, 'r').read()
except:
print("Fehler beim Lesen der Datei!")
eingelesene_daten = [[], []]
# Daten auslesen, in Zeilen splitten und in einer Liste speichern
zeilen = profil_datei.split('\n')
for zeile in zeilen:
if len(zeile) > 1 and zeile.find('#') < 0:
attribut, wert = zeile.split(':')
eingelesene_daten[0].append(attribut)
eingelesene_daten[1].append(wert)
# Allgemeine Daten
self.kunde = eingelesene_daten[1][0]
self.artikelnummer = eingelesene_daten[1][1]
self.seite = eingelesene_daten[1][2]
self.kruemmung = eingelesene_daten[1][3]
# Reinigungsparameter
self.loesungsmittel = eingelesene_daten[1][4]
self.druck = eingelesene_daten[1][5]
self.linsenradius = eingelesene_daten[1][6]
self.servowinkel = eingelesene_daten[1][7]
self.drehzahl = eingelesene_daten[1][8]
self.wiederholungen = eingelesene_daten[1][9]
self.x_offset = eingelesene_daten[1][10]
self.z_offset = eingelesene_daten[1][11]
self.oberflaechen_radius = eingelesene_daten[1][12]
# Liste vor dem Befüllen leeren
self.profilkoordinaten.clear()
self.profilkoordinaten = [[], []]
# Prüfen ob Koordinaten vorhanden sind. Wenn ja auch diese einlesen und
# in einer zweidimensionalen Liste Speichern.
if len(eingelesene_daten[0]) > 13:
for i in range(13, len(eingelesene_daten[0]), 1):
# X-Koordinate
self.profilkoordinaten[0].append(float(eingelesene_daten[0][i]))
# Z-Koordinate
self.profilkoordinaten[1].append(float(eingelesene_daten[1][i]))
self.profil_bereinigen()
print("Optikprofil erfolgreich eingelesen.")
[Doku] def profil_speichern(self, pfad, allgemeine_daten, reinigungs_parameter):
"""Erstellt ein Profil und speichert dieses anschließend in einer
Profildatei.
Die zu speichernden Werte werden zuvor aus den Eingabefeldern der GUI
ausgelesen. Wurde auch ein Profil der Optik aufgenommen wird dieses in
Form von X- und Z-Koordinatenpaaren gespeichert (``X:Z``).
Alle Eigenschaften und Parameter werden zeilenweise in der Form
``attribut:wert`` gespeichert. Kommentarzeilen werden mit dem Zeichen
``#`` gekennzeichnet und zwischen den drei Abschnitten eingefügt.
Allgemeine Daten:
- Kunde: Freier Text
- Artikelnummer: Freier Text
- Seite: kann 0 (oben) und 1 (unten) sein
- Krümmung: kann 0 (konvex), 1 (konkav) und 2 (planar) sein.
Reinigungs-Parameter:
- Lösungsmittel: Menge des aufzutragenden Lösungsmittels in
:math:`{\\mu l}`
- Linsenradius: Radius der Linse in mm
- Servowinkel: Winkel des Reinigungskopfes in °
- Drehzahl: Drehzahl des Drehtellers in 1/min
- Wiederholungen: Anzahl der Reinigungswiederholungen, einheitenlos
- X-Offset: X-Versatz zum Reinigungsstartpunkt in mm
- Z-Offset: Z-Versatz zum Reinigungsstartpunkt in mm
- Krümmungsradius: Radius der Oberfläche (wird berechnet) in mm
Note:
Eine Profildatei hat immer die Endung ``*.profil`` und muss, wenn
nicht in den Grundeinstellungen anders definiert, im Verzeichnis
``~\Python\linsenfischer\profile`` abgelegt sein. Sie besteht
grundsätzlich aus den drei Abschnitten **Allgemeine Daten**,
**Reinigungsparameter** und aus den optionalen
**Profilkoordinaten**.
Args:
pfad (str): Pfad zur Profildatei
allgemeine_daten (dict): Enthält die allgemeinen Daten zu einer
Optik als (str)
reinigungs_parameter (dict): Enthält die Reinigungsparameter einer
Optik als (str).
"""
print("Profilkoordinaten werden im Verzeichnis ", pfad,
"gespeichert ...")
# Datei öffnen
profil_datei = open(pfad, 'w')
# speichern der Allgemein-Daten
profil_datei.write("#ALLGEMEINE DATEN\n")
profil_datei.write("kunde:" + allgemeine_daten['kunde'] + "\n")
profil_datei.write("artikelnummer:" + allgemeine_daten
['artikelnummer'] + "\n")
profil_datei.write("seite:" + str(allgemeine_daten['seite']) + "\n")
profil_datei.write(
"kruemmung:" + str(allgemeine_daten['kruemmung']) + "\n")
profil_datei.write("\n")
# speichern der Reinigungsparameter
profil_datei.write("#REINIGUNGSPARAMETER\n")
profil_datei.write("loesungsmittel:" +
str(reinigungs_parameter['loesungsmittel']) + "\n")
profil_datei.write("druck:" + str(reinigungs_parameter['druck']) + "\n")
profil_datei.write(
"linsenradius:" + str(reinigungs_parameter['linsenradius']) + "\n")
profil_datei.write(
"servowinkel:" + str(reinigungs_parameter['servowinkel']) + "\n")
profil_datei.write(
"drehzahl:" + str(reinigungs_parameter['drehzahl']) + "\n")
profil_datei.write("wiederholungen:" +
str(reinigungs_parameter['wiederholungen']) + "\n")
profil_datei.write(
"x_offset:" + str(reinigungs_parameter['x_offset']) + "\n")
profil_datei.write(
"z_offset:" + str(reinigungs_parameter['z_offset']) + "\n")
# Wenn Koordinaten erfasst wurden auch den Linsenradius speichern
if (len(self.profilkoordinaten[0]) > 0):
# Radius über drei punkte berechnen
mittlerer_abtastpunkt = int(len(self.profilkoordinaten[0]) / 2)
p1 = [float(self.profilkoordinaten[0][0]),
float(self.profilkoordinaten[1][0])]
p2 = [float(self.profilkoordinaten[0][mittlerer_abtastpunkt]),
float(self.profilkoordinaten[1][mittlerer_abtastpunkt])]
p3 = [float(self.profilkoordinaten[0][-1]),
float(self.profilkoordinaten[1][-1])]
radius = hilfsfunktionen.radius_berechnen(p1, p2, p3)
print("Berechneter Radius:", radius)
# Radius in Datei schreiben
profil_datei.write("oberflaechen_radius:" + str(radius) + "\n")
# Leerzeile schreiben
profil_datei.write("\n")
if (len(self.profilkoordinaten[0]) > 0):
# Header der Profilkoordinaten in die Profildatei schreiben
profil_datei.write("#PROFILKOORDINATEN X,Z\n")
# Koordinaten schreiben
for i in range(len(self.profilkoordinaten[0])):
profil_datei.write(
str(self.profilkoordinaten[0][i]) + ":" +
str(self.profilkoordinaten[1][i]) + "\n")
# Datei wieder schließen
profil_datei.close()
[Doku] def update_profilkoordinaten(self, profil):
"""Befüllt die klasseninterne, zweidimensionale Liste
``profilkoordinaten`` mit X- und Z-Koordinaten, welche bei der
Profilabtastung ermittelt wurden.
Args:
profil (list): Liste aus Koordinatenpaaren in der
Form ['X:Z'] *(str)*
"""
# Etwaige voerherige Listeneinträge löschen
self.profilkoordinaten.clear()
self.profilkoordinaten = [[], []]
# Liste befüllen
for i in range(len(profil)):
x, z = profil[i].split(':')
self.profilkoordinaten[0].append(x)
self.profilkoordinaten[1].append(z)
[Doku] def profil_bereinigen(self):
"""Bereitet die abgetasteten X- und Z-Koordinaten eines Profiles so auf,
damit sie vom CNC-Controller abgefahren werden können.
Bei den Z-Koordinaten wird zunächst der größte Z-Wert ermittelt und bei
allen Z-Koordinaten abgezogen :math:`{Z_{neu} = Z_i - Z_{max}}`.
Bei den X-Koordinaten wird ebenfalls der größte X-Wert ermittelt und
anschließend die Differenz :math:`X_{neu} = {X_{max} - X_i}` gebildet.
Diese beiden Operationen bewirken, dass das gesamte Profil an der
vertikalen Achse gespiegelt und das 1. Koordiantenpaar in den Ursprung
gelegt wird.Die neuen Koordinaten können im Anschluss mittels relativer
Positionierung (G91) abgefahren werden.
"""
print("Optikprofil wird bereinigt ...")
# Z-Koordinate bereinigen:
maximales_z = max(self.profilkoordinaten[1])
for i in range(len(self.profilkoordinaten[1])):
self.profilkoordinaten[1][i] = self.profilkoordinaten[1][i] - \
maximales_z
# X-Koordinaten berreinigen:
maximales_x = max(self.profilkoordinaten[0])
for i in range(len(self.profilkoordinaten[0])):
differenz = maximales_x - self.profilkoordinaten[0][i]
self.profilkoordinaten[0][i] = differenz