<jupyter_start><jupyter_text>Suspensión activa Configuración físicaEl diseño de un sistema de suspensión automotriz es un problema de control interesante y desafiante. Cuando se diseña el sistema de suspensión, se usa un modelo de 1/4 (una de las cuatro ruedas) para simplificar el problema a un sistema de resorte-amortiguador múltiple 1-D. A continuación se muestra un diagrama de este sistema. ```{figure} .\susp1.png:width: 400px:align: center:name: suspSuspensión activa```Este modelo es para un sistema de suspensión activa donde se incluye un actuador que puede generar la fuerza de control $U$ para controlar el movimiento de la carrocería del autobús. Parámetros del sistema(M1) 1/4 masa del cuerpo del autobús 2500 kg(M2) masa de suspensión 320 kg(K1) constante de resorte del sistema de suspensión 80,000 N/m(K2) constante de resorte de rueda y neumático 500,000 N/m(b1) constante de amortiguamiento del sistema de suspensión 350 N.s/m(b2) constante de amortiguamiento de rueda y neumático 15,020 N.s/m(U) fuerza de control  Ecuaciones de movimientoDe la imagen de arriba y la ley de Newton, podemos obtener las ecuaciones dinámicas de la siguiente manera:$$ M_1 \ddot{x}_1 = - b_1 (\dot{x}_1 - \dot{x}_2) - K_1 (x_1 - x_2) + u \ $$$$ M_2 \ddot{x}_2 = b_1 (\dot{x}_1 - \dot{x}_2) + K_1 (x_1 - x_2) + b_2 (\dot{w} - \dot{x} _2) + K_2 (w - x_2) - u$$ En la siguiente celda importo las útilidades de Python que estaremos utilizando<jupyter_code>import control as ctrl
import numpy as np
import matplotlib.pyplot as plt<jupyter_output><empty_output><jupyter_text>Ahora defino los parámetros y las funciones que gobiernan la dinámica del sistema (no es necesario entender la implementación)<jupyter_code>params = {'M1': 2500, 'M2': 320, 'K1': 80000, 'K2': 500000, 'b1': 350, 'b2': 15020}

def derivs_susp(t, x, u, params):
    "Las ecuaciones de las derivadadas de las variables de estados"
    f, w = u
    x1, x2, y1, y2 = x  

    m1 = params.get('M1', 2500)
    m2 = params.get('M2', 320)
    k1 = params.get('K1', 80000)
    k2 = params.get('K2', 500000)
    b1 = params.get('b1', 350)
    b2 = params.get('b2', 15020)

    dx1 = x2
    dx2 = -(b1*b2)/(m1*m2)*x1 + (((b1/m1)*((b1/m1)+(b1/m2)+(b2/m2)))-(k1/m1))*y1 - (b1/m1)*y2 + 1/m1*f + (b1*b2)/(m1*m2)*w
    dy1 = b2/m2*x1 - ((b1/m1)+(b1/m2)+(b2/m2))*y1 + y2  - (b2/m2)*w
    dy2 = k2/m2*x1 - ((k1/m1)+(k1/m2)+(k2/m2))*y1 + ((1/m1)+(1/m2))*f - (k2/m2)*w
    return dx1, dx2, dy1, dy2

def outputs_susp(t, x, u, params):
    "Las salidas del sistema"
    return [x[3]]<jupyter_output><empty_output><jupyter_text>La variable medida en este sistema es$$y=x_1-x_2$$En la siguiente linea se crea un modelo del sistema de la suspensión. Las variables de entrada son la varaible $u$ y al varable $w$.<jupyter_code>susp_sys = ctrl.NonlinearIOSystem(updfcn=derivs_susp, 
                                  outfcn=outputs_susp, 
                                  inputs=['u','w'], 
                                  outputs=['y1'], 
                                  states=['x1', 'dx1', 'y1', 'dy1'], 
                                  name='susp')<jupyter_output><empty_output><jupyter_text>Ahora vamos a definir el vector de entradas $U$, contiene las entradas $u$ y $w$ para cada instante definido en un vector $T$.<jupyter_code>T=np.linspace(0,5,501)

def Usignal(T):
    U = np.zeros((2, len(T)))
    for i, t in enumerate(T):
        U[1,i] = 0.1 if t >= 0.2 and t < 2.5 else  0 # u vale 0.1 entre 0.2<t<2.5, sino 0    
    return U

U=Usignal(T)<jupyter_output><empty_output><jupyter_text>Grafico las señales $u$ y $w$<jupyter_code>fig, ax = plt.subplots(figsize=(12,5))
ax.plot(T, U[0,:], label=r'$u$')
ax.plot(T, U[1,:], label=r'$w$')
ax.set_xlabel('Tiempo [s]')
ax.set_ylabel('Amplitud señal (u en Newton, w en metros')
ax.legend();<jupyter_output><empty_output><jupyter_text>Ahora simularemos la respuesta al sistema a esas dos entradas.<jupyter_code>x0 = (0, 0, 0, 0)
t, y = ctrl.input_output_response(susp_sys, T, U, x0)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13869521912350596, 'fraction_numerical': 0.05926294820717132, 'mean_word_length': 3.617241379310345, 'pattern_counts': {'":': 0, '<': 28, '<?xml version=': 0, '>': 26, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 5, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '189326', 'license': 'MIT', 'n_tokens_mistral': 1761, 'n_tokens_neox': 1629, 'n_words': 456, 'path': 'problemas/susp_activa.ipynb', 'repo_name': 'gonmolina/maerial_ceaten', 'size': '4016'}