Voici une petite fonction pour simuler un Timer avec Lua, afin de gérer un ou plusieurs évènements (signaux, contact, panneau d’affichage, info-bulles, etc…).
Présentation
L’idée est la suivante : nous voulons qu’un train s’arrête devant un signal et après X secondes, redémarre et gère les signaux sur son trajet afin de respecter le cantonnement pour les autres trains derrière lui. Bien-sûr, nous pourrions utiliser le transit souple pour gérer le cantonnement en gare mais c’est juste un exemple d’une des possibilités offertes par cette fonction.
L’idéal serait d’avoir une fonction Timer qui tourne en continue ET qui sert également à gérer autre chose qu’un train. Tant qu’à faire, autant que cette fonction soit utilisée pour d’autres objets.
Bref, récapitulons nos besoins pour ce travail :
- Nous voulons intervenir sur le durée d’attente d’un train en gare,
- Déclencher un compteur à un moment et à un endroit donnés,
- Définir à l’avance un temps d’arrêt,
- Notre train doit pouvoir gérer les signaux rencontrés sur sa route.
Pour exécuter ce script, vous devez être en mode de conduite automatique.
Voici le script détaillé ligne par ligne :
clearlog() -- Efface l'écran de la fenêtre d'évènements
print("EEP Version ", EEPVer) -- Retourne la version EEP utilisée
nb_Inc = 0; -- Compteur pour l'incrémentation
nb_Ecart = 200; -- 200 millisecondes (EEPMain est appelée 5 fois par seconde)
nb_Sec = 0; -- Compteur des secondes
nb_Temps_Attente = 30; -- Temps d'attente du train en gare : 30 sec (exemple)
nb_Compteur_Attente = 0; -- Compteur pour l'attente au signal
bool_Contact_Franchi = nil; -- Boolean pour savoir si le contact n° 1 est franchi ou pas
-- FONCTION PRINCIPALE EEPMain(), appelée 5 fois par seconde
function EEPMain()
fnc_Calcul_Temps() -- Appelle la fonction fnc_Calcul_Temps()
return 1
end -- Fin de la fonction principale
-- Fonction calcul du temps en seconde
-- (Cette fonction peut être utilisée comme base de travail pour gérer plusieurs évènements à la fois)
function fnc_Calcul_Temps()
nb_Inc = nb_Inc + nb_Ecart; -- On rajoute le nombre d'incréments de 200 millisecondes
-- Opérateur modulo qui retourne la valeur 0 si nb_Inc = 1000 (1000 millisecondes = 1 seconde)
if (nb_Inc % 1000 == 0) then
nb_Sec = nb_Sec + 1; -- Incrémente une seconde à chaque fois
-- Si le contact n° 1 est franchi ET que le compteur d'attente = 0
if (bool_Contact_Franchi == true) then
-- On incrémente le compteur d'attente d'une seconde
nb_Compteur_Attente = nb_Compteur_Attente + 1;
-- Si le compteur d'attente est égal au temps d'attente initial
if (nb_Compteur_Attente == nb_Temps_Attente) then
print("Ouverture du signal n° 1"); -- Pour info
EEPSetSignal(1, 1); -- Ouvre le signal n° 1
bool_Contact_Franchi = false; -- Le contact a déjà été franchi
nb_Compteur_Attente = 0; -- Réinitialise le compteur à 0
end
end
-- print("Nombre de secondes écoulées : ", nb_Sec) -- Pour info
print("Nombre nb_Compteur_Attente : ", nb_Compteur_Attente) -- Pour info
nb_Inc = 0; -- Une seconde est écoulée (nouvelle incrémentation à calculer)
end
end -- Fin de la fonction
-- Une fois le point de contact véhicule franchi (avant le signal n° 1), positionne le boolean à true
function fnc_Commute_Contact_1()
print("Contact n° 1 franchi"); -- Pour info
bool_Contact_Franchi = true;
end -- Fin de la fonction
-- Après avoir redémarré, une fois le point de contact n° 2 franchi, position le boolean à false
-- pour repositionner le signal sur Arrêt pour le prochain train
function fnc_Commute_Contact_2()
EEPSetSignal(1, 2);
end -- Fin de la fonction
Développement
Pour notre exemple, nous avons besoin de placer deux points de contact en amont et en aval du signal n° 1 comme nous le montre la figure n° 1 :
Ouvrons déjà la fenêtre des propriétés du point de contact n° 1 :
Le nom de la fonction fnc_Commute_Contact_1 (sans les parenthèses !) est entrée dans la zone de saisie Fonction Lua (encadrée en rouge).
Lorsque la locomotive franchit le point de contact, la fonction est appelée et affecte la valeur true à la variable bool_Contact_Franchi.
La fonction fnc_Calcul_Temps() étant appelée 5 fois par seconde via la fonction principale EEPMain(), il est facile de savoir où nous en sommes avec le décompte du temps. Si une seconde est écoulée (opérateur modulo % à la ligne n° 22), on incrémente la variable nb_Sec de 1 seconde (ligne n° 23).
Après c’est juste de la logique : la variable bool_Contact_Franchi étant égale à true, le test est donc vrai et la variable nb_Compteur_Attente est incrémentée d’une seconde supplémentaire (ligne n° 27).
Donc… Tant que la variable nb_Compteur_Attente n’est pas égale à la variable nb_Temps_Attente (ligne n° 29), le test ne peut pas se réaliser et le programme continue à compter.
Inévitablement, au bout de 30 secondes, la variable nb_Compteur_Attente est égale à la variable nb_Temps_Attente (ligne n° 29) ainsi le test est donc vrai et peut s’exécuter. Il nous reste à utiliser la fonction LUA EEPSetSignal(1, 1) à la ligne n° 31 pour ouvrir le signal sur voie libre afin de redémarrer la locomotive et de réinitialiser les variables bool_Contact_Franchi à false et nb_Compteur_Attente à 0 (Lignes 32 et 33). En effet, ne pas réinitialiser ces variables conduirait au prochain passage à redémarrer la locomotive immédiatement.
Important : La fonction EEPSetSignal(n, n) contient deux paramètres. Le premier paramètre est le numéro du signal affiché dans la vue 2D ou dans la fenêtre de ses propriétés et le deuxième paramètre est la position (ordre donné au conducteur) du signal. Ici dans notre cas, 1 = voie libre, 2 = arrêt. Veuillez notez qu’en fonction des signaux, vous pouvez trouver plusieurs positions possibles. Dans ce cas, il convient de s’assurer du numéro exact de la position en regardant directement dans les propriétés du signal correspondant.
Dans les deux cas, la variable nb_Inc est réinitialisée à 0 (ligne n° 38) car une seconde vient de s’écouler.
Le signal étant ouvert, il convient maintenant de le refermer sur la position Arrêt et c’est justement le rôle de la fonction fnc_Commute_Contact_2.
Comme pour le premier point de contact, le nom de la fonction fnc_Commute_Contact_2 (toujours sans les parenthèses !) est entrée dans la zone de saisie Fonction Lua (encadrée en rouge).
Lorsque la locomotive franchit le point de contact, la fonction est appelée et commutera le signal sur Arrêt via la fonction LUA EEPSetSignal(1, 2) :
Dans un but pédagogique, nous avons volontairement insérer un deuxième point de contact véhicule après le signal pour appeler la fonction fnc_Commute_Contact_2. Nous aurions très bien pu nous contenter de mettre un contact pour signalisation en relation avec le signal n° 1 et de régler sa position sur Arrêt. Ainsi, lorsque la locomotive franchira le point de contact, le signal sera rebasculé sur Arrêt :
Ceci remplace la fonction LUA EEPSetSignal(1, 2) dans la fonction fnc_Commute_Contact_2.
A ce stade, vous pouvez supprimer le point de contact véhicule n° 2 situé après le signal et la fonction fnc_Commute_Contact_2 dans le script devenu inutile.
Vous avez la possibilité de télécharger ce projet en cliquant sur le bouton ci-dessous. Celui-ci a été réalisé avec la version EEP15.
Timer_FR
Vous pouvez également visualiser la démo de ce script en cliquant sur la vidéo ci-dessous :
Merci d'avoir lu cet article. Si vous avez des questions ou des suggestions, n’hésitez pas à nous en faire part en bas de cette page en commentaires.
Amusez-vous à lire un autre article. A bientôt !