直接调用 您所在的位置:网站首页 matlab如何跳出for循环 直接调用

直接调用

2023-03-19 16:42| 来源: 网络整理| 查看: 265

目录前言技术篇一. Python与Matlab交互二. Matlab与Simulink交互三. Pyhton与Matlab/Simulink交互小结

目录

—— 前言—— 技术篇1)Python与Matlab交互2)Matlab与Simulink交互3)Pyhton与Matlab/Simulink交互—- 小结

前言

一年前,还没接触过Pyhton和Simulink,Matlab也只会写一些简单的计算脚本。如今使用Python的AI库和Matlab/Simulink快一年了,期间用Simulink做微电网的暂态仿真,搭建环境,然后在Python中做强化学习的训练。为了实现训练的自主运行,需要打通Python和Matlab/Simulink的接口,经过一段时间的探索,终于找到了一个可行的方案。20年初的时候,2019版的Matalb还没有Reinforcement learning (RL)库,只有Deep learning库,直到2020a版本,Mathwork官方才建立化强化学习库。并且由于刚引入,其支持的RL算法较少,且很多个性化的训练需求无法完成。另外,我的训练需要和Simulink交互,且动态修改Simulink内部参数,并实时分析Simulink的仿真数据,这使得Matlab的RL包无法直接满足需求。于是最终选择了Pyhton和Matlab/Simulink混合仿真的路线,期间踩了不少坑,也解决了不少麻烦。现在把它们记录下来,算是一个小结,也希望给像我一样遇到类似困难的同学提供一点帮助。

技术篇

Python最终与Simulink交互,是通过与Maltlab的交互实现的,整个过程有两个关键点:一是Python调用并运行Maltab的m文件,同时直接读取工作区中的参数数据;二是Matlab通过代码控制Simulink启停,重置参数,并读取Simlink的仿真结果。这两点实现后,将Simulink作为环境,在Python中进行AI训练就不再是难事。下面分别介绍这两个关键点。

一. Python与Matlab交互

Python与Matlab交互有两种方式:1)Python作为主控程序,调用Matlab;2)Matlab作为主控程序,调用Python。

Python call Matlab

Python调用Matlab是逻辑是,在Matlab中安装Python 包形式的引擎API,然后再py文件中 improt matlab engine,即Matlab进程,通过这个engine可以直接调用Matlab内置函数或者自己编写的m文件。具体实现分为以下4步。1)检查Python和Matlab的版本适配情况。目前Mathwork官方发布的版本适配情况如下图所示。其中,Matlab的版本可以从安装文件名直接看出来;python版本可以在Matlab中通过以下代码查找:pe = pyenv; pe.Version更详细的版本适配内容可参考Mathwork官方文档:https://link.zhihu.com/?target=https%3A//ww2.mathworks.cn/help/matlab/matlab_external/install-supported-python-implementation.html%3Flang%3Den2)在Matalb根目录中安装Python包形式的引擎APIWindows中,在管理员模式下按“win+R”,键入cmd,回车打开进入系统命令行,键入:

cd "matlabroot\extern\engines\python"python setup.py install

或者在MATLAB 命令提示符下键入以下命令:

cd (fullfile(matlabroot,'extern','engines','python'))system('python setup.py install')

更详细教程可参考Mathwork官方文档:官方文档(中文版)https://link.zhihu.com/?target=https%3A//ww2.mathworks.cn/help/matlab/matlab_external/install-the-matlab-engine-for-python.html3)在Python中import matlab engine 并调用

import matlab.engine # 在Python中导入Matlab引擎eng = matlab.engine.start_matlab() # 启动Matlab引擎,命名为engeng.ini_operating_point(nargout=0) # 通过eng运行写好的m文件 “ini_operating_point.m”,nargout=0表示不返回输出。 # Note: 此m文件需要在ptyhon的启动界面下。

通过上述方法,相当于用Python开启了一个虚拟Matlab进程,没有UI界面,但是工作区及其变量依然存在。运行完m文件后,可以通过Python直接读取虚拟进程中的变量,例如:

out = eng.eval('out') # 用 matlab的eval 函数读取变量 ‘out’

另外,在Python中将变量赋值到Matlab工作区的指令也很常用,例如:

eng.workspace['Q_ref'] = Q_ref.tolist() # 在Matlab工作区生成变量‘Q_ref’,大小等于Python中的变量‘Q_ref’

上述通过Python启动Matlab engine的过程大致要花30秒,比直接打开Matlab要稍微慢点。4)退出Matlab engine

eng.quit() # quit Matlab engine

使用完Matlab代码后,需要在Python中手动代码退出,否则这个进程会一直挂在后台,占用系统资源。

Matlab call Python

Matlab里可以很方便地调用Python。在Matlab Command window里键入 pyversion ,就能看到链接的Python解释器,下图是我通过Anaconda配置的写强化学习训练的环境,命名成了“DQN”…. Python版本是3.6。这里插个题外话,关于Python的版本和环境管理。早期Tenserflow代码使用的是早版本Python,所以需要通过Python环境管理来支持之前版本的代码。目前,最新的Tensorflow和Pytorch库都需要较新版本的Python支持。具体的例子和更详细的使用方法,可参考知乎上的其它帖子和Mathwork官方文档,这里不做赘述,传送门如下:https://zhuanlan.zhihu.com/p/40992247https://ww2.mathworks.cn/help/matlab/call-python-libraries.html?s_tid=CRUX_lftnav

二. Matlab与Simulink交互

常见的Simulink使用方法是拖动模块,搭建系统,然后点击控制栏中的 ‘Run’来运行,并通过Scope观测输出。这种方式在少工作量的场景下比较方便,但如果碰到以下场景,手动启停就不太现实了。比如:1)需要频繁地调参,甚至在仿真过程中动态修改参数;2)需要批量仿真,反复运行成千上万次;3)初始化时间很长,实际需要观察时间段在仿真末尾几秒。这时候就需要代码来控制Simulink仿真。实际上,鼠标点击能实现的控制操作都可以通过代码来实现。主要涉及到两个函数:一是仿真运行函数 sim( ),用于控制simulink仿真的启停;二是参数设置函数 set_param( ),用于参数设置,包括仿真控制参数,和仿真模型参数。下面贴一段我写的代码,使用了上面提到了命令。这段代码的功能是将一个Simulink模型仿真到4秒,并存成工作点,以后的仿真读取工作点直接从4秒时刻继续。

% -------------------------------------------------------------------------% This manuscripte is to set the initial operaton point of simulink file% The environment is Banshee microgrid% Last modfied: 3/17/2021 by Buxin She% -------------------------------------------------------------------------%%% parameter initializationfile_name = 'Banshee_grid_connected_PQ';start_time = '4'; normal_stop_time = '11';% load sim modelload_system(file_name);% set loading initial operation point offset_param(file_name,'LoadInitialState','off');set_param(file_name,'SimscapeUseOperatingPoints','off');% set getting final state on and save it as IniOperPointset_param(file_name,'SaveCompleteFinalSimState','on');set_param(file_name,'SaveFinalState','on');set_param(file_name,'FinalStateName','myOperPoint');simOut = sim(file_name,'StopTime',start_time);myOperPoint = simOut.myOperPoint;save('IniOperPoint.mat', 'myOperPoint');set_param(file_name,'SaveCompleteFinalSimState','off');% set loading initial operation point onset_param(file_name,'LoadInitialState','on'); set_param(file_name,'InitialState','myOperPoint');set_param(file_name,'SimscapeUseOperatingPoints','on'); % enable Operation point initializationset_param(file_name,'SimscapeOperatingPoint','myOperPoint');% restore the stop timeset_param(file_name,'StopTime',normal_stop_time);

One more thing,怎么通过代码控制Simulink更新内部仿真参数,做到动态仿真。方法是使用Simulink Assertion 模块。在Assertion中设置一个触发逻辑,Simulink会自动运行Assertion下预先写好的代码。我的一个具体使用方式是写一句暂停代码(set_param(bdroot, ‘SimulationCommand’, ‘pause’)),触发后使Simulink仿真暂停,然后在m文件中用代码更新仿真参数和设置,最后通过set_param()控制Simulink继续运行。

关于Matlab与Simulink交互更详细的例子和使用方法,可参考下面教程:1)Sim() 函数使用教程https://zhuanlan.zhihu.com/p/57487483https://link.zhihu.com/?target=https%3A//www.mathworks.com/help/simulink/slref/sim.html2)Set_param()函数使用教程https://link.zhihu.com/?target=https%3A//www.mathworks.com/help/simulink/slref/set_param.html

三. Pyhton与Matlab/Simulink交互

搞定了Python/Matlab交互,Matlab/Simulink交互之后,通过Python控制Simulink就容易很多了。整理交互逻辑是:Python启动matlab engine,然后通过代码控制Simulink启停,读取、更新仿真参数,最后直接读取、存储Matlab工作区的变量结果。贴一段以Simulink作为环境,Python作为主控程序,调用Tensorflow进行强化学习的代码(代码有所简化),运用到了上面提到的大部分技巧。

import numpy as npimport tensorflow as tfimport matlab.engine# ------------------------- Training loop ------------------------------# Start Matlab engine and initialize simulink modeleng = matlab.engine.start_matlab()eng.ini_sim_ddpg(nargout=0) while True: # set action action_temp = policy(state_temp, action_noise, lower_action, upper_action) print(f'action_temp is {action_temp}') # sim and get next state eng.set_param('simple_case_ddpg/Control/kp', 'value', str(kp), nargout=0) eng.set_param('simple_case_ddpg/Control/ki', 'value', str(ki), nargout=0) eng.set_param('simple_case_ddpg/Control/pause_time', 'value', str(pause_time), nargout=0) eng.set_param('simple_case_ddpg', 'SimulationCommand', 'continue', nargout=0) # update next state and reward next_state_temp = np.array([-0.0116, eng.eval('out.t(end)'), eng.eval('out.Vt(end)')]) next_state_temp = next_state_temp[None, :] # expand dimension to (1, 3) reward_temp = get_reward(next_state_temp) # get reward based on t and Vt episode_reward += reward_temp # record buffer buffer_temp = merge_buffer(state_temp, action_temp, reward_temp, next_state_temp) buffer = np.append(buffer, buffer_temp[None, :], axis=0) buffer_counter += 1 # learn and update target network learn() update_target(target_actor.variables, actor.variables, tau) update_target(target_critic.variables, critic.variables, tau) # episode done pause_time += step_time if pause_time > (stop_time + step_time): eng.set_param('simple_case_ddpg', 'SimulationCommand', 'stop', nargout=0) break # print episodic reward print("Episode * {} * Avg Reward is ==> {}".format(episodes + ep + 1, episode_reward))eng.quit() # quit Matlab engine

小结

本文主要讲述了Python,Matlab,Simulink三者交互的逻辑,小结了一些交互技巧。现在来看,Matlab在2020、2021的版本中加强了对强化学习的支持,基本涵盖了目前主流的RL算法,使用Simulink作为环境时,不必大费周章地与Python进行交互了。但是,如果想跟踪最新的AI研究成果,并用到科研中,上述交互还是很有价值的。因为最新的AI算法大都是Python开源,并且Github也有很多优质的资源。所以Mark一下本文,以做防身用。共勉。

https://zhuanlan.zhihu.com/p/392728491



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有