python으로 workspace 변수 호출하기

12 次查看(过去 30 天)
changhoon ji
changhoon ji 2020-6-22
回答: Angelo Yeo 2024-6-26,0:07
simulink의 결과 변수를 받기 위해서 다음과 같이 코딩을 했는데 에러가 뜹니다...단순히 변수를 차지 못 하겠다는 에러인데 이게 왜 뜨는지 모르겠습니다.
에러 코드와 현재 simulink를 추가적으로 올리겠습니다.
첨부한 코드에서 def getHistory(self) 부분에서 오류가 발생합니다.
import matlab.engine
import matplotlib.pyplot as plt
eng = matlab.engine.start_matlab()
class SimulinkPlant:
def __init__(self, modelName='plant'):
self.modelName = modelName # The name of the Simulink Model (To be placed in the same directory as the Python Code)
# Logging the variables
self.yHist = 0
self.tHist = 0
def setControlAction(self, u):
# Helper Function to set value of control action
self.eng.set_param('{}/u'.format(self.modelName), 'value', str(u), nargout=0)
def getHistory(self):
# Helper Function to get Plant Output and Time History
return self.eng.workspace['output'], self.eng.workspace['tout']
def connectToMatlab(self):
print("Starting matlab")
self.eng = matlab.engine.start_matlab()
print("Connected to Matlab")
# Load the model
self.eng.eval("model = '{}'".format(self.modelName), nargout=0)
self.eng.eval("load_system(model)", nargout=0)
# Initialize Control Action to 0
self.setControlAction(0)
print("Initialized Model")
# Start Simulation and then Instantly pause
self.eng.set_param(self.modelName, 'SimulationCommand', 'start', 'SimulationCommand', 'pause', nargout=0)
self.yHist, self.tHist = self.getHistory()
def connectController(self, controller):
self.controller = controller
self.controller.initialize()
def simulate(self):
# Control Loop
while (self.eng.get_param(self.modelName, 'SimulationStatus') != ('stopped' or 'terminating')):
# Generate the Control action based on the past outputs
u = self.controller.getControlEffort(self.yHist, self.tHist)
# Set that Control Action
self.setControlAction(u)
# Pause the Simulation for each timestep
self.eng.set_param(self.modelName, 'SimulationCommand', 'continue', 'SimulationCommand', 'pause', nargout=0)
self.yHist, self.tHist = self.getHistory()
def disconnect(self):
self.eng.set_param(self.modelName, 'SimulationCommand', 'stop', nargout=0)
self.eng.quit()
class PIController:
def __init__(self):
# Maintain a History of Variables
self.yHist = []
self.tHist = []
self.uHist = []
self.eSum = 0
def initialize(self):
# Initialize the graph
self.fig, = plt.plot(self.tHist, self.yHist)
plt.xlim(0, 10)
plt.ylim(0, 20)
plt.ylabel("Plant Output")
plt.xlabel("Time(s)")
plt.title("Plant Response")
def updateGraph(self):
# Update the Graph
self.fig.set_xdata(self.tHist)
self.fig.set_ydata(self.yHist)
plt.pause(0.1)
plt.show()
def getControlEffort(self, yHist, tHist):
# Returns control action based on past outputs
self.yHist = yHist
self.tHist = tHist
self.updateGraph()
if (type(self.yHist) == float):
y = self.yHist
else:
y = self.yHist[-1][0]
# Set Point is 10
e = 10 - y
self.eSum += e
u = 1 * e + 0.001 * self.eSum
print(y)
self.uHist.append(u)
return u
plant = SimulinkPlant(modelName="plant")
# Establishes a Connection
plant.connectToMatlab()
# Instantiates the controller
controller = PIController()
plant.connectController(controller)
# Control Loop
plant.simulate()
# Closes Connection to MATLAB
plant.disconnect()

오류 내용

: matlab.internal.engine.getVariable (line 27)
Undefined variable 'output'.
Traceback (most recent call last):
File "/Users/jichanghun/learning/data_structure/PycharmProjects/untitled/practice.py", line 115, in <module>
plant.connectToMatlab()
File "/Users/jichanghun/learning/data_structure/PycharmProjects/untitled/practice.py", line 37, in connectToMatlab
self.yHist, self.tHist = self.getHistory()
File "/Users/jichanghun/learning/data_structure/PycharmProjects/untitled/practice.py", line 19, in getHistory
return self.eng.workspace['output'], self.eng.workspace['tout']
File "/Users/jichanghun/opt/anaconda3/envs/untitled/lib/python3.7/site-packages/matlab/engine/matlabengine.py", line 120, in __getitem__
future = _method(attr)
File "/Users/jichanghun/opt/anaconda3/envs/untitled/lib/python3.7/site-packages/matlab/engine/matlabengine.py", line 71, in __call__
_stderr, feval=True).result()
File "/Users/jichanghun/opt/anaconda3/envs/untitled/lib/python3.7/site-packages/matlab/engine/futureresult.py", line 67, in result
return self.__future.result(timeout)
File "/Users/jichanghun/opt/anaconda3/envs/untitled/lib/python3.7/site-packages/matlab/engine/fevalfuture.py", line 82, in result
self._result = pythonengine.getFEvalResult(self._future,self._nargout, None, out=self._out, err=self._err)
matlab.engine.MatlabExecutionError:
File /Applications/MATLAB_R2020a.app/toolbox/matlab/external/engines/engine_api/+matlab/+internal/+engine/getVariable.m, line 27, in getVariable
Undefined variable 'output'.

回答(1 个)

Angelo Yeo
Angelo Yeo 2024-6-26,0:07
실행 중인 MATLAB 세션에 Python을 통해 접근하기 위해서 수행해야 하는 몇 가지 명령어들이 있습니다.
(1) 공유할 MATLAB 세션에서 아래와 같은 명령어로 해당 세션을 공유할 수 있도록 해주어야 합니다.
matlab.engine.shareEngine
(2) 파이썬 측에서는 matlab.engine.start_matlab()이 아니라 matlab.engine.connect_matlab()을 수행하셔야 할 것으로 보입니다. 현재 상황에서는 Python쪽에서 세션을 하나 새로 띄우고 "output"이라는 변수를 찾고 있는 상황으로 보입니다.
이 주제와 관련하여 아래의 문서를 참고하셔서 진행방식을 수정하시면 파이썬 환경에서 실행 중인 MATLAB 세션에 접근하실 수 있으실 것으로 생각합니다.

类别

Help CenterFile Exchange 中查找有关 MATLAB에서 Python 라이브러리 的更多信息

产品


版本

R2020a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!