아래 내용은 마이크로소프트웨어 2008년 2월호에 기사로 나간 내용입니다. 물론 초안이라서 책에 나간 내용과는 약간 차이가 있습니다. 저작권 문제가 있을 수 있으므로, 복사하시지는 말고 링크만 걸어 주시기 바랍니다. 잡지 기사를 pdf로 보실려면 iMaso 홈페이지에 가셔서 구매하실 수 있습니다.



State Machine의 개념과 Stateflow에서의 기본적인 모델링 방법 2


요 약

State Machine을 Stateflow에서 모델링하는 기초적인 방법을 지난 시간에 배웠다. 이제는 좀 더 활용도를 높이기 위해서 Stateflow에서 제공하는 기능들을 살펴보고, Parallel State가 무엇인지, 어떻게 사용하는지에 대해서도 배워보자.

제 1 절  우선 순위에 대해서

Stateflow에서 각 state에 대한 transition을 만들다 보면 하나의 state에서 여러개의 transition이 생긴다. 이럴 경우 어떤 transition이 먼저 실행되는지가 중요한 경우들이 있을 수 있다. 그림 1에 서 {twoCoin}(state를 지칭할때는 {}를붙이겠다.)을 보면 insertCoin과 cancel 두 개의 이벤트가 발생할 때 실제로 어느 것을 먼저 비교할 것인가에 대한 기준이 있어야 한다. Stateflow의 경우 내부적인 기준을 가지고 이를 자동으로 결정하고, 그 결정 사항을 보여 주게 된다. {twoCoin}에서두개의 transition을 보면 숫자 1과 2가 적혀 있으며, 이 숫자가 실행될 transition을 체크하기 위한 우선 순위이다. 물론 숫자가 작을 수록 우선 순위가 크므로 그림 1와 같은 모델에서 {twoCoin}에있으면, 이벤트가 발생할때 마다 우선 순위가 높은 insertCoin 이벤트의 transition이 먼저 체크 된다.

사용자 삽입 이미지

그림 1: 제약 있는 자판기 모델

1.1  디폴트로 생성되는 우선 순위

Stateflow 내부적으로 생성되는 우선 순위는 총 세 가지 경우를 기본으로 생성된다. 아래 세 가지 경우고 동시에 발생하는 경우에는 아래 순서로 우선 순위가 결정된다. 이에 대해서는 뒤에 나오는 Super state와 substate를 설명할 때 자세히 설명하도록 하겠다.

1.1.1  계층 구조에 따라서
State chart에서 계층 구조란 하나의 state안에 여러 개의 state를 포함하고 있을 수 있는 것을 말한다. 또 한 이럴 경우 transition을 체크하는 우선 순위가 가장 바깥에 있는 state가 다른 state(즉 자기가 포함하지 않은 state)로 transition이 일어날 경우가 가장 높다. 이 경우는 superstate와 substate를 뒤에서 설명하면서 자세하게 설명하도록 하겠다.

1.1.2  Transition 레이블에 따라서
transition 레이블이란, 그림 2처 럼 transition 위에 적을 수 있는 내용을 말한다. 여기서 기본적인 우선 순위는 transition이 일어날 확률이 적은 것일 수록 우선 순위가 높다. 이벤트와 조건식을 가지고 쉽게 이해해 보자. 이벤트의 경우 그 이벤트가 꼭 발생해야 하지만, 조건식의 경우 조건이 맞으면 된다. 그럼 이 둘의 경우 어떤 경우에 발생할 확률이 높을까? 당연히 조건식의 경우가 발생할 확률이 높다. 물론 조건식도 [a == 3]과 같은 조건식은 당연히 이벤트 처럼 발생하기 힘들 수 있지만, 여기서는 전체적인 것을 생각해 봤을 때 이다. 그러므로 이벤트가 있는 transition이 조건식만 있는 transition보다 당연히 우선 순위가 높다. 이를 바탕으로 생각해 보면 이벤트도 있고 조건식이 있는 경우가 우선 순위가 제일 높다는 것을 알 수 있다. 이와 같이 하나의 state에서 transition이 여러 개 있을 경우 transition이 발생되는 이벤트나 조건에 따라서 어느 것이 먼저 테스트 되는지 알 수 있게 된다. 그림 3를 보면 우선 순위가 e2[in1 > 20]이 제일 높고 그 다음이 e2, e1, 마지막으로 [in1 < 10] 이다.

사용자 삽입 이미지

그림 2: transition 레이블


사용자 삽입 이미지

그림 3: 레이블에 따른 우선 순위

1.1.3  Transition의 위치에 따라서
그림 3를 보면 위에 규칙에 의하면 우선 순위가 같은 e2와 e1이 있다. 레이블로 보면 둘 다 이벤트 이므로 위에 있는 규칙인 transition 레이블에 따라서 우선 순위를 매길 수가 없다. 이런 경우는 transision의 시작점을 기준으로 transition이 시계를 기준으로 12시에 가까울 수록 우선 순위가 높다. 즉 시계 방향으로 돌면서 우선 순위가 낮아 지게 된다. 그림 3를 보면 e2와 e1 둘 중에 시계 방향으로 봤을때 e1이 e2보다 나중에 있으므로, e2가 e1보다 우선 순위가 높다.

1.1.4  직접 지정하기
Stateflow가 우선 순위를 대부분 지정해 주고, 화면상에 표시하기 때문에 쉽게 우선 순위를 알 수 있지만, 우선 순위를 직접 지정하고 싶을때가 있다. 이럴 경우에도 사용자는 쉽게 이를 지정할 수 있다. 이를 지정하기 위해서는 먼저 File→Chart Properties 를 선택하면 사용자가 직접 우선 순위를 지정할 수 있게 할 것인지 여부를 체크할 수 있다. 여기에 체크를 한후, transition을 마우스 오른쪽 클릭을 하게되면 그림 4처럼 직접 지정할 수 있게 된다.

사용자 삽입 이미지

그림 4: 사용자 지정 레이블

제 2 절  Junction에 대해서

transition이 일어 나는 것은 앞에서 본 우선 순위에 의해서 어떤 transition이 실행될 것인지가 결정되고 나서 이다. 그러면 e1 이벤트가 발생하고 조건에 따라서 다른 state로 가야 하는게 결정되면 어떻게 하면 될까? 물론 각각의 transition에 e1[c1], e1[c2], e1[c3] 등을 각각 만들면 되지만, 보기에도 좋아 보지는 않는다. 이럴 경우 junction을 사용하면 된다. 그림 5를 보면 {A}에서{B}로 transition이 e1[c1], e1[c2], e1[c3]에 의해서 일어 난다. 그림과 같이 독립적인 3개의 transition을 만들어서 사용해도 되지만, 이것보다는 {C}에서{D}로가는것처럼 junction을 이용해서 사용할 수 있다. 위와 아래를 비교해보면 junction을 이용하는 것이 훨씬 이해가기 쉽다. junction의 경우는 항상 지나가는 길을 여러개로 만들수 있는 것이라고 생각하면 된다.

사용자 삽입 이미지

그림 5: Junction을 이용한 transition

또 하나의 사용은 앞 연재에서 봤던 condition action과 transition action을 구별 지을 수 있게 해준다. 그림 6에 서 e1 이벤트가 발생하고 그 다음에 있는 모든 조건이 맞지 않으면, 우선 순위 4번인 아무 조건이 없는 transition으로 다시 {C}로돌아간다. 이 때 out1 = 1 이라는 transition action은 실행되지 않지만, {out1 = 5;}라는 condition action은 실행된다. 즉 transition의 경우 항상 state가 바뀌는 경우에만 실행이 되지만, condition action은 조건이 만족되기만 하면 실행이 가능하다. junction은 잘 사용하면 모델을 읽는 사람에게 편하게 읽을 수 있도록 해주므로 주의 깊게 잘 사용하도록 하자.


사용자 삽입 이미지

그림 6: condition action과 transition action

제 3 절  Temporal Logic을 써보자

temporal logic이란 state chart가 업데이트 되는 수에 관련된 함수들을 말한다. 예를 들어 {on}에서 10번 업데이트 되는 동안에 있다가 11번째 업데이트때는 {off}로가야한다면어떻게모델링을해야할까? 이에 대한 해답이 바로 temporal logic을 쓰는 것이다. 대표적인 temporal logic 함수들은 아래와 같다.

after
after(n, E) 와 같이 사용하며, E는 이벤트이며, n은 0보다 큰 숫자이거나 0이나 혹은 더 큰 숫자를 리턴하는 함수를 사용하면 된다. 이름이 뜻하듯이 E가 n번 발생한 후에 true를 넘겨 주거나 혹은 이벤트를 생성한다.
before
before(n, E) 와 같이 사용한다. E가 주어진 n 이전에 발생했는지 여부를 알려 준다.
at
at(n, E) 와 같이 사용하며, E가 정확히 n 번째에 발생했을 경우 true를 넘겨 주거나 이벤트를 생성한다.
every
every(n, E) 와 같이 사용하며, E가 n번째 마다 발생했을 경우 true를 넘겨 주거나 이벤트를 생성한다. every(2, e1) 이면 e1 이벤트가 2번째 발생할때 마다 true를 넘겨 주거나 이벤트를 생성한다.

더 많은 temporal logic이 있지만, 대표적인 것만 설명했다. 이런 temporal logic은 대부분 이벤트로도 쓰이고, 조건문으로도 사용할 수 있다. 즉 그림 7처럼 이벤트나 조건문 모두에 사용할 수 있다. {E}에서{F}로 transition이 일어나는 경우는 timeClock 이라는 이벤트가 3번 발생한 후, 즉 4번째 발생했을 때이며, {F}에서 {E}로 transition이 일어나는 경우는 e1 이벤트가 5번 일어난후 즉 6번째 이다.


사용자 삽입 이미지

그림 7: temporal logic의 사용

temporal logic을 잘 활용하면, 자신만의 스케줄러를 만들 수 있다. 즉 인풋 이벤트로 원하는 샘플링 시간인, 0.001초로 펄스를 만들어서 인풋 이벤트로 만들고 temporal logic 을 이용하면 자신만의 스케줄러를 만들어서 원하는 작업을 할 수 있게 만들 수 있다. 또한 버튼을 눌렀을때를 생각해 보자. 한개의 버튼이 있는데, 누르고 있는 시간에 따라서 다른 동작을 하게 만들어야 할 경우에도 temporal logic을 잘 활용하면 된다.

제 4 절  Action에 대하여

Stateflow를 활용하다 보면 여러 가지 action에 대해서 알게 된다. 여기서 action들에 대해서 정리하고 넘어 가도록 하자. 크게 봐서 action은 state에 연관된 action과 transition에 연관된 action으로 두 종류가 있다. state action은 다시 entry, during, exit 으로 구별되며, transition에 연관된 action은 condition action과 transition action으로 나누어 진다.

4.1  Action이 실행되는 순서


사용자 삽입 이미지

그림 8: 다양한 Actions

그림 8를 보면, 다양한 action들이 있는 것을 알 수 있다. 그림 8는 transition action과 state action이 다 포함된 모델이다. 여기서 알고자 하는 것은 각 action들의 순서를 확인하고자 하는 것이다. 먼저 몇 가지 가정을 하고 시작하자. out으로 시작하는 변수들은 아웃풋으로 가정하고, in으로 시작하는 변수들은 인풋으로 가정한다. e로 시작되는 변수들은 인풋 이벤트이며, timeClock은 0.001초 단위로 rising/falling edge가 반복되는 펄스 신호이다. 즉 그림 8의 모델은 0.001초 단위로 업데이트 되는 모델이다. 현재 시간이 0.001초이면 {A}가활성화되어서 entry action인 out1 = 1 이 실행된다. 이 상태에서 0.003초가 되면, 즉 timeClock 이벤트가 세 번 발생했을때 e1 이벤트가 발생하면 {A}에서{B}로 transition이 일어 나게 된다. 이 때 실행되는 action을 순서대로 고려해 보면 다음과 같다.

  1. {A}에있는 exit action인 out1 = 3이 실행된다.
  2. {A}에서{B}로실제로 transition이 일어 나므로 transition action인 out2 = 2가 실행된다.
  3. {B}에 entry action인 out3 = 1이 실행된다.

위 순서를 보듯이 transition action은 항상 exit action과 entry action 사이에 발생한다. 좀 더 이해를 돕기 위해, 이번에도 {A}에있는상태에서 e2 이벤트가 발생했다고 생각해 보자. e2 이벤트가 발생했으면, transition을 따라가 보면 junction에 도달하게 된다. junction의 경우 무조건 분기해 주는 역할뿐이므로 junction에서 밖으로 나가는 세가지 분기가 있다. 이 중에 우선 순위가 가장 높은 경우가 [in1 > 10]{out2 = 2;}이다. 이 조건이 만약 참이면, 실행되는 action의 순서를 생각해 보자.

  1. {A}에있는 exit action인 out1 = 3이 실행된다.
  2. in1 > 10 이 참이므로, condition action인 out2 = 2가 실행된다.
  3. {A}에서{B}로실제로 transition이 일어 나므로 transition action인 out2 = 0이 실행된다.
  4. {B}에있는 entry action인 out3 = 1이 실행된다.

위와 같이 condition action은 condition이 참인 경우에는 transition이 안 일어 나도 condition이 참이면 실행이 되는 action이고, transition action의 경우 실제로 active state가 변경될 경우에 실행되는 action이다.

다음 연재에서 배우겠지만, action을 실행할때 함수 형태로도 실행할 수 있으므로 필요한 경우에 맞게 잘 선택해서 사용하면 된다.

제 5 절  Superstate와 Substate

State chart에서 각각의 state는 다른 state를 포함할 수 있다. 여기서 포함된 state를 substate라고 하며, 다른 state를 포함하고 있는 state를 superstate라고 한다. 상대적인 개념으로 항상 얘기하므로 잘 구별해서 얘기해야 한다. 또 superstate가 활성화 되면 그 안에 있는 substate중에 하나가 무조건 활성화 되어야 한다. 그래서 제일 안쪽에 있는 substate가 활성화 되어야 한다. 즉 superstate만 활성화 되고 substate가 하나도 활성화 되지 않는 상황은 존재하지 않는다.

사용자 삽입 이미지

그림 9: Superstate와 Substate

5.1  Superstate와 substate 구별하기

그림 9는 superstate와 substate를 표시하며, 그 사이에 transition을 보여 주고 있다. {A}는{SubA1}, {SubsubA1}, {SubsubA2}, 그리고 {SubA2}의 superstate이며, {SubA1}은{SubsubA1}의 superstate이다. 물론 {SubsubA2}는{SubA1}의 substate이다. 이런 state를 나타낼때는 계층 구조적으로 나타낼수 있다. 즉 {A.SubA1}과같이나타낼수있다.

5.2  State활성화 및 Action이 실행되는 순서

앞에서 언급했던 transition을 테스트하는 우선 순위는 superstate와 substate 사이에서는 더욱 복잡해진다. 하지만 기본적인 사항을 잘 숙지하고 하나씩 체크하면 충분히 이해할 수 있다. 앞에서 우선 순위를 체크할때 가장 먼저 고려하는 것이 superstate에서 다른 state로 나가는 transition이다. 지금부터는 전부 설명이 그림 9를 기준으로 한다. 최초로 차트가 업데이트 될 때 활성화 되는 state는 아래와 같은 순서로 활성화 되면서 state action이 실행된다.

  1. 차트가 업데이트가 되어서 디폴트 transition을 따라서 {A}가활성화된다. 그리고 entry action인 doEnA() 실행된다.
  2. {A}가활성화되었으므로 substate인 {A.SubA1}이나{A.SubA2}가활성화되어야한다. 이 때 {A}안에있는디폴트 transition을 따라서 {A.SubA1}이활성화되게해준다. entry action인 doEnSubA1() 실행된다.
  3. {A.SubA1}이활성화되었으므로 substate인 {A.SubA1.SubsubA2}가활성화된다.

이 상황에서 e10 이벤트가 발생했다고 하자. 그러면 어떤 transition이 제일 먼저 테스트가 될까? 가장 바깥에 있는 superstate인 {A}에서바깥으로나가는 transition이 제일 먼저 테스트 된다. 즉 {A}에서{B}와{B.SubB1}가는 transition이 제일 먼저 테스트될 대상이다. 이 둘중에서 e1 이벤트에 대한 transition이 먼저 테스트되는 이유는 같은 이벤트이므로 시계방향으로 봐서 12시에 가까운 쪽이 우선 순위가 높기 때문이다.

{A}에서직접적으로나가는 transition이 없으므로 during action인 doDuA()가 실행된다. 그리고 {A.SubA1}에서나가는 transition이 없으므로 during action인 doDuSubA1()이 실행된다. 그리고 현재 활성화 된 {A.SubA1.SubsubA2}에서{A.SubA2}로나가는({A.SubA1.SubsubA2}입장에서는자신의 superstate인{A.SubA1}을나가는것이므로) transition인 [in < 1]인 조건을 먼저 테스트한다. 그 다음으로 이벤트 e10이 있는 transition을 테스트한다. 여기서는 in이 1로 가정하면 {A.SubA1.SubsubA1}이활성화되게된다.

위와 같은 상황에서 이번에는 e1 이벤트가 발생하면 어떻게 되는지 생각해 보자. 가장 먼저 테스트되는 transition이므로 실제로 {A}에서{B}로 transition이 일어나게 된다. 활성화 되는 state와 state action들을 순서대로 정리하면 아래와 같다.

  1. {A}에서{B}로가는 transition이 실제로 일어 나게 되므로 현재 활성화 되어 있는 {A.SubA1.SubsubA1}이비활성화되며, exit action이 없으므로 아무것도 실행하지않는다.
  2. {A.SubA1}을비활성화시키면서 exit action인 doExSubA1()이 실행된다.
  3. {A}를비활성화시키면서 exit action인 doExA()가 실행된다.
  4. transition action이 없으므로 실행되지 않는다.
  5. {B}를활성화하면서 entry action인 doEnB()를 실행한다.
  6. {B.SubB1}이활성화된다.
  7. {B.SubB1}에 entry action이 없으므로 아무것도 실행되지 않는다.

{A.SubA1.SubsubA1}이활성화된상태에서 e2 이벤트가 발생하면 어떻게 되는지 확인해 보면 {A}에서일어나는일은그대로이지만, {B}에서는 transition이 {B}의경계를가리키므로{B}내부의 state가 활성화 되는 것은 디폴트 transition에 따라서 {B.SubB1}이활성화된다. 바로 위와 결과는 같지만, 과정이 다른 것이다.

제 6 절  Parallel State를 활용하자

지금까지 본 state는 주의 깊게 살펴 보면 실제로 활성화된 state가 항상 한 개뿐이다.(물론 가장 안쪽에 있는 substate를 말한다.) 실제로 모델링을 하다보면 동시에 여러 개의 state가 활성화 되어야 할 필요가 있다.

예를 들어 FAN이 두 개 있는 상태에서 각각의 FAN의 ON/OFF 상태를 모델링 한다면 FAN1과 FAN2의 상태가 각각 활성화된 상태여야 한다. 그림 10는 이를 모델링하는 과정에서 {PowerOn.FAN1}과{PowerOn.FAN2}는어느한쪽만활성화되면 FAN이 두 개가 동시에 동작하지 않을 것이다. 이를 위해서 {PowerOn.FAN1}과{PowerOn.FAN2}를동시에활성화시키는방법이이두 state를 parallel state로 만드는 것이다. 이를 위해서 그림 10와 같이 parallel state로 만들고자 하는 state를 포함하고 있는 superstate에서 마우스 오른쪽 클릭을 하여 Decomposiont →Parallel (AND)를 선택하면 그림 11와 같이 state의 경계가 점선으로 변하게 된다. 또한 state 오른쪽 윗 부분을 보면 숫자 1,2 가 적혀 있는데, 이는 동시에 활성화 되기는 하지만 실제로 컴퓨터에서 계산할때는 어쨌든 먼저 활성화되는 순서가 있어야 하므로 그 순서를 나타낸다. 이 순서는 parallel state의 위쪽 경계선의 높이에 따라서 자동으로 생성된다. 물론 transition의 우선 순위를 지정할 수 있는것과 똑같이 사용자가 직접 지정할 수 있다.


사용자 삽입 이미지

그림 10: Parallel state를 위한 메뉴


사용자 삽입 이미지

그림 11: Parallel state

주의할 것은 parallel state 사이에는 어떠한 transition도 있어서는 안되며, 그림 11에 서처럼 {PowerOn}에서 parallel state로 어떠한 디폴트 transition도 없음을 기억해야 한다. 왜냐하면 {PowerOn}이활성화되면 {PowerOn.FAN1}과{PowerOn.FAN2}모두활성화되기때문에디폴트 transition이 있을 수가 없다. 하지만 parallel state인 {PowerOn.FAN1}과 {PowerOn.FAN2}내부에 exclusive state(베타적인 state, 지금까지 배웠던 state)가 있을 경우에는 어떤 state가 처음에 시작되어야 하는지 알려 줘야 하기 때문에 반드시 디폴트 transition이 있어야 한다.

6.1  로컬 이벤트를 생성해 보자

지금까지 이벤트는 Simulink로부터 받아 오거나 Simulink로 내보냈었다. 하지만 parallel state를 사용할 경우 로컬 이벤트를 생성해서 다른 parallel state의 transition을 발생시킬 수 있다. 그림 12를 보면 {A}, {B}, {C}는서로 parallel state이다. 하지만 그 사이에도 우선 순위가 있어서 그림에서 보는데로 실행된다. 외부에서 들어오는 이벤트는 e1 밖에 없으며, local_e1과 local_e2는 로컬 이벤트이다.

사용자 삽입 이미지

그림 12: 로컬 이벤트를 사용한 모델

현재 이벤트 e1이 발생했을때 차트가 업데이트되면서 {A.SubA1}, {B.SubB1}, {C.SubC1}이활성화되어있는경우이벤트 e1이 발생하면 {C.SubC1}에서{C.SubC2}로 transition이 발생하게 된다. 이 때 transition action으로 local_e1을 발생하게 되면 {C.SubC2}를활성화하기전에다른 parallel state가 다시 체크된다. 즉 {A.SubA1}에서{A.SubA2}로 transition이 실제로 일어나서 {A.SubA2}가활성화된다. 그리고 마찬가지로 {B.SubB2}가활성화되고, 그 다음에 {C.SubC2}가활성화된다.

{C.SubC2}가활성화된상태에서이벤트 e1이 발생하게 되면, send(local_e2, B)를 실행시킨다. send(Event, state) 형태로 사용하며, 위와 다르게 특정한 state 안에만 로컬 이벤트를 발생시킨다. 즉 이번에는 {B}에만로컬이벤트인 local_e2가 발생하므로 {B.SubB2}에서 {B.SubB1}으로 transition이 일어나며, {A}의경우는아무런 transition이 일어 나지 않는다.


크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기(0) 이올린에 추천하기(0)

트랙백을 보내세요

트랙백 주소 :: http://www.cipher.pe.kr/tt/cipher/trackback/173

댓글을 달아 주세요

[로그인][오픈아이디란?]
비밀글 (Serect)
댓글 달기 (Submit)