2017-02-09 17 views
2

私は、Modelica変数が別の変数の三角波であるモデルを作成しようとしています。 (X =時間;モデルがコンパイルので任意である)Modelicaで三角波関数を生成する問題

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

の下に見ることができるように、結果は、奇妙である:まず、私は床()として以下の機能を試してみました次のステップフロアの前に

enter image description here

何とか0.005秒functio:中

ズームnは予期せぬ動作をし、次の値で終わる線形関数になります。

enter image description here

私はCEIL()関数を試みました。私は同じ問題が他の値で切り上げ()関数で発生実現まですべてが右に見えた(例えば、x = 13)

あなたができれば、私は感謝:この「グリッチ」はなぜ起こるか

  1. 助け、私は理解してそれが設計やバグによって意図的なものであれば?
  2. どうすれば修正できますか?
  3. 三角波関数を作成する方法はありますか?

P.私はあなたのシミュレーションでグリッチの説明を持っていない2人のギザギザ体」

答えて

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

私は別の問題があります:質問にあるように、関数p = func(x)が必要です。ここで、xは時間の任意の関数です。あなたのコードは一定の信号uに依存します。あなたはそれを変更できますか? – Foad

2

表現や出来事は正確な時期には起こらない。

は、彼らが0.990.01あり、150時間= x-floor(x)1-(x-floor(x))を考えてみましょう。時間= 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()関数の詳細を簡単な言葉で教えてください。私はそれについて読むことを試みたが、完全には理解していなかった。なぜ私は理論的に区別できないいくつかの信号は、ModelicaでOKですが、他の信号はなぜですか?例えばfloor()関数は微分可能ではないが、OpenModelicaはエラーなしでコンパイルする。 – Foad

+0

'noEvent'はソルバーが実行時にゼロクロスを見つけようとしないようにする。基本的に、イベントの直後に時間があるかどうかは本当に分かりません。時には、noEventが存在しない場合、if式の条件に予期しないことが起こることがあります。また、微分可能な関数については、インデックス縮小を行う場合(またはツールがヤコビ行列に依存する場合)にのみ必要です。部分的に微分可能な関数もあれば、機能しているものもあります(関数がイベントを与えた場合、その派生関数はイベント中には使用されず、左右に存在します)。 –

4

。例えば、

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

ありがとうございました。私はあなたのコードを試してみましたが、それはうまくコンパイルされますが、描画することができる唯一の2つのパラメータは定数aとbです。コードにxやyのような他の変数を追加してもらいたいですか? Cの背景から来ている私はブロック全体の概念に慣れていない、そうでなければ私はそれを自分で追加するだろう。 2番目の点は、Modelica標準ライブラリに台形ブロックもあることです。なぜそれを使用していないのですか? – Foad

+0

希望の出力変数「y」を持つように 'Test4'モデルを更新しました。 'x = time'はCombiTimeTableに対して暗黙的なものであるため、時間以外の入力には可能性はありません。 はい、台形信号を使用することもできますが、時間がずれているだけです( 'Test4'も参照してください)。 – DelmeDelmi

2

私の最初のアドバイスはfoo>=0に比べsign(foo)>=0を行うための何のメリットがないため、サインイン機能を削除することです。

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である代わりに、イプシロン、ゼロ以下sin(x*pi/b)を有していると、もはや不可能で

あなたがsign(sin(x*pi/b))>=0を使用し、代わりに、イプシロンのゼロ以上、それは真の解決策は、このように少し複雑です。1.

です目に

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; 

解決策test2は、式mod(x,2*b)を生成する問題イベントが1つしかなく、<がこれと同期を失わないということです。

実際にはtest3もほぼ確実に動作しますが、ほとんどの場合、イベントの生成はmod(x,2*b)mod(x,b)の間で同期しないことがあります。未知の結果を伴います。

3つの例すべてが同様の出力を生成するように変更されていることに注意してください。

+0

まずはお返事に感謝します。 2番目のコードは、このページの最初のソリューションであり、containsシグナルを生成します。 2番目のコードでは、bが半分の期間であるようです。あなたはそれを修正できますか?第三に、あなたの最初のコードは問題を解決しません。私はOpenModelicaとWolfram SystemModellerの両方でそれを試しました。最後に、sign()関数を削除することが絶対に正しいです。それを追加する私の愚かだった:)、それを削除することは私の問題を解決しません。 – Foad

+0

'' pi''の 'Modelica.Constants.pi'もあります。 – DelmeDelmi

関連する問題