Una vez obtenida la dinámica del manipulador, tenemos la necesidad de construir una función f
para poder simular el comportamiento del manipulador, empecemos escribiendo la ecuación:
en donde $\mu_1 = m_2 l_2^2$ y $\mu_2 = m_2 l_1 l_2$; por lo que de aqui en adelante, podemos caracterizar la dinámica de este manipulador como la siguiente ecuación:
$$ \tau = M(q)\ddot{q} + C(q, \dot{q}) + G(q) $$Si ahora cambiamos nuestra atención al problema de contruir la función
$$ \dot{x} = f(x, t) $$tenemos que empezar por que representa el estado $x$.
En el ejercicio pasado nuestro manipulador tenía un solo grado de libertad, por lo que el estado terminaba siendo:
$$ x = \begin{pmatrix} q_1 \\ \dot{q}_1 \end{pmatrix} $$En este caso, nuestro manipulador tiene dos grados de libertad, por lo que necesitamos que el estado incluya a la posición de ambos grados de libertad, así como su velocidad:
$$ x = \begin{pmatrix} q_1 \\ q_2 \\ \dot{q}_1 \\ \dot{q}_2 \end{pmatrix} $$Por lo que para construir $f(x,t)$, necesitamos calcular los siguientes terminos:
$$ \dot{x} = \begin{pmatrix} \dot{q}_1 \\ \dot{q}_2 \\ \ddot{q}_1 \\ \ddot{q}_2 \end{pmatrix} $$en donde los primeros dos terminos son triviales, ya que son los mismos que obtenemos del estado del sistema ($\dot{q}_1$, $\dot{q}_2$), y los segundos dos terminos los podemos obtener de la ecuación de movimiento del manipulador:
$$ \ddot{q} = M^{-1}\left( \tau - C(q, \dot{q})\dot{q} - G(q) \right) $$
In [ ]:
def f(t, x):
# Se importan funciones matematicas necesarias
from numpy import matrix, sin, cos
# Se desenvuelven las variables que componen al estado
q1, q2, q̇1, q̇2 = x
# Se definen constantes del sistema
g = 9.81
m1, m2, J1, J2 = 0.3, 0.2, 0.0005, 0.0002
l1, l2 = 0.4, 0.3
τ1, τ2 = 0, 0
# Se agrupan terminos en vectores
q̇ = matrix([[q̇1], [q̇2]])
τ = matrix([[τ1], [τ2]])
# Se calculan terminos comúnes
μ1 = m2*l2**2
μ2 = m2*l1*l2
c1 = cos(q1)
c2 = cos(q2)
s2 = sin(q2)
c12 = cos(q1 + q2)
# Se calculan las matrices de la ecuación de movimiento
# ESCRIBE TU CODIGO AQUI
raise NotImplementedError
# Se calculan las variables a devolver por el sistema
# ESCRIBE TU CODIGO AQUI
raise NotImplementedError
q1pp = qpp.item(0)
q2pp = qpp.item(1)
# Se devuelve la derivada de las variables de entrada
return [q1p, q2p, q1pp, q2pp]
In [ ]:
from numpy.testing import assert_almost_equal
assert_almost_equal(f(0, [0, 0, 0, 0]), [0,0,-1392.38, 3196.16], 2)
assert_almost_equal(f(0, [1, 1, 0, 0]), [0,0,-53.07, 104.34], 2)
print("Sin errores")
Mandamos llamar al simulador
In [ ]:
from robots.simuladores import simulador
In [ ]:
%matplotlib widget
ts, xs = simulador(puerto_zmq="5551", f=f, x0=[0, 0, 0, 0], dt=0.02)
El argumento
puerto_zmq
se refiere al puerto por el cual esta mandando datos, para el visualizador descrito a continuación.
Estos datos se estan actualizando en tiempo real, y si bien es posible ver el comportamiento general con esta gráfica, tambien es posible ver una visualización en tiempo real de este manipulador, para lo cual es necesario mantener este documento abierto, mientras se abre el documento visualizacion.ipynb
.