【问题标题】:Executing step-by-step a Simulink model from Python从 Python 逐步执行 Simulink 模型
【发布时间】:2018-07-29 13:50:41
【问题描述】:

我需要从一个用 Python 编写的外部应用程序控制 Simulink 控制方案。我需要做的是逐步完成模拟,并在每一步检索输出并让 Python 应用程序确定新的输入集。这是一个固定的时间段。 有没有办法做到这一点?我承认我很难尝试使用 matlab 脚本来实现这一点,更不用说 Python。 这是可行的吗?如果没有,有没有办法将 Python 模块插入到 simulink 方案中?

谢谢


编辑:这是我设法解决的方法

为了逐步运行模拟,我创建了这个带有时钟、关系运算符和断言块的块结构

其中 Tmp 是每次暂停的时间戳

Tmp=get_param(bdroot,'SimulationTime')

断言块包含以下指令:

set_param(bdroot,'SimulationCommand','pause')

这样,模拟在每一步之后都会暂停,即 (clockTime-Tmp)=timeStep。

现在,我创建了一个 Python 脚本来启动模拟(请参阅接受的答案)并像这样迭代:

#While the simulation is running
while eng.get_param('simpleTest','SimulationStatus')!=('stopped' or 'terminating'):
    if eng.get_param('simpleTest','SimulationStatus')=='paused':
        #do your evaluations and operations 
        eng.set_param('simpleTest','SimulationCommand','update',nargout=0) #if you have updated any simulation parameters
        eng.set_param('simpleTest','SimulationCommand','continue',nargout=0)

这对我来说似乎很好,但如果有更好的选择,请告诉我。

【问题讨论】:

    标签: python matlab interface simulink


    【解决方案1】:

    使用 matlab.engine bindings in Python 您可以启动 MATLAB 引擎实例并将单个命令作为字符串发送到 MATLAB(如果您还没有使用它)。这种技术可以让您像在 MATLAB 命令行中输入字符串一样输入字符串。例如:

     >>>import matlab.engine # load engine functionality
     >>>eng = matlab.engine.start_matlab() # init instance of engine
     >>>eng.sim("simulinkModelName") # start a simulink model by calling it through the engine instance
    

    根据文档,这也可以让您pass data to MATLAB from Python。根据您的说法,这应该足以实现您的要求。


    但是,我想到了另一种方法,即使用 TCP/IP 连接在两个进程之间进行通信(Python GUI 到 Simulink)。这将使您可以将消息从一个程序发送到下一个程序,然后您可以相应地解析它们。 (Simulink、Matlab 和 Python 都有 TCP/IP 选项!)

    在这个想法中,我会让 GUI 充当服务器并在后台异步线程中侦听/发送消息到客户端 (simulink)。例如,您可以发送命令开始模拟,然后在某个点停止并等待接收来自 Python 的数据。

    这可能需要对线程过程有更复杂的了解,我建议您查看threading in Pythonusing sockets in Python

    如果您确实想要迁移到另一种语言进行 GUI 开发,那么 TCP/IP 命令对于未来的实现也将是相同的。


    我希望这可以帮助您完成任务!

    【讨论】:

    • 感谢您的回复。这非常有帮助,但它似乎仍然无法解决我的逐步模拟问题。我可以从 python 启动一个 Simulink 模块,但我找不到任何方法来一次遍历模拟。
    • 没问题!我想我会采取的方法是在 Python GUI 和 simulink 模型中启动 TCP/IP 连接,然后在 Simulink 模型中使用类似于 while(!continueMessageReceived) 的 matlab 函数,这样 simulink 模型就是停留在特定块,直到它收到您选择的消息。这与一次一步地迭代模拟具有相同的意义。然后,您可以在从阻塞的 while 循环中断之前再次将必要的数据传入/传出 Simulink。祝你好运!
    • 非常感谢您的意见。最终,解决方案更加简单,并且不涉及 TCP/IP 连接:我所做的是创建一个与仿真时间同步的块,并在 (currentTime-previousTime)=timeStep 时暂停仿真。然后,我在 python 中创建了一个 if 语句,使用 get_param('modelName', 'SimulationStatus') 和 set_param('modelName', 'SimulationCommand', 'continue')来自 Python 中导入的 matlab api。这对我来说很好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-28
    • 2017-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-02
    • 2011-03-29
    相关资源
    最近更新 更多