离散系统小步长更新问题

问题描述

1、在仿真中没有连续系统时,也会有小步长的更新。 2、对于有些模块例如通信模块,如果跟随连续系统的求解器进行小步长更新,会影响与其他系统之间的交互。 所以,目前希望只让一些特定的模块(根据simulink)有跟随小步长的选项来增加准确性,其他的不跟随,且在没有连续系统的情况下不应有小步长更新

解决方案

问题1

  1. 对于只有连续系统的模型,在每一个step()中,执行完outputupdate后,就已经完成了该步长的更新,不需要调用求解器。因此在执行solve时要先判断该模型是否有连续系统,没有的话solve就立即结束,如果有的话,再进行求解器的求解。
  2. 在构建模型的时候,会维护布尔变量no_continuous_system,在solve中对其进行判断,如果为True则跳过求解器求解环节。
  3. 测试如下,设置一个只有离散系统的模型,subsystem中只有一个gain系统,设置起始时间0,终止时间3,步长为1。output时输出当前时间,从结果可以看到只在大周期更新。

问题2

  1. 有一些特定的离散模块(比如通信模块),因为模型中有连续系统,所以这些离散系统在小周期也会进行output输出,就会出现小周期也进行通信。求解器阶数不同时,小周期次数不同,通信次数也不同,不方便同步控制。
  2. 考虑离散系统和连续系统相连的情况,小步长更新时,连续系统的输出会改变。可能导致离散系统的输入改变,从而导致离散系统的输出也改变(比如gain系统)。对于系统基类,设置默认情况下跟随小步长更新,而对于一些特殊系统,可以手动关闭小周期更新,选择只在大周期更新。
  3. 具体实现是,对于所有的系统都增加一个parameter为update_on_minor_step,默认值为True,就是在小周期进行更新,False时小周期不会更新。它只会影响离散系统,连续系统会忽略这个值。对于一些特殊模块,如果有在小周期不更新的需求,需要修改这个参数。
    1. 如果使用gui,需要设置一个布尔类型的参数来进行设置,目前在step中做了对应的修改,效果如下,默认是勾选状态。
    2. 如果不使用gui,只需要调用step.set_parameter('update_on_minor_step',False),即可手动关闭。
  4. 使用下面的模型进行测试
    1. 默认情况下,因为设置初始状态为True,所有系统都应在小周期输出,结果如下: 可以看到scope和step都在小步长进行更新。
    2. 将step中的update_on_minor_step状态取消,结果如下所示。 可以看到step只在大步长进行输出。
  5. 对于source类的系统小周期输出与否可能会影响结果,比如step系统,设置步长为1,step设置在0.1跳变。如果只在大周期更新,在t=1时才会发生变化,但是小周期更新时,在第一个小周期(对于ode3是t=0.5)就会发生变化。如下图所示。图1为不在小周期更新,图2为在小周期更新。
  6. 还需确认哪些模块需要这样的功能,需要修改对应的info.json文件,以及可能需要修改对应的system.py文件。目前只修改了step作为样例。(5.11进行了修改,去掉了step中的选项,对discrete类中的系统加了上面的选项)
  7. 自己写的模块
    1. 如果确定小周期更新与否不会变,就在initialize中加上self.parameters['update_on_minor_step']=False
    2. 如果需要用户可以自己选择小周期更新与否,gui中该系统对应的info.json需要在参数一栏添加以下内容:
      "update_on_minor_step": {
         "value": true,
         "data_type": "bool",
         "dimensions": [],
         "label": "update when meet minor steps",
         "description": "update when meet minor steps"
       }
      

本文章使用limfx的vscode插件快速发布