Auteur Sujet: Modélisation logicielle d'un réseau - le système de Jean-Luc  (Lu 67467 fois)

Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1691
    • Voir le profil
Bonjour,

Ma petite contribution à la modélisation.

Ayant travaillé sur l'approche objet pour la gestion d'un gare cachée, les articles sont en attente de publication, j'ai fait des classes pour chaque type de voie : aiguille, voie d'extrémité de la gare et voie en gare. Les classes en question sont instanciées et les objets sont connectés pour former un graphe. Une recherche de chemin est ensuite faite pour trouver une voie libre ou pour relier l'entrée à une voie ou bien une voie à la sortie. Le défaut est que le graphe est orienté ce qui fait qu'un aiguillage va connaître les voies en aval mais pas en amont. Donc partant de l'entrée, on trouve une voie en gare, idem partant de la sortie mais on ne trouve pas un chemin de l'entrée vers la sortie par exemple.

Titillé par DDEFF, j'ai généralisé l'idée à un graphe où chaque nœud (bout de voie) connaît ses voisins. Comme exemple, j'ai choisi la gare de DDEFF que j'ai re-dessinnée en PECO code 55 (gare dont on peut déduire deux choses d'ailleurs : 1) Ça va coûté un bras à DDEFF, rien qu'en appareils de voie, il y en a pour 1300€, 2) DDEFF a de la place, la gare fait 4,2m de long. Bref je suis jaloux !  ;D)

Je vous mets le lien vers le PDF : La gare de DDEFF en PDF

J'ai donc défini une classe abstraite de base, Voie :

class Voie
{
  private:
    byte mIdentifiant;
    byte mDirection;
 
  protected:
    void fixeDirection(byte dir);
   
  public:
    Voie(byte identifiant) { mIdentifiant = identifiant; mDirection = AUCUNE_DIRECTION; }
    byte idVoie() { return mIdentifiant; }
    byte direction() { return mDirection; }
    virtual void connecteDeVoie(Voie *voie, byte connecteur) = 0;
    virtual bool creeCheminVers(byte identifiant, byte dir, Voie *venantDe = NULL) = 0;
};

Une voie a : 1) un identifiant, 2) une direction. On l'instancie en lui donnant un identifiant et par défaut il n'y a pas de direction fixée. La direction est fixée plus tard lorsque le graphe est construit.

connecteDeVoie permet d'établir une connexion entre deux voies, j'explique ci-dessous. creeCheminVers permet de trouver un chemin entre deux nœuds du graphe (entre deux bout de voies) en suivant une direction.

Ensuite, j'ai 5 classes :

1) les voies de garage qui n'ont qu'un seul connecteur : SORTANT



2) les voies normales qui ont 2 connecteurs : ENTRANT et SORTANT



3) les aiguillages qui ont 3 connecteurs : ENTRANT, SORTANT_DROIT et SORTANT_DEVIE



4) les traversées de jonction double (on peut ajouter également les simples) qui ont 4 connecteurs : ENTRANT, SORTANT, ENTRANT_BIS et SORTANT_BIS
5) les croisement qui ont également 4 connecteurs



Un sens normal de parcours est également défini : de entrant vers sortant.
« Modifié: mars 07, 2016, 06:00:03 pm par Jean-Luc »
Cordialement

Thierry

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 740
    • Voir le profil
Re : Modélisation logicielle d'un réseau - le système de Jean-Luc
« Réponse #1 le: mars 07, 2016, 06:15:49 pm »
Effectivement, le réseau est impressionnant...

DDEFF

  • Hero Member
  • *****
  • Messages: 730
    • Voir le profil
Re : Modélisation logicielle d'un réseau - le système de Jean-Luc
« Réponse #2 le: mars 07, 2016, 06:58:38 pm »
Merci Jean-Luc,

Sur le bras que ça va me coûter, c'est sûr. Je m'y suis déjà préparé psychologiquement   :( :(
Tu comprends aussi pourquoi je suis particulièrement motivé pour que ce soit commandé par du tout-Arduino, très bon marché  ;D

Sur la longueur, en employant des éléments Peco classiques, je vais sur les 4,20m, c'est vrai aussi. :( :(

En fait, le problème vient des 3 croisements.
Comme ils sont reliés aux TJD, si on les laisse tels quels, cela définit un écart de voie qui se répercute sur les autres écarts de voie, même sans croisements.
Il faut donc, pour raccourcir la gare, quasiment ne laisser du croisement que le croisement lui même (sans les petits bouts de droite qui l'accompagnent) et faire de même pour les TJD.
Comme je n'ai pas les 4,20 m (on s'en doutait), je pense ainsi réduire la longueur totale de la gare.
Y'a du boulot, du charcutage, mais je tiens à la caser quelque part.
A priori, j'ai une pièce de 3,42 m x 2,57 m et j'aurais bien tort de me plaindre.

Ta démarche m'intéresse au plus haut point, évidemment.
D'autant que je vais pouvoir comparer avec ma solution SGDD qui a été inventée pour cette gare. Et qui fonctionne.
Mais elle utilise une méthode vraiment ... non-conventionnelle (voir SGDD (1) et (2) )
J'ai le programme, pour les curieux.

J'appelle le sens "normal" sens "horaire", mais c'est un détail.
On peut peut-être s'éviter les zones genre "voie 0" en disant que ce n'est jamais que la partie de rails qui fait partie de l'aiquille 0 ? (quand la zone est très courte)

Bon courage !
Et merci pour le plan à l'échelle  ;D ;D
"Ce n'est pas le puits qui est trop profond, c'est ta corde qui est trop courte" (proverbe chinois)

Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1691
    • Voir le profil
Re : Modélisation logicielle d'un réseau - le système de Jean-Luc
« Réponse #3 le: mars 07, 2016, 08:02:44 pm »
La solution pour caser les 4m dans ta pièce est de courber la gare. Note que j'ai mis des voies de garage très généreuses  :)

Concernant les voies intermédiaires, du point de vu du graphe on peut effectivement les omettre mais je pense étendre le système au delà de la détermination des itinéraires.

Je continue.

Chaque classe dispose de fonction de connexion. Ainsi une voie de garage possède une unique fonction de connexion :

    void connecteAVoie(Voie &voie, byte connecteur);


qui va connecter SORTANT à la voie et au connecteur passés en argument.

Une voie normale possède 2 fonctions de connexion :

    void connecteSortantAVoie(Voie &voie, byte connecteur);
    void connecteEntrantAVoie(Voie &voie, byte connecteur);

qui vont connecter respectivement SORTANT et ENTRANT à la voie et au connecteur passés en argument. Si on utilise connecteSortantAVoie, une voie normale est connecté dans le sens normal (DIRECTION_AVANT) si on utilise connecteEntrantAVoie, elle est connectée dans le sens inverse (DIRECTION_ARRIERE).

Un aiguillage possède 3 fonctions de connexion :

    void connecteSortantDroitAVoie(Voie &voie, byte connecteur);
    void connecteSortantDevieAVoie(Voie &voie, byte connecteur);
    void connecteEntrantAVoie(Voie &voie, byte connecteur);

De la même manière, si on utilise connecteSortantDroitAVoie ou connecteSortantDevieAVoie, l'aiguillage est connecté en DIRECTION_AVANT et si on utilise connecteEntrantAVoie, il est connectée en DIRECTION_ARRIERE.

Idem pour les croisement et TJD :

    void connecteSortantAVoie(Voie &voie, byte connecteur);
    void connecteSortantBisAVoie(Voie &voie, byte connecteur);
    void connecteEntrantAVoie(Voie &voie, byte connecteur);
    void connecteEntrantBisAVoie(Voie &voie, byte connecteur);

Les connexions doivent être réalisées de manière compatible. C'est à dire qu'un élément de voie ne peut pas être connecté de telle sorte qu'il soit à la fois en DIRECTION_AVANT et DIRECTION_ARRIERE. Pour cela il faut connecter en parcourant les éléments dans une direction.

Je ne traite donc pas les boucles de retournement pour l'instant.

Les objets sont instanciés simplement. Par exemple, si on prend en bas à gauche VoieLibre0, Aiguille0, Voie0 et Voie1, on a

VoieNormale voieLibre0(VOIE_LIBRE_0);
Aiguillage aiguille0(AIGUILLE_0);
VoieNormale voie0(VOIE_0);
VoieNormale voie1(VOIE_1);

Une fois instanciés les objets, on les connecte. Il faut décider d'un direction de connexion, de la gauche vers la droite dans notre cas :

  voieLibre0.connecteSortantAVoie(aiguille0, ENTRANT);
  aiguille0.connecteSortantDevieAVoie(voie0, ENTRANT);
  aiguille0.connecteSortantDroitAVoie(voie1, ENTRANT);

Ici tous les objets sont en DIRECTION_AVANT. Mais, par exemple, en connectant de gauche à droite, l'aiguillage Aiguille3 sera en DIRECTION_ARRIERE.

On a donc une ligne par connecteur dans la gare. Pour la gare de DDEFF nous avons 110 connexions :

  /*
   * Connexion des voies de bas en haut et de gauche à droite
   */
  voieLibre0.connecteSortantAVoie(aiguille0, ENTRANT);
  aiguille0.connecteSortantDevieAVoie(voie0, ENTRANT);
  aiguille0.connecteSortantDroitAVoie(voie1, ENTRANT);
  voie0.connecteSortantAVoie(tjd0, ENTRANT_BIS);
  voie1.connecteSortantAVoie(tjd8, ENTRANT_BIS);
 
  voieLibre1.connecteSortantAVoie(tjd0, ENTRANT);
  tjd0.connecteSortantAVoie(voie3, ENTRANT);
  tjd0.connecteSortantBisAVoie(voie2, ENTRANT);
  voie3.connecteSortantAVoie(tjd8, ENTRANT);
  tjd8.connecteSortantAVoie(voie22, ENTRANT);
  tjd8.connecteSortantBisAVoie(voie21, ENTRANT);
  voie22.connecteSortantAVoie(aiguille12, SORTANT_DEVIE);
  aiguille12.connecteEntrantAVoie(voieGarage2, SORTANT);
  voie32.connecteSortantAVoie(aiguille12, SORTANT_DROIT);

  voieLibre2.connecteSortantAVoie(tjd1, ENTRANT);
  voie2.connecteSortantAVoie(tjd1, ENTRANT_BIS);
  tjd1.connecteSortantAVoie(voie8, ENTRANT);
  tjd1.connecteSortantBisAVoie(voie6, ENTRANT);
  voie8.connecteSortantAVoie(tjd12, ENTRANT);
  voie21.connecteSortantAVoie(tjd12, ENTRANT_BIS);
  tjd12.connecteSortantAVoie(voie27, ENTRANT);
  tjd12.connecteSortantBisAVoie(croisement2, ENTRANT_BIS);
  voie27.connecteSortantAVoie(tjd15, ENTRANT_BIS);
  croisement2.connecteSortantAVoie(tjd15, ENTRANT);
  tjd15.connecteSortantBisAVoie(voie31, ENTRANT);
  tjd15.connecteSortantAVoie(voie32, ENTRANT);
  voie31.connecteSortantAVoie(aiguille11, ENTRANT);
  aiguille11.connecteSortantDevieAVoie(voieGarage3, SORTANT);
  aiguille11.connecteSortantDroitAVoie(voieGarage4, SORTANT);

  voieLibre3.connecteSortantAVoie(tjd2, ENTRANT);
  voie6.connecteSortantAVoie(tjd2, ENTRANT_BIS);
  tjd2.connecteSortantAVoie(voie12, ENTRANT);
  tjd2.connecteSortantBisAVoie(voie11, ENTRANT);
  voie12.connecteSortantAVoie(tjd11, ENTRANT_BIS);
  voie20.connecteSortantAVoie(tjd11, ENTRANT);
  tjd11.connecteSortantBisAVoie(voie26, ENTRANT);
  tjd11.connecteSortantAVoie(croisement2, ENTRANT);
  voie26.connecteSortantAVoie(tjd14, ENTRANT);
  croisement2.connecteSortantBisAVoie(tjd14, ENTRANT_BIS);
  tjd14.connecteSortantAVoie(voie30, ENTRANT);
  tjd14.connecteSortantBisAVoie(voie29, ENTRANT);
  voie30.connecteSortantAVoie(aiguille10, ENTRANT);
  aiguille10.connecteSortantDroitAVoie(voieGarage5, SORTANT);
  aiguille10.connecteSortantDevieAVoie(voie34, ENTRANT);
  voie34.connecteSortantAVoie(aiguille14, SORTANT_DROIT);
  voie33.connecteSortantAVoie(aiguille14, SORTANT_DEVIE);
  aiguille14.connecteEntrantAVoie(voieGarage6, SORTANT);
 
  voieLibre4.connecteSortantAVoie(tjd4, ENTRANT);
  voie11.connecteSortantAVoie(tjd4, ENTRANT_BIS);
  tjd4.connecteSortantAVoie(voie16, ENTRANT);
  tjd4.connecteSortantBisAVoie(croisement0, ENTRANT_BIS);
  voie16.connecteSortantAVoie(tjd7, ENTRANT_BIS);
  croisement0.connecteSortantAVoie(tjd7, ENTRANT);
  tjd7.connecteSortantAVoie(voie20, ENTRANT);
  tjd7.connecteSortantBisAVoie(voie19, ENTRANT);
  voie19.connecteSortantAVoie(aiguille8, SORTANT_DROIT);
  voie25.connecteSortantAVoie(aiguille8, SORTANT_DEVIE);
  aiguille8.connecteEntrantAVoie(voie28, ENTRANT);
  voie28.connecteSortantAVoie(tjd16, ENTRANT);
  voie29.connecteSortantAVoie(tjd16, ENTRANT_BIS);
  tjd16.connecteSortantAVoie(voie33, ENTRANT);
  tjd16.connecteSortantBisAVoie(voieGarage7, SORTANT);

  voieLibre5.connecteSortantAVoie(tjd3, ENTRANT_BIS);
  voie10.connecteSortantAVoie(tjd3, ENTRANT);
  tjd3.connecteSortantAVoie(croisement0, ENTRANT);
  tjd3.connecteSortantBisAVoie(voie15, ENTRANT);
  voie15.connecteSortantAVoie(tjd6, ENTRANT);
  croisement0.connecteSortantBisAVoie(tjd6, ENTRANT_BIS);
  tjd6.connecteSortantAVoie(voie18, ENTRANT);
  tjd6.connecteSortantBisAVoie(croisement1, ENTRANT_BIS);
  voie18.connecteSortantAVoie(tjd10, ENTRANT_BIS);
  croisement1.connecteSortantAVoie(tjd10, ENTRANT);
  tjd10.connecteSortantAVoie(voie25, ENTRANT);
  tjd10.connecteSortantBisAVoie(voieGarage8, SORTANT);

  voieLibre6.connecteSortantAVoie(aiguille3, SORTANT_DROIT);
  voie5.connecteSortantAVoie(aiguille3, SORTANT_DEVIE);
  aiguille3.connecteEntrantAVoie(aiguille4, ENTRANT);
  aiguille4.connecteSortantDroitAVoie(voie9, ENTRANT);
  aiguille4.connecteSortantDevieAVoie(voie10, ENTRANT);
  voie9.connecteSortantAVoie(tjd5, ENTRANT_BIS);
  voie14.connecteSortantAVoie(tjd5, ENTRANT);
  tjd5.connecteSortantAVoie(croisement1, ENTRANT);
  tjd5.connecteSortantBisAVoie(voie17, ENTRANT);
  voie17.connecteSortantAVoie(tjd9, ENTRANT);
  croisement1.connecteSortantBisAVoie(tjd9, ENTRANT_BIS);
  tjd9.connecteSortantAVoie(voie24, ENTRANT);
  tjd9.connecteSortantBisAVoie(voie23, ENTRANT);
  voie24.connecteSortantAVoie(aiguille9, SORTANT_DROIT);
  voie36.connecteSortantAVoie(aiguille9, SORTANT_DEVIE);
  aiguille9.connecteEntrantAVoie(voieGarage9, SORTANT);

  voieGarage0.connecteAVoie(aiguille1, ENTRANT);
  aiguille1.connecteSortantDroitAVoie(voie5, ENTRANT); 
  aiguille1.connecteSortantDevieAVoie(voie4, ENTRANT);

  voieGarage1.connecteAVoie(aiguille2, SORTANT_DEVIE);
  voie4.connecteSortantAVoie(aiguille2, SORTANT_DROIT);
  aiguille2.connecteEntrantAVoie(voie7, ENTRANT);
  voie7.connecteSortantAVoie(aiguille5, ENTRANT);
  aiguille5.connecteSortantDevieAVoie(voieLibre9, ENTRANT);
  aiguille5.connecteSortantDroitAVoie(aiguille6, ENTRANT); 
  aiguille6.connecteSortantDroitAVoie(voieLibre8, ENTRANT); 
  aiguille6.connecteSortantDevieAVoie(aiguille7, ENTRANT);
  aiguille7.connecteSortantDroitAVoie(voie14, ENTRANT);
  aiguille7.connecteSortantDevieAVoie(voie13, ENTRANT);
  voie13.connecteSortantAVoie(tjd13, ENTRANT);
  voie23.connecteSortantAVoie(tjd13, ENTRANT_BIS);
  tjd13.connecteSortantAVoie(voie36, ENTRANT);
  tjd13.connecteSortantBisAVoie(voie35, ENTRANT);
  voie35.connecteSortantAVoie(aiguille13, ENTRANT);
  aiguille13.connecteSortantDroitAVoie(voieGarage10, SORTANT);
  aiguille13.connecteSortantDevieAVoie(voieLibre7, ENTRANT);

Je vous livre le sketch complet avec la recherche de deux chemins. Je n'ai pas tout testé, je viens de le terminer. Il peut être modifié pour ajouter des requêtes de chemin. Pour l'instant l'algorithme ne cherche qu'un seul chemin. Je vais rajouter la recherche de tous les chemins possibles, le calcul de l'intersection des chemins et donc l'établissement de plusieurs chemins simultanément.

Ça tourne sur un Uno en bouffant 33% de la flash et 52% de la SRAM
« Modifié: mars 07, 2016, 08:40:53 pm par Dominique »
Cordialement

DDEFF

  • Hero Member
  • *****
  • Messages: 730
    • Voir le profil
Re : Modélisation logicielle d'un réseau - le système de Jean-Luc
« Réponse #4 le: mars 07, 2016, 08:33:45 pm »
C'est d'une limpidité de cristal !  ;D
Et tu utilises des noms en clair pour les voies, pas des bytes. C'est un progrès aussi.  C'est beaucoup plus parlant ;D

Quelques bugs en lançant, mais c'est un programme non déverminé. Donc, rien de grave.

Pour mes 4 m, je ne suis pas inquiet. Il y a plein de solutions. Mais je vais essayer sans la tordre (j'aime bien les 2 x 2 diagonales bien droites).
Merci de t'en soucier.  ;)
"Ce n'est pas le puits qui est trop profond, c'est ta corde qui est trop courte" (proverbe chinois)

DDEFF

  • Hero Member
  • *****
  • Messages: 730
    • Voir le profil
Re : Modélisation logicielle d'un réseau - le système de Jean-Luc
« Réponse #5 le: mars 08, 2016, 09:20:50 am »
J'ai bien conscience que ça va "polluer" ton exposé, mais je me pose quelques questions :
#ifdef __AVR__
#include <avr/pgmspace.h>
#endif

#ifndef __AVR__
#include <iostream>
#define F(string) string
#define PROGMEM
Je ne connais pas ___AVR__ ?

Le simple fait de mettre #define DEBUG au début suffit pour pouvoir afficher les essais ?
Tu mets les sorties Serial.print() entre #ifdef DEBUG .... #endif et elles sont affichées et si tu dévalides le #define DEBUG pour ne plus les afficher.
C'est sympa, ça.

J'ai adoré le :
void afficheLigne(byte nb)
{
  while(nb--) {
    Serial.print('-');
  }
  Serial.println();
}
C'est tout bête, mais marrant.

Et, dans mes efforts pour comprendre les pointeurs, je choisis "venantDe". Exemple :
bool Aiguillage::creeCheminVers(byte identifiant, byte dir, Voie *venantDe)
{
  if (idVoie() == identifiant) return true;
  else {
    if (direction() == dir) {
      if (mVoieSortantDroit != NULL) {
        if (mVoieSortantDroit->creeCheminVers(identifiant, dir, this)) {
          afficheNomVoie(idVoie());
          Serial.println(F(": droit"));
          return true;
        }
        else if (mVoieSortantDevie != NULL) {
          if (mVoieSortantDevie->creeCheminVers(identifiant, dir, this)) {
            afficheNomVoie(idVoie());
            Serial.println(F(": devie"));
            return true;
          }
          else return false;
        }
        else return false;
      }
      else return false;
    }
    else {
      if (mVoieEntrant != NULL) {
        if (mVoieEntrant->creeCheminVers(identifiant, dir, this)) {
          afficheNomVoie(idVoie());
          if (venantDe == mVoieSortantDroit) {
            Serial.println(F(": droit"));
          }
          else {
            Serial.println(F(": devie"));
          }
          return true;
        }
        else return false;
      }
      else return false;
    }
  }
}

Au début, il y a une étoile : Voie *venantDe
J'en déduis que c'est un pointeur ?

Puis, un peu plus loin dans un test, tu as : if (venantDe == mVoieSortantDroit)
Et là, c'est le contenu de la variable ?

Peux-tu m'expliquer la nuance ? C'est là que je bute.
Dommage, c'est une notion fondamentale.
Pour moi, si *venantDe est un pointeur, pour avoir le contenu, tu mets &venantDe...

D'avance, merci  :D

"Ce n'est pas le puits qui est trop profond, c'est ta corde qui est trop courte" (proverbe chinois)

Thierry

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 740
    • Voir le profil
Re : Modélisation logicielle d'un réseau - le système de Jean-Luc
« Réponse #6 le: mars 08, 2016, 10:34:54 am »
Si je peux me permettre, je m'insinue...

Le test vérifie que l'argument venantDe et la donnée membre de la classe mVoieSortantDroit pointent vers la même voie. Si les pointeurs sont égaux, alors évidemment les contenus aussi ! Mais là on veut absolument s'assurer qu'on ne parle pas de choses différentes mais exactement de la même voie, donc on compare les pointeurs.

Et non, si venantDe est un pointeur, alors *venantDe est son contenu, et &venantDe est le pointeur contenant la valeur du pointeur venantDe !

Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1691
    • Voir le profil
Re : Modélisation logicielle d'un réseau - le système de Jean-Luc
« Réponse #7 le: mars 08, 2016, 11:51:09 am »
Je complète la réponse de Thierry avec un petit dessin que j'ai fait en parallèle  :)

J'ai bien conscience que ça va "polluer" ton exposé, mais je me pose quelques questions :

Pas du tout, ça ne pollue rien, un forum c'est fait pour discuter  :)

Citer
#ifdef __AVR__
#include <avr/pgmspace.h>
#endif

#ifndef __AVR__
#include <iostream>
#define F(string) string
#define PROGMEM
Je ne connais pas ___AVR__ ?

__AVR__ est un symbole défini par le compilateur quand il compile pour AVR et donc pour Arduino Uno/Nano. Sinon il ne l'est pas. J'utilise ça pour émuler des macros et des classes Arduino sur mon Mac. Ça me permet de compiler et exécuter le programme sur mon Mac, sans Arduino, et de mettre au point dans un environnement plus confortable.

Citer
Le simple fait de mettre #define DEBUG au début suffit pour pouvoir afficher les essais ?
Tu mets les sorties Serial.print() entre #ifdef DEBUG .... #endif et elles sont affichées et si tu dévalides le #define DEBUG pour ne plus les afficher.
C'est sympa, ça.

C'est ça


Citer
Et, dans mes efforts pour comprendre les pointeurs, je choisis "venantDe". Exemple :
bool Aiguillage::creeCheminVers(byte identifiant, byte dir, Voie *venantDe)
{
  if (idVoie() == identifiant) return true;
  else {
    if (direction() == dir) {
      if (mVoieSortantDroit != NULL) {
        if (mVoieSortantDroit->creeCheminVers(identifiant, dir, this)) {
          afficheNomVoie(idVoie());
          Serial.println(F(": droit"));
          return true;
        }
        else if (mVoieSortantDevie != NULL) {
          if (mVoieSortantDevie->creeCheminVers(identifiant, dir, this)) {
            afficheNomVoie(idVoie());
            Serial.println(F(": devie"));
            return true;
          }
          else return false;
        }
        else return false;
      }
      else return false;
    }
    else {
      if (mVoieEntrant != NULL) {
        if (mVoieEntrant->creeCheminVers(identifiant, dir, this)) {
          afficheNomVoie(idVoie());
          if (venantDe == mVoieSortantDroit) {
            Serial.println(F(": droit"));
          }
          else {
            Serial.println(F(": devie"));
          }
          return true;
        }
        else return false;
      }
      else return false;
    }
  }
}

Au début, il y a une étoile : Voie *venantDe
J'en déduis que c'est un pointeur ?

C'est ça.

Citer
Puis, un peu plus loin dans un test, tu as : if (venantDe == mVoieSortantDroit)
Et là, c'est le contenu de la variable ?

Non, je compare les pointeurs.

En effet, chaque voie connaît ses voisines via des pointeurs. Par exemple quand on écrit :

voie8.connecteSortantAVoie(tjd12, ENTRANT);
voie21.connecteSortantAVoie(tjd12, ENTRANT_BIS);

ça donne ça



Quand creeCheminVers de la TJD est appelée, venantDe sert à savoir de où on vient, voie8 ou voie21 ? En le comparant avec les deux pointeurs arrière, on détermine la position de l'aiguille d'entrée de le TJD. Idem quand on entre dans une aiguille par la branche déviée ou la branche droite
Cordialement

DDEFF

  • Hero Member
  • *****
  • Messages: 730
    • Voir le profil
Re : Modélisation logicielle d'un réseau - le système de Jean-Luc
« Réponse #8 le: mars 08, 2016, 06:00:08 pm »
Donc, pour voir ce que j'ai compris :

Sur ton schéma, Jean-Luc, chaque flèche est un pointeur.

Pour tjd12, pointeur de mVoieEntrant = voie8 et pointeur de mVoieEntrantBis = voie21
De même pour voie8, pointeur de mVoieSortant = tjd12 et pour voie21, pointeur de mVoieSortant = tjd12

Maintenant, il faut l'écrire en code compilable.

Dans le test if (venantDe == mVoieSortantDroit) {..},

mVoieSortantDroit est un élément de la classe Voie et donc ce n'est pas un pointeur.
Il s'ensuit que venantDe n'est pas non plus un pointeur pour qu'on compare des choses de même nature.

Il y a deux mVoieSortantDroit : celui de la voie8 et celui de la voie21 et il faut donc choisir.

Tu es dans bool traverseeJonctionDouble(...), donc tu es sur la tjd12 et tu recherches les antécédents pour pouvoir créer un chemin qui va venir soit de la voie8, soit de la voie21.
Quand tu rentres comme argument de bool(...) Voie *venantDe, tu veux préciser en entrée que tu viens de la voie8 ou que tu viens de la voie21.

Admettons qu'on vienne de la voie8.

Est-ce que je peux dire, dans tjd12, que Voie *venantDe = voie8 ?

Par ailleurs, dans voie8, mSortantDroit, pointe vers tjd12.
Est-ce que je peux dire, dans voie8 cette fois, que *mSortantDroit = tjd12 ?

Et là, je bloque. Que valent venantDe et mSortantDroit  ? ???









"Ce n'est pas le puits qui est trop profond, c'est ta corde qui est trop courte" (proverbe chinois)

Dominique

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 2870
  • 100% Arduino et N
    • Voir le profil
Re : Modélisation logicielle d'un réseau - le système de Jean-Luc
« Réponse #9 le: mars 08, 2016, 06:41:51 pm »
Salut Jean-Luc,

Il y a un truc qui m'intéresserait : comment mettre des images dans le dossier www.locoduino.org/pic ?
C'est peut-être réservé à l'admin ?

En tout cas c'est mieux de pouvoir mettre les images au bon endroit dans le texte

Danke !
Dominique
Cordialement,
Dominique

Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1691
    • Voir le profil
Re : Modélisation logicielle d'un réseau - le système de Jean-Luc
« Réponse #10 le: mars 09, 2016, 12:12:21 am »
Sur ton schéma, Jean-Luc, chaque flèche est un pointeur.

Oui

Citer
Pour tjd12, pointeur de mVoieEntrant = voie8 et pointeur de mVoieEntrantBis = voie21
De même pour voie8, pointeur de mVoieSortant = tjd12 et pour voie21, pointeur de mVoieSortant = tjd12

Oui

Citer
Dans le test if (venantDe == mVoieSortantDroit) {..},

mVoieSortantDroit est un élément de la classe Voie et donc ce n'est pas un pointeur.

Non, mVoieSortantDroit est un pointeur vers un objet de type Voie. Regarde dans la déclaration de la classe Aiguille :

    Voie *mVoieSortantDroit;


Citer
Il y a deux mVoieSortantDroit : celui de la voie8 et celui de la voie21 et il faut donc choisir.

Non,  mVoieSortantDroit est une donnée membre de la classe Aiguille.

Citer
Tu es dans bool traverseeJonctionDouble(...), donc tu es sur la tjd12 et tu recherches les antécédents pour pouvoir créer un chemin qui va venir soit de la voie8, soit de la voie21.
Quand tu rentres comme argument de bool(...) Voie *venantDe, tu veux préciser en entrée que tu viens de la voie8 ou que tu viens de la voie21.

Admettons qu'on vienne de la voie8.

Est-ce que je peux dire, dans tjd12, que Voie *venantDe = voie8 ?

Non. Comme voie8 a passé this dans l'argument venantDe, venantDe est un pointeur vers voie8, c'est à dire &voie8. On compare chacun des pointeurs vers les voies précédentes : mVoieEntrant et mVoieEntrantBis à venantDe. L'un d'entre eux étant un pointeur vers voie8, il est égal à venantDe et de cette manière tu sais d'où on vient et tu connais la position de l'aiguille d'entrée de la TJD

Citer
Par ailleurs, dans voie8, mSortantDroit, pointe vers tjd12.
Est-ce que je peux dire, dans voie8 cette fois, que *mSortantDroit = tjd12 ?

Je ne suis pas sûr de comprendre ce que tu veux écrire. Ton égal est le égal mathématique ou l'affectation ?
« Modifié: mars 09, 2016, 12:20:09 am par Jean-Luc »
Cordialement

Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1691
    • Voir le profil
Re : Modélisation logicielle d'un réseau - le système de Jean-Luc
« Réponse #11 le: mars 09, 2016, 12:18:49 am »
Salut Dominique

Il y a un truc qui m'intéresserait : comment mettre des images dans le dossier www.locoduino.org/pic ?
C'est peut-être réservé à l'admin ?

C'est réservé à l'admin effectivement.

Eventuellement vous pouvez vous faire un article bidon dont vous ne demandez pas la publication et vous chargez vos images dans cet article. Il suffit ensuite de récupérer l'URL de l'image pour pouvoir l'insérer dans le forum. Comme ceci :

Cordialement

DDEFF

  • Hero Member
  • *****
  • Messages: 730
    • Voir le profil
Re : Modélisation logicielle d'un réseau - le système de Jean-Luc
« Réponse #12 le: mars 09, 2016, 10:38:18 am »
Merci Jean-Luc pour ta patience...

Mais je crois avoir compris.

Dans la class Voie, ligne 222 tu définis :
    virtual bool creeCheminVers(byte identifiant, byte dir, Voie *venantDe = NULL) = 0;
Donc venantDe est un pointeur et tu l'initialises à NULL.

Également dans la class Aiguille, ligne 452, tu définis :
    virtual bool creeCheminVers(byte identifiant, byte dir, Voie *venantDe = NULL);
Donc il y a des venantDe qui servent quand on est sur une voie et d'autres qui servent quand on est sur une aiguille.

En fait, ce pointeur est crée et initialisé à NULL dans tous les creeCheminVers(...), comme donnée d'entrée.

Dans la class Aiguille, ligne 441, tu définis :
    Voie *mVoieSortantDroit;Donc mVoieSortant droit est un pointeur.

Quelques lignes plus bas, ligne 458, tu lui affectes la valeur :
    mVoieSortantDroit = &voie;
Là, l'affectation est claire pour moi.

Mais pour venantDe, c'est plus complexe et je ne la trouvais pas.

En fait, tu la passe avec le this ligne 295 :
      if (mVoie->creeCheminVers(identifiant, dir, this))
Là, c'est pour VoieEnImpasse, mais il y en a pour tous les éléments.

Et après, effectivement, tu compares les deux pointeurs pour la TJD ligne 792 :
      if (venantDe == mVoieEntrant && mVoieSortant != NULL)Et comparer des pointeurs, c'est comme comparer les contenus.

C'est bon ?  ???

J'ai relu la prose de Thierry et ça m'a aussi aidé.
J'avais cru comprendre ses articles, mais finalement pas complètement...

Autre chose :

On démarre par la class Voie.
class VoieEnImpasse hérite de Voie
class VoieNormale hérite de Voie

Puis class VoieMuli
class Aiguille hérite de VoieMulti
class Croisement hérite de VoieMulti

class TraverseeJonctionDouble hérite de Croisement

C'est quand même très souple
"Ce n'est pas le puits qui est trop profond, c'est ta corde qui est trop courte" (proverbe chinois)

Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1691
    • Voir le profil
Re : Modélisation logicielle d'un réseau - le système de Jean-Luc
« Réponse #13 le: mars 09, 2016, 10:58:07 am »
Tout bon :)
Cordialement

DDEFF

  • Hero Member
  • *****
  • Messages: 730
    • Voir le profil
Re : Modélisation logicielle d'un réseau - le système de Jean-Luc
« Réponse #14 le: mars 09, 2016, 11:44:09 am »
Yes !!!! ;D ;D ;D ;D

A bientôt 60 balais (le 26/04, le jour de Tchernobyl  :D), c'est quand même plus dur.
"Ce n'est pas le puits qui est trop profond, c'est ta corde qui est trop courte" (proverbe chinois)