programing

상태 시스템 튜토리얼

kingscode 2022. 7. 16. 16:49
반응형

상태 시스템 튜토리얼

인터넷 상에서 국영 기계 개발에 대한 좋은 튜토리얼을 알고 계신 분 계십니까?아니면 전자책?

나는 국영 기계에서 일하기 시작했는데 나를 시작하기 위해 뭔가 일반적인 것이 필요하다.

함수 포인터를 사용하는 경우 상태 머신은 C에서 매우 단순합니다.

기본적으로 상태 함수 포인터용과 상태 전이 규칙용 두 개의 배열이 필요합니다.모든 상태 함수는 코드를 반환하고 상태 전이 테이블을 상태별로 조회하여 코드를 반환하여 다음 상태를 찾은 후 실행합니다.

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;
}

★★★★★★★★는 넣지 않습니다lookup_transitions()사소한 기능을 합니다.

그게 내가 수년간 주정부 기계를 하는 방식이야.

는 거대한 기능 포인터보다 하는 것을 한다.switch문장은 qrdl의 답변과 달리 저는 보통 명시적인 반환 코드나 변환 테이블을 사용하지 않습니다.

또한 대부분의 경우 추가 데이터를 전달하는 메커니즘이 필요합니다.스테이트 머신의 예를 다음에 나타냅니다.

#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);
}

이게 네가 알아야 할 전부야.

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;
    }
}

유감스럽게도 스테이트 머신에 관한 문서의 대부분은 C++ 또는 다형성을 직접 지원하는 다른 언어용으로 작성되어 있습니다.이는 FSM 구현에서 상태를 추상 스테이트 클래스에서 파생된 클래스로 모델링하는 것이 좋기 때문입니다.

단, 스테이트 머신을 C에 실장하려면 switch 문을 사용하여 이벤트를 스테이트로 디스패치하거나(단순한 FSM의 경우 거의 코드 업이 됩니다), 테이블을 사용하여 이벤트를 스테이트 이행에 매핑하는 것은 매우 간단합니다.

C의 스테이트 머신의 기본 프레임워크에 관한 심플하지만 적절한 기사가 몇 개 있습니다.

편집: 사이트 "유지보수 중", 웹 아카이브 링크:

switch에서는, 매크로 「숨기기」의을 「에 하는 경우가 .switch의 「」를 )if/then/else「」가 .switchC 소스 내의 스테이트 머신을 기술하기 위한 「FSM 언어」를 작성합니다.어프로치를 어프로치는 확실히 메리트가 또, 보다 FSM에서는 입니다.

이러한 프레임워크 중 하나는 Steve Rabin에 의해 "Game Programming Jems" Chapter 3.0(일반적인 견고한 AI 엔진 설계)에 요약되어 있습니다.

여기에서는, 같은 매크로의 세트에 대해 설명합니다.

C++ 스테이트 머신의 실장에도 관심이 있는 경우는, 그 밖에도 많이 있습니다.관심 있으시면 제가 포인터 올려드릴게요.

C에서는 수공예 스테이트 머신을 배우기 위한 많은 레슨이 있지만, Ragel 스테이트 머신 컴파일러도 제안합니다.

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

상태 머신을 정의하는 매우 간단한 방법이 있습니다.그래프 생성, 다양한 스타일(테이블 기반, goto-drived)의 코드 생성, 원하는 경우 코드 분석 등을 할 수 있습니다.또한 강력하며 다양한 프로토콜의 프로덕션 코드에 사용할 수 있습니다.

스테이트 머신은 복잡한 문제에 대해 매우 복잡할 수 있습니다.또한 예상치 못한 버그가 발생할 수 있습니다.만약 누군가가 버그에 부딪히거나 미래에 논리를 바꾸어야 한다면 그들은 악몽으로 변할 수 있다.상태 다이어그램이 없으면 이를 추적하고 디버깅하기가 어렵습니다.구조화된 프로그래밍이 훨씬 좋습니다(예를 들어 메인라인 수준에서 상태 기계를 사용하지 않을 수 있습니다).인터럽트 컨텍스트(통상 상태 머신이 사용되는 곳)에서도 구조화된 프로그래밍을 사용할 수 있습니다.codeproject.com에 있는 이 문서 "Macros to simulate multiple-tasking/interrupt code"를 참조하십시오.

스테이트 머신은 본질적으로 설명하거나 사용할 튜토리얼이 필요한 것이 아닙니다.제가 제안하는 것은 당신이 데이터를 어떻게 해석해야 하는지 살펴보는 것입니다.

를 들어 Near Space 풍선 비행 컴퓨터의 데이터 프로토콜을 구문 분석해야 했습니다. 이 프로토콜은 SD 카드에 데이터를 특정 형식(이진수)으로 저장하여 쉼표로 구분된 파일로 구문 분석해야 했습니다.스테이트 머신을 사용하면 다음 비트의 정보에 따라 해석할 내용을 변경해야 하기 때문에 스테이트 머신을 사용하는 것이 가장 적합합니다.

이 코드는 C++를 사용하여 작성되며 Parse FCU로 사용할 수 있습니다.이 코드에서는 먼저 어떤 버전을 해석하고 있는지 검출하고 거기에서2개의 다른 스테이트 머신을 입력합니다.

정상적인 상태로 스테이트 머신에 이행해, 그 시점에서 해석을 개시해, 어떤 문자가 검출되고 있는지에 따라서, 다음의 스테이트로 이행하거나, 이전의 스테이트로 돌아옵니다.이를 통해 데이터가 저장되는 방식과 특정 데이터가 있는지 여부에 따라 코드가 스스로 적응할 수 있습니다.

이 예에서 GPS 문자열은 비행 컴퓨터가 기록해야 하는 요건이 아니기 때문에 단일 로그 쓰기의 종료 바이트가 발견되면 GPS 문자열의 처리를 건너뛸 수 있습니다.

스테이트 머신은 쓰기 쉽고 일반적으로 흐름이라는 규칙을 따릅니다.시스템을 통과하는 입력은 상태 간에 어느 정도 쉽게 흐를 것입니다.

Real-Time Object-Oriented Modeling은 훌륭했습니다(1994년에 출판되어 현재는 81센트에 배송료 3.99달러에 판매되고 있습니다).

언급URL : https://stackoverflow.com/questions/1371460/state-machines-tutorials

반응형