Guy on Simulink

Simulink & Model-Based Design

Communicating with an External Application for Co-Simulation 2

Posted by Guy Rouleau,

Today I am describing an example that I recently submitted to MATLAB Central and GitHub with the help of my colleague Haihua Feng: Example implementation of Co-simulation using Simulink.

In case you did not know, MathWorks' website lists a lot of third-party modeling and simulation tools from MathWorks Connection Partners.

MathWorks Connection Partners

Many of them offer the option to do Co-simulation with Simulink. With such solutions, those third-party tools allow their users to design part of their algorithms in the third-party tool (usually a specialized domain for which MathWorks does not have a dedicated toolbox), and part of it in Simulink (for example designing a controller for which you want to generate embedded code).

If you are the author of such a tool or would like to integrate your tool in Simulink for co-simulation, I recommend going through this post in details.

The Project

Once you have downloaded the submission from MATLAB Central or cloned it from GitHub, open the Simulink Project SimulinkCoSimulationExample.prj. In the Shortcuts tab, you will notice that I added shortcuts to help you go through the steps you will need to follow to run the examples.

Co-simulation project

Those steps include:

  • Download and build the ZeroMQ library
  • Build a co-simulation server executable
  • Build a S-function to communicate with the server executable

Let's look at those steps in more details.

ZeroMQ

To implement the communication between Simulink and the other software, we decided to use a library named ZeroMQ. I could try myself to describe what ZeroMQ is, but I thought the best would be to quote the ZeroMQ manual description of how it began:

We took a normal TCP socket, injected it with a mix of radioactive isotopes stolen from a secret Soviet atomic research project, bombarded it with 1950-era cosmic rays, and put it into the hands of a drug-addled comic book author with a badly-disguised fetish for bulging muscles clad in spandex. Yes, ZeroMQ sockets are the world-saving superheroes of the networking world.

See the full manual for more details.

Installing ZeroMQ

In my opinion, the easiest way to get the library is through GitHub. You will need two GitHub entries: cppzmq and libzmq.

In MATLAB, if you already have set up Git source control, you can clone the repositories from the Current Folder browser. If you prefer, you can also simply clone the repositories by calling the Git command-line client directly from the MATLAB prompt.

Cloning zmk git repositories

Once this is done, you need to build the library. For that, you will need a compiler. In my case, I used Microsoft Visual Studio 2015, so I launched the command prompt from Visual Studio:

Launching MSVC command prompt

I navigated to the build folder of libzmq and executed the provided build batch script:

Building ZMQ

As you can imagine, there are many ways of building the library for various OS and compilers, see the ZMQ documentation for the options available for your particular setup.

Once the library has been built, it needs to be added to the system path. If you are in my Simulink Project, the shortcut SetEnvVariable will do it using the setenv function.

The Server Application

The next step is creating a server app. In this example, the server app implements a simple algorithm: an exponentially weighted moving average. At every time step, Simulink will send data to the server, the server will do some math and send the results back to Simulink.

The main file of the server app is statcalserver.cpp. If you go through the code, what you will find is a simple example that first binds to a socket (a specific IP address and port). Then it goes in a loop where it waits for a request from the client. When a request comes in, it decodes the data associated with it, processes it and sends the reply to the client. Here is a snippet of the server code:

Server Code

In the Simulink Project, look at shortcut buildCoSimExample to see how the mex command can be used to build the server app.

The Client

On the Simulink side, the client is implemented using a C-Mex S-function (In fact it is a C++ S-function). Let's look at the most important parts.

At the beginning of the simulation, we use mdlSetupRuntimeResources to open the connection with the server. We store in a pointer work vector the information related to this connection.

Setup Resources

One important thing to note is that for maximum performance, we made the input of the S-function non-directfeedthrough. That way the S-Function does not use its input at the current time step to compute its output. As you can imagine, this introduces a delay, but this allows Simulink to not wait for the server to respond before moving forward and execute other blocks in the simulation.

To make that work, we send the request to the server after all block outputs have been computed, in mdlUpdate.

mdlUpdate

and at the next time step, in mdlOutput we retrieve the response from the server and output it.

mdlOutput

Finally, when the simulation is over we close the connection in mdlCleanupRuntimeResources

Cleanup Resources

In the Simulink Project, look at shortcut buildCoSimExample to see how the mex command can be used to build the S-Function.

To learn more about the available callback methods in an S-Function and when they are called, I recommend looking at Simulink Engine Interaction with C S-Functions.

The Final Result

As mentioned above, in the Simulink Project I created shortcuts to MATLAB scripts to help with all the steps leading to here.

Once you have the libzmq DLL built and on the OS path, the server executable built, and the S-function mexed and on the MATLAB path, you should be able to launch the server. In the Simulink Project, you can use shortcut startCoSimServer, which will execute the following code:

Launch Server

With the server running, we can finally simulate the example model clientModel.slx and observe the results:

Co-Simulation model

Now it's your turn

If you are considering implementing a co-simulation with an external application, give a try to this technique and let us know how that goes in the comments below.

2 CommentsOldest to Newest

Timofte Bogdan replied on : 1 of 2

For anyone interested i was able to build the .dll s using Visual Studio 2017 and VisualGDB CMake import functionality. As a compiler only MinGW 64 based TDM-GCC-64 was able to compile (Gcc 5.01 based)

Add A Comment

Your email address will not be published. Required fields are marked *

Preview: hide