I have a variable A= 25 (1X1 double) in my MATLAB workspace and I am using the MATLAB Engine API to call it in python by using the following code.
import matlab.engine
eng = matlab.engine.start_matlab()
var = eng.workspace['A']
print(var)
I am getting the following error message:
Error using matlab.internal.engine.getVariable
Undefined variable 'A'.
Traceback (most recent call last):
File "readingdata.py", line 20, in <module>
test = eng.workspace['A']
File "/usr/local/lib/python3.8/dist-packages/matlab/engine/matlabengine.py", line 120, in __getitem__
future = _method(attr)
File "/usr/local/lib/python3.8/dist-packages/matlab/engine/matlabengine.py", line 70, in __call__
return FutureResult(self._engine(), future, nargs, _stdout,
File "/usr/local/lib/python3.8/dist-packages/matlab/engine/futureresult.py", line 67, in result
return self.__future.result(timeout)
File "/usr/local/lib/python3.8/dist-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 /usr/local/MATLAB/R2022a/toolbox/matlab/external/engines/engine_api/+matlab/+internal/+engine/getVariable.m, line 27, in getVariable
Undefined variable 'A'.
I could do the same using scipy.io
Is there something I am missing?

답변 (1개)

Kojiro Saito
Kojiro Saito 2022년 3월 28일

2 개 추천

It's because engine.start_matlab launches a new MATALB session and there's no variable in workspace.
You need to create a session to a running MATLAB as described in this document.
In MATLAB, you need to call matlab.engine.shareEngine.
[MATLAB side]
A = 25;
matlab.engine.shareEngine
Then, you need to create a session from Python using engine.connect_matlab not engine.start_matlab.
[Python side]
import matlab.engine
eng = matlab.engine.connect_matlab()
var = eng.workspace['A']
print(var)

댓글 수: 11

Thank you for the answer. SInce I was already sharing my MATLAB session I could do without including the matlab.engine.shareEngine command.
I have a follow up question. The whole idea behind using matlab engine API was to load a predfined environment of MATLAB BAsicGridWorld in python.
When I simply load env in python it displays <matlab.object object at 0x7f2488eaa5f0>
The env is of the class rl.env.rlMDPEnv.I need to access env. Model.States and for which I have to parse differently. Is that correct?
I am currently refering https://gist.github.com/mbauman/9121961. I hope that is a correct way to go about. If not any reference would be highly appreciated.
Once again, thanks for the prompt response.
BR,
Ankita
You can use eval function for accesing the element of MATLAB object.
[Python side]
import matlab.engine
eng = matlab.engine.connect_matlab()
states = eng.eval('env.Model.States')
print(states)
result:
['[1,1]', '[2,1]', '[3,1]', '[4,1]', '[5,1]', '[1,2]', '[2,2]', '[3,2]', '[4,2]', '[5,2]', '[1,3]', '[2,3]', '[3,3]', '[4,3]', '[5,3]', '[1,4]', '[2,4]', '[3,4]', '[4,4]', '[5,4]', '[1,5]', '[2,5]', '[3,5]', '[4,5]', '[5,5]']
[MATLAB side]
Based on this document's Example.
% Make MATLAB to be sharable
matlab.engine.shareEngine;
% rlMDPEnv shipping demo
GW = createGridWorld(5,5);
GW.CurrentState = '[2,1]';
GW.TerminalStates = '[5,5]';
GW.ObstacleStates = ["[3,3]";"[3,4]";"[3,5]";"[4,3]"];
updateStateTranstionForObstacles(GW)
GW.T(state2idx(GW,"[2,4]"),:,:) = 0;
GW.T(state2idx(GW,"[2,4]"),state2idx(GW,"[4,4]"),:) = 1;
nS = numel(GW.States);
nA = numel(GW.Actions);
GW.R = -1*ones(nS,nS,nA);
GW.R(state2idx(GW,"[2,4]"),state2idx(GW,"[4,4]"),:) = 5;
GW.R(:,state2idx(GW,GW.TerminalStates),:) = 10;
env = rlMDPEnv(GW);
Thnak you for your quick response.
Ankita Tondwalkar
Ankita Tondwalkar 2022년 4월 3일
편집: Ankita Tondwalkar 2022년 4월 3일
@Kojiro Saito When I am trying to import the MATLAB environment in python it gives the following error:
File /usr/local/MATLAB/R2022a/toolbox/rl/rl/rlMDPEnv.m, line 31, in rlMDPEnv
Input must be a MDP model.
Line 31 of rlMDPEnv.m is env = rl.env.rlMDPEnv(MDP);
MATLAB part of the code:
GW = createGridWorld(5,5);
GW.CurrentState = '[2,1]';
GW.TerminalStates = '[5,5]';
nS = numel(GW.States);
nA = numel(GW.Actions);
GW.R = -1*ones(nS,nS,nA);
GW.R(state2idx(GW,"[2,4]"),state2idx(GW,"[4,4]"),:) = 5;
GW.R(:,state2idx(GW,GW.TerminalStates),:) = 10;
env = rlMDPEnv(GW);
Python part of the code:
import matlab.engine
eng = matlab.engine.connect_matlab()
env = eng.rlMDPEnv("GW")
model = PPO(env))
model.learn(100)
However, when I try with rlPredefinedEnv("BasicGridWorld") it does not throw any error.
Any thoughts?
I think you need to import GW from MATLAB workspace to Python first.
import matlab.engine
eng = matlab.engine.connect_matlab()
#env = eng.rlMDPEnv("GW")
gw = eng.workspace['GW']
env = eng.rlMDPEnv(gw)
Ankita Tondwalkar
Ankita Tondwalkar 2022년 4월 4일
편집: Ankita Tondwalkar 2022년 4월 4일
Thank you for the reply.
Ankita Tondwalkar
Ankita Tondwalkar 2022년 4월 7일
편집: Ankita Tondwalkar 2022년 4월 8일
Hello @Kojiro Saito . Please find a snippet of my python code which is trying to import environment from MATLAB.
import numpy as np
eng = matlab.engine.connect_matlab()
env = eng.rlPredefinedEnv("BasicGridWorld")
action = np.array([1]) (This is because my action is a np array in my code)
action = matlab.int64(action.tolist())
obs,rew = eng.step(env,action)
obs,rew = eng.step(env,action)
TypeError: cannot unpack non-iterable float object
Basically it just returning states and not rewards, whereas when I do the same in MATLAB it returns both observation and rewards. What could be the reson for it?
Thanks,
Ankita
Hello Kojiro,
I found the solution to it. Instead of using, obs,rew = eng.step(env,action) , I used
t = eng.step(env, action, nargout=2) and it returned me the next observaton and reward.
Ankita Tondwalkar
Ankita Tondwalkar 2022년 4월 9일
편집: Ankita Tondwalkar 2022년 4월 9일
The action space in BasicGridWorld environment is N-1, S-2, E-3 and W-4. While sampling an action from distribution in python, the four possible actions are 0 , 1, 2 and 3.
Whenever action 0 is selected to obtain the next observation and reward I get the following error:
File /usr/local/MATLAB/R2022a/toolbox/rl/rl/+rl/+env/rlMDPEnv.m, line 76, in rlMDPEnv.step
Invalid index specified.
This is my python code where I am generating an action which is a np array, since matlab does not support np array as is, I first convert it to matlab matrix and then pass it to the step function.
action = argmax(action.tolist())
action = matlab.int64(action.tolist())
output = self.eng.step(self.env,action,nargout=4)
Is this an indexing error or is it because step function can takeonly 2 arguments and I have passed 3?
Any leads will be very helpful.
This problem resulted from that fact how indexing works differenty in MATLAB and Python. I made sure while callig in Python I followed the indexing rule for Python.
Hello,
I am trying to access predefined enviromen ("BasicGridWorld") variable, obsInfo and actInfo present in MATLAB workspace in Python.
While doing so, I am able to find my MATLAB session but unable to connect to it.
In my Python terminal I am getting the following error:
matlab.engine.EngineError: Unable to connect to MATLAB session 'MATLAB_3052'.
In MATLAB I am using the share engine command (but I get the error that "The current MATLAB session is shared already")while in Python I have the matlab.engine.connect_matlab(). Can anyone let me know if I am missing something?
Thanks,
Ankita

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 Call MATLAB from Python에 대해 자세히 알아보기

질문:

2022년 3월 27일

댓글:

2022년 9월 26일

Community Treasure Hunt

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

Start Hunting!

Translated by