Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Av. Hidalgo 935, Colonia Centro, C.P. 44100, Guadalajara, Jalisco, México
bibliotecadigital@redudg.udg.mx - Tel. 31 34 22 77 ext. 11959
Universidad de Guadalajara
Centro Universitario de los Valles
Director
Dr. Carlos Renato Vázquez Topete
Codirector
Dr. Yehoshua Aguilar Molina
Capítulo 1. Introducción
alto que dependiendo sus características y aplicaciones oscilan en un precio de entre 50,000
y 100,000 USD, costo poco accesible para la mayoría de industrias locales y nacionales. En
México, existen alrededor de diez empresas dedicadas al desarrollo de tecnologías
innovadoras con máquinas y sistemas robóticos para PyMES (pequeñas y medianas
empresas) [6].
Dado que la mayoría de robots industriales son de origen extranjero, cualquier empresa
del país necesitaría importar el robot en caso de ser necesario. Eso genera una desventaja en
la PyMES, debido a que no cuentan, en general, con el capital necesario para los gastos de
importación.
En el proyecto se plantea el diseño detallado referente a la morfología del robot, así como
el análisis de elementos finitos en las piezas mecánicas por medio de herramientas CAD
(Computer Aided Design) y CAE (Computer Aided Engineering). Se describe el modelo
matemático de la cinemática directa, inversa y diferencial del robot, así como el estudio
dinámico del mismo. Se desarrollan técnicas de control aplicables en los motores CD del
robot que representan las articulaciones, se realiza la regulación y el seguimiento de
trayectorias previamente establecidas; todo esto mediante el uso de programación y de una
interfaz de usuario en la PC que puede comunicarse con el robot SCARA por medio de una
tarjeta de adquisición de datos.
muestra de forma detallada como se diseñó y se controló el robot. A pesar de ser un trabajo
muy completo se omiten algunos aspectos importantes, por lo cual se consideran otras
investigaciones más recientes que muestran trabajos experimentales con robots, estas
investigaciones mencionan el control de un robot SCARA por medio de diferentes
controladores. Una de estas investigaciones, expresan que uno de los principales aspectos a
considerar en el robot es el controlador, ya que este nos permite mantener una estabilidad en
la posición y trayectoria deseada ante perturbaciones en el sistema [8].
1.1.1 Justificación.
Debido a las exigencias en los sistemas industriales del país y la falta de empresas
mexicanas que puedan sustentar estas exigencias, se propone el diseño y construcción de un
robot SCARA de tres grados de libertad, que cuente con una estructura ergonómica, es decir
que incluya con buena interacción humano-robot-ambiente, así como versátil, que se adapte
a las necesidades de sus tareas programadas al momento de realizar operaciones de
movimientos de objetos y ensamblaje en el plano horizontal. Se busca desarrollar un robot
que cumpla con el equilibrio de economía y rendimiento. Aunado a esto se necesita que el
robot tenga una interfaz gráfica amigable para el usuario y un desarrollo de control
susceptible a cualquier modificación de sus tareas programadas.
1.1.2 Objetivos.
Objetivo general
Diseñar y construir un robot SCARA de tres grados de libertad capaz de seguir
trayectorias de referencia especificadas por el usuario mediante una interfaz
gráfica.
Objetivo particular
Obtener el modelo cinemático directo e inverso y diferencial del robot SCARA
diseñado.
Diseñar componentes mecánicos que cumplan con una ergonomía y versatilidad
idónea para el robot, con herramientas CAD.
Simular y analizar la estructura del robot con herramientas CAE.
Fabricar y ensamblar las piezas mecánicas del robot.
Seleccionar sensores, actuadores y controladores adecuados para la operación del
robot.
Diseñar e implementar el sistema eléctrico y electrónico del robot.
Desarrollar el modelo dinámico del robot.
Diseñar e implementar algoritmos de control, fiables y eficientes para el
seguimiento de trayectorias de referencia.
Programar la interface de desarrollo para la operación del robot en PC.
Realizar pruebas mecánicas y de control en el robot.
Evaluar y analizar los resultados.
4
1Fig. 2.1. A) Vista frontal SCARA, B) vista superior SCARA, C) espacio de trabajo
SCARA.
La configuración SCARA representa una geometría especial de robot industrial, dado que
es un brazo planar antropomórfico con dos articulaciones rotacionales y una prismática o
lineal para manipular objetos. El robot SCARA propuesto para su diseño contiene 3 DOF y
se constituye de dos articulaciones tipo revolutas 𝑞1 y 𝑞2 , que permiten la rotación de los
eslabones (ver Fig. 2.1 A, B). La última articulación d es de tipo prismática, perpendicular al
movimiento de los eslabones anteriores como se muestra en la Fig. 2.1.A.
Para obtener el modelo geométrico directo del robot SCARA, se utiliza la metodología
Denavit-Hartenberg [10], que consiste en determinar una tabla de parámetros relacionados
con los eslabones del robot (ver Fig. 2.2). Estos parámetros permiten crear las matrices de
transformación homogéneas que involucran operaciones de rotación y translación dentro de
una matriz que estructura el modelo cinemático directo.
6
1 0 0 0
𝐻23 = [0 1 0 0]
0 0 1 𝑑 (3
0 0 0 1
De las matrices anteriores se simplifica “S” para mencionar seno y “C” por coseno. Para
obtener la última posición del robot es necesario multiplicar las matrices 𝐻01 𝐻12 = 𝐻02 , que al
multiplicarla por la matriz 𝐻23 se obtiene la matriz homogénea de la posición final del robot,
expresada como 𝐻03 como se aprecia a continuación:
𝐶𝑞1 𝐶𝑞2 − 𝑆𝑞1 𝑆𝑞2 𝐶𝑞1 𝑆𝑞2 + 𝑆𝑞1 𝐶𝑞2 0 𝑙2 𝐶𝑞1 + 𝑙3 𝐶𝑞2 𝐶𝑞1 + 𝑙3 𝑆𝑞2 𝑆𝑞1
𝑙2 𝑆𝑞1 + 𝑙3 𝑆𝑞1 𝐶𝑞2 + 𝑙3 𝐶𝑞1 𝑆𝑞2
𝐻0 = [𝑆𝑞1 𝐶𝑞2 + 𝐶𝑞1 𝑆𝑞2
2 𝑆𝑞1 𝑆𝑞2 − 𝐶𝑞1 𝐶𝑞2 0 ]
0 0 −1 𝐵1 + 𝑙1 (4
0 0 0 1
𝐶𝑞1 𝐶𝑞2 − 𝑆𝑞1 𝑆𝑞2 𝐶𝑞1 𝑆𝑞2 + 𝑆𝑞1 𝐶𝑞2 0 𝑙2 𝐶𝑞1 + 𝑙3 𝐶𝑞2 𝐶𝑞1 + 𝑙3 𝑆𝑞2 𝑆𝑞1
𝑙2 𝑆𝑞1 + 𝑙3 𝑆𝑞1 𝐶𝑞2 + 𝑙3 𝐶𝑞1 𝑆𝑞2
𝐻0 = [𝑆𝑞1 𝐶𝑞2 + 𝐶𝑞1 𝑆𝑞2
3 𝑆𝑞1 𝑆𝑞2 − 𝐶𝑞1 𝐶𝑞2 0 ]
0 0 −1 𝐵1 + 𝑙1 − 𝑑 (5
0 0 0 1
𝑃𝑧 = 𝐵1 + 𝑙1 − 𝑑 (8
En donde Px es la posición en el eje X, Py es la posición en el eje Y, Pz para la posición
en el eje Z, determinadas mediante simplificaciones utilizando identidades trigonométricas
de suma de ángulos.
Para el cálculo de la cinemática inversa del robot SCARA se utiliza la forma geométrica,
donde se consideran todas las variables independientes de la función cinemática inversa
como: (X, Y, Z, 𝜃 ), donde X, Y y Z son posiciones expresadas en metros y 𝜃 que es el ángulo
formado por los eslabones y esta dado en radianes. El primer análisis a realizar consiste en
observar el comportamiento de las 2 primeras articulaciones rotacionales, considerándose
una vista superior del robot. Como se observa en la Fig. 2.3, las variables 𝑞1 y 𝑞2 están en
función de las posiciones X y Y.
5Fig. 2.4. Modelo de barras del robot SCARA desde vista superior.
Utilizando el teorema de Pitágoras se tiene que:
9
ℎ2 = 𝑃𝑥 2 + 𝑃𝑦 2
ℎ2 = 𝑙2 2 + 𝑙3 2 − 2𝑙2 𝑙3 (cos(𝜋 − 𝑞2 ))
𝑃𝑥 2 + 𝑃𝑦 2 = 𝑙2 2 + 𝑙3 2 + 2𝑙2 𝑙3 (cos(𝜋 − 𝑞2 ))
𝑃𝑥 2 +𝑃𝑦2 −𝑙2 2 −𝑙3 2
cos(𝑞2 ) = 2𝑙2 𝑙3
4𝑙2 2 𝑙3 2 − (𝑃𝑥 2 + 𝑃𝑦 2 − 𝑙2 2 − 𝑙3 2 )2
𝑠𝑒𝑛(𝑞2 ) = √
2𝑙2 𝑙3
√4𝑙2 2 𝑙3 2 −(𝑃𝑥 2 + 𝑃𝑦 2 − 𝑙2 2 − 𝑙3 2 )2
𝑞2 = 𝑡𝑎𝑛−1 (9
𝑃𝑥 2 + 𝑃𝑦 2 − 𝑙2 2 − 𝑙3 2
𝑃𝑦 𝑙3 𝑠𝑒𝑛(𝑞2 )
𝑞1 = 𝑡𝑎𝑛−1 ( ) − 𝑡𝑎𝑛−1 ( )
𝑃𝑥 𝑙2 +𝑙3 cos(𝑞2 ) ( 10
La Ec. (10) se encuentra en función de 𝑞2 , cuyo resultado puede ser negativo o positivo;
de acuerdo con la solución aplicada en la Ec. (10) el valor de 𝑞1 se modifica. Entonces 𝑞1 y
𝑞2 dependerán de los puntos asignados en el espacio (x, y).
Para el cálculo de la variable d no es necesario realizar análisis bidimensional, debido a
que el valor de la variable representa el desplazamiento en la articulación lineal sobre el eje
z del marco de referencia de la base, se desarrolla un cálculo directo sobre el valor de la
entrada del eje z. Al desarrollar el análisis en el eje z como se observa en la Fig. 2.2 se obtiene:
𝑑 = 𝐵1 + 𝑙1 − 𝑃𝑧
( 11
10
𝜕𝑦
=0
𝜕𝑑
𝜕𝑧
= −1
𝜕𝑑
Cuya representación matricial es:
Finalmente, considerando las Ecs. (12) y (13), se obtiene el Jacobiano geométrico del
robot SCARA, el cual se observa en la Ec. (14). Este representa la matriz de transformación
del efector final visto desde la base del robot.
−𝑙2 𝑆𝑞1 − 𝑙3 𝑆(𝑞1 +𝑞2 ) −𝑙3 𝑆(𝑞1 +𝑞2 ) 0
𝑙2 𝐶𝑞1 + 𝑙3 𝐶(𝑞1 +𝑞2 ) 𝑙3 𝐶(𝑞1 +𝑞2 ) 0
0 0 −1
𝐽= 0
0 0 ( 14
0 0 0
[ 1 1 0]
Como se observa en la Ec. (14) la matriz jacobiana depende de las posiciones articulares,
en este caso 𝑞1 y 𝑞2 , al igual que el giro de la herramienta con respecto al eje X y Y son nulos
por consiguiente en estas direcciones el robot es fijo ya que sólo se desplaza la muñeca en el
eje Z.
La inversa de la matriz jacobiana se muestra en la Ec. (15), esta matriz permite encontrar
la velocidad de las articulaciones o la velocidad del efector final.
( 15
𝑑 = 40 𝑚𝑚
6Fig. 2.5. Simulación cinemática del robot SCARA: a) Vista 3D del robot, b) Vista X-Y
del robot.
Como se observa en la Fig. 2.5, la línea de color rojo corresponde a la base del robot, la
línea negra al eslabón 1, la línea verde al eslabón 2 y la línea amarilla al eslabón 3. Los
eslabones se mueven respecto a los ángulos proporcionados de modo que la cinemática
obtenida corresponde de forma correcta. Se aprecia cómo se mueven los 3 DOF y como se
genera la posición final del efector final.
13
El objetivo de este capítulo es describir el diseño del robot SCARA, así como las
características y funcionamiento de sus componentes fundamentales: estructura física,
motores, sensores, fuente de alimentación y microcontrolador. El diseño del robot SCARA
abarca la iteración sinérgica de diferentes ingenierías para su desarrollo, en el cual la
experimentación puede estar sujeta a modificaciones permanentes. La metodología de diseño
a seguir consiste en tres partes fundamentales: modelamiento, simulación e integración. A lo
largo del desarrollo del robot serán seguidos estos procesos a fin de mejorar cada sección del
robot.
11Fig. 3.4. Espacio de trabajo del robot SCARA diseñado, en vista de planta.
masa del robot SCARA a diseñar, donde la masa de la base y eslabones fueron obtenidos de
la simulación de las piezas; de tal forma que se considera la masa de los eslabones más la
masa de los motores a utilizar como se muestra en la Fig. 3.9.
De esta forma se encuentran los pesos 𝑝1 y 𝑝2 de los eslabones y un peso p que es el peso
máximo el cual el efector final sostendrá.
Ya que se conocen los pesos de los eslabones es posible obtener la sumatoria de fuerzas
de cada eslabón [19], como se muestra a continuación:
∑ 𝐹𝑦 = ∑ 𝐹𝑅
( 19
Obtenidas las sumatorias es posible encontrar también el momento flector, ya sea del codo
o del hombro del robot considerando el centro de masa de cada eslabón, así como las medidas
de sus longitudes y pesos. Para obtener los momentos antes señalados, es necesario analizar
el siguiente diagrama de fuerzas de la Fig. 3.11.
0.20 𝑚
𝑀2 = 11.77 𝑁 (0.15 𝑚 + ) + 9.81 𝑁(0.15 𝑚 + 0.20 𝑚) = 6.37 𝑁. 𝑚
2 ( 23
22
A fin de obtener el momento 2, se emplea, dado que mueve a toda la cadena cinemática
del robot SCARA, el momento 1; presentado en la siguiente ecuación:
𝐿1
𝑀1 = 𝑀2 + 𝑝1 ( )
2 ( 24
0.15 𝑚
𝑀1 = 6.37 𝑁. 𝑚 + 12.36 𝑁 ( ) = 7.3 𝑁. 𝑚
2 ( 25
Dado los momentos obtenidos en los eslabones, surge una idea más general de cómo
trabaja el robot bajo las cargas sometidas. Aunado a esto, los momentos brindan información
para seleccionar los motores del robot, lo que se verá en los capítulos próximos.
Para complementar el diseño del manipulador, es necesario hacer un análisis de cargas y
esfuerzos bajo condiciones estáticas con el fin de obtener la resistencia máxima en cada
elemento mecánico. En algunos componentes considerados como elementos críticos se
realizó un análisis de elementos finitos FEA (Finite Element Analysis), para evaluar el
comportamiento de éstos ante la aplicación de las cargas calculadas.
El software utilizado, SolidWorks genera un estudio estático que indica los
desplazamientos que tendrán las piezas ante tales fuerzas aplicadas, fuerzas de reacción,
deformaciones unitarias y distribución del factor de seguridad.
El software presenta como resultados la distribución del esfuerzo en la escala de Von
Mises (𝑁⁄𝑚2 ) para la deformación; la distribución del desplazamiento estático medido en
escala URES (mm) y analiza la deformación generada de forma gráfica y codificada en
colores que indican las zonas más vulnerables; esto es, el tono azul indica el límite mínimo
y rojo el límite máximo.
En la Fig. 3.12 se observa el estudio estático realizado al soporte del eslabón 1
(SCARA_P5), este soporte se une al eje del motor 1 que se encuentra en la base del robot
SCARA y que une también el eslabón 1 con su respectiva carga. La imagen muestra el
análisis de tensión en la pieza al aplicarse en ella una fuerza de 35N (Newtons), esta fuerza
es la total obtenida en la sumatoria anterior de las fuerzas en el robot. Se observa que al ser
aplicada la fuerza no se rompe el limite elástico de la pieza, considerando que el material de
esta pieza es aluminio lo cual tiene un límite elástico de 145 𝑁⁄𝑚2 .
23
Los estudios anteriores ayudan a conocer el comportamiento de la pieza ante una fuerza y
generan parámetros indispensables para su fabricación. El siguiente estudio realizado en la
pieza es el factor de seguridad, que ayuda a visualizar las incertidumbres que pueden ocurrir
cuando las cargas reales actúen sobre una pieza ya construida, dicho de otro modo es una
medida de seguridad relativa de un componente bajo la acción de una carga [21]. En la Fig.
3.14 se aprecia como la pieza diseñada no está por debajo del factor de seguridad de 2.5 el
cual indica que la pieza tiene la resistencia mecánica adecuada.
Para unir el eje (SCARA_P9) con el segundo eslabón, se utiliza una base de sujeción
(SCARA_P8). Es importante conocer si esta podrá soportar el peso del eslabón en conjunto
con la carga máxima y así poder generar el giro de movimiento del mismo eslabón. En la Fig.
3.21 se observa el análisis de tensión, que indica si la pieza no rompe el límite elástico,
conociendo que su material es el aluminio.
Por último se realiza el análisis estático al eje de unión 2 (SCARA_P15), este eje une al
tornillo de potencia con el eje del motor y así generar el movimiento que subirá y bajará la
carga máxima en el robot. De tal forma que el análisis de tensión mostrado en la Fig. 3.27
indica que no rompe el límite elástico de su material de fabricación el aluminio.
real que son alrededor de 35N distribuidas en los eslabones, se aprecia como el último
eslabón se hunde a causa de las cargas presentadas al encontrarse en su posición extendida.
𝐽𝑖 = ∑(𝑙𝑐𝑖 )2 (𝑚𝑖 ) ( 27
35
Se define 𝑙𝑐𝑖 como la distancia del eje de giro al centro de masa del eslabón i y 𝑚𝑖 , definida
como la masa del eslabón i. Para calcular el momento de inercia que experimenta cada
actuador del robot SCARA es importante considerar los parámetros mostrados en la Tabla
3.2, datos obtenidos por el software de diseño.
40Tabla 3.2. Especificaciones de los parámetros en nuestro robot SCARA.
PARAMETROS DEL ROBOT SCARA
𝑚1 6 kg
𝑚2 1.26 kg
𝑚3 2.2 kg
𝑙1 0.20 m
𝑙2 0.16 m
𝑙3 0.19 m
B1 0.05 m
𝑙𝑐11 0.07 m
𝑙𝑐12 0.25 m
𝑙𝑐13 0.34 m
𝑙𝑐𝑚2 0.15 m
𝑙𝑐22 0.08 m
𝑙𝑐23 0.17 m
𝑚𝑀2 0.400 kg
𝑚𝑀3 0.310 kg
Para obtener el momento de inercia del primer actuador, es importante considerar las
distancias desde el eje del actuador 1 hasta los centros de masa del eslabón 1
(𝑙𝑐11 ), el eslabón 2 (𝑙𝑐12 ), el actuador 2 (𝑙𝑐𝑚2 ) y el eslabón 3 (𝑙𝑐13 ). Así como las masas de
los eslabones en conjunto con el peso del actuador y la carga total a mover. De modo que el
momento de inercia para el actuador 1 queda expresado de la siguiente forma:
𝐽1 = 0.37𝑘𝑔𝑚2 ( 29
Para el momento de inercia del segundo actuador sólo se considera la cadena cinemática
a partir del actuador 2, considerando solamente la distancia del eje del actuador 2 (𝑙𝑐22 ) al
centro de masa del eslabón 2 y el eslabón 3 (𝑙𝑐23 ), respectivamente. Se expresa entonces el
momento de inercia como:
𝐽2 = ∑(𝑙𝑐22 )2 𝑚2 + (𝑙𝑐23 )2 𝑚3
( 30
36
𝐽2 = 0.07164 𝑘𝑔𝑚2
( 31
Al obtener los momentos de inercia de los actuadores se puede continuar con el cálculo
del par de cada motor. Se considera la velocidad angular (𝜔𝑖 ) y la aceleración angular (𝛼𝑖 )
como valores de diseño, que indican que tan rápido girará el motor, en la Tabla 3.1 se muestra
la velocidad definida para el robot SCARA, así como la aceleración de 4 𝑟𝑎𝑑⁄𝑠 2 .
El coeficiente de fricción (Cfr) se obtiene dado el rodamiento SKF seleccionado en el
área de contacto con el motor. Este coeficiente es proporcionado por el fabricante [32], en
este caso para las dos articulaciones del robot el coeficiente es de 0.0018 𝑁𝑚/ (𝑟𝑎𝑑⁄𝑠)
considerando que los rodamientos son cónicos, para más detalles ir ala apéndice W.
Obtenidos los datos anteriores se sustituyen estos valores en la Ec. (26) para obtener los
pares 𝑡1 y 𝑡2 como se observa en las Ecs. (32) y (33):
𝑡1 = 0.37𝑚2 𝑘𝑔 ∗ 4 𝑟𝑎𝑑⁄𝑠 2 + 0.0018 ∗ 4 𝑟𝑎𝑑⁄𝑠 = 1.48 𝑁𝑚
( 32
Los pares obtenidos indican el par máximo requerido para mover los eslabones con la
carga de los demás componentes, de modo que tomando en cuenta la velocidad ya establecida
del robot se puede elegir los actuadores que cumplan con estos criterios en general.
Para la selección de los motores de las articulaciones rotacionales del robot SCARA, se
consideró utilizar el motor PITTMAN GM9000 para el movimiento de la primera
articulación y el motor PITTMAN GM8000 para el movimiento de la segunda articulación.
Estos motores pueden cumplir con el par requerido, así como la velocidad y aceleración
adecuada para los movimientos del robot. Se seleccionaron los motores de esta marca ya que
brindan un funcionamiento suave, son muy estables con su corriente y tensión y no generan
tanto ruido [22]. En la Tabla 3.4 se observa las características de los motores utilizados. Cabe
señalar que estos motores son de corriente continua e imán permanente, los pares máximos
de los motores son multiplicados por la caja de reducción incorporada en cada motor la cual
eleva al par y reducen la velocidad, de modo que los pares finales de estos son suficientes
para soportar las cargas en los eslabones. Las especificaciones de los motores se encuentran
en los apéndices P y Q.
Por otro lado para obtener el par de elevación y descenso de la carga que moverá el robot
SCARA se utilizará un tornillo de potencia que permite distribuir mejor la fuerza de empuje
sobre la base de apoyo, en la Fig. 3.33 se presenta el esquema de un mecanismo con tornillo
de potencia.
37
Dónde:
F Valor de la carga a elevar por el tornillo.
p Paso o avance del tornillo.
𝒅𝒎 Diámetro medio del tornillo.
𝝁 Coeficiente de rozamiento de la rosca del tornillo y tuerca.
𝝷 Ángulo de la rosca.
El tornillo de potencia a utilizar es un tornillo embalado con las siguientes características
mostradas en la Tabla 3.3:
42Tabla 3.3. Especificaciones de los tornillos utilizados en el robot SCARA.
5 mm 12 mm 0.1 29° 7 kg
Sustituyendo los valores de la Tabla 3.3 en la Ec. (34) y considerando que la carga máxima
que levantar nuestro robot SCARA es de 9.81 N se tiene que:
9.81 𝑁 ∗ 0.012 𝑚 (0.005 𝑚 + 3.1416𝑚 ∗ 0.1 ∗ 0.012 ∗ 𝑠𝑒𝑐29°)
𝑡𝑝 = ( )∗ ( 35
2 (3.1416 ∗ 0.012 − 0.1 ∗ 0.005 ∗ 𝑠𝑒𝑐29°)
38
1 𝑘𝑔 100 𝑐𝑚
𝑡𝑝 = 0.17𝑁. 𝑚 ( )( ) = 1.7 𝑘𝑔. 𝑐𝑚
9.81 1𝑚 ( 36
Con el par obtenido en la Ec. (36) se selecciona un actuador que pueda mover la carga
máxima del robot SCARA, de modo que la pueda subir y bajar en distintos puntos sin que
esta pueda descender bruscamente. Los datos sustituidos fueron tomados de tornillos de
potencia comerciales, con el fin de encontrarse más fácil en el mercado.
El motor para mover la carga máxima seleccionada, es el motor marca NAMIKI, dado
que ofrece una velocidad mayor para subir y bajar la carga del robot a diferencia de los
motores PITTMAN. En la Tabla 3.4 se observan las características principales de los motores
utilizados en el robot.
43Tabla 3.4. Especificaciones de los motores utilizados en el robot SCARA.
ESPECIFICACIONES DE MOTORES EN EL ROBOT SCARA
Hombro Codo Eje Z
Datos del motor
M1 M2 M3
Voltaje de alimentación (VDC) 24 12 12
Velocidad sin carga (𝑟𝑝𝑚/ 𝑟𝑎𝑑⁄𝑠) 236/24.7 75/7.85 120/12.56
Par máximo continuo (N-m) 1.1 0.8 0.5
Par pico al arranque (N-m) 6.1 2.3 1.6
Corriente al arranque (A) 9.64 1.41 1.8
Datos de la caja de engranes
Relación de reducción 19.7:1 10:1 80:1
Como se observa en la Fig. 3.42, la pieza SCARA_P8 posee un conducto por donde la
pieza SCARA_P9 se fija mediante un tornillo de 1/4 in. Además cuenta con cuatro ranuras
roscadas para tornillo 7/32 in. que se utilizan para unir al eslabón 2.
Al unir cada parte mencionada anteriormente, se realiza un ensamble final del robot
SCARA tal como se aprecia en la Fig. 3.54. Este acople de fracciones cuenta con todas las
piezas fijas por medio de tornillos u opresores. Del mismo modo, tal y como se encentra es
la forma en la que se utiliza para realizar todas las pruebas de control de posición y
estabilidad.
Dicho de otro modo, el sentido de giro del motor depende de la polaridad que se le aplica a
sus terminales, en consecuencia, para cambiar el giro es necesario intercambiar las terminales
del motor o bien cambiar la polaridad de alimentación y es posible regular su velocidad
haciendo circular mayor o menor corriente.
Esto se consigue creando una onda cuadrada que conmuta constantemente entre 0 y 5 para
generar una tensión proporcional a la escala. Es importante considerar que si la frecuencia
del PWM es muy baja esta genera en el motor una vibración y por contrario si es muy alta el
motor se calentara.
Para el control del primer motor se toma en cuenta el driver LMD18200, este se alimenta
con 12 VCD y será el encargado de mover la primera articulación. Su control se basa en tres
partes importantes (dirección, break y PWM), los pines mencionados permitirán detener el
motor, girar el motor hacia la izquierda o hacia la derecha e incluso regular velocidad. En la
Tabla 3.8 se observa la forma de control con este driver, los estados de estos pines permitirán
el control vía software con Matlab.
73Tabla 3.8. Tabla de control LMD18200.
Antes de aplicar la fórmula a los encoders de cada motor, es importante considerar que
estos cuentan con una caja reductora con relaciones de engranes diferentes, por consiguiente
se debe multiplicar las CPR por la relación reductora como se muestra en la Tabla 3.10.
81Tabla 3.8. Especificaciones de los encoders incrementales en el robot SCARA.
CONSIDERACIONES DE LOS ENCODERS INCREMENTALES DEL ROBOT SCARA
Relación de Pulso por cada revolución Grados Grados
Motor CRP
reducción con caja de engranes Mecánicos Eléctricos
M1 500 19.7:1 9850 pulsos 360° 0.0365°
M2 500 19.5:1 9750 pulsos 360° 0.0369°
M3 2 80:1 160 pulsos 360° 2.25°
Además de los encoders incrementales utilizados en el robot SCARA se utilizan sensores
de final de carrera. Estos sensores están ubicados cerca de cada articulación y se encargan de
producir una señal cuando el eslabón está llegando a su límite máximo. En el robot SCARA
se colocaran 2 sensores final de carrera por actuador, de modo que se limita a los
movimientos de las 3 articulaciones del robot.
El funcionamiento de los finales de carrera es muy sencillo, se conecta la parte común a
un voltaje de 5VCD y el contacto NO (normalmente abierto), en donde al detectar que el
eslabón llega al límite este cierra el contacto NO y manda una señal a la etapa de control para
generar determinada tarea, el diagrama interno se muestra en la figura 3.66.
Esta ecuación es una forma compacta y con la notación más ampliamente utilizada en el
área de la robótica. Donde de la ecuación tenemos que 𝑞 = [𝑞1 , 𝑞2 . . , 𝑞𝑛 ]𝑇 ∈ ℝ𝑛 representa
el vector de posiciones articulares o coordenadas generalizadas, 𝑞̇ = [𝑞̇ 1 , 𝑞̇ 2 . . , 𝑞̇ 𝑛 ]𝑇 ∈ ℝ𝑛 es
el vector de velocidades articulares, 𝑞̈ = [𝑞̈ 1 , 𝑞̈ 2 . . , 𝑞̈ 𝑛 ]𝑇 ∈ ℝ𝑛 es el vector de aceleraciones
articulares, 𝑀(𝑞) ∈ ℝ𝑛𝑥𝑛 es la matriz de inercia que representa el cambio de estado de
movimiento del robot manipulador, la cual es simétrica y definida positiva, 𝐶(𝑞, 𝑞̇ ) ∈ ℝ𝑛𝑥𝑛
es la matriz de fuerzas centrípetas y de Coriolis, la fuerzas centrípetas son fuerzas radiales y
las fuerzas de Coriolis representan una desviación en el movimiento de traslación debido a
su componente de rotación, 𝑔(𝑞) ∈ ℝ𝑛 es el vector de fuerzas o pares gravitacionales
obtenido como el gradiente de la energía potencial y 𝜏 = [𝜏1 , 𝜏2 . . , 𝜏𝑛 ]𝑇 es el vector de pares
aplicados al robot.
Para lograr lo anterior se estudia y desarrollan las ecuaciones de la dinámica del robot
SCARA, para obtener la dinámica se utiliza el método de Euler-Lagrange, el cual está basado
en el balance de la energía cinética y potencial.
Para desarrollar la dinámica del robot SCARA se inicia con el estudio de la energía
potencial y cinética de cada uno de los eslabones del robot. Se define como formulación de
Lagrange o Lagrangiano a la diferencia entre la energía cinética EC y potencial EP [29].
ℒ = 𝐸𝐶 − 𝐸𝑃 = 1⁄2 𝑚𝑞̇ 2 − 𝑚𝑔𝑞
( 39
𝜕ℒ 𝜕𝐸𝐶
=
𝜕𝑞̇ 𝜕𝑞̇ ( 41
Remplazando las Ecs. (40) y (41) en la segunda ley de Newton para un cuerpo con energía
cinética y potencial se obtiene la siguiente ecuación general:
𝑑 𝜕ℒ 𝜕ℒ
[ ]− =𝜏
𝑑𝑡 𝜕𝑞̇ 𝜕𝑞 ( 42
𝐸𝑃1 = 𝑚1 𝑔𝑙1
( 44
𝐸𝐶2 = 1⁄2 𝑚2 (𝑙2 2 𝑞1̇ 2 + 2𝑙2 𝑙3 𝑞1̇ (𝑞1̇ +𝑞̇ 2 )𝐶𝑞2 + 𝑙3 2 (𝑞1̇ +𝑞̇ 2 )2 )
( 46
𝐸𝑃2 = 𝑚2 𝑔𝑙1
( 47
𝐸𝐶3 = 1⁄2 𝑚3 (𝑙2 2 𝑞1̇ 2 + 2𝑙2 𝑙3 𝑞1̇ (𝑞1̇ +𝑞̇ 2 )𝐶𝑞2 + 𝑙3 2 (𝑞1̇ +𝑞̇ 2 )2 + 𝑑̇ 2 )
( 49
𝐸𝑃3 = 𝑚3 𝑔(𝐵1 + 𝑙1 − 𝑑)
( 50
Obtenidas cada tipo de energía potencial y cinética de cada eslabón es posible generar la
ecuación Lagrangiana, haciendo una sumatoria de energía potencial y cinética de la siguiente
forma:
ℒ = 𝐸𝐶1 + 𝐸𝐶2 +𝐸𝐶3 − 𝐸𝑃1 − 𝐸𝑃2 − 𝐸𝑃3
( 51
2
ℒ = 1⁄2 𝑚1 𝑙2 2 𝑞1̇ 2 + 1⁄2 𝑚2 (𝑙2 2 𝑞1̇ 2 + 2𝑙2 𝑙3 𝑞1̇ (𝑞1̇ +𝑞̇ 2 )𝐶𝑞2 + 𝑙3 2 (𝑞1̇ +𝑞̇ 2 ) )
2 2
+ 1⁄ 𝑚3 (𝑙2 2 𝑞 ̇ 2 + 2𝑙2 𝑙3 𝑞 ̇ (𝑞 ̇ +𝑞̇ )𝐶𝑞 + 𝑙3 2 (𝑞 ̇ +𝑞̇ ) + 𝑑̇ )
2 1 1 1 2 2 1 2
( 52
− 𝑚1 𝑔𝑙1 − 𝑚2 𝑔𝑙1 − 𝑚3 𝑔(𝐵1 + 𝑙1 − 𝑑)
62
Para calcular ahora el par en el robot se necesita seguir la Ec. (39), de la cual se obtienen
las siguientes ecuaciones:
𝜕ℒ
=0
𝜕𝑞1 ( 53
𝜕ℒ
= (𝑚1 + 𝑚2 + 𝑚3 )𝑙2 2 𝑞1̇ + (𝑚2 + 𝑚3 )𝑙3 2 (𝑞1̇ +𝑞̇ 2 )
𝜕𝑞1̇
( 54
+ (𝑚2 + 𝑚3 )𝑙2 𝑙3 (2𝑞̇ 1 +𝑞̇ 2 )𝐶𝑞2
𝑑 𝜕ℒ
[ ] = (𝑚1 + 𝑚2 + 𝑚3 )𝑙2 2 𝑞1̈ + (𝑚2 + 𝑚3 )𝑙3 2 (𝑞1̈ + 𝑞2̈ )
𝑑𝑡 𝜕𝑞1̇
( 55
+ (𝑚2 + 𝑚3 )2𝑙2 𝑙3 [𝐶𝑞2 (𝑞1̈ + 𝑞2̈ ) − (𝑞1̇ +𝑞̇ 2 )𝑆𝑞2 𝑞2̇ ]
Finalmente, utilizando la definición de la Ec. (42) y las expresiones obtenidas de las Ecs.
(53) y (55) se obtiene el par 1:
𝑑 𝜕ℒ 𝜕ℒ
𝜏1 = [ ]−
𝑑𝑡 𝜕𝑞1̇ 𝜕𝑞1
= [(𝑚1 + 𝑚2 + 𝑚3 )𝑙2 2 + (𝑚2 + 𝑚3 )𝑙3 2 + (𝑚2 + 𝑚3 )𝑙2 𝑙3 2𝐶𝑞2 ]𝑞1̈
( 56
+ [(𝑚2 + 𝑚3 )𝑙3 2 + (𝑚2 + 𝑚3 )𝑙2 𝑙3 2𝐶𝑞2 ]𝑞2̈ − (𝑚2 + 𝑚3 )𝑙2 𝑙3 2𝑞1̇ 𝑆𝑞2 𝑞2̇
2
− (𝑚2 + 𝑚3 )2𝑙2 𝑙3 𝑆𝑞2 𝑞̇ 2
𝜕ℒ
= (𝑚2 + 𝑚3 )𝑙2 𝑙3 𝐶𝑞2 𝑞1̇ + (𝑚2 + 𝑚3 )𝑙3 2 (𝑞1̇ +𝑞̇ 2 )
𝜕𝑞2̇ ( 58
𝑑 𝜕ℒ 2
[ ] = (𝑚2 + 𝑚3 )𝑙2 𝑙3 [𝐶𝑞2 𝑞̈ 1 − 𝑆𝑞2 𝑞2̇ 𝑞1̇ ] + (𝑚2 + 𝑚3 )𝑙3 (𝑞1̈ + 𝑞2̈ )
𝑑𝑡 𝜕𝑞2̇ ( 59
63
𝑑 𝜕ℒ 𝜕ℒ
𝜏2 = [ ]−
𝑑𝑡 𝜕𝑞2̇ 𝜕𝑞2
2
= [(𝑚2 + 𝑚3 )𝑙2 𝑙3 𝐶𝑞2 + (𝑚2 + 𝑚3 )𝑙3 ]𝑞̈ 1 + [(𝑚2 + 𝑚3 )𝑙3 2 ]𝑞2̈ ( 60
− (𝑚2 + 𝑚3 )𝑙2 𝑙3 𝑆𝑞2 𝑞2̇ 𝑞1̇
𝜕ℒ
= 𝑚3 𝑑̇
𝜕𝑑̇ ( 62
𝑑 𝜕ℒ
[ ] = 𝑚3 𝑑̈
𝑑𝑡 𝜕𝑑̇ ( 63
𝑑 𝜕ℒ 𝜕ℒ
𝐹3 = [ ]− = 𝑚3 𝑑̈ − 𝑚3 𝑔
𝑑𝑡 𝜕𝑑̇ 𝜕𝑑 ( 64
Al encontrar los pares y la fuerza del robot SCARA, siendo[𝜏1 , 𝜏2 y 𝐹3 ]𝑇 los pares emitidos
por los actuadores que actúan en las articulaciones del robot. Las Ecs. (56), (60) y (64)
constituyen las ecuaciones diferenciales no lineales del robot.
Para los propósitos de control, es más práctico reescribir el modelo dinámico del robot de
las Ecs. (56), (60) y (64) en su forma compacta como se muestra en la Ec. (68). En la Ec.
(68) la matriz 𝑀(𝑞) multiplica al vector de aceleraciones 𝑞̈ , por lo tanto, de las Ecs. (56),
(60) y (64) se toman los términos en los cuales se tiene el término 𝑞̈ 1 , 𝑞̈ 2 y 𝑑̈ para obtener así
los elementos de la matriz de inercia 𝑀(𝑞) ∈ ℝ3𝑥3 que está en función de la posición articular
q. Una vez realizado este reordenamiento de términos se obtiene que los elementos de la
matriz 𝑀(𝑞) son:
𝑚11 (𝑞) = (𝑚1 + 𝑚2 + 𝑚3 )𝑙2 2 + (𝑚2 + 𝑚3 )𝑙3 2 + (𝑚2 + 𝑚3 )𝑙2 𝑙3 2𝐶𝑞2
𝑚12 (𝑞) = (𝑚2 + 𝑚3 )𝑙3 2 + (𝑚2 + 𝑚3 )2𝑙2 𝑙3 𝐶𝑞2
𝑚13 (𝑞) = 0
𝑚21 (𝑞) = (𝑚2 + 𝑚3 )[𝑙2 𝑙3 𝐶𝑞2 + 𝑙3 2 ]
𝑚22 (𝑞) = (𝑚2 + 𝑚3 )𝑙3 2
𝑚23 (𝑞) = 0
𝑚31 (𝑞) = 0
𝑚32 (𝑞) = 0
64
𝑚33 (𝑞) = 𝑚3
La matriz 𝐶(𝑞, 𝑞̇ ) ∈ ℝ3𝑥3 llamada matriz de fuerzas centrifugas y de Coriolis puede no
ser única, pero el vector si 𝐶(𝑞, 𝑞̇ )𝑞̇ , para obtener 𝐶(𝑞, 𝑞̇ ) es a través de los coeficientes o
símbolos de Christoffel 𝑐𝑖𝑗𝑘 (𝑞) definidos como [12]:
1 𝜕𝑀𝑘𝑗 (𝑞) 𝜕𝑀𝑘𝑖 (𝑞) 𝜕𝑀𝑖𝑗 (𝑞)
𝑐𝑖𝑗𝑘 (𝑞) = [ + − ]
2 𝜕𝑞𝑖 𝜕𝑞𝑗 𝜕𝑞𝑘 ( 65
Donde 𝑀𝑖𝑗 (𝑞) denota 𝑖𝑗-esimo elemento de la matriz de inercia 𝑀(𝑞). De tal forma que
el 𝑘𝑗-esimo elemento de la matriz 𝐶(𝑞, 𝑞̇ ) puede obtenerse de:
𝑐1𝑗𝑘 (𝑞)
𝑐2𝑗𝑘 (𝑞)
𝑃𝑐𝑗𝑘 (𝑞, 𝑞̇ ) = .. 𝑞̇
( 66
[𝑐𝑛𝑗𝑘 (𝑞)]
Por lo tanto se calculan los coeficientes de Christoffel usando la Ec. (65) y los elementos
de la matriz de inercia obtenidos anteriormente con lo que se obtiene:
𝑐11 (𝑞, 𝑞̇ ) = −(𝑚2 + 𝑚3 )𝑙2 𝑙3 2𝑆𝑞2
𝑐21 (𝑞, 𝑞̇ ) = −(𝑚2 + 𝑚3 )𝑙2 𝑙3 𝑆𝑞2
𝑐31 (𝑞, 𝑞̇ ) = 0
𝑐12 (𝑞, 𝑞̇ ) = −(𝑚2 + 𝑚3 )𝑙2 𝑙3 2𝑆𝑞2 𝑞2̇
𝑐22 (𝑞, 𝑞̇ ) = 0
𝑐32 (𝑞, 𝑞̇ ) = 0
𝑐13 (𝑞, 𝑞̇ ) = 0
𝑐23 (𝑞, 𝑞̇ ) = 0
𝑐33 (𝑞, 𝑞̇ ) = 0
Cuando el robot se desplaza en el plano horizontal X-Y, la energía potencial resulta nula,
esto es 𝑃(𝑞) = 0, y ya que 𝑔(𝑞) = 𝜕𝑃(𝑞)⁄𝜕𝑞 , entonces 𝑔(𝑞) = 0. Por otro lado solo se
presenta la gravedad en el desplazamiento vertical para el par 𝜏3 , y queda expresado como:
𝑔1 = 0
𝑔2 = 0
𝑔3 = −𝑚3
Finalmente ya obtenidos los pares y la fuerza de los eslabones, expresar en forma matricial
el modelo del robot SCARA, este tiene la forma siguiente:
65
𝜏1
[𝜏2 ]
𝐹3
(𝑚1 + 𝑚2 + 𝑚3 )𝑙2 2 + (𝑚2 + 𝑚3 )𝑙3 2 + (𝑚2 + 𝑚3 )𝑙2 𝑙3 2𝐶𝑞2 (𝑚2 + 𝑚3 )𝑙3 2 + (𝑚2 + 𝑚3 )2𝑙2 𝑙3 𝐶𝑞2 0 𝑞̈1
=[ (𝑚2 + 𝑚3 )[𝑙2 𝑙3 𝐶𝑞2 + 𝑙3 2 ] (𝑚2 + 𝑚3 )𝑙3 2 0 ] [𝑞2̈ ]
0 0 𝑚3 𝑑̈
( 68
−(𝑚2 + 𝑚3 )𝑙2 𝑙3 2𝑆𝑞2 −(𝑚2 + 𝑚3 )𝑙2 𝑙3 𝑆𝑞2 0 𝑞1̇ 0
+ [−(𝑚2 + 𝑚3 )𝑙2 𝑙3 2𝑆𝑞2 0 0] [𝑞2̇ ] + [ 0 ] ∗ 𝑔
0 0 0 𝑑̇ −𝑚3
𝑢 = −𝐾𝑝 𝑞̃ − 𝐾𝑖 ∫ 𝑞̃ 𝑑𝑡 − 𝐾𝑑 𝑞̇
( 69
Donde 𝐾𝑝 , 𝐾𝑖 y 𝐾𝑑 son las ganancias positivas proporcional, integral y derivada que deben
sintonizarse. En la Ec. (69), 𝑞̃ se considera como el error de posición angular entrada al
controlador; definido como la posición actual en la que se encuentra el robot 𝑞(𝑡) menos la
posición 𝑞𝑑 (𝑡) ingresada por el usuario 𝑞̃(𝑡) = 𝑞(𝑡) − 𝑞𝑑 (𝑡). En el robot SCARA se
utilizaron los siguientes valores para estas ganancias:
𝐾𝑝1 = 0.06, 𝐾𝑖1 = 0.01 y 𝐾𝑑1 = 0.004 para la articulación 1, 𝐾𝑝2 = 0.06, 𝐾𝑖2 = 0.02 y
𝐾𝑑2 = 0.005 para la articulación 2 y 𝐾𝑝3 = 0.02, 𝐾𝑖3 = 0.01 y 𝐾𝑑3 = 0.005 para la
articulación 3.
Estos valores para las ganancias de control se sintonizaron al linealizar el sistema que se
esta analizando para llevarlo a la forma general de los sistemas lineales en el espacio de
66
estados, donde se utilizó MATLAB para los cálculos complejos. Por lo mismo no se plantean
en este punto.
Para controlar la posición de las articulaciones en el robot, se considera como entrada al
controlador el error de posición angular 𝑞̃(𝑡) y la salida del controlador es el voltaje a aplicar
al motor 𝑢. Así entonces, el controlador PID genera la señal a aplicar al motor como la suma
ponderada del error de posición, la integral del error de posición y la derivada de la posición
del error.
Se considera que la derivada de la posición del motor es igual a la velocidad del motor ν,
y que la derivada de la posición deseada es cero dado a ser constante, por tanto, la derivada
del error es igual a la velocidad. Para la implementación del controlador PID se utiliza una
discretización con tiempo de muestreo fijo Δt suficientemente pequeño, dicho tiempo la placa
Arduino mandará en unos de sus puertos de salida el voltaje efectivo calculado 𝑢, hasta que
un nuevo ciclo se ejecute y se recalcule la ley de control y se envié el dato obtenido por el
puerto.
1 4
5 6
3 8
95Fig. 3.76. Convergencia a cero de los errores en las posiciones Px, Py, Pz reales sin
perturbación.
Con la nueva carga aumenta en poco los errores, ya que se necesita un esfuerzo mayor en
el robot para alcanzar la posición deseada P (x, y, z) = (0.38, -0.0032, 0.37). En la Fig. 3.78
se observa como los errores tratan de llegar a cero sin alcanzarlo totalmente.
98Fig. 3.78. Convergencia a cero de los errores en las posiciones Px, Py, Pz reales con
carga.
Capítulo 6. Conclusiones
Al realizar esta tesis se logró cumplir con el objetivo principal, en donde se diseñó y
construyó un robot SCARA de tres grados de libertad, que es capaz de seguir trayectorias de
referencia especificadas por el usuario mediante una interfaz gráfica.
El prototipo construido es mecánicamente funcional y operacional, ya que tiene el
movimiento independiente de cada uno de sus motores; generando en cada articulación el
seguimiento de órdenes diferentes. Debido a que la mayoría de piezas son de aluminio 6061,
ninguna de estas ha llegado a deformarse por lo tanto puede ser sometido a tareas complejas.
El robot SCARA puede mover sin problema la carga máxima de 1kg, aunque se puede notar
un pequeño incremento en la cantidad de tiempo para realizar su tarea programada y en el
error debido a esta carga extra.
El robot desarrollado no cumplió satisfactoriamente con la precisión y la repetibilidad
buscada, ya que existen pequeñas fricciones entre las piezas que afectan el movimiento del
robot, así como un pequeño desacoplo mecánico entre los dos eslabones rotacionales
provocados por la estructura física de los motores utilizados, aun siendo estos los más aptos
para esta aplicación. La precisión de posicionamiento real en el robot está en el rango de ±1.1
mm aproximadamente y el error promedio en la repetibilidad de 0.28 mm, como se analizó
en el desarrollo del proyecto ambos resultados no coinciden con los valores señalados en las
características del robot; pero se pueden corregir modificando algunas piezas del robot y con
el uso de técnicas de control más sofisticadas.
El costo total del robot en general cumple con lo planteado en el proyecto, donde el costo
total es de $24,342 haciendo del mimo un robot accesible para empresas pequeñas, medianas
o grandes. Si consideramos la versatilidad que tiene el robot, se puede adaptar a diferentes
tareas que sean requeridas, siempre y cuando cumplan con las limitaciones en el robot, como
son el seguimiento de posiciones dentro del espacio de trabajo o mover objetos con un peso
menor a 1kg.
Algunas mejoras en el robot serián adecuación de una pinza en el efector final para tareas
de paletizado y agregar visión artificial para selección de objetos. Estas mejoras ayudarán al
robot a ampliar su campo de trabajo y lo hará más competitivo.
Por último, el presente trabajo generó grandes competencias en el diseño, construcción y
control de robots, mismas que pueden ser utilizadas no sólo en este tipo de robots, si no en
cualquier otro. Se tomaron en cuenta los detalles prácticos de fabricación y ensamblaje así
como la de control con el fin de no cometer errores futuros en próximos diseños con robots.
83
Referencias
[16] A. Ollero. Robótica, Manipuladores y robots móviles. Ed. Marcombo. Barcelona. 2001.
pp. 80–94.
[17] C. Rouff, “Fast Trigonometric Functions for Robot Control”, Robotics age, Noviembre
de 1981.
[18] S. Gómez. “Análisis estático,” SolidWorks Simulation, 1st. ed. México.
[19] R. Budynas y J. Nisbett. Diseño en ingeniería mecánia de Shigley. Ed. McGraw Hill.
México. 2008. pp. 4,137-147.
[20] R. Hibbeler. Dinámica. Ed. Pearson. México. 2010. pp. 395–412.
[21] R. Kelly and V. Santibáñez y A. Loría, Control of Robots Manipulators in Joint Space.
Springer-Verlag. Londres. 2005.
[22] Pittman DC Motor: http://www.pittman-motors.com/Gearboxes-Brakes-
Encoders/Encoders.aspx
[23] Tapared Roller Bearings: http://www.skf.com/mx/products/bearings-units-
housings/roller-bearings/tapered-roller-bearings/single-row-tapered-roller-bearings/single-
row/index.html
[24] J. Craig, “A Generic Motor Driver Design for Mobile Robotic Platform,”. M.S. thesis,
Dept. Electron. Eng., Waikato Univ., Hamilton, New Zealand, 2004.
[25] ST Dual Full-Bridge Driver:
https://www.sparkfun.com/datasheets/Robotics/L298_H_Bridge.pdf
[26] J. Heidenhain. (2014, Abril.). Manual de Aplicación de Encoders.West Instruments de
México.,DF. México. [Online]. Available: http://www.westmexico.com.mx/
[27] E. Silge (2012, Octubre.). Encoder Incremental Descripción General. Eltra., Buenos
Aires. Argentina. [Online]. Available: http://www.silge.com.ar/
[28] L. Sciavicco y B. Siciliano, Modelling and Control of Robot Manipulators.2da.ed
Springer-Verlag. Londres. 2000.
[29] W. Khalil y E. Dembre, “Modeling identification and control of robots”, Hermes Penton
Science. 2002. pp.347-376.
[30] J. J. Craig, “Robótica”, Prentice Hall Pearson, 3ra. Ed., 2006.
[31] Graphical User Interfaces MathWorks:http://www.mathworks.com/discovery/matlab-
gui.html?s_tid=srchtitle
[32] International Standard ISO 9283. (1998). “Manipulating industrial robots Performance
criteria and related test methods”. Second edition.
85
Apéndices
float contadorX = 0;
float contadorX2 = 0;
float contadorX3 = 0;
//VARIABLES DE POSICIONES REALES
float posX = 0;
float posX2 = 0;
float posX3 = 0;
//VARIABLES DE POSICIONES DESEADAS
float posDesX =0;
float posDesX2=0;
float posDesX3=0;
//VARIABLES DE POSICIONES ANTERIORES
float posant = 0;
float posant2 = 0;
float posant3 = 0;
// POSICION HOME
const int posH =-90;
//VARIABLES DE VELOCIDAD
float velx = 0;
float velx2 = 0;
float velx3 = 0;
float previous_error=0;
float previous_error2=0;
float previous_error3=0;
float velDesX = 0;
float velEstX=0;
float errorVelX = 0;
//VARIABLES ERROR DE POSICION
float errorPosX = 0;
float errorPosX2 = 0;
float errorPosX3 = 0;
float errorPosXerror = 0;
float intErrorPosX=0;
112
float voltMotorX = 0;
float intErrorPosXVelX=0;
//VARIABLES DE PWM
int pwm = 0;
int pwmm = 0;
int pwm2 = 0;
int pwm3 = 0;
//VARIABLES DE TIEMPO
float dt = 0.01; //Tiempo de muestreo para control y calculo de velocidades
float tiempoInicio = 0;
int bandera = 0;
int bandera2 = 0;
int band= 0;
int bando=0;
int bandito=0;
int iniciar1=0;
int iniciar2=0;
int k = 0;
//VARIABLES DE INTEGRACION
float integral1 = 0;
float integral2 = 0;
float integral3 = 0;
//VARIABLES DE PID
float PID =0;
float PID2 =0;
float PID3 =0;
//VARIABLES DE CONTROL
float x3 = 0;
float y3 = 0;
float z3 = 0;
//Variables para trayectorias de referencia
float x0 = 37;
float y0 = 0;
113
float x1 = 0;
float x2 = 0;
float tiempoConstante = 0;
float tiempoConstante2 = 0;
float tiempoConstante3 = 0;
float posXant = 0;
float posYant = 0;
float posY = 0;
float posDesY = 0;
float errorPosY = 0;
float intErrorPosY=0;
float voltMotorY = 0;
float PWMMotorY = 0;
float velEstY=0;
float vely = 0;
float velDesY = 0;
float velDesY2 = 0;
float velDesY3 = 0;
float velDesX2= 0;
float velDesX3= 0;
//Variables para transmision de datos
int s=0;
int s1=0;
int pinicio=0;
char b = '0';
int bz=0;
int bz2=0;
int bz3=0;
int dato = 0;
int signo = 1;
float u = 0;
float y = 0;
float z = 0;
115
int posantpositiva=0;
int posantpositiva2=0;
int posantpositiva3=0;
//Constantes para SENSORES
const int sensor1 = 26; // Pulsador
const int sensor2= 27;
const int sensor3 = 28;
const int sensor4= 29;
const int sensor5 = 30;
const int sensor6= 31;
//HOME
float val = 0; //val se emplea para almacenar el estado del boton
int valor = 0;
int val2 = 0;
int valor2 = 0;
int val3 = 0;
int old_val=0;
int old_val2=0;
int old_val3=0;
int state=0;
int state2=0;
//Variables para la memoria eeprom
byte ee_valor0;
byte ee_valor1;
byte ee_valor2;
byte ee_valor3;
byte ee_valor4;
byte ee_valor5;
int posantp=0;
int posantn=0;
//Rutinas para recibir datos y escribir
void recibir(){
if ((b>47)&&(b<58)){
116
dato=dato*10+b-48;
}
if (b=='-'){
signo=-1;
}
if (b=='x'){
x3=dato;
x3=x3/100*signo;
posDesX=x3;
dato=0;
signo=1;
}
if (b=='y'){
y3=dato;
y3=y3/100*signo;
posDesX2=y3;
dato=0;
signo=1;
}
if (b=='z'){
z3=dato;
z3=z3/100*signo;
posDesX3=z3;
dato=0;
signo=1;
}
}
void escribir(float variable){
if (variable<0){
Serial.print('-');
Serial.println(round(-1*variable*10),DEC);
}
else
117
{
Serial.println(round(variable*10),DEC);
}
}
void setup()
{
// put your setup code here, to run once:
Serial.begin(9600);
//ASIGNACION DE INTERRUPCION
attachInterrupt( 0, IntEncoderX, RISING);
attachInterrupt( 4, IntEncoderX2, RISING);
attachInterrupt( 3, IntEncoderX3, RISING);
//ASIGNACION DE PINES DE INCODER
pinMode(encoderXA, INPUT);
pinMode(encoderXB, INPUT);
pinMode(encoderXA2, INPUT);
pinMode(encoderXB2, INPUT);
pinMode(encoderXA3, INPUT);
pinMode(encoderXB3, INPUT);
//ASIGNACION DE PINES DE PWM Y IN
pinMode(motorXp, OUTPUT);
pinMode(motorXn, OUTPUT);
pinMode(motorXnp, OUTPUT);
pinMode(motorXp2, OUTPUT);
pinMode(motorXn2, OUTPUT);
pinMode(motorXnp2, OUTPUT);
pinMode(motorXp3, OUTPUT);
pinMode(motorXn3, OUTPUT);
pinMode(motorXn3, OUTPUT);
//ASIGNACION DE PINES DE SENSORES
pinMode(sensor1, INPUT);
pinMode(sensor2, INPUT);
pinMode(sensor3, INPUT);
118
analogWrite(motorXp3,LOW);
digitalWrite (motorXn3,LOW);
digitalWrite (motorXnp,LOW);
}
if (ee_valor0>0){
posDesX=-1*(ee_valor0);
}
if (ee_valor1>0){
posDesX=ee_valor1;
}
if (ee_valor2>0){
posDesX2=-1*(ee_valor2);
}
if (ee_valor3>0){
posDesX2=ee_valor3;
}
if (ee_valor4>0){
posDesX3=-1*(ee_valor4);
}
if (ee_valor5>0){
posDesX3=ee_valor5;
}
}
if (b=='N'){//Motores desenergizados
analogWrite(motorXp,LOW);
digitalWrite(motorXn,LOW);
digitalWrite(motorXnp,LOW);
analogWrite(motorXp2,LOW);
digitalWrite(motorXn2,LOW);
digitalWrite(motorXnp2,LOW);
analogWrite(motorXp3,LOW);
digitalWrite(motorXn3,LOW);
digitalWrite(motorXnp3,LOW);
120
}
if (b=='O'){//Tray
x0=posX;
y0=posY;
x11=x11+x0;
y11=y11+y0;
x22=x22+x0;
y22=y22+y0;
x3=x3+x0;
y3=y3+y0;
x44=x44+x0;
y44=y44+y0;
posDesX=posX;
posDesY=posY;
posXant=posX;
posYant=posY;
intErrorPosX=0;
intErrorPosY=0;
velEstX=0;
velEstY=0;
D=sqrt((x3-x11)*(x3-x11)+(y3-y11)*(y3-y11)); //Distancia1
D2=sqrt((x3-x22)*(x3-x22)+(y3-y22)*(y3-y22)); //Distancia2
D3=sqrt((x3-x44)*(x3-x44)+(y3-y44)*(y3-y44)); //Distancia3
P= 0.5*velMax*velMax/acelMax;//Distancia de aceleración constante1
P2=0.5*velMax2*velMax2/acelMax2;//Distancia de aceleración constante2
P3=0.5*velMax3*velMax3/acelMax3;//Distancia de aceleración constante3
velMaxY=velMax/sqrt(1+((x3-x11)*(x3-x11)+(y3-y11)*(y3-y11)));
velMaxX=velMax/sqrt(1+((y3-y11)*(y3-y11)+(x3-x11)*(x3-x11)));
velMaxY2=velMax2/sqrt(1+((x3-x22)*(x3-x22)+(y3-y22)*(y3-y22)));
velMaxX2=velMax2/sqrt(1+((y3-y22)*(y3-y22))/((x3-x22)*(x3-x22)));
velMaxY3=velMax3/sqrt(1+((x3-x44)*(x3-x44))/((y3-y44)*(y3-y44)));
velMaxX3=velMax3/sqrt(1+((y3-y44)*(y3-y44))/((x3-x44)*(x3-x44)));
acelMaxX=0.5*velMaxX*velMaxX/abs(P*(x3-x11)/D);
121
acelMaxY=0.5*velMaxY*velMaxY/abs(P*(y3-y11)/D);
acelMaxX2=0.5*velMaxX2*velMaxX2/abs(P*(x3-x22)/D2);
acelMaxY2=0.5*velMaxY2*velMaxY2/abs(P*(y3-y22)/D2);
acelMaxX3=0.5*velMaxX3*velMaxX3/abs(P*(x3-x44)/D2);
acelMaxY3=0.5*velMaxY3*velMaxY3/abs(P*(y3-y44)/D2);
tiempoConstante=abs((x3-x11)*(1-2*P/D)/velMaxX);//Tiempo de velocidad constante
tiempoConstante2=abs((x3-x22)*(1-2*P2/D2)/velMaxX2);//Tiempo de velocidad
constante
tiempoConstante3=abs((x3-x44)*(1-2*P3/D3)/velMaxX3);//Tiempo de velocidad
constante
tiempoP=abs(velMaxX/acelMaxX); //Tiempo de aceleración constante
tiempoP2=abs(velMaxX2/acelMaxX2);
tiempoP3=abs(velMaxX3/acelMaxX3);
k=0;
s=0;
if ((x3-x11)<0){
velMaxX=velMaxX*(-1);
acelMaxX=acelMaxX*(-1);}
if ((y3-y11)<0){
velMaxY=velMaxY*(-1);
acelMaxY=acelMaxY*(-1);}
if ((x3-x22)<0){
velMaxX2=velMaxX2*(-1);
acelMaxX2=acelMaxX2*(-1);}
if ((y3-y22)<0){
velMaxY2=velMaxY2*(-1);
acelMaxY2=acelMaxY2*(-1);}
if ((x3-x44)<0){
velMaxX3=velMaxX3*(-1);
acelMaxX3=acelMaxX3*(-1);}
if ((y3-y44)<0){
velMaxY3=velMaxY3*(-1);
122
acelMaxY3=acelMaxY3*(-1);}
}
if (b=='F'){//Recibir datos
bandera2=1;
}
else {
recibir();
}
}
// Control de Posicion inicial
if ((iniciar1 == 1) && (old_val == LOW)){
analogWrite(motorXp,LOW);
digitalWrite (motorXn,LOW);
digitalWrite (motorXnp,LOW);
delay(1000);
}
if ((val == LOW) && (old_val == LOW)){
state=1-state;
delay(10);
}
old_val = val; // valor del antiguo estado
if (state==1){
//bandera=1;
valor=1;
posDesX=-90;
posX=0;
contadorX=0;
errorPosX=0;
velx=0;
integral1=0;
PID=0;
delay(100);
123
}
if ((iniciar2 == 1) && (old_val2 == LOW)){
analogWrite(motorXp2,LOW);
digitalWrite (motorXn2,LOW);
digitalWrite (motorXnp2,LOW);
delay(1000);
}
if ((val2 == LOW) && (old_val2 == LOW)){
state2=1-state2;
delay(10);
}
old_val2 = val2; // valor del antiguo estado
if (state2==1){
valor2=1;
posDesX2=-90;
posX2=0;
contadorX2=0;
errorPosX2=0;
velx2=0;
integral2=0;
PID2=0;
delay(100);
}
if ((valor==1) && (valor2==1)){
bandera=1;
}
else{
bandera=0;
}
//Control
while ((bandera==1) || (bandera2==1)){
tiempoInicio=millis();
124
k=k++;
//Calcular posicion y velocidad reales en mm a partir de encoders
posX=(contadorX*360)/9750; //Conversion a grados
posX2=(contadorX2*360)/9750; //Conversion a grados
posX3=(contadorX3*16/25.4); //Conversion lineal,vueltas por pulgadas
//CALCULO DE ERROR DE POSICION
errorPosX=posDesX-posX;
errorPosX2=posDesX2-posX2;
errorPosX3=posDesX3-posX3;
//CALCULO DE LA PARTE DERIVATIVA
velx=(errorPosX-previous_error)/dt; //VELOCIDAD ESTIMADA
velx2=(errorPosX2-previous_error2)/dt; //VELOCIDAD ESTIMADA
velx3=(errorPosX3-previous_error3)/dt; //VELOCIDAD ESTIMADA
//CALCULO DE LA PARTE INTEGRAL
integral1= integral1+(dt*errorPosX); //ERROR ACTUAL =integral del error
integral2= integral2+(dt*errorPosX2); //ERROR ACTUAL =integral del error
integral3= integral3+(dt*errorPosX3); //ERROR ACTUAL =integral del error
//velocidades de referencia
if (k*dt<tiempoP){
velDesX=acelMaxX*(k*dt);
velDesY=acelMaxY*(k*dt);
}
if ((k*dt>tiempoP)&(k*dt<tiempoP+tiempoConstante)){
velDesX=velMaxX;
velDesY=velMaxY;
}
if ((k*dt>tiempoP+tiempoConstante)&(k*dt<2*tiempoP+tiempoConstante)){
velDesX=velMaxX-(k*dt-tiempoP-tiempoConstante)*acelMaxX;
velDesY=velMaxY-(k*dt-tiempoP-tiempoConstante)*acelMaxY;
}
if (k*dt>(2*tiempoP+tiempoConstante)){
velDesX=0;
velDesY=0;
125
}
if (k*dt<tiempoP2){
velDesX2=acelMaxX2*(k*dt);
velDesY2=acelMaxY2*(k*dt);
}
if ((k*dt>tiempoP2)&(k*dt<tiempoP2+tiempoConstante2)){
velDesX2=velMaxX2;
velDesY2=velMaxY2;
}
if ((k*dt>tiempoP2+tiempoConstante2)&(k*dt<2*tiempoP2+tiempoConstante2)){
velDesX2=velMaxX2-(k*dt-tiempoP2-tiempoConstante2)*acelMaxX2;
velDesY2=velMaxY2-(k*dt-tiempoP2-tiempoConstante2)*acelMaxY2;
}
if (k*dt>(2*tiempoP2+tiempoConstante2)){
velDesX2=0;
velDesY2=0;
}
if (k*dt<tiempoP3){
velDesX3=acelMaxX3*(k*dt);
velDesY3=acelMaxY3*(k*dt);
}
if ((k*dt>tiempoP3)&(k*dt<tiempoP3+tiempoConstante3)){
velDesX3=velMaxX3;
velDesY3=velMaxY3;
}
if ((k*dt>tiempoP3+tiempoConstante3)&(k*dt<2*tiempoP3+tiempoConstante3)){
velDesX3=velMaxX3-(k*dt-tiempoP3-tiempoConstante3)*acelMaxX3;
velDesY3=velMaxY3-(k*dt-tiempoP3-tiempoConstante3)*acelMaxY3;
}
if (k*dt>(2*tiempoP3+tiempoConstante3)){
velDesX3=0;
velDesY3=0;
}
126
posDesX=posDesX+velDesX*dt;
posDesY=posDesY+velDesY*dt;
posDesX2=posDesX2+velDesX2*dt;
posDesY2=posDesY2+velDesY2*dt;
posDesX3=posDesX3+velDesX3*dt;
posDesY3=posDesY3+velDesY3*dt;
//CONTROLADOR PID
PID = (kp*errorPosX)+(ki*integral1)+(kd*velx);//CONTROLADOR PID1
PID2= (kp2*errorPosX2)+(ki2*integral2)+(kd2*velx2);//CONTROLADOR PID2
PID3= (kp3*errorPosX3)+(ki3*integral3)+(kd3*velx3);//CONTROLADOR PID3
//Control de PWMs
pwm=(abs(PID)*255)/11.96;
pwm2=(abs(PID2)*255)/11.96;
pwm3=(abs(PID3)*255)/11.96;
//Control a PWMs
if (PID2<0){//DER
analogWrite(motorXp2,pwm2);
digitalWrite(motorXn2,LOW);
digitalWrite(motorXnp2,HIGH);
}
if (PID3>=0){//IZQ
analogWrite(motorXp3,pwm3);
digitalWrite(motorXn3,HIGH);
digitalWrite(motorXnp3,LOW);
}
if (PID3<0){//DER
analogWrite(motorXp3,pwm3);
digitalWrite(motorXn3,LOW);
digitalWrite(motorXnp3,HIGH);
}
//Enviar info a puerto serial cada 7 dt
s++;
if (s==7){
escribir(posX);
escribir(posX2);
escribir(posX3);
escribir(errorPosX);
escribir(errorPosX2);
escribir(errorPosX3);
escribir(bandera);
s=0;
}
//Guardar posición anterior para calcular velocidad
posant=posX;
posant2=posX2;
posant3=posX3;
previous_error=errorPosX;
previous_error2=errorPosX2;
128
previous_error3=errorPosX3;
//Almacenamiento de posiciones
posantpositiva=abs(posant);
if (posant>0){
EEPROM.write(0, posant);
EEPROM.write(1, 0);
}
if (posant<0){
EEPROM.write(1, posantpositiva);
EEPROM.write(0, 0);
}
posantpositiva2=abs(posant2);
if (posant2>0){
EEPROM.write(2, posant2);
EEPROM.write(3, 0);
}
if (posant2<0){
EEPROM.write(2, posantpositiva2);
EEPROM.write(3, 0);
}
posantpositiva3=abs(posant3);
if (posant3>0){
EEPROM.write(4, posant2);
EEPROM.write(5, 0);
}
if (posant2<0){
EEPROM.write(4, posantpositiva2);
EEPROM.write(5, 0);
}
//Ajuste para tiempo de muestreo fijo
while((millis()-tiempoInicio)<(dt*1000)){
}
129
if ((abs(posDesX-posX)<0.1)&&(abs(posDesX2-posX2)<0.1)){
bandera=-1;
escribir(posX);
escribir(posX2);
escribir(posX3);
escribir(errorPosX);
escribir(errorPosX2);
escribir(errorPosX3);
escribir(bandera);
analogWrite(motorXp,LOW);
digitalWrite(motorXn,LOW);
digitalWrite(motorXnp,LOW);
analogWrite(motorXp2,LOW);
digitalWrite(motorXn2,LOW);
digitalWrite(motorXnp2,LOW);
analogWrite(motorXp3,LOW);
digitalWrite(motorXn3,LOW);
digitalWrite(motorXnp3,LOW);
}
}
}
//Interrupción encoder posición M1
void IntEncoderX()
{ if (digitalRead(encoderXA)==digitalRead(encoderXB)){
contadorX++ ;}
else{
contadorX-- ;}
}
//Interrupción encoder posición M2
void IntEncoderX2()
{ if (digitalRead(encoderXA2)==digitalRead(encoderXB2)){
contadorX2++ ;}
130
else{
contadorX2-- ;}
}
//Interrupción encoder posición M3
void IntEncoderX3()
{ if (digitalRead(encoderXA3)==digitalRead(encoderXB3)){
contadorX3++ ;}
else{
contadorX3-- ;}
}
131
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
132
% --- Outputs from this function are returned to the command line.
function varargout = SCARA_CONTROL_FINAL_OutputFcn(hObject, eventdata,
handles)
% varargout cell array for returning output args (see VARARGOUT);
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
vposz=[];
ve1=[];
ve2=[];
ve3=[];
vt=[];
% Se guardan los datos introducidos en el vector
p(1) = str2double(get(handles.edit_p1, 'String'));
p(2) = str2double(get(handles.edit_p2, 'String'));
p(3) = str2double(get(handles.edit_p3, 'String'));
% Se resuelve el problema cinematico directo con los resultados
q=cinematicaInversa(p)
Px = p(1);
Py = p(2);
Pz = p(3);
% Se pasan los ángulos de radines a grados
q(2)=acos((Px*Px+Py*Py-l2*l2-l3*l3)/(2*l2*l3));
q2=q(2)*57.2958;
t1=(atan2(Py,Px))*180/pi;
A1(1)=t1-((atan2(-sqrt((4*l2^2*(Px^2+Py^2))-(Px^2+Py^2+l2^2-
l3^2)^2),(Px^2+Py^2+l2^2-l3^2)))*180/pi);
A1(2)=t1-((atan2(sqrt((4*l2^2*(Px^2+Py^2))-(Px^2+Py^2+l2^2-
l3^2)^2),(Px^2+Py^2+l2^2-l3^2)))*180/pi);
q3=l1-l4-Pz;
while(a)
x2=l2*cosd(A1(x));
y2=l2*sind(A1(x));
z2=l1;
x3=l3*cosd(A1(x)+A2(y))+l2*cosd(A1(x));
y3=l3*sind(A1(x)+A2(y))+l2*sind(A1(x));
z3=l1;
x3=round(x3);
y3=round(y3);
if (x3==Px)
a=0;
A1=A1(x);
q1=A1;
end
x=x+1;
if (x==3)
x=1;
end
end
G01(PS,q1,q2,q3);
%Se actualizan los datos de la cinemática directa
set(handles.text15,'String', q1);
set(handles.text16,'String', q2);
set(handles.text32,'String', q3);
if bandera<1;
set(handles.text33,'String','Posicionamiento realizado con exito!');
end
fclose(PS);
delete(PS);
clear PS;
instrreset
%Graficas de posiciones
figure(1)
134
subplot(3,1,1);plot(vt,vposx,'b-');grid minor;xlabel('Tiempo
(s)');ylabel('Posición (m)');title('Px real'); hold on
plot(vt, p(1),'r-')
subplot(3,1,2);plot(vt,vposy,'b-');grid minor;xlabel('Tiempo
(s)');ylabel('Posición (m)');title('Py real'); hold on;
plot(vt, p(2),'r-');
subplot(3,1,3);plot(vt,vposz,'b-');grid minor ;xlabel('Tiempo
(s)');ylabel('Posición (m)');title('Pz real');hold on;
plot(vt, p(3),'r-');
%Graficas de errores
figure(2)
subplot(3,1,1);plot(vt,ve1,'b-'); grid on;xlabel('Tiempo
(s)');ylabel('Posición (m)');title('Error en Px'); hold on;
subplot(3,1,2);plot(vt,ve2,'b-');grid on;xlabel('Tiempo
(s)');ylabel('Posición (m)');title('Error en Py'); hold on;
subplot(3,1,3);plot(vt,ve3,'b-');grid on;xlabel('Tiempo
(s)');ylabel('Posición (m)');title('Error en Pz'); hold on;
end
set(handles.text33,'String','');
global PS vposx vposy vposz vt ve1 a b c ve2 ve3 bandera1 aa bb cc
conectarArduino;
fwrite(PS,'N','uchar');
%Variables del robot
l1=0.23;
l2=0.17;
l3=0.20;
l4=0.08;
vposx=[];%Vector donde se almacena la posicion 1
vposy=[];%Vector donde se almacena la posicion 2
vposz=[];%Vector donde se almacena la posicion 3
ve1=[];%Vector donde se almacena el error 1
ve2=[];%Vector donde se almacena el error 2
ve3=[];%Vector donde se almacena el error 3
vt=[];%Vector donde se almacena el tiempo
%Se crea un vector nulo q de 3 elementos
q = [0 0 0];
% Se guardan los valores introducidos en el vector q
q(1) = str2double(get(handles.edit_q1, 'String'));
q(2) = str2double(get(handles.edit_q2, 'String'));
q(3) = str2double(get(handles.edit_q3, 'String'));
aa=q(1);
bb=q(2);
cc=q(3);
%Envió de datos ha arduino
G01(PS,q(1),q(2),q(3));
%Cinemática directa resuelta
Px=l3*cosd(q(1)+ q(2))+l2*cosd(q(1));
Py=l3*sind(q(1)+ q(2))+l2*sind(q(1));
Pz=l1-q(3)-l4;
set(handles.text9,'String',Px);
set(handles.text10,'String',Py);
set(handles.text31,'String',Pz);
% Se resuelve el problema cinemático directo del robot
T = cinematicaDirecta(q);
set(handles.text18,'String',a);
set(handles.text19,'String',b);
set(handles.text20,'String',c);
if bandera1<1;
set(handles.text33,'String','Posicionamiento realizado con exito!');
end
fclose(PS);
delete(PS);
clear PS;
instrreset
% graficas de Posición
figure(1)
subplot(3,1,1);plot(vt,vposx,'b-');grid minor;xlabel('Tiempo
(s)');ylabel('Ángulo (º)');title('q1 real');
hold on;plot(vt,aa,'r-');
subplot(3,1,2);plot(vt,vposy,'b-');grid minor;xlabel('Tiempo
(s)');ylabel('Ángulo (º)');title('q2 real');
hold on;plot(vt,bb,'r-');
subplot(3,1,3);plot(vt,vposz,'b-');grid minor;xlabel('Tiempo
(s)');ylabel('Desplazamiento (m)');title('d real');
hold on;plot(vt,cc,'r-');
139
% graficas de error
figure(2)
subplot(3,1,1);plot(vt,ve1,'b-');grid minor;xlabel('Tiempo
(s)');ylabel('Grados (º)');title('Error en q1'); hold on;
subplot(3,1,2);plot(vt,ve2,'b-');grid minor;xlabel('Tiempo
(s)');ylabel('Grados (º)');title('Error en q2'); hold on;
subplot(3,1,3);plot(vt,ve3,'b-');grid minor;xlabel('Tiempo
(s)');ylabel('m');title('Eror en d'); hold on;
blah=get(handles.uibuttongroup1,'SelectedObject');
selection=get(blah,'String');
switch selection
case 'CINEMATICA DIRECTA'
%encendido de texto
set(handles.text7,'Enable','On')
set(handles.pushbutton_cd, 'Enable', 'On');
set(handles.edit_q1,'Enable','On')
set(handles.edit_q2,'Enable','On')
set(handles.edit_q3,'Enable','On')
%apagado de texto
set(handles.text33,'String','');
set(handles.edit_p1,'Enable','Off')
set(handles.edit_p2,'Enable','Off')
set(handles.edit_p3,'Enable','Off')
set(handles.pushbutton_ci, 'Enable', 'Off');
set(handles.pushbutton4, 'Enable', 'Off');
case 'CINEMATICA INVERSA'
set(handles.text33,'String','');
set(handles.pushbutton_ci, 'Enable', 'On');
%apagado de texto
set(handles.edit_q1,'Enable','Off')
set(handles.edit_q2,'Enable','Off')
set(handles.edit_q3,'Enable','Off')
set(handles.pushbutton_cd, 'Enable', 'Off');
set(handles.pushbutton4, 'Enable', 'Off');
%encendido de texto
set(handles.edit_p1,'Enable','On')
set(handles.edit_p2,'Enable','On')
set(handles.edit_p3,'Enable','On')
case 'TRAYECTORIAS'
%apagado de texto
set(handles.pushbutton_cd, 'Enable', 'Off');
set(handles.pushbutton_ci, 'Enable', 'Off');
set(handles.edit_p1,'Enable','Off')
set(handles.edit_p2,'Enable','Off')
set(handles.edit_p3,'Enable','Off')
set(handles.edit_q1,'Enable','Off')
set(handles.edit_q2,'Enable','Off')
set(handles.edit_q3,'Enable','Off')
%encendido de texto
set(handles.pushbutton4, 'Enable', 'On');
end
guidata(hObject,handles); %Salvar datos de la aplicación
141
subplot(3,1,2);plot(vt,vposy,'b-');grid minor;xlabel('Tiempo
(s)');ylabel('Posición (m)');title('Py real'); hold on;
plot(vt, p(2),'r-');
subplot(3,1,3);plot(vt,vposz,'b-');grid minor ;xlabel('Tiempo
(s)');ylabel('Posición (m)');title('Pz real');hold on;
plot(vt, p(3),'r-');
%Graficas de errores
figure(2)
subplot(3,1,1);plot(vt,ve1,'b-'); grid on;xlabel('Tiempo
(s)');ylabel('Posición (m)');title('Error en Px'); hold on;
subplot(3,1,2);plot(vt,ve2,'b-');grid on;xlabel('Tiempo
(s)');ylabel('Posición (m)');title('Error en Py'); hold on;
subplot(3,1,3);plot(vt,ve3,'b-');grid on;xlabel('Tiempo
(s)');ylabel('Posición (m)');title('Error en Pz'); hold on;
143
end
146