lunes, 26 de junio de 2017

Dc motor pid velicity control

Components:


Arduino uno
Wires
9vdc adapter
Simulink

We are going to design a model-based pid controller. First, we need a mathematical model of our plant (dc motor). Second, based in our plant's model, we are going to design a pid to control the motor shaft velocity.

How to obtain the plant's model?

The relationship between the output and the input of a motor is described by a transfer function.
A first order transfer function describes the dynamics of our motor, where the input is voltage or a pwm signal, and the output is a rpm signal. Due to the lack of knowing the coefficients of the first order ode of the motor, we have to estimate the coeficcients or parameters.

Parameters estimation:
In simulink, we build the next model. This has to be deployed to the Arduino. Important: for all the experiments Ts=0.05 (sample time).

Model 1. Parameter estimation embedded.

Connect the hardware as follow:


In the L298n fritzing's part, an enable pin is missing which is connected to pin 7 in the Arduino.

Once the model 1 is embedded in the Arduino, we build the host model 2 in Simulink, where the variables: velocity, position and pwm are going to be shown, saved and processed for further analysis.

Model 2. Parameters estimation host.
Where does the rpm conversion comes from?

Rpm = [pulses / second] / [1496 pulses / revolution] * [60 seconds / 1 minute]

Explanation

Rpm = [lecture from the encoder (pulses/sec)] / [11 pulses * 34 gear ratio * 4 quadrature encoder] * [60 seconds / min]

After running the model, the variables: velocity, position and pwm are in the Matlab's workspace into one variable x. Therefore, we need to extract each variable as following:

clc
clear ans, clear pos, clear vel, clear pwm; clear i;
senal=x.signals.values;
t=x.time;
for i=1:1:length(senal)
senal(:,:,i);
vel(i)=ans(1);
pos(i)=ans(2);
pwm(i)=ans(3);
end
pos=double(pos');
vel=double(vel');
pwm=double(pwm');
clear ans, clear i, clear senal;

Workspace
Now we have the input pwm and output velocity which describe the motor's dynamics.

In order to find the parameters, we have to use ident application.

To be continued...

jueves, 4 de mayo de 2017

Identificación de los parámetros de un sistema de primer orden

En esta serie de dos artículos, siendo la identificación de los parámetros del sistema el primer artículo, pretendo diseñar un controlar PID para un sistema de primer orden.

Hay varias maneras de diseñar un controlador PID: prueba y error, Ziegler-Nichols o el diseño basado en un modelo matemático. En muchos libros de control, te presentan las funciones de transferencias y no explican donde las obtuvieron; por lo que en la práctica, se dificulta aplicar la teoría de control basada en un modelo matemático, debido a que no sabemos como obtener la función de transferencia.

Nuestro sistema de primer orden consistirá en un circuito RC, como el que te presentó en la siguiente figura1.
Figura1. Montaje de circuito.
Para el circuito RC utilizaremos un capacitor de 100 uF y un resitor de 10 kOhm.

La función de transferencia de un sistema de primer orden es la siguiente:

Figura2. Función de transferencia RC.
En donde RC es la constante de tiempo (tau), que es el tiempo en el cual la salida del sistema alcanza el 63%, debido a una entrada escalón. Si sustituimos los valores del capacitor y resistor, la función de transferencia queda de la siguiente manera:
Figura3. Función de transferencia RC=1.
Si a nuestro sistema lo excitamos con una señal de tipo escalón, en cuatro tau alcanzará aproximadamente el 98% de su voltaje final. Para profundizar en la teoría de sistemas de primer orden, les comparto este video. Para análisis de circuitos RC les comparto este link de Khan Academy, donde tienen una serie de videos explicando este tema en el dominio del tiempo. En el dominio de Laplace les comparto este video de katkimshow quien explica de manera excelente.

La salida de nuestro circuito debido a una entrada escalón unitario es la siguiente:
Figura4. Simulación de respuesta al escalón unitario.

Se puede observar que en cuatro tau, 4 segundos, alcanza aproximadamente el 98% del valor final de la salida del sistema.

¿Qué pasa si no conocieramos los parámetros del sistema, en este caso la resistencia y la capacitancia del circuito?

Para este experimento utilizo Simulink, Matlab y Arduino. Para la identificación de las características del sistema creé un modelo en Simulink para la pc y uno para cargarlo en el Arduino Uno, de manera que todo el programa corra embebido en el Arduino y la pc solo tenga la función de visualizar datos, guardarlos, para su posterior análisis, etc.

El modelo que cargaré en el Arduino es el siguiente:
Figura5. Arduino embebido.

Y el que correré en la pc es el siguiente:
Figura6. Host PC.
Ya cargado el programa en el Arduino, procedo a correr el programa host en la pc, obteniendo la siguiente gráfica.
Figura7. Scope Host Pc.

Básicamente, el experimento consiste en aplicar un voltaje de entrada de 5 volts al circuito RC  en t = 10 segundos. Los pines pwm de Arduino son capaces de brindar 5 voltios cuando se le configura a 255 equivalente a un duty cycle del 100 %, debido a que este pwm es de 8 bits.
Los datos entrada-salida se muestran en la figura7, estos datos son guardados en la variable x, que es un arreglo de vectores que se deben extraer para su posterior análisis.

El m file para extraer los valores Vin, Vout y t, de x es el siguiente:

clc
clear ans, clear Vin, clear Vout clear i;
senal=x.signals.values;
t=x.time;
for i=1:1:length(senal)
senal(:,:,i);
Vin(i)=ans(1);
Vout(i)=ans(2);
end
Vin=double(Vin');
Vout=double(Vout');
clear ans, clear i, clear senal;

Teniendo el voltaje de entrada Vin, el voltaje de salidos Vout, que es el voltaje del capacitor y el tiempo t, en el workspace de Matlab, procedemos a la identificación de los parámetros de sistema con la aplicación System Identification corriendo el comando >> ident en el prompt.


Damos click en Time domain data, se abre la siguiente ventana la cual configuramos de esta manera:

Damos en click en Time plot y podemos visualizar los datos obtenidos en el experimento.


Debido a que el rango de interes de 10 segundos en adelante, realizo un pre-procesamiento a la señal, tomando un rago de tiempo de 9.9 seg < t < 17 seg. 

Se abre la siguiente ventana donde configuramos el rango de tiempo de nuestro interés en Time span, damos click en insert y los cambios se guardarán en la variable mydatae.


Mydatae se utilizará en Working data, para la obtención de la función de transferencia. Damos click en estimate, posterior en Transfer Function.

Se abre la siguiente ventana, en donde configuramos la cantidad de polos, en nuestro caso solo es un polo debido a que el sistema es de primer orden, y ningún cero. Permanece seleccionado Continous-time y damos click en estimate.


La función de tranferencia tf1 pasa a la ventana principal. Aquí ya podemos validar tf1 dándole click en model output.
Se abre la siguiente ventana, donde validamos que tf1 corresponde en un 99.52% de los datos obtenidos en nuestro experimento.
Tf1 lo llevamos al workspace. Lo podemos visualizar escribiendo el siguiente comando en el prompt.
>> tf1

tf1 =

  From input "u1" to output "y1":
    0.9332
  ----------
  s + 0.9364

Tf1 aún no está en la forma que lo presenté en la figura2. Por lo que dividimos cada uno de los términos de tf1 con 0.9364, como se muestra a continuación:

>> tf2=tf(tf1.num/tf1.den(2),tf1.den/tf1.den(2))

tf2 =

    0.9966
  -----------
  1.068 s + 1

Continuous-time transfer function.

Como podemos ver, la función de transferencia obtenida experimental es casi idéntica a la teórica.

Bueno, todo esto que les comparto no  lo hago por motivos de lucro, considero que el conocimiento no debe estar encerrado para un cierto grupo, sino que debe estar para todo aquel que lo busca, todo para bien. Cualquier comentario o duda estoy a la orden. Saludos, hasta la próxima.