{"id":7128,"date":"2018-05-01T16:04:54","date_gmt":"2018-05-01T21:04:54","guid":{"rendered":"https:\/\/blogs.mathworks.com\/simulink\/?p=7128"},"modified":"2018-05-15T09:19:40","modified_gmt":"2018-05-15T14:19:40","slug":"communicating-with-an-external-application-for-co-simulation","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/simulink\/2018\/05\/01\/communicating-with-an-external-application-for-co-simulation\/","title":{"rendered":"Communicating with an External Application for Co-Simulation"},"content":{"rendered":"<p>Today I am describing an example that I recently submitted to <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/66969-example-implementation-of-co-simulation-using-simulink\">MATLAB Central<\/a> and <a href=\"https:\/\/github.com\/mathworks\/SimulinkCoSimulationExample\">GitHub<\/a> with the help of my colleague Haihua Feng: <strong><a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/66969-example-implementation-of-co-simulation-using-simulink\">Example implementation of Co-simulation using Simulink<\/a><\/strong>.<\/p>\n<p>In case you did not know, MathWorks' website lists a lot of <a href=\"https:\/\/www.mathworks.com\/products\/connections\/search-products.html?q=&fq=connections-product-type:mst&page=1\">third-party modeling and simulation tools<\/a> from MathWorks <a href=\"https:\/\/www.mathworks.com\/products\/connections\/join.html\">Connection Partners<\/a>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2018Q1\/connectionPartners.png\" alt=\"MathWorks Connection Partners\" \/><\/p>\n<p>Many of them offer the option to do <a href=\"https:\/\/en.wikipedia.org\/wiki\/Co-simulation\">Co-simulation<\/a> 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).<\/p>\n<p>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.<\/p>\n<p><strong>The Project<\/strong><\/p>\n<p>Once you have downloaded the <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/66969-example-implementation-of-co-simulation-using-simulink\">submission from MATLAB Central<\/a> or <a href=\"https:\/\/github.com\/mathworks\/SimulinkCoSimulationExample\">cloned it from GitHub<\/a>, open the Simulink Project <strong>SimulinkCoSimulationExample.prj<\/strong>. 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.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2018Q1\/CoSimSlProject.png\" alt=\"Co-simulation project\" \/><\/p>\n<p>Those steps include:<\/p>\n<ul>\n<li>Download and build the ZeroMQ library<\/li>\n<li>Build a co-simulation server executable<\/li>\n<li>Build a S-function to communicate with the server executable<\/li>\n<\/ul>\n<p>Let's look at those steps in more details.<\/p>\n<p><strong>ZeroMQ<\/strong><\/p>\n<p>To implement the communication between Simulink and the other software, we decided to use a library named <a href=\"http:\/\/zeromq.org\">ZeroMQ<\/a>. I could try myself to describe what ZeroMQ is, but I thought the best would be to quote the <a href=\"http:\/\/zguide.zeromq.org\/page:all#header-3\">ZeroMQ manual description of how it began<\/a>:<\/p>\n<p><em>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.<\/em><\/p>\n<p>See the <a href=\"http:\/\/zguide.zeromq.org\/page:all\">full manual for more details<\/a>.<\/p>\n<p><strong>Installing ZeroMQ<\/strong><\/p>\n<p>In my opinion, the easiest way to get the library is through <a href=\"https:\/\/github.com\/\">GitHub<\/a>. You will need two GitHub entries: <a href=\"https:\/\/github.com\/zeromq\/cppzmq\">cppzmq<\/a> and <a href=\"https:\/\/github.com\/zeromq\/libzmq\">libzmq<\/a>.<\/p>\n<p>In MATLAB, if you already have <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/matlab_prog\/set-up-git-source-control.html\">set up Git source control<\/a>, you can <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/matlab_prog\/retrieve-from-git-repository.html\">clone the repositories from the Current Folder browser<\/a>. If you prefer, you can also simply clone the repositories by calling the Git command-line client directly from the MATLAB prompt.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2018Q1\/gitClone.png\" alt=\"Cloning zmk git repositories\" \/><\/p>\n<p>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:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2018Q1\/msvcCmd.png\" alt=\"Launching MSVC command prompt\" \/><\/p>\n<p>I navigated to the build folder of libzmq and executed the provided build batch script:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2018Q1\/buildzmq.png\" alt=\"Building ZMQ\" \/><\/p>\n<p>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.<\/p>\n<p>Once the library has been built, it needs to be added to the system path. If you are in my Simulink Project, the shortcut <strong><tt>SetEnvVariable<\/tt><\/strong> will do it using the <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/setenv.html\">setenv<\/a> function.<\/p>\n<p><strong>The Server Application<\/strong><\/p>\n<p>The next step is creating a server app. In this example, the server app implements a simple algorithm: an <a href=\"https:\/\/en.wikipedia.org\/wiki\/Moving_average#Exponential_moving_average\">exponentially weighted moving average<\/a>. At every time step, Simulink will send data to the server, the server will do some math and send the results back to Simulink.<\/p>\n<p>The main file of the server app is <tt>statcalserver.cpp<\/tt>. 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:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2018Q1\/serverCode.png\" alt=\"Server Code\" \/><\/p>\n<p>In the Simulink Project, look at shortcut <tt>buildCoSimExample<\/tt> to see how the <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/mex.html\">mex<\/a> command can be used to build the server app.<\/p>\n<p><strong>The Client<\/strong><\/p>\n<p>On the Simulink side, the client is implemented using a <a href=\"https:\/\/www.mathworks.com\/help\/simulink\/c-c-s-functions.html\">C-Mex S-function<\/a> (In fact it is a C++ S-function). Let's look at the most important parts.<\/p>\n<p>At the beginning of the simulation, we use <a href=\"https:\/\/www.mathworks.com\/help\/simulink\/sfg\/mdlsetupruntimeresources.html\">mdlSetupRuntimeResources<\/a> to open the connection with the server. We store in a <a href=\"https:\/\/www.mathworks.com\/help\/simulink\/sfg\/ssgetpwork.html\">pointer work vector<\/a> the information related to this connection.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2018Q1\/setupRessources.png\" alt=\"Setup Resources\" \/><\/p>\n<p>One important thing to note is that for maximum performance, we made the input of the S-function <a href=\"https:\/\/www.mathworks.com\/help\/simulink\/sfg\/sssetinputportdirectfeedthrough.html\">non-directfeedthrough<\/a>. 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.<\/p>\n<p>To make that work, we send the request to the server after all block outputs have been computed, in <a href=\"https:\/\/www.mathworks.com\/help\/simulink\/sfg\/mdlupdate.html\">mdlUpdate<\/a>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2018Q1\/updateWrapper.png\" alt=\"mdlUpdate\" \/><\/p>\n<p>and at the next time step, in <a href=\"https:\/\/www.mathworks.com\/help\/simulink\/sfg\/mdloutputs.html\">mdlOutput<\/a> we retrieve the response from the server and output it.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2018Q1\/outputWrapper.png\" alt=\"mdlOutput\" \/><\/p>\n<p>Finally, when the simulation is over we close the connection in <a href=\"https:\/\/www.mathworks.com\/help\/simulink\/sfg\/mdlcleanupruntimeresources.html\">mdlCleanupRuntimeResources<\/a><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2018Q1\/cleanupRessources.png\" alt=\"Cleanup Resources\" \/><\/p>\n<p>In the Simulink Project, look at shortcut <tt>buildCoSimExample<\/tt> to see how the <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/mex.html\">mex<\/a> command can be used to build the S-Function.<\/p>\n<p>To learn more about the available callback methods in an S-Function and when they are called, I recommend looking at <a href=\"https:\/\/www.mathworks.com\/help\/simulink\/sfg\/how-the-simulink-engine-interacts-with-c-s-functions.html\">Simulink Engine Interaction with C S-Functions<\/a>.<\/p>\n<p><strong>The Final Result<\/strong><\/p>\n<p>As mentioned above, in the Simulink Project I created <a href=\"https:\/\/www.mathworks.com\/help\/simulink\/ug\/create-shortcuts-to-frequent-tasks.html\">shortcuts<\/a> to MATLAB scripts to help with all the steps leading to here.<\/p>\n<p>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 <tt>startCoSimServer<\/tt>,  which will execute the following code:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2018Q1\/launchEXE.png\" alt=\"Launch Server\" \/><\/p>\n<p>With the server running, we can finally simulate the example model <tt>clientModel.slx<\/tt> and observe the results:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2018Q1\/coSimModel.png\" alt=\"Co-Simulation model\" \/><\/p>\n<p><strong>Now it's your turn<\/strong><\/p>\n<p>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.<\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img decoding=\"async\"  class=\"img-responsive\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2018Q1\/coSimModel.png\" onError=\"this.style.display ='none';\" \/><\/div>\n<p>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.<br \/>\nIn case you... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/simulink\/2018\/05\/01\/communicating-with-an-external-application-for-co-simulation\/\">read more >><\/a><\/p>\n","protected":false},"author":41,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[87,10],"tags":[524],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/7128"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/comments?post=7128"}],"version-history":[{"count":59,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/7128\/revisions"}],"predecessor-version":[{"id":7525,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/7128\/revisions\/7525"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/media?parent=7128"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/categories?post=7128"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/tags?post=7128"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}