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




Flow Graph와 Truth Table의 이해

요 약

State machine을 모델링하는 기본적인 내용은 다 배웠다. 이번 연재에서는 복잡한 로직등을 action이나 조건식에 사용할 수 있게 해주는 flow graph와 truth table에 대해서 배워 보도록 하자.

제 1 절  Flow graph

Flow Graph는 복잡한 로직(주로 조건문과 반복문)을 Stateflow 내부에서 모델링할때 사용한다. 앞 연재에서 배웠던 junction과 transition을 이용하여 로직을 구성하게 된다. 아래와 같이 간단한 c 코드를 Flow Graph로 바꾸면 그림 1와 같다. 앞 연재를 잘 보았다면 그림 1를 충분히 이해할 수 있지만, 한번 더 확인해 보자.


if u > 0.5
  y = 1
else
  y = 0

Stateflow 내에서는 Junction에는 머무를 수가 없고 무조건 지나가야 하므로 state chart가 업데이트 될때마다 default transition을 따라서 들어 와서 각 junction에서 어떤 transition을 따라서 움직여야 하는지를 판단해서 terminating junction을 만날때까지 실행이 된다. terminating junction이란 junction중에서 transition이 들어 오기만 하고 나가는 transition이 없는 junction을 말한다.


사용자 삽입 이미지

그림 1: 간단한 Flow Graph

Flow graph에는 한 개의 default transition과 최소 한 개 이상의 terminating junction이 필요하다. terminating junction은 여러 개 있을 수 있는데, C에서 함수를 작성할때 return 문이 여러 개 있으면 분석때 복잡한 것처럼 flow graph에서도 가능하면 한 개의 terminating junction을 두는게 좋다.

Chart가 업데이트 되었을때 첫 번째 junction에서 우선 순위에 따라서 [ u >0.5 ] 인 조건식을 먼저 검사하게 된다. 이 조건식이 참인 경우 transition을 따라서 다음 junction으로 움직이고, 그 뒤에 junction을 따라서 { y = 1;}이실행된다. 그리고 다시 junction으로 움직이고, 아무 것도 없는 transition을 따라서 terminating junction에서 실행이 멈추게 된다. 이상과 같이 flow graph는 junction에서 우선 순위에 따라서 조건 검사하고 transion 따라서 움직이는 것을 잘 찾아 다니면 쉽게 이해할 수 있다.

1.1  Flow Graph Pattern

Flow graph가 복잡해지면 transition과 junction이 많아져서 오히려 가독성이 떨어지게 된다. 이러한 가독성을 높게 하기 위해서 일반적으로 The MathWorks 사에서 제공하는 패턴 형태가 있다. 물론 현재까지 stateflow를 사용한 유저들의 의견이 충분히 반영되어 있으므로 가능한 지키는 것이 좋다. junction과 transition으로 정형화된 모양으로 형태만 보고도 조건문인지, 반복문인지 등을 구별할 수 있다. 그림 1의 경우 if-else 문을 표시한다.


사용자 삽입 이미지

그림 2: if-else if-else 패턴

그림 2의 경우 c 코드에서는 if-else if 문으로 아래와 같다.


if ( u > 1 )
{
...
}
else if ( u < 0.5 )
{
...
}
else
{
...
}

그림 3는 c 코드에서 if 내부에 다시 if가 있는 것으로 아래에 코드가 있다.


사용자 삽입 이미지

그림 3: if속에 if문 패턴


if ( u > 1 )
{
 ...
  if ( u < 0.5 )
  {
   ...
  }
}
else
{
 ...
}

그림 4는 for 구문을 표시하며, 그림 5는 while 구문이며, 그림 6는 do-while 구문을 나타낸다. 이와 같이 패턴 형태로 로직을 구성하게 되면 flow graph를 읽을때 가독성이 확실히 좋아 짐을 알 수 있다. 물론 이것이 법칙은 아니지만 대부분의 사용자가 사용하는 방식이므로 따라서 하는게 좋다.


사용자 삽입 이미지

그림 4: for 패턴


사용자 삽입 이미지

그림 5: while 패턴


사용자 삽입 이미지

그림 6: do while 패턴

1.2  Flow graph의 주의할 점

Flow graph를 사용할때 주의해야 할 점이 있다. 항상 junction에서 나와서 junction으로 transition이 발생하는데, transition에 조건문이 있을 경우 항상 조건이 없는 transition이 있어야 한다는 것이다. 예를 들어 그림 7의 flow graph를 보면 condition1이 참이고 condition2가 거짓인 경우 그림 7에 표시한 부분에서 backtracking이 발생하여 다시 돌아 가서 y=0;이 실행되게 된다. 이런 경우는 주로 사용자가 원하지 않는 경우이다. 이런 경우를 피하기 위해서는 backtracking이 발생한 junction에서 Junction 1 이라고 표시된 junction으로 transition이 있어야 한다. 이런 backtracking을 피하기 위해서는 조건이 있는 transition이 나가는 junction의 경우 항상 조건이 없는 transition을 추가하면 해결된다.

사용자 삽입 이미지

그림 7: Backtracking의 예제

또 하나 주의 할 점은 반복문의 패턴을 만들때이다. 그림 4와 그림 8를 비교해 보면 내용 자체는 똑같다. 하지만 그림 4는 제대로 동작하고, 그림 8는 실행 자체가 되지를 않는다. 반복문을 flow graph로 구성할때는 무조건 아무 조건이 없는 transition이 반복문 바깥에 있는 junction으로 나가야 한다. 그림 8는 조건문이 반복문 바깥에 있는 junction으로 나가므로 제대로 실행이 되지 않는다. 의미상 flow graph에서는 같아보여도 실제로 실행이 되지 않는다. 이는 stateflow에서의 제약 사항 이다.


사용자 삽입 이미지

그림 8: 잘못 구성한 반복문

1.3  Graphical Function

일반적인 프로그래밍 언어를 보면 같은 일을 모아서 반복하거나 혹은 단위일을 하게 하는 경우에 함수 형태로 만들 수 있는 것처럼 flow graph도 함수 형태로 만들 수 있다. 이를 graphical function이라고 한다. graphical function을 만들때는 c에서 함수 만드는 것처럼 함수의 이름과 인풋, 아웃풋에 대해서 정의 하고 그 내부 구성을 flow graph로 만드는 것이다. c와는 다르게 인풋과 아웃풋의 데이타 타입을 함수명에 표시하지 않고 변수명만 적으면 된다. 그림 9에 서 점선으로 동그라미친 부분을 보면 공통되는 부분이라는 것을 알 수 있다. 물론 조건문의 값이 2와 1로 다르지만 이 부분을 함수의 인풋 형태로 만들면 동그라미 친 부분은 동일하다는 것을 알 수 있다. 이럴때 graphical function을 사용할 수 있는 것이다.


사용자 삽입 이미지

그림 9: 반복되는 부분이 있는 function flow

그림 10와 같이 왼쪽에 있는 아이콘중에 f()로 되어 있는 아이콘이 graphical function을 만들기 위한 아이콘이다. 이를 클릭해서 차트 에디터의 빈 공간이 클릭을 하면 function 이라고 적힌 빈 상자가 생긴다. function 다음에 함수의 형태를 쓰므로서 graphical function을 만들 수 있다. 빈 상자는 네 모서리를 움직여서 크기를 바꿀수 있으며, 그 안에 flow graph를 만들어서 graphical function을 만들 수 있다.


사용자 삽입 이미지

그림 10: graphical function 만들기 1

그림 11를 완성해서 원래 flow graph에 반영한 모습이다. 그림과 같이 상당히 단순화 되는 것을 알수 있다. 그리고 graphical function으로 만든 부분을 내용은 보여 주지 않고 함수의 이름 형태로만 보여 줄 수도 있다. 이렇게 하기 위해서는 graphical function 위에서 마우스 오른쪽 버튼을 클릭하여 ”Make Contents → Subcharted”를 선택하면 된다. 이 과정이 그림 12에 나와 있다. 이렇게 subchart화된 graphical function의 내용을 보기 위해서는 박스 안쪽을 더블 클릭하면 볼 수 있게 된다.


사용자 삽입 이미지

그림 11: graphical function 만들기 2


사용자 삽입 이미지

그림 12: Subchart화된 graphical function

첫 연재에서 state chart를 만들고 시물레이션할 때 에니메이션으로 어떤 조건에 state가 어떻게 변하는지 볼 수 있다고 했듯이 마찬가지로 graphical function도 어떤 transition을 따라서 움직이는지를 에니메이션 형태로 볼 수 있다. 따라서 복잡한 로직의 경우 flow graph를 잘 활용해서 만들어 놓으면, 조건이나 인풋에 따라서 실제로 어떤 흐름으로 움직이는지 볼 수 있으므로 본인이 만든 알고리즘을 디버깅할때 실제 c코드를 보는 것보다 훨씬 쉽게 할 수 있다.

1.4  Inner Flow Graph

지금까지 설명한 것처럼 flow graph를 단독으로 사용할 수도 있지만, graphical function 형태로 만들어서 state chart의 condition/transition/state action등에 사용할 수도 있다. 또 한 state 내부에 flow graph를 사용할 수도 있는데, 이를 inner flow graph라고 한다. 그림 13를 보면서 그 활용도를 확인해 보자.

사용자 삽입 이미지

그림 13: flow graph의 state내에서의 활용

차트가 처음으로 업데이트된 상황에서 어떤 action이 실행되는지 확인해 보자.

  1. default transition을 따라서 {S1}이활성화된다.
  2. {S1}의 entry action인 action1이 실행된다.
  3. {S1}내부에있는 innter graph의 default transition을 따라서 flow graph가 실행되므로 act1이 실행된다.
  4. u1 > 1의 조건이 참이면 y = 1이 실행되고, 거짓이면 y = 0이 된다.

{S1}이활성화된상태에서다시차트가업데이트되고 e2 이벤트가 발생하게 되면 {S1}의 during action인 action2가 실행된다. 여기서 중요한 것은 inner flow graph가 실행되지 않는 다는 것이다. 그 다음으로 차트가 업데이트 될 때 e1 이벤트가 발생하게 되면 어떻게 될까? 한번 생각해 보자.

  1. {S1}에서나가는 transition을 체크했을때 e1 이벤트가 발생했으므로 {S1}에서{S2}로 transition이 일어나게 된다.
  2. {S1}의 exit action인 action3이 실행된다.
  3. transition action이 없으므로 바로 {S2}가활성화된다.
  4. {S2}가활성화되면서 entry action인 action4가 실행된다.
  5. inner flow graph의 default transition을 따라서 실행되므로 act2가 실행된다.
  6. u1 > 1의 조건에 따라서 y=1이거나 y=0이 된다.

{S2}가활성화된상태에서다시한번차트가업데이트되고아무런이벤트가발생하지않았을때의동작을살펴보자

  1. {S2}에서나가는 transition이 아무것도 일어 나지 않으므로 during action인 action5가 실행된다.
  2. {S2}의경계에서 inner flow graph로 transition이 있으므로 act3가 실행된다.
  3. u1 > 1의 조건에 따라서 y=1 또는 y=0이 된다.

위에서 설명한 것처럼 innter flow graph의 경우 state의 경계에서 inner flow graph로 transition이 있는지 여부에 따라서 during action 다음에 inner flow graph가 실행되는지의 여부가 판가름 난다. 앞에서 본것처럼 inner flow graph의 경우 state의 entry/during action 처럼 동작을 하지만, 순서가 실제 state의 action보다는 뒤에 실행된다는 것을 명심해야 한다.

제 2 절  Truth Table

조건이 아주 많고 그런 조건의 조합으로 어떤 action을 실행할지 결정해야 하는 경우들이 있다. 물론 flow graph를 사용해서 조건문을 실제로 조합해서 모델링할 수도 있지만, 이런 경우는 stateflow에서 제공하는 truth table을 이용하는 것이 훨씬 수월하게 작업을 하도록 도와 준다.

Truth table의 경우 function 형태로만 제공되며 truth table을 위한 에디터가 따로 제공된다. 게다가 truth table만을 사용하기 위한 사용자를 위하여 truth table 블럭이 존재한다. 여기서는 truth table을 함수 형태로 사용하는 것을 보도록 하겠다.

세 개의 센서가 있는 시스템에서 아래와 같은 세 가지 조건이 있다고 가정해 보자.

  1. 세 개의 센서는 정상 작동하면 0과 같거나 혹은 더 큰 값을 가진다.
  2. 세 개의 센서의 값이 정상 작동하는 경우는 세 센서의 값을 다 더하고 3으로 나눈다. 즉 평균을 구한다.
  3. 한 개의 센서만 음수의 값을 가질 경우, 즉 두 센서의 값은 정상적일 경우, 두 센서의 값 만을 더하고 2로 나누어 평균을 낸다.
  4. 한 개의 센서만 정상 작동할 경우 시스템에 문제가 있다고 가정하고 -1을 가진다.
  5. 모든 센서가 정상 작동하지 않을 경우 -1을 값으로 가진다..

2.1  Truth Table 에디터

위와 같은 경우 c로 어떻게 코딩하면 되는지 한번 생각해 보기 바란다. 프로그래머의 능력에 따라서 각각의 코드가 나오므로 독자에게 이 부분은 맡기겠다. 여기서는 truth table을 이용하여 모델링해 보도록 하겠다.

차트 에디터에서 왼쪽에 있는 아이콘 중에서 junction 아이콘 밑에 있는 아이콘을 클릭하면 된다. 이를 클릭하면 graphical function 처럼 박스가 생기는데 이번에는 function이 아니라 truthtable 이라고 적힌다. 그리고 박스의 중간에 함수의 이름과 인풋, 아웃풋을 적게 된다. 그리고 박스 안을 더블 클릭하면 그림 14가 나와서 모델링을 하게 된다.


사용자 삽입 이미지

그림 14: Truth Table 에디터

조건식은 sensor_a >= 0, sensor_b >= 0, sensor_c >= 0 세 개의 조건식의 참/거짓여부로 판단할 수 있다. 이를 위해서 truthtable 에디터의 condition table에 행을 두개 더 추가 하고, 열의 경우 7개를 더 추가한다. 열을 7개 더 추가하는 이유는 truthtable을 만들 경우 가능한 모든 경우의 수를 만들어야 한다. 즉 3개의 조건이 참/거짓으로 만들 수 있는 최고의 경우의 수는 8이므로 7개를 더 만들어야 한다.

그림 15에 서처럼 condition table에 3개의 조건을 각각의 행에 두고 열에는 T/F로 조합을 만든다. 그리고 action table에는 y를 계산하는 각각의 action을 실제로 적는다. action table의 제일 왼쪽에 보면 숫자가 있는데, 이 숫자를 condition table의 각 열의 맨 마지막에 숫자로 적는다. 만약 두 개 이상의 숫자를 적어야 하면 ,로 구별하면 된다.


사용자 삽입 이미지

그림 15: Truth Table 모델링

그림 15에서 D5와 D8을 삭제해 보자. truth table이 복잡하다보면 조건을 적다가 빠트리는 경우도 있을 수가 있다. 이럴 경우를 체크하기 위해서 그림 14에 있는 체크 아이콘을 클릭했을때 나오는 에러 윈도우가 그림 16이다. 그림 16를 보면 FFF(D8)와 FTT(D5) 조건이 빠졌다고 체크해주는 것을 알 수 있다.


사용자 삽입 이미지

그림 16: Truth Table 에러 체크

2.2  Simulink와 연동한 알고리즘의 체크

모델링을 다 했으니, 제대로 모델링 했는지 체크를 해보기 위해서 Simulink와 연동하여 테스트해 보자. 그림 17는 테스트를 하기 위해서 Simulink로 전체 모델을 만든 것이다. sensor들의 값은 sine 인풋으로 값을 주었는데, phase를 약간 달리하므로 인풋 값에 차이가 날 것이다. 그림 18는 10초간 시물레이션했을때 그 결과를 보여 주는 것이다. c로 코딩했을때와 truth table로 모델링한 것과의 차이점 뿐만 아니라 알고리즘을 테스트 하기 위한 부분까지도 얼마나 쉬운지 알 수 있을 것이다.


사용자 삽입 이미지

그림 17: 테스트하기 위한 Simulink 모델


사용자 삽입 이미지

그림 18: 테스트하기 위한 Simulink 모델의 scope으로 본 결과


크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기(0) 이올린에 추천하기(0)
받은 트랙백이 없고, 댓글 2개가 달렸습니다.

댓글+트랙백 RSS :: http://www.cipher.pe.kr/tt/cipher/rss/response/174

댓글+트랙백 ATOM :: http://www.cipher.pe.kr/tt/cipher/atom/response/174

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

트랙백 RSS :: http://www.cipher.pe.kr/tt/cipher/rss/trackback/174

트랙백 ATOM :: http://www.cipher.pe.kr/tt/cipher/atom/trackback/174

댓글을 달아 주세요

댓글 RSS 주소 : http://www.cipher.pe.kr/tt/cipher/rss/comment/174
댓글 ATOM 주소 : http://www.cipher.pe.kr/tt/cipher/atom/comment/174
  1. 비밀방문자 2010/06/20 21:49  댓글주소  수정/삭제  댓글쓰기

    관리자만 볼 수 있는 댓글입니다.

    • 게으른 엔지니어 2010/06/22 17:56  댓글주소  수정/삭제

      temporal logic 이 원하시는 기능을 구현하기 위해서 사용하는 것입니다. 이 다음 기사에서도 언급되어 있습니다. 매스웍스 코리아 기술 지원 부서, 02-6006-5100 으로 문의 하시면 더 자세히 문의 가능합니다. 물론 사용하시는 제품의 라이센스 번호와 함께 문의 하셔야 합니다.

[로그인][오픈아이디란?]