from sympy import init_printing
init_printing()
from sympy import *
In diesem Notebook wollen wir die Bewegungsgleichung des Systems Wagen mit mathematischem Pendel herleiten. Für die symbolische Mathematik steht Python-Bibliothek sympy
zur Verfügung.
Der hier gezeigte Code entspricht dem Vorgehen des letzten Blogeintrags.
Code - Start
Hilfsfunktionen
# vector 2 spintensor
def vec2spin(v):
= Matrix([[0,-v[2],v[1]],[v[2],0,-v[0]],[-v[1],v[0],0]])
S return S
# spintensor 2 vector
def spin2vec(S):
= Matrix([S[2,1],S[0,2],S[1,0]])
s return s
Parameter
# parameters
= symbols('g', positive=True)
g = symbols('m1 s1 d1', positive=True)
m1, s1, d1 = symbols('m2 s2 d2', positive=True)
m2, s2, d2
print(g.is_positive)
True
Kräfte und Momente
# Forces and Moments
= symbols('F1') F1
= Matrix([F1]) u_vec
Koordinaten
# coordinates
= symbols('q_1, qdot_1 qddot_1')
q1, q1d, q1dd = symbols('q_2, qdot_2 qddot_2')
q2, q2d, q2dd
display(q1, q1d, q1dd) display(q2, q2d, q2dd)
\(\displaystyle q_{1}\)
\(\displaystyle \dot{q}_{1}\)
\(\displaystyle \ddot{q}_{1}\)
\(\displaystyle q_{2}\)
\(\displaystyle \dot{q}_{2}\)
\(\displaystyle \ddot{q}_{2}\)
# states
= symbols('x1 x2 x3 x4') x1, x2, x3, x4
# coordinates subs lists
= [(q1, x1), (q2, x2), (q1d, x3), (q2d, x4)]
list_q2x = [(x1, q1), (x2, q2), (x3, q1d), (x4, q2d)] list_x2q
= Matrix([[q1],[q2]])
q_vec q_vec
\(\displaystyle \left[\begin{matrix}q_{1}\\q_{2}\end{matrix}\right]\)
= Matrix([[q1d],[q2d]])
qd_vec qd_vec
\(\displaystyle \left[\begin{matrix}\dot{q}_{1}\\\dot{q}_{2}\end{matrix}\right]\)
= Matrix([[q1dd],[q2dd]])
qdd_vec qdd_vec
\(\displaystyle \left[\begin{matrix}\ddot{q}_{1}\\\ddot{q}_{2}\end{matrix}\right]\)
= Matrix([[x1],[x2],[x3],[x4]])
x_vec x_vec
\(\displaystyle \left[\begin{matrix}x_{1}\\x_{2}\\x_{3}\\x_{4}\end{matrix}\right]\)
= Matrix([[x1],[x2],[x3],[x4]])
x_vec x_vec
\(\displaystyle \left[\begin{matrix}x_{1}\\x_{2}\\x_{3}\\x_{4}\end{matrix}\right]\)
= Matrix([[q_vec],[qd_vec]])
q_and_qd q_and_qd
\(\displaystyle \left[\begin{matrix}q_{1}\\q_{2}\\\dot{q}_{1}\\\dot{q}_{2}\end{matrix}\right]\)
q_and_qd.subs(list_q2x)
\(\displaystyle \left[\begin{matrix}x_{1}\\x_{2}\\x_{3}\\x_{4}\end{matrix}\right]\)
Lagrange II - Terme
Transformationsmatrizen
= eye(3)
A_1I A_1I
\(\displaystyle \left[\begin{matrix}1 & 0 & 0\\0 & 1 & 0\\0 & 0 & 1\end{matrix}\right]\)
= A_1I.T
A_I1 A_I1
\(\displaystyle \left[\begin{matrix}1 & 0 & 0\\0 & 1 & 0\\0 & 0 & 1\end{matrix}\right]\)
= Matrix([
A_21 0],
[cos(q2), sin(q2), -sin(q2), cos(q2), 0],
[0, 0, 1]])
[ A_21
\(\displaystyle \left[\begin{matrix}\cos{\left(q_{2} \right)} & \sin{\left(q_{2} \right)} & 0\\- \sin{\left(q_{2} \right)} & \cos{\left(q_{2} \right)} & 0\\0 & 0 & 1\end{matrix}\right]\)
= A_21.T
A_12 A_12
\(\displaystyle \left[\begin{matrix}\cos{\left(q_{2} \right)} & - \sin{\left(q_{2} \right)} & 0\\\sin{\left(q_{2} \right)} & \cos{\left(q_{2} \right)} & 0\\0 & 0 & 1\end{matrix}\right]\)
= simplify(A_21@A_1I)
A_2I A_2I
\(\displaystyle \left[\begin{matrix}\cos{\left(q_{2} \right)} & \sin{\left(q_{2} \right)} & 0\\- \sin{\left(q_{2} \right)} & \cos{\left(q_{2} \right)} & 0\\0 & 0 & 1\end{matrix}\right]\)
= A_2I.T
A_I2 A_I2
\(\displaystyle \left[\begin{matrix}\cos{\left(q_{2} \right)} & - \sin{\left(q_{2} \right)} & 0\\\sin{\left(q_{2} \right)} & \cos{\left(q_{2} \right)} & 0\\0 & 0 & 1\end{matrix}\right]\)
Position und Geschwindigkeitsvektoren¶
Körper 1:
= Matrix([[q1],[0],[0]])
rs1_1 rs1_1
\(\displaystyle \left[\begin{matrix}q_{1}\\0\\0\end{matrix}\right]\)
= rs1_1.jacobian(q_vec)@qd_vec
vs1_1 vs1_1
\(\displaystyle \left[\begin{matrix}\dot{q}_{1}\\0\\0\end{matrix}\right]\)
Korper 2:
= Matrix([[0],[0],[q2]])
phi_I2_2 phi_I2_2
\(\displaystyle \left[\begin{matrix}0\\0\\q_{2}\end{matrix}\right]\)
= phi_I2_2.jacobian(q_vec)@qd_vec
w_I2_2 = vec2spin(w_I2_2)
wspin_I2_2 wspin_I2_2
\(\displaystyle \left[\begin{matrix}0 & - \dot{q}_{2} & 0\\\dot{q}_{2} & 0 & 0\\0 & 0 & 0\end{matrix}\right]\)
= w_I2_2
ws2_2 ws2_2
\(\displaystyle \left[\begin{matrix}0\\0\\\dot{q}_{2}\end{matrix}\right]\)
# relative coordinates
= Matrix([[0],[-s2],[0]])+A_21 @ rs1_1
rs2_2 rs2_2
\(\displaystyle \left[\begin{matrix}q_{1} \cos{\left(q_{2} \right)}\\- q_{1} \sin{\left(q_{2} \right)} - s_{2}\\0\end{matrix}\right]\)
= simplify(rs2_2.jacobian(q_vec)@qd_vec+wspin_I2_2@rs2_2)
vs2_2 vs2_2
\(\displaystyle \left[\begin{matrix}\dot{q}_{1} \cos{\left(q_{2} \right)} + \dot{q}_{2} s_{2}\\- \dot{q}_{1} \sin{\left(q_{2} \right)}\\0\end{matrix}\right]\)
Energie Terme
= diag(m1,m1,m1)
M1_diag = diag(m2,m2,m2)
M2_diag M2_diag
\(\displaystyle \left[\begin{matrix}m_{2} & 0 & 0\\0 & m_{2} & 0\\0 & 0 & m_{2}\end{matrix}\right]\)
= nsimplify(simplify(1/2*vs1_1.T@M1_diag@vs1_1 + 1/2*vs2_2.T@M2_diag@vs2_2))
T T
\(\displaystyle \left[\begin{matrix}\frac{m_{1} \dot{q}_{1}^{2}}{2} + \frac{m_{2} \dot{q}_{1}^{2}}{2} + m_{2} \dot{q}_{1} \dot{q}_{2} s_{2} \cos{\left(q_{2} \right)} + \frac{m_{2} \dot{q}_{2}^{2} s_{2}^{2}}{2}\end{matrix}\right]\)
= Matrix([[0],[-g],[0]])
g_vec_I @g_vec_I A_2I
\(\displaystyle \left[\begin{matrix}- g \sin{\left(q_{2} \right)}\\- g \cos{\left(q_{2} \right)}\\0\end{matrix}\right]\)
= simplify(- m2 * (A_2I@g_vec_I).T@rs2_2)
Vg2 Vg2
\(\displaystyle \left[\begin{matrix}- g m_{2} s_{2} \cos{\left(q_{2} \right)}\end{matrix}\right]\)
= Vg2
V V
\(\displaystyle \left[\begin{matrix}- g m_{2} s_{2} \cos{\left(q_{2} \right)}\end{matrix}\right]\)
= nsimplify(Matrix([1/2*d1*q1d**2 + 1/2*d2*q2d**2]))
R R
\(\displaystyle \left[\begin{matrix}\frac{d_{1} \dot{q}_{1}^{2}}{2} + \frac{d_{2} \dot{q}_{2}^{2}}{2}\end{matrix}\right]\)
Generalisierte Kräfte
= Matrix([[F1],[0],[0]])
F1_1 F1_1
\(\displaystyle \left[\begin{matrix}F_{1}\\0\\0\end{matrix}\right]\)
= vs1_1.jacobian(qd_vec).T@F1_1
Qq Qq
\(\displaystyle \left[\begin{matrix}F_{1}\\0\end{matrix}\right]\)
Bewegungsgleichung - Ableitungen
\[ \frac{d}{dt} \left( \frac{\partial T}{\partial \dot{\mathbf{q}}} \right)^T - \left( \frac{\partial T}{\partial \mathbf{q}} \right)^T + \left( \frac{\partial V}{\partial \mathbf{q}} \right)^T + \left( \frac{\partial R}{\partial \dot{\mathbf{q}}} \right)^T = \mathbf{Q} \]
= nsimplify(T.jacobian(qd_vec).T)
T_qd T_qd
\(\displaystyle \left[\begin{matrix}m_{1} \dot{q}_{1} + m_{2} \dot{q}_{1} + m_{2} \dot{q}_{2} s_{2} \cos{\left(q_{2} \right)}\\m_{2} \dot{q}_{1} s_{2} \cos{\left(q_{2} \right)} + m_{2} \dot{q}_{2} s_{2}^{2}\end{matrix}\right]\)
= simplify(T_qd.jacobian(qd_vec)@qdd_vec + T_qd.jacobian(q_vec)@qd_vec)
T_qd_dt T_qd_dt
\(\displaystyle \left[\begin{matrix}m_{2} \ddot{q}_{2} s_{2} \cos{\left(q_{2} \right)} - m_{2} \dot{q}_{2}^{2} s_{2} \sin{\left(q_{2} \right)} + \ddot{q}_{1} \left(m_{1} + m_{2}\right)\\m_{2} s_{2} \left(\ddot{q}_{1} \cos{\left(q_{2} \right)} + \ddot{q}_{2} s_{2} - \dot{q}_{1} \dot{q}_{2} \sin{\left(q_{2} \right)}\right)\end{matrix}\right]\)
= simplify(T.jacobian(q_vec).T)
T_q T_q
\(\displaystyle \left[\begin{matrix}0\\- m_{2} \dot{q}_{1} \dot{q}_{2} s_{2} \sin{\left(q_{2} \right)}\end{matrix}\right]\)
= nsimplify(R.jacobian(qd_vec).T)
R_qd R_qd
\(\displaystyle \left[\begin{matrix}d_{1} \dot{q}_{1}\\d_{2} \dot{q}_{2}\end{matrix}\right]\)
= simplify(V.jacobian(q_vec).T)
V_q V_q
\(\displaystyle \left[\begin{matrix}0\\g m_{2} s_{2} \sin{\left(q_{2} \right)}\end{matrix}\right]\)
= T_qd_dt - T_q + V_q + R_qd -Qq
EoM_1 EoM_1
\(\displaystyle \left[\begin{matrix}- F_{1} + d_{1} \dot{q}_{1} + m_{2} \ddot{q}_{2} s_{2} \cos{\left(q_{2} \right)} - m_{2} \dot{q}_{2}^{2} s_{2} \sin{\left(q_{2} \right)} + \ddot{q}_{1} \left(m_{1} + m_{2}\right)\\d_{2} \dot{q}_{2} + g m_{2} s_{2} \sin{\left(q_{2} \right)} + m_{2} \dot{q}_{1} \dot{q}_{2} s_{2} \sin{\left(q_{2} \right)} + m_{2} s_{2} \left(\ddot{q}_{1} \cos{\left(q_{2} \right)} + \ddot{q}_{2} s_{2} - \dot{q}_{1} \dot{q}_{2} \sin{\left(q_{2} \right)}\right)\end{matrix}\right]\)
Wir haben hier nun die Bewegungsgleichung. Jedoch ist diese Darstellung für Simulation und Regelung nicht geeignet.
Bewegungsgleichung
Üblicher ist die Darstellung mit Hilfe der Massenmatrix.
\[ \mathbf{M}(\mathbf{q})\ddot{\mathbf{q}} + \mathbf{g}(\mathbf{q},\dot{\mathbf{q}}) = \mathbf{Q}(\mathbf{q}) = \mathbf{B}(\mathbf{q}) \mathbf{u} \]
= T_qd_dt.jacobian(qdd_vec)
Mq Mq
\(\displaystyle \left[\begin{matrix}m_{1} + m_{2} & m_{2} s_{2} \cos{\left(q_{2} \right)}\\m_{2} s_{2} \cos{\left(q_{2} \right)} & m_{2} s_{2}^{2}\end{matrix}\right]\)
= simplify(T_qd_dt-T_q+R_qd+V_q-Mq@qdd_vec)
gqqd gqqd
\(\displaystyle \left[\begin{matrix}d_{1} \dot{q}_{1} - m_{2} \dot{q}_{2}^{2} s_{2} \sin{\left(q_{2} \right)}\\d_{2} \dot{q}_{2} + g m_{2} s_{2} \sin{\left(q_{2} \right)}\end{matrix}\right]\)
Ergebnis
Nun haben wir eine übliche Darstellung der Bewegungsgleichung.
Mq
\(\displaystyle \left[\begin{matrix}m_{1} + m_{2} & m_{2} s_{2} \cos{\left(q_{2} \right)}\\m_{2} s_{2} \cos{\left(q_{2} \right)} & m_{2} s_{2}^{2}\end{matrix}\right]\)
gqqd
\(\displaystyle \left[\begin{matrix}d_{1} \dot{q}_{1} - m_{2} \dot{q}_{2}^{2} s_{2} \sin{\left(q_{2} \right)}\\d_{2} \dot{q}_{2} + g m_{2} s_{2} \sin{\left(q_{2} \right)}\end{matrix}\right]\)
Qq Qq
\(\displaystyle \left[\begin{matrix}F_{1}\\0\end{matrix}\right]\)
Vergleich
Als letztes können wir noch die beiden Gleichungen vergleichen.
\[ \begin{split} & EoM_1 := \frac{d}{dt} \left( \frac{\partial T}{\partial \dot{\mathbf{q}}} \right)^T - \left( \frac{\partial T}{\partial \mathbf{q}} \right)^T + \left( \frac{\partial V}{\partial \mathbf{q}} \right)^T + \left( \frac{\partial R}{\partial \dot{\mathbf{q}}} \right)^T - \mathbf{Q} = \mathbf{0} \\ & EoM_2 := \mathbf{M}(\mathbf{q})\ddot{\mathbf{q}} + \mathbf{g}(\mathbf{q},\dot{\mathbf{q}}) - \mathbf{Q}(\mathbf{q}) = \mathbf{0} \end{split} \]
= Mq@qdd_vec+gqqd-Qq
EoM_2 EoM_2
\(\displaystyle \left[\begin{matrix}- F_{1} + d_{1} \dot{q}_{1} + m_{2} \ddot{q}_{2} s_{2} \cos{\left(q_{2} \right)} - m_{2} \dot{q}_{2}^{2} s_{2} \sin{\left(q_{2} \right)} + \ddot{q}_{1} \left(m_{1} + m_{2}\right)\\d_{2} \dot{q}_{2} + g m_{2} s_{2} \sin{\left(q_{2} \right)} + m_{2} \ddot{q}_{1} s_{2} \cos{\left(q_{2} \right)} + m_{2} \ddot{q}_{2} s_{2}^{2}\end{matrix}\right]\)
-EoM_2) simplify(EoM_1
\(\displaystyle \left[\begin{matrix}0\\0\end{matrix}\right]\)
Substitution (Änderung der Parameternamen)
Für eine bessere Lesbarkeit können wir den Parametern auch nachträglich neue Namen geben. In unserem Fall ersetzen wir die \(1\) mit \(c\) für cart
und die \(2\) mit \(p\) für pole
. Weiters ersetzen wir die Länge \(s_2\) mit \(l\).
= symbols('m_c d_c', positive=True)
mc, dc = symbols('F_c')
Fc = symbols('m_p l d_p', positive=True) mp, l, dp
# number to name
= [(m1, mc), (d1, dc), (F1, Fc), (m2, mp), (d2, dp), (s2,l)] list_num2name
Mq.subs(list_num2name)
\(\displaystyle \left[\begin{matrix}m_{c} + m_{p} & l m_{p} \cos{\left(q_{2} \right)}\\l m_{p} \cos{\left(q_{2} \right)} & l^{2} m_{p}\end{matrix}\right]\)
gqqd.subs(list_num2name)
\(\displaystyle \left[\begin{matrix}d_{c} \dot{q}_{1} - l m_{p} \dot{q}_{2}^{2} \sin{\left(q_{2} \right)}\\d_{p} \dot{q}_{2} + g l m_{p} \sin{\left(q_{2} \right)}\end{matrix}\right]\)
Qq.subs(list_num2name)
\(\displaystyle \left[\begin{matrix}F_{c}\\0\end{matrix}\right]\)
Anmerkungen
Für größere Systeme sollten die Durchnummerierung der Parameter beibehalten werden. Bei mechanischen Systemen mit 4 oder mehr Körper wird sonst die Parameterbezeichnung unübersichtlich.
Fazit
In diesem Notebook haben wir eine Modellbildung mit Hilfe von sympy
durchgeführt. sympy
hat das Ziel ein vollständiges CAS Programm bereit zu stellen.