Tutorial de Robótica en VPL. Creación de una Orquestación de Servicios Reusable
Microsoft Robotics Studio proporciona una reutilización de los diseños mediante la escritura de Servicios. Este diseño le permite escribir un servicio (una vez) para una especificación de hardware común y utilizarlo posteriormente con una gran variedad de plataformas hardware de robots.
Se creará un patrón de actividad abstracta que mediante ficheros de configuración permita en tiempo de ejecución que enlace con especificaciones concretas de servicios de hardware, incluso en el entorno de simulación.
La funcionalidad de este tutorial consiste en: Si un sensor de contacto es presionado, el robot retrocede una pequeña distancia, gira aleatoriamente por un corto periodo de tiempo y sigue caminando en línea recta con una velocidad aleatoria. Este tutorial se puede encontrar en la carpeta de instalación de MSRDS bajo la sub-carpeta “Samples\RoboticsTutorials\Tutorial3\mvpl”.
A pesar de que MSRDS posee gran cantidad de servicios, necesitamos uno que permita ejecutar comandos para retroceder, girar aleatoriamente y caminar en línea recta a velocidad aleatoria. Este servicio como tal no existe en MSRDS pero se puede crear construyéndolo como un nuevo servicio.
Comience abriendo un nuevo proyecto y añada al diagrama una actividad “Activity”. Personalice el nombre de la actividad en la venatana/caja de propiedades, mediante la propiedad “Name”, por ejemplo llámele “RandomDrive”. Realizando doble clic sobre la nueva actividad, acceda a su diagrama interno que actualmente se encontrará vacío. Para cada actividad existirá un diagrama interno diferente, a los cuales se puede acceder desde el botón con lista desplegable de la parte superior izquierda del diagrama (cuyo nombre cuando está la actividad vacía es “Action”).
 Figura 95: Lista de diagramas internos de un servicio.
Una nueva actividad inicialmente posee dos acciones. La acción “Start” se ejecuta una vez inmediatamente después de que la actividad comience. En este tutorial no es necesaria por tanto, será ignorada. La segunda acción llamada “Action” puede ser usada como un comando por otros diagramas de la misma forma que ha utilizado operaciones de otros servicios anteriormente en otros diagramas. Además de estas dos acciones, se pueden añadir más acciones bien con la opción “Actions and Notifications” del menú “Edit”, o bien con el icono situado a la derecha del botón con lista desplegable de las acciones, marcado con un círculo verde en la anterior figura y cuyo símbolo es:
En la ventana de acciones y notificaciones, añada dos actividades nuevas pulsando sobre el botón “Add” y renombre las tres (dos nuevas y la ya existente “Action”) como “Retroceder”, “Girar” y “Caminar”.
Cuando se implementen estas tres acciones, es necesario saber la dirección en la que está caminando el robot actualmente para poder retroceder. La dirección puede ser enviada como un valor de entrada a este bloque. Para cada acción, añada un nuevo valor de entrada (“InputValue”) cuyo nombre (para todos) sea “Polaridad”, de tipo “Double” cierre la ventana pulsando OK. Caminar hacia delante se indicará con el valor “1.0” y retroceder con el valor “-1.0”.
 Figura 96: Adición de nuevas acciones a una actividad.
Acción Girar Seleccione el diagrama de la acción Girar. La velocidad de giro debe ser aleatoria y la forma más sencilla es incorporando un servicio “Math Function” al diagrama. Conecte este bloque a la entrada del diagrama y en la ventana de conexiones seleccione en la lista “Random”. Como no tiene ningún valor en la conexión, no se mostrará la ventana de datos de la conexión. “Random” genera valores entre “0.0” y “1.0”.
Se procurará que el valor que genere no se acerque mucho a cero (pues podría no notarse el efecto) ni a uno (pues un giro a toda velocidad podría hacer volcar el robot). Para ello, añadiremos una actividad “Calculate” con el número que llega del bloque “Random” le aplicaremos el cálculo “Result * 0.5 + 0.25” que debe introducir en la caja de texto de la actividad “Calculate”, provocando que el rango de valores del número aleatorio quede entre 0.25 y 0.75. Al enlazar estos dos bloques, seleccione “From: Random-Success” de la ventana de conexiones.
 Figura 97: Inserción del servicio “Math Function” y cálculo de la velocidad de giro mediante la actividad Calculate
Para calcular el valor que le añadiremos a la potencia del motor, usaremos el cálculo realizado pero antes debemos aplicar el sentido de giro, o polaridad del mismo. Esto se consigue conociendo el sentido en la dirección en la que el robot está caminando, para lo que se debe extraer el valor de la polaridad de la entrada usando una actividad “Calculate y combinándola con el número aleatorio que obtuvimos mediante una actividad “Join”. Esta adición sencilla de bloques, debería quedar como indica la siguiente figura:
 Figura 98: Extracción de la polaridad y unión de mensajes mediante la actividad Join
Para provocar que el robot gire, las ruedas deben girar en direcciones distintas. Por tanto son necesarias dos nuevas actividades “Calculate” con el cálculo “Random * Polaridad” en una y anteponiendo a esta expresión un signo negativo en la otra actividad. Ambos valores deben pasarse simultáneamente, por tanto es necesaria una nueva actividad “Join”, que enlace en sus entradas con las anteriores actividades “Calculate”.
 Figura 99: Adición de dos actividades “Calculate” y una “Join” para el cálculo de la potencia de cada rueda
Añada un servicio “Generic Differential Drive” al diagrama de esta actividad de giro y conéctelo a la salida del bloque “Join”. Seleccione en la ventana de conexiones “To: SetDrivePower” y en la ventana de datos de la conexión, pase el valor “Izquierda” a “LeftWheelPower” y “Derecha” a “RightWheelPower”.
A esta altura el robot estaría girando, pero es necesario mantenerlo girando urante unos instantes para que realmente cambie de dirección. La forma más sencilla de mantenerlo girando un tiempo es esperando en este punto durante unos instantes sin hacer ninguna otra actividad. Esto lo realizaremos mediante las inserciones de una actividad “Data” y un servicio “Timer”. Inserte 1500 como valor (serán milisegundos = 1,5 segundos) en la caja de texto de la actividad “Data” y cambie su tipo a “Int”. Enlace a actividad “Data” con el servicio “Timer” estableciendo su conexión con “To: Wait” y como valores de la conexión asigne “Value” a “Interval”. Conecte la operación de salida “SetDrivePower” del servicio “Generic Differential Drive” al bloque “Data” y seleccione “From: SetDrivePower-Success”.
Enlace la salida del “Timer” al pin de salida de datos de la actividad. Esta acción (Girar) no tiene valores de salida pero aún es posible enviar mensajes de salida indicando que todo se terminó apropiadamente enviando el mensaje del resultado del “Timer”, asegurando que no se envía antes de que las operaciones del “Timer” terminen.
 Figura 100: Esquema final de la acción Girar de la actividad “RandomDrive”.
Acción Retroceder Esta acción es similar a la anterior, salvo porque usa valores fijos en lugar de aleatorios para la potencia de ambas ruedas, reduciendo la potencia de entrada a un 40% y convirtiéndola en negativa para el cambio de sentido de la marcha. La potencia aplicada a cada rueda será la calculada en la actividad “Calculate”.
El bloque “Generic Differential Drive” debe ser la misma instancia que la de la actividad anterior y a su vez la misma en las tres actividades. Para ello se recomienda realizar una copia de la misma en el diagrama anterior y pegarla en el diagrama de esta acción.
 Figura 101: Esquema final de la acción Retroceder de la actividad “RandomDrive”. Acción Caminar Esta acción también es similar a la de Girar, salvo en que ambas ruedas recibirán la misma potencia y no es necesario esperar un intervalo de tiempo. El bloque “Generic Differential Drive” debe ser la misma instancia que la de la actividad anterior y a su vez la misma en las tres actividades. Para ello se recomienda realizar una copia de la misma en el diagrama anterior y pegarla en el diagrama de esta acción.
 Figura 102: Esquema final de la acción Caminar de la actividad “RandomDrive”.
Orquestación de actividades personalizadas
Usaremos esta actividad “RandomDrive” con sus tres acciones definidas anteriormente (girar, retroceder y caminar) para construir el programa. Vuelva al diagrama principal del proyecto y añada un sensor de contacto genérico y seguidamente una actividad “If”. Enlace el pin de salida de notificaciones del sensor con la entrada del bloque “If”, seleccionando “From: ContactSensorUpdate”. Establezca la condición “Pressed” en la caja de texto de la primera y única condición del bloque “If”. Ahora es necesario averiguar la dirección actual del robot y cambiarla. Añada un bloque “Variable” y defina la variable “Polaridad” de tipo “Double”. Conecte la salida de la condición del bloque If a la entrada del bloque “Variable”, pero en este caso seleccione “GetValue” de la ventana de conexiones. Ahora la dirección es conocida y se puede retroceder. Conecte el bloque “Variable” al bloque “RandomDrive” y seleccione la acción “Retroceder” de la ventana de conexiones. En la ventana de datos de la conexión seleccione “Polaridad” como valor de entrada de “Polaridad”.
 Figura 103: Diseño necesario para retroceder caso de que se pulse el sensor.
Llega el momento de implementar el giro. Como ya se dispone de un valor nuevo de polaridad, se debe combinar con un “Join” el resultado del retroceso para calcular la nueva dirección (mediante una inversión del antiguo valor). Añada ese bloque “Join” y un bloque “Calculate” una la salida del bloque “variable donde se definió la variable Polaridad con el bloque “Calculate” y añada como expresión a calcular “-Polaridad” en su caja de texto. Enlace la salida de “Calculate” con la entrada inferior del bloque “Join” recién añadido y escriba “Polaridad” en su caja de texto. Copie y pegue el bloque “RandomDrive” y conéctelo a la salida del nuevo bloque “Join”, seleccionando la acción Girar en la ventana de diálogo de conexiones y en la de datos de conexiones seleccione “Polaridad” como valor entrante a “Polaridad”.
 Figura 104: Diseño necesario para la implementación del giro.
Finalmente es necesario recordar la nueva dirección en la variable, para la próxima vez que el sensor de contacto sea presionado. Añada una nueva actividad “Variable”, seleccione “Polaridad” y conéctela al último bloque “Calculate”, seleccionando “SetVariable” en el diálogo de conexiones. Añada una nueva actividad “Data” y otra “Variable” para inicializar la variable Polaridad a “1.0” (hacia delante) y enlácelas con el valor “To: SetValue”. Añada una nueva actividad “Join” cuyas entradas provienen de las salidas del segundo bloque “RandomDrive” y de la actividad “Calculate” previa al anterior bloque Join”. La salida del nuevo “Join” se enlazará a la entrada de una tercera copia del bloque “RandomDrive” que en esta ocasión utilizará la acción “Caminar”.
 Figura 105: Diseño final del tutorial “Creación de orquestación de servicios”.
A estas alturas, sólo resta configurar un manifest y ejecutar la aplicación. Configure el manifest apropiado tanto para el servicio “Generic Contact Sensor” como para una de las copias del “Generic Differential Drive” que posee la actividad “RandomDrive” mediante la importación del manifest deseado. Si no posee un robot, puede probar con el manifest del “simulated mobile robot” o si quiere realizar la simulación con un Logo NXT Tribot seleccione el manifest “LEGO.NXT.Tribot.simulation.Manifest.xml”.
Ejecute el tutorial pulsando F5 o seleccionando la opción “Start” del menú “Run”. En el caso de que estuviese ejecutando una simulación, será necesario pulsar el sensor de contacto. Esto se puede hacer con la cámara del entorno de simulación. Por defecto, la cámara es “transparente”. Se puede atravesar el robot y éste no se moverá. Es posible convertir la cámara en una cámara rígida con la que se puede golpear al robot como si la cámara existiera realmente en el escenario. Esto es posible activando la opción “Enable rigid body for default camera” del menú “Physics” opción “Settings”.
 Figura 106: Convertir la cámara del entorno de simulación en una cámara rígida.
Ahora sólo debe mover la cámara con los cursores de los tres ejes XYZ (letras q, w, e, r, a, s, d) hasta acercarse lo suficiente al sensor de contacto del robot y tocarle. Entonces el robot comenzará a moverse hacia atrás tal y como se le programó. Tiene que perseguir al robot en marcha para probar la segunda y tercera fase (acciones) que se programaron y aunque es algo más difícil, esto le ayudará a coger soltura con los cursores de manejo de los ejes.
Add as favourites (162) | Quote this article on your site | Views: 2671
Only registered users can write comments. Please login or register.
Related Items:
- Jobs: Two Chair positions for new Centre for Computational Neuroscience and Co
- Birmingham Fellows in Robotics and Cognitive Systems
- Finding papers about consciousness and robotics
- Paladyn. Journal of Behavioral Robotics
- International Journal of Social Robotics
- Cognitive Robotics and Machine Consciousness
- Cognitive Robotics
- Polymorphic Robotics
- Urbi goes Open Source
- The Tower of Hanoi for Robotics
|