Hello, vous reprendrez bien un p'tit timer (à consommer sans modération !)

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...).

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. L'idéal serait d'avoir une fonction Timer qui ne s'arrête jamais ET qui sert également à gérer autre chose qu'un train. Tant qu'à faire, autant que cette fonction soit utilisée pour d'autres trains ou objets !

Bref, récapitulons nos besoins pour ce travail :

  1. Nous voulons intervenir sur le durée d'attente d'un train en gare (ou tout autre objet),
  2. Déclencher un compteur quand nous l'avons décidé,
  3. Définir à l'avance un temps d'arrêt,
  4. Notre train doit pouvoir gérer les signaux rencontrés sur sa route.

Voici le script détaillé ligne par ligne :

clearlog() -- Efface l'écran de la fenêtre d'évènements

-- Déclaration des variables utilisées dans le script

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
bool_Contact_Franchi = null; -- Flag pour savoir si le contact n° 1 est franchi ou pas
nb_Temps_Attente = 60; -- Temps d'attente du train en gare : 60 sec (exemple)
nb_Compteur_Attente = 0; -- Compteur pour l'attente au signal


-- 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 calcul 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
-- additionne les secondes
nb_Sec = nb_Sec + 1; -- Incrémente une seconde
-- Si le contact n° 1 est franchi ET que le compteur d'attente = 0

if (int_Contact_Franchi == true and nb_Compteur_Attente == 0) then
nb_Compteur_Attente = 1; -- On début le comptage avec 1 seconde écoulée
-- Si le contact 1 est franchi ET que le compteur est > ou égal à 1
elseif (int_Contact_Franchi == true and nb_Compteur_Attente >= 1) then
-- On incrémente le compteur d'attente d'une seconde
nb_Compteur_Attente = nb_Compteur_Attente + 1;
-- Si le compteur d'attente est = 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
nb_Compteur_Attente = 0;-- Réinitialise le compteur à 0
end
end
print("Nombre de secondes écoulées : ", nb_Sec); -- Pour info
nb_Inc = 0; -- La 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), définir le flag à true

function fnc_Commute_Contact_1()

print("Signal n° 1 franchi"); -- Pour info
int_Contact_Franchi = true;

end -- Fin de la fonction


-- Après avoir redémarré, une fois le point de contact n° 2 franchi, définir le flag à false
-- pour repositionner le signal sur Stop pour le prochain train

function fnc_Commute_Contact_2()

int_Contact_Franchi = false;
EEPSetSignal(1, 2);
print("Fermeture du signal n° 1"); -- Pour info

end -- Fin de la fonction


Explications :

Rien de compliqué. Il suffit de placer un signal sur une voie. Un point de contact pour véhicule avant le signal et un autre point de contact pour véhicule après le signal.

Que se passe t'il ? La locomotive franchi le point de contact n° 1. Dans la fenêtre des propriétés de ce point de contact, j'ai rentré le nom de la fonction LUA fnc_Commute_Contact_1 sans les parenthèses !!

Cette fonction positionnera le flag int_Contact_Franchi à true (dès que la locomotive le franchira)

La fonction fnc_Calcul_Temps() étant appelée 5 fois par seconde, il est facile de savoir où nous en sommes avec le décompte du temps. Si une seconde est écoulée (opérateur modulo %), on incrémente la variable nb_Sec de 1 seconde.

Si le point de contact n° 1 a été franchi (donc le flag int_Contact_Franchi = true), il reste à tester la variable nb_Compteur_Attente. Si celle-ci est égale 0 alors le point de contact vient tout juste d'être franchi, ce qui veut dire que nous pouvons commencer à compter les secondes restantes par rapport à la variable nb_Temps_Attente.

Après c'est juste de la logique : Le "chronomètre" étant enclenché, désormais la variable nb_Compteur_Attente est supérieure ou égale à 1.

Donc... Tant que la variable nb_Compteur_Attente n'est pas égale à la variable nb_Temps_Attente, nous continuons à compter.

Maintenant, au bout de 60 secondes, enfin, la variable nb_Compteur_Attente est égale à la variable nb_Temps_Attente !

Il me reste à utiliser la fonction LUA EEPSetSignal(1, 1) pour ouvrir le signal sur voie libre pour redémarrer la locomotive.

Rien de compliqué. Il suffit de placer un signal sur une voie. Un point de contact pour véhicule avant le signal et un autre point de contact pour véhicule après le signal.

Dans la fenêtre des propriétés du 2ème point de contact, j'ai rentré le nom de la fonction LUA fnc_Commute_Contact_2 (toujours sans les parenthèses !)

Une fois que la locomotive franchira ce 2ème point de contact, la fonction LUA EEPSetSignal(1, 2), repositionnera le signal sur Arrêt, Stop ou Halt (selon votre version linguistique) ceci afin de respecter les cantonnements.

Voilà, dans un prochain tuto, je reprendrai cette base et nous verrons qu'il sera possible de greffer d'autres évènements sur la fonction de calcul du temps. Et cerise sur le gâteau, nous utiliserons l'enregistrement des fonctions pour les utiliser en Callback, (fonction de rappel) ce qui nous permettra d'automatiser encore plus le processus. Ceci explique aussi pourquoi j'ai testé avant tout la première seconde. J'aurai très bien pu tester uniquement si le nombre de secondes écoulées était seulement supérieur de 0. Patience, la réponse dans un prochain tuto !

Naturellement, il vous faudra être en mode de conduite automatique pour utiliser ce script.

Vous trouverez dans la section téléchargement en cliquant dans l'onglet LUA, la copie du projet pour le charger directement dans EEP. J'ai réalisé ce petit projet avec la version EEP15.

Vous pouvez également visualiser la démo de ce script en cliquant sur la vidéo ci-dessous :


Si vous avez des questions, n'hésitez pas à m'écrire.

Cordialement

Domi