
In SUMO sind Züge erst einmal ganz normale Fahrzeuge und man kann ihnen Halte (in SUMO heißen sie stop) in ihrer Route mitgeben. Natürlich kann SUMO auch Fahren im Block und ähnliche Bahnbesonderheiten simulieren, das ist für das Anhalten in diesem Artikel aber nicht so wichtig. Nehmen wir also an, wir haben schon eine Haltestelle mit dem schönen Namen „Halt“ definiert und möchten, dass unser Zug dort hält. In netedit sieht das im einfachsten Fall wie oben im Bild aus, in SUMO’s XML so:
<routes>
<trip id="Zug" type="DEFAULT_RAILTYPE" depart="0" from="E0" to="E1">
<stop trainStop="Halt" duration="60"/>
</trip>
</routes>
Wie man leicht erraten kann, hält dieser Zug dann in der Simulation eine Minute am angegebenen Halt.
Wie man den Zug und alles weitere in SUMO’s netedit definiert beschreibe ich hier nicht näher und beschränke mich auch im Folgenden auf die XML-Dateien. Natürlich kann man das auch alles in netedit klicken. Insgesamt benötigt man immer ein Netz, eine Routendatei (wie oben), eine Additional-Datei (für den Halt) und eine sumocfg, die alles zusammenführt. Ich habe Netz, Halt und initiale Route in netedit erstellt und einmal die sumocfg gespeichert und dann mit XML weitergemacht. Die finalen Dateien finden sich auch am Ende des Artikels zum Download.
Wenn man das nicht nur anschauen möchte, wertet man das am besten aus indem man stopinfo-output aktiviert:
sumo -c train.sumocfg --stop-output stops.xml
was folgende Ausgabe in der Datei stops.xml erzeugt (unwesentliche Attribute habe ich zugunsten der Lesbarkeit weggelassen und es sei sumo auch verziehen, dass es busStop schreibt, auch wenn es ein Zug ist):
<stops>
<stopinfo id="Zug" ... started="39.00" ended="99.00" busStop="Halt" .../>
</stops>
Der Zug hat also tatsächlich von Sekunde 39 bis Sekunde 99 gehalten. Um Verspätungen zu ermitteln, müssten wir jedoch wissen, wann er denn hätte losfahren sollen, wir brauchen also einen Fahrplan. Dazu nutzen wir in der Routendatei das Attribut until an Stelle von duration um deutlich zu machen, dass es eine geplante Abfahrtzeit gibt:
<routes>
<trip id="Zug" type="DEFAULT_RAILTYPE" depart="0.00" from="E0" to="E1">
<stop trainStop="Halt" until="120.00"/>
</trip>
</routes>
Jetzt enthält der stop output auch mehr Informationen:
<stops>
<stopinfo id="Zug" ... started="39.00" ended="120.00" delay="0.00" busStop="Halt" .../>
</stops>
Keine Verspätung (delay), alles super. Jetzt lassen wir unseren Zug mal extra langsam fahren, um eine Verspätung zu provozieren:
<routes>
<vType id="langsam" vClass="rail" maxSpeed="1"/>
<trip id="Zug" type="langsam" depart="0" from="E0" to="E1">
<stop trainStop="Halt" until="120"/>
</trip>
</routes>
Der stop output sieht jetzt so aus:
<stops>
<stopinfo id="Zug" ... started="163.00" ended="164.00" delay="44.00" busStop="Halt" .../>
</stops>
Die Verspätung ist jetzt schon mal abgebildet, aber wir würden natürlich gerne wissen woran es lag. Ist der Zug schon zu spät angekommen oder ist er genau hier einfach nur länger stehengeblieben? Dazu müssen wir allerdings auch die geplante Ankunftszeit wissen:
<routes>
<vType id="langsam" vClass="rail" maxSpeed="1"/>
<trip id="Zug" type="langsam" depart="0" from="E0" to="E1">
<stop trainStop="Halt" arrival="60" until="120"/>
</trip>
</routes>
generiert folgende Ausgabe:
<stops>
<stopinfo id="Zug" ... started="163.00" ended="164.00" delay="44.00" arrivalDelay="103.00" busStop="Halt" .../>
</stops>
Wir sehen also, dass der Zug tatsächlich schon viel zu spät angekommen ist und sogar durch einen kürzeren Halt etwas Zeit gut gemacht hat. Jetzt wollen wir das mal mit ein paar mehr Zügen ausprobieren:
<routes>
<vType id="default" vClass="rail"/>
<vType id="langsam" vClass="rail" maxSpeed="1"/>
<vTypeDistribution id="mix" vTypes="langsam default"/>
<flow id="Zug" type="mix" begin="0" end="3600" period="300" from="E0" to="E1">
<stop trainStop="Halt" until="120"/>
</flow>
</routes>
Jetzt fährt also alle fünf Minuten ein Zug (und er ist mit 50% Wahrscheinlichkeit langsam) und man kann sehen, wie die Verspätung von Zug.1 und Zug.2 vor allem auf die nachfolgenden wirkt:

Dieses Bild wurde übrigens mit dem folgenden Aufruf erzeugt:
$SUMO_HOME/tools/visualization/plotXMLAttributes.py -x id,type -y delay --join-x \
--join "\n" --barplot flow_stops.xml
und hier noch die Dateien des Szenarios zum herunterladen.
SUMO unterstützt für Halte die Attribute until und arrival. Damit lassen sich Fahrpläne für Fahrzeuge abbilden und die Verspätungen sowohl bei Ankunft als auch bei Abfahrt auswerten.
Der erste Data Independence Day (oder auch Datenunabhängigkeitstag „DUT“) ist ja jetzt schon wieder zwei Wochen her, aber manchmal brauchen die Sachen etwas. Ich bin jedenfalls ein großer Fan davon die Hoheit über die eigenen Daten zu behalten und der Vortrag von Marc-Uwe Kling war auch sehr dazu geeignet, mehr Fans für die Idee zu gewinnen.
Die etwas niedriger hängenden Früchte sind bei mir schon abgeerntet, ich habe keine wirklich aktiven GMail-Accounts und auch auf Facebook bin ich schon lange nicht mehr (dafür noch auf LinkedIn, naja). Eine Sache, die mich aber schon lange ärgert, ist, wie schwierig es einem gemacht wird, die zahlreichen Sachen, die das Handy so speichert, auf den Rechner zu bekommen, ohne (in meinem Fall bei Android) Google alles über den Zaun zu werfen. Und ich rede noch nicht mal von GPS- oder Browser-Daten, die sowieso in den globalen Datenhalden landen, sondern von echten lokalen Dateien: Fotos, Downloads und sowas. Natürlich kann man das per Bluetooth irgendwohin schieben, nur leider funktioniert das nur selten sofort und automatisieren lässt sich das auch nicht gut. Ich habe lange mit Nextclouds Auto-Upload meine Fotos synchronisiert, aber so richtig problemlos war das auch nicht.
Daher jetzt die gute Nachricht: Dateisynchronisation kann ganz einfach sein. Tada: Syncthing.
Ein offenes Protokoll, offene Software und man braucht auch keinen zentralen Server (sorry Nextcloud). Einfach auf dem Handy und auf dem lokalen Rechner das Programm installieren (ich nutze auf dem Handy syncthing-fork und unter Ubuntu-Linux kann man es einfach mit dem Paketmanager apt installieren). Es gibt aber auch Downloads für so ziemlich jedes andere Betriebssystem und man kann natürlich auch „richtige“ Rechner damit synchronisieren, nicht nur Handys.
Auf dem Handy startet man Syncthing-Fork wie jede andere App auch und gibt Zugriff auf das Dateisystem (sonst wird es schwierig mit der Dateisynchronisation). Auf dem Rechner reicht es in der Regel das Basissystem zu installieren und zu starten (im Startmenü sollte es einen Eintrag „Start Syncthing“ geben). Das Frontend nutzt den Browser, nach dem Start verbindet man sich einfach mit localhost:8384 auf und schon geht es los (eventuell geht auch schon beim Start automatisch Euer Browser auf).
Nachdem es auf beiden Geräten läuft, muss man die Geräte miteinander bekannt machen. Am einfachsten geht man im Handy auf Gerät hinzufügen.

Dann verlangt das Handy die Kennung des neuen Geräts, die findet Ihr auf dem Rechner unter „Dieses Gerät: Kennung“. Wenn man da klickt wird auch ein QR-Code angezeigt, den man scannen kann und schon kennt das Handy die Kennung. Man bestätigt noch auf dem Rechner das neue Gerät und der Verbindung steht nichts mehr im Wege. Ich gebe zu, dass die GUI auf dem Rechner anfangs etwas einschüchtert, aber es ist wirklich einfach. Hier die Ansicht auf meinem Rechner beim Hinzufügen eines neuen Geräts:

Es gibt Ordner (linke Seite), das sind die Dateien, die man synchronisiert (immer komplette Ordner, aber man kann Ausnahmen definieren) und Geräte (rechte Seite). Man kann also auch den gleichen Ordner mit mehreren Geräten synchronisieren.
Als nächstes gibt man an, welchen Ordner man synchronisieren möchte, also zum Beispiel die Bilder (auf dem Handy in der Regel DCIM/Camera) oder die Downloads. Man muss das für jeden Ordner separat machen, aber alle Unterordner werden mitsynchronisiert.

Man gibt dem Ordner einen schönen Namen (damit man ihn wiedererkennt), wählt das richtige Verzeichnis aus (also zum Beispiel Download) und klickt an, dass er mit dem Rechner synchronisiert werden soll.

Jetzt auf der Rechnerseite noch bestätigen und auch dort ein passendes Verzeichnis wählen (oder einfach ein neues erstellen) und fertig! Ab jetzt werden beide Verzeichnisse immer synchronisiert, wenn auf beiden Geräten syncthing läuft. Es bietet sich also an es in den Autostart aufzunehmen.
Probleme gab es bei mir bis jetzt nur, wenn das Handy aus Versehen im Energiesparmodus oder nicht im WLAN war. In beiden Fällen wird nämlich standardmäßig nicht synchronisiert (lässt sich in der Konfiguration natürlich ändern und auch der Statusscreen ist hier hilfreich). Mit den fortgeschrittenen Aktionen wie der Verschlüsselung hat nicht immer alles sofort geklappt, aber ich hatte nie Datenverlust und es brauchte bei Problemen nur einen Neustart der App oder ein Pausieren und Neustart des betroffenen Ordners. Da Syncthing auch Optionen hat, eine Historie geänderter Dateien zu speichern, benutze ich es jetzt auch als Backup-Tool. Was syncthing allerdings nicht kann, ist lokale Verzeichnisse synchron halten, da muss man weiter rsync benutzen.
Insgesamt jedoch ein wunderbares Werkzeug zur Daten“befreiung“ insbesondere vom mobilen Endgerät. Ich habe das am DI.Day zwar nicht bei mir selbst neu installiert, aber dafür eines der Kinder überzeugt (und das ist ja eigentlich noch viel besser).
]]>
Es klingt erstmal einfach, SUMO unterstützt für die Fahrzeugattribute departPos und arrivalPos den Wert random und im Wesentlichen passiert was man erwartet: SUMO zieht eine zufällige Zahl gleichverteilt zwischen 0 und der maximal möglichen Position auf der Kante und lässt das Fahrzeug dort starten beziehungsweise enden. Kein Problem soweit.
Aber was passiert, wenn die Startkante und die Zielkante identisch sind? Wenn Zufall involviert ist, kann es vorkommen, dass die Startposition mal vor und mal hinter der Endposition liegt. Da man in SUMO nicht rückwärts fahren kann, kann das heißen, dass das Fahrzeug einen großen Umweg fahren muss oder sogar gar keine gültige Route hat, je nachdem wie der Rest des Netzes aussieht. Also eine fehlerhafte Route wenn die Würfel schlecht fallen? Jakob hat bei der Lösung des Problems nach unserer Diskussion einen anderen Weg gewählt. Wir sollten eine Warnung ausgeben und die Ankunftsposition anpassen. Denn bei der Bearbeitung ist aufgefallen, dass wir bisher auch schon „heimlich“ die Ankunftsposition angepasst haben, wenn sie vor der Startposition lag und sonst keine gültige Route möglich war.
Es gibt jetzt also wieder eine Warnung mehr in SUMO und hoffentlich ein nachvollziehbares Verhalten der Simulation und der Router bei zufälligen Positionen.
Falls Ihr mehr über SUMO lernen wollt oder auch kleine Geschichten erlebt oder große Wissenschaft damit gemacht habt, reicht gerne einen Beitrag zur nächsten SUMO-Konferenz ein, kommt vorbei oder hinterlasst hier einen Kommentar.
PS: Mit diesem Artikel beginne ich (hoffentlich) eine unregelmäßige Reihe über Erkenntnisse, kleine Merkwürdigkeiten und Besonderheiten in meiner Lieblingsverkehrssimulation.(Disclaimer: Ich bin auch an der Entwicklung derselben nicht ganz unbeteiligt..)
]]>Amazon will in amerikanischen Großstädten seine Pakete mit einer Kombination aus U-Bahn und Fahrradkurieren ausliefern, denn mit diesem Kombiverkehr ließe sich der allgegenwärtige Stau umfahren. Ein Pilotprojekt startet in New York. Außerdem berichtet Martin Randelhof von der Integration von Binnenschiff und Fahrrad in den innerstädtischen Lieferverkehr.
Mein absolutes Lieblingszitat:
]]>Python relies on a notion of “we’re all consenting adults here.”
]]>