Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Modelica中三角波函数生成问题_Modelica_Openmodelica - Fatal编程技术网

Modelica中三角波函数生成问题

Modelica中三角波函数生成问题,modelica,openmodelica,Modelica,Openmodelica,我试图创建一个模型,其中一个Modelica变量是另一个变量的三角波。首先,我尝试了floor()函数,如下所示: 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

我试图创建一个模型,其中一个Modelica变量是另一个变量的三角波。首先,我尝试了floor()函数,如下所示:

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
(x=时间;是任意的,因此模型可以编译)

但是结果很奇怪,正如你在下面看到的

放大:

不知何故,在下一步之前0.005秒,楼层函数意外地发生行为,并成为以下一个值结束的线性函数

然后我尝试了ceil()函数。在我意识到ceil()函数在其他值(例如x=13)时也会出现同样的问题之前,一切似乎都是正确的

如果您能:

  • 请帮助我理解为什么会发生这种“小故障”,以及它是否是设计或bug故意造成的
  • 我怎样才能解决这个问题
  • 有没有其他方法可以创建三角波函数

  • 顺便说一句,我用这个“波函数”来模拟两个锯齿状物体之间的相互作用“

    我无法解释你的模拟中出现的小故障

    然而,我会对锯齿函数采取另一种方法:我把它看作是一个积分器,向上和向下积分+1和-1。积分时间决定了锯齿函数的振幅和周期

    下图显示了一个使用MSL块的实现和一个使用代码的实现

    致以最良好的祝愿, 雷内·贾斯尼尔森

    框图: 代码:

    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;
    
    模型测试3
    参数实a=2“振幅”;
    参数实b=3“周期”;
    真u,y;
    初始方程
    u=1;
    y=0;
    方程式
    4*a/b*u=der(y);
    当y>a时
    u=-1;
    否则当y<-a那么
    u=1;
    结束时;
    结束试验3;
    
    模拟结果:

    我想问题是由于浮点表示和事件没有在准确的时间发生

    考虑
    x层(x)
    1-(x层(x))
    在时间=0.99时,它们是
    0.99
    0.01
    ;在时间=1.00时它们是
    0.0
    1.0
    ,这会导致您的问题

    对于a=b=1,可以使用以下公式计算p: <代码> p= min(mod(x,2),2-mod(x,2));。甚至可以将<代码> Novivs/COD>添加到它,并且可以考虑信号连续(但不可微)。< /P>
    如果允许您使用Modelica标准库,您可以使用CombitMetable块,通过线性插值和周期外推,建立参数化、基于时间的锯齿形信号。例如

    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;
    

    我的第一个建议是删除sign函数,因为与
    foo>=0
    相比,执行
    sign(foo)>=0
    没有任何好处

    有趣的是,这似乎解决了Dymola中的问题——我假设OpenModelica中也存在这样的问题:

    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)
    与floor函数稍微不同步,但是如果使用
    sin(x*pi/b)>=0
    ,这在根查找ε内,不会发生奇怪的事情

    当您使用符号(sin(x*pi/b))>=0时,这不再可能,而不是使用小于零的ε,它现在是-1,而不是大于零的ε,它是1

    因此,真正的解决方案稍微复杂一些:

    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“正常工作”
    参数实数b=1;
    参数实数a=1;
    实x,p,u;
    实相=mod(x,b*2);
    方程式
    
    如果阶段性问题很多,请考虑我对整个MODEICA世界非常陌生,所以我先道歉,如果我的问题看起来很愚蠢:首先我尝试了你的代码,它确实编译成功,但是唯一可能绘制的两个参数是常量A和B。你可以把其他变量添加到你的代码中,比如X和Y,它们可以是D。rawn?来自C背景,我不熟悉整个块的概念,否则我会自己添加它。第二点是Modelica标准库中也有一个梯形块。为什么不使用它呢?我更新了
    Test4
    模型,使其具有所需的输出变量
    y
    x=time
    对于Comb是隐式的iTimeTable,因此除了时间之外,没有其他输入的可能性。是的,您也可以使用梯形信号,但只能在时间上移动,另请参见
    Test4
    。我认为mod()函数值得一试。您介意将代码添加到您的答案中吗?如果可以,我也将不胜感激:1.让我了解更多关于noEvent()的信息用简单的话来说函数。我试着去读它,但没有完全理解。2.让我知道为什么一些理论上不可微的信号在Modelica中是可以的,而其他的则不行?例如floor()函数不应该是可微的,但OpenModelica编译时不会出现任何错误
    noEvent
    使其成为可微函数,因此解算器不会在运行时尝试查找过零。基本上,您不知道是否在事件发生后才获得时间。有时,如果if表达式中的条件发生错误,则可能会出现意外情况e是不存在的。关于可微函数:它们仅在执行索引缩减时(或者如果工具依赖于雅可比矩阵)才是必需的。有些函数是分段可微的,并且可能也可以工作(如果函数给出事件,因为在事件期间不使用导数,并且呈现在左侧和右侧)。首先,非常感谢您的回答。您的第二个代码是本页中生成包含信号的第一个解决方案。第二,在您的第二个代码中,b似乎是半周期。您能修复它吗?第三,您的第一个代码不能解决问题。我在OpenModelica和Wolfram SystemModeler中都尝试过。最后,您完全正确关于删除sign()函数,我真是太蠢了,添加了:),尽管删除它并不能解决我的问题。还有
    Modelica.Constants.pi
    pi
    。我还有一个iss
    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;
    
    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;