integraciÓn de sistema de visiÓn artificial...

135
Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place ESCUELA SUPERIOR DE INGENIEROS DE SEVILLA Ingeniería en Automática y Electrónica Industrial PROYECTO FIN DE CARRERA INTEGRACIÓN DE SISTEMA DE VISIÓN ARTIFICIAL Y ROBOT EN APLICACIÓN TIPO PICK&PLACE Autor: Francisco Javier Romero Galey Tutores: Manuel Vargas Villanueva Luis Fernando Castaño Castaño Ingeniería en Automática y Electrónica Industrial -

Upload: dokiet

Post on 26-Sep-2018

220 views

Category:

Documents


0 download

TRANSCRIPT

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place

ESCUELA SUPERIOR DE INGENIEROS DE SEVILLAIngeniería en Automática y Electrónica Industrial

PROYECTO FIN DE CARRERA

INTEGRACIÓN DE SISTEMA DE VISIÓN ARTIFICIAL Y ROBOT EN APLICACIÓN

TIPO PICK&PLACE

Autor: Francisco Javier Romero GaleyTutores: Manuel Vargas Villanueva

Luis Fernando Castaño Castaño

Ingeniería en Automática y Electrónica Industrial -

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place

Índice de contenido1Objetivo del proyecto......................................................................................................................... 42Descripción y justificación de los equipos utilizados.........................................................................5

2.1Descripción general del sistema................................................................................................. 52.2Sistema de visión artificial..........................................................................................................52.3Transportador de banda y servomotor brushless........................................................................ 62.4Robot SCARA............................................................................................................................ 82.5PC industrial y entorno de desarrollo C++............................................................................... 112.6Sistema de aire comprimido..................................................................................................... 12

3Fundamentos y algoritmos de visión artificial................................................................................. 133.1Descripción de los procesos utilizados..................................................................................... 133.2Preprocesamiento......................................................................................................................133.3Histograma................................................................................................................................133.4Umbral óptimo mediante método de Otsu................................................................................143.5Binarización de la imagen.........................................................................................................153.6Erosión binaria de la imagen.................................................................................................... 153.7Etiquetado y segmentación....................................................................................................... 163.8Análisis de características de cada objeto.................................................................................18

4Implementación del sistema de visión artificial............................................................................... 194.1Introducción.............................................................................................................................. 194.2Descripción de las librerías MIL-Lite.......................................................................................194.3Diagrama general de las clases utilizadas.................................................................................204.4Controles de adquisición de imagen......................................................................................... 224.5 Clases VARIANT y SAFEARRAY para contener imágenes................................................. 244.6Preprocesamiento. Filtrado de la mediana................................................................................324.7Histograma y umbral automático mediante Método de Otsu................................................... 344.8Implementación de la función de erosión................................................................................. 384.9Implementación de las funciones de etiquetado, segmentación, análisis de piezas y clasificación................................................................................................................................... 40

4.9.1Barrido y etiquetado inicial...............................................................................................404.9.2Agrupamiento de etiquetas en objetos.............................................................................. 424.9.3Análisis de piezas encontradas..........................................................................................434.9.4Coloreado de la imagen etiquetada e información en pantalla......................................... 454.9.5Almacenamiento de resultado final en variables globales................................................ 46

5Descripción del robot....................................................................................................................... 485.1Estructura y sistemas de referencia...........................................................................................485.2Software de programación, monitorización y mantenimiento..................................................495.3Lenguaje de programación MELFA BASIC IV....................................................................... 525.4Funciones para seguimiento de encoder (Tracking Function)..................................................535.5Función multitarea.................................................................................................................... 58

6Configuración y programación del Robot........................................................................................ 596.1Parámetros de configuración del robot..................................................................................... 59

6.1.1Parámetros generales.........................................................................................................596.1.2Parámetros de comunicaciones......................................................................................... 59

Ingeniería en Automática y Electrónica Industrial -

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place

6.1.3Parámetros para la función de tracking.............................................................................596.2Listado y descripción de los programas escritos para el robot................................................. 606.3Implementación de la función de tracking................................................................................616.4Procedimiento de calibración del encoder de banda.................................................................646.5Procedimiento de calibración del sistema de referencia del equipo de visión artificial........... 66

6.5.1Transformación entre Sistema de Visión y Sistema de Robot .........................................666.5.2Obtención de P_ORGV (traslación entre sistemas de referencia).................................... 686.5.3Obtención de βRV (rotación entre sistemas de referencia)...............................................70

6.6Ejecución multitarea de programas de manipulación y comunicaciones................................. 726.7Estructura de subrutinas del programa de comunicaciones...................................................... 736.8Criterio de ordenación de las posiciones detectadas.................................................................74

7Control de estados y comunicaciones en el PC................................................................................ 767.1Modos de trabajo y funciones relacionadas..............................................................................767.2Máquina de estados en C++ para control de secuencia............................................................ 787.3Control de comunicaciones Ethernet entre PC y Robot........................................................... 79

8Conclusiones.....................................................................................................................................849Bibliografía.......................................................................................................................................8510Listado de programas de C++ Builder............................................................................................86

10.1Código fuente principal VisionV7.cpp................................................................................... 8610.2Código fuente Unit1_VisionV7.cpp....................................................................................... 8610.3Código fuente Unit1_VisionV7.h......................................................................................... 119

11Listado de programas del robot.................................................................................................... 12311.1Programa MAIN.prg.............................................................................................................12311.2Programa COM.prg.............................................................................................................. 12411.3Programa CLE1.prg.............................................................................................................. 12611.4Programa CLE2.prg.............................................................................................................. 12611.5Programa CLV1.prg..............................................................................................................12711.6Programa CLV2.prg..............................................................................................................12711.7Programa CLV3.prg..............................................................................................................12811.8Programa CLV4.prg..............................................................................................................128

12Especificaciones técnicas de los equipos utilizados.....................................................................13012.1Robot RH5-AH55 controladora CR2A-572 MITSUBISHI ELECTRIC............................ 13012.2Cámara SONY XCD-V50.................................................................................................... 13212.3Tarjeta MATROX METEOR II/1394...................................................................................13312.4Servomotor MITSUBISHI ELECTRIC MRJ2S-A HCKFS................................................ 13412.5Bomba de vacío NORGREN M/58112................................................................................ 135

Ingeniería en Automática y Electrónica Industrial -

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place1 Objetivo del proyecto

1 Objetivo del proyectoEn este proyecto se integra una aplicación de manipulación (tipo pick&place) con robot y visión

artificial, con piezas sobre una cinta de transporte que está en movimiento durante la manipulación. Este tipo de aplicaciones están cada vez mas demandadas en diversos sectores como por ejemplo el sector de alimentación, puesto que el coste de la tecnología empleada es decreciente, mientras que el coste de la mano de obra empleada habitualmente para la manipulación es creciente. Además las exigencias del mercado en cuanto a controles de calidad automáticos es cada vez mayor, y también los requerimientos de envasado de los productos tanto individualmente como en grupos.

Un PC industrial con sistema de visión artificial inspecciona la cinta para localizar las piezas previamente, con algoritmos para prever que la imagen contenga un número de piezas variado, y seleccionar las que son correctas. Después comunica vía Ethernet las posiciones localizadas al robot. A partir de ahí el robot se hace cargo, leyendo continuamente un tren de pulsos de un encoder solidario al movimiento de la cinta para poder hacer un seguimiento de la posición de las piezas mientras la cinta se desplaza, y cogerla mientras la acompaña en su movimento.

El proyecto ha implicado, a grandes rasgos, las siguientes tareas:

1. Diseño de la aplicación en su conjunto.

2. Montaje y conexión de todos los equipos.

3. Programación en C++ de las rutinas de visión artificial y control general.

4. Programación del robot en MELFA BASIC IV (MITSUBISHI ELECTRIC).

Ingeniería en Automática y Electrónica Industrial 1-1

Ilustración 1: Modelado básico del sistema objeto del proyecto

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place2 Descripción y justificación de los equipos utilizados

2 Descripción y justificación de los equipos utilizados

2.1 Descripción general del sistemaEl sistema general consta de los elementos que se muestran esquemáticamente en , donde se

especifica además el tipo de comunicación establecida entre los distintos equipos. Además hay una serie de elementos auxiliares (cajas y bornas de conexión eléctrica, elementos mecánicos de acoplamiento, pupitre para PC, soporte para cámara, base para montaje del robot,..) puesto que aunque son necesarios, no son determinantes de la funcionalidad del sistema ni aportan información relevante para la comprensión del mismo.

2.2 Sistema de visión artificialEl sistema de visión artificial está compuesto a su vez por los siguientes elementos:

● Cámara monocromo modelo SONY XCD-V50 con CCD progresivo 1/3 VGA (640x480 pixeles) de 8bits(15/30/60fps) o 14bits(15/30fps), con posibilidad de trigger externo mediante señal TTL. Dispone de salida digital IEE1394b permitiendo hasta 800Mbps y la conexión de varias cámaras en la misma línea.

● Objetivo de 8,5mm 1:1.5 con rosca C estándar.

● Tarjeta Firewire IEEE1394 para PCI modelo MATROX METEOR II/1394.

Ingeniería en Automática y Electrónica Industrial 2-2

Ilustración 2: Equipos de la aplicación y tipo de comunicaciones o señales que los integran

Cinta transportadora de bandaCinta transportadora de banda

Robot SCARARobot SCARA

Sistema de visionSistema de vision

PC industrial táctilPC industrial táctil

IEEE 1394Firewire

Ethernet

ServomotorServomotor

RS232C

SSCNETEncoder

C++ Builder (Borland)C++ Builder (Borland)MIL Lite (Matrox)MIL Lite (Matrox)RT Tool (Mitsubishi Electric)RT Tool (Mitsubishi Electric)

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place2 Descripción y justificación de los equipos utilizados

● Librerías de software MIL Lite de MATROX, paquete básico que permite la configuración del sistema y de la cámara, la adquisición de la imagen, componente display para contener y mostrar la imagen en pantalla, y un componente para mostrar información adicional en el display de imagen. En la aplicación se utiliza la versión ActiveX. MATROX ofrece amplias posibilidades de tratamiento de imagen en el paquete completo MIL, pero no se ha utilizado puesto que el objeto del proyecto contempla la implementación de los algoritmos de preprocesado y procesado de imagen.

Se ha elegido un sistema digital IEEE1394 porque cada vez está mas implantado frente a los sistemas basados en “frame grabber” analógicos. La conexión se simplifica pudiendo utilizar practicamente cualquier PC estándar. Además la conexión de múltiples cámaras es muy simple puesto que las tarjetas IEE1394 incluyen varios puertos, e incluso con IEE1394b es posible la conexión múltiple en un único puerto.

Por otra parte, se ha utilizado un sistema basado en PC frente a un sistema cerrado para poder desarrollar los algoritmos de control, además de tratarse de un sistema relativamente más económico (puesto que no se adquiere software, únicamente el hardware necesario).

2.3 Transportador de banda y servomotor brushlessPara el transporte de las piezas se utiliza un transportador de banda modelo GUF-P 2000 AA de

MK-system con una longitud L=1500mm y un ancho de banda B=250mm, que son medidas adecuadas al alcance de la aplicación. El transportador soporta 75Kg de carga y 80m/min., ambas características son sobradamente suficientes para el objetivo del proyecto. El diámetro del rodillo de arastre es de 52mm.

Ingeniería en Automática y Electrónica Industrial 2-3

Ilustración 3: Sistema de visión artificial: librerías MIL, tarjeta IEEE1394 y cámara

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place2 Descripción y justificación de los equipos utilizados

Para el accionamiento del transportador se ha montado un servomotor modelo HC-KFS43 de MITSUBISHI ELECTRIC con servodriver modelo MRJ2S. Este motor es tipo brushless AC con encoder absoluto de 17bits (131072 pulsos / revolución) y el servodriver tienen una conexión de bus digital tipo SSCNET II de MITSUBISHI ELECTRIC que permite integrarlo en el robot.

Además el servodriver tiene una conexión RS232C que se ha llevado al puerto COM1 del PC, de modo que desde el software de configuración y monitorización de estos equipos se puede configurar

Ingeniería en Automática y Electrónica Industrial 2-4

Ilustración 4: Transportador de banda

Ilustración 5: Servoaccionamiento para banda

Ilustración 6: Expresiones para el avance lineal de banda

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place2 Descripción y justificación de los equipos utilizados

el servo, e incluso poner en funcionamiento en modo test, tanto de forma continua en velocidad constante (Modo JOG) como realizando un posicionado (Modo POSITIONING). Para el objetivo de este proyecto, el modo de trabajo será JOG para la manipulación en contínuo de las piezas.

El objetivo de este servoaccionamiento es doble, porque además de generar el movimiento del transportador, ofrece una salida de pulsos configurable réplica del movimiento de su eje, y actúa por tanto como un encoder conectado a la banda, que en este caso se configurará a 4000 pulsos/vuelta.

La conexión mecánica del servomotor al transportador de banda se ejecuta mediante poleas de transmisión y correa dentada de paso normalizado XL (ver Ilustración 7: Poleas de transmisiónpaso XL para correa dentada).

Teniendo en cuenta esta relación de transmisión (17 a 34 dientes), y el diámetro del rodillo de arrastre se obtienen las relaciones de transmisión necesarias entre el motor y el movimiento lineal de la banda. Hay que considerar que el robot admite una velocidad máxima lineal de 20m/min para su función de tracking, que se utilizará para acompañar los productos durante la cogida. Se obtiene así la velocidad máxima del motor en esta circunstancia (ver Ilustración 6: Expresiones para elavance lineal de banda).

2.4 Robot SCARAEl robot utilizado es el modelo RH5-AH55 de MITSUBISHI ELECTRIC, con configuración

SCARA de 4 ejes, carga nominal 5Kg y radio de alcance 550mm. Este robot es ideal para

Ingeniería en Automática y Electrónica Industrial 2-5

Ilustración 7: Poleas de transmisión paso XL para correa dentada

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place2 Descripción y justificación de los equipos utilizados

aplicaciones de Pick&Place en un plano horizontal por la alta velocidad que ofrece (0,48seg en ciclo estándar de 25mm vertical + 300mm horizontal + 25mm vertical, y vuelta) y por el ventajoso coste al tener 4 ejes frente a los 6 ejes de un robot antropomórfico. Ofrece una repetibilidad de 0,02mm en X-Y y 0,01mm en Z.

En Ilustración 11: Componentes principales del robot RH5 se detalla la composición de motores y reductores del brazo del robot.

Además se dispone de una consola de mano “teaching Box” modelo R28TB (Ilustración 9:Teaching Box)para el control manual del robot, acceso a programa y variables, etc.

Ingeniería en Automática y Electrónica Industrial 2-6

Ilustración 8: Robot SCARA modelo RH5-AH55 de MITSUBISHI ELECTRIC

Ilustración 9: Teaching Box

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place2 Descripción y justificación de los equipos utilizados

En la unidad de control se han montado las siguientes tarjetas adicionales (Ilustración 10:Controlador del robot y tarjetas adicionales):

● SLOT1: Tarjeta ETHERNET modelo 2A-HR533-E para conexión con el PC. Por esta tarjeta se establece la conexión con el software de programación y monitorización del robot, además del intercambio de datos con la aplicación desarrollada en C++ para enviar las posiciones de las piezas a coger, y otras variables de control.

● SLOT 2: Tarjeta SERIE+ENCODER modelo 2A-RZ581-E, que dispone de 2 puertos RS422

Ingeniería en Automática y Electrónica Industrial 2-7

Ilustración 11: Componentes principales del robot RH5

Ilustración 10: Controlador del robot y tarjetas adicionales

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place2 Descripción y justificación de los equipos utilizados

(no utilizados en esta aplicación) y 2 puertos para entrada de encoder con señal Line Driver, que permitirán al robot hacer un seguimiento de las posiciones objetivos con el movimiento de la banda, utilizando un control continuo sobre esta variable contador de pulsos. Para ello el robot dispone de funciones de TRACKING que se explicarán detalladamente, y trabaja con una velocidad de cinta de hasta 20m/min.

● SLOT 3: Tarjeta EJE ADICIONAL modelo 2A-RZ541-E que permite al robot añadir servomotores adicionales, integrados digitalmente en el bus de su controlador, de modo que es posible incluso la interpolación con los ejes propios del robot. En este caso se configurará como un mecanismo adicional independiente, con el propósito de mantener el movimiento de la cinta transportadora.

2.5 PC industrial y entorno de desarrollo C++Para el control del sistema de visión y enlace con el robot se utiliza un PC industrial tipo panel

táctil, modelo IPC-BP1151 de MITSUBISHI ELECTRIC, con sistema operativo Window 2000 Profesional. Este tipo de PC destaca por sus características de robustez por su alta protección frente a temperatura, vibraciones, salpicaduras de agua, etc. Dispone de un procesador Celeron 1200MHz y 256MB de RAM

Para el desarrollo de la aplicación se utiliza el entorno C++ Builder 2006 de BORLAND, por las siguientes razones:

● La programación en C++ permite el control al nivel adecuado para las rutinas de visión, y su estandarización no deja lugar a dudas.

● Se utiliza un entorno visual para poder conseguir una interfaz potente y funcional, con el apoyo de los componentes visuales prediseñados que ofrecen este tipo de entornos.

● Se podría haber implementado igualmente en Visual C, de hecho las librerías MIL Lite ofrecen soporte para este entorno y no para el de Borland, no obstante he utilizado el C++ Builder puesto que los paquetes de Borland, sobre todo Delphi (que utiliza Pascal orientado a objetos) están muy valorados en las aplicaciones industriales,.. y al fin y al cabo alguno tenía que coger.

Ingeniería en Automática y Electrónica Industrial 2-8

Ilustración 12: PC industrial táctil formato panel

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place2 Descripción y justificación de los equipos utilizados

2.6 Sistema de aire comprimido

Para la cogida de las piezas se ha fabricado una pieza mecánica que se acopla al eje final del robot y aloja una ventosa de doble fuelle. El diseño es hueco para conducir el tubo por el interior del eje del robot (también hueco) hasta la ventosa. La depresión se genera con un bomba de vacío de una etapa efecto venturi modelo M/58112/11 de NORGREN.

El control de la actuación la realiza el propio robot, activando con una salida digital a transistor un circuito de 24VDC que acciona la electroválvula correspondiente, alojada en la base del robot. El generador de vacío se ha colocado lo más cerca posble de la ventosa, para minimizar el volumen de aire a evacuar y conseguir así el menor tiempo de respuesta posible.

Ingeniería en Automática y Electrónica Industrial 2-9

Ilustración 13: Bomba de vacío de una etapa

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place3 Fundamentos y algoritmos de visión artificial

3 Fundamentos y algoritmos de visión artificial

3.1 Descripción de los procesos utilizadosEn esta aplicación el problema de visión artificial que se plantea es la discriminación y

localización de una serie de objetos, concretamente discos circulares blancos, sobre una banda de transporte oscura. La cámara proporciona imágenes de resolución 640x480 en tonos de grises con una profundidad de 8 bits, es decir, con 256 niveles de grises. No obstante se puede fijar un factor de escalado para bajar la resolución y aumentar la velocidad de proceso, y así se hará trabajndo con imágenes de 320x240. Los algoritmos que se aplicarán sobre la imagen original serán los siguientes, en el orden indicado:

1. Captura de la imagen mediante las librerías MIL Lite

2. Preprocesamiento con filtrado de la mediana.

3. Obtención del histograma de la imagen.

4. Cálculo de umbral óptimo (con método de Otsu) para binarización, para separar las piezas del fondo independientemente de las condiciones de luz que haya en ese momento.

5. Binarización de la imagen.

6. Erosión binaria de la imagen, para eliminar puntos aislados y separar piezas unidas.

7. Segmentación mediante etiquetado, para separar las piezas.

8. Análisis de características de cada objeto.

3.2 PreprocesamientoEn todas las aplicaciones es interesante incluir al menos un algoritmo de suavizado en el dominio

del espacio, es decir, trabajando con una función unidimensional que transforme la intensidad de cada píxel en un valor promediado u obtenido de alguna otra forma, a partir de los píxeles de su entorno. Concretamente utilizando un promedio en base a la mediana del entorno, se pueden eliminar píxeles muy blancos que puedan resultar de reflejos en las piezas debido a unas condiciones de luz distintas a las ensayadas. Este método tiene la ventaja frente al promedio aritmético de que no desdibuja los bordes de las piezas, que en una aplicación como esta puede ser perjudicial porque piezas muy cercanas pueden quedar unidad debido al promedio.

El filtrado de la median garantiza que el método de Otsu tenga un resultado más fiable, puesto que en caso de brillos aislados abundantes la imagen presentaría un grupo importante en la zona alta del histograma, y en lugar de 2 regiones (fondo y objeto) habría 3 regiones.

3.3 HistogramaEl histograma de una imagen es la representación gráfica o analítica de la distribución relativa de

cada valor posible de pixel de imagen, y en caso de imágenes grises de 8 bits será un vector de 256 componentes, siendo la componente i el número de pixeles de nivel i en la imagen, dividido por el número total de pixeles:

Ingeniería en Automática y Electrónica Industrial 3-10

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place3 Fundamentos y algoritmos de visión artificial

El histograma es formalmente la función estadística de densidad de probabilidad en forma discreta de los distintos niveles de gris dentro de la imagen.

Si se integra el resultado es la función de distribución ω[i].

3.4 Umbral óptimo mediante método de OtsuPreviamente a la binarización de la imagen para segmentar objeto de fondo, se debe fijar el

umbral adecuado. Si la imagen presenta unas zonas de objeto y fondo bien diferenciadas, el histograma tendrá una forma como se muestra en Ilustración 14: Histograma de imagen con objetosy fondo diferenciados, y el umbral adecuado se sitúa en el valle de la figura.

Para la determinación automática de este umbral se ha implementado el algoritmo denominado método de Otsu, publicado en 1979 en “IEEE Transactions on System Man Cybernetics” por Nobuyuki Otsu, en el artículo “A threshold selection method from gray-level histogram”. El algoritmo consiste en obtener para todos los umbrales posibles (tantos como niveles de gris tenga la

Ingeniería en Automática y Electrónica Industrial 3-11

histograma [ i ]=N pixeles de nivel i

N total0≤i≤255

[i ]=∑ j=0

ihistograma [ j ] 0≤i≤255

Ilustración 14: Histograma de imagen con objetos y fondo diferenciados

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place3 Fundamentos y algoritmos de visión artificial

imagen) un valor denominado varianza entre clases (σB2, sigma_b_squared) y que viene a medir el

grado de diferencia entre los pixeles de la clase intensidad<umbral, y la clase restante intensidad>umbral, que representarían objeto y fondo (o viceversa) respectivamente. El umbral que maximize esta varianza entre clases es el óptimo para la binarización. Las formulación de estos conceptos se detalla en Ilustración 15: Formulación del método de Otsu.

3.5 Binarización de la imagenEl proceso de binarización de la imagen reducirá el conjunto de posibles valores de cada pixel a

2, blanco y negro, 0 y 1. De esta forma las operaciones posteriores son más rápidas y en general se consumen menos recursos del sistema. Dado un umbral t, la imagen se recorre asignando el valor correspondiente a cada pixel según:

3.6 Erosión binaria de la imagenLos procedimientos de erosión y dilatación de imágenes consisten en aplicar una máscara con 1's

a cada píxel con su entorno, y tomar como valor de salida el mínimo o máximo respectivamente. Concretamente en el caso de la erosión binaria, el mínimo será 0 si hay algún píxel negro en el entorno, por tanto se borrarán todos los píxeles del borde exterior de los objetos, y los que estén aislados. Depende del orden de la máscara utilizada (3x3,5x5,7x7,..) la erosión será más agresiva, aunque el tiempo de computación aumenta considerablemente con ésta y en general todas las operaciones de contorno, cuando el orden utilizado es alto.

Ingeniería en Automática y Electrónica Industrial 3-12

pixelbinario={1 si pixel≤t0 si pixelt}

Ilustración 15: Formulación del método de Otsu

B2 t =

T∗t −t 2

1−t optimo=Max

t{B

2 t }

t =∑i=0

t n i

Nt =∑i=0

ti

ni

NT=∑i=0

iMAX in i

N

B2 t ≡varianza entre clases it e it

t ≡ probabilidad de la clase itt≡media de la clase itn i≡número de pixeles de intensidad iN≡número de pixeles total de la imagenT≡media total de la imagen

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place3 Fundamentos y algoritmos de visión artificial

En función de la naturaleza de la imagen, se pueden utilizar máscaras con estructuras espaciales en la distribución de los 1's, para realizar la erosión por ejemplo en direcciones paralelas a un eje, o formas concretas. En este proyecto se utilizan matrices de máscara sin estructura. El procedimiento se muestra en Ilustración 16: Resultado de erosión binaria con máscara no estructurada de 3x3.

En esta aplicación la función de erosión se implementa con dos objetivos:

1. Filtrado binario de la imagen, eliminando todos los píxeles aislados que puedan aparecer, y que posteriormente se etiquetarían como un objeto encontrado. Aunque se descarte por tener un tamaño demasiado pequeño, se está sobrecargando el procesamiento innecesariamente, y además hay un número máximo previsto de objetos que podría desbordarse si hay mucho ruido, dejando fuera los objetos verdaderamente interesantes.

2. Separación de piezas unidas, puesto que la erosión moderada permite borrar la zona de contacto entre discos que vengan unidos en la cinta, siempre claro está que esa zona de unión tenga un ancho en píxeles menor que la máscara utilizada. En tal caso el procedimiento tendría que repetirse varias veces, o utilizar una máscara muy grande, resultando demasiado agresivo y lento en computación como para ser útil.

3.7 Etiquetado y segmentaciónEl siguiente procedimiento aplicado es la segmentación de la imagen separando los distintos

objetos. Para ello hay que utilizar un criterio de conectividad entre pixeles, como pueden ser los siguientes (ver Ilustración 17: Pixeles 4-conectados (izda) y 8-conectados (dcha) ):

● Conectividad-4: la conexión es horizontal y vertical.

● Conectividad-8: la conexión es también en diagonal.

Ingeniería en Automática y Electrónica Industrial 3-13

Ilustración 16: Resultado de erosión binaria con máscara no estructurada de 3x3

0 0 0 0

0 0 0 1

0 0 1 1

0 0 1 1

0 0 0 0

1 1 1 1

1 1 1 1

1 1 1 1

0 0 1 1

0 0 0 1

1 1 1 1

1 1 1 1

10

1 1 1

1 1 1

1 1 1

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place3 Fundamentos y algoritmos de visión artificial

El etiquetado consiste en recorrer la imagen y asignar una etiqueta a cada píxel, que será nueva si ese píxel no está conectado, o la misma del píxel al que esté conectado en caso de estarlo (digamos que la hereda). Ocurrirá no obstante que un píxel podrá encontrarse conectado a dos píxeles con etiquetas distintas. Entonces se asignará la etiqueta de menor valor (la más antigua) y se registrará

Ingeniería en Automática y Electrónica Industrial 3-14

Ilustración 17: Pixeles 4-conectados (izda) y 8-conectados (dcha)

0

1

1 0

1

0

0

0 0

1

1

11

111

1

1

Ilustración 18: Procedimiento de etiquetado

0 0 0

0 0 255

0 255 255

0 255 255

0 0 0 0

255 0 0 0

255 0 0 255

255 0 255 255

0 0 0 0 0 0 0

255 0

0 0

0 0

255 0

255 255

0 0 0

0 0 1

0 3 1

0 3 1

0 0 0 0

1 0 0 0

1 0 0 4

1 0 5 4

0 0 0 0 0 0 0

2 0

0 0

0 0

2 0

2 2

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place3 Fundamentos y algoritmos de visión artificial

en un array al efecto el enlace existente entre ambas etiquetas.

Después de terminar el recorrido completo de la imagen, se deben resolver todos estos enlaces agrupando las etiquetas emparentadas en una misma etiqueta de grupo, de modo que al final se tendrá una imagen etiquetada, donde cada píxel tendrá una etiqueta que a su vez corresponderá con una etiqueta de grupo. El número de etiquetas de grupo encontradas será el número de objetos distintos (no conectados) de la imagen.

En Ilustración 18: Procedimiento de etiquetado se muestra un ejemplo sencillo con dos objetos, partiendo de una imagen donde los píxeles blancos tienen valor 255. Se recorre la imagen en orden de filas, mirando si cada píxel está 4-conectado con los pixeles ya recorridos, o sea, con el de la izquierda y el de arriba. La conectividad-4 produce una algoritmo bastante más rápido y así se implementa en este proyecto. Si los enlaces se registran adecuadamente, al final se obtiene la imagen etiquetada junto con un vector que agrupa las etiquetas en etiquetas de grupo. Así a un píxel con etiqueta e pertenecal objeto identificado por EtiquetaGrupo[e]. En el ejemplo anterior sería:

EtiquetaGrupo[]=(0,1,2,1,2,2)

3.8 Análisis de características de cada objetoUna vez segmentada la imagen, se procederá a calcular el centro de gravedad de cada objeto,

medido en pixeles. Si las coordenadas del píxel son (i,j) en los ejes X e Y respectivamente, la expresión necesaria es:

Se requiere recorrer de nuevo la matriz de imagen etiquetada utilizando el vector de clases para computar cada píxel en su objeto correspondiente. Se podría haber generado una matriz de clases ya compactada, es decir, con el número de clase en lugar de etiqueta, pero es un proceso adicional que no aporta nada, sino consumo de tiempo, porque después es necesario volver a barrer esa matriz.

El número de pixeles del objeto Npix se utilizará además para confirmar que se trata de una pieza objetivo, puesto que el tamaño esperado se conoce a priori. Así en caso de tener algunas piezas pegadas o alguna mancha se podrá discriminar, puesto que la posición del centro de gravedad de todas formas no sería válida.

También puede ocurrir que los discos se corten en la imagen, incluso que un disco grande cortado se vea como un disco pequeño, provocando un error en la manipulación del robot puesto que la posición del centro de gravedad no será buena. Por eso también se computan los píxeles de cada objeto que se encuentran en un ancho predefinido de periferia, desechando el objeto si se supera un límite determinado.

Ingeniería en Automática y Electrónica Industrial 3-15

xCGm =

∑ i∗pixel mi , j Npix m

∇ pixelm del objeto m

yCGm =∑ j∗ pixelmi , j

Npixm∇ pixelm del objeto m

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

4 Implementación del sistema de visión artificial

4.1 IntroducciónEl sistema de visión artificial se ha implementado utilizando los controles ActiveX MIL-Lite de

Matrox, el fabricante de la tarjeta IEEE1394 utilizada. Con estos controles se captan y muestran las imágenes en pantalla.

Para el procesado se han escrito las funciones correspondientes en C++, incluyendo funciones para obtención de histograma, selección de umbral óptimo, binarización, erosión, etiquetado y segmentación, y análisis de los objetos encontrados.

En general cada función reserva automáticamente la memoria necesaria para la imagen, y los resultados se almacenan en algún componente de pantalla (como es el caso del umbral, contenido en el objeto ScrollBarUmbral) o en una clase de variables globales (class Global) creada para ello (aquí se almacenan los resultados del proceso, como son el número de piezas válidas encontradas y su tamaño y posición).

4.2 Descripción de las librerías MIL-LitePara la adquisición de la imagen se han instalado en C++ Builder los controles ActiveX del

paquete de Matrox[1] denominado MIL-Lite Ilustración 22: Control TSYSTEM).

Con estos se configura el sistema, se adquiere la imagen, y se muestra en display. Además el objeto Digitizer permite en este caso, al tener conexión IEEE1394 con la cámara a través de la tarjeta MATROX METEOR II/1394, configurar los parámetros básicos de la misma como pueden ser el modo de trigger externo si se utiliza, el área de imagen escaneado por la cámara, etc. Para ello la cámara debe estar conectada puesto que estas funciones se realizan en tiempo de desarrollo.

Ingeniería en Automática y Electrónica Industrial 4-16

Ilustración 19: Librerías incluidas en MIL Lite para adquisición de imagen

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

Una vez instalados estos componentes aparecen en la paleta del C++ Builder[2] junto al resto de componentes que el propio software ofrece (VCL, Visual Component Library), como se muestra en Ilustración 20: Componentes ActiveMIL incorporados a C++ Builder.

4.3 Diagrama general de las clases utilizadasLos objetos principales de la aplicación desarrollada pertenecen a las siguientes clases:

● Clase Taction: contienen las funciones desarrolladas para tratar la imagen, gestionar las comuniaciones, etc. Este componente de C++ Builder viene a ser un contenedor de líneas de código con algunas facilidades como agruparlas y categorizarlas en tiempo de desarrollo para un fácil acceso, o asignaciones rápidas con botones sin escribir código.

● Clase TImageMil: contienen las imágenes, se describirán más adelante.

● Clase Tdisplay: para mostrar las imágenes en pantalla.

● Clase Tchart: componente de C++ Builder para mostrar gráficos.

● Clase Global: esta clase se ha creado para contener las variables globales de la aplicación y los métodos de acceso, ambos de tipo static.

● También se utilizan las clases TSYSTEM, TDigitizer, TApp de las librarías MIL que se describirán en los siguientes apartados, o los componentes de comunicaciones TidTCPClient y TIdAntiFreeze, para conseguir un diagrama sintetizado de los procesos principales de la aplicación. Y en general se utilizan bastantes componentes de la librería VCL de C++ Builder para conseguir el aspecto final de la apicación.

En Ilustración 33: Secuencia de acciones para acceso a las imágenes se muestra graficamente el flujo de la información a través de estos objetos.

Ingeniería en Automática y Electrónica Industrial 4-17

Ilustración 20: Componentes ActiveMIL incorporados a C++ Builder

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

Ingeniería en Automática y Electrónica Industrial 4-18

Ilustración 21: Objetos y clases principales utilizados para el desarrollo del sistema de visión artificial

ROBOT ROBOT

SISTEMA DE VISION ARTIFICIALSISTEMA DE VISION ARTIFICIAL

Objeto:ImageMil1Clase:TimageMilOrigen:MILFunción:Contiene laimagen capturada

Objeto:Display1Clase:TDisplayOrigen:MILFunción: Muestra imagencontenida en ImageMil1

Objeto:ActionCapturaClase:TActionOrigen:Este proyectoFunción:Ejecuta el método decaptura de imagen del objetoTDigitizer1

Objeto:ActionHistogramaClase:TActionOrigen:Este proyectoFunción:Obtiene histogramade la imagen, calcula umbralpor método de Otsu y muestraen gráfico los resultados

Objeto:CharHistogramaClase:TCharOrigen:VCLFunción: Muestra gráficade histograma y valoresestadísticos

Objeto:ScrollBarUmbralClase:ScrollBarOrigen:VCLFunción: Contiene umbralpara binarización

Objeto:ImageMil2Clase:TimageMilOrigen:MILFunción:Contiene laimagen binarizada

Objeto:ActionBinarizaClase:TActionOrigen:Este proyectoFunción:binariza imagen

Objeto:ActionErosionClase:TActionOrigen:Este proyectoFunción:erosiona imagen

Objeto:ActionEtiquetadoClase:TActionOrigen:Este proyectoFuncion:Etiqueta, segmenta,extrae las característicasde las piezas vistas

Objeto:Display2Clase:TDisplayOrigen:MILFunción: Muestra imagencontenida en ImageMil2

Clase:GlobalOrigen:Este proyectoFuncion:Contenedor devariables globales deposición y número depiezas

Objeto:ActionCompletoMultipleClase:TActionOrigen:Este proyectoFunción:Esta función llama secuencialmentea las anteriores, y se comunica con el robot para enviarle los datos.

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

4.4 Controles de adquisición de imagenEl control SYSTEM1 (clase TSYSTEM) configura los parámetros básicos como el tipo de tarjeta

de adquisición, si hay varias cámaras, etc.. y en esta aplicación no es necesario modificar sus propiedades por defecto puesto que únicamente hay un sistema instalado y ya lo reconoce.

El control Digitizer1 (clase Tdigitizer) permite configurar las propiedades de la cámara o la tarjeta de adquisición y contiene métodos y eventos para muy diversas operaciones relacionadas con este proceso, como se recoge en Ilustración 24: Control TDigitizer, donde se observa que además encapsula otros objetos como las tablas de asignación LUT.

Algunas propiedades deben accederse naturalmente desde programa en tiempo de ejecución, no obstante las propiedades constantes durante la ejecuación, o al menos con un valor inicial determinado se modifican más facilmente desde el Inspector de Objetos de C++ Builder. Y a las propiedades principales se accede directamente con un wizard haciendo doble click en el icono no visual del objeto, por ejemplo para configurar que la asignación de los recursos de memoria se haga automáticamente al inicio (Ilustración 23: Propiedad Automatic Allocation para TDigitizer).

Ingeniería en Automática y Electrónica Industrial 4-19

Ilustración 22: Control TSYSTEM

Ilustración 23: Propiedad Automatic Allocation para TDigitizer

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

En la pestaña de atributos se accede a configurar en este caso la cámara, claro que debe estar conectada y accesible, si no en lugar de las propiedades se encuentra uno con Ilustración 25:Acceso IEEE1394 a configuración de cámara.

Ingeniería en Automática y Electrónica Industrial 4-20

Ilustración 24: Control TDigitizer

Ilustración 25: Acceso IEEE1394 a configuración de cámara

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

Los métodos empleados de este control digitalizador son los siguientes:

● Digitizer1->Grab() »Captura una imagen

● Digitizer1->GrabContinuous »Captura imágenes continuamente (modo video)

● Digitizer1->Halt »Detiene la grabación contínua

También se accede a algunas propiedades en tiempo de ejecución, por ejemplo para detener la grabación contínua antes de pasar a modo de captura únicamente(Texto 1: Ejemplo de métodos deTDigitizer).

4.5 Clases VARIANT y SAFEARRAY para contener imágenesCuando se ejecuta el método Grab() del control Digitizer, éste adquiere la imagen según los

parámetros configurados y la envía al objeto ImageMil1 (clase TImageMil, por defecto trata de instalarse como clase TImage pero C++ Builder ya tiene un control con ese nombre, que además también sirve para mostrar imágenes!) cuya estructura, propiedades y métodos se muestran en Ilustración 26: Control TImageMil.

Las propiedades principales son las siguientes: imagen con datos sin signo de 8 bits, número de bandas por defecto que será 1 (monocromo) y tamaño por defecto que será 640x480 (configuración de la cámara). Está habilitada la grabación (desde el control Digitizer) y el display (hacia el control Display). La propiedad CanProcess se refiere al uso de los controles de procesamiento del paquete de software MIL completo, que en este proyecto no se utilizan.

Lo más importante en este proyecto de este control es la forma de acceder a la imagen para tratarla. La filosofía de la programación orientada a objetos pasa por no tener que conocer incluso como ImageMil1 almacena los píxeles de la imagen, sino utilizar los métodos que ofrece para ello y que se presuponen optimizados en cuanto a robustez y tiempo de ejecución. En este caso el método es Get, como no podía ser de otra forma.

Ingeniería en Automática y Electrónica Industrial 4-21

if (Digitizer1->GrabInProgress==TRUE)

Digitizer1->Halt();

Digitizer1->Grab();

Texto 1: Ejemplo de métodos de TDigitizer

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

Hay que decir que también es posible el acceso directo a la imagen de dos formas:

1. En lugar de habilitar AutomaticAllocation, se puede pasar como parámetro la zona de memoria a utilizar mediante el método AssignMemory, debiendo el programador reservar previamente la memoria necesaria para ello.

Ingeniería en Automática y Electrónica Industrial 4-22

Ilustración 26: Control TImageMil

Ilustración 27: Wizard con propiedades de TimageMil

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

2. Habilitar AutomaticAllocation, y después obtener un puntero a la dirección de memoria real de la imagen, mediante la propiedad HostAddress, como por ejemplo se hace en Texto 2:Código para acceso directo a memoria de imagen.

En este proyecto se accede a las imágenes mediante el método Get (Ilustración 28: Sintaxis delmétodo Get de TImageMil).

Ingeniería en Automática y Electrónica Industrial 4-23

Unsigned char *pimagen,pixel;

long midepth;

int ncolumnas,nfilas;

int i,j;

ncolumnas=ImageMil1->PitchByte;

nfilas=(ImageMil1->DataSize)/ncolumnas;

pimagen=(unsigned char *) ImageMil1->HostAddress;

pixel=pimagen[i*ncolumnas*j]; // Acceso a pixel (i,j)

Texto 2: Código para acceso directo a memoria de imagen

Ilustración 28: Sintaxis del método Get de TImageMil

ImageMil1->Get(&vimagen,imSingleBand,imAllBands,0,0,SizeX,SizeY);

Texto 3: Línea de código con método Get de TImageMIL

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

Y se usará casi siempre para acceder a la imagen completa, como se muestra en Texto 3: Línea decódigo con método Get de TImageMIL.

Ingeniería en Automática y Electrónica Industrial 4-24

Ilustración 29: Valores posibles para VARTYPE, identificador de tipo de VARIANT

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

Ingeniería en Automática y Electrónica Industrial 4-25

Ilustración 30: Métodos para la clase VARIANT

Ilustración 31: Definición de la clase SAFEARRAY

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

Previamente se debe crear un elemento de tipo VARIANT (no confundir con Variant), que es una clase de Microsoft diseñada para el intercambio de datos entre distintas aplicaciones de Window. Esta clase contiene una unión de prácticamente todos los posibles tipos de datos, y una variable VARTYPE identificadora del tipo realmente contenido, cuyos posibles valores se muestran en Ilustración 29: Valores posibles para VARTYPE, identificador de tipo de VARIANT(incompleto, fuente wtypes.h).

Además provee métodos para inicializar y liberar los recursos asociados, declarados en oleauto.h, se muestran en Ilustración 30: Métodos para la clase VARIANT.

Concretamente, el tipo de datos que debe contener el VARIANT pasado al método Get debe ser un SAFEARRAY, que es otro invento de Microsoft para el intercambio de todo tipo de arrays entre aplicaciones de Window. Es una estructura con variables que identifican las dimensiones y tipos de datos, incluso un contador de accesos (cLocks) a modo de semáforo. Los detalles están en Ilustración 31: Definición de la clase SAFEARRAY.

Como es de esperar los métodos para trabajar con SAFEARRAY's están creados, las declaraciones se detallan en fuente oleauto.h ( ver Ilustración 32: Métodos para SAFEARRAY).

La secuencia de funciones a realizar para acceder a las imágenes se muestra esquemáticamente en Ilustración 45: Imagen binaria coloreada después del etiquetado (colores invertidos), y el código de programa correspondiente en Texto 4: Código de programa para acceso a las imágenes.

Ingeniería en Automática y Electrónica Industrial 4-26

Ilustración 32: Métodos para SAFEARRAY

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

Conviene resaltar que aunque parezca que hay un despilfarro de código para realizar un “simple” direccionamiento a un array, lo importante es que al final lo que se realiza a nivel de computador es ese acceso, pues la mayor parte del código se resuelve durante la compilación, y con el uso de estas clases lo que se garantiza es compatibilidad de tipos y por tanto robustez y portabilidad general de la aplicación.

De hecho el acceso es incluso más rápido que si se toma el puntero de la dirección física donde SAFEARRAY contiene la imagen, y se recorre directamente la imagen incrementando el puntero en cada iteración. Por ejemplo para obtener el histograma he ensayado diversas formas de acceso (ver Ilustración 34: Prueba de tiempos con varias formas de acceso a la imagen) y comprobado que la más rápidad es esta, 145ms (Ttest[14]) frente a 250ms (Ttest[15]), imagen de 640x480.

Ingeniería en Automática y Electrónica Industrial 4-27

Ilustración 33: Secuencia de acciones para acceso a las imágenes

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

La velocidad si es mayor si el array de histograma se define de forma global en lugar de local dentro de la función, por razones que Windows sabrá.

Ingeniería en Automática y Electrónica Industrial 4-28

VARIANT vimagen;

SAFEARRAY* psaimagen=NULL;

SAFEARRAYBOUND rgsabound[2];

const unsigned int cDims=2;

long rgIndices[2];

int SizeX,SizeY,

unsigned char pixel;

/* Extracción de imagen desde ImageMil1.................. */

VariantInit(&vimagen); // Inicializa el VARIANT

vimagen.vt=VT_ARRAY|VT_UI1; // tipo de dato: SAFEARRAY de UINT8

SizeX=ImageMil1->SizeX; // Tamaño de array necesario

SizeY=ImageMil1->SizeY; // Tamaño de array necesario

rgsabound[0].cElements=SizeX;

rgsabound[0].lLbound=0;

rgsabound[1].cElements=SizeY;

rgsabound[1].lLbound=0;

psaimagen=SafeArrayCreate(VT_UI1,cDims,rgsabound);

vimagen.parray=psaimagen;

ImageMil1->Get(&vimagen,imSingleBand,imAllBands,0,0,SizeX,SizeY);

/*Ya tenemos la imagen...................... */

.......... Otras instrucciones ................rgIndices[0]=i;

rgIndices[1]=j;

SafeArrayGetElement(psaimagen,rgIndices,&pixel ); // pixel (i,j)

.......... Otras instrucciones ................VariantClear(&vimagen); // Libera recursos

Texto 4: Código de programa para acceso a las imágenes

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

4.6 Preprocesamiento. Filtrado de la mediana.El primer algoritmo que se puede aplicar (en modo AUTO es opcional, marcando en la pantalla

de control de la aplicación) es un procedimiento de filtrado según la mediana de un entorno del píxel de orden configurable (#define OrdenDeMascaraMediana 3).

Ingeniería en Automática y Electrónica Industrial 4-29

Ilustración 34: Prueba de tiempos con varias formas de acceso a la imagen

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

El programa hace un barrido de la imagen, y para cada píxel muestrea el entorno llenando vectorentorno[cntentorno] con los datos (cntentorno será como máximo el orden de máscara al cuadrado, y menor en la periferia de imagen al descartar el exterior), para después extraer la mediana con el código que se muestra en Texto 5: Líneas de programa para obtención de lamediana,que trata de hacer el mínimo de iteraciones posibles.

En Ilustración 44: Código del bucle de recorrido de la imagen etiquetada se muestra un ejemplodel resultado del algoritmo implementado, sobre una imagen “artificial” de discos de

distintos tonos de gris con manchas blancas (se muestra la imagen invertida).

Ingeniería en Automática y Electrónica Industrial 4-30

/* Ordenado de entorno para tomar mediana */

FinOrdenado=0;

while (!FinOrdenado) {

FinOrdenado=1;

for (int e=0;e<cntentorno-1;e++) {

if (vectorentorno[e]>vectorentorno[e+1]) {

pixtemp=vectorentorno[e];

vectorentorno[e]=vectorentorno[e+1];

vectorentorno[e+1]=pixtemp;

FinOrdenado=0;

}}}

mediana=vectorentorno[cntentorno/2+1];

Texto 5: Líneas de programa para obtención de la mediana

Ilustración 35: Ejemplo de preprocesado mediante filtrado de la mediana (imagen invertida)

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

4.7 Histograma y umbral automático mediante Método de OtsuEl histograma se obtiene con la función contenida en ActionHistograma, a la que se accede

directamente desde el entorno, como al resto, desde el objeto no visual ActionList:

Esta función crea un array de 256 posiciones tipo double y contabiliza en histograma[i] el número de píxeles que tienen el nivel de intensidad i. Las líneas de código (resumido) para obtener el histograma se muestran en Texto 6: Código de programa para realizar histograma.

El histograma obtenido se muestra en pantalla utilizando un componente VCL de la clase TChar, especializado en gráficos y que permite configurar fácilmente el aspecto final del mismo durante el desarrollo, y durante la ejecución basta utilizar el método AddArray sobre la serie correpondiente. Se pueden configurar diversas series para mostrar varias curvas sobre un mismo gráfico, de hecho se muestran también las curvas de probabilidad acumulada y varianza entre clases (Ilustración 19:Librerías incluidas en MIL Lite para adquisición de imagen)

Ingeniería en Automática y Electrónica Industrial 4-31

Ilustración 36: Objeto ActionList conteniendo ActionHistograma

Ilustración 37: Objeto TChar de VCL de C++Builder

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

Debajo del gráfico del histograma se sitúa una barra para seleccionar manualmente el umbral de binarización de la imagen, viéndolo así junto al eje de abcisas del histograma.

Para la determinación automática de este umbral se ha implementado el algoritmo denominado método de Otsu, que se detalla en el capítulo anterior.

Ingeniería en Automática y Electrónica Industrial 4-32

Ilustración 38: Función graythresh en MATLAB

PixSize=(ImageMil1->MaximumPixelValue)+1;

histograma=new double [PixSize];

vectoromega=new double [PixSize];

for(int h=0;h<PixSize;h++)

histograma[h]=0; // Reset histograma

for(int i=0;i<SizeX;i++) {

for(int j=0;j<SizeY;j++) {

rgIndices[0]=i;

rgIndices[1]=j;

SafeArrayGetElement(psaimagen,rgIndices,&pixel );

if (pixel<=(PixSize-1))

histograma[pixel]+=1;

else

cnt_fallos++; // Intentos de acceso fuera de rango

}

}

Texto 6: Código de programa para realizar histograma

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

Matlab[3] incorpora la función graythresh que implementa desde las versiones R14 este método para obtener un umbral de binarización (Ilustración 36: Objeto ActionList conteniendo

ActionHistograma).

Para implementar la función se han utilizado los mismos nombres de variables que utiliza Matlab, que a su vez mantiene la nomenclatura de la publicación original. La implementación desde luego es distinta que en Matlab, que utiliza como no operaciones matriciales para el cálculo,

Ingeniería en Automática y Electrónica Industrial 4-33

/* Metodo de Otsu. */

mu_T=0;

for(int t=0;t<NivelesGris;t++){

histograma[t]=histograma[t]/(SizeX*SizeY);

mu_T+=t*histograma[t];

}

sigma_b_squared_MAX=0;

if (mu_T>0) {

for(int t=0;t<NivelesGris;t++){

/* Probabilidad de la clase t>umbral */

omega+=histograma[t];

/* media de la clase t<umbral */

mu+=t*histograma[t];

/* Zona útil del histograma 0.001-0.999 */

if ((omega>0.001)&&(omega<0.999))

/* VARIANZA ENTRE CLASES */

sigma_b_squared=((mu_T*omega-mu)*(mu_T*omega-mu))/

(omega*(1-omega));

else sigma_b_squared=0;

if (sigma_b_squared>=sigma_b_squared_MAX) {

sigma_b_squared_MAX=sigma_b_squared;

umbral_otsu=t;

}

}

}

/* Muestra el umbral calculado, y lo "convierte" en variable global */

if (umbral_otsu<UmbralOtsuMinimo) umbral_otsu=UmbralOtsuMinimo;

ScrollBarUmbral->Position=umbral_otsu;

StaticTextUmbral->Caption=AnsiString(umbral_otsu);

Texto 7: Implementación del método de Otsu en C++

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

mientras que en C++ todo se resuelve a base de for / if. Las líneas de código principales que se han implementado se muestran en Texto 7: Implementación del método de Otsu en C++.

El umbral calculado se “coloca” en el objeto ScrollBarUmbral, de modo que se puede ver en pantalla, y además es accesible al resto de funciones de la aplicación, digamos que se convierte en variable global de ese modo.

En Ilustración 38: Función graythresh en MATLAB se muestra un ejemplo con una imagen de varios discos (¡Ojo, la imagen que aquí se muestra está invertida, para no gastar tanta tinta en la impresión!), el histograma tiene una zona oscura en torno a intensidad 17 que corresponde al fondo y otra zona de imagen entorno a 30, de menor cantidad de pixeles. Sobre el mismo histograma se representa el vector ω(t) en rojo, que representa la probabiidad de la clase intensidad<t y que siempre evoluciona de 0 a 1. También se representa el vector σB

2 (t) en verde, que debe presentar un máximo global si la imagen claro está encaja en el patrón de 2 distribuciones gaussianas, fondo y objeto. El umbral calculado es 21, la posición del cursor del ScrollBar se sitúa efectivamente en el valle del histograma.

La zona del histograma que debe considerarse es aquella entre omega=0 y omega=1, que es donde hay pixeles, pues antes todavía no hay ninguno, y después ya se han visto todos. Los cálculos deben evitarse fuera de la zona puesto que se producen indeterminaciones y valores infinitos al tener 0 en denominador y/o numerador. Se han limitado concretamente en el rango [0,001 – 0,999]

Ingeniería en Automática y Electrónica Industrial 4-34

Ilustración 39: Ejemplo de imagen (se muestra invertida) con histograma y curva de varianza entre clases

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

para evitar valores extremos que distorsionan la escala del gráfico y dificultan la depuración al observar exponenciales muy altas.

Para la depuración se incluye además la opción de ir viendo los cálculos paso a paso, mediante las opciones del menú Herramientas Vision que se muestran en Ilustración 39: Ejemplo de imagen(se muestra invertida) con histograma y curva de varianza entre clases.

Por otra parte también hay que considerar que cuando la imagen es muy oscura, el método de Otsu también trabaja y coloca un umbral muy pequeño, destacando al binarizar las zona de intensidad mínima pero mayor que cero debido a los reflejos en la banda. Entonces los algoritmos posteriores trabajan sobre eso, pudiendo ocasionar falsos datos, como en el ejemplo Ilustración 40:Herramientas para depuración de histograma. Para evitarlo se ha fijado un umbral mínimo en el programa, accesible en #define UmbralMinimo.

4.8 Implementación de la función de erosiónPara el procedimiento de erosión se ha escrito una función con “vocación generalista”, puesto

que fácilmente podría modificarse para cambiar la estructura de la máscara empleada. En Ilustración 27: Wizard con propiedades de TimageMil se puede ver el código del bucle de recorrido de la imagen, previamante se crean dinamicamente (mediante new). Se definen los índices (ipix,jpix) para acceso al entorno del píxel (i,j), y se trabaja únicamente con los píxeles de ValorBinarioAlto, o sea, blancos. Para los pixeles periféricos, los píxeles del entorno que quedarían fuera de la imagen no se computan, ni siquiera se accede puesto que no es necesario (no obstante el método SafeArrayGetElement no provoca una excepción cuando se accede fuera del array, antes

Ingeniería en Automática y Electrónica Industrial 4-35

Ilustración 40: Herramientas para depuración de histograma

Ilustración 41: Imagen con ruido de nivel de intensidad=5 (izda), binarizada y etiquetada debido al bajo umbral asignado=4 (dcha). (Se muestran las imágenes invertidas)

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

comprueba que el índice está dentro de los límites).

El orden se indica mediante la etiqueta #define OrdenDeMascara 3. El tiempo de conmutación se ve afectado por 2 factores principales, además de las características lógicamente del PC utilizado:

1. Un factor variable como es el número de pixeles blancos de la imagen.

2. Un factor determinado que es el orden de la máscara utilizada.

En Tabla 1: Tiempos del proceso de erosión en varios casos se recogen los tiempos medidos en varios casos, tratando con imágenes de resolución 640x480 (por tanto se realizan 307200 * OrdenDeMascara2 iteraciones), y se concluye que utilizar máscaras de orden superior a 3 es prácticamente prohibitivo, al menos en este proyecto!.

Una posible solución para reducir los tiempos podría ser arrastrar el contenido del entorno durante el desplazamiento por la imagen, que si se hace por columnas consistiría en que a cada paso de bajada se reste al resultado de máscara la fila superior y se añada la fila inferior, de modo que para máscaras de orden superiores a 3 se reducirían las iteraciones. Sin embargo esta forma obliga a arrastrar el resultado de la máscara y operar incluso sobre los pixeles negros, que antes se estaban ignorando, por tanto en imágenes predominantemente negras, que de hecho serán la mayoría en la aplicación objeto de este proyecto, el tiempo se aumenta y el resultado que cabe esperar es por tanto peor.

Ingeniería en Automática y Electrónica Industrial 4-36

Ilustración 42: bucle principal de la rutina de erosión

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

OrdenDeMascara Imagen 2 circulos grandes Imagen blanca total3 90ms 313ms5 179ms 759ms7 310ms 1386ms

Tabla 1: Tiempos del proceso de erosión en varios casos

4.9 Implementación de las funciones de etiquetado, segmentación, análisis de piezas y clasificación.

La funciones de etiquetado, segmetnación y análisis de piezas se incluyen en el objeto ActionEtiquetado, y comprende una serie de pasos que se describen a continuación.

4.9.1 Barrido y etiquetado inicialEn primer lugar se recorre la imagen asignando nuevas etiquetas ( que se van almacenando en la

matriz etiquetas[SizeX][SizeY] ) a los pixeles blancos de la imagen que no están 4-conectados con ningún otro de los ya recorridos, y en caso de conexión se “hereda” la etiqueta del píxel conectado, siguiendo el criterio de mantener siempre el mínimo valor de etiqueta en caso de conexión múltiple.

En Texto 8: Algoritmo de etiquetado sintetizado, se puede ver el código de esta parte sintetizado, puesto que muchas partes irrelevantes para la comprensión del mismo se han sustituido por un comentario “no formal” (del modo ........ Comentario ....... ). Es muy importante registrar adecuadamente los enlaces encontrados para posteriormente tratarlos.

En el vector enlaces[] no se utiliza la componente cero puesto que ese valor representará un píxel sin etiquetar, o sea, negro. Por otra parte, se utiliza el valor de marca enlaces[e]=-1 cuando la etiqueta e se usa por primera vez, es decir, no está enlazada con ninguna otra. Así en el paso posterior se podrá reiniciar la numeración de las clases llegado este punto.

El valor máximo de etiquetas admitido se define con #define MaximoEtiquetas 500, y a su vez el máximo de clases (piezas) esperados con #define MaximoClases 50. Cuando se alcanza uno de estos valores no se renueva la numeración, por tanto el objeto de clase 50 no debe considerarse posteriormente puesto que realmente es una agrupación de todo lo encontrado a partir de la utilización de la etiqueta 49.

Ingeniería en Automática y Electrónica Industrial 4-37

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

Ingeniería en Automática y Electrónica Industrial 4-38

/* Recorrido de etiquetado*/

int NuevaEtiqueta=1,arriba,izda;

for(int i=0;i<SizeX;i++) {

for(int j=0;j<SizeY;j++) {

..... Lee pixel..... if ((pixel==ValorBinarioAlto)&& (NuevaEtiqueta<MaximoEtiquetas)) {

arriba=etiquetas[i][j-1];

izda=etiquetas[i-1][j];

/* Los casos siguientes están ordenados de mayor a

menor número de ocurrencias, para optimizar algoritmo*/

..... Si 4-conectado arriba e izda, arriba=izquierda .....etiquetas[i][j]=arriba;

..... Si 4-conectado arriba e izda, izda>arriba .....etiquetas[i][j]=izda;enlaces[arriba]=izda;

..... Si 4-conectado arriba e izda, izda<arriba .....etiquetas[i][j]=arriba;

enlaces[izda]=arriba;

..... Si 4-conectado arriba .....etiquetas[i][j]=arriba;

..... Si 4-conectado izda .....etiquetas[i][j]=izda;

..... Si NO 4-conectado.....etiquetas[i][j]=NuevaEtiqueta;

enlaces[NuevaEtiqueta]=-1; //marca

NuevaEtiqueta++;

}

else etiquetas[i][j]=0; // píxel negro

}}

Texto 8: Algoritmo de etiquetado sintetizado

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

4.9.2 Agrupamiento de etiquetas en objetosA continuación se realiza un procedimiento de agrupamiento de las distintas etiquetas, trabajando

sobre el vector enlaces[]. No es necesario referirse aquí a la matriz etiquetas[SizeX][SizeY], toda la información de “parentesco” está recogida en el vector enlaces[]. Se realiza un procedimiento acumulativo de modo que sobre el mismo vector se reescribe asignando a cada etiqueta e su correspondiente clase que se guarda en enlaces[e]. Por eso es importante el orden de asignación de menor etiqueta en el paso anterior, para garantizar que este recorrido es efectivo.

La componente clases[0] no se utiliza, puesto que la etiqueta 0 corresponde al fondo de imagen y no tiene interés. Por lo demás en Ilustración 37: Objeto TChar de VCL de C++Builder se muestra el código completo de esta parte, con preciosos comentarios aclaratorios (en el programa se llama clases[] al vector que resulta conteniendo las etiquetas de grupo, y se denominan clases a estos grupos).

Ingeniería en Automática y Electrónica Industrial 4-39

Ilustración 43: Código del agrupamiento de etiquetas en objetos

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

4.9.3 Análisis de piezas encontradasLlegado este punto es necesario volver a recorrer la imagen, ahora ya trabajando sobre la matriz

etiquetas[SizeX][SizeY], para determinar los parámetros de interés que finalmente son:

● XCG[c] Coordenada x en mm del centro de gravedad de la clase c

● YCG[c] Coordenada y en mm del centro de gravedad de la clase c

● Npiezas Número de piezas válidas encontradas

Estos parámetros son los finales, que se almacenarán en las respectivas variables globales de la clase Global correspondiente:

● XCG[c] Se almacenará en Global::XCG[c]

● YCG[c] Se almacenará en Global::XCG[c]

● Npiezas Se almacenará en Global::XCG[c]

Ingeniería en Automática y Electrónica Industrial 4-40

Ilustración 44: Código del bucle de recorrido de la imagen etiquetada

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

Ingeniería en Automática y Electrónica Industrial 4-41

/* Obtención de coordenadas de posición y selección de piezas válidas */

int Npix;

bool PiezaValida;

Npiezas=0;

for (int c=0;c<ClaseMaxima;c++) {

if (Npixvector[c]>0) { // Condición de seguridad redundante

xvector[c]=xvector[c]/Npixvector[c];

yvector[c]=yvector[c]/Npixvector[c];

Npix=Npixvector[c];

..... Si hay demasiados pixeles en la periferia .....PiezaValida=FALSE;

TipoPieza[c]="PERIFERICO";

..... Si el numero de pixeles corresponde a círculo pequeño .....PiezaValida=TRUE;

TipoPieza[c]="CIRC.PEQUEÑO";

..... Si el numero de pixeles corresponde a círculo pequeño .....PiezaValida=TRUE;

TipoPieza[c]="CIRC.GRANDE";

..... En otro caso .....PiezaValida=FALSE;

TipoPieza[c]="COSAS RARAS";

}

if (PiezaValida) {

/* Centro de gravedad, convertido de pixel a mm */

XCG[Npiezas]=(int)(PixToMm*xvector[c]);

YCG[Npiezas]=(int)(PixToMm*yvector[c]);

Npiezas++;

}

Texto 9: Código sintetizado de la clasificación de piezas

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

Por el camino será necesario utilizar un mayor número de variables locales, que se detallan a continuación:

● xvector[c] Vector para acumular las coordenadas x de los pixeles de la clase c

● yvector[c] Vector para acumular las coordenadas y de los pixeles de la clase c

● Npixvector[c] Vector para acumular el total de pixeles de la clase c

● NpixPeriferia[c] Vector para acumular el total de pixeles “periféricos” de la clase c

● TipoPieza[c] Vector de textos, para informar del tipo de pieza de la clase c

● PiezaValida Variable bool para validar las piezas buenas

En Ilustración 42: bucle principal de la rutina de erosión, se puede ver la extracción de parámetros de la imagen, y en Texto 9: Código sintetizado de la clasificación de piezas, como después se clasifican y se guardan las piezas válidas, todavía en variables locales.

4.9.4 Coloreado de la imagen etiquetada e información en pantallaOpcionalmente, se puede activar esta parte del programa que muestra en el Display2 la imagen

con diferentes tonos de gris asignados a cada etiqueta, quedando un resultado como se muestra en Ilustración 41: Imagen con ruido de nivel de intensidad=5 (izda), binarizada y etiquetada debido albajo umbral asignado=4 (dcha). (Se muestran las imágenes invertidas). Esta función es opcional, se activa desde la pantalla principal de la aplicación con el CheckBoxColorea.

Después de esta operación se libera la memoria para contener la imagen binaria mediante el método VariantClear, puesto que no será necesario utilizarla más.

También se muestra la información completa del proceso en pantalla, como líneas de texto de un objeto TMemo MemoEtiquetado, y se marcan los centros de gravedad de las piezas encontradas, con un bucle de recorrido de los vectores de información obtenidos en los pasos anteriores. El resultado se puede ver en Ilustración 43: Código del agrupamiento de etiquetas en objetos.

Ingeniería en Automática y Electrónica Industrial 4-42

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

4.9.5 Almacenamiento de resultado final en variables globalesLas posiciones obtenidas finalmente para las piezas válidas deben ponerse a disposición de otras

funciones para poder enviarlas al robot posteriormente, para ello se ha definido una clase denominada class Global que contiene variables estáticas y métodos estáticos de acceso a las mismas, como se muestra en Texto 10: Declaración de variables globales para almacenarresultado del proceso de visión.

Ingeniería en Automática y Electrónica Industrial 4-43

Ilustración 45: Imagen binaria coloreada después del etiquetado (colores invertidos)

Ilustración 46: Información de clasificación de imagen etiquetada

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place4 Implementación del sistema de visión artificial

Ingeniería en Automática y Electrónica Industrial 4-44

class Global

{

private:

static int XCG[MaximoClases];

static int YCG[MaximoClases];

static int TipoPieza[MaximoClases];

static int Npiezas;

..... otras declaraciones .....public:

static void SetXCG(int n,int newXCG) { XCG[n]=newXCG; }

static int GetXCG(int n) { return XCG[n]; }

static void SetYCG(int n,int newYCG) { YCG[n]=newYCG; }

static int GetYCG(int n) { return YCG[n]; }

static void SetNpiezas(int newNpiezas) { Npiezas=newNpiezas; }

static int GetNpiezas() { return Npiezas; }

..... otras declaraciones .....};

int Global::XCG[MaximoClases];

int Global::YCG[MaximoClases];

int Global::TipoPieza[MaximoClases];

int Global::Npiezas;

enum Estado Global::EstadoAuto;

int Global::Nciclos;

Texto 10: Declaración de variables globales para almacenar resultado del proceso de visión

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place5 Descripción del robot

5 Descripción del robot

5.1 Estructura y sistemas de referenciaEl robot utilizado en el proyecto es el SCARA RH5-AH55 de radio de alcance 550mm y

capacidad de carga 5Kg. El robot dispone de 4 ejes, accionados con servomotores brushless AC equipados con encoder absoluto de resolución 17bits (131072pulsos/vuelta) y reductores sin holgura de Harmonic Drive. La unidad de control CR2A572 contiene tanto las placas de CPU como las placas de potencia. Las posiciones se refieren normalmente en modo cartesiano, resolviendo el controlador interno el modelo cinemático inverso para controlar cada eje según la trayectoria objetivo. En Ilustración 47: Sistema de referencia cartesiano del robot RH5-AH55 se muestra el sistema de referencia, con origen en la base del robot.

El punto de referencia por defecto está situado en el extremo del eje vertical del robot, aunque puede cambiarse como se comentará luego.

Durante el movimiento manual con la Teaching Box se pueden especificar otro sistema referencia anclado en ese punto, y también mover los ejes individualmente o utilizar coordenadas cilíndricas.

Ingeniería en Automática y Electrónica Industrial 5-45

Ilustración 47: Sistema de referencia cartesiano del robot RH5-AH55

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place5 Descripción del robot

5.2 Software de programación, monitorización y mantenimiento.Para la programación, configuración de parámetros y monitorización del estado y programas del

robot se utiliza el software RT TOOLBOX, que incorpora las herramientas que se muestran en Ilustración 48: Herramientas del software RT Toolbox y se describen a continuación:

● Program Edit: edición de programas, accediendo al disco duro y/o robot.

● Monitor: herramientas de monitorización de programas, variables, estado de los ejes, información e histórico de errores, entradas y salidas digitales, etc..

● Parameter: edición de parámetros de configuración del robot.

● Backup/Restore: permite guardar y recuperar todos los datos de configuración y programas del robot.

● Program Converter: para actualizar programas en versiones muy antiguas.

● Remote Maintenance: configura acceso para mantenimiento remoto.

● Position Repair: esta utilidad permite actualizar todas las posiciones memorizadas del robot en caso de modificar la posición de instalación robot o sustituirlo por otro con alguna diferencia en la calibración del origen.

● Maintenance forecast: información relacionada con el mantenimiento del robot, como los tiempos previstos para reposición de baterías.

Ingeniería en Automática y Electrónica Industrial 5-46

Ilustración 48: Herramientas del software RT Toolbox

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place5 Descripción del robot

Ingeniería en Automática y Electrónica Industrial 5-47

Ilustración 49: Configuración de las comunicaciones en RT Toolbox

Ilustración 50: Simulación robot SCARA RH5-AH55

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place5 Descripción del robot

Para poder trabajar, en primer lugar se deberá configurar el acceso al robot que por defecto viene vía RS232 COM1. En este proyecto se utiliza una conexión TCP/IP con la dirección IP que tiene por defecto el controlador (NETIP=192,168,0,1). El puerto también es el que viene por defecto (NETPORT[1]=10001). El resultado se muestra en Ilustración 49: Configuración de lascomunicaciones en RT Toolbox.

El software RT TOOLBOX incorpora, en Program Edit Tool, una herramienta de simulación muy útil que permite ejecutar y probar los programas e incluso medir con precisión los tiempos de ciclo de cualquier modelo de robot.

En Ilustración 51: Simulación robot RV-3S se muestra el sistema de coordenadas TOOL, que está anclado en el punto final del robot, para un robot tipo antropomórfico. Mediante la instrucción TOOL(PHERR) se introducen las coordenadas del punto objetivo de la herramienta respecto del punto final por defecto del robot, de este modo el modelo cinemático utilizado por el robot se modifica para adecuarlo a la herramienta (incluso se pueden tener varias y seleccionarla mediante M_TOOL (ej: M_TOOL=2 ' selecciona la herramienta número 2 ).

En el caso del SCARA RH5-AH55 objeto de este proyecto, la referencia se muestra en Ilustración 50: Simulación robot SCARA RH5-AH55. En estos robots de 4 ejes, no es posible la articulación en las coordenadas A y B (rotación en torno a ejes X e Y), que por tanto siempre serán de valor 0.

Ingeniería en Automática y Electrónica Industrial 5-48

Ilustración 51: Simulación robot RV-3S

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place5 Descripción del robot

Para configurar los parámetros del robot se utiliza Maintenance Tool. Los parámetros están categorizados en Common y Robot1, si se configuran ejes adicionales como un mecanismo adicional (es decir, no interpolando con los ejes principales del robot) entonces aparecería el Robot 2 con los parámetros asociados a este nuevo mecanismo.

Para modificar un parámetro se accede al mismo y al escribirlo se guarda en la memoria EEPROM del controlador. Por ejemplo la asignacion de los canales de encoder conectados al controlador se realiza con el parámetro EXTENC, como se muestra en Ilustración 52: Ejemplo deacceso a parámetro EXTENC.

5.3 Lenguaje de programación MELFA BASIC IVLa programación se realiza en el lenguaje MELFA BASIC IV propio de toda la gama de robots

de MITSUBISHI ELECTRIC[4]. La sintaxis es efectivamente tipo BASIC, y la programación resulta bastante simple mediante el empleo de estas sentencias de alto nivel.

Las instrucciones de control de movimiento contemplan interpolaciones lineales y circulares, e instrucciones varias para optimizar velocidades y aceleraciones automáticamente (OADL, SPDOPT), o especificar un enlace suave entre movimientos continuos (CNT)

Para el control del flujo se dispone de instrucciones IF, WHILE, SELECT CASE, además de saltos a subrutinas desde línea de programa (GOSUB), saltos a subrutinas por interrupciones de entradas digitales o comunicaciones (ACT), llamadas a otros programas con paso de argumentos (CALLP, FPRM). También es posible la programación multitarea, para lo que se disponen de 32 espacios de programa (SLOTs), con varios modos de ejecución posible (REP, CYC, START, ALWAYS, ERROR). Las variables pueden entonces ser locales o globales (son accesibles a todos los programas, en estas variables siempre el segundo carácter es guión bajo “_”).

Los tipos de datos utilizados son los siguientes:

Ingeniería en Automática y Electrónica Industrial 5-49

Ilustración 52: Ejemplo de acceso a parámetro EXTENC

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place5 Descripción del robot

● Variables numéricas: pueden ser tipo entero (INTE, %), real de simple precisión (FLOAT, !) o real de doble precisión (DOUBLE, #). Las variables se pueden declarar al principio del programa (ej: DEF DOUBLE MIVAR1,MIVAR2) o utilizarse directamente, con una declaración implícita (ej: MIVAR1#=3.1416). Las variables numércias no pueden nombrarse con carácter inicial C,P ni J.

● Variables alfanuméricas: puede definirse también al principio del programa (ej: DEF TEXTO1, TEXTO2) o de forma implícita cuando se asigne en el programa (ej: CTEXT$=”HOLA”), pero en este caso siempre debe comenzar por “C”.

● Variables de posición CARTESIANAS: se definen al principcio del programa (ej: DEF POS ARRIBA) o de forma implícita (PARRIBA=P_CURR), pero en este caso siempre debe comenzar por “P”. Las variables de posición constan de un vector de 8 coordenadas tipo DOUBLE de la forma P1=(P1.X,P1.Y,P1.Z,P1.A,P1.B,P1.C,P1.L1,P1.L2) accesibles directamente, por ejemplo para aumentar 15mm la altura de la posición P2 se escribe P2.Z=P2.Z+15. El sistema de referencia por defecto del robot está en el centro de su base, (ver . Las 2 últimas coordenadas son para el caso de conectar ejes adicionales, que se quieran gobernar con movimientos interpolados con los ejes principales del robot. Si no se utilizan estarán siempre a cero. Además de las coordenadas cartesianas de posición, estas variables almacenan un par de variables FLAGs (FL1,FL2) para determinar la postura exacta del robot, ya que debido a la indeterminación del modelo cinemático inverso es necesario puesto que una posición cartesiana se puede alcanzar con más de una posición de los ejes. Si no se especifican se tienen las de defecto según el modelo de robot (ej: P1=P_CURR ' P1=(100,100,35,30,0,0,0,0)(7,0) )

● Variables de posición ANGULARES: similares a las anteriores pero se almacena la posición angular de cada eje motor, y el carácter de referencia es J.

● Entradas / Salidas: las entradas y salidas digitales del robot se nombran de la forma M_IN(n) y M_OUT(n) respectivamente (ej: M_OUT(4)=1), aunque pueden asignarse nombres genéricos mediante DEF IO.

● Variables globales: el controlador ofrece una serie de variables globales que se pueden utilizar directamente, se caracterizan por el segundo carácter que debe ser “_”, y el primero según el tipo (ej: M_1,P_1). Para declararlas con nombres genéricos deben escribirse las declaraciones en un programa que sólo contenga esas declaraciones, y que se habilita asignándolo al parámetro PRGUSR.

5.4 Funciones para seguimiento de encoder (Tracking Function)El robot dispone de funciones para realizar seguimiento contínuo de hasta 2 encoders

simultáneos, para realizar un acompañamiento de una cinta de transporte sobre la que deban manipularse productos en movimiento, con una especificación de velocidad máxima de 20m/min. De forma genérica se dispondrá de un sensor de barrera y un sistema de visión (Ilustración 53:Esquema general de aplicación con tracking), aunque se puede trabajar sólo con el sensor de barrera (piezas con una orientación y posición transversal fijas) o como en este proyecto sólo con el sistema de visión.

Ingeniería en Automática y Electrónica Industrial 5-50

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place5 Descripción del robot

La conexión del encoder se realiza en una tarjeta adicional (Ilustración 54: Detalle de conexiónde encoder para tracking) que se ha incorporado en el slot 2 del controlador, en este proyecto se ha utilizado la salida de monitorización de pulsos del servomotor que acciona el transportador de banda, que ofrece una señal tipo Line Driver como requiere la tarjeta del robot.

Una vez realizada la instalación y conexión de los elementos descritos, se debe proceder a la configuración de los parámetros necesarios en el robot, mediante la utilidad Maintenance Tool descrita anteriormente (o con la Teaching Box si uno es paciente). A continuación se describen estos parámetros, indicando los valores que se han utilizado en este proyecto.

Ingeniería en Automática y Electrónica Industrial 5-51

Ilustración 53: Esquema general de aplicación con tracking

Ilustración 54: Detalle de conexión de encoder para tracking

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place5 Descripción del robot

● TRMODE=1 => Activa las funciones de tracking.

● EXTENC=(3,0,0,0,0,0) => Asocia M_ENC[0] con el encoder conectado al canal 1 del slot 2.

● P_ENCDLT=(?,?,?,0,0,?,0,0)1 => variable de posición que almacena el avance de la banda (en unidades cartesianas del sistema de referencia del robot) por cada pulso de encoder. Por ejemplo si P_ENCDLT=(0,0,0.001,0,0,0) quiere decir que por cada 1000 pulsos del encoder la banda se habrá desplazado 1mm en la dirección Y+ del robot. Este parámetro puede estimarse teóricamente a priori, pero es difícil asegurar un montaje exacto del sistema mecánico y mantener los distintos planos del robot y banda paralelos, por lo que lo aconsejable, y así se hace en este proyecto, es incluir un programa de calibración que permita la obtención de P_ENCDLT de forma empírica, una vez que el sistema está montado.

Una vez configurados los parámetros TRMODE y EXTENC, ya puede comprobarse la lectura del encoder con la variable de estado M_ENC (pulsos acumulados, al utilizarse un único encoder no es necesario el índice M_ENC[0] ya que lo toma por defecto). El contador M_ENC es cíclico entre el valor M_ENCMIN=0 y M_ENCMAX=1.000.000.000 (valores por defecto).

También pueden monitorizarse M_ENCSPD (frecuencia de encoder en pulsos/seg) y P_CVSPD (velocidad de banda, en mm/seg para las componentes lineales en las direcciones X,Y,Z y rad/seg para las componentes angulares en las direcciones A,B,C). Estas 2 variables están relacionadas lógicamente mediante P_ENCDLT, por tanto si este parámetro no se ha definido todavía correctamente, la velocidad P_CVSPD no será correcta.

Para la gestión de la acumulación de piezas pendientes de manipular, el software del robot prevee un buffer tipo FIFO donde ir almacenando parejas de variables de posiciones y de encoder asociado con la misma, de modo que cuando el sistema de visión capture una imagen para procesarla, el robot pueda almacenar junto con las posiciones encontradas el valor de encoder en el momento de la captura de imagen, y así pueda siempre actualizar esas posiciones escalando el recorrido de encoder con el parámetro P_ENCDLT. El buffer también puede incorporar un entero en el rango 1 a 65535 como identificador del tipo de objeto. Las funciones y variables asociadas a este buffer son las siguientes:

● TRWRT PCAP,MCAP => almacena la posición PCAP y el valor de encoder MCAP en el buffer. Se pueden añadir los argumentos opcionales Tipo de producto, Número de buffer (puede haber hasta 8), y Número de encoder.

● TRRD PCAP,MCAP => extrae de buffer la posición y encoder más antiguos, y los almacena en PCAP y MCAP.

● TRCLR => borra el buffer.

● M_TRBFCT => variable de estado que indica el número de registros actual del buffer.

● TRCWDST => este parámetro es una distancia en mm que el controlador utiliza para filtrar los registros entrados al buffer evitando duplicidad de una misma pieza. Por defecto es 5mm, quiere decir que cada posición con su valor de encoder es actualizada al valor de encoder actual, y comparada con la actualización del resto de registros del buffer. Si la distancia a alguna otra es inferior a 5mm, se considera la misma y se descarta.

1 Las coordenadas A y B son necesariamente 0 para el SCARA RH5, además de L1 y L2 puesto que no hay ejes adicionales interpolados en este proyecto.

Ingeniería en Automática y Electrónica Industrial 5-52

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place5 Descripción del robot

La instrucción TRK es la que activa en sí el seguimiento, si no se ejecuta TRK ON todo el resto de funciones no tienen efecto en cuanto al movimiento del robot se refiere. Cuando se activa el modo tracking con TRK ON, el robot se mueve solidario con la banda. Un simple programa con la única instrucción TRK ON (se incluye en el proyecto como TTR.prg) es bastante ilustrativo, si se ejecuta y se mueve la banda incluso manualmente, el robot la seguirá. Si se le obliga a salir de su zona alcanzable se provoca un error H2160. La sintaxis completa de esta instrucción es la siguiente:

Después de ejecutar la instrucción, el robot actualiza continuamente al valor actual de la posición PTRK que llamaremos PTRKactual, escalando con P_ENCDLT:

PTRKactual=PTRK+(M_ENCactual – MTRK) * P_ENCDLT

Ingeniería en Automática y Electrónica Industrial 5-53

TRK ON PTRK MTRK POSICIONREF(defecto P_ZERO) NºENC(defecto 0)

Ejemplo: TRK ON P1,M1

Texto 11: Sintaxis de instrucción TRK

Ilustración 55: Desplazamiento de objeto desde captura hasta manipulación

Instante de capturaM_ENC=MTRK

Y+

X+

Y+

X+

POBJ

Y+

X+

POBJ

PTRK

Instante actualM_ENC=M_ENCactual

PTRKactual

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place5 Descripción del robot

Además la posición PTRKactual la utilizará como sistema de referencia para las instrucciones de movimiento que se ejecuten durante el modo tracking, es decir, si se ejecutan las líneas que se muestran en Texto 12: Instrucciones de modo tracking, la operación PTRKactual*POBJ es la composición relativa de la posición POBJ respecto de la posición PTRKactual, por tanto si POBJ son las coordenadas de posición de la pieza respecto del origen del sistema de visión artificial, y PTRKactual es ese origen, el robot se moverá hacia la pieza objetivo siguiendo su movimiento en la cinta.

En Ilustración 55: Desplazamiento de objeto desde captura hasta manipulación se representa

esta situación, en un caso simplificado en que los sistemas de referencia del sistema de visión y el

Ingeniería en Automática y Electrónica Industrial 5-54

TRK ON PTRK MTRK ' Activa modo tracking

MOV POBJ ' Mueve a PTRKactual*POBJ

TRK OFF ' Fin de modo tracking

Texto 12: Instrucciones de modo tracking

Ilustración 56: Sistema multitarea del robot

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place5 Descripción del robot

robot tienen la misma orientación.

5.5 Función multitareaEl sistema operativo del robot prevee la ejecución simultánea de hasta 32 programas diferentes,

con un espacio de variable globales que pueden compartir, y una serie de funciones para cargar y ejecutar estos programas (Ilustración 56: Sistema multitarea del robot). Los distintos programas se pueden ejecutar automáticamente al encender el robot, arrancándolos desde el panel de operación o entradas digitales, o bien siendo llamados desde otros programas.

El control de equipos externos mediante comunicaciones es muy indicado para utilizar esta capacidad del robot, puesto que se estructura la programación y se facilita la depuración.

Ingeniería en Automática y Electrónica Industrial 5-55

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place6 Configuración y programación del Robot

6 Configuración y programación del Robot

6.1 Parámetros de configuración del robotPara la configuración del robot se han modificado los parámetros que se detallan a continuación,

indicando el valor asignado y la función.

6.1.1 Parámetros generales● PRGUSR=”UBP” => define el programa contenedor de las definiciones de las variables

globales que se utilizarán

● BZR=0 => desconecta el dichoso pitido cuando se produce una alarma.

6.1.2 Parámetros de comunicaciones● CPRC13=2 => especifica modo Data Link para puerto OPT13

● COMDEV[2]=OPT13 => asigna puerto OPT13 a COM3

6.1.3 Parámetros para la función de tracking● TRMODE=1 => Activa las funciones de tracking.

● EXTENC=(3,0,0,0,0,0) => Asocia M_ENC[0] con el encoder conectado al canal 1 de la tarjeta de encoder en slot 2.

● P_ENCDLT=(?,?,?,0,0,?,0,0)2 => variable de posición que almacena el avance de la banda (en unidades cartesianas del sistema de referencia del robot) por cada pulso de encoder. En este proyecto el valor teórico suponiendo un montaje preciso en la posición que se indica en Ilustración 59: Matriz de rotación genérica, teniendo en cuenta que la banda avanza 81,68mm/revMOTOR en dirección -Y, y la resolución del encoder es de 4000pulsos/revmotor, resulta

P_ENCDLT=(0,-81.68/4000,0,0,0,0,0,0)=(0,-0.02042,0,0,0,0,0,0)

Para obtener este parámetro de forma empírica se utilizan los programas CLE1 y CLE2, que se describen más adelante. En cualquier caso hay que esperar P_ENCDLT.C=0, incluso asegurarlo por programa, puesto que lo contrario significaría que la cinta tiene rotación respecto del robot, y produciría errores en las composiciones finales de los movimientos.

2 Las coordenadas A y B son necesariamente 0 para el SCARA RH5, además de L1 y L2 puesto que no hay ejes adicionales interpolados en este proyecto.

Ingeniería en Automática y Electrónica Industrial 6-56

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place6 Configuración y programación del Robot

● TRCWDST=20 => Distancia en mm mínima para considerar dos posiciones diferentes en el buffer de tracking.

6.2 Listado y descripción de los programas escritos para el robotA continuación se listan los programas que se han escrito en el robot, las funciones que realiza y

la forma de ejecución prevista.

● MAIN: programa principal que se debe arrancar desde el panel de operación (por tanto se ejecuta en SLOT 1) para poner en marcha el sistema. Este programa accede al buffer de posiciones leidas y realiza los movimientos para la manipulación de las piezas, utilizando las funciones de tracking del robot.

● COM: programa de comunicaciones y gestión del buffer de posiciones leidas. Es arrancado por MAIN y ejecutado en SLOT 2, gestiona las comunicaciones con el PC mediante el servidor TCP/IP, convierte las posiciones leidas al sistema de referencia del robot, las ordena y las almacena en el buffer.

● CLE1,CLE2: programas para la calibración del encoder de banda, obteniendo P_ENCDLT. Se deben ejecutar secuencialmente desde el panel de operación, según se detalla en el capítulo de calibración de encoder.

● CLV1,CLV2,CLV3,CLV4: programas para la calibración de la posición relativa del sistema de visión artifical.Se deben ejecutar secuencialmente desde el panel de operación, según se

Ingeniería en Automática y Electrónica Industrial 6-57

Ilustración 57: Variable de escalado de encoder P_ENCDLT

Encoder: 4000pul/rev

Avance de banda: 81,68mm/revMOTOR

P_ENCDLT:(0,-0.02042,0,0,0,0,0,0)

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place6 Configuración y programación del Robot

detalla en el capítulo de calibración de visión.

● UBP: programa para declaración de variables globales, nunca se ejecuta.

● TTR: programa para test de la función de tracking, cuando se arranca desde el panel de operación el robot queda solidario con la banda, si se mueve incluso manualmente el robot debe seguirla. Sirve para confirmar que los parámetros de configuración de la función de tracking están correctamente.

6.3 Implementación de la función de trackingEn el programa MAIN se implementa la manipulación de las piezas detectadas, utilizando el

seguimiento de encoder que proporciona la instrucción TRK. Como se explicó en el capítulo descriptivo del robot, cuando se activa el modo tracking con TRK ON PTRK MTRK, el robot se mueve solidario con la banda y actualiza continuamente al valor actual de la posición PTRK que llamaremos PTRKactual, escalando con P_ENCDLT:

PTRKactual=PTRK+(M_ENCactual – MTRK) * P_ENCDLT

Además la posición PTRKactual la utilizará como sistema de referencia para las instrucciones de movimiento que se ejecuten durante el modo tracking, es decir, si se ejecutan las líneas que se muestran en Texto 13: Instrucciones de modo tracking, la operación PTRKactual*POBJ es la composición relativa de la posición POBJ respecto de la posición PTRKactual, por tanto si POBJ son las coordenadas de posición de la pieza respecto del origen del sistema de visión artificial, y PTRKactual es ese origen, el robot se moverá hacia la pieza objetivo siguiendo su movimiento en la cinta.

En lo sucesivo se denominarán P_ORGV≡PTRK (Posición ORiGen de sistema de visión) la posición de referencia de tracking y PV≡POBJ (Posición respecto Visión).

Hay que tener en cuenta también que la composición P_ORGVactual*PV la realiza el robot en el sistema de coordenadas de herramienta, es decir, considerando que P_ORGVactual es la posición del extremo útil de la herramienta, y si está girado la composición se hace conforme a ese giro. De esta forma se simplifica la operación en caso de modificar la herramienta o de trabajar con varias a la vez, puesto que todas las operaciones siguen siendo válidas simplemente modificando P_TOOL.

Si los sistemas de referencia tienen la misma orientación, hay que asegurarse de que P_ORGV.A=P_ORGV.B=P_ORGV.C=0 y poco más, porque si por ejemplo P_ORGV.C<>03 el robot realiza una rotación de las coordenadas XOBJ e YOBJ según ese ángulo P_ORGV.C.3 La composición se hace concretamente sobre P_ORGVactual, pero puesto que la banda se mueve en línea recta, o

sea, se desplaza sin rotar respecto del robot, necesariamente P_ENCDLT.C=0 por tanto durante todo el recorrido P_ORGVactual.C=P_ORGV.C.

Ingeniería en Automática y Electrónica Industrial 6-58

TRK ON PTRK MTRK ' Activa modo tracking

MOV POBJ ' Mueve a PTRKactual*POBJ

TRK OFF ' Fin de modo tracking

Texto 13: Instrucciones de modo tracking

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place6 Configuración y programación del Robot

Para considerar la rotación del sistema caben 2 posibilidades4:

1. Registrar esa rotación en la variable P_ORGV, en las componentes de rotación A,B,C. Por ejemplo en el caso de Ilustración 58: Rotación simple de sistema de visión respecto delrobot, donde dada la posición de la cámara determina un sistema de coordenadas rotado respecto del robot en torno al eje Y, por tanto debería ser P_ORGV.B=180. Sin embargo esta forma es bastante compleja de modelar si hay más de una rotación, y la calibración empírica tampoco es simple.

2. Mantener P_ORGV=(P_ORGV.X,P_ORGV.Y,P_ORGV.Z,0,0,0,0,0) y procesar la rotación con funciones matemáticas en el robot. En general para obtener una posición PB=(xB,yB,zB) respecto de un sistema B, que está rotado respecto de un sistema A, se construye una matriz de rotación donde cada fila es un vector unitario del sistema A respecto de B, de la forma siguiente:

En este caso la cámara ya fija la situación relativa de los ejes X e Y, por tanto con el ángulo β que se muestra en x la orientación está totalmente determinada, y la matriz de rotación se simplifica como se muestra en Ilustración 60: Matriz de rotación particularizada.

En este proyecto se resuelve la orientación por este segundo método, de modo que el robot cuando recibe las posiciones del sistema de visión las transforma con las líneas de programa de Texto 14: Sentencias para la rotación en el programa del robot.

Durante el proceso de instalación y puesta en marcha del sistema será necesario por tanto determinar el origen del sistema de visión, que se almacenará en la variable global de usuario

4 Considerando siempre que el robot será el encargado de procesar la información y realizar la calibración necesaria, de modo que el sistema de visión se limite a enviar las posiciones halladas (convertidas eso sí de pixel a mm.).

Ingeniería en Automática y Electrónica Industrial 6-59

Ilustración 59: Matriz de rotación genérica

Ilustración 58: Rotación simple de sistema de visión respecto del robot

Y+

X+Y+

X+Sistema Visión Sistema Robot

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place6 Configuración y programación del Robot

P_ORGV, así como el ángulo β que se almacena en M_RVBETA. Ambos se obtienen mediante los programas de calibración CLV1,CLV2,CLV3,CLV4.

Por último falta indicar que la coordenada PV.C se puede utilizar para dar a la pinza una orientación determinada, medida respecto del sistema del robot puesto que P_ORGV.C=0. Si se quiere orientar la pieza en base a la posición angular que detecte el sistema de visión, entonces debe referirse a éste sumando el ángulo β según se muestra en Ilustración 61: Rotación y orientación depieza, con PV.C = θR = β + θV (si el sentido positivo de ángulo de visión coincide con el robot) .

En caso de tener una aplicación sin visión artificial, únicamente con un detector de barrera para

Ingeniería en Automática y Electrónica Industrial 6-60

Ilustración 60: Matriz de rotación particularizada

140 PROBOT=P_ZERO

150 PROBOT.X=COS(M_RVBETA)*VX+SIN(M_RVBETA)*VY ' ROTACION del sistema de vision respecto del robot

160 PROBOT.Y=SIN(M_RVBETA)*VX-COS(M_RVBETA)*VY ' ROTACION del sistema de vision respecto del robot

Texto 14: Sentencias para la rotación en el programa del robot

Ilustración 61: Rotación y orientación de pieza

θR

Y+

X+

Y+

X+

Sistema VisiónSistema Robot

β

θV

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place6 Configuración y programación del Robot

capturar el paso del producto, la operación se simplificaría y sólo sería necesario conocer la posición del objeto en el momento de la activación del sensor (con un proceso de calibración correpondiente). Esta posición sería P_ORGV, y el seguimiento se haría haciendo un movimiento a P_ZERO, puesto que la posición relativa es nula:

El robot debe almacenar en buffer el valor de encoder (MTRK) para cada detección de producto. En este caso la orientación deseada de la herramienta sería más sencillo almacenarla en P_ORGV.C, es decir, registrarla en el proceso de calibración.

6.4 Procedimiento de calibración del encoder de bandaPara obtener P_ENCDLT mediante un procedimiento empìrico una vez instalado el sistema

completo, se realiza un procedimiento que se denomina calibración de encoder banda, y los programas CLE1.prg y CLE2.prg se utilizan para tal fin. Los pasos a realizar son los siguientes:

1. Colocar una pieza en la zona de trabajo del robot, mejor hacia un extremo, y llevar la herramienta del robot hasta situarlo sobre la pieza. Esto se puede hacer mediante la consola de mano trabajando en modo JOG (con SERVO ON), o bien por tratarse de un SCARA con los motores parados (SERVO OFF) empujando el brazo robot, ya que los ejes J1,J2 y J4 no tienen freno, y el eje J3 (vertical) que si tienen freno se puede liberar con el pulsador J3 BRAKE RELEASE. Ejecutar el programa CLE1.prg, que registrará la posición y valor de encoder en las variables globales P_CLEA (PA) y M_CLEA (MENCA) respectivamente.

2. A continuación avanzar la banda manualmente, con cuidado de que la pieza no deslice, hasta situarla hacia el otro extremo del rango del robot.

3. Llevar el robot hasta la pieza igual que en el paso 1. La orientación no es importante mantenerla puesto que de todas formas las componentes A,B y C se pondrán a 0 por programa (las componentes A y B no intervienen en el SCARA, pero se hace genéricamente). Si no se hace así y durante el movimiento manual se mueve alguna orientación, después se reflejará este movimiento durante la operación de tracking.

Ingeniería en Automática y Electrónica Industrial 6-61

TRK ON PTRK MTRK ' Activa modo tracking

MOV P_ZERO ' Mueve a PTRKactual

TRK OFF ' Fin de modo tracking

Texto 15: Sentencias para tracking sin visión, 1ª forma

TRBASE PTRK ' Sistema de referencia general

TRK ON PTRK MTRK ' Activa modo tracking

MOV PTRK ' Mueve a PTRKactual

TRK OFF ' Fin de modo tracking

Texto 16: Sentencias para tracking sin visión, 2ª forma

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place6 Configuración y programación del Robot

Ingeniería en Automática y Electrónica Industrial 6-62

150 MENCDIF#=M_CLEB-M_CLEA ' MENCDIF# es el avance del encoder

160 ' Corrección de MENCDIF#

165 RANGO#=M_ENCMAX-M_ENCMIN ' Fondo de escala del contador de encoder

170 IF MENCDIF#<(-RANGO#/2) THEN MENCDIF#= MENCDIF# + RANGO# + M_ENCMIN ' Corrección movimiento decremental encoder

171 IF MENCDIF#>(RANGO#/2) THEN MENCDIF#=MENCDIF#-RANGO#-M_ENCMIN ' Corrección movimiento incremental encoder

180 '

190 P_ENCDLT=(P_CLEB-P_CLEA)/(MENCDIF#) ' Calculo de P_ENCDLT

195 P_ENCDLT.C=0 ' Si al pasar de A a B se ha cambiado la orientación de la herramienta, se desprecia

Texto 17: Sentencias para obtener P_ENCDLT en el robot

Ilustración 62: Procedimiento de calibrado de encoder. Obtención de P_ENCDLT

PA, MENCA

PB, MENCB

1

2

3

4

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place6 Configuración y programación del Robot

4. Ejecutar el programa CLE2.prg, que registrará la posición y valor de encoder en las variables globales P_CLEB (PB) y M_CLEB (MENCB) respectivamente, y calculará P_ENCDLT.

Todas las variables utilizadas antes son globales y por tanto retentivas, de modo que el programa CLE2 tiene acceso a las variables obtenidas por CLE1. También pueden consultarse a posteriori incluso tras desconectar el robot para conprobar el resultado de la calibración. Las líneas de programa para el cálculo de P_ENCDLT se muestran en Texto 21: Representación gráfica delorden de manipulación de las piezas detectadas.

Es necesario contemplar una posible correción del avance del encoder, porque el contador M_ENC es cíclico y si se desborda por M_ENCMIN (defecto 0) toma el valor M_ENCMAX (defecto 1.000.000.000), y viceversa. Puede ocurrir entonces que si se conecta alimentación al robot para hacer la calibración del encoder de banda, con lo cual M_ENC=0 (esta variable no es retentiva), y la banda se mueve un poco en el sentido decremental del encoder, la variable M_CLEA tome un valor muy alto (por ejemplo M_CLEA=999.999.999 si se mueve 1 pulso), y si se avanza por ejemplo 1000 pulsos de encoder en sentido incremental, se tiene

MENCDIF = M_CLEB-M_CLEA = 999 – 999.999.999 = -999.999.000 !!

Sin embargo al aplicar la corrección:

MENCDIF = -999.999.000 + 1.000.000.000 = 1000 ☺

De igual modo ocurriría si la calibración se hiciera en el sentido decremental de la banda, partiendo de M_ENC=0, entonces:

MENCDIF = 999.999.999 – 0 – 1.000.000.000 = -1000 ☺

Observar que el sentido de avance en el proceso de la calibración puede ser cualquiera, lo que no puede ocurrir es que se tengan medidas fuera de un rango del contador de encoder.

6.5 Procedimiento de calibración del sistema de referencia del equipo de visión artificial

6.5.1 Transformación entre Sistema de Visión y Sistema de Robot Tal y como se ha concluido en el capítulo sobre las funciones de tracking del robot, es necesario

para la operación de la aplicación determinar la posición relativa del sistema de referencia con que trabaja el equipo de visión artificial, respecto del sistema de referencia del robot. Expresando la posición del objeto con coordenadas extendidas[5], la traslación y rotación se concentran en la matriz de transformación de Ilustración 63: Matriz de transformación completa genérica.

En nuestra aplicación, la disposición relativa de ambos sistema se muestra en Ilustración 62:Procedimiento de calibrado de encoder. Obtención de P_ENCDLT5. La matriz de transformación se simplifica entonces, puesto que la posición relativa de los ejes X e Y está fijada por la cámara de visión, y el eje Z será coincidente porque practicamente cámara y robot trabajan en el mismo plano6. Por tanto toda la rotación se recoge en el ángulo M_RVBETA. La traslación a su vez se

5 En este capítulo el tratamiento de las piezas se hace considerándolas puntuales, y su orientación por tanto no se considera. Los ángulos βV (orientación vista por el sistema de visión) y βV (orientación respecto del robot para ajustar la coordenada C de la herramienta) se tratan en el capítulo sobre las funciones de tracking.

6 La banda puede tener un desplazamiento vertical durante su recorrido que tampoco afecta a esta consideración,

Ingeniería en Automática y Electrónica Industrial 6-63

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place6 Configuración y programación del Robot

recogerá en P_ORGV, resultando la expresión de Ilustración 64: Matriz de transformacióncompleta particularizada.

El proceso de calibración servirá para obtener las variables P_ORGV y M_RVBETA de forma empírica, una vez instalado el sistema, al igual que se hace al obtener P_ENCDLT, que de hecho debe haberse obtenido previamente puesto que se utilizará en este procedimiento.

En primer lugar se obtiene P_ORGV calibrando sobre un punto P1A situado en el origen del sistema de visión, y después se obtiene βRV a partir de otro punto P2A situado en el campo de visión

con ambas coordenadas no nulas.

puesto que en la variable P_ENCDLT.Z de calibración del encoder de banda ya se recoge. Hay que considerar que el plano sobre el que se sitúa la pieza en la captura de la imagen, se mantiene durante la manipulación del robot puesto que la banda es plana, luego si la ventosa de succión puede absorber esa inclinación, recogerá la pieza en la posición vista por la cámara sin problemas.

Ingeniería en Automática y Electrónica Industrial 6-64

Ilustración 63: Matriz de transformación completa genérica

Ilustración 64: Matriz de transformación completa particularizada

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place6 Configuración y programación del Robot

6.5.2 Obtención de P_ORGV (traslación entre sistemas de referencia)Si el robot tiene a su alcance el campo de visión, para obtener P_ORGV basta situar una pieza en

el origen del sistema, y llevar el robot hasta esa pieza. Pero normalmente no es el caso y el campo de visión está fuera del rango del robot, por tanto será necesario llevar esa pieza de referencia hasta donde el robot pueda alcanzarla, y medir el avance del encoder de banda para restar la cantidad de movimiento correspondiente en cada coordenada, según P_ENCDLT. El proceso se ilustra en Ilustración 57: Variable de escalado de encoder P_ENCDLT.Los pasos a realizar son los siguientes:

Ingeniería en Automática y Electrónica Industrial 6-65

Ilustración 65: Sistemas de referencia en una posición arbitraria de banda y equipo de visión

βR

Y+

X+Y+

X+

Sistema Robot

βV

X+

V0 (P_ORGV)

(M_RVBETA)ΒRV

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place6 Configuración y programación del Robot

1. Colocar una pieza centrada en el origen del campo de visión. Para ello poner la cámara en modo VIDEO y utilizar una pieza circular marcada para que pueda situarse facilmente en la esquina superior izquierda, que es donde está el origen del sistema de visión. Una vez situada en la imagen sólo debe verse ¼ de la pieza, lógicamente. Ejecutar el programa CLV1.prg y entonces el PC registrará el valor de encoder en la variable global M_CLV1A (MENC1A).

2. A continuación avanzar la banda manualmente, con cuidado de que la pieza no deslice, hasta situarla en el rango del robot.

3. Llevar el robot hasta la pieza. La orientación no es importante mantenerla puesto que de todas formas las componentes A,B y C se pondrán a 0 por programa (las componentes A y

Ingeniería en Automática y Electrónica Industrial 6-66

180 MENCDIF#=M_CLV1B-M_CLV1A ' MENCDIF es el avance del encoder

190 P_CLV1A=P_CLV1B-P_ENCDLT*MENCDIF# ' Mediante P_ENCDLT se obtiene la posicion A respecto al robot

200 P_ORGV=P_CLV1A ' Final

Texto 18: Sentencias para obtener P_ORGV en el robot

Ilustración 66: Procedimiento de calibrado de origen de visión. Obtención de P_ORGV

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place6 Configuración y programación del Robot

B no intervienen en el SCARA, pero se hace genéricamente). Si no se hace así la composición final de movimientos no será correcta..

4. Ejecutar el programa CLV2.prg, que registrará la posición y valor de encoder en las variables globales P_CLV1B (P1B) y M_CLV1B (MENC1B) respectivamente, y calculará P_ORGV.

Todas las variables utilizadas antes son globales y por tanto retentivas, de modo que el programa CLV2 tiene acceso a las variables obtenidas por CLV1. También pueden consultarse a posteriori incluso tras desconectar el robot para conprobar el resultado de la calibración. Las líneas de programa para el cálculo de P_ORGV son las de Texto 20: Bucle de ordenado de posiciones en elrobot.

6.5.3 Obtención de βRV (rotación entre sistemas de referencia)El procedimiento es similar al anterior, pero ahora la pieza se debe situar en un punto del campo

de visión donde las coordenadas sean ambas no nulas, para no tener argumentos nulos en la función atan2 (ver Ilustración 67: Procedimiento de calibrado de rotación de visión. Obtención de βRV.). Lo ideal es alejar lo más posible la pieza del origen, para reducir los errores del cálculo de posición del sistema de visión, al relativizarlos con medidas mayores. Los pasos a realizar son los siguientes:

1. Colocar una pieza en el campo de visión. Una vez situada en la imagen ejecutar el programa CLV3.prg, que se queda a la espera de la posición vista desde el PC. En el PC ejecutar

Ingeniería en Automática y Electrónica Industrial 6-67

Ilustración 67: Procedimiento de calibrado de rotación de visión. Obtención de βRV.

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place6 Configuración y programación del Robot

“Enviar X Y”, y entonces el PC registrará esa posición y el valor de encoder en las variables globales P_VA y M_CLV2A (MENC2A).

2. A continuación avanzar la banda manualmente, con cuidado de que la pieza no deslice, hasta situarla en el rango del robot.

3. Llevar el robot hasta la pieza. La orientación no es importante mantenerla puesto que de todas formas la componente C se pondrá a 0 por programa (las componentes A y B no intervienen en el SCARA).

4. Ejecutar el programa CLV4.prg, que registrará la posición y valor de encoder en las variables globales P_CLV2B (P2B) y M_CLV2B (MENC2B) respectivamente, y calculará P_ORGV.

Todas las variables utilizadas antes son globales y por tanto retentivas, de modo que el programa CLV4 tiene acceso a las variables obtenidas por CLV3. También pueden consultarse a posteriori incluso tras desconectar el robot para conprobar el resultado de la calibración.

Las líneas de programa para el cálculo de M_RVBETA son las de Texto 16: Sentencias paratracking sin visión, 2ª forma.

Ingeniería en Automática y Electrónica Industrial 6-68

180 MENCDIF#=M_CLV2B-M_CLV2A ' MENCDIF es el avance del encoder

190 P_CLV2A=P_CLV2B-P_ENCDLT*MENCDIF# ' Mediante P_ENCDLT se obtiene la posicion A respecto al robot

200 XREL=P_CLV2A.X-P_ORGV.X ' Posicion X relativa

210 YREL=P_CLV2A.Y-P_ORGV.Y ' Posicion Y relativa

215 AUXHOR=XREL*P_VA.X-YREL*P_VA.Y

216 AUXVER=XREL*P_VA.Y+YREL*P_VA.X

220 M_RVBETA=ATN2(AUXVER,AUXHOR) ' Se obtiene la rotación del sistema de visión respecto del sistema del robot

230 M_RVBETG=DEG(M_RVBETA) ' Valor en grados para monitorización

Texto 19: Sentencias para obtener M_RVBETA en el robot

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place6 Configuración y programación del Robot

6.6 Ejecución multitarea de programas de manipulación y comunicaciones

Después de haber realizado los procedimientos de calibración el sistema está operativo, y se puede poner en marcha el programa MAIN para la ejecución automática de la manipulación de

Ingeniería en Automática y Electrónica Industrial 6-69

Ilustración 68: Coordinación entre programas de manipulación y comunicaciones

Carga y arrancaslot 2 : COM

Extrae registro depila de tracking

Manipula pieza

Espera comandodel PC

Recibido“PCTrigger”

?

Captura valorde encoder M_ENC

Espera comandodel PC

RecibidoDatosPosicion

?

Guarda Datos yencoder en Buffer

si procede

Recibido“PCTrigger”

?

ROBOTSLOT1: MAIN.prg

ROBOTSLOT2: COM.prg

Espera que hayadatos en pila de

tracking

Espera que lapieza esté en

rango alcanzable PILA TRACKING

(FIFO)

Ordena posicionessegún situaciónde robot y cinta

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place6 Configuración y programación del Robot

piezas. Este programa a su vez arranca a COM, y ambos se ejecutan paralelamente:

● COM se comunica con el PC y después de procesar los datos almacena en el buffer de tracking las posiciones de las piezas a manipular

● MAIN está pendiente del buffer y va sacando los datos. Cuando una posición está a su alcance va a cogerla y la suelta en la posición prevista.

El planteamiento es robusto puesto que los programas son independientes, y el sincronismo temporal entre ambos no es crítico, en cuanto que no importa en que momento COM ha guardado una posición en el buffer, puesto que MAIN la recogerá junto con un valor de encoder asociado que le permite localizar la posición actual, en base al avance medido de encoder. Este valor está en la variable global M_ENC y por tanto ambos programas pueden acceder a su lectura. El diagrama de flujo de esta secuencia se ilustra en Ilustración 68: Coordinación entre programas de manipulacióny comunicaciones.

6.7 Estructura de subrutinas del programa de comunicacionesEl programa COM se ha escrito basado en subrutinas, de modo que cuando espera una orden del

Ingeniería en Automática y Electrónica Industrial 6-70

Ilustración 69: Diagrama de subrutinas utilizadas en COM

Espera trama del PC, con formato genérico:INPUT CORDEN$,CNCICLOS$,VX,VY,VTHETA,NPIEZA,NPZAS

CORDEN$=”PCTrigger” Subrutina *TRIGGER

ROBOTSLOT2: COM.prg

CORDEN$=”Datos”

CORDEN$=”Cero”

Subrutina *DATOS

Subrutina *CERO

Subrutina *ORDENA

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place6 Configuración y programación del Robot

PC, en función de la orden recibida realiza una función determinada. Puesto que la secuencia de órdenes no tiene por qué siempre ser la misma, de esta forma se garantiza que el programa no se quedará descontrolado si el PC envía las distintas tramas en un orden no esperado. Además se utiliza una única instrucción INPUT con un formato de instrucción común para todas las órdenes, aunque no se utilicen algunos “argumentos”, de esta forma si hay una descoordinación en la secuencia de órdenes el robot no queda en estado de error por recibir datos en “Illegal Format”.

6.8 Criterio de ordenación de las posiciones detectadasEl sistema de visión artificial ordena las piezas localizadas en función del sentido de barrido de la

imagen, sin embargo para el robot es más interesante seguir un orden de manipulación en función de la dirección de avance de la cinta, porque de lo contrario alguna pieza puede ir alejándose y entonces el tiempo necesario para cogerla se alarga, perdiendo efectividad el proceso de pick&place. El ordenado de las piezas lo hace el robot en el programa COM, utilizando el vector P_ENCDLT que al fin y al cabo es un vector en la dirección de avance de la cinta. Para medir este avance se utiliza el producto escalar del vector posición de la pieza, después de hacerle la rotación necesaria para referirlo al sistema de referencia del robot (RPV1 y RPV2 en Ilustración 69: Diagramade subrutinas utilizadas en COM), con el vector P_ENCDLT, resultando el valor de proyección de uno sobre otro, multiplicado por el módulo de P_ENCDLT:

Ingeniería en Automática y Electrónica Industrial 6-71

Ilustración 70: Criterio para ordenar las piezas detectadas según el avance en la banda

Y+

X+P_ENCDLT

Sistema Robot

P_ORGV

RPV1

RPV2

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place6 Configuración y programación del Robot

Las posiciones cuando se reciben se almacenan en un array temporal PARRAY(20) y se extrae el avance de cada una en MAVANCE(20) mediante la expresión:

MAVANCE(N)=P_ENCDLT.X*PARRAY(N).X+P_ENCDLT.Y*PARRAY(N).Y

Posteriormente se recorre un número de veces suficiente el vector PARRAY(20) comparando el avance de cada posición con la consecutiva, y permutando ambas si procede, como se muestra en Texto 15: Sentencias para tracking sin visión, 1ª forma.

Ingeniería en Automática y Electrónica Industrial 6-72

560 FOR VUELTAS=1 TO NPZAS ' Vueltas para asegurar que todas las posiciones se mueven como deben, creo que sobra una

570 FOR M=1 TO NPZAS-1 ' Recorrido del array hasta penúltimo580 N=M+1590 IF MAVANCE(M)<MAVANCE(N) THEN 600 PTEMP=PARRAY(M)605 MTEMP=MAVANCE(M)610 PARRAY(M)=PARRAY(N)620 MAVANCE(M)=MAVANCE(N)630 PARRAY(N)=PTEMP640 MAVANCE(N)=MTEMP650 ENDIF660 NEXT670 NEXT672 FOR N=1 TO NPZAS ' Solo queda enviar el array ordenado al

buffer de tracking673 PAUX=PARRAY(N)674 TRWRT PAUX,MCAP# ' La posicion (x,y) y el valor de

encoder asociado a la captura se guardan en buffer676 NEXTTexto 20: Bucle de ordenado de posiciones en el robot

Texto 21: Representación gráfica del orden de manipulación de las piezas detectadas

AVANCE1=∥ PV 1R ∥⋅cos1=

PV 1R ⋅P ENCDLT∥P ENCDLT∥

AVANCE 2=∥ PV 2R ∥⋅cos2=

PV 2R ⋅P ENCDLT∥P ENCDLT∥

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place7 Control de estados y comunicaciones en el PC

7 Control de estados y comunicaciones en el PCEn este capítulo se describen las funciones de control general de la aplicación que realiza el PC,

incluyendo los modos de trabajo MANUAL y AUTO, la ejecución secuencial de los procesos de visión artificial, y la gestión de las comunicaciones.

7.1 Modos de trabajo y funciones relacionadasPara que el sistema tenga un funcionamiento en contínuo con un cierto grado de robustez se han

implementado secuencias de control tanto en el PC como en el Robot, que tienen puntos de encuentro en las comunicaciones TCP/IP. Para comprender bien el conjunto hay que tener presente los modos de trabajo MANUAL y AUTO que se muestran en Ilustración 71: Modos de trabajo dela aplicación general.

Ingeniería en Automática y Electrónica Industrial 7-73

Ilustración 71: Modos de trabajo de la aplicación general

Modo MANUAL:Ejecución independiente de losprocesos de tratamiento de imagen.Herramientas auxiliares paradepuración.Conexión y desconexión con robot, envío de posición y de cero.

Modo AUTO:Ejecución secuencial de captura,tratamiento de imagen, comunicacióny visualización de gráficas, según opciones seleccionadas.

FOTOCaptura imagen y

muestra en Display1

HISTOGRAMAObtiene histograma,umbral por Otsu ymuestra gráficas.

BINARIZAImagen binaria, semuestra en Display2

BUSQUEDALocaliza posición

de piezas

VIDEOModo video en

Display1

Archivo ImagenSu pueden cargar ysalvar imagenessobre Display1

Herramientas VisiónVarias utilidades decopia, inversión,etc

Herramientas RobotConexión y envío deposiciones patrón

START 1 CICLO:Ejecuta 1 vez ActionCompleto,que incluye:

FOTO+

HISTOGRAMA+

BINARIZA+

BUSQUEDA+

COMUNICACIÒN

START CONTINUOEjecuta hastapulsar STOP

ActionCompleto,que incluye:

FOTO+

HISTOGRAMA+

BINARIZA+

BUSQUEDA+

COMUNICACIÒN

Inicio

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place7 Control de estados y comunicaciones en el PC

En modo MANUAL las funciones se ejecutan por eventos y el control secuencial no es necesario, las pulsaciones de los botones u opciones de menús correspondientes generan las llamadas a los eventos y a las acciones correspondientes. Lo único a tener en cuenta es el orden manual de ejecución, por ejemplo si se ejecuta BINARIZA sin haber hecho antes FOTO y seleccionar un

Ingeniería en Automática y Electrónica Industrial 7-74

Ilustración 72: Máquina de estados en modo AUTO

Leyenda

Preparado

Inicio

Marcha1CicloEnProceso

Fin ActionCompleto

MarchaContinuoEsperando

Timer1

MarchaContinuoEnProceso

Fin ActionCompleto

Estado

Pulsación 1 CICLO Pulsación CONTINUO

Evento

Pulsación STOP

Enum Estado {Alarma, Preparado, MarchaContinuoEsperando, MarchaContinuoEnProceso, Marcha1CicloEnProceso};

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place7 Control de estados y comunicaciones en el PC

umbral, no es de esperar un resultado muy allá.

En modo AUTO sin embargo, las acciones se ejecutan secuencialmente y entonces se requiere un control de la secuencia, mas allá de las soluciones rápidas de inhabilitar botones y tal, puesto que siguen interviniendo llamadas a eventos de Windows (por ejemplo Timer) que no están controladas en tiempo real y pueden provocar el solapamiento de funciones. Por ejemplo si se solapan las comunicaciones el sincronismo de mensajes se pierde y puede haber varias preguntas seguidas sin respuesta o respuestas que no corresponden. Aunque se ha previsto la actuación en este caso, se trata de evitar al máximo que ocurra.

7.2 Máquina de estados en C++ para control de secuenciaPara establecer una secuencia robusta, en el modo AUTO se implementa una máquina de estados

con una variable de tipo enumerado (enum Estado EstadoAuto) accesible por todas las funciones, de modo que cada función consulte antes de hacer nada si la aplicación se encuentra en un estado válido, y si procede realice su función y modifique a su vez el estado en que queda la aplicación. El diagrama se muestra en Ilustración 72: Máquina de estados en modo AUTO.

Para ello se necesitan variables globales, que se han implementado en una clase denominada Global, que incorpora también otras variables globales de la aplicación, y los métodos de acceso necesarios, como se muestra en Texto 22: Variables relacionadas con máquina de estados en modoAUTO.

Ingeniería en Automática y Electrónica Industrial 7-75

Enum Estado {Alarma, Preparado, MarchaContinuoEsperando, MarchaContinuoEnProceso, Marcha1CicloEnProceso};

class Global

{

private:

static enum Estado EstadoAuto;

public

static void Para() { EstadoAuto=Preparado; }

static enum Estado GetEstado() { return EstadoAuto; }

static void NuevoEstado(Estado newEstado) { EstadoAuto=newEstado; }

};

enum Estado Global::EstadoAuto;

int Global::Nciclos;

Texto 22: Variables relacionadas con máquina de estados en modo AUTO

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place7 Control de estados y comunicaciones en el PC

Esta clase Global se utiliza únicamente como contenedor de variables globales, y no se declarará ningún elemento de esta clase. Las variables son de tipo static (en private:) y por tanto se garantiza que unicamente hay una copia. Además se definen las funciones de acceso también de tipo static (en public:). Esta solución (frente a la declaración directa) produce un código más portable al no “contaminar” el espacio de nombres, y permite crear diversas funciones de acceso y controlar así la forma de interactuar con estas variables globales[6].

7.3 Control de comunicaciones Ethernet entre PC y RobotPara transmitir la información desde el sistema de visión artificial hacia el robot se utiliza una

conexión Ethernet con protocolo TCP/IP, el robot actúa como servidor y el PC como cliente. Puesto que hay un único PC y un único robot, es posible utilizar tanto esta forma como la contraria, pero resulta más sencillo utilizar el robot como servidor de modo que arranca y se pone en modo escucha, y es el PC el que deberá confirmar la conexión e iniciar la secuencia de comunicaciones. Realmente una vez establecida la conexión tanto cliente como servidor pueden enviar y recibir mensajes indistintamente. En caso de un PC con varios robots, o una conexión entre varios robots, sería necesario utilizar el modo cliente del robot.

El robot utiliza por defecto el puerto NETPORT[1]=10000 en modo CPRCE11=0 (No Procedure) para la comunicación con el software de programación y monitorización RT Toolbox, de modo que a través de Ethernet se configura y programa el robot (podría utilizarse también el puerto serie RS232 del frontal del controlador). En esta aplicación se ha configurado además el puerto 10003 con la función Data Link en modo Server para el intercambio de datos con el PC, modificando los parámetros que se muestran en Tabla 2: Parámetros para configuración decomunicaciones en el robot, mediante Maintenance Tool de RT Toolbox.

Parámetro Valor ExplicaciónNETIP 192,168,0,1 (Por defecto) Dirección IP del controlador.NETPORT[3] 10003 (Por defecto) Puerto asignado para OPT13CPRCE13 2 Modo Data Link para OPT13COMDEV[2] OPT13 Puerto COM3 asignado para OPT13NETMODE[2] 1 (Por defecto) Modo Server para OPT13

Tabla 2: Parámetros para configuración de comunicaciones en el robotLas instrucciones necesarias en el robot son OPEN y CLOSE7 para abrir y cerrar el puerto, y las

instrucciones INPUT y PRINT para recibir y enviar datos, que deben ser cadenas de texto con terminación CR (“\n”). El carácter “,” en la entrada se interpreta como separación de cadenas, de modo que la instrucción INPUT impone un formato y máscara a los datos recibidos, y si no hay coincidencia se genera un error 3500 (Ilegal Format Data).

7 Esta instrucción es además la que borra el buffer del servidor, además claro está de la instrucción INPUT que extrae los datos. Es importante considerar que si el robot se para pulsando STOP (realmente es PAUSA) o se detiene por una alarma, y se reinicia continuando por donde iba (sin pulsar RESET hasta apagar el LED de STOP), el buffer tiene todos los datos que haya recibido en el periodo de pausa o error, y sólo con CLOSE se garantiza el borrado.

Ingeniería en Automática y Electrónica Industrial 7-76

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place7 Control de estados y comunicaciones en el PC

En el PC las comunicaciones se resuelven mediante un componente VCL denominado IdTCPClient, que provee de los métodos y propiedades necesarios para gestionar los socket de Windows, nombre genérico que engloba a las funciones de bajo nivel que gestionan los puertos de comunicaciones. Estos componentes pertenecen a un conjunto de componentes de código abierto (denominado Indy, Internet Direct, ver Ilustración 74: Extracto de la web www.indyproject.org) que se incluyen en Delphi y Borland C++ Builder, se pueden considerar equivalentes a los componentes WinSock de Microsoft (las primeras versiones de Indy se denominaron WinShoes, con humor).

Ingeniería en Automática y Electrónica Industrial 7-77

Ilustración 73: Propiedades de IdTCPClient y IdAntiFreeze

Ilustración 74: Extracto de la web www.indyproject.org

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place7 Control de estados y comunicaciones en el PC

Ingeniería en Automática y Electrónica Industrial 7-78

Ilustración 75: Diagrama de flujo de la secuencia de comunicaciones

Envía “PCTrigger”+Nciclo

al Robot

Captura imagen

Recibido“ACKPCTrigger”Nciclo correcto

?

Procesa imagen

EnvíaDatosPosicion

al Robot

Recibido“ACKDatos”

?

Espera comandodel PC

Recibido“PCTrigger”

?

Captura valorde encoder M_ENC

Envía “ACKPCTrigger”+ Nciclo al PC

Espera comandodel PC

RecibidoDatosPosicion

?

Informa del fallo

Envía “ACKDatos”

al PC

Guarda Datos yencoder en Buffer

si procede

Recibido“PCTrigger”

?

PCActionCompleto

ROBOTSLOT2: COM.prg

Procesa imagenInforma del fallo

FIN

Hay piezasdetectadas

?

Borrado de bufferde entrada

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place7 Control de estados y comunicaciones en el PC

La conexión que ofrece IdTCPCliente es de tipo bloqueante, es decir, cuando se ejecuta un comando de lectura o escritura la aplicación queda ocupada hasta la terminación del comando, y si se trata de una lectura y aún no hay datos se produce un bloqueo de la aplicación8. Se ha incluido un parámetro timeout para la lectura de modo que si no responde el robot en el tiempo prefijado se continúa, no obstante esta solución tampoco es muy buena porque durante ese tiempo por ejemplo no se puede pulsar el botón STOP de la aplicación, ni hacer nada.

La solución más adecuada sería trabajar con distintos hilos de ejecución (Threads), no obstante

8 Si fuera de tipo no bloqueante se necesitaría gestionar mensajes de windows para confirmar la terminación de la lectura y se hace más complejo el control de las comunicaciones.

Ingeniería en Automática y Electrónica Industrial 7-79

Ilustración 76: Diagrama de flujo de la secuencia de comunicaciones, modo simple sin respuesta del robot

Envía “PCTrigger”+Nciclo

al Robot

Captura imagen

Procesa imagen

EnvíaDatosPosicion

al Robot

Espera comandodel PC

Recibido“PCTrigger”

?

Captura valorde encoder M_ENC

Espera comandodel PC

RecibidoDatosPosicion

?

Guarda Datos yencoder en Buffer

si procede

Recibido“PCTrigger”

?

PCActionCompleto

ROBOTSLOT2: COM.prg

FIN

Hay piezasdetectadas

?

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place7 Control de estados y comunicaciones en el PC

esta aplicación es bastante simple, y basta incluir el componente IdAntiFreeze, que permite el funcionamiento de la interfaz de Windows durante la ejecución de los comandos de Indy.

Los comandos utilizados son InputLn() y WriteLn() que gestionan la recepción y envío de mensajes de texto, con carácter de terminación CR por defecto al igual que el robot.

Una vez establecida la comunicación, y trabajando en modo AUTO, los programas del PC y el robot deben trabajar en modo coordinado, y de una forma robusta ante fallos, para lo que se implementan las secuencias mostradas en Ilustración 75: Diagrama de flujo de la secuencia decomunicaciones. Cada mensaje del PC hacia el robot tienen una respuesta de confirmación asociada, para que el PC pueda informar al usuario de posibles errores. Realmente se podría trabajar con un esquema más simple eliminando esas respuestas, como se muestra en Ilustración 73:Propiedades de IdTCPClient y IdAntiFreeze.

El comando “PCTrigger” es utilizado como señal de sincronismo entre el instante de la captura de la imagen por parte del PC, y la captura del valor del encoder de banda por parte del robot, puesto que ambos dispositivos no están bajo el mismo controlador. Inmediatamente después de la captura, el PC envía “PCTrigger”y posteriormente se entretiene en el tratamiento de la imagen. Se añade una variable contador de ciclos para identificar que el PC identifique que la respuesta de confirmación corresponde efectivamente al trigger que acaba de enviar, puesto que en caso de pausa o error, como se explicaba anteriormente, el robot puede acumular comandos en su buffer y cuando arranca responde a todos seguidamente, provocando un error puesto que el encoder captado corresponde a otro instante, y entonces las posiciones que asocia el robot están fuera de rango durante la operación de tracking.

Puesto que puede no haber datos que enviar, se prevee en el robot la recepción consecutivas de comandos “PCTrigger”. En el programa COM el argumento de formato de la instrucción INPUT tiene una cadena inicial CORDEN$ que indica si el mensaje es un trigger (CORDEN$= ”PCTrigger”) o son datos válidos (CORDEN$= “Datos”)9.

9 También se contempla una posible orden (CORDEN$ = “Cero”) para test, que permite enviar desde el menú Herramientas Robot una posición cero y comprobar que P_ORGV se ha calibrado correctamente al hacer que se posicione sobre esta posición, desplazada por el valor de avance de encoder.

Ingeniería en Automática y Electrónica Industrial 7-80

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place8 Conclusiones

8 ConclusionesLa integración de todos los equipos se ha realizado con éxito, en cuanto que el sistema completo

realiza la inspección y manipulación de las piezas como estaba planteado conseguir.

Respecto del sistema de visión artificial empleado se puede concluir que:

1. El sistema basado en PC industrial y la cámara basada en IEEE1394 resulta una solución efectiva y flexible, que de hecho cada vez más terreno en el mercado frente a las clásicas tarjetas grame grabber.

2. En este proyecto los tiempos de proceso completo (sin preprocesado) están por debajo de 500ms, para una resolución de imagen de 320x240 de 8 bits, lo cual es suficiente teniendo en cuanto que la inspección es de varias piezas, y la manipulación del robot para esa tarea es bastante más lenta.

3. El método de Otsu resulta un eficaz procedimiento para establecer un umbral automático enla binarización de la imagen. No obstante como todo proceso automático está sujeto a riesgos, y si los reflejos en la banda aumentaran de intensidad por un cambio en las condiciones de luz, se requeriría modificar el umbral mínimo programado actualmente. En una aplicación industrial, lo ideal sería fijar las condiciones con iluminación artificial y prescindir de este proceso de forma contínua, dejándolo para la puesta en marcha.

4. Los algoritmos de erosión y segmentación no han resultado suficientes para discriminar las piezas que vienen en contacto, por lo que se requeriría implementar otros procedimientos que trabajen considerando la forma del objeto y no simplemente su tamaño.

En cuanto a la tarea del robot, puede concluirse lo siguiente:

1. La configuración tipo SCARA ha resultado adecuada a la aplicación por tratarse de trabajo en plano horizontal, y facilita la implantación del sistema al no tener que considerar rotaciones en torno a los ejes X e Y.

2. La definición de la zona de trabajo del robot es muy importante para conseguir una velocidad total elevada, puesto que en determinadas posturas el robot ofrece una velocidad lineal muy baja respecto de sus posibilidades.

3. También es fundamental para optimizar el rendimiento del sistema, la estrategia a seguir en el orden de la manipulación del sistema. Este capítulo posiblemente daría para un trabajo específico, puesto que al final el parámetro global que vendría a caracterizar un sistema de manipulación de este tipo es la producción (pzas/minuto) que ofrece.

De un modo más general, cabe concluir también la importancia que tiene la definición de una secuencia de control general y de comunicaciones suficientemente robusta para que un sistema de este tipo pudiera trabajar en una aplicación real durante horas sin tener contínuas paradas.

Ingeniería en Automática y Electrónica Industrial 8-81

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place9 Bibliografía

9 Bibliografía

Bibliografía1: Matrox, ActiveMil User Guide,Documento WWW2: F. Charte, C++ Builder 2006,Anaya 3: Mathwork, Toolbox Images Documentation,Documento WWW4: MITSUBISHI ELECTRIC, Mitsubishi Industrial Robot:Detailed Explanation of function and operations,Documentación técnica 5: A. Ollero, ROBÓTICA Manipuladores y robots móviles,Marcombo 6: B. Swart, M.Cashman, P. Gustavson, J.Hollinworth, Borland C++ Builder 6 Developer's Guide,Sams

Ingeniería en Automática y Electrónica Industrial 9-82

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

10 Listado de programas de C++ Builder

10.1 Código fuente principal VisionV7.cpp//---------------------------------------------------------------------------

#include <vcl.h>#pragma hdrstop//---------------------------------------------------------------------------USEFORM("Unit1_VisionV7.cpp", Form1);//---------------------------------------------------------------------------int invierte(SAFEARRAY* psaimagenIN,SAFEARRAY* psaimagenOUT,int anchopix);

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int){ try { Application->Initialize(); Application->CreateForm(__classid(TForm1), &Form1); Application->Run(); } catch (Exception &exception) { Application->ShowException(&exception); } catch (...) { try { throw Exception(""); } catch (Exception &exception) { Application->ShowException(&exception); } } return 0;}

//---------------------------------------------------------------------------

10.2 Código fuente Unit1_VisionV7.cpp//---------------------------------------------------------------------------

#include <vcl.h>#pragma hdrstop

#include "Unit1_VisionV7.h"//---------------------------------------------------------------------------#pragma package(smart_init)

Ingeniería en Automática y Electrónica Industrial 10-83

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

#pragma link "MIL_OCX"#pragma resource "*.dfm"TForm1 *Form1;//---------------------------------------------------------------------------#define ValorBinarioBajo 0#define ValorBinarioAlto 255#define NivelesGris 256#define UmbralOtsuMinimo 20 // Minimo umbral automatico admitido#define TimeoutTCP 500 // ms#define MaximoEtiquetas 500 // Limite de etiquetas en barrido etiquetado#define MaximoClases 50 // Maximo-1 objetos distintos en etiquetado#define AnchoPeriferia 10 // Ancho considerado de la periferia, en pixeles#define MaxPixPeriferia 100 // Maximo de pixeles permitidos en periferia#define PixToMm 0.650 // Factor de conversión de pixeles a mm#define MinPequeno 1300 // Número de pixeles mínimo para círculo pequeño#define MaxPequeno 1800 // Número de pixeles máximo para círculo pequeño#define MinGrande 2750 // Número de pixeles mínimo para círculo grande#define MaxGrande 3250 // Número de pixeles máximo para círculo grande#define OrdenDeMascara 3 // Orden IMPAR de matriz de máscara en Erosión#define OrdenDeMascaraMediana 3 // Orden IMPAR de mascara en filtrado mediana//---------------------------------------------------------------------------/* Variables test,son réplicas globales de variables locales, para permitiracceso al debugger cuando se pausa la aplicación. Pueden verse con Watch */double histogramatest[NivelesGris],vectoromegatest[NivelesGris];double vectorsigmabsquaredtest[NivelesGris];int PixSizetest;int enlacestest[MaximoEtiquetas],clasestest[MaximoEtiquetas];int etiquetas[640][480];//double histograma[NivelesGris],vectoromega[NivelesGris];int EtiquetaMaximatest,ClaseMaximatest;int cnt[10],cntsolapamientos,cntsolapamientos1ciclo;//---------------------------------------------------------------------------enum Estado {Alarma,Preparado,MarchaContinuoEsperando,MarchaContinuoEnProceso, Marcha1CicloEnProceso};

class Global{private: static int XCG[MaximoClases]; static int YCG[MaximoClases]; static int TipoPieza[MaximoClases]; static int Npiezas; static enum Estado EstadoAuto; static int Nciclos;public: static void SetXCG(int n,int newXCG) { XCG[n]=newXCG; } static int GetXCG(int n) { return XCG[n]; } static void SetYCG(int n,int newYCG) { YCG[n]=newYCG; } static int GetYCG(int n) { return YCG[n]; } static void SetNpiezas(int newNpiezas) { Npiezas=newNpiezas; } static int GetNpiezas() { return Npiezas; } static void NuevoEstado(Estado newEstado) { EstadoAuto=newEstado; } static void Para() { EstadoAuto=Preparado; } static enum Estado GetEstado() { return EstadoAuto; } static void SetNCiclos(int newNciclos) { Nciclos=newNciclos; } static void IncNciclos() { Nciclos++; } static int GetNciclos() { return Nciclos; }};

Ingeniería en Automática y Electrónica Industrial 10-84

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

int Global::XCG[MaximoClases];int Global::YCG[MaximoClases];int Global::TipoPieza[MaximoClases];int Global::Npiezas;enum Estado Global::EstadoAuto;int Global::Nciclos;

//---------------------------------------------------------------------------

//---------------------------------------------------------------------------__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner){}//---------------------------------------------------------------------------

void __fastcall TForm1::ButtonGrabClick(TObject *Sender){ ActionCaptura->Execute();}//---------------------------------------------------------------------------void __fastcall TForm1::ButtonGrabContClick(TObject *Sender){ Digitizer1->GrabContinuous(); // Graba sobre Imagemil1}//---------------------------------------------------------------------------void __fastcall TForm1::ButtonHaltClick(TObject *Sender){ Digitizer1->Halt();}//---------------------------------------------------------------------------void __fastcall TForm1::ButtonCopiaClick(TObject *Sender){ //vimagen.parray=Global::Getpsaimagen1(); //ImageMil2->Put(vimagen,imSingleBand,imAllBands,0,0,SizeX,SizeY);}//---------------------------------------------------------------------------

void __fastcall TForm1::ButtonInvertClick(TObject *Sender){ //invierte(Global::Getpsaimagen2(),Global::Getpsaimagen2(),255);

//vimagen.parray=Global::Getpsaimagen2(); //ImageMil2->Put(vimagen,imSingleBand,imAllBands,0,0,SizeX,SizeY);

}//---------------------------------------------------------------------------

void __fastcall TForm1::ScrollBarUmbralChange(TObject *Sender){ StaticTextUmbral->Caption=AnsiString(ScrollBarUmbral->Position);}//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)

Ingeniería en Automática y Electrónica Industrial 10-85

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

{ StaticTextUmbral->Caption=AnsiString(ScrollBarUmbral->Position);

/* Al crear el SAFEARRAY se invierten los componentes de rgsabound porque el SAFEARRAY almacena los datos por columnas (tipo BASIC o FORTRAN) en lugar de por filas como C++. Así el compilador garantiza que los direccionamientos [i][j] van a funcionar correstamente. Creo.

ShowMessage( "Tras SafeArrayCreate SizeX= "+AnsiString(SizeX)+"\n" "psaimagen1->rgsabound[0].cElements= "+ AnsiString(psaimagen1->rgsabound[0].cElements)+"\n" "SizeY= "+AnsiString(SizeY)+"\n" "psaimagen1->rgsabound[0].cElements= " + AnsiString(psaimagen1->rgsabound[1].cElements)+"\n" ); */

Global::NuevoEstado(Preparado); StatusBarInfo->Panels->Items[1]->Text= "ESTADO AUTO: Preparado"; StatusBarInfo->Panels->Items[2]->Text="TCP SERVER ROBOT: pendiente"; SpeedButtonAuto->Click();

/* Tamaño de imagen en función del escalado de Digitizer */ ImageMil1->SizeX=static_cast<long>(640*Digitizer1->ScaleX); ImageMil1->SizeY=static_cast<long>(480*Digitizer1->ScaleY); ImageMil2->SizeX=ImageMil1->SizeX; ImageMil2->SizeY=ImageMil1->SizeY;

}//---------------------------------------------------------------------------

void __fastcall TForm1::ButtonBinarizaClick(TObject *Sender)

{ ActionBinariza->Execute();}//---------------------------------------------------------------------------

void __fastcall TForm1::ButtonExitClick(TObject *Sender){ ImageMil1->Free(); ImageMil2->Free(); Digitizer1->Free(); SYSTEM1->Free(); exit(0);}//---------------------------------------------------------------------------

void __fastcall TForm1::ImageMil1ContentModified(TObject *Sender, long OffsetX, long OffsetY, long SizeX, long SizeY){ ShowMessage("Evento Imagen 1 modificada");}//---------------------------------------------------------------------------

void __fastcall TForm1::ButtonHistogramaClick(TObject *Sender)

Ingeniería en Automática y Electrónica Industrial 10-86

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

{ ActionHistograma->Execute(); ButtonHistograma->SetFocus(); // Para no repetir en modo paso a paso}//---------------------------------------------------------------------------

void __fastcall TForm1::ButtonCGClick(TObject *Sender){ ActionBusqueda->Execute();}

//---------------------------------------------------------------------------

void __fastcall TForm1::IdTCPClient1Connected(TObject *Sender){ StatusBarInfo->Panels->Items[2]->Text="TCP SERVER ROBOT: CONECTADO";}//---------------------------------------------------------------------------

void __fastcall TForm1::IdTCPClient1Disconnected(TObject *Sender){ StatusBarInfo->Panels->Items[2]->Text="TCP SERVER ROBOT: DESCONECTADO"; CheckBoxComunicate->Checked=FALSE;}//---------------------------------------------------------------------------

void __fastcall TForm1::ButtonConnectClick(TObject *Sender){ if(! IdTCPClient1->Connected()) IdTCPClient1->Connect();}//---------------------------------------------------------------------------

void __fastcall TForm1::ButtonDisconnectClick(TObject *Sender){ if(IdTCPClient1->Connected()) IdTCPClient1->Disconnect();}//---------------------------------------------------------------------------

void __fastcall TForm1::ButtonWriteClick(TObject *Sender){ AnsiString XCGstring,YCGstring;

if(IdTCPClient1->Connected()) { XCGstring=AnsiString(Global::GetXCG(0)); XCGstring=AnsiString(Global::GetXCG(0)); IdTCPClient1->WriteLn(XCGstring+","+YCGstring); }}//---------------------------------------------------------------------------

void __fastcall TForm1::ButtonReadClick(TObject *Sender){/*if(IdTCPClient1->Connected()) { LabeledEditLectura->Text=(IdTCPClient1->ReadLn("F",1000)); if (LabeledEditLectura->Text=="")

Ingeniería en Automática y Electrónica Industrial 10-87

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

LabeledEditLectura->Text="Lectura vacia"; else LabeledEditEncoder->Text=(IdTCPClient1->ReadLn("F",1000));

}*/}

//---------------------------------------------------------------------------

void __fastcall TForm1::TimerInfoTimer(TObject *Sender){ long Tiempo; // long deliberadamente para casting a ms Tiempo=1000*(App1->Timer->Read()); StatusBarInfo->Panels->Items[0]->Text=" Reloj "+AnsiString(Tiempo);

/*switch (Global::GetEstado()) {

case Alarma: { StatusBarInfo->Panels->Items[1]->Text="ESTADO AUTO: Alarma"; break; } case MarchaContinuoEsperando:{ StatusBarInfo->Panels->Items[1]->Text="ESTADO AUTO: Continuo,Esperando"; break; } case MarchaContinuoEnProceso: { StatusBarInfo->Panels->Items[1]->Text="ESTADO AUTO: Continuo,En Proceso"; cnt[9]++; break; } case Preparado: { StatusBarInfo->Panels->Items[1]->Text="ESTADO AUTO: Preparado"; break; } case Marcha1CicloEnProceso: { StatusBarInfo->Panels->Items[1]->Text="ESTADO AUTO: 1 Ciclo,En Proceso"; break; } } */

}//---------------------------------------------------------------------------

void __fastcall TForm1::LabeledEditOnChange(TObject *Sender){ /* Situacion de cuelgue while (LabeledEditOn->Text==1) { //Form1->ButtonTodo->Click(); } */}//---------------------------------------------------------------------------

void __fastcall TForm1::Digitizer1CameraPresent(TObject *Sender){

Ingeniería en Automática y Electrónica Industrial 10-88

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

ShowMessage("Camara presente"); }//---------------------------------------------------------------------------

void __fastcall TForm1::ButtonEtiquetadoClick(TObject *Sender){ActionEtiquetado->Execute();}//---------------------------------------------------------------------------

void __fastcall TForm1::CargarClick(TObject *Sender){ImageMil1->Load(NULL,0);// ImageMil1->Load(NULL,0); Ajusta imagen al tamaño del display}//---------------------------------------------------------------------------

void __fastcall TForm1::SalvarClick(TObject *Sender){ImageMil1->Save(NULL);}//---------------------------------------------------------------------------

void __fastcall TForm1::HistogramapasoapasoClick(TObject *Sender){ if (Histogramapasoapaso->Checked==FALSE) Histogramapasoapaso->Checked=TRUE; else Histogramapasoapaso->Checked=FALSE;}//---------------------------------------------------------------------------

void __fastcall TForm1::OtsupasoapasoClick(TObject *Sender){ if (Otsupasoapaso->Checked==FALSE) Otsupasoapaso->Checked=TRUE; else Otsupasoapaso->Checked=FALSE;}//---------------------------------------------------------------------------

void __fastcall TForm1::ImagenizdadchaClick(TObject *Sender){ VARIANT vimagen; SAFEARRAY* psaimagen=NULL; SAFEARRAYBOUND rgsabound[2]; const unsigned int cDims=2; int SizeX,SizeY;

/* Extracción de imagen desde ImageMil1 */ VariantInit(&vimagen); vimagen.vt=VT_ARRAY|VT_UI1; // tipo de dato: SAFEARRAY de UINT8

Ingeniería en Automática y Electrónica Industrial 10-89

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

SizeX=ImageMil1->SizeX; SizeY=ImageMil1->SizeY; rgsabound[0].cElements=SizeX; rgsabound[0].lLbound=0; rgsabound[1].cElements=SizeY; rgsabound[1].lLbound=0;

psaimagen=SafeArrayCreate(VT_UI1,cDims,rgsabound);

vimagen.parray=psaimagen;

ImageMil1->Get(&vimagen,imSingleBand,imAllBands,0,0,SizeX,SizeY);

/*Ya tenemos la imagen...................... */

ImageMil2->Put(vimagen,imSingleBand,imAllBands,0,0,SizeX,SizeY);

}//---------------------------------------------------------------------------

void __fastcall TForm1::InvierteimagendchaClick(TObject *Sender){ VARIANT vimagen,vimagenINV; SAFEARRAY *psaimagen=NULL,*psaimagenINV=NULL; SAFEARRAYBOUND rgsabound[2]; const unsigned int cDims=2; long rgIndices[2]; int SizeX,SizeY,PixMax;

unsigned char pixelIN,pixelOUT;

/* Extracción de imagen desde ImageMil2 */ VariantInit(&vimagen); vimagen.vt=VT_ARRAY|VT_UI1; // tipo de dato: SAFEARRAY de UINT8 VariantInit(&vimagenINV); vimagenINV.vt=VT_ARRAY|VT_UI1; // tipo de dato: SAFEARRAY de UINT8 SizeX=ImageMil2->SizeX; SizeY=ImageMil2->SizeY; rgsabound[0].cElements=SizeX; rgsabound[0].lLbound=0; rgsabound[1].cElements=SizeY; rgsabound[1].lLbound=0;

psaimagen=SafeArrayCreate(VT_UI1,cDims,rgsabound); psaimagenINV=SafeArrayCreate(VT_UI1,cDims,rgsabound);

vimagen.parray=psaimagen; vimagenINV.parray=psaimagenINV;

ImageMil2->Get(&vimagen,imSingleBand,imAllBands,0,0,SizeX,SizeY);

/*Ya tenemos la imagen...................... */

PixMax=(ImageMil1->MaximumPixelValue);

for(int i=0;i<SizeX;i++) { for(int j=0;j<SizeY;j++) {

Ingeniería en Automática y Electrónica Industrial 10-90

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

rgIndices[0]=i; rgIndices[1]=j; SafeArrayGetElement(psaimagen,rgIndices,&pixelIN); pixelOUT=PixMax-pixelIN; SafeArrayPutElement(psaimagenINV,rgIndices,&pixelOUT); }

} ImageMil2->Put(vimagenINV,imSingleBand,imAllBands,0,0,SizeX,SizeY); VariantClear(&vimagen); VariantClear(&vimagenINV);}//---------------------------------------------------------------------------

void __fastcall TForm1::ImagenpruebasimpleClick(TObject *Sender){ VARIANT vimagen; SAFEARRAY *psaimagen=NULL; SAFEARRAYBOUND rgsabound[2]; const unsigned int cDims=2; long rgIndices[2]; int SizeX,SizeY;

int ValorBajo,ValorAlto; unsigned char pixelOUT;

ValorBajo=0; ValorAlto=255;

VariantInit(&vimagen); vimagen.vt=VT_ARRAY|VT_UI1; // tipo de dato: SAFEARRAY de UINT8 SizeX=ImageMil2->SizeX; SizeY=ImageMil2->SizeY; rgsabound[0].cElements=SizeX; rgsabound[0].lLbound=0; rgsabound[1].cElements=SizeY; rgsabound[1].lLbound=0;

psaimagen=SafeArrayCreate(VT_UI1,cDims,rgsabound);

vimagen.parray=psaimagen;

for(int i=0;i<SizeX;i++) { for(int j=0;j<SizeY;j++) { rgIndices[0]=i; rgIndices[1]=j; pixelOUT=ValorBajo; if ((i>50)&(i<100)&(j>200)&(j<300)) pixelOUT=ValorAlto; SafeArrayPutElement(psaimagen,rgIndices,&pixelOUT); }

} ImageMil2->Put(vimagen,imSingleBand,imAllBands,0,0,SizeX,SizeY); VariantClear(&vimagen);}//---------------------------------------------------------------------------

Ingeniería en Automática y Electrónica Industrial 10-91

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

void __fastcall TForm1::EnviaceroaRobotClick(TObject *Sender){ if(IdTCPClient1->Connected()) IdTCPClient1->WriteLn("Cero,0,0,0,0,0"); else ShowMessage ("¡¡¡No hay conexión con el Robot!!!");}//---------------------------------------------------------------------------

void __fastcall TForm1::ConectarClick(TObject *Sender){ if(! IdTCPClient1->Connected()) { IdTCPClient1->Connect(); }}//---------------------------------------------------------------------------

void __fastcall TForm1::ButtonStartClick(TObject *Sender){ if (Global::GetEstado()==Preparado) Global::NuevoEstado(MarchaContinuoEsperando);

SpeedButtonManual->Enabled=FALSE; ButtonStart->Enabled=FALSE; ButtonStop->Enabled=TRUE;}//---------------------------------------------------------------------------

void __fastcall TForm1::ButtonStopClick(TObject *Sender){ Global::NuevoEstado(Preparado); StatusBarInfo->Panels->Items[1]->Text= "ESTADO AUTO: Preparado";

SpeedButtonManual->Enabled=TRUE; ButtonStart->Enabled=TRUE;

ActionCompleto->Tag=0; // Marca de proceso ocupado}//---------------------------------------------------------------------------

void __fastcall TForm1::ActionHistogramaExecute(TObject *Sender){ VARIANT vimagen; SAFEARRAY* psaimagen=NULL; SAFEARRAYBOUND rgsabound[2]; const unsigned int cDims=2; long rgIndices[2];

int SizeX,SizeY; unsigned char pixel,*puntpixel; double histograma[NivelesGris],vectoromega[NivelesGris]; double vectorsigmabsquared[NivelesGris];

double mu_T,mu,omega,sigma_b_squared,sigma_b_squared_MAX; int umbral_otsu; long Tini,Tfinhist,Tfinotsu; // long deliberadamente para casting a ms

Ingeniería en Automática y Electrónica Industrial 10-92

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

Tini=1000*(App1->Timer->Read());

/* Extracción de imagen desde ImageMil1 */ VariantInit(&vimagen); vimagen.vt=VT_ARRAY|VT_UI1; // tipo de dato: SAFEARRAY de UINT8 SizeX=ImageMil1->SizeX; SizeY=ImageMil1->SizeY; rgsabound[0].cElements=SizeX; rgsabound[0].lLbound=0; rgsabound[1].cElements=SizeY; rgsabound[1].lLbound=0;

psaimagen=SafeArrayCreate(VT_UI1,cDims,rgsabound);

vimagen.parray=psaimagen;

ImageMil1->Get(&vimagen,imSingleBand,imAllBands,0,0,SizeX,SizeY);

//puntpixel= (unsigned char *) psaimagen->pvData;

/*Ya tenemos la imagen...................... */

/* Obtención del histograma */ //ShowMessage("Voy a obtener histograma");

for(int h=0;h<NivelesGris;h++) histograma[h]=0; // Reset histograma

for(int i=0;i<SizeX;i++) { for(int j=0;j<SizeY;j++) { rgIndices[0]=i; rgIndices[1]=j; SafeArrayGetElement(psaimagen,rgIndices,&pixel ); histograma[pixel]+=1; //histograma[*puntpixel]+=1; } }

VariantClear(&vimagen); Tfinhist=1000*(App1->Timer->Read());

/* Metodo de Otsu. Primero se normaliza el histograma en [0,1] y se obtiene la media total*/ mu_T=0; for(int t=0;t<NivelesGris;t++){ histograma[t]=histograma[t]/(SizeX*SizeY); mu_T+=t*histograma[t];

if (Histogramapasoapaso->Checked==TRUE) ShowMessage( "histograma["+AnsiString(t)+"]="+ AnsiString(histograma[t]*SizeX*SizeY)+ "\nSizeX="+AnsiString(SizeX)+ "\nSizeY="+AnsiString(SizeY)+ "\nSizeX*SizeY="+AnsiString(SizeX*SizeY)+ "\nhistograma["+AnsiString(t)+"]="+

Ingeniería en Automática y Electrónica Industrial 10-93

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

AnsiString(histograma[t]) ); } StaticTextMedia->Caption="Media="+AnsiString((int)mu_T);

sigma_b_squared_MAX=0; mu=0; omega=0; if (mu_T>0) { for(int t=0;t<NivelesGris;t++){ /* Probabilidad de la clase t>umbral */ omega+=histograma[t]; /* media de la clase t<umbral */ mu+=t*histograma[t]; /* Zona útil del histograma 0.001-0.999 */ if ((omega>0.001)&&(omega<0.999)) /* VARIANZA ENTRE CLASES */ sigma_b_squared=((mu_T*omega-mu)*(mu_T*omega-mu))/ (omega*(1-omega)); else sigma_b_squared=0; /* vectores para mostrar en gráfico */ vectoromega[t]=omega; vectorsigmabsquared[t]=sigma_b_squared; if (sigma_b_squared>=sigma_b_squared_MAX) { sigma_b_squared_MAX=sigma_b_squared; umbral_otsu=t; } if (Otsupasoapaso->Checked==TRUE) ShowMessage("t="+AnsiString(t)+"\n"+ "omega="+AnsiString(omega)+"\n"+ "mu="+AnsiString(mu)+"\n"+ "(mu_T*omega-mu)="+AnsiString(mu_T*omega-mu)+"\n"+ "cuadrado="+AnsiString((mu_T*omega-mu)*(mu_T*omega-mu)) +"\n"+ "(omega*(1-omega))="+AnsiString(omega*(1-omega))+"\n"+ "sigma_b_squared="+AnsiString(sigma_b_squared));

/* Test Chart */ histogramatest[t]=histograma[t]; vectoromegatest[t]=vectoromega[t]; vectorsigmabsquaredtest[t]=vectorsigmabsquared[t]; PixSizetest=NivelesGris; } } else StaticTextMedia->Caption="Todo negro!";

StaticTextVarMax->Caption="VarMax="+AnsiString((int)sigma_b_squared_MAX);

/* Muestra el umbral calculado, y lo "convierte" en variable global */ if (umbral_otsu<UmbralOtsuMinimo) umbral_otsu=UmbralOtsuMinimo; ScrollBarUmbral->Position=umbral_otsu; StaticTextUmbral->Caption=AnsiString(umbral_otsu);

if (CheckBoxGrafica->Checked==TRUE) { /* Representación gráfica de histograma y vectores estadísticos */ ChartHistograma->Series[0]->Clear();

Ingeniería en Automática y Electrónica Industrial 10-94

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

ChartHistograma->Series[0]->AddArray( histograma, NivelesGris); ChartHistograma->Series[1]->Clear(); ChartHistograma->Series[1]->AddArray( vectoromega, NivelesGris); ChartHistograma->Series[2]->Clear(); ChartHistograma->Series[2]->AddArray( vectorsigmabsquared, NivelesGris); }

Tfinotsu=1000*(App1->Timer->Read()); StaticTextTHist->Caption="His "+AnsiString(Tfinhist-Tini)+"ms"; StaticTextTOtsu->Caption="Ots "+AnsiString(Tfinotsu-Tfinhist)+"ms"; }//---------------------------------------------------------------------------

void __fastcall TForm1::ActionCapturaExecute(TObject *Sender){ long Tini,Tfin; // long deliberadamente para casting a ms

Tini=1000*(App1->Timer->Read()); if (Digitizer1->GrabInProgress==TRUE) Digitizer1->Halt(); Digitizer1->Grab(); // Graba sobre ImageMil1

Tfin=1000*(App1->Timer->Read()); StaticTextTGrab->Caption="Fot "+AnsiString(Tfin-Tini)+"ms";

}//---------------------------------------------------------------------------

void __fastcall TForm1::ActionBinarizaExecute(TObject *Sender){ VARIANT vimagen,vimagenBIN; SAFEARRAY *psaimagen=NULL,*psaimagenBIN=NULL; SAFEARRAYBOUND rgsabound[2]; const unsigned int cDims=2; long rgIndices[2]; int SizeX,SizeY;

int umbral; unsigned char pixelIN,pixelOUT; long Tini,Tfin; // long deliberadamente para casting a ms

Tini=1000*(App1->Timer->Read());

umbral=ScrollBarUmbral->Position;

/* Extracción de imagen desde ImageMil1 */ VariantInit(&vimagen); vimagen.vt=VT_ARRAY|VT_UI1; // tipo de dato: SAFEARRAY de UINT8 VariantInit(&vimagenBIN); vimagenBIN.vt=VT_ARRAY|VT_UI1; // tipo de dato: SAFEARRAY de UINT8 SizeX=ImageMil1->SizeX; SizeY=ImageMil1->SizeY; rgsabound[0].cElements=SizeX; rgsabound[0].lLbound=0; rgsabound[1].cElements=SizeY; rgsabound[1].lLbound=0;

Ingeniería en Automática y Electrónica Industrial 10-95

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

psaimagen=SafeArrayCreate(VT_UI1,cDims,rgsabound); psaimagenBIN=SafeArrayCreate(VT_UI1,cDims,rgsabound);

vimagen.parray=psaimagen; vimagenBIN.parray=psaimagenBIN;

ImageMil1->Get(&vimagen,imSingleBand,imAllBands,0,0,SizeX,SizeY);

/*Ya tenemos la imagen en psaimagen */

for(int i=0;i<SizeX;i++) { for(int j=0;j<SizeY;j++) { rgIndices[0]=i; rgIndices[1]=j; SafeArrayGetElement(psaimagen,rgIndices,&pixelIN); if (pixelIN<=umbral) pixelOUT=ValorBinarioBajo; else pixelOUT=ValorBinarioAlto; SafeArrayPutElement(psaimagenBIN,rgIndices,&pixelOUT); }

}

/* Ya tenemos la imagen binarizada en psaimagenBIN */

ImageMil2->Put(vimagenBIN,imSingleBand,imAllBands,0,0,SizeX,SizeY);

VariantClear(&vimagen); VariantClear(&vimagenBIN);

Tfin=1000*(App1->Timer->Read()); StaticTextTBin->Caption="Bin "+AnsiString(Tfin-Tini)+"ms";

}//---------------------------------------------------------------------------

void __fastcall TForm1::ActionBusquedaExecute(TObject *Sender){ VARIANT vimagen; SAFEARRAY* psaimagen=NULL; SAFEARRAYBOUND rgsabound[2]; const unsigned int cDims=2; long rgIndices[2];

int SizeX,SizeY; unsigned char pixel; long x,y,den;

int CGpix[2],CGmm[2],Npix,Npiezas; long Tini,Tfin; // long deliberadamente para casting a ms

Tini=1000*(App1->Timer->Read());

/* Extracción de imagen desde ImageMil2 */ VariantInit(&vimagen); vimagen.vt=VT_ARRAY|VT_UI1; // tipo de dato: SAFEARRAY de UINT8 SizeX=ImageMil1->SizeX;

Ingeniería en Automática y Electrónica Industrial 10-96

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

SizeY=ImageMil1->SizeY; rgsabound[0].cElements=SizeX; rgsabound[0].lLbound=0; rgsabound[1].cElements=SizeY; rgsabound[1].lLbound=0;

psaimagen=SafeArrayCreate(VT_UI1,cDims,rgsabound);

vimagen.parray=psaimagen;

ImageMil2->Get(&vimagen,imSingleBand,imAllBands,0,0,SizeX,SizeY);

/*Ya tenemos la imagen...................... */

x=y=den=0; for(int i=0;i<SizeX;i++) { for(int j=0;j<SizeY;j++) { rgIndices[0]=i; rgIndices[1]=j; SafeArrayGetElement(psaimagen,rgIndices,&pixel); /* Para cada pixel...*/ x=x+i*(pixel==ValorBinarioAlto); y=y+j*(pixel==ValorBinarioAlto); den=den+(pixel==ValorBinarioAlto); } }

VariantClear(&vimagen);

if (den==0) { CGpix[0]=(SizeX/2); CGpix[1]=(SizeY/2); } else { CGpix[0]=(int)(x/den); CGpix[1]=(int)(y/den); } Npix=den;

GraphicContext1->DrawingRegion->CenterX=CGpix[0]; GraphicContext1->DrawingRegion->CenterY=CGpix[1]; GraphicContext1->Cross(45);

CGmm[0]=PixToMm*CGpix[0]; CGmm[1]=PixToMm*CGpix[1];

/* Comprobacion del tipo de pieza detectada */

if ((Npix>6500)&&(Npix<7500)) { Npiezas=1; //StaticTextTipoImagen->Caption="CIRC.PEQUEÑO"; } else { if ((Npix>11500)&&(Npix<13000)) { Npiezas=1; //StaticTextTipoImagen->Caption="CIRC.GRANDE"; } else {

Ingeniería en Automática y Electrónica Industrial 10-97

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

Npiezas=0; //StaticTextTipoImagen->Caption="COSAS RARAS"; } }

Global::SetNpiezas(Npiezas); Global::SetXCG(0,CGmm[0]); Global::SetYCG(0,CGmm[1]);

//StaticTextCG->Caption="CG="+AnsiString(CGmm[0])+","+AnsiString(CGmm[1]); //StaticTextNpix->Caption="Nºpix="+AnsiString(Npix);

Tfin=1000*(App1->Timer->Read()); StaticTextTCG->Caption="Sim "+AnsiString(Tfin-Tini)+"ms";

}

//---------------------------------------------------------------------------

void __fastcall TForm1::TimerRunTimer(TObject *Sender){ if (Global::GetEstado()==MarchaContinuoEsperando) { cnt[6]++; Global::NuevoEstado(MarchaContinuoEnProceso); StatusBarInfo->Panels->Items[1]->Text= "ESTADO AUTO: Continuo,En Proceso"; //ActionCompleto->Execute(); ActionCompletoMultiple->Execute(); if (Global::GetEstado()==MarchaContinuoEnProceso) { cnt[7]++; Global::NuevoEstado(MarchaContinuoEsperando); StatusBarInfo->Panels->Items[1]->Text= "ESTADO AUTO: Continuo,Esperando"; } } else { if (Global::GetEstado()==MarchaContinuoEnProceso) cntsolapamientos++; } cnt[8]++;}//---------------------------------------------------------------------------

void __fastcall TForm1::SpeedButtonManualClick(TObject *Sender){ ButtonGrab->Enabled=TRUE; ButtonHistograma->Enabled=TRUE; ButtonBinariza->Enabled=TRUE; ButtonCG->Enabled=TRUE; ButtonGrabCont->Enabled=TRUE; ButtonErosion->Enabled=TRUE; ButtonEtiqueta->Enabled=TRUE; ArchivoImagen->Enabled=TRUE; HerramientasVision->Enabled=TRUE; HerramientasRobot->Enabled=TRUE;

Ingeniería en Automática y Electrónica Industrial 10-98

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

ButtonStart->Enabled=FALSE; ButtonStop->Enabled=FALSE; ButtonStart1Ciclo->Enabled=FALSE;

}//---------------------------------------------------------------------------

void __fastcall TForm1::SpeedButtonAutoClick(TObject *Sender){ ButtonGrab->Enabled=FALSE; ButtonHistograma->Enabled=FALSE; ButtonBinariza->Enabled=FALSE; ButtonCG->Enabled=FALSE; ButtonGrabCont->Enabled=FALSE; ButtonErosion->Enabled=FALSE; ButtonEtiqueta->Enabled=FALSE; ArchivoImagen->Enabled=FALSE; HerramientasVision->Enabled=FALSE; HerramientasRobot->Enabled=FALSE;

ButtonStart->Enabled=TRUE; ButtonStop->Enabled=TRUE; ButtonStart1Ciclo->Enabled=TRUE;

}//---------------------------------------------------------------------------

void __fastcall TForm1::ButtonStart1CicloClick(TObject *Sender){ if (Global::GetEstado()==Preparado) { Global::NuevoEstado(Marcha1CicloEnProceso); StatusBarInfo->Panels->Items[1]->Text= "ESTADO AUTO: 1 Ciclo,En Proceso"; //ActionCompleto->Execute(); ActionCompletoMultiple->Execute(); Global::NuevoEstado(Preparado); StatusBarInfo->Panels->Items[1]->Text= "ESTADO AUTO: Preparado"; } else if (Global::GetEstado()==Marcha1CicloEnProceso) cntsolapamientos1ciclo++;}//---------------------------------------------------------------------------

void __fastcall TForm1::ActionCompletoExecute(TObject *Sender){ AnsiString RespuestaRobot,TramaEnviada,ResultadoCompleto; int Nciclos; bool ComOk; int ContadorTramasBasura; long Tini,Tfin,Tcom; // long deliberadamente para casting a ms

/* Contador de ciclos de ActionCompleto */ Global::IncNciclos(); Nciclos=Global::GetNciclos();

/* Conexión automática con Robot */

Ingeniería en Automática y Electrónica Industrial 10-99

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

if((!IdTCPClient1->Connected()) && (CheckBoxComunicate->Checked==TRUE)) IdTCPClient1->Connect();

Tini=1000*(App1->Timer->Read());

if (IdTCPClient1->Connected()) { if(CheckBoxComunicate->Checked==TRUE) ComOk=TRUE; else { ComOk=FALSE; ResultadoCompleto="No seleccionado Comunicate"; } } else { ComOk=FALSE; ResultadoCompleto="No conectado"; }

/* Limpieza del buffer. En caso de haber enviado cadenas PCTrigger al Robot mientras este se encuentra en PAUSE, porque se ha pulsado STOP o bien por alguna alarma, al reiniciarse procesará y responderá a todos los PCTrigger llenando el buffer de recepción del PC de basura que el PC iría recogiendo dessincronizadamente con ReadLn. Por eso se debe vaciar al comienzo de cada secuencia */ if (ComOk){ while (IdTCPClient1->ReadLn("\r",5)!="") ContadorTramasBasura++; }

/* Enviar trigger software al Robot, cadena de texto "PCTrigger" */ if (ComOk) { TramaEnviada="PCTrigger,"+AnsiString(Nciclos)+",0,0,0"; IdTCPClient1->WriteLn(TramaEnviada); StatusBarInfo->Panels->Items[3]->Text="Enviado: "+TramaEnviada; ResultadoCompleto="Enviado PCTrigger"; }

/* Captura de imagen, la cámara está en modo video (default). El tiempo empleado será un error de encoder para el tracking! */ ActionCaptura->Execute();

/* Confirmación de respuesta del robot, cadena "ACKPCTrigger"+Nciclos */ if (ComOk) { RespuestaRobot=IdTCPClient1->ReadLn("\r",TimeoutTCP); StatusBarInfo->Panels->Items[4]->Text="Recibido: "+RespuestaRobot; if (RespuestaRobot!=("ACKPCTrigger"+AnsiString(Nciclos))) { ComOk=FALSE; ResultadoCompleto="Timeout ACKCPTrigger"; } else ResultadoCompleto="Recibido ACKPCTrigger"; }

/* Procesamiento de la imagen */ if (CheckBoxUmbralOtsu->Checked==TRUE) // Metodo Otsu seleccionado ActionHistograma->Execute(); ActionBinariza->Execute();

Ingeniería en Automática y Electrónica Industrial 10-100

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

ActionBusqueda->Execute();

/* Confirmación de que hay datos que merezca la pena enviar */ if (ComOk) { if (Global::GetNpiezas()==0) { ComOk=False; ResultadoCompleto="Npiezas=0, no hay datos listos"; } }

Tcom=1000*(App1->Timer->Read());

/* Envio de datos de posicion */ if (ComOk) { TramaEnviada= "Datos,"+ AnsiString(Nciclos)+","+ AnsiString(Global::GetXCG(0))+","+ AnsiString(Global::GetYCG(0))+","+ "1,0,0"; IdTCPClient1->WriteLn(TramaEnviada); StatusBarInfo->Panels->Items[3]->Text="Enviado: "+TramaEnviada; ResultadoCompleto="Enviados los datos"; }

/* Confirmación de respuesta del robot, cadena "ACKDatos" */ if (ComOk) { RespuestaRobot=IdTCPClient1->ReadLn("\r",TimeoutTCP); StatusBarInfo->Panels->Items[4]->Text="Recibido: "+RespuestaRobot; if (RespuestaRobot!="ACKDatos") { ComOk=FALSE; ResultadoCompleto="Timeout ACKDatos"; } else ResultadoCompleto="Recibido ACKDatos"; }

Tfin=1000*(App1->Timer->Read()); StaticTextTCompleto->Caption="TOT "+AnsiString(Tfin-Tini)+"ms"; StaticTextTCom->Caption="Com "+AnsiString(Tfin-Tcom)+"ms";

MemoComunicaciones->Lines->Append(AnsiString(Global::GetNciclos())+": "+ ResultadoCompleto);

}//---------------------------------------------------------------------------

void __fastcall TForm1::EnviaXYalRobot1Click(TObject *Sender){ /* Envio de datos de posicion */ if ((IdTCPClient1->Connected())) IdTCPClient1->WriteLn( AnsiString(Global::GetXCG(0))+","+ AnsiString(Global::GetYCG(0))+","+ "1"); else ShowMessage ("¡¡¡No hay conexión con el Robot!!!");}

Ingeniería en Automática y Electrónica Industrial 10-101

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

//---------------------------------------------------------------------------

void __fastcall TForm1::DesconectarClick(TObject *Sender){ IdTCPClient1->Disconnect(); }//---------------------------------------------------------------------------

void __fastcall TForm1::ActionErosionExecute(TObject *Sender){ VARIANT vimagenIN,vimagenOUT; SAFEARRAY *psaimagenIN=NULL,*psaimagenOUT=NULL; SAFEARRAYBOUND rgsabound[2]; const unsigned int cDims=2; long rgIndices[2],rgIndicesEntorno[2]; int SizeX,SizeY;

int umbral; unsigned char pixelIN,pixelOUT; long Tini,Tfin; // long deliberadamente para casting a ms

Tini=1000*(App1->Timer->Read());

/* Extracción de imagen desde ImageMil1 */ VariantInit(&vimagenIN); vimagenIN.vt=VT_ARRAY|VT_UI1; // tipo de dato: SAFEARRAY de UINT8 VariantInit(&vimagenOUT); vimagenOUT.vt=VT_ARRAY|VT_UI1; // tipo de dato: SAFEARRAY de UINT8 SizeX=ImageMil1->SizeX; SizeY=ImageMil1->SizeY; rgsabound[0].cElements=SizeX; rgsabound[0].lLbound=0; rgsabound[1].cElements=SizeY; rgsabound[1].lLbound=0;

psaimagenIN=SafeArrayCreate(VT_UI1,cDims,rgsabound); psaimagenOUT=SafeArrayCreate(VT_UI1,cDims,rgsabound);

vimagenIN.parray=psaimagenIN; vimagenOUT.parray=psaimagenOUT;

ImageMil2->Get(&vimagenIN,imSingleBand,imAllBands,0,0,SizeX,SizeY);

/*Ya tenemos la imagen en psaimagenIN, seguimos.. */

/* Asignación dinámica de memoria para matrices mascara y entorno */ int **mascara, **entorno; mascara=new int* [OrdenDeMascara]; for (int nfila=0;nfila<OrdenDeMascara;nfila++) mascara[nfila]=new int [OrdenDeMascara]; /* entorno=new int* [OrdenDeMascara]; for (int nfila=0;nfila<OrdenDeMascara;nfila++) entorno[nfila]=new int [OrdenDeMascara]; */

Ingeniería en Automática y Electrónica Industrial 10-102

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

/* Valores iniciales de matrices mascara y entorno. La matriz mascara será de 1s, para erosion maxima. La matriz entorno será de 0s, para inicio fuera de imagen. */ for (int fil=0;fil<OrdenDeMascara;fil++) { for (int col=0;col<OrdenDeMascara;col++) { mascara[fil][col]=1; //entorno[fil][col]=0; } }

/* Barrido de imagen */ int resultadomascara,ipix,jpix; int radiomascara,limiteerosion;

/* Radio de la matriz mascara: */ radiomascara=OrdenDeMascara/2; //ShowMessage("radiomascara="+AnsiString(radiomascara)); /* Valor límite para decidir la erosión del pixel */ limiteerosion=OrdenDeMascara*OrdenDeMascara*ValorBinarioAlto;

for(int i=0;i<SizeX;i++) { for(int j=0;j<SizeY;j++) { rgIndices[0]=i; rgIndices[1]=j; SafeArrayGetElement(psaimagenIN,rgIndices,&pixelIN); if (pixelIN==ValorBinarioAlto) { /* Barrido de cada entorno de pixel blanco */ resultadomascara=0; for (int fil=0;fil<OrdenDeMascara;fil++) {

/**** bloque desplazada a la izda ****/for (int col=0;col<OrdenDeMascara;col++) { /* Para cada pixel del entorno */ ipix=i+fil-radiomascara; jpix=j+col-radiomascara; if ((ipix>0)&&(ipix<SizeX)&&(jpix>0)&&(jpix<SizeY)) { /* Acceso al pixel, del entorno */ cnt[9]++; rgIndicesEntorno[0]=ipix; rgIndicesEntorno[1]=jpix; SafeArrayGetElement(psaimagenIN,rgIndicesEntorno,&pixelIN); //entorno[fil][col]=pixelIN //resultadomascara+=mascara[fil][col]*pixelIN; resultadomascara+=pixelIN; if (resultadomascara>=limiteerosion ) { pixelOUT=ValorBinarioAlto; SafeArrayPutElement(psaimagenOUT,rgIndices,&pixelOUT); } }}/**** Fin bloque desplazada a la izda ****/

} } }

}

Ingeniería en Automática y Electrónica Industrial 10-103

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

/* Ya tenemos la imagen erosionada en psaimagenOUT */

ImageMil2->Put(vimagenOUT,imSingleBand,imAllBands,0,0,SizeX,SizeY);

/* Liberando memoria, que después pasa lo que pasa */ for (int nfila=0;nfila<OrdenDeMascara;nfila++) delete [] mascara[nfila]; delete [] mascara;

/* for (int nfila=0;nfila<OrdenDeMascara;nfila++) delete [] entorno[nfila]; delete [] entorno; */

VariantClear(&vimagenIN); VariantClear(&vimagenOUT);

Tfin=1000*(App1->Timer->Read()); StaticTextErosion->Caption="Ero "+AnsiString(Tfin-Tini)+"ms";

}//---------------------------------------------------------------------------

void __fastcall TForm1::ButtonErosionClick(TObject *Sender){ ActionErosion->Execute();}//---------------------------------------------------------------------------

void __fastcall TForm1::ActionEtiquetadoExecute(TObject *Sender){ VARIANT vimagen; SAFEARRAY* psaimagen=NULL; SAFEARRAYBOUND rgsabound[2]; const unsigned int cDims=2; long rgIndices[2];

int SizeX,SizeY; unsigned char pixel; long x,y,den;

long Tini,Tfin; // long deliberadamente para casting a ms

/* En los vectores enlaces y clases la componente inicial no se usa */ int enlaces[MaximoEtiquetas+1],clases[MaximoEtiquetas+1]; int EtiquetaMaxima,ClaseMaxima;

Tini=1000*(App1->Timer->Read());

/* Extracción de imagen desde ImageMil2 */ VariantInit(&vimagen); vimagen.vt=VT_ARRAY|VT_UI1; // tipo de dato: SAFEARRAY de UINT8 SizeX=ImageMil1->SizeX; SizeY=ImageMil1->SizeY; rgsabound[0].cElements=SizeX;

Ingeniería en Automática y Electrónica Industrial 10-104

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

rgsabound[0].lLbound=0; rgsabound[1].cElements=SizeY; rgsabound[1].lLbound=0;

psaimagen=SafeArrayCreate(VT_UI1,cDims,rgsabound);

vimagen.parray=psaimagen;

ImageMil2->Get(&vimagen,imSingleBand,imAllBands,0,0,SizeX,SizeY);

/*Ya tenemos la imagen...................... */

cnt[0]=cnt[1]=cnt[2]=cnt[3]=cnt[4]=cnt[5]=0;

/* Asignación dinámica de memoria para matriz etiqueta */ //ShowMessage(AnsiString(SizeX)+","+AnsiString(SizeY)); /*int **etiquetas; etiquetas=new int* [SizeX]; for (int nfila=0;nfila<SizeX;nfila++) etiquetas[nfila]=new int [SizeY]; */

/* Reset inicial de vector enlaces, de dimensión MaximoEtiquetas+1 */for (int i=0;i<=MaximoEtiquetas;i++) enlaces[i]=0;

/* Recorrido de etiquetado, las filas y columnas extremas se etiquetan a 0.Si se acaban las etiquetas disponibles, el resto de imagen se etiqueta a 0.Por eso la componente 0 de los vectores enlaces y clases no se utilizará */int NuevaEtiqueta=1,arriba,izda;for(int i=0;i<SizeX;i++) { for(int j=0;j<SizeY;j++) { rgIndices[0]=i; rgIndices[1]=j; SafeArrayGetElement(psaimagen,rgIndices,&pixel); if ((pixel==ValorBinarioAlto) &&(i>0)&&(i<SizeX-1)&&(j>0)&&(j<SizeY-1) && (NuevaEtiqueta<MaximoEtiquetas)) { arriba=etiquetas[i][j-1]; izda=etiquetas[i-1][j]; /* Los casos siguientes están ordenados de mayor a menor número de ocurrencias, para optimizar algoritmo*/ if (arriba!=0) { if (izda!=0) { if (arriba==izda){ /* 4-conectado arriba e izda */ //cnt[0]++; etiquetas[i][j]=arriba; } else { if (arriba>izda) { /* 4-conectado arriba e izda con diferentes etiquetas */ //cnt[2]++; etiquetas[i][j]=izda; enlaces[arriba]=izda; }

Ingeniería en Automática y Electrónica Industrial 10-105

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

else { if (arriba<izda) { /* 4-conectado arriba e izda con diferentes etiquetas */ //cnt[1]++; etiquetas[i][j]=arriba; enlaces[izda]=arriba; } } } } else { /* conectado arriba */ //cnt[3]++; etiquetas[i][j]=arriba; } } else { // arriba==0 if (izda!=0){ /* conectado izda */ //cnt[4]++; etiquetas[i][j]=izda; } else { /* No conectado ni arriba ni izda, nueva etiqueta */ //cnt[5]++; etiquetas[i][j]=NuevaEtiqueta; enlaces[NuevaEtiqueta]=-1; //marca NuevaEtiqueta++; } } } else etiquetas[i][j]=0; }}EtiquetaMaxima=NuevaEtiqueta-1;EtiquetaMaximatest=EtiquetaMaxima;

/* Agrupación de etiquetas en clases, según las conexiones recogidad enenlaces[]. Si se agotan las clases disponibles, se mantiene la última clase */

int NuevaClase=1;int padre,abuelo;for (int c=0;c<=EtiquetaMaxima;c++) { enlacestest[c]=enlaces[c]; padre=enlaces[c];

/* Si padre=0 esa etiqueta no se usa. Si padre=-1 esa etiqueta es la primera del objeto, no hay abuelo */ if (padre>0) abuelo=enlaces[padre]; else abuelo=0;

/* Si hay abuelo el enlace lo hereda, si no queda como está. El proceso es contiuo y no se requiere recursividad, puesto que enlaces se va compactando y el parentesco mayor posible es abuelo*/ if (abuelo>0) enlaces[c]=abuelo;

Ingeniería en Automática y Electrónica Industrial 10-106

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

else enlaces[c]=padre;

/* Renumeración de etiquetas en clases, enlace[]= -1 inicia secuencia */ if (enlaces[c]==-1) { clases[c]=NuevaClase; if (NuevaClase<MaximoClases) NuevaClase++; } else clases[c]=clases[enlaces[c]];

clasestest[c]=clases[c];}

/* la última clase se desprecia incluso en caso de ser igual a MaximoClases,puesto que entonces esa clase agruparía todo el exceso de imagen */ClaseMaxima=NuevaClase-1;ClaseMaximatest=ClaseMaxima;

/************** Análisis de objetos *************************************/

/* Declaración e inicialización de variables que intervienen.Estos vectores se utilizan desde la componente 0, no desde 1 como ocurrecon enlaces[] y clases[] */long xvector[MaximoClases],yvector[MaximoClases];int Npixvector[MaximoClases],NpixPeriferia[MaximoClases];int XCG[MaximoClases],YCG[MaximoClases];AnsiString TipoPieza[MaximoClases];int Npiezas;for (int c=0;c<MaximoClases;c++) { xvector[c]=0; yvector[c]=0; Npixvector[c]=0; NpixPeriferia[c]=0;}

/* Barrido de la imagen etiquetas[][] */int ClasePixel;for(int i=0;i<SizeX;i++) { for(int j=0;j<SizeY;j++) { if (etiquetas[i][j]>0) { ClasePixel=clases[etiquetas[i][j]]; xvector[ClasePixel-1]+=i; yvector[ClasePixel-1]+=j; Npixvector[ClasePixel-1]+=1; if ((i<AnchoPeriferia)||(i>SizeX-AnchoPeriferia)|| (j<AnchoPeriferia)||(j>SizeY-AnchoPeriferia) ) NpixPeriferia[ClasePixel-1]+=1; } }}

/* Obtención de coordenadas de posición y selección de piezas válidas */int Npix;bool PiezaValida;Npiezas=0;for (int c=0;c<ClaseMaxima;c++) { if (Npixvector[c]>0) { // Condición de seguridad redundante xvector[c]=xvector[c]/Npixvector[c]; yvector[c]=yvector[c]/Npixvector[c];

Ingeniería en Automática y Electrónica Industrial 10-107

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

Npix=Npixvector[c];

if (NpixPeriferia[c]>MaxPixPeriferia) { PiezaValida=FALSE; TipoPieza[c]="PERIFERICO"; } else { if ((Npix>MinPequeno)&&(Npix<MaxPequeno)) { PiezaValida=TRUE; TipoPieza[c]="CIRC.PEQUEÑO"; } else { if ((Npix>MinGrande)&&(Npix<MaxGrande)) { PiezaValida=TRUE; TipoPieza[c]="CIRC.GRANDE"; } else { PiezaValida=FALSE; TipoPieza[c]="COSAS RARAS"; } } }

if (PiezaValida) { /* Centro de gravedad, convertido de pixel a mm */ XCG[Npiezas]=(int)(PixToMm*xvector[c]); YCG[Npiezas]=(int)(PixToMm*yvector[c]); Npiezas++; } }}

/* COLOREA IMAGEN ETIQUETADA. El display se traga valores por encima de 255.*/if (CheckBoxColorea->Checked==TRUE) { for(int i=0;i<SizeX;i++) { for(int j=0;j<SizeY;j++) { if (etiquetas[i][j]>0) pixel=clases[etiquetas[i][j]]*50; else pixel=0; rgIndices[0]=i; rgIndices[1]=j; SafeArrayPutElement(psaimagen,rgIndices,&pixel); } } ImageMil2->Put(vimagen,imSingleBand,imAllBands,0,0,SizeX,SizeY);}

/* Ya no se va a requerir la memoria de la imagen */ VariantClear(&vimagen);

/* Liberando memoria, que después pasa lo que pasa */ /*for (int nfila=0;nfila<SizeX;nfila++) delete [] etiquetas[nfila]; delete [] etiquetas; */

Ingeniería en Automática y Electrónica Industrial 10-108

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

/* Información en pantalla *///MemoEtiquetado->Lines->Clear();MemoEtiquetado->Lines->Append("-----------------------");MemoEtiquetado->Lines->Append("Cosas encontradas: "+AnsiString(ClaseMaxima));for (int c=0;c<ClaseMaxima;c++) { if (Npixvector[c]>0) { // Condición de seguridad redundante GraphicContext1->DrawingRegion->CenterX=xvector[c]; GraphicContext1->DrawingRegion->CenterY=yvector[c]; GraphicContext1->Cross(5); MemoEtiquetado->Lines->Append("Cosa "+AnsiString(c+1)+": "+ AnsiString((int)(PixToMm*xvector[c]))+", "+ AnsiString((int)(PixToMm*yvector[c]))+", "+ AnsiString(Npixvector[c])+","+ TipoPieza[c]); }}

/* Escritura de variables globales de resultado */

Global::SetNpiezas(Npiezas);MemoEtiquetado->Lines->Append("Piezas validas: "+AnsiString(Npiezas));for (int c=0;c<Npiezas;c++) { Global::SetXCG(c,XCG[c]); Global::SetYCG(c,YCG[c]); MemoEtiquetado->Lines->Append("Pieza "+AnsiString(c+1)+": "+ AnsiString(XCG[c])+", "+ AnsiString(YCG[c]));}

Tfin=1000*(App1->Timer->Read()); StaticTextEtiquetado->Caption="Mul "+AnsiString(Tfin-Tini)+"ms";

}//---------------------------------------------------------------------------

void __fastcall TForm1::ButtonEtiquetaClick(TObject *Sender){ActionEtiquetado->Execute();}//---------------------------------------------------------------------------

void __fastcall TForm1::ActionCompletoMultipleExecute(TObject *Sender){ AnsiString RespuestaRobot,TramaEnviada,ResultadoCompleto; int Nciclos; bool ComOk; int ContadorTramasBasura; long Tini,Tfin,Tcom; // long deliberadamente para casting a ms

Tini=1000*(App1->Timer->Read());

/* Contador de ciclos de ActionCompleto */ Global::IncNciclos(); Nciclos=Global::GetNciclos();

Ingeniería en Automática y Electrónica Industrial 10-109

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

/* Conexión automática con Robot */ if (CheckBoxComunicate->Checked==TRUE) { if (!IdTCPClient1->Connected()) IdTCPClient1->Connect(); if (IdTCPClient1->Connected()) ComOk=TRUE; else { ComOk=FALSE; ResultadoCompleto="Falla la conexión"; } } else { ComOk=FALSE; ResultadoCompleto="No seleccionado Comunicate"; }

/* Limpieza del buffer. En caso de haber enviado cadenas PCTrigger al Robot mientras este se encuentra en PAUSE, porque se ha pulsado STOP o bien por alguna alarma, al reiniciarse procesará y responderá a todos los PCTrigger llenando el buffer de recepción del PC de basura que el PC iría recogiendo dessincronizadamente con ReadLn. Por eso se debe vaciar al comienzo de cada secuencia */ if (ComOk){ while (IdTCPClient1->ReadLn("\r",20)!="") ContadorTramasBasura++; }

/* Enviar trigger software al Robot, cadena de texto "PCTrigger" */ if (ComOk) { TramaEnviada="PCTrigger,"+AnsiString(Nciclos)+",0,0,0,0,0"; IdTCPClient1->WriteLn(TramaEnviada); StatusBarInfo->Panels->Items[3]->Text="Enviado: "+TramaEnviada; ResultadoCompleto="Enviado PCTrigger"; }

/* Captura de imagen, la cámara está en modo video (default). El tiempo empleado será un error de encoder para el tracking! */ if (CheckBoxCaptura->Checked==TRUE) ActionCaptura->Execute();

/* Confirmación de respuesta del robot, cadena "ACKPCTrigger"+Nciclos */ if (ComOk) { RespuestaRobot=IdTCPClient1->ReadLn("\r",TimeoutTCP); StatusBarInfo->Panels->Items[4]->Text="Recibido: "+RespuestaRobot; if (RespuestaRobot!=("ACKPCTrigger"+AnsiString(Nciclos))) { ComOk=FALSE; ResultadoCompleto="Timeout ACKCPTrigger"; } else ResultadoCompleto="Recibido ACKPCTrigger"; }

/* Procesamiento de la imagen */ if (CheckBoxUmbralOtsu->Checked==FALSE) { StaticTextTHist->Caption="His 000ms"; StaticTextTOtsu->Caption="Ots 000ms";

Ingeniería en Automática y Electrónica Industrial 10-110

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

} else ActionHistograma->Execute();

ActionBinariza->Execute();

if (CheckBoxErosion->Checked==FALSE) { StaticTextErosion->Caption="Ero 000ms"; } else ActionErosion->Execute();

ActionEtiquetado->Execute();

/* Confirmación de que hay datos que merezca la pena enviar */ int Npiezas; if (ComOk) { Npiezas=Global::GetNpiezas(); if (Npiezas==0) { ComOk=False; ResultadoCompleto="Npiezas=0, no hay datos listos"; } }

Tcom=1000*(App1->Timer->Read());

/* Envio de datos de posicion si procede */ int cntpiezas=0; while ((ComOk)&& (cntpiezas<Npiezas)) { TramaEnviada= "Datos,"+ AnsiString(Nciclos)+","+ AnsiString(Global::GetXCG(cntpiezas))+","+ AnsiString(Global::GetYCG(cntpiezas))+","+ "1,"+ // Orientación, sin uso AnsiString(cntpiezas+1)+","+ AnsiString(Npiezas) ; cntpiezas++; IdTCPClient1->WriteLn(TramaEnviada); StatusBarInfo->Panels->Items[3]->Text="Enviado: "+TramaEnviada; ResultadoCompleto="Enviado hasta Pieza "+AnsiString(cntpiezas); }

/* Confirmación de respuesta del robot, cadena "ACKDatos" */ if (ComOk) { RespuestaRobot=IdTCPClient1->ReadLn("\r",TimeoutTCP); StatusBarInfo->Panels->Items[4]->Text="Recibido: "+RespuestaRobot; if (RespuestaRobot!="ACKDatos") { ComOk=FALSE; ResultadoCompleto="Timeout ACKDatos"; } else ResultadoCompleto="Recibido ACKDatos"; }

Tfin=1000*(App1->Timer->Read());

Ingeniería en Automática y Electrónica Industrial 10-111

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

StaticTextTCompleto->Caption="TOT "+AnsiString(Tfin-Tini)+"ms"; StaticTextTCom->Caption="Com "+AnsiString(Tfin-Tcom)+"ms";

MemoComunicaciones->Lines->Append(AnsiString(Global::GetNciclos())+": "+ ResultadoCompleto); }//---------------------------------------------------------------------------

void __fastcall TForm1::ImagencirculoClick(TObject *Sender){ VARIANT vimagen; SAFEARRAY *psaimagen=NULL; SAFEARRAYBOUND rgsabound[2]; const unsigned int cDims=2; long rgIndices[2]; int SizeX,SizeY;

int ValorBajo,ValorAlto; unsigned char pixelOUT;

ValorBajo=0; ValorAlto=255;

VariantInit(&vimagen); vimagen.vt=VT_ARRAY|VT_UI1; // tipo de dato: SAFEARRAY de UINT8 SizeX=ImageMil2->SizeX; SizeY=ImageMil2->SizeY; rgsabound[0].cElements=SizeX; rgsabound[0].lLbound=0; rgsabound[1].cElements=SizeY; rgsabound[1].lLbound=0;

psaimagen=SafeArrayCreate(VT_UI1,cDims,rgsabound);

vimagen.parray=psaimagen;

for(int i=0;i<SizeX;i++) { for(int j=0;j<SizeY;j++) { rgIndices[0]=i; rgIndices[1]=j; pixelOUT=ValorBajo; if ( ((i-200)*(i-200)+(j-200)*(j-200))<=10000 ) pixelOUT=ValorAlto; if ( ((i-400)*(i-400)+(j-200)*(j-200))<=10000 ) pixelOUT=ValorAlto; SafeArrayPutElement(psaimagen,rgIndices,&pixelOUT); }

} ImageMil1->Put(vimagen,imSingleBand,imAllBands,0,0,SizeX,SizeY); VariantClear(&vimagen);

}//---------------------------------------------------------------------------

void __fastcall TForm1::Cargarsobreimagendcha1Click(TObject *Sender)

Ingeniería en Automática y Electrónica Industrial 10-112

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

{ImageMil2->Load(NULL,0);}//---------------------------------------------------------------------------

void __fastcall TForm1::Salvarimagendcha1Click(TObject *Sender){ImageMil2->Save(NULL);}//---------------------------------------------------------------------------

void __fastcall TForm1::Imagendepruebavarioscirculos1Click(TObject *Sender){ VARIANT vimagen; SAFEARRAY *psaimagen=NULL; SAFEARRAYBOUND rgsabound[2]; const unsigned int cDims=2; long rgIndices[2]; int SizeX,SizeY;

int ValorBajo,ValorAlto; unsigned char pixelOUT;

ValorBajo=0; ValorAlto=255;

VariantInit(&vimagen); vimagen.vt=VT_ARRAY|VT_UI1; // tipo de dato: SAFEARRAY de UINT8 SizeX=ImageMil2->SizeX; SizeY=ImageMil2->SizeY; rgsabound[0].cElements=SizeX; rgsabound[0].lLbound=0; rgsabound[1].cElements=SizeY; rgsabound[1].lLbound=0;

psaimagen=SafeArrayCreate(VT_UI1,cDims,rgsabound);

vimagen.parray=psaimagen;

for(int i=0;i<SizeX;i++) { for(int j=0;j<SizeY;j++) { rgIndices[0]=i; rgIndices[1]=j; pixelOUT=ValorBajo; if ( ((i-200)*(i-200)+(j-200)*(j-200))<=4000 ) pixelOUT=ValorAlto; if ( ((i-400)*(i-400)+(j-350)*(j-350))<=8000 ) pixelOUT=ValorAlto; if ( ((i-500)*(i-500)+(j-350)*(j-350))<=8000 ) pixelOUT=ValorAlto; if ( ((i-100)*(i-100)+(j-450)*(j-450))<=2000 ) pixelOUT=ValorAlto; if ( ((i-600)*(i-600)+(j-100)*(j-100))<=3000 ) pixelOUT=ValorAlto; SafeArrayPutElement(psaimagen,rgIndices,&pixelOUT); }

Ingeniería en Automática y Electrónica Industrial 10-113

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

} ImageMil1->Put(vimagen,imSingleBand,imAllBands,0,0,SizeX,SizeY); VariantClear(&vimagen);

}//---------------------------------------------------------------------------

void __fastcall TForm1::ButtonTestClick(TObject *Sender){ActionCompletoMultiple->Execute();}//---------------------------------------------------------------------------

void __fastcall TForm1::ActionPrefiltradoMedianaExecute(TObject *Sender){ VARIANT vimagenIN,vimagenOUT; SAFEARRAY *psaimagenIN=NULL,*psaimagenOUT=NULL; SAFEARRAYBOUND rgsabound[2]; const unsigned int cDims=2; long rgIndices[2],rgIndicesEntorno[2]; int SizeX,SizeY;

unsigned char pixelIN,pixelOUT; long Tini,Tfin; // long deliberadamente para casting a ms

Tini=1000*(App1->Timer->Read());

/* Extracción de imagen desde ImageMil1 */ VariantInit(&vimagenIN); vimagenIN.vt=VT_ARRAY|VT_UI1; // tipo de dato: SAFEARRAY de UINT8 VariantInit(&vimagenOUT); vimagenOUT.vt=VT_ARRAY|VT_UI1; // tipo de dato: SAFEARRAY de UINT8 SizeX=ImageMil1->SizeX; SizeY=ImageMil1->SizeY; rgsabound[0].cElements=SizeX; rgsabound[0].lLbound=0; rgsabound[1].cElements=SizeY; rgsabound[1].lLbound=0;

psaimagenIN=SafeArrayCreate(VT_UI1,cDims,rgsabound); psaimagenOUT=SafeArrayCreate(VT_UI1,cDims,rgsabound);

vimagenIN.parray=psaimagenIN; vimagenOUT.parray=psaimagenOUT;

ImageMil1->Get(&vimagenIN,imSingleBand,imAllBands,0,0,SizeX,SizeY);

/*Ya tenemos la imagen en psaimagenIN, seguimos.. */

/* Asignación dinámica de memoria para matrices mascara y entorno */ int *vectorentorno,cntentorno; vectorentorno=new int[OrdenDeMascaraMediana*OrdenDeMascaraMediana];

/* Barrido de imagen */ int ipix,jpix; int pixtemp; bool FinOrdenado; int radiomascara;

Ingeniería en Automática y Electrónica Industrial 10-114

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

/* Radio de la matriz mascara */ radiomascara=OrdenDeMascaraMediana/2; //ShowMessage("radiomascara="+AnsiString(radiomascara));

for(int i=0;i<SizeX;i++) { for(int j=0;j<SizeY;j++) { rgIndices[0]=i; rgIndices[1]=j; SafeArrayGetElement(psaimagenIN,rgIndices,&pixelIN); /* Barrido de cada entorno de pixel blanco */ cntentorno=0; for (int fil=0;fil<OrdenDeMascaraMediana;fil++) { for (int col=0;col<OrdenDeMascaraMediana;col++) { /* Para cada pixel del entorno */ ipix=i+fil-radiomascara; jpix=j+col-radiomascara; if ((ipix>0)&&(ipix<SizeX)&&(jpix>0)&&(jpix<SizeY)) { /* Acceso al pixel, del entorno */ cnt[9]++; rgIndicesEntorno[0]=ipix; rgIndicesEntorno[1]=jpix; SafeArrayGetElement(psaimagenIN,rgIndicesEntorno,&pixelIN); vectorentorno[cntentorno]=pixelIN; cntentorno++; } } } /* Ordenado de entorno para tomar mediana */ FinOrdenado=0; while (!FinOrdenado) { FinOrdenado=1; for (int e=0;e<cntentorno-1;e++) { if (vectorentorno[e]>vectorentorno[e+1]) { pixtemp=vectorentorno[e]; vectorentorno[e]=vectorentorno[e+1]; vectorentorno[e+1]=pixtemp; FinOrdenado=0; } } } /* Ahora se toma la mediana */ pixelOUT=vectorentorno[cntentorno/2+1]; SafeArrayPutElement(psaimagenOUT,rgIndices,&pixelOUT); } }

/* Ya tenemos la imagen erosionada en psaimagenOUT */

ImageMil1->Put(vimagenOUT,imSingleBand,imAllBands,0,0,SizeX,SizeY);

Ingeniería en Automática y Electrónica Industrial 10-115

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

delete [] vectorentorno;

VariantClear(&vimagenIN); VariantClear(&vimagenOUT);

Tfin=1000*(App1->Timer->Read()); StaticTextMediana->Caption="Fil "+AnsiString(Tfin-Tini)+"ms";

}//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender){ ActionPrefiltradoMediana->Execute(); }//---------------------------------------------------------------------------

10.3 Código fuente Unit1_VisionV7.h//---------------------------------------------------------------------------

#ifndef Unit1_VisionV7H#define Unit1_VisionV7H//---------------------------------------------------------------------------#include <Classes.hpp>#include <Controls.hpp>#include <StdCtrls.hpp>#include <Forms.hpp>#include "MIL_OCX.h"#include <OleCtrls.hpp>#include <ExtCtrls.hpp>#include <Chart.hpp>#include <Series.hpp>#include <TeEngine.hpp>#include <TeeProcs.hpp>#include <IdBaseComponent.hpp>#include <IdComponent.hpp>#include <IdTCPClient.hpp>#include <IdTCPConnection.hpp>#include <IdAntiFreeze.hpp>#include <IdAntiFreezeBase.hpp>#include <Grids.hpp>#include <ValEdit.hpp>#include <Menus.hpp>#include <ActnList.hpp>#include <Buttons.hpp>#include <ComCtrls.hpp>//---------------------------------------------------------------------------class TForm1 : public TForm{__published: // IDE-managed Components TApp *App1; TSYSTEM *SYSTEM1; TDigitizer *Digitizer1; TImageMil *ImageMil1;

Ingeniería en Automática y Electrónica Industrial 10-116

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

TDisplay *Display1; TButton *ButtonGrab; TButton *ButtonGrabCont; TGraphicContext *GraphicContext1; TDisplay *Display2; TImageMil *ImageMil2; TButton *ButtonBinariza; TScrollBar *ScrollBarUmbral; TButton *ButtonExit; TChart *ChartHistograma; TBarSeries *Series1; TStaticText *StaticTextUmbral; TButton *ButtonHistograma; TButton *ButtonCG; TIdTCPClient *IdTCPClient1; TIdAntiFreeze *IdAntiFreeze1; TTimer *TimerInfo; TMainMenu *MainMenu1; TMenuItem *ArchivoImagen; TMenuItem *Cargar; TMenuItem *Salvar; TStaticText *StaticTextTGrab; TStaticText *StaticTextTHist; TStaticText *StaticTextTOtsu; TStaticText *StaticTextTCG; TStaticText *StaticTextTBin; TMenuItem *HerramientasVision; TMenuItem *Histogramapasoapaso; TMenuItem *Otsupasoapaso; TLineSeries *Series2; TMenuItem *Imagenizdadcha; TMenuItem *Invierteimagendcha; TMenuItem *Imagenpruebasimple; TStaticText *StaticTextMedia; TStaticText *StaticTextVarMax; TMenuItem *HerramientasRobot; TMenuItem *EnviaceroaRobot; TMenuItem *Conectar; TButton *ButtonStart; TButton *ButtonStop; TTimer *TimerRun; TActionList *ActionList1; TAction *ActionCaptura; TAction *ActionHistograma; TAction *ActionBinariza; TAction *ActionBusqueda; TAction *ActionCompleto; TSpeedButton *SpeedButtonManual; TSpeedButton *SpeedButtonAuto; TButton *ButtonStart1Ciclo; TStaticText *StaticTextTCompleto; TMenuItem *EnviaXYalRobot1; TStaticText *StaticTextTCom; TLineSeries *Series3; TCheckBox *CheckBoxComunicate; TCheckBox *CheckBoxGrafica; TMenuItem *Desconectar; TButton *ButtonErosion;

Ingeniería en Automática y Electrónica Industrial 10-117

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

TStaticText *StaticTextErosion; TAction *ActionErosion; TAction *ActionEtiquetado; TStaticText *StaticTextEtiquetado; TButton *ButtonEtiqueta; TMemo *MemoEtiquetado; TAction *ActionCompletoMultiple; TCheckBox *CheckBoxColorea; TMenuItem *Imagencirculo; TMenuItem *Cargarsobreimagendcha1; TMenuItem *Salvarimagendcha1; TMenuItem *Imagendepruebavarioscirculos1; TCheckBox *CheckBoxCaptura; TBevel *Bevel2; TBevel *Bevel4; TCheckBox *CheckBoxUmbralOtsu; TCheckBox *CheckBoxErosion; TStatusBar *StatusBarInfo; TMemo *MemoComunicaciones; TAction *ActionPrefiltradoMediana; TCheckBox *CheckBoxMediana; TButton *Button1; TStaticText *StaticTextMediana; void __fastcall ButtonGrabClick(TObject *Sender); void __fastcall ButtonGrabContClick(TObject *Sender); void __fastcall ButtonHaltClick(TObject *Sender); void __fastcall ButtonCopiaClick(TObject *Sender); void __fastcall ButtonInvertClick(TObject *Sender); void __fastcall ScrollBarUmbralChange(TObject *Sender); void __fastcall FormCreate(TObject *Sender); void __fastcall ButtonBinarizaClick(TObject *Sender); void __fastcall ButtonExitClick(TObject *Sender); void __fastcall ImageMil1ContentModified(TObject *Sender, long OffsetX, long OffsetY, long SizeX, long SizeY); void __fastcall ButtonHistogramaClick(TObject *Sender); void __fastcall ButtonCGClick(TObject *Sender); void __fastcall IdTCPClient1Connected(TObject *Sender); void __fastcall IdTCPClient1Disconnected(TObject *Sender); void __fastcall ButtonConnectClick(TObject *Sender); void __fastcall ButtonDisconnectClick(TObject *Sender); void __fastcall ButtonWriteClick(TObject *Sender); void __fastcall ButtonReadClick(TObject *Sender); void __fastcall TimerInfoTimer(TObject *Sender); void __fastcall LabeledEditOnChange(TObject *Sender); void __fastcall Digitizer1CameraPresent(TObject *Sender); void __fastcall ButtonEtiquetadoClick(TObject *Sender); void __fastcall CargarClick(TObject *Sender); void __fastcall SalvarClick(TObject *Sender); void __fastcall HistogramapasoapasoClick(TObject *Sender); void __fastcall OtsupasoapasoClick(TObject *Sender); void __fastcall ImagenizdadchaClick(TObject *Sender); void __fastcall InvierteimagendchaClick(TObject *Sender); void __fastcall ImagenpruebasimpleClick(TObject *Sender); void __fastcall EnviaceroaRobotClick(TObject *Sender); void __fastcall ConectarClick(TObject *Sender); void __fastcall ButtonStartClick(TObject *Sender); void __fastcall ButtonStopClick(TObject *Sender); void __fastcall ActionHistogramaExecute(TObject *Sender);

Ingeniería en Automática y Electrónica Industrial 10-118

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place10 Listado de programas de C++ Builder

void __fastcall ActionCapturaExecute(TObject *Sender); void __fastcall ActionBusquedaExecute(TObject *Sender); void __fastcall ActionBinarizaExecute(TObject *Sender); void __fastcall TimerRunTimer(TObject *Sender); void __fastcall SpeedButtonManualClick(TObject *Sender); void __fastcall SpeedButtonAutoClick(TObject *Sender); void __fastcall ButtonStart1CicloClick(TObject *Sender); void __fastcall ActionCompletoExecute(TObject *Sender); void __fastcall EnviaXYalRobot1Click(TObject *Sender); void __fastcall DesconectarClick(TObject *Sender); void __fastcall ActionErosionExecute(TObject *Sender); void __fastcall ButtonErosionClick(TObject *Sender); void __fastcall ActionEtiquetadoExecute(TObject *Sender); void __fastcall ButtonEtiquetaClick(TObject *Sender); void __fastcall ActionCompletoMultipleExecute(TObject *Sender); void __fastcall ImagencirculoClick(TObject *Sender); void __fastcall Cargarsobreimagendcha1Click(TObject *Sender); void __fastcall Salvarimagendcha1Click(TObject *Sender); void __fastcall Imagendepruebavarioscirculos1Click( TObject *Sender); void __fastcall ButtonTestClick(TObject *Sender); void __fastcall ActionPrefiltradoMedianaExecute(TObject *Sender); void __fastcall Button1Click(TObject *Sender);

private: // User declarationspublic: // User declarations __fastcall TForm1(TComponent* Owner);};

//---------------------------------------------------------------------------extern PACKAGE TForm1 *Form1;//---------------------------------------------------------------------------

#endif

Ingeniería en Automática y Electrónica Industrial 10-119

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place11 Listado de programas del robot

11 Listado de programas del robot

11.1 Programa MAIN.prg10 OVRD 10020 ACCEL 50,5025 CNT 130 'LOADSET 1,140 'OADL ON50 '55 TRCLR56 '60 IF M_PSA(2)=0 THEN GOTO *SLOT2RUN70 XLOAD 2,"COM" ' Carga programa COM es SLOT 280 WAIT C_PRG(2)="COM" ' Espera que el programa COM este cargado en SLOT 290 XRUN 2 ' Arranca programa en SLOT 2100 *SLOT2RUN110 'IF M_PSA(3)=0 THEN GOTO *SLOT3RUN120 ' XLOAD 3,"ROB2"130 ' WAIT C_PRG(3)="ROB2"140 'XRUN 3150 '*SLOT3RUN160 WHILE(1)170 DATABUF=M_TRBFCT ' Para monitorizacion rapida en Variables de Program Monitor180 WAIT M_TRBFCT>0190 GOSUB *TRACKING200 WEND210 *TRACKING220 TRRD PV,MV# ' Extrae de Buffer posicion respecto de P_PRGV y encoder en el momento de la foto230 ESPERA=1240 WHILE ESPERA=1250 PORGVYA=TRWCUR(1,P_ORGV,MV#) ' Origen de sistema de referencia actualizado segun encoder255 PACTUAL=PORGVYA*PV ' Posicion de pieza actualizada segun encoder260 IF (POSCQ(PACTUAL))=1 THEN ESPERA=0 ' La pieza entra en zona de trabajo270 WEND280 'DLY 1300 TRK ON,P_ORGV,MV# ' Inicia TRACKING con origen de referencia P_ORGV310 MOV PV,+100 ' Mueve hacia PACTUAL*P_ZERO/P_ZERO*PV=PACTUAL*PV315 CNT 0320 MOV PV,-10325 M_OUT(4)=1330 MOV PV,+100 ' Sube un poco340 TEMP#=P_ENCDLT.X ' para comprobar resolucion de decimales345 CNT 1360 TRK OFF370 MOV PSUELTA371 MOV PSUELTA,-15375 M_OUT(4)=0390 RETURNPV=(+50.338,-69.844,+0.000,+0.000,+0.000,+0.000)(0,0)PORGVYA=(+445.920,+186.979,+154.392,+0.000,+0.000,+0.000,+0.000,+0.000)(4,0)P_ORGV=(+571.037,+468.513,+157.575,+0.000,+0.000,+0.000,+0.000,+0.000)(4,0)

Ingeniería en Automática y Electrónica Industrial 11-120

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place11 Listado de programas del robot

PACTUAL=(+496.258,+117.135,+154.392,+0.000,+0.000,+0.000,+0.000,+0.000)(4,0)PSUELTA=(+395.579,+262.056,+214.300,+0.000,+0.000,+33.629,+0.000,+0.000)(4,0)PESPERA=(+329.030,+411.254,+229.303,+0.000,+0.000,+34.507,+0.000,+0.000)(4,0)

11.2 Programa COM.prg10 '############################################################################20 ' COMUNICACION CON EL SISTEMA DE VISION ARTIFICAL30 ' ROTACION DE COORDENADAS DEL SISTEMA DE VISION RESPECTO DEL ROBOT40 ' ORDENADO Y ALMACENAMIENTO EN BUFFER PARA TRACKING50 '############################################################################55 DIM PARRAY(20) ' Array para ordenar las posiciones recibidas, no se esperan mas de 10 o 1256 DIM MAVANCE(20) 'Array de valores de avance, criterio utilizados para ordenar las piezas60 '70 ' Al inicio el Robot debe tener el Buffer vacío, ya que al terminar un programa se cierran los puertos abiertos en el mismo80 M_E_CORR=30090 '100 OPEN "COM3:" AS #1 ' COMDEV[2]=OPT13 (COM3=OPT13); NETPORT[3]=10003 (Puerto asignado); CPRCE13=2 (modo DataLink)110 '120 *WAITCOM130 INPUT #1,CORDEN$,CNCICLOS$,VX,VY,VTHETA,NPIEZA,NPZAS ' Espera comando del PC140 IF CORDEN$="PCTrigger" THEN GOSUB *TRIGGER ' Procesamiento de PCTrigger150 IF CORDEN$="Datos" THEN GOSUB *DATOS ' Procesamiento de datos recibidos160 IF CORDEN$="Cero" THEN GOSUB *CERO ' Procesamiento cero, se almacena en buffer M_ENC y posición=(0,0), para test170 GOTO *WAITCOM180 '190 '200 *TRIGGER210 NTRIG=NTRIG+1 ' Contador para depuracion220 MCAP#=M_ENC-M_E_CORR ' Captura encoder, con corrección por software si procede230 CRESP$="ACKPCTrigger"+CNCICLOS$ ' Respuesta compuesta con el nº de ciclo para que PC confirme sincronismo comunicaciones240 PRINT #1,CRESP$ ' Confirma al PC la recepción y procesamiento de "PCTrigger"250 RETURN260 '270 '280 *DATOS290 NDAT=NDAT+1 ' Contador para depuracion300 PROBOT=P_ZERO310 PROBOT.X=COS(M_RVBETA)*VX+SIN(M_RVBETA)*VY ' ROTACION del sistema de vision respecto del robot320 PROBOT.Y=SIN(M_RVBETA)*VX-COS(M_RVBETA)*VY ' ROTACION del sistema de vision respecto del robot325 PARRAY(NPIEZA)=PROBOT ' Guarda posiciones en array. NPIEZA viene numerado desde 1, justamente como trabaja el robot340 IF NPIEZA=NPZAS THEN ' El robot confirma recepcion del paquete cuando recibe la ultima pieza350 PRINT #1,"ACKDatos" ' Confirma al PC la recepcion correcta de datos355 GOSUB *ORDENA360 ENDIF370 RETURN

Ingeniería en Automática y Electrónica Industrial 11-121

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place11 Listado de programas del robot

380 '390 '400 *CERO410 NCER=NCER+1 ' Contador para depuracion420 PROBOT=P_ZERO430 PROBOT.X=0440 PROBOT.Y=0450 TRWRT PROBOT,M_ENC460 RETURN470 '500 *ORDENA510 IF NPZAS=1 THEN520 TRWRT PROBOT,MCAP# ' La posicion (x,y) y el valor de encoder asociado a la captura se guardan en buffer530 ENDIF550 IF NPZAS>1 AND NPZAS<30 THEN ' Segunda condicion es de seguridad552 FOR N=1 TO NPZAS ' calcula las variables de medida utilizadas para ordenar554 MAVANCE(N)=P_ENCDLT.X*PARRAY(N).X+P_ENCDLT.Y*PARRAY(N).Y556 NEXT560 FOR VUELTAS=1 TO NPZAS ' Vueltas para segurar que todas las posiciones se mueven como deben, creo que sobra una570 FOR M=1 TO NPZAS-1 ' Recorrido del array hasta el penúltimo580 N=M+1590 IF MAVANCE(M)<MAVANCE(N) THEN ' A permutaaaaaaaaaaaaaaaaarrrrrrrr600 PTEMP=PARRAY(M)605 MTEMP=MAVANCE(M)610 PARRAY(M)=PARRAY(N)620 MAVANCE(M)=MAVANCE(N)630 PARRAY(N)=PTEMP640 MAVANCE(N)=MTEMP650 ENDIF660 NEXT670 NEXT672 FOR N=1 TO NPZAS ' Solo queda enviar el array ordenado al buffer de tracking673 PAUX=PARRAY(N)674 TRWRT PAUX,MCAP# ' La posicion (x,y) y el valor de encoder asociado a la captura se guardan en buffer676 NEXT680 ENDIF690 RETURNPARRAY(1)=(+21.128,-134.564,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000)(0,0)PARRAY(2)=(+50.338,-69.844,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000)(0,0)PARRAY(3)=(+124.382,-72.575,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000)(0,0)PARRAY(4)=(+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000)(0,0)PARRAY(5)=(+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000)(0,0)PARRAY(6)=(+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000)(0,0)PARRAY(7)=(+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000)(0,0)PARRAY(8)=(+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000)(0,0)PARRAY(9)=(+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000)(0,0)PARRAY(10)=(+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000)(0,0)PARRAY(11)=(+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000)(0,0)PARRAY(12)=(+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000)(0,0)PARRAY(13)=(+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000)(0,0)PARRAY(14)=(+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000)(0,0)PARRAY(15)=(+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000)(0,0)

Ingeniería en Automática y Electrónica Industrial 11-122

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place11 Listado de programas del robot

PARRAY(16)=(+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000)(0,0)PARRAY(17)=(+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000)(0,0)PARRAY(18)=(+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000)(0,0)PARRAY(19)=(+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000)(0,0)PARRAY(20)=(+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000)(0,0)PROBOT=(+21.128,-134.564,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000)(0,0)PTEMP=(+50.338,-69.844,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000)(0,0)PAUX=(+50.338,-69.844,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000)(0,0)

11.3 Programa CLE1.prg10 '#################################################################################20 ' CALIBRACION DEL ENCODER DE BANDA : PASO 130 ' 1) CLE1.prg: Posición A para obtener P_ENCDLT40 ' 2) CLE2.prg: Posición B para obtener P_ENCDLT50 '#################################################################################60 '70 ' Con la banda parada, colocar una pieza en la misma y llevar el Robot hasta situarlo en la pieza80 IF M_CLEST<>0 AND M_CLEST<>2 THEN ERROR 9100 ' Control de estado para asegurar el orden correcto de los pasos85 '90 M_CLEA=M_ENC 'Captura lectura de encoder en posición A100 P_CLEA=P_FBC 'Captura posicion A de robot en base a feedback de servos120 '140 M_CLEST=1 ' Paso 1 realizado220 HLTP_CLEA=(+534.251,+117.527,+153.202,+0.000,+0.000,-6.596,+0.000,+0.000)(4,0)P30=(-0.003,-0.039,+0.000,+0.000,+0.000,+0.000)(4,0)P31=(-0.003,-0.039,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000)PA=(+347.140,+318.769,+158.405,+0.000,+0.000,+0.099)(4,0)PB=(+309.082,-118.517,+155.235,+0.000,+0.000,+0.004)(4,0)

11.4 Programa CLE2.prg10 '#################################################################################20 ' CALIBRACION DEL ENCODER DE BANDA : PASO 230 ' 1) CLE1.prg: Posici¢n A para obtener P_ENCDLT40 ' 2) CLE2.prg: Posici¢n B para obtener P_ENCDLT50 '#################################################################################60 '70 ' Previamente se debe haber realizado el paso 1 (CLE1.prg)80 ' Desplazar la banda, llevar el robot hasta la pieza, y ejecutar este programa90 IF M_CLEST<>1 THEN ERROR 9100 ' Control de estado para asegurar el orden correcto de los pasos100 '110 '120 M_CLEB=M_ENC 'Captura lectura de encoder en posicion B130 P_CLEB=P_FBC 'Captura posicion B de robot en base a feedback de servos

Ingeniería en Automática y Electrónica Industrial 11-123

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place11 Listado de programas del robot

140 '150 MENCDIF#=M_CLEB-M_CLEA ' MENCDIF# es el avance del encoder160 ' Corrección de MENCDIF#, aunque lo mejor es mover la banda al arranque para alejarse del límite del rango165 RANGO#=M_ENCMAX-M_ENCMIN ' Fondo de escala del contador de encoder170 IF MENCDIF#<(-RANGO#/2) THEN MENCDIF#=MENCDIF#+RANGO#+M_ENCMIN ' Corrección movimiento decremental encoder171 IF MENCDIF#>(RANGO#/2) THEN MENCDIF#=MENCDIF#-RANGO#-M_ENCMIN ' Corrección movimiento incremental encoder180 '190 P_ENCDLT=(P_CLEB-P_CLEA)/(MENCDIF#) ' Calculo de P_ENCDLT195 P_ENCDLT.C=0 ' Si al pasar de A a B se ha cambiado la orientación de la herramienta, se desprecia200 '210 M_CLEST=2 ' Paso 2 y último realizado220 HLTP_CLEB=(+330.230,-341.555,+148.012,+0.000,+0.000,-34.542,+0.000,+0.000)(4,0)P_CLEA=(+534.251,+117.527,+153.202,+0.000,+0.000,-6.596,+0.000,+0.000)(4,0)P30=(-0.003,-0.039,+0.000,+0.000,+0.000,+0.000)(4,0)P31=(-0.003,-0.039,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000)PA=(+347.140,+318.769,+158.405,+0.000,+0.000,+0.099)(4,0)PB=(+309.082,-118.517,+155.235,+0.000,+0.000,+0.004)(4,0)

11.5 Programa CLV1.prg10 '##########################################################################20 ' CALIBRACION DE POSICION DEL SISTEMA VISION : PASO 130 ' 1) CLV1.prg: Posicion A para obtener P_ORGV (origen de sistema de vision)40 ' 2) CLV2.prg: Posicion B para obtener P_ORGV (origen de sistema de vision)50 ' 3) CLV3.prg: Posicion A para obtener M_RVBETA (rotacion de sistema de vision)60 ' 4) CLV4.prg: Posicion B para obtener M_RVBETA (rotacion de sistema de vision)70 ' IMPORTANTE: previamente debe haberse calibrado encoder para tener P_ENCDLT80 '##########################################################################90 '100 ' Con la banda parada, Colocar pieza en el ORIGEN (arriba izquierda) del campo de vision y ejecutar este programa130 '140 M_CLV1A=M_ENC ' Captura lectura de encoder en posicion A145 '150 M_CLVST=1 ' Paso 1 realizado160 HLT

11.6 Programa CLV2.prg10 '##########################################################################20 ' CALIBRACION DE POSICION DEL SISTEMA VISION : PASO 130 ' 1) CLV1.prg: Posicion A para obtener P_ORGV (origen de sistema de vision)40 ' 2) CLV2.prg: Posicion B para obtener P_ORGV (origen de sistema de vision)50 ' 3) CLV3.prg: Posicion A para obtener M_RVBETA (rotacion de sistema de vision)60 ' 4) CLV4.prg: Posicion B para obtener M_RVBETA (rotacion de sistema de vision)70 ' IMPORTANTE: previamente debe haberse calibrado encoder para tener P_ENCDLT80 '##########################################################################90 '100 ' Previamente se debe haber realizado el paso 1 (CLV1.prg)

Ingeniería en Automática y Electrónica Industrial 11-124

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place11 Listado de programas del robot

110 ' Desplazar la banda, llevar el robot a la pieza con la orientacion deseada, y ejecutar este programa120 '130 IF M_CLVST<>1 THEN ERROR 9100 ' Control de estado para segurar el orden de los pasos correctos140 '150 M_CLV1B=M_ENC ' Captura lectura de encoder en posicion B160 P_CLV1B=P_FBC ' Captura posicion B de robot en base a feedback de servos170 '180 MENCDIF#=M_CLV1B-M_CLV1A ' MENCDIF es el avance del encoder190 P_CLV1A=P_CLV1B-P_ENCDLT*MENCDIF# ' Mediante P_ENCDLT se obtiene la posicion A respecto al robot200 P_ORGV=P_CLV1A ' Finalmente se obtiene el origen del sistema de vision, para utilizarlo con TRK210 P_ORGV.A=0220 P_ORGV.B=0230 P_ORGV.C=0 ' Orientaciones nulas puesto que P_ORGV será el sistema de refencia relativo durante tracking240 '250 M_CLVST=2 ' Paso 2 realizado260 HLTP_CLV1B=(+239.501,-277.500,+149.140,+0.000,+0.000,-14.506,+0.000,+0.000)(4,0)P_CLV1A=(+571.037,+468.513,+157.575,+0.000,+0.000,-14.506,+0.000,+0.000)(4,0)P_ORGV=(+571.037,+468.513,+157.575,+0.000,+0.000,+0.000,+0.000,+0.000)(4,0)

11.7 Programa CLV3.prg10 '##########################################################################20 ' CALIBRACION DE POSICION DEL SISTEMA VISION : PASO 330 ' 1) CLV1.prg: Posicion A para obtener P_ORGV (origen de sistema de vision)40 ' 2) CLV2.prg: Posicion B para obtener P_ORGV (origen de sistema de vision)50 ' 3) CLV3.prg: Posicion A para obtener M_RVBETA (rotacion de sistema de vision)60 ' 4) CLV4.prg: Posicion B para obtener M_RVBETA (rotacion de sistema de vision)70 ' IMPORTANTE: previamente debe haberse calibrado encoder para tener P_ENCDLT80 '##########################################################################90 '110 ' Poner una pieza en el campo de vision del robot, ejecutar este programa, y desde PC "Enviar (X,Y) al robot"140 '150 OPEN "COM3:" AS #1160 INPUT #1,VXA,VYA ' Respecto de V (vision), recibe posiciones X e Y, de A170 M_CLV2A=M_ENC ' Captura lectura de encoder en posicion A175 P_VA=P_ZERO176 P_VA.X=VXA177 P_VA.Y=VYA180 '190 M_CLVST=3 ' Paso 3 realizado200 HLTP_VA=(+167.000,+125.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000)(0,0)

11.8 Programa CLV4.prg10 '##########################################################################20 ' CALIBRACION DE POSICION DEL SISTEMA VISION : PASO 130 ' 1) CLV1.prg: Posicion A para obtener P_ORGV (origen de sistema de vision)

Ingeniería en Automática y Electrónica Industrial 11-125

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place11 Listado de programas del robot

40 ' 2) CLV2.prg: Posicion B para obtener P_ORGV (origen de sistema de vision)50 ' 3) CLV3.prg: Posicion A para obtener M_RVBETA (rotacion de sistema de vision)60 ' 4) CLV4.prg: Posicion B para obtener M_RVBETA (rotacion de sistema de vision)70 ' IMPORTANTE: previamente debe haberse calibrado encoder para tener P_ENCDLT80 '##########################################################################90 '100 ' Previamente se debe haber realizado el paso 3 (CLV3.prg)110 ' Desplazar la banda, llevar el robot a la pieza con cualquier orientacion, y ejecutar este porograma120 '130 IF M_CLVST<>3 THEN ERROR 9100 ' Control de estado para segurar el orden de los pasos correctos140 '150 M_CLV2B=M_ENC ' Captura lectura de encoder en posicion B160 P_CLV2B=P_FBC ' Captura posicion B de robot en base a feedback de servos170 '180 MENCDIF#=M_CLV2B-M_CLV2A ' MENCDIF es el avance del encoder190 P_CLV2A=P_CLV2B-P_ENCDLT*MENCDIF# ' Mediante P_ENCDLT se obtiene la posicion A respecto al robot200 XREL=P_CLV2A.X-P_ORGV.X ' Posicion X relativa210 YREL=P_CLV2A.Y-P_ORGV.Y ' Posicion Y relativa215 AUXHOR=XREL*P_VA.X-YREL*P_VA.Y216 AUXVER=XREL*P_VA.Y+YREL*P_VA.X220 M_RVBETA=ATN2(AUXVER,AUXHOR) ' Se obtienen la rotación del sistema de visión respecto del sistema del robot230 M_RVBETG=DEG(M_RVBETA) ' Valor en grados para monitorización240 '250 M_CLVST=4 ' Paso 4 realizado260 HLTP_CLV2B=(+418.417,-284.882,+149.513,+0.000,+0.000,-32.846)(4,0)P_CLV2A=(+673.448,+288.980,+156.002,+0.000,+0.000,-32.846,+0.000,+0.000)(4,0)P_ORGV=(+571.037,+468.513,+157.575,+0.000,+0.000,+0.000,+0.000,+0.000)(4,0)P_VA=(+167.000,+125.000,+0.000,+0.000,+0.000,+0.000,+0.000,+0.000)(0,0)

Ingeniería en Automática y Electrónica Industrial 11-126

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place12 Especificaciones técnicas de los equipos utilizados

12 Especificaciones técnicas de los equipos utilizados

12.1 Robot RH5-AH55 controladora CR2A-572 MITSUBISHI ELECTRIC

Ingeniería en Automática y Electrónica Industrial 12-127

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place12 Especificaciones técnicas de los equipos utilizados

Ingeniería en Automática y Electrónica Industrial 12-128

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place12 Especificaciones técnicas de los equipos utilizados

12.2 Cámara SONY XCD-V50

Ingeniería en Automática y Electrónica Industrial 12-129

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place12 Especificaciones técnicas de los equipos utilizados

12.3 Tarjeta MATROX METEOR II/1394

Ingeniería en Automática y Electrónica Industrial 12-130

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place12 Especificaciones técnicas de los equipos utilizados

12.4 Servomotor MITSUBISHI ELECTRIC MRJ2S-A HCKFS

Ingeniería en Automática y Electrónica Industrial 12-131

Integración de sistema de visión artificial y robot en aplicación tipo Pick&Place12 Especificaciones técnicas de los equipos utilizados

12.5 Bomba de vacío NORGREN M/58112

Ingeniería en Automática y Electrónica Industrial 12-132