Azzera filtri
Azzera filtri

python으로 workspace 변수 호출하기

12 visualizzazioni (ultimi 30 giorni)
changhoon ji
changhoon ji il 22 Giu 2020
Risposto: Angelo Yeo il 26 Giu 2024 alle 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'.

Risposte (1)

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

Categorie

Scopri di più su MATLAB에서 Python 라이브러리 in Help Center e File Exchange

Prodotti


Release

R2020a

Community Treasure Hunt

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

Start Hunting!