/Python-Simulink

Run Simulink models with Python using shared libraries.

Primary LanguageJupyter NotebookBSD 3-Clause "New" or "Revised" LicenseBSD-3-Clause

Python-Simulink

Run your Simulink models & libraries in Python.

Motivation

  1. Running software-in-the-loop tests with Simulink becomes time consuming with Matlab & Simulink overhead. There are ways to reduce it (Model reference, etc) however nothing has shown to be as fast as a precompiled shared library.

  2. Python has a very mature set of tools and packages to automate testing.

  3. Testing can be distributed to machines without Matlab/Simulink licenses.

  4. There are more and more Python developers. Being able to hand off a Simulink Library for further use there is a good feature.

Use cases

  1. Use Python and it's ecosystem to run complex Simulink models.
  2. Use Python & pytest to run Software-in-the-Loop (SIL) tests on Simulink subsystems.
  3. Give Simulink algorithms to developers without Matlab/Simulink licenses to use.
  4. Use GitHub/GitLab actions and Python to automate testing in the cloud.
  5. Start a programming language war at your company.

Disclaimer

This repository is a set of instructions, with examples, on how to create a Pythonic wrapper for Simulink models. It is not a turnkey Python module to do this:

import simulinkdll
simulinkdll.run("my_model.slx")
do_stuff()

For a given library or model configuring the Python should only need done when the Simulink Parameters/Signals change. The end developer will then be able do a import simulink_model, but it takes development time.

High level instructions.

  1. Create a shared library in Simulink.
  2. Create Python representations of all items in the header file.
  3. Open the shared library (.dll, .so) in Python and run the model.

Examples

  • For demonstrating minimal dll functionality and the steps required to run a model in Python.
  • Demonstrate implementions of SimulinkGlobal vs ExportedGlobal in Simulink.Parameter and Simulink.Signal variables.

A simple discrete transfer function. Compiled with a 1st order low pass filter.

There are two example notebooks for Example 2.

  1. Simple Example - A simple low-level ctypes wrapper.
  2. Pythonic Example - Use Python syntactic sugar to create a high level TransferTF python class to interact with the model. Adds datalogging and pandas integration.

Adapted from Mathworks's Simulation of a Bouncing Ball

Running a Simulation in Simulink also has some overhead. By compiling the model to a shared library and executing it, this overhead is eliminated.

bouncing_ball_benchmark.m benchmarks the model by testing increasingly smaller time steps. The model was then compiled and tested in Python and the corresponding times are recorded below.

Time Step Simulink Duration (s) Python Duration (s)
1e-4 0.5905 0.06
1e-5 1.0461 0.61
1e-6 8.1991 6.08
1e-7 78.9901 60.18

Jenkins Build Automation

This project also serves as a proof of concept for using CI/CD devops techniques with Simulink Models. There is a Jenkinsfile that will build each of the examples and archive the artifacts:

  • shared library (.dll)
  • header files (.h)

Jenkins Pipeline screenshot:

Jenkins pipeline screenshot

Jenkins Artifacts screenshot:

Jenkins artifacts

Discussion, Questions & Feedback