Académique Documents
Professionnel Documents
Culture Documents
SISTEMAS DE CONTROL
MARZO 2015
Tabla de contenido
TEMA ............................................................................................................................................. 2
Objetivos ....................................................................................................................................... 2
General .................................................................................................................................. 2
Específicos ............................................................................................................................. 2
Resumen ....................................................................................................................................... 2
Abstract ......................................................................................................................................... 3
Marco Teórico ............................................................................................................................... 3
El Sensor Óptico reflexivo con salida a Transistor CNY 70 ........................................ 3
Arduino Mega........................................................................................................................ 3
Control PID ............................................................................................................................ 4
Funcionamiento .................................................................................................................... 8
Conclusiones ......................................................................................................................... 9
Recomendaciones ................................................................................................................. 9
Bibliografía ............................................................................................................................ 9
Anexos ................................................................................................................................. 10
2.2. Específicos:
Diseñar un seguidor de Línea.
Realizar la respectiva programación en Arduino.
Visualizar la respuesta del sistema en un ordenador.
Probar el prototipo agregando perturbaciones.
Analizar los resultados en base a los conocimientos recibidos.
3. Resumen
2
4. Abstract
This work presents the design, construction and programming Arduino a line follower
which has 6 digital sensors, in order to implement a PID control as it is paramount that
the follower can correct errors and return to the line if a disturbance. To verify these
characteristics of PID control, use the Processing program which connects with
Arduino and displays the steady state response of our tracker, making a friendly and
interactive learning environment.
5. Marco teórico
- Características.
La construcción compacta con distancia de del centro-a-centro de 0.1 ' (pulgadas)
No necesita ningún ambiente especial
Señal de salida alta
El coeficiente de temperatura bajo
Detector provista de filtro óptico
El ratio de corriente de transferencia (CTR) típico es del 5%
3
5.3. Control PID
4
el error de seguimiento se reduce a cero. El Derivativo determina la reacción del
tiempo en el que el error se produce. La suma de estas tres acciones es usada para
ajustar al proceso vía un elemento de control como la posición de una válvula de
control o la energía suministrada a un calentador, por ejemplo. Ajustando estas tres
variables en el algoritmo de control del PID, el controlador puede proveer un control
diseñado para lo que requiera el proceso a realizar. La respuesta del controlador
puede ser descrita en términos de respuesta del control ante un error, el grado el cual
el controlador llega al "set point", y el grado de oscilación del sistema. Nótese que el
uso del PID para control no garantiza control óptimo del sistema o la estabilidad del
mismo. Algunas aplicaciones pueden solo requerir de uno o dos modos de los que
provee este sistema de control. Un controlador PID puede ser llamado también PI, PD,
P o I en la ausencia de las acciones de control respectivas.
- Proporcional
5
El error, la banda proporcional y la posición inicial del elemento final de control se
expresan en tanto por uno. Nos indicará la posición que pasará a ocupar el elemento
final de control
Ejemplo: Cambiar la posición de una válvula (elemento final de control)
proporcionalmente a la desviación de la temperatura (variable) respecto al punto de
consigna
- Integral
El modo de control Integral tiene como propósito disminuir y eliminar el error en estado
estacionario, provocado por el modo proporcional. El control integral actúa cuando hay
una desviación entre la variable y el punto de consigna, integrando esta desviación en
el tiempo y sumándola a la acción proporcional. El error es integrado, lo cual tiene la
función de promediarlo o sumarlo por un período determinado; Luego es multiplicado
por una constante Ki. Posteriormente, la respuesta integral es adicionada al modo
Proporcional para formar el control P + I con el propósito de obtener una respuesta
estable del sistema sin error estacionario.
El modo integral presenta un desfasamiento en la respuesta de 90º que sumados a los
180º de la retroalimentación ( negativa ) acercan al proceso a tener un retraso de 270º,
luego entonces solo será necesario que el tiempo muerto contribuya con 90º de
retardo para provocar la oscilación del proceso. <<< la ganancia total del lazo de
control debe ser menor a 1, y así inducir una atenuación en la salida del controlador
para conducir el proceso a estabilidad del mismo. >>> Se caracteriza por el tiempo de
acción integral en minutos por repetición. Es el tiempo en que delante una señal en
escalón, el elemento final de control repite el mismo movimiento correspondiente a la
acción proporcional.
El control integral se utiliza para obviar el inconveniente del offset (desviación
permanente de la variable con respecto al punto de consigna) de la banda
proporcional.
6
- Derivativo
La acción derivativa se manifiesta cuando hay un cambio en el valor absoluto del error;
(si el error es constante, solamente actúan los modos proporcional e
integral).El error es la desviación existente entre el punto de medida y el valor
consigna, o "Set Point".La función de la acción derivativa es mantener el error al
mínimo corrigiéndolo proporcionalmente con la misma velocidad que se produce; de
esta manera evita que el error se incremente.
Se deriva con respecto al tiempo y se multiplica por una constante D y luego se suma
a las señales anteriores (P+I). Es importante adaptar la respuesta de control a los
cambios en el sistema ya que una mayor derivativa corresponde a un cambio más
rápido y el controlador puede responder acordemente.
7
- Significado de las constantes
6. Funcionamiento
1. Los 6 sensores CNY 70 sensan continuamente la línea negra y envían una trama
de 0 y 1 dependiendo la refractibilidad de cada uno y su posición.
2. Arduino uno compara cada uno de las tramas enviadas y conoce la posición a la
que se encuentra el robot seguidor de linea
8
El sensor proporciona una señal digital al controlador, la cual representa el punto
actual en el que se encuentra el proceso o sistema. La señal un valor lógico de 0 o 1.
El controlador lee una señal externa que representa el valor que se desea alcanzar.
Esta señal recibe el nombre de punto de consigna (o punto de referencia), la cual es
de la misma naturaleza y tiene el mismo rango de valores que la señal que
proporciona el sensor.
El controlador resta la señal de punto actual a la señal de punto de consigna,
obteniendo así la señal de error, que determina en cada instante la diferencia que hay
entre el valor deseado (consigna) y el valor medido. La señal de error es utilizada por
cada uno de los 3 componentes del controlador PID. Las 3 señales sumadas,
componen la señal de salida que el controlador va a utilizar para gobernar al actuador.
La señal resultante de la suma de estas tres se llama variable manipulada y no se
aplica directamente sobre el actuador, sino que debe ser transformada para ser
compatible con el actuador utilizado.
Las tres componentes de un controlador PID son: parte Proporcional, acción Integral y
acción Derivativa. El peso de la influencia que cada una de estas partes tiene en la
suma final, viene dado por la constante proporcional, el tiempo integral y el tiempo
derivativo, respectivamente. Se pretenderá lograr que el bucle de control corrija
eficazmente y en el mínimo tiempo posible los efectos de las perturbaciones.
7. Desarrollo
Para la implementación del control PID a un seguidor de línea se utilizó los
siguientes materiales:
Para desarrollar este proyecto primero fue necesario contar con todas las
herramientas de software que permiten lograr una comunicación entre Arduino omega
y el computador, así como lograr procesar la información proveniente de los
componentes físicos.
9
#include <PID_v1.h>
#include <QTRSensors.h>
#include <DRV8835MotorShield.h>
#define NUM_SENSORS 6
#define EMITTER_PIN 2
NUM_SENSORS,TIMEOUT, EMITTER_PIN);
DRV8835MotorShield motors;
int KP = 4;
int KD = 6;
int KI=0.0001;
int lastError=0;
unsigned long serialTime; //this will help us know when to talk with processing
void setup()
10
Serial.begin(9600);
Input = analogRead(inputPin);
Setpoint = 100;
myPID.SetMode(AUTOMATIC);
delay(500);
int i;
pinMode(13, OUTPUT);
for (i = 0; i < 80; i++) // make the calibration take about 10 seconds
motors.setSpeeds(-100, 100);
else
motors.setSpeeds(100, -100);
qtrrc.calibrate();
delay(5);
// reads all sensors 10 times at 2.5 ms per six sensors (i.e. ~25 ms per call)
digitalWrite(13, LOW); // turn off LED to indicate we are through with calibration
motors.setSpeeds(0,0);
11
// print the calibration minimum values measured when emitters were on
Serial.begin(9600);
Serial.print(qtrrc.calibratedMinimumOn[i]);
Serial.print(' ');
Serial.println();
Serial.print(qtrrc.calibratedMaximumOn[i]);
Serial.print(' ');
Serial.println();
Serial.println();
delay(1000);
/////////////////////////////////////////////////////
long integral;
void loop()
//pid-related code
Input = analogRead(inputPin);
myPID.Compute();
analogWrite(outputPin,Output);
12
/////////////////////////////////////////////////////////////////////////////
// print the sensor values as numbers from 0 to 9, where 0 means maximum reflectance
and
unsigned char i;
Serial.print(sensorValues[i] * 10 / 1001);
Serial.print(' ');
Serial.print(" ");
Serial.print(" ");
Serial.print(" ");
lastError = error;
13
int m1Speed = MAX_SPEED + speedDifference;
if (m1Speed < 0)
m1Speed = 0;
if (m2Speed < 0)
m2Speed = 0;
m1Speed = MAX_SPEED;
m2Speed = MAX_SPEED;
motors.setSpeeds(m2Speed, m1Speed);
/////////////////////////////////////////////////////////////////////////////
if(millis()>serialTime)
SerialReceive();
SerialSend();
serialTime+=500;
/********************************************
14
********************************************/
} // easily convert it to a
void SerialReceive()
int index=0;
while(Serial.available()&&index<26)
index++;
15
{
Setpoint=double(foo.asFloat[0]);
} // overwrite.
p = double(foo.asFloat[3]); //
i = double(foo.asFloat[4]); //
d = double(foo.asFloat[5]); //
myPID.SetTunings(p, i, d); //
else myPID.SetMode(AUTOMATIC); //
else myPID.SetControllerDirection(REVERSE); //
void SerialSend()
16
Serial.print("PID ");
Serial.print(Setpoint);
Serial.print(" ");
Serial.print(Input);
Serial.print(" ");
Serial.print(Output);
Serial.print(" ");
Serial.print(myPID.GetKp());
Serial.print(" ");
Serial.print(myPID.GetKi());
Serial.print(" ");
Serial.print(myPID.GetKd());
Serial.print(" ");
if(myPID.GetMode()==AUTOMATIC) Serial.print("Automatic");
else Serial.print("Manual");
Serial.print(" ");
if(myPID.GetDirection()==DIRECT) Serial.println("Direct");
else Serial.println("Reverse");
Inicialmente se establecen todos los valores iniciales de las ganancias para el control PID
con los que se desea trabajar, se puede ir probando con varios valores hasta obtener el
resultado requerido.
Para recibir la entrada analógica, proveniente del sensor, se utiliza el comando
‘analogRead’, aquí se define el pin de entrada analógico por donde ingresa la señal. La
salida que se utiliza en este proyecto es una señal PWM con la cual se controlara los
motores del seguidor de línea. A la salida de esta función se obtiene el parámetro de
control, el cual corresponde a un rango de valores de 0 a 500 que son valores que
monitoreamos con Arduino mediante los sensores.
En el circuito la señal del sensor ingresa a la placa Arduino, y se compara con un setpoint
que puede ser modificado en el programa arduino debido al monitoreo decidimos que
nuestro setpoint iva a ser 500 ya que en 500 el robot iva por la mitad de la línea. A la salida
se obtiene una señal PWM como se mencionó anteriormente.
17
Para encontrar los valores de las ganancias Kp, Ki, Kd se consultaron en tablas ya
realizadas por medio de cálculos para cada situación como se puede ver en la
siguiente tabla.
Entonces para definir estos valores, se puede ver en la tabla que hay fórmulas de
sintonización para controles rápidos, normales y lentos. Esto depende de cada
aplicación aunque no son valores estándar ya que se pueden modificar según los
requerimientos.
Entonces para definir estos valores, se puede ver en la tabla que hay fórmulas de
sintonización para controles rápidos, normales y lentos. Esto depende de cada
aplicación aunque no son valores estándar ya que se pueden modificar según los
requerimientos.
Para observar la gráfica q produce nuestro sistema contamos con el siguiente código
en el software Prosessing que trabajan en conjunto.
import java.nio.ByteBuffer;
import processing.serial.*;
import controlP5.*;
18
/***********************************************
* User spcification section
**********************************************/
int windowWidth = 900; // set the size of the
int windowHeight = 600; // form
int windowSpan = 30000; // number of mS into the past you want to display
int refreshRate = 100; // how often you want the graph to be reDrawn;
/***********************************************
* end user spec
**********************************************/
int nextRefresh;
int arrayLength = windowSpan / refreshRate+1;
int[] InputData = new int[arrayLength]; //we might not need them this big, but
int[] SetpointData = new int[arrayLength]; // this is worst case
int[] OutputData = new int[arrayLength];
int nPoints = 0;
19
Serial myPort;
ControlP5 controlP5;
controlP5.Button AMButton, DRButton;
controlP5.Textlabel AMLabel, AMCurrent, InLabel,
OutLabel, SPLabel, PLabel,
ILabel, DLabel,DRLabel, DRCurrent;
controlP5.Textfield SPField, InField, OutField,
PField, IField, DField;
PrintWriter output;
PFont AxisFont, TitleFont;
void setup()
{
frameRate(30);
size(windowWidth , windowHeight);
//AxisFont = loadFont("axis.vlw");
//TitleFont = loadFont("Titles.vlw");
nextRefresh=millis();
if (outputFileName!="") output = createWriter(outputFileName);
}
void draw()
{
20
background(200);
drawGraph();
drawButtonArea();
}
void drawGraph()
{
//draw Base, gridlines
stroke(0);
fill(230);
rect(ioLeft, inputTop,ioWidth-1 , inputHeight);
rect(ioLeft, outputTop, ioWidth-1, outputHeight);
stroke(210);
//Section Titles
//textFont(TitleFont);
fill(255);
text("PID Input / Setpoint",(int)ioLeft+10,(int)inputTop-5);
text("PID Output",(int)ioLeft+10,(int)outputTop-5);
}
interval = (int)outputHeight/5;
for(int i=0;i<6;i++)
{
if(i>0&&i<5) line(ioLeft+1,outputTop+i*interval,ioRight-2,outputTop+i*interval);
text(str((OutScaleMax-OutScaleMin)/5*(float)(5-
i)+OutScaleMin),ioRight+5,outputTop+i*interval+4);
}
21
{
int x = (int)ioRight-shift-2-i*interval;
line(x,inputTop+1,x,inputTop+inputHeight-1);
line(x,outputTop+1,x,outputTop+outputHeight-1);
float t = firstDisplay-(float)i*timeInterval;
if(t>=0) text(str(t),x,outputTop+outputHeight+10);
}
// add the latest data to the data Arrays. the values need
// to be massaged to get them to graph correctly. they
// need to be scaled to fit where they're going, and
// because 0, 0 is the top left, we need to flip the values.
// this is easier than having the user stand on their head
// to read the graph.
if(millis() > nextRefresh && madeContact)
{
nextRefresh += refreshRate;
for(int i=nPoints-1;i>0;i--)
{
InputData[i]=InputData[i-1];
SetpointData[i]=SetpointData[i-1];
OutputData[i]=OutputData[i-1];
}
if (nPoints < arrayLength) nPoints++;
InputData[0] = int(inputHeight)-int(inputHeight*(Input-InScaleMin)/(InScaleMax-
InScaleMin));
SetpointData[0] =int( inputHeight)-int(inputHeight*(Setpoint-InScaleMin)/(InScaleMax-
InScaleMin));
OutputData[0] = int(outputHeight)-int(outputHeight*(Output-OutScaleMin)/(OutScaleMax-
OutScaleMin));
}
//draw lines for the input, setpoint, and output
strokeWeight(2);
for(int i=0; i<nPoints-2; i++)
{
int X1 = int(ioRight-2-float(i)*pointWidth);
int X2 = int(ioRight-2-float(i+1)*pointWidth);
boolean y1Above, y1Below, y2Above, y2Below;
22
y1Below = (Y1<0); // the min or max, don't draw the
y2Above = (Y2>inputHeight); // line. if only one point is
y2Below = (Y2<0); // outside constrain it to the limit,
if(y1Above) // and leave the other one untouched.
{ //
if(y2Above) drawLine=false; //
else if(y2Below) { //
Y1 = (int)inputHeight; //
Y2 = 0; //
} //
else Y1 = (int)inputHeight; //
} //
else if(y1Below) //
{ //
if(y2Below) drawLine=false; //
else if(y2Above) { //
Y1 = 0; //
Y2 = (int)inputHeight; //
} //
else Y1 = 0; //
} //
else //
{ //
if(y2Below) Y2 = 0; //
else if(y2Above) Y2 = (int)inputHeight; //
} //
if(drawLine)
{
line(X1,Y1+inputTop, X2, Y2+inputTop);
}
23
{ //
if(y2Below) drawLine=false; //
else if(y2Above) { //
Y1 = 0; //
Y2 = (int)(inputHeight); //
} //
else Y1 = 0; //
} //
else //
{ //
if(y2Below) Y2 = 0; //
else if(y2Above) Y2 = (int)(inputHeight); //
} //
if(drawLine)
{
line(X1, Y1+inputTop, X2, Y2+inputTop);
}
24
if(drawLine)
{
line(X1, outputTop + Y1, X2, outputTop + Y2);
}
}
strokeWeight(1);
}
void drawButtonArea()
{
stroke(0);
fill(100);
rect(0, 0, ioLeft, windowHeight);
}
void Toggle_AM() {
if(AMLabel.valueLabel().getText()=="Manual")
{
AMLabel.setValue("Automatic");
}
else
{
AMLabel.setValue("Manual");
}
}
void Toggle_DR() {
if(DRLabel.valueLabel().getText()=="Direct")
{
DRLabel.setValue("Reverse");
}
else
{
DRLabel.setValue("Direct");
}
}
toSend[0] = float(SPField.getText());
25
toSend[1] = float(InField.getText());
toSend[2] = float(OutField.getText());
toSend[3] = float(PField.getText());
toSend[4] = float(IField.getText());
toSend[5] = float(DField.getText());
Byte a = (AMLabel.valueLabel().getText()=="Manual")?(byte)0:(byte)1;
Byte d = (DRLabel.valueLabel().getText()=="Direct")?(byte)0:(byte)1;
myPort.write(a);
myPort.write(d);
myPort.write(floatArrayToByteArray(toSend));
justSent=true;
}
if (s.length ==9)
{
Setpoint = float(s[1]); // * pull the information
Input = float(s[2]); // we need out of the
Output = float(s[3]); // string and put it
SPLabel.setValue(s[1]); // where it's needed
InLabel.setValue(s[2]); //
OutLabel.setValue(trim(s[3])); //
PLabel.setValue(trim(s[4])); //
ILabel.setValue(trim(s[5])); //
DLabel.setValue(trim(s[6])); //
AMCurrent.setValue(trim(s[7])); //
DRCurrent.setValue(trim(s[8]));
if(justSent) // * if this is the first read
26
{ // since we sent values to
SPField.setText(trim(s[1])); // the arduino, take the
InField.setText(trim(s[2])); // current values and put
OutField.setText(trim(s[3])); // them into the input fields
PField.setText(trim(s[4])); //
IField.setText(trim(s[5])); //
DField.setText(trim(s[6])); //
// mode = trim(s[7]); //
AMLabel.setValue(trim(s[7])); //
//dr = trim(s[8]); //
DRCurrent.setValue(trim(s[8])); //
justSent=false; //
} //
if(!madeContact) madeContact=true;
}
}
27
8. Análisis de resultados
28
Figura 8: diagrama del robot
Figura 9: valor de cero cuando la línea está a la derecha del arreglo de sensores
29
Figura 10: valor de cero cuando la línea está en el medio del arreglo de sensores
Figura 11: valor de cero cuando la línea está a la izquierda del arreglo de sensores
30
El control PID para el control del robot seguidor de línea es difícil mantenerlo estable
debido a que existen diferentes formas de pistas, al momento en que el control se
encuentra sintonizado la variable a controlar sigue inmediatamente al setpoint ante
cualquier cambio, así también no existe un rango de error exagerado entre estas dos
señales, sin embargo bajo condiciones no ideales el sistema oscila pero se intenta
mantener en un rango aceptable, todos los elementos que se usan en el circuito,
tiempos de muestreo o retroalimentación influyen en la respuesta del control PID.
KP KI KD Resultado
0.0001 0.0001 0.0001 Mantiene siempre
una línea recta
5 0.0001 0.0001 No tiene
oscilaciones, tiene
una respuesta lenta
5 5 0.0001 Es muy oscilatorio,
no alcanza e set
point.
10 6 0.0001 Pierde Pista
5 0.0001 1 Aumenta la
velocidad, pierde la
respuesta a
perturbaciones
6 0.001 6 Aumenta velocidad,
aumenta oscilación.
5 0.0001 6 Mantiene la
velocidad, no
presenta perdidas de
pista, buena
respuesta ante las
perturbaciones
Tabla 4 Análisis de resultados variando las constantes.
El control está implementado de forma digital con una placa Arduino OMEGA que
trabaja como un controlador y a la vez como una tarjeta de adquisición de datos, lo
cual permite una amplia aplicación. Con la que podemos ver la respuesta de nuestro
sistema ante las perturbaciones.
9. Conclusiones:
El control PID es un sistema de control por realimentación.
Implementar un control PID al seguidor de línea, hace que éste mejore su
funcionamiento “recordando” en donde está la línea en caso de perderla, es
decir, recibir una perturbación.
La programación en Arduino facilita la implementación del control PID.
El Software Processing facilita la visualización de la respuesta del sistema.
El seguidor de línea mejora su desempeño de diferentes mañeras a medida
que cambiamos las constantes del control PID utilizando la interface de
Processing o la de Arduino.
31
10. Recomendaciones:
Usar un arreglo de sensores que nos permitan obtener una señal digitalizada.
En la programación, usar variables que hagan referencia al elemento al que
pertenecen.
Usar micro motores para disminuir el peso y mejorar el torque.
Verificar el funcionamiento cambiando los valores de las constantes integral,
diferencial y proporcional para escoger el mejor desempeño del seguidor.
11. Bibliografía
http://platea.pntic.mec.es/~lmarti2/veloraton/sensoroptref.htm
http://arduino.cc/en/pmwiki.php?n=Main/ArduinoBoardMega
http://www.dia.uned.es/~fmorilla/MaterialDidactico/El%20controlador%20PI
D.pdf
12. ANEXOS
32
33