Staatmachines Tutorials

Ik vraag me gewoon af of iemand een goede tutorials op het internet kent voor het ontwikkelen van staatsmachines. Of eBooks?

Ik begin met werken aan staatsmachines en hoeft alleen maar iets te hebben dat ik me begonnen.


Antwoord 1, Autoriteit 100%

Staatsmachines zijn erg eenvoudig in C als u functiewijzers gebruikt.

In principe heb je 2 arrays nodig – een voor staatsfunctiewijzers en een voor staatsovergangsregels. Elke staatsfunctie retourneert de code, u opzoekende overgangstabel op de staat en de retourcode om de volgende toestand te vinden en vervolgens uit te voeren.

int entry_state(void);
int foo_state(void);
int bar_state(void);
int exit_state(void);
/* array and enum below must be in sync! */
int (* state[])(void) = { entry_state, foo_state, bar_state, exit_state};
enum state_codes { entry, foo, bar, end};
enum ret_codes { ok, fail, repeat};
struct transition {
    enum state_codes src_state;
    enum ret_codes   ret_code;
    enum state_codes dst_state;
};
/* transitions from end state aren't needed */
struct transition state_transitions[] = {
    {entry, ok,     foo},
    {entry, fail,   end},
    {foo,   ok,     bar},
    {foo,   fail,   end},
    {foo,   repeat, foo},
    {bar,   ok,     end},
    {bar,   fail,   end},
    {bar,   repeat, foo}};
#define EXIT_STATE end
#define ENTRY_STATE entry
int main(int argc, char *argv[]) {
    enum state_codes cur_state = ENTRY_STATE;
    enum ret_codes rc;
    int (* state_fun)(void);
    for (;;) {
        state_fun = state[cur_state];
        rc = state_fun();
        if (EXIT_STATE == cur_state)
            break;
        cur_state = lookup_transitions(cur_state, rc);
    }
    return EXIT_SUCCESS;
}

Ik doe niet lookup_transitions()-functie zoals het triviaal is.

Dat is de manier waarop ik al jarenmachines doe.


Antwoord 2, Autoriteit 21%

Ik geef de voorkeur aan het gebruik van functiewijzers over gigantische switchVerklaringen, maar in tegenstelling tot QRDL’s antwoord Ik gebruik normaal geen expliciete retourcodes of overgangstabellen.

U wilt in de meeste gevallen ook een mechanisme om aanvullende gegevens door te geven. Hier is een voorbeeld Machine:

#include <stdio.h>
struct state;
typedef void state_fn(struct state *);
struct state
{
    state_fn * next;
    int i; // data
};
state_fn foo, bar;
void foo(struct state * state)
{
    printf("%s %i\n", __func__, ++state->i);
    state->next = bar;
}
void bar(struct state * state)
{
    printf("%s %i\n", __func__, ++state->i);
    state->next = state->i < 10 ? foo : 0;
}
int main(void)
{
    struct state state = { foo, 0 };
    while(state.next) state.next(&state);
}

Antwoord 3, Autoriteit 6%

Helaas zijn de meeste artikelen over staatsmachines geschreven voor C++ of andere talen die directe steun hebben voor polymorfisme, omdat het leuk is om de staten te modelleren in een FSM-implementatie als klassen die zijn afgeleid van een abstracte staatsklasse.

Het is echter vrij eenvoudig om de staatsmachines in C te implementeren die gebruikmaken van schakelafscheidingsverklaringen om gebeurtenissen naar staten te verzenden (voor eenvoudige FSM’s, ze zijn vrijwel goed op) of met behulp van tabellen om gebeurtenissen in kaart te brengen.

Er zijn een paar eenvoudige, maar fatsoenlijke artikelen over een basiskader voor staatsmachines in C hier:

Bewerken: Site “in onderhoud”, links naar webarchief:

switch-statement-gebaseerde state-machines gebruiken vaak een set macro’s om de mechanica van de switch-statement te ‘verbergen’ (of gebruiken een set van if/then/elsestatements in plaats van een switch) en maak wat neerkomt op een “FSM-taal” voor het beschrijven van de toestandsmachine in C-bron. Persoonlijk geef ik de voorkeur aan de op tabellen gebaseerde benadering, maar deze hebben zeker voordelen, worden veel gebruikt en kunnen vooral effectief zijn voor eenvoudigere FSM’s.

Een dergelijk raamwerk wordt beschreven door Steve Rabin in “Edelstenen voor het programmeren van games” Hoofdstuk 3.0 (Een algemene robuuste AI-engine ontwerpen).

Een vergelijkbare set macro’s wordt hier besproken:

Als je ook geïnteresseerd bent in C++ state machine-implementaties, er is nog veel meer te vinden. Ik zal tips plaatsen als je geïnteresseerd bent.


Antwoord 4, autoriteit 6%

Statistische machines zijn niet iets dat inherent een tutorial nodig heeft om uitgelegd of zelfs gebruikt te worden. Ik stel voor dat je de gegevens bekijkt en bekijkt hoe deze moeten worden geparseerd.

Ik moest bijvoorbeeld het gegevensprotocol ontleden voor een Near Space-ballonvluchtcomputer, het sloeg gegevens op de SD-kaart op in een specifiek formaat (binair) dat moest worden geparseerd in een door komma’s gescheiden bestand. Het is het meest logisch om hiervoor een statusmachine te gebruiken, want afhankelijk van wat het volgende stukje informatie is, moeten we veranderen wat we aan het ontleden zijn.

De code is geschreven met C++ en is beschikbaar als ParseFCU. Zoals je kunt zien, detecteert het eerst welke versie we aan het parseren zijn en van daaruit gaat het naar twee verschillende statusmachines.

Het komt in de staatsmachine in een bekende goede staat, op dat moment beginnen we te parseren en afhankelijk van welke personages die we tegenkomen, gaan we door naar de volgende staat, of gaan terug naar een vorige staat. Dit maakt de code in principe in staat om zichzelf aan te passen aan de manier waarop de gegevens worden opgeslagen en of bepaalde gegevens al dan niet bestaan.

In mijn voorbeeld is de GPS-reeks geen vereiste voor de vluchtcomputer om te loggen, zodat de verwerking van de GPS-reeks kan worden overgeslagen als de eindbytes voor die enkele logboek schrijven.

Staatmachines zijn eenvoudig te schrijven, en in het algemeen volg ik de regel die het zou moeten stromen. Invoer die door het systeem gaat, moet met een bepaald gemak uit de staat van de staat stromen.


Antwoord 5, Autoriteit 3%

Dit is alles wat u moet weten.

int state = 0;
while (state < 3)
{
    switch (state)
    {
        case 0:
            // Do State 0 Stuff
            if (should_go_to_next_state)
            {
                state++;
            }
            break;
        case 1:
            // Do State 1 Stuff    
            if (should_go_back) 
            {
                state--;
            }    
            else if (should_go_to_next_state) 
            {
                state++;
            }
            break;
        case 2:
            // Do State 2 Stuff    
            if (should_go_back_two) 
            {
                state -= 2;
            }    
            else if (should_go_to_next_state) 
            {
                state++;
            }
            break;
        default:
            break;
    }
}

Antwoord 6, Autoriteit 3%

Real-Time-Object Oriented Modeling was fantastisch (gepubliceerd in 1994 en nu verkopen voor zo weinig als 81 cent, plus $ 3,99 verzendkosten).


Antwoord 7, Autoriteit 3%

Er is veel les te leren handcrafting state machines in C, maar laat me ook voorstellen Ragel state machine compiler:

http://www.complang.org/ragel/

Het heeft een vrij eenvoudige manier om het definiëren van state machines en dan kunt u grafieken genereren, het genereren van code in verschillende stijlen (-table-driven, goto driven), te analyseren die code als je wilt, enz. En het is krachtig, kunnen worden productie gebruikte code voor verschillende protocollen.


Antwoord 8

State machines kan zeer complex voor een complex probleem. Ze zijn ook onderworpen aan onverwachte bugs. Ze kunnen veranderen in een nachtmerrie als iemand in een bug loopt of moet de logica in de toekomst veranderen. Ze zijn ook moeilijk te volgen en te debuggen zonder de staat diagram. Gestructureerd programmeren is veel beter (bijvoorbeeld zou je waarschijnlijk geen gebruik maken van een state machine op mainline niveau). U kunt gestructureerd programmeren gebruiken, zelfs in interrupt context (waar state machines worden meestal gebruikt). Zie dit artikel “Macro’s te simuleren multi- tasking / blokkeringscode op onderbrekingsniveau “vinden op codeproject.com.

Other episodes