Erweitertes Rangierbeispiel

Vorwort

Das erweiterte Rangierbeispiel wendet sich an erfahrene Anwender von Rocrail, die auch vertiefte Kenntnisse im Bereich XML-Scripting haben. Es wird in den einzelnen Code-Schnipseln nich auf jede einzelne Befehlszeile eingegangen, sondern die Gesamtfunktionsweise beschrieben. Einzelne Erläuterungen sind im jeweiligen Codeschnipsel eingefügt.
Ab Revision 11.715+

Das Rangieren (österr. Verschieben)


Beim Rangieren geht es in der Regel darum beladene oder leere Wagons zu einem Zug zusammenzustellen oder diesen Aufzulösen. Dabei folgt das Rangieren meist einem modularen Prinzip. Wagons sollen entweder auf einem Abschnitt aufgenommen oder abgestellt werden. Dieser Vorgang wiederholt sich im Prinzip dann immer wieder in einem Block.

Was bedeutet das jetzt auf ein XML-Script übertragen ? Das XML-Script erfasst den Rangierablauf. Das XML-Script wird in jedem Block aufgerufen, in dem etwas passieren soll, was mit dem Rangieren zu tun hat. Es muß also als Erstes geprüft werden, ob sich eine Lok in einem bestimmten Block befindet. Danach folgt dann die Prüfung, ob die Lok bereits Wagons mitführt, oder Wagons in den Zug aufgenommen werden sollen. Auch das gibt bereits eine Reihenfolge vor. Als Erstes wird darauf geprüft, ob die Lok Wagons im Zug hat. Wenn das der Fall ist, werden diese abgestellt. Als Zweites wird darauf geprüft, ob sich Wagons im Block befinden, die in den Zug aufgenommen werden sollen. Darauf folgen dann evtl. Kupplungsbefehle und ein Fahrbefehl mit einem neuen Ziel.
Vom Schema her, sieht es damit so aus:

  1. Prüfen, ob eine Lok in einem bestimmten Block steht
  2. Prüfen ob: a) Eine Lok Wagons mitführt oder b) Eine Lok bestimmte Wagons aufnehmen soll
  3. Notwendige Kuppelbefehle
  4. Neues Fahrziel setzen und starten

Dieses Schema kann man effektiv in einem XML-Script einsetzen, da es sich in den einzelnen Blöcken immer wiederholt. Dazu gibt es in der Regel einen Block (Ausziehgleis), in dem geprüft wird, ob die Lok Wagons mitführt und was mit diesen geschehen soll, oder ob irgendwo Wagons stehen, die geholt / bewegt werden sollen. Die einzelnen Code-Schnipsel setzen voraus, daß man die Positionsbestimmung einsetzt. Nur so ist bekannt, wo sich ein Wagon befindet und welche Position er hat. Die hier vorgestellten Code-Schnipsel bieten eine Basis, mit der man eigene Rangierabläufe zusammenstellen kann. Weitergehende Individualisierungen sind möglich.

Die einzelnen Code-Schnipsel

XML - Variablen setzen

<!-- Variablen setzen -->
<vr id="var1" text="true"/>
<vr id="var2" text="false"/>
<vr id="%lcid%" value="1"/>
<vr id="Pos_%callerid%" value="#%callerid%"/>

Diese Variablen sollten immer am Anfang des XML-Scriptes stehen. Sie werden für die Auswertung oder Berechnung benötigt.

XML - Prüfung, ob Lok im Block xy

<!-- Prüfen ob die Lok im Block xy steht (BLOCK durch realen Block ersetzen) -->
<if state="lc %lcid% = BLOCK">
	<then>
	<!-- Dann, weitere Prüfungen -->
	</then>
</if>

Hier wird geprüft, ob die Lok sich in einem bestimmten Block befindet. Dieser Teil umschließt die weiteren Script-Teile. Diese werden also dazwischen eingefügt. Es können auch mehrere Blöcke definiert werden und mit alltrue=“false” als oder verknüpft werden

Die folgenden Code-Schnipsel werden für die Blöcke benötigt (Abstell-Gleise) , in denen Wagons aufgenommen oder abgestellt werden sollen.


XML - Wagons aus Zug lösen

<!-- Prüfen, ob sich Wagen im Zug befinden -->
<foreach table="carlist" condition="@%callerid% = %operatorid%">
	<!-- Wagen aus dem Zug lösen -->
	<operator id="@%callerid%" cmd="removecar" carids="%oid%"/>
	<!-- Textfeld der Variablen Wagon löschen -->
	<vr id="%oid%" text=""/>
	<!-- Zaehler der Variablen Lok um EINS erhöhen -->
	<vr id="%lcid%" value="#%lcid% + 1"/>
</foreach>
<!-- Wagons gefunden - Folgekommandos hier einfügen -->

Hier wird geprüft, ob die Lok Wagons mitführt.

XML - Wagons gefunden - Folgekommandos

<!-- Wenn Wagen im Zug gefunden wurden, ist Zaehler groesser Eins -->
<if condition="#%lcid% > 1">
	<then>
		<!-- Hier können Komanndos zum Abkuppeln eingefügt werden -->
		<!-- Hier können Fahrbefehle mit Zielblock stehen -->
		<!-- Variable der Lok auf NULL setzen -->
		<vr id="%lcid%" value="0"/>
		<!-- script verlassen -->
		<exit/>
	</then>
</if>

Dieser Teil ist notwendig, damit die Wagons, welche sich im Zug befinden, auf dem Gleis stehen gelassen werden.

XML- Wagons in den Zug übernehmen

<!-- Pruefen welcher Wagen der Letzte in Block ist -->
<foreach table="carlist" condition="#%oid% = #Pos_%callerid%" state="car %oid% = %callerid%">
	<!-- Wagen zum Rangierzug hinzufuegen -->
	<operator id="@%callerid%" cmd="addcar" carids="%oid%"/>
	<!-- Variable für loaded/empty setzen -->
	<if state="car %oid% = loaded">
		<then>
		<vr id="var1" text="loaded"/>
		<vr id="var2" text="@var1"/>
		</then>
	</if>
	<if state="car %oid% = empty">
		<then>
			<vr id="var1" text="empty"/>
			<vr id="var2" text="@var1"/>
		</then>
	</if>
	<!-- %lcid% als Zaehler setzen -->
	<vr id="%lcid%" value="#%lcid% + 1"/>
	<!-- Variable Pos_Block reduzieren -->
	<vr id="Pos_%callerid%" value="#Pos_%callerid% - 1"/>
	<!-- Nur einen Wagen nehmen -->
	<trace text="Wagen %oid% gefunden - suche weiter"/>
	<break/>
</foreach>
 
<!-- Pruefen, ob weitere Wagen vorhanden sind -->
<while condition="#Pos_%callerid% > 0|@var1 = @var2" max="10">
	<!-- Pruefen welcher Wagen als letzter im Block steht -->
	<foreach table="carlist" condition="#%oid% = #Pos_%callerid%" state="car %oid% = %callerid%">
		<!-- Prüfen, ob der Wagen gleich dem letzten Wagen beladen oder leer ist-->
		<if state="car %oid% = @var1">
			<then>
				<!-- Wagen zum Rangierzug hinzufuegen -->
				<operator id="@%callerid%" cmd="addcar" carids="%oid%"/>
				<!-- Zaehler fuer Rangierfunktionen setzen -->
				<vr id="%lcid%" value="#%lcid% + 1"/>
				<!-- Variable Pos_Block reduzieren -->
				<vr id="Pos_%callerid%" value="#Pos_%callerid% - 1"/>
			</then>
			<else>
				<!-- var2 auf emty setzen, damit Schleife beendet wird -->
				<vr id="var2" text="ungleich"/>
			</else>
		</if>
	</foreach>
</while>

Hier wird geprüft, ob in dem Block Wagons stehen. Es wird ihr Ladezustand abgefragt. Dabei wird mit dem letzten Wagon (der als Letztes im Block abgestellt wurde) im Block begonnen. Es werden dann nur Wagons in den Zug übernommen die den gleichen Ladezustand haben. Wird rückwärts gerechnet ein Wagon gefunden, der einen anderen Ladezustand hat, wird die Schleife beendet.

Die folgenden Code-Schnipsel werden für den Block benötigt, der als Ausziehgleis dient.


XML - Wagons im Zug gleich Variable charge

<!-- Pruefen, ob sich Wagons im Zuge befinden die gleich "charge" sind -->
<foreach table="carlist" condition="@%callerid% = %operatorid%" state="car %oid% = @charge">
	<!-- Hier können Fahrbefehle mit Zielblock stehen -->
	<!-- script verlassen -->
	<exit/>
</foreach>

Hier wird geprüft, ob die Lok Wagons mitführt und was mit diesen passieren soll, wenn der Ladezustand des Wagons = charge (Variable mit dem Inhalt loaded oder empty) ist. Diese Wagons werden zu einem neuen Güterzug zusammengestellt.

XML - Wagons im Zug ungleich charge

<!-- Untergruppe des letzten Wagons im Zug ermitteln -->
<!-- Pruefen ob sich im Zug Wagons befinden, die von "charge" abweichen -->
<foreach table="carlist" condition="@%callerid% = %operatorid%" state="car %oid% ! @charge">
	<!-- Hier passende Untergruppe ermitteln -->
	<switch var="%carsubtype%">
		<!-- Untergruppe definieren -->
		<case val="UNTERGRUPPE">
			<!-- Hier Fahrbefehl mit Ziel einfuegen -->
		</case>
		<!-- Hier evtl. weitere Untergruppen definieren -->
	</switch>
</foreach>

Hier wird geprüft, ob die Lok Wagons mitführt und was mit diesen passieren soll, wenn der Ladezustand des Wagons ! charge (Variable mit dem Inhalt loaded oder empty) ist. Dabei wird auch auf die Untergruppe der Wagons geprüft, damit diese im entsprechenden Abstell-Gleis abgestellt werden.

XML - Wo sind Wagons gleich Variable charge

<!-- Pruefen, wo sich noch Wagons befinden  = charge -->
<foreach table="carlist" state="car %oid% = BLOCK|car %oid% = BLOCK"  alltrue="false">
	<if state="car %oid% = @charge">
		<then>
			<!-- Hier Fahrbefehl Zielblock einsetzen-->
			<!-- Fahrbefehl Richtung Block -->
			<lc bkid="%callerid%" cmd="gotoblock" blockid="%carlocation%"/>
			<lc bkid="%callerid%" cmd="go"/>
			<!-- script verlassen -->
			<exit/>
		</then>
	</if>
</foreach>

Hier wird geprüft, wo sich noch Wagons befinden, die den Ladezustand gleich der Variablen charge haben.

XML- Wo sind Wagons ungleich charge

<!-- Pruefen, ob sich noch Wagons in BLOCK befinden und ungleich "charge" sind -->
<foreach table="carlist" state="car %oid% = BLOCK|car %oid% ! @charge">
	<!-- Hier Fahrbefehl Zielblock einsetzen-->
	<!-- script verlassen -->
	<exit/>
</foreach>

Hier wird geprüft, wo sich noch Wagons befinden, die den Ladezustand ungleich der Variablen charge haben.

XML - Zug auflösen

<foreach table="carlist" state="car %oid% = BLOCK|bk BLOCK = occupied">
	<!-- Wagons ent- oder beladen, je nach Einstellung der Variablen "Charge" -->
	<if condition="@charge = loaded">
		<then>
			<car id="%oid%" cmd="empty"/>
		</then>
		<else>
			<car id="%oid%" cmd="loaded"/>
		</else>
	</if>
	<!-- Wagong aus Zug entfernen -->
	<operator id="ZUG-ID" cmd="removecar" carids="%oid%"/>
</foreach>

Hier wird der Güterzug aufgelöst.

<lc bkid="BK1" cmd="classset" class="KLASSE"/>
<lc bkid="BK1" cmd="releasetrain"/>
<lc bkid="BK1" cmd="classdel" class="KLASSE"/>

Das Setzen einer Klasse im Güterzug bevor dieser von der Lok getrennt und aufgelöst wird, gibt die Möglichkeit, später eine freie Güterzug-Kennung für das Zusammenstellen zu verwenden.

XML - Zug zusammenstellen

<!-- Wagenliste aufrufen -->
<foreach table="carlist" state="car %oid% = BLOCK">
	<!-- Wagen zum Zug hinzufügen -->
	<operator id="ZUG-ID" cmd="addcar" carids="%oid%"/>
</foreach>

Hier wird ein Güterzug zusammengestellt.

XML - Wagons im Block

<!-- Pruefen welcher Wagen der Letzte in Block ist und welche Untergruppe er hat-->
<foreach table="carlist" condition="#%oid% = #Pos_%callerid%" state="car %oid% = %callerid%">
<!-- Wagen zum Zug hinzufügen -->
	<operator id="@%callerid%" cmd="addcar" carids="%oid%"/>
	<!-- Variable für Untergruppe setzen -->
	<vr id="var1" text="%carsubtype%"/>
	<vr id="var2" text="@var1"/>
	<!-- %lcid% als Zaehler setzen -->
	<vr id="%lcid%" value="#%lcid% + 1"/>
	<!-- Variable Pos_Block reduzieren -->
	<vr id="Pos_%callerid%" value="#Pos_%callerid% - 1"/>
	<!-- Nur einen Wagen nehmen -->
	<break/>
</foreach>
<!-- Pruefen, ob weitere Wagen der geleichen Untergruppe vorhanden sind -->
<while condition="#Pos_%callerid% > 0|@var1 = @var2" max="10">
	<!-- Pruefen welche Wagen davon im Block stehen, welche Position sie haben und beladen sind -->
	<foreach table="carlist" condition="#%oid% = #Pos_%callerid%" state="car %oid% = %callerid%">
		<!-- Prüfen, ob die Untergruppe gleich ist -->
		<if condition="@var1 = %carsubtype%">
			<then>
				<!-- Wagen zum Rangierzug hinzufügen -->
				<operator id="@%callerid%" cmd="addcar" carids="%oid%"/>
				<!-- Zaehler fuer Rangierfunktionen setzen -->
				<vr id="%lcid%" value="#%lcid% + 1"/>
				<!-- Variable Pos_Block reduzieren -->
				<vr id="Pos_%callerid%" value="#Pos_%callerid% - 1"/>
			</then>
			<else>
				<!-- sonst var2 ändern auf neue Untergruppe, damit Schleife beendet wird -->
				<vr id="var2" text="%carsubtype%"/>
			</else>
		</if>
	</foreach>
</while>

Hier werden Wagons, die der Güterzug abgestellt hat, in den Rangierzug übernommen. Dabei wird geprüft, welche Untergruppe der letzte Wagon hat. Es werden nur Wagons der gleichen Untergruppe übernommen.

XML - Leeren Zug finden

<foreach table="operatorlist" state="operator %oid% = goods|operator %oid% = KLASSE">
	<lc bkid="%callerid%" cmd="assigntrain" train="%oid%"/>
	<trace text="%oid%"/>
	<break/>
</foreach>

Hier kann man einen leeren Zug suchen und diesen für das Zusammenstellen eines neuen Güterzuges verwenden.

XML - Fahrbefehl Zielblock

<!-- Fahrbefehl mit Zielblock -->
<!-- <lc bkid="%callerid%" cmd="swap"/>
 -->
<lc bkid="%callerid%" cmd="gotoblock" blockid="BLOCK"/>
<lc bkid="%callerid%" cmd="go"/>
<!-- script verlassen -->
<exit/>

Dieser Script-Teil setzt einen neuen Fahrbefehl für die Lok. Je nach Ausfahrtrichtung und Konfiguration in den Blöcken muß hier zusätzlich ein SWAP eingefügt werden <lc bkid=”%callerid%” cmd=“swap”/>.

Das erweiterte Rangierbeispiel

Im Demo-Beispiel sind diese Code-Schnipsel ebenfalls verwendet und bieten die Möglichkeit, Rangierabläufe visualisiert nachzuvollziehen. Die Variable charge gibt dabei das Szenario vor. Hat die Variable charge als Inhalt “loaded” werden beladene Wagons zu einem Güterzug zusammengestellt und leere Wagons in die Abstellgleise gestellt. Beim Inhalt “empty” genau umgekehrtes Prinzip. Außerdem werden leere Wagons, die vor beladenen Wagons im Abstellgleis stehen in einen anderen Block verschoben, um sie zum Schluß wieder in das entsprechende Abstellgleis zurückzustellen. Im Textfeld sind zwei Eingabemöglichkeiten gegeben.

  • “Zusammenstellen” Mit dieser Eingabe wir ein Güterzug zusammengestellt.
  • “Aufloesen” (Achtung - Schreibweise beachten ! Keine Umlaute verwenden) Mit dieser Eingabe wird ein Güterzug aufgelöst.

Die Wagons müssen über das Menü manuell auf beladen gesetzt werden. Die Visualisierung ist darauf beschränkt, daß max. 6 Wagons zu einem Güterzug zusammengestellt und max. 3 Wagons in den Abstellgleisen abgestellt werden können! Es sollten also auch nur max. 3 Wagons im Block 8 abgestellt werden.

Dateien


Personal Tools