Auteur Sujet: Machine à états  (Lu 7947 fois)

petitrain

  • Jr. Member
  • **
  • Messages: 80
    • Voir le profil
Re : Machine à états
« Réponse #15 le: décembre 20, 2015, 12:09:45 am »
Ce n'est qu'une bibliothèque de plus pour l'Arduino. On peut très bien combiner les méthodes de la "library" avec le langage Arduino ou du C/C++.
Dans les dernières pages du guide de l'utilisateur, il explique comment écrire le code après avoir fait son grafcet sur papier avec quelques exemples.On part de l'état initial, puis on code  chaque état et chaque transition,on vérouille l'état précédant, après on s'occupe des sorties et des variables pour chaque état.  Je trouvais que de cette manière, c'était plus intuitif. La gestion de millis() est assez délicate a manier (pour des apprentis programmeurs), là, on débroussaille le problème.

nopxor

  • Jr. Member
  • **
  • Messages: 80
    • Voir le profil
Re : Machine à états
« Réponse #16 le: avril 10, 2018, 06:37:53 pm »
Bonjour,

Pour illustrer concrètement l'emploi des machines à états sur Arduino, il y a un excellent tutoriel là:
https://forum.arduino.cc/index.php?topic=470879.0

Marc-Henri

  • Full Member
  • ***
  • Messages: 130
    • Voir le profil
    • Modélisme ferroviaire & électronique
Re : Machine à états
« Réponse #17 le: avril 29, 2019, 12:25:51 pm »
Bonjour à tous,

Depuis nos derniers échanges au sujet des machines d'états, j'ai avancé, mais sans utiliser l'outil Yakindu Statechart Tool. J'ai réalisé 2 projets Arduino incluant des machines d'états C++.

Gare cachée sur ligne en voie unique
Ce projet a été réalisé pour le réseau d'un ami. La détection des trains se fait par des ILS.
  • Voie: 2 instances.
  • GareCachée: 1 instance.
  • Bouton: 2 instances.
  • Led: 3 instances une pour la led 13 et 2 pour les leds du TCO.

Gestion de mon 2ème réseau en N
Ce 2ème projet, encore en cours, comprend plusieurs machines d'états implantées dans des classes C++.
  • Zone de détection: 8 instances.
  • Boutons: 1 instance de cette classe pour gérer les 7 boutons du TCO connectés à une entrée analogique.
  • Led: 1 instance, pour faire clignoter la led 13 de la carte et indiquer ainsi visuellement que le programme n'est pas planté.
  • Mode: 1 instance de cette classe pour lire le mode de fonctionnement via un contacteur rotatif connecté à une entrée analogique.
  • Aiguilles: 1 instance pour gérer les 5 aiguilles du réseau. Cette classe est responsable du séquencement des commandes des aiguilles afin d'assurer qu'une seule est active à la fois.
  • GareCachée: 1 instance de cette classe inclut 4 instances de zones pour détecter les trains.
  • Affichage: 1 instance de cette classe pour gérer l'affichage LCD pour afficher l'état de la gare cachée et donner d'autres informations à l'utilisateur.
  • Signal: 2 instances de cette classe pour gérer les signaux en sortie de gare.
  • VoieDeGare: 2 instances de cette classe qui incluent 1 instance de zone.
  • Itineraire: 8 instances.
  • ChefDeGare: 1 instance de cette classe qui assure la coordination du tout.

Il y a donc plus d'une vingtaine de machines d'états qui interagissent entre elles. Les classes sous jacentes restent suffisamment simples pour pouvoir être codées directement sans passer par un outil supplémentaire. L'architecture se base sur l'approche décrite ici: https://paulmurraycbr.github.io/ArduinoTheOOWay.html et mentionnée dans mon post: http://forum.locoduino.org/index.php?topic=576.0.

Je posterai plus de détails ultérieurement.

Bon début de semaine et meilleures salutations.

Marc-Henri
« Modifié: avril 29, 2019, 12:32:30 pm par Marc-Henri »

Marc-Henri

  • Full Member
  • ***
  • Messages: 130
    • Voir le profil
    • Modélisme ferroviaire & électronique
Machine à états en C++
« Réponse #18 le: juin 06, 2019, 10:15:08 am »
Bonjour à tous,

Mon projet de réseau hivernal utilise abondamment les machines d'états à raison d'une par classe (http://forum.locoduino.org/index.php?topic=763.0). Bien que mon programme soit opérationnel, je ne suis pas 100% satisfait de mon code.

Les machines d'états se répartissent entre la méthode loop et les méthodes publiques appelées par les autres objets. De plus, les instructions switch deviennent vite très longues et la lisibilité du code n'est pas optimale.

Idéalement, j'aimerais avoir une fonction pour chaque état. En C, on utiliserait un pointeur sur fonction dont la valeur définirait l'état courant. De multiples exemples sont disponibles sur le web, y-compris pour les AVR.

Deux approches me paraissent possibles:

Pointeur vers méthode
En C++, il serait intéressant d'avoir une méthode pour chaque état et un pointeur vers la méthode correspondant à l'état courant.
  • Avantage: les méthodes ont directement accès aux membres de la classe.
  • Inconvénient: il ne semble pas simple de définir des pointeurs sur des méthodes.

Patron de conception État
L'alternative est le patron de conception état. Chaque état est implanté par une classe dérivée d'une classe abstraite. Ensuite, plutôt qu'un pointeur sur une méthode, c'est un pointeur sur la classe abstraite qui est mis en oeuvre. Le changement d'état consiste à changer l'instance d'objet correspondant à l'état courant.
  • Avantage: meilleur découpage du programme.
  • Inconvénient: les classes dérivées définies pour chaque état n'ont pas accès aux membres de la classe qui implémente la machine d'états. Il peut en effet être nécessaire de partager des données entre les différents états. Encore peu expérimenté en C++, j'aimerais savoir si on peut utiliser la notion d'amitié (friend class) pour cela.

Qu'en pensent les experts en C++ de Locoduino ?

Meilleures salutations.

Pierre59

  • Full Member
  • ***
  • Messages: 142
    • Voir le profil
Re : Machine à états
« Réponse #19 le: juin 06, 2019, 03:55:11 pm »
Bonjour

Bonne idée que d'utiliser des patrons de conception. J'ai déjà proposé sur le forum un patron de conception "observateur".

Pour résoudre les problèmes de visibilité en général on passe aux méthodes des classes états un pointeur sur la classe qui implémente la machine à états.

Cordialement

Pierre

Thierry

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 500
    • Voir le profil
Re : Machine à états
« Réponse #20 le: juin 06, 2019, 05:27:03 pm »
Le 'friend' de fonction ou de classe est une 'astuce' donnée par le C++ pour contourner les limitations de portée imposées par le langage et le programmeur. C'est un moyen de rendre public des données privées seulement à une audience autorisée.
C'est peu élégant, mais c'est souvent le seul moyen d'éviter de mettre les données public ! Il faut simplement décider si l'on veut mettre public ou non les données à partager. Si la réponse est non, alors le 'friend' s'impose.
Noter que le mot clé friend s'applique à une classe entière, mais il peut aussi s'utiliser pour une fonction, permettant ainsi à cette seule fonction d’accéder aux données privées de la classe amie. Réduire la portée de données qui de base étaient privées me parait une bonne façon de réfléchir.

Marc-Henri

  • Full Member
  • ***
  • Messages: 130
    • Voir le profil
    • Modélisme ferroviaire & électronique
Re : Machine à états
« Réponse #21 le: juin 13, 2019, 03:29:12 pm »
Merci beaucoup Pierre et Thierry pour vos réponses.

Bonne fin de semaine et meilleures salutations.

Marc-Henri