2
votes

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

Simulation stepper in simulink

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.

1

1 Answers

2
votes

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!