아래 내용은 마이크로소프트웨어 2007년 10월호에 기사로 나간 내용입니다. 물론 초안이라서 책에 나간 내용과는 약간 차이가 있습니다. 저작권 문제가 있을 수 있으므로, 복사하시지는 말고 링크만 걸어 주시기 바랍니다.
자동 코드 생성 툴의 활용
|
요 약 |
제 1 절 자동 코드 생성
시뮬레이션으로 제어기 설계를 끝냈으면, 이제 실시간으로 성능을 테스트 해야 할 시간이 됐다. 실시간으로 성능을 테스트 하기 위해서는 먼저 실시간으로 테스트 하기 위한 C 코드가 있어야 한다. C++의 경우에도 임베딩하는 경우가 있지만, 여전히 C 언어가 임베디드 소프트웨어로 가장 많이 사용되고 있다. 제어기나 복잡한 알고리즘을 시뮬레이션으로 테스트를 끝내고 이를 바탕으로 다시 처음부터 C 코드를 작성하게 되면 엄청난 시간과 노력이 들게 된다. 이럴때 사용할 수 있는 코드 생성에 대해서 살펴 보도록 하자.
1.1 자동 코드 생성의 유용성과 효율성
자동 코드 생성 툴의 유용성에 대해서 예를 들어 설명하면, Flight Code라는 용어를 쓰는데, 이는 항공기에서 비행을 위해서 작성하게 되는 모든 소스 코드를 일컫는 말이다. 국방 항공쪽에서 세계적으로 유명한 Lockheed-Martin에 따르면 이런 Flight Code는 천5백만 LOC를 넘는다고 한다. 국방/항공쪽은 잘못되면 크나큰 인명의 손실을 입기 때문에 소스 코드를 작성할때 수도 없이 많은 테스트를 해야 한다. 그리고 개발 단계에서는 아직 하드웨어가 완성되어 있지 않으므로 시뮬레이션을 통해서 이런 작업을 하게 되는데, 자동 코드 생성 툴을 사용하지 않게 되면 시뮬레이션으로 테스트한 알고리즘을 다시 처음부터 C로 작성하는 것이므로 시간과 비용의 소모가 엄청나게 된다. 때문에 자동 코드 생성 툴을 쓰게 되면 이런 C 코드 생성에 필요한 시간과 비용을 절약하게 된다.SAE(Society of Automotive Engineers)는 자동차나 비행기등 엔진등의 힘에 의해서 움직이는 것들 취급하는 엔지니어들을 위한 가장 큰 협회중에 하나이다. 2004년에 Visteon 이라는 회사가 자동 코드 생성된 코드와 직접 손으로 작성한 코드를 비교한 논문을 제출했는데, LOC 비교가 아니라 생성된 코드를 위해서 필요한 ROM과 RAM의 사이즈를 비교했다. 표 1에 그 결과가 나와 있듯이 손으로 작성한 코드 보다 낳은 결과를 보임을 알 수 있다. 대부분 다른 회사에서 자동 코드 생성 툴을 썼을때의 결과를 보면 실제로 직접 작성한 코드와 비슷하거나 혹은 조금 안 좋은 결과를 보여 주지만, 사용되는 비용과 시간을 생각해 보면 충분히 자동 코드 생성 툴들을 이용할 만하다.
|
|
1.2 자동 코드 생성 툴
Simulink 모델에 대한 자동 코드 생성툴의 대표적인 소프트웨어가 같은 회사인 MathWorks사 제품인 Real-TIme Workshop(RTW라 칭한다)이다. 또 다른 소프트웨어로서 dSpace사의 TargetLink가 있다. 작년부터 MathWorks사는 소프트웨어를 6개월에 한번씩 출시하고 있는데, RTW의 경우 Simulink의 버전이 변경됨과 동시에 변경된 버전을 지원하고 있지만, TargetLink의 경우 Simulink 버전의 변경을 같이 따라가지 못하고 지난 버전을 지원한다. TargetLink의 경우 생성되는 코드를 사용자가 원하는 형태로 어느 정도 수정할 수 있는 기능이 있는데, RTW의 경우 이런 사용자의 수정을 할 수가 없도록 되어있다. 이런 작업을 하기 위해서는 Real-Time Workshop Embedded Coder(RTW-EC라 칭한다.)를 따로 구매해야 한다. 본 기사에서는 필자가 익숙한 RTW와 RTW-EC를 이용하여 설명하도록 하겠다.
![]()
|
복잡한 모델을 이용하여 설명하면 전체 코드를 보여 주지 못하므로, 그림 1와 같은 간단한 사칙 연산을 하는 모델을 만들어서 RTW와 RTW-EC를 이용하여 코드를 생성해서 어떤 차이가 있는지를 확인해 보자.
1.3 Real-Time Workshop
![]()
|
![]()
|
RTW를 사용하기 위해서는 그림 2와 같이 선택하면 그림 3와 같은 윈도우가 보여 지므로, 화살표로 설명한 부분중에서 System target file 부분에 있는 grt.tlc 파일이 코드가 어떻게 생성되기를 바라는지에 대한 내용을 미리 셋팅한 것이다. 왼쪽에 있는 메뉴에서 Real-Time Workshop 메뉴 아래에 생성되어 있는 메뉴는 System target file을 선택함에 따라 다르게 나타날 수 있다. RTW-EC의 경우 더 많은 메뉴가 생성된다.
![]()
|
이제 Generate code 버튼을 클릭하면 그림 4와 같은 윈도우가 생성되면서 생성된 코드를 볼 수 있게 해준다. 코드를 생성하고자 하는 모델의 이름이 sc.mdl 파일이기 때문에 sc.c와 같이 모델의 이름이 붙은 파일들이 생성된다. 소스 코드는 sc_grt_rtw 라는 폴더 안에 포함되며, html 리포트는 html 디렉토리 밑에 sc_codegen_rpt.html 파일을 열면 된다. 여기서 sc.c 파일에 실제로 모델의 알고리즘이 들어 있는 함수가 있으며, 함수의 이름을 어느 정도 짐작할 수 있을 것이다. 리포트 윈도우에서 함수에 관련된 부분만 보게 되면 아래와 같다. 예상한것처럼 함수의 이름은 sc_output 이다. 생성된 코드에서 주석 부분은 Simulink 모델중에서 어떤 블럭과 연계되어 있는지를 보여 준다. 물론 옵션으로 이런 주석 부분을 없앨 수도 있다.
27 /* Model output function */
28 static void sc_output(int_T tid)
29 {
30 /* Sum: ’<Root>/Add’ incorporates:
31 * Inport: ’<Root>/In1’
32 * Inport: ’<Root>/In2’
33 */
34 sc_B.Add = sc_U.In1 + sc_U.In2;
35
36 /* Math: ’<Root>/Math Function’ incorporates:
37 * Inport: ’<Root>/In3’
38 */
39 sc_B.MathFunction = exp(sc_U.In3);
40
41 /* Product: ’<Root>/Divide’ */
42 sc_B.Divide = sc_B.Add / sc_B.MathFunction;
43
44 /* Gain: ’<Root>/Gain’ */
45 sc_B.Gain = sc_P.Gain_Gain * sc_B.Divide;
46
47 /* Outport: ’<Root>/Out1’ */
48 sc_Y.Out1 = sc_B.Gain;
49 UNUSED_PARAMETER(tid);
50 }
모델에서코드를생성하게되면, 옵션을 선택해서 간단하게 만들 수 있는 코드는 최대한 간단하게 만들수 있는데, 아래의 코드는 주석문을 넣지 않고, Block Reduction과 Signal Reuse등의 옵션을 체크해서 나온 결과를 보여 준다.
8 static void sc_output(int_T tid)
9 {
10 sc_Y.Out1 = (sc_U.In1 + sc_U.In2) / exp(sc_U.In3) * sc_P.Gain_Gain;
11 UNUSED_PARAMETER(tid);
12 }
1.4 Real-Time Workshop Embedded Coder
지금까지 보여 준 것은 RTW를 이용해서 생성된 코드를 보여 줬는데, 실제로 RTW는 쉽게 이해하자면, Hardware-In-the-Loop(HIL)이나 Rapid Control Prototyping을 위한 코드를 생성해 준다. 실제로 임베딩하기 위해서 코드를 생성해야 하면, RTW-EC를 이용해야 한다. RTW-EC는 이름이 의미하는 것처럼 임베딩되기 위한 최적화된 코드를 생성해 준다. 아래 표 2는 그림 1에 있는 모델을 RTW와 RTW-EC로 코드를 생성했을때 생기는 파일들과 LOC(Line Of Code)이다. rtwtypes.h 파일이 RTW-EC에서 더 많은 LOC를 보여 주는 것은 RTW에서 생성된 파일은 다른 헤더 파일을 인클루드 하고 있기 때문이다. RTW-EC에서 생성된 파일은 다른 파일을 인클루드 하더라도 ANSI C 헤더 파일만을 인클루드 하기 때문에 LOC가 커지는 것이다.
|
|
RTW-EC는 기본적으로 다른 시스템에 C 코드와 합쳐서 실행되는 것을 목표로하는 코드를 생성하므로 인풋 인자를 가지는 함수 형태로 만들수 있다. 아래 코드는 인풋 3개와 아웃풋 1개를 가지고 게인값을 변경시킬수 있도록 함수의 인자로(총 5개) 받을 수 있도록 생성된 함수이다. 이와 같이 함수 형태로 만들어서 다른 환경, 즉 임베딩 시키고자 하는 환경에서 사용할 수 있도록 만들어 주는 제품이 RTW-EC이다.
4 void sc_step(Parameters_sc *sc_P, real_T sc_U_In1, real_T sc_U_In2, real_T
5 sc_U_In3, real_T *sc_Y_Out1)
6 {
7 (*sc_Y_Out1) = (sc_U_In1 + sc_U_In2) / exp(sc_U_In3) * sc_P->Gain_Gain;
8 }
그러면 RTW-EC로 생성된 코드는 어느 정도 정확성과 효율적일지가 궁금해진다. 이는 이미 수 많은 프로젝트에 사용되어서 그 효율성과 정확성은 어느 정도 입증되었다고 본다.
제 2 절 시뮬레이션과 실시간 테스트
앞 연재에서 시뮬레이션의 중요성을 강조했는데, 이제는 실제 하드웨어에서 실시간으로 플랜트를 제어할때도 같은 성능이 나오는지를 테스트 해야 한다. 이미 알고 있듯이 실시간으로 제어 하기 위해서는 윈도우 XP와 같은 범용 운영체제를 사용하지 않고, 실시간 성능을 지원하는 운영체제를 써야 한다. 가장 많이 쓰는 실시간 운영 체제는 윈드리버사의 VxWorks이다. 그 외에 리눅스에서 실시간 성능을 구현한 MontaVista도 있고, 교육용으로 많이 쓰는 uC-OSII 등 선택의 폭이 여러 가지 이다.범용 운영체제와 다르게 이런 실시간 운영체제는 특정한 보드에 포팅하거나 혹은 입출력을 위한 보드에 대한 드라이버는 직접 작성하는 수고를 해야 한다. 이런 작업은 하드웨어 종속적인 작업이라서 항상 수작업이 필요한 작업이다. 시뮬레이션으로 제어기 설계를 완료하고 이제 실시간으로 성능을 테스트 하기 위해서 다시 수작업으로 이런 일들을 해야 하므로 역시나 시간 소모적인 작업이다.
그럼 Simulink로 만든 모델을 실시간으로 빠르게 테스트 해보고 싶은데, 어떻게 하면 될까? 여기서 Rapid Control Prototyping(RCP)가 나오는 것이다.
2.1 Rapid Control Prototyping
RCP는 엔지니어가 시뮬레이션을 통해서 테스트한 알고리즘을 쉽고 빠르게 실제 하드웨어와 연결하여, 실시간으로 알고리즴을 테스트할 수 있는 방법을 말한다. 여기서 쉽고 빠르게가 강조 되는 것으로 알 수 있듯이, 시뮬레이션시에 사용한 모델을 그대로 자동 코드 생성 툴로 코드를 생성하여, 실시간 운영체제와 IO를 위한 디바이스 드라이버까지를 제공받아서 사용하는 것이다. 즉 엔지니어가 개발한 알고리즘을 다시 C로 코딩하는 작업과 실시간으로 하드웨어를 돌리기 위한 실시간 운영체제의 포팅과 디바이스 드라이버 작업을 하지 않고, 하드웨어의 연결로 빠르고 쉽게 알고리즘을 테스트할 수 있도록 하는 것이다.이와 같은 RCP의 경우 실제로 제공되는 제품들이 있다. 상용 제품과 오픈 소스 제품군으로 볼 수 있는데, 상용 제품군은 MathWorks사의 xPC Target, dSpace사의 AutoBox, National Instruments사의 LabView등이 있다. RCP 환경은 그 특성상 모델링 툴과 밀접한 연관을 가지고 있는데, NI사의 제품을 제외한 대부분의 RCP 상용 제품은 Simulink로 모델링하며, RTW로 생성된 코드를 자동으로 각 하드웨어에 맞는 디바이스와 실시간 운영체제와 인터페이싱하도록 구성된다. 오픈 소스는 Scilab/Scicos와 Linux RTAI를 활용한 방법등이 있으나, 전체가 패키지 형태로 묶여 있는 것은 아직 없는 실정이다.
2.2 Hardware-In-the-Loop
Hardware-In-the-Loop(HIL)은 간단하게 정의 하자면 실제 플랜트 대신에 수학적 모델링을 통해서 나온 모델을 실시간으로 실행시켜서 외부 인터페이스를 붙여서 플랜트 이외에 부분에 실제 하드웨어가 있는 것처럼 여기도록 하는 것이다. 즉 플랜트의 동역학 부분을 소프트웨어로 대체하는 것이 HIL의 개념이다.HILS에서도 결국엔 RCP장비에 임베딩시켜서 실행되는 것이므로 앞에서 설명한 RCP장비를 HILS(Hardware-In-the-Loop System)에서 사용할 수도 있다. 단지 자동 코드 생성되는 모델이 제어기인지 아니면 플랜트인지에 따라서 다른 것이다. 예전에는 제어기도 하드웨어로 구성했었으므로, RCP는 HILS에 포함되는 개념으로 생각해도 된다.
![]()
|
그림 5를 보면 RCP의 경우 제어기 모델을 자동 코드 생성을 통해서 하드웨어에 임베딩해서 실제 플랜트를 실시간으로 제어하는 경우이고, HIL의 경우 수학적으로 모델링된 플랜트를 실시간으로 실행하여 제어를 위한 로직등은 실제 하드웨어에 임베딩된 제어기로 제어하는 것으로 실제 하드웨어 플랜트 없이 하는 경우이다.
2.3 MBD를 활용한 실제 하드웨어 제어
이제 실제 소프트웨어에서 RCP로 제어하는 것을 예로 들어 보자. 여기서 예로 들 예제는 그림 6와 같이 UAV(Unmanned Aerial Vehicle)의 전체 모델중에 Carnard라고 하는 부분을 모델링하여 제어기 설계하고, 시물레이션을 통해서 그 성능을 검증하고, RCP환경의 하나인 xPC Target을 이용하여 제어기의 성능을 확인할 것이다.
![]()
|
Carnard는 DC 모터를 이용하여 제어 되고 있으므로, 전체 시스템을 모델링할때 필요한 부분이 DC 모터에 대한 부분이 필요하며, DC 모터에 가해지는 힘은 대기중의 저항이 큰 영향을 주므로 UAV의 특성상 대기에 대한 모델링도 필요하다. 이러한 것들을 전부 Simulink와 그 외 다른 툴을 이용하여 모델링을 한다. 플랜트와 제어기를 전부 모델링한 후에 시뮬레이션으로 제어기의 게인 값들을 선정하고, xPC Target을 이용하여 시뮬레이션 했을때의 결과와 실시간으로 하드웨어를 제어 했을때의 결과를 비교해 보도록 하겠다.
2.3.1 DC 모터 모델링
DC 모터는 그림 7와 같이 단순화 할 수 있으며, 이를 수학적 모델링을 하지 않고, Simulink의 add-on제품중에 플랜트 모델링을 쉽게 할 수 있도록 도와주는 Physical Modeling Tool을 이용하여 모델링을 하게 되면 그림 8와 같다. Aerodynamic Load는 DC 모터에 저항처럼 작용을 하지만, UAV의 고도에 따라서 달라 지는 점이 있다. 이런 대기의 모델을 미리 정해 놓은 것이 있어서 여기서 모델링은 ISA Atmosphere 모델을 이용하였다. 이 부분을 C로 직접 작성할 수도 있지만, 역시나 Simulink의 add-on중에 하나를 이용하면 그림 9와 같이 간단하게 하나의 블럭으로 표시할 수 있다.
![]()
|
![]()
|
![]()
|
2.3.2 증폭기 모델링
실제로 하드웨어를 구성하게 되면 모터를 구동할때 증폭기를 사용하게 된다. 증폭기의 특성을 직접 실험으로 테스트 해보면 그림 10와 같이 steady state 일때는 원하는 만큼 증폭이 되지만, transient state 일때는 오버슛도 보이고 하기 때문에 안정화 되기전에는 시스템에 원치 않는 영향을 미친다. 따라서 시뮬레이션할때도 이 부분이 고려되어야 한다. 증폭기를 수학적 모델링하는 것은 힘들기 때문에 이미 테스트한 입력값과 측정된 출력값을 이용하여 모델링을 한다. System Identification Toolbox를 이용하면 이런 과정을 좀 더 단순하고 간단하게 해준다.
![]()
|
2.3.3 Open-loop System
이런 모델링을 다 모아서 Simulink 모델로 합치고, 같은 역할을 하는 부분끼리 서브 시스템으로 묶으면 그림 11와 같이 나타난다. 이런 Open-loop 모텔이 제어 하고자 하는 플랜트가 되는 것이다. 이와 동등한 하드웨어 사진을 보면 그림 12
![]()
|
![]()
|
2.3.4 제어기 설계 및 RCP
이제 실제로 알고리즘 개발자가 개발해야 하는 제어기를 설계 하는 것이다. 당연히 Closed-loop으로 해야 하므로, Closed-loop 시스템으로 만들고 제어기를 개발할때는 지난 연재에서 설명한 툴들을 이용하여 설계 하게 된다. Simulation으로 원하는 각도로 입력값을 줬을때 그와 같은 출력값이 나오도록 제어기가 설계되었으면, 이제 실시간으로 테스트 해야 한다.실시간 테스트는 xPC Target이라는 툴을 이용하여 하게 되는데, 일반적인 PC에서 운영될 수 있는 xPC Target Real-Time Kernel이라는 실시간 운영체제를 제공한다. 실시간으로 외부 하드웨어와 인터페이스해야 하므로 A/D보드등이 필요한데, xPC Target에서 지정한 보드를 이용하면 이 보드에 대한 모든 소스 코드를 제공하므로 사용자가 이런 디바이스 드라이버 작성에 대한 고민도 할 필요가 없다. xPC Target이 다른 RCP 툴과의 차이점은 일반 PC를 사용하므로 만약 xPC Target에서 지정한 보드이외의 보드를 써야할 경우 드라이버 직접 작성해서 계속 재 사용할 수 있다는 장점이 있다. 즉 회사에서 직접 만든 보드의 경우 한번은 드라이버를 작성해야 하지만, 그 뒤로 그 보드를 쓸데는 계속해서 재 사용이 가능한 것이다. 다른 RCP를 지원하는 소프트웨어는 이런 개방적인 형태로 되어 있지 않은게 대부분이다. 즉, 자신들 만의 하드웨어만을 써야 하는 것이다.
Simulink로 만든 모델을 RTW를 이용하여 코드 생성하며, Microsoft Visual C++ 컴파일러를 이용하여, 실행 파일을 만들어서 Target PC에서 실행할 수 있도록 다운로드 한다. 즉 모델을 만드는 호스트 PC(Windows XP 이상)가 있으며, 실시간으로 실행되는 타겟 PC(xPC Target Real-Time Kernel)가 있어야 한다. 두 PC는 서로 TCP/IP 로 연결된다. 타겟 PC의 조종은 전부 호스트 PC에서 Simulink와 MATLAB 환경에서 하게 되며, 타겟 PC를 조정하기 위한 xpcexplr 라는 GUI 환경을 제공한다.
그림 13를 보면 시뮬레이션 결과 실제 하드웨어 테스트한 결과가 거의 유사함을 알 수 있다. 이와 같이 MBD를 이용하여 최대한의 시뮬레이션을 일반적인 PC 상에서 수행하고, 어느 정도 만족할 만한 결과가 나왔을때 RCP로 실시간에서의 성능을 테스트 하며, 실제로 보드와 같은 환경에 임베딩할때는 RTW-EC로 C코드를 생성해서 사용하면 된다.
![]()
|
이상과 같이 총 4회에 걸쳐 MBD에 대한 내용을 소개했는데, MBD를 제품 개발시에 도입하게 되면 시간과 비용의 절감을 가져 올 수 있으며, 개발자의 입장에서도 개발을 하기 위한 여러 가지 툴을 사용해서 최대한 편리한 환경에서 개발할 수 있으므로 한번쯤은 도입을 생각해 보기 바란다. 각 연재에서 설명한 툴등은 훨씬 더 많은 기능들이 있으므로 궁금한 내용이 있으면, 각 회사에 연락하거나 필자에게 연락하면 최대한 자세히 알려 주겠다. MBD를 이용한 개발은 국내 소프트웨어 개발자들에게는 생소할 수 있지만, 구글과 같은 써치 엔진에서 MBD를 검색해 보면 얼마나 많은 곳에서 사용하는지 알 수 있을 것이다.
RTW와 RTW-EC를 위한 모델과 소스 코드는 이달의 디스켓에 포함되어 있으니 생성된 코드가 어떤지 궁금하면 소스 코드를 열어 보기 바란다.

















댓글을 달아 주세요