I need to control a Simulink control scheme from an external application, written in Python. What I need to do is to step through the simulation and, at each step, retrieve the output and let the Python application determine the new set of inputs. This for a fixed time period. Is there any way at all to do this? I admit I am having a hard time trying to achieve this using a matlab script, let alone Python. Is this doable? If not, is there a way to insert the Python module into the simulink scheme?
Thanks
EDIT: THIS IS HOW I MANAGED TO SOLVE IT
In order to run the simulation step-by-step, I created this block structure with a clock, a relational operator and an Assertion block
where Tmp is the timestamp of each pause
Tmp=get_param(bdroot,'SimulationTime')
The assertion block contains the following instructions:
set_param(bdroot,'SimulationCommand','pause')
This way, the simulation pauses after each step, i.e. (clockTime-Tmp)=timeStep.
Now, I create a Python script that launches the simulation (see accepted answer) and iterates through like this:
#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)
This seems to work fine for me, but if there are better options, please let me know.
Using the matlab.engine
bindings in Python you can start a MATLAB engine instance and send individual commands to MATLAB as a string (if you aren't already using this). This technique will let you enter in strings as if you were entering them on the MATLAB command line. For example:
>>>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
This also lets you pass data to MATLAB from Python, according to the documentation. From what you have stated this should be enough to achieve what you were asking.
However, another approach comes to mind which is using TCP/IP connections to communicate between the two processes (Python GUI to Simulink). This would let you send messages from one program to the next and then you could parse them accordingly. (Simulink, Matlab & Python all have TCP/IP options with them!)
In this idea I would have the GUI acting as a server and listening/sending messages to the client (simulink) in a background asynchronous thread. You could send a command to start the simulation, then stop at a certain point and wait to receive data from Python for example.
This may require a more complex understanding of the threading processes and I would recommend looking up threading in Python, as well as using sockets in Python.
If you did then want to move to another language for GUI development the TCP/IP commands would also be the same for future implementations.
I hope this can help and you get your task completed!