Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Sunday, November 25, 2012

Practica 4 Sistemas Multiagentes[Laboratorio]

Aunque no existe una definición formal y precisa de lo que es un agente, éstos son por lo general vistos como entidades inteligentes, equivalentes en términos computacionales a un proceso del sistema operativo, que existen dentro de cierto contexto o ambiente, y que se pueden comunicar a través de un mecanismo de comunicación interproceso, usualmente un sistema de red, utilizando protocolos de comunicación.En cierto modo, un sistema multiagentes es un sistema distribuido en el cual los nodos o elementos son sistemas de inteligencia artificial, o bien un sistema distribuido donde la conducta combinada de dichos elementos produce un resultado en conjunto inteligente.


Hay que notar que los agentes no son necesariamente inteligentes. Existen como en todo el resto del dominio de la inteligencia artificial, dos enfoques para construir sistemas multiagentes:

El enfoque formal o clásico, que consiste en dotar de los agentes de la mayor inteligencia posible utilizando descripciones formales del problema que resolver y de hacer reposar el funcionamiento del sistema en tales capacidades cognitivas. Usualmente la inteligencia es definida utilizando un sistema formal (por ejemplo, sistemas de inferencia lógica) para la descripción, raciocinio, inferencia de nuevo conocimiento y planificación de acciones a realizar en el medio ambiente.


El enfoque constructivista, que persigue la idea de brindarle inteligencia al conjunto de todos los agentes, para que a través de mecanismos ingeniosamente elaborados de interacción, el sistema mismo genere comportamiento inteligente que no necesariamente estaba planeado desde un principio o definido dentro de los agentes mismos (que pueden ser realmente simples). Este tipo de conducta es habitualmente llamado comportamiento emergente.




El estudio de los sistemas multiagentes está "interesado en el desarrollo y análisis de resoluciones a problemas sofisticados de IA y arquitecturas de control tanto para sistemas con un único agente como sistemas multiagentes”. Los temas de investigación en SMA’s son:
  • ingeniería de software orientado a agentes
  • creencias, deseos e intenciones (en inglés Beliefs, Desires and Intentions, BDI)
  • cooperación y coordinación
  • organización
  • comunicación
  • negociación
  • resolución de problemas distribuida
  • aprendizaje de multiagentes
  • comunidades científicas
  • fiabilidad y tolerancia a fallos

Para el caso de nuestra practica utilizamos el IDE de Netbeans para codificar en Java y el plugin de JADE, anteriormente utilizado en el reporte 4 de la clase de Sistemas Adaptativos, mismo que implementamos un pequeño ejemplo de como poder utilizar los sistemas multiagentes. Las clases utilizadas para el ejemplo fueron solo una denominada JADE con el cual inicializamos lo que es la interfaz gráfica de JADE, esto para mayor facilidad de lo que queríamos implementar, sin embargo una vez hecho el vídeo  la información se almacena en un archivo binario, a diferencia de codificarlo para un ejemplo automatizado. 





En este ejemplo para la practica, se mencionan al agente dos y tres que son de alguna manera los vendedores, quienes utilizan el medio para ofertar a nuestro comprador el libro que este busca, este código fue utilizado para inicializar la plataforma (GUI) de JADE, por lo cual implementamos un ejemplo manual, de como funcionan los sistemas multiagentes, sin embargo se puede mejorar, ya que es mas factible poder establecer limites, alcances y las metas a conseguir por cada uno de los agentes. Para el caso del vídeo se ejemplifica mas claramente como implementamos sobre este código  el uso de los diferentes agentes. 

Aclarando esto, se tiene entonces que el ejemplo utilizado es mas para fines de ver como interactuan un agente con los compradores potenciales y como pueden estos mantener entre estos una subasta ejemplificada, pero haciendo esto de manera manual, se puede implementar de manera automatizada, pero no podríamos para el caso del ejemplo, ver de donde provienen cada una de las propuestas económicas que cada agente realizaría  por lo que implementamos el ejemplo de forma manual y visualizando, a través de la clase jade.tool.dummy agent.Dummy agent, como podemos realizar una subasta del tipo que prefieramos.


La codificación para nuestra practica es breve, pero el ejemplo en el vídeo mostrado es sustancioso, para quienes se quieran atrever a realizar ejemplos mas complejos como el mostrado mas abajo por Victor Dark en su pagina personal de Youtube, donde nos muestra la interacción de agentes utilizando Twitter para determinar la información que recoge cada agente y como se interpreta para cada uno.




Bibliografía Consultada:

Introducción a los Agentes y Sistemas Multiagentes.  Llamas Bello César. Departamento de Informática Universidad de Valladolid.

Modelado de sistemas complejos mediante simulación basada en agentes y mediante dinámica de sistemas  Izquierdo, Luis R.; Galán, José M.;Santos, José I.;del Olmo, Ricardo (2008).  Empiria. Revista de Metodología de Ciencias Sociales 16. pp. 85-112.

Developing Multi-Agent Systems with JADE. Fabio Luigi Bellifemine, Giovanni Caire, Dominic Greenwood. Chapter 4.



Paginas visitadas para la realización de la practica:









Thursday, November 15, 2012

Reporte 2 [CLASE]

Introducción
En el siguiente ejercicio se generó un programa que obtiene la distribución de grado y la densidad de una red compleja asignada y que es representada por su matriz de adyacencias correspondiente a la Unidad 2: "Algoritmos Adaptativos".


Desarrollo
Para calcular la densidad de la red y la distribución de grado se utilizo un método llamado Calculos( ) dentro de la clase Network.java. La parte más importante del codigo se encuentra obviamente aquí, ya que se evalúan los elementos de la matriz inicial (matriz[ ]) para sacar los valores de m y n y los nodos del grafo.


Lo primero que se calculan son el número de vértices, así como los nodos de la matriz para sacar lo valores de n y m y poder hacer el primer cálculo que es el de la densidad de la red.
for (int i=0; i < matriz.lenght;i++) {  
    for(int j=0;j < matriz.lenght;j++) {
 suma += matriz[i][j];
    }
 sumas[k] = suma;
 nodos += suma;
 k++;
 suma = 0;
 n = k; 
 m = nodos / 2; //
}

densidad = (float)(2*m) / (float)( n*(n-1) );


Una vez que se tienen ya los valores de n y m de la matriz se hace un conteo en los vértices de las repeticiones de número de nodos que hay en cada uno. Esto es para calcular el número de vértices con grado k y posteriormente encontrar la Distribución de grado.


También mediante un for se guardan los diferentes nodos que se encuentran en la matriz g[ ] ( != 0 ) y poder tener los grados de la red analizada.
 do {

    for (int r=0;r < n;r++) {
 if ( sumas[r] == aux ) {
            rep++;
     vertices[j] = sumas[r];
     repet[j] = rep;
     g[aux] = aux;
 }
    }

 aux++;
 rep=0;
 j++;

 }while(j <= n);
  
int aux1=0;
 for (int z=0;z < n;z++) {
     if (g[z] != 0 ) {
 grado[aux1] = g[z];
 aux1++;
     }
 }


Por último se imprimen los resultados obtenidos en un método independiente, llamado mostrarDatos( ) ahí mismo se realiza el cálculo de la distribución de grado antes de imprimirla para no guardarla en otro vector para cada grado.
 for(int r=0;r < 1;r++){System.out.println("\n");}
 System.out.println("\t\t    ----------------------");
 System.out.println("\t\t    ~Densidad de la Red~ "); 
 System.out.println("\t\t    ----------------------");

 System.out.println(" \tn = "+n);
 System.out.println(" \tm = "+m);
 System.out.println("\t\tDensidad = 2m / n(n-1)");
 System.out.println("\t\tDensidad = 2 x "+m+" / "+n+"("+n+"-1)");
 System.out.println("\t\tDensidad de la Red -> "+(2*m)+"/"+(n*(n-1))+" = "+densidad); 

 for(int r=0;r < 1;r++){System.out.println("\n");}
 System.out.println("\t\t--------------------------------");
 System.out.println("\t\t     ~Distribucion de Grado~    "); 
 System.out.println("\t\t--------------------------------");
 System.out.println("\t\t|| K || Vertices ||   Pr(k)   ||");
 int aux2 = 0;
 for(int v=0; v < n;v++){   
   if (repet[v] != 0 ) {
     int r = repet[v];
     float Pr = (float)r / n;
     System.out.println("\t\t   "+grado[aux2]+"\t    "+repet[v]+"\t   "+Pr);
     aux2++;
   }
 }


Para ver el código completo:

https://gist.github.com/4092835


A continuación se presenta la gráfica de la Distribución de Grado:




EXTRA: Se realizó la agrupación de la red mediante los grados calculados, se clasificó por color cada vértice dependiendo el grado de los subgrafos:




Video



Conclusiones
Se pretendió desde un principio adaptar este programa a cualquier red compleja que se pretenda analizar, teniendo la matriz de adyacencias en un archivo .txt, se presentaron algunas fallas al insertas los valores enteros en la matriz del programa y se optó que para fines prácticos por esta ocasión se insertaran los datos manualmente. Se harán las modificaciones correspondientes para adaptarlo a cualquier tamaño de red.

Tuesday, November 13, 2012

Reporte 1 [CLASE]

Introducción
En el siguiente ejercicio se desarrolló la simulación de un Ventilador Auto-ajustable a la temperatura del ambiente haciendo réplica del ejemplo visto en clase en la Unidad 1 "Algoritmos Adaptativos".


Desarrollo
El lenguaje que se utilizó fue JAVA y se utilizaron 2 Threads que se conectaban e interactuaban constantemente para mostrar el cambio de temperatura y estado del ventilador.


En la clase Reconocedor.java se fija una temperatura inicial de 25º C para comenzar la simulación e instanciamos el HiloTemperatura para que comience a evaluar la temperatura e irla ajustando dependiendo del estado actual del Ventilador. A continuación se presenta un fragmento del código

while(true) {

long end = System.currentTimeMillis(); //Se obtiene la hora del sistema en milisegundos (final)
long dif = end - start; //Se calcula el tiempo transcurrido entre la hora del sistema final e inicial

 if(dif >= 20000) { //Genera una temperatura aleatoria cada 20 segundos

  temp = ((genRand.nextInt(10000) % 30) + 17); 
                //Se genera un numero aleatorio entre 17 y 30
  temperatura = (double)temp; 
                // Se hace la conversion de tipo de dato entero a double
   
        /*Se pasan los valores de temperatura y velocidad en la clase Hilo Temperatura*/

  hiloTemp.setTemperatura(temperatura); 
  hiloTemp.setVelocidad(velocidad);

  start = System.currentTimeMillis();

  if (temperatura > 24) {
   estadoVentilador = true;
   setEstado(estadoVentilador);
    
  } else {
   estadoVentilador = false;
   setEstado(estadoVentilador);
  } 

  velocidad = hiloTemp.getVelocidad();
  temperatura = hiloTemp.getTemperatura(); 

 }
 else {
  if (temperatura > 24) {
   estadoVentilador = true;
   setEstado(estadoVentilador);
   
  } else {
   estadoVentilador = false;
   setEstado(estadoVentilador);
  } 
   
 velocidad = hiloTemp.getVelocidad();
 temperatura = hiloTemp.getTemperatura(); 

 } 
 

 for(int r=0;r<20;r++){System.out.println("\n");}
  System.out.println("\t\t----------------------------------");
  System.out.println("\t\t~Sistema Control de un Ventilador~"); 
  System.out.println("\t\t----------------------------------");

  System.out.println("\n\t\t\t~Estado del Ventilador~");
  System.out.println("\n\tTemperatura Ambiental -> "+temperatura+" ºC");
  System.out.println("\n\tVelocidad -> "+velocidad);
  System.out.println("\n\tEstado -> "+state); 

  temperatura = hiloTemp.getTemperatura();
  hiloTemp.setTemperatura(temperatura); 
   
Thread.sleep(5000);
} //Fin del while



En la clase HiloTemperatura.java se hacen validaciones para ajustar la velocidad del ventilador y reducir o aumentar la temperatura dependiendo del estado actual del mismo.


Si el ventilador se encuentra prendido, dependiendo la velocidad del mismo, irá bajando la temperatura del ambiente en un intervalo de 500 milisegundos del hilo de la clase Ventilador, es decir, que para fines prácticos, cada 500 milisegundos disminuirá la temperatura del Ventilador dependiendo de la velocidad del mismo y el estado del Sistema. A continuación se presenta un fragmento del código:


while(true) {
/*Se ira reduciendo la temperatura ambiental dependiendo de la velocidad del ventilador cada 500 milisegundos*/  
  
 if ( (temperatura >= 25) && (temperatura <= 28) ) {
 velocidad = 1;
 hiloVent.setVelocidad(velocidad);
   
  temperatura = temperatura - 0.10;
  hiloVent.setTemperatura(temperatura);
   
 } 

 else if( (temperatura >= 29) && (temperatura <=34) ) {
 velocidad = 2;
 hiloVent.setVelocidad(velocidad);
 
  temperatura = temperatura - 0.05;
  hiloVent.setTemperatura(temperatura);
    
 } 

 else if( temperatura >= 35 ) {
 velocidad = 3;
 hiloVent.setVelocidad(velocidad);

  temperatura = temperatura - 0.02;
  hiloVent.setTemperatura(temperatura);
    
 } 

 else if (temperatura <= 24) {
 velocidad = 0;
 hiloVent.setVelocidad(velocidad);

  temperatura = temperatura + 0.12;
  hiloVent.setTemperatura(temperatura);
    
 }

Thread.sleep(500);
}


Para ver el código completo:

http://gist.github.com/4067869


Video


Conclusiones
Una vez visto los resultados de la aplicación se observa que hay un ligero retardo en el ajuste de la velocidad en pantalla, pero aún así se ajusta y se va aumentando o disminuyendo dependiendo de la velocidad. Para fines de simulación, cada 20 segundos se cambia la temperatura del ambiente aleatoriamente para poder observar en las corridas diferentes ajustes.

Sunday, November 11, 2012

Reporte 4 [Clase]

Sistemas Multiagente

Para realizar este reporte se nos dieron 4 opciones JADE, SPADE, Madkit y Robocup, de las cuales se escogió hacerlo sobre uno de los lenguajes que mas llaman la atención por la versatilidad que presenta y su aplicación simple, esto debido a que es multiplataforma y existe en la mayoría de los equipos un JRE para poder correr dichas aplicaciones generadas en Java sin necesidad de instalar complementos adicionales (dependiendo el programador ya incluiría en su instalación los paquetes que requiera adicionales) .

JADE (Java Agent DEvelopment Framework) es un marco de trabajo aplicado plenamente en el lenguaje Java. Simplifica la implementación de sistemas multi-agente a través de un middleware que cumple con las especificaciones FIPA y a través de un conjunto de herramientas gráficas que soportan la depuración y fases de despliegue. La plataforma de agentes pueden ser distribuidos a través de máquinas (que ni siquiera necesitan compartir el mismo sistema operativo) y la configuración se puede controlar a través de una interfaz gráfica de usuario remoto . 

La configuración se puede cambiar incluso en tiempo de ejecución moviendo agentes de una máquina a otra, como y cuando sea necesario. JADE está completamente implementada en lenguaje Java y la exigencia mínima del sistema es la versión 1.4 de Java (el entorno de tiempo de ejecución o el JDK).

JADE es software libre y se distribuye por Telecom Italia , el titular del derecho de autor, en el software de código abierto bajo los términos de la LGPL (Lesser General Public License Version 2). Desde mayo de 2003, una Asociación JADE ha creado supervisiones para la gestión del proyecto JADE. Actualmente lista 5 miembros: Telecom Italia , Motorola , Whitestein Technologies AG, GmbH Profactor y France Telecom R & D .

JADE tiene una extensión denominada WADE (Workflows and Agents Development Environment) que es un sistema de workflow que permite crear procesos mediante un editor gráfico llamado WOLF.

El componente clave de la plataforma WADE es la clase Workflow Engine Agent que extiende la clase Agent básica de la biblioteca JADE incorporada en el flujo de trabajo,  es un motor pequeño y ligero. Además de los comportamientos JADE normales, un Workflow Engine Agent es por lo tanto capaz de ejecutar flujos de trabajo representadas de acuerdo con un formalismo WADE específico. Este formalismo se basa en el lenguaje Java: un flujo de trabajo WADE es en realidad una clase Java con una estructura bien definida. Este enfoque permite combinar la expresividad de la metáfora del flujo de trabajo con el poder de un lenguaje de programación como Java, y permite el uso de flujos de trabajo para la definición de sistema de lógica interna.


En principio WADE apoya el estilo de programación "editor de textos - programación" en el sentido de que no hay cosas ocultas que los desarrolladores no pueden controlar. Sin embargo, sobre todo teniendo en cuenta que una de las ventajas principales del enfoque de flujo de trabajo es la posibilidad de representar los procesos en una forma gráfica amigable, WADE viene con un entorno de desarrollo llamado WOLF que facilita la creación de WADE  o una aplicación basada en WADE. WOLF es un plug-in de Eclipse, y como consecuencia permite a los desarrolladores aprovechar WADE con todo el poder de la IDE de Eclipse más características adicionales específicas de WAD.


Ejemplo tomado del tutorial de WADE, Fracción de código

... 
public class AssemblerAgent extends WorkflowEngineAgent { 
  private AssemblerAgentGui myGui; 
  private DispatchingCapabilities dc = new DispatchingCapabilities(); 
  private List searcherAgents = new ArrayList();  
  private int index = 0; 
  /**
   * Agent initialization
   */

  protected void agentSpecificSetup() throws AgentInitializationException { 
    super.agentSpecificSetup(); 
// Create and show the gui
    myGui = new AssemblerAgentGui(this); 
    myGui.initGui(); 
    myGui.setVisible(true); 
    // Initialize the DispatchingCapabilities instance used 
    // to launch workflows
    dc.init(this);

    // Subscribe to the DF to keep the searchers list up to date
    ServiceDescription sd = new ServiceDescription(); 
    sd.setType("Searcher Agent"); 
    DFAgentDescription dfTemplate = new DFAgentDescription(); 
    dfTemplate.addServices(sd); 
    SearchConstraints sc = new SearchConstraints(); 
    sc.setMaxResults(new Long(-1)); 
    ACLMessage subscribe = DFService.createSubscriptionMessage( 
                           this,  
                           getDefaultDF(),  
                           dfTemplate,  
                           sc); 
    addBehaviour(new SubscriptionInitiator(this, subscribe) { 
      ... 
    } ); 
  } 
  ... 
  /** 
   * Select a suitable SearcherAgent 
   */ 



  public AID getSearcherAgent() { 
    if (searcherAgents.isEmpty()) { 
      throw new RuntimeException("No SearcherAgent available"); 
    } 
    if (index >=searcherAgents.size()) { 
      index = 0; 
    } 
    return (AID) searcherAgents.get(index++); 
  } 
  /**
   * The method invoked by the GUI when the user requests
   * the assembling of a toy
   */
  void assembleToy(final String type) { 
    ... 
  } 



Finalmente obtenemos de manera simple y llana la salida de este código, el cual posteriormente implementará la interfaz gráfica para definir las tareas visuales que se realizan.


El orden de las imágenes no necesariamente cumple con lo especificado en el código o en el reporte de cada uno de los pasos a seguir cuando utilizamos el tutorial; sin embargo es muy claro en la forma de trabajo que debemos seguir para obtener un resultado favorable; también es un hecho, el tutorial esta orientado a un ejemplo especifico, si nosotros deseamos interactuar con WADE a través de JADE podemos implementar por mencionar un ejemplo, la practica 4 utilizando estas herramientas si nuestro interés es aplicar el lenguaje Java en su conjunto con estas dos herramientas indispensables para un resultado sobresaliente en una aplicación sencilla.


También la empresa Oracle presenta una herramienta interesante que trabaja de manera similar, mas poderosa y mas orientada a las empresas de mayor peso, dejo aquí un demo de esa herramienta y como podemos, por mencionar el ejemplo de subastas, hacer una pequeña aplicación de esa subasta mediante JDeveloper. Les dejo este Link para que visiten y visualicen en tiempo real como trabaja esta herramienta. Hay opciones de paga que también permiten obtener un trabajo de mayor calidad y menores contratiempos basados en estas herramientas que se presentan en este reporte.

Video Demostrativo



Vídeo 1 en Youtube sobre el uso de Jade y Wade en Android.


Vídeo 2 Ejemplo sin utilizar la Interfaz Gráfica, solo a través de consola.


Vídeo 3 Ejemplo interactuando con la GUI de JADE directamente.


Paginas visitadas

http://jade.tilab.com/

http://jade.tilab.com/wade/index.html

Videos utilizados incrustados en este reporte desde su ubicación original para no afectar a sus autores. Videos personales incluidos en este reporte, utilizando la salida en consola para el reporte.

Imágenes utilizadas en este reporte:

E X P L O I T I N G I N T E R A C T I V E  
W O R K F L O W S  O N  A N D R O I D D E V I C E S
http://jade.tilab.com/wade/doc/tutorial/ExploitingInteractiveWorkflowsOnAndroidDevices.pdf


WA D E  T U TO R I A L  
DEFINING AGENT TASKS AS WORKFLOWS

http://jade.tilab.com/wade/doc/tutorial/WADE-Tutorial.pdf


Wednesday, September 5, 2012

Practica 1 "Semáforos"[Laboratorio]

Practica 1 "Cruce Vial con Semáforos Implementados"


Practica 1 Manejo de Clases en la practica


Métodos Utilizados

Métodos que generan todos los datos de carril y define la cantidad de veces que la simulación se ejecutará. Parámetros que ejecutan los valores que se le pasaran al metodo de simulación; determina el numero de veces que la simulación se ejecutará.

    public void Iniciar(String Corridas) {
        generadordeDatosCarril();
        simulaciones(Corridas);

    }

public void simulaciones(String Corridas) {
        int Contador = 0;
        while (Contador < Integer.parseInt(Corridas)) {

            Dibujar_Interseccion();
            MovimientoCarroHztal();
            MovimientoCarroVtcal();

            if (Inicio_semaforo == 10) {
                luces_v = "Verde";
            } else if (Inicio_semaforo == 14) {
                luces_v = "Amarillo";
            } else if (Inicio_semaforo == 15) {
                luces_v = "Rojo";
//.............................................

 
Estas clases y métodos implementados nos funcionan como un indicador o switch para la toma de decisiones sobre las demás clases y métodos implementados para indicar si se coloca o no un carro o si se mueve o no de un espacio a otro.

    public void setVProb(Float verticalProb) {
        prob_VCarro = verticalProb;
    }

    public void setHProb(Float horizontalProb) {
        prob_HCarro = horizontalProb;
    }
Ahora bien creamos una tercer clase que se encarga de darle ahora si, vida a nuestro sistema de semáforos, indicándole a los vehículos cuando podrán avanzar, cuando detenerse o en su caso, poder avanzar en sentidos contrarios al mismo tiempo en cruces hacia la izquierda de ambos sentidos, se utilizan mas pero solo mencionaremos estos dos.
//para los "verticales"
public void MovimientoCarroVtcal() {
        for (int i = ArregloVertical.size() - 1; i > -1; i--) {
            for (int j = 0; j < ArregloVertical.get(0).size(); j++) {
                if (ArregloVertical.get(i).get(j).equals("c")) { //si el elemento es igual a "c" entonces...
                    if (i == ArregloVertical.size() - 1) {
                        ArregloVertical.get(i).set(j, " "); //si el actual carro en el arreglo es el ultimo colocar un espacio vacio" "
                    } else if (i == 9 && luces_v.equals("Verde")) {//........
//para los horizontales

public void MovimientoCarroHztal() {
        for (int i = ArregloHorizontal.size() - 1; i > -1; i--) {
            for (int j = ArregloHorizontal.get(0).size() - 1; j > -1; j--) {
                if (ArregloHorizontal.get(i).get(j).equals("C")) { //si el elemento es igual a C entonces
                    if (j == ArregloHorizontal.get(0).size() - 1) {
                        ArregloHorizontal.get(i).set(j, " ");
                    } else if (luces_h.equals("Rojo") && j == 10) {//.........


Implementamos cada uno de los "threads" que correremos para el control de los semáforos, o dicho de otra manera "el flujo del sistema", mediante la implementación de cada una de las clases trabajando en su conjunto.
public class ProcessA extends CircuitoVial implements Runnable {
  public void run() {
    while (true) {
      try {
        Thread.sleep(1 + (int) (random.nextDouble() * 500));
      } catch (InterruptedException e1) {
        e1.printStackTrace();
      }
      System.out.print("A");
      contador.notifyToWakeup();
    }
  }
}
quedaría pendiente la interfaz gráfica...
Observaciones: Modificaciones realizadas, para evitar problemas o aproximaciones de plagio, comentadas y externadas en este espacio. Aclaración para los gúrus del idioma Ingles y las barreras del idioma: Semáforo para San Google y para cualquier diccionario del idioma Inglés ( Semaphore, Traffic Light(semaforos) o Traffic Lights(plural) Así que aclarado el tema... Pendiente temporal: Interfaz Gráfica y Video, de momento lo importante era ver que no se tuvieran problemas por las observaciones arriba mencionadas.