Voir les contributions

Cette section vous permet de consulter les contributions (messages, sujets et fichiers joints) d'un utilisateur. Vous ne pourrez voir que les contributions des zones auxquelles vous avez accès.


Messages - Pierre59

Pages: 1 ... 17 18 [19]
271
Bonjour

J'en remet une couche (d'objets), voici un squelette d'itinéraire.

Il faut d'abord quelque classes accessoires  :

class Zone {
  boolean etat; // etat de la Zone (libre ou occupee)
public:
  boolean libre() { return !etat; }
};

class Aiguille {
public:
  boolean directer() { /* commande de l'aiguille */ return true; }
  boolean devier()   { /* commande de l'aiguille */ return true; }
};

class Signal {
public:
  boolean ouvrir() { /* commande du signal */ return true; }
  boolean fermer() { /* commande du signal */ return true; }
} ;

Puis quelques variables :

TB iTB; TD iTD; BT iBT; DT iDT; // itineraires
Zone za,zb,zc; // zones
Aiguille a1,a2,a3; // aiguilles
Signal s1,s2,s3; // signaux

La classe de base "Itineraire" contient tout ce qui est commun à tous les itinéraires :

class Itineraire { // classe de base des itineraires
  byte etat; // l'etat de l'itineraire (libre, en attente, forme, ... )

public:
  boolean libre() { return etat==0; }
  boolean formation()    { if (formable()) return former(); else return false; }
  boolean destruction() { if (deformable()) return deformer(); else return false; }
   
protected:
  virtual boolean formable();
  virtual boolean former();
  virtual boolean deformable();
  virtual boolean deformer();
 
// methodes utilitaires
protected:
  boolean libre(Zone &a) { return a.libre(); }
  boolean libres(Zone &a,Zone &b) { return a.libre() && b.libre(); }
  boolean libres(Zone &a,Zone &b,Zone &c) { return a.libre() && b.libre()&& c.libre(); }
  boolean libres(Zone &a,Zone &b,Zone &c,Zone &d) { return a.libre() && b.libre() && c.libre() && d.libre(); }
  // ...
  boolean libre(Itineraire &a) { return a.libre();
  boolean libres(Itineraire &a,Itineraire &b) { return a.libre() && b.libre(); }
  boolean libres(Itineraire &a,Itineraire &b,Itineraire &c) { return a.libre() && b.libre()&& c.libre(); }
  boolean libres(Itineraire &a,Itineraire &b,Itineraire &c,Itineraire &d) { return a.libre() && b.libre() && c.libre() && d.libre(); }
   // ...
  };

Les méthodes formation() et deformation() permettent de former et de détruire l'itinéraire (elles peuvent êtres enrichies si nécessaire). Elles peuvent êtres appellées par les boutons de commande et/ou par d'autres objets (Zone par exemple) pour des destructions automatiques.

Les méthodes formable(), former(), deformable() et deformer() sont propres à un itinéraire particulier, elles seront définies dans des classes dérivées, une par itinéraire (c'est pour cela qu'elles sont marquées virtuelles).

Les méthodes libre(s)(…) sont des méthodes utilitaires pour faciliter l'écriture des méthodes précédentes. Pour ne pas faire de copies inutiles les objets sont appelés par référence. (on peut aussi utiliser des méthodes avec un nombre d'arguments variables).

Voici pour finir un exemple d'itinéraire particulier (une des classes correspondant à chaque itinéraire) :

class TC:public Itineraire { // un itineraire particulier de T vers C
  virtual boolean formable() { return
    libres(iTB,iTD,iBT,iDT) && // enclanchements entre itineraires
    libres(za,zb,zc); // enclanchements sur les zones
  }
  virtual boolean former() { return a1.devier() && a2.directer() && s1.ouvrir(); }
  virtual boolean deformable() { return libres(za,zb,zc); }
  virtual boolean deformer() { return s1.fermer(); }
};


La méthode formable() gère les enclanchements.
La méthode former() établit l'itinéraire en positionnant les aiguilles et en ouvrant le signal.
La méthode deformable() s'assure que l'itinéraire peut être détruit.
La méthode deformer() ferme le signal.

Bien sur d'autres tests et d'autres actions peuvent êtres ajoutées dans ces méthodes.

Vous voyez ce n'est pas si compliqué que cela, il faut bien entendu écrire toutes les classes itinéraire particulier, mais c'est assez répétitif.
Il est facile de modifier des itinéraires d'ajouter des itinéraires …
Il est facile de faire la mise au point avec des affichages sur le moniteur série.
Bon courage !

Pierre

272
Bonjour

Je voudrais monter ici une approche objet de la modélisation logicielle d'un réseau.

Mon réseau est constitué d'un ovale à double voie sur lequel il y a une coulisse et une gare moyenne. Cette gare comporte plusieurs voies à quai, une partie marchandises et un dépot, de la gare part aussi une voie unique finissant à une petite gare terminus.

Le réseau comporte une trentaine d'aiguilles, une trentaine de zones et une dizaine de cantons.

Le réseau est géré par un très gros programme sur PC. Une dizaine de cartes électroniques sur deux bus I2C font l'interface entre le PC et le réseau.

Le programme sur PC comporte plusieurs parties :

- une partie de gestion des cartes électroniques (rétrosignalisation, souris, commandes des alimentations, des aiguilles, des signaux …)

- une partie de gestion de TCOs sur l'écran du PC (il pourrait avoir un TCO réel)

- une grosse partie de gestion du fonctionnement du réseau, cette partie reçoit toutes les infos du réseau (rétrosignalisation …) et toutes les commandes des utilisateurs (souris, itinéraires, …), elle sait ainsi toujours ce qui se passe sur le réseau. Cette partie est réalisée en programmation objet et ne comporte pas de tables, la description du réseau se fait par les liens entre les objets et les méthodes (fonctions) de ces objets.

Je vais essayer de décrire les principales classes et leur fonctionnement en détaillant un peu plus la classe Zone. Mes classes sont en Java mais je vais essayer de les présenter à la C++ (longtemps que je n'ai pas fait de C++ objet).

La classe essentielle est la classe Zone :

class Zone {
   String nom;
   boolean etat; // libre ou occupé
   Train train; // le train dans la zone
   Signal signalPair,signalImpair; // les signaux éventuels de la zone

   Zone(…) {…} // constructeur

   virtual Zone suivantePaire(); // la zone suivante paire (éventuellement vide)
   virtual Zone suvanteImpaire(); // la zone suivante impaire (éventuellement vide)

   virtual void actions(); // les actions spécifiques à faire en cas d'occupation
   virtual void desactions(); // les actions spécifiques à faire en cas de libération

   boolean occupee() { return etat; } // méthode utilitaire
   boolean libre() { return !etat; } // méthode utilitaire

   void occuper() { // appelée par la rétrosignalisation
      // fait tout ce qu'il y a à faire en cas d'occupation (actions communes à toutes les zones)
      actions(); // fait les actions spécifiques à une zone
   }
   void liberer() { // appelée par la rétrosignalisation
      // fait tout ce qu'il y a à faire en cas de libération (actions communes à toutes les zones)
      desactions(); // fait les actions spécifiques à une zone
   }
}

chaque zone réelle fait l'objet d'une classe héritant de la classe Zone, voici un exemple :

class Z9 : Zone { // héritage de Zone
   
   Z9(…) {…} // constructeur

   void actions() { aubiner(c3,c5); } // fermeture de signaux (occupation)
   void desactions() { detruire(XA,XB,XC); } // destruction d'itinéraires (liberation)

   Zone suivantePaire() { return z11; } // la zone paire suivante (toujours la meme)
   Zone suivantePaire() { if (a3.directe()) return z9; else return z7; } // la zone impaire suivante (dépends de la position de l'aiguille a3)
}

Ces classes zones décrivent la géométrie du réseau et les interactions entre les différentes parties. Elles précisent les liens entre les zones (de façon dynamique en fonction de la position réelle des aiguilles), l'emplacement des signaux, … Tout le réseau est ainsi décrit.

Les autres classes principales s'articulent autour des zones :

- la classe signal gère les signaux (lumineux et mécaniques), elle calcule les feux en fonction des occupations de zones, des signaux adjacents et de la position des aiguilles, elle fait le cantonnement pour les parties du réseau qui en sont équipées) et commandes les signaux.

- la classe Aiguille garde la position d'une l'aiguille et fait l'interface avec l'électronique pour les commandes

- la classe Train mémorise les informations sur un train ( sens, vitesse, nom de l'engin moteur, adresse DCC, …)

- la classe Itineraire réalise les itinéraires (une centaine), elle fait les enclanchements entre itinéraires, la mémorisation/création/destruction des itinéraires. Elle est organisée comme la classe Zone, la classe Itineraire contient tout ce qui est commun à tous les itinéraires, des classes (héritant de la classe Itineraire) contenant  les parties spécifiques.


Cette programmation objet bien que assez technique est très puissante, elle peut gérer des petits ou grands réseaux,, elle évite les tables (avec leur problèmes de construction/mise à jour, …), elle facilite grandement des modification ponctuelles du réseau (seules quelques classes sont à modifier ou à créer) et facilite la mise au point au début. Elle nécessite un processeur assez puissant. Du point de vue allocation mémoire les objets sont tous crées à l'initialisation du programme, l'accroissement des variables est linéaire avec l'accroissement du réseau.

Cette programmation n'évite pas (comme avec d'autres types de  programmations) les problèmes de synchronisation dans le cas de fonctionnement multi-tâches et/ou de programmation évenementielle (sur interruptions).

Voila, n'hésitez pas à poser des questions, et franchissez le pas de la programmation objet (voir les cours sur les objets et l'héritage dans une autre partie du site)

Pierre



273
Bonjour

Personnellement je fais des allocations/désallocations dynamiques dans le "loop()", pour des "buffers" d'images, mais je prends beaucoup précautions sur l'ordre des allocations et des désallocations.

Pierre

274
Bonjour

Je pense que le problème vient de l'erreur :

sketch_may27a:8: error: array bound is not an integer constant

la taille d'un tableau doit être une constante et pas une variable.

En C sur un ordinateur on ferait un "malloc()", mais sur Arduino c'est beaucoup plus délicat.

Pierre

275
Vos projets / Re : Bus I2C
« le: mai 12, 2015, 11:24:28 am »
Bonjour

J'utilise un bus I2C pour la communication entre les cartes électroniques de mon réseau. Toutes les cartes comportent un ATmega Atmel et sont proches les unes des autres. Je n'ai pas de problèmes de communications.

Pour communiquer avec le PC, j'ai un adaptateur USB I2C avec en circuit FTDI USB-parallèle et un ATmega8 pour l'I2C (fait maison). Mais je pense qu'un Arduino peut faire aussi l'affaire.

Pierre

276
Vos projets / Re : Re : Commande d'itinéraires par arduino
« le: mars 15, 2015, 09:09:40 am »
Sur ton schéma, j'aurais 3 coupures à faire en plus :
Quand un train va de Z en E, une fois qu'il a libéré la première aiguille, on doit pouvoir aller de Z en C
Quand il a libéré la deuxième aiguille, on doit pouvoir aller de Z en D.
Par ailleurs, quand on va de T vers le haut, on doit pouvoir aller de Z en T dès que la première aiguille est libre.
Évidemment, ça complique ...  :(
Bonjour

En fait Z est le départ d'une petite ligne à voie unique non cantonnée, il ne peut y avoir 2 trains sur Z. T est un tiroir et il ne peut y avoir 2 trains.
Par contre quand on va de T en D, dès que la première aiguille est libérée on pourrait faire un C vers T (pareil avec Z).

En pratique tout le fond de gare (haut de l'mage) est utilisé pour des manoeuvres a commande manuelle. Cela serait couteux de multiplier les zones qui nécessitent chacune une détection de présence et des relais de commutation des sources en analogique. Une petite simplification est donc faite. Par contre sur les voies principales (A B C) sur le devant de la gare (bas de l'image) le découpage en zones est complet.

Pierre

277
Vos projets / Re : Commande d'itinéraires par arduino
« le: mars 14, 2015, 10:35:40 am »
Bonjour

Dans un PRS l'ensemble des voies et aiguillages est découpé en zones.

Une zone est un groupe de voies, d'aiguillages, de TJD, TJS, croisements, .. tels qu'il ne peut physiquement y avoir qu'un seul train.

Certaines zones n'ont qu'une aiguille, d'autres plusieurs. Toutes les zones ont bien évidemment une détection de présence de train.

Dès qu'une zone est libérée elle peut être utilisée pour un autre itinéraire (transit souple).

Voici un exemple de découpage en zones sur une gare moyenne. C'est en fait le TCO de mon réseau qui est affiché à l"écran.

Pierre

278
Vos projets / Re : Commande d'itinéraires par arduino
« le: mars 12, 2015, 05:07:45 pm »
Bonjour

Je pilote 32 aiguilles avec un ATmega8535 (il n'y avait pas encore d'Arduino quand j'ai commencé le réseau).
Les moteurs sont commandés par des L2722 (deux amplis op sortant 1A), les L2722 étant eux même commandés par des démutiplexeurs. On peut commander plus d'aiguilles avec plus de démutiplexeurs et beaucoup d'aiguilles (256 voire plus) avec deux niveaux de démutiplexeurs.

Cordialement

Pierre

279
Vos projets / Re : Re : Un Arduino par canton
« le: février 08, 2015, 11:51:22 am »
Pourrais-tu expliquer ce que tu fais sur ton réseau ?

Je fonctionne au choix en analogique ou en digital. En analogique j'ai 4 sources PWM (128 pas) commandables par l'ordinateur, en digital une centrale commandable aussi par l'ordinateur.
L'ordinateur connait la position des trains (détection de présence dans les zones et cantons), des aiguilles (par le biais des itinéraires) et a des informations de détection ponctuelles pour les signaux.

Quand un train passe sur une détection ponctuelle, l'ordinateur connait l'état du signal, la vitesse du train (cran), si par exemple le signal est à l'avertissement l'ordinateur va envoyer des commandes à l'alimentation (analogique ou digitale) pour réduire progressivement la vitesse (cran) jusqu'a 30 km/h. Si le signal est fermé il arrive sur le détecteur ponctuel à 30 km/h et reçoit alors un ordre d'arret.

Voila c'est très classique.

Pierre

280
Vos projets / Re : Re : Un Arduino par canton
« le: février 06, 2015, 04:39:56 pm »
Il y a deux façons de faire :
- avoir une collection d'alimentations centralisées, autant que tu veux avoir de locomotive en fonctionnement sur le réseau. Une série de relai permet de connecter chacune de ces alimentation a un ou plusieurs cantons.
- avoir une alimentation par canton sans relais pour l'y connecter.

Dans le premier cas, il y a énormément de câblage et la régulation de vitesse n'est probablement pas possible.
Bonjour

Je ne vois pas pourquoi ce "n'est probablement pas possible" ? A priori je le fait sur mon réseau !

Pierre

Pages: 1 ... 17 18 [19]