Informe - Escuela de Ingeniería Eléctrica

Anuncio
Universidad de Costa Rica
Facultad de Ingeniería
Escuela de Ingeniería Eléctrica
IE – 0502 Proyecto Eléctrico
Desarrollo de un modelo para la programación,
monitoreo y supervisión del robot RX90
Por:
Lucía Acuña Avendaño
Diego Castro Hernández
Ciudad Universitaria Rodrigo Facio
Octubre del 2005
Desarrollo de un modelo para la programación,
monitoreo y supervisión del robot RX90
Por:
Lucía Acuña Avendaño
Diego Castro Hernández
Sometido a la Escuela de Ingeniería Eléctrica
de la Facultad de Ingeniería
de la Universidad de Costa Rica
como requisito parcial para optar por el grado de:
BACHILLER EN INGENIERÍA ELÉCTRICA
Aprobado por el Tribunal:
_________________________________
Ing. Peter Zeledón Méndez
Profesor Guía
_________________________________
Ing. Esteban Zeledón Chaves
Lector
_________________________________
Ing. Manrique Murillo Calvo
Lector
ii
DEDICATORIA
Les dedicamos este trabajo a Dios, a nuestras familias y a todas las personas que
han ayudado en nuestra formación como ingenieros y como personas.
iii
RECONOCIMIENTOS
A Peter Zeledón, nuestro profesor guía por su apoyo.
iv
ÍNDICE GENERAL
ÍNDICE DE FIGURAS..................................................................................vii
ÍNDICE DE TABLAS......................................................................................x
RESUMEN.......................................................................................................xi
CAPÍTULO 1: Introducción .........................................................................12
1.1
1.2
Problema y justificación .......................................................................................12
Objetivos...............................................................................................................13
1.1.1
Objetivo general............................................................................................13
1.1.2
Objetivos específicos ....................................................................................13
1.3
Metodología ..........................................................................................................14
CAPÍTULO 2: Marco teórico .......................................................................17
2.1
2.2
2.3
2.4
2.5
2.6
2.7
2.8
2.9
Tipos de robots......................................................................................................17
2.1.1
Robots de investigación ................................................................................17
2.1.2
Robots industriales........................................................................................18
Sistema de brazo robot:.........................................................................................19
Unidad de energía externa ....................................................................................20
Brazo de robot.......................................................................................................21
Controlador ...........................................................................................................21
Péndulo de instrucción..........................................................................................22
Instrumental final del brazo ..................................................................................23
Lenguajes de programación para el control de robots ..........................................23
2.8.1
Programación gestual....................................................................................24
2.8.2
Programación textual ....................................................................................24
2.8.3
Lenguajes de programación más usados.......................................................25
Modelos tridimensionales y sistemas de simulación ............................................26
CAPÍTULO 3: El Brazo robot Staübli RX90..............................................29
3.1 Características del brazo robot Staübli RX90.................................................................30
3.1.1 Partes del brazo robot Staübli RX90....................................................................30
3.1.2 Rangos de operación del Staübli RX90 ...............................................................31
3.1.3 Dimensiones de las partes del brazo robot...........................................................34
CAPÍTULO 4: Desarrollo del modelo tridimensional del Staübli RX90 .36
4.1 Creación de las partes del modelo tridimensional ..........................................................38
4.2 Ensamblado de las partes modeladas..............................................................................40
4.2.1 Conversión de archivos Inventor - Autocad ........................................................40
v
4.2.2 Ensamblado de las partes en Autocad..................................................................43
4.3 Programación del modelo ...............................................................................................44
4.3.1 Rotación de bloques ......................................................................................46
4.3.2 Verificación de los movimientos ...............................................................49
4.3.3 Interfaz gráfica del modelo .........................................................................53
4.3.4 Ejemplo de la simulación de una rutina ...................................................58
4.3.5 Monitoreo del brazo robot ...........................................................................61
4.3.6 Acceso al programa de simulación ...........................................................63
CAPÍTULO 5: Extracción y lectura de coordenadas.................................64
5.1
5.2
5.3
Guía v+ .................................................................................................................64
Instrucciones en el lenguaje V+ para la extracción de coordenadas.....................65
Modificación del programa Copérnico .................................................................68
5.3.1 Envío de las coordenadas a la pantalla del monitor.............................................68
5.3.2 Creación del archivo Coordenadas.txt .................................................................73
5.3.2 Ejemplo de un archivo Coordenadas.txt ..............................................................75
5.4
Lectura de coordenadas ........................................................................................77
CAPÍTULO 6: Resultados experimentales..................................................81
6.1
6.2
6.3
Rutinas de prueba..................................................................................................81
Movimiento del modelo y del robot .....................................................................84
Resultados experimentales....................................................................................86
7.0 Conclusiones .............................................................................................89
8.0 Recomendaciones .....................................................................................91
BIBLIOGRAFÍA............................................................................................92
APENDICES...................................................................................................93
Apéndice 01: Código fuente del modelo ..............................................................................94
Apéndice 02: Copérnico modificado ..................................................................................116
ANEXOS .......................................................................................................133
vi
ÍNDICE DE FIGURAS
Figura 1.1: Diagrama de la metodología del proyecto ...............................16
Figura 2.1 Robot ASIMO, de la empresa Honda........................................18
Figura 2.2 Robots industriales operando en la industria automotriz .......19
Figura 2.3 Comparación del brazo humano con un brazo robot ..............20
Figura 2.4 Diagrama de bloque de un controlador de robot. ....................22
Figura 2.5 Apariencia del péndulo de instrucción. .....................................23
Figura 2.6 Modelo de brazo robótico, utilizando aplicaciones CAD ........27
Figura 3.1 Brazo robot Staübli RX90...........................................................30
Figura 3.2 Grados de libertad del brazo robot Staübli RX90 ...................31
Figura 3.3 Vista lateral del área de trabajo del Staübli RX90 ..................32
Figura 3.4 Vista superior del área de trabajo del Staübli RX90 ...............33
Figura 3.5 Dimensiones del Staübli RX90 (vista lateral y trasera) ...........35
Figura 4.1 Diagrama del proceso de creación del modelo..........................37
Figura 4.2 Pantalla inicial del Inventor .......................................................38
Figura 4.3 Proceso de modelado de una pieza en Inventor........................39
Figura 4.4 Partes del modelo del Staübli RX90 creadas en Autodesk
Inventor ® .......................................................................................................40
Figura 4.5 Archivo del pie del brazo con extensión “.sat” insertado en
Autocad ...........................................................................................................42
Figura 4.6 Cuadro de dialogo para crear bloques en Autocad..................42
Figura 4.7 Modelo tridimensional del brazo robot Staübli RX90.............43
Figura 4.8 Diagrama del proceso de programación del modelo................45
Figura 4.9 Distribución de los ejes del modelo tridimensional. Se
muestran los puntos de referencia para obtener la dirección del eje de
rotación en cada articulación ........................................................................47
vii
Figura 4.10 Rotación de la articulación 2. Se señalan los bloques
involucrados en esta rotación........................................................................48
Figura 4.11 Mensaje de error por sobrepasar límites de operación .........50
Figura 4.12 Mensaje para indicar al usuario el peligro de colisión ..........51
Figura 4.13 Sistema de coordenadas utilizado para detrminar las
coordenadas del punto de verificación .........................................................52
Figura 4.14 Vista frontal y derecha de la superficie cilíndrica de
protección en tono azul. .................................................................................52
Figura 4.15 Punto, cuyas coordenadas se utilizan para determinar el
peligro de un movimiento ..............................................................................53
Figura 4.16 Interfaz gráfica del software.....................................................54
Figura 4.17 Botón para observar coordenadas actuales del modelo y
cuadro de información que aparece .............................................................55
Figura 4.18 Diagrama de flujo del algoritmo de simulaciòn......................56
Figura 4.19 Interfaz para programar comando Drive para la cintura ....57
Figura 4.20 Interfaz para programar comando Here y Move...................57
Figura 4.21 Interfaz para programar comando Here y Move...................58
Figura 4.22 Interfaz para programar comando Ready..............................58
Figura 4.23 Programación del comando Drive ...........................................59
Figura 4.24 Programación del comando Here ............................................59
Figura 4.25 Cuadro de texto del simulador .................................................59
Figura 4.26 Programación de un ciclo de 5 repeticiones............................60
Figura 4.27 Programación del comando ready ...........................................60
Figura 4.28 Programación del comando Move ...........................................60
Figura 4.29 Cuadro de texto del simulador, mostrando la rutina completa
..........................................................................................................................61
Figura 4.30 a) Botón Monitoreo y b) Botón Inicio de monitoreo, para
iniciar el monitoreo del brazo robot.............................................................62
Figura 4.31 Acceso al cuadro de dialogo para ejecutar un macro ............63
viii
Figura 4.32 Cuadro de dialogo “Macros”, se debe ejecutar el macro
“Principal” ......................................................................................................64
Figura 5.1: Programa Copérnico..................................................................69
Figura 5.2: Posición del robot para cada conjunto de coordenadas de
prueba1.v2.......................................................................................................76
Figura 5.3: Diagrama de flujo del proceso de comunicación.....................79
Figura 5.4: Diagrama de flujo del proceso de lectura ................................80
Figura 6.1 Primeros tres movimientos de la rutina 1 .................................82
Figura 6.2 Primeros tres movimientos de la rutina 2 .................................83
Figura 6.3 Secuencia de movimientos ..........................................................85
ix
ÍNDICE DE TABLAS
Tabla 3.1 Rangos de rotación, velocidades y resolución de rotación por unión...............32
x
RESUMEN
El propósito de este trabajo consiste en la elaboración de un modelo tridimensional
del brazo robot Staubli RX90, ubicado en el laboratorio de Control Automático de la
Universidad de Costa Rica.
Dicho modelo permite la simulación de rutinas de movimiento y el monitoreo del
movimiento del robot.
Mediante la simulación de rutinas, se le permite al usuario que desea controlar el
robot visualizar el movimiento en tres dimensiones y tener la certeza de que la rutina
programada no provoca que el robot sobrepase los límites de operación ni que el robot se
golpee a si mismo.
A través del monitoreo del robot, se mejora la percepción visual del movimiento del
robot para quien desea controlarlo remotamente, pues sólo se contaba con una señal de
video para visualizar el movimiento del robot, ahora se tiene un medio tridimensional para
observar los movimientos ejecutados.
Además, se elaboró una guía para programación del lenguaje V+, para facilitar el
aprendizaje a quien desee controlar el robot. Dicha guía contiene las instrucciones de V+
más comúnmente utilizadas para el control del brazo Staubli RX90.
xi
CAPÍTULO 1: Introducción
1.1
Problema y justificación
En las últimas décadas, la utilización de robots en la industria y en el sector
científico se ha intensificado de gran manera. Sumado a esto, los avances tecnológicos
relacionados con áreas como la informática, electrónica digital y el control automático han
facilitado y promovido la creación de potentes herramientas de automatización de procesos.
Una de las razones principales que motivan el uso de robots consiste en la
sustitución del ser humano en la ejecución de tareas peligrosas o en la realización de
trabajos repetitivos que requieren gran precisión. Desde este punto de vista, la
programación del accionar del robot toma una importancia significativa.
Sin embargo dentro de la programación del movimiento de un robot, no sólo debe
considerarse la sistematización de un conjunto de comandos e instrucciones que el robot
comprenda y ejecute, es también relevante contar con un sistema capaz de permitirle al
programador simular la secuencia de movimientos y acciones programadas, es en este
punto donde el presente proyecto de investigación interviene.
La Escuela de Ingeniería Eléctrica de la Universidad de Costa Rica, cuenta con un
dispositivo robótico denominado Brazo Robot Staübli RX90, actualmente se cuenta con un
sistema que permite controlar el brazo a nivel local o remoto, pero no existe la posibilidad
de simular las secuencias de movimiento programadas de una forma gráfica que permita
ver el movimiento del robot.
La razón de ser de este proyecto consiste en dotar a este sistema de un medio para
simular el movimiento del brazo mediante la utilización de un modelo tridimensional con
las mismas características de forma y comportamiento del robot real.
12
Además el modelo a desarrollar llegará a satisfacer la necesidad de contar con un
medio para visualizar, en un ambiente tridimensional, el movimiento del robot cuando es
controlado remotamente.
1.2
Objetivos
1.1.1
Objetivo general
Elaborar un programa basado en un lenguaje de alto nivel (Borland Delphi y Visual
Basic 6.0) para el desarrollo de un modelo tridimensional para la programación, monitoreo
y supervisión del Robot RX90 en un ambiente de Windows de Microsoft.
1.1.2
Objetivos específicos
•
Aprender a programar en un lenguaje de alto nivel.
•
Desarrollar un modelo tridimensional dinámico del RX90.
•
Desarrollar un programa capaz de realizar las lecturas de coordenadas
enviadas por el controlador del RX90 a la interfaz “Einstein” desarrollada por
Esteban Zeledón Ch. y Peter Zeledón M. para la comunicación local-remoto con el
robot RX90.
•
Desarrollar una guía para programación en lenguaje V+, el cual es el
lenguaje más utilizado para la programación de robots y es el empleado por Staübli
Inc. desarrollador del RX90.
•
Desarrollar rutinas ejemplo.
13
•
Poner a disponibilidad de los estudiantes de la Universidad de Costa Rica
con permiso de utilizar las licencias de AutoCad la posibilidad de controlar y
programar un robot de tecnología de punta.
1.3
Metodología
Para la elaboración del modelo tridimensional del Brazo Robot Staübli RX90, fue
necesario en primera instancia, conocer las características físicas y la forma en que se
comporta el brazo al ser programado.
Para lo anterior se contó con los manuales proporcionados por el fabricante para
operación, montaje, mantenimiento y programación del RX90 y con el documento escrito y
programas desarrollados en la investigación dirigida y denominada : “Creación de una
interfaz gráfica humano-máquina para el control, monitoreo y supervisión del Brazo Robot
Staubli RX90 vía Internet” desarrollado por Esteban Zeledón Chaves y Peter Bernal
Zeledón Méndez.
Una vez dominados estos aspectos, se procedió a la creación de las partes del brazo
en el programa Inventor de AutoDesk, en su versión 7.0. Se escogió este software pues
cuenta con las condiciones idóneas para la creación y modelado estático de entidades
tridimensionales.
Sin embargo, el ensamblado de las partes creadas se realizó en el programa
AutoCad, pues este software facilitó la posibilidad de programar los bloques
tridimensionales ensamblados, mediante la creación de macros o procedimientos en el
lenguaje Visual Basic.
14
Una vez elaborado y programado el modelo tridimensional del Brazo Robot Staubli
RX90, se procedió a realizar un programa que permitiera la comunicación del modelo con
la interfaz creada para el control del brazo utilizando Internet, de esta forma se podría llevar
a cabo la simulación del movimiento utilizando el modelo y se podría observar en tres
dimensiones el movimiento del brazo cuando se controle remotamente.
En forma paralela, se encontraron las instrucciones en V+ que permitieron extraer
las coordenadas del robot. Luego de estudiar el manual del lenguaje empleado por Staübli
Inc. desarrollador del RX90, se desarrolló una guía para programación en lenguaje V+. El
objetivo de esta guía de programación es facilitar el aprendizaje del lenguaje, en ella
aparecen los comandos más utilizados tanto en inglés como en español. Con la ayuda de
esta guía cualquier estudiante que así lo desee es capaz de elaborar fácilmente rutinas
básicas para el robot, sin tener que pasar por la lectura extensa de los manuales.
Al contar con una forma de extraer las coordenadas, se procedió a realizar un
experimento del uso de los comandos de V+ en el laboratorio de control. Se controló el
robot y se trató de obtener las coordenadas conforme éste se fuera moviendo. Para ello se
idearon varias rutinas de prueba.
Una vez comprobada la posibilidad de extraer las coordenadas conforme se fuese
moviendo el brazo robot se procedió a crear un programa en Delphi y en Visual Basic. El
programa en Visual Basic fue capaz de realizar las lecturas de coordenadas enviadas por el
controlador del RX90 a la interfaz “Einstein”.
15
Figura 1.1: Diagrama de la metodología del proyecto
Fuente: autores
16
CAPÍTULO 2: Marco teórico
La ciencia avanza a un paso acelerado y el área de la robótica no es la excepción.
Como parte del diseño y creación de máquinas robóticas, el desarrollo de modelos
tridimensionales y sistemas de simulación son vitales para asegurar el correcto
funcionamiento del dispositivo mediante la recreación virtual del movimiento deseado del
robot.
Pero antes de entrar en detalle en lo referente al desarrollo de modelos
tridimensionales y sistemas de simulación, surge la necesidad de presentar conceptos
básicos relacionados con la robótica.
2.1
Tipos de robots
Como criterio de clasificación se empleará el uso del robot, se cuenta con dos
clasificaciones: robots de investigación y robots industriales.
2.1.1
Robots de investigación
Los robots de investigación intentan aportar algo nuevo a la robótica: nuevos
algoritmos más inteligentes o nuevas formas de movimiento. Este tipo de robots abarca los
robots antropomórficos, de tipo vehículo y los que imitan animales.
17
Figura 2.1 Robot ASIMO, de la empresa Honda
Fuente:www.robotics.utexas.edu/robotresearch
En la actualidad se realizan grandes esfuerzos por desarrollar robots
antropomórficos, tal es el caso del robot ASIMO, creado por la empresa Honda.
Los robots tipo vehículo son utilizados para transportar objetos o investigar regiones
de difícil acceso. Dentro de este tipo de robot puede mencionarse el MICROROVER,
enviado por la NASA al planeta Marte.
Mientras que los robots que imitan animales, basan su comportamiento en la
imitación del movimiento de animales como arañas, serpientes u hormigas.
2.1.2
Robots industriales
Este tipo de robots tienen un gran impacto en la industria y son por tanto
económicamente rentables. Básicamente son brazos mecánicos, con cierto número de
grados de libertad y que se caracterizan por la gran capacidad de realizar diversas tareas:
18
pintan superficies, sueldan, colocan piezas. Se utilizan en las plantas de montaje, haciendo
trabajos repetitivos y que pueden ser peligrosos para las personas.
Figura 2.2 Robots industriales operando en la industria automotriz
Fuente:www.robotics.utexas.edu/robotresearch
Un robot industrial es un tipo de maquinaria que proporciona una flexibilidad doble:
flexibilidad mecánica ya que al estar constituido por un sistema mecánico articulado puede
variar la posición de su extremo libre en el espacio, adoptando orientaciones especiales y
flexibilidad de programación, debido a que su configuración espacial está controlada por un
computador, de manera que es sencillo implementar rutinas de movimiento. El brazo robot
Staubli RX90 es un robot industrial.
2.2
Sistema de brazo robot:
Un tipo de robot industrial son los brazos robóticos. El diseño de un manipulador
robótico o brazo robot, toma como base el brazo humano, aunque con algunas diferencias.
Por ejemplo, un brazo robótico puede extenderse telescópicamente, para alargar el alcance
19
del brazo. En algunas ocasiones se les colocan pinzas para imitar la función y estructura de
la mano humana.
Figura 2.3 Comparación del brazo humano con un brazo robot
Fuente: www.chi.itesm.mx
Un sistema de brazo robot consta de los siguientes elementos:
1. Unidad de energía externa
2. Brazo de robot
3. Controlador
4. Péndulo de instrucción
5. Instrumental de final-del-brazo
2.3
Unidad de energía externa
Provee una combinación de energía eléctrica, hidráulica y neumática al sistema de
brazo robot. Los robots con cargas de trabajo reducidas son energizados por un sistema
eléctrico monofásico de 110 VAC. En el caso de robots con cargas medianas de trabajo el
suministro se da mediante sistemas eléctricos monofásicos de 110 VAC o trifásico de 208
acompañados de elemento instrumental final con energía neumática. Los robots industriales
20
con grandes cargas de trabajo usan principalmente energía eléctrica trifásica de 208 VAC
acompañada de un elemento instrumental final con energía hidráulica.
2.4
Brazo de robot
El brazo de robot es un dispositivo mecánico manejado ya sea por servo-motores
eléctricos, dispositivos neumáticos o accionadores hidráulicos. Los elementos básicos de
manejo, lineales o accionadores rotarios, permiten proveer movimientos ya sean de brazos
lineales o rotacionales. La combinación de los movimientos incluidos en el brazo
determinará el tipo de geometría.
2.5
Controlador
Se considera al controlador como el “cerebro” del sistema. Generalmente está
constituido por una computadora, por ende puede ser divido en sus componentes:
MPU/CPU (Unidad Micro Procesadora / Unidad Central Procesadora), la memoria, los
dispositivos de I/O: (Entrada/Salida), y la fuente de poder.
21
Figura 2.4 Diagrama de bloque de un controlador de robot.
Fuente: Manual del Taller de Integración Curricular de la Robótica
El controlador recibe retroalimentación del brazo sobre la posición de cada
articulación y su velocidad, de esta manera la posición de cada servomotor es ajustada a la
rutina de movimiento que está siendo ejecutada.
2.6
Péndulo de instrucción
El péndulo de instrucción permite al programador:
Energizar al robot y prepararlo para ser programado.
Escribir e instruir los programas del robot.
Ejecutar los nuevos programas.
El péndulo de instrucción es usado principalmente para guardar puntos o
localizaciones en un espacio tridimensional. Además si se desea mover el brazo robot
“manualmente”, se realiza la rotación a travéz del péndulo de instrucción. En la figura 2.5,
se muestrta la apariencia de este dispositivo.
22
Figura 2.5 Apariencia del péndulo de instrucción.
Fuente: Autores
2.7
Instrumental final del brazo
El elemento instrumental final es el que proporciona al robot la capacidad de
producir. El instrumental del final del brazo es frecuentemente llamado "end effector". Por
ejemplo si se requiere que un robot sea capaz de tomar un determinado objeto se le debe
agregar un elemento instrumental final en forma de pinzas, que le permita realizar su tarea.
2.8
Lenguajes de programación para el control de robots
La comunicación hombre-robot se puede llevar a cabo por medio del
reconocimiento de un conjunto de palabras dentro de un vocabulario limitado (depende del
hablante), a través de la enseñanza (utilizando el control manual y grabando los ángulos del
movimiento) y la repetición o con ayuda de lenguajes de programación de alto nivel.
La programación robótica puede realizarse con ayuda de un operador responsable
de las instrucciones que permiten el control (explícita) o permitiendo que el sistema tome
23
las decisiones al modelar la tarea y el entorno. La programación explícita cuenta con dos
técnicas: gestual y textual.
2.8.1
Programación gestual
Necesita al propio robot en la creación del programa y no es adaptable al entorno en
tiempo real con lo cual no ofrece soluciones de emergencia. El usuario no necesita conocer
ningún lenguaje de programación. Está dividida en dos clases:
Aprendizaje directo: utilizando un brazo maestro o maniquí se desplaza el punto
final de brazo. Una trayectoria continua es generada al memorizar un gran número de
puntos.
Por medio de un dispositivo de enseñanza: se controlan los movimientos y se
generan funciones auxiliares tales como la selección de las velocidades, la generación de
retardos, la señalización del estado de los sensores y el borrado y modificación de los
puntos de trabajo.
2.8.2
Programación textual
Los movimientos del brazo robótico se calculan usando instrucciones textuales
adecuadas. Esto permite mayor precisión en el movimiento además de existir una
comunicación con el entorno. Se subdivide en:
Programación textual explícita: Se dirige el movimiento punto a punto con la ayuda
de un lenguaje formal (secuencia de instrucciones textuales). Existen dos niveles, por un
lado, el elemental que controla los movimientos del brazo con incrementos angulares de
las articulaciones (articular) o definiendo los movimientos con respecto al sistema de
24
manufactura (cartesiano), por otro lado, el estructurado relaciona el objeto y el sistema
del robot (estructura de datos arborescente).
Programación textual especificativa: Se modelan las tareas y el universo del robot
utilizando una base de datos.
2.8.3
Lenguajes de programación más usados
Programación gestual: cuentan con instrucciones como PLAY (reproducir),
RECORD (grabar), FF (adelantar), FR (atrasar), PAUSE, STOP y funciones auxiliares
tales como INSERT (insertar un punto o una operación de trabajo) y DELETE (borrar) o
funciones relacionadas con sensores externos. Entre los más conocidos están el FUNKY
(IBM) con mando tipo “joystick” y T3 (CINCINNATI MILACROM) con dispositivo de
enseñanza ("teach pendant").
Programación textual explícita elemental: estos lenguajes presentan saltos
condicionales y a subrutinas, son de tipo intérprete y cuentan con instrucciones para el
uso de sensores básicos (tacto, fuerza, movimiento, proximidad y presencia). Entre estos
se encuentran el ANORAD (ANORAD CORPORATION), EMILY (IBM) que está
escrito en ensamblador y es transportable, RPL (SRI INTERNATIONAL) que cuenta con
compilador, SIGLA que es transportable, VAL (UNIMATION INC) con instrucciones en
inglés sencillas e intuitivas y MAL (politécnico de Milán).
Programación textual explícita estructurada: con estructuras de datos de tipo
complejo (vectores, posiciones y transformaciones). Entre los principales están AL
(Universidad de Stanford) con estructuras de bloques similares al ALGOL, HELP
(GENERAL ELECTRIC) escrito en Pascal/ Fortran y MAPLE (IBM) escrito como
intérprete en el lenguaje PL-1.
25
Programación textual especificativa: en este grupo se encuentran el RAPT
(Universidad de Edimburgo) que es intérprete, fue escrito en lenguaje APT y define una
serie de planos, cilindros y esferas con las cuales se construye cualquier otro objeto y el
LAMA (MIT) que se adapta bien al entorno.
Aunque hoy en día existan numerosos lenguajes de programación para robots, al
diseñarse estos lenguajes para la programación de un robot específico no es posible
aplicarlos de forma universal, solo funcionan para un modelo en particular. Además, los
lenguajes al crearse se dirigen a una utilización concreta y su utilización en otras áreas
diferentes es limitada. Así, todavía no existe un lenguaje ideal para la programación
robótica que cumpla con las características de universalidad y libertad de aplicación en
cualquier área deseada. El lenguaje ideal se caracterizaría por la claridad de la estructura
del programa, la sencillez de aplicación, la facilidad de ampliación, la
facilidad de
corrección y mantenimiento, la eficacia, la transportabilidad sobre cualquier equipo
mecánico o informático, la adaptabilidad a sensores (tacto, visión, etc), la posibilidad de
descripción de todo tipo de herramientas acoplables al manipulador y la interacción con
otros sistemas.
2.9
Modelos tridimensionales y sistemas de simulación
Ante la necesidad de probar los sistemas de robots desarrollados sin poner en riesgo
la integridad física del dispositivo surge la necesidad de sistemas de simulación del
movimiento del robot.
Sin embargo, aunque se cuente con programas computacionales que permitan
obtener las coordenadas de las articulaciones de un robot en un momento dado, la
26
visualización del movimiento real de robot se vuelve difícil si sólo se cuenta con estos
datos. Es precisamente ante esta situación, que los modelos tridimensionales del sistema
facilitan enormemente la labor de quien programa el movimiento del robot.
En la actualidad, se cuenta con la tecnología para desarrollar modelos
tridimensionales dinámicos de robots. Es decir, modelos que representan fielmente al robot
en sus características dinámicas, tomando en consideración aspectos como el peso de cada
componente, la fricción de las junturas, el desgaste, el equilibrio, deformaciones físicas,
entre otros aspectos.
Dependiendo de la aplicación así será el grado de complejidad del modelo a
desarrollar, por ejemplo si se requiere que el robot reconozca patrones en su ambiente, será
necesaria la construcción de mundos virtuales para poder realizar las simulaciones con el
mayor grado de semejanza a la realidad.
Pero si solo quiere visualizarse el movimiento del robot, se pueden desarrollar
modelos programables en aplicaciones C.A.D (que proviene de las siglas en inglés de
Computer Assisted Design).
Figura 2.6 Modelo de brazo robótico, utilizando aplicaciones CAD
Fuente:www.robotics.utexas.edu/robotresearch
27
La tecnología CAD aporta grandes beneficios en numerosas disciplinas pero que
normalmente abarca el diseño gráfico, el manejo de bases de datos para el diseño y la
fabricación, control numérico de máquinas herramientas, robótica y visión computarizada.
Los modelos tridimensionales desarrollados en aplicaciones CAD, requieren como
datos de entrada para simular el movimiento, todos los parámetros que permitan describir
completamente la posición de cada articulación del robot, así como los parámetros que
describan el movimiento que se desea realizar.
28
CAPÍTULO 3: El Brazo robot Staübli RX90
De acuerdo a las geometrías de brazos robóticos expuestas en el capítulo anterior, el
brazo robótico Staübli RX90 se considera de geometría ensamblada esférica.
Este brazo es utilizado en aplicaciones de “cuarto limpio”, posee un grado de
protección IP 65, que corresponde a una protección total contra polvo y contra el
lanzamiento de agua en todas direcciones.
Los movimientos de las uniones o junturas son generados por servomotores, cada
uno provisto de sensores y frenos. Gracias a estos sensores es posible determinar la
posición absoluta del brazo.
El equilibrio del brazo se efectúa mediante un sistema avanzado de resortes, que le
permiten al robot efectuar sus movimientos a una alta velocidad sin riesgo de perder su
equilibrio, siempre y cuando se cumplan los requisitos del fabricante referentes a la
instalación del brazo robot en el lugar de trabajo.
El dispositivo robótico tiene una capacidad de trabajo de 6 kg operando a velocidad
nominal. Algunas uniones pueden llegar a desarrollar un par de torsión máximo de 100 Nm
(Newton metros).
29
Figura 3.1 Brazo robot Staübli RX90
Fuente:www.staübli.com
3.1 Características del brazo robot Staübli RX90
3.1.1 Partes del brazo robot Staübli RX90
Este dispositivo robótico está compuesto por seis partes principales, dichas partes se
encuentran identificadas en la figura 3.2 y se listan a continuación:
A.
Pie
B.
Hombro
C.
Codo
D.
Antebrazo
E.
Brazo
F.
Muñeca
Cuenta con seis grados de libertad, determinados por las seis articulaciones
mostradas en la figura 3.2. Los grados de libertad se numeran del uno al seis.
30
Figura 3.2 Grados de libertad del brazo robot Staübli RX90
Fuente:www.staübli.com
3.1.2 Rangos de operación del Staübli RX90
Las especificaciones de rango de rotación permitido, velocidades máxima y nominal
además de la resolución de la rotación de cada unión se muestra en la tabla 3.1.
31
Tabla 3.1 Rangos de rotación, velocidades y resolución de rotación por unión
Unión
1
2
3
4
5
6
Amplitud (°)
320
275
285
540
225
540
Repartición de
A
B
C
D
E
F
amplitud (°)
+/- 160
+/- 137.5
+/- 142.5
+/- 270
+120/ -105
+/- 270
236
200
286
401
320
580
356
356
296
409
800
1125
0.87
0.87
0.72
1
1.95
2.75
Velocidad nominal
(°/s)
Velocidad máxima
(°/s)
Resolución angular
(x 103 °)
Figura 3.3 Vista lateral del área de trabajo del Staübli RX90
Fuente:www.staübli.com
32
Figura 3.4 Vista superior del área de trabajo del Staübli RX90
Fuente:www.staübli.com
Este brazo robot no cuenta con un medio que le permita detectar si al ejecutar un
movimiento podría golpearse a si mismo, pues sólo verifica que el movimiento de una
determinada unión se encuentre dentro del rango mostrado en la tabla 3.1.
El peligro de que el robot se golpee a si mismo, depende en gran medida de su
ubicación en el área de trabajo. Para el caso específico del Staubli RX90, se encuentra
“montado” sobre una base cilíndrica, del mismo radio que el pie del robot y con una altura
de 68 cm. El principal peligro radica en que la parte superior del robot llegue a golpear
dicha base. Como la colocación del robot depende de la aplicación para cual será utilizado
el brazo, entonces, para cada forma de colocar el robot, se tendrán diversas posibilidades de
causar un daño al robot. El controlador no tiene ninguna forma de determinar qué objetos
se encuentran cerca del brazo, por esta razón, el controlador no “sabe” si al ejecutar un
determinado movimiento, el instrumental final del brazo golpeará la base.
33
Además si el brazo se calibra de forma incorrecta, es más probable que el brazo al
ejecutar un movimiento se dañe a si mismo, pues las posiciones absolutas de cada unión
estarán siendo determinadas de forma incorrecta por el controlador del robot.
Por lo tanto, la calibración y las rutinas de movimientos que se deseen ejecutar
deben estar debidamente revisadas para asegurar la integridad del robot. Sin embargo, en la
actualidad no existen los medios para simular una rutina, de ahí la importancia del aporte
del presente proyecto.
3.1.3 Dimensiones de las partes del brazo robot
De acuerdo a las especificaciones del fabricante, existen dos tipos de brazo robot
Staübli RX90, la diferencia entre ambos radica en la longitud de la sección correspondiente
al brazo.
El robot instalado en el Laboratorio de Control y Automatización de la Escuela de
Ingeniería Eléctrica corresponde al tipo de brazo denominado de “brazo alargado”, por lo
que se presentará en la figura 3.3 las dimensiones para este tipo de brazo según el
fabricante (cotas en milímetros).
34
Figura 3.5 Dimensiones del Staübli RX90 (vista lateral y trasera)
Fuente:www.staübli.com
35
CAPÍTULO 4: Desarrollo del modelo tridimensional del Staübli
RX90
Como se mencionó en el capítulo 3, actualmente el brazo robótico Staübli RX90 no
cuenta con un sistema que le permita evitar la ejecución de un movimiento que pueda
provocarle un daño a su estructura.
Además, se tiene la posibilidad de controlar el brazo mediante la red Internet, esto
se logra a través de la aplicación COPÉRNICO, creada por Peter Zeledón y Esteban
Zeledón. El único mecanismo que posee COPÉRNICO para la verificación del movimiento
del brazo consiste en la presentación en pantalla de un video capturado por una WebCam y
transmitido a través de Internet.
El hecho de contar sólo con el video como medio de observación del movimiento
presenta desventajas como la visualización en dos dimensiones del movimiento, la baja
calidad del video tomado por la cámara y la lentitud de la transmisión del video a través de
la red. Esta situación, se pretende mejorar con la implementación del modelo
tridimensional, que imitará el movimiento real del robot.
El proceso de creación del modelo, se explica detalladamente en los siguientes
apartados. A manera de resumen, se presenta el siguiente diagrama, donde se muestra cada
paso para la creación del modelo.
36
Figura 4.1 Diagrama del proceso de creación del modelo
Fuente:Autores
37
4.1 Creación de las partes del modelo tridimensional
Utilizando el software Autodesk Inventor 7.0 ®, se crearon modelos
tridimensionales a escala de cada una de las partes del brazo robótico Staübli RX90. Cada
pieza modelada es una copia fiel de la pieza real.
Se utilizó el sofware Autodesk Inventor, pues es un sistema particularmente sencillo
para el modelado de sólidos en un entorno tridimensional, sin embargo no presenta
características idóneas para realizar la programación del modelo, por esta razón se decidió
crear cada parte del brazo en el Inventor y proceder con el ensamblado y programación del
modelo en Autocad.
El proceso de creación de cada pieza inicia con la determinción de las dimensiones
reales de cada pieza, a partir de dichas medidas se inició el proceso de modelado de cada
parte del brazo.
Para crear una parte nueva debe ejecutarse el programa Inventor e indicarle al
software que se desea crear un archivo “Standard .ipt”, dicho archivo será almacenado con
una extensión “.ipt”. La pantalla de arranque se muestra en la siguiente figura.
Figura 4.2 Pantalla inicial del Inventor
Fuente:Autores
38
Con esta pantalla abierta se procede a la creación del sólido tridimensional. Cada
pieza del robot debe ser “descompuesta” mentalmente por quien la modela, pues con el
Inventor se crean los sólidos apartir de figuras geométrics básicas, tales como un círculo
que posteriormente se le da forma tridimensional con la herramienta “extrude” que permite
convertir dicho círculo en el plano en un cilindro tridimensional de una altura deseada. En
la siguiente figura se muestra brevemente una parte del proceso de modelado del pie del
robot.
Figura 4.3 Proceso de modelado de una pieza en Inventor
Fuente:Autores
Como se observa, en la figura 4.2.1, inicialmente se determinó la base de la pieza,
posteriormente en el cuadro 2, se le dió forma de prisma al rectángulo anterior.
Posteriormente se crea un círculo que corresponderá al cuerpo de la pieza, como se observa
en el cuadro 4. De igual forma se procede con los detalles, se crean en un plano y se les da
forma tridimensional de acuerdo a las dimensiones deseadas.
En las siguientes figuras se muestran las partes creadas.
39
E. Antebrazo
A. Pie
B. Hombro
C. Brazo
D. Codo
F. Muñeca
G. Instrumental final
Figura 4.4 Partes del modelo del Staübli RX90 creadas en Autodesk Inventor ®
Fuente: Autores
4.2 Ensamblado de las partes modeladas
4.2.1 Conversión de archivos Inventor - Autocad
Una vez creadas las partes del brazo robótico se procede al ensamblado de modelo,
es decir, a la unión de las piezas para la obtención final del modelo tridimensional del brazo
robótico.
40
Cada pieza fue creada como un archivo con extensión “.ipt”, como la intención es
ensamblar el modelo en el programa Autodesk Autocad 2004 ®, es necesario entonces
exportar los archivos “.ipt” a un formato que Autocad sea capaz de procesar.
La forma en la cual se realizó dicha exportación fue almacenando en el disco duro
los archivos “.ipt” como archivos con extensión “.sat” (también conocidos como archivos
ACIS con formato ASCII). Este tipo de archivo es interpretado por Autocad como un
modelo de un objeto tridimensional o de una región bidimensional según sea el caso.
La conversión de archivos de “.ipt” a “.sat” no altera ninguna característica del
modelo del sólido almacenado en el archivo y fue el método seleccionado para realizar la
transferencia de archivos.
El aspecto inicial de los archivos “.sat” en Autocad se muestra en la figura 4.5.
Cada parte creada como “.ipt” fue importada en Autocad siguiendo el proceso de
conversión de formatos mencionado anteriormente. Una vez abierto cada archivo en
Autocad, se procedió a constituir cada pieza como un bloque con un nombre único para
cada parte.
Para insertar un archivo “.sat” en Autocad, se debe hacer clic en “archivo ACIS …”
dicha opción se encuentra en el menú “Insertar” en la barra de herramientas de Autocad.
Una vez insertada la pieza en Autocad, su apariencia es similar a la mostrada en la
figura 4.4.
41
Figura 4.5 Archivo del pie del brazo con extensión “.sat” insertado en Autocad
Fuente: Autores
Posteriormente, cada pieza insertada debe convertise en un bloque con un nombre
único que caracterice la pieza, pues para la programación es necesario reconocer cada parte
del modelo.
El proceso para realizar la creación de un bloque consiste en escribir el comando
“block” en la pantalla de comandos, con lo que se abrirá un cuadro de dialogo para la
creación de bloques, por lo que basta con seguir las indicaciones mostradas en la pantalla y
se habrá creado el bloque.
Figura 4.6 Cuadro de dialogo para crear bloques en Autocad
Fuente: Autores
42
4.2.2 Ensamblado de las partes en Autocad
Una vez insertada cada parte en Autocad y convertida cada pieza en un bloque, se
procedió a unir cada parte para formar el modelo completo del brazo robótico.
Como aspecto estético se le dió a cada parte una textura lisa para observar de una
manera más adecuada la forma tridimensional de cada pieza.
La unión de las partes se realizó de tal forma que el brazo ensamblado conserva las
características del brazo real, además se le asignó un color a cada pieza para distinguir
claramente cada parte durante el ensamblado. El modelo resultante se muestra en la figura
4.7.
Figura 4.7 Modelo tridimensional del brazo robot Staübli RX90
Fuente: Autores
43
Una vez ensamblado, el modelo es almacenado en el disco duro como un archivo de
dibujo de Autocad, es decir con extensión “.dwg”.
4.3 Programación del modelo
Para la programación del modelo, se realizaron varias etapas, debidamente
definidas. En el siguiente diagrama se resume cada etapa. La explicación del proceso de
programación, se expondrá en los siguientes apartados.
44
Programación
del modelo
Distribución de los ejes, para efectuar
las rotaciones, cada eje debe
convertirse también en bloque
Programación de las funciones para rotar
cada articulación, definiendo cuáles
bloques deben moverse y cuáles no, al
efectuarse cada rotación
Programación de las funciones de
verificación de rangos y de
protección del robot, creación de
formularios de precaución
Creación de los algoritmos para
reconocer y ejecutar comandos de
movimientos
Desarrollo de la interfaz gráfica, que permita
programar rutinas con los comandos
reconocibles, guardar y abrir rutinas en
archivos “.txt”
Programación del modo Monitoreo, que
permite visualizar al modelo imitando el
movimiento real del robot al ejecutarse una
rutina verdadera
Figura 4.8 Diagrama del proceso de programación del modelo
Fuente: Autores
45
4.3.1 Rotación de bloques
La programación del modelo se realizó en el lenguaje Visual Basic.
Inicialmente se crearon seis funciones para rotar cada una de las articulaciones del
brazo.
Cada función de rotación tiene como parámetro el valor del ángulo en grados, en
que se desea rotar la articulación deseada.
Se tomará la función RotarArticulacion1 para ejemplificar los procedimientos
realizados.
Como el parámetro de entrada de cada función para rotar es el ángulo, antes de
llamar a esta función se debe ya sea calcular o extraer de algún dato el número de grados
que se desea rotar la articulación correspondiente.
Posteriormente, para poder realizar la rotación de bloques es necesario contar con
un eje de rotación, dicho eje de rotación se forma con al menos dos puntos, estos puntos
son obtenidos de los “puntos de inserción” de los ejes del modelo tridimensional. El punto
de inserción de cada eje se define en el momento de convertir el eje en un bloque. Mediante
dicho punto es posible determinar la posición del eje.
La distribución de los ejes en el modelo se realiza de tal forma que en cada
articulación puedan identificarse dos puntos de inserción con la dirección adecuada, de tal
manera que la línea que une ambos puntos funcione como eje de rotación. Los ejes del
modelo se muestran en la figura 4.9.
46
Figura 4.9 Distribución de los ejes del modelo tridimensional. Se muestran los puntos
de referencia para obtener la dirección del eje de rotación en cada articulación
Fuente: Autores
Como se observa en la figura anterior, cada articulación cuenta con un eje que le
proporciona dos puntos que hacen posible tener la referencia para realizar la rotación
correspondiente a dicha articulación. La obtención del punto de inserción de los ejes
correspondientes se realiza mediante la función GetPuntoInserciondeEjes, cuyo parámetro
es el nombre del eje correspondiente y su salida es la posición del punto de inserción
correspondiente al eje.
Se tiene acceso al valor de la posición del punto de inserción de un bloque mediante
la siguiente expresión:
GetPuntoInserciondeEjes = ThisDrawing.ModelSpace.Item(i).InsertionPoint
Una vez obtenidas las posiciones de los dos puntos de inserción que definen el eje
de rotación, se procede a rotar las partes el modelo que se ven afectadas por la rotación de
la articulación correspondiente.
47
Por ejemplo, para el caso de la rotación de la articulación 2, todo el modelo debe
rotar excepto el pie del modelo, el eje vertical del pie, la base y el hombro. En la siguiente
figura se muestra la rotación de la articulación 2, señalando los bloques involucrados en el
proceso de rotado de esta unión.
Figura 4.10 Rotación de la articulación 2. Se señalan los bloques involucrados en esta
rotación
Fuente: Autores
El código que realiza la rotación es el siguiente.
For i = 0 To ThisDrawing.ModelSpace.Count - 1
str = ThisDrawing.ModelSpace.Item(i).ObjectName
If str = "AcDbBlockReference" Then
NombreObjeto = ThisDrawing.ModelSpace.Item(i).Name
If NombreObjeto <> "ejePieVertical1" And NombreObjeto <> "pie"
And NombreObjeto <> "base" And NombreObjeto <> "hombro" Then
ThisDrawing.ModelSpace.Item(i).Rotate3D
PuntoInsercion1, PuntoInsercion2,
sgn(AnguloRotación)*(3.14159265358979 / 180)
End If
End If
Next
Donde:
ThisDrawing.ModelSpace.Count = es el número de bloques presentes
en el modelo.
48
ThisDrawing.ModelSpace.Item(i).ObjectName = es el nombre del
i-ésimo bloque presente en el modelo.
ThisDrawing.ModelSpace.Item(i).Rotate3D = es la función que
realiza la rotación, tiene como parámetros dos puntos que definen el eje de
rotación y el ángulo de rotación en radianes.
La sección resaltada en amarillo, es donde se indican los bloques que no deben ser
movidos cuando se ejecuta la totación de esta unión en particular. Para cada unión se cuenta
con un conjunto de bloques que no deben ser movidos, los bloques a rotar dependen
evidentemente de la unión.
Finalmente, luego de cada rotación se actualiza el modelo, mediante la instrucción
ThisDrawing.Application.Update.
4.3.2 Verificación de los movimientos
Es indispensable que el modelo tenga un medio para alertar al usuario cuando un
movimiento se encuentra ya sea fuera del rango permitido para una articulación en
particular o cuando el movimiento deseado pueda llegar a causar un daño a la integridad
física del robot.
Inicialmente, se desarrolló la función “VerificacionDeRangos” que se encarga de
determinar si el movimiento deseado infringe los límites de operación del Staübli RX90
dados por el fabricante. Esta función recibe como parámetros el número de articulación a
rotar y el valor del ángulo que se desea rotar. La función detecta cuando el movimiento a
ejecutar sobrepasaría los límites de operación y detiene la simulación presentando al
usuario un mensaje de advertencia como el mostrado en la figura 4.11. La detección la
49
realiza haciendo el cálculo del conjunto de coordenadas a las que llegaría el modelo si
ejecutase el movimiento, con dichos valores de las coordenadas futuras simplemente se
revisa y todas las coordenadas están dentro de los rangos determinados por el fabricante. Si
hay al menos un valor de coordenada fuera de rango, se procede a mostrar el mensaje.
Figura 4.11 Mensaje de error por sobrepasar límites de operación
Fuente: Autores
De esta forma se le indica al usuario que la rutina simulada no es apta para el brazo
robot, sin embargo el principal aporte del modelo radica en indicarle al usuario cuando la
rutina deseada podría provocar un daño a la integridad física del robot.
El medio para detectar esta situación se basa en un mapeo de las coordenadas de un
punto ubicado en una posición del modelo que fue determinada experimentalmente como la
posición que puede fácilmente indicar si el movimiento puede provocar o no una colisión al
robot. La determinación de este punto se basó en la ejecución real de movimientos a baja
velocidad que de antemano se sabía que provocarían un golpe a la base, al pie del robot o a
la interfaz de conexión con el controlador. Esta interfaz se encuentra en la parte trasera del
pie del robot y es una zona que no debe ser golpeada. A la hora de ejecutar dichos
movimientos, se procuraba detener al robot justo antes de que colisionara, de tal manera
que al observarse la posición de cada parte del robot, se pudiera encontrar la forma de
evitar dicha colisión.
50
Por lo que se llegó a la conclusión que si se coloca un punto a 5 cm sobre el
instrumental final (que es la única parte del robot que puede provocar colisión) y se define
una superficie cilíndrica imaginaria de protección que rodee la base y el pie del robot,
siempre habrá forma de detectar un moviminiento riesgoso para la integridad del robot.
El criterio para determinar si el movimiento puede causar daño consiste en crear una
superficie cilíndrica alrededor de la base, incluyendo el pie del robot. El radio de dicha
superficie se define de tal manera que sea mayor que el radio de la base, por lo que se tiene
un rango de protección.
Si el punto definido se encuentra dentro o sobre la superficie de protección, se
considera que el movimiento es peligroso y podría provocar una colisión. Se le notificará al
usuario mediante el formulario mostrado en la figura 4.12 y se detendrá la simulación. En
dicho formulario se muestra además la posición del punto, mediante las tres coordenadas x,
y, z, de un sistema de coordenadas centrado en el centro de la parte inferior de la base.
Figura 4.12 Mensaje para indicar al usuario el peligro de colisión
Fuente: Autores
La orientación del sistema de coordenadas y su posición se muestran en la siguiente
figura. Con la línea roja discontinua se señala el origen del sistema.
51
Figura 4.13 Sistema de coordenadas utilizado para determinar las coordenadas del
punto de verificación
Fuente: Autores
El radio de la superficie cilíndrica de protección es de 19 cm y la altura medida
desde el suelo es de 98 cm. Cabe recordar que el radio de la base es de 15 cm y la altura de
la base es de 67 cm.
En las siguientes figuras se muestra la superficie cilíndrica de protección y el punto
ubicado sobre el instrumental final.
Figura 4.14 Vista frontal y derecha de la superficie cilíndrica de protección en tono
azul.
Fuente: Autores
52
Figura 4.15 Punto, cuyas coordenadas se utilizan para determinar el peligro de un
movimiento
Fuente: Autores
4.3.3 Interfaz gráfica del modelo
Para hacer del modelo un software amigable con el usuario, se creó una interfaz
gráfica lo más simple posible. Una captura de pantalla de dicha interfaz se muestra en la
figura 4.16.
53
Figura 4.16 Interfaz gráfica del software
Fuente: Autores
Es a través de esta interfaz que el usuario puede programar una rutina, almacenarla
en el directorio de su elección como un archivo con extensión “.txt”, abrir una rutina
previamente almacenada en el computador y realizar la simulación.
La interfaz tiene una apariencia similar a la del programa Copérnico y Galileo en su
sección para programar rutinas (estas aplicaciones son las utilizadas actualmente para
realizar el control del robot real, se controla localmente con Galileo y remotamente con
Copérnico), esto con el objetivo de familiarizar al usuario con la metodología real para
programar rutinas de movimiento.
Se cuenta con un botón que permite informar al usuario acerca del valor actual de
las coordenadas en cada una de las articulaciones, esto es especialmente útil cuando se
54
desee simular una rutina en una posición que no sea la posición “Ready” o la posición
“Zero”. Dicho botón y el cuadro de dialogo que muestra se pueden observar en la siguiente
figura.
Figura 4.17 Botón para observar coordenadas actuales del modelo y cuadro de
información que aparece
Fuente: Autores
Además se tiene la opción de hacer clic en el botón “Ver modelo”, que oculta la
interfaz gráfica y muestra el modelo.
Las instrucciones que son interpretadas por el programa son1:
Drive
Here
Move
For
Ready
En la siguiente figura, se presenta el diagrama de flujo del algoritmo de simulado de
una rutina.
1
Para mayor detalle acerca de esta funciones ver Anexos: “Guía rápida de lenguaje V+”
55
Figura 4.18 Diagrama de flujo del algoritmo de simulaciòn
Fuente: Autores
Para el comando “Drive”, basta con elegir de las barras de desplazamiento de la
articulación deseada el valor del ángulo y de la velocidad, luego hacer clic sobre el botón
“Registrar”, de esta forma aparece en pantalla la instrucción “Drive” con los parámetros
escogidos.
56
Figura 4.19 Interfaz para programar comando Drive para la cintura
Fuente: Autores
La velocidad no será simulada por el modelo, pues el objetivo es mostrar a una
velocidad adecuada el movimiento que haría el brazo robot real al ejecutar una rutina
determinada, asegurando que no infringe los límites de operación y que no es peligrosa para
el robot. Además, se pretende dar a quien simula la oportunidad de observar detalladamente
cada movimiento, para que determine si el espacio físico con el que cuenta en la realidad es
suficiente para ejecutar la rutina sin el riesgo de que el robot colisione con objetos extraños.
En el caso de la instrucción “Here”, para su uso se requiere digitar primero el nombre del
punto con el cual el programa reconocerá el conjunto de coordenadas de la posición del
robot que se desea almacenar para posteriormente hacer uso del comando “Move”,
llamando al punto por el mismo nombre utilizado al programar la instrucción “Here”.
Figura 4.20 Interfaz para programar comando Here y Move
Fuente: Autores
Para simular una rutina donde se desee utilizar la instrucción “For”, basta con
indicar el número de veces que se desea repetir el ciclo e indicar luego del código del ciclo,
la finalización del mismo haciendo clic sobre el botón “Fin de ciclo”.
57
Figura 4.21 Interfaz para programar comando Here y Move
Fuente: Autores
Finalmente, el uso de la instrucción “ready” es bastante simple, pues sólo se
requiere para su simulación, hacer clic sobre el botón “ready”.
Figura 4.22 Interfaz para programar comando Ready
Fuente: Autores
4.3.4 Ejemplo de la simulación de una rutina
Se mostrará a manera de ejemplo la creación de una nueva rutina y su simulación.
Se desea simular una rutina donde se mueva la cintura 90° y el codo 45°. Después,
se almacenará la posición del modelo luego de simular los dos movimientos anteriores bajo
el nombre “punto1”. Posteriormente, se simulará un ciclo de repeticiones que consistirá en
mover el modelo a la posición “Ready” y luego a la posición “punto1”, dicho ciclo se
repetirá 5 veces.
La rutina anterior, se inicia programando los movimientos de la cintura y el codo,
utilizando el comando Drive. Se elige el número de grados que se desea mover cada parte y
se hace clic en registrar para cada articulación que se desee rotar.
58
Figura 4.23 Programación del comando Drive
Fuente: Autores
Como se desea almacenar la posición del modelo luego de ejecutar los dos
comandos anteriores, se hará uso del comando Here. Se coloca primero el nombre de la
posición, en este caso “punto1”.
Figura 4.24 Programación del comando Here
Fuente: Autores
Posteriormente se hace clic en el botón Here, de manera que en el cuadro de texto
aparecerá el comando Here.
Figura 4.25 Cuadro de texto del simulador
Fuente: Autores
59
Para programar el ciclo de 5 repeticiones, basta con escribir con el teclado el
número 5, en el espacio dedicado al número de repeticiones.
Figura 4.26 Programación de un ciclo de 5 repeticiones
Fuente: Autores
Luego, se desea que el modelo se mueva a la posición Ready, esto se logra haciendo
clic en el botón Ready.
Figura 4.27 Programación del comando ready
Fuente: Autores
Con esto, aparecerá la palabra “ready” en el cuadro de texto. La última instrucción
del ciclo de repeticiones consiste en mover el modelo a la posición “punto1” almacenada
anteriormente, de manera que se hará uso del comando Move.
Para lo cual, se digitará el nombre de la posición a la que se desea mover el modelo
en el espacio dedicado para dicho fin.
Figura 4.28 Programación del comando Move
Fuente: Autores
60
Luego se hace clic en el botón Move.
Y para terminar el ciclo se hace clic en el botón “Fin de ciclo”.
La rutina debe finalizarse siempre haciendo clic en el botón “Finalizar rutina”. En
este punto de la programación de la rutina, la pantalla de texto debe aparecer como se
muestra en la siguiente figura.
Figura 4.29 Cuadro de texto del simulador, mostrando la rutina completa
Fuente: Autores
Para simular la rutina, simplemente se hace clic en el botón rojo de “Simular”.
4.3.5 Monitoreo del brazo robot
El modo monitoreo, permite al usuario observar al modelo realizando los mismos
movimientos del robot real en un determinado instante, mientras se está ejecutando una
rutina real en el robot.
61
Para realizar el monitoreo del brazo robot real, inicialmente se debe hacer clic sobre
el botón “Monitoreo”, que provocará la presentación en pantalla de un mensaje donde se
confirma el monitoreo, antes de hacer clic en el botón “Inicio de monitoreo” debe
ejecutarse una rutina mediante el programa Copérnico y posteriormente hacer clic en el
botón “Inicio de monitoreo”, de manera que el modelo se encuentre en espera de las
coordenadas enviadas por el brazo robot al ejecutar cada movimiento.
a
b
Figura 4.30 a) Botón Monitoreo y b) Botón Inicio de monitoreo, para iniciar el
monitoreo del brazo robot
Fuente: Autores
Una vez que se envía cada coordenada el modelo procede a procesar dicha
información, ejecutando el movimiento que envió el brazo real. La comunicación entre el
modelo y el programa Copérnico se realiza mediante un archivo de texto creado en un
directorio previamente establecido en cada programa.
Para lograr que el modelo no se “pierda” al leer el archivo de texto donde Copérnico
guarda las coordenadas enviadas por el brazo robot real, se diseñó un método que permite
leer cada coordenada si ya fue enviada y en el orden correcto, para evitar que el modelo
pretenda leer una línea del archivo de texto que no existe y provoque un error y además
para evitar que la lectura de las coordenadas tenga lugar de una manera desfasada y
provoque que el modelo mueva a la coordenada enviada la articulación incorrecta. Si la
62
lectura se realiza de manera desordenada, es evidente que el modelo no ejecutará el mismo
movimiento del brazo real.
Por lo que para evitar este tipo de inconvenientes, se establecieron ciclos de
búsqueda de coordenadas que permiten leer sólo si fue enviada la coordenada y además
leerla en el orden correcto.
4.3.6 Acceso al programa de simulación
El programa de simulación fue programado como una “macro” dentro del archivo
“.dwg” del modelo. Por lo que para ejecutar el simulador debe ser accesado mediante el
procedimiento establecido por Autocad para ejecutar macros, basta con indicar a Autocad
que acepte los macros contenidos en el archivo al abrirlo.
Se ejecuta un macro desde el menú “Herramientas”, luego el menú “Macro” y
finalmente se debe ser hacer clic en “Macros”
Figura 4.31 Acceso al cuadro de diálogo para ejecutar un macro
Fuente: Autores
63
Una vez realizado este procedimiento se abre el cuadro de diálogo “Macros”, en
dicho menú debe elegirse ejecutar el macro “Principal”, que al ejecutarse mostrará la
interfaz gráfica del simulador.
Figura 4.32 Cuadro de dialogo “Macros”, se debe ejecutar el macro “Principal”
Fuente: Autores
Otra forma de acceder la macro Principal, es mediante la creación de botones en las
barras de herramientas, sin embargo este procedimiento debe ejecutarse para cada
computadora donde se use el simulador, por esta razón se describe la forma general de
ejecutar un macro en Autocad.
CAPÍTULO 5: Extracción y lectura de coordenadas
5.1
Guía v+
Tal como se indicó en la metodología, paralelamente a la creación del modelo
tridimensional del robot, se estudiaron los manuales de utilización del lenguaje V+ con el
64
fin de utilizar las instrucciones que garantizarían una extracción eficiente de las
coordenadas del robot mientras este se encuentra en movimiento.
Dado que es requerido tener una comprensión general del lenguaje V+, se escribió
en un primer momento la “ Guía rápida del lenguaje V+”, documento en inglés con
traducción al español basado en el manual V+ Languaje User Guide. En esta guía se
especificaron los conceptos básicos del lenguaje tales como los tipos de programas, la
organización de estos, las subrutinas, los tipos de datos y clases de variables seguidos de las
principales funciones (string, numéricas, lógicas y de control del sistema) y las
instrucciones más utilizadas. Tal como se mencionó en un principio, el objetivo de esta
guía de programación fue facilitar el aprendizaje del lenguaje, aparece en inglés para que
pueda ser utilizada por personas de otros países y en español para que los estudiantes
nacionales no tengan dificultades con el idioma . La “Guía rápida del lenguaje V+” se
adjunta en los anexos. Con la ayuda de esta guía cualquier estudiante que así lo desee será
capaz de elaborar fácilmente rutinas básicas para el robot, sin tener que pasar por la lectura
extensa de los manuales.
5.2
Instrucciones en el lenguaje V+ para la extracción de coordenadas
A continuación se dará una breve explicación de las instrucciones utilizadas en la
extracción de coordenadas, en la siguiente sección se describirá el programa de V+
65
utilizado para este fin. Básicamente, los comandos a describir son: HERE, DECOMPOSE,
FOR, WAIT, TYPE2.
DECOMPOSE
Los puntos de precisión son variables propias de V+ que están compuestas por los seis
ángulos de las articulaciones del robot. Utilizando DECOMPOSE se logra asignar a seis
elementos de un arreglo los seis valores de un punto de precisión.
DECOMPOSE array_name[] = #loc_name
Pondrá los valores de juntura de #loc_name en el arreglo array_name. DECOMPOSE
trabaja tanto con transformaciones como con puntos de precisión tales como #loc_name.
Las transformaciones son igualmente variables propias de V+ que guardan los valores de
posición de las seis articulaciones con respecto a un sistema de coordenadas definido en el
robot.
Por ejemplo:
DECOMPOSE x[] = part
Asigna los componentes de la transformación part a los elementos desde el 0 hasta el 5 del
arreglo x.
DECOMPOSE angles[4] = #pick
Asigna los componentes del punto de precisión #pick al elemento del arreglo angles[4] y a
los cinco elementos del arreglo angles que lo siguen.
FOR
La instrucción FOR crea un ciclo de ejecución que ejecutará un bloque dado de código un
2
Para mayor información sobre las instrucciones y sobre el lenguaje V+ en general léase la “Guía rápida de
66
número especificado de veces. La forma básica de un ciclo FOR es:
FOR índice = start_val TO end_val STEP incr
bloque de código
.
END
El índice es una variable real que guardará huella del número de veces que el ciclo FOR se
ha ejecutado. Esta variable está disponible para uso dentro del ciclo.
El start_val es una expresión real para el valor de arranque del índice.
El end_val es una expresión real para el valor del fin del índice. La ejecución del ciclo
terminará cuando el índice alcance este valor.
El incr es una expresión real que indica la cantidad en que será incrementado el índice
después de cada ejecución del ciclo. El valor predefinido es 1.
Ejemplo:
106 FOR i = 1 TO 10
107 FOR j = 1 To 10
108 TYPE values[i,j]
109 END
110 TYPE " "
111 END
En este ejemplo el primer for recorre todas las filas de la matriz values, el segundo for
recorre los elementos de la fila correspondiente y el Type aparecen en pantalla dichos
valores. Luego de que aparezcan en pantalla todos los valores de una fila, con el segundo
Type aparece en pantalla un espacio en blanco.
V + ” en los anexos.
67
HERE
El método más directo de crear una variable de situación es poner el robot o dispositivo de
movimiento en una posición y entrar el comando de monitor: HERE loc_name
HERE #pick
crea el punto de precisión #pick igual a los valores de juntura del robot actuales.
Con la instrucción Here se guardan los ángulos de las seis articulaciones del robot en un
instante dado en el punto de precisión que aparece después de la instrucción. Se debe
recordar que un punto de precisión es una variable propia de V+ y está compuesta por los
seis valores de los ángulos de las articulaciones del robot.
TYPE
Instrucción de programa usada para mandar texto a la pantalla del monitor. Si se ha
definido que el valor del entero x es 27 y se realiza la siguiente instrucción:
TYPE "The value of x is ", x, "."
La salida en el monitor sera: The value of x is 27.
WAIT
La instrucción WAIT suspende la ejecución del programa actual por 16 milisegundos.
5.3
Modificación del programa Copérnico
5.3.1 Envío de las coordenadas a la pantalla del monitor
El programa Copérnico cuenta con un área de texto que en delphi se denomina
TMemo, se deseó que al ejecutar una rutina aparezcan en el TMemo las coordenadas del
68
robot conforme éste se moviera. Para ello, se modificaron las funciones asociadas a los
botones “Registrar” para cada una de las seis articulaciones y a los botones “Ready” y
“Finalizar rutina” en los comandos de movimiento del programa Copérnico. Estos botones
permiten agregar líneas de programa a las rutinas que están siendo creadas por el usuario.
Figura 5.1: Programa Copérnico
Fuente: Trabajo final de raduación de Peter Zeledón y Esteban Zeledón
La idea fue que al hacer clic en uno de estos botones no sólo se agregasen a la rutina el
comando de movimiento asociado ya sea un drive, un ready o la instrucción que marca el
fin del programa, sino también un conjunto de instrucciones en V+ que permitieran que en
el TMemo aparecieran los valores de juntura para cada posición del robot durante el
movimiento.
69
Las instrucciones en V+ utilizadas en la extracción de coordenadas fueron las que se
describieron en la sección 5.2. Después de cada comando de movimiento y de cada ready y
antes del fin del programa se agregaron en la rutina que estuviera escribiendo el usuario las
siguientes líneas en V+:
HERE #P
DECOMPOSE A[] = #P
FOR i = 1 TO 15
WAIT
END
TYPE A[0]
FOR i = 1 TO 15
WAIT
END
TYPE A[1]
FOR i = 1 TO 15
WAIT
END
TYPE A[2]
FOR i = 1 TO 15
WAIT
END
TYPE A[3]
FOR i = 1 TO 15
WAIT
END
TYPE A[4]
FOR i = 1 TO 15
WAIT
END
TYPE A[5]
Estas líneas de código permitieron crear un punto de precisión #P que contuviera los
seis valores de los ángulos de las articulaciones del robot antes de que comenzara a
ejecutarse el movimiento. La instrucción DECOMPOSE como se explicó anteriormente
llenó el vector A con los seis valores del punto de precisión #P.
Luego, el FOR garantizó que el programa esperara 15 veces 16 milisegundos, es
decir 240 milisegundos, antes de ejecutar la siguiente instrucción. Por último, el TYPE
70
mostró el valor del ángulo de la primera articulación en pantalla. Esto último se repitió para
las seis articulaciones. Así, antes de que el robot comenzara el movimiento se guardaron las
coordenadas y éstas se fueron mostrando en pantalla conforme se ejecutó el movimiento.
Después, al leer las coordenadas del TMemo fue necesario garantizar que se
escribiera una coordenada a la vez, es decir que hubiera un cierto tiempo entre la escritura
de una coordenada y la siguiente, es por ello que se utilizó el FOR con el WAIT antes de
cada TYPE, el tiempo mínimo necesario fue precisamente de 240 milisegundos. Este
tiempo fue determinado experimentalmente, se comenzó a probar la lectura del TMemo con
un tiempo de 480 milisegundos. Al aumentar el tiempo la lectura se realizaba
correctamente. Luego se fue disminuyendo el tiempo hasta que se encontró el límite de 240
milisegundos. Disminuir el tiempo por debajo de este valor causaba una lectura errónea del
TMemo.
De esta forma, para el caso del botón “Ready” la función asociada después de las
modificaciones para la extracción fue:
procedure TCopernico.ReadyClick(Sender: TObject);
begin
Leer.Lines.Add('ready');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.Count-1]);
Sleep(400);
Leer.Lines.Add('HERE #P');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.Count-1]);
Sleep(400);
Leer.Lines.Add('DECOMPOSE A[] = #P');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.Count-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.Count-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.Count-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.Count-1]);
71
Sleep(400);
Leer.Lines.Add('TYPE A[0]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.Count-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.Count-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.Count-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.Count-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[1]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.Count-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.Count-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.Count-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.Count-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[2]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.Count-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.Count-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.Count-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.Count-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[3]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.Count-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.Count-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.Count-1]);
Sleep(400);
Leer.Lines.Add('END');
72
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.Count-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[4]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.Count-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.Count-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.Count-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.Count-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[5]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.Count-1]);
end;
Leer.Lines.Add( ) agregó la línea de comando en V+ entre paréntesis al TMemo de
Copérnico y ClientSocket.Socket.SendText envió esta última línea al TMemo de Galileo
con lo que apareció en la rutina de V+ que estaba editando el usuario. Sin embargo, debido
a problemas con el Bufer, se utilizó la instrucción de delphi Sleep (400) para que se
esperase 400 milisegundos antes de enviar la siguiente línea de programa al servidor. Si no
se esperaba este mínimo de tiempo entre cada envió, el bufer se llenaba y en el siguiente
envío las líneas de comando aparecían en el TMemo del programa Galileo en una sola línea
con lo que no se podía editar correctamente la rutina.
5.3.2 Creación del archivo Coordenadas.txt
En primer lugar fue necesario crear un archivo de texto llamado Coordenadas en un
directorio que pudiera ser accesado fácilmente por el programa Copérnico y por el modelo
del robot. Por ello, al iniciar la conexión con el servidor, es decir al hacer clic en “Llamar a
...” en la pestaña “Archivo” del programa Copérnico se creó un archivo en el directorio
73
C:\Documents and Settings\All Users. Éstas fueron las líneas que se agregaron a la función
TCopernico.LlamarClick asociada con “Llamar a ...” :
AssignFile (MiFichero,'C:\Documents and Settings\All Users\Coordenadas.txt');
Rewrite (MiFichero); //Rewrite lo crea si no existe y si existe le borra el contenido
CloseFile (MiFichero);// Se cierra el archivo
Como se explicó anteriormente el programa Copérnico cuenta con un área de texto
que en delphi se denomina TMemo, en ésta aparecieron las coordenadas de posición
actuales del robot conforme éste realizaba el movimiento. A este TMemo se le asoció una
función llamada Coordenadas que se ejecutaba cada vez que ocurría un cambio en el área
de texto. Esta función se muestra a continuación:
procedure TCopernico.Coordenada(Sender: TObject);
Var
MiFichero : TextFile;
begin
// Permite anexar los valores de coordenadas en el archivo de texto creado
AssignFile (MiFichero,'C:\Documents and Settings\All Users\Coordenadas.txt');
Append (MiFichero); //Se escoje el modo anexar
WriteLn(MiFichero, Leer.Lines[Leer.Lines.Count-2]); //Se escribe la antepenúltima
línea
CloseFile (MiFichero);// Se cierra el archivo
end;
Básicamente,
el programa abre el archivo Coordenadas.txt y le anexa la
antepenúltima línea del TMemo cada vez que se detecta un cambio en el TMemo. Así una
vez creado el archivo se va anexando todo lo que aparece en el TMemo.
A la hora de que aparecieran las coordenadas en el TMemo, para que fueran
copiadas correctamente en el archivo se debió garantizar que existiera un tiempo mínimo
entre la aparición de una coordenada y la siguiente en el TMemo, es decir que al detectarse
74
un cambio en el TMemo fuera debido a que fue agregada una única línea con una
coordenada. Esto se logró con la instrucción FOR y el WAIT en V+ que permitieron una
espera de 240 milisegundos. Si se omitiera este ciclo antes de las instrucciones TYPE las
líneas se escribirían en grupos y al detectarse el cambio en el TMemo sólo se copiaría en el
archivo la última coordenada.
Además, al hacer clic en el botón “Ejecutar Rutina” en “Rutina” del programa
Copérnico se limpió el archivo Coordenadas.txt, lo que permitió que el modelo al empezar
a leer ese archivo encontrara solamente las coordenadas, esto facilitó la lectura. Para ello se
agregaron las siguientes líneas a la función TCopernico.ExecuteClick asociada al botón
“Ejecutar Rutina”:
AssignFile (MiFichero,'C:\Documents and Settings\All Users\Coordenadas.txt');
Rewrite (MiFichero);// Se borra el contenido anterior del archivo
WriteLn(MiFichero, Leer.Lines[Leer.Lines.Count-2]); // Se escribe la línea
CloseFile (MiFichero);// Se cierra el archivo
5.3.2 Ejemplo de un archivo Coordenadas.txt
El siguiente archivo se obtuvo después de la ejecución de la prueba1:
ex prueba1.v2
.ex prueba1.v2[4l
0
-89.99992
89.99969
0
75
0
0
-53
-89.99992
89.99969
0
0
0
-53
-45.99992
89.99969
0
0
0
Program task 0 stopped at prueba1.v2, step 151 22-Nov-05
Figura 5.2: Posición del robot para cada conjunto de coordenadas de prueba1.v2
Fuente: Autores
76
La rutina prueba1.v2 constó de dos comandos de movimiento, el archivo de texto
guardó tres conjuntos de seis coordenadas, una por cada articulación. El primer conjunto
correspondió a la posición ready que fue la posición en que se encontraba el robot antes de
iniciar el movimiento, el segundo conjunto correspondió a la posición del robot una vez
terminado el primer movimiento (Drive 1,-53,25) y antes de comenzar el segundo, el tercer
conjunto correspondió a la posición del robot una vez terminado el segundo movimiento
(Drive 2,44,25), es decir, el fin de la rutina.
5.4
Lectura de coordenadas
La función asociada al botón “Monitoreando” en el modelo del robot es la que se
encarga de la lectura del archivo Coordenadas.txt y del correspondiente movimiento del
robot. El primer paso del programa es abrir el archivo de texto y si éste está vacío, se cierra
y se vuelve a abrir hasta que se escriba en él. Esto se realizó con las siguientes
instrucciones, donde EOF(1) indica si se ha alcanzado el fin de línea.
etiqueta0:
If EOF(1) = True Then
Close #1
Open Directorio For Input As #1
GoTo etiqueta0
End If
Luego, se comienza un while, mientras no se llegue a la última línea se lee primero
una línea y se averigua si contiene "ex", "Program" o "E-". Si la coordenada en lectura
77
78
contiene un "E-", se le asigna el valor de cero. Por otro lado, si la coordenada en lectura no
contiene un "ex" ni un "Program" se copia la línea en un vector y con dicho valor se
procede a mover la articulación 1 del modelo.
A continuación, se espera que se escriba una nueva coordenada antes de continuar
con la lectura del archivo, para ello si se llega a la última línea se cierra, se vuelve a abrir el
archivo y se llega a la última línea leída antes de cerrar, si sigue habiendo un fin de línea se
vuelve a cerrar y así se continúa hasta que se escriba una nueva coordenada. Para ejecutar
lo anterior se utilizaron las siguientes instrucciones:
etiqueta1:
If EOF(1) = True Then
Close #1
Open Directorio For Input As #1
For i = 1 To ContadorLineas
Line Input #1, dato
Next
If EOF(1) = True Then
GoTo etiqueta1
Por ultimo, si se encuentra en la próxima línea un “Program” se cierra el archivo y
se termina la función.
Estos pasos se repiten seis veces para leer un conjunto de seis coordenadas y con
éstas mover las seis articulaciones del robot. Luego se regresa al siguiente ciclo del while,
79
mientras no se llegue a la última línea del archivo. Si se sale del while se cierra el archivo y
se sale de la función.
Figura 5.3: Diagrama de flujo del proceso de comunicación
Fuente: Autores
80
Figura 5.4: Diagrama de flujo del proceso de lectura
Fuente: Autores
81
CAPÍTULO 6: Resultados experimentales
6.1
Rutinas de prueba
Se realizaron tres rutinas ejemplo para probar el movimineto del modelo en tiempo
real, es decir el modo de monitoreo del modelo. Primeramente se simularon para
comprobar que no se producían moviminetos fuera de rango ni que produjeran que el robot
se golpeara contra si mismo. Luego, se editaron utilizando Copérnico.
La primera rutina fue la siguiente:
.Program rutina1.v2
Drive 2,-35,25
Drive 3,-25,25
Drive 5,-33,25
Drive 5,33,25
Drive 3,25,25
Drive 2,35,25
Drive 1,30,25
Drive 2,-35,25
Drive 3,-25,25
Drive 5,-33,25
Drive 5,33,25
Drive 3,25,25
Drive 2,35,25
Drive 1,30,25
Drive 2,35,25
ready
e
Se recuerda que toda rutina comienza por un .Program y termina con una e.
En esta rutina se mueven primero el brazo, el codo y la muñeca –35, -25 y 33
grados respectivamente. Luego vuelven a su posición original, es decir la posición ready
con las siguientes 3 instrucciones de Drive. Se rota la cintura 30 grados y se repiten una vez
82
más todos los movimientos realizados hasta ahora. Finalmente, con el último Drive se
mueve la articulación dos, es decir, el brazo 35 grados y se regresa a la posición ready con
el comando ready final. Se debe recordar que el primer argumento del drive es el número
de articulación, el segundo es el ángulo que se va a rotar y el tercero la velocidad del
movimineto. Para las tres rutinas de ejemplo la velocidad será de un 25 % de la velocidad
máxima del robot.
Figura 6.1 Primeros tres movimientos de la rutina 1
Fuente:autores
La segunda rutina es la siguiente:
.Program rutina2.v2
Drive 1,30,25
Drive 2,-29,25
Drive 2,32,25
Drive 3,69,25
Drive 4,-103,25
Drive 4,103,25
Drive 5,77,25
Drive 5,-53,49
ready
e
83
Esta rutina es más corta que la anterior, se mueven sucesivamente la cintura, el
brazo dos veces, el codo, el antebrazo, el antebrazo de nuevo y la muñeca dos veces. Los
ángulos de rotación se aprecian en el código. El ready final coloca al robot en su posición
ready que corresponde a la posición en que el robot está totalmente vertical.
Figura 6.2 Primeros tres movimientos de la rutina 2
Fuente:autores
La tercera rutina es la siguiente:
.Program rutina3.v2
Drive 1,-53,25
Drive 2,44,25
Drive 3,-38,25
84
Drive 4,-56,25
Drive 5,34,25
Drive 6,-106,25
ready
e
En esta última rutina se mueven la cintura, el brazo, el codo, el antebrazo, la
muñeca y la mano. También termina con un ready.
6.2
Movimiento del modelo y del robot
A continuación se muestran tres secuencias de imágenes donde se compara el
movimiento del modelo y del robot para la rutina de prueba tres.
Posición inicial
Movimiento 2
Movimiento 1
Movimiento 3
85
Movimiento 6
Movimiento 7
Movimiento 8
Figura 6.3 Secuencia de movimientos
Fuente:autores
En un principio, tanto el robot como el modelo se encuentran en la posición ready.
En la figura del movimiento 1 el robot rota su cintura –53 grados, pero el modelo sigue en
la posición ready. Esto se debe a que las coordenadas del robot de la posición anterior van
apareciendo en la pantalla de Copérnico conforme el robot se mueve a la siguiente
posición. Agregando los tiempos de transmisión, escritura y lectura, se puede afirmar que el
modelo no comenzará a realizar el movimiento uno hasta que el robot no comience a
86
realizar el movimiento dos. Por ello, en la figura final del movimiento dos, el modelo ya
realizó el primer movimiento, mientras que el robot ya rotó su articulación-dos 44 grados.
En la figura del movimiento tres, el modelo ya realizó el segundo movimiento y el robot
rotó la articulación-tres –38 grados. En la figura del movimiento seis ya el robot rotó las
articulación-cuatro, articulación-cinco y articulación-seis, mientras que el modelo está
atrasado un movimiento con respecto al robot. Finalmente en el movimiento siete el robot
ejecuta la instrucción ready, pero no es hasta la imagen del movimiento ocho cuando tanto
el robot como el modelo se encuentran en la posición ready. No se capturaron imágenes de
los movimientos 4 y 5.
6.3
Resultados experimentales
En general el retraso final es de alrededor de 4 segundos utilizando la red de la
escuela de ingeniería eléctrica. El retraso del modelo del robot con respecto al robot real se
debe a varias razones. La principal es que las coordenadas del robot en la posición que tenía
antes de comenzar el movimiento aparecen en la pantalla del programa Copérnico mientras
que el robot está ejecutando el próximo movimiento, es decir que el modelo lee las
coordenadas de la posición anterior mientras que el robot se dirige a la próxima posición.
Esto se debe al tiempo que se tarda en ejecutar el TYPE en el que se debe tomar en cuenta
el tiempo propio del controlador y el tiempo adicional de 240 milisegundos que es el
mínimo para asegurar una buena lectura de las coordenadas. Este tiempo no puede ser
disminuido. Al disminuirse se producen problemas a la hora de leer el TMemo de
Copérnico y guardar las coordenadas en el archivo de texto. El archivo resultante no
87
contiene todas las coordenadas que describen el movimiento del robot ya que algunas no
pudieron leerse del Tmemo.
Otras fuentes de retraso son el tiempo que se necesita para anexar cada coordenada
al archivo de texto y el tiempo que necesita el modelo para leer la coordenada y realizar el
movimiento. El movimiento de la cintura es el más lento ya que se deben mover todas las
partes del modelo. Por otro lado, el movimiento ready no corresponde siempre al mismo
conjunto de movimientos hecho por el robot, ya que éste busca el camino más corto a la
posición ready y el modelo, en cambio, mueve una articulación a la vez.
En resumen, las fuentes de retraso son:
•
Algoritmo de extracción de coordenadas (no se puede disminuir).
•
Espera de 240 milisegundos para garantizar que el archivo de texto contenga
todas las coordenadas que describen el movimineto del robot (no se puede
disminuir).
•
Espera de 400 milisegundos para garantizar que la rutina en V+ sea editada
correctamente (no se puede disminuir).
•
Tiempo de transmisión (depende de la red).
•
Tiempo de respuesta del controlador antes de que aparezca una coordenada
en la pantalla (no se puede disminuir).
•
Tiempo de escritura en el archivo Coordenadas.txt (no se puede disminuir).
88
•
Tiempo de lectura del archivo de texto y movimiento del modelo (se puede
mejorar el algoritmo de lectura).
89
7.0 Conclusiones
1. Con la elaboración del modelo se provee un medio para simular rutinas de
movimiento mostrando al usuario el movimiento real del robot de tal manera que
éste decida si cuenta con un espacio de trabajo mínimo en el cual el robot se pueda
mover libremente sin colisionar con algún objeto. Si bien no se modela todo el
espacio donde se desenvuelve el robot, el usuario tendrá una noción precisa del
movimiento del robot con la cuál podrá decidir si en algún movimiento en particular
de la rutina que ejecutará puede ser posible que el robot colisione con otro objeto.
2. Gracias al modelo se logra indicar cuándo una rutina puede poner en peligro la
integridad física del brazo del robot. Esto resulta particularmente útil a la hora de
trabajar con control remoto, puesto que el usuario no está en capacidad de
reaccionar rápidamente ante el peligro de golpe sólo con la ayuda del video. Se
debe tener en cuenta que en caso de golpear el panel de conexión con el controlador
se corre el riesgo de dañar gravemente el sistema de comunicación del robot y el
controlador imposibilitando el uso del robot en futuras ocasiones. Por ejemplo, en el
caso de un estudiante que quiera controlar el robot en forma remota, gracias a la
simulación provista por el modelo, el estudiante evitará ejecutar rutinas que causen
la colisión del robot contra alguna de sus partes. Antes de contar con el modelo esto
no era posible y el estudiante al ejecutar una rutina que provocara la colisión la
90
podría detener después de que el video le demostrara que el robot se había
golpeado. No había forma de saber cuando una rutina era peligrosa.
3. La principal ventaja del monitoreo es la capacidad de utilizar el movimiento
tridimensional del modelo como una fuente de realimentación y con esto controlar
más eficazmente el robot, anteriormente sólo se contaba con un video cuya calidad
dependía de las condiciones de transmisión y de la calidad de la cámara. Gracias al
modelo el usuario es capaz de conocer en detalle el movimiento real del robot,
puede así modificar los futuros movimientos de éste.
4. La misma naturaleza del método de extracción de las coordenadas impide que el
movimiento del robot y del modelo coincidan ya que el modelo lee las coordenadas
de la posición anterior mientras que el robot se dirige a la próxima posición.
5. El software de Autocad presenta características idóneas para el desarrollo de
modelos tridimensionales que requieren programación orientada al movimiento.
6. Gracias a la “Guía Rápida de V+” cualquier estudiante del país que así lo desee será
capaz de elaborar fácilmente rutinas básicas para el robot, sin tener que pasar por la
lectura engorrosa y bastante larga de los manuales.
91
8.0 Recomendaciones
1. Introducir en Copérnico un medio para interpretar las rutinas editadas en el
simulador.
2. Incluir en Copérnico el simulador, incluyendo el modelo.
3. Disminuir el tiempo de retardo mediante el mejoramiento del método de extracción
de coordenadas.
92
BIBLIOGRAFÍA
1. Zeledón, Peter y Zeledón, Esteban. Trabajo final de graduación: “Creación de una
Interfaz Gráfica Humano-Máquina para el control, Monitoreo y Supervisión del
Brazo Robot Staubli RX90 Via Internet”. Universidad de Costa Rica, Facultad de
Ingeniería, Escuela de Ingeniería Eléctrica. Julio del 2004.
2. Joyannes, Luis. Microsoft Visual Basic 6.0: Iniciación y referencia. Segunda
edición. Editorial McGraw Hill. Estados Unidos, 1999.
3. Manual del Taller de Integración Curricular de la Robótica
4. Nelson, Ross. Guía completa de Visual Basic para Windows. Segunda edición.
Editorial McGraw Hill. Estados Unidos, 1993.
5. Manual de usuario Autodesk Inventor 5.0. Autodesk Development S.A.R.L. 2000.
Suiza.
6. Sutpin, Joe. Autocad 2004 VBA: A PROGRAMMER’S REFERENCE, Editorial
Apress, Estados Unidos. 2003.
7. Información de Internet:
http//:www.robotics.utexas.edu/robotresearch
http//:www.chi.itesm.mx
http://www.staübli.com
http://www.emagister.com/vba-para-autocad-cursos-624687.htm
93
APENDICES
94
Apéndice 01: Código fuente del modelo
Funciones para rotar los bloques:
Sub RotarArticulación1(ByVal AnguloRotacion As Double)
Dim i As Integer, j As Integer
Dim str As String, NombreObjeto As String
Dim PuntoInsercion1 As Variant, PuntoInsercion2 As Variant
'Obtención de los puntos de inserción que definirán la dirección del eje de
rotación
PuntoInsercion1 = GetPuntoInserciondeEjes("ejePieVertical1")
PuntoInsercion2 = GetPuntoInserciondeEjes("ejePieHorizontal1")
j = 1
For j = 1 To Abs(AnguloRotacion)
i = 0
For i = 0 To ThisDrawing.ModelSpace.Count - 1
str = ThisDrawing.ModelSpace.Item(i).ObjectName
If str = "AcDbBlockReference" Then
NombreObjeto = ThisDrawing.ModelSpace.Item(i).Name
If NombreObjeto <> "ejePieVertical1" And NombreObjeto <> "pie" And
NombreObjeto <> "base" And NombreObjeto <> "piso" Then
ThisDrawing.ModelSpace.Item(i).Rotate3D PuntoInsercion1,
PuntoInsercion2, Sgn(AnguloRotacion) * (3.14159265358979 / 180)
End If
End If
Next
'ThisDrawing.Regen acActiveViewport
ThisDrawing.Application.Update
Next j
End Sub
Sub RotarArticulación2(ByVal AnguloRotacion As Double)
Dim i As Integer, j As Integer
Dim str As String, NombreObjeto As String
Dim PuntoInsercion1 As Variant, PuntoInsercion2 As Variant
'Obtención de los puntos de inserción que definirán la dirección del eje de
rotación
PuntoInsercion1 = GetPuntoInserciondeEjes("ejeAntebrazohorizonta2")
PuntoInsercion2 = GetPuntoInserciondeEjes("ejeAntebrazoVertical2")
j = 1
For j = 1 To Abs(AnguloRotacion)
i = 0
For i = 0 To ThisDrawing.ModelSpace.Count - 1
str = ThisDrawing.ModelSpace.Item(i).ObjectName
If str = "AcDbBlockReference" Then
95
NombreObjeto = ThisDrawing.ModelSpace.Item(i).Name
If NombreObjeto <> "ejePieVertical1" And NombreObjeto <>
"ejePieHorizontal1" And NombreObjeto <> "pie" And NombreObjeto <> "hombro" And
NombreObjeto <> "ejeAntebrazohorizonta2" And NombreObjeto <> "base" And
NombreObjeto <> "piso" Then
ThisDrawing.ModelSpace.Item(i).Rotate3D PuntoInsercion1,
PuntoInsercion2, (3.14159265358979 / 180) * Sgn(AnguloRotacion)
End If
End If
Next
'ThisDrawing.Regen acActiveViewport
ThisDrawing.Application.Update
Next j
End Sub
Sub RotarArticulación3(ByVal AnguloRotacion As Double)
Dim i As Integer, j As Integer
Dim str As String, NombreObjeto As String
Dim PuntoInsercion1 As Variant, PuntoInsercion2 As Variant
'Obtención de los puntos de inserción que definirán la dirección del eje de
rotación
PuntoInsercion1 = GetPuntoInserciondeEjes("ejeAntebrazoHorizontal3")
PuntoInsercion2 = GetPuntoInserciondeEjes("ejeAntebrazoVertical3")
j = 1
For j = 1 To Abs(AnguloRotacion)
i = 0
For i = 0 To ThisDrawing.ModelSpace.Count - 1
str = ThisDrawing.ModelSpace.Item(i).ObjectName
If str = "AcDbBlockReference" Then
NombreObjeto = ThisDrawing.ModelSpace.Item(i).Name
If NombreObjeto <> "ejePieVertical1" And NombreObjeto <>
"ejePieHorizontal1" And NombreObjeto <> "ejeAntebrazohorizonta2" And NombreObjeto
<> "ejeAntebrazoVertical2" And NombreObjeto <> "ejeAntebrazoVertical3" And
NombreObjeto <> "pie" And NombreObjeto <> "hombro" And NombreObjeto <>
"antebrazo" And NombreObjeto <> "base" And NombreObjeto <> "piso" Then
ThisDrawing.ModelSpace.Item(i).Rotate3D PuntoInsercion1,
PuntoInsercion2, (3.14159265358979 / 180) * Sgn(AnguloRotacion)
End If
End If
Next
'ThisDrawing.Regen acActiveViewport
ThisDrawing.Application.Update
Next j
End Sub
Sub RotarArticulación4(ByVal AnguloRotacion As Double)
Dim i As Integer, j As Integer
Dim str As String, NombreObjeto As String
Dim PuntoInsercion1 As Variant, PuntoInsercion2 As Variant
'Obtención de los puntos de inserción que definirán la dirección del eje de
rotación
PuntoInsercion1 = GetPuntoInserciondeEjes("ejeAntebrazoHorizontal3")
96
PuntoInsercion2 = GetPuntoInserciondeEjes("ejeCodoVertical4")
j = 1
For j = 1 To Abs(AnguloRotacion)
i = 0
For i = 0 To ThisDrawing.ModelSpace.Count - 1
str = ThisDrawing.ModelSpace.Item(i).ObjectName
If str = "AcDbBlockReference" Then
NombreObjeto = ThisDrawing.ModelSpace.Item(i).Name
If NombreObjeto = "ejeMuñecaVertical5" Or NombreObjeto =
"ejeMuñecaHorizontal5" Or NombreObjeto = "ejeInstFinalHorizontal6" Or
NombreObjeto = "brazo" Or NombreObjeto = "muñeca" Or NombreObjeto = "inst final"
Or NombreObjeto = "Punto" Then
ThisDrawing.ModelSpace.Item(i).Rotate3D PuntoInsercion1,
PuntoInsercion2, (3.14159265358979 / 180) * Sgn(AnguloRotacion)
End If
End If
Next
'ThisDrawing.Regen acActiveViewport
ThisDrawing.Application.Update
Next j
End Sub
Sub RotarArticulación5(ByVal AnguloRotacion As Double)
Dim i As Integer, j As Integer
Dim str As String, NombreObjeto As String
Dim PuntoInsercion1 As Variant, PuntoInsercion2 As Variant
'Obtención de los puntos de inserción que definirán la dirección del eje de
rotación
PuntoInsercion1 = GetPuntoInserciondeEjes("ejeMuñecaHorizontal5")
PuntoInsercion2 = GetPuntoInserciondeEjes("ejeMuñecaVertical5")
j = 1
For j = 1 To Abs(AnguloRotacion)
i = 0
For i = 0 To ThisDrawing.ModelSpace.Count - 1
str = ThisDrawing.ModelSpace.Item(i).ObjectName
If str = "AcDbBlockReference" Then
NombreObjeto = ThisDrawing.ModelSpace.Item(i).Name
If NombreObjeto = "ejeMuñecaVertical5" Or NombreObjeto =
"ejeInstFinalHorizontal6" Or NombreObjeto = "muñeca" Or NombreObjeto = "inst
final" Or NombreObjeto = "Punto" Then
ThisDrawing.ModelSpace.Item(i).Rotate3D PuntoInsercion1,
PuntoInsercion2, (3.14159265358979 / 180) * Sgn(AnguloRotacion)
End If
End If
Next
'ThisDrawing.Regen acActiveViewport
ThisDrawing.Application.Update
Next j
End Sub
Sub RotarArticulación6(ByVal AnguloRotacion As Double)
Dim i As Integer, j As Integer
Dim str As String, NombreObjeto As String
97
Dim PuntoInsercion1 As Variant, PuntoInsercion2 As Variant
'Obtención de los puntos de inserción que definirán la dirección del eje de
rotación
PuntoInsercion1 = GetPuntoInserciondeEjes("ejeMuñecaVertical5")
PuntoInsercion2 = GetPuntoInserciondeEjes("ejeInstFinalHorizontal6")
j = 1
For j = 1 To Abs(AnguloRotacion)
i = 0
For i = 0 To ThisDrawing.ModelSpace.Count - 1
str = ThisDrawing.ModelSpace.Item(i).ObjectName
If str = "AcDbBlockReference" Then
NombreObjeto = ThisDrawing.ModelSpace.Item(i).Name
If NombreObjeto = "inst final" Or NombreObjeto = "Punto" Then
ThisDrawing.ModelSpace.Item(i).Rotate3D PuntoInsercion1,
PuntoInsercion2, (3.14159265358979 / 180) * Sgn(AnguloRotacion)
End If
End If
Next
'ThisDrawing.Regen acActiveViewport
ThisDrawing.Application.Update
Next j
End Sub
Código del formulario principal
Global
Global
Global
Global
Global
Global
CoordenadaActualR1
CoordenadaActualR2
CoordenadaActualR3
CoordenadaActualR4
CoordenadaActualR5
CoordenadaActualR6
As
As
As
As
As
As
'coodenadas deseadas
Global CoordenadaDeseadaR1
Global CoordenadaDeseadaR2
Global CoordenadaDeseadaR3
Global CoordenadaDeseadaR4
Global CoordenadaDeseadaR5
Global CoordenadaDeseadaR6
Double
Double
Double
Double
Double
Double
As
As
As
As
As
As
Double
Double
Double
Double
Double
Double
Global FueraRango As Boolean
Global Golpe As Boolean
Global NumInstruccionesFor As Integer
Type PuntosPrecision 'Declarando el tipo de datos a utilizar para almacenar
ptos de precision
Nombre As String
R1 As Double
R2 As Double
R3 As Double
R4 As Double
R5 As Double
R6 As Double
End Type
Global MatrizHere() As PuntosPrecision
Global NumeroHere As Integer
Global ContadorHere As Integer
98
Sub Simulacion(ByVal NombreArchivo As String)
Dim instruccion As String, NombrePunto As String
Dim j As Integer, repeticiones As Integer
ContadorHere = 0
'Determinando el número de instrucciones Here a ejecutar para guardar espacio en
memoria
Open NombreArchivo For Input As #1
Do While Not EOF(1)
Line Input #1, instruccion
b = InStr(instruccion, "Here")
If b <> 0 Then
ContadorHere = ContadorHere + 1
End If
Loop
ReDim MatrizHere(ContadorHere) As PuntosPrecision
Close #1
Open NombreArchivo For Input As #1
j = 0
NumeroHere = 1
Do While Not EOF(1)
Line Input #1, instruccion 'Leyendo la linea correspondiente
j = j + 1
If instruccion = "e" Then
'e indica fin de rutina
Exit Do
End If
'Buscando la instrucción introducida en la rutina
'Buscando instruccion "Drive"
b = InStr(instruccion, "Drive")
If b <> 0 Then
GetDrive (instruccion)
End If
'Buscando instruccion "ready"
b = InStr(instruccion, "ready")
If b <> 0 Then
GetPosicionReady
End If
'Buscando instruccion for
b = InStr(instruccion, "For")
If b <> 0 Then
instruccion = RTrim(instruccion)
'Eliminando posibles espacios
a la derecha de la instruccion introducida
repeticiones = Val(Mid(instruccion, 12, Len(instruccion) - 11))
'Obteniendo el numero de repeticiones del For
'la
instruccion Len devuelve la longitud de la cadena,
'el
numero de repeticiones se obtienen del 12 caracter en adelante
Call GetFor(j, instruccion, NombreArchivo, repeticiones)
j = NumInstruccionesFor + j
End If
'Buscando instruccion Here
b = InStr(instruccion, "Here")
99
If b <> 0 Then
NombrePunto = Mid(instruccion, 6, Len(instruccion) - 5)
Call GetHere(NombrePunto, NumeroHere)
NumeroHere = NumeroHere + 1
End If
'Buscando instruccion Move
b = InStr(instruccion, "Move")
If b <> 0 Then
NombrePunto = Mid(instruccion, 6, Len(instruccion) - 5)
Call GetMove(NombrePunto, ContadorHere)
End If
'Si hubo algun error por rangos de movimientos o posible golpe
If FueraRango = True Or Golpe = True Then
Close
Exit Sub
End If
Loop
Close #1
End Sub
Código de las instrucciones de V+ reconocidas por el modelo
'función para la obtención de los puntos de inserción de los dos eje
'correspondientes a la rotación deseada.
'Parámetros de entrada:el nombre de los ejes necesarios para la rotación
'Salida: puntos de inserción de cada eje
Function GetPuntoInserciondeEjes(ByVal eje As String) As Variant
Dim i As Integer
Dim str As String
Dim NombreObjeto As String
i = 0
For i = 0 To ThisDrawing.ModelSpace.Count - 1
str = ThisDrawing.ModelSpace.Item(i).ObjectName
If str = "AcDbBlockReference" Then
NombreObjeto = ThisDrawing.ModelSpace.Item(i).Name
If NombreObjeto = eje Then
GetPuntoInserciondeEjes =
ThisDrawing.ModelSpace.Item(i).InsertionPoint
Exit For
End If
End If
Next
End Function
Sub GetDrive(ByVal instruccion As String)
Dim b As Variant
Dim Matriz() As String
Dim union As Integer, AnguloRotacion As Double
100
Matriz = Split(instruccion, ",")
Drive encontrada
union = Right(Matriz(0), 1)
AnguloRotacion = Val(Matriz(1))
'Extrayendo argumentos de la instruccion
'Obteniendo el numero de la union a mover
'Obteniendo el angulo de rotacion
Call VerificacionDeRangos(union, AnguloRotacion)
If FueraRango = True Then
ErrorForm.Show
Exit Sub
End If
Select Case union
Case 1
RotarArticulación1 (AnguloRotacion)
CoordenadaActualR1 = CoordenadaActualR1
Case 2
RotarArticulación2 (AnguloRotacion)
CoordenadaActualR2 = CoordenadaActualR2
ProteccionGolpe
If Golpe = True Then
PeligroForm.Show
Exit Sub
End If
Case 3
RotarArticulación3 (AnguloRotacion)
CoordenadaActualR3 = CoordenadaActualR3
ProteccionGolpe
If Golpe = True Then
PeligroForm.Show
Exit Sub
End If
Case 4
CoordenadaActualR4 = CoordenadaActualR4
RotarArticulación4 (AnguloRotacion)
Case 5
RotarArticulación5 (AnguloRotacion)
CoordenadaActualR5 = CoordenadaActualR5
ProteccionGolpe
If Golpe = True Then
PeligroForm.Show
Exit Sub
End If
Case 6
CoordenadaActualR6 = CoordenadaActualR6
RotarArticulación6 (AnguloRotacion)
+ AnguloRotacion
+ AnguloRotacion
+ AnguloRotacion
+ AnguloRotacion
+ AnguloRotacion
+ AnguloRotacion
End Select
End Sub
Sub GetFor(ByVal j As Integer, ByVal instruccion As String, ByVal NombreArchivo
As String, ByVal repeticiones As Integer)
Dim i As Integer, n As Integer, repeticiones2 As Integer, g As Integer
Dim aux As Integer, aux2 As Integer
Dim NombrePunto As String
aux2 = 0 'llevará el numero de instrucciones de cada for ejecutado
For i = 1 To repeticiones
101
n = 0
Do While instruccion <> "End"
Line Input #1, instruccion 'Leyendo la linea correspondiente
'Buscando la instrucción introducida en la rutina
n = n + 1
'Buscando instruccion "Drive"
b = InStr(instruccion, "Drive")
If b <> 0 Then
GetDrive (instruccion)
End If
'Buscando instruccion "ready"
b = InStr(instruccion, "ready")
If b <> 0 Then
GetPosicionReady
End If
'Buscando instruccion for
b = InStr(instruccion, "For")
If b <> 0 Then
instruccion = RTrim(instruccion)
'Eliminando posibles espacios a la derecha de la instruccion introducida
repeticiones2 = Val(Mid(instruccion, 12, Len(instruccion) 11)) 'Obteniendo el numero de repeticiones del For
'la instruccion Len devuelve la longitud de la cadena,
'el numero de repeticiones se obtienen del 12 caracter en adelante
Call GetFor(j + n, instruccion, NombreArchivo, repeticiones2)
n = n + NumInstruccionesFor 'menos 1 porque se cuenta la
instrucción actual y luego se le sumará 1 al n
End If
'Buscando instruccion Here
b = InStr(instruccion, "Here")
If b <> 0 Then
NombrePunto = Mid(instruccion, 6, Len(instruccion) - 5)
Call GetHere(NombrePunto, NumeroHere)
NumeroHere = NumeroHere + 1
End If
'Buscando instruccion Move
b = InStr(instruccion, "Move")
If b <> 0 Then
NombrePunto = Mid(instruccion, 6, Len(instruccion) - 5)
Call GetMove(NombrePunto, ContadorHere)
End If
If FueraRango = True Or Golpe = True Then
Close
Exit Sub
End If
Loop
If i <> repeticiones Then
iteraciones del For por simular
Close #1
'Revisando si faltan
102
Open NombreArchivo For Input As #1
For g = 1 To j
Line Input #1, instruccion
'Leyendo la linea
correspondiente
Next
End If
Next
NumInstruccionesFor = n
End Sub
Sub GetHere(ByVal NombrePunto As String, ByVal i As Integer)
MatrizHere(i).Nombre = NombrePunto
MatrizHere(i).R1 = CoordenadaActualR1
MatrizHere(i).R2 = CoordenadaActualR2
MatrizHere(i).R3 = CoordenadaActualR3
MatrizHere(i).R4 = CoordenadaActualR4
MatrizHere(i).R5 = CoordenadaActualR5
MatrizHere(i).R6 = CoordenadaActualR6
End Sub
Sub GetMove(ByVal NombrePunto As String, ByVal Contador As Integer)
Dim i As Integer
Dim AnguloRotacion As Double
Dim Texto As String
i = 1
Do While i <= Contador
Texto = MatrizHere(i).Nombre
If Texto = NombrePunto Then
AnguloRotacion = MatrizHere(i).R1 - CoordenadaActualR1
Call VerificacionDeRangos(1, AnguloRotacion)
If FueraRango = True Then
ErrorForm.Show
Exit Sub
End If
CoordenadaActualR1 = MatrizHere(i).R1
RotarArticulación1 (AnguloRotacion)
AnguloRotacion = MatrizHere(i).R2 - CoordenadaActualR2
Call VerificacionDeRangos(2, AnguloRotacion)
If FueraRango = True Then
ErrorForm.Show
Exit Sub
End If
CoordenadaActualR2 = MatrizHere(i).R2
RotarArticulación2 (AnguloRotacion)
ProteccionGolpe
If Golpe = True Then
PeligroForm.Show
Exit Sub
End If
AnguloRotacion = MatrizHere(i).R3 - CoordenadaActualR3
Call VerificacionDeRangos(3, AnguloRotacion)
If FueraRango = True Then
ErrorForm.Show
Exit Sub
103
End If
CoordenadaActualR3 = MatrizHere(i).R3
RotarArticulación3 (AnguloRotacion)
ProteccionGolpe
If Golpe = True Then
PeligroForm.Show
Exit Sub
End If
AnguloRotacion = MatrizHere(i).R4 - CoordenadaActualR4
Call VerificacionDeRangos(4, AnguloRotacion)
If FueraRango = True Then
ErrorForm.Show
Exit Sub
End If
CoordenadaActualR4 = MatrizHere(i).R4
RotarArticulación4 (AnguloRotacion)
AnguloRotacion = MatrizHere(i).R5 - CoordenadaActualR5
Call VerificacionDeRangos(5, AnguloRotacion)
If FueraRango = True Then
ErrorForm.Show
Exit Sub
End If
CoordenadaActualR5 = MatrizHere(i).R5
RotarArticulación5 (AnguloRotacion)
ProteccionGolpe
If Golpe = True Then
PeligroForm.Show
Exit Sub
End If
AnguloRotacion = MatrizHere(i).R6 - CoordenadaActualR6
Call VerificacionDeRangos(6, AnguloRotacion)
If FueraRango = True Then
ErrorForm.Show
Exit Sub
End If
CoordenadaActualR6 = MatrizHere(i).R6
RotarArticulación6 (AnguloRotacion)
Exit Do
End If
i = i + 1
Loop
End Sub
Código de las funciones para mover el modelo
Sub GetPosicionReady()
Dim AnguloRotacion As Double
AnguloRotacion = -CoordenadaActualR1
RotarArticulación1 (AnguloRotacion)
CoordenadaActualR1 = 0
104
AnguloRotacion = -90 - CoordenadaActualR2
RotarArticulación2 (AnguloRotacion)
CoordenadaActualR2 = -90
ProteccionGolpe
If Golpe = True Then
PeligroForm.Show
Exit Sub
End If
AnguloRotacion = 90 - CoordenadaActualR3
RotarArticulación3 (AnguloRotacion)
CoordenadaActualR3 = 90
ProteccionGolpe
If Golpe = True Then
PeligroForm.Show
Exit Sub
End If
AnguloRotacion = -CoordenadaActualR4
RotarArticulación4 (AnguloRotacion)
CoordenadaActualR4 = 0
AnguloRotacion = -CoordenadaActualR5
RotarArticulación5 (AnguloRotacion)
CoordenadaActualR5 = 0
ProteccionGolpe
If Golpe = True Then
PeligroForm.Show
Exit Sub
End If
AnguloRotacion = -CoordenadaActualR6
RotarArticulación6 (AnguloRotacion)
CoordenadaActualR6 = 0
End Sub
Sub GetPosicionZero()
Dim AnguloRotacion As Double
AnguloRotacion = -CoordenadaActualR1
RotarArticulación1 (AnguloRotacion)
CoordenadaActualR1 = 0
AnguloRotacion = -CoordenadaActualR2
RotarArticulación2 (AnguloRotacion)
CoordenadaActualR2 = 0
ProteccionGolpe
If Golpe = True Then
PeligroForm.Show
Exit Sub
End If
AnguloRotacion = -CoordenadaActualR3
RotarArticulación3 (AnguloRotacion)
CoordenadaActualR3 = 0
ProteccionGolpe
If Golpe = True Then
105
PeligroForm.Show
Exit Sub
End If
AnguloRotacion = -CoordenadaActualR4
RotarArticulación4 (AnguloRotacion)
CoordenadaActualR4 = 0
AnguloRotacion = -CoordenadaActualR5
RotarArticulación5 (AnguloRotacion)
CoordenadaActualR5 = 0
ProteccionGolpe
If Golpe = True Then
PeligroForm.Show
Exit Sub
End If
AnguloRotacion = -CoordenadaActualR6
RotarArticulación6 (AnguloRotacion)
CoordenadaActualR6 = 0
End Sub
Código de las funciones para verificar los movimientos
Sub VerificacionDeRangos(ByVal union As Integer, ByVal AnguloRotacion As Double)
'Verificación de que el movimiento programado no infrinja los rangos
permitidos
FueraRango = False
Select Case union
Case 1 ''Articulacion 1
If Abs(AnguloRotacion + CoordenadaActualR1) > 160 Then
FueraRango = True
End If
Case 2 ''Articulacion 2
If (AnguloRotacion + CoordenadaActualR2) > 47.5 Or (AnguloRotacion +
CoordenadaActualR2) < -227.5 Then
FueraRango = True
End If
Case 3 ''Articulacion 3
If (AnguloRotacion + CoordenadaActualR3) > 232.5 Or (AnguloRotacion +
CoordenadaActualR3) < -52.5 Then
FueraRango = True
End If
Case 4 ''Articulacion 4
If Abs(AnguloRotacion + CoordenadaActualR4) > 270 Then
FueraRango = True
End If
Case 5 ''Articulacion 5
If (AnguloRotacion + CoordenadaActualR5) < -105 Or (AnguloRotacion +
CoordenadaActualR5) > 120 Then
FueraRango = True
End If
106
Case 6 ''Articulacion 6
If Abs(AnguloRotacion + CoordenadaActualR6) > 270 Then
FueraRango = True
End If
End Select
End Sub
Sub ProteccionGolpe()
Dim punto As Variant
Dim R As Double, L As Double
L = 680 + 500
'Los 500 son de la altura del pie
R = 170
'Radio del pie es de 300 mm
Golpe = False
'Verificación de que el movimiento programado no presente un peligro para el
robot
punto = GetPuntoInserciondeEjes("Punto")
'Determinación de si el punto se encuentra sobre o dentro del cilindro de
seguridad
If (((punto(1) * punto(1) + punto(0) * punto(0)) <= R * R) And punto(2) >= 0
And punto(2) <= L) Then
Golpe = True
End If
End Sub
Código de los formularios
1.
Formulario de notificación de error por limites de operación
Private Sub CommandButton1_Click()
ErrorForm.hide
SimulandoForm.hide
MonitoreandoForm.hide
Close
End Sub
2.
Formulario de monitoreo
Private Sub Btn_Monitoreando_Click()
Dim Coordenadas(0 To 5) As String
Dim Directorio As String, dato As String
Dim b As Integer, c As Integer, ContadorLineas As Integer
ContadorLineas = 0
'Cuenta la linea actual de lectura
Directorio = "C:\Documents and Settings\All Users\" + "Coordenadas.txt"
Open Directorio For Input As #1
Sleep (300)
etiqueta0:
If EOF(1) = True Then
Close #1
Open Directorio For Input As #1
GoTo etiqueta0
End If
Do While Not EOF(1)
107
Line Input #1, dato
ContadorLineas = ContadorLineas + 1
b = InStr(dato, "ex")
c = InStr(dato, "Program")
d = InStr(dato, "E-")
If d <> 0 Then
'Si la coordenada en lectura contiene un "E-", se le
asigna el valor de cero
dato = "0"
End If
If b = 0 And c = 0 And dato <> "" Then
If b = 0 And c = 0 And dato <> "" Then
Coordenadas(0) = dato
CoordenadaDeseadaR1 = Val(Coordenadas(0))
AnguloRotacion = CoordenadaDeseadaR1 - CoordenadaActualR1
CoordenadaActualR1 = CoordenadaDeseadaR1
RotarArticulación1 (AnguloRotacion)
etiqueta1:
If EOF(1) = True Then
Close #1
Open Directorio For Input As #1
For i = 1 To ContadorLineas
Line Input #1, dato
Next
If EOF(1) = True Then
GoTo etiqueta1
End If
End If
End If
If c = 1 Then
Close #1
MonitoreandoForm.hide
Simulador.Show
Exit Sub
End If
Line Input #1, dato
ContadorLineas = ContadorLineas + 1
b = InStr(dato, "ex")
c = InStr(dato, "Program")
d = InStr(dato, "E-")
If d <> 0 Then
'Si la coordenada en lectura contiene un "E-", se le
asigna el valor de cero
dato = "0"
End If
If b = 0 And c = 0 And dato <> "" Then
Coordenadas(1) = dato
CoordenadaDeseadaR2 = Val(Coordenadas(1))
AnguloRotacion = CoordenadaDeseadaR2 - CoordenadaActualR2
CoordenadaActualR2 = CoordenadaDeseadaR2
RotarArticulación2 (AnguloRotacion)
etiqueta2:
If EOF(1) = True Then
Close #1
Open Directorio For Input As #1
For i = 1 To ContadorLineas
Line Input #1, dato
108
Next
If EOF(1) = True Then
GoTo etiqueta2
End If
End If
End If
If c = 1 Then
Close #1
MonitoreandoForm.hide
Simulador.Show
Exit Sub
End If
Line Input #1, dato
ContadorLineas = ContadorLineas + 1
b = InStr(dato, "ex")
c = InStr(dato, "Program")
d = InStr(dato, "E-")
If d <> 0 Then
'Si la coordenada en lectura contiene un "E-", se le
asigna el valor de cero
dato = "0"
End If
If b = 0 And c = 0 And dato <> "" Then
Coordenadas(2) = dato
CoordenadaDeseadaR3 = Val(Coordenadas(2))
AnguloRotacion = CoordenadaDeseadaR3 - CoordenadaActualR3
CoordenadaActualR3 = CoordenadaDeseadaR3
RotarArticulación3 (AnguloRotacion)
etiqueta3:
If EOF(1) = True Then
Close #1
Open Directorio For Input As #1
For i = 1 To ContadorLineas
Line Input #1, dato
Next
If EOF(1) = True Then
GoTo etiqueta3
End If
End If
End If
If c = 1 Then
Close #1
MonitoreandoForm.hide
Simulador.Show
Exit Sub
End If
Line Input #1, dato
ContadorLineas = ContadorLineas + 1
b = InStr(dato, "ex")
c = InStr(dato, "Program")
d = InStr(dato, "E-")
If d <> 0 Then
'Si la coordenada en lectura contiene un "E-", se le
asigna el valor de cero
dato = "0"
End If
If b = 0 And c = 0 And dato <> "" Then
Coordenadas(3) = dato
109
CoordenadaDeseadaR4 = Val(Coordenadas(3))
AnguloRotacion = CoordenadaDeseadaR4 - CoordenadaActualR4
CoordenadaActualR4 = CoordenadaDeseadaR4
RotarArticulación4 (AnguloRotacion)
etiqueta4:
If EOF(1) = True Then
Close #1
Open Directorio For Input As #1
For i = 1 To ContadorLineas
Line Input #1, dato
Next
If EOF(1) = True Then
GoTo etiqueta4
End If
End If
End If
If c = 1 Then
Close #1
MonitoreandoForm.hide
Simulador.Show
Exit Sub
End If
Line Input #1, dato
ContadorLineas = ContadorLineas + 1
b = InStr(dato, "ex")
c = InStr(dato, "Program")
d = InStr(dato, "E-")
If d <> 0 Then
'Si la coordenada en lectura contiene un "E-", se le
asigna el valor de cero
dato = "0"
End If
If b = 0 And c = 0 And dato <> "" Then
Coordenadas(4) = dato
CoordenadaDeseadaR5 = Val(Coordenadas(4))
AnguloRotacion = CoordenadaDeseadaR5 - CoordenadaActualR5
CoordenadaActualR5 = CoordenadaDeseadaR5
RotarArticulación5 (AnguloRotacion)
etiqueta5:
If EOF(1) = True Then
Close #1
Open Directorio For Input As #1
For i = 1 To ContadorLineas
Line Input #1, dato
Next
If EOF(1) = True Then
GoTo etiqueta5
End If
End If
End If
If c = 1 Then
Close #1
MonitoreandoForm.hide
Simulador.Show
Exit Sub
End If
Line Input #1, dato
110
ContadorLineas = ContadorLineas + 1
b = InStr(dato, "ex")
c = InStr(dato, "Program")
d = InStr(dato, "E-")
If d <> 0 Then
'Si la coordenada en lectura contiene un "E-", se le
asigna el valor de cero
dato = "0"
End If
If b = 0 And c = 0 And dato <> "" Then
Coordenadas(5) = dato
CoordenadaDeseadaR6 = Val(Coordenadas(5))
AnguloRotacion = CoordenadaDeseadaR6 - CoordenadaActualR6
CoordenadaActualR6 = CoordenadaDeseadaR6
RotarArticulación6 (AnguloRotacion)
etiqueta6:
If EOF(1) = True Then
Close #1
Open Directorio For Input As #1
For i = 1 To ContadorLineas
Line Input #1, dato
Next
If EOF(1) = True Then
GoTo etiqueta6
End If
End If
End If
If c = 1 Then
Close #1
MonitoreandoForm.hide
Simulador.Show
Exit Sub
End If
End If
If c = 1 Then
Close #1
MonitoreandoForm.hide
Simulador.Show
Exit Sub
End If
Loop
Close #1
MonitoreandoForm.hide
Simulador.Show
End Sub
Private Sub Btn_Cancelar_Monitoreo_Click()
MonitoreandoForm.hide
Simulador.Show
End Sub
3.
Formulario de movimiento del modelo
Private Sub CommandButton1_Click()
If Simulador.Cmb_Posiciones_Modelo.Text = "Ready" Then
GetPosicionReady
End If
If Simulador.Cmb_Posiciones_Modelo.Text = "Zero" Then
GetPosicionZero
111
End If
MoviendoForm.hide
Simulador.Show
End Sub
Private Sub CommandButton2_Click()
MoviendoForm.hide
Simulador.Show
End Sub
4.
Formulario de simulación
Private Sub CommandButton1_Click()
Dim DirectorioTemporal As String
DirectorioTemporal = ThisDrawing.Path + "\" + "temporal.txt"
Open DirectorioTemporal For Output As #1
Print #1, Simulador.Texto.Text
Close #1
Simulacion (DirectorioTemporal)
Kill (DirectorioTemporal)
SimulandoForm.hide
Golpe = False
FueraRango = False
Simulador.Show
End Sub
Private Sub CommandButton2_Click()
SimulandoForm.hide
Simulador.Show
End Sub
5.
Formulario para abrir la vista del modelo
Private Sub CommandButton1_Click()
VistaForm.hide
Simulador.Show
End Sub
6.
Formulario para indicar peligro de colisión del robot
Private Sub BtnAceptar_Click()
PeligroForm.hide
SimulandoForm.hide
MoviendoForm.hide
MonitoreandoForm.hide
Close
End Sub
7.
Formulario principal
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
'coordenadas actuales
'''' Botones opciones ''''
Private Sub Btn_Abrir_Rutina_Click()
Dim NombreArchivo As String
Cuadro_Dialogo_Abrir.ShowOpen
112
If Cuadro_Dialogo_Abrir.FileName <> "" Then
'SI EL ARCHIVO NO EXISTE, ENTONCES SE CREA
NombreArchivo = Cuadro_Dialogo_Abrir.FileName
'Open NombreArchivo For Output As #1
'Close #1
Simulador.Caption = "Simulador - " + NombreArchivo
Open NombreArchivo For Input As #1
Texto.Text = Input$(LOF(1), #1)
Close #1
End If
End Sub
Private Sub Btn_Guardar_Rutina_Click()
'** Procedimiento para guardar rutina desde archivo de texto
Dim NombreArchivo As String
Cuadro_Dialogo_Abrir.ShowSave
If Cuadro_Dialogo_Abrir.FileName <> "" Then
NombreArchivo = Cuadro_Dialogo_Abrir.FileName
Open NombreArchivo For Output As #1
Print #1, Texto.Text
Close #1
Simulador.Caption = "Simulador - " + NombreArchivo
End If
End Sub
**
''''''''''Botones Here y Move''''''''''''
Private Sub Btn_Here_Click()
If Nombre_Punto_Texto.Value <> "" Then
Texto.Text = Texto.Text + "Here " + Nombre_Punto_Texto.Value + Chr$(13) +
Chr$(10)
Texto.SetFocus
End If
End Sub
Private Sub Btn_Move_Click()
If Nombre_Punto_Move_Texto <> "" Then
Texto.Text = Texto.Text + "Move " + Nombre_Punto_Move_Texto.Value + Chr$(13) +
Chr$(10)
Texto.SetFocus
End If
End Sub
Private Sub Btn_Vista_Modelo_Click()
Simulador.hide
VistaForm.Show
End Sub
'''' Botones simular y nueva rutina '''''
Private Sub Simular_Rutina_Click()
Simulador.hide
SimulandoForm.Show
End Sub
''''' Boton Nueva Rutina
Private Sub Btn_Nueva_Rutina_Click()
Simulador.Caption = "Simulador - Nueva Rutina"
Texto.Text = ""
Texto.SetFocus
End Sub
113
'''' Botones Ready, Ciclos For, Finalizar'''''
Private Sub Btn_Ready_Click()
Texto.Text = Texto.Text + "ready" + Chr$(13) + Chr$(10)
Texto.SetFocus
End Sub
Private Sub Btn_Inicio_Ciclo_Click()
Texto.Text = Texto.Text + "For i=1 to " + Repeticiones_For_Texto.Value + Chr$(13)
+ Chr$(10)
Texto.SetFocus
End Sub
Private Sub Btn_Fin_CIclo_Click()
Texto.Text = Texto.Text + "End" + Chr$(13) + Chr$(10)
Texto.SetFocus
End Sub
Private Sub Finalizar_Rutina_Click()
Texto.Text = Texto.Text + "e" + Chr$(13) + Chr$(10)
End Sub
''''' Boton para mover el modelo
'''''
Private Sub Cmb_Posiciones_Modelo_DropButtonClick()
Simulador.Cmb_Posiciones_Modelo.AddItem ("Ready")
Simulador.Cmb_Posiciones_Modelo.AddItem ("Zero")
End Sub
Private Sub Btn_Mover_Modelo_Click()
Simulador.hide
MoviendoForm.Show
End Sub
'''''''''''Botones Registrar''''''''''''
Private Sub Btn_Registar_Cintura_Click()
'' ********************** Procedimiento para guardar rutina desde archivo de
texto
********
'Open "C:\rutinas.txt" For Input As #1
'Do While Not EOF(1)
'
Line Input #1, instruccion 'Leyendo la linea correspondiente
'
Texto.Text = Texto.Text + instruccion + Chr$(13) + Chr$(10)
'Loop
Texto.Text = Texto.Text + "Drive 1," + LTrim(str$(Grados_Cintura_Texto.Value)) +
"," + LTrim(str$(Velocidad_Cintura_Texto.Value)) + Chr$(13) + Chr$(10)
Texto.SetFocus
End Sub
Private Sub Btn_Registar_Brazo_Click()
Texto.Text = Texto.Text + "Drive 2," + LTrim(str$(Grados_Brazo_Texto.Value)) +
"," + LTrim(str$(Velocidad_Brazo_Texto.Value)) + Chr$(13) + Chr$(10)
Texto.SetFocus
End Sub
Private Sub Btn_Registar_Codo_Click()
Texto.Text = Texto.Text + "Drive 3," + LTrim(str$(Grados_Codo_Texto.Value)) + ","
+ LTrim(str$(Velocidad_Codo_Texto.Value)) + Chr$(13) + Chr$(10)
Texto.SetFocus
End Sub
Private Sub Btn_Registar_Antebrazo_Click()
Texto.Text = Texto.Text + "Drive 4," + LTrim(str$(Grados_Antebrazo_Texto.Value))
+ "," + LTrim(str$(Velocidad_Antebrazo_Texto.Value)) + Chr$(13) + Chr$(10)
114
Texto.SetFocus
End Sub
Private Sub Btn_Registar_Muñeca_Click()
Texto.Text = Texto.Text + "Drive 5," + LTrim(str$(Grados_Muñeca_Texto.Value)) +
"," + LTrim(str$(Velocidad_Muñeca_Texto.Value)) + Chr$(13) + Chr$(10)
Texto.SetFocus
End Sub
Private Sub Btn_Registar_Mano_Click()
Texto.Text = Texto.Text + "Drive 6," + LTrim(str$(Grados_Mano_Texto.Value)) + ","
+ LTrim(str$(Velocidad_Mano_Texto.Value)) + Chr$(13) + Chr$(10)
Texto.SetFocus
End Sub
'''''''''''Cuadros de texto de grados (Barras de desplazamiento)''''''''''''
Private Sub Grados_Cintura_Scroll()
Grados_Cintura_Texto.Value = str$(Grados_Cintura.Value)
End Sub
Private Sub Grados_Cintura_Change()
Grados_Cintura_Texto.Value = str$(Grados_Cintura.Value)
End Sub
Private Sub Grados_Brazo_Scroll()
Grados_Brazo_Texto.Value = str$(Grados_Brazo.Value)
End Sub
Private Sub Grados_Brazo_Change()
Grados_Brazo_Texto.Value = str$(Grados_Brazo.Value)
End Sub
Private Sub Grados_Codo_Scroll()
Grados_Codo_Texto.Value = str$(Grados_Codo.Value)
End Sub
Private Sub Grados_Codo_Change()
Grados_Codo_Texto.Value = str$(Grados_Codo.Value)
End Sub
Private Sub Grados_Antebrazo_Scroll()
Grados_Antebrazo_Texto.Value = str$(Grados_Antebrazo.Value)
End Sub
Private Sub Grados_Antebrazo_Change()
Grados_Antebrazo_Texto.Value = str$(Grados_Antebrazo.Value)
End Sub
Private Sub Grados_Muñeca_Scroll()
Grados_Muñeca_Texto.Value = str$(Grados_Muñeca.Value)
End Sub
Private Sub Grados_Muñeca_Change()
Grados_Muñeca_Texto.Value = str$(Grados_Muñeca.Value)
End Sub
Private Sub Grados_Mano_Scroll()
Grados_Mano_Texto.Value = str$(Grados_Mano.Value)
End Sub
Private Sub Grados_Mano_Change()
Grados_Mano_Texto.Value = str$(Grados_Mano.Value)
End Sub
'''''''''''Cuadros de texto de velocidad (Barras de desplazamiento)''''''''''''
Private Sub Velocidad_Cintura_Scroll()
Velocidad_Cintura_Texto.Value = str$(Velocidad_Cintura.Value)
End Sub
Private Sub Velocidad_Cintura_Change()
Velocidad_Cintura_Texto.Value = str$(Velocidad_Cintura.Value)
End Sub
115
Private Sub Velocidad_Brazo_Scroll()
Velocidad_Brazo_Texto.Value = str$(Velocidad_Brazo.Value)
End Sub
Private Sub Velocidad_Brazo_Change()
Velocidad_Brazo_Texto.Value = str$(Velocidad_Brazo.Value)
End Sub
Private Sub Velocidad_Codo_Scroll()
Velocidad_Codo_Texto.Value = str$(Velocidad_Codo.Value)
End Sub
Private Sub Velocidad_Codo_Change()
Velocidad_Codo_Texto.Value = str$(Velocidad_Codo.Value)
End Sub
Private Sub Velocidad_Antebrazo_Scroll()
Velocidad_Antebrazo_Texto.Value = str$(Velocidad_Antebrazo.Value)
End Sub
Private Sub Velocidad_Antebrazo_Change()
Velocidad_Antebrazo_Texto.Value = str$(Velocidad_Antebrazo.Value)
End Sub
Private Sub Velocidad_Muñeca_Scroll()
Velocidad_Muñeca_Texto.Value = str$(Velocidad_Muñeca.Value)
End Sub
Private Sub Velocidad_Muñeca_Change()
Velocidad_Muñeca_Texto.Value = str$(Velocidad_Muñeca.Value)
End Sub
Private Sub Velocidad_Mano_Scroll()
Velocidad_Mano_Texto.Value = str$(Velocidad_Mano.Value)
End Sub
Private Sub Velocidad_Mano_Change()
Velocidad_Mano_Texto.Value = str$(Velocidad_Mano.Value)
End Sub
' ****** Modo de monitoreo *******
Private Sub BtnMonitoreo_Click()
Simulador.hide
MonitoreandoForm.Show
End Sub
116
Apéndice 02: Copérnico modificado
unit Unidad_Copernico;
interface
uses
// Declaración de librerías a utilizar
Windows, Messages, SysUtils, Classes, Graphics,
Controls, Forms, Dialogs,
ExtCtrls, ScktComp, Menus, StdCtrls, ComCtrls,
ShellApi,
Tabnotbk, jpeg, OleCtrls, NetMeetingLib_TLB,
Buttons;
type
// Declaración todos los objetos a utilizar y su clase
(componentes a utilizar)
TCopernico = class(TForm)
Escribir: TMemo;
Menu: TMainMenu;
Archivo1: TMenuItem;
Llamar: TMenuItem;
Desconectar: TMenuItem;
N1: TMenuItem;
Salir: TMenuItem;
ClientSocket: TClientSocket;
ServerSocket: TServerSocket;
Leer: TMemo;
BarraEstado: TStatusBar;
RutinasBtn: TMenuItem;
SendBtn: TMenuItem;
OpenDialog: TOpenDialog;
ActiveBtn: TMenuItem;
LoadBtn: TMenuItem;
AbourtBtn: TMenuItem;
Label1: TLabel;
Video: TTabbedNotebook;
GroupBox6: TGroupBox;
Label42: TLabel;
Call_NettMetting: TButton;
ConsolaGnal: TTabbedNotebook;
GroupBox5: TGroupBox;
POWER: TButton;
OFF: TButton;
GroupBox4: TGroupBox;
Label37: TLabel;
Label38: TLabel;
Label39: TLabel;
Label40: TLabel;
Label41: TLabel;
Load_Calibrate: TButton;
Ex_Calibrate: TButton;
GroupBox1: TGroupBox;
DisDry: TButton;
EnDry: TButton;
GroupBox3: TGroupBox;
Label20: TLabel;
Label21: TLabel;
SpeedEdit: TEdit;
Speed: TButton;
GroupBox2: TGroupBox;
DoReady: TButton;
FileEdit: TEdit;
Edit_Routine: TButton;
Load: TButton;
Execute: TButton;
Label2: TLabel;
Comandos_Drive: TGroupBox;
Box4: TGroupBox;
Label4: TLabel;
Label30: TLabel;
Edit1: TEdit;
Joint1: TScrollBar;
Btn_cintura: TButton;
Speed_J1: TScrollBar;
Edit7: TEdit;
Box5: TGroupBox;
Label5: TLabel;
Label31: TLabel;
Joint2: TScrollBar;
Edit2: TEdit;
Btn_brazo: TButton;
Speed_J2: TScrollBar;
Edit8: TEdit;
Box6: TGroupBox;
Label6: TLabel;
Label32: TLabel;
Edit3: TEdit;
Joint3: TScrollBar;
Btn_codo: TButton;
Speed_J3: TScrollBar;
Edit9: TEdit;
Box7: TGroupBox;
Label7: TLabel;
Label33: TLabel;
Joint4: TScrollBar;
117
Edit4: TEdit;
Btn_antebrazo: TButton;
Speed_J4: TScrollBar;
Edit10: TEdit;
Box8: TGroupBox;
Label8: TLabel;
Label34: TLabel;
Edit5: TEdit;
Joint5: TScrollBar;
Btn_muneca: TButton;
Speed_J5: TScrollBar;
Edit11: TEdit;
Box9: TGroupBox;
Label29: TLabel;
Label35: TLabel;
Joint6: TScrollBar;
Edit6: TEdit;
Btn_mano: TButton;
Speed_J6: TScrollBar;
Edit12: TEdit;
MOVE: TGroupBox;
Label27: TLabel;
PointMove: TEdit;
Mover: TButton;
NetMeeting1: TNetMeeting;
Label3: TLabel;
Read_Posicion: TGroupBox;
Button1: TButton;
Directorio: TGroupBox;
VerArchivos: TButton;
Posicion: TGroupBox;
Ready: TButton;
Bevel1: TBevel;
Image1: TImage;
GroupBox15: TGroupBox;
Label65: TLabel;
Subrutina: TEdit;
CALL: TButton;
GroupBox14: TGroupBox;
Label64: TLabel;
Text_Repeticiones: TEdit;
Inicio_ciclo: TButton;
Fin_ciclo: TButton;
Bevel2: TBevel;
Abortar: TBitBtn;
Button2: TButton;
GroupBox7: TGroupBox;
FinRutina: TBitBtn;
Panel1: TPanel;
New_Routine: TButton;
SalvarUnidad: TComboBox;
Label9: TLabel;
DefinirUnidad: TButton;
procedure Coordenada(Sender: TObject);
procedure LlamarClick(Sender: TObject);
procedure DesconectarClick(Sender: TObject);
procedure SalirClick(Sender: TObject);
procedure ServerSocketAccept(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocketConnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocketClientDisconnect(Sender:
TObject;
Socket: TCustomWinSocket);
procedure ServerSocketClientConnect(Sender:
TObject;
Socket: TCustomWinSocket);
procedure ClientSocketDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocketRead(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocketError(Sender: TObject;
Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
procedure ServerSocketClientError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent:
TErrorEvent;
var ErrorCode: Integer);
procedure SendBtnClick(Sender: TObject);
procedure ActiveBtnClick(Sender: TObject);
procedure LoadBtnClick(Sender: TObject);
procedure AbourtBtnClick(Sender: TObject);
procedure LeerKeyDown(Sender: TObject; var Key:
Word;
Shift: TShiftState);
procedure Call_NettMettingClick(Sender: TObject);
procedure POWERClick(Sender: TObject);
procedure OFFClick(Sender: TObject);
procedure Load_CalibrateClick(Sender: TObject);
procedure Ex_CalibrateClick(Sender: TObject);
procedure DisDryClick(Sender: TObject);
procedure EnDryClick(Sender: TObject);
procedure VerArchivosClick(Sender: TObject);
procedure SpeedClick(Sender: TObject);
procedure DoReadyClick(Sender: TObject);
procedure New_RoutineClick(Sender: TObject);
procedure Edit_RoutineClick(Sender: TObject);
procedure Joint1Change(Sender: TObject);
procedure Joint2Change(Sender: TObject);
procedure Joint3Change(Sender: TObject);
procedure Joint4Change(Sender: TObject);
procedure Joint5Change(Sender: TObject);
procedure Joint6Change(Sender: TObject);
procedure Speed_J1Change(Sender: TObject);
procedure Speed_J2Change(Sender: TObject);
procedure Speed_J3Change(Sender: TObject);
procedure Speed_J4Change(Sender: TObject);
procedure Speed_J5Change(Sender: TObject);
procedure Speed_J6Change(Sender: TObject);
procedure Btn_cinturaClick(Sender: TObject);
procedure Btn_brazoClick(Sender: TObject);
procedure Btn_codoClick(Sender: TObject);
118
procedure Btn_antebrazoClick(Sender: TObject);
procedure Btn_munecaClick(Sender: TObject);
procedure Btn_manoClick(Sender: TObject);
procedure MoverClick(Sender: TObject);
procedure The_endClick(Sender: TObject);
procedure LoadClick(Sender: TObject);
procedure ExecuteClick(Sender: TObject);
procedure ReadyClick(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Inicio_cicloClick(Sender: TObject);
procedure Fin_cicloClick(Sender: TObject);
procedure CALLClick(Sender: TObject);
procedure AbortarClick(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FinRutinaClick(Sender: TObject);
procedure DefinirUnidadClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
Protected
AceptarConexion: Boolean;
end;
var
Copernico: TCopernico;
Direccion: String;
i, Inicio, Final: Integer;
Bandera : Integer;
implementation // Programa a implementarse o
ejecutarse
uses Unidad_Principal;
{$R *.DFM}
////////////////////////////////////////////////////////////////////////////////
////////////////////// PROCEDIMIENTOS MENU
PRINCIPAL ///////////////////////////
procedure TCopernico.ActiveBtnClick(Sender:
TObject);
begin
ServerSocket.Active:=True;
ActiveBtn.Enabled:=False;
Llamar.Enabled:=False;
Desconectar.Enabled:=True;
Leer.ReadOnly:=False;
Leer.Lines.Clear;
Leer.Color:=clWhite;
ConsolaGnal.Enabled:=True;
Video.Enabled:=True;
end;
procedure TCopernico.LlamarClick(Sender: TObject);
Var
MiFichero : TextFile;
begin
Direccion:='163.178.124.183';
ActiveBtn.Enabled:=False;
Llamar.Enabled:=False;
Desconectar.Enabled:=True;
LoadBtn.Enabled:=True;
ConsolaGnal.Enabled:=True;
Video.Enabled:=True;
ServerSocket.Active:=True; //Activar Sockect en
modo Servidor
if ClientSocket.Active then //Activar Sockect en
modo Cliente
ClientSocket.Active:=False;
if InputQuery('Conexión','Comunicarse con:',
Direccion)then
if Length (Direccion)>0 then
begin
ClientSocket.Host:=Direccion;
ClientSocket.Active:=True;
Leer.ReadOnly:=False;
Leer.Lines.Clear;
Leer.Color:=clWhite;
end;
AssignFile (MiFichero,'C:\Documents and Settings\All
Users\Coordenadas.txt');
Rewrite (MiFichero); //Rewrite lo crea si no existe y si
existe le borra el contenido
CloseFile (MiFichero);// Se cierra el archivo
end;
procedure TCopernico.DesconectarClick(Sender:
TObject);
begin
ConsolaGnal.Enabled:=False;
Video.Enabled:=False;
ActiveBtn.Enabled:=True;
Llamar.Enabled:=True;
Desconectar.Enabled:=False;
LoadBtn.Enabled:=False;
SendBtn.Enabled:=False;
AbourtBtn.Enabled:=False;
Leer.Color:=clBtnFace;
Leer.Lines.Clear;
Leer.Enabled:=True;
Escribir.Lines.Clear;
ServerSocket.Active:=False;
ClientSocket.Active:=False;
BarraEstado.Panels[0].Text:='Desconectado';
end;
procedure TCopernico.SalirClick(Sender: TObject);
begin
ServerSocket.Active:=False;
119
ClientSocket.Active:=False;
Copernico.Close;
end;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
procedure TCopernico.ServerSocketAccept(Sender:
TObject;
Socket: TCustomWinSocket);
begin
AceptarConexion:=True;
end;
////////////////////////////////////////////////////////////////////////////////
////////////////////// PROCEDIMIENTOS CUADROS DE
MENSAJES///////////////////////
procedure TCopernico.ClientSocketConnect(Sender:
TObject;
Socket: TCustomWinSocket);
begin
BarraEstado.Panels[0].Text:='Enlazado con:'+
Socket.RemoteHost;
end;
procedure
TCopernico.ServerSocketClientDisconnect(Sender:
TObject;
Socket: TCustomWinSocket);
begin
BarraEstado.Panels[0].Text:='Finalizó comunicación
con:'
+ Socket.RemoteAddress + ', esperando nuevo cliente';
end;
procedure
TCopernico.ServerSocketClientConnect(Sender:
TObject;
Socket: TCustomWinSocket);
begin
BarraEstado.Panels[0].Text:='Enlazado con:' +
Socket.RemoteAddress;
end;
procedure TCopernico.ClientSocketDisconnect(Sender:
TObject;
Socket: TCustomWinSocket);
begin
BarraEstado.Panels[0].Text:='Finalizó comunicación
con:'
+ Socket.RemoteAddress + ', el servidor ha salido de
servicio';
end;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
{Lectura y envió de datos}
procedure TCopernico.ClientSocketRead(Sender:
TObject;
Socket: TCustomWinSocket);
begin
// Lee datos como cliente cuando esta comunicándose
con un servidor
Leer.Font.Color:=clBlue;
Leer.Lines.Add(Socket.ReceiveText);
Leer.Font.Color:=clBlack;
end;
procedure TCopernico.ServerSocketClientRead(Sender:
TObject;
Socket: TCustomWinSocket);
begin
// Lee datos como servidor cuando algun cliente desea
comunicarse
Leer.Font.Color:=clBlue;
Leer.Lines.Add(Socket.ReceiveText);
Leer.Font.Color:=clBlack;
end;
procedure TCopernico.LeerKeyDown(Sender: TObject;
var Key: Word;
Shift: TShiftState);
begin
If key=VK_Return then
//Envía datos como servidor comunicandose al
cliente conectado
if AceptarConexion then
ServerSocket.Socket.Connections[0].SendText
(Leer.Lines[Leer.Lines.Count-1])
else
//Envía datos como cliente esperando respuesta del
servidor
ClientSocket.Socket.SendText
(Leer.Lines[Leer.Lines.Count-1])
end;
////////////////////////////////////////////////////////////////////////////////
////////////////////////// MENSAJES DE ERROR
///////////////////////////////////
procedure TCopernico.ClientSocketError(Sender:
TObject;
Socket: TCustomWinSocket; ErrorEvent:
TErrorEvent;
var ErrorCode: Integer);
begin
Leer.Lines.Add('Error al conectar con:' + Direccion);
ErrorCode:=0;
ShowMessage('La comunicación no es posible por el
momento');
120
end;
end;
procedure TCopernico.ServerSocketClientError(Sender:
TObject;
Socket: TCustomWinSocket; ErrorEvent:
TErrorEvent;
var ErrorCode: Integer);
begin
Leer.Lines.Add('Imposible comunicarse por el
momento con' + Direccion);
ErrorCode:=0;
ShowMessage('Error en la comunicación ');
end;
// Energizar
////////////////////////////////////////////////////////////////////////////////
////////////////////////////// ENVIO DE RUTINAS
////////////////////////////////
procedure TCopernico.LoadBtnClick(Sender: TObject);
begin
SendBtn.Enabled:=True;
AbourtBtn.Enabled:=True;
Escribir.Clear;
OpenDialog.Execute;
Escribir.Lines.LoadFromFile(OpenDialog.FileName);
Leer.Lines.LoadFromFile(OpenDialog.FileName);
end;
procedure TCopernico.SendBtnClick(Sender: TObject);
begin
SendBtn.Enabled:=False;
AbourtBtn.Enabled:=False;
if AceptarConexion then
ServerSocket.Socket.SendText(Escribir.Lines.Text)
else
ClientSocket.Socket.SendText(Escribir.Lines.Text)
end;
procedure TCopernico.AbourtBtnClick(Sender:
TObject);
begin
SendBtn.Enabled:=False;
AbourtBtn.Enabled:=False;
Escribir.Clear;
end;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////// BOTONERA
/////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
{MENU INICIO}
procedure TCopernico.Call_NettMettingClick(Sender:
TObject);
begin
ShellExecute(Self.handle,'Open','C:\CONF.EXE','',nil,
SW_SHOWNORMAL);
procedure TCopernico.POWERClick(Sender: TObject);
begin
Leer.Lines.Add('en po');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
procedure TCopernico.OFFClick(Sender: TObject);
begin
Leer.Lines.Add('dis po');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
// Modo de simulación
procedure TCopernico.DisDryClick(Sender: TObject);
begin
Leer.Lines.Add('dis dry');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
procedure TCopernico.EnDryClick(Sender: TObject);
begin
Leer.Lines.Add('en dry');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
// Ver archivos
procedure TCopernico.VerArchivosClick(Sender:
TObject);
begin
Leer.Lines.Add('fdir');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
// Velocidad
procedure TCopernico.SpeedClick(Sender: TObject);
begin
Leer.Lines.Add('sp '+SpeedEdit.Text);
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
// Posición de modo de lectura
procedure TCopernico.DoReadyClick(Sender:
TObject);
121
begin
Leer.Lines.Add('do ready');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
begin
Leer.Lines.Add('def d='+SalvarUnidad.Text);
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
// Lectura de la ubicación actual
procedure TCopernico.New_RoutineClick(Sender:
TObject);
begin
Leer.Lines.Add('store '+FileEdit.Text+'.V2');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
procedure TCopernico.Button1Click(Sender: TObject);
begin
Leer.Lines.Add('where');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
// Calibrar rutinas
procedure TCopernico.Load_CalibrateClick(Sender:
TObject);
begin
Leer.Lines.Add('load c:\util_4e3\spec.v2');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
procedure TCopernico.Ex_CalibrateClick(Sender:
TObject);
begin
Leer.Lines.Add('ex 1 a.spec');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
{Crear o editar rutinas}
procedure TCopernico.LoadClick(Sender: TObject);
begin
Leer.Lines.Add('load '+FileEdit.Text);
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
procedure TCopernico.ExecuteClick(Sender: TObject);
Var
MiFichero : TextFile;
begin
Leer.Lines.Add('ex '+ FileEdit.Text);
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
AssignFile (MiFichero,'C:\Documents and Settings\All
Users\Coordenadas.txt');
Rewrite (MiFichero);
WriteLn(MiFichero, Leer.Lines[Leer.Lines.Count-2]);
CloseFile (MiFichero);// Se cierra el archivo
end;
procedure TCopernico.DefinirUnidadClick(Sender:
TObject);
procedure TCopernico.Edit_RoutineClick(Sender:
TObject);
begin
Leer.Lines.Add('Edit '+FileEdit.Text);
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
procedure TCopernico.AbortarClick(Sender: TObject);
begin
Leer.Lines.Add('Abort' );
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
procedure TCopernico.Button2Click(Sender: TObject);
begin
Leer.Lines.Add('Flist '+FileEdit.Text );
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
procedure TCopernico.Joint1Change(Sender: TObject);
var
I: integer;
S : string;
begin
I := Joint1.Position;
Str(I,S);
Edit1.text:= S;
end;
procedure TCopernico.Joint2Change(Sender: TObject);
var
I: integer;
S : string;
begin
I := Joint2.Position;
Str(I,S);
Edit2.text:= S;
end;
procedure TCopernico.Joint3Change(Sender: TObject);
122
var
I: integer;
S : string;
begin
I := Joint3.Position;
Str(I,S);
Edit3.text:= S;
end;
procedure TCopernico.Joint4Change(Sender: TObject);
var
I: integer;
S : string;
begin
I := Joint4.Position;
Str(I,S);
Edit4.text:= S;
end;
procedure TCopernico.Joint5Change(Sender: TObject);
var
I: integer;
S : string;
begin
I := Joint5.Position;
Str(I,S);
Edit5.text:= S;
end;
procedure TCopernico.Joint6Change(Sender: TObject);
var
I: integer;
S : string;
begin
I := Joint6.Position;
Str(I,S);
Edit6.text:= S;
end;
procedure TCopernico.Speed_J1Change(Sender:
TObject);
var
I: integer;
S : string;
begin
I := Speed_J1.Position;
Str(I,S);
Edit7.text:= S;
end;
procedure TCopernico.Speed_J2Change(Sender:
TObject);
var
I: integer;
S : string;
begin
I := Speed_J2.Position;
Str(I,S);
Edit8.text:= S;
end;
procedure TCopernico.Speed_J3Change(Sender:
TObject);
var
I: integer;
S : string;
begin
I := Speed_J3.Position;
Str(I,S);
Edit9.text:= S;
end;
procedure TCopernico.Speed_J4Change(Sender:
TObject);
var
I: integer;
S : string;
begin
I := Speed_J4.Position;
Str(I,S);
Edit10.text:= S;
end;
procedure TCopernico.Speed_J5Change(Sender:
TObject);
var
I: integer;
S : string;
begin
I := Speed_J5.Position;
Str(I,S);
Edit11.text:= S;
end;
procedure TCopernico.Speed_J6Change(Sender:
TObject);
var
I: integer;
S : string;
begin
I := Speed_J6.Position;
Str(I,S);
Edit12.text:= S;
end;
///*******************************************
*******************************//
// Al hacer click en los siguientes botones se agrega un
comando de movimeinto
// en la rutina que se esta creando
// Ademas de la instruccion de moviiento se agregan
ocho instrucciones que
// permiten extraer las coordenadas actuales y las
muestran en la pantalla
123
// Here #p crea un punto de precision de la posici{on
actual, ese punto consta de
// 6 valores que corresponden a los 6 valores de los
angulos de las articulaciones
// Decompose A[] = #p guarda esos 6 valores en un
vector
// Type A[i] con i de 0 a 5 muestra an el TMemo Leer
cada uno de estos 6 valores,
// uno por linea
// Ademas se utiliza un sleep para darle tiempo al bufer
de que mande los datos
procedure TCopernico.Btn_cinturaClick(Sender:
TObject);
begin
Leer.Lines.Add('Drive 1,'+Edit1.Text+','+Edit7.Text);
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('HERE #P');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('DECOMPOSE A[] = #P');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[0]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[1]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[2]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[3]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[4]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
124
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[5]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
procedure TCopernico.Btn_brazoClick(Sender:
TObject);
begin
Leer.Lines.Add('Drive 2,'+Edit2.Text+','+Edit8.Text);
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('HERE #P');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('DECOMPOSE A[] = #P');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[0]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[1]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[2]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[3]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[4]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
125
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[5]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
procedure TCopernico.Btn_codoClick(Sender:
TObject);
begin
Leer.Lines.Add('Drive 3,'+Edit3.Text+','+Edit9.Text);
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('HERE #P');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('DECOMPOSE A[] = #P');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[0]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[1]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[2]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[3]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[4]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
126
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[5]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
procedure TCopernico.Btn_antebrazoClick(Sender:
TObject);
begin
Leer.Lines.Add('Drive 4,'+Edit4.Text+','+Edit10.Text);
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('HERE #P');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('DECOMPOSE A[] = #P');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[0]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[1]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[2]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[3]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[4]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
127
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[5]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
procedure TCopernico.Btn_munecaClick(Sender:
TObject);
begin
Leer.Lines.Add('Drive 5,'+Edit5.Text+','+Edit11.Text);
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('HERE #P');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('DECOMPOSE A[] = #P');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[0]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[1]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[2]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[3]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[4]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
128
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[5]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
procedure TCopernico.Btn_manoClick(Sender:
TObject);
begin
Leer.Lines.Add('Drive 6,'+Edit6.Text+','+Edit12.Text);
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('HERE #P');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('DECOMPOSE A[] = #P');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[0]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[1]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[2]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[3]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[4]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
129
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[5]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
procedure TCopernico.MoverClick(Sender: TObject);
begin
Leer.Lines.Add('move '+PointMove.Text);
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('HERE #P');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('DECOMPOSE A[] = #P');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[0]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[1]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[2]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[3]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[4]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
130
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[5]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
procedure TCopernico.The_endClick(Sender: TObject);
begin
Leer.Lines.Add('e');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
{Envia el robot a la posición de inicio o lectura en una
rutina}
procedure TCopernico.ReadyClick(Sender: TObject);
begin
Leer.Lines.Add('ready');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('HERE #P');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('DECOMPOSE A[] = #P');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[0]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[1]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[2]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[3]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[4]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
131
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[5]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
//********************************************
******************************////
{Realización de ciclos}
procedure TCopernico.Inicio_cicloClick(Sender:
TObject);
begin
Leer.Lines.Add('For i=1 to '+Text_Repeticiones.Text);
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
procedure TCopernico.Fin_cicloClick(Sender:
TObject);
begin
Leer.Lines.Add('End');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
{Llamado de ciclos}
procedure TCopernico.CALLClick(Sender: TObject);
begin
Leer.Lines.Add('Call '+ Subrutina.Text);
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
procedure TCopernico.FinRutinaClick(Sender:
TObject);
begin
Leer.Lines.Add('HERE #P');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('DECOMPOSE A[] = #P');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[0]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[1]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[2]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
132
Leer.Lines.Add('TYPE A[3]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[4]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('FOR i = 1 TO 15');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('WAIT');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('END');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('TYPE A[5]');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
Sleep(400);
Leer.Lines.Add('e');
ClientSocket.Socket.SendText(Leer.Lines[Leer.Lines.C
ount-1]);
end;
procedure TCopernico.Coordenada(Sender: TObject);
Var
MiFichero : TextFile;
begin
// Permite anexar los valores de coordenadas en el
archivo de texto creado
AssignFile (MiFichero,'C:\Documents and Settings\All
Users\Coordenadas.txt');
Append (MiFichero);
WriteLn(MiFichero, Leer.Lines[Leer.Lines.Count-2]);
CloseFile (MiFichero);// Se cierra el archivo
end;
end.
133
ANEXOS
Descargar