Four aspect automatic block signalling

Jivora

New member
Hello.

Recently I started building the prototypical 100km long route Plzen - Cheb (in western Czech republic) in 1967 to 1999 status where so called "four-aspect-automatic-block signalling" was used. Automatic signals are half the braking distance apart and the sequence of signal aspects approaching the stop is: "clear" - "warning" - "repeated-warning" - "stop".

I decided to augment my set of signals for this (now historical) signalling pattern too. But here I found a problem. Due to the nature of my signal models and its work I need to use scripted signals. I used this setting something like this:

if (me.GetSignalStateEx()==0) {SetFXCoronaTexture("l-stop",coronaRed);}
if (me.GetSignalStateEx()==4) {SetFXCoronaTexture("l-opakovana",coronaWhite);}
if ((me.GetSignalStateEx()==4) or (me.GetSignalStateEx()==7)) {SetFXCoronaTexture("l-warning",coronaYellow);}
if (me.GetSignalStateEx()==8) {SetFXCoronaTexture("l-clear",coronaGreen);}

The desired aspect sequence is:
GREEN ---> YELLOW ---> YELLOW+WHITE ---> RED
TS2009 seems to understand the script (signals are not black) but it never displays the YELLOW light alone so the sequence is: green -> yellow+white -> red... Which (of course) is not the proper function of the 4 aspect AB and deliberately leads to SPAD for every train approaching signal at stop...
It seems that TS2009 thinks about (me.GetSignalStateEx()==7) signal status as if it was (me.GetSignalStateEx()==8) instead.

Don't you know how to override this problem?

Thanks a lot.
V. Raim
Jivora
 
state 7 is always an advance state. i do not see how missing that state can cause a SPAD for you unless your signals are also meant to control speed. by default, the state 4 should cause the train to slow down. state 7 does not. you can configure these in the signal config if you wish. be sure your signals container in the config has the 7 state available. unless you are using a completely new logic, which it doesnt look like, the default script checks what states are available against the config file. good luck!
 
Hi, thanks. The braking distance is 1000m. But signals are 500m from each other.

Yes I use it a bit other. I mean:
0 stop
4 repeated warning
7 warning
8 clear

Trainz will think that I have 500m braking distance and the aspect 7 is advance warning. But the driver will see the aspect "warning". This spreading braking distance to two subsequent blocks worked over whole line, including stations, so no confussion is possible. Just only my problem is that the trainz ignores "7" state and turns directly from 4 to 8.


I haven't included any "signals" conteiner. I use coronas in "effects" conteiner and *.gs file that specifies when is which corona displayed according to the me.GetSignalStateEx()== value and turnout position (medium speed etc.).

I am not particulary expert in trainz script and trainz internal logic.
 
Last edited:
you will need a signals container with the states defined in order for trainz to understand them.


Code:
signals
{
  0
  {
    light                               -1
  }
  
  4
  {
    light                               -1
  }
  
  7
  {
    light                               -1
  }
  
  8
  {
    light                               -1
  }
}

without this the only states available are 0, 4, 8 because it is assumed it is an old style signal with 3 states.

while you may be using the script to set the lights, the actual logic of the signal circuit is being handled by trainz (to my best understanding of what your script is doing) in which case it is checking the signals container to make sure the signal can display the states offered. if none is defined, they are limited to 0,4,8.

in addition, if you are only using the script to set the coronas and no meshes, or you are not altering the default logic behavior of a trainz signal, the script is not really needed as the signal container should be able to handle this. in the sample i posted, the light is -1 because it is script controlled. to use default control define the lights there in the container instead of using a script.
 
Last edited:
Hi, thanks,

I will try to implement this tomorrow. Thanks a lot.

The script is definitely needed. I set many things using it:
- 40, 60, 80, 100, 120 kph speed restrictions on turnouts set according to various turnout position (unlimited number of turnouts in train route) and its respective speeds. (proper aspect for 100% routes)
- various side protections ("speed 40kph and ???" instead of non-restrictive aspect if some other turnout is not aligned properly) or ("speed 100kph and warning" where is turnout in wrong position within 200m beyond the signal.)
- Override "stop" on signals
- "shunting permitted" aspect onto an occupied track

Most (if not all) is an ultra-heavy modification (but with 100% using of original principles) of an original script that already exists from an author who developed it for 2004 and unfortunately cannot help as he is out of the trainz since 2007.

I am also about to change from coronas over to LOD meshes for lights and light bars... Just to make the light more realistical from 20m as well as visible from up to 1300m...
 
Last edited:
Hi again

I applied your solution to testing signal and once again No state 7 for me... Do I need to declare using SignalStateEx somewhere else?


Thanks.
V.R.
 
Okay. The config.txt is here:



kind "mosignal"
function "TrackSignal"
light 1
trackside 2.5
region "Czech Republic"
type "Signals"
username "SSSR_ABlok_4"
script "cstt_sssr_ablok.gs"
class "csttSIG"


mesh-table
{
default
{
mesh "SSSR_4AB.im"
auto-create 1

effects
{
l-stop
{
kind "corona"
att "a.light1"
object-size 0.1
}

l-opakovana
{
kind "corona"
att "a.light0"
object-size 0.1
}

l-proceed
{
kind "corona"
att "a.light2"
object-size 0.1
}

l-caution
{
kind "corona"
att "a.light3"
object-size 0.1
}
}
}
}


signals
{
0
{
light -1
}

4
{
light -1
}

7
{
light -1
}

8
{
light -1
}
}
category-class "WA"
category-region-0 "CZ"
category-era-0 1950
asset-filename "SSSR_4AB"


kuid-table
{
red <kuid:77641:24802>
green <kuid:77641:24801>
yellow <kuid:77641:24800>
white <kuid:77641:24804>
}
kuid <kuid:266640:1579>
 
And here is the script that is called by the config.txt:
(this file is only modified by me. The original author released it for three aspect automatic block and I have his written consent to use parts or as a whole in my projects)



include "signal.gs"
include "gs.gs"
include "Browser.gs"


class csttSIG isclass Signal
{
Asset coronaRed, coronaGreen, coronaYellow, coronaWhite;
thread void Update(void);
bool bVylozene;
bool bZhasnute;
string mainSignalName;

// inicializace
public void Init(void)
{
coronaRed = GetAsset().FindAsset("red");
coronaGreen = GetAsset().FindAsset("green");
coronaYellow = GetAsset().FindAsset("yellow");
coronaWhite = GetAsset().FindAsset("white");
// Zachytávat události
AddHandler(me,"Signal","StateChanged","MainStateChange");
AddHandler(me,"csttSIG", "Setting", "Setting");
PostMessage(me,"csttSIG","Setting",0.3);

}

thread void Update(void)
{
// Volab telesa
SetFXCoronaTexture("l-caution",null);
SetFXCoronaTexture("l-stop",null);
SetFXCoronaTexture("l-opakovana",null);
SetFXCoronaTexture("l-proceed",null);
if (bZhasnute)
{
SetSignalState(0,"Zhasnute navestidlo!");
}
else
{
SetSignalState(AUTOMATIC,"");
if (me.GetSignalStateEx()==0) {SetFXCoronaTexture("l-stop",coronaRed);}
if (me.GetSignalStateEx()==4) {SetFXCoronaTexture("l-opakovana",coronaWhite);}
if (me.GetSignalStateEx()==7) {SetFXCoronaTexture("l-caution",coronaYellow);}
if (me.GetSignalStateEx()==8) {SetFXCoronaTexture("l-proceed",coronaGreen);}
}
}

void Setting(Message msg)
{
if (me==msg.src)
{
Update(); // Vylozeni
}
}

void MainStateChange(Message msg)
{
if (msg.src==me and !bZhasnute) Update();
}

// ###################################################šš
// Vlastnosti
// nacist promenne ze session
public void SetProperties(Soup db)
{
mainSignalName=db.GetNamedTag("mainSigName");
if (mainSignalName==""){SetFXNameText("name0"," ");} else {SetFXNameText("name0",mainSignalName);}
bVylozene=db.GetNamedTagAsBool("Vylozene");
bZhasnute=db.GetNamedTagAsBool("Zhasnute");
}

// ulozit promenne do session
public Soup GetProperties(void)
{
Soup db=Constructors.NewSoup();
db.SetNamedTag("mainSigName",mainSignalName);
db.SetNamedTag("Vylozene",bVylozene);
db.SetNamedTag("Zhasnute",bZhasnute);
return db;
}

// #############################################################š
// HTML Dialog
public string GetDescriptionHTML(void)
{
string html,sLink;
html="<html><body>";
html=html+"<table bgcolor=#C3CDD7 width=100% border=2><tr><td><img src=logo.bmp></td></tr></table>";
//html=html+"<table bgcolor=#C0C0C0 width=100% border=2><tr><tr><td bgcolor=#C3CDD7><font color=#000000>" + HTMLWindow.CheckBox("live://property/Vylozene", bVylozene) + "Vyložit návěstidlo o 45° ke koleji.</font></td></tr></table>";
html=html+"<table bgcolor=#C0C0C0 width=100% border=2><tr><tr><td bgcolor=#C3CDD7><font color=#000000>" + HTMLWindow.CheckBox("live://property/Zhasnute", bZhasnute) + "Zhasnté návěstidlo, trvale signál Stůj</font></td></tr></table>";
//sLink = mainSignalName;if (mainSignalName=="" or mainSignalName == " ") sLink = "Zadej";
//html=html+"<table bgcolor=#C0C0C0 width=100% border=2><tr><td bgcolor=#C3CDD7 width=80%><font color=#000000>Nápis na označovacím štítku:</font></td><td bgcolor=#C3CDD7 width=20%><font color=#800000><a href=live://property/mainSigName>"+sLink+"</a></font></td></tr>";
html=html+"</body></html>";
return html;
}

public void LinkPropertyValue(string id)
{
string[] kousek=Str.Tokens(id,"/");
if (kousek[0]=="Vylozene") {bVylozene=!bVylozene;}
if (kousek[0]=="Zhasnute") {bZhasnute=!bZhasnute;}
PostMessage(me,"csttSIG","Setting",0.3);
}

public string GetPropertyValue(string id)
{
string[] kousek=Str.Tokens(id,"/");
if (kousek[0]=="mainSigName") {string s = mainSignalName;return s;}
return "";
}

public string GetPropertyType(string id)
{
string[] kousek=Str.Tokens(id,"/");
if (kousek[0]=="mainSigName") { return "string,0,6"; }
else if (kousek[0]=="nextSigName") { return "list"; }
return "link";
}

public void SetPropertyValue(string id, string val)
{
string[] kousek=Str.Tokens(id,"/");
if (kousek[0]=="mainSigName"){mainSignalName = val;if (mainSignalName==""){SetFXNameText("name0"," ");}else{SetFXNameText("name0",mainSignalName);}}
PostMessage(me,"csttSIG","Setting",0.3);
}


public string GetPropertyName(string id)
{
string[] kousek=Str.Tokens(id,"/");
if (kousek[0]=="mainSigName") { return "Zadej označení návěstidla"; }
return "";
}


};
 
There is a "tag" that sets the distance a signal will "look down the line" for another signal and check if it's at "Caution". So in order for the "advance Caution" to show, the next signal must be in the present signal's overlap range.

Sorry I don't recall what the tag is off hand...
 
Hi, thanks.
I tried adding the "overlap 300" tag and I placed signals 250m apart (half the real value). Unfortunaltely it hasn't done what I wanted. It only caused normal "overlap" behaviour - stop on the signal when the vehicle was within 50 from the signal in advance...

What I want to make is this: (not my image) http://limbonic.wz.cz/navesti_na_ctyrznakem_AB_2.jpg

(The braking distance is marked on the top of the image - but it is irelevant for this case if it is advanced caution aspect or this 4AB prototypical setting. Four aspect ABS (AB4) is for high capacity for slow trains - still allowing trains to travel at line speed (70 to 100kph on this line). It is much like advanced caution. Slow 3000ton trains climbing at 1:66 grade at a speed of about 55kph just don't brake at single yellow and only cutoff. They brake at yellow+white. While Express train needs to start braking at single yellow to be able to stop by the red signal.
 
Last edited:
the problem is your script isnt calling inherited(); in the public void Init(void) function which is a requirement to pick up any information passed via the built in scripts. this should ALWAYS be called FIRST. without this, your signal is relegated to an old 1.3 style 3 aspect signal. if you have your signals container set the default logic should recognize 7 as an applicable state and your script should light those lights.

Code:
[COLOR=#333333]if (me.GetSignalStateEx()==0) {SetFXCoronaTexture("l-stop",coronaRed);}[/COLOR]
[COLOR=#333333]if (me.GetSignalStateEx()==4) {SetFXCoronaTexture("l-opakovana",coronaWhite);}[/COLOR]
[COLOR=#333333]if (([/COLOR][COLOR=#333333]me.GetSignalStateEx()==4) or ([/COLOR][COLOR=#333333]me.GetSignalStateEx()==7)) {SetFXCoronaTexture("l-caution",coronaYellow);}[/COLOR]
[COLOR=#333333]if (me.GetSignalStateEx()==8) {SetFXCoronaTexture("l-proceed",coronaGreen);} [/COLOR]

or

Code:
switch(me.GetSignalStateEx()){
    case EX_STOP:
        SetFXCoronaTexture("l-stop",coronaRed);
        break;
    case EX_CAUTION:
        SetFXCoronaTexture("l-opakovana",coronaWhite);
        break;
    case EX_ADVANCE_CAUTION:
        SetFXCoronaTexture("l-opakovana",coronaWhite);
        SetFXCoronaTexture("l-caution",coronaYellow);
        break;
    case EX_PROCEED:
        SetFXCoronaTexture("l-proceed",coronaGreen);
        break;
    default:
        break;
}

should produce what you want.
 
Last edited:
Hi, I recycle the old thread for the new purpose. I have another problem. I use (with written permision) some body else's old script which do I use comunication and html parts from. I have a branched html script for entering various variables such as 'speed rule' or 'points. The script is branched so I can enter various conditions for various switches setting. Now I need to transfer one setting from the "general" part of the html rule to "route specific". But here is however a problem for me. It appears well but when I click the "check-box" in one route - the parameter changes in all other routes too. Don't you know how to fix the problem? I need the setting to be settable individualy for each train-route. Here is the line of the script that serves my check-box:

html=html+"<tr><td colspan=2 bgcolor=#C3CDD7><font color=#000000>" + HTMLWindow.CheckBox("live://property/Opakovaci", bOpakovaci) + "Opakovane Ocekavej.</font></td></tr>";


Thanks.
 
Back
Top