2017-02-09 3 views
2

하나의 Modelica 변수가 다른 변수의 삼각형 파형 인 모델을 만들려고합니다. (X = 시간, 모델 컴파일 있도록 임의)모델에서 삼각 파 함수 생성

model test1 
    final constant Real pi=2*Modelica.Math.asin(1.0); 
    parameter Real b = 1; 
    parameter Real a = 1; 
    Real x,p,u; 
equation 
    if sign(sin(x*pi/b))>=0 then 
    p=a*(x-b*floor(x/b)); 
    else 
    p=a*(b-(x-b*floor(x/b))); 
    end if; 
    x=time; 
    u = floor(x/b); 
end test1 

하지만 enter image description here

아래에 볼 수있는 결과는, 이상해 : 우선 바닥() 아래와 같은 기능을 시도

확대 : 어떻게 든 0.005 초 다음 단계 바닥 능의 이전

enter image description here

n은 예기치 않게 동작하고 다음 값으로 끝나는 선형 함수가됩니다.

enter image description here

다음 I는 올림() 함수를 시도했다. 저도 같은 문제가 다른 값에 천장을 만들다() 함수를 어떻게 실현까지 모든 것이 잘 보였다 (예를 들어 X = 13)

당신이 수 있다면 감사하겠습니다이 "결함"이 발생하는 이유

  1. 도움이 나를 이해 디자인이나 버그로 고의적 인 경우?
  2. 어떻게 해결할 수 있습니까?
  3. 삼각파 함수를 만드는 다른 방법이 있습니까?

P. 나는 시뮬레이션의 결함에 대한 설명이없는 두 개의 톱니 몸 "

답변

2

사이의 상호 작용을 모델링하기 위해이"파동 함수 "를 사용하고 있습니다.

을 그러나, 나는 톱니 기능에 대한 또 다른 접근 방식을 취할 것 : +1과 -1을 통합 한 적분기로 보았습니다. 적분 시간은 톱니파 함수의 진폭과주기를 결정합니다.

아래 그림은 MSL 블록과 코드를 사용한 구현을 보여줍니다. 아래의 결과는 두 가지 구현에서 동일합니다.

B 동부 표준시 관련, 르네 그냥 닐슨

블록 다이어그램 : Block diagram implementation 코드 :

model test3 
    parameter Real a=2 "amplitude"; 
    parameter Real b=3 "period"; 

    Real u, y; 
initial equation 
    u = 1; 
    y = 0; 
equation 
    4*a/b*u = der(y); 
    when y > a then 
    u = -1; 
    elsewhen y < -a then 
    u = 1; 
    end when; 
end test3; 

시뮬레이션 결과 : 것 같아요 문제는 부동 소수점 때문이다 enter image description here

+0

다른 문제가 있습니다. 질문에서 볼 수 있듯이 x가 임의의 시간 함수 인 p = func (x)라는 함수를 갖고 싶습니다. 당신의 코드는 일정한 신호에 의존합니다. 그것을 수정할 수 있습니까? – Foad

2

표현과 사건은 정확한 시간에 나타나지 않는다.

시간 = 0.99에서 x-floor(x)1-(x-floor(x))을 고려하면, 이들은 0.990.01입니다. 시간 = 1.00 일 때 문제가 발생하는 0.01.0입니다.

a = b = 1 인 경우 p는 p=min(mod(x,2),2-mod(x,2));입니다. noEvent을 추가 할 수도 있으며, 신호를 연속적이라고 간주 할 수 있습니다 (그러나 구별 할 수는 없습니다). 당신은, 당신은 선형 보간 및주기적인 외삽와 CombiTimeTable 블록을 사용하여 매개 변수화, 시간 기반 지그재그 신호를 구축 할 수있는 Modelica 표준 라이브러리를 사용하도록 허용하는 경우

model test 
    parameter Real b = 1; 
    parameter Real a = 3; 
    Real x, p; 
equation 
    p = 2*a*min(1/b * mod(x, b),1 - 1/b * mod(x, b)); 
    x = time; 
end test; 
+0

mod() 함수는 가치가 있다고 생각합니다. 대답에 코드를 추가 하시겠습니까? 나는 또한 당신이 할 수 있으면 고맙게 여길 것이다. 1. noEvent() 함수에 대해 간단한 단어로 더 많이 알려줘. 나는 그것에 대해 읽으려고했지만 완전히 이해하지는 못했습니다. 2. 왜 이론적으로 차별화되지 않는 신호가 Modelica에서는 괜찮 았지만 다른 신호는 그렇지 않은지 알려주십시오. 예를 들어 floor() 함수는 미분 가능하지 않아야하지만 OpenModelica는 오류없이 컴파일됩니다. – Foad

+0

'noEvent'는 그것을 수행하므로 해석자는 런타임에 제로 크로싱을 찾으려고하지 않습니다. 기본적으로 이벤트가 끝난 직후에 시간이 있는지 여부를 알 수 없습니다. 때로는 noEvent가없는 경우 if 식의 조건에 예상치 못한 일이 발생할 수 있습니다. 그리고 차별화 된 기능에 대해서 : 색인 축소를 수행 할 때 (또는 도구가 Jacobians에 의존하는 경우)에만 필요합니다. 일부 함수는 구분할 수 있으며 함수도 사용할 수 있습니다 (함수가 이벤트를 제공하는 경우 파생 함수가 이벤트 중에 사용되지 않고 왼쪽과 오른쪽에 표시되기 때문에). –

4

. foo>=0에 비해 sign(foo)>=0을하는 어떤 이득이 없기 때문에 예를 들어,

model Test4 
    parameter Real a=2 "Amplitude"; 
    parameter Real b=3 "Period"; 
    Real y=zigzag.y[1] "Zigzag"; 
    Modelica.Blocks.Sources.CombiTimeTable zigzag(
    table=[0,0;b/4,a;b/4,a;b/2,0;b/2,0;3*b/4,-a;3*b/4,-a;b,0], 
    extrapolation=Modelica.Blocks.Types.Extrapolation.Periodic) 
    annotation(Placement(transformation(extent={{-80,60},{-60,80}}))); 
    Modelica.Blocks.Sources.Trapezoid trapezoid(
    amplitude=2*a, 
    rising=b/2, 
    width=0, 
    falling=b/2, 
    period=b, 
    offset=-a) 
    annotation(Placement(transformation(extent={{-80,25},{-60,45}}))); 
    annotation(uses(Modelica(version="3.2.2"))); 
end Test4; 
+0

감사합니다. 제 생각으로는 전체 Modelica 세계에 매우 익숙해 져 있습니다. 제 질문이 어리석은 짓이라면 사전에 사과드립니다. 우선 코드를 해봤지만 성공적으로 컴파일 할 수 있지만 그릴 수있는 두 개의 매개 변수는 상수 a와 b뿐입니다. 코드에 다른 변수를 추가 하시겠습니까? x 및 y와 같이 그릴 수 있습니까? C의 배경에서 오는 나는 전체 블록 개념에 익숙하지 않다. 그렇지 않으면 나는 그것을 직접 추가 할 것이다. 두 번째 요점은 Modelica 표준 라이브러리에 Trapezoid 블록이 있다는 것입니다. 왜 그것을 사용하지 않습니까? – Foad

+0

원하는 출력 변수 'y'를 갖도록'Test4' 모델을 업데이트했습니다. 'x = time'은 CombiTimeTable에 대해 암시 적이기 때문에 시간보다 다른 입력에 대한 가능성은 없습니다. 예, 사다리꼴 신호를 사용할 수도 있지만 시간 만 이동하면됩니다 ('Test4'도 참조). – DelmeDelmi

2

나의 첫번째 조언은, 로그인 기능을 제거하는 것입니다.

이제
model test1 "almost original" 
    final constant Real pi=2*Modelica.Math.asin(1.0); 
    parameter Real b = 1; 
    parameter Real a = 1; 
    Real x,p,u; 
equation 
    if sin(x*pi/b)>=0 then 
    p=a*(x-b*floor(x/b)); 
    else 
    p=a*(b-(x-b*floor(x/b))); 
    end if; 
    x=time; 
    u = floor(x/b); 
end test1; 

난 단지 그것을 설명해야 - 그리고 이유는 sin(x*pi/b)가와 동기화 약간 점이다 : 나는 OpenModelica 또한 가정 - Dymola에서 문제를 해결하는 것만큼 재미있는

바닥 기능 -하지만 루트 발견 엡실론 안에있는 sin(x*pi/b)>=0을 사용하면 이상한 일은 발생하지 않습니다.

대신 지금 -1이며, 0 대신 위의 엡실론의 그것이 진정한 솔루션 따라서 약간 더 복잡하다 1.

입니다 영하 sin(x*pi/b) 엡실론을 필요없이 더 이상 가능하지 그 sign(sin(x*pi/b))>=0를 사용 제에서

model test3 "almost working" 
    parameter Real b = 1; 
    parameter Real a = 1; 
    Real x,p,u; 
equation 
    if mod(x,2*b)<b then 
    p=a/b*mod(x,b); 
    else 
    p=a-a/b*mod(x,b); 
    end if; 
    x=time; 
    u = floor(x/b); 
end test3; 

요점 : 개선 제안 된 솔루션에 기반

model test2 "working" 
    parameter Real b = 1; 
    parameter Real a = 1; 
    Real x,p,u; 
    Real phase=mod(x,b*2); 
equation 
    if phase<b then 
    p=a/b*phase; 
    else 
    p=a-a/b*(phase-b); 
    end if; 
    x=time; 
    u = floor(x/b); 
end test2; 

테스트 2는 문제가있는 이벤트가 하나만 발생하여 mod(x,2*b)이라는 표현식을 생성하고 <이 동기화되지 않게됩니다.

실제로는 test3도 거의 효과가 있지만 드문 경우이지만 이벤트 생성이 mod(x,2*b)mod(x,b) 사이에서 동기화되지 않을 수 있습니다. 알 수없는 결과가 있습니다.

세 가지 예 모두가 유사하게 보이는 출력을 생성하도록 수정되었습니다.

+0

먼저 답을 알려 주셔서 감사합니다. 두 번째 코드는 포함 된 신호를 생성하는이 페이지의 첫 번째 솔루션입니다. 둘째, 두 번째 코드에서 b는 절반 인 것으로 보입니다. 고칠 수 있습니까? 셋째, 첫 번째 코드가 문제를 해결하지 못합니다. OpenModelica와 Wolfram SystemModeller에서 모두 시도했습니다. 마지막으로 sign() 함수를 제거하는 것이 옳다. 그것을 제거하는 것은 나를 바보로 만들었지 만 그것을 제거해도 내 문제는 해결되지 않습니다. – Foad

+0

''pi''를위한'Modelica.Constants.pi'도 있습니다. – DelmeDelmi