# Mass-spring-damper

In this tutorial, we will describe the mechanics and control of the one degree of freedom translational mass-spring-damper system subject to a control input force. We will first derive the dynamic equations by hand. Then, we will derive them using the `sympy.mechanics` python package.

The system on which we will work is depicted below:



Note that in what follows, we use the notation $u(t) = F$.

## 1. Mechanics

### Deriving the dynamical equations by hand

#### 1.1 By using Newton equations

Using Newton's law, we have:

\begin{align}
    m \ddot{x}(t) &= \sum F_{ext} \\
    &= - b \dot{x}(t) - k x(t) + u(t)
\end{align}

#### 1.2 By using the Lagrange Method

Let's first derive the kinematic and potential energies.

\begin{equation}
    T = \frac{1}{2} m \dot{x} \\
    V = - \int \vec{F} . \vec{dl} = - \int (-kx \vec{1_x}) . dx \vec{1_x} = \frac{k x^2}{2}
\end{equation}

The Lagrangian is then given by:
\begin{equation}
    \mathcal{L} = T - V = \frac{1}{2} m \dot{x} - \frac{k x^2}{2}
\end{equation}

Using the Lagrange's equations we can derive the dynamics of the system:

\begin{equation}
    \frac{d}{dt} \frac{\partial \mathcal{L}}{\partial \dot{q}} - \frac{\partial \mathcal{L}}{\partial q} = Q
\end{equation}

where $q$ are the generalized coordinates (in this case $x$), and $Q$ represents the non-conservative forces (input force, dragging or friction forces, etc).

* $\frac{d}{dt} \frac{\partial \mathcal{L}}{\partial \dot{x}} = \frac{d}{dt} m \dot{x}(t) = m \ddot{x}(t) $
* $\frac{\partial \mathcal{L}}{\partial x} = - k x(t) $
* $Q = - b \dot{x}(t) + u(t) $

which when putting everything back together gives us:

\begin{equation}
    m \ddot{x}(t) + b \dot{x}(t) + k x(t) = u(t)
\end{equation}

### Deriving the dynamical equations using sympy


```python
import sympy
import sympy.physics.mechanics as mechanics
from sympy import init_printing
init_printing(use_latex='mathjax')
from sympy import pprint
```


```python
# define variables 
q = mechanics.dynamicsymbols('q')
dq = mechanics.dynamicsymbols('q', 1)
u = mechanics.dynamicsymbols('u')

# define constants
m, k, b = sympy.symbols('m k b')

# define the inertial frame
N = mechanics.ReferenceFrame('N')

# define a particle for the mass
P = mechanics.Point('P')
P.set_vel(N, dq * N.x) # go in the x direction
Pa = mechanics.Particle('Pa', P, m)

# define the potential energy for the particle (the kinematic one is derived automatically)
Pa.potential_energy = k * q**2 / 2.0

# define the Lagrangian and the non-conservative force applied on the point P
L = mechanics.Lagrangian(N, Pa)
force = [(P, -b * dq * N.x + u * N.x)]

# Lagrange equations 
lagrange = mechanics.LagrangesMethod(L, [q], forcelist = force, frame = N)
pprint(lagrange.form_lagranges_equations())
```

    ⎡                              2             ⎤
    ⎢  d                          d              ⎥
    ⎢b⋅──(q(t)) + 1.0⋅k⋅q(t) + m⋅───(q(t)) - u(t)⎥
    ⎢  dt                          2             ⎥
    ⎣                            dt              ⎦


## 2. Laplace transform and transfer function

Applying the Laplace transform on the dynamic equation:

\begin{equation}
    m \ddot{x}(t) + b \dot{x}(t) + k x(t) = u(t) \stackrel{L}{\rightarrow} m s^2 X(s) + b s X(s) + k X(s) = U(s)
\end{equation}

The transfer equation is given by:

\begin{equation}
    H(s) = \frac{X(s)}{U(s)} = \frac{1}{m s^2 + b s + k}
\end{equation}

By calculating the pole:

\begin{equation}
    m s^2 + b s + k = 0 \Leftrightarrow s = \frac{-b}{2m} \pm \sqrt{\left(\frac{b}{2m}\right)^2 - \frac{k}{m}}
\end{equation}

Note that $b, k, m > 0$ because they represent real physical quantities.

### LTI system

We can rewrite the above equation as a first-order system of equations. Let's first define the state vector $\pmb{x} = \left[ \begin{array}{c} x(t) \\ \dot{x}(t) \end{array} \right]$ and the control vector $\pmb{u} = \left[ \begin{array}{c} u(t) \end{array} \right]$, then we can rewrite the above equation in the form $\pmb{\dot{x}} = \pmb{Ax} + \pmb{Bu}$, as below:

\begin{equation}
    \left[ \begin{array}{c} \dot{x}(t) \\ \ddot{x}(t) \end{array} \right] = \left[ \begin{array}{cc} 0 & 1 \\ -\frac{k}{m} & -\frac{b}{m} \end{array} \right] \left[ \begin{array}{c} x(t) \\ \dot{x}(t) \end{array} \right] + \left[ \begin{array}{c} 0 \\ \frac{1}{m} \end{array} \right] \left[ \begin{array}{c} u(t) \end{array} \right]
\end{equation}

If there is no $u(t)$, i.e. $u(t) = 0 \; \forall t$, then we have $\pmb{\dot{x}} = \pmb{Ax}$. The solution to this system of equation is $\pmb{x}(t) = e^{\pmb{A}t} \pmb{x}_0$.


```python

```

3004917c36d3d9173a492457c866edeaecbf9a5d
ipynb
Jupyter Notebook
tutorials/robotics/mass-spring-damper.ipynb
Pandinosaurus/pyrobolearn
9cd7c060723fda7d2779fa255ac998c2c82b8436
Apache-2.0
2021-01-21T21:08:30.000Z
2022-03-29T16:45:49.000Z
tutorials/robotics/mass-spring-damper.ipynb
Pandinosaurus/pyrobolearn
9cd7c060723fda7d2779fa255ac998c2c82b8436
Apache-2.0
tutorials/robotics/mass-spring-damper.ipynb
Pandinosaurus/pyrobolearn
9cd7c060723fda7d2779fa255ac998c2c82b8436
Apache-2.0
2020-09-29T21:25:39.000Z
2020-09-29T21:25:39.000Z
Qwen/Qwen-72B
1. YES
2. YES