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

동기 시스템(Synchronous Systems)

동기 시스템(Synchronous Systems)

모델리카 버전 3.3에서는 비결정적 이산 동작에 대한 문제를 해결하기 위해 새로운 기능이 도입되었습니다 [Elmqvist].이 섹션에서는 이러한 문제가 버전 3.3 이전에 어떻게 나타났는지에 대한 몇 가지 예를 제시하고 새로운 기능이 이전의 문제를 해결하는 데 어떻게 도움이 되는지 보여줍니다.

다음 모델을 살펴 보겠습니다.

model IndependentSampling "Sampling independently"
  Real x "Sampled at 10Hz via one method";
  Real y "Sampled at 10Hz via another method";
  Real e "Error between x and y";
  Real next_time "Next sample for y";
equation
  when sample(0,0.1) then
    x = time;
  end when;

  when {initial(), time>pre(next_time)} then
    y = time;
    next_time = pre(next_time)+0.1;
  end when;
  e = x-y;
end IndependentSampling;

자세히 보면 xy 가 둘 다 불연속 시간으로 계산된다는 것을 알 수 있고, 시뮬레이션 시작 시 처음에 샘플링된 다음 0.1초마다 다시 샘플링 하는 것을 이해 할 수 있습니다. 그러나 "여기서 이 두가지가 정말로 동일한가" 라는 의문을 가지게 됩니다. 이 질문을 해결하는 데 도움이 되도록 이들 간의 차이를 측정하는 변수 e 를 추가하여 시뮬레이션 했습니다.

/static/_images/SIS.svg

이 모델을 시뮬레이트하면 xy 에 대한 궤적의 모양은 같습니다. 그러나, 실제로 차이점을 확인하기 위한 오류 값 e 를 살펴보면 아래와 같습니다.

/static/_images/SIS_e.svg

이제 다음 모델을 살펴 보겠습니다.

model SynchronizedSampling "A simple way to synchronize sampling"
  Integer tick "A clock counter";
  Real x, y;
  Real e "Error between x and y";
equation
  when sample(0,0.1) then
    tick = pre(tick)+1;
  end when;

  when change(tick) then
    x = time;
  end when;

  when change(tick) then
    y = time;
  end when;

  e = x-y;
end SynchronizedSampling;

여기에서 두 변수에 대한 할당을 트리거하는 공통의 신호를 설정합니다.이런 식으로 설정하면 tick 신호가 참이 될 때 xy 에 값이 할당된다는 것을 확실히 알 수 있습니다.당연한 것이겠지만, 이 모델을 실행하면 오류가 항상 0임을 아래 선도와 같이 알 수 있습니다.

/static/_images/SSS.svg

각 신호가 공통 "틱"(또는 클록)을 기준으로 샘플링되는 이러한 접근 방식은 결정성 문제를 방지하는 좋은 방법입니다. 그러나 다른 신호보다 더 높은 속도로 샘플링하는 하나의 신호가 있지만 특정 시간에 함께 샘플링해야 하는 경우는 어떻게 해야할 까요? 다음 예를 살펴 보겠습니다.

model SubsamplingWithIntegers "Use integers to implement subsampling"
  Integer tick "Clock counter";
  Real x, y, z;
equation
  when sample(0,0.1) then
    tick = pre(tick)+1;
  end when;

  when change(tick) then
    x = time;
  end when;

  when change(tick) then
    y = time;
  end when;

  when mod(tick-1,2)==0 then
    z = time;
  end when;
end SubsamplingWithIntegers;

이 경우 tick 변수는 변경될 때마다 xy 값을 업데이트하는 카운터입니다.이 부분은 이전 모델과 동일합니다. 그러나 tick 값이 홀수일 때만 샘플링되는 세 번째 신호 z 를 추가했고, xy 가 이것 보다 두 배로 자주 샘플링됩니다(xy 가 2번 일때 한번 호출 됩니다). 호출 주기는 다르지만, z 가 업데이트될 때마다 xy 가 정확히 동시에 업데이트된다는 것을 확인할 수 있습니다. 이 모델을 시뮬레이션하면 다음 결과를 얻을 수 있습니다.

/static/_images/SSI.svg

이것은 버전 3.3 이전의 모델리카에서 취한 접근 방식입니다. 그러나 버전 3.3에서는 이러한 상황을 보다 쉽게 표현할 수 있는 몇 가지 새로운 기능을 도입했습니다.

다음 모델을 통해 확인해 보겠습니다.

model SamplingWithClocks "Using clocks to sub and super sample"
  Real x, y, z, w;
equation
  x = sample(time, Clock(1,10));
  y = sample(time, Clock(1,10));
  z = subSample(x, 2);
  w = superSample(x, 3);
end SamplingWithClocks;

이제 when 문에 의존하는 대신 sample 함수라는 향상된 버전의 구문을 사용합니다.여기서 첫 번째 인수는 샘플링된 값을 결정하기 위해 연산되어야 하는 표현식이고, 두 번째 인수는 언제 연산을 할지 설정 합니다. 이 코드를 하나씩 살펴 보겠습니다.

  x = sample(time, Clock(1,10));

0.1 이라는 표현이 없다는 점을 확인할 수 있습니다.클록 간격에 대한 언급이 더 이상 실수로 표시되지 않는 대신, Clock 연산자를 사용하여 x 에 대한 클럭 간격을 유리수로 정의합니다. 이를 통해 클럭 간의 정확한 비교를 수행할 수 있기 때문에 중요한 부분 입니다.다음 줄을 보겠습니다.

  y = sample(time, Clock(1,10));

다시, clock으로 표현하는 것이 합리적인 이유를 살펴 보겠습니다. 이것이 의미하는 바는 사실 두 clock인 xy 가 정확한 비교를 허용하는 정수 수량으로 정의되기 때문에, 동일하다는 것을 확실히 모델리카 컴파일러가 알 수 있다는 것입니다.즉, 시뮬레이션을 실행할 때 이 두 클럭이 동시에 트리거된다는 것을 확실히 보장할 수 있습니다.

x 의 절반만큼 느린 시계를 만들고 싶다면 subSample 연산자를 사용하여 이를 달성할 수 있습니다. z 의 정의에서 이것을 볼 수 있습니다:

  z = subSample(x, 2);

연산할 때, 모델리카 컴파일러는 이러한 클럭에 대해 추론할 수 있습니다. x 클럭이 1초마다 \frac{1}{10} 를 트리거한다는 것을 알고 있고, subSample 연산자가 제공하는 정보를 사용하여 z 가 1초마다 \frac{2}{10} 를 트리거한다고 모델리카 컴파일러는 추론할 수 있습니다. 개념적으로 이는 z 가 다음과 같이 정의될 수도 있음을 의미합니다.

z = sample(time, Clock(2,10));

그러나 subSample 연산자를 사용하여 x 를 사용하여 z 를 정의 함으로써, x 가 어떻게 정의 되는지에 관계 없이, 항상 x 를 기준으로 z 를 사용할 수 있습니다.

유사한 방식으로 superSample 연산자를 사용하여 x 보다 3배 더 자주 트리거하는 w 라는 또 다른 clock을 정의할 수 있습니다.

  w = superSample(x, 3);

다시 말하지만, 다음과 같이 sample 을 사용하여 w 를 직접 정의할 수 있습니다.

w = sample(time, Clock(1,30));

또한, superSample 을 사용하면 w 가 항상 x 보다 3배, z 보다 6배 빠르게 샘플링하도록 할 수 있습니다.(zx 에 대해서도 정의됩니다)

모델리카의 동기식 클락(synchronous clock) 기능은 비교적 새로운 기능입니다. 따라서 아직 모든 모델리카 컴파일러에서 지원되지 않습니다. 이러한 동기 기능 및 해당 응용 프로그램에 대한 자세한 내용은 [Elmqvist] 또는 모델리카 사양(specification)의 버전 3.3 이상을 참조하십시오.

[Elmqvist] (1,2)

"Fundamentals of Synchronous Control in Modelica", Hilding Elmqvist, Martin Otter and Sven-Erik Mattsson http://www.ep.liu.se/ecp/076/001/ecp12076001.pdf