Discrete Systems with Python
Transcript of Discrete Systems with Python
Discrete Systems with Python
Hans-Petter Halvorsen
https://www.halvorsen.blog
https://www.halvorsen.blog/documents/programming/python/
Free Textbook with lots of Practical Examples
Additional Python Resources
https://www.halvorsen.blog/documents/programming/python/
β’ Differential Equationsβ’ Simulationβ’ Discrete Systemsβ’ Examples
Contents
β’ Python has powerful features for simulation of continuous differential equations and dynamic systems.
β’ Sometimes we want to or need to discretize a continuous system and then simulate it in Python.
β’ This means we need to make a discrete version of our continuous differential equations.
β’ The built-in ODE solvers in Python use different discretization methods
Simulation of Discrete Systems
Differential Equations
Hans-Petter Halvorsen
https://www.halvorsen.blog
Differential Equationsππ¦ππ‘
= π π‘, π¦ , π¦ π‘! = π¦!
ππ¦ππ‘
= π¦! = οΏ½ΜοΏ½
Different notation is used:
ππ¦ππ‘
= 3y + 2, π¦ π‘! = 0
Example:Initial condition
Differential Equation on general form:
ODE β Ordinary Differential Equations
Differential Equations
οΏ½ΜοΏ½ = ππ₯Example:
Where π = β "#, where π is denoted as the time constant of the system
Note that οΏ½ΜοΏ½ = !"!#
The solution for the differential equation is found to be (learned in basic Math courses and will not be derived here):
π₯ π‘ = π!"π₯# Where π₯$ = π₯ 0 = π₯(π‘$) is the initial condition
Where π₯! = π₯ 0 = π₯(π‘!) is the initial condition
Python Codeimport math as mtimport numpy as npimport matplotlib.pyplot as plt
# ParametersT = 5a = -1/Tx0 = 1 t = 0tstart = 0tstop = 25increment = 1
x = []x = np.zeros(tstop+1)t = np.arange(tstart,tstop+1,increment)
# Define the Equationfor k in range(tstop):
x[k] = mt.exp(a*t[k]) * x0
# Plot the Resultsplt.plot(t,x)plt.title('Plotting Differential Equation Solution')plt.xlabel('t')plt.ylabel('x(t)')plt.grid()plt.axis([0, 25, 0, 1])
π₯ π‘ = π*+π₯,In our system we can set π = 5 and the initial condition π₯! = π₯(0) = 1
Alt. Solutionimport numpy as npimport matplotlib.pyplot as plt
# ParametersT = 5a = -1/Tx0 = 1 t = 0
tstart = 0tstop = 25increment = 1N = 25
#t = np.arange(tstart,tstop+1,increment) #Alternative Approacht = np.linspace(tstart, tstop, N)
x = np.exp(a*t) * x0
# Plot the Resultsplt.plot(t,x)plt.title('Plotting Differential Equation Solution')plt.xlabel('t')plt.ylabel('x(t)')plt.grid()plt.axis([0, 25, 0, 1])plt.show()
π₯ π‘ = π*+π₯,In our system we can set π = 5 and the initial condition π₯! = π₯(0) = 1
In this alternative solution no For Loop has been used
(without For Loop)
Summaryβ’ Solving differential equations like shown in these
examples works fineβ’ But the problem is that we first have to manually (by
βpen and paperβ) find the solution to the differential equation.
β’ An alternative is to use solvers for Ordinary Differential Equations (ODE) in Python, so-called ODE Solvers
β’ The next approach is to find the discrete version and then implement and simulate the discrete system
β’ The scipy.integrate library has two powerful powerfulfunctions; ode() and odeint(), for numerically solving first order ordinary differential equations (ODEs).
β’ The ode() is more flexible, while odeint() (ODE integrator) has a simpler Python interface and works fine for most problems.
β’ For details, see the SciPy documentation:β’ https://docs.scipy.org/doc/scipy/reference/generated/scipy.
integrate.odeint.htmlβ’ https://docs.scipy.org/doc/scipy-
0.14.0/reference/generated/scipy.integrate.ode.html
ODE Solvers in Python
Python Codeimport numpy as npfrom scipy.integrate import odeintimport matplotlib.pyplot as plt
# Initializationtstart = 0tstop = 25increment = 1x0 = 1t = np.arange(tstart,tstop+1,increment)
# Function that returns dx/dtdef mydiff(x, t):
T = 5a = -1/Tdxdt = a * xreturn dxdt
# Solve ODEx = odeint(mydiff, x0, t)print(x)
# Plot the Resultsplt.plot(t,x)plt.title('Plotting Differential Equation Solution')plt.xlabel('t')plt.ylabel('x(t)')plt.grid()plt.axis([0, 25, 0, 1])plt.show()
In our system we can set π = 5 (π = β "#
) and the initial condition π₯! = π₯(0) = 1
Here we use an ODE solver in SciPy
οΏ½ΜοΏ½ = ππ₯
Discrete Systems
Hans-Petter Halvorsen
https://www.halvorsen.blog
DiscretizationEuler backward method:
Euler forward method:
οΏ½ΜοΏ½ βπ₯ π β π₯(π β 1)
π2
οΏ½ΜοΏ½ βπ₯ π + 1 β π₯(π)
π2
β’ EulerβEuler forward methodβEuler backward method
β’ Zero Order Hold (ZOH) β’ Tustinβ’ ...
Discretization MethodsWe have many different Discretization Methods
We will focus on this since it it easy to use and implement
Discrete SystemsDifferent Discrete Symbols and meanings
Present/Current Value:
Previous Value:
Next (Future) Value:
Note! Different Notation is used in different literature!
π₯ π β 1 = π₯$%& = π₯(π‘$%&)
π₯ π = π₯$ = π₯(π‘$)
π₯ π + 1 = π₯$'& = π₯(π‘$'&)
EulerEuler backward method:
More Accurate!
Euler forward method:Simpler to use!οΏ½ΜοΏ½ β
π₯ π + 1 β π₯(π)π(
οΏ½ΜοΏ½ βπ₯ π β π₯(π β 1)
π(
Where π$ is the sampling time, and π₯(π + 1), π₯(π) and π₯(π β 1) are discrete values of π₯(π‘)
(We will primary use this in the examples)
Simulation ExampleGiven the following differential equation:
οΏ½ΜοΏ½ = ππ₯where π = β "
#, where π is the time constant
Note! οΏ½ΜοΏ½ = 565+
Find the discrete differential equation and plot the solution for this system using Python.Set π = 5 and the initial condition π₯(0) = 1.We will create a script in Python where we plot the solution π₯ π‘in the time interval 0 β€ π‘ β€ 25
DiscretizationThe differential equation of the system is:
οΏ½ΜοΏ½ = ππ₯We need to find the discrete version:
We use the Euler forward method:
οΏ½ΜοΏ½ βπ₯!"# β π₯!
π$
π₯%&" β π₯%π$
= ππ₯%
This gives:
Next:
π₯%&" β π₯% = π$ππ₯%
π₯78" = π₯7 + π2ππ₯7
Next:
π₯78" = (1 + ππ2) π₯7
This gives the following discrete version:
Python Codeimport numpy as npimport matplotlib.pyplot as plt
# Model ParametersT = 5a = -1/T# Simulation ParametersTs = 0.01Tstop = 25xk = 1N = int(Tstop/Ts) # Simulation lengthdata = []data.append(xk)
# Simulationfor k in range(N):
xk1 = xk + Ts* a * xkxk = xk1data.append(xk1)
# Plot the Simulation Resultst = np.arange(0,Tstop+Ts,Ts)
plt.plot(t,data)plt.title('Plotting Differential Equation Solution')plt.xlabel('t')plt.ylabel('x(t)')plt.grid()plt.axis([0, 25, 0, 1])plt.show()
π₯%&" = (1 + ππ$)π₯%Simulation of Discrete System:
Differential Equation: οΏ½ΜοΏ½ = ππ₯
Alt. Codeimport numpy as npimport matplotlib.pyplot as plt
# Model ParametersT = 5a = -1/T# Simulation ParametersTs = 0.01Tstop = 25
N = int(Tstop/Ts) # Simulation lengthx = np.zeros(N+2) # Initialization the x vectorx[0] = 1 # Initial Condition
# Simulationfor k in range(N+1):
x[k+1] = (1 + a*Ts) * x[k]
# Plot the Simulation Resultst = np.arange(0,Tstop+2*Ts,Ts) # Create Time Series
plt.plot(t,x)plt.title('Plotting Differential Equation Solution')plt.xlabel('t')plt.ylabel('x(t)')plt.grid()plt.axis([0, 25, 0, 1])plt.show()
π₯%&" = (1 + ππ$)π₯%Simulation of Discrete System:
Differential Equation: οΏ½ΜοΏ½ = ππ₯(using Arrays)
More Examples
Hans-Petter Halvorsen
https://www.halvorsen.blog
Bacteria Simulation
Hans-Petter Halvorsen
https://www.halvorsen.blog
Bacteria SimulationThe model is as follows:
In this example we will simulate a simple model of a bacteria population in a jar.
Birth rate: ππ₯Death rate: ππ₯'
Then the total rate of change of bacteria population is:
οΏ½ΜοΏ½ = ππ₯ β ππ₯<
Note that οΏ½ΜοΏ½ = ()(*
Where x is the number of bacteria in the jar
In the simulations we can set b=1/hour and p=0.5 bacteria-hour
We will simulate the number of bacteria in the jar after 1 hour, assuming that initially there are 100 bacteria present.
DiscretizationThe differential equation of the system is:
οΏ½ΜοΏ½ = ππ₯ β ππ₯<
We need to find the discrete version:
We use the Euler forward method:
οΏ½ΜοΏ½ βπ₯!"# β π₯!
π$
π₯%&" β π₯%π$
= ππ₯% β ππ₯%'
This gives:
Next:
π₯%&" β π₯% = π$(ππ₯% β ππ₯%')
π₯78" = π₯7 + π2(ππ₯7 β ππ₯7<)
This gives the following discrete version:
Python Code# Simulation of Bacteria Populationimport numpy as npimport matplotlib.pyplot as plt
# Model Parametersb = 1p = 0.5
# Simulation ParametersTs = 0.01Tstop = 1xk = 100N = int(Tstop/Ts) # Simulation lengthdata = []data.append(xk)
# Simulationfor k in range(N):
xk1 = xk + Ts* (b * xk - p * xk**2);xk = xk1data.append(xk1)
# Plot the Simulation Resultst = np.arange(0,Tstop+Ts,Ts)
plt.plot(t,data)plt.title('Simulation of Bacteria Population')plt.xlabel('t [s]')plt.ylabel('x(t)')plt.grid()plt.xlim(0, 1)plt.ylim(0, 100) plt.show()
π₯%&" = π₯% + π$(ππ₯% β ππ₯%')Simulation of Discrete System:
Differential Equation: οΏ½ΜοΏ½ = ππ₯ β ππ₯'
Alt. Codeimport numpy as npimport matplotlib.pyplot as plt
# Model Parametersb = 1p = 0.5
# Simulation ParametersTs = 0.01Tstop = 1
N = int(Tstop/Ts) # Simulation lengthx = np.zeros(N+2) # Initialization the x vectorx[0] = 100 # Initial Condition
# Simulationfor k in range(N+1):
x[k+1] = x[k] + Ts * (b * x[k] - p * x[k]**2)
# Plot the Simulation Resultst = np.arange(0,Tstop+2*Ts,Ts) # Create Time Series
plt.plot(t,x)plt.title('Simulation of Bacteria Population')plt.xlabel('t [s]')plt.ylabel('x(t)')plt.grid()plt.axis([0, 1, 0, 100])plt.show()
π₯%&" = π₯% + π$(ππ₯% β ππ₯%')Simulation of Discrete System:
Differential Equation: οΏ½ΜοΏ½ = ππ₯ β ππ₯'(using Arrays)
Simulations with 2 variables
Hans-Petter Halvorsen
https://www.halvorsen.blog
Simulation with 2 variablesGiven the following system:
ππ₯"ππ‘
= βπ₯<
ππ₯<ππ‘
= π₯"
Let's find the discrete system and simulate the discrete system in Python.
DiscretizationUsing Euler:
οΏ½ΜοΏ½ βπ₯ π + 1 β π₯(π)
π2Then we get:
π₯" π + 1 = π₯" π β π2π₯< ππ₯< π + 1 = π₯< π + π2π₯" π
Which we can implement in Python
The equations will be solved in the time span [β1 1] with initial values [1, 1].
Python Codeimport numpy as npimport matplotlib.pyplot as plt
# Model and Simulation Parametersb = 1p = 0.5Ts = 0.1Tstart = -1Tstop = 1x1k = 1x2k = 1N = int((Tstop-Tstart)/Ts) # Simulation lengthdatax1 = []datax2 = []datax1.append(x1k)datax2.append(x2k)
# Simulationfor k in range(N):
x1k1 = x1k - Ts * x2kx2k1 = x2k + Ts * x1k
x1k = x1k1x2k = x2k1datax1.append(x1k1)datax2.append(x2k1)
# Plot the Simulation Resultst = np.arange(Tstart,Tstop+Ts,Ts)
plt.plot(t,datax1, t, datax2)plt.title('Simulation with 2 Variables')plt.xlabel('t [s]')plt.ylabel('x(t)')plt.grid()plt.axis([-1, 1, -1.5, 1.5])plt.show()
π₯! π + 1 = π₯! π β π"π₯# ππ₯# π + 1 = π₯# π + π"π₯! π
ππ₯!ππ‘
= βπ₯#
ππ₯#ππ‘
= π₯!
Alt. Code# Simulation with 2 Variablesimport numpy as npimport matplotlib.pyplot as plt
# Model Parametersb = 1p = 0.5
# Simulation ParametersTs = 0.1Tstart = -1Tstop = 1N = int((Tstop-Tstart)/Ts) # Simulation lengthx1 = np.zeros(N+2)x2 = np.zeros(N+2)x1[0] = 1x2[0] = 1
# Simulationfor k in range(N+1):
x1[k+1] = x1[k] - Ts * x2[k]x2[k+1] = x2[k] + Ts * x1[k]
# Plot the Simulation Resultst = np.arange(Tstart,Tstop+2*Ts,Ts)
plt.plot(t,x1, t, x2)plt.title('Simulation with 2 Variables')plt.xlabel('t [s]')plt.ylabel('x(t)')plt.grid()plt.axis([-1, 1, -1.5, 1.5])plt.show()
π₯! π + 1 = π₯! π β π"π₯# ππ₯# π + 1 = π₯# π + π"π₯! π
ππ₯!ππ‘
= βπ₯#
ππ₯#ππ‘
= π₯!
(using Arrays)
Simulation of 1.order System
Hans-Petter Halvorsen
https://www.halvorsen.blog
1.order Dynamic System
οΏ½ΜοΏ½ =1π (βπ¦ + πΎπ’)
Where πΎ is the Gain and π is the Time constant
οΏ½ΜοΏ½ = ππ¦ + ππ’ Dynamic Systemπ’(π‘) π¦(π‘)
Assume the following general Differential Equation:
or
Where π = β "#
and π = +#
This differential equation represents a 1. order dynamic system
Assume π’(π‘) is a step (π), then we can find that the solution to the differential equation is:
π¦ π‘ = πΎπ(1 β π,*#)
Input Signal Output Signal
Step Response100%
63%
πΎπ
π‘π
π¦ π‘ = πΎπ(1 β π,*#)
οΏ½ΜοΏ½ =1π (βπ¦ + πΎπ’)
1.order Dynamic SystemοΏ½ΜοΏ½ =
1π (βπ¦ + πΎπ’)
Let's find the mathematical expression for the step response
π π¦(π ) =1π (βπ¦(π ) + πΎπ’(π ))
We use Laplace: Note οΏ½ΜοΏ½ βΊ π π¦(π )
We apply a step in the input signal π’(π ): π’ π = -$
π π¦ π +1π π¦(π ) =
πΎπ π’(π )
ππ π¦ π + π¦(π ) = πΎπ’(π )
(ππ + 1)π¦ π = πΎπ’(π )
π¦ π =πΎ
ππ + 1π’(π )
π¦ π =πΎ
ππ + 1 Dππ
We use the following Laplace Transformation pair in order to find π¦(π‘): π
ππ + 1 π βΊ π(1 β π,*#)
Given the differential equation:
π¦ π‘ = πΎπ(1 β π,*#)
This gives the following step response:
Next, we use Inverse Laplace
Python Codeimport numpy as npimport matplotlib.pyplot as plt
K = 3T = 4start = 0stop = 30increment = 0.1t = np.arange(start,stop,increment)
y = K * (1-np.exp(-t/T))
plt.plot(t, y)plt.title('1.order Dynamic System')plt.xlabel('t [s]')plt.ylabel('y(t)'plt.grid()
π¦ π‘ = πΎπ(1 β πE+#)
We start by plotting the following:
In the Python code we can set:
π = 1πΎ = 3π = 4
Python Code (Alternative Code)import numpy as npimport matplotlib.pyplot as plt
def model(t):K = 3T = 4y = K * (1-np.exp(-t/T))return y
start = 0stop = 30increment = 0.1t = np.arange(start,stop,increment)
y = model(t)
plt.plot(t, y)plt.title('1.order Dynamic System')plt.xlabel('t [s]')plt.ylabel('y(t)'plt.grid()
π¦ π‘ = πΎπ(1 β πE+#)
We start by plotting the following:
In the Python code we can set:
π = 1πΎ = 3π = 4
Discretization
οΏ½ΜοΏ½ = ππ¦ + ππ’We start with the differential equation:
We use the Euler forward method:
οΏ½ΜοΏ½ βπ¦!"# β π¦!
π$
This gives:
.!"#,.!#$
= ππ¦% + ππ’%
This gives the following discrete differential equation:
π¦%&" = π¦% + π$ ππ¦% + ππ’%
Further we get:
π¦%&" = π¦% + π$ππ¦%+ π$ππ’%
π¦78" = (1 + π2π)π¦7+ π2ππ’7
Python Code# Simulation of discrete modelimport numpy as npimport matplotlib.pyplot as plt
# Model ParametersK = 3T = 4
a = -1/Tb = K/T
# Simulation ParametersTs = 0.1Tstop = 30uk = 1 # Step Responseyk = 0 # Initial ValueN = int(Tstop/Ts) # Simulation lengthdata = []data.append(yk)
# Simulationfor k in range(N):
yk1 = (1 + a*Ts) * yk + Ts * b * ukyk = yk1data.append(yk1)
# Plot the Simulation Resultst = np.arange(0,Tstop+Ts,Ts)
plt.plot(t,data)plt.title('1.order Dynamic System')plt.xlabel('t [s]')plt.ylabel('y(t)')plt.grid()
Where π = β "#
and π = +#
π¦78" = (1 + π2π)π¦7+ π2ππ’7
In the Python code we can set:
Let's simulate the discrete system:
πΎ = 3π = 4
Alt. Solution# Simulation of discrete modelimport numpy as npimport matplotlib.pyplot as plt
# Model ParametersK = 3T = 4
a = -1/Tb = K/T
# Simulation ParametersTs = 0.1 # Sampling TimeTstop = 30 # End of Simulation Timeuk = 1 # Step ResponseN = int(Tstop/Ts) # Simulation lengthy = np.zeros(N+2) # Initialization the x vectory[0] = 0
# Simulationfor k in range(N+1):
y[k+1] = (1 + a*Ts) * y[k] + Ts * b * uk
# Plot the Simulation Resultst = np.arange(0,Tstop+2*Ts,Ts) # Create Time Seriesplt.plot(t,y)# Formatting the appearance of the Plotplt.title('1.order Dynamic System')plt.xlabel('t [s]')plt.ylabel('y(t)')plt.grid()
Where π = β "#
and π = +#
π¦78" = (1 + π2π)π¦7+ π2ππ’7
In the Python code we can set:
Let's simulate the discrete system:
πΎ = 3π = 4
Higher Order Systems
Hans-Petter Halvorsen
https://www.halvorsen.blog
Mass-Spring DamperGiven a so-called "Mass-Spring-Damper" system
πΉ π‘ β ποΏ½ΜοΏ½ π‘ β ππ₯ π‘ = ποΏ½ΜοΏ½(π‘)
The system can be described by the following equation:
Where π‘ is the time, πΉ(π‘) is an external force applied to the system, π is the damping constant, π is the stiffness of the spring, π is a mass.
x(t) is the position of the object (π)
οΏ½ΜοΏ½ π‘ is the first derivative of the position, which equals the velocity/speed of the object (π)
οΏ½ΜοΏ½(π‘) is the second derivative of the position, which equals the acceleration of the object (π)
Newtons 2.law: βπΉ = ππ
Mass-Spring DamperπΉ π‘ β ποΏ½ΜοΏ½ π‘ β ππ₯ π‘ = ποΏ½ΜοΏ½(π‘)
ποΏ½ΜοΏ½ = πΉ β ποΏ½ΜοΏ½ β ππ₯
οΏ½ΜοΏ½ =1π πΉ β ποΏ½ΜοΏ½ β ππ₯
Higher order differential equations can typically be reformulated into a system of first order differential equations
We set π₯ = π₯"οΏ½ΜοΏ½ = π₯'
This gives:οΏ½ΜοΏ½" = π₯'οΏ½ΜοΏ½' = οΏ½ΜοΏ½= "
/πΉ β ποΏ½ΜοΏ½ β ππ₯ = "
/πΉ β ππ₯' β ππ₯"
οΏ½ΜοΏ½ =1π
πΉ β ποΏ½ΜοΏ½ β ππ₯οΏ½ΜοΏ½" = π₯<οΏ½ΜοΏ½< =
"M πΉ β ππ₯< β ππ₯"
Finally:
π₯"= Positionπ₯'= Velocity/Speed
Python Codeimport numpy as npfrom scipy.integrate import odeintimport matplotlib.pyplot as plt
# Initializationtstart = 0tstop = 60increment = 0.1
# Initial conditionx_init = [0,0]
t = np.arange(tstart,tstop+1,increment)
# Function that returns dx/dtdef mydiff(x, t):
c = 4 # Damping constantk = 2 # Stiffness of the springm = 20 # MassF = 5
dx1dt = x[1] dx2dt = (F - c*x[1] - k*x[0])/m
dxdt = [dx1dt, dx2dt]return dxdt
# Solve ODEx = odeint(mydiff, x_init, t)
x1 = x[:,0]x2 = x[:,1]
# Plot the Resultsplt.plot(t,x1)plt.plot(t,x2)plt.title('Simulation of Mass-Spring-Damper System')plt.xlabel('t')plt.ylabel('x(t)')plt.legend(["x1", "x2"])plt.grid()plt.show()
π₯"= Positionπ₯'= Velocity/Speed
οΏ½ΜοΏ½" = π₯'οΏ½ΜοΏ½' =
"/πΉ β ππ₯' β ππ₯"
Using SciPy ODE Solver
State-space ModelοΏ½ΜοΏ½" = π₯<οΏ½ΜοΏ½< =
"M πΉ β ππ₯< β ππ₯"
οΏ½ΜοΏ½" = π₯<οΏ½ΜοΏ½< =β
7M π₯" β
NM π₯<+ "
MπΉ
οΏ½ΜοΏ½ = π΄π₯ + π΅π’
π΄ =0 1
βππ
βππ
π΅ =01π
π₯ =π₯#π₯%
οΏ½ΜοΏ½"οΏ½ΜοΏ½'
=0 1
βππ
βππ
π₯"π₯' +
01π
πΉ
Python Codeimport numpy as npimport matplotlib.pyplot as pltimport control
# Parameters defining the systemc = 4 # Damping constantk = 2 # Stiffness of the springm = 20 # MassF = 5 # Force
# Simulation Parameterststart = 0tstop = 60increment = 0.1t = np.arange(tstart,tstop+1,increment)
# System matricesA = [[0, 1], [-k/m, -c/m]]B = [[0], [1/m]]C = [[1, 0]]sys = control.ss(A, B, C, 0)
# Step response for the systemt, y, x = control.forced_response(sys, t, F)plt.plot(t, y)plt.title('Simulation of Mass-Spring-Damper System')plt.xlabel('t')plt.ylabel('x(t)')plt.grid()plt.show()
State-space Model
οΏ½ΜοΏ½"οΏ½ΜοΏ½'
=0 1
βππ β
ππ
π₯"π₯' +
01π
πΉ
π¦ = 1 0π₯"π₯'
Python Codeimport numpy as npimport matplotlib.pyplot as pltimport control
# Parameters defining the systemc = 4 # Damping constantk = 2 # Stiffness of the springm = 20 # MassF = 5 # Force
# Simulation Parameterststart = 0tstop = 60increment = 0.1t = np.arange(tstart,tstop+1,increment)
# System matricesA = [[0, 1], [-k/m, -c/m]]B = [[0], [1/m]]C = [[1, 0]]sys = control.ss(A, B, C, 0)
# Step response for the systemt, y, x = control.forced_response(sys, t, F)x1 = x[0 ,:]x2 = x[1 ,:]
plt.plot(t, x1, t, x2)plt.title('Simulation of Mass-Spring-Damper System')plt.xlabel('t')plt.ylabel('x(t)')plt.grid()plt.show()
State-space Model
οΏ½ΜοΏ½"οΏ½ΜοΏ½'
=0 1
βππ β
ππ
π₯"π₯' +
01π
πΉ
π¦ = 1 0π₯"π₯'
DiscretizationGiven:
οΏ½ΜοΏ½! = π₯"οΏ½ΜοΏ½" =
!#πΉ β ππ₯" β ππ₯!
Using Euler:
οΏ½ΜοΏ½ βπ₯ π + 1 β π₯(π)
π$
Then we get:π₯! π + 1 β π₯! π
π$= π₯" π
π₯" π + 1 β π₯" ππ$
=1π
πΉ(π) β ππ₯" π β ππ₯! π
This gives:π₯! π + 1 = π₯! π + π$π₯" π
π₯" π + 1 = π₯" π + π$1π
πΉ(π) β ππ₯" π β ππ₯! π
Then we get:π₯! π + 1 = π₯! π + π$π₯" ππ₯" π + 1 = βπ$
%#π₯! π + π₯" π β π$
&#π₯" π + π$
!#πΉ(π)
Finally:π₯! π + 1 = π₯! π + π$π₯" ππ₯" π + 1 = βπ$
%#π₯! π + (1 β π$
&#)π₯" π + π$
!#πΉ(π)
π₯" π + 1 = π₯" π + π$π₯' ππ₯' π + 1 = βπ$
%/π₯" π + (1 β π$
0/)π₯' π + π$
"/πΉ
π₯" π + 1π₯' π + 1
=1 π$
βπ$ππ 1 β π$
ππ
π₯" ππ₯' π
+0
π$1π
πΉ
Discrete State-space ModelDiscrete System:
π₯(π + 1) = π΄(π₯(π) + π΅(π’(π)
π΄ =1 π$
βπ$ππ
1 β π$ππ
π΅ =0
π$1π
π₯(π) = π₯# ππ₯% π
We can set it on Discrete state space form:
This gives:
Python Code# Simulation of Mass-Spring-Damper Systemimport numpy as npimport matplotlib.pyplot as plt
# Model Parametersc = 4 # Damping constantk = 2 # Stiffness of the springm = 20 # MassF = 5 # Force
# Simulation ParametersTs = 0.1Tstart = 0Tstop = 60N = int((Tstop-Tstart)/Ts) # Simulation lengthx1 = np.zeros(N+2)x2 = np.zeros(N+2)x1[0] = 0 # Initial Positionx2[0] = 0 # Initial Speed
a11 = 1a12 = Tsa21 = -(Ts*k)/ma22 = 1 - (Ts*c)/m
b1 = 0b2 = Ts/m
# Simulationfor k in range(N+1):
x1[k+1] = a11 * x1[k] + a12 * x2[k] + b1 * Fx2[k+1] = a21 * x1[k] + a22 * x2[k] + b2 * F
# Plot the Simulation Resultst = np.arange(Tstart,Tstop+2*Ts,Ts)
#plt.plot(t, x1, t, x2)plt.plot(t,x1)plt.plot(t,x2)plt.title('Simulation of Mass-Spring-Damper System')plt.xlabel('t [s]')plt.ylabel('x(t)')plt.grid()plt.legend(["x1", "x2"])plt.show()
π₯!= Positionπ₯"= Velocity/Speed
Discrete System
π₯" π + 1 = π₯" π + π$π₯' ππ₯' π + 1 = βπ$
%/π₯" π + (1 β π$
0/)π₯' π + π$
"/πΉ
Additional Python Resources
https://www.halvorsen.blog/documents/programming/python/
Hans-Petter Halvorsen
University of South-Eastern Norwaywww.usn.no
E-mail: [email protected]: https://www.halvorsen.blog