Found an issue with the book? Report it on Github.

software-in-the-Loop 제어기(Software-in-the-Loop Controller)

software-in-the-Loop 제어기(Software-in-the-Loop Controller)

이전 보간(Interpolation) 예제에서 외부 C 함수를 사용하여 데이터를 관리하고 보간할 수 있음을 확인했으며,이 섹션에서는 임베디드 컨트롤러용 C 코드를 모델리카 모델에 통합하는 방법을 살펴보겠습니다.

(외부) 제어를 위한 동작 방법(strategies)을 통합하여 물리적 시스템의 수학적 모델을 모델리카로 구현하는 것이 때때로 유용합니다.왜냐하면, 대부분의 경우 이러한 동작 방법은 임베디드 컨트롤러와 함께 사용하기 위해 생성된 C 코드로 존재하기 때문 입니다.이 예제는 이전에 다룬 히스테리시스(Hysteresis) 주제를 다시 살펴보겠지만, 불연속 상태를 사용하여 모델리카에서 히스테리시스 동작을 구현하는 대신 외부 C 함수에서 구현하겠습니다.이 예제는 매우 간단하지만 외부 제어를 위한 동작 방법을 통합하는 데 필요한 모든 필수적인 과정을 보여줍니다.

물리적 모델(Physical Model)

이전에 보여줬던 "물리적 모델"부터 살펴보겠습니다.이 경우, 본질적으로 히스테리시스(Hysteresis) 에 대해 논의하는 동안 이전에 생성한 모델을 다시 구현한 것과 같습니다.수정된 구현은 다음과 같습니다.

model HysteresisEmbeddedControl "A control strategy that uses embedded C code"
  type HeatCapacitance=Real(unit="J/K");
  type Temperature=Real(unit="K");
  type Heat=Real(unit="W");
  type Mass=Real(unit="kg");
  type HeatTransferCoefficient=Real(unit="W/K");
  parameter HeatCapacitance C=1.0;
  parameter HeatTransferCoefficient h=2.0;
  parameter Heat Qcapacity=25.0;
  parameter Temperature Tamb=285;
  parameter Temperature Tbar=295;
  Temperature T;
  Heat Q;
initial equation
  T = Tbar+5;
equation
  when sample(0, 0.01) then
    Q = computeHeat(T, Tbar, Qcapacity);
  end when;
  C*der(T) = Q-h*(T-Tamb);
end HysteresisEmbeddedControl;

equation 섹션을 자세히 살펴보겠습니다.

equation
  when sample(0, 0.01) then
    Q = computeHeat(T, Tbar, Qcapacity);
  end when;
  C*der(T) = Q-h*(T-Tamb);
end HysteresisEmbeddedControl;

computeHeat 함수는 사용할 열의 양을 결정하기 위해 10밀리초마다 호출됩니다. 잠시 후에 살펴보겠지만 "bang-bang" 제어 방법, 즉 발열 이 없는 상태(제로)와 완전 발열 사이를 전환하도록 컨트롤러를 구현합니다.:ref:hysteresis 에 대한 이전 논의에서 보았듯이 이러한 종류의 접근 방식은 "채터링"으로 이어질 수 있습니다.그런 이유로 10밀리초마다 실행되는 when 문 안에 Q 계산을 넣습니다. 이 10밀리초 간격은 본질적으로 다른 제어 상태에대한 절환 시점을 결정하는 (일반적으로 "스케줄러"라고 하는) 동작을 구현합니다.

임베디드 제어 구현 방법(Embedded Control Strategy)

주어진 시간 동안 시스템에 열을 얼마나 적용해야 하는지 결정하는 모델리카 함수인 computeHeat 는 다음과 같이 구현합니다.

impure function computeHeat "Modelica wrapper for an embedded C controller"
  input Real T;
  input Real Tbar;
  input Real Q;
  output Real heat;
  external "C" annotation ...
end computeHeat;

이번에는 이전 예제에서와 같이 외부 C 함수의 이름이 external 키워드 부분에 없는데,이것은 외부 C 함수가 모델리카 대응 함수와 정확히 동일한 이름과 인수를 가짐을 의미합니다. C 함수의 소스 코드를 보면 다음과 같은 경우임을 알 수 있습니다.

#ifndef _COMPUTE_HEAT_C_
#define _COMPUTE_HEAT_C_

#define UNINITIALIZED -1
#define ON 1
#define OFF 0

double
computeHeat(double T, double Tbar, double Q) {
  static int state = UNINITIALIZED;
  if (state==UNINITIALIZED) {
    if (T>Tbar) state = OFF;
    else state = ON;
  }
  if (state==OFF && T<Tbar-2) state = ON;
  if (state==ON && T>Tbar+2) state = OFF;

  if (state==ON) return Q;
  else return 0;
}

#endif

즉, 매핑이 실제로 필요하지 않은 방식으로 정의함으로써 모델리카 함수의 입력 및 출력 인수가 기본 C 함수의 인수에 매핑되는 방식을 지정하는 수고를 덜 수 있습니다.

computeHeat 의 C 구현에 static 변수 state 가 있는데,여기에서 static 키워드를 사용한다는 것은 state 변수의 값이 computeHeat 호출에서 다음 호출로 유지된다는 것을 나타냅니다. 이러한 종류의 변수는 스케줄러의 한 호출에서 다음 호출까지 정보를 보존해야 하기 때문에 임베디드 제어 방법에서 매우 일반적으로 사용합니다.(예: 여기에서 볼 수 있듯이 히스테리시스 제어를 구현하기 위해).

static 변수의 존재는 computeHeat 함수가 동일한 입력 인수에 대해 다른 결과 를 반환할 수 있음을 의미하기 때문에 중요한 문제입니다.함수가 입력 인수에만 의존 하는 것은 수학적으로 표현할 수 있는데, 이것은 진정한 의미에서 수학 함수가 아닙니다.컴퓨터 과학에서는 그러한 함수를 "순수하지 않다(impure)"고 말합니다. 즉, 함수를 호출할 때마다 일부 내부 메모리 또는 함수가 반환하는 값에 영향을 주는 변수가 변경되는 것 입니다.

설계에 따라 임베디드 제어 방법을 구현하기 위해 이렇게 순수하지 않은 것도 사용해야 할 때, 모델리카와 같은 수학 지향 환경에서는 주의해야 합니다. 모델리카 컴파일러는 기본적으로 모든 함수가 순수하고 다른 영향(side effect)이 없다고 가정하고 있습니다. 만약 순수하지 않은 것이나 다른 영향을 줄 수 있는 것의 경우 매우 비효율적인 시뮬레이션 또는 최악의 경우 완전히 잘못된 결과를 초래할 수 있다고 가정하기 때문입니다.

이러한 문제는 기본 솔버가 "실제" 해를 계산하기 전에 많은 "후보(candidate)" 해를 계산해야 하기 때문에 발생합니다. 후보 해를 생성하기 위해 솔버가 다른 영향이 있는 함수를 호출해야 하는 경우 솔버는 예상하지 못하는 변수의 변경으로 인해 트리거되는 효과를 예상할 수 없습니다.

computeHeat 정의에 impure 한정자가 적용되는 것은 바로 이러한 이유 때문입니다.

impure function computeHeat "Modelica wrapper for an embedded C controller"
  input Real T;

이것은 이 함수에 다른 영향을 주는 부분이 있거나 입력 이외의 항목에 의존하는 결과를 반환 하면 안되고, 후보 해를 생성할 때에 호출해서는 안 됨 을 모델리카 컴파일러에게 알립니다.처음에는 함수 호출을 완전히 금지하는 것처럼 보이겠지만 그렇지 않습니다.제어 방법을 구현하는 것을 다시한번 생각해 보겠습니다.

equation
  when sample(0, 0.01) then
    Q = computeHeat(T, Tbar, Qcapacity);
  end when;
  C*der(T) = Q-h*(T-Tamb);
end HysteresisEmbeddedControl;

특히 computeHeatwhen 문 내에서만 호출되며 "연속" 방정식의 일부로는 호출되지 않습니다.결과적으로 computeHeat 가 이벤트에 대한 응답으로만 호출되고 연속 변수에 대한 후보 해를 해석할 때는 호출되지 않는다는 것을 확신할 수 있습니다.

결과(Results)

C 함수 computeHeat 에서 아래 두 문장이 설정 온도 주위에 +/- 2도만큼 감지되지 않는 영역을 구현한 것을 알 수 있습니다.

  if (state==OFF && T<Tbar-2) state = ON;
  if (state==ON && T>Tbar+2) state = OFF;

예제의 시뮬레이션 결과를 통해 채터링을 방지했다는 것을 명확히 알 수 있습니다.

/static/_images/SIL.svg