J'écris du code de machine à états finis et je n'arrive pas à comprendre l'ordre de mes instructions "Switch" et "if" (qui devraient venir en premier).

Actuellement, je l'ai écrit comme tel:

task main()
{
    // State variable default.
    SystemStateType SystemState = State1;

    While(1)
    {
        //Taken in from external sensors in real time
        int reading;

        if (reading == 0)
        {
            SystemState = State1;
        }
        else
        {
            SystemState = State2;
        }

        switch (SystemState)
        {
            case State1:
                //actions
                break;

            case State2:
                //other actions 
                break;
        }
    }
}

Le code est destiné à prendre les données du capteur en temps réel et à répondre en conséquence. Je me rends compte qu'il ne s'agit pas d'un code fonctionnel, mais j'espère que puisque la question est théorique, mon code actuel sera suffisant. S'il vous plaît laissez-moi savoir si je manque quelque chose.

Je vous remercie!

0
Ben 17 janv. 2017 à 10:07

2 réponses

Meilleure réponse

Je ne peux pas comprendre l'ordre de mes instructions "Switch" et "if" (qui devraient venir en premier).

Votre instruction switch examine la valeur de la variable SystemState, qui est définie via votre instruction if. Le bon ordre est donc d'avoir votre instruction if, de sorte que SystemState variable takes the desired value, and then examine the value of SystemState dans votre instruction switch.

Supposons que vous ayez des instructions if et switch dans le sens inverse, comme ceci:

task main()
{
    // State variable default.
    SystemStateType SystemState = State1;

    While(1)
    {
        //Taken in from external sensors in real time
        int reading;

        switch (SystemState)
        {
            case State1:
                //actions
                break;

            case State2:
                //other actions 
                break;
        }

        if (reading == 0)
        {
            SystemState = State1;
        }
        else
        {
            SystemState = State2;
        }

    }
}

Ensuite, dans l'instruction switch, votre variable SystemState serait toujours State1.

Bien sûr, gardez à l'esprit que de la manière dont vous avez écrit votre code en ce moment, reading ne peut recevoir aucune entrée. Vous devez donner à reading un moyen d'obtenir une valeur.

1
Marievi 17 janv. 2017 à 08:18

L'ordre des instructions IF et SWITCH n'est pas important dans l'exemple OP. Dans une machine à états finis, pour chaque STATE différent, la machine effectue un certain ensemble d'opérations. La transition d'un état à un autre est conceptuellement séparée, mais est souvent effectuée par le même code: de cette façon, dans certains états, un ensemble d'entrées peut être vérifié (et d'autres ignorés), et dans un autre état, un ensemble différent d'entrées peut être vérifié. Parmi les entrées vérifiées, l'une d'elles peut déclencher un changement d'état.

Supposons que vous ayez un moteur, un bouton de démarrage, un bouton d'arrêt et un bouton pour régler la vitesse du moteur. Lorsque vous appuyez sur START, le moteur tourne avec la vitesse réglée par le bouton. Lorsque vous appuyez sur STOP, le moteur s'arrête (jusqu'à ce que START soit à nouveau enfoncé). Cette machine a deux états: STOPPED et RUNNING. Le moteur, le bouton, le démarrage et l'arrêt sont tous des E / S qu'un autre fil se soucie de lire ou de régler. Le pseudocode serait comme ça.

STATE = STOPPED;
while (1) {
  switch (STATE) {

    case STOPPED:
      Motor = 0;   // the motor does not turn
      if (Start) STATE = RUNNING;
      break;

    case RUNNING:
      Motor = Knob;   // rotate with the speed given by Knob
      if (Stop) STATE = STOPPED;
      break;

  } // end switch
} // end of forever cycle

Maintenant, imaginez que le moteur doit faire des montées et descentes. Deux états peuvent être ajoutés, ACCEL et DECEL. Dans l'état STOPPED, le code vérifie si Start est pressé; si tel est le cas, le nouvel état devient ACCEL. Dans l'état ACCEL, la valeur du moteur est augmentée jusqu'à ce qu'elle atteigne la valeur du bouton. Il en va de même pour l'état DECEL, je l'omets par souci de brièveté.

Veuillez noter que, pendant l'état ACCEL, les boutons ne sont PAS cochés. Il pourrait être parfaitement légal de dire que la phase ACCEL ne doit pas être interrompue. Si la phase doit supporter une interruption, alors la phase ACCEL doit cocher le bouton Stop. C'est la beauté d'une machine à états: vous pouvez décomposer une chose complexe en différentes étapes et vous concentrer sur elles séparément.

L'idée de placer un IF en dehors de switch peut également jouer un rôle, et en fait, les boutons d'arrêt d'urgence / de sécurité doivent être traités de cette façon: quel que soit l'état de la machine, une commande d'arrêt doit arrêter la machine. Pour plus de simplicité, cela peut être fait en dehors du flux normal de la machine d'état: lorsque le bouton d'urgence est enfoncé, arrêtez chaque mouvement, éteignez tout et forcez l'état ARRÊTÉ (ou, mieux encore, un état URGENCE qui nécessite plus d'attention de l'utilisateur).

Si tout le cycle while (1) { est exécuté à la vitesse maximale, il n'y a aucune différence pour placer le IF avant ou après le SWITCH. Si, à la place, toute la logique de la machine s'exécute dans une routine qui est appelée cycliquement, disons toutes les millisecondes, alors le if peut être exécuté 1 milliseconde plus tôt s'il est placé avant le switch. Mais cela a de toute façon peu d'importance, car toute la machine souffre d'une latence de 1 milliseconde.

0
linuxfan says Reinstate Monica 17 janv. 2017 à 08:58