<jupyter_start><jupyter_text>Práctica 1 - Introducción a Jupyter lab y libreria ```robots```  Introducción a la libreria ```robots``` y sus simuladores Recordando los resultados obtenidos en el documento anterior, tenemos que:$$\tau_1 = \left[ m_1 l_1^2 + J_1 \right] \ddot{q}_1 + g\left[ m_1 l_1 \cos(q_1) \right]$$sin embargo, no tenemos una buena manera de simular el comportamiento de este sistema ya que este sistema es de segundo orden y no lineal; por lo que el primer paso para simular este sistema es convertirlo a un sistema de primer orden.Primero necesitamos definir una variable de estado para el sistema, y ya que queremos convertir un sistema de segundo orden, en uno de primer orden, necesitamos duplicar el numero de variables. > Nota: Si tuvieramos un sistema de tercer orden tendriamos que triplicar el numero de variables para convertirlo en un sistema de primer orden y asi sucesivamente. Si definimos el estado del sistema $x$ como:$$x =\begin{pmatrix} q_1 \\ \dot{q}_1 \end{pmatrix}$$entonces es claro que podemos obtener la derivada del sistema haciendo:$$\dot{x} = \frac{d}{dt} x = \frac{d}{dt}\begin{pmatrix} q_1 \\ \dot{q}_1 \end{pmatrix} = \begin{pmatrix} \dot{q}_1 \\ \ddot{q}_1 \end{pmatrix}$$por lo que podemos utilizar métodos numéricos como el método de Euler, Runge-Kutta, etc. para obtener el comportamiento de estas variables a traves del tiempo, tomando en cuenta que siempre es necesario tener una función $f$ tal que:$$\dot{x} = f(x,t)$$ Nuestra tarea entonces, es construir una función ```f```, tal que, cuando le demos como datos $x = \begin{pmatrix} q_1 \\ \dot{q}_1 \end{pmatrix}$, nos pueda devolver como resultado $\dot{x} = \begin{pmatrix} \dot{q}_1 \\ \ddot{q}_1 \end{pmatrix}$.Para esto necesitamos calcular $\dot{q}_1$ y $\ddot{q}_1$, pero si revisamos la ecuación de movimiento calculada en el documento anterior (```simbolico.ipynb```), podemos ver que $\ddot{q}_1$ es facilmente despejable:$$\ddot{q}_1 = \frac{1}{m_1 l_1^2 + J_1} \left[ \tau_1 - g m_1 l_1 \cos{q}_1 \right]$$ Para calcular $\dot{q}_1$, tan solo tenemos que darnos cuenta que uno de nuestros datos es $\dot{q}_1$, por lo que esta ecuación es trivial:$$\dot{q}_1 = \dot{q}_1$$con lo que ya tenemos todo lo necesario para construir la función ```f```:<jupyter_code>def f(x, t):
    # Se importan funciones matematicas necesarias
    from numpy import cos
    # Se desenvuelven las variables que componen al estado
    q1, q̇1 = x
    # Se definen constantes del sistema
    g = 9.81
    m1, J1 = 0.3, 0.0005
    l1 = 0.2
    τ1 = 0
    
    # Se calculan las variables a devolver por el sistema
    q1p = q̇1
    q1pp = 1/(m1*l1**2 + J1)*(τ1 - g*m1*l1*cos(q1))
    # Se devuelve la derivada de las variables de entrada
    return [q1p, q1pp]<jupyter_output><empty_output><jupyter_text>Una vez que tenemos la función ```f```, tenemos que importar la función ```odeint``` de la librería ```integrate``` de ```scipy```.<jupyter_code>from scipy.integrate import odeint<jupyter_output><empty_output><jupyter_text>Esta función implementará un método numérico para integrar el estado del sistema a traves del tiempo, definiremos tambien un vector con todos los tiempos en los que nos interesa saber el estado del sistema, para esto importamos ```linspace```.<jupyter_code>from numpy import linspace<jupyter_output><empty_output><jupyter_text>Definimos los tiempos como $0s$ hasta $10s$ con mil datos en total, y la condición inicial de nuestro sistema:$$x_0 = \begin{pmatrix} 0 \\ 0 \end{pmatrix} = \begin{pmatrix} q_1 \\ \dot{q}_1 \end{pmatrix}$$<jupyter_code>ts = linspace(0, 10, 1000)
x0 = [0, 0]<jupyter_output><empty_output><jupyter_text>Y con estos datos, mandamos llamar a la función ```odeint```:<jupyter_code>xs = odeint(f, x0, ts)<jupyter_output><empty_output><jupyter_text>Para visualizar estos datos importamos la libreria ```matplotlib``` para graficación:<jupyter_code>from matplotlib.pyplot import plot, legend
%matplotlib widget<jupyter_output><empty_output><jupyter_text>Y graficamos:<jupyter_code>graf_pos, graf_vel = plot(xs)
legend([graf_pos, graf_vel], ["posicion", "velocidad"])<jupyter_output><empty_output><jupyter_text>Sin embargo, en esta clase utilizaremos un sistema de simulación a medida, el cual nos quita la responsabilidad del codigo de graficación y nos brindará algunas ventajas en practicas posteriores. A continuación importamos la función ```simulador``` de la librería simuladores del paquete ```robots```:<jupyter_code>from robots.simuladores import simulador<jupyter_output><empty_output><jupyter_text>> Nota que dentro de la carpeta de esta práctica existe una carpeta llamada robots, esta carpeta contiene todo el código que hace funcionar las siguientes funciones, si deseas averiguar como funciona, puedes abrir esos archivos y estudiarlos. Definimos de nuevo la función ```f``` con la única diferencia del orden de las entradas:<jupyter_code>def f(t, x):
    # Se importan funciones matematicas necesarias
    from numpy import cos
    # Se desenvuelven las variables que componen al estado
    q1, q̇1 = x
    # Se definen constantes del sistema
    g = 9.81
    m1, J1 = 0.3, 0.0005
    l1 = 0.4
    τ1 = 0
    
    # Se calculan las variables a devolver por el sistema
    q1p = q̇1
    q1pp = 1/(m1*l1**2 + J1)*(τ1 - g*m1*l1*cos(q1))
    # Se devuelve la derivada de las variables de entrada
    return [q1p, q1pp]<jupyter_output><empty_output><jupyter_text>Mandamos llamar al simulador<jupyter_code>%matplotlib widget
ts, xs = simulador(puerto_zmq="5551", f=f, x0=[0,0], dt=0.02)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10646319569120287, 'fraction_numerical': 0.0236983842010772, 'mean_word_length': 4.926595744680851, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '221285', 'license': 'MIT', 'n_tokens_mistral': 2023, 'n_tokens_neox': 1956, 'n_words': 670, 'path': 'Practicas/practica1/numerico.ipynb', 'repo_name': 'robblack007/clase-dinamica-robot', 'size': '5570'}