Control de Tiempo Real estricto en un robot móvil

Anuncio
Proyecto Fin de Carrera
Ingeniería Informática
Control de Tiempo Real estricto en un robot móvil
basado en MaRTE OS
Francisco Javier Feijoo Cano
Director: José Luis Villarroel Salcedo
Departamento de Informática e Ingeniería de Sistemas
Centro Politécnico Superior
Universidad de Zaragoza
Diciembre 2007
Mi agradecimiento a la gente del laboratorio de robótica que han hecho posible
la realización del presente trabajo en especial a Danilo Tardioli, porque con
sus conocimientos y su colaboración, me ayudó a seguir hacia delante en los
momentos más difíciles.
Agradecer también la desinteresada colaboración de Daniel Sangorrin, que desde la Universidad de Cantabria me prestó su ayuda y su tiempo en diferentes
partes del proyecto.
Índice general
Índice de guras
9
Índice de cuadros
10
1. Introducción
11
1.1.
Objetivo y alcance
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11
1.2.
Contexto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
1.3.
Diferentes objetivos de los sistemas operativos . . . . . . . . . . . . . . . .
12
1.3.1.
Sistema operativo de propósito general
. . . . . . . . . . . . . . . .
12
1.3.2.
Sistema operativo de tiempo real
. . . . . . . . . . . . . . . . . . .
13
1.3.3.
Elección del sistema
. . . . . . . . . . . . . . . . . . . . . . . . . .
14
1.4.
Necesidad de control temporal en un robot móvil
. . . . . . . . . . . . . .
14
1.5.
Estructura de la memoria
. . . . . . . . . . . . . . . . . . . . . . . . . . .
15
2. El sistema operativo MaRTE OS
16
2.1.
Características
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
2.2.
Trabajando con MaRTE OS . . . . . . . . . . . . . . . . . . . . . . . . . .
18
3. El robot móvil Pioneer
3.1.
3.2.
20
Arquitectura del sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
3.1.1.
Sensores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21
3.1.2.
Actuadores
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22
3.1.3.
Mecanismo de comunicación . . . . . . . . . . . . . . . . . . . . . .
22
Método de trabajo actual con el robot
. . . . . . . . . . . . . . . . . . . .
4. Integración de los sensores en MaRTE
22
24
4.1.
Análisis general . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
24
4.2.
Diseño arquitectural
24
4.3.
4.4.
4.5.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . .
25
4.3.1.
Microcontrolador y P2OS
Análisis
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
4.3.2.
Diseño . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
4.4.1.
Láser SICK LMS
Análisis
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
4.4.2.
Diseño . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
28
Comunicación inalámbrica
. . . . . . . . . . . . . . . . . . . . . . . . . . .
5
30
4.6.
4.7.
4.5.1.
Análisis
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
30
4.5.2.
Diseño . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
31
GPS Novatel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
32
4.6.1.
Análisis
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
32
4.6.2.
Diseño . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
33
Implementación y pruebas
. . . . . . . . . . . . . . . . . . . . . . . . . . .
5. Caracterización temporal completa del sistema
33
34
5.1.
Medir el tiempo de cómputo en MaRTE
. . . . . . . . . . . . . . . . . . .
34
5.2.
Dependencia de la línea serie . . . . . . . . . . . . . . . . . . . . . . . . . .
35
6. Pruebas realizadas y resultados
6.1.
37
Navegación autónoma y tiempo real estricto
6.1.1.
. . . . . . . . . . . . . . . . .
37
Esquema de tareas y cumplimiento de plazos . . . . . . . . . . . . .
38
6.2.
Comunicaciones en tiempo real
. . . . . . . . . . . . . . . . . . . . . . . .
41
6.3.
Resultados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
42
7. Conclusiones y trabajos futuros
44
7.1.
Conclusiones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
44
7.2.
Dicultades encontradas
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
45
7.3.
Trabajos futuros
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
45
Bibliografía
46
A. Fases del proyecto y diagrama de Gantt
48
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
48
A.2. Diagrama de Gantt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
49
A.1. Hitos temporales
B. Estudio sobre sistemas operativos de tiempo real
50
B.1. Arquitectura de un SO de tiempo real . . . . . . . . . . . . . . . . . . . . .
B.1.1. Arquitectura de un SO de propósito general
50
. . . . . . . . . . . . .
50
B.1.2. Clases de tiempo real . . . . . . . . . . . . . . . . . . . . . . . . . .
51
B.1.3. Características de rendimiento . . . . . . . . . . . . . . . . . . . . .
51
B.1.4. Arquitectura de un SO de tiempo real
. . . . . . . . . . . . . . . .
52
. . . . . . . . . . . . . . . . . . . . . . . .
55
B.1.5. Rendimiento del sistema
B.2. Algunos de los SO de tiempo real más usados
. . . . . . . . . . . . . . . .
55
B.2.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
55
B.2.2. ADEOS (Adaptative Domain Environment Operating Systems ) . . .
56
B.2.3. RTLinux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
58
B.2.4. MaRTE
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
60
B.2.5. VxWorks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
62
C. P2OS: El Sistema Operativo del microcontrolador.
C.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
C.1.1. Especicaciones técnicas
. . . . . . . . . . . . . . . . . . . . . . . .
C.2. El Sistema Operativo del robot. P2OS
. . . . . . . . . . . . . . . . . . . .
64
64
64
65
ÍNDICE GENERAL
7
C.2.1. Conexión Cliente-Servidor
. . . . . . . . . . . . . . . . . . . . . . .
65
C.2.2. Comandos de movimiento
. . . . . . . . . . . . . . . . . . . . . . .
66
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
67
C.2.4. Emergencias y paradas . . . . . . . . . . . . . . . . . . . . . . . . .
67
C.2.3. Sonar
D. El láser SICK LMS
68
D.1. Información básica sobre el láser . . . . . . . . . . . . . . . . . . . . . . . .
68
D.2. Software. Mecanismo de comunicación
. . . . . . . . . . . . . . . . . . . .
69
D.2.1. Esquema de funcionamiento para la comunicación con LMS . . . . .
69
D.2.2. Establecer la comunicación con LMS
. . . . . . . . . . . . . . . . .
69
D.2.3. Valores por defecto del LMS . . . . . . . . . . . . . . . . . . . . . .
70
D.2.4. Cambiar la velocidad de transmisión
. . . . . . . . . . . . . . . . .
70
. . . . . . . . . . . . . . . . . . . .
71
D.2.5. Cambiar la resolución del LMS
D.2.6. Cambiar la unidad de medida en LMS
. . . . . . . . . . . . . . . .
D.2.7. Empezar con la salida continua de datos desde el LMS
72
. . . . . . .
72
D.2.8. Interpretación de los datos recibidos . . . . . . . . . . . . . . . . . .
73
D.2.9. Detención de la salida continua de datos
. . . . . . . . . . . . . . .
74
D.2.10. Formato de la cadena de datos de salida
. . . . . . . . . . . . . . .
74
D.2.11. Información del byte de estado (status byte) . . . . . . . . . . . . .
75
E. Trabajando con MaRTE OS
76
E.1. Instalación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
76
E.2. Creación de nuevos drivers . . . . . . . . . . . . . . . . . . . . . . . . . . .
76
E.3. Arrancar en red con MaRTE OS y el robot . . . . . . . . . . . . . . . . . .
77
E.3.1.
Elementos hardware
. . . . . . . . . . . . . . . . . . . . . . . . . .
77
E.3.2.
Elementos software . . . . . . . . . . . . . . . . . . . . . . . . . . .
77
E.3.3.
Conguración del servidor
. . . . . . . . . . . . . . . . . . . . . . .
77
E.3.4.
Conguración del host
. . . . . . . . . . . . . . . . . . . . . . . . .
79
E.3.5.
Método de trabajo
. . . . . . . . . . . . . . . . . . . . . . . . . . .
79
F. Manual de usuario y API
F.1. Manual de usuario
80
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
F.2. Funciones en lenguaje C
80
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
83
F.2.1.
P2OS
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
83
F.2.2.
Láser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
84
F.2.3.
GPS
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
84
F.2.4.
Comunicación inalámbrica . . . . . . . . . . . . . . . . . . . . . . .
85
F.3. Funciones en lenguaje Ada . . . . . . . . . . . . . . . . . . . . . . . . . . .
86
F.3.1.
P2OS
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
86
F.3.2.
Láser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
87
F.3.3.
GPS
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
87
F.3.4.
Comunicación inalámbrica . . . . . . . . . . . . . . . . . . . . . . .
88
F.4. Consideración nal
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
88
G. Interfaz de programación entre Ada y C
89
G.1. Visibilidad global de los datos . . . . . . . . . . . . . . . . . . . . . . . . .
90
G.2. Visibilidad global de funciones . . . . . . . . . . . . . . . . . . . . . . . . .
93
G.3. Ejecución del programa . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
94
G.3.1. Inicialización
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
94
G.3.2. Captura de excepciones . . . . . . . . . . . . . . . . . . . . . . . . .
94
G.4. Interfaz de funciones
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
95
Índice de guras
2.1.
Arquitectura de MaRTE OS para aplicaciones ADA y C
2.2.
Entorno de desarrollo del proyecto.
. . . . . . . . . .
18
. . . . . . . . . . . . . . . . . . . . . .
19
3.1.
Robot Pioneer 3-AT.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
3.2.
Los dispositivos más importantes del robot y sus conexiones. . . . . . . . .
21
4.1.
Diseño del driver P2OS
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
4.2.
Esquema de funcionamiento del puerto serie. . . . . . . . . . . . . . . . . .
29
4.3.
Doble búfer del láser para minimizar bloqueos. . . . . . . . . . . . . . . . .
30
5.1.
Medición del tiempo de cómputo de una función en MaRTE para C y Ada
respectivamente.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
34
5.2.
Ejemplo de tareas con tiempos en MaRTE. . . . . . . . . . . . . . . . . . .
36
6.1.
Algoritmo de navegación adaptado a MaRTE.
. . . . . . . . . . . . . . . .
37
6.2.
Esquema de las tareas
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
38
6.3.
Navegación del robot a través de comunicación inalámbrica y control.
. . .
42
A.1. Diagrama de Gantt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
49
D.1. Principio de medida y rango angular de LMS . . . . . . . . . . . . . . . . .
68
D.2. Resumen del funcionamiento de las comunicaciones con LMS . . . . . . . .
69
D.3. Esquema de la inicialización del LMS . . . . . . . . . . . . . . . . . . . . .
70
D.4. Barrido láser en el modo 0 ..180
. . . . . . . . . . . . . . . . . .
71
D.5. Operaciones en la ejecución de un programa con LMS . . . . . . . . . . . .
73
F.1. Funciones para manejar el P20S en C . . . . . . . . . . . . . . . . . . . . .
83
F.2. Funciones para manejar el Láser en C . . . . . . . . . . . . . . . . . . . . .
84
F.3. Funciones para manejar el GPS en C
84
o
o
y 0..100
o
. . . . . . . . . . . . . . . . . . . . .
F.4. Funciones para manejar el P20S en Ada
. . . . . . . . . . . . . . . . . . .
86
F.5. Funciones para manejar el Láser en Ada
. . . . . . . . . . . . . . . . . . .
87
F.6. Funciones para manejar el GPS en Ada . . . . . . . . . . . . . . . . . . . .
87
9
Índice de cuadros
4.1.
Opciones de conguración del láser
. . . . . . . . . . . . . . . . . . . . . .
28
5.1.
Interrupciones generadas por la línea serie. . . . . . . . . . . . . . . . . . .
35
6.1.
Información sobre las tareas. . . . . . . . . . . . . . . . . . . . . . . . . . .
39
6.2.
Resultados obtenidos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
43
10
Capítulo 1
Introducción
1.1. Objetivo y alcance
El objetivo principal de este proyecto es la implantación del sistema operativo (SO)
de tiempo real estricto MaRTE OS en un robot móvil Pioneer 3-AT. Se crearán los controladores (drivers ) de algunos dispositivos del robot. Entre ellos el microcontrolador, el
láser, el sistema de comunicación inalámbrico y el GPS. Además se proporcionarán las
herramientas necesarias para continuar investigando y poder realizar aplicaciones en este
nuevo sistema.
MaRTE OS (Minimal Real Time Operating System for Embedded Applications ) [1] es
un SO para aplicaciones empotradas basado en un subconjunto del estándar POSIX.13
para tiempo real. Está escrito principalmente en Ada y actualmente está siendo desarrollado en la Universidad de Cantabria. Es totalmente necesario añadir al control de los
robots restricciones de tiempo real. Una mala gestión del procesador por parte del SO
puede provocar diversos problemas de control en el robot. Con el SO MaRTE pueden
realizarse aplicaciones ables bajo un entorno determinista que asegura una planicación
correcta de las tareas que componen la aplicación.
Para poder realizar comunicaciones en tiempo real se estudiará y portará a MaRTE el protocolo RT-WMP que actualmente se desarrolla en la Universidad de Zaragoza.
RT-WMP (Real Time Wireless Multi-hop Protocol ) [7] es un protocolo de comunicación
basado en paso de testigo, con la característica principal de soportar transmisiones en
tiempo real.
Se demostrará el correcto funcionamiento de las herramientas desarrolladas con diferentes aplicaciones y se evaluarán los resultados obtenidos. Además se deberá realizar
una caracterización temporal completa del conjunto de funciones disponibles para cada
dispositivo.
Como valor añadido del proyecto, se han establecido las bases para trabajar con un SO
de tiempo real de libre distribución que es capaz de funcionar en diferentes arquitecturas.
Esto permite el estudio de diferentes técnicas y protocolos basados en tiempo real que
hasta ahora eran difíciles o imposibles de realizar.
11
1.2. Contexto
El proyecto se ha llevado a cabo en el grupo de Robótica, Percepción y Tiempo Real
del Departamento de Informática e Ingeniería de Sistemas (DIIS). El departamento posee
4 robots móviles Pioneer de la casa constructora ActiveMedia.
Hasta ahora los robots sólo tenían instalado un SO Linux de propósito general. Para
poder interaccionar con los dispositivos del robot (odometría, láser, GPS, comunicaciones,
etc) se trabaja a través de una plataforma cliente/servidor llamada Player/Stage de libre
distribución que se ejecuta sobre este SO.
Una aplicación que se ejecuta en un SO de estas características no puede controlar qué
tarea entra a ocupar el procesador en cada instante haciendo imposible garantizar el cumplimiento de restricciones temporales. La forma de ejecución de las tareas que componen
la aplicación no las determina el usuario, sino el SO que tiene otros objetivos diferentes a
los de tiempo real. No se garantiza una correcta planicación de las tareas que se ejecutan
en el robot, pudiendo provocar comportamientos no especicados en el sistema.
1.3. Diferentes objetivos de los sistemas operativos
Los SO proporcionan una plataforma de software encima de la cual otros programas,
llamados aplicaciones, puedan funcionar. Las aplicaciones se programan para que funcionen encima de un SO particular, por tanto, la elección del SO determina en gran medida
las aplicaciones que se pueden utilizar.
En el anexo B se ilustran las características más importantes que diferencian a un SO
de propósito general de uno de tiempo real desde un punto de vista técnico.
1.3.1. Sistema operativo de propósito general
El objetivo de este tipo de SO es gestionar y administrar ecientemente los recursos
hardware del ordenador, permitiendo ejecutar concurrentemente varios programas sin que
haya conictos en el acceso de cada uno de ellos a cada uno de los recursos que necesita
y sin que ningún programa monopolice un recurso determinado.
El SO intentará que la CPU del ordenador realice el mayor rendimiento medio posible. Esto se consigue gracias a un planicador que aprovecha al máximo la capacidad
del procesador haciendo evolucionar todos los procesos o tareas alterando su ejecución y
modicando dinámicamente la prioridades.
El usuario no tiene acceso al control directo del hardware y tampoco puede prever con
seguridad el momento en el que una tarea terminará su ejecución, ni el momento en el
1. Introducción
13
que un proceso obtendrá un resultado.
Otra de las características de este tipo de SO es que son multitarea, multiaplicación
y multiusuario. En una misma máquina pueden estar en ejecución varias tareas, estar en
marcha varias aplicaciones y estar registrados varios usuarios al mismo tiempo.
1.3.2. Sistema operativo de tiempo real
Un sistema de tiempo real es un sistema de procesamiento de información que debe
responder a estímulos de entrada generados externamente en un período nito y especíco. Las respuestas correctas dependen no sólo de los resultados obtenidos sino también
del tiempo en que son entregadas. Las fallos por no responder a tiempo son tan malos
como un mal resultado.
Este tipo de sistemas está formado por dispositivos de E/S, hardware y software de
propósito especíco en donde existe una fuerte interacción con el entorno. El entorno
cambia con el tiempo y el sistema debe controlar y/o reaccionar ante cada uno de los
cambios. Para conseguir un funcionamiento correcto se imponen varias restricciones.
Restricciones de tiempos: Cómputo, periodo, plazos.
Restricciones de predecibilidad: Implica que debe ser posible demostrar o comprobar a priori que los requerimientos de tiempos se cumplen en cualquier circunstancia. Como consecuencia, la predecibilidad implica:
•
Una cuidadosa planicación de tareas y recursos.
•
Cumplimiento predecible de requisitos temporales: determinismo.
•
Anticipación a fallos, y sus requerimientos temporales.
•
Consideraciones de sobrecargas: degradación controlada.
•
Consideraciones de elementos de impredecibilidad.
•
Dotar al sistema con capacidades de monitorización y control de tiempos (hardware, software, SO, lenguaje, líneas y protocolos de comunicaciones).
Restricciones de recursos: una tarea puede requerir acceso a ciertos recursos,
además del procesador, como dispositivos de E/S, redes de comunicación, estructuras
de datos, archivos y bases de datos.
Restricciones de precedencia: una tarea puede requerir resultados de una u otra
tarea antes de comenzar su ejecución.
A diferencia de los SO de propósito general, los SO de tiempo real son monousuario y
monoaplicación. Sólo puede haber un usuario que es el que ejecuta la única aplicación que
hay en el sistema. Esta aplicación se encargará de crear las diferentes tareas que controlen
el sistema.
1.3.3. Elección del sistema
Es evidente que estos dos tipos de SO cubren aplicaciones totalmente diferentes. Un
SO de propósito general no está diseñado para controlar un sistema móvil que realiza
operaciones con unos requisitos temporales y ha de ser able en todo momento. Por otro
lado, tampoco es lógico usar un SO de tiempo real en aplicaciones sin restricciones temporales, que en un SO de propósito general se ejecutan sin problemas.
Será necesario usar un SO de tiempo real cuando la aplicación requiera un control
estricto, de forma que cuando reciba un dato de entrada sea necesario realizar el procesamiento de dicho dato antes de la recepción de la siguiente entrada.
Es posible encontrar sistemas empotrados que basan su funcionamiento en algún tipo
de SO de tiempo real realizando multitud de aplicaciones en aviones, trenes, coches,
teléfonos móviles, etc.
1.4. Necesidad de control temporal en un robot móvil
El robot que se ha usado en el proyecto esta formado por una serie de sensores que
recogen información del entorno y actuadores que le permiten realizar movimientos. Cada uno de estos dispositivos envían/reciben datos a una frecuencia diferente. Para poder
recoger los datos correctamente será necesario crear una tarea para cada dispositivo que
se ejecute a la frecuencia correspondiente.
Para que el robot se mueva o realice un trabajo, será necesaria una tarea que se encargue por ejemplo de ejecutar un algoritmo de navegación evitando obstáculos. Además
es posible que se desee visualizar en una pantalla lo que el robot está haciendo y para ello
se creará otra tarea que muestre los datos deseados.
Al tratarse de un sistema móvil, los requisitos temporales se deben respetar siempre.
Los algoritmos de control tienen que cumplir unos periodos jos y responder dentro de
unos plazos previamente establecidos. En un robot que se mueve a una velocidad de 2
m/s (7.2 km/h) y ejecuta su control cada 100 milisegundos, reaccionar 50 milisegundos
más tarde supone reaccionar 10 cm más lejos de lo que se desea. Esto puede provocar un
golpe del robot, a una persona o realizar un mal movimiento.
Como es lógico, cada tarea del sistema tendrá una prioridad determinada, que será
asignada después de realizar un estudio de planicabilidad. La tarea que atiende un sensor
tiene más prioridad que la tarea que realiza la navegación. De la misma forma, la tarea
de navegación no puede ser interrumpida por la tarea que muestra información en la pantalla. En denitiva no se puede permitir que en un momento determinado el SO decida
dar mayor o menor prioridad a una de las tareas, ni expulsar a una tarea del procesador
para que entre otra.
1. Introducción
15
Para que todas las tareas empiecen en los momentos determinados y acaben dentro de
su plazo correspondiente es necesario disponer de un SO de tiempo real que asegure una
ejecución de las tareas de la misma forma que han sido planicadas.
1.5. Estructura de la memoria
En el capítulo 2 y 3 se puede ver una introducción al SO MaRTE y al robot utilizado
durante el proyecto. En el capítulo 4 se muestra el proceso de desarrollo de cada uno de
los drivers, pasando por las fases de análisis, diseño, implementación y pruebas. En el
capítulo 5 se explican algunas consideraciones sobre la medición del tiempo en MaRTE y
en el capítulo 6 se muestran las aplicaciones realizadas para demostrar el buen funcionamiento del sistema y los resultados que se han obtenido en el proyecto.
Para nalizar en el capítulo 7 se pueden ver las conclusiones obtenidas y los trabajos
futuros que se plantean como resultado de este proyecto. Además tras la memoria se
puede profundizar en los aspectos más importantes que se han planteado consultando
los diferentes anexos realizados. Características de SO de tiempo real, manuales de los
drivers, arranque en red, API de la aplicación o los hitos más importantes del proyecto
son algunos de los temas que se pueden consultar.
Capítulo 2
El sistema operativo MaRTE OS
MaRTE OS es un SO de tiempo real destinado al desarrollo de aplicaciones empotradas
que se ajusta al perl de Sistema de Tiempo Real Mínimo denido en el estándar
POSIX.13.1. MaRTE está escrito en lenguaje Ada, con partes en C y en ensamblador, y
soporta aplicaciones Ada, C y C++. [2]
2.1. Características
Permite ejecutar aplicaciones en máquinas desnudas.
Da y controla el acceso a los recursos hardware.
Es bastante diferente de un sistema de propósito general como Linux ya que no
soporta sistemas de cheros ni tiene una consola de comandos.
Sigue el subconjunto mínimo de tiempo real POSIX.13. Dentro de POSIX.13 MaRTE OS gura dentro de la categoría Mínimo, destinada a sistemas empotrados
pequeños, en la cual no es necesario ofrecer sistema de cheros ni multiproceso.
MaRTE OS no hace uso pues de la MMU de algunas arquitecturas, no usa disco
duro sino que se aloja en memoria volátil y tampoco necesita de un terminal. Es lo
que se denomina en jerga POSIX como controlador de un Tostador. Funcionalidad
del perl mínimo del subconjunto POSIX.13 incluida en MaRTE OS:
•
Threads: también llamados hilos o hebras. Un thread es una secuencia de
instrucciones ejecutada en paralelo con otras secuencias. Los threads son una
forma de dividir un programa en varias tareas que se ejecutan de forma concurrente.
•
Mutexes, variables condicionales, semáforos: estructuras utilizadas para
la sincronización de varios threads.
•
Señales: servicio del núcleo que permite indicar la existencia de un evento.
•
Relojes y contadores: ofrecen funcionalidad para controlar el tiempo de
ejecución de cada thread.
•
Suspensión de threads, retrasos absolutos y relativos.
16
2. El sistema operativo MaRTE OS
•
17
Ficheros de dispositivo y entrada/salida: Permiten tratar los dispositivos desde un punto de vista abstracto como si fueran un chero al que realizar
llamadas del tipo open, read, write, ...
•
Funcionalidad extra: Manejadores de interrupciones hardware, planicación
denida por la aplicación.
Ofrece concurrencia a nivel de thread (tareas en Ada) pero no a nivel de procesos.
En MaRTE OS sólo hay un proceso (que será el encargado de crear los threads -tareas
necesarios), y por tanto un único espacio de direcciones de memoria.
Utiliza una política de planicación expulsiva con prioridades jas. Estos algoritmos
permiten un alto aprovechamiento de la CPU y su implementación es sencilla tal
y como dene el estándar POSIX.13.1 permite utilizar políticas de planicación
expulsivas como FIFO con prioridades, round-robin o servidor esporádico. Para la
sincronización de tareas implementa el protocolo de herencia básica de prioridad y
el techo de prioridad inmediato.
Todos los servicios tienen una respuesta y latencia temporal acotada, por lo que se
puede utilizar para aplicaciones de tiempo real (tanto estricto como no).
El espacio de direcciones es compartido por el núcleo y la aplicación con lo cual
no se provee la protección de otros sistemas operativos y se debe probar a fondo el
sistema nal. La ventaja es que permite una mayor velocidad de ejecución.
Es un núcleo monolítico. Un núcleo monolítico se caracteriza porque cuando se está
ejecutando una parte de su código no hay otras partes ejecutándose concurrentemente. Permite simplicar su desarrollo y ser muy ecientes en sistemas monoprocesador, aunque es complicado portarlo a sistemas multiprocesador. Está escrito en
Ada 95 (salvo algo de código en C y ensamblador) pero ofrece interfaces tanto para
aplicaciones Ada como C, o incluso aplicaciones que mezclen threads con tareas Ada.
Es portable a diferentes plataformas gracias a una capa de abstracción hardware.
Incluyendo microcontroladores, de gran importancia en el mundo de los sistemas
empotrados. Actualmente se encuentran implementadas para:
•
Arquitectura x86 PC (bien en máquinas desnudas o bien en emuladores). El
núcleo es compatible con cargadores que usen el protocolo Multiboot.
•
Arquitectura Linux y LinuxLib, donde MaRTE OS corre dentro de Linux.
Principalmente destinada a investigación y enseñanza (no se puede alcanzar
requerimientos de tiempo real estricto dentro de un sistema que no lo es, como
Linux).
•
Arquitectura M683XX. No se distribuye actualmente con MaRTE OS debido
a que corresponde a una versión antigua que no ha sido actualizada.
Es código libre con licencia GNU/GPL.
Figura 2.1: Arquitectura de MaRTE OS para aplicaciones ADA y C
En la gura 2.1 podemos ver la arquitectura en forma de capas de MaRTE OS para
una aplicación escrita en Ada y en C. La principal diferencia entre ambas radica en la capa
utilizada para comunicar la aplicación con el resto del sistema. Como puede apreciarse
en ambas guras, el núcleo incluye una interfaz abstracta de bajo nivel para acceder al
hardware. En ella se dene la visión que del hardware tienen las partes del núcleo que
son independientes de la plataforma de ejecución (Ej: x86, PowerPC, ARM, MIPS,...).
Esta interfaz constituye la única parte del núcleo que es dependiente del hardware, lo
que facilita el portado de MaRTE OS a distintas plataformas. Por otro lado, los gestores
de dispositivos (drivers ) también presentarán dependencias respecto al hardware sobre el
que se ejecutan.
2.2. Trabajando con MaRTE OS
En el anexo E se puede consultar la forma de instalación del sistema, el proceso de
creación de nuevos drivers y la conguración necesaria de nuestro entorno de desarrollo
para poder arrancar el SO a través de la red.
MaRTE es un SO destinado a controlar aplicaciones empotradas en diferentes máquinas y arquitecturas. Por este motivo al desarrollar una aplicación será necesario un
ordenador donde el usuario programa y compila (servidor), y otra máquina donde se ejecute el archivo generado en el proceso anterior (host ).
Para comenzar con MaRTE OS es muy recomendable el uso de alguna máquina virtual,
como por ejemplo Qemu (disponible en http://fabrice.bellard.free.fr/qemu/). De esta forma no hay que traspasar el archivo entre diferentes ordenadores. Para un mayor detalle
sobre como utilizar la máquina virtual con MaRTE OS se recomienda leer [3].
En este caso, la máquina host es el robot, y por lo tanto todas las pruebas deberán
realizarse sobre esta arquitectura. El entorno en el que se ha desarrollado el proyecto se
muestra en la gura 2.2
2. El sistema operativo MaRTE OS
with MaRTE_OS;
with Text_IO;
use Text_IO;
Ordenador de
desarrollo
19
Robot en ejecución
Arranque
en red o
mprogram
en disco
procedure robot is
begin
setSpeed(1.0,0.1);
...
end procedure;
Compilación
Programa
ejecutable
MaRTE OS
Código
objeto
Enlazado
Programa
ejecutable
Red
Red
Inicializa
el sistema
Ejecuta programa
del usuario
Servidor DHCP + TFTP
Figura 2.2: Entorno de desarrollo del proyecto.
En el servidor tendremos que tener Linux con los archivos y el compilador de MaRTE
instalado. Aquí será donde se programe la aplicación incluyendo las librerías del SO. Al
compilar con el compilador de MaRTE se obtiene un chero llamado mprogram que se
deberá copiar al robot para ser ejecutado. Para agilizar el proceso, se permitió al robot
arrancar en red, descargándose el archivo generado después de compilar. El ordenador
host obtiene la dirección de red por medio de un servidor DHCP, y este es el que le indica
que archivo debe descargarse para arrancar. La máquina host lo descarga mediante un
servidor TFTP instalado en el servidor y comienza la ejecución del SO y la aplicación
programada. Esta conguración esta completamente especicada en el apartado 2.3 de [4].
Capítulo 3
El robot móvil Pioneer
3.1. Arquitectura del sistema
En la gura 3.1 se puden observar los robots disponibles en el laboratio. Cada uno
de estos robots está formado por un ordenador Pentium III a 800MHz, con 250MB de
memoria RAM, 40GB de disco duro y una variedad de dispositivos sensores y actuadores.
Los sensores permiten obtener información del entorno. Los actuadores sirven para interaccionar con el entorno y dar cierta movilidad al sistema. En la gura 3.2 se muestra una
esquema gráco de la arquitectura del sistema donde se detallan los diferentes dispositivos
estudiados y sus conexiones.
Figura 3.1: Robot Pioneer 3-AT.
El láser, el microcontrolador y el GPS se comunican con el robot a través de la línea
serie RS232. El microcontrolador tiene conectados varios sensores. Él mismo se comunica
con estos sensores gracias a un SO llamado P2OS que lleva incorporado. El ordenador
(el robot) se comunica con el micro y sus sensores mediante comandos que el P2OS comprende.
La tarjeta inalámbrica es de tipo PCMCIA. El robot no dispone de un conector de
este tipo pero si de uno de tipo PCI 104. Para poder usar la tarjeta se ha utilizado un
adaptador entre PCMCIA y PCI 104 de 32 bits.
20
3. El robot móvil Pioneer
21
LÁSER
ttyS0
GPS
ttyS1
MICROCONTROLADOR
Odometría
Sonar
ttyS2
PCI 104
ROBOT
ADAPTADOR
PCI-PCMCIA
PCMCIA
LINEA SERIE
RS232
TARJETA
INALÁMBRICA
Motores
Brújula
P2OS
Figura 3.2: Los dispositivos más importantes del robot y sus conexiones.
3.1.1. Sensores
Posición relativa:
El sensor de odometría es el que informa al robot de la posición en la que se encuentra
situado respecto a los movimientos realizados. Básicamente lo que hace es medir el
movimiento de las ruedas del robot, calculando la posición en X, en Y y el ángulo
que se ha movido. Un sensor tacométrico esta conectado al microcontrolador. Con
cada movimiento de las ruedas el sensor envía pulsos al microcontrolador y este
los traduce a valores correspondientes al movimiento. Esta medida es aproximada
y poco able ya que si una rueda derrapa el sistema de odometría creerá que el
robot se ha movido más de lo que realmente se ha movido. Esto provoca que el
robot tenga una información acerca de su posición incorrecta. Además, debido a
que la odometría es un valor respecto al desplazamiento realizado, el error se va
acumulando y cuantos más movimientos se hacen la calidad de la medida empeora.
Con el sistema de odometría también se puede saber a que velocidad se realizan los
movimientos, tanto translacional como angularmente. Estos valores de velocidad se
obtienen derivando el valor de la posición.
Posición global:
Gracias al dispositivo GPS de la marca Novatel modelo ProPack G2 que lleva incorporado el robot se puede obtener la posición global en la que se encuentra el robot.
El error del GPS es de pocos metros y se puede reducir a centímetros si se usa una
estación base diferencial. El problema del sistema GPS es que sólo puede usarse en
exteriores porque en interiores no recibe la señal de los satélites. Esto obliga a usar
la odometría en interiores.
Entorno 2D con láser:
El robot dispone de un sensor láser de distancias de la marca SICK modelo LMS
que es capaz de aportar información sobre lo que el robot tiene delante suyo. Su
funcionamiento se basa en un mecanismo de espejo rotatorio, que va dirigiendo un
o
pulso láser en un recorrido horizontal de hasta 180 . Las medidas se calculan por
tiempo de vuelo. Para obtener más información acerca del dispositivo SICK LMS
se recomienda consultar el anexo D.
Entorno 2D con sonar:
También existe la posibilidad de usar los 16 sensores sonar que proporcionan información similar al láser pero más limitada. En vez de utilizar un láser, lanza una
onda que luego recoge y se obtiene la distancia al obstáculo. El problema es que las
ondas no se transmiten en línea recta como el láser. Esto provoca que en diferentes
situaciones el valor que se recoge es erróneo e incluso puede que la onda que recoge
un sensor es la que envió otro de los sensores debido a algún rebote. Además en vez
de obtener las 360 distancias que puede proporcionar el láser, ofrece tan solo 16.
Orientación:
Es posible usar una brújula electrónica para conocer de forma precisa la orientación
del robot. La brújula es uno más de los sensores que está conectado al microcontrolador.
Bumpers :
En la parte frontal y trasera del robot están colocados 10 sensores que indican al
robot que ha tocado o se ha chocado con algo. Cuando uno de estos sensores se
activa, el robot por defecto se para. Este comportamiento es congurable. También
está conectado al microcontrolador.
3.1.2. Actuadores
Motores: Para realizar movimientos el robot dispone de 2 motores para mover las
ruedas de cada lado. Se puede mover en la dirección X, Y con desplazamientos de
o
translación y 360
angularmente, pero para girar ha de rotar sobre sí mismo derra-
pando ya que las ruedas están jas sin poder modicar la dirección. La velocidad
o
de translación máxima es de 2 metros/segundo y la angular de 360
por segundo.
3.1.3. Mecanismo de comunicación
El robot dispone de un conector PCI 104. Gracias a un adaptador que convierte una
entrada PCI 104 a una de tipo PCMCIA es posible usar una tarjeta inalámbrica de tipo
PCMCIA de la marca Conceptronics. A través de esta tarjeta se puede enviar información
del robot a cualquier otra tarjeta inalámbrica utilizando el protocolo 802.11. Además es
posible utilizar el protocolo RT-WMP para comunicaciones en tiempo real que se esta
desarrollando actualmente en la Universidad de Zaragoza.
3.2. Método de trabajo actual con el robot
Actualmente el robot tiene instalado un SO Linux de propósito general. Para controlarlo se utiliza un programa de software libre con licencia GNU llamado Player/Stage.
Player se ejecuta sobre el robot proporcionando un interfaz simple y claro para el manejo
de sus sensores y actuadores sobre una red IP. Por lo tanto, para poder controlar el robot,
se necesita de un programa cliente que acceda por medio de un socket TCP/IP a Player.
3. El robot móvil Pioneer
23
Este cliente puede leer la información que devuelven los sensores, dar órdenes a los actuadores y congurar los dispositivos que monta el robot al vuelo. Entre las principales
características de Player cabe mencionar su capacidad para soportar distintos robots y
su facilidad para añadir nuevo hardware. Todo esto es posible gracias a su arquitectura
modular.
Otra de las cosas que se puede destacar de Player es que si un programa de control
funciona en su simulador (Stage), generalmente, este funcionará en el robot real sin ningún cambio. El programa es muy cómodo para desarrollar sistemas de navegación y todo
tipo de aplicaciones robóticas. Permite realizar un desarrollo rápido usando un entorno
integrado como Eclipse. Además no es necesario tener un robot para hacer pruebas ya
que se pueden hacer en el simulador. El único problema del simulador es que no tiene en
cuenta algunos factores del entorno. Las ruedas del robot no derrapan nunca, la odometría
es perfecta y todos los valores de láser están disponibles instantáneamente sin error alguno.
Capítulo 4
Integración de los sensores en MaRTE
4.1. Análisis general
Actualmente los algoritmos de control desarrollados para el robot (o el simulador del
robot) se ejecutan sobre un SO Linux de propósito general. Un algoritmo de navegación
bien diseñado no conseguirá mover el robot con la precisión que se desea. Mientras se
ejecuta el algoritmo de navegación, el SO realiza diferentes tareas y su planicador dejará
ejecutar la navegación si lo cree conveniente. Esto quiere decir que el movimiento del robot
está condicionado por la carga y la política de planicación del sistema. En el capítulo 6
se ha demostrado que si se ejecuta una aplicación en Linux para mover el robot y se carga
el sistema con otros procesos el robot se mueve de forma descontrolada.
Si se ha desarrollado un buen algoritmo de navegación y se necesita un sistema able
y robusto se deberá realizar una aplicación en MaRTE similar a la que podemos ver en el
apartado 6.1. El ordenador del robot está dedicado únicamente a leer los sensores, procesar
los datos (navegación) y mandar comandos a los motores. La planicación se realiza antes
de lanzar la aplicación. Un SO como MaRTE y un estudio de planicabilidad garantizan
que todas las tareas que forman la aplicación siempre se van a ejecutar dentro de sus
plazos.
4.2. Diseño arquitectural
En la gura 3.2 se pueden observar los dispositivos que componen el sistema y sus
conexiones. Se han desarrollado los diferentes drivers que permiten la interacción del
ordenador con:
El microcontrolador. Driver de comunicación a través de la línea serie entre
microcontrolador y ordenador.
El láser. Driver de comunicación a través de la línea serie entre láser y ordenador.
El GPS. Driver de comunicación a través de la línea serie entre GPS y ordenador.
La tarjeta inalámbrica. Driver de comunicación a través de la conexión PCI 104
con el adaptador PCI/PCMCIA. Y a través de ésta se realiza la comunicación con
la tarjeta inalámbrica PCMCIA.
24
4. Integración de los sensores en MaRTE
25
A continuación se explican las fases de análisis, diseño, implementación y pruebas por las
que ha evolucionado el proyecto.
4.3. Microcontrolador y P2OS
4.3.1. Análisis
Como punto de partida es necesario conocer qué características tiene el microcontrolador y qué tarea de control hay que realizar para que el robot y el micro se comuniquen
perfectamente. Para ello se estudió en profundidad el manual disponible en [11] donde
se especican las características del micro y se dene desde el sistema de conexión para
cada elemento hasta los diferentes comandos que se pueden enviar. En el anexo C hay
disponible una versión resumida del manual en castellano.
Varios de los sensores están conectados al microcontrolador que a su vez está conectado con el ordenador principal del robot a través de la línea serie RS232. Este micro
se comunica mediante el P2OS con los motores, el sistema de odometría, los sensores
sonar, la brújula, etc. El P2OS tiene una estructura cliente/servidor. El servidor está en
el micro esperando los comandos que el cliente (el ordenador) le va mandando. Se pueden
diferenciar dos tipos de paquetes de comunicación entre el micro y el ordenador:
Paquetes SIP: Son Paquetes de Información del Servidor que cada 100 ms envía
el microcontrolador al ordenador. Este paquete contiene información actualizada
sobre todos los dispositivos conectados al micro. Esto signica que cada 100 ms
el ordenador tiene actualizada correctamente la información de odometría, sonar,
orientación, etc.
Paquetes de Comando: Son paquetes diferentes a los anteriores. En este caso van
en la dirección contraria, el ordenador envía una orden al micro para que realice un
nuevo comando. Por ejemplo modicar el valor de la velocidad, la conguración de
un sensor, etc.
El driver desarrollado para el micro debe ser capaz de enviarle comandos correctamente, y de recibir la información que el micro envía periódicamente. Es decir, el driver
implementa la parte cliente del P2OS.
4.3.2. Diseño
El primer paso fue estudiar como estaba implementado el controlador del micro en
la plataforma Player que se usa en el robot. En términos generales Player dispone de un
nivel de usuario y un nivel hardware que se comunican pasándose mensajes en las dos
direcciones.
En el nivel hardware se crea un thread por cada dispositivo que se instancia en el
robot. Si usamos tres dispositivos (microcontrolador, láser y GPS) se creará un thread
para cada uno. Cada thread atiende los datos que se envían/reciben para cada dispositivo
y actualiza una serie de variables compartidas entre ambos niveles (datos de posición,
velocidad, orientación, etc). Además intercambia mensajes con el nivel superior.
El nivel de usuario tiene una visión abstracta del hardware. Es un nuevo proceso que
mediante una serie de funciones que componen el API de Player, obtiene los datos compartidos y va generando los diferentes tipos de mensajes que comunican con el nivel hardware.
Esta forma de comunicación con los dispositivos es incompatible con las características del tiempo real. El usuario no puede tomar decisiones sobre las prioridades de los
diferentes threads que se crean. Todos los threads entran en conicto entre ellos y con los
demás procesos del sistema.
La alternativa al sistema de Player fue reutilizar una parte del driver que implementaba el cliente del P2OS y rediseñar la forma de creación y comunicación de las diferentes
tareas. Las funciones que construyen, envían y reciben comandos para el microcontrolador
se mantuvieron modicando algunas llamadas al sistema. Para todas estas funciones que
estaban escritas en C, se elaboró una interfaz para poder utilizar toda la exibilidad de
las tareas Ada. En el anexo G se puede ver como se realiza la interfaz entre C y Ada, y
en el anexo F el conjunto de funciones que el usuario tiene a su disposición.
Se proporcionan funciones que interaccionan directamente con el hardware y funciones que obtienen datos compartidos por las tareas. Los dos niveles de Player ahora se
convierten en un sólo nivel. El usuario deberá crear las tareas que interaccionan con el
hardware y las que se comunican mediante los datos compartidos. Ahora el control total
de las tareas la tiene el usuario.
Las funciones que realmente interaccionan con el hardware están escritas en C. Como
la comunicación entre tareas no se puede implementar con objetos protegidos Ada se
implementaron con mutexes de C. En este caso tienen la característica de poder ser inicializados con un protocolo de planicación de techo de prioridad inmediato modicando
los atributos del mutex con el valor PTHREAD_PRIO_INHERIT y con la prioridad
deseada. En cualquier caso el usuario puede modicarlo para usar cualquiera de los protocolos disponibles.
Cuando una tarea quiere acceder a información compartida, debe realizar un bloqueo
(función de usuario lockP2os), ejecutar las funciones correspondientes sobre los datos
compartidos y volver a liberar el mutex (unlockP2os). El tiempo de cómputo que transcurre desde que se captura el mutex hasta que se libera supone un tiempo de bloqueo
para otras tareas que también quieran acceder a los datos. Esta forma de trabajar se ha
utilizado también en el láser y en el GPS. En la gura 4.3 se puede ver una explicación
gráca para el caso del láser.
En la gura 4.1 se muestran las fases y tareas que están involucradas en la comunicación entre el robot y el micro. Cuando encendemos el robot, el micro se queda a
4. Integración de los sensores en MaRTE
27
Ordenador del
robot + MaRTE
Microcontrolador
+
Comunicación
Servidor P2OS
1
Escucha
peticiones
del cliente
2
Envía SIP
cada 100 ms
Cliente P2OS
Conexión
2
2' Recibe
comandos y
actúa
SYNC0
SYNC1
SYNC2
Conecta al
servidor
1
Dos tareas concurrentes
T1
Recibe SIP
cada 100 ms
y actualiza
variable
compartida
2'
T2
Envía
comandos
Figura 4.1: Diseño del driver P2OS
la espera para recibir (1) una serie de comandos de conexión (comandos SYNC) que el
cliente deberá mandar. Cuando el micro tiene un cliente conectado, realiza dos tareas
automáticamente. Por un lado (2) envía un paquete SIP al cliente cada 100ms y por otro
(2') espera la recepción de comandos del cliente para actuar sobre los motores.
En el otro lado, el cliente lo forma el ordenador del robot controlado por MaRTE.
Cuando la aplicación comienza manda los comandos de conexión (1) y el siguiente paso
es lanzar dos tareas diferentes. La primera tarea (2) realiza la lectura de los paquetes SIP
que envía el servidor (esto se hace cada 100ms). La segunda tarea (2') es la encargada de
enviar los comandos al robot. En esta segunda tarea será donde se ejecute por ejemplo
un algoritmo de navegación.
4.4. Láser SICK LMS
4.4.1. Análisis
El láser es el dispositivo que permite al robot obtener información sobre el entorno.
Cada cierto tiempo este dispositivo envía al ordenador un conjunto de valores que representan la distancia que separa el sensor de los objetos que hay delante suyo. De forma
similar al microcontrolador, el ordenador se comunica con el láser a través de la línea
serie intercambiando datos. En el anexo D se detalla en profundidad el funcionamiento
del dispositivo y los diferentes comandos que se envían para congurarlo y comenzar la
lectura de datos.
Hay varias conguraciones posibles para usar el láser. Para realizar la conguración se
han de enviar diferentes comandos de una forma determinada. En primer lugar se puede
congurar la velocidad de conexión con el dispositivo (9600, 19200 y 38000 bytes por se-
Rango angular
0º .. 100º
0º .. 100º
0º .. 100º
0º .. 180º
0º .. 180º
Resolución angular
1º
0.5º
0.25º
1º
0.5º
Número de puntos
101
201
401
181
361
Cuadro 4.1: Opciones de conguración del láser
gundo). Es posible obtener las distancias en un rango de 100
o
o
de 1 , 0.5
o
ó 0.25
o
ó 180
o
y con una precisión
obteniéndose un número de valores de distancias diferente en cada caso.
Por último se puede congurar la precisión de las distancias que se recogen en cm o en mm.
Las fases de comunicación con el dispositivo son muy simples:
1. Enviar comandos de conguración.
2. Enviar comando Start para empezar a recibir datos de forma continua.
3. Enviar comando Stop y Reset para terminar y dejar el dispositivo con los valores
por defecto.
Cuantos más puntos se obtengan del láser, se podrá conocer mejor el entorno pero
la frecuencia de muestreo será menor. Los diferentes modos de conguración del láser se
pueden consultar en la tabla 4.1. Todos los datos se envían a través de la línea serie a una
velocidad determinada limitando la capacidad de transmisión.
El driver del láser debía ser capaz de implementar la comunicación entre el dispositivo
y el robot a la perfección. Además se debían de aportar soluciones para poder usarlo
dentro del marco del tiempo real.
4.4.2. Diseño
La cantidad de información (bytes) que el sensor manda al robot es muy grande y lo
hace a una frecuencia elevada. Esto provoca que se generen un gran número de interrupciones a través de la línea serie. Se estudió la gestión de interrupciones en el puerto serie
en MaRTE ya que a tasas de envío altas se perdían interrupciones. Esto es un error grave
que había que arreglar y con este objetivo se estudió como estaba implementada la línea
serie.
Los problemas de la línea serie
En la gura 4.2 se pueden observar los elementos más importantes que componen el
driver de la línea serie en MaRTE. El problema que planteaba este diseño es que la rutina de interrupción se ejecuta correctamente dependiendo de la velocidad del procesador.
El procesador del robot es más lento (800 MHz) que el procesador que había usado la
persona que desarrolló este driver y no lo tuvo en consideración. El primer problema
4. Integración de los sensores en MaRTE
29
BUFER DE ENTRADA
INT RS232
PROGRAMA
DE USUARIO
REGISTRO
ENTRADA
Read
Rutina de
interrupción REGISTRO
SALIDA
Serial_port_driver
write
BUFER DE SALIDA
(bloqueante
/ nobloqueante)
Figura 4.2: Esquema de funcionamiento del puerto serie.
importante fue que el búfer circular (entrada y salida) tan solo tenía espacio para 1 Byte. Este problema se solucionó modicando la denición del búfer ampliando la capacidad.
El segundo problema que hubo que solucionar fue que mientras se estaba atendiendo
a una interrupción, llegaban nuevas interrupciones que más tarde no eran atendidas. Para
ello se modicó el manejador de la interrupción para que antes de salir comprobara si
habían nuevos datos en el registro del RS232. De esta forma se consiguió que la línea
serie funcionara con el láser SICK LMS para las velocidades de 9600bps y 19200bps. El
problema es que este manejador presenta una condición de carrera y un aumento en la
frecuencia de recepción de interrupciones provoca que de nuevo no dé tiempo al driver
a atender a todas las interrupciones correctamente. Con la siguiente velocidad posible
(38400bps) el driver volvía a fallar. La solución más sencilla es ampliar la velocidad del
procesador. Sin embargo en Linux, con la misma velocidad y el mismo procesador todo
funciona correctamente. La explicación es que, o bien el código del driver de la línea serie
no está tan optimizado como para Linux, o directamente el driver está mal implementado
y con velocidades altas no funciona.
El desarrollo del driver se realizó siguiendo el manual del dispositivo. Una vez corregida la transmisión de datos a través de la línea serie en MaRTE, se implementaron los
diferentes comandos que hay que enviar al láser, así como todas las funciones necesarias
para una comunicación correcta entre el ordenador y el dispositivo.
El láser tiene unas fases de ejecución determinadas y deja poco margen a la imaginación. La única forma para conseguir que funcione correctamente es traducir a código el
manual. Sin embargo, sí que se realizó una modicación adicional para poder usar el láser
correctamente en tiempo real.
Lectura y reducción de bloqueos
Cuando realizamos una lectura del dispositivo láser rellenamos un búfer de distancias
de diferente dimensión dependiendo del modo con el que lo hayamos inicializado, y por lo
tanto tardaremos más o menos tiempo en leerlo. Por otro lado cuando tenemos una aplica-
Tarea utiliza el
láser
Tarea que
atualiza el
búfer del láser
wait (mutex)
Escritura
completa
variable
protegida
signal (mutex)
valores1
valores2
wait (mutex)
Lectura
completa
variable
protegida
Estructura con las
signal (mutex)
medidas del láser
duplicada para minimizar
bloqueos.
Figura 4.3: Doble búfer del láser para minimizar bloqueos.
ción y queremos consultar el láser entero iremos leyendo el búfer de elemento en elemento.
Puede suceder que cuando usemos el láser desde una tarea leamos el búfer mientras que la
tarea que actualiza el mismo búfer también este escribiendo, dejando un dato incoherente.
La gura 4.3 muestra la solución que se ha dado a este problema. Para evitar leer
un dato incoherente se tiene que proteger el búfer en el que se esta escribiendo/ leyendo
en cada momento. Se implementó un objeto protegido mediante un mutex de la misma
forma que en el driver del microcontrolador.
Además para evitar tener que esperar a que una de las dos operaciones acaben completamente se duplicó el búfer. De esta forma cuando una tarea actualiza el búfer, la
tarea que lo lee puede continuar sin bloquearse. Cuando el búfer esté actualizado y la
otra tarea ya no esté leyendo (ha liberado el bloqueo) se intercambiarán los vectores y se
podrá continuar. En el apartado 6.1 se pueden ver los valores de los bloqueos entre tareas
y objetos protegidos para una aplicación típica.
4.5. Comunicación inalámbrica
4.5.1. Análisis
Este driver se implementó para poder comunicar el robot con otras máquinas. Para
ello MaRTE OS dispone de un controlador para una tarjeta Conceptronics de tipo PCI.
Por problemas de tamaño, es imposible instalar una tarjeta de este tipo en el robot. Lo
que si se podía hacer es poner un adaptador PCMCIA/PCI que permite instalar una tarjeta Conceptronics de tipo PCMCIA. Debido a que las tarjetas son del mismo fabricante
y de modelos muy similares el driver es exactamente el mismo para ambas tarjetas.
El problema surgió debido a que no existía en MaRTE el driver para comunicarse con
la tarjeta mediante PCMCIA. Desarrolladores de MaRTE OS en la Universidad de Cantabria estudiaron el problema y proporcionaron el driver que solucionaba los problemas
anteriores.
4. Integración de los sensores en MaRTE
31
El ojetivo a partir de aquí fue realizar comunicaciones en tiempo real usando las funciones que proporcionaba este driver. El problema es que en un sistema distribuido (con
varios robots o máquinas comunicándose), la tarea que monitorea y controla diferentes
aspectos del entorno está dividida entre los nodos. Debido a los retardos impredecibles
de la comunicación, los diferentes nodos pueden obtener nueva información en distintos
instantes, causando que algunos nodos tengan una visión incorrecta del entorno. Estos
actuarán inconsistentemente y fuera de control. Por lo tanto en un sistema distribuido
de tiempo real se necesita garantizar el tiempo que tarda en enviarse un mensaje para permitir una planicación en tiempo real. En consecuencia cada evento o fase en un
protocolo de comunicación debe tener una duración acotada. Sin embargo, los protocolos
de comunicación inalámbrica existentes como 802.11 no aportan garantías temporales en
transmisiones de red debido a interferencia entre paquetes, retransmisiones y problemas
de bloqueos.
4.5.2. Diseño
Con el driver de la tarjeta funcionando se disponía de la tecnología suciente para enviar una trama de bytes desde una máquina a otra. Es decir, mediante las funciones send y
receive que proporciona el driver era posible enviar datos desde una dirección MAC a otra.
La mejor alternativa para poder conseguir una comunicación dentro del marco de
tiempo real fue adaptar el protocolo RT-WMP para comunicaciones en tiempo real, que
esta siendo desarrollando en la Universidad de Zaragoza a MaRTE OS.
El protocolo RT-WMP funciona en tres fases. Fase de arbitrio de la prioridad, fase de
autorización de transmisión y fase de transmisión del mensaje. Durante la fase de arbitrio
de la prioridad, los nodos se ponen de acuerdo sobre cual de ellos tiene el mensaje de más
prioridad en la red en ese momento. Después, en la fase de autorización de transmisión, se
envía una autorización para transmitir al nodo que tiene el mensaje de mayor prioridad.
Finalmente, en la fase de transmisión del mensaje, éste nodo envía el mensaje al nodo de
destino.
RT-WMP funciona mediante paso de testigo sobre un conjunto de nodos acotado. Cada nodo tiene su propia cola de mensajes y cada cola de mensajes tiene una prioridad (de
1 a 255 niveles). Cada mensaje tiene una dirección de destino, que es uno de los nodos de
la red. Cuando un nodo recibe un token, éste busca en su cola el mensaje con mayor prioridad y, sí el valor de la prioridad del mensaje es mayor que el valor en el correspondiente
campo del token, el nodo cambia el valor de la estación con mayor prioridad y el valor de
la prioridad del mensaje en el campo del token y lo envía a otro nodo. El último nodo que
recibe el toquen comprueba cual es el nodo que tiene el mensaje de mayor prioridad y, por
lo tanto, cual es el nodo autorizado a enviar el mensaje. Entonces, manda un mensaje de
autorización al nodo que tiene el mensaje de mayor prioridad. Finalmente este mensaje es
enviado a través de un camino multi-salto. Cuando el mensaje llega al destino, el bucle se
reinicia. Los nodos saben sólo el número de nodos de la red. Cada nodo esta identicado
con un número natural entre 0 y N que es su dirección en la red WMP. Las conrmaciones
(ACK) son implícitas. Sí el nodo A envía un token al nodo B, y el nodo B lo envía al nodo
C, el nodo A interpreta que éste pasa como un reconocimiento implícito de que el token
fue recibido correctamente por el nodo B. Todas las capas de bajo nivel del protocolo
envían sus tramas mediante broadcast. No hay ltrado y todos los nodos reciben la misma
trama, lo cual es obligatorio para que el protocolo funcione correctamente. En [7] se puede
obtener más información sobre el funcionamiento de RT-WMP.
El protocolo hasta ahora sólo funcionaba en Linux, y está escrito en C y C++. Gracias
a la exibilidad y modularidad con la que está implementado, adaptarlo a MaRTE no fue
una tarea difícil. En primer lugar se denió la mejor forma de hacer el protocolo multiplataforma. Mediante cheros de denición se puede compilar el código directamente para la
plataforma deseada. Para conseguir que funcionara en MaRTE fue necesario adaptar las
llamadas al sistema del protocolo (para Linux) a sus equivalentes llamadas para MaRTE.
En el capítulo 6 se puede ver una de las aplicaciones realizadas usando comunicaciones
inalámbricas.
Para este protocolo no se ha realizado un interfaz Ada debido a la escasez de tiempo.
El protocolo genera diferentes threads que controla el SO pero no el usuario. En un futuro
este interfaz permitirá lanzar el protocolo utilizando tareas de Ada.
4.6. GPS Novatel
4.6.1. Análisis
Este dispositivo tiene la misión de leer la posición, que es devuelta en coordenadas
geográcas (longitud/latitud). Por lo tanto, también se encarga de pasarlas a coordenadas
cartesianas en el sistema UTM (X,Y,h) donde X es positiva hacia el Este de la cuadrícula
e Y hacia el Norte y h es el uso o zona UTM (UTM zone). El origen de este sistema de
coordenadas es para la X el meridiano central del huso UTM en el que está el robot, y
para la Y el ecuador.
El problema inherente que trae consigo el uso de UTM es que el robot cambie de huso.
Lo que ocurre en este caso es que el origen del sistema de coordenadas para la coordenada
X también cambia y por lo tanto también cambiará la idea de posición que tiene el robot.
Para evitar esto, se guarda el primer huso UTM de la primera lectura que se ha tomado
del GPS y a partir de él se calculan las posiciones en coordenadas UTM.
Para más información del sistema GPS y de la proyección UTM ver el anexo H en
[10].
4. Integración de los sensores en MaRTE
33
4.6.2. Diseño
La comunicación con el dispositivo GPS se llevó a cabo siguiendo la misma idea que
para el microcontrolador. En primer lugar se estudió el manual del dispositivo [12] y cómo
estaba implementado el driver para Player. Las funcionalidades básicas que interaccionan
a nivel hardware pudieron ser reutilizadas con algunas modicaciones.
Para poder permitir un uso de tiempo real correcto también se creó otro objeto protegido mediante mutex exactamente igual que el del microcontrolador. El sistema GPS es
de gran utilidad para poder corregir la posición (la odometría) del robot y disponer de una
buena localización. El dispositivo envía cada segundo un nuevo dato con las coordenadas
de la posición global.
4.7. Implementación y pruebas
Esta ha sido la parte más laboriosa del proyecto ya que la implementación de los
drivers debía ser a bajo nivel en lenguaje C. Básicamente se tuvo que realizar una traducción de los manuales a dicho lenguaje cumpliendo estrictamente con cada byte enviado y
recibido. Además para poder probar cada nuevo avance o mejora era necesario ejecutar
el código en el robot, haciendo mucho más pesado el trabajo. Pero es así como debe de
realizarse la programación de un sistema empotrado.
Cuando se completó la implementación y testeo de las funciones de cada driver en C,
se realizó un interfaz entre C y Ada para poder usar dichas funciones desde un programa
Ada. Esto posibilita realizar una mejor planicación de las tareas ya que para este tipo
de aplicaciones, el lenguaje Ada es sin duda la mejor herramienta de desarrollo. Se puede
consultar la conversión entre ambos lenguajes y tipos en el anexo G.
Se ha creado por tanto un nuevo conjunto de funciones o API para el desarrollo de
aplicaciones robóticas bajo el control de MaRTE OS tanto en Ada como en C disponible en
el anexo F. Es importante resaltar que todas las funciones desarrolladas fueron fuertemente
testeadas tanto individualmente como en conjunto con diferentes aplicaciones como se
puede ver en el capítulo 6. Como resultado nal se dispone de un entorno de control para
el robot amplio y robusto.
Capítulo 5
Caracterización temporal completa del
sistema
En un sistema de tiempo real, es completamente necesario denir de forma precisa los
tiempos de cómputo de las operaciones que se pueden realizar, así como los periodos de
ejecución de las tareas (o sus operaciones) y de los plazos de respuesta si es que existen. Por
este motivo, en el momento que se probaron completamente las funciones de los drivers
implementados, se midieron los tiempos de cómputo con la máxima precisión posible.
5.1. Medir el tiempo de cómputo en MaRTE
Para medir el tiempo de cómputo de una función en MaRTE se han de tomar algunas precauciones. Se puede medir el tiempo inicial y nal de la ejecución de la función y
luego restarlos. Pero de esta forma se obtiene el tiempo que está la función en ejecución
y no su tiempo de cómputo. Si dicha función no se ejecuta a la máxima prioridad o se
suspende en algún momento el planicador de MaRTE es libre de expulsarla mientras se
está ejecutando para realizar otras operaciones y más tarde nalizar la primera.
Para realizar una medida correcta del cómputo es necesario usar los relojes de ejecución disponibles en MaRTE. En la gura 5.1 se muestra la forma correcta de medir el
tiempo de cómputo de una función para los lenguajes C y Ada. De esta forma el tiempo
with POSIX;
with POSIX_Timers;
pragma Elaborate_All (POSIX_Timers);
struct timespec ts;
//para medir la duracion de la interrupcion
procedure medir is
CPU_Time_First : POSIX.Timespec := POSIX.To_Timespec (0.0);
CPU_Time_Last : POSIX.Timespec := POSIX.To_Timespec (0.0);
begin
CPU_Time_First :=
POSIX_Timers.Get_Time(POSIX_Timers.Clock_Task_Cputime_Id);
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
double t1=ts.tv_nsec;
funcion_a_medir();
funcion_a_medir;
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
CPU_Time_Last :=
POSIX_Timers.Get_Time(POSIX_Timers.Clock_Task_Cputime_Id);
double t2=ts.tv_nsec;
printf("%.6lf nseconds elapsed\n", t2-t1);
put("Tiempo = ");
put ((POSIX.To_Duration (CPU_Time_Last) POSIX.To_Duration (CPU_Time_First)) * 1000);
put_line("ms.");
esc: terminar
Figura 5.1: Medición del tiempo de cómputo de una función en MaRTE para C y Ada
respectivamente.
34
5. Caracterización temporal completa del sistema
Baud rate interrupciones /
segundo
9600
1200
19200
2400
38400
4800
Periodo mínimo
(inversa)
833.333µs
416.66µs
208.333µs
35
Utilización
0.03240
0.0648
0.1296
Cuadro 5.1: Interrupciones generadas por la línea serie.
medido corresponde únicamente al tiempo en el que la función que se desea medir ha
estado ocupando el procesador.
En el anexo F se puede ver el tiempo de cómputo de las funciones desarrolladas para el
microcontrolador, el láser y el GPS. Todos han sido medidos usando los relojes de tiempo
de ejecución.
Debido a que el driver de la tarjeta inalámbrica estuvo disponible varios meses después
de comenzar el proyecto, el tiempo de cómputo de las funciones del protocolo RT-WMP
no ha podido ser medido completamente. Aunque las pruebas realizadas para la comunicación inalámbrica funcionan correctamente no se ha podido realizar un estudio de
planicabilidad completo. Este trabajo será necesario hacerlo si en el futuro se pretende
hacer un uso intensivo de la comunicación inalámbrica en el robot.
5.2. Dependencia de la línea serie
Otro de los aspectos importantes de este sistema es que los drivers del P2OS, del láser
y del GPS funcionan a través de la línea serie. Cada byte que envían estos dispositivos
es capturado por MaRTE a través de una interrupción asociada a la línea serie como se
muestra en la gura 4.2. En el momento en el que se instancia un dispositivo, por ejemplo
el láser, dicha interrupción se ejecutará cada vez que reciba un byte. Se midió el tiempo
de cómputo de la interrupción, resultando ser de 29 microsegundos. La frecuencia a la
que se ejecutará dicha interrupción dependerá de la conguración de la línea serie.
Para cada dispositivo habrá que tener en cuenta estas interrupciones. Una posibilidad
es estimar que en el peor caso existe una tarea periódica de tiempo de ejecución 29 microsegundos y con un periodo igual a la separación mínima entre eventos. Esta separación se
obtiene a partir de la velocidad a la que se instancia el dispositivo como se puede ver en
la tabla 5.1.
Si se instancia el P2OS a 9600 y el láser a 19200, sin hacer ninguna operación más
habrá una utilización del procesador del 9.72 % y si además se instancia el GPS (9600)
dicha utilización será del 12.96 %. Estos datos son indispensables para poder realizar una
planicación correcta de tiempo real.
En la gura 5.2 se puede ver la distribución de tareas necesarias para realizar una
INT línea serie
C=29µs
T=833.33µs
Rutina de
interrupción
linea serie
Ejemplo de uso del
driver P2OS con
tareas a 9600bps
C = Cómputo
T = Periodo
Tarea actualiza P2OS
Datos P2OS
C=620µs
T=100ms
p2osGetValues
Tarea que usa P2OS
C=20ms
T=300ms
lockP2os
unlockP2os
Valores de ejemplo
Figura 5.2: Ejemplo de tareas con tiempos en MaRTE.
aplicación en tiempo real cuando se instancia el driver del microcontrolador. Por un lado
se puede ver la rutina de interrupción que se ejecuta por haber instanciado el driver del
P2OS. Tendremos que crear una tarea para cada dispositivo que funciona a través de la
línea serie para tener en cuenta dicha rutina de interrupción. Por otro lado existirá una
tarea de actualización de los datos del P2OS que se ejecutará continuamente a la frecuencia a la que se reciben los paquetes de información del micro. Y por último se crearán
las tareas necesarias que usen las funciones del driver para realizar una navegación, visualizar datos del micro, etc. Los valores que se muestran para las tareas de manejo de
la interrupción y actualización del P2OS corresponden a sus valores reales. Para la otra
tarea será necesario medir el tiempo de cómputo (los de la gura son valores de ejemplo).
Como se explicó en el apartado 4.4.2, para acceder a las funciones de los objetos protegidos implementados con mutexes es necesario realizar un bloqueo, leer los datos deseados
y quitar el bloqueo. Será el usuario el que deba realizar el bloqueo y el desbloqueo correctamente bajo su responsabilidad. Si no se produce el bloqueo el sistema funcionará pero
no tendrá un soporte de tiempo real y los datos pueden ser incoherentes.
Capítulo 6
Pruebas realizadas y resultados
Después de testear a fondo las funciones que se crearon para poder interaccionar con
los drivers, se pasó a realizar diferentes aplicaciones para comprobar que todo funcionaba
correctamente.
6.1. Navegación autónoma y tiempo real estricto
En primer lugar se adaptó un buen algoritmo de navegación para poder usarlo en
MaRTE con las funciones que se han implementado en el proyecto. El algoritmo seleccionado usa el láser para obtener información del entorno y el microcontrolador para leer
la odometría y actuar sobre los motores. Cuando empieza la ejecución intenta encontrar
algún objeto que se encuentre en movimiento usando el láser. En el momento en el que
algún objeto se mueve en su rango de visión, comienza a generar nuevos objetivos hacia los
que mueve el robot. Para poder estimar estos nuevos objetivos realiza diferentes cálculos
matriciales, entre ellos la estimación de la posición del objeto móvil mediante ltros de
Kalman [13]. A todo es este proceso se le denomina traking.
Además lleva incorporado un sistema de evitación de obstáculos conocido como ND
que computa la mejor dirección de movimiento para un vehículo omnidireccional y circular [14]. Este algoritmo realiza gran cantidad de cálculos y por tanto su ejecución ocupa el
procesador durante bastante tiempo. El esquema general del algoritmo se puede ver en 6.1
Nuevo
objetivo
traking
Evitación de obstáculos
ND
Nuevo
movimiento
Obstáculos
(sensores)
Robot
Figura 6.1: Algoritmo de navegación adaptado a MaRTE.
La aplicación está compuesta por varias tareas que interaccionan entre sí modicando
y consultando los objetos protegidos (a partir de ahora servidores), generando nuevos
37
movimientos y visualizando algunos datos de interés en una pantalla instalada en el robot.
Todo ello bajo el control del tiempo real ofrecido por MaRTE y respaldado por un estudio
de tiempos con la política de planicación basada en prioridades estáticas RMS. RMS
(Rate Monotonic Scheduling ) establece que la asignación de prioridades más altas a las
tareas más frecuentes (periodo más corto) es óptima [5]. Este método de planicación
requiere que el plazo de respuesta (tiempo que tiene la tarea para llevar a cabo su trabajo)
sea igual al periodo, tal y como sucede en nuestro caso.
6.1.1. Esquema de tareas y cumplimiento de plazos
En la gura 6.2 se puede ver el esquema con las tareas, servidores y las diferentes
llamadas a los servicios.
INT Microcontrolador (9600)
C=0.029ms
T=0.833ms
P=0.833ms
Prio
HW
Rutina de
interrupción
linea serie
Tarea actualiza P2OS
C=0.062ms
T=100ms
P=100ms
Prio
22
Tarea de navegación
C=50ms
T=100ms
P=100ms
Prio
21
Tarea Visualización
Prio
20
C=12ms
T=100ms
P=100ms
INT Láser (19200)
C=0.029ms
Rutina de
T=0.4196ms interrupción
P=0.4196ms linea serie
Prio
HW
Prio
22
Servidor P2OS
p2osGetValues
(B=0.062ms)
lockP2os
p2osGetXpos
p2osGetYpos
p2osGetAngle
p2osGetXSpeed
p2osGetYawSpeed
unlockP2os
B=0.02186ms
Servidor Láser
Prio
21
lockLaser
laserazo * 361veces
GetCounLaser
unlockLaser
B=1.1226ms
Tarea actualiza Láser
C=1.867ms
T=397.15ms
P=397.15ms
Prio
19
readLMSValues
(B=0.001ms)
C = Cómputo
T = Periodo
P = Plazo
B = Bloqueo
Figura 6.2: Esquema de las tareas
En la tabla 6.1 se se muestra la información sobre las tareas que se usará para realizar
6. Pruebas realizadas y resultados
39
la planicación. Se va a realizar el test de tiempo de nalización y después se calculará la
utilización del procesador en esta aplicación.[6]
Tarea
INT Láser
INT Micro
Actualiza P2OS
Navegación
Visualización
Actualiza Láser
Servidor P2OS
Servidor Láser
Periodo = Plazo
0.4196
0.833
100
100
200
397.5
Cómputo
0.029
0.029
0.062
50
12
1.867
Bloqueo
0
0
0.02186
1.1226
0.001
0
Techo de prioridad
Prioridad
HW
HW
22
21
20
19
22
21
Cuadro 6.1: Información sobre las tareas.
Test de tiempo de nalización
En esta aplicación las tareas se comunican entre sí a través de los servidores que
guardan los valores correctos del micro y del láser. Para poder realizar una planicación
correcta, se debe estudiar cómo se verán afectadas las prioridades de las tareas al usar
los servicios (funciones) que ofrecen dichos servidores. Se decidió usar un protocolo de
techo de prioridad inmediato, que establece que una tarea que acceda a un recuso hereda
inmediatamente el techo de prioridad del servidor. Este protocolo lo proporciona MaRTE
y es sencillo de comprender.
Para realizar el análisis de cumplimiento de plazos hay que obtener en primer lugar los
tiempos de ejecución de peor caso tanto de las tareas como de los diferentes servicios que
ofrece cada servidor. Estos son los bloqueos entre tareas ejecutándose con un protocolo
de techo de prioridad inmediato:
Bloqueo de las rutinas de interrupción:
Ambas tareas se ejecutan a prioridad hardware (prioridad establecida por MaRTE).
Como se ejecutan a la misma prioridad habrá que tener en cuenta que cualquiera de
las dos tareas puede retrasar a la otra. Para tener esto en cuenta cada tarea tendrá
como termino de expulsión a la otra.
Bloqueo de la tarea que actualiza P2OS:
Seleccionamos los servidores de prioridad mayor o igual que la tarea que actualiza
p2os. Seleccionamos las tareas de menor prioridad y buscamos el servicio más largo
que es llamado por una tarea de menor prioridad en alguno de los servidores anteriores. En este caso la tarea navegación llama a las funciones entre lockP2os y
unlockP2os creando un bloqueo de 0.02186ms.
Bloqueo de la tarea navegación:
De la misma forma calculamos el bloqueo para esta tarea. En este caso el servicio
más largo es utilizar las funciones entre lockLaser, unlockLaser, llamado por la
tarea visualización. Produce un bloqueo de 1.226ms.
Bloqueo de la tarea visualización:
Esta tarea es bloqueada durante tan solo 0.001ms por la tarea actualiza láser con el
servicio readLMSValues que tan sólo bloquea y desbloquea el mutex para cambiar
el valor de la variable que determina el búfer de lectura escritura dentro del driver
del láser.
Bloqueo de la tarea actualiza láser:
No existen tareas de menor prioridad así que la tarea no será bloqueada.
A continuación comprobaremos el cumplimiento de plazos de las tareas calculando el
trabajo requerido al procesador en los plazos de respuesta de cada tarea.
W (Di ) =
X Di
d e ∗ Cj + Ci + Bi ≤ Di
Pj
j<i
(6.1)
Tarea INT láser:
W (D0 ) =
P
j<0 d
D0
e ∗ Cj + C0 + B0 = 0,029 + 0,029 + 0 = 0,058 < 0,4196
Pj
Tarea INT P2os:
W (D1 ) =
P
j<1 d
0,833
D1
e ∗ Cj + C1 + B1 = d
e ∗ 0,029 + 0,029 + 0 = 0,058 < 0,833
Pj
0,4196
Tarea actualiza P2OS:
W (D2 ) =
P
j<2 d
100
100
D2
e∗Cj +C2 +B2 = d
e∗0,029+d
e∗0,029+0,062+0,0218 =
Pj
0,4196
0,833
10,518 < 100
Tarea navegación:
D3
100
100
100
e ∗ Cj + C3 + B3 = d
e ∗ 0,029 + d
e ∗ 0,029 + d
e∗
Pj
0,4196
0,833
100
0,062 + 50 + 1,122 = 61,654 < 200
W (D3 ) =
P
j<3 d
Tarea visualización:
W (D4 ) =
0,062 + d
P
j<4 d
D4
200
200
200
e ∗ Cj + C4 + B4 = d
e ∗ 0,029 + d
e ∗ 0,029 + d
e∗
Pj
0,4196
0,833
100
200
e ∗ 50 + 12 + 1,867 = 134,191 < 200
100
Tarea actualiza láser:
W (D5 ) =
P
j<5 d
D5
397,15
397,15
397,15
e ∗ Cj + C5 + B5 = d
e ∗ 0,029 + d
e ∗ 0,029 + d
e∗
Pj
0,4196
0,833
100
6. Pruebas realizadas y resultados
0,062 + d
41
397,15
397,15
e ∗ 50 + d
e ∗ 12 + 1,867 + 0 = 267,873 < 397,15
100
200
Se puede observar que todas las tareas nalizan antes de su plazo de respuesta y por
lo tanto el test de nalización se supera sin problemas.
Utilización del procesador
La utilización del procesador (U) para n tareas con prioridades asignadas en orden de
frecuencia, se calcula con la siguiente expresión:
U (n) =
n
X
Ci
i=1
Pi
(6.2)
Tras realizar los cálculos correspondientes la utilización total es del 66.83 % para las
6 tareas de la aplicación. El resto del procesador puede ser usado por tareas con menor
prioridad sin problemas.
6.2. Comunicaciones en tiempo real
Para demostrar que la comunicación inalámbrica del robot funcionaba correctamente
se desarrolló la siguiente aplicación. En la gura 6.3 se puede observar un esquema de
los elementos que componen la aplicación. Por un lado se dispone del robot iniciado con
MaRTE constituyendo un nodo de la red RT-WMP (nodo 0). Cualquier otro ordenador
de la sala se puede iniciar con MaRTE (nodo 1) para que haga de estación de control del
robot. Se ha realizado una aplicación que permite:
Manejar el robot desde la estación de control mediante el teclado.
Visualizar en la estación de control los datos más importantes que están disponibles
en el robot.
Con esta aplicación se pretende poner de maniesto que es posible realizar el control del
robot desde un ordenador y mandar los comandos pertinentes al robot. El protocolo sobre
el que se ejecuta la aplicación (RT-WMP) es un protocolo determinista que tiene todos los
tiempos de envío y recepción acotados. La comunicación es determinista y las aplicaciones que se ejecutan sobre el ordenador y el robot también lo son. Este es sólo un ejemplo
sencillo de lo que se puede conseguir utilizando los elementos que se han desarrollado en
este proyecto.
Se establecen las bases para investigar en aplicaciones multi-agente. Por ejemplo con
estos recursos se podrían desarrollar aplicaciones en las que un conjunto de robots comparten información para ampliar o mejorar su conocimiento del entorno. Si uno de los
robots dispone de una cámara y obtiene información importante puede compartirla con
los robots que estén a su alrededor. Si un equipo de robots están realizando una misión en
la cual deben moverse unos cerca de otros y uno de ellos dispone de GPS puede informar
Estación de control
+
+
Da órdenes
&
Visualiza datos
______________________________________________________
|
|
|
*** * ****| Posición
* **
* ** * * * *
|*
|
***** ****| x = 1.454
* **
* ** * * * *
|* *
|
***** ****| y = 0.321
* ***
|***** *******
|
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
|* *
| rot = 0.675
|
****** ***** ****|
|************* *
|
*************** ****
*
*
*
*
*
*
*
*
*
*
*
*
*
*
|
| Velocidad
|
* **
* *
|************* * **** ** ***** ****|
|
trans = 0.1
* **
* *
|************* * **** ** ***** ****|
|
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
* ** **
|********** Láser
| ang = 0.2
|
* **
* *
|************* * **** ** ***** ****|
|
Odometría
______________________________________________________
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
|* *
|
Movimiento
|
|
q:
+
vtrans
w:
+
vrot
|
|
a: - vtrans
s: - vrot
|
|
______________________________________________________
esc: terminar |
|
Teclado
RT-WMP
Robot
+
Ejecuta órdenes
&
Envía datos
Figura 6.3: Navegación del robot a través de comunicación inalámbrica y control.
al resto de la posición en la que están. Estos son sólo algunos ejemplos de las posibilidades
que ofrece un buen sistema de comunicación, y la importancia de hacerlo con restricciones
de tiempo real para aplicaciones de control.
6.3. Resultados
Hasta ahora todo el trabajo que se había realizado sobre los robots se había hecho
sobre Linux utilizando Player. Los robots ejecutan los nuevos algoritmos que se van desarrollando sin problemas aparentes. Es complicado convencer y demostrar a alguien que
este trabajando con los robots como se ha hecho hasta ahora de que trabajar con MaRTE
es una opción mucho mejor. El problema es que los robots se usan con la nalidad de
comprobar si un tipo de aplicación se ha implementado correctamente y poco más. Los
robots hasta ahora no se han usado teniendo en mente conceptos como robustez, determinismo, tolerancia a fallos o rendimiento.
Tras este proyecto todos los dispositivos que se han desarrollado funcionan perfectamente en el robot. La persona que desee realizar una aplicación en MaRTE tiene a su
disposición un conjunto de funciones prácticamente idénticas a las que proporciona Player
para controlar el robot. Existen además otras funciones que se deben conocer y usar para
que las tareas funcionen correctamente en tiempo real.
Para poder ver en que situaciones MaRTE OS permite controlar mejor al robot que
Linux, se realizaron una serie de experimentos. El robot debía moverse en línea recta a
una distancia de 4 metros con diferentes niveles de carga en el sistema y a diferentes
velocidades. Se desarrolló una aplicación para Linux y otra para MaRTE que realizaban
el mismo movimiento. Con esta prueba se pretendía observar si el robot se comportaría
igual en SO diferentes. Los resultados se muestran en la tabla 6.2.
6. Pruebas realizadas y resultados
43
Prueba realizada Velocidad Distancia recorrida (cm) Error (%)
Linux
0.2 m/s
410
2.5
MaRTE
0.2 m/s
402
0.5
Linux
0.4 m/s
420
5
MaRTE
0.4 m/s
404
1
Linux con carga
0.2 m/s
500
25
MaRTE con carga
0.2 m/s
402
0.5
Cuadro 6.2: Resultados obtenidos.
Pruebas sin carga en el sistema
En la primera prueba MaRTE únicamente estaba ejecutando las tareas de la aplicación
que movía el robot cuatro metros hacia delante. Sin embargo en Linux, al existir otros
threads en ejecución, la aplicación que movía al robot no disponía del procesador en los
instantes precisos. Cuando el robot llegaba a los cuatro metros, no se paraba y seguía
andando un poco más. La aplicación tiene que obtener el procesador para leer el valor
de la distancia recorrida, comprobar que es 4 metros y volver a pedir el procesador para
decirle al microcontrolador que tiene que parar las ruedas. Todo ese tiempo que transcurre
desde que el robot llega al objetivo y el microcontrolador recibe la orden, el robot sigue
moviéndose a una velocidad determinada. Cuanto mayor sea la velocidad, mayor será el
error que comete.
Pruebas con carga en el sistema
La siguiente prueba se realizó para demostrar que realmente la carga del sistema estaba provocando los errores que se producían en Linux. Se escribió un pequeño programa
llamado computos con un bucle que realizaba muchos cálculos y por tanto requería mucho procesador. Mediante el comando nice -n -10 computos se lanzó en Linux el programa
con una prioridad del sistema de -10 (la máxima en este SO es -20). El sistema siguió
funcionando y se ejecutó la aplicación que debía mandar al robot a 4 metros. Con el ordenador sobrecargado la aplicación disponía del procesador con mucha menos frecuencia.
Esto provocó que desde que llegó a su objetivo hasta que se pararon los motores, pasó
mucho más tiempo y por lo tanto se desplazo más distancia.
En MaRTE se lanzó la aplicación de la misma forma con otra tarea más que realizaba
los mismos calculos que el programa computos. Se le asignó una prioridad menor que
a las demás tareas del sistema. El resultado fue el mismo que ejecutar la aplicación sin
carga. Esto es debido a que la tarea de menos prioridad no afecta a las demás.
En la tabla anterior se pueden observar los errores cometidos en las diferentes pruebas.
El robot funciona más o menos bien en Linux cuando no hay sobrecarga, pero si en un
momento dado el SO decide realizar otras tareas el robot se ve perjudicado. Esto es un
problema muy grave en una aplicación de control.
Capítulo 7
Conclusiones y trabajos futuros
7.1. Conclusiones
Durante el desarrollo del proyecto se ha estudiado un nuevo SO destinado al control de
tiempo real en aplicaciones empotradas. Los robots disponibles en el laboratorio suponen
una plataforma de trabajo perfecta para poder comprobar la potencia de un SO de estas
características. Se han estudiado diferentes dispositivos y se han programado los drivers
que permiten a MaRTE OS comunicarse con ellos.
Tras varios meses de trabajo están disponibles diferentes herramientas para trabajar
con el robot desde un nuevo punto de vista. Aunque hasta ahora los robots funcionaban
más o menos bien, era indispensable disponer de un SO able para poder afrontar nuevas
aplicaciones con mayores exigencias. Ahora se dispone de los elementos adecuados para
controlar de forma able y determinista los robots.
En el capítulo 6 se han visto diferentes aplicaciones que funcionan perfectamente y
demuestran que este nuevo sistema cumple los objetivos planteados. Además se ha explicado y demostrado porqué un robot ha de trabajar utilizando un SO de tiempo real
como MaRTE. Los resultados ponen de maniesto las limitaciones que tiene un SO de
propósito general como Linux. En denitiva un sistema de control para el robot funciona
mucho mejor en MaRTE que en Linux.
Las herramientas que proporciona este proyecto permiten estudiar mejor diferentes
protocolos y sistemas de tiempo real. La posibilidad de estudiar el protocolo de comunicación RT-WMP en un SO de tiempo real permite denir de forma precisa tiempos de
funciones, retardos, bloqueos, etc. Este es sólo un ejemplo, pero seguro que en el futuro
aparecerán nuevas aplicaciones que utilicen MaRTE.
Al haber trabajado con los diferentes dispositivos a tan bajo nivel, se ha podido comprender mejor el funcionamiento del hardware del robot. Conguraciones nuevas no usadas
anteriormente o comandos que mejoraban el movimiento han sido sólo algunas de las aportaciones.
44
7. Conclusiones y trabajos futuros
45
7.2. Dicultades encontradas
En primer lugar MaRTE es un SO que actualmente está en desarrollo. Pese a que
en la página de distribución de la aplicación se aporta mucha documentación, a veces la
documentación existente no es suciente para encontrar la solución a los problemas que
van surgiendo. Además al tratarse de un SO relativamente nuevo, aparecieron problemas
con algunos drivers.
La línea serie es el elemento fundamental mediante el cual se conectan varios de los
dispositivos del robot. Cuando se afrontó la programación del láser aparecieron errores
debido al uso intensivo que éste hace de la línea serie. Encontrar el fallo y solucionarlo
retrasó el proyecto más de un mes. Finalmente la solución que se encontró pasó a formar
parte de MaRTE OS. El driver PCMCIA para MaRTE tampoco estaba implementado
cuando empezó el proyecto, aunque fue posible usarlo unos meses más tarde.
Por último, el desarrollo de aplicaciones empotradas es un campo en el que no estaba
experimentado. El hecho de programar en un sitio y probarlo en otro (en este caso un
robot) supone invertir muchas horas de trabajo para cargar la aplicación, reiniciar el
robot, etc.
7.3. Trabajos futuros
En el apartado 4.4.2 se explica como se trató de solucionar el problema que presentaba
el controlador de la línea serie en MaRTE. Tras varias semanas se pudo solucionar parcialmente consiguiendo usar el láser a una velocidad de 19200bps pero no a la siguiente
velocidad de 38400bps. Solucionando este problema, el láser podrá ser usado con todo su
potencial.
El protocolo de comunicación RT-WMP no dispone de interfaz para poder usarlo desde un programa Ada. La gestión de tareas en Ada es mucho más exible que en C. Sería
interesante poder juntar las ventajas de Ada y las posibilidades del protocolo.
Hay muchos otros sensores que pueden ser integrados también para MaRTE aumentando así las capacidades del robot. Sería interesante poder usar cámaras desde el punto
de vista del tiempo real.
Pero lo más importante es que se abre un nuevo campo de investigación para aplicaciones robóticas que hasta ahora no estaba disponible. A partir de ahora ya no sólo se van
a poder probar aplicaciones que muevan al robot. Se puede ir más allá y exigir al robot
que realice diferentes tareas tal y cómo se ha planicado previamente. El usuario ahora
controla totalmente lo que hacen los dispositivos, las tareas y el procesador.
Bibliografía
[1] Mario Aldea Rivas y Michael González Harbour. MaRTE OS: An Ada Kernel for
Real-Time Embedded Applications, 2001.
[2] Mario Aldea. Planicación de Tareas en Sistemas Operativos de Tiempo Real Estricto
para Aplicaciones Empotradas, 2002.
[3] Daniel Sangorrin. Hello MaRTE using an emulator, tutorial para MaRTE, Mayo 2005
[4] Daniel Sangorrin. Gestión de dispositivos de entrada/salida analógica, digital y por el
bus serie I2C, proyecto n de carrera, Febrero 2006
[5] Liu, C.L., Layland, J.W.. Scheduling Algorithms for Multiprogramming in a Hard Real-
Time Environment, 1973.
[6] José Luis Villarroel Salcedo. Sistemas de Tiempo Real, apuntes de la asignatura .
[7] Danilo Tardioli y J. L. Villarroel. Real-Time Communications over 802.11: RT-WMP,
The Fourth IEEE International Conference on Mobile Ad-hoc and Sensor Systems,
2007.
[8] Francisco Guerreira. Entorno para la instalación y utilización de manejadores de
dispositivos en MaRTE OS, proyecto n de carrera, Marzo 2003.
[9] José Luis Mantecón. Desarrollo de una librería gráca para MaRTE OS, proyecto n
de carrera, Diciembre 2003.
[10] Óscar García Grasa. Robotización de una aplicación de supervisión agrícola, proyecto
n de carrera, Junio 2007
[11] Pioneer3
&
Pioneer2
H8-Series
http://www.mobilerobots.com.
46
Operation
Manual.
Disponible
en
BIBLIOGRAFÍA
47
[12] GPS Novatel Manual, disponible en http://www.novatel.com/.
[13] L. Montesano, J. Minguez y L. Montano. Modeling the Static and the Dynamic
Parts of the Environment to Improve Sensor-based Navigation. In Proceedings of
the International Conference on Robotics and Automation (ICRA), 2005, Barcelona,
España .
[14] Minguez J,., Montano L. Nearness Diagram Navigation (ND): Collision Avoidance
in Troublesome Scenarios. IEEE Transactions on Robotics and Automation. Vol. 20,
No. 1, 2004.
Apéndice A
Fases del proyecto y diagrama de Gantt
A.1. Hitos temporales
En
Diciembre de 2006 comencé a realizar una beca de colaboración en el laboratorio
de Robótica, Percepción y Tiempo Real del Departamento de Informática e Ingeniería de
Sistemas (DIIS). Durante la beca estudié y realicé diferentes pruebas de la calidad de
la señal en comunicaciones inalámbricas. Además comencé a trabajar con los robots y
conocer su funcionamiento.
En
Abril de 2007 decidí realizar este proyecto. El proyecto une los sistemas de tiempo
real, los sistemas empotrados, los sistemas operativos y la robótica. Estas fueron algunas
de las razones por las que decidí realizar este proyecto. El primer paso fue estudiar a fondo
el sistema operativo MaRTE OS (instalación, método de trabajo, cheros, instalación de
drivers). El siguiente paso fue conseguir tener un sistema de desarrollo adecuado para
trabajar con el robot y arrancar el sistema operativo a través de la red.
En
Junio comencé a analizar, diseñar, implementar y probar cada uno de los drivers
uno por uno. Comencé por el del micro, cuando funcionó completamente pasé al driver del
láser y por último el GPS. Durante toda esta fase fueron apareciendo problemas debido
a que un elemento importantísimo de MaRTE OS no funcionaba correctamente; la línea
serie. Después de muchos quebraderos de cabeza se encontró el problema y se solucionó.
En
Septiembre la Universidad de Cantabria envió el driver de PCMCIA. Este elemen-
to era indispensable para poder integrar la tarjeta inalámbrica en el robot. Se consiguió
hacer funcionar la tarjeta y además se adaptó el protocolo RT-WMP al sistema operativo
MaRTE.
Finalmente en
Octubre se realizaron diversas aplicaciones usando todos los recursos
generados en el proyecto. Navegación autónoma, navegación remota o visualización en
Tiempo Real son algunas de las aplicaciones realizadas.
Hay que destacar que desde la elección del proyecto comencé a recopilar documentos
y redactar los apartados que componen este proyecto. En la gura A.1 se pueden ver con
más detalle todas estas tareas avanzando en el tiempo.
48
A. Fases del proyecto y diagrama de Gantt
49
A.2. Diagrama de Gantt
A continuación se muestra la distribución temporal de las tareas más importantes del
proyecto. También se puede observar que algunas de ellas fueron realizadas en paralelo.
Actividad
Dic Ene Feb Mar Abr May Jun Jul Ago Sep Oct Nov
Comienzo lectura documentos calidad señal
Documentación Robot+ Player/Stage
Realización pruebas robot
Conclusiones calidad señal
Comienzo del Proyecto
Estudio sistema operativo MaRTE
Arranque en red MaRTE
Estudio P2OS + implementación + test
Estudio Láser + implementación + test
Estudio GPS + implementación + test
Revisión linea serie + corrección driver MaRTE
Estudio comunicación inalámbrica + implementación RTWMP en MaRTE + test
Aplicaciones de prueba
Documentación
Figura A.1: Diagrama de Gantt
Apéndice B
Estudio sobre sistemas operativos de
tiempo real
B.1. Arquitectura de un SO de tiempo real
En este capítulo se van a exponer las características más importantes de un sistema
operativo de tiempo real, comparando diferentes aspectos con los sistemas operativos
convencionales. Se tratan temas como las clases de tiempo real dependiendo de la precisión
que necesitemos, el rendimiento, ventajas y desventajas. Al nal se presenta un resumen
de algunos SO de tiempo real existentes.
B.1.1. Arquitectura de un SO de propósito general
La memoria física de un computador está dividida entre el espacio reservado para los
usuarios (user-space ) y el espacio reservado para el kernel (kernel-space ). El kernel multitarea es capaz de manejar múltiples aplicaciones de usuarios que ejecutan en el espacio
de usuario haciendo creer a cada uno que dispone de todo el espacio de memoria y de
todos los recursos hardware. La comunicación entre los programas en el espacio de usuario y el espacio del kernel se realiza a través de las llamadas al sistema. Estas llamadas
típicamente lo que hacen es acceder a recursos físicos compartidos. Todos los accesos a los
recursos hardware son controlados por el kernel de modo que los programas de usuario
no conozcan los detalles físicos de los dispositivos.
Las funcionalidades principales de un SO de propósito general son:
Gestión de procesos. Planicación de procesos.
Gestión de memoria.
Interactuar con el Hardware.
Servidor de Ficheros.
Servidor de Comunicaciones.
La funcionalidad principal y requerida para un sistema operativo de tiempo real es
proveer de un nivel de servicio adecuado a las aplicaciones que requieran una respuesta
50
B. Estudio sobre sistemas operativos de tiempo real
51
en un intervalo de tiempo determinado.
La característica principal de un sistema operativo de tiempo real es la respuesta ante
eventos internos ó externos, tales como interrupciones hardware externas, interrupciones
software internas ó interrupciones de reloj internas, es decir los requerimientos temporales.
Una de las medidas de rendimiento de un SO de tiempo real es la latencia, ó tiempo
desde que ocurre el evento y éste es tratado. La otra medida es el jitter, ó variaciones en
el periodo normal de ocurrencia de eventos periódicos.
Todos los sistemas operativos tienden a tener una baja latencia y un bajo jitter, pero
los sistemas operativos de tiempo real requieren que esos valores estén determinados y
que no dependan de la carga del sistema.
B.1.2. Clases de tiempo real
Un programa ó un sistema operativo es considerado como de tiempo real, si a pesar de
las restricciones de tiempo le permiten trabajar y funcionar correctamente. Se distinguen
las siguientes clases:
Tiempo real estricto (Hard Real Time ): Todas las acciones deben ocurrir dentro
del plazo especicado.
Tiempo real exible (Soft Real Time ): Se pueden perder plazos de vez en cuando.
El valor de la respuesta decrece con el tiempo.
Tiempo real rme (Firm Real Time ): Se pueden perder plazos ocasionalmente.
Una respuesta tardía no tiene valor.
B.1.3. Características de rendimiento
El criterio fundamental de evaluación del rendimiento de un sistema operativo de
tiempo real es la latencia y el periodo del jitter ante un evento. Un evento es cualquier
tipo de interrupción, tanto interna, como externa.
Latencia en un evento.
Un evento puede ser tanto una interrupción hardware como una interrupción software.
La latencia ante una interrupción hardware es el tiempo desde que se produce la
interrupción hasta que se ejecuta la primera instrucción de la rutina de tratamiento.
Puede haber retrasos debido al acceso al bus.
La latencia ante una interrupción software es el tiempo desde que la señal es generada hasta que la primera instrucción de la tarea es ejecutada. Aquí el valor depende
únicamente del acceso a los registros del procesador.
Periodo del jitter.
El periodo del jitter se reere a las variaciones en el tiempo que experimenta una
tarea cuando se ejecuta de manera repetitiva.
B.1.4. Arquitectura de un SO de tiempo real
El objetivo de un sistema operativo de tiempo real es reducir la latencia y el jitter en
las interrupciones, tanto internas como externas, al orden de microsegundos.
Es decir, la parte fundamental para convertir un sistema operativo de propósito general en un sistema operativo de tiempo real es el manejo de las interrupciones.
El procesamiento de interrupciones en el kernel estándar está divido en 2 tareas. Una
tarea que se encarga de leer los datos del dispositivo físico y escribirlos en un búfer, es lo
que se conoce como manejador de interrupciones, y una tarea que se encarga de pasar los
datos del búfer a otro para que sean accesible por el kernel. Con este esquema, cuando
el manejador está ejecutando, todas las interrupciones están inhibidas con el siguiente
retardo impredecible en el servicio de otras interrupciones que se puedan haber producido
y por tanto en los valores de latencia y jitter.
Para conseguir reducir la latencia y el jitter se han desarrollado distintas alternativas
que modican el kernel de Linux en este aspecto fundamentalmente.
Actualmente hay dos corrientes de diseño:
Atención prioritaria en el kernel estándar (Preemptable kernel )
Esta metodología modica el kernel en profundidad de forma que los procesos de
kernel ejecuten con máxima prioridad de forma que puedan interrumpir a procesos
de menor prioridad en el acceso a los recursos que necesiten.
Esta metodología implica cambios en los manejadores de interrupciones para que
las interrupciones de alta prioridad no sean bloqueadas por el manejador de interrupciones mientras está manejando otra de menor prioridad.
El resultado de esta metodología es una latencia y un jitter del orden de 1 milisegundo en un Pentium a 100 Mhz. A partir de la versión 2.5.4 del kernel de Linux
se incorpora esta metodología.
B. Estudio sobre sistemas operativos de tiempo real
53
Como se puede observar en la gura la tarea de tiempo real está controlada por el
planicador del kernel y es una más de las tareas que controla el kernel. Esta tarea
hace referencia a los procesos de tiempo real en el espacio de usuario. El planicador
sabe que las tareas de tiempo real tiene mayor prioridad que las tareas que no son
de tiempo real.
Como se puede comprobar esta metodología es adecuada para aplicaciones de audio y vídeo donde el periodo de interrupciones es del orden de 1 milisegundo, pero
inadecuado cuando ya hablamos de menos de 1 milisegundo.
Benecios y limitaciones de la estrategia de kernel preemptable :
Ventajas
Desventajas
Desarrollo de aplicaciones de tiempo real más fácil El rendimiento no es lo suficientemente bueno
para los requerimientos de baja latencia en el
rango de microsegundos
Protección de memoria disponible
El peor caso de latencia de una interrupción es
desconocido ya que no es posible testearlo
Los programas de tiempo real no pueden quebrar
el kernel
Cambio fuerte en el código fuente del kernel
Acceso completo a los servicios del sistema (TCP/IP,Cada vez que sale una nueva versión del kernel
I/O)
es necesario un test profundo
Threads de POSIX disponibles para las funciones de Para realizar el análisis de funcionamiento son
tiempo real
necesarios todos los drivers de dispositivos y
módulos
Soporte de herramientas para facilitar la
depuración
Rendimiento global del sistema reducido
Modicaciones sobre el kernel estándar (Patch )
Existen 4 estrategias de modicación del kernel de Linux para proveer capacidades
de tiempo real. Tres de ellas implican añadir un segundo kernel (dual) para manejar
las tareas de tiempo real y el cuarto implica modicar directamente el código del
kernel para añadir características de tiempo real.
Benecios y limitaciones de la estrategia de kernel dual:
Ventajas
Cambios de contexto y latencia de interrupciones
muy bajo (5 - 10 microsegundos)
Desventajas
Todas las características de tiempo real deben
ser implementadas como módulos
El kernel estándar de Linux ejecuta como una tarea El desarrollo de aplicaciones de tiempo real es
de baja prioridad del microkernel
mucho más complicado
Capa de abstracción hardware e interrupciones
Se debe ser conocedor de Linux en profundidad
Garantizada una planificación determinística
Interacción entre el kernel y los drivers de los
dispositivos
Código incorrecto puede provocar el fallo del
kernel
Más difícil depurar el código
Las llamadas al sistemas de Linux no pueden
tomar el control y el rendimiento no puede ser
garantizado
•
Micro-kernel
Esta estrategia añade un segundo kernel que en realidad es una capa interfaz entre el hardware y el kernel estándar, lo que se llama tradicionalmente
HAL Hardware Abstraction Layer . Esta capa, micro-kernel, controla la ejecución de las tareas de tiempo real y ejecuta el kernel estándar como una tarea
en background, es decir, el kernel estándar sólo ejecuta cuando no hay tareas
de tiempo real pendientes.
Una implementación de esta estrategia es ADEOS. Los desarrolladores de este
proyecto fueron precisamente los que pusieron el nombre de nano-kernel para
diferenciarlo claramente de la estrategia de micro-kernel patentado por Yodaiken.
•
Extensión con un nuevo kernel de acceso a los recursos (Recurso-kernel ) Esta
estrategia añade un kernel de forma que éste proporciona una puerta de acceso
a los recursos, tales como al sistema de cheros, al puerto paralelo, etc, tanto
para el kernel estándar como para los procesos de usuario. El recurso kernel no
sólo captura las interrupciones sino que proporciona un mecanismo donde los
programas de usuario pueden requerir, reservar y garantizarse un porcentaje
nito de los recursos como pueden ser de CPU, memoria, etc.
•
Extensiones POSIX de tiempo real añadidas al kernel
Esta estrategia consiste en modicar directamente el kernel estándar de Linux
para añadir librerías que implementan las extensiones de tiempo real de POSIX. El resultado es un kernel conforme al estándar IEEE 1003.1d. No añade
un segundo kernel.
B. Estudio sobre sistemas operativos de tiempo real
55
Las modicaciones realizadas al kernel consisten en la implementación de relojes, señales, semáforos, memoria compartida, planicador por prioridades, etc
según lo especicado en IEEE 1003.1d.
Existen 2 aproximaciones diferentes para esta estrategia:
•
KURT (The Kansas University Real Time Linux) que únicamente implementa
los relojes conforme al estándar IEEE 1003.1d.
•
TimeSys Linux. Añade al preemptable kernel un planicador de kernel que
proporciona una latencia y un jitter menor de 100microsegundos. El parche
con el planicador no proporciona una alta resolución en los relojes, que es
necesaria para tareas de tiempo real repetitivas.
B.1.5. Rendimiento del sistema
Si comparamos por ejemplo el kernel estándar con RTLinux podremos observar claramente como existe gran diferencia tanto en la latencia en las interrupciones como en
el jitter, siendo mucho menos para el caso de RTLinux y siempre en el orden de 1 a 10
microsegundos para un Pentium a 100Mhz.
Si comparamos entre si las distintas estrategias de diseño de un sistema operativo de
tiempo real podremos observar que las diferencias no son tan amplias si las comparamos
con el kernel estándar.
SO estándar
Aplicación
No Tiempo-Real
Latencia/Jitter
100µs a 100ms
Linux(>2.5.X)
estándar
IEEE 1003.1d
Soft Real-Time
1ms
Hard Real-Time
10 a 100µs
Micro-Kernel
Hard Real-Time
1 a 10µs
RTOS Kernel
Hard Real-Time
1 a 10µs
B.2. Algunos de los SO de tiempo real más usados
B.2.1. Introducción
Vamos a realizar una breve descripción de la arquitectura, licencia y entorno para el
cual están diseñados los S.O.T.R. que hemos escogido. Algunas de éstos están en continuo
desarrollo y otros por el contrario están un poco estancadas ó denitivamente olvidadas,
pero que son nombrados porque nacieron con el objetivo de proporcionar una nueva
característica ó una nueva losofía de diseño que otros S.O.T.R. no proporcionaban y que
otras han seguido posteriormente.
Distribución
ADEOS
RT-Linux
MaRTE
VxWorks
Licencia
GNU/GPL
Comercial
GNU/GPL
Comercial
B.2.2. ADEOS (Adaptative
tems )
Arquitectura
Nano-kernel
Micro-kernel
Extensiones POSIX
Micro-kernel
Domain Environment Operating Sys-
El objetivo de ADEOS es proporcionar un entorno exible para compartir los recursos
hardware para múltiples sistemas operativos ó múltiples instancias de un mismo sistema
operativo.
ADEOS activa múltiples kernels, llamados dominios, que existen simultáneamente sobre el mismo hardware. Ninguno de éstos dominios necesariamente conoce la existencia
del resto, pero todos ellos si conocen de la existencia de ADEOS. Un dominio puede ser
un SO completo, pero no necesariamente.
La licencia de ADEOS es GNU/GPL. La arquitectura de ADEOS es la de kernel dual
y más especícamente la llamada Nano-kernel.
Dominios y Pipeline.
Para permitir que las interrupciones y los eventos del sistema sean repartidos para
compartir por los múltiples kernels (normalmente SO completos), ADEOS dene lo que
ha llamado abstractamente "dominio". Un dominio es un componente software del kernel
base al cuál ADEOS puede noticar:
Las interrupciones hardware.
Llamadas al sistema de las aplicaciones Linux.
Eventos del sistema lanzados por el kernel de Linux.
Otros eventos que personalicemos nosotros.
Un dominio puede ser accesible como un módulo dinámico del kernel, ó como uno estático formando parte de una imagen del kernel, no produciendo ningún tipo de incidencia
en el comportamiento de ADEOS.
ADEOS también puede asegurar que los eventos sean disparados en el orden correcto
para los distintos dominios denidos, gracias a ello, es posible proporcionar determinismo.
Esto nos permite asignar a cada dominio una prioridad estática. El valor de esta prioridad
B. Estudio sobre sistemas operativos de tiempo real
57
determina el orden en que los eventos son tratados por los dominios. Todos los dominios
son encolados de acuerdo a sus respectivas prioridades, formando un pipeline de forma
abstracta, que es el que usa ADEOS para manejar el ujo de eventos desde el más prioritario hacia el menos prioritario. Los eventos de entrada son encauzados a la cabecera del
pipeline (dominio más prioritario) y progresan hacia la cola (dominio menos prioritario).
El código del kernel de Linux es enteramente el sólo un dominio especial predenido,
que es creado por ADEOS en las primeras etapas de carga de Linux. Este dominio inicial
normalmente hace referencia al dominio "root "hasta que la infraestructura proporciona
lo suciente para cargar el resto de dominios dinámicamente (ej. el módulo cargador del
kernel ).
Modo de Trabajo.
ADEOS controla todas las interrupciones, los traps de la CPU y las excepciones del
nivel hardware, ya que reprograma el software del manejador. De hecho, ADEOS actualmente reemplaza los manejadores instalados anteriormente por Linux durante el arranque
por los suyos propios para las correspondientes interrupciones y eventos. En la plataforma
x86, se hace simplemente cambiando el descriptor de interrupción de la tabla.
En cualquier momento dada una CPU con ADEOS activado, un dominio puede estar:
Ejecutándose.
Interrumpido por un dominio más prioritario durante el procesamiento de una interrupción/ evento de entrada mientras el estaba procesando un evento pendiente.
Voluntariamente autosuspendido, después de que todas las interrupciones/eventos
hayan sido procesados.
Cuando un dominio ha nalizado de procesar una interrupción/evento que ha recibido, llama a un servicio especial de ADEOS (adeos_suspend_domain() ) el cual provoca
que se pase la interrupción/ evento al siguiente dominio del pipeline y así sucesivamente,
realizándose un ciclo del más prioritario al menos prioritario.
Hay que destacar que ADEOS reanuda un dominio sólo si tiene que procesar una interrupción/evento ó si ocurre que ha sido interrumpido por un dominio más prioritario que
ha recibido alguna interrupción/ evento para procesar, en otras palabras, no se produce
intercambio entre dos dominios a menos que haya trabajo pendiente para alguno de ellos.
Cuando una interrupción ocurre en un sistema ocioso, ADEOS despierta al dominio más
prioritario interesado en ella y el ciclo de proceso del pipeline comienza de nuevo.
¾Por qué puedes necesitar ADEOS?
Porque necesitas controlar determinísticamente el ujo de interrupciones hardware
usando una capa software antes de que el kernel de Linux las procese. Este control
incluye la interceptación, el enmascarado y/o la priorización de las interrupciones.
Porque necesitas monitorizar las llamadas al sistema de Linux, añadiendo más información y sin tener que modicar el código de las llamadas al sistema.
Porque quieres un mecanismo para monitorizar los eventos internos que ocurren en
el kernel de Linux como pueden ser la planicación de tareas, la creación de procesos
ó las señales que capturan las tareas.
Implementación de un dominio.
El interfaz entre un dominio y ADEOS esta compuesto de:
Un descriptor, que es una estructura de datos que describe las propiedades del
dominio en el tiempo.
Una rutina de entrada al dominio, a la cual ADEOS llama para iniciar un dominio.
Esta rutina se encarga de registrar el conjunto de interrupciones/ eventos que va a
manejar y a continuación el dominio pasa a ejecutar el bucle ocioso.
Enlaces:
ADEOS (web ocial distribución) http://www.opersys.com/adeos/
ADEOS (web ocial desarrollo) https://gna.org/projects/adeos/
Documentos:
Diseño Adeos: http://gayuba1.datsi..upm.es/ dlopez/cache/doc/adeos.design.pdf
Adeos: http://gayuba1.datsi..upm.es/ dlopez/cache/doc/porting.txt RTOS sobre
ADEOS: http://gayuba1.datsi..upm.es/ dlopez/cache/doc/rtos.over.adeos.pdf
B.2.3. RTLinux
RTLinux es un SO de tiempo real que ejecuta Linux como un thread de menos prioridad
que las tareas de tiempo real. Con este diseño, las tareas de tiempo real y los manejadores de interrupciones nunca se ven retrasados por operaciones que no son de tiempo real.
La primera versión de RTLinux estaba diseñada para ejecutarse en la plataforma x86
y proporcionaba una pequeña API y un pequeño entorno de programación. La versión 2,
que fue totalmente reescrita, fue diseñada para el soporte de multiprocesamiento simétrico
(SMP) y para ser ejecutada en una amplia variedad de arquitecturas.
RTLinux proporciona la capacidad de ejecutar tareas de tiempo real y manejadores de
interrupciones en la misma máquina que el Linux estándar. Estas tareas y los manejadores
ejecutan cuando se necesitan en detrimento de lo que estuviera ejecutando Linux. El peor
caso de tiempo es entre que se detecta la interrupción hardware y el procesador ejecuta
la primera instrucción del manejador de la interrupción. Este tiempo es del orden de los
10 microsegundos en la plataforma x86.
Actualmente hay 2 versiones de RTLinux:
B. Estudio sobre sistemas operativos de tiempo real
59
RTLinux/Open: Disponible bajo la licencia GPL, pero que ya no se trabaja en ella
desde 2001.
RTLinux/Pro: Distribución comercial.
Ambas versiones son distribuidas por la empresa FSMLabs.
La arquitectura de diseño de RTLinux se encuentra patentada por FSMLabs. Una
versión de la patente se encuentra accesible en el enlace:
http://www.fsmlabs.com/products/rtlinuxpro/rtlinux_patent.html. Y en aquí se puede
ver que la FSF (Free Software Foundation ) esta de acuerdo en los términos de la patente.
http://www.gnu.org/philosophy/rtlinux-patent.html
A través de este otro enlace podemos leer una pequeña reexión sobre los efectos de
la patente en el desarrollo de aplicaciones en RTLinux:
http://www.linuxdevices.com/articles/AT2094189920.html.
A partir de aquí la descripción que se hace es sobre RTLinux/Open o RTLinux/GPL.
Arquitectura.
RTLinux es un pequeño y rápido sistema operativo que sigue el estándar POSIX
1003.13: sistema operativo de tiempo real mínimo. RTLinux añade una capa de abstracción
hardware entre el kernel estándar de Linux y el hardware de la máquina.
Hay 3 modicaciones principales en el kernel de Linux con el objetivo de que RTLinux
tenga el control del hardware de la máquina:
Control directo de las interrupciones hardware.
Control del reloj hardware e implementación de un reloj virtual para Linux.
El control de las interrupciones por parte de Linux es reemplazado por 2 funciones
que permiten activar ó desactivar las interrupciones, pero las virtuales.
Estas modicaciones del kernel de Linux son complejas aunque no requieren excesivo código, pero si más que RTAI. RTLinux proporciona un entorno de ejecución bajo el
kernel de Linux, como consecuencia de esto, las tareas de tiempo real no pueden usar los
servicios de Linux. Para disminuir este problema, el sistema de tiempo real se ha divido
en dos partes: la capa de tiempo real estricto que ejecuta encima de RTLinux, y la capa
de tiempo real exible, que ejecuta como un proceso normal de Linux. Para la comunicación de ambas capas se pueden usar varios mecanismos (FIFO, memoria compartida). La
propuesta de 2 capas es un método útil para proporcionar tiempo real estricto mientras
se mantienen las características de escritorio de un sistema operativo. La separación del
mecanismo del kernel de tiempo real del mecanismo del kernel de Linux de propósito
general permite optimizar ambos sistemas de forma independiente.
Características.
Soporte de múltiples arquitecturas y válida para arquitecturas multiprocesador.
Gestión de procesos: Planicación, soporte de threads periódicos, amplio rango de
prioridades, creación y borrado de threads, etc.
Gestión de memoria: No protección de memoria en el kernel y no asignación de
memoria de forma dinámica.
Comunicación entre procesos: Semáforos, Mutex, control de inversión de prioridades,
memoria compartida y FIFO's.
Tiempo y relojes: Resolución de nanosegundos. No relojes de usuario. Facilidades
para añadir nuevos relojes hardware.
Programación de drivers: Se proporcionan funciones de acceso a dispositivos.
No proporciona herramientas de calidad de servicio.
Enlaces:
Página Ocial (http://www.fsmlabs.com, http://www.rtlinux.com, http://www.rtlinux.org)
Repositorio RTLinux GPL: http://www.rtlinux-gpl.org
Análisis RTLinux/GPL: http://www.mnis.fr/opensource/ocera/rtos/c1450.html
B.2.4. MaRTE
Aunque es el sistema operativo tratado en el proyecto y ya se ha hecho una descripción
de él, pondremos los aspectos tratados en las secciones anteriores en forma de comparativa.
Es un SO mínimo de tiempor real para aplicaciones empotradas, que puede ser usado
en diferentes plataformas, incluyendo microcontroladores.
Cumple un subconjunto POSIX.13.
Ofrece los interfaces POSIX para los lenguajes C y ADA.
Permite el desarrollo cruzado de aplicaciones de tiempo real C y ADA.
Permite el desarrollo de aplicaciones C-ADA.
Arquitectura.
La parte central del sistema operativo MaRTE está en su kernel, el cual implementa
las funcionalidades básicas del sistema. El kernel tiene una interfaz abstracta de bajo
nivel para el acceso al hardware. Esta interfaz encapsula operaciones tales como: manejo
de interrupciones, manejo del reloj y del tiempo y cambios de contexto en los threads. El
B. Estudio sobre sistemas operativos de tiempo real
61
objetivo de esto es facilitar la migración desde una plataforma a otra, ya que lo único que
sería necesario cambiar es la capa de abstracción del hardware.
En la parte de arriba del kernel hay una interfaz para aplicaciones POSIX.1 (actualmente funciones Ada con la forma de funciones POSIX.1). Esto proporciona dos importantes ventajas:
Aplicaciones C pueden usar el kernel directamente, solo son necesarias un conjunto
de cabeceras C.
La capa de bajo nivel GNARL está por encima de la interfaz POSIX. Esta capa es
para adaptarlo al kernel
La distribución GNAT que se ha adaptado para que funcione en el sistema operativo
MaRTE es la versión estándar desarrollada para Linux.
Características.
Apropiado para aplicaciones estáticas con el números de tareas y recursos del sistema
conocido en tiempo de compilación.
Los servicios tendrán tiempo de respuesta limitados.
No está protegido.
Multiplataforma.
Multilenguaje.
Entorno de Desarrollo.
El entorno de desarrollo es en un PC con Linux. Y el destino para el que se desarrolla
en una máquina x86 desnuda. Ambos sistemas están conectados por medio de una red
de área local Ethernet (para aplicaciones de arranque) y un cable seria (para depuración
remota). El compilador y el linker están basados en GCC y GNAT.
El ciclo de desarrollo de una aplicación es bastante rápido e incluye los siguientes
pasos:
1. El destino es arrancado con un disco netboot el cual es generado automáticamente
durante la instalación del sistema operativo MaRTE.
2. La aplicación es compilada y enlazada en el ordenador de desarrollo usando los
comandos mgnatmake o mgcc.
3. En la máquina destino el programa netboot descarga la aplicación que está en el
ordenador de desarrollo a través de la Ethernet y lo ejecuta.
4. La aplicación se ejecuta libremente o es depurada remotamente desde el ordenador
de desarrollo.
5. Tan pronto como la aplicación naliza el programa netboot de nuevo toma el control
de la máquina destino y un nuevo ciclo puede empezar desde el paso 2.
Enlaces.
Sitio Ocial. http://marte.unican.es
B.2.5. VxWorks
Es un componente run-time de la plataforma de desarrollo de sistemas empotrados
Tornado II (Windows y UNIX). Hay dos versiones de VxWorks: VxWorks a secas, que es
de la que hablaremos aquí. Y VxWorks AE, que está diseñado especialmente para alta
disponibilidad con la ayuda distribuida de la mensajería y de la alta tolerancia.
Características.
Herramientas de desarrollo cruzado host-target:
•
Compilador, Linkador y Cargador para el sistema target.
•
Depurador remoto.
•
Determinación de tiempos de ejecución.
•
Simulador del sistema sobre el host.
Soporte de un gran número de placas comerciales mediante Board Support Packages
(más de 200), así como de placas a medida:
•
Inicialización del HW.
•
Conguración de interrupciones y temporizadores
•
Memory mapping, etc.
Consta de una interfaz con varias APIs (más de 1800 funciones). Es utilizado en diferentes tipos de aplicaciones: desde automoción (Antilock Braking Systems ) a aplicaciones
espaciales (Mars PathFinder ), equipamiento de ocina (impresoras, faxes, etc.) y electrodomésticos (microondas, lavavajillas, etc.). Está adaptado a diferentes arquitecturas de
CPU tales como: PowerPC, Intel 80x86, Motorola 68K, Intel 80960, ARM, SPARC, etc...
Arquitectura.
La arquitectura está basada en microkernel, dicho microkernel lo han llamado wind
de unos pocos KB que incluye:
Planicador multitarea basado en prioridades y con desplazamiento, el cual consta
de 256 prioridades y tiene limitado el número de tareas.
Primitivas de sincronización y comunicación entre tareas.
B. Estudio sobre sistemas operativos de tiempo real
63
Soporte a interrupciones.
Gestión de watchdog timers.
Gestión de memoria.
Al tener una arquitectura modular, el sistema nal puede ser ampliado con diferentes
módulos tales como: sistema de E/S, sistemas de cheros soporte para redes, etc.. Por lo
tanto el sistema nal es adaptable a cientos de conguraciones diferentes ya que incluso
los diferentes módulos son escalables. Los módulos individuales pueden ser utilizados durante el desarrollo y ser omitidos en el sistema nal. Es compatible con la norma POSIX
1003.1 (llamadas básicas al sistema) y 1003.1b (real-time extensions ).
Enlaces.
Sitio Ocial de VxWorks:
http://www.windriver.com/products/device_technologies/os/vxworks6/
http://dmi.uib.es/ aortiz
Apéndice C
P2OS: El Sistema Operativo del
microcontrolador.
C.1. Introducción
Para la realización del proyecto se ha usado un robot Pioneer 3-AT, distribuido por la
empresa ActivMedia Robotics. Este robot contiene todo tipo de sensores y componentes
de navegación que le permiten moverse en un entorno real. Es una plataforma perfecta
para una gran variedad de proyectos de investigación.
A continuación se resume el contenido de [11], dejando claros los puntos más importantes del manual. Para una especicación más detallada consultar [11].
C.1.1. Especicaciones técnicas
Cada robot esta hecho con un cuerpo de aluminio, un sistema de movimiento (dos o
cuatro ruedas), motores DC reversibles, electrónica de control del motor y conducción,
encoders de movimiento de alta resolución, y baterías de larga duración. Todo ello soportado por un microcontrolador embebido sobre el cual está instalado el sistema operativo
P2OS C.2, que distribuye ActivMedia.
El robot actualmente presenta las siguientes características hardware:
CPU Intel Pentium III 850-MHz con 256 MB memoria RAM.
1 Láser Sick LMS
1 Microcontrolador H8-Series. Controla odometría (posición), giróscopo , sonar y
bumpers.
1 GPS Novatel.
1 Tarjeta Wi-Fi Conceptronics PCMCIA para comunicación inalámbrica a través
de un adaptador PCI 104.
64
C. P2OS: El Sistema Operativo del microcontrolador.
65
C.2. El Sistema Operativo del robot. P2OS
La arquitectura de control del robot es de tipo cliente-servidor. Por un lado está el
microcontrolador H8-Series dirigido por el P2OS (servidor) y por otro el PC del robot
(cliente) conectados mediante el puerto serie.
El servidor se encarga de controlar las operaciones de bajo nivel, como manejar los
motores, lanzar el sonar, almacenar los valores del sonar y de la información de las ruedas,
y otras muchas cosas. El cliente manda comandos para que el servidor los ejecute.
Para comunicarse entre ambos se usan dos tipos de paquetes:
Comand packet : Cliente ->Servidor. El cliente manda al servidor paquetes con
los comandos que quiere que el microcontrolador ejecute en los dispositivos a los que
accede. Por ejemplo, el cliente manda un comando de tipo VEL 2 al servidor.
Cuando el P2OS recibe ese comando ordena a los motores correspondientes que se
muevan a la velocidad correspondiente. Para ver una descripción completa de los
comandos ver [11].
Server Information Packet (SIP) : Servidor ->Cliente
. El servidor envía
cada 100 ms un paquete llamado SIP con información relativa a los dispositivos que
controla. Se obtiene información de la odometría (posición), sonar, batería, bumpers,
velocidad, etc.
Ambos paquetes son cadenas de bits formadas por cinco elementos principales: una cabecera de dos bytes, un byte con el número de bytes que siguen, el comando o paquete
SIP, los parámetros del comando o los datos del paquete SIP, y nalmente, dos bytes de
checksum. Cada paquete está limitado a 206 bytes.
Los diferentes tipos de paquetes se pueden ver en el manual extenso del microcontrolador ([11]). Por su extensión no se expondrán aquí.
C.2.1. Conexión Cliente-Servidor
Antes de poder ejecutar ningún control sobre el robot, debe de ejecutarse una aplicación cliente que establezca una conexión con el servidor del robot a través del puerto serie.
Después de establecer la conexión el cliente podrá enviar comandos y recibir información
del servidor.
Cadena de sincronización:
Para establecer la conexión el cliente debe enviar tres comandos de sincronización
SYNC0, SYNC1 y SYNC2. La secuencia de bytes en hexadecimal que el cliente debe
enviar es la siguiente:
SYNC0: 0xFA, OxFB, 0x03, 0x00, 0x00, 0x00
SYNC1: 0xFA, OxFB, 0x03, 0x01, 0x00, 0x01
SYNC2: 0xFA, OxFB, 0x03, 0x02, 0x00, 0x02
Autoconguración:
Tras el comando SYNC2 el servidor manda al cliente los valores que tiene grabados
en su memoria ash sobre el nombre (Nombre del robot en cuestión), clase (Pioneer) y subclase (P2AT8, P2DX, ..) del robot. Con esta información el cliente podrá
ajustar los parámetros concretos del robot en su aplicación.
Abrir el servidor: OPEN
Este es el siguiente comando que tiene que mandar el cliente para que el servidor
comience diferentes servicios, como el sonar, los controladores del motor, escuche
los comandos del cliente, y comience a transmitir paquetes de información (SIP).
Comando en hexadecimal: 0xFA, OxFB, 0x03, 0x01, 0x00, 0x01
Mantener vivo al servidor: PULSE
El microcontrolador tiene un watchdog de 2 segundos (parámetro congurable en
la ash) que controla de forma segura el robot. Si en un periodo de 2 segundos no
llega ningún comando del cliente, esto indicará que el cliente ha perdido el control
del robot y este dejará de moverse. En el momento que se reciba un comando el
robot volverá a moverse. Si nuestra aplicación tiene periodos en los que el cliente
no manda ningún comando al servidor, se deberá mandar frecuentemente (menos
de 2 segundos) el comando PULSE para evitar que el watchdog salte. Comando en
hexadecimal: 0xFA, OxFB, 0x03, 0x00, 0x00, 0x00
Cerrar el servidor: CLOSE
Para cerrar la conexión con el servidor, parando los motores, sonar y demás funciones del servidor. Comando en hexadecimal: 0xFA, OxFB, 0x03, 0x02, 0x00, 0x02
C.2.2. Comandos de movimiento
El servidor P2OS que controla el motor acepta comandos de dos tipos.
Control directo de las ruedas
En este modo, el cliente debe de mandar un comando de translación (VEL) y después otro de rotación (ROTATE). Este modo es mucho más preciso.
Control directo del movimiento
De esta otra forma, el cliente manda un comando de tipo VEL2 con dos argumentos
que indican la velocidad para las ruedas de cada lado del robot. Esto requiere, que
C. P2OS: El Sistema Operativo del microcontrolador.
67
el cliente calcule, a partir de la translación y rotación deseadas, los dos valores de
los parámetros para componer el comando.
El robot establece su posición a partir de las lecturas de los encoders que controlan
cada rueda del robot. Mantiene la posición de sus coordenadas internas y las envía en el
paquete de información SIP. Los valores devueltos son la posición en x (xpos), en y (ypos)
y la dirección (Thpos).
Estos valores representan la odometría del robot y sólo son válidos para tratar las
variaciones de estos en pequeños movimientos. Se debe a que el movimiento del robot
depende del entorno y si una rueda derrapa creerá estar en una posición, pero realmente
está en otra. En supercies deslizantes el robot trabaja peor que en supercies rugosas.
C.2.3. Sonar
Cuando el cliente se conecta al servidor, el P2OS inicia directamente el sonar, mandando la información de este a través de los paquetes de información (SIP). Se puede
usar el comando SONAR para habilitar o deshabilitar todos o algunos de los dispositivos
sonar. Existen además otros dos comandos POLLING y SONAR_CYCLE. El primero
establece la secuencia para lanzar cada uno de los sonar y el segundo para cambiar la
frecuencia con la que se lanzan.
C.2.4. Emergencias y paradas
El robot Pioneer va equipado con sensores de contacto en la parte delantera y trasera.
Cuando alguno de los sensores se activa (toca un obstáculo) se produce una parada de
emergencia. P2OS permite activar o desactivar dichos sensores con el comando BUMPSTALL. Además se puede congurar en la ash la acción que realizará el sensor al detectar
un contacto (por defecto parada de emergencia).
Apéndice D
El láser SICK LMS
D.1. Información básica sobre el láser
Nota: Esta es una versión resumida en castellano de las hojas de especicación del
fabricante del láser SICK LMS. Si desea información completa y más especica consulte
el Manual rápido de LMS en www.sick.es.
El Sistema de Medida Láser LMS 200, LMS 220, LMS 211, LMS 221, LMS 291 está
basado en el principio de la medida del tiempo-de-vuelo (Radar Láser). Un único pulso
láser es enviado fuera y reejado por la supercie de un objeto dentro del rango del sensor.
El tiempo transcurrido entre la emisión y la recepción del pulso del láser sirve para calcular
la distancia entre el objeto y el LMS. Mediante un espejo rotatorio integrado los pulsos
del láser barren un rango en forma de radio en frente de la unidad LMS. Se dene de
esta forma un campo o área de detección de dos dimensiones. Los principales benecios
de estos principios de medida son:
Detección de objetos independientemente del color o la textura que tengan.
Detección able de la presencia de objetos.
Figura D.1: Principio de medida y rango angular de LMS
LMS ofrece solución a una gran cantidad de aplicaciones:
Determina el volumen de los objetos (medición de paquetes, palets, contenedores )
Determina la posición de los objetos (palets, contenedores, cintas transportadoras )
Previene la colisión de vehículos
68
D. El láser SICK LMS
69
Controla procesos de atraque (posicionamiento)
Clasicación de objetos (detección de vehículos)
Automatización de procesos
.. y muchas más
D.2. Software. Mecanismo de comunicación
D.2.1. Esquema de funcionamiento para la comunicación con LMS
Figura D.2: Resumen del funcionamiento de las comunicaciones con LMS
D.2.2. Establecer la comunicación con LMS
Después de encender el láser, el led amarillo y el rojo se encenderán hasta que el
proceso de inicialización haya sido completado. Solo cuando el led verde o el rojo esté
activo, la unidad estará lista para la comunicación. Además, un mensaje de inicialización
es enviado a la velocidad de 9600 bps a través del puerto serie al PC conectado.
Mensaje de inicialización en hexadecimal LMS -> PC
02 80 17 00 90 4C 4D 53 32 30 30 3B 33 30 31 30 3633 3B 56 30 32 2E 31 30 20 10 72 D0
Para probar la conexión con el LMS conectado, se recomienda enviar el comando de
estado al LMS. El comando de petición de estado para el LMS es:
Mensaje en hexadecimal PC -> LMS
02 00 01 00 31 15 12
Mensaje en hexadecimal LMS -> PC
C6 02 81 .. REFERENCIA A D.5
Nota: El red rojo activado permanente o temporalmente indica una infracción en alguno de los campos de la memoria interna del LMS. En caso de de que todo funcione
correctamente sin infracciones el led verde se mantendrá activo de forma permanente.
Figura D.3: Esquema de la inicialización del LMS
D.2.3. Valores por defecto del LMS
Por defecto, el láser después de inicializarse tiene los siguientes valores:
Parámetro
Puerto serie
Rango angular
Resolución angular
Unidades de medida
Valor
C6 02 81 .. REFERENCIA A D.5
8 bits de datos
sin paridad
1 bit de stop
sin control de flujo
0 .. 180º
0.5º
mm
Los valores por defecto de la tabla deben ser cambiados con los comandos que se describen más adelante.
D.2.4. Cambiar la velocidad de transmisión
Tras apagar el LMS, la velocidad de transmisión se resetea a 9600 baud. Para acceder
a las mediciones del LMS a mayor velocidad, es necesario cambiar la velocidad a una
mayor después de cada inicialización con alguno de los siguientes comandos:
D. El láser SICK LMS
71
Velocidad de LMS
9600 baud
19200 baud
19200 baud
Nota:
Comando PC -> LMS
02 00 02 00 20 42 52 08
02 00 02 00 20 41 51 08
02 00 02 00 20 40 50 08
Respuesta
06 02 81 03 00
06 02 81 03 00
06 02 81 03 00
LMS -> PC
A0 00 10 36 1A
A0 00 10 36 1A
A0 00 10 36 1A
Al cambiar la velocidad de transmisión mediante estos comandos la comunica-
ción con LMS y PC se interrumpe. Para reanudar de nuevo la comunicación con el LMS,
es necesario cambiar a la nueva velocidad en el programa del PC también.
D.2.5. Cambiar la resolución del LMS
El LMS puede suministrar datos de distancia en los siguientes formatos:
o
Rango angular: 0
.. 100
o
o
ó 0
o
o
.. 180
Resolución angular: 1 , 0.5 , 0.25
o
o
o
(solo para 100 )
Dependiendo de formato seleccionado, serán suministrados los diferentes valores de
distancia:
Rango angular
0º .. 100º
0º .. 100º
0º .. 100º
0º .. 180º
0º .. 180º
Resolución angular
1º
0.5º
0.25º
1º
0.5º
Numero de valores
101
201
401
181
361
Los diferentes modos pueden ser seleccionados enviando el correspondiente comando
del PC al LMS:
Nota:
Después de enviar un comando, un paquete de reconocimiento (ACK) y la
respuesta del LMS necesita ser recibida en el PC. Cuando se haya recibido la respuesta
completa al ACK, la conguración del LMS habrá sido realizada y el siguiente comando
podrá ser enviado. Los comandos intermedios serán ignorados.
Modo LMS
0º .. 100º -- 1º
0º .. 100º -- 0.5º
0º .. 100º -- 0.25º
0º .. 180º -- 1º
0º .. 180º -- 0.5º
Comando PC -> LMS
02 00 05 00 3B 64 00 64 00 1D 0F
02 00 05 00 3B 64 00 32 00 B1 59
02 00 05 00 3B 64 00 19 00 E7 72
02 00 05 00 3B B4 00 64 00 97 49
02 00 05 00 3B B4 00 32 00 3B 1F
Respuesta LMS -> PC
06 02 81 07 00 BB 01 64 00 64 00 10 4A 3F
06 02 81 07 00 BB 01 64 00 32 00 10 12 92
06 02 81 07 00 BB 01 64 00 19 00 10 BE C4
06 02 81 07 00 BB 01 B4 00 64 00 10 5EB2
06 02 81 07 00 BB 01 B4 00 32 00 10 06 1F
o
Figura D.4: Barrido láser en el modo 0 ..180
o
y 0..100
o
D.2.6. Cambiar la unidad de medida en LMS
Dependiendo de la aplicación, el LMS puede ser establecido para medir la distancia
en dos unidades.
Modo
mm mode
cm mode
Nota:
Medida / rango de detección
0 .. 8191 mm = 8.191 metros
0 .. 8191 cm = 81.91 metros
La precisión de la medida en cm no es tan alta como en mm.
Cambio a mm: Para cambiar a una unidad diferente de medida, es necesario
habilitar el Modo conguración del LMS. Seguiremos los siguientes pasos, enviando
los comandos correspondientes:
Unidad de distancia Comando PC -> LMS
Respuesta LMS -> PC
1. Modo configuración 02 00 0A 00 20 00 53 49 43 4B 5F 4C06 02 81 03 00 A0 00 10 36 1A
4D 53 BE C5
2. Cambio a mm
02 00 21 00 77 00 00 00 00 00 00 0106 02 81 23 00 F7 00 00 00 46 0000
00 00 02 02 00 00 00 00 00 00 00 0000 01 00 00 02 02 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00
00 FC 7E
00 00 00 10 FA EA
Cambio a cm: De la misma forma que antes, primero enviaremos el comando para
cambiar a Modo conguración y luego el comando apropiado:
Unidad de distancia Comando PC -> LMS
Respuesta LMS -> PC
1. Modo configuración 02 00 0A 00 20 00 53 49 43 4B 5F 4C06 02 81 03 00 A0 00 10 36 1A
4D 53 BE C5
2. Cambio a cm
02 00 21 00 77 00 00 00 00 00 00 0006 02 81 23 00 F7 00 00 00 46 0000
00 00 02 02 00 00 00 00 00 00 00 000D 00 00 00 02 02 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00
00 E8 72
00 00 00 10 D2 F2
Nota: Después de enviar un comando, un paquete de reconocimiento (ACK) y la
respuesta del LMS necesita ser recibida en el PC. Cuando se haya recibido la respuesta completa al ACK, la conguración del LMS habrá sido realizada y el siguiente
comando podrá ser enviado. Para el cambio entre el modo mm y cm la respuestas
del LMS puede tardar hasta 7 segundos. Los comandos intermedios serán ignorados.
D.2.7. Empezar con la salida continua de datos desde el LMS
Cuando se han establecido correctamente todos los parámetros, el LMS necesita un
comando para enviar los datos de las mediciones al PC. A diferencia de las aplicaciones
por encuesta, el LMS envía una cadena continua de datos a través del puerto serie.
D. El láser SICK LMS
Salida de datos continua
del LMS
Comienzo
73
Comando PC -> LMS
Respuesta LMS -> PC
02 00 02 00 20 24 34 08
06 02 81 03 00 A0 00 10 36 1A
<output string header> < LMS data >
(refer to section D.2.)
Nota: Antes de enviar cualquier otro comando de conguración al LMS, la salida
continua de datos debe ser parada mediante un comando especial (Ver D.2.9)
D.2.8. Interpretación de los datos recibidos
Un programa de PC típico para monitorear y procesar tareas necesita realizar las siguientes operaciones. Mientras el programa se encuentra en salida de datos continua, es
posible enviar un comando que indique Parar salida continua de datos.
Figura D.5: Operaciones en la ejecución de un programa con LMS
Para determinar el comienzo de una cadena de datos LMS, es necesario identicar una
cabecera especial en la cadena de entrada. La cabecera de salida de la cadena de salida
es diferente para cada modo de medida.
Rango angular
0º .. 100º
0º .. 100º
0º .. 100º
0º .. 180º
0º .. 180º
Resolución angular
1º
0.5º
0.25º
1º
0.5º
Número de puntos
101
201
401
181
361
Nota: Aunque hay un carácter STX al inicio de cada cadena de datos, no hay un
carácter ETX al nal. La cadena de datos actual debe ser identicada de alguna de las
siguiente formas:
Reconociendo el inicio de la siguiente cadena de datos
Almacenando un número exacto de valores calculados a partir de la información de
la longitud en la cabecera de datos de la cadena de salida.
D.2.9. Detención de la salida continua de datos
Antes de enviar cualquier otro comando de conguración al LMS, la salida continua
de datos debe ser parada.
Salida de datos
continua del LMS
Parada
Comando PC -> LMS
Respuesta LMS -> PC
02 00 02 00 20 25 35 08
06 02 81 03 00 A0 00 10 36 1A
D.2.10. Formato de la cadena de datos de salida
Una vez hemos comenzado con la salida continua de datos, el LMS nos envía una
cadena de datos de un formato determinado. El formato en cuestión se describe en detalle
a continuación:
STX ADR LenL LenH
Low High
byte byte
Campo
STX
ADR
Len
CMD
DataLen
Data ..
Status
CRC
CMD Data Data Data
LenL LenH 0º
Low
byte
Data
0º
High
byte
Data
1º
Low
byte
Data ...
Status CRC CRC High
1º
(more
Low byte
High data)
byte
byte
Tamaño del
Significado
dato
(numero de
bits)
8
Start byte (STX = 02 hexadecimal)
8
Dirección del suscriptor (en este caso el PC). Normalmente el valor es 81
hexadecimal
16
Longitud total de la cadena de datos LMS. Numero de bytes sin incluir el
checksum (CRC = 2 bytes)
8
Byte de comando, en este caso (B0 hexadecimal), que indica salida
dontinua de datos
16
Numero de bytes de datos de la medicion (depende del modo en el que
este configurado el LMS)
n x 16
Datos de las medidas (2 bytes cada uno) de acuerdo con el modo de
medida.
8
Byte de estado. Indica errores del sistema, contaminación, etc.
16
CRC checksum
D. El láser SICK LMS
75
D.2.11. Información del byte de estado (status byte)
Durante la salida continua de datos, el LMS manda un byte de estado al nal de cada
cadena de salida de datos. Con una programación adecuada, el byte de estado puede ser
monitorizado y evaluado durante la captura de datos.
Bit 0
0
1
0
1
0
Bit 1
0
0
1
1
0
Bit 2
0
0
0
0
1
Sin error (este es el estado correcto)
Información
Warning
Error
Error fatal
Por último el Bit 6 indica valor de medida imposible y el Bit 7 que existe contaminación
en la medida láser.
Apéndice E
Trabajando con MaRTE OS
E.1. Instalación
La instalación de MaRTE es muy sencilla. En la página web de distribución de MaRTE
se puede obtener tanto el compilador de lenguaje Ada GNAT como el archivo comprimido que contiene MaRTE. Siguiendo los pasos que se indican en el archivo README
se puede instalar todo correctamente. Además MaRTE contiene diferentes ejemplos para
probar que la instalación ha sido realizada correctamente.
Como referencia rápida, será necesario:
Instalar el compilador GNAT 2005 disponible en su página web.
Descargar MaRTE OS de la página mencionada.
Instalar MaRTE OS en el ordenador con linux ejecutando el programa minstall (leer
el archivo README de MaRTE para ver detalles).
Congurar las variables del sistema correctamente para poder ejecutar los programas
de compilación mgcc (C) y mgnatmake (Ada).
Estos son los pasos básicos para instalar el programa que permite generar el archivo
(mprogram) que se ejecutará en la máquina controlada por MaRTE.
E.2. Creación de nuevos drivers
Aunque en [4] queda totalmente denido el proceso de creación de drivers desde el
punto de vista más técnico, a continuación se describe de forma rápida el proceso para
añadir un nuevo driver desde el punto de vista de usuario programador de MaRTE.
En la carpeta kernel de MaRTE se debe abrir el chero kernel-devices-table.ads y
añadir un nuevo dispositivo de forma similar a los dispositivos que ya hay disponibles. El
propio chero deja claro lo que hay que hacer. Por defecto están disponibles la entrada
(teclado), salida estándar y salida de error (pantalla). Aquí es donde se han añadido las
terminales del puerto serie ttyS0, ttyS1 y ttyS2 asociados a los dispositivos láser, P2OS
76
E. Trabajando con MaRTE OS
77
y GPS. Cada vez que se modique este chero hay que compilar el kernel de MaRTE
ejecutando el comando mkkernel. Para usar el nuevo driver se procede de la misma forma
que en Linux. Se obtiene un descriptor de chero realizando un fd = open(/dev/ttyS0)
del nombre del terminal correspondiente. A partir de este momento se pueden usar las
funciones write y read sobre el dispositivo de la forma habitual.
E.3. Arrancar en red con MaRTE OS y el robot
Para conseguir el arranque en red en MaRTE hacen falta diferentes elementos hardware
y software.
E.3.1. Elementos hardware
En primer lugar hace falta un PC normal conectado a la red donde se programará
la aplicación. A este ordenador lo llamaremos servidor. Por otro lado hace falta el robot
Pioneer, al cual se puede conectar una pantalla para poder ver lo que sucede (más cómodo
que la línea gdb de debug ). Se conectará un teclado para poder realizar operaciones y se
conectará a la red. A esta máquina la llamaremos host.
E.3.2. Elementos software
Servidor
Se necesitan los siguientes elementos:
1. Tener instalado MaRTE OS correctamente.
2. Un servidor DHCP, por ejemplo instalar con aptitude el servidor dhcpd.
3. Un servidor tftp, de la misma forma que antes instalar el servidor tftp.
Host
Esta máquina tiene que disponer de linux y del gestor de arranque Grub. Además
se tiene que conocer la tarjeta de red que usa y descargar de la página http://romo-matic.net/ el archivo de arranque en red correspondiente. En el caso del robot la
tarjeta de red es una Intel eepro100.
E.3.3. Conguración del servidor
Conguración del servidor dhcp:
El archivo de conguración del servidor de direcciones dinámicas se encuentra en
/etc/dhcp.conf. En este archivo se deben añadir todos aquellos host que han de
arranquen en red. Básicamente se dene cada host con una dirección MAC (única
para cada máquina) y se le indica cual será su dirección de red y que archivo ha de
descargarse para arrancar.
-----------------------------------------------------
dhcpd.conf
.....................................................
option subnet-mask 255.255.255.0;
default-lease-time 600;
max-lease-time 7200;
server-name "Nombre-de-servidor";
allow bootp;
subnet 155.210.155.0 netmask 255.255.255.0 {
}
host robot {
filename "/tftpdboot/mprogram";
server-name "Nombre-de-servidor";
next-server 155.210.155.36;
hardware ethernet 00:04:BF:90:08:72;
fixed-address 155.210.155.16;
option root-path "/tftpdboot";
}
# ......... más máquinas ....
......................................................
En este caso cuando el servidor esté activo, si le llega una petición dhcp desde
una máquina con dirección MAC 00:04:BF:90:08:72, este sabrá que es el host robot quien le esta pidiendo una dirección de red. El servidor contestará diciéndole
que tiene la IP 155.210.155.16 y que se descargue el chero para arrancar desde
/tftpdboot/mprogram.
Conguración del servidor TFTP:
Este servidor es el que hace posible la transferencia del chero mprogram (resultado de la compilación con MaRTE) a través de la red entre diferentes máquinas.
Para compartir un directorio de la máquina en red, hay que editar el chero /etc/inetd.conf, modicando las líneas que aparecen a continuación.
#:BOOT: TFTP service is provided primarily for booting. Most sites
#
run this only on machines acting as "boot servers."
tftp dgram
udp wait nobody /usr/sbin/tcpd
/usr/sbin/in.tftpd /tftpdboot
De esta forma cuando se arranca el ordenador se comparte con el resto de máquinas
el directorio /tftpdboot. Y es aquí donde deberá estar el archivo mprogram, para
que el host se lo descargue.
E. Trabajando con MaRTE OS
79
E.3.4. Conguración del host
En el directorio /boot hay que colocar el archivo de arranque en red y modicar el
chero menu.lst del directorio /boot/grub añadiendo la siguiente entrada.
# ENTRADA PARA MaRTE OS EN EL MENU GRUB
title
MaRTE OS
root
(hd0,1)
kernel
/boot/mprogram
E.3.5. Método de trabajo
Antes de empezar a trabajar con MaRTE OS en los robots se han de cumplir los
siguientes puntos:
1. Conseguir red. Si estás trabajando desde un ordenador jo de la sala nada más
arrancar ya se debería disponer de red. En el caso de usar un portátil se deberá ejecutar un programa proporcionado por el administrador del laboratorio para obtener
IP correspondiente. (sudo ./ethUni IP )
2. Hay que eliminar todos los procesos dhcp y dhcpd que estén corriendo en el sistema,
si los hay. Normalmente al arrancar el sistema, también arranca un cliente DHCP que
pide una dirección de red automáticamente y el propio servidor DHCPD arranca con
una conguración determinada. Para ahorrar funcionamientos incorrectos lo mejor
es buscar los procesos que están ejecutándose en el servidor con sudo ps aux | grep
dhcp y matarlos con kill -9 "numero proceso". Ahora se lanzará el servidor DHCPD
de la siguiente manera sudo dhcpd -f -d, y todo queda listo para empezar a trabajar.
3. Cuando compilamos el programa con MaRTE (mgnatmake en ADA y mgcc en C)
el chero mprogram queda en un directorio especicado por el usuario en la instalación. Después de compilar se debe copiar ese chero al directorio compartido con
TFTP. La orden usada durante el proyecto es cp /home/usuario/export/mprogram
/tftpdboot/.
4. Ahora el servidor está listo para escuchar la petición del host (robot). Sera necesario arrancar el robot, donde aparecerá una lista (GRUB) de los diferentes SO que
se pueden arrancar.Se deberá elegir la entrada de MaRTE OS tal como se haya
congurado, y listo.
Un detalle importante a tener en cuenta es que la primera vez que se arranca el
robot conviene hacerlo en linux porque la tarjeta de red queda congurada correctamente.
Los posteriores arranques en red (con la tarjeta congurada) son mucho más rápidos,
permitiendo desarrollar mejor la aplicación en MaRTE.
Apéndice F
Manual de usuario y API
F.1. Manual de usuario
A continuación se recogen los pasos más importantes que hay que seguir para realizar
una aplicación en el SO MaRTE usando las funciones implementadas para el robot.
Se debe tener instalado el entorno de desarrollo en nuestro ordenador con Linux tal y
como se explica en el anexo E. La versión estándar de MaRTE por el momento no ofrece
los drivers que se han implementado. Para poder usar los dispositivos del robot se deben
de copiar las carpetas que contienen los drivers del robot para MaRTE en los lugares
apropiados.
Se van a mostrar las partes básicas que componen una aplicación Ada para utilizar el
dispositivo del microcontrolador (el proceso es similar para C).
1. Poner las directivas
with y use correspondientes al dispositivo y los recursos que se
deseen usar. De esta forma estarán disponibles dentro de la aplicación las funciones
que hay denidas en los cheros incluidos. En este caso se necesita MaRTE_OS
como en cualquier otra aplicación para MaRTE_OS, System para poder asignar
prioridades del sistema, text_io y Ada.Real_Time para poder utilizar los temporizadores y nalmente p2os_import para utilizar las funciones del microcontrolador.
with
with
with
use
with
MaRTE_OS;
system;
text_io, Ada.Real_Time;
text_io, Ada.Real_Time;
p2os_import; use p2os_import;
2. Crear un procedimiento en el que se denirán las tareas que componen la aplicación.
En esta aplicación se crearán tres tareas. La primera tarea se crea automáticamente.
Como se explicó en el capítulo 3.2, el hecho de instanciar un dispositivo supone
crear una tarea que atiende a las interrupciones con un periodo determinado por
la velocidad a la que se instancia el dispositivo. La segunda tarea (actualiza_p2os )
actualizará cada 100 ms el valor del objeto protegido que contiene los datos del
micro. La última tarea (movimiento ) será la que se encargue de mover el robot tres
metros hacia delante.
80
F. Manual de usuario y API
81
3. Habrá que denir la prioridad de cada tarea de la siguiente forma. La tarea que
atiende a la interrupción tiene prioridad hardware y el usuario no la debe indicar. La
tarea de actualización se ejecuta cada 100ms por lo que se le asigna más prioridad
que a la de movimiento que se ejecuta cada 150ms. Por ejempolo asignamos las
prioridades 22 y 19:
prioridad_actualizacion: constant System.Any_Priority := 22;
prioridad_movimiento : constant System.Any_Priority := 19;
4. Habrá que denir las tareas con las prioridades correspondientes:
task actualiza_p2os is
pragma Priority (prioridad_actualizacion);
end actualiza_p2os;
task movimiento is
pragma Priority (prioridad_movimiento);
end movimiento;
5. Por último se crearán las tareas para que el objeto protegido este actualizado cada
100ms y el robot consiga moverse hasta que la odometría indique que se el valor
de la x vale 3 metros. Se puede ver que el robor se va a mover traslacionalmente a
0.2m/s y 0.0rad/s angularmente.
task body actualiza_p2os is
periodo
: constant Time_Span := Milliseconds (100);
siguiente : Time;
port : C.char_array := "/dev/ttyS0";
var : C.Int;
begin
--Comienza la incialización del microcontrolador
var:=initP2os(port);
while true loop
--Con esta función se actualiza el objeto protegido
p2osGetValues;
--Suspension hasta que vuelva a empezar su periodo
siguiente := siguiente + periodo;
delay until siguiente;
end loop;
end actualiza_p2os;
task body movimiento is
periodo : constant Time_Span := Milliseconds (200);
siguiente : Time;
x: float := 0.0;
begin
siguiente := clock;
while true loop
--Obtenemos el valor de X
lockP2os;
x := float(p2osGetXpos);
unlockP2os;
--Ordenamos al micro que mueva los motores a 0.2 m/s
if x < 3.0 then SetSpeed(0.2,0.0);
else SetSpeed(0.0,0.0);
end if;
--Suspension hasta que vuelva a empezar su periodo
siguiente := siguiente + periodo;
delay until siguiente;
end loop;
--Fin de control de movimiento
end movimiento;
F. Manual de usuario y API
83
F.2. Funciones en lenguaje C
A continuación se presenta el conjunto de funciones disponibles para programar los
dispositivos en lenguaje C. Para la comunicación inalámbrica no se han documentado las
funciones debido que todavía no se ha podido probar correctamente este driver. Se pueden
ver las funciones del microcontrolador (P2OS), las del láser y las del GPS. Para todas
ellas se muestran y explican los parámetros de entrada de las funciones y el resultado que
se obtiene con ellas. Además se puede observar el tiempo de cómputo para cada función.
Esto facilita enormemente realizar y analizar aplicaciones para el robot con MaRTE OS.
F.2.1. P2OS
Función
int initP2os(char * port);
int p2osShutdown();
void p2osMotorOn();
void p2osMotorOff();
void p2osSonarOn();
void p2osSonarOff();
void p2osGetValues();
int p2osGetLwstall();
int p2osGetRwstall();
unsigned char p2osGetStatus();
unsigned char p2osGetBattery();
unsigned char p2osGetSonarreadings();
unsigned char p2osGetAnalog();
unsigned char p2osGetDigin();
unsigned char p2osGetDigout();
unsigned short p2osGetCompass();
unsigned short p2osGetTimer();
unsigned short p2osGetRawxpos();
unsigned short p2osGetRawypos();
unsigned short p2osGetFrontbumpers();
unsigned short p2osGetRearbumpers();
short p2osGetLvel();
short p2osGetRvel();
short p2osGetControl();
unsigned short p2osGetSonar(int I);
float p2osGetXpos();
float p2osGetYpos();
float p2osGetAngle();
int p2osGetX_offset();
int p2osGetY_offset();
int p2osGetAngle_offset();
float p2osGetXSpeed();
float p2osGetYawSpeed();
void PrintP2OS_SIP();
void SetSpeed(float trans, float rot);
P2OS
Cómputo
Funcionamiento
12.97*
Inicializa el driver del microcontrolador en el
puerto indicado en port.
1.209*
Finaliza el driver
0.029
Activa /desactiva los motores
0.029
Activa /desactiva el sonar
0.062
0.00394
Actualiza los valores del SIP. Esta función
debe ser periódica (todo el rato en un bucle)
Valores del sensor de parada.
0.00402
0.00380
0.00401
0.00394
0.00402
Valor del registro de estado del micro.
Nivel de batería
Número de valores sonar.
Registro analógico del micro.
Registro digital del mico. (entrada/salida)
0.00401
0.00394
0.00396
Valor de la brújula digital
Timer del micro.
Valor de x e y entre un cambio y otro.
0.00401
Valor de los sensores de choque
0.00402
Velocidad a izquierda y derecha
0.00380
0.00401
0.00394
Registro de control
Sonar número I del robot
Valores de la odometría del robot.
0.00380
Valores de la variación de odometría
0.00402
Valor de la velocidad de translación y
rotación del robot
9.355*
Muestra la información del paquete SIP
0.029
Establece la velocidad de translación(m/s) y
rotación (rad/s) del robot.
void lockP2os();
0.001
Bloquea/desbloquea la lectura/escritura de
void unlockP2os();
los valores SIP (soporte Tiempo Real)
*Valores de tiempo inicio/fin (No de cómputo) debido a que esas funciones no son importantes para
el control de Tiempo Real
Figura F.1: Funciones para manejar el P20S en C
F.2.2. Láser
Las funciones que controlan el dispositivo láser son:
LÁSER
Función
Cómputo (ms)
Funcionamiento
void connectToLMS
(int range_mode,
int res_mode,
int unit_mode,
char * port,
int baud_sel)
6.5*
Conecta y configura el láser con los parametros:
range_mode = {RANGE_100 , RANGE_180}
res_mode = {RES_1_DEG, RES_0_5_DEG,
RES_0_25_DEG}
unit_mode = {MMMODE,CMMODE}
port = nombre del dispositivo (p.e “/dev/ttyS0”)
baud_sel = {9600,19600,38400}
void resetLMS()
void stopLMS()
6.8*
Reset / parada del dispositivo. Se establece la
configuración por defecto.
int readLMSValues()
BPS
100- 1º 100-0.5º 100-0.25º
180-1º
9600
224.67
19200 112.35
38400
int readLMSValues()
453.318
868.52
397.15
224.67
453.318
198.03
180-0.5º Duración de la actualización del láser.
Los valores del láser quedan actualizados para las
776.43
funciones de lectura.
397.15
(no funciona en el robot, límite tecnológico)
Modo 100- 1º 100-0.5º 100-0.25º
0.540
10.518
2.070
180-1º
0.952
180-0.5º Actualiza los valores del láser.
Tiempo de cómputo real (independiente de la línea
1.867
serie)
int laserazo (int i)
0.0031
Devuelve el valor de la distancia del láser número I
int GetCountLaser()
0.0036
Número de valores que se han recogido en el
último barrido
double
GetScanResLaser()
0.0035
Devuelve la resolución a la que esta configurado el
láser.
double
GetRangeResLaser()
0.0056
Devuelve el rango en el que está configurado el
láser
int getStatus ()
0.0041
Devuelve el estado de funcionamiento del láser.
Los valores se pueden consultar en el anexo D.
void lockLaser()
void unlockLaser()
0.001
Bloquea/desbloquea la lectura/ escritura del láser.
*Valores de tiempo inicio/fin (No de cómputo) debido a que esas funciones no son importantes para el control de
Tiempo Real
Figura F.2: Funciones para manejar el Láser en C
F.2.3. GPS
GPS Novatel
Cómputo (ms)
Funcionamiento
1.053*
Inicializa el driver en el dispositivo indicado
en el parámetro puerto.
int SetupNovatel()
11.15206*
Establece los valores del GPS. Operación
interna de configuración.
int leerSerie()
0.20585 (Periodo
Lee los valores de la linea serie.
mínimo 1 segundo)
void leeGps()
0.033
Actualiza los valores del GPS
float gps_X()
0.003599
Valor en X
float gps_Y()
0.003599
Valor en Y
void ShutdownSerial()
2.31086
Finaliza el dispositivo
void lockGPS()
0.001
Bloquea/desbloquea la lectura/escritura del
void unlockGPS()
GPS
*Valores de tiempo inicio/fin (No de cómputo) debido a que esas funciones no son importantes para
el control de Tiempo Real
Función
void initNovatel (char * puerto)
Figura F.3: Funciones para manejar el GPS en C
F. Manual de usuario y API
85
F.2.4. Comunicación inalámbrica
El conjunto de funciones usado para poder realizar una comunicación inalámbrica
no ha sido testeado hasta el punto de poder ofrecer un API able. Además para poder
realizar la comunicación se usa el driver PCI, el driver PCMCIA (yenta_socket) y el
driver de la tarjeta (rt61). Para poder hacerlo funcionar necesitaremos además el código
del protocolo RT-WMP. Por ello se ha decido no crear un API. El camino correcto, para
poder implementar un protocolo de comunicación será estudiar la aplicación de ejemplo
que se incluye con el proyecto. El orden de cada una de las funciones es importante, así
como la conguración del sistema. Además este driver todavía no ha sido publicado con
la distribución actual de MaRTE y no ha sido revisado por sus distribuidores.
F.3. Funciones en lenguaje Ada
De la misma forma que para lenguaje C, se presentan las funciones y los datos correspondientes para programar aplicaciones en lenguaje Ada.
F.3.1. P2OS
P2OS
Función
Cómputo
Funcionamiento
function initP2os (port: C.char_array) return C.Int;
12.97* Inicializa el driver del
microcontrolador en el puerto
indicado en port.
function p2osShutdown return C.Int;
1.209* Finaliza el driver
procedure p2osMotorOn;
0.029 Activa /desactiva los motores
procedure p2osMotorOff;
procedure p2osSonarOn;
0.029 Activa /desactiva el sonar
procedure p2osSonarOff;
procedure p2osGetValues;
0.062 Actualiza los valores del SIP. Esta
función debe ser periódica (todo el
rato en un bucle)
function p2osGetLwstall return C.Int;
0.00394 Valores del sensor de parada.
function p2osGetRwstall return C.Int;
unction p2osGetStatus return C.unsigned_char;
0.00402 Valor del registro de estado del
micro.
function p2osGetBattery return C.unsigned_char;
0.00380 Nivel de batería
function p2osGetSonarreadings return
0.00401 Número de valores sonar.
C.unsigned_char;
function p2osGetAnalog return C.unsigned_char;
0.00394 Registro analógico del micro.
function p2osGetDigin return C.unsigned_char;
0.00402 Registro digital del mico.
function p2osGetDigout return C.unsigned_char;
(entrada/salida)
function p2osGetCompass return C.unsigned_short;
0.00401 Valor de la brújula digital
function p2osGetTimer return C.unsigned_short;
0.00394 Timer del micro.
function p2osGetRawxpos return C.unsigned_short;
0.00396 Valor de x e y entre un cambio y
function p2osGetRawypos return C.unsigned_short;
otro.
function p2osGetFrontbumpers return
0.00401 Valor de los sensores de choque
C.unsigned_short;
function p2osGetRearbumpers return
C.unsigned_short;
function p2osGetLvel return C.short;
0.00402 Velocidad a izquierda y derecha
function p2osGetRvel return C.short;
function p2osGetControl return C.short;
0.00380 Registro de control
function p2osGetSonar(I: C.Int) return
0.00401 Sonar numero I del robot
C.unsigned_short;
function p2osGetXpos return C.Double;
0.00394 Valores de la odometría del robot.
function p2osGetYpos return C.Double;
function p2osGetAngle return C.Double;
function p2osGetX_offset return C.Int;
0.00380 Valores de la variación de
function p2osGetY_offset return C.Int;
odometría
function p2osGetAngle_offset return C.Int;
function p2osGetXSpeed return C.Double;
0.00402 Valor de la velocidad de translación
function p2osGetYawSpeed return C.Double;
y rotación del robot
procedure PrintP2OS_SIP;
9.355* Muestra la información del paquete
SIP
procedure SetSpeed(trans: Float; rot: Float);
0.029 Establece la velocidad de
translación(m/s) y rotación (rad/s)
del robot.
procedure lockP2os;
0.001 Bloquea/desbloquea la
procedure unlockP2os;
lectura/escritura de los valores SIP
(soporte Tiempo Real)
*Valores de tiempo inicio/fin (No de cómputo) debido a que esas funciones no son importantes para
el control de Tiempo Real
Figura F.4: Funciones para manejar el P20S en Ada
F. Manual de usuario y API
87
F.3.2. Láser
LÁSER
Función
Cómputo (ms)
Funcionamiento
procedure connectToLMS
(range_mode,
res_mode, unit_mode:
C.Int; port: C.char_array;
baud_sel:C.Int);
6.5*
Conecta y configura el láser con los parametros:
range_mode = {RANGE_100 , RANGE_180}
res_mode = {RES_1_DEG, RES_0_5_DEG,
RES_0_25_DEG}
unit_mode = {MMMODE,CMMODE}
port = nombre del dispositivo (p.e “/dev/ttyS0”)
baud_sel = {9600,19600,38400}
procedure resetLMS;
procedure stopLMS;
6.8*
Reset / parada del dispositivo. Se establece la
configuración por defecto.
function readLMSValues
return C.Int;
BPS
100- 1º 100-0.5º 100-0.25º 180-1º 180-0.5º Duración de la actualización del láser.
Los valores del láser quedan actualizados para
224.67 453.318
868.52
397.15 776.43
las funciones de lectura.
19200 112.35 224.67
453.318 198.03 397.15
9600
38400
function readLMSValues
return C.Int;
(no funciona en el robot, límite tecnológico)
Modo 100- 1º 100-0.5º 100-0.25º 180-1º 180-0.5º Actualiza los valores del láser.
Tiempo de cómputo real (independiente de la
0.540 10.518
2.070
0.952
1.867
línea serie)
function laserazo (i:
C.Int) return C.Int;
0.0031
Devuelve el valor de la distancia del láser
número I
function GetCountLaser
return C.Int;
0.0036
Número de valores que se han recogido en el
último barrido
function
GetScanResLaser return
C.Double;
0.0035
Devuelve la resolución a la que esta
configurado el láser.
function
GetRangeResLaser
return C.Double;
0.0056
Devuelve el rango en el que está configurado el
láser
int getStatus ();
0.0041
Devuelve el estado de funcionamiento del láser.
Los valores se pueden consultar en el anexo D.
void lockLaser();
void unlockLaser();
0.001
Bloquea/desbloquea la lectura/ escritura del
láser.
*Valores de tiempo inicio/fin (No de cómputo) debido a que esas funciones no son importantes para el control
de Tiempo Real
Figura F.5: Funciones para manejar el Láser en Ada
F.3.3. GPS
Función
procedure initNovatel(port:
C.char_array);
function SetupNovatel return C.Int;
function leerSerie return C.Int;
GPS Novatel
Cómputo (ms)
1.053*
11.15206*
0.20585 (Periodo
mínimo 1 segundo)
0.033
0.003599
0.003599
2.31086
0.001
procedure leeGps;
function gps_X return Float;
function gps_Y return Float;
procedure ShutdownNovatel;
procedure lockGPS;
procedure unlockGPS;
*Valores de tiempo inicio/fin (No de cómputo) debido a que
el control de Tiempo Real
Funcionamiento
Inicializa el driver en el dispositivo
indicado en el parámetro puerto.
Establece los valores del GPS.
Operación interna de configuración.
Lee los valores de la linea serie
Actualiza los valores del GPS
Valor en X
Valor en Y
Finaliza el dispositivo
Bloquea/desbloquea la
lectura/escritura del GPS
esas funciones no son importantes para
Figura F.6: Funciones para manejar el GPS en Ada
F.3.4. Comunicación inalámbrica
Como se ha comentado en el apartado para el lenguaje C (F.2.4), este driver no dispone
de un API able por el momento. Por lo tanto tampoco se dispone del interfaz para ADA.
F.4. Consideración nal
Además de los tiempos que se muestran en cada función usada, a la hora de desarrollar
una aplicación en tiempo real, será necesario conocer el tiempo de cómputo y periodo de
las interrupciones que atienden la línea serie. Esta interrupción es diferente dependiendo
de la velocidad a la que se instancie el driver. El tiempo de cómputo de la interrupción
es de 29 microsegundos y los periodos de ejecución correspondientes a cada modo (en el
peor caso posible) se pueden ver aquí:
Baud rate interrupciones /
segundo
9600
1200
19200
2400
38400
4800
Periodo mínimo
(inversa)
833.333µs
416.66µs
208.333µs
Utilización
0.03240
0.0648
0.1296
Apéndice G
Interfaz de programación entre Ada y C
En este anexo se va a explicar como se puede mezclar Ada con C y C++. Algunas
razones para mezclar Ada con C/C++ son las siguientes:
Tienes una gran cantidad de código escrito en Ada y quieres hacer desarrollos en el
futuro en C/C++.
Preeres desarrollar aplicaciones en Ada, pero estás obligado a usar librerías que ya
existen en C/C++.
Con algunas limitaciones, ambos casos son posibles.
En general, una aplicación está compuesta de uno o más elementos visibles globalmente. Estos items tienen un nombre que está asociado o con la dirección del dato o la
dirección del punto de entrada de una función. El código fuente que generan estos items
se almacena en uno o más cheros fuente en el ordenador de desarrollo.
Cada chero fuente está escrito o en Ada o en C/C++ y está procesado por su propio compilador. El proceso de compilación convierte el código fuente al código objeto. El
linker combina estos módulos de código objeto en un sólo chero ejecutable. Tanto Ada
como C/C++ usan este sistema de compilación y lincado separado. Mientras todas los
cheros fuente estén escritos en el mismo lenguaje, el compilador y el linker funcionarán
perfectamente. Los problemas aparecen cuando algunos cheros están escritos en Ada y
otros en C o en C++.
Imaginemos que un programa está compuesto de dos partes. Una parte está escrita en
Ada y la otra en C/C++. Nos preguntaremos:
1. ¾Cómo se reere una parte a los datos globales de la otra parte?
2. ¾Cómo una parte crea dinámicamente y subsecuentemente se reere a datos de la
otra parte? ¾Cómo se destruyen estos datos?
3. ¾Cómo puede una parte llamar a las funciones de la otra parte?¾Cómo se pasan los
argumentos? ¾Cómo se recibe los valores devueltos?
4. ¾Dónde esta el punto de entrada del programa?¾Es un main() en C/C++ o es un
procedimiento en la parte Ada?
89
En este capítulo trataremos estas cuestiones.
G.1. Visibilidad global de los datos
Un dato almacenado estáticamente ocupa una porción de memoria que puede ser determinada en tiempo de lincado. Un chero fuente puede denir estáticamente datos que
son visibles a otros cheros fuente o pueden acceder estáticamente a datos denidos en
otros cheros fuente.
En C/C++, los datos almacenados estáticamente son visibles globalmente si están
denidos fuera de una función y no está presente la palabra
static. Una función C/C++
puede referirse a los datos que han sido almacenados estáticamente en otro chero fuente
declarando el dato con la palabra clave
extern. Por ejemplo, la siguiente declaración en
C++ crea un dato visible a Ada y se reere a un datos que Ada ha creado:
extern struct adastuff FromAda2Cpp; // Import from Ada to C++
struct cppstuff FromCpp2Ada; // Export from C++ to Ada
Un ejemplo para C sería el siguiente:
extern struct adastuff FromAda2C; // Import from Ada to C
struct cstuff FromC2Ada; // Export from C to Ada
Lo programas Ada hacen visibles los datos globalmente a C/C++ usando el comando
pragma export. Un procedimiento o función Ada puede referirse a un dato que ha sido
almacenado estáticamente en un chero fuente C/C++ usando el comando
pragma im-
port. Algunos ejemplo:
pragma import(CPP, CPP_HIS_STUFF, "FromCpp2Ada");
pragma export(CPP, CPP_MY_STUFF, "FromAda2Cpp");
pragma import(C, C_HIS_STUFF, "FromC2Ada");
pragma export(C, C_MY_STUFF, "FromAda2C");
Estos comandos de Ada asocian un nombre local Ada con un nombre global C/C++.
Tendremos que tener cuidado con los nombres en Ada ya que permiten poner puntos. Esta
característica no esta disponible en C/C++ ya que en este caso indica una estructura,
una unión o una clase. Estos pragmas Ada realizan una función importante asociando el
nombre interno Ada con el símbolo externo y traduciendo símbolos externos a la forma
que es compatible con C/C++.
G. Interfaz de programación entre Ada y C
91
Ada y C/C++ pueden compartir cualquier tipo de dato si las representaciones que
hace la máquina son binariamente compatibles. El paquete Ada INTERFACES.C es útil
para forzar estas correspondencias. La siguiente lista muestra la correspondencia de tipos
entre Ada y C++.
Tipo Ada
Integer
Interfaces.C.int
Short_Integer
Interfaces.C.short
Long_Integer
Long_Long_Integer
Interfaces.C.long
Character
Interfaces.C.char
Interfaces.C.plain_char
Interfaces.C.unsigned_char
Interfaces.C.signed_char
Byte_Integer
Short_Short_Integer
Interfaces.C.unsigned
Interfaces.C.unsigned_short
Interfaces.C.unsigned_long
Float
Interfaces.C.C_float
Long_Float
Interfaces.C.double
Interfaces.C.long_double
Interfaces.C.char_array
Interfaces.C.wchar_t
Tipo C/C++
int
int
short
short
long
long
long
char
char
char
unsigned char
signed char
signed char
signed char
unsigned int
unsigned short
unsigned long
float
float
double
double
double
char *
wchar_t
El tipo puntero Ada (access ) es equivalente al correspondiente tipo puntero C/C++.
Ada, C y C++ pueden compartir estructuras, uniones y vectores. Es obligatorio denir
en el mismo orden los elementos para en las estructuras para asegurar que si las estructuras tienen el mismo número y tipo de elementos, entonces serán binariamente compatibles.
Este es un ejemplo de código Ada accediendo a una estructura de datos C++:
Lado en C++
class cpprec // Define the structure
{
int numitems;
float weightofitems;
};
cpprec cpp_name; // Declare the shared structure
Lado en Ada
type adarec is -- Define the structure
record
itemcount : INTEGER;
itemweight : FLOAT;
end record;
ada_name : adarec; -- Declare the shared structure
pragma import(cpp, ada_name, "cpp_name");-- Tie the two names together
Ahora, cualquier referencia del código Ada a ada_name.itemcount accederá a la mismo posición de memoria entera vista por C++ como cpp_name.numitems.
Si el registro Ada es de tipo
tagged, entonces la denición C++ del registro necesita
dar espacio para la etiqueta del registro Ada. Una variable que imite el tipo *void se tiene
que insertar en la denición de la clase antes del primer elemento. El siguiente código
muestra un ejemplo:
Lado en C++
class cpprec // Define the structure
{
void* tagspace; // Allow space for the Ada tag
int numitems;
float weightofitems;
};
cpprec cpp_name; // Declare the shared structure
Lado en Ada
type adarec is -- Define the structure
record
itemcount : INTEGER;
itemweight : FLOAT;
end record;
ada_name : adarec; -- Declare the shared structure
pragma import(cpp, ada_name, "cpp_name");-- Tie the two names together
El código C/C++ no puede acceder directamente a datos globales de un paquete Ada
existente desde que los símbolos globales han introducido el carácter punto. En este caso,
el programador debe usar un pragma export Ada para cada elemento C/C++ que quiera
hacer visible.
G. Interfaz de programación entre Ada y C
93
G.2. Visibilidad global de funciones
Hay que diferenciar los conceptos de función y procedimiento. Un procedimiento es
simplemente una función que no devuelve un valor. En Ada, un subprograma es o un
procedimiento o una función. Por otro lado C/C++ solo soporta el concepto de función.
Sin embargo, una función C/C++ puede ser declarada devolviendo void ; en este caso, el
funcionamiento es el mismo que en un procedimiento Ada. La declaración void simplemente le indica al compilador que no espere un valor de retorno.
Hay muchos tipos diferentes de función tanto en Ada como en C/C++. Los siguientes
tipos comunes de funciones pueden ser usados en ambos lados.
1. Funciones globales - Ada puede llamar a funciones C/C++ globales y C/C++ puede
llamar a funciones globales Ada.
2. Miembros de funciones - Ada puede llamar a miembros de funciones C++. C++ no
puede llamar a operaciones Ada.
Los subprogramas Ada que no pueden ser accedidos desde C/C++ son las operaciones
de planicación y las funciones INITIALIZE, FINALIZE y ADJUST de tipos de control.
Todas las funciones C/C++ son accesibles desde Ada, aunque los constructores y destructores de C++ no pueden estar disponibles desde Ada directamente.
Como para los datos globales, la directiva Ada
pragma export y pragma import
asocian la función Ada con la función C/C++. Un ejemplo de Ada llamando a una función
C++:
Lado en Ada
function CPROC(input : in integer) return integer;
pragma import(CPP, CPROC, "c_proc");
result : integer;
...
result := CPROC(123); -- Put answer in variable "result"
Lado en C++
int c_proc(int input)
{
int tmp; // Accumulate the result here.
... // Do some processing here.
return tmp; // Return the result.
}
Para el caso de funciones, el compilador Ada usa la codicación de nombres de C++
para generar el símbolo global real. El programador debe asegurarse de que los tipos
de los argumentos encajen entre la declaración de la función Ada y la función C++.
Para argumentos de tipo registro y enumerador, el nombre debe ser exactamente entre
la denición Ada y C++. La especicación real del tipo del argumento no es un problema.
G.3. Ejecución del programa
G.3.1. Inicialización
El programa principal puede estar escrito en Ada o en C/C++. En ambos casos, el código de inicialización del sistema de ejecución necesita ejecutarse antes de que el programa
principal se comience. Este código de inicialización es capturado automáticamente y de
forma transparente cuando el programa está escrito en un único lenguaje. Si mezclamos
ambos lenguajes, el código de inicialización del usuario debe llamar explícitamente a la
inicialización del sistema de ejecución antes de que los elementos del otro lenguaje sean
usados.
Si las funciones principales están escritas en Ada y el código Ada referencia elementos
C++, entonces el programa principal Ada deberá llamar a la función _main() antes de
cualquier referencia a un elemento C/C++.
Si las funciones principales están escritas en C/C++, entonces el main() debe llamar
a una función llamada adainit antes que se haga referencia a un elemento Ada. Esto
debe también llamar a adanal después de la última referencia a todos los elementos Ada.
G.3.2. Captura de excepciones
Tanto Ada como C++ tienen su propio sistema de captura de excepciones. Mientras
un programa se ejecuta, el sistema de ejecución mantiene un pila de llamadas. Por ejemplo, la función main() llama a la función sub1(). La función sub1() llama a la función
sub2() y ésta a la función sub3(). Si la función sub3() detecta una condición de excepción,
deberá lanzar (o capturar) una excepción. Esta excepción transere el control a sub1()
para tratar la excepción.
Si esas cuatro funciones estuvieran escritas en el mismo lenguaje, el mecanismo nativo
de tratamiento de excepciones funcionaría a la perfección. ¾Esto funcionaría si todas las
funciones estuvieran escritas en el mismo lenguaje, menos sub2() que está escrita en un
lenguaje diferente? Si en el ejemplo, sub2() estuviera escrita en C++ y se hubiera compilado con la opción -Xnewexchandling, la respuesta sería sí. La captura de excepciones
es una posible transferencia de control en la pila de llamadas. Para conseguir esto, el
compilador construye tablas que son usadas en tiempo de ejecución por el mecanismo de
captura de excepciones. La opción -Xnewexchandling indica al compilador C++ que
debe construir una tabla de captura de excepciones compatible con la de Ada.
G. Interfaz de programación entre Ada y C
95
Si, en el ejemplo anterior todas las funciones estuvieran en C++ y sub2() en Ada,
entonces la respuesta es no. Actualmente no hay un mecanismo para construir tablas de
excepciones C++.
G.4. Interfaz de funciones
Muchos de los problemas para disponer de funciones en ambos sentidos se soluciona
escribiendo funciones que actúan de interfaz entre C/C++ y Ada. Una buena manera de
hacerlo es establecer un conjunto de funciones para cada clase C++. Este conjunto deberá
tener como mínimo un constructor y un destructor de la clase. Todos los otros miembros
se pueden acceder directamente.
Por ejemplo, podríamos denir una clase C++ llamada MyClass que tiene una función
llamada Print. La función MyClass_AdaCreate crea una instancia de un objeto de tipo
MyClass y devuelve un puntero a él.
Lado en Ada
-- Define and import the three canonical interface functions
-function MyClass_AdaCreate return MyClass_AdaPtrType;
function MyClass_AdaCopy(arg : in MyClass_AdaPtrType)
return MyClass_AdaPtrType;
procedure MyClass_AdaDelete(arg : in MyClass_AdaPtrType);
pragma import (CPP, MyClass_AdaCreate, "MyClass_AdaCreate");
pragma import (CPP, MyClass_AdaCopy, "MyClass_AdaCopy");
pragma import (CPP, MyClass_AdaDelete, "MyClass_AdaDelete");
-- Define the normal member function "Print". Note that the
-- name of the first argument MUST be "this".
-procedure MyClass_Print(this : in MyClass_AdaPtrType);
pragma import (CPP, MyClass_Print, "MyClass::Print");
-- Define the variables
-Instance1 : MyClass_AdaPtrType; -- Pointer to 1st object
Instance2 : MyClass_AdaPtrType; -- Pointer to 2nd object
...
-- Executable code.
-Instance1 := MyClass_AdaCreate; -- Create the object
Instance2 := MyClass_AdaCopy(Instance1); -- Make a copy
MyClass_Print(Instance1); -- Print Instance1
MyClass_Print(Instance2); -- Print Instance2
MyClass_AdaDelete(Instance1); -- Delete Instance1
MyClass_AdaDelete(Instance2); -- Delete Instance2
Lado en C++
// Define the three canonical functions to create, copy,
// and delete objects of type MyClass.
//
MyClass* MyClass_AdaCreate(void)
{
return new MyClass; // Create a new one on the heap
}
MyClass* MyClass_AdaCopy(MyClass* src)
{
return new (*src); // Create a copy on the heap
}
void MyClass_AdaDelete(MyClass* deletethis)
{
delete *deletethis; // Delete this object
}
Es importante jarse en la directiva pragma import. El primer parámetro indica el
lenguaje externo, el segundo es el nombre de la función Ada externa. El tercero indica el
nombre de la función C++.
Descargar