Physiksimulation/Dokumentation/Projektverlauf/
Datum: 14. Juli 2016
In dieser Woche haben wir die Arbeiten an unserem Cython-Interface beendet, haben es fehlerfrei lauffähig gemacht und begonnen, es in unser Python-Programm zu integrieren.
Mithilfe eines Fehlergraphen haben wir uns daran gemacht, die Anomalie zu lösen: Warum liefert der gleiche Code mit den gleichen Parametern unterschiedliche Ergebnisse, nur weil er einmal von Cython und einmal direkt aufgerufen wird? Dabei haben wir alle möglichen Fehlerquellen angeguckt. „Werden die Geschwindigkeiten in der Cython-Variante korrekt berechnet?“ - nein. „Werden die Beschleunigungen richtig berechnet und die Änderungen werden nur nicht übernommen?“- nein.
Letztendlich lag der Fehler in einer Eigenheit vom Cython-Compiler: Unsere Objekte haben eine bool-Variable isFixed, um sie an einer Stelle zu halten. Im Standardkonstruktor setzt C++ bool-Variablen auf false, Cython aber auf true. Daraus entstand diese sehr merkwürdige Anomalie. Der Fehler konnte dann schnell beseitigt werden.
Unser Cython-Interface haben wir der Übersichtlichkeit halber um eine eigene PyCObject-Klasse erweitert. Diese kann man nach Belieben und bequem ändern, bevor man sie an das Universum weitergibt. Hier kann man nun außerdem für jedes Objekt eine eigene Farbe angeben, die dann bei der Visualisierung genutzt wird. Die Änderungen am Interface sind recht klein:
# im PyCInterface.pyx [...] cdef class Zwischengesicht: [...] def add (self, o): self.intfc.add (o.x, o.y, o.z, o.vx, o.vy, o.vz, o.m) [...] class PyCObject: def __init__(self): self.name = "" self.color_r = (1,1,1) # white self.x = 0 self.y = 0 self.z = 0 self.vx = 0 self.vy = 0 self.vz = 0 self.ax = 0 self.ay = 0 self.az = 0 self.m = 0 self.fixed = False
Diese bessere Art des Objektehinzufügens haben wir nun in unserer Hauptklasse genutzt, um beim Klick auf den „Planten hinzufügen“-Button ein PyCObject zu erzeugen, es hin manipulieren und es mit „Okay“ in das Universum zu übernehmen oder es bei „Cancel“ zu verwerfen. Die wichtigsten Stellen dazu aus dem langen Hauptprogramm:
# das "Planeten hinzufügen"-Fenster class PopupWindow0(QtGui.QWidget): def __init__(self, parent=None, widget=None): [...] # ruft beim Klicken auf den "Okay"-Button die Methode output0 auf QtCore.QObject.connect(btn0, QtCore.SIGNAL(_fromUtf8("accepted()")), self.output0) [...] def output0(self): obj = PyCObject() obj.x = float(PositionEditx0.text()) # übernimmt die Werte aus den Eingabefeldern obj.y = float(PositionEdity0.text()) # und speichert sie in den Attributen des obj.z = float(PositionEditz0.text()) # PyCObjects [...] interface.add (obj)
In der nächsten Woche, am letzten regulären Labortermin, bauen wir alle unsere Klassen zu einem kompletten Programm zusammen. Vom Hauptfenster aus wird man dann leicht Objekte erstellen können (ist ohnehin fast fertig) und mit einem Klick die Animation starten können.