IRESTE/DOC.md
2022-02-14 18:37:45 +01:00

173 lines
5.2 KiB
Markdown

# DOCUMENTATION
## Reseau routier .net.xml de SUMO
[ref](https://sumo.dlr.de/docs/Networks/SUMO_Road_Networks.html)
![Différents éléments composant le reseau routier](net_el.jpg "Elements d'un réseau")
### Edge
Relie deux nodes, il possède un ID unique le décrivant et les deux ID des nodes composant ses extrémitées.
Il ne possède pas directement d'information concernant le tracé de la route, ces données sont fournis par les [lanes](#Lane)
Un edge est considéré comme "interne" si il est inclus dans une jonction
### Lane
Comme le nom l'indique, decris une voie de la route.
Possède un ID et un index numéroté de droite à gauche, une vitesse maximale autorisé, une longueur.
Le tracé de la route est defini par la propriètée "shape" qui est composée d'une liste de position x,y
### Junction/Node
Une jonction entre plusieurs routes.
Possède un ID, une position (x,y), une liste des voies qui s'y intersecte, une liste des voies internes qui la compose, un shape qui l'englobe
## Implémentation
### main.py
#### Imports
imports "classiques" :
```python
import os, sys
import time
```
imports pour sumo, honnêtement je suis pas sur qu'on en ai besoin si la librairie
est installée avec pip mais bon c'était le code recommandé [ici](https://sumo.dlr.de/docs/Tools/Sumolib.html) :
```python
if 'SUMO_HOME' in os.environ:
tools = os.path.join(os.environ['SUMO_HOME'], 'tools')
sys.path.append(tools)
else:
print("please declare environment variable 'SUMO_HOME'")
```
imports pour Qt :
```python
from PySide6.QtCore import Qt, QTimer
from PySide6.QtWidgets import QApplication, QMainWindow
from PySide6.QtGui import QSurfaceFormat, QAction
```
import du fichier contenant la description de interface, generée par uic :
```python
from window import Ui_MainWindow
```
le fichier contenant la boucle principale de maj :
```python
from mainLoop import mainLoop
```
#### Classe MainWindow
On définit la classe MainWindow qui hérite de QMainWindow
```python
class MainWindow(QMainWindow):
```
La fonction `__init__` est la fonction qui est appellée quand on crée l'objet (le constructeur)
```python
def __init__(self):
```
On fait appel à la fonction `__init__` de la superclass, donc on execute le code d'initialisation de la classe QMainWindow
```python
super(MainWindow, self).__init__()
```
On genere l'interface à partir du fichier générée par QT Designer
```python
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
```
On initialise la boucle de mise à jour
```python
self.mainLoop = mainLoop(self)
```
On donne à la boucle principale le widget qui nous sert à afficher les infos (l'interface avec position, vitesse,... à droite de l'écran)
Après il est transmis à chaque voiture qui décident de ce quelles vont afficher
```python
self.mainLoop.addInfosDisplay(self.ui.infos)
```
On génere le menu (l'interface en haut de l'écran)
Avec le menu general, qui as un sous-menu (File), qui as un sous-menu (Open), qui as deux sous-actions (ouvrir le réseau et ouvrir les vehicules)
Pour chaque action on les relient (connect) à un fonction qui serat executée quand on cliquerat sur le bouton
```python
fileMenu = self.menuBar().addMenu("&File")
openMenu = fileMenu.addMenu("&Open")
openNet = QAction("&Open Network",self)
openNet.setStatusTip("Open Network file (.net.xml)")
openNet.triggered.connect(self.mainLoop.openNetwork)
openMenu.addAction(openNet)
openVeh = QAction("&Open Vehicles",self)
openVeh.setStatusTip("Open Vehicle description (.rou.xml)")
openVeh.triggered.connect(self.mainLoop.openVehicles)
openMenu.addAction(openVeh)
```
On crée un timer qui va executer toutes les 1/60s (60fps) la fonction update de notre boucle principale
```python
timer = QTimer(self)
timer.timeout.connect(self.mainLoop.update)
timer.start(1.0/60)
```
Cette fonction est appelée à chaque appui sur le clavier, ici si la touche est Esc ou Q on arrète le programme
```python
def keyPressEvent(self, e):
if e.key() == Qt.Key_Escape or e.key() == Qt.Key_Q:
self.close()
```
#### main
`__name__` est defini à `"__main__"` seulement si on est dans le fichier principal (i.e pas dans un module)
Donc cette portion de code est celle executée quand on lance main.py
```python
if __name__ == "__main__":
```
On crée une QApplication, comme ça Qt se demerde pour gérer l'event loop, le context,...
```python
app = QApplication()
```
On définie les propriètés par defaut de la surface, j'avais mis ça pour activer l'AA mais ça à l'air foiré ([cf](https://doc.qt.io/qtforpython/PySide6/QtOpenGLWidgets/QOpenGLWidget.html#PySide6.QtOpenGLWidgets.PySide6.QtOpenGLWidgets.QOpenGLWidget.resized))
```python
format = QSurfaceFormat()
format.setDepthBufferSize(24)
format.setVersion(3, 2)
format.setSamples(4)
format.setProfile(QSurfaceFormat.CoreProfile)
QSurfaceFormat.setDefaultFormat(format)
```
On crée notre objet de fenetre principale défini [juste au dessus](#Classe-MainWindow)
```python
window = MainWindow()
window.show()
```
Finalement on lance l'event loop, et on quitte dès qu'elle retourne
```python
sys.exit(app.exec())
```