import sympy
import numpy as np
It can be difficult to build constraints for general dynamic solutions. Each constraint is realtively straight forward, but keeping track of Jacobian terms or acceleration constraints
can be cumbersome and confusing. In this notebook, you will use SymPy to
lambdify
the constraints, Jacobian, and $\mathbf{Q}_d$First, define the variables using sympy.Matrix
. SymPy uses var
to define variables, here you create
$q = \left[\begin{matrix}q_{1}\\q_{2}\\q_{3}\\q_{4}\\q_{5}\\q_{6}\end{matrix}\right],~ \dot{q} = \left[\begin{matrix}dq_{1}\\dq_{2}\\dq_{3}\\dq_{4}\\dq_{5}\\dq_{6}\end{matrix}\right],~t,~and~L$
as SymPy variables.
sympy.var('q1, q2, q3, q4, q5, q6')
sympy.var('dq1, dq2, dq3, dq4, dq5, dq6')
sympy.var('t, L2')
q = sympy.Matrix([q1, q2, q3, q4, q5, q6])
dq = sympy.Matrix([dq1, dq2, dq3, dq4, dq5, dq6])
q
$\mathbf{q} = \left[\begin{matrix}q_{1}\\q_{2}\\q_{3}\\q_{4}\\q_{5}\\q_{6}\end{matrix}\right]$
dq
In this example, you have two rigid bodies. Body one $[q_1,~q_2,~q_3]$ slides on the x-axis. Body 1 and body 2, $[q_4,~q_5,~q_6]$ are connected by a pin in the center of body 1, $\mathbf{R}_{pin} = q_1\hat{i}+q_2\hat{j}$.
C = sympy.Matrix([q1 - q4 + L2/2*sympy.cos(q6),
q2 - q5 + L2/2*sympy.sin(q6),
q2,
q3])
C
Next, take the Jacobian, $\mathbf{C_q}$.
Cq = C.jacobian(q)
print('Cq dimensions:', Cq.shape)
Cq
Cq dimensions: (4, 6)
Now, you can calculate
$\mathbf{Q_d} = -(\mathbf{C_q \dot{q}})_\mathbf{q}\mathbf{\dot{q}} - 2\mathbf{C}_{\mathbf{q}t}\dot{\mathbf{q}}- \mathbf{C}_{tt}$
Qd = -(C.jacobian(q)@dq).jacobian(q)@dq\
- 2*sympy.diff(Cq,t)@dq\
- sympy.diff(C, t, 2)
Qd
lambdify
the constraints, Jacobian, and $\mathbf{Q}_d$¶Finally, you can create functions that return NumPy arrays with sympy.lambdify
. The inputs are
sympy.lambdify( inputs, function, "numpy" )
where the inputs
are $\mathbf{q}$, $\dot{\mathbf{q}}$, and other parameters like time or dimensions, $L^2$.
Cq_sys = sympy.lambdify((q, t, L2), Cq, 'numpy')
Cq_sys(np.zeros(6), 1, L2 = 1)
array([[ 1. , 0. , 0. , -1. , 0. , -0. ], [ 0. , 1. , 0. , 0. , -1. , 0.5], [ 0. , 1. , 0. , 0. , 0. , 0. ], [ 0. , 0. , 1. , 0. , 0. , 0. ]])
Q = sympy.lambdify((q, dq, t, L2), Qd, "numpy")
Q(np.ones(6), np.ones(6), 0, L2 = 1)
array([[0.27015115], [0.42073549], [0. ], [0. ]])