Python Dynamics Simulations : Part 1 — Setting Up Simulations

Juan Sandubete
Jul 24, 2020 · 5 min read

From some years now, it has become popular to teach university subjects with the help of Matlab and Simulink. It is justified as it is a plug and play environment which allows to launch all kind of simulations with minor efforts and to focus in the actual content under study. Nice. The problem it originates is the dependence of this property software. Many people cannot simulate dynamics (e.g. a simple DC motor) without using Matlab.

I worked in a project for which engineers were struggling to embed Simulink in a test-bed system as they were not able to simulate the digital twin otherwise… That does not make sense.

For this reason I have planned to write some stories, a tutorial, to show how I deal with the dynamics simulations using Python, NumPy and SciPy (mainly) which can be executed even with a Raspberry Pi. Here you have the complete index of the tutorial.

In this Part 1 I will show some easy ways to create system “blocks” and how to interconnect them for the simulation.

Note: This post is the most basic in terms of code. It is introductory, written for people who is not comfortable dealing with OOP. If it is too easy for you, I encourage you to take a look of the index and to jump to the stuff you want.

1. Steps

The following is my workflow recommendation, it is not the only way to do it so feel free to make suggestions.

  1. Draw a block diagram. As we do not have a visual framework to setup the system blocks, it is easier if you draw them first with reference to all the signals.
  2. Write, at least, one function for each block. The code is more readable when there is a function for the DC motor model and another for its controller. This gets more important as systems become more complex.
  3. Write an interconnection function.
    - The functions must begin with the extraction of the previous simulation step arguments, i.e. for time interval k, the variable x_{k} will be equal to x_{k+1} from the previous step.
    - With the help of the block diagram and (important!) suitable nomenclature, write outputs variables as inputs for the subsequent blocks.
    - Return the values which will be the updating arguments for the following interval and also all the data you may want to store or plot later.
  4. Create a initial values list with the same length of the interconnection function return list, one value per variable.
  5. Create time vector and (if necessary) reference values for the controller.
  6. Do not forget to plot your results or to store them after simulating.

2. Non-Linear Motor Control

To show it in a simple way, we will see the non-linear control (input-output linearization method) of a DC motor as an example of those steps and to show what can we achieve simulating dynamics with Python. If you only want to see how to implement your equations, you can skip the maths stuff.

Suppose the motor dynamics following the expression [1]:

Equation 1. Motor model

Where tau is the torque, a (empirically determined) weights the inertia due to the current torque, k (empirically determined too) weights the effort through the current torque and the input to modify the change rate of the torque itself, and u is the control input to the motor, the voltage. Then, choosing the control law (how u is calculated) as follows:

Equation 2. Control law

Leads the output torque to:

Equation 3. Error dynamics

Thus the term which depends of tau gets compensated by the first control term, linearizing the relation input-output and making the error to exponentially tend to zero.

  1. Blocks diagram:
Figure 1. Blocks diagram of motor model with controller

Note. The simulation step block only serves for us to clearly see how outputs are propagated in time, but it is not something you have to create.

2. Functions for each module: Here the controller and the motor model.

Motor model code
Controller code

3. Interconnection function: This function also must have a special arguments in order to work as ODE Integrator expects to, i.e. integrated signals (states), time steps and external arguments like the references for the controller.

Interconnection code

4. Initial values, time vector and ODE simulation: In this example, the ODE integration is made for every step, loading the corresponding references.

ODE Integration (simulation)

Note: It may be easier to run the simulation once instead of taking every step separately in a for loop, but this way you can add logic and other stuff without breaking the integrator. Feel free to share any considerations here!

3. Results

The resulting controller for this simple system makes perfect results, so I added some modelling error to the controller embedded model, with respect to the real motor model, in order to evaluate how it works with some uncertainties. For values: a = 1, k = 1, a_model_error = 0.1 k_model_error = 0.3, the results are something like this (in red, real output, dashed the reference):

Figure 2. Simulation results with non-perfect modelling of the motor.

Pretty good even with injected errors in the modelling of 10% and 30% respectively for each model parameter.

That’s all ! Here you can find the complete code on Github (also with the plots functions). To learn how to do these simulations, I read this Marat Kopytjuk story and also this web owned by John D. Hedengren. They have good material, so take a look of it.

I hope you enjoyed this tutorial and, if you have any thoughts, recommendations or petitions for future tutorials on Dynamic Simulations with Python, I would really appreciate your comments!

Now you can check the second part of this tutorial to learn how to test C/C++ controllers using what you know of Python Dynamics Simulations.

4. References

[1] Jean-Jacques E. Slotine, Weiping Li (1988)Feedback Linearization’ in Applied Nonliner Control.

Robotics Devs

Code and algorithms tutorials for roboticists

Juan Sandubete

Written by

Andalusian Robotics Engineer and SCUBA Diver who loves to learn stuff, to build artifacts and to experience nice things. https://www.instagram.com/jsandubete

Robotics Devs

Dynamic simulations with Python, navigation and control algorithms with C++, embedded systems, basic electronics and other useful topics for robotics developers. If you want to publish in Robotics Devs, send your draft to: roboticsdevs@gmail.com

Juan Sandubete

Written by

Andalusian Robotics Engineer and SCUBA Diver who loves to learn stuff, to build artifacts and to experience nice things. https://www.instagram.com/jsandubete

Robotics Devs

Dynamic simulations with Python, navigation and control algorithms with C++, embedded systems, basic electronics and other useful topics for robotics developers. If you want to publish in Robotics Devs, send your draft to: roboticsdevs@gmail.com

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store