Capitulo V. Sistema Robot dirigido por voz. El propósito principal de

Anuncio
Capitulo V. Sistema Robot dirigido por voz.
El propósito principal de este sistema es que el robot ejecute ciertas instrucciones en tiempo real, lo interesante es que las instrucciones se las da el usuario a la computadora por medio de voz; La computadora decodifica la voz y la convierte en instrucciones legibles para el robot. Después de esto se envían las instrucciones al robot por medio de bluetooth. Y el robot al momento de recibirlas las ejecuta en tiempo real.
Este sistema ha sido programando en el lenguaje de programación java, todas las herramientas utilizadas en este sistema están previamente analizadas para poder tener una integración completa y compatible a la hora de la integración del sistema. El sistema consta de dos estados el primero llamado “Autónomo” este es un estado en el cual el robot puede tomar sus propias dediciones las cuales están previamente programadas. El segundo estado llamado “Dirigido” es el estado en el cual el robot ejecuta las instrucciones de voz, previamente decodificadas por una computadora.
El robot se desenvuelve en un ambiente estático y predefinido por el usuario. Donde el robot se encontrara con una serie de situaciones que el mismo debe resolver, en dado caso que el robot entre en una situación de pánico y no la pueda resolver el problema, el robot solicitara la intervención del usuario para resolver dicho problema
Todo este sistema fue desarrollado con el IDE llamado Eclipse. Este IDE nos permite programar en Java. Seleccione este IDE porque me permitió integrar varias aplicaciones y herramientas como lo son Sphinx, Icommand, etc. De tal manera que puedo generar un modulo de reconocimiento de voz, y a la ves un modulo de instrucciones legibles para el robot y por ultimo un modulo de integración de estas dos partes. 5.1. Componentes básicos del sistema.
Básicamente el sistema esta formado por tres partes principales, las cuales nos permiten dividir el sistema en diferentes sectores. Como por ejemplo, existe un sector donde reconocimiento de voz, otro sector donde se encuentran las instrucciones que el robot va a ejecutar y por ultimo una sección donde pasamos de voz a comandos legibles para el robot. Diagrama de Contexto
USUARIO
Comando de voz
Reconocimiento de voz.
Comando decodificado
Selección de comando de voz a instrucción legible para el robot.
Numero de comando
Instrucciones legibles para el robot.
Robot ejecuta comando “Dirigido” Robot ejecuta comando “Autónomo”
Se ejecuta este comando hasta que el robot se encuentre en una situación crítica o de pánico.
Figura 5.1 Diagrama de Contexto
En la figura 5.1 podemos notar la estructura básica del sistema robot dirigido por voz con todos sus componentes esenciales. De esta manera tenemos un panorama amplio de cómo esta conformado el sistema.
Lo primero que debe ocurrir es que el usuario desee decirle al robot que es lo que el quiere que el robot ejecute, esto por medio de comandos de voz predefinidos, al momento de que el usuario le mandan a la computadora el comando de voz, este comando se decodificado en una cadena de caracteres, esto con la ayuda de la herramienta Sphinx 4. Seguido de esto, dicha cadena se compara con una seria de comandos pre­definidos con anterioridad. Y se le asigna un número de comando a dicha instrucción. Después de tener el número de comando correspondiente, se le indica al robot que comando de los pre­definidos debe ejecutar.
Comando de voz.
Ejemplo. “Go”.
Cadena decodificada por el sector de reconocimiento de voz Si el comando es “go”
El comando se envía al robot por me dio de Bluetooh y se ejecuta en tiempo real. Ejemplo del comandos
Numero de comando
1
Moto.Backward(700);
2
Motor.a.Backward(25);
back
1
left
2
go
3
3 Moto.Forward(700);
right 4
4
Motor.a.Forward(25);
ETC
#
ETC
#
Figura 5.2 Estructura básica de manejo de comandos.
Para el manejo de comandos que el robot ejecuta, decidí integrar en el sistema un patron de diseño de software llamando Command Pattern, que me permite manipular los comandos del robot de manera independiente. La ventaja de utilizar dicho patron es que me permite agregar o eliminar comandos sin dañar el sistema original. Command Pattern UML
Client
Invoker Command
_Interface Command
setCommand()
execute()
Receiver
action()
Concrete
execute()
Figura 5.3 Estructura básica del patrón de diseño llamado Command Pattern.
En la figura 5.3 podemos ver la estructura básica del patron, en un diagrama UML. Que nos permite ver los componentes principales para poder implementar dicho patron.
Para el sector de reconocimiento de voz, se implemento la herramienta llamada sphinx que nos permite reconocer la voz utilizando una gramática de tipo BNF, junto con Java Speech API Grammar Format (JSGF). Esto nos permite definir una gramática adecuada para poder reconocer los comandos de voz. Esta herramienta procesa la voz y dependiendo de cómo nosotros pronunciemos el comando decodifica la voz y la compara con la gramática que nosotros definimos previamente, después nos regresa una cadena de caracteres con el mejor resultado obtenido por la descodificación del comando de voz. Voz
Decodificación de voz
Comparación con la gramática
Resultado de la comparación con la gramática en forma de cadena de Caracteres (String).
Figura 5.4 Reconocimiento de voz.
5.2. Diagrama de clases.
Figura 5.5 Diagrama de clase del sector de reconocimiento de voz.
En la figura 5.5 Se muestra como es que se comunican las clases, de esta manera tenemos un panorama más amplio de que es lo que hace el sistema en este sector.
Para el diagrama de clases, empezamos con la clase principal en la cual inicializamos el sistema, como el lenguaje de programación es orientado a objetos, tenemos una serie de clases que heredan y utilizan métodos conectados entre ellos.
Figura 5.6 Diagrama de clase donde inicializamos el sistema.
En la figura 5.6 se muestra la clase que utilizamos para inicializar el sistema, esto mandando a llamar los métodos Conectar(); TextoReconocido(); que se encuentran el la clase de Reconocedor_voz. Figura 5.7 Diagrama de clase Reconocedor de voz.
En la figura 5.7 se muestra la clase en la cual tenemos dos métodos principales el primero llamado Conectar, nos permite activar la herramienta llamada sphinx en la cual nosotros hemos programado la inicializamos lo que es el micrófono de nuestra computadora y así mismo la conexión con el robot para que reciba información por medio de vía bluetooth. En el método llamado TextoReconocido, es donde se decodifica el comando de voz, esto solicitando la ayuda de la herramienta sphinx, después de que dicha herramienta nos regresa el mejor resultado en forma de cadena (String), entonces se manda a llamar a las siguientes clases:
•
•
int command_number = Sender.Sender_Voice_Command(res);
Sender.Number_command(command_number);
Que nos permiten comparar que comando se va a enviar al robot para ser ejecutado en tiempo real. En el supuesto caso que la herramienta sphinx nos regrese la cadena llamada “Exit”, esto nos indica que el usuario desea salir del sistema, para esta parte utilice un la clase llamada teclado, esta clase nos permite leer, desde el teclado cualquier tipo de dato, puede ser String, float, char, integer, etc. Y esto le sirve al sistema para confirmar la salida del mismo.
Figura 5.8 Diagrama de clase Teclado.
En la figura 5.8 se muestra el diagrama de clase que me ayuda a obtener el carácter de “Y” o “N” del teclado, dependiendo de que es lo que realmente desee el usuario. En este diagrama podemos ver que no solo existe para obtener String sino también cualquier tipo de carácter desde el teclado ya sea Float, String, Boolean, Etc. Para este sistema nosotros solo utilizamos el método llamado readString() que nos permite leer dicho dato solicitado por el sistema. Para saber si el usuario realmente desea salir del mismo.
Para la ejecución de comando se creo una clase llamada Sender. Que nos permite compara y definir el comando que será enviando al robot en tiempo real.
Figura 5.9 clase Sender.
En la figura 5.9 tenemos la estructura básica de la clase Sender. En esta clase como mencione anteriormente hay dos métodos principales, el primero llamado Sender_Voice_Command(), que requiere una cadena (String) para ejecutarse, es el que se encarga de hacer la comparación entre cadenas de caracteres y regresa el número de comando a ejecutar. Este número nos sirve para activar el método Number_comman que nos permite enviar y ejecutar el comando en tiempo real. Para el manejo de los comandos utilizamos el patron de diseño de software llamado command pattern. Que nos permite integrar los comandos de manera independiente y sin afectar el sistema. Al implementar dicho patron utilice las siguientes clases.
igura 5.10 Diagrama de clase del sector command pattern.
En la figura 5.10 podemos ver como se encuentra implementado el patron de diseño de software llamado command pattern. También podemos observar en que parte va la lista de comando de una manera clara, estas clases le permiten al sistema tener por separado lo que son los comandos del robot y el sistema por completo. Para implementar este patron de diseño de software en el sistema lo primero que hice fue generar una clase tipo interfaz llamada Command que nos permita tener el método llamado execute() para poder acceder a el desde otras clases.
Figura 5.11 Diagrama de clases Command.
Seguido de esto el sistema cuenta con una clase llamada Concrete_Comand_Car que es la clase encargada de tener todos los métodos de los comandos que el robot debe ejecutar, dentro de estos métodos es donde ponemos las instrucciones del robot.
Figura 5.12 Diagrama de clase Concrete_Command_Car.
Cada uno de estos métodos tiene las instrucciones que el robot va a ejecutar, como por ejemplo:
public void Go()
{
Moto.setSpeed(70);
if(goNum == 1)
{
if( us.getDistance() > 30)
{
Moto.forward();
System.out.println("Avanza 30 cm");
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else
{
}
Moto.stop();
File sound = new File("Alarm.rso");
Speaker.playSoundFile(sound.getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto­generated catch block
e.printStackTrace();
}
}
if(goNum == 2)
{
if(us.getDistance() > 60)
{
Moto.forward();
System.out.println("Avanza 60 cm");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else
Moto.stop();
{
}
File sound = new File("Alarm.rso");
Speaker.playSoundFile(sound.getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto­generated catch block
e.printStackTrace();
}
}
if(goNum == 3)
{
if(us.getDistance() > 90)
{
Moto.forward();
System.out.println("Avanza 90 cm");
try {
Thread.sleep(4500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else
{
}
Moto.stop();
File sound = new File("Alarm.rso");
Speaker.playSoundFile(sound.getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto­generated catch block
e.printStackTrace();
}
}
} Moto.flt();
System.out.println("Sensor de ultrasonido desactivado");
Por cada uno de estos comandos debemos de tener una clase que hereda la ubicación de dicho método poder así llamarlos de manera independiente y para esto debemos de generar dichas clases de la siguiente manera.
Figura 3.13 Diagrama de las diferentes clases de cada comandos.
En la figura 5.13 tenemos la colección de diagramas de clases que son las cuales debemos de generas si deseamos tener un comando mas para que el robot ejecute, estas 6 clases son iguales y si el usuario así lo desea puede agregar los comandos que el necesita.
Este patron requiere de una clase llamada invoker que se encarga como su nombre lo dice de invocar cada uno de los métodos mencionados anteriormente, cuenta con un Slot de la clase Command y con dos métodos llamados SetCommand() y Run() que nos permiten ejecutar los comandos.
Figura 5.14 Diagrama de clase Invoker_Command.
Por ultimo requerimos de un cliente, que en este caso es la clase llamada Sender la cual nos sirve como pivote dentro del sistema y nos permite conectar la parte de reconocimiento de voz con la parte de patrones de diseño de software que en este caso son los comandos.
Figura 5.15 Diagrama de clase Sender.
En la figura 5.15 podemos notar que cuenta con dos métodos esenciales el primero llamando Sender_Voice_Command() la cuan es de tipo entero y nos permite regresar un número pre­asignado a los comando que el usuario mencione durante el reconocimiento de voz. Por ejemplo si el usuario dice Left y dentro de esta clase esta asignado el Left a la instrucción 3 entonces se le asigna dicho numero. Después de conseguir el numero el sistema requiere del método llamado Number_command. En cual nosotros mandamos a llamar a la clase llamada Invoker_Command la cual tiene la capacidad de ejecutar el comando en este ejemplo el 3. Para esto dicho metodo cuenta con un switch que indica que comando debe ejecutar, en este caso es el 3 así que seria:
case 3:
//ingresas el comando que quieres que se ejecute w.SetCommand(Left);
//se ejecuta el comando
w.Run();
break;
Como mencione anteriormente si el usuario deseara agregar otros comandos lo único que tendría que hacer es agregar dicho comando de una manera concreta en la clase llamada Concrete_Command_Car seguido de esto, se debe generar la clase del comando que el usuario agrego. De manera independiente y extendiendo la interfaz command, como se vio en la lista de comandos con que cuenta este sistema. Y por ultimo agregar la instrucción a la gramática del sistema y modificar la clase Sender agregándole la instrucción dentro de los “if” y “case”. De manera inversa si el usuario desea eliminar un comando tendría que hacer los mismos pasos mencionado anteriormente pero eliminado dichos comandos.
Los comandos de este sistema pueden ser tan complejos como el usuario lo desee, en este caso en especifico el sistema cuenta con un método llamado “Free” que requiere de otros métodos dentro de la clase command, este método tiene la capacidad de evadir objetos y solicitar la ayuda de el usuario, esto si el robot se encuentra en una situación critica o de pánico. Como ejemplo aquí les agrego el método mencionado con anterioridad que es una combinación de los métodos básicos.
public void Free() {
int count = 0;
Moto.setSpeed(70);
Moto.forward();
while(true)
{
if(count >= 2 || touch.isPressed() == true)
{
Alarm();
Stop();
break;
}
else
{
if( us.getDistance() <= 30)
{
Stop();
Left();
Back();
if(touch.isPressed() == true)
{
Stop();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
}
Center();
count++;
System.out.print("La disrancia es: "+ us.getDistance()+ "\n El contador Tiene" + count);
if(us.getDistance() > 31)
{
Moto.setSpeed(70);
Moto.forward();
count = 0;
System.out.print("Contador = 0;");
}
}
}
}
}
Como se puede notar en este método el robot cuenta con una inteligencia artificial reactiva que le permite comportarse con forme a ciertas situaciones y con reglas que le permiten resolver un cierto problema. Como por ejemplo en el caso del método free el robot se encuentra a un distancia de 30 cm. de un objeto cualquiera este se detiene y realiza una serie de movimientos que le permiten evadir el objeto.
Si al momento que el robot retrocede para evadir el objeto se encuentra con alguno otro objeto por la parte trasera este se detiene y pide la ayuda del usuario avisándole con una serie de frecuencias pre­programadas. Así mismo si el robot realiza el movimiento de evadir objetos 4 veces se deduce que el robot se encuentra encerrado y como no tiene la capacidad de ver pues solicita la ayuda del usuario para salir del problema utilizando las mismas frecuencias mencionadas anteriormente.
El pionero de este tipo de inteligencia es Dr. Rodney Brooks que actualmente es el director de los laboratorios de inteligencia artificial en MIT (Massachusetts Institute of Technology). [Web 11]
Ya que el sistema cuenta con todo lo mencionado anteriormente, me atrevo a decir que este sistema puede ser escalado y modificado al gusto del usuario según lo desee y es muy importante que al momento de agregar o quitar comandos la estructura básica del sistema no genere ningún problema es por esto que decidí utilizar el patron mencionado anteriormente.
5.3. Diagrama de Flujo.
Comando de voz
Usuario
Inicio
Procesamiento de voz. Salida del sistema
Finalización de comando ejecutado.
Selección de comando.
Ejecución de comando
Robot ejecutando. Estado Dirigido
Solicitando ayuda del usuario
Robot ejecutando. Estado Autónomo
Situación crítica o de pánico
Figura 5.16 Diagrama de Flujo del sistema robot dirigido por voz.
Descargar